diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 15d3cc9f0..8407d57a5 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,5 +1,19 @@ # Change Log +## v3.60.0 - Apr 16, 2023 + +* Fixes labels of the Size section in the Inspector view. +* Scene compiler: fixes class-field declaration. +* Scene compiler: fixes nested prefab varname resolution. +* Improves folder icons. +* Adds command for enable/disable pixel art rendering mode. +* New game objects support: NineSlice and ThreeSlice. +* Removes Parent section. +* Supports the new ScriptNode object. +* Updates the app icon. +* Updates to Phaser 3.60. +* Updates allInOne built-in templates to support Phaser 3.60 and script nodes. + ## v3.36.2 - Dec 14, 2022 * Get latest update from Core: diff --git a/design/blender-mono/custom/nineslice/dark/3slice.png b/design/blender-mono/custom/nineslice/dark/3slice.png new file mode 100644 index 000000000..29eb8687a Binary files /dev/null and b/design/blender-mono/custom/nineslice/dark/3slice.png differ diff --git a/design/blender-mono/custom/nineslice/dark/3slice@2x.png b/design/blender-mono/custom/nineslice/dark/3slice@2x.png new file mode 100644 index 000000000..d60f64cb2 Binary files /dev/null and b/design/blender-mono/custom/nineslice/dark/3slice@2x.png differ diff --git a/design/blender-mono/custom/nineslice/dark/9slice.png b/design/blender-mono/custom/nineslice/dark/9slice.png new file mode 100644 index 000000000..91be9336d Binary files /dev/null and b/design/blender-mono/custom/nineslice/dark/9slice.png differ diff --git a/design/blender-mono/custom/nineslice/dark/9slice@2x.png b/design/blender-mono/custom/nineslice/dark/9slice@2x.png new file mode 100644 index 000000000..7a314516e Binary files /dev/null and b/design/blender-mono/custom/nineslice/dark/9slice@2x.png differ diff --git a/design/blender-mono/custom/nineslice/light/3slice.png b/design/blender-mono/custom/nineslice/light/3slice.png new file mode 100644 index 000000000..b7d2c2f06 Binary files /dev/null and b/design/blender-mono/custom/nineslice/light/3slice.png differ diff --git a/design/blender-mono/custom/nineslice/light/3slice@2x.png b/design/blender-mono/custom/nineslice/light/3slice@2x.png new file mode 100644 index 000000000..c7df8adf1 Binary files /dev/null and b/design/blender-mono/custom/nineslice/light/3slice@2x.png differ diff --git a/design/blender-mono/custom/nineslice/light/9slice.png b/design/blender-mono/custom/nineslice/light/9slice.png new file mode 100644 index 000000000..5dd748809 Binary files /dev/null and b/design/blender-mono/custom/nineslice/light/9slice.png differ diff --git a/design/blender-mono/custom/nineslice/light/9slice@2x.png b/design/blender-mono/custom/nineslice/light/9slice@2x.png new file mode 100644 index 000000000..896514625 Binary files /dev/null and b/design/blender-mono/custom/nineslice/light/9slice@2x.png differ diff --git a/design/blender-mono/custom/nineslice/nineslice.svg b/design/blender-mono/custom/nineslice/nineslice.svg new file mode 100644 index 000000000..55cf72d2d --- /dev/null +++ b/design/blender-mono/custom/nineslice/nineslice.svg @@ -0,0 +1,7101 @@ + + + + + Blender icons v. 2.5.08 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Blender icons v. 2.5.08 + 21.05.2012 + + + Andrzej Ambroż + + + + + Andrzej Ambroż + + + + + Andrzej Ambroż + + + + + GNU General Public License, version 2 or later. + + + + + + + + + + + + + + + + + + + diff --git a/design/logo-icons/1024.png b/design/logo-icons/1024.png new file mode 100644 index 000000000..1e4046695 Binary files /dev/null and b/design/logo-icons/1024.png differ diff --git a/design/logo-icons/128.png b/design/logo-icons/128.png index 97895c2ff..72b41a151 100644 Binary files a/design/logo-icons/128.png and b/design/logo-icons/128.png differ diff --git a/design/logo-icons/256.png b/design/logo-icons/256.png index 3a2f17a7c..b8d34a418 100644 Binary files a/design/logo-icons/256.png and b/design/logo-icons/256.png differ diff --git a/design/logo-icons/32.png b/design/logo-icons/32.png index 252a6c1a7..1d0bb3eac 100644 Binary files a/design/logo-icons/32.png and b/design/logo-icons/32.png differ diff --git a/design/logo-icons/48.png b/design/logo-icons/48.png index 4f9c5bc1c..924c8c54a 100644 Binary files a/design/logo-icons/48.png and b/design/logo-icons/48.png differ diff --git a/design/logo-icons/512.png b/design/logo-icons/512.png new file mode 100644 index 000000000..a435efb9e Binary files /dev/null and b/design/logo-icons/512.png differ diff --git a/design/logo-icons/64.png b/design/logo-icons/64.png index 8bd53ff0e..313bef195 100644 Binary files a/design/logo-icons/64.png and b/design/logo-icons/64.png differ diff --git a/design/logo-icons/build-icons.sh b/design/logo-icons/build-icons.sh new file mode 100755 index 000000000..16bfb1420 --- /dev/null +++ b/design/logo-icons/build-icons.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# optipng *.png + +convert 16.png 32.png 48.png 256.png icon.ico + +rm -Rf icon.iconset +mkdir icon.iconset + +cp 16.png icon.iconset/icon_16x16.png + +cp 32.png icon.iconset/icon_16x16@2x.png +cp 32.png icon.iconset/icon_32x32.png + +cp 64.png icon.iconset/icon_32x32@2x.png +cp 64.png icon.iconset/icon_64x64.png + +cp 128.png icon.iconset/icon_64x64@2x.png +cp 128.png icon.iconset/icon_128x128.png + +cp 512.png icon.iconset/icon_64x64@2x.png +cp 512.png icon.iconset/icon_512x512.png + +cp 1024.png icon.iconset/icon_512x512@2x.png + +iconutil -c icns icon.iconset/ + +rm -R icon.iconset \ No newline at end of file diff --git a/design/logo-icons/dark-128.png b/design/logo-icons/dark-128.png new file mode 100644 index 000000000..6cd0f2c47 Binary files /dev/null and b/design/logo-icons/dark-128.png differ diff --git a/design/logo-icons/drawing.svg b/design/logo-icons/drawing.svg new file mode 100644 index 000000000..50b5703a8 --- /dev/null +++ b/design/logo-icons/drawing.svg @@ -0,0 +1,3810 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/design/logo-icons/icon.icns b/design/logo-icons/icon.icns new file mode 100644 index 000000000..bb659a08d Binary files /dev/null and b/design/logo-icons/icon.icns differ diff --git a/design/logo-icons/icon.ico b/design/logo-icons/icon.ico new file mode 100644 index 000000000..1433166fa Binary files /dev/null and b/design/logo-icons/icon.ico differ diff --git a/design/logo-icons/logo.png b/design/logo-icons/logo.png deleted file mode 100644 index cd15a158e..000000000 Binary files a/design/logo-icons/logo.png and /dev/null differ diff --git a/scripts/make-all-help-files.js b/scripts/make-all-help-files.js index 6333b40b9..019f6ea36 100755 --- a/scripts/make-all-help-files.js +++ b/scripts/make-all-help-files.js @@ -120,6 +120,12 @@ utils.makeHelpFile([ "Phaser.GameObjects.TileSprite.tileScaleY", "Phaser.GameObjects.TileSprite.setTileScale", + "Phaser.GameObjects.NineSlice", + "Phaser.GameObjects.NineSlice.leftWidth", + "Phaser.GameObjects.NineSlice.rightWidth", + "Phaser.GameObjects.NineSlice.topHeight", + "Phaser.GameObjects.NineSlice.bottomHeight", + "Phaser.GameObjects.GameObject.parentContainer", "Phaser.GameObjects.Text", diff --git a/source/editor/package.json b/source/editor/package.json index 6c03739d0..1ae4da1de 100644 --- a/source/editor/package.json +++ b/source/editor/package.json @@ -7,7 +7,7 @@ "start": "tsc -b -w", "build": "tsc -b", "clean": "tsc -b -clean", - "editor-dev": "PhaserEditor2D -editor . -project \"$PHASEREDITOR_DEMO_PROJECT\" -dev -disable-plugins phasereditor2d.code" + "editor-dev": "PhaserEditor2D -editor . -project \"$PHASEREDITOR_DEMO_PROJECT\" -dev" }, "devDependencies": { "tslint": "^6.1.3", diff --git a/source/editor/plugins/colibri/icons/dark/folder.png b/source/editor/plugins/colibri/icons/dark/folder.png index 1cdad53eb..3369e8bc8 100644 Binary files a/source/editor/plugins/colibri/icons/dark/folder.png and b/source/editor/plugins/colibri/icons/dark/folder.png differ diff --git a/source/editor/plugins/colibri/icons/dark/folder@2x.png b/source/editor/plugins/colibri/icons/dark/folder@2x.png index 5874a3aa5..4f7dfcda5 100644 Binary files a/source/editor/plugins/colibri/icons/dark/folder@2x.png and b/source/editor/plugins/colibri/icons/dark/folder@2x.png differ diff --git a/source/editor/plugins/colibri/icons/light/folder.png b/source/editor/plugins/colibri/icons/light/folder.png index 16298ccde..ba371ec09 100644 Binary files a/source/editor/plugins/colibri/icons/light/folder.png and b/source/editor/plugins/colibri/icons/light/folder.png differ diff --git a/source/editor/plugins/colibri/icons/light/folder@2x.png b/source/editor/plugins/colibri/icons/light/folder@2x.png index 1e58be1a2..63dc667b5 100644 Binary files a/source/editor/plugins/colibri/icons/light/folder@2x.png and b/source/editor/plugins/colibri/icons/light/folder@2x.png differ diff --git a/source/editor/plugins/colibri/src/ui/controls/viewers/GridTreeViewerRenderer.ts b/source/editor/plugins/colibri/src/ui/controls/viewers/GridTreeViewerRenderer.ts index b1c84a1d6..67c3f27a1 100644 --- a/source/editor/plugins/colibri/src/ui/controls/viewers/GridTreeViewerRenderer.ts +++ b/source/editor/plugins/colibri/src/ui/controls/viewers/GridTreeViewerRenderer.ts @@ -458,15 +458,25 @@ namespace colibri.ui.controls.viewers { this.prepareContextForText(args); - const label = args.viewer.getLabelProvider().getLabel(args.obj); + const labelProvider = args.viewer.getLabelProvider(); + const styledLabelProvider = args.viewer.getStyledLabelProvider(); - const trim = this.trimLabel(ctx, label, args.w - 10); + const label = labelProvider.getLabel(args.obj); - const x2 = Math.max(x, x + args.w / 2 - trim.textWidth / 2); + const trimLabel = this.trimLabel(ctx, label, args.w - 10); + + const x2 = Math.max(x, x + args.w / 2 - trimLabel.textWidth / 2); const y2 = args.y + args.h - 5; - ctx.fillText(trim.text, x2, y2); + if (styledLabelProvider && !selected) { + + this.renderStyledLabel(args, x2, y2, styledLabelProvider, trimLabel.text.length); + + } else { + + ctx.fillText(trimLabel.text, x2, y2); + } ctx.restore(); diff --git a/source/editor/plugins/colibri/src/ui/controls/viewers/TreeViewerRenderer.ts b/source/editor/plugins/colibri/src/ui/controls/viewers/TreeViewerRenderer.ts index d6731d82e..b9fb12acd 100644 --- a/source/editor/plugins/colibri/src/ui/controls/viewers/TreeViewerRenderer.ts +++ b/source/editor/plugins/colibri/src/ui/controls/viewers/TreeViewerRenderer.ts @@ -288,7 +288,7 @@ namespace colibri.ui.controls.viewers { args.canvasContext.fillText(label, x, y); } - protected renderStyledLabel(args: RenderCellArgs, x: number, y: number, styledProvider: IStyledLabelProvider) { + protected renderStyledLabel(args: RenderCellArgs, x: number, y: number, styledProvider: IStyledLabelProvider, maxLength = -1) { const dark = controls.Controls.getTheme().dark; @@ -300,15 +300,31 @@ namespace colibri.ui.controls.viewers { ctx.save(); + let len = 0; + for (const part of parts) { ctx.fillStyle = part.color; - ctx.fillText(part.text, cursor, y); + let text = part.text; + + if (maxLength > 0 && len + part.text.length > maxLength) { + + text = text.substring(0, maxLength - len - 2) + ".."; + } + + ctx.fillText(text, cursor, y); - const width = this.measureText(args, part.text); + const width = this.measureText(args, text); cursor += width; + + len += text.length; + + if (maxLength > 0 && len >= maxLength) { + + break; + } } ctx.restore(); diff --git a/source/editor/plugins/phasereditor2d.animations/data/phaser-docs.json b/source/editor/plugins/phasereditor2d.animations/data/phaser-docs.json index 59505f419..71c70a048 100644 --- a/source/editor/plugins/phasereditor2d.animations/data/phaser-docs.json +++ b/source/editor/plugins/phasereditor2d.animations/data/phaser-docs.json @@ -5,7 +5,7 @@ "Phaser.Types.Animations.Animation.repeat": "Number of times to repeat the animation (-1 for infinity)", "Phaser.Types.Animations.Animation.repeatDelay": "Delay before the animation repeats. Value given in milliseconds.", "Phaser.Types.Animations.Animation.yoyo": "Should the animation yoyo? (reverse back down to the start) before repeating?", - "Phaser.Types.Animations.Animation.showOnStart": "Should sprite.visible = true when the animation starts to play?", + "Phaser.Types.Animations.Animation.showOnStart": "Should sprite.visible = true when the animation starts to play? This happens _after_ any delay, if set.", "Phaser.Types.Animations.Animation.hideOnComplete": "Should sprite.visible = false when the animation finishes?", "Phaser.Types.Animations.Animation.skipMissedFrames": "Skip frames if the time lags, or always advanced anyway?" } \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.files/icons/dark/project.png b/source/editor/plugins/phasereditor2d.files/icons/dark/project.png index 1cdad53eb..3369e8bc8 100644 Binary files a/source/editor/plugins/phasereditor2d.files/icons/dark/project.png and b/source/editor/plugins/phasereditor2d.files/icons/dark/project.png differ diff --git a/source/editor/plugins/phasereditor2d.files/icons/dark/project@2x.png b/source/editor/plugins/phasereditor2d.files/icons/dark/project@2x.png index 5874a3aa5..4f7dfcda5 100644 Binary files a/source/editor/plugins/phasereditor2d.files/icons/dark/project@2x.png and b/source/editor/plugins/phasereditor2d.files/icons/dark/project@2x.png differ diff --git a/source/editor/plugins/phasereditor2d.files/icons/light/project.png b/source/editor/plugins/phasereditor2d.files/icons/light/project.png index 16298ccde..ba371ec09 100644 Binary files a/source/editor/plugins/phasereditor2d.files/icons/light/project.png and b/source/editor/plugins/phasereditor2d.files/icons/light/project.png differ diff --git a/source/editor/plugins/phasereditor2d.files/icons/light/project@2x.png b/source/editor/plugins/phasereditor2d.files/icons/light/project@2x.png index 1e58be1a2..63dc667b5 100644 Binary files a/source/editor/plugins/phasereditor2d.files/icons/light/project@2x.png and b/source/editor/plugins/phasereditor2d.files/icons/light/project@2x.png differ diff --git a/source/editor/plugins/phasereditor2d.ide/src/IDEPlugin.ts b/source/editor/plugins/phasereditor2d.ide/src/IDEPlugin.ts index 20ced08d0..0b969baf3 100644 --- a/source/editor/plugins/phasereditor2d.ide/src/IDEPlugin.ts +++ b/source/editor/plugins/phasereditor2d.ide/src/IDEPlugin.ts @@ -261,7 +261,7 @@ namespace phasereditor2d.ide { /* program entry point */ - export const VER = "3.36.2"; + export const VER = "3.60.0"; async function main() { diff --git a/source/editor/plugins/phasereditor2d.ide/src/core/code/CodeUtils.ts b/source/editor/plugins/phasereditor2d.ide/src/core/code/CodeUtils.ts index 23eec3fef..4932c4e3a 100644 --- a/source/editor/plugins/phasereditor2d.ide/src/core/code/CodeUtils.ts +++ b/source/editor/plugins/phasereditor2d.ide/src/core/code/CodeUtils.ts @@ -15,7 +15,7 @@ namespace phasereditor2d.ide.core.code { return "./" + importFile.getNameWithoutExtension(); } - if (importFilePath.startsWith(parentPath)) { + if (importFilePath.startsWith(parentPath + "/")) { return "./" + importFileElements.slice(parentElements.length).join("/"); } diff --git a/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AssetPackGrouping.ts b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AssetPackGrouping.ts index ba2b9774c..23c0c1b8a 100644 --- a/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AssetPackGrouping.ts +++ b/source/editor/plugins/phasereditor2d.pack/src/ui/viewers/AssetPackGrouping.ts @@ -25,7 +25,7 @@ namespace phasereditor2d.pack.ui.viewers { window.localStorage["phasereditor2d.scene.ui.blocks.SceneEditorBlocksProvider.assetGrouping"] = groupType; } - static getGroupingPreference() { + static getGroupingPreference(): string { return window.localStorage["phasereditor2d.scene.ui.blocks.SceneEditorBlocksProvider.assetGrouping"] || AssetPackGrouping.GROUP_ASSETS_BY_TYPE; diff --git a/source/editor/plugins/phasereditor2d.phaser/scripts/phaser.js b/source/editor/plugins/phasereditor2d.phaser/scripts/phaser.js old mode 100755 new mode 100644 index 296df62db..abcbac12f --- a/source/editor/plugins/phasereditor2d.phaser/scripts/phaser.js +++ b/source/editor/plugins/phasereditor2d.phaser/scripts/phaser.js @@ -7,22046 +7,23056 @@ exports["Phaser"] = factory(); else root["Phaser"] = factory(); -})(this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 1528); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { +})(this, () => { +return /******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ 6659: +/***/ ((module) => { + +"use strict"; + + +var has = Object.prototype.hasOwnProperty + , prefix = '~'; /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Constructor to create a storage for our `EE` objects. + * An `Events` instance is a plain object whose properties are event names. + * + * @constructor + * @private */ +function Events() {} -// Taken from klasse by mattdesl https://github.com/mattdesl/klasse +// +// We try to not inherit from `Object.prototype`. In some engines creating an +// instance in this way is faster than calling `Object.create(null)` directly. +// If `Object.create(null)` is not supported we prefix the event names with a +// character to make sure that the built-in object properties are not +// overridden or used as an attack vector. +// +if (Object.create) { + Events.prototype = Object.create(null); -function hasGetterOrSetter (def) -{ - return (!!def.get && typeof def.get === 'function') || (!!def.set && typeof def.set === 'function'); + // + // This hack is needed because the `__proto__` property is still inherited in + // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. + // + if (!new Events().__proto__) prefix = false; } -function getProperty (definition, k, isClassDescriptor) -{ - // This may be a lightweight object, OR it might be a property that was defined previously. +/** + * Representation of a single event listener. + * + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} [once=false] Specify if the listener is a one-time listener. + * @constructor + * @private + */ +function EE(fn, context, once) { + this.fn = fn; + this.context = context; + this.once = once || false; +} - // For simple class descriptors we can just assume its NOT previously defined. - var def = (isClassDescriptor) ? definition[k] : Object.getOwnPropertyDescriptor(definition, k); +/** + * Add a listener for a given event. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} context The context to invoke the listener with. + * @param {Boolean} once Specify if the listener is a one-time listener. + * @returns {EventEmitter} + * @private + */ +function addListener(emitter, event, fn, context, once) { + if (typeof fn !== 'function') { + throw new TypeError('The listener must be a function'); + } - if (!isClassDescriptor && def.value && typeof def.value === 'object') - { - def = def.value; - } + var listener = new EE(fn, context || emitter, once) + , evt = prefix ? prefix + event : event; - // This might be a regular property, or it may be a getter/setter the user defined in a class. - if (def && hasGetterOrSetter(def)) - { - if (typeof def.enumerable === 'undefined') - { - def.enumerable = true; - } + if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; + else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); + else emitter._events[evt] = [emitter._events[evt], listener]; - if (typeof def.configurable === 'undefined') - { - def.configurable = true; - } + return emitter; +} - return def; - } - else - { - return false; - } +/** + * Clear event by name. + * + * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. + * @param {(String|Symbol)} evt The Event name. + * @private + */ +function clearEvent(emitter, evt) { + if (--emitter._eventsCount === 0) emitter._events = new Events(); + else delete emitter._events[evt]; } -function hasNonConfigurable (obj, k) -{ - var prop = Object.getOwnPropertyDescriptor(obj, k); +/** + * Minimal `EventEmitter` interface that is molded against the Node.js + * `EventEmitter` interface. + * + * @constructor + * @public + */ +function EventEmitter() { + this._events = new Events(); + this._eventsCount = 0; +} - if (!prop) - { - return false; - } +/** + * Return an array listing the events for which the emitter has registered + * listeners. + * + * @returns {Array} + * @public + */ +EventEmitter.prototype.eventNames = function eventNames() { + var names = [] + , events + , name; - if (prop.value && typeof prop.value === 'object') - { - prop = prop.value; - } + if (this._eventsCount === 0) return names; - if (prop.configurable === false) - { - return true; - } + for (name in (events = this._events)) { + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); + } - return false; -} + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } + + return names; +}; /** - * Extends the given `myClass` object's prototype with the properties of `definition`. + * Return the listeners registered for a given event. * - * @function extend - * @ignore - * @param {Object} ctor The constructor object to mix into. - * @param {Object} definition A dictionary of functions for the class. - * @param {boolean} isClassDescriptor Is the definition a class descriptor? - * @param {Object} [extend] The parent constructor object. + * @param {(String|Symbol)} event The event name. + * @returns {Array} The registered listeners. + * @public */ -function extend (ctor, definition, isClassDescriptor, extend) -{ - for (var k in definition) - { - if (!definition.hasOwnProperty(k)) - { - continue; - } - - var def = getProperty(definition, k, isClassDescriptor); +EventEmitter.prototype.listeners = function listeners(event) { + var evt = prefix ? prefix + event : event + , handlers = this._events[evt]; - if (def !== false) - { - // If Extends is used, we will check its prototype to see if the final variable exists. + if (!handlers) return []; + if (handlers.fn) return [handlers.fn]; - var parent = extend || ctor; + for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { + ee[i] = handlers[i].fn; + } - if (hasNonConfigurable(parent.prototype, k)) - { - // Just skip the final property - if (Class.ignoreFinals) - { - continue; - } + return ee; +}; - // We cannot re-define a property that is configurable=false. - // So we will consider them final and throw an error. This is by - // default so it is clear to the developer what is happening. - // You can set ignoreFinals to true if you need to extend a class - // which has configurable=false; it will simply not re-define final properties. - throw new Error('cannot override final property \'' + k + '\', set Class.ignoreFinals = true to skip'); - } +/** + * Return the number of listeners listening to a given event. + * + * @param {(String|Symbol)} event The event name. + * @returns {Number} The number of listeners. + * @public + */ +EventEmitter.prototype.listenerCount = function listenerCount(event) { + var evt = prefix ? prefix + event : event + , listeners = this._events[evt]; - Object.defineProperty(ctor.prototype, k, def); - } - else - { - ctor.prototype[k] = definition[k]; - } - } -} + if (!listeners) return 0; + if (listeners.fn) return 1; + return listeners.length; +}; /** - * Applies the given `mixins` to the prototype of `myClass`. + * Calls each of the listeners registered for a given event. * - * @function mixin - * @ignore - * @param {Object} myClass The constructor object to mix into. - * @param {Object|Array} mixins The mixins to apply to the constructor. + * @param {(String|Symbol)} event The event name. + * @returns {Boolean} `true` if the event had listeners, else `false`. + * @public */ -function mixin (myClass, mixins) -{ - if (!mixins) - { - return; +EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { + var evt = prefix ? prefix + event : event; + + if (!this._events[evt]) return false; + + var listeners = this._events[evt] + , len = arguments.length + , args + , i; + + if (listeners.fn) { + if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); + + switch (len) { + case 1: return listeners.fn.call(listeners.context), true; + case 2: return listeners.fn.call(listeners.context, a1), true; + case 3: return listeners.fn.call(listeners.context, a1, a2), true; + case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; + case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; + case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; } - if (!Array.isArray(mixins)) - { - mixins = [ mixins ]; + for (i = 1, args = new Array(len -1); i < len; i++) { + args[i - 1] = arguments[i]; } - for (var i = 0; i < mixins.length; i++) - { - extend(myClass, mixins[i].prototype || mixins[i]); + listeners.fn.apply(listeners.context, args); + } else { + var length = listeners.length + , j; + + for (i = 0; i < length; i++) { + if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); + + switch (len) { + case 1: listeners[i].fn.call(listeners[i].context); break; + case 2: listeners[i].fn.call(listeners[i].context, a1); break; + case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; + case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; + default: + if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { + args[j - 1] = arguments[j]; + } + + listeners[i].fn.apply(listeners[i].context, args); + } } -} + } + + return true; +}; /** - * Creates a new class with the given descriptor. - * The constructor, defined by the name `initialize`, - * is an optional function. If unspecified, an anonymous - * function will be used which calls the parent class (if - * one exists). - * - * You can also use `Extends` and `Mixins` to provide subclassing - * and inheritance. - * - * @class Phaser.Class - * @constructor - * @param {Object} definition a dictionary of functions for the class - * @example - * - * var MyClass = new Phaser.Class({ - * - * initialize: function() { - * this.foo = 2.0; - * }, + * Add a listener for a given event. * - * bar: function() { - * return this.foo + 5; - * } - * }); + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public */ -function Class (definition) -{ - if (!definition) - { - definition = {}; - } +EventEmitter.prototype.on = function on(event, fn, context) { + return addListener(this, event, fn, context, false); +}; - // The variable name here dictates what we see in Chrome debugger - var initialize; - var Extends; +/** + * Add a one-time listener for a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.once = function once(event, fn, context) { + return addListener(this, event, fn, context, true); +}; - if (definition.initialize) - { - if (typeof definition.initialize !== 'function') - { - throw new Error('initialize must be a function'); - } +/** + * Remove the listeners of a given event. + * + * @param {(String|Symbol)} event The event name. + * @param {Function} fn Only remove the listeners that match this function. + * @param {*} context Only remove the listeners that have this context. + * @param {Boolean} once Only remove one-time listeners. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { + var evt = prefix ? prefix + event : event; - initialize = definition.initialize; + if (!this._events[evt]) return this; + if (!fn) { + clearEvent(this, evt); + return this; + } - // Usually we should avoid 'delete' in V8 at all costs. - // However, its unlikely to make any performance difference - // here since we only call this on class creation (i.e. not object creation). - delete definition.initialize; - } - else if (definition.Extends) - { - var base = definition.Extends; + var listeners = this._events[evt]; - initialize = function () - { - base.apply(this, arguments); - }; + if (listeners.fn) { + if ( + listeners.fn === fn && + (!once || listeners.once) && + (!context || listeners.context === context) + ) { + clearEvent(this, evt); } - else - { - initialize = function () {}; + } else { + for (var i = 0, events = [], length = listeners.length; i < length; i++) { + if ( + listeners[i].fn !== fn || + (once && !listeners[i].once) || + (context && listeners[i].context !== context) + ) { + events.push(listeners[i]); + } } - if (definition.Extends) - { - initialize.prototype = Object.create(definition.Extends.prototype); - initialize.prototype.constructor = initialize; + // + // Reset the array, or remove it completely if we have no more listeners. + // + if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; + else clearEvent(this, evt); + } - // For getOwnPropertyDescriptor to work, we need to act directly on the Extends (or Mixin) + return this; +}; - Extends = definition.Extends; +/** + * Remove all listeners, or those of the specified event. + * + * @param {(String|Symbol)} [event] The event name. + * @returns {EventEmitter} `this`. + * @public + */ +EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { + var evt; - delete definition.Extends; - } - else - { - initialize.prototype.constructor = initialize; - } + if (event) { + evt = prefix ? prefix + event : event; + if (this._events[evt]) clearEvent(this, evt); + } else { + this._events = new Events(); + this._eventsCount = 0; + } - // Grab the mixins, if they are specified... - var mixins = null; + return this; +}; - if (definition.Mixins) - { - mixins = definition.Mixins; - delete definition.Mixins; - } +// +// Alias methods names because people roll like that. +// +EventEmitter.prototype.off = EventEmitter.prototype.removeListener; +EventEmitter.prototype.addListener = EventEmitter.prototype.on; - // First, mixin if we can. - mixin(initialize, mixins); +// +// Expose the prefix. +// +EventEmitter.prefixed = prefix; - // Now we grab the actual definition which defines the overrides. - extend(initialize, definition, true, Extends); +// +// Allow `EventEmitter` to be imported as module namespace. +// +EventEmitter.EventEmitter = EventEmitter; - return initialize; +// +// Expose the module. +// +if (true) { + module.exports = EventEmitter; } -Class.extend = extend; -Class.mixin = mixin; -Class.ignoreFinals = false; -module.exports = Class; +/***/ }), + +/***/ 62270: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var QuickSet = __webpack_require__(82590); + +/** + * Takes an array of Game Objects, or any objects that have public `x` and `y` properties, and aligns them next to each other. + * + * The first item isn't moved. The second item is aligned next to the first, then the third next to the second, and so on. + * + * @function Phaser.Actions.AlignTo + * @since 3.22.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} position - The position to align the items with. This is an align constant, such as `Phaser.Display.Align.LEFT_CENTER`. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var AlignTo = function (items, position, offsetX, offsetY) +{ + var target = items[0]; + + for (var i = 1; i < items.length; i++) + { + var item = items[i]; + + QuickSet(item, target, position, offsetX, offsetY); + + target = item; + } + + return items; +}; + +module.exports = AlignTo; /***/ }), -/* 1 */ -/***/ (function(module, exports) { + +/***/ 61148: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var PropertyValueInc = __webpack_require__(6124); + /** - * A NOOP (No Operation) callback function. + * Takes an array of Game Objects, or any objects that have a public `angle` property, + * and then adds the given value to each of their `angle` properties. * - * Used internally by Phaser when it's more expensive to determine if a callback exists - * than it is to just invoke an empty function. + * The optional `step` property is applied incrementally, multiplied by each item in the array. * - * @function Phaser.Utils.NOOP + * To use this with a Group: `Angle(group.getChildren(), value, step)` + * + * @function Phaser.Actions.Angle * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to be added to the `angle` property. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ -var NOOP = function () +var Angle = function (items, value, step, index, direction) { - // NOOP + return PropertyValueInc(items, 'angle', value, step, index, direction); }; -module.exports = NOOP; +module.exports = Angle; /***/ }), -/* 2 */ -/***/ (function(module, exports) { + +/***/ 22015: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Finds the key within the top level of the {@link source} object, or returns {@link defaultValue} + * Takes an array of objects and passes each of them to the given callback. * - * @function Phaser.Utils.Objects.GetFastValue + * @function Phaser.Actions.Call * @since 3.0.0 * - * @param {object} source - The object to search - * @param {string} key - The key for the property on source. Must exist at the top level of the source object (no periods) - * @param {*} [defaultValue] - The default value to use if the key does not exist. + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] * - * @return {*} The value if found; otherwise, defaultValue (null if none provided) + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {Phaser.Types.Actions.CallCallback} callback - The callback to be invoked. It will be passed just one argument: the item from the array. + * @param {*} context - The scope in which the callback will be invoked. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that was passed to this Action. */ -var GetFastValue = function (source, key, defaultValue) +var Call = function (items, callback, context) { - var t = typeof(source); - - if (!source || t === 'number' || t === 'string') - { - return defaultValue; - } - else if (source.hasOwnProperty(key) && source[key] !== undefined) - { - return source[key]; - } - else + for (var i = 0; i < items.length; i++) { - return defaultValue; + var item = items[i]; + + callback.call(context, item); } + + return items; }; -module.exports = GetFastValue; +module.exports = Call; /***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 31060: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji -// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl - -var Class = __webpack_require__(0); -var FuzzyEqual = __webpack_require__(124); - /** - * @classdesc - * A representation of a vector in 2D space. + * Takes an array of objects and returns the first element in the array that has properties which match + * all of those specified in the `compare` object. For example, if the compare object was: `{ scaleX: 0.5, alpha: 1 }` + * then it would return the first item which had the property `scaleX` set to 0.5 and `alpha` set to 1. * - * A two-component vector. + * To use this with a Group: `GetFirst(group.getChildren(), compare, index)` * - * @class Vector2 - * @memberof Phaser.Math - * @constructor + * @function Phaser.Actions.GetFirst * @since 3.0.0 * - * @param {number|Phaser.Types.Math.Vector2Like} [x] - The x component, or an object with `x` and `y` properties. - * @param {number} [y] - The y component. + * @generic {Phaser.GameObjects.GameObject[]} G - [items] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be searched by this action. + * @param {object} compare - The comparison object. Each property in this object will be checked against the items of the array. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * + * @return {?(object|Phaser.GameObjects.GameObject)} The first object in the array that matches the comparison object, or `null` if no match was found. */ -var Vector2 = new Class({ - - initialize: +var GetFirst = function (items, compare, index) +{ + if (index === undefined) { index = 0; } - function Vector2 (x, y) + for (var i = index; i < items.length; i++) { - /** - * The x component of this Vector. - * - * @name Phaser.Math.Vector2#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.x = 0; + var item = items[i]; - /** - * The y component of this Vector. - * - * @name Phaser.Math.Vector2#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.y = 0; + var match = true; - if (typeof x === 'object') + for (var property in compare) { - this.x = x.x || 0; - this.y = x.y || 0; + if (item[property] !== compare[property]) + { + match = false; + } } - else - { - if (y === undefined) { y = x; } - this.x = x || 0; - this.y = y || 0; + if (match) + { + return item; } - }, - - /** - * Make a clone of this Vector2. - * - * @method Phaser.Math.Vector2#clone - * @since 3.0.0 - * - * @return {Phaser.Math.Vector2} A clone of this Vector2. - */ - clone: function () - { - return new Vector2(this.x, this.y); - }, + } - /** - * Copy the components of a given Vector into this Vector. - * - * @method Phaser.Math.Vector2#copy - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector to copy the components from. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - copy: function (src) - { - this.x = src.x || 0; - this.y = src.y || 0; + return null; +}; - return this; - }, +module.exports = GetFirst; - /** - * Set the component values of this Vector from a given Vector2Like object. - * - * @method Phaser.Math.Vector2#setFromObject - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} obj - The object containing the component values to set for this Vector. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - setFromObject: function (obj) - { - this.x = obj.x || 0; - this.y = obj.y || 0; - return this; - }, +/***/ }), - /** - * Set the `x` and `y` components of the this Vector to the given `x` and `y` values. - * - * @method Phaser.Math.Vector2#set - * @since 3.0.0 - * - * @param {number} x - The x value to set for this Vector. - * @param {number} [y=x] - The y value to set for this Vector. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - set: function (x, y) - { - if (y === undefined) { y = x; } +/***/ 52367: +/***/ ((module) => { - this.x = x; - this.y = y; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +/** + * Takes an array of objects and returns the last element in the array that has properties which match + * all of those specified in the `compare` object. For example, if the compare object was: `{ scaleX: 0.5, alpha: 1 }` + * then it would return the last item which had the property `scaleX` set to 0.5 and `alpha` set to 1. + * + * To use this with a Group: `GetLast(group.getChildren(), compare, index)` + * + * @function Phaser.Actions.GetLast + * @since 3.3.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be searched by this action. + * @param {object} compare - The comparison object. Each property in this object will be checked against the items of the array. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * + * @return {?(object|Phaser.GameObjects.GameObject)} The last object in the array that matches the comparison object, or `null` if no match was found. + */ +var GetLast = function (items, compare, index) +{ + if (index === undefined) { index = 0; } - /** - * This method is an alias for `Vector2.set`. - * - * @method Phaser.Math.Vector2#setTo - * @since 3.4.0 - * - * @param {number} x - The x value to set for this Vector. - * @param {number} [y=x] - The y value to set for this Vector. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - setTo: function (x, y) + for (var i = index; i < items.length; i++) { - return this.set(x, y); - }, + var item = items[i]; - /** - * Sets the `x` and `y` values of this object from a given polar coordinate. - * - * @method Phaser.Math.Vector2#setToPolar - * @since 3.0.0 - * - * @param {number} azimuth - The angular coordinate, in radians. - * @param {number} [radius=1] - The radial coordinate (length). - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - setToPolar: function (azimuth, radius) - { - if (radius == null) { radius = 1; } + var match = true; - this.x = Math.cos(azimuth) * radius; - this.y = Math.sin(azimuth) * radius; + for (var property in compare) + { + if (item[property] !== compare[property]) + { + match = false; + } + } - return this; - }, + if (match) + { + return item; + } + } - /** - * Check whether this Vector is equal to a given Vector. - * - * Performs a strict equality check against each Vector's components. - * - * @method Phaser.Math.Vector2#equals - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector. - * - * @return {boolean} Whether the given Vector is equal to this Vector. - */ - equals: function (v) - { - return ((this.x === v.x) && (this.y === v.y)); - }, + return null; +}; - /** - * Check whether this Vector is approximately equal to a given Vector. - * - * @method Phaser.Math.Vector2#fuzzyEquals - * @since 3.23.0 - * - * @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector. - * @param {number} [epsilon=0.0001] - The tolerance value. - * - * @return {boolean} Whether both absolute differences of the x and y components are smaller than `epsilon`. - */ - fuzzyEquals: function (v, epsilon) - { - return (FuzzyEqual(this.x, v.x, epsilon) && FuzzyEqual(this.y, v.y, epsilon)); - }, +module.exports = GetLast; - /** - * Calculate the angle between this Vector and the positive x-axis, in radians. - * - * @method Phaser.Math.Vector2#angle - * @since 3.0.0 - * - * @return {number} The angle between this Vector, and the positive x-axis, given in radians. - */ - angle: function () - { - // computes the angle in radians with respect to the positive x-axis - var angle = Math.atan2(this.y, this.x); +/***/ }), - if (angle < 0) - { - angle += 2 * Math.PI; - } +/***/ 12673: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return angle; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Set the angle of this Vector. - * - * @method Phaser.Math.Vector2#setAngle - * @since 3.23.0 - * - * @param {number} angle - The angle, in radians. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - setAngle: function (angle) - { - return this.setToPolar(angle, this.length()); - }, +var AlignIn = __webpack_require__(40327); +var CONST = __webpack_require__(84093); +var GetFastValue = __webpack_require__(72632); +var NOOP = __webpack_require__(72283); +var Zone = __webpack_require__(71030); - /** - * Add a given Vector to this Vector. Addition is component-wise. - * - * @method Phaser.Math.Vector2#add - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector to add to this Vector. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - add: function (src) - { - this.x += src.x; - this.y += src.y; +var tempZone = new Zone({ sys: { queueDepthSort: NOOP, events: { once: NOOP } } }, 0, 0, 1, 1).setOrigin(0, 0); - return this; - }, +/** + * Takes an array of Game Objects, or any objects that have public `x` and `y` properties, + * and then aligns them based on the grid configuration given to this action. + * + * @function Phaser.Actions.GridAlign + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {Phaser.Types.Actions.GridAlignConfig} options - The GridAlign Configuration object. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var GridAlign = function (items, options) +{ + if (options === undefined) { options = {}; } - /** - * Subtract the given Vector from this Vector. Subtraction is component-wise. - * - * @method Phaser.Math.Vector2#subtract - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector to subtract from this Vector. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - subtract: function (src) - { - this.x -= src.x; - this.y -= src.y; + var widthSet = options.hasOwnProperty('width'); + var heightSet = options.hasOwnProperty('height'); - return this; - }, + var width = GetFastValue(options, 'width', -1); + var height = GetFastValue(options, 'height', -1); - /** - * Perform a component-wise multiplication between this Vector and the given Vector. - * - * Multiplies this Vector by the given Vector. - * - * @method Phaser.Math.Vector2#multiply - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector to multiply this Vector by. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - multiply: function (src) - { - this.x *= src.x; - this.y *= src.y; + var cellWidth = GetFastValue(options, 'cellWidth', 1); + var cellHeight = GetFastValue(options, 'cellHeight', cellWidth); - return this; - }, + var position = GetFastValue(options, 'position', CONST.TOP_LEFT); + var x = GetFastValue(options, 'x', 0); + var y = GetFastValue(options, 'y', 0); - /** - * Scale this Vector by the given value. - * - * @method Phaser.Math.Vector2#scale - * @since 3.0.0 - * - * @param {number} value - The value to scale this Vector by. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - scale: function (value) + var cx = 0; + var cy = 0; + var w = (width * cellWidth); + var h = (height * cellHeight); + + tempZone.setPosition(x, y); + tempZone.setSize(cellWidth, cellHeight); + + for (var i = 0; i < items.length; i++) { - if (isFinite(value)) + AlignIn(items[i], tempZone, position); + + if (widthSet && width === -1) { - this.x *= value; - this.y *= value; + // We keep laying them out horizontally until we've done them all + tempZone.x += cellWidth; } - else + else if (heightSet && height === -1) { - this.x = 0; - this.y = 0; + // We keep laying them out vertically until we've done them all + tempZone.y += cellHeight; } + else if (heightSet && !widthSet) + { + // We keep laying them out until we hit the column limit + cy += cellHeight; + tempZone.y += cellHeight; - return this; - }, - - /** - * Perform a component-wise division between this Vector and the given Vector. - * - * Divides this Vector by the given Vector. - * - * @method Phaser.Math.Vector2#divide - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector to divide this Vector by. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - divide: function (src) - { - this.x /= src.x; - this.y /= src.y; - - return this; - }, + if (cy === h) + { + cy = 0; + cx += cellWidth; + tempZone.y = y; + tempZone.x += cellWidth; - /** - * Negate the `x` and `y` components of this Vector. - * - * @method Phaser.Math.Vector2#negate - * @since 3.0.0 - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - negate: function () - { - this.x = -this.x; - this.y = -this.y; - - return this; - }, - - /** - * Calculate the distance between this Vector and the given Vector. - * - * @method Phaser.Math.Vector2#distance - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to. - * - * @return {number} The distance from this Vector to the given Vector. - */ - distance: function (src) - { - var dx = src.x - this.x; - var dy = src.y - this.y; - - return Math.sqrt(dx * dx + dy * dy); - }, - - /** - * Calculate the distance between this Vector and the given Vector, squared. - * - * @method Phaser.Math.Vector2#distanceSq - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to. - * - * @return {number} The distance from this Vector to the given Vector, squared. - */ - distanceSq: function (src) - { - var dx = src.x - this.x; - var dy = src.y - this.y; - - return dx * dx + dy * dy; - }, - - /** - * Calculate the length (or magnitude) of this Vector. - * - * @method Phaser.Math.Vector2#length - * @since 3.0.0 - * - * @return {number} The length of this Vector. - */ - length: function () - { - var x = this.x; - var y = this.y; - - return Math.sqrt(x * x + y * y); - }, - - /** - * Set the length (or magnitude) of this Vector. - * - * @method Phaser.Math.Vector2#setLength - * @since 3.23.0 - * - * @param {number} length - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - setLength: function (length) - { - return this.normalize().scale(length); - }, - - /** - * Calculate the length of this Vector squared. - * - * @method Phaser.Math.Vector2#lengthSq - * @since 3.0.0 - * - * @return {number} The length of this Vector, squared. - */ - lengthSq: function () - { - var x = this.x; - var y = this.y; - - return x * x + y * y; - }, - - /** - * Normalize this Vector. - * - * Makes the vector a unit length vector (magnitude of 1) in the same direction. - * - * @method Phaser.Math.Vector2#normalize - * @since 3.0.0 - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - normalize: function () - { - var x = this.x; - var y = this.y; - var len = x * x + y * y; - - if (len > 0) - { - len = 1 / Math.sqrt(len); - - this.x = x * len; - this.y = y * len; + if (cx === w) + { + // We've hit the column limit, so return, even if there are items left + break; + } + } } + else + { + // We keep laying them out until we hit the column limit + cx += cellWidth; + tempZone.x += cellWidth; - return this; - }, - - /** - * Rotate this Vector to its perpendicular, in the positive direction. - * - * @method Phaser.Math.Vector2#normalizeRightHand - * @since 3.0.0 - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - normalizeRightHand: function () - { - var x = this.x; + if (cx === w) + { + cx = 0; + cy += cellHeight; + tempZone.x = x; + tempZone.y += cellHeight; - this.x = this.y * -1; - this.y = x; + if (cy === h) + { + // We've hit the column limit, so return, even if there are items left + break; + } + } + } + } - return this; - }, + return items; +}; - /** - * Rotate this Vector to its perpendicular, in the negative direction. - * - * @method Phaser.Math.Vector2#normalizeLeftHand - * @since 3.23.0 - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - normalizeLeftHand: function () - { - var x = this.x; +module.exports = GridAlign; - this.x = this.y; - this.y = x * -1; - return this; - }, +/***/ }), - /** - * Calculate the dot product of this Vector and the given Vector. - * - * @method Phaser.Math.Vector2#dot - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to dot product with this Vector2. - * - * @return {number} The dot product of this Vector and the given Vector. - */ - dot: function (src) - { - return this.x * src.x + this.y * src.y; - }, +/***/ 691: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Calculate the cross product of this Vector and the given Vector. - * - * @method Phaser.Math.Vector2#cross - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to cross with this Vector2. - * - * @return {number} The cross product of this Vector and the given Vector. - */ - cross: function (src) - { - return this.x * src.y - this.y * src.x; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Linearly interpolate between this Vector and the given Vector. - * - * Interpolates this Vector towards the given Vector. - * - * @method Phaser.Math.Vector2#lerp - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to interpolate towards. - * @param {number} [t=0] - The interpolation percentage, between 0 and 1. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - lerp: function (src, t) - { - if (t === undefined) { t = 0; } +var PropertyValueInc = __webpack_require__(6124); - var ax = this.x; - var ay = this.y; +/** + * Takes an array of Game Objects, or any objects that have a public `alpha` property, + * and then adds the given value to each of their `alpha` properties. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `IncAlpha(group.getChildren(), value, step)` + * + * @function Phaser.Actions.IncAlpha + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to be added to the `alpha` property. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var IncAlpha = function (items, value, step, index, direction) +{ + return PropertyValueInc(items, 'alpha', value, step, index, direction); +}; - this.x = ax + t * (src.x - ax); - this.y = ay + t * (src.y - ay); +module.exports = IncAlpha; - return this; - }, - /** - * Transform this Vector with the given Matrix. - * - * @method Phaser.Math.Vector2#transformMat3 - * @since 3.0.0 - * - * @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector2 with. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - transformMat3: function (mat) - { - var x = this.x; - var y = this.y; - var m = mat.val; +/***/ }), - this.x = m[0] * x + m[3] * y + m[6]; - this.y = m[1] * x + m[4] * y + m[7]; +/***/ 3877: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Transform this Vector with the given Matrix. - * - * @method Phaser.Math.Vector2#transformMat4 - * @since 3.0.0 - * - * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector2 with. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - transformMat4: function (mat) - { - var x = this.x; - var y = this.y; - var m = mat.val; +var PropertyValueInc = __webpack_require__(6124); - this.x = m[0] * x + m[4] * y + m[12]; - this.y = m[1] * x + m[5] * y + m[13]; +/** + * Takes an array of Game Objects, or any objects that have a public `x` property, + * and then adds the given value to each of their `x` properties. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `IncX(group.getChildren(), value, step)` + * + * @function Phaser.Actions.IncX + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to be added to the `x` property. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var IncX = function (items, value, step, index, direction) +{ + return PropertyValueInc(items, 'x', value, step, index, direction); +}; - return this; - }, +module.exports = IncX; - /** - * Make this Vector the zero vector (0, 0). - * - * @method Phaser.Math.Vector2#reset - * @since 3.0.0 - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - reset: function () - { - this.x = 0; - this.y = 0; - return this; - }, +/***/ }), - /** - * Limit the length (or magnitude) of this Vector. - * - * @method Phaser.Math.Vector2#limit - * @since 3.23.0 - * - * @param {number} max - The maximum length. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - limit: function (max) - { - var len = this.length(); +/***/ 71020: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (len && len > max) - { - this.scale(max / len); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +var PropertyValueInc = __webpack_require__(6124); - /** - * Reflect this Vector off a line defined by a normal. - * - * @method Phaser.Math.Vector2#reflect - * @since 3.23.0 - * - * @param {Phaser.Math.Vector2} normal - A vector perpendicular to the line. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - reflect: function (normal) - { - normal = normal.clone().normalize(); +/** + * Takes an array of Game Objects, or any objects that have public `x` and `y` properties, + * and then adds the given value to each of them. + * + * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `IncXY(group.getChildren(), x, y, stepX, stepY)` + * + * @function Phaser.Actions.IncXY + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} x - The amount to be added to the `x` property. + * @param {number} [y=x] - The amount to be added to the `y` property. If `undefined` or `null` it uses the `x` value. + * @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var IncXY = function (items, x, y, stepX, stepY, index, direction) +{ + if (y === undefined || y === null) { y = x; } - return this.subtract(normal.scale(2 * this.dot(normal))); - }, + PropertyValueInc(items, 'x', x, stepX, index, direction); - /** - * Reflect this Vector across another. - * - * @method Phaser.Math.Vector2#mirror - * @since 3.23.0 - * - * @param {Phaser.Math.Vector2} axis - A vector to reflect across. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - mirror: function (axis) - { - return this.reflect(axis).negate(); - }, + return PropertyValueInc(items, 'y', y, stepY, index, direction); +}; - /** - * Rotate this Vector by an angle amount. - * - * @method Phaser.Math.Vector2#rotate - * @since 3.23.0 - * - * @param {number} delta - The angle to rotate by, in radians. - * - * @return {Phaser.Math.Vector2} This Vector2. - */ - rotate: function (delta) - { - var cos = Math.cos(delta); - var sin = Math.sin(delta); +module.exports = IncXY; - return this.set(cos * this.x - sin * this.y, sin * this.x + cos * this.y); - } -}); +/***/ }), -/** - * A static zero Vector2 for use by reference. - * - * This constant is meant for comparison operations and should not be modified directly. - * - * @constant - * @name Phaser.Math.Vector2.ZERO - * @type {Phaser.Math.Vector2} - * @since 3.1.0 - */ -Vector2.ZERO = new Vector2(); +/***/ 28970: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * A static right Vector2 for use by reference. - * - * This constant is meant for comparison operations and should not be modified directly. - * - * @constant - * @name Phaser.Math.Vector2.RIGHT - * @type {Phaser.Math.Vector2} - * @since 3.16.0 + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -Vector2.RIGHT = new Vector2(1, 0); -/** - * A static left Vector2 for use by reference. - * - * This constant is meant for comparison operations and should not be modified directly. - * - * @constant - * @name Phaser.Math.Vector2.LEFT - * @type {Phaser.Math.Vector2} - * @since 3.16.0 - */ -Vector2.LEFT = new Vector2(-1, 0); +var PropertyValueInc = __webpack_require__(6124); /** - * A static up Vector2 for use by reference. + * Takes an array of Game Objects, or any objects that have a public `y` property, + * and then adds the given value to each of their `y` properties. * - * This constant is meant for comparison operations and should not be modified directly. + * The optional `step` property is applied incrementally, multiplied by each item in the array. * - * @constant - * @name Phaser.Math.Vector2.UP - * @type {Phaser.Math.Vector2} - * @since 3.16.0 - */ -Vector2.UP = new Vector2(0, -1); - -/** - * A static down Vector2 for use by reference. + * To use this with a Group: `IncY(group.getChildren(), value, step)` * - * This constant is meant for comparison operations and should not be modified directly. + * @function Phaser.Actions.IncY + * @since 3.0.0 * - * @constant - * @name Phaser.Math.Vector2.DOWN - * @type {Phaser.Math.Vector2} - * @since 3.16.0 - */ -Vector2.DOWN = new Vector2(0, 1); - -/** - * A static one Vector2 for use by reference. + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] * - * This constant is meant for comparison operations and should not be modified directly. + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to be added to the `y` property. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. * - * @constant - * @name Phaser.Math.Vector2.ONE - * @type {Phaser.Math.Vector2} - * @since 3.16.0 + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ -Vector2.ONE = new Vector2(1, 1); +var IncY = function (items, value, step, index, direction) +{ + return PropertyValueInc(items, 'y', value, step, index, direction); +}; -module.exports = Vector2; +module.exports = IncY; /***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 82249: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GEOM_CONST = __webpack_require__(56); - /** - * @classdesc - * Defines a Point in 2D space, with an x and y component. + * Takes an array of Game Objects and positions them on evenly spaced points around the perimeter of a Circle. * - * @class Point - * @memberof Phaser.Geom - * @constructor + * If you wish to pass a `Phaser.GameObjects.Circle` Shape to this function, you should pass its `geom` property. + * + * @function Phaser.Actions.PlaceOnCircle * @since 3.0.0 * - * @param {number} [x=0] - The x coordinate of this Point. - * @param {number} [y=x] - The y coordinate of this Point. + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Circle} circle - The Circle to position the Game Objects on. + * @param {number} [startAngle=0] - Optional angle to start position from, in radians. + * @param {number} [endAngle=6.28] - Optional angle to stop position at, in radians. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -var Point = new Class({ - - initialize: - - function Point (x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } - - /** - * The geometry constant type of this object: `GEOM_CONST.POINT`. - * Used for fast type comparisons. - * - * @name Phaser.Geom.Point#type - * @type {number} - * @readonly - * @since 3.19.0 - */ - this.type = GEOM_CONST.POINT; +var PlaceOnCircle = function (items, circle, startAngle, endAngle) +{ + if (startAngle === undefined) { startAngle = 0; } + if (endAngle === undefined) { endAngle = 6.28; } - /** - * The x coordinate of this Point. - * - * @name Phaser.Geom.Point#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.x = x; + var angle = startAngle; + var angleStep = (endAngle - startAngle) / items.length; - /** - * The y coordinate of this Point. - * - * @name Phaser.Geom.Point#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.y = y; - }, + var cx = circle.x; + var cy = circle.y; + var radius = circle.radius; - /** - * Set the x and y coordinates of the point to the given values. - * - * @method Phaser.Geom.Point#setTo - * @since 3.0.0 - * - * @param {number} [x=0] - The x coordinate of this Point. - * @param {number} [y=x] - The y coordinate of this Point. - * - * @return {this} This Point object. - */ - setTo: function (x, y) + for (var i = 0; i < items.length; i++) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } - - this.x = x; - this.y = y; + items[i].x = cx + (radius * Math.cos(angle)); + items[i].y = cy + (radius * Math.sin(angle)); - return this; + angle += angleStep; } -}); + return items; +}; -module.exports = Point; +module.exports = PlaceOnCircle; /***/ }), -/* 5 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 30285: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var PluginCache = __webpack_require__(24); -var SceneEvents = __webpack_require__(20); - /** - * @classdesc - * The Game Object Factory is a Scene plugin that allows you to quickly create many common - * types of Game Objects and have them automatically registered with the Scene. - * - * Game Objects directly register themselves with the Factory and inject their own creation - * methods into the class. + * Takes an array of Game Objects and positions them on evenly spaced points around the perimeter of an Ellipse. + * + * If you wish to pass a `Phaser.GameObjects.Ellipse` Shape to this function, you should pass its `geom` property. * - * @class GameObjectFactory - * @memberof Phaser.GameObjects - * @constructor + * @function Phaser.Actions.PlaceOnEllipse * @since 3.0.0 * - * @param {Phaser.Scene} scene - The Scene to which this Game Object Factory belongs. + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to position the Game Objects on. + * @param {number} [startAngle=0] - Optional angle to start position from, in radians. + * @param {number} [endAngle=6.28] - Optional angle to stop position at, in radians. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -var GameObjectFactory = new Class({ +var PlaceOnEllipse = function (items, ellipse, startAngle, endAngle) +{ + if (startAngle === undefined) { startAngle = 0; } + if (endAngle === undefined) { endAngle = 6.28; } - initialize: + var angle = startAngle; + var angleStep = (endAngle - startAngle) / items.length; - function GameObjectFactory (scene) + var a = ellipse.width / 2; + var b = ellipse.height / 2; + + for (var i = 0; i < items.length; i++) { - /** - * The Scene to which this Game Object Factory belongs. - * - * @name Phaser.GameObjects.GameObjectFactory#scene - * @type {Phaser.Scene} - * @protected - * @since 3.0.0 - */ - this.scene = scene; + items[i].x = ellipse.x + a * Math.cos(angle); + items[i].y = ellipse.y + b * Math.sin(angle); - /** - * A reference to the Scene.Systems. - * - * @name Phaser.GameObjects.GameObjectFactory#systems - * @type {Phaser.Scenes.Systems} - * @protected - * @since 3.0.0 - */ - this.systems = scene.sys; + angle += angleStep; + } - /** - * A reference to the Scene Event Emitter. - * - * @name Phaser.GameObjects.GameObjectFactory#events - * @type {Phaser.Events.EventEmitter} - * @protected - * @since 3.50.0 - */ - this.events = scene.sys.events; + return items; +}; - /** - * A reference to the Scene Display List. - * - * @name Phaser.GameObjects.GameObjectFactory#displayList - * @type {Phaser.GameObjects.DisplayList} - * @protected - * @since 3.0.0 - */ - this.displayList; +module.exports = PlaceOnEllipse; - /** - * A reference to the Scene Update List. - * - * @name Phaser.GameObjects.GameObjectFactory#updateList - * @type {Phaser.GameObjects.UpdateList} - * @protected - * @since 3.0.0 - */ - this.updateList; - this.events.once(SceneEvents.BOOT, this.boot, this); - this.events.on(SceneEvents.START, this.start, this); - }, +/***/ }), - /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. - * - * @method Phaser.GameObjects.GameObjectFactory#boot - * @private - * @since 3.5.1 - */ - boot: function () - { - this.displayList = this.systems.displayList; - this.updateList = this.systems.updateList; +/***/ 61557: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.events.once(SceneEvents.DESTROY, this.destroy, this); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. - * - * @method Phaser.GameObjects.GameObjectFactory#start - * @private - * @since 3.5.0 - */ - start: function () - { - this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); - }, +var GetPoints = __webpack_require__(8570); - /** - * Adds an existing Game Object to this Scene. - * - * If the Game Object renders, it will be added to the Display List. - * If it has a `preUpdate` method, it will be added to the Update List. - * - * @method Phaser.GameObjects.GameObjectFactory#existing - * @since 3.0.0 - * - * @generic {(Phaser.GameObjects.GameObject|Phaser.GameObjects.Group|Phaser.GameObjects.Layer)} G - [child,$return] - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.Group|Phaser.GameObjects.Layer)} child - The child to be added to this Scene. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was added. - */ - existing: function (child) +/** + * Positions an array of Game Objects on evenly spaced points of a Line. + * + * @function Phaser.Actions.PlaceOnLine + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Line} line - The Line to position the Game Objects on. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + */ +var PlaceOnLine = function (items, line) +{ + var points = GetPoints(line, items.length); + + for (var i = 0; i < items.length; i++) { - if (child.renderCanvas || child.renderWebGL) - { - this.displayList.add(child); - } + var item = items[i]; + var point = points[i]; - // For when custom objects have overridden `preUpdate` but don't hook into the ADDED_TO_SCENE event: - // Adding to the list multiple times is safe, as it won't add duplicates into the list anyway. - if (child.preUpdate) - { - this.updateList.add(child); - } + item.x = point.x; + item.y = point.y; + } - return child; - }, + return items; +}; - /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. - * - * @method Phaser.GameObjects.GameObjectFactory#shutdown - * @private - * @since 3.0.0 - */ - shutdown: function () - { - this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); - }, +module.exports = PlaceOnLine; - /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. - * - * @method Phaser.GameObjects.GameObjectFactory#destroy - * @private - * @since 3.0.0 - */ - destroy: function () - { - this.shutdown(); - this.events.off(SceneEvents.START, this.start, this); +/***/ }), - this.scene = null; - this.systems = null; - this.events = null; +/***/ 63549: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.displayList = null; - this.updateList = null; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -}); +var MarchingAnts = __webpack_require__(40053); +var RotateLeft = __webpack_require__(77640); +var RotateRight = __webpack_require__(38487); /** - * Static method called directly by the Game Object factory functions. - * With this method you can register a custom GameObject factory in the GameObjectFactory, - * providing a name (`factoryType`) and the constructor (`factoryFunction`) in order - * to be called when you call to Phaser.Scene.add[ factoryType ] method. + * Takes an array of Game Objects and positions them on evenly spaced points around the perimeter of a Rectangle. + * + * Placement starts from the top-left of the rectangle, and proceeds in a clockwise direction. + * If the `shift` parameter is given you can offset where placement begins. * - * @method Phaser.GameObjects.GameObjectFactory.register - * @static + * @function Phaser.Actions.PlaceOnRectangle * @since 3.0.0 * - * @param {string} factoryType - The key of the factory that you will use to call to Phaser.Scene.add[ factoryType ] method. - * @param {function} factoryFunction - The constructor function to be called when you invoke to the Phaser.Scene.add method. + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to position the Game Objects on. + * @param {number} [shift=0] - An optional positional offset. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -GameObjectFactory.register = function (factoryType, factoryFunction) +var PlaceOnRectangle = function (items, rect, shift) { - if (!GameObjectFactory.prototype.hasOwnProperty(factoryType)) + if (shift === undefined) { shift = 0; } + + var points = MarchingAnts(rect, false, items.length); + + if (shift > 0) { - GameObjectFactory.prototype[factoryType] = factoryFunction; + RotateLeft(points, shift); + } + else if (shift < 0) + { + RotateRight(points, Math.abs(shift)); } -}; -/** - * Static method called directly by the Game Object factory functions. - * With this method you can remove a custom GameObject factory registered in the GameObjectFactory, - * providing a its `factoryType`. - * - * @method Phaser.GameObjects.GameObjectFactory.remove - * @static - * @since 3.0.0 - * - * @param {string} factoryType - The key of the factory that you want to remove from the GameObjectFactory. - */ -GameObjectFactory.remove = function (factoryType) -{ - if (GameObjectFactory.prototype.hasOwnProperty(factoryType)) + for (var i = 0; i < items.length; i++) { - delete GameObjectFactory.prototype[factoryType]; + items[i].x = points[i].x; + items[i].y = points[i].y; } -}; -PluginCache.register('GameObjectFactory', GameObjectFactory, 'add'); + return items; +}; -module.exports = GameObjectFactory; +module.exports = PlaceOnRectangle; /***/ }), -/* 6 */ -/***/ (function(module, exports) { + +/***/ 51629: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// Source object -// The key as a string, or an array of keys, i.e. 'banner', or 'banner.hideBanner' -// The default value to use if the key doesn't exist +var BresenhamPoints = __webpack_require__(58813); /** - * Retrieves a value from an object. + * Takes an array of Game Objects and positions them on evenly spaced points around the edges of a Triangle. + * + * If you wish to pass a `Phaser.GameObjects.Triangle` Shape to this function, you should pass its `geom` property. * - * @function Phaser.Utils.Objects.GetValue + * @function Phaser.Actions.PlaceOnTriangle * @since 3.0.0 * - * @param {object} source - The object to retrieve the value from. - * @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object. - * @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object. + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] * - * @return {*} The value of the requested key. + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Triangle} triangle - The Triangle to position the Game Objects on. + * @param {number} [stepRate=1] - An optional step rate, to increase or decrease the packing of the Game Objects on the lines. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -var GetValue = function (source, key, defaultValue) +var PlaceOnTriangle = function (items, triangle, stepRate) { - if (!source || typeof source === 'number') - { - return defaultValue; - } - else if (source.hasOwnProperty(key)) - { - return source[key]; - } - else if (key.indexOf('.') !== -1) - { - var keys = key.split('.'); - var parent = source; - var value = defaultValue; + var p1 = BresenhamPoints({ x1: triangle.x1, y1: triangle.y1, x2: triangle.x2, y2: triangle.y2 }, stepRate); + var p2 = BresenhamPoints({ x1: triangle.x2, y1: triangle.y2, x2: triangle.x3, y2: triangle.y3 }, stepRate); + var p3 = BresenhamPoints({ x1: triangle.x3, y1: triangle.y3, x2: triangle.x1, y2: triangle.y1 }, stepRate); - // Use for loop here so we can break early - for (var i = 0; i < keys.length; i++) - { - if (parent.hasOwnProperty(keys[i])) - { - // Yes it has a key property, let's carry on down - value = parent[keys[i]]; + // Remove overlaps + p1.pop(); + p2.pop(); + p3.pop(); - parent = parent[keys[i]]; - } - else - { - // Can't go any further, so reset to default - value = defaultValue; - break; - } - } + p1 = p1.concat(p2, p3); - return value; - } - else + var step = p1.length / items.length; + var p = 0; + + for (var i = 0; i < items.length; i++) { - return defaultValue; + var item = items[i]; + var point = p1[Math.floor(p)]; + + item.x = point.x; + item.y = point.y; + + p += step; } + + return items; }; -module.exports = GetValue; +module.exports = PlaceOnTriangle; /***/ }), -/* 7 */ -/***/ (function(module, exports) { + +/***/ 1045: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * This is a slightly modified version of jQuery.isPlainObject. - * A plain object is an object whose internal class property is [object Object]. + * Play an animation on all Game Objects in the array that have an Animation component. * - * @function Phaser.Utils.Objects.IsPlainObject + * You can pass either an animation key, or an animation configuration object for more control over the playback. + * + * @function Phaser.Actions.PlayAnimation * @since 3.0.0 * - * @param {object} obj - The object to inspect. + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] * - * @return {boolean} `true` if the object is plain, otherwise `false`. + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {boolean} [ignoreIfPlaying=false] - If this animation is already playing then ignore this call. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -var IsPlainObject = function (obj) +var PlayAnimation = function (items, key, ignoreIfPlaying) { - // Not plain objects: - // - Any object or value whose internal [[Class]] property is not "[object Object]" - // - DOM nodes - // - window - if (typeof(obj) !== 'object' || obj.nodeType || obj === obj.window) + for (var i = 0; i < items.length; i++) { - return false; - } + var gameObject = items[i]; - // Support: Firefox <20 - // The try/catch suppresses exceptions thrown when attempting to access - // the "constructor" property of certain host objects, ie. |window.location| - // https://bugzilla.mozilla.org/show_bug.cgi?id=814622 - try - { - if (obj.constructor && !({}).hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) + if (gameObject.anims) { - return false; + gameObject.anims.play(key, ignoreIfPlaying); } } - catch (e) - { - return false; - } - // If the function hasn't returned already, we're confident that - // |obj| is a plain object, created by {} or constructed with new Object - return true; + return items; }; -module.exports = IsPlainObject; +module.exports = PlayAnimation; /***/ }), -/* 8 */ -/***/ (function(module, exports) { + +/***/ 6124: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var types = {}; - /** - * @namespace Phaser.Loader.FileTypesManager + * Takes an array of Game Objects, or any objects that have a public property as defined in `key`, + * and then adds the given value to it. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `PropertyValueInc(group.getChildren(), key, value, step)` + * + * @function Phaser.Actions.PropertyValueInc + * @since 3.3.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {string} key - The property to be updated. + * @param {number} value - The amount to be added to the property. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ +var PropertyValueInc = function (items, key, value, step, index, direction) +{ + if (step === undefined) { step = 0; } + if (index === undefined) { index = 0; } + if (direction === undefined) { direction = 1; } -var FileTypesManager = { + var i; + var t = 0; + var end = items.length; - /** - * Static method called when a LoaderPlugin is created. - * - * Loops through the local types object and injects all of them as - * properties into the LoaderPlugin instance. - * - * @method Phaser.Loader.FileTypesManager.install - * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - The LoaderPlugin to install the types into. - */ - install: function (loader) + if (direction === 1) { - for (var key in types) + // Start to End + for (i = index; i < end; i++) { - loader[key] = types[key]; + items[i][key] += value + (t * step); + t++; } - }, - - /** - * Static method called directly by the File Types. - * - * The key is a reference to the function used to load the files via the Loader, i.e. `image`. - * - * @method Phaser.Loader.FileTypesManager.register - * @since 3.0.0 - * - * @param {string} key - The key that will be used as the method name in the LoaderPlugin. - * @param {function} factoryFunction - The function that will be called when LoaderPlugin.key is invoked. - */ - register: function (key, factoryFunction) - { - types[key] = factoryFunction; - }, - - /** - * Removed all associated file types. - * - * @method Phaser.Loader.FileTypesManager.destroy - * @since 3.0.0 - */ - destroy: function () + } + else { - types = {}; + // End to Start + for (i = index; i >= 0; i--) + { + items[i][key] += value + (t * step); + t++; + } } + return items; }; -module.exports = FileTypesManager; +module.exports = PropertyValueInc; /***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; +/***/ 23646: +/***/ ((module) => { -var has = Object.prototype.hasOwnProperty - , prefix = '~'; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ /** - * Constructor to create a storage for our `EE` objects. - * An `Events` instance is a plain object whose properties are event names. + * Takes an array of Game Objects, or any objects that have a public property as defined in `key`, + * and then sets it to the given value. * - * @constructor - * @private + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `PropertyValueSet(group.getChildren(), key, value, step)` + * + * @function Phaser.Actions.PropertyValueSet + * @since 3.3.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {string} key - The property to be updated. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ -function Events() {} +var PropertyValueSet = function (items, key, value, step, index, direction) +{ + if (step === undefined) { step = 0; } + if (index === undefined) { index = 0; } + if (direction === undefined) { direction = 1; } -// -// We try to not inherit from `Object.prototype`. In some engines creating an -// instance in this way is faster than calling `Object.create(null)` directly. -// If `Object.create(null)` is not supported we prefix the event names with a -// character to make sure that the built-in object properties are not -// overridden or used as an attack vector. -// -if (Object.create) { - Events.prototype = Object.create(null); + var i; + var t = 0; + var end = items.length; + + if (direction === 1) + { + // Start to End + for (i = index; i < end; i++) + { + items[i][key] = value + (t * step); + t++; + } + } + else + { + // End to Start + for (i = index; i >= 0; i--) + { + items[i][key] = value + (t * step); + t++; + } + } + + return items; +}; + +module.exports = PropertyValueSet; - // - // This hack is needed because the `__proto__` property is still inherited in - // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5. - // - if (!new Events().__proto__) prefix = false; -} + +/***/ }), + +/***/ 4392: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Representation of a single event listener. - * - * @param {Function} fn The listener function. - * @param {*} context The context to invoke the listener with. - * @param {Boolean} [once=false] Specify if the listener is a one-time listener. - * @constructor - * @private + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -function EE(fn, context, once) { - this.fn = fn; - this.context = context; - this.once = once || false; -} + +var Random = __webpack_require__(30977); /** - * Add a listener for a given event. + * Takes an array of Game Objects and positions them at random locations within the Circle. + * + * If you wish to pass a `Phaser.GameObjects.Circle` Shape to this function, you should pass its `geom` property. * - * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. - * @param {(String|Symbol)} event The event name. - * @param {Function} fn The listener function. - * @param {*} context The context to invoke the listener with. - * @param {Boolean} once Specify if the listener is a one-time listener. - * @returns {EventEmitter} - * @private + * @function Phaser.Actions.RandomCircle + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Circle} circle - The Circle to position the Game Objects within. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -function addListener(emitter, event, fn, context, once) { - if (typeof fn !== 'function') { - throw new TypeError('The listener must be a function'); - } +var RandomCircle = function (items, circle) +{ + for (var i = 0; i < items.length; i++) + { + Random(circle, items[i]); + } - var listener = new EE(fn, context || emitter, once) - , evt = prefix ? prefix + event : event; + return items; +}; - if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; - else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); - else emitter._events[evt] = [emitter._events[evt], listener]; +module.exports = RandomCircle; - return emitter; -} -/** - * Clear event by name. - * - * @param {EventEmitter} emitter Reference to the `EventEmitter` instance. - * @param {(String|Symbol)} evt The Event name. - * @private - */ -function clearEvent(emitter, evt) { - if (--emitter._eventsCount === 0) emitter._events = new Events(); - else delete emitter._events[evt]; -} +/***/ }), + +/***/ 94985: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Minimal `EventEmitter` interface that is molded against the Node.js - * `EventEmitter` interface. - * - * @constructor - * @public + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -function EventEmitter() { - this._events = new Events(); - this._eventsCount = 0; -} + +var Random = __webpack_require__(72006); /** - * Return an array listing the events for which the emitter has registered - * listeners. + * Takes an array of Game Objects and positions them at random locations within the Ellipse. + * + * If you wish to pass a `Phaser.GameObjects.Ellipse` Shape to this function, you should pass its `geom` property. * - * @returns {Array} - * @public + * @function Phaser.Actions.RandomEllipse + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to position the Game Objects within. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -EventEmitter.prototype.eventNames = function eventNames() { - var names = [] - , events - , name; +var RandomEllipse = function (items, ellipse) +{ + for (var i = 0; i < items.length; i++) + { + Random(ellipse, items[i]); + } - if (this._eventsCount === 0) return names; + return items; +}; - for (name in (events = this._events)) { - if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); - } +module.exports = RandomEllipse; - if (Object.getOwnPropertySymbols) { - return names.concat(Object.getOwnPropertySymbols(events)); - } - return names; -}; +/***/ }), + +/***/ 63305: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Return the listeners registered for a given event. - * - * @param {(String|Symbol)} event The event name. - * @returns {Array} The registered listeners. - * @public + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -EventEmitter.prototype.listeners = function listeners(event) { - var evt = prefix ? prefix + event : event - , handlers = this._events[evt]; - - if (!handlers) return []; - if (handlers.fn) return [handlers.fn]; - for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) { - ee[i] = handlers[i].fn; - } - - return ee; -}; +var Random = __webpack_require__(74077); /** - * Return the number of listeners listening to a given event. + * Takes an array of Game Objects and positions them at random locations on the Line. + * + * If you wish to pass a `Phaser.GameObjects.Line` Shape to this function, you should pass its `geom` property. * - * @param {(String|Symbol)} event The event name. - * @returns {Number} The number of listeners. - * @public + * @function Phaser.Actions.RandomLine + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Line} line - The Line to position the Game Objects randomly on. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -EventEmitter.prototype.listenerCount = function listenerCount(event) { - var evt = prefix ? prefix + event : event - , listeners = this._events[evt]; +var RandomLine = function (items, line) +{ + for (var i = 0; i < items.length; i++) + { + Random(line, items[i]); + } - if (!listeners) return 0; - if (listeners.fn) return 1; - return listeners.length; + return items; }; -/** - * Calls each of the listeners registered for a given event. - * - * @param {(String|Symbol)} event The event name. - * @returns {Boolean} `true` if the event had listeners, else `false`. - * @public - */ -EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { - var evt = prefix ? prefix + event : event; +module.exports = RandomLine; - if (!this._events[evt]) return false; - var listeners = this._events[evt] - , len = arguments.length - , args - , i; +/***/ }), - if (listeners.fn) { - if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); +/***/ 90739: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - switch (len) { - case 1: return listeners.fn.call(listeners.context), true; - case 2: return listeners.fn.call(listeners.context, a1), true; - case 3: return listeners.fn.call(listeners.context, a1, a2), true; - case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; - case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; - case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (i = 1, args = new Array(len -1); i < len; i++) { - args[i - 1] = arguments[i]; +var Random = __webpack_require__(30001); + +/** + * Takes an array of Game Objects and positions them at random locations within the Rectangle. + * + * @function Phaser.Actions.RandomRectangle + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to position the Game Objects within. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + */ +var RandomRectangle = function (items, rect) +{ + for (var i = 0; i < items.length; i++) + { + Random(rect, items[i]); } - listeners.fn.apply(listeners.context, args); - } else { - var length = listeners.length - , j; + return items; +}; - for (i = 0; i < length; i++) { - if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); +module.exports = RandomRectangle; - switch (len) { - case 1: listeners[i].fn.call(listeners[i].context); break; - case 2: listeners[i].fn.call(listeners[i].context, a1); break; - case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; - case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break; - default: - if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { - args[j - 1] = arguments[j]; - } - listeners[i].fn.apply(listeners[i].context, args); - } - } - } +/***/ }), - return true; -}; +/***/ 91417: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Add a listener for a given event. - * - * @param {(String|Symbol)} event The event name. - * @param {Function} fn The listener function. - * @param {*} [context=this] The context to invoke the listener with. - * @returns {EventEmitter} `this`. - * @public + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -EventEmitter.prototype.on = function on(event, fn, context) { - return addListener(this, event, fn, context, false); -}; -/** - * Add a one-time listener for a given event. - * - * @param {(String|Symbol)} event The event name. - * @param {Function} fn The listener function. - * @param {*} [context=this] The context to invoke the listener with. - * @returns {EventEmitter} `this`. - * @public - */ -EventEmitter.prototype.once = function once(event, fn, context) { - return addListener(this, event, fn, context, true); -}; +var Random = __webpack_require__(99761); /** - * Remove the listeners of a given event. + * Takes an array of Game Objects and positions them at random locations within the Triangle. + * + * If you wish to pass a `Phaser.GameObjects.Triangle` Shape to this function, you should pass its `geom` property. * - * @param {(String|Symbol)} event The event name. - * @param {Function} fn Only remove the listeners that match this function. - * @param {*} context Only remove the listeners that have this context. - * @param {Boolean} once Only remove one-time listeners. - * @returns {EventEmitter} `this`. - * @public + * @function Phaser.Actions.RandomTriangle + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Triangle} triangle - The Triangle to position the Game Objects within. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { - var evt = prefix ? prefix + event : event; +var RandomTriangle = function (items, triangle) +{ + for (var i = 0; i < items.length; i++) + { + Random(triangle, items[i]); + } - if (!this._events[evt]) return this; - if (!fn) { - clearEvent(this, evt); - return this; - } + return items; +}; - var listeners = this._events[evt]; +module.exports = RandomTriangle; - if (listeners.fn) { - if ( - listeners.fn === fn && - (!once || listeners.once) && - (!context || listeners.context === context) - ) { - clearEvent(this, evt); - } - } else { - for (var i = 0, events = [], length = listeners.length; i < length; i++) { - if ( - listeners[i].fn !== fn || - (once && !listeners[i].once) || - (context && listeners[i].context !== context) - ) { - events.push(listeners[i]); - } - } - // - // Reset the array, or remove it completely if we have no more listeners. - // - if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; - else clearEvent(this, evt); - } +/***/ }), - return this; -}; +/***/ 26182: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Remove all listeners, or those of the specified event. - * - * @param {(String|Symbol)} [event] The event name. - * @returns {EventEmitter} `this`. - * @public + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { - var evt; - if (event) { - evt = prefix ? prefix + event : event; - if (this._events[evt]) clearEvent(this, evt); - } else { - this._events = new Events(); - this._eventsCount = 0; - } +var PropertyValueInc = __webpack_require__(6124); - return this; +/** + * Takes an array of Game Objects, or any objects that have a public `rotation` property, + * and then adds the given value to each of their `rotation` properties. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `Rotate(group.getChildren(), value, step)` + * + * @function Phaser.Actions.Rotate + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to be added to the `rotation` property (in radians). + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var Rotate = function (items, value, step, index, direction) +{ + return PropertyValueInc(items, 'rotation', value, step, index, direction); }; -// -// Alias methods names because people roll like that. -// -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; -EventEmitter.prototype.addListener = EventEmitter.prototype.on; - -// -// Expose the prefix. -// -EventEmitter.prefixed = prefix; - -// -// Allow `EventEmitter` to be imported as module namespace. -// -EventEmitter.EventEmitter = EventEmitter; - -// -// Expose the module. -// -if (true) { - module.exports = EventEmitter; -} +module.exports = Rotate; /***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 87299: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Contains = __webpack_require__(57); -var GetPoint = __webpack_require__(171); -var GetPoints = __webpack_require__(306); -var GEOM_CONST = __webpack_require__(56); -var Line = __webpack_require__(47); -var Random = __webpack_require__(174); +var RotateAroundDistance = __webpack_require__(72395); +var DistanceBetween = __webpack_require__(53996); /** - * @classdesc - * Encapsulates a 2D rectangle defined by its corner point in the top-left and its extends in x (width) and y (height) + * Rotates each item around the given point by the given angle. * - * @class Rectangle - * @memberof Phaser.Geom - * @constructor + * @function Phaser.Actions.RotateAround * @since 3.0.0 + * @see Phaser.Math.RotateAroundDistance * - * @param {number} [x=0] - The X coordinate of the top left corner of the Rectangle. - * @param {number} [y=0] - The Y coordinate of the top left corner of the Rectangle. - * @param {number} [width=0] - The width of the Rectangle. - * @param {number} [height=0] - The height of the Rectangle. + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {object} point - Any object with public `x` and `y` properties. + * @param {number} angle - The angle to rotate by, in radians. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -var Rectangle = new Class({ - - initialize: +var RotateAround = function (items, point, angle) +{ + var x = point.x; + var y = point.y; - function Rectangle (x, y, width, height) + for (var i = 0; i < items.length; i++) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 0; } - if (height === undefined) { height = 0; } + var item = items[i]; - /** - * The geometry constant type of this object: `GEOM_CONST.RECTANGLE`. - * Used for fast type comparisons. - * - * @name Phaser.Geom.Rectangle#type - * @type {number} - * @readonly - * @since 3.19.0 - */ - this.type = GEOM_CONST.RECTANGLE; + RotateAroundDistance(item, x, y, angle, Math.max(1, DistanceBetween(item.x, item.y, x, y))); + } - /** - * The X coordinate of the top left corner of the Rectangle. - * - * @name Phaser.Geom.Rectangle#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.x = x; + return items; +}; - /** - * The Y coordinate of the top left corner of the Rectangle. - * - * @name Phaser.Geom.Rectangle#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.y = y; +module.exports = RotateAround; - /** - * The width of the Rectangle, i.e. the distance between its left side (defined by `x`) and its right side. - * - * @name Phaser.Geom.Rectangle#width - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.width = width; - /** - * The height of the Rectangle, i.e. the distance between its top side (defined by `y`) and its bottom side. - * - * @name Phaser.Geom.Rectangle#height - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.height = height; - }, +/***/ }), - /** - * Checks if the given point is inside the Rectangle's bounds. - * - * @method Phaser.Geom.Rectangle#contains - * @since 3.0.0 - * - * @param {number} x - The X coordinate of the point to check. - * @param {number} y - The Y coordinate of the point to check. - * - * @return {boolean} `true` if the point is within the Rectangle's bounds, otherwise `false`. - */ - contains: function (x, y) - { - return Contains(this, x, y); - }, +/***/ 92194: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Calculates the coordinates of a point at a certain `position` on the Rectangle's perimeter. - * - * The `position` is a fraction between 0 and 1 which defines how far into the perimeter the point is. - * - * A value of 0 or 1 returns the point at the top left corner of the rectangle, while a value of 0.5 returns the point at the bottom right corner of the rectangle. Values between 0 and 0.5 are on the top or the right side and values between 0.5 and 1 are on the bottom or the left side. - * - * @method Phaser.Geom.Rectangle#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [output,$return] - * - * @param {number} position - The normalized distance into the Rectangle's perimeter to return. - * @param {(Phaser.Geom.Point|object)} [output] - An object to update with the `x` and `y` coordinates of the point. - * - * @return {(Phaser.Geom.Point|object)} The updated `output` object, or a new Point if no `output` object was given. - */ - getPoint: function (position, output) - { - return GetPoint(this, position, output); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Returns an array of points from the perimeter of the Rectangle, each spaced out based on the quantity or step required. - * - * @method Phaser.Geom.Rectangle#getPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point[]} O - [output,$return] - * - * @param {number} quantity - The number of points to return. Set to `false` or 0 to return an arbitrary number of points (`perimeter / stepRate`) evenly spaced around the Rectangle based on the `stepRate`. - * @param {number} [stepRate] - If `quantity` is 0, determines the normalized distance between each returned point. - * @param {(array|Phaser.Geom.Point[])} [output] - An array to which to append the points. - * - * @return {(array|Phaser.Geom.Point[])} The modified `output` array, or a new array if none was provided. - */ - getPoints: function (quantity, stepRate, output) - { - return GetPoints(this, quantity, stepRate, output); - }, +var MathRotateAroundDistance = __webpack_require__(72395); - /** - * Returns a random point within the Rectangle's bounds. - * - * @method Phaser.Geom.Rectangle#getRandomPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [point,$return] - * - * @param {Phaser.Geom.Point} [point] - The object in which to store the `x` and `y` coordinates of the point. - * - * @return {Phaser.Geom.Point} The updated `point`, or a new Point if none was provided. - */ - getRandomPoint: function (point) +/** + * Rotates an array of Game Objects around a point by the given angle and distance. + * + * @function Phaser.Actions.RotateAroundDistance + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {object} point - Any object with public `x` and `y` properties. + * @param {number} angle - The angle to rotate by, in radians. + * @param {number} distance - The distance from the point of rotation in pixels. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + */ +var RotateAroundDistance = function (items, point, angle, distance) +{ + var x = point.x; + var y = point.y; + + // There's nothing to do + if (distance === 0) { - return Random(this, point); - }, + return items; + } - /** - * Sets the position, width, and height of the Rectangle. - * - * @method Phaser.Geom.Rectangle#setTo - * @since 3.0.0 - * - * @param {number} x - The X coordinate of the top left corner of the Rectangle. - * @param {number} y - The Y coordinate of the top left corner of the Rectangle. - * @param {number} width - The width of the Rectangle. - * @param {number} height - The height of the Rectangle. - * - * @return {this} This Rectangle object. - */ - setTo: function (x, y, width, height) + for (var i = 0; i < items.length; i++) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; + MathRotateAroundDistance(items[i], x, y, angle, distance); + } - return this; - }, + return items; +}; - /** - * Resets the position, width, and height of the Rectangle to 0. - * - * @method Phaser.Geom.Rectangle#setEmpty - * @since 3.0.0 - * - * @return {this} This Rectangle object. - */ - setEmpty: function () - { - return this.setTo(0, 0, 0, 0); - }, +module.exports = RotateAroundDistance; - /** - * Sets the position of the Rectangle. - * - * @method Phaser.Geom.Rectangle#setPosition - * @since 3.0.0 - * - * @param {number} x - The X coordinate of the top left corner of the Rectangle. - * @param {number} [y=x] - The Y coordinate of the top left corner of the Rectangle. - * - * @return {this} This Rectangle object. - */ - setPosition: function (x, y) - { - if (y === undefined) { y = x; } - this.x = x; - this.y = y; +/***/ }), - return this; - }, +/***/ 30363: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Sets the width and height of the Rectangle. - * - * @method Phaser.Geom.Rectangle#setSize - * @since 3.0.0 - * - * @param {number} width - The width to set the Rectangle to. - * @param {number} [height=width] - The height to set the Rectangle to. - * - * @return {this} This Rectangle object. - */ - setSize: function (width, height) - { - if (height === undefined) { height = width; } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.width = width; - this.height = height; +var PropertyValueInc = __webpack_require__(6124); - return this; - }, +/** + * Takes an array of Game Objects, or any objects that have a public `scaleX` property, + * and then adds the given value to each of their `scaleX` properties. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `ScaleX(group.getChildren(), value, step)` + * + * @function Phaser.Actions.ScaleX + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to be added to the `scaleX` property. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var ScaleX = function (items, value, step, index, direction) +{ + return PropertyValueInc(items, 'scaleX', value, step, index, direction); +}; - /** - * Determines if the Rectangle is empty. A Rectangle is empty if its width or height is less than or equal to 0. - * - * @method Phaser.Geom.Rectangle#isEmpty - * @since 3.0.0 - * - * @return {boolean} `true` if the Rectangle is empty. A Rectangle object is empty if its width or height is less than or equal to 0. - */ - isEmpty: function () - { - return (this.width <= 0 || this.height <= 0); - }, +module.exports = ScaleX; - /** - * Returns a Line object that corresponds to the top of this Rectangle. - * - * @method Phaser.Geom.Rectangle#getLineA - * @since 3.0.0 - * - * @generic {Phaser.Geom.Line} O - [line,$return] - * - * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. - * - * @return {Phaser.Geom.Line} A Line object that corresponds to the top of this Rectangle. - */ - getLineA: function (line) - { - if (line === undefined) { line = new Line(); } - line.setTo(this.x, this.y, this.right, this.y); +/***/ }), - return line; - }, +/***/ 51449: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Returns a Line object that corresponds to the right of this Rectangle. - * - * @method Phaser.Geom.Rectangle#getLineB - * @since 3.0.0 - * - * @generic {Phaser.Geom.Line} O - [line,$return] - * - * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. - * - * @return {Phaser.Geom.Line} A Line object that corresponds to the right of this Rectangle. - */ - getLineB: function (line) - { - if (line === undefined) { line = new Line(); } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - line.setTo(this.right, this.y, this.right, this.bottom); +var PropertyValueInc = __webpack_require__(6124); - return line; - }, +/** + * Takes an array of Game Objects, or any objects that have public `scaleX` and `scaleY` properties, + * and then adds the given value to each of them. + * + * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `ScaleXY(group.getChildren(), scaleX, scaleY, stepX, stepY)` + * + * @function Phaser.Actions.ScaleXY + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} scaleX - The amount to be added to the `scaleX` property. + * @param {number} [scaleY] - The amount to be added to the `scaleY` property. If `undefined` or `null` it uses the `scaleX` value. + * @param {number} [stepX=0] - This is added to the `scaleX` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `scaleY` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var ScaleXY = function (items, scaleX, scaleY, stepX, stepY, index, direction) +{ + if (scaleY === undefined || scaleY === null) { scaleY = scaleX; } - /** - * Returns a Line object that corresponds to the bottom of this Rectangle. - * - * @method Phaser.Geom.Rectangle#getLineC - * @since 3.0.0 - * - * @generic {Phaser.Geom.Line} O - [line,$return] - * - * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. - * - * @return {Phaser.Geom.Line} A Line object that corresponds to the bottom of this Rectangle. - */ - getLineC: function (line) - { - if (line === undefined) { line = new Line(); } + PropertyValueInc(items, 'scaleX', scaleX, stepX, index, direction); - line.setTo(this.right, this.bottom, this.x, this.bottom); + return PropertyValueInc(items, 'scaleY', scaleY, stepY, index, direction); +}; - return line; - }, +module.exports = ScaleXY; - /** - * Returns a Line object that corresponds to the left of this Rectangle. - * - * @method Phaser.Geom.Rectangle#getLineD - * @since 3.0.0 - * - * @generic {Phaser.Geom.Line} O - [line,$return] - * - * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. - * - * @return {Phaser.Geom.Line} A Line object that corresponds to the left of this Rectangle. - */ - getLineD: function (line) - { - if (line === undefined) { line = new Line(); } - line.setTo(this.x, this.bottom, this.x, this.y); +/***/ }), - return line; - }, +/***/ 64895: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The x coordinate of the left of the Rectangle. - * Changing the left property of a Rectangle object has no effect on the y and height properties. However it does affect the width property, whereas changing the x value does not affect the width property. - * - * @name Phaser.Geom.Rectangle#left - * @type {number} - * @since 3.0.0 - */ - left: { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - get: function () - { - return this.x; - }, +var PropertyValueInc = __webpack_require__(6124); - set: function (value) - { - if (value >= this.right) - { - this.width = 0; - } - else - { - this.width = this.right - value; - } +/** + * Takes an array of Game Objects, or any objects that have a public `scaleY` property, + * and then adds the given value to each of their `scaleY` properties. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `ScaleY(group.getChildren(), value, step)` + * + * @function Phaser.Actions.ScaleY + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to be added to the `scaleY` property. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var ScaleY = function (items, value, step, index, direction) +{ + return PropertyValueInc(items, 'scaleY', value, step, index, direction); +}; - this.x = value; - } +module.exports = ScaleY; - }, - /** - * The sum of the x and width properties. - * Changing the right property of a Rectangle object has no effect on the x, y and height properties, however it does affect the width property. - * - * @name Phaser.Geom.Rectangle#right - * @type {number} - * @since 3.0.0 - */ - right: { +/***/ }), - get: function () - { - return this.x + this.width; - }, +/***/ 30329: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - set: function (value) - { - if (value <= this.x) - { - this.width = 0; - } - else - { - this.width = value - this.x; - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - }, +var PropertyValueSet = __webpack_require__(23646); - /** - * The y coordinate of the top of the Rectangle. Changing the top property of a Rectangle object has no effect on the x and width properties. - * However it does affect the height property, whereas changing the y value does not affect the height property. - * - * @name Phaser.Geom.Rectangle#top - * @type {number} - * @since 3.0.0 - */ - top: { +/** + * Takes an array of Game Objects, or any objects that have the public property `alpha` + * and then sets it to the given value. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetAlpha(group.getChildren(), value, step)` + * + * @function Phaser.Actions.SetAlpha + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetAlpha = function (items, value, step, index, direction) +{ + return PropertyValueSet(items, 'alpha', value, step, index, direction); +}; - get: function () - { - return this.y; - }, +module.exports = SetAlpha; - set: function (value) - { - if (value >= this.bottom) - { - this.height = 0; - } - else - { - this.height = (this.bottom - value); - } - this.y = value; - } +/***/ }), - }, +/***/ 43954: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The sum of the y and height properties. - * Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property. - * - * @name Phaser.Geom.Rectangle#bottom - * @type {number} - * @since 3.0.0 - */ - bottom: { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - get: function () - { - return this.y + this.height; - }, +var PropertyValueSet = __webpack_require__(23646); - set: function (value) - { - if (value <= this.y) - { - this.height = 0; - } - else - { - this.height = value - this.y; - } - } +/** + * Takes an array of Game Objects, or any objects that have the public property `blendMode` + * and then sets it to the given value. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetBlendMode(group.getChildren(), value)` + * + * @function Phaser.Actions.SetBlendMode + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetBlendMode = function (items, value, index, direction) +{ + return PropertyValueSet(items, 'blendMode', value, 0, index, direction); +}; - }, +module.exports = SetBlendMode; - /** - * The x coordinate of the center of the Rectangle. - * - * @name Phaser.Geom.Rectangle#centerX - * @type {number} - * @since 3.0.0 - */ - centerX: { - get: function () - { - return this.x + (this.width / 2); - }, +/***/ }), - set: function (value) - { - this.x = value - (this.width / 2); - } +/***/ 70688: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The y coordinate of the center of the Rectangle. - * - * @name Phaser.Geom.Rectangle#centerY - * @type {number} - * @since 3.0.0 - */ - centerY: { +var PropertyValueSet = __webpack_require__(23646); - get: function () - { - return this.y + (this.height / 2); - }, +/** + * Takes an array of Game Objects, or any objects that have the public property `depth` + * and then sets it to the given value. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetDepth(group.getChildren(), value, step)` + * + * @function Phaser.Actions.SetDepth + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetDepth = function (items, value, step, index, direction) +{ + return PropertyValueSet(items, 'depth', value, step, index, direction); +}; - set: function (value) - { - this.y = value - (this.height / 2); - } +module.exports = SetDepth; + + +/***/ }), + +/***/ 8314: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ +/** + * Passes all provided Game Objects to the Input Manager to enable them for input with identical areas and callbacks. + * + * @see {@link Phaser.GameObjects.GameObject#setInteractive} + * + * @function Phaser.Actions.SetHitArea + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {*} hitArea - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. + * @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - A callback to be invoked when the Game Object is interacted with. If you provide a shape you must also provide a callback. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + */ +var SetHitArea = function (items, hitArea, hitAreaCallback) +{ + for (var i = 0; i < items.length; i++) + { + items[i].setInteractive(hitArea, hitAreaCallback); } -}); + return items; +}; -module.exports = Rectangle; +module.exports = SetHitArea; /***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 12894: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var PropertyValueSet = __webpack_require__(23646); + /** - * @namespace Phaser.GameObjects.Components + * Takes an array of Game Objects, or any objects that have the public properties `originX` and `originY` + * and then sets them to the given values. + * + * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetOrigin(group.getChildren(), originX, originY, stepX, stepY)` + * + * @function Phaser.Actions.SetOrigin + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} originX - The amount to set the `originX` property to. + * @param {number} [originY] - The amount to set the `originY` property to. If `undefined` or `null` it uses the `originX` value. + * @param {number} [stepX=0] - This is added to the `originX` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `originY` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ +var SetOrigin = function (items, originX, originY, stepX, stepY, index, direction) +{ + if (originY === undefined || originY === null) { originY = originX; } -module.exports = { + PropertyValueSet(items, 'originX', originX, stepX, index, direction); + PropertyValueSet(items, 'originY', originY, stepY, index, direction); - Alpha: __webpack_require__(607), - AlphaSingle: __webpack_require__(303), - BlendMode: __webpack_require__(304), - ComputedSize: __webpack_require__(608), - Crop: __webpack_require__(609), - Depth: __webpack_require__(305), - Flip: __webpack_require__(610), - GetBounds: __webpack_require__(611), - Mask: __webpack_require__(309), - Origin: __webpack_require__(632), - PathFollower: __webpack_require__(633), - Pipeline: __webpack_require__(167), - ScrollFactor: __webpack_require__(312), - Size: __webpack_require__(634), - Texture: __webpack_require__(635), - TextureCrop: __webpack_require__(636), - Tint: __webpack_require__(637), - ToJSON: __webpack_require__(176), - Transform: __webpack_require__(313), - TransformMatrix: __webpack_require__(25), - Visible: __webpack_require__(314) + items.forEach(function (item) + { + item.updateDisplayOrigin(); + }); + return items; }; +module.exports = SetOrigin; + /***/ }), -/* 12 */ -/***/ (function(module, exports) { + +/***/ 38767: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @author Matthew Groves <@doormat> - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var PropertyValueSet = __webpack_require__(23646); + /** - * Generate shader source to test maximum ifs. + * Takes an array of Game Objects, or any objects that have the public property `rotation` + * and then sets it to the given value. * - * @private - * @ignore - * @param {number} maxIfs - The number of if statements to generate + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetRotation(group.getChildren(), value, step)` + * + * @function Phaser.Actions.SetRotation + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ -function GenerateSrc (maxIfs) +var SetRotation = function (items, value, step, index, direction) { - var src = ''; + return PropertyValueSet(items, 'rotation', value, step, index, direction); +}; - for (var i = 0; i < maxIfs; ++i) - { - if (i > 0) - { - src += '\nelse '; - } +module.exports = SetRotation; - if (i < maxIfs - 1) - { - src += 'if(test == ' + i + '.0){}'; - } - } - return src; -} +/***/ }), + +/***/ 18584: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @namespace Phaser.Renderer.WebGL.Utils + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var PropertyValueSet = __webpack_require__(23646); + +/** + * Takes an array of Game Objects, or any objects that have the public properties `scaleX` and `scaleY` + * and then sets them to the given values. + * + * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetScale(group.getChildren(), scaleX, scaleY, stepX, stepY)` + * + * @function Phaser.Actions.SetScale * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} scaleX - The amount to set the `scaleX` property to. + * @param {number} [scaleY] - The amount to set the `scaleY` property to. If `undefined` or `null` it uses the `scaleX` value. + * @param {number} [stepX=0] - This is added to the `scaleX` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `scaleY` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ -module.exports = { +var SetScale = function (items, scaleX, scaleY, stepX, stepY, index, direction) +{ + if (scaleY === undefined || scaleY === null) { scaleY = scaleX; } - /** - * Packs four floats on a range from 0.0 to 1.0 into a single Uint32 - * - * @function Phaser.Renderer.WebGL.Utils.getTintFromFloats - * @since 3.0.0 - * - * @param {number} r - Red component in a range from 0.0 to 1.0 - * @param {number} g - Green component in a range from 0.0 to 1.0 - * @param {number} b - Blue component in a range from 0.0 to 1.0 - * @param {number} a - Alpha component in a range from 0.0 to 1.0 - * - * @return {number} The packed RGBA values as a Uint32. - */ - getTintFromFloats: function (r, g, b, a) - { - var ur = ((r * 255) | 0) & 0xff; - var ug = ((g * 255) | 0) & 0xff; - var ub = ((b * 255) | 0) & 0xff; - var ua = ((a * 255) | 0) & 0xff; + PropertyValueSet(items, 'scaleX', scaleX, stepX, index, direction); - return ((ua << 24) | (ur << 16) | (ug << 8) | ub) >>> 0; - }, + return PropertyValueSet(items, 'scaleY', scaleY, stepY, index, direction); +}; - /** - * Packs a Uint24, representing RGB components, with a Float32, representing - * the alpha component, with a range between 0.0 and 1.0 and return a Uint32 - * - * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlpha - * @since 3.0.0 - * - * @param {number} rgb - Uint24 representing RGB components - * @param {number} a - Float32 representing Alpha component - * - * @return {number} Packed RGBA as Uint32 - */ - getTintAppendFloatAlpha: function (rgb, a) - { - var ua = ((a * 255) | 0) & 0xff; +module.exports = SetScale; - return ((ua << 24) | rgb) >>> 0; - }, - /** - * Packs a Uint24, representing RGB components, with a Float32, representing - * the alpha component, with a range between 0.0 and 1.0 and return a - * swizzled Uint32 - * - * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlphaAndSwap - * @since 3.0.0 - * - * @param {number} rgb - Uint24 representing RGB components - * @param {number} a - Float32 representing Alpha component - * - * @return {number} Packed RGBA as Uint32 - */ - getTintAppendFloatAlphaAndSwap: function (rgb, a) - { - var ur = ((rgb >> 16) | 0) & 0xff; - var ug = ((rgb >> 8) | 0) & 0xff; - var ub = (rgb | 0) & 0xff; - var ua = ((a * 255) | 0) & 0xff; +/***/ }), - return ((ua << 24) | (ub << 16) | (ug << 8) | ur) >>> 0; - }, +/***/ 17381: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Unpacks a Uint24 RGB into an array of floats of ranges of 0.0 and 1.0 - * - * @function Phaser.Renderer.WebGL.Utils.getFloatsFromUintRGB - * @since 3.0.0 - * - * @param {number} rgb - RGB packed as a Uint24 - * - * @return {array} Array of floats representing each component as a float - */ - getFloatsFromUintRGB: function (rgb) - { - var ur = ((rgb >> 16) | 0) & 0xff; - var ug = ((rgb >> 8) | 0) & 0xff; - var ub = (rgb | 0) & 0xff; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return [ ur / 255, ug / 255, ub / 255 ]; - }, +var PropertyValueSet = __webpack_require__(23646); - /** - * Check to see how many texture units the GPU supports, based on the given config value. - * Then tests this against the maximum number of iterations GLSL can support. - * - * @function Phaser.Renderer.WebGL.Utils.checkShaderMax - * @since 3.50.0 - * - * @param {WebGLRenderingContext} gl - The WebGLContext used to create the shaders. - * @param {number} maxTextures - The Game Config maxTextures value. - * - * @return {number} The number of texture units that is supported by this browser and GPU. - */ - checkShaderMax: function (gl, maxTextures) - { - if (!maxTextures || maxTextures === -1) - { - maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); - } +/** + * Takes an array of Game Objects, or any objects that have the public property `scaleX` + * and then sets it to the given value. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetScaleX(group.getChildren(), value, step)` + * + * @function Phaser.Actions.SetScaleX + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetScaleX = function (items, value, step, index, direction) +{ + return PropertyValueSet(items, 'scaleX', value, step, index, direction); +}; - var shader = gl.createShader(gl.FRAGMENT_SHADER); +module.exports = SetScaleX; - var fragTemplate = [ - 'precision mediump float;', - 'void main(void){', - 'float test = 0.1;', - '%forloop%', - 'gl_FragColor = vec4(0.0);', - '}' - ].join('\n'); - // eslint-disable-next-line no-constant-condition - while (true) - { - var fragmentSrc = fragTemplate.replace(/%forloop%/gi, GenerateSrc(maxTextures)); +/***/ }), - gl.shaderSource(shader, fragmentSrc); - gl.compileShader(shader); +/***/ 74370: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) - { - maxTextures = (maxTextures / 2) | 0; - } - else - { - // valid! - break; - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return maxTextures; - }, +var PropertyValueSet = __webpack_require__(23646); - /** - * Checks the given Fragment Shader Source for `%count%` and `%forloop%` declarations and - * replaces those with GLSL code for setting `texture = texture2D(uMainSampler[i], outTexCoord)`. - * - * @function Phaser.Renderer.WebGL.Utils.parseFragmentShaderMaxTextures - * @since 3.50.0 - * - * @param {string} fragmentShaderSource - The Fragment Shader source code to operate on. - * @param {number} maxTextures - The number of maxTextures value. - * - * @return {string} The modified Fragment Shader source. - */ - parseFragmentShaderMaxTextures: function (fragmentShaderSource, maxTextures) - { - if (!fragmentShaderSource) - { - return ''; - } +/** + * Takes an array of Game Objects, or any objects that have the public property `scaleY` + * and then sets it to the given value. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetScaleY(group.getChildren(), value, step)` + * + * @function Phaser.Actions.SetScaleY + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetScaleY = function (items, value, step, index, direction) +{ + return PropertyValueSet(items, 'scaleY', value, step, index, direction); +}; - var src = ''; +module.exports = SetScaleY; - for (var i = 0; i < maxTextures; i++) - { - if (i > 0) - { - src += '\n\telse '; - } - if (i < maxTextures - 1) - { - src += 'if (outTexId < ' + i + '.5)'; - } +/***/ }), - src += '\n\t{'; - src += '\n\t\ttexture = texture2D(uMainSampler[' + i + '], outTexCoord);'; - src += '\n\t}'; - } +/***/ 27773: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - fragmentShaderSource = fragmentShaderSource.replace(/%count%/gi, maxTextures.toString()); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return fragmentShaderSource.replace(/%forloop%/gi, src); - } +var PropertyValueSet = __webpack_require__(23646); + +/** + * Takes an array of Game Objects, or any objects that have the public properties `scrollFactorX` and `scrollFactorY` + * and then sets them to the given values. + * + * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetScrollFactor(group.getChildren(), scrollFactorX, scrollFactorY, stepX, stepY)` + * + * @function Phaser.Actions.SetScrollFactor + * @since 3.21.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} scrollFactorX - The amount to set the `scrollFactorX` property to. + * @param {number} [scrollFactorY] - The amount to set the `scrollFactorY` property to. If `undefined` or `null` it uses the `scrollFactorX` value. + * @param {number} [stepX=0] - This is added to the `scrollFactorX` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `scrollFactorY` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetScrollFactor = function (items, scrollFactorX, scrollFactorY, stepX, stepY, index, direction) +{ + if (scrollFactorY === undefined || scrollFactorY === null) { scrollFactorY = scrollFactorX; } + + PropertyValueSet(items, 'scrollFactorX', scrollFactorX, stepX, index, direction); + + return PropertyValueSet(items, 'scrollFactorY', scrollFactorY, stepY, index, direction); }; +module.exports = SetScrollFactor; + /***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 75257: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MATH = __webpack_require__(193); -var GetValue = __webpack_require__(6); +var PropertyValueSet = __webpack_require__(23646); /** - * Retrieves a value from an object. Allows for more advanced selection options, including: + * Takes an array of Game Objects, or any objects that have the public property `scrollFactorX` + * and then sets it to the given value. * - * Allowed types: - * - * Implicit - * { - * x: 4 - * } + * The optional `step` property is applied incrementally, multiplied by each item in the array. * - * From function - * { - * x: function () - * } + * To use this with a Group: `SetScrollFactorX(group.getChildren(), value, step)` * - * Randomly pick one element from the array - * { - * x: [a, b, c, d, e, f] - * } + * @function Phaser.Actions.SetScrollFactorX + * @since 3.21.0 * - * Random integer between min and max: - * { - * x: { randInt: [min, max] } - * } + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] * - * Random float between min and max: - * { - * x: { randFloat: [min, max] } - * } - * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. * - * @function Phaser.Utils.Objects.GetAdvancedValue - * @since 3.0.0 + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetScrollFactorX = function (items, value, step, index, direction) +{ + return PropertyValueSet(items, 'scrollFactorX', value, step, index, direction); +}; + +module.exports = SetScrollFactorX; + + +/***/ }), + +/***/ 54512: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var PropertyValueSet = __webpack_require__(23646); + +/** + * Takes an array of Game Objects, or any objects that have the public property `scrollFactorY` + * and then sets it to the given value. * - * @param {object} source - The object to retrieve the value from. - * @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object. - * @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object. + * The optional `step` property is applied incrementally, multiplied by each item in the array. * - * @return {*} The value of the requested key. + * To use this with a Group: `SetScrollFactorY(group.getChildren(), value, step)` + * + * @function Phaser.Actions.SetScrollFactorY + * @since 3.21.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ -var GetAdvancedValue = function (source, key, defaultValue) +var SetScrollFactorY = function (items, value, step, index, direction) { - var value = GetValue(source, key, null); + return PropertyValueSet(items, 'scrollFactorY', value, step, index, direction); +}; - if (value === null) - { - return defaultValue; - } - else if (Array.isArray(value)) - { - return MATH.RND.pick(value); - } - else if (typeof value === 'object') - { - if (value.hasOwnProperty('randInt')) - { - return MATH.RND.integerInRange(value.randInt[0], value.randInt[1]); - } - else if (value.hasOwnProperty('randFloat')) - { - return MATH.RND.realInRange(value.randFloat[0], value.randFloat[1]); - } - } - else if (typeof value === 'function') +module.exports = SetScrollFactorY; + + +/***/ }), + +/***/ 69423: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Takes an array of Game Objects, or any objects that have the public method setTint() and then updates it to the given value(s). You can specify tint color per corner or provide only one color value for `topLeft` parameter, in which case whole item will be tinted with that color. + * + * @function Phaser.Actions.SetTint + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {number} topLeft - The tint being applied to top-left corner of item. If other parameters are given no value, this tint will be applied to whole item. + * @param {number} [topRight] - The tint to be applied to top-right corner of item. + * @param {number} [bottomLeft] - The tint to be applied to the bottom-left corner of item. + * @param {number} [bottomRight] - The tint to be applied to the bottom-right corner of item. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + */ +var SetTint = function (items, topLeft, topRight, bottomLeft, bottomRight) +{ + for (var i = 0; i < items.length; i++) { - return value(key); + items[i].setTint(topLeft, topRight, bottomLeft, bottomRight); } - return value; + return items; }; -module.exports = GetAdvancedValue; +module.exports = SetTint; /***/ }), -/* 14 */ -/***/ (function(module, exports) { + +/***/ 58291: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MATH_CONST = { - - /** - * The value of PI * 2. - * - * @name Phaser.Math.PI2 - * @type {number} - * @since 3.0.0 - */ - PI2: Math.PI * 2, +var PropertyValueSet = __webpack_require__(23646); - /** - * The value of PI * 0.5. - * - * @name Phaser.Math.TAU - * @type {number} - * @since 3.0.0 - */ - TAU: Math.PI * 0.5, +/** + * Takes an array of Game Objects, or any objects that have the public property `visible` + * and then sets it to the given value. + * + * To use this with a Group: `SetVisible(group.getChildren(), value)` + * + * @function Phaser.Actions.SetVisible + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {boolean} value - The value to set the property to. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetVisible = function (items, value, index, direction) +{ + return PropertyValueSet(items, 'visible', value, 0, index, direction); +}; - /** - * An epsilon value (1.0e-6) - * - * @name Phaser.Math.EPSILON - * @type {number} - * @since 3.0.0 - */ - EPSILON: 1.0e-6, +module.exports = SetVisible; - /** - * For converting degrees to radians (PI / 180) - * - * @name Phaser.Math.DEG_TO_RAD - * @type {number} - * @since 3.0.0 - */ - DEG_TO_RAD: Math.PI / 180, - /** - * For converting radians to degrees (180 / PI) - * - * @name Phaser.Math.RAD_TO_DEG - * @type {number} - * @since 3.0.0 - */ - RAD_TO_DEG: 180 / Math.PI, +/***/ }), - /** - * An instance of the Random Number Generator. - * This is not set until the Game boots. - * - * @name Phaser.Math.RND - * @type {Phaser.Math.RandomDataGenerator} - * @since 3.0.0 - */ - RND: null, +/***/ 94833: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The minimum safe integer this browser supports. - * We use a const for backward compatibility with Internet Explorer. - * - * @name Phaser.Math.MIN_SAFE_INTEGER - * @type {number} - * @since 3.21.0 - */ - MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER || -9007199254740991, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The maximum safe integer this browser supports. - * We use a const for backward compatibility with Internet Explorer. - * - * @name Phaser.Math.MAX_SAFE_INTEGER - * @type {number} - * @since 3.21.0 - */ - MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER || 9007199254740991 +var PropertyValueSet = __webpack_require__(23646); +/** + * Takes an array of Game Objects, or any objects that have the public property `x` + * and then sets it to the given value. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetX(group.getChildren(), value, step)` + * + * @function Phaser.Actions.SetX + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetX = function (items, value, step, index, direction) +{ + return PropertyValueSet(items, 'x', value, step, index, direction); }; -module.exports = MATH_CONST; +module.exports = SetX; /***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 14284: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var ComponentsToJSON = __webpack_require__(176); -var DataManager = __webpack_require__(101); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(75); -var SceneEvents = __webpack_require__(20); +var PropertyValueSet = __webpack_require__(23646); /** - * @classdesc - * The base class that all Game Objects extend. - * You don't create GameObjects directly and they cannot be added to the display list. - * Instead, use them as the base for your own custom classes. + * Takes an array of Game Objects, or any objects that have the public properties `x` and `y` + * and then sets them to the given values. * - * @class GameObject - * @memberof Phaser.GameObjects - * @extends Phaser.Events.EventEmitter - * @constructor + * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetXY(group.getChildren(), x, y, stepX, stepY)` + * + * @function Phaser.Actions.SetXY * @since 3.0.0 * - * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. - * @param {string} type - A textual representation of the type of Game Object, i.e. `sprite`. + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} x - The amount to set the `x` property to. + * @param {number} [y=x] - The amount to set the `y` property to. If `undefined` or `null` it uses the `x` value. + * @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ -var GameObject = new Class({ +var SetXY = function (items, x, y, stepX, stepY, index, direction) +{ + if (y === undefined || y === null) { y = x; } - Extends: EventEmitter, + PropertyValueSet(items, 'x', x, stepX, index, direction); - initialize: + return PropertyValueSet(items, 'y', y, stepY, index, direction); +}; - function GameObject (scene, type) - { - EventEmitter.call(this); +module.exports = SetXY; - /** - * A reference to the Scene to which this Game Object belongs. - * - * Game Objects can only belong to one Scene. - * - * You should consider this property as being read-only. You cannot move a - * Game Object to another Scene by simply changing it. - * - * @name Phaser.GameObjects.GameObject#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; - /** - * Holds a reference to the Display List that contains this Game Object. - * - * This is set automatically when this Game Object is added to a Scene or Layer. - * - * You should treat this property as being read-only. - * - * @name Phaser.GameObjects.GameObject#displayList - * @type {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} - * @default null - * @since 3.50.0 - */ - this.displayList = null; +/***/ }), - /** - * A textual representation of this Game Object, i.e. `sprite`. - * Used internally by Phaser but is available for your own custom classes to populate. - * - * @name Phaser.GameObjects.GameObject#type - * @type {string} - * @since 3.0.0 - */ - this.type = type; +/***/ 96574: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The current state of this Game Object. - * - * Phaser itself will never modify this value, although plugins may do so. - * - * Use this property to track the state of a Game Object during its lifetime. For example, it could change from - * a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant - * in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons. - * If you need to store complex data about your Game Object, look at using the Data Component instead. - * - * @name Phaser.GameObjects.GameObject#state - * @type {(number|string)} - * @since 3.16.0 - */ - this.state = 0; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The parent Container of this Game Object, if it has one. - * - * @name Phaser.GameObjects.GameObject#parentContainer - * @type {Phaser.GameObjects.Container} - * @since 3.4.0 - */ - this.parentContainer = null; +var PropertyValueSet = __webpack_require__(23646); - /** - * The name of this Game Object. - * Empty by default and never populated by Phaser, this is left for developers to use. - * - * @name Phaser.GameObjects.GameObject#name - * @type {string} - * @default '' - * @since 3.0.0 - */ - this.name = ''; +/** + * Takes an array of Game Objects, or any objects that have the public property `y` + * and then sets it to the given value. + * + * The optional `step` property is applied incrementally, multiplied by each item in the array. + * + * To use this with a Group: `SetY(group.getChildren(), value, step)` + * + * @function Phaser.Actions.SetY + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + */ +var SetY = function (items, value, step, index, direction) +{ + return PropertyValueSet(items, 'y', value, step, index, direction); +}; - /** - * The active state of this Game Object. - * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it. - * An active object is one which is having its logic and internal systems updated. - * - * @name Phaser.GameObjects.GameObject#active - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.active = true; +module.exports = SetY; - /** - * The Tab Index of the Game Object. - * Reserved for future use by plugins and the Input Manager. - * - * @name Phaser.GameObjects.GameObject#tabIndex - * @type {number} - * @default -1 - * @since 3.0.0 - */ - this.tabIndex = -1; - /** - * A Data Manager. - * It allows you to store, query and get key/value paired information specific to this Game Object. - * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`. - * - * @name Phaser.GameObjects.GameObject#data - * @type {Phaser.Data.DataManager} - * @default null - * @since 3.0.0 - */ - this.data = null; +/***/ }), - /** - * The flags that are compared against `RENDER_MASK` to determine if this Game Object will render or not. - * The bits are 0001 | 0010 | 0100 | 1000 set by the components Visible, Alpha, Transform and Texture respectively. - * If those components are not used by your custom class then you can use this bitmask as you wish. - * - * @name Phaser.GameObjects.GameObject#renderFlags - * @type {number} - * @default 15 - * @since 3.0.0 - */ - this.renderFlags = 15; +/***/ 74086: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A bitmask that controls if this Game Object is drawn by a Camera or not. - * Not usually set directly, instead call `Camera.ignore`, however you can - * set this property directly using the Camera.id property: - * - * @example - * this.cameraFilter |= camera.id - * - * @name Phaser.GameObjects.GameObject#cameraFilter - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.cameraFilter = 0; - - /** - * If this Game Object is enabled for input then this property will contain an InteractiveObject instance. - * Not usually set directly. Instead call `GameObject.setInteractive()`. - * - * @name Phaser.GameObjects.GameObject#input - * @type {?Phaser.Types.Input.InteractiveObject} - * @default null - * @since 3.0.0 - */ - this.input = null; - - /** - * If this Game Object is enabled for Arcade or Matter Physics then this property will contain a reference to a Physics Body. - * - * @name Phaser.GameObjects.GameObject#body - * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|MatterJS.BodyType)} - * @default null - * @since 3.0.0 - */ - this.body = null; - - /** - * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`. - * This includes calls that may come from a Group, Container or the Scene itself. - * While it allows you to persist a Game Object across Scenes, please understand you are entirely - * responsible for managing references to and from this Game Object. - * - * @name Phaser.GameObjects.GameObject#ignoreDestroy - * @type {boolean} - * @default false - * @since 3.5.0 - */ - this.ignoreDestroy = false; - - this.on(Events.ADDED_TO_SCENE, this.addedToScene, this); - this.on(Events.REMOVED_FROM_SCENE, this.removedFromScene, this); - - // Tell the Scene to re-sort the children - scene.sys.queueDepthSort(); - }, - - /** - * Sets the `active` property of this Game Object and returns this Game Object for further chaining. - * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList. - * - * @method Phaser.GameObjects.GameObject#setActive - * @since 3.0.0 - * - * @param {boolean} value - True if this Game Object should be set as active, false if not. - * - * @return {this} This GameObject. - */ - setActive: function (value) - { - this.active = value; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +var Vector2 = __webpack_require__(93736); - /** - * Sets the `name` property of this Game Object and returns this Game Object for further chaining. - * The `name` property is not populated by Phaser and is presented for your own use. - * - * @method Phaser.GameObjects.GameObject#setName - * @since 3.0.0 - * - * @param {string} value - The name to be given to this Game Object. - * - * @return {this} This GameObject. - */ - setName: function (value) - { - this.name = value; +/** + * Takes an array of items, such as Game Objects, or any objects with public `x` and + * `y` properties and then iterates through them. As this function iterates, it moves + * the position of the current element to be that of the previous entry in the array. + * This repeats until all items have been moved. + * + * The direction controls the order of iteration. A value of 0 (the default) assumes + * that the final item in the array is the 'head' item. + * + * A direction value of 1 assumes that the first item in the array is the 'head' item. + * + * The position of the 'head' item is set to the x/y values given to this function. + * Every other item in the array is then updated, in sequence, to be that of the + * previous (or next) entry in the array. + * + * The final x/y coords are returned, or set in the 'output' Vector2. + * + * Think of it as being like the game Snake, where the 'head' is moved and then + * each body piece is moved into the space of the previous piece. + * + * @function Phaser.Actions.ShiftPosition + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items] + * @generic {Phaser.Math.Vector2} O - [output,$return] + * + * @param {(Phaser.Types.Math.Vector2Like[]|Phaser.GameObjects.GameObject[])} items - An array of Game Objects, or objects with public x and y positions. The contents of this array are updated by this Action. + * @param {number} x - The x coordinate to place the head item at. + * @param {number} y - The y coordinate to place the head item at. + * @param {number} [direction=0] - The iteration direction. 0 = first to last and 1 = last to first. + * @param {Phaser.Types.Math.Vector2Like} [output] - An optional Vec2Like object to store the final position in. + * + * @return {Phaser.Types.Math.Vector2Like} The output vector. + */ +var ShiftPosition = function (items, x, y, direction, output) +{ + if (direction === undefined) { direction = 0; } + if (output === undefined) { output = new Vector2(); } - return this; - }, + var px; + var py; + var len = items.length; - /** - * Sets the current state of this Game Object. - * - * Phaser itself will never modify the State of a Game Object, although plugins may do so. - * - * For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'. - * The state value should typically be an integer (ideally mapped to a constant - * in your game code), but could also be a string. It is recommended to keep it light and simple. - * If you need to store complex data about your Game Object, look at using the Data Component instead. - * - * @method Phaser.GameObjects.GameObject#setState - * @since 3.16.0 - * - * @param {(number|string)} value - The state of the Game Object. - * - * @return {this} This GameObject. - */ - setState: function (value) + if (len === 1) { - this.state = value; - - return this; - }, + px = items[0].x; + py = items[0].y; - /** - * Adds a Data Manager component to this Game Object. - * - * @method Phaser.GameObjects.GameObject#setDataEnabled - * @since 3.0.0 - * @see Phaser.Data.DataManager - * - * @return {this} This GameObject. - */ - setDataEnabled: function () + items[0].x = x; + items[0].y = y; + } + else { - if (!this.data) - { - this.data = new DataManager(this); - } - - return this; - }, + var i = 1; + var pos = 0; - /** - * Allows you to store a key value pair within this Game Objects Data Manager. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * ```javascript - * sprite.setData('name', 'Red Gem Stone'); - * ``` - * - * You can also pass in an object of key value pairs as the first argument: - * - * ```javascript - * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); - * ``` - * - * To get a value back again you can call `getData`: - * - * ```javascript - * sprite.getData('gold'); - * ``` - * - * Or you can access the value directly via the `values` property, where it works like any other variable: - * - * ```javascript - * sprite.data.values.gold += 50; - * ``` - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * - * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. - * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. - * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. - * - * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. - * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. - * - * @method Phaser.GameObjects.GameObject#setData - * @since 3.0.0 - * - * @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. - * @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored. - * - * @return {this} This GameObject. - */ - setData: function (key, value) - { - if (!this.data) + if (direction === 0) { - this.data = new DataManager(this); + pos = len - 1; + i = len - 2; } - this.data.set(key, value); + px = items[pos].x; + py = items[pos].y; - return this; - }, + // Update the head item to the new x/y coordinates + items[pos].x = x; + items[pos].y = y; - /** - * Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * - * @method Phaser.GameObjects.GameObject#incData - * @since 3.23.0 - * - * @param {(string|object)} key - The key to increase the value for. - * @param {*} [data] - The value to increase for the given key. - * - * @return {this} This GameObject. - */ - incData: function (key, value) - { - if (!this.data) + for (var c = 0; c < len; c++) { - this.data = new DataManager(this); - } - - this.data.inc(key, value); + if (i >= len || i === -1) + { + continue; + } - return this; - }, + // Current item + var cur = items[i]; - /** - * Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * - * @method Phaser.GameObjects.GameObject#toggleData - * @since 3.23.0 - * - * @param {(string|object)} key - The key to toggle the value for. - * - * @return {this} This GameObject. - */ - toggleData: function (key) - { - if (!this.data) - { - this.data = new DataManager(this); - } + // Get current item x/y, to be passed to the next item in the list + var cx = cur.x; + var cy = cur.y; - this.data.toggle(key); + // Set current item to the previous items x/y + cur.x = px; + cur.y = py; - return this; - }, + // Set current as previous + px = cx; + py = cy; - /** - * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist. - * - * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: - * - * ```javascript - * sprite.getData('gold'); - * ``` - * - * Or access the value directly: - * - * ```javascript - * sprite.data.values.gold; - * ``` - * - * You can also pass in an array of keys, in which case an array of values will be returned: - * - * ```javascript - * sprite.getData([ 'gold', 'armor', 'health' ]); - * ``` - * - * This approach is useful for destructuring arrays in ES6. - * - * @method Phaser.GameObjects.GameObject#getData - * @since 3.0.0 - * - * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys. - * - * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array. - */ - getData: function (key) - { - if (!this.data) - { - this.data = new DataManager(this); + if (direction === 0) + { + i--; + } + else + { + i++; + } } + } - return this.data.get(key); - }, + // Return the final set of coordinates as they're effectively lost from the shift and may be needed - /** - * Pass this Game Object to the Input Manager to enable it for Input. - * - * Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area - * for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced - * input detection. - * - * If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If - * this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific - * shape for it to use. - * - * You can also provide an Input Configuration Object as the only argument to this method. - * - * @example - * sprite.setInteractive(); - * - * @example - * sprite.setInteractive(new Phaser.Geom.Circle(45, 46, 45), Phaser.Geom.Circle.Contains); - * - * @example - * graphics.setInteractive(new Phaser.Geom.Rectangle(0, 0, 128, 128), Phaser.Geom.Rectangle.Contains); - * - * @method Phaser.GameObjects.GameObject#setInteractive - * @since 3.0.0 - * - * @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not given it will try to create a Rectangle based on the texture frame. - * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The callback that determines if the pointer is within the Hit Area shape or not. If you provide a shape you must also provide a callback. - * @param {boolean} [dropZone=false] - Should this Game Object be treated as a drop zone target? - * - * @return {this} This GameObject. - */ - setInteractive: function (hitArea, hitAreaCallback, dropZone) - { - this.scene.sys.input.enable(this, hitArea, hitAreaCallback, dropZone); + output.x = px; + output.y = py; - return this; - }, + return output; +}; - /** - * If this Game Object has previously been enabled for input, this will disable it. - * - * An object that is disabled for input stops processing or being considered for - * input events, but can be turned back on again at any time by simply calling - * `setInteractive()` with no arguments provided. - * - * If want to completely remove interaction from this Game Object then use `removeInteractive` instead. - * - * @method Phaser.GameObjects.GameObject#disableInteractive - * @since 3.7.0 - * - * @return {this} This GameObject. - */ - disableInteractive: function () - { - if (this.input) - { - this.input.enabled = false; - } +module.exports = ShiftPosition; - return this; - }, - /** - * If this Game Object has previously been enabled for input, this will queue it - * for removal, causing it to no longer be interactive. The removal happens on - * the next game step, it is not immediate. - * - * The Interactive Object that was assigned to this Game Object will be destroyed, - * removed from the Input Manager and cleared from this Game Object. - * - * If you wish to re-enable this Game Object at a later date you will need to - * re-create its InteractiveObject by calling `setInteractive` again. - * - * If you wish to only temporarily stop an object from receiving input then use - * `disableInteractive` instead, as that toggles the interactive state, where-as - * this erases it completely. - * - * If you wish to resize a hit area, don't remove and then set it as being - * interactive. Instead, access the hitarea object directly and resize the shape - * being used. I.e.: `sprite.input.hitArea.setSize(width, height)` (assuming the - * shape is a Rectangle, which it is by default.) - * - * @method Phaser.GameObjects.GameObject#removeInteractive - * @since 3.7.0 - * - * @return {this} This GameObject. - */ - removeInteractive: function () - { - this.scene.sys.input.clear(this); +/***/ }), - this.input = undefined; +/***/ 86347: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * This callback is invoked when this Game Object is added to a Scene. - * - * Can be overriden by custom Game Objects, but be aware of some Game Objects that - * will use this, such as Sprites, to add themselves into the Update List. - * - * You can also listen for the `ADDED_TO_SCENE` event from this Game Object. - * - * @method Phaser.GameObjects.GameObject#addedToScene - * @since 3.50.0 - */ - addedToScene: function () - { - }, +var ArrayShuffle = __webpack_require__(18592); - /** - * This callback is invoked when this Game Object is removed from a Scene. - * - * Can be overriden by custom Game Objects, but be aware of some Game Objects that - * will use this, such as Sprites, to removed themselves from the Update List. - * - * You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object. - * - * @method Phaser.GameObjects.GameObject#removedFromScene - * @since 3.50.0 - */ - removedFromScene: function () - { - }, +/** + * Shuffles the array in place. The shuffled array is both modified and returned. + * + * @function Phaser.Actions.Shuffle + * @since 3.0.0 + * @see Phaser.Utils.Array.Shuffle + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + */ +var Shuffle = function (items) +{ + return ArrayShuffle(items); +}; - /** - * To be overridden by custom GameObjects. Allows base objects to be used in a Pool. - * - * @method Phaser.GameObjects.GameObject#update - * @since 3.0.0 - * - * @param {...*} [args] - args - */ - update: function () - { - }, +module.exports = Shuffle; - /** - * Returns a JSON representation of the Game Object. - * - * @method Phaser.GameObjects.GameObject#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object. - */ - toJSON: function () - { - return ComponentsToJSON(this); - }, - /** - * Compares the renderMask with the renderFlags to see if this Game Object will render or not. - * Also checks the Game Object against the given Cameras exclusion list. - * - * @method Phaser.GameObjects.GameObject#willRender - * @since 3.0.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object. - * - * @return {boolean} True if the Game Object should be rendered, otherwise false. - */ - willRender: function (camera) - { - return !(GameObject.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); - }, +/***/ }), - /** - * Returns an array containing the display list index of either this Game Object, or if it has one, - * its parent Container. It then iterates up through all of the parent containers until it hits the - * root of the display list (which is index 0 in the returned array). - * - * Used internally by the InputPlugin but also useful if you wish to find out the display depth of - * this Game Object and all of its ancestors. - * - * @method Phaser.GameObjects.GameObject#getIndexList - * @since 3.4.0 - * - * @return {number[]} An array of display list position indexes. - */ - getIndexList: function () - { - // eslint-disable-next-line consistent-this - var child = this; - var parent = this.parentContainer; +/***/ 1558: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var indexes = []; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - while (parent) - { - indexes.unshift(parent.getIndex(child)); +var MathSmoothStep = __webpack_require__(5514); - child = parent; +/** + * Smoothstep is a sigmoid-like interpolation and clamping function. + * + * The function depends on three parameters, the input x, the "left edge" and the "right edge", with the left edge being assumed smaller than the right edge. The function receives a real number x as an argument and returns 0 if x is less than or equal to the left edge, 1 if x is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial, between 0 and 1 otherwise. The slope of the smoothstep function is zero at both edges. This is convenient for creating a sequence of transitions using smoothstep to interpolate each segment as an alternative to using more sophisticated or expensive interpolation techniques. + * + * @function Phaser.Actions.SmoothStep + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {string} property - The property of the Game Object to interpolate. + * @param {number} min - The minimum interpolation value. + * @param {number} max - The maximum interpolation value. + * @param {boolean} [inc=false] - Should the values be incremented? `true` or set (`false`) + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + */ +var SmoothStep = function (items, property, min, max, inc) +{ + if (inc === undefined) { inc = false; } - if (!parent.parentContainer) - { - break; - } - else - { - parent = parent.parentContainer; - } - } + var step = Math.abs(max - min) / items.length; + var i; - if (this.displayList) + if (inc) + { + for (i = 0; i < items.length; i++) { - indexes.unshift(this.displayList.getIndex(child)); + items[i][property] += MathSmoothStep(i * step, min, max); } - else + } + else + { + for (i = 0; i < items.length; i++) { - indexes.unshift(this.scene.sys.displayList.getIndex(child)); + items[i][property] = MathSmoothStep(i * step, min, max); } + } - return indexes; - }, + return items; +}; - /** - * Adds this Game Object to the given Display List. - * - * If no Display List is specified, it will default to the Display List owned by the Scene to which - * this Game Object belongs. - * - * A Game Object can only exist on one Display List at any given time, but may move freely between them. - * - * If this Game Object is already on another Display List when this method is called, it will first - * be removed from it, before being added to the new list. - * - * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. - * - * If a Game Object isn't on any display list, it will not be rendered. If you just wish to temporarly - * disable it from rendering, consider using the `setVisible` method, instead. - * - * @method Phaser.GameObjects.GameObject#addToDisplayList - * @fires Phaser.Scenes.Events#ADDED_TO_SCENE - * @fires Phaser.GameObjects.Events#ADDED_TO_SCENE - * @since 3.53.0 - * - * @param {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} [displayList] - The Display List to add to. Defaults to the Scene Display List. - * - * @return {this} This Game Object. - */ - addToDisplayList: function (displayList) - { - if (displayList === undefined) { displayList = this.scene.sys.displayList; } +module.exports = SmoothStep; - if (this.displayList && this.displayList !== displayList) - { - this.removeFromDisplayList(); - } - // Don't repeat if it's already on this list - if (!displayList.exists(this)) - { - this.displayList = displayList; +/***/ }), - displayList.add(this, true); +/***/ 9938: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - displayList.queueDepthSort(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.emit(Events.ADDED_TO_SCENE, this, this.scene); +var MathSmootherStep = __webpack_require__(87736); - displayList.events.emit(SceneEvents.ADDED_TO_SCENE, this, this.scene); - } +/** + * Smootherstep is a sigmoid-like interpolation and clamping function. + * + * The function depends on three parameters, the input x, the "left edge" and the "right edge", with the left edge being assumed smaller than the right edge. The function receives a real number x as an argument and returns 0 if x is less than or equal to the left edge, 1 if x is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial, between 0 and 1 otherwise. The slope of the smoothstep function is zero at both edges. This is convenient for creating a sequence of transitions using smoothstep to interpolate each segment as an alternative to using more sophisticated or expensive interpolation techniques. + * + * @function Phaser.Actions.SmootherStep + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {string} property - The property of the Game Object to interpolate. + * @param {number} min - The minimum interpolation value. + * @param {number} max - The maximum interpolation value. + * @param {boolean} [inc=false] - Should the values be incremented? `true` or set (`false`) + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + */ +var SmootherStep = function (items, property, min, max, inc) +{ + if (inc === undefined) { inc = false; } - return this; - }, + var step = Math.abs(max - min) / items.length; + var i; - /** - * Adds this Game Object to the Update List belonging to the Scene. - * - * When a Game Object is added to the Update List it will have its `preUpdate` method called - * every game frame. This method is passed two parameters: `delta` and `time`. - * - * If you wish to run your own logic within `preUpdate` then you should always call - * `preUpdate.super(delta, time)` within it, or it may fail to process required operations, - * such as Sprite animations. - * - * @method Phaser.GameObjects.GameObject#addToUpdateList - * @since 3.53.0 - * - * @return {this} This Game Object. - */ - addToUpdateList: function () + if (inc) { - if (this.scene && this.preUpdate) + for (i = 0; i < items.length; i++) { - this.scene.sys.updateList.add(this); + items[i][property] += MathSmootherStep(i * step, min, max); } - - return this; - }, - - /** - * Removes this Game Object from the Display List it is currently on. - * - * A Game Object can only exist on one Display List at any given time, but may move freely removed - * and added back at a later stage. - * - * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. - * - * If a Game Object isn't on any Display List, it will not be rendered. If you just wish to temporarly - * disable it from rendering, consider using the `setVisible` method, instead. - * - * @method Phaser.GameObjects.GameObject#removeFromDisplayList - * @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE - * @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE - * @since 3.53.0 - * - * @return {this} This Game Object. - */ - removeFromDisplayList: function () + } + else { - var displayList = this.displayList || this.scene.sys.displayList; - - if (displayList.exists(this)) + for (i = 0; i < items.length; i++) { - displayList.remove(this, true); + items[i][property] = MathSmootherStep(i * step, min, max); + } + } - displayList.queueDepthSort(); + return items; +}; - this.displayList = null; +module.exports = SmootherStep; - this.emit(Events.REMOVED_FROM_SCENE, this, this.scene); - displayList.events.emit(SceneEvents.REMOVED_FROM_SCENE, this, this.scene); - } +/***/ }), - return this; - }, +/***/ 71060: +/***/ ((module) => { - /** - * Removes this Game Object from the Scene's Update List. - * - * When a Game Object is on the Update List, it will have its `preUpdate` method called - * every game frame. Calling this method will remove it from the list, preventing this. - * - * Removing a Game Object from the Update List will stop most internal functions working. - * For example, removing a Sprite from the Update List will prevent it from being able to - * run animations. - * - * @method Phaser.GameObjects.GameObject#removeFromUpdateList - * @since 3.53.0 - * - * @return {this} This Game Object. - */ - removeFromUpdateList: function () +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Takes an array of Game Objects and then modifies their `property` so the value equals, or is incremented, by the + * calculated spread value. + * + * The spread value is derived from the given `min` and `max` values and the total number of items in the array. + * + * For example, to cause an array of Sprites to change in alpha from 0 to 1 you could call: + * + * ```javascript + * Phaser.Actions.Spread(itemsArray, 'alpha', 0, 1); + * ``` + * + * @function Phaser.Actions.Spread + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {string} property - The property of the Game Object to spread. + * @param {number} min - The minimum value. + * @param {number} max - The maximum value. + * @param {boolean} [inc=false] - Should the values be incremented? `true` or set (`false`) + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that were passed to this Action. + */ +var Spread = function (items, property, min, max, inc) +{ + if (inc === undefined) { inc = false; } + if (items.length === 0) { return items; } + if (items.length === 1) // if only one item put it at the center { - if (this.scene && this.preUpdate) + if (inc) { - this.scene.sys.updateList.remove(this); + items[0][property] += (max + min) / 2; + } + else + { + items[0][property] = (max + min) / 2; } - return this; - }, + return items; + } - /** - * Destroys this Game Object removing it from the Display List and Update List and - * severing all ties to parent resources. - * - * Also removes itself from the Input Manager and Physics Manager if previously enabled. - * - * Use this to remove a Game Object from your game if you don't ever plan to use it again. - * As long as no reference to it exists within your own code it should become free for - * garbage collection by the browser. - * - * If you just want to temporarily disable an object then look at using the - * Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected. - * - * @method Phaser.GameObjects.GameObject#destroy - * @fires Phaser.GameObjects.Events#DESTROY - * @since 3.0.0 - * - * @param {boolean} [fromScene=false] - `True` if this Game Object is being destroyed by the Scene, `false` if not. - */ - destroy: function (fromScene) + var step = Math.abs(max - min) / (items.length - 1); + var i; + + if (inc) { - // This Game Object has already been destroyed - if (!this.scene || this.ignoreDestroy) + for (i = 0; i < items.length; i++) { - return; + items[i][property] += i * step + min; } - - if (fromScene === undefined) { fromScene = false; } - - if (this.preDestroy) + } + else + { + for (i = 0; i < items.length; i++) { - this.preDestroy.call(this); + items[i][property] = i * step + min; } + } - this.emit(Events.DESTROY, this, fromScene); + return items; +}; - this.removeAllListeners(); +module.exports = Spread; - if (this.postPipelines) - { - this.resetPostPipeline(true); - } - this.removeFromDisplayList(); - this.removeFromUpdateList(); +/***/ }), - if (this.input) - { - this.scene.sys.input.clear(this); +/***/ 11207: +/***/ ((module) => { - this.input = undefined; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (this.data) - { - this.data.destroy(); +/** + * Takes an array of Game Objects and toggles the visibility of each one. + * Those previously `visible = false` will become `visible = true`, and vice versa. + * + * @function Phaser.Actions.ToggleVisible + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + */ +var ToggleVisible = function (items) +{ + for (var i = 0; i < items.length; i++) + { + items[i].visible = !items[i].visible; + } - this.data = undefined; - } + return items; +}; - if (this.body) - { - this.body.destroy(); +module.exports = ToggleVisible; - this.body = undefined; - } - this.active = false; - this.visible = false; +/***/ }), - this.scene = undefined; - this.parentContainer = undefined; - } +/***/ 24404: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -}); +/** + * @author Richard Davey + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Wrap = __webpack_require__(1071); /** - * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not. + * Iterates through the given array and makes sure that each objects x and y + * properties are wrapped to keep them contained within the given Rectangles + * area. * - * @constant {number} RENDER_MASK - * @memberof Phaser.GameObjects.GameObject - * @default + * @function Phaser.Actions.WrapInRectangle + * @since 3.0.0 + * @see Phaser.Math.Wrap + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. + * @param {Phaser.Geom.Rectangle} rect - The rectangle which the objects will be wrapped to remain within. + * @param {number} [padding=0] - An amount added to each side of the rectangle during the operation. + * + * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. */ -GameObject.RENDER_MASK = 15; +var WrapInRectangle = function (items, rect, padding) +{ + if (padding === undefined) + { + padding = 0; + } -module.exports = GameObject; + for (var i = 0; i < items.length; i++) + { + var item = items[i]; + + item.x = Wrap(item.x, rect.left - padding, rect.right + padding); + item.y = Wrap(item.y, rect.top - padding, rect.bottom + padding); + } + + return items; +}; + +module.exports = WrapInRectangle; /***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 83979: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var PluginCache = __webpack_require__(24); -var SceneEvents = __webpack_require__(20); +/** + * @namespace Phaser.Actions + */ + +module.exports = { + + AlignTo: __webpack_require__(62270), + Angle: __webpack_require__(61148), + Call: __webpack_require__(22015), + GetFirst: __webpack_require__(31060), + GetLast: __webpack_require__(52367), + GridAlign: __webpack_require__(12673), + IncAlpha: __webpack_require__(691), + IncX: __webpack_require__(3877), + IncXY: __webpack_require__(71020), + IncY: __webpack_require__(28970), + PlaceOnCircle: __webpack_require__(82249), + PlaceOnEllipse: __webpack_require__(30285), + PlaceOnLine: __webpack_require__(61557), + PlaceOnRectangle: __webpack_require__(63549), + PlaceOnTriangle: __webpack_require__(51629), + PlayAnimation: __webpack_require__(1045), + PropertyValueInc: __webpack_require__(6124), + PropertyValueSet: __webpack_require__(23646), + RandomCircle: __webpack_require__(4392), + RandomEllipse: __webpack_require__(94985), + RandomLine: __webpack_require__(63305), + RandomRectangle: __webpack_require__(90739), + RandomTriangle: __webpack_require__(91417), + Rotate: __webpack_require__(26182), + RotateAround: __webpack_require__(87299), + RotateAroundDistance: __webpack_require__(92194), + ScaleX: __webpack_require__(30363), + ScaleXY: __webpack_require__(51449), + ScaleY: __webpack_require__(64895), + SetAlpha: __webpack_require__(30329), + SetBlendMode: __webpack_require__(43954), + SetDepth: __webpack_require__(70688), + SetHitArea: __webpack_require__(8314), + SetOrigin: __webpack_require__(12894), + SetRotation: __webpack_require__(38767), + SetScale: __webpack_require__(18584), + SetScaleX: __webpack_require__(17381), + SetScaleY: __webpack_require__(74370), + SetScrollFactor: __webpack_require__(27773), + SetScrollFactorX: __webpack_require__(75257), + SetScrollFactorY: __webpack_require__(54512), + SetTint: __webpack_require__(69423), + SetVisible: __webpack_require__(58291), + SetX: __webpack_require__(94833), + SetXY: __webpack_require__(14284), + SetY: __webpack_require__(96574), + ShiftPosition: __webpack_require__(74086), + Shuffle: __webpack_require__(86347), + SmootherStep: __webpack_require__(9938), + SmoothStep: __webpack_require__(1558), + Spread: __webpack_require__(71060), + ToggleVisible: __webpack_require__(11207), + WrapInRectangle: __webpack_require__(24404) + +}; + + +/***/ }), + +/***/ 85463: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(16938); +var FindClosestInSorted = __webpack_require__(2406); +var Frame = __webpack_require__(71519); +var GetValue = __webpack_require__(10850); +var SortByDigits = __webpack_require__(28834); /** * @classdesc - * The Game Object Creator is a Scene plugin that allows you to quickly create many common - * types of Game Objects and return them. Unlike the Game Object Factory, they are not automatically - * added to the Scene. + * A Frame based Animation. * - * Game Objects directly register themselves with the Creator and inject their own creation - * methods into the class. + * Animations in Phaser consist of a sequence of `AnimationFrame` objects, which are managed by + * this class, along with properties that impact playback, such as the animations frame rate + * or delay. * - * @class GameObjectCreator - * @memberof Phaser.GameObjects + * This class contains all of the properties and methods needed to handle playback of the animation + * directly to an `AnimationState` instance, which is owned by a Sprite, or similar Game Object. + * + * You don't typically create an instance of this class directly, but instead go via + * either the `AnimationManager` or the `AnimationState` and use their `create` methods, + * depending on if you need a global animation, or local to a specific Sprite. + * + * @class Animation + * @memberof Phaser.Animations * @constructor * @since 3.0.0 * - * @param {Phaser.Scene} scene - The Scene to which this Game Object Factory belongs. + * @param {Phaser.Animations.AnimationManager} manager - A reference to the global Animation Manager + * @param {string} key - The unique identifying string for this animation. + * @param {Phaser.Types.Animations.Animation} config - The Animation configuration. */ -var GameObjectCreator = new Class({ +var Animation = new Class({ initialize: - function GameObjectCreator (scene) + function Animation (manager, key, config) { /** - * The Scene to which this Game Object Creator belongs. + * A reference to the global Animation Manager. * - * @name Phaser.GameObjects.GameObjectCreator#scene - * @type {Phaser.Scene} - * @protected + * @name Phaser.Animations.Animation#manager + * @type {Phaser.Animations.AnimationManager} * @since 3.0.0 */ - this.scene = scene; + this.manager = manager; /** - * A reference to the Scene.Systems. + * The unique identifying string for this animation. * - * @name Phaser.GameObjects.GameObjectCreator#systems - * @type {Phaser.Scenes.Systems} - * @protected + * @name Phaser.Animations.Animation#key + * @type {string} * @since 3.0.0 */ - this.systems = scene.sys; + this.key = key; /** - * A reference to the Scene Event Emitter. + * A frame based animation (as opposed to a bone based animation) * - * @name Phaser.GameObjects.GameObjectCreator#events - * @type {Phaser.Events.EventEmitter} - * @protected - * @since 3.50.0 + * @name Phaser.Animations.Animation#type + * @type {string} + * @default frame + * @since 3.0.0 */ - this.events = scene.sys.events; + this.type = 'frame'; /** - * A reference to the Scene Display List. + * Extract all the frame data into the frames array. * - * @name Phaser.GameObjects.GameObjectCreator#displayList - * @type {Phaser.GameObjects.DisplayList} - * @protected + * @name Phaser.Animations.Animation#frames + * @type {Phaser.Animations.AnimationFrame[]} * @since 3.0.0 */ - this.displayList; + this.frames = this.getFrames( + manager.textureManager, + GetValue(config, 'frames', []), + GetValue(config, 'defaultTextureKey', null), + GetValue(config, 'sortFrames', true) + ); /** - * A reference to the Scene Update List. + * The frame rate of playback in frames per second (default 24 if duration is null) * - * @name Phaser.GameObjects.GameObjectCreator#updateList - * @type {Phaser.GameObjects.UpdateList} - * @protected + * @name Phaser.Animations.Animation#frameRate + * @type {number} + * @default 24 * @since 3.0.0 */ - this.updateList; - - this.events.once(SceneEvents.BOOT, this.boot, this); - this.events.on(SceneEvents.START, this.start, this); - }, + this.frameRate = GetValue(config, 'frameRate', null); - /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. - * - * @method Phaser.GameObjects.GameObjectCreator#boot - * @private - * @since 3.5.1 - */ - boot: function () - { - this.displayList = this.systems.displayList; - this.updateList = this.systems.updateList; + /** + * How long the animation should play for, in milliseconds. + * If the `frameRate` property has been set then it overrides this value, + * otherwise the `frameRate` is derived from `duration`. + * + * @name Phaser.Animations.Animation#duration + * @type {number} + * @since 3.0.0 + */ + this.duration = GetValue(config, 'duration', null); - this.events.once(SceneEvents.DESTROY, this.destroy, this); - }, + /** + * How many ms per frame, not including frame specific modifiers. + * + * @name Phaser.Animations.Animation#msPerFrame + * @type {number} + * @since 3.0.0 + */ + this.msPerFrame; - /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. + /** + * Skip frames if the time lags, or always advanced anyway? + * + * @name Phaser.Animations.Animation#skipMissedFrames + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.skipMissedFrames = GetValue(config, 'skipMissedFrames', true); + + /** + * The delay in ms before the playback will begin. + * + * @name Phaser.Animations.Animation#delay + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.delay = GetValue(config, 'delay', 0); + + /** + * Number of times to repeat the animation. Set to -1 to repeat forever. + * + * @name Phaser.Animations.Animation#repeat + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.repeat = GetValue(config, 'repeat', 0); + + /** + * The delay in ms before the a repeat play starts. + * + * @name Phaser.Animations.Animation#repeatDelay + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.repeatDelay = GetValue(config, 'repeatDelay', 0); + + /** + * Should the animation yoyo (reverse back down to the start) before repeating? + * + * @name Phaser.Animations.Animation#yoyo + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.yoyo = GetValue(config, 'yoyo', false); + + /** + * If the animation has a delay set, before playback will begin, this + * controls when the first frame is set on the Sprite. If this property + * is 'false' then the frame is set only after the delay has expired. + * This is the default behavior. + * + * @name Phaser.Animations.Animation#showBeforeDelay + * @type {boolean} + * @default false + * @since 3.60.0 + */ + this.showBeforeDelay = GetValue(config, 'showBeforeDelay', false); + + /** + * Should the GameObject's `visible` property be set to `true` when the animation starts to play? + * + * @name Phaser.Animations.Animation#showOnStart + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.showOnStart = GetValue(config, 'showOnStart', false); + + /** + * Should the GameObject's `visible` property be set to `false` when the animation finishes? + * + * @name Phaser.Animations.Animation#hideOnComplete + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.hideOnComplete = GetValue(config, 'hideOnComplete', false); + + /** + * Global pause. All Game Objects using this Animation instance are impacted by this property. + * + * @name Phaser.Animations.Animation#paused + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.paused = false; + + this.calculateDuration(this, this.getTotalFrames(), this.duration, this.frameRate); + + if (this.manager.on) + { + this.manager.on(Events.PAUSE_ALL, this.pause, this); + this.manager.on(Events.RESUME_ALL, this.resume, this); + } + }, + + /** + * Gets the total number of frames in this animation. * - * @method Phaser.GameObjects.GameObjectCreator#start - * @private - * @since 3.5.0 + * @method Phaser.Animations.Animation#getTotalFrames + * @since 3.50.0 + * + * @return {number} The total number of frames in this animation. */ - start: function () + getTotalFrames: function () { - this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); + return this.frames.length; }, /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. + * Calculates the duration, frame rate and msPerFrame values. * - * @method Phaser.GameObjects.GameObjectCreator#shutdown - * @private + * @method Phaser.Animations.Animation#calculateDuration + * @since 3.50.0 + * + * @param {Phaser.Animations.Animation} target - The target to set the values on. + * @param {number} totalFrames - The total number of frames in the animation. + * @param {?number} [duration] - The duration to calculate the frame rate from. Pass `null` if you wish to set the `frameRate` instead. + * @param {?number} [frameRate] - The frame rate to calculate the duration from. + */ + calculateDuration: function (target, totalFrames, duration, frameRate) + { + if (duration === null && frameRate === null) + { + // No duration or frameRate given, use default frameRate of 24fps + target.frameRate = 24; + target.duration = (24 / totalFrames) * 1000; + } + else if (duration && frameRate === null) + { + // Duration given but no frameRate, so set the frameRate based on duration + // I.e. 12 frames in the animation, duration = 4000 ms + // So frameRate is 12 / (4000 / 1000) = 3 fps + target.duration = duration; + target.frameRate = totalFrames / (duration / 1000); + } + else + { + // frameRate given, derive duration from it (even if duration also specified) + // I.e. 15 frames in the animation, frameRate = 30 fps + // So duration is 15 / 30 = 0.5 * 1000 (half a second, or 500ms) + target.frameRate = frameRate; + target.duration = (totalFrames / frameRate) * 1000; + } + + target.msPerFrame = 1000 / target.frameRate; + }, + + /** + * Add frames to the end of the animation. + * + * @method Phaser.Animations.Animation#addFrame * @since 3.0.0 + * + * @param {(string|Phaser.Types.Animations.AnimationFrame[])} config - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects. + * + * @return {this} This Animation object. */ - shutdown: function () + addFrame: function (config) { - this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); + return this.addFrameAt(this.frames.length, config); }, /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. + * Add frame/s into the animation. * - * @method Phaser.GameObjects.GameObjectCreator#destroy - * @private + * @method Phaser.Animations.Animation#addFrameAt * @since 3.0.0 + * + * @param {number} index - The index to insert the frame at within the animation. + * @param {(string|Phaser.Types.Animations.AnimationFrame[])} config - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects. + * + * @return {this} This Animation object. */ - destroy: function () + addFrameAt: function (index, config) { - this.shutdown(); + var newFrames = this.getFrames(this.manager.textureManager, config); - this.events.off(SceneEvents.START, this.start, this); + if (newFrames.length > 0) + { + if (index === 0) + { + this.frames = newFrames.concat(this.frames); + } + else if (index === this.frames.length) + { + this.frames = this.frames.concat(newFrames); + } + else + { + var pre = this.frames.slice(0, index); + var post = this.frames.slice(index); - this.scene = null; - this.systems = null; - this.events = null; + this.frames = pre.concat(newFrames, post); + } - this.displayList = null; - this.updateList = null; - } + this.updateFrameSequence(); + } -}); + return this; + }, -/** - * Static method called directly by the Game Object creator functions. - * With this method you can register a custom GameObject factory in the GameObjectCreator, - * providing a name (`factoryType`) and the constructor (`factoryFunction`) in order - * to be called when you invoke Phaser.Scene.make[ factoryType ] method. - * - * @method Phaser.GameObjects.GameObjectCreator.register - * @static - * @since 3.0.0 - * - * @param {string} factoryType - The key of the factory that you will use to call to Phaser.Scene.make[ factoryType ] method. - * @param {function} factoryFunction - The constructor function to be called when you invoke to the Phaser.Scene.make method. - */ -GameObjectCreator.register = function (factoryType, factoryFunction) -{ - if (!GameObjectCreator.prototype.hasOwnProperty(factoryType)) + /** + * Check if the given frame index is valid. + * + * @method Phaser.Animations.Animation#checkFrame + * @since 3.0.0 + * + * @param {number} index - The index to be checked. + * + * @return {boolean} `true` if the index is valid, otherwise `false`. + */ + checkFrame: function (index) { - GameObjectCreator.prototype[factoryType] = factoryFunction; - } -}; + return (index >= 0 && index < this.frames.length); + }, -/** - * Static method called directly by the Game Object Creator functions. - * - * With this method you can remove a custom Game Object Creator that has been previously - * registered in the Game Object Creator. Pass in its `factoryType` in order to remove it. - * - * @method Phaser.GameObjects.GameObjectCreator.remove - * @static - * @since 3.0.0 - * - * @param {string} factoryType - The key of the factory that you want to remove from the GameObjectCreator. - */ -GameObjectCreator.remove = function (factoryType) -{ - if (GameObjectCreator.prototype.hasOwnProperty(factoryType)) + /** + * Called internally when this Animation first starts to play. + * Sets the accumulator and nextTick properties. + * + * @method Phaser.Animations.Animation#getFirstTick + * @protected + * @since 3.0.0 + * + * @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call. + */ + getFirstTick: function (state) { - delete GameObjectCreator.prototype[factoryType]; - } -}; + // When is the first update due? + state.accumulator = 0; -PluginCache.register('GameObjectCreator', GameObjectCreator, 'make'); + state.nextTick = state.msPerFrame + state.currentFrame.duration; + }, -module.exports = GameObjectCreator; + /** + * Returns the AnimationFrame at the provided index + * + * @method Phaser.Animations.Animation#getFrameAt + * @protected + * @since 3.0.0 + * + * @param {number} index - The index in the AnimationFrame array + * + * @return {Phaser.Animations.AnimationFrame} The frame at the index provided from the animation sequence + */ + getFrameAt: function (index) + { + return this.frames[index]; + }, + /** + * Creates AnimationFrame instances based on the given frame data. + * + * @method Phaser.Animations.Animation#getFrames + * @since 3.0.0 + * + * @param {Phaser.Textures.TextureManager} textureManager - A reference to the global Texture Manager. + * @param {(string|Phaser.Types.Animations.AnimationFrame[])} frames - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects. + * @param {string} [defaultTextureKey] - The key to use if no key is set in the frame configuration object. + * + * @return {Phaser.Animations.AnimationFrame[]} An array of newly created AnimationFrame instances. + */ + getFrames: function (textureManager, frames, defaultTextureKey, sortFrames) + { + if (sortFrames === undefined) { sortFrames = true; } -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { + var out = []; + var prev; + var animationFrame; + var index = 1; + var i; + var textureKey; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // if frames is a string, we'll get all the frames from the texture manager as if it's a sprite sheet + if (typeof frames === 'string') + { + textureKey = frames; -var IsPlainObject = __webpack_require__(7); + if (!textureManager.exists(textureKey)) + { + console.warn('Texture "%s" not found', textureKey); -// @param {boolean} deep - Perform a deep copy? -// @param {object} target - The target object to copy to. -// @return {object} The extended object. + return out; + } -/** - * This is a slightly modified version of http://api.jquery.com/jQuery.extend/ - * - * @function Phaser.Utils.Objects.Extend - * @since 3.0.0 - * - * @param {...*} [args] - The objects that will be mixed. - * - * @return {object} The extended object. - */ -var Extend = function () -{ - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; + var texture = textureManager.get(textureKey); + var frameKeys = texture.getFrameNames(); - // Handle a deep copy situation - if (typeof target === 'boolean') - { - deep = target; - target = arguments[1] || {}; + if (sortFrames) + { + SortByDigits(frameKeys); + } - // skip the boolean and the target - i = 2; - } + frames = []; - // extend Phaser if only one argument is passed - if (length === i) - { - target = this; - --i; - } + frameKeys.forEach(function (value) + { + frames.push({ key: textureKey, frame: value }); + }); + } - for (; i < length; i++) - { - // Only deal with non-null/undefined values - if ((options = arguments[i]) != null) + if (!Array.isArray(frames) || frames.length === 0) { - // Extend the base object - for (name in options) + return out; + } + + for (i = 0; i < frames.length; i++) + { + var item = frames[i]; + + var key = GetValue(item, 'key', defaultTextureKey); + + if (!key) { - src = target[name]; - copy = options[name]; + continue; + } - // Prevent never-ending loop - if (target === copy) - { - continue; - } + // Could be an integer or a string + var frame = GetValue(item, 'frame', 0); - // Recurse if we're merging plain objects or arrays - if (deep && copy && (IsPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) - { - if (copyIsArray) - { - copyIsArray = false; - clone = src && Array.isArray(src) ? src : []; - } - else - { - clone = src && IsPlainObject(src) ? src : {}; - } + // The actual texture frame + var textureFrame = textureManager.getFrame(key, frame); - // Never move original objects, clone them - target[name] = Extend(deep, clone, copy); + if (!textureFrame) + { + console.warn('Texture "%s" not found', key); - // Don't bring in undefined values - } - else if (copy !== undefined) - { - target[name] = copy; - } + continue; } - } - } - - // Return the modified object - return target; -}; -module.exports = Extend; + animationFrame = new Frame(key, frame, index, textureFrame); + animationFrame.duration = GetValue(item, 'duration', 0); -/***/ }), -/* 18 */ -/***/ (function(module, exports) { + animationFrame.isFirst = (!prev); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // The previously created animationFrame + if (prev) + { + prev.nextFrame = animationFrame; -/** - * 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)); -}; + animationFrame.prevFrame = prev; + } -module.exports = Clamp; + out.push(animationFrame); + prev = animationFrame; -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { + index++; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (out.length > 0) + { + animationFrame.isLast = true; -var TransformMatrix = __webpack_require__(25); + // Link them end-to-end, so they loop + animationFrame.nextFrame = out[0]; -var tempMatrix1 = new TransformMatrix(); -var tempMatrix2 = new TransformMatrix(); -var tempMatrix3 = new TransformMatrix(); + out[0].prevFrame = animationFrame; -var result = { camera: tempMatrix1, sprite: tempMatrix2, calc: tempMatrix3 }; + // Generate the progress data -/** - * 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; + var slice = 1 / (out.length - 1); - spriteMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY); + for (i = 0; i < out.length; i++) + { + out[i].progress = i * slice; + } + } - camMatrix.copyFrom(camera.matrix); + return out; + }, - if (parentMatrix) + /** + * Called internally. Sets the accumulator and nextTick values of the current Animation. + * + * @method Phaser.Animations.Animation#getNextTick + * @since 3.0.0 + * + * @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call. + */ + getNextTick: function (state) { - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY); + state.accumulator -= state.nextTick; - // Undo the camera scroll - spriteMatrix.e = src.x; - spriteMatrix.f = src.y; - } - else + state.nextTick = state.msPerFrame + state.currentFrame.duration; + }, + + /** + * Returns the frame closest to the given progress value between 0 and 1. + * + * @method Phaser.Animations.Animation#getFrameByProgress + * @since 3.4.0 + * + * @param {number} value - A value between 0 and 1. + * + * @return {Phaser.Animations.AnimationFrame} The frame closest to the given progress value. + */ + getFrameByProgress: function (value) { - spriteMatrix.e -= camera.scrollX * src.scrollFactorX; - spriteMatrix.f -= camera.scrollY * src.scrollFactorY; - } + value = Clamp(value, 0, 1); - // Multiply by the Sprite matrix, store result in calcMatrix - camMatrix.multiply(spriteMatrix, calcMatrix); + return FindClosestInSorted(value, this.frames, 'progress'); + }, - return result; -}; + /** + * Advance the animation frame. + * + * @method Phaser.Animations.Animation#nextFrame + * @since 3.0.0 + * + * @param {Phaser.Animations.AnimationState} state - The Animation State to advance. + */ + nextFrame: function (state) + { + var frame = state.currentFrame; -module.exports = GetCalcMatrix; + if (frame.isLast) + { + // We're at the end of the animation + // Yoyo? (happens before repeat) + if (state.yoyo) + { + this.handleYoyoFrame(state, false); + } + else if (state.repeatCounter > 0) + { + // Repeat (happens before complete) -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { + if (state.inReverse && state.forward) + { + state.forward = false; + } + else + { + this.repeatAnimation(state); + } + } + else + { + state.complete(); + } + } + else + { + this.updateAndGetNextTick(state, frame.nextFrame); + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Handle the yoyo functionality in nextFrame and previousFrame methods. + * + * @method Phaser.Animations.Animation#handleYoyoFrame + * @private + * @since 3.12.0 + * + * @param {Phaser.Animations.AnimationState} state - The Animation State to advance. + * @param {boolean} isReverse - Is animation in reverse mode? (Default: false) + */ + handleYoyoFrame: function (state, isReverse) + { + if (!isReverse) { isReverse = false; } -/** - * @namespace Phaser.Scenes.Events - */ + if (state.inReverse === !isReverse && state.repeatCounter > 0) + { + if (state.repeatDelay === 0 || state.pendingRepeat) + { + state.forward = isReverse; + } -module.exports = { + this.repeatAnimation(state); - ADDED_TO_SCENE: __webpack_require__(656), - BOOT: __webpack_require__(657), - CREATE: __webpack_require__(658), - DESTROY: __webpack_require__(659), - PAUSE: __webpack_require__(660), - POST_UPDATE: __webpack_require__(661), - PRE_RENDER: __webpack_require__(662), - PRE_UPDATE: __webpack_require__(663), - READY: __webpack_require__(664), - REMOVED_FROM_SCENE: __webpack_require__(665), - RENDER: __webpack_require__(666), - RESUME: __webpack_require__(667), - SHUTDOWN: __webpack_require__(668), - SLEEP: __webpack_require__(669), - START: __webpack_require__(670), - TRANSITION_COMPLETE: __webpack_require__(671), - TRANSITION_INIT: __webpack_require__(672), - TRANSITION_OUT: __webpack_require__(673), - TRANSITION_START: __webpack_require__(674), - TRANSITION_WAKE: __webpack_require__(675), - UPDATE: __webpack_require__(676), - WAKE: __webpack_require__(677) + return; + } -}; + if (state.inReverse !== isReverse && state.repeatCounter === 0) + { + state.complete(); + return; + } -/***/ }), -/* 21 */ -/***/ (function(module, exports) { + state.forward = isReverse; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var frame = (isReverse) ? state.currentFrame.nextFrame : state.currentFrame.prevFrame; -var FILE_CONST = { + this.updateAndGetNextTick(state, frame); + }, /** - * The Loader is idle. - * - * @name Phaser.Loader.LOADER_IDLE - * @type {number} - * @since 3.0.0 + * Returns the animation last frame. + * + * @method Phaser.Animations.Animation#getLastFrame + * @since 3.12.0 + * + * @return {Phaser.Animations.AnimationFrame} The last Animation Frame. */ - LOADER_IDLE: 0, + getLastFrame: function () + { + return this.frames[this.frames.length - 1]; + }, /** - * The Loader is actively loading. - * - * @name Phaser.Loader.LOADER_LOADING - * @type {number} + * Called internally when the Animation is playing backwards. + * Sets the previous frame, causing a yoyo, repeat, complete or update, accordingly. + * + * @method Phaser.Animations.Animation#previousFrame * @since 3.0.0 + * + * @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call. */ - LOADER_LOADING: 1, + previousFrame: function (state) + { + var frame = state.currentFrame; - /** - * The Loader is processing files is has loaded. - * - * @name Phaser.Loader.LOADER_PROCESSING - * @type {number} - * @since 3.0.0 - */ - LOADER_PROCESSING: 2, + if (frame.isFirst) + { + // We're at the start of the animation + if (state.yoyo) + { + this.handleYoyoFrame(state, true); + } + else if (state.repeatCounter > 0) + { + if (state.inReverse && !state.forward) + { + this.repeatAnimation(state); + } + else + { + // Repeat (happens before complete) + state.forward = true; - /** - * The Loader has completed loading and processing. - * - * @name Phaser.Loader.LOADER_COMPLETE - * @type {number} - * @since 3.0.0 - */ - LOADER_COMPLETE: 3, + this.repeatAnimation(state); + } + } + else + { + state.complete(); + } + } + else + { + this.updateAndGetNextTick(state, frame.prevFrame); + } + }, /** - * The Loader is shutting down. - * - * @name Phaser.Loader.LOADER_SHUTDOWN - * @type {number} - * @since 3.0.0 + * Update Frame and Wait next tick. + * + * @method Phaser.Animations.Animation#updateAndGetNextTick + * @private + * @since 3.12.0 + * + * @param {Phaser.Animations.AnimationState} state - The Animation State. + * @param {Phaser.Animations.AnimationFrame} frame - An Animation frame. */ - LOADER_SHUTDOWN: 4, + updateAndGetNextTick: function (state, frame) + { + state.setCurrentFrame(frame); - /** - * The Loader has been destroyed. - * - * @name Phaser.Loader.LOADER_DESTROYED - * @type {number} - * @since 3.0.0 - */ - LOADER_DESTROYED: 5, + this.getNextTick(state); + }, /** - * File is in the load queue but not yet started - * - * @name Phaser.Loader.FILE_PENDING - * @type {number} + * Removes the given AnimationFrame from this Animation instance. + * This is a global action. Any Game Object using this Animation will be impacted by this change. + * + * @method Phaser.Animations.Animation#removeFrame * @since 3.0.0 + * + * @param {Phaser.Animations.AnimationFrame} frame - The AnimationFrame to be removed. + * + * @return {this} This Animation object. */ - FILE_PENDING: 10, + removeFrame: function (frame) + { + var index = this.frames.indexOf(frame); - /** - * File has been started to load by the loader (onLoad called) - * - * @name Phaser.Loader.FILE_LOADING - * @type {number} - * @since 3.0.0 - */ - FILE_LOADING: 11, + if (index !== -1) + { + this.removeFrameAt(index); + } + + return this; + }, /** - * File has loaded successfully, awaiting processing - * - * @name Phaser.Loader.FILE_LOADED - * @type {number} + * Removes a frame from the AnimationFrame array at the provided index + * and updates the animation accordingly. + * + * @method Phaser.Animations.Animation#removeFrameAt * @since 3.0.0 + * + * @param {number} index - The index in the AnimationFrame array + * + * @return {this} This Animation object. */ - FILE_LOADED: 12, + removeFrameAt: function (index) + { + this.frames.splice(index, 1); + + this.updateFrameSequence(); + + return this; + }, /** - * File failed to load - * - * @name Phaser.Loader.FILE_FAILED - * @type {number} + * Called internally during playback. Forces the animation to repeat, providing there are enough counts left + * in the repeat counter. + * + * @method Phaser.Animations.Animation#repeatAnimation + * @fires Phaser.Animations.Events#ANIMATION_REPEAT + * @fires Phaser.Animations.Events#SPRITE_ANIMATION_REPEAT + * @fires Phaser.Animations.Events#SPRITE_ANIMATION_KEY_REPEAT * @since 3.0.0 + * + * @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call. */ - FILE_FAILED: 13, + repeatAnimation: function (state) + { + if (state._pendingStop === 2) + { + if (state._pendingStopValue === 0) + { + return state.stop(); + } + else + { + state._pendingStopValue--; + } + } + + if (state.repeatDelay > 0 && !state.pendingRepeat) + { + state.pendingRepeat = true; + state.accumulator -= state.nextTick; + state.nextTick += state.repeatDelay; + } + else + { + state.repeatCounter--; + + if (state.forward) + { + state.setCurrentFrame(state.currentFrame.nextFrame); + } + else + { + state.setCurrentFrame(state.currentFrame.prevFrame); + } + + if (state.isPlaying) + { + this.getNextTick(state); + + state.handleRepeat(); + } + } + }, /** - * File is being processed (onProcess callback) - * - * @name Phaser.Loader.FILE_PROCESSING - * @type {number} + * Converts the animation data to JSON. + * + * @method Phaser.Animations.Animation#toJSON * @since 3.0.0 + * + * @return {Phaser.Types.Animations.JSONAnimation} The resulting JSONAnimation formatted object. */ - FILE_PROCESSING: 14, + toJSON: function () + { + var output = { + key: this.key, + type: this.type, + frames: [], + frameRate: this.frameRate, + duration: this.duration, + skipMissedFrames: this.skipMissedFrames, + delay: this.delay, + repeat: this.repeat, + repeatDelay: this.repeatDelay, + yoyo: this.yoyo, + showBeforeDelay: this.showBeforeDelay, + showOnStart: this.showOnStart, + hideOnComplete: this.hideOnComplete + }; + + this.frames.forEach(function (frame) + { + output.frames.push(frame.toJSON()); + }); + + return output; + }, /** - * The File has errored somehow during processing. - * - * @name Phaser.Loader.FILE_ERRORED - * @type {number} + * Called internally whenever frames are added to, or removed from, this Animation. + * + * @method Phaser.Animations.Animation#updateFrameSequence * @since 3.0.0 + * + * @return {this} This Animation object. */ - FILE_ERRORED: 16, + updateFrameSequence: function () + { + var len = this.frames.length; + var slice = 1 / (len - 1); + + var frame; + + for (var i = 0; i < len; i++) + { + frame = this.frames[i]; + + frame.index = i + 1; + frame.isFirst = false; + frame.isLast = false; + frame.progress = i * slice; + + if (i === 0) + { + frame.isFirst = true; + + if (len === 1) + { + frame.isLast = true; + frame.nextFrame = frame; + frame.prevFrame = frame; + } + else + { + frame.isLast = false; + frame.prevFrame = this.frames[len - 1]; + frame.nextFrame = this.frames[i + 1]; + } + } + else if (i === len - 1 && len > 1) + { + frame.isLast = true; + frame.prevFrame = this.frames[len - 2]; + frame.nextFrame = this.frames[0]; + } + else if (len > 1) + { + frame.prevFrame = this.frames[i - 1]; + frame.nextFrame = this.frames[i + 1]; + } + } + + return this; + }, /** - * File has finished processing. - * - * @name Phaser.Loader.FILE_COMPLETE - * @type {number} + * Pauses playback of this Animation. The paused state is set immediately. + * + * @method Phaser.Animations.Animation#pause * @since 3.0.0 + * + * @return {this} This Animation object. */ - FILE_COMPLETE: 17, + pause: function () + { + this.paused = true; + + return this; + }, /** - * File has been destroyed - * - * @name Phaser.Loader.FILE_DESTROYED - * @type {number} + * Resumes playback of this Animation. The paused state is reset immediately. + * + * @method Phaser.Animations.Animation#resume * @since 3.0.0 + * + * @return {this} This Animation object. */ - FILE_DESTROYED: 18, + resume: function () + { + this.paused = false; + + return this; + }, /** - * File was populated from local data and doesn't need an HTTP request - * - * @name Phaser.Loader.FILE_POPULATED - * @type {number} + * Destroys this Animation instance. It will remove all event listeners, + * remove this animation and its key from the global Animation Manager, + * and then destroy all Animation Frames in turn. + * + * @method Phaser.Animations.Animation#destroy * @since 3.0.0 */ - FILE_POPULATED: 19 - -}; - -module.exports = FILE_CONST; - + destroy: function () + { + if (this.manager.off) + { + this.manager.off(Events.PAUSE_ALL, this.pause, this); + this.manager.off(Events.RESUME_ALL, this.resume, this); + } -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { + this.manager.remove(this.key); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + for (var i = 0; i < this.frames.length; i++) + { + this.frames[i].destroy(); + } -/** - * @namespace Phaser.Core.Events - */ + this.frames = []; -module.exports = { + this.manager = null; + } - BLUR: __webpack_require__(612), - BOOT: __webpack_require__(613), - CONTEXT_LOST: __webpack_require__(614), - CONTEXT_RESTORED: __webpack_require__(615), - DESTROY: __webpack_require__(616), - FOCUS: __webpack_require__(617), - HIDDEN: __webpack_require__(618), - PAUSE: __webpack_require__(619), - POST_RENDER: __webpack_require__(620), - POST_STEP: __webpack_require__(621), - PRE_RENDER: __webpack_require__(622), - PRE_STEP: __webpack_require__(623), - READY: __webpack_require__(624), - RESUME: __webpack_require__(625), - STEP: __webpack_require__(626), - VISIBLE: __webpack_require__(627) +}); -}; +module.exports = Animation; /***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71519: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var Events = __webpack_require__(95); -var GetFastValue = __webpack_require__(2); -var GetURL = __webpack_require__(155); -var MergeXHRSettings = __webpack_require__(240); -var XHRLoader = __webpack_require__(517); -var XHRSettings = __webpack_require__(156); +var Class = __webpack_require__(56694); /** * @classdesc - * The base File class used by all File Types that the Loader can support. - * You shouldn't create an instance of a File directly, but should extend it with your own class, setting a custom type and processing methods. + * A single frame in an Animation sequence. * - * @class File - * @memberof Phaser.Loader + * An AnimationFrame consists of a reference to the Texture it uses for rendering, references to other + * frames in the animation, and index data. It also has the ability to modify the animation timing. + * + * AnimationFrames are generated automatically by the Animation class. + * + * @class AnimationFrame + * @memberof Phaser.Animations * @constructor * @since 3.0.0 * - * @param {Phaser.Loader.LoaderPlugin} loader - The Loader that is going to load this File. - * @param {Phaser.Types.Loader.FileConfig} fileConfig - The file configuration object, as created by the file type. - */ -var File = new Class({ + * @param {string} textureKey - The key of the Texture this AnimationFrame uses. + * @param {(string|number)} textureFrame - The key of the Frame within the Texture that this AnimationFrame uses. + * @param {number} index - The index of this AnimationFrame within the Animation sequence. + * @param {Phaser.Textures.Frame} frame - A reference to the Texture Frame this AnimationFrame uses for rendering. + * @param {boolean} [isKeyFrame=false] - Is this Frame a Keyframe within the Animation? + */ +var AnimationFrame = new Class({ initialize: - function File (loader, fileConfig) + function AnimationFrame (textureKey, textureFrame, index, frame, isKeyFrame) { + if (isKeyFrame === undefined) { isKeyFrame = false; } + /** - * A reference to the Loader that is going to load this file. + * The key of the Texture this AnimationFrame uses. * - * @name Phaser.Loader.File#loader - * @type {Phaser.Loader.LoaderPlugin} + * @name Phaser.Animations.AnimationFrame#textureKey + * @type {string} * @since 3.0.0 */ - this.loader = loader; + this.textureKey = textureKey; /** - * A reference to the Cache, or Texture Manager, that is going to store this file if it loads. + * The key of the Frame within the Texture that this AnimationFrame uses. * - * @name Phaser.Loader.File#cache - * @type {(Phaser.Cache.BaseCache|Phaser.Textures.TextureManager)} - * @since 3.7.0 + * @name Phaser.Animations.AnimationFrame#textureFrame + * @type {(string|number)} + * @since 3.0.0 */ - this.cache = GetFastValue(fileConfig, 'cache', false); + this.textureFrame = textureFrame; /** - * The file type string (image, json, etc) for sorting within the Loader. + * The index of this AnimationFrame within the Animation sequence. * - * @name Phaser.Loader.File#type - * @type {string} + * @name Phaser.Animations.AnimationFrame#index + * @type {number} * @since 3.0.0 */ - this.type = GetFastValue(fileConfig, 'type', false); + this.index = index; /** - * Unique cache key (unique within its file type) + * A reference to the Texture Frame this AnimationFrame uses for rendering. * - * @name Phaser.Loader.File#key - * @type {string} + * @name Phaser.Animations.AnimationFrame#frame + * @type {Phaser.Textures.Frame} * @since 3.0.0 */ - this.key = GetFastValue(fileConfig, 'key', false); - - var loadKey = this.key; - - if (loader.prefix && loader.prefix !== '') - { - this.key = loader.prefix + loadKey; - } - - if (!this.type || !this.key) - { - throw new Error('Invalid Loader.' + this.type + ' key'); - } - - var url = GetFastValue(fileConfig, 'url'); - - if (url === undefined) - { - url = loader.path + loadKey + '.' + GetFastValue(fileConfig, 'extension', ''); - } - else if (typeof url === 'string' && !url.match(/^(?:blob:|data:|http:\/\/|https:\/\/|\/\/)/)) - { - url = loader.path + url; - } + this.frame = frame; /** - * The URL of the file, not including baseURL. - * - * Automatically has Loader.path prepended to it if a string. - * - * Can also be a JavaScript Object, such as the results of parsing JSON data. + * Is this the first frame in an animation sequence? * - * @name Phaser.Loader.File#url - * @type {object|string} + * @name Phaser.Animations.AnimationFrame#isFirst + * @type {boolean} + * @default false + * @readonly * @since 3.0.0 */ - this.url = url; + this.isFirst = false; /** - * The final URL this file will load from, including baseURL and path. - * Set automatically when the Loader calls 'load' on this file. + * Is this the last frame in an animation sequence? * - * @name Phaser.Loader.File#src - * @type {string} + * @name Phaser.Animations.AnimationFrame#isLast + * @type {boolean} + * @default false + * @readonly * @since 3.0.0 */ - this.src = ''; + this.isLast = false; /** - * The merged XHRSettings for this file. + * A reference to the AnimationFrame that comes before this one in the animation, if any. * - * @name Phaser.Loader.File#xhrSettings - * @type {Phaser.Types.Loader.XHRSettingsObject} + * @name Phaser.Animations.AnimationFrame#prevFrame + * @type {?Phaser.Animations.AnimationFrame} + * @default null + * @readonly * @since 3.0.0 */ - this.xhrSettings = XHRSettings(GetFastValue(fileConfig, 'responseType', undefined)); - - if (GetFastValue(fileConfig, 'xhrSettings', false)) - { - this.xhrSettings = MergeXHRSettings(this.xhrSettings, GetFastValue(fileConfig, 'xhrSettings', {})); - } + this.prevFrame = null; /** - * The XMLHttpRequest instance (as created by XHR Loader) that is loading this File. + * A reference to the AnimationFrame that comes after this one in the animation, if any. * - * @name Phaser.Loader.File#xhrLoader - * @type {?XMLHttpRequest} + * @name Phaser.Animations.AnimationFrame#nextFrame + * @type {?Phaser.Animations.AnimationFrame} + * @default null + * @readonly * @since 3.0.0 */ - this.xhrLoader = null; + this.nextFrame = null; /** - * The current state of the file. One of the FILE_CONST values. + * Additional time (in ms) that this frame should appear for during playback. + * The value is added onto the msPerFrame set by the animation. * - * @name Phaser.Loader.File#state + * @name Phaser.Animations.AnimationFrame#duration * @type {number} + * @default 0 * @since 3.0.0 */ - this.state = (typeof(this.url) === 'function') ? CONST.FILE_POPULATED : CONST.FILE_PENDING; + this.duration = 0; /** - * The total size of this file. - * Set by onProgress and only if loading via XHR. + * What % through the animation does this frame come? + * This value is generated when the animation is created and cached here. * - * @name Phaser.Loader.File#bytesTotal + * @name Phaser.Animations.AnimationFrame#progress * @type {number} * @default 0 + * @readonly * @since 3.0.0 */ - this.bytesTotal = 0; + this.progress = 0; /** - * Updated as the file loads. - * Only set if loading via XHR. + * Is this Frame a KeyFrame within the Animation? * - * @name Phaser.Loader.File#bytesLoaded - * @type {number} - * @default -1 - * @since 3.0.0 + * @name Phaser.Animations.AnimationFrame#isKeyFrame + * @type {boolean} + * @since 3.50.0 */ - this.bytesLoaded = -1; + this.isKeyFrame = isKeyFrame; + }, + + /** + * Generates a JavaScript object suitable for converting to JSON. + * + * @method Phaser.Animations.AnimationFrame#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Animations.JSONAnimationFrame} The AnimationFrame data. + */ + toJSON: function () + { + return { + key: this.textureKey, + frame: this.textureFrame, + duration: this.duration, + keyframe: this.isKeyFrame + }; + }, + + /** + * Destroys this object by removing references to external resources and callbacks. + * + * @method Phaser.Animations.AnimationFrame#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.frame = undefined; + } + +}); + +module.exports = AnimationFrame; + + +/***/ }), + +/***/ 90249: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Animation = __webpack_require__(85463); +var Class = __webpack_require__(56694); +var CustomMap = __webpack_require__(33885); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(16938); +var GameEvents = __webpack_require__(97081); +var GetFastValue = __webpack_require__(72632); +var GetValue = __webpack_require__(10850); +var MATH_CONST = __webpack_require__(83392); +var NumberArray = __webpack_require__(13401); +var Pad = __webpack_require__(76400); + +/** + * @classdesc + * The Animation Manager. + * + * Animations are managed by the global Animation Manager. This is a singleton class that is + * responsible for creating and delivering animations and their corresponding data to all Game Objects. + * Unlike plugins it is owned by the Game instance, not the Scene. + * + * Sprites and other Game Objects get the data they need from the AnimationManager. + * + * @class AnimationManager + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Animations + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - A reference to the Phaser.Game instance. + */ +var AnimationManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function AnimationManager (game) + { + EventEmitter.call(this); /** - * A percentage value between 0 and 1 indicating how much of this file has loaded. - * Only set if loading via XHR. + * A reference to the Phaser.Game instance. * - * @name Phaser.Loader.File#percentComplete - * @type {number} - * @default -1 + * @name Phaser.Animations.AnimationManager#game + * @type {Phaser.Game} + * @protected * @since 3.0.0 */ - this.percentComplete = -1; + this.game = game; /** - * For CORs based loading. - * If this is undefined then the File will check BaseLoader.crossOrigin and use that (if set) + * A reference to the Texture Manager. * - * @name Phaser.Loader.File#crossOrigin - * @type {(string|undefined)} + * @name Phaser.Animations.AnimationManager#textureManager + * @type {Phaser.Textures.TextureManager} + * @protected * @since 3.0.0 */ - this.crossOrigin = undefined; + this.textureManager = null; /** - * The processed file data, stored here after the file has loaded. + * The global time scale of the Animation Manager. * - * @name Phaser.Loader.File#data - * @type {*} + * This scales the time delta between two frames, thus influencing the speed of time for the Animation Manager. + * + * @name Phaser.Animations.AnimationManager#globalTimeScale + * @type {number} + * @default 1 * @since 3.0.0 */ - this.data = undefined; + this.globalTimeScale = 1; /** - * A config object that can be used by file types to store transitional data. + * The Animations registered in the Animation Manager. * - * @name Phaser.Loader.File#config - * @type {*} + * This map should be modified with the {@link #add} and {@link #create} methods of the Animation Manager. + * + * @name Phaser.Animations.AnimationManager#anims + * @type {Phaser.Structs.Map.} + * @protected * @since 3.0.0 */ - this.config = GetFastValue(fileConfig, 'config', {}); + this.anims = new CustomMap(); /** - * If this is a multipart file, i.e. an atlas and its json together, then this is a reference - * to the parent MultiFile. Set and used internally by the Loader or specific file types. + * A list of animation mix times. * - * @name Phaser.Loader.File#multiFile - * @type {?Phaser.Loader.MultiFile} - * @since 3.7.0 + * See the {@link #setMix} method for more details. + * + * @name Phaser.Animations.AnimationManager#mixes + * @type {Phaser.Structs.Map.} + * @since 3.50.0 */ - this.multiFile; + this.mixes = new CustomMap(); /** - * Does this file have an associated linked file? Such as an image and a normal map. - * Atlases and Bitmap Fonts use the multiFile, because those files need loading together but aren't - * actually bound by data, where-as a linkFile is. + * Whether the Animation Manager is paused along with all of its Animations. * - * @name Phaser.Loader.File#linkFile - * @type {?Phaser.Loader.File} - * @since 3.7.0 + * @name Phaser.Animations.AnimationManager#paused + * @type {boolean} + * @default false + * @since 3.0.0 */ - this.linkFile; + this.paused = false; + + /** + * The name of this Animation Manager. + * + * @name Phaser.Animations.AnimationManager#name + * @type {string} + * @since 3.0.0 + */ + this.name = 'AnimationManager'; + + game.events.once(GameEvents.BOOT, this.boot, this); }, /** - * Links this File with another, so they depend upon each other for loading and processing. - * - * @method Phaser.Loader.File#setLink - * @since 3.7.0 + * Registers event listeners after the Game boots. * - * @param {Phaser.Loader.File} fileB - The file to link to this one. + * @method Phaser.Animations.AnimationManager#boot + * @listens Phaser.Core.Events#DESTROY + * @since 3.0.0 */ - setLink: function (fileB) + boot: function () { - this.linkFile = fileB; + this.textureManager = this.game.textures; - fileB.linkFile = this; + this.game.events.once(GameEvents.DESTROY, this.destroy, this); }, /** - * Resets the XHRLoader instance this file is using. + * Adds a mix between two animations. * - * @method Phaser.Loader.File#resetXHR - * @since 3.0.0 + * Mixing allows you to specify a unique delay between a pairing of animations. + * + * When playing Animation A on a Game Object, if you then play Animation B, and a + * mix exists, it will wait for the specified delay to be over before playing Animation B. + * + * This allows you to customise smoothing between different types of animation, such + * as blending between an idle and a walk state, or a running and a firing state. + * + * Note that mixing is only applied if you use the `Sprite.play` method. If you opt to use + * `playAfterRepeat` or `playAfterDelay` instead, those will take priority and the mix + * delay will not be used. + * + * To update an existing mix, just call this method with the new delay. + * + * To remove a mix pairing, see the `removeMix` method. + * + * @method Phaser.Animations.AnimationManager#addMix + * @since 3.50.0 + * + * @param {(string|Phaser.Animations.Animation)} animA - The string-based key, or instance of, Animation A. + * @param {(string|Phaser.Animations.Animation)} animB - The string-based key, or instance of, Animation B. + * @param {number} delay - The delay, in milliseconds, to wait when transitioning from Animation A to B. + * + * @return {this} This Animation Manager. */ - resetXHR: function () + addMix: function (animA, animB, delay) { - if (this.xhrLoader) + var anims = this.anims; + var mixes = this.mixes; + + var keyA = (typeof(animA) === 'string') ? animA : animA.key; + var keyB = (typeof(animB) === 'string') ? animB : animB.key; + + if (anims.has(keyA) && anims.has(keyB)) { - this.xhrLoader.onload = undefined; - this.xhrLoader.onerror = undefined; - this.xhrLoader.onprogress = undefined; + var mixObj = mixes.get(keyA); + + if (!mixObj) + { + mixObj = {}; + } + + mixObj[keyB] = delay; + + mixes.set(keyA, mixObj); } + + return this; }, /** - * 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. + * Removes a mix between two animations. * - * @method Phaser.Loader.File#load - * @since 3.0.0 + * Mixing allows you to specify a unique delay between a pairing of animations. + * + * Calling this method lets you remove those pairings. You can either remove + * it between `animA` and `animB`, or if you do not provide the `animB` parameter, + * it will remove all `animA` mixes. + * + * If you wish to update an existing mix instead, call the `addMix` method with the + * new delay. + * + * @method Phaser.Animations.AnimationManager#removeMix + * @since 3.50.0 + * + * @param {(string|Phaser.Animations.Animation)} animA - The string-based key, or instance of, Animation A. + * @param {(string|Phaser.Animations.Animation)} [animB] - The string-based key, or instance of, Animation B. If not given, all mixes for Animation A will be removed. + * + * @return {this} This Animation Manager. */ - load: function () + removeMix: function (animA, animB) { - if (this.state === CONST.FILE_POPULATED) - { - // Can happen for example in a JSONFile if they've provided a JSON object instead of a URL - this.loader.nextFile(this, true); - } - else - { - this.state = CONST.FILE_LOADING; + var mixes = this.mixes; - this.src = GetURL(this, this.loader.baseURL); + var keyA = (typeof(animA) === 'string') ? animA : animA.key; - if (this.src.indexOf('data:') === 0) + var mixObj = mixes.get(keyA); + + if (mixObj) + { + if (animB) { - console.warn('Local data URIs are not supported: ' + this.key); + var keyB = (typeof(animB) === 'string') ? animB : animB.key; + + if (mixObj.hasOwnProperty(keyB)) + { + // Remove just this pairing + delete mixObj[keyB]; + } } - else + else if (!animB) { - // The creation of this XHRLoader starts the load process going. - // It will automatically call the following, based on the load outcome: - // - // xhr.onload = this.onLoad - // xhr.onerror = this.onError - // xhr.onprogress = this.onProgress - - this.xhrLoader = XHRLoader(this, this.loader.xhr); + // Remove everything for animA + mixes.delete(keyA); } } + + return this; }, /** - * Called when the file finishes loading, is sent a DOM ProgressEvent. + * Returns the mix delay between two animations. * - * @method Phaser.Loader.File#onLoad - * @since 3.0.0 + * If no mix has been set-up, this method will return zero. * - * @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event. - * @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this load. + * If you wish to create, or update, a new mix, call the `addMix` method. + * If you wish to remove a mix, call the `removeMix` method. + * + * @method Phaser.Animations.AnimationManager#getMix + * @since 3.50.0 + * + * @param {(string|Phaser.Animations.Animation)} animA - The string-based key, or instance of, Animation A. + * @param {(string|Phaser.Animations.Animation)} animB - The string-based key, or instance of, Animation B. + * + * @return {number} The mix duration, or zero if no mix exists. */ - onLoad: function (xhr, event) + getMix: function (animA, animB) { - // On iOS, Capacitor often runs on a capacitor:// protocol, meaning local files are served from capacitor:// rather than file:// - // See: https://github.com/photonstorm/phaser/issues/5685 + var mixes = this.mixes; - var isLocalFile = xhr.responseURL && (xhr.responseURL.indexOf('file://') === 0 || xhr.responseURL.indexOf('capacitor://') === 0); + var keyA = (typeof(animA) === 'string') ? animA : animA.key; + var keyB = (typeof(animB) === 'string') ? animB : animB.key; - var localFileOk = (isLocalFile && event.target.status === 0); + var mixObj = mixes.get(keyA); - var success = !(event.target && event.target.status !== 200) || localFileOk; + if (mixObj && mixObj.hasOwnProperty(keyB)) + { + return mixObj[keyB]; + } + else + { + return 0; + } + }, - // Handle HTTP status codes of 4xx and 5xx as errors, even if xhr.onerror was not called. - if (xhr.readyState === 4 && xhr.status >= 400 && xhr.status <= 599) + /** + * Adds an existing Animation to the Animation Manager. + * + * @method Phaser.Animations.AnimationManager#add + * @fires Phaser.Animations.Events#ADD_ANIMATION + * @since 3.0.0 + * + * @param {string} key - The key under which the Animation should be added. The Animation will be updated with it. Must be unique. + * @param {Phaser.Animations.Animation} animation - The Animation which should be added to the Animation Manager. + * + * @return {this} This Animation Manager. + */ + add: function (key, animation) + { + if (this.anims.has(key)) { - success = false; + console.warn('Animation key exists: ' + key); + + return this; } - this.state = CONST.FILE_LOADED; + animation.key = key; - this.resetXHR(); + this.anims.set(key, animation); - this.loader.nextFile(this, success); + this.emit(Events.ADD_ANIMATION, key, animation); + + return this; }, /** - * Called if the file errors while loading, is sent a DOM ProgressEvent. + * Checks to see if the given key is already in use within the Animation Manager or not. * - * @method Phaser.Loader.File#onError - * @since 3.0.0 + * Animations are global. Keys created in one scene can be used from any other Scene in your game. They are not Scene specific. * - * @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event. - * @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this error. + * @method Phaser.Animations.AnimationManager#exists + * @since 3.16.0 + * + * @param {string} key - The key of the Animation to check. + * + * @return {boolean} `true` if the Animation already exists in the Animation Manager, or `false` if the key is available. */ - onError: function () + exists: function (key) { - this.resetXHR(); + return this.anims.has(key); + }, - this.loader.nextFile(this, false); + /** + * Create one, or more animations from a loaded Aseprite JSON file. + * + * Aseprite is a powerful animated sprite editor and pixel art tool. + * + * You can find more details at https://www.aseprite.org/ + * + * To export a compatible JSON file in Aseprite, please do the following: + * + * 1. Go to "File - Export Sprite Sheet" + * + * 2. On the **Layout** tab: + * 2a. Set the "Sheet type" to "Packed" + * 2b. Set the "Constraints" to "None" + * 2c. Check the "Merge Duplicates" checkbox + * + * 3. On the **Sprite** tab: + * 3a. Set "Layers" to "Visible layers" + * 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags + * + * 4. On the **Borders** tab: + * 4a. Check the "Trim Sprite" and "Trim Cells" options + * 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough) + * + * 5. On the **Output** tab: + * 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type + * 5b. Check "JSON Data" and give your json file a name + * 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind. + * 5d. Make sure "Tags" is checked in the Meta options + * 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more. + * + * 6. Click export + * + * This was tested with Aseprite 1.2.25. + * + * This will export a png and json file which you can load using the Aseprite Loader, i.e.: + * + * ```javascript + * function preload () + * { + * this.load.path = 'assets/animations/aseprite/'; + * this.load.aseprite('paladin', 'paladin.png', 'paladin.json'); + * } + * ``` + * + * Once loaded, you can call this method from within a Scene with the 'atlas' key: + * + * ```javascript + * this.anims.createFromAseprite('paladin'); + * ``` + * + * Any animations defined in the JSON will now be available to use in Phaser and you play them + * via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline, + * you can play it in Phaser using that Tag name: + * + * ```javascript + * this.add.sprite(400, 300).play('War Cry'); + * ``` + * + * When calling this method you can optionally provide an array of tag names, and only those animations + * will be created. For example: + * + * ```javascript + * this.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]); + * ``` + * + * This will only create the 3 animations defined. Note that the tag names are case-sensitive. + * + * @method Phaser.Animations.AnimationManager#createFromAseprite + * @since 3.50.0 + * + * @param {string} key - The key of the loaded Aseprite atlas. It must have been loaded prior to calling this method. + * @param {string[]} [tags] - An array of Tag names. If provided, only animations found in this array will be created. + * @param {(Phaser.Animations.AnimationManager|Phaser.GameObjects.GameObject)} [target] - Create the animations on this target Sprite. If not given, they will be created globally in this Animation Manager. + * + * @return {Phaser.Animations.Animation[]} An array of Animation instances that were successfully created. + */ + createFromAseprite: function (key, tags, target) + { + var output = []; + + var data = this.game.cache.json.get(key); + + if (!data) + { + console.warn('No Aseprite data found for: ' + key); + + return output; + } + + var _this = this; + + var meta = GetValue(data, 'meta', null); + var frames = GetValue(data, 'frames', null); + + if (meta && frames) + { + var frameTags = GetValue(meta, 'frameTags', []); + + frameTags.forEach(function (tag) + { + var animFrames = []; + + var name = GetFastValue(tag, 'name', null); + var from = GetFastValue(tag, 'from', 0); + var to = GetFastValue(tag, 'to', 0); + var direction = GetFastValue(tag, 'direction', 'forward'); + + if (!name) + { + // Skip if no name + return; + } + + if (!tags || (tags && tags.indexOf(name) > -1)) + { + // Get all the frames for this tag and calculate the total duration in milliseconds. + var totalDuration = 0; + for (var i = from; i <= to; i++) + { + var frameKey = i.toString(); + var frame = frames[frameKey]; + + if (frame) + { + var frameDuration = GetFastValue(frame, 'duration', MATH_CONST.MAX_SAFE_INTEGER); + animFrames.push({ key: key, frame: frameKey, duration: frameDuration }); + totalDuration += frameDuration; + } + } + + // Fix duration to play nice with how the next tick is calculated. + var msPerFrame = totalDuration / animFrames.length; + + animFrames.forEach(function (entry) + { + entry.duration -= msPerFrame; + }); + + if (direction === 'reverse') + { + animFrames = animFrames.reverse(); + } + + // Create the animation + var createConfig = { + key: name, + frames: animFrames, + duration: totalDuration, + yoyo: (direction === 'pingpong') + }; + + var result; + + if (target) + { + if (target.anims) + { + result = target.anims.create(createConfig); + } + } + else + { + result = _this.create(createConfig); + } + + if (result) + { + output.push(result); + } + } + }); + } + + return output; }, /** - * Called during the file load progress. Is sent a DOM ProgressEvent. + * Creates a new Animation and adds it to the Animation Manager. * - * @method Phaser.Loader.File#onProgress - * @fires Phaser.Loader.Events#FILE_PROGRESS + * Animations are global. Once created, you can use them in any Scene in your game. They are not Scene specific. + * + * If an invalid key is given this method will return `false`. + * + * If you pass the key of an animation that already exists in the Animation Manager, that animation will be returned. + * + * A brand new animation is only created if the key is valid and not already in use. + * + * If you wish to re-use an existing key, call `AnimationManager.remove` first, then this method. + * + * @method Phaser.Animations.AnimationManager#create + * @fires Phaser.Animations.Events#ADD_ANIMATION * @since 3.0.0 * - * @param {ProgressEvent} event - The DOM ProgressEvent. + * @param {Phaser.Types.Animations.Animation} config - The configuration settings for the Animation. + * + * @return {(Phaser.Animations.Animation|false)} The Animation that was created, or `false` if the key is already in use. */ - onProgress: function (event) + create: function (config) { - if (event.lengthComputable) + var key = config.key; + + var anim = false; + + if (key) { - this.bytesLoaded = event.loaded; - this.bytesTotal = event.total; + anim = this.get(key); - this.percentComplete = Math.min((this.bytesLoaded / this.bytesTotal), 1); + if (!anim) + { + anim = new Animation(this, key, config); - this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete); + this.anims.set(key, anim); + + this.emit(Events.ADD_ANIMATION, key, anim); + } + else + { + console.warn('AnimationManager key already exists: ' + key); + } } + + return anim; }, /** - * Usually overridden by the FileTypes and is called by Loader.nextFile. - * This method controls what extra work this File does with its loaded data, for example a JSON file will parse itself during this stage. + * Loads this Animation Manager's Animations and settings from a JSON object. * - * @method Phaser.Loader.File#onProcess + * @method Phaser.Animations.AnimationManager#fromJSON * @since 3.0.0 + * + * @param {(string|Phaser.Types.Animations.JSONAnimations|Phaser.Types.Animations.JSONAnimation)} data - The JSON object to parse. + * @param {boolean} [clearCurrentAnimations=false] - If set to `true`, the current animations will be removed (`anims.clear()`). If set to `false` (default), the animations in `data` will be added. + * + * @return {Phaser.Animations.Animation[]} An array containing all of the Animation objects that were created as a result of this call. */ - onProcess: function () + fromJSON: function (data, clearCurrentAnimations) { - this.state = CONST.FILE_PROCESSING; + if (clearCurrentAnimations === undefined) { clearCurrentAnimations = false; } - this.onProcessComplete(); + if (clearCurrentAnimations) + { + this.anims.clear(); + } + + // Do we have a String (i.e. from JSON, or an Object?) + if (typeof data === 'string') + { + data = JSON.parse(data); + } + + var output = []; + + // Array of animations, or a single animation? + if (data.hasOwnProperty('anims') && Array.isArray(data.anims)) + { + for (var i = 0; i < data.anims.length; i++) + { + output.push(this.create(data.anims[i])); + } + + if (data.hasOwnProperty('globalTimeScale')) + { + this.globalTimeScale = data.globalTimeScale; + } + } + else if (data.hasOwnProperty('key') && data.type === 'frame') + { + output.push(this.create(data)); + } + + return output; }, /** - * Called when the File has completed processing. - * Checks on the state of its multifile, if set. + * Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object. * - * @method Phaser.Loader.File#onProcessComplete - * @since 3.7.0 + * Generates objects with string based frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNames}. + * + * It's a helper method, designed to make it easier for you to extract all of the frame names from texture atlases. + * + * If you're working with a sprite sheet, see the `generateFrameNumbers` method instead. + * + * Example: + * + * If you have a texture atlases loaded called `gems` and it contains 6 frames called `ruby_0001`, `ruby_0002`, and so on, + * then you can call this method using: `this.anims.generateFrameNames('gems', { prefix: 'ruby_', start: 1, end: 6, zeroPad: 4 })`. + * + * The `end` value tells it to select frames 1 through 6, incrementally numbered, all starting with the prefix `ruby_`. The `zeroPad` + * value tells it how many zeroes pad out the numbers. To create an animation using this method, you can do: + * + * ```javascript + * this.anims.create({ + * key: 'ruby', + * repeat: -1, + * frames: this.anims.generateFrameNames('gems', { + * prefix: 'ruby_', + * end: 6, + * zeroPad: 4 + * }) + * }); + * ``` + * + * Please see the animation examples for further details. + * + * @method Phaser.Animations.AnimationManager#generateFrameNames + * @since 3.0.0 + * + * @param {string} key - The key for the texture containing the animation frames. + * @param {Phaser.Types.Animations.GenerateFrameNames} [config] - The configuration object for the animation frame names. + * + * @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects. */ - onProcessComplete: function () + generateFrameNames: function (key, config) { - this.state = CONST.FILE_COMPLETE; + var prefix = GetValue(config, 'prefix', ''); + var start = GetValue(config, 'start', 0); + var end = GetValue(config, 'end', 0); + var suffix = GetValue(config, 'suffix', ''); + var zeroPad = GetValue(config, 'zeroPad', 0); + var out = GetValue(config, 'outputArray', []); + var frames = GetValue(config, 'frames', false); - if (this.multiFile) + if (!this.textureManager.exists(key)) { - this.multiFile.onFileComplete(this); + console.warn('Texture "%s" not found', key); + + return out; } - this.loader.fileProcessComplete(this); + var texture = this.textureManager.get(key); + + if (!texture) + { + return out; + } + + var i; + + if (!config) + { + // Use every frame in the atlas + frames = texture.getFrameNames(); + + for (i = 0; i < frames.length; i++) + { + out.push({ key: key, frame: frames[i] }); + } + } + else + { + if (!frames) + { + frames = NumberArray(start, end); + } + + for (i = 0; i < frames.length; i++) + { + var frame = prefix + Pad(frames[i], zeroPad, '0', 1) + suffix; + + if (texture.has(frame)) + { + out.push({ key: key, frame: frame }); + } + else + { + console.warn('Frame "%s" not found in texture "%s"', frame, key); + } + } + } + + return out; }, /** - * Called when the File has completed processing but it generated an error. - * Checks on the state of its multifile, if set. + * Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object. * - * @method Phaser.Loader.File#onProcessError - * @since 3.7.0 + * Generates objects with numbered frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNumbers}. + * + * If you're working with a texture atlas, see the `generateFrameNames` method instead. + * + * It's a helper method, designed to make it easier for you to extract frames from sprite sheets. + * + * Example: + * + * If you have a sprite sheet loaded called `explosion` and it contains 12 frames, then you can call this method using: + * + * `this.anims.generateFrameNumbers('explosion', { start: 0, end: 11 })`. + * + * The `end` value of 11 tells it to stop after the 12th frame has been added, because it started at zero. + * + * To create an animation using this method, you can do: + * + * ```javascript + * this.anims.create({ + * key: 'boom', + * frames: this.anims.generateFrameNumbers('explosion', { + * start: 0, + * end: 11 + * }) + * }); + * ``` + * + * Note that `start` is optional and you don't need to include it if the animation starts from frame 0. + * + * To specify an animation in reverse, swap the `start` and `end` values. + * + * If the frames are not sequential, you may pass an array of frame numbers instead, for example: + * + * `this.anims.generateFrameNumbers('explosion', { frames: [ 0, 1, 2, 1, 2, 3, 4, 0, 1, 2 ] })` + * + * Please see the animation examples and `GenerateFrameNumbers` config docs for further details. + * + * @method Phaser.Animations.AnimationManager#generateFrameNumbers + * @since 3.0.0 + * + * @param {string} key - The key for the texture containing the animation frames. + * @param {Phaser.Types.Animations.GenerateFrameNumbers} [config] - The configuration object for the animation frames. + * + * @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects. */ - onProcessError: function () + generateFrameNumbers: function (key, config) { - this.state = CONST.FILE_ERRORED; + var start = GetValue(config, 'start', 0); + var end = GetValue(config, 'end', -1); + var first = GetValue(config, 'first', false); + var out = GetValue(config, 'outputArray', []); + var frames = GetValue(config, 'frames', false); - if (this.multiFile) + if (!this.textureManager.exists(key)) { - this.multiFile.onFileFailed(this); + console.warn('Texture "%s" not found', key); + + return out; } - this.loader.fileProcessComplete(this); + var texture = this.textureManager.get(key); + + if (!texture) + { + return out; + } + + if (first && texture.has(first)) + { + out.push({ key: key, frame: first }); + } + + // No 'frames' array? Then generate one automatically + if (!frames) + { + if (end === -1) + { + // -1 because of __BASE, which we don't want in our results + // and -1 because frames are zero based + end = texture.frameTotal - 2; + } + + frames = NumberArray(start, end); + } + + for (var i = 0; i < frames.length; i++) + { + var frameName = frames[i]; + + if (texture.has(frameName)) + { + out.push({ key: key, frame: frameName }); + } + else + { + console.warn('Frame "%s" not found in texture "%s"', frameName, key); + } + } + + return out; }, /** - * Checks if a key matching the one used by this file exists in the target Cache or not. - * This is called automatically by the LoaderPlugin to decide if the file can be safely - * loaded or will conflict. + * Get an Animation. * - * @method Phaser.Loader.File#hasCacheConflict - * @since 3.7.0 + * @method Phaser.Animations.AnimationManager#get + * @since 3.0.0 * - * @return {boolean} `true` if adding this file will cause a conflict, otherwise `false`. + * @param {string} key - The key of the Animation to retrieve. + * + * @return {Phaser.Animations.Animation} The Animation. */ - hasCacheConflict: function () + get: function (key) { - return (this.cache && this.cache.exists(this.key)); + return this.anims.get(key); }, /** - * Adds this file to its target cache upon successful loading and processing. - * This method is often overridden by specific file types. + * Returns an array of all Animation keys that are using the given + * Texture. Only Animations that have at least one AnimationFrame + * entry using this texture will be included in the result. * - * @method Phaser.Loader.File#addToCache - * @since 3.7.0 + * @method Phaser.Animations.AnimationManager#getAnimsFromTexture + * @since 3.60.0 + * + * @param {(string|Phaser.Textures.Texture|Phaser.Textures.Frame)} key - The unique string-based key of the Texture, or a Texture, or Frame instance. + * + * @return {string[]} An array of Animation keys that feature the given Texture. */ - addToCache: function () + getAnimsFromTexture: function (key) { - if (this.cache) + var texture = this.textureManager.get(key); + + var match = texture.key; + var anims = this.anims.getArray(); + + var out = []; + + for (var i = 0; i < anims.length; i++) { - this.cache.add(this.key, this.data); + var anim = anims[i]; + var frames = anim.frames; + + for (var c = 0; c < frames.length; c++) + { + if (frames[c].textureKey === match) + { + out.push(anim.key); + + break; + } + } } - this.pendingDestroy(); + return out; }, /** - * Called once the file has been added to its cache and is now ready for deletion from the Loader. - * It will emit a `filecomplete` event from the LoaderPlugin. + * Pause all animations. * - * @method Phaser.Loader.File#pendingDestroy - * @fires Phaser.Loader.Events#FILE_COMPLETE - * @fires Phaser.Loader.Events#FILE_KEY_COMPLETE - * @since 3.7.0 + * @method Phaser.Animations.AnimationManager#pauseAll + * @fires Phaser.Animations.Events#PAUSE_ALL + * @since 3.0.0 + * + * @return {this} This Animation Manager. */ - pendingDestroy: function (data) + pauseAll: function () { - if (data === undefined) { data = this.data; } - - var key = this.key; - var type = this.type; + if (!this.paused) + { + this.paused = true; - this.loader.emit(Events.FILE_COMPLETE, key, type, data); - this.loader.emit(Events.FILE_KEY_COMPLETE + type + '-' + key, key, type, data); + this.emit(Events.PAUSE_ALL); + } - this.loader.flagForRemoval(this); + return this; }, /** - * Destroy this File and any references it holds. + * Play an animation on the given Game Objects that have an Animation Component. * - * @method Phaser.Loader.File#destroy - * @since 3.7.0 - */ - destroy: function () - { - this.loader = null; - this.cache = null; - this.xhrSettings = null; - this.multiFile = null; - this.linkFile = null; - this.data = null; - } - -}); - -/** - * Static method for creating object URL using URL API and setting it as image 'src' attribute. - * If URL API is not supported (usually on old browsers) it falls back to creating Base64 encoded url using FileReader. - * - * @method Phaser.Loader.File.createObjectURL - * @static - * @since 3.7.0 - * - * @param {HTMLImageElement} image - Image object which 'src' attribute should be set to object URL. - * @param {Blob} blob - A Blob object to create an object URL for. - * @param {string} defaultType - Default mime type used if blob type is not available. - */ -File.createObjectURL = function (image, blob, defaultType) -{ - if (typeof URL === 'function') - { - image.src = URL.createObjectURL(blob); - } - else + * @method Phaser.Animations.AnimationManager#play + * @since 3.0.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} children - An array of Game Objects to play the animation on. They must have an Animation Component. + * + * @return {this} This Animation Manager. + */ + play: function (key, children) { - var reader = new FileReader(); - - reader.onload = function () + if (!Array.isArray(children)) { - image.removeAttribute('crossOrigin'); - image.src = 'data:' + (blob.type || defaultType) + ';base64,' + reader.result.split(',')[1]; - }; + children = [ children ]; + } - reader.onerror = image.onerror; + for (var i = 0; i < children.length; i++) + { + children[i].anims.play(key); + } - reader.readAsDataURL(blob); - } -}; + return this; + }, -/** - * Static method for releasing an existing object URL which was previously created - * by calling {@link File#createObjectURL} method. - * - * @method Phaser.Loader.File.revokeObjectURL - * @static - * @since 3.7.0 - * - * @param {HTMLImageElement} image - Image object which 'src' attribute should be revoked. - */ -File.revokeObjectURL = function (image) -{ - if (typeof URL === 'function') + /** + * Takes an array of Game Objects that have an Animation Component and then + * starts the given animation playing on them. The start time of each Game Object + * is offset, incrementally, by the `stagger` amount. + * + * For example, if you pass an array with 4 children and a stagger time of 1000, + * the delays will be: + * + * child 1: 1000ms delay + * child 2: 2000ms delay + * child 3: 3000ms delay + * child 4: 4000ms delay + * + * If you set the `staggerFirst` parameter to `false` they would be: + * + * child 1: 0ms delay + * child 2: 1000ms delay + * child 3: 2000ms delay + * child 4: 3000ms delay + * + * You can also set `stagger` to be a negative value. If it was -1000, the above would be: + * + * child 1: 3000ms delay + * child 2: 2000ms delay + * child 3: 1000ms delay + * child 4: 0ms delay + * + * @method Phaser.Animations.AnimationManager#staggerPlay + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} children - An array of Game Objects to play the animation on. They must have an Animation Component. + * @param {number} stagger - The amount of time, in milliseconds, to offset each play time by. If a negative value is given, it's applied to the children in reverse order. + * @param {boolean} [staggerFirst=true] -Should the first child be staggered as well? + * + * @return {this} This Animation Manager. + */ + staggerPlay: function (key, children, stagger, staggerFirst) { - URL.revokeObjectURL(image.src); - } -}; - -module.exports = File; - - -/***/ }), -/* 24 */ -/***/ (function(module, exports) { + if (stagger === undefined) { stagger = 0; } + if (staggerFirst === undefined) { staggerFirst = true; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!Array.isArray(children)) + { + children = [ children ]; + } -// Contains the plugins that Phaser uses globally and locally. -// These are the source objects, not instantiated. -var corePlugins = {}; + var len = children.length; -// Contains the plugins that the dev has loaded into their game -// These are the source objects, not instantiated. -var customPlugins = {}; + if (!staggerFirst) + { + len--; + } -var PluginCache = {}; + for (var i = 0; i < children.length; i++) + { + var time = (stagger < 0) ? Math.abs(stagger) * (len - i) : stagger * i; -/** - * @namespace Phaser.Plugins.PluginCache - */ + children[i].anims.playAfterDelay(key, time); + } -/** - * Static method called directly by the Core internal Plugins. - * Key is a reference used to get the plugin from the plugins object (i.e. InputPlugin) - * Plugin is the object to instantiate to create the plugin - * Mapping is what the plugin is injected into the Scene.Systems as (i.e. input) - * - * @method Phaser.Plugins.PluginCache.register - * @since 3.8.0 - * - * @param {string} key - A reference used to get this plugin from the plugin cache. - * @param {function} plugin - The plugin to be stored. Should be the core object, not instantiated. - * @param {string} mapping - If this plugin is to be injected into the Scene Systems, this is the property key map used. - * @param {boolean} [custom=false] - Core Scene plugin or a Custom Scene plugin? - */ -PluginCache.register = function (key, plugin, mapping, custom) -{ - if (custom === undefined) { custom = false; } + return this; + }, - corePlugins[key] = { plugin: plugin, mapping: mapping, custom: custom }; -}; + /** + * Removes an Animation from this Animation Manager, based on the given key. + * + * This is a global action. Once an Animation has been removed, no Game Objects + * can carry on using it. + * + * @method Phaser.Animations.AnimationManager#remove + * @fires Phaser.Animations.Events#REMOVE_ANIMATION + * @since 3.0.0 + * + * @param {string} key - The key of the animation to remove. + * + * @return {Phaser.Animations.Animation} The Animation instance that was removed from the Animation Manager. + */ + remove: function (key) + { + var anim = this.get(key); -/** - * Stores a custom plugin in the global plugin cache. - * The key must be unique, within the scope of the cache. - * - * @method Phaser.Plugins.PluginCache.registerCustom - * @since 3.8.0 - * - * @param {string} key - A reference used to get this plugin from the plugin cache. - * @param {function} plugin - The plugin to be stored. Should be the core object, not instantiated. - * @param {string} mapping - If this plugin is to be injected into the Scene Systems, this is the property key map used. - * @param {?any} data - A value to be passed to the plugin's `init` method. - */ -PluginCache.registerCustom = function (key, plugin, mapping, data) -{ - customPlugins[key] = { plugin: plugin, mapping: mapping, data: data }; -}; + if (anim) + { + this.emit(Events.REMOVE_ANIMATION, key, anim); -/** - * Checks if the given key is already being used in the core plugin cache. - * - * @method Phaser.Plugins.PluginCache.hasCore - * @since 3.8.0 - * - * @param {string} key - The key to check for. - * - * @return {boolean} `true` if the key is already in use in the core cache, otherwise `false`. - */ -PluginCache.hasCore = function (key) -{ - return corePlugins.hasOwnProperty(key); -}; + this.anims.delete(key); -/** - * Checks if the given key is already being used in the custom plugin cache. - * - * @method Phaser.Plugins.PluginCache.hasCustom - * @since 3.8.0 - * - * @param {string} key - The key to check for. - * - * @return {boolean} `true` if the key is already in use in the custom cache, otherwise `false`. - */ -PluginCache.hasCustom = function (key) -{ - return customPlugins.hasOwnProperty(key); -}; + this.removeMix(key); + } -/** - * Returns the core plugin object from the cache based on the given key. - * - * @method Phaser.Plugins.PluginCache.getCore - * @since 3.8.0 - * - * @param {string} key - The key of the core plugin to get. - * - * @return {Phaser.Types.Plugins.CorePluginContainer} The core plugin object. - */ -PluginCache.getCore = function (key) -{ - return corePlugins[key]; -}; + return anim; + }, -/** - * Returns the custom plugin object from the cache based on the given key. - * - * @method Phaser.Plugins.PluginCache.getCustom - * @since 3.8.0 - * - * @param {string} key - The key of the custom plugin to get. - * - * @return {Phaser.Types.Plugins.CustomPluginContainer} The custom plugin object. - */ -PluginCache.getCustom = function (key) -{ - return customPlugins[key]; -}; + /** + * Resume all paused animations. + * + * @method Phaser.Animations.AnimationManager#resumeAll + * @fires Phaser.Animations.Events#RESUME_ALL + * @since 3.0.0 + * + * @return {this} This Animation Manager. + */ + resumeAll: function () + { + if (this.paused) + { + this.paused = false; -/** - * Returns an object from the custom cache based on the given key that can be instantiated. - * - * @method Phaser.Plugins.PluginCache.getCustomClass - * @since 3.8.0 - * - * @param {string} key - The key of the custom plugin to get. - * - * @return {function} The custom plugin object. - */ -PluginCache.getCustomClass = function (key) -{ - return (customPlugins.hasOwnProperty(key)) ? customPlugins[key].plugin : null; -}; + this.emit(Events.RESUME_ALL); + } -/** - * Removes a core plugin based on the given key. - * - * @method Phaser.Plugins.PluginCache.remove - * @since 3.8.0 - * - * @param {string} key - The key of the core plugin to remove. - */ -PluginCache.remove = function (key) -{ - if (corePlugins.hasOwnProperty(key)) - { - delete corePlugins[key]; - } -}; + return this; + }, -/** - * Removes a custom plugin based on the given key. - * - * @method Phaser.Plugins.PluginCache.removeCustom - * @since 3.8.0 - * - * @param {string} key - The key of the custom plugin to remove. - */ -PluginCache.removeCustom = function (key) -{ - if (customPlugins.hasOwnProperty(key)) + /** + * Returns the Animation data as JavaScript object based on the given key. + * Or, if not key is defined, it will return the data of all animations as array of objects. + * + * @method Phaser.Animations.AnimationManager#toJSON + * @since 3.0.0 + * + * @param {string} [key] - The animation to get the JSONAnimation data from. If not provided, all animations are returned as an array. + * + * @return {Phaser.Types.Animations.JSONAnimations} The resulting JSONAnimations formatted object. + */ + toJSON: function (key) { - delete customPlugins[key]; - } -}; + var output = { + anims: [], + globalTimeScale: this.globalTimeScale + }; -/** - * Removes all Core Plugins. - * - * This includes all of the internal system plugins that Phaser needs, like the Input Plugin and Loader Plugin. - * So be sure you only call this if you do not wish to run Phaser again. - * - * @method Phaser.Plugins.PluginCache.destroyCorePlugins - * @since 3.12.0 - */ -PluginCache.destroyCorePlugins = function () -{ - for (var key in corePlugins) - { - if (corePlugins.hasOwnProperty(key)) + if (key !== undefined && key !== '') { - delete corePlugins[key]; + output.anims.push(this.anims.get(key).toJSON()); } - } -}; - -/** - * Removes all Custom Plugins. - * - * @method Phaser.Plugins.PluginCache.destroyCustomPlugins - * @since 3.12.0 - */ -PluginCache.destroyCustomPlugins = function () -{ - for (var key in customPlugins) - { - if (customPlugins.hasOwnProperty(key)) + else { - delete customPlugins[key]; + this.anims.each(function (animationKey, animation) + { + output.anims.push(animation.toJSON()); + }); } + + return output; + }, + + /** + * Destroy this Animation Manager and clean up animation definitions and references to other objects. + * This method should not be called directly. It will be called automatically as a response to a `destroy` event from the Phaser.Game instance. + * + * @method Phaser.Animations.AnimationManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.anims.clear(); + this.mixes.clear(); + + this.textureManager = null; + + this.game = null; } -}; -module.exports = PluginCache; +}); + +module.exports = AnimationManager; /***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 16569: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var MATH_CONST = __webpack_require__(14); -var Vector2 = __webpack_require__(3); +var Class = __webpack_require__(56694); +var CustomMap = __webpack_require__(33885); +var GetFastValue = __webpack_require__(72632); +var Events = __webpack_require__(16938); +var Animation = __webpack_require__(85463); /** * @classdesc - * A Matrix used for display transformations for rendering. + * The Animation State Component. * - * It is represented like so: + * This component provides features to apply animations to Game Objects. It is responsible for + * loading, queuing animations for later playback, mixing between animations and setting + * the current animation frame to the Game Object that owns this component. * - * ``` - * | a | c | tx | - * | b | d | ty | - * | 0 | 0 | 1 | - * ``` + * This component lives as an instance within any Game Object that has it defined, such as Sprites. * - * @class TransformMatrix - * @memberof Phaser.GameObjects.Components + * You can access its properties and methods via the `anims` property, i.e. `Sprite.anims`. + * + * As well as playing animations stored in the global Animation Manager, this component + * can also create animations that are stored locally within it. See the `create` method + * for more details. + * + * Prior to Phaser 3.50 this component was called just `Animation` and lived in the + * `Phaser.GameObjects.Components` namespace. It was renamed to `AnimationState` + * in 3.50 to help better identify its true purpose when browsing the documentation. + * + * @class AnimationState + * @memberof Phaser.Animations * @constructor * @since 3.0.0 * - * @param {number} [a=1] - The Scale X value. - * @param {number} [b=0] - The Skew Y value. - * @param {number} [c=0] - The Skew X value. - * @param {number} [d=1] - The Scale Y value. - * @param {number} [tx=0] - The Translate X value. - * @param {number} [ty=0] - The Translate Y value. + * @param {Phaser.GameObjects.GameObject} parent - The Game Object to which this animation component belongs. */ -var TransformMatrix = new Class({ +var AnimationState = new Class({ initialize: - function TransformMatrix (a, b, c, d, tx, ty) + function AnimationState (parent) { - if (a === undefined) { a = 1; } - if (b === undefined) { b = 0; } - if (c === undefined) { c = 0; } - if (d === undefined) { d = 1; } - if (tx === undefined) { tx = 0; } - if (ty === undefined) { ty = 0; } + /** + * The Game Object to which this animation component belongs. + * + * You can typically access this component from the Game Object + * via the `this.anims` property. + * + * @name Phaser.Animations.AnimationState#parent + * @type {Phaser.GameObjects.GameObject} + * @since 3.0.0 + */ + this.parent = parent; /** - * The matrix values. + * A reference to the global Animation Manager. * - * @name Phaser.GameObjects.Components.TransformMatrix#matrix - * @type {Float32Array} + * @name Phaser.Animations.AnimationState#animationManager + * @type {Phaser.Animations.AnimationManager} * @since 3.0.0 */ - this.matrix = new Float32Array([ a, b, c, d, tx, ty, 0, 0, 1 ]); + this.animationManager = parent.scene.sys.anims; + + this.animationManager.on(Events.REMOVE_ANIMATION, this.globalRemove, this); /** - * The decomposed matrix. + * A reference to the Texture Manager. * - * @name Phaser.GameObjects.Components.TransformMatrix#decomposedMatrix - * @type {object} + * @name Phaser.Animations.AnimationState#textureManager + * @type {Phaser.Textures.TextureManager} + * @protected + * @since 3.50.0 + */ + this.textureManager = this.animationManager.textureManager; + + /** + * The Animations stored locally in this Animation component. + * + * Do not modify the contents of this Map directly, instead use the + * `add`, `create` and `remove` methods of this class instead. + * + * @name Phaser.Animations.AnimationState#anims + * @type {Phaser.Structs.Map.} + * @protected + * @since 3.50.0 + */ + this.anims = null; + + /** + * Is an animation currently playing or not? + * + * @name Phaser.Animations.AnimationState#isPlaying + * @type {boolean} + * @default false * @since 3.0.0 */ - this.decomposedMatrix = { - translateX: 0, - translateY: 0, - scaleX: 1, - scaleY: 1, - rotation: 0 - }; - }, + this.isPlaying = false; - /** - * The Scale X value. - * - * @name Phaser.GameObjects.Components.TransformMatrix#a - * @type {number} - * @since 3.4.0 - */ - a: { + /** + * Has the current animation started playing, or is it waiting for a delay to expire? + * + * @name Phaser.Animations.AnimationState#hasStarted + * @type {boolean} + * @default false + * @since 3.50.0 + */ + this.hasStarted = false; - get: function () - { - return this.matrix[0]; - }, + /** + * The current Animation loaded into this Animation component. + * + * Will by `null` if no animation is yet loaded. + * + * @name Phaser.Animations.AnimationState#currentAnim + * @type {?Phaser.Animations.Animation} + * @default null + * @since 3.0.0 + */ + this.currentAnim = null; - set: function (value) - { - this.matrix[0] = value; - } + /** + * The current AnimationFrame being displayed by this Animation component. + * + * Will by `null` if no animation is yet loaded. + * + * @name Phaser.Animations.AnimationState#currentFrame + * @type {?Phaser.Animations.AnimationFrame} + * @default null + * @since 3.0.0 + */ + this.currentFrame = null; - }, + /** + * The key, instance, or config of the next Animation to be loaded into this Animation component + * when the current animation completes. + * + * Will by `null` if no animation has been queued. + * + * @name Phaser.Animations.AnimationState#nextAnim + * @type {?(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} + * @default null + * @since 3.16.0 + */ + this.nextAnim = null; - /** - * The Skew Y value. - * - * @name Phaser.GameObjects.Components.TransformMatrix#b - * @type {number} - * @since 3.4.0 - */ - b: { + /** + * A queue of Animations to be loaded into this Animation component when the current animation completes. + * + * Populate this queue via the `chain` method. + * + * @name Phaser.Animations.AnimationState#nextAnimsQueue + * @type {array} + * @since 3.24.0 + */ + this.nextAnimsQueue = []; - get: function () - { - return this.matrix[1]; - }, + /** + * The Time Scale factor. + * + * You can adjust this value to modify the passage of time for the animation that is currently + * playing. For example, setting it to 2 will make the animation play twice as fast. Or setting + * it to 0.5 will slow the animation down. + * + * You can change this value at run-time, or set it via the `PlayAnimationConfig`. + * + * Prior to Phaser 3.50 this property was private and called `_timeScale`. + * + * @name Phaser.Animations.AnimationState#timeScale + * @type {number} + * @default 1 + * @since 3.50.0 + */ + this.timeScale = 1; - set: function (value) - { - this.matrix[1] = value; - } + /** + * The frame rate of playback, of the current animation, in frames per second. + * + * This value is set when a new animation is loaded into this component and should + * be treated as read-only, as changing it once playback has started will not alter + * the animation. To change the frame rate, provide a new value in the `PlayAnimationConfig` object. + * + * @name Phaser.Animations.AnimationState#frameRate + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.frameRate = 0; - }, + /** + * The duration of the current animation, in milliseconds. + * + * This value is set when a new animation is loaded into this component and should + * be treated as read-only, as changing it once playback has started will not alter + * the animation. To change the duration, provide a new value in the `PlayAnimationConfig` object. + * + * @name Phaser.Animations.AnimationState#duration + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.duration = 0; - /** - * The Skew X value. - * - * @name Phaser.GameObjects.Components.TransformMatrix#c - * @type {number} - * @since 3.4.0 - */ - c: { + /** + * The number of milliseconds per frame, not including frame specific modifiers that may be present in the + * Animation data. + * + * This value is calculated when a new animation is loaded into this component and should + * be treated as read-only. Changing it will not alter playback speed. + * + * @name Phaser.Animations.AnimationState#msPerFrame + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.msPerFrame = 0; - get: function () - { - return this.matrix[2]; - }, + /** + * Skip frames if the time lags, or always advanced anyway? + * + * @name Phaser.Animations.AnimationState#skipMissedFrames + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.skipMissedFrames = true; - set: function (value) - { - this.matrix[2] = value; - } + /** + * The delay before starting playback of the current animation, in milliseconds. + * + * This value is set when a new animation is loaded into this component and should + * be treated as read-only, as changing it once playback has started will not alter + * the animation. To change the delay, provide a new value in the `PlayAnimationConfig` object. + * + * Prior to Phaser 3.50 this property was private and called `_delay`. + * + * @name Phaser.Animations.AnimationState#delay + * @type {number} + * @default 0 + * @since 3.50.0 + */ + this.delay = 0; - }, + /** + * The number of times to repeat playback of the current animation. + * + * If -1, it means the animation will repeat forever. + * + * This value is set when a new animation is loaded into this component and should + * be treated as read-only, as changing it once playback has started will not alter + * the animation. To change the number of repeats, provide a new value in the `PlayAnimationConfig` object. + * + * Prior to Phaser 3.50 this property was private and called `_repeat`. + * + * @name Phaser.Animations.AnimationState#repeat + * @type {number} + * @default 0 + * @since 3.50.0 + */ + this.repeat = 0; - /** - * The Scale Y value. - * - * @name Phaser.GameObjects.Components.TransformMatrix#d - * @type {number} - * @since 3.4.0 - */ - d: { + /** + * The number of milliseconds to wait before starting the repeat playback of the current animation. + * + * This value is set when a new animation is loaded into this component, but can also be modified + * at run-time. + * + * You can change the repeat delay by providing a new value in the `PlayAnimationConfig` object. + * + * Prior to Phaser 3.50 this property was private and called `_repeatDelay`. + * + * @name Phaser.Animations.AnimationState#repeatDelay + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.repeatDelay = 0; - get: function () - { - return this.matrix[3]; - }, + /** + * Should the current animation yoyo? An animation that yoyos will play in reverse, from the end + * to the start, before then repeating or completing. An animation that does not yoyo will just + * play from the start to the end. + * + * This value is set when a new animation is loaded into this component, but can also be modified + * at run-time. + * + * You can change the yoyo by providing a new value in the `PlayAnimationConfig` object. + * + * Prior to Phaser 3.50 this property was private and called `_yoyo`. + * + * @name Phaser.Animations.AnimationState#yoyo + * @type {boolean} + * @default false + * @since 3.50.0 + */ + this.yoyo = false; - set: function (value) - { - this.matrix[3] = value; - } + /** + * If the animation has a delay set, before playback will begin, this + * controls when the first frame is set on the Sprite. If this property + * is 'false' then the frame is set only after the delay has expired. + * This is the default behavior. + * + * If this property is 'true' then the first frame of this animation + * is set immediately, and then when the delay expires, playback starts. + * + * @name Phaser.Animations.AnimationState#showBeforeDelay + * @type {boolean} + * @since 3.60.0 + */ + this.showBeforeDelay = false; - }, + /** + * Should the GameObject's `visible` property be set to `true` when the animation starts to play? + * + * This will happen _after_ any delay that may have been set. + * + * This value is set when a new animation is loaded into this component, but can also be modified + * at run-time, assuming the animation is currently delayed. + * + * @name Phaser.Animations.AnimationState#showOnStart + * @type {boolean} + * @since 3.50.0 + */ + this.showOnStart = false; - /** - * The Translate X value. - * - * @name Phaser.GameObjects.Components.TransformMatrix#e - * @type {number} - * @since 3.11.0 - */ - e: { + /** + * Should the GameObject's `visible` property be set to `false` when the animation completes? + * + * This value is set when a new animation is loaded into this component, but can also be modified + * at run-time, assuming the animation is still actively playing. + * + * @name Phaser.Animations.AnimationState#hideOnComplete + * @type {boolean} + * @since 3.50.0 + */ + this.hideOnComplete = false; - get: function () - { - return this.matrix[4]; - }, + /** + * Is the playhead moving forwards (`true`) or in reverse (`false`) ? + * + * @name Phaser.Animations.AnimationState#forward + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.forward = true; - set: function (value) - { - this.matrix[4] = value; - } + /** + * An internal trigger that tells the component if it should plays the animation + * in reverse mode ('true') or not ('false'). This is used because `forward` can + * be changed by the `yoyo` feature. + * + * Prior to Phaser 3.50 this property was private and called `_reverse`. + * + * @name Phaser.Animations.AnimationState#inReverse + * @type {boolean} + * @default false + * @since 3.50.0 + */ + this.inReverse = false; - }, + /** + * Internal time overflow accumulator. + * + * This has the `delta` time added to it as part of the `update` step. + * + * @name Phaser.Animations.AnimationState#accumulator + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.accumulator = 0; - /** - * The Translate Y value. - * - * @name Phaser.GameObjects.Components.TransformMatrix#f - * @type {number} - * @since 3.11.0 - */ - f: { + /** + * The time point at which the next animation frame will change. + * + * This value is compared against the `accumulator` as part of the `update` step. + * + * @name Phaser.Animations.AnimationState#nextTick + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.nextTick = 0; - get: function () - { - return this.matrix[5]; - }, + /** + * A counter keeping track of how much delay time, in milliseconds, is left before playback begins. + * + * This is set via the `playAfterDelay` method, although it can be modified at run-time + * if required, as long as the animation has not already started playing. + * + * @name Phaser.Animations.AnimationState#delayCounter + * @type {number} + * @default 0 + * @since 3.50.0 + */ + this.delayCounter = 0; - set: function (value) - { - this.matrix[5] = value; - } + /** + * A counter that keeps track of how many repeats are left to run. + * + * This value is set when a new animation is loaded into this component, but can also be modified + * at run-time. + * + * @name Phaser.Animations.AnimationState#repeatCounter + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.repeatCounter = 0; - }, + /** + * An internal flag keeping track of pending repeats. + * + * @name Phaser.Animations.AnimationState#pendingRepeat + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.pendingRepeat = false; - /** - * The Translate X value. - * - * @name Phaser.GameObjects.Components.TransformMatrix#tx - * @type {number} - * @since 3.4.0 - */ - tx: { + /** + * Is the Animation paused? + * + * @name Phaser.Animations.AnimationState#_paused + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this._paused = false; - get: function () - { - return this.matrix[4]; - }, + /** + * Was the animation previously playing before being paused? + * + * @name Phaser.Animations.AnimationState#_wasPlaying + * @type {boolean} + * @private + * @default false + * @since 3.0.0 + */ + this._wasPlaying = false; - set: function (value) - { - this.matrix[4] = value; - } + /** + * Internal property tracking if this Animation is waiting to stop. + * + * 0 = No + * 1 = Waiting for ms to pass + * 2 = Waiting for repeat + * 3 = Waiting for specific frame + * + * @name Phaser.Animations.AnimationState#_pendingStop + * @type {number} + * @private + * @since 3.4.0 + */ + this._pendingStop = 0; + /** + * Internal property used by _pendingStop. + * + * @name Phaser.Animations.AnimationState#_pendingStopValue + * @type {any} + * @private + * @since 3.4.0 + */ + this._pendingStopValue; }, /** - * The Translate Y value. + * Sets an animation, or an array of animations, to be played in the future, after the current one completes or stops. * - * @name Phaser.GameObjects.Components.TransformMatrix#ty - * @type {number} - * @since 3.4.0 + * The current animation must enter a 'completed' state for this to happen, i.e. finish all of its repeats, delays, etc, + * or have one of the `stop` methods called. + * + * An animation set to repeat forever will never enter a completed state unless stopped. + * + * You can chain a new animation at any point, including before the current one starts playing, during it, or when it ends (via its `animationcomplete` event). + * + * Chained animations are specific to a Game Object, meaning different Game Objects can have different chained animations without impacting the global animation they're playing. + * + * Call this method with no arguments to reset all currently chained animations. + * + * @method Phaser.Animations.AnimationState#chain + * @since 3.16.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} [key] - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - ty: { + chain: function (key) + { + var parent = this.parent; - get: function () + if (key === undefined) { - return this.matrix[5]; - }, + this.nextAnimsQueue.length = 0; + this.nextAnim = null; - set: function (value) - { - this.matrix[5] = value; + return parent; } - }, - - /** - * The rotation of the Matrix. Value is in radians. - * - * @name Phaser.GameObjects.Components.TransformMatrix#rotation - * @type {number} - * @readonly - * @since 3.4.0 - */ - rotation: { + if (!Array.isArray(key)) + { + key = [ key ]; + } - get: function () + for (var i = 0; i < key.length; i++) { - return Math.acos(this.a / this.scaleX) * ((Math.atan(-this.c / this.a) < 0) ? -1 : 1); + var anim = key[i]; + + if (!this.nextAnim) + { + this.nextAnim = anim; + } + else + { + this.nextAnimsQueue.push(anim); + } } + return this.parent; }, /** - * The rotation of the Matrix, normalized to be within the Phaser right-handed - * clockwise rotation space. Value is in radians. + * Returns the key of the animation currently loaded into this component. * - * @name Phaser.GameObjects.Components.TransformMatrix#rotationNormalized - * @type {number} - * @readonly - * @since 3.19.0 + * Prior to Phaser 3.50 this method was called `getCurrentKey`. + * + * @method Phaser.Animations.AnimationState#getName + * @since 3.50.0 + * + * @return {string} The key of the Animation currently loaded into this component, or an empty string if none loaded. */ - rotationNormalized: { + getName: function () + { + return (this.currentAnim) ? this.currentAnim.key : ''; + }, - get: function () + /** + * Returns the key of the animation frame currently displayed by this component. + * + * @method Phaser.Animations.AnimationState#getFrameName + * @since 3.50.0 + * + * @return {string} The key of the Animation Frame currently displayed by this component, or an empty string if no animation has been loaded. + */ + getFrameName: function () + { + return (this.currentFrame) ? this.currentFrame.textureFrame : ''; + }, + + /** + * Internal method used to load an animation into this component. + * + * @method Phaser.Animations.AnimationState#load + * @protected + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or a `PlayAnimationConfig` object. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + */ + load: function (key) + { + if (this.isPlaying) { - var matrix = this.matrix; + this.stop(); + } - var a = matrix[0]; - var b = matrix[1]; - var c = matrix[2]; - var d = matrix[3]; + var manager = this.animationManager; + var animKey = (typeof key === 'string') ? key : GetFastValue(key, 'key', null); - if (a || b) - { - // var r = Math.sqrt(a * a + b * b); + // Get the animation, first from the local map and, if not found, from the Animation Manager + var anim = (this.exists(animKey)) ? this.get(animKey) : manager.get(animKey); - return (b > 0) ? Math.acos(a / this.scaleX) : -Math.acos(a / this.scaleX); - } - else if (c || d) - { - // var s = Math.sqrt(c * c + d * d); + if (!anim) + { + console.warn('Missing animation: ' + animKey); + } + else + { + this.currentAnim = anim; - return MATH_CONST.TAU - ((d > 0) ? Math.acos(-c / this.scaleY) : -Math.acos(c / this.scaleY)); - } - else + // And now override the animation values, if set in the config. + + var totalFrames = anim.getTotalFrames(); + var frameRate = GetFastValue(key, 'frameRate', anim.frameRate); + var duration = GetFastValue(key, 'duration', anim.duration); + + anim.calculateDuration(this, totalFrames, duration, frameRate); + + this.delay = GetFastValue(key, 'delay', anim.delay); + this.repeat = GetFastValue(key, 'repeat', anim.repeat); + this.repeatDelay = GetFastValue(key, 'repeatDelay', anim.repeatDelay); + this.yoyo = GetFastValue(key, 'yoyo', anim.yoyo); + this.showBeforeDelay = GetFastValue(key, 'showBeforeDelay', anim.showBeforeDelay); + this.showOnStart = GetFastValue(key, 'showOnStart', anim.showOnStart); + this.hideOnComplete = GetFastValue(key, 'hideOnComplete', anim.hideOnComplete); + this.skipMissedFrames = GetFastValue(key, 'skipMissedFrames', anim.skipMissedFrames); + + this.timeScale = GetFastValue(key, 'timeScale', this.timeScale); + + var startFrame = GetFastValue(key, 'startFrame', 0); + + if (startFrame > anim.getTotalFrames()) { - return 0; + startFrame = 0; } - } - }, + var frame = anim.frames[startFrame]; - /** - * The decomposed horizontal scale of the Matrix. This value is always positive. - * - * @name Phaser.GameObjects.Components.TransformMatrix#scaleX - * @type {number} - * @readonly - * @since 3.4.0 - */ - scaleX: { + if (startFrame === 0 && !this.forward) + { + frame = anim.getLastFrame(); + } - get: function () - { - return Math.sqrt((this.a * this.a) + (this.b * this.b)); + this.currentFrame = frame; } + return this.parent; }, /** - * The decomposed vertical scale of the Matrix. This value is always positive. + * Pause the current animation and set the `isPlaying` property to `false`. + * You can optionally pause it at a specific frame. * - * @name Phaser.GameObjects.Components.TransformMatrix#scaleY - * @type {number} - * @readonly - * @since 3.4.0 + * @method Phaser.Animations.AnimationState#pause + * @since 3.0.0 + * + * @param {Phaser.Animations.AnimationFrame} [atFrame] - An optional frame to set after pausing the animation. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - scaleY: { + pause: function (atFrame) + { + if (!this._paused) + { + this._paused = true; + this._wasPlaying = this.isPlaying; + this.isPlaying = false; + } - get: function () + if (atFrame !== undefined) { - return Math.sqrt((this.c * this.c) + (this.d * this.d)); + this.setCurrentFrame(atFrame); } + return this.parent; }, /** - * Reset the Matrix to an identity matrix. + * Resumes playback of a paused animation and sets the `isPlaying` property to `true`. + * You can optionally tell it to start playback from a specific frame. * - * @method Phaser.GameObjects.Components.TransformMatrix#loadIdentity + * @method Phaser.Animations.AnimationState#resume * @since 3.0.0 * - * @return {this} This TransformMatrix. + * @param {Phaser.Animations.AnimationFrame} [fromFrame] - An optional frame to set before restarting playback. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - loadIdentity: function () + resume: function (fromFrame) { - var matrix = this.matrix; + if (this._paused) + { + this._paused = false; + this.isPlaying = this._wasPlaying; + } - matrix[0] = 1; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 1; - matrix[4] = 0; - matrix[5] = 0; + if (fromFrame !== undefined) + { + this.setCurrentFrame(fromFrame); + } - return this; + return this.parent; }, /** - * Translate the Matrix. + * Waits for the specified delay, in milliseconds, then starts playback of the given animation. * - * @method Phaser.GameObjects.Components.TransformMatrix#translate - * @since 3.0.0 + * If the animation _also_ has a delay value set in its config, it will be **added** to the delay given here. * - * @param {number} x - The horizontal translation value. - * @param {number} y - The vertical translation value. + * If an animation is already running and a new animation is given to this method, it will wait for + * the given delay before starting the new animation. * - * @return {this} This TransformMatrix. + * If no animation is currently running, the given one begins after the delay. + * + * Prior to Phaser 3.50 this method was called 'delayedPlay' and the parameters were in the reverse order. + * + * @method Phaser.Animations.AnimationState#playAfterDelay + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.50.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {number} delay - The delay, in milliseconds, to wait before starting the animation playing. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - translate: function (x, y) + playAfterDelay: function (key, delay) { - var matrix = this.matrix; + if (!this.isPlaying) + { + this.delayCounter = delay; - matrix[4] = matrix[0] * x + matrix[2] * y + matrix[4]; - matrix[5] = matrix[1] * x + matrix[3] * y + matrix[5]; + this.play(key, true); + } + else + { + // If we've got a nextAnim, move it to the queue + var nextAnim = this.nextAnim; + var queue = this.nextAnimsQueue; - return this; + if (nextAnim) + { + queue.unshift(nextAnim); + } + + this.nextAnim = key; + + this._pendingStop = 1; + this._pendingStopValue = delay; + } + + return this.parent; }, /** - * Scale the Matrix. + * Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback + * of the given animation. * - * @method Phaser.GameObjects.Components.TransformMatrix#scale - * @since 3.0.0 + * You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an + * idle animation to a walking animation, by making them blend smoothly into each other. * - * @param {number} x - The horizontal scale value. - * @param {number} y - The vertical scale value. + * If no animation is currently running, the given one will start immediately. * - * @return {this} This TransformMatrix. + * @method Phaser.Animations.AnimationState#playAfterRepeat + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.50.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {number} [repeatCount=1] - How many times should the animation repeat before the next one starts? + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - scale: function (x, y) + playAfterRepeat: function (key, repeatCount) { - var matrix = this.matrix; + if (repeatCount === undefined) { repeatCount = 1; } - matrix[0] *= x; - matrix[1] *= x; - matrix[2] *= y; - matrix[3] *= y; + if (!this.isPlaying) + { + this.play(key); + } + else + { + // If we've got a nextAnim, move it to the queue + var nextAnim = this.nextAnim; + var queue = this.nextAnimsQueue; - return this; + if (nextAnim) + { + queue.unshift(nextAnim); + } + + if (this.repeatCounter !== -1 && repeatCount > this.repeatCounter) + { + repeatCount = this.repeatCounter; + } + + this.nextAnim = key; + + this._pendingStop = 2; + this._pendingStopValue = repeatCount; + } + + return this.parent; }, /** - * Rotate the Matrix. + * Start playing the given animation on this Sprite. * - * @method Phaser.GameObjects.Components.TransformMatrix#rotate + * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite. + * + * The benefit of a global animation is that multiple Sprites can all play the same animation, without + * having to duplicate the data. You can just create it once and then play it on any Sprite. + * + * The following code shows how to create a global repeating animation. The animation will be created + * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': + * + * ```javascript + * var config = { + * key: 'run', + * frames: 'muybridge', + * frameRate: 15, + * repeat: -1 + * }; + * + * // This code should be run from within a Scene: + * this.anims.create(config); + * ``` + * + * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone, + * you can call the `Animation.create` method instead. It accepts the exact same parameters as when + * creating a global animation, however the resulting data is kept locally in this Sprite. + * + * With the animation created, either globally or locally, you can now play it on this Sprite: + * + * ```javascript + * this.add.sprite(x, y).play('run'); + * ``` + * + * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config + * object instead: + * + * ```javascript + * this.add.sprite(x, y).play({ key: 'run', frameRate: 24 }); + * ``` + * + * When playing an animation on a Sprite it will first check to see if it can find a matching key + * locally within the Sprite. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * If you need a Sprite to be able to play both local and global animations, make sure they don't + * have conflicting keys. + * + * See the documentation for the `PlayAnimationConfig` config object for more details about this. + * + * Also, see the documentation in the Animation Manager for further details on creating animations. + * + * @method Phaser.Animations.AnimationState#play + * @fires Phaser.Animations.Events#ANIMATION_START * @since 3.0.0 * - * @param {number} angle - The angle of rotation in radians. + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {boolean} [ignoreIfPlaying=false] - If this animation is already playing then ignore this call. * - * @return {this} This TransformMatrix. + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - rotate: function (angle) + play: function (key, ignoreIfPlaying) { - var sin = Math.sin(angle); - var cos = Math.cos(angle); + if (ignoreIfPlaying === undefined) { ignoreIfPlaying = false; } - var matrix = this.matrix; + var currentAnim = this.currentAnim; + var parent = this.parent; - var a = matrix[0]; - var b = matrix[1]; - var c = matrix[2]; - var d = matrix[3]; + // Must be either an Animation instance, or a PlayAnimationConfig object + var animKey = (typeof key === 'string') ? key : key.key; - matrix[0] = a * cos + c * sin; - matrix[1] = b * cos + d * sin; - matrix[2] = a * -sin + c * cos; - matrix[3] = b * -sin + d * cos; + if (ignoreIfPlaying && this.isPlaying && currentAnim.key === animKey) + { + return parent; + } - return this; + // Are we mixing? + if (currentAnim && this.isPlaying) + { + var mix = this.animationManager.getMix(currentAnim.key, key); + + if (mix > 0) + { + return this.playAfterDelay(key, mix); + } + } + + this.forward = true; + this.inReverse = false; + + this._paused = false; + this._wasPlaying = true; + + return this.startAnimation(key); }, /** - * Multiply this Matrix by the given Matrix. + * Start playing the given animation on this Sprite, in reverse. * - * If an `out` Matrix is given then the results will be stored in it. - * If it is not given, this matrix will be updated in place instead. - * Use an `out` Matrix if you do not wish to mutate this matrix. + * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite. * - * @method Phaser.GameObjects.Components.TransformMatrix#multiply - * @since 3.0.0 + * The benefit of a global animation is that multiple Sprites can all play the same animation, without + * having to duplicate the data. You can just create it once and then play it on any Sprite. * - * @param {Phaser.GameObjects.Components.TransformMatrix} rhs - The Matrix to multiply by. - * @param {Phaser.GameObjects.Components.TransformMatrix} [out] - An optional Matrix to store the results in. + * The following code shows how to create a global repeating animation. The animation will be created + * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': * - * @return {(this|Phaser.GameObjects.Components.TransformMatrix)} Either this TransformMatrix, or the `out` Matrix, if given in the arguments. + * ```javascript + * var config = { + * key: 'run', + * frames: 'muybridge', + * frameRate: 15, + * repeat: -1 + * }; + * + * // This code should be run from within a Scene: + * this.anims.create(config); + * ``` + * + * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone, + * you can call the `Animation.create` method instead. It accepts the exact same parameters as when + * creating a global animation, however the resulting data is kept locally in this Sprite. + * + * With the animation created, either globally or locally, you can now play it on this Sprite: + * + * ```javascript + * this.add.sprite(x, y).playReverse('run'); + * ``` + * + * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config + * object instead: + * + * ```javascript + * this.add.sprite(x, y).playReverse({ key: 'run', frameRate: 24 }); + * ``` + * + * When playing an animation on a Sprite it will first check to see if it can find a matching key + * locally within the Sprite. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * If you need a Sprite to be able to play both local and global animations, make sure they don't + * have conflicting keys. + * + * See the documentation for the `PlayAnimationConfig` config object for more details about this. + * + * Also, see the documentation in the Animation Manager for further details on creating animations. + * + * @method Phaser.Animations.AnimationState#playReverse + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.12.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - multiply: function (rhs, out) + playReverse: function (key, ignoreIfPlaying) { - var matrix = this.matrix; - var source = rhs.matrix; + if (ignoreIfPlaying === undefined) { ignoreIfPlaying = false; } - var localA = matrix[0]; - var localB = matrix[1]; - var localC = matrix[2]; - var localD = matrix[3]; - var localE = matrix[4]; - var localF = matrix[5]; + // Must be either an Animation instance, or a PlayAnimationConfig object + var animKey = (typeof key === 'string') ? key : key.key; - var sourceA = source[0]; - var sourceB = source[1]; - var sourceC = source[2]; - var sourceD = source[3]; - var sourceE = source[4]; - var sourceF = source[5]; + if (ignoreIfPlaying && this.isPlaying && this.currentAnim.key === animKey) + { + return this.parent; + } - var destinationMatrix = (out === undefined) ? this : out; + this.forward = false; + this.inReverse = true; - destinationMatrix.a = (sourceA * localA) + (sourceB * localC); - destinationMatrix.b = (sourceA * localB) + (sourceB * localD); - destinationMatrix.c = (sourceC * localA) + (sourceD * localC); - destinationMatrix.d = (sourceC * localB) + (sourceD * localD); - destinationMatrix.e = (sourceE * localA) + (sourceF * localC) + localE; - destinationMatrix.f = (sourceE * localB) + (sourceF * localD) + localF; + this._paused = false; + this._wasPlaying = true; - return destinationMatrix; + return this.startAnimation(key); }, /** - * Multiply this Matrix by the matrix given, including the offset. - * - * The offsetX is added to the tx value: `offsetX * a + offsetY * c + tx`. - * The offsetY is added to the ty value: `offsetY * b + offsetY * d + ty`. + * Load the animation based on the key and set-up all of the internal values + * needed for playback to start. If there is no delay, it will also fire the start events. * - * @method Phaser.GameObjects.Components.TransformMatrix#multiplyWithOffset - * @since 3.11.0 + * @method Phaser.Animations.AnimationState#startAnimation + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.50.0 * - * @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from. - * @param {number} offsetX - Horizontal offset to factor in to the multiplication. - * @param {number} offsetY - Vertical offset to factor in to the multiplication. + * @param {(string|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or a `PlayAnimationConfig` object. * - * @return {this} This TransformMatrix. + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - multiplyWithOffset: function (src, offsetX, offsetY) + startAnimation: function (key) { - var matrix = this.matrix; - var otherMatrix = src.matrix; + this.load(key); - var a0 = matrix[0]; - var b0 = matrix[1]; - var c0 = matrix[2]; - var d0 = matrix[3]; - var tx0 = matrix[4]; - var ty0 = matrix[5]; + var anim = this.currentAnim; + var gameObject = this.parent; - var pse = offsetX * a0 + offsetY * c0 + tx0; - var psf = offsetX * b0 + offsetY * d0 + ty0; + if (!anim) + { + return gameObject; + } - var a1 = otherMatrix[0]; - var b1 = otherMatrix[1]; - var c1 = otherMatrix[2]; - var d1 = otherMatrix[3]; - var tx1 = otherMatrix[4]; - var ty1 = otherMatrix[5]; + // Should give us 9,007,199,254,740,991 safe repeats + this.repeatCounter = (this.repeat === -1) ? Number.MAX_VALUE : this.repeat; - matrix[0] = a1 * a0 + b1 * c0; - matrix[1] = a1 * b0 + b1 * d0; - matrix[2] = c1 * a0 + d1 * c0; - matrix[3] = c1 * b0 + d1 * d0; - matrix[4] = tx1 * a0 + ty1 * c0 + pse; - matrix[5] = tx1 * b0 + ty1 * d0 + psf; + anim.getFirstTick(this); - return this; + this.isPlaying = true; + this.pendingRepeat = false; + this.hasStarted = false; + + this._pendingStop = 0; + this._pendingStopValue = 0; + this._paused = false; + + // Add any delay the animation itself may have had as well + this.delayCounter += this.delay; + + if (this.delayCounter === 0) + { + this.handleStart(); + } + else if (this.showBeforeDelay) + { + // We have a delay, but still need to set the frame + this.setCurrentFrame(this.currentFrame); + } + + return gameObject; }, /** - * Transform the Matrix. - * - * @method Phaser.GameObjects.Components.TransformMatrix#transform - * @since 3.0.0 - * - * @param {number} a - The Scale X value. - * @param {number} b - The Shear Y value. - * @param {number} c - The Shear X value. - * @param {number} d - The Scale Y value. - * @param {number} tx - The Translate X value. - * @param {number} ty - The Translate Y value. + * Handles the start of an animation playback. * - * @return {this} This TransformMatrix. + * @method Phaser.Animations.AnimationState#handleStart + * @private + * @since 3.50.0 */ - transform: function (a, b, c, d, tx, ty) + handleStart: function () { - var matrix = this.matrix; + if (this.showOnStart) + { + this.parent.setVisible(true); + } - var a0 = matrix[0]; - var b0 = matrix[1]; - var c0 = matrix[2]; - var d0 = matrix[3]; - var tx0 = matrix[4]; - var ty0 = matrix[5]; + this.setCurrentFrame(this.currentFrame); - matrix[0] = a * a0 + b * c0; - matrix[1] = a * b0 + b * d0; - matrix[2] = c * a0 + d * c0; - matrix[3] = c * b0 + d * d0; - matrix[4] = tx * a0 + ty * c0 + tx0; - matrix[5] = tx * b0 + ty * d0 + ty0; + this.hasStarted = true; - return this; + this.emitEvents(Events.ANIMATION_START); }, /** - * Transform a point using this Matrix. - * - * @method Phaser.GameObjects.Components.TransformMatrix#transformPoint - * @since 3.0.0 - * - * @param {number} x - The x coordinate of the point to transform. - * @param {number} y - The y coordinate of the point to transform. - * @param {(Phaser.Geom.Point|Phaser.Math.Vector2|object)} point - The Point object to store the transformed coordinates. + * Handles the repeat of an animation. * - * @return {(Phaser.Geom.Point|Phaser.Math.Vector2|object)} The Point containing the transformed coordinates. + * @method Phaser.Animations.AnimationState#handleRepeat + * @private + * @since 3.50.0 */ - transformPoint: function (x, y, point) + handleRepeat: function () { - if (point === undefined) { point = { x: 0, y: 0 }; } + this.pendingRepeat = false; - var matrix = this.matrix; + this.emitEvents(Events.ANIMATION_REPEAT); + }, - var a = matrix[0]; - var b = matrix[1]; - var c = matrix[2]; - var d = matrix[3]; - var tx = matrix[4]; - var ty = matrix[5]; + /** + * Handles the stop of an animation playback. + * + * @method Phaser.Animations.AnimationState#handleStop + * @private + * @since 3.50.0 + */ + handleStop: function () + { + this._pendingStop = 0; - point.x = x * a + y * c + tx; - point.y = x * b + y * d + ty; + this.isPlaying = false; - return point; + this.emitEvents(Events.ANIMATION_STOP); }, /** - * Invert the Matrix. - * - * @method Phaser.GameObjects.Components.TransformMatrix#invert - * @since 3.0.0 + * Handles the completion of an animation playback. * - * @return {this} This TransformMatrix. + * @method Phaser.Animations.AnimationState#handleComplete + * @private + * @since 3.50.0 */ - invert: function () + handleComplete: function () { - var matrix = this.matrix; - - var a = matrix[0]; - var b = matrix[1]; - var c = matrix[2]; - var d = matrix[3]; - var tx = matrix[4]; - var ty = matrix[5]; + this._pendingStop = 0; - var n = a * d - b * c; + this.isPlaying = false; - matrix[0] = d / n; - matrix[1] = -b / n; - matrix[2] = -c / n; - matrix[3] = a / n; - matrix[4] = (c * ty - d * tx) / n; - matrix[5] = -(a * ty - b * tx) / n; + if (this.hideOnComplete) + { + this.parent.setVisible(false); + } - return this; + this.emitEvents(Events.ANIMATION_COMPLETE, Events.ANIMATION_COMPLETE_KEY); }, /** - * Set the values of this Matrix to copy those of the matrix given. - * - * @method Phaser.GameObjects.Components.TransformMatrix#copyFrom - * @since 3.11.0 + * Fires the given animation event. * - * @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from. + * @method Phaser.Animations.AnimationState#emitEvents + * @private + * @since 3.50.0 * - * @return {this} This TransformMatrix. + * @param {string} event - The Animation Event to dispatch. */ - copyFrom: function (src) + emitEvents: function (event, keyEvent) { - var matrix = this.matrix; + var anim = this.currentAnim; - matrix[0] = src.a; - matrix[1] = src.b; - matrix[2] = src.c; - matrix[3] = src.d; - matrix[4] = src.e; - matrix[5] = src.f; + if (anim) + { + var frame = this.currentFrame; - return this; + var gameObject = this.parent; + + var frameKey = frame.textureFrame; + + gameObject.emit(event, anim, frame, gameObject, frameKey); + + if (keyEvent) + { + gameObject.emit(keyEvent + anim.key, anim, frame, gameObject, frameKey); + } + } }, /** - * Set the values of this Matrix to copy those of the array given. - * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f. - * - * @method Phaser.GameObjects.Components.TransformMatrix#copyFromArray - * @since 3.11.0 + * Reverse the Animation that is already playing on the Game Object. * - * @param {array} src - The array of values to set into this matrix. + * @method Phaser.Animations.AnimationState#reverse + * @since 3.12.0 * - * @return {this} This TransformMatrix. + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - copyFromArray: function (src) + reverse: function () { - var matrix = this.matrix; + if (this.isPlaying) + { + this.inReverse = !this.inReverse; - matrix[0] = src[0]; - matrix[1] = src[1]; - matrix[2] = src[2]; - matrix[3] = src[3]; - matrix[4] = src[4]; - matrix[5] = src[5]; + this.forward = !this.forward; + } - return this; + return this.parent; }, /** - * Copy the values from this Matrix to the given Canvas Rendering Context. - * This will use the Context.transform method. + * Returns a value between 0 and 1 indicating how far this animation is through, ignoring repeats and yoyos. * - * @method Phaser.GameObjects.Components.TransformMatrix#copyToContext - * @since 3.12.0 + * The value is based on the current frame and how far that is in the animation, it is not based on + * the duration of the animation. * - * @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to. + * @method Phaser.Animations.AnimationState#getProgress + * @since 3.4.0 * - * @return {CanvasRenderingContext2D} The Canvas Rendering Context. + * @return {number} The progress of the current animation in frames, between 0 and 1. */ - copyToContext: function (ctx) + getProgress: function () { - var matrix = this.matrix; + var frame = this.currentFrame; - ctx.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); + if (!frame) + { + return 0; + } - return ctx; + var p = frame.progress; + + if (this.inReverse) + { + p *= -1; + } + + return p; }, /** - * Copy the values from this Matrix to the given Canvas Rendering Context. - * This will use the Context.setTransform method. + * Takes a value between 0 and 1 and uses it to set how far this animation is through playback. * - * @method Phaser.GameObjects.Components.TransformMatrix#setToContext - * @since 3.12.0 + * Does not factor in repeats or yoyos, but does handle playing forwards or backwards. * - * @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to. + * The value is based on the current frame and how far that is in the animation, it is not based on + * the duration of the animation. * - * @return {CanvasRenderingContext2D} The Canvas Rendering Context. + * @method Phaser.Animations.AnimationState#setProgress + * @since 3.4.0 + * + * @param {number} [value=0] - The progress value, between 0 and 1. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - setToContext: function (ctx) + setProgress: function (value) { - var matrix = this.matrix; + if (!this.forward) + { + value = 1 - value; + } - ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); + this.setCurrentFrame(this.currentAnim.getFrameByProgress(value)); - return ctx; + return this.parent; }, /** - * Copy the values in this Matrix to the array given. + * Sets the number of times that the animation should repeat after its first play through. + * For example, if repeat is 1, the animation will play a total of twice: the initial play plus 1 repeat. * - * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f. + * To repeat indefinitely, use -1. + * The value should always be an integer. * - * @method Phaser.GameObjects.Components.TransformMatrix#copyToArray - * @since 3.12.0 + * Calling this method only works if the animation is already running. Otherwise, any + * value specified here will be overwritten when the next animation loads in. To avoid this, + * use the `repeat` property of the `PlayAnimationConfig` object instead. * - * @param {array} [out] - The array to copy the matrix values in to. + * @method Phaser.Animations.AnimationState#setRepeat + * @since 3.4.0 * - * @return {array} An array where elements 0 to 5 contain the values from this matrix. + * @param {number} value - The number of times that the animation should repeat. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - copyToArray: function (out) + setRepeat: function (value) { - var matrix = this.matrix; - - if (out === undefined) - { - out = [ matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5] ]; - } - else - { - out[0] = matrix[0]; - out[1] = matrix[1]; - out[2] = matrix[2]; - out[3] = matrix[3]; - out[4] = matrix[4]; - out[5] = matrix[5]; - } + this.repeatCounter = (value === -1) ? Number.MAX_VALUE : value; - return out; + return this.parent; }, /** - * Set the values of this Matrix. - * - * @method Phaser.GameObjects.Components.TransformMatrix#setTransform - * @since 3.0.0 + * Handle the removal of an animation from the Animation Manager. * - * @param {number} a - The Scale X value. - * @param {number} b - The Shear Y value. - * @param {number} c - The Shear X value. - * @param {number} d - The Scale Y value. - * @param {number} tx - The Translate X value. - * @param {number} ty - The Translate Y value. + * @method Phaser.Animations.AnimationState#globalRemove + * @since 3.50.0 * - * @return {this} This TransformMatrix. + * @param {string} [key] - The key of the removed Animation. + * @param {Phaser.Animations.Animation} [animation] - The removed Animation. */ - setTransform: function (a, b, c, d, tx, ty) + globalRemove: function (key, animation) { - var matrix = this.matrix; + if (animation === undefined) { animation = this.currentAnim; } - matrix[0] = a; - matrix[1] = b; - matrix[2] = c; - matrix[3] = d; - matrix[4] = tx; - matrix[5] = ty; + if (this.isPlaying && animation.key === this.currentAnim.key) + { + this.stop(); - return this; + this.setCurrentFrame(this.currentAnim.frames[0]); + } }, /** - * Decompose this Matrix into its translation, scale and rotation values using QR decomposition. + * Restarts the current animation from its beginning. * - * The result must be applied in the following order to reproduce the current matrix: + * You can optionally reset the delay and repeat counters as well. * - * translate -> rotate -> scale + * Calling this will fire the `ANIMATION_RESTART` event immediately. * - * @method Phaser.GameObjects.Components.TransformMatrix#decomposeMatrix + * If you `includeDelay` then it will also fire the `ANIMATION_START` event once + * the delay has expired, otherwise, playback will just begin immediately. + * + * @method Phaser.Animations.AnimationState#restart + * @fires Phaser.Animations.Events#ANIMATION_RESTART * @since 3.0.0 * - * @return {object} The decomposed Matrix. + * @param {boolean} [includeDelay=false] - Whether to include the delay value of the animation when restarting. + * @param {boolean} [resetRepeats=false] - Whether to reset the repeat counter or not? + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - decomposeMatrix: function () + restart: function (includeDelay, resetRepeats) { - var decomposedMatrix = this.decomposedMatrix; + if (includeDelay === undefined) { includeDelay = false; } + if (resetRepeats === undefined) { resetRepeats = false; } - var matrix = this.matrix; + var anim = this.currentAnim; + var gameObject = this.parent; - // a = scale X (1) - // b = shear Y (0) - // c = shear X (0) - // d = scale Y (1) + if (!anim) + { + return gameObject; + } - var a = matrix[0]; - var b = matrix[1]; - var c = matrix[2]; - var d = matrix[3]; + if (resetRepeats) + { + this.repeatCounter = (this.repeat === -1) ? Number.MAX_VALUE : this.repeat; + } - var determ = a * d - b * c; + anim.getFirstTick(this); - decomposedMatrix.translateX = matrix[4]; - decomposedMatrix.translateY = matrix[5]; + this.emitEvents(Events.ANIMATION_RESTART); - if (a || b) - { - var r = Math.sqrt(a * a + b * b); + this.isPlaying = true; + this.pendingRepeat = false; - decomposedMatrix.rotation = (b > 0) ? Math.acos(a / r) : -Math.acos(a / r); - decomposedMatrix.scaleX = r; - decomposedMatrix.scaleY = determ / r; - } - else if (c || d) - { - var s = Math.sqrt(c * c + d * d); + // Set this to `true` if there is no delay to include, so it skips the `hasStarted` check in `update`. + this.hasStarted = !includeDelay; - decomposedMatrix.rotation = Math.PI * 0.5 - (d > 0 ? Math.acos(-c / s) : -Math.acos(c / s)); - decomposedMatrix.scaleX = determ / s; - decomposedMatrix.scaleY = s; - } - else - { - decomposedMatrix.rotation = 0; - decomposedMatrix.scaleX = 0; - decomposedMatrix.scaleY = 0; - } + this._pendingStop = 0; + this._pendingStopValue = 0; + this._paused = false; - return decomposedMatrix; + this.setCurrentFrame(anim.frames[0]); + + return this.parent; }, /** - * Apply the identity, translate, rotate and scale operations on the Matrix. + * The current animation has completed. This dispatches the `ANIMATION_COMPLETE` event. * - * @method Phaser.GameObjects.Components.TransformMatrix#applyITRS - * @since 3.0.0 + * This method is called by the Animation instance and should not usually be invoked directly. * - * @param {number} x - The horizontal translation. - * @param {number} y - The vertical translation. - * @param {number} rotation - The angle of rotation in radians. - * @param {number} scaleX - The horizontal scale. - * @param {number} scaleY - The vertical scale. + * If no animation is loaded, no events will be dispatched. * - * @return {this} This TransformMatrix. + * If another animation has been queued for playback, it will be started after the events fire. + * + * @method Phaser.Animations.AnimationState#complete + * @fires Phaser.Animations.Events#ANIMATION_COMPLETE + * @since 3.50.0 + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - applyITRS: function (x, y, rotation, scaleX, scaleY) + complete: function () { - var matrix = this.matrix; + this._pendingStop = 0; - var radianSin = Math.sin(rotation); - var radianCos = Math.cos(rotation); + this.isPlaying = false; - // Translate - matrix[4] = x; - matrix[5] = y; + if (this.currentAnim) + { + this.handleComplete(); + } - // Rotate and Scale - matrix[0] = radianCos * scaleX; - matrix[1] = radianSin * scaleX; - matrix[2] = -radianSin * scaleY; - matrix[3] = radianCos * scaleY; + if (this.nextAnim) + { + var key = this.nextAnim; - return this; + this.nextAnim = (this.nextAnimsQueue.length > 0) ? this.nextAnimsQueue.shift() : null; + + this.play(key); + } + + return this.parent; }, /** - * Takes the `x` and `y` values and returns a new position in the `output` vector that is the inverse of - * the current matrix with its transformation applied. + * Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` event. * - * Can be used to translate points from world to local space. + * If no animation is running, no events will be dispatched. * - * @method Phaser.GameObjects.Components.TransformMatrix#applyInverse - * @since 3.12.0 + * If there is another animation in the queue (set via the `chain` method) then it will start playing. * - * @param {number} x - The x position to translate. - * @param {number} y - The y position to translate. - * @param {Phaser.Math.Vector2} [output] - A Vector2, or point-like object, to store the results in. + * @method Phaser.Animations.AnimationState#stop + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.0.0 * - * @return {Phaser.Math.Vector2} The coordinates, inverse-transformed through this matrix. + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - applyInverse: function (x, y, output) + stop: function () { - if (output === undefined) { output = new Vector2(); } + this._pendingStop = 0; - var matrix = this.matrix; + this.isPlaying = false; - var a = matrix[0]; - var b = matrix[1]; - var c = matrix[2]; - var d = matrix[3]; - var tx = matrix[4]; - var ty = matrix[5]; + this.delayCounter = 0; - var id = 1 / ((a * d) + (c * -b)); + if (this.currentAnim) + { + this.handleStop(); + } - output.x = (d * id * x) + (-c * id * y) + (((ty * c) - (tx * d)) * id); - output.y = (a * id * y) + (-b * id * x) + (((-ty * a) + (tx * b)) * id); + if (this.nextAnim) + { + var key = this.nextAnim; - return output; + this.nextAnim = this.nextAnimsQueue.shift(); + + this.play(key); + } + + return this.parent; }, /** - * Returns the X component of this matrix multiplied by the given values. - * This is the same as `x * a + y * c + e`. + * Stops the current animation from playing after the specified time delay, given in milliseconds. * - * @method Phaser.GameObjects.Components.TransformMatrix#getX - * @since 3.12.0 + * It then dispatches the `ANIMATION_STOP` event. * - * @param {number} x - The x value. - * @param {number} y - The y value. + * If no animation is running, no events will be dispatched. * - * @return {number} The calculated x value. + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. + * + * @method Phaser.Animations.AnimationState#stopAfterDelay + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.4.0 + * + * @param {number} delay - The number of milliseconds to wait before stopping this animation. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - getX: function (x, y) + stopAfterDelay: function (delay) { - return x * this.a + y * this.c + this.e; + this._pendingStop = 1; + this._pendingStopValue = delay; + + return this.parent; }, /** - * Returns the Y component of this matrix multiplied by the given values. - * This is the same as `x * b + y * d + f`. + * Stops the current animation from playing when it next repeats. * - * @method Phaser.GameObjects.Components.TransformMatrix#getY - * @since 3.12.0 + * It then dispatches the `ANIMATION_STOP` event. * - * @param {number} x - The x value. - * @param {number} y - The y value. + * If no animation is running, no events will be dispatched. * - * @return {number} The calculated y value. - */ - getY: function (x, y) - { - return x * this.b + y * this.d + this.f; - }, - - /** - * Returns the X component of this matrix multiplied by the given values. + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. * - * This is the same as `x * a + y * c + e`, optionally passing via `Math.round`. + * Prior to Phaser 3.50 this method was called `stopOnRepeat` and had no parameters. * - * @method Phaser.GameObjects.Components.TransformMatrix#getXRound + * @method Phaser.Animations.AnimationState#stopAfterRepeat + * @fires Phaser.Animations.Events#ANIMATION_STOP * @since 3.50.0 * - * @param {number} x - The x value. - * @param {number} y - The y value. - * @param {boolean} [round=false] - Math.round the resulting value? + * @param {number} [repeatCount=1] - How many times should the animation repeat before stopping? * - * @return {number} The calculated x value. + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - getXRound: function (x, y, round) + stopAfterRepeat: function (repeatCount) { - var v = this.getX(x, y); + if (repeatCount === undefined) { repeatCount = 1; } - if (round) + if (this.repeatCounter !== -1 && repeatCount > this.repeatCounter) { - v = Math.round(v); + repeatCount = this.repeatCounter; } - return v; + this._pendingStop = 2; + this._pendingStopValue = repeatCount; + + return this.parent; }, /** - * Returns the Y component of this matrix multiplied by the given values. + * Stops the current animation from playing when it next sets the given frame. + * If this frame doesn't exist within the animation it will not stop it from playing. * - * This is the same as `x * b + y * d + f`, optionally passing via `Math.round`. + * It then dispatches the `ANIMATION_STOP` event. * - * @method Phaser.GameObjects.Components.TransformMatrix#getYRound - * @since 3.50.0 + * If no animation is running, no events will be dispatched. * - * @param {number} x - The x value. - * @param {number} y - The y value. - * @param {boolean} [round=false] - Math.round the resulting value? + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. * - * @return {number} The calculated y value. + * @method Phaser.Animations.AnimationState#stopOnFrame + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.4.0 + * + * @param {Phaser.Animations.AnimationFrame} frame - The frame to check before stopping this animation. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. */ - getYRound: function (x, y, round) + stopOnFrame: function (frame) { - var v = this.getY(x, y); - - if (round) - { - v = Math.round(v); - } + this._pendingStop = 3; + this._pendingStopValue = frame; - return v; + return this.parent; }, /** - * Returns a string that can be used in a CSS Transform call as a `matrix` property. + * Returns the total number of frames in this animation, or returns zero if no + * animation has been loaded. * - * @method Phaser.GameObjects.Components.TransformMatrix#getCSSMatrix - * @since 3.12.0 + * @method Phaser.Animations.AnimationState#getTotalFrames + * @since 3.4.0 * - * @return {string} A string containing the CSS Transform matrix values. + * @return {number} The total number of frames in the current animation, or zero if no animation has been loaded. */ - getCSSMatrix: function () + getTotalFrames: function () { - var m = this.matrix; - - return 'matrix(' + m[0] + ',' + m[1] + ',' + m[2] + ',' + m[3] + ',' + m[4] + ',' + m[5] + ')'; + return (this.currentAnim) ? this.currentAnim.getTotalFrames() : 0; }, /** - * Destroys this Transform Matrix. + * The internal update loop for the AnimationState Component. * - * @method Phaser.GameObjects.Components.TransformMatrix#destroy - * @since 3.4.0 + * This is called automatically by the `Sprite.preUpdate` method. + * + * @method Phaser.Animations.AnimationState#update + * @since 3.0.0 + * + * @param {number} time - The current timestamp. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. */ - destroy: function () + update: function (time, delta) { - this.matrix = null; - this.decomposedMatrix = null; - } + var anim = this.currentAnim; -}); + if (!this.isPlaying || !anim || anim.paused) + { + return; + } -module.exports = TransformMatrix; + this.accumulator += delta * this.timeScale; + if (this._pendingStop === 1) + { + this._pendingStopValue -= delta; -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { + if (this._pendingStopValue <= 0) + { + return this.stop(); + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!this.hasStarted) + { + if (this.accumulator >= this.delayCounter) + { + this.accumulator -= this.delayCounter; -var GetFastValue = __webpack_require__(2); + this.handleStart(); + } + } + else if (this.accumulator >= this.nextTick) + { + // Process one frame advance as standard -/** - * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile[]} Array of Tile objects. - */ -var GetTilesWithin = function (tileX, tileY, width, height, filteringOptions, layer) -{ - if (tileX === undefined) { tileX = 0; } - if (tileY === undefined) { tileY = 0; } - if (width === undefined) { width = layer.width; } - if (height === undefined) { height = layer.height; } - if (!filteringOptions) { filteringOptions = {}; } + if (this.forward) + { + anim.nextFrame(this); + } + else + { + anim.previousFrame(this); + } - var isNotEmpty = GetFastValue(filteringOptions, 'isNotEmpty', false); - var isColliding = GetFastValue(filteringOptions, 'isColliding', false); - var hasInterestingFace = GetFastValue(filteringOptions, 'hasInterestingFace', false); + // And only do more if we're skipping frames and have time left + if (this.isPlaying && this._pendingStop === 0 && this.skipMissedFrames && this.accumulator > this.nextTick) + { + var safetyNet = 0; - // Clip x, y to top left of map, while shrinking width/height to match. - if (tileX < 0) - { - width += tileX; - tileX = 0; - } + do + { + if (this.forward) + { + anim.nextFrame(this); + } + else + { + anim.previousFrame(this); + } - if (tileY < 0) - { - height += tileY; - tileY = 0; - } + safetyNet++; - // Clip width and height to bottom right of map. - if (tileX + width > layer.width) - { - width = Math.max(layer.width - tileX, 0); - } + } while (this.isPlaying && this.accumulator > this.nextTick && safetyNet < 60); + } + } + }, - if (tileY + height > layer.height) + /** + * Sets the given Animation Frame as being the current frame + * and applies it to the parent Game Object, adjusting size and origin as needed. + * + * @method Phaser.Animations.AnimationState#setCurrentFrame + * @fires Phaser.Animations.Events#ANIMATION_UPDATE + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.4.0 + * + * @param {Phaser.Animations.AnimationFrame} animationFrame - The animation frame to change to. + * + * @return {Phaser.GameObjects.GameObject} The Game Object this Animation Component belongs to. + */ + setCurrentFrame: function (animationFrame) { - height = Math.max(layer.height - tileY, 0); - } + var gameObject = this.parent; - var results = []; + this.currentFrame = animationFrame; - for (var ty = tileY; ty < tileY + height; ty++) - { - for (var tx = tileX; tx < tileX + width; tx++) - { - var tile = layer.data[ty][tx]; + gameObject.texture = animationFrame.frame.texture; + gameObject.frame = animationFrame.frame; - if (tile !== null) - { - if (isNotEmpty && tile.index === -1) - { - continue; - } + if (gameObject.isCropped) + { + gameObject.frame.updateCropUVs(gameObject._crop, gameObject.flipX, gameObject.flipY); + } - if (isColliding && !tile.collides) - { - continue; - } + if (animationFrame.setAlpha) + { + gameObject.alpha = animationFrame.alpha; + } - if (hasInterestingFace && !tile.hasInterestingFace) - { - continue; - } + gameObject.setSizeToFrame(); - results.push(tile); + if (gameObject._originComponent) + { + if (animationFrame.frame.customPivot) + { + gameObject.setOrigin(animationFrame.frame.pivotX, animationFrame.frame.pivotY); + } + else + { + gameObject.updateDisplayOrigin(); } } - } - - return results; -}; - -module.exports = GetTilesWithin; - -/***/ }), -/* 27 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.isPlaying && this.hasStarted) + { + this.emitEvents(Events.ANIMATION_UPDATE); -/** - * Takes an array of Game Objects, or any objects that have a public property as defined in `key`, - * and then sets it to the given value. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `PropertyValueSet(group.getChildren(), key, value, step)` - * - * @function Phaser.Actions.PropertyValueSet - * @since 3.3.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {string} key - The property to be updated. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var PropertyValueSet = function (items, key, value, step, index, direction) -{ - if (step === undefined) { step = 0; } - if (index === undefined) { index = 0; } - if (direction === undefined) { direction = 1; } + if (this._pendingStop === 3 && this._pendingStopValue === animationFrame) + { + this.stop(); + } + } - var i; - var t = 0; - var end = items.length; + return gameObject; + }, - if (direction === 1) + /** + * Advances the animation to the next frame, regardless of the time or animation state. + * If the animation is set to repeat, or yoyo, this will still take effect. + * + * Calling this does not change the direction of the animation. I.e. if it was currently + * playing in reverse, calling this method doesn't then change the direction to forwards. + * + * @method Phaser.Animations.AnimationState#nextFrame + * @since 3.16.0 + * + * @return {Phaser.GameObjects.GameObject} The Game Object this Animation Component belongs to. + */ + nextFrame: function () { - // Start to End - for (i = index; i < end; i++) + if (this.currentAnim) { - items[i][key] = value + (t * step); - t++; + this.currentAnim.nextFrame(this); } - } - else + + return this.parent; + }, + + /** + * Advances the animation to the previous frame, regardless of the time or animation state. + * If the animation is set to repeat, or yoyo, this will still take effect. + * + * Calling this does not change the direction of the animation. I.e. if it was currently + * playing in forwards, calling this method doesn't then change the direction to backwards. + * + * @method Phaser.Animations.AnimationState#previousFrame + * @since 3.16.0 + * + * @return {Phaser.GameObjects.GameObject} The Game Object this Animation Component belongs to. + */ + previousFrame: function () { - // End to Start - for (i = index; i >= 0; i--) + if (this.currentAnim) { - items[i][key] = value + (t * step); - t++; + this.currentAnim.previousFrame(this); } - } - - return items; -}; - -module.exports = PropertyValueSet; + return this.parent; + }, -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Get an Animation instance that has been created locally on this Sprite. + * + * See the `create` method for more details. + * + * @method Phaser.Animations.AnimationState#get + * @since 3.50.0 + * + * @param {string} key - The key of the Animation to retrieve. + * + * @return {Phaser.Animations.Animation} The Animation, or `null` if the key is invalid. + */ + get: function (key) + { + return (this.anims) ? this.anims.get(key) : null; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Checks to see if the given key is already used locally within the animations stored on this Sprite. + * + * @method Phaser.Animations.AnimationState#exists + * @since 3.50.0 + * + * @param {string} key - The key of the Animation to check. + * + * @return {boolean} `true` if the Animation exists locally, or `false` if the key is available, or there are no local animations. + */ + exists: function (key) + { + return (this.anims) ? this.anims.has(key) : false; + }, -var BlendModes = __webpack_require__(35); -var GetAdvancedValue = __webpack_require__(13); + /** + * Creates a new Animation that is local specifically to this Sprite. + * + * When a Sprite owns an animation, it is kept out of the global Animation Manager, which means + * you're free to use keys that may be already defined there. Unless you specifically need a Sprite + * to have a unique animation, you should favor using global animations instead, as they allow for + * the same animation to be used across multiple Sprites, saving on memory. However, if this Sprite + * is the only one to use this animation, it's sensible to create it here. + * + * If an invalid key is given this method will return `false`. + * + * If you pass the key of an animation that already exists locally, that animation will be returned. + * + * A brand new animation is only created if the key is valid and not already in use by this Sprite. + * + * If you wish to re-use an existing key, call the `remove` method first, then this method. + * + * @method Phaser.Animations.AnimationState#create + * @since 3.50.0 + * + * @param {Phaser.Types.Animations.Animation} config - The configuration settings for the Animation. + * + * @return {(Phaser.Animations.Animation|false)} The Animation that was created, or `false` if the key is already in use. + */ + create: function (config) + { + var key = config.key; -/** - * Builds a Game Object using the provided configuration object. - * - * @function Phaser.GameObjects.BuildGameObject - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - A reference to the Scene. - * @param {Phaser.GameObjects.GameObject} gameObject - The initial GameObject. - * @param {Phaser.Types.GameObjects.GameObjectConfig} config - The config to build the GameObject with. - * - * @return {Phaser.GameObjects.GameObject} The built Game Object. - */ -var BuildGameObject = function (scene, gameObject, config) -{ - // Position + var anim = false; - gameObject.x = GetAdvancedValue(config, 'x', 0); - gameObject.y = GetAdvancedValue(config, 'y', 0); - gameObject.depth = GetAdvancedValue(config, 'depth', 0); + if (key) + { + anim = this.get(key); - // Flip + if (!anim) + { + anim = new Animation(this, key, config); - gameObject.flipX = GetAdvancedValue(config, 'flipX', false); - gameObject.flipY = GetAdvancedValue(config, 'flipY', false); + if (!this.anims) + { + this.anims = new CustomMap(); + } - // Scale - // Either: { scale: 2 } or { scale: { x: 2, y: 2 }} + this.anims.set(key, anim); + } + else + { + console.warn('Animation key already exists: ' + key); + } + } - var scale = GetAdvancedValue(config, 'scale', null); + return anim; + }, - if (typeof scale === 'number') - { - gameObject.setScale(scale); - } - else if (scale !== null) + /** + * Create one, or more animations from a loaded Aseprite JSON file. + * + * Aseprite is a powerful animated sprite editor and pixel art tool. + * + * You can find more details at https://www.aseprite.org/ + * + * To export a compatible JSON file in Aseprite, please do the following: + * + * 1. Go to "File - Export Sprite Sheet" + * + * 2. On the **Layout** tab: + * 2a. Set the "Sheet type" to "Packed" + * 2b. Set the "Constraints" to "None" + * 2c. Check the "Merge Duplicates" checkbox + * + * 3. On the **Sprite** tab: + * 3a. Set "Layers" to "Visible layers" + * 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags + * + * 4. On the **Borders** tab: + * 4a. Check the "Trim Sprite" and "Trim Cells" options + * 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough) + * + * 5. On the **Output** tab: + * 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type + * 5b. Check "JSON Data" and give your json file a name + * 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind. + * 5d. Make sure "Tags" is checked in the Meta options + * 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more. + * + * 6. Click export + * + * This was tested with Aseprite 1.2.25. + * + * This will export a png and json file which you can load using the Aseprite Loader, i.e.: + * + * ```javascript + * function preload () + * { + * this.load.path = 'assets/animations/aseprite/'; + * this.load.aseprite('paladin', 'paladin.png', 'paladin.json'); + * } + * ``` + * + * Once loaded, you can call this method on a Sprite with the 'atlas' key: + * + * ```javascript + * const sprite = this.add.sprite(400, 300); + * + * sprite.anims.createFromAseprite('paladin'); + * ``` + * + * Any animations defined in the JSON will now be available to use on this Sprite and you play them + * via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline, + * you can play it on the Sprite using that Tag name: + * + * ```javascript + * const sprite = this.add.sprite(400, 300); + * + * sprite.anims.createFromAseprite('paladin'); + * + * sprite.play('War Cry'); + * ``` + * + * When calling this method you can optionally provide an array of tag names, and only those animations + * will be created. For example: + * + * ```javascript + * sprite.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]); + * ``` + * + * This will only create the 3 animations defined. Note that the tag names are case-sensitive. + * + * @method Phaser.Animations.AnimationState#createFromAseprite + * @since 3.60.0 + * + * @param {string} key - The key of the loaded Aseprite atlas. It must have been loaded prior to calling this method. + * @param {string[]} [tags] - An array of Tag names. If provided, only animations found in this array will be created. + * + * @return {Phaser.Animations.Animation[]} An array of Animation instances that were successfully created. + */ + createFromAseprite: function (key, tags) { - gameObject.scaleX = GetAdvancedValue(scale, 'x', 1); - gameObject.scaleY = GetAdvancedValue(scale, 'y', 1); - } - - // ScrollFactor - // Either: { scrollFactor: 2 } or { scrollFactor: { x: 2, y: 2 }} + return this.animationManager.createFromAseprite(key, tags, this.parent); + }, - var scrollFactor = GetAdvancedValue(config, 'scrollFactor', null); + /** + * Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object. + * + * Generates objects with string based frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNames}. + * + * It's a helper method, designed to make it easier for you to extract all of the frame names from texture atlases. + * If you're working with a sprite sheet, see the `generateFrameNumbers` method instead. + * + * Example: + * + * If you have a texture atlases loaded called `gems` and it contains 6 frames called `ruby_0001`, `ruby_0002`, and so on, + * then you can call this method using: `this.anims.generateFrameNames('gems', { prefix: 'ruby_', end: 6, zeroPad: 4 })`. + * + * The `end` value tells it to look for 6 frames, incrementally numbered, all starting with the prefix `ruby_`. The `zeroPad` + * value tells it how many zeroes pad out the numbers. To create an animation using this method, you can do: + * + * ```javascript + * this.anims.create({ + * key: 'ruby', + * repeat: -1, + * frames: this.anims.generateFrameNames('gems', { + * prefix: 'ruby_', + * end: 6, + * zeroPad: 4 + * }) + * }); + * ``` + * + * Please see the animation examples for further details. + * + * @method Phaser.Animations.AnimationState#generateFrameNames + * @since 3.50.0 + * + * @param {string} key - The key for the texture containing the animation frames. + * @param {Phaser.Types.Animations.GenerateFrameNames} [config] - The configuration object for the animation frame names. + * + * @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects. + */ + generateFrameNames: function (key, config) + { + return this.animationManager.generateFrameNames(key, config); + }, - if (typeof scrollFactor === 'number') + /** + * Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object. + * + * Generates objects with numbered frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNumbers}. + * + * If you're working with a texture atlas, see the `generateFrameNames` method instead. + * + * It's a helper method, designed to make it easier for you to extract frames from sprite sheets. + * If you're working with a texture atlas, see the `generateFrameNames` method instead. + * + * Example: + * + * If you have a sprite sheet loaded called `explosion` and it contains 12 frames, then you can call this method using: + * `this.anims.generateFrameNumbers('explosion', { start: 0, end: 11 })`. + * + * The `end` value tells it to stop after 12 frames. To create an animation using this method, you can do: + * + * ```javascript + * this.anims.create({ + * key: 'boom', + * frames: this.anims.generateFrameNumbers('explosion', { + * start: 0, + * end: 11 + * }) + * }); + * ``` + * + * Note that `start` is optional and you don't need to include it if the animation starts from frame 0. + * + * To specify an animation in reverse, swap the `start` and `end` values. + * + * If the frames are not sequential, you may pass an array of frame numbers instead, for example: + * + * `this.anims.generateFrameNumbers('explosion', { frames: [ 0, 1, 2, 1, 2, 3, 4, 0, 1, 2 ] })` + * + * Please see the animation examples and `GenerateFrameNumbers` config docs for further details. + * + * @method Phaser.Animations.AnimationState#generateFrameNumbers + * @since 3.50.0 + * + * @param {string} key - The key for the texture containing the animation frames. + * @param {Phaser.Types.Animations.GenerateFrameNumbers} [config] - The configuration object for the animation frames. + * + * @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects. + */ + generateFrameNumbers: function (key, config) { - gameObject.setScrollFactor(scrollFactor); - } - else if (scrollFactor !== null) + return this.animationManager.generateFrameNumbers(key, config); + }, + + /** + * Removes a locally created Animation from this Sprite, based on the given key. + * + * Once an Animation has been removed, this Sprite cannot play it again without re-creating it. + * + * @method Phaser.Animations.AnimationState#remove + * @since 3.50.0 + * + * @param {string} key - The key of the animation to remove. + * + * @return {Phaser.Animations.Animation} The Animation instance that was removed from this Sprite, if the key was valid. + */ + remove: function (key) { - gameObject.scrollFactorX = GetAdvancedValue(scrollFactor, 'x', 1); - gameObject.scrollFactorY = GetAdvancedValue(scrollFactor, 'y', 1); - } + var anim = this.get(key); - // Rotation + if (anim) + { + if (this.currentAnim === anim) + { + this.stop(); + } - gameObject.rotation = GetAdvancedValue(config, 'rotation', 0); + this.anims.delete(key); + } - var angle = GetAdvancedValue(config, 'angle', null); + return anim; + }, - if (angle !== null) + /** + * Destroy this Animation component. + * + * Unregisters event listeners and cleans up its references. + * + * @method Phaser.Animations.AnimationState#destroy + * @since 3.0.0 + */ + destroy: function () { - gameObject.angle = angle; - } + this.animationManager.off(Events.REMOVE_ANIMATION, this.globalRemove, this); - // Alpha + if (this.anims) + { + this.anims.clear(); + } - gameObject.alpha = GetAdvancedValue(config, 'alpha', 1); + this.animationManager = null; + this.parent = null; + this.nextAnim = null; + this.nextAnimsQueue.length = 0; - // Origin - // Either: { origin: 0.5 } or { origin: { x: 0.5, y: 0.5 }} + this.currentAnim = null; + this.currentFrame = null; + }, - var origin = GetAdvancedValue(config, 'origin', null); + /** + * `true` if the current animation is paused, otherwise `false`. + * + * @name Phaser.Animations.AnimationState#isPaused + * @readonly + * @type {boolean} + * @since 3.4.0 + */ + isPaused: { - if (typeof origin === 'number') - { - gameObject.setOrigin(origin); - } - else if (origin !== null) - { - var ox = GetAdvancedValue(origin, 'x', 0.5); - var oy = GetAdvancedValue(origin, 'y', 0.5); + get: function () + { + return this._paused; + } - gameObject.setOrigin(ox, oy); } - // BlendMode - - gameObject.blendMode = GetAdvancedValue(config, 'blendMode', BlendModes.NORMAL); - - // Visible - - gameObject.visible = GetAdvancedValue(config, 'visible', true); +}); - // Add to Scene +module.exports = AnimationState; - var add = GetAdvancedValue(config, 'add', true); - if (add) - { - scene.sys.displayList.add(gameObject); - } +/***/ }), - if (gameObject.preUpdate) - { - scene.sys.updateList.add(gameObject); - } +/***/ 44509: +/***/ ((module) => { - return gameObject; -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = BuildGameObject; +/** + * The Add Animation Event. + * + * This event is dispatched when a new animation is added to the global Animation Manager. + * + * This can happen either as a result of an animation instance being added to the Animation Manager, + * or the Animation Manager creating a new animation directly. + * + * @event Phaser.Animations.Events#ADD_ANIMATION + * @type {string} + * @since 3.0.0 + * + * @param {string} key - The key of the Animation that was added to the global Animation Manager. + * @param {Phaser.Animations.Animation} animation - An instance of the newly created Animation. + */ +module.exports = 'add'; /***/ }), -/* 29 */ -/***/ (function(module, exports) { + +/***/ 84563: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Phaser Tilemap constants for orientation. - * - * @namespace Phaser.Tilemaps.Orientation - * @memberof Phaser.Tilemaps - * @since 3.50.0 - */ - -/** - * Phaser Tilemap constants for orientation. - * - * To find out what each mode does please see [Phaser.Tilemaps.Orientation]{@link Phaser.Tilemaps.Orientation}. - * - * @typedef {Phaser.Tilemaps.Orientation} Phaser.Tilemaps.OrientationType - * @memberof Phaser.Tilemaps + * The Animation Complete Event. + * + * This event is dispatched by a Sprite when an animation playing on it completes playback. + * This happens when the animation gets to the end of its sequence, factoring in any delays + * or repeats it may have to process. + * + * An animation that is set to loop, or repeat forever, will never fire this event, because + * it never actually completes. If you need to handle this, listen for the `ANIMATION_STOP` + * event instead, as this is emitted when the animation is stopped directly. + * + * Listen for it on the Sprite using `sprite.on('animationcomplete', listener)` + * + * The animation event flow is as follows: + * + * 1. `ANIMATION_START` + * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) + * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) + * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) + * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) + * + * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. + * + * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. + * + * @event Phaser.Animations.Events#ANIMATION_COMPLETE + * @type {string} * @since 3.50.0 + * + * @param {Phaser.Animations.Animation} animation - A reference to the Animation that completed. + * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. + * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation updated. + * @param {string} frameKey - The unique key of the Animation Frame within the Animation. */ +module.exports = 'animationcomplete'; -module.exports = { - - /** - * Orthogonal Tilemap orientation constant. - * - * @name Phaser.Tilemaps.Orientation.ORTHOGONAL - * @type {number} - * @const - * @since 3.50.0 - */ - ORTHOGONAL: 0, - /** - * Isometric Tilemap orientation constant. - * - * @name Phaser.Tilemaps.Orientation.ISOMETRIC - * @type {number} - * @const - * @since 3.50.0 - */ - ISOMETRIC: 1, +/***/ }), - /** - * Staggered Tilemap orientation constant. - * - * @name Phaser.Tilemaps.Orientation.STAGGERED - * @type {number} - * @const - * @since 3.50.0 - */ - STAGGERED: 2, +/***/ 61586: +/***/ ((module) => { - /** - * Hexagonal Tilemap orientation constant. - * - * @name Phaser.Tilemaps.Orientation.HEXAGONAL - * @type {number} - * @const - * @since 3.50.0 - */ - HEXAGONAL: 3 +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -}; +/** + * The Animation Complete Dynamic Key Event. + * + * This event is dispatched by a Sprite when an animation playing on it completes playback. + * This happens when the animation gets to the end of its sequence, factoring in any delays + * or repeats it may have to process. + * + * An animation that is set to loop, or repeat forever, will never fire this event, because + * it never actually completes. If you need to handle this, listen for the `ANIMATION_STOP` + * event instead, as this is emitted when the animation is stopped directly. + * + * The difference between this and the `ANIMATION_COMPLETE` event is that this one has a + * dynamic event name that contains the name of the animation within it. For example, + * if you had an animation called `explode` you could listen for the completion of that + * specific animation by using: `sprite.on('animationcomplete-explode', listener)`. Or, if you + * wish to use types: `sprite.on(Phaser.Animations.Events.ANIMATION_COMPLETE_KEY + 'explode', listener)`. + * + * The animation event flow is as follows: + * + * 1. `ANIMATION_START` + * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) + * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) + * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) + * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) + * + * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. + * + * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. + * + * @event Phaser.Animations.Events#ANIMATION_COMPLETE_KEY + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.Animations.Animation} animation - A reference to the Animation that completed. + * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. + * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation updated. + * @param {string} frameKey - The unique key of the Animation Frame within the Animation. + */ +module.exports = 'animationcomplete-'; /***/ }), -/* 30 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72175: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -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 - * and then performs the following steps: + * The Animation Repeat Event. * - * 1. Checks the alpha of the source combined with the Camera alpha. If 0 or less it aborts. - * 2. Takes the Camera and Game Object matrix and multiplies them, combined with the parent matrix if given. - * 3. Sets the blend mode of the context to be that used by the Game Object. - * 4. Sets the alpha value of the context to be that used by the Game Object combined with the Camera. - * 5. Saves the context state. - * 6. Sets the final matrix values into the context via setTransform. - * 7. If Renderer.antialias, or the frame.source.scaleMode is set, then imageSmoothingEnabled is set. + * This event is dispatched by a Sprite when an animation repeats playing on it. + * This happens if the animation was created, or played, with a `repeat` value specified. * - * This function is only meant to be used internally. Most of the Canvas Renderer classes use it. + * An animation will repeat when it reaches the end of its sequence. * - * @function Phaser.Renderer.Canvas.SetTransform - * @since 3.12.0 + * Listen for it on the Sprite using `sprite.on('animationrepeat', listener)` * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {CanvasRenderingContext2D} ctx - The canvas context to set the transform on. - * @param {Phaser.GameObjects.GameObject} src - The Game Object being rendered. Can be any type that extends the base class. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. - * @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - A parent transform matrix to apply to the Game Object before rendering. + * The animation event flow is as follows: * - * @return {boolean} `true` if the Game Object context was set, otherwise `false`. + * 1. `ANIMATION_START` + * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) + * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) + * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) + * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) + * + * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. + * + * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. + * + * @event Phaser.Animations.Events#ANIMATION_REPEAT + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has repeated. + * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. + * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation repeated. + * @param {string} frameKey - The unique key of the Animation Frame within the Animation. */ -var SetTransform = function (renderer, ctx, src, camera, parentMatrix) -{ - var alpha = camera.alpha * src.alpha; - - if (alpha <= 0) - { - // Nothing to see, so don't waste time calculating stuff - return false; - } - - var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; - - // Blend Mode - ctx.globalCompositeOperation = renderer.blendModes[src.blendMode]; - - // Alpha - ctx.globalAlpha = alpha; +module.exports = 'animationrepeat'; - ctx.save(); - calcMatrix.setToContext(ctx); +/***/ }), - ctx.imageSmoothingEnabled = !(!renderer.antialias || (src.frame && src.frame.source.scaleMode)); +/***/ 568: +/***/ ((module) => { - return true; -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = SetTransform; +/** + * The Animation Restart Event. + * + * This event is dispatched by a Sprite when an animation restarts playing on it. + * This only happens when the `Sprite.anims.restart` method is called. + * + * Listen for it on the Sprite using `sprite.on('animationrestart', listener)` + * + * The animation event flow is as follows: + * + * 1. `ANIMATION_START` + * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) + * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) + * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) + * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) + * + * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. + * + * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. + * + * @event Phaser.Animations.Events#ANIMATION_RESTART + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has restarted. + * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. + * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation restarted. + * @param {string} frameKey - The unique key of the Animation Frame within the Animation. + */ +module.exports = 'animationrestart'; /***/ }), -/* 31 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 37690: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(33); -var Smoothing = __webpack_require__(192); - -// The pool into which the canvas elements are placed. -var pool = []; - -// Automatically apply smoothing(false) to created Canvas elements -var _disableContextSmoothing = false; - /** - * The CanvasPool is a global static object, that allows Phaser to recycle and pool 2D Context Canvas DOM elements. - * It does not pool WebGL Contexts, because once the context options are set they cannot be modified again, - * which is useless for some of the Phaser pipelines / renderer. + * The Animation Start Event. * - * This singleton is instantiated as soon as Phaser loads, before a Phaser.Game instance has even been created. - * Which means all instances of Phaser Games on the same page can share the one single pool. + * This event is dispatched by a Sprite when an animation starts playing on it. + * This happens when the animation is played, factoring in any delay that may have been specified. + * This event happens after the delay has expired and prior to the first update event. * - * @namespace Phaser.Display.Canvas.CanvasPool + * Listen for it on the Sprite using `sprite.on('animationstart', listener)` + * + * The animation event flow is as follows: + * + * 1. `ANIMATION_START` + * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) + * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) + * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) + * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) + * + * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. + * + * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. + * + * @event Phaser.Animations.Events#ANIMATION_START + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has started. + * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. + * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation started. + * @param {string} frameKey - The unique key of the Animation Frame within the Animation. + */ +module.exports = 'animationstart'; + + +/***/ }), + +/***/ 58525: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Animation Stop Event. + * + * This event is dispatched by a Sprite when an animation is stopped on it. An animation + * will only be stopeed if a method such as `Sprite.stop` or `Sprite.anims.stopAfterDelay` + * is called. It can also be emitted if a new animation is started before the current one completes. + * + * Listen for it on the Sprite using `sprite.on('animationstop', listener)` + * + * The animation event flow is as follows: + * + * 1. `ANIMATION_START` + * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) + * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) + * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) + * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) + * + * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. + * + * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. + * + * @event Phaser.Animations.Events#ANIMATION_STOP + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has stopped. + * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. + * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation stopped. + * @param {string} frameKey - The unique key of the Animation Frame within the Animation. + */ +module.exports = 'animationstop'; + + +/***/ }), + +/***/ 5243: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Animation Update Event. + * + * This event is dispatched by a Sprite when an animation playing on it updates. This happens when the animation changes frame. + * An animation will change frame based on the frame rate and other factors like `timeScale` and `delay`. It can also change + * frame when stopped or restarted. + * + * Listen for it on the Sprite using `sprite.on('animationupdate', listener)` + * + * If an animation is playing faster than the game frame-rate can handle, it's entirely possible for it to emit several + * update events in a single game frame, so please be aware of this in your code. The **final** event received that frame + * is the one that is rendered to the game. + * + * The animation event flow is as follows: + * + * 1. `ANIMATION_START` + * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) + * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) + * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) + * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) + * + * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. + * + * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. + * + * @event Phaser.Animations.Events#ANIMATION_UPDATE + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has updated. + * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. + * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation updated. + * @param {string} frameKey - The unique key of the Animation Frame within the Animation. + */ +module.exports = 'animationupdate'; + + +/***/ }), + +/***/ 10598: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Pause All Animations Event. + * + * This event is dispatched when the global Animation Manager is told to pause. + * + * When this happens all current animations will stop updating, although it doesn't necessarily mean + * that the game has paused as well. + * + * @event Phaser.Animations.Events#PAUSE_ALL + * @type {string} * @since 3.0.0 */ -var CanvasPool = function () -{ - /** - * Creates a new Canvas DOM element, or pulls one from the pool if free. - * - * @function Phaser.Display.Canvas.CanvasPool.create - * @since 3.0.0 - * - * @param {*} parent - The parent of the Canvas object. - * @param {number} [width=1] - The width of the Canvas. - * @param {number} [height=1] - The height of the Canvas. - * @param {number} [canvasType=Phaser.CANVAS] - The type of the Canvas. Either `Phaser.CANVAS` or `Phaser.WEBGL`. - * @param {boolean} [selfParent=false] - Use the generated Canvas element as the parent? - * - * @return {HTMLCanvasElement} The canvas element that was created or pulled from the pool - */ - var create = function (parent, width, height, canvasType, selfParent) - { - if (width === undefined) { width = 1; } - if (height === undefined) { height = 1; } - if (canvasType === undefined) { canvasType = CONST.CANVAS; } - if (selfParent === undefined) { selfParent = false; } +module.exports = 'pauseall'; - var canvas; - var container = first(canvasType); - if (container === null) - { - container = { - parent: parent, - canvas: document.createElement('canvas'), - type: canvasType - }; +/***/ }), - if (canvasType === CONST.CANVAS) - { - pool.push(container); - } +/***/ 4860: +/***/ ((module) => { - canvas = container.canvas; - } - else - { - container.parent = parent; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - canvas = container.canvas; - } +/** + * The Remove Animation Event. + * + * This event is dispatched when an animation is removed from the global Animation Manager. + * + * @event Phaser.Animations.Events#REMOVE_ANIMATION + * @type {string} + * @since 3.0.0 + * + * @param {string} key - The key of the Animation that was removed from the global Animation Manager. + * @param {Phaser.Animations.Animation} animation - An instance of the removed Animation. + */ +module.exports = 'remove'; - if (selfParent) - { - container.parent = canvas; - } - canvas.width = width; - canvas.height = height; +/***/ }), - if (_disableContextSmoothing && canvasType === CONST.CANVAS) - { - Smoothing.disable(canvas.getContext('2d')); - } +/***/ 31865: +/***/ ((module) => { - return canvas; - }; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Resume All Animations Event. + * + * This event is dispatched when the global Animation Manager resumes, having been previously paused. + * + * When this happens all current animations will continue updating again. + * + * @event Phaser.Animations.Events#RESUME_ALL + * @type {string} + * @since 3.0.0 + */ +module.exports = 'resumeall'; + + +/***/ }), + +/***/ 16938: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Animations.Events + */ + +module.exports = { + + ADD_ANIMATION: __webpack_require__(44509), + ANIMATION_COMPLETE: __webpack_require__(84563), + ANIMATION_COMPLETE_KEY: __webpack_require__(61586), + ANIMATION_REPEAT: __webpack_require__(72175), + ANIMATION_RESTART: __webpack_require__(568), + ANIMATION_START: __webpack_require__(37690), + ANIMATION_STOP: __webpack_require__(58525), + ANIMATION_UPDATE: __webpack_require__(5243), + PAUSE_ALL: __webpack_require__(10598), + REMOVE_ANIMATION: __webpack_require__(4860), + RESUME_ALL: __webpack_require__(31865) + +}; + + +/***/ }), + +/***/ 13517: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Animations + */ + +module.exports = { + + Animation: __webpack_require__(85463), + AnimationFrame: __webpack_require__(71519), + AnimationManager: __webpack_require__(90249), + AnimationState: __webpack_require__(16569), + Events: __webpack_require__(16938) + +}; + + +/***/ }), + +/***/ 23740: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CustomMap = __webpack_require__(33885); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(69773); + +/** + * @classdesc + * The BaseCache is a base Cache class that can be used for storing references to any kind of data. + * + * Data can be added, retrieved and removed based on the given keys. + * + * Keys are string-based. + * + * @class BaseCache + * @memberof Phaser.Cache + * @constructor + * @since 3.0.0 + */ +var BaseCache = new Class({ + + initialize: + + function BaseCache () + { + /** + * The Map in which the cache objects are stored. + * + * You can query the Map directly or use the BaseCache methods. + * + * @name Phaser.Cache.BaseCache#entries + * @type {Phaser.Structs.Map.} + * @since 3.0.0 + */ + this.entries = new CustomMap(); + + /** + * An instance of EventEmitter used by the cache to emit related events. + * + * @name Phaser.Cache.BaseCache#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events = new EventEmitter(); + }, /** - * Creates a new Canvas DOM element, or pulls one from the pool if free. + * Adds an item to this cache. The item is referenced by a unique string, which you are responsible + * for setting and keeping track of. The item can only be retrieved by using this string. * - * @function Phaser.Display.Canvas.CanvasPool.create2D + * @method Phaser.Cache.BaseCache#add + * @fires Phaser.Cache.Events#ADD * @since 3.0.0 * - * @param {*} parent - The parent of the Canvas object. - * @param {number} [width=1] - The width of the Canvas. - * @param {number} [height=1] - The height of the Canvas. + * @param {string} key - The unique key by which the data added to the cache will be referenced. + * @param {*} data - The data to be stored in the cache. * - * @return {HTMLCanvasElement} The created canvas. + * @return {this} This BaseCache object. */ - var create2D = function (parent, width, height) + add: function (key, data) { - return create(parent, width, height, CONST.CANVAS); - }; + this.entries.set(key, data); + + this.events.emit(Events.ADD, this, key, data); + + return this; + }, /** - * Creates a new Canvas DOM element, or pulls one from the pool if free. + * Checks if this cache contains an item matching the given key. + * This performs the same action as `BaseCache.exists`. * - * @function Phaser.Display.Canvas.CanvasPool.createWebGL + * @method Phaser.Cache.BaseCache#has * @since 3.0.0 * - * @param {*} parent - The parent of the Canvas object. - * @param {number} [width=1] - The width of the Canvas. - * @param {number} [height=1] - The height of the Canvas. + * @param {string} key - The unique key of the item to be checked in this cache. * - * @return {HTMLCanvasElement} The created WebGL canvas. + * @return {boolean} Returns `true` if the cache contains an item matching the given key, otherwise `false`. */ - var createWebGL = function (parent, width, height) + has: function (key) { - return create(parent, width, height, CONST.WEBGL); - }; + return this.entries.has(key); + }, /** - * Gets the first free canvas index from the pool. + * Checks if this cache contains an item matching the given key. + * This performs the same action as `BaseCache.has` and is called directly by the Loader. * - * @function Phaser.Display.Canvas.CanvasPool.first - * @since 3.0.0 + * @method Phaser.Cache.BaseCache#exists + * @since 3.7.0 * - * @param {number} [canvasType=Phaser.CANVAS] - The type of the Canvas. Either `Phaser.CANVAS` or `Phaser.WEBGL`. + * @param {string} key - The unique key of the item to be checked in this cache. * - * @return {HTMLCanvasElement} The first free canvas, or `null` if a WebGL canvas was requested or if the pool doesn't have free canvases. + * @return {boolean} Returns `true` if the cache contains an item matching the given key, otherwise `false`. */ - var first = function (canvasType) + exists: function (key) { - if (canvasType === undefined) { canvasType = CONST.CANVAS; } - - if (canvasType === CONST.WEBGL) - { - return null; - } - - for (var i = 0; i < pool.length; i++) - { - var container = pool[i]; - - if (!container.parent && container.type === canvasType) - { - return container; - } - } - - return null; - }; + return this.entries.has(key); + }, /** - * Looks up a canvas based on its parent, and if found puts it back in the pool, freeing it up for re-use. - * The canvas has its width and height set to 1, and its parent attribute nulled. + * Gets an item from this cache based on the given key. * - * @function Phaser.Display.Canvas.CanvasPool.remove + * @method Phaser.Cache.BaseCache#get * @since 3.0.0 * - * @param {*} parent - The canvas or the parent of the canvas to free. + * @param {string} key - The unique key of the item to be retrieved from this cache. + * + * @return {*} The item in the cache, or `null` if no item matching the given key was found. */ - var remove = function (parent) + get: function (key) { - // Check to see if the parent is a canvas object - var isCanvas = parent instanceof HTMLCanvasElement; - - pool.forEach(function (container) - { - if ((isCanvas && container.canvas === parent) || (!isCanvas && container.parent === parent)) - { - container.parent = null; - container.canvas.width = 1; - container.canvas.height = 1; - } - }); - }; + return this.entries.get(key); + }, /** - * Gets the total number of used canvas elements in the pool. + * Removes and item from this cache based on the given key. * - * @function Phaser.Display.Canvas.CanvasPool.total + * If an entry matching the key is found it is removed from the cache and a `remove` event emitted. + * No additional checks are done on the item removed. If other systems or parts of your game code + * are relying on this item, it is up to you to sever those relationships prior to removing the item. + * + * @method Phaser.Cache.BaseCache#remove + * @fires Phaser.Cache.Events#REMOVE * @since 3.0.0 * - * @return {number} The number of used canvases. + * @param {string} key - The unique key of the item to remove from the cache. + * + * @return {this} This BaseCache object. */ - var total = function () + remove: function (key) { - var c = 0; + var entry = this.get(key); - pool.forEach(function (container) + if (entry) { - if (container.parent) - { - c++; - } - }); + this.entries.delete(key); - return c; - }; + this.events.emit(Events.REMOVE, this, key, entry.data); + } + + return this; + }, /** - * Gets the total number of free canvas elements in the pool. + * Returns all keys in use in this cache. * - * @function Phaser.Display.Canvas.CanvasPool.free - * @since 3.0.0 + * @method Phaser.Cache.BaseCache#getKeys + * @since 3.17.0 * - * @return {number} The number of free canvases. + * @return {string[]} Array containing all the keys. */ - var free = function () + getKeys: function () { - return pool.length - total(); - }; + return this.entries.keys(); + }, /** - * Disable context smoothing on any new Canvas element created. + * Destroys this cache and all items within it. * - * @function Phaser.Display.Canvas.CanvasPool.disableSmoothing + * @method Phaser.Cache.BaseCache#destroy * @since 3.0.0 */ - var disableSmoothing = function () + destroy: function () { - _disableContextSmoothing = true; - }; + this.entries.clear(); + this.events.removeAllListeners(); - /** - * Enable context smoothing on any new Canvas element created. - * - * @function Phaser.Display.Canvas.CanvasPool.enableSmoothing - * @since 3.0.0 - */ - var enableSmoothing = function () - { - _disableContextSmoothing = false; - }; + this.entries = null; + this.events = null; + } - return { - create2D: create2D, - create: create, - createWebGL: createWebGL, - disableSmoothing: disableSmoothing, - enableSmoothing: enableSmoothing, - first: first, - free: free, - pool: pool, - remove: remove, - total: total - }; -}; +}); -// If we export the called function here, it'll only be invoked once (not every time it's required). -module.exports = CanvasPool(); +module.exports = BaseCache; /***/ }), -/* 32 */ -/***/ (function(module, exports) { + +/***/ 43474: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** -* The `Matter.Common` module contains utility functions that are common to all modules. -* -* @class Common -*/ + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -var Common = {}; +var BaseCache = __webpack_require__(23740); +var Class = __webpack_require__(56694); +var GameEvents = __webpack_require__(97081); -module.exports = Common; +/** + * @classdesc + * The Cache Manager is the global cache owned and maintained by the Game instance. + * + * Various systems, such as the file Loader, rely on this cache in order to store the files + * it has loaded. The manager itself doesn't store any files, but instead owns multiple BaseCache + * instances, one per type of file. You can also add your own custom caches. + * + * @class CacheManager + * @memberof Phaser.Cache + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Game} game - A reference to the Phaser.Game instance that owns this CacheManager. + */ +var CacheManager = new Class({ -(function() { + initialize: - Common._nextId = 0; - Common._seed = 0; - Common._nowStartTime = +(new Date()); + function CacheManager (game) + { + /** + * A reference to the Phaser.Game instance that owns this CacheManager. + * + * @name Phaser.Cache.CacheManager#game + * @type {Phaser.Game} + * @protected + * @since 3.0.0 + */ + this.game = game; - /** - * Extends the object in the first argument using the object in the second argument. - * @method extend - * @param {} obj - * @param {boolean} deep - * @return {} obj extended - */ - Common.extend = function(obj, deep) { - var argsStart, - args, - deepClone; + /** + * A Cache storing all binary files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#binary + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.binary = new BaseCache(); - if (typeof deep === 'boolean') { - argsStart = 2; - deepClone = deep; - } else { - argsStart = 1; - deepClone = true; - } + /** + * A Cache storing all bitmap font data files, typically added via the Loader. + * Only the font data is stored in this cache, the textures are part of the Texture Manager. + * + * @name Phaser.Cache.CacheManager#bitmapFont + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.bitmapFont = new BaseCache(); - for (var i = argsStart; i < arguments.length; i++) { - var source = arguments[i]; + /** + * A Cache storing all JSON data files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#json + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.json = new BaseCache(); - if (source) { - for (var prop in source) { - if (deepClone && source[prop] && source[prop].constructor === Object) { - if (!obj[prop] || obj[prop].constructor === Object) { - obj[prop] = obj[prop] || {}; - Common.extend(obj[prop], deepClone, source[prop]); - } else { - obj[prop] = source[prop]; - } - } else { - obj[prop] = source[prop]; - } - } - } - } - - return obj; - }; + /** + * A Cache storing all physics data files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#physics + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.physics = new BaseCache(); - /** - * Creates a new clone of the object, if deep is true references will also be cloned. - * @method clone - * @param {} obj - * @param {bool} deep - * @return {} obj cloned - */ - Common.clone = function(obj, deep) { - return Common.extend({}, deep, obj); - }; + /** + * A Cache storing all shader source files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#shader + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.shader = new BaseCache(); - /** - * Returns the list of keys for the given object. - * @method keys - * @param {} obj - * @return {string[]} keys - */ - Common.keys = function(obj) { - if (Object.keys) - return Object.keys(obj); + /** + * A Cache storing all non-streaming audio files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#audio + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.audio = new BaseCache(); - // avoid hasOwnProperty for performance - var keys = []; - for (var key in obj) - keys.push(key); - return keys; - }; + /** + * A Cache storing all non-streaming video files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#video + * @type {Phaser.Cache.BaseCache} + * @since 3.20.0 + */ + this.video = new BaseCache(); - /** - * Returns the list of values for the given object. - * @method values - * @param {} obj - * @return {array} Array of the objects property values - */ - Common.values = function(obj) { - var values = []; - - if (Object.keys) { - var keys = Object.keys(obj); - for (var i = 0; i < keys.length; i++) { - values.push(obj[keys[i]]); - } - return values; - } - - // avoid hasOwnProperty for performance - for (var key in obj) - values.push(obj[key]); - return values; - }; + /** + * A Cache storing all text files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#text + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.text = new BaseCache(); - /** - * Gets a value from `base` relative to the `path` string. - * @method get - * @param {} obj The base object - * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz' - * @param {number} [begin] Path slice begin - * @param {number} [end] Path slice end - * @return {} The object at the given path - */ - Common.get = function(obj, path, begin, end) { - path = path.split('.').slice(begin, end); + /** + * A Cache storing all html files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#html + * @type {Phaser.Cache.BaseCache} + * @since 3.12.0 + */ + this.html = new BaseCache(); - for (var i = 0; i < path.length; i += 1) { - obj = obj[path[i]]; - } + /** + * A Cache storing all WaveFront OBJ files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#obj + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.obj = new BaseCache(); - return obj; - }; + /** + * A Cache storing all tilemap data files, typically added via the Loader. + * Only the data is stored in this cache, the textures are part of the Texture Manager. + * + * @name Phaser.Cache.CacheManager#tilemap + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.tilemap = new BaseCache(); - /** - * Sets a value on `base` relative to the given `path` string. - * @method set - * @param {} obj The base object - * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz' - * @param {} val The value to set - * @param {number} [begin] Path slice begin - * @param {number} [end] Path slice end - * @return {} Pass through `val` for chaining - */ - Common.set = function(obj, path, val, begin, end) { - var parts = path.split('.').slice(begin, end); - Common.get(obj, path, 0, -1)[parts[parts.length - 1]] = val; - return val; - }; + /** + * A Cache storing all xml data files, typically added via the Loader. + * + * @name Phaser.Cache.CacheManager#xml + * @type {Phaser.Cache.BaseCache} + * @since 3.0.0 + */ + this.xml = new BaseCache(); - /** - * Shuffles the given array in-place. - * The function uses a seeded random generator. - * @method shuffle - * @param {array} array - * @return {array} array shuffled randomly - */ - Common.shuffle = function(array) { - for (var i = array.length - 1; i > 0; i--) { - var j = Math.floor(Common.random() * (i + 1)); - var temp = array[i]; - array[i] = array[j]; - array[j] = temp; - } - return array; - }; + /** + * An object that contains your own custom BaseCache entries. + * Add to this via the `addCustom` method. + * + * @name Phaser.Cache.CacheManager#custom + * @type {Object.} + * @since 3.0.0 + */ + this.custom = {}; - /** - * Randomly chooses a value from a list with equal probability. - * The function uses a seeded random generator. - * @method choose - * @param {array} choices - * @return {object} A random choice object from the array - */ - Common.choose = function(choices) { - return choices[Math.floor(Common.random() * choices.length)]; - }; + this.game.events.once(GameEvents.DESTROY, this.destroy, this); + }, /** - * Returns true if the object is a HTMLElement, otherwise false. - * @method isElement - * @param {object} obj - * @return {boolean} True if the object is a HTMLElement, otherwise false + * Add your own custom Cache for storing your own files. + * The cache will be available under `Cache.custom.key`. + * The cache will only be created if the key is not already in use. + * + * @method Phaser.Cache.CacheManager#addCustom + * @since 3.0.0 + * + * @param {string} key - The unique key of your custom cache. + * + * @return {Phaser.Cache.BaseCache} A reference to the BaseCache that was created. If the key was already in use, a reference to the existing cache is returned instead. */ - Common.isElement = function(obj) { - if (typeof HTMLElement !== 'undefined') { - return obj instanceof HTMLElement; + addCustom: function (key) + { + if (!this.custom.hasOwnProperty(key)) + { + this.custom[key] = new BaseCache(); } - return !!(obj && obj.nodeType && obj.nodeName); - }; - - /** - * Returns true if the object is an array. - * @method isArray - * @param {object} obj - * @return {boolean} True if the object is an array, otherwise false - */ - Common.isArray = function(obj) { - return Object.prototype.toString.call(obj) === '[object Array]'; - }; + return this.custom[key]; + }, /** - * Returns true if the object is a function. - * @method isFunction - * @param {object} obj - * @return {boolean} True if the object is a function, otherwise false + * Removes all entries from all BaseCaches and destroys all custom caches. + * + * @method Phaser.Cache.CacheManager#destroy + * @since 3.0.0 */ - Common.isFunction = function(obj) { - return typeof obj === "function"; - }; + destroy: function () + { + var keys = [ + 'binary', + 'bitmapFont', + 'json', + 'physics', + 'shader', + 'audio', + 'video', + 'text', + 'html', + 'obj', + 'tilemap', + 'xml' + ]; - /** - * Returns true if the object is a plain object. - * @method isPlainObject - * @param {object} obj - * @return {boolean} True if the object is a plain object, otherwise false - */ - Common.isPlainObject = function(obj) { - return typeof obj === 'object' && obj.constructor === Object; - }; + for (var i = 0; i < keys.length; i++) + { + this[keys[i]].destroy(); + this[keys[i]] = null; + } - /** - * Returns true if the object is a string. - * @method isString - * @param {object} obj - * @return {boolean} True if the object is a string, otherwise false - */ - Common.isString = function(obj) { - return Object.prototype.toString.call(obj) === '[object String]'; - }; - - /** - * Returns the given value clamped between a minimum and maximum value. - * @method clamp - * @param {number} value - * @param {number} min - * @param {number} max - * @return {number} The value clamped between min and max inclusive - */ - Common.clamp = function(value, min, max) { - if (value < min) - return min; - if (value > max) - return max; - return value; - }; - - /** - * Returns the sign of the given value. - * @method sign - * @param {number} value - * @return {number} -1 if negative, +1 if 0 or positive - */ - Common.sign = function(value) { - return value < 0 ? -1 : 1; - }; - - /** - * Returns the current timestamp since the time origin (e.g. from page load). - * The result will be high-resolution including decimal places if available. - * @method now - * @return {number} the current timestamp - */ - Common.now = function() { - if (typeof window !== 'undefined' && window.performance) { - if (window.performance.now) { - return window.performance.now(); - } else if (window.performance.webkitNow) { - return window.performance.webkitNow(); - } + for (var key in this.custom) + { + this.custom[key].destroy(); } - return (new Date()) - Common._nowStartTime; - }; - - /** - * Returns a random value between a minimum and a maximum value inclusive. - * The function uses a seeded random generator. - * @method random - * @param {number} min - * @param {number} max - * @return {number} A random number between min and max inclusive - */ - Common.random = function(min, max) { - min = (typeof min !== "undefined") ? min : 0; - max = (typeof max !== "undefined") ? max : 1; - return min + _seededRandom() * (max - min); - }; + this.custom = null; - var _seededRandom = function() { - // https://en.wikipedia.org/wiki/Linear_congruential_generator - Common._seed = (Common._seed * 9301 + 49297) % 233280; - return Common._seed / 233280; - }; + this.game = null; + } - /** - * Converts a CSS hex colour string into an integer. - * @method colorToNumber - * @param {string} colorString - * @return {number} An integer representing the CSS hex string - */ - Common.colorToNumber = function(colorString) { - colorString = colorString.replace('#',''); +}); - if (colorString.length == 3) { - colorString = colorString.charAt(0) + colorString.charAt(0) - + colorString.charAt(1) + colorString.charAt(1) - + colorString.charAt(2) + colorString.charAt(2); - } +module.exports = CacheManager; - return parseInt(colorString, 16); - }; - /** - * The console logging level to use, where each level includes all levels above and excludes the levels below. - * The default level is 'debug' which shows all console messages. - * - * Possible level values are: - * - 0 = None - * - 1 = Debug - * - 2 = Info - * - 3 = Warn - * - 4 = Error - * @property Common.logLevel - * @type {Number} - * @default 1 - */ - Common.logLevel = 1; +/***/ }), - /** - * Shows a `console.log` message only if the current `Common.logLevel` allows it. - * The message will be prefixed with 'matter-js' to make it easily identifiable. - * @method log - * @param ...objs {} The objects to log. - */ - Common.log = function() { - if (console && Common.logLevel > 0 && Common.logLevel <= 3) { - console.log.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments))); - } - }; +/***/ 94762: +/***/ ((module) => { - /** - * Shows a `console.info` message only if the current `Common.logLevel` allows it. - * The message will be prefixed with 'matter-js' to make it easily identifiable. - * @method info - * @param ...objs {} The objects to log. - */ - Common.info = function() { - if (console && Common.logLevel > 0 && Common.logLevel <= 2) { - console.info.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments))); - } - }; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Shows a `console.warn` message only if the current `Common.logLevel` allows it. - * The message will be prefixed with 'matter-js' to make it easily identifiable. - * @method warn - * @param ...objs {} The objects to log. - */ - Common.warn = function() { - if (console && Common.logLevel > 0 && Common.logLevel <= 3) { - console.warn.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments))); - } - }; - - /** - * Returns the next unique sequential ID. - * @method nextId - * @return {Number} Unique sequential ID - */ - Common.nextId = function() { - return Common._nextId++; - }; - - /** - * A cross browser compatible indexOf implementation. - * @method indexOf - * @param {array} haystack - * @param {object} needle - * @return {number} The position of needle in haystack, otherwise -1. - */ - Common.indexOf = function(haystack, needle) { - if (haystack.indexOf) - return haystack.indexOf(needle); - - for (var i = 0; i < haystack.length; i++) { - if (haystack[i] === needle) - return i; - } - - return -1; - }; - - /** - * A cross browser compatible array map implementation. - * @method map - * @param {array} list - * @param {function} func - * @return {array} Values from list transformed by func. - */ - Common.map = function(list, func) { - if (list.map) { - return list.map(func); - } - - var mapped = []; - - for (var i = 0; i < list.length; i += 1) { - mapped.push(func(list[i])); - } - - return mapped; - }; - - /** - * Takes a directed graph and returns the partially ordered set of vertices in topological order. - * Circular dependencies are allowed. - * @method topologicalSort - * @param {object} graph - * @return {array} Partially ordered set of vertices in topological order. - */ - Common.topologicalSort = function(graph) { - // https://github.com/mgechev/javascript-algorithms - // Copyright (c) Minko Gechev (MIT license) - // Modifications: tidy formatting and naming - var result = [], - visited = [], - temp = []; - - for (var node in graph) { - if (!visited[node] && !temp[node]) { - Common._topologicalSort(node, visited, temp, graph, result); - } - } - - return result; - }; - - Common._topologicalSort = function(node, visited, temp, graph, result) { - var neighbors = graph[node] || []; - temp[node] = true; - - for (var i = 0; i < neighbors.length; i += 1) { - var neighbor = neighbors[i]; - - if (temp[neighbor]) { - // skip circular dependencies - continue; - } - - if (!visited[neighbor]) { - Common._topologicalSort(neighbor, visited, temp, graph, result); - } - } - - temp[node] = false; - visited[node] = true; - - result.push(node); - }; - - /** - * Takes _n_ functions as arguments and returns a new function that calls them in order. - * The arguments applied when calling the new function will also be applied to every function passed. - * The value of `this` refers to the last value returned in the chain that was not `undefined`. - * Therefore if a passed function does not return a value, the previously returned value is maintained. - * After all passed functions have been called the new function returns the last returned value (if any). - * If any of the passed functions are a chain, then the chain will be flattened. - * @method chain - * @param ...funcs {function} The functions to chain. - * @return {function} A new function that calls the passed functions in order. - */ - Common.chain = function() { - var funcs = []; - - for (var i = 0; i < arguments.length; i += 1) { - var func = arguments[i]; - - if (func._chained) { - // flatten already chained functions - funcs.push.apply(funcs, func._chained); - } else { - funcs.push(func); - } - } - - var chain = function() { - // https://github.com/GoogleChrome/devtools-docs/issues/53#issuecomment-51941358 - var lastResult, - args = new Array(arguments.length); - - for (var i = 0, l = arguments.length; i < l; i++) { - args[i] = arguments[i]; - } - - for (i = 0; i < funcs.length; i += 1) { - var result = funcs[i].apply(lastResult, args); - - if (typeof result !== 'undefined') { - lastResult = result; - } - } - - return lastResult; - }; - - chain._chained = funcs; - - return chain; - }; - - /** - * Chains a function to excute before the original function on the given `path` relative to `base`. - * See also docs for `Common.chain`. - * @method chainPathBefore - * @param {} base The base object - * @param {string} path The path relative to `base` - * @param {function} func The function to chain before the original - * @return {function} The chained function that replaced the original - */ - Common.chainPathBefore = function(base, path, func) { - return Common.set(base, path, Common.chain( - func, - Common.get(base, path) - )); - }; - - /** - * Chains a function to excute after the original function on the given `path` relative to `base`. - * See also docs for `Common.chain`. - * @method chainPathAfter - * @param {} base The base object - * @param {string} path The path relative to `base` - * @param {function} func The function to chain after the original - * @return {function} The chained function that replaced the original - */ - Common.chainPathAfter = function(base, path, func) { - return Common.set(base, path, Common.chain( - Common.get(base, path), - func - )); - }; -})(); +/** + * The Cache Add Event. + * + * This event is dispatched by any Cache that extends the BaseCache each time a new object is added to it. + * + * @event Phaser.Cache.Events#ADD + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Cache.BaseCache} cache - The cache to which the object was added. + * @param {string} key - The key of the object added to the cache. + * @param {*} object - A reference to the object that was added to the cache. + */ +module.exports = 'add'; /***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 75968: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Global constants. + * The Cache Remove Event. * - * @ignore + * This event is dispatched by any Cache that extends the BaseCache each time an object is removed from it. + * + * @event Phaser.Cache.Events#REMOVE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Cache.BaseCache} cache - The cache from which the object was removed. + * @param {string} key - The key of the object removed from the cache. + * @param {*} object - A reference to the object that was removed from the cache. */ +module.exports = 'remove'; -var CONST = { - /** - * Phaser Release Version - * - * @name Phaser.VERSION - * @const - * @type {string} - * @since 3.0.0 - */ - VERSION: '3.55.2', +/***/ }), - BlendModes: __webpack_require__(35), +/***/ 69773: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - ScaleModes: __webpack_require__(168), +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * This setting will auto-detect if the browser is capable of suppporting WebGL. - * If it is, it will use the WebGL Renderer. If not, it will fall back to the Canvas Renderer. - * - * @name Phaser.AUTO - * @const - * @type {number} - * @since 3.0.0 - */ - AUTO: 0, +/** + * @namespace Phaser.Cache.Events + */ - /** - * Forces Phaser to only use the Canvas Renderer, regardless if the browser supports - * WebGL or not. - * - * @name Phaser.CANVAS - * @const - * @type {number} - * @since 3.0.0 - */ - CANVAS: 1, +module.exports = { - /** - * Forces Phaser to use the WebGL Renderer. If the browser does not support it, there is - * no fallback to Canvas with this setting, so you should trap it and display a suitable - * message to the user. - * - * @name Phaser.WEBGL - * @const - * @type {number} - * @since 3.0.0 - */ - WEBGL: 2, + ADD: __webpack_require__(94762), + REMOVE: __webpack_require__(75968) - /** - * A Headless Renderer doesn't create either a Canvas or WebGL Renderer. However, it still - * absolutely relies on the DOM being present and available. This mode is meant for unit testing, - * not for running Phaser on the server, which is something you really shouldn't do. - * - * @name Phaser.HEADLESS - * @const - * @type {number} - * @since 3.0.0 - */ - HEADLESS: 3, +}; - /** - * In Phaser the value -1 means 'forever' in lots of cases, this const allows you to use it instead - * to help you remember what the value is doing in your code. - * - * @name Phaser.FOREVER - * @const - * @type {number} - * @since 3.0.0 - */ - FOREVER: -1, - /** - * Direction constant. - * - * @name Phaser.NONE - * @const - * @type {number} - * @since 3.0.0 - */ - NONE: 4, +/***/ }), - /** - * Direction constant. - * - * @name Phaser.UP - * @const - * @type {number} - * @since 3.0.0 - */ - UP: 5, +/***/ 45820: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Direction constant. - * - * @name Phaser.DOWN - * @const - * @type {number} - * @since 3.0.0 - */ - DOWN: 6, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Direction constant. - * - * @name Phaser.LEFT - * @const - * @type {number} - * @since 3.0.0 - */ - LEFT: 7, +/** + * @namespace Phaser.Cache + */ - /** - * Direction constant. - * - * @name Phaser.RIGHT - * @const - * @type {number} - * @since 3.0.0 - */ - RIGHT: 8 +module.exports = { -}; + BaseCache: __webpack_require__(23740), + CacheManager: __webpack_require__(43474), + Events: __webpack_require__(69773) -module.exports = CONST; +}; /***/ }), -/* 34 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 51052: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 Line = __webpack_require__(47); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var DegToRad = __webpack_require__(75606); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(89787); +var Rectangle = __webpack_require__(74118); +var TransformMatrix = __webpack_require__(69360); +var ValueToColor = __webpack_require__(93222); +var Vector2 = __webpack_require__(93736); /** * @classdesc - * The Shape Game Object is a base class for the various different shapes, such as the Arc, Star or Polygon. - * You cannot add a Shape directly to your Scene, it is meant as a base for your own custom Shape classes. + * A Base Camera class. * - * @class Shape - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects + * The Camera is the way in which all games are rendered in Phaser. They provide a view into your game world, + * and can be positioned, rotated, zoomed and scrolled accordingly. + * + * A Camera consists of two elements: The viewport and the scroll values. + * + * The viewport is the physical position and size of the Camera within your game. Cameras, by default, are + * created the same size as your game, but their position and size can be set to anything. This means if you + * wanted to create a camera that was 320x200 in size, positioned in the bottom-right corner of your game, + * you'd adjust the viewport to do that (using methods like `setViewport` and `setSize`). + * + * If you wish to change where the Camera is looking in your game, then you scroll it. You can do this + * via the properties `scrollX` and `scrollY` or the method `setScroll`. Scrolling has no impact on the + * viewport, and changing the viewport has no impact on the scrolling. + * + * By default a Camera will render all Game Objects it can see. You can change this using the `ignore` method, + * allowing you to filter Game Objects out on a per-Camera basis. + * + * The Base Camera is extended by the Camera class, which adds in special effects including Fade, + * Flash and Camera Shake, as well as the ability to follow Game Objects. + * + * The Base Camera was introduced in Phaser 3.12. It was split off from the Camera class, to allow + * you to isolate special effects as needed. Therefore the 'since' values for properties of this class relate + * to when they were added to the Camera class. + * + * @class BaseCamera + * @memberof Phaser.Cameras.Scene2D * @constructor - * @since 3.13.0 + * @since 3.12.0 * - * @extends Phaser.GameObjects.Components.AlphaSingle - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.Events.EventEmitter + * @extends Phaser.GameObjects.Components.Alpha * @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 {string} [type] - The internal type of the Shape. - * @param {any} [data] - The data of the source shape geometry, if any. + * @param {number} x - The x position of the Camera, relative to the top-left of the game canvas. + * @param {number} y - The y position of the Camera, relative to the top-left of the game canvas. + * @param {number} width - The width of the Camera, in pixels. + * @param {number} height - The height of the Camera, in pixels. */ -var Shape = new Class({ +var BaseCamera = new Class({ - Extends: GameObject, + Extends: EventEmitter, Mixins: [ Components.AlphaSingle, - Components.BlendMode, - Components.Depth, - Components.GetBounds, - Components.Mask, - Components.Origin, - Components.Pipeline, - Components.ScrollFactor, - Components.Transform, Components.Visible ], initialize: - function Shape (scene, type, data) + function BaseCamera (x, y, width, height) { - if (type === undefined) { type = 'Shape'; } + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 0; } + if (height === undefined) { height = 0; } - GameObject.call(this, scene, type); + EventEmitter.call(this); /** - * The source Shape data. Typically a geometry object. - * You should not manipulate this directly. + * A reference to the Scene this camera belongs to. * - * @name Phaser.GameObjects.Shape#geom - * @type {any} - * @readonly - * @since 3.13.0 + * @name Phaser.Cameras.Scene2D.BaseCamera#scene + * @type {Phaser.Scene} + * @since 3.0.0 */ - this.geom = data; + this.scene; /** - * Holds the polygon path data for filled rendering. + * A reference to the Game Scene Manager. * - * @name Phaser.GameObjects.Shape#pathData - * @type {number[]} + * @name Phaser.Cameras.Scene2D.BaseCamera#sceneManager + * @type {Phaser.Scenes.SceneManager} + * @since 3.12.0 + */ + this.sceneManager; + + /** + * A reference to the Game Scale Manager. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#scaleManager + * @type {Phaser.Scale.ScaleManager} + * @since 3.16.0 + */ + this.scaleManager; + + /** + * A reference to the Scene's Camera Manager to which this Camera belongs. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#cameraManager + * @type {Phaser.Cameras.Scene2D.CameraManager} + * @since 3.17.0 + */ + this.cameraManager; + + /** + * The Camera ID. Assigned by the Camera Manager and used to handle camera exclusion. + * This value is a bitmask. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#id + * @type {number} * @readonly - * @since 3.13.0 + * @since 3.11.0 */ - this.pathData = []; + this.id = 0; /** - * Holds the earcut polygon path index data for filled rendering. + * The name of the Camera. This is left empty for your own use. * - * @name Phaser.GameObjects.Shape#pathIndexes - * @type {number[]} + * @name Phaser.Cameras.Scene2D.BaseCamera#name + * @type {string} + * @default '' + * @since 3.0.0 + */ + this.name = ''; + + /** + * Should this camera round its pixel values to integers? + * + * @name Phaser.Cameras.Scene2D.BaseCamera#roundPixels + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.roundPixels = false; + + /** + * Is this Camera visible or not? + * + * A visible camera will render and perform input tests. + * An invisible camera will not render anything and will skip input tests. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#visible + * @type {boolean} + * @default true + * @since 3.10.0 + */ + + /** + * Is this Camera using a bounds to restrict scrolling movement? + * + * Set this property along with the bounds via `Camera.setBounds`. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#useBounds + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.useBounds = false; + + /** + * The World View is a Rectangle that defines the area of the 'world' the Camera is currently looking at. + * This factors in the Camera viewport size, zoom and scroll position and is updated in the Camera preRender step. + * If you have enabled Camera bounds the worldview will be clamped to those bounds accordingly. + * You can use it for culling or intersection checks. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#worldView + * @type {Phaser.Geom.Rectangle} * @readonly - * @since 3.13.0 + * @since 3.11.0 */ - this.pathIndexes = []; + this.worldView = new Rectangle(); /** - * The fill color used by this Shape. + * Is this Camera dirty? * - * @name Phaser.GameObjects.Shape#fillColor + * A dirty Camera has had either its viewport size, bounds, scroll, rotation or zoom levels changed since the last frame. + * + * This flag is cleared during the `postRenderCamera` method of the renderer. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#dirty + * @type {boolean} + * @default true + * @since 3.11.0 + */ + this.dirty = true; + + /** + * The x position of the Camera viewport, relative to the top-left of the game canvas. + * The viewport is the area into which the camera renders. + * To adjust the position the camera is looking at in the game world, see the `scrollX` value. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_x * @type {number} - * @since 3.13.0 + * @private + * @since 3.0.0 */ - this.fillColor = 0xffffff; + this._x = x; /** - * The fill alpha value used by this Shape. + * The y position of the Camera, relative to the top-left of the game canvas. + * The viewport is the area into which the camera renders. + * To adjust the position the camera is looking at in the game world, see the `scrollY` value. * - * @name Phaser.GameObjects.Shape#fillAlpha + * @name Phaser.Cameras.Scene2D.BaseCamera#_y * @type {number} - * @since 3.13.0 + * @private + * @since 3.0.0 */ - this.fillAlpha = 1; + this._y = y; /** - * The stroke color used by this Shape. + * The width of the Camera viewport, in pixels. * - * @name Phaser.GameObjects.Shape#strokeColor + * The viewport is the area into which the Camera renders. Setting the viewport does + * not restrict where the Camera can scroll to. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_width * @type {number} - * @since 3.13.0 + * @private + * @since 3.11.0 */ - this.strokeColor = 0xffffff; + this._width = width; /** - * The stroke alpha value used by this Shape. + * The height of the Camera viewport, in pixels. * - * @name Phaser.GameObjects.Shape#strokeAlpha + * The viewport is the area into which the Camera renders. Setting the viewport does + * not restrict where the Camera can scroll to. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_height * @type {number} - * @since 3.13.0 + * @private + * @since 3.11.0 */ - this.strokeAlpha = 1; + this._height = height; /** - * The stroke line width used by this Shape. + * The bounds the camera is restrained to during scrolling. * - * @name Phaser.GameObjects.Shape#lineWidth + * @name Phaser.Cameras.Scene2D.BaseCamera#_bounds + * @type {Phaser.Geom.Rectangle} + * @private + * @since 3.0.0 + */ + this._bounds = new Rectangle(); + + /** + * The horizontal scroll position of this Camera. + * + * Change this value to cause the Camera to scroll around your Scene. + * + * Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method, + * will automatically adjust the Camera scroll values accordingly. + * + * You can set the bounds within which the Camera can scroll via the `setBounds` method. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_scrollX * @type {number} - * @since 3.13.0 + * @private + * @default 0 + * @since 3.11.0 */ - this.lineWidth = 1; + this._scrollX = 0; /** - * Controls if this Shape is filled or not. - * Note that some Shapes do not support being filled (such as Line shapes) + * The vertical scroll position of this Camera. * - * @name Phaser.GameObjects.Shape#isFilled - * @type {boolean} - * @since 3.13.0 + * Change this value to cause the Camera to scroll around your Scene. + * + * Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method, + * will automatically adjust the Camera scroll values accordingly. + * + * You can set the bounds within which the Camera can scroll via the `setBounds` method. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_scrollY + * @type {number} + * @private + * @default 0 + * @since 3.11.0 */ - this.isFilled = false; + this._scrollY = 0; /** - * Controls if this Shape is stroked or not. - * Note that some Shapes do not support being stroked (such as Iso Box shapes) + * The Camera horizontal zoom value. Change this value to zoom in, or out of, a Scene. * - * @name Phaser.GameObjects.Shape#isStroked + * A value of 0.5 would zoom the Camera out, so you can now see twice as much + * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel + * now takes up 2 pixels when rendered. + * + * Set to 1 to return to the default zoom level. + * + * Be careful to never set this value to zero. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_zoomX + * @type {number} + * @private + * @default 1 + * @since 3.50.0 + */ + this._zoomX = 1; + + /** + * The Camera vertical zoom value. Change this value to zoom in, or out of, a Scene. + * + * A value of 0.5 would zoom the Camera out, so you can now see twice as much + * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel + * now takes up 2 pixels when rendered. + * + * Set to 1 to return to the default zoom level. + * + * Be careful to never set this value to zero. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_zoomY + * @type {number} + * @private + * @default 1 + * @since 3.50.0 + */ + this._zoomY = 1; + + /** + * The rotation of the Camera in radians. + * + * Camera rotation always takes place based on the Camera viewport. By default, rotation happens + * in the center of the viewport. You can adjust this with the `originX` and `originY` properties. + * + * Rotation influences the rendering of _all_ Game Objects visible by this Camera. However, it does not + * rotate the Camera viewport itself, which always remains an axis-aligned rectangle. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_rotation + * @type {number} + * @private + * @default 0 + * @since 3.11.0 + */ + this._rotation = 0; + + /** + * A local transform matrix used for internal calculations. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#matrix + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.0.0 + */ + this.matrix = new TransformMatrix(); + + /** + * Does this Camera have a transparent background? + * + * @name Phaser.Cameras.Scene2D.BaseCamera#transparent * @type {boolean} - * @since 3.13.0 + * @default true + * @since 3.0.0 */ - this.isStroked = false; + this.transparent = true; /** - * Controls if this Shape path is closed during rendering when stroked. - * Note that some Shapes are always closed when stroked (such as Ellipse shapes) + * The background color of this Camera. Only used if `transparent` is `false`. * - * @name Phaser.GameObjects.Shape#closePath + * @name Phaser.Cameras.Scene2D.BaseCamera#backgroundColor + * @type {Phaser.Display.Color} + * @since 3.0.0 + */ + this.backgroundColor = ValueToColor('rgba(0,0,0,0)'); + + /** + * The Camera alpha value. Setting this property impacts every single object that this Camera + * renders. You can either set the property directly, i.e. via a Tween, to fade a Camera in or out, + * or via the chainable `setAlpha` method instead. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#alpha + * @type {number} + * @default 1 + * @since 3.11.0 + */ + + /** + * Should the camera cull Game Objects before checking them for input hit tests? + * In some special cases it may be beneficial to disable this. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#disableCull * @type {boolean} - * @since 3.13.0 + * @default false + * @since 3.0.0 */ - this.closePath = true; + this.disableCull = false; /** - * Private internal value. - * A Line used when parsing internal path data to avoid constant object re-creation. + * A temporary array of culled objects. * - * @name Phaser.GameObjects.Shape#_tempLine - * @type {Phaser.Geom.Line} + * @name Phaser.Cameras.Scene2D.BaseCamera#culledObjects + * @type {Phaser.GameObjects.GameObject[]} + * @default [] * @private - * @since 3.13.0 + * @since 3.0.0 */ - this._tempLine = new Line(); + this.culledObjects = []; /** - * The native (un-scaled) width of this Game Object. + * The mid-point of the Camera in 'world' coordinates. * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. + * Use it to obtain exactly where in the world the center of the camera is currently looking. * - * @name Phaser.GameObjects.Shape#width + * This value is updated in the preRender method, after the scroll values and follower + * have been processed. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#midPoint + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.11.0 + */ + this.midPoint = new Vector2(width / 2, height / 2); + + /** + * The horizontal origin of rotation for this Camera. + * + * By default the camera rotates around the center of the viewport. + * + * Changing the origin allows you to adjust the point in the viewport from which rotation happens. + * A value of 0 would rotate from the top-left of the viewport. A value of 1 from the bottom right. + * + * See `setOrigin` to set both origins in a single, chainable call. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#originX * @type {number} - * @since 3.13.0 + * @default 0.5 + * @since 3.11.0 */ - this.width = 0; + this.originX = 0.5; /** - * The native (un-scaled) height of this Game Object. + * The vertical origin of rotation for this Camera. * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. + * By default the camera rotates around the center of the viewport. * - * @name Phaser.GameObjects.Shape#height + * Changing the origin allows you to adjust the point in the viewport from which rotation happens. + * A value of 0 would rotate from the top-left of the viewport. A value of 1 from the bottom right. + * + * See `setOrigin` to set both origins in a single, chainable call. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#originY * @type {number} - * @since 3.0.0 + * @default 0.5 + * @since 3.11.0 */ - this.height = 0; + this.originY = 0.5; - this.initPipeline(); + /** + * Does this Camera have a custom viewport? + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_customViewport + * @type {boolean} + * @private + * @default false + * @since 3.12.0 + */ + this._customViewport = false; + + /** + * The Mask this Camera is using during render. + * Set the mask using the `setMask` method. Remove the mask using the `clearMask` method. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#mask + * @type {?(Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask)} + * @since 3.17.0 + */ + this.mask = null; + + /** + * The Camera that this Camera uses for translation during masking. + * + * If the mask is fixed in position this will be a reference to + * the CameraManager.default instance. Otherwise, it'll be a reference + * to itself. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#_maskCamera + * @type {?Phaser.Cameras.Scene2D.BaseCamera} + * @private + * @since 3.17.0 + */ + this._maskCamera = null; + + /** + * This array is populated with all of the Game Objects that this Camera has rendered + * in the previous (or current, depending on when you inspect it) frame. + * + * It is cleared at the start of `Camera.preUpdate`, or if the Camera is destroyed. + * + * You should not modify this array as it is used internally by the input system, + * however you can read it as required. Note that Game Objects may appear in this + * list multiple times if they belong to multiple non-exclusive Containers. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#renderList + * @type {Phaser.GameObjects.GameObject[]} + * @since 3.52.0 + */ + this.renderList = []; + + /** + * Is this Camera a Scene Camera? (which is the default), or a Camera + * belonging to a Texture? + * + * @name Phaser.Cameras.Scene2D.BaseCamera#isSceneCamera + * @type {boolean} + * @default true + * @since 3.60.0 + */ + this.isSceneCamera = true; }, /** - * Sets the fill color and alpha for this Shape. + * Adds the given Game Object to this cameras render list. * - * If you wish for the Shape to not be filled then call this method with no arguments, or just set `isFilled` to `false`. + * This is invoked during the rendering stage. Only objects that are actually rendered + * will appear in the render list. * - * Note that some Shapes do not support fill colors, such as the Line shape. + * @method Phaser.Cameras.Scene2D.BaseCamera#addToRenderList + * @since 3.52.0 * - * This call can be chained. + * @param {Phaser.GameObjects.GameObject} child - The Game Object to add to the render list. + */ + addToRenderList: function (child) + { + this.renderList.push(child); + }, + + /** + * Set the Alpha level of this Camera. The alpha controls the opacity of the Camera as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. * - * @method Phaser.GameObjects.Shape#setFillStyle - * @since 3.13.0 + * @method Phaser.Cameras.Scene2D.BaseCamera#setAlpha + * @since 3.11.0 * - * @param {number} [color] - The color used to fill this shape. If not provided the Shape will not be filled. - * @param {number} [alpha=1] - The alpha value used when filling this shape, if a fill color is given. + * @param {number} [value=1] - The Camera alpha value. * - * @return {this} This Game Object instance. + * @return {this} This Camera instance. */ - setFillStyle: function (color, alpha) + + /** + * Sets the rotation origin of this Camera. + * + * The values are given in the range 0 to 1 and are only used when calculating Camera rotation. + * + * By default the camera rotates around the center of the viewport. + * + * Changing the origin allows you to adjust the point in the viewport from which rotation happens. + * A value of 0 would rotate from the top-left of the viewport. A value of 1 from the bottom right. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setOrigin + * @since 3.11.0 + * + * @param {number} [x=0.5] - The horizontal origin value. + * @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`. + * + * @return {this} This Camera instance. + */ + setOrigin: function (x, y) { - if (alpha === undefined) { alpha = 1; } + if (x === undefined) { x = 0.5; } + if (y === undefined) { y = x; } - if (color === undefined) - { - this.isFilled = false; - } - else - { - this.fillColor = color; - this.fillAlpha = alpha; - this.isFilled = true; - } + this.originX = x; + this.originY = y; return this; }, /** - * Sets the stroke color and alpha for this Shape. - * - * If you wish for the Shape to not be stroked then call this method with no arguments, or just set `isStroked` to `false`. - * - * Note that some Shapes do not support being stroked, such as the Iso Box shape. - * - * This call can be chained. + * Calculates what the Camera.scrollX and scrollY values would need to be in order to move + * the Camera so it is centered on the given x and y coordinates, without actually moving + * the Camera there. The results are clamped based on the Camera bounds, if set. * - * @method Phaser.GameObjects.Shape#setStrokeStyle - * @since 3.13.0 + * @method Phaser.Cameras.Scene2D.BaseCamera#getScroll + * @since 3.11.0 * - * @param {number} [lineWidth] - The width of line to stroke with. If not provided or undefined the Shape will not be stroked. - * @param {number} [color] - The color used to stroke this shape. If not provided the Shape will not be stroked. - * @param {number} [alpha=1] - The alpha value used when stroking this shape, if a stroke color is given. + * @param {number} x - The horizontal coordinate to center on. + * @param {number} y - The vertical coordinate to center on. + * @param {Phaser.Math.Vector2} [out] - A Vector2 to store the values in. If not given a new Vector2 is created. * - * @return {this} This Game Object instance. + * @return {Phaser.Math.Vector2} The scroll coordinates stored in the `x` and `y` properties. */ - setStrokeStyle: function (lineWidth, color, alpha) + getScroll: function (x, y, out) { - if (alpha === undefined) { alpha = 1; } + if (out === undefined) { out = new Vector2(); } - if (lineWidth === undefined) - { - this.isStroked = false; - } - else + var originX = this.width * 0.5; + var originY = this.height * 0.5; + + out.x = x - originX; + out.y = y - originY; + + if (this.useBounds) { - this.lineWidth = lineWidth; - this.strokeColor = color; - this.strokeAlpha = alpha; - this.isStroked = true; + out.x = this.clampX(out.x); + out.y = this.clampY(out.y); } - return this; + return out; }, /** - * Sets if this Shape path is closed during rendering when stroked. - * Note that some Shapes are always closed when stroked (such as Ellipse shapes) - * - * This call can be chained. + * Moves the Camera horizontally so that it is centered on the given x coordinate, bounds allowing. + * Calling this does not change the scrollY value. * - * @method Phaser.GameObjects.Shape#setClosePath - * @since 3.13.0 + * @method Phaser.Cameras.Scene2D.BaseCamera#centerOnX + * @since 3.16.0 * - * @param {boolean} value - Set to `true` if the Shape should be closed when stroked, otherwise `false`. + * @param {number} x - The horizontal coordinate to center on. * - * @return {this} This Game Object instance. + * @return {this} This Camera instance. */ - setClosePath: function (value) + centerOnX: function (x) { - this.closePath = value; + var originX = this.width * 0.5; + + this.midPoint.x = x; + + this.scrollX = x - originX; + + if (this.useBounds) + { + this.scrollX = this.clampX(this.scrollX); + } return this; }, /** - * Sets the internal size of this Game Object, as used for frame or physics body creation. - * - * This will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or call the - * `setDisplaySize` method, which is the same thing as changing the scale but allows you - * to do so by giving pixel values. - * - * If you have enabled this Game Object for input, changing the size will _not_ change the - * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * Moves the Camera vertically so that it is centered on the given y coordinate, bounds allowing. + * Calling this does not change the scrollX value. * - * @method Phaser.GameObjects.Shape#setSize - * @private - * @since 3.13.0 + * @method Phaser.Cameras.Scene2D.BaseCamera#centerOnY + * @since 3.16.0 * - * @param {number} width - The width of this Game Object. - * @param {number} height - The height of this Game Object. + * @param {number} y - The vertical coordinate to center on. * - * @return {this} This Game Object instance. + * @return {this} This Camera instance. */ - setSize: function (width, height) + centerOnY: function (y) { - this.width = width; - this.height = height; + var originY = this.height * 0.5; + + this.midPoint.y = y; + + this.scrollY = y - originY; + + if (this.useBounds) + { + this.scrollY = this.clampY(this.scrollY); + } return this; }, /** - * Sets the display size of this Shape. - * - * Calling this will adjust the scale. + * Moves the Camera so that it is centered on the given coordinates, bounds allowing. * - * @method Phaser.GameObjects.Shape#setDisplaySize - * @since 3.53.0 + * @method Phaser.Cameras.Scene2D.BaseCamera#centerOn + * @since 3.11.0 * - * @param {number} width - The display width of this Shape. - * @param {number} height - The display height of this Shape. + * @param {number} x - The horizontal coordinate to center on. + * @param {number} y - The vertical coordinate to center on. * - * @return {this} This Shape instance. + * @return {this} This Camera instance. */ - setDisplaySize: function (width, height) + centerOn: function (x, y) { - this.displayWidth = width; - this.displayHeight = height; + this.centerOnX(x); + this.centerOnY(y); return this; }, /** - * Internal destroy handler, called as part of the destroy process. + * Moves the Camera so that it is looking at the center of the Camera Bounds, if enabled. * - * @method Phaser.GameObjects.Shape#preDestroy - * @protected - * @since 3.13.0 - */ - preDestroy: function () + * @method Phaser.Cameras.Scene2D.BaseCamera#centerToBounds + * @since 3.0.0 + * + * @return {this} This Camera instance. + */ + centerToBounds: function () { - this.geom = null; - this._tempLine = null; - this.pathData = []; - this.pathIndexes = []; + if (this.useBounds) + { + var bounds = this._bounds; + var originX = this.width * 0.5; + var originY = this.height * 0.5; + + this.midPoint.set(bounds.centerX, bounds.centerY); + + this.scrollX = bounds.centerX - originX; + this.scrollY = bounds.centerY - originY; + } + + return this; }, /** - * The displayed width of this Game Object. - * - * This value takes into account the scale factor. + * Moves the Camera so that it is re-centered based on its viewport size. * - * Setting this value will adjust the Game Object's scale property. + * @method Phaser.Cameras.Scene2D.BaseCamera#centerToSize + * @since 3.0.0 * - * @name Phaser.GameObjects.Shape#displayWidth - * @type {number} - * @since 3.13.0 + * @return {this} This Camera instance. */ - displayWidth: { - - get: function () - { - return this.scaleX * this.width; - }, - - set: function (value) - { - this.scaleX = value / this.width; - } + centerToSize: function () + { + this.scrollX = this.width * 0.5; + this.scrollY = this.height * 0.5; + return this; }, /** - * The displayed height of this Game Object. + * Takes an array of Game Objects and returns a new array featuring only those objects + * visible by this camera. * - * This value takes into account the scale factor. + * @method Phaser.Cameras.Scene2D.BaseCamera#cull + * @since 3.0.0 * - * Setting this value will adjust the Game Object's scale property. + * @generic {Phaser.GameObjects.GameObject[]} G - [renderableObjects,$return] * - * @name Phaser.GameObjects.Shape#displayHeight - * @type {number} - * @since 3.13.0 + * @param {Phaser.GameObjects.GameObject[]} renderableObjects - An array of Game Objects to cull. + * + * @return {Phaser.GameObjects.GameObject[]} An array of Game Objects visible to this Camera. */ - displayHeight: { - - get: function () - { - return this.scaleY * this.height; - }, - - set: function (value) + cull: function (renderableObjects) + { + if (this.disableCull) { - this.scaleY = value / this.height; + return renderableObjects; } - } - -}); - -module.exports = Shape; - - -/***/ }), -/* 35 */ -/***/ (function(module, exports) { + var cameraMatrix = this.matrix.matrix; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var mva = cameraMatrix[0]; + var mvb = cameraMatrix[1]; + var mvc = cameraMatrix[2]; + var mvd = cameraMatrix[3]; -/** - * Phaser Blend Modes. - * - * @namespace Phaser.BlendModes - * @since 3.0.0 - */ + /* First Invert Matrix */ + var determinant = (mva * mvd) - (mvb * mvc); -module.exports = { + if (!determinant) + { + return renderableObjects; + } - /** - * Skips the Blend Mode check in the renderer. - * - * @name Phaser.BlendModes.SKIP_CHECK - * @type {number} - * @const - * @since 3.0.0 - */ - SKIP_CHECK: -1, + var mve = cameraMatrix[4]; + var mvf = cameraMatrix[5]; - /** - * 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, + var scrollX = this.scrollX; + var scrollY = this.scrollY; + var cameraW = this.width; + var cameraH = this.height; + var cullTop = this.y; + var cullBottom = cullTop + cameraH; + var cullLeft = this.x; + var cullRight = cullLeft + cameraW; + var culledObjects = this.culledObjects; + var length = renderableObjects.length; - /** - * 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, + determinant = 1 / determinant; - /** - * 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, + culledObjects.length = 0; - /** - * 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, + for (var index = 0; index < length; ++index) + { + var object = renderableObjects[index]; - /** - * 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, + if (!object.hasOwnProperty('width') || object.parentContainer) + { + culledObjects.push(object); + continue; + } - /** - * 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, + var objectW = object.width; + var objectH = object.height; + var objectX = (object.x - (scrollX * object.scrollFactorX)) - (objectW * object.originX); + var objectY = (object.y - (scrollY * object.scrollFactorY)) - (objectH * object.originY); + var tx = (objectX * mva + objectY * mvc + mve); + var ty = (objectX * mvb + objectY * mvd + mvf); + var tw = ((objectX + objectW) * mva + (objectY + objectH) * mvc + mve); + var th = ((objectX + objectW) * mvb + (objectY + objectH) * mvd + mvf); - /** - * 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, + if ((tw > cullLeft && tx < cullRight) && (th > cullTop && ty < cullBottom)) + { + culledObjects.push(object); + } + } - /** - * 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, + return culledObjects; + }, /** - * 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 + * Converts the given `x` and `y` coordinates into World space, based on this Cameras transform. + * You can optionally provide a Vector2, or similar object, to store the results in. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#getWorldPoint * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [output,$return] + * + * @param {number} x - The x position to convert to world space. + * @param {number} y - The y position to convert to world space. + * @param {(object|Phaser.Math.Vector2)} [output] - An optional object to store the results in. If not provided a new Vector2 will be created. + * + * @return {Phaser.Math.Vector2} An object holding the converted values in its `x` and `y` properties. */ - COLOR_BURN: 8, + getWorldPoint: function (x, y, output) + { + if (output === undefined) { output = new Vector2(); } - /** - * 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, + var cameraMatrix = this.matrix.matrix; - /** - * 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, + var mva = cameraMatrix[0]; + var mvb = cameraMatrix[1]; + var mvc = cameraMatrix[2]; + var mvd = cameraMatrix[3]; + var mve = cameraMatrix[4]; + var mvf = cameraMatrix[5]; - /** - * 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, + // Invert Matrix + var determinant = (mva * mvd) - (mvb * mvc); - /** - * 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, + if (!determinant) + { + output.x = x; + output.y = y; - /** - * 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, + return output; + } - /** - * 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, + determinant = 1 / determinant; - /** - * 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, + var ima = mvd * determinant; + var imb = -mvb * determinant; + var imc = -mvc * determinant; + var imd = mva * determinant; + var ime = (mvc * mvf - mvd * mve) * determinant; + var imf = (mvb * mve - mva * mvf) * determinant; - /** - * 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, + var c = Math.cos(this.rotation); + var s = Math.sin(this.rotation); - /** - * Alpha erase blend mode. For Canvas and WebGL. - * - * @name Phaser.BlendModes.ERASE - * @type {number} - * @const - * @since 3.0.0 - */ - ERASE: 17, + var zoomX = this.zoomX; + var zoomY = this.zoomY; - /** - * 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, + var scrollX = this.scrollX; + var scrollY = this.scrollY; - /** - * 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, + var sx = x + ((scrollX * c - scrollY * s) * zoomX); + var sy = y + ((scrollX * s + scrollY * c) * zoomY); - /** - * 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, + // Apply transform to point + output.x = (sx * ima + sy * imc) + ime; + output.y = (sx * imb + sy * imd) + imf; - /** - * 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, + return output; + }, /** - * 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 + * Given a Game Object, or an array of Game Objects, it will update all of their camera filter settings + * so that they are ignored by this Camera. This means they will not be rendered by this Camera. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#ignore * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Layer|Phaser.GameObjects.Layer[])} entries - The Game Object, or array of Game Objects, to be ignored by this Camera. + * + * @return {this} This Camera instance. */ - DESTINATION_IN: 22, + ignore: function (entries) + { + var id = this.id; - /** - * 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, + if (!Array.isArray(entries)) + { + entries = [ entries ]; + } - /** - * 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, + for (var i = 0; i < entries.length; i++) + { + var entry = entries[i]; - /** - * 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, + if (Array.isArray(entry)) + { + this.ignore(entry); + } + else if (entry.isParent) + { + this.ignore(entry.getChildren()); + } + else + { + entry.cameraFilter |= id; + } + } - /** - * 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, + return this; + }, /** - * 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 + * Internal preRender step. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#preRender + * @protected * @since 3.0.0 */ - XOR: 27 - -}; - - -/***/ }), -/* 36 */ -/***/ (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__(14); - -/** - * Convert the given angle from degrees, to the equivalent angle in radians. - * - * @function Phaser.Math.DegToRad - * @since 3.0.0 - * - * @param {number} degrees - The angle (in degrees) to convert to radians. - * - * @return {number} The given angle converted to radians. - */ -var DegToRad = function (degrees) -{ - return degrees * CONST.DEG_TO_RAD; -}; - -module.exports = DegToRad; - + preRender: function () + { + this.renderList.length = 0; -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { + var width = this.width; + var height = this.height; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var halfWidth = width * 0.5; + var halfHeight = height * 0.5; -/** - * @namespace Phaser.Cameras.Scene2D.Events - */ + var zoomX = this.zoomX; + var zoomY = this.zoomY; + var matrix = this.matrix; -module.exports = { + var originX = width * this.originX; + var originY = height * this.originY; - DESTROY: __webpack_require__(743), - FADE_IN_COMPLETE: __webpack_require__(744), - FADE_IN_START: __webpack_require__(745), - FADE_OUT_COMPLETE: __webpack_require__(746), - FADE_OUT_START: __webpack_require__(747), - FLASH_COMPLETE: __webpack_require__(748), - FLASH_START: __webpack_require__(749), - FOLLOW_UPDATE: __webpack_require__(750), - PAN_COMPLETE: __webpack_require__(751), - PAN_START: __webpack_require__(752), - POST_RENDER: __webpack_require__(753), - PRE_RENDER: __webpack_require__(754), - ROTATE_COMPLETE: __webpack_require__(755), - ROTATE_START: __webpack_require__(756), - SHAKE_COMPLETE: __webpack_require__(757), - SHAKE_START: __webpack_require__(758), - ZOOM_COMPLETE: __webpack_require__(759), - ZOOM_START: __webpack_require__(760) + var sx = this.scrollX; + var sy = this.scrollY; -}; + if (this.useBounds) + { + sx = this.clampX(sx); + sy = this.clampY(sy); + } + if (this.roundPixels) + { + originX = Math.round(originX); + originY = Math.round(originY); + } -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { + // Values are in pixels and not impacted by zooming the Camera + this.scrollX = sx; + this.scrollY = sy; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var midX = sx + halfWidth; + var midY = sy + halfHeight; -var Class = __webpack_require__(0); -var GetColor = __webpack_require__(103); -var GetColor32 = __webpack_require__(328); -var HSVToRGB = __webpack_require__(188); -var RGBToHSV = __webpack_require__(329); + // The center of the camera, in world space, so taking zoom into account + // Basically the pixel value of what it's looking at in the middle of the cam + this.midPoint.set(midX, midY); -/** - * @namespace Phaser.Display.Color - */ + var displayWidth = width / zoomX; + var displayHeight = height / zoomY; -/** - * @classdesc - * The Color class holds a single color value and allows for easy modification and reading of it. - * - * @class Color - * @memberof Phaser.Display - * @constructor - * @since 3.0.0 - * - * @param {number} [red=0] - The red color value. A number between 0 and 255. - * @param {number} [green=0] - The green color value. A number between 0 and 255. - * @param {number} [blue=0] - The blue color value. A number between 0 and 255. - * @param {number} [alpha=255] - The alpha value. A number between 0 and 255. - */ -var Color = new Class({ + this.worldView.setTo( + midX - (displayWidth / 2), + midY - (displayHeight / 2), + displayWidth, + displayHeight + ); - initialize: + matrix.applyITRS(this.x + originX, this.y + originY, this.rotation, zoomX, zoomY); + matrix.translate(-originX, -originY); + }, - function Color (red, green, blue, alpha) + /** + * Takes an x value and checks it's within the range of the Camera bounds, adjusting if required. + * Do not call this method if you are not using camera bounds. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#clampX + * @since 3.11.0 + * + * @param {number} x - The value to horizontally scroll clamp. + * + * @return {number} The adjusted value to use as scrollX. + */ + clampX: function (x) { - if (red === undefined) { red = 0; } - if (green === undefined) { green = 0; } - if (blue === undefined) { blue = 0; } - if (alpha === undefined) { alpha = 255; } - - /** - * The internal red color value. - * - * @name Phaser.Display.Color#r - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.r = 0; - - /** - * The internal green color value. - * - * @name Phaser.Display.Color#g - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.g = 0; - - /** - * The internal blue color value. - * - * @name Phaser.Display.Color#b - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this.b = 0; - - /** - * The internal alpha color value. - * - * @name Phaser.Display.Color#a - * @type {number} - * @private - * @default 255 - * @since 3.0.0 - */ - this.a = 255; + var bounds = this._bounds; - /** - * The hue color value. A number between 0 and 1. - * This is the base color. - * - * @name Phaser.Display.Color#_h - * @type {number} - * @default 0 - * @private - * @since 3.13.0 - */ - this._h = 0; + var dw = this.displayWidth; - /** - * The saturation color value. A number between 0 and 1. - * This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white. - * - * @name Phaser.Display.Color#_s - * @type {number} - * @default 0 - * @private - * @since 3.13.0 - */ - this._s = 0; + var bx = bounds.x + ((dw - this.width) / 2); + var bw = Math.max(bx, bx + bounds.width - dw); - /** - * The lightness color value. A number between 0 and 1. - * This controls how dark the color is. Where 1 is as bright as possible and 0 is black. - * - * @name Phaser.Display.Color#_v - * @type {number} - * @default 0 - * @private - * @since 3.13.0 - */ - this._v = 0; + if (x < bx) + { + x = bx; + } + else if (x > bw) + { + x = bw; + } - /** - * Is this color update locked? - * - * @name Phaser.Display.Color#_locked - * @type {boolean} - * @private - * @since 3.13.0 - */ - this._locked = false; + return x; + }, - /** - * An array containing the calculated color values for WebGL use. - * - * @name Phaser.Display.Color#gl - * @type {number[]} - * @since 3.0.0 - */ - this.gl = [ 0, 0, 0, 1 ]; + /** + * Takes a y value and checks it's within the range of the Camera bounds, adjusting if required. + * Do not call this method if you are not using camera bounds. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#clampY + * @since 3.11.0 + * + * @param {number} y - The value to vertically scroll clamp. + * + * @return {number} The adjusted value to use as scrollY. + */ + clampY: function (y) + { + var bounds = this._bounds; - /** - * Pre-calculated internal color value. - * - * @name Phaser.Display.Color#_color - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._color = 0; + var dh = this.displayHeight; - /** - * Pre-calculated internal color32 value. - * - * @name Phaser.Display.Color#_color32 - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._color32 = 0; + var by = bounds.y + ((dh - this.height) / 2); + var bh = Math.max(by, by + bounds.height - dh); - /** - * Pre-calculated internal color rgb string value. - * - * @name Phaser.Display.Color#_rgba - * @type {string} - * @private - * @default '' - * @since 3.0.0 - */ - this._rgba = ''; + if (y < by) + { + y = by; + } + else if (y > bh) + { + y = bh; + } - this.setTo(red, green, blue, alpha); + return y; }, + /* + var gap = this._zoomInversed; + return gap * Math.round((src.x - this.scrollX * src.scrollFactorX) / gap); + */ + /** - * Sets this color to be transparent. Sets all values to zero. + * If this Camera has previously had movement bounds set on it, this will remove them. * - * @method Phaser.Display.Color#transparent + * @method Phaser.Cameras.Scene2D.BaseCamera#removeBounds * @since 3.0.0 * - * @return {Phaser.Display.Color} This Color object. + * @return {this} This Camera instance. */ - transparent: function () + removeBounds: function () { - this._locked = true; + this.useBounds = false; - this.red = 0; - this.green = 0; - this.blue = 0; - this.alpha = 0; + this.dirty = true; - this._locked = false; + this._bounds.setEmpty(); - return this.update(true); + return this; }, /** - * Sets the color of this Color component. + * Set the rotation of this Camera. This causes everything it renders to appear rotated. * - * @method Phaser.Display.Color#setTo + * Rotating a camera does not rotate the viewport itself, it is applied during rendering. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setAngle * @since 3.0.0 * - * @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. - * @param {boolean} [updateHSV=true] - Update the HSV values after setting the RGB values? + * @param {number} [value=0] - The cameras angle of rotation, given in degrees. * - * @return {Phaser.Display.Color} This Color object. + * @return {this} This Camera instance. */ - setTo: function (red, green, blue, alpha, updateHSV) + setAngle: function (value) { - if (alpha === undefined) { alpha = 255; } - if (updateHSV === undefined) { updateHSV = true; } - - this._locked = true; - - this.red = red; - this.green = green; - this.blue = blue; - this.alpha = alpha; + if (value === undefined) { value = 0; } - this._locked = false; + this.rotation = DegToRad(value); - return this.update(updateHSV); + return this; }, /** - * Sets the red, green, blue and alpha GL values of this Color component. + * Sets the background color for this Camera. * - * @method Phaser.Display.Color#setGLTo + * By default a Camera has a transparent background but it can be given a solid color, with any level + * of transparency, via this method. + * + * The color value can be specified using CSS color notation, hex or numbers. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setBackgroundColor * @since 3.0.0 * - * @param {number} red - The red color value. A number between 0 and 1. - * @param {number} green - The green color value. A number between 0 and 1. - * @param {number} blue - The blue color value. A number between 0 and 1. - * @param {number} [alpha=1] - The alpha value. A number between 0 and 1. + * @param {(string|number|Phaser.Types.Display.InputColorObject)} [color='rgba(0,0,0,0)'] - The color value. In CSS, hex or numeric color notation. * - * @return {Phaser.Display.Color} This Color object. + * @return {this} This Camera instance. */ - setGLTo: function (red, green, blue, alpha) + setBackgroundColor: function (color) { - if (alpha === undefined) { alpha = 1; } - - this._locked = true; + if (color === undefined) { color = 'rgba(0,0,0,0)'; } - this.redGL = red; - this.greenGL = green; - this.blueGL = blue; - this.alphaGL = alpha; + this.backgroundColor = ValueToColor(color); - this._locked = false; + this.transparent = (this.backgroundColor.alpha === 0); - return this.update(true); + return this; }, /** - * Sets the color based on the color object given. + * Set the bounds of the Camera. The bounds are an axis-aligned rectangle. * - * @method Phaser.Display.Color#setFromRGB + * The Camera bounds controls where the Camera can scroll to, stopping it from scrolling off the + * edges and into blank space. It does not limit the placement of Game Objects, or where + * the Camera viewport can be positioned. + * + * Temporarily disable the bounds by changing the boolean `Camera.useBounds`. + * + * Clear the bounds entirely by calling `Camera.removeBounds`. + * + * If you set bounds that are smaller than the viewport it will stop the Camera from being + * able to scroll. The bounds can be positioned where-ever you wish. By default they are from + * 0x0 to the canvas width x height. This means that the coordinate 0x0 is the top left of + * the Camera bounds. However, you can position them anywhere. So if you wanted a game world + * that was 2048x2048 in size, with 0x0 being the center of it, you can set the bounds x/y + * to be -1024, -1024, with a width and height of 2048. Depending on your game you may find + * it easier for 0x0 to be the top-left of the bounds, or you may wish 0x0 to be the middle. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setBounds * @since 3.0.0 * - * @param {Phaser.Types.Display.InputColorObject} color - An object containing `r`, `g`, `b` and optionally `a` values in the range 0 to 255. + * @param {number} x - The top-left x coordinate of the bounds. + * @param {number} y - The top-left y coordinate of the bounds. + * @param {number} width - The width of the bounds, in pixels. + * @param {number} height - The height of the bounds, in pixels. + * @param {boolean} [centerOn=false] - If `true` the Camera will automatically be centered on the new bounds. * - * @return {Phaser.Display.Color} This Color object. + * @return {this} This Camera instance. */ - setFromRGB: function (color) + setBounds: function (x, y, width, height, centerOn) { - this._locked = true; + if (centerOn === undefined) { centerOn = false; } - this.red = color.r; - this.green = color.g; - this.blue = color.b; + this._bounds.setTo(x, y, width, height); - if (color.hasOwnProperty('a')) + this.dirty = true; + this.useBounds = true; + + if (centerOn) { - this.alpha = color.a; + this.centerToBounds(); + } + else + { + this.scrollX = this.clampX(this.scrollX); + this.scrollY = this.clampY(this.scrollY); } - this._locked = false; - - return this.update(true); + return this; }, /** - * Sets the color based on the hue, saturation and lightness values given. + * Returns a rectangle containing the bounds of the Camera. * - * @method Phaser.Display.Color#setFromHSV - * @since 3.13.0 + * If the Camera does not have any bounds the rectangle will be empty. * - * @param {number} h - The hue, in the range 0 - 1. This is the base color. - * @param {number} s - The saturation, in the range 0 - 1. This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white. - * @param {number} v - The value, in the range 0 - 1. This controls how dark the color is. Where 1 is as bright as possible and 0 is black. + * The rectangle is a copy of the bounds, so is safe to modify. * - * @return {Phaser.Display.Color} This Color object. + * @method Phaser.Cameras.Scene2D.BaseCamera#getBounds + * @since 3.16.0 + * + * @param {Phaser.Geom.Rectangle} [out] - An optional Rectangle to store the bounds in. If not given, a new Rectangle will be created. + * + * @return {Phaser.Geom.Rectangle} A rectangle containing the bounds of this Camera. */ - setFromHSV: function (h, s, v) + getBounds: function (out) { - return HSVToRGB(h, s, v, this); + if (out === undefined) { out = new Rectangle(); } + + var source = this._bounds; + + out.setTo(source.x, source.y, source.width, source.height); + + return out; }, /** - * Updates the internal cache values. + * Sets the name of this Camera. + * This value is for your own use and isn't used internally. * - * @method Phaser.Display.Color#update - * @private + * @method Phaser.Cameras.Scene2D.BaseCamera#setName * @since 3.0.0 * - * @return {Phaser.Display.Color} This Color object. + * @param {string} [value=''] - The name of the Camera. + * + * @return {this} This Camera instance. */ - update: function (updateHSV) + setName: function (value) { - if (updateHSV === undefined) { updateHSV = false; } - - if (this._locked) - { - return this; - } - - var r = this.r; - var g = this.g; - var b = this.b; - var a = this.a; - - this._color = GetColor(r, g, b); - this._color32 = GetColor32(r, g, b, a); - this._rgba = 'rgba(' + r + ',' + g + ',' + b + ',' + (a / 255) + ')'; + if (value === undefined) { value = ''; } - if (updateHSV) - { - RGBToHSV(r, g, b, this); - } + this.name = value; return this; }, /** - * Updates the internal hsv cache values. + * Set the position of the Camera viewport within the game. * - * @method Phaser.Display.Color#updateHSV - * @private - * @since 3.13.0 + * This does not change where the camera is 'looking'. See `setScroll` to control that. * - * @return {Phaser.Display.Color} This Color object. + * @method Phaser.Cameras.Scene2D.BaseCamera#setPosition + * @since 3.0.0 + * + * @param {number} x - The top-left x coordinate of the Camera viewport. + * @param {number} [y=x] - The top-left y coordinate of the Camera viewport. + * + * @return {this} This Camera instance. */ - updateHSV: function () + setPosition: function (x, y) { - var r = this.r; - var g = this.g; - var b = this.b; + if (y === undefined) { y = x; } - RGBToHSV(r, g, b, this); + this.x = x; + this.y = y; return this; }, /** - * Returns a new Color component using the values from this one. + * Set the rotation of this Camera. This causes everything it renders to appear rotated. * - * @method Phaser.Display.Color#clone + * Rotating a camera does not rotate the viewport itself, it is applied during rendering. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setRotation * @since 3.0.0 * - * @return {Phaser.Display.Color} A new Color object. + * @param {number} [value=0] - The rotation of the Camera, in radians. + * + * @return {this} This Camera instance. */ - clone: function () + setRotation: function (value) { - return new Color(this.r, this.g, this.b, this.a); + if (value === undefined) { value = 0; } + + this.rotation = value; + + return this; }, /** - * Sets this Color object to be grayscaled based on the shade value given. + * Should the Camera round pixel values to whole integers when rendering Game Objects? * - * @method Phaser.Display.Color#gray - * @since 3.13.0 - * - * @param {number} shade - A value between 0 and 255. + * In some types of game, especially with pixel art, this is required to prevent sub-pixel aliasing. * - * @return {Phaser.Display.Color} This Color object. + * @method Phaser.Cameras.Scene2D.BaseCamera#setRoundPixels + * @since 3.0.0 + * + * @param {boolean} value - `true` to round Camera pixels, `false` to not. + * + * @return {this} This Camera instance. */ - gray: function (shade) + setRoundPixels: function (value) { - return this.setTo(shade, shade, shade); + this.roundPixels = value; + + return this; }, /** - * Sets this Color object to be a random color between the `min` and `max` values given. + * Sets the Scene the Camera is bound to. * - * @method Phaser.Display.Color#random - * @since 3.13.0 - * - * @param {number} [min=0] - The minimum random color value. Between 0 and 255. - * @param {number} [max=255] - The maximum random color value. Between 0 and 255. + * @method Phaser.Cameras.Scene2D.BaseCamera#setScene + * @since 3.0.0 * - * @return {Phaser.Display.Color} This Color object. + * @param {Phaser.Scene} scene - The Scene the camera is bound to. + * @param {boolean} [isSceneCamera=true] - Is this Camera being used for a Scene (true) or a Texture? (false) + * + * @return {this} This Camera instance. */ - random: function (min, max) + setScene: function (scene, isSceneCamera) { - if (min === undefined) { min = 0; } - if (max === undefined) { max = 255; } + if (isSceneCamera === undefined) { isSceneCamera = true; } - var r = Math.floor(min + Math.random() * (max - min)); - var g = Math.floor(min + Math.random() * (max - min)); - var b = Math.floor(min + Math.random() * (max - min)); + if (this.scene && this._customViewport) + { + this.sceneManager.customViewports--; + } - return this.setTo(r, g, b); + this.scene = scene; + this.isSceneCamera = isSceneCamera; + + var sys = scene.sys; + + this.sceneManager = sys.game.scene; + this.scaleManager = sys.scale; + this.cameraManager = sys.cameras; + + this.updateSystem(); + + return this; }, /** - * Sets this Color object to be a random grayscale color between the `min` and `max` values given. + * Set the position of where the Camera is looking within the game. + * You can also modify the properties `Camera.scrollX` and `Camera.scrollY` directly. + * Use this method, or the scroll properties, to move your camera around the game world. * - * @method Phaser.Display.Color#randomGray - * @since 3.13.0 - * - * @param {number} [min=0] - The minimum random color value. Between 0 and 255. - * @param {number} [max=255] - The maximum random color value. Between 0 and 255. + * This does not change where the camera viewport is placed. See `setPosition` to control that. * - * @return {Phaser.Display.Color} This Color object. + * @method Phaser.Cameras.Scene2D.BaseCamera#setScroll + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the Camera in the game world. + * @param {number} [y=x] - The y coordinate of the Camera in the game world. + * + * @return {this} This Camera instance. */ - randomGray: function (min, max) + setScroll: function (x, y) { - if (min === undefined) { min = 0; } - if (max === undefined) { max = 255; } + if (y === undefined) { y = x; } - var s = Math.floor(min + Math.random() * (max - min)); + this.scrollX = x; + this.scrollY = y; - return this.setTo(s, s, s); + return this; }, /** - * Increase the saturation of this Color by the percentage amount given. - * The saturation is the amount of the base color in the hue. + * Set the size of the Camera viewport. * - * @method Phaser.Display.Color#saturate - * @since 3.13.0 - * - * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. + * By default a Camera is the same size as the game, but can be made smaller via this method, + * allowing you to create mini-cam style effects by creating and positioning a smaller Camera + * viewport within your game. * - * @return {Phaser.Display.Color} This Color object. + * @method Phaser.Cameras.Scene2D.BaseCamera#setSize + * @since 3.0.0 + * + * @param {number} width - The width of the Camera viewport. + * @param {number} [height=width] - The height of the Camera viewport. + * + * @return {this} This Camera instance. */ - saturate: function (amount) + setSize: function (width, height) { - this.s += amount / 100; + if (height === undefined) { height = width; } + + this.width = width; + this.height = height; return this; }, /** - * Decrease the saturation of this Color by the percentage amount given. - * The saturation is the amount of the base color in the hue. + * This method sets the position and size of the Camera viewport in a single call. * - * @method Phaser.Display.Color#desaturate - * @since 3.13.0 - * - * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. + * If you're trying to change where the Camera is looking at in your game, then see + * the method `Camera.setScroll` instead. This method is for changing the viewport + * itself, not what the camera can see. * - * @return {Phaser.Display.Color} This Color object. + * By default a Camera is the same size as the game, but can be made smaller via this method, + * allowing you to create mini-cam style effects by creating and positioning a smaller Camera + * viewport within your game. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setViewport + * @since 3.0.0 + * + * @param {number} x - The top-left x coordinate of the Camera viewport. + * @param {number} y - The top-left y coordinate of the Camera viewport. + * @param {number} width - The width of the Camera viewport. + * @param {number} [height=width] - The height of the Camera viewport. + * + * @return {this} This Camera instance. */ - desaturate: function (amount) + setViewport: function (x, y, width, height) { - this.s -= amount / 100; + this.x = x; + this.y = y; + this.width = width; + this.height = height; return this; }, /** - * Increase the lightness of this Color by the percentage amount given. + * Set the zoom value of the Camera. * - * @method Phaser.Display.Color#lighten - * @since 3.13.0 - * - * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. + * Changing to a smaller value, such as 0.5, will cause the camera to 'zoom out'. + * Changing to a larger value, such as 2, will cause the camera to 'zoom in'. * - * @return {Phaser.Display.Color} This Color object. + * A value of 1 means 'no zoom' and is the default. + * + * Changing the zoom does not impact the Camera viewport in any way, it is only applied during rendering. + * + * As of Phaser 3.50 you can now set the horizontal and vertical zoom values independently. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setZoom + * @since 3.0.0 + * + * @param {number} [x=1] - The horizontal zoom value of the Camera. The minimum it can be is 0.001. + * @param {number} [y=x] - The vertical zoom value of the Camera. The minimum it can be is 0.001. + * + * @return {this} This Camera instance. */ - lighten: function (amount) + setZoom: function (x, y) { - this.v += amount / 100; + if (x === undefined) { x = 1; } + if (y === undefined) { y = x; } + + if (x === 0) + { + x = 0.001; + } + + if (y === 0) + { + y = 0.001; + } + + this.zoomX = x; + this.zoomY = y; return this; }, /** - * Decrease the lightness of this Color by the percentage amount given. + * Sets the mask to be applied to this Camera during rendering. * - * @method Phaser.Display.Color#darken - * @since 3.13.0 - * - * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. * - * @return {Phaser.Display.Color} This Color object. + * Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * If a mask is already set on this Camera it will be immediately replaced. + * + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setMask + * @since 3.17.0 + * + * @param {(Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask)} mask - The mask this Camera will use when rendering. + * @param {boolean} [fixedPosition=true] - Should the mask translate along with the Camera, or be fixed in place and not impacted by the Cameras transform? + * + * @return {this} This Camera instance. */ - darken: function (amount) + setMask: function (mask, fixedPosition) { - this.v -= amount / 100; + if (fixedPosition === undefined) { fixedPosition = true; } + + this.mask = mask; + + this._maskCamera = (fixedPosition) ? this.cameraManager.default : this; return this; }, /** - * Brighten this Color by the percentage amount given. + * Clears the mask that this Camera was using. * - * @method Phaser.Display.Color#brighten - * @since 3.13.0 - * - * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. + * @method Phaser.Cameras.Scene2D.BaseCamera#clearMask + * @since 3.17.0 * - * @return {Phaser.Display.Color} This Color object. + * @param {boolean} [destroyMask=false] - Destroy the mask before clearing it? + * + * @return {this} This Camera instance. */ - brighten: function (amount) + clearMask: function (destroyMask) { - var r = this.r; - var g = this.g; - var b = this.b; + if (destroyMask === undefined) { destroyMask = false; } - r = Math.max(0, Math.min(255, r - Math.round(255 * - (amount / 100)))); - g = Math.max(0, Math.min(255, g - Math.round(255 * - (amount / 100)))); - b = Math.max(0, Math.min(255, b - Math.round(255 * - (amount / 100)))); + if (destroyMask && this.mask) + { + this.mask.destroy(); + } - return this.setTo(r, g, b); + this.mask = null; + + return this; }, /** - * The color of this Color component, not including the alpha channel. + * Sets the visibility of this Camera. * - * @name Phaser.Display.Color#color - * @type {number} - * @readonly + * An invisible Camera will skip rendering and input tests of everything it can see. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setVisible + * @since 3.10.0 + * + * @param {boolean} value - The visible state of the Camera. + * + * @return {this} This Camera instance. + */ + + /** + * Returns an Object suitable for JSON storage containing all of the Camera viewport and rendering properties. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#toJSON * @since 3.0.0 + * + * @return {Phaser.Types.Cameras.Scene2D.JSONCamera} A well-formed object suitable for conversion to JSON. */ - color: { + toJSON: function () + { + var output = { + name: this.name, + x: this.x, + y: this.y, + width: this.width, + height: this.height, + zoom: this.zoom, + rotation: this.rotation, + roundPixels: this.roundPixels, + scrollX: this.scrollX, + scrollY: this.scrollY, + backgroundColor: this.backgroundColor.rgba + }; - get: function () + if (this.useBounds) { - return this._color; + output['bounds'] = { + x: this._bounds.x, + y: this._bounds.y, + width: this._bounds.width, + height: this._bounds.height + }; } + return output; }, /** - * The color of this Color component, including the alpha channel. + * Internal method called automatically by the Camera Manager. * - * @name Phaser.Display.Color#color32 - * @type {number} - * @readonly + * @method Phaser.Cameras.Scene2D.BaseCamera#update + * @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. */ - color32: { + update: function () + { + // NOOP + }, - get: function () + /** + * Set if this Camera is being used as a Scene Camera, or a Texture + * Camera. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#setIsSceneCamera + * @since 3.60.0 + * + * @param {boolean} value - Is this being used as a Scene Camera, or a Texture camera? + */ + setIsSceneCamera: function (value) + { + this.isSceneCamera = value; + + return this; + }, + + /** + * Internal method called automatically when the viewport changes. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#updateSystem + * @private + * @since 3.12.0 + */ + updateSystem: function () + { + if (!this.scaleManager || !this.isSceneCamera) { - return this._color32; + return; + } + + var custom = (this._x !== 0 || this._y !== 0 || this.scaleManager.width !== this._width || this.scaleManager.height !== this._height); + + var sceneManager = this.sceneManager; + + if (custom && !this._customViewport) + { + // We need a custom viewport for this Camera + sceneManager.customViewports++; + } + else if (!custom && this._customViewport) + { + // We're turning off a custom viewport for this Camera + sceneManager.customViewports--; } + this.dirty = true; + this._customViewport = custom; }, /** - * The color of this Color component as a string which can be used in CSS color values. + * Destroys this Camera instance and its internal properties and references. + * Once destroyed you cannot use this Camera again, even if re-added to a Camera Manager. * - * @name Phaser.Display.Color#rgba - * @type {string} - * @readonly + * This method is called automatically by `CameraManager.remove` if that methods `runDestroy` argument is `true`, which is the default. + * + * Unless you have a specific reason otherwise, always use `CameraManager.remove` and allow it to handle the camera destruction, + * rather than calling this method directly. + * + * @method Phaser.Cameras.Scene2D.BaseCamera#destroy + * @fires Phaser.Cameras.Scene2D.Events#DESTROY * @since 3.0.0 */ - rgba: { + destroy: function () + { + this.emit(Events.DESTROY, this); - get: function () + this.removeAllListeners(); + + this.matrix.destroy(); + + this.culledObjects = []; + + if (this._customViewport) { - return this._rgba; + // We're turning off a custom viewport for this Camera + this.sceneManager.customViewports--; } + this.renderList = []; + + this._bounds = null; + + this.scene = null; + this.scaleManager = null; + this.sceneManager = null; + this.cameraManager = null; }, /** - * The red color value, normalized to the range 0 to 1. + * The x position of the Camera viewport, relative to the top-left of the game canvas. + * The viewport is the area into which the camera renders. + * To adjust the position the camera is looking at in the game world, see the `scrollX` value. * - * @name Phaser.Display.Color#redGL + * @name Phaser.Cameras.Scene2D.BaseCamera#x * @type {number} * @since 3.0.0 */ - redGL: { + x: { get: function () { - return this.gl[0]; + return this._x; }, set: function (value) { - this.gl[0] = Math.min(Math.abs(value), 1); - - this.r = Math.floor(this.gl[0] * 255); - - this.update(true); + this._x = value; + this.updateSystem(); } }, /** - * The green color value, normalized to the range 0 to 1. + * The y position of the Camera viewport, relative to the top-left of the game canvas. + * The viewport is the area into which the camera renders. + * To adjust the position the camera is looking at in the game world, see the `scrollY` value. * - * @name Phaser.Display.Color#greenGL + * @name Phaser.Cameras.Scene2D.BaseCamera#y * @type {number} * @since 3.0.0 */ - greenGL: { + y: { get: function () { - return this.gl[1]; + return this._y; }, set: function (value) { - this.gl[1] = Math.min(Math.abs(value), 1); - - this.g = Math.floor(this.gl[1] * 255); - - this.update(true); + this._y = value; + this.updateSystem(); } }, /** - * The blue color value, normalized to the range 0 to 1. + * The width of the Camera viewport, in pixels. * - * @name Phaser.Display.Color#blueGL + * The viewport is the area into which the Camera renders. Setting the viewport does + * not restrict where the Camera can scroll to. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#width * @type {number} * @since 3.0.0 */ - blueGL: { + width: { get: function () { - return this.gl[2]; + return this._width; }, set: function (value) { - this.gl[2] = Math.min(Math.abs(value), 1); - - this.b = Math.floor(this.gl[2] * 255); - - this.update(true); + this._width = value; + this.updateSystem(); } }, /** - * The alpha color value, normalized to the range 0 to 1. + * The height of the Camera viewport, in pixels. * - * @name Phaser.Display.Color#alphaGL + * The viewport is the area into which the Camera renders. Setting the viewport does + * not restrict where the Camera can scroll to. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#height * @type {number} * @since 3.0.0 */ - alphaGL: { + height: { get: function () { - return this.gl[3]; + return this._height; }, set: function (value) { - this.gl[3] = Math.min(Math.abs(value), 1); - - this.a = Math.floor(this.gl[3] * 255); - - this.update(); + this._height = value; + this.updateSystem(); } }, /** - * The red color value, normalized to the range 0 to 255. + * The horizontal scroll position of this Camera. * - * @name Phaser.Display.Color#red + * Change this value to cause the Camera to scroll around your Scene. + * + * Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method, + * will automatically adjust the Camera scroll values accordingly. + * + * You can set the bounds within which the Camera can scroll via the `setBounds` method. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#scrollX * @type {number} + * @default 0 * @since 3.0.0 */ - red: { + scrollX: { get: function () { - return this.r; + return this._scrollX; }, set: function (value) { - value = Math.floor(Math.abs(value)); - - this.r = Math.min(value, 255); - - this.gl[0] = value / 255; - - this.update(true); + if (value !== this._scrollX) + { + this._scrollX = value; + this.dirty = true; + } } }, /** - * The green color value, normalized to the range 0 to 255. + * The vertical scroll position of this Camera. * - * @name Phaser.Display.Color#green + * Change this value to cause the Camera to scroll around your Scene. + * + * Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method, + * will automatically adjust the Camera scroll values accordingly. + * + * You can set the bounds within which the Camera can scroll via the `setBounds` method. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#scrollY * @type {number} + * @default 0 * @since 3.0.0 */ - green: { + scrollY: { get: function () { - return this.g; + return this._scrollY; }, set: function (value) { - value = Math.floor(Math.abs(value)); - - this.g = Math.min(value, 255); - - this.gl[1] = value / 255; - - this.update(true); + if (value !== this._scrollY) + { + this._scrollY = value; + this.dirty = true; + } } }, /** - * The blue color value, normalized to the range 0 to 255. + * The Camera zoom value. Change this value to zoom in, or out of, a Scene. * - * @name Phaser.Display.Color#blue + * A value of 0.5 would zoom the Camera out, so you can now see twice as much + * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel + * now takes up 2 pixels when rendered. + * + * Set to 1 to return to the default zoom level. + * + * Be careful to never set this value to zero. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#zoom * @type {number} + * @default 1 * @since 3.0.0 */ - blue: { + zoom: { get: function () { - return this.b; + return (this._zoomX + this._zoomY) / 2; }, set: function (value) { - value = Math.floor(Math.abs(value)); - - this.b = Math.min(value, 255); - - this.gl[2] = value / 255; + this._zoomX = value; + this._zoomY = value; - this.update(true); + this.dirty = true; } }, /** - * The alpha color value, normalized to the range 0 to 255. + * The Camera horizontal zoom value. Change this value to zoom in, or out of, a Scene. * - * @name Phaser.Display.Color#alpha + * A value of 0.5 would zoom the Camera out, so you can now see twice as much + * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel + * now takes up 2 pixels when rendered. + * + * Set to 1 to return to the default zoom level. + * + * Be careful to never set this value to zero. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#zoomX * @type {number} - * @since 3.0.0 + * @default 1 + * @since 3.50.0 */ - alpha: { + zoomX: { get: function () { - return this.a; + return this._zoomX; }, set: function (value) { - value = Math.floor(Math.abs(value)); - - this.a = Math.min(value, 255); - - this.gl[3] = value / 255; - - this.update(); + this._zoomX = value; + this.dirty = true; } }, /** - * The hue color value. A number between 0 and 1. - * This is the base color. + * The Camera vertical zoom value. Change this value to zoom in, or out of, a Scene. * - * @name Phaser.Display.Color#h + * A value of 0.5 would zoom the Camera out, so you can now see twice as much + * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel + * now takes up 2 pixels when rendered. + * + * Set to 1 to return to the default zoom level. + * + * Be careful to never set this value to zero. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#zoomY * @type {number} - * @since 3.13.0 + * @default 1 + * @since 3.50.0 */ - h: { + zoomY: { get: function () { - return this._h; + return this._zoomY; }, set: function (value) { - this._h = value; - - HSVToRGB(value, this._s, this._v, this); + this._zoomY = value; + this.dirty = true; } }, /** - * The saturation color value. A number between 0 and 1. - * This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white. + * The rotation of the Camera in radians. * - * @name Phaser.Display.Color#s + * Camera rotation always takes place based on the Camera viewport. By default, rotation happens + * in the center of the viewport. You can adjust this with the `originX` and `originY` properties. + * + * Rotation influences the rendering of _all_ Game Objects visible by this Camera. However, it does not + * rotate the Camera viewport itself, which always remains an axis-aligned rectangle. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#rotation * @type {number} - * @since 3.13.0 + * @private + * @default 0 + * @since 3.11.0 */ - s: { + rotation: { get: function () { - return this._s; + return this._rotation; }, set: function (value) { - this._s = value; + this._rotation = value; + this.dirty = true; + } - HSVToRGB(this._h, value, this._v, this); + }, + + /** + * The horizontal position of the center of the Camera's viewport, relative to the left of the game canvas. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#centerX + * @type {number} + * @readonly + * @since 3.10.0 + */ + centerX: { + + get: function () + { + return this.x + (0.5 * this.width); } }, /** - * The lightness color value. A number between 0 and 1. - * This controls how dark the color is. Where 1 is as bright as possible and 0 is black. + * The vertical position of the center of the Camera's viewport, relative to the top of the game canvas. * - * @name Phaser.Display.Color#v + * @name Phaser.Cameras.Scene2D.BaseCamera#centerY * @type {number} - * @since 3.13.0 + * @readonly + * @since 3.10.0 */ - v: { + centerY: { get: function () { - return this._v; - }, + return this.y + (0.5 * this.height); + } - set: function (value) + }, + + /** + * The displayed width of the camera viewport, factoring in the camera zoom level. + * + * If a camera has a viewport width of 800 and a zoom of 0.5 then its display width + * would be 1600, as it's displaying twice as many pixels as zoom level 1. + * + * Equally, a camera with a width of 800 and zoom of 2 would have a display width + * of 400 pixels. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#displayWidth + * @type {number} + * @readonly + * @since 3.11.0 + */ + displayWidth: { + + get: function () { - this._v = value; + return this.width / this.zoomX; + } - HSVToRGB(this._h, this._s, value, this); + }, + + /** + * The displayed height of the camera viewport, factoring in the camera zoom level. + * + * If a camera has a viewport height of 600 and a zoom of 0.5 then its display height + * would be 1200, as it's displaying twice as many pixels as zoom level 1. + * + * Equally, a camera with a height of 600 and zoom of 2 would have a display height + * of 300 pixels. + * + * @name Phaser.Cameras.Scene2D.BaseCamera#displayHeight + * @type {number} + * @readonly + * @since 3.11.0 + */ + displayHeight: { + + get: function () + { + return this.height / this.zoomY; } } }); -module.exports = Color; +module.exports = BaseCamera; /***/ }), -/* 39 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 47751: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji -// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl - -var Class = __webpack_require__(0); +var BaseCamera = __webpack_require__(51052); +var CenterOn = __webpack_require__(79993); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var Effects = __webpack_require__(53030); +var Events = __webpack_require__(89787); +var Linear = __webpack_require__(42798); +var Rectangle = __webpack_require__(74118); +var Vector2 = __webpack_require__(93736); /** * @classdesc - * A representation of a vector in 3D space. + * A Camera. * - * A three-component vector. + * The Camera is the way in which all games are rendered in Phaser. They provide a view into your game world, + * and can be positioned, rotated, zoomed and scrolled accordingly. * - * @class Vector3 - * @memberof Phaser.Math + * A Camera consists of two elements: The viewport and the scroll values. + * + * The viewport is the physical position and size of the Camera within your game. Cameras, by default, are + * created the same size as your game, but their position and size can be set to anything. This means if you + * wanted to create a camera that was 320x200 in size, positioned in the bottom-right corner of your game, + * you'd adjust the viewport to do that (using methods like `setViewport` and `setSize`). + * + * If you wish to change where the Camera is looking in your game, then you scroll it. You can do this + * via the properties `scrollX` and `scrollY` or the method `setScroll`. Scrolling has no impact on the + * viewport, and changing the viewport has no impact on the scrolling. + * + * By default a Camera will render all Game Objects it can see. You can change this using the `ignore` method, + * allowing you to filter Game Objects out on a per-Camera basis. + * + * A Camera also has built-in special effects including Fade, Flash and Camera Shake. + * + * @class Camera + * @memberof Phaser.Cameras.Scene2D * @constructor * @since 3.0.0 * - * @param {number} [x] - The x component. - * @param {number} [y] - The y component. - * @param {number} [z] - The z component. + * @extends Phaser.Cameras.Scene2D.BaseCamera + * @extends Phaser.GameObjects.Components.PostPipeline + * + * @param {number} x - The x position of the Camera, relative to the top-left of the game canvas. + * @param {number} y - The y position of the Camera, relative to the top-left of the game canvas. + * @param {number} width - The width of the Camera, in pixels. + * @param {number} height - The height of the Camera, in pixels. */ -var Vector3 = new Class({ +var Camera = new Class({ + + Extends: BaseCamera, + + Mixins: [ + Components.PostPipeline + ], initialize: - function Vector3 (x, y, z) + function Camera (x, y, width, height) { + BaseCamera.call(this, x, y, width, height); + + this.initPostPipeline(); + /** - * The x component of this Vector. + * Does this Camera allow the Game Objects it renders to receive input events? * - * @name Phaser.Math.Vector3#x - * @type {number} - * @default 0 + * @name Phaser.Cameras.Scene2D.Camera#inputEnabled + * @type {boolean} + * @default true * @since 3.0.0 */ - this.x = 0; + this.inputEnabled = true; /** - * The y component of this Vector. + * The Camera Fade effect handler. + * To fade this camera see the `Camera.fade` methods. * - * @name Phaser.Math.Vector3#y - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Cameras.Scene2D.Camera#fadeEffect + * @type {Phaser.Cameras.Scene2D.Effects.Fade} + * @since 3.5.0 */ - this.y = 0; + this.fadeEffect = new Effects.Fade(this); /** - * The z component of this Vector. + * The Camera Flash effect handler. + * To flash this camera see the `Camera.flash` method. * - * @name Phaser.Math.Vector3#z - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Cameras.Scene2D.Camera#flashEffect + * @type {Phaser.Cameras.Scene2D.Effects.Flash} + * @since 3.5.0 */ - this.z = 0; + this.flashEffect = new Effects.Flash(this); - if (typeof x === 'object') - { - this.x = x.x || 0; - this.y = x.y || 0; - this.z = x.z || 0; - } - else - { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - } + /** + * The Camera Shake effect handler. + * To shake this camera see the `Camera.shake` method. + * + * @name Phaser.Cameras.Scene2D.Camera#shakeEffect + * @type {Phaser.Cameras.Scene2D.Effects.Shake} + * @since 3.5.0 + */ + this.shakeEffect = new Effects.Shake(this); + + /** + * The Camera Pan effect handler. + * To pan this camera see the `Camera.pan` method. + * + * @name Phaser.Cameras.Scene2D.Camera#panEffect + * @type {Phaser.Cameras.Scene2D.Effects.Pan} + * @since 3.11.0 + */ + this.panEffect = new Effects.Pan(this); + + /** + * The Camera Rotate To effect handler. + * To rotate this camera see the `Camera.rotateTo` method. + * + * @name Phaser.Cameras.Scene2D.Camera#rotateToEffect + * @type {Phaser.Cameras.Scene2D.Effects.RotateTo} + * @since 3.23.0 + */ + this.rotateToEffect = new Effects.RotateTo(this); + + /** + * The Camera Zoom effect handler. + * To zoom this camera see the `Camera.zoom` method. + * + * @name Phaser.Cameras.Scene2D.Camera#zoomEffect + * @type {Phaser.Cameras.Scene2D.Effects.Zoom} + * @since 3.11.0 + */ + this.zoomEffect = new Effects.Zoom(this); + + /** + * The linear interpolation value to use when following a target. + * + * Can also be set via `setLerp` or as part of the `startFollow` call. + * + * The default values of 1 means the camera will instantly snap to the target coordinates. + * A lower value, such as 0.1 means the camera will more slowly track the target, giving + * a smooth transition. You can set the horizontal and vertical values independently, and also + * adjust this value in real-time during your game. + * + * Be sure to keep the value between 0 and 1. A value of zero will disable tracking on that axis. + * + * @name Phaser.Cameras.Scene2D.Camera#lerp + * @type {Phaser.Math.Vector2} + * @since 3.9.0 + */ + this.lerp = new Vector2(1, 1); + + /** + * The values stored in this property are subtracted from the Camera targets position, allowing you to + * offset the camera from the actual target x/y coordinates by this amount. + * Can also be set via `setFollowOffset` or as part of the `startFollow` call. + * + * @name Phaser.Cameras.Scene2D.Camera#followOffset + * @type {Phaser.Math.Vector2} + * @since 3.9.0 + */ + this.followOffset = new Vector2(); + + /** + * The Camera dead zone. + * + * The deadzone is only used when the camera is following a target. + * + * It defines a rectangular region within which if the target is present, the camera will not scroll. + * If the target moves outside of this area, the camera will begin scrolling in order to follow it. + * + * The `lerp` values that you can set for a follower target also apply when using a deadzone. + * + * You can directly set this property to be an instance of a Rectangle. Or, you can use the + * `setDeadzone` method for a chainable approach. + * + * The rectangle you provide can have its dimensions adjusted dynamically, however, please + * note that its position is updated every frame, as it is constantly re-centered on the cameras mid point. + * + * Calling `setDeadzone` with no arguments will reset an active deadzone, as will setting this property + * to `null`. + * + * @name Phaser.Cameras.Scene2D.Camera#deadzone + * @type {?Phaser.Geom.Rectangle} + * @since 3.11.0 + */ + this.deadzone = null; + + /** + * Internal follow target reference. + * + * @name Phaser.Cameras.Scene2D.Camera#_follow + * @type {?any} + * @private + * @default null + * @since 3.0.0 + */ + this._follow = null; }, /** - * Set this Vector to point up. + * Sets the Camera dead zone. * - * Sets the y component of the vector to 1, and the others to 0. + * The deadzone is only used when the camera is following a target. * - * @method Phaser.Math.Vector3#up - * @since 3.0.0 + * It defines a rectangular region within which if the target is present, the camera will not scroll. + * If the target moves outside of this area, the camera will begin scrolling in order to follow it. * - * @return {Phaser.Math.Vector3} This Vector3. + * The deadzone rectangle is re-positioned every frame so that it is centered on the mid-point + * of the camera. This allows you to use the object for additional game related checks, such as + * testing if an object is within it or not via a Rectangle.contains call. + * + * The `lerp` values that you can set for a follower target also apply when using a deadzone. + * + * Calling this method with no arguments will reset an active deadzone. + * + * @method Phaser.Cameras.Scene2D.Camera#setDeadzone + * @since 3.11.0 + * + * @param {number} [width] - The width of the deadzone rectangle in pixels. If not specified the deadzone is removed. + * @param {number} [height] - The height of the deadzone rectangle in pixels. + * + * @return {this} This Camera instance. */ - up: function () + setDeadzone: function (width, height) { - this.x = 0; - this.y = 1; - this.z = 0; + if (width === undefined) + { + this.deadzone = null; + } + else + { + if (this.deadzone) + { + this.deadzone.width = width; + this.deadzone.height = height; + } + else + { + this.deadzone = new Rectangle(0, 0, width, height); + } + + if (this._follow) + { + var originX = this.width / 2; + var originY = this.height / 2; + + var fx = this._follow.x - this.followOffset.x; + var fy = this._follow.y - this.followOffset.y; + + this.midPoint.set(fx, fy); + + this.scrollX = fx - originX; + this.scrollY = fy - originY; + } + + CenterOn(this.deadzone, this.midPoint.x, this.midPoint.y); + } return this; }, /** - * Sets the components of this Vector to be the `Math.min` result from the given vector. + * Fades the Camera in from the given color over the duration specified. * - * @method Phaser.Math.Vector3#min - * @since 3.50.0 + * @method Phaser.Cameras.Scene2D.Camera#fadeIn + * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_START + * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE + * @since 3.3.0 * - * @param {Phaser.Math.Vector3} v - The Vector3 to check the minimum values against. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. + * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. + * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. + * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - min: function (v) + fadeIn: function (duration, red, green, blue, callback, context) { - this.x = Math.min(this.x, v.x); - this.y = Math.min(this.y, v.y); - this.z = Math.min(this.z, v.z); - - return this; + return this.fadeEffect.start(false, duration, red, green, blue, true, callback, context); }, /** - * Sets the components of this Vector to be the `Math.max` result from the given vector. + * Fades the Camera out to the given color over the duration specified. + * This is an alias for Camera.fade that forces the fade to start, regardless of existing fades. * - * @method Phaser.Math.Vector3#max - * @since 3.50.0 + * @method Phaser.Cameras.Scene2D.Camera#fadeOut + * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_START + * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE + * @since 3.3.0 * - * @param {Phaser.Math.Vector3} v - The Vector3 to check the maximum values against. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. + * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. + * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. + * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - max: function (v) + fadeOut: function (duration, red, green, blue, callback, context) { - this.x = Math.max(this.x, v.x); - this.y = Math.max(this.y, v.y); - this.z = Math.max(this.z, v.z); - - return this; + return this.fadeEffect.start(true, duration, red, green, blue, true, callback, context); }, /** - * Make a clone of this Vector3. + * Fades the Camera from the given color to transparent over the duration specified. * - * @method Phaser.Math.Vector3#clone - * @since 3.0.0 + * @method Phaser.Cameras.Scene2D.Camera#fadeFrom + * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_START + * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE + * @since 3.5.0 * - * @return {Phaser.Math.Vector3} A new Vector3 object containing this Vectors values. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. + * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. + * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. + * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. + * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * + * @return {this} This Camera instance. */ - clone: function () + fadeFrom: function (duration, red, green, blue, force, callback, context) { - return new Vector3(this.x, this.y, this.z); + return this.fadeEffect.start(false, duration, red, green, blue, force, callback, context); }, /** - * Adds the two given Vector3s and sets the results into this Vector3. + * Fades the Camera from transparent to the given color over the duration specified. * - * @method Phaser.Math.Vector3#addVectors - * @since 3.50.0 + * @method Phaser.Cameras.Scene2D.Camera#fade + * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_START + * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE + * @since 3.0.0 * - * @param {Phaser.Math.Vector3} a - The first Vector to add. - * @param {Phaser.Math.Vector3} b - The second Vector to add. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. + * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. + * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. + * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. + * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - addVectors: function (a, b) + fade: function (duration, red, green, blue, force, callback, context) { - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; - - return this; + return this.fadeEffect.start(true, duration, red, green, blue, force, callback, context); }, /** - * Calculate the cross (vector) product of two given Vectors. + * Flashes the Camera by setting it to the given color immediately and then fading it away again quickly over the duration specified. * - * @method Phaser.Math.Vector3#crossVectors + * @method Phaser.Cameras.Scene2D.Camera#flash + * @fires Phaser.Cameras.Scene2D.Events#FLASH_START + * @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE * @since 3.0.0 * - * @param {Phaser.Math.Vector3} a - The first Vector to multiply. - * @param {Phaser.Math.Vector3} b - The second Vector to multiply. + * @param {number} [duration=250] - The duration of the effect in milliseconds. + * @param {number} [red=255] - The amount to fade the red channel towards. A value between 0 and 255. + * @param {number} [green=255] - The amount to fade the green channel towards. A value between 0 and 255. + * @param {number} [blue=255] - The amount to fade the blue channel towards. A value between 0 and 255. + * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. + * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - crossVectors: function (a, b) + flash: function (duration, red, green, blue, force, callback, context) { - var ax = a.x; - var ay = a.y; - var az = a.z; - var bx = b.x; - var by = b.y; - var bz = b.z; - - this.x = ay * bz - az * by; - this.y = az * bx - ax * bz; - this.z = ax * by - ay * bx; - - return this; + return this.flashEffect.start(duration, red, green, blue, force, callback, context); }, /** - * Check whether this Vector is equal to a given Vector. - * - * Performs a strict equality check against each Vector's components. + * Shakes the Camera by the given intensity over the duration specified. * - * @method Phaser.Math.Vector3#equals + * @method Phaser.Cameras.Scene2D.Camera#shake + * @fires Phaser.Cameras.Scene2D.Events#SHAKE_START + * @fires Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE * @since 3.0.0 * - * @param {Phaser.Math.Vector3} v - The Vector3 to compare against. + * @param {number} [duration=100] - The duration of the effect in milliseconds. + * @param {(number|Phaser.Math.Vector2)} [intensity=0.05] - The intensity of the shake. + * @param {boolean} [force=false] - Force the shake effect to start immediately, even if already running. + * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @return {boolean} True if the two vectors strictly match, otherwise false. + * @return {this} This Camera instance. */ - equals: function (v) + shake: function (duration, intensity, force, callback, context) { - return ((this.x === v.x) && (this.y === v.y) && (this.z === v.z)); + return this.shakeEffect.start(duration, intensity, force, callback, context); }, /** - * Copy the components of a given Vector into this Vector. + * This effect will scroll the Camera so that the center of its viewport finishes at the given destination, + * over the duration and with the ease specified. * - * @method Phaser.Math.Vector3#copy - * @since 3.0.0 + * @method Phaser.Cameras.Scene2D.Camera#pan + * @fires Phaser.Cameras.Scene2D.Events#PAN_START + * @fires Phaser.Cameras.Scene2D.Events#PAN_COMPLETE + * @since 3.11.0 * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} src - The Vector to copy the components from. + * @param {number} x - The destination x coordinate to scroll the center of the Camera viewport to. + * @param {number} y - The destination y coordinate to scroll the center of the Camera viewport to. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {(string|function)} [ease='Linear'] - The ease to use for the pan. Can be any of the Phaser Easing constants or a custom function. + * @param {boolean} [force=false] - Force the pan effect to start immediately, even if already running. + * @param {Phaser.Types.Cameras.Scene2D.CameraPanCallback} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, + * the current camera scroll x coordinate and the current camera scroll y coordinate. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - copy: function (src) + pan: function (x, y, duration, ease, force, callback, context) { - this.x = src.x; - this.y = src.y; - this.z = src.z || 0; - - return this; + return this.panEffect.start(x, y, duration, ease, force, callback, context); }, /** - * Set the `x`, `y`, and `z` components of this Vector to the given `x`, `y`, and `z` values. + * This effect will rotate the Camera so that the viewport finishes at the given angle in radians, + * over the duration and with the ease specified. * - * @method Phaser.Math.Vector3#set - * @since 3.0.0 + * @method Phaser.Cameras.Scene2D.Camera#rotateTo + * @since 3.23.0 * - * @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y and z components. - * @param {number} [y] - The y value to set for this Vector. - * @param {number} [z] - The z value to set for this Vector. + * @param {number} radians - The destination angle in radians to rotate the Camera viewport to. If the angle is positive then the rotation is clockwise else anticlockwise + * @param {boolean} [shortestPath=false] - If shortest path is set to true the camera will rotate in the quickest direction clockwise or anti-clockwise. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {(string|function)} [ease='Linear'] - The ease to use for the rotation. Can be any of the Phaser Easing constants or a custom function. + * @param {boolean} [force=false] - Force the rotation effect to start immediately, even if already running. + * @param {CameraRotateCallback} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, + * the current camera rotation angle in radians. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {Phaser.Cameras.Scene2D.Camera} This Camera instance. */ - set: function (x, y, z) + rotateTo: function (radians, shortestPath, duration, ease, force, callback, context) { - if (typeof x === 'object') - { - this.x = x.x || 0; - this.y = x.y || 0; - this.z = x.z || 0; - } - else - { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - } - - return this; + return this.rotateToEffect.start(radians, shortestPath, duration, ease, force, callback, context); }, /** - * Sets the components of this Vector3 from the position of the given Matrix4. + * This effect will zoom the Camera to the given scale, over the duration and with the ease specified. * - * @method Phaser.Math.Vector3#setFromMatrixPosition - * @since 3.50.0 + * @method Phaser.Cameras.Scene2D.Camera#zoomTo + * @fires Phaser.Cameras.Scene2D.Events#ZOOM_START + * @fires Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE + * @since 3.11.0 * - * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the position from. + * @param {number} zoom - The target Camera zoom value. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {(string|function)} [ease='Linear'] - The ease to use for the pan. Can be any of the Phaser Easing constants or a custom function. + * @param {boolean} [force=false] - Force the pan effect to start immediately, even if already running. + * @param {Phaser.Types.Cameras.Scene2D.CameraPanCallback} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, + * the current camera scroll x coordinate and the current camera scroll y coordinate. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - setFromMatrixPosition: function (m) + zoomTo: function (zoom, duration, ease, force, callback, context) { - return this.fromArray(m.val, 12); + return this.zoomEffect.start(zoom, duration, ease, force, callback, context); }, /** - * Sets the components of this Vector3 from the Matrix4 column specified. - * - * @method Phaser.Math.Vector3#setFromMatrixColumn - * @since 3.50.0 - * - * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the column from. - * @param {number} index - The column index. + * Internal preRender step. * - * @return {Phaser.Math.Vector3} This Vector3. + * @method Phaser.Cameras.Scene2D.Camera#preRender + * @protected + * @since 3.0.0 */ - setFromMatrixColumn: function (mat4, index) + preRender: function () { - return this.fromArray(mat4.val, index * 4); + this.renderList.length = 0; + + var width = this.width; + var height = this.height; + + var halfWidth = width * 0.5; + var halfHeight = height * 0.5; + + var zoom = this.zoom; + var matrix = this.matrix; + + var originX = width * this.originX; + var originY = height * this.originY; + + var follow = this._follow; + var deadzone = this.deadzone; + + var sx = this.scrollX; + var sy = this.scrollY; + + if (deadzone) + { + CenterOn(deadzone, this.midPoint.x, this.midPoint.y); + } + + var emitFollowEvent = false; + + if (this.roundPixels) + { + originX = Math.floor(originX); + originY = Math.floor(originY); + } + + if (follow && !this.panEffect.isRunning) + { + var lerp = this.lerp; + + var fx = follow.x - this.followOffset.x; + var fy = follow.y - this.followOffset.y; + + if (this.roundPixels) + { + fx = Math.floor(fx); + fy = Math.floor(fy); + } + + if (deadzone) + { + if (fx < deadzone.x) + { + sx = Linear(sx, sx - (deadzone.x - fx), lerp.x); + } + else if (fx > deadzone.right) + { + sx = Linear(sx, sx + (fx - deadzone.right), lerp.x); + } + + if (fy < deadzone.y) + { + sy = Linear(sy, sy - (deadzone.y - fy), lerp.y); + } + else if (fy > deadzone.bottom) + { + sy = Linear(sy, sy + (fy - deadzone.bottom), lerp.y); + } + } + else + { + sx = Linear(sx, fx - originX, lerp.x); + sy = Linear(sy, fy - originY, lerp.y); + } + + emitFollowEvent = true; + } + + if (this.useBounds) + { + sx = this.clampX(sx); + sy = this.clampY(sy); + } + + if (this.roundPixels) + { + sx = Math.floor(sx); + sy = Math.floor(sy); + } + + // Values are in pixels and not impacted by zooming the Camera + this.scrollX = sx; + this.scrollY = sy; + + var midX = sx + halfWidth; + var midY = sy + halfHeight; + + // The center of the camera, in world space, so taking zoom into account + // Basically the pixel value of what it's looking at in the middle of the cam + this.midPoint.set(midX, midY); + + var displayWidth = width / zoom; + var displayHeight = height / zoom; + + var vwx = midX - (displayWidth / 2); + var vwy = midY - (displayHeight / 2); + + if (this.roundPixels) + { + vwx = Math.floor(vwx); + vwy = Math.floor(vwy); + } + + this.worldView.setTo(vwx, vwy, displayWidth, displayHeight); + + matrix.applyITRS(Math.floor(this.x + originX), Math.floor(this.y + originY), this.rotation, zoom, zoom); + matrix.translate(-originX, -originY); + + this.shakeEffect.preRender(); + + if (emitFollowEvent) + { + this.emit(Events.FOLLOW_UPDATE, this, follow); + } }, /** - * Sets the components of this Vector3 from the given array, based on the offset. + * Sets the linear interpolation value to use when following a target. * - * Vector3.x = array[offset] - * Vector3.y = array[offset + 1] - * Vector3.z = array[offset + 2] + * The default values of 1 means the camera will instantly snap to the target coordinates. + * A lower value, such as 0.1 means the camera will more slowly track the target, giving + * a smooth transition. You can set the horizontal and vertical values independently, and also + * adjust this value in real-time during your game. * - * @method Phaser.Math.Vector3#fromArray - * @since 3.50.0 + * Be sure to keep the value between 0 and 1. A value of zero will disable tracking on that axis. * - * @param {number[]} array - The array of values to get this Vector from. - * @param {number} [offset=0] - The offset index into the array. + * @method Phaser.Cameras.Scene2D.Camera#setLerp + * @since 3.9.0 * - * @return {Phaser.Math.Vector3} This Vector3. + * @param {number} [x=1] - The amount added to the horizontal linear interpolation of the follow target. + * @param {number} [y=1] - The amount added to the vertical linear interpolation of the follow target. + * + * @return {this} This Camera instance. */ - fromArray: function (array, offset) + setLerp: function (x, y) { - if (offset === undefined) { offset = 0; } + if (x === undefined) { x = 1; } + if (y === undefined) { y = x; } - this.x = array[offset]; - this.y = array[offset + 1]; - this.z = array[offset + 2]; + this.lerp.set(x, y); return this; }, /** - * Add a given Vector to this Vector. Addition is component-wise. + * Sets the horizontal and vertical offset of the camera from its follow target. + * The values are subtracted from the targets position during the Cameras update step. * - * @method Phaser.Math.Vector3#add - * @since 3.0.0 + * @method Phaser.Cameras.Scene2D.Camera#setFollowOffset + * @since 3.9.0 * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector. + * @param {number} [x=0] - The horizontal offset from the camera follow target.x position. + * @param {number} [y=0] - The vertical offset from the camera follow target.y position. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - add: function (v) + setFollowOffset: function (x, y) { - this.x += v.x; - this.y += v.y; - this.z += v.z || 0; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + this.followOffset.set(x, y); return this; }, /** - * Add the given value to each component of this Vector. + * Sets the Camera to follow a Game Object. * - * @method Phaser.Math.Vector3#addScalar - * @since 3.50.0 + * When enabled the Camera will automatically adjust its scroll position to keep the target Game Object + * in its center. * - * @param {number} s - The amount to add to this Vector. + * You can set the linear interpolation value used in the follow code. + * Use low lerp values (such as 0.1) to automatically smooth the camera motion. * - * @return {Phaser.Math.Vector3} This Vector3. - */ - addScalar: function (s) - { - this.x += s; - this.y += s; - this.z += s; - - return this; - }, - - /** - * Add and scale a given Vector to this Vector. Addition is component-wise. + * If you find you're getting a slight "jitter" effect when following an object it's probably to do with sub-pixel + * rendering of the targets position. This can be rounded by setting the `roundPixels` argument to `true` to + * force full pixel rounding rendering. Note that this can still be broken if you have specified a non-integer zoom + * value on the camera. So be sure to keep the camera zoom to integers. * - * @method Phaser.Math.Vector3#addScale - * @since 3.50.0 + * @method Phaser.Cameras.Scene2D.Camera#startFollow + * @since 3.0.0 * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector. - * @param {number} scale - The amount to scale `v` by. + * @param {(Phaser.GameObjects.GameObject|object)} target - The target for the Camera to follow. + * @param {boolean} [roundPixels=false] - Round the camera position to whole integers to avoid sub-pixel rendering? + * @param {number} [lerpX=1] - A value between 0 and 1. This value specifies the amount of linear interpolation to use when horizontally tracking the target. The closer the value to 1, the faster the camera will track. + * @param {number} [lerpY=1] - A value between 0 and 1. This value specifies the amount of linear interpolation to use when vertically tracking the target. The closer the value to 1, the faster the camera will track. + * @param {number} [offsetX=0] - The horizontal offset from the camera follow target.x position. + * @param {number} [offsetY=0] - The vertical offset from the camera follow target.y position. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - addScale: function (v, scale) + startFollow: function (target, roundPixels, lerpX, lerpY, offsetX, offsetY) { - this.x += v.x * scale; - this.y += v.y * scale; - this.z += v.z * scale || 0; + if (roundPixels === undefined) { roundPixels = false; } + if (lerpX === undefined) { lerpX = 1; } + if (lerpY === undefined) { lerpY = lerpX; } + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = offsetX; } + + this._follow = target; + + this.roundPixels = roundPixels; + + lerpX = Clamp(lerpX, 0, 1); + lerpY = Clamp(lerpY, 0, 1); + + this.lerp.set(lerpX, lerpY); + + this.followOffset.set(offsetX, offsetY); + + var originX = this.width / 2; + var originY = this.height / 2; + + var fx = target.x - offsetX; + var fy = target.y - offsetY; + + this.midPoint.set(fx, fy); + + this.scrollX = fx - originX; + this.scrollY = fy - originY; + + if (this.useBounds) + { + this.scrollX = this.clampX(this.scrollX); + this.scrollY = this.clampY(this.scrollY); + } return this; }, /** - * Subtract the given Vector from this Vector. Subtraction is component-wise. + * Stops a Camera from following a Game Object, if previously set via `Camera.startFollow`. * - * @method Phaser.Math.Vector3#subtract + * @method Phaser.Cameras.Scene2D.Camera#stopFollow * @since 3.0.0 * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to subtract from this Vector. - * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - subtract: function (v) + stopFollow: function () { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z || 0; + this._follow = null; return this; }, /** - * Perform a component-wise multiplication between this Vector and the given Vector. - * - * Multiplies this Vector by the given Vector. + * Resets any active FX, such as a fade, flash or shake. Useful to call after a fade in order to + * remove the fade. * - * @method Phaser.Math.Vector3#multiply + * @method Phaser.Cameras.Scene2D.Camera#resetFX * @since 3.0.0 * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to multiply this Vector by. - * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera instance. */ - multiply: function (v) + resetFX: function () { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z || 1; + this.rotateToEffect.reset(); + this.panEffect.reset(); + this.shakeEffect.reset(); + this.flashEffect.reset(); + this.fadeEffect.reset(); return this; }, /** - * Scale this Vector by the given value. + * Internal method called automatically by the Camera Manager. * - * @method Phaser.Math.Vector3#scale + * @method Phaser.Cameras.Scene2D.Camera#update + * @protected * @since 3.0.0 * - * @param {number} scale - The value to scale this Vector by. - * - * @return {Phaser.Math.Vector3} This Vector3. + * @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. */ - scale: function (scale) + update: function (time, delta) { - if (isFinite(scale)) - { - this.x *= scale; - this.y *= scale; - this.z *= scale; - } - else + if (this.visible) { - this.x = 0; - this.y = 0; - this.z = 0; + this.rotateToEffect.update(time, delta); + this.panEffect.update(time, delta); + this.zoomEffect.update(time, delta); + this.shakeEffect.update(time, delta); + this.flashEffect.update(time, delta); + this.fadeEffect.update(time, delta); } - - return this; }, /** - * Perform a component-wise division between this Vector and the given Vector. + * Destroys this Camera instance. You rarely need to call this directly. * - * Divides this Vector by the given Vector. + * Called by the Camera Manager. If you wish to destroy a Camera please use `CameraManager.remove` as + * cameras are stored in a pool, ready for recycling later, and calling this directly will prevent that. * - * @method Phaser.Math.Vector3#divide + * @method Phaser.Cameras.Scene2D.Camera#destroy + * @fires Phaser.Cameras.Scene2D.Events#DESTROY * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to divide this Vector by. - * - * @return {Phaser.Math.Vector3} This Vector3. */ - divide: function (v) + destroy: function () { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z || 1; + this.resetFX(); - return this; - }, + BaseCamera.prototype.destroy.call(this); - /** - * Negate the `x`, `y` and `z` components of this Vector. - * - * @method Phaser.Math.Vector3#negate - * @since 3.0.0 - * - * @return {Phaser.Math.Vector3} This Vector3. - */ - negate: function () - { - this.x = -this.x; - this.y = -this.y; - this.z = -this.z; + this._follow = null; - return this; - }, + this.deadzone = null; + } - /** - * Calculate the distance between this Vector and the given Vector. - * - * @method Phaser.Math.Vector3#distance - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to. - * - * @return {number} The distance from this Vector to the given Vector. - */ - distance: function (v) - { - var dx = v.x - this.x; - var dy = v.y - this.y; - var dz = v.z - this.z || 0; +}); - return Math.sqrt(dx * dx + dy * dy + dz * dz); - }, +module.exports = Camera; - /** - * Calculate the distance between this Vector and the given Vector, squared. - * - * @method Phaser.Math.Vector3#distanceSq - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to. - * - * @return {number} The distance from this Vector to the given Vector, squared. - */ - distanceSq: function (v) - { - var dx = v.x - this.x; - var dy = v.y - this.y; - var dz = v.z - this.z || 0; - return dx * dx + dy * dy + dz * dz; - }, +/***/ }), - /** - * Calculate the length (or magnitude) of this Vector. - * - * @method Phaser.Math.Vector3#length - * @since 3.0.0 - * - * @return {number} The length of this Vector. - */ - length: function () +/***/ 62382: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Camera = __webpack_require__(47751); +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var PluginCache = __webpack_require__(91963); +var RectangleContains = __webpack_require__(94287); +var ScaleEvents = __webpack_require__(40444); +var SceneEvents = __webpack_require__(7599); + +/** + * @classdesc + * The Camera Manager is a plugin that belongs to a Scene and is responsible for managing all of the Scene Cameras. + * + * By default you can access the Camera Manager from within a Scene using `this.cameras`, although this can be changed + * in your game config. + * + * Create new Cameras using the `add` method. Or extend the Camera class with your own addition code and then add + * the new Camera in using the `addExisting` method. + * + * Cameras provide a view into your game world, and can be positioned, rotated, zoomed and scrolled accordingly. + * + * A Camera consists of two elements: The viewport and the scroll values. + * + * The viewport is the physical position and size of the Camera within your game. Cameras, by default, are + * created the same size as your game, but their position and size can be set to anything. This means if you + * wanted to create a camera that was 320x200 in size, positioned in the bottom-right corner of your game, + * you'd adjust the viewport to do that (using methods like `setViewport` and `setSize`). + * + * If you wish to change where the Camera is looking in your game, then you scroll it. You can do this + * via the properties `scrollX` and `scrollY` or the method `setScroll`. Scrolling has no impact on the + * viewport, and changing the viewport has no impact on the scrolling. + * + * By default a Camera will render all Game Objects it can see. You can change this using the `ignore` method, + * allowing you to filter Game Objects out on a per-Camera basis. The Camera Manager can manage up to 31 unique + * 'Game Object ignore capable' Cameras. Any Cameras beyond 31 that you create will all be given a Camera ID of + * zero, meaning that they cannot be used for Game Object exclusion. This means if you need your Camera to ignore + * Game Objects, make sure it's one of the first 31 created. + * + * A Camera also has built-in special effects including Fade, Flash, Camera Shake, Pan and Zoom. + * + * @class CameraManager + * @memberof Phaser.Cameras.Scene2D + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene that owns the Camera Manager plugin. + */ +var CameraManager = new Class({ + + initialize: + + function CameraManager (scene) { - var x = this.x; - var y = this.y; - var z = this.z; + /** + * The Scene that owns the Camera Manager plugin. + * + * @name Phaser.Cameras.Scene2D.CameraManager#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - return Math.sqrt(x * x + y * y + z * z); + /** + * A reference to the Scene.Systems handler for the Scene that owns the Camera Manager. + * + * @name Phaser.Cameras.Scene2D.CameraManager#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.systems = scene.sys; + + /** + * All Cameras created by, or added to, this Camera Manager, will have their `roundPixels` + * property set to match this value. By default it is set to match the value set in the + * game configuration, but can be changed at any point. Equally, individual cameras can + * also be changed as needed. + * + * @name Phaser.Cameras.Scene2D.CameraManager#roundPixels + * @type {boolean} + * @since 3.11.0 + */ + this.roundPixels = scene.sys.game.config.roundPixels; + + /** + * An Array of the Camera objects being managed by this Camera Manager. + * The Cameras are updated and rendered in the same order in which they appear in this array. + * Do not directly add or remove entries to this array. However, you can move the contents + * around the array should you wish to adjust the display order. + * + * @name Phaser.Cameras.Scene2D.CameraManager#cameras + * @type {Phaser.Cameras.Scene2D.Camera[]} + * @since 3.0.0 + */ + this.cameras = []; + + /** + * A handy reference to the 'main' camera. By default this is the first Camera the + * Camera Manager creates. You can also set it directly, or use the `makeMain` argument + * in the `add` and `addExisting` methods. It allows you to access it from your game: + * + * ```javascript + * var cam = this.cameras.main; + * ``` + * + * Also see the properties `camera1`, `camera2` and so on. + * + * @name Phaser.Cameras.Scene2D.CameraManager#main + * @type {Phaser.Cameras.Scene2D.Camera} + * @since 3.0.0 + */ + this.main; + + /** + * A default un-transformed Camera that doesn't exist on the camera list and doesn't + * count towards the total number of cameras being managed. It exists for other + * systems, as well as your own code, should they require a basic un-transformed + * camera instance from which to calculate a view matrix. + * + * @name Phaser.Cameras.Scene2D.CameraManager#default + * @type {Phaser.Cameras.Scene2D.Camera} + * @since 3.17.0 + */ + this.default; + + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + scene.sys.events.on(SceneEvents.START, this.start, this); }, /** - * Calculate the length of this Vector squared. - * - * @method Phaser.Math.Vector3#lengthSq - * @since 3.0.0 + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. * - * @return {number} The length of this Vector, squared. + * @method Phaser.Cameras.Scene2D.CameraManager#boot + * @private + * @listens Phaser.Scenes.Events#DESTROY + * @since 3.5.1 */ - lengthSq: function () + boot: function () { - var x = this.x; - var y = this.y; - var z = this.z; + var sys = this.systems; - return x * x + y * y + z * z; + if (sys.settings.cameras) + { + // We have cameras to create + this.fromJSON(sys.settings.cameras); + } + else + { + // Make one + this.add(); + } + + this.main = this.cameras[0]; + + // Create a default camera + this.default = new Camera(0, 0, sys.scale.width, sys.scale.height).setScene(this.scene); + + sys.game.scale.on(ScaleEvents.RESIZE, this.onResize, this); + + this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); }, /** - * Normalize this Vector. - * - * Makes the vector a unit length vector (magnitude of 1) in the same direction. - * - * @method Phaser.Math.Vector3#normalize - * @since 3.0.0 + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. * - * @return {Phaser.Math.Vector3} This Vector3. + * @method Phaser.Cameras.Scene2D.CameraManager#start + * @private + * @listens Phaser.Scenes.Events#UPDATE + * @listens Phaser.Scenes.Events#SHUTDOWN + * @since 3.5.0 */ - normalize: function () + start: function () { - var x = this.x; - var y = this.y; - var z = this.z; - var len = x * x + y * y + z * z; - - if (len > 0) + if (!this.main) { - len = 1 / Math.sqrt(len); + var sys = this.systems; - this.x = x * len; - this.y = y * len; - this.z = z * len; + if (sys.settings.cameras) + { + // We have cameras to create + this.fromJSON(sys.settings.cameras); + } + else + { + // Make one + this.add(); + } + + this.main = this.cameras[0]; } - return this; + var eventEmitter = this.systems.events; + + eventEmitter.on(SceneEvents.UPDATE, this.update, this); + eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * Calculate the dot product of this Vector and the given Vector. + * Adds a new Camera into the Camera Manager. The Camera Manager can support up to 31 different Cameras. * - * @method Phaser.Math.Vector3#dot - * @since 3.0.0 + * Each Camera has its own viewport, which controls the size of the Camera and its position within the canvas. * - * @param {Phaser.Math.Vector3} v - The Vector3 to dot product with this Vector3. + * Use the `Camera.scrollX` and `Camera.scrollY` properties to change where the Camera is looking, or the + * Camera methods such as `centerOn`. Cameras also have built in special effects, such as fade, flash, shake, + * pan and zoom. * - * @return {number} The dot product of this Vector and `v`. - */ - dot: function (v) - { - return this.x * v.x + this.y * v.y + this.z * v.z; - }, - - /** - * Calculate the cross (vector) product of this Vector (which will be modified) and the given Vector. + * By default Cameras are transparent and will render anything that they can see based on their `scrollX` + * and `scrollY` values. Game Objects can be set to be ignored by a Camera by using the `Camera.ignore` method. * - * @method Phaser.Math.Vector3#cross + * The Camera will have its `roundPixels` property set to whatever `CameraManager.roundPixels` is. You can change + * it after creation if required. + * + * See the Camera class documentation for more details. + * + * @method Phaser.Cameras.Scene2D.CameraManager#add * @since 3.0.0 * - * @param {Phaser.Math.Vector3} v - The Vector to cross product with. + * @param {number} [x=0] - The horizontal position of the Camera viewport. + * @param {number} [y=0] - The vertical position of the Camera viewport. + * @param {number} [width] - The width of the Camera viewport. If not given it'll be the game config size. + * @param {number} [height] - The height of the Camera viewport. If not given it'll be the game config size. + * @param {boolean} [makeMain=false] - Set this Camera as being the 'main' camera. This just makes the property `main` a reference to it. + * @param {string} [name=''] - The name of the Camera. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {Phaser.Cameras.Scene2D.Camera} The newly created Camera. */ - cross: function (v) + add: function (x, y, width, height, makeMain, name) { - var ax = this.x; - var ay = this.y; - var az = this.z; - var bx = v.x; - var by = v.y; - var bz = v.z; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.scene.sys.scale.width; } + if (height === undefined) { height = this.scene.sys.scale.height; } + if (makeMain === undefined) { makeMain = false; } + if (name === undefined) { name = ''; } - this.x = ay * bz - az * by; - this.y = az * bx - ax * bz; - this.z = ax * by - ay * bx; + var camera = new Camera(x, y, width, height); - return this; + camera.setName(name); + camera.setScene(this.scene); + camera.setRoundPixels(this.roundPixels); + + camera.id = this.getNextID(); + + this.cameras.push(camera); + + if (makeMain) + { + this.main = camera; + } + + return camera; }, /** - * Linearly interpolate between this Vector and the given Vector. + * Adds an existing Camera into the Camera Manager. * - * Interpolates this Vector towards the given Vector. + * The Camera should either be a `Phaser.Cameras.Scene2D.Camera` instance, or a class that extends from it. * - * @method Phaser.Math.Vector3#lerp + * The Camera will have its `roundPixels` property set to whatever `CameraManager.roundPixels` is. You can change + * it after addition if required. + * + * The Camera will be assigned an ID, which is used for Game Object exclusion and then added to the + * manager. As long as it doesn't already exist in the manager it will be added then returned. + * + * If this method returns `null` then the Camera already exists in this Camera Manager. + * + * @method Phaser.Cameras.Scene2D.CameraManager#addExisting * @since 3.0.0 * - * @param {Phaser.Math.Vector3} v - The Vector3 to interpolate towards. - * @param {number} [t=0] - The interpolation percentage, between 0 and 1. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to be added to the Camera Manager. + * @param {boolean} [makeMain=false] - Set this Camera as being the 'main' camera. This just makes the property `main` a reference to it. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {?Phaser.Cameras.Scene2D.Camera} The Camera that was added to the Camera Manager, or `null` if it couldn't be added. */ - lerp: function (v, t) + addExisting: function (camera, makeMain) { - if (t === undefined) { t = 0; } + if (makeMain === undefined) { makeMain = false; } - var ax = this.x; - var ay = this.y; - var az = this.z; + var index = this.cameras.indexOf(camera); - this.x = ax + t * (v.x - ax); - this.y = ay + t * (v.y - ay); - this.z = az + t * (v.z - az); + if (index === -1) + { + camera.id = this.getNextID(); - return this; - }, + camera.setRoundPixels(this.roundPixels); - /** - * Takes a Matrix3 and applies it to this Vector3. - * - * @method Phaser.Math.Vector3#applyMatrix3 - * @since 3.50.0 - * - * @param {Phaser.Math.Matrix3} mat3 - The Matrix3 to apply to this Vector3. - * - * @return {Phaser.Math.Vector3} This Vector3. - */ - applyMatrix3: function (mat3) - { - var x = this.x; - var y = this.y; - var z = this.z; - var m = mat3.val; + this.cameras.push(camera); - this.x = m[0] * x + m[3] * y + m[6] * z; - this.y = m[1] * x + m[4] * y + m[7] * z; - this.z = m[2] * x + m[5] * y + m[8] * z; + if (makeMain) + { + this.main = camera; + } - return this; + return camera; + } + + return null; }, /** - * Takes a Matrix4 and applies it to this Vector3. + * Gets the next available Camera ID number. * - * @method Phaser.Math.Vector3#applyMatrix4 - * @since 3.50.0 + * The Camera Manager supports up to 31 unique cameras, after which the ID returned will always be zero. + * You can create additional cameras beyond 31, but they cannot be used for Game Object exclusion. * - * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to apply to this Vector3. + * @method Phaser.Cameras.Scene2D.CameraManager#getNextID + * @private + * @since 3.11.0 * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {number} The next available Camera ID, or 0 if they're all already in use. */ - applyMatrix4: function (mat4) + getNextID: function () { - var x = this.x; - var y = this.y; - var z = this.z; - var m = mat4.val; + var cameras = this.cameras; - var w = 1 / (m[3] * x + m[7] * y + m[11] * z + m[15]); + var testID = 1; - this.x = (m[0] * x + m[4] * y + m[8] * z + m[12]) * w; - this.y = (m[1] * x + m[5] * y + m[9] * z + m[13]) * w; - this.z = (m[2] * x + m[6] * y + m[10] * z + m[14]) * w; + // Find the first free camera ID we can use - return this; + for (var t = 0; t < 32; t++) + { + var found = false; + + for (var i = 0; i < cameras.length; i++) + { + var camera = cameras[i]; + + if (camera && camera.id === testID) + { + found = true; + continue; + } + } + + if (found) + { + testID = testID << 1; + } + else + { + return testID; + } + } + + return 0; }, /** - * Transform this Vector with the given Matrix. + * Gets the total number of Cameras in this Camera Manager. * - * @method Phaser.Math.Vector3#transformMat3 - * @since 3.0.0 + * If the optional `isVisible` argument is set it will only count Cameras that are currently visible. * - * @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector3 with. + * @method Phaser.Cameras.Scene2D.CameraManager#getTotal + * @since 3.11.0 * - * @return {Phaser.Math.Vector3} This Vector3. + * @param {boolean} [isVisible=false] - Set the `true` to only include visible Cameras in the total. + * + * @return {number} The total number of Cameras in this Camera Manager. */ - transformMat3: function (mat) + getTotal: function (isVisible) { - var x = this.x; - var y = this.y; - var z = this.z; - var m = mat.val; + if (isVisible === undefined) { isVisible = false; } - this.x = x * m[0] + y * m[3] + z * m[6]; - this.y = x * m[1] + y * m[4] + z * m[7]; - this.z = x * m[2] + y * m[5] + z * m[8]; + var total = 0; - return this; + var cameras = this.cameras; + + for (var i = 0; i < cameras.length; i++) + { + var camera = cameras[i]; + + if (!isVisible || (isVisible && camera.visible)) + { + total++; + } + } + + return total; }, /** - * Transform this Vector with the given Matrix4. + * Populates this Camera Manager based on the given configuration object, or an array of config objects. * - * @method Phaser.Math.Vector3#transformMat4 + * See the `Phaser.Types.Cameras.Scene2D.CameraConfig` documentation for details of the object structure. + * + * @method Phaser.Cameras.Scene2D.CameraManager#fromJSON * @since 3.0.0 * - * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with. + * @param {(Phaser.Types.Cameras.Scene2D.CameraConfig|Phaser.Types.Cameras.Scene2D.CameraConfig[])} config - A Camera configuration object, or an array of them, to be added to this Camera Manager. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {this} This Camera Manager instance. */ - transformMat4: function (mat) + fromJSON: function (config) { - var x = this.x; - var y = this.y; - var z = this.z; - var m = mat.val; + if (!Array.isArray(config)) + { + config = [ config ]; + } - this.x = m[0] * x + m[4] * y + m[8] * z + m[12]; - this.y = m[1] * x + m[5] * y + m[9] * z + m[13]; - this.z = m[2] * x + m[6] * y + m[10] * z + m[14]; + var gameWidth = this.scene.sys.scale.width; + var gameHeight = this.scene.sys.scale.height; + + for (var i = 0; i < config.length; i++) + { + var cameraConfig = config[i]; + + var x = GetFastValue(cameraConfig, 'x', 0); + var y = GetFastValue(cameraConfig, 'y', 0); + var width = GetFastValue(cameraConfig, 'width', gameWidth); + var height = GetFastValue(cameraConfig, 'height', gameHeight); + + var camera = this.add(x, y, width, height); + + // Direct properties + camera.name = GetFastValue(cameraConfig, 'name', ''); + camera.zoom = GetFastValue(cameraConfig, 'zoom', 1); + camera.rotation = GetFastValue(cameraConfig, 'rotation', 0); + camera.scrollX = GetFastValue(cameraConfig, 'scrollX', 0); + camera.scrollY = GetFastValue(cameraConfig, 'scrollY', 0); + camera.roundPixels = GetFastValue(cameraConfig, 'roundPixels', false); + camera.visible = GetFastValue(cameraConfig, 'visible', true); + + // Background Color + + var backgroundColor = GetFastValue(cameraConfig, 'backgroundColor', false); + + if (backgroundColor) + { + camera.setBackgroundColor(backgroundColor); + } + + // Bounds + + var boundsConfig = GetFastValue(cameraConfig, 'bounds', null); + + if (boundsConfig) + { + var bx = GetFastValue(boundsConfig, 'x', 0); + var by = GetFastValue(boundsConfig, 'y', 0); + var bwidth = GetFastValue(boundsConfig, 'width', gameWidth); + var bheight = GetFastValue(boundsConfig, 'height', gameHeight); + + camera.setBounds(bx, by, bwidth, bheight); + } + } return this; }, /** - * Transforms the coordinates of this Vector3 with the given Matrix4. + * Gets a Camera based on its name. * - * @method Phaser.Math.Vector3#transformCoordinates + * Camera names are optional and don't have to be set, so this method is only of any use if you + * have given your Cameras unique names. + * + * @method Phaser.Cameras.Scene2D.CameraManager#getCamera * @since 3.0.0 * - * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with. + * @param {string} name - The name of the Camera. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {?Phaser.Cameras.Scene2D.Camera} The first Camera with a name matching the given string, otherwise `null`. */ - transformCoordinates: function (mat) + getCamera: function (name) { - var x = this.x; - var y = this.y; - var z = this.z; - var m = mat.val; - - var tx = (x * m[0]) + (y * m[4]) + (z * m[8]) + m[12]; - var ty = (x * m[1]) + (y * m[5]) + (z * m[9]) + m[13]; - var tz = (x * m[2]) + (y * m[6]) + (z * m[10]) + m[14]; - var tw = (x * m[3]) + (y * m[7]) + (z * m[11]) + m[15]; + var cameras = this.cameras; - this.x = tx / tw; - this.y = ty / tw; - this.z = tz / tw; + for (var i = 0; i < cameras.length; i++) + { + if (cameras[i].name === name) + { + return cameras[i]; + } + } - return this; + return null; }, /** - * Transform this Vector with the given Quaternion. + * Returns an array of all cameras below the given Pointer. * - * @method Phaser.Math.Vector3#transformQuat - * @since 3.0.0 + * The first camera in the array is the top-most camera in the camera list. * - * @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with. + * @method Phaser.Cameras.Scene2D.CameraManager#getCamerasBelowPointer + * @since 3.10.0 * - * @return {Phaser.Math.Vector3} This Vector3. + * @param {Phaser.Input.Pointer} pointer - The Pointer to check against. + * + * @return {Phaser.Cameras.Scene2D.Camera[]} An array of cameras below the Pointer. */ - transformQuat: function (q) + getCamerasBelowPointer: function (pointer) { - // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations - var x = this.x; - var y = this.y; - var z = this.z; - var qx = q.x; - var qy = q.y; - var qz = q.z; - var qw = q.w; + var cameras = this.cameras; - // calculate quat * vec - var ix = qw * x + qy * z - qz * y; - var iy = qw * y + qz * x - qx * z; - var iz = qw * z + qx * y - qy * x; - var iw = -qx * x - qy * y - qz * z; + var x = pointer.x; + var y = pointer.y; - // calculate result * inverse quat - this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; - this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; - this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + var output = []; - return this; + for (var i = 0; i < cameras.length; i++) + { + var camera = cameras[i]; + + if (camera.visible && camera.inputEnabled && RectangleContains(camera, x, y)) + { + // So the top-most camera is at the top of the search array + output.unshift(camera); + } + } + + return output; }, /** - * Multiplies this Vector3 by the specified matrix, applying a W divide. This is useful for projection, - * e.g. unprojecting a 2D point into 3D space. + * Removes the given Camera, or an array of Cameras, from this Camera Manager. * - * @method Phaser.Math.Vector3#project + * If found in the Camera Manager it will be immediately removed from the local cameras array. + * If also currently the 'main' camera, 'main' will be reset to be camera 0. + * + * The removed Cameras are automatically destroyed if the `runDestroy` argument is `true`, which is the default. + * If you wish to re-use the cameras then set this to `false`, but know that they will retain their references + * and internal data until destroyed or re-added to a Camera Manager. + * + * @method Phaser.Cameras.Scene2D.CameraManager#remove * @since 3.0.0 * - * @param {Phaser.Math.Matrix4} mat - The Matrix4 to multiply this Vector3 with. + * @param {(Phaser.Cameras.Scene2D.Camera|Phaser.Cameras.Scene2D.Camera[])} camera - The Camera, or an array of Cameras, to be removed from this Camera Manager. + * @param {boolean} [runDestroy=true] - Automatically call `Camera.destroy` on each Camera removed from this Camera Manager. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {number} The total number of Cameras removed. */ - project: function (mat) + remove: function (camera, runDestroy) { - var x = this.x; - var y = this.y; - var z = this.z; - var m = mat.val; + if (runDestroy === undefined) { runDestroy = true; } - var a00 = m[0]; - var a01 = m[1]; - var a02 = m[2]; - var a03 = m[3]; - var a10 = m[4]; - var a11 = m[5]; - var a12 = m[6]; - var a13 = m[7]; - var a20 = m[8]; - var a21 = m[9]; - var a22 = m[10]; - var a23 = m[11]; - var a30 = m[12]; - var a31 = m[13]; - var a32 = m[14]; - var a33 = m[15]; + if (!Array.isArray(camera)) + { + camera = [ camera ]; + } - var lw = 1 / (x * a03 + y * a13 + z * a23 + a33); + var total = 0; + var cameras = this.cameras; - this.x = (x * a00 + y * a10 + z * a20 + a30) * lw; - this.y = (x * a01 + y * a11 + z * a21 + a31) * lw; - this.z = (x * a02 + y * a12 + z * a22 + a32) * lw; + for (var i = 0; i < camera.length; i++) + { + var index = cameras.indexOf(camera[i]); - return this; + if (index !== -1) + { + if (runDestroy) + { + cameras[index].destroy(); + } + else + { + cameras[index].renderList = []; + } + + cameras.splice(index, 1); + + total++; + } + } + + if (!this.main && cameras[0]) + { + this.main = cameras[0]; + } + + return total; }, /** - * Multiplies this Vector3 by the given view and projection matrices. + * The internal render method. This is called automatically by the Scene and should not be invoked directly. * - * @method Phaser.Math.Vector3#projectViewMatrix - * @since 3.50.0 + * It will iterate through all local cameras and render them in turn, as long as they're visible and have + * an alpha level > 0. * - * @param {Phaser.Math.Matrix4} viewMatrix - A View Matrix. - * @param {Phaser.Math.Matrix4} projectionMatrix - A Projection Matrix. + * @method Phaser.Cameras.Scene2D.CameraManager#render + * @protected + * @since 3.0.0 * - * @return {Phaser.Math.Vector3} This Vector3. + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Renderer that will render the children to this camera. + * @param {Phaser.GameObjects.DisplayList} displayList - The Display List for the Scene. */ - projectViewMatrix: function (viewMatrix, projectionMatrix) + render: function (renderer, displayList) { - return this.applyMatrix4(viewMatrix).applyMatrix4(projectionMatrix); + var scene = this.scene; + var cameras = this.cameras; + + for (var i = 0; i < cameras.length; i++) + { + var camera = cameras[i]; + + if (camera.visible && camera.alpha > 0) + { + camera.preRender(); + + var visibleChildren = this.getVisibleChildren(displayList.getChildren(), camera); + + renderer.render(scene, visibleChildren, camera); + } + } }, /** - * Multiplies this Vector3 by the given inversed projection matrix and world matrix. + * Takes an array of Game Objects and a Camera and returns a new array + * containing only those Game Objects that pass the `willRender` test + * against the given Camera. * - * @method Phaser.Math.Vector3#unprojectViewMatrix + * @method Phaser.Cameras.Scene2D.CameraManager#getVisibleChildren * @since 3.50.0 * - * @param {Phaser.Math.Matrix4} projectionMatrix - An inversed Projection Matrix. - * @param {Phaser.Math.Matrix4} worldMatrix - A World View Matrix. + * @param {Phaser.GameObjects.GameObject[]} children - An array of Game Objects to be checked against the camera. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to filter the Game Objects against. * - * @return {Phaser.Math.Vector3} This Vector3. + * @return {Phaser.GameObjects.GameObject[]} A filtered list of only Game Objects within the Scene that will render against the given Camera. */ - unprojectViewMatrix: function (projectionMatrix, worldMatrix) + getVisibleChildren: function (children, camera) { - return this.applyMatrix4(projectionMatrix).applyMatrix4(worldMatrix); + return children.filter(function (child) + { + return child.willRender(camera); + }); }, /** - * Unproject this point from 2D space to 3D space. - * The point should have its x and y properties set to - * 2D screen space, and the z either at 0 (near plane) - * or 1 (far plane). The provided matrix is assumed to already - * be combined, i.e. projection * view * model. + * Resets this Camera Manager. * - * After this operation, this vector's (x, y, z) components will - * represent the unprojected 3D coordinate. + * This will iterate through all current Cameras, destroying them all, then it will reset the + * cameras array, reset the ID counter and create 1 new single camera using the default values. * - * @method Phaser.Math.Vector3#unproject + * @method Phaser.Cameras.Scene2D.CameraManager#resetAll * @since 3.0.0 * - * @param {Phaser.Math.Vector4} viewport - Screen x, y, width and height in pixels. - * @param {Phaser.Math.Matrix4} invProjectionView - Combined projection and view matrix. + * @return {Phaser.Cameras.Scene2D.Camera} The freshly created main Camera. + */ + resetAll: function () + { + for (var i = 0; i < this.cameras.length; i++) + { + this.cameras[i].destroy(); + } + + this.cameras = []; + + this.main = this.add(); + + return this.main; + }, + + /** + * The main update loop. Called automatically when the Scene steps. * - * @return {Phaser.Math.Vector3} This Vector3. + * @method Phaser.Cameras.Scene2D.CameraManager#update + * @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. */ - unproject: function (viewport, invProjectionView) + update: function (time, delta) { - var viewX = viewport.x; - var viewY = viewport.y; - var viewWidth = viewport.z; - var viewHeight = viewport.w; + for (var i = 0; i < this.cameras.length; i++) + { + this.cameras[i].update(time, delta); + } + }, - var x = this.x - viewX; - var y = (viewHeight - this.y - 1) - viewY; - var z = this.z; + /** + * The event handler that manages the `resize` event dispatched by the Scale Manager. + * + * @method Phaser.Cameras.Scene2D.CameraManager#onResize + * @since 3.18.0 + * + * @param {Phaser.Structs.Size} gameSize - The default Game Size object. This is the un-modified game dimensions. + * @param {Phaser.Structs.Size} baseSize - The base Size object. The game dimensions. The canvas width / height values match this. + */ + onResize: function (gameSize, baseSize, displaySize, previousWidth, previousHeight) + { + for (var i = 0; i < this.cameras.length; i++) + { + var cam = this.cameras[i]; - this.x = (2 * x) / viewWidth - 1; - this.y = (2 * y) / viewHeight - 1; - this.z = 2 * z - 1; + // if camera is at 0x0 and was the size of the previous game size, then we can safely assume it + // should be updated to match the new game size too - return this.project(invProjectionView); + if (cam._x === 0 && cam._y === 0 && cam._width === previousWidth && cam._height === previousHeight) + { + cam.setSize(baseSize.width, baseSize.height); + } + } }, /** - * Make this Vector the zero vector (0, 0, 0). + * Resizes all cameras to the given dimensions. * - * @method Phaser.Math.Vector3#reset + * @method Phaser.Cameras.Scene2D.CameraManager#resize + * @since 3.2.0 + * + * @param {number} width - The new width of the camera. + * @param {number} height - The new height of the camera. + */ + resize: function (width, height) + { + for (var i = 0; i < this.cameras.length; i++) + { + this.cameras[i].setSize(width, height); + } + }, + + /** + * The Scene that owns this plugin is shutting down. + * We need to kill and reset all internal properties as well as stop listening to Scene events. + * + * @method Phaser.Cameras.Scene2D.CameraManager#shutdown + * @private * @since 3.0.0 + */ + shutdown: function () + { + this.main = undefined; + + for (var i = 0; i < this.cameras.length; i++) + { + this.cameras[i].destroy(); + } + + this.cameras = []; + + var eventEmitter = this.systems.events; + + eventEmitter.off(SceneEvents.UPDATE, this.update, this); + eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); + }, + + /** + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. * - * @return {Phaser.Math.Vector3} This Vector3. + * @method Phaser.Cameras.Scene2D.CameraManager#destroy + * @private + * @since 3.0.0 */ - reset: function () + destroy: function () { - this.x = 0; - this.y = 0; - this.z = 0; + this.shutdown(); - return this; + this.default.destroy(); + + this.systems.events.off(SceneEvents.START, this.start, this); + this.systems.events.off(SceneEvents.DESTROY, this.destroy, this); + this.systems.game.scale.off(ScaleEvents.RESIZE, this.onResize, this); + + this.scene = null; + this.systems = null; } }); -/** - * A static zero Vector3 for use by reference. - * - * This constant is meant for comparison operations and should not be modified directly. - * - * @constant - * @name Phaser.Math.Vector3.ZERO - * @type {Phaser.Math.Vector3} - * @since 3.16.0 - */ -Vector3.ZERO = new Vector3(); +PluginCache.register('CameraManager', CameraManager, 'cameras'); -/** - * A static right Vector3 for use by reference. - * - * This constant is meant for comparison operations and should not be modified directly. - * - * @constant - * @name Phaser.Math.Vector3.RIGHT - * @type {Phaser.Math.Vector3} - * @since 3.16.0 - */ -Vector3.RIGHT = new Vector3(1, 0, 0); +module.exports = CameraManager; -/** - * A static left Vector3 for use by reference. - * - * This constant is meant for comparison operations and should not be modified directly. - * - * @constant - * @name Phaser.Math.Vector3.LEFT - * @type {Phaser.Math.Vector3} - * @since 3.16.0 - */ -Vector3.LEFT = new Vector3(-1, 0, 0); -/** - * A static up Vector3 for use by reference. - * - * This constant is meant for comparison operations and should not be modified directly. - * - * @constant - * @name Phaser.Math.Vector3.UP - * @type {Phaser.Math.Vector3} - * @since 3.16.0 - */ -Vector3.UP = new Vector3(0, -1, 0); +/***/ }), -/** - * A static down Vector3 for use by reference. - * - * This constant is meant for comparison operations and should not be modified directly. - * - * @constant - * @name Phaser.Math.Vector3.DOWN - * @type {Phaser.Math.Vector3} - * @since 3.16.0 - */ -Vector3.DOWN = new Vector3(0, 1, 0); +/***/ 92522: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * A static forward Vector3 for use by reference. - * - * This constant is meant for comparison operations and should not be modified directly. - * - * @constant - * @name Phaser.Math.Vector3.FORWARD - * @type {Phaser.Math.Vector3} - * @since 3.16.0 + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -Vector3.FORWARD = new Vector3(0, 0, 1); + +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(89787); /** - * A static back Vector3 for use by reference. + * @classdesc + * A Camera Fade effect. * - * This constant is meant for comparison operations and should not be modified directly. + * This effect will fade the camera viewport to the given color, over the duration specified. * - * @constant - * @name Phaser.Math.Vector3.BACK - * @type {Phaser.Math.Vector3} - * @since 3.16.0 - */ -Vector3.BACK = new Vector3(0, 0, -1); - -/** - * A static one Vector3 for use by reference. + * Only the camera viewport is faded. None of the objects it is displaying are impacted, i.e. their colors do + * not change. * - * This constant is meant for comparison operations and should not be modified directly. + * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, + * which is invoked each frame for the duration of the effect, if required. * - * @constant - * @name Phaser.Math.Vector3.ONE - * @type {Phaser.Math.Vector3} - * @since 3.16.0 + * @class Fade + * @memberof Phaser.Cameras.Scene2D.Effects + * @constructor + * @since 3.5.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. */ -Vector3.ONE = new Vector3(1, 1, 1); +var Fade = new Class({ -module.exports = Vector3; + initialize: + function Fade (camera) + { + /** + * The Camera this effect belongs to. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#camera + * @type {Phaser.Cameras.Scene2D.Camera} + * @readonly + * @since 3.5.0 + */ + this.camera = camera; -/***/ }), -/* 40 */ -/***/ (function(module, exports) { + /** + * Is this effect actively running? + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#isRunning + * @type {boolean} + * @readonly + * @default false + * @since 3.5.0 + */ + this.isRunning = false; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Has this effect finished running? + * + * This is different from `isRunning` because it remains set to `true` when the effect is over, + * until the effect is either reset or started again. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#isComplete + * @type {boolean} + * @readonly + * @default false + * @since 3.5.0 + */ + this.isComplete = false; -/** - * @namespace Phaser.Tilemaps.Formats - */ + /** + * The direction of the fade. + * `true` = fade out (transparent to color), `false` = fade in (color to transparent) + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#direction + * @type {boolean} + * @readonly + * @since 3.5.0 + */ + this.direction = true; -module.exports = { + /** + * The duration of the effect, in milliseconds. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#duration + * @type {number} + * @readonly + * @default 0 + * @since 3.5.0 + */ + this.duration = 0; - /** - * CSV Map Type - * - * @name Phaser.Tilemaps.Formats.CSV - * @type {number} - * @since 3.0.0 - */ - CSV: 0, + /** + * The value of the red color channel the camera will use for the fade effect. + * A value between 0 and 255. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#red + * @type {number} + * @private + * @since 3.5.0 + */ + this.red = 0; - /** - * Tiled JSON Map Type - * - * @name Phaser.Tilemaps.Formats.TILED_JSON - * @type {number} - * @since 3.0.0 - */ - TILED_JSON: 1, + /** + * The value of the green color channel the camera will use for the fade effect. + * A value between 0 and 255. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#green + * @type {number} + * @private + * @since 3.5.0 + */ + this.green = 0; - /** - * 2D Array Map Type - * - * @name Phaser.Tilemaps.Formats.ARRAY_2D - * @type {number} - * @since 3.0.0 - */ - ARRAY_2D: 2, + /** + * The value of the blue color channel the camera will use for the fade effect. + * A value between 0 and 255. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#blue + * @type {number} + * @private + * @since 3.5.0 + */ + this.blue = 0; + + /** + * The value of the alpha channel used during the fade effect. + * A value between 0 and 1. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#alpha + * @type {number} + * @private + * @since 3.5.0 + */ + this.alpha = 0; + + /** + * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#progress + * @type {number} + * @since 3.5.0 + */ + this.progress = 0; + + /** + * Effect elapsed timer. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#_elapsed + * @type {number} + * @private + * @since 3.5.0 + */ + this._elapsed = 0; + + /** + * This callback is invoked every frame for the duration of the effect. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#_onUpdate + * @type {?Phaser.Types.Cameras.Scene2D.CameraFadeCallback} + * @private + * @default null + * @since 3.5.0 + */ + this._onUpdate; + + /** + * On Complete callback scope. + * + * @name Phaser.Cameras.Scene2D.Effects.Fade#_onUpdateScope + * @type {any} + * @private + * @since 3.5.0 + */ + this._onUpdateScope; + }, /** - * Weltmeister (Impact.js) Map Type - * - * @name Phaser.Tilemaps.Formats.WELTMEISTER - * @type {number} - * @since 3.0.0 + * Fades the Camera to or from the given color over the duration specified. + * + * @method Phaser.Cameras.Scene2D.Effects.Fade#start + * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_START + * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_START + * @since 3.5.0 + * + * @param {boolean} [direction=true] - The direction of the fade. `true` = fade out (transparent to color), `false` = fade in (color to transparent) + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. + * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. + * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. + * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. + * @param {Phaser.Types.Cameras.Scene2D.CameraFadeCallback} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * + * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. */ - WELTMEISTER: 3 - -}; + start: function (direction, duration, red, green, blue, force, callback, context) + { + if (direction === undefined) { direction = true; } + if (duration === undefined) { duration = 1000; } + if (red === undefined) { red = 0; } + if (green === undefined) { green = 0; } + if (blue === undefined) { blue = 0; } + if (force === undefined) { force = false; } + if (callback === undefined) { callback = null; } + if (context === undefined) { context = this.camera.scene; } + if (!force && this.isRunning) + { + return this.camera; + } -/***/ }), -/* 41 */ -/***/ (function(module, exports, __webpack_require__) { + this.isRunning = true; + this.isComplete = false; + this.duration = duration; + this.direction = direction; + this.progress = 0; -/** - * The `Matter.Body` module contains methods for creating and manipulating body models. - * A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`. - * Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the module `Matter.Bodies`. - * - * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). - * @class Body - */ + this.red = red; + this.green = green; + this.blue = blue; + this.alpha = (direction) ? Number.MIN_VALUE : 1; -var Body = {}; + this._elapsed = 0; -module.exports = Body; + this._onUpdate = callback; + this._onUpdateScope = context; -var Vertices = __webpack_require__(64); -var Vector = __webpack_require__(83); -var Sleeping = __webpack_require__(165); -var Common = __webpack_require__(32); -var Bounds = __webpack_require__(84); -var Axes = __webpack_require__(271); + var eventName = (direction) ? Events.FADE_OUT_START : Events.FADE_IN_START; -(function() { + this.camera.emit(eventName, this.camera, this, duration, red, green, blue); - Body._inertiaScale = 4; - Body._nextCollidingGroupId = 1; - Body._nextNonCollidingGroupId = -1; - Body._nextCategory = 0x0001; + return this.camera; + }, /** - * Creates a new rigid body model. The options parameter is an object that specifies any properties you wish to override the defaults. - * All properties have default values, and many are pre-calculated automatically based on other properties. - * Vertices must be specified in clockwise order. - * See the properties section below for detailed information on what you can pass via the `options` object. - * @method create - * @param {} options - * @return {body} body + * The main update loop for this effect. Called automatically by the Camera. + * + * @method Phaser.Cameras.Scene2D.Effects.Fade#update + * @since 3.5.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. */ - Body.create = function(options) { - var defaults = { - id: Common.nextId(), - type: 'body', - label: 'Body', - parts: [], - plugin: {}, - angle: 0, - vertices: null, // Phaser change: no point calling fromPath if they pass in vertices anyway - position: { x: 0, y: 0 }, - force: { x: 0, y: 0 }, - torque: 0, - positionImpulse: { x: 0, y: 0 }, - previousPositionImpulse: { x: 0, y: 0 }, - constraintImpulse: { x: 0, y: 0, angle: 0 }, - totalContacts: 0, - speed: 0, - angularSpeed: 0, - velocity: { x: 0, y: 0 }, - angularVelocity: 0, - isSensor: false, - isStatic: false, - isSleeping: false, - motion: 0, - sleepThreshold: 60, - density: 0.001, - restitution: 0, - friction: 0.1, - frictionStatic: 0.5, - frictionAir: 0.01, - collisionFilter: { - category: 0x0001, - mask: 0xFFFFFFFF, - group: 0 - }, - slop: 0.05, - timeScale: 1, - events: null, - bounds: null, - chamfer: null, - circleRadius: 0, - positionPrev: null, - anglePrev: 0, - parent: null, - axes: null, - area: 0, - mass: 0, - inverseMass: 0, - inertia: 0, - inverseInertia: 0, - _original: null, - render: { - visible: true, - opacity: 1, - sprite: { - xOffset: 0, - yOffset: 0 - }, - fillColor: null, // custom Phaser property - fillOpacity: null, // custom Phaser property - lineColor: null, // custom Phaser property - lineOpacity: null, // custom Phaser property - lineThickness: null // custom Phaser property - }, - gameObject: null, // custom Phaser property - scale: { x: 1, y: 1 }, // custom Phaser property - centerOfMass: { x: 0, y: 0 }, // custom Phaser property (float, 0 - 1) - centerOffset: { x: 0, y: 0 }, // custom Phaser property (pixel values) - gravityScale: { x: 1, y: 1 }, // custom Phaser property - ignoreGravity: false, // custom Phaser property - ignorePointer: false, // custom Phaser property - onCollideCallback: null, // custom Phaser property - onCollideEndCallback: null, // custom Phaser property - onCollideActiveCallback: null, // custom Phaser property - onCollideWith: {} // custom Phaser property - }; - - if (!options.hasOwnProperty('position') && options.hasOwnProperty('vertices')) - { - options.position = Vertices.centre(options.vertices); - } - else if (!options.hasOwnProperty('vertices')) + update: function (time, delta) + { + if (!this.isRunning) { - defaults.vertices = Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'); + return; } - var body = Common.extend(defaults, options); + this._elapsed += delta; - _initProperties(body, options); + this.progress = Clamp(this._elapsed / this.duration, 0, 1); - // Helper function - body.setOnCollideWith = function (body, callback) + if (this._onUpdate) { - if (callback) - { - this.onCollideWith[body.id] = callback; - } - else - { - delete this.onCollideWith[body.id]; - } - - return this; + this._onUpdate.call(this._onUpdateScope, this.camera, this.progress); } - return body; - }; + if (this._elapsed < this.duration) + { + this.alpha = (this.direction) ? this.progress : 1 - this.progress; + } + else + { + this.alpha = (this.direction) ? 1 : 0; + this.effectComplete(); + } + }, /** - * Returns the next unique group index for which bodies will collide. - * If `isNonColliding` is `true`, returns the next unique group index for which bodies will _not_ collide. - * See `body.collisionFilter` for more information. - * @method nextGroup - * @param {bool} [isNonColliding=false] - * @return {Number} Unique group index + * Called internally by the Canvas Renderer. + * + * @method Phaser.Cameras.Scene2D.Effects.Fade#postRenderCanvas + * @since 3.5.0 + * + * @param {CanvasRenderingContext2D} ctx - The Canvas context to render to. + * + * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`. */ - Body.nextGroup = function(isNonColliding) { - if (isNonColliding) - return Body._nextNonCollidingGroupId--; + postRenderCanvas: function (ctx) + { + if (!this.isRunning && !this.isComplete) + { + return false; + } - return Body._nextCollidingGroupId++; - }; + var camera = this.camera; + + ctx.fillStyle = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',' + this.alpha + ')'; + ctx.fillRect(camera.x, camera.y, camera.width, camera.height); + + return true; + }, /** - * Returns the next unique category bitfield (starting after the initial default category `0x0001`). - * There are 32 available. See `body.collisionFilter` for more information. - * @method nextCategory - * @return {Number} Unique category bitfield + * Called internally by the WebGL Renderer. + * + * @method Phaser.Cameras.Scene2D.Effects.Fade#postRenderWebGL + * @since 3.5.0 + * + * @param {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} pipeline - The WebGL Pipeline to render to. Must provide the `drawFillRect` method. + * @param {function} getTintFunction - A function that will return the gl safe tint colors. + * + * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`. */ - Body.nextCategory = function() { - Body._nextCategory = Body._nextCategory << 1; - return Body._nextCategory; - }; + postRenderWebGL: function (pipeline, getTintFunction) + { + if (!this.isRunning && !this.isComplete) + { + return false; + } + + var camera = this.camera; + var red = this.red / 255; + var green = this.green / 255; + var blue = this.blue / 255; + + pipeline.drawFillRect( + camera.x, camera.y, camera.width, camera.height, + getTintFunction(blue, green, red, 1), + this.alpha + ); + + return true; + }, /** - * Initialises body properties. - * @method _initProperties - * @private - * @param {body} body - * @param {} [options] + * Called internally when the effect completes. + * + * @method Phaser.Cameras.Scene2D.Effects.Fade#effectComplete + * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE + * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE + * @since 3.5.0 */ - var _initProperties = function(body, options) { - options = options || {}; + effectComplete: function () + { + this._onUpdate = null; + this._onUpdateScope = null; - // init required properties (order is important) - Body.set(body, { - bounds: body.bounds || Bounds.create(body.vertices), - positionPrev: body.positionPrev || Vector.clone(body.position), - anglePrev: body.anglePrev || body.angle, - vertices: body.vertices, - parts: body.parts || [body], - isStatic: body.isStatic, - isSleeping: body.isSleeping, - parent: body.parent || body - }); + this.isRunning = false; + this.isComplete = true; - var bounds = body.bounds; + var eventName = (this.direction) ? Events.FADE_OUT_COMPLETE : Events.FADE_IN_COMPLETE; - Vertices.rotate(body.vertices, body.angle, body.position); - Axes.rotate(body.axes, body.angle); - Bounds.update(bounds, body.vertices, body.velocity); + this.camera.emit(eventName, this.camera, this); + }, - // allow options to override the automatically calculated properties - Body.set(body, { - axes: options.axes || body.axes, - area: options.area || body.area, - mass: options.mass || body.mass, - inertia: options.inertia || body.inertia - }); + /** + * Resets this camera effect. + * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. + * + * @method Phaser.Cameras.Scene2D.Effects.Fade#reset + * @since 3.5.0 + */ + reset: function () + { + this.isRunning = false; + this.isComplete = false; - if (body.parts.length === 1) - { - var centerOfMass = body.centerOfMass; - var centerOffset = body.centerOffset; - - var bodyWidth = bounds.max.x - bounds.min.x; - var bodyHeight = bounds.max.y - bounds.min.y; - - centerOfMass.x = -(bounds.min.x - body.position.x) / bodyWidth; - centerOfMass.y = -(bounds.min.y - body.position.y) / bodyHeight; - - centerOffset.x = bodyWidth * centerOfMass.x; - centerOffset.y = bodyHeight * centerOfMass.y; - } - }; + this._onUpdate = null; + this._onUpdateScope = null; + }, /** - * Given a property and a value (or map of), sets the property(s) on the body, using the appropriate setter functions if they exist. - * Prefer to use the actual setter functions in performance critical situations. - * @method set - * @param {body} body - * @param {} settings A property name (or map of properties and values) to set on the body. - * @param {} value The value to set if `settings` is a single property name. + * Destroys this effect, releasing it from the Camera. + * + * @method Phaser.Cameras.Scene2D.Effects.Fade#destroy + * @since 3.5.0 */ - Body.set = function(body, settings, value) { - var property; + destroy: function () + { + this.reset(); - if (typeof settings === 'string') { - property = settings; - settings = {}; - settings[property] = value; - } + this.camera = null; + } - for (property in settings) { - if (!Object.prototype.hasOwnProperty.call(settings, property)) - continue; +}); - value = settings[property]; - switch (property) { +module.exports = Fade; - case 'isStatic': - Body.setStatic(body, value); - break; - case 'isSleeping': - Sleeping.set(body, value); - break; - case 'mass': - Body.setMass(body, value); - break; - case 'density': - Body.setDensity(body, value); - break; - case 'inertia': - Body.setInertia(body, value); - break; - case 'vertices': - Body.setVertices(body, value); - break; - case 'position': - Body.setPosition(body, value); - break; - case 'angle': - Body.setAngle(body, value); - break; - case 'velocity': - Body.setVelocity(body, value); - break; - case 'angularVelocity': - Body.setAngularVelocity(body, value); - break; - case 'parts': - Body.setParts(body, value); - break; - case 'centre': - Body.setCentre(body, value); - break; - default: - body[property] = value; - } - } - }; - /** - * Sets the body as static, including isStatic flag and setting mass and inertia to Infinity. - * @method setStatic - * @param {body} body - * @param {bool} isStatic - */ - Body.setStatic = function(body, isStatic) { - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; - part.isStatic = isStatic; +/***/ }), - if (isStatic) { - part._original = { - restitution: part.restitution, - friction: part.friction, - mass: part.mass, - inertia: part.inertia, - density: part.density, - inverseMass: part.inverseMass, - inverseInertia: part.inverseInertia - }; +/***/ 22151: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - part.restitution = 0; - part.friction = 1; - part.mass = part.inertia = part.density = Infinity; - part.inverseMass = part.inverseInertia = 0; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - part.positionPrev.x = part.position.x; - part.positionPrev.y = part.position.y; - part.anglePrev = part.angle; - part.angularVelocity = 0; - part.speed = 0; - part.angularSpeed = 0; - part.motion = 0; - } else if (part._original) { - part.restitution = part._original.restitution; - part.friction = part._original.friction; - part.mass = part._original.mass; - part.inertia = part._original.inertia; - part.density = part._original.density; - part.inverseMass = part._original.inverseMass; - part.inverseInertia = part._original.inverseInertia; +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(89787); - part._original = null; - } - } - }; +/** + * @classdesc + * A Camera Flash effect. + * + * This effect will flash the camera viewport to the given color, over the duration specified. + * + * Only the camera viewport is flashed. None of the objects it is displaying are impacted, i.e. their colors do + * not change. + * + * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, + * which is invoked each frame for the duration of the effect, if required. + * + * @class Flash + * @memberof Phaser.Cameras.Scene2D.Effects + * @constructor + * @since 3.5.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. + */ +var Flash = new Class({ - /** - * Sets the mass of the body. Inverse mass, density and inertia are automatically updated to reflect the change. - * @method setMass - * @param {body} body - * @param {number} mass - */ - Body.setMass = function(body, mass) { - var moment = body.inertia / (body.mass / 6); - body.inertia = moment * (mass / 6); - body.inverseInertia = 1 / body.inertia; + initialize: - body.mass = mass; - body.inverseMass = 1 / body.mass; - body.density = body.mass / body.area; - }; + function Flash (camera) + { + /** + * The Camera this effect belongs to. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#camera + * @type {Phaser.Cameras.Scene2D.Camera} + * @readonly + * @since 3.5.0 + */ + this.camera = camera; - /** - * Sets the density of the body. Mass and inertia are automatically updated to reflect the change. - * @method setDensity - * @param {body} body - * @param {number} density - */ - Body.setDensity = function(body, density) { - Body.setMass(body, density * body.area); - body.density = density; - }; + /** + * Is this effect actively running? + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#isRunning + * @type {boolean} + * @readonly + * @default false + * @since 3.5.0 + */ + this.isRunning = false; - /** - * Sets the moment of inertia (i.e. second moment of area) of the body. - * Inverse inertia is automatically updated to reflect the change. Mass is not changed. - * @method setInertia - * @param {body} body - * @param {number} inertia - */ - Body.setInertia = function(body, inertia) { - body.inertia = inertia; - body.inverseInertia = 1 / body.inertia; - }; + /** + * The duration of the effect, in milliseconds. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#duration + * @type {number} + * @readonly + * @default 0 + * @since 3.5.0 + */ + this.duration = 0; - /** - * Sets the body's vertices and updates body properties accordingly, including inertia, area and mass (with respect to `body.density`). - * Vertices will be automatically transformed to be orientated around their centre of mass as the origin. - * They are then automatically translated to world space based on `body.position`. - * - * The `vertices` argument should be passed as an array of `Matter.Vector` points (or a `Matter.Vertices` array). - * Vertices must form a convex hull, concave hulls are not supported. - * - * @method setVertices - * @param {body} body - * @param {vector[]} vertices - */ - Body.setVertices = function(body, vertices) { - // change vertices - if (vertices[0].body === body) { - body.vertices = vertices; - } else { - body.vertices = Vertices.create(vertices, body); - } + /** + * The value of the red color channel the camera will use for the flash effect. + * A value between 0 and 255. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#red + * @type {number} + * @private + * @since 3.5.0 + */ + this.red = 0; - // update properties - body.axes = Axes.fromVertices(body.vertices); - body.area = Vertices.area(body.vertices); - Body.setMass(body, body.density * body.area); + /** + * The value of the green color channel the camera will use for the flash effect. + * A value between 0 and 255. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#green + * @type {number} + * @private + * @since 3.5.0 + */ + this.green = 0; - // orient vertices around the centre of mass at origin (0, 0) - var centre = Vertices.centre(body.vertices); - Vertices.translate(body.vertices, centre, -1); + /** + * The value of the blue color channel the camera will use for the flash effect. + * A value between 0 and 255. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#blue + * @type {number} + * @private + * @since 3.5.0 + */ + this.blue = 0; - // update inertia while vertices are at origin (0, 0) - Body.setInertia(body, Body._inertiaScale * Vertices.inertia(body.vertices, body.mass)); + /** + * The value of the alpha channel used during the flash effect. + * A value between 0 and 1. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#alpha + * @type {number} + * @since 3.5.0 + */ + this.alpha = 1; - // update geometry - Vertices.translate(body.vertices, body.position); + /** + * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#progress + * @type {number} + * @since 3.5.0 + */ + this.progress = 0; - Bounds.update(body.bounds, body.vertices, body.velocity); - }; + /** + * Effect elapsed timer. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#_elapsed + * @type {number} + * @private + * @since 3.5.0 + */ + this._elapsed = 0; + + /** + * This is an internal copy of the initial value of `this.alpha`, used to calculate the current alpha value of the fade effect. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#_alpha + * @type {number} + * @private + * @readonly + * @since 3.60.0 + */ + this._alpha; + + /** + * This callback is invoked every frame for the duration of the effect. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#_onUpdate + * @type {?Phaser.Types.Cameras.Scene2D.CameraFlashCallback} + * @private + * @default null + * @since 3.5.0 + */ + this._onUpdate; + + /** + * On Complete callback scope. + * + * @name Phaser.Cameras.Scene2D.Effects.Flash#_onUpdateScope + * @type {any} + * @private + * @since 3.5.0 + */ + this._onUpdateScope; + }, /** - * Sets the parts of the `body` and updates mass, inertia and centroid. - * Each part will have its parent set to `body`. - * By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.` - * Note that this method will ensure that the first part in `body.parts` will always be the `body`. - * @method setParts - * @param {body} body - * @param [body] parts - * @param {bool} [autoHull=true] + * Flashes the Camera to or from the given color over the duration specified. + * + * @method Phaser.Cameras.Scene2D.Effects.Flash#start + * @fires Phaser.Cameras.Scene2D.Events#FLASH_START + * @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE + * @since 3.5.0 + * + * @param {number} [duration=250] - The duration of the effect in milliseconds. + * @param {number} [red=255] - The amount to flash the red channel towards. A value between 0 and 255. + * @param {number} [green=255] - The amount to flash the green channel towards. A value between 0 and 255. + * @param {number} [blue=255] - The amount to flash the blue channel towards. A value between 0 and 255. + * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. + * @param {Phaser.Types.Cameras.Scene2D.CameraFlashCallback} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * + * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. */ - Body.setParts = function(body, parts, autoHull) { - var i; - - // add all the parts, ensuring that the first part is always the parent body - parts = parts.slice(0); - body.parts.length = 0; - body.parts.push(body); - body.parent = body; + start: function (duration, red, green, blue, force, callback, context) + { + if (duration === undefined) { duration = 250; } + if (red === undefined) { red = 255; } + if (green === undefined) { green = 255; } + if (blue === undefined) { blue = 255; } + if (force === undefined) { force = false; } + if (callback === undefined) { callback = null; } + if (context === undefined) { context = this.camera.scene; } - for (i = 0; i < parts.length; i++) { - var part = parts[i]; - if (part !== body) { - part.parent = body; - body.parts.push(part); - } + if (!force && this.isRunning) + { + return this.camera; } - if (body.parts.length === 1) - return; + this.isRunning = true; + this.duration = duration; + this.progress = 0; - autoHull = typeof autoHull !== 'undefined' ? autoHull : true; + this.red = red; + this.green = green; + this.blue = blue; - // find the convex hull of all parts to set on the parent body - if (autoHull) { - var vertices = []; - for (i = 0; i < parts.length; i++) { - vertices = vertices.concat(parts[i].vertices); - } + this._alpha = this.alpha; + this._elapsed = 0; - Vertices.clockwiseSort(vertices); + this._onUpdate = callback; + this._onUpdateScope = context; - var hull = Vertices.hull(vertices), - hullCentre = Vertices.centre(hull); + this.camera.emit(Events.FLASH_START, this.camera, this, duration, red, green, blue); - Body.setVertices(body, hull); - Vertices.translate(body.vertices, hullCentre); + return this.camera; + }, + + /** + * The main update loop for this effect. Called automatically by the Camera. + * + * @method Phaser.Cameras.Scene2D.Effects.Flash#update + * @since 3.5.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.isRunning) + { + return; } - // sum the properties of all compound parts of the parent body - var total = Body._totalProperties(body); + this._elapsed += delta; - // Phaser addition - var cx = total.centre.x; - var cy = total.centre.y; + this.progress = Clamp(this._elapsed / this.duration, 0, 1); - var bounds = body.bounds; - var centerOfMass = body.centerOfMass; - var centerOffset = body.centerOffset; + if (this._onUpdate) + { + this._onUpdate.call(this._onUpdateScope, this.camera, this.progress); + } - Bounds.update(bounds, body.vertices, body.velocity); + if (this._elapsed < this.duration) + { + this.alpha = this._alpha * (1 - this.progress); + } + else + { + this.effectComplete(); + } + }, - centerOfMass.x = -(bounds.min.x - cx) / (bounds.max.x - bounds.min.x); - centerOfMass.y = -(bounds.min.y - cy) / (bounds.max.y - bounds.min.y); + /** + * Called internally by the Canvas Renderer. + * + * @method Phaser.Cameras.Scene2D.Effects.Flash#postRenderCanvas + * @since 3.5.0 + * + * @param {CanvasRenderingContext2D} ctx - The Canvas context to render to. + * + * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`. + */ + postRenderCanvas: function (ctx) + { + if (!this.isRunning) + { + return false; + } - centerOffset.x = cx; - centerOffset.y = cy; + var camera = this.camera; - body.area = total.area; - body.parent = body; - body.position.x = cx; - body.position.y = cy; - body.positionPrev.x = cx; - body.positionPrev.y = cy; + ctx.fillStyle = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',' + this.alpha + ')'; + ctx.fillRect(camera.x, camera.y, camera.width, camera.height); - Body.setMass(body, total.mass); - Body.setInertia(body, total.inertia); - Body.setPosition(body, total.centre); - }; + return true; + }, /** - * Set the centre of mass of the body. - * The `centre` is a vector in world-space unless `relative` is set, in which case it is a translation. - * The centre of mass is the point the body rotates about and can be used to simulate non-uniform density. - * This is equal to moving `body.position` but not the `body.vertices`. - * Invalid if the `centre` falls outside the body's convex hull. - * @method setCentre - * @param {body} body - * @param {vector} centre - * @param {bool} relative + * Called internally by the WebGL Renderer. + * + * @method Phaser.Cameras.Scene2D.Effects.Flash#postRenderWebGL + * @since 3.5.0 + * + * @param {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} pipeline - The WebGL Pipeline to render to. Must provide the `drawFillRect` method. + * @param {function} getTintFunction - A function that will return the gl safe tint colors. + * + * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`. */ - Body.setCentre = function(body, centre, relative) { - if (!relative) { - body.positionPrev.x = centre.x - (body.position.x - body.positionPrev.x); - body.positionPrev.y = centre.y - (body.position.y - body.positionPrev.y); - body.position.x = centre.x; - body.position.y = centre.y; - } else { - body.positionPrev.x += centre.x; - body.positionPrev.y += centre.y; - body.position.x += centre.x; - body.position.y += centre.y; + postRenderWebGL: function (pipeline, getTintFunction) + { + if (!this.isRunning) + { + return false; } - }; - /** - * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged. - * @method setPosition - * @param {body} body - * @param {vector} position - */ - Body.setPosition = function(body, position) { - var delta = Vector.sub(position, body.position); - body.positionPrev.x += delta.x; - body.positionPrev.y += delta.y; + var camera = this.camera; + var red = this.red / 255; + var green = this.green / 255; + var blue = this.blue / 255; - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; - part.position.x += delta.x; - part.position.y += delta.y; - Vertices.translate(part.vertices, delta); - Bounds.update(part.bounds, part.vertices, body.velocity); - } - }; + pipeline.drawFillRect( + camera.x, camera.y, camera.width, camera.height, + getTintFunction(blue, green, red, 1), + this.alpha + ); + + return true; + }, /** - * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged. - * @method setAngle - * @param {body} body - * @param {number} angle + * Called internally when the effect completes. + * + * @method Phaser.Cameras.Scene2D.Effects.Flash#effectComplete + * @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE + * @since 3.5.0 */ - Body.setAngle = function(body, angle) { - var delta = angle - body.angle; - body.anglePrev += delta; + effectComplete: function () + { + this.alpha = this._alpha; + this._onUpdate = null; + this._onUpdateScope = null; - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; - part.angle += delta; - Vertices.rotate(part.vertices, delta, body.position); - Axes.rotate(part.axes, delta); - Bounds.update(part.bounds, part.vertices, body.velocity); - if (i > 0) { - Vector.rotateAbout(part.position, delta, body.position, part.position); - } - } - }; + this.isRunning = false; - /** - * Sets the linear velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. - * @method setVelocity - * @param {body} body - * @param {vector} velocity - */ - Body.setVelocity = function(body, velocity) { - body.positionPrev.x = body.position.x - velocity.x; - body.positionPrev.y = body.position.y - velocity.y; - body.velocity.x = velocity.x; - body.velocity.y = velocity.y; - body.speed = Vector.magnitude(body.velocity); - }; + this.camera.emit(Events.FLASH_COMPLETE, this.camera, this); + }, /** - * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. - * @method setAngularVelocity - * @param {body} body - * @param {number} velocity + * Resets this camera effect. + * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. + * + * @method Phaser.Cameras.Scene2D.Effects.Flash#reset + * @since 3.5.0 */ - Body.setAngularVelocity = function(body, velocity) { - body.anglePrev = body.angle - velocity; - body.angularVelocity = velocity; - body.angularSpeed = Math.abs(body.angularVelocity); - }; + reset: function () + { + this.isRunning = false; - /** - * Moves a body by a given vector relative to its current position, without imparting any velocity. - * @method translate - * @param {body} body - * @param {vector} translation - */ - Body.translate = function(body, translation) { - Body.setPosition(body, Vector.add(body.position, translation)); - }; + this._onUpdate = null; + this._onUpdateScope = null; + }, /** - * Rotates a body by a given angle relative to its current angle, without imparting any angular velocity. - * @method rotate - * @param {body} body - * @param {number} rotation - * @param {vector} [point] + * Destroys this effect, releasing it from the Camera. + * + * @method Phaser.Cameras.Scene2D.Effects.Flash#destroy + * @since 3.5.0 */ - Body.rotate = function(body, rotation, point) { - if (!point) { - Body.setAngle(body, body.angle + rotation); - } else { - var cos = Math.cos(rotation), - sin = Math.sin(rotation), - dx = body.position.x - point.x, - dy = body.position.y - point.y; - - Body.setPosition(body, { - x: point.x + (dx * cos - dy * sin), - y: point.y + (dx * sin + dy * cos) - }); + destroy: function () + { + this.reset(); - Body.setAngle(body, body.angle + rotation); - } - }; + this.camera = null; + } - /** - * Scales the body, including updating physical properties (mass, area, axes, inertia), from a world-space point (default is body centre). - * @method scale - * @param {body} body - * @param {number} scaleX - * @param {number} scaleY - * @param {vector} [point] - */ - Body.scale = function(body, scaleX, scaleY, point) { - var totalArea = 0, - totalInertia = 0; +}); - point = point || body.position; +module.exports = Flash; - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; - part.scale.x = scaleX; - part.scale.y = scaleY; +/***/ }), - // scale vertices - Vertices.scale(part.vertices, scaleX, scaleY, point); +/***/ 37551: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // update properties - part.axes = Axes.fromVertices(part.vertices); - part.area = Vertices.area(part.vertices); - Body.setMass(part, body.density * part.area); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // update inertia (requires vertices to be at origin) - Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y }); - Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass)); - Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y }); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var EaseMap = __webpack_require__(35060); +var Events = __webpack_require__(89787); +var Vector2 = __webpack_require__(93736); - if (i > 0) { - totalArea += part.area; - totalInertia += part.inertia; - } +/** + * @classdesc + * A Camera Pan effect. + * + * This effect will scroll the Camera so that the center of its viewport finishes at the given destination, + * over the duration and with the ease specified. + * + * Only the camera scroll is moved. None of the objects it is displaying are impacted, i.e. their positions do + * not change. + * + * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, + * which is invoked each frame for the duration of the effect if required. + * + * @class Pan + * @memberof Phaser.Cameras.Scene2D.Effects + * @constructor + * @since 3.11.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. + */ +var Pan = new Class({ - // scale position - part.position.x = point.x + (part.position.x - point.x) * scaleX; - part.position.y = point.y + (part.position.y - point.y) * scaleY; + initialize: - // update bounds - Bounds.update(part.bounds, part.vertices, body.velocity); - } + function Pan (camera) + { + /** + * The Camera this effect belongs to. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#camera + * @type {Phaser.Cameras.Scene2D.Camera} + * @readonly + * @since 3.11.0 + */ + this.camera = camera; - // handle parent body - if (body.parts.length > 1) { - body.area = totalArea; + /** + * Is this effect actively running? + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#isRunning + * @type {boolean} + * @readonly + * @default false + * @since 3.11.0 + */ + this.isRunning = false; - if (!body.isStatic) { - Body.setMass(body, body.density * totalArea); - Body.setInertia(body, totalInertia); - } - } + /** + * The duration of the effect, in milliseconds. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#duration + * @type {number} + * @readonly + * @default 0 + * @since 3.11.0 + */ + this.duration = 0; - // handle circles - if (body.circleRadius) { - if (scaleX === scaleY) { - body.circleRadius *= scaleX; - } else { - // body is no longer a circle - body.circleRadius = null; - } - } - }; + /** + * The starting scroll coordinates to pan the camera from. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#source + * @type {Phaser.Math.Vector2} + * @since 3.11.0 + */ + this.source = new Vector2(); + + /** + * The constantly updated value based on zoom. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#current + * @type {Phaser.Math.Vector2} + * @since 3.11.0 + */ + this.current = new Vector2(); + + /** + * The destination scroll coordinates to pan the camera to. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#destination + * @type {Phaser.Math.Vector2} + * @since 3.11.0 + */ + this.destination = new Vector2(); + + /** + * The ease function to use during the pan. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#ease + * @type {function} + * @since 3.11.0 + */ + this.ease; + + /** + * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#progress + * @type {number} + * @since 3.11.0 + */ + this.progress = 0; + + /** + * Effect elapsed timer. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#_elapsed + * @type {number} + * @private + * @since 3.11.0 + */ + this._elapsed = 0; + + /** + * This callback is invoked every frame for the duration of the effect. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#_onUpdate + * @type {?Phaser.Types.Cameras.Scene2D.CameraPanCallback} + * @private + * @default null + * @since 3.11.0 + */ + this._onUpdate; + + /** + * On Complete callback scope. + * + * @name Phaser.Cameras.Scene2D.Effects.Pan#_onUpdateScope + * @type {any} + * @private + * @since 3.11.0 + */ + this._onUpdateScope; + }, /** - * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration. - * @method update - * @param {body} body - * @param {number} deltaTime - * @param {number} timeScale - * @param {number} correction + * This effect will scroll the Camera so that the center of its viewport finishes at the given destination, + * over the duration and with the ease specified. + * + * @method Phaser.Cameras.Scene2D.Effects.Pan#start + * @fires Phaser.Cameras.Scene2D.Events#PAN_START + * @fires Phaser.Cameras.Scene2D.Events#PAN_COMPLETE + * @since 3.11.0 + * + * @param {number} x - The destination x coordinate to scroll the center of the Camera viewport to. + * @param {number} y - The destination y coordinate to scroll the center of the Camera viewport to. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {(string|function)} [ease='Linear'] - The ease to use for the pan. Can be any of the Phaser Easing constants or a custom function. + * @param {boolean} [force=false] - Force the pan effect to start immediately, even if already running. + * @param {Phaser.Types.Cameras.Scene2D.CameraPanCallback} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, + * the current camera scroll x coordinate and the current camera scroll y coordinate. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * + * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. */ - Body.update = function(body, deltaTime, timeScale, correction) { - var deltaTimeSquared = Math.pow(deltaTime * timeScale * body.timeScale, 2); + start: function (x, y, duration, ease, force, callback, context) + { + if (duration === undefined) { duration = 1000; } + if (ease === undefined) { ease = EaseMap.Linear; } + if (force === undefined) { force = false; } + if (callback === undefined) { callback = null; } + if (context === undefined) { context = this.camera.scene; } - // from the previous step - var frictionAir = 1 - body.frictionAir * timeScale * body.timeScale, - velocityPrevX = body.position.x - body.positionPrev.x, - velocityPrevY = body.position.y - body.positionPrev.y; + var cam = this.camera; - // update velocity with Verlet integration - body.velocity.x = (velocityPrevX * frictionAir * correction) + (body.force.x / body.mass) * deltaTimeSquared; - body.velocity.y = (velocityPrevY * frictionAir * correction) + (body.force.y / body.mass) * deltaTimeSquared; + if (!force && this.isRunning) + { + return cam; + } - body.positionPrev.x = body.position.x; - body.positionPrev.y = body.position.y; - body.position.x += body.velocity.x; - body.position.y += body.velocity.y; + this.isRunning = true; + this.duration = duration; + this.progress = 0; - // update angular velocity with Verlet integration - body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared; - body.anglePrev = body.angle; - body.angle += body.angularVelocity; + // Starting from + this.source.set(cam.scrollX, cam.scrollY); - // track speed and acceleration - body.speed = Vector.magnitude(body.velocity); - body.angularSpeed = Math.abs(body.angularVelocity); + // Destination + this.destination.set(x, y); - // transform the body geometry - for (var i = 0; i < body.parts.length; i++) { - var part = body.parts[i]; + // Zoom factored version + cam.getScroll(x, y, this.current); - Vertices.translate(part.vertices, body.velocity); - - if (i > 0) { - part.position.x += body.velocity.x; - part.position.y += body.velocity.y; - } + // Using this ease + if (typeof ease === 'string' && EaseMap.hasOwnProperty(ease)) + { + this.ease = EaseMap[ease]; + } + else if (typeof ease === 'function') + { + this.ease = ease; + } - if (body.angularVelocity !== 0) { - Vertices.rotate(part.vertices, body.angularVelocity, body.position); - Axes.rotate(part.axes, body.angularVelocity); - if (i > 0) { - Vector.rotateAbout(part.position, body.angularVelocity, body.position, part.position); - } - } + this._elapsed = 0; - Bounds.update(part.bounds, part.vertices, body.velocity); - } - }; + this._onUpdate = callback; + this._onUpdateScope = context; - /** - * Applies a force to a body from a given world-space position, including resulting torque. - * @method applyForce - * @param {body} body - * @param {vector} position - * @param {vector} force - */ - Body.applyForce = function(body, position, force) { - body.force.x += force.x; - body.force.y += force.y; - var offset = { x: position.x - body.position.x, y: position.y - body.position.y }; - body.torque += offset.x * force.y - offset.y * force.x; - }; + this.camera.emit(Events.PAN_START, this.camera, this, duration, x, y); + + return cam; + }, /** - * Returns the sums of the properties of all compound parts of the parent body. - * @method _totalProperties - * @private - * @param {body} body - * @return {} + * The main update loop for this effect. Called automatically by the Camera. + * + * @method Phaser.Cameras.Scene2D.Effects.Pan#update + * @since 3.11.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. */ - Body._totalProperties = function(body) { - // from equations at: - // https://ecourses.ou.edu/cgi-bin/ebook.cgi?doc=&topic=st&chap_sec=07.2&page=theory - // http://output.to/sideway/default.asp?qno=121100087 + update: function (time, delta) + { + if (!this.isRunning) + { + return; + } - var properties = { - mass: 0, - area: 0, - inertia: 0, - centre: { x: 0, y: 0 } - }; + this._elapsed += delta; - // sum the properties of all compound parts of the parent body - for (var i = body.parts.length === 1 ? 0 : 1; i < body.parts.length; i++) { - var part = body.parts[i], - mass = part.mass !== Infinity ? part.mass : 1; + var progress = Clamp(this._elapsed / this.duration, 0, 1); - properties.mass += mass; - properties.area += part.area; - properties.inertia += part.inertia; - properties.centre = Vector.add(properties.centre, Vector.mult(part.position, mass)); - } + this.progress = progress; - properties.centre = Vector.div(properties.centre, properties.mass); + var cam = this.camera; - return properties; - }; + if (this._elapsed < this.duration) + { + var v = this.ease(progress); - /* - * - * Events Documentation - * - */ + cam.getScroll(this.destination.x, this.destination.y, this.current); - /** - * Fired when a body starts sleeping (where `this` is the body). - * - * @event sleepStart - * @this {body} The body that has started sleeping - * @param {} event An event object - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ + var x = this.source.x + ((this.current.x - this.source.x) * v); + var y = this.source.y + ((this.current.y - this.source.y) * v); - /** - * Fired when a body ends sleeping (where `this` is the body). - * - * @event sleepEnd - * @this {body} The body that has ended sleeping - * @param {} event An event object - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ + cam.setScroll(x, y); - /* - * - * Properties Documentation - * - */ + if (this._onUpdate) + { + this._onUpdate.call(this._onUpdateScope, cam, progress, x, y); + } + } + else + { + cam.centerOn(this.destination.x, this.destination.y); + + if (this._onUpdate) + { + this._onUpdate.call(this._onUpdateScope, cam, progress, cam.scrollX, cam.scrollY); + } + + this.effectComplete(); + } + }, /** - * An integer `Number` uniquely identifying number generated in `Body.create` by `Common.nextId`. + * Called internally when the effect completes. * - * @property id - * @type number + * @method Phaser.Cameras.Scene2D.Effects.Pan#effectComplete + * @fires Phaser.Cameras.Scene2D.Events#PAN_COMPLETE + * @since 3.11.0 */ + effectComplete: function () + { + this._onUpdate = null; + this._onUpdateScope = null; + + this.isRunning = false; + + this.camera.emit(Events.PAN_COMPLETE, this.camera, this); + }, /** - * A `String` denoting the type of object. + * Resets this camera effect. + * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. * - * @property type - * @type string - * @default "body" - * @readOnly - */ - - /** - * An arbitrary `String` name to help the user identify and manage bodies. - * - * @property label - * @type string - * @default "Body" - */ - - /** - * An array of bodies that make up this body. - * The first body in the array must always be a self reference to the current body instance. - * All bodies in the `parts` array together form a single rigid compound body. - * Parts are allowed to overlap, have gaps or holes or even form concave bodies. - * Parts themselves should never be added to a `World`, only the parent body should be. - * Use `Body.setParts` when setting parts to ensure correct updates of all properties. - * - * @property parts - * @type body[] + * @method Phaser.Cameras.Scene2D.Effects.Pan#reset + * @since 3.11.0 */ + reset: function () + { + this.isRunning = false; - /** - * An object reserved for storing plugin-specific properties. - * - * @property plugin - * @type {} - */ + this._onUpdate = null; + this._onUpdateScope = null; + }, /** - * A self reference if the body is _not_ a part of another body. - * Otherwise this is a reference to the body that this is a part of. - * See `body.parts`. + * Destroys this effect, releasing it from the Camera. * - * @property parent - * @type body + * @method Phaser.Cameras.Scene2D.Effects.Pan#destroy + * @since 3.11.0 */ + destroy: function () + { + this.reset(); - /** - * A `Number` specifying the angle of the body, in radians. - * - * @property angle - * @type number - * @default 0 - */ + this.camera = null; + this.source = null; + this.destination = null; + } - /** - * An array of `Vector` objects that specify the convex hull of the rigid body. - * These should be provided about the origin `(0, 0)`. E.g. - * - * [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }] - * - * When passed via `Body.create`, the vertices are translated relative to `body.position` (i.e. world-space, and constantly updated by `Body.update` during simulation). - * The `Vector` objects are also augmented with additional properties required for efficient collision detection. - * - * Other properties such as `inertia` and `bounds` are automatically calculated from the passed vertices (unless provided via `options`). - * Concave hulls are not currently supported. The module `Matter.Vertices` contains useful methods for working with vertices. - * - * @property vertices - * @type vector[] - */ +}); - /** - * A `Vector` that specifies the current world-space position of the body. - * - * @property position - * @type vector - * @default { x: 0, y: 0 } - */ +module.exports = Pan; - /** - * A `Vector` that holds the current scale values as set by `Body.setScale`. - * - * @property scale - * @type vector - * @default { x: 1, y: 1 } - */ - /** - * A `Vector` that specifies the force to apply in the current step. It is zeroed after every `Body.update`. See also `Body.applyForce`. - * - * @property force - * @type vector - * @default { x: 0, y: 0 } - */ +/***/ }), - /** - * A `Number` that specifies the torque (turning force) to apply in the current step. It is zeroed after every `Body.update`. - * - * @property torque - * @type number - * @default 0 - */ +/***/ 1771: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A `Number` that _measures_ the current speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.velocity`). - * - * @readOnly - * @property speed - * @type number - * @default 0 - */ +/** + * @author Jason Nicholls + * @copyright 2018 Photon Storm Ltd. + * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} + */ - /** - * A `Number` that _measures_ the current angular speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.angularVelocity`). - * - * @readOnly - * @property angularSpeed - * @type number - * @default 0 - */ +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(89787); +var EaseMap = __webpack_require__(35060); - /** - * A `Vector` that _measures_ the current velocity of the body after the last `Body.update`. It is read-only. - * If you need to modify a body's velocity directly, you should either apply a force or simply change the body's `position` (as the engine uses position-Verlet integration). - * - * @readOnly - * @property velocity - * @type vector - * @default { x: 0, y: 0 } - */ +/** + * @classdesc + * A Camera Rotate effect. + * + * This effect will rotate the Camera so that the its viewport finishes at the given angle in radians, + * over the duration and with the ease specified. + * + * Camera rotation always takes place based on the Camera viewport. By default, rotation happens + * in the center of the viewport. You can adjust this with the `originX` and `originY` properties. + * + * Rotation influences the rendering of _all_ Game Objects visible by this Camera. However, it does not + * rotate the Camera viewport itself, which always remains an axis-aligned rectangle. + * + * Only the camera is rotates. None of the objects it is displaying are impacted, i.e. their positions do + * not change. + * + * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, + * which is invoked each frame for the duration of the effect if required. + * + * @class RotateTo + * @memberof Phaser.Cameras.Scene2D.Effects + * @constructor + * @since 3.23.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. + */ +var RotateTo = new Class({ - /** - * A `Number` that _measures_ the current angular velocity of the body after the last `Body.update`. It is read-only. - * If you need to modify a body's angular velocity directly, you should apply a torque or simply change the body's `angle` (as the engine uses position-Verlet integration). - * - * @readOnly - * @property angularVelocity - * @type number - * @default 0 - */ + initialize: - /** - * A flag that indicates whether a body is considered static. A static body can never change position or angle and is completely fixed. - * If you need to set a body as static after its creation, you should use `Body.setStatic` as this requires more than just setting this flag. - * - * @property isStatic - * @type boolean - * @default false - */ + function RotateTo (camera) + { + /** + * The Camera this effect belongs to. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#camera + * @type {Phaser.Cameras.Scene2D.Camera} + * @readonly + * @since 3.23.0 + */ + this.camera = camera; - /** - * A flag that indicates whether a body is a sensor. Sensor triggers collision events, but doesn't react with colliding body physically. - * - * @property isSensor - * @type boolean - * @default false - */ + /** + * Is this effect actively running? + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#isRunning + * @type {boolean} + * @readonly + * @default false + * @since 3.23.0 + */ + this.isRunning = false; - /** - * A flag that indicates whether the body is considered sleeping. A sleeping body acts similar to a static body, except it is only temporary and can be awoken. - * If you need to set a body as sleeping, you should use `Sleeping.set` as this requires more than just setting this flag. - * - * @property isSleeping - * @type boolean - * @default false - */ + /** + * The duration of the effect, in milliseconds. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#duration + * @type {number} + * @readonly + * @default 0 + * @since 3.23.0 + */ + this.duration = 0; - /** - * A `Number` that _measures_ the amount of movement a body currently has (a combination of `speed` and `angularSpeed`). It is read-only and always positive. - * It is used and updated by the `Matter.Sleeping` module during simulation to decide if a body has come to rest. - * - * @readOnly - * @property motion - * @type number - * @default 0 - */ + /** + * The starting angle to rotate the camera from. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#source + * @type {number} + * @since 3.23.0 + */ + this.source = 0; - /** - * A `Number` that defines the number of updates in which this body must have near-zero velocity before it is set as sleeping by the `Matter.Sleeping` module (if sleeping is enabled by the engine). - * - * @property sleepThreshold - * @type number - * @default 60 - */ + /** + * The constantly updated value based on the force. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#current + * @type {number} + * @since 3.23.0 + */ + this.current = 0; - /** - * A `Number` that defines the density of the body, that is its mass per unit area. - * If you pass the density via `Body.create` the `mass` property is automatically calculated for you based on the size (area) of the object. - * This is generally preferable to simply setting mass and allows for more intuitive definition of materials (e.g. rock has a higher density than wood). - * - * @property density - * @type number - * @default 0.001 - */ + /** + * The destination angle in radians to rotate the camera to. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#destination + * @type {number} + * @since 3.23.0 + */ + this.destination = 0; - /** - * A `Number` that defines the mass of the body, although it may be more appropriate to specify the `density` property instead. - * If you modify this value, you must also modify the `body.inverseMass` property (`1 / mass`). - * - * @property mass - * @type number - */ + /** + * The ease function to use during the Rotate. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#ease + * @type {function} + * @since 3.23.0 + */ + this.ease; - /** - * A `Number` that defines the inverse mass of the body (`1 / mass`). - * If you modify this value, you must also modify the `body.mass` property. - * - * @property inverseMass - * @type number - */ + /** + * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#progress + * @type {number} + * @since 3.23.0 + */ + this.progress = 0; - /** - * A `Number` that defines the moment of inertia (i.e. second moment of area) of the body. - * It is automatically calculated from the given convex hull (`vertices` array) and density in `Body.create`. - * If you modify this value, you must also modify the `body.inverseInertia` property (`1 / inertia`). - * - * @property inertia - * @type number - */ + /** + * Effect elapsed timer. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#_elapsed + * @type {number} + * @private + * @since 3.23.0 + */ + this._elapsed = 0; - /** - * A `Number` that defines the inverse moment of inertia of the body (`1 / inertia`). - * If you modify this value, you must also modify the `body.inertia` property. - * - * @property inverseInertia - * @type number - */ + /** + * @callback CameraRotateCallback + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera on which the effect is running. + * @param {number} progress - The progress of the effect. A value between 0 and 1. + * @param {number} angle - The Camera's new angle in radians. + */ - /** - * A `Number` that defines the restitution (elasticity) of the body. The value is always positive and is in the range `(0, 1)`. - * A value of `0` means collisions may be perfectly inelastic and no bouncing may occur. - * A value of `0.8` means the body may bounce back with approximately 80% of its kinetic energy. - * Note that collision response is based on _pairs_ of bodies, and that `restitution` values are _combined_ with the following formula: - * - * Math.max(bodyA.restitution, bodyB.restitution) - * - * @property restitution - * @type number - * @default 0 - */ + /** + * This callback is invoked every frame for the duration of the effect. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#_onUpdate + * @type {?CameraRotateCallback} + * @private + * @default null + * @since 3.23.0 + */ + this._onUpdate; - /** - * A `Number` that defines the friction of the body. The value is always positive and is in the range `(0, 1)`. - * A value of `0` means that the body may slide indefinitely. - * A value of `1` means the body may come to a stop almost instantly after a force is applied. - * - * The effects of the value may be non-linear. - * High values may be unstable depending on the body. - * The engine uses a Coulomb friction model including static and kinetic friction. - * Note that collision response is based on _pairs_ of bodies, and that `friction` values are _combined_ with the following formula: - * - * Math.min(bodyA.friction, bodyB.friction) - * - * @property friction - * @type number - * @default 0.1 - */ + /** + * On Complete callback scope. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#_onUpdateScope + * @type {any} + * @private + * @since 3.23.0 + */ + this._onUpdateScope; - /** - * A `Number` that defines the static friction of the body (in the Coulomb friction model). - * A value of `0` means the body will never 'stick' when it is nearly stationary and only dynamic `friction` is used. - * The higher the value (e.g. `10`), the more force it will take to initially get the body moving when nearly stationary. - * This value is multiplied with the `friction` property to make it easier to change `friction` and maintain an appropriate amount of static friction. - * - * @property frictionStatic - * @type number - * @default 0.5 - */ + /** + * The direction of the rotation. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#clockwise + * @type {boolean} + * @since 3.23.0 + */ + this.clockwise = true; - /** - * A `Number` that defines the air friction of the body (air resistance). - * A value of `0` means the body will never slow as it moves through space. - * The higher the value, the faster a body slows when moving through space. - * The effects of the value are non-linear. - * - * @property frictionAir - * @type number - * @default 0.01 - */ + /** + * The shortest direction to the target rotation. + * + * @name Phaser.Cameras.Scene2D.Effects.RotateTo#shortestPath + * @type {boolean} + * @since 3.23.0 + */ + this.shortestPath = false; + }, /** - * An `Object` that specifies the collision filtering properties of this body. - * - * Collisions between two bodies will obey the following rules: - * - If the two bodies have the same non-zero value of `collisionFilter.group`, - * they will always collide if the value is positive, and they will never collide - * if the value is negative. - * - If the two bodies have different values of `collisionFilter.group` or if one - * (or both) of the bodies has a value of 0, then the category/mask rules apply as follows: - * - * Each body belongs to a collision category, given by `collisionFilter.category`. This - * value is used as a bit field and the category should have only one bit set, meaning that - * the value of this property is a power of two in the range [1, 2^31]. Thus, there are 32 - * different collision categories available. + * This effect will scroll the Camera so that the center of its viewport finishes at the given angle, + * over the duration and with the ease specified. * - * Each body also defines a collision bitmask, given by `collisionFilter.mask` which specifies - * the categories it collides with (the value is the bitwise AND value of all these categories). + * @method Phaser.Cameras.Scene2D.Effects.RotateTo#start + * @fires Phaser.Cameras.Scene2D.Events#ROTATE_START + * @fires Phaser.Cameras.Scene2D.Events#ROTATE_COMPLETE + * @since 3.23.0 * - * Using the category/mask rules, two bodies `A` and `B` collide if each includes the other's - * category in its mask, i.e. `(categoryA & maskB) !== 0` and `(categoryB & maskA) !== 0` - * are both true. + * @param {number} radians - The destination angle in radians to rotate the Camera viewport to. If the angle is positive then the rotation is clockwise else anticlockwise + * @param {boolean} [shortestPath=false] - If shortest path is set to true the camera will rotate in the quickest direction clockwise or anti-clockwise. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {(string|function)} [ease='Linear'] - The ease to use for the Rotate. Can be any of the Phaser Easing constants or a custom function. + * @param {boolean} [force=false] - Force the rotation effect to start immediately, even if already running. + * @param {CameraRotateCallback} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, + * the current camera scroll x coordinate and the current camera scroll y coordinate. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @property collisionFilter - * @type object + * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. */ + start: function (radians, shortestPath, duration, ease, force, callback, context) + { + if (duration === undefined) { duration = 1000; } + if (ease === undefined) { ease = EaseMap.Linear; } + if (force === undefined) { force = false; } + if (callback === undefined) { callback = null; } + if (context === undefined) { context = this.camera.scene; } + if (shortestPath === undefined) { shortestPath = false; } - /** - * An Integer `Number`, that specifies the collision group this body belongs to. - * See `body.collisionFilter` for more information. - * - * @property collisionFilter.group - * @type object - * @default 0 - */ + this.shortestPath = shortestPath; - /** - * A bit field that specifies the collision category this body belongs to. - * The category value should have only one bit set, for example `0x0001`. - * This means there are up to 32 unique collision categories available. - * See `body.collisionFilter` for more information. - * - * @property collisionFilter.category - * @type object - * @default 1 - */ + var tmpDestination = radians; - /** - * A bit mask that specifies the collision categories this body may collide with. - * See `body.collisionFilter` for more information. - * - * @property collisionFilter.mask - * @type object - * @default -1 - */ + if (radians < 0) + { + tmpDestination = -1 * radians; + this.clockwise = false; + } + else + { + this.clockwise = true; + } - /** - * A `Number` that specifies a tolerance on how far a body is allowed to 'sink' or rotate into other bodies. - * Avoid changing this value unless you understand the purpose of `slop` in physics engines. - * The default should generally suffice, although very large bodies may require larger values for stable stacking. - * - * @property slop - * @type number - * @default 0.05 - */ + var maxRad = (360 * Math.PI) / 180; - /** - * A `Number` that allows per-body time scaling, e.g. a force-field where bodies inside are in slow-motion, while others are at full speed. - * - * @property timeScale - * @type number - * @default 1 - */ + tmpDestination = tmpDestination - (Math.floor(tmpDestination / maxRad) * maxRad); - /** - * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`. - * - * @property render - * @type object - */ + var cam = this.camera; - /** - * A flag that indicates if the body should be rendered. - * - * @property render.visible - * @type boolean - * @default true - */ + if (!force && this.isRunning) + { + return cam; + } - /** - * Sets the opacity to use when rendering. - * - * @property render.opacity - * @type number - * @default 1 - */ + this.isRunning = true; + this.duration = duration; + this.progress = 0; - /** - * An `Object` that defines the sprite properties to use when rendering, if any. - * - * @property render.sprite - * @type object - */ + // Starting from + this.source = cam.rotation; - /** - * A `Number` that defines the offset in the x-axis for the sprite (normalised by texture width). - * - * @property render.sprite.xOffset - * @type number - * @default 0 - */ + // Destination + this.destination = tmpDestination; - /** - * A `Number` that defines the offset in the y-axis for the sprite (normalised by texture height). - * - * @property render.sprite.yOffset - * @type number - * @default 0 - */ + // Using this ease + if (typeof ease === 'string' && EaseMap.hasOwnProperty(ease)) + { + this.ease = EaseMap[ease]; + } + else if (typeof ease === 'function') + { + this.ease = ease; + } - /** - * A hex color value that defines the fill color to use when rendering the body. - * - * @property render.fillColor - * @type number - */ + this._elapsed = 0; - /** - * A value that defines the fill opacity to use when rendering the body. - * - * @property render.fillOpacity - * @type number - */ + this._onUpdate = callback; + this._onUpdateScope = context; - /** - * A hex color value that defines the line color to use when rendering the body. - * - * @property render.lineColor - * @type number - */ - /** - * A value that defines the line opacity to use when rendering the body. - * - * @property render.lineOpacity - * @type number - */ + if (this.shortestPath) + { + // The shortest path is true so calculate the quickest direction + var cwDist = 0; + var acwDist = 0; - /** - * A `Number` that defines the line width to use when rendering the body outline. - * - * @property render.lineThickness - * @type number - */ + if (this.destination > this.source) + { + cwDist = Math.abs(this.destination - this.source); + } + else + { + cwDist = (Math.abs(this.destination + maxRad) - this.source); + } - /** - * An array of unique axis vectors (edge normals) used for collision detection. - * These are automatically calculated from the given convex hull (`vertices` array) in `Body.create`. - * They are constantly updated by `Body.update` during the simulation. - * - * @property axes - * @type vector[] - */ - - /** - * A `Number` that _measures_ the area of the body's convex hull, calculated at creation by `Body.create`. - * - * @property area - * @type string - * @default - */ + if (this.source > this.destination) + { + acwDist = Math.abs(this.source - this.destination); + } + else + { + acwDist = (Math.abs(this.source + maxRad) - this.destination); + } - /** - * A `Bounds` object that defines the AABB region for the body. - * It is automatically calculated from the given convex hull (`vertices` array) in `Body.create` and constantly updated by `Body.update` during simulation. - * - * @property bounds - * @type bounds - */ + if (cwDist < acwDist) + { + this.clockwise = true; + } + else if (cwDist > acwDist) + { + this.clockwise = false; + } + } - /** - * A reference to the Phaser Game Object this body belongs to, if any. - * - * @property gameObject - * @type Phaser.GameObjects.GameObject - */ + this.camera.emit(Events.ROTATE_START, this.camera, this, duration, tmpDestination); - /** - * The center of mass of the Body. - * - * @property centerOfMass - * @type vector - * @default { x: 0, y: 0 } - */ + return cam; + }, /** - * The center of the body in pixel values. - * Used by Phaser for texture aligment. + * The main update loop for this effect. Called automatically by the Camera. * - * @property centerOffset - * @type vector - * @default { x: 0, y: 0 } - */ - - /** - * Will this Body ignore World gravity during the Engine update? + * @method Phaser.Cameras.Scene2D.Effects.RotateTo#update + * @since 3.23.0 * - * @property ignoreGravity - * @type boolean - * @default false + * @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.isRunning) + { + return; + } - /** - * Scale the influence of World gravity when applied to this body. - * - * @property gravityScale - * @type vector - * @default { x: 1, y: 1 } - */ + this._elapsed += delta; - /** - * Will this Body ignore Phaser Pointer input events? - * - * @property ignorePointer - * @type boolean - * @default false - */ + var progress = Clamp(this._elapsed / this.duration, 0, 1); - /** - * A callback that is invoked when this Body starts colliding with any other Body. - * - * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. - * - * @property onCollideCallback - * @type function - * @default null - */ + this.progress = progress; - /** - * A callback that is invoked when this Body stops colliding with any other Body. - * - * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. - * - * @property onCollideEndCallback - * @type function - * @default null - */ + var cam = this.camera; - /** - * A callback that is invoked for the duration that this Body is colliding with any other Body. - * - * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. - * - * @property onCollideActiveCallback - * @type function - * @default null - */ + if (this._elapsed < this.duration) + { + var v = this.ease(progress); - /** - * A collision callback dictionary used by the `Body.setOnCollideWith` function. - * - * @property onCollideWith - * @type object - * @default null - */ + this.current = cam.rotation; + var distance = 0; + var maxRad = (360 * Math.PI) / 180; + var target = this.destination; + var current = this.current; -})(); + if (this.clockwise === false) + { + target = this.current; + current = this.destination; + } + if (target >= current) + { + distance = Math.abs(target - current); + } + else + { + distance = (Math.abs(target + maxRad) - current); + } -/***/ }), -/* 42 */ -/***/ (function(module, exports) { + var r = 0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.clockwise) + { + r = (cam.rotation + (distance * v)); + } + else + { + r = (cam.rotation - (distance * v)); + } -/** - * Returns the bottom coordinate from the bounds of the Game Object. - * - * @function Phaser.Display.Bounds.GetBottom - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. - * - * @return {number} The bottom coordinate of the bounds of the Game Object. - */ -var GetBottom = function (gameObject) -{ - return (gameObject.y + gameObject.height) - (gameObject.height * gameObject.originY); -}; + cam.rotation = r; -module.exports = GetBottom; + if (this._onUpdate) + { + this._onUpdate.call(this._onUpdateScope, cam, progress, r); + } + } + else + { + cam.rotation = this.destination; + if (this._onUpdate) + { + this._onUpdate.call(this._onUpdateScope, cam, progress, this.destination); + } + + this.effectComplete(); + } + }, -/***/ }), -/* 43 */ -/***/ (function(module, exports) { + /** + * Called internally when the effect completes. + * + * @method Phaser.Cameras.Scene2D.Effects.RotateTo#effectComplete + * @since 3.23.0 + */ + effectComplete: function () + { + this._onUpdate = null; + this._onUpdateScope = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.isRunning = false; -/** - * Returns the left coordinate from the bounds of the Game Object. - * - * @function Phaser.Display.Bounds.GetLeft - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. - * - * @return {number} The left coordinate of the bounds of the Game Object. - */ -var GetLeft = function (gameObject) -{ - return gameObject.x - (gameObject.width * gameObject.originX); -}; + this.camera.emit(Events.ROTATE_COMPLETE, this.camera, this); + }, -module.exports = GetLeft; + /** + * Resets this camera effect. + * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. + * + * @method Phaser.Cameras.Scene2D.Effects.RotateTo#reset + * @since 3.23.0 + */ + reset: function () + { + this.isRunning = false; + this._onUpdate = null; + this._onUpdateScope = null; + }, -/***/ }), -/* 44 */ -/***/ (function(module, exports) { + /** + * Destroys this effect, releasing it from the Camera. + * + * @method Phaser.Cameras.Scene2D.Effects.RotateTo#destroy + * @since 3.23.0 + */ + destroy: function () + { + this.reset(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.camera = null; + this.source = null; + this.destination = null; + } -/** - * Returns the right coordinate from the bounds of the Game Object. - * - * @function Phaser.Display.Bounds.GetRight - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. - * - * @return {number} The right coordinate of the bounds of the Game Object. - */ -var GetRight = function (gameObject) -{ - return (gameObject.x + gameObject.width) - (gameObject.width * gameObject.originX); -}; +}); -module.exports = GetRight; +module.exports = RotateTo; /***/ }), -/* 45 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Returns the top coordinate from the bounds of the Game Object. - * - * @function Phaser.Display.Bounds.GetTop - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. - * - * @return {number} The top coordinate of the bounds of the Game Object. - */ -var GetTop = function (gameObject) -{ - return gameObject.y - (gameObject.height * gameObject.originY); -}; - -module.exports = GetTop; - -/***/ }), -/* 46 */ -/***/ (function(module, exports) { +/***/ 3241: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(89787); +var Vector2 = __webpack_require__(93736); + /** - * Takes an array of Game Objects, or any objects that have a public property as defined in `key`, - * and then adds the given value to it. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `PropertyValueInc(group.getChildren(), key, value, step)` - * - * @function Phaser.Actions.PropertyValueInc - * @since 3.3.0 + * @classdesc + * A Camera Shake effect. * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * This effect will shake the camera viewport by a random amount, bounded by the specified intensity, each frame. * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {string} key - The property to be updated. - * @param {number} value - The amount to be added to the property. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * Only the camera viewport is moved. None of the objects it is displaying are impacted, i.e. their positions do + * not change. * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var PropertyValueInc = function (items, key, value, step, index, direction) -{ - if (step === undefined) { step = 0; } - if (index === undefined) { index = 0; } - if (direction === undefined) { direction = 1; } - - var i; - var t = 0; - var end = items.length; - - if (direction === 1) - { - // Start to End - for (i = index; i < end; i++) - { - items[i][key] += value + (t * step); - t++; - } - } - else - { - // End to Start - for (i = index; i >= 0; i--) - { - items[i][key] += value + (t * step); - t++; - } - } - - return items; -}; - -module.exports = PropertyValueInc; - - -/***/ }), -/* 47 */ -/***/ (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 GetPoint = __webpack_require__(307); -var GetPoints = __webpack_require__(172); -var GEOM_CONST = __webpack_require__(56); -var Random = __webpack_require__(173); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * Defines a Line segment, a part of a line between two endpoints. + * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, + * which is invoked each frame for the duration of the effect if required. * - * @class Line - * @memberof Phaser.Geom + * @class Shake + * @memberof Phaser.Cameras.Scene2D.Effects * @constructor - * @since 3.0.0 + * @since 3.5.0 * - * @param {number} [x1=0] - The x coordinate of the lines starting point. - * @param {number} [y1=0] - The y coordinate of the lines starting point. - * @param {number} [x2=0] - The x coordinate of the lines ending point. - * @param {number} [y2=0] - The y coordinate of the lines ending point. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. */ -var Line = new Class({ +var Shake = new Class({ initialize: - function Line (x1, y1, x2, y2) + function Shake (camera) { - if (x1 === undefined) { x1 = 0; } - if (y1 === undefined) { y1 = 0; } - if (x2 === undefined) { x2 = 0; } - if (y2 === undefined) { y2 = 0; } - /** - * The geometry constant type of this object: `GEOM_CONST.LINE`. - * Used for fast type comparisons. + * The Camera this effect belongs to. * - * @name Phaser.Geom.Line#type - * @type {number} + * @name Phaser.Cameras.Scene2D.Effects.Shake#camera + * @type {Phaser.Cameras.Scene2D.Camera} * @readonly - * @since 3.19.0 + * @since 3.5.0 */ - this.type = GEOM_CONST.LINE; + this.camera = camera; /** - * The x coordinate of the lines starting point. + * Is this effect actively running? * - * @name Phaser.Geom.Line#x1 - * @type {number} - * @since 3.0.0 - */ - this.x1 = x1; + * @name Phaser.Cameras.Scene2D.Effects.Shake#isRunning + * @type {boolean} + * @readonly + * @default false + * @since 3.5.0 + */ + this.isRunning = false; /** - * The y coordinate of the lines starting point. + * The duration of the effect, in milliseconds. * - * @name Phaser.Geom.Line#y1 + * @name Phaser.Cameras.Scene2D.Effects.Shake#duration * @type {number} - * @since 3.0.0 + * @readonly + * @default 0 + * @since 3.5.0 */ - this.y1 = y1; + this.duration = 0; /** - * The x coordinate of the lines ending point. + * The intensity of the effect. Use small float values. The default when the effect starts is 0.05. + * This is a Vector2 object, allowing you to control the shake intensity independently across x and y. + * You can modify this value while the effect is active to create more varied shake effects. * - * @name Phaser.Geom.Line#x2 + * @name Phaser.Cameras.Scene2D.Effects.Shake#intensity + * @type {Phaser.Math.Vector2} + * @since 3.5.0 + */ + this.intensity = new Vector2(); + + /** + * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. + * + * @name Phaser.Cameras.Scene2D.Effects.Shake#progress * @type {number} + * @since 3.5.0 + */ + this.progress = 0; + + /** + * Effect elapsed timer. + * + * @name Phaser.Cameras.Scene2D.Effects.Shake#_elapsed + * @type {number} + * @private + * @since 3.5.0 + */ + this._elapsed = 0; + + /** + * How much to offset the camera by horizontally. + * + * @name Phaser.Cameras.Scene2D.Effects.Shake#_offsetX + * @type {number} + * @private + * @default 0 * @since 3.0.0 */ - this.x2 = x2; + this._offsetX = 0; /** - * The y coordinate of the lines ending point. + * How much to offset the camera by vertically. * - * @name Phaser.Geom.Line#y2 + * @name Phaser.Cameras.Scene2D.Effects.Shake#_offsetY * @type {number} + * @private + * @default 0 * @since 3.0.0 */ - this.y2 = y2; - }, + this._offsetY = 0; - /** - * Get a point on a line that's a given percentage along its length. - * - * @method Phaser.Geom.Line#getPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [output,$return] - * - * @param {number} position - A value between 0 and 1, where 0 is the start, 0.5 is the middle and 1 is the end of the line. - * @param {(Phaser.Geom.Point|object)} [output] - An optional point, or point-like object, to store the coordinates of the point on the line. - * - * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point on the line. - */ - getPoint: function (position, output) - { - return GetPoint(this, position, output); - }, + /** + * This callback is invoked every frame for the duration of the effect. + * + * @name Phaser.Cameras.Scene2D.Effects.Shake#_onUpdate + * @type {?Phaser.Types.Cameras.Scene2D.CameraShakeCallback} + * @private + * @default null + * @since 3.5.0 + */ + this._onUpdate; - /** - * Get a number of points along a line's length. - * - * Provide a `quantity` to get an exact number of points along the line. - * - * Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when - * providing a `stepRate`. - * - * @method Phaser.Geom.Line#getPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point[]} O - [output,$return] - * - * @param {number} quantity - The number of points to place on the line. Set to `0` to use `stepRate` instead. - * @param {number} [stepRate] - The distance between each point on the line. When set, `quantity` is implied and should be set to `0`. - * @param {(array|Phaser.Geom.Point[])} [output] - An optional array of Points, or point-like objects, to store the coordinates of the points on the line. - * - * @return {(array|Phaser.Geom.Point[])} An array of Points, or point-like objects, containing the coordinates of the points on the line. - */ - getPoints: function (quantity, stepRate, output) - { - return GetPoints(this, quantity, stepRate, output); + /** + * On Complete callback scope. + * + * @name Phaser.Cameras.Scene2D.Effects.Shake#_onUpdateScope + * @type {any} + * @private + * @since 3.5.0 + */ + this._onUpdateScope; }, /** - * Get a random Point on the Line. - * - * @method Phaser.Geom.Line#getRandomPoint - * @since 3.0.0 + * Shakes the Camera by the given intensity over the duration specified. * - * @generic {Phaser.Geom.Point} O - [point,$return] + * @method Phaser.Cameras.Scene2D.Effects.Shake#start + * @fires Phaser.Cameras.Scene2D.Events#SHAKE_START + * @fires Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE + * @since 3.5.0 * - * @param {(Phaser.Geom.Point|object)} [point] - An instance of a Point to be modified. + * @param {number} [duration=100] - The duration of the effect in milliseconds. + * @param {(number|Phaser.Math.Vector2)} [intensity=0.05] - The intensity of the shake. + * @param {boolean} [force=false] - Force the shake effect to start immediately, even if already running. + * @param {Phaser.Types.Cameras.Scene2D.CameraShakeCallback} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. * - * @return {Phaser.Geom.Point} A random Point on the Line. + * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. */ - getRandomPoint: function (point) + start: function (duration, intensity, force, callback, context) { - return Random(this, point); - }, + if (duration === undefined) { duration = 100; } + if (intensity === undefined) { intensity = 0.05; } + if (force === undefined) { force = false; } + if (callback === undefined) { callback = null; } + if (context === undefined) { context = this.camera.scene; } - /** - * Set new coordinates for the line endpoints. - * - * @method Phaser.Geom.Line#setTo - * @since 3.0.0 - * - * @param {number} [x1=0] - The x coordinate of the lines starting point. - * @param {number} [y1=0] - The y coordinate of the lines starting point. - * @param {number} [x2=0] - The x coordinate of the lines ending point. - * @param {number} [y2=0] - The y coordinate of the lines ending point. - * - * @return {this} This Line object. - */ - setTo: function (x1, y1, x2, y2) - { - if (x1 === undefined) { x1 = 0; } - if (y1 === undefined) { y1 = 0; } - if (x2 === undefined) { x2 = 0; } - if (y2 === undefined) { y2 = 0; } + if (!force && this.isRunning) + { + return this.camera; + } - this.x1 = x1; - this.y1 = y1; + this.isRunning = true; + this.duration = duration; + this.progress = 0; - this.x2 = x2; - this.y2 = y2; + if (typeof intensity === 'number') + { + this.intensity.set(intensity); + } + else + { + this.intensity.set(intensity.x, intensity.y); + } - return this; + this._elapsed = 0; + this._offsetX = 0; + this._offsetY = 0; + + this._onUpdate = callback; + this._onUpdateScope = context; + + this.camera.emit(Events.SHAKE_START, this.camera, this, duration, intensity); + + return this.camera; }, /** - * Returns a Vector2 object that corresponds to the start of this Line. - * - * @method Phaser.Geom.Line#getPointA - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [vec2,$return] - * - * @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created. + * The pre-render step for this effect. Called automatically by the Camera. * - * @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the start of this Line. + * @method Phaser.Cameras.Scene2D.Effects.Shake#preRender + * @since 3.5.0 */ - getPointA: function (vec2) + preRender: function () { - if (vec2 === undefined) { vec2 = new Vector2(); } - - vec2.set(this.x1, this.y1); - - return vec2; + if (this.isRunning) + { + this.camera.matrix.translate(this._offsetX, this._offsetY); + } }, /** - * Returns a Vector2 object that corresponds to the end of this Line. - * - * @method Phaser.Geom.Line#getPointB - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [vec2,$return] + * The main update loop for this effect. Called automatically by the Camera. * - * @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created. + * @method Phaser.Cameras.Scene2D.Effects.Shake#update + * @since 3.5.0 * - * @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the end of this Line. + * @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. */ - getPointB: function (vec2) + update: function (time, delta) { - if (vec2 === undefined) { vec2 = new Vector2(); } - - vec2.set(this.x2, this.y2); + if (!this.isRunning) + { + return; + } - return vec2; - }, + this._elapsed += delta; - /** - * The left position of the Line. - * - * @name Phaser.Geom.Line#left - * @type {number} - * @since 3.0.0 - */ - left: { + this.progress = Clamp(this._elapsed / this.duration, 0, 1); - get: function () + if (this._onUpdate) { - return Math.min(this.x1, this.x2); - }, + this._onUpdate.call(this._onUpdateScope, this.camera, this.progress); + } - set: function (value) + if (this._elapsed < this.duration) { - if (this.x1 <= this.x2) - { - this.x1 = value; - } - else + var intensity = this.intensity; + var width = this.camera.width; + var height = this.camera.height; + var zoom = this.camera.zoom; + + this._offsetX = (Math.random() * intensity.x * width * 2 - intensity.x * width) * zoom; + this._offsetY = (Math.random() * intensity.y * height * 2 - intensity.y * height) * zoom; + + if (this.camera.roundPixels) { - this.x2 = value; + this._offsetX = Math.round(this._offsetX); + this._offsetY = Math.round(this._offsetY); } } - + else + { + this.effectComplete(); + } }, /** - * The right position of the Line. + * Called internally when the effect completes. * - * @name Phaser.Geom.Line#right - * @type {number} - * @since 3.0.0 + * @method Phaser.Cameras.Scene2D.Effects.Shake#effectComplete + * @fires Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE + * @since 3.5.0 */ - right: { + effectComplete: function () + { + this._offsetX = 0; + this._offsetY = 0; - get: function () - { - return Math.max(this.x1, this.x2); - }, + this._onUpdate = null; + this._onUpdateScope = null; - set: function (value) - { - if (this.x1 > this.x2) - { - this.x1 = value; - } - else - { - this.x2 = value; - } - } + this.isRunning = false; + this.camera.emit(Events.SHAKE_COMPLETE, this.camera, this); }, /** - * The top position of the Line. + * Resets this camera effect. + * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. * - * @name Phaser.Geom.Line#top - * @type {number} - * @since 3.0.0 + * @method Phaser.Cameras.Scene2D.Effects.Shake#reset + * @since 3.5.0 */ - top: { - - get: function () - { - return Math.min(this.y1, this.y2); - }, + reset: function () + { + this.isRunning = false; - set: function (value) - { - if (this.y1 <= this.y2) - { - this.y1 = value; - } - else - { - this.y2 = value; - } - } + this._offsetX = 0; + this._offsetY = 0; + this._onUpdate = null; + this._onUpdateScope = null; }, /** - * The bottom position of the Line. + * Destroys this effect, releasing it from the Camera. * - * @name Phaser.Geom.Line#bottom - * @type {number} - * @since 3.0.0 + * @method Phaser.Cameras.Scene2D.Effects.Shake#destroy + * @since 3.5.0 */ - bottom: { - - get: function () - { - return Math.max(this.y1, this.y2); - }, - - set: function (value) - { - if (this.y1 > this.y2) - { - this.y1 = value; - } - else - { - this.y2 = value; - } - } + destroy: function () + { + this.reset(); + this.camera = null; + this.intensity = null; } }); -module.exports = Line; +module.exports = Shake; /***/ }), -/* 48 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Sets the fillStyle on the target context based on the given Shape. - * - * @method Phaser.GameObjects.Shape#FillStyleCanvas - * @since 3.13.0 - * @private - * - * @param {CanvasRenderingContext2D} ctx - The context to set the fill style on. - * @param {Phaser.GameObjects.Shape} src - The Game Object to set the fill style from. - * @param {number} [altColor] - An alternative color to render with. - * @param {number} [altAlpha] - An alternative alpha to render with. - */ -var FillStyleCanvas = function (ctx, src, altColor, altAlpha) -{ - var fillColor = (altColor) ? altColor : src.fillColor; - var fillAlpha = (altAlpha) ? altAlpha : src.fillAlpha; - - var red = ((fillColor & 0xFF0000) >>> 16); - var green = ((fillColor & 0xFF00) >>> 8); - var blue = (fillColor & 0xFF); - ctx.fillStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + fillAlpha + ')'; -}; - -module.exports = FillStyleCanvas; - - -/***/ }), -/* 49 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 13383: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var EaseMap = __webpack_require__(35060); +var Events = __webpack_require__(89787); /** * @classdesc - * A MultiFile is a special kind of parent that contains two, or more, Files as children and looks after - * the loading and processing of them all. It is commonly extended and used as a base class for file types such as AtlasJSON or BitmapFont. + * A Camera Zoom effect. * - * You shouldn't create an instance of a MultiFile directly, but should extend it with your own class, setting a custom type and processing methods. + * This effect will zoom the Camera to the given scale, over the duration and with the ease specified. * - * @class MultiFile - * @memberof Phaser.Loader + * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, + * which is invoked each frame for the duration of the effect if required. + * + * @class Zoom + * @memberof Phaser.Cameras.Scene2D.Effects * @constructor - * @since 3.7.0 + * @since 3.11.0 * - * @param {Phaser.Loader.LoaderPlugin} loader - The Loader that is going to load this File. - * @param {string} type - The file type string for sorting within the Loader. - * @param {string} key - The key of the file within the loader. - * @param {Phaser.Loader.File[]} files - An array of Files that make-up this MultiFile. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. */ -var MultiFile = new Class({ +var Zoom = new Class({ initialize: - function MultiFile (loader, type, key, files) + function Zoom (camera) { - var finalFiles = []; - - // Clean out any potential 'null' or 'undefined' file entries - files.forEach(function (file) - { - if (file) - { - finalFiles.push(file); - } - }); - /** - * A reference to the Loader that is going to load this file. + * The Camera this effect belongs to. * - * @name Phaser.Loader.MultiFile#loader - * @type {Phaser.Loader.LoaderPlugin} - * @since 3.7.0 + * @name Phaser.Cameras.Scene2D.Effects.Zoom#camera + * @type {Phaser.Cameras.Scene2D.Camera} + * @readonly + * @since 3.11.0 */ - this.loader = loader; + this.camera = camera; /** - * The file type string for sorting within the Loader. + * Is this effect actively running? * - * @name Phaser.Loader.MultiFile#type - * @type {string} - * @since 3.7.0 + * @name Phaser.Cameras.Scene2D.Effects.Zoom#isRunning + * @type {boolean} + * @readonly + * @default false + * @since 3.11.0 */ - this.type = type; + this.isRunning = false; /** - * Unique cache key (unique within its file type) + * The duration of the effect, in milliseconds. * - * @name Phaser.Loader.MultiFile#key - * @type {string} - * @since 3.7.0 + * @name Phaser.Cameras.Scene2D.Effects.Zoom#duration + * @type {number} + * @readonly + * @default 0 + * @since 3.11.0 */ - this.key = key; + this.duration = 0; /** - * The current index being used by multi-file loaders to avoid key clashes. + * The starting zoom value; * - * @name Phaser.Loader.MultiFile#multiKeyIndex + * @name Phaser.Cameras.Scene2D.Effects.Zoom#source * @type {number} - * @private - * @since 3.20.0 + * @since 3.11.0 */ - this.multiKeyIndex = loader.multiKeyIndex++; + this.source = 1; /** - * Array of files that make up this MultiFile. + * The destination zoom value. * - * @name Phaser.Loader.MultiFile#files - * @type {Phaser.Loader.File[]} - * @since 3.7.0 + * @name Phaser.Cameras.Scene2D.Effects.Zoom#destination + * @type {number} + * @since 3.11.0 */ - this.files = finalFiles; + this.destination = 1; /** - * The completion status of this MultiFile. + * The ease function to use during the zoom. * - * @name Phaser.Loader.MultiFile#complete - * @type {boolean} - * @default false - * @since 3.7.0 + * @name Phaser.Cameras.Scene2D.Effects.Zoom#ease + * @type {function} + * @since 3.11.0 */ - this.complete = false; + this.ease; /** - * The number of files to load. + * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. * - * @name Phaser.Loader.MultiFile#pending + * @name Phaser.Cameras.Scene2D.Effects.Zoom#progress * @type {number} - * @since 3.7.0 + * @since 3.11.0 */ - - this.pending = finalFiles.length; + this.progress = 0; /** - * The number of files that failed to load. + * Effect elapsed timer. * - * @name Phaser.Loader.MultiFile#failed + * @name Phaser.Cameras.Scene2D.Effects.Zoom#_elapsed * @type {number} - * @default 0 - * @since 3.7.0 + * @private + * @since 3.11.0 */ - this.failed = 0; + this._elapsed = 0; /** - * A storage container for transient data that the loading files need. + * This callback is invoked every frame for the duration of the effect. * - * @name Phaser.Loader.MultiFile#config - * @type {any} - * @since 3.7.0 + * @name Phaser.Cameras.Scene2D.Effects.Zoom#_onUpdate + * @type {?Phaser.Types.Cameras.Scene2D.CameraZoomCallback} + * @private + * @default null + * @since 3.11.0 */ - this.config = {}; + this._onUpdate; /** - * A reference to the Loaders baseURL at the time this MultiFile was created. - * Used to populate child-files. + * On Complete callback scope. * - * @name Phaser.Loader.MultiFile#baseURL - * @type {string} - * @since 3.20.0 + * @name Phaser.Cameras.Scene2D.Effects.Zoom#_onUpdateScope + * @type {any} + * @private + * @since 3.11.0 */ - this.baseURL = loader.baseURL; + this._onUpdateScope; + }, - /** - * A reference to the Loaders path at the time this MultiFile was created. - * Used to populate child-files. - * - * @name Phaser.Loader.MultiFile#path - * @type {string} - * @since 3.20.0 - */ - this.path = loader.path; + /** + * This effect will zoom the Camera to the given scale, over the duration and with the ease specified. + * + * @method Phaser.Cameras.Scene2D.Effects.Zoom#start + * @fires Phaser.Cameras.Scene2D.Events#ZOOM_START + * @fires Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE + * @since 3.11.0 + * + * @param {number} zoom - The target Camera zoom value. + * @param {number} [duration=1000] - The duration of the effect in milliseconds. + * @param {(string|function)} [ease='Linear'] - The ease to use for the Zoom. Can be any of the Phaser Easing constants or a custom function. + * @param {boolean} [force=false] - Force the zoom effect to start immediately, even if already running. + * @param {Phaser.Types.Cameras.Scene2D.CameraZoomCallback} [callback] - This callback will be invoked every frame for the duration of the effect. + * It is sent three arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, + * and the current camera zoom value. + * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * + * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. + */ + start: function (zoom, duration, ease, force, callback, context) + { + if (duration === undefined) { duration = 1000; } + if (ease === undefined) { ease = EaseMap.Linear; } + if (force === undefined) { force = false; } + if (callback === undefined) { callback = null; } + if (context === undefined) { context = this.camera.scene; } - /** - * A reference to the Loaders prefix at the time this MultiFile was created. - * Used to populate child-files. - * - * @name Phaser.Loader.MultiFile#prefix - * @type {string} - * @since 3.20.0 - */ - this.prefix = loader.prefix; + var cam = this.camera; - // Link the files - for (var i = 0; i < finalFiles.length; i++) + if (!force && this.isRunning) { - finalFiles[i].multiFile = this; + return cam; } + + this.isRunning = true; + this.duration = duration; + this.progress = 0; + + // Starting from + this.source = cam.zoom; + + // Zooming to + this.destination = zoom; + + // Using this ease + if (typeof ease === 'string' && EaseMap.hasOwnProperty(ease)) + { + this.ease = EaseMap[ease]; + } + else if (typeof ease === 'function') + { + this.ease = ease; + } + + this._elapsed = 0; + + this._onUpdate = callback; + this._onUpdateScope = context; + + this.camera.emit(Events.ZOOM_START, this.camera, this, duration, zoom); + + return cam; }, /** - * Checks if this MultiFile is ready to process its children or not. + * The main update loop for this effect. Called automatically by the Camera. * - * @method Phaser.Loader.MultiFile#isReadyToProcess - * @since 3.7.0 + * @method Phaser.Cameras.Scene2D.Effects.Zoom#update + * @since 3.11.0 * - * @return {boolean} `true` if all children of this MultiFile have loaded, otherwise `false`. + * @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. */ - isReadyToProcess: function () + update: function (time, delta) { - return (this.pending === 0 && this.failed === 0 && !this.complete); + if (!this.isRunning) + { + return; + } + + this._elapsed += delta; + + this.progress = Clamp(this._elapsed / this.duration, 0, 1); + + if (this._elapsed < this.duration) + { + this.camera.zoom = this.source + ((this.destination - this.source) * this.ease(this.progress)); + + if (this._onUpdate) + { + this._onUpdate.call(this._onUpdateScope, this.camera, this.progress, this.camera.zoom); + } + } + else + { + this.camera.zoom = this.destination; + + if (this._onUpdate) + { + this._onUpdate.call(this._onUpdateScope, this.camera, this.progress, this.destination); + } + + this.effectComplete(); + } }, /** - * Adds another child to this MultiFile, increases the pending count and resets the completion status. - * - * @method Phaser.Loader.MultiFile#addToMultiFile - * @since 3.7.0 - * - * @param {Phaser.Loader.File} files - The File to add to this MultiFile. + * Called internally when the effect completes. * - * @return {Phaser.Loader.MultiFile} This MultiFile instance. + * @method Phaser.Cameras.Scene2D.Effects.Zoom#effectComplete + * @fires Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE + * @since 3.11.0 */ - addToMultiFile: function (file) + effectComplete: function () { - this.files.push(file); - - file.multiFile = this; - - this.pending++; + this._onUpdate = null; + this._onUpdateScope = null; - this.complete = false; + this.isRunning = false; - return this; + this.camera.emit(Events.ZOOM_COMPLETE, this.camera, this); }, /** - * Called by each File when it finishes loading. - * - * @method Phaser.Loader.MultiFile#onFileComplete - * @since 3.7.0 + * Resets this camera effect. + * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. * - * @param {Phaser.Loader.File} file - The File that has completed processing. + * @method Phaser.Cameras.Scene2D.Effects.Zoom#reset + * @since 3.11.0 */ - onFileComplete: function (file) + reset: function () { - var index = this.files.indexOf(file); + this.isRunning = false; - if (index !== -1) - { - this.pending--; - } + this._onUpdate = null; + this._onUpdateScope = null; }, /** - * Called by each File that fails to load. - * - * @method Phaser.Loader.MultiFile#onFileFailed - * @since 3.7.0 + * Destroys this effect, releasing it from the Camera. * - * @param {Phaser.Loader.File} file - The File that has failed to load. + * @method Phaser.Cameras.Scene2D.Effects.Zoom#destroy + * @since 3.11.0 */ - onFileFailed: function (file) + destroy: function () { - var index = this.files.indexOf(file); + this.reset(); - if (index !== -1) - { - this.failed++; - } + this.camera = null; } }); -module.exports = MultiFile; +module.exports = Zoom; /***/ }), -/* 50 */ -/***/ (function(module, exports) { + +/***/ 53030: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Calculate the distance between two sets of coordinates (points). - * - * @function Phaser.Math.Distance.Between - * @since 3.0.0 - * - * @param {number} x1 - The x coordinate of the first point. - * @param {number} y1 - The y coordinate of the first point. - * @param {number} x2 - The x coordinate of the second point. - * @param {number} y2 - The y coordinate of the second point. - * - * @return {number} The distance between each point. + * @namespace Phaser.Cameras.Scene2D.Effects */ -var DistanceBetween = function (x1, y1, x2, y2) -{ - var dx = x1 - x2; - var dy = y1 - y2; - return Math.sqrt(dx * dx + dy * dy); -}; +module.exports = { -module.exports = DistanceBetween; + Fade: __webpack_require__(92522), + Flash: __webpack_require__(22151), + Pan: __webpack_require__(37551), + Shake: __webpack_require__(3241), + RotateTo: __webpack_require__(1771), + Zoom: __webpack_require__(13383) + +}; /***/ }), -/* 51 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 39577: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Input.Events + * The Destroy Camera Event. + * + * This event is dispatched by a Camera instance when it is destroyed by the Camera Manager. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('cameradestroy', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.DESTROY, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#DESTROY + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.BaseCamera} camera - The camera that was destroyed. */ +module.exports = 'cameradestroy'; -module.exports = { - BOOT: __webpack_require__(922), - DESTROY: __webpack_require__(923), - DRAG_END: __webpack_require__(924), - DRAG_ENTER: __webpack_require__(925), - DRAG: __webpack_require__(926), - DRAG_LEAVE: __webpack_require__(927), - DRAG_OVER: __webpack_require__(928), - DRAG_START: __webpack_require__(929), - DROP: __webpack_require__(930), - GAME_OUT: __webpack_require__(931), - GAME_OVER: __webpack_require__(932), - GAMEOBJECT_DOWN: __webpack_require__(933), - GAMEOBJECT_DRAG_END: __webpack_require__(934), - GAMEOBJECT_DRAG_ENTER: __webpack_require__(935), - GAMEOBJECT_DRAG: __webpack_require__(936), - GAMEOBJECT_DRAG_LEAVE: __webpack_require__(937), - GAMEOBJECT_DRAG_OVER: __webpack_require__(938), - GAMEOBJECT_DRAG_START: __webpack_require__(939), - GAMEOBJECT_DROP: __webpack_require__(940), - GAMEOBJECT_MOVE: __webpack_require__(941), - GAMEOBJECT_OUT: __webpack_require__(942), - GAMEOBJECT_OVER: __webpack_require__(943), - GAMEOBJECT_POINTER_DOWN: __webpack_require__(944), - GAMEOBJECT_POINTER_MOVE: __webpack_require__(945), - GAMEOBJECT_POINTER_OUT: __webpack_require__(946), - GAMEOBJECT_POINTER_OVER: __webpack_require__(947), - GAMEOBJECT_POINTER_UP: __webpack_require__(948), - GAMEOBJECT_POINTER_WHEEL: __webpack_require__(949), - GAMEOBJECT_UP: __webpack_require__(950), - GAMEOBJECT_WHEEL: __webpack_require__(951), - MANAGER_BOOT: __webpack_require__(952), - MANAGER_PROCESS: __webpack_require__(953), - MANAGER_UPDATE: __webpack_require__(954), - POINTER_DOWN: __webpack_require__(955), - POINTER_DOWN_OUTSIDE: __webpack_require__(956), - POINTER_MOVE: __webpack_require__(957), - POINTER_OUT: __webpack_require__(958), - POINTER_OVER: __webpack_require__(959), - POINTER_UP: __webpack_require__(960), - POINTER_UP_OUTSIDE: __webpack_require__(961), - POINTER_WHEEL: __webpack_require__(962), - POINTERLOCK_CHANGE: __webpack_require__(963), - PRE_UPDATE: __webpack_require__(964), - SHUTDOWN: __webpack_require__(965), - START: __webpack_require__(966), - UPDATE: __webpack_require__(967) - -}; - - -/***/ }), -/* 52 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. +/***/ }), + +/***/ 85373: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Positions the Game Object so that the top of its bounds aligns with the given coordinate. + * The Camera Fade In Complete Event. * - * @function Phaser.Display.Bounds.SetTop - * @since 3.0.0 + * This event is dispatched by a Camera instance when the Fade In Effect completes. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * Listen to it from a Camera instance using `Camera.on('camerafadeincomplete', listener)`. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. - * @param {number} value - The coordinate to position the Game Object bounds on. + * @event Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE + * @type {string} + * @since 3.3.0 * - * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Fade} effect - A reference to the effect instance. */ -var SetTop = function (gameObject, value) -{ - gameObject.y = value + (gameObject.height * gameObject.originY); - - return gameObject; -}; - -module.exports = SetTop; +module.exports = 'camerafadeincomplete'; /***/ }), -/* 53 */ -/***/ (function(module, exports) { + +/***/ 92057: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Positions the Game Object so that the left of its bounds aligns with the given coordinate. + * The Camera Fade In Start Event. * - * @function Phaser.Display.Bounds.SetLeft - * @since 3.0.0 + * This event is dispatched by a Camera instance when the Fade In Effect starts. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * Listen to it from a Camera instance using `Camera.on('camerafadeinstart', listener)`. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. - * @param {number} value - The coordinate to position the Game Object bounds on. + * @event Phaser.Cameras.Scene2D.Events#FADE_IN_START + * @type {string} + * @since 3.3.0 * - * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Fade} effect - A reference to the effect instance. + * @param {number} duration - The duration of the effect. + * @param {number} red - The red color channel value. + * @param {number} green - The green color channel value. + * @param {number} blue - The blue color channel value. */ -var SetLeft = function (gameObject, value) -{ - gameObject.x = value + (gameObject.width * gameObject.originX); - - return gameObject; -}; - -module.exports = SetLeft; +module.exports = 'camerafadeinstart'; /***/ }), -/* 54 */ -/***/ (function(module, exports) { + +/***/ 1903: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Positions the Game Object so that the left of its bounds aligns with the given coordinate. + * The Camera Fade Out Complete Event. * - * @function Phaser.Display.Bounds.SetRight - * @since 3.0.0 + * This event is dispatched by a Camera instance when the Fade Out Effect completes. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * Listen to it from a Camera instance using `Camera.on('camerafadeoutcomplete', listener)`. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. - * @param {number} value - The coordinate to position the Game Object bounds on. + * @event Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE + * @type {string} + * @since 3.3.0 * - * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Fade} effect - A reference to the effect instance. */ -var SetRight = function (gameObject, value) -{ - gameObject.x = (value - gameObject.width) + (gameObject.width * gameObject.originX); - - return gameObject; -}; - -module.exports = SetRight; +module.exports = 'camerafadeoutcomplete'; /***/ }), -/* 55 */ -/***/ (function(module, exports) { + +/***/ 96131: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Positions the Game Object so that the bottom of its bounds aligns with the given coordinate. + * The Camera Fade Out Start Event. * - * @function Phaser.Display.Bounds.SetBottom - * @since 3.0.0 + * This event is dispatched by a Camera instance when the Fade Out Effect starts. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * Listen to it from a Camera instance using `Camera.on('camerafadeoutstart', listener)`. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. - * @param {number} value - The coordinate to position the Game Object bounds on. + * @event Phaser.Cameras.Scene2D.Events#FADE_OUT_START + * @type {string} + * @since 3.3.0 * - * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Fade} effect - A reference to the effect instance. + * @param {number} duration - The duration of the effect. + * @param {number} red - The red color channel value. + * @param {number} green - The green color channel value. + * @param {number} blue - The blue color channel value. */ -var SetBottom = function (gameObject, value) -{ - gameObject.y = (value - gameObject.height) + (gameObject.height * gameObject.originY); - - return gameObject; -}; - -module.exports = SetBottom; +module.exports = 'camerafadeoutstart'; /***/ }), -/* 56 */ -/***/ (function(module, exports) { + +/***/ 85409: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GEOM_CONST = { - - /** - * A Circle Geometry object type. - * - * @name Phaser.Geom.CIRCLE - * @type {number} - * @since 3.19.0 - */ - CIRCLE: 0, - - /** - * An Ellipse Geometry object type. - * - * @name Phaser.Geom.ELLIPSE - * @type {number} - * @since 3.19.0 - */ - ELLIPSE: 1, - - /** - * A Line Geometry object type. - * - * @name Phaser.Geom.LINE - * @type {number} - * @since 3.19.0 - */ - LINE: 2, - - /** - * A Point Geometry object type. - * - * @name Phaser.Geom.POINT - * @type {number} - * @since 3.19.0 - */ - POINT: 3, - - /** - * A Polygon Geometry object type. - * - * @name Phaser.Geom.POLYGON - * @type {number} - * @since 3.19.0 - */ - POLYGON: 4, - - /** - * A Rectangle Geometry object type. - * - * @name Phaser.Geom.RECTANGLE - * @type {number} - * @since 3.19.0 - */ - RECTANGLE: 5, - - /** - * A Triangle Geometry object type. - * - * @name Phaser.Geom.TRIANGLE - * @type {number} - * @since 3.19.0 - */ - TRIANGLE: 6 - -}; - -module.exports = GEOM_CONST; +/** + * The Camera Flash Complete Event. + * + * This event is dispatched by a Camera instance when the Flash Effect completes. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('cameraflashcomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.FLASH_COMPLETE, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE + * @type {string} + * @since 3.3.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Flash} effect - A reference to the effect instance. + */ +module.exports = 'cameraflashcomplete'; /***/ }), -/* 57 */ -/***/ (function(module, exports) { + +/***/ 25500: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Checks if a given point is inside a Rectangle's bounds. + * The Camera Flash Start Event. * - * @function Phaser.Geom.Rectangle.Contains - * @since 3.0.0 + * This event is dispatched by a Camera instance when the Flash Effect starts. * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to check. - * @param {number} x - The X coordinate of the point to check. - * @param {number} y - The Y coordinate of the point to check. + * Listen for it via either of the following: * - * @return {boolean} `true` if the point is within the Rectangle's bounds, otherwise `false`. + * ```js + * this.cameras.main.on('cameraflashstart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.FLASH_START, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#FLASH_START + * @type {string} + * @since 3.3.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Flash} effect - A reference to the effect instance. + * @param {number} duration - The duration of the effect. + * @param {number} red - The red color channel value. + * @param {number} green - The green color channel value. + * @param {number} blue - The blue color channel value. */ -var Contains = function (rect, x, y) -{ - if (rect.width <= 0 || rect.height <= 0) - { - return false; - } - - return (rect.x <= x && rect.x + rect.width >= x && rect.y <= y && rect.y + rect.height >= y); -}; - -module.exports = Contains; +module.exports = 'cameraflashstart'; /***/ }), -/* 58 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 44071: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var DeepCopy = __webpack_require__(175); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(374); -var GetFastValue = __webpack_require__(2); -var Matrix4 = __webpack_require__(69); -var RendererEvents = __webpack_require__(91); -var RenderTarget = __webpack_require__(141); -var Utils = __webpack_require__(12); -var WebGLShader = __webpack_require__(375); - /** - * @classdesc - * The `WebGLPipeline` is a base class used by all of the core Phaser pipelines. + * The Camera Follower Update Event. * - * It describes the way elements will be rendered in WebGL. Internally, it handles - * compiling the shaders, creating vertex buffers, assigning primitive topology and - * binding vertex attributes, all based on the given configuration data. + * This event is dispatched by a Camera instance when it is following a + * Game Object and the Camera position has been updated as a result of + * that following. * - * The pipeline is configured by passing in a `WebGLPipelineConfig` object. Please - * see the documentation for this type to fully understand the configuration options - * available to you. + * Listen to it from a Camera instance using: `camera.on('followupdate', listener)`. * - * Usually, you would not extend from this class directly, but would instead extend - * from one of the core pipelines, such as the Multi Pipeline. + * @event Phaser.Cameras.Scene2D.Events#FOLLOW_UPDATE + * @type {string} + * @since 3.50.0 * - * The pipeline flow per render-step is as follows: + * @param {Phaser.Cameras.Scene2D.BaseCamera} camera - The camera that emitted the event. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the camera is following. + */ +module.exports = 'followupdate'; + + +/***/ }), + +/***/ 19818: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Pan Complete Event. * - * 1) onPreRender - called once at the start of the render step - * 2) onRender - call for each Scene Camera that needs to render (so can be multiple times per render step) - * 3) Internal flow: - * 3a) bind (only called if a Game Object is using this pipeline and it's not currently active) - * 3b) onBind (called for every Game Object that uses this pipeline) - * 3c) flush (can be called by a Game Object, internal method or from outside by changing pipeline) - * 4) onPostRender - called once at the end of the render step + * This event is dispatched by a Camera instance when the Pan Effect completes. * - * @class WebGLPipeline - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Renderer.WebGL - * @constructor + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerapancomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.PAN_COMPLETE, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#PAN_COMPLETE + * @type {string} + * @since 3.3.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Pan} effect - A reference to the effect instance. + */ +module.exports = 'camerapancomplete'; + + +/***/ }), + +/***/ 80002: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Pan Start Event. + * + * This event is dispatched by a Camera instance when the Pan Effect starts. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerapanstart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.PAN_START, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#PAN_START + * @type {string} + * @since 3.3.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Pan} effect - A reference to the effect instance. + * @param {number} duration - The duration of the effect. + * @param {number} x - The destination scroll x coordinate. + * @param {number} y - The destination scroll y coordinate. + */ +module.exports = 'camerapanstart'; + + +/***/ }), + +/***/ 87966: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Post-Render Event. + * + * This event is dispatched by a Camera instance after is has finished rendering. + * It is only dispatched if the Camera is rendering to a texture. + * + * Listen to it from a Camera instance using: `camera.on('postrender', listener)`. + * + * @event Phaser.Cameras.Scene2D.Events#POST_RENDER + * @type {string} * @since 3.0.0 * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration object for this WebGL Pipeline. + * @param {Phaser.Cameras.Scene2D.BaseCamera} camera - The camera that has finished rendering to a texture. */ -var WebGLPipeline = new Class({ +module.exports = 'postrender'; - Extends: EventEmitter, - initialize: +/***/ }), - function WebGLPipeline (config) - { - EventEmitter.call(this); +/***/ 74217: +/***/ ((module) => { - var game = config.game; - var renderer = game.renderer; - var gl = renderer.gl; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Pre-Render Event. + * + * This event is dispatched by a Camera instance when it is about to render. + * It is only dispatched if the Camera is rendering to a texture. + * + * Listen to it from a Camera instance using: `camera.on('prerender', listener)`. + * + * @event Phaser.Cameras.Scene2D.Events#PRE_RENDER + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.BaseCamera} camera - The camera that is about to render to a texture. + */ +module.exports = 'prerender'; + + +/***/ }), + +/***/ 34805: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Rotate Complete Event. + * + * This event is dispatched by a Camera instance when the Rotate Effect completes. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerarotatecomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.ROTATE_COMPLETE, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#ROTATE_COMPLETE + * @type {string} + * @since 3.23.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.RotateTo} effect - A reference to the effect instance. + */ +module.exports = 'camerarotatecomplete'; + + +/***/ }), + +/***/ 30408: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Rotate Start Event. + * + * This event is dispatched by a Camera instance when the Rotate Effect starts. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerarotatestart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.ROTATE_START, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#ROTATE_START + * @type {string} + * @since 3.23.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.RotateTo} effect - A reference to the effect instance. + * @param {number} duration - The duration of the effect. + * @param {number} destination - The destination value. + */ +module.exports = 'camerarotatestart'; + + +/***/ }), + +/***/ 49856: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Shake Complete Event. + * + * This event is dispatched by a Camera instance when the Shake Effect completes. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerashakecomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.SHAKE_COMPLETE, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE + * @type {string} + * @since 3.3.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Shake} effect - A reference to the effect instance. + */ +module.exports = 'camerashakecomplete'; + + +/***/ }), + +/***/ 69189: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Shake Start Event. + * + * This event is dispatched by a Camera instance when the Shake Effect starts. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerashakestart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.SHAKE_START, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#SHAKE_START + * @type {string} + * @since 3.3.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Shake} effect - A reference to the effect instance. + * @param {number} duration - The duration of the effect. + * @param {number} intensity - The intensity of the effect. + */ +module.exports = 'camerashakestart'; + + +/***/ }), + +/***/ 67657: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Zoom Complete Event. + * + * This event is dispatched by a Camera instance when the Zoom Effect completes. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerazoomcomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.ZOOM_COMPLETE, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE + * @type {string} + * @since 3.3.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Zoom} effect - A reference to the effect instance. + */ +module.exports = 'camerazoomcomplete'; + + +/***/ }), + +/***/ 14229: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Camera Zoom Start Event. + * + * This event is dispatched by a Camera instance when the Zoom Effect starts. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerazoomstart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.ZOOM_START, () => {}); + * ``` + * + * @event Phaser.Cameras.Scene2D.Events#ZOOM_START + * @type {string} + * @since 3.3.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. + * @param {Phaser.Cameras.Scene2D.Effects.Zoom} effect - A reference to the effect instance. + * @param {number} duration - The duration of the effect. + * @param {number} zoom - The destination zoom value. + */ +module.exports = 'camerazoomstart'; + + +/***/ }), + +/***/ 89787: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Cameras.Scene2D.Events + */ + +module.exports = { + + DESTROY: __webpack_require__(39577), + FADE_IN_COMPLETE: __webpack_require__(85373), + FADE_IN_START: __webpack_require__(92057), + FADE_OUT_COMPLETE: __webpack_require__(1903), + FADE_OUT_START: __webpack_require__(96131), + FLASH_COMPLETE: __webpack_require__(85409), + FLASH_START: __webpack_require__(25500), + FOLLOW_UPDATE: __webpack_require__(44071), + PAN_COMPLETE: __webpack_require__(19818), + PAN_START: __webpack_require__(80002), + POST_RENDER: __webpack_require__(87966), + PRE_RENDER: __webpack_require__(74217), + ROTATE_COMPLETE: __webpack_require__(34805), + ROTATE_START: __webpack_require__(30408), + SHAKE_COMPLETE: __webpack_require__(49856), + SHAKE_START: __webpack_require__(69189), + ZOOM_COMPLETE: __webpack_require__(67657), + ZOOM_START: __webpack_require__(14229) + +}; + + +/***/ }), + +/***/ 32356: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Cameras.Scene2D + */ + +module.exports = { + + Camera: __webpack_require__(47751), + BaseCamera: __webpack_require__(51052), + CameraManager: __webpack_require__(62382), + Effects: __webpack_require__(53030), + Events: __webpack_require__(89787) + +}; + + +/***/ }), + +/***/ 84219: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var GetValue = __webpack_require__(10850); + +/** + * @classdesc + * A Fixed Key Camera Control. + * + * This allows you to control the movement and zoom of a camera using the defined keys. + * + * ```javascript + * var camControl = new FixedKeyControl({ + * camera: this.cameras.main, + * left: cursors.left, + * right: cursors.right, + * speed: float OR { x: 0, y: 0 } + * }); + * ``` + * + * Movement is precise and has no 'smoothing' applied to it. + * + * You must call the `update` method of this controller every frame. + * + * @class FixedKeyControl + * @memberof Phaser.Cameras.Controls + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.Cameras.Controls.FixedKeyControlConfig} config - The Fixed Key Control configuration object. + */ +var FixedKeyControl = new Class({ + + initialize: + function FixedKeyControl (config) + { /** - * Name of the pipeline. Used for identification and setting from Game Objects. + * The Camera that this Control will update. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#name - * @type {string} + * @name Phaser.Cameras.Controls.FixedKeyControl#camera + * @type {?Phaser.Cameras.Scene2D.Camera} + * @default null * @since 3.0.0 */ - this.name = GetFastValue(config, 'name', 'WebGLPipeline'); + this.camera = GetValue(config, 'camera', null); /** - * The Phaser Game instance to which this pipeline is bound. + * The Key to be pressed that will move the Camera left. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#game - * @type {Phaser.Game} + * @name Phaser.Cameras.Controls.FixedKeyControl#left + * @type {?Phaser.Input.Keyboard.Key} + * @default null * @since 3.0.0 */ - this.game = game; + this.left = GetValue(config, 'left', null); /** - * The WebGL Renderer instance to which this pipeline is bound. + * The Key to be pressed that will move the Camera right. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#renderer - * @type {Phaser.Renderer.WebGL.WebGLRenderer} + * @name Phaser.Cameras.Controls.FixedKeyControl#right + * @type {?Phaser.Input.Keyboard.Key} + * @default null * @since 3.0.0 */ - this.renderer = renderer; + this.right = GetValue(config, 'right', null); /** - * A reference to the WebGL Pipeline Manager. + * The Key to be pressed that will move the Camera up. * - * This is initially undefined and only set when this pipeline is added - * to the manager. + * @name Phaser.Cameras.Controls.FixedKeyControl#up + * @type {?Phaser.Input.Keyboard.Key} + * @default null + * @since 3.0.0 + */ + this.up = GetValue(config, 'up', null); + + /** + * The Key to be pressed that will move the Camera down. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#manager - * @type {?Phaser.Renderer.WebGL.PipelineManager} - * @since 3.50.0 + * @name Phaser.Cameras.Controls.FixedKeyControl#down + * @type {?Phaser.Input.Keyboard.Key} + * @default null + * @since 3.0.0 */ - this.manager; + this.down = GetValue(config, 'down', null); /** - * The WebGL context this WebGL Pipeline uses. + * The Key to be pressed that will zoom the Camera in. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#gl - * @type {WebGLRenderingContext} + * @name Phaser.Cameras.Controls.FixedKeyControl#zoomIn + * @type {?Phaser.Input.Keyboard.Key} + * @default null * @since 3.0.0 */ - this.gl = gl; + this.zoomIn = GetValue(config, 'zoomIn', null); /** - * The canvas which this WebGL Pipeline renders to. + * The Key to be pressed that will zoom the Camera out. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#view - * @type {HTMLCanvasElement} + * @name Phaser.Cameras.Controls.FixedKeyControl#zoomOut + * @type {?Phaser.Input.Keyboard.Key} + * @default null * @since 3.0.0 */ - this.view = game.canvas; + this.zoomOut = GetValue(config, 'zoomOut', null); /** - * Width of the current viewport. + * The speed at which the camera will zoom if the `zoomIn` or `zoomOut` keys are pressed. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#width + * @name Phaser.Cameras.Controls.FixedKeyControl#zoomSpeed * @type {number} + * @default 0.01 * @since 3.0.0 */ - this.width = 0; + this.zoomSpeed = GetValue(config, 'zoomSpeed', 0.01); /** - * Height of the current viewport. + * The smallest zoom value the camera will reach when zoomed out. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#height + * @name Phaser.Cameras.Controls.FixedKeyControl#minZoom * @type {number} - * @since 3.0.0 + * @default 0.001 + * @since 3.53.0 */ - this.height = 0; + this.minZoom = GetValue(config, 'minZoom', 0.001); /** - * The current number of vertices that have been added to the pipeline batch. + * The largest zoom value the camera will reach when zoomed in. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexCount + * @name Phaser.Cameras.Controls.FixedKeyControl#maxZoom + * @type {number} + * @default 1000 + * @since 3.53.0 + */ + this.maxZoom = GetValue(config, 'maxZoom', 1000); + + /** + * The horizontal speed the camera will move. + * + * @name Phaser.Cameras.Controls.FixedKeyControl#speedX * @type {number} * @default 0 * @since 3.0.0 */ - this.vertexCount = 0; + this.speedX = 0; /** - * The total number of vertices that this pipeline batch can hold before it will flush. - * - * This defaults to `renderer batchSize * 6`, where `batchSize` is defined in the Renderer Game Config. + * The vertical speed the camera will move. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexCapacity + * @name Phaser.Cameras.Controls.FixedKeyControl#speedY * @type {number} + * @default 0 * @since 3.0.0 */ - this.vertexCapacity = 0; + this.speedY = 0; + + var speed = GetValue(config, 'speed', null); + + if (typeof speed === 'number') + { + this.speedX = speed; + this.speedY = speed; + } + else + { + this.speedX = GetValue(config, 'speed.x', 0); + this.speedY = GetValue(config, 'speed.y', 0); + } /** - * Raw byte buffer of vertices. - * - * Either set via the config object `vertices` property, or generates a new Array Buffer of - * size `vertexCapacity * vertexSize`. + * Internal property to track the current zoom level. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexData - * @type {ArrayBuffer} - * @readonly + * @name Phaser.Cameras.Controls.FixedKeyControl#_zoom + * @type {number} + * @private + * @default 0 * @since 3.0.0 */ - this.vertexData; + this._zoom = 0; /** - * The WebGLBuffer that holds the vertex data. - * - * Created from the `vertexData` ArrayBuffer. If `vertices` are set in the config, a `STATIC_DRAW` buffer - * is created. If not, a `DYNAMIC_DRAW` buffer is created. + * A flag controlling if the Controls will update the Camera or not. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexBuffer - * @type {WebGLBuffer} - * @readonly + * @name Phaser.Cameras.Controls.FixedKeyControl#active + * @type {boolean} * @since 3.0.0 */ - this.vertexBuffer; + this.active = (this.camera !== null); + }, + + /** + * Starts the Key Control running, providing it has been linked to a camera. + * + * @method Phaser.Cameras.Controls.FixedKeyControl#start + * @since 3.0.0 + * + * @return {this} This Key Control instance. + */ + start: function () + { + this.active = (this.camera !== null); + + return this; + }, + + /** + * Stops this Key Control from running. Call `start` to start it again. + * + * @method Phaser.Cameras.Controls.FixedKeyControl#stop + * @since 3.0.0 + * + * @return {this} This Key Control instance. + */ + stop: function () + { + this.active = false; + + return this; + }, + + /** + * Binds this Key Control to a camera. + * + * @method Phaser.Cameras.Controls.FixedKeyControl#setCamera + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to bind this Key Control to. + * + * @return {this} This Key Control instance. + */ + setCamera: function (camera) + { + this.camera = camera; + + return this; + }, + + /** + * Applies the results of pressing the control keys to the Camera. + * + * You must call this every step, it is not called automatically. + * + * @method Phaser.Cameras.Controls.FixedKeyControl#update + * @since 3.0.0 + * + * @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 (delta) + { + if (!this.active) + { + return; + } + + if (delta === undefined) { delta = 1; } + + var cam = this.camera; + + if (this.up && this.up.isDown) + { + cam.scrollY -= ((this.speedY * delta) | 0); + } + else if (this.down && this.down.isDown) + { + cam.scrollY += ((this.speedY * delta) | 0); + } + + if (this.left && this.left.isDown) + { + cam.scrollX -= ((this.speedX * delta) | 0); + } + else if (this.right && this.right.isDown) + { + cam.scrollX += ((this.speedX * delta) | 0); + } + + // Camera zoom + + if (this.zoomIn && this.zoomIn.isDown) + { + cam.zoom -= this.zoomSpeed; + + if (cam.zoom < this.minZoom) + { + cam.zoom = this.minZoom; + } + } + else if (this.zoomOut && this.zoomOut.isDown) + { + cam.zoom += this.zoomSpeed; + + if (cam.zoom > this.maxZoom) + { + cam.zoom = this.maxZoom; + } + } + }, + + /** + * Destroys this Key Control. + * + * @method Phaser.Cameras.Controls.FixedKeyControl#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.camera = null; + + this.left = null; + this.right = null; + this.up = null; + this.down = null; + + this.zoomIn = null; + this.zoomOut = null; + } + +}); + +module.exports = FixedKeyControl; + + +/***/ }), + +/***/ 69370: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var GetValue = __webpack_require__(10850); + +/** + * @classdesc + * A Smoothed Key Camera Control. + * + * This allows you to control the movement and zoom of a camera using the defined keys. + * Unlike the Fixed Camera Control you can also provide physics values for acceleration, drag and maxSpeed for smoothing effects. + * + * ```javascript + * var controlConfig = { + * camera: this.cameras.main, + * left: cursors.left, + * right: cursors.right, + * up: cursors.up, + * down: cursors.down, + * zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q), + * zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E), + * zoomSpeed: 0.02, + * acceleration: 0.06, + * drag: 0.0005, + * maxSpeed: 1.0 + * }; + * ``` + * + * You must call the `update` method of this controller every frame. + * + * @class SmoothedKeyControl + * @memberof Phaser.Cameras.Controls + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.Cameras.Controls.SmoothedKeyControlConfig} config - The Smoothed Key Control configuration object. + */ +var SmoothedKeyControl = new Class({ + initialize: + + function SmoothedKeyControl (config) + { /** - * The primitive topology which the pipeline will use to submit draw calls. - * - * Defaults to GL_TRIANGLES if not otherwise set in the config. + * The Camera that this Control will update. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#topology - * @type {GLenum} + * @name Phaser.Cameras.Controls.SmoothedKeyControl#camera + * @type {?Phaser.Cameras.Scene2D.Camera} + * @default null * @since 3.0.0 */ - this.topology = GetFastValue(config, 'topology', gl.TRIANGLES); + this.camera = GetValue(config, 'camera', null); /** - * Uint8 view to the `vertexData` ArrayBuffer. Used for uploading vertex buffer resources to the GPU. + * The Key to be pressed that will move the Camera left. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#bytes - * @type {Uint8Array} + * @name Phaser.Cameras.Controls.SmoothedKeyControl#left + * @type {?Phaser.Input.Keyboard.Key} + * @default null * @since 3.0.0 */ - this.bytes; + this.left = GetValue(config, 'left', null); /** - * Float32 view of the array buffer containing the pipeline's vertices. + * The Key to be pressed that will move the Camera right. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexViewF32 - * @type {Float32Array} + * @name Phaser.Cameras.Controls.SmoothedKeyControl#right + * @type {?Phaser.Input.Keyboard.Key} + * @default null * @since 3.0.0 */ - this.vertexViewF32; + this.right = GetValue(config, 'right', null); /** - * Uint32 view of the array buffer containing the pipeline's vertices. + * The Key to be pressed that will move the Camera up. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexViewU32 - * @type {Uint32Array} + * @name Phaser.Cameras.Controls.SmoothedKeyControl#up + * @type {?Phaser.Input.Keyboard.Key} + * @default null * @since 3.0.0 */ - this.vertexViewU32; + this.up = GetValue(config, 'up', null); /** - * Indicates if the current pipeline is active, or not. + * The Key to be pressed that will move the Camera down. * - * Toggle this property to enable or disable a pipeline from rendering anything. + * @name Phaser.Cameras.Controls.SmoothedKeyControl#down + * @type {?Phaser.Input.Keyboard.Key} + * @default null + * @since 3.0.0 + */ + this.down = GetValue(config, 'down', null); + + /** + * The Key to be pressed that will zoom the Camera in. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#active - * @type {boolean} - * @since 3.10.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#zoomIn + * @type {?Phaser.Input.Keyboard.Key} + * @default null + * @since 3.0.0 */ - this.active = true; + this.zoomIn = GetValue(config, 'zoomIn', null); /** - * Holds the most recently assigned texture unit. + * The Key to be pressed that will zoom the Camera out. * - * Treat this value as read-only. + * @name Phaser.Cameras.Controls.SmoothedKeyControl#zoomOut + * @type {?Phaser.Input.Keyboard.Key} + * @default null + * @since 3.0.0 + */ + this.zoomOut = GetValue(config, 'zoomOut', null); + + /** + * The speed at which the camera will zoom if the `zoomIn` or `zoomOut` keys are pressed. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#currentUnit + * @name Phaser.Cameras.Controls.SmoothedKeyControl#zoomSpeed * @type {number} - * @since 3.50.0 + * @default 0.01 + * @since 3.0.0 */ - this.currentUnit = 0; + this.zoomSpeed = GetValue(config, 'zoomSpeed', 0.01); /** - * Some pipelines require the forced use of texture zero (like the light pipeline). - * - * This property should be set when that is the case. + * The smallest zoom value the camera will reach when zoomed out. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#forceZero - * @type {boolean} - * @since 3.50.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#minZoom + * @type {number} + * @default 0.001 + * @since 3.53.0 */ - this.forceZero = GetFastValue(config, 'forceZero', false); + this.minZoom = GetValue(config, 'minZoom', 0.001); /** - * Indicates if this pipeline has booted or not. - * - * A pipeline boots only when the Game instance itself, and all associated systems, is - * fully ready. + * The largest zoom value the camera will reach when zoomed in. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#hasBooted - * @type {boolean} - * @readonly - * @since 3.50.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#maxZoom + * @type {number} + * @default 1000 + * @since 3.53.0 */ - this.hasBooted = false; + this.maxZoom = GetValue(config, 'maxZoom', 1000); /** - * Indicates if this is a Post FX Pipeline, or not. + * The horizontal acceleration the camera will move. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#isPostFX - * @type {boolean} - * @readonly - * @since 3.50.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#accelX + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.isPostFX = false; + this.accelX = 0; /** - * An array of RenderTarget instances that belong to this pipeline. + * The vertical acceleration the camera will move. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#renderTargets - * @type {Phaser.Renderer.WebGL.RenderTarget[]} - * @since 3.50.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#accelY + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.renderTargets = []; + this.accelY = 0; + + var accel = GetValue(config, 'acceleration', null); + + if (typeof accel === 'number') + { + this.accelX = accel; + this.accelY = accel; + } + else + { + this.accelX = GetValue(config, 'acceleration.x', 0); + this.accelY = GetValue(config, 'acceleration.y', 0); + } /** - * A reference to the currently bound Render Target instance from the `WebGLPipeline.renderTargets` array. + * The horizontal drag applied to the camera when it is moving. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#currentRenderTarget - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @since 3.50.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#dragX + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.currentRenderTarget; + this.dragX = 0; /** - * An array of all the WebGLShader instances that belong to this pipeline. - * - * Shaders manage their own attributes and uniforms, but share the same vertex data buffer, - * which belongs to this pipeline. - * - * Shaders are set in a call to the `setShadersFromConfig` method, which happens automatically, - * but can also be called at any point in your game. See the method documentation for details. + * The vertical drag applied to the camera when it is moving. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#shaders - * @type {Phaser.Renderer.WebGL.WebGLShader[]} - * @since 3.50.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#dragY + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.shaders = []; + this.dragY = 0; + + var drag = GetValue(config, 'drag', null); + + if (typeof drag === 'number') + { + this.dragX = drag; + this.dragY = drag; + } + else + { + this.dragX = GetValue(config, 'drag.x', 0); + this.dragY = GetValue(config, 'drag.y', 0); + } /** - * A reference to the currently bound WebGLShader instance from the `WebGLPipeline.shaders` array. - * - * For lots of pipelines, this is the only shader, so it is a quick way to reference it without - * an array look-up. + * The maximum horizontal speed the camera will move. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#currentShader - * @type {Phaser.Renderer.WebGL.WebGLShader} - * @since 3.50.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#maxSpeedX + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.currentShader; + this.maxSpeedX = 0; /** - * The Projection matrix, used by shaders as 'uProjectionMatrix' uniform. + * The maximum vertical speed the camera will move. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#projectionMatrix - * @type {Phaser.Math.Matrix4} - * @since 3.50.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#maxSpeedY + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.projectionMatrix; + this.maxSpeedY = 0; + + var maxSpeed = GetValue(config, 'maxSpeed', null); + + if (typeof maxSpeed === 'number') + { + this.maxSpeedX = maxSpeed; + this.maxSpeedY = maxSpeed; + } + else + { + this.maxSpeedX = GetValue(config, 'maxSpeed.x', 0); + this.maxSpeedY = GetValue(config, 'maxSpeed.y', 0); + } /** - * The cached width of the Projection matrix. + * Internal property to track the speed of the control. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#projectionWidth + * @name Phaser.Cameras.Controls.SmoothedKeyControl#_speedX * @type {number} - * @since 3.50.0 + * @private + * @default 0 + * @since 3.0.0 */ - this.projectionWidth = 0; + this._speedX = 0; /** - * The cached height of the Projection matrix. + * Internal property to track the speed of the control. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#projectionHeight + * @name Phaser.Cameras.Controls.SmoothedKeyControl#_speedY * @type {number} - * @since 3.50.0 + * @private + * @default 0 + * @since 3.0.0 */ - this.projectionHeight = 0; + this._speedY = 0; /** - * The configuration object that was used to create this pipeline. - * - * Treat this object as 'read only', because changing it post-creation will not - * impact this pipeline in any way. However, it is used internally for cloning - * and post-boot set-up. + * Internal property to track the zoom of the control. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#config - * @type {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} - * @since 3.50.0 + * @name Phaser.Cameras.Controls.SmoothedKeyControl#_zoom + * @type {number} + * @private + * @default 0 + * @since 3.0.0 */ - this.config = config; + this._zoom = 0; /** - * Has the GL Context been reset to the Phaser defaults since the last time - * this pipeline was bound? This is set automatically when the Pipeline Manager - * resets itself, usually after handing off to a 3rd party renderer like Spine. - * - * You should treat this property as read-only. + * A flag controlling if the Controls will update the Camera or not. * - * @name Phaser.Renderer.WebGL.WebGLPipeline#glReset + * @name Phaser.Cameras.Controls.SmoothedKeyControl#active * @type {boolean} - * @since 3.53.0 + * @since 3.0.0 */ - this.glReset = false; + this.active = (this.camera !== null); }, /** - * Called when the Game has fully booted and the Renderer has finished setting up. + * Starts the Key Control running, providing it has been linked to a camera. * - * By this stage all Game level systems are now in place. You can perform any final tasks that the - * pipeline may need, that relies on game systems such as the Texture Manager being ready. + * @method Phaser.Cameras.Controls.SmoothedKeyControl#start + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.WebGLPipeline#boot - * @fires Phaser.Renderer.WebGL.Pipelines.Events#BOOT - * @since 3.11.0 + * @return {this} This Key Control instance. */ - boot: function () + start: function () { - var i; - var gl = this.gl; - var config = this.config; - var renderer = this.renderer; + this.active = (this.camera !== null); - if (!this.isPostFX) - { - this.projectionMatrix = new Matrix4().identity(); - } - - // Create the Render Targets - - var renderTargets = this.renderTargets; - - var targets = GetFastValue(config, 'renderTarget', false); - - // If boolean, set to number = 1 - if (typeof(targets) === 'boolean' && targets) - { - targets = 1; - } - - var width = renderer.width; - var height = renderer.height; - - if (typeof(targets) === 'number') - { - // Create this many default RTs - for (i = 0; i < targets; i++) - { - renderTargets.push(new RenderTarget(renderer, width, height, 1, 0, true)); - } - } - else if (Array.isArray(targets)) - { - for (i = 0; i < targets.length; i++) - { - var scale = GetFastValue(targets[i], 'scale', 1); - var minFilter = GetFastValue(targets[i], 'minFilter', 0); - var autoClear = GetFastValue(targets[i], 'autoClear', 1); - - renderTargets.push(new RenderTarget(renderer, width, height, scale, minFilter, autoClear)); - } - } - - if (renderTargets.length) - { - // Default to the first one in the array - this.currentRenderTarget = renderTargets[0]; - } - - // Create the Shaders - - this.setShadersFromConfig(config); - - // Which shader has the largest vertex size? - var shaders = this.shaders; - var vertexSize = 0; - - for (i = 0; i < shaders.length; i++) - { - if (shaders[i].vertexSize > vertexSize) - { - vertexSize = shaders[i].vertexSize; - } - } - - var batchSize = GetFastValue(config, 'batchSize', renderer.config.batchSize); - - // * 6 because there are 6 vertices in a quad and 'batchSize' represents the quantity of quads in the batch - - this.vertexCapacity = batchSize * 6; - - var data = new ArrayBuffer(this.vertexCapacity * vertexSize); - - this.vertexData = data; - this.bytes = new Uint8Array(data); - this.vertexViewF32 = new Float32Array(data); - this.vertexViewU32 = new Uint32Array(data); - - var configVerts = GetFastValue(config, 'vertices', null); - - if (configVerts) - { - this.vertexViewF32.set(configVerts); - - this.vertexBuffer = renderer.createVertexBuffer(data, gl.STATIC_DRAW); - } - else - { - this.vertexBuffer = renderer.createVertexBuffer(data.byteLength, gl.DYNAMIC_DRAW); - } - - // Set-up shaders - - this.setVertexBuffer(); - - for (i = shaders.length - 1; i >= 0; i--) - { - shaders[i].rebind(); - } - - this.hasBooted = true; - - renderer.on(RendererEvents.RESIZE, this.resize, this); - renderer.on(RendererEvents.PRE_RENDER, this.onPreRender, this); - renderer.on(RendererEvents.RENDER, this.onRender, this); - renderer.on(RendererEvents.POST_RENDER, this.onPostRender, this); - - this.emit(Events.BOOT, this); - - this.onBoot(); - }, + return this; + }, /** - * This method is called once when this pipeline has finished being set-up - * at the end of the boot process. By the time this method is called, all - * of the shaders are ready and configured. + * Stops this Key Control from running. Call `start` to start it again. * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onBoot - * @since 3.50.0 + * @method Phaser.Cameras.Controls.SmoothedKeyControl#stop + * @since 3.0.0 + * + * @return {this} This Key Control instance. */ - onBoot: function () + stop: function () { + this.active = false; + + return this; }, /** - * This method is called once when this pipeline has finished being set-up - * at the end of the boot process. By the time this method is called, all - * of the shaders are ready and configured. It's also called if the renderer - * changes size. + * Binds this Key Control to a camera. * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onResize - * @since 3.50.0 + * @method Phaser.Cameras.Controls.SmoothedKeyControl#setCamera + * @since 3.0.0 * - * @param {number} width - The new width of this WebGL Pipeline. - * @param {number} height - The new height of this WebGL Pipeline. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to bind this Key Control to. + * + * @return {this} This Key Control instance. */ - onResize: function () + setCamera: function (camera) { + this.camera = camera; + + return this; }, /** - * Sets the currently active shader within this pipeline. + * Applies the results of pressing the control keys to the Camera. * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setShader - * @since 3.50.0 + * You must call this every step, it is not called automatically. * - * @param {Phaser.Renderer.WebGL.WebGLShader} shader - The shader to set as being current. - * @param {boolean} [setAttributes=false] - Should the vertex attribute pointers be set? + * @method Phaser.Cameras.Controls.SmoothedKeyControl#update + * @since 3.0.0 * - * @return {this} This WebGLPipeline instance. + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. */ - setShader: function (shader, setAttributes) + update: function (delta) { - var renderer = this.renderer; - - if (shader !== this.currentShader || renderer.currentProgram !== this.currentShader.program) + if (!this.active) { - this.flush(); + return; + } - renderer.resetTextures(); + if (delta === undefined) { delta = 1; } - var wasBound = this.setVertexBuffer(); + var cam = this.camera; - if (wasBound && !setAttributes) - { - setAttributes = true; - } + // Apply Deceleration - shader.bind(setAttributes, false); + if (this._speedX > 0) + { + this._speedX -= this.dragX * delta; - this.currentShader = shader; + if (this._speedX < 0) + { + this._speedX = 0; + } } - - return this; - }, - - /** - * Searches all shaders in this pipeline for one matching the given name, then returns it. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#getShaderByName - * @since 3.50.0 - * - * @param {string} name - The index of the shader to set. - * - * @return {Phaser.Renderer.WebGL.WebGLShader} The WebGLShader instance, if found. - */ - getShaderByName: function (name) - { - var shaders = this.shaders; - - for (var i = 0; i < shaders.length; i++) + else if (this._speedX < 0) { - if (shaders[i].name === name) + this._speedX += this.dragX * delta; + + if (this._speedX > 0) { - return shaders[i]; + this._speedX = 0; } } - }, - - /** - * Destroys all shaders currently set in the `WebGLPipeline.shaders` array and then parses the given - * `config` object, extracting the shaders from it, creating `WebGLShader` instances and finally - * setting them into the `shaders` array of this pipeline. - * - * This is a destructive process. Be very careful when you call it, should you need to. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setShadersFromConfig - * @since 3.50.0 - * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration object for this WebGL Pipeline. - * - * @return {this} This WebGLPipeline instance. - */ - setShadersFromConfig: function (config) - { - var i; - var shaders = this.shaders; - var renderer = this.renderer; - for (i = 0; i < shaders.length; i++) + if (this._speedY > 0) { - shaders[i].destroy(); - } - - var vName = 'vertShader'; - var fName = 'fragShader'; - var aName = 'attributes'; + this._speedY -= this.dragY * delta; - var defaultVertShader = GetFastValue(config, vName, null); - var defaultFragShader = Utils.parseFragmentShaderMaxTextures(GetFastValue(config, fName, null), renderer.maxTextures); - var defaultAttribs = GetFastValue(config, aName, null); + if (this._speedY < 0) + { + this._speedY = 0; + } + } + else if (this._speedY < 0) + { + this._speedY += this.dragY * delta; - var configShaders = GetFastValue(config, 'shaders', []); + if (this._speedY > 0) + { + this._speedY = 0; + } + } - var len = configShaders.length; + // Check for keys - if (len === 0) + if (this.up && this.up.isDown) { - if (defaultVertShader && defaultFragShader) + this._speedY += this.accelY; + + if (this._speedY > this.maxSpeedY) { - this.shaders = [ new WebGLShader(this, 'default', defaultVertShader, defaultFragShader, DeepCopy(defaultAttribs)) ]; + this._speedY = this.maxSpeedY; } } - else + else if (this.down && this.down.isDown) { - var newShaders = []; + this._speedY -= this.accelY; - for (i = 0; i < len; i++) + if (this._speedY < -this.maxSpeedY) { - var shaderEntry = configShaders[i]; - - var name = GetFastValue(shaderEntry, 'name', 'default'); + this._speedY = -this.maxSpeedY; + } + } - var vertShader = GetFastValue(shaderEntry, vName, defaultVertShader); - var fragShader = Utils.parseFragmentShaderMaxTextures(GetFastValue(shaderEntry, fName, defaultFragShader), renderer.maxTextures); - var attributes = GetFastValue(shaderEntry, aName, defaultAttribs); + if (this.left && this.left.isDown) + { + this._speedX += this.accelX; - if (vertShader && fragShader) - { - newShaders.push(new WebGLShader(this, name, vertShader, fragShader, DeepCopy(attributes))); - } + if (this._speedX > this.maxSpeedX) + { + this._speedX = this.maxSpeedX; } + } + else if (this.right && this.right.isDown) + { + this._speedX -= this.accelX; - this.shaders = newShaders; + if (this._speedX < -this.maxSpeedX) + { + this._speedX = -this.maxSpeedX; + } } - if (this.shaders.length === 0) + // Camera zoom + + if (this.zoomIn && this.zoomIn.isDown) { - console.warn('Pipeline: ' + this.name + ' - Invalid shader config'); + this._zoom = -this.zoomSpeed; } - else + else if (this.zoomOut && this.zoomOut.isDown) { - this.currentShader = this.shaders[0]; + this._zoom = this.zoomSpeed; } - - return this; - }, - - /** - * Custom pipelines can use this method in order to perform any required pre-batch tasks - * for the given Game Object. It must return the texture unit the Game Object was assigned. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setGameObject - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object being rendered or added to the batch. - * @param {Phaser.Textures.Frame} [frame] - Optional frame to use. Can override that of the Game Object. - * - * @return {number} The texture unit the Game Object has been assigned. - */ - setGameObject: function (gameObject, frame) - { - if (frame === undefined) { frame = gameObject.frame; } - - this.currentUnit = this.renderer.setTextureSource(frame.source); - - return this.currentUnit; - }, - - /** - * Check if the current batch of vertices is full. - * - * You can optionally provide an `amount` parameter. If given, it will check if the batch - * needs to flush _if_ the `amount` is added to it. This allows you to test if you should - * flush before populating the batch. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#shouldFlush - * @since 3.0.0 - * - * @param {number} [amount=0] - Will the batch need to flush if this many vertices are added to it? - * - * @return {boolean} `true` if the current batch should be flushed, otherwise `false`. - */ - shouldFlush: function (amount) - { - if (amount === undefined) { amount = 0; } - - return (this.vertexCount + amount > this.vertexCapacity); - }, - - /** - * Resizes the properties used to describe the viewport. - * - * This method is called automatically by the renderer during its resize handler. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#resize - * @fires Phaser.Renderer.WebGL.Pipelines.Events#RESIZE - * @since 3.0.0 - * - * @param {number} width - The new width of this WebGL Pipeline. - * @param {number} height - The new height of this WebGL Pipeline. - * - * @return {this} This WebGLPipeline instance. - */ - resize: function (width, height) - { - if (width !== this.width || height !== this.height) + else { - this.flush(); + this._zoom = 0; } - this.width = width; - this.height = height; - - var targets = this.renderTargets; + // Apply to Camera - for (var i = 0; i < targets.length; i++) + if (this._speedX !== 0) { - targets[i].resize(width, height); + cam.scrollX -= ((this._speedX * delta) | 0); } - this.setProjectionMatrix(width, height); - - this.emit(Events.RESIZE, width, height, this); - - this.onResize(width, height); - - return this; - }, - - /** - * Adjusts this pipelines ortho Projection Matrix to use the given dimensions - * and resets the `uProjectionMatrix` uniform on all bound shaders. - * - * This method is called automatically by the renderer during its resize handler. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setProjectionMatrix - * @since 3.50.0 - * - * @param {number} width - The new width of this WebGL Pipeline. - * @param {number} height - The new height of this WebGL Pipeline. - * - * @return {this} This WebGLPipeline instance. - */ - setProjectionMatrix: function (width, height) - { - var projectionMatrix = this.projectionMatrix; - - // Because not all pipelines have them - if (!projectionMatrix) + if (this._speedY !== 0) { - return this; + cam.scrollY -= ((this._speedY * delta) | 0); } - this.projectionWidth = width; - this.projectionHeight = height; - - projectionMatrix.ortho(0, width, height, 0, -1000, 1000); - - var shaders = this.shaders; - - var name = 'uProjectionMatrix'; - - for (var i = 0; i < shaders.length; i++) + if (this._zoom !== 0) { - var shader = shaders[i]; + cam.zoom += this._zoom; - if (shader.hasUniform(name)) + if (cam.zoom < this.minZoom) { - shader.resetUniform(name); - - shader.setMatrix4fv(name, false, projectionMatrix.val, shader); + cam.zoom = this.minZoom; } - } - - return this; - }, - - /** - * Adjusts this pipelines ortho Projection Matrix to match that of the global - * WebGL Renderer Projection Matrix. - * - * This method is called automatically by the Pipeline Manager when this - * pipeline is set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#updateProjectionMatrix - * @since 3.50.0 - */ - updateProjectionMatrix: function () - { - if (this.projectionMatrix) - { - var globalWidth = this.renderer.projectionWidth; - var globalHeight = this.renderer.projectionHeight; - - if (this.projectionWidth !== globalWidth || this.projectionHeight !== globalHeight) + else if (cam.zoom > this.maxZoom) { - this.setProjectionMatrix(globalWidth, globalHeight); + cam.zoom = this.maxZoom; } } }, /** - * This method is called every time the Pipeline Manager makes this pipeline the currently active one. - * - * It binds the resources and shader needed for this pipeline, including setting the vertex buffer - * and attribute pointers. + * Destroys this Key Control. * - * @method Phaser.Renderer.WebGL.WebGLPipeline#bind - * @fires Phaser.Renderer.WebGL.Pipelines.Events#BIND + * @method Phaser.Cameras.Controls.SmoothedKeyControl#destroy * @since 3.0.0 - * - * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. - * - * @return {this} This WebGLPipeline instance. */ - bind: function (currentShader) + destroy: function () { - if (currentShader === undefined) { currentShader = this.currentShader; } - - if (this.glReset) - { - return this.rebind(currentShader); - } + this.camera = null; - var wasBound = this.setVertexBuffer(); + this.left = null; + this.right = null; + this.up = null; + this.down = null; - currentShader.bind(wasBound); + this.zoomIn = null; + this.zoomOut = null; + } - this.currentShader = currentShader; +}); - this.emit(Events.BIND, this, currentShader); +module.exports = SmoothedKeyControl; - this.onActive(currentShader); - return this; - }, +/***/ }), - /** - * This method is called every time the Pipeline Manager rebinds this pipeline. - * - * It resets all shaders this pipeline uses, setting their attributes again. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#rebind - * @fires Phaser.Renderer.WebGL.Pipelines.Events#REBIND - * @since 3.0.0 - * - * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. - * - * @return {this} This WebGLPipeline instance. - */ - rebind: function (currentShader) - { - this.setVertexBuffer(); +/***/ 6524: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var shaders = this.shaders; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Loop in reverse, so the first shader in the array is left as being bound - for (var i = shaders.length - 1; i >= 0; i--) - { - var shader = shaders[i].rebind(); +/** + * @namespace Phaser.Cameras.Controls + */ - if (!currentShader || shader === currentShader) - { - this.currentShader = shader; - } - } +module.exports = { - this.emit(Events.REBIND, this.currentShader); + FixedKeyControl: __webpack_require__(84219), + SmoothedKeyControl: __webpack_require__(69370) - this.onActive(this.currentShader); +}; - this.onRebind(); - this.glReset = false; +/***/ }), - return this; - }, +/***/ 44143: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Binds the vertex buffer to be the active ARRAY_BUFFER on the WebGL context. - * - * It first checks to see if it's already set as the active buffer and only - * binds itself if not. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setVertexBuffer - * @since 3.50.0 - * - * @return {boolean} `true` if the vertex buffer was bound, or `false` if it was already bound. - */ - setVertexBuffer: function () - { - var gl = this.gl; - var buffer = this.vertexBuffer; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (gl.getParameter(gl.ARRAY_BUFFER_BINDING) !== buffer) - { - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); +/** + * @namespace Phaser.Cameras + */ - return true; - } +/** + * @namespace Phaser.Types.Cameras + */ - return false; - }, +module.exports = { - /** - * This method is called as a result of the `WebGLPipeline.batchQuad` method, right before a quad - * belonging to a Game Object is about to be added to the batch. When this is called, the - * renderer has just performed a flush. It will bind the current render target, if any are set - * and finally call the `onPreBatch` hook. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#preBatch - * @since 3.50.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.Cameras.Scene2D.Camera)} [gameObject] - The Game Object or Camera that invoked this pipeline, if any. - * - * @return {this} This WebGLPipeline instance. - */ - preBatch: function (gameObject) - { - if (this.currentRenderTarget) - { - this.currentRenderTarget.bind(); - } + Controls: __webpack_require__(6524), + Scene2D: __webpack_require__(32356) - this.onPreBatch(gameObject); +}; - return this; - }, - /** - * This method is called as a result of the `WebGLPipeline.batchQuad` method, right after a quad - * belonging to a Game Object has been added to the batch. When this is called, the - * renderer has just performed a flush. - * - * It calls the `onDraw` hook followed by the `onPostBatch` hook, which can be used to perform - * additional Post FX Pipeline processing. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#postBatch - * @since 3.50.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.Cameras.Scene2D.Camera)} [gameObject] - The Game Object or Camera that invoked this pipeline, if any. - * - * @return {this} This WebGLPipeline instance. - */ - postBatch: function (gameObject) - { - this.onDraw(this.currentRenderTarget); +/***/ }), - this.onPostBatch(gameObject); +/***/ 86459: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * This method is only used by Post FX Pipelines and those that extend from them. - * - * This method is called every time the `postBatch` method is called and is passed a - * reference to the current render target. - * - * At the very least a Post FX Pipeline should call `this.bindAndDraw(renderTarget)`, - * however, you can do as much additional processing as you like in this method if - * you override it from within your own pipelines. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onDraw - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} renderTarget - The Render Target. - */ - onDraw: function () - { - }, +/** + * Global constants. + * + * @ignore + */ - /** - * This method is called every time the Pipeline Manager deactivates this pipeline, swapping from - * it to another one. This happens after a call to `flush` and before the new pipeline is bound. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#unbind - * @since 3.50.0 - */ - unbind: function () - { - if (this.currentRenderTarget) - { - this.currentRenderTarget.unbind(); - } - }, +var CONST = { /** - * Uploads the vertex data and emits a draw call for the current batch of vertices. + * Phaser Release Version * - * @method Phaser.Renderer.WebGL.WebGLPipeline#flush - * @fires Phaser.Renderer.WebGL.Pipelines.Events#BEFORE_FLUSH - * @fires Phaser.Renderer.WebGL.Pipelines.Events#AFTER_FLUSH + * @name Phaser.VERSION + * @const + * @type {string} * @since 3.0.0 - * - * @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not? - * - * @return {this} This WebGLPipeline instance. */ - flush: function (isPostFlush) - { - if (isPostFlush === undefined) { isPostFlush = false; } - - if (this.vertexCount > 0) - { - this.emit(Events.BEFORE_FLUSH, this, isPostFlush); - - this.onBeforeFlush(isPostFlush); - - var gl = this.gl; - var vertexCount = this.vertexCount; - var vertexSize = this.currentShader.vertexSize; - - if (this.active) - { - this.setVertexBuffer(); - - if (vertexCount === this.vertexCapacity) - { - gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.DYNAMIC_DRAW); - } - else - { - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bytes.subarray(0, vertexCount * vertexSize)); - } - - gl.drawArrays(this.topology, 0, vertexCount); - } - - this.vertexCount = 0; - - this.emit(Events.AFTER_FLUSH, this, isPostFlush); + VERSION: '3.60.0', - this.onAfterFlush(isPostFlush); - } + BlendModes: __webpack_require__(95723), - return this; - }, + ScaleModes: __webpack_require__(27394), /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called every time the Pipeline Manager makes this the active pipeline. It is called - * at the end of the `WebGLPipeline.bind` method, after the current shader has been set. The current - * shader is passed to this hook. - * - * For example, if a display list has 3 Sprites in it that all use the same pipeline, this hook will - * only be called for the first one, as the 2nd and 3rd Sprites do not cause the pipeline to be changed. - * - * If you need to listen for that event instead, use the `onBind` hook. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onActive - * @since 3.50.0 + * This setting will auto-detect if the browser is capable of suppporting WebGL. + * If it is, it will use the WebGL Renderer. If not, it will fall back to the Canvas Renderer. * - * @param {Phaser.Renderer.WebGL.WebGLShader} currentShader - The shader that was set as current. + * @name Phaser.AUTO + * @const + * @type {number} + * @since 3.0.0 */ - onActive: function () - { - }, + AUTO: 0, /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called every time a **Game Object** asks the Pipeline Manager to use this pipeline, - * even if the pipeline is already active. - * - * Unlike the `onActive` method, which is only called when the Pipeline Manager makes this pipeline - * active, this hook is called for every Game Object that requests use of this pipeline, allowing you to - * perform per-object set-up, such as loading shader uniform data. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onBind - * @since 3.50.0 + * Forces Phaser to only use the Canvas Renderer, regardless if the browser supports + * WebGL or not. * - * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. + * @name Phaser.CANVAS + * @const + * @type {number} + * @since 3.0.0 */ - onBind: function () - { - }, + CANVAS: 1, /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called when the Pipeline Manager needs to rebind this pipeline. This happens after a - * pipeline has been cleared, usually when passing control over to a 3rd party WebGL library, like Spine, - * and then returing to Phaser again. + * Forces Phaser to use the WebGL Renderer. If the browser does not support it, there is + * no fallback to Canvas with this setting, so you should trap it and display a suitable + * message to the user. * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onRebind - * @since 3.50.0 + * @name Phaser.WEBGL + * @const + * @type {number} + * @since 3.0.0 */ - onRebind: function () - { - }, + WEBGL: 2, /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called every time the `batchQuad` or `batchTri` methods are called. If this was - * as a result of a Game Object, then the Game Object reference is passed to this hook too. - * - * This hook is called _after_ the quad (or tri) has been added to the batch, so you can safely - * call 'flush' from within this. - * - * Note that Game Objects may call `batchQuad` or `batchTri` multiple times for a single draw, - * for example the Graphics Game Object. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onBatch - * @since 3.50.0 + * A Headless Renderer doesn't create either a Canvas or WebGL Renderer. However, it still + * absolutely relies on the DOM being present and available. This mode is meant for unit testing, + * not for running Phaser on the server, which is something you really shouldn't do. * - * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. + * @name Phaser.HEADLESS + * @const + * @type {number} + * @since 3.0.0 */ - onBatch: function () - { - }, + HEADLESS: 3, /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called immediately before a **Game Object** is about to add itself to the batch. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onPreBatch - * @since 3.50.0 + * In Phaser the value -1 means 'forever' in lots of cases, this const allows you to use it instead + * to help you remember what the value is doing in your code. * - * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. + * @name Phaser.FOREVER + * @const + * @type {number} + * @since 3.0.0 */ - onPreBatch: function () - { - }, + FOREVER: -1, /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called immediately after a **Game Object** has been added to the batch. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onPostBatch - * @since 3.50.0 + * Direction constant. * - * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. + * @name Phaser.NONE + * @const + * @type {number} + * @since 3.0.0 */ - onPostBatch: function () - { - }, + NONE: 4, /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called once per frame, right before anything has been rendered, but after the canvas - * has been cleared. If this pipeline has a render target, it will also have been cleared by this point. + * Direction constant. * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onPreRender - * @since 3.50.0 + * @name Phaser.UP + * @const + * @type {number} + * @since 3.0.0 */ - onPreRender: function () - { - }, + UP: 5, /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called _once per frame_, by every Camera in a Scene that wants to render. - * - * It is called at the start of the rendering process, before anything has been drawn to the Camera. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onRender - * @since 3.50.0 + * Direction constant. * - * @param {Phaser.Scene} scene - The Scene being rendered. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered with. + * @name Phaser.DOWN + * @const + * @type {number} + * @since 3.0.0 */ - onRender: function () - { - }, + DOWN: 6, /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called _once per frame_, after all rendering has happened and snapshots have been taken. - * - * It is called at the very end of the rendering process, once all Cameras, for all Scenes, have - * been rendered. + * Direction constant. * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onPostRender - * @since 3.50.0 + * @name Phaser.LEFT + * @const + * @type {number} + * @since 3.0.0 */ - onPostRender: function () - { - }, + LEFT: 7, /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called every time this pipeline is asked to flush its batch. - * - * It is called immediately before the `gl.bufferData` and `gl.drawArrays` calls are made, so you can - * perform any final pre-render modifications. To apply changes post-render, see `onAfterFlush`. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onBeforeFlush - * @since 3.50.0 + * Direction constant. * - * @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not? + * @name Phaser.RIGHT + * @const + * @type {number} + * @since 3.0.0 */ - onBeforeFlush: function () - { - }, + RIGHT: 8 - /** - * By default this is an empty method hook that you can override and use in your own custom pipelines. - * - * This method is called immediately after this pipeline has finished flushing its batch. - * - * It is called after the `gl.drawArrays` call. - * - * You can perform additional post-render effects, but be careful not to call `flush` - * on this pipeline from within this method, or you'll cause an infinite loop. - * - * To apply changes pre-render, see `onBeforeFlush`. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#onAfterFlush - * @since 3.50.0 - * - * @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not? - */ - onAfterFlush: function () - { - }, +}; - /** - * Adds a single vertex to the current vertex buffer and increments the - * `vertexCount` property by 1. - * - * This method is called directly by `batchTri` and `batchQuad`. - * - * It does not perform any batch limit checking itself, so if you need to call - * this method directly, do so in the same way that `batchQuad` does, for example. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#batchVert - * @since 3.50.0 - * - * @param {number} x - The vertex x position. - * @param {number} y - The vertex y position. - * @param {number} u - UV u value. - * @param {number} v - UV v value. - * @param {number} unit - Texture unit to which the texture needs to be bound. - * @param {(number|boolean)} tintEffect - The tint effect for the shader to use. - * @param {number} tint - The tint color value. - */ - batchVert: function (x, y, u, v, unit, tintEffect, tint) - { - var vertexViewF32 = this.vertexViewF32; - var vertexViewU32 = this.vertexViewU32; +module.exports = CONST; - var vertexOffset = (this.vertexCount * this.currentShader.vertexComponentCount) - 1; - vertexViewF32[++vertexOffset] = x; - vertexViewF32[++vertexOffset] = y; - vertexViewF32[++vertexOffset] = u; - vertexViewF32[++vertexOffset] = v; - vertexViewF32[++vertexOffset] = unit; - vertexViewF32[++vertexOffset] = tintEffect; - vertexViewU32[++vertexOffset] = tint; +/***/ }), - this.vertexCount++; - }, +/***/ 14033: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Adds the vertices data into the batch and flushes if full. - * - * Assumes 6 vertices in the following arrangement: - * - * ``` - * 0----3 - * |\ B| - * | \ | - * | \ | - * | A \| - * | \ - * 1----2 - * ``` - * - * Where tx0/ty0 = 0, tx1/ty1 = 1, tx2/ty2 = 2 and tx3/ty3 = 3 - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#batchQuad - * @since 3.50.0 - * - * @param {(Phaser.GameObjects.GameObject|null)} gameObject - The Game Object, if any, drawing this quad. - * @param {number} x0 - The top-left x position. - * @param {number} y0 - The top-left y position. - * @param {number} x1 - The bottom-left x position. - * @param {number} y1 - The bottom-left y position. - * @param {number} x2 - The bottom-right x position. - * @param {number} y2 - The bottom-right y position. - * @param {number} x3 - The top-right x position. - * @param {number} y3 - The top-right y position. - * @param {number} u0 - UV u0 value. - * @param {number} v0 - UV v0 value. - * @param {number} u1 - UV u1 value. - * @param {number} v1 - UV v1 value. - * @param {number} tintTL - The top-left tint color value. - * @param {number} tintTR - The top-right tint color value. - * @param {number} tintBL - The bottom-left tint color value. - * @param {number} tintBR - The bottom-right tint color value. - * @param {(number|boolean)} tintEffect - The tint effect for the shader to use. - * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs. - * @param {number} [unit=0] - Texture unit to which the texture needs to be bound. - * - * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`. - */ - batchQuad: function (gameObject, x0, y0, x1, y1, x2, y2, x3, y3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, unit) - { - if (unit === undefined) { unit = this.currentUnit; } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var hasFlushed = false; +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(86459); +var DefaultPlugins = __webpack_require__(18360); +var Device = __webpack_require__(77290); +var GetFastValue = __webpack_require__(72632); +var GetValue = __webpack_require__(10850); +var IsPlainObject = __webpack_require__(42911); +var NOOP = __webpack_require__(72283); +var PhaserMath = __webpack_require__(5923); +var PIPELINE_CONST = __webpack_require__(65641); +var ValueToColor = __webpack_require__(93222); - if (this.shouldFlush(6)) - { - this.flush(); +/** + * @classdesc + * The active game configuration settings, parsed from a {@link Phaser.Types.Core.GameConfig} object. + * + * @class Config + * @memberof Phaser.Core + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.Core.GameConfig} [GameConfig] - The configuration object for your Phaser Game instance. + * + * @see Phaser.Game#config + */ +var Config = new Class({ - hasFlushed = true; + initialize: - unit = this.setTexture2D(texture); - } + function Config (config) + { + if (config === undefined) { config = {}; } - this.batchVert(x0, y0, u0, v0, unit, tintEffect, tintTL); - this.batchVert(x1, y1, u0, v1, unit, tintEffect, tintBL); - this.batchVert(x2, y2, u1, v1, unit, tintEffect, tintBR); - this.batchVert(x0, y0, u0, v0, unit, tintEffect, tintTL); - this.batchVert(x2, y2, u1, v1, unit, tintEffect, tintBR); - this.batchVert(x3, y3, u1, v0, unit, tintEffect, tintTR); + var defaultBannerColor = [ + '#ff0000', + '#ffff00', + '#00ff00', + '#00ffff', + '#000000' + ]; - this.onBatch(gameObject); + var defaultBannerTextColor = '#ffffff'; - return hasFlushed; - }, + // Scale Manager - Anything set in here over-rides anything set in the core game config - /** - * Adds the vertices data into the batch and flushes if full. - * - * Assumes 3 vertices in the following arrangement: - * - * ``` - * 0 - * |\ - * | \ - * | \ - * | \ - * | \ - * 1-----2 - * ``` - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#batchTri - * @since 3.50.0 - * - * @param {(Phaser.GameObjects.GameObject|null)} gameObject - The Game Object, if any, drawing this quad. - * @param {number} x1 - The bottom-left x position. - * @param {number} y1 - The bottom-left y position. - * @param {number} x2 - The bottom-right x position. - * @param {number} y2 - The bottom-right y position. - * @param {number} x3 - The top-right x position. - * @param {number} y3 - The top-right y position. - * @param {number} u0 - UV u0 value. - * @param {number} v0 - UV v0 value. - * @param {number} u1 - UV u1 value. - * @param {number} v1 - UV v1 value. - * @param {number} tintTL - The top-left tint color value. - * @param {number} tintTR - The top-right tint color value. - * @param {number} tintBL - The bottom-left tint color value. - * @param {(number|boolean)} tintEffect - The tint effect for the shader to use. - * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs. - * @param {number} [unit=0] - Texture unit to which the texture needs to be bound. - * - * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`. - */ - batchTri: function (gameObject, x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintEffect, texture, unit) - { - if (unit === undefined) { unit = this.currentUnit; } + var scaleConfig = GetValue(config, 'scale', null); - var hasFlushed = false; + /** + * @const {(number|string)} Phaser.Core.Config#width - The width of the underlying canvas, in pixels. + */ + this.width = GetValue(scaleConfig, 'width', 1024, config); - if (this.shouldFlush(3)) - { - this.flush(); + /** + * @const {(number|string)} Phaser.Core.Config#height - The height of the underlying canvas, in pixels. + */ + this.height = GetValue(scaleConfig, 'height', 768, config); - hasFlushed = true; + /** + * @const {(Phaser.Scale.ZoomType|number)} Phaser.Core.Config#zoom - The zoom factor, as used by the Scale Manager. + */ + this.zoom = GetValue(scaleConfig, 'zoom', 1, config); - unit = this.setTexture2D(texture); - } + /** + * @const {?*} Phaser.Core.Config#parent - A parent DOM element into which the canvas created by the renderer will be injected. + */ + this.parent = GetValue(scaleConfig, 'parent', undefined, config); - this.batchVert(x0, y0, u0, v0, unit, tintEffect, tintTL); - this.batchVert(x1, y1, u0, v1, unit, tintEffect, tintTR); - this.batchVert(x2, y2, u1, v1, unit, tintEffect, tintBL); + /** + * @const {Phaser.Scale.ScaleModeType} Phaser.Core.Config#scaleMode - The scale mode as used by the Scale Manager. The default is zero, which is no scaling. + */ + this.scaleMode = GetValue(scaleConfig, (scaleConfig) ? 'mode' : 'scaleMode', 0, config); - this.onBatch(gameObject); + /** + * @const {boolean} Phaser.Core.Config#expandParent - Is the Scale Manager allowed to adjust the CSS height property of the parent to be 100%? + */ + this.expandParent = GetValue(scaleConfig, 'expandParent', true, config); - return hasFlushed; - }, + /** + * @const {boolean} Phaser.Core.Config#autoRound - Automatically round the display and style sizes of the canvas. This can help with performance in lower-powered devices. + */ + this.autoRound = GetValue(scaleConfig, 'autoRound', false, config); - /** - * Pushes a filled rectangle into the vertex batch. - * - * The dimensions are run through `Math.floor` before the quad is generated. - * - * Rectangle has no transform values and isn't transformed into the local space. - * - * Used for directly batching untransformed rectangles, such as Camera background colors. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#drawFillRect - * @since 3.50.0 - * - * @param {number} x - Horizontal top left coordinate of the rectangle. - * @param {number} y - Vertical top left coordinate of the rectangle. - * @param {number} width - Width of the rectangle. - * @param {number} height - Height of the rectangle. - * @param {number} color - Color of the rectangle to draw. - * @param {number} alpha - Alpha value of the rectangle to draw. - * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs. - * @param {boolean} [flipUV=true] - Flip the vertical UV coordinates of the texture before rendering? - */ - drawFillRect: function (x, y, width, height, color, alpha, texture, flipUV) - { - if (texture === undefined) { texture = this.renderer.whiteTexture.glTexture; } - if (flipUV === undefined) { flipUV = true; } + /** + * @const {Phaser.Scale.CenterType} Phaser.Core.Config#autoCenter - Automatically center the canvas within the parent? + */ + this.autoCenter = GetValue(scaleConfig, 'autoCenter', 0, config); - x = Math.floor(x); - y = Math.floor(y); + /** + * @const {number} Phaser.Core.Config#resizeInterval - How many ms should elapse before checking if the browser size has changed? + */ + this.resizeInterval = GetValue(scaleConfig, 'resizeInterval', 500, config); - var xw = Math.floor(x + width); - var yh = Math.floor(y + height); + /** + * @const {?(HTMLElement|string)} Phaser.Core.Config#fullscreenTarget - The DOM element that will be sent into full screen mode, or its `id`. If undefined Phaser will create its own div and insert the canvas into it when entering fullscreen mode. + */ + this.fullscreenTarget = GetValue(scaleConfig, 'fullscreenTarget', null, config); - var unit = this.setTexture2D(texture); + /** + * @const {number} Phaser.Core.Config#minWidth - The minimum width, in pixels, the canvas will scale down to. A value of zero means no minimum. + */ + this.minWidth = GetValue(scaleConfig, 'minWidth', 0, config); - var tint = Utils.getTintAppendFloatAlphaAndSwap(color, alpha); + /** + * @const {number} Phaser.Core.Config#maxWidth - The maximum width, in pixels, the canvas will scale up to. A value of zero means no maximum. + */ + this.maxWidth = GetValue(scaleConfig, 'maxWidth', 0, config); - var u0 = 0; - var v0 = 0; - var u1 = 1; - var v1 = 1; + /** + * @const {number} Phaser.Core.Config#minHeight - The minimum height, in pixels, the canvas will scale down to. A value of zero means no minimum. + */ + this.minHeight = GetValue(scaleConfig, 'minHeight', 0, config); - if (flipUV) - { - v0 = 1; - v1 = 0; - } + /** + * @const {number} Phaser.Core.Config#maxHeight - The maximum height, in pixels, the canvas will scale up to. A value of zero means no maximum. + */ + this.maxHeight = GetValue(scaleConfig, 'maxHeight', 0, config); - this.batchQuad(null, x, y, x, yh, xw, yh, xw, y, u0, v0, u1, v1, tint, tint, tint, tint, 0, texture, unit); - }, + /** + * @const {number} Phaser.Core.Config#renderType - Force Phaser to use a specific renderer. Can be `CONST.CANVAS`, `CONST.WEBGL`, `CONST.HEADLESS` or `CONST.AUTO` (default) + */ + this.renderType = GetValue(config, 'type', CONST.AUTO); - /** - * Sets the texture to be bound to the next available texture unit and returns - * the unit id. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setTexture2D - * @since 3.50.0 - * - * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch. If not given uses `whiteTexture`. - * - * @return {number} The assigned texture unit. - */ - setTexture2D: function (texture) - { - if (texture === undefined) { texture = this.renderer.whiteTexture.glTexture; } + /** + * @const {?HTMLCanvasElement} Phaser.Core.Config#canvas - Force Phaser to use your own Canvas element instead of creating one. + */ + this.canvas = GetValue(config, 'canvas', null); - this.currentUnit = this.renderer.setTexture2D(texture); + /** + * @const {?(CanvasRenderingContext2D|WebGLRenderingContext)} Phaser.Core.Config#context - Force Phaser to use your own Canvas context instead of creating one. + */ + this.context = GetValue(config, 'context', null); - return this.currentUnit; - }, + /** + * @const {?string} Phaser.Core.Config#canvasStyle - Optional CSS attributes to be set on the canvas object created by the renderer. + */ + this.canvasStyle = GetValue(config, 'canvasStyle', null); - /** - * Activates the given WebGL Texture and binds it to the requested texture slot. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#bindTexture - * @since 3.50.0 - * - * @param {WebGLTexture} [target] - The WebGLTexture to activate and bind. - * @param {number} [unit=0] - The WebGL texture ID to activate. Defaults to `gl.TEXTURE0`. - * - * @return {this} This WebGL Pipeline instance. - */ - bindTexture: function (texture, unit) - { - if (unit === undefined) { unit = 0; } + /** + * @const {boolean} Phaser.Core.Config#customEnvironment - Is Phaser running under a custom (non-native web) environment? If so, set this to `true` to skip internal Feature detection. If `true` the `renderType` cannot be left as `AUTO`. + */ + this.customEnvironment = GetValue(config, 'customEnvironment', false); - var gl = this.gl; + /** + * @const {?object} Phaser.Core.Config#sceneConfig - The default Scene configuration object. + */ + this.sceneConfig = GetValue(config, 'scene', null); - gl.activeTexture(gl.TEXTURE0 + unit); + /** + * @const {string[]} Phaser.Core.Config#seed - A seed which the Random Data Generator will use. If not given, a dynamic seed based on the time is used. + */ + this.seed = GetValue(config, 'seed', [ (Date.now() * Math.random()).toString() ]); - gl.bindTexture(gl.TEXTURE_2D, texture); + PhaserMath.RND = new PhaserMath.RandomDataGenerator(this.seed); - return this; - }, + /** + * @const {string} Phaser.Core.Config#gameTitle - The title of the game. + */ + this.gameTitle = GetValue(config, 'title', ''); - /** - * Activates the given Render Target texture and binds it to the - * requested WebGL texture slot. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#bindRenderTarget - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The Render Target to activate and bind. - * @param {number} [unit=0] - The WebGL texture ID to activate. Defaults to `gl.TEXTURE0`. - * - * @return {this} This WebGL Pipeline instance. - */ - bindRenderTarget: function (target, unit) - { - return this.bindTexture(target.texture, unit); - }, + /** + * @const {string} Phaser.Core.Config#gameURL - The URL of the game. + */ + this.gameURL = GetValue(config, 'url', 'https://phaser.io'); - /** - * Sets the current duration into a 1f uniform value based on the given name. - * - * This can be used for mapping time uniform values, such as `iTime`. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setTime - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * - * @return {this} This WebGLPipeline instance. - */ - setTime: function (uniform) - { - this.set1f(uniform, this.game.loop.getDuration()); + /** + * @const {string} Phaser.Core.Config#gameVersion - The version of the game. + */ + this.gameVersion = GetValue(config, 'version', ''); - return this; - }, + /** + * @const {boolean} Phaser.Core.Config#autoFocus - If `true` the window will automatically be given focus immediately and on any future mousedown event. + */ + this.autoFocus = GetValue(config, 'autoFocus', true); - /** - * Sets a 1f uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set1f - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new value of the `float` uniform. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set1f: function (name, x, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {(number|boolean)} Phaser.Core.Config#stableSort - `false` or `0` = Use the built-in StableSort (needed for older browsers), `true` or `1` = Rely on ES2019 Array.sort being stable (modern browsers only), or `-1` = Try and determine this automatically based on browser inspection (not guaranteed to work, errs on side of caution). + */ + this.stableSort = GetValue(config, 'stableSort', -1); - shader.set1f(name, x); + if (this.stableSort === -1) + { + this.stableSort = (Device.browser.es2019) ? 1 : 0; + } - return this; - }, + Device.features.stableSort = this.stableSort; - /** - * Sets a 2f uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set2f - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new X component of the `vec2` uniform. - * @param {number} y - The new Y component of the `vec2` uniform. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set2f: function (name, x, y, shader) - { - if (shader === undefined) { shader = this.currentShader; } + // DOM Element Container - shader.set2f(name, x, y); + /** + * @const {?boolean} Phaser.Core.Config#domCreateContainer - Should the game create a div element to act as a DOM Container? Only enable if you're using DOM Element objects. You must provide a parent object if you use this feature. + */ + this.domCreateContainer = GetValue(config, 'dom.createContainer', false); - return this; - }, + /** + * @const {?string} Phaser.Core.Config#domPointerEvents - The default `pointerEvents` attribute set on the DOM Container. + */ + this.domPointerEvents = GetValue(config, 'dom.pointerEvents', 'none'); - /** - * Sets a 3f uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set3f - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new X component of the `vec3` uniform. - * @param {number} y - The new Y component of the `vec3` uniform. - * @param {number} z - The new Z component of the `vec3` uniform. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set3f: function (name, x, y, z, shader) - { - if (shader === undefined) { shader = this.currentShader; } + // Input - shader.set3f(name, x, y, z); + /** + * @const {boolean} Phaser.Core.Config#inputKeyboard - Enable the Keyboard Plugin. This can be disabled in games that don't need keyboard input. + */ + this.inputKeyboard = GetValue(config, 'input.keyboard', true); - return this; - }, + /** + * @const {*} Phaser.Core.Config#inputKeyboardEventTarget - The DOM Target to listen for keyboard events on. Defaults to `window` if not specified. + */ + this.inputKeyboardEventTarget = GetValue(config, 'input.keyboard.target', window); - /** - * Sets a 4f uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set4f - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - X component of the uniform - * @param {number} y - Y component of the uniform - * @param {number} z - Z component of the uniform - * @param {number} w - W component of the uniform - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set4f: function (name, x, y, z, w, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {?number[]} Phaser.Core.Config#inputKeyboardCapture - `preventDefault` will be called on every non-modified key which has a key code in this array. By default, it is empty. + */ + this.inputKeyboardCapture = GetValue(config, 'input.keyboard.capture', []); - shader.set4f(name, x, y, z, w); + /** + * @const {(boolean|object)} Phaser.Core.Config#inputMouse - Enable the Mouse Plugin. This can be disabled in games that don't need mouse input. + */ + this.inputMouse = GetValue(config, 'input.mouse', true); - return this; - }, + /** + * @const {?*} Phaser.Core.Config#inputMouseEventTarget - The DOM Target to listen for mouse events on. Defaults to the game canvas if not specified. + */ + this.inputMouseEventTarget = GetValue(config, 'input.mouse.target', null); - /** - * Sets a 1fv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set1fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set1fv: function (name, arr, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#inputMousePreventDefaultDown - Should `mousedown` DOM events have `preventDefault` called on them? + */ + this.inputMousePreventDefaultDown = GetValue(config, 'input.mouse.preventDefaultDown', true); - shader.set1fv(name, arr); + /** + * @const {boolean} Phaser.Core.Config#inputMousePreventDefaultUp - Should `mouseup` DOM events have `preventDefault` called on them? + */ + this.inputMousePreventDefaultUp = GetValue(config, 'input.mouse.preventDefaultUp', true); - return this; - }, + /** + * @const {boolean} Phaser.Core.Config#inputMousePreventDefaultMove - Should `mousemove` DOM events have `preventDefault` called on them? + */ + this.inputMousePreventDefaultMove = GetValue(config, 'input.mouse.preventDefaultMove', true); - /** - * Sets a 2fv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set2fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set2fv: function (name, arr, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#inputMousePreventDefaultWheel - Should `wheel` DOM events have `preventDefault` called on them? + */ + this.inputMousePreventDefaultWheel = GetValue(config, 'input.mouse.preventDefaultWheel', true); - shader.set2fv(name, arr); + /** + * @const {boolean} Phaser.Core.Config#inputTouch - Enable the Touch Plugin. This can be disabled in games that don't need touch input. + */ + this.inputTouch = GetValue(config, 'input.touch', Device.input.touch); - return this; - }, + /** + * @const {?*} Phaser.Core.Config#inputTouchEventTarget - The DOM Target to listen for touch events on. Defaults to the game canvas if not specified. + */ + this.inputTouchEventTarget = GetValue(config, 'input.touch.target', null); - /** - * Sets a 3fv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set3fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set3fv: function (name, arr, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#inputTouchCapture - Should touch events be captured? I.e. have prevent default called on them. + */ + this.inputTouchCapture = GetValue(config, 'input.touch.capture', true); - shader.set3fv(name, arr); + /** + * @const {number} Phaser.Core.Config#inputActivePointers - The number of Pointer objects created by default. In a mouse-only, or non-multi touch game, you can leave this as 1. + */ + this.inputActivePointers = GetValue(config, 'input.activePointers', 1); - return this; - }, + /** + * @const {number} Phaser.Core.Config#inputSmoothFactor - The smoothing factor to apply during Pointer movement. See {@link Phaser.Input.Pointer#smoothFactor}. + */ + this.inputSmoothFactor = GetValue(config, 'input.smoothFactor', 0); - /** - * Sets a 4fv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set4fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set4fv: function (name, arr, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#inputWindowEvents - Should Phaser listen for input events on the Window? If you disable this, events like 'POINTER_UP_OUTSIDE' will no longer fire. + */ + this.inputWindowEvents = GetValue(config, 'input.windowEvents', true); - shader.set4fv(name, arr); + /** + * @const {boolean} Phaser.Core.Config#inputGamepad - Enable the Gamepad Plugin. This can be disabled in games that don't need gamepad input. + */ + this.inputGamepad = GetValue(config, 'input.gamepad', false); - return this; - }, + /** + * @const {*} Phaser.Core.Config#inputGamepadEventTarget - The DOM Target to listen for gamepad events on. Defaults to `window` if not specified. + */ + this.inputGamepadEventTarget = GetValue(config, 'input.gamepad.target', window); - /** - * Sets a 1iv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set1iv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set1iv: function (name, arr, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#disableContextMenu - Set to `true` to disable the right-click context menu. + */ + this.disableContextMenu = GetValue(config, 'disableContextMenu', false); - shader.set1iv(name, arr); + /** + * @const {Phaser.Types.Core.AudioConfig} Phaser.Core.Config#audio - The Audio Configuration object. + */ + this.audio = GetValue(config, 'audio', {}); - return this; - }, + // If you do: { banner: false } it won't display any banner at all - /** - * Sets a 2iv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set2iv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set2iv: function (name, arr, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#hideBanner - Don't write the banner line to the console.log. + */ + this.hideBanner = (GetValue(config, 'banner', null) === false); - shader.set2iv(name, arr); + /** + * @const {boolean} Phaser.Core.Config#hidePhaser - Omit Phaser's name and version from the banner. + */ + this.hidePhaser = GetValue(config, 'banner.hidePhaser', false); - return this; - }, + /** + * @const {string} Phaser.Core.Config#bannerTextColor - The color of the banner text. + */ + this.bannerTextColor = GetValue(config, 'banner.text', defaultBannerTextColor); - /** - * Sets a 3iv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set3iv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set3iv: function (name, arr, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {string[]} Phaser.Core.Config#bannerBackgroundColor - The background colors of the banner. + */ + this.bannerBackgroundColor = GetValue(config, 'banner.background', defaultBannerColor); - shader.set3iv(name, arr); + if (this.gameTitle === '' && this.hidePhaser) + { + this.hideBanner = true; + } - return this; - }, + /** + * @const {Phaser.Types.Core.FPSConfig} Phaser.Core.Config#fps - The Frame Rate Configuration object, as parsed by the Timestep class. + */ + this.fps = GetValue(config, 'fps', null); - /** - * Sets a 4iv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set4iv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set4iv: function (name, arr, shader) - { - if (shader === undefined) { shader = this.currentShader; } + // Render Settings - Anything set in here over-rides anything set in the core game config - shader.set4iv(name, arr); + var renderConfig = GetValue(config, 'render', null); - return this; - }, + /** + * @const {Phaser.Types.Core.PipelineConfig} Phaser.Core.Config#pipeline - An object mapping WebGL names to WebGLPipeline classes. These should be class constructors, not instances. + */ + this.pipeline = GetValue(renderConfig, 'pipeline', null, config); - /** - * Sets a 1i uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set1i - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new value of the `int` uniform. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set1i: function (name, x, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#autoMobilePipeline - Automatically enable the Mobile Pipeline if iOS or Android detected? + */ + this.autoMobilePipeline = GetValue(renderConfig, 'autoMobilePipeline', true, config); - shader.set1i(name, x); + /** + * @const {string} Phaser.Core.Config#defaultPipeline - The WebGL Pipeline that Game Objects will use by default. Set to 'MultiPipeline' as standard. See also 'autoMobilePipeline'. + */ + this.defaultPipeline = GetValue(renderConfig, 'defaultPipeline', PIPELINE_CONST.MULTI_PIPELINE, config); - return this; - }, + /** + * @const {boolean} Phaser.Core.Config#antialias - When set to `true`, WebGL uses linear interpolation to draw scaled or rotated textures, giving a smooth appearance. When set to `false`, WebGL uses nearest-neighbor interpolation, giving a crisper appearance. `false` also disables antialiasing of the game canvas itself, if the browser supports it, when the game canvas is scaled. + */ + this.antialias = GetValue(renderConfig, 'antialias', true, config); - /** - * Sets a 2i uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set2i - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new X component of the `ivec2` uniform. - * @param {number} y - The new Y component of the `ivec2` uniform. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set2i: function (name, x, y, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#antialiasGL - Sets the `antialias` property when the WebGL context is created. Setting this value does not impact any subsequent textures that are created, or the canvas style attributes. + */ + this.antialiasGL = GetValue(renderConfig, 'antialiasGL', true, config); - shader.set2i(name, x, y); + /** + * @const {string} Phaser.Core.Config#mipmapFilter - Sets the `mipmapFilter` property when the WebGL renderer is created. + */ + this.mipmapFilter = GetValue(renderConfig, 'mipmapFilter', '', config); - return this; - }, + /** + * @const {boolean} Phaser.Core.Config#desynchronized - When set to `true` it will create a desynchronized context for both 2D and WebGL. See https://developers.google.com/web/updates/2019/05/desynchronized for details. + */ + this.desynchronized = GetValue(renderConfig, 'desynchronized', false, config); - /** - * Sets a 3i uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set3i - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new X component of the `ivec3` uniform. - * @param {number} y - The new Y component of the `ivec3` uniform. - * @param {number} z - The new Z component of the `ivec3` uniform. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set3i: function (name, x, y, z, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#roundPixels - Draw texture-based Game Objects at only whole-integer positions. Game Objects without textures, like Graphics, ignore this property. + */ + this.roundPixels = GetValue(renderConfig, 'roundPixels', false, config); - shader.set3i(name, x, y, z); + /** + * @const {boolean} Phaser.Core.Config#pixelArt - Prevent pixel art from becoming blurred when scaled. It will remain crisp (tells the WebGL renderer to automatically create textures using a linear filter mode). + */ + this.pixelArt = GetValue(renderConfig, 'pixelArt', this.zoom !== 1, config); - return this; - }, + if (this.pixelArt) + { + this.antialias = false; + this.antialiasGL = false; + this.roundPixels = true; + } - /** - * Sets a 4i uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#set4i - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - X component of the uniform. - * @param {number} y - Y component of the uniform. - * @param {number} z - Z component of the uniform. - * @param {number} w - W component of the uniform. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - set4i: function (name, x, y, z, w, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#transparent - Whether the game canvas will have a transparent background. + */ + this.transparent = GetValue(renderConfig, 'transparent', false, config); - shader.set4i(name, x, y, z, w); + /** + * @const {boolean} Phaser.Core.Config#clearBeforeRender - Whether the game canvas will be cleared between each rendering frame. You can disable this if you have a full-screen background image or game object. + */ + this.clearBeforeRender = GetValue(renderConfig, 'clearBeforeRender', true, config); - return this; - }, + /** + * @const {boolean} Phaser.Core.Config#preserveDrawingBuffer - If the value is true the WebGL buffers will not be cleared and will preserve their values until cleared or overwritten by the author. + */ + this.preserveDrawingBuffer = GetValue(renderConfig, 'preserveDrawingBuffer', false, config); - /** - * Sets a matrix 2fv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix2fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {boolean} transpose - Whether to transpose the matrix. Should be `false`. - * @param {number[]|Float32Array} matrix - The new values for the `mat2` uniform. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - setMatrix2fv: function (name, transpose, matrix, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {boolean} Phaser.Core.Config#premultipliedAlpha - In WebGL mode, sets the drawing buffer to contain colors with pre-multiplied alpha. + */ + this.premultipliedAlpha = GetValue(renderConfig, 'premultipliedAlpha', true, config); - shader.setMatrix2fv(name, transpose, matrix); + /** + * @const {boolean} Phaser.Core.Config#failIfMajorPerformanceCaveat - Let the browser abort creating a WebGL context if it judges performance would be unacceptable. + */ + this.failIfMajorPerformanceCaveat = GetValue(renderConfig, 'failIfMajorPerformanceCaveat', false, config); - return this; - }, + /** + * @const {string} Phaser.Core.Config#powerPreference - "high-performance", "low-power" or "default". A hint to the browser on how much device power the game might use. + */ + this.powerPreference = GetValue(renderConfig, 'powerPreference', 'default', config); - /** - * Sets a matrix 3fv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix3fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {boolean} transpose - Whether to transpose the matrix. Should be `false`. - * @param {Float32Array} matrix - The new values for the `mat3` uniform. - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - setMatrix3fv: function (name, transpose, matrix, shader) - { - if (shader === undefined) { shader = this.currentShader; } + /** + * @const {number} Phaser.Core.Config#batchSize - The default WebGL Batch size. Represents the number of _quads_ that can be added to a single batch. + */ + this.batchSize = GetValue(renderConfig, 'batchSize', 4096, config); - shader.setMatrix3fv(name, transpose, matrix); + /** + * @const {number} Phaser.Core.Config#maxTextures - When in WebGL mode, this sets the maximum number of GPU Textures to use. The default, -1, will use all available units. The WebGL1 spec says all browsers should provide a minimum of 8. + */ + this.maxTextures = GetValue(renderConfig, 'maxTextures', -1, config); - return this; - }, + /** + * @const {number} Phaser.Core.Config#maxLights - The maximum number of lights allowed to be visible within range of a single Camera in the LightManager. + */ + this.maxLights = GetValue(renderConfig, 'maxLights', 10, config); - /** - * Sets a matrix 4fv uniform value based on the given name on the currently set shader. - * - * The current shader is bound, before the uniform is set, making it active within the - * WebGLRenderer. This means you can safely call this method from a location such as - * a Scene `create` or `update` method. However, when working within a Shader file - * directly, use the `WebGLShader` method equivalent instead, to avoid the program - * being set. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix4fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {boolean} transpose - Should the matrix be transpose - * @param {Float32Array} matrix - Matrix data - * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. - * - * @return {this} This WebGLPipeline instance. - */ - setMatrix4fv: function (name, transpose, matrix, shader) - { - if (shader === undefined) { shader = this.currentShader; } + var bgc = GetValue(config, 'backgroundColor', 0); - shader.setMatrix4fv(name, transpose, matrix); + /** + * @const {Phaser.Display.Color} Phaser.Core.Config#backgroundColor - The background color of the game canvas. The default is black. This value is ignored if `transparent` is set to `true`. + */ + this.backgroundColor = ValueToColor(bgc); - return this; - }, + if (this.transparent) + { + this.backgroundColor = ValueToColor(0x000000); + this.backgroundColor.alpha = 0; + } - /** - * Destroys all shader instances, removes all object references and nulls all external references. - * - * @method Phaser.Renderer.WebGL.WebGLPipeline#destroy - * @fires Phaser.Renderer.WebGL.Pipelines.Events#DESTROY - * @since 3.0.0 - * - * @return {this} This WebGLPipeline instance. - */ - destroy: function () - { - this.emit(Events.DESTROY, this); + /** + * @const {Phaser.Types.Core.BootCallback} Phaser.Core.Config#preBoot - Called before Phaser boots. Useful for initializing anything not related to Phaser that Phaser may require while booting. + */ + this.preBoot = GetValue(config, 'callbacks.preBoot', NOOP); - var i; + /** + * @const {Phaser.Types.Core.BootCallback} Phaser.Core.Config#postBoot - A function to run at the end of the boot sequence. At this point, all the game systems have started and plugins have been loaded. + */ + this.postBoot = GetValue(config, 'callbacks.postBoot', NOOP); - var shaders = this.shaders; + /** + * @const {Phaser.Types.Core.PhysicsConfig} Phaser.Core.Config#physics - The Physics Configuration object. + */ + this.physics = GetValue(config, 'physics', {}); - for (i = 0; i < shaders.length; i++) - { - shaders[i].destroy(); - } + /** + * @const {(boolean|string)} Phaser.Core.Config#defaultPhysicsSystem - The default physics system. It will be started for each scene. Either 'arcade', 'impact' or 'matter'. + */ + this.defaultPhysicsSystem = GetValue(this.physics, 'default', false); - var targets = this.renderTargets; + /** + * @const {string} Phaser.Core.Config#loaderBaseURL - A URL used to resolve paths given to the loader. Example: 'http://labs.phaser.io/assets/'. + */ + this.loaderBaseURL = GetValue(config, 'loader.baseURL', ''); - for (i = 0; i < targets.length; i++) - { - targets[i].destroy(); - } + /** + * @const {string} Phaser.Core.Config#loaderPath - A URL path used to resolve relative paths given to the loader. Example: 'images/sprites/'. + */ + this.loaderPath = GetValue(config, 'loader.path', ''); - this.gl.deleteBuffer(this.vertexBuffer); + /** + * @const {number} Phaser.Core.Config#loaderMaxParallelDownloads - Maximum parallel downloads allowed for resources (Default to 32). + */ + this.loaderMaxParallelDownloads = GetValue(config, 'loader.maxParallelDownloads', (Device.os.android) ? 6 : 32); - var renderer = this.renderer; + /** + * @const {(string|undefined)} Phaser.Core.Config#loaderCrossOrigin - 'anonymous', 'use-credentials', or `undefined`. If you're not making cross-origin requests, leave this as `undefined`. See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes}. + */ + this.loaderCrossOrigin = GetValue(config, 'loader.crossOrigin', undefined); - renderer.off(RendererEvents.RESIZE, this.resize, this); - renderer.off(RendererEvents.PRE_RENDER, this.onPreRender, this); - renderer.off(RendererEvents.RENDER, this.onRender, this); - renderer.off(RendererEvents.POST_RENDER, this.onPostRender, this); + /** + * @const {string} Phaser.Core.Config#loaderResponseType - The response type of the XHR request, e.g. `blob`, `text`, etc. + */ + this.loaderResponseType = GetValue(config, 'loader.responseType', ''); - this.removeAllListeners(); + /** + * @const {boolean} Phaser.Core.Config#loaderAsync - Should the XHR request use async or not? + */ + this.loaderAsync = GetValue(config, 'loader.async', true); - this.game = null; - this.renderer = null; - this.manager = null; - this.gl = null; - this.view = null; - this.shaders = null; - this.renderTargets = null; - this.bytes = null; - this.vertexViewF32 = null; - this.vertexViewU32 = null; - this.vertexData = null; - this.vertexBuffer = null; - this.currentShader = null; - this.currentRenderTarget = null; + /** + * @const {string} Phaser.Core.Config#loaderUser - Optional username for all XHR requests. + */ + this.loaderUser = GetValue(config, 'loader.user', ''); - return this; - } + /** + * @const {string} Phaser.Core.Config#loaderPassword - Optional password for all XHR requests. + */ + this.loaderPassword = GetValue(config, 'loader.password', ''); -}); + /** + * @const {number} Phaser.Core.Config#loaderTimeout - Optional XHR timeout value, in ms. + */ + this.loaderTimeout = GetValue(config, 'loader.timeout', 0); -module.exports = WebGLPipeline; + /** + * @const {boolean} Phaser.Core.Config#loaderWithCredentials - Optional XHR withCredentials value. + */ + this.loaderWithCredentials = GetValue(config, 'loader.withCredentials', false); + /** + * @const {string} Phaser.Core.Config#loaderImageLoadType - Optional load type for image, `XHR` is default, or `HTMLImageElement` for a lightweight way. + */ + this.loaderImageLoadType = GetValue(config, 'loader.imageLoadType', 'XHR'); -/***/ }), -/* 59 */ -/***/ (function(module, exports, __webpack_require__) { + // On iOS, Capacitor often runs on a capacitor:// protocol, meaning local files are served from capacitor:// rather than file:// + // See: https://github.com/photonstorm/phaser/issues/5685 -"use strict"; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * @const {string[]} Phaser.Core.Config#loaderLocalScheme - An array of schemes that the Loader considers as being 'local' files. Defaults to: `[ 'file://', 'capacitor://' ]`. + */ + this.loaderLocalScheme = GetValue(config, 'loader.localScheme', [ 'file://', 'capacitor://' ]); -/** - * This module implements a modified ear slicing algorithm, optimized by z-order curve hashing and extended to - * handle holes, twisted polygons, degeneracies and self-intersections in a way that doesn't guarantee correctness - * of triangulation, but attempts to always produce acceptable results for practical data. - * - * Example: - * - * ```javascript - * const triangles = Phaser.Geom.Polygon.Earcut([10,0, 0,50, 60,60, 70,10]); // returns [1,0,3, 3,2,1] - * ``` - * - * Each group of three vertex indices in the resulting array forms a triangle. - * - * ```javascript - * // triangulating a polygon with a hole - * earcut([0,0, 100,0, 100,100, 0,100, 20,20, 80,20, 80,80, 20,80], [4]); - * // [3,0,4, 5,4,0, 3,4,7, 5,0,1, 2,3,7, 6,5,1, 2,7,6, 6,1,2] - * - * // triangulating a polygon with 3d coords - * earcut([10,0,1, 0,50,2, 60,60,3, 70,10,4], null, 3); - * // [1,0,3, 3,2,1] - * ``` - * - * If you pass a single vertex as a hole, Earcut treats it as a Steiner point. - * - * If your input is a multi-dimensional array (e.g. GeoJSON Polygon), you can convert it to the format - * expected by Earcut with `Phaser.Geom.Polygon.Earcut.flatten`: - * - * ```javascript - * var data = earcut.flatten(geojson.geometry.coordinates); - * var triangles = earcut(data.vertices, data.holes, data.dimensions); - * ``` - * - * After getting a triangulation, you can verify its correctness with `Phaser.Geom.Polygon.Earcut.deviation`: - * - * ```javascript - * var deviation = earcut.deviation(vertices, holes, dimensions, triangles); - * ``` - * Returns the relative difference between the total area of triangles and the area of the input polygon. - * 0 means the triangulation is fully correct. - * - * For more information see https://github.com/mapbox/earcut - * - * @function Phaser.Geom.Polygon.Earcut - * @since 3.50.0 - * - * @param {number[]} data - A flat array of vertex coordinate, like [x0,y0, x1,y1, x2,y2, ...] - * @param {number[]} [holeIndices] - An array of hole indices if any (e.g. [5, 8] for a 12-vertex input would mean one hole with vertices 5–7 and another with 8–11). - * @param {number} [dimensions=2] - The number of coordinates per vertex in the input array (2 by default). - * - * @return {number[]} An array of triangulated data. - */ + /** + * @const {number} Phaser.Core.Config#glowFXQuality - The quality of the Glow FX (defaults to 0.1) + */ + this.glowFXQuality = GetValue(config, 'fx.glow.quality', 0.1); - // Earcut 2.2.2 (January 21st 2020) + /** + * @const {number} Phaser.Core.Config#glowFXDistance - The distance of the Glow FX (defaults to 10) + */ + this.glowFXDistance = GetValue(config, 'fx.glow.distance', 10); -/* - * ISC License - * - * Copyright (c) 2016, Mapbox - * - * Permission to use, copy, modify, and/or distribute this software for any purpose - * with or without fee is hereby granted, provided that the above copyright notice - * and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - * THIS SOFTWARE. - */ + /* + * Allows `plugins` property to either be an array, in which case it just replaces + * the default plugins like previously, or a config object. + * + * plugins: { + * global: [ + * { key: 'TestPlugin', plugin: TestPlugin, start: true, data: { msg: 'The plugin is alive' } }, + * ], + * scene: [ + * { key: 'WireFramePlugin', plugin: WireFramePlugin, systemKey: 'wireFramePlugin', sceneKey: 'wireframe' } + * ], + * default: [], OR + * defaultMerge: [ + * 'ModPlayer' + * ] + * } + */ + /** + * @const {any} Phaser.Core.Config#installGlobalPlugins - An array of global plugins to be installed. + */ + this.installGlobalPlugins = []; + /** + * @const {any} Phaser.Core.Config#installScenePlugins - An array of Scene level plugins to be installed. + */ + this.installScenePlugins = []; -function earcut(data, holeIndices, dim) { + var plugins = GetValue(config, 'plugins', null); + var defaultPlugins = DefaultPlugins.DefaultScene; - dim = dim || 2; + if (plugins) + { + // Old 3.7 array format? + if (Array.isArray(plugins)) + { + this.defaultPlugins = plugins; + } + else if (IsPlainObject(plugins)) + { + this.installGlobalPlugins = GetFastValue(plugins, 'global', []); + this.installScenePlugins = GetFastValue(plugins, 'scene', []); - var hasHoles = holeIndices && holeIndices.length, - outerLen = hasHoles ? holeIndices[0] * dim : data.length, - outerNode = linkedList(data, 0, outerLen, dim, true), - triangles = []; + if (Array.isArray(plugins.default)) + { + defaultPlugins = plugins.default; + } + else if (Array.isArray(plugins.defaultMerge)) + { + defaultPlugins = defaultPlugins.concat(plugins.defaultMerge); + } + } + } - if (!outerNode || outerNode.next === outerNode.prev) return triangles; + /** + * @const {any} Phaser.Core.Config#defaultPlugins - The plugins installed into every Scene (in addition to CoreScene and Global). + */ + this.defaultPlugins = defaultPlugins; - var minX, minY, maxX, maxY, x, y, invSize; + // Default / Missing Images + var pngPrefix = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg'; - if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); + /** + * @const {string} Phaser.Core.Config#defaultImage - A base64 encoded PNG that will be used as the default blank texture. + */ + this.defaultImage = GetValue(config, 'images.default', pngPrefix + 'AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=='); - // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox - if (data.length > 80 * dim) { - minX = maxX = data[0]; - minY = maxY = data[1]; + /** + * @const {string} Phaser.Core.Config#missingImage - A base64 encoded PNG that will be used as the default texture when a texture is assigned that is missing or not loaded. + */ + this.missingImage = GetValue(config, 'images.missing', pngPrefix + 'CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=='); - for (var i = dim; i < outerLen; i += dim) { - x = data[i]; - y = data[i + 1]; - if (x < minX) minX = x; - if (y < minY) minY = y; - if (x > maxX) maxX = x; - if (y > maxY) maxY = y; - } + /** + * @const {string} Phaser.Core.Config#whiteImage - A base64 encoded PNG that will be used as the default texture when a texture is assigned that is white or not loaded. + */ + this.whiteImage = GetValue(config, 'images.white', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC'); - // minX, minY and invSize are later used to transform coords into integers for z-order calculation - invSize = Math.max(maxX - minX, maxY - minY); - invSize = invSize !== 0 ? 1 / invSize : 0; + if (window) + { + if (window.FORCE_WEBGL) + { + this.renderType = CONST.WEBGL; + } + else if (window.FORCE_CANVAS) + { + this.renderType = CONST.CANVAS; + } + } } - earcutLinked(outerNode, triangles, dim, minX, minY, invSize); +}); - return triangles; -} +module.exports = Config; -// create a circular doubly linked list from polygon points in the specified winding order -function linkedList(data, start, end, dim, clockwise) { - var i, last; - if (clockwise === (signedArea(data, start, end, dim) > 0)) { - for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); - } else { - for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); - } +/***/ }), - if (last && equals(last, last.next)) { - removeNode(last); - last = last.next; - } +/***/ 50150: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return last; -} +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -// eliminate colinear or duplicate points -function filterPoints(start, end) { - if (!start) return start; - if (!end) end = start; +var CanvasInterpolation = __webpack_require__(70616); +var CanvasPool = __webpack_require__(61068); +var CONST = __webpack_require__(86459); +var Features = __webpack_require__(90185); - var p = start, - again; - do { - again = false; +/** + * Called automatically by Phaser.Game and responsible for creating the renderer it will use. + * + * Relies upon two webpack global flags to be defined: `WEBGL_RENDERER` and `CANVAS_RENDERER` during build time, but not at run-time. + * + * @function Phaser.Core.CreateRenderer + * @since 3.0.0 + * + * @param {Phaser.Game} game - The Phaser.Game instance on which the renderer will be set. + */ +var CreateRenderer = function (game) +{ + var config = game.config; - if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { - removeNode(p); - p = end = p.prev; - if (p === p.next) break; - again = true; + if ((config.customEnvironment || config.canvas) && config.renderType === CONST.AUTO) + { + throw new Error('Must set explicit renderType in custom environment'); + } - } else { - p = p.next; + // Not a custom environment, didn't provide their own canvas and not headless, so determine the renderer: + if (!config.customEnvironment && !config.canvas && config.renderType !== CONST.HEADLESS) + { + if (config.renderType === CONST.AUTO) + { + config.renderType = Features.webGL ? CONST.WEBGL : CONST.CANVAS; } - } while (again || p !== end); - - return end; -} - -// main ear slicing loop which triangulates a polygon (given as a linked list) -function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { - if (!ear) return; - // interlink polygon nodes in z-order - if (!pass && invSize) indexCurve(ear, minX, minY, invSize); + if (config.renderType === CONST.WEBGL) + { + if (!Features.webGL) { throw new Error('Cannot create WebGL context, aborting.'); } + } + else if (config.renderType === CONST.CANVAS) + { + if (!Features.canvas) { throw new Error('Cannot create Canvas context, aborting.'); } + } + else + { + throw new Error('Unknown value for renderer type: ' + config.renderType); + } + } - var stop = ear, - prev, next; + // Pixel Art mode? + if (!config.antialias) + { + CanvasPool.disableSmoothing(); + } - // iterate through ears, slicing them one by one - while (ear.prev !== ear.next) { - prev = ear.prev; - next = ear.next; + var baseSize = game.scale.baseSize; - if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { - // cut off the triangle - triangles.push(prev.i / dim); - triangles.push(ear.i / dim); - triangles.push(next.i / dim); + var width = baseSize.width; + var height = baseSize.height; - removeNode(ear); + // Does the game config provide its own canvas element to use? + if (config.canvas) + { + game.canvas = config.canvas; - // skipping the next vertex leads to less sliver triangles - ear = next.next; - stop = next.next; + game.canvas.width = width; + game.canvas.height = height; + } + else + { + game.canvas = CanvasPool.create(game, width, height, config.renderType); + } - continue; - } + // Does the game config provide some canvas css styles to use? + if (config.canvasStyle) + { + game.canvas.style = config.canvasStyle; + } - ear = next; + // Pixel Art mode? + if (!config.antialias) + { + CanvasInterpolation.setCrisp(game.canvas); + } - // if we looped through the whole remaining polygon and can't find any more ears - if (ear === stop) { - // try filtering points and slicing again - if (!pass) { - earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); + if (config.renderType === CONST.HEADLESS) + { + // Nothing more to do here + return; + } - // if this didn't work, try curing all small self-intersections locally - } else if (pass === 1) { - ear = cureLocalIntersections(filterPoints(ear), triangles, dim); - earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); + var CanvasRenderer; + var WebGLRenderer; - // as a last resort, try splitting the remaining polygon into two - } else if (pass === 2) { - splitEarcut(ear, triangles, dim, minX, minY, invSize); - } + if (true) + { + CanvasRenderer = __webpack_require__(91135); + WebGLRenderer = __webpack_require__(11857); - break; + // Let the config pick the renderer type, as both are included + if (config.renderType === CONST.WEBGL) + { + game.renderer = new WebGLRenderer(game); + } + else + { + game.renderer = new CanvasRenderer(game); + game.context = game.renderer.gameContext; } } -} -// check whether a polygon node forms a valid ear with adjacent nodes -function isEar(ear) { - var a = ear.prev, - b = ear, - c = ear.next; + if (false) + {} - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + if (false) + {} +}; - // now make sure we don't have other points inside the potential ear - var p = ear.next.next; +module.exports = CreateRenderer; - while (p !== ear.prev) { - if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && - area(p.prev, p, p.next) >= 0) return false; - p = p.next; - } - return true; -} +/***/ }), -function isEarHashed(ear, minX, minY, invSize) { - var a = ear.prev, - b = ear, - c = ear.next; +/***/ 77291: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (area(a, b, c) >= 0) return false; // reflex, can't be an ear +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // triangle bbox; min & max are calculated like this for speed - var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x), - minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y), - maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x), - maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y); +var CONST = __webpack_require__(86459); - // z-order range for the current triangle bbox; - var minZ = zOrder(minTX, minTY, minX, minY, invSize), - maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); +/** + * 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; - var p = ear.prevZ, - n = ear.nextZ; + if (config.hideBanner) + { + return; + } - // look for points inside the triangle in both directions - while (p && p.z >= minZ && n && n.z <= maxZ) { - if (p !== ear.prev && p !== ear.next && - pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && - area(p.prev, p, p.next) >= 0) return false; - p = p.prevZ; + var renderType = 'WebGL'; - if (n !== ear.prev && n !== ear.next && - pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && - area(n.prev, n, n.next) >= 0) return false; - n = n.nextZ; + if (config.renderType === CONST.CANVAS) + { + renderType = 'Canvas'; } - - // look for remaining points in decreasing z-order - while (p && p.z >= minZ) { - if (p !== ear.prev && p !== ear.next && - pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && - area(p.prev, p, p.next) >= 0) return false; - p = p.prevZ; + else if (config.renderType === CONST.HEADLESS) + { + renderType = 'Headless'; } - // look for remaining points in increasing z-order - while (n && n.z <= maxZ) { - if (n !== ear.prev && n !== ear.next && - pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && - area(n.prev, n, n.next) >= 0) return false; - n = n.nextZ; + 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'; } - return true; -} + if (!game.device.browser.ie) + { + var c = ''; + var args = [ c ]; -// go through all polygon nodes and cure small local self-intersections -function cureLocalIntersections(start, triangles, dim) { - var p = start; - do { - var a = p.prev, - b = p.next.next; + if (Array.isArray(config.bannerBackgroundColor)) + { + var lastColor; - if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { + config.bannerBackgroundColor.forEach(function (color) + { + c = c.concat('%c '); - triangles.push(a.i / dim); - triangles.push(p.i / dim); - triangles.push(b.i / dim); + args.push('background: ' + color); - // remove two nodes involved - removeNode(p); - removeNode(p.next); + lastColor = color; - p = start = b; + }); + + // inject the text color + args[args.length - 1] = 'color: ' + config.bannerTextColor + '; background: ' + lastColor; } - p = p.next; - } while (p !== start); + else + { + c = c.concat('%c '); - return filterPoints(p); -} + args.push('color: ' + config.bannerTextColor + '; background: ' + config.bannerBackgroundColor); + } -// try splitting polygon into two and triangulate them independently -function splitEarcut(start, triangles, dim, minX, minY, invSize) { - // look for a valid diagonal that divides the polygon into two - var a = start; - do { - var b = a.next.next; - while (b !== a.prev) { - if (a.i !== b.i && isValidDiagonal(a, b)) { - // split the polygon in two by the diagonal - var c = splitPolygon(a, b); + // URL link background color (always transparent to support different browser themes) + args.push('background: transparent'); - // filter colinear points around the cuts - a = filterPoints(a, a.next); - c = filterPoints(c, c.next); + if (config.gameTitle) + { + c = c.concat(config.gameTitle); - // run earcut on each half - earcutLinked(a, triangles, dim, minX, minY, invSize); - earcutLinked(c, triangles, dim, minX, minY, invSize); - return; + if (config.gameVersion) + { + c = c.concat(' v' + config.gameVersion); + } + + if (!config.hidePhaser) + { + c = c.concat(' / '); } - b = b.next; } - a = a.next; - } while (a !== start); -} -// link every hole into the outer loop, producing a single-ring polygon without holes -function eliminateHoles(data, holeIndices, outerNode, dim) { - var queue = [], - i, len, start, end, list; + var fb = ( false) ? 0 : ''; - for (i = 0, len = holeIndices.length; i < len; i++) { - start = holeIndices[i] * dim; - end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; - list = linkedList(data, start, end, dim, false); - if (list === list.next) list.steiner = true; - queue.push(getLeftmost(list)); - } + if (!config.hidePhaser) + { + c = c.concat('Phaser v' + CONST.VERSION + fb + ' (' + renderType + ' | ' + audioType + ')'); + } - queue.sort(compareX); + c = c.concat(' %c ' + config.gameURL); - // process holes from left to right - for (i = 0; i < queue.length; i++) { - eliminateHole(queue[i], outerNode); - outerNode = filterPoints(outerNode, outerNode.next); + // 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'); } +}; - return outerNode; -} +module.exports = DebugHeader; -function compareX(a, b) { - return a.x - b.x; -} -// find a bridge between vertices that connects hole with an outer ring and and link it -function eliminateHole(hole, outerNode) { - outerNode = findHoleBridge(hole, outerNode); - if (outerNode) { - var b = splitPolygon(outerNode, hole); +/***/ }), - // filter collinear points around the cuts - filterPoints(outerNode, outerNode.next); - filterPoints(b, b.next); - } -} +/***/ 15213: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -// David Eberly's algorithm for finding a bridge between hole and outer polygon -function findHoleBridge(hole, outerNode) { - var p = outerNode, - hx = hole.x, - hy = hole.y, - qx = -Infinity, - m; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // find a segment intersected by a ray from the hole's leftmost point to the left; - // segment's endpoint with lesser x will be potential connection point - do { - if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { - var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); - if (x <= hx && x > qx) { - qx = x; - if (x === hx) { - if (hy === p.y) return p; - if (hy === p.next.y) return p.next; - } - m = p.x < p.next.x ? p : p.next; - } - } - p = p.next; - } while (p !== outerNode); +var AddToDOM = __webpack_require__(99584); +var AnimationManager = __webpack_require__(90249); +var CacheManager = __webpack_require__(43474); +var CanvasPool = __webpack_require__(61068); +var Class = __webpack_require__(56694); +var Config = __webpack_require__(14033); +var CreateDOMContainer = __webpack_require__(85178); +var CreateRenderer = __webpack_require__(50150); +var DataManager = __webpack_require__(81078); +var DebugHeader = __webpack_require__(77291); +var Device = __webpack_require__(77290); +var DOMContentLoaded = __webpack_require__(21546); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(97081); +var InputManager = __webpack_require__(69898); +var PluginCache = __webpack_require__(91963); +var PluginManager = __webpack_require__(49274); +var ScaleManager = __webpack_require__(756); +var SceneManager = __webpack_require__(13553); +var TextureEvents = __webpack_require__(38203); +var TextureManager = __webpack_require__(6237); +var TimeStep = __webpack_require__(26617); +var VisibilityHandler = __webpack_require__(26493); - if (!m) return null; +if (true) +{ + var SoundManagerCreator = __webpack_require__(84191); +} - if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint +if (false) +{ var FacebookInstantGamesPlugin; } - // look for points inside the triangle of hole point, segment intersection and endpoint; - // if there are no points found, we have a valid connection; - // otherwise choose the point of the minimum angle with the ray as connection point +/** + * @classdesc + * The Phaser.Game instance is the main controller for the entire Phaser game. It is responsible + * for handling the boot process, parsing the configuration values, creating the renderer, + * and setting-up all of the global Phaser systems, such as sound and input. + * Once that is complete it will start the Scene Manager and then begin the main game loop. + * + * You should generally avoid accessing any of the systems created by Game, and instead use those + * made available to you via the Phaser.Scene Systems class instead. + * + * @class Game + * @memberof Phaser + * @constructor + * @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.Types.Core.GameConfig} [GameConfig] - The configuration object for your Phaser Game instance. + */ +var Game = new Class({ - var stop = m, - mx = m.x, - my = m.y, - tanMin = Infinity, - tan; + initialize: - p = m; + function Game (config) + { + /** + * The parsed Game Configuration object. + * + * The values stored within this object are read-only and should not be changed at run-time. + * + * @name Phaser.Game#config + * @type {Phaser.Core.Config} + * @readonly + * @since 3.0.0 + */ + this.config = new Config(config); - do { - if (hx >= p.x && p.x >= mx && hx !== p.x && - pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { + /** + * A reference to either the Canvas or WebGL Renderer that this Game is using. + * + * @name Phaser.Game#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.0.0 + */ + this.renderer = null; - tan = Math.abs(hy - p.y) / (hx - p.x); // tangential + /** + * A reference to an HTML Div Element used as the DOM Element Container. + * + * Only set if `createDOMContainer` is `true` in the game config (by default it is `false`) and + * if you provide a parent element to insert the Phaser Game inside. + * + * See the DOM Element Game Object for more details. + * + * @name Phaser.Game#domContainer + * @type {HTMLDivElement} + * @since 3.17.0 + */ + this.domContainer = null; - if (locallyInside(p, hole) && - (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) { - m = p; - tanMin = tan; - } - } + /** + * A reference to the HTML Canvas Element that Phaser uses to render the game. + * This is created automatically by Phaser unless you provide a `canvas` property + * in your Game Config. + * + * @name Phaser.Game#canvas + * @type {HTMLCanvasElement} + * @since 3.0.0 + */ + this.canvas = null; - p = p.next; - } while (p !== stop); + /** + * A reference to the Rendering Context belonging to the Canvas Element this game is rendering to. + * If the game is running under Canvas it will be a 2d Canvas Rendering Context. + * If the game is running under WebGL it will be a WebGL Rendering Context. + * This context is created automatically by Phaser unless you provide a `context` property + * in your Game Config. + * + * @name Phaser.Game#context + * @type {(CanvasRenderingContext2D|WebGLRenderingContext)} + * @since 3.0.0 + */ + this.context = null; - return m; -} + /** + * A flag indicating when this Game instance has finished its boot process. + * + * @name Phaser.Game#isBooted + * @type {boolean} + * @readonly + * @since 3.0.0 + */ + this.isBooted = false; -// whether sector in vertex m contains sector in vertex p in the same coordinates -function sectorContainsSector(m, p) { - return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0; -} + /** + * A flag indicating if this Game is currently running its game step or not. + * + * @name Phaser.Game#isRunning + * @type {boolean} + * @readonly + * @since 3.0.0 + */ + this.isRunning = false; -// interlink polygon nodes in z-order -function indexCurve(start, minX, minY, invSize) { - var p = start; - do { - if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize); - p.prevZ = p.prev; - p.nextZ = p.next; - p = p.next; - } while (p !== start); + /** + * An Event Emitter which is used to broadcast game-level events from the global systems. + * + * @name Phaser.Game#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events = new EventEmitter(); - p.prevZ.nextZ = null; - p.prevZ = null; + /** + * An instance of the Animation Manager. + * + * The Animation Manager is a global system responsible for managing all animations used within your game. + * + * @name Phaser.Game#anims + * @type {Phaser.Animations.AnimationManager} + * @since 3.0.0 + */ + this.anims = new AnimationManager(this); - sortLinked(p); -} + /** + * An instance of the Texture Manager. + * + * The Texture Manager is a global system responsible for managing all textures being used by your game. + * + * @name Phaser.Game#textures + * @type {Phaser.Textures.TextureManager} + * @since 3.0.0 + */ + this.textures = new TextureManager(this); -// Simon Tatham's linked list merge sort algorithm -// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html -function sortLinked(list) { - var i, p, q, e, tail, numMerges, pSize, qSize, - inSize = 1; + /** + * An instance of the Cache Manager. + * + * The Cache Manager is a global system responsible for caching, accessing and releasing external game assets. + * + * @name Phaser.Game#cache + * @type {Phaser.Cache.CacheManager} + * @since 3.0.0 + */ + this.cache = new CacheManager(this); - do { - p = list; - list = null; - tail = null; - numMerges = 0; + /** + * An instance of the Data Manager. This is a global manager, available from any Scene + * and allows you to share and exchange your own game-level data or events without having + * to use an internal event system. + * + * @name Phaser.Game#registry + * @type {Phaser.Data.DataManager} + * @since 3.0.0 + */ + this.registry = new DataManager(this, new EventEmitter()); - while (p) { - numMerges++; - q = p; - pSize = 0; - for (i = 0; i < inSize; i++) { - pSize++; - q = q.nextZ; - if (!q) break; - } - qSize = inSize; + /** + * An instance of the Input Manager. + * + * The Input Manager is a global system responsible for the capture of browser-level input events. + * + * @name Phaser.Game#input + * @type {Phaser.Input.InputManager} + * @since 3.0.0 + */ + this.input = new InputManager(this, this.config); - while (pSize > 0 || (qSize > 0 && q)) { + /** + * An instance of the Scene Manager. + * + * The Scene Manager is a global system responsible for creating, modifying and updating the Scenes in your game. + * + * @name Phaser.Game#scene + * @type {Phaser.Scenes.SceneManager} + * @since 3.0.0 + */ + this.scene = new SceneManager(this, this.config.sceneConfig); - if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { - e = p; - p = p.nextZ; - pSize--; - } else { - e = q; - q = q.nextZ; - qSize--; - } + /** + * A reference to the Device inspector. + * + * Contains information about the device running this game, such as OS, browser vendor and feature support. + * Used by various systems to determine capabilities and code paths. + * + * @name Phaser.Game#device + * @type {Phaser.DeviceConf} + * @since 3.0.0 + */ + this.device = Device; - if (tail) tail.nextZ = e; - else list = e; + /** + * An instance of the Scale Manager. + * + * The Scale Manager is a global system responsible for handling scaling of the game canvas. + * + * @name Phaser.Game#scale + * @type {Phaser.Scale.ScaleManager} + * @since 3.16.0 + */ + this.scale = new ScaleManager(this, this.config); - e.prevZ = tail; - tail = e; - } + /** + * An instance of the base Sound Manager. + * + * The Sound Manager is a global system responsible for the playback and updating of all audio in your game. + * + * You can disable the inclusion of the Sound Manager in your build by toggling the webpack `FEATURE_SOUND` flag. + * + * @name Phaser.Game#sound + * @type {(Phaser.Sound.NoAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager)} + * @since 3.0.0 + */ + this.sound = null; - p = q; + if (true) + { + this.sound = SoundManagerCreator.create(this); } - tail.nextZ = null; - inSize *= 2; - - } while (numMerges > 1); + /** + * An instance of the Time Step. + * + * The Time Step is a global system responsible for setting-up and responding to the browser frame events, processing + * them and calculating delta values. It then automatically calls the game step. + * + * @name Phaser.Game#loop + * @type {Phaser.Core.TimeStep} + * @since 3.0.0 + */ + this.loop = new TimeStep(this, this.config.fps); - return list; -} + /** + * An instance of 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.Game#plugins + * @type {Phaser.Plugins.PluginManager} + * @since 3.0.0 + */ + this.plugins = new PluginManager(this, this.config); -// z-order of a point given coords and inverse of the longer side of data bbox -function zOrder(x, y, minX, minY, invSize) { - // coords are transformed into non-negative 15-bit integer range - x = 32767 * (x - minX) * invSize; - y = 32767 * (y - minY) * invSize; + if (false) + {} - x = (x | (x << 8)) & 0x00FF00FF; - x = (x | (x << 4)) & 0x0F0F0F0F; - x = (x | (x << 2)) & 0x33333333; - x = (x | (x << 1)) & 0x55555555; + /** + * Is this Game pending destruction at the start of the next frame? + * + * @name Phaser.Game#pendingDestroy + * @type {boolean} + * @private + * @since 3.5.0 + */ + this.pendingDestroy = false; - y = (y | (y << 8)) & 0x00FF00FF; - y = (y | (y << 4)) & 0x0F0F0F0F; - y = (y | (y << 2)) & 0x33333333; - y = (y | (y << 1)) & 0x55555555; + /** + * Remove the Canvas once the destroy is over? + * + * @name Phaser.Game#removeCanvas + * @type {boolean} + * @private + * @since 3.5.0 + */ + this.removeCanvas = false; - return x | (y << 1); -} + /** + * Remove everything when the game is destroyed. + * You cannot create a new Phaser instance on the same web page after doing this. + * + * @name Phaser.Game#noReturn + * @type {boolean} + * @private + * @since 3.12.0 + */ + this.noReturn = false; -// find the leftmost node of a polygon ring -function getLeftmost(start) { - var p = start, - leftmost = start; - do { - if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p; - p = p.next; - } while (p !== start); + /** + * Does the window the game is running in currently have focus or not? + * This is modified by the VisibilityHandler. + * + * @name Phaser.Game#hasFocus + * @type {boolean} + * @readonly + * @since 3.9.0 + */ + this.hasFocus = false; - return leftmost; -} + /** + * Is the Game currently paused? This will stop everything from updating, + * except the `TimeStep` and related RequestAnimationFrame or setTimeout. + * Those will continue stepping, but the core Game step will be skipped. + * + * @name Phaser.Game#isPaused + * @type {boolean} + * @since 3.60.0 + */ + this.isPaused = false; -// check if a point lies within a convex triangle -function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { - return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && - (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && - (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; -} + // Wait for the DOM Ready event, then call boot. + DOMContentLoaded(this.boot.bind(this)); + }, -// check if a diagonal between two polygon nodes is valid (lies in polygon interior) -function isValidDiagonal(a, b) { - return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges - (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible - (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors - equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case -} + /** + * This method is called automatically when the DOM is ready. It is responsible for creating the renderer, + * displaying the Debug Header, adding the game canvas to the DOM and emitting the 'boot' event. + * It listens for a 'ready' event from the base systems and once received it will call `Game.start`. + * + * @method Phaser.Game#boot + * @protected + * @fires Phaser.Core.Events#BOOT + * @listens Phaser.Textures.Events#READY + * @since 3.0.0 + */ + boot: function () + { + if (!PluginCache.hasCore('EventEmitter')) + { + console.warn('Aborting. Core Plugins missing.'); + return; + } -// signed area of a triangle -function area(p, q, r) { - return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); -} + this.isBooted = true; -// check if two points are equal -function equals(p1, p2) { - return p1.x === p2.x && p1.y === p2.y; -} + this.config.preBoot(this); -// check if two segments intersect -function intersects(p1, q1, p2, q2) { - var o1 = sign(area(p1, q1, p2)); - var o2 = sign(area(p1, q1, q2)); - var o3 = sign(area(p2, q2, p1)); - var o4 = sign(area(p2, q2, q1)); + this.scale.preBoot(); - if (o1 !== o2 && o3 !== o4) return true; // general case + CreateRenderer(this); - if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 - if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 - if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 - if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 + CreateDOMContainer(this); - return false; -} + DebugHeader(this); -// for collinear points p, q, r, check if point q lies on segment pr -function onSegment(p, q, r) { - return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y); -} + AddToDOM(this.canvas, this.config.parent); -function sign(num) { - return num > 0 ? 1 : num < 0 ? -1 : 0; -} + // The Texture Manager has to wait on a couple of non-blocking events before it's fully ready. + // So it will emit this internal event when done: + this.textures.once(TextureEvents.READY, this.texturesReady, this); -// check if a polygon diagonal intersects any polygon segments -function intersectsPolygon(a, b) { - var p = a; - do { - if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && - intersects(p, p.next, a, b)) return true; - p = p.next; - } while (p !== a); + this.events.emit(Events.BOOT); - return false; -} + if (false) + {} + }, -// check if a polygon diagonal is locally inside the polygon -function locallyInside(a, b) { - return area(a.prev, a, a.next) < 0 ? - area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : - area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; -} + /** + * Called automatically when the Texture Manager has finished setting up and preparing the + * default textures. + * + * @method Phaser.Game#texturesReady + * @private + * @fires Phaser.Game#READY + * @since 3.12.0 + */ + texturesReady: function () + { + // Start all the other systems + this.events.emit(Events.READY); -// check if the middle point of a polygon diagonal is inside the polygon -function middleInside(a, b) { - var p = a, - inside = false, - px = (a.x + b.x) / 2, - py = (a.y + b.y) / 2; - do { - if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y && - (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) - inside = !inside; - p = p.next; - } while (p !== a); + this.start(); + }, - return inside; -} + /** + * Called automatically by Game.boot once all of the global systems have finished setting themselves up. + * By this point the Game is now ready to start the main loop running. + * It will also enable the Visibility Handler. + * + * @method Phaser.Game#start + * @protected + * @since 3.0.0 + */ + start: function () + { + this.isRunning = true; -// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; -// if one belongs to the outer ring and another to a hole, it merges it into a single ring -function splitPolygon(a, b) { - var a2 = new Node(a.i, a.x, a.y), - b2 = new Node(b.i, b.x, b.y), - an = a.next, - bp = b.prev; + this.config.postBoot(this); - a.next = b; - b.prev = a; + if (this.renderer) + { + this.loop.start(this.step.bind(this)); + } + else + { + this.loop.start(this.headlessStep.bind(this)); + } - a2.next = an; - an.prev = a2; + VisibilityHandler(this); - b2.next = a2; - a2.prev = b2; + var eventEmitter = this.events; - bp.next = b2; - b2.prev = bp; + eventEmitter.on(Events.HIDDEN, this.onHidden, this); + eventEmitter.on(Events.VISIBLE, this.onVisible, this); + eventEmitter.on(Events.BLUR, this.onBlur, this); + eventEmitter.on(Events.FOCUS, this.onFocus, this); + }, - return b2; -} + /** + * The main Game Step. Called automatically by the Time Step, once per browser frame (typically as a result of + * Request Animation Frame, or Set Timeout on very old browsers.) + * + * The step will update the global managers first, then proceed to update each Scene in turn, via the Scene Manager. + * + * It will then render each Scene in turn, via the Renderer. This process emits `prerender` and `postrender` events. + * + * @method Phaser.Game#step + * @fires Phaser.Core.Events#PRE_STEP + * @fires Phaser.Core.Events#STEP + * @fires Phaser.Core.Events#POST_STEP + * @fires Phaser.Core.Events#PRE_RENDER + * @fires Phaser.Core.Events#POST_RENDER + * @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. + */ + step: function (time, delta) + { + if (this.pendingDestroy) + { + return this.runDestroy(); + } -// create a node and optionally link it with previous one (in a circular doubly linked list) -function insertNode(i, x, y, last) { - var p = new Node(i, x, y); + if (this.isPaused) + { + return; + } - if (!last) { - p.prev = p; - p.next = p; + var eventEmitter = this.events; - } else { - p.next = last.next; - p.prev = last; - last.next.prev = p; - last.next = p; - } - return p; -} + // Global Managers like Input and Sound update in the prestep -function removeNode(p) { - p.next.prev = p.prev; - p.prev.next = p.next; + eventEmitter.emit(Events.PRE_STEP, time, delta); - if (p.prevZ) p.prevZ.nextZ = p.nextZ; - if (p.nextZ) p.nextZ.prevZ = p.prevZ; -} + // This is mostly meant for user-land code and plugins -function Node(i, x, y) { - // vertex index in coordinates array - this.i = i; + eventEmitter.emit(Events.STEP, time, delta); - // vertex coordinates - this.x = x; - this.y = y; + // Update the Scene Manager and all active Scenes - // previous and next vertex nodes in a polygon ring - this.prev = null; - this.next = null; + this.scene.update(time, delta); - // z-order curve value - this.z = null; + // Our final event before rendering starts - // previous and next nodes in z-order - this.prevZ = null; - this.nextZ = null; + eventEmitter.emit(Events.POST_STEP, time, delta); - // indicates whether this is a steiner point - this.steiner = false; -} + var renderer = this.renderer; -// return a percentage difference between the polygon area and its triangulation area; -// used to verify correctness of triangulation -earcut.deviation = function (data, holeIndices, dim, triangles) { - var hasHoles = holeIndices && holeIndices.length; - var outerLen = hasHoles ? holeIndices[0] * dim : data.length; + // Run the Pre-render (clearing the canvas, setting background colors, etc) - var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); - if (hasHoles) { - for (var i = 0, len = holeIndices.length; i < len; i++) { - var start = holeIndices[i] * dim; - var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; - polygonArea -= Math.abs(signedArea(data, start, end, dim)); - } - } + renderer.preRender(); - var trianglesArea = 0; - for (i = 0; i < triangles.length; i += 3) { - var a = triangles[i] * dim; - var b = triangles[i + 1] * dim; - var c = triangles[i + 2] * dim; - trianglesArea += Math.abs( - (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - - (data[a] - data[b]) * (data[c + 1] - data[a + 1])); - } + eventEmitter.emit(Events.PRE_RENDER, renderer, time, delta); - return polygonArea === 0 && trianglesArea === 0 ? 0 : - Math.abs((trianglesArea - polygonArea) / polygonArea); -}; + // The main render loop. Iterates all Scenes and all Cameras in those scenes, rendering to the renderer instance. -function signedArea(data, start, end, dim) { - var sum = 0; - for (var i = start, j = end - dim; i < end; i += dim) { - sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); - j = i; - } - return sum; -} + this.scene.render(renderer); -// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts -earcut.flatten = function (data) { - var dim = data[0][0].length, - result = {vertices: [], holes: [], dimensions: dim}, - holeIndex = 0; + // The Post-Render call. Tidies up loose end, takes snapshots, etc. - for (var i = 0; i < data.length; i++) { - for (var j = 0; j < data[i].length; j++) { - for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); - } - if (i > 0) { - holeIndex += data[i - 1].length; - result.holes.push(holeIndex); - } - } - return result; -}; + renderer.postRender(); -module.exports = earcut; + // The final event before the step repeats. Your last chance to do anything to the canvas before it all starts again. + eventEmitter.emit(Events.POST_RENDER, renderer, time, delta); + }, -/***/ }), -/* 60 */ -/***/ (function(module, exports) { + /** + * A special version of the Game Step for the HEADLESS renderer only. + * + * The main Game Step. Called automatically by the Time Step, once per browser frame (typically as a result of + * Request Animation Frame, or Set Timeout on very old browsers.) + * + * The step will update the global managers first, then proceed to update each Scene in turn, via the Scene Manager. + * + * This process emits `prerender` and `postrender` events, even though nothing actually displays. + * + * @method Phaser.Game#headlessStep + * @fires Phaser.Game#PRE_RENDER + * @fires Phaser.Game#POST_RENDER + * @since 3.2.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. + */ + headlessStep: function (time, delta) + { + if (this.pendingDestroy) + { + return this.runDestroy(); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.isPaused) + { + return; + } -/** - * 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 eventEmitter = this.events; - var red = ((strokeColor & 0xFF0000) >>> 16); - var green = ((strokeColor & 0xFF00) >>> 8); - var blue = (strokeColor & 0xFF); + // Global Managers like Input and Sound update in the prestep - ctx.strokeStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + strokeAlpha + ')'; - ctx.lineWidth = src.lineWidth; -}; + eventEmitter.emit(Events.PRE_STEP, time, delta); -module.exports = LineStyleCanvas; + // This is mostly meant for user-land code and plugins + eventEmitter.emit(Events.STEP, time, delta); -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { + // Update the Scene Manager and all active Scenes -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.scene.update(time, delta); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -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); + // Our final event before rendering starts -/** - * @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({ + eventEmitter.emit(Events.POST_STEP, time, delta); - Extends: File, + // Render + this.scene.isProcessing = false; - initialize: + eventEmitter.emit(Events.PRE_RENDER, null, time, delta); - // 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 + eventEmitter.emit(Events.POST_RENDER, null, time, delta); + }, - function JSONFile (loader, key, url, xhrSettings, dataKey) + /** + * Called automatically by the Visibility Handler. + * This will pause the main loop and then emit a pause event. + * + * @method Phaser.Game#onHidden + * @protected + * @fires Phaser.Core.Events#PAUSE + * @since 3.0.0 + */ + onHidden: function () { - 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.loop.pause(); - this.state = CONST.FILE_POPULATED; - } + this.events.emit(Events.PAUSE); }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * This will pause the entire game and emit a `PAUSE` event. * - * @method Phaser.Loader.FileTypes.JSONFile#onProcess - * @since 3.7.0 + * All of Phaser's internal systems will be paused and the game will not re-render. + * + * Note that it does not pause any Loader requests that are currently in-flight. + * + * @method Phaser.Game#pause + * @fires Phaser.Core.Events#PAUSE + * @since 3.60.0 */ - onProcess: function () + pause: function () { - if (this.state !== CONST.FILE_POPULATED) - { - this.state = CONST.FILE_PROCESSING; - - try - { - var json = JSON.parse(this.xhrLoader.responseText); - } - catch (e) - { - console.warn('Invalid JSON: ' + this.key); - - this.onProcessError(); - - throw e; - } - - var key = this.config; - - if (typeof key === 'string') - { - this.data = GetValue(json, key, json); - } - else - { - this.data = json; - } - } - - this.onProcessComplete(); - } + var wasPaused = this.isPaused; -}); + this.isPaused = true; -/** - * 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 (!wasPaused) { - // 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])); + this.events.emit(Events.PAUSE); } - } - else - { - this.addFile(new JSONFile(this, key, url, xhrSettings, dataKey)); - } - - return this; -}); - -module.exports = JSONFile; - - -/***/ }), -/* 62 */ -/***/ (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. + * Called automatically by the Visibility Handler. + * This will resume the main loop and then emit a resume event. * - * @name Phaser.Physics.Arcade.DYNAMIC_BODY - * @readonly - * @type {number} + * @method Phaser.Game#onVisible + * @protected + * @fires Phaser.Core.Events#RESUME * @since 3.0.0 - * - * @see Phaser.Physics.Arcade.Body#physicsType - * @see Phaser.Physics.Arcade.Group#physicsType */ - DYNAMIC_BODY: 0, + onVisible: function () + { + this.loop.resume(); + + this.events.emit(Events.RESUME); + }, /** - * Static Body. + * This will resume the entire game and emit a `RESUME` event. * - * @name Phaser.Physics.Arcade.STATIC_BODY - * @readonly - * @type {number} - * @since 3.0.0 + * All of Phaser's internal systems will be resumed and the game will start rendering again. * - * @see Phaser.Physics.Arcade.Body#physicsType - * @see Phaser.Physics.Arcade.StaticBody#physicsType + * @method Phaser.Game#resume + * @fires Phaser.Core.Events#RESUME + * @since 3.60.0 */ - STATIC_BODY: 1, + resume: function () + { + var wasPaused = this.isPaused; + + this.isPaused = false; + + if (wasPaused) + { + this.events.emit(Events.RESUME); + } + }, /** - * Arcade Physics Group containing Dynamic Bodies. + * Called automatically by the Visibility Handler. + * This will set the main loop into a 'blurred' state, which pauses it. * - * @name Phaser.Physics.Arcade.GROUP - * @readonly - * @type {number} + * @method Phaser.Game#onBlur + * @protected * @since 3.0.0 */ - GROUP: 2, + onBlur: function () + { + this.hasFocus = false; + + this.loop.blur(); + }, /** - * A Tilemap Layer. + * Called automatically by the Visibility Handler. + * This will set the main loop into a 'focused' state, which resumes it. * - * @name Phaser.Physics.Arcade.TILEMAPLAYER - * @readonly - * @type {number} + * @method Phaser.Game#onFocus + * @protected * @since 3.0.0 */ - TILEMAPLAYER: 3, + onFocus: function () + { + this.hasFocus = true; + + this.loop.focus(); + }, /** - * Facing no direction (initial value). + * Returns the current game frame. * - * @name Phaser.Physics.Arcade.FACING_NONE - * @readonly - * @type {number} - * @since 3.0.0 + * When the game starts running, the frame is incremented every time Request Animation Frame, or Set Timeout, fires. * - * @see Phaser.Physics.Arcade.Body#facing + * @method Phaser.Game#getFrame + * @since 3.16.0 + * + * @return {number} The current game frame. */ - FACING_NONE: 10, + getFrame: function () + { + return this.loop.frame; + }, /** - * Facing up. + * Returns the time that the current game step started at, as based on `performance.now`. * - * @name Phaser.Physics.Arcade.FACING_UP - * @readonly - * @type {number} - * @since 3.0.0 + * @method Phaser.Game#getTime + * @since 3.16.0 * - * @see Phaser.Physics.Arcade.Body#facing + * @return {number} The current game timestamp. */ - FACING_UP: 11, + getTime: function () + { + return this.loop.now; + }, /** - * Facing down. + * Flags this Game instance as needing to be destroyed on the _next frame_, making this an asynchronous operation. * - * @name Phaser.Physics.Arcade.FACING_DOWN - * @readonly - * @type {number} - * @since 3.0.0 + * It will wait until the current frame has completed and then call `runDestroy` internally. * - * @see Phaser.Physics.Arcade.Body#facing - */ - FACING_DOWN: 12, - - /** - * Facing left. + * If you need to react to the games eventual destruction, listen for the `DESTROY` event. * - * @name Phaser.Physics.Arcade.FACING_LEFT - * @readonly - * @type {number} + * If you **do not** need to run Phaser again on the same web page you can set the `noReturn` argument to `true` and it will free-up + * memory being held by the core Phaser plugins. If you do need to create another game instance on the same page, leave this as `false`. + * + * @method Phaser.Game#destroy + * @fires Phaser.Core.Events#DESTROY * @since 3.0.0 * - * @see Phaser.Physics.Arcade.Body#facing + * @param {boolean} removeCanvas - Set to `true` if you would like the parent canvas element removed from the DOM, or `false` to leave it in place. + * @param {boolean} [noReturn=false] - If `true` all the core Phaser plugins are destroyed. You cannot create another instance of Phaser on the same web page if you do this. */ - FACING_LEFT: 13, + destroy: function (removeCanvas, noReturn) + { + if (noReturn === undefined) { noReturn = false; } + + this.pendingDestroy = true; + + this.removeCanvas = removeCanvas; + this.noReturn = noReturn; + }, /** - * Facing right. - * - * @name Phaser.Physics.Arcade.FACING_RIGHT - * @readonly - * @type {number} - * @since 3.0.0 + * Destroys this Phaser.Game instance, all global systems, all sub-systems and all Scenes. * - * @see Phaser.Physics.Arcade.Body#facing + * @method Phaser.Game#runDestroy + * @private + * @since 3.5.0 */ - FACING_RIGHT: 14 + runDestroy: function () + { + this.scene.destroy(); -}; + this.events.emit(Events.DESTROY); -module.exports = CONST; + this.events.removeAllListeners(); + + if (this.renderer) + { + this.renderer.destroy(); + } + + if (this.removeCanvas && this.canvas) + { + CanvasPool.remove(this.canvas); + + if (this.canvas.parentNode) + { + this.canvas.parentNode.removeChild(this.canvas); + } + } + + if (this.domContainer) + { + this.domContainer.parentNode.removeChild(this.domContainer); + } + + this.loop.destroy(); + + this.pendingDestroy = false; + } + +}); + +module.exports = Game; + +/** + * "Computers are good at following instructions, but not at reading your mind." - Donald Knuth + */ /***/ }), -/* 63 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 26617: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetTileAt = __webpack_require__(158); -var GetTilesWithin = __webpack_require__(26); +var Class = __webpack_require__(56694); +var GetValue = __webpack_require__(10850); +var NOOP = __webpack_require__(72283); +var RequestAnimationFrame = __webpack_require__(27385); + +// http://www.testufo.com/#test=animation-time-graph /** - * 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. + * @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. * - * @function Phaser.Tilemaps.Components.CalculateFacesWithin + * 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 {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. + * @param {Phaser.Game} game - A reference to the Phaser.Game instance that owns this Time Step. + * @param {Phaser.Types.Core.FPSConfig} config */ -var CalculateFacesWithin = function (tileX, tileY, width, height, layer) -{ - var above = null; - var below = null; - var left = null; - var right = null; +var TimeStep = new Class({ - var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + initialize: - for (var i = 0; i < tiles.length; i++) + function TimeStep (game, config) { - var tile = tiles[i]; + /** + * A reference to the Phaser.Game instance. + * + * @name Phaser.Core.TimeStep#game + * @type {Phaser.Game} + * @readonly + * @since 3.0.0 + */ + this.game = game; - 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); + /** + * 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(); - 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(); - } - } - } -}; + /** + * 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; -module.exports = CalculateFacesWithin; + /** + * 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. + * + * Setting this cannot guarantee the browser runs at this rate, it merely influences + * the internal timing values to help the Timestep know when it has gone out of sync. + * + * @name Phaser.Core.TimeStep#minFps + * @type {number} + * @default 5 + * @since 3.0.0 + */ + this.minFps = GetValue(config, 'min', 5); -/***/ }), -/* 64 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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 `Matter.Vertices` module contains methods for creating and manipulating sets of vertices. -* A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`. -* A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull). -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Vertices -*/ + /** + * Enforce a frame rate limit. This forces how often the Game step will run. By default it is zero, + * which means it will run at whatever limit the browser (via RequestAnimationFrame) can handle, which + * is the optimum rate for fast-action or responsive games. + * + * However, if you are building a non-game app, like a graphics generator, or low-intensity game that doesn't + * require 60fps, then you can lower the step rate via this Game Config value: + * + * ```js + * fps: { + * limit: 30 + * } + * ``` + * + * Setting this _beyond_ the rate of RequestAnimationFrame will make no difference at all. + * + * Use it purely to _restrict_ updates in low-intensity situations only. + * + * @name Phaser.Core.TimeStep#fpsLimit + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.fpsLimit = GetValue(config, 'limit', 0); -var Vertices = {}; + /** + * Is the FPS rate limited? + * + * This is set by setting the Game Config `limit` value to a value above zero. + * + * Consider this property as read-only. + * + * @name Phaser.Core.TimeStep#hasFpsLimit + * @type {boolean} + * @default false + * @since 3.60.0 + */ + this.hasFpsLimit = (this.fpsLimit > 0); -module.exports = Vertices; + /** + * Internal value holding the fps rate limit in ms. + * + * @name Phaser.Core.TimeStep#_limitRate + * @type {number} + * @private + * @since 3.60.0 + */ + this._limitRate = (this.hasFpsLimit) ? (1000 / this.fpsLimit) : 0; -var Vector = __webpack_require__(83); -var Common = __webpack_require__(32); + /** + * The minimum fps 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; -(function() { + /** + * The target fps 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; - /** - * Creates a new set of `Matter.Body` compatible vertices. - * The `points` argument accepts an array of `Matter.Vector` points orientated around the origin `(0, 0)`, for example: - * - * [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }] - * - * The `Vertices.create` method returns a new array of vertices, which are similar to Matter.Vector objects, - * but with some additional references required for efficient collision detection routines. - * - * Vertices must be specified in clockwise order. - * - * Note that the `body` argument is not optional, a `Matter.Body` reference must be provided. - * - * @method create - * @param {vector[]} points - * @param {body} body - */ - Vertices.create = function(points, body) { - var vertices = []; + /** + * 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; - for (var i = 0; i < points.length; i++) { - var point = points[i], - vertex = { - x: point.x, - y: point.y, - index: i, - body: body, - isInternal: false, - contact: null, - offset: null - }; + /** + * 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; - vertex.contact = { - vertex: vertex, - normalImpulse: 0, - tangentImpulse: 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; - vertices.push(vertex); - } + /** + * A callback to be invoked each time the TimeStep steps. + * + * @name Phaser.Core.TimeStep#callback + * @type {Phaser.Types.Core.TimeStepCallback} + * @default NOOP + * @since 3.0.0 + */ + this.callback = NOOP; - return vertices; - }; + /** + * You can force the TimeStep to use SetTimeOut 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); - /** - * Parses a string containing ordered x y pairs separated by spaces (and optionally commas), - * into a `Matter.Vertices` object for the given `Matter.Body`. - * For parsing SVG paths, see `Svg.pathToVertices`. - * @method fromPath - * @param {string} path - * @param {body} body - * @return {vertices} vertices - */ - Vertices.fromPath = function(path, body) { - var pathPattern = /L?\s*([-\d.e]+)[\s,]*([-\d.e]+)*/ig, - points = []; + /** + * The time, updated each step by adding the elapsed delta time to the previous value. + * + * This differs from the `TimeStep.now` value, which is the high resolution time value + * as provided by Request Animation Frame. + * + * @name Phaser.Core.TimeStep#time + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.time = 0; - path.replace(pathPattern, function(match, x, y) { - points.push({ x: parseFloat(x), y: parseFloat(y) }); - }); + /** + * 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; - return Vertices.create(points, body); - }; + /** + * The time of the previous step. + * + * This is typically a high resolution timer value, as provided by Request Animation Frame. + * + * @name Phaser.Core.TimeStep#lastTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.lastTime = 0; - /** - * Returns the centre (centroid) of the set of vertices. - * @method centre - * @param {vertices} vertices - * @return {vector} The centre point - */ - Vertices.centre = function(vertices) { - var area = Vertices.area(vertices, true), - centre = { x: 0, y: 0 }, - cross, - temp, - j; + /** + * 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; - for (var i = 0; i < vertices.length; i++) { - j = (i + 1) % vertices.length; - cross = Vector.cross(vertices[i], vertices[j]); - temp = Vector.mult(Vector.add(vertices[i], vertices[j]), cross); - centre = Vector.add(centre, temp); - } + /** + * 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; - return Vector.div(centre, 6 * area); - }; - - /** - * Returns the average (mean) of the set of vertices. - * @method mean - * @param {vertices} vertices - * @return {vector} The average point - */ - Vertices.mean = function(vertices) { - var average = { x: 0, y: 0 }; - - for (var i = 0; i < vertices.length; i++) { - average.x += vertices[i].x; - average.y += vertices[i].y; - } - - return Vector.div(average, vertices.length); - }; - - /** - * Returns the area of the set of vertices. - * @method area - * @param {vertices} vertices - * @param {bool} signed - * @return {number} The area - */ - Vertices.area = function(vertices, signed) { - var area = 0, - j = vertices.length - 1; - - for (var i = 0; i < vertices.length; i++) { - area += (vertices[j].x - vertices[i].x) * (vertices[j].y + vertices[i].y); - j = i; - } - - if (signed) - return area / 2; - - return Math.abs(area) / 2; - }; - - /** - * Returns the moment of inertia (second moment of area) of the set of vertices given the total mass. - * @method inertia - * @param {vertices} vertices - * @param {number} mass - * @return {number} The polygon's moment of inertia - */ - Vertices.inertia = function(vertices, mass) { - var numerator = 0, - denominator = 0, - v = vertices, - cross, - j; - - // find the polygon's moment of inertia, using second moment of area - // from equations at http://www.physicsforums.com/showthread.php?t=25293 - for (var n = 0; n < v.length; n++) { - j = (n + 1) % v.length; - cross = Math.abs(Vector.cross(v[j], v[n])); - numerator += cross * (Vector.dot(v[j], v[j]) + Vector.dot(v[j], v[n]) + Vector.dot(v[n], v[n])); - denominator += cross; - } - - return (mass / 6) * (numerator / denominator); - }; - - /** - * Translates the set of vertices in-place. - * @method translate - * @param {vertices} vertices - * @param {vector} vector - * @param {number} scalar - */ - Vertices.translate = function(vertices, vector, scalar) { - var i; - if (scalar) { - for (i = 0; i < vertices.length; i++) { - vertices[i].x += vector.x * scalar; - vertices[i].y += vector.y * scalar; - } - } else { - for (i = 0; i < vertices.length; i++) { - vertices[i].x += vector.x; - vertices[i].y += vector.y; - } - } - - return vertices; - }; - - /** - * Rotates the set of vertices in-place. - * @method rotate - * @param {vertices} vertices - * @param {number} angle - * @param {vector} point - */ - Vertices.rotate = function(vertices, angle, point) { - if (angle === 0) - return; - - var cos = Math.cos(angle), - sin = Math.sin(angle); - - for (var i = 0; i < vertices.length; i++) { - var vertice = vertices[i], - dx = vertice.x - point.x, - dy = vertice.y - point.y; - - vertice.x = point.x + (dx * cos - dy * sin); - vertice.y = point.y + (dx * sin + dy * cos); - } - - return vertices; - }; - - /** - * Returns `true` if the `point` is inside the set of `vertices`. - * @method contains - * @param {vertices} vertices - * @param {vector} point - * @return {boolean} True if the vertices contains point, otherwise false - */ - Vertices.contains = function(vertices, point) { - for (var i = 0; i < vertices.length; i++) { - var vertice = vertices[i], - nextVertice = vertices[(i + 1) % vertices.length]; - if ((point.x - vertice.x) * (nextVertice.y - vertice.y) + (point.y - vertice.y) * (vertice.x - nextVertice.x) > 0) { - return false; - } - } - - return true; - }; - - /** - * Scales the vertices from a point (default is centre) in-place. - * @method scale - * @param {vertices} vertices - * @param {number} scaleX - * @param {number} scaleY - * @param {vector} point - */ - Vertices.scale = function(vertices, scaleX, scaleY, point) { - if (scaleX === 1 && scaleY === 1) - return vertices; - - point = point || Vertices.centre(vertices); - - var vertex, - delta; - - for (var i = 0; i < vertices.length; i++) { - vertex = vertices[i]; - delta = Vector.sub(vertex, point); - vertices[i].x = point.x + delta.x * scaleX; - vertices[i].y = point.y + delta.y * scaleY; - } - - return vertices; - }; - - /** - * Chamfers a set of vertices by giving them rounded corners, returns a new set of vertices. - * The radius parameter is a single number or an array to specify the radius for each vertex. - * @method chamfer - * @param {vertices} vertices - * @param {number[]} radius - * @param {number} quality - * @param {number} qualityMin - * @param {number} qualityMax - */ - Vertices.chamfer = function(vertices, radius, quality, qualityMin, qualityMax) { - if (typeof radius === 'number') { - radius = [radius]; - } else { - radius = radius || [8]; - } - - // quality defaults to -1, which is auto - quality = (typeof quality !== 'undefined') ? quality : -1; - qualityMin = qualityMin || 2; - qualityMax = qualityMax || 14; - - var newVertices = []; - - for (var i = 0; i < vertices.length; i++) { - var prevVertex = vertices[i - 1 >= 0 ? i - 1 : vertices.length - 1], - vertex = vertices[i], - nextVertex = vertices[(i + 1) % vertices.length], - currentRadius = radius[i < radius.length ? i : radius.length - 1]; - - if (currentRadius === 0) { - newVertices.push(vertex); - continue; - } - - var prevNormal = Vector.normalise({ - x: vertex.y - prevVertex.y, - y: prevVertex.x - vertex.x - }); - - var nextNormal = Vector.normalise({ - x: nextVertex.y - vertex.y, - y: vertex.x - nextVertex.x - }); - - var diagonalRadius = Math.sqrt(2 * Math.pow(currentRadius, 2)), - radiusVector = Vector.mult(Common.clone(prevNormal), currentRadius), - midNormal = Vector.normalise(Vector.mult(Vector.add(prevNormal, nextNormal), 0.5)), - scaledVertex = Vector.sub(vertex, Vector.mult(midNormal, diagonalRadius)); - - var precision = quality; - - if (quality === -1) { - // automatically decide precision - precision = Math.pow(currentRadius, 0.32) * 1.75; - } - - precision = Common.clamp(precision, qualityMin, qualityMax); - - // use an even value for precision, more likely to reduce axes by using symmetry - if (precision % 2 === 1) - precision += 1; - - var alpha = Math.acos(Vector.dot(prevNormal, nextNormal)), - theta = alpha / precision; - - for (var j = 0; j < precision; j++) { - newVertices.push(Vector.add(Vector.rotate(radiusVector, theta * j), scaledVertex)); - } - } - - return newVertices; - }; - - /** - * Sorts the input vertices into clockwise order in place. - * @method clockwiseSort - * @param {vertices} vertices - * @return {vertices} vertices - */ - Vertices.clockwiseSort = function(vertices) { - var centre = Vertices.mean(vertices); - - vertices.sort(function(vertexA, vertexB) { - return Vector.angle(centre, vertexA) - Vector.angle(centre, vertexB); - }); - - return vertices; - }; - - /** - * Returns true if the vertices form a convex shape (vertices must be in clockwise order). - * @method isConvex - * @param {vertices} vertices - * @return {bool} `true` if the `vertices` are convex, `false` if not (or `null` if not computable). - */ - Vertices.isConvex = function(vertices) { - // http://paulbourke.net/geometry/polygonmesh/ - // Copyright (c) Paul Bourke (use permitted) - - var flag = 0, - n = vertices.length, - i, - j, - k, - z; - - if (n < 3) - return null; - - for (i = 0; i < n; i++) { - j = (i + 1) % n; - k = (i + 2) % n; - z = (vertices[j].x - vertices[i].x) * (vertices[k].y - vertices[j].y); - z -= (vertices[j].y - vertices[i].y) * (vertices[k].x - vertices[j].x); - - if (z < 0) { - flag |= 1; - } else if (z > 0) { - flag |= 2; - } - - if (flag === 3) { - return false; - } - } - - if (flag !== 0){ - return true; - } else { - return null; - } - }; - - /** - * Returns the convex hull of the input vertices as a new array of points. - * @method hull - * @param {vertices} vertices - * @return [vertex] vertices - */ - Vertices.hull = function(vertices) { - // http://geomalgorithms.com/a10-_hull-1.html - - var upper = [], - lower = [], - vertex, - i; - - // sort vertices on x-axis (y-axis for ties) - vertices = vertices.slice(0); - vertices.sort(function(vertexA, vertexB) { - var dx = vertexA.x - vertexB.x; - return dx !== 0 ? dx : vertexA.y - vertexB.y; - }); - - // build lower hull - for (i = 0; i < vertices.length; i += 1) { - vertex = vertices[i]; - - while (lower.length >= 2 - && Vector.cross3(lower[lower.length - 2], lower[lower.length - 1], vertex) <= 0) { - lower.pop(); - } - - lower.push(vertex); - } - - // build upper hull - for (i = vertices.length - 1; i >= 0; i -= 1) { - vertex = vertices[i]; - - while (upper.length >= 2 - && Vector.cross3(upper[upper.length - 2], upper[upper.length - 1], vertex) <= 0) { - upper.pop(); - } - - upper.push(vertex); - } - - // concatenation of the lower and upper hulls gives the convex hull - // omit last points because they are repeated at the beginning of the other list - upper.pop(); - lower.pop(); - - return upper.concat(lower); - }; - -})(); - - -/***/ }), -/* 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 Contains = __webpack_require__(66); -var GetPoint = __webpack_require__(300); -var GetPoints = __webpack_require__(301); -var GEOM_CONST = __webpack_require__(56); -var Random = __webpack_require__(170); - -/** - * @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 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; /** - * The geometry constant type of this object: `GEOM_CONST.CIRCLE`. - * Used for fast type comparisons. + * An internal counter to allow for the browser 'cooling down' after coming back into focus. * - * @name Phaser.Geom.Circle#type + * @name Phaser.Core.TimeStep#_coolDown * @type {number} - * @readonly - * @since 3.19.0 + * @private + * @default 0 + * @since 3.0.0 */ - this.type = GEOM_CONST.CIRCLE; + this._coolDown = 0; /** - * The x position of the center of the circle. + * The delta time, in ms, since the last game step. This is a clamped and smoothed average value. * - * @name Phaser.Geom.Circle#x + * @name Phaser.Core.TimeStep#delta * @type {number} * @default 0 * @since 3.0.0 */ - this.x = x; + this.delta = 0; /** - * The y position of the center of the circle. + * Internal index of the delta history position. * - * @name Phaser.Geom.Circle#y + * @name Phaser.Core.TimeStep#deltaIndex * @type {number} * @default 0 * @since 3.0.0 */ - this.y = y; + this.deltaIndex = 0; /** - * The internal radius of the circle. + * Internal array holding the previous delta values, used for delta smoothing. * - * @name Phaser.Geom.Circle#_radius + * @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} - * @private + * @default 10 * @since 3.0.0 */ - this._radius = radius; + this.deltaSmoothingMax = GetValue(config, 'deltaHistory', 10); /** - * The internal diameter of the circle. + * 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. * - * @name Phaser.Geom.Circle#_diameter + * This can be changed in the Game Config via the `fps.panicMax` property. The default is 120. + * + * @name Phaser.Core.TimeStep#panicMax * @type {number} - * @private + * @default 120 * @since 3.0.0 */ - this._diameter = radius * 2; + 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, set at the start of the current step. + * + * This is typically a high resolution timer value, as provided by Request Animation Frame. + * + * 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); }, /** - * Check to see if the Circle contains the given x / y coordinates. + * Called by the Game instance when the DOM window.onBlur event triggers. * - * @method Phaser.Geom.Circle#contains + * @method Phaser.Core.TimeStep#blur * @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) + blur: function () { - return Contains(this, x, y); + this.inFocus = false; }, /** - * 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. + * Called by the Game instance when the DOM window.onFocus event triggers. * - * @method Phaser.Geom.Circle#getPoint + * @method Phaser.Core.TimeStep#focus * @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) + focus: function () { - return GetPoint(this, position, point); + this.inFocus = true; + + this.resetDelta(); }, /** - * 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. + * Called when the visibility API says the game is 'hidden' (tab switch out of view, etc) * - * @method Phaser.Geom.Circle#getPoints + * @method Phaser.Core.TimeStep#pause * @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) + pause: function () { - return GetPoints(this, quantity, stepRate, output); + this._pauseTime = window.performance.now(); }, /** - * Returns a uniformly distributed random point from anywhere within the Circle. + * Called when the visibility API says the game is 'visible' again (tab switch back into view, etc) * - * @method Phaser.Geom.Circle#getRandomPoint + * @method Phaser.Core.TimeStep#resume * @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) + resume: function () { - return Random(this, point); + this.resetDelta(); + + this.startTime += this.time - this._pauseTime; }, /** - * Sets the x, y and radius of this circle. + * Resets the time, lastTime, fps averages and delta history. + * Called automatically when a browser sleeps them resumes. * - * @method Phaser.Geom.Circle#setTo + * @method Phaser.Core.TimeStep#resetDelta * @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) + resetDelta: function () { - this.x = x; - this.y = y; - this._radius = radius; - this._diameter = radius * 2; + var now = window.performance.now(); - return this; + 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; }, /** - * Sets this Circle to be empty with a radius of zero. - * Does not change its position. + * Starts the Time Step running, if it is not already doing so. + * Called automatically by the Game Boot process. * - * @method Phaser.Geom.Circle#setEmpty + * @method Phaser.Core.TimeStep#start * @since 3.0.0 * - * @return {this} This Circle object. + * @param {Phaser.Types.Core.TimeStepCallback} callback - The callback to be invoked each time the Time Step steps. */ - setEmpty: function () + start: function (callback) { - this._radius = 0; - this._diameter = 0; + if (this.started) + { + return this; + } - 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; + + var step = (this.hasFpsLimit) ? this.stepLimitFPS.bind(this) : this.step.bind(this); + + this.raf.start(step, this.forceSetTimeOut, this._target); }, /** - * Sets the position of this Circle. + * Takes the delta value and smooths it based on the previous frames. * - * @method Phaser.Geom.Circle#setPosition - * @since 3.0.0 + * Called automatically as part of the step. * - * @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. + * @method Phaser.Core.TimeStep#smoothDelta + * @since 3.60.0 * - * @return {this} This Circle object. + * @param {number} delta - The delta value for this step. + * + * @return {number} The smoothed delta value. */ - setPosition: function (x, y) + smoothDelta: function (delta) { - if (y === undefined) { y = x; } + var idx = this.deltaIndex; + var history = this.deltaHistory; + var max = this.deltaSmoothingMax; - this.x = x; - this.y = y; + if (this._coolDown > 0 || !this.inFocus) + { + this._coolDown--; - return this; + delta = Math.min(delta, this._target); + } + + if (delta > this._min) + { + // Probably super bad start time or browser tab context loss, + // so use the last 'sane' delta value + + delta = history[idx]; + + // Clamp delta to min (in case history has become corrupted somehow) + delta = Math.min(delta, this._min); + } + + // Smooth out the delta over the previous X frames + + // add the delta to the smoothing array + history[idx] = delta; + + // 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 + var 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; + + return avg; }, /** - * Checks to see if the Circle is empty: has a radius of zero. + * 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. * - * @method Phaser.Geom.Circle#isEmpty - * @since 3.0.0 + * 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. * - * @return {boolean} True if the Circle is empty, otherwise false. + * 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. + * + * Compute the new exponential moving average with an alpha of 0.25. + * + * @method Phaser.Core.TimeStep#updateFPS + * @since 3.60.0 + * + * @param {number} time - The timestamp passed in from RequestAnimationFrame or setTimeout. */ - isEmpty: function () + updateFPS: function (time) { - return (this._radius <= 0); + this.actualFps = 0.25 * this.framesThisSecond + 0.75 * this.actualFps; + this.nextFpsUpdate = time + 1000; + this.framesThisSecond = 0; }, /** - * The radius of the Circle. + * The main step method with an fps limiter. 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. * - * @name Phaser.Geom.Circle#radius - * @type {number} - * @since 3.0.0 + * @method Phaser.Core.TimeStep#stepLimitFPS + * @since 3.60.0 + * + * @param {number} time - The timestamp passed in from RequestAnimationFrame or setTimeout. */ - radius: { + stepLimitFPS: function (time) + { + this.now = time; - get: function () + // delta time (time is in ms) + // Math.max because Chrome will sometimes give negative deltas + var delta = Math.max(0, time - this.lastTime); + + this.rawDelta = delta; + + // Real-world timer advance + this.time += this.rawDelta; + + if (this.smoothStep) { - return this._radius; - }, + delta = this.smoothDelta(delta); + } - set: function (value) + // Set as the world delta value (after smoothing, if applied) + this.delta += delta; + + if (time >= this.nextFpsUpdate) { - this._radius = value; - this._diameter = value * 2; + this.updateFPS(time); } + this.framesThisSecond++; + + if (this.delta >= this._limitRate) + { + this.callback(time, this.delta); + + this.delta = 0; + } + + // Shift time value over + this.lastTime = time; + + this.frame++; }, /** - * The diameter of the Circle. + * 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. * - * @name Phaser.Geom.Circle#diameter - * @type {number} + * @method Phaser.Core.TimeStep#step * @since 3.0.0 + * + * @param {number} time - The timestamp passed in from RequestAnimationFrame or setTimeout. */ - diameter: { + step: function (time) + { + this.now = time; - get: function () + // delta time (time is in ms) + // Math.max because Chrome will sometimes give negative deltas + var delta = Math.max(0, time - this.lastTime); + + this.rawDelta = delta; + + // Real-world timer advance + this.time += this.rawDelta; + + if (this.smoothStep) { - return this._diameter; - }, + delta = this.smoothDelta(delta); + } - set: function (value) + // Set as the world delta value (after smoothing, if applied) + this.delta = delta; + + if (time >= this.nextFpsUpdate) { - this._diameter = value; - this._radius = value * 0.5; + this.updateFPS(time); } + this.framesThisSecond++; + + this.callback(time, delta); + + // Shift time value over + this.lastTime = time; + + this.frame++; }, /** - * The left position of the Circle. + * Manually calls `TimeStep.step`. * - * @name Phaser.Geom.Circle#left - * @type {number} + * @method Phaser.Core.TimeStep#tick * @since 3.0.0 */ - left: { + tick: function () + { + var now = window.performance.now(); - get: function () + if (this.hasFpsLimit) { - return this.x - this._radius; - }, - - set: function (value) + this.stepLimitFPS(now); + } + else { - this.x = value + this._radius; + this.step(now); } - }, /** - * The right position of the Circle. + * Sends the TimeStep to sleep, stopping Request Animation Frame (or SetTimeout) and toggling the `running` flag to false. * - * @name Phaser.Geom.Circle#right - * @type {number} + * @method Phaser.Core.TimeStep#sleep * @since 3.0.0 */ - right: { - - get: function () + sleep: function () + { + if (this.running) { - return this.x + this._radius; - }, + this.raf.stop(); - set: function (value) - { - this.x = value - this._radius; + this.running = false; } - }, /** - * The top position of the Circle. + * 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. * - * @name Phaser.Geom.Circle#top - * @type {number} + * @method Phaser.Core.TimeStep#wake * @since 3.0.0 + * + * @param {boolean} [seamless=false] - Adjust the startTime based on the lastTime values. */ - top: { + wake: function (seamless) + { + if (seamless === undefined) { seamless = false; } - get: function () - { - return this.y - this._radius; - }, + var now = window.performance.now(); - set: function (value) + if (this.running) { - this.y = value + this._radius; + return; } + else if (seamless) + { + this.startTime += -this.lastTime + (this.lastTime + now); + } + + var step = (this.hasFpsLimit) ? this.stepLimitFPS.bind(this) : this.step.bind(this); + this.raf.start(step, this.forceSetTimeOut, this._target); + + this.running = true; + + this.nextFpsUpdate = now + 1000; + this.framesThisSecond = 0; + this.fpsLimitTriggered = false; + + this.tick(); }, /** - * The bottom position of the Circle. + * Gets the duration which the game has been running, in seconds. * - * @name Phaser.Geom.Circle#bottom - * @type {number} + * @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. */ - bottom: { + stop: function () + { + this.running = false; + this.started = false; - get: function () - { - return this.y + this._radius; - }, + this.raf.stop(); - set: function (value) - { - this.y = value - this._radius; - } + 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.raf.destroy(); + + this.raf = null; + this.game = null; + this.callback = null; } }); -module.exports = Circle; +module.exports = TimeStep; /***/ }), -/* 66 */ -/***/ (function(module, exports) { + +/***/ 26493: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Events = __webpack_require__(97081); + /** - * Check to see if the Circle contains the given x / y coordinates. + * 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.Geom.Circle.Contains + * @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.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. + * @param {Phaser.Game} game - The Game instance this Visibility Handler is working on. */ -var Contains = function (circle, x, y) +var VisibilityHandler = function (game) { - // 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); + var hiddenVar; + var eventEmitter = game.events; - return (dx + dy) <= (circle.radius * circle.radius); + if (document.hidden !== undefined) + { + hiddenVar = 'visibilitychange'; } else { - return false; + 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 = Contains; +module.exports = VisibilityHandler; /***/ }), -/* 67 */ -/***/ (function(module, exports) { + +/***/ 41651: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 + * The Game Blur Event. * - * @param {Phaser.Geom.Line} line - The line to calculate the length of. + * This event is dispatched by the Game Visibility Handler when the window in which the Game instance is embedded + * enters a blurred state. The blur event is raised when the window loses focus. This can happen if a user swaps + * tab, or if they simply remove focus from the browser to another app. * - * @return {number} The length of the line. + * @event Phaser.Core.Events#BLUR + * @type {string} + * @since 3.0.0 */ -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; +module.exports = 'blur'; /***/ }), -/* 68 */ -/***/ (function(module, exports) { + +/***/ 5520: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 + * The Game Boot Event. * - * @param {number} value - The value to wrap. - * @param {number} min - The minimum value. - * @param {number} max - The maximum value. + * This event is dispatched when the Phaser Game instance has finished booting, but before it is ready to start running. + * The global systems use this event to know when to set themselves up, dispatching their own `ready` events as required. * - * @return {number} The wrapped value. + * @event Phaser.Core.Events#BOOT + * @type {string} + * @since 3.0.0 */ -var Wrap = function (value, min, max) -{ - var range = max - min; - - return (min + ((((value - min) % range) + range) % range)); -}; - -module.exports = Wrap; +module.exports = 'boot'; /***/ }), -/* 69 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 51673: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Vector3 = __webpack_require__(39); +/** + * The Game Context Lost Event. + * + * This event is dispatched by the Game if the WebGL Renderer it is using encounters a WebGL Context Lost event from the browser. + * + * The renderer halts all rendering and cannot resume after this happens. + * + * @event Phaser.Core.Events#CONTEXT_LOST + * @type {string} + * @since 3.19.0 + */ +module.exports = 'contextlost'; + + +/***/ }), + +/***/ 25055: +/***/ ((module) => { /** - * @ignore + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var EPSILON = 0.000001; /** - * @classdesc - * A four-dimensional matrix. + * The Game Destroy Event. * - * Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji - * and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl + * This event is dispatched when the game instance has been told to destroy itself. + * Lots of internal systems listen to this event in order to clear themselves out. + * Custom plugins and game code should also do the same. * - * @class Matrix4 - * @memberof Phaser.Math - * @constructor + * @event Phaser.Core.Events#DESTROY + * @type {string} * @since 3.0.0 - * - * @param {Phaser.Math.Matrix4} [m] - Optional Matrix4 to copy values from. */ -var Matrix4 = new Class({ +module.exports = 'destroy'; - 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); - }, +/***/ 23767: +/***/ ((module) => { - /** - * 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); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +/** + * The Game Focus Event. + * + * This event is dispatched by the Game Visibility Handler when the window in which the Game instance is embedded + * enters a focused state. The focus event is raised when the window re-gains focus, having previously lost it. + * + * @event Phaser.Core.Events#FOCUS + * @type {string} + * @since 3.0.0 + */ +module.exports = 'focus'; - 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; +/***/ 57564: +/***/ ((module) => { - 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]); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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]); - }, +/** + * The Game Hidden Event. + * + * This event is dispatched by the Game Visibility Handler when the document in which the Game instance is embedded + * enters a hidden state. Only browsers that support the Visibility API will cause this event to be emitted. + * + * In most modern browsers, when the document enters a hidden state, the Request Animation Frame and setTimeout, which + * control the main game loop, will automatically pause. There is no way to stop this from happening. It is something + * your game should account for in its own code, should the pause be an issue (i.e. for multiplayer games) + * + * @event Phaser.Core.Events#HIDDEN + * @type {string} + * @since 3.0.0 + */ +module.exports = 'hidden'; - /** - * 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; +/***/ 38327: +/***/ ((module) => { - var sx = scale.x; - var sy = scale.y; - var sz = scale.z; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this.setValues( - rm[0] * sx, - rm[1] * sx, - rm[2] * sx, - 0, +/** + * The Game Pause Event. + * + * This event is dispatched when the Game loop enters a paused state, usually as a result of the Visibility Handler. + * + * @event Phaser.Core.Events#PAUSE + * @type {string} + * @since 3.0.0 + */ +module.exports = 'pause'; - 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 - ); - }, +/***/ 43807: +/***/ ((module) => { - /** - * 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(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var out = this.val; +/** + * The Game Post-Render Event. + * + * This event is dispatched right at the end of the render process. + * + * Every Scene will have rendered and been drawn to the canvas by the time this event is fired. + * Use it for any last minute post-processing before the next game step begins. + * + * @event Phaser.Core.Events#POST_RENDER + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - A reference to the current renderer being used by the Game instance. + */ +module.exports = 'postrender'; - 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(); +/***/ 73652: +/***/ ((module) => { - var out = this.val; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - out[0] = x; - out[5] = y; - out[10] = z; - out[15] = 1; +/** + * The Game Post-Step Event. + * + * This event is dispatched after the Scene Manager has updated. + * Hook into it from plugins or systems that need to do things before the render starts. + * + * @event Phaser.Core.Events#POST_STEP + * @type {string} + * @since 3.0.0 + * + * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ +module.exports = 'poststep'; - 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; +/***/ 780: +/***/ ((module) => { - var a01 = a[1]; - var a02 = a[2]; - var a03 = a[3]; - var a12 = a[6]; - var a13 = a[7]; - var a23 = a[11]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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; +/** + * The Game Pre-Render Event. + * + * This event is dispatched immediately before any of the Scenes have started to render. + * + * The renderer will already have been initialized this frame, clearing itself and preparing to receive the Scenes for rendering, but it won't have actually drawn anything yet. + * + * @event Phaser.Core.Events#PRE_RENDER + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - A reference to the current renderer being used by the Game instance. + */ +module.exports = 'prerender'; - 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(); - }, +/***/ 13781: +/***/ ((module) => { - /** - * Invert this Matrix. - * - * @method Phaser.Math.Matrix4#invert - * @since 3.0.0 - * - * @return {this} This Matrix4. - */ - invert: function () - { - var a = this.val; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a03 = a[3]; +/** + * The Game Pre-Step Event. + * + * This event is dispatched before the main Game Step starts. By this point in the game cycle none of the Scene updates have yet happened. + * Hook into it from plugins or systems that need to update before the Scene Manager does. + * + * @event Phaser.Core.Events#PRE_STEP + * @type {string} + * @since 3.0.0 + * + * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ +module.exports = 'prestep'; - 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]; +/***/ 38247: +/***/ ((module) => { - var b00 = a00 * a11 - a01 * a10; - var b01 = a00 * a12 - a02 * a10; - var b02 = a00 * a13 - a03 * a10; - var b03 = a01 * a12 - a02 * a11; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var b04 = a01 * a13 - a03 * a11; - var b05 = a02 * a13 - a03 * a12; - var b06 = a20 * a31 - a21 * a30; - var b07 = a20 * a32 - a22 * a30; +/** + * The Game Ready Event. + * + * This event is dispatched when the Phaser Game instance has finished booting, the Texture Manager is fully ready, + * and all local systems are now able to start. + * + * @event Phaser.Core.Events#READY + * @type {string} + * @since 3.0.0 + */ +module.exports = 'ready'; - 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; - } +/***/ 29129: +/***/ ((module) => { - det = 1 / det; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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 - ); - }, +/** + * The Game Resume Event. + * + * This event is dispatched when the game loop leaves a paused state and resumes running. + * + * @event Phaser.Core.Events#RESUME + * @type {string} + * @since 3.0.0 + */ +module.exports = 'resume'; - /** - * 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]; +/***/ 34994: +/***/ ((module) => { - var a20 = a[8]; - var a21 = a[9]; - var a22 = a[10]; - var a23 = a[11]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var a30 = a[12]; - var a31 = a[13]; - var a32 = a[14]; - var a33 = a[15]; +/** + * The Game Step Event. + * + * This event is dispatched after the Game Pre-Step and before the Scene Manager steps. + * Hook into it from plugins or systems that need to update before the Scene Manager does, but after the core Systems have. + * + * @event Phaser.Core.Events#STEP + * @type {string} + * @since 3.0.0 + * + * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ +module.exports = 'step'; - 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]; +/***/ 98704: +/***/ ((module) => { - var a10 = a[4]; - var a11 = a[5]; - var a12 = a[6]; - var a13 = a[7]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var a20 = a[8]; - var a21 = a[9]; - var a22 = a[10]; - var a23 = a[11]; +/** + * The Game Visible Event. + * + * This event is dispatched by the Game Visibility Handler when the document in which the Game instance is embedded + * enters a visible state, previously having been hidden. + * + * Only browsers that support the Visibility API will cause this event to be emitted. + * + * @event Phaser.Core.Events#VISIBLE + * @type {string} + * @since 3.0.0 + */ +module.exports = 'visible'; - 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; - }, +/***/ 97081: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a03 = a[3]; +/** + * @namespace Phaser.Core.Events + */ - var a10 = a[4]; - var a11 = a[5]; - var a12 = a[6]; - var a13 = a[7]; +module.exports = { - var a20 = a[8]; - var a21 = a[9]; - var a22 = a[10]; - var a23 = a[11]; + BLUR: __webpack_require__(41651), + BOOT: __webpack_require__(5520), + CONTEXT_LOST: __webpack_require__(51673), + DESTROY: __webpack_require__(25055), + FOCUS: __webpack_require__(23767), + HIDDEN: __webpack_require__(57564), + PAUSE: __webpack_require__(38327), + POST_RENDER: __webpack_require__(43807), + POST_STEP: __webpack_require__(73652), + PRE_RENDER: __webpack_require__(780), + PRE_STEP: __webpack_require__(13781), + READY: __webpack_require__(38247), + RESUME: __webpack_require__(29129), + STEP: __webpack_require__(34994), + VISIBLE: __webpack_require__(98704) - 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; +/***/ 80293: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - b0 = b[4]; - b1 = b[5]; - b2 = b[6]; - b3 = b[7]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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; +/** + * @namespace Phaser.Core + */ - b0 = b[8]; - b1 = b[9]; - b2 = b[10]; - b3 = b[11]; +module.exports = { - 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; + Config: __webpack_require__(14033), + CreateRenderer: __webpack_require__(50150), + DebugHeader: __webpack_require__(77291), + Events: __webpack_require__(97081), + TimeStep: __webpack_require__(26617), + VisibilityHandler: __webpack_require__(26493) - 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; +/***/ 52780: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - 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], +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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], +var Arne16 = __webpack_require__(81543); +var CanvasPool = __webpack_require__(61068); +var GetValue = __webpack_require__(10850); - 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], +/** + * 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); - 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] - ); - }, + var width = Math.floor(Math.abs(data[0].length * pixelWidth)); + var height = Math.floor(Math.abs(data.length * pixelHeight)); - /** - * 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) + if (!canvas) { - return this.multiplyMatrices(m, this); - }, + canvas = CanvasPool.create2D(this, width, height); + resizeCanvas = false; + clearCanvas = false; + } - /** - * 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) + if (resizeCanvas) { - 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]; + canvas.width = width; + canvas.height = height; + } - 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]; + var ctx = canvas.getContext('2d', { willReadFrequently: true }); - 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 - ); - }, + if (clearCanvas) + { + ctx.clearRect(0, 0, width, height); + } - /** - * 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) + // preRender Callback? + if (preRender) { - return this.translateXYZ(v.x, v.y, v.z); - }, + preRender(canvas, ctx); + } - /** - * 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) + // Draw it + for (var y = 0; y < data.length; y++) { - var a = this.val; + var row = data[y]; - 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]; + for (var x = 0; x < row.length; x++) + { + var d = row[x]; - return this; - }, + if (d !== '.' && d !== ' ') + { + ctx.fillStyle = palette[d]; + ctx.fillRect(x * pixelWidth, y * pixelHeight, pixelWidth, pixelHeight); + } + } + } - /** - * 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) + // postRender Callback? + if (postRender) { - return this.scaleXYZ(v.x, v.y, v.z); - }, + postRender(canvas, ctx); + } - /** - * 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; + return canvas; +}; - a[0] = a[0] * x; - a[1] = a[1] * x; - a[2] = a[2] * x; - a[3] = a[3] * x; +module.exports = GenerateTexture; - 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; - }, +/***/ 84106: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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 +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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; +/** + * @namespace Phaser.Create + */ - 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 - ); - }, +module.exports = { - /** - * 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); + GenerateTexture: __webpack_require__(52780), + Palettes: __webpack_require__(25235) - 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]; +/***/ 81543: +/***/ ((module) => { - var a10 = a[4]; - var a11 = a[5]; - var a12 = a[6]; - var a13 = a[7]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var a20 = a[8]; - var a21 = a[9]; - var a22 = a[10]; - var a23 = a[11]; +/** + * 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' +}; - 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; +/***/ 75846: +/***/ ((module) => { - var b20 = x * z * t + y * s; - var b21 = y * z * t - x * s; - var b22 = z * z * t + c; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // 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 - ); +/** + * A 16 color palette inspired by the Commodore 64. + * + * @name Phaser.Create.Palettes.C64 + * @since 3.0.0 + * + * @type {Phaser.Types.Create.Palette} + */ +module.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' +}; + + +/***/ }), + +/***/ 83206: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * A 16 color CGA inspired palette by [Arne](http://androidarts.com/palette/16pal.htm) + * + * @name Phaser.Create.Palettes.CGA + * @since 3.0.0 + * + * @type {Phaser.Types.Create.Palette} + */ +module.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' +}; + + +/***/ }), + +/***/ 13194: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * A 16 color JMP palette by [Arne](http://androidarts.com/palette/16pal.htm) + * + * @name Phaser.Create.Palettes.JMP + * @since 3.0.0 + * + * @type {Phaser.Types.Create.Palette} + */ +module.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' +}; + + +/***/ }), + +/***/ 50686: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * A 16 color palette inspired by Japanese computers like the MSX. + * + * @name Phaser.Create.Palettes.MSX + * @since 3.0.0 + * + * @type {Phaser.Types.Create.Palette} + */ +module.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' +}; + + +/***/ }), + +/***/ 25235: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Create.Palettes + */ + +module.exports = { + + ARNE16: __webpack_require__(81543), + C64: __webpack_require__(75846), + CGA: __webpack_require__(83206), + JMP: __webpack_require__(13194), + MSX: __webpack_require__(50686) + +}; + + +/***/ }), + +/***/ 63120: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 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__(56694); +var CubicBezier = __webpack_require__(34631); +var Curve = __webpack_require__(38517); +var Vector2 = __webpack_require__(93736); + +/** + * @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; }, /** - * Rotate this matrix on its X axis. + * Gets the starting point on the curve. * - * @method Phaser.Math.Matrix4#rotateX + * @method Phaser.Curves.CubicBezier#getStartPoint * @since 3.0.0 * - * @param {number} rad - The angle in radians to rotate by. + * @generic {Phaser.Math.Vector2} O - [out,$return] * - * @return {this} This Matrix4. + * @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. */ - rotateX: function (rad) + getStartPoint: function (out) { - 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; + if (out === undefined) { out = new Vector2(); } - return this; + return out.copy(this.p0); }, /** - * Rotate this matrix on its Y axis. + * Returns the resolution of this curve. * - * @method Phaser.Math.Matrix4#rotateY + * @method Phaser.Curves.CubicBezier#getResolution * @since 3.0.0 * - * @param {number} rad - The angle to rotate by, in radians. + * @param {number} divisions - The amount of divisions used by this curve. * - * @return {this} This Matrix4. + * @return {number} The resolution of the curve. */ - rotateY: function (rad) + getResolution: function (divisions) { - 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]; + return divisions; + }, - var a20 = a[8]; - var a21 = a[9]; - var a22 = a[10]; - var a23 = a[11]; + /** + * 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(); } - // 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; + var p0 = this.p0; + var p1 = this.p1; + var p2 = this.p2; + var p3 = this.p3; - return this; + return out.set(CubicBezier(t, p0.x, p1.x, p2.x, p3.x), CubicBezier(t, p0.y, p1.y, p2.y, p3.y)); }, /** - * Rotate this matrix on its Z axis. + * Draws this curve to the specified graphics object. * - * @method Phaser.Math.Matrix4#rotateZ + * @method Phaser.Curves.CubicBezier#draw * @since 3.0.0 * - * @param {number} rad - The angle to rotate by, in radians. + * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] * - * @return {this} This Matrix4. + * @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. */ - rotateZ: function (rad) + draw: function (graphics, pointsTotal) { - var a = this.val; - var s = Math.sin(rad); - var c = Math.cos(rad); + if (pointsTotal === undefined) { pointsTotal = 32; } - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a03 = a[3]; + var points = this.getPoints(pointsTotal); - var a10 = a[4]; - var a11 = a[5]; - var a12 = a[6]; - var a13 = a[7]; + graphics.beginPath(); + graphics.moveTo(this.p0.x, this.p0.y); - // 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; + for (var i = 1; i < points.length; i++) + { + graphics.lineTo(points[i].x, points[i].y); + } - return this; + graphics.strokePath(); + + // So you can chain graphics calls + return graphics; }, /** - * Set the values of this Matrix from the given rotation Quaternion and translation Vector. + * Returns a JSON object that describes this curve. * - * @method Phaser.Math.Matrix4#fromRotationTranslation + * @method Phaser.Curves.CubicBezier#toJSON * @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. + * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. */ - fromRotationTranslation: function (q, v) + toJSON: function () { - // Quaternion math - var x = q.x; - var y = q.y; - var z = q.z; - var w = q.w; + 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 + ] + }; + } - var x2 = x + x; - var y2 = y + y; - var z2 = z + z; +}); - var xx = x * x2; - var xy = x * y2; - var xz = x * z2; +/** + * 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 yy = y * y2; - var yz = y * z2; - var zz = z * z2; + 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]); - var wx = w * x2; - var wy = w * y2; - var wz = w * z2; + return new CubicBezierCurve(p0, p1, p2, p3); +}; - return this.setValues( - 1 - (yy + zz), - xy + wz, - xz - wy, - 0, +module.exports = CubicBezierCurve; - xy - wz, - 1 - (xx + zz), - yz + wx, - 0, - xz + wy, - yz - wx, - 1 - (xx + yy), - 0, +/***/ }), - v.x, - v.y, - v.z, - 1 - ); - }, +/***/ 38517: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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) +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var FromPoints = __webpack_require__(80222); +var Rectangle = __webpack_require__(74118); +var Vector2 = __webpack_require__(93736); + +/** + * @classdesc + * A Base Curve class, which all other curve types extend. + * + * Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + * + * @class Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 + * + * @param {string} type - The curve type. + */ +var Curve = new Class({ + + initialize: + + function Curve (type) { - var x = q.x; - var y = q.y; - var z = q.z; - var w = q.w; + /** + * String based identifier for the type of curve. + * + * @name Phaser.Curves.Curve#type + * @type {string} + * @since 3.0.0 + */ + this.type = type; - var x2 = x + x; - var y2 = y + y; - var z2 = z + z; + /** + * The default number of divisions within the curve. + * + * @name Phaser.Curves.Curve#defaultDivisions + * @type {number} + * @default 5 + * @since 3.0.0 + */ + this.defaultDivisions = 5; - var xx = x * x2; - var xy = x * y2; - var xz = x * z2; + /** + * The quantity of arc length divisions within the curve. + * + * @name Phaser.Curves.Curve#arcLengthDivisions + * @type {number} + * @default 100 + * @since 3.0.0 + */ + this.arcLengthDivisions = 100; - var yy = y * y2; - var yz = y * z2; - var zz = z * z2; + /** + * An array of cached arc length values. + * + * @name Phaser.Curves.Curve#cacheArcLengths + * @type {number[]} + * @default [] + * @since 3.0.0 + */ + this.cacheArcLengths = []; - var wx = w * x2; - var wy = w * y2; - var wz = w * z2; + /** + * Does the data of this curve need updating? + * + * @name Phaser.Curves.Curve#needsUpdate + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.needsUpdate = true; - return this.setValues( - 1 - (yy + zz), - xy + wz, - xz - wy, - 0, + /** + * For a curve on a Path, `false` means the Path will ignore this curve. + * + * @name Phaser.Curves.Curve#active + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.active = true; - xy - wz, - 1 - (xx + zz), - yz + wx, - 0, + /** + * A temporary calculation Vector. + * + * @name Phaser.Curves.Curve#_tmpVec2A + * @type {Phaser.Math.Vector2} + * @private + * @since 3.0.0 + */ + this._tmpVec2A = new Vector2(); - xz + wy, - yz - wx, - 1 - (xx + yy), - 0, + /** + * A temporary calculation Vector. + * + * @name Phaser.Curves.Curve#_tmpVec2B + * @type {Phaser.Math.Vector2} + * @private + * @since 3.0.0 + */ + this._tmpVec2B = new Vector2(); + }, - 0, - 0, - 0, - 1 - ); + /** + * 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.Curve#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. + * @param {number} [pointsTotal=32] - The resolution of the curve. The higher the value the smoother it will render, at the cost of rendering performance. + * + * @return {Phaser.GameObjects.Graphics} The Graphics object to which the curve was drawn. + */ + draw: function (graphics, pointsTotal) + { + if (pointsTotal === undefined) { pointsTotal = 32; } + + // So you can chain graphics calls + return graphics.strokePoints(this.getPoints(pointsTotal)); }, /** - * Generate a frustum matrix with the given bounds. + * Returns a Rectangle where the position and dimensions match the bounds of this Curve. * - * @method Phaser.Math.Matrix4#frustum + * You can control the accuracy of the bounds. The value given is used to work out how many points + * to plot across the curve. Higher values are more accurate at the cost of calculation speed. + * + * @method Phaser.Curves.Curve#getBounds * @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. + * @param {Phaser.Geom.Rectangle} [out] - The Rectangle to store the bounds in. If falsey a new object will be created. + * @param {number} [accuracy=16] - The accuracy of the bounds calculations. * - * @return {this} This Matrix4. + * @return {Phaser.Geom.Rectangle} A Rectangle object holding the bounds of this curve. If `out` was given it will be this object. */ - frustum: function (left, right, bottom, top, near, far) + getBounds: function (out, accuracy) { - var rl = 1 / (right - left); - var tb = 1 / (top - bottom); - var nf = 1 / (near - far); + if (!out) { out = new Rectangle(); } + if (accuracy === undefined) { accuracy = 16; } - return this.setValues( - (near * 2) * rl, - 0, - 0, - 0, + var len = this.getLength(); - 0, - (near * 2) * tb, - 0, - 0, + if (accuracy > len) + { + accuracy = len / 2; + } - (right + left) * rl, - (top + bottom) * tb, - (far + near) * nf, - -1, + // The length of the curve in pixels + // So we'll have 1 spaced point per 'accuracy' pixels - 0, - 0, - (far * near * 2) * nf, - 0 - ); + var spaced = Math.max(1, Math.round(len / accuracy)); + + return FromPoints(this.getSpacedPoints(spaced), out); }, /** - * Generate a perspective projection matrix with the given bounds. + * Returns an array of points, spaced out X distance pixels apart. + * The smaller the distance, the larger the array will be. * - * @method Phaser.Math.Matrix4#perspective + * @method Phaser.Curves.Curve#getDistancePoints * @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. + * @param {number} distance - The distance, in pixels, between each point along the curve. * - * @return {this} This Matrix4. + * @return {Phaser.Geom.Point[]} An Array of Point objects. */ - perspective: function (fovy, aspect, near, far) + getDistancePoints: function (distance) { - 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, + var len = this.getLength(); - 0, - 0, - (far + near) * nf, - -1, + var spaced = Math.max(1, len / distance); - 0, - 0, - (2 * far * near) * nf, - 0 - ); + return this.getSpacedPoints(spaced); }, /** - * Generate a perspective projection matrix with the given bounds. + * Get a point at the end of the curve. * - * @method Phaser.Math.Matrix4#perspectiveLH + * @method Phaser.Curves.Curve#getEndPoint * @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. + * @param {Phaser.Math.Vector2} [out] - Optional Vector object to store the result in. * - * @return {this} This Matrix4. + * @return {Phaser.Math.Vector2} Vector2 containing the coordinates of the curves end point. */ - perspectiveLH: function (width, height, near, far) + getEndPoint: function (out) { - return this.setValues( - (2 * near) / width, - 0, - 0, - 0, + if (out === undefined) { out = new Vector2(); } - 0, - (2 * near) / height, - 0, - 0, + return this.getPointAt(1, out); + }, - 0, - 0, - -far / (near - far), - 1, + /** + * Get total curve arc length + * + * @method Phaser.Curves.Curve#getLength + * @since 3.0.0 + * + * @return {number} The total length of the curve. + */ + getLength: function () + { + var lengths = this.getLengths(); - 0, - 0, - (near * far) / (near - far), - 0 - ); + return lengths[lengths.length - 1]; }, + /** - * Generate an orthogonal projection matrix with the given bounds. + * Get a list of cumulative segment lengths. * - * @method Phaser.Math.Matrix4#ortho + * These lengths are + * + * - [0] 0 + * - [1] The first segment + * - [2] The first and second segment + * - ... + * - [divisions] All segments + * + * @method Phaser.Curves.Curve#getLengths * @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. + * @param {number} [divisions] - The number of divisions or segments. * - * @return {this} This Matrix4. + * @return {number[]} An array of cumulative lengths. */ - ortho: function (left, right, bottom, top, near, far) + getLengths: function (divisions) { - var lr = left - right; - var bt = bottom - top; - var nf = near - far; + if (divisions === undefined) { divisions = this.arcLengthDivisions; } - // Avoid division by zero - lr = (lr === 0) ? lr : 1 / lr; - bt = (bt === 0) ? bt : 1 / bt; - nf = (nf === 0) ? nf : 1 / nf; + if ((this.cacheArcLengths.length === divisions + 1) && !this.needsUpdate) + { + return this.cacheArcLengths; + } - return this.setValues( - -2 * lr, - 0, - 0, - 0, + this.needsUpdate = false; - 0, - -2 * bt, - 0, - 0, + var cache = []; + var current; + var last = this.getPoint(0, this._tmpVec2A); + var sum = 0; - 0, - 0, - 2 * nf, - 0, + cache.push(0); - (left + right) * lr, - (top + bottom) * bt, - (far + near) * nf, - 1 - ); + for (var p = 1; p <= divisions; p++) + { + current = this.getPoint(p / divisions, this._tmpVec2B); + + sum += current.distance(last); + + cache.push(sum); + + last.copy(current); + } + + this.cacheArcLengths = cache; + + return cache; // { sums: cache, sum:sum }; Sum is in the last element. }, + // Get point at relative position in curve according to arc length + + // - u [0 .. 1] + /** - * Generate a right-handed look-at matrix with the given eye position, target and up axis. + * Get a point at a relative position on the curve, by arc length. * - * @method Phaser.Math.Matrix4#lookAtRH - * @since 3.50.0 + * @method Phaser.Curves.Curve#getPointAt + * @since 3.0.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. + * @generic {Phaser.Math.Vector2} O - [out,$return] * - * @return {this} This Matrix4. + * @param {number} u - The relative position, [0..1]. + * @param {Phaser.Math.Vector2} [out] - A point to store the result in. + * + * @return {Phaser.Math.Vector2} The point. */ - lookAtRH: function (eye, target, up) + getPointAt: function (u, out) { - var m = this.val; + var t = this.getUtoTmapping(u); - _z.subVectors(eye, target); + return this.getPoint(t, out); + }, - if (_z.getLengthSquared() === 0) - { - // eye and target are in the same position - _z.z = 1; - } + // Get sequence of points using getPoint( t ) - _z.normalize(); - _x.crossVectors(up, _z); + /** + * Get a sequence of evenly spaced points from the curve. + * + * You can pass `divisions`, `stepRate`, or neither. + * + * The number of divisions will be + * + * 1. `divisions`, if `divisions` > 0; or + * 2. `this.getLength / stepRate`, if `stepRate` > 0; or + * 3. `this.defaultDivisions` + * + * `1 + divisions` points will be returned. + * + * @method Phaser.Curves.Curve#getPoints + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2[]} O - [out,$return] + * + * @param {number} [divisions] - The number of divisions to make. + * @param {number} [stepRate] - The curve distance between points, implying `divisions`. + * @param {(array|Phaser.Math.Vector2[])} [out] - An optional array to store the points in. + * + * @return {(array|Phaser.Math.Vector2[])} An array of Points from the curve. + */ + getPoints: function (divisions, stepRate, out) + { + if (out === undefined) { out = []; } - if (_x.getLengthSquared() === 0) + // If divisions is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. + if (!divisions) { - // up and z are parallel - - if (Math.abs(up.z) === 1) + if (!stepRate) { - _z.x += 0.0001; + divisions = this.defaultDivisions; } else { - _z.z += 0.0001; + divisions = this.getLength() / stepRate; } - - _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; + for (var d = 0; d <= divisions; d++) + { + out.push(this.getPoint(d / divisions)); + } - return this; + return out; }, /** - * Generate a look-at matrix with the given eye position, focal point, and up axis. + * Get a random point from the curve. * - * @method Phaser.Math.Matrix4#lookAt + * @method Phaser.Curves.Curve#getRandomPoint * @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. + * @generic {Phaser.Math.Vector2} O - [out,$return] * - * @return {this} This Matrix4. - */ - lookAt: function (eye, center, up) + * @param {Phaser.Math.Vector2} [out] - A point object to store the result in. + * + * @return {Phaser.Math.Vector2} The point. + */ + getRandomPoint: function (out) { - 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); + if (out === undefined) { out = new Vector2(); } - z0 *= len; - z1 *= len; - z2 *= len; + return this.getPoint(Math.random(), out); + }, - var x0 = upy * z2 - upz * z1; - var x1 = upz * z0 - upx * z2; - var x2 = upx * z1 - upy * z0; + // Get sequence of points using getPointAt( u ) - len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2); + /** + * Get a sequence of equally spaced points (by arc distance) from the curve. + * + * `1 + divisions` points will be returned. + * + * @method Phaser.Curves.Curve#getSpacedPoints + * @since 3.0.0 + * + * @param {number} [divisions=this.defaultDivisions] - The number of divisions to make. + * @param {number} [stepRate] - Step between points. Used to calculate the number of points to return when divisions is falsy. Ignored if divisions is positive. + * @param {(array|Phaser.Math.Vector2[])} [out] - An optional array to store the points in. + * + * @return {Phaser.Math.Vector2[]} An array of points. + */ + getSpacedPoints: function (divisions, stepRate, out) + { + if (out === undefined) { out = []; } - if (!len) - { - x0 = 0; - x1 = 0; - x2 = 0; - } - else + // If divisions is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. + if (!divisions) { - len = 1 / len; - x0 *= len; - x1 *= len; - x2 *= len; + if (!stepRate) + { + divisions = this.defaultDivisions; + } + else + { + divisions = this.getLength() / stepRate; + } } - 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 + for (var d = 0; d <= divisions; d++) { - len = 1 / len; - y0 *= len; - y1 *= len; - y2 *= len; - } - - return this.setValues( - x0, - y0, - z0, - 0, - - x1, - y1, - z1, - 0, + var t = this.getUtoTmapping(d / divisions, null, divisions); - x2, - y2, - z2, - 0, + out.push(this.getPoint(t)); + } - -(x0 * eyex + x1 * eyey + x2 * eyez), - -(y0 * eyex + y1 * eyey + y2 * eyez), - -(z0 * eyex + z1 * eyey + z2 * eyez), - 1 - ); + return out; }, /** - * Set the values of this matrix from the given `yaw`, `pitch` and `roll` values. + * Get a point at the start of the curve. * - * @method Phaser.Math.Matrix4#yawPitchRoll + * @method Phaser.Curves.Curve#getStartPoint * @since 3.0.0 * - * @param {number} yaw - The yaw value. - * @param {number} pitch - The pitch value. - * @param {number} roll - The roll value. + * @generic {Phaser.Math.Vector2} O - [out,$return] * - * @return {this} This Matrix4. + * @param {Phaser.Math.Vector2} [out] - A point to store the result in. + * + * @return {Phaser.Math.Vector2} The point. */ - yawPitchRoll: function (yaw, pitch, roll) + getStartPoint: function (out) { - 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); + if (out === undefined) { out = new Vector2(); } - return this; + return this.getPointAt(0, out); }, /** - * Generate a world matrix from the given rotation, position, scale, view matrix and projection matrix. + * Get a unit vector tangent at a relative position on the curve. + * In case any sub curve does not implement its tangent derivation, + * 2 points a small delta apart will be used to find its gradient + * which seems to give a reasonable approximation * - * @method Phaser.Math.Matrix4#setWorldMatrix + * @method Phaser.Curves.Curve#getTangent * @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. + * @generic {Phaser.Math.Vector2} O - [out,$return] * - * @return {this} This Matrix4. + * @param {number} t - The relative position on the curve, [0..1]. + * @param {Phaser.Math.Vector2} [out] - A vector to store the result in. + * + * @return {Phaser.Math.Vector2} Vector approximating the tangent line at the point t (delta +/- 0.0001) */ - setWorldMatrix: function (rotation, position, scale, viewMatrix, projectionMatrix) + getTangent: function (t, out) { - this.yawPitchRoll(rotation.y, rotation.x, rotation.z); + if (out === undefined) { out = new Vector2(); } - _tempMat1.scaling(scale.x, scale.y, scale.z); - _tempMat2.xyz(position.x, position.y, position.z); + var delta = 0.0001; + var t1 = t - delta; + var t2 = t + delta; - this.multiplyLocal(_tempMat1); - this.multiplyLocal(_tempMat2); + // Capping in case of danger - if (viewMatrix) + if (t1 < 0) { - this.multiplyLocal(viewMatrix); + t1 = 0; } - if (projectionMatrix) + if (t2 > 1) { - this.multiplyLocal(projectionMatrix); + t2 = 1; } - return this; + this.getPoint(t1, this._tmpVec2A); + this.getPoint(t2, out); + + return out.subtract(this._tmpVec2A).normalize(); }, /** - * Multiplies this Matrix4 by the given `src` Matrix4 and stores the results in the `out` Matrix4. + * Get a unit vector tangent at a relative position on the curve, by arc length. * - * @method Phaser.Math.Matrix4#multiplyToMat4 - * @since 3.50.0 + * @method Phaser.Curves.Curve#getTangentAt + * @since 3.0.0 * - * @param {Phaser.Math.Matrix4} src - The Matrix4 to multiply with this one. - * @param {Phaser.Math.Matrix4} out - The receiving Matrix. + * @generic {Phaser.Math.Vector2} O - [out,$return] * - * @return {Phaser.Math.Matrix4} This `out` Matrix4. + * @param {number} u - The relative position on the curve, [0..1]. + * @param {Phaser.Math.Vector2} [out] - A vector to store the result in. + * + * @return {Phaser.Math.Vector2} The tangent vector. */ - multiplyToMat4: function (src, out) + getTangentAt: function (u, 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, + var t = this.getUtoTmapping(u); - 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 - ); + return this.getTangent(t, out); }, /** - * Takes the rotation and position vectors and builds this Matrix4 from them. + * Given a distance in pixels, get a t to find p. * - * @method Phaser.Math.Matrix4#fromRotationXYTranslation - * @since 3.50.0 + * @method Phaser.Curves.Curve#getTFromDistance + * @since 3.0.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`) + * @param {number} distance - The distance, in pixels. + * @param {number} [divisions] - Optional amount of divisions. * - * @return {this} This Matrix4. + * @return {number} The distance. */ - fromRotationXYTranslation: function (rotation, position, translateFirst) + getTFromDistance: function (distance, divisions) { - 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) + if (distance <= 0) { - // 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 0; } - return this.setValues( - cy, - c01, - c02, - 0, - 0, - cx, - sx, - 0, - sy, - c21, - c22, - 0, - a30, - a31, - a32, - 1 - ); + return this.getUtoTmapping(0, distance, divisions); }, /** - * Returns the maximum axis scale from this Matrix4. + * Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant. * - * @method Phaser.Math.Matrix4#getMaxScaleOnAxis - * @since 3.50.0 + * @method Phaser.Curves.Curve#getUtoTmapping + * @since 3.0.0 * - * @return {number} The maximum axis scale. + * @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. */ - getMaxScaleOnAxis: function () + getUtoTmapping: function (u, distance, divisions) { - 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; - - -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Sound.Events - */ - -module.exports = { - - COMPLETE: __webpack_require__(987), - DECODED: __webpack_require__(988), - DECODED_ALL: __webpack_require__(989), - DESTROY: __webpack_require__(990), - DETUNE: __webpack_require__(991), - GLOBAL_DETUNE: __webpack_require__(992), - GLOBAL_MUTE: __webpack_require__(993), - GLOBAL_RATE: __webpack_require__(994), - GLOBAL_VOLUME: __webpack_require__(995), - LOOP: __webpack_require__(996), - LOOPED: __webpack_require__(997), - MUTE: __webpack_require__(998), - PAN: __webpack_require__(999), - PAUSE_ALL: __webpack_require__(1000), - PAUSE: __webpack_require__(1001), - PLAY: __webpack_require__(1002), - RATE: __webpack_require__(1003), - RESUME_ALL: __webpack_require__(1004), - RESUME: __webpack_require__(1005), - SEEK: __webpack_require__(1006), - STOP_ALL: __webpack_require__(1007), - STOP: __webpack_require__(1008), - UNLOCKED: __webpack_require__(1009), - VOLUME: __webpack_require__(1010) - -}; - - -/***/ }), -/* 71 */ -/***/ (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__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * A single Image File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#image method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#image. - * - * @class ImageFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.ImageFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - * @param {Phaser.Types.Loader.FileTypes.ImageFrameConfig} [frameConfig] - The frame configuration object. Only provided for, and used by, Sprite Sheets. - */ -var ImageFile = new Class({ - - Extends: File, + var arcLengths = this.getLengths(divisions); - initialize: + var i = 0; + var il = arcLengths.length; - function ImageFile (loader, key, url, xhrSettings, frameConfig) - { - var extension = 'png'; - var normalMapURL; + var targetArcLength; // The targeted u distance value to get - if (IsPlainObject(key)) + if (distance) { - var config = key; - - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - normalMapURL = GetFastValue(config, 'normalMap'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - frameConfig = GetFastValue(config, 'frameConfig'); + // Cannot overshoot the curve + targetArcLength = Math.min(distance, arcLengths[il - 1]); } - - if (Array.isArray(url)) + else { - normalMapURL = url[1]; - url = url[0]; + targetArcLength = u * arcLengths[il - 1]; } - var fileConfig = { - type: 'image', - cache: loader.textureManager, - extension: extension, - responseType: 'blob', - key: key, - url: url, - xhrSettings: xhrSettings, - config: frameConfig - }; + // binary search for the index with largest value smaller than target u distance - File.call(this, loader, fileConfig); + var low = 0; + var high = il - 1; + var comparison; - // Do we have a normal map to load as well? - if (normalMapURL) + while (low <= high) { - var normalMap = new ImageFile(loader, this.key, normalMapURL, xhrSettings, frameConfig); - - normalMap.type = 'normalMap'; + i = Math.floor(low + (high - low) / 2); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats - this.setLink(normalMap); + comparison = arcLengths[i] - targetArcLength; - loader.addFile(normalMap); + if (comparison < 0) + { + low = i + 1; + } + else if (comparison > 0) + { + high = i - 1; + } + else + { + high = i; + break; + } } - }, - /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. - * - * @method Phaser.Loader.FileTypes.ImageFile#onProcess - * @since 3.7.0 - */ - onProcess: function () - { - this.state = CONST.FILE_PROCESSING; + i = high; - this.data = new Image(); + if (arcLengths[i] === targetArcLength) + { + return i / (il - 1); + } - this.data.crossOrigin = this.crossOrigin; + // we could get finer grain at lengths, or use simple interpolation between two points - var _this = this; + var lengthBefore = arcLengths[i]; + var lengthAfter = arcLengths[i + 1]; - this.data.onload = function () - { - File.revokeObjectURL(_this.data); + var segmentLength = lengthAfter - lengthBefore; - _this.onProcessComplete(); - }; + // determine where we are between the 'before' and 'after' points - this.data.onerror = function () - { - File.revokeObjectURL(_this.data); + var segmentFraction = (targetArcLength - lengthBefore) / segmentLength; - _this.onProcessError(); - }; + // add that fractional amount to t - File.createObjectURL(this.data, this.xhrLoader.response, 'image/png'); + return (i + segmentFraction) / (il - 1); }, /** - * Adds this file to its target cache upon successful loading and processing. + * Calculate and cache the arc lengths. * - * @method Phaser.Loader.FileTypes.ImageFile#addToCache - * @since 3.7.0 + * @method Phaser.Curves.Curve#updateArcLengths + * @since 3.0.0 + * + * @see Phaser.Curves.Curve#getLengths() */ - addToCache: function () + updateArcLengths: function () { - var texture; - var linkFile = this.linkFile; - - if (linkFile && linkFile.state === CONST.FILE_COMPLETE) - { - if (this.type === 'image') - { - texture = this.cache.addImage(this.key, this.data, linkFile.data); - } - else - { - texture = this.cache.addImage(linkFile.key, linkFile.data, this.data); - } - - this.pendingDestroy(texture); - - linkFile.pendingDestroy(texture); - } - else if (!linkFile) - { - texture = this.cache.addImage(this.key, this.data); - - this.pendingDestroy(texture); - } - } - -}); + this.needsUpdate = true; -/** - * Adds an Image, or array of Images, to the current load queue. - * - * You can call this method from within your Scene's `preload`, along with any other files you wish to load: - * - * ```javascript - * function preload () - * { - * this.load.image('logo', 'images/phaserLogo.png'); - * } - * ``` - * - * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, - * or if it's already running, when the next free load slot becomes available. This happens automatically if you - * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued - * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. - * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the - * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been - * loaded. - * - * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. - * If you try to load an animated gif only the first frame will be rendered. Browsers do not natively support playback - * of animated gifs to Canvas elements. - * - * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.image({ - * key: 'logo', - * url: 'images/AtariLogo.png' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.ImageFileConfig` for more details. - * - * Once the file has finished loading you can use it as a texture for a Game Object by referencing its key: - * - * ```javascript - * this.load.image('logo', 'images/AtariLogo.png'); - * // and later in your game ... - * this.add.image(x, y, 'logo'); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, - * then you can specify it by providing an array as the `url` where the second element is the normal map: - * - * ```javascript - * this.load.image('logo', [ 'images/AtariLogo.png', 'images/AtariLogo-n.png' ]); - * ``` - * - * Or, if you are using a config object use the `normalMap` property: - * - * ```javascript - * this.load.image({ - * key: 'logo', - * url: 'images/AtariLogo.png', - * normalMap: 'images/AtariLogo-n.png' - * }); - * ``` - * - * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. - * Normal maps are a WebGL only feature. - * - * Note: The ability to load this type of file will only be available if the Image File type has been built into Phaser. - * It is available in the default build but can be excluded from custom builds. - * - * @method Phaser.Loader.LoaderPlugin#image - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.ImageFileConfig|Phaser.Types.Loader.FileTypes.ImageFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. - * - * @return {this} The Loader instance. - */ -FileTypesManager.register('image', function (key, url, xhrSettings) -{ - if (Array.isArray(key)) - { - for (var i = 0; i < key.length; i++) - { - // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new ImageFile(this, key[i])); - } - } - else - { - this.addFile(new ImageFile(this, key, url, xhrSettings)); + this.getLengths(); } - return this; }); -module.exports = ImageFile; +module.exports = Curve; /***/ }), -/* 72 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Internally used method to set the colliding state of a tile. This does not recalculate - * interesting faces. - * - * @function Phaser.Tilemaps.Components.SetTileCollision - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.Tile} tile - The Tile to set the collision on. - * @param {boolean} [collides=true] - Should the tile index collide or not? - */ -var SetTileCollision = function (tile, collides) -{ - if (collides) - { - tile.setCollision(true, true, true, true, false); - } - else - { - tile.resetCollision(false); - } -}; - -module.exports = SetTileCollision; - -/***/ }), -/* 73 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 48835: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AnimationState = __webpack_require__(164); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var GameObject = __webpack_require__(15); -var SpriteRender = __webpack_require__(1065); +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var Class = __webpack_require__(56694); +var Curve = __webpack_require__(38517); +var DegToRad = __webpack_require__(75606); +var GetValue = __webpack_require__(10850); +var RadToDeg = __webpack_require__(23701); +var Vector2 = __webpack_require__(93736); /** * @classdesc - * A Sprite Game Object. - * - * A Sprite Game Object is used for the display of both static and animated images in your game. - * Sprites can have input events and physics bodies. They can also be tweened, tinted, scrolled - * and animated. - * - * The main difference between a Sprite and an Image Game Object is that you cannot animate Images. - * As such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation - * Component. If you do not require animation then you can safely use Images to replace Sprites in all cases. + * An Elliptical Curve derived from the Base Curve class. + * + * See https://en.wikipedia.org/wiki/Elliptic_curve for more details. * - * @class Sprite - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects + * @class Ellipse + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves * @constructor * @since 3.0.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.GetBounds - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.TextureCrop - * @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. + * @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 Sprite = new Class({ - - Extends: GameObject, +var EllipseCurve = new Class({ - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.Depth, - Components.Flip, - Components.GetBounds, - Components.Mask, - Components.Origin, - Components.Pipeline, - Components.ScrollFactor, - Components.Size, - Components.TextureCrop, - Components.Tint, - Components.Transform, - Components.Visible, - SpriteRender - ], + Extends: Curve, initialize: - function Sprite (scene, x, y, texture, frame) + function EllipseCurve (x, y, xRadius, yRadius, startAngle, endAngle, clockwise, rotation) { - GameObject.call(this, scene, 'Sprite'); + 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 internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. + * The center point of the ellipse. Used for calculating rotation. * - * @name Phaser.GameObjects.Sprite#_crop - * @type {object} + * @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.11.0 + * @since 3.0.0 */ - this._crop = this.resetCropObject(); + this._xRadius = xRadius; /** - * The Animation State component of this Sprite. + * The vertical radius of the ellipse. * - * This component provides features to apply animations to this Sprite. - * It is responsible for playing, loading, queuing animations for later playback, - * mixing between animations and setting the current animation frame to this Sprite. + * @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.GameObjects.Sprite#anims - * @type {Phaser.Animations.AnimationState} + * @name Phaser.Curves.Ellipse#_startAngle + * @type {number} + * @private * @since 3.0.0 */ - this.anims = new AnimationState(this); + this._startAngle = DegToRad(startAngle); - this.setTexture(texture, frame); - this.setPosition(x, y); - this.setSizeToFrame(); - this.setOriginFromFrame(); - this.initPipeline(); - }, + /** + * The end angle of the ellipse in radians. + * + * @name Phaser.Curves.Ellipse#_endAngle + * @type {number} + * @private + * @since 3.0.0 + */ + this._endAngle = DegToRad(endAngle); - // Overrides Game Object method - addedToScene: function () - { - this.scene.sys.updateList.add(this); - }, + /** + * Anti-clockwise direction. + * + * @name Phaser.Curves.Ellipse#_clockwise + * @type {boolean} + * @private + * @since 3.0.0 + */ + this._clockwise = clockwise; - // Overrides Game Object method - removedFromScene: function () - { - this.scene.sys.updateList.remove(this); + /** + * The rotation of the arc. + * + * @name Phaser.Curves.Ellipse#_rotation + * @type {number} + * @private + * @since 3.0.0 + */ + this._rotation = DegToRad(rotation); }, /** - * Update this Sprite's animations. + * Gets the starting point on the curve. * - * @method Phaser.GameObjects.Sprite#preUpdate - * @protected + * @method Phaser.Curves.Ellipse#getStartPoint * @since 3.0.0 * - * @param {number} time - The current timestamp. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. + * @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. */ - preUpdate: function (time, delta) + getStartPoint: function (out) { - this.anims.update(time, delta); + if (out === undefined) { out = new Vector2(); } + + return this.getPoint(0, out); }, /** - * Start playing the given animation on this Sprite. - * - * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite. - * - * The benefit of a global animation is that multiple Sprites can all play the same animation, without - * having to duplicate the data. You can just create it once and then play it on any Sprite. - * - * The following code shows how to create a global repeating animation. The animation will be created - * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': - * - * ```javascript - * var config = { - * key: 'run', - * frames: 'muybridge', - * frameRate: 15, - * repeat: -1 - * }; - * - * // This code should be run from within a Scene: - * this.anims.create(config); - * ``` - * - * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone, - * you can call the `Animation.create` method instead. It accepts the exact same parameters as when - * creating a global animation, however the resulting data is kept locally in this Sprite. - * - * With the animation created, either globally or locally, you can now play it on this Sprite: - * - * ```javascript - * this.add.sprite(x, y).play('run'); - * ``` - * - * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config - * object instead: - * - * ```javascript - * this.add.sprite(x, y).play({ key: 'run', frameRate: 24 }); - * ``` - * - * When playing an animation on a Sprite it will first check to see if it can find a matching key - * locally within the Sprite. If it can, it will play the local animation. If not, it will then - * search the global Animation Manager and look for it there. - * - * If you need a Sprite to be able to play both local and global animations, make sure they don't - * have conflicting keys. - * - * See the documentation for the `PlayAnimationConfig` config object for more details about this. - * - * Also, see the documentation in the Animation Manager for further details on creating animations. + * Get the resolution of the curve. * - * @method Phaser.GameObjects.Sprite#play - * @fires Phaser.Animations.Events#ANIMATION_START + * @method Phaser.Curves.Ellipse#getResolution * @since 3.0.0 * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. + * @param {number} divisions - Optional divisions value. * - * @return {this} This Game Object. + * @return {number} The curve resolution. */ - play: function (key, ignoreIfPlaying) + getResolution: function (divisions) { - return this.anims.play(key, ignoreIfPlaying); + return divisions * 2; }, /** - * Start playing the given animation on this Sprite, in reverse. - * - * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite. + * Get point at relative position in curve according to length. * - * The benefit of a global animation is that multiple Sprites can all play the same animation, without - * having to duplicate the data. You can just create it once and then play it on any Sprite. + * @method Phaser.Curves.Ellipse#getPoint + * @since 3.0.0 * - * The following code shows how to create a global repeating animation. The animation will be created - * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': + * @generic {Phaser.Math.Vector2} O - [out,$return] * - * ```javascript - * var config = { - * key: 'run', - * frames: 'muybridge', - * frameRate: 15, - * repeat: -1 - * }; + * @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. * - * // This code should be run from within a Scene: - * this.anims.create(config); - * ``` - * - * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone, - * you can call the `Animation.create` method instead. It accepts the exact same parameters as when - * creating a global animation, however the resulting data is kept locally in this Sprite. - * - * With the animation created, either globally or locally, you can now play it on this Sprite: - * - * ```javascript - * this.add.sprite(x, y).playReverse('run'); - * ``` - * - * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config - * object instead: - * - * ```javascript - * this.add.sprite(x, y).playReverse({ key: 'run', frameRate: 24 }); - * ``` - * - * When playing an animation on a Sprite it will first check to see if it can find a matching key - * locally within the Sprite. If it can, it will play the local animation. If not, it will then - * search the global Animation Manager and look for it there. - * - * If you need a Sprite to be able to play both local and global animations, make sure they don't - * have conflicting keys. - * - * See the documentation for the `PlayAnimationConfig` config object for more details about this. - * - * Also, see the documentation in the Animation Manager for further details on creating animations. - * - * @method Phaser.GameObjects.Sprite#playReverse - * @fires Phaser.Animations.Events#ANIMATION_START - * @since 3.50.0 - * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. - * - * @return {this} This Game Object. + * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. */ - playReverse: function (key, ignoreIfPlaying) + getPoint: function (t, out) { - return this.anims.playReverse(key, ignoreIfPlaying); + 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); }, /** - * Waits for the specified delay, in milliseconds, then starts playback of the given animation. - * - * If the animation _also_ has a delay value set in its config, it will be **added** to the delay given here. - * - * If an animation is already running and a new animation is given to this method, it will wait for - * the given delay before starting the new animation. - * - * If no animation is currently running, the given one begins after the delay. - * - * When playing an animation on a Sprite it will first check to see if it can find a matching key - * locally within the Sprite. If it can, it will play the local animation. If not, it will then - * search the global Animation Manager and look for it there. - * - * Prior to Phaser 3.50 this method was called 'delayedPlay'. + * Sets the horizontal radius of this curve. * - * @method Phaser.GameObjects.Sprite#playAfterDelay - * @fires Phaser.Animations.Events#ANIMATION_START - * @since 3.50.0 + * @method Phaser.Curves.Ellipse#setXRadius + * @since 3.0.0 * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {number} delay - The delay, in milliseconds, to wait before starting the animation playing. + * @param {number} value - The horizontal radius of this curve. * - * @return {this} This Game Object. + * @return {this} This curve object. */ - playAfterDelay: function (key, delay) + setXRadius: function (value) { - return this.anims.playAfterDelay(key, delay); + this.xRadius = value; + + return this; }, /** - * Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback - * of the given animation. - * - * You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an - * idle animation to a walking animation, by making them blend smoothly into each other. - * - * If no animation is currently running, the given one will start immediately. - * - * When playing an animation on a Sprite it will first check to see if it can find a matching key - * locally within the Sprite. If it can, it will play the local animation. If not, it will then - * search the global Animation Manager and look for it there. + * Sets the vertical radius of this curve. * - * @method Phaser.GameObjects.Sprite#playAfterRepeat - * @fires Phaser.Animations.Events#ANIMATION_START - * @since 3.50.0 + * @method Phaser.Curves.Ellipse#setYRadius + * @since 3.0.0 * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {number} [repeatCount=1] - How many times should the animation repeat before the next one starts? + * @param {number} value - The vertical radius of this curve. * - * @return {this} This Game Object. + * @return {this} This curve object. */ - playAfterRepeat: function (key, repeatCount) + setYRadius: function (value) { - return this.anims.playAfterRepeat(key, repeatCount); + this.yRadius = value; + + return this; }, /** - * Sets an animation, or an array of animations, to be played immediately after the current one completes or stops. - * - * The current animation must enter a 'completed' state for this to happen, i.e. finish all of its repeats, delays, etc, - * or have the `stop` method called directly on it. - * - * An animation set to repeat forever will never enter a completed state. - * - * You can chain a new animation at any point, including before the current one starts playing, during it, - * or when it ends (via its `animationcomplete` event). - * - * Chained animations are specific to a Game Object, meaning different Game Objects can have different chained - * animations without impacting the animation they're playing. - * - * Call this method with no arguments to reset all currently chained animations. - * - * When playing an animation on a Sprite it will first check to see if it can find a matching key - * locally within the Sprite. If it can, it will play the local animation. If not, it will then - * search the global Animation Manager and look for it there. + * Sets the width of this curve. * - * @method Phaser.GameObjects.Sprite#chain - * @since 3.50.0 + * @method Phaser.Curves.Ellipse#setWidth + * @since 3.0.0 * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them. + * @param {number} value - The width of this curve. * - * @return {this} This Game Object. + * @return {this} This curve object. */ - chain: function (key) + setWidth: function (value) { - return this.anims.chain(key); + this.xRadius = value / 2; + + return this; }, /** - * Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` events. - * - * If no animation is playing, no event will be dispatched. + * Sets the height of this curve. * - * If there is another animation queued (via the `chain` method) then it will start playing immediately. + * @method Phaser.Curves.Ellipse#setHeight + * @since 3.0.0 * - * @method Phaser.GameObjects.Sprite#stop - * @fires Phaser.Animations.Events#ANIMATION_STOP - * @since 3.50.0 + * @param {number} value - The height of this curve. * - * @return {this} This Game Object. + * @return {this} This curve object. */ - stop: function () + setHeight: function (value) { - return this.anims.stop(); + this.yRadius = value / 2; + + return this; }, /** - * Stops the current animation from playing after the specified time delay, given in milliseconds. - * - * It then dispatches the `ANIMATION_STOP` event. - * - * If no animation is running, no events will be dispatched. - * - * If there is another animation in the queue (set via the `chain` method) then it will start playing, - * when the current one stops. + * Sets the start angle of this curve. * - * @method Phaser.GameObjects.Sprite#stopAfterDelay - * @fires Phaser.Animations.Events#ANIMATION_STOP - * @since 3.50.0 + * @method Phaser.Curves.Ellipse#setStartAngle + * @since 3.0.0 * - * @param {number} delay - The number of milliseconds to wait before stopping this animation. + * @param {number} value - The start angle of this curve, in radians. * - * @return {this} This Game Object. + * @return {this} This curve object. */ - stopAfterDelay: function (delay) + setStartAngle: function (value) { - return this.anims.stopAfterDelay(delay); + this.startAngle = value; + + return this; }, /** - * Stops the current animation from playing after the given number of repeats. - * - * It then dispatches the `ANIMATION_STOP` event. - * - * If no animation is running, no events will be dispatched. - * - * If there is another animation in the queue (set via the `chain` method) then it will start playing, - * when the current one stops. + * Sets the end angle of this curve. * - * @method Phaser.GameObjects.Sprite#stopAfterRepeat - * @fires Phaser.Animations.Events#ANIMATION_STOP - * @since 3.50.0 + * @method Phaser.Curves.Ellipse#setEndAngle + * @since 3.0.0 * - * @param {number} [repeatCount=1] - How many times should the animation repeat before stopping? + * @param {number} value - The end angle of this curve, in radians. * - * @return {this} This Game Object. + * @return {this} This curve object. */ - stopAfterRepeat: function (repeatCount) + setEndAngle: function (value) { - return this.anims.stopAfterRepeat(repeatCount); + this.endAngle = value; + + return this; }, /** - * Stops the current animation from playing when it next sets the given frame. - * If this frame doesn't exist within the animation it will not stop it from playing. + * Sets if this curve extends clockwise or anti-clockwise. * - * It then dispatches the `ANIMATION_STOP` event. + * @method Phaser.Curves.Ellipse#setClockwise + * @since 3.0.0 * - * If no animation is running, no events will be dispatched. + * @param {boolean} value - The clockwise state of this curve. * - * If there is another animation in the queue (set via the `chain` method) then it will start playing, - * when the current one stops. + * @return {this} This curve object. + */ + setClockwise: function (value) + { + this.clockwise = value; + + return this; + }, + + /** + * Sets the rotation of this curve. * - * @method Phaser.GameObjects.Sprite#stopOnFrame - * @fires Phaser.Animations.Events#ANIMATION_STOP - * @since 3.50.0 + * @method Phaser.Curves.Ellipse#setRotation + * @since 3.0.0 * - * @param {Phaser.Animations.AnimationFrame} frame - The frame to check before stopping this animation. + * @param {number} value - The rotation of this curve, in radians. * - * @return {this} This Game Object. + * @return {this} This curve object. */ - stopOnFrame: function (frame) + setRotation: function (value) { - return this.anims.stopOnFrame(frame); + this.rotation = value; + + return this; }, /** - * Build a JSON representation of this Sprite. + * The x coordinate of the center of the ellipse. * - * @method Phaser.GameObjects.Sprite#toJSON + * @name Phaser.Curves.Ellipse#x + * @type {number} * @since 3.0.0 - * - * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object. */ - toJSON: function () - { - return Components.ToJSON(this); + x: { + + get: function () + { + return this.p0.x; + }, + + set: function (value) + { + this.p0.x = value; + } + }, /** - * Handles the pre-destroy step for the Sprite, which removes the Animation component. + * The y coordinate of the center of the ellipse. * - * @method Phaser.GameObjects.Sprite#preDestroy - * @private - * @since 3.14.0 + * @name Phaser.Curves.Ellipse#y + * @type {number} + * @since 3.0.0 */ - preDestroy: function () - { - this.anims.destroy(); + y: { - this.anims = undefined; - } + get: function () + { + return this.p0.y; + }, -}); + set: function (value) + { + this.p0.y = value; + } -module.exports = Sprite; + }, + /** + * The horizontal radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#xRadius + * @type {number} + * @since 3.0.0 + */ + xRadius: { -/***/ }), -/* 74 */ -/***/ (function(module, exports) { + get: function () + { + return this._xRadius; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + set: function (value) + { + this._xRadius = value; + } -/** - * Removes a single item from an array and returns it without creating gc, like the native splice does. - * Based on code by Mike Reinstein. - * - * @function Phaser.Utils.Array.SpliceOne - * @since 3.0.0 - * - * @param {array} array - The array to splice from. - * @param {number} index - The index of the item which should be spliced. - * - * @return {*} The item which was spliced (removed). - */ -var SpliceOne = function (array, index) -{ - if (index >= array.length) - { - return; - } + }, - var len = array.length - 1; + /** + * The vertical radius of the ellipse. + * + * @name Phaser.Curves.Ellipse#yRadius + * @type {number} + * @since 3.0.0 + */ + yRadius: { - var item = array[index]; + get: function () + { + return this._yRadius; + }, - for (var i = index; i < len; i++) - { - array[i] = array[i + 1]; - } + set: function (value) + { + this._yRadius = value; + } - array.length = len; + }, - return item; -}; + /** + * The start angle of the ellipse in degrees. + * + * @name Phaser.Curves.Ellipse#startAngle + * @type {number} + * @since 3.0.0 + */ + startAngle: { -module.exports = SpliceOne; + get: function () + { + return RadToDeg(this._startAngle); + }, + set: function (value) + { + this._startAngle = DegToRad(value); + } -/***/ }), -/* 75 */ -/***/ (function(module, exports, __webpack_require__) { + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The end angle of the ellipse in degrees. + * + * @name Phaser.Curves.Ellipse#endAngle + * @type {number} + * @since 3.0.0 + */ + endAngle: { -/** - * @namespace Phaser.GameObjects.Events - */ + get: function () + { + return RadToDeg(this._endAngle); + }, -module.exports = { + set: function (value) + { + this._endAngle = DegToRad(value); + } - ADDED_TO_SCENE: __webpack_require__(643), - DESTROY: __webpack_require__(644), - REMOVED_FROM_SCENE: __webpack_require__(645), - VIDEO_COMPLETE: __webpack_require__(646), - VIDEO_CREATED: __webpack_require__(647), - VIDEO_ERROR: __webpack_require__(648), - VIDEO_LOOP: __webpack_require__(649), - VIDEO_PLAY: __webpack_require__(650), - VIDEO_SEEKED: __webpack_require__(651), - VIDEO_SEEKING: __webpack_require__(652), - VIDEO_STOP: __webpack_require__(653), - VIDEO_TIMEOUT: __webpack_require__(654), - VIDEO_UNLOCKED: __webpack_require__(655) + }, -}; + /** + * `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; + }, -/***/ }), -/* 76 */ -/***/ (function(module, exports) { + set: function (value) + { + this._clockwise = value; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + }, -/** - * Snap a value to nearest grid slice, using floor. - * - * Example: if you have an interval gap of `5` and a position of `12`... you will snap to `10`. - * As will `14` snap to `10`... but `16` will snap to `15`. - * - * @function Phaser.Math.Snap.Floor - * @since 3.0.0 - * - * @param {number} value - The value to snap. - * @param {number} gap - The interval gap of the grid. - * @param {number} [start=0] - Optional starting offset for gap. - * @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning. - * - * @return {number} The snapped value. - */ -var SnapFloor = function (value, gap, start, divide) -{ - if (start === undefined) { start = 0; } + /** + * The rotation of the ellipse, relative to the center, in degrees. + * + * @name Phaser.Curves.Ellipse#angle + * @type {number} + * @since 3.14.0 + */ + angle: { - if (gap === 0) - { - return value; - } + get: function () + { + return RadToDeg(this._rotation); + }, - value -= start; - value = gap * Math.floor(value / gap); + set: function (value) + { + this._rotation = DegToRad(value); + } - return (divide) ? (start + value) / gap : start + value; -}; + }, -module.exports = SnapFloor; + /** + * 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; + }, -/***/ }), -/* 77 */ -/***/ (function(module, exports) { + set: function (value) + { + this._rotation = value; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + }, + + /** + * 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) + }; + } + +}); /** - * Shallow Object Clone. Will not clone nested objects. + * Creates a curve from the provided Ellipse Curve Configuration object. * - * @function Phaser.Utils.Objects.Clone + * @function Phaser.Curves.Ellipse.fromJSON * @since 3.0.0 * - * @param {object} obj - The object to clone. + * @param {Phaser.Types.Curves.JSONEllipseCurve} data - The JSON object containing this curve data. * - * @return {object} A new object with the same properties as the input object. + * @return {Phaser.Curves.Ellipse} The ellipse curve constructed from the configuration object. */ -var Clone = function (obj) +EllipseCurve.fromJSON = function (data) { - var clone = {}; - - for (var key in obj) - { - if (Array.isArray(obj[key])) - { - clone[key] = obj[key].slice(0); - } - else - { - clone[key] = obj[key]; - } - } - - return clone; + return new EllipseCurve(data); }; -module.exports = Clone; +module.exports = EllipseCurve; /***/ }), -/* 78 */ -/***/ (function(module, exports) { + +/***/ 58084: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(56694); +var Curve = __webpack_require__(38517); +var FromPoints = __webpack_require__(80222); +var Rectangle = __webpack_require__(74118); +var Vector2 = __webpack_require__(93736); + /** - * Tests if the start and end indexes are a safe range for the given array. - * - * @function Phaser.Utils.Array.SafeRange - * @since 3.4.0 + * @classdesc + * A LineCurve is a "curve" comprising exactly two points (a line segment). * - * @param {array} array - The array to check. - * @param {number} startIndex - The start index. - * @param {number} endIndex - The end index. - * @param {boolean} [throwError=true] - Throw an error if the range is out of bounds. + * @class Line + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 * - * @return {boolean} True if the range is safe, otherwise false. + * @param {(Phaser.Math.Vector2|number[])} p0 - The first endpoint. + * @param {Phaser.Math.Vector2} [p1] - The second endpoint. */ -var SafeRange = function (array, startIndex, endIndex, throwError) -{ - var len = array.length; +var LineCurve = new Class({ - if (startIndex < 0 || - startIndex > len || - startIndex >= endIndex || - endIndex > len || - startIndex + endIndex > len) + Extends: Curve, + + initialize: + + // vec2s or array + function LineCurve (p0, p1) { - if (throwError) + Curve.call(this, 'LineCurve'); + + if (Array.isArray(p0)) { - throw new Error('Range Error: Values outside acceptable range'); + p1 = new Vector2(p0[2], p0[3]); + p0 = new Vector2(p0[0], p0[1]); } - return false; - } - else - { - return true; - } -}; + /** + * The first endpoint. + * + * @name Phaser.Curves.Line#p0 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p0 = p0; -module.exports = SafeRange; + /** + * The second endpoint. + * + * @name Phaser.Curves.Line#p1 + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.p1 = p1; + // Override default Curve.arcLengthDivisions -/***/ }), -/* 79 */ -/***/ (function(module, exports) { + /** + * 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; + }, -/** - * @author Richard Davey - * @author Angry Bytes (and contributors) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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(); } -/** - * The comparator function. - * - * @ignore - * - * @param {*} a - The first item to test. - * @param {*} b - The second itemt to test. - * - * @return {boolean} True if they localCompare, otherwise false. - */ -function Compare (a, b) -{ - return String(a).localeCompare(b); -} + return FromPoints([ this.p0, this.p1 ], out); + }, -/** - * Process the array contents. - * - * @ignore - * - * @param {array} array - The array to process. - * @param {function} compare - The comparison function. - * - * @return {array} - The processed array. - */ -function Process (array, compare) -{ - // Short-circuit when there's nothing to sort. - var len = array.length; + /** + * 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(); } - if (len <= 1) + 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) { - return array; - } + if (divisions === undefined) { divisions = 1; } - // Rather than dividing input, simply iterate chunks of 1, 2, 4, 8, etc. - // Chunks are the size of the left or right hand in merge sort. - // Stop when the left-hand covers all of the array. - var buffer = new Array(len); + return divisions; + }, - for (var chk = 1; chk < len; chk *= 2) + /** + * 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) { - RunPass(array, compare, chk, buffer); + if (out === undefined) { out = new Vector2(); } - var tmp = array; + if (t === 1) + { + return out.copy(this.p1); + } - array = buffer; + out.copy(this.p1).subtract(this.p0).scale(t).add(this.p0); - buffer = tmp; - } + return out; + }, - return array; -} + // Line curve is linear, so we can overwrite default getPointAt -/** - * Run a single pass with the given chunk size. - * - * @ignore - * - * @param {array} arr - The array to run the pass on. - * @param {function} comp - The comparison function. - * @param {number} chk - The number of iterations. - * @param {array} result - The array to store the result in. - */ -function RunPass (arr, comp, chk, result) -{ - var len = arr.length; - var i = 0; + /** + * 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); + }, - // Step size / double chunk size. - var dbl = chk * 2; + /** + * 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] + * + * @param {number} [t] - The relative position on the line, [0..1]. + * @param {Phaser.Math.Vector2} [out] - A vector to store the result in. + * + * @return {Phaser.Math.Vector2} The tangent vector. + */ + getTangent: function (t, out) + { + if (out === undefined) { out = new Vector2(); } - // Bounds of the left and right chunks. - var l, r, e; + out.copy(this.p1).subtract(this.p0).normalize(); - // Iterators over the left and right chunk. - var li, ri; + return out; + }, - // Iterate over pairs of chunks. - for (l = 0; l < len; l += dbl) + /** + * 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) { - r = l + chk; - e = r + chk; + var t; - if (r > len) + if (distance) { - r = len; - } + var arcLengths = this.getLengths(divisions); + var lineLength = arcLengths[arcLengths.length - 1]; - if (e > len) + // Cannot overshoot the curve + var targetLineLength = Math.min(distance, lineLength); + + t = targetLineLength / lineLength; + } + else { - e = len; + t = u; } - // Iterate both chunks in parallel. - li = l; - ri = r; + return t; + }, - while (true) - { - // Compare the chunks. - if (li < r && ri < e) - { - // This works for a regular `sort()` compatible comparator, - // but also for a simple comparator like: `a > b` - if (comp(arr[li], arr[ri]) <= 0) - { - result[i++] = arr[li++]; - } - else - { - result[i++] = arr[ri++]; - } - } - else if (li < r) - { - // Nothing to compare, just flush what's left. - result[i++] = arr[li++]; - } - else if (ri < e) - { - result[i++] = arr[ri++]; - } - else - { - // Both iterators are at the chunk ends. - break; - } - } + // 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 + ] + }; } -} + +}); /** - * An in-place stable array sort, because `Array#sort()` is not guaranteed stable. - * - * This is an implementation of merge sort, without recursion. - * - * Function based on the Two-Screen/stable sort 0.1.8 from https://github.com/Two-Screen/stable + * Configures this line from a JSON representation. * - * @function Phaser.Utils.Array.StableSort + * @function Phaser.Curves.Line.fromJSON * @since 3.0.0 * - * @param {array} array - The input array to be sorted. - * @param {function} [compare] - The comparison function. + * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. * - * @return {array} The sorted result. + * @return {Phaser.Curves.Line} A new LineCurve object. */ -var StableSort = function (array, compare) +LineCurve.fromJSON = function (data) { - if (compare === undefined) { compare = Compare; } - - var result = Process(array, compare); + var points = data.points; - // This simply copies back if the result isn't in the original array, which happens on an odd number of passes. - if (result !== array) - { - RunPass(result, null, array.length, array); - } + var p0 = new Vector2(points[0], points[1]); + var p1 = new Vector2(points[2], points[3]); - return array; + return new LineCurve(p0, p1); }; -module.exports = StableSort; +module.exports = LineCurve; /***/ }), -/* 80 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 64761: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var EaseMap = __webpack_require__(134); -var UppercaseFirst = __webpack_require__(205); +var Class = __webpack_require__(56694); +var Curve = __webpack_require__(38517); +var QuadraticBezierInterpolation = __webpack_require__(16252); +var Vector2 = __webpack_require__(93736); /** - * This internal function is used to return the correct ease function for a Tween. - * - * It can take a variety of input, including an EaseMap based string, or a custom function. - * - * @function Phaser.Tweens.Builders.GetEaseFunction - * @since 3.0.0 + * @classdesc + * A quadratic Bézier curve constructed from two control points. * - * @param {(string|function)} ease - The ease to find. This can be either a string from the EaseMap, or a custom function. - * @param {number[]} [easeParams] - An optional array of ease parameters to go with the ease. + * @class QuadraticBezier + * @extends Phaser.Curves.Curve + * @memberof Phaser.Curves + * @constructor + * @since 3.2.0 * - * @return {function} The ease function. + * @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 GetEaseFunction = function (ease, easeParams) -{ - // Default ease function - var easeFunction = EaseMap.Power0; +var QuadraticBezier = new Class({ - // Prepare ease function - if (typeof ease === 'string') - { - // String based look-up + Extends: Curve, - // 1) They specified it correctly - if (EaseMap.hasOwnProperty(ease)) + initialize: + + function QuadraticBezier (p0, p1, p2) + { + Curve.call(this, 'QuadraticBezierCurve'); + + if (Array.isArray(p0)) { - easeFunction = EaseMap[ease]; + p2 = new Vector2(p0[4], p0[5]); + p1 = new Vector2(p0[2], p0[3]); + p0 = new Vector2(p0[0], p0[1]); } - else + + /** + * 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++) { - // Do some string manipulation to try and find it - var direction = ''; + graphics.lineTo(points[i].x, points[i].y); + } - if (ease.indexOf('.')) - { - // quad.in = Quad.easeIn - // quad.out = Quad.easeOut - // quad.inout = Quad.easeInOut + graphics.strokePath(); - direction = ease.substr(ease.indexOf('.') + 1); + // So you can chain graphics calls + return graphics; + }, - if (direction.toLowerCase() === 'in') - { - direction = 'easeIn'; - } - else if (direction.toLowerCase() === 'out') - { - direction = 'easeOut'; - } - else if (direction.toLowerCase() === 'inout') - { - direction = 'easeInOut'; - } - } + /** + * 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 + ] + }; + } - ease = UppercaseFirst(ease.substr(0, ease.indexOf('.') + 1) + direction); +}); - if (EaseMap.hasOwnProperty(ease)) +/** + * 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; + + +/***/ }), + +/***/ 11956: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 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__(14976); +var Class = __webpack_require__(56694); +var Curve = __webpack_require__(38517); +var Vector2 = __webpack_require__(93736); + +/** + * @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') { - easeFunction = EaseMap[ease]; + 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); } - } - else if (typeof ease === 'function') + + 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) { - // Custom function - easeFunction = ease; - } - else if (Array.isArray(ease) && ease.length === 4) + 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) { - // Bezier function (TODO) - } + if (out === undefined) { out = new Vector2(); } - // No custom ease parameters? - if (!easeParams) + 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 ease function - return easeFunction; - } + return divisions * this.points.length; + }, - var cloneParams = easeParams.slice(0); + /** + * 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(); } - cloneParams.unshift(0); + var points = this.points; - // Return ease function with custom ease parameters - return function (v) + 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 () { - cloneParams[0] = v; + var points = []; - return easeFunction.apply(this, cloneParams); - }; + 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 = GetEaseFunction; +module.exports = SplineCurve; + + +/***/ }), + +/***/ 73962: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Curves + */ + +module.exports = { + Path: __webpack_require__(12822), + MoveTo: __webpack_require__(53639), + + CubicBezier: __webpack_require__(63120), + Curve: __webpack_require__(38517), + Ellipse: __webpack_require__(48835), + Line: __webpack_require__(58084), + QuadraticBezier: __webpack_require__(64761), + Spline: __webpack_require__(11956) +}; /***/ }), -/* 81 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 53639: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Utils = __webpack_require__(12); +var Class = __webpack_require__(56694); +var Vector2 = __webpack_require__(93736); /** - * Renders a stroke outline around the given Shape. + * @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. * - * @method Phaser.GameObjects.Shape#StrokePathWebGL - * @since 3.13.0 - * @private + * @class MoveTo + * @memberof Phaser.Curves + * @constructor + * @since 3.0.0 * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The WebGL Pipeline used to render this Shape. - * @param {Phaser.GameObjects.Shape} src - The Game Object shape being rendered in this call. - * @param {number} alpha - The base alpha value. - * @param {number} dx - The source displayOriginX. - * @param {number} dy - The source displayOriginY. + * @param {number} [x=0] - `x` pixel coordinate. + * @param {number} [y=0] - `y` pixel coordinate. */ -var StrokePathWebGL = function (pipeline, src, alpha, dx, dy) -{ - var strokeTint = pipeline.strokeTint; - var strokeTintColor = Utils.getTintAppendFloatAlpha(src.strokeColor, src.strokeAlpha * alpha); +var MoveTo = new Class({ - strokeTint.TL = strokeTintColor; - strokeTint.TR = strokeTintColor; - strokeTint.BL = strokeTintColor; - strokeTint.BR = strokeTintColor; + initialize: - var path = src.pathData; - var pathLength = path.length - 1; - var lineWidth = src.lineWidth; - var halfLineWidth = lineWidth / 2; + 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; - var px1 = path[0] - dx; - var py1 = path[1] - dy; + /** + * 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); + }, - if (!src.closePath) + /** + * 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) { - pathLength -= 2; - } + if (out === undefined) { out = new Vector2(); } - for (var i = 2; i < pathLength; i += 2) + 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) { - var px2 = path[i] - dx; - var py2 = path[i + 1] - dy; + return this.getPoint(u, out); + }, - pipeline.batchLine( - px1, - py1, - px2, - py2, - halfLineWidth, - halfLineWidth, - lineWidth, - i - 2, - (src.closePath) ? (i === pathLength - 1) : false - ); + /** + * 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; + }, - px1 = px2; - py1 = py2; + /** + * 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 = StrokePathWebGL; +}); + +module.exports = MoveTo; /***/ }), -/* 82 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 12822: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Contains = __webpack_require__(115); -var GetPoint = __webpack_require__(476); -var GetPoints = __webpack_require__(477); -var GEOM_CONST = __webpack_require__(56); -var Line = __webpack_require__(47); -var Random = __webpack_require__(181); +// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + +var Class = __webpack_require__(56694); +var CubicBezierCurve = __webpack_require__(63120); +var EllipseCurve = __webpack_require__(48835); +var GameObjectFactory = __webpack_require__(61286); +var LineCurve = __webpack_require__(58084); +var MovePathTo = __webpack_require__(53639); +var QuadraticBezierCurve = __webpack_require__(64761); +var Rectangle = __webpack_require__(74118); +var SplineCurve = __webpack_require__(11956); +var Vector2 = __webpack_require__(93736); +var MATH_CONST = __webpack_require__(83392); /** * @classdesc - * A triangle is a plane created by connecting three points. - * The first two arguments specify the first point, the middle two arguments - * specify the second point, and the last two arguments specify the third point. + * A Path combines multiple Curves into one continuous compound curve. + * It does not matter how many Curves are in the Path or what type they are. * - * @class Triangle - * @memberof Phaser.Geom + * A Curve in a Path does not have to start where the previous Curve ends - that is to say, a Path does not + * have to be an uninterrupted curve. Only the order of the Curves influences the actual points on the Path. + * + * @class Path + * @memberof Phaser.Curves * @constructor * @since 3.0.0 * - * @param {number} [x1=0] - `x` coordinate of the first point. - * @param {number} [y1=0] - `y` coordinate of the first point. - * @param {number} [x2=0] - `x` coordinate of the second point. - * @param {number} [y2=0] - `y` coordinate of the second point. - * @param {number} [x3=0] - `x` coordinate of the third point. - * @param {number} [y3=0] - `y` coordinate of the third point. + * @param {number} [x=0] - The X coordinate of the Path's starting point or a {@link Phaser.Types.Curves.JSONPath}. + * @param {number} [y=0] - The Y coordinate of the Path's starting point. */ -var Triangle = new Class({ +var Path = new Class({ initialize: - function Triangle (x1, y1, x2, y2, x3, y3) + function Path (x, y) { - if (x1 === undefined) { x1 = 0; } - if (y1 === undefined) { y1 = 0; } - if (x2 === undefined) { x2 = 0; } - if (y2 === undefined) { y2 = 0; } - if (x3 === undefined) { x3 = 0; } - if (y3 === undefined) { y3 = 0; } + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } /** - * The geometry constant type of this object: `GEOM_CONST.TRIANGLE`. - * Used for fast type comparisons. + * The name of this Path. + * Empty by default and never populated by Phaser, this is left for developers to use. * - * @name Phaser.Geom.Triangle#type - * @type {number} - * @readonly - * @since 3.19.0 + * @name Phaser.Curves.Path#name + * @type {string} + * @default '' + * @since 3.0.0 */ - this.type = GEOM_CONST.TRIANGLE; + this.name = ''; /** - * `x` coordinate of the first point. + * The list of Curves which make up this Path. * - * @name Phaser.Geom.Triangle#x1 - * @type {number} - * @default 0 + * @name Phaser.Curves.Path#curves + * @type {Phaser.Curves.Curve[]} + * @default [] * @since 3.0.0 */ - this.x1 = x1; + this.curves = []; /** - * `y` coordinate of the first point. + * The cached length of each Curve in the Path. * - * @name Phaser.Geom.Triangle#y1 - * @type {number} - * @default 0 + * Used internally by {@link #getCurveLengths}. + * + * @name Phaser.Curves.Path#cacheLengths + * @type {number[]} + * @default [] * @since 3.0.0 */ - this.y1 = y1; + this.cacheLengths = []; /** - * `x` coordinate of the second point. + * Automatically closes the path. * - * @name Phaser.Geom.Triangle#x2 - * @type {number} - * @default 0 + * @name Phaser.Curves.Path#autoClose + * @type {boolean} + * @default false * @since 3.0.0 */ - this.x2 = x2; + this.autoClose = false; /** - * `y` coordinate of the second point. + * The starting point of the Path. * - * @name Phaser.Geom.Triangle#y2 - * @type {number} - * @default 0 + * This is not necessarily equivalent to the starting point of the first Curve in the Path. In an empty Path, it's also treated as the ending point. + * + * @name Phaser.Curves.Path#startPoint + * @type {Phaser.Math.Vector2} * @since 3.0.0 */ - this.y2 = y2; + this.startPoint = new Vector2(); /** - * `x` coordinate of the third point. + * A temporary vector used to avoid object creation when adding a Curve to the Path. * - * @name Phaser.Geom.Triangle#x3 - * @type {number} - * @default 0 + * @name Phaser.Curves.Path#_tmpVec2A + * @type {Phaser.Math.Vector2} + * @private * @since 3.0.0 */ - this.x3 = x3; + this._tmpVec2A = new Vector2(); /** - * `y` coordinate of the third point. + * A temporary vector used to avoid object creation when adding a Curve to the Path. * - * @name Phaser.Geom.Triangle#y3 - * @type {number} - * @default 0 + * @name Phaser.Curves.Path#_tmpVec2B + * @type {Phaser.Math.Vector2} + * @private * @since 3.0.0 */ - this.y3 = y3; + this._tmpVec2B = new Vector2(); + + if (typeof x === 'object') + { + this.fromJSON(x); + } + else + { + this.startPoint.set(x, y); + } }, /** - * Checks whether a given points lies within the triangle. + * Appends a Curve to the end of the Path. * - * @method Phaser.Geom.Triangle#contains + * The Curve does not have to start where the Path ends or, for an empty Path, at its defined starting point. + * + * @method Phaser.Curves.Path#add * @since 3.0.0 * - * @param {number} x - The x coordinate of the point to check. - * @param {number} y - The y coordinate of the point to check. + * @param {Phaser.Curves.Curve} curve - The Curve to append. * - * @return {boolean} `true` if the coordinate pair is within the triangle, otherwise `false`. + * @return {this} This Path object. */ - contains: function (x, y) + add: function (curve) { - return Contains(this, x, y); + this.curves.push(curve); + + return this; }, /** - * Returns a specific point on the triangle. + * Creates a circular Ellipse Curve positioned at the end of the Path. * - * @method Phaser.Geom.Triangle#getPoint + * @method Phaser.Curves.Path#circleTo * @since 3.0.0 * - * @generic {Phaser.Geom.Point} O - [output,$return] - * - * @param {number} position - Position as float within `0` and `1`. `0` equals the first point. - * @param {(Phaser.Geom.Point|object)} [output] - Optional Point, or point-like object, that the calculated point will be written to. + * @param {number} radius - The radius of the circle. + * @param {boolean} [clockwise=false] - `true` to create a clockwise circle as opposed to a counter-clockwise circle. + * @param {number} [rotation=0] - The rotation of the circle in degrees. * - * @return {(Phaser.Geom.Point|object)} Calculated `Point` that represents the requested position. It is the same as `output` when this parameter has been given. + * @return {this} This Path object. */ - getPoint: function (position, output) + circleTo: function (radius, clockwise, rotation) { - return GetPoint(this, position, output); + if (clockwise === undefined) { clockwise = false; } + + return this.ellipseTo(radius, radius, 0, 360, clockwise, rotation); }, /** - * Calculates a list of evenly distributed points on the triangle. It is either possible to pass an amount of points to be generated (`quantity`) or the distance between two points (`stepRate`). + * Ensures that the Path is closed. * - * @method Phaser.Geom.Triangle#getPoints - * @since 3.0.0 + * A closed Path starts and ends at the same point. If the Path is not closed, a straight Line Curve will be created from the ending point directly to the starting point. During the check, the actual starting point of the Path, i.e. the starting point of the first Curve, will be used as opposed to the Path's defined {@link startPoint}, which could differ. * - * @generic {Phaser.Geom.Point[]} O - [output,$return] + * Calling this method on an empty Path will result in an error. * - * @param {number} quantity - Number of points to be generated. Can be falsey when `stepRate` should be used. All points have the same distance along the triangle. - * @param {number} [stepRate] - Distance between two points. Will only be used when `quantity` is falsey. - * @param {(array|Phaser.Geom.Point[])} [output] - Optional Array for writing the calculated points into. Otherwise a new array will be created. + * @method Phaser.Curves.Path#closePath + * @since 3.0.0 * - * @return {(array|Phaser.Geom.Point[])} Returns a list of calculated `Point` instances or the filled array passed as parameter `output`. + * @return {this} This Path object. */ - getPoints: function (quantity, stepRate, output) + closePath: function () { - return GetPoints(this, quantity, stepRate, output); + // Add a line curve if start and end of lines are not connected + var startPoint = this.curves[0].getPoint(0); + var endPoint = this.curves[this.curves.length - 1].getPoint(1); + + if (!startPoint.equals(endPoint)) + { + // This will copy a reference to the vectors, which probably isn't sensible + this.curves.push(new LineCurve(endPoint, startPoint)); + } + + return this; }, /** - * Returns a random point along the triangle. + * Creates a cubic bezier curve starting at the previous end point and ending at p3, using p1 and p2 as control points. * - * @method Phaser.Geom.Triangle#getRandomPoint + * @method Phaser.Curves.Path#cubicBezierTo * @since 3.0.0 * - * @generic {Phaser.Geom.Point} O - [point,$return] - * - * @param {Phaser.Geom.Point} [point] - Optional `Point` that should be modified. Otherwise a new one will be created. + * @param {(number|Phaser.Math.Vector2)} x - The x coordinate of the end point. Or, if a Vector2, the p1 value. + * @param {(number|Phaser.Math.Vector2)} y - The y coordinate of the end point. Or, if a Vector2, the p2 value. + * @param {(number|Phaser.Math.Vector2)} control1X - The x coordinate of the first control point. Or, if a Vector2, the p3 value. + * @param {number} [control1Y] - The y coordinate of the first control point. Not used if Vector2s are provided as the first 3 arguments. + * @param {number} [control2X] - The x coordinate of the second control point. Not used if Vector2s are provided as the first 3 arguments. + * @param {number} [control2Y] - The y coordinate of the second control point. Not used if Vector2s are provided as the first 3 arguments. * - * @return {Phaser.Geom.Point} Random `Point`. When parameter `point` has been provided it will be returned. + * @return {this} This Path object. */ - getRandomPoint: function (point) + cubicBezierTo: function (x, y, control1X, control1Y, control2X, control2Y) { - return Random(this, point); + var p0 = this.getEndPoint(); + var p1; + var p2; + var p3; + + // Assume they're all Vector2s + if (x instanceof Vector2) + { + p1 = x; + p2 = y; + p3 = control1X; + } + else + { + p1 = new Vector2(control1X, control1Y); + p2 = new Vector2(control2X, control2Y); + p3 = new Vector2(x, y); + } + + return this.add(new CubicBezierCurve(p0, p1, p2, p3)); }, + // Creates a quadratic bezier curve starting at the previous end point and ending at p2, using p1 as a control point + /** - * Sets all three points of the triangle. Leaving out any coordinate sets it to be `0`. + * Creates a Quadratic Bezier Curve starting at the ending point of the Path. * - * @method Phaser.Geom.Triangle#setTo - * @since 3.0.0 + * @method Phaser.Curves.Path#quadraticBezierTo + * @since 3.2.0 * - * @param {number} [x1=0] - `x` coordinate of the first point. - * @param {number} [y1=0] - `y` coordinate of the first point. - * @param {number} [x2=0] - `x` coordinate of the second point. - * @param {number} [y2=0] - `y` coordinate of the second point. - * @param {number} [x3=0] - `x` coordinate of the third point. - * @param {number} [y3=0] - `y` coordinate of the third point. + * @param {(number|Phaser.Math.Vector2[])} x - The X coordinate of the second control point or, if it's a `Vector2`, the first control point. + * @param {number} [y] - The Y coordinate of the second control point or, if `x` is a `Vector2`, the second control point. + * @param {number} [controlX] - If `x` is not a `Vector2`, the X coordinate of the first control point. + * @param {number} [controlY] - If `x` is not a `Vector2`, the Y coordinate of the first control point. * - * @return {this} This Triangle object. + * @return {this} This Path object. */ - setTo: function (x1, y1, x2, y2, x3, y3) + quadraticBezierTo: function (x, y, controlX, controlY) { - if (x1 === undefined) { x1 = 0; } - if (y1 === undefined) { y1 = 0; } - if (x2 === undefined) { x2 = 0; } - if (y2 === undefined) { y2 = 0; } - if (x3 === undefined) { x3 = 0; } - if (y3 === undefined) { y3 = 0; } - - this.x1 = x1; - this.y1 = y1; - - this.x2 = x2; - this.y2 = y2; + var p0 = this.getEndPoint(); + var p1; + var p2; - this.x3 = x3; - this.y3 = y3; + // Assume they're all Vector2s + if (x instanceof Vector2) + { + p1 = x; + p2 = y; + } + else + { + p1 = new Vector2(controlX, controlY); + p2 = new Vector2(x, y); + } - return this; + return this.add(new QuadraticBezierCurve(p0, p1, p2)); }, /** - * Returns a Line object that corresponds to Line A of this Triangle. + * Draws all Curves in the Path to a Graphics Game Object. * - * @method Phaser.Geom.Triangle#getLineA + * @method Phaser.Curves.Path#draw * @since 3.0.0 * - * @generic {Phaser.Geom.Line} O - [line,$return] + * @generic {Phaser.GameObjects.Graphics} G - [out,$return] * - * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics Game Object to draw to. + * @param {number} [pointsTotal=32] - The number of points to draw for each Curve. Higher numbers result in a smoother curve but require more processing. * - * @return {Phaser.Geom.Line} A Line object that corresponds to line A of this Triangle. + * @return {Phaser.GameObjects.Graphics} The Graphics object which was drawn to. */ - getLineA: function (line) + draw: function (graphics, pointsTotal) { - if (line === undefined) { line = new Line(); } + for (var i = 0; i < this.curves.length; i++) + { + var curve = this.curves[i]; - line.setTo(this.x1, this.y1, this.x2, this.y2); + if (!curve.active) + { + continue; + } - return line; + curve.draw(graphics, pointsTotal); + } + + return graphics; }, /** - * Returns a Line object that corresponds to Line B of this Triangle. + * Creates an ellipse curve positioned at the previous end point, using the given parameters. * - * @method Phaser.Geom.Triangle#getLineB + * @method Phaser.Curves.Path#ellipseTo * @since 3.0.0 * - * @generic {Phaser.Geom.Line} O - [line,$return] - * - * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. + * @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. * - * @return {Phaser.Geom.Line} A Line object that corresponds to line B of this Triangle. + * @return {this} This Path object. */ - getLineB: function (line) + ellipseTo: function (xRadius, yRadius, startAngle, endAngle, clockwise, rotation) { - if (line === undefined) { line = new Line(); } + var ellipse = new EllipseCurve(0, 0, xRadius, yRadius, startAngle, endAngle, clockwise, rotation); - line.setTo(this.x2, this.y2, this.x3, this.y3); + var end = this.getEndPoint(this._tmpVec2A); - return line; + // Calculate where to center the ellipse + var start = ellipse.getStartPoint(this._tmpVec2B); + + end.subtract(start); + + ellipse.x = end.x; + ellipse.y = end.y; + + return this.add(ellipse); }, /** - * Returns a Line object that corresponds to Line C of this Triangle. + * Creates a Path from a Path Configuration object. * - * @method Phaser.Geom.Triangle#getLineC - * @since 3.0.0 + * The provided object should be a {@link Phaser.Types.Curves.JSONPath}, as returned by {@link #toJSON}. Providing a malformed object may cause errors. * - * @generic {Phaser.Geom.Line} O - [line,$return] + * @method Phaser.Curves.Path#fromJSON + * @since 3.0.0 * - * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. + * @param {Phaser.Types.Curves.JSONPath} data - The JSON object containing the Path data. * - * @return {Phaser.Geom.Line} A Line object that corresponds to line C of this Triangle. + * @return {this} This Path object. */ - getLineC: function (line) + fromJSON: function (data) { - if (line === undefined) { line = new Line(); } - - line.setTo(this.x3, this.y3, this.x1, this.y1); + // data should be an object matching the Path.toJSON object structure. - return line; - }, + this.curves = []; + this.cacheLengths = []; - /** - * Left most X coordinate of the triangle. Setting it moves the triangle on the X axis accordingly. - * - * @name Phaser.Geom.Triangle#left - * @type {number} - * @since 3.0.0 - */ - left: { + this.startPoint.set(data.x, data.y); - get: function () - { - return Math.min(this.x1, this.x2, this.x3); - }, + this.autoClose = data.autoClose; - set: function (value) + for (var i = 0; i < data.curves.length; i++) { - var diff = 0; + var curve = data.curves[i]; - if (this.x1 <= this.x2 && this.x1 <= this.x3) - { - diff = this.x1 - value; - } - else if (this.x2 <= this.x1 && this.x2 <= this.x3) - { - diff = this.x2 - value; - } - else + switch (curve.type) { - diff = this.x3 - value; - } + case 'LineCurve': + this.add(LineCurve.fromJSON(curve)); + break; - this.x1 -= diff; - this.x2 -= diff; - this.x3 -= diff; + case 'EllipseCurve': + this.add(EllipseCurve.fromJSON(curve)); + break; + + case 'SplineCurve': + this.add(SplineCurve.fromJSON(curve)); + break; + + case 'CubicBezierCurve': + this.add(CubicBezierCurve.fromJSON(curve)); + break; + + case 'QuadraticBezierCurve': + this.add(QuadraticBezierCurve.fromJSON(curve)); + break; + } } + return this; }, /** - * Right most X coordinate of the triangle. Setting it moves the triangle on the X axis accordingly. + * Returns a Rectangle with a position and size matching the bounds of this Path. * - * @name Phaser.Geom.Triangle#right - * @type {number} + * @method Phaser.Curves.Path#getBounds * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} [out] - The Rectangle to store the bounds in. + * @param {number} [accuracy=16] - The accuracy of the bounds calculations. Higher values are more accurate at the cost of calculation speed. + * + * @return {Phaser.Geom.Rectangle} The modified `out` Rectangle, or a new Rectangle if none was provided. */ - right: { + getBounds: function (out, accuracy) + { + if (out === undefined) { out = new Rectangle(); } + if (accuracy === undefined) { accuracy = 16; } - get: function () - { - return Math.max(this.x1, this.x2, this.x3); - }, + out.x = Number.MAX_VALUE; + out.y = Number.MAX_VALUE; - set: function (value) + var bounds = new Rectangle(); + var maxRight = MATH_CONST.MIN_SAFE_INTEGER; + var maxBottom = MATH_CONST.MIN_SAFE_INTEGER; + + for (var i = 0; i < this.curves.length; i++) { - var diff = 0; + var curve = this.curves[i]; - if (this.x1 >= this.x2 && this.x1 >= this.x3) - { - diff = this.x1 - value; - } - else if (this.x2 >= this.x1 && this.x2 >= this.x3) - { - diff = this.x2 - value; - } - else + if (!curve.active) { - diff = this.x3 - value; + continue; } - this.x1 -= diff; - this.x2 -= diff; - this.x3 -= diff; + curve.getBounds(bounds, accuracy); + + out.x = Math.min(out.x, bounds.x); + out.y = Math.min(out.y, bounds.y); + + maxRight = Math.max(maxRight, bounds.right); + maxBottom = Math.max(maxBottom, bounds.bottom); } + out.right = maxRight; + out.bottom = maxBottom; + + return out; }, /** - * Top most Y coordinate of the triangle. Setting it moves the triangle on the Y axis accordingly. + * Returns an array containing the length of the Path at the end of each Curve. * - * @name Phaser.Geom.Triangle#top - * @type {number} + * The result of this method will be cached to avoid recalculating it in subsequent calls. The cache is only invalidated when the {@link #curves} array changes in length, leading to potential inaccuracies if a Curve in the Path is changed, or if a Curve is removed and another is added in its place. + * + * @method Phaser.Curves.Path#getCurveLengths * @since 3.0.0 + * + * @return {number[]} An array containing the length of the Path at the end of each one of its Curves. */ - top: { + getCurveLengths: function () + { + // We use cache values if curves and cache array are same length - get: function () + if (this.cacheLengths.length === this.curves.length) { - return Math.min(this.y1, this.y2, this.y3); - }, + return this.cacheLengths; + } - set: function (value) + // Get length of sub-curve + // Push sums into cached array + + var lengths = []; + var sums = 0; + + for (var i = 0; i < this.curves.length; i++) { - var diff = 0; + sums += this.curves[i].getLength(); - if (this.y1 <= this.y2 && this.y1 <= this.y3) - { - diff = this.y1 - value; - } - else if (this.y2 <= this.y1 && this.y2 <= this.y3) - { - diff = this.y2 - value; - } - else + lengths.push(sums); + } + + this.cacheLengths = lengths; + + return lengths; + }, + + /** + * Returns the Curve that forms the Path at the given normalized location (between 0 and 1). + * + * @method Phaser.Curves.Path#getCurveAt + * @since 3.60.0 + * + * @param {number} t - The normalized location on the Path, between 0 and 1. + * + * @return {?Phaser.Curves.Curve} The Curve that is part of this Path at a given location, or `null` if no curve was found. + */ + getCurveAt: function (t) + { + var d = t * this.getLength(); + var curveLengths = this.getCurveLengths(); + var i = 0; + + while (i < curveLengths.length) + { + if (curveLengths[i] >= d) { - diff = this.y3 - value; + return this.curves[i]; } - this.y1 -= diff; - this.y2 -= diff; - this.y3 -= diff; + i++; } + return null; }, /** - * Bottom most Y coordinate of the triangle. Setting it moves the triangle on the Y axis accordingly. + * Returns the ending point of the Path. * - * @name Phaser.Geom.Triangle#bottom - * @type {number} + * A Path's ending point is equivalent to the ending point of the last Curve in the Path. For an empty Path, the ending point is at the Path's defined {@link #startPoint}. + * + * @method Phaser.Curves.Path#getEndPoint * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - The object to store the point in. + * + * @return {Phaser.Math.Vector2} The modified `out` object, or a new Vector2 if none was provided. */ - bottom: { + getEndPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } - get: function () + if (this.curves.length > 0) { - return Math.max(this.y1, this.y2, this.y3); - }, - - set: function (value) + this.curves[this.curves.length - 1].getPoint(1, out); + } + else { - var diff = 0; + out.copy(this.startPoint); + } - if (this.y1 >= this.y2 && this.y1 >= this.y3) - { - diff = this.y1 - value; - } - else if (this.y2 >= this.y1 && this.y2 >= this.y3) - { - diff = this.y2 - value; - } - else - { - diff = this.y3 - value; - } + return out; + }, - this.y1 -= diff; - this.y2 -= diff; - this.y3 -= diff; - } + /** + * Returns the total length of the Path. + * + * @see {@link #getCurveLengths} + * + * @method Phaser.Curves.Path#getLength + * @since 3.0.0 + * + * @return {number} The total length of the Path. + */ + getLength: function () + { + var lens = this.getCurveLengths(); - } + return lens[lens.length - 1]; + }, -}); + // To get accurate point with reference to + // entire path distance at time t, + // following has to be done: -module.exports = Triangle; + // 1. Length of each sub path have to be known + // 2. Locate and identify type of curve + // 3. Get t for the curve + // 4. Return curve.getPointAt(t') + /** + * Calculates the coordinates of the point at the given normalized location (between 0 and 1) on the Path. + * + * The location is relative to the entire Path, not to an individual Curve. A location of 0.5 is always in the middle of the Path and is thus an equal distance away from both its starting and ending points. In a Path with one Curve, it would be in the middle of the Curve; in a Path with two Curves, it could be anywhere on either one of them depending on their lengths. + * + * @method Phaser.Curves.Path#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The location of the point to return, between 0 and 1. + * @param {Phaser.Math.Vector2} [out] - The object in which to store the calculated point. + * + * @return {?Phaser.Math.Vector2} The modified `out` object, or a new `Vector2` if none was provided. + */ + getPoint: function (t, out) + { + if (out === undefined) { out = new Vector2(); } -/***/ }), -/* 83 */ -/***/ (function(module, exports) { + var d = t * this.getLength(); + var curveLengths = this.getCurveLengths(); + var i = 0; -/** -* The `Matter.Vector` module contains methods for creating and manipulating vectors. -* Vectors are the basis of all the geometry related operations in the engine. -* A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`. -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Vector -*/ + while (i < curveLengths.length) + { + if (curveLengths[i] >= d) + { + var diff = curveLengths[i] - d; + var curve = this.curves[i]; -// TODO: consider params for reusing vector objects + var segmentLength = curve.getLength(); + var u = (segmentLength === 0) ? 0 : 1 - diff / segmentLength; -var Vector = {}; + return curve.getPointAt(u, out); + } -module.exports = Vector; + i++; + } -(function() { + // loop where sum != 0, sum > d , sum+1 1 && !points[points.length - 1].equals(points[0])) + { + points.push(points[0]); + } - /** - * Subtracts the two vectors. - * @method sub - * @param {vector} vectorA - * @param {vector} vectorB - * @param {vector} [output] - * @return {vector} A new vector of vectorA and vectorB subtracted - */ - Vector.sub = function(vectorA, vectorB, output) { - if (!output) output = {}; - output.x = vectorA.x - vectorB.x; - output.y = vectorA.y - vectorB.y; - return output; - }; + return points; + }, /** - * Multiplies a vector and a scalar. - * @method mult - * @param {vector} vector - * @param {number} scalar - * @return {vector} A new vector multiplied by scalar + * Returns a randomly chosen point anywhere on the path. This follows the same rules as `getPoint` in that it may return a point on any Curve inside this path. + * + * When calling this method multiple times, the points are not guaranteed to be equally spaced spatially. + * + * @method Phaser.Curves.Path#getRandomPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - `Vector2` instance that should be used for storing the result. If `undefined` a new `Vector2` will be created. + * + * @return {Phaser.Math.Vector2} The modified `out` object, or a new `Vector2` if none was provided. */ - Vector.mult = function(vector, scalar) { - return { x: vector.x * scalar, y: vector.y * scalar }; - }; + getRandomPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } - /** - * Divides a vector and a scalar. - * @method div - * @param {vector} vector - * @param {number} scalar - * @return {vector} A new vector divided by scalar - */ - Vector.div = function(vector, scalar) { - return { x: vector.x / scalar, y: vector.y / scalar }; - }; + return this.getPoint(Math.random(), out); + }, /** - * Returns the perpendicular vector. Set `negate` to true for the perpendicular in the opposite direction. - * @method perp - * @param {vector} vector - * @param {bool} [negate=false] - * @return {vector} The perpendicular vector + * Divides this Path into a set of equally spaced points, + * + * The resulting points are equally spaced with respect to the points' position on the path, but not necessarily equally spaced spatially. + * + * @method Phaser.Curves.Path#getSpacedPoints + * @since 3.0.0 + * + * @param {number} [divisions=40] - The amount of points to divide this Path into. + * + * @return {Phaser.Math.Vector2[]} A list of the points this path was subdivided into. */ - Vector.perp = function(vector, negate) { - negate = negate === true ? -1 : 1; - return { x: negate * -vector.y, y: negate * vector.x }; - }; + getSpacedPoints: function (divisions) + { + if (divisions === undefined) { divisions = 40; } - /** - * Negates both components of a vector such that it points in the opposite direction. - * @method neg - * @param {vector} vector - * @return {vector} The negated vector - */ - Vector.neg = function(vector) { - return { x: -vector.x, y: -vector.y }; - }; + var points = []; + + for (var i = 0; i <= divisions; i++) + { + points.push(this.getPoint(i / divisions)); + } + + if (this.autoClose) + { + points.push(points[0]); + } + + return points; + }, /** - * Returns the angle between the vector `vectorB - vectorA` and the x-axis in radians. - * @method angle - * @param {vector} vectorA - * @param {vector} vectorB - * @return {number} The angle in radians + * Returns the starting point of the Path. + * + * @method Phaser.Curves.Path#getStartPoint + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Math.Vector2} [out] - `Vector2` instance that should be used for storing the result. If `undefined` a new `Vector2` will be created. + * + * @return {Phaser.Math.Vector2} The modified `out` object, or a new Vector2 if none was provided. */ - Vector.angle = function(vectorA, vectorB) { - return Math.atan2(vectorB.y - vectorA.y, vectorB.x - vectorA.x); - }; + getStartPoint: function (out) + { + if (out === undefined) { out = new Vector2(); } + + return out.copy(this.startPoint); + }, /** - * Temporary vector pool (not thread-safe). - * @property _temp - * @type {vector[]} - * @private + * Gets a unit vector tangent at a relative position on the path. + * + * @method Phaser.Curves.Path#getTangent + * @since 3.23.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {number} t - The relative position on the path, [0..1]. + * @param {Phaser.Math.Vector2} [out] - A vector to store the result in. + * + * @return {Phaser.Math.Vector2} Vector approximating the tangent line at the point t (delta +/- 0.0001) */ - Vector._temp = [ - Vector.create(), Vector.create(), - Vector.create(), Vector.create(), - Vector.create(), Vector.create() - ]; + getTangent: function (t, out) + { + if (out === undefined) { out = new Vector2(); } -})(); + var d = t * this.getLength(); + var curveLengths = this.getCurveLengths(); + var i = 0; -/***/ }), -/* 84 */ -/***/ (function(module, exports) { + while (i < curveLengths.length) + { + if (curveLengths[i] >= d) + { + var diff = curveLengths[i] - d; + var curve = this.curves[i]; -/** -* The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB). -* -* @class Bounds -*/ + var segmentLength = curve.getLength(); + var u = (segmentLength === 0) ? 0 : 1 - diff / segmentLength; -var Bounds = {}; + return curve.getTangentAt(u, out); + } -module.exports = Bounds; + i++; + } -(function() { + return null; + }, /** - * Creates a new axis-aligned bounding box (AABB) for the given vertices. - * @method create - * @param {vertices} vertices - * @return {bounds} A new bounds object + * Creates a line curve from the previous end point to x/y. + * + * @method Phaser.Curves.Path#lineTo + * @since 3.0.0 + * + * @param {(number|Phaser.Math.Vector2)} x - The X coordinate of the line's end point, or a `Vector2` containing the entire end point. + * @param {number} [y] - The Y coordinate of the line's end point, if a number was passed as the X parameter. + * + * @return {this} This Path object. */ - Bounds.create = function(vertices) { - var bounds = { - min: { x: 0, y: 0 }, - max: { x: 0, y: 0 } - }; + lineTo: function (x, y) + { + if (x instanceof Vector2) + { + this._tmpVec2B.copy(x); + } + else + { + this._tmpVec2B.set(x, y); + } - if (vertices) - Bounds.update(bounds, vertices); - - return bounds; - }; + var end = this.getEndPoint(this._tmpVec2A); + + return this.add(new LineCurve([ end.x, end.y, this._tmpVec2B.x, this._tmpVec2B.y ])); + }, /** - * Updates bounds using the given vertices and extends the bounds given a velocity. - * @method update - * @param {bounds} bounds - * @param {vertices} vertices - * @param {vector} velocity + * Creates a spline curve starting at the previous end point, using the given points on the curve. + * + * @method Phaser.Curves.Path#splineTo + * @since 3.0.0 + * + * @param {Phaser.Math.Vector2[]} points - The points the newly created spline curve should consist of. + * + * @return {this} This Path object. */ - Bounds.update = function(bounds, vertices, velocity) { - bounds.min.x = Infinity; - bounds.max.x = -Infinity; - bounds.min.y = Infinity; - bounds.max.y = -Infinity; + splineTo: function (points) + { + points.unshift(this.getEndPoint()); - for (var i = 0; i < vertices.length; i++) { - var vertex = vertices[i]; - if (vertex.x > bounds.max.x) bounds.max.x = vertex.x; - if (vertex.x < bounds.min.x) bounds.min.x = vertex.x; - if (vertex.y > bounds.max.y) bounds.max.y = vertex.y; - if (vertex.y < bounds.min.y) bounds.min.y = vertex.y; - } - - if (velocity) { - if (velocity.x > 0) { - bounds.max.x += velocity.x; - } else { - bounds.min.x += velocity.x; - } - - if (velocity.y > 0) { - bounds.max.y += velocity.y; - } else { - bounds.min.y += velocity.y; - } - } - }; + return this.add(new SplineCurve(points)); + }, /** - * Returns true if the bounds contains the given point. - * @method contains - * @param {bounds} bounds - * @param {vector} point - * @return {boolean} True if the bounds contain the point, otherwise false + * Creates a "gap" in this path from the path's current end point to the given coordinates. + * + * After calling this function, this Path's end point will be equal to the given coordinates + * + * @method Phaser.Curves.Path#moveTo + * @since 3.0.0 + * + * @param {(number|Phaser.Math.Vector2)} x - The X coordinate of the position to move the path's end point to, or a `Vector2` containing the entire new end point. + * @param {number} [y] - The Y coordinate of the position to move the path's end point to, if a number was passed as the X coordinate. + * + * @return {this} This Path object. */ - Bounds.contains = function(bounds, point) { - return point.x >= bounds.min.x && point.x <= bounds.max.x - && point.y >= bounds.min.y && point.y <= bounds.max.y; - }; + moveTo: function (x, y) + { + if (x instanceof Vector2) + { + return this.add(new MovePathTo(x.x, x.y)); + } + else + { + return this.add(new MovePathTo(x, y)); + } + }, /** - * Returns true if the two bounds intersect. - * @method overlaps - * @param {bounds} boundsA - * @param {bounds} boundsB - * @return {boolean} True if the bounds overlap, otherwise false + * Converts this Path to a JSON object containing the path information and its constituent curves. + * + * @method Phaser.Curves.Path#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.Curves.JSONPath} The JSON object containing this path's data. */ - Bounds.overlaps = function(boundsA, boundsB) { - return (boundsA.min.x <= boundsB.max.x && boundsA.max.x >= boundsB.min.x - && boundsA.max.y >= boundsB.min.y && boundsA.min.y <= boundsB.max.y); - }; + toJSON: function () + { + var out = []; + + for (var i = 0; i < this.curves.length; i++) + { + out.push(this.curves[i].toJSON()); + } + + return { + type: 'Path', + x: this.startPoint.x, + y: this.startPoint.y, + autoClose: this.autoClose, + curves: out + }; + }, /** - * Translates the bounds by the given vector. - * @method translate - * @param {bounds} bounds - * @param {vector} vector + * cacheLengths must be recalculated. + * + * @method Phaser.Curves.Path#updateArcLengths + * @since 3.0.0 */ - Bounds.translate = function(bounds, vector) { - bounds.min.x += vector.x; - bounds.max.x += vector.x; - bounds.min.y += vector.y; - bounds.max.y += vector.y; - }; + updateArcLengths: function () + { + this.cacheLengths = []; + + this.getCurveLengths(); + }, /** - * Shifts the bounds to the given position. - * @method shift - * @param {bounds} bounds - * @param {vector} position + * Disposes of this Path, clearing its internal references to objects so they can be garbage-collected. + * + * @method Phaser.Curves.Path#destroy + * @since 3.0.0 */ - Bounds.shift = function(bounds, position) { - var deltaX = bounds.max.x - bounds.min.x, - deltaY = bounds.max.y - bounds.min.y; - - bounds.min.x = position.x; - bounds.max.x = position.x + deltaX; - bounds.min.y = position.y; - bounds.max.y = position.y + deltaY; - }; - -})(); + destroy: function () + { + this.curves.length = 0; + this.cacheLengths.length = 0; + this.startPoint = undefined; + } + +}); + +/** + * Creates a new Path Object. + * + * @method Phaser.GameObjects.GameObjectFactory#path + * @since 3.0.0 + * + * @param {number} x - The horizontal position of this Path. + * @param {number} y - The vertical position of this Path. + * + * @return {Phaser.Curves.Path} The Path Object that was created. + */ +GameObjectFactory.register('path', function (x, y) +{ + return new Path(x, y); +}); + +// When registering a factory function 'this' refers to the GameObjectFactory 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 + +module.exports = Path; /***/ }), -/* 85 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 81078: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(29); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var Rectangle = __webpack_require__(502); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(35026); + +/** + * @callback DataEachCallback + * + * @param {*} parent - The parent object of the DataManager. + * @param {string} key - The key of the value. + * @param {*} value - The value. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data. + */ /** * @classdesc - * A Tile is a representation of a single tile within the Tilemap. This is a lightweight data - * representation, so its position information is stored without factoring in scroll, layer - * scale or layer position. + * The Data Manager Component features a means to store pieces of data specific to a Game Object, System or Plugin. + * You can then search, query it, and retrieve the data. The parent must either extend EventEmitter, + * or have a property called `events` that is an instance of it. * - * @class Tile - * @memberof Phaser.Tilemaps + * @class DataManager + * @memberof Phaser.Data * @constructor * @since 3.0.0 * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.Visible - * - * @param {Phaser.Tilemaps.LayerData} layer - The LayerData object in the Tilemap that this tile belongs to. - * @param {number} index - The unique index of this tile within the map. - * @param {number} x - The x coordinate of this tile in tile coordinates. - * @param {number} y - The y coordinate of this tile in tile coordinates. - * @param {number} width - Width of the tile in pixels. - * @param {number} height - Height of the tile in pixels. - * @param {number} baseWidth - The base width a tile in the map (in pixels). Tiled maps support - * multiple tileset sizes within one map, but they are still placed at intervals of the base - * tile width. - * @param {number} baseHeight - The base height of the tile in pixels (in pixels). Tiled maps - * support multiple tileset sizes within one map, but they are still placed at intervals of the - * base tile height. + * @param {object} parent - The object that this DataManager belongs to. + * @param {Phaser.Events.EventEmitter} [eventEmitter] - The DataManager's event emitter. */ -var Tile = new Class({ - - Mixins: [ - Components.Alpha, - Components.Flip, - Components.Visible - ], +var DataManager = new Class({ initialize: - function Tile (layer, index, x, y, width, height, baseWidth, baseHeight) + function DataManager (parent, eventEmitter) { /** - * The LayerData in the Tilemap data that this tile belongs to. - * - * @name Phaser.Tilemaps.Tile#layer - * @type {Phaser.Tilemaps.LayerData} - * @since 3.0.0 - */ - this.layer = layer; - - /** - * The index of this tile within the map data corresponding to the tileset, or -1 if this - * represents a blank tile. + * The object that this DataManager belongs to. * - * @name Phaser.Tilemaps.Tile#index - * @type {number} + * @name Phaser.Data.DataManager#parent + * @type {*} * @since 3.0.0 */ - this.index = index; + this.parent = parent; /** - * The x map coordinate of this tile in tile units. + * The DataManager's event emitter. * - * @name Phaser.Tilemaps.Tile#x - * @type {number} + * @name Phaser.Data.DataManager#events + * @type {Phaser.Events.EventEmitter} * @since 3.0.0 */ - this.x = x; + this.events = eventEmitter; - /** - * The y map coordinate of this tile in tile units. - * - * @name Phaser.Tilemaps.Tile#y - * @type {number} - * @since 3.0.0 - */ - this.y = y; + if (!eventEmitter) + { + this.events = (parent.events) ? parent.events : parent; + } /** - * The width of the tile in pixels. + * The data list. * - * @name Phaser.Tilemaps.Tile#width - * @type {number} + * @name Phaser.Data.DataManager#list + * @type {Object.} + * @default {} * @since 3.0.0 */ - this.width = width; + this.list = {}; /** - * The height of the tile in pixels. + * The public values list. You can use this to access anything you have stored + * in this Data Manager. For example, if you set a value called `gold` you can + * access it via: * - * @name Phaser.Tilemaps.Tile#height - * @type {number} - * @since 3.0.0 - */ - this.height = height; - - /** - * The right of the tile in pixels. + * ```javascript + * this.data.values.gold; + * ``` * - * Set in the `updatePixelXY` method. + * You can also modify it directly: * - * @name Phaser.Tilemaps.Tile#right - * @type {number} - * @since 3.50.0 - */ - this.right; - - /** - * The bottom of the tile in pixels. + * ```javascript + * this.data.values.gold += 1000; + * ``` * - * Set in the `updatePixelXY` method. + * Doing so will emit a `setdata` event from the parent of this Data Manager. * - * @name Phaser.Tilemaps.Tile#bottom - * @type {number} - * @since 3.50.0 - */ - this.bottom; - - /** - * The maps base width of a tile in pixels. Tiled maps support multiple tileset sizes - * within one map, but they are still placed at intervals of the base tile size. + * Do not modify this object directly. Adding properties directly to this object will not + * emit any events. Always use `DataManager.set` to create new items the first time around. * - * @name Phaser.Tilemaps.Tile#baseWidth - * @type {number} - * @since 3.0.0 + * @name Phaser.Data.DataManager#values + * @type {Object.} + * @default {} + * @since 3.10.0 */ - this.baseWidth = (baseWidth !== undefined) ? baseWidth : width; + this.values = {}; /** - * The maps base height of a tile in pixels. Tiled maps support multiple tileset sizes - * within one map, but they are still placed at intervals of the base tile size. + * Whether setting data is frozen for this DataManager. * - * @name Phaser.Tilemaps.Tile#baseHeight - * @type {number} + * @name Phaser.Data.DataManager#_frozen + * @type {boolean} + * @private + * @default false * @since 3.0.0 */ - this.baseHeight = (baseHeight !== undefined) ? baseHeight : height; + this._frozen = false; - /** - * The x coordinate of the top left of this tile in pixels. This is relative to the top left - * of the layer this tile is being rendered within. This property does NOT factor in camera - * scroll, layer scale or layer position. - * - * @name Phaser.Tilemaps.Tile#pixelX - * @type {number} - * @since 3.0.0 - */ - this.pixelX = 0; + if (!parent.hasOwnProperty('sys') && this.events) + { + this.events.once(Events.DESTROY, this.destroy, this); + } + }, - /** - * The y coordinate of the top left of this tile in pixels. This is relative to the top left - * of the layer this tile is being rendered within. This property does NOT factor in camera - * scroll, layer scale or layer position. - * - * @name Phaser.Tilemaps.Tile#pixelY - * @type {number} - * @since 3.0.0 - */ - this.pixelY = 0; + /** + * Retrieves the value for the given key, or undefined if it doesn't exist. + * + * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: + * + * ```javascript + * this.data.get('gold'); + * ``` + * + * Or access the value directly: + * + * ```javascript + * this.data.values.gold; + * ``` + * + * You can also pass in an array of keys, in which case an array of values will be returned: + * + * ```javascript + * this.data.get([ 'gold', 'armor', 'health' ]); + * ``` + * + * This approach is useful for destructuring arrays in ES6. + * + * @method Phaser.Data.DataManager#get + * @since 3.0.0 + * + * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys. + * + * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array. + */ + get: function (key) + { + var list = this.list; - this.updatePixelXY(); + if (Array.isArray(key)) + { + var output = []; - /** - * Tile specific properties. These usually come from Tiled. - * - * @name Phaser.Tilemaps.Tile#properties - * @type {any} - * @since 3.0.0 - */ - this.properties = {}; + for (var i = 0; i < key.length; i++) + { + output.push(list[key[i]]); + } - /** - * The rotation angle of this tile. - * - * @name Phaser.Tilemaps.Tile#rotation - * @type {number} - * @since 3.0.0 - */ - this.rotation = 0; - - /** - * Whether the tile should collide with any object on the left side. - * - * This property is used by Arcade Physics only, however, you can also use it - * in your own checks. - * - * @name Phaser.Tilemaps.Tile#collideLeft - * @type {boolean} - * @since 3.0.0 - */ - this.collideLeft = false; - - /** - * Whether the tile should collide with any object on the right side. - * - * This property is used by Arcade Physics only, however, you can also use it - * in your own checks. - * - * @name Phaser.Tilemaps.Tile#collideRight - * @type {boolean} - * @since 3.0.0 - */ - this.collideRight = false; - - /** - * Whether the tile should collide with any object on the top side. - * - * This property is used by Arcade Physics only, however, you can also use it - * in your own checks. - * - * @name Phaser.Tilemaps.Tile#collideUp - * @type {boolean} - * @since 3.0.0 - */ - this.collideUp = false; - - /** - * Whether the tile should collide with any object on the bottom side. - * - * This property is used by Arcade Physics only, however, you can also use it - * in your own checks. - * - * @name Phaser.Tilemaps.Tile#collideDown - * @type {boolean} - * @since 3.0.0 - */ - this.collideDown = false; - - /** - * Whether the tiles left edge is interesting for collisions. - * - * @name Phaser.Tilemaps.Tile#faceLeft - * @type {boolean} - * @since 3.0.0 - */ - this.faceLeft = false; - - /** - * Whether the tiles right edge is interesting for collisions. - * - * @name Phaser.Tilemaps.Tile#faceRight - * @type {boolean} - * @since 3.0.0 - */ - this.faceRight = false; - - /** - * Whether the tiles top edge is interesting for collisions. - * - * @name Phaser.Tilemaps.Tile#faceTop - * @type {boolean} - * @since 3.0.0 - */ - this.faceTop = false; - - /** - * Whether the tiles bottom edge is interesting for collisions. - * - * @name Phaser.Tilemaps.Tile#faceBottom - * @type {boolean} - * @since 3.0.0 - */ - this.faceBottom = false; - - /** - * Tile collision callback. - * - * @name Phaser.Tilemaps.Tile#collisionCallback - * @type {function} - * @since 3.0.0 - */ - this.collisionCallback = undefined; - - /** - * The context in which the collision callback will be called. - * - * @name Phaser.Tilemaps.Tile#collisionCallbackContext - * @type {object} - * @since 3.0.0 - */ - this.collisionCallbackContext = this; - - /** - * The tint to apply to this tile. Note: tint is currently a single color value instead of - * the 4 corner tint component on other GameObjects. - * - * @name Phaser.Tilemaps.Tile#tint - * @type {number} - * @default - * @since 3.0.0 - */ - this.tint = 0xffffff; - - /** - * An empty object where physics-engine specific information (e.g. bodies) may be stored. - * - * @name Phaser.Tilemaps.Tile#physics - * @type {object} - * @since 3.0.0 - */ - this.physics = {}; - }, + return output; + } + else + { + return list[key]; + } + }, /** - * Check if the given x and y world coordinates are within this Tile. This does not factor in - * camera scroll, layer scale or layer position. + * Retrieves all data values in a new object. * - * @method Phaser.Tilemaps.Tile#containsPoint + * @method Phaser.Data.DataManager#getAll * @since 3.0.0 * - * @param {number} x - The x coordinate to test. - * @param {number} y - The y coordinate to test. - * - * @return {boolean} True if the coordinates are within this Tile, otherwise false. + * @return {Object.} All data values. */ - containsPoint: function (x, y) + getAll: function () { - return !(x < this.pixelX || y < this.pixelY || x > this.right || y > this.bottom); + var results = {}; + + for (var key in this.list) + { + if (this.list.hasOwnProperty(key)) + { + results[key] = this.list[key]; + } + } + + return results; }, /** - * Copies the tile data & properties from the given tile to this tile. This copies everything - * except for position and interesting faces. + * Queries the DataManager for the values of keys matching the given regular expression. * - * @method Phaser.Tilemaps.Tile#copy + * @method Phaser.Data.DataManager#query * @since 3.0.0 * - * @param {Phaser.Tilemaps.Tile} tile - The tile to copy from. + * @param {RegExp} search - A regular expression object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj). * - * @return {this} This Tile object instance. + * @return {Object.} The values of the keys matching the search string. */ - copy: function (tile) + query: function (search) { - this.index = tile.index; - this.alpha = tile.alpha; - this.properties = tile.properties; - this.visible = tile.visible; - this.setFlip(tile.flipX, tile.flipY); - this.tint = tile.tint; - this.rotation = tile.rotation; - this.collideUp = tile.collideUp; - this.collideDown = tile.collideDown; - this.collideLeft = tile.collideLeft; - this.collideRight = tile.collideRight; - this.collisionCallback = tile.collisionCallback; - this.collisionCallbackContext = tile.collisionCallbackContext; + var results = {}; - return this; + for (var key in this.list) + { + if (this.list.hasOwnProperty(key) && key.match(search)) + { + results[key] = this.list[key]; + } + } + + return results; }, /** - * The collision group for this Tile, defined within the Tileset. This returns a reference to - * the collision group stored within the Tileset, so any modification of the returned object - * will impact all tiles that have the same index as this tile. + * Sets a value for the given key. If the key doesn't already exist in the Data Manager then it is created. * - * @method Phaser.Tilemaps.Tile#getCollisionGroup - * @since 3.0.0 + * ```javascript + * data.set('name', 'Red Gem Stone'); + * ``` * - * @return {?object} The collision group for this Tile, as defined in the Tileset, or `null` if no group was defined. - */ - getCollisionGroup: function () - { - return this.tileset ? this.tileset.getTileCollisionGroup(this.index) : null; - }, - - /** - * The tile data for this Tile, defined within the Tileset. This typically contains Tiled - * collision data, tile animations and terrain information. This returns a reference to the tile - * data stored within the Tileset, so any modification of the returned object will impact all - * tiles that have the same index as this tile. + * You can also pass in an object of key value pairs as the first argument: * - * @method Phaser.Tilemaps.Tile#getTileData - * @since 3.0.0 + * ```javascript + * data.set({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); + * ``` * - * @return {?object} The tile data for this Tile, as defined in the Tileset, or `null` if no data was defined. - */ - getTileData: function () - { - return this.tileset ? this.tileset.getTileData(this.index) : null; - }, - - /** - * Gets the world X position of the left side of the tile, factoring in the layers position, - * scale and scroll. + * To get a value back again you can call `get`: * - * @method Phaser.Tilemaps.Tile#getLeft - * @since 3.0.0 + * ```javascript + * data.get('gold'); + * ``` * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * Or you can access the value directly via the `values` property, where it works like any other variable: * - * @return {number} The left (x) value of this tile. - */ - getLeft: function (camera) - { - var tilemapLayer = this.tilemapLayer; - - return (tilemapLayer) ? tilemapLayer.tileToWorldX(this.x, camera) : this.x * this.baseWidth; - }, - - /** - * Gets the world X position of the right side of the tile, factoring in the layer's position, - * scale and scroll. + * ```javascript + * data.values.gold += 50; + * ``` * - * @method Phaser.Tilemaps.Tile#getRight - * @since 3.0.0 + * When the value is first set, a `setdata` event is emitted. * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. + * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. + * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. * - * @return {number} The right (x) value of this tile. - */ - getRight: function (camera) - { - var tilemapLayer = this.tilemapLayer; - - return (tilemapLayer) ? this.getLeft(camera) + this.width * tilemapLayer.scaleX : this.getLeft(camera) + this.width; - }, - - /** - * Gets the world Y position of the top side of the tile, factoring in the layer's position, - * scale and scroll. + * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. + * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. * - * @method Phaser.Tilemaps.Tile#getTop + * @method Phaser.Data.DataManager#set + * @fires Phaser.Data.Events#SET_DATA + * @fires Phaser.Data.Events#CHANGE_DATA + * @fires Phaser.Data.Events#CHANGE_DATA_KEY * @since 3.0.0 * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * @generic {any} T + * @genericUse {(string|T)} - [key] * - * @return {number} The top (y) value of this tile. + * @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. + * @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored. + * + * @return {this} This Data Manager instance. */ - getTop: function (camera) + set: function (key, data) { - var tilemapLayer = this.tilemapLayer; + if (this._frozen) + { + return this; + } - // Tiled places tiles on a grid of baseWidth x baseHeight. The origin for a tile in grid - // units is the bottom left, so the y coordinate needs to be adjusted by the difference - // between the base size and this tile's size. - return tilemapLayer - ? tilemapLayer.tileToWorldY(this.y, camera) - (this.height - this.baseHeight) * tilemapLayer.scaleY - : this.y * this.baseHeight - (this.height - this.baseHeight); + if (typeof key === 'string') + { + return this.setValue(key, data); + } + else + { + for (var entry in key) + { + this.setValue(entry, key[entry]); + } + } + + return this; }, /** - * Gets the world Y position of the bottom side of the tile, factoring in the layer's position, - * scale and scroll. - - * @method Phaser.Tilemaps.Tile#getBottom - * @since 3.0.0 + * Increase a value for the given key. If the key doesn't already exist in the Data Manager then it is increased from 0. * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * When the value is first set, a `setdata` event is emitted. * - * @return {number} The bottom (y) value of this tile. - */ - getBottom: function (camera) - { - var tilemapLayer = this.tilemapLayer; - - return tilemapLayer - ? this.getTop(camera) + this.height * tilemapLayer.scaleY - : this.getTop(camera) + this.height; - }, - - - /** - * Gets the world rectangle bounding box for the tile, factoring in the layers position, - * scale and scroll. + * @method Phaser.Data.DataManager#inc + * @fires Phaser.Data.Events#SET_DATA + * @fires Phaser.Data.Events#CHANGE_DATA + * @fires Phaser.Data.Events#CHANGE_DATA_KEY + * @since 3.23.0 * - * @method Phaser.Tilemaps.Tile#getBounds - * @since 3.0.0 + * @generic {any} T + * @genericUse {(string|T)} - [key] * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. - * @param {Phaser.Geom.Rectangle} [output] - Optional Rectangle object to store the results in. + * @param {(string|object)} key - The key to increase the value for. + * @param {number} [data=1] - The amount to increase the given key by. Pass a negative value to decrease the key. * - * @return {(Phaser.Geom.Rectangle|object)} The bounds of this Tile. + * @return {this} This Data Manager instance. */ - getBounds: function (camera, output) + inc: function (key, data) { - if (output === undefined) { output = new Rectangle(); } + if (this._frozen) + { + return this; + } - output.x = this.getLeft(); - output.y = this.getTop(); - output.width = this.getRight() - output.x; - output.height = this.getBottom() - output.y; + if (data === undefined) + { + data = 1; + } - return output; - }, + var value = this.get(key); - /** - * Gets the world X position of the center of the tile, factoring in the layer's position, - * scale and scroll. - * - * @method Phaser.Tilemaps.Tile#getCenterX - * @since 3.0.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. - * - * @return {number} The center x position of this Tile. - */ - getCenterX: function (camera) - { - return (this.getLeft(camera) + this.getRight(camera)) / 2; + if (value === undefined) + { + value = 0; + } + + this.set(key, (value + data)); + + return this; }, /** - * Gets the world Y position of the center of the tile, factoring in the layer's position, - * scale and scroll. - * - * @method Phaser.Tilemaps.Tile#getCenterY - * @since 3.0.0 + * Toggle a boolean value for the given key. If the key doesn't already exist in the Data Manager then it is toggled from false. * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * When the value is first set, a `setdata` event is emitted. * - * @return {number} The center y position of this Tile. - */ - getCenterY: function (camera) - { - return (this.getTop(camera) + this.getBottom(camera)) / 2; - }, - - /** - * Check for intersection with this tile. This does not factor in camera scroll, layer scale or - * layer position. + * @method Phaser.Data.DataManager#toggle + * @fires Phaser.Data.Events#SET_DATA + * @fires Phaser.Data.Events#CHANGE_DATA + * @fires Phaser.Data.Events#CHANGE_DATA_KEY + * @since 3.23.0 * - * @method Phaser.Tilemaps.Tile#intersects - * @since 3.0.0 + * @generic {any} T + * @genericUse {(string|T)} - [key] * - * @param {number} x - The x axis in pixels. - * @param {number} y - The y axis in pixels. - * @param {number} right - The right point. - * @param {number} bottom - The bottom point. + * @param {(string|object)} key - The key to toggle the value for. * - * @return {boolean} `true` if the Tile intersects with the given dimensions, otherwise `false`. + * @return {this} This Data Manager instance. */ - intersects: function (x, y, right, bottom) + toggle: function (key) { - return !( - right <= this.pixelX || bottom <= this.pixelY || - x >= this.right || y >= this.bottom - ); + if (this._frozen) + { + return this; + } + + this.set(key, !this.get(key)); + + return this; }, /** - * Checks if the tile is interesting. + * Internal value setter, called automatically by the `set` method. * - * @method Phaser.Tilemaps.Tile#isInteresting - * @since 3.0.0 + * @method Phaser.Data.DataManager#setValue + * @fires Phaser.Data.Events#SET_DATA + * @fires Phaser.Data.Events#CHANGE_DATA + * @fires Phaser.Data.Events#CHANGE_DATA_KEY + * @private + * @since 3.10.0 * - * @param {boolean} collides - If true, will consider the tile interesting if it collides on any side. - * @param {boolean} faces - If true, will consider the tile interesting if it has an interesting face. + * @param {string} key - The key to set the value for. + * @param {*} data - The value to set. * - * @return {boolean} True if the Tile is interesting, otherwise false. + * @return {this} This Data Manager instance. */ - isInteresting: function (collides, faces) + setValue: function (key, data) { - if (collides && faces) + if (this._frozen) { - return (this.canCollide || this.hasInterestingFace); + return this; } - else if (collides) + + if (this.has(key)) { - return this.collides; + // Hit the key getter, which will in turn emit the events. + this.values[key] = data; } - else if (faces) + else { - return this.hasInterestingFace; - } + var _this = this; + var list = this.list; + var events = this.events; + var parent = this.parent; - return false; - }, + Object.defineProperty(this.values, key, { - /** - * Reset collision status flags. - * - * @method Phaser.Tilemaps.Tile#resetCollision - * @since 3.0.0 - * - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate interesting faces for this tile and its neighbors. - * - * @return {this} This Tile object instance. - */ - resetCollision: function (recalculateFaces) - { - if (recalculateFaces === undefined) { recalculateFaces = true; } + enumerable: true, - this.collideLeft = false; - this.collideRight = false; - this.collideUp = false; - this.collideDown = false; + configurable: true, - this.faceTop = false; - this.faceBottom = false; - this.faceLeft = false; - this.faceRight = false; + get: function () + { + return list[key]; + }, - if (recalculateFaces) - { - var tilemapLayer = this.tilemapLayer; + set: function (value) + { + if (!_this._frozen) + { + var previousValue = list[key]; + list[key] = value; - if (tilemapLayer) - { - this.tilemapLayer.calculateFacesAt(this.x, this.y); - } + events.emit(Events.CHANGE_DATA, parent, key, value, previousValue); + events.emit(Events.CHANGE_DATA_KEY + key, parent, value, previousValue); + } + } + + }); + + list[key] = data; + + events.emit(Events.SET_DATA, parent, key, data); } return this; }, /** - * Reset faces. + * Passes all data entries to the given callback. * - * @method Phaser.Tilemaps.Tile#resetFaces + * @method Phaser.Data.DataManager#each * @since 3.0.0 * - * @return {this} This Tile object instance. + * @param {DataEachCallback} callback - The function to call. + * @param {*} [context] - Value to use as `this` when executing callback. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data. + * + * @return {this} This Data Manager instance. */ - resetFaces: function () + each: function (callback, context) { - this.faceTop = false; - this.faceBottom = false; - this.faceLeft = false; - this.faceRight = false; + var args = [ this.parent, null, undefined ]; + + for (var i = 1; i < arguments.length; i++) + { + args.push(arguments[i]); + } + + for (var key in this.list) + { + args[1] = key; + args[2] = this.list[key]; + + callback.apply(context, args); + } return this; }, /** - * Sets the collision flags for each side of this tile and updates the interesting faces list. + * Merge the given object of key value pairs into this DataManager. * - * @method Phaser.Tilemaps.Tile#setCollision + * Any newly created values will emit a `setdata` event. Any updated values (see the `overwrite` argument) + * will emit a `changedata` event. + * + * @method Phaser.Data.DataManager#merge + * @fires Phaser.Data.Events#SET_DATA + * @fires Phaser.Data.Events#CHANGE_DATA + * @fires Phaser.Data.Events#CHANGE_DATA_KEY * @since 3.0.0 * - * @param {boolean} left - Indicating collide with any object on the left. - * @param {boolean} [right] - Indicating collide with any object on the right. - * @param {boolean} [up] - Indicating collide with any object on the top. - * @param {boolean} [down] - Indicating collide with any object on the bottom. - * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate interesting faces for this tile and its neighbors. + * @param {Object.} data - The data to merge. + * @param {boolean} [overwrite=true] - Whether to overwrite existing data. Defaults to true. * - * @return {this} This Tile object instance. + * @return {this} This Data Manager instance. */ - setCollision: function (left, right, up, down, recalculateFaces) + merge: function (data, overwrite) { - if (right === undefined) { right = left; } - if (up === undefined) { up = left; } - if (down === undefined) { down = left; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - this.collideLeft = left; - this.collideRight = right; - this.collideUp = up; - this.collideDown = down; - - this.faceLeft = left; - this.faceRight = right; - this.faceTop = up; - this.faceBottom = down; + if (overwrite === undefined) { overwrite = true; } - if (recalculateFaces) + // Merge data from another component into this one + for (var key in data) { - var tilemapLayer = this.tilemapLayer; - - if (tilemapLayer) + if (data.hasOwnProperty(key) && (overwrite || (!overwrite && !this.has(key)))) { - this.tilemapLayer.calculateFacesAt(this.x, this.y); + this.setValue(key, data[key]); } } @@ -22054,33219 +23064,35311 @@ var Tile = new Class({ }, /** - * Set a callback to be called when this tile is hit by an object. The callback must true for - * collision processing to take place. + * Remove the value for the given key. * - * @method Phaser.Tilemaps.Tile#setCollisionCallback + * If the key is found in this Data Manager it is removed from the internal lists and a + * `removedata` event is emitted. + * + * You can also pass in an array of keys, in which case all keys in the array will be removed: + * + * ```javascript + * this.data.remove([ 'gold', 'armor', 'health' ]); + * ``` + * + * @method Phaser.Data.DataManager#remove + * @fires Phaser.Data.Events#REMOVE_DATA * @since 3.0.0 * - * @param {function} callback - Callback function. - * @param {object} context - Callback will be called within this context. + * @param {(string|string[])} key - The key to remove, or an array of keys to remove. * - * @return {this} This Tile object instance. + * @return {this} This Data Manager instance. */ - setCollisionCallback: function (callback, context) + remove: function (key) { - if (callback === null) + if (this._frozen) { - this.collisionCallback = undefined; - this.collisionCallbackContext = undefined; + return this; + } + + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + this.removeValue(key[i]); + } } else { - this.collisionCallback = callback; - this.collisionCallbackContext = context; + return this.removeValue(key); } return this; }, /** - * Sets the size of the tile and updates its pixelX and pixelY. + * Internal value remover, called automatically by the `remove` method. * - * @method Phaser.Tilemaps.Tile#setSize - * @since 3.0.0 + * @method Phaser.Data.DataManager#removeValue + * @private + * @fires Phaser.Data.Events#REMOVE_DATA + * @since 3.10.0 * - * @param {number} tileWidth - The width of the tile in pixels. - * @param {number} tileHeight - The height of the tile in pixels. - * @param {number} baseWidth - The base width a tile in the map (in pixels). - * @param {number} baseHeight - The base height of the tile in pixels (in pixels). + * @param {string} key - The key to set the value for. * - * @return {this} This Tile object instance. + * @return {this} This Data Manager instance. */ - setSize: function (tileWidth, tileHeight, baseWidth, baseHeight) + removeValue: function (key) { - if (tileWidth !== undefined) { this.width = tileWidth; } - if (tileHeight !== undefined) { this.height = tileHeight; } - if (baseWidth !== undefined) { this.baseWidth = baseWidth; } - if (baseHeight !== undefined) { this.baseHeight = baseHeight; } + if (this.has(key)) + { + var data = this.list[key]; - this.updatePixelXY(); + delete this.list[key]; + delete this.values[key]; + + this.events.emit(Events.REMOVE_DATA, this.parent, key, data); + } return this; }, /** - * Used internally. Updates the tiles world XY position based on the current tile size. + * Retrieves the data associated with the given 'key', deletes it from this Data Manager, then returns it. * - * @method Phaser.Tilemaps.Tile#updatePixelXY + * @method Phaser.Data.DataManager#pop + * @fires Phaser.Data.Events#REMOVE_DATA * @since 3.0.0 * - * @return {this} This Tile object instance. + * @param {string} key - The key of the value to retrieve and delete. + * + * @return {*} The value of the given key. */ - updatePixelXY: function () + pop: function (key) { - var orientation = this.layer.orientation; - - if (orientation === CONST.ORTHOGONAL) - { - // In orthogonal mode, Tiled places tiles on a grid of baseWidth x baseHeight. The origin for a tile is the - // bottom left, while the Phaser renderer assumes the origin is the top left. The y - // coordinate needs to be adjusted by the difference. + var data = undefined; - this.pixelX = this.x * this.baseWidth; - this.pixelY = this.y * this.baseHeight; - } - else if (orientation === CONST.ISOMETRIC) + if (!this._frozen && this.has(key)) { - // Reminder: For the tilemap to be centered we have to move the image to the right with the camera! - // This is crucial for wordtotile, tiletoworld to work. + data = this.list[key]; - this.pixelX = (this.x - this.y) * this.baseWidth * 0.5; - this.pixelY = (this.x + this.y) * this.baseHeight * 0.5; - } - else if (orientation === CONST.STAGGERED) - { - this.pixelX = this.x * this.baseWidth + this.y % 2 * (this.baseWidth / 2); - this.pixelY = this.y * (this.baseHeight / 2); - } - else if (orientation === CONST.HEXAGONAL) - { - var len = this.layer.hexSideLength; - var rowHeight = ((this.baseHeight - len) / 2 + len); + delete this.list[key]; + delete this.values[key]; - this.pixelX = this.x * this.baseWidth + this.y % 2 * (this.baseWidth / 2); - this.pixelY = this.y * rowHeight; + this.events.emit(Events.REMOVE_DATA, this.parent, key, data); } - this.right = this.pixelX + this.baseWidth; - this.bottom = this.pixelY + this.baseHeight; - - return this; + return data; }, /** - * Clean up memory. + * Determines whether the given key is set in this Data Manager. * - * @method Phaser.Tilemaps.Tile#destroy + * Please note that the keys are case-sensitive and must be valid JavaScript Object property strings. + * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. + * + * @method Phaser.Data.DataManager#has * @since 3.0.0 + * + * @param {string} key - The key to check. + * + * @return {boolean} Returns `true` if the key exists, otherwise `false`. */ - destroy: function () + has: function (key) { - this.collisionCallback = undefined; - this.collisionCallbackContext = undefined; - this.properties = undefined; + return this.list.hasOwnProperty(key); }, /** - * True if this tile can collide on any of its faces or has a collision callback set. + * Freeze or unfreeze this Data Manager. A frozen Data Manager will block all attempts + * to create new values or update existing ones. * - * @name Phaser.Tilemaps.Tile#canCollide - * @type {boolean} - * @readonly + * @method Phaser.Data.DataManager#setFreeze * @since 3.0.0 + * + * @param {boolean} value - Whether to freeze or unfreeze the Data Manager. + * + * @return {this} This Data Manager instance. */ - canCollide: { - - get: function () - { - return (this.collideLeft || this.collideRight || this.collideUp || this.collideDown || (this.collisionCallback !== undefined)); - } + setFreeze: function (value) + { + this._frozen = value; + return this; }, /** - * True if this tile can collide on any of its faces. + * Delete all data in this Data Manager and unfreeze it. * - * @name Phaser.Tilemaps.Tile#collides - * @type {boolean} - * @readonly + * @method Phaser.Data.DataManager#reset * @since 3.0.0 + * + * @return {this} This Data Manager instance. */ - collides: { - - get: function () + reset: function () + { + for (var key in this.list) { - return (this.collideLeft || this.collideRight || this.collideUp || this.collideDown); + delete this.list[key]; + delete this.values[key]; } + this._frozen = false; + + return this; }, /** - * True if this tile has any interesting faces. + * Destroy this data manager. * - * @name Phaser.Tilemaps.Tile#hasInterestingFace - * @type {boolean} - * @readonly + * @method Phaser.Data.DataManager#destroy * @since 3.0.0 */ - hasInterestingFace: { + destroy: function () + { + this.reset(); - get: function () - { - return (this.faceTop || this.faceBottom || this.faceLeft || this.faceRight); - } + this.events.off(Events.CHANGE_DATA); + this.events.off(Events.SET_DATA); + this.events.off(Events.REMOVE_DATA); + this.parent = null; }, /** - * The tileset that contains this Tile. This is null if accessed from a LayerData instance - * before the tile is placed in a TilemapLayer, or if the tile has an index that doesn't correspond - * to any of the maps tilesets. + * Gets or sets the frozen state of this Data Manager. + * A frozen Data Manager will block all attempts to create new values or update existing ones. * - * @name Phaser.Tilemaps.Tile#tileset - * @type {?Phaser.Tilemaps.Tileset} - * @readonly + * @name Phaser.Data.DataManager#freeze + * @type {boolean} * @since 3.0.0 */ - tileset: { + freeze: { get: function () { - var tilemapLayer = this.layer.tilemapLayer; - - if (tilemapLayer) - { - var tileset = tilemapLayer.gidMap[this.index]; - - if (tileset) - { - return tileset; - } - } - - return null; - } - - }, - - /** - * The tilemap layer that contains this Tile. This will only return null if accessed from a - * LayerData instance before the tile is placed within a TilemapLayer. - * - * @name Phaser.Tilemaps.Tile#tilemapLayer - * @type {?Phaser.Tilemaps.TilemapLayer} - * @readonly - * @since 3.0.0 - */ - tilemapLayer: { + return this._frozen; + }, - get: function () + set: function (value) { - return this.layer.tilemapLayer; + this._frozen = (value) ? true : false; } }, /** - * The tilemap that contains this Tile. This will only return null if accessed from a LayerData - * instance before the tile is placed within a TilemapLayer. + * Return the total number of entries in this Data Manager. * - * @name Phaser.Tilemaps.Tile#tilemap - * @type {?Phaser.Tilemaps.Tilemap} - * @readonly + * @name Phaser.Data.DataManager#count + * @type {number} * @since 3.0.0 */ - tilemap: { + count: { get: function () { - var tilemapLayer = this.tilemapLayer; + var i = 0; - return tilemapLayer ? tilemapLayer.tilemap : null; + for (var key in this.list) + { + if (this.list[key] !== undefined) + { + i++; + } + } + + return i; } } }); -module.exports = Tile; +module.exports = DataManager; /***/ }), -/* 86 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 76508: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** -* The `Matter.Bodies` module contains factory methods for creating rigid body models -* with commonly used body configurations (such as rectangles, circles and other polygons). -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Bodies -*/ + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -// TODO: true circle bodies +var Class = __webpack_require__(56694); +var DataManager = __webpack_require__(81078); +var PluginCache = __webpack_require__(91963); +var SceneEvents = __webpack_require__(7599); -var Bodies = {}; +/** + * @classdesc + * The Data Component features a means to store pieces of data specific to a Game Object, System or Plugin. + * You can then search, query it, and retrieve the data. The parent must either extend EventEmitter, + * or have a property called `events` that is an instance of it. + * + * @class DataManagerPlugin + * @extends Phaser.Data.DataManager + * @memberof Phaser.Data + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - A reference to the Scene that this DataManager belongs to. + */ +var DataManagerPlugin = new Class({ -module.exports = Bodies; + Extends: DataManager, -var Vertices = __webpack_require__(64); -var Common = __webpack_require__(32); -var Body = __webpack_require__(41); -var Bounds = __webpack_require__(84); -var Vector = __webpack_require__(83); -var decomp = __webpack_require__(1393); + initialize: -(function() { + function DataManagerPlugin (scene) + { + DataManager.call(this, scene, scene.sys.events); - /** - * Creates a new rigid body model with a rectangle hull. - * The options parameter is an object that specifies any properties you wish to override the defaults. - * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. - * @method rectangle - * @param {number} x - * @param {number} y - * @param {number} width - * @param {number} height - * @param {object} [options] - * @return {body} A new rectangle body - */ - Bodies.rectangle = function(x, y, width, height, options) { - options = options || {}; + /** + * A reference to the Scene that this DataManager belongs to. + * + * @name Phaser.Data.DataManagerPlugin#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - var rectangle = { - label: 'Rectangle Body', - position: { x: x, y: y }, - vertices: Vertices.fromPath('L 0 0 L ' + width + ' 0 L ' + width + ' ' + height + ' L 0 ' + height) - }; + /** + * A reference to the Scene's Systems. + * + * @name Phaser.Data.DataManagerPlugin#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.systems = scene.sys; - if (options.chamfer) { - var chamfer = options.chamfer; - rectangle.vertices = Vertices.chamfer(rectangle.vertices, chamfer.radius, - chamfer.quality, chamfer.qualityMin, chamfer.qualityMax); - delete options.chamfer; - } + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + scene.sys.events.on(SceneEvents.START, this.start, this); + }, - return Body.create(Common.extend({}, rectangle, options)); - }; - /** - * Creates a new rigid body model with a trapezoid hull. - * The options parameter is an object that specifies any properties you wish to override the defaults. - * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. - * @method trapezoid - * @param {number} x - * @param {number} y - * @param {number} width - * @param {number} height - * @param {number} slope - * @param {object} [options] - * @return {body} A new trapezoid body + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. + * + * @method Phaser.Data.DataManagerPlugin#boot + * @private + * @since 3.5.1 */ - Bodies.trapezoid = function(x, y, width, height, slope, options) { - options = options || {}; - - slope *= 0.5; - var roof = (1 - (slope * 2)) * width; - - var x1 = width * slope, - x2 = x1 + roof, - x3 = x2 + x1, - verticesPath; - - if (slope < 0.5) { - verticesPath = 'L 0 0 L ' + x1 + ' ' + (-height) + ' L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0'; - } else { - verticesPath = 'L 0 0 L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0'; - } + boot: function () + { + this.events = this.systems.events; - var trapezoid = { - label: 'Trapezoid Body', - position: { x: x, y: y }, - vertices: Vertices.fromPath(verticesPath) - }; + this.events.once(SceneEvents.DESTROY, this.destroy, this); + }, - if (options.chamfer) { - var chamfer = options.chamfer; - trapezoid.vertices = Vertices.chamfer(trapezoid.vertices, chamfer.radius, - chamfer.quality, chamfer.qualityMin, chamfer.qualityMax); - delete options.chamfer; - } + /** + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. + * + * @method Phaser.Data.DataManagerPlugin#start + * @private + * @since 3.5.0 + */ + start: function () + { + this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); + }, - return Body.create(Common.extend({}, trapezoid, options)); - }; + /** + * The Scene that owns this plugin is shutting down. + * We need to kill and reset all internal properties as well as stop listening to Scene events. + * + * @method Phaser.Data.DataManagerPlugin#shutdown + * @private + * @since 3.5.0 + */ + shutdown: function () + { + this.systems.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); + }, /** - * Creates a new rigid body model with a circle hull. - * The options parameter is an object that specifies any properties you wish to override the defaults. - * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. - * @method circle - * @param {number} x - * @param {number} y - * @param {number} radius - * @param {object} [options] - * @param {number} [maxSides] - * @return {body} A new circle body + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. + * + * @method Phaser.Data.DataManagerPlugin#destroy + * @since 3.5.0 */ - Bodies.circle = function(x, y, radius, options, maxSides) { - options = options || {}; + destroy: function () + { + DataManager.prototype.destroy.call(this); - var circle = { - label: 'Circle Body', - circleRadius: radius - }; - - // approximate circles with polygons until true circles implemented in SAT - maxSides = maxSides || 25; - var sides = Math.ceil(Math.max(10, Math.min(maxSides, radius))); + this.events.off(SceneEvents.START, this.start, this); - // optimisation: always use even number of sides (half the number of unique axes) - if (sides % 2 === 1) - sides += 1; + this.scene = null; + this.systems = null; + } - return Bodies.polygon(x, y, sides, radius, Common.extend({}, circle, options)); - }; +}); - /** - * Creates a new rigid body model with a regular polygon hull with the given number of sides. - * The options parameter is an object that specifies any properties you wish to override the defaults. - * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. - * @method polygon - * @param {number} x - * @param {number} y - * @param {number} sides - * @param {number} radius - * @param {object} [options] - * @return {body} A new regular polygon body - */ - Bodies.polygon = function(x, y, sides, radius, options) { - options = options || {}; +PluginCache.register('DataManagerPlugin', DataManagerPlugin, 'data'); - if (sides < 3) - return Bodies.circle(x, y, radius, options); - - var theta = 2 * Math.PI / sides, - path = '', - offset = theta * 0.5; - - for (var i = 0; i < sides; i += 1) { - var angle = offset + (i * theta), - xx = Math.cos(angle) * radius, - yy = Math.sin(angle) * radius; - - path += 'L ' + xx.toFixed(3) + ' ' + yy.toFixed(3) + ' '; - } - - var polygon = { - label: 'Polygon Body', - position: { x: x, y: y }, - vertices: Vertices.fromPath(path) - }; - - if (options.chamfer) { - var chamfer = options.chamfer; - polygon.vertices = Vertices.chamfer(polygon.vertices, chamfer.radius, - chamfer.quality, chamfer.qualityMin, chamfer.qualityMax); - delete options.chamfer; - } - - return Body.create(Common.extend({}, polygon, options)); - }; - - /** - * Creates a body using the supplied vertices (or an array containing multiple sets of vertices). - * If the vertices are convex, they will pass through as supplied. - * Otherwise if the vertices are concave, they will be decomposed if [poly-decomp.js](https://github.com/schteppe/poly-decomp.js) is available. - * Note that this process is not guaranteed to support complex sets of vertices (e.g. those with holes may fail). - * By default the decomposition will discard collinear edges (to improve performance). - * It can also optionally discard any parts that have an area less than `minimumArea`. - * If the vertices can not be decomposed, the result will fall back to using the convex hull. - * The options parameter is an object that specifies any `Matter.Body` properties you wish to override the defaults. - * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. - * @method fromVertices - * @param {number} x - * @param {number} y - * @param [[vector]] vertexSets - * @param {object} [options] - * @param {bool} [flagInternal=false] - * @param {number} [removeCollinear=0.01] - * @param {number} [minimumArea=10] - * @return {body} - */ - Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) { - var body, - parts, - isConvex, - vertices, - i, - j, - k, - v, - z; - - options = options || {}; - parts = []; - - flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false; - removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01; - minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10; - - if (!decomp) { - Common.warn('Bodies.fromVertices: poly-decomp.js required. Could not decompose vertices. Fallback to convex hull.'); - } - - // ensure vertexSets is an array of arrays - if (!Common.isArray(vertexSets[0])) { - vertexSets = [vertexSets]; - } - - for (v = 0; v < vertexSets.length; v += 1) { - vertices = vertexSets[v]; - isConvex = Vertices.isConvex(vertices); - - if (isConvex || !decomp) { - if (isConvex) { - vertices = Vertices.clockwiseSort(vertices); - } else { - // fallback to convex hull when decomposition is not possible - vertices = Vertices.hull(vertices); - } - - parts.push({ - position: { x: x, y: y }, - vertices: vertices - }); - } else { - // initialise a decomposition - var concave = vertices.map(function(vertex) { - return [vertex.x, vertex.y]; - }); - - // vertices are concave and simple, we can decompose into parts - decomp.makeCCW(concave); - if (removeCollinear !== false) - decomp.removeCollinearPoints(concave, removeCollinear); - - // use the quick decomposition algorithm (Bayazit) - var decomposed = decomp.quickDecomp(concave); - - // for each decomposed chunk - for (i = 0; i < decomposed.length; i++) { - var chunk = decomposed[i]; - - // convert vertices into the correct structure - var chunkVertices = chunk.map(function(vertices) { - return { - x: vertices[0], - y: vertices[1] - }; - }); - - // skip small chunks - if (minimumArea > 0 && Vertices.area(chunkVertices) < minimumArea) - continue; - - // create a compound part - parts.push({ - position: Vertices.centre(chunkVertices), - vertices: chunkVertices - }); - } - } - } - - // create body parts - for (i = 0; i < parts.length; i++) { - parts[i] = Body.create(Common.extend(parts[i], options)); - } - - if (flagInternal) - { - Bodies.flagCoincidentParts(parts, 5); - } - - if (parts.length > 1) { - // create the parent body to be returned, that contains generated compound parts - body = Body.create(Common.extend({ parts: parts.slice(0) }, options)); - Body.setPosition(body, { x: x, y: y }); - - return body; - } else { - return parts[0]; - } - }; - - /** - * Takes an array of Body objects and flags all internal edges (coincident parts) based on the maxDistance - * value. The array is changed in-place and returned, so you can pass this function a `Body.parts` property. - * - * @method flagCoincidentParts - * @param {body[]} parts - The Body parts, or array of bodies, to flag. - * @param {number} [maxDistance=5] - * @return {body[]} The modified `parts` parameter. - */ - Bodies.flagCoincidentParts = function (parts, maxDistance) - { - if (maxDistance === undefined) { maxDistance = 5; } - - for (var i = 0; i < parts.length; i++) - { - var partA = parts[i]; - - for (var j = i + 1; j < parts.length; j++) - { - var partB = parts[j]; - - if (Bounds.overlaps(partA.bounds, partB.bounds)) - { - var pav = partA.vertices; - var pbv = partB.vertices; - - // iterate vertices of both parts - for (var k = 0; k < partA.vertices.length; k++) - { - for (var z = 0; z < partB.vertices.length; z++) - { - // find distances between the vertices - var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z])); - var db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length])); - - // if both vertices are very close, consider the edge concident (internal) - if (da < maxDistance && db < maxDistance) - { - pav[k].isInternal = true; - pbv[z].isInternal = true; - } - } - } - } - } - } - - return parts; - }; - -})(); +module.exports = DataManagerPlugin; /***/ }), -/* 87 */ -/***/ (function(module, exports) { + +/***/ 73569: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Returns the center x coordinate from the bounds of the Game Object. + * The Change Data Event. * - * @function Phaser.Display.Bounds.GetCenterX - * @since 3.0.0 + * This event is dispatched by a Data Manager when an item in the data store is changed. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for + * a change data event from a Game Object you would use: `sprite.on('changedata', listener)`. * - * @return {number} The center x coordinate of the bounds of the Game Object. + * This event is dispatched for all items that change in the Data Manager. + * To listen for the change of a specific item, use the `CHANGE_DATA_KEY_EVENT` event. + * + * @event Phaser.Data.Events#CHANGE_DATA + * @type {string} + * @since 3.0.0 + * + * @param {any} parent - A reference to the object that the Data Manager responsible for this event belongs to. + * @param {string} key - The unique key of the data item within the Data Manager. + * @param {any} value - The new value of the item in the Data Manager. + * @param {any} previousValue - The previous value of the item in the Data Manager. */ -var GetCenterX = function (gameObject) -{ - return gameObject.x - (gameObject.width * gameObject.originX) + (gameObject.width * 0.5); -}; - -module.exports = GetCenterX; +module.exports = 'changedata'; /***/ }), -/* 88 */ -/***/ (function(module, exports) { + +/***/ 15590: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Positions the Game Object so that the center top of its bounds aligns with the given coordinate. + * The Change Data Key Event. * - * @function Phaser.Display.Bounds.SetCenterX - * @since 3.0.0 + * This event is dispatched by a Data Manager when an item in the data store is changed. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for + * the change of a specific data item from a Game Object you would use: `sprite.on('changedata-key', listener)`, + * where `key` is the unique string key of the data item. For example, if you have a data item stored called `gold` + * then you can listen for `sprite.on('changedata-gold')`. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. - * @param {number} x - The coordinate to position the Game Object bounds on. + * @event Phaser.Data.Events#CHANGE_DATA_KEY + * @type {string} + * @since 3.16.1 * - * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + * @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event. + * @param {any} value - The item that was updated in the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance. + * @param {any} previousValue - The previous item that was updated in the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance. */ -var SetCenterX = function (gameObject, x) -{ - var offsetX = gameObject.width * gameObject.originX; +module.exports = 'changedata-'; - gameObject.x = (x + offsetX) - (gameObject.width * 0.5); - return gameObject; -}; +/***/ }), -module.exports = SetCenterX; +/***/ 37669: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Data Manager Destroy Event. + * + * The Data Manager will listen for the destroy event from its parent, and then close itself down. + * + * @event Phaser.Data.Events#DESTROY + * @type {string} + * @since 3.50.0 + */ +module.exports = 'destroy'; /***/ }), -/* 89 */ -/***/ (function(module, exports) { + +/***/ 87090: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Returns the center y coordinate from the bounds of the Game Object. + * The Remove Data Event. * - * @function Phaser.Display.Bounds.GetCenterY - * @since 3.0.0 + * This event is dispatched by a Data Manager when an item is removed from it. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for + * the removal of a data item on a Game Object you would use: `sprite.on('removedata', listener)`. * - * @return {number} The center y coordinate of the bounds of the Game Object. + * @event Phaser.Data.Events#REMOVE_DATA + * @type {string} + * @since 3.0.0 + * + * @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event. + * @param {string} key - The unique key of the data item within the Data Manager. + * @param {any} data - The item that was removed from the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance. */ -var GetCenterY = function (gameObject) -{ - return gameObject.y - (gameObject.height * gameObject.originY) + (gameObject.height * 0.5); -}; - -module.exports = GetCenterY; +module.exports = 'removedata'; /***/ }), -/* 90 */ -/***/ (function(module, exports) { + +/***/ 90142: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Positions the Game Object so that the center top of its bounds aligns with the given coordinate. + * The Set Data Event. * - * @function Phaser.Display.Bounds.SetCenterY - * @since 3.0.0 + * This event is dispatched by a Data Manager when a new item is added to the data store. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for + * the addition of a new data item on a Game Object you would use: `sprite.on('setdata', listener)`. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. - * @param {number} y - The coordinate to position the Game Object bounds on. + * @event Phaser.Data.Events#SET_DATA + * @type {string} + * @since 3.0.0 * - * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + * @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event. + * @param {string} key - The unique key of the data item within the Data Manager. + * @param {any} data - The item that was added to the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance. */ -var SetCenterY = function (gameObject, y) -{ - var offsetY = gameObject.height * gameObject.originY; - - gameObject.y = (y + offsetY) - (gameObject.height * 0.5); - - return gameObject; -}; - -module.exports = SetCenterY; +module.exports = 'setdata'; /***/ }), -/* 91 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 35026: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Renderer.Events + * @namespace Phaser.Data.Events */ module.exports = { - POST_RENDER: __webpack_require__(628), - PRE_RENDER: __webpack_require__(629), - RENDER: __webpack_require__(630), - RESIZE: __webpack_require__(631) + CHANGE_DATA: __webpack_require__(73569), + CHANGE_DATA_KEY: __webpack_require__(15590), + DESTROY: __webpack_require__(37669), + REMOVE_DATA: __webpack_require__(87090), + SET_DATA: __webpack_require__(90142) }; /***/ }), -/* 92 */ -/***/ (function(module, exports) { + +/***/ 1999: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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', +/** + * @namespace Phaser.Data + */ - /** - * The Graphics and Shapes Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.GRAPHICS_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - GRAPHICS_PIPELINE: 'GraphicsPipeline', +module.exports = { - /** - * The Post FX Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - POSTFX_PIPELINE: 'PostFXPipeline', + DataManager: __webpack_require__(81078), + DataManagerPlugin: __webpack_require__(76508), + Events: __webpack_require__(35026) - /** - * The Utility Pipeline. - * - * @name Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE - * @type {string} - * @const - * @since 3.50.0 - */ - UTILITY_PIPELINE: 'UtilityPipeline' }; -module.exports = PIPELINE_CONST; - /***/ }), -/* 93 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 10720: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SpliceOne = __webpack_require__(74); +var Browser = __webpack_require__(1350); /** - * Removes the given item, or array of items, from the array. - * - * The array is modified in-place. - * - * You can optionally specify a callback to be invoked for each item successfully removed from the array. - * - * @function Phaser.Utils.Array.Remove - * @since 3.4.0 + * Determines the audio playback capabilities of the device running this Phaser Game instance. + * These values are read-only and populated during the boot sequence of the game. + * They are then referenced by internal game systems and are available for you to access + * via `this.sys.game.device.audio` from within any Scene. * - * @param {array} array - The array to be modified. - * @param {*|Array.<*>} item - The item, or array of items, to be removed from the array. - * @param {function} [callback] - A callback to be invoked for each item successfully removed from the array. - * @param {object} [context] - The context in which the callback is invoked. + * @typedef {object} Phaser.Device.Audio + * @since 3.0.0 * - * @return {*|Array.<*>} The item, or array of items, that were successfully removed from the array. + * @property {boolean} audioData - Can this device play HTML Audio tags? + * @property {boolean} dolby - Can this device play EC-3 Dolby Digital Plus files? + * @property {boolean} m4a - Can this device can play m4a files. + * @property {boolean} aac - Can this device can play aac files. + * @property {boolean} flac - Can this device can play flac files. + * @property {boolean} mp3 - Can this device play mp3 files? + * @property {boolean} ogg - Can this device play ogg files? + * @property {boolean} opus - Can this device play opus files? + * @property {boolean} wav - Can this device play wav files? + * @property {boolean} webAudio - Does this device have the Web Audio API? + * @property {boolean} webm - Can this device play webm files? */ -var Remove = function (array, item, callback, context) -{ - if (context === undefined) { context = array; } - - var index; - - // Fast path to avoid array mutation and iteration - if (!Array.isArray(item)) - { - index = array.indexOf(item); +var Audio = { - if (index !== -1) - { - SpliceOne(array, index); + flac: false, + aac: false, + audioData: false, + dolby: false, + m4a: false, + mp3: false, + ogg: false, + opus: false, + wav: false, + webAudio: false, + webm: false - if (callback) - { - callback.call(context, item); - } +}; - return item; - } - else - { - return null; - } +function init () +{ + if (typeof importScripts === 'function') + { + return Audio; } - // If we got this far, we have an array of items to remove + Audio.audioData = !!(window['Audio']); - var itemLength = item.length - 1; - var removed = []; + Audio.webAudio = !!(window['AudioContext'] || window['webkitAudioContext']); - while (itemLength >= 0) + var audioElement = document.createElement('audio'); + var result = !!audioElement.canPlayType; + + try { - var entry = item[itemLength]; + if (result) + { + var CanPlay = function (type1, type2) + { + var canPlayType1 = audioElement.canPlayType('audio/' + type1).replace(/^no$/, ''); - index = array.indexOf(entry); + if (type2) + { + return Boolean(canPlayType1 || audioElement.canPlayType('audio/' + type2).replace(/^no$/, '')); + } + else + { + return Boolean(canPlayType1); + } + }; - if (index !== -1) - { - SpliceOne(array, index); + // wav Mimetypes accepted: + // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements - removed.push(entry); + Audio.ogg = CanPlay('ogg; codecs="vorbis"'); + Audio.opus = CanPlay('ogg; codecs="opus"', 'opus'); + Audio.mp3 = CanPlay('mpeg'); + Audio.wav = CanPlay('wav'); + Audio.m4a = CanPlay('x-m4a'); + Audio.aac = CanPlay('aac'); + Audio.flac = CanPlay('flac', 'x-flac'); + Audio.webm = CanPlay('webm; codecs="vorbis"'); - if (callback) + if (audioElement.canPlayType('audio/mp4; codecs="ec-3"') !== '') { - callback.call(context, entry); + if (Browser.edge) + { + Audio.dolby = true; + } + else if (Browser.safari && Browser.safariVersion >= 9) + { + if ((/Mac OS X (\d+)_(\d+)/).test(navigator.userAgent)) + { + var major = parseInt(RegExp.$1, 10); + var minor = parseInt(RegExp.$2, 10); + + if ((major === 10 && minor >= 11) || major > 10) + { + Audio.dolby = true; + } + } + } } } - - itemLength--; + } + catch (e) + { + // Nothing to do here } - return removed; -}; + return Audio; +} -module.exports = Remove; +module.exports = init(); /***/ }), -/* 94 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 1350: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var FromPoints = __webpack_require__(199); -var Rectangle = __webpack_require__(10); -var Vector2 = __webpack_require__(3); +var OS = __webpack_require__(36580); /** - * @classdesc - * A Base Curve class, which all other curve types extend. - * - * Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + * Determines the browser type and version running this Phaser Game instance. + * These values are read-only and populated during the boot sequence of the game. + * They are then referenced by internal game systems and are available for you to access + * via `this.sys.game.device.browser` from within any Scene. * - * @class Curve - * @memberof Phaser.Curves - * @constructor + * @typedef {object} Phaser.Device.Browser * @since 3.0.0 * - * @param {string} type - The curve type. + * @property {boolean} chrome - Set to true if running in Chrome. + * @property {boolean} edge - Set to true if running in Microsoft Edge browser. + * @property {boolean} firefox - Set to true if running in Firefox. + * @property {boolean} ie - Set to true if running in Internet Explorer 11 or less (not Edge). + * @property {boolean} mobileSafari - Set to true if running in Mobile Safari. + * @property {boolean} opera - Set to true if running in Opera. + * @property {boolean} safari - Set to true if running in Safari. + * @property {boolean} silk - Set to true if running in the Silk browser (as used on the Amazon Kindle) + * @property {boolean} trident - Set to true if running a Trident version of Internet Explorer (IE11+) + * @property {number} chromeVersion - If running in Chrome this will contain the major version number. + * @property {number} firefoxVersion - If running in Firefox this will contain the major version number. + * @property {number} ieVersion - If running in Internet Explorer this will contain the major version number. Beyond IE10 you should use Browser.trident and Browser.tridentVersion. + * @property {number} safariVersion - If running in Safari this will contain the major version number. + * @property {number} tridentVersion - If running in Internet Explorer 11 this will contain the major version number. See {@link http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx} */ -var Curve = new Class({ - - initialize: - - function Curve (type) - { - /** - * String based identifier for the type of curve. - * - * @name Phaser.Curves.Curve#type - * @type {string} - * @since 3.0.0 - */ - this.type = type; - - /** - * The default number of divisions within the curve. - * - * @name Phaser.Curves.Curve#defaultDivisions - * @type {number} - * @default 5 - * @since 3.0.0 - */ - this.defaultDivisions = 5; - - /** - * The quantity of arc length divisions within the curve. - * - * @name Phaser.Curves.Curve#arcLengthDivisions - * @type {number} - * @default 100 - * @since 3.0.0 - */ - this.arcLengthDivisions = 100; - - /** - * An array of cached arc length values. - * - * @name Phaser.Curves.Curve#cacheArcLengths - * @type {number[]} - * @default [] - * @since 3.0.0 - */ - this.cacheArcLengths = []; - - /** - * Does the data of this curve need updating? - * - * @name Phaser.Curves.Curve#needsUpdate - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.needsUpdate = true; +var Browser = { - /** - * For a curve on a Path, `false` means the Path will ignore this curve. - * - * @name Phaser.Curves.Curve#active - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.active = true; + chrome: false, + chromeVersion: 0, + edge: false, + firefox: false, + firefoxVersion: 0, + ie: false, + ieVersion: 0, + mobileSafari: false, + opera: false, + safari: false, + safariVersion: 0, + silk: false, + trident: false, + tridentVersion: 0, + es2019: false - /** - * A temporary calculation Vector. - * - * @name Phaser.Curves.Curve#_tmpVec2A - * @type {Phaser.Math.Vector2} - * @private - * @since 3.0.0 - */ - this._tmpVec2A = new Vector2(); +}; - /** - * A temporary calculation Vector. - * - * @name Phaser.Curves.Curve#_tmpVec2B - * @type {Phaser.Math.Vector2} - * @private - * @since 3.0.0 - */ - this._tmpVec2B = new Vector2(); - }, +function init () +{ + var ua = navigator.userAgent; - /** - * 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.Curve#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. - * @param {number} [pointsTotal=32] - The resolution of the curve. The higher the value the smoother it will render, at the cost of rendering performance. - * - * @return {Phaser.GameObjects.Graphics} The Graphics object to which the curve was drawn. - */ - draw: function (graphics, pointsTotal) + if ((/Edg\/\d+/).test(ua)) { - if (pointsTotal === undefined) { pointsTotal = 32; } - - // So you can chain graphics calls - return graphics.strokePoints(this.getPoints(pointsTotal)); - }, - - /** - * Returns a Rectangle where the position and dimensions match the bounds of this Curve. - * - * You can control the accuracy of the bounds. The value given is used to work out how many points - * to plot across the curve. Higher values are more accurate at the cost of calculation speed. - * - * @method Phaser.Curves.Curve#getBounds - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} [out] - The Rectangle to store the bounds in. If falsey a new object will be created. - * @param {number} [accuracy=16] - The accuracy of the bounds calculations. - * - * @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, accuracy) + Browser.edge = true; + Browser.es2019 = true; + } + else if ((/OPR/).test(ua)) { - if (!out) { out = new Rectangle(); } - if (accuracy === undefined) { accuracy = 16; } + Browser.opera = true; + Browser.es2019 = true; + } + else if ((/Chrome\/(\d+)/).test(ua) && !OS.windowsPhone) + { + Browser.chrome = true; + Browser.chromeVersion = parseInt(RegExp.$1, 10); + Browser.es2019 = (Browser.chromeVersion > 69); + } + else if ((/Firefox\D+(\d+)/).test(ua)) + { + Browser.firefox = true; + Browser.firefoxVersion = parseInt(RegExp.$1, 10); + Browser.es2019 = (Browser.firefoxVersion > 10); + } + else if ((/AppleWebKit/).test(ua) && OS.iOS) + { + Browser.mobileSafari = true; + } + else if ((/MSIE (\d+\.\d+);/).test(ua)) + { + Browser.ie = true; + Browser.ieVersion = parseInt(RegExp.$1, 10); + } + else if ((/Version\/(\d+\.\d+) Safari/).test(ua) && !OS.windowsPhone) + { + Browser.safari = true; + Browser.safariVersion = parseInt(RegExp.$1, 10); + Browser.es2019 = (Browser.safariVersion > 10); + } + else if ((/Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/).test(ua)) + { + Browser.ie = true; + Browser.trident = true; + Browser.tridentVersion = parseInt(RegExp.$1, 10); + Browser.ieVersion = parseInt(RegExp.$3, 10); + } - var len = this.getLength(); + // Silk gets its own if clause because its ua also contains 'Safari' + if ((/Silk/).test(ua)) + { + Browser.silk = true; + } - if (accuracy > len) - { - accuracy = len / 2; - } + return Browser; +} - // The length of the curve in pixels - // So we'll have 1 spaced point per 'accuracy' pixels +module.exports = init(); - var spaced = Math.max(1, Math.round(len / accuracy)); - return FromPoints(this.getSpacedPoints(spaced), out); - }, +/***/ }), - /** - * Returns an array of points, spaced out X distance pixels apart. - * The smaller the distance, the larger the array will be. - * - * @method Phaser.Curves.Curve#getDistancePoints - * @since 3.0.0 - * - * @param {number} distance - The distance, in pixels, between each point along the curve. - * - * @return {Phaser.Geom.Point[]} An Array of Point objects. - */ - getDistancePoints: function (distance) - { - var len = this.getLength(); +/***/ 98581: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var spaced = Math.max(1, len / distance); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this.getSpacedPoints(spaced); - }, +var CanvasPool = __webpack_require__(61068); - /** - * Get a point at the end of the curve. - * - * @method Phaser.Curves.Curve#getEndPoint - * @since 3.0.0 - * - * @param {Phaser.Math.Vector2} [out] - Optional Vector object to store the result in. - * - * @return {Phaser.Math.Vector2} Vector2 containing the coordinates of the curves end point. - */ - getEndPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } +/** + * Determines the canvas features of the browser running this Phaser Game instance. + * These values are read-only and populated during the boot sequence of the game. + * They are then referenced by internal game systems and are available for you to access + * via `this.sys.game.device.canvasFeatures` from within any Scene. + * + * @typedef {object} Phaser.Device.CanvasFeatures + * @since 3.0.0 + * + * @property {boolean} supportInverseAlpha - Set to true if the browser supports inversed alpha. + * @property {boolean} supportNewBlendModes - Set to true if the browser supports new canvas blend modes. + */ +var CanvasFeatures = { - return this.getPointAt(1, out); - }, + supportInverseAlpha: false, + supportNewBlendModes: false - /** - * Get total curve arc length - * - * @method Phaser.Curves.Curve#getLength - * @since 3.0.0 - * - * @return {number} The total length of the curve. - */ - getLength: function () - { - var lengths = this.getLengths(); +}; - return lengths[lengths.length - 1]; - }, +function checkBlendMode () +{ + var pngHead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/'; + var pngEnd = 'AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=='; + var magenta = new Image(); - /** - * Get a list of cumulative segment lengths. - * - * These lengths are - * - * - [0] 0 - * - [1] The first segment - * - [2] The first and second segment - * - ... - * - [divisions] All segments - * - * @method Phaser.Curves.Curve#getLengths - * @since 3.0.0 - * - * @param {number} [divisions] - The number of divisions or segments. - * - * @return {number[]} An array of cumulative lengths. - */ - getLengths: function (divisions) + magenta.onload = function () { - if (divisions === undefined) { divisions = this.arcLengthDivisions; } + var yellow = new Image(); - if ((this.cacheArcLengths.length === divisions + 1) && !this.needsUpdate) + yellow.onload = function () { - return this.cacheArcLengths; - } - - this.needsUpdate = false; + var canvas = CanvasPool.create2D(yellow, 6); + var context = canvas.getContext('2d', { willReadFrequently: true }); - var cache = []; - var current; - var last = this.getPoint(0, this._tmpVec2A); - var sum = 0; + context.globalCompositeOperation = 'multiply'; - cache.push(0); + context.drawImage(magenta, 0, 0); + context.drawImage(yellow, 2, 0); - for (var p = 1; p <= divisions; p++) - { - current = this.getPoint(p / divisions, this._tmpVec2B); + if (!context.getImageData(2, 0, 1, 1)) + { + return false; + } - sum += current.distance(last); + var data = context.getImageData(2, 0, 1, 1).data; - cache.push(sum); + CanvasPool.remove(yellow); - last.copy(current); - } + CanvasFeatures.supportNewBlendModes = (data[0] === 255 && data[1] === 0 && data[2] === 0); + }; - this.cacheArcLengths = cache; + yellow.src = pngHead + '/wCKxvRF' + pngEnd; + }; - return cache; // { sums: cache, sum:sum }; Sum is in the last element. - }, + magenta.src = pngHead + 'AP804Oa6' + pngEnd; - // Get point at relative position in curve according to arc length + return false; +} - // - u [0 .. 1] +function checkInverseAlpha () +{ + var canvas = CanvasPool.create2D(this, 2); + var context = canvas.getContext('2d', { willReadFrequently: true }); - /** - * Get a point at a relative position on the curve, by arc length. - * - * @method Phaser.Curves.Curve#getPointAt - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} u - The relative position, [0..1]. - * @param {Phaser.Math.Vector2} [out] - A point to store the result in. - * - * @return {Phaser.Math.Vector2} The point. - */ - getPointAt: function (u, out) - { - var t = this.getUtoTmapping(u); + context.fillStyle = 'rgba(10, 20, 30, 0.5)'; - return this.getPoint(t, out); - }, + // Draw a single pixel + context.fillRect(0, 0, 1, 1); - // Get sequence of points using getPoint( t ) + // Get the color values + var s1 = context.getImageData(0, 0, 1, 1); - /** - * Get a sequence of evenly spaced points from the curve. - * - * You can pass `divisions`, `stepRate`, or neither. - * - * The number of divisions will be - * - * 1. `divisions`, if `divisions` > 0; or - * 2. `this.getLength / stepRate`, if `stepRate` > 0; or - * 3. `this.defaultDivisions` - * - * `1 + divisions` points will be returned. - * - * @method Phaser.Curves.Curve#getPoints - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2[]} O - [out,$return] - * - * @param {number} [divisions] - The number of divisions to make. - * @param {number} [stepRate] - The curve distance between points, implying `divisions`. - * @param {(array|Phaser.Math.Vector2[])} [out] - An optional array to store the points in. - * - * @return {(array|Phaser.Math.Vector2[])} An array of Points from the curve. - */ - getPoints: function (divisions, stepRate, out) + if (s1 === null) { - if (out === undefined) { out = []; } + return false; + } - // If divisions is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. - if (!divisions) - { - if (!stepRate) - { - divisions = this.defaultDivisions; - } - else - { - divisions = this.getLength() / stepRate; - } - } + // Plot them to x2 + context.putImageData(s1, 1, 0); - for (var d = 0; d <= divisions; d++) - { - out.push(this.getPoint(d / divisions)); - } + // Get those values + var s2 = context.getImageData(1, 0, 1, 1); - return out; - }, + var result = (s2.data[0] === s1.data[0] && s2.data[1] === s1.data[1] && s2.data[2] === s1.data[2] && s2.data[3] === s1.data[3]); - /** - * Get a random point from the curve. - * - * @method Phaser.Curves.Curve#getRandomPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A point object to store the result in. - * - * @return {Phaser.Math.Vector2} The point. - */ - getRandomPoint: function (out) + CanvasPool.remove(this); + + // Compare and return + return result; +} + +function init () +{ + if (typeof importScripts !== 'function' && document !== undefined) { - if (out === undefined) { out = new Vector2(); } + CanvasFeatures.supportNewBlendModes = checkBlendMode(); + CanvasFeatures.supportInverseAlpha = checkInverseAlpha(); + } - return this.getPoint(Math.random(), out); - }, + return CanvasFeatures; +} - // Get sequence of points using getPointAt( u ) +module.exports = init(); - /** - * Get a sequence of equally spaced points (by arc distance) from the curve. - * - * `1 + divisions` points will be returned. - * - * @method Phaser.Curves.Curve#getSpacedPoints - * @since 3.0.0 - * - * @param {number} [divisions=this.defaultDivisions] - The number of divisions to make. - * @param {number} [stepRate] - Step between points. Used to calculate the number of points to return when divisions is falsy. Ignored if divisions is positive. - * @param {(array|Phaser.Math.Vector2[])} [out] - An optional array to store the points in. - * - * @return {Phaser.Math.Vector2[]} An array of points. - */ - getSpacedPoints: function (divisions, stepRate, out) - { - if (out === undefined) { out = []; } - // If divisions is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. - if (!divisions) - { - if (!stepRate) - { - divisions = this.defaultDivisions; - } - else - { - divisions = this.getLength() / stepRate; - } - } +/***/ }), - for (var d = 0; d <= divisions; d++) - { - var t = this.getUtoTmapping(d / divisions, null, divisions); +/***/ 90185: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - out.push(this.getPoint(t)); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return out; - }, +var OS = __webpack_require__(36580); +var Browser = __webpack_require__(1350); +var CanvasPool = __webpack_require__(61068); - /** - * Get a point at the start of the curve. - * - * @method Phaser.Curves.Curve#getStartPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Math.Vector2} [out] - A point to store the result in. - * - * @return {Phaser.Math.Vector2} The point. - */ - getStartPoint: function (out) - { - if (out === undefined) { out = new Vector2(); } - - return this.getPointAt(0, out); - }, - - /** - * Get a unit vector tangent at a relative position on the curve. - * In case any sub curve does not implement its tangent derivation, - * 2 points a small delta apart will be used to find its gradient - * which seems to give a reasonable approximation - * - * @method Phaser.Curves.Curve#getTangent - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} t - The relative position on the curve, [0..1]. - * @param {Phaser.Math.Vector2} [out] - A vector to store the result in. - * - * @return {Phaser.Math.Vector2} Vector approximating the tangent line at the point t (delta +/- 0.0001) - */ - getTangent: function (t, out) - { - if (out === undefined) { out = new Vector2(); } - - var delta = 0.0001; - var t1 = t - delta; - var t2 = t + delta; - - // Capping in case of danger +/** + * Determines the features of the browser running this Phaser Game instance. + * These values are read-only and populated during the boot sequence of the game. + * They are then referenced by internal game systems and are available for you to access + * via `this.sys.game.device.features` from within any Scene. + * + * @typedef {object} Phaser.Device.Features + * @since 3.0.0 + * + * @property {boolean} canvas - Is canvas available? + * @property {?boolean} canvasBitBltShift - True if canvas supports a 'copy' bitblt onto itself when the source and destination regions overlap. + * @property {boolean} file - Is file available? + * @property {boolean} fileSystem - Is fileSystem available? + * @property {boolean} getUserMedia - Does the device support the getUserMedia API? + * @property {boolean} littleEndian - Is the device big or little endian? (only detected if the browser supports TypedArrays) + * @property {boolean} localStorage - Is localStorage available? + * @property {boolean} pointerLock - Is Pointer Lock available? + * @property {boolean} stableSort - Is Array.sort stable? + * @property {boolean} support32bit - Does the device context support 32bit pixel manipulation using array buffer views? + * @property {boolean} vibration - Does the device support the Vibration API? + * @property {boolean} webGL - Is webGL available? + * @property {boolean} worker - Is worker available? + */ +var Features = { - if (t1 < 0) - { - t1 = 0; - } + canvas: false, + canvasBitBltShift: null, + file: false, + fileSystem: false, + getUserMedia: true, + littleEndian: false, + localStorage: false, + pointerLock: false, + stableSort: false, + support32bit: false, + vibration: false, + webGL: false, + worker: false - if (t2 > 1) - { - t2 = 1; - } +}; - this.getPoint(t1, this._tmpVec2A); - this.getPoint(t2, out); +// Check Little or Big Endian system. +// @author Matt DesLauriers (@mattdesl) +function checkIsLittleEndian () +{ + var a = new ArrayBuffer(4); + var b = new Uint8Array(a); + var c = new Uint32Array(a); - return out.subtract(this._tmpVec2A).normalize(); - }, + b[0] = 0xa1; + b[1] = 0xb2; + b[2] = 0xc3; + b[3] = 0xd4; - /** - * Get a unit vector tangent at a relative position on the curve, by arc length. - * - * @method Phaser.Curves.Curve#getTangentAt - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {number} u - The relative position on the curve, [0..1]. - * @param {Phaser.Math.Vector2} [out] - A vector to store the result in. - * - * @return {Phaser.Math.Vector2} The tangent vector. - */ - getTangentAt: function (u, out) + if (c[0] === 0xd4c3b2a1) { - var t = this.getUtoTmapping(u); + return true; + } - return this.getTangent(t, out); - }, + if (c[0] === 0xa1b2c3d4) + { + return false; + } + else + { + // Could not determine endianness + return null; + } +} - /** - * Given a distance in pixels, get a t to find p. - * - * @method Phaser.Curves.Curve#getTFromDistance - * @since 3.0.0 - * - * @param {number} distance - The distance, in pixels. - * @param {number} [divisions] - Optional amount of divisions. - * - * @return {number} The distance. - */ - getTFromDistance: function (distance, divisions) +function init () +{ + if (typeof importScripts === 'function') { - if (distance <= 0) - { - return 0; - } + return Features; + } - return this.getUtoTmapping(0, distance, divisions); - }, + Features.canvas = !!window['CanvasRenderingContext2D']; - /** - * Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant. - * - * @method Phaser.Curves.Curve#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) + try { - var arcLengths = this.getLengths(divisions); + Features.localStorage = !!localStorage.getItem; + } + catch (error) + { + Features.localStorage = false; + } - var i = 0; - var il = arcLengths.length; + Features.file = !!window['File'] && !!window['FileReader'] && !!window['FileList'] && !!window['Blob']; + Features.fileSystem = !!window['requestFileSystem']; - var targetArcLength; // The targeted u distance value to get + var isUint8 = false; - if (distance) - { - // Cannot overshoot the curve - targetArcLength = Math.min(distance, arcLengths[il - 1]); - } - else + var testWebGL = function () + { + if (window['WebGLRenderingContext']) { - targetArcLength = u * arcLengths[il - 1]; - } + try + { + var canvas = CanvasPool.createWebGL(this); - // binary search for the index with largest value smaller than target u distance + var ctx = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); - var low = 0; - var high = il - 1; - var comparison; + var canvas2D = CanvasPool.create2D(this); - while (low <= high) - { - i = Math.floor(low + (high - low) / 2); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats + var ctx2D = canvas2D.getContext('2d', { willReadFrequently: true }); - comparison = arcLengths[i] - targetArcLength; + // Can't be done on a webgl context + var image = ctx2D.createImageData(1, 1); - if (comparison < 0) - { - low = i + 1; - } - else if (comparison > 0) - { - high = i - 1; + // Test to see if ImageData uses CanvasPixelArray or Uint8ClampedArray. + // @author Matt DesLauriers (@mattdesl) + isUint8 = image.data instanceof Uint8ClampedArray; + + CanvasPool.remove(canvas); + CanvasPool.remove(canvas2D); + + return !!ctx; } - else + catch (e) { - high = i; - break; + return false; } } - i = high; + return false; + }; - if (arcLengths[i] === targetArcLength) - { - return i / (il - 1); - } + Features.webGL = testWebGL(); - // we could get finer grain at lengths, or use simple interpolation between two points + Features.worker = !!window['Worker']; - var lengthBefore = arcLengths[i]; - var lengthAfter = arcLengths[i + 1]; + Features.pointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document; - var segmentLength = lengthAfter - lengthBefore; + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia; - // determine where we are between the 'before' and 'after' points + window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL; - var segmentFraction = (targetArcLength - lengthBefore) / segmentLength; + Features.getUserMedia = Features.getUserMedia && !!navigator.getUserMedia && !!window.URL; - // add that fractional amount to t + // Older versions of firefox (< 21) apparently claim support but user media does not actually work + if (Browser.firefox && Browser.firefoxVersion < 21) + { + Features.getUserMedia = false; + } - return (i + segmentFraction) / (il - 1); - }, + // Excludes iOS versions as they generally wrap UIWebView (eg. Safari WebKit) and it + // is safer to not try and use the fast copy-over method. + if (!OS.iOS && (Browser.ie || Browser.firefox || Browser.chrome)) + { + Features.canvasBitBltShift = true; + } - /** - * Calculate and cache the arc lengths. - * - * @method Phaser.Curves.Curve#updateArcLengths - * @since 3.0.0 - * - * @see Phaser.Curves.Curve#getLengths() - */ - updateArcLengths: function () + // Known not to work + if (Browser.safari || Browser.mobileSafari) { - this.needsUpdate = true; + Features.canvasBitBltShift = false; + } - this.getLengths(); + navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate; + + if (navigator.vibrate) + { + Features.vibration = true; } -}); + if (typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined' && typeof Uint32Array !== 'undefined') + { + Features.littleEndian = checkIsLittleEndian(); + } -module.exports = Curve; + Features.support32bit = ( + typeof ArrayBuffer !== 'undefined' && + typeof Uint8ClampedArray !== 'undefined' && + typeof Int32Array !== 'undefined' && + Features.littleEndian !== null && + isUint8 + ); + + return Features; +} + +module.exports = init(); /***/ }), -/* 95 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 33553: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Loader.Events + * Determines the full screen support of the browser running this Phaser Game instance. + * These values are read-only and populated during the boot sequence of the game. + * They are then referenced by internal game systems and are available for you to access + * via `this.sys.game.device.fullscreen` from within any Scene. + * + * @typedef {object} Phaser.Device.Fullscreen + * @since 3.0.0 + * + * @property {boolean} available - Does the browser support the Full Screen API? + * @property {boolean} keyboard - Does the browser support access to the Keyboard during Full Screen mode? + * @property {string} cancel - If the browser supports the Full Screen API this holds the call you need to use to cancel it. + * @property {string} request - If the browser supports the Full Screen API this holds the call you need to use to activate it. */ +var Fullscreen = { -module.exports = { - - ADD: __webpack_require__(968), - COMPLETE: __webpack_require__(969), - FILE_COMPLETE: __webpack_require__(970), - FILE_KEY_COMPLETE: __webpack_require__(971), - FILE_LOAD_ERROR: __webpack_require__(972), - FILE_LOAD: __webpack_require__(973), - FILE_PROGRESS: __webpack_require__(974), - POST_PROCESS: __webpack_require__(975), - PROGRESS: __webpack_require__(976), - START: __webpack_require__(977) + available: false, + cancel: '', + keyboard: false, + request: '' }; +/** +* Checks for support of the Full Screen API. +* +* @ignore +*/ +function init () +{ + if (typeof importScripts === 'function') + { + return Fullscreen; + } + + var i; + + var suffix1 = 'Fullscreen'; + var suffix2 = 'FullScreen'; + + var fs = [ + 'request' + suffix1, + 'request' + suffix2, + 'webkitRequest' + suffix1, + 'webkitRequest' + suffix2, + 'msRequest' + suffix1, + 'msRequest' + suffix2, + 'mozRequest' + suffix2, + 'mozRequest' + suffix1 + ]; + + for (i = 0; i < fs.length; i++) + { + if (document.documentElement[fs[i]]) + { + Fullscreen.available = true; + Fullscreen.request = fs[i]; + break; + } + } + + var cfs = [ + 'cancel' + suffix2, + 'exit' + suffix1, + 'webkitCancel' + suffix2, + 'webkitExit' + suffix1, + 'msCancel' + suffix2, + 'msExit' + suffix1, + 'mozCancel' + suffix2, + 'mozExit' + suffix1 + ]; + + if (Fullscreen.available) + { + for (i = 0; i < cfs.length; i++) + { + if (document[cfs[i]]) + { + Fullscreen.cancel = cfs[i]; + break; + } + } + } + + // Keyboard Input? + // Safari 5.1 says it supports fullscreen keyboard, but is lying. + if (window['Element'] && Element['ALLOW_KEYBOARD_INPUT'] && !(/ Version\/5\.1(?:\.\d+)? Safari\//).test(navigator.userAgent)) + { + Fullscreen.keyboard = true; + } + + Object.defineProperty(Fullscreen, 'active', { get: function () { return !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement); } }); + + return Fullscreen; +} + +module.exports = init(); + /***/ }), -/* 96 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 95872: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Point = __webpack_require__(4); - -// This is based off an explanation and expanded math presented by Paul Bourke: -// See http:'local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ +var Browser = __webpack_require__(1350); /** - * Checks if two Lines intersect. If the Lines are identical, they will be treated as parallel and thus non-intersecting. + * Determines the input support of the browser running this Phaser Game instance. + * These values are read-only and populated during the boot sequence of the game. + * They are then referenced by internal game systems and are available for you to access + * via `this.sys.game.device.input` from within any Scene. * - * @function Phaser.Geom.Intersects.LineToLine + * @typedef {object} Phaser.Device.Input * @since 3.0.0 * - * @param {Phaser.Geom.Line} line1 - The first Line to check. - * @param {Phaser.Geom.Line} line2 - The second Line to check. - * @param {Phaser.Geom.Point} [out] - A Point in which to optionally store the point of intersection. - * - * @return {boolean} `true` if the two Lines intersect, and the `out` object will be populated, if given. Otherwise, `false`. + * @property {?string} wheelType - The newest type of Wheel/Scroll event supported: 'wheel', 'mousewheel', 'DOMMouseScroll' + * @property {boolean} gamepads - Is navigator.getGamepads available? + * @property {boolean} mspointer - Is mspointer available? + * @property {boolean} touch - Is touch available? */ -var LineToLine = function (line1, line2, out) -{ - if (out === undefined) { out = new Point(); } - - 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 Input = { - var numA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); - var numB = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); - var deNom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); + gamepads: false, + mspointer: false, + touch: false, + wheelEvent: null - // 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 (deNom === 0) +function init () +{ + if (typeof importScripts === 'function') { - return false; + return Input; } - // Calculate the intermediate fractional point that the lines potentially intersect. - - var uA = numA / deNom; - var uB = numB / deNom; + if ('ontouchstart' in document.documentElement || (navigator.maxTouchPoints && navigator.maxTouchPoints >= 1)) + { + Input.touch = true; + } - // The fractional point will be between 0 and 1 inclusive if the lines intersect. - // If the fractional calculation is larger than 1 or smaller than 0 the lines would need to be longer to intersect. + if (navigator.msPointerEnabled || navigator.pointerEnabled) + { + Input.mspointer = true; + } - if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) + if (navigator.getGamepads) { - out.x = x1 + (uA * (x2 - x1)); - out.y = y1 + (uA * (y2 - y1)); + Input.gamepads = true; + } - return true; + // See https://developer.mozilla.org/en-US/docs/Web/Events/wheel + if ('onwheel' in window || (Browser.ie && 'WheelEvent' in window)) + { + // DOM3 Wheel Event: FF 17+, IE 9+, Chrome 31+, Safari 7+ + Input.wheelEvent = 'wheel'; + } + else if ('onmousewheel' in window) + { + // Non-FF legacy: IE 6-9, Chrome 1-31, Safari 5-7. + Input.wheelEvent = 'mousewheel'; + } + else if (Browser.firefox && 'MouseScrollEvent' in window) + { + // FF prior to 17. This should probably be scrubbed. + Input.wheelEvent = 'DOMMouseScroll'; } - return false; -}; + return Input; +} -module.exports = LineToLine; +module.exports = init(); /***/ }), -/* 97 */ -/***/ (function(module, exports) { + +/***/ 36580: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Calculate the angle of the line in radians. + * Determines the operating system of the device running this Phaser Game instance. + * These values are read-only and populated during the boot sequence of the game. + * They are then referenced by internal game systems and are available for you to access + * via `this.sys.game.device.os` from within any Scene. * - * @function Phaser.Geom.Line.Angle + * @typedef {object} Phaser.Device.OS * @since 3.0.0 * - * @param {Phaser.Geom.Line} line - The line to calculate the angle of. - * - * @return {number} The angle of the line, in radians. + * @property {boolean} android - Is running on android? + * @property {boolean} chromeOS - Is running on chromeOS? + * @property {boolean} cordova - Is the game running under Apache Cordova? + * @property {boolean} crosswalk - Is the game running under the Intel Crosswalk XDK? + * @property {boolean} desktop - Is running on a desktop? + * @property {boolean} ejecta - Is the game running under Ejecta? + * @property {boolean} electron - Is the game running under GitHub Electron? + * @property {boolean} iOS - Is running on iOS? + * @property {boolean} iPad - Is running on iPad? + * @property {boolean} iPhone - Is running on iPhone? + * @property {boolean} kindle - Is running on an Amazon Kindle? + * @property {boolean} linux - Is running on linux? + * @property {boolean} macOS - Is running on macOS? + * @property {boolean} node - Is the game running under Node.js? + * @property {boolean} nodeWebkit - Is the game running under Node-Webkit? + * @property {boolean} webApp - Set to true if running as a WebApp, i.e. within a WebView + * @property {boolean} windows - Is running on windows? + * @property {boolean} windowsPhone - Is running on a Windows Phone? + * @property {number} iOSVersion - If running in iOS this will contain the major version number. + * @property {number} pixelRatio - PixelRatio of the host device? */ -var Angle = function (line) -{ - return Math.atan2(line.y2 - line.y1, line.x2 - line.x1); +var OS = { + + android: false, + chromeOS: false, + cordova: false, + crosswalk: false, + desktop: false, + ejecta: false, + electron: false, + iOS: false, + iOSVersion: 0, + iPad: false, + iPhone: false, + kindle: false, + linux: false, + macOS: false, + node: false, + nodeWebkit: false, + pixelRatio: 1, + webApp: false, + windows: false, + windowsPhone: false + }; -module.exports = Angle; +function init () +{ + if (typeof importScripts === 'function') + { + return OS; + } + var ua = navigator.userAgent; -/***/ }), -/* 98 */ -/***/ (function(module, exports, __webpack_require__) { + if ((/Windows/).test(ua)) + { + OS.windows = true; + } + else if ((/Mac OS/).test(ua) && !((/like Mac OS/).test(ua))) + { + // Because iOS 13 identifies as Mac OS: + if (navigator.maxTouchPoints && navigator.maxTouchPoints > 2) + { + OS.iOS = true; + OS.iPad = true; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + (navigator.appVersion).match(/Version\/(\d+)/); -var Clamp = __webpack_require__(18); + OS.iOSVersion = parseInt(RegExp.$1, 10); + } + else + { + OS.macOS = true; + } + } + else if ((/Android/).test(ua)) + { + OS.android = true; + } + else if ((/Linux/).test(ua)) + { + OS.linux = true; + } + else if ((/iP[ao]d|iPhone/i).test(ua)) + { + OS.iOS = true; -/** - * Return a value based on the range between `min` and `max` and the percentage given. - * - * @function Phaser.Math.FromPercent - * @since 3.0.0 - * - * @param {number} percent - A value between 0 and 1 representing the percentage. - * @param {number} min - The minimum value. - * @param {number} [max] - The maximum value. - * - * @return {number} The value that is `percent` percent between `min` and `max`. - */ -var FromPercent = function (percent, min, max) -{ - percent = Clamp(percent, 0, 1); + (navigator.appVersion).match(/OS (\d+)/); - return (max - min) * percent + min; -}; + OS.iOSVersion = parseInt(RegExp.$1, 10); -module.exports = FromPercent; + OS.iPhone = ua.toLowerCase().indexOf('iphone') !== -1; + OS.iPad = ua.toLowerCase().indexOf('ipad') !== -1; + } + else if ((/Kindle/).test(ua) || (/\bKF[A-Z][A-Z]+/).test(ua) || (/Silk.*Mobile Safari/).test(ua)) + { + OS.kindle = true; + // This will NOT detect early generations of Kindle Fire, I think there is no reliable way... + // E.g. "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-80) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true" + } + else if ((/CrOS/).test(ua)) + { + OS.chromeOS = true; + } -/***/ }), -/* 99 */ -/***/ (function(module, exports) { + if ((/Windows Phone/i).test(ua) || (/IEMobile/i).test(ua)) + { + OS.android = false; + OS.iOS = false; + OS.macOS = false; + OS.windows = true; + OS.windowsPhone = true; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var silk = (/Silk/).test(ua); -/** - * Retrieves the value of the given key from an object. - * - * @function Phaser.Tweens.Builders.GetBoolean - * @since 3.0.0 - * - * @param {object} source - The object to retrieve the value from. - * @param {string} key - The key to look for in the `source` object. - * @param {*} defaultValue - The default value to return if the `key` doesn't exist or if no `source` object is provided. - * - * @return {*} The retrieved value. - */ -var GetBoolean = function (source, key, defaultValue) -{ - if (!source) + if (OS.windows || OS.macOS || (OS.linux && !silk) || OS.chromeOS) { - return defaultValue; + OS.desktop = true; } - else if (source.hasOwnProperty(key)) + + // Windows Phone / Table reset + if (OS.windowsPhone || (((/Windows NT/i).test(ua)) && ((/Touch/i).test(ua)))) { - return source[key]; + OS.desktop = false; } - else + + // WebApp mode in iOS + if (navigator.standalone) { - return defaultValue; + OS.webApp = true; } -}; -module.exports = GetBoolean; + if (typeof importScripts !== 'function') + { + if (window.cordova !== undefined) + { + OS.cordova = true; + } + + if (window.ejecta !== undefined) + { + OS.ejecta = true; + } + } + + if (typeof process !== 'undefined' && process.versions && process.versions.node) + { + OS.node = true; + } + + if (OS.node && typeof process.versions === 'object') + { + OS.nodeWebkit = !!process.versions['node-webkit']; + + OS.electron = !!process.versions.electron; + } + + if ((/Crosswalk/).test(ua)) + { + OS.crosswalk = true; + } + + OS.pixelRatio = window['devicePixelRatio'] || 1; + + return OS; +} + +module.exports = init(); /***/ }), -/* 100 */ -/***/ (function(module, exports) { + +/***/ 53861: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var TWEEN_CONST = { +var GetFastValue = __webpack_require__(72632); - /** - * TweenData state. - * - * @name Phaser.Tweens.CREATED - * @type {number} - * @since 3.0.0 - */ - CREATED: 0, +/** + * Determines the video support of the browser running this Phaser Game instance. + * + * These values are read-only and populated during the boot sequence of the game. + * + * They are then referenced by internal game systems and are available for you to access + * via `this.sys.game.device.video` from within any Scene. + * + * In Phaser 3.20 the properties were renamed to drop the 'Video' suffix. + * + * @typedef {object} Phaser.Device.Video + * @since 3.0.0 + * + * @property {boolean} h264 - Can this device play h264 mp4 video files? + * @property {boolean} hls - Can this device play hls video files? + * @property {boolean} mp4 - Can this device play h264 mp4 video files? + * @property {boolean} m4v - Can this device play m4v (typically mp4) video files? + * @property {boolean} ogg - Can this device play ogg video files? + * @property {boolean} vp9 - Can this device play vp9 video files? + * @property {boolean} webm - Can this device play webm video files? + * @property {function} getVideoURL - Returns the first video URL that can be played by this browser. + */ +var Video = { - /** - * TweenData state. - * - * @name Phaser.Tweens.INIT - * @type {number} - * @since 3.0.0 - */ - INIT: 1, + h264: false, + hls: false, + mp4: false, + m4v: false, + ogg: false, + vp9: false, + webm: false, + hasRequestVideoFrame: false - /** - * TweenData state. - * - * @name Phaser.Tweens.DELAY - * @type {number} - * @since 3.0.0 - */ - DELAY: 2, +}; - /** - * TweenData state. - * - * @name Phaser.Tweens.OFFSET_DELAY - * @type {number} - * @since 3.0.0 - */ - OFFSET_DELAY: 3, +function init () +{ + if (typeof importScripts === 'function') + { + return Video; + } - /** - * TweenData state. - * - * @name Phaser.Tweens.PENDING_RENDER - * @type {number} - * @since 3.0.0 - */ - PENDING_RENDER: 4, + var videoElement = document.createElement('video'); + var result = !!videoElement.canPlayType; + var no = /^no$/; - /** - * TweenData state. - * - * @name Phaser.Tweens.PLAYING_FORWARD - * @type {number} - * @since 3.0.0 - */ - PLAYING_FORWARD: 5, + try + { + if (result) + { + if (videoElement.canPlayType('video/ogg; codecs="theora"').replace(no, '')) + { + Video.ogg = true; + } - /** - * TweenData state. - * - * @name Phaser.Tweens.PLAYING_BACKWARD - * @type {number} - * @since 3.0.0 - */ - PLAYING_BACKWARD: 6, + if (videoElement.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(no, '')) + { + // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546 + Video.h264 = true; + Video.mp4 = true; + } - /** - * TweenData state. - * - * @name Phaser.Tweens.HOLD_DELAY - * @type {number} - * @since 3.0.0 - */ - HOLD_DELAY: 7, + if (videoElement.canPlayType('video/x-m4v').replace(no, '')) + { + Video.m4v = true; + } - /** - * TweenData state. - * - * @name Phaser.Tweens.REPEAT_DELAY - * @type {number} - * @since 3.0.0 - */ - REPEAT_DELAY: 8, + if (videoElement.canPlayType('video/webm; codecs="vp8, vorbis"').replace(no, '')) + { + Video.webm = true; + } - /** - * TweenData state. - * - * @name Phaser.Tweens.COMPLETE - * @type {number} - * @since 3.0.0 - */ - COMPLETE: 9, + if (videoElement.canPlayType('video/webm; codecs="vp9"').replace(no, '')) + { + Video.vp9 = true; + } - // Tween specific (starts from 20 to cleanly allow extra TweenData consts in the future) + if (videoElement.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(no, '')) + { + Video.hls = true; + } + } + } + catch (e) + { + // Nothing to do + } - /** - * Tween state. - * - * @name Phaser.Tweens.PENDING_ADD - * @type {number} - * @since 3.0.0 - */ - PENDING_ADD: 20, + if (videoElement.parentNode) + { + videoElement.parentNode.removeChild(videoElement); + } - /** - * Tween state. - * - * @name Phaser.Tweens.PAUSED - * @type {number} - * @since 3.0.0 - */ - PAUSED: 21, + Video.getVideoURL = function (urls) + { + if (!Array.isArray(urls)) + { + urls = [ urls ]; + } - /** - * Tween state. - * - * @name Phaser.Tweens.LOOP_DELAY - * @type {number} - * @since 3.0.0 - */ - LOOP_DELAY: 22, + for (var i = 0; i < urls.length; i++) + { + var url = GetFastValue(urls[i], 'url', urls[i]); - /** - * Tween state. - * - * @name Phaser.Tweens.ACTIVE - * @type {number} - * @since 3.0.0 - */ - ACTIVE: 23, + if (url.indexOf('blob:') === 0) + { + return { + url: url, + type: '' + }; + } - /** - * Tween state. - * - * @name Phaser.Tweens.COMPLETE_DELAY - * @type {number} - * @since 3.0.0 - */ - COMPLETE_DELAY: 24, + var videoType; - /** - * Tween state. - * - * @name Phaser.Tweens.PENDING_REMOVE - * @type {number} - * @since 3.0.0 - */ - PENDING_REMOVE: 25, + if (url.indexOf('data:') === 0) + { + videoType = url.split(',')[0].match(/\/(.*?);/); + } + else + { + videoType = url.match(/\.([a-zA-Z0-9]+)($|\?)/); + } - /** - * Tween state. - * - * @name Phaser.Tweens.REMOVED - * @type {number} - * @since 3.0.0 - */ - REMOVED: 26 + videoType = GetFastValue(urls[i], 'type', (videoType) ? videoType[1] : '').toLowerCase(); -}; + if (Video[videoType]) + { + return { + url: url, + type: videoType + }; + } + } -module.exports = TWEEN_CONST; + return null; + }; + + return Video; +} + +module.exports = init(); /***/ }), -/* 101 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 77290: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Events = __webpack_require__(315); +// This singleton is instantiated as soon as Phaser loads, +// before a Phaser.Game instance has even been created. +// Which means all instances of Phaser Games can share it, +// without having to re-poll the device all over again + +/** + * @namespace Phaser.Device + * @since 3.0.0 + */ /** - * @callback DataEachCallback + * @typedef {object} Phaser.DeviceConf * - * @param {*} parent - The parent object of the DataManager. - * @param {string} key - The key of the value. - * @param {*} value - The value. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data. + * @property {Phaser.Device.OS} os - The OS Device functions. + * @property {Phaser.Device.Browser} browser - The Browser Device functions. + * @property {Phaser.Device.Features} features - The Features Device functions. + * @property {Phaser.Device.Input} input - The Input Device functions. + * @property {Phaser.Device.Audio} audio - The Audio Device functions. + * @property {Phaser.Device.Video} video - The Video Device functions. + * @property {Phaser.Device.Fullscreen} fullscreen - The Fullscreen Device functions. + * @property {Phaser.Device.CanvasFeatures} canvasFeatures - The Canvas Device functions. + */ + +module.exports = { + + os: __webpack_require__(36580), + browser: __webpack_require__(1350), + features: __webpack_require__(90185), + input: __webpack_require__(95872), + audio: __webpack_require__(10720), + video: __webpack_require__(53861), + fullscreen: __webpack_require__(33553), + canvasFeatures: __webpack_require__(98581) + +}; + + +/***/ }), + +/***/ 65246: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); + +var tempMatrix = new Float32Array(20); + /** * @classdesc - * The Data Manager Component features a means to store pieces of data specific to a Game Object, System or Plugin. - * You can then search, query it, and retrieve the data. The parent must either extend EventEmitter, - * or have a property called `events` that is an instance of it. + * 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. * - * @class DataManager - * @memberof Phaser.Data - * @constructor - * @since 3.0.0 + * Use the method `getData` to return a Float32Array containing the current color values. * - * @param {object} parent - The object that this DataManager belongs to. - * @param {Phaser.Events.EventEmitter} [eventEmitter] - The DataManager's event emitter. + * @class ColorMatrix + * @memberof Phaser.Display + * @constructor + * @since 3.50.0 */ -var DataManager = new Class({ +var ColorMatrix = new Class({ initialize: - function DataManager (parent, eventEmitter) + function ColorMatrix () { /** - * The object that this DataManager belongs to. + * Internal ColorMatrix array. * - * @name Phaser.Data.DataManager#parent - * @type {*} - * @since 3.0.0 + * @name Phaser.Display.ColorMatrix#_matrix + * @type {Float32Array} + * @private + * @since 3.50.0 */ - this.parent = parent; + this._matrix = new Float32Array(20); /** - * The DataManager's event emitter. + * 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.Data.DataManager#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 + * @name Phaser.Display.ColorMatrix#alpha + * @type {number} + * @since 3.50.0 */ - this.events = eventEmitter; - - if (!eventEmitter) - { - this.events = (parent.events) ? parent.events : parent; - } + this.alpha = 1; /** - * The data list. + * Is the ColorMatrix array dirty? * - * @name Phaser.Data.DataManager#list - * @type {Object.} - * @default {} - * @since 3.0.0 + * @name Phaser.Display.ColorMatrix#_dirty + * @type {boolean} + * @private + * @since 3.50.0 */ - this.list = {}; + this._dirty = true; /** - * The public values list. You can use this to access anything you have stored - * in this Data Manager. For example, if you set a value called `gold` you can - * access it via: - * - * ```javascript - * this.data.values.gold; - * ``` - * - * You can also modify it directly: - * - * ```javascript - * this.data.values.gold += 1000; - * ``` - * - * Doing so will emit a `setdata` event from the parent of this Data Manager. - * - * Do not modify this object directly. Adding properties directly to this object will not - * emit any events. Always use `DataManager.set` to create new items the first time around. + * The matrix data as a Float32Array. * - * @name Phaser.Data.DataManager#values - * @type {Object.} - * @default {} - * @since 3.10.0 - */ - this.values = {}; - - /** - * Whether setting data is frozen for this DataManager. + * Returned by the `getData` method. * - * @name Phaser.Data.DataManager#_frozen - * @type {boolean} + * @name Phaser.Display.ColorMatrix#data + * @type {Float32Array} * @private - * @default false - * @since 3.0.0 + * @since 3.50.0 */ - this._frozen = false; + this._data = new Float32Array(20); - if (!parent.hasOwnProperty('sys') && this.events) - { - this.events.once(Events.DESTROY, this.destroy, this); - } + this.reset(); }, /** - * Retrieves the value for the given key, or undefined if it doesn't exist. - * - * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: - * - * ```javascript - * this.data.get('gold'); - * ``` - * - * Or access the value directly: - * - * ```javascript - * this.data.values.gold; - * ``` - * - * You can also pass in an array of keys, in which case an array of values will be returned: - * - * ```javascript - * this.data.get([ 'gold', 'armor', 'health' ]); - * ``` - * - * This approach is useful for destructuring arrays in ES6. + * Sets this ColorMatrix from the given array of color values. * - * @method Phaser.Data.DataManager#get - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#set + * @since 3.50.0 * - * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys. + * @param {(number[]|Float32Array)} value - The ColorMatrix values to set. Must have 20 elements. * - * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array. + * @return {this} This ColorMatrix instance. */ - get: function (key) + set: function (value) { - var list = this.list; - - if (Array.isArray(key)) - { - var output = []; + this._matrix.set(value); - for (var i = 0; i < key.length; i++) - { - output.push(list[key[i]]); - } + this._dirty = true; - return output; - } - else - { - return list[key]; - } + return this; }, /** - * Retrieves all data values in a new object. + * Resets the ColorMatrix to default values and also resets + * the `alpha` property back to 1. * - * @method Phaser.Data.DataManager#getAll - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#reset + * @since 3.50.0 * - * @return {Object.} All data values. + * @return {this} This ColorMatrix instance. */ - getAll: function () + reset: function () { - var results = {}; + var m = this._matrix; - for (var key in this.list) - { - if (this.list.hasOwnProperty(key)) - { - results[key] = this.list[key]; - } - } + m.fill(0); - return results; + m[0] = 1; + m[6] = 1; + m[12] = 1; + m[18] = 1; + + this.alpha = 1; + + this._dirty = true; + + return this; }, /** - * Queries the DataManager for the values of keys matching the given regular expression. + * Gets the ColorMatrix as a Float32Array. * - * @method Phaser.Data.DataManager#query - * @since 3.0.0 + * Can be used directly as a 1fv shader uniform value. * - * @param {RegExp} search - A regular expression object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj). + * @method Phaser.Display.ColorMatrix#getData + * @since 3.50.0 * - * @return {Object.} The values of the keys matching the search string. + * @return {Float32Array} The ColorMatrix as a Float32Array. */ - query: function (search) + getData: function () { - var results = {}; + var data = this._data; - for (var key in this.list) + if (this._dirty) { - if (this.list.hasOwnProperty(key) && key.match(search)) - { - results[key] = this.list[key]; - } + data.set(this._matrix); + + data[4] /= 255; + data[9] /= 255; + data[14] /= 255; + data[19] /= 255; + + this._dirty = false; } - return results; + return data; }, /** - * Sets a value for the given key. If the key doesn't already exist in the Data Manager then it is created. - * - * ```javascript - * data.set('name', 'Red Gem Stone'); - * ``` - * - * You can also pass in an object of key value pairs as the first argument: - * - * ```javascript - * data.set({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); - * ``` - * - * To get a value back again you can call `get`: - * - * ```javascript - * data.get('gold'); - * ``` - * - * Or you can access the value directly via the `values` property, where it works like any other variable: - * - * ```javascript - * data.values.gold += 50; - * ``` - * - * When the value is first set, a `setdata` event is emitted. - * - * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. - * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. - * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. - * - * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. - * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. + * Changes the brightness of this ColorMatrix by the given amount. * - * @method Phaser.Data.DataManager#set - * @fires Phaser.Data.Events#SET_DATA - * @fires Phaser.Data.Events#CHANGE_DATA - * @fires Phaser.Data.Events#CHANGE_DATA_KEY - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#brightness + * @since 3.50.0 * - * @param {(string|object)} key - The key to set the value for. Or an object or key value pairs. If an object the `data` argument is ignored. - * @param {*} data - The value to set for the given key. If an object is provided as the key this argument is ignored. + * @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 DataManager object. + * @return {this} This ColorMatrix instance. */ - set: function (key, data) + brightness: function (value, multiply) { - if (this._frozen) - { - return this; - } + if (value === undefined) { value = 0; } + if (multiply === undefined) { multiply = false; } - if (typeof key === 'string') - { - return this.setValue(key, data); - } - else - { - for (var entry in key) - { - this.setValue(entry, key[entry]); - } - } + var b = value; - return this; + return this.multiply([ + b, 0, 0, 0, 0, + 0, b, 0, 0, 0, + 0, 0, b, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); }, /** - * Increase a value for the given key. If the key doesn't already exist in the Data Manager then it is increased from 0. - * - * When the value is first set, a `setdata` event is emitted. + * Changes the saturation of this ColorMatrix by the given amount. * - * @method Phaser.Data.DataManager#inc - * @fires Phaser.Data.Events#SET_DATA - * @fires Phaser.Data.Events#CHANGE_DATA - * @fires Phaser.Data.Events#CHANGE_DATA_KEY - * @since 3.23.0 + * @method Phaser.Display.ColorMatrix#saturate + * @since 3.50.0 * - * @param {(string|object)} key - The key to increase the value for. - * @param {*} [data] - The value to increase for the given key. + * @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 {Phaser.Data.DataManager} This DataManager object. + * @return {this} This ColorMatrix instance. */ - inc: function (key, data) + saturate: function (value, multiply) { - if (this._frozen) - { - return this; - } - - if (data === undefined) - { - data = 1; - } - - var value = this.get(key); - if (value === undefined) - { - value = 0; - } + if (value === undefined) { value = 0; } + if (multiply === undefined) { multiply = false; } - this.set(key, (value + data)); + var x = (value * 2 / 3) + 1; + var y = ((x - 1) * -0.5); - return this; + return this.multiply([ + x, y, y, 0, 0, + y, x, y, 0, 0, + y, y, x, 0, 0, + 0, 0, 0, 1, 0 + ], multiply); }, /** - * Toggle a boolean value for the given key. If the key doesn't already exist in the Data Manager then it is toggled from false. - * - * When the value is first set, a `setdata` event is emitted. + * Desaturates this ColorMatrix (removes color from it). * - * @method Phaser.Data.DataManager#toggle - * @fires Phaser.Data.Events#SET_DATA - * @fires Phaser.Data.Events#CHANGE_DATA - * @fires Phaser.Data.Events#CHANGE_DATA_KEY - * @since 3.23.0 + * @method Phaser.Display.ColorMatrix#saturation + * @since 3.50.0 * - * @param {(string|object)} key - The key to toggle the value for. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? * - * @return {Phaser.Data.DataManager} This DataManager object. + * @return {this} This ColorMatrix instance. */ - toggle: function (key) + desaturate: function (multiply) { - if (this._frozen) - { - return this; - } - - this.set(key, !this.get(key)); + if (multiply === undefined) { multiply = false; } - return this; + return this.saturate(-1, multiply); }, /** - * Internal value setter, called automatically by the `set` method. + * Rotates the hues of this ColorMatrix by the value given. * - * @method Phaser.Data.DataManager#setValue - * @fires Phaser.Data.Events#SET_DATA - * @fires Phaser.Data.Events#CHANGE_DATA - * @fires Phaser.Data.Events#CHANGE_DATA_KEY - * @private - * @since 3.10.0 + * @method Phaser.Display.ColorMatrix#hue + * @since 3.50.0 * - * @param {string} key - The key to set the value for. - * @param {*} data - The value to set. + * @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 DataManager object. + * @return {this} This ColorMatrix instance. */ - setValue: function (key, data) + hue: function (rotation, multiply) { - if (this._frozen) - { - return this; - } - - if (this.has(key)) - { - // Hit the key getter, which will in turn emit the events. - this.values[key] = data; - } - else - { - var _this = this; - var list = this.list; - var events = this.events; - var parent = this.parent; - - Object.defineProperty(this.values, key, { - - enumerable: true, - - configurable: true, - - get: function () - { - return list[key]; - }, - - set: function (value) - { - if (!_this._frozen) - { - var previousValue = list[key]; - list[key] = value; - - events.emit(Events.CHANGE_DATA, parent, key, value, previousValue); - events.emit(Events.CHANGE_DATA_KEY + key, parent, value, previousValue); - } - } - - }); + if (rotation === undefined) { rotation = 0; } + if (multiply === undefined) { multiply = false; } - list[key] = data; + rotation = rotation / 180 * Math.PI; - events.emit(Events.SET_DATA, parent, key, data); - } + var cos = Math.cos(rotation); + var sin = Math.sin(rotation); + var lumR = 0.213; + var lumG = 0.715; + var lumB = 0.072; - return this; + 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); }, /** - * Passes all data entries to the given callback. + * Sets this ColorMatrix to be grayscale. * - * @method Phaser.Data.DataManager#each - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#grayscale + * @since 3.50.0 * - * @param {DataEachCallback} callback - The function to call. - * @param {*} [context] - Value to use as `this` when executing callback. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data. + * @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 DataManager object. + * @return {this} This ColorMatrix instance. */ - each: function (callback, context) + grayscale: function (value, multiply) { - var args = [ this.parent, null, undefined ]; - - for (var i = 1; i < arguments.length; i++) - { - args.push(arguments[i]); - } + if (value === undefined) { value = 1; } + if (multiply === undefined) { multiply = false; } - for (var key in this.list) - { - args[1] = key; - args[2] = this.list[key]; + return this.saturate(-value, multiply); + }, - callback.apply(context, args); - } + /** + * 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; + return this.multiply(ColorMatrix.BLACK_WHITE, multiply); }, /** - * Merge the given object of key value pairs into this DataManager. - * - * Any newly created values will emit a `setdata` event. Any updated values (see the `overwrite` argument) - * will emit a `changedata` event. + * Change the contrast of this ColorMatrix by the amount given. * - * @method Phaser.Data.DataManager#merge - * @fires Phaser.Data.Events#SET_DATA - * @fires Phaser.Data.Events#CHANGE_DATA - * @fires Phaser.Data.Events#CHANGE_DATA_KEY - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#contrast + * @since 3.50.0 * - * @param {Object.} data - The data to merge. - * @param {boolean} [overwrite=true] - Whether to overwrite existing data. Defaults to true. + * @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 DataManager object. + * @return {this} This ColorMatrix instance. */ - merge: function (data, overwrite) + contrast: function (value, multiply) { - if (overwrite === undefined) { overwrite = true; } + if (value === undefined) { value = 0; } + if (multiply === undefined) { multiply = false; } - // Merge data from another component into this one - for (var key in data) - { - if (data.hasOwnProperty(key) && (overwrite || (!overwrite && !this.has(key)))) - { - this.setValue(key, data[key]); - } - } + var v = value + 1; + var o = -0.5 * (v - 1); - return this; + return this.multiply([ + v, 0, 0, 0, o, + 0, v, 0, 0, o, + 0, 0, v, 0, o, + 0, 0, 0, 1, 0 + ], multiply); }, /** - * Remove the value for the given key. + * Converts this ColorMatrix to have negative values. * - * If the key is found in this Data Manager it is removed from the internal lists and a - * `removedata` event is emitted. + * @method Phaser.Display.ColorMatrix#negative + * @since 3.50.0 * - * You can also pass in an array of keys, in which case all keys in the array will be removed: + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? * - * ```javascript - * this.data.remove([ 'gold', 'armor', 'health' ]); - * ``` + * @return {this} This ColorMatrix instance. + */ + negative: function (multiply) + { + if (multiply === undefined) { multiply = false; } + + return this.multiply(ColorMatrix.NEGATIVE, multiply); + }, + + /** + * Apply a desaturated luminance to this ColorMatrix. * - * @method Phaser.Data.DataManager#remove - * @fires Phaser.Data.Events#REMOVE_DATA - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#desaturateLuminance + * @since 3.50.0 * - * @param {(string|string[])} key - The key to remove, or an array of keys to remove. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? * - * @return {this} This DataManager object. + * @return {this} This ColorMatrix instance. */ - remove: function (key) + desaturateLuminance: function (multiply) { - if (this._frozen) - { - return this; - } - - if (Array.isArray(key)) - { - for (var i = 0; i < key.length; i++) - { - this.removeValue(key[i]); - } - } - else - { - return this.removeValue(key); - } + if (multiply === undefined) { multiply = false; } - return this; + return this.multiply(ColorMatrix.DESATURATE_LUMINANCE, multiply); }, /** - * Internal value remover, called automatically by the `remove` method. + * Applies a sepia tone to this ColorMatrix. * - * @method Phaser.Data.DataManager#removeValue - * @private - * @fires Phaser.Data.Events#REMOVE_DATA - * @since 3.10.0 + * @method Phaser.Display.ColorMatrix#sepia + * @since 3.50.0 * - * @param {string} key - The key to set the value for. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? * - * @return {this} This DataManager object. + * @return {this} This ColorMatrix instance. */ - removeValue: function (key) + sepia: function (multiply) { - if (this.has(key)) - { - var data = this.list[key]; - - delete this.list[key]; - delete this.values[key]; - - this.events.emit(Events.REMOVE_DATA, this.parent, key, data); - } + if (multiply === undefined) { multiply = false; } - return this; + return this.multiply(ColorMatrix.SEPIA, multiply); }, /** - * Retrieves the data associated with the given 'key', deletes it from this Data Manager, then returns it. + * Applies a night vision tone to this ColorMatrix. * - * @method Phaser.Data.DataManager#pop - * @fires Phaser.Data.Events#REMOVE_DATA - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#night + * @since 3.50.0 * - * @param {string} key - The key of the value to retrieve and delete. + * @param {number} [intensity=0.1] - The intensity of this effect. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? * - * @return {*} The value of the given key. + * @return {this} This ColorMatrix instance. */ - pop: function (key) + night: function (intensity, multiply) { - var data = undefined; - - if (!this._frozen && this.has(key)) - { - data = this.list[key]; + if (intensity === undefined) { intensity = 0.1; } + if (multiply === undefined) { multiply = false; } - delete this.list[key]; - delete this.values[key]; + 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); + }, - this.events.emit(Events.REMOVE_DATA, this.parent, key, data); - } + /** + * 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 data; + return this.multiply(ColorMatrix.LSD, multiply); }, /** - * Determines whether the given key is set in this Data Manager. - * - * Please note that the keys are case-sensitive and must be valid JavaScript Object property strings. - * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. + * Applies a brown tone to this ColorMatrix. * - * @method Phaser.Data.DataManager#has - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#brown + * @since 3.50.0 * - * @param {string} key - The key to check. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? * - * @return {boolean} Returns `true` if the key exists, otherwise `false`. + * @return {this} This ColorMatrix instance. */ - has: function (key) + brown: function (multiply) { - return this.list.hasOwnProperty(key); + if (multiply === undefined) { multiply = false; } + + return this.multiply(ColorMatrix.BROWN, multiply); }, /** - * Freeze or unfreeze this Data Manager. A frozen Data Manager will block all attempts - * to create new values or update existing ones. + * Applies a vintage pinhole color effect to this ColorMatrix. * - * @method Phaser.Data.DataManager#setFreeze - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#vintagePinhole + * @since 3.50.0 * - * @param {boolean} value - Whether to freeze or unfreeze the Data Manager. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? * - * @return {this} This DataManager object. + * @return {this} This ColorMatrix instance. */ - setFreeze: function (value) + vintagePinhole: function (multiply) { - this._frozen = value; + if (multiply === undefined) { multiply = false; } - return this; + return this.multiply(ColorMatrix.VINTAGE, multiply); }, /** - * Delete all data in this Data Manager and unfreeze it. + * Applies a kodachrome color effect to this ColorMatrix. * - * @method Phaser.Data.DataManager#reset - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#kodachrome + * @since 3.50.0 * - * @return {this} This DataManager object. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. */ - reset: function () + kodachrome: function (multiply) { - for (var key in this.list) - { - delete this.list[key]; - delete this.values[key]; - } - - this._frozen = false; + if (multiply === undefined) { multiply = false; } - return this; + return this.multiply(ColorMatrix.KODACHROME, multiply); }, /** - * Destroy this data manager. + * Applies a technicolor color effect to this ColorMatrix. * - * @method Phaser.Data.DataManager#destroy - * @since 3.0.0 + * @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. */ - destroy: function () + technicolor: function (multiply) { - this.reset(); - - this.events.off(Events.CHANGE_DATA); - this.events.off(Events.SET_DATA); - this.events.off(Events.REMOVE_DATA); + if (multiply === undefined) { multiply = false; } - this.parent = null; + return this.multiply(ColorMatrix.TECHNICOLOR, multiply); }, /** - * Gets or sets the frozen state of this Data Manager. - * A frozen Data Manager will block all attempts to create new values or update existing ones. + * Applies a polaroid color effect to this ColorMatrix. * - * @name Phaser.Data.DataManager#freeze - * @type {boolean} - * @since 3.0.0 + * @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. */ - freeze: { + polaroid: function (multiply) + { + if (multiply === undefined) { multiply = false; } - get: function () - { - return this._frozen; - }, + return this.multiply(ColorMatrix.POLAROID, multiply); + }, - set: function (value) - { - this._frozen = (value) ? true : false; - } + /** + * 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(ColorMatrix.SHIFT_BGR, multiply); }, /** - * Return the total number of entries in this Data Manager. + * Multiplies the two given matrices. * - * @name Phaser.Data.DataManager#count - * @type {number} - * @since 3.0.0 + * @method Phaser.Display.ColorMatrix#multiply + * @since 3.50.0 + * + * @param {number[]} a - The 5x4 array to multiply with ColorMatrix._matrix. + * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * + * @return {this} This ColorMatrix instance. */ - count: { + multiply: function (a, multiply) + { + if (multiply === undefined) { multiply = false; } - get: function () + // Duplicate _matrix into c + + if (!multiply) { - var i = 0; + this.reset(); + } - for (var key in this.list) - { - if (this.list[key] !== undefined) - { - i++; - } - } + var m = this._matrix; + var c = tempMatrix; + + // copy _matrix to tempMatrox + c.set(m); + + m.set([ + // R + (c[0] * a[0]) + (c[1] * a[5]) + (c[2] * a[10]) + (c[3] * a[15]), + (c[0] * a[1]) + (c[1] * a[6]) + (c[2] * a[11]) + (c[3] * a[16]), + (c[0] * a[2]) + (c[1] * a[7]) + (c[2] * a[12]) + (c[3] * a[17]), + (c[0] * a[3]) + (c[1] * a[8]) + (c[2] * a[13]) + (c[3] * a[18]), + (c[0] * a[4]) + (c[1] * a[9]) + (c[2] * a[14]) + (c[3] * a[19]) + c[4], + + // G + (c[5] * a[0]) + (c[6] * a[5]) + (c[7] * a[10]) + (c[8] * a[15]), + (c[5] * a[1]) + (c[6] * a[6]) + (c[7] * a[11]) + (c[8] * a[16]), + (c[5] * a[2]) + (c[6] * a[7]) + (c[7] * a[12]) + (c[8] * a[17]), + (c[5] * a[3]) + (c[6] * a[8]) + (c[7] * a[13]) + (c[8] * a[18]), + (c[5] * a[4]) + (c[6] * a[9]) + (c[7] * a[14]) + (c[8] * a[19]) + c[9], + + // B + (c[10] * a[0]) + (c[11] * a[5]) + (c[12] * a[10]) + (c[13] * a[15]), + (c[10] * a[1]) + (c[11] * a[6]) + (c[12] * a[11]) + (c[13] * a[16]), + (c[10] * a[2]) + (c[11] * a[7]) + (c[12] * a[12]) + (c[13] * a[17]), + (c[10] * a[3]) + (c[11] * a[8]) + (c[12] * a[13]) + (c[13] * a[18]), + (c[10] * a[4]) + (c[11] * a[9]) + (c[12] * a[14]) + (c[13] * a[19]) + c[14], + + // A + (c[15] * a[0]) + (c[16] * a[5]) + (c[17] * a[10]) + (c[18] * a[15]), + (c[15] * a[1]) + (c[16] * a[6]) + (c[17] * a[11]) + (c[18] * a[16]), + (c[15] * a[2]) + (c[16] * a[7]) + (c[17] * a[12]) + (c[18] * a[17]), + (c[15] * a[3]) + (c[16] * a[8]) + (c[17] * a[13]) + (c[18] * a[18]), + (c[15] * a[4]) + (c[16] * a[9]) + (c[17] * a[14]) + (c[18] * a[19]) + c[19] - return i; - } + ]); + + this._dirty = true; + return this; } }); -module.exports = DataManager; +/** + * A constant array used by the ColorMatrix class for black_white operations. + * + * @name Phaser.Display.ColorMatrix.BLACK_WHITE + * @const + * @type {number[]} + * @since 3.60.0 + */ +ColorMatrix.BLACK_WHITE = [ 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 ]; +/** + * A constant array used by the ColorMatrix class for negative operations. + * + * @name Phaser.Display.ColorMatrix.NEGATIVE + * @const + * @type {number[]} + * @since 3.60.0 + */ +ColorMatrix.NEGATIVE = [ -1, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 1, 0 ]; -/***/ }), -/* 102 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * A constant array used by the ColorMatrix class for desatured luminance operations. + * + * @name Phaser.Display.ColorMatrix.DESATURATE_LUMINANCE + * @const + * @type {number[]} + * @since 3.60.0 + */ +ColorMatrix.DESATURATE_LUMINANCE = [ 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 ]; /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * A constant array used by the ColorMatrix class for sepia operations. + * + * @name Phaser.Display.ColorMatrix.SEPIA + * @const + * @type {number[]} + * @since 3.60.0 */ +ColorMatrix.SEPIA = [ 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 ]; -var Class = __webpack_require__(0); +/** + * A constant array used by the ColorMatrix class for lsd operations. + * + * @name Phaser.Display.ColorMatrix.LSD + * @const + * @type {number[]} + * @since 3.60.0 + */ +ColorMatrix.LSD = [ 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 ]; /** - * @callback EachMapCallback + * A constant array used by the ColorMatrix class for brown operations. * - * @param {string} key - The key of the Map entry. - * @param {E} entry - The value of the Map entry. + * @name Phaser.Display.ColorMatrix.BROWN + * @const + * @type {number[]} + * @since 3.60.0 + */ +ColorMatrix.BROWN = [ 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 ]; + +/** + * A constant array used by the ColorMatrix class for vintage pinhole operations. * - * @return {?boolean} The callback result. + * @name Phaser.Display.ColorMatrix.VINTAGE + * @const + * @type {number[]} + * @since 3.60.0 */ +ColorMatrix.VINTAGE = [ 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 ]; /** - * @classdesc - * The keys of a Map can be arbitrary values. + * A constant array used by the ColorMatrix class for kodachrome operations. * - * ```javascript - * var map = new Map([ - * [ 1, 'one' ], - * [ 2, 'two' ], - * [ 3, 'three' ] - * ]); - * ``` + * @name Phaser.Display.ColorMatrix.KODACHROME + * @const + * @type {number[]} + * @since 3.60.0 + */ +ColorMatrix.KODACHROME = [ 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 ]; + +/** + * A constant array used by the ColorMatrix class for technicolor operations. * - * @class Map - * @memberof Phaser.Structs - * @constructor - * @since 3.0.0 + * @name Phaser.Display.ColorMatrix.TECHNICOLOR + * @const + * @type {number[]} + * @since 3.60.0 + */ +ColorMatrix.TECHNICOLOR = [ 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 ]; + +/** + * A constant array used by the ColorMatrix class for polaroid shift operations. * - * @generic K - * @generic V - * @genericUse {V[]} - [elements] + * @name Phaser.Display.ColorMatrix.POLAROID + * @const + * @type {number[]} + * @since 3.60.0 + */ +ColorMatrix.POLAROID = [ 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 ]; + +/** + * A constant array used by the ColorMatrix class for shift BGR operations. * - * @param {Array.<*>} elements - An optional array of key-value pairs to populate this Map with. + * @name Phaser.Display.ColorMatrix.SHIFT_BGR + * @const + * @type {number[]} + * @since 3.60.0 */ -var Map = new Class({ +ColorMatrix.SHIFT_BGR = [ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 ]; + +module.exports = ColorMatrix; + + +/***/ }), + +/***/ 39298: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var NOOP = __webpack_require__(72283); + +/** + * @classdesc + * The RGB class holds a single color value and allows for easy modification and reading of it, + * with optional on-change callback notification and a dirty flag. + * + * @class RGB + * @memberof Phaser.Display + * @constructor + * @since 3.50.0 + * + * @param {number} [red=0] - The red color value. A number between 0 and 1. + * @param {number} [green=0] - The green color value. A number between 0 and 1. + * @param {number} [blue=0] - The blue color value. A number between 0 and 1. + */ +var RGB = new Class({ initialize: - function Map (elements) + function RGB (red, green, blue) { /** - * The entries in this Map. + * Cached RGB values. * - * @genericUse {Object.} - [$type] + * @name Phaser.Display.RGB#_rgb + * @type {number[]} + * @private + * @since 3.50.0 + */ + this._rgb = [ 0, 0, 0 ]; + + /** + * This callback will be invoked each time one of the RGB color values change. * - * @name Phaser.Structs.Map#entries - * @type {Object.} - * @default {} - * @since 3.0.0 + * The callback is sent the new color values as the parameters. + * + * @name Phaser.Display.RGB#onChangeCallback + * @type {function} + * @since 3.50.0 */ - this.entries = {}; + this.onChangeCallback = NOOP; /** - * The number of key / value pairs in this Map. + * Is this color dirty? * - * @name Phaser.Structs.Map#size - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Display.RGB#dirty + * @type {boolean} + * @since 3.50.0 */ - this.size = 0; + this.dirty = false; - if (Array.isArray(elements)) - { - for (var i = 0; i < elements.length; i++) - { - this.set(elements[i][0], elements[i][1]); - } - } + this.set(red, green, blue); }, /** - * Adds an element with a specified `key` and `value` to this Map. - * If the `key` already exists, the value will be replaced. - * - * @method Phaser.Structs.Map#set - * @since 3.0.0 + * Sets the red, green and blue values of this RGB object, flags it as being + * dirty and then invokes the `onChangeCallback`, if set. * - * @genericUse {K} - [key] - * @genericUse {V} - [value] - * @genericUse {Phaser.Structs.Map.} - [$return] + * @method Phaser.Display.RGB#set + * @since 3.50.0 * - * @param {string} key - The key of the element to be added to this Map. - * @param {*} value - The value of the element to be added to this Map. + * @param {number} [red=0] - The red color value. A number between 0 and 1. + * @param {number} [green=0] - The green color value. A number between 0 and 1. + * @param {number} [blue=0] - The blue color value. A number between 0 and 1. * - * @return {Phaser.Structs.Map} This Map object. + * @return {this} This RGB instance. */ - set: function (key, value) + set: function (red, green, blue) { - if (!this.has(key)) - { - this.size++; - } + if (red === undefined) { red = 0; } + if (green === undefined) { green = 0; } + if (blue === undefined) { blue = 0; } - this.entries[key] = value; + this._rgb = [ red, green, blue ]; + + this.onChange(); return this; }, /** - * Returns the value associated to the `key`, or `undefined` if there is none. - * - * @method Phaser.Structs.Map#get - * @since 3.0.0 + * Compares the given rgb parameters with those in this object and returns + * a boolean `true` value if they are equal, otherwise it returns `false`. * - * @genericUse {K} - [key] - * @genericUse {V} - [$return] + * @method Phaser.Display.RGB#equals + * @since 3.50.0 * - * @param {string} key - The key of the element to return from the `Map` object. + * @param {number} red - The red value to compare with this object. + * @param {number} green - The green value to compare with this object. + * @param {number} blue - The blue value to compare with this object. * - * @return {*} The element associated with the specified key or `undefined` if the key can't be found in this Map object. + * @return {boolean} `true` if the given values match those in this object, otherwise `false`. */ - get: function (key) + equals: function (red, green, blue) { - if (this.has(key)) - { - return this.entries[key]; - } + var rgb = this._rgb; + + return (rgb[0] === red && rgb[1] === green && rgb[2] === blue); }, /** - * Returns an `Array` of all the values stored in this Map. - * - * @method Phaser.Structs.Map#getArray - * @since 3.0.0 - * - * @genericUse {V[]} - [$return] + * Internal on change handler. Sets this object as being dirty and + * then invokes the `onChangeCallback`, if set, passing in the + * new RGB values. * - * @return {Array.<*>} An array of the values stored in this Map. + * @method Phaser.Display.RGB#onChange + * @since 3.50.0 */ - getArray: function () + onChange: function () { - var output = []; - var entries = this.entries; + this.dirty = true; - for (var key in entries) - { - output.push(entries[key]); - } + var rgb = this._rgb; - return output; + this.onChangeCallback.call(this, rgb[0], rgb[1], rgb[2]); }, /** - * Returns a boolean indicating whether an element with the specified key exists or not. - * - * @method Phaser.Structs.Map#has - * @since 3.0.0 - * - * @genericUse {K} - [key] + * The red color value. Between 0 and 1. * - * @param {string} key - The key of the element to test for presence of in this Map. + * Changing this property will flag this RGB object as being dirty + * and invoke the `onChangeCallback` , if set. * - * @return {boolean} Returns `true` if an element with the specified key exists in this Map, otherwise `false`. + * @name Phaser.Display.RGB#r + * @type {number} + * @since 3.50.0 */ - has: function (key) - { - return (this.entries.hasOwnProperty(key)); - }, + r: { - /** - * Delete the specified element from this Map. - * - * @method Phaser.Structs.Map#delete - * @since 3.0.0 - * - * @genericUse {K} - [key] - * @genericUse {Phaser.Structs.Map.} - [$return] - * - * @param {string} key - The key of the element to delete from this Map. - * - * @return {Phaser.Structs.Map} This Map object. - */ - delete: function (key) - { - if (this.has(key)) + get: function () { - delete this.entries[key]; - this.size--; + return this._rgb[0]; + }, + + set: function (value) + { + this._rgb[0] = value; + this.onChange(); } - return this; }, /** - * Delete all entries from this Map. - * - * @method Phaser.Structs.Map#clear - * @since 3.0.0 + * The green color value. Between 0 and 1. * - * @genericUse {Phaser.Structs.Map.} - [$return] + * Changing this property will flag this RGB object as being dirty + * and invoke the `onChangeCallback` , if set. * - * @return {Phaser.Structs.Map} This Map object. + * @name Phaser.Display.RGB#g + * @type {number} + * @since 3.50.0 */ - clear: function () - { - Object.keys(this.entries).forEach(function (prop) - { - delete this.entries[prop]; + g: { - }, this); + get: function () + { + return this._rgb[1]; + }, - this.size = 0; + set: function (value) + { + this._rgb[1] = value; + this.onChange(); + } - return this; }, /** - * Returns all entries keys in this Map. - * - * @method Phaser.Structs.Map#keys - * @since 3.0.0 + * The blue color value. Between 0 and 1. * - * @genericUse {K[]} - [$return] + * Changing this property will flag this RGB object as being dirty + * and invoke the `onChangeCallback` , if set. * - * @return {string[]} Array containing entries' keys. + * @name Phaser.Display.RGB#b + * @type {number} + * @since 3.50.0 */ - keys: function () - { - return Object.keys(this.entries); - }, + b: { - /** - * Returns an `Array` of all entries. - * - * @method Phaser.Structs.Map#values - * @since 3.0.0 - * - * @genericUse {V[]} - [$return] - * - * @return {Array.<*>} An `Array` of entries. - */ - values: function () - { - var output = []; - var entries = this.entries; + get: function () + { + return this._rgb[2]; + }, - for (var key in entries) + set: function (value) { - output.push(entries[key]); + this._rgb[2] = value; + this.onChange(); } - return output; }, /** - * Dumps the contents of this Map to the console via `console.group`. + * Nulls any external references this object contains. * - * @method Phaser.Structs.Map#dump - * @since 3.0.0 + * @method Phaser.Display.RGB#destroy + * @since 3.50.0 */ - dump: function () + destroy: function () { - var entries = this.entries; + this.onChangeCallback = null; + } - // eslint-disable-next-line no-console - console.group('Map'); +}); - for (var key in entries) - { - console.log(key, entries[key]); - } +module.exports = RGB; - // eslint-disable-next-line no-console - console.groupEnd(); - }, - /** - * Iterates through all entries in this Map, passing each one to the given callback. - * - * If the callback returns `false`, the iteration will break. - * - * @method Phaser.Structs.Map#each - * @since 3.0.0 - * - * @genericUse {EachMapCallback.} - [callback] - * @genericUse {Phaser.Structs.Map.} - [$return] - * - * @param {EachMapCallback} callback - The callback which will receive the keys and entries held in this Map. - * - * @return {Phaser.Structs.Map} This Map object. - */ - each: function (callback) - { - var entries = this.entries; +/***/ }), - for (var key in entries) - { - if (callback(key, entries[key]) === false) - { - break; - } - } +/***/ 84093: +/***/ ((module) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ALIGN_CONST = { /** - * Returns `true` if the value exists within this Map. Otherwise, returns `false`. - * - * @method Phaser.Structs.Map#contains - * @since 3.0.0 - * - * @genericUse {V} - [value] - * - * @param {*} value - The value to search for. - * - * @return {boolean} `true` if the value is found, otherwise `false`. - */ - contains: function (value) - { - var entries = this.entries; + * A constant representing a top-left alignment or position. + * @constant + * @name Phaser.Display.Align.TOP_LEFT + * @since 3.0.0 + * @type {number} + */ + TOP_LEFT: 0, - for (var key in entries) - { - if (entries[key] === value) - { - return true; - } - } + /** + * A constant representing a top-center alignment or position. + * @constant + * @name Phaser.Display.Align.TOP_CENTER + * @since 3.0.0 + * @type {number} + */ + TOP_CENTER: 1, - return false; - }, + /** + * A constant representing a top-right alignment or position. + * @constant + * @name Phaser.Display.Align.TOP_RIGHT + * @since 3.0.0 + * @type {number} + */ + TOP_RIGHT: 2, /** - * Merges all new keys from the given Map into this one. - * If it encounters a key that already exists it will be skipped unless override is set to `true`. - * - * @method Phaser.Structs.Map#merge - * @since 3.0.0 - * - * @genericUse {Phaser.Structs.Map.} - [map,$return] - * - * @param {Phaser.Structs.Map} map - The Map to merge in to this Map. - * @param {boolean} [override=false] - Set to `true` to replace values in this Map with those from the source map, or `false` to skip them. - * - * @return {Phaser.Structs.Map} This Map object. - */ - merge: function (map, override) - { - if (override === undefined) { override = false; } + * A constant representing a left-top alignment or position. + * @constant + * @name Phaser.Display.Align.LEFT_TOP + * @since 3.0.0 + * @type {number} + */ + LEFT_TOP: 3, - var local = this.entries; - var source = map.entries; + /** + * A constant representing a left-center alignment or position. + * @constant + * @name Phaser.Display.Align.LEFT_CENTER + * @since 3.0.0 + * @type {number} + */ + LEFT_CENTER: 4, - for (var key in source) - { - if (local.hasOwnProperty(key) && override) - { - local[key] = source[key]; - } - else - { - this.set(key, source[key]); - } - } + /** + * A constant representing a left-bottom alignment or position. + * @constant + * @name Phaser.Display.Align.LEFT_BOTTOM + * @since 3.0.0 + * @type {number} + */ + LEFT_BOTTOM: 5, - return this; - } + /** + * A constant representing a center alignment or position. + * @constant + * @name Phaser.Display.Align.CENTER + * @since 3.0.0 + * @type {number} + */ + CENTER: 6, -}); + /** + * A constant representing a right-top alignment or position. + * @constant + * @name Phaser.Display.Align.RIGHT_TOP + * @since 3.0.0 + * @type {number} + */ + RIGHT_TOP: 7, -module.exports = Map; + /** + * A constant representing a right-center alignment or position. + * @constant + * @name Phaser.Display.Align.RIGHT_CENTER + * @since 3.0.0 + * @type {number} + */ + RIGHT_CENTER: 8, + + /** + * A constant representing a right-bottom alignment or position. + * @constant + * @name Phaser.Display.Align.RIGHT_BOTTOM + * @since 3.0.0 + * @type {number} + */ + RIGHT_BOTTOM: 9, + + /** + * A constant representing a bottom-left alignment or position. + * @constant + * @name Phaser.Display.Align.BOTTOM_LEFT + * @since 3.0.0 + * @type {number} + */ + BOTTOM_LEFT: 10, + + /** + * A constant representing a bottom-center alignment or position. + * @constant + * @name Phaser.Display.Align.BOTTOM_CENTER + * @since 3.0.0 + * @type {number} + */ + BOTTOM_CENTER: 11, + + /** + * A constant representing a bottom-right alignment or position. + * @constant + * @name Phaser.Display.Align.BOTTOM_RIGHT + * @since 3.0.0 + * @type {number} + */ + BOTTOM_RIGHT: 12 + +}; + +module.exports = ALIGN_CONST; /***/ }), -/* 103 */ -/***/ (function(module, exports) { + +/***/ 32058: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetBottom = __webpack_require__(97328); +var GetCenterX = __webpack_require__(59994); +var SetBottom = __webpack_require__(73174); +var SetCenterX = __webpack_require__(28417); + /** - * Given 3 separate color values this will return an integer representation of it. + * Takes given Game Object and aligns it so that it is positioned in the bottom center of the other. * - * @function Phaser.Display.Color.GetColor + * @function Phaser.Display.Align.In.BottomCenter * @since 3.0.0 * - * @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. + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] * - * @return {number} The combined color value. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. */ -var GetColor = function (red, green, blue) +var BottomCenter = function (gameObject, alignIn, offsetX, offsetY) { - return red << 16 | green << 8 | blue; + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } + + SetCenterX(gameObject, GetCenterX(alignIn) + offsetX); + SetBottom(gameObject, GetBottom(alignIn) + offsetY); + + return gameObject; }; -module.exports = GetColor; +module.exports = BottomCenter; /***/ }), -/* 104 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 85535: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetBottom = __webpack_require__(97328); +var GetLeft = __webpack_require__(40163); +var SetBottom = __webpack_require__(73174); +var SetLeft = __webpack_require__(74465); + /** - * @namespace Phaser.Scale.Events + * Takes given Game Object and aligns it so that it is positioned in the bottom left of the other. + * + * @function Phaser.Display.Align.In.BottomLeft + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. */ +var BottomLeft = function (gameObject, alignIn, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } -module.exports = { - - ENTER_FULLSCREEN: __webpack_require__(800), - FULLSCREEN_FAILED: __webpack_require__(801), - FULLSCREEN_UNSUPPORTED: __webpack_require__(802), - LEAVE_FULLSCREEN: __webpack_require__(803), - ORIENTATION_CHANGE: __webpack_require__(804), - RESIZE: __webpack_require__(805) + SetLeft(gameObject, GetLeft(alignIn) - offsetX); + SetBottom(gameObject, GetBottom(alignIn) + offsetY); + return gameObject; }; +module.exports = BottomLeft; + /***/ }), -/* 105 */ -/***/ (function(module, exports, __webpack_require__) { -/* WEBPACK VAR INJECTION */(function(process) {/** +/***/ 9605: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetBottom = __webpack_require__(97328); +var GetRight = __webpack_require__(70271); +var SetBottom = __webpack_require__(73174); +var SetRight = __webpack_require__(19298); + /** - * Determines the operating system of the device running this Phaser Game instance. - * These values are read-only and populated during the boot sequence of the game. - * They are then referenced by internal game systems and are available for you to access - * via `this.sys.game.device.os` from within any Scene. + * Takes given Game Object and aligns it so that it is positioned in the bottom right of the other. * - * @typedef {object} Phaser.Device.OS + * @function Phaser.Display.Align.In.BottomRight * @since 3.0.0 * - * @property {boolean} android - Is running on android? - * @property {boolean} chromeOS - Is running on chromeOS? - * @property {boolean} cordova - Is the game running under Apache Cordova? - * @property {boolean} crosswalk - Is the game running under the Intel Crosswalk XDK? - * @property {boolean} desktop - Is running on a desktop? - * @property {boolean} ejecta - Is the game running under Ejecta? - * @property {boolean} electron - Is the game running under GitHub Electron? - * @property {boolean} iOS - Is running on iOS? - * @property {boolean} iPad - Is running on iPad? - * @property {boolean} iPhone - Is running on iPhone? - * @property {boolean} kindle - Is running on an Amazon Kindle? - * @property {boolean} linux - Is running on linux? - * @property {boolean} macOS - Is running on macOS? - * @property {boolean} node - Is the game running under Node.js? - * @property {boolean} nodeWebkit - Is the game running under Node-Webkit? - * @property {boolean} webApp - Set to true if running as a WebApp, i.e. within a WebView - * @property {boolean} windows - Is running on windows? - * @property {boolean} windowsPhone - Is running on a Windows Phone? - * @property {number} iOSVersion - If running in iOS this will contain the major version number. - * @property {number} pixelRatio - PixelRatio of the host device? + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. */ -var OS = { - - android: false, - chromeOS: false, - cordova: false, - crosswalk: false, - desktop: false, - ejecta: false, - electron: false, - iOS: false, - iOSVersion: 0, - iPad: false, - iPhone: false, - kindle: false, - linux: false, - macOS: false, - node: false, - nodeWebkit: false, - pixelRatio: 1, - webApp: false, - windows: false, - windowsPhone: false - -}; - -function init () +var BottomRight = function (gameObject, alignIn, offsetX, offsetY) { - if (typeof importScripts === 'function') - { - return OS; - } - - var ua = navigator.userAgent; + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - if ((/Windows/).test(ua)) - { - OS.windows = true; - } - else if ((/Mac OS/).test(ua) && !((/like Mac OS/).test(ua))) - { - // Because iOS 13 identifies as Mac OS: - if (navigator.maxTouchPoints && navigator.maxTouchPoints > 2) - { - OS.iOS = true; - OS.iPad = true; + SetRight(gameObject, GetRight(alignIn) + offsetX); + SetBottom(gameObject, GetBottom(alignIn) + offsetY); - (navigator.appVersion).match(/Version\/(\d+)/); + return gameObject; +}; - OS.iOSVersion = parseInt(RegExp.$1, 10); - } - else - { - OS.macOS = true; - } - } - else if ((/Android/).test(ua)) - { - OS.android = true; - } - else if ((/Linux/).test(ua)) - { - OS.linux = true; - } - else if ((/iP[ao]d|iPhone/i).test(ua)) - { - OS.iOS = true; +module.exports = BottomRight; - (navigator.appVersion).match(/OS (\d+)/); - OS.iOSVersion = parseInt(RegExp.$1, 10); +/***/ }), - OS.iPhone = ua.toLowerCase().indexOf('iphone') !== -1; - OS.iPad = ua.toLowerCase().indexOf('ipad') !== -1; - } - else if ((/Kindle/).test(ua) || (/\bKF[A-Z][A-Z]+/).test(ua) || (/Silk.*Mobile Safari/).test(ua)) - { - OS.kindle = true; +/***/ 22529: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // This will NOT detect early generations of Kindle Fire, I think there is no reliable way... - // E.g. "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-80) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true" - } - else if ((/CrOS/).test(ua)) - { - OS.chromeOS = true; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if ((/Windows Phone/i).test(ua) || (/IEMobile/i).test(ua)) - { - OS.android = false; - OS.iOS = false; - OS.macOS = false; - OS.windows = true; - OS.windowsPhone = true; - } +var CenterOn = __webpack_require__(21843); +var GetCenterX = __webpack_require__(59994); +var GetCenterY = __webpack_require__(29568); - var silk = (/Silk/).test(ua); +/** + * Takes given Game Object and aligns it so that it is positioned in the center of the other. + * + * @function Phaser.Display.Align.In.Center + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var Center = function (gameObject, alignIn, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - if (OS.windows || OS.macOS || (OS.linux && !silk) || OS.chromeOS) - { - OS.desktop = true; - } + CenterOn(gameObject, GetCenterX(alignIn) + offsetX, GetCenterY(alignIn) + offsetY); - // Windows Phone / Table reset - if (OS.windowsPhone || (((/Windows NT/i).test(ua)) && ((/Touch/i).test(ua)))) - { - OS.desktop = false; - } + return gameObject; +}; - // WebApp mode in iOS - if (navigator.standalone) - { - OS.webApp = true; - } +module.exports = Center; - if (typeof importScripts !== 'function') - { - if (window.cordova !== undefined) - { - OS.cordova = true; - } - if (window.ejecta !== undefined) - { - OS.ejecta = true; - } - } +/***/ }), - if (typeof process !== 'undefined' && process.versions && process.versions.node) - { - OS.node = true; - } +/***/ 5739: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (OS.node && typeof process.versions === 'object') - { - OS.nodeWebkit = !!process.versions['node-webkit']; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - OS.electron = !!process.versions.electron; - } +var GetCenterY = __webpack_require__(29568); +var GetLeft = __webpack_require__(40163); +var SetCenterY = __webpack_require__(81711); +var SetLeft = __webpack_require__(74465); - if ((/Crosswalk/).test(ua)) - { - OS.crosswalk = true; - } +/** + * Takes given Game Object and aligns it so that it is positioned in the left center of the other. + * + * @function Phaser.Display.Align.In.LeftCenter + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var LeftCenter = function (gameObject, alignIn, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - OS.pixelRatio = window['devicePixelRatio'] || 1; + SetLeft(gameObject, GetLeft(alignIn) - offsetX); + SetCenterY(gameObject, GetCenterY(alignIn) + offsetY); - return OS; -} + return gameObject; +}; -module.exports = init(); +module.exports = LeftCenter; -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(807))) /***/ }), -/* 106 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 40327: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @namespace Phaser.Textures.Events - */ +var ALIGN_CONST = __webpack_require__(84093); -module.exports = { +var AlignInMap = []; - ADD: __webpack_require__(861), - ERROR: __webpack_require__(862), - LOAD: __webpack_require__(863), - READY: __webpack_require__(864), - REMOVE: __webpack_require__(865) +AlignInMap[ALIGN_CONST.BOTTOM_CENTER] = __webpack_require__(32058); +AlignInMap[ALIGN_CONST.BOTTOM_LEFT] = __webpack_require__(85535); +AlignInMap[ALIGN_CONST.BOTTOM_RIGHT] = __webpack_require__(9605); +AlignInMap[ALIGN_CONST.CENTER] = __webpack_require__(22529); +AlignInMap[ALIGN_CONST.LEFT_CENTER] = __webpack_require__(5739); +AlignInMap[ALIGN_CONST.RIGHT_CENTER] = __webpack_require__(27683); +AlignInMap[ALIGN_CONST.TOP_CENTER] = __webpack_require__(96439); +AlignInMap[ALIGN_CONST.TOP_LEFT] = __webpack_require__(81447); +AlignInMap[ALIGN_CONST.TOP_RIGHT] = __webpack_require__(47888); +AlignInMap[ALIGN_CONST.LEFT_BOTTOM] = AlignInMap[ALIGN_CONST.BOTTOM_LEFT]; +AlignInMap[ALIGN_CONST.LEFT_TOP] = AlignInMap[ALIGN_CONST.TOP_LEFT]; +AlignInMap[ALIGN_CONST.RIGHT_BOTTOM] = AlignInMap[ALIGN_CONST.BOTTOM_RIGHT]; +AlignInMap[ALIGN_CONST.RIGHT_TOP] = AlignInMap[ALIGN_CONST.TOP_RIGHT]; +/** + * Takes given Game Object and aligns it so that it is positioned relative to the other. + * The alignment used is based on the `position` argument, which is an `ALIGN_CONST` value, such as `LEFT_CENTER` or `TOP_RIGHT`. + * + * @function Phaser.Display.Align.In.QuickSet + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [child,$return] + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} position - The position to align the Game Object with. This is an align constant, such as `ALIGN_CONST.LEFT_CENTER`. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var QuickSet = function (child, alignIn, position, offsetX, offsetY) +{ + return AlignInMap[position](child, alignIn, offsetX, offsetY); }; +module.exports = QuickSet; + /***/ }), -/* 107 */ -/***/ (function(module, exports) { + +/***/ 27683: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 }, +var GetCenterY = __webpack_require__(29568); +var GetRight = __webpack_require__(70271); +var SetCenterY = __webpack_require__(81711); +var SetRight = __webpack_require__(19298); - /** - * 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 }, +/** + * Takes given Game Object and aligns it so that it is positioned in the right center of the other. + * + * @function Phaser.Display.Align.In.RightCenter + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var RightCenter = function (gameObject, alignIn, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - /** - * 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 } + SetRight(gameObject, GetRight(alignIn) + offsetX); + SetCenterY(gameObject, GetCenterY(alignIn) + offsetY); + return gameObject; }; -module.exports = WEBGL_CONST; +module.exports = RightCenter; /***/ }), -/* 108 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 96439: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(59); -var GetFastValue = __webpack_require__(2); -var ShaderSourceFS = __webpack_require__(878); -var ShaderSourceVS = __webpack_require__(879); -var TransformMatrix = __webpack_require__(25); -var Utils = __webpack_require__(12); -var WEBGL_CONST = __webpack_require__(107); -var WebGLPipeline = __webpack_require__(58); +var GetCenterX = __webpack_require__(59994); +var GetTop = __webpack_require__(47196); +var SetCenterX = __webpack_require__(28417); +var SetTop = __webpack_require__(84349); /** - * @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. + * Takes given Game Object and aligns it so that it is positioned in the top center of the other. * - * 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`. + * @function Phaser.Display.Align.In.TopCenter + * @since 3.0.0 * - * 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. + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] * - * @class MultiPipeline - * @extends Phaser.Renderer.WebGL.WebGLPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.50.0 + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. */ -var MultiPipeline = new Class({ - - Extends: WebGLPipeline, +var TopCenter = function (gameObject, alignIn, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - initialize: + SetCenterX(gameObject, GetCenterX(alignIn) + offsetX); + SetTop(gameObject, GetTop(alignIn) - offsetY); - function MultiPipeline (config) - { - var renderer = config.game.renderer; + return gameObject; +}; - var fragmentShaderSource = GetFastValue(config, 'fragShader', ShaderSourceFS); +module.exports = TopCenter; - 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(); +/***/ 81447: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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(); +var GetLeft = __webpack_require__(40163); +var GetTop = __webpack_require__(47196); +var SetLeft = __webpack_require__(74465); +var SetTop = __webpack_require__(84349); - /** - * A temporary Transform Matrix, re-used internally during batching by the - * Shape Game Objects. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#calcMatrix - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.55.0 - */ - this.calcMatrix = new TransformMatrix(); +/** + * Takes given Game Object and aligns it so that it is positioned in the top left of the other. + * + * @function Phaser.Display.Align.In.TopLeft + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var TopLeft = function (gameObject, alignIn, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - /** - * Used internally to draw stroked triangles. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#tempTriangle - * @type {array} - * @private - * @since 3.55.0 - */ - this.tempTriangle = [ - { x: 0, y: 0, width: 0 }, - { x: 0, y: 0, width: 0 }, - { x: 0, y: 0, width: 0 }, - { x: 0, y: 0, width: 0 } - ]; + SetLeft(gameObject, GetLeft(alignIn) - offsetX); + SetTop(gameObject, GetTop(alignIn) - offsetY); - /** - * Cached stroke tint. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#strokeTint - * @type {object} - * @private - * @since 3.55.0 - */ - this.strokeTint = { TL: 0, TR: 0, BL: 0, BR: 0 }; + return gameObject; +}; - /** - * Cached fill tint. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#fillTint - * @type {object} - * @private - * @since 3.55.0 - */ - this.fillTint = { TL: 0, TR: 0, BL: 0, BR: 0 }; +module.exports = TopLeft; - /** - * Internal texture frame reference. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#currentFrame - * @type {Phaser.Textures.Frame} - * @private - * @since 3.55.0 - */ - this.currentFrame = { u0: 0, v0: 0, u1: 1, v1: 1 }; - /** - * Internal path quad cache. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#firstQuad - * @type {number[]} - * @private - * @since 3.55.0 - */ - this.firstQuad = [ 0, 0, 0, 0, 0 ]; +/***/ }), - /** - * Internal path quad cache. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#prevQuad - * @type {number[]} - * @private - * @since 3.55.0 - */ - this.prevQuad = [ 0, 0, 0, 0, 0 ]; +/***/ 47888: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Used internally for triangulating a polygon. - * - * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#polygonCache - * @type {array} - * @private - * @since 3.55.0 - */ - this.polygonCache = []; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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); +var GetRight = __webpack_require__(70271); +var GetTop = __webpack_require__(47196); +var SetRight = __webpack_require__(19298); +var SetTop = __webpack_require__(84349); - this.currentShader.set1iv('uMainSampler', this.renderer.textureIndexes); - }, +/** + * Takes given Game Object and aligns it so that it is positioned in the top right of the other. + * + * @function Phaser.Display.Align.In.TopRight + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var TopRight = function (gameObject, alignIn, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - /** - * 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); + SetRight(gameObject, GetRight(alignIn) + offsetX); + SetTop(gameObject, GetTop(alignIn) - offsetY); - var camMatrix = this._tempMatrix1; - var spriteMatrix = this._tempMatrix2; - var calcMatrix = this._tempMatrix3; + return gameObject; +}; - var frame = gameObject.frame; - var texture = frame.glTexture; +module.exports = TopRight; - 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; +/***/ 46997: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (gameObject.isCropped) - { - var crop = gameObject._crop; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (crop.flipX !== gameObject.flipX || crop.flipY !== gameObject.flipY) - { - frame.updateCropUVs(crop, gameObject.flipX, gameObject.flipY); - } +/** + * @namespace Phaser.Display.Align.In + */ - u0 = crop.u0; - v0 = crop.v0; - u1 = crop.u1; - v1 = crop.v1; +module.exports = { - frameWidth = crop.width; - frameHeight = crop.height; + BottomCenter: __webpack_require__(32058), + BottomLeft: __webpack_require__(85535), + BottomRight: __webpack_require__(9605), + Center: __webpack_require__(22529), + LeftCenter: __webpack_require__(5739), + QuickSet: __webpack_require__(40327), + RightCenter: __webpack_require__(27683), + TopCenter: __webpack_require__(96439), + TopLeft: __webpack_require__(81447), + TopRight: __webpack_require__(47888) - 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)); - } +/***/ 93545: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - flipX = -1; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Auto-invert the flipY if this is coming from a GLTexture +var CONST = __webpack_require__(84093); +var Extend = __webpack_require__(98611); - if (gameObject.flipY || (frame.source.isGLTexture && !texture.flipY)) - { - if (!customPivot) - { - y += (-frame.realHeight + (displayOriginY * 2)); - } +/** + * @namespace Phaser.Display.Align + */ - flipY = -1; - } +var Align = { - spriteMatrix.applyITRS(gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX * flipX, gameObject.scaleY * flipY); + In: __webpack_require__(46997), + To: __webpack_require__(86639) - camMatrix.copyFrom(camera.matrix); +}; - if (parentTransformMatrix) - { - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * gameObject.scrollFactorX, -camera.scrollY * gameObject.scrollFactorY); +// Merge in the consts +Align = Extend(false, Align, CONST); - // 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; - } +module.exports = Align; - // 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; +/***/ 27118: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var tx0 = calcMatrix.getXRound(x, y, roundPixels); - var ty0 = calcMatrix.getYRound(x, y, roundPixels); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var tx1 = calcMatrix.getXRound(x, yh, roundPixels); - var ty1 = calcMatrix.getYRound(x, yh, roundPixels); +var GetBottom = __webpack_require__(97328); +var GetCenterX = __webpack_require__(59994); +var SetCenterX = __webpack_require__(28417); +var SetTop = __webpack_require__(84349); - var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); - var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); +/** + * Takes given Game Object and aligns it so that it is positioned next to the bottom center position of the other. + * + * @function Phaser.Display.Align.To.BottomCenter + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var BottomCenter = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - var tx3 = calcMatrix.getXRound(xw, y, roundPixels); - var ty3 = calcMatrix.getYRound(xw, y, roundPixels); + SetCenterX(gameObject, GetCenterX(alignTo) + offsetX); + SetTop(gameObject, GetBottom(alignTo) + offsetY); - var getTint = Utils.getTintAppendFloatAlpha; - var cameraAlpha = camera.alpha; + return gameObject; +}; - 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); +module.exports = BottomCenter; - if (this.shouldFlush(6)) - { - this.flush(); - } - var unit = this.setGameObject(gameObject, frame); +/***/ }), - this.manager.preBatch(gameObject); +/***/ 84469: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.batchQuad(gameObject, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, gameObject.tintFill, texture, unit); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.manager.postBatch(gameObject); - }, +var GetBottom = __webpack_require__(97328); +var GetLeft = __webpack_require__(40163); +var SetLeft = __webpack_require__(74465); +var SetTop = __webpack_require__(84349); - /** - * 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); +/** + * Takes given Game Object and aligns it so that it is positioned next to the bottom left position of the other. + * + * @function Phaser.Display.Align.To.BottomLeft + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var BottomLeft = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - var camMatrix = this._tempMatrix1; - var spriteMatrix = this._tempMatrix2; - var calcMatrix = this._tempMatrix3; + SetLeft(gameObject, GetLeft(alignTo) - offsetX); + SetTop(gameObject, GetBottom(alignTo) + offsetY); - var u0 = (frameX / textureWidth) + uOffset; - var v0 = (frameY / textureHeight) + vOffset; - var u1 = (frameX + frameWidth) / textureWidth + uOffset; - var v1 = (frameY + frameHeight) / textureHeight + vOffset; + return gameObject; +}; - var width = srcWidth; - var height = srcHeight; +module.exports = BottomLeft; - var x = -displayOriginX; - var y = -displayOriginY; - if (gameObject.isCropped) - { - var crop = gameObject._crop; +/***/ }), - var cropWidth = crop.width; - var cropHeight = crop.height; +/***/ 51577: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - width = cropWidth; - height = cropHeight; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - srcWidth = cropWidth; - srcHeight = cropHeight; +var GetBottom = __webpack_require__(97328); +var GetRight = __webpack_require__(70271); +var SetRight = __webpack_require__(19298); +var SetTop = __webpack_require__(84349); - frameX = crop.x; - frameY = crop.y; +/** + * Takes given Game Object and aligns it so that it is positioned next to the bottom right position of the other. + * + * @function Phaser.Display.Align.To.BottomRight + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var BottomRight = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - var ox = frameX; - var oy = frameY; + SetRight(gameObject, GetRight(alignTo) + offsetX); + SetTop(gameObject, GetBottom(alignTo) + offsetY); - if (flipX) - { - ox = (frameWidth - crop.x - cropWidth); - } + return gameObject; +}; - if (flipY) - { - oy = (frameHeight - crop.y - cropHeight); - } +module.exports = BottomRight; - 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); +/***/ 90271: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (flipX) - { - width *= -1; - x += srcWidth; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (flipY) - { - height *= -1; - y += srcHeight; - } +var GetBottom = __webpack_require__(97328); +var GetLeft = __webpack_require__(40163); +var SetBottom = __webpack_require__(73174); +var SetRight = __webpack_require__(19298); - var xw = x + width; - var yh = y + height; +/** + * Takes given Game Object and aligns it so that it is positioned next to the left bottom position of the other. + * + * @function Phaser.Display.Align.To.LeftBottom + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var LeftBottom = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - spriteMatrix.applyITRS(srcX, srcY, rotation, scaleX, scaleY); + SetRight(gameObject, GetLeft(alignTo) - offsetX); + SetBottom(gameObject, GetBottom(alignTo) + offsetY); - camMatrix.copyFrom(camera.matrix); + return gameObject; +}; - if (parentTransformMatrix) - { - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY); +module.exports = LeftBottom; - // 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; +/***/ 30466: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var tx0 = calcMatrix.getXRound(x, y, roundPixels); - var ty0 = calcMatrix.getYRound(x, y, roundPixels); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var tx1 = calcMatrix.getXRound(x, yh, roundPixels); - var ty1 = calcMatrix.getYRound(x, yh, roundPixels); +var GetCenterY = __webpack_require__(29568); +var GetLeft = __webpack_require__(40163); +var SetCenterY = __webpack_require__(81711); +var SetRight = __webpack_require__(19298); - var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); - var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); +/** + * Takes given Game Object and aligns it so that it is positioned next to the left center position of the other. + * + * @function Phaser.Display.Align.To.LeftCenter + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var LeftCenter = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - var tx3 = calcMatrix.getXRound(xw, y, roundPixels); - var ty3 = calcMatrix.getYRound(xw, y, roundPixels); + SetRight(gameObject, GetLeft(alignTo) - offsetX); + SetCenterY(gameObject, GetCenterY(alignTo) + offsetY); - if (textureUnit === undefined) - { - textureUnit = this.renderer.setTexture2D(texture); - } + return gameObject; +}; - if (gameObject) - { - this.manager.preBatch(gameObject); - } +module.exports = LeftCenter; - 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); +/***/ 50087: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var spriteMatrix = this._tempMatrix1.copyFrom(transformMatrix); - var calcMatrix = this._tempMatrix2; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var xw = x + frame.width; - var yh = y + frame.height; +var GetLeft = __webpack_require__(40163); +var GetTop = __webpack_require__(47196); +var SetRight = __webpack_require__(19298); +var SetTop = __webpack_require__(84349); - if (parentTransformMatrix) - { - spriteMatrix.multiply(parentTransformMatrix, calcMatrix); - } - else - { - calcMatrix = spriteMatrix; - } +/** + * Takes given Game Object and aligns it so that it is positioned next to the left top position of the other. + * + * @function Phaser.Display.Align.To.LeftTop + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var LeftTop = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - var tx0 = calcMatrix.getX(x, y); - var ty0 = calcMatrix.getY(x, y); + SetRight(gameObject, GetLeft(alignTo) - offsetX); + SetTop(gameObject, GetTop(alignTo) - offsetY); - var tx1 = calcMatrix.getX(x, yh); - var ty1 = calcMatrix.getY(x, yh); + return gameObject; +}; - var tx2 = calcMatrix.getX(xw, yh); - var ty2 = calcMatrix.getY(xw, yh); +module.exports = LeftTop; - var tx3 = calcMatrix.getX(xw, y); - var ty3 = calcMatrix.getY(xw, y); - var unit = this.renderer.setTextureSource(frame.source); +/***/ }), - tint = Utils.getTintAppendFloatAlpha(tint, alpha); +/***/ 82590: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - 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); - }, +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Pushes a filled rectangle into the vertex batch. - * - * Rectangle factors in the given transform matrices before adding to the batch. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchFillRect - * @since 3.55.0 - * - * @param {number} x - Horizontal top left coordinate of the rectangle. - * @param {number} y - Vertical top left coordinate of the rectangle. - * @param {number} width - Width of the rectangle. - * @param {number} height - Height of the rectangle. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchFillRect: function (x, y, width, height, currentMatrix, parentMatrix) - { - this.renderer.pipelines.set(this); +var ALIGN_CONST = __webpack_require__(84093); - var calcMatrix = this.calcMatrix; +var AlignToMap = []; - // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix - if (parentMatrix) - { - parentMatrix.multiply(currentMatrix, calcMatrix); - } +AlignToMap[ALIGN_CONST.BOTTOM_CENTER] = __webpack_require__(27118); +AlignToMap[ALIGN_CONST.BOTTOM_LEFT] = __webpack_require__(84469); +AlignToMap[ALIGN_CONST.BOTTOM_RIGHT] = __webpack_require__(51577); +AlignToMap[ALIGN_CONST.LEFT_BOTTOM] = __webpack_require__(90271); +AlignToMap[ALIGN_CONST.LEFT_CENTER] = __webpack_require__(30466); +AlignToMap[ALIGN_CONST.LEFT_TOP] = __webpack_require__(50087); +AlignToMap[ALIGN_CONST.RIGHT_BOTTOM] = __webpack_require__(13555); +AlignToMap[ALIGN_CONST.RIGHT_CENTER] = __webpack_require__(99049); +AlignToMap[ALIGN_CONST.RIGHT_TOP] = __webpack_require__(67788); +AlignToMap[ALIGN_CONST.TOP_CENTER] = __webpack_require__(78170); +AlignToMap[ALIGN_CONST.TOP_LEFT] = __webpack_require__(54145); +AlignToMap[ALIGN_CONST.TOP_RIGHT] = __webpack_require__(75548); - var xw = x + width; - var yh = y + height; +/** + * Takes a Game Object and aligns it next to another, at the given position. + * The alignment used is based on the `position` argument, which is a `Phaser.Display.Align` property such as `LEFT_CENTER` or `TOP_RIGHT`. + * + * @function Phaser.Display.Align.To.QuickSet + * @since 3.22.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [child,$return] + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} position - The position to align the Game Object with. This is an align constant, such as `Phaser.Display.Align.LEFT_CENTER`. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var QuickSet = function (child, alignTo, position, offsetX, offsetY) +{ + return AlignToMap[position](child, alignTo, offsetX, offsetY); +}; - var x0 = calcMatrix.getX(x, y); - var y0 = calcMatrix.getY(x, y); +module.exports = QuickSet; - var x1 = calcMatrix.getX(x, yh); - var y1 = calcMatrix.getY(x, yh); - var x2 = calcMatrix.getX(xw, yh); - var y2 = calcMatrix.getY(xw, yh); +/***/ }), - var x3 = calcMatrix.getX(xw, y); - var y3 = calcMatrix.getY(xw, y); +/***/ 13555: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var tint = this.fillTint; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.batchQuad(null, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint.TL, tint.TR, tint.BL, tint.BR, 2); - }, +var GetBottom = __webpack_require__(97328); +var GetRight = __webpack_require__(70271); +var SetBottom = __webpack_require__(73174); +var SetLeft = __webpack_require__(74465); - /** - * Pushes a filled triangle into the vertex batch. - * - * Triangle factors in the given transform matrices before adding to the batch. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchFillTriangle - * @since 3.55.0 - * - * @param {number} x0 - Point 0 x coordinate. - * @param {number} y0 - Point 0 y coordinate. - * @param {number} x1 - Point 1 x coordinate. - * @param {number} y1 - Point 1 y coordinate. - * @param {number} x2 - Point 2 x coordinate. - * @param {number} y2 - Point 2 y coordinate. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchFillTriangle: function (x0, y0, x1, y1, x2, y2, currentMatrix, parentMatrix) - { - this.renderer.pipelines.set(this); +/** + * Takes given Game Object and aligns it so that it is positioned next to the right bottom position of the other. + * + * @function Phaser.Display.Align.To.RightBottom + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var RightBottom = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - var calcMatrix = this.calcMatrix; + SetLeft(gameObject, GetRight(alignTo) + offsetX); + SetBottom(gameObject, GetBottom(alignTo) + offsetY); - // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix - if (parentMatrix) - { - parentMatrix.multiply(currentMatrix, calcMatrix); - } + return gameObject; +}; - var tx0 = calcMatrix.getX(x0, y0); - var ty0 = calcMatrix.getY(x0, y0); +module.exports = RightBottom; - var tx1 = calcMatrix.getX(x1, y1); - var ty1 = calcMatrix.getY(x1, y1); - var tx2 = calcMatrix.getX(x2, y2); - var ty2 = calcMatrix.getY(x2, y2); +/***/ }), - var tint = this.fillTint; +/***/ 99049: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.batchTri(null, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, tint.TL, tint.TR, tint.BL, 2); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Pushes a stroked triangle into the vertex batch. - * - * Triangle factors in the given transform matrices before adding to the batch. - * - * The triangle is created from 3 lines and drawn using the `batchStrokePath` method. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchStrokeTriangle - * @since 3.55.0 - * - * @param {number} x0 - Point 0 x coordinate. - * @param {number} y0 - Point 0 y coordinate. - * @param {number} x1 - Point 1 x coordinate. - * @param {number} y1 - Point 1 y coordinate. - * @param {number} x2 - Point 2 x coordinate. - * @param {number} y2 - Point 2 y coordinate. - * @param {number} lineWidth - The width of the line in pixels. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchStrokeTriangle: function (x0, y0, x1, y1, x2, y2, lineWidth, currentMatrix, parentMatrix) - { - var tempTriangle = this.tempTriangle; +var GetCenterY = __webpack_require__(29568); +var GetRight = __webpack_require__(70271); +var SetCenterY = __webpack_require__(81711); +var SetLeft = __webpack_require__(74465); - tempTriangle[0].x = x0; - tempTriangle[0].y = y0; - tempTriangle[0].width = lineWidth; +/** + * Takes given Game Object and aligns it so that it is positioned next to the right center position of the other. + * + * @function Phaser.Display.Align.To.RightCenter + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var RightCenter = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - tempTriangle[1].x = x1; - tempTriangle[1].y = y1; - tempTriangle[1].width = lineWidth; + SetLeft(gameObject, GetRight(alignTo) + offsetX); + SetCenterY(gameObject, GetCenterY(alignTo) + offsetY); - tempTriangle[2].x = x2; - tempTriangle[2].y = y2; - tempTriangle[2].width = lineWidth; + return gameObject; +}; - tempTriangle[3].x = x0; - tempTriangle[3].y = y0; - tempTriangle[3].width = lineWidth; +module.exports = RightCenter; - this.batchStrokePath(tempTriangle, lineWidth, false, currentMatrix, parentMatrix); - }, - /** - * Adds the given path to the vertex batch for rendering. - * - * It works by taking the array of path data and then passing it through Earcut, which - * creates a list of polygons. Each polygon is then added to the batch. - * - * The path is always automatically closed because it's filled. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchFillPath - * @since 3.55.0 - * - * @param {Phaser.Types.Math.Vector2Like[]} path - Collection of points that represent the path. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchFillPath: function (path, currentMatrix, parentMatrix) - { - this.renderer.pipelines.set(this); +/***/ }), - var calcMatrix = this.calcMatrix; +/***/ 67788: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix - if (parentMatrix) - { - parentMatrix.multiply(currentMatrix, calcMatrix); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var length = path.length; - var polygonCache = this.polygonCache; - var polygonIndexArray; - var point; +var GetRight = __webpack_require__(70271); +var GetTop = __webpack_require__(47196); +var SetLeft = __webpack_require__(74465); +var SetTop = __webpack_require__(84349); - var tintTL = this.fillTint.TL; - var tintTR = this.fillTint.TR; - var tintBL = this.fillTint.BL; +/** + * Takes given Game Object and aligns it so that it is positioned next to the right top position of the other. + * + * @function Phaser.Display.Align.To.RightTop + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var RightTop = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - for (var pathIndex = 0; pathIndex < length; ++pathIndex) - { - point = path[pathIndex]; - polygonCache.push(point.x, point.y); - } + SetLeft(gameObject, GetRight(alignTo) + offsetX); + SetTop(gameObject, GetTop(alignTo) - offsetY); - polygonIndexArray = Earcut(polygonCache); - length = polygonIndexArray.length; + return gameObject; +}; - for (var index = 0; index < length; index += 3) - { - var p0 = polygonIndexArray[index + 0] * 2; - var p1 = polygonIndexArray[index + 1] * 2; - var p2 = polygonIndexArray[index + 2] * 2; +module.exports = RightTop; - var x0 = polygonCache[p0 + 0]; - var y0 = polygonCache[p0 + 1]; - var x1 = polygonCache[p1 + 0]; - var y1 = polygonCache[p1 + 1]; - var x2 = polygonCache[p2 + 0]; - var y2 = polygonCache[p2 + 1]; - var tx0 = calcMatrix.getX(x0, y0); - var ty0 = calcMatrix.getY(x0, y0); +/***/ }), - var tx1 = calcMatrix.getX(x1, y1); - var ty1 = calcMatrix.getY(x1, y1); +/***/ 78170: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var tx2 = calcMatrix.getX(x2, y2); - var ty2 = calcMatrix.getY(x2, y2); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.batchTri(null, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, tintTL, tintTR, tintBL, 2); - } +var GetCenterX = __webpack_require__(59994); +var GetTop = __webpack_require__(47196); +var SetBottom = __webpack_require__(73174); +var SetCenterX = __webpack_require__(28417); - polygonCache.length = 0; - }, +/** + * Takes given Game Object and aligns it so that it is positioned next to the top center position of the other. + * + * @function Phaser.Display.Align.To.TopCenter + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var TopCenter = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - /** - * Adds the given path to the vertex batch for rendering. - * - * It works by taking the array of path data and calling `batchLine` for each section - * of the path. - * - * The path is optionally closed at the end. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchStrokePath - * @since 3.55.0 - * - * @param {Phaser.Types.Math.Vector2Like[]} path - Collection of points that represent the path. - * @param {number} lineWidth - The width of the line segments in pixels. - * @param {boolean} pathOpen - Indicates if the path should be closed or left open. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchStrokePath: function (path, lineWidth, pathOpen, currentMatrix, parentMatrix) - { - this.renderer.pipelines.set(this); + SetCenterX(gameObject, GetCenterX(alignTo) + offsetX); + SetBottom(gameObject, GetTop(alignTo) - offsetY); - // Reset the closePath booleans - this.prevQuad[4] = 0; - this.firstQuad[4] = 0; + return gameObject; +}; - var pathLength = path.length - 1; +module.exports = TopCenter; - for (var pathIndex = 0; pathIndex < pathLength; pathIndex++) - { - var point0 = path[pathIndex]; - var point1 = path[pathIndex + 1]; - this.batchLine( - point0.x, - point0.y, - point1.x, - point1.y, - point0.width / 2, - point1.width / 2, - lineWidth, - pathIndex, - !pathOpen && (pathIndex === pathLength - 1), - currentMatrix, - parentMatrix - ); - } - }, +/***/ }), - /** - * Creates a line out of 4 quads and adds it to the vertex batch based on the given line values. - * - * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchLine - * @since 3.55.0 - * - * @param {number} ax - x coordinate of the start of the line. - * @param {number} ay - y coordinate of the start of the line. - * @param {number} bx - x coordinate of the end of the line. - * @param {number} by - y coordinate of the end of the line. - * @param {number} aLineWidth - Width of the start of the line. - * @param {number} bLineWidth - Width of the end of the line. - * @param {number} index - If this line is part of a multi-line draw, the index of the line in the draw. - * @param {boolean} closePath - Does this line close a multi-line path? - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchLine: function (ax, ay, bx, by, aLineWidth, bLineWidth, lineWidth, index, closePath, currentMatrix, parentMatrix) - { - this.renderer.pipelines.set(this); +/***/ 54145: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var calcMatrix = this.calcMatrix; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix - if (parentMatrix) - { - parentMatrix.multiply(currentMatrix, calcMatrix); - } +var GetLeft = __webpack_require__(40163); +var GetTop = __webpack_require__(47196); +var SetBottom = __webpack_require__(73174); +var SetLeft = __webpack_require__(74465); - var dx = bx - ax; - var dy = by - ay; +/** + * Takes given Game Object and aligns it so that it is positioned next to the top left position of the other. + * + * @function Phaser.Display.Align.To.TopLeft + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var TopLeft = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - var len = Math.sqrt(dx * dx + dy * dy); - var al0 = aLineWidth * (by - ay) / len; - var al1 = aLineWidth * (ax - bx) / len; - var bl0 = bLineWidth * (by - ay) / len; - var bl1 = bLineWidth * (ax - bx) / len; + SetLeft(gameObject, GetLeft(alignTo) - offsetX); + SetBottom(gameObject, GetTop(alignTo) - offsetY); - var lx0 = bx - bl0; - var ly0 = by - bl1; - var lx1 = ax - al0; - var ly1 = ay - al1; - var lx2 = bx + bl0; - var ly2 = by + bl1; - var lx3 = ax + al0; - var ly3 = ay + al1; + return gameObject; +}; - // tx0 = bottom right - var brX = calcMatrix.getX(lx0, ly0); - var brY = calcMatrix.getY(lx0, ly0); +module.exports = TopLeft; - // tx1 = bottom left - var blX = calcMatrix.getX(lx1, ly1); - var blY = calcMatrix.getY(lx1, ly1); - // tx2 = top right - var trX = calcMatrix.getX(lx2, ly2); - var trY = calcMatrix.getY(lx2, ly2); +/***/ }), - // tx3 = top left - var tlX = calcMatrix.getX(lx3, ly3); - var tlY = calcMatrix.getY(lx3, ly3); +/***/ 75548: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var tint = this.strokeTint; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var tintTL = tint.TL; - var tintTR = tint.TR; - var tintBL = tint.BL; - var tintBR = tint.BR; +var GetRight = __webpack_require__(70271); +var GetTop = __webpack_require__(47196); +var SetBottom = __webpack_require__(73174); +var SetRight = __webpack_require__(19298); - // TL, BL, BR, TR - this.batchQuad(null, tlX, tlY, blX, blY, brX, brY, trX, trY, 0, 0, 1, 1, tintTL, tintTR, tintBL, tintBR, 2); +/** + * Takes given Game Object and aligns it so that it is positioned next to the top right position of the other. + * + * @function Phaser.Display.Align.To.TopRight + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. + * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. + * @param {number} [offsetX=0] - Optional horizontal offset from the position. + * @param {number} [offsetY=0] - Optional vertical offset from the position. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + */ +var TopRight = function (gameObject, alignTo, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - if (lineWidth <= 2) - { - // No point doing a linejoin if the line isn't thick enough - return; - } + SetRight(gameObject, GetRight(alignTo) + offsetX); + SetBottom(gameObject, GetTop(alignTo) - offsetY); - var prev = this.prevQuad; - var first = this.firstQuad; + return gameObject; +}; - if (index > 0 && prev[4]) - { - this.batchQuad(null, tlX, tlY, blX, blY, prev[0], prev[1], prev[2], prev[3], 0, 0, 1, 1, tintTL, tintTR, tintBL, tintBR, 2); - } - else - { - first[0] = tlX; - first[1] = tlY; - first[2] = blX; - first[3] = blY; - first[4] = 1; - } +module.exports = TopRight; - if (closePath && first[4]) - { - // Add a join for the final path segment - this.batchQuad(null, brX, brY, trX, trY, first[0], first[1], first[2], first[3], 0, 0, 1, 1, tintTL, tintTR, tintBL, tintBR, 2); - } - else - { - // Store it - prev[0] = brX; - prev[1] = brY; - prev[2] = trX; - prev[3] = trY; - prev[4] = 1; - } - } +/***/ }), -}); +/***/ 86639: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -module.exports = MultiPipeline; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Display.Align.To + */ + +module.exports = { + + BottomCenter: __webpack_require__(27118), + BottomLeft: __webpack_require__(84469), + BottomRight: __webpack_require__(51577), + LeftBottom: __webpack_require__(90271), + LeftCenter: __webpack_require__(30466), + LeftTop: __webpack_require__(50087), + QuickSet: __webpack_require__(82590), + RightBottom: __webpack_require__(13555), + RightCenter: __webpack_require__(99049), + RightTop: __webpack_require__(67788), + TopCenter: __webpack_require__(78170), + TopLeft: __webpack_require__(54145), + TopRight: __webpack_require__(75548) + +}; /***/ }), -/* 109 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 21843: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Clamp = __webpack_require__(18); -var Extend = __webpack_require__(17); +var SetCenterX = __webpack_require__(28417); +var SetCenterY = __webpack_require__(81711); /** - * @classdesc - * A Frame is a section of a Texture. + * Positions the Game Object so that it is centered on the given coordinates. * - * @class Frame - * @memberof Phaser.Textures - * @constructor + * @function Phaser.Display.Bounds.CenterOn * @since 3.0.0 * - * @param {Phaser.Textures.Texture} texture - The Texture this Frame is a part of. - * @param {(number|string)} name - The name of this Frame. The name is unique within the Texture. - * @param {number} sourceIndex - The index of the TextureSource that this Frame is a part of. - * @param {number} x - The x coordinate of the top-left of this Frame. - * @param {number} y - The y coordinate of the top-left of this Frame. - * @param {number} width - The width of this Frame. - * @param {number} height - The height of this Frame. + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. + * @param {number} x - The horizontal coordinate to position the Game Object on. + * @param {number} y - The vertical coordinate to position the Game Object on. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. */ -var Frame = new Class({ +var CenterOn = function (gameObject, x, y) +{ + SetCenterX(gameObject, x); - initialize: + return SetCenterY(gameObject, y); +}; - function Frame (texture, name, sourceIndex, x, y, width, height) - { - /** - * The Texture this Frame is a part of. - * - * @name Phaser.Textures.Frame#texture - * @type {Phaser.Textures.Texture} - * @since 3.0.0 - */ - this.texture = texture; +module.exports = CenterOn; - /** - * The name of this Frame. - * The name is unique within the Texture. - * - * @name Phaser.Textures.Frame#name - * @type {string} - * @since 3.0.0 - */ - this.name = name; - /** - * The TextureSource this Frame is part of. - * - * @name Phaser.Textures.Frame#source - * @type {Phaser.Textures.TextureSource} - * @since 3.0.0 - */ - this.source = texture.source[sourceIndex]; +/***/ }), - /** - * The index of the TextureSource in the Texture sources array. - * - * @name Phaser.Textures.Frame#sourceIndex - * @type {number} - * @since 3.0.0 - */ - this.sourceIndex = sourceIndex; +/***/ 97328: +/***/ ((module) => { - /** - * A reference to the Texture Source WebGL Texture that this Frame is using. - * - * @name Phaser.Textures.Frame#glTexture - * @type {?WebGLTexture} - * @default null - * @since 3.11.0 - */ - this.glTexture = this.source.glTexture; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * X position within the source image to cut from. - * - * @name Phaser.Textures.Frame#cutX - * @type {number} - * @since 3.0.0 - */ - this.cutX; +/** + * Returns the bottom coordinate from the bounds of the Game Object. + * + * @function Phaser.Display.Bounds.GetBottom + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * + * @return {number} The bottom coordinate of the bounds of the Game Object. + */ +var GetBottom = function (gameObject) +{ + return (gameObject.y + gameObject.height) - (gameObject.height * gameObject.originY); +}; - /** - * Y position within the source image to cut from. - * - * @name Phaser.Textures.Frame#cutY - * @type {number} - * @since 3.0.0 - */ - this.cutY; +module.exports = GetBottom; - /** - * The width of the area in the source image to cut. - * - * @name Phaser.Textures.Frame#cutWidth - * @type {number} - * @since 3.0.0 - */ - this.cutWidth; - /** - * The height of the area in the source image to cut. - * - * @name Phaser.Textures.Frame#cutHeight - * @type {number} - * @since 3.0.0 - */ - this.cutHeight; +/***/ }), - /** - * The X rendering offset of this Frame, taking trim into account. - * - * @name Phaser.Textures.Frame#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.x = 0; +/***/ 7126: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The Y rendering offset of this Frame, taking trim into account. - * - * @name Phaser.Textures.Frame#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.y = 0; +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The rendering width of this Frame, taking trim into account. - * - * @name Phaser.Textures.Frame#width - * @type {number} - * @since 3.0.0 - */ - this.width; +var GetBottom = __webpack_require__(97328); +var GetLeft = __webpack_require__(40163); +var GetRight = __webpack_require__(70271); +var GetTop = __webpack_require__(47196); +var Rectangle = __webpack_require__(74118); - /** - * The rendering height of this Frame, taking trim into account. - * - * @name Phaser.Textures.Frame#height - * @type {number} - * @since 3.0.0 - */ - this.height; +/** + * Returns the unrotated bounds of the Game Object as a rectangle. + * + * @function Phaser.Display.Bounds.GetBounds + * @since 3.24.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * @param {(Phaser.Geom.Rectangle|object)} [output] - An object to store the values in. If not provided a new Rectangle will be created. + * + * @return {(Phaser.Geom.Rectangle|object)} - The bounds of the Game Object. + */ +var GetBounds = function (gameObject, output) +{ + if (output === undefined) { output = new Rectangle(); } - /** - * Half the width, floored. - * Precalculated for the renderer. - * - * @name Phaser.Textures.Frame#halfWidth - * @type {number} - * @since 3.0.0 - */ - this.halfWidth; + var left = GetLeft(gameObject); + var top = GetTop(gameObject); - /** - * Half the height, floored. - * Precalculated for the renderer. - * - * @name Phaser.Textures.Frame#halfHeight - * @type {number} - * @since 3.0.0 - */ - this.halfHeight; + output.x = left; + output.y = top; + output.width = GetRight(gameObject) - left; + output.height = GetBottom(gameObject) - top; - /** - * The x center of this frame, floored. - * - * @name Phaser.Textures.Frame#centerX - * @type {number} - * @since 3.0.0 - */ - this.centerX; + return output; +}; - /** - * The y center of this frame, floored. - * - * @name Phaser.Textures.Frame#centerY - * @type {number} - * @since 3.0.0 - */ - this.centerY; +module.exports = GetBounds; - /** - * The horizontal pivot point of this Frame. - * - * @name Phaser.Textures.Frame#pivotX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.pivotX = 0; - /** - * The vertical pivot point of this Frame. - * - * @name Phaser.Textures.Frame#pivotY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.pivotY = 0; +/***/ }), - /** - * Does this Frame have a custom pivot point? - * - * @name Phaser.Textures.Frame#customPivot - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.customPivot = false; +/***/ 59994: +/***/ ((module) => { - /** - * **CURRENTLY UNSUPPORTED** - * - * Is this frame is rotated or not in the Texture? - * Rotation allows you to use rotated frames in texture atlas packing. - * It has nothing to do with Sprite rotation. - * - * @name Phaser.Textures.Frame#rotated - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.rotated = false; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Over-rides the Renderer setting. - * -1 = use Renderer Setting - * 0 = No rounding - * 1 = Round - * - * @name Phaser.Textures.Frame#autoRound - * @type {number} - * @default -1 - * @since 3.0.0 - */ - this.autoRound = -1; +/** + * Returns the center x coordinate from the bounds of the Game Object. + * + * @function Phaser.Display.Bounds.GetCenterX + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * + * @return {number} The center x coordinate of the bounds of the Game Object. + */ +var GetCenterX = function (gameObject) +{ + return gameObject.x - (gameObject.width * gameObject.originX) + (gameObject.width * 0.5); +}; - /** - * Any Frame specific custom data can be stored here. - * - * @name Phaser.Textures.Frame#customData - * @type {object} - * @since 3.0.0 - */ - this.customData = {}; +module.exports = GetCenterX; - /** - * WebGL UV u0 value. - * - * @name Phaser.Textures.Frame#u0 - * @type {number} - * @default 0 - * @since 3.11.0 - */ - this.u0 = 0; - /** - * WebGL UV v0 value. - * - * @name Phaser.Textures.Frame#v0 - * @type {number} - * @default 0 - * @since 3.11.0 - */ - this.v0 = 0; +/***/ }), - /** - * WebGL UV u1 value. - * - * @name Phaser.Textures.Frame#u1 - * @type {number} - * @default 0 - * @since 3.11.0 - */ - this.u1 = 0; +/***/ 29568: +/***/ ((module) => { - /** - * WebGL UV v1 value. - * - * @name Phaser.Textures.Frame#v1 - * @type {number} - * @default 0 - * @since 3.11.0 - */ - this.v1 = 0; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The un-modified source frame, trim and UV data. - * - * @name Phaser.Textures.Frame#data - * @type {object} - * @private - * @since 3.0.0 - */ - this.data = { - cut: { - x: 0, - y: 0, - w: 0, - h: 0, - r: 0, - b: 0 - }, - trim: false, - sourceSize: { - w: 0, - h: 0 - }, - spriteSourceSize: { - x: 0, - y: 0, - w: 0, - h: 0, - r: 0, - b: 0 - }, - radius: 0, - drawImage: { - x: 0, - y: 0, - width: 0, - height: 0 - } - }; +/** + * Returns the center y coordinate from the bounds of the Game Object. + * + * @function Phaser.Display.Bounds.GetCenterY + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * + * @return {number} The center y coordinate of the bounds of the Game Object. + */ +var GetCenterY = function (gameObject) +{ + return gameObject.y - (gameObject.height * gameObject.originY) + (gameObject.height * 0.5); +}; - this.setSize(width, height, x, y); - }, +module.exports = GetCenterY; - /** - * Sets the width, height, x and y of this Frame. - * - * This is called automatically by the constructor - * and should rarely be changed on-the-fly. - * - * @method Phaser.Textures.Frame#setSize - * @since 3.7.0 - * - * @param {number} width - The width of the frame before being trimmed. - * @param {number} height - The height of the frame before being trimmed. - * @param {number} [x=0] - The x coordinate of the top-left of this Frame. - * @param {number} [y=0] - The y coordinate of the top-left of this Frame. - * - * @return {Phaser.Textures.Frame} This Frame object. - */ - setSize: function (width, height, x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - this.cutX = x; - this.cutY = y; - this.cutWidth = width; - this.cutHeight = height; +/***/ }), - this.width = width; - this.height = height; +/***/ 40163: +/***/ ((module) => { - this.halfWidth = Math.floor(width * 0.5); - this.halfHeight = Math.floor(height * 0.5); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.centerX = Math.floor(width / 2); - this.centerY = Math.floor(height / 2); +/** + * Returns the left coordinate from the bounds of the Game Object. + * + * @function Phaser.Display.Bounds.GetLeft + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * + * @return {number} The left coordinate of the bounds of the Game Object. + */ +var GetLeft = function (gameObject) +{ + return gameObject.x - (gameObject.width * gameObject.originX); +}; - var data = this.data; - var cut = data.cut; +module.exports = GetLeft; - cut.x = x; - cut.y = y; - cut.w = width; - cut.h = height; - cut.r = x + width; - cut.b = y + height; - data.sourceSize.w = width; - data.sourceSize.h = height; +/***/ }), - data.spriteSourceSize.w = width; - data.spriteSourceSize.h = height; +/***/ 52088: +/***/ ((module) => { - data.radius = 0.5 * Math.sqrt(width * width + height * height); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var drawImage = data.drawImage; +/** + * Returns the amount the Game Object is visually offset from its x coordinate. + * This is the same as `width * origin.x`. + * This value will only be > 0 if `origin.x` is not equal to zero. + * + * @function Phaser.Display.Bounds.GetOffsetX + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * + * @return {number} The horizontal offset of the Game Object. + */ +var GetOffsetX = function (gameObject) +{ + return gameObject.width * gameObject.originX; +}; - drawImage.x = x; - drawImage.y = y; - drawImage.width = width; - drawImage.height = height; +module.exports = GetOffsetX; - return this.updateUVs(); - }, - /** - * If the frame was trimmed when added to the Texture Atlas, this records the trim and source data. - * - * @method Phaser.Textures.Frame#setTrim - * @since 3.0.0 - * - * @param {number} actualWidth - The width of the frame before being trimmed. - * @param {number} actualHeight - The height of the frame before being trimmed. - * @param {number} destX - The destination X position of the trimmed frame for display. - * @param {number} destY - The destination Y position of the trimmed frame for display. - * @param {number} destWidth - The destination width of the trimmed frame for display. - * @param {number} destHeight - The destination height of the trimmed frame for display. - * - * @return {Phaser.Textures.Frame} This Frame object. - */ - setTrim: function (actualWidth, actualHeight, destX, destY, destWidth, destHeight) - { - var data = this.data; - var ss = data.spriteSourceSize; +/***/ }), - // Store actual values +/***/ 23379: +/***/ ((module) => { - data.trim = true; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - data.sourceSize.w = actualWidth; - data.sourceSize.h = actualHeight; +/** + * Returns the amount the Game Object is visually offset from its y coordinate. + * This is the same as `width * origin.y`. + * This value will only be > 0 if `origin.y` is not equal to zero. + * + * @function Phaser.Display.Bounds.GetOffsetY + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * + * @return {number} The vertical offset of the Game Object. + */ +var GetOffsetY = function (gameObject) +{ + return gameObject.height * gameObject.originY; +}; - ss.x = destX; - ss.y = destY; - ss.w = destWidth; - ss.h = destHeight; - ss.r = destX + destWidth; - ss.b = destY + destHeight; +module.exports = GetOffsetY; - // Adjust properties - this.x = destX; - this.y = destY; - this.width = destWidth; - this.height = destHeight; +/***/ }), - this.halfWidth = destWidth * 0.5; - this.halfHeight = destHeight * 0.5; +/***/ 70271: +/***/ ((module) => { - this.centerX = Math.floor(destWidth / 2); - this.centerY = Math.floor(destHeight / 2); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this.updateUVs(); - }, +/** + * Returns the right coordinate from the bounds of the Game Object. + * + * @function Phaser.Display.Bounds.GetRight + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * + * @return {number} The right coordinate of the bounds of the Game Object. + */ +var GetRight = function (gameObject) +{ + return (gameObject.x + gameObject.width) - (gameObject.width * gameObject.originX); +}; - /** - * Takes a crop data object and, based on the rectangular region given, calculates the - * required UV coordinates in order to crop this Frame for WebGL and Canvas rendering. - * - * This is called directly by the Game Object Texture Components `setCrop` method. - * Please use that method to crop a Game Object. - * - * @method Phaser.Textures.Frame#setCropUVs - * @since 3.11.0 - * - * @param {object} crop - The crop data object. This is the `GameObject._crop` property. - * @param {number} x - The x coordinate to start the crop from. Cannot be negative or exceed the Frame width. - * @param {number} y - The y coordinate to start the crop from. Cannot be negative or exceed the Frame height. - * @param {number} width - The width of the crop rectangle. Cannot exceed the Frame width. - * @param {number} height - The height of the crop rectangle. Cannot exceed the Frame height. - * @param {boolean} flipX - Does the parent Game Object have flipX set? - * @param {boolean} flipY - Does the parent Game Object have flipY set? - * - * @return {object} The updated crop data object. - */ - setCropUVs: function (crop, x, y, width, height, flipX, flipY) - { - // Clamp the input values +module.exports = GetRight; - var cx = this.cutX; - var cy = this.cutY; - var cw = this.cutWidth; - var ch = this.cutHeight; - var rw = this.realWidth; - var rh = this.realHeight; - x = Clamp(x, 0, rw); - y = Clamp(y, 0, rh); +/***/ }), - width = Clamp(width, 0, rw - x); - height = Clamp(height, 0, rh - y); +/***/ 47196: +/***/ ((module) => { - var ox = cx + x; - var oy = cy + y; - var ow = width; - var oh = height; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var data = this.data; +/** + * Returns the top coordinate from the bounds of the Game Object. + * + * @function Phaser.Display.Bounds.GetTop + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. + * + * @return {number} The top coordinate of the bounds of the Game Object. + */ +var GetTop = function (gameObject) +{ + return gameObject.y - (gameObject.height * gameObject.originY); +}; - if (data.trim) - { - var ss = data.spriteSourceSize; +module.exports = GetTop; - // Need to check for intersection between the cut area and the crop area - // If there is none, we set UV to be empty, otherwise set it to be the intersection area - width = Clamp(width, 0, cw - x); - height = Clamp(height, 0, ch - y); +/***/ }), - var cropRight = x + width; - var cropBottom = y + height; +/***/ 73174: +/***/ ((module) => { - var intersects = !(ss.r < x || ss.b < y || ss.x > cropRight || ss.y > cropBottom); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (intersects) - { - var ix = Math.max(ss.x, x); - var iy = Math.max(ss.y, y); - var iw = Math.min(ss.r, cropRight) - ix; - var ih = Math.min(ss.b, cropBottom) - iy; +/** + * Positions the Game Object so that the bottom of its bounds aligns with the given coordinate. + * + * @function Phaser.Display.Bounds.SetBottom + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. + * @param {number} value - The coordinate to position the Game Object bounds on. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + */ +var SetBottom = function (gameObject, value) +{ + gameObject.y = (value - gameObject.height) + (gameObject.height * gameObject.originY); - ow = iw; - oh = ih; + return gameObject; +}; - if (flipX) - { - ox = cx + (cw - (ix - ss.x) - iw); - } - else - { - ox = cx + (ix - ss.x); - } +module.exports = SetBottom; - if (flipY) - { - oy = cy + (ch - (iy - ss.y) - ih); - } - else - { - oy = cy + (iy - ss.y); - } - x = ix; - y = iy; +/***/ }), - width = iw; - height = ih; - } - else - { - ox = 0; - oy = 0; - ow = 0; - oh = 0; - } - } - else - { - if (flipX) - { - ox = cx + (cw - x - width); - } +/***/ 28417: +/***/ ((module) => { - if (flipY) - { - oy = cy + (ch - y - height); - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var tw = this.source.width; - var th = this.source.height; +/** + * Positions the Game Object so that the center top of its bounds aligns with the given coordinate. + * + * @function Phaser.Display.Bounds.SetCenterX + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. + * @param {number} x - The coordinate to position the Game Object bounds on. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + */ +var SetCenterX = function (gameObject, x) +{ + var offsetX = gameObject.width * gameObject.originX; - // Map the given coordinates into UV space, clamping to the 0-1 range. + gameObject.x = (x + offsetX) - (gameObject.width * 0.5); - crop.u0 = Math.max(0, ox / tw); - crop.v0 = Math.max(0, oy / th); - crop.u1 = Math.min(1, (ox + ow) / tw); - crop.v1 = Math.min(1, (oy + oh) / th); + return gameObject; +}; - crop.x = x; - crop.y = y; +module.exports = SetCenterX; - crop.cx = ox; - crop.cy = oy; - crop.cw = ow; - crop.ch = oh; - crop.width = width; - crop.height = height; +/***/ }), - crop.flipX = flipX; - crop.flipY = flipY; +/***/ 81711: +/***/ ((module) => { - return crop; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Takes a crop data object and recalculates the UVs based on the dimensions inside the crop object. - * Called automatically by `setFrame`. - * - * @method Phaser.Textures.Frame#updateCropUVs - * @since 3.11.0 - * - * @param {object} crop - The crop data object. This is the `GameObject._crop` property. - * @param {boolean} flipX - Does the parent Game Object have flipX set? - * @param {boolean} flipY - Does the parent Game Object have flipY set? - * - * @return {object} The updated crop data object. - */ - updateCropUVs: function (crop, flipX, flipY) - { - return this.setCropUVs(crop, crop.x, crop.y, crop.width, crop.height, flipX, flipY); - }, +/** + * Positions the Game Object so that the center top of its bounds aligns with the given coordinate. + * + * @function Phaser.Display.Bounds.SetCenterY + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. + * @param {number} y - The coordinate to position the Game Object bounds on. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + */ +var SetCenterY = function (gameObject, y) +{ + var offsetY = gameObject.height * gameObject.originY; - /** - * Directly sets the canvas and WebGL UV data for this frame. - * - * Use this if you need to override the values that are generated automatically - * when the Frame is created. - * - * @method Phaser.Textures.Frame#setUVs - * @since 3.50.0 - * - * @param {number} width - Width of this frame for the Canvas data. - * @param {number} height - Height of this frame for the Canvas data. - * @param {number} u0 - UV u0 value. - * @param {number} v0 - UV v0 value. - * @param {number} u1 - UV u1 value. - * @param {number} v1 - UV v1 value. - * - * @return {Phaser.Textures.Frame} This Frame object. - */ - setUVs: function (width, height, u0, v0, u1, v1) - { - // Canvas data + gameObject.y = (y + offsetY) - (gameObject.height * 0.5); - var cd = this.data.drawImage; + return gameObject; +}; - cd.width = width; - cd.height = height; +module.exports = SetCenterY; - // WebGL data - this.u0 = u0; - this.v0 = v0; +/***/ }), - this.u1 = u1; - this.v1 = v1; +/***/ 74465: +/***/ ((module) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Updates the internal WebGL UV cache and the drawImage cache. - * - * @method Phaser.Textures.Frame#updateUVs - * @since 3.0.0 - * - * @return {Phaser.Textures.Frame} This Frame object. - */ - updateUVs: function () - { - var cx = this.cutX; - var cy = this.cutY; - var cw = this.cutWidth; - var ch = this.cutHeight; +/** + * Positions the Game Object so that the left of its bounds aligns with the given coordinate. + * + * @function Phaser.Display.Bounds.SetLeft + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. + * @param {number} value - The coordinate to position the Game Object bounds on. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + */ +var SetLeft = function (gameObject, value) +{ + gameObject.x = value + (gameObject.width * gameObject.originX); - // Canvas data + return gameObject; +}; - var cd = this.data.drawImage; +module.exports = SetLeft; - cd.width = cw; - cd.height = ch; - // WebGL data +/***/ }), - var tw = this.source.width; - var th = this.source.height; +/***/ 19298: +/***/ ((module) => { - this.u0 = cx / tw; - this.v0 = cy / th; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.u1 = (cx + cw) / tw; - this.v1 = (cy + ch) / th; +/** + * Positions the Game Object so that the left of its bounds aligns with the given coordinate. + * + * @function Phaser.Display.Bounds.SetRight + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. + * @param {number} value - The coordinate to position the Game Object bounds on. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + */ +var SetRight = function (gameObject, value) +{ + gameObject.x = (value - gameObject.width) + (gameObject.width * gameObject.originX); - return this; - }, + return gameObject; +}; + +module.exports = SetRight; + + +/***/ }), + +/***/ 84349: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Positions the Game Object so that the top of its bounds aligns with the given coordinate. + * + * @function Phaser.Display.Bounds.SetTop + * @since 3.0.0 + * + * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. + * @param {number} value - The coordinate to position the Game Object bounds on. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + */ +var SetTop = function (gameObject, value) +{ + gameObject.y = value + (gameObject.height * gameObject.originY); + + return gameObject; +}; + +module.exports = SetTop; + + +/***/ }), + +/***/ 15252: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Display.Bounds + */ + +module.exports = { + + CenterOn: __webpack_require__(21843), + GetBottom: __webpack_require__(97328), + GetBounds: __webpack_require__(7126), + GetCenterX: __webpack_require__(59994), + GetCenterY: __webpack_require__(29568), + GetLeft: __webpack_require__(40163), + GetOffsetX: __webpack_require__(52088), + GetOffsetY: __webpack_require__(23379), + GetRight: __webpack_require__(70271), + GetTop: __webpack_require__(47196), + SetBottom: __webpack_require__(73174), + SetCenterX: __webpack_require__(28417), + SetCenterY: __webpack_require__(81711), + SetLeft: __webpack_require__(74465), + SetRight: __webpack_require__(19298), + SetTop: __webpack_require__(84349) + +}; + + +/***/ }), + +/***/ 70616: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Display.Canvas.CanvasInterpolation + * @since 3.0.0 + */ +var CanvasInterpolation = { /** - * Updates the internal WebGL UV cache. + * Sets the CSS image-rendering property on the given canvas to be 'crisp' (aka 'optimize contrast' on webkit). * - * @method Phaser.Textures.Frame#updateUVsInverted + * @function Phaser.Display.Canvas.CanvasInterpolation.setCrisp * @since 3.0.0 - * - * @return {Phaser.Textures.Frame} This Frame object. + * + * @param {HTMLCanvasElement} canvas - The canvas object to have the style set on. + * + * @return {HTMLCanvasElement} The canvas. */ - updateUVsInverted: function () + setCrisp: function (canvas) { - var tw = this.source.width; - var th = this.source.height; + var types = [ 'optimizeSpeed', '-moz-crisp-edges', '-o-crisp-edges', '-webkit-optimize-contrast', 'optimize-contrast', 'crisp-edges', 'pixelated' ]; - this.u0 = (this.cutX + this.cutHeight) / tw; - this.v0 = this.cutY / th; + types.forEach(function (type) + { + canvas.style['image-rendering'] = type; + }); - this.u1 = this.cutX / tw; - this.v1 = (this.cutY + this.cutWidth) / th; + canvas.style.msInterpolationMode = 'nearest-neighbor'; - return this; + return canvas; }, /** - * Clones this Frame into a new Frame object. + * Sets the CSS image-rendering property on the given canvas to be 'bicubic' (aka 'auto'). * - * @method Phaser.Textures.Frame#clone + * @function Phaser.Display.Canvas.CanvasInterpolation.setBicubic * @since 3.0.0 - * - * @return {Phaser.Textures.Frame} A clone of this Frame. + * + * @param {HTMLCanvasElement} canvas - The canvas object to have the style set on. + * + * @return {HTMLCanvasElement} The canvas. */ - clone: function () + setBicubic: function (canvas) { - var clone = new Frame(this.texture, this.name, this.sourceIndex); + canvas.style['image-rendering'] = 'auto'; + canvas.style.msInterpolationMode = 'bicubic'; - clone.cutX = this.cutX; - clone.cutY = this.cutY; - clone.cutWidth = this.cutWidth; - clone.cutHeight = this.cutHeight; + return canvas; + } - clone.x = this.x; - clone.y = this.y; +}; - clone.width = this.width; - clone.height = this.height; +module.exports = CanvasInterpolation; - clone.halfWidth = this.halfWidth; - clone.halfHeight = this.halfHeight; - clone.centerX = this.centerX; - clone.centerY = this.centerY; +/***/ }), - clone.rotated = this.rotated; +/***/ 61068: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - clone.data = Extend(true, clone.data, this.data); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - clone.updateUVs(); +var CONST = __webpack_require__(86459); +var Smoothing = __webpack_require__(8213); - return clone; - }, +// The pool into which the canvas elements are placed. +var pool = []; + +// Automatically apply smoothing(false) to created Canvas elements +var _disableContextSmoothing = false; +/** + * The CanvasPool is a global static object, that allows Phaser to recycle and pool 2D Context Canvas DOM elements. + * It does not pool WebGL Contexts, because once the context options are set they cannot be modified again, + * which is useless for some of the Phaser pipelines / renderer. + * + * This singleton is instantiated as soon as Phaser loads, before a Phaser.Game instance has even been created. + * Which means all instances of Phaser Games on the same page can share the one single pool. + * + * @namespace Phaser.Display.Canvas.CanvasPool + * @since 3.0.0 + */ +var CanvasPool = function () +{ /** - * Destroys this Frame by nulling its reference to the parent Texture and and data objects. + * Creates a new Canvas DOM element, or pulls one from the pool if free. * - * @method Phaser.Textures.Frame#destroy + * @function Phaser.Display.Canvas.CanvasPool.create * @since 3.0.0 + * + * @param {*} parent - The parent of the Canvas object. + * @param {number} [width=1] - The width of the Canvas. + * @param {number} [height=1] - The height of the Canvas. + * @param {number} [canvasType=Phaser.CANVAS] - The type of the Canvas. Either `Phaser.CANVAS` or `Phaser.WEBGL`. + * @param {boolean} [selfParent=false] - Use the generated Canvas element as the parent? + * + * @return {HTMLCanvasElement} The canvas element that was created or pulled from the pool */ - destroy: function () + var create = function (parent, width, height, canvasType, selfParent) { - this.source = null; - this.texture = null; - this.glTexture = null; - this.customData = null; - this.data = null; - }, + if (width === undefined) { width = 1; } + if (height === undefined) { height = 1; } + if (canvasType === undefined) { canvasType = CONST.CANVAS; } + if (selfParent === undefined) { selfParent = false; } - /** - * The width of the Frame in its un-trimmed, un-padded state, as prepared in the art package, - * before being packed. - * - * @name Phaser.Textures.Frame#realWidth - * @type {number} - * @readonly - * @since 3.0.0 - */ - realWidth: { + var canvas; + var container = first(canvasType); - get: function () + if (container === null) { - return this.data.sourceSize.w; + container = { + parent: parent, + canvas: document.createElement('canvas'), + type: canvasType + }; + + if (canvasType === CONST.CANVAS) + { + pool.push(container); + } + + canvas = container.canvas; } + else + { + container.parent = parent; - }, + canvas = container.canvas; + } - /** - * The height of the Frame in its un-trimmed, un-padded state, as prepared in the art package, - * before being packed. - * - * @name Phaser.Textures.Frame#realHeight - * @type {number} - * @readonly - * @since 3.0.0 - */ - realHeight: { + if (selfParent) + { + container.parent = canvas; + } - get: function () + canvas.width = width; + canvas.height = height; + + if (_disableContextSmoothing && canvasType === CONST.CANVAS) { - return this.data.sourceSize.h; + Smoothing.disable(canvas.getContext('2d', { willReadFrequently: false })); } - }, + return canvas; + }; /** - * The radius of the Frame (derived from sqrt(w * w + h * h) / 2) + * Creates a new Canvas DOM element, or pulls one from the pool if free. * - * @name Phaser.Textures.Frame#radius - * @type {number} - * @readonly + * @function Phaser.Display.Canvas.CanvasPool.create2D * @since 3.0.0 + * + * @param {*} parent - The parent of the Canvas object. + * @param {number} [width=1] - The width of the Canvas. + * @param {number} [height=1] - The height of the Canvas. + * + * @return {HTMLCanvasElement} The created canvas. */ - radius: { - - get: function () - { - return this.data.radius; - } - - }, + var create2D = function (parent, width, height) + { + return create(parent, width, height, CONST.CANVAS); + }; /** - * Is the Frame trimmed or not? + * Creates a new Canvas DOM element, or pulls one from the pool if free. * - * @name Phaser.Textures.Frame#trimmed - * @type {boolean} - * @readonly + * @function Phaser.Display.Canvas.CanvasPool.createWebGL * @since 3.0.0 + * + * @param {*} parent - The parent of the Canvas object. + * @param {number} [width=1] - The width of the Canvas. + * @param {number} [height=1] - The height of the Canvas. + * + * @return {HTMLCanvasElement} The created WebGL canvas. */ - trimmed: { - - get: function () - { - return this.data.trim; - } - - }, + var createWebGL = function (parent, width, height) + { + return create(parent, width, height, CONST.WEBGL); + }; /** - * The Canvas drawImage data object. + * Gets the first free canvas index from the pool. * - * @name Phaser.Textures.Frame#canvasData - * @type {object} - * @readonly + * @function Phaser.Display.Canvas.CanvasPool.first * @since 3.0.0 + * + * @param {number} [canvasType=Phaser.CANVAS] - The type of the Canvas. Either `Phaser.CANVAS` or `Phaser.WEBGL`. + * + * @return {HTMLCanvasElement} The first free canvas, or `null` if a WebGL canvas was requested or if the pool doesn't have free canvases. */ - canvasData: { + var first = function (canvasType) + { + if (canvasType === undefined) { canvasType = CONST.CANVAS; } - get: function () + if (canvasType === CONST.WEBGL) { - return this.data.drawImage; + return null; } - } - -}); + for (var i = 0; i < pool.length; i++) + { + var container = pool[i]; -module.exports = Frame; + if (!container.parent && container.type === canvasType) + { + return container; + } + } + return null; + }; -/***/ }), -/* 110 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Looks up a canvas based on its parent, and if found puts it back in the pool, freeing it up for re-use. + * The canvas has its width and height set to 1, and its parent attribute nulled. + * + * @function Phaser.Display.Canvas.CanvasPool.remove + * @since 3.0.0 + * + * @param {*} parent - The canvas or the parent of the canvas to free. + */ + var remove = function (parent) + { + // Check to see if the parent is a canvas object + var isCanvas = parent instanceof HTMLCanvasElement; -/** + pool.forEach(function (container) + { + if ((isCanvas && container.canvas === parent) || (!isCanvas && container.parent === parent)) + { + container.parent = null; + container.canvas.width = 1; + container.canvas.height = 1; + } + }); + }; + + /** + * Gets the total number of used canvas elements in the pool. + * + * @function Phaser.Display.Canvas.CanvasPool.total + * @since 3.0.0 + * + * @return {number} The number of used canvases. + */ + var total = function () + { + var c = 0; + + pool.forEach(function (container) + { + if (container.parent) + { + c++; + } + }); + + return c; + }; + + /** + * Gets the total number of free canvas elements in the pool. + * + * @function Phaser.Display.Canvas.CanvasPool.free + * @since 3.0.0 + * + * @return {number} The number of free canvases. + */ + var free = function () + { + return pool.length - total(); + }; + + /** + * Disable context smoothing on any new Canvas element created. + * + * @function Phaser.Display.Canvas.CanvasPool.disableSmoothing + * @since 3.0.0 + */ + var disableSmoothing = function () + { + _disableContextSmoothing = true; + }; + + /** + * Enable context smoothing on any new Canvas element created. + * + * @function Phaser.Display.Canvas.CanvasPool.enableSmoothing + * @since 3.0.0 + */ + var enableSmoothing = function () + { + _disableContextSmoothing = false; + }; + + return { + create2D: create2D, + create: create, + createWebGL: createWebGL, + disableSmoothing: disableSmoothing, + enableSmoothing: enableSmoothing, + first: first, + free: free, + pool: pool, + remove: remove, + total: total + }; +}; + +// If we export the called function here, it'll only be invoked once (not every time it's required). +module.exports = CanvasPool(); + + +/***/ }), + +/***/ 8213: +/***/ ((module) => { + +/** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayUtils = __webpack_require__(208); -var Class = __webpack_require__(0); -var NOOP = __webpack_require__(1); -var StableSort = __webpack_require__(79); +// Browser specific prefix, so not going to change between contexts, only between browsers +var prefix = ''; /** - * @callback EachListCallback + * @namespace Phaser.Display.Canvas.Smoothing + * @since 3.0.0 + */ +var Smoothing = function () +{ + /** + * Gets the Smoothing Enabled vendor prefix being used on the given context, or null if not set. + * + * @function Phaser.Display.Canvas.Smoothing.getPrefix + * @since 3.0.0 + * + * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The canvas context to check. + * + * @return {string} The name of the property on the context which controls image smoothing (either `imageSmoothingEnabled` or a vendor-prefixed version thereof), or `null` if not supported. + */ + var getPrefix = function (context) + { + var vendors = [ 'i', 'webkitI', 'msI', 'mozI', 'oI' ]; + + for (var i = 0; i < vendors.length; i++) + { + var s = vendors[i] + 'mageSmoothingEnabled'; + + if (s in context) + { + return s; + } + } + + return null; + }; + + /** + * Sets the Image Smoothing property on the given context. Set to false to disable image smoothing. + * By default browsers have image smoothing enabled, which isn't always what you visually want, especially + * when using pixel art in a game. Note that this sets the property on the context itself, so that any image + * drawn to the context will be affected. This sets the property across all current browsers but support is + * patchy on earlier browsers, especially on mobile. + * + * @function Phaser.Display.Canvas.Smoothing.enable + * @since 3.0.0 + * + * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The context on which to enable smoothing. + * + * @return {(CanvasRenderingContext2D|WebGLRenderingContext)} The provided context. + */ + var enable = function (context) + { + if (prefix === '') + { + prefix = getPrefix(context); + } + + if (prefix) + { + context[prefix] = true; + } + + return context; + }; + + /** + * Sets the Image Smoothing property on the given context. Set to false to disable image smoothing. + * By default browsers have image smoothing enabled, which isn't always what you visually want, especially + * when using pixel art in a game. Note that this sets the property on the context itself, so that any image + * drawn to the context will be affected. This sets the property across all current browsers but support is + * patchy on earlier browsers, especially on mobile. + * + * @function Phaser.Display.Canvas.Smoothing.disable + * @since 3.0.0 + * + * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The context on which to disable smoothing. + * + * @return {(CanvasRenderingContext2D|WebGLRenderingContext)} The provided context. + */ + var disable = function (context) + { + if (prefix === '') + { + prefix = getPrefix(context); + } + + if (prefix) + { + context[prefix] = false; + } + + return context; + }; + + /** + * Returns `true` if the given context has image smoothing enabled, otherwise returns `false`. + * Returns null if no smoothing prefix is available. + * + * @function Phaser.Display.Canvas.Smoothing.isEnabled + * @since 3.0.0 + * + * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The context to check. + * + * @return {?boolean} `true` if smoothing is enabled on the context, otherwise `false`. `null` if not supported. + */ + var isEnabled = function (context) + { + return (prefix !== null) ? context[prefix] : null; + }; + + return { + disable: disable, + enable: enable, + getPrefix: getPrefix, + isEnabled: isEnabled + }; + +}; + +module.exports = Smoothing(); + + +/***/ }), + +/***/ 59271: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Sets the touch-action property on the canvas style. Can be used to disable default browser touch actions. * - * @param {I} item - The item which is currently being processed. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + * @function Phaser.Display.Canvas.TouchAction + * @since 3.0.0 + * + * @param {HTMLCanvasElement} canvas - The canvas element to have the style applied to. + * @param {string} [value='none'] - The touch action value to set on the canvas. Set to `none` to disable touch actions. + * + * @return {HTMLCanvasElement} The canvas element. + */ +var TouchAction = function (canvas, value) +{ + if (value === undefined) { value = 'none'; } + + canvas.style['msTouchAction'] = value; + canvas.style['ms-touch-action'] = value; + canvas.style['touch-action'] = value; + + return canvas; +}; + +module.exports = TouchAction; + + +/***/ }), + +/***/ 36505: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Sets the user-select property on the canvas style. Can be used to disable default browser selection actions. + * + * @function Phaser.Display.Canvas.UserSelect + * @since 3.0.0 + * + * @param {HTMLCanvasElement} canvas - The canvas element to have the style applied to. + * @param {string} [value='none'] - The touch callout value to set on the canvas. Set to `none` to disable touch callouts. + * + * @return {HTMLCanvasElement} The canvas element. + */ +var UserSelect = function (canvas, value) +{ + if (value === undefined) { value = 'none'; } + + var vendors = [ + '-webkit-', + '-khtml-', + '-moz-', + '-ms-', + '' + ]; + + vendors.forEach(function (vendor) + { + canvas.style[vendor + 'user-select'] = value; + }); + + canvas.style['-webkit-touch-callout'] = value; + canvas.style['-webkit-tap-highlight-color'] = 'rgba(0, 0, 0, 0)'; + + return canvas; +}; + +module.exports = UserSelect; + + +/***/ }), + +/***/ 23514: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Display.Canvas + */ + +module.exports = { + + CanvasInterpolation: __webpack_require__(70616), + CanvasPool: __webpack_require__(61068), + Smoothing: __webpack_require__(8213), + TouchAction: __webpack_require__(59271), + UserSelect: __webpack_require__(36505) + +}; + + +/***/ }), + +/***/ 27119: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var GetColor = __webpack_require__(22946); +var GetColor32 = __webpack_require__(5657); +var HSVToRGB = __webpack_require__(24650); +var RGBToHSV = __webpack_require__(68033); + +/** + * @namespace Phaser.Display.Color */ /** * @classdesc - * List is a generic implementation of an ordered list which contains utility methods for retrieving, manipulating, and iterating items. + * The Color class holds a single color value and allows for easy modification and reading of it. * - * @class List - * @memberof Phaser.Structs + * @class Color + * @memberof Phaser.Display * @constructor * @since 3.0.0 * - * @generic T - * - * @param {*} parent - The parent of this list. + * @param {number} [red=0] - The red color value. A number between 0 and 255. + * @param {number} [green=0] - The green color value. A number between 0 and 255. + * @param {number} [blue=0] - The blue color value. A number between 0 and 255. + * @param {number} [alpha=255] - The alpha value. A number between 0 and 255. */ -var List = new Class({ +var Color = new Class({ initialize: - function List (parent) + function Color (red, green, blue, alpha) { + if (red === undefined) { red = 0; } + if (green === undefined) { green = 0; } + if (blue === undefined) { blue = 0; } + if (alpha === undefined) { alpha = 255; } + /** - * The parent of this list. + * The internal red color value. * - * @name Phaser.Structs.List#parent - * @type {*} + * @name Phaser.Display.Color#r + * @type {number} + * @private + * @default 0 * @since 3.0.0 */ - this.parent = parent; + this.r = 0; /** - * The objects that belong to this collection. + * The internal green color value. * - * @genericUse {T[]} - [$type] + * @name Phaser.Display.Color#g + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this.g = 0; + + /** + * The internal blue color value. * - * @name Phaser.Structs.List#list - * @type {Array.<*>} - * @default [] + * @name Phaser.Display.Color#b + * @type {number} + * @private + * @default 0 * @since 3.0.0 */ - this.list = []; + this.b = 0; /** - * The index of the current element. + * The internal alpha color value. * - * This is used internally when iterating through the list with the {@link #first}, {@link #last}, {@link #get}, and {@link #previous} properties. + * @name Phaser.Display.Color#a + * @type {number} + * @private + * @default 255 + * @since 3.0.0 + */ + this.a = 255; + + /** + * The hue color value. A number between 0 and 1. + * This is the base color. * - * @name Phaser.Structs.List#position + * @name Phaser.Display.Color#_h + * @type {number} + * @default 0 + * @private + * @since 3.13.0 + */ + this._h = 0; + + /** + * The saturation color value. A number between 0 and 1. + * This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white. + * + * @name Phaser.Display.Color#_s + * @type {number} + * @default 0 + * @private + * @since 3.13.0 + */ + this._s = 0; + + /** + * The lightness color value. A number between 0 and 1. + * This controls how dark the color is. Where 1 is as bright as possible and 0 is black. + * + * @name Phaser.Display.Color#_v * @type {number} * @default 0 + * @private + * @since 3.13.0 + */ + this._v = 0; + + /** + * Is this color update locked? + * + * @name Phaser.Display.Color#_locked + * @type {boolean} + * @private + * @since 3.13.0 + */ + this._locked = false; + + /** + * An array containing the calculated color values for WebGL use. + * + * @name Phaser.Display.Color#gl + * @type {number[]} * @since 3.0.0 */ - this.position = 0; + this.gl = [ 0, 0, 0, 1 ]; /** - * A callback that is invoked every time a child is added to this list. + * Pre-calculated internal color value. * - * @name Phaser.Structs.List#addCallback - * @type {function} - * @since 3.4.0 + * @name Phaser.Display.Color#_color + * @type {number} + * @private + * @default 0 + * @since 3.0.0 */ - this.addCallback = NOOP; + this._color = 0; /** - * A callback that is invoked every time a child is removed from this list. + * Pre-calculated internal color32 value. * - * @name Phaser.Structs.List#removeCallback - * @type {function} - * @since 3.4.0 + * @name Phaser.Display.Color#_color32 + * @type {number} + * @private + * @default 0 + * @since 3.0.0 */ - this.removeCallback = NOOP; + this._color32 = 0; /** - * The property key to sort by. + * Pre-calculated internal color rgb string value. * - * @name Phaser.Structs.List#_sortKey + * @name Phaser.Display.Color#_rgba * @type {string} - * @since 3.4.0 + * @private + * @default '' + * @since 3.0.0 */ - this._sortKey = ''; + this._rgba = ''; + + this.setTo(red, green, blue, alpha); }, /** - * Adds the given item to the end of the list. Each item must be unique. + * Sets this color to be transparent. Sets all values to zero. * - * @method Phaser.Structs.List#add + * @method Phaser.Display.Color#transparent * @since 3.0.0 * - * @genericUse {T} - [child,$return] - * - * @param {*|Array.<*>} child - The item, or array of items, to add to the list. - * @param {boolean} [skipCallback=false] - Skip calling the List.addCallback if this child is added successfully. - * - * @return {*} The list's underlying array. + * @return {Phaser.Display.Color} This Color object. */ - add: function (child, skipCallback) + transparent: function () { - if (skipCallback) - { - return ArrayUtils.Add(this.list, child); - } - else - { - return ArrayUtils.Add(this.list, child, 0, this.addCallback, this); - } + this._locked = true; + + this.red = 0; + this.green = 0; + this.blue = 0; + this.alpha = 0; + + this._locked = false; + + return this.update(true); }, /** - * Adds an item to list, starting at a specified index. Each item must be unique within the list. + * Sets the color of this Color component. * - * @method Phaser.Structs.List#addAt + * @method Phaser.Display.Color#setTo * @since 3.0.0 * - * @genericUse {T} - [child,$return] - * - * @param {*} child - The item, or array of items, to add to the list. - * @param {number} [index=0] - The index in the list at which the element(s) will be inserted. - * @param {boolean} [skipCallback=false] - Skip calling the List.addCallback if this child is added successfully. + * @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. + * @param {boolean} [updateHSV=true] - Update the HSV values after setting the RGB values? * - * @return {*} The List's underlying array. + * @return {Phaser.Display.Color} This Color object. */ - addAt: function (child, index, skipCallback) + setTo: function (red, green, blue, alpha, updateHSV) { - if (skipCallback) - { - return ArrayUtils.AddAt(this.list, child, index); - } - else - { - return ArrayUtils.AddAt(this.list, child, index, 0, this.addCallback, this); - } + if (alpha === undefined) { alpha = 255; } + if (updateHSV === undefined) { updateHSV = true; } + + this._locked = true; + + this.red = red; + this.green = green; + this.blue = blue; + this.alpha = alpha; + + this._locked = false; + + return this.update(updateHSV); }, /** - * Retrieves the item at a given position inside the List. + * Sets the red, green, blue and alpha GL values of this Color component. * - * @method Phaser.Structs.List#getAt + * @method Phaser.Display.Color#setGLTo * @since 3.0.0 * - * @genericUse {T} - [$return] - * - * @param {number} index - The index of the item. + * @param {number} red - The red color value. A number between 0 and 1. + * @param {number} green - The green color value. A number between 0 and 1. + * @param {number} blue - The blue color value. A number between 0 and 1. + * @param {number} [alpha=1] - The alpha value. A number between 0 and 1. * - * @return {*} The retrieved item, or `undefined` if it's outside the List's bounds. + * @return {Phaser.Display.Color} This Color object. */ - getAt: function (index) + setGLTo: function (red, green, blue, alpha) { - return this.list[index]; + if (alpha === undefined) { alpha = 1; } + + this._locked = true; + + this.redGL = red; + this.greenGL = green; + this.blueGL = blue; + this.alphaGL = alpha; + + this._locked = false; + + return this.update(true); }, /** - * Locates an item within the List and returns its index. + * Sets the color based on the color object given. * - * @method Phaser.Structs.List#getIndex + * @method Phaser.Display.Color#setFromRGB * @since 3.0.0 * - * @genericUse {T} - [child] - * - * @param {*} child - The item to locate. + * @param {Phaser.Types.Display.InputColorObject} color - An object containing `r`, `g`, `b` and optionally `a` values in the range 0 to 255. * - * @return {number} The index of the item within the List, or -1 if it's not in the List. + * @return {Phaser.Display.Color} This Color object. */ - getIndex: function (child) + setFromRGB: function (color) { - // Return -1 if given child isn't a child of this display list - return this.list.indexOf(child); + this._locked = true; + + this.red = color.r; + this.green = color.g; + this.blue = color.b; + + if (color.hasOwnProperty('a')) + { + this.alpha = color.a; + } + + this._locked = false; + + return this.update(true); }, /** - * Sort the contents of this List so the items are in order based on the given property. - * For example, `sort('alpha')` would sort the List contents based on the value of their `alpha` property. + * Sets the color based on the hue, saturation and lightness values given. * - * @method Phaser.Structs.List#sort - * @since 3.0.0 + * @method Phaser.Display.Color#setFromHSV + * @since 3.13.0 * - * @genericUse {T[]} - [children,$return] + * @param {number} h - The hue, in the range 0 - 1. This is the base color. + * @param {number} s - The saturation, in the range 0 - 1. This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white. + * @param {number} v - The value, in the range 0 - 1. This controls how dark the color is. Where 1 is as bright as possible and 0 is black. * - * @param {string} property - The property to lexically sort by. - * @param {function} [handler] - Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean. + * @return {Phaser.Display.Color} This Color object. + */ + setFromHSV: function (h, s, v) + { + return HSVToRGB(h, s, v, this); + }, + + /** + * Updates the internal cache values. * - * @return {Phaser.Structs.List} This List object. + * @method Phaser.Display.Color#update + * @private + * @since 3.0.0 + * + * @return {Phaser.Display.Color} This Color object. */ - sort: function (property, handler) + update: function (updateHSV) { - if (!property) + if (updateHSV === undefined) { updateHSV = false; } + + if (this._locked) { return this; } - if (handler === undefined) + var r = this.r; + var g = this.g; + var b = this.b; + var a = this.a; + + this._color = GetColor(r, g, b); + this._color32 = GetColor32(r, g, b, a); + this._rgba = 'rgba(' + r + ',' + g + ',' + b + ',' + (a / 255) + ')'; + + if (updateHSV) { - handler = function (childA, childB) - { - return childA[property] - childB[property]; - }; + RGBToHSV(r, g, b, this); } - StableSort(this.list, handler); - return this; }, /** - * Searches for the first instance of a child with its `name` - * property matching the given argument. Should more than one child have - * the same name only the first is returned. - * - * @method Phaser.Structs.List#getByName - * @since 3.0.0 - * - * @genericUse {T | null} - [$return] + * Updates the internal hsv cache values. * - * @param {string} name - The name to search for. + * @method Phaser.Display.Color#updateHSV + * @private + * @since 3.13.0 * - * @return {?*} The first child with a matching name, or null if none were found. + * @return {Phaser.Display.Color} This Color object. */ - getByName: function (name) + updateHSV: function () { - return ArrayUtils.GetFirst(this.list, 'name', name); + var r = this.r; + var g = this.g; + var b = this.b; + + RGBToHSV(r, g, b, this); + + return this; }, /** - * Returns a random child from the group. + * Returns a new Color component using the values from this one. * - * @method Phaser.Structs.List#getRandom + * @method Phaser.Display.Color#clone * @since 3.0.0 * - * @genericUse {T | null} - [$return] - * - * @param {number} [startIndex=0] - Offset from the front of the group (lowest child). - * @param {number} [length=(to top)] - Restriction on the number of values you want to randomly select from. - * - * @return {?*} A random child of this Group. + * @return {Phaser.Display.Color} A new Color object. */ - getRandom: function (startIndex, length) + clone: function () { - return ArrayUtils.GetRandom(this.list, startIndex, length); + return new Color(this.r, this.g, this.b, this.a); }, /** - * Returns the first element in a given part of the List which matches a specific criterion. - * - * @method Phaser.Structs.List#getFirst - * @since 3.0.0 - * - * @genericUse {T | null} - [$return] + * Sets this Color object to be grayscaled based on the shade value given. * - * @param {string} property - The name of the property to test or a falsey value to have no criterion. - * @param {*} value - The value to test the `property` against, or `undefined` to allow any value and only check for existence. - * @param {number} [startIndex=0] - The position in the List to start the search at. - * @param {number} [endIndex] - The position in the List to optionally stop the search at. It won't be checked. + * @method Phaser.Display.Color#gray + * @since 3.13.0 + * + * @param {number} shade - A value between 0 and 255. * - * @return {?*} The first item which matches the given criterion, or `null` if no such item exists. + * @return {Phaser.Display.Color} This Color object. */ - getFirst: function (property, value, startIndex, endIndex) + gray: function (shade) { - return ArrayUtils.GetFirst(this.list, property, value, startIndex, endIndex); + return this.setTo(shade, shade, shade); }, /** - * Returns all children in this List. - * - * You can optionally specify a matching criteria using the `property` and `value` arguments. - * - * For example: `getAll('parent')` would return only children that have a property called `parent`. - * - * You can also specify a value to compare the property to: - * - * `getAll('visible', true)` would return only children that have their visible property set to `true`. - * - * Optionally you can specify a start and end index. For example if this List had 100 children, - * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only - * the first 50 children in the List. - * - * @method Phaser.Structs.List#getAll - * @since 3.0.0 - * - * @genericUse {T} - [value] - * @genericUse {T[]} - [$return] + * Sets this Color object to be a random color between the `min` and `max` values given. * - * @param {string} [property] - An optional property to test against the value argument. - * @param {*} [value] - If property is set then Child.property must strictly equal this value to be included in the results. - * @param {number} [startIndex] - The first child index to start the search from. - * @param {number} [endIndex] - The last child index to search up until. + * @method Phaser.Display.Color#random + * @since 3.13.0 + * + * @param {number} [min=0] - The minimum random color value. Between 0 and 255. + * @param {number} [max=255] - The maximum random color value. Between 0 and 255. * - * @return {Array.<*>} All items of the List which match the given criterion, if any. + * @return {Phaser.Display.Color} This Color object. */ - getAll: function (property, value, startIndex, endIndex) + random: function (min, max) { - return ArrayUtils.GetAll(this.list, property, value, startIndex, endIndex); + if (min === undefined) { min = 0; } + if (max === undefined) { max = 255; } + + var r = Math.floor(min + Math.random() * (max - min)); + var g = Math.floor(min + Math.random() * (max - min)); + var b = Math.floor(min + Math.random() * (max - min)); + + return this.setTo(r, g, b); }, /** - * Returns the total number of items in the List which have a property matching the given value. - * - * @method Phaser.Structs.List#count - * @since 3.0.0 - * - * @genericUse {T} - [value] + * Sets this Color object to be a random grayscale color between the `min` and `max` values given. * - * @param {string} property - The property to test on each item. - * @param {*} value - The value to test the property against. + * @method Phaser.Display.Color#randomGray + * @since 3.13.0 + * + * @param {number} [min=0] - The minimum random color value. Between 0 and 255. + * @param {number} [max=255] - The maximum random color value. Between 0 and 255. * - * @return {number} The total number of matching elements. + * @return {Phaser.Display.Color} This Color object. */ - count: function (property, value) + randomGray: function (min, max) { - return ArrayUtils.CountAllMatching(this.list, property, value); + if (min === undefined) { min = 0; } + if (max === undefined) { max = 255; } + + var s = Math.floor(min + Math.random() * (max - min)); + + return this.setTo(s, s, s); }, /** - * Swaps the positions of two items in the list. - * - * @method Phaser.Structs.List#swap - * @since 3.0.0 + * Increase the saturation of this Color by the percentage amount given. + * The saturation is the amount of the base color in the hue. * - * @genericUse {T} - [child1,child2] + * @method Phaser.Display.Color#saturate + * @since 3.13.0 + * + * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. * - * @param {*} child1 - The first item to swap. - * @param {*} child2 - The second item to swap. + * @return {Phaser.Display.Color} This Color object. */ - swap: function (child1, child2) + saturate: function (amount) { - ArrayUtils.Swap(this.list, child1, child2); + this.s += amount / 100; + + return this; }, /** - * Moves an item in the List to a new position. + * Decrease the saturation of this Color by the percentage amount given. + * The saturation is the amount of the base color in the hue. * - * @method Phaser.Structs.List#moveTo - * @since 3.0.0 + * @method Phaser.Display.Color#desaturate + * @since 3.13.0 + * + * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. * - * @genericUse {T} - [child,$return] + * @return {Phaser.Display.Color} This Color object. + */ + desaturate: function (amount) + { + this.s -= amount / 100; + + return this; + }, + + /** + * Increase the lightness of this Color by the percentage amount given. * - * @param {*} child - The item to move. - * @param {number} index - Moves an item in the List to a new position. + * @method Phaser.Display.Color#lighten + * @since 3.13.0 + * + * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. * - * @return {*} The item that was moved. + * @return {Phaser.Display.Color} This Color object. */ - moveTo: function (child, index) + lighten: function (amount) { - return ArrayUtils.MoveTo(this.list, child, index); + this.v += amount / 100; + + return this; }, /** - * Moves the given array element above another one in the array. - * - * @method Phaser.Structs.List#moveAbove - * @since 3.55.0 + * Decrease the lightness of this Color by the percentage amount given. * - * @genericUse {T} - [child1,child2] + * @method Phaser.Display.Color#darken + * @since 3.13.0 + * + * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. * - * @param {*} child1 - The element to move above base element. - * @param {*} child2 - The base element. + * @return {Phaser.Display.Color} This Color object. */ - moveAbove: function (child1, child2) + darken: function (amount) { - return ArrayUtils.MoveAbove(this.list, child1, child2); + this.v -= amount / 100; + + return this; }, /** - * Moves the given array element below another one in the array. - * - * @method Phaser.Structs.List#moveBelow - * @since 3.55.0 + * Brighten this Color by the percentage amount given. * - * @genericUse {T} - [child1,child2] + * @method Phaser.Display.Color#brighten + * @since 3.13.0 + * + * @param {number} amount - The percentage amount to change this color by. A value between 0 and 100. * - * @param {*} child1 - The element to move below base element. - * @param {*} child2 - The base element. + * @return {Phaser.Display.Color} This Color object. */ - moveBelow: function (child1, child2) + brighten: function (amount) { - return ArrayUtils.MoveBelow(this.list, child1, child2); + var r = this.r; + var g = this.g; + var b = this.b; + + r = Math.max(0, Math.min(255, r - Math.round(255 * - (amount / 100)))); + g = Math.max(0, Math.min(255, g - Math.round(255 * - (amount / 100)))); + b = Math.max(0, Math.min(255, b - Math.round(255 * - (amount / 100)))); + + return this.setTo(r, g, b); }, /** - * Removes one or many items from the List. + * The color of this Color component, not including the alpha channel. * - * @method Phaser.Structs.List#remove + * @name Phaser.Display.Color#color + * @type {number} + * @readonly * @since 3.0.0 - * - * @genericUse {T} - [child,$return] - * - * @param {*} child - The item, or array of items, to remove. - * @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback. - * - * @return {*} The item, or array of items, which were successfully removed from the List. */ - remove: function (child, skipCallback) - { - if (skipCallback) - { - return ArrayUtils.Remove(this.list, child); - } - else + color: { + + get: function () { - return ArrayUtils.Remove(this.list, child, this.removeCallback, this); + return this._color; } + }, /** - * Removes the item at the given position in the List. + * The color of this Color component, including the alpha channel. * - * @method Phaser.Structs.List#removeAt + * @name Phaser.Display.Color#color32 + * @type {number} + * @readonly * @since 3.0.0 - * - * @genericUse {T} - [$return] - * - * @param {number} index - The position to remove the item from. - * @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback. - * - * @return {*} The item that was removed. */ - removeAt: function (index, skipCallback) - { - if (skipCallback) - { - return ArrayUtils.RemoveAt(this.list, index); - } - else + color32: { + + get: function () { - return ArrayUtils.RemoveAt(this.list, index, this.removeCallback, this); + return this._color32; } + }, /** - * Removes the items within the given range in the List. + * The color of this Color component as a string which can be used in CSS color values. * - * @method Phaser.Structs.List#removeBetween + * @name Phaser.Display.Color#rgba + * @type {string} + * @readonly * @since 3.0.0 - * - * @genericUse {T[]} - [$return] - * - * @param {number} [startIndex=0] - The index to start removing from. - * @param {number} [endIndex] - The position to stop removing at. The item at this position won't be removed. - * @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback. - * - * @return {Array.<*>} An array of the items which were removed. */ - removeBetween: function (startIndex, endIndex, skipCallback) - { - if (skipCallback) - { - return ArrayUtils.RemoveBetween(this.list, startIndex, endIndex); - } - else + rgba: { + + get: function () { - return ArrayUtils.RemoveBetween(this.list, startIndex, endIndex, this.removeCallback, this); + return this._rgba; } + }, /** - * Removes all the items. + * The red color value, normalized to the range 0 to 1. * - * @method Phaser.Structs.List#removeAll + * @name Phaser.Display.Color#redGL + * @type {number} * @since 3.0.0 - * - * @genericUse {Phaser.Structs.List.} - [$return] - * - * @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback. - * - * @return {Phaser.Structs.List} This List object. */ - removeAll: function (skipCallback) - { - var i = this.list.length; + redGL: { - while (i--) + get: function () { - this.remove(this.list[i], skipCallback); + return this.gl[0]; + }, + + set: function (value) + { + this.gl[0] = Math.min(Math.abs(value), 1); + + this.r = Math.floor(this.gl[0] * 255); + + this.update(true); } - return this; }, /** - * Brings the given child to the top of this List. + * The green color value, normalized to the range 0 to 1. * - * @method Phaser.Structs.List#bringToTop + * @name Phaser.Display.Color#greenGL + * @type {number} * @since 3.0.0 - * - * @genericUse {T} - [child,$return] - * - * @param {*} child - The item to bring to the top of the List. - * - * @return {*} The item which was moved. */ - bringToTop: function (child) - { - return ArrayUtils.BringToTop(this.list, child); + greenGL: { + + get: function () + { + return this.gl[1]; + }, + + set: function (value) + { + this.gl[1] = Math.min(Math.abs(value), 1); + + this.g = Math.floor(this.gl[1] * 255); + + this.update(true); + } + }, /** - * Sends the given child to the bottom of this List. + * The blue color value, normalized to the range 0 to 1. * - * @method Phaser.Structs.List#sendToBack + * @name Phaser.Display.Color#blueGL + * @type {number} * @since 3.0.0 - * - * @genericUse {T} - [child,$return] - * - * @param {*} child - The item to send to the back of the list. - * - * @return {*} The item which was moved. - */ - sendToBack: function (child) - { - return ArrayUtils.SendToBack(this.list, child); - }, - - /** - * Moves the given child up one place in this group unless it's already at the top. - * - * @method Phaser.Structs.List#moveUp - * @since 3.0.0 - * - * @genericUse {T} - [child,$return] - * - * @param {*} child - The item to move up. - * - * @return {*} The item which was moved. */ - moveUp: function (child) - { - ArrayUtils.MoveUp(this.list, child); + blueGL: { - return child; - }, + get: function () + { + return this.gl[2]; + }, - /** - * Moves the given child down one place in this group unless it's already at the bottom. - * - * @method Phaser.Structs.List#moveDown - * @since 3.0.0 - * - * @genericUse {T} - [child,$return] - * - * @param {*} child - The item to move down. - * - * @return {*} The item which was moved. - */ - moveDown: function (child) - { - ArrayUtils.MoveDown(this.list, child); + set: function (value) + { + this.gl[2] = Math.min(Math.abs(value), 1); - return child; - }, + this.b = Math.floor(this.gl[2] * 255); - /** - * Reverses the order of all children in this List. - * - * @method Phaser.Structs.List#reverse - * @since 3.0.0 - * - * @genericUse {Phaser.Structs.List.} - [$return] - * - * @return {Phaser.Structs.List} This List object. - */ - reverse: function () - { - this.list.reverse(); + this.update(true); + } - return this; }, /** - * Shuffles the items in the list. + * The alpha color value, normalized to the range 0 to 1. * - * @method Phaser.Structs.List#shuffle + * @name Phaser.Display.Color#alphaGL + * @type {number} * @since 3.0.0 - * - * @genericUse {Phaser.Structs.List.} - [$return] - * - * @return {Phaser.Structs.List} This List object. */ - shuffle: function () - { - ArrayUtils.Shuffle(this.list); + alphaGL: { - return this; - }, + get: function () + { + return this.gl[3]; + }, - /** - * Replaces a child of this List with the given newChild. The newChild cannot be a member of this List. - * - * @method Phaser.Structs.List#replace - * @since 3.0.0 - * - * @genericUse {T} - [oldChild,newChild,$return] - * - * @param {*} oldChild - The child in this List that will be replaced. - * @param {*} newChild - The child to be inserted into this List. - * - * @return {*} Returns the oldChild that was replaced within this group. - */ - replace: function (oldChild, newChild) - { - return ArrayUtils.Replace(this.list, oldChild, newChild); - }, + set: function (value) + { + this.gl[3] = Math.min(Math.abs(value), 1); - /** - * Checks if an item exists within the List. - * - * @method Phaser.Structs.List#exists - * @since 3.0.0 - * - * @genericUse {T} - [child] - * - * @param {*} child - The item to check for the existence of. - * - * @return {boolean} `true` if the item is found in the list, otherwise `false`. - */ - exists: function (child) - { - return (this.list.indexOf(child) > -1); - }, + this.a = Math.floor(this.gl[3] * 255); - /** - * Sets the property `key` to the given value on all members of this List. - * - * @method Phaser.Structs.List#setAll - * @since 3.0.0 - * - * @genericUse {T} - [value] - * - * @param {string} property - The name of the property to set. - * @param {*} value - The value to set the property to. - * @param {number} [startIndex] - The first child index to start the search from. - * @param {number} [endIndex] - The last child index to search up until. - */ - setAll: function (property, value, startIndex, endIndex) - { - ArrayUtils.SetAll(this.list, property, value, startIndex, endIndex); + this.update(); + } - return this; }, /** - * Passes all children to the given callback. + * The red color value, normalized to the range 0 to 255. * - * @method Phaser.Structs.List#each + * @name Phaser.Display.Color#red + * @type {number} * @since 3.0.0 - * - * @genericUse {EachListCallback.} - [callback] - * - * @param {EachListCallback} callback - The function to call. - * @param {*} [context] - Value to use as `this` when executing callback. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. */ - each: function (callback, context) - { - var args = [ null ]; + red: { - for (var i = 2; i < arguments.length; i++) + get: function () { - args.push(arguments[i]); - } + return this.r; + }, - for (i = 0; i < this.list.length; i++) + set: function (value) { - args[0] = this.list[i]; + value = Math.floor(Math.abs(value)); - callback.apply(context, args); + this.r = Math.min(value, 255); + + this.gl[0] = value / 255; + + this.update(true); } + }, /** - * Clears the List and recreates its internal array. + * The green color value, normalized to the range 0 to 255. * - * @method Phaser.Structs.List#shutdown + * @name Phaser.Display.Color#green + * @type {number} * @since 3.0.0 */ - shutdown: function () - { - this.removeAll(); + green: { - this.list = []; - }, + get: function () + { + return this.g; + }, - /** - * Destroys this List. - * - * @method Phaser.Structs.List#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.removeAll(); + set: function (value) + { + value = Math.floor(Math.abs(value)); + + this.g = Math.min(value, 255); + + this.gl[1] = value / 255; + + this.update(true); + } - this.parent = null; - this.addCallback = null; - this.removeCallback = null; }, /** - * The number of items inside the List. + * The blue color value, normalized to the range 0 to 255. * - * @name Phaser.Structs.List#length + * @name Phaser.Display.Color#blue * @type {number} - * @readonly * @since 3.0.0 */ - length: { + blue: { get: function () { - return this.list.length; + return this.b; + }, + + set: function (value) + { + value = Math.floor(Math.abs(value)); + + this.b = Math.min(value, 255); + + this.gl[2] = value / 255; + + this.update(true); } }, /** - * The first item in the List or `null` for an empty List. + * The alpha color value, normalized to the range 0 to 255. * - * @name Phaser.Structs.List#first - * @genericUse {T} - [$type] - * @type {*} - * @readonly + * @name Phaser.Display.Color#alpha + * @type {number} * @since 3.0.0 */ - first: { + alpha: { get: function () { - this.position = 0; + return this.a; + }, - if (this.list.length > 0) - { - return this.list[0]; - } - else - { - return null; - } + set: function (value) + { + value = Math.floor(Math.abs(value)); + + this.a = Math.min(value, 255); + + this.gl[3] = value / 255; + + this.update(); } }, /** - * The last item in the List, or `null` for an empty List. + * The hue color value. A number between 0 and 1. + * This is the base color. * - * @name Phaser.Structs.List#last - * @genericUse {T} - [$type] - * @type {*} - * @readonly - * @since 3.0.0 + * @name Phaser.Display.Color#h + * @type {number} + * @since 3.13.0 */ - last: { + h: { get: function () { - if (this.list.length > 0) - { - this.position = this.list.length - 1; + return this._h; + }, - return this.list[this.position]; - } - else - { - return null; - } + set: function (value) + { + this._h = value; + + HSVToRGB(value, this._s, this._v, this); } }, /** - * The next item in the List, or `null` if the entire List has been traversed. - * - * This property can be read successively after reading {@link #first} or manually setting the {@link #position} to iterate the List. + * The saturation color value. A number between 0 and 1. + * This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white. * - * @name Phaser.Structs.List#next - * @genericUse {T} - [$type] - * @type {*} - * @readonly - * @since 3.0.0 + * @name Phaser.Display.Color#s + * @type {number} + * @since 3.13.0 */ - next: { + s: { get: function () { - if (this.position < this.list.length) - { - this.position++; + return this._s; + }, - return this.list[this.position]; - } - else - { - return null; - } + set: function (value) + { + this._s = value; + + HSVToRGB(this._h, value, this._v, this); } }, /** - * The previous item in the List, or `null` if the entire List has been traversed. - * - * This property can be read successively after reading {@link #last} or manually setting the {@link #position} to iterate the List backwards. + * The lightness color value. A number between 0 and 1. + * This controls how dark the color is. Where 1 is as bright as possible and 0 is black. * - * @name Phaser.Structs.List#previous - * @genericUse {T} - [$type] - * @type {*} - * @readonly - * @since 3.0.0 + * @name Phaser.Display.Color#v + * @type {number} + * @since 3.13.0 */ - previous: { + v: { get: function () { - if (this.position > 0) - { - this.position--; + return this._v; + }, - return this.list[this.position]; - } - else - { - return null; - } + set: function (value) + { + this._v = value; + + HSVToRGB(this._h, this._s, value, this); } } }); -module.exports = List; +module.exports = Color; /***/ }), -/* 111 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 30245: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Contains = __webpack_require__(112); -var GetPoint = __webpack_require__(445); -var GetPoints = __webpack_require__(446); -var GEOM_CONST = __webpack_require__(56); -var Random = __webpack_require__(180); +var GetColor = __webpack_require__(22946); /** - * @classdesc - * An Ellipse object. + * Return an array of Colors in a Color Spectrum. * - * 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 an Ellipse you should look at the capabilities of the Graphics class. + * The spectrum colors flow in the order: red, yellow, green, blue. * - * @class Ellipse - * @memberof Phaser.Geom - * @constructor - * @since 3.0.0 + * By default this function will return an array with 1024 elements in. * - * @param {number} [x=0] - The x position of the center of the ellipse. - * @param {number} [y=0] - The y position of the center of the ellipse. - * @param {number} [width=0] - The width of the ellipse. - * @param {number} [height=0] - The height of the ellipse. + * However, you can reduce this to a smaller quantity if needed, by specitying the `limit` parameter. + * + * @function Phaser.Display.Color.ColorSpectrum + * @since 3.50.0 + * + * @param {number} [limit=1024] - How many colors should be returned? The maximum is 1024 but you can set a smaller quantity if required. + * + * @return {Phaser.Types.Display.ColorObject[]} An array containing `limit` parameter number of elements, where each contains a Color Object. */ -var Ellipse = new Class({ +var ColorSpectrum = function (limit) +{ + if (limit === undefined) { limit = 1024; } - initialize: + var colors = []; - function Ellipse (x, y, width, height) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 0; } - if (height === undefined) { height = 0; } + var range = 255; - /** - * The geometry constant type of this object: `GEOM_CONST.ELLIPSE`. - * Used for fast type comparisons. - * - * @name Phaser.Geom.Ellipse#type - * @type {number} - * @readonly - * @since 3.19.0 - */ - this.type = GEOM_CONST.ELLIPSE; + var i; + var r = 255; + var g = 0; + var b = 0; - /** - * The x position of the center of the ellipse. - * - * @name Phaser.Geom.Ellipse#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.x = x; + // Red to Yellow + for (i = 0; i <= range; i++) + { + colors.push({ r: r, g: i, b: b, color: GetColor(r, i, b) }); + } - /** - * The y position of the center of the ellipse. - * - * @name Phaser.Geom.Ellipse#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.y = y; + g = 255; - /** - * The width of the ellipse. - * - * @name Phaser.Geom.Ellipse#width - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.width = width; + // Yellow to Green + for (i = range; i >= 0; i--) + { + colors.push({ r: i, g: g, b: b, color: GetColor(i, g, b) }); + } - /** - * The height of the ellipse. - * - * @name Phaser.Geom.Ellipse#height - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.height = height; - }, + r = 0; - /** - * Check to see if the Ellipse contains the given x / y coordinates. - * - * @method Phaser.Geom.Ellipse#contains - * @since 3.0.0 - * - * @param {number} x - The x coordinate to check within the ellipse. - * @param {number} y - The y coordinate to check within the ellipse. - * - * @return {boolean} True if the coordinates are within the ellipse, otherwise false. - */ - contains: function (x, y) + // Green to Blue + for (i = 0; i <= range; i++, g--) { - return Contains(this, x, y); - }, + colors.push({ r: r, g: g, b: i, color: GetColor(r, g, i) }); + } - /** - * 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. - * - * @method Phaser.Geom.Ellipse#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 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. - */ - getPoint: function (position, point) - { - return GetPoint(this, position, point); - }, + g = 0; + b = 255; - /** - * 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. - * - * @method Phaser.Geom.Ellipse#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 ellipse 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 ellipse. - */ - getPoints: function (quantity, stepRate, output) + // Blue to Red + for (i = 0; i <= range; i++, b--, r++) { - return GetPoints(this, quantity, stepRate, output); - }, + colors.push({ r: r, g: g, b: b, color: GetColor(r, g, b) }); + } - /** - * Returns a uniformly distributed random point from anywhere within the given Ellipse. - * - * @method Phaser.Geom.Ellipse#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) + if (limit === 1024) { - return Random(this, point); - }, - - /** - * Sets the x, y, width and height of this ellipse. - * - * @method Phaser.Geom.Ellipse#setTo - * @since 3.0.0 - * - * @param {number} x - The x position of the center of the ellipse. - * @param {number} y - The y position of the center of the ellipse. - * @param {number} width - The width of the ellipse. - * @param {number} height - The height of the ellipse. - * - * @return {this} This Ellipse object. - */ - setTo: function (x, y, width, height) + return colors; + } + else { - this.x = x; - this.y = y; - this.width = width; - this.height = height; + var out = []; - return this; - }, + var t = 0; + var inc = 1024 / limit; - /** - * Sets this Ellipse to be empty with a width and height of zero. - * Does not change its position. - * - * @method Phaser.Geom.Ellipse#setEmpty - * @since 3.0.0 - * - * @return {this} This Ellipse object. - */ - setEmpty: function () - { - this.width = 0; - this.height = 0; + for (i = 0; i < limit; i++) + { + out.push(colors[Math.floor(t)]); - return this; - }, + t += inc; + } - /** - * Sets the position of this Ellipse. - * - * @method Phaser.Geom.Ellipse#setPosition - * @since 3.0.0 - * - * @param {number} x - The x position of the center of the ellipse. - * @param {number} y - The y position of the center of the ellipse. - * - * @return {this} This Ellipse object. - */ - setPosition: function (x, y) - { - if (y === undefined) { y = x; } + return out; + } +}; - this.x = x; - this.y = y; +module.exports = ColorSpectrum; - return this; - }, - /** - * Sets the size of this Ellipse. - * Does not change its position. - * - * @method Phaser.Geom.Ellipse#setSize - * @since 3.0.0 - * - * @param {number} width - The width of the ellipse. - * @param {number} [height=width] - The height of the ellipse. - * - * @return {this} This Ellipse object. - */ - setSize: function (width, height) - { - if (height === undefined) { height = width; } +/***/ }), - this.width = width; - this.height = height; +/***/ 86672: +/***/ ((module) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Checks to see if the Ellipse is empty: has a width or height equal to zero. - * - * @method Phaser.Geom.Ellipse#isEmpty - * @since 3.0.0 - * - * @return {boolean} True if the Ellipse is empty, otherwise false. - */ - isEmpty: function () - { - return (this.width <= 0 || this.height <= 0); - }, +/** + * Converts the given color value into an Object containing r,g,b and a properties. + * + * @function Phaser.Display.Color.ColorToRGBA + * @since 3.0.0 + * + * @param {number} color - A color value, optionally including the alpha value. + * + * @return {Phaser.Types.Display.ColorObject} An object containing the parsed color values. + */ +var ColorToRGBA = function (color) +{ + var output = { + r: color >> 16 & 0xFF, + g: color >> 8 & 0xFF, + b: color & 0xFF, + a: 255 + }; - /** - * Returns the minor radius of the ellipse. Also known as the Semi Minor Axis. - * - * @method Phaser.Geom.Ellipse#getMinorRadius - * @since 3.0.0 - * - * @return {number} The minor radius. - */ - getMinorRadius: function () + if (color > 16777215) { - return Math.min(this.width, this.height) / 2; - }, + output.a = color >>> 24; + } - /** - * Returns the major radius of the ellipse. Also known as the Semi Major Axis. - * - * @method Phaser.Geom.Ellipse#getMajorRadius - * @since 3.0.0 - * - * @return {number} The major radius. - */ - getMajorRadius: function () - { - return Math.max(this.width, this.height) / 2; - }, + return output; +}; - /** - * The left position of the Ellipse. - * - * @name Phaser.Geom.Ellipse#left - * @type {number} - * @since 3.0.0 - */ - left: { +module.exports = ColorToRGBA; - get: function () - { - return this.x - (this.width / 2); - }, - set: function (value) - { - this.x = value + (this.width / 2); - } +/***/ }), - }, +/***/ 25409: +/***/ ((module) => { - /** - * The right position of the Ellipse. - * - * @name Phaser.Geom.Ellipse#right - * @type {number} - * @since 3.0.0 - */ - right: { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - get: function () - { - return this.x + (this.width / 2); - }, +/** + * 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); - set: function (value) - { - this.x = value - (this.width / 2); - } + return (hex.length === 1) ? '0' + hex : hex; +}; - }, +module.exports = ComponentToHex; - /** - * The top position of the Ellipse. - * - * @name Phaser.Geom.Ellipse#top - * @type {number} - * @since 3.0.0 - */ - top: { - get: function () - { - return this.y - (this.height / 2); - }, +/***/ }), - set: function (value) - { - this.y = value + (this.height / 2); - } +/***/ 22946: +/***/ ((module) => { - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The bottom position of the Ellipse. - * - * @name Phaser.Geom.Ellipse#bottom - * @type {number} - * @since 3.0.0 - */ - bottom: { +/** + * Given 3 separate color values this will return an integer representation of it. + * + * @function Phaser.Display.Color.GetColor + * @since 3.0.0 + * + * @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. + * + * @return {number} The combined color value. + */ +var GetColor = function (red, green, blue) +{ + return red << 16 | green << 8 | blue; +}; - get: function () - { - return this.y + (this.height / 2); - }, +module.exports = GetColor; - set: function (value) - { - this.y = value - (this.height / 2); - } - } +/***/ }), -}); +/***/ 5657: +/***/ ((module) => { -module.exports = Ellipse; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Given an alpha and 3 color values this will return an integer representation of it. + * + * @function Phaser.Display.Color.GetColor32 + * @since 3.0.0 + * + * @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 - The alpha color value. A number between 0 and 255. + * + * @return {number} The combined color value. + */ +var GetColor32 = function (red, green, blue, alpha) +{ + return alpha << 24 | red << 16 | green << 8 | blue; +}; + +module.exports = GetColor32; /***/ }), -/* 112 */ -/***/ (function(module, exports) { + +/***/ 74777: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Color = __webpack_require__(27119); +var HueToComponent = __webpack_require__(59998); + /** - * Check to see if the Ellipse contains the given x / y coordinates. + * Converts HSL (hue, saturation and lightness) values to a Phaser Color object. * - * @function Phaser.Geom.Ellipse.Contains + * @function Phaser.Display.Color.HSLToColor * @since 3.0.0 * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to check. - * @param {number} x - The x coordinate to check within the ellipse. - * @param {number} y - The y coordinate to check within the ellipse. + * @param {number} h - The hue value in the range 0 to 1. + * @param {number} s - The saturation value in the range 0 to 1. + * @param {number} l - The lightness value in the range 0 to 1. * - * @return {boolean} True if the coordinates are within the ellipse, otherwise false. + * @return {Phaser.Display.Color} A Color object created from the results of the h, s and l values. */ -var Contains = function (ellipse, x, y) +var HSLToColor = function (h, s, l) { - if (ellipse.width <= 0 || ellipse.height <= 0) + // achromatic by default + var r = l; + var g = l; + var b = l; + + if (s !== 0) { - return false; - } + var q = (l < 0.5) ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; - // Normalize the coords to an ellipse with center 0,0 and a radius of 0.5 - var normx = ((x - ellipse.x) / ellipse.width); - var normy = ((y - ellipse.y) / ellipse.height); + r = HueToComponent(p, q, h + 1 / 3); + g = HueToComponent(p, q, h); + b = HueToComponent(p, q, h - 1 / 3); + } - normx *= normx; - normy *= normy; + var color = new Color(); - return (normx + normy < 0.25); + return color.setGLTo(r, g, b, 1); }; -module.exports = Contains; +module.exports = HSLToColor; /***/ }), -/* 113 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 89263: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Actions = __webpack_require__(275); -var Class = __webpack_require__(0); -var Events = __webpack_require__(75); -var EventEmitter = __webpack_require__(9); -var GetAll = __webpack_require__(207); -var GetFastValue = __webpack_require__(2); -var GetValue = __webpack_require__(6); -var IsPlainObject = __webpack_require__(7); -var Range = __webpack_require__(437); -var Set = __webpack_require__(149); -var Sprite = __webpack_require__(73); +var HSVToRGB = __webpack_require__(24650); /** - * @classdesc - * A Group is a way for you to create, manipulate, or recycle similar Game Objects. + * Generates an HSV color wheel which is an array of 360 Color objects, for each step of the wheel. * - * Group membership is non-exclusive. A Game Object can belong to several groups, one group, or none. - * - * Groups themselves aren't displayable, and can't be positioned, rotated, scaled, or hidden. - * - * @class Group - * @memberof Phaser.GameObjects - * @extends Phaser.Events.EventEmitter - * @constructor + * @function Phaser.Display.Color.HSVColorWheel * @since 3.0.0 - * @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. If `key` is set, Phaser.GameObjects.Group#createMultiple is also called with these settings. * - * @see Phaser.Physics.Arcade.Group - * @see Phaser.Physics.Arcade.StaticGroup + * @param {number} [s=1] - The saturation, in the range 0 - 1. + * @param {number} [v=1] - The value, in the range 0 - 1. + * + * @return {Phaser.Types.Display.ColorObject[]} An array containing 360 ColorObject elements, where each element contains a Color object corresponding to the color at that point in the HSV color wheel. */ -var Group = new Class({ - - Extends: EventEmitter, +var HSVColorWheel = function (s, v) +{ + if (s === undefined) { s = 1; } + if (v === undefined) { v = 1; } - initialize: + var colors = []; - function Group (scene, children, config) + for (var c = 0; c <= 359; c++) { - EventEmitter.call(this); + colors.push(HSVToRGB(c / 359, s, v)); + } - // They can pass in any of the following as the first argument: + return colors; +}; - // 1) A single child - // 2) An array of children - // 3) A config object - // 4) An array of config objects +module.exports = HSVColorWheel; - // Or they can pass in a child, or array of children AND a config object - if (config) - { - // config has been set, are the children an array? +/***/ }), - if (children && !Array.isArray(children)) - { - children = [ children ]; - } - } - else if (Array.isArray(children)) - { - // No config, so let's check the children argument +/***/ 24650: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (IsPlainObject(children[0])) - { - // It's an array of plain config objects - config = children; - children = null; - } - } - else if (IsPlainObject(children)) - { - // Children isn't an array. Is it a config object though? - config = children; - children = null; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * This scene this group belongs to. - * - * @name Phaser.GameObjects.Group#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; +var GetColor = __webpack_require__(22946); - /** - * Members of this group. - * - * @name Phaser.GameObjects.Group#children - * @type {Phaser.Structs.Set.} - * @since 3.0.0 - */ - this.children = new Set(); +/** + * RGB space conversion. + * + * @ignore + * + * @param {number} n - The value to convert. + * @param {number} h - The h value. + * @param {number} s - The s value. + * @param {number} v - The v value. + * + * @return {number} The converted value. + */ +function ConvertValue (n, h, s, v) +{ + var k = (n + h * 6) % 6; - /** - * A flag identifying this object as a group. - * - * @name Phaser.GameObjects.Group#isParent - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.isParent = true; + var min = Math.min(k, 4 - k, 1); - /** - * A textual representation of this Game Object. - * Used internally by Phaser but is available for your own custom classes to populate. - * - * @name Phaser.GameObjects.Group#type - * @type {string} - * @default 'Group' - * @since 3.21.0 - */ - this.type = 'Group'; + return Math.round(255 * (v - v * s * Math.max(0, min))); +} - /** - * The class to create new group members from. - * - * @name Phaser.GameObjects.Group#classType - * @type {Function} - * @since 3.0.0 - * @default Phaser.GameObjects.Sprite - */ - this.classType = GetFastValue(config, 'classType', Sprite); +/** + * Converts a HSV (hue, saturation and value) color set to RGB. + * + * Conversion formula from https://en.wikipedia.org/wiki/HSL_and_HSV + * + * Assumes HSV values are contained in the set [0, 1]. + * + * @function Phaser.Display.Color.HSVToRGB + * @since 3.0.0 + * + * @param {number} h - The hue, in the range 0 - 1. This is the base color. + * @param {number} s - The saturation, in the range 0 - 1. This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white. + * @param {number} v - The value, in the range 0 - 1. This controls how dark the color is. Where 1 is as bright as possible and 0 is black. + * @param {(Phaser.Types.Display.ColorObject|Phaser.Display.Color)} [out] - A Color object to store the results in. If not given a new ColorObject will be created. + * + * @return {(Phaser.Types.Display.ColorObject|Phaser.Display.Color)} An object with the red, green and blue values set in the r, g and b properties. + */ +var HSVToRGB = function (h, s, v, out) +{ + if (s === undefined) { s = 1; } + if (v === undefined) { v = 1; } - /** - * The name of this group. - * Empty by default and never populated by Phaser, this is left for developers to use. - * - * @name Phaser.GameObjects.Group#name - * @type {string} - * @default '' - * @since 3.18.0 - */ - this.name = GetFastValue(config, 'name', ''); + var r = ConvertValue(5, h, s, v); + var g = ConvertValue(3, h, s, v); + var b = ConvertValue(1, h, s, v); - /** - * Whether this group runs its {@link Phaser.GameObjects.Group#preUpdate} method (which may update any members). - * - * @name Phaser.GameObjects.Group#active - * @type {boolean} - * @since 3.0.0 - */ - this.active = GetFastValue(config, 'active', true); + if (!out) + { + return { r: r, g: g, b: b, color: GetColor(r, g, b) }; + } + else if (out.setTo) + { + return out.setTo(r, g, b, out.alpha, true); + } + else + { + out.r = r; + out.g = g; + out.b = b; + out.color = GetColor(r, g, b); - /** - * The maximum size of this group, if used as a pool. -1 is no limit. - * - * @name Phaser.GameObjects.Group#maxSize - * @type {number} - * @since 3.0.0 - * @default -1 - */ - this.maxSize = GetFastValue(config, 'maxSize', -1); + return out; + } +}; - /** - * A default texture key to use when creating new group members. - * - * This is used in {@link Phaser.GameObjects.Group#create} - * but not in {@link Phaser.GameObjects.Group#createMultiple}. - * - * @name Phaser.GameObjects.Group#defaultKey - * @type {string} - * @since 3.0.0 - */ - this.defaultKey = GetFastValue(config, 'defaultKey', null); +module.exports = HSVToRGB; - /** - * A default texture frame to use when creating new group members. - * - * @name Phaser.GameObjects.Group#defaultFrame - * @type {(string|number)} - * @since 3.0.0 - */ - this.defaultFrame = GetFastValue(config, 'defaultFrame', null); - /** - * Whether to call the update method of any members. - * - * @name Phaser.GameObjects.Group#runChildUpdate - * @type {boolean} - * @default false - * @since 3.0.0 - * @see Phaser.GameObjects.Group#preUpdate - */ - this.runChildUpdate = GetFastValue(config, 'runChildUpdate', false); +/***/ }), - /** - * A function to be called when adding or creating group members. - * - * @name Phaser.GameObjects.Group#createCallback - * @type {?Phaser.Types.GameObjects.Group.GroupCallback} - * @since 3.0.0 - */ - this.createCallback = GetFastValue(config, 'createCallback', null); +/***/ 91487: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A function to be called when removing group members. - * - * @name Phaser.GameObjects.Group#removeCallback - * @type {?Phaser.Types.GameObjects.Group.GroupCallback} - * @since 3.0.0 - */ - this.removeCallback = GetFastValue(config, 'removeCallback', null); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A function to be called when creating several group members at once. - * - * @name Phaser.GameObjects.Group#createMultipleCallback - * @type {?Phaser.Types.GameObjects.Group.GroupMultipleCreateCallback} - * @since 3.0.0 - */ - this.createMultipleCallback = GetFastValue(config, 'createMultipleCallback', null); +var Color = __webpack_require__(27119); - /** - * A function to be called when adding or creating group members. - * For internal use only by a Group, or any class that extends it. - * - * @name Phaser.GameObjects.Group#internalCreateCallback - * @type {?Phaser.Types.GameObjects.Group.GroupCallback} - * @private - * @since 3.22.0 - */ - this.internalCreateCallback = GetFastValue(config, 'internalCreateCallback', null); +/** + * Converts a hex string into a Phaser Color object. + * + * The hex string can supplied as `'#0033ff'` or the short-hand format of `'#03f'`; it can begin with an optional "#" or "0x", or be unprefixed. + * + * An alpha channel is _not_ supported. + * + * @function Phaser.Display.Color.HexStringToColor + * @since 3.0.0 + * + * @param {string} hex - The hex color value to convert, such as `#0033ff` or the short-hand format: `#03f`. + * + * @return {Phaser.Display.Color} A Color object populated by the values of the given string. + */ +var HexStringToColor = function (hex) +{ + var color = new Color(); - /** - * A function to be called when removing group members. - * For internal use only by a Group, or any class that extends it. - * - * @name Phaser.GameObjects.Group#internalRemoveCallback - * @type {?Phaser.Types.GameObjects.Group.GroupCallback} - * @private - * @since 3.22.0 - */ - this.internalRemoveCallback = GetFastValue(config, 'internalRemoveCallback', null); + // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") + hex = hex.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i, function (m, r, g, b) + { + return r + r + g + g + b + b; + }); - if (children) - { - this.addMultiple(children); - } + var result = (/^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i).exec(hex); - if (config) - { - this.createMultiple(config); - } + if (result) + { + var r = parseInt(result[1], 16); + var g = parseInt(result[2], 16); + var b = parseInt(result[3], 16); - this.on(Events.ADDED_TO_SCENE, this.addedToScene, this); - this.on(Events.REMOVED_FROM_SCENE, this.removedFromScene, this); - }, + color.setTo(r, g, b); + } - // Overrides Game Object method - addedToScene: function () + return color; +}; + +module.exports = HexStringToColor; + + +/***/ }), + +/***/ 59998: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 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) { - this.scene.sys.updateList.add(this); - }, + t += 1; + } - // Overrides Game Object method - removedFromScene: function () + if (t > 1) { - this.scene.sys.updateList.remove(this); - }, + t -= 1; + } - /** - * Creates a new Game Object and adds it to this group, unless the group {@link Phaser.GameObjects.Group#isFull is full}. - * - * Calls {@link Phaser.GameObjects.Group#createCallback}. - * - * @method Phaser.GameObjects.Group#create - * @since 3.0.0 - * - * @param {number} [x=0] - The horizontal position of the new Game Object in the world. - * @param {number} [y=0] - The vertical position of the new Game Object in the world. - * @param {string} [key=defaultKey] - The texture key of the new Game Object. - * @param {(string|number)} [frame=defaultFrame] - The texture frame of the new Game Object. - * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of the new Game Object. - * @param {boolean} [active=true] - The {@link Phaser.GameObjects.GameObject#active} state of the new Game Object. - * - * @return {any} The new Game Object (usually a Sprite, etc.). - */ - create: function (x, y, key, frame, visible, active) + if (t < 1 / 6) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (key === undefined) { key = this.defaultKey; } - if (frame === undefined) { frame = this.defaultFrame; } - if (visible === undefined) { visible = true; } - if (active === undefined) { active = true; } + return p + (q - p) * 6 * t; + } - // Pool? - if (this.isFull()) - { - return null; - } + if (t < 1 / 2) + { + return q; + } - var child = new this.classType(this.scene, x, y, key, frame); + if (t < 2 / 3) + { + return p + (q - p) * (2 / 3 - t) * 6; + } - child.addToDisplayList(this.scene.sys.displayList); - child.addToUpdateList(); + return p; +}; - child.visible = visible; - child.setActive(active); +module.exports = HueToComponent; - this.add(child); - return child; - }, +/***/ }), - /** - * Creates several Game Objects and adds them to this group. - * - * If the group becomes {@link Phaser.GameObjects.Group#isFull}, no further Game Objects are created. - * - * Calls {@link Phaser.GameObjects.Group#createMultipleCallback} and {@link Phaser.GameObjects.Group#createCallback}. - * - * @method Phaser.GameObjects.Group#createMultiple - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Group.GroupCreateConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig[]} config - Creation settings. This can be a single configuration object or an array of such objects, which will be applied in turn. - * - * @return {any[]} The newly created Game Objects. - */ - createMultiple: function (config) - { - if (this.isFull()) - { - return []; - } +/***/ 74853: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!Array.isArray(config)) - { - config = [ config ]; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var output = []; +var Color = __webpack_require__(27119); +var IntegerToRGB = __webpack_require__(15978); - if (config[0].key) - { - for (var i = 0; i < config.length; i++) - { - var entries = this.createFromConfig(config[i]); +/** + * Converts the given color value into an instance of a Color object. + * + * @function Phaser.Display.Color.IntegerToColor + * @since 3.0.0 + * + * @param {number} input - The color value to convert into a Color object. + * + * @return {Phaser.Display.Color} A Color object. + */ +var IntegerToColor = function (input) +{ + var rgb = IntegerToRGB(input); - output = output.concat(entries); - } - } + return new Color(rgb.r, rgb.g, rgb.b, rgb.a); +}; - return output; - }, +module.exports = IntegerToColor; - /** - * A helper for {@link Phaser.GameObjects.Group#createMultiple}. - * - * @method Phaser.GameObjects.Group#createFromConfig - * @since 3.0.0 - * - * @param {Phaser.Types.GameObjects.Group.GroupCreateConfig} options - Creation settings. - * - * @return {any[]} The newly created Game Objects. - */ - createFromConfig: function (options) - { - if (this.isFull()) - { - return []; - } - this.classType = GetFastValue(options, 'classType', this.classType); +/***/ }), - var key = GetFastValue(options, 'key', undefined); - var frame = GetFastValue(options, 'frame', null); - var visible = GetFastValue(options, 'visible', true); - var active = GetFastValue(options, 'active', true); +/***/ 15978: +/***/ ((module) => { - var entries = []; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Can't do anything without at least a key - if (key === undefined) - { - return entries; - } - else - { - if (!Array.isArray(key)) - { - key = [ key ]; - } +/** + * Return the component parts of a color as an Object with the properties alpha, red, green, blue. + * + * Alpha will only be set if it exists in the given color (0xAARRGGBB) + * + * @function Phaser.Display.Color.IntegerToRGB + * @since 3.0.0 + * + * @param {number} input - The color value to convert into a Color object. + * + * @return {Phaser.Types.Display.ColorObject} An object with the red, green and blue values set in the r, g and b properties. + */ +var IntegerToRGB = function (color) +{ + if (color > 16777215) + { + // The color value has an alpha component + return { + a: color >>> 24, + r: color >> 16 & 0xFF, + g: color >> 8 & 0xFF, + b: color & 0xFF + }; + } + else + { + return { + a: 255, + r: color >> 16 & 0xFF, + g: color >> 8 & 0xFF, + b: color & 0xFF + }; + } +}; - if (!Array.isArray(frame)) - { - frame = [ frame ]; - } - } +module.exports = IntegerToRGB; - // Build an array of key frame pairs to loop through - var repeat = GetFastValue(options, 'repeat', 0); - var randomKey = GetFastValue(options, 'randomKey', false); - var randomFrame = GetFastValue(options, 'randomFrame', false); - var yoyo = GetFastValue(options, 'yoyo', false); - var quantity = GetFastValue(options, 'quantity', false); - var frameQuantity = GetFastValue(options, 'frameQuantity', 1); - var max = GetFastValue(options, 'max', 0); +/***/ }), - // If a quantity value is set we use that to override the frameQuantity +/***/ 53756: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var range = Range(key, frame, { - max: max, - qty: (quantity) ? quantity : frameQuantity, - random: randomKey, - randomB: randomFrame, - repeat: repeat, - yoyo: yoyo - }); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (options.createCallback) - { - this.createCallback = options.createCallback; - } +var Linear = __webpack_require__(42798); - if (options.removeCallback) - { - this.removeCallback = options.removeCallback; - } +/** + * @namespace Phaser.Display.Color.Interpolate + * @memberof Phaser.Display.Color + * @since 3.0.0 + */ - for (var c = 0; c < range.length; c++) - { - var created = this.create(0, 0, range[c].a, range[c].b, visible, active); +/** + * Interpolates between the two given color ranges over the length supplied. + * + * @function Phaser.Display.Color.Interpolate.RGBWithRGB + * @memberof Phaser.Display.Color.Interpolate + * @static + * @since 3.0.0 + * + * @param {number} r1 - Red value. + * @param {number} g1 - Blue value. + * @param {number} b1 - Green value. + * @param {number} r2 - Red value. + * @param {number} g2 - Blue value. + * @param {number} b2 - Green value. + * @param {number} [length=100] - Distance to interpolate over. + * @param {number} [index=0] - Index to start from. + * + * @return {Phaser.Types.Display.ColorObject} An object containing the interpolated color values. + */ +var RGBWithRGB = function (r1, g1, b1, r2, g2, b2, length, index) +{ + if (length === undefined) { length = 100; } + if (index === undefined) { index = 0; } - if (!created) - { - break; - } + var t = index / length; - entries.push(created); - } + return { + r: Linear(r1, r2, t), + g: Linear(g1, g2, t), + b: Linear(b1, b2, t) + }; +}; - // Post-creation options (applied only to those items created in this call): +/** + * Interpolates between the two given color objects over the length supplied. + * + * @function Phaser.Display.Color.Interpolate.ColorWithColor + * @memberof Phaser.Display.Color.Interpolate + * @static + * @since 3.0.0 + * + * @param {Phaser.Display.Color} color1 - The first Color object. + * @param {Phaser.Display.Color} color2 - The second Color object. + * @param {number} [length=100] - Distance to interpolate over. + * @param {number} [index=0] - Index to start from. + * + * @return {Phaser.Types.Display.ColorObject} An object containing the interpolated color values. + */ +var ColorWithColor = function (color1, color2, length, index) +{ + if (length === undefined) { length = 100; } + if (index === undefined) { index = 0; } - var x = GetValue(options, 'setXY.x', 0); - var y = GetValue(options, 'setXY.y', 0); - var stepX = GetValue(options, 'setXY.stepX', 0); - var stepY = GetValue(options, 'setXY.stepY', 0); + return RGBWithRGB(color1.r, color1.g, color1.b, color2.r, color2.g, color2.b, length, index); +}; - Actions.SetXY(entries, x, y, stepX, stepY); +/** + * Interpolates between the Color object and color values over the length supplied. + * + * @function Phaser.Display.Color.Interpolate.ColorWithRGB + * @memberof Phaser.Display.Color.Interpolate + * @static + * @since 3.0.0 + * + * @param {Phaser.Display.Color} color1 - The first Color object. + * @param {number} r - Red value. + * @param {number} g - Blue value. + * @param {number} b - Green value. + * @param {number} [length=100] - Distance to interpolate over. + * @param {number} [index=0] - Index to start from. + * + * @return {Phaser.Types.Display.ColorObject} An object containing the interpolated color values. + */ +var ColorWithRGB = function (color, r, g, b, length, index) +{ + if (length === undefined) { length = 100; } + if (index === undefined) { index = 0; } - var rotation = GetValue(options, 'setRotation.value', 0); - var stepRotation = GetValue(options, 'setRotation.step', 0); + return RGBWithRGB(color.r, color.g, color.b, r, g, b, length, index); +}; - Actions.SetRotation(entries, rotation, stepRotation); +module.exports = { - var scaleX = GetValue(options, 'setScale.x', 1); - var scaleY = GetValue(options, 'setScale.y', scaleX); - var stepScaleX = GetValue(options, 'setScale.stepX', 0); - var stepScaleY = GetValue(options, 'setScale.stepY', 0); + RGBWithRGB: RGBWithRGB, + ColorWithRGB: ColorWithRGB, + ColorWithColor: ColorWithColor - Actions.SetScale(entries, scaleX, scaleY, stepScaleX, stepScaleY); +}; - var originX = GetValue(options, 'setOrigin.x', 0.5); - var originY = GetValue(options, 'setOrigin.y', originX); - var stepOriginX = GetValue(options, 'setOrigin.stepX', 0); - var stepOriginY = GetValue(options, 'setOrigin.stepY', 0); - Actions.SetOrigin(entries, originX, originY, stepOriginX, stepOriginY); +/***/ }), - var alpha = GetValue(options, 'setAlpha.value', 1); - var stepAlpha = GetValue(options, 'setAlpha.step', 0); +/***/ 73904: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - Actions.SetAlpha(entries, alpha, stepAlpha); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var depth = GetValue(options, 'setDepth.value', 0); - var stepDepth = GetValue(options, 'setDepth.step', 0); +var Color = __webpack_require__(27119); - Actions.SetDepth(entries, depth, stepDepth); +/** + * Converts an object containing `r`, `g`, `b` and `a` properties into a Color class instance. + * + * @function Phaser.Display.Color.ObjectToColor + * @since 3.0.0 + * + * @param {Phaser.Types.Display.InputColorObject} input - An object containing `r`, `g`, `b` and `a` properties in the range 0 to 255. + * + * @return {Phaser.Display.Color} A Color object. + */ +var ObjectToColor = function (input) +{ + return new Color(input.r, input.g, input.b, input.a); +}; - var scrollFactorX = GetValue(options, 'setScrollFactor.x', 1); - var scrollFactorY = GetValue(options, 'setScrollFactor.y', scrollFactorX); - var stepScrollFactorX = GetValue(options, 'setScrollFactor.stepX', 0); - var stepScrollFactorY = GetValue(options, 'setScrollFactor.stepY', 0); +module.exports = ObjectToColor; - Actions.SetScrollFactor(entries, scrollFactorX, scrollFactorY, stepScrollFactorX, stepScrollFactorY); - var hitArea = GetFastValue(options, 'hitArea', null); - var hitAreaCallback = GetFastValue(options, 'hitAreaCallback', null); +/***/ }), - if (hitArea) - { - Actions.SetHitArea(entries, hitArea, hitAreaCallback); - } +/***/ 26841: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var grid = GetFastValue(options, 'gridAlign', false); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (grid) - { - Actions.GridAlign(entries, grid); - } +var Color = __webpack_require__(27119); - if (this.createMultipleCallback) - { - this.createMultipleCallback.call(this, entries); - } +/** + * Converts a CSS 'web' string into a Phaser Color object. + * + * The web string can be in the format `'rgb(r,g,b)'` or `'rgba(r,g,b,a)'` where r/g/b are in the range [0..255] and a is in the range [0..1]. + * + * @function Phaser.Display.Color.RGBStringToColor + * @since 3.0.0 + * + * @param {string} rgb - The CSS format color string, using the `rgb` or `rgba` format. + * + * @return {Phaser.Display.Color} A Color object. + */ +var RGBStringToColor = function (rgb) +{ + var color = new Color(); - return entries; - }, + var result = (/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/).exec(rgb.toLowerCase()); - /** - * Updates any group members, if {@link Phaser.GameObjects.Group#runChildUpdate} is enabled. - * - * @method Phaser.GameObjects.Group#preUpdate - * @since 3.0.0 - * - * @param {number} time - The current timestamp. - * @param {number} delta - The delta time elapsed since the last frame. - */ - preUpdate: function (time, delta) + if (result) { - if (!this.runChildUpdate || this.children.size === 0) - { - return; - } + var r = parseInt(result[1], 10); + var g = parseInt(result[2], 10); + var b = parseInt(result[3], 10); + var a = (result[4] !== undefined) ? parseFloat(result[4]) : 1; - // Because a Group child may mess with the length of the Group during its update - var temp = this.children.entries.slice(); + color.setTo(r, g, b, a * 255); + } - for (var i = 0; i < temp.length; i++) - { - var item = temp[i]; + return color; +}; - if (item.active) - { - item.update(time, delta); - } - } - }, +module.exports = RGBStringToColor; - /** - * Adds a Game Object to this group. - * - * Calls {@link Phaser.GameObjects.Group#createCallback}. - * - * @method Phaser.GameObjects.Group#add - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to add. - * @param {boolean} [addToScene=false] - Also add the Game Object to the scene. - * - * @return {this} This Group object. - */ - add: function (child, addToScene) - { - if (addToScene === undefined) { addToScene = false; } - if (this.isFull()) - { - return this; - } +/***/ }), - this.children.set(child); +/***/ 68033: +/***/ ((module) => { - if (this.internalCreateCallback) +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts an RGB color value to HSV (hue, saturation and value). + * Conversion formula from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes RGB values are contained in the set [0, 255] and returns h, s and v in the set [0, 1]. + * Based on code by Michael Jackson (https://github.com/mjijackson) + * + * @function Phaser.Display.Color.RGBToHSV + * @since 3.0.0 + * + * @param {number} r - The red color value. A number between 0 and 255. + * @param {number} g - The green color value. A number between 0 and 255. + * @param {number} b - The blue color value. A number between 0 and 255. + * @param {(Phaser.Types.Display.HSVColorObject|Phaser.Display.Color)} [out] - An object to store the color values in. If not given an HSV Color Object will be created. + * + * @return {(Phaser.Types.Display.HSVColorObject|Phaser.Display.Color)} An object with the properties `h`, `s` and `v` set. + */ +var RGBToHSV = function (r, g, b, out) +{ + if (out === undefined) { out = { h: 0, s: 0, v: 0 }; } + + r /= 255; + g /= 255; + b /= 255; + + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var d = max - min; + + // achromatic by default + var h = 0; + var s = (max === 0) ? 0 : d / max; + var v = max; + + if (max !== min) + { + if (max === r) { - this.internalCreateCallback.call(this, child); + h = (g - b) / d + ((g < b) ? 6 : 0); } - - if (this.createCallback) + else if (max === g) { - this.createCallback.call(this, child); + h = (b - r) / d + 2; } - - if (addToScene) + else if (max === b) { - child.addToDisplayList(this.scene.sys.displayList); - child.addToUpdateList(); + h = (r - g) / d + 4; } - child.on(Events.DESTROY, this.remove, this); - - return this; - }, + h /= 6; + } - /** - * Adds several Game Objects to this group. - * - * Calls {@link Phaser.GameObjects.Group#createCallback}. - * - * @method Phaser.GameObjects.Group#addMultiple - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject[]} children - The Game Objects to add. - * @param {boolean} [addToScene=false] - Also add the Game Objects to the scene. - * - * @return {this} This group. - */ - addMultiple: function (children, addToScene) + if (out.hasOwnProperty('_h')) { - if (addToScene === undefined) { addToScene = false; } + out._h = h; + out._s = s; + out._v = v; + } + else + { + out.h = h; + out.s = s; + out.v = v; + } - if (Array.isArray(children)) - { - for (var i = 0; i < children.length; i++) - { - this.add(children[i], addToScene); - } - } + return out; +}; - return this; - }, +module.exports = RGBToHSV; - /** - * Removes a member of this Group and optionally removes it from the Scene and / or destroys it. - * - * Calls {@link Phaser.GameObjects.Group#removeCallback}. - * - * @method Phaser.GameObjects.Group#remove - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to remove. - * @param {boolean} [removeFromScene=false] - Optionally remove the Group member from the Scene it belongs to. - * @param {boolean} [destroyChild=false] - Optionally call destroy on the removed Group member. - * - * @return {this} This Group object. - */ - remove: function (child, removeFromScene, destroyChild) + +/***/ }), + +/***/ 4880: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ComponentToHex = __webpack_require__(25409); + +/** + * Converts the color values into an HTML compatible color string, prefixed with either `#` or `0x`. + * + * @function Phaser.Display.Color.RGBToString + * @since 3.0.0 + * + * @param {number} r - The red color value. A number between 0 and 255. + * @param {number} g - The green color value. A number between 0 and 255. + * @param {number} b - The blue color value. A number between 0 and 255. + * @param {number} [a=255] - The alpha value. A number between 0 and 255. + * @param {string} [prefix=#] - The prefix of the string. Either `#` or `0x`. + * + * @return {string} A string-based representation of the color values. + */ +var RGBToString = function (r, g, b, a, prefix) +{ + if (a === undefined) { a = 255; } + if (prefix === undefined) { prefix = '#'; } + + if (prefix === '#') { - if (removeFromScene === undefined) { removeFromScene = false; } - if (destroyChild === undefined) { destroyChild = false; } + return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1, 7); + } + else + { + return '0x' + ComponentToHex(a) + ComponentToHex(r) + ComponentToHex(g) + ComponentToHex(b); + } +}; - if (!this.children.contains(child)) - { - return this; - } +module.exports = RGBToString; - this.children.delete(child); - if (this.internalRemoveCallback) - { - this.internalRemoveCallback.call(this, child); - } +/***/ }), - if (this.removeCallback) - { - this.removeCallback.call(this, child); - } +/***/ 37243: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - child.off(Events.DESTROY, this.remove, this); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (destroyChild) - { - child.destroy(); - } - else if (removeFromScene) - { - child.removeFromDisplayList(); - child.removeFromUpdateList(); - } +var Between = __webpack_require__(17489); +var Color = __webpack_require__(27119); - return this; - }, +/** + * Creates a new Color object where the r, g, and b values have been set to random values + * based on the given min max values. + * + * @function Phaser.Display.Color.RandomRGB + * @since 3.0.0 + * + * @param {number} [min=0] - The minimum value to set the random range from (between 0 and 255) + * @param {number} [max=255] - The maximum value to set the random range from (between 0 and 255) + * + * @return {Phaser.Display.Color} A Color object. + */ +var RandomRGB = function (min, max) +{ + if (min === undefined) { min = 0; } + if (max === undefined) { max = 255; } - /** - * Removes all members of this Group and optionally removes them from the Scene and / or destroys them. - * - * Does not call {@link Phaser.GameObjects.Group#removeCallback}. - * - * @method Phaser.GameObjects.Group#clear - * @since 3.0.0 - * - * @param {boolean} [removeFromScene=false] - Optionally remove each Group member from the Scene. - * @param {boolean} [destroyChild=false] - Optionally call destroy on the removed Group members. - * - * @return {this} This group. - */ - clear: function (removeFromScene, destroyChild) - { - if (removeFromScene === undefined) { removeFromScene = false; } - if (destroyChild === undefined) { destroyChild = false; } + return new Color(Between(min, max), Between(min, max), Between(min, max)); +}; - var children = this.children; +module.exports = RandomRGB; - for (var i = 0; i < children.size; i++) - { - var gameObject = children.entries[i]; - gameObject.off(Events.DESTROY, this.remove, this); +/***/ }), - if (destroyChild) +/***/ 93222: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var HexStringToColor = __webpack_require__(91487); +var IntegerToColor = __webpack_require__(74853); +var ObjectToColor = __webpack_require__(73904); +var RGBStringToColor = __webpack_require__(26841); + +/** + * Converts the given source color value into an instance of a Color class. + * The value can be either a string, prefixed with `rgb` or a hex string, a number or an Object. + * + * @function Phaser.Display.Color.ValueToColor + * @since 3.0.0 + * + * @param {(string|number|Phaser.Types.Display.InputColorObject)} input - The source color value to convert. + * + * @return {Phaser.Display.Color} A Color object. + */ +var ValueToColor = function (input) +{ + var t = typeof input; + + switch (t) + { + case 'string': + + if (input.substr(0, 3).toLowerCase() === 'rgb') { - gameObject.destroy(); + return RGBStringToColor(input); } - else if (removeFromScene) + else { - gameObject.removeFromDisplayList(); - gameObject.removeFromUpdateList(); + return HexStringToColor(input); } + + case 'number': + + return IntegerToColor(input); + + case 'object': + + return ObjectToColor(input); + } +}; + +module.exports = ValueToColor; + + +/***/ }), + +/***/ 95509: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Color = __webpack_require__(27119); + +Color.ColorSpectrum = __webpack_require__(30245); +Color.ColorToRGBA = __webpack_require__(86672); +Color.ComponentToHex = __webpack_require__(25409); +Color.GetColor = __webpack_require__(22946); +Color.GetColor32 = __webpack_require__(5657); +Color.HexStringToColor = __webpack_require__(91487); +Color.HSLToColor = __webpack_require__(74777); +Color.HSVColorWheel = __webpack_require__(89263); +Color.HSVToRGB = __webpack_require__(24650); +Color.HueToComponent = __webpack_require__(59998); +Color.IntegerToColor = __webpack_require__(74853); +Color.IntegerToRGB = __webpack_require__(15978); +Color.Interpolate = __webpack_require__(53756); +Color.ObjectToColor = __webpack_require__(73904); +Color.RandomRGB = __webpack_require__(37243); +Color.RGBStringToColor = __webpack_require__(26841); +Color.RGBToHSV = __webpack_require__(68033); +Color.RGBToString = __webpack_require__(4880); +Color.ValueToColor = __webpack_require__(93222); + +module.exports = Color; + + +/***/ }), + +/***/ 24816: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Display + */ + +module.exports = { + + Align: __webpack_require__(93545), + BaseShader: __webpack_require__(31053), + Bounds: __webpack_require__(15252), + Canvas: __webpack_require__(23514), + Color: __webpack_require__(95509), + ColorMatrix: __webpack_require__(65246), + Masks: __webpack_require__(93310), + RGB: __webpack_require__(39298) + +}; + + +/***/ }), + +/***/ 76756: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var GameObjectFactory = __webpack_require__(61286); + +/** + * @classdesc + * A Bitmap Mask combines the alpha (opacity) of a masked pixel with the alpha of another pixel. + * Unlike the Geometry Mask, which is a clipping path, a Bitmap Mask behaves like an alpha mask, + * not a clipping path. It is only available when using the WebGL Renderer. + * + * A Bitmap Mask can use any Game Object or Dynamic Texture to determine the alpha of each pixel of the masked Game Object(s). + * For any given point of a masked Game Object's texture, the pixel's alpha will be multiplied by the alpha + * of the pixel at the same position in the Bitmap Mask's Game Object. The color of the pixel from the + * Bitmap Mask doesn't matter. + * + * For example, if a pure blue pixel with an alpha of 0.95 is masked with a pure red pixel with an + * alpha of 0.5, the resulting pixel will be pure blue with an alpha of 0.475. Naturally, this means + * that a pixel in the mask with an alpha of 0 will hide the corresponding pixel in all masked Game Objects. + * A pixel with an alpha of 1 in the masked Game Object will receive the same alpha as the + * corresponding pixel in the mask. + * + * Note: You cannot combine Bitmap Masks and Blend Modes on the same Game Object. You can, however, + * combine Geometry Masks and Blend Modes together. + * + * The Bitmap Mask's location matches the location of its Game Object, not the location of the + * masked objects. Moving or transforming the underlying Game Object will change the mask + * (and affect the visibility of any masked objects), whereas moving or transforming a masked object + * will not affect the mask. + * + * The Bitmap Mask will not render its Game Object by itself. If the Game Object is not in a + * Scene's display list, it will only be used for the mask and its full texture will not be directly + * visible. Adding the underlying Game Object to a Scene will not cause any problems - it will + * render as a normal Game Object and will also serve as a mask. + * + * @class BitmapMask + * @memberof Phaser.Display.Masks + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to which this mask is being added. + * @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} [maskObject] - The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param {number} [x] - If creating a Game Object, the horizontal position in the world. + * @param {number} [y] - If creating a Game Object, the vertical position in the world. + * @param {(string|Phaser.Textures.Texture)} [texture] - If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param {(string|number|Phaser.Textures.Frame)} [frame] - If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. + */ +var BitmapMask = new Class({ + + initialize: + + function BitmapMask (scene, maskObject, x, y, texture, frame) + { + if (!maskObject) + { + maskObject = scene.sys.make.image({ x: x, y: y, key: texture, frame: frame, add: false }); } - this.children.clear(); + /** + * The Game Object that is used as the mask. Must use a texture, such as a Sprite. + * + * @name Phaser.Display.Masks.BitmapMask#bitmapMask + * @type {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} + * @since 3.0.0 + */ + this.bitmapMask = maskObject; - return this; + /** + * Whether to invert the masks alpha. + * + * If `true`, the alpha of the masking pixel will be inverted before it's multiplied with the masked pixel. + * + * Essentially, this means that a masked area will be visible only if the corresponding area in the mask is invisible. + * + * @name Phaser.Display.Masks.BitmapMask#invertAlpha + * @type {boolean} + * @since 3.1.2 + */ + this.invertAlpha = false; + + /** + * Is this mask a stencil mask? This is false by default and should not be changed. + * + * @name Phaser.Display.Masks.BitmapMask#isStencil + * @type {boolean} + * @readonly + * @since 3.17.0 + */ + this.isStencil = false; }, /** - * Tests if a Game Object is a member of this group. + * Sets a new Game Object or Dynamic Texture for this Bitmap Mask to use. * - * @method Phaser.GameObjects.Group#contains - * @since 3.0.0 + * If a Game Object it must have a texture, such as a Sprite. * - * @param {Phaser.GameObjects.GameObject} child - A Game Object. + * You can update the source of the mask as often as you like. * - * @return {boolean} True if the Game Object is a member of this group. + * @method Phaser.Display.Masks.BitmapMask#setBitmap + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} maskObject - The Game Object or Dynamic Texture that will be used as the mask. If a Game Object, it must have a texture, such as a Sprite. */ - contains: function (child) + setBitmap: function (maskObject) { - return this.children.contains(child); + this.bitmapMask = maskObject; }, /** - * All members of the group. + * Prepares the WebGL Renderer to render a Game Object with this mask applied. * - * @method Phaser.GameObjects.Group#getChildren + * This renders the masking Game Object to the mask framebuffer and switches to the main framebuffer so that the masked Game Object will be rendered to it instead of being rendered directly to the frame. + * + * @method Phaser.Display.Masks.BitmapMask#preRenderWebGL * @since 3.0.0 * - * @return {Phaser.GameObjects.GameObject[]} The group members. - */ - getChildren: function () - { - return this.children.entries; - }, - - /** - * The number of members of the group. - * - * @method Phaser.GameObjects.Group#getLength - * @since 3.0.0 - * - * @return {number} + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to prepare. + * @param {Phaser.GameObjects.GameObject} maskedObject - The masked Game Object which will be drawn. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to. */ - getLength: function () + preRenderWebGL: function (renderer, maskedObject, camera) { - return this.children.size; + renderer.pipelines.BITMAPMASK_PIPELINE.beginMask(this, maskedObject, camera); }, /** - * Returns all children in this Group that match the given criteria based on the `property` and `value` arguments. - * - * For example: `getMatching('visible', true)` would return only children that have their `visible` property set. - * - * Optionally, you can specify a start and end index. For example if the Group has 100 elements, - * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only - * the first 50. + * Finalizes rendering of a masked Game Object. * - * @method Phaser.GameObjects.Group#getMatching - * @since 3.50.0 + * This resets the previously bound framebuffer and switches the WebGL Renderer to the Bitmap Mask Pipeline, which uses a special fragment shader to apply the masking effect. * - * @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] - An optional start index to search from. - * @param {number} [endIndex] - An optional end index to search to. + * @method Phaser.Display.Masks.BitmapMask#postRenderWebGL + * @since 3.0.0 * - * @return {any[]} An array of matching Group members. The array will be empty if nothing matched. + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to clean up. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to. + * @param {Phaser.Renderer.WebGL.RenderTarget} [renderTarget] - Optional WebGL RenderTarget. */ - getMatching: function (property, value, startIndex, endIndex) + postRenderWebGL: function (renderer, camera, renderTarget) { - return GetAll(this.children.entries, property, value, startIndex, endIndex); + renderer.pipelines.BITMAPMASK_PIPELINE.endMask(this, camera, renderTarget); }, /** - * Scans the Group, from top to bottom, for the first member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, - * assigns `x` and `y`, and returns the member. - * - * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer. * - * @method Phaser.GameObjects.Group#getFirst + * @method Phaser.Display.Masks.BitmapMask#preRenderCanvas * @since 3.0.0 * - * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. - * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. - * @param {number} [x] - The horizontal position of the Game Object in the world. - * @param {number} [y] - The vertical position of the Game Object in the world. - * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). - * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). - * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). - * - * @return {?any} The first matching group member, or a newly created member, or null. + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to. + * @param {Phaser.GameObjects.GameObject} mask - The masked Game Object which would be rendered. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to. */ - getFirst: function (state, createIfNull, x, y, key, frame, visible) + preRenderCanvas: function () { - return this.getHandler(true, 1, state, createIfNull, x, y, key, frame, visible); + // NOOP }, /** - * Scans the Group, from top to bottom, for the nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, - * assigns `x` and `y`, and returns the member. - * - * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * - * @method Phaser.GameObjects.Group#getFirstNth - * @since 3.6.0 + * This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer. * - * @param {number} nth - The nth matching Group member to search for. - * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. - * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. - * @param {number} [x] - The horizontal position of the Game Object in the world. - * @param {number} [y] - The vertical position of the Game Object in the world. - * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). - * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). - * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). + * @method Phaser.Display.Masks.BitmapMask#postRenderCanvas + * @since 3.0.0 * - * @return {?any} The first matching group member, or a newly created member, or null. + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to. */ - getFirstNth: function (nth, state, createIfNull, x, y, key, frame, visible) + postRenderCanvas: function () { - return this.getHandler(true, nth, state, createIfNull, x, y, key, frame, visible); + // NOOP }, /** - * Scans the Group for the last member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, - * assigns `x` and `y`, and returns the member. - * - * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * - * @method Phaser.GameObjects.Group#getLast - * @since 3.6.0 + * Destroys this BitmapMask and nulls any references it holds. * - * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. - * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. - * @param {number} [x] - The horizontal position of the Game Object in the world. - * @param {number} [y] - The vertical position of the Game Object in the world. - * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). - * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). - * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). + * Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it, + * so be sure to call `clearMask` on any Game Object using it, before destroying it. * - * @return {?any} The first matching group member, or a newly created member, or null. + * @method Phaser.Display.Masks.BitmapMask#destroy + * @since 3.7.0 */ - getLast: function (state, createIfNull, x, y, key, frame, visible) + destroy: function () { - return this.getHandler(false, 1, state, createIfNull, x, y, key, frame, visible); - }, + this.bitmapMask = null; + } - /** - * Scans the Group for the last nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, - * assigns `x` and `y`, and returns the member. - * - * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * - * @method Phaser.GameObjects.Group#getLastNth - * @since 3.6.0 - * - * @param {number} nth - The nth matching Group member to search for. - * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. - * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. - * @param {number} [x] - The horizontal position of the Game Object in the world. - * @param {number} [y] - The vertical position of the Game Object in the world. - * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). - * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). - * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). - * - * @return {?any} The first matching group member, or a newly created member, or null. - */ - getLastNth: function (nth, state, createIfNull, x, y, key, frame, visible) - { - return this.getHandler(false, nth, state, createIfNull, x, y, key, frame, visible); - }, +}); - /** - * Scans the group for the last member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, - * assigns `x` and `y`, and returns the member. - * - * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * - * @method Phaser.GameObjects.Group#getHandler - * @private - * @since 3.6.0 - * - * @param {boolean} forwards - Search front to back or back to front? - * @param {number} nth - Stop matching after nth successful matches. - * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. - * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. - * @param {number} [x] - The horizontal position of the Game Object in the world. - * @param {number} [y] - The vertical position of the Game Object in the world. - * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). - * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). - * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). - * - * @return {?any} The first matching group member, or a newly created member, or null. - */ - getHandler: function (forwards, nth, state, createIfNull, x, y, key, frame, visible) - { - if (state === undefined) { state = false; } - if (createIfNull === undefined) { createIfNull = false; } +/** + * A Bitmap Mask combines the alpha (opacity) of a masked pixel with the alpha of another pixel. + * Unlike the Geometry Mask, which is a clipping path, a Bitmap Mask behaves like an alpha mask, + * not a clipping path. It is only available when using the WebGL Renderer. + * + * A Bitmap Mask can use any Game Object, or Dynamic Texture, to determine the alpha of each pixel of the masked Game Object(s). + * For any given point of a masked Game Object's texture, the pixel's alpha will be multiplied by the alpha + * of the pixel at the same position in the Bitmap Mask's Game Object. The color of the pixel from the + * Bitmap Mask doesn't matter. + * + * For example, if a pure blue pixel with an alpha of 0.95 is masked with a pure red pixel with an + * alpha of 0.5, the resulting pixel will be pure blue with an alpha of 0.475. Naturally, this means + * that a pixel in the mask with an alpha of 0 will hide the corresponding pixel in all masked Game Objects + * A pixel with an alpha of 1 in the masked Game Object will receive the same alpha as the + * corresponding pixel in the mask. + * + * Note: You cannot combine Bitmap Masks and Blend Modes on the same Game Object. You can, however, + * combine Geometry Masks and Blend Modes together. + * + * The Bitmap Mask's location matches the location of its Game Object, not the location of the + * masked objects. Moving or transforming the underlying Game Object will change the mask + * (and affect the visibility of any masked objects), whereas moving or transforming a masked object + * will not affect the mask. + * + * The Bitmap Mask will not render its Game Object by itself. If the Game Object is not in a + * Scene's display list, it will only be used for the mask and its full texture will not be directly + * visible. Adding the underlying Game Object to a Scene will not cause any problems - it will + * render as a normal Game Object and will also serve as a mask. + * + * @method Phaser.GameObjects.GameObjectFactory#bitmapMask + * @since 3.60.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} [maskObject] - The Game Object or Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param {number} [x] - If creating a Game Object, the horizontal position in the world. + * @param {number} [y] - If creating a Game Object, the vertical position in the world. + * @param {(string|Phaser.Textures.Texture)} [texture] - If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param {(string|number|Phaser.Textures.Frame)} [frame] - If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Display.Masks.BitmapMask} The Bitmap Mask that was created. + */ +GameObjectFactory.register('bitmapMask', function (maskObject, x, y, key, frame) +{ + return new BitmapMask(this.scene, maskObject, x, y, key, frame); +}); - var gameObject; +module.exports = BitmapMask; - var i; - var total = 0; - var children = this.children.entries; - if (forwards) - { - for (i = 0; i < children.length; i++) - { - gameObject = children[i]; +/***/ }), - if (gameObject.active === state) - { - total++; +/***/ 63037: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (total === nth) - { - break; - } - } - else - { - gameObject = null; - } - } - } - else - { - for (i = children.length - 1; i >= 0; i--) - { - gameObject = children[i]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (gameObject.active === state) - { - total++; +var Class = __webpack_require__(56694); - if (total === nth) - { - break; - } - } - else - { - gameObject = null; - } - } - } +/** + * @classdesc + * A Geometry Mask can be applied to a Game Object to hide any pixels of it which don't intersect + * a visible pixel from the geometry mask. The mask is essentially a clipping path which can only + * make a masked pixel fully visible or fully invisible without changing its alpha (opacity). + * + * A Geometry Mask uses a Graphics Game Object to determine which pixels of the masked Game Object(s) + * should be clipped. For any given point of a masked Game Object's texture, the pixel will only be displayed + * if the Graphics Game Object of the Geometry Mask has a visible pixel at the same position. The color and + * alpha of the pixel from the Geometry Mask do not matter. + * + * The Geometry Mask's location matches the location of its Graphics object, not the location of the masked objects. + * Moving or transforming the underlying Graphics object will change the mask (and affect the visibility + * of any masked objects), whereas moving or transforming a masked object will not affect the mask. + * You can think of the Geometry Mask (or rather, of its Graphics object) as an invisible curtain placed + * in front of all masked objects which has its own visual properties and, naturally, respects the camera's + * visual properties, but isn't affected by and doesn't follow the masked objects by itself. + * + * @class GeometryMask + * @memberof Phaser.Display.Masks + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - This parameter is not used. + * @param {Phaser.GameObjects.Graphics} graphicsGeometry - The Graphics Game Object to use for the Geometry Mask. Doesn't have to be in the Display List. + */ +var GeometryMask = new Class({ - if (gameObject) - { - if (typeof(x) === 'number') - { - gameObject.x = x; - } + initialize: - if (typeof(y) === 'number') - { - gameObject.y = y; - } + function GeometryMask (scene, graphicsGeometry) + { + /** + * The Graphics object which describes the Geometry Mask. + * + * @name Phaser.Display.Masks.GeometryMask#geometryMask + * @type {Phaser.GameObjects.Graphics} + * @since 3.0.0 + */ + this.geometryMask = graphicsGeometry; - return gameObject; - } + /** + * Similar to the BitmapMasks invertAlpha setting this to true will then hide all pixels + * drawn to the Geometry Mask. + * + * This is a WebGL only feature. + * + * @name Phaser.Display.Masks.GeometryMask#invertAlpha + * @type {boolean} + * @since 3.16.0 + */ + this.invertAlpha = false; - // Got this far? We need to create or bail - if (createIfNull) - { - return this.create(x, y, key, frame, visible); - } - else - { - return null; - } - }, + /** + * Is this mask a stencil mask? + * + * @name Phaser.Display.Masks.GeometryMask#isStencil + * @type {boolean} + * @readonly + * @since 3.17.0 + */ + this.isStencil = true; - /** - * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`, - * assigns `x` and `y`, and returns the member. - * - * If no inactive member is found and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * The new Game Object will have its active state set to `true`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * - * @method Phaser.GameObjects.Group#get - * @since 3.0.0 - * - * @param {number} [x] - The horizontal position of the Game Object in the world. - * @param {number} [y] - The vertical position of the Game Object in the world. - * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). - * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). - * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). - * - * @return {?any} The first inactive group member, or a newly created member, or null. - */ - get: function (x, y, key, frame, visible) - { - return this.getFirst(false, true, x, y, key, frame, visible); + /** + * The current stencil level. This can change dynamically at runtime + * and is set in the applyStencil method. + * + * @name Phaser.Display.Masks.GeometryMask#level + * @type {boolean} + * @since 3.17.0 + */ + this.level = 0; }, /** - * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `true`, - * assigns `x` and `y`, and returns the member. - * - * If no active member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * Sets a new Graphics object for the Geometry Mask. * - * @method Phaser.GameObjects.Group#getFirstAlive + * @method Phaser.Display.Masks.GeometryMask#setShape * @since 3.0.0 * - * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. - * @param {number} [x] - The horizontal position of the Game Object in the world. - * @param {number} [y] - The vertical position of the Game Object in the world. - * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). - * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). - * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). + * @param {Phaser.GameObjects.Graphics} graphicsGeometry - The Graphics object which will be used for the Geometry Mask. * - * @return {any} The first active group member, or a newly created member, or null. + * @return {this} This Geometry Mask */ - getFirstAlive: function (createIfNull, x, y, key, frame, visible) + setShape: function (graphicsGeometry) { - return this.getFirst(true, createIfNull, x, y, key, frame, visible); + this.geometryMask = graphicsGeometry; + + return this; }, /** - * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`, - * assigns `x` and `y`, and returns the member. - * - * If no inactive member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`. - * The new Game Object will have an active state set to `true`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * - * @method Phaser.GameObjects.Group#getFirstDead - * @since 3.0.0 + * Sets the `invertAlpha` property of this Geometry Mask. * - * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. - * @param {number} [x] - The horizontal position of the Game Object in the world. - * @param {number} [y] - The vertical position of the Game Object in the world. - * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). - * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). - * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). + * Inverting the alpha essentially flips the way the mask works. * - * @return {any} The first inactive group member, or a newly created member, or null. - */ - getFirstDead: function (createIfNull, x, y, key, frame, visible) - { - return this.getFirst(false, createIfNull, x, y, key, frame, visible); - }, - - /** - * {@link Phaser.GameObjects.Components.Animation#play Plays} an animation for all members of this group. + * This is a WebGL only feature. * - * @method Phaser.GameObjects.Group#playAnimation - * @since 3.0.0 + * @method Phaser.Display.Masks.GeometryMask#setInvertAlpha + * @since 3.17.0 * - * @param {string} key - The string-based key of the animation to play. - * @param {string} [startFrame=0] - Optionally start the animation playing from this frame index. + * @param {boolean} [value=true] - Invert the alpha of this mask? * - * @return {this} This Group object. + * @return {this} This Geometry Mask */ - playAnimation: function (key, startFrame) + setInvertAlpha: function (value) { - Actions.PlayAnimation(this.children.entries, key, startFrame); + if (value === undefined) { value = true; } + + this.invertAlpha = value; return this; }, /** - * Whether this group's size at its {@link Phaser.GameObjects.Group#maxSize maximum}. + * Renders the Geometry Mask's underlying Graphics object to the OpenGL stencil buffer and enables the stencil test, which clips rendered pixels according to the mask. * - * @method Phaser.GameObjects.Group#isFull + * @method Phaser.Display.Masks.GeometryMask#preRenderWebGL * @since 3.0.0 * - * @return {boolean} True if the number of members equals {@link Phaser.GameObjects.Group#maxSize}. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to. + * @param {Phaser.GameObjects.GameObject} child - The Game Object being rendered. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through. */ - isFull: function () + preRenderWebGL: function (renderer, child, camera) { - if (this.maxSize === -1) + var gl = renderer.gl; + + // Force flushing before drawing to stencil buffer + renderer.flush(); + + if (renderer.maskStack.length === 0) { - return false; + gl.enable(gl.STENCIL_TEST); + gl.clear(gl.STENCIL_BUFFER_BIT); + + renderer.maskCount = 0; } - else + + if (renderer.currentCameraMask.mask !== this) { - return (this.children.size >= this.maxSize); + renderer.currentMask.mask = this; } - }, - - /** - * Counts the number of active (or inactive) group members. - * - * @method Phaser.GameObjects.Group#countActive - * @since 3.0.0 - * - * @param {boolean} [value=true] - Count active (true) or inactive (false) group members. - * - * @return {number} The number of group members with an active state matching the `active` argument. - */ - countActive: function (value) - { - if (value === undefined) { value = true; } - var total = 0; + renderer.maskStack.push({ mask: this, camera: camera }); - for (var i = 0; i < this.children.size; i++) - { - if (this.children.entries[i].active === value) - { - total++; - } - } + this.applyStencil(renderer, camera, true); - return total; + renderer.maskCount++; }, /** - * Counts the number of in-use (active) group members. + * Applies the current stencil mask to the renderer. * - * @method Phaser.GameObjects.Group#getTotalUsed - * @since 3.0.0 + * @method Phaser.Display.Masks.GeometryMask#applyStencil + * @since 3.17.0 * - * @return {number} The number of group members with an active state of true. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through. + * @param {boolean} inc - Is this an INCR stencil or a DECR stencil? */ - getTotalUsed: function () + applyStencil: function (renderer, camera, inc) { - return this.countActive(); - }, + var gl = renderer.gl; + var geometryMask = this.geometryMask; + var level = renderer.maskCount; + var mask = 0xff; - /** - * The difference of {@link Phaser.GameObjects.Group#maxSize} and the number of active group members. - * - * This represents the number of group members that could be created or reactivated before reaching the size limit. - * - * @method Phaser.GameObjects.Group#getTotalFree - * @since 3.0.0 - * - * @return {number} maxSize minus the number of active group numbers; or a large number (if maxSize is -1). - */ - getTotalFree: function () - { - var used = this.getTotalUsed(); - var capacity = (this.maxSize === -1) ? 999999999999 : this.maxSize; + gl.colorMask(false, false, false, false); - return (capacity - used); - }, + if (inc) + { + gl.stencilFunc(gl.EQUAL, level, mask); + gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR); - /** - * Sets the `active` property of this Group. - * When active, this Group runs its `preUpdate` method. - * - * @method Phaser.GameObjects.Group#setActive - * @since 3.24.0 - * - * @param {boolean} value - True if this Group should be set as active, false if not. - * - * @return {this} This Group object. - */ - setActive: function (value) - { - this.active = value; + // Do this _after_ we set the stencilFunc + level++; + } + else + { + gl.stencilFunc(gl.EQUAL, level + 1, mask); + gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR); + } - return this; - }, + this.level = level; - /** - * Sets the `name` property of this Group. - * The `name` property is not populated by Phaser and is presented for your own use. - * - * @method Phaser.GameObjects.Group#setName - * @since 3.24.0 - * - * @param {string} value - The name to be given to this Group. - * - * @return {this} This Group object. - */ - setName: function (value) - { - this.name = value; + // Write stencil buffer + geometryMask.renderWebGL(renderer, geometryMask, camera); - return this; - }, + renderer.flush(); - /** - * Sets the property as defined in `key` of each group member to the given value. - * - * @method Phaser.GameObjects.Group#propertyValueSet - * @since 3.21.0 - * - * @param {string} key - The property to be updated. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {this} This Group object. - */ - propertyValueSet: function (key, value, step, index, direction) - { - Actions.PropertyValueSet(this.children.entries, key, value, step, index, direction); + gl.colorMask(true, true, true, true); + gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); - return this; + if (this.invertAlpha) + { + gl.stencilFunc(gl.NOTEQUAL, level, mask); + } + else + { + gl.stencilFunc(gl.EQUAL, level, mask); + } }, /** - * Adds the given value to the property as defined in `key` of each group member. - * - * @method Phaser.GameObjects.Group#propertyValueInc - * @since 3.21.0 + * Flushes all rendered pixels and disables the stencil test of a WebGL context, thus disabling the mask for it. * - * @param {string} key - The property to be updated. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * @method Phaser.Display.Masks.GeometryMask#postRenderWebGL + * @since 3.0.0 * - * @return {this} This Group object. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw flush. */ - propertyValueInc: function (key, value, step, index, direction) + postRenderWebGL: function (renderer) { - Actions.PropertyValueInc(this.children.entries, key, value, step, index, direction); + var gl = renderer.gl; - return this; - }, + renderer.maskStack.pop(); - /** - * Sets the x of each group member. - * - * @method Phaser.GameObjects.Group#setX - * @since 3.21.0 - * - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - setX: function (value, step) - { - Actions.SetX(this.children.entries, value, step); + renderer.maskCount--; - return this; - }, + // Force flush before disabling stencil test + renderer.flush(); - /** - * Sets the y of each group member. - * - * @method Phaser.GameObjects.Group#setY - * @since 3.21.0 - * - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - setY: function (value, step) - { - Actions.SetY(this.children.entries, value, step); + var current = renderer.currentMask; - return this; - }, + if (renderer.maskStack.length === 0) + { + // If this is the only mask in the stack, flush and disable + current.mask = null; - /** - * Sets the x, y of each group member. - * - * @method Phaser.GameObjects.Group#setXY - * @since 3.21.0 - * - * @param {number} x - The amount to set the `x` property to. - * @param {number} [y=x] - The amount to set the `y` property to. If `undefined` or `null` it uses the `x` value. - * @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - setXY: function (x, y, stepX, stepY) - { - Actions.SetXY(this.children.entries, x, y, stepX, stepY); + gl.disable(gl.STENCIL_TEST); + } + else + { + var prev = renderer.maskStack[renderer.maskStack.length - 1]; - return this; + prev.mask.applyStencil(renderer, prev.camera, false); + + if (renderer.currentCameraMask.mask !== prev.mask) + { + current.mask = prev.mask; + current.camera = prev.camera; + } + else + { + current.mask = null; + } + } }, /** - * Adds the given value to the x of each group member. - * - * @method Phaser.GameObjects.Group#incX - * @since 3.21.0 + * Sets the clipping path of a 2D canvas context to the Geometry Mask's underlying Graphics object. * - * @param {number} value - The amount to be added to the `x` property. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @method Phaser.Display.Masks.GeometryMask#preRenderCanvas + * @since 3.0.0 * - * @return {this} This Group object. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance to set the clipping path on. + * @param {Phaser.GameObjects.GameObject} mask - The Game Object being rendered. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through. */ - incX: function (value, step) + preRenderCanvas: function (renderer, mask, camera) { - Actions.IncX(this.children.entries, value, step); + var geometryMask = this.geometryMask; - return this; - }, + renderer.currentContext.save(); - /** - * Adds the given value to the y of each group member. - * - * @method Phaser.GameObjects.Group#incY - * @since 3.21.0 - * - * @param {number} value - The amount to be added to the `y` property. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - incY: function (value, step) - { - Actions.IncY(this.children.entries, value, step); + geometryMask.renderCanvas(renderer, geometryMask, camera, null, null, true); - return this; + renderer.currentContext.clip(); }, /** - * Adds the given value to the x, y of each group member. - * - * @method Phaser.GameObjects.Group#incXY - * @since 3.21.0 + * Restore the canvas context's previous clipping path, thus turning off the mask for it. * - * @param {number} x - The amount to be added to the `x` property. - * @param {number} [y=x] - The amount to be added to the `y` property. If `undefined` or `null` it uses the `x` value. - * @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter. + * @method Phaser.Display.Masks.GeometryMask#postRenderCanvas + * @since 3.0.0 * - * @return {this} This Group object. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance being restored. */ - incXY: function (x, y, stepX, stepY) + postRenderCanvas: function (renderer) { - Actions.IncXY(this.children.entries, x, y, stepX, stepY); - - return this; + renderer.currentContext.restore(); }, /** - * Iterate through the group members changing the position of each element to be that of the element that came before - * it in the array (or after it if direction = 1) - * - * The first group member position is set to x/y. - * - * @method Phaser.GameObjects.Group#shiftPosition - * @since 3.21.0 + * Destroys this GeometryMask and nulls any references it holds. * - * @param {number} x - The x coordinate to place the first item in the array at. - * @param {number} y - The y coordinate to place the first item in the array at. - * @param {number} [direction=0] - The iteration direction. 0 = first to last and 1 = last to first. + * Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it, + * so be sure to call `clearMask` on any Game Object using it, before destroying it. * - * @return {this} This Group object. + * @method Phaser.Display.Masks.GeometryMask#destroy + * @since 3.7.0 */ - shiftPosition: function (x, y, direction) + destroy: function () { - Actions.ShiftPosition(this.children.entries, x, y, direction); + this.geometryMask = null; + } - return this; - }, +}); - /** - * Sets the angle of each group member. - * - * @method Phaser.GameObjects.Group#angle - * @since 3.21.0 - * - * @param {number} value - The amount to set the angle to, in degrees. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - angle: function (value, step) - { - Actions.Angle(this.children.entries, value, step); +module.exports = GeometryMask; - return this; - }, - /** - * Sets the rotation of each group member. - * - * @method Phaser.GameObjects.Group#rotate - * @since 3.21.0 - * - * @param {number} value - The amount to set the rotation to, in radians. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - rotate: function (value, step) - { - Actions.Rotate(this.children.entries, value, step); +/***/ }), - return this; - }, +/***/ 93310: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Rotates each group member around the given point by the given angle. - * - * @method Phaser.GameObjects.Group#rotateAround - * @since 3.21.0 - * - * @param {Phaser.Types.Math.Vector2Like} point - Any object with public `x` and `y` properties. - * @param {number} angle - The angle to rotate by, in radians. - * - * @return {this} This Group object. - */ - rotateAround: function (point, angle) - { - Actions.RotateAround(this.children.entries, point, angle); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +/** + * @namespace Phaser.Display.Masks + */ - /** - * Rotates each group member around the given point by the given angle and distance. - * - * @method Phaser.GameObjects.Group#rotateAroundDistance - * @since 3.21.0 - * - * @param {Phaser.Types.Math.Vector2Like} point - Any object with public `x` and `y` properties. - * @param {number} angle - The angle to rotate by, in radians. - * @param {number} distance - The distance from the point of rotation in pixels. - * - * @return {this} This Group object. - */ - rotateAroundDistance: function (point, angle, distance) - { - Actions.RotateAroundDistance(this.children.entries, point, angle, distance); +module.exports = { - return this; - }, + BitmapMask: __webpack_require__(76756), + GeometryMask: __webpack_require__(63037) - /** - * Sets the alpha of each group member. - * - * @method Phaser.GameObjects.Group#setAlpha - * @since 3.21.0 - * - * @param {number} value - The amount to set the alpha to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - setAlpha: function (value, step) - { - Actions.SetAlpha(this.children.entries, value, step); +}; - return this; - }, - /** - * Sets the tint of each group member. - * - * @method Phaser.GameObjects.Group#setTint - * @since 3.21.0 - * - * @param {number} topLeft - The tint being applied to top-left corner of item. If other parameters are given no value, this tint will be applied to whole item. - * @param {number} [topRight] - The tint to be applied to top-right corner of item. - * @param {number} [bottomLeft] - The tint to be applied to the bottom-left corner of item. - * @param {number} [bottomRight] - The tint to be applied to the bottom-right corner of item. - * - * @return {this} This Group object. - */ - setTint: function (topLeft, topRight, bottomLeft, bottomRight) - { - Actions.SetTint(this.children.entries, topLeft, topRight, bottomLeft, bottomRight); +/***/ }), - return this; - }, +/***/ 31053: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Sets the originX, originY of each group member. - * - * @method Phaser.GameObjects.Group#setOrigin - * @since 3.21.0 - * - * @param {number} originX - The amount to set the `originX` property to. - * @param {number} [originY] - The amount to set the `originY` property to. If `undefined` or `null` it uses the `originX` value. - * @param {number} [stepX=0] - This is added to the `originX` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `originY` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - setOrigin: function (originX, originY, stepX, stepY) - { - Actions.SetOrigin(this.children.entries, originX, originY, stepX, stepY); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +var Class = __webpack_require__(56694); - /** - * Sets the scaleX of each group member. - * - * @method Phaser.GameObjects.Group#scaleX - * @since 3.21.0 - * - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - scaleX: function (value, step) - { - Actions.ScaleX(this.children.entries, value, step); +/** + * @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({ - return this; - }, + initialize: - /** - * Sets the scaleY of each group member. - * - * @method Phaser.GameObjects.Group#scaleY - * @since 3.21.0 - * - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - scaleY: function (value, step) + function BaseShader (key, fragmentSrc, vertexSrc, uniforms) { - Actions.ScaleY(this.children.entries, value, step); + if (!fragmentSrc || fragmentSrc === '') + { + fragmentSrc = [ + 'precision mediump float;', - return this; - }, + 'uniform vec2 resolution;', - /** - * Sets the scaleX, scaleY of each group member. - * - * @method Phaser.GameObjects.Group#scaleXY - * @since 3.21.0 - * - * @param {number} scaleX - The amount to be added to the `scaleX` property. - * @param {number} [scaleY] - The amount to be added to the `scaleY` property. If `undefined` or `null` it uses the `scaleX` value. - * @param {number} [stepX=0] - This is added to the `scaleX` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `scaleY` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - scaleXY: function (scaleX, scaleY, stepX, stepY) - { - Actions.ScaleXY(this.children.entries, scaleX, scaleY, stepX, stepY); + 'varying vec2 fragCoord;', - return this; - }, + 'void main () {', + ' vec2 uv = fragCoord / resolution.xy;', + ' gl_FragColor = vec4(uv.xyx, 1.0);', + '}' + ].join('\n'); + } - /** - * Sets the depth of each group member. - * - * @method Phaser.GameObjects.Group#setDepth - * @since 3.0.0 - * - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * - * @return {this} This Group object. - */ - setDepth: function (value, step) - { - Actions.SetDepth(this.children.entries, value, step); + if (!vertexSrc || vertexSrc === '') + { + vertexSrc = [ + 'precision mediump float;', - return this; - }, + 'uniform mat4 uProjectionMatrix;', + 'uniform mat4 uViewMatrix;', + 'uniform vec2 uResolution;', - /** - * Sets the blendMode of each group member. - * - * @method Phaser.GameObjects.Group#setBlendMode - * @since 3.21.0 - * - * @param {number} value - The amount to set the property to. - * - * @return {this} This Group object. - */ - setBlendMode: function (value) - { - Actions.SetBlendMode(this.children.entries, value); + 'attribute vec2 inPosition;', - return this; - }, + 'varying vec2 fragCoord;', + 'varying vec2 outTexCoord;', - /** - * Passes all group members to the Input Manager to enable them for input with identical areas and callbacks. - * - * @method Phaser.GameObjects.Group#setHitArea - * @since 3.21.0 - * - * @param {*} hitArea - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. - * @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - A callback to be invoked when the Game Object is interacted with. If you provide a shape you must also provide a callback. - * - * @return {this} This Group object. - */ - setHitArea: function (hitArea, hitAreaCallback) - { - Actions.SetHitArea(this.children.entries, hitArea, hitAreaCallback); + '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'); + } - return this; - }, + if (uniforms === undefined) { uniforms = null; } - /** - * Shuffles the group members in place. - * - * @method Phaser.GameObjects.Group#shuffle - * @since 3.21.0 - * - * @return {this} This Group object. - */ - shuffle: function () - { - Actions.Shuffle(this.children.entries); + /** + * 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; - return this; - }, + /** + * 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; - /** - * Deactivates a member of this group. - * - * @method Phaser.GameObjects.Group#kill - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - A member of this group. - */ - kill: function (gameObject) + /** + * 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; + + +/***/ }), + +/***/ 99584: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Adds the given element to the DOM. If a parent is provided the element is added as a child of the parent, providing it was able to access it. + * If no parent was given it falls back to using `document.body`. + * + * @function Phaser.DOM.AddToDOM + * @since 3.0.0 + * + * @param {HTMLElement} element - The element to be added to the DOM. Usually a Canvas object. + * @param {(string|HTMLElement)} [parent] - The parent in which to add the element. Can be a string which is passed to `getElementById` or an actual DOM object. + * + * @return {HTMLElement} The element that was added to the DOM. + */ +var AddToDOM = function (element, parent) +{ + var target; + + if (parent) { - if (this.children.contains(gameObject)) + if (typeof parent === 'string') { - gameObject.setActive(false); + // Hopefully an element ID + target = document.getElementById(parent); } - }, - - /** - * Deactivates and hides a member of this group. - * - * @method Phaser.GameObjects.Group#killAndHide - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - A member of this group. - */ - killAndHide: function (gameObject) - { - if (this.children.contains(gameObject)) + else if (typeof parent === 'object' && parent.nodeType === 1) { - gameObject.setActive(false); - gameObject.setVisible(false); + // Quick test for a HTMLElement + target = parent; } - }, + } + else if (element.parentElement || parent === null) + { + return element; + } - /** - * Sets the visible of each group member. - * - * @method Phaser.GameObjects.Group#setVisible - * @since 3.21.0 - * - * @param {boolean} value - The value to set the property to. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {this} This Group object. - */ - setVisible: function (value, index, direction) + // Fallback, covers an invalid ID and a non HTMLElement object + if (!target) { - Actions.SetVisible(this.children.entries, value, index, direction); + target = document.body; + } - return this; - }, + target.appendChild(element); - /** - * Toggles (flips) the visible state of each member of this group. - * - * @method Phaser.GameObjects.Group#toggleVisible - * @since 3.0.0 - * - * @return {this} This Group object. - */ - toggleVisible: function () - { - Actions.ToggleVisible(this.children.entries); + return element; +}; - return this; - }, +module.exports = AddToDOM; - /** - * Empties this Group of all children and removes it from the Scene. - * - * Does not call {@link Phaser.GameObjects.Group#removeCallback}. - * - * Children of this Group will _not_ be removed from the Scene by calling this method - * unless you specify the `removeFromScene` parameter. - * - * Children of this Group will also _not_ be destroyed by calling this method - * unless you specify the `destroyChildren` parameter. - * - * @method Phaser.GameObjects.Group#destroy - * @since 3.0.0 - * - * @param {boolean} [destroyChildren=false] - Also {@link Phaser.GameObjects.GameObject#destroy} each Group member. - * @param {boolean} [removeFromScene=false] - Optionally remove each Group member from the Scene. - */ - destroy: function (destroyChildren, removeFromScene) - { - if (destroyChildren === undefined) { destroyChildren = false; } - if (removeFromScene === undefined) { removeFromScene = false; } - // This Game Object had already been destroyed - if (!this.scene || this.ignoreDestroy) - { - return; - } +/***/ }), - this.emit(Events.DESTROY, this); +/***/ 85178: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.removeAllListeners(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.scene.sys.updateList.remove(this); +var AddToDOM = __webpack_require__(99584); - this.clear(removeFromScene, destroyChildren); +var CreateDOMContainer = function (game) +{ + var config = game.config; - this.scene = undefined; - this.children = undefined; + if (!config.parent || !config.domCreateContainer) + { + return; } -}); + // DOM Element Container + var div = document.createElement('div'); -module.exports = Group; + div.style.cssText = [ + 'display: block;', + 'width: ' + game.scale.width + 'px;', + 'height: ' + game.scale.height + 'px;', + 'padding: 0; margin: 0;', + 'position: absolute;', + 'overflow: hidden;', + 'pointer-events: ' + config.domPointerEvents + ';', + 'transform: scale(1);', + 'transform-origin: left top;' + ].join(' '); + + game.domContainer = div; + + AddToDOM(div, config.parent); +}; + +module.exports = CreateDOMContainer; /***/ }), -/* 114 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 21546: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Utils = __webpack_require__(12); +var OS = __webpack_require__(36580); /** - * Renders a filled path for the given Shape. + * @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. * - * @method Phaser.GameObjects.Shape#FillPathWebGL - * @since 3.13.0 - * @private + * @function Phaser.DOM.DOMContentLoaded + * @since 3.0.0 * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The WebGL Pipeline used to render this Shape. - * @param {Phaser.GameObjects.Components.TransformMatrix} calcMatrix - The transform matrix used to get the position values. - * @param {Phaser.GameObjects.Shape} src - The Game Object shape being rendered in this call. - * @param {number} alpha - The base alpha value. - * @param {number} dx - The source displayOriginX. - * @param {number} dy - The source displayOriginY. + * @param {ContentLoadedCallback} callback - The callback to be invoked when the device is ready and the DOM content is loaded. */ -var FillPathWebGL = function (pipeline, calcMatrix, src, alpha, dx, dy) +var DOMContentLoaded = function (callback) { - var fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha); + if (document.readyState === 'complete' || document.readyState === 'interactive') + { + callback(); - var path = src.pathData; - var pathIndexes = src.pathIndexes; + return; + } - for (var i = 0; i < pathIndexes.length; i += 3) + var check = function () { - var p0 = pathIndexes[i] * 2; - var p1 = pathIndexes[i + 1] * 2; - var p2 = pathIndexes[i + 2] * 2; + document.removeEventListener('deviceready', check, true); + document.removeEventListener('DOMContentLoaded', check, true); + window.removeEventListener('load', check, true); - var x0 = path[p0 + 0] - dx; - var y0 = path[p0 + 1] - dy; - var x1 = path[p1 + 0] - dx; - var y1 = path[p1 + 1] - dy; - var x2 = path[p2 + 0] - dx; - var y2 = path[p2 + 1] - dy; + callback(); + }; - var tx0 = calcMatrix.getX(x0, y0); - var ty0 = calcMatrix.getY(x0, y0); + 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); + } +}; - var tx1 = calcMatrix.getX(x1, y1); - var ty1 = calcMatrix.getY(x1, y1); +module.exports = DOMContentLoaded; - var tx2 = calcMatrix.getX(x2, y2); - var ty2 = calcMatrix.getY(x2, y2); - pipeline.batchTri(src, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, 2); +/***/ }), + +/***/ 74181: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 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 = FillPathWebGL; +module.exports = GetInnerHeight; /***/ }), -/* 115 */ -/***/ (function(module, exports) { + +/***/ 9229: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// http://www.blackpawn.com/texts/pointinpoly/ +var CONST = __webpack_require__(55301); /** - * Checks if a point (as a pair of coordinates) is inside a Triangle's bounds. + * Attempts to determine the screen orientation using the Orientation API. * - * @function Phaser.Geom.Triangle.Contains - * @since 3.0.0 + * @function Phaser.DOM.GetScreenOrientation + * @since 3.16.0 * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to check. - * @param {number} x - The X coordinate of the point to check. - * @param {number} y - The Y coordinate of the point to check. + * @param {number} width - The width of the viewport. + * @param {number} height - The height of the viewport. * - * @return {boolean} `true` if the point is inside the Triangle, otherwise `false`. + * @return {string} The orientation. */ -var Contains = function (triangle, x, y) +var GetScreenOrientation = function (width, height) { - var v0x = triangle.x3 - triangle.x1; - var v0y = triangle.y3 - triangle.y1; + var screen = window.screen; + var orientation = (screen) ? screen.orientation || screen.mozOrientation || screen.msOrientation : false; - var v1x = triangle.x2 - triangle.x1; - var v1y = triangle.y2 - triangle.y1; + 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; + } - var v2x = x - triangle.x1; - var v2y = y - triangle.y1; + 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; + } +}; - var dot00 = (v0x * v0x) + (v0y * v0y); - var dot01 = (v0x * v1x) + (v0y * v1y); - var dot02 = (v0x * v2x) + (v0y * v2y); - var dot11 = (v1x * v1x) + (v1y * v1y); - var dot12 = (v1x * v2x) + (v1y * v2y); +module.exports = GetScreenOrientation; - // Compute barycentric coordinates - var b = ((dot00 * dot11) - (dot01 * dot01)); - var inv = (b === 0) ? 0 : (1 / b); - var u = ((dot11 * dot02) - (dot01 * dot12)) * inv; - var v = ((dot00 * dot12) - (dot01 * dot02)) * inv; - return (u >= 0 && v >= 0 && (u + v < 1)); +/***/ }), + +/***/ 2893: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 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 = Contains; +module.exports = GetTarget; /***/ }), -/* 116 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 89200: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Rectangle = __webpack_require__(10); -var Vector2 = __webpack_require__(3); - /** - * Returns the length of the line. + * 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. * - * @ignore - * @private + * @function Phaser.DOM.ParseXML + * @since 3.0.0 * - * @param {number} x1 - The x1 coordinate. - * @param {number} y1 - The y1 coordinate. - * @param {number} x2 - The x2 coordinate. - * @param {number} y2 - The y2 coordinate. + * @param {string} data - The XML source stored in a string. * - * @return {number} The length of the line. + * @return {?(DOMParser|ActiveXObject)} The parsed XML data, or `null` if the data could not be parsed. */ -function GetLength (x1, y1, x2, y2) +var ParseXML = function (data) { - var x = x1 - x2; - var y = y1 - y2; - var magnitude = (x * x) + (y * y); + var xml = ''; - return Math.sqrt(magnitude); -} + 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; + + +/***/ }), + +/***/ 55638: +/***/ ((module) => { /** - * @classdesc - * A Face Geometry Object. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Attempts to remove the element from its parentNode in the DOM. * - * A Face is used by the Mesh Game Object. A Mesh consists of one, or more, faces that are - * used to render the Mesh Game Objects in WebGL. + * @function Phaser.DOM.RemoveFromDOM + * @since 3.0.0 * - * A Face consists of 3 Vertex instances, for the 3 corners of the face and methods to help - * you modify and test them. + * @param {HTMLElement} element - The DOM element to remove from its parent node. + */ +var RemoveFromDOM = function (element) +{ + if (element.parentNode) + { + element.parentNode.removeChild(element); + } +}; + +module.exports = RemoveFromDOM; + + +/***/ }), + +/***/ 27385: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var NOOP = __webpack_require__(72283); + +/** + * @classdesc + * Abstracts away the use of RAF or setTimeOut for the core game update loop. * - * @class Face - * @memberof Phaser.Geom.Mesh - * @constructor - * @since 3.50.0 + * This is invoked automatically by the Phaser.Game instance. * - * @param {Phaser.Geom.Mesh.Vertex} vertex1 - The first vertex of the Face. - * @param {Phaser.Geom.Mesh.Vertex} vertex2 - The second vertex of the Face. - * @param {Phaser.Geom.Mesh.Vertex} vertex3 - The third vertex of the Face. + * @class RequestAnimationFrame + * @memberof Phaser.DOM + * @constructor + * @since 3.0.0 */ -var Face = new Class({ +var RequestAnimationFrame = new Class({ initialize: - function Face (vertex1, vertex2, vertex3) + function RequestAnimationFrame () { /** - * The first vertex in this Face. + * True if RequestAnimationFrame is running, otherwise false. * - * @name Phaser.Geom.Mesh.Face#vertex1 - * @type {Phaser.Geom.Mesh.Vertex} - * @since 3.50.0 + * @name Phaser.DOM.RequestAnimationFrame#isRunning + * @type {boolean} + * @default false + * @since 3.0.0 */ - this.vertex1 = vertex1; + this.isRunning = false; /** - * The second vertex in this Face. + * The callback to be invoked each step. * - * @name Phaser.Geom.Mesh.Face#vertex2 - * @type {Phaser.Geom.Mesh.Vertex} - * @since 3.50.0 + * @name Phaser.DOM.RequestAnimationFrame#callback + * @type {FrameRequestCallback} + * @since 3.0.0 */ - this.vertex2 = vertex2; + this.callback = NOOP; /** - * The third vertex in this Face. + * True if the step is using setTimeout instead of RAF. * - * @name Phaser.Geom.Mesh.Face#vertex3 - * @type {Phaser.Geom.Mesh.Vertex} - * @since 3.50.0 + * @name Phaser.DOM.RequestAnimationFrame#isSetTimeOut + * @type {boolean} + * @default false + * @since 3.0.0 */ - this.vertex3 = vertex3; + this.isSetTimeOut = false; /** - * The bounds of this Face. + * The setTimeout or RAF callback ID used when canceling them. * - * Be sure to call the `Face.updateBounds` method _before_ using this property. + * @name Phaser.DOM.RequestAnimationFrame#timeOutID + * @type {?number} + * @default null + * @since 3.0.0 + */ + this.timeOutID = null; + + /** + * The delay rate in ms for setTimeOut. * - * @name Phaser.Geom.Mesh.Face#bounds - * @type {Phaser.Geom.Rectangle} - * @since 3.50.0 + * @name Phaser.DOM.RequestAnimationFrame#delay + * @type {number} + * @default 0 + * @since 3.60.0 */ - this.bounds = new Rectangle(); + this.delay = 0; + + var _this = this; /** - * The face inCenter. Do not access directly, instead use the `getInCenter` method. + * The RAF step function. * - * @name Phaser.Geom.Mesh.Face#_inCenter - * @type {Phaser.Math.Vector2} - * @private - * @since 3.50.0 + * Invokes the callback and schedules another call to requestAnimationFrame. + * + * @name Phaser.DOM.RequestAnimationFrame#step + * @type {FrameRequestCallback} + * @since 3.0.0 + * + * @param {number} time - The timestamp passed in from RequestAnimationFrame. */ - this._inCenter = new Vector2(); + this.step = function step (time) + { + _this.callback(time); + + if (_this.isRunning) + { + _this.timeOutID = window.requestAnimationFrame(step); + } + }; + + /** + * The SetTimeout step function. + * + * Invokes the callback and schedules another call to setTimeout. + * + * @name Phaser.DOM.RequestAnimationFrame#stepTimeout + * @type {function} + * @since 3.0.0 + */ + this.stepTimeout = function stepTimeout () + { + if (_this.isRunning) + { + // Make the next request before the callback, so that timing is maintained + _this.timeOutID = window.setTimeout(stepTimeout, _this.delay); + } + + _this.callback(window.performance.now()); + }; }, /** - * Calculates and returns the in-center position of this Face. - * - * @method Phaser.Geom.Mesh.Face#getInCenter - * @since 3.50.0 + * Starts the requestAnimationFrame or setTimeout process running. * - * @param {boolean} [local=true] Return the in center from the un-transformed vertex positions (`true`), or transformed? (`false`) + * @method Phaser.DOM.RequestAnimationFrame#start + * @since 3.0.0 * - * @return {Phaser.Math.Vector2} A Vector2 containing the in center position of this Face. + * @param {FrameRequestCallback} callback - The callback to invoke each step. + * @param {boolean} forceSetTimeOut - Should it use SetTimeout, even if RAF is available? + * @param {number} delay - The setTimeout delay rate in ms. */ - getInCenter: function (local) + start: function (callback, forceSetTimeOut, delay) { - if (local === undefined) { local = true; } + if (this.isRunning) + { + return; + } - var v1 = this.vertex1; - var v2 = this.vertex2; - var v3 = this.vertex3; + this.callback = callback; - var v1x; - var v1y; + this.isSetTimeOut = forceSetTimeOut; - var v2x; - var v2y; + this.delay = delay; - var v3x; - var v3y; + this.isRunning = true; - if (local) - { - v1x = v1.x; - v1y = v1.y; + this.timeOutID = (forceSetTimeOut) ? window.setTimeout(this.stepTimeout, 0) : window.requestAnimationFrame(this.step); + }, - v2x = v2.x; - v2y = v2.y; + /** + * Stops the requestAnimationFrame or setTimeout from running. + * + * @method Phaser.DOM.RequestAnimationFrame#stop + * @since 3.0.0 + */ + stop: function () + { + this.isRunning = false; - v3x = v3.x; - v3y = v3.y; + if (this.isSetTimeOut) + { + clearTimeout(this.timeOutID); } else { - v1x = v1.vx; - v1y = v1.vy; - - v2x = v2.vx; - v2y = v2.vy; - - v3x = v3.vx; - v3y = v3.vy; + window.cancelAnimationFrame(this.timeOutID); } - - var d1 = GetLength(v3x, v3y, v2x, v2y); - var d2 = GetLength(v1x, v1y, v3x, v3y); - var d3 = GetLength(v2x, v2y, v1x, v1y); - - var p = d1 + d2 + d3; - - return this._inCenter.set( - (v1x * d1 + v2x * d2 + v3x * d3) / p, - (v1y * d1 + v2y * d2 + v3y * d3) / p - ); }, /** - * Checks if the given coordinates are within this Face. - * - * You can optionally provide a transform matrix. If given, the Face vertices - * will be transformed first, before being checked against the coordinates. - * - * @method Phaser.Geom.Mesh.Face#contains - * @since 3.50.0 - * - * @param {number} x - The horizontal position to check. - * @param {number} y - The vertical position to check. - * @param {Phaser.GameObjects.Components.TransformMatrix} [calcMatrix] - Optional transform matrix to apply to the vertices before comparison. + * Stops the step from running and clears the callback reference. * - * @return {boolean} `true` if the coordinates lay within this Face, otherwise `false`. + * @method Phaser.DOM.RequestAnimationFrame#destroy + * @since 3.0.0 */ - contains: function (x, y, calcMatrix) + destroy: function () { - var vertex1 = this.vertex1; - var vertex2 = this.vertex2; - var vertex3 = this.vertex3; + this.stop(); - var v1x = vertex1.vx; - var v1y = vertex1.vy; + this.callback = NOOP; + } - var v2x = vertex2.vx; - var v2y = vertex2.vy; +}); - var v3x = vertex3.vx; - var v3y = vertex3.vy; +module.exports = RequestAnimationFrame; - if (calcMatrix) - { - var a = calcMatrix.a; - var b = calcMatrix.b; - var c = calcMatrix.c; - var d = calcMatrix.d; - var e = calcMatrix.e; - var f = calcMatrix.f; - v1x = vertex1.vx * a + vertex1.vy * c + e; - v1y = vertex1.vx * b + vertex1.vy * d + f; +/***/ }), - v2x = vertex2.vx * a + vertex2.vy * c + e; - v2y = vertex2.vx * b + vertex2.vy * d + f; +/***/ 3590: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - v3x = vertex3.vx * a + vertex3.vy * c + e; - v3y = vertex3.vx * b + vertex3.vy * d + f; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var t0x = v3x - v1x; - var t0y = v3y - v1y; +/** + * @namespace Phaser.DOM + */ - var t1x = v2x - v1x; - var t1y = v2y - v1y; +var Dom = { - var t2x = x - v1x; - var t2y = y - v1y; + AddToDOM: __webpack_require__(99584), + DOMContentLoaded: __webpack_require__(21546), + GetInnerHeight: __webpack_require__(74181), + GetScreenOrientation: __webpack_require__(9229), + GetTarget: __webpack_require__(2893), + ParseXML: __webpack_require__(89200), + RemoveFromDOM: __webpack_require__(55638), + RequestAnimationFrame: __webpack_require__(27385) - var dot00 = (t0x * t0x) + (t0y * t0y); - var dot01 = (t0x * t1x) + (t0y * t1y); - var dot02 = (t0x * t2x) + (t0y * t2y); - var dot11 = (t1x * t1x) + (t1y * t1y); - var dot12 = (t1x * t2x) + (t1y * t2y); +}; - // Compute barycentric coordinates - var bc = ((dot00 * dot11) - (dot01 * dot01)); - var inv = (bc === 0) ? 0 : (1 / bc); - var u = ((dot11 * dot02) - (dot01 * dot12)) * inv; - var v = ((dot00 * dot12) - (dot01 * dot02)) * inv; +module.exports = Dom; - return (u >= 0 && v >= 0 && (u + v < 1)); - }, - /** - * Checks if the vertices in this Face are orientated counter-clockwise, or not. - * - * It checks the transformed position of the vertices, not the local one. - * - * @method Phaser.Geom.Mesh.Face#isCounterClockwise - * @since 3.50.0 - * - * @param {number} z - The z-axis value to test against. Typically the `Mesh.modelPosition.z`. - * - * @return {boolean} `true` if the vertices in this Face run counter-clockwise, otherwise `false`. - */ - isCounterClockwise: function (z) - { - var v1 = this.vertex1; - var v2 = this.vertex2; - var v3 = this.vertex3; +/***/ }), - var d = (v2.vx - v1.vx) * (v3.vy - v1.vy) - (v2.vy - v1.vy) * (v3.vx - v1.vx); +/***/ 78491: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return (z <= 0) ? d >= 0 : d < 0; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Loads the data from this Vertex into the given Typed Arrays. - * - * @method Phaser.Geom.Mesh.Face#load - * @since 3.50.0 - * - * @param {Float32Array} F32 - A Float32 Array to insert the position, UV and unit data in to. - * @param {Uint32Array} U32 - A Uint32 Array to insert the color and alpha data in to. - * @param {number} offset - The index of the array to insert this Vertex to. - * @param {number} textureUnit - The texture unit currently in use. - * @param {number} tintEffect - The tint effect to use. - * - * @return {number} The new vertex index array offset. - */ - load: function (F32, U32, offset, textureUnit, tintEffect) - { - offset = this.vertex1.load(F32, U32, offset, textureUnit, tintEffect); - offset = this.vertex2.load(F32, U32, offset, textureUnit, tintEffect); - offset = this.vertex3.load(F32, U32, offset, textureUnit, tintEffect); +var Class = __webpack_require__(56694); +var EE = __webpack_require__(6659); +var PluginCache = __webpack_require__(91963); - return offset; - }, +/** + * @classdesc + * EventEmitter is a Scene Systems plugin compatible version of eventemitter3. + * + * @class EventEmitter + * @memberof Phaser.Events + * @constructor + * @since 3.0.0 + */ +var EventEmitter = new Class({ - /** - * Transforms all Face vertices by the given matrix, storing the results in their `vx`, `vy` and `vz` properties. - * - * @method Phaser.Geom.Mesh.Face#transformCoordinatesLocal - * @since 3.50.0 - * - * @param {Phaser.Math.Matrix4} transformMatrix - The transform matrix to apply to this vertex. - * @param {number} width - The width of the parent Mesh. - * @param {number} height - The height of the parent Mesh. - * @param {number} cameraZ - The z position of the MeshCamera. - * - * @return {this} This Face instance. - */ - transformCoordinatesLocal: function (transformMatrix, width, height, cameraZ) - { - this.vertex1.transformCoordinatesLocal(transformMatrix, width, height, cameraZ); - this.vertex2.transformCoordinatesLocal(transformMatrix, width, height, cameraZ); - this.vertex3.transformCoordinatesLocal(transformMatrix, width, height, cameraZ); + Extends: EE, - return this; + initialize: + + function EventEmitter () + { + EE.call(this); }, /** - * Updates the bounds of this Face, based on the translated values of the vertices. - * - * Call this method prior to accessing the `Face.bounds` property. - * - * @method Phaser.Geom.Mesh.Face#updateBounds - * @since 3.50.0 + * Removes all listeners. * - * @return {this} This Face instance. + * @method Phaser.Events.EventEmitter#shutdown + * @since 3.0.0 */ - updateBounds: function () + shutdown: function () { - var v1 = this.vertex1; - var v2 = this.vertex2; - var v3 = this.vertex3; - - var bounds = this.bounds; - - bounds.x = Math.min(v1.vx, v2.vx, v3.vx); - bounds.y = Math.min(v1.vy, v2.vy, v3.vy); - bounds.width = Math.max(v1.vx, v2.vx, v3.vx) - bounds.x; - bounds.height = Math.max(v1.vy, v2.vy, v3.vy) - bounds.y; - - return this; + this.removeAllListeners(); }, /** - * Checks if this Face is within the view of the given Camera. - * - * This method is called in the `MeshWebGLRenderer` function. It performs the following tasks: - * - * First, the `Vertex.update` method is called on each of the vertices. This populates them - * with the new translated values, updating their `tx`, `ty` and `ta` properties. - * - * Then it tests to see if this face is visible due to the alpha values, if not, it returns. - * - * After this, if `hideCCW` is set, it calls `isCounterClockwise` and returns if not. - * - * Finally, it will update the `Face.bounds` based on the newly translated vertex values - * and return the results of an intersection test between the bounds and the camera world view - * rectangle. - * - * @method Phaser.Geom.Mesh.Face#isInView - * @since 3.50.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against. - * @param {boolean} hideCCW - Test the counter-clockwise orientation of the verts? - * @param {number} z - The Cameras z position, used in the CCW test. - * @param {number} alpha - The alpha of the parent object. - * @param {number} a - The parent transform matrix data a component. - * @param {number} b - The parent transform matrix data b component. - * @param {number} c - The parent transform matrix data c component. - * @param {number} d - The parent transform matrix data d component. - * @param {number} e - The parent transform matrix data e component. - * @param {number} f - The parent transform matrix data f component. - * @param {boolean} roundPixels - Round the vertex position or not? + * Removes all listeners. * - * @return {boolean} `true` if this Face can be seen by the Camera. + * @method Phaser.Events.EventEmitter#destroy + * @since 3.0.0 */ - isInView: function (camera, hideCCW, z, alpha, a, b, c, d, e, f, roundPixels) + destroy: function () { - var v1 = this.vertex1.update(a, b, c, d, e, f, roundPixels, alpha); - var v2 = this.vertex2.update(a, b, c, d, e, f, roundPixels, alpha); - var v3 = this.vertex3.update(a, b, c, d, e, f, roundPixels, alpha); + this.removeAllListeners(); + } - // Alpha check first - if (v1.ta <= 0 && v2.ta <= 0 && v3.ta <= 0) - { - return false; - } +}); - // CCW check - if (hideCCW && !this.isCounterClockwise(z)) - { - return false; - } +/** + * Return an array listing the events for which the emitter has registered listeners. + * + * @method Phaser.Events.EventEmitter#eventNames + * @since 3.0.0 + * + * @return {Array.} + */ - // Bounds check - var bounds = this.bounds; +/** + * Return the listeners registered for a given event. + * + * @method Phaser.Events.EventEmitter#listeners + * @since 3.0.0 + * + * @param {(string|symbol)} event - The event name. + * + * @return {Function[]} The registered listeners. + */ - bounds.x = Math.min(v1.tx, v2.tx, v3.tx); - bounds.y = Math.min(v1.ty, v2.ty, v3.ty); - bounds.width = Math.max(v1.tx, v2.tx, v3.tx) - bounds.x; - bounds.height = Math.max(v1.ty, v2.ty, v3.ty) - bounds.y; +/** + * Return the number of listeners listening to a given event. + * + * @method Phaser.Events.EventEmitter#listenerCount + * @since 3.0.0 + * + * @param {(string|symbol)} event - The event name. + * + * @return {number} The number of listeners. + */ - var cr = camera.x + camera.width; - var cb = camera.y + camera.height; +/** + * Calls each of the listeners registered for a given event. + * + * @method Phaser.Events.EventEmitter#emit + * @since 3.0.0 + * + * @param {(string|symbol)} event - The event name. + * @param {...*} [args] - Additional arguments that will be passed to the event handler. + * + * @return {boolean} `true` if the event had listeners, else `false`. + */ - if (bounds.width <= 0 || bounds.height <= 0 || camera.width <= 0 || camera.height <= 0) - { - return false; - } +/** + * Add a listener for a given event. + * + * @method Phaser.Events.EventEmitter#on + * @since 3.0.0 + * + * @param {(string|symbol)} event - The event name. + * @param {function} fn - The listener function. + * @param {*} [context=this] - The context to invoke the listener with. + * + * @return {this} `this`. + */ - return !(bounds.right < camera.x || bounds.bottom < camera.y || bounds.x > cr || bounds.y > cb); - }, +/** + * Add a listener for a given event. + * + * @method Phaser.Events.EventEmitter#addListener + * @since 3.0.0 + * + * @param {(string|symbol)} event - The event name. + * @param {function} fn - The listener function. + * @param {*} [context=this] - The context to invoke the listener with. + * + * @return {this} `this`. + */ - /** - * Translates the vertices of this Face by the given amounts. - * - * The actual vertex positions are adjusted, not their transformed position. - * - * Therefore, this updates the vertex data directly. - * - * @method Phaser.Geom.Mesh.Face#translate - * @since 3.50.0 - * - * @param {number} x - The amount to horizontally translate by. - * @param {number} [y=0] - The amount to vertically translate by. - * - * @return {this} This Face instance. - */ - translate: function (x, y) +/** + * Add a one-time listener for a given event. + * + * @method Phaser.Events.EventEmitter#once + * @since 3.0.0 + * + * @param {(string|symbol)} event - The event name. + * @param {function} fn - The listener function. + * @param {*} [context=this] - The context to invoke the listener with. + * + * @return {this} `this`. + */ + +/** + * Remove the listeners of a given event. + * + * @method Phaser.Events.EventEmitter#removeListener + * @since 3.0.0 + * + * @param {(string|symbol)} event - The event name. + * @param {function} [fn] - Only remove the listeners that match this function. + * @param {*} [context] - Only remove the listeners that have this context. + * @param {boolean} [once] - Only remove one-time listeners. + * + * @return {this} `this`. + */ + +/** + * Remove the listeners of a given event. + * + * @method Phaser.Events.EventEmitter#off + * @since 3.0.0 + * + * @param {(string|symbol)} event - The event name. + * @param {function} [fn] - Only remove the listeners that match this function. + * @param {*} [context] - Only remove the listeners that have this context. + * @param {boolean} [once] - Only remove one-time listeners. + * + * @return {this} `this`. + */ + +/** + * Remove all listeners, or those of the specified event. + * + * @method Phaser.Events.EventEmitter#removeAllListeners + * @since 3.0.0 + * + * @param {(string|symbol)} [event] - The event name. + * + * @return {this} `this`. + */ + +PluginCache.register('EventEmitter', EventEmitter, 'events'); + +module.exports = EventEmitter; + + +/***/ }), + +/***/ 95146: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Events + */ + +module.exports = { EventEmitter: __webpack_require__(78491) }; + + +/***/ }), + +/***/ 20170: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); + +/** + * @classdesc + * The Barrel FX Controller. + * + * This FX controller manages the barrel distortion effect for a Game Object. + * + * A barrel effect allows you to apply either a 'pinch' or 'expand' distortion to + * a Game Object. The amount of the effect can be modified in real-time. + * + * A Barrel effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addBarrel(); + * sprite.postFX.addBarrel(); + * ``` + * + * @class Barrel + * @extends Phaser.FX.Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [amount=1] - The amount of distortion applied to the barrel effect. A value of 1 is no distortion. Typically keep this within +- 1. + */ +var Barrel = new Class({ + + Extends: Controller, + + initialize: + + function Barrel (gameObject, amount) { - if (y === undefined) { y = 0; } + if (amount === undefined) { amount = 1; } - var v1 = this.vertex1; - var v2 = this.vertex2; - var v3 = this.vertex3; + Controller.call(this, FX_CONST.BARREL, gameObject); - v1.x += x; - v1.y += y; + /** + * The amount of distortion applied to the barrel effect. + * + * Typically keep this within the range 1 (no distortion) to +- 1. + * + * @name Phaser.FX.Barrel#amount + * @type {number} + * @since 3.60.0 + */ + this.amount = amount; + } - v2.x += x; - v2.y += y; +}); - v3.x += x; - v3.y += y; +module.exports = Barrel; - return this; - }, - /** - * The x coordinate of this Face, based on the in center position of the Face. - * - * @name Phaser.Geom.Mesh.Face#x - * @type {number} - * @since 3.50.0 - */ - x: { +/***/ }), - get: function () - { - return this.getInCenter().x; - }, +/***/ 51182: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - set: function (value) - { - var current = this.getInCenter(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.translate(value - current.x, 0); - } +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); + +/** + * @classdesc + * The Bloom FX Controller. + * + * This FX controller manages the bloom effect for a Game Object. + * + * Bloom is an effect used to reproduce an imaging artifact of real-world cameras. + * The effect produces fringes of light extending from the borders of bright areas in an image, + * contributing to the illusion of an extremely bright light overwhelming the + * camera or eye capturing the scene. + * + * A Bloom effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addBloom(); + * sprite.postFX.addBloom(); + * ``` + * + * @class Bloom + * @extends Phaser.FX.Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [color=0xffffff] - The color of the Bloom, as a hex value. + * @param {number} [offsetX=1] - The horizontal offset of the bloom effect. + * @param {number} [offsetY=1] - The vertical offset of the bloom effect. + * @param {number} [blurStrength=1] - The strength of the blur process of the bloom effect. + * @param {number} [strength=1] - The strength of the blend process of the bloom effect. + * @param {number} [steps=4] - The number of steps to run the Bloom effect for. This value should always be an integer. + */ +var Bloom = new Class({ + + Extends: Controller, + + initialize: + + function Bloom (gameObject, color, offsetX, offsetY, blurStrength, strength, steps) + { + if (offsetX === undefined) { offsetX = 1; } + if (offsetY === undefined) { offsetY = 1; } + if (blurStrength === undefined) { blurStrength = 1; } + if (strength === undefined) { strength = 1; } + if (steps === undefined) { steps = 4; } + + Controller.call(this, FX_CONST.BLOOM, gameObject); + + /** + * The number of steps to run the Bloom effect for. + * + * This value should always be an integer. + * + * It defaults to 4. The higher the value, the smoother the Bloom, + * but at the cost of exponentially more gl operations. + * + * Keep this to the lowest possible number you can have it, while + * still looking correct for your game. + * + * @name Phaser.FX.Bloom#steps + * @type {number} + * @since 3.60.0 + */ + this.steps = steps; + + /** + * The horizontal offset of the bloom effect. + * + * @name Phaser.FX.Bloom#offsetX + * @type {number} + * @since 3.60.0 + */ + this.offsetX = offsetX; + + /** + * The vertical offset of the bloom effect. + * + * @name Phaser.FX.Bloom#offsetY + * @type {number} + * @since 3.60.0 + */ + this.offsetY = offsetY; + + /** + * The strength of the blur process of the bloom effect. + * + * @name Phaser.FX.Bloom#blurStrength + * @type {number} + * @since 3.60.0 + */ + this.blurStrength = blurStrength; + /** + * The strength of the blend process of the bloom effect. + * + * @name Phaser.FX.Bloom#strength + * @type {number} + * @since 3.60.0 + */ + this.strength = strength; + + /** + * The internal gl color array. + * + * @name Phaser.FX.Bloom#glcolor + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor = [ 1, 1, 1 ]; + + if (color !== undefined && color !== null) + { + this.color = color; + } }, /** - * The y coordinate of this Face, based on the in center position of the Face. + * The color of the bloom as a number value. * - * @name Phaser.Geom.Mesh.Face#y + * @name Phaser.FX.Bloom#color * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - y: { + color: { get: function () { - return this.getInCenter().y; + var color = this.glcolor; + + return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0)); }, set: function (value) { - var current = this.getInCenter(); + var color = this.glcolor; - this.translate(0, value - current.y); + color[0] = ((value >> 16) & 0xFF) / 255; + color[1] = ((value >> 8) & 0xFF) / 255; + color[2] = (value & 0xFF) / 255; } - }, + } - /** - * Set the alpha value of this Face. - * - * Each vertex is given the same value. If you need to adjust the alpha on a per-vertex basis - * then use the `Vertex.alpha` property instead. - * - * When getting the alpha of this Face, it will return an average of the alpha - * component of all three vertices. - * - * @name Phaser.Geom.Mesh.Face#alpha - * @type {number} - * @since 3.50.0 - */ - alpha: { +}); - get: function () - { - var v1 = this.vertex1; - var v2 = this.vertex2; - var v3 = this.vertex3; +module.exports = Bloom; - return (v1.alpha + v2.alpha + v3.alpha) / 3; - }, - set: function (value) +/***/ }), + +/***/ 51498: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); + +/** + * @classdesc + * The Blur FX Controller. + * + * This FX controller manages the blur effect for a Game Object. + * + * A Gaussian blur is the result of blurring an image by a Gaussian function. It is a widely used effect, + * typically to reduce image noise and reduce detail. The visual effect of this blurring technique is a + * smooth blur resembling that of viewing the image through a translucent screen, distinctly different + * from the bokeh effect produced by an out-of-focus lens or the shadow of an object under usual illumination. + * + * A Blur effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addBlur(); + * sprite.postFX.addBlur(); + * ``` + * + * @class Blur + * @extends Phaser.FX.Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [quality=0] - The quality of the blur effect. Can be either 0 for Low Quality, 1 for Medium Quality or 2 for High Quality. + * @param {number} [x=2] - The horizontal offset of the blur effect. + * @param {number} [y=2] - The vertical offset of the blur effect. + * @param {number} [strength=1] - The strength of the blur effect. + * @param {number} [color=0xffffff] - The color of the blur, as a hex value. + * @param {number} [steps=4] - The number of steps to run the blur effect for. This value should always be an integer. + */ +var Blur = new Class({ + + Extends: Controller, + + initialize: + + function Blur (gameObject, quality, x, y, strength, color, steps) + { + if (quality === undefined) { quality = 0; } + if (x === undefined) { x = 2; } + if (y === undefined) { y = 2; } + if (strength === undefined) { strength = 1; } + if (steps === undefined) { steps = 4; } + + Controller.call(this, FX_CONST.BLUR, gameObject); + + /** + * The quality of the blur effect. + * + * This can be: + * + * 0 for Low Quality + * 1 for Medium Quality + * 2 for High Quality + * + * The higher the quality, the more complex shader is used + * and the more processing time is spent on the GPU calculating + * the final blur. This value is used in conjunction with the + * `steps` value, as one has a direct impact on the other. + * + * Keep this value as low as you can, while still achieving the + * desired effect you need for your game. + * + * @name Phaser.FX.Blur#quality + * @type {number} + * @since 3.60.0 + */ + this.quality = 0; + + /** + * The horizontal offset of the blur effect. + * + * @name Phaser.FX.Blur#x + * @type {number} + * @since 3.60.0 + */ + this.x = x; + + /** + * The vertical offset of the blur effect. + * + * @name Phaser.FX.Blur#y + * @type {number} + * @since 3.60.0 + */ + this.y = y; + + /** + * The number of steps to run the Blur effect for. + * + * This value should always be an integer. + * + * It defaults to 4. The higher the value, the smoother the blur, + * but at the cost of exponentially more gl operations. + * + * Keep this to the lowest possible number you can have it, while + * still looking correct for your game. + * + * @name Phaser.FX.Blur#steps + * @type {number} + * @since 3.60.0 + */ + this.steps = steps; + + /** + * The strength of the blur effect. + * + * @name Phaser.FX.Blur#strength + * @type {number} + * @since 3.60.0 + */ + this.strength = strength; + + /** + * The internal gl color array. + * + * @name Phaser.FX.Blur#glcolor + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor = [ 1, 1, 1 ]; + + if (color !== undefined && color !== null) { - this.vertex1.alpha = value; - this.vertex2.alpha = value; - this.vertex3.alpha = value; + this.color = color; } - }, /** - * The depth of this Face, which is an average of the z component of all three vertices. + * The color of the blur as a number value. * - * The depth is calculated based on the transformed z value, not the local one. - * - * @name Phaser.Geom.Mesh.Face#depth + * @name Phaser.FX.Blur#color * @type {number} - * @readonly - * @since 3.50.0 + * @since 3.60.0 */ - depth: { + color: { get: function () { - var v1 = this.vertex1; - var v2 = this.vertex2; - var v3 = this.vertex3; + var color = this.glcolor; - return (v1.vz + v2.vz + v3.vz) / 3; - } + return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0)); + }, - }, + set: function (value) + { + var color = this.glcolor; + + color[0] = ((value >> 16) & 0xFF) / 255; + color[1] = ((value >> 8) & 0xFF) / 255; + color[2] = (value & 0xFF) / 255; + } - /** - * Destroys this Face and nulls the references to the vertices. - * - * @method Phaser.Geom.Mesh.Face#destroy - * @since 3.50.0 - */ - destroy: function () - { - this.vertex1 = null; - this.vertex2 = null; - this.vertex3 = null; } }); -module.exports = Face; +module.exports = Blur; /***/ }), -/* 117 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 12042: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Utils = __webpack_require__(12); -var Vector3 = __webpack_require__(39); +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); /** * @classdesc - * A Vertex Geometry Object. + * The Bokeh FX Controller. * - * This class consists of all the information required for a single vertex within a Face Geometry Object. + * This FX controller manages the bokeh effect for a Game Object. * - * Faces, and thus Vertex objects, are used by the Mesh Game Object in order to render objects in WebGL. + * Bokeh refers to a visual effect that mimics the photographic technique of creating a shallow depth of field. + * This effect is used to emphasize the game's main subject or action, by blurring the background or foreground + * elements, resulting in a more immersive and visually appealing experience. It is achieved through rendering + * techniques that simulate the out-of-focus areas, giving a sense of depth and realism to the game's graphics. * - * @class Vertex - * @memberof Phaser.Geom.Mesh + * This effect can also be used to generate a Tilt Shift effect, which is a technique used to create a miniature + * effect by blurring everything except a small area of the image. This effect is achieved by blurring the + * top and bottom elements, while keeping the center area in focus. + * + * A Bokeh effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addBokeh(); + * sprite.postFX.addBokeh(); + * ``` + * + * @class Bokeh + * @extends Phaser.FX.Controller + * @memberof Phaser.FX * @constructor - * @extends Phaser.Math.Vector3 - * @since 3.50.0 + * @since 3.60.0 * - * @param {number} x - The x position of the vertex. - * @param {number} y - The y position of the vertex. - * @param {number} z - The z position of the vertex. - * @param {number} u - The UV u coordinate of the vertex. - * @param {number} v - The UV v coordinate of the vertex. - * @param {number} [color=0xffffff] - The color value of the vertex. - * @param {number} [alpha=1] - The alpha value of the vertex. - * @param {number} [nx=0] - The x normal value of the vertex. - * @param {number} [ny=0] - The y normal value of the vertex. - * @param {number} [nz=0] - The z normal value of the vertex. + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [radius=0.5] - The radius of the bokeh effect. + * @param {number} [amount=1] - The amount of the bokeh effect. + * @param {number} [contrast=0.2] - The color contrast of the bokeh effect. + * @param {boolean} [isTiltShift=false] - Is this a bokeh or Tile Shift effect? + * @param {number} [blurX=1] - If Tilt Shift, the amount of horizontal blur. + * @param {number} [blurY=1] - If Tilt Shift, the amount of vertical blur. + * @param {number} [strength=1] - If Tilt Shift, the strength of the blur. */ -var Vertex = new Class({ +var Bokeh = new Class({ - Extends: Vector3, + Extends: Controller, initialize: - function Vertex (x, y, z, u, v, color, alpha, nx, ny, nz) + function Bokeh (gameObject, radius, amount, contrast, isTiltShift, blurX, blurY, strength) { - if (color === undefined) { color = 0xffffff; } - if (alpha === undefined) { alpha = 1; } - if (nx === undefined) { nx = 0; } - if (ny === undefined) { ny = 0; } - if (nz === undefined) { nz = 0; } + if (radius === undefined) { radius = 0.5; } + if (amount === undefined) { amount = 1; } + if (contrast === undefined) { contrast = 0.2; } + if (isTiltShift === undefined) { isTiltShift = false; } + if (blurX === undefined) { blurX = 1; } + if (blurY === undefined) { blurY = 1; } + if (strength === undefined) { strength = 1; } - Vector3.call(this, x, y, z); + Controller.call(this, FX_CONST.BOKEH, gameObject); /** - * The projected x coordinate of this vertex. + * The radius of the bokeh effect. * - * @name Phaser.Geom.Mesh.Vertex#vx - * @type {number} - * @since 3.50.0 - */ - this.vx = 0; - - /** - * The projected y coordinate of this vertex. + * This is a float value, where a radius of 0 will result in no effect being applied, + * and a radius of 1 will result in a strong bokeh. However, you can exceed this value + * for even stronger effects. * - * @name Phaser.Geom.Mesh.Vertex#vy + * @name Phaser.FX.Bokeh#radius * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.vy = 0; + this.radius = radius; /** - * The projected z coordinate of this vertex. + * The amount, or strength, of the bokeh effect. Defaults to 1. * - * @name Phaser.Geom.Mesh.Vertex#vz + * @name Phaser.FX.Bokeh#amount * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.vz = 0; + this.amount = amount; /** - * The projected x coordinate of this vertex. + * The color contrast, or brightness, of the bokeh effect. Defaults to 0.2. * - * @name Phaser.Geom.Mesh.Vertex#nx + * @name Phaser.FX.Bokeh#contrast * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.nx = nx; + this.contrast = contrast; /** - * The projected y coordinate of this vertex. + * Is this a Tilt Shift effect or a standard bokeh effect? * - * @name Phaser.Geom.Mesh.Vertex#ny - * @type {number} - * @since 3.50.0 + * @name Phaser.FX.Bokeh#isTiltShift + * @type {boolean} + * @since 3.60.0 */ - this.ny = ny; + this.isTiltShift = isTiltShift; /** - * The projected z coordinate of this vertex. + * If a Tilt Shift effect this controls the strength of the blur. * - * @name Phaser.Geom.Mesh.Vertex#nz + * Setting this value on a non-Tilt Shift effect will have no effect. + * + * @name Phaser.FX.Bokeh#strength * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.nz = nz; + this.strength = strength; /** - * UV u coordinate of this vertex. + * If a Tilt Shift effect this controls the amount of horizontal blur. * - * @name Phaser.Geom.Mesh.Vertex#u + * Setting this value on a non-Tilt Shift effect will have no effect. + * + * @name Phaser.FX.Bokeh#blurX * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.u = u; + this.blurX = blurX; /** - * UV v coordinate of this vertex. + * If a Tilt Shift effect this controls the amount of vertical blur. * - * @name Phaser.Geom.Mesh.Vertex#v + * Setting this value on a non-Tilt Shift effect will have no effect. + * + * @name Phaser.FX.Bokeh#blurY * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.v = v; + this.blurY = blurY; + } + +}); + +module.exports = Bokeh; + + +/***/ }), + +/***/ 69900: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); + +/** + * @classdesc + * The Circle FX Controller. + * + * This FX controller manages the circle effect for a Game Object. + * + * This effect will draw a circle around the texture of the Game Object, effectively masking off + * any area outside of the circle without the need for an actual mask. You can control the thickness + * of the circle, the color of the circle and the color of the background, should the texture be + * transparent. You can also control the feathering applied to the circle, allowing for a harsh or soft edge. + * + * Please note that adding this effect to a Game Object will not change the input area or physics body of + * the Game Object, should it have one. + * + * A Circle effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addCircle(); + * sprite.postFX.addCircle(); + * ``` + * + * @class Circle + * @extends Phaser.FX.Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [thickness=8] - The width of the circle around the texture, in pixels. + * @param {number} [color=0xfeedb6] - The color of the circular ring, given as a number value. + * @param {number} [backgroundColor=0xff0000] - The color of the background, behind the texture, given as a number value. + * @param {number} [scale=1] - The scale of the circle. The default scale is 1, which is a circle the full size of the underlying texture. + * @param {number} [feather=0.005] - The amount of feathering to apply to the circle from the ring. + */ +var Circle = new Class({ + + Extends: Controller, + + initialize: + + function Circle (gameObject, thickness, color, backgroundColor, scale, feather) + { + if (thickness === undefined) { thickness = 8; } + if (scale === undefined) { scale = 1; } + if (feather === undefined) { feather = 0.005; } + + Controller.call(this, FX_CONST.CIRCLE, gameObject); /** - * The color value of this vertex. + * The scale of the circle. The default scale is 1, which is a circle + * the full size of the underlying texture. Reduce this value to create + * a smaller circle, or increase it to create a circle that extends off + * the edges of the texture. * - * @name Phaser.Geom.Mesh.Vertex#color + * @name Phaser.FX.Circle#scale * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.color = color; + this.scale = scale; /** - * The alpha value of this vertex. + * The amount of feathering to apply to the circle from the ring, + * extending into the middle of the circle. The default is 0.005, + * which is a very low amount of feathering just making sure the ring + * has a smooth edge. Increase this amount to a value such as 0.5 + * or 0.025 for larger amounts of feathering. * - * @name Phaser.Geom.Mesh.Vertex#alpha + * @name Phaser.FX.Circle#feather * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.alpha = alpha; + this.feather = feather; /** - * The translated x coordinate of this vertex. + * The width of the circle around the texture, in pixels. This value + * doesn't factor in the feather, which can extend the thickness + * internally depending on its value. * - * @name Phaser.Geom.Mesh.Vertex#tx + * @name Phaser.FX.Circle#thickness * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.tx = 0; + this.thickness = thickness; /** - * The translated y coordinate of this vertex. + * The internal gl color array for the ring color. * - * @name Phaser.Geom.Mesh.Vertex#ty - * @type {number} - * @since 3.50.0 + * @name Phaser.FX.Circle#glcolor + * @type {number[]} + * @since 3.60.0 */ - this.ty = 0; + this.glcolor = [ 1, 0.2, 0.7 ]; /** - * The translated alpha value of this vertex. + * The internal gl color array for the background color. * - * @name Phaser.Geom.Mesh.Vertex#ta - * @type {number} - * @since 3.50.0 + * @name Phaser.FX.Circle#glcolor2 + * @type {number[]} + * @since 3.60.0 */ - this.ta = 0; + this.glcolor2 = [ 1, 0, 0, 0.4 ]; + + if (color !== undefined && color !== null) + { + this.color = color; + } + + if (backgroundColor !== undefined && backgroundColor !== null) + { + this.backgroundColor = backgroundColor; + } }, /** - * Sets the U and V properties. + * The color of the circular ring, given as a number value. * - * @method Phaser.Geom.Mesh.Vertex#setUVs - * @since 3.50.0 - * - * @param {number} u - The UV u coordinate of the vertex. - * @param {number} v - The UV v coordinate of the vertex. - * - * @return {this} This Vertex. + * @name Phaser.FX.Circle#color + * @type {number} + * @since 3.60.0 */ - setUVs: function (u, v) - { - this.u = u; - this.v = v; + color: { + + get: function () + { + var color = this.glcolor; + + return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0)); + }, + + set: function (value) + { + var color = this.glcolor; + + color[0] = ((value >> 16) & 0xFF) / 255; + color[1] = ((value >> 8) & 0xFF) / 255; + color[2] = (value & 0xFF) / 255; + } - return this; }, /** - * Transforms this vertex by the given matrix, storing the results in `vx`, `vy` and `vz`. - * - * @method Phaser.Geom.Mesh.Vertex#transformCoordinatesLocal - * @since 3.50.0 + * The color of the background, behind the texture, given as a number value. * - * @param {Phaser.Math.Matrix4} transformMatrix - The transform matrix to apply to this vertex. - * @param {number} width - The width of the parent Mesh. - * @param {number} height - The height of the parent Mesh. - * @param {number} cameraZ - The z position of the MeshCamera. + * @name Phaser.FX.Circle#backgroundColor + * @type {number} + * @since 3.60.0 */ - transformCoordinatesLocal: function (transformMatrix, width, height, cameraZ) - { - var x = this.x; - var y = this.y; - var z = this.z; - - var m = transformMatrix.val; + backgroundColor: { - var tx = (x * m[0]) + (y * m[4]) + (z * m[8]) + m[12]; - var ty = (x * m[1]) + (y * m[5]) + (z * m[9]) + m[13]; - var tz = (x * m[2]) + (y * m[6]) + (z * m[10]) + m[14]; - var tw = (x * m[3]) + (y * m[7]) + (z * m[11]) + m[15]; + get: function () + { + var color = this.glcolor2; - this.vx = (tx / tw) * width; - this.vy = -(ty / tw) * height; + return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0)); + }, - if (cameraZ <= 0) - { - this.vz = (tz / tw); - } - else + set: function (value) { - this.vz = -(tz / tw); + var color = this.glcolor2; + + color[0] = ((value >> 16) & 0xFF) / 255; + color[1] = ((value >> 8) & 0xFF) / 255; + color[2] = (value & 0xFF) / 255; } + + } + +}); + +module.exports = Circle; + + +/***/ }), + +/***/ 48991: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var BaseColorMatrix = __webpack_require__(65246); +var FX_CONST = __webpack_require__(47406); + +/** + * @classdesc + * The ColorMatrix FX Controller. + * + * This FX controller manages the color matrix effect for a Game Object. + * + * The color matrix effect is a visual technique that involves manipulating the colors of an image + * or scene using a mathematical matrix. This process can adjust hue, saturation, brightness, and contrast, + * allowing developers to create various stylistic appearances or mood settings within the game. + * Common applications include simulating different lighting conditions, applying color filters, + * or achieving a specific visual style. + * + * A ColorMatrix effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addColorMatrix(); + * sprite.postFX.addColorMatrix(); + * ``` + * + * @class ColorMatrix + * @extends Phaser.Display.ColorMatrix + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + */ +var ColorMatrix = new Class({ + + Extends: BaseColorMatrix, + + initialize: + + function ColorMatrix (gameObject) + { + BaseColorMatrix.call(this); + + /** + * The FX_CONST type of this effect. + * + * @name Phaser.FX.ColorMatrix#type + * @type {number} + * @since 3.60.0 + */ + this.type = FX_CONST.COLOR_MATRIX; + + /** + * A reference to the Game Object that owns this effect. + * + * @name Phaser.FX.ColorMatrix#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.60.0 + */ + this.gameObject = gameObject; + + /** + * Toggle this boolean to enable or disable this effect, + * without removing and adding it from the Game Object. + * + * @name Phaser.FX.ColorMatrix#active + * @type {boolean} + * @since 3.60.0 + */ + this.active = true; + }, + + destroy: function () + { + this.gameObject = null; + this._matrix = null; + this._data = null; + } + +}); + +module.exports = ColorMatrix; + + +/***/ }), + +/***/ 47551: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); + +/** + * @classdesc + * FX Controller is the base class that all built-in FX use. + * + * You should not normally create an instance of this class directly, but instead use one of the built-in FX that extend it. + * + * @class Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {number} type - The FX Type constant. + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + */ +var Controller = new Class({ + + initialize: + + function Controller (type, gameObject) + { + /** + * The FX_CONST type of this effect. + * + * @name Phaser.FX.Controller#type + * @type {number} + * @since 3.60.0 + */ + this.type = type; + + /** + * A reference to the Game Object that owns this effect. + * + * @name Phaser.FX.Controller#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.60.0 + */ + this.gameObject = gameObject; + + /** + * Toggle this boolean to enable or disable this effect, + * without removing and adding it from the Game Object. + * + * Only works for Pre FX. + * + * Post FX are always active. + * + * @name Phaser.FX.Controller#active + * @type {boolean} + * @since 3.60.0 + */ + this.active = true; }, /** - * Updates this Vertex based on the given transform. + * Sets the active state of this FX Controller. * - * @method Phaser.Geom.Mesh.Vertex#update - * @since 3.50.0 + * A disabled FX Controller will not be updated. * - * @param {number} a - The parent transform matrix data a component. - * @param {number} b - The parent transform matrix data b component. - * @param {number} c - The parent transform matrix data c component. - * @param {number} d - The parent transform matrix data d component. - * @param {number} e - The parent transform matrix data e component. - * @param {number} f - The parent transform matrix data f component. - * @param {boolean} roundPixels - Round the vertex position or not? - * @param {number} alpha - The alpha of the parent object. + * @method Phaser.FX.Controller#setActive + * @since 3.60.0 * - * @return {this} This Vertex. + * @param {boolean} value - `true` to enable this FX Controller, or `false` to disable it. + * + * @return {this} This FX Controller instance. */ - update: function (a, b, c, d, e, f, roundPixels, alpha) + setActive: function (value) { - var tx = this.vx * a + this.vy * c + e; - var ty = this.vx * b + this.vy * d + f; - - if (roundPixels) - { - tx = Math.round(tx); - ty = Math.round(ty); - } - - this.tx = tx; - this.ty = ty; - this.ta = this.alpha * alpha; + this.active = value; return this; }, /** - * Loads the data from this Vertex into the given Typed Arrays. - * - * @method Phaser.Geom.Mesh.Vertex#load - * @since 3.50.0 - * - * @param {Float32Array} F32 - A Float32 Array to insert the position, UV and unit data in to. - * @param {Uint32Array} U32 - A Uint32 Array to insert the color and alpha data in to. - * @param {number} offset - The index of the array to insert this Vertex to. - * @param {number} textureUnit - The texture unit currently in use. - * @param {number} tintEffect - The tint effect to use. + * Destroys this FX Controller. * - * @return {number} The new array offset. + * @method Phaser.FX.Controller#destroy + * @since 3.60.0 */ - load: function (F32, U32, offset, textureUnit, tintEffect) + destroy: function () { - F32[++offset] = this.tx; - F32[++offset] = this.ty; - F32[++offset] = this.u; - F32[++offset] = this.v; - F32[++offset] = textureUnit; - F32[++offset] = tintEffect; - U32[++offset] = Utils.getTintAppendFloatAlpha(this.color, this.ta); - - return offset; + this.gameObject = null; + this.active = false; } }); -module.exports = Vertex; +module.exports = Controller; /***/ }), -/* 118 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 47909: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** -* The `Matter.Composite` module contains methods for creating and manipulating composite bodies. -* A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure. -* It is important to use the functions in this module to modify composites, rather than directly modifying their properties. -* Note that the `Matter.World` object is also a type of `Matter.Composite` and as such all composite methods here can also operate on a `Matter.World`. -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Composite -*/ + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -var Composite = {}; +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); -module.exports = Composite; +/** + * @classdesc + * The Displacement FX Controller. + * + * This FX controller manages the displacement effect for a Game Object. + * + * The displacement effect is a visual technique that alters the position of pixels in an image + * or texture based on the values of a displacement map. This effect is used to create the illusion + * of depth, surface irregularities, or distortion in otherwise flat elements. It can be applied to + * characters, objects, or backgrounds to enhance realism, convey movement, or achieve various + * stylistic appearances. + * + * A Displacement effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addDisplacement(); + * sprite.postFX.addDisplacement(); + * ``` + * + * @class Displacement + * @extends Phaser.FX.Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {string} [texture='__WHITE'] - The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager. + * @param {number} [x=0.005] - The amount of horizontal displacement to apply. A very small float number, such as 0.005. + * @param {number} [y=0.005] - The amount of vertical displacement to apply. A very small float number, such as 0.005. + */ +var Displacement = new Class({ -var Events = __webpack_require__(166); -var Common = __webpack_require__(32); -var Bounds = __webpack_require__(84); -var Body = __webpack_require__(41); + Extends: Controller, -(function() { + initialize: - /** - * Creates a new composite. The options parameter is an object that specifies any properties you wish to override the defaults. - * See the properites section below for detailed information on what you can pass via the `options` object. - * @method create - * @param {} [options] - * @return {composite} A new composite - */ - Composite.create = function(options) { - return Common.extend({ - id: Common.nextId(), - type: 'composite', - parent: null, - isModified: false, - bodies: [], - constraints: [], - composites: [], - label: 'Composite', - plugin: {} - }, options); - }; + function Displacement (gameObject, texture, x, y) + { + if (texture === undefined) { texture = '__WHITE'; } + if (x === undefined) { x = 0.005; } + if (y === undefined) { y = 0.005; } - /** - * Sets the composite's `isModified` flag. - * If `updateParents` is true, all parents will be set (default: false). - * If `updateChildren` is true, all children will be set (default: false). - * @method setModified - * @param {composite} composite - * @param {boolean} isModified - * @param {boolean} [updateParents=false] - * @param {boolean} [updateChildren=false] - */ - Composite.setModified = function(composite, isModified, updateParents, updateChildren) { + Controller.call(this, FX_CONST.DISPLACEMENT, gameObject); - Events.trigger(composite, 'compositeModified', composite); + /** + * The amount of horizontal displacement to apply. + * + * @name Phaser.FX.Displacement#x + * @type {number} + * @since 3.60.0 + */ + this.x = x; - composite.isModified = isModified; + /** + * The amount of vertical displacement to apply. + * + * @name Phaser.FX.Displacement#y + * @type {number} + * @since 3.60.0 + */ + this.y = y; - if (updateParents && composite.parent) { - Composite.setModified(composite.parent, isModified, updateParents, updateChildren); - } + /** + * The underlying WebGLTexture used for displacement. + * + * @name Phaser.FX.Displacement#glTexture + * @type {WebGLTexture} + * @since 3.60.0 + */ + this.glTexture; - if (updateChildren) { - for(var i = 0; i < composite.composites.length; i++) { - var childComposite = composite.composites[i]; - Composite.setModified(childComposite, isModified, updateParents, updateChildren); - } - } - }; + this.setTexture(texture); + }, /** - * Generic add function. Adds one or many body(s), constraint(s) or a composite(s) to the given composite. - * Triggers `beforeAdd` and `afterAdd` events on the `composite`. - * @method add - * @param {composite} composite - * @param {} object - * @return {composite} The original composite with the objects added + * Sets the Texture to be used for the displacement effect. + * + * You can only use a whole texture, not a frame from a texture atlas or sprite sheet. + * + * @method Phaser.GameObjects.Components.FX#setTexture + * @since 3.60.0 + * + * @param {string} [texture='__WHITE'] - The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager. + * + * @return {this} This FX Controller. */ - Composite.add = function(composite, object) { - var objects = [].concat(object); + setTexture: function (texture) + { + var phaserTexture = this.gameObject.scene.sys.textures.getFrame(texture); - Events.trigger(composite, 'beforeAdd', { object: object }); + if (phaserTexture) + { + this.glTexture = phaserTexture.glTexture; + } - for (var i = 0; i < objects.length; i++) { - var obj = objects[i]; + return this; + } - switch (obj.type) { +}); - case 'body': - // skip adding compound parts - if (obj.parent !== obj) { - Common.warn('Composite.add: skipped adding a compound body part (you must add its parent instead)'); - break; - } +module.exports = Displacement; - Composite.addBody(composite, obj); - break; - case 'constraint': - Composite.addConstraint(composite, obj); - break; - case 'composite': - Composite.addComposite(composite, obj); - break; - case 'mouseConstraint': - Composite.addConstraint(composite, obj.constraint); - break; - } - } +/***/ }), - Events.trigger(composite, 'afterAdd', { object: object }); +/***/ 18919: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return composite; - }; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Generic remove function. Removes one or many body(s), constraint(s) or a composite(s) to the given composite. - * Optionally searching its children recursively. - * Triggers `beforeRemove` and `afterRemove` events on the `composite`. - * @method remove - * @param {composite} composite - * @param {} object - * @param {boolean} [deep=false] - * @return {composite} The original composite with the objects removed - */ - Composite.remove = function(composite, object, deep) { - var objects = [].concat(object); +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); - Events.trigger(composite, 'beforeRemove', { object: object }); +/** + * @classdesc + * The Glow FX Controller. + * + * This FX controller manages the glow effect for a Game Object. + * + * The glow effect is a visual technique that creates a soft, luminous halo around game objects, + * characters, or UI elements. This effect is used to emphasize importance, enhance visual appeal, + * or convey a sense of energy, magic, or otherworldly presence. The effect can also be set on + * the inside of the Game Object. The color and strength of the glow can be modified. + * + * A Glow effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addGlow(); + * sprite.postFX.addGlow(); + * ``` + * + * @class Glow + * @extends Phaser.FX.Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [color=0xffffff] - The color of the glow effect as a number value. + * @param {number} [outerStrength=4] - The strength of the glow outward from the edge of the Sprite. + * @param {number} [innerStrength=0] - The strength of the glow inward from the edge of the Sprite. + * @param {boolean} [knockout=false] - If `true` only the glow is drawn, not the texture itself. + */ +var Glow = new Class({ - for (var i = 0; i < objects.length; i++) { - var obj = objects[i]; + Extends: Controller, - switch (obj.type) { + initialize: - case 'body': - Composite.removeBody(composite, obj, deep); - break; - case 'constraint': - Composite.removeConstraint(composite, obj, deep); - break; - case 'composite': - Composite.removeComposite(composite, obj, deep); - break; - case 'mouseConstraint': - Composite.removeConstraint(composite, obj.constraint); - break; + function Glow (gameObject, color, outerStrength, innerStrength, knockout) + { + if (outerStrength === undefined) { outerStrength = 4; } + if (innerStrength === undefined) { innerStrength = 0; } + if (knockout === undefined) { knockout = false; } - } - } + Controller.call(this, FX_CONST.GLOW, gameObject); - Events.trigger(composite, 'afterRemove', { object: object }); + /** + * The strength of the glow outward from the edge of the Sprite. + * + * @name Phaser.FX.Glow#outerStrength + * @type {number} + * @since 3.60.0 + */ + this.outerStrength = outerStrength; - return composite; - }; + /** + * The strength of the glow inward from the edge of the Sprite. + * + * @name Phaser.FX.Glow#innerStrength + * @type {number} + * @since 3.60.0 + */ + this.innerStrength = innerStrength; - /** - * Adds a composite to the given composite. - * @private - * @method addComposite - * @param {composite} compositeA - * @param {composite} compositeB - * @return {composite} The original compositeA with the objects from compositeB added - */ - Composite.addComposite = function(compositeA, compositeB) { - compositeA.composites.push(compositeB); - compositeB.parent = compositeA; - Composite.setModified(compositeA, true, true, false); - return compositeA; - }; + /** + * If `true` only the glow is drawn, not the texture itself. + * + * @name Phaser.FX.Glow#knockout + * @type {number} + * @since 3.60.0 + */ + this.knockout = knockout; - /** - * Removes a composite from the given composite, and optionally searching its children recursively. - * @private - * @method removeComposite - * @param {composite} compositeA - * @param {composite} compositeB - * @param {boolean} [deep=false] - * @return {composite} The original compositeA with the composite removed - */ - Composite.removeComposite = function(compositeA, compositeB, deep) { - var position = compositeA.composites.indexOf(compositeB); - if (position !== -1) { - Composite.removeCompositeAt(compositeA, position); - Composite.setModified(compositeA, true, true, false); - } + /** + * A 4 element array of gl color values. + * + * @name Phaser.FX.Glow#glcolor + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor = [ 1, 1, 1, 1 ]; - if (deep) { - for (var i = 0; i < compositeA.composites.length; i++){ - Composite.removeComposite(compositeA.composites[i], compositeB, true); - } + if (color !== undefined) + { + this.color = color; } - - return compositeA; - }; + }, /** - * Removes a composite from the given composite. - * @private - * @method removeCompositeAt - * @param {composite} composite - * @param {number} position - * @return {composite} The original composite with the composite removed + * The color of the glow as a number value. + * + * @name Phaser.FX.Glow#color + * @type {number} + * @since 3.60.0 */ - Composite.removeCompositeAt = function(composite, position) { - composite.composites.splice(position, 1); - Composite.setModified(composite, true, true, false); - return composite; - }; + color: { - /** - * Adds a body to the given composite. - * @private - * @method addBody - * @param {composite} composite - * @param {body} body - * @return {composite} The original composite with the body added - */ - Composite.addBody = function(composite, body) { - composite.bodies.push(body); - Composite.setModified(composite, true, true, false); - return composite; - }; + get: function () + { + var color = this.glcolor; - /** - * Removes a body from the given composite, and optionally searching its children recursively. - * @private - * @method removeBody - * @param {composite} composite - * @param {body} body - * @param {boolean} [deep=false] - * @return {composite} The original composite with the body removed - */ - Composite.removeBody = function(composite, body, deep) { - var position = composite.bodies.indexOf(body); - if (position !== -1) { - Composite.removeBodyAt(composite, position); - Composite.setModified(composite, true, true, false); - } + return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0)); + }, - if (deep) { - for (var i = 0; i < composite.composites.length; i++){ - Composite.removeBody(composite.composites[i], body, true); - } + set: function (value) + { + var color = this.glcolor; + + color[0] = ((value >> 16) & 0xFF) / 255; + color[1] = ((value >> 8) & 0xFF) / 255; + color[2] = (value & 0xFF) / 255; } - return composite; - }; + } - /** - * Removes a body from the given composite. - * @private - * @method removeBodyAt - * @param {composite} composite - * @param {number} position - * @return {composite} The original composite with the body removed - */ - Composite.removeBodyAt = function(composite, position) { - composite.bodies.splice(position, 1); - Composite.setModified(composite, true, true, false); - return composite; - }; - - /** - * Adds a constraint to the given composite. - * @private - * @method addConstraint - * @param {composite} composite - * @param {constraint} constraint - * @return {composite} The original composite with the constraint added - */ - Composite.addConstraint = function(composite, constraint) { - composite.constraints.push(constraint); - Composite.setModified(composite, true, true, false); - return composite; - }; - - /** - * Removes a constraint from the given composite, and optionally searching its children recursively. - * @private - * @method removeConstraint - * @param {composite} composite - * @param {constraint} constraint - * @param {boolean} [deep=false] - * @return {composite} The original composite with the constraint removed - */ - Composite.removeConstraint = function(composite, constraint, deep) { - var position = composite.constraints.indexOf(constraint); - if (position !== -1) { - Composite.removeConstraintAt(composite, position); - } - - if (deep) { - for (var i = 0; i < composite.composites.length; i++){ - Composite.removeConstraint(composite.composites[i], constraint, true); - } - } - - return composite; - }; - - /** - * Removes a body from the given composite. - * @private - * @method removeConstraintAt - * @param {composite} composite - * @param {number} position - * @return {composite} The original composite with the constraint removed - */ - Composite.removeConstraintAt = function(composite, position) { - composite.constraints.splice(position, 1); - Composite.setModified(composite, true, true, false); - return composite; - }; - - /** - * Removes all bodies, constraints and composites from the given composite. - * Optionally clearing its children recursively. - * @method clear - * @param {composite} composite - * @param {boolean} keepStatic - * @param {boolean} [deep=false] - */ - Composite.clear = function(composite, keepStatic, deep) { - if (deep) { - for (var i = 0; i < composite.composites.length; i++){ - Composite.clear(composite.composites[i], keepStatic, true); - } - } - - if (keepStatic) { - composite.bodies = composite.bodies.filter(function(body) { return body.isStatic; }); - } else { - composite.bodies.length = 0; - } - - composite.constraints.length = 0; - composite.composites.length = 0; - Composite.setModified(composite, true, true, false); - - return composite; - }; - - /** - * Returns all bodies in the given composite, including all bodies in its children, recursively. - * @method allBodies - * @param {composite} composite - * @return {body[]} All the bodies - */ - Composite.allBodies = function(composite) { - var bodies = [].concat(composite.bodies); +}); - for (var i = 0; i < composite.composites.length; i++) - bodies = bodies.concat(Composite.allBodies(composite.composites[i])); +module.exports = Glow; - return bodies; - }; - /** - * Returns all constraints in the given composite, including all constraints in its children, recursively. - * @method allConstraints - * @param {composite} composite - * @return {constraint[]} All the constraints - */ - Composite.allConstraints = function(composite) { - var constraints = [].concat(composite.constraints); +/***/ }), - for (var i = 0; i < composite.composites.length; i++) - constraints = constraints.concat(Composite.allConstraints(composite.composites[i])); +/***/ 62494: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return constraints; - }; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Returns all composites in the given composite, including all composites in its children, recursively. - * @method allComposites - * @param {composite} composite - * @return {composite[]} All the composites - */ - Composite.allComposites = function(composite) { - var composites = [].concat(composite.composites); +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); - for (var i = 0; i < composite.composites.length; i++) - composites = composites.concat(Composite.allComposites(composite.composites[i])); +/** + * @classdesc + * The Gradient FX Controller. + * + * This FX controller manages the gradient effect for a Game Object. + * + * The gradient overlay effect is a visual technique where a smooth color transition is applied over Game Objects, + * such as sprites or UI components. This effect is used to enhance visual appeal, emphasize depth, or create + * stylistic and atmospheric variations. It can also be utilized to convey information, such as representing + * progress or health status through color changes. + * + * A Gradient effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addGradient(); + * sprite.postFX.addGradient(); + * ``` + * + * @class Gradient + * @extends Phaser.FX.Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [color1=0xff0000] - The first gradient color, given as a number value. + * @param {number} [color2=0x00ff00] - The second gradient color, given as a number value. + * @param {number} [alpha=0.2] - The alpha value of the gradient effect. + * @param {number} [fromX=0] - The horizontal position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + * @param {number} [fromY=0] - The vertical position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + * @param {number} [toX=0] - The horizontal position the gradient will end at. This value is noralized, between 0 and 1 and is not in pixels. + * @param {number} [toY=1] - The vertical position the gradient will end at. This value is noralized, between 0 and 1 and is not in pixels. + * @param {number} [size=0] - How many 'chunks' the gradient is divided in to, as spread over the entire height of the texture. Leave this at zero for a smooth gradient, or set higher for a more retro chunky effect. + */ +var Gradient = new Class({ - return composites; - }; + Extends: Controller, - /** - * Searches the composite recursively for an object matching the type and id supplied, null if not found. - * @method get - * @param {composite} composite - * @param {number} id - * @param {string} type - * @return {object} The requested object, if found - */ - Composite.get = function(composite, id, type) { - var objects, - object; + initialize: - switch (type) { - case 'body': - objects = Composite.allBodies(composite); - break; - case 'constraint': - objects = Composite.allConstraints(composite); - break; - case 'composite': - objects = Composite.allComposites(composite).concat(composite); - break; - } + function Gradient (gameObject, color1, color2, alpha, fromX, fromY, toX, toY, size) + { + if (alpha === undefined) { alpha = 0.2; } + if (fromX === undefined) { fromX = 0; } + if (fromY === undefined) { fromY = 0; } + if (toX === undefined) { toX = 0; } + if (toY === undefined) { toY = 1; } + if (size === undefined) { size = 0; } - if (!objects) - return null; + Controller.call(this, FX_CONST.GRADIENT, gameObject); - object = objects.filter(function(object) { - return object.id.toString() === id.toString(); - }); + /** + * The alpha value of the gradient effect. + * + * @name Phaser.FX.Gradient#alpha + * @type {number} + * @since 3.60.0 + */ + this.alpha = alpha; - return object.length === 0 ? null : object[0]; - }; + /** + * Sets how many 'chunks' the gradient is divided in to, as spread over the + * entire height of the texture. Leave this at zero for a smooth gradient, + * or set to a higher number to split the gradient into that many sections, giving + * a more banded 'retro' effect. + * + * @name Phaser.FX.Gradient#size + * @type {number} + * @since 3.60.0 + */ + this.size = size; - /** - * Moves the given object(s) from compositeA to compositeB (equal to a remove followed by an add). - * @method move - * @param {compositeA} compositeA - * @param {object[]} objects - * @param {compositeB} compositeB - * @return {composite} Returns compositeA - */ - Composite.move = function(compositeA, objects, compositeB) { - Composite.remove(compositeA, objects); - Composite.add(compositeB, objects); - return compositeA; - }; + /** + * The horizontal position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + * + * @name Phaser.FX.Gradient#fromX + * @type {number} + * @since 3.60.0 + */ + this.fromX = fromX; - /** - * Assigns new ids for all objects in the composite, recursively. - * @method rebase - * @param {composite} composite - * @return {composite} Returns composite - */ - Composite.rebase = function(composite) { - var objects = Composite.allBodies(composite) - .concat(Composite.allConstraints(composite)) - .concat(Composite.allComposites(composite)); + /** + * The vertical position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + * + * @name Phaser.FX.Gradient#fromY + * @type {number} + * @since 3.60.0 + */ + this.fromY = fromY; - for (var i = 0; i < objects.length; i++) { - objects[i].id = Common.nextId(); - } + /** + * The horizontal position the gradient will end. This value is noralized, between 0 and 1 and is not in pixels. + * + * @name Phaser.FX.Gradient#toX + * @type {number} + * @since 3.60.0 + */ + this.toX = toX; - Composite.setModified(composite, true, true, false); + /** + * The vertical position the gradient will end. This value is noralized, between 0 and 1 and is not in pixels. + * + * @name Phaser.FX.Gradient#toY + * @type {number} + * @since 3.60.0 + */ + this.toY = toY; - return composite; - }; + /** + * The internal gl color array for the starting color. + * + * @name Phaser.FX.Gradient#glcolor1 + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor1 = [ 255, 0, 0 ]; - /** - * Translates all children in the composite by a given vector relative to their current positions, - * without imparting any velocity. - * @method translate - * @param {composite} composite - * @param {vector} translation - * @param {bool} [recursive=true] - */ - Composite.translate = function(composite, translation, recursive) { - var bodies = recursive ? Composite.allBodies(composite) : composite.bodies; + /** + * The internal gl color array for the ending color. + * + * @name Phaser.FX.Gradient#glcolor2 + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor2 = [ 0, 255, 0 ]; - for (var i = 0; i < bodies.length; i++) { - Body.translate(bodies[i], translation); + if (color1 !== undefined && color1 !== null) + { + this.color1 = color1; } - Composite.setModified(composite, true, true, false); - - return composite; - }; - - /** - * Rotates all children in the composite by a given angle about the given point, without imparting any angular velocity. - * @method rotate - * @param {composite} composite - * @param {number} rotation - * @param {vector} point - * @param {bool} [recursive=true] - */ - Composite.rotate = function(composite, rotation, point, recursive) { - var cos = Math.cos(rotation), - sin = Math.sin(rotation), - bodies = recursive ? Composite.allBodies(composite) : composite.bodies; - - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i], - dx = body.position.x - point.x, - dy = body.position.y - point.y; - - Body.setPosition(body, { - x: point.x + (dx * cos - dy * sin), - y: point.y + (dx * sin + dy * cos) - }); - - Body.rotate(body, rotation); + if (color2 !== undefined && color2 !== null) + { + this.color2 = color2; } - - Composite.setModified(composite, true, true, false); - - return composite; - }; + }, /** - * Scales all children in the composite, including updating physical properties (mass, area, axes, inertia), from a world-space point. - * @method scale - * @param {composite} composite - * @param {number} scaleX - * @param {number} scaleY - * @param {vector} point - * @param {bool} [recursive=true] + * The first gradient color, given as a number value. + * + * @name Phaser.FX.Gradient#color1 + * @type {number} + * @since 3.60.0 */ - Composite.scale = function(composite, scaleX, scaleY, point, recursive) { - var bodies = recursive ? Composite.allBodies(composite) : composite.bodies; - - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i], - dx = body.position.x - point.x, - dy = body.position.y - point.y; - - Body.setPosition(body, { - x: point.x + dx * scaleX, - y: point.y + dy * scaleY - }); - - Body.scale(body, scaleX, scaleY); - } + color1: { - Composite.setModified(composite, true, true, false); + get: function () + { + var color = this.glcolor1; - return composite; - }; + return (((color[0]) << 16) + ((color[1]) << 8) + (color[2] | 0)); + }, - /** - * Returns the union of the bounds of all of the composite's bodies. - * @method bounds - * @param {composite} composite The composite. - * @returns {bounds} The composite bounds. - */ - Composite.bounds = function(composite) { - var bodies = Composite.allBodies(composite), - vertices = []; + set: function (value) + { + var color = this.glcolor1; - for (var i = 0; i < bodies.length; i += 1) { - var body = bodies[i]; - vertices.push(body.bounds.min, body.bounds.max); + color[0] = ((value >> 16) & 0xFF); + color[1] = ((value >> 8) & 0xFF); + color[2] = (value & 0xFF); } - return Bounds.create(vertices); - }; - - /* - * - * Events Documentation - * - */ - - /** - * Fired when a call to `Composite.add` is made, before objects have been added. - * - * @event beforeAdd - * @param {} event An event object - * @param {} event.object The object(s) to be added (may be a single body, constraint, composite or a mixed array of these) - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired when a call to `Composite.add` is made, after objects have been added. - * - * @event afterAdd - * @param {} event An event object - * @param {} event.object The object(s) that have been added (may be a single body, constraint, composite or a mixed array of these) - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired when a call to `Composite.remove` is made, before objects have been removed. - * - * @event beforeRemove - * @param {} event An event object - * @param {} event.object The object(s) to be removed (may be a single body, constraint, composite or a mixed array of these) - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired when a call to `Composite.remove` is made, after objects have been removed. - * - * @event afterRemove - * @param {} event An event object - * @param {} event.object The object(s) that have been removed (may be a single body, constraint, composite or a mixed array of these) - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /* - * - * Properties Documentation - * - */ - - /** - * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`. - * - * @property id - * @type number - */ - - /** - * A `String` denoting the type of object. - * - * @property type - * @type string - * @default "composite" - * @readOnly - */ + }, /** - * An arbitrary `String` name to help the user identify and manage composites. + * The second gradient color, given as a number value. * - * @property label - * @type string - * @default "Composite" + * @name Phaser.FX.Gradient#color2 + * @type {number} + * @since 3.60.0 */ + color2: { - /** - * A flag that specifies whether the composite has been modified during the current step. - * Most `Matter.Composite` methods will automatically set this flag to `true` to inform the engine of changes to be handled. - * If you need to change it manually, you should use the `Composite.setModified` method. - * - * @property isModified - * @type boolean - * @default false - */ + get: function () + { + var color = this.glcolor2; - /** - * The `Composite` that is the parent of this composite. It is automatically managed by the `Matter.Composite` methods. - * - * @property parent - * @type composite - * @default null - */ + return (((color[0]) << 16) + ((color[1]) << 8) + (color[2] | 0)); + }, - /** - * An array of `Body` that are _direct_ children of this composite. - * To add or remove bodies you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property. - * If you wish to recursively find all descendants, you should use the `Composite.allBodies` method. - * - * @property bodies - * @type body[] - * @default [] - */ + set: function (value) + { + var color = this.glcolor2; - /** - * An array of `Constraint` that are _direct_ children of this composite. - * To add or remove constraints you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property. - * If you wish to recursively find all descendants, you should use the `Composite.allConstraints` method. - * - * @property constraints - * @type constraint[] - * @default [] - */ + color[0] = ((value >> 16) & 0xFF); + color[1] = ((value >> 8) & 0xFF); + color[2] = (value & 0xFF); + } - /** - * An array of `Composite` that are _direct_ children of this composite. - * To add or remove composites you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property. - * If you wish to recursively find all descendants, you should use the `Composite.allComposites` method. - * - * @property composites - * @type composite[] - * @default [] - */ + } - /** - * An object reserved for storing plugin-specific properties. - * - * @property plugin - * @type {} - */ +}); -})(); +module.exports = Gradient; /***/ }), -/* 119 */ -/***/ (function(module, exports) { + +/***/ 68897: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); + /** - * Checks if the given tile coordinates are within the bounds of the layer. + * @classdesc + * The Pixelate FX Controller. * - * @function Phaser.Tilemaps.Components.IsInLayerBounds - * @since 3.0.0 + * This FX controller manages the pixelate effect for a Game Object. * - * @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 act upon. + * The pixelate effect is a visual technique that deliberately reduces the resolution or detail of an image, + * creating a blocky or mosaic appearance composed of large, visible pixels. This effect can be used for stylistic + * purposes, as a homage to retro gaming, or as a means to obscure certain elements within the game, such as + * during a transition or to censor specific content. * - * @return {boolean} `true` if the tile coordinates are within the bounds of the layer, otherwise `false`. + * A Pixelate effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addPixelate(); + * sprite.postFX.addPixelate(); + * ``` + * + * @class Pixelate + * @extends Phaser.FX.Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [amount=1] - The amount of pixelation to apply. */ -var IsInLayerBounds = function (tileX, tileY, layer) -{ - return (tileX >= 0 && tileX < layer.width && tileY >= 0 && tileY < layer.height); -}; +var Pixelate = new Class({ -module.exports = IsInLayerBounds; + Extends: Controller, + + initialize: + + function Pixelate (gameObject, amount) + { + if (amount === undefined) { amount = 1; } + + Controller.call(this, FX_CONST.PIXELATE, gameObject); + + /** + * The amount of pixelation to apply. + * + * @name Phaser.FX.Pixelate#amount + * @type {number} + * @since 3.60.0 + */ + this.amount = amount; + } + +}); + +module.exports = Pixelate; /***/ }), -/* 120 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 58575: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(29); -var GetFastValue = __webpack_require__(2); +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); /** * @classdesc - * A class for representing data about about a layer in a map. Maps are parsed from CSV, Tiled, - * etc. into this format. Tilemap and TilemapLayer objects have a reference - * to this data and use it to look up and perform operations on tiles. + * The Shadow FX Controller. * - * @class LayerData - * @memberof Phaser.Tilemaps + * This FX controller manages the shadow effect for a Game Object. + * + * The shadow effect is a visual technique used to create the illusion of depth and realism by adding darker, + * offset silhouettes or shapes beneath game objects, characters, or environments. These simulated shadows + * help to enhance the visual appeal and immersion, making the 2D game world appear more dynamic and three-dimensional. + * + * A Shadow effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addShadow(); + * sprite.postFX.addShadow(); + * ``` + * + * @class Shadow + * @extends Phaser.FX.Controller + * @memberof Phaser.FX * @constructor - * @since 3.0.0 + * @since 3.60.0 * - * @param {Phaser.Types.Tilemaps.LayerDataConfig} [config] - The Layer Data configuration object. + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [x=0] - The horizontal offset of the shadow effect. + * @param {number} [y=0] - The vertical offset of the shadow effect. + * @param {number} [decay=0.1] - The amount of decay for shadow effect. + * @param {number} [power=1] - The power of the shadow effect. + * @param {number} [color=0x000000] - The color of the shadow. + * @param {number} [samples=6] - The number of samples that the shadow effect will run for. An integer between 1 and 12. + * @param {number} [intensity=1] - The intensity of the shadow effect. */ -var LayerData = new Class({ +var Shadow = new Class({ + + Extends: Controller, initialize: - function LayerData (config) + function Shadow (gameObject, x, y, decay, power, color, samples, intensity) { - if (config === undefined) { config = {}; } - - /** - * The name of the layer, if specified in Tiled. - * - * @name Phaser.Tilemaps.LayerData#name - * @type {string} - * @since 3.0.0 - */ - this.name = GetFastValue(config, 'name', 'layer'); - - /** - * The x offset of where to draw from the top left. - * - * @name Phaser.Tilemaps.LayerData#x - * @type {number} - * @since 3.0.0 - */ - this.x = GetFastValue(config, 'x', 0); - - /** - * The y offset of where to draw from the top left. - * - * @name Phaser.Tilemaps.LayerData#y - * @type {number} - * @since 3.0.0 - */ - this.y = GetFastValue(config, 'y', 0); - - /** - * The width of the layer in tiles. - * - * @name Phaser.Tilemaps.LayerData#width - * @type {number} - * @since 3.0.0 - */ - this.width = GetFastValue(config, 'width', 0); + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (decay === undefined) { decay = 0.1; } + if (power === undefined) { power = 1; } + if (samples === undefined) { samples = 6; } + if (intensity === undefined) { intensity = 1; } - /** - * The height of the layer in tiles. - * - * @name Phaser.Tilemaps.LayerData#height - * @type {number} - * @since 3.0.0 - */ - this.height = GetFastValue(config, 'height', 0); + Controller.call(this, FX_CONST.SHADOW, gameObject); /** - * The pixel width of the tiles. + * The horizontal offset of the shadow effect. * - * @name Phaser.Tilemaps.LayerData#tileWidth + * @name Phaser.FX.Shadow#x * @type {number} - * @since 3.0.0 + * @since 3.60.0 */ - this.tileWidth = GetFastValue(config, 'tileWidth', 0); + this.x = x; /** - * The pixel height of the tiles. + * The vertical offset of the shadow effect. * - * @name Phaser.Tilemaps.LayerData#tileHeight + * @name Phaser.FX.Shadow#y * @type {number} - * @since 3.0.0 + * @since 3.60.0 */ - this.tileHeight = GetFastValue(config, 'tileHeight', 0); + this.y = y; /** - * The base tile width. + * The amount of decay for the shadow effect. * - * @name Phaser.Tilemaps.LayerData#baseTileWidth + * @name Phaser.FX.Shadow#decay * @type {number} - * @since 3.0.0 + * @since 3.60.0 */ - this.baseTileWidth = GetFastValue(config, 'baseTileWidth', this.tileWidth); + this.decay = decay; /** - * The base tile height. + * The power of the shadow effect. * - * @name Phaser.Tilemaps.LayerData#baseTileHeight + * @name Phaser.FX.Shadow#power * @type {number} - * @since 3.0.0 + * @since 3.60.0 */ - this.baseTileHeight = GetFastValue(config, 'baseTileHeight', this.tileHeight); + this.power = power; /** - * The layers orientation, necessary to be able to determine a tiles pixelX and pixelY as well as the layers width and height. + * The internal gl color array. * - * @name Phaser.Tilemaps.LayerData#orientation - * @type {Phaser.Tilemaps.OrientationType} - * @since 3.50.0 + * @name Phaser.FX.Shadow#glcolor + * @type {number[]} + * @since 3.60.0 */ - this.orientation = GetFastValue(config, 'orientation', CONST.ORTHOGONAL); + this.glcolor = [ 0, 0, 0, 1 ]; /** - * The width in pixels of the entire layer. + * The number of samples that the shadow effect will run for. * - * @name Phaser.Tilemaps.LayerData#widthInPixels - * @type {number} - * @since 3.0.0 - */ - this.widthInPixels = GetFastValue(config, 'widthInPixels', this.width * this.baseTileWidth); - - /** - * The height in pixels of the entire layer. + * This should be an integer with a minimum value of 1 and a maximum of 12. * - * @name Phaser.Tilemaps.LayerData#heightInPixels + * @name Phaser.FX.Shadow#samples * @type {number} - * @since 3.0.0 + * @since 3.60.0 */ - this.heightInPixels = GetFastValue(config, 'heightInPixels', this.height * this.baseTileHeight); + this.samples = samples; /** - * The alpha value of the layer. + * The intensity of the shadow effect. * - * @name Phaser.Tilemaps.LayerData#alpha + * @name Phaser.FX.Shadow#intensity * @type {number} - * @since 3.0.0 - */ - this.alpha = GetFastValue(config, 'alpha', 1); - - /** - * Is the layer visible or not? - * - * @name Phaser.Tilemaps.LayerData#visible - * @type {boolean} - * @since 3.0.0 - */ - this.visible = GetFastValue(config, 'visible', true); - - /** - * Layer specific properties (can be specified in Tiled) - * - * @name Phaser.Tilemaps.LayerData#properties - * @type {object[]} - * @since 3.0.0 + * @since 3.60.0 */ - this.properties = GetFastValue(config, 'properties', []); + this.intensity = intensity; - /** - * Tile ID index map. - * - * @name Phaser.Tilemaps.LayerData#indexes - * @type {array} - * @since 3.0.0 - */ - this.indexes = GetFastValue(config, 'indexes', []); + if (color !== undefined) + { + this.color = color; + } + }, - /** - * Tile Collision ID index map. - * - * @name Phaser.Tilemaps.LayerData#collideIndexes - * @type {array} - * @since 3.0.0 - */ - this.collideIndexes = GetFastValue(config, 'collideIndexes', []); + /** + * The color of the shadow. + * + * @name Phaser.FX.Shadow#color + * @type {number} + * @since 3.60.0 + */ + color: { - /** - * An array of callbacks. - * - * @name Phaser.Tilemaps.LayerData#callbacks - * @type {array} - * @since 3.0.0 - */ - this.callbacks = GetFastValue(config, 'callbacks', []); + get: function () + { + var color = this.glcolor; - /** - * An array of physics bodies. - * - * @name Phaser.Tilemaps.LayerData#bodies - * @type {array} - * @since 3.0.0 - */ - this.bodies = GetFastValue(config, 'bodies', []); + return (((color[0] * 255) << 16) + ((color[1] * 255) << 8) + (color[2] * 255 | 0)); + }, - /** - * An array of the tile data indexes. - * - * @name Phaser.Tilemaps.LayerData#data - * @type {Phaser.Tilemaps.Tile[][]} - * @since 3.0.0 - */ - this.data = GetFastValue(config, 'data', []); + set: function (value) + { + var color = this.glcolor; - /** - * A reference to the Tilemap layer that owns this data. - * - * @name Phaser.Tilemaps.LayerData#tilemapLayer - * @type {Phaser.Tilemaps.TilemapLayer} - * @since 3.0.0 - */ - this.tilemapLayer = GetFastValue(config, 'tilemapLayer', null); + color[0] = ((value >> 16) & 0xFF) / 255; + color[1] = ((value >> 8) & 0xFF) / 255; + color[2] = (value & 0xFF) / 255; + } - /** - * The length of the horizontal sides of the hexagon. - * Only used for hexagonal orientation Tilemaps. - * - * @name Phaser.Tilemaps.LayerData#hexSideLength - * @type {number} - * @since 3.50.0 - */ - this.hexSideLength = GetFastValue(config, 'hexSideLength', 0); } }); -module.exports = LayerData; +module.exports = Shadow; /***/ }), -/* 121 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 33755: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(29); -var GetFastValue = __webpack_require__(2); +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); /** * @classdesc - * A class for representing data about a map. Maps are parsed from CSV, Tiled, etc. into this - * format. A Tilemap object get a copy of this data and then unpacks the needed properties into - * itself. + * The Shine FX Controller. * - * @class MapData - * @memberof Phaser.Tilemaps + * This FX controller manages the shift effect for a Game Object. + * + * The shine effect is a visual technique that simulates the appearance of reflective + * or glossy surfaces by passing a light beam across a Game Object. This effect is used to + * enhance visual appeal, emphasize certain features, and create a sense of depth or + * material properties. + * + * A Shine effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addShine(); + * sprite.postFX.addShine(); + * ``` + * + * @class Shine + * @extends Phaser.FX.Controller + * @memberof Phaser.FX * @constructor - * @since 3.0.0 + * @since 3.60.0 * - * @param {Phaser.Types.Tilemaps.MapDataConfig} [config] - The Map configuration object. + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [speed=0.5] - The speed of the Shine effect. + * @param {number} [lineWidth=0.5] - The line width of the Shine effect. + * @param {number} [gradient=3] - The gradient of the Shine effect. + * @param {boolean} [reveal=false] - Does this Shine effect reveal or get added to its target? */ -var MapData = new Class({ +var Shine = new Class({ + + Extends: Controller, initialize: - function MapData (config) + function Shine (gameObject, speed, lineWidth, gradient, reveal) { - if (config === undefined) { config = {}; } + if (speed === undefined) { speed = 0.5; } + if (lineWidth === undefined) { lineWidth = 0.5; } + if (gradient === undefined) { gradient = 3; } + if (reveal === undefined) { reveal = false; } - /** - * The key in the Phaser cache that corresponds to the loaded tilemap data. - * - * @name Phaser.Tilemaps.MapData#name - * @type {string} - * @since 3.0.0 - */ - this.name = GetFastValue(config, 'name', 'map'); + Controller.call(this, FX_CONST.SHINE, gameObject); /** - * The width of the entire tilemap. + * The speed of the Shine effect. * - * @name Phaser.Tilemaps.MapData#width + * @name Phaser.FX.Shine#speed * @type {number} - * @since 3.0.0 + * @since 3.60.0 */ - this.width = GetFastValue(config, 'width', 0); + this.speed = speed; /** - * The height of the entire tilemap. + * The line width of the Shine effect. * - * @name Phaser.Tilemaps.MapData#height + * @name Phaser.FX.Shine#lineWidth * @type {number} - * @since 3.0.0 - */ - this.height = GetFastValue(config, 'height', 0); - - /** - * If the map is infinite or not. - * - * @name Phaser.Tilemaps.MapData#infinite - * @type {boolean} - * @since 3.17.0 + * @since 3.60.0 */ - this.infinite = GetFastValue(config, 'infinite', false); + this.lineWidth = lineWidth; /** - * The width of the tiles. + * The gradient of the Shine effect. * - * @name Phaser.Tilemaps.MapData#tileWidth + * @name Phaser.FX.Shine#gradient * @type {number} - * @since 3.0.0 + * @since 3.60.0 */ - this.tileWidth = GetFastValue(config, 'tileWidth', 0); + this.gradient = gradient; /** - * The height of the tiles. + * Does this Shine effect reveal or get added to its target? * - * @name Phaser.Tilemaps.MapData#tileHeight - * @type {number} - * @since 3.0.0 + * @name Phaser.FX.Shine#reveal + * @type {boolean} + * @since 3.60.0 */ - this.tileHeight = GetFastValue(config, 'tileHeight', 0); + this.reveal = reveal; + } - /** - * The width in pixels of the entire tilemap. - * - * @name Phaser.Tilemaps.MapData#widthInPixels - * @type {number} - * @since 3.0.0 - */ - this.widthInPixels = GetFastValue(config, 'widthInPixels', this.width * this.tileWidth); +}); - /** - * The height in pixels of the entire tilemap. - * - * @name Phaser.Tilemaps.MapData#heightInPixels - * @type {number} - * @since 3.0.0 - */ - this.heightInPixels = GetFastValue(config, 'heightInPixels', this.height * this.tileHeight); +module.exports = Shine; - /** - * The format of the map data. - * - * @name Phaser.Tilemaps.MapData#format - * @type {number} - * @since 3.0.0 - */ - this.format = GetFastValue(config, 'format', null); - /** - * The orientation of the map data (i.e. orthogonal, isometric, hexagonal), default 'orthogonal'. - * - * @name Phaser.Tilemaps.MapData#orientation - * @type {Phaser.Tilemaps.OrientationType} - * @since 3.50.0 - */ - this.orientation = GetFastValue(config, 'orientation', CONST.ORTHOGONAL); +/***/ }), - /** - * Determines the draw order of tilemap. Default is right-down - * - * 0, or 'right-down' - * 1, or 'left-down' - * 2, or 'right-up' - * 3, or 'left-up' - * - * @name Phaser.Tilemaps.MapData#renderOrder - * @type {string} - * @since 3.12.0 - */ - this.renderOrder = GetFastValue(config, 'renderOrder', 'right-down'); +/***/ 24949: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The version of the map data (as specified in Tiled). - * - * @name Phaser.Tilemaps.MapData#version - * @type {string} - * @since 3.0.0 - */ - this.version = GetFastValue(config, 'version', '1'); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Map specific properties (can be specified in Tiled) - * - * @name Phaser.Tilemaps.MapData#properties - * @type {object} - * @since 3.0.0 - */ - this.properties = GetFastValue(config, 'properties', {}); +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); - /** - * An array with all the layers configured to the MapData. - * - * @name Phaser.Tilemaps.MapData#layers - * @type {(Phaser.Tilemaps.LayerData[]|Phaser.Tilemaps.ObjectLayer)} - * @since 3.0.0 - */ - this.layers = GetFastValue(config, 'layers', []); +/** + * @classdesc + * The Vignette FX Controller. + * + * This FX controller manages the vignette effect for a Game Object. + * + * The vignette effect is a visual technique where the edges of the screen, or a Game Object, gradually darken or blur, + * creating a frame-like appearance. This effect is used to draw the player's focus towards the central action or subject, + * enhance immersion, and provide a cinematic or artistic quality to the game's visuals. + * + * A Vignette effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addVignette(); + * sprite.postFX.addVignette(); + * ``` + * + * @class Vignette + * @extends Phaser.FX.Controller + * @memberof Phaser.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [x=0.5] - The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1. + * @param {number} [y=0.5] - The vertical offset of the vignette effect. This value is normalized to the range 0 to 1. + * @param {number} [radius=0.5] - The radius of the vignette effect. This value is normalized to the range 0 to 1. + * @param {number} [strength=0.5] - The strength of the vignette effect. + */ +var Vignette = new Class({ - /** - * An array of Tiled Image Layers. - * - * @name Phaser.Tilemaps.MapData#images - * @type {array} - * @since 3.0.0 - */ - this.images = GetFastValue(config, 'images', []); + Extends: Controller, - /** - * An object of Tiled Object Layers. - * - * @name Phaser.Tilemaps.MapData#objects - * @type {object} - * @since 3.0.0 - */ - this.objects = GetFastValue(config, 'objects', {}); + initialize: - /** - * An object of collision data. Must be created as physics object or will return undefined. - * - * @name Phaser.Tilemaps.MapData#collision - * @type {object} - * @since 3.0.0 - */ - this.collision = GetFastValue(config, 'collision', {}); + function Vignette (gameObject, x, y, radius, strength) + { + if (x === undefined) { x = 0.5; } + if (y === undefined) { y = 0.5; } + if (radius === undefined) { radius = 0.5; } + if (strength === undefined) { strength = 0.5; } + + Controller.call(this, FX_CONST.VIGNETTE, gameObject); /** - * An array of Tilesets. + * The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1. * - * @name Phaser.Tilemaps.MapData#tilesets - * @type {Phaser.Tilemaps.Tileset[]} - * @since 3.0.0 + * @name Phaser.FX.Vignette#x + * @type {number} + * @since 3.60.0 */ - this.tilesets = GetFastValue(config, 'tilesets', []); + this.x = x; /** - * The collection of images the map uses(specified in Tiled) + * The vertical offset of the vignette effect. This value is normalized to the range 0 to 1. * - * @name Phaser.Tilemaps.MapData#imageCollections - * @type {array} - * @since 3.0.0 + * @name Phaser.FX.Vignette#y + * @type {number} + * @since 3.60.0 */ - this.imageCollections = GetFastValue(config, 'imageCollections', []); + this.y = y; /** - * An array of tile instances. + * The radius of the vignette effect. This value is normalized to the range 0 to 1. * - * @name Phaser.Tilemaps.MapData#tiles - * @type {array} - * @since 3.0.0 + * @name Phaser.FX.Vignette#radius + * @type {number} + * @since 3.60.0 */ - this.tiles = GetFastValue(config, 'tiles', []); + this.radius = radius; /** - * The length of the horizontal sides of the hexagon. - * Only used for hexagonal orientation Tilemaps. + * The strength of the vignette effect. * - * @name Phaser.Tilemaps.MapData#hexSideLength + * @name Phaser.FX.Vignette#strength * @type {number} - * @since 3.50.0 + * @since 3.60.0 */ - this.hexSideLength = GetFastValue(config, 'hexSideLength', 0); + this.strength = strength; } }); -module.exports = MapData; +module.exports = Vignette; /***/ }), -/* 122 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 66241: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); +var Class = __webpack_require__(56694); +var Controller = __webpack_require__(47551); +var FX_CONST = __webpack_require__(47406); /** * @classdesc - * A Tileset is a combination of an image containing the tiles and a container for data about - * each tile. + * The Wipe FX Controller. * - * @class Tileset - * @memberof Phaser.Tilemaps + * This FX controller manages the wipe effect for a Game Object. + * + * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements + * in the game, such as images, text, or scene transitions. This effect is often used to create + * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition + * between game states. + * + * You can set both the direction and the axis of the wipe effect. The following combinations are possible: + * + * * left to right: direction 0, axis 0 + * * right to left: direction 1, axis 0 + * * top to bottom: direction 1, axis 1 + * * bottom to top: direction 1, axis 0 + * + * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect. + * + * A Wipe effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addWipe(); + * sprite.postFX.addWipe(); + * sprite.preFX.addReveal(); + * sprite.postFX.addReveal(); + * ``` + * + * @class Wipe + * @extends Phaser.FX.Controller + * @memberof Phaser.FX * @constructor - * @since 3.0.0 + * @since 3.60.0 * - * @param {string} name - The name of the tileset in the map data. - * @param {number} firstgid - The first tile index this tileset contains. - * @param {number} [tileWidth=32] - Width of each tile (in pixels). - * @param {number} [tileHeight=32] - Height of each tile (in pixels). - * @param {number} [tileMargin=0] - The margin around all tiles in the sheet (in pixels). - * @param {number} [tileSpacing=0] - The spacing between each tile in the sheet (in pixels). - * @param {object} [tileProperties={}] - Custom properties defined per tile in the Tileset. - * These typically are custom properties created in Tiled when editing a tileset. - * @param {object} [tileData={}] - Data stored per tile. These typically are created in Tiled - * when editing a tileset, e.g. from Tiled's tile collision editor or terrain editor. + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that has this fx. + * @param {number} [wipeWidth=0.1] - The width of the wipe effect. This value is normalized in the range 0 to 1. + * @param {number} [direction=0] - The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. + * @param {number} [axis=0] - The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. + * @param {boolean} [reveal=false] - Is this a reveal (true) or a fade (false) effect? */ -var Tileset = new Class({ +var Wipe = new Class({ + + Extends: Controller, initialize: - function Tileset (name, firstgid, tileWidth, tileHeight, tileMargin, tileSpacing, tileProperties, tileData) + function Wipe (gameObject, wipeWidth, direction, axis, reveal) { - if (tileWidth === undefined || tileWidth <= 0) { tileWidth = 32; } - if (tileHeight === undefined || tileHeight <= 0) { tileHeight = 32; } - if (tileMargin === undefined) { tileMargin = 0; } - if (tileSpacing === undefined) { tileSpacing = 0; } - if (tileProperties === undefined) { tileProperties = {}; } - if (tileData === undefined) { tileData = {}; } + if (wipeWidth === undefined) { wipeWidth = 0.1; } + if (direction === undefined) { direction = 0; } + if (axis === undefined) { axis = 0; } + if (reveal === undefined) { reveal = false; } - /** - * The name of the Tileset. - * - * @name Phaser.Tilemaps.Tileset#name - * @type {string} - * @since 3.0.0 - */ - this.name = name; + Controller.call(this, FX_CONST.WIPE, gameObject); /** - * The starting index of the first tile index this Tileset contains. + * The progress of the Wipe effect. This value is normalized to the range 0 to 1. * - * @name Phaser.Tilemaps.Tileset#firstgid - * @type {number} - * @since 3.0.0 - */ - this.firstgid = firstgid; - - /** - * The width of each tile (in pixels). Use setTileSize to change. + * Adjust this value to make the wipe transition (i.e. via a Tween) * - * @name Phaser.Tilemaps.Tileset#tileWidth + * @name Phaser.FX.Wipe#progress * @type {number} - * @readonly - * @since 3.0.0 + * @since 3.60.0 */ - this.tileWidth = tileWidth; + this.progress = 0; /** - * The height of each tile (in pixels). Use setTileSize to change. + * The width of the wipe effect. This value is normalized in the range 0 to 1. * - * @name Phaser.Tilemaps.Tileset#tileHeight + * @name Phaser.FX.Wipe#wipeWidth * @type {number} - * @readonly - * @since 3.0.0 + * @since 3.60.0 */ - this.tileHeight = tileHeight; + this.wipeWidth = wipeWidth; /** - * The margin around the tiles in the sheet (in pixels). Use `setSpacing` to change. + * The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. * - * @name Phaser.Tilemaps.Tileset#tileMargin + * @name Phaser.FX.Wipe#direction * @type {number} - * @readonly - * @since 3.0.0 + * @since 3.60.0 */ - this.tileMargin = tileMargin; + this.direction = direction; /** - * The spacing between each the tile in the sheet (in pixels). Use `setSpacing` to change. + * The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. * - * @name Phaser.Tilemaps.Tileset#tileSpacing + * @name Phaser.FX.Wipe#axis * @type {number} - * @readonly - * @since 3.0.0 + * @since 3.60.0 */ - this.tileSpacing = tileSpacing; + this.axis = axis; /** - * Tileset-specific properties per tile that are typically defined in the Tiled editor in the - * Tileset editor. + * Is this a reveal (true) or a fade (false) effect? * - * @name Phaser.Tilemaps.Tileset#tileProperties - * @type {object} - * @since 3.0.0 + * @name Phaser.FX.Wipe#reveal + * @type {boolean} + * @since 3.60.0 */ - this.tileProperties = tileProperties; + this.reveal = reveal; + } - /** - * Tileset-specific data per tile that are typically defined in the Tiled editor, e.g. within - * the Tileset collision editor. This is where collision objects and terrain are stored. - * - * @name Phaser.Tilemaps.Tileset#tileData - * @type {object} - * @since 3.0.0 - */ - this.tileData = tileData; +}); - /** - * The cached image that contains the individual tiles. Use setImage to set. - * - * @name Phaser.Tilemaps.Tileset#image - * @type {?Phaser.Textures.Texture} - * @readonly - * @since 3.0.0 - */ - this.image = null; +module.exports = Wipe; - /** - * The gl texture used by the WebGL renderer. - * - * @name Phaser.Tilemaps.Tileset#glTexture - * @type {?WebGLTexture} - * @readonly - * @since 3.11.0 - */ - this.glTexture = null; - /** - * The number of tile rows in the the tileset. - * - * @name Phaser.Tilemaps.Tileset#rows - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.rows = 0; +/***/ }), - /** - * The number of tile columns in the tileset. - * - * @name Phaser.Tilemaps.Tileset#columns - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.columns = 0; +/***/ 47406: +/***/ ((module) => { - /** - * The total number of tiles in the tileset. - * - * @name Phaser.Tilemaps.Tileset#total - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.total = 0; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The look-up table to specific tile image texture coordinates (UV in pixels). Each element - * contains the coordinates for a tile in an object of the form {x, y}. - * - * @name Phaser.Tilemaps.Tileset#texCoordinates - * @type {object[]} - * @readonly - * @since 3.0.0 - */ - this.texCoordinates = []; - }, +var FX_CONST = { /** - * Get a tiles properties that are stored in the Tileset. Returns null if tile index is not - * contained in this Tileset. This is typically defined in Tiled under the Tileset editor. - * - * @method Phaser.Tilemaps.Tileset#getTileProperties - * @since 3.0.0 - * - * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. + * The Glow FX. * - * @return {?(object|undefined)} + * @name Phaser.FX.GLOW + * @type {number} + * @const + * @since 3.60.0 */ - getTileProperties: function (tileIndex) - { - if (!this.containsTileIndex(tileIndex)) { return null; } - - return this.tileProperties[tileIndex - this.firstgid]; - }, + GLOW: 4, /** - * Get a tile's data that is stored in the Tileset. Returns null if tile index is not contained - * in this Tileset. This is typically defined in Tiled and will contain both Tileset collision - * info and terrain mapping. - * - * @method Phaser.Tilemaps.Tileset#getTileData - * @since 3.0.0 + * The Shadow FX. * - * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. - * - * @return {?object|undefined} + * @name Phaser.FX.SHADOW + * @type {number} + * @const + * @since 3.60.0 */ - getTileData: function (tileIndex) - { - if (!this.containsTileIndex(tileIndex)) { return null; } - - return this.tileData[tileIndex - this.firstgid]; - }, + SHADOW: 5, /** - * Get a tile's collision group that is stored in the Tileset. Returns null if tile index is not - * contained in this Tileset. This is typically defined within Tiled's tileset collision editor. - * - * @method Phaser.Tilemaps.Tileset#getTileCollisionGroup - * @since 3.0.0 + * The Pixelate FX. * - * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. - * - * @return {?object} + * @name Phaser.FX.PIXELATE + * @type {number} + * @const + * @since 3.60.0 */ - getTileCollisionGroup: function (tileIndex) - { - var data = this.getTileData(tileIndex); - - return (data && data.objectgroup) ? data.objectgroup : null; - }, + PIXELATE: 6, /** - * Returns true if and only if this Tileset contains the given tile index. - * - * @method Phaser.Tilemaps.Tileset#containsTileIndex - * @since 3.0.0 - * - * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. + * The Vignette FX. * - * @return {boolean} + * @name Phaser.FX.VIGNETTE + * @type {number} + * @const + * @since 3.60.0 */ - containsTileIndex: function (tileIndex) - { - return ( - tileIndex >= this.firstgid && - tileIndex < (this.firstgid + this.total) - ); - }, + VIGNETTE: 7, /** - * Returns the texture coordinates (UV in pixels) in the Tileset image for the given tile index. - * Returns null if tile index is not contained in this Tileset. - * - * @method Phaser.Tilemaps.Tileset#getTileTextureCoordinates - * @since 3.0.0 + * The Shine FX. * - * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. - * - * @return {?object} Object in the form { x, y } representing the top-left UV coordinate - * within the Tileset image. + * @name Phaser.FX.SHINE + * @type {number} + * @const + * @since 3.60.0 */ - getTileTextureCoordinates: function (tileIndex) - { - if (!this.containsTileIndex(tileIndex)) { return null; } - - return this.texCoordinates[tileIndex - this.firstgid]; - }, + SHINE: 8, /** - * Sets the image associated with this Tileset and updates the tile data (rows, columns, etc.). - * - * @method Phaser.Tilemaps.Tileset#setImage - * @since 3.0.0 + * The Blur FX. * - * @param {Phaser.Textures.Texture} texture - The image that contains the tiles. - * - * @return {Phaser.Tilemaps.Tileset} This Tileset object. + * @name Phaser.FX.BLUR + * @type {number} + * @const + * @since 3.60.0 */ - setImage: function (texture) - { - this.image = texture; - - this.glTexture = texture.get().source.glTexture; - - this.updateTileData(this.image.source[0].width, this.image.source[0].height); - - return this; - }, + BLUR: 9, // uses 3 shaders, slots 9, 10 and 11 /** - * Sets the tile width & height and updates the tile data (rows, columns, etc.). + * The Gradient FX. * - * @method Phaser.Tilemaps.Tileset#setTileSize - * @since 3.0.0 - * - * @param {number} [tileWidth] - The width of a tile in pixels. - * @param {number} [tileHeight] - The height of a tile in pixels. - * - * @return {Phaser.Tilemaps.Tileset} This Tileset object. + * @name Phaser.FX.GRADIENT + * @type {number} + * @const + * @since 3.60.0 */ - setTileSize: function (tileWidth, tileHeight) - { - if (tileWidth !== undefined) { this.tileWidth = tileWidth; } - if (tileHeight !== undefined) { this.tileHeight = tileHeight; } - - if (this.image) - { - this.updateTileData(this.image.source[0].width, this.image.source[0].height); - } - - return this; - }, + GRADIENT: 12, /** - * Sets the tile margin & spacing and updates the tile data (rows, columns, etc.). - * - * @method Phaser.Tilemaps.Tileset#setSpacing - * @since 3.0.0 + * The Bloom FX. * - * @param {number} [margin] - The margin around the tiles in the sheet (in pixels). - * @param {number} [spacing] - The spacing between the tiles in the sheet (in pixels). + * @name Phaser.FX.BLOOM + * @type {number} + * @const + * @since 3.60.0 + */ + BLOOM: 13, + + /** + * The Color Matrix FX. * - * @return {Phaser.Tilemaps.Tileset} This Tileset object. + * @name Phaser.FX.COLOR_MATRIX + * @type {number} + * @const + * @since 3.60.0 */ - setSpacing: function (margin, spacing) - { - if (margin !== undefined) { this.tileMargin = margin; } - if (spacing !== undefined) { this.tileSpacing = spacing; } + COLOR_MATRIX: 14, - if (this.image) - { - this.updateTileData(this.image.source[0].width, this.image.source[0].height); - } + /** + * The Circle FX. + * + * @name Phaser.FX.CIRCLE + * @type {number} + * @const + * @since 3.60.0 + */ + CIRCLE: 15, - return this; - }, + /** + * The Barrel FX. + * + * @name Phaser.FX.BARREL + * @type {number} + * @const + * @since 3.60.0 + */ + BARREL: 16, /** - * Updates tile texture coordinates and tileset data. + * The Displacement FX. * - * @method Phaser.Tilemaps.Tileset#updateTileData - * @since 3.0.0 + * @name Phaser.FX.DISPLACEMENT + * @type {number} + * @const + * @since 3.60.0 + */ + DISPLACEMENT: 17, + + /** + * The Wipe FX. * - * @param {number} imageWidth - The (expected) width of the image to slice. - * @param {number} imageHeight - The (expected) height of the image to slice. + * @name Phaser.FX.WIPE + * @type {number} + * @const + * @since 3.60.0 + */ + WIPE: 18, + + /** + * The Bokeh and Tilt Shift FX. * - * @return {Phaser.Tilemaps.Tileset} This Tileset object. + * @name Phaser.FX.BOKEH + * @type {number} + * @const + * @since 3.60.0 */ - updateTileData: function (imageWidth, imageHeight) - { - var rowCount = (imageHeight - this.tileMargin * 2 + this.tileSpacing) / (this.tileHeight + this.tileSpacing); - var colCount = (imageWidth - this.tileMargin * 2 + this.tileSpacing) / (this.tileWidth + this.tileSpacing); + BOKEH: 19 - if (rowCount % 1 !== 0 || colCount % 1 !== 0) - { - console.warn('Image tile area not tile size multiple in: ' + this.name); - } +}; - // In Tiled a tileset image that is not an even multiple of the tile dimensions is truncated - // - hence the floor when calculating the rows/columns. - rowCount = Math.floor(rowCount); - colCount = Math.floor(colCount); +module.exports = FX_CONST; - this.rows = rowCount; - this.columns = colCount; - // In Tiled, "empty" spaces in a tileset count as tiles and hence count towards the gid - this.total = rowCount * colCount; +/***/ }), - this.texCoordinates.length = 0; +/***/ 96910: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var tx = this.tileMargin; - var ty = this.tileMargin; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (var y = 0; y < this.rows; y++) - { - for (var x = 0; x < this.columns; x++) - { - this.texCoordinates.push({ x: tx, y: ty }); - tx += this.tileWidth + this.tileSpacing; - } +var Extend = __webpack_require__(98611); +var FX_CONST = __webpack_require__(47406); - tx = this.tileMargin; - ty += this.tileHeight + this.tileSpacing; - } +/** + * @namespace Phaser.FX + */ - return this; - } +var FX = { -}); + Barrel: __webpack_require__(20170), + Controller: __webpack_require__(47551), + Bloom: __webpack_require__(51182), + Blur: __webpack_require__(51498), + Bokeh: __webpack_require__(12042), + Circle: __webpack_require__(69900), + ColorMatrix: __webpack_require__(48991), + Displacement: __webpack_require__(47909), + Glow: __webpack_require__(18919), + Gradient: __webpack_require__(62494), + Pixelate: __webpack_require__(68897), + Shadow: __webpack_require__(58575), + Shine: __webpack_require__(33755), + Vignette: __webpack_require__(24949), + Wipe: __webpack_require__(66241) -module.exports = Tileset; +}; + +FX = Extend(false, FX, FX_CONST); + +module.exports = FX; /***/ }), -/* 123 */ -/***/ (function(module, exports) { + +/***/ 88933: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ALIGN_CONST = { +var BlendModes = __webpack_require__(95723); +var GetAdvancedValue = __webpack_require__(20494); - /** - * A constant representing a top-left alignment or position. - * @constant - * @name Phaser.Display.Align.TOP_LEFT - * @since 3.0.0 - * @type {number} - */ - TOP_LEFT: 0, +/** + * Builds a Game Object using the provided configuration object. + * + * @function Phaser.GameObjects.BuildGameObject + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - A reference to the Scene. + * @param {Phaser.GameObjects.GameObject} gameObject - The initial GameObject. + * @param {Phaser.Types.GameObjects.GameObjectConfig} config - The config to build the GameObject with. + * + * @return {Phaser.GameObjects.GameObject} The built Game Object. + */ +var BuildGameObject = function (scene, gameObject, config) +{ + // Position - /** - * A constant representing a top-center alignment or position. - * @constant - * @name Phaser.Display.Align.TOP_CENTER - * @since 3.0.0 - * @type {number} - */ - TOP_CENTER: 1, + gameObject.x = GetAdvancedValue(config, 'x', 0); + gameObject.y = GetAdvancedValue(config, 'y', 0); + gameObject.depth = GetAdvancedValue(config, 'depth', 0); - /** - * A constant representing a top-right alignment or position. - * @constant - * @name Phaser.Display.Align.TOP_RIGHT - * @since 3.0.0 - * @type {number} - */ - TOP_RIGHT: 2, + // Flip - /** - * A constant representing a left-top alignment or position. - * @constant - * @name Phaser.Display.Align.LEFT_TOP - * @since 3.0.0 - * @type {number} - */ - LEFT_TOP: 3, + gameObject.flipX = GetAdvancedValue(config, 'flipX', false); + gameObject.flipY = GetAdvancedValue(config, 'flipY', false); - /** - * A constant representing a left-center alignment or position. - * @constant - * @name Phaser.Display.Align.LEFT_CENTER - * @since 3.0.0 - * @type {number} - */ - LEFT_CENTER: 4, + // Scale + // Either: { scale: 2 } or { scale: { x: 2, y: 2 }} - /** - * A constant representing a left-bottom alignment or position. - * @constant - * @name Phaser.Display.Align.LEFT_BOTTOM - * @since 3.0.0 - * @type {number} - */ - LEFT_BOTTOM: 5, + var scale = GetAdvancedValue(config, 'scale', null); - /** - * A constant representing a center alignment or position. - * @constant - * @name Phaser.Display.Align.CENTER - * @since 3.0.0 - * @type {number} - */ - CENTER: 6, + if (typeof scale === 'number') + { + gameObject.setScale(scale); + } + else if (scale !== null) + { + gameObject.scaleX = GetAdvancedValue(scale, 'x', 1); + gameObject.scaleY = GetAdvancedValue(scale, 'y', 1); + } - /** - * A constant representing a right-top alignment or position. - * @constant - * @name Phaser.Display.Align.RIGHT_TOP - * @since 3.0.0 - * @type {number} - */ - RIGHT_TOP: 7, + // ScrollFactor + // Either: { scrollFactor: 2 } or { scrollFactor: { x: 2, y: 2 }} - /** - * A constant representing a right-center alignment or position. - * @constant - * @name Phaser.Display.Align.RIGHT_CENTER - * @since 3.0.0 - * @type {number} - */ - RIGHT_CENTER: 8, + var scrollFactor = GetAdvancedValue(config, 'scrollFactor', null); - /** - * A constant representing a right-bottom alignment or position. - * @constant - * @name Phaser.Display.Align.RIGHT_BOTTOM - * @since 3.0.0 - * @type {number} - */ - RIGHT_BOTTOM: 9, + if (typeof scrollFactor === 'number') + { + gameObject.setScrollFactor(scrollFactor); + } + else if (scrollFactor !== null) + { + gameObject.scrollFactorX = GetAdvancedValue(scrollFactor, 'x', 1); + gameObject.scrollFactorY = GetAdvancedValue(scrollFactor, 'y', 1); + } - /** - * A constant representing a bottom-left alignment or position. - * @constant - * @name Phaser.Display.Align.BOTTOM_LEFT - * @since 3.0.0 - * @type {number} - */ - BOTTOM_LEFT: 10, + // Rotation - /** - * A constant representing a bottom-center alignment or position. - * @constant - * @name Phaser.Display.Align.BOTTOM_CENTER - * @since 3.0.0 - * @type {number} - */ - BOTTOM_CENTER: 11, + gameObject.rotation = GetAdvancedValue(config, 'rotation', 0); - /** - * A constant representing a bottom-right alignment or position. - * @constant - * @name Phaser.Display.Align.BOTTOM_RIGHT - * @since 3.0.0 - * @type {number} - */ - BOTTOM_RIGHT: 12 + var angle = GetAdvancedValue(config, 'angle', null); -}; + if (angle !== null) + { + gameObject.angle = angle; + } -module.exports = ALIGN_CONST; + // Alpha + gameObject.alpha = GetAdvancedValue(config, 'alpha', 1); -/***/ }), -/* 124 */ -/***/ (function(module, exports) { + // Origin + // Either: { origin: 0.5 } or { origin: { x: 0.5, y: 0.5 }} -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var origin = GetAdvancedValue(config, 'origin', null); -/** - * Check whether the given values are fuzzily equal. - * - * Two numbers are fuzzily equal if their difference is less than `epsilon`. - * - * @function Phaser.Math.Fuzzy.Equal - * @since 3.0.0 - * - * @param {number} a - The first value. - * @param {number} b - The second value. - * @param {number} [epsilon=0.0001] - The epsilon. - * - * @return {boolean} `true` if the values are fuzzily equal, otherwise `false`. - */ -var Equal = function (a, b, epsilon) -{ - if (epsilon === undefined) { epsilon = 0.0001; } + if (typeof origin === 'number') + { + gameObject.setOrigin(origin); + } + else if (origin !== null) + { + var ox = GetAdvancedValue(origin, 'x', 0.5); + var oy = GetAdvancedValue(origin, 'y', 0.5); - return Math.abs(a - b) < epsilon; + gameObject.setOrigin(ox, oy); + } + + // BlendMode + + gameObject.blendMode = GetAdvancedValue(config, 'blendMode', BlendModes.NORMAL); + + // Visible + + gameObject.visible = GetAdvancedValue(config, 'visible', true); + + // Add to Scene + + var add = GetAdvancedValue(config, 'add', true); + + if (add) + { + scene.sys.displayList.add(gameObject); + } + + if (gameObject.preUpdate) + { + scene.sys.updateList.add(gameObject); + } + + return gameObject; }; -module.exports = Equal; +module.exports = BuildGameObject; /***/ }), -/* 125 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 32291: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 ImageRender = __webpack_require__(1068); +var GetAdvancedValue = __webpack_require__(20494); /** - * @classdesc - * An Image Game Object. - * - * An Image is a light-weight Game Object useful for the display of static images in your game, - * such as logos, backgrounds, scenery or other non-animated elements. Images can have input - * events and physics bodies, or be tweened, tinted or scrolled. The main difference between an - * Image and a Sprite is that you cannot animate an Image as they do not have the Animation component. + * Adds an Animation component to a Sprite and populates it based on the given config. * - * @class Image - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor + * @function Phaser.GameObjects.BuildGameObjectAnimation * @since 3.0.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.GetBounds - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.TextureCrop - * @extends Phaser.GameObjects.Components.Tint - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.Visible + * @param {Phaser.GameObjects.Sprite} sprite - The sprite to add an Animation component to. + * @param {object} config - The animation config. * - * @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. + * @return {Phaser.GameObjects.Sprite} The updated Sprite. */ -var Image = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.Depth, - Components.Flip, - Components.GetBounds, - Components.Mask, - Components.Origin, - Components.Pipeline, - Components.ScrollFactor, - Components.Size, - Components.TextureCrop, - Components.Tint, - Components.Transform, - Components.Visible, - ImageRender - ], +var BuildGameObjectAnimation = function (sprite, config) +{ + var animConfig = GetAdvancedValue(config, 'anims', null); - initialize: + if (animConfig === null) + { + return sprite; + } - function Image (scene, x, y, texture, frame) + if (typeof animConfig === 'string') { - GameObject.call(this, scene, 'Image'); + // { 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] + // } + // } - /** - * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. - * - * @name Phaser.GameObjects.Image#_crop - * @type {object} - * @private - * @since 3.11.0 - */ - this._crop = this.resetCropObject(); + var anims = sprite.anims; - this.setTexture(texture, frame); - this.setPosition(x, y); - this.setSizeToFrame(); - this.setOriginFromFrame(); - this.initPipeline(); - } + var key = GetAdvancedValue(animConfig, 'key', undefined); -}); + if (key) + { + var startFrame = GetAdvancedValue(animConfig, 'startFrame', undefined); -module.exports = Image; + 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); -/***/ }), -/* 126 */ -/***/ (function(module, exports) { + var playConfig = { + key: key, + delay: delay, + repeat: repeat, + repeatDelay: repeatDelay, + yoyo: yoyo, + startFrame: startFrame + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (play) + { + anims.play(playConfig); + } + else if (delayedPlay > 0) + { + anims.playAfterDelay(playConfig, delayedPlay); + } + else + { + anims.load(playConfig); + } + } + } -/** - * Determine whether the source object has a property with the specified key. - * - * @function Phaser.Utils.Objects.HasValue - * @since 3.0.0 - * - * @param {object} source - The source object to be checked. - * @param {string} key - The property to check for within the object - * - * @return {boolean} `true` if the provided `key` exists on the `source` object, otherwise `false`. - */ -var HasValue = function (source, key) -{ - return (source.hasOwnProperty(key)); + return sprite; }; -module.exports = HasValue; +module.exports = BuildGameObjectAnimation; /***/ }), -/* 127 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 91713: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clone = __webpack_require__(77); +var Class = __webpack_require__(56694); +var List = __webpack_require__(71207); +var PluginCache = __webpack_require__(91963); +var GameObjectEvents = __webpack_require__(56631); +var SceneEvents = __webpack_require__(7599); +var StableSort = __webpack_require__(17922); /** - * Creates a new Object using all values from obj1 and obj2. - * If a value exists in both obj1 and obj2, the value in obj1 is used. - * - * This is only a shallow copy. Deeply nested objects are not cloned, so be sure to only use this - * function on shallow objects. + * @classdesc + * The Display List plugin. * - * @function Phaser.Utils.Objects.Merge - * @since 3.0.0 + * Display Lists belong to a Scene and maintain the list of Game Objects to render every frame. * - * @param {object} obj1 - The first object. - * @param {object} obj2 - The second object. + * Some of these Game Objects may also be part of the Scene's [Update List]{@link Phaser.GameObjects.UpdateList}, for updating. * - * @return {object} A new object containing the union of obj1's and obj2's properties. + * @class DisplayList + * @extends Phaser.Structs.List. + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene that this Display List belongs to. */ -var Merge = function (obj1, obj2) -{ - var clone = Clone(obj1); - - for (var key in obj2) - { - if (!clone.hasOwnProperty(key)) - { - clone[key] = obj2[key]; - } - } +var DisplayList = new Class({ - return clone; -}; + Extends: List, -module.exports = Merge; + initialize: + function DisplayList (scene) + { + List.call(this, scene); -/***/ }), -/* 128 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The flag the determines whether Game Objects should be sorted when `depthSort()` is called. + * + * @name Phaser.GameObjects.DisplayList#sortChildrenFlag + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.sortChildrenFlag = false; -/** -* The `Matter.Constraint` module contains methods for creating and manipulating constraints. -* Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position). -* The stiffness of constraints can be modified to create springs or elastic. -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Constraint -*/ + /** + * The Scene that this Display List belongs to. + * + * @name Phaser.GameObjects.DisplayList#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; -var Constraint = {}; + /** + * The Scene's Systems. + * + * @name Phaser.GameObjects.DisplayList#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.systems = scene.sys; -module.exports = Constraint; + /** + * The Scene's Event Emitter. + * + * @name Phaser.GameObjects.DisplayList#events + * @type {Phaser.Events.EventEmitter} + * @since 3.50.0 + */ + this.events = scene.sys.events; -var Vertices = __webpack_require__(64); -var Vector = __webpack_require__(83); -var Sleeping = __webpack_require__(165); -var Bounds = __webpack_require__(84); -var Axes = __webpack_require__(271); -var Common = __webpack_require__(32); + // Set the List callbacks + this.addCallback = this.addChildCallback; + this.removeCallback = this.removeChildCallback; -(function() { + this.events.once(SceneEvents.BOOT, this.boot, this); + this.events.on(SceneEvents.START, this.start, this); + }, - Constraint._warming = 0.4; - Constraint._torqueDampen = 1; - Constraint._minLength = 0.000001; + /** + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. + * + * @method Phaser.GameObjects.DisplayList#boot + * @private + * @since 3.5.1 + */ + boot: function () + { + this.events.once(SceneEvents.DESTROY, this.destroy, this); + }, /** - * Creates a new constraint. - * All properties have default values, and many are pre-calculated automatically based on other properties. - * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` value (e.g. `0.7` or above). - * If the constraint is unstable, try lowering the `stiffness` value and / or increasing `engine.constraintIterations`. - * For compound bodies, constraints must be applied to the parent body (not one of its parts). - * See the properties section below for detailed information on what you can pass via the `options` object. - * @method create - * @param {} options - * @return {constraint} constraint + * Internal method called from `List.addCallback`. + * + * @method Phaser.GameObjects.DisplayList#addChildCallback + * @private + * @fires Phaser.Scenes.Events#ADDED_TO_SCENE + * @fires Phaser.GameObjects.Events#ADDED_TO_SCENE + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the list. */ - Constraint.create = function(options) { - var constraint = options; + addChildCallback: function (gameObject) + { + if (gameObject.displayList && gameObject.displayList !== this) + { + gameObject.removeFromDisplayList(); + } - // if bodies defined but no points, use body centre - if (constraint.bodyA && !constraint.pointA) - constraint.pointA = { x: 0, y: 0 }; - if (constraint.bodyB && !constraint.pointB) - constraint.pointB = { x: 0, y: 0 }; + if (gameObject.parentContainer) + { + gameObject.parentContainer.remove(gameObject); + } - // calculate static length using initial world space points - var initialPointA = constraint.bodyA ? Vector.add(constraint.bodyA.position, constraint.pointA) : constraint.pointA, - initialPointB = constraint.bodyB ? Vector.add(constraint.bodyB.position, constraint.pointB) : constraint.pointB, - length = Vector.magnitude(Vector.sub(initialPointA, initialPointB)); - - constraint.length = typeof constraint.length !== 'undefined' ? constraint.length : length; + if (!gameObject.displayList) + { + this.queueDepthSort(); - // option defaults - constraint.id = constraint.id || Common.nextId(); - constraint.label = constraint.label || 'Constraint'; - constraint.type = 'constraint'; - constraint.stiffness = constraint.stiffness || (constraint.length > 0 ? 1 : 0.7); - constraint.damping = constraint.damping || 0; - constraint.angularStiffness = constraint.angularStiffness || 0; - constraint.angleA = constraint.bodyA ? constraint.bodyA.angle : constraint.angleA; - constraint.angleB = constraint.bodyB ? constraint.bodyB.angle : constraint.angleB; - constraint.plugin = {}; + gameObject.displayList = this; - // render - var render = { - visible: true, - type: 'line', - anchors: true, - lineColor: null, // custom Phaser property - lineOpacity: null, // custom Phaser property - lineThickness: null, // custom Phaser property - pinSize: null, // custom Phaser property - anchorColor: null, // custom Phaser property - anchorSize: null // custom Phaser property - }; + gameObject.emit(GameObjectEvents.ADDED_TO_SCENE, gameObject, this.scene); - if (constraint.length === 0 && constraint.stiffness > 0.1) { - render.type = 'pin'; - render.anchors = false; - } else if (constraint.stiffness < 0.9) { - render.type = 'spring'; + this.events.emit(SceneEvents.ADDED_TO_SCENE, gameObject, this.scene); } - - constraint.render = Common.extend(render, constraint.render); - - return constraint; - }; + }, /** - * Prepares for solving by constraint warming. + * Internal method called from `List.removeCallback`. + * + * @method Phaser.GameObjects.DisplayList#removeChildCallback * @private - * @method preSolveAll - * @param {body[]} bodies + * @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE + * @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the list. */ - Constraint.preSolveAll = function(bodies) { - for (var i = 0; i < bodies.length; i += 1) { - var body = bodies[i], - impulse = body.constraintImpulse; + removeChildCallback: function (gameObject) + { + this.queueDepthSort(); - if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) { - continue; - } + gameObject.displayList = null; - body.position.x += impulse.x; - body.position.y += impulse.y; - body.angle += impulse.angle; - } - }; + gameObject.emit(GameObjectEvents.REMOVED_FROM_SCENE, gameObject, this.scene); + + this.events.emit(SceneEvents.REMOVED_FROM_SCENE, gameObject, this.scene); + }, /** - * Solves all constraints in a list of collisions. + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. + * + * @method Phaser.GameObjects.DisplayList#start * @private - * @method solveAll - * @param {constraint[]} constraints - * @param {number} timeScale + * @since 3.5.0 */ - Constraint.solveAll = function(constraints, timeScale) { - // Solve fixed constraints first. - for (var i = 0; i < constraints.length; i += 1) { - var constraint = constraints[i], - fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic), - fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic); + start: function () + { + this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); + }, - if (fixedA || fixedB) { - Constraint.solve(constraints[i], timeScale); - } - } + /** + * Force a sort of the display list on the next call to depthSort. + * + * @method Phaser.GameObjects.DisplayList#queueDepthSort + * @since 3.0.0 + */ + queueDepthSort: function () + { + this.sortChildrenFlag = true; + }, - // Solve free constraints last. - for (i = 0; i < constraints.length; i += 1) { - constraint = constraints[i]; - fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic); - fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic); + /** + * Immediately sorts the display list if the flag is set. + * + * @method Phaser.GameObjects.DisplayList#depthSort + * @since 3.0.0 + */ + depthSort: function () + { + if (this.sortChildrenFlag) + { + StableSort(this.list, this.sortByDepth); - if (!fixedA && !fixedB) { - Constraint.solve(constraints[i], timeScale); - } + this.sortChildrenFlag = false; } - }; + }, /** - * Solves a distance constraint with Gauss-Siedel method. - * @private - * @method solve - * @param {constraint} constraint - * @param {number} timeScale + * Compare the depth of two Game Objects. + * + * @method Phaser.GameObjects.DisplayList#sortByDepth + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} childA - The first Game Object. + * @param {Phaser.GameObjects.GameObject} childB - The second Game Object. + * + * @return {number} The difference between the depths of each Game Object. */ - Constraint.solve = function(constraint, timeScale) { - var bodyA = constraint.bodyA, - bodyB = constraint.bodyB, - pointA = constraint.pointA, - pointB = constraint.pointB; + sortByDepth: function (childA, childB) + { + return childA._depth - childB._depth; + }, - if (!bodyA && !bodyB) - return; + /** + * Returns an array which contains all objects currently on the Display List. + * This is a reference to the main list array, not a copy of it, so be careful not to modify it. + * + * @method Phaser.GameObjects.DisplayList#getChildren + * @since 3.12.0 + * + * @return {Phaser.GameObjects.GameObject[]} The group members. + */ + getChildren: function () + { + return this.list; + }, - // update reference angle - if (bodyA && !bodyA.isStatic) { - Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA); - constraint.angleA = bodyA.angle; - } - - // update reference angle - if (bodyB && !bodyB.isStatic) { - Vector.rotate(pointB, bodyB.angle - constraint.angleB, pointB); - constraint.angleB = bodyB.angle; - } + /** + * The Scene that owns this plugin is shutting down. + * + * We need to kill and reset all internal properties as well as stop listening to Scene events. + * + * @method Phaser.GameObjects.DisplayList#shutdown + * @private + * @since 3.0.0 + */ + shutdown: function () + { + var list = this.list; - var pointAWorld = pointA, - pointBWorld = pointB; + while (list.length) + { + list[0].destroy(true); + } - if (bodyA) pointAWorld = Vector.add(bodyA.position, pointA); - if (bodyB) pointBWorld = Vector.add(bodyB.position, pointB); + this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); + }, - if (!pointAWorld || !pointBWorld) - return; + /** + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. + * + * @method Phaser.GameObjects.DisplayList#destroy + * @private + * @since 3.0.0 + */ + destroy: function () + { + this.shutdown(); - var delta = Vector.sub(pointAWorld, pointBWorld), - currentLength = Vector.magnitude(delta); + this.events.off(SceneEvents.START, this.start, this); - // prevent singularity - if (currentLength < Constraint._minLength) { - currentLength = Constraint._minLength; - } + this.scene = null; + this.systems = null; + this.events = null; + } - // solve distance constraint with Gauss-Siedel method - var difference = (currentLength - constraint.length) / currentLength, - stiffness = constraint.stiffness < 1 ? constraint.stiffness * timeScale : constraint.stiffness, - force = Vector.mult(delta, difference * stiffness), - massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0), - inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0), - resistanceTotal = massTotal + inertiaTotal, - torque, - share, - normal, - normalVelocity, - relativeVelocity; +}); - if (constraint.damping) { - var zero = Vector.create(); - normal = Vector.div(delta, currentLength); +PluginCache.register('DisplayList', DisplayList, 'displayList'); - relativeVelocity = Vector.sub( - bodyB && Vector.sub(bodyB.position, bodyB.positionPrev) || zero, - bodyA && Vector.sub(bodyA.position, bodyA.positionPrev) || zero - ); +module.exports = DisplayList; - normalVelocity = Vector.dot(normal, relativeVelocity); - } - if (bodyA && !bodyA.isStatic) { - share = bodyA.inverseMass / massTotal; +/***/ }), - // keep track of applied impulses for post solving - bodyA.constraintImpulse.x -= force.x * share; - bodyA.constraintImpulse.y -= force.y * share; +/***/ 89980: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // apply forces - bodyA.position.x -= force.x * share; - bodyA.position.y -= force.y * share; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // apply damping - if (constraint.damping) { - bodyA.positionPrev.x -= constraint.damping * normal.x * normalVelocity * share; - bodyA.positionPrev.y -= constraint.damping * normal.y * normalVelocity * share; - } +var Class = __webpack_require__(56694); +var ComponentsToJSON = __webpack_require__(48129); +var DataManager = __webpack_require__(81078); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(56631); +var SceneEvents = __webpack_require__(7599); - // apply torque - torque = (Vector.cross(pointA, force) / resistanceTotal) * Constraint._torqueDampen * bodyA.inverseInertia * (1 - constraint.angularStiffness); - bodyA.constraintImpulse.angle -= torque; - bodyA.angle -= torque; - } - - if (bodyB && !bodyB.isStatic) { - share = bodyB.inverseMass / massTotal; +/** + * @classdesc + * The base class that all Game Objects extend. + * You don't create GameObjects directly and they cannot be added to the display list. + * Instead, use them as the base for your own custom classes. + * + * @class GameObject + * @memberof Phaser.GameObjects + * @extends Phaser.Events.EventEmitter + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. + * @param {string} type - A textual representation of the type of Game Object, i.e. `sprite`. + */ +var GameObject = new Class({ - // keep track of applied impulses for post solving - bodyB.constraintImpulse.x += force.x * share; - bodyB.constraintImpulse.y += force.y * share; - - // apply forces - bodyB.position.x += force.x * share; - bodyB.position.y += force.y * share; + Extends: EventEmitter, - // apply damping - if (constraint.damping) { - bodyB.positionPrev.x += constraint.damping * normal.x * normalVelocity * share; - bodyB.positionPrev.y += constraint.damping * normal.y * normalVelocity * share; - } + initialize: - // apply torque - torque = (Vector.cross(pointB, force) / resistanceTotal) * Constraint._torqueDampen * bodyB.inverseInertia * (1 - constraint.angularStiffness); - bodyB.constraintImpulse.angle += torque; - bodyB.angle += torque; - } + function GameObject (scene, type) + { + EventEmitter.call(this); - }; + /** + * A reference to the Scene to which this Game Object belongs. + * + * Game Objects can only belong to one Scene. + * + * You should consider this property as being read-only. You cannot move a + * Game Object to another Scene by simply changing it. + * + * @name Phaser.GameObjects.GameObject#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - /** - * Performs body updates required after solving constraints. - * @private - * @method postSolveAll - * @param {body[]} bodies - */ - Constraint.postSolveAll = function(bodies) { - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i], - impulse = body.constraintImpulse; + /** + * Holds a reference to the Display List that contains this Game Object. + * + * This is set automatically when this Game Object is added to a Scene or Layer. + * + * You should treat this property as being read-only. + * + * @name Phaser.GameObjects.GameObject#displayList + * @type {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} + * @default null + * @since 3.50.0 + */ + this.displayList = null; - if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) { - continue; - } + /** + * A textual representation of this Game Object, i.e. `sprite`. + * Used internally by Phaser but is available for your own custom classes to populate. + * + * @name Phaser.GameObjects.GameObject#type + * @type {string} + * @since 3.0.0 + */ + this.type = type; - Sleeping.set(body, false); + /** + * The current state of this Game Object. + * + * Phaser itself will never modify this value, although plugins may do so. + * + * Use this property to track the state of a Game Object during its lifetime. For example, it could change from + * a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant + * in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons. + * If you need to store complex data about your Game Object, look at using the Data Component instead. + * + * @name Phaser.GameObjects.GameObject#state + * @type {(number|string)} + * @since 3.16.0 + */ + this.state = 0; - // update geometry and reset - for (var j = 0; j < body.parts.length; j++) { - var part = body.parts[j]; - - Vertices.translate(part.vertices, impulse); + /** + * The parent Container of this Game Object, if it has one. + * + * @name Phaser.GameObjects.GameObject#parentContainer + * @type {Phaser.GameObjects.Container} + * @since 3.4.0 + */ + this.parentContainer = null; - if (j > 0) { - part.position.x += impulse.x; - part.position.y += impulse.y; - } + /** + * The name of this Game Object. + * Empty by default and never populated by Phaser, this is left for developers to use. + * + * @name Phaser.GameObjects.GameObject#name + * @type {string} + * @default '' + * @since 3.0.0 + */ + this.name = ''; - if (impulse.angle !== 0) { - Vertices.rotate(part.vertices, impulse.angle, body.position); - Axes.rotate(part.axes, impulse.angle); - if (j > 0) { - Vector.rotateAbout(part.position, impulse.angle, body.position, part.position); - } - } + /** + * The active state of this Game Object. + * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it. + * An active object is one which is having its logic and internal systems updated. + * + * @name Phaser.GameObjects.GameObject#active + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.active = true; - Bounds.update(part.bounds, part.vertices, body.velocity); - } + /** + * The Tab Index of the Game Object. + * Reserved for future use by plugins and the Input Manager. + * + * @name Phaser.GameObjects.GameObject#tabIndex + * @type {number} + * @default -1 + * @since 3.0.0 + */ + this.tabIndex = -1; - // dampen the cached impulse for warming next step - impulse.angle *= Constraint._warming; - impulse.x *= Constraint._warming; - impulse.y *= Constraint._warming; - } - }; + /** + * A Data Manager. + * It allows you to store, query and get key/value paired information specific to this Game Object. + * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`. + * + * @name Phaser.GameObjects.GameObject#data + * @type {Phaser.Data.DataManager} + * @default null + * @since 3.0.0 + */ + this.data = null; - /** - * Returns the world-space position of `constraint.pointA`, accounting for `constraint.bodyA`. - * @method pointAWorld - * @param {constraint} constraint - * @returns {vector} the world-space position - */ - Constraint.pointAWorld = function(constraint) { - return { - x: (constraint.bodyA ? constraint.bodyA.position.x : 0) + constraint.pointA.x, - y: (constraint.bodyA ? constraint.bodyA.position.y : 0) + constraint.pointA.y - }; - }; + /** + * 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; - /** - * Returns the world-space position of `constraint.pointB`, accounting for `constraint.bodyB`. - * @method pointBWorld - * @param {constraint} constraint - * @returns {vector} the world-space position - */ - Constraint.pointBWorld = function(constraint) { - return { - x: (constraint.bodyB ? constraint.bodyB.position.x : 0) + constraint.pointB.x, - y: (constraint.bodyB ? constraint.bodyB.position.y : 0) + constraint.pointB.y - }; - }; + /** + * 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; - /* - * - * Properties Documentation - * - */ + /** + * If this Game Object is enabled for input then this property will contain an InteractiveObject instance. + * Not usually set directly. Instead call `GameObject.setInteractive()`. + * + * @name Phaser.GameObjects.GameObject#input + * @type {?Phaser.Types.Input.InteractiveObject} + * @default null + * @since 3.0.0 + */ + this.input = null; - /** - * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`. - * - * @property id - * @type number - */ + /** + * If this Game Object is enabled for Arcade or Matter Physics then this property will contain a reference to a Physics Body. + * + * @name Phaser.GameObjects.GameObject#body + * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|MatterJS.BodyType)} + * @default null + * @since 3.0.0 + */ + this.body = null; - /** - * A `String` denoting the type of object. - * - * @property type - * @type string - * @default "constraint" - * @readOnly - */ + /** + * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`. + * This includes calls that may come from a Group, Container or the Scene itself. + * While it allows you to persist a Game Object across Scenes, please understand you are entirely + * responsible for managing references to and from this Game Object. + * + * @name Phaser.GameObjects.GameObject#ignoreDestroy + * @type {boolean} + * @default false + * @since 3.5.0 + */ + this.ignoreDestroy = false; - /** - * An arbitrary `String` name to help the user identify and manage bodies. - * - * @property label - * @type string - * @default "Constraint" - */ + this.on(Events.ADDED_TO_SCENE, this.addedToScene, this); + this.on(Events.REMOVED_FROM_SCENE, this.removedFromScene, this); - /** - * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`. - * - * @property render - * @type object - */ + // Tell the Scene to re-sort the children + scene.sys.queueDepthSort(); + }, /** - * A flag that indicates if the constraint should be rendered. + * Sets the `active` property of this Game Object and returns this Game Object for further chaining. + * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList. * - * @property render.visible - * @type boolean - * @default true - */ - - /** - * A `Number` that defines the line width to use when rendering the constraint outline. - * A value of `0` means no outline will be rendered. + * @method Phaser.GameObjects.GameObject#setActive + * @since 3.0.0 * - * @property render.lineWidth - * @type number - * @default 2 - */ - - /** - * A `String` that defines the stroke style to use when rendering the constraint outline. - * It is the same as when using a canvas, so it accepts CSS style property values. + * @param {boolean} value - True if this Game Object should be set as active, false if not. * - * @property render.strokeStyle - * @type string - * @default a random colour + * @return {this} This GameObject. */ + setActive: function (value) + { + this.active = value; - /** - * A `String` that defines the constraint rendering type. - * The possible values are 'line', 'pin', 'spring'. - * An appropriate render type will be automatically chosen unless one is given in options. - * - * @property render.type - * @type string - * @default 'line' - */ + return this; + }, /** - * A `Boolean` that defines if the constraint's anchor points should be rendered. + * Sets the `name` property of this Game Object and returns this Game Object for further chaining. + * The `name` property is not populated by Phaser and is presented for your own use. * - * @property render.anchors - * @type boolean - * @default true - */ - - /** - * The first possible `Body` that this constraint is attached to. + * @method Phaser.GameObjects.GameObject#setName + * @since 3.0.0 * - * @property bodyA - * @type body - * @default null - */ - - /** - * The second possible `Body` that this constraint is attached to. + * @param {string} value - The name to be given to this Game Object. * - * @property bodyB - * @type body - * @default null + * @return {this} This GameObject. */ + setName: function (value) + { + this.name = value; - /** - * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyA` if defined, otherwise a world-space position. - * - * @property pointA - * @type vector - * @default { x: 0, y: 0 } - */ + return this; + }, /** - * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyB` if defined, otherwise a world-space position. + * Sets the current state of this Game Object. * - * @property pointB - * @type vector - * @default { x: 0, y: 0 } - */ - - /** - * A `Number` that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. - * A value of `1` means the constraint should be very stiff. - * A value of `0.2` means the constraint acts like a soft spring. + * Phaser itself will never modify the State of a Game Object, although plugins may do so. * - * @property stiffness - * @type number - * @default 1 - */ - - /** - * A `Number` that specifies the damping of the constraint, - * i.e. the amount of resistance applied to each body based on their velocities to limit the amount of oscillation. - * Damping will only be apparent when the constraint also has a very low `stiffness`. - * A value of `0.1` means the constraint will apply heavy damping, resulting in little to no oscillation. - * A value of `0` means the constraint will apply no damping. + * For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'. + * The state value should typically be an integer (ideally mapped to a constant + * in your game code), but could also be a string. It is recommended to keep it light and simple. + * If you need to store complex data about your Game Object, look at using the Data Component instead. * - * @property damping - * @type number - * @default 0 - */ - - /** - * A `Number` that specifies the target resting length of the constraint. - * It is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. + * @method Phaser.GameObjects.GameObject#setState + * @since 3.16.0 * - * @property length - * @type number - */ - - /** - * An object reserved for storing plugin-specific properties. + * @param {(number|string)} value - The state of the Game Object. * - * @property plugin - * @type {} + * @return {this} This GameObject. */ - -})(); - - -/***/ }), -/* 129 */ -/***/ (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__(35); -var Circle = __webpack_require__(65); -var CircleContains = __webpack_require__(66); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var GameObject = __webpack_require__(15); -var Rectangle = __webpack_require__(10); -var RectangleContains = __webpack_require__(57); - -/** - * @classdesc - * A Zone Game Object. - * - * A Zone is a non-rendering rectangular Game Object that has a position and size. - * It has no texture and never displays, but does live on the display list and - * can be moved, scaled and rotated like any other Game Object. - * - * Its primary use is for creating Drop Zones and Input Hit Areas and it has a couple of helper methods - * specifically for this. It is also useful for object overlap checks, or as a base for your own - * non-displaying Game Objects. - - * The default origin is 0.5, the center of the Zone, the same as with Game Objects. - * - * @class Zone - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Visible - * - * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. - * @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=1] - The width of the Game Object. - * @param {number} [height=1] - The height of the Game Object. - */ -var Zone = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Depth, - Components.GetBounds, - Components.Origin, - Components.Transform, - Components.ScrollFactor, - Components.Visible - ], - - initialize: - - function Zone (scene, x, y, width, height) + setState: function (value) { - if (width === undefined) { width = 1; } - if (height === undefined) { height = width; } - - GameObject.call(this, scene, 'Zone'); - - this.setPosition(x, y); - - /** - * The native (un-scaled) width of this Game Object. - * - * @name Phaser.GameObjects.Zone#width - * @type {number} - * @since 3.0.0 - */ - this.width = width; - - /** - * The native (un-scaled) height of this Game Object. - * - * @name Phaser.GameObjects.Zone#height - * @type {number} - * @since 3.0.0 - */ - this.height = height; - - /** - * The Blend Mode of the Game Object. - * Although a Zone never renders, it still has a blend mode to allow it to fit seamlessly into - * display lists without causing a batch flush. - * - * @name Phaser.GameObjects.Zone#blendMode - * @type {number} - * @since 3.0.0 - */ - this.blendMode = BlendModes.NORMAL; + this.state = value; - this.updateDisplayOrigin(); + return this; }, /** - * The displayed width of this Game Object. - * This value takes into account the scale factor. + * Adds a Data Manager component to this Game Object. * - * @name Phaser.GameObjects.Zone#displayWidth - * @type {number} + * @method Phaser.GameObjects.GameObject#setDataEnabled * @since 3.0.0 + * @see Phaser.Data.DataManager + * + * @return {this} This GameObject. */ - displayWidth: { - - get: function () - { - return this.scaleX * this.width; - }, - - set: function (value) + setDataEnabled: function () + { + if (!this.data) { - this.scaleX = value / this.width; + this.data = new DataManager(this); } + return this; }, /** - * The displayed height of this Game Object. - * This value takes into account the scale factor. + * Allows you to store a key value pair within this Game Objects Data Manager. * - * @name Phaser.GameObjects.Zone#displayHeight - * @type {number} + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. + * + * If the key doesn't already exist in the Data Manager then it is created. + * + * ```javascript + * sprite.setData('name', 'Red Gem Stone'); + * ``` + * + * You can also pass in an object of key value pairs as the first argument: + * + * ```javascript + * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); + * ``` + * + * To get a value back again you can call `getData`: + * + * ```javascript + * sprite.getData('gold'); + * ``` + * + * Or you can access the value directly via the `values` property, where it works like any other variable: + * + * ```javascript + * sprite.data.values.gold += 50; + * ``` + * + * When the value is first set, a `setdata` event is emitted from this Game Object. + * + * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. + * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. + * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. + * + * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. + * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. + * + * @method Phaser.GameObjects.GameObject#setData * @since 3.0.0 + * + * @generic {any} T + * @genericUse {(string|T)} - [key] + * + * @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. + * @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored. + * + * @return {this} This GameObject. */ - displayHeight: { - - get: function () - { - return this.scaleY * this.height; - }, - - set: function (value) + setData: function (key, value) + { + if (!this.data) { - this.scaleY = value / this.height; + this.data = new DataManager(this); } + this.data.set(key, value); + + return this; }, /** - * Sets the size of this Game Object. + * Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0. * - * @method Phaser.GameObjects.Zone#setSize - * @since 3.0.0 + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. * - * @param {number} width - The width of this Game Object. - * @param {number} height - The height of this Game Object. - * @param {boolean} [resizeInput=true] - If this Zone has a Rectangle for a hit area this argument will resize the hit area as well. + * If the key doesn't already exist in the Data Manager then it is created. * - * @return {this} This Game Object. + * When the value is first set, a `setdata` event is emitted from this Game Object. + * + * @method Phaser.GameObjects.GameObject#incData + * @since 3.23.0 + * + * @generic {any} T + * @genericUse {(string|T)} - [key] + * + * @param {(string|object)} key - The key to increase the value for. + * @param {*} [data] - The value to increase for the given key. + * + * @return {this} This GameObject. */ - setSize: function (width, height, resizeInput) + incData: function (key, value) { - if (resizeInput === undefined) { resizeInput = true; } - - this.width = width; - this.height = height; + if (!this.data) + { + this.data = new DataManager(this); + } - this.updateDisplayOrigin(); + this.data.inc(key, value); - var input = this.input; + return this; + }, - if (resizeInput && input && !input.customHitArea) + /** + * Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false. + * + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. + * + * If the key doesn't already exist in the Data Manager then it is created. + * + * When the value is first set, a `setdata` event is emitted from this Game Object. + * + * @method Phaser.GameObjects.GameObject#toggleData + * @since 3.23.0 + * + * @generic {any} T + * @genericUse {(string|T)} - [key] + * + * @param {(string|object)} key - The key to toggle the value for. + * + * @return {this} This GameObject. + */ + toggleData: function (key) + { + if (!this.data) { - input.hitArea.width = width; - input.hitArea.height = height; + this.data = new DataManager(this); } + this.data.toggle(key); + return this; }, /** - * Sets the display size of this Game Object. - * Calling this will adjust the scale. + * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist. * - * @method Phaser.GameObjects.Zone#setDisplaySize + * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: + * + * ```javascript + * sprite.getData('gold'); + * ``` + * + * Or access the value directly: + * + * ```javascript + * sprite.data.values.gold; + * ``` + * + * You can also pass in an array of keys, in which case an array of values will be returned: + * + * ```javascript + * sprite.getData([ 'gold', 'armor', 'health' ]); + * ``` + * + * This approach is useful for destructuring arrays in ES6. + * + * @method Phaser.GameObjects.GameObject#getData * @since 3.0.0 * - * @param {number} width - The width of this Game Object. - * @param {number} height - The height of this Game Object. + * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys. * - * @return {this} This Game Object. + * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array. */ - setDisplaySize: function (width, height) + getData: function (key) { - this.displayWidth = width; - this.displayHeight = height; + if (!this.data) + { + this.data = new DataManager(this); + } - return this; + return this.data.get(key); }, /** - * Sets this Zone to be a Circular Drop Zone. - * The circle is centered on this Zones `x` and `y` coordinates. + * Pass this Game Object to the Input Manager to enable it for Input. * - * @method Phaser.GameObjects.Zone#setCircleDropZone + * Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area + * for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced + * input detection. + * + * If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If + * this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific + * shape for it to use. + * + * You can also provide an Input Configuration Object as the only argument to this method. + * + * @example + * sprite.setInteractive(); + * + * @example + * sprite.setInteractive(new Phaser.Geom.Circle(45, 46, 45), Phaser.Geom.Circle.Contains); + * + * @example + * graphics.setInteractive(new Phaser.Geom.Rectangle(0, 0, 128, 128), Phaser.Geom.Rectangle.Contains); + * + * @method Phaser.GameObjects.GameObject#setInteractive * @since 3.0.0 * - * @param {number} radius - The radius of the Circle that will form the Drop Zone. + * @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not given it will try to create a Rectangle based on the texture frame. + * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The callback that determines if the pointer is within the Hit Area shape or not. If you provide a shape you must also provide a callback. + * @param {boolean} [dropZone=false] - Should this Game Object be treated as a drop zone target? * - * @return {this} This Game Object. + * @return {this} This GameObject. */ - setCircleDropZone: function (radius) + setInteractive: function (hitArea, hitAreaCallback, dropZone) { - return this.setDropZone(new Circle(0, 0, radius), CircleContains); + this.scene.sys.input.enable(this, hitArea, hitAreaCallback, dropZone); + + return this; }, /** - * Sets this Zone to be a Rectangle Drop Zone. - * The rectangle is centered on this Zones `x` and `y` coordinates. + * If this Game Object has previously been enabled for input, this will disable it. * - * @method Phaser.GameObjects.Zone#setRectangleDropZone - * @since 3.0.0 + * An object that is disabled for input stops processing or being considered for + * input events, but can be turned back on again at any time by simply calling + * `setInteractive()` with no arguments provided. * - * @param {number} width - The width of the rectangle drop zone. - * @param {number} height - The height of the rectangle drop zone. + * If want to completely remove interaction from this Game Object then use `removeInteractive` instead. * - * @return {this} This Game Object. + * @method Phaser.GameObjects.GameObject#disableInteractive + * @since 3.7.0 + * + * @return {this} This GameObject. */ - setRectangleDropZone: function (width, height) + disableInteractive: function () { - return this.setDropZone(new Rectangle(0, 0, width, height), RectangleContains); + this.scene.sys.input.disable(this); + + return this; }, /** - * Allows you to define your own Geometry shape to be used as a Drop Zone. + * If this Game Object has previously been enabled for input, this will queue it + * for removal, causing it to no longer be interactive. The removal happens on + * the next game step, it is not immediate. * - * @method Phaser.GameObjects.Zone#setDropZone - * @since 3.0.0 + * The Interactive Object that was assigned to this Game Object will be destroyed, + * removed from the Input Manager and cleared from this Game Object. * - * @param {object} hitArea - A Geometry shape instance, such as Phaser.Geom.Ellipse, or your own custom shape. - * @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - A function that will return `true` if the given x/y coords it is sent are within the shape. + * If you wish to re-enable this Game Object at a later date you will need to + * re-create its InteractiveObject by calling `setInteractive` again. * - * @return {this} This Game Object. + * If you wish to only temporarily stop an object from receiving input then use + * `disableInteractive` instead, as that toggles the interactive state, where-as + * this erases it completely. + * + * If you wish to resize a hit area, don't remove and then set it as being + * interactive. Instead, access the hitarea object directly and resize the shape + * being used. I.e.: `sprite.input.hitArea.setSize(width, height)` (assuming the + * shape is a Rectangle, which it is by default.) + * + * @method Phaser.GameObjects.GameObject#removeInteractive + * @since 3.7.0 + * + * @return {this} This GameObject. */ - setDropZone: function (hitArea, hitAreaCallback) + removeInteractive: function () { - if (hitArea === undefined) - { - this.setRectangleDropZone(this.width, this.height); - } - else if (!this.input) - { - this.setInteractive(hitArea, hitAreaCallback, true); - } + this.scene.sys.input.clear(this); + + this.input = undefined; return this; }, /** - * A NOOP method so you can pass a Zone to a Container. - * Calling this method will do nothing. It is intentionally empty. + * This callback is invoked when this Game Object is added to a Scene. * - * @method Phaser.GameObjects.Zone#setAlpha - * @private - * @since 3.11.0 + * Can be overriden by custom Game Objects, but be aware of some Game Objects that + * will use this, such as Sprites, to add themselves into the Update List. + * + * You can also listen for the `ADDED_TO_SCENE` event from this Game Object. + * + * @method Phaser.GameObjects.GameObject#addedToScene + * @since 3.50.0 */ - setAlpha: function () + addedToScene: function () { }, /** - * A NOOP method so you can pass a Zone to a Container in Canvas. - * Calling this method will do nothing. It is intentionally empty. + * This callback is invoked when this Game Object is removed from a Scene. * - * @method Phaser.GameObjects.Zone#setBlendMode - * @private - * @since 3.16.2 + * Can be overriden by custom Game Objects, but be aware of some Game Objects that + * will use this, such as Sprites, to removed themselves from the Update List. + * + * You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object. + * + * @method Phaser.GameObjects.GameObject#removedFromScene + * @since 3.50.0 */ - setBlendMode: function () + removedFromScene: function () { }, /** - * A Zone does not render. + * To be overridden by custom GameObjects. Allows base objects to be used in a Pool. * - * @method Phaser.GameObjects.Zone#renderCanvas - * @private - * @since 3.53.0 + * @method Phaser.GameObjects.GameObject#update + * @since 3.0.0 * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Image} 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 {...*} [args] - args */ - renderCanvas: function (renderer, src, camera) + update: function () { - camera.addToRenderList(src); }, /** - * A Zone does not render. + * Returns a JSON representation of the Game Object. * - * @method Phaser.GameObjects.Zone#renderWebGL - * @private - * @since 3.53.0 + * @method Phaser.GameObjects.GameObject#toJSON + * @since 3.0.0 * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Image} 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 + * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object. */ - renderWebGL: function (renderer, src, camera) + toJSON: function () { - camera.addToRenderList(src); - } - -}); + return ComponentsToJSON(this); + }, -module.exports = Zone; + /** + * Compares the renderMask with the renderFlags to see if this Game Object will render or not. + * Also checks the Game Object against the given Cameras exclusion list. + * + * @method Phaser.GameObjects.GameObject#willRender + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object. + * + * @return {boolean} True if the Game Object should be rendered, otherwise false. + */ + willRender: function (camera) + { + var listWillRender = (this.displayList && this.displayList.active) ? this.displayList.willRender(camera) : true; + return !(!listWillRender || GameObject.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); + }, -/***/ }), -/* 130 */ -/***/ (function(module, exports) { + /** + * Returns an array containing the display list index of either this Game Object, or if it has one, + * its parent Container. It then iterates up through all of the parent containers until it hits the + * root of the display list (which is index 0 in the returned array). + * + * Used internally by the InputPlugin but also useful if you wish to find out the display depth of + * this Game Object and all of its ancestors. + * + * @method Phaser.GameObjects.GameObject#getIndexList + * @since 3.4.0 + * + * @return {number[]} An array of display list position indexes. + */ + getIndexList: function () + { + // eslint-disable-next-line consistent-this + var child = this; + var parent = this.parentContainer; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var indexes = []; -/** - * Calculates the perimeter of a Rectangle. - * - * @function Phaser.Geom.Rectangle.Perimeter - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to use. - * - * @return {number} The perimeter of the Rectangle, equal to `(width * 2) + (height * 2)`. - */ -var Perimeter = function (rect) -{ - return 2 * (rect.width + rect.height); -}; + while (parent) + { + indexes.unshift(parent.getIndex(child)); -module.exports = Perimeter; + child = parent; + if (!parent.parentContainer) + { + break; + } + else + { + parent = parent.parentContainer; + } + } -/***/ }), -/* 131 */ -/***/ (function(module, exports) { + if (this.displayList) + { + indexes.unshift(this.displayList.getIndex(child)); + } + else + { + indexes.unshift(this.scene.sys.displayList.getIndex(child)); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return indexes; + }, -/** - * Shuffles the contents of the given array using the Fisher-Yates implementation. - * - * The original array is modified directly and returned. - * - * @function Phaser.Utils.Array.Shuffle - * @since 3.0.0 - * - * @generic T - * @genericUse {T[]} - [array,$return] - * - * @param {T[]} array - The array to shuffle. This array is modified in place. - * - * @return {T[]} The shuffled array. - */ -var Shuffle = function (array) -{ - for (var i = array.length - 1; i > 0; i--) + /** + * Adds this Game Object to the given Display List. + * + * If no Display List is specified, it will default to the Display List owned by the Scene to which + * this Game Object belongs. + * + * A Game Object can only exist on one Display List at any given time, but may move freely between them. + * + * If this Game Object is already on another Display List when this method is called, it will first + * be removed from it, before being added to the new list. + * + * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. + * + * If a Game Object isn't on any display list, it will not be rendered. If you just wish to temporarly + * disable it from rendering, consider using the `setVisible` method, instead. + * + * @method Phaser.GameObjects.GameObject#addToDisplayList + * @fires Phaser.Scenes.Events#ADDED_TO_SCENE + * @fires Phaser.GameObjects.Events#ADDED_TO_SCENE + * @since 3.53.0 + * + * @param {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} [displayList] - The Display List to add to. Defaults to the Scene Display List. + * + * @return {this} This Game Object. + */ + addToDisplayList: function (displayList) { - var j = Math.floor(Math.random() * (i + 1)); - var temp = array[i]; - array[i] = array[j]; - array[j] = temp; - } - - return array; -}; - -module.exports = Shuffle; - + if (displayList === undefined) { displayList = this.scene.sys.displayList; } -/***/ }), -/* 132 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.displayList && this.displayList !== displayList) + { + this.removeFromDisplayList(); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Don't repeat if it's already on this list + if (!displayList.exists(this)) + { + this.displayList = displayList; -/** - * @namespace Phaser.Animations.Events - */ + displayList.add(this, true); -module.exports = { + displayList.queueDepthSort(); - ADD_ANIMATION: __webpack_require__(724), - ANIMATION_COMPLETE: __webpack_require__(725), - ANIMATION_COMPLETE_KEY: __webpack_require__(726), - ANIMATION_REPEAT: __webpack_require__(727), - ANIMATION_RESTART: __webpack_require__(728), - ANIMATION_START: __webpack_require__(729), - ANIMATION_STOP: __webpack_require__(730), - ANIMATION_UPDATE: __webpack_require__(731), - PAUSE_ALL: __webpack_require__(732), - REMOVE_ANIMATION: __webpack_require__(733), - RESUME_ALL: __webpack_require__(734) + this.emit(Events.ADDED_TO_SCENE, this, this.scene); -}; + displayList.events.emit(SceneEvents.ADDED_TO_SCENE, this, this.scene); + } + return this; + }, -/***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Adds this Game Object to the Update List belonging to the Scene. + * + * When a Game Object is added to the Update List it will have its `preUpdate` method called + * every game frame. This method is passed two parameters: `delta` and `time`. + * + * If you wish to run your own logic within `preUpdate` then you should always call + * `super.preUpdate(delta, time)` within it, or it may fail to process required operations, + * such as Sprite animations. + * + * @method Phaser.GameObjects.GameObject#addToUpdateList + * @since 3.53.0 + * + * @return {this} This Game Object. + */ + addToUpdateList: function () + { + if (this.scene && this.preUpdate) + { + this.scene.sys.updateList.add(this); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var DegToRad = __webpack_require__(36); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(37); -var Rectangle = __webpack_require__(10); -var TransformMatrix = __webpack_require__(25); -var ValueToColor = __webpack_require__(187); -var Vector2 = __webpack_require__(3); + /** + * Removes this Game Object from the Display List it is currently on. + * + * A Game Object can only exist on one Display List at any given time, but may move freely removed + * and added back at a later stage. + * + * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. + * + * If a Game Object isn't on any Display List, it will not be rendered. If you just wish to temporarly + * disable it from rendering, consider using the `setVisible` method, instead. + * + * @method Phaser.GameObjects.GameObject#removeFromDisplayList + * @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE + * @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE + * @since 3.53.0 + * + * @return {this} This Game Object. + */ + removeFromDisplayList: function () + { + var displayList = this.displayList || this.scene.sys.displayList; -/** - * @classdesc - * A Base Camera class. - * - * The Camera is the way in which all games are rendered in Phaser. They provide a view into your game world, - * and can be positioned, rotated, zoomed and scrolled accordingly. - * - * A Camera consists of two elements: The viewport and the scroll values. - * - * The viewport is the physical position and size of the Camera within your game. Cameras, by default, are - * created the same size as your game, but their position and size can be set to anything. This means if you - * wanted to create a camera that was 320x200 in size, positioned in the bottom-right corner of your game, - * you'd adjust the viewport to do that (using methods like `setViewport` and `setSize`). - * - * If you wish to change where the Camera is looking in your game, then you scroll it. You can do this - * via the properties `scrollX` and `scrollY` or the method `setScroll`. Scrolling has no impact on the - * viewport, and changing the viewport has no impact on the scrolling. - * - * By default a Camera will render all Game Objects it can see. You can change this using the `ignore` method, - * allowing you to filter Game Objects out on a per-Camera basis. - * - * The Base Camera is extended by the Camera class, which adds in special effects including Fade, - * Flash and Camera Shake, as well as the ability to follow Game Objects. - * - * The Base Camera was introduced in Phaser 3.12. It was split off from the Camera class, to allow - * you to isolate special effects as needed. Therefore the 'since' values for properties of this class relate - * to when they were added to the Camera class. - * - * @class BaseCamera - * @memberof Phaser.Cameras.Scene2D - * @constructor - * @since 3.12.0 - * - * @extends Phaser.Events.EventEmitter - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.Visible - * - * @param {number} x - The x position of the Camera, relative to the top-left of the game canvas. - * @param {number} y - The y position of the Camera, relative to the top-left of the game canvas. - * @param {number} width - The width of the Camera, in pixels. - * @param {number} height - The height of the Camera, in pixels. - */ -var BaseCamera = new Class({ + if (displayList && displayList.exists(this)) + { + displayList.remove(this, true); - Extends: EventEmitter, + displayList.queueDepthSort(); - Mixins: [ - Components.Alpha, - Components.Visible - ], + this.displayList = null; - initialize: + this.emit(Events.REMOVED_FROM_SCENE, this, this.scene); - function BaseCamera (x, y, width, height) + displayList.events.emit(SceneEvents.REMOVED_FROM_SCENE, this, this.scene); + } + + return this; + }, + + /** + * Removes this Game Object from the Scene's Update List. + * + * When a Game Object is on the Update List, it will have its `preUpdate` method called + * every game frame. Calling this method will remove it from the list, preventing this. + * + * Removing a Game Object from the Update List will stop most internal functions working. + * For example, removing a Sprite from the Update List will prevent it from being able to + * run animations. + * + * @method Phaser.GameObjects.GameObject#removeFromUpdateList + * @since 3.53.0 + * + * @return {this} This Game Object. + */ + removeFromUpdateList: function () { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 0; } - if (height === undefined) { height = 0; } + if (this.scene && this.preUpdate) + { + this.scene.sys.updateList.remove(this); + } - EventEmitter.call(this); + return this; + }, - /** - * A reference to the Scene this camera belongs to. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene; + /** + * Destroys this Game Object removing it from the Display List and Update List and + * severing all ties to parent resources. + * + * Also removes itself from the Input Manager and Physics Manager if previously enabled. + * + * Use this to remove a Game Object from your game if you don't ever plan to use it again. + * As long as no reference to it exists within your own code it should become free for + * garbage collection by the browser. + * + * If you just want to temporarily disable an object then look at using the + * Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected. + * + * @method Phaser.GameObjects.GameObject#destroy + * @fires Phaser.GameObjects.Events#DESTROY + * @since 3.0.0 + * + * @param {boolean} [fromScene=false] - `True` if this Game Object is being destroyed by the Scene, `false` if not. + */ + destroy: function (fromScene) + { + // This Game Object has already been destroyed + if (!this.scene || this.ignoreDestroy) + { + return; + } - /** - * A reference to the Game Scene Manager. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#sceneManager - * @type {Phaser.Scenes.SceneManager} - * @since 3.12.0 - */ - this.sceneManager; + if (fromScene === undefined) { fromScene = false; } - /** - * A reference to the Game Scale Manager. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#scaleManager - * @type {Phaser.Scale.ScaleManager} - * @since 3.16.0 - */ - this.scaleManager; + if (this.preDestroy) + { + this.preDestroy.call(this); + } - /** - * A reference to the Scene's Camera Manager to which this Camera belongs. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#cameraManager - * @type {Phaser.Cameras.Scene2D.CameraManager} - * @since 3.17.0 - */ - this.cameraManager; + this.emit(Events.DESTROY, this, fromScene); - /** - * The Camera ID. Assigned by the Camera Manager and used to handle camera exclusion. - * This value is a bitmask. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#id - * @type {number} - * @readonly - * @since 3.11.0 - */ - this.id = 0; + this.removeAllListeners(); - /** - * The name of the Camera. This is left empty for your own use. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#name - * @type {string} - * @default '' - * @since 3.0.0 - */ - this.name = ''; + if (this.postPipelines) + { + this.resetPostPipeline(true); + } - /** - * Should this camera round its pixel values to integers? - * - * @name Phaser.Cameras.Scene2D.BaseCamera#roundPixels - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.roundPixels = false; + this.removeFromDisplayList(); + this.removeFromUpdateList(); - /** - * Is this Camera visible or not? - * - * A visible camera will render and perform input tests. - * An invisible camera will not render anything and will skip input tests. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#visible - * @type {boolean} - * @default true - * @since 3.10.0 - */ + if (this.input) + { + this.scene.sys.input.clear(this); - /** - * Is this Camera using a bounds to restrict scrolling movement? - * - * Set this property along with the bounds via `Camera.setBounds`. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#useBounds - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.useBounds = false; + this.input = undefined; + } - /** - * The World View is a Rectangle that defines the area of the 'world' the Camera is currently looking at. - * This factors in the Camera viewport size, zoom and scroll position and is updated in the Camera preRender step. - * If you have enabled Camera bounds the worldview will be clamped to those bounds accordingly. - * You can use it for culling or intersection checks. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#worldView - * @type {Phaser.Geom.Rectangle} - * @readonly - * @since 3.11.0 - */ - this.worldView = new Rectangle(); + if (this.data) + { + this.data.destroy(); - /** - * Is this Camera dirty? - * - * A dirty Camera has had either its viewport size, bounds, scroll, rotation or zoom levels changed since the last frame. - * - * This flag is cleared during the `postRenderCamera` method of the renderer. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#dirty - * @type {boolean} - * @default true - * @since 3.11.0 - */ - this.dirty = true; + this.data = undefined; + } - /** - * The x position of the Camera viewport, relative to the top-left of the game canvas. - * The viewport is the area into which the camera renders. - * To adjust the position the camera is looking at in the game world, see the `scrollX` value. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_x - * @type {number} - * @private - * @since 3.0.0 - */ - this._x = x; + if (this.body) + { + this.body.destroy(); - /** - * The y position of the Camera, relative to the top-left of the game canvas. - * The viewport is the area into which the camera renders. - * To adjust the position the camera is looking at in the game world, see the `scrollY` value. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_y - * @type {number} - * @private - * @since 3.0.0 - */ - this._y = y; + this.body = undefined; + } - /** - * The width of the Camera viewport, in pixels. - * - * The viewport is the area into which the Camera renders. Setting the viewport does - * not restrict where the Camera can scroll to. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_width - * @type {number} - * @private - * @since 3.11.0 - */ - this._width = width; + if (this.preFX) + { + this.preFX.destroy(); - /** - * The height of the Camera viewport, in pixels. - * - * The viewport is the area into which the Camera renders. Setting the viewport does - * not restrict where the Camera can scroll to. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_height - * @type {number} - * @private - * @since 3.11.0 - */ - this._height = height; + this.preFX = undefined; + } - /** - * The bounds the camera is restrained to during scrolling. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_bounds - * @type {Phaser.Geom.Rectangle} - * @private - * @since 3.0.0 - */ - this._bounds = new Rectangle(); + if (this.postFX) + { + this.postFX.destroy(); - /** - * The horizontal scroll position of this Camera. - * - * Change this value to cause the Camera to scroll around your Scene. - * - * Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method, - * will automatically adjust the Camera scroll values accordingly. - * - * You can set the bounds within which the Camera can scroll via the `setBounds` method. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_scrollX - * @type {number} - * @private - * @default 0 - * @since 3.11.0 - */ - this._scrollX = 0; + this.postFX = undefined; + } - /** - * The vertical scroll position of this Camera. - * - * Change this value to cause the Camera to scroll around your Scene. - * - * Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method, - * will automatically adjust the Camera scroll values accordingly. - * - * You can set the bounds within which the Camera can scroll via the `setBounds` method. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_scrollY - * @type {number} - * @private - * @default 0 - * @since 3.11.0 - */ - this._scrollY = 0; + this.active = false; + this.visible = false; - /** - * The Camera horizontal zoom value. Change this value to zoom in, or out of, a Scene. - * - * A value of 0.5 would zoom the Camera out, so you can now see twice as much - * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel - * now takes up 2 pixels when rendered. - * - * Set to 1 to return to the default zoom level. - * - * Be careful to never set this value to zero. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_zoomX - * @type {number} - * @private - * @default 1 - * @since 3.50.0 - */ - this._zoomX = 1; + this.scene = undefined; + this.parentContainer = undefined; + } - /** - * The Camera vertical zoom value. Change this value to zoom in, or out of, a Scene. - * - * A value of 0.5 would zoom the Camera out, so you can now see twice as much - * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel - * now takes up 2 pixels when rendered. - * - * Set to 1 to return to the default zoom level. - * - * Be careful to never set this value to zero. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_zoomY - * @type {number} - * @private - * @default 1 - * @since 3.50.0 - */ - this._zoomY = 1; +}); - /** - * The rotation of the Camera in radians. - * - * Camera rotation always takes place based on the Camera viewport. By default, rotation happens - * in the center of the viewport. You can adjust this with the `originX` and `originY` properties. - * - * Rotation influences the rendering of _all_ Game Objects visible by this Camera. However, it does not - * rotate the Camera viewport itself, which always remains an axis-aligned rectangle. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#_rotation - * @type {number} - * @private - * @default 0 - * @since 3.11.0 - */ - this._rotation = 0; +/** + * 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.GameObject + * @default + */ +GameObject.RENDER_MASK = 15; - /** - * A local transform matrix used for internal calculations. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#matrix - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.0.0 - */ - this.matrix = new TransformMatrix(); +module.exports = GameObject; - /** - * Does this Camera have a transparent background? - * - * @name Phaser.Cameras.Scene2D.BaseCamera#transparent - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.transparent = true; - /** - * The background color of this Camera. Only used if `transparent` is `false`. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#backgroundColor - * @type {Phaser.Display.Color} - * @since 3.0.0 - */ - this.backgroundColor = ValueToColor('rgba(0,0,0,0)'); +/***/ }), - /** - * The Camera alpha value. Setting this property impacts every single object that this Camera - * renders. You can either set the property directly, i.e. via a Tween, to fade a Camera in or out, - * or via the chainable `setAlpha` method instead. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#alpha - * @type {number} - * @default 1 - * @since 3.11.0 - */ +/***/ 99325: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Should the camera cull Game Objects before checking them for input hit tests? - * In some special cases it may be beneficial to disable this. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#disableCull - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.disableCull = false; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A temporary array of culled objects. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#culledObjects - * @type {Phaser.GameObjects.GameObject[]} - * @default [] - * @private - * @since 3.0.0 - */ - this.culledObjects = []; +var Class = __webpack_require__(56694); +var PluginCache = __webpack_require__(91963); +var SceneEvents = __webpack_require__(7599); - /** - * The mid-point of the Camera in 'world' coordinates. - * - * Use it to obtain exactly where in the world the center of the camera is currently looking. - * - * This value is updated in the preRender method, after the scroll values and follower - * have been processed. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#midPoint - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.11.0 - */ - this.midPoint = new Vector2(width / 2, height / 2); +/** + * @classdesc + * The Game Object Creator is a Scene plugin that allows you to quickly create many common + * types of Game Objects and return them using a configuration object, rather than + * having to specify a limited set of parameters such as with the GameObjectFactory. + * + * Game Objects made via this class are automatically added to the Scene and Update List + * unless you explicitly set the `add` property in the configuration object to `false`. + * + * @class GameObjectCreator + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to which this Game Object Factory belongs. + */ +var GameObjectCreator = new Class({ - /** - * The horizontal origin of rotation for this Camera. - * - * By default the camera rotates around the center of the viewport. - * - * Changing the origin allows you to adjust the point in the viewport from which rotation happens. - * A value of 0 would rotate from the top-left of the viewport. A value of 1 from the bottom right. - * - * See `setOrigin` to set both origins in a single, chainable call. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#originX - * @type {number} - * @default 0.5 - * @since 3.11.0 - */ - this.originX = 0.5; + initialize: + function GameObjectCreator (scene) + { /** - * The vertical origin of rotation for this Camera. - * - * By default the camera rotates around the center of the viewport. - * - * Changing the origin allows you to adjust the point in the viewport from which rotation happens. - * A value of 0 would rotate from the top-left of the viewport. A value of 1 from the bottom right. - * - * See `setOrigin` to set both origins in a single, chainable call. + * The Scene to which this Game Object Creator belongs. * - * @name Phaser.Cameras.Scene2D.BaseCamera#originY - * @type {number} - * @default 0.5 - * @since 3.11.0 + * @name Phaser.GameObjects.GameObjectCreator#scene + * @type {Phaser.Scene} + * @protected + * @since 3.0.0 */ - this.originY = 0.5; + this.scene = scene; /** - * Does this Camera have a custom viewport? + * A reference to the Scene.Systems. * - * @name Phaser.Cameras.Scene2D.BaseCamera#_customViewport - * @type {boolean} - * @private - * @default false - * @since 3.12.0 + * @name Phaser.GameObjects.GameObjectCreator#systems + * @type {Phaser.Scenes.Systems} + * @protected + * @since 3.0.0 */ - this._customViewport = false; + this.systems = scene.sys; /** - * The Mask this Camera is using during render. - * Set the mask using the `setMask` method. Remove the mask using the `clearMask` method. + * A reference to the Scene Event Emitter. * - * @name Phaser.Cameras.Scene2D.BaseCamera#mask - * @type {?(Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask)} - * @since 3.17.0 + * @name Phaser.GameObjects.GameObjectCreator#events + * @type {Phaser.Events.EventEmitter} + * @protected + * @since 3.50.0 */ - this.mask = null; + this.events = scene.sys.events; /** - * The Camera that this Camera uses for translation during masking. - * - * If the mask is fixed in position this will be a reference to - * the CameraManager.default instance. Otherwise, it'll be a reference - * to itself. + * A reference to the Scene Display List. * - * @name Phaser.Cameras.Scene2D.BaseCamera#_maskCamera - * @type {?Phaser.Cameras.Scene2D.BaseCamera} - * @private - * @since 3.17.0 + * @name Phaser.GameObjects.GameObjectCreator#displayList + * @type {Phaser.GameObjects.DisplayList} + * @protected + * @since 3.0.0 */ - this._maskCamera = null; + this.displayList; /** - * This array is populated with all of the Game Objects that this Camera has rendered - * in the previous (or current, depending on when you inspect it) frame. - * - * It is cleared at the start of `Camera.preUpdate`, or if the Camera is destroyed. - * - * You should not modify this array as it is used internally by the input system, - * however you can read it as required. Note that Game Objects may appear in this - * list multiple times if they belong to multiple non-exclusive Containers. + * A reference to the Scene Update List. * - * @name Phaser.Cameras.Scene2D.BaseCamera#renderList - * @type {Phaser.GameObjects.GameObject[]} - * @since 3.52.0 + * @name Phaser.GameObjects.GameObjectCreator#updateList + * @type {Phaser.GameObjects.UpdateList} + * @protected + * @since 3.0.0 */ - this.renderList = []; + this.updateList; + + this.events.once(SceneEvents.BOOT, this.boot, this); + this.events.on(SceneEvents.START, this.start, this); }, /** - * Adds the given Game Object to this cameras render list. - * - * This is invoked during the rendering stage. Only objects that are actually rendered - * will appear in the render list. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#addToRenderList - * @since 3.52.0 + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to add to the render list. + * @method Phaser.GameObjects.GameObjectCreator#boot + * @private + * @since 3.5.1 */ - addToRenderList: function (child) + boot: function () { - this.renderList.push(child); + this.displayList = this.systems.displayList; + this.updateList = this.systems.updateList; + + this.events.once(SceneEvents.DESTROY, this.destroy, this); }, /** - * Set the Alpha level of this Camera. The alpha controls the opacity of the Camera as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#setAlpha - * @since 3.11.0 - * - * @param {number} [value=1] - The Camera alpha value. + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. * - * @return {this} This Camera instance. + * @method Phaser.GameObjects.GameObjectCreator#start + * @private + * @since 3.5.0 */ + start: function () + { + this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); + }, /** - * Sets the rotation origin of this Camera. - * - * The values are given in the range 0 to 1 and are only used when calculating Camera rotation. - * - * By default the camera rotates around the center of the viewport. - * - * Changing the origin allows you to adjust the point in the viewport from which rotation happens. - * A value of 0 would rotate from the top-left of the viewport. A value of 1 from the bottom right. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#setOrigin - * @since 3.11.0 - * - * @param {number} [x=0.5] - The horizontal origin value. - * @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`. + * The Scene that owns this plugin is shutting down. + * We need to kill and reset all internal properties as well as stop listening to Scene events. * - * @return {this} This Camera instance. + * @method Phaser.GameObjects.GameObjectCreator#shutdown + * @private + * @since 3.0.0 */ - setOrigin: function (x, y) + shutdown: function () { - if (x === undefined) { x = 0.5; } - if (y === undefined) { y = x; } - - this.originX = x; - this.originY = y; - - return this; + this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * Calculates what the Camera.scrollX and scrollY values would need to be in order to move - * the Camera so it is centered on the given x and y coordinates, without actually moving - * the Camera there. The results are clamped based on the Camera bounds, if set. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#getScroll - * @since 3.11.0 - * - * @param {number} x - The horizontal coordinate to center on. - * @param {number} y - The vertical coordinate to center on. - * @param {Phaser.Math.Vector2} [out] - A Vector2 to store the values in. If not given a new Vector2 is created. + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. * - * @return {Phaser.Math.Vector2} The scroll coordinates stored in the `x` and `y` properties. + * @method Phaser.GameObjects.GameObjectCreator#destroy + * @private + * @since 3.0.0 */ - getScroll: function (x, y, out) + destroy: function () { - if (out === undefined) { out = new Vector2(); } + this.shutdown(); - var originX = this.width * 0.5; - var originY = this.height * 0.5; + this.events.off(SceneEvents.START, this.start, this); - out.x = x - originX; - out.y = y - originY; + this.scene = null; + this.systems = null; + this.events = null; - if (this.useBounds) - { - out.x = this.clampX(out.x); - out.y = this.clampY(out.y); - } + this.displayList = null; + this.updateList = null; + } - return out; - }, +}); - /** - * Moves the Camera horizontally so that it is centered on the given x coordinate, bounds allowing. - * Calling this does not change the scrollY value. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#centerOnX - * @since 3.16.0 - * - * @param {number} x - The horizontal coordinate to center on. - * - * @return {this} This Camera instance. - */ - centerOnX: function (x) +/** + * Static method called directly by the Game Object creator functions. + * With this method you can register a custom GameObject factory in the GameObjectCreator, + * providing a name (`factoryType`) and the constructor (`factoryFunction`) in order + * to be called when you invoke Phaser.Scene.make[ factoryType ] method. + * + * @method Phaser.GameObjects.GameObjectCreator.register + * @static + * @since 3.0.0 + * + * @param {string} factoryType - The key of the factory that you will use to call to Phaser.Scene.make[ factoryType ] method. + * @param {function} factoryFunction - The constructor function to be called when you invoke to the Phaser.Scene.make method. + */ +GameObjectCreator.register = function (factoryType, factoryFunction) +{ + if (!GameObjectCreator.prototype.hasOwnProperty(factoryType)) { - var originX = this.width * 0.5; + GameObjectCreator.prototype[factoryType] = factoryFunction; + } +}; - this.midPoint.x = x; +/** + * Static method called directly by the Game Object Creator functions. + * + * With this method you can remove a custom Game Object Creator that has been previously + * registered in the Game Object Creator. Pass in its `factoryType` in order to remove it. + * + * @method Phaser.GameObjects.GameObjectCreator.remove + * @static + * @since 3.0.0 + * + * @param {string} factoryType - The key of the factory that you want to remove from the GameObjectCreator. + */ +GameObjectCreator.remove = function (factoryType) +{ + if (GameObjectCreator.prototype.hasOwnProperty(factoryType)) + { + delete GameObjectCreator.prototype[factoryType]; + } +}; - this.scrollX = x - originX; +PluginCache.register('GameObjectCreator', GameObjectCreator, 'make'); - if (this.useBounds) - { - this.scrollX = this.clampX(this.scrollX); - } +module.exports = GameObjectCreator; - return this; - }, - /** - * Moves the Camera vertically so that it is centered on the given y coordinate, bounds allowing. - * Calling this does not change the scrollX value. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#centerOnY - * @since 3.16.0 - * - * @param {number} y - The vertical coordinate to center on. - * - * @return {this} This Camera instance. - */ - centerOnY: function (y) +/***/ }), + +/***/ 61286: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var PluginCache = __webpack_require__(91963); +var SceneEvents = __webpack_require__(7599); + +/** + * @classdesc + * The Game Object Factory is a Scene plugin that allows you to quickly create many common + * types of Game Objects and have them automatically registered with the Scene. + * + * Game Objects directly register themselves with the Factory and inject their own creation + * methods into the class. + * + * @class GameObjectFactory + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to which this Game Object Factory belongs. + */ +var GameObjectFactory = new Class({ + + initialize: + + function GameObjectFactory (scene) { - var originY = this.height * 0.5; + /** + * The Scene to which this Game Object Factory belongs. + * + * @name Phaser.GameObjects.GameObjectFactory#scene + * @type {Phaser.Scene} + * @protected + * @since 3.0.0 + */ + this.scene = scene; - this.midPoint.y = y; + /** + * A reference to the Scene.Systems. + * + * @name Phaser.GameObjects.GameObjectFactory#systems + * @type {Phaser.Scenes.Systems} + * @protected + * @since 3.0.0 + */ + this.systems = scene.sys; - this.scrollY = y - originY; + /** + * A reference to the Scene Event Emitter. + * + * @name Phaser.GameObjects.GameObjectFactory#events + * @type {Phaser.Events.EventEmitter} + * @protected + * @since 3.50.0 + */ + this.events = scene.sys.events; - if (this.useBounds) - { - this.scrollY = this.clampY(this.scrollY); - } + /** + * A reference to the Scene Display List. + * + * @name Phaser.GameObjects.GameObjectFactory#displayList + * @type {Phaser.GameObjects.DisplayList} + * @protected + * @since 3.0.0 + */ + this.displayList; - return this; + /** + * A reference to the Scene Update List. + * + * @name Phaser.GameObjects.GameObjectFactory#updateList + * @type {Phaser.GameObjects.UpdateList} + * @protected + * @since 3.0.0 + */ + this.updateList; + + this.events.once(SceneEvents.BOOT, this.boot, this); + this.events.on(SceneEvents.START, this.start, this); }, /** - * Moves the Camera so that it is centered on the given coordinates, bounds allowing. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#centerOn - * @since 3.11.0 - * - * @param {number} x - The horizontal coordinate to center on. - * @param {number} y - The vertical coordinate to center on. + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. * - * @return {this} This Camera instance. + * @method Phaser.GameObjects.GameObjectFactory#boot + * @private + * @since 3.5.1 */ - centerOn: function (x, y) + boot: function () { - this.centerOnX(x); - this.centerOnY(y); + this.displayList = this.systems.displayList; + this.updateList = this.systems.updateList; - return this; + this.events.once(SceneEvents.DESTROY, this.destroy, this); }, /** - * Moves the Camera so that it is looking at the center of the Camera Bounds, if enabled. + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. * - * @method Phaser.Cameras.Scene2D.BaseCamera#centerToBounds + * @method Phaser.GameObjects.GameObjectFactory#start + * @private + * @since 3.5.0 + */ + start: function () + { + this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); + }, + + /** + * Adds an existing Game Object to this Scene. + * + * If the Game Object renders, it will be added to the Display List. + * If it has a `preUpdate` method, it will be added to the Update List. + * + * @method Phaser.GameObjects.GameObjectFactory#existing * @since 3.0.0 * - * @return {this} This Camera instance. + * @generic {(Phaser.GameObjects.GameObject|Phaser.GameObjects.Group|Phaser.GameObjects.Layer)} G - [child,$return] + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.Group|Phaser.GameObjects.Layer)} child - The child to be added to this Scene. + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was added. */ - centerToBounds: function () + existing: function (child) { - if (this.useBounds) + if (child.renderCanvas || child.renderWebGL) { - var bounds = this._bounds; - var originX = this.width * 0.5; - var originY = this.height * 0.5; - - this.midPoint.set(bounds.centerX, bounds.centerY); + this.displayList.add(child); + } - this.scrollX = bounds.centerX - originX; - this.scrollY = bounds.centerY - originY; + // For when custom objects have overridden `preUpdate` but don't hook into the ADDED_TO_SCENE event: + // Adding to the list multiple times is safe, as it won't add duplicates into the list anyway. + if (child.preUpdate) + { + this.updateList.add(child); } - return this; + return child; }, /** - * Moves the Camera so that it is re-centered based on its viewport size. + * The Scene that owns this plugin is shutting down. + * We need to kill and reset all internal properties as well as stop listening to Scene events. * - * @method Phaser.Cameras.Scene2D.BaseCamera#centerToSize + * @method Phaser.GameObjects.GameObjectFactory#shutdown + * @private * @since 3.0.0 - * - * @return {this} This Camera instance. */ - centerToSize: function () + shutdown: function () { - this.scrollX = this.width * 0.5; - this.scrollY = this.height * 0.5; - - return this; + this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * Takes an array of Game Objects and returns a new array featuring only those objects - * visible by this camera. + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. * - * @method Phaser.Cameras.Scene2D.BaseCamera#cull + * @method Phaser.GameObjects.GameObjectFactory#destroy + * @private * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [renderableObjects,$return] - * - * @param {Phaser.GameObjects.GameObject[]} renderableObjects - An array of Game Objects to cull. - * - * @return {Phaser.GameObjects.GameObject[]} An array of Game Objects visible to this Camera. */ - cull: function (renderableObjects) + destroy: function () { - if (this.disableCull) - { - return renderableObjects; - } + this.shutdown(); - var cameraMatrix = this.matrix.matrix; + this.events.off(SceneEvents.START, this.start, this); - var mva = cameraMatrix[0]; - var mvb = cameraMatrix[1]; - var mvc = cameraMatrix[2]; - var mvd = cameraMatrix[3]; + this.scene = null; + this.systems = null; + this.events = null; - /* First Invert Matrix */ - var determinant = (mva * mvd) - (mvb * mvc); - - if (!determinant) - { - return renderableObjects; - } - - var mve = cameraMatrix[4]; - var mvf = cameraMatrix[5]; - - var scrollX = this.scrollX; - var scrollY = this.scrollY; - var cameraW = this.width; - var cameraH = this.height; - var cullTop = this.y; - var cullBottom = cullTop + cameraH; - var cullLeft = this.x; - var cullRight = cullLeft + cameraW; - var culledObjects = this.culledObjects; - var length = renderableObjects.length; - - determinant = 1 / determinant; - - culledObjects.length = 0; - - for (var index = 0; index < length; ++index) - { - var object = renderableObjects[index]; - - if (!object.hasOwnProperty('width') || object.parentContainer) - { - culledObjects.push(object); - continue; - } - - var objectW = object.width; - var objectH = object.height; - var objectX = (object.x - (scrollX * object.scrollFactorX)) - (objectW * object.originX); - var objectY = (object.y - (scrollY * object.scrollFactorY)) - (objectH * object.originY); - var tx = (objectX * mva + objectY * mvc + mve); - var ty = (objectX * mvb + objectY * mvd + mvf); - var tw = ((objectX + objectW) * mva + (objectY + objectH) * mvc + mve); - var th = ((objectX + objectW) * mvb + (objectY + objectH) * mvd + mvf); - - if ((tw > cullLeft && tx < cullRight) && (th > cullTop && ty < cullBottom)) - { - culledObjects.push(object); - } - } + this.displayList = null; + this.updateList = null; + } - return culledObjects; - }, +}); - /** - * Converts the given `x` and `y` coordinates into World space, based on this Cameras transform. - * You can optionally provide a Vector2, or similar object, to store the results in. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#getWorldPoint - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {number} x - The x position to convert to world space. - * @param {number} y - The y position to convert to world space. - * @param {(object|Phaser.Math.Vector2)} [output] - An optional object to store the results in. If not provided a new Vector2 will be created. - * - * @return {Phaser.Math.Vector2} An object holding the converted values in its `x` and `y` properties. - */ - getWorldPoint: function (x, y, output) +/** + * Static method called directly by the Game Object factory functions. + * With this method you can register a custom GameObject factory in the GameObjectFactory, + * providing a name (`factoryType`) and the constructor (`factoryFunction`) in order + * to be called when you call to Phaser.Scene.add[ factoryType ] method. + * + * @method Phaser.GameObjects.GameObjectFactory.register + * @static + * @since 3.0.0 + * + * @param {string} factoryType - The key of the factory that you will use to call to Phaser.Scene.add[ factoryType ] method. + * @param {function} factoryFunction - The constructor function to be called when you invoke to the Phaser.Scene.add method. + */ +GameObjectFactory.register = function (factoryType, factoryFunction) +{ + if (!GameObjectFactory.prototype.hasOwnProperty(factoryType)) { - if (output === undefined) { output = new Vector2(); } + GameObjectFactory.prototype[factoryType] = factoryFunction; + } +}; - var cameraMatrix = this.matrix.matrix; +/** + * Static method called directly by the Game Object factory functions. + * With this method you can remove a custom GameObject factory registered in the GameObjectFactory, + * providing a its `factoryType`. + * + * @method Phaser.GameObjects.GameObjectFactory.remove + * @static + * @since 3.0.0 + * + * @param {string} factoryType - The key of the factory that you want to remove from the GameObjectFactory. + */ +GameObjectFactory.remove = function (factoryType) +{ + if (GameObjectFactory.prototype.hasOwnProperty(factoryType)) + { + delete GameObjectFactory.prototype[factoryType]; + } +}; - var mva = cameraMatrix[0]; - var mvb = cameraMatrix[1]; - var mvc = cameraMatrix[2]; - var mvd = cameraMatrix[3]; - var mve = cameraMatrix[4]; - var mvf = cameraMatrix[5]; +PluginCache.register('GameObjectFactory', GameObjectFactory, 'add'); - // Invert Matrix - var determinant = (mva * mvd) - (mvb * mvc); +module.exports = GameObjectFactory; - if (!determinant) - { - output.x = x; - output.y = y; - return output; - } +/***/ }), - determinant = 1 / determinant; +/***/ 73329: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var ima = mvd * determinant; - var imb = -mvb * determinant; - var imc = -mvc * determinant; - var imd = mva * determinant; - var ime = (mvc * mvf - mvd * mve) * determinant; - var imf = (mvb * mve - mva * mvf) * determinant; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var c = Math.cos(this.rotation); - var s = Math.sin(this.rotation); +var TransformMatrix = __webpack_require__(69360); - var zoomX = this.zoomX; - var zoomY = this.zoomY; +var tempMatrix1 = new TransformMatrix(); +var tempMatrix2 = new TransformMatrix(); +var tempMatrix3 = new TransformMatrix(); - var scrollX = this.scrollX; - var scrollY = this.scrollY; +var result = { camera: tempMatrix1, sprite: tempMatrix2, calc: tempMatrix3 }; - var sx = x + ((scrollX * c - scrollY * s) * zoomX); - var sy = y + ((scrollX * s + scrollY * c) * zoomY); +/** + * 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; - // Apply transform to point - output.x = (sx * ima + sy * imc) + ime; - output.y = (sx * imb + sy * imd) + imf; + spriteMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY); - return output; - }, + camMatrix.copyFrom(camera.matrix); - /** - * Given a Game Object, or an array of Game Objects, it will update all of their camera filter settings - * so that they are ignored by this Camera. This means they will not be rendered by this Camera. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#ignore - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group)} entries - The Game Object, or array of Game Objects, to be ignored by this Camera. - * - * @return {this} This Camera instance. - */ - ignore: function (entries) + if (parentMatrix) { - var id = this.id; - - if (!Array.isArray(entries)) - { - entries = [ entries ]; - } - - for (var i = 0; i < entries.length; i++) - { - var entry = entries[i]; - - if (Array.isArray(entry)) - { - this.ignore(entry); - } - else if (entry.isParent) - { - this.ignore(entry.getChildren()); - } - else - { - entry.cameraFilter |= id; - } - } - - return this; - }, + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY); - /** - * Internal preRender step. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#preRender - * @protected - * @since 3.0.0 - */ - preRender: function () + // Undo the camera scroll + spriteMatrix.e = src.x; + spriteMatrix.f = src.y; + } + else { - this.renderList.length = 0; - - var width = this.width; - var height = this.height; - - var halfWidth = width * 0.5; - var halfHeight = height * 0.5; + spriteMatrix.e -= camera.scrollX * src.scrollFactorX; + spriteMatrix.f -= camera.scrollY * src.scrollFactorY; + } - var zoomX = this.zoomX; - var zoomY = this.zoomY; - var matrix = this.matrix; + // Multiply by the Sprite matrix, store result in calcMatrix + camMatrix.multiply(spriteMatrix, calcMatrix); - var originX = width * this.originX; - var originY = height * this.originY; + return result; +}; - var sx = this.scrollX; - var sy = this.scrollY; +module.exports = GetCalcMatrix; - if (this.useBounds) - { - sx = this.clampX(sx); - sy = this.clampY(sy); - } - if (this.roundPixels) - { - originX = Math.round(originX); - originY = Math.round(originY); - } +/***/ }), - // Values are in pixels and not impacted by zooming the Camera - this.scrollX = sx; - this.scrollY = sy; +/***/ 92034: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var midX = sx + halfWidth; - var midY = sy + halfHeight; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // The center of the camera, in world space, so taking zoom into account - // Basically the pixel value of what it's looking at in the middle of the cam - this.midPoint.set(midX, midY); +var Class = __webpack_require__(56694); +var ProcessQueue = __webpack_require__(74623); +var PluginCache = __webpack_require__(91963); +var SceneEvents = __webpack_require__(7599); - var displayWidth = width / zoomX; - var displayHeight = height / zoomY; +/** + * @classdesc + * The Update List plugin. + * + * Update Lists belong to a Scene and maintain the list Game Objects to be updated every frame. + * + * Some or all of these Game Objects may also be part of the Scene's [Display List]{@link Phaser.GameObjects.DisplayList}, for Rendering. + * + * @class UpdateList + * @extends Phaser.Structs.ProcessQueue. + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene that the Update List belongs to. + */ +var UpdateList = new Class({ - this.worldView.setTo( - midX - (displayWidth / 2), - midY - (displayHeight / 2), - displayWidth, - displayHeight - ); + Extends: ProcessQueue, - matrix.applyITRS(this.x + originX, this.y + originY, this.rotation, zoomX, zoomY); - matrix.translate(-originX, -originY); - }, + initialize: - /** - * Takes an x value and checks it's within the range of the Camera bounds, adjusting if required. - * Do not call this method if you are not using camera bounds. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#clampX - * @since 3.11.0 - * - * @param {number} x - The value to horizontally scroll clamp. - * - * @return {number} The adjusted value to use as scrollX. - */ - clampX: function (x) + function UpdateList (scene) { - var bounds = this._bounds; - - var dw = this.displayWidth; + ProcessQueue.call(this); - var bx = bounds.x + ((dw - this.width) / 2); - var bw = Math.max(bx, bx + bounds.width - dw); + // No duplicates in this list + this.checkQueue = true; - if (x < bx) - { - x = bx; - } - else if (x > bw) - { - x = bw; - } + /** + * The Scene that the Update List belongs to. + * + * @name Phaser.GameObjects.UpdateList#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - return x; - }, + /** + * The Scene's Systems. + * + * @name Phaser.GameObjects.UpdateList#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.systems = scene.sys; - /** - * Takes a y value and checks it's within the range of the Camera bounds, adjusting if required. - * Do not call this method if you are not using camera bounds. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#clampY - * @since 3.11.0 - * - * @param {number} y - The value to vertically scroll clamp. - * - * @return {number} The adjusted value to use as scrollY. - */ - clampY: function (y) - { - var bounds = this._bounds; + /** + * The `pending` list is a selection of items which are due to be made 'active' in the next update. + * + * @name Phaser.GameObjects.UpdateList#_pending + * @type {Array.<*>} + * @private + * @default [] + * @since 3.20.0 + */ - var dh = this.displayHeight; + /** + * The `active` list is a selection of items which are considered active and should be updated. + * + * @name Phaser.GameObjects.UpdateList#_active + * @type {Array.<*>} + * @private + * @default [] + * @since 3.20.0 + */ - var by = bounds.y + ((dh - this.height) / 2); - var bh = Math.max(by, by + bounds.height - dh); + /** + * The `destroy` list is a selection of items that were active and are awaiting being destroyed in the next update. + * + * @name Phaser.GameObjects.UpdateList#_destroy + * @type {Array.<*>} + * @private + * @default [] + * @since 3.20.0 + */ - if (y < by) - { - y = by; - } - else if (y > bh) - { - y = bh; - } + /** + * The total number of items awaiting processing. + * + * @name Phaser.GameObjects.UpdateList#_toProcess + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ - return y; + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + scene.sys.events.on(SceneEvents.START, this.start, this); }, - /* - var gap = this._zoomInversed; - return gap * Math.round((src.x - this.scrollX * src.scrollFactorX) / gap); - */ - /** - * If this Camera has previously had movement bounds set on it, this will remove them. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#removeBounds - * @since 3.0.0 + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. * - * @return {this} This Camera instance. + * @method Phaser.GameObjects.UpdateList#boot + * @private + * @since 3.5.1 */ - removeBounds: function () + boot: function () { - this.useBounds = false; - - this.dirty = true; - - this._bounds.setEmpty(); - - return this; + this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); }, /** - * Set the rotation of this Camera. This causes everything it renders to appear rotated. - * - * Rotating a camera does not rotate the viewport itself, it is applied during rendering. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#setAngle - * @since 3.0.0 - * - * @param {number} [value=0] - The cameras angle of rotation, given in degrees. + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. * - * @return {this} This Camera instance. + * @method Phaser.GameObjects.UpdateList#start + * @private + * @since 3.5.0 */ - setAngle: function (value) + start: function () { - if (value === undefined) { value = 0; } - - this.rotation = DegToRad(value); + var eventEmitter = this.systems.events; - return this; + eventEmitter.on(SceneEvents.PRE_UPDATE, this.update, this); + eventEmitter.on(SceneEvents.UPDATE, this.sceneUpdate, this); + eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * Sets the background color for this Camera. - * - * By default a Camera has a transparent background but it can be given a solid color, with any level - * of transparency, via this method. - * - * The color value can be specified using CSS color notation, hex or numbers. + * The update step. * - * @method Phaser.Cameras.Scene2D.BaseCamera#setBackgroundColor - * @since 3.0.0 + * Pre-updates every active Game Object in the list. * - * @param {(string|number|Phaser.Types.Display.InputColorObject)} [color='rgba(0,0,0,0)'] - The color value. In CSS, hex or numeric color notation. + * @method Phaser.GameObjects.UpdateList#sceneUpdate + * @since 3.20.0 * - * @return {this} This Camera instance. + * @param {number} time - The current timestamp. + * @param {number} delta - The delta time elapsed since the last frame. */ - setBackgroundColor: function (color) + sceneUpdate: function (time, delta) { - if (color === undefined) { color = 'rgba(0,0,0,0)'; } - - this.backgroundColor = ValueToColor(color); + var list = this._active; + var length = list.length; - this.transparent = (this.backgroundColor.alpha === 0); + for (var i = 0; i < length; i++) + { + var gameObject = list[i]; - return this; + if (gameObject.active) + { + gameObject.preUpdate.call(gameObject, time, delta); + } + } }, /** - * Set the bounds of the Camera. The bounds are an axis-aligned rectangle. - * - * The Camera bounds controls where the Camera can scroll to, stopping it from scrolling off the - * edges and into blank space. It does not limit the placement of Game Objects, or where - * the Camera viewport can be positioned. - * - * Temporarily disable the bounds by changing the boolean `Camera.useBounds`. - * - * Clear the bounds entirely by calling `Camera.removeBounds`. + * The Scene that owns this plugin is shutting down. * - * If you set bounds that are smaller than the viewport it will stop the Camera from being - * able to scroll. The bounds can be positioned where-ever you wish. By default they are from - * 0x0 to the canvas width x height. This means that the coordinate 0x0 is the top left of - * the Camera bounds. However, you can position them anywhere. So if you wanted a game world - * that was 2048x2048 in size, with 0x0 being the center of it, you can set the bounds x/y - * to be -1024, -1024, with a width and height of 2048. Depending on your game you may find - * it easier for 0x0 to be the top-left of the bounds, or you may wish 0x0 to be the middle. + * We need to kill and reset all internal properties as well as stop listening to Scene events. * - * @method Phaser.Cameras.Scene2D.BaseCamera#setBounds + * @method Phaser.GameObjects.UpdateList#shutdown * @since 3.0.0 - * - * @param {number} x - The top-left x coordinate of the bounds. - * @param {number} y - The top-left y coordinate of the bounds. - * @param {number} width - The width of the bounds, in pixels. - * @param {number} height - The height of the bounds, in pixels. - * @param {boolean} [centerOn=false] - If `true` the Camera will automatically be centered on the new bounds. - * - * @return {this} This Camera instance. */ - setBounds: function (x, y, width, height, centerOn) + shutdown: function () { - if (centerOn === undefined) { centerOn = false; } + var i = this._active.length; - this._bounds.setTo(x, y, width, height); + while (i--) + { + this._active[i].destroy(true); + } - this.dirty = true; - this.useBounds = true; + i = this._pending.length; - if (centerOn) + while (i--) { - this.centerToBounds(); + this._pending[i].destroy(true); } - else + + i = this._destroy.length; + + while (i--) { - this.scrollX = this.clampX(this.scrollX); - this.scrollY = this.clampY(this.scrollY); + this._destroy[i].destroy(true); } - return this; - }, + this._toProcess = 0; - /** - * Returns a rectangle containing the bounds of the Camera. - * - * If the Camera does not have any bounds the rectangle will be empty. - * - * The rectangle is a copy of the bounds, so is safe to modify. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#getBounds - * @since 3.16.0 - * - * @param {Phaser.Geom.Rectangle} [out] - An optional Rectangle to store the bounds in. If not given, a new Rectangle will be created. - * - * @return {Phaser.Geom.Rectangle} A rectangle containing the bounds of this Camera. - */ - getBounds: function (out) - { - if (out === undefined) { out = new Rectangle(); } + this._pending = []; + this._active = []; + this._destroy = []; - var source = this._bounds; + this.removeAllListeners(); - out.setTo(source.x, source.y, source.width, source.height); + var eventEmitter = this.systems.events; - return out; + eventEmitter.off(SceneEvents.PRE_UPDATE, this.update, this); + eventEmitter.off(SceneEvents.UPDATE, this.sceneUpdate, this); + eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * Sets the name of this Camera. - * This value is for your own use and isn't used internally. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#setName - * @since 3.0.0 + * The Scene that owns this plugin is being destroyed. * - * @param {string} [value=''] - The name of the Camera. + * We need to shutdown and then kill off all external references. * - * @return {this} This Camera instance. + * @method Phaser.GameObjects.UpdateList#destroy + * @since 3.0.0 */ - setName: function (value) + destroy: function () { - if (value === undefined) { value = ''; } + this.shutdown(); - this.name = value; + this.systems.events.off(SceneEvents.START, this.start, this); - return this; - }, + this.scene = null; + this.systems = null; + } /** - * Set the position of the Camera viewport within the game. + * Adds a new item to the Update List. * - * This does not change where the camera is 'looking'. See `setScroll` to control that. + * The item is added to the pending list and made active in the next update. * - * @method Phaser.Cameras.Scene2D.BaseCamera#setPosition + * @method Phaser.GameObjects.UpdateList#add * @since 3.0.0 * - * @param {number} x - The top-left x coordinate of the Camera viewport. - * @param {number} [y=x] - The top-left y coordinate of the Camera viewport. + * @param {*} item - The item to add to the queue. * - * @return {this} This Camera instance. + * @return {*} The item that was added. */ - setPosition: function (x, y) - { - if (y === undefined) { y = x; } - - this.x = x; - this.y = y; - - return this; - }, /** - * Set the rotation of this Camera. This causes everything it renders to appear rotated. + * Removes an item from the Update List. * - * Rotating a camera does not rotate the viewport itself, it is applied during rendering. + * The item is added to the pending destroy and fully removed in the next update. * - * @method Phaser.Cameras.Scene2D.BaseCamera#setRotation + * @method Phaser.GameObjects.UpdateList#remove * @since 3.0.0 * - * @param {number} [value=0] - The rotation of the Camera, in radians. + * @param {*} item - The item to be removed from the queue. * - * @return {this} This Camera instance. + * @return {*} The item that was removed. */ - setRotation: function (value) - { - if (value === undefined) { value = 0; } - - this.rotation = value; - - return this; - }, /** - * Should the Camera round pixel values to whole integers when rendering Game Objects? - * - * In some types of game, especially with pixel art, this is required to prevent sub-pixel aliasing. + * Removes all active items from this Update List. * - * @method Phaser.Cameras.Scene2D.BaseCamera#setRoundPixels - * @since 3.0.0 + * All the items are marked as 'pending destroy' and fully removed in the next update. * - * @param {boolean} value - `true` to round Camera pixels, `false` to not. + * @method Phaser.GameObjects.UpdateList#removeAll + * @since 3.20.0 * - * @return {this} This Camera instance. + * @return {this} This Update List object. */ - setRoundPixels: function (value) - { - this.roundPixels = value; - - return this; - }, /** - * Sets the Scene the Camera is bound to. + * Update this queue. First it will process any items awaiting destruction, and remove them. * - * @method Phaser.Cameras.Scene2D.BaseCamera#setScene - * @since 3.0.0 + * Then it will check to see if there are any items pending insertion, and move them to an + * active state. Finally, it will return a list of active items for further processing. * - * @param {Phaser.Scene} scene - The Scene the camera is bound to. + * @method Phaser.GameObjects.UpdateList#update + * @since 3.0.0 * - * @return {this} This Camera instance. + * @return {Array.<*>} A list of active items. */ - setScene: function (scene) - { - if (this.scene && this._customViewport) - { - this.sceneManager.customViewports--; - } - - this.scene = scene; - - var sys = scene.sys; - - this.sceneManager = sys.game.scene; - this.scaleManager = sys.scale; - this.cameraManager = sys.cameras; - - this.updateSystem(); - - return this; - }, /** - * Set the position of where the Camera is looking within the game. - * You can also modify the properties `Camera.scrollX` and `Camera.scrollY` directly. - * Use this method, or the scroll properties, to move your camera around the game world. + * Returns the current list of active items. * - * This does not change where the camera viewport is placed. See `setPosition` to control that. + * This method returns a reference to the active list array, not a copy of it. + * Therefore, be careful to not modify this array outside of the ProcessQueue. * - * @method Phaser.Cameras.Scene2D.BaseCamera#setScroll + * @method Phaser.GameObjects.UpdateList#getActive * @since 3.0.0 * - * @param {number} x - The x coordinate of the Camera in the game world. - * @param {number} [y=x] - The y coordinate of the Camera in the game world. - * - * @return {this} This Camera instance. + * @return {Array.<*>} A list of active items. */ - setScroll: function (x, y) - { - if (y === undefined) { y = x; } - - this.scrollX = x; - this.scrollY = y; - - return this; - }, /** - * Set the size of the Camera viewport. - * - * By default a Camera is the same size as the game, but can be made smaller via this method, - * allowing you to create mini-cam style effects by creating and positioning a smaller Camera - * viewport within your game. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#setSize - * @since 3.0.0 - * - * @param {number} width - The width of the Camera viewport. - * @param {number} [height=width] - The height of the Camera viewport. + * The number of entries in the active list. * - * @return {this} This Camera instance. + * @name Phaser.GameObjects.UpdateList#length + * @type {number} + * @readonly + * @since 3.20.0 */ - setSize: function (width, height) - { - if (height === undefined) { height = width; } +}); - this.width = width; - this.height = height; +PluginCache.register('UpdateList', UpdateList, 'updateList'); - return this; - }, +module.exports = UpdateList; - /** - * This method sets the position and size of the Camera viewport in a single call. - * - * If you're trying to change where the Camera is looking at in your game, then see - * the method `Camera.setScroll` instead. This method is for changing the viewport - * itself, not what the camera can see. - * - * By default a Camera is the same size as the game, but can be made smaller via this method, - * allowing you to create mini-cam style effects by creating and positioning a smaller Camera - * viewport within your game. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#setViewport - * @since 3.0.0 - * - * @param {number} x - The top-left x coordinate of the Camera viewport. - * @param {number} y - The top-left y coordinate of the Camera viewport. - * @param {number} width - The width of the Camera viewport. - * @param {number} [height=width] - The height of the Camera viewport. - * - * @return {this} This Camera instance. - */ - setViewport: function (x, y, width, height) - { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - return this; - }, +/***/ }), - /** - * Set the zoom value of the Camera. - * - * Changing to a smaller value, such as 0.5, will cause the camera to 'zoom out'. - * Changing to a larger value, such as 2, will cause the camera to 'zoom in'. - * - * A value of 1 means 'no zoom' and is the default. - * - * Changing the zoom does not impact the Camera viewport in any way, it is only applied during rendering. - * - * As of Phaser 3.50 you can now set the horizontal and vertical zoom values independently. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#setZoom - * @since 3.0.0 - * - * @param {number} [x=1] - The horizontal zoom value of the Camera. The minimum it can be is 0.001. - * @param {number} [y=x] - The vertical zoom value of the Camera. The minimum it can be is 0.001. - * - * @return {this} This Camera instance. - */ - setZoom: function (x, y) - { - if (x === undefined) { x = 1; } - if (y === undefined) { y = x; } +/***/ 8810: +/***/ ((module) => { - if (x === 0) - { - x = 0.001; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (y === 0) - { - y = 0.001; - } +/** + * Renders one character of the Bitmap Text to the WebGL Pipeline. + * + * @function BatchChar + * @since 3.50.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The WebGLPipeline. Must have a `batchQuad` method. + * @param {Phaser.GameObjects.BitmapText} src - The BitmapText Game Object. + * @param {Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter} char - The character to render. + * @param {Phaser.Types.GameObjects.BitmapText.BitmapFontCharacterData} glyph - The character glyph. + * @param {number} offsetX - The x offset. + * @param {number} offsetY - The y offset. + * @param {Phaser.GameObjects.Components.TransformMatrix} calcMatrix - The transform matrix. + * @param {boolean} roundPixels - Round the transform values or not? + * @param {number} tintTL - Top-left tint value. + * @param {number} tintTR - Top-right tint value. + * @param {number} tintBL - Bottom-left tint value. + * @param {number} tintBR - Bottom-right tint value. + * @param {number} tintEffect - The tint effect mode. + * @param {WebGLTexture} texture - The WebGL texture. + * @param {number} textureUnit - The texture unit. + */ +var BatchChar = function (pipeline, src, char, glyph, offsetX, offsetY, calcMatrix, roundPixels, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit) +{ + var x = (char.x - src.displayOriginX) + offsetX; + var y = (char.y - src.displayOriginY) + offsetY; - this.zoomX = x; - this.zoomY = y; + var xw = x + char.w; + var yh = y + char.h; - return this; - }, + var tx0 = calcMatrix.getXRound(x, y, roundPixels); + var ty0 = calcMatrix.getYRound(x, y, roundPixels); - /** - * Sets the mask to be applied to this Camera during rendering. - * - * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. - * - * Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * If a mask is already set on this Camera it will be immediately replaced. - * - * Masks have no impact on physics or input detection. They are purely a rendering component - * that allows you to limit what is visible during the render pass. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#setMask - * @since 3.17.0 - * - * @param {(Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask)} mask - The mask this Camera will use when rendering. - * @param {boolean} [fixedPosition=true] - Should the mask translate along with the Camera, or be fixed in place and not impacted by the Cameras transform? - * - * @return {this} This Camera instance. - */ - setMask: function (mask, fixedPosition) - { - if (fixedPosition === undefined) { fixedPosition = true; } + var tx1 = calcMatrix.getXRound(x, yh, roundPixels); + var ty1 = calcMatrix.getYRound(x, yh, roundPixels); - this.mask = mask; + var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); + var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); - this._maskCamera = (fixedPosition) ? this.cameraManager.default : this; + var tx3 = calcMatrix.getXRound(xw, y, roundPixels); + var ty3 = calcMatrix.getYRound(xw, y, roundPixels); - return this; - }, + pipeline.batchQuad(src, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, glyph.u0, glyph.v0, glyph.u1, glyph.v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); +}; - /** - * Clears the mask that this Camera was using. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#clearMask - * @since 3.17.0 - * - * @param {boolean} [destroyMask=false] - Destroy the mask before clearing it? - * - * @return {this} This Camera instance. - */ - clearMask: function (destroyMask) - { - if (destroyMask === undefined) { destroyMask = false; } +module.exports = BatchChar; - if (destroyMask && this.mask) - { - this.mask.destroy(); - } - this.mask = null; +/***/ }), - return this; - }, +/***/ 82173: +/***/ ((module) => { - /** - * Sets the visibility of this Camera. - * - * An invisible Camera will skip rendering and input tests of everything it can see. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#setVisible - * @since 3.10.0 - * - * @param {boolean} value - The visible state of the Camera. - * - * @return {this} This Camera instance. - */ +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Returns an Object suitable for JSON storage containing all of the Camera viewport and rendering properties. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#toJSON - * @since 3.0.0 - * - * @return {Phaser.Types.Cameras.Scene2D.JSONCamera} A well-formed object suitable for conversion to JSON. - */ - toJSON: function () +/** + * Calculate the full bounds, in local and world space, of a BitmapText Game Object. + * + * Returns a BitmapTextSize object that contains global and local variants of the Game Objects x and y coordinates and + * its width and height. Also includes an array of the line lengths and all word positions. + * + * The global position and size take into account the Game Object's position and scale. + * + * The local position and size just takes into account the font data. + * + * @function GetBitmapTextSize + * @since 3.0.0 + * @private + * + * @param {(Phaser.GameObjects.DynamicBitmapText|Phaser.GameObjects.BitmapText)} src - The BitmapText to calculate the bounds values for. + * @param {boolean} [round=false] - Whether to round the positions to the nearest integer. + * @param {boolean} [updateOrigin=false] - Whether to update the origin of the BitmapText after bounds calculations? + * @param {object} [out] - Object to store the results in, to save constant object creation. If not provided an empty object is returned. + * + * @return {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} The calculated bounds values of the BitmapText. + */ +var GetBitmapTextSize = function (src, round, updateOrigin, out) +{ + if (updateOrigin === undefined) { updateOrigin = false; } + + if (out === undefined) { - var output = { - name: this.name, - x: this.x, - y: this.y, - width: this.width, - height: this.height, - zoom: this.zoom, - rotation: this.rotation, - roundPixels: this.roundPixels, - scrollX: this.scrollX, - scrollY: this.scrollY, - backgroundColor: this.backgroundColor.rgba + out = { + local: { + x: 0, + y: 0, + width: 0, + height: 0 + }, + global: { + x: 0, + y: 0, + width: 0, + height: 0 + }, + lines: { + shortest: 0, + longest: 0, + lengths: null, + height: 0 + }, + wrappedText: '', + words: [], + characters: [], + scaleX: 0, + scaleY: 0 }; - if (this.useBounds) - { - output['bounds'] = { - x: this._bounds.x, - y: this._bounds.y, - width: this._bounds.width, - height: this._bounds.height - }; - } + return out; + } - return output; - }, + var text = src.text; + var textLength = text.length; + var maxWidth = src.maxWidth; + var wordWrapCharCode = src.wordWrapCharCode; - /** - * Internal method called automatically by the Camera Manager. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#update - * @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. - */ - update: function () - { - // NOOP - }, + var bx = Number.MAX_VALUE; + var by = Number.MAX_VALUE; + var bw = 0; + var bh = 0; - /** - * Internal method called automatically when the viewport changes. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#updateSystem - * @private - * @since 3.12.0 - */ - updateSystem: function () - { - if (!this.scaleManager) - { - return; - } + var chars = src.fontData.chars; + var lineHeight = src.fontData.lineHeight; + var letterSpacing = src.letterSpacing; + var lineSpacing = src.lineSpacing; - var custom = (this._x !== 0 || this._y !== 0 || this.scaleManager.width !== this._width || this.scaleManager.height !== this._height); + var xAdvance = 0; + var yAdvance = 0; - var sceneManager = this.sceneManager; + var charCode = 0; - if (custom && !this._customViewport) - { - // We need a custom viewport for this Camera - sceneManager.customViewports++; - } - else if (!custom && this._customViewport) - { - // We're turning off a custom viewport for this Camera - sceneManager.customViewports--; - } + var glyph = null; - this.dirty = true; - this._customViewport = custom; - }, + var align = src._align; - /** - * Destroys this Camera instance and its internal properties and references. - * Once destroyed you cannot use this Camera again, even if re-added to a Camera Manager. - * - * This method is called automatically by `CameraManager.remove` if that methods `runDestroy` argument is `true`, which is the default. - * - * Unless you have a specific reason otherwise, always use `CameraManager.remove` and allow it to handle the camera destruction, - * rather than calling this method directly. - * - * @method Phaser.Cameras.Scene2D.BaseCamera#destroy - * @fires Phaser.Cameras.Scene2D.Events#DESTROY - * @since 3.0.0 - */ - destroy: function () - { - this.emit(Events.DESTROY, this); + var x = 0; + var y = 0; - this.removeAllListeners(); + var scale = (src.fontSize / src.fontData.size); + var sx = scale * src.scaleX; + var sy = scale * src.scaleY; - this.matrix.destroy(); + var lastGlyph = null; + var lastCharCode = 0; + var lineWidths = []; + var shortestLine = Number.MAX_VALUE; + var longestLine = 0; + var currentLine = 0; + var currentLineWidth = 0; - this.culledObjects = []; + var i; + var words = []; + var characters = []; + var current = null; - if (this._customViewport) + // Scan for breach of maxWidth and insert carriage-returns + if (maxWidth > 0) + { + for (i = 0; i < textLength; i++) { - // We're turning off a custom viewport for this Camera - this.sceneManager.customViewports--; - } + charCode = text.charCodeAt(i); - this.renderList = []; + if (charCode === 10) + { + if (current !== null) + { + words.push({ + word: current.word, + i: current.i, + x: current.x * sx, + y: current.y * sy, + w: current.w * sx, + h: current.h * sy, + cr: true + }); - this._bounds = null; + current = null; + } - this.scene = null; - this.scaleManager = null; - this.sceneManager = null; - this.cameraManager = null; - }, + xAdvance = 0; + yAdvance += lineHeight + lineSpacing; + lastGlyph = null; - /** - * The x position of the Camera viewport, relative to the top-left of the game canvas. - * The viewport is the area into which the camera renders. - * To adjust the position the camera is looking at in the game world, see the `scrollX` value. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#x - * @type {number} - * @since 3.0.0 - */ - x: { + continue; + } - get: function () - { - return this._x; - }, + glyph = chars[charCode]; - set: function (value) - { - this._x = value; - this.updateSystem(); - } + if (!glyph) + { + continue; + } - }, + if (lastGlyph !== null) + { + var glyphKerningOffset = glyph.kerning[lastCharCode]; + } - /** - * The y position of the Camera viewport, relative to the top-left of the game canvas. - * The viewport is the area into which the camera renders. - * To adjust the position the camera is looking at in the game world, see the `scrollY` value. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#y - * @type {number} - * @since 3.0.0 - */ - y: { + if (charCode === wordWrapCharCode) + { + if (current !== null) + { + words.push({ + word: current.word, + i: current.i, + x: current.x * sx, + y: current.y * sy, + w: current.w * sx, + h: current.h * sy, + cr: false + }); - get: function () - { - return this._y; - }, + current = null; + } + } + else + { + if (current === null) + { + // We're starting a new word, recording the starting index, etc + current = { word: '', i: i, x: xAdvance, y: yAdvance, w: 0, h: lineHeight, cr: false }; + } - set: function (value) + current.word = current.word.concat(text[i]); + current.w += glyph.xOffset + glyph.xAdvance + ((glyphKerningOffset !== undefined) ? glyphKerningOffset : 0); + } + + xAdvance += glyph.xAdvance + letterSpacing; + lastGlyph = glyph; + lastCharCode = charCode; + } + + // Last word + if (current !== null) { - this._y = value; - this.updateSystem(); + words.push({ + word: current.word, + i: current.i, + x: current.x * sx, + y: current.y * sy, + w: current.w * sx, + h: current.h * sy, + cr: false + }); } - }, + // Reset for the next loop + xAdvance = 0; + yAdvance = 0; + lastGlyph = null; + lastCharCode = 0; - /** - * The width of the Camera viewport, in pixels. - * - * The viewport is the area into which the Camera renders. Setting the viewport does - * not restrict where the Camera can scroll to. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#width - * @type {number} - * @since 3.0.0 - */ - width: { + // Loop through the words array and see if we've got any > maxWidth + var prev; + var offset = 0; + var crs = []; - get: function () + for (i = 0; i < words.length; i++) { - return this._width; - }, + var entry = words[i]; + var left = entry.x; + var right = entry.x + entry.w; - set: function (value) - { - this._width = value; - this.updateSystem(); - } + if (prev) + { + var diff = left - (prev.x + prev.w); - }, + offset = left - (diff + prev.w); - /** - * The height of the Camera viewport, in pixels. - * - * The viewport is the area into which the Camera renders. Setting the viewport does - * not restrict where the Camera can scroll to. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#height - * @type {number} - * @since 3.0.0 - */ - height: { + prev = null; + } - get: function () - { - return this._height; - }, + var checkLeft = left - offset; + var checkRight = right - offset; - set: function (value) - { - this._height = value; - this.updateSystem(); - } + if (checkLeft > maxWidth || checkRight > maxWidth) + { + crs.push(entry.i - 1); - }, + if (entry.cr) + { + crs.push(entry.i + entry.word.length); - /** - * The horizontal scroll position of this Camera. - * - * Change this value to cause the Camera to scroll around your Scene. - * - * Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method, - * will automatically adjust the Camera scroll values accordingly. - * - * You can set the bounds within which the Camera can scroll via the `setBounds` method. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#scrollX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - scrollX: { + offset = 0; + prev = null; + } + else + { + prev = entry; + } + } + else if (entry.cr) + { + crs.push(entry.i + entry.word.length); - get: function () + offset = 0; + prev = null; + } + } + + var stringInsert = function (str, index, value) { - return this._scrollX; - }, + return str.substr(0, index) + value + str.substr(index + 1); + }; - set: function (value) + for (i = crs.length - 1; i >= 0; i--) { - this._scrollX = value; - this.dirty = true; + // eslint-disable-next-line quotes + text = stringInsert(text, crs[i], "\n"); } - }, + out.wrappedText = text; - /** - * The vertical scroll position of this Camera. - * - * Change this value to cause the Camera to scroll around your Scene. - * - * Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method, - * will automatically adjust the Camera scroll values accordingly. - * - * You can set the bounds within which the Camera can scroll via the `setBounds` method. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#scrollY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - scrollY: { + textLength = text.length; - get: function () - { - return this._scrollY; - }, + // Recalculated in the next loop + words = []; + current = null; + } - set: function (value) + var charIndex = 0; + + for (i = 0; i < textLength; i++) + { + charCode = text.charCodeAt(i); + + if (charCode === 10) { - this._scrollY = value; - this.dirty = true; - } + if (current !== null) + { + words.push({ + word: current.word, + i: current.i, + x: current.x * sx, + y: current.y * sy, + w: current.w * sx, + h: current.h * sy + }); - }, + current = null; + } - /** - * The Camera zoom value. Change this value to zoom in, or out of, a Scene. - * - * A value of 0.5 would zoom the Camera out, so you can now see twice as much - * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel - * now takes up 2 pixels when rendered. - * - * Set to 1 to return to the default zoom level. - * - * Be careful to never set this value to zero. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#zoom - * @type {number} - * @default 1 - * @since 3.0.0 - */ - zoom: { + xAdvance = 0; + yAdvance += lineHeight + lineSpacing; + lastGlyph = null; - get: function () - { - return (this._zoomX + this._zoomY) / 2; - }, + lineWidths[currentLine] = currentLineWidth; - set: function (value) - { - this._zoomX = value; - this._zoomY = value; + if (currentLineWidth > longestLine) + { + longestLine = currentLineWidth; + } - this.dirty = true; - } + if (currentLineWidth < shortestLine) + { + shortestLine = currentLineWidth; + } - }, + currentLine++; + currentLineWidth = 0; - /** - * The Camera horizontal zoom value. Change this value to zoom in, or out of, a Scene. - * - * A value of 0.5 would zoom the Camera out, so you can now see twice as much - * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel - * now takes up 2 pixels when rendered. - * - * Set to 1 to return to the default zoom level. - * - * Be careful to never set this value to zero. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#zoomX - * @type {number} - * @default 1 - * @since 3.50.0 - */ - zoomX: { + continue; + } - get: function () - { - return this._zoomX; - }, + glyph = chars[charCode]; - set: function (value) + if (!glyph) { - this._zoomX = value; - this.dirty = true; + continue; } - }, - - /** - * The Camera vertical zoom value. Change this value to zoom in, or out of, a Scene. - * - * A value of 0.5 would zoom the Camera out, so you can now see twice as much - * of the Scene as before. A value of 2 would zoom the Camera in, so every pixel - * now takes up 2 pixels when rendered. - * - * Set to 1 to return to the default zoom level. - * - * Be careful to never set this value to zero. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#zoomY - * @type {number} - * @default 1 - * @since 3.50.0 - */ - zoomY: { + x = xAdvance; + y = yAdvance; - get: function () + if (lastGlyph !== null) { - return this._zoomY; - }, + var kerningOffset = glyph.kerning[lastCharCode]; - set: function (value) + x += (kerningOffset !== undefined) ? kerningOffset : 0; + } + + if (bx > x) { - this._zoomY = value; - this.dirty = true; + bx = x; } - }, + if (by > y) + { + by = y; + } - /** - * The rotation of the Camera in radians. - * - * Camera rotation always takes place based on the Camera viewport. By default, rotation happens - * in the center of the viewport. You can adjust this with the `originX` and `originY` properties. - * - * Rotation influences the rendering of _all_ Game Objects visible by this Camera. However, it does not - * rotate the Camera viewport itself, which always remains an axis-aligned rectangle. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#rotation - * @type {number} - * @private - * @default 0 - * @since 3.11.0 - */ - rotation: { + var gw = x + glyph.xAdvance; + var gh = y + lineHeight; - get: function () + if (bw < gw) { - return this._rotation; - }, + bw = gw; + } - set: function (value) + if (bh < gh) { - this._rotation = value; - this.dirty = true; + bh = gh; } - }, + var charWidth = glyph.xOffset + glyph.xAdvance + ((kerningOffset !== undefined) ? kerningOffset : 0); - /** - * The horizontal position of the center of the Camera's viewport, relative to the left of the game canvas. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#centerX - * @type {number} - * @readonly - * @since 3.10.0 - */ - centerX: { + if (charCode === wordWrapCharCode) + { + if (current !== null) + { + words.push({ + word: current.word, + i: current.i, + x: current.x * sx, + y: current.y * sy, + w: current.w * sx, + h: current.h * sy + }); - get: function () + current = null; + } + } + else { - return this.x + (0.5 * this.width); + if (current === null) + { + // We're starting a new word, recording the starting index, etc + current = { word: '', i: charIndex, x: xAdvance, y: yAdvance, w: 0, h: lineHeight }; + } + + current.word = current.word.concat(text[i]); + current.w += charWidth; } - }, + characters.push({ + i: charIndex, + idx: i, + char: text[i], + code: charCode, + x: (glyph.xOffset + x) * scale, + y: (glyph.yOffset + yAdvance) * scale, + w: glyph.width * scale, + h: glyph.height * scale, + t: yAdvance * scale, + r: gw * scale, + b: lineHeight * scale, + line: currentLine, + glyph: glyph + }); - /** - * The vertical position of the center of the Camera's viewport, relative to the top of the game canvas. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#centerY - * @type {number} - * @readonly - * @since 3.10.0 - */ - centerY: { + xAdvance += glyph.xAdvance + letterSpacing + ((kerningOffset !== undefined) ? kerningOffset : 0); + lastGlyph = glyph; + lastCharCode = charCode; + currentLineWidth = gw * scale; + charIndex++; + } - get: function () - { - return this.y + (0.5 * this.height); - } + // Last word + if (current !== null) + { + words.push({ + word: current.word, + i: current.i, + x: current.x * sx, + y: current.y * sy, + w: current.w * sx, + h: current.h * sy + }); + } - }, + lineWidths[currentLine] = currentLineWidth; - /** - * The displayed width of the camera viewport, factoring in the camera zoom level. - * - * If a camera has a viewport width of 800 and a zoom of 0.5 then its display width - * would be 1600, as it's displaying twice as many pixels as zoom level 1. - * - * Equally, a camera with a width of 800 and zoom of 2 would have a display width - * of 400 pixels. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#displayWidth - * @type {number} - * @readonly - * @since 3.11.0 - */ - displayWidth: { + if (currentLineWidth > longestLine) + { + longestLine = currentLineWidth; + } - get: function () + if (currentLineWidth < shortestLine) + { + shortestLine = currentLineWidth; + } + + // Adjust all of the character positions based on alignment + if (align > 0) + { + for (var c = 0; c < characters.length; c++) { - return this.width / this.zoomX; - } + var currentChar = characters[c]; - }, + if (align === 1) + { + var ax1 = ((longestLine - lineWidths[currentChar.line]) / 2); - /** - * The displayed height of the camera viewport, factoring in the camera zoom level. - * - * If a camera has a viewport height of 600 and a zoom of 0.5 then its display height - * would be 1200, as it's displaying twice as many pixels as zoom level 1. - * - * Equally, a camera with a height of 600 and zoom of 2 would have a display height - * of 300 pixels. - * - * @name Phaser.Cameras.Scene2D.BaseCamera#displayHeight - * @type {number} - * @readonly - * @since 3.11.0 - */ - displayHeight: { + currentChar.x += ax1; + currentChar.r += ax1; + } + else if (align === 2) + { + var ax2 = (longestLine - lineWidths[currentChar.line]); - get: function () - { - return this.height / this.zoomY; + currentChar.x += ax2; + currentChar.r += ax2; + } } - } -}); + var local = out.local; + var global = out.global; + var lines = out.lines; -module.exports = BaseCamera; + local.x = bx * scale; + local.y = by * scale; + local.width = bw * scale; + local.height = bh * scale; + global.x = (src.x - src._displayOriginX) + (bx * sx); + global.y = (src.y - src._displayOriginY) + (by * sy); -/***/ }), -/* 134 */ -/***/ (function(module, exports, __webpack_require__) { + global.width = bw * sx; + global.height = bh * sy; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + lines.shortest = shortestLine; + lines.longest = longestLine; + lines.lengths = lineWidths; -var Back = __webpack_require__(334); -var Bounce = __webpack_require__(335); -var Circular = __webpack_require__(336); -var Cubic = __webpack_require__(337); -var Elastic = __webpack_require__(338); -var Expo = __webpack_require__(339); -var Linear = __webpack_require__(340); -var Quadratic = __webpack_require__(341); -var Quartic = __webpack_require__(342); -var Quintic = __webpack_require__(343); -var Sine = __webpack_require__(344); -var Stepped = __webpack_require__(345); + if (round) + { + local.x = Math.ceil(local.x); + local.y = Math.ceil(local.y); + local.width = Math.ceil(local.width); + local.height = Math.ceil(local.height); -// EaseMap -module.exports = { + global.x = Math.ceil(global.x); + global.y = Math.ceil(global.y); + global.width = Math.ceil(global.width); + global.height = Math.ceil(global.height); - Power0: Linear, - Power1: Quadratic.Out, - Power2: Cubic.Out, - Power3: Quartic.Out, - Power4: Quintic.Out, + lines.shortest = Math.ceil(shortestLine); + lines.longest = Math.ceil(longestLine); + } - Linear: Linear, - Quad: Quadratic.Out, - Cubic: Cubic.Out, - Quart: Quartic.Out, - Quint: Quintic.Out, - Sine: Sine.Out, - Expo: Expo.Out, - Circ: Circular.Out, - Elastic: Elastic.Out, - Back: Back.Out, - Bounce: Bounce.Out, - Stepped: Stepped, + if (updateOrigin) + { + src._displayOriginX = (src.originX * local.width); + src._displayOriginY = (src.originY * local.height); - 'Quad.easeIn': Quadratic.In, - 'Cubic.easeIn': Cubic.In, - 'Quart.easeIn': Quartic.In, - 'Quint.easeIn': Quintic.In, - 'Sine.easeIn': Sine.In, - 'Expo.easeIn': Expo.In, - 'Circ.easeIn': Circular.In, - 'Elastic.easeIn': Elastic.In, - 'Back.easeIn': Back.In, - 'Bounce.easeIn': Bounce.In, + global.x = src.x - (src._displayOriginX * src.scaleX); + global.y = src.y - (src._displayOriginY * src.scaleY); - 'Quad.easeOut': Quadratic.Out, - 'Cubic.easeOut': Cubic.Out, - 'Quart.easeOut': Quartic.Out, - 'Quint.easeOut': Quintic.Out, - 'Sine.easeOut': Sine.Out, - 'Expo.easeOut': Expo.Out, - 'Circ.easeOut': Circular.Out, - 'Elastic.easeOut': Elastic.Out, - 'Back.easeOut': Back.Out, - 'Bounce.easeOut': Bounce.Out, + if (round) + { + global.x = Math.ceil(global.x); + global.y = Math.ceil(global.y); + } + } - 'Quad.easeInOut': Quadratic.InOut, - 'Cubic.easeInOut': Cubic.InOut, - 'Quart.easeInOut': Quartic.InOut, - 'Quint.easeInOut': Quintic.InOut, - 'Sine.easeInOut': Sine.InOut, - 'Expo.easeInOut': Expo.InOut, - 'Circ.easeInOut': Circular.InOut, - 'Elastic.easeInOut': Elastic.InOut, - 'Back.easeInOut': Back.InOut, - 'Bounce.easeInOut': Bounce.InOut + out.words = words; + out.characters = characters; + out.lines.height = lineHeight; + out.scale = scale; + out.scaleX = src.scaleX; + out.scaleY = src.scaleY; + return out; }; +module.exports = GetBitmapTextSize; + /***/ }), -/* 135 */ -/***/ (function(module, exports) { + +/***/ 68298: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var ParseXMLBitmapFont = __webpack_require__(31476); + /** - * Calculates a linear (interpolation) value over t. + * Parse an XML Bitmap Font from an Atlas. * - * @function Phaser.Math.Linear + * Adds the parsed Bitmap Font data to the cache with the `fontName` key. + * + * @function ParseFromAtlas * @since 3.0.0 + * @private * - * @param {number} p0 - The first point. - * @param {number} p1 - The second point. - * @param {number} t - The percentage between p0 and p1 to return, represented as a number between 0 and 1. + * @param {Phaser.Scene} scene - The Scene to parse the Bitmap Font for. + * @param {string} fontName - The key of the font to add to the Bitmap Font cache. + * @param {string} textureKey - The key of the BitmapFont's texture. + * @param {string} frameKey - The key of the BitmapFont texture's frame. + * @param {string} xmlKey - The key of the XML data of the font to parse. + * @param {number} [xSpacing] - The x-axis spacing to add between each letter. + * @param {number} [ySpacing] - The y-axis spacing to add to the line height. * - * @return {number} The step t% of the way between p0 and p1. + * @return {boolean} Whether the parsing was successful or not. */ -var Linear = function (p0, p1, t) +var ParseFromAtlas = function (scene, fontName, textureKey, frameKey, xmlKey, xSpacing, ySpacing) { - return (p1 - p0) * t + p0; + var texture = scene.sys.textures.get(textureKey); + var frame = texture.get(frameKey); + var xml = scene.sys.cache.xml.get(xmlKey); + + if (frame && xml) + { + var data = ParseXMLBitmapFont(xml, frame, xSpacing, ySpacing, texture); + + scene.sys.cache.bitmapFont.add(fontName, { data: data, texture: textureKey, frame: frameKey, fromAtlas: true }); + + return true; + } + else + { + return false; + } }; -module.exports = Linear; +module.exports = ParseFromAtlas; /***/ }), -/* 136 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 39860: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var OS = __webpack_require__(105); +var GetValue = __webpack_require__(10850); /** - * Determines the browser type and version running this Phaser Game instance. - * These values are read-only and populated during the boot sequence of the game. - * They are then referenced by internal game systems and are available for you to access - * via `this.sys.game.device.browser` from within any Scene. - * - * @typedef {object} Phaser.Device.Browser + * Parses a Retro Font configuration object so you can pass it to the BitmapText constructor + * and create a BitmapText object using a fixed-width retro font. + * + * @function Phaser.GameObjects.RetroFont.Parse * @since 3.0.0 - * - * @property {boolean} chrome - Set to true if running in Chrome. - * @property {boolean} edge - Set to true if running in Microsoft Edge browser. - * @property {boolean} firefox - Set to true if running in Firefox. - * @property {boolean} ie - Set to true if running in Internet Explorer 11 or less (not Edge). - * @property {boolean} mobileSafari - Set to true if running in Mobile Safari. - * @property {boolean} opera - Set to true if running in Opera. - * @property {boolean} safari - Set to true if running in Safari. - * @property {boolean} silk - Set to true if running in the Silk browser (as used on the Amazon Kindle) - * @property {boolean} trident - Set to true if running a Trident version of Internet Explorer (IE11+) - * @property {number} chromeVersion - If running in Chrome this will contain the major version number. - * @property {number} firefoxVersion - If running in Firefox this will contain the major version number. - * @property {number} ieVersion - If running in Internet Explorer this will contain the major version number. Beyond IE10 you should use Browser.trident and Browser.tridentVersion. - * @property {number} safariVersion - If running in Safari this will contain the major version number. - * @property {number} tridentVersion - If running in Internet Explorer 11 this will contain the major version number. See {@link http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx} + * + * @param {Phaser.Scene} scene - A reference to the Phaser Scene. + * @param {Phaser.Types.GameObjects.BitmapText.RetroFontConfig} config - The font configuration object. + * + * @return {Phaser.Types.GameObjects.BitmapText.BitmapFontData} A parsed Bitmap Font data entry for the Bitmap Font cache. */ -var Browser = { - - chrome: false, - chromeVersion: 0, - edge: false, - firefox: false, - firefoxVersion: 0, - ie: false, - ieVersion: 0, - mobileSafari: false, - opera: false, - safari: false, - safariVersion: 0, - silk: false, - trident: false, - tridentVersion: 0 +var ParseRetroFont = function (scene, config) +{ + var w = config.width; + var h = config.height; -}; + var cx = Math.floor(w / 2); + var cy = Math.floor(h / 2); -function init () -{ - var ua = navigator.userAgent; + var letters = GetValue(config, 'chars', ''); - if ((/Edge\/\d+/).test(ua)) - { - Browser.edge = true; - } - else if ((/Chrome\/(\d+)/).test(ua) && !OS.windowsPhone) - { - Browser.chrome = true; - Browser.chromeVersion = parseInt(RegExp.$1, 10); - } - else if ((/Firefox\D+(\d+)/).test(ua)) - { - Browser.firefox = true; - Browser.firefoxVersion = parseInt(RegExp.$1, 10); - } - else if ((/AppleWebKit/).test(ua) && OS.iOS) - { - Browser.mobileSafari = true; - } - else if ((/MSIE (\d+\.\d+);/).test(ua)) - { - Browser.ie = true; - Browser.ieVersion = parseInt(RegExp.$1, 10); - } - else if ((/Opera/).test(ua)) - { - Browser.opera = true; - } - else if ((/Safari/).test(ua) && !OS.windowsPhone) + if (letters === '') { - Browser.safari = true; + return; } - else if ((/Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/).test(ua)) + + var key = GetValue(config, 'image', ''); + + var frame = scene.sys.textures.getFrame(key); + var textureX = frame.cutX; + var textureY = frame.cutY; + var textureWidth = frame.source.width; + var textureHeight = frame.source.height; + + var offsetX = GetValue(config, 'offset.x', 0); + var offsetY = GetValue(config, 'offset.y', 0); + var spacingX = GetValue(config, 'spacing.x', 0); + var spacingY = GetValue(config, 'spacing.y', 0); + var lineSpacing = GetValue(config, 'lineSpacing', 0); + + var charsPerRow = GetValue(config, 'charsPerRow', null); + + if (charsPerRow === null) { - Browser.ie = true; - Browser.trident = true; - Browser.tridentVersion = parseInt(RegExp.$1, 10); - Browser.ieVersion = parseInt(RegExp.$3, 10); + charsPerRow = textureWidth / w; + + if (charsPerRow > letters.length) + { + charsPerRow = letters.length; + } } - // Silk gets its own if clause because its ua also contains 'Safari' - if ((/Silk/).test(ua)) + var x = offsetX; + var y = offsetY; + + var data = { + retroFont: true, + font: key, + size: w, + lineHeight: h + lineSpacing, + chars: {} + }; + + var r = 0; + + for (var i = 0; i < letters.length; i++) { - Browser.silk = true; + var charCode = letters.charCodeAt(i); + + var u0 = (textureX + x) / textureWidth; + var v0 = (textureY + y) / textureHeight; + var u1 = (textureX + x + w) / textureWidth; + var v1 = (textureY + y + h) / textureHeight; + + data.chars[charCode] = + { + x: x, + y: y, + width: w, + height: h, + centerX: cx, + centerY: cy, + xOffset: 0, + yOffset: 0, + xAdvance: w, + data: {}, + kerning: {}, + u0: u0, + v0: v0, + u1: u1, + v1: v1 + }; + + r++; + + if (r === charsPerRow) + { + r = 0; + x = offsetX; + y += h + spacingY; + } + else + { + x += w + spacingX; + } } - return Browser; -} + var entry = { + data: data, + frame: null, + texture: key + }; -module.exports = init(); + return entry; +}; + +module.exports = ParseRetroFont; /***/ }), -/* 137 */ -/***/ (function(module, exports) { + +/***/ 31476: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Generate a random floating point number between the two given bounds, minimum inclusive, maximum exclusive. + * Read an integer value from an XML Node. * - * @function Phaser.Math.FloatBetween + * @function getValue * @since 3.0.0 + * @private * - * @param {number} min - The lower bound for the float, inclusive. - * @param {number} max - The upper bound for the float exclusive. + * @param {Node} node - The XML Node. + * @param {string} attribute - The attribute to read. * - * @return {number} A random float within the given range. + * @return {number} The parsed value. */ -var FloatBetween = function (min, max) +function getValue (node, attribute) { - return Math.random() * (max - min) + min; -}; - -module.exports = FloatBetween; - - -/***/ }), -/* 138 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return parseInt(node.getAttribute(attribute), 10); +} /** - * Checks if the given `width` and `height` are a power of two. - * Useful for checking texture dimensions. + * Parse an XML font to Bitmap Font data for the Bitmap Font cache. * - * @function Phaser.Math.Pow2.IsSize + * @function ParseXMLBitmapFont * @since 3.0.0 + * @private * - * @param {number} width - The width. - * @param {number} height - The height. + * @param {XMLDocument} xml - The XML Document to parse the font from. + * @param {Phaser.Textures.Frame} frame - The texture frame to take into account when creating the uv data. + * @param {number} [xSpacing=0] - The x-axis spacing to add between each letter. + * @param {number} [ySpacing=0] - The y-axis spacing to add to the line height. + * @param {Phaser.Textures.Texture} [texture] - If provided, each glyph in the Bitmap Font will be added to this texture as a frame. * - * @return {boolean} `true` if `width` and `height` are a power of two, otherwise `false`. + * @return {Phaser.Types.GameObjects.BitmapText.BitmapFontData} The parsed Bitmap Font data. */ -var IsSizePowerOfTwo = function (width, height) +var ParseXMLBitmapFont = function (xml, frame, xSpacing, ySpacing, texture) { - return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0); -}; + if (xSpacing === undefined) { xSpacing = 0; } + if (ySpacing === undefined) { ySpacing = 0; } -module.exports = IsSizePowerOfTwo; + var textureX = frame.cutX; + var textureY = frame.cutY; + var textureWidth = frame.source.width; + var textureHeight = frame.source.height; + var sourceIndex = frame.sourceIndex; + + var data = {}; + var info = xml.getElementsByTagName('info')[0]; + var common = xml.getElementsByTagName('common')[0]; + + data.font = info.getAttribute('face'); + data.size = getValue(info, 'size'); + data.lineHeight = getValue(common, 'lineHeight') + ySpacing; + data.chars = {}; + + var letters = xml.getElementsByTagName('char'); + + var adjustForTrim = (frame !== undefined && frame.trimmed); + + if (adjustForTrim) + { + var top = frame.height; + var left = frame.width; + } + + for (var i = 0; i < letters.length; i++) + { + var node = letters[i]; + + var charCode = getValue(node, 'id'); + var letter = String.fromCharCode(charCode); + var gx = getValue(node, 'x'); + var gy = getValue(node, 'y'); + var gw = getValue(node, 'width'); + var gh = getValue(node, 'height'); + + // Handle frame trim issues + + if (adjustForTrim) + { + if (gx < left) + { + left = gx; + } + + if (gy < top) + { + top = gy; + } + } + + if (adjustForTrim && top !== 0 && left !== 0) + { + // Now we know the top and left coordinates of the glyphs in the original data + // so we can work out how much to adjust the glyphs by + + gx -= frame.x; + gy -= frame.y; + } + + var u0 = (textureX + gx) / textureWidth; + var v0 = (textureY + gy) / textureHeight; + var u1 = (textureX + gx + gw) / textureWidth; + var v1 = (textureY + gy + gh) / textureHeight; + + data.chars[charCode] = + { + x: gx, + y: gy, + width: gw, + height: gh, + centerX: Math.floor(gw / 2), + centerY: Math.floor(gh / 2), + xOffset: getValue(node, 'xoffset'), + yOffset: getValue(node, 'yoffset'), + xAdvance: getValue(node, 'xadvance') + xSpacing, + data: {}, + kerning: {}, + u0: u0, + v0: v0, + u1: u1, + v1: v1 + }; + + if (texture && gw !== 0 && gh !== 0) + { + var charFrame = texture.add(letter, sourceIndex, gx, gy, gw, gh); + + if (charFrame) + { + charFrame.setUVs(gw, gh, u0, v0, u1, v1); + } + } + } + + var kernings = xml.getElementsByTagName('kerning'); + + for (i = 0; i < kernings.length; i++) + { + var kern = kernings[i]; + + var first = getValue(kern, 'first'); + var second = getValue(kern, 'second'); + var amount = getValue(kern, 'amount'); + + data.chars[second].kerning[first] = amount; + } + + return data; +}; + +module.exports = ParseXMLBitmapFont; /***/ }), -/* 139 */ -/***/ (function(module, exports) { + +/***/ 55873: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var RETRO_FONT_CONST = __webpack_require__(66863); +var Extend = __webpack_require__(98611); + /** - * Snap a value to nearest grid slice, using ceil. - * - * Example: if you have an interval gap of `5` and a position of `12`... you will snap to `15`. - * As will `14` snap to `15`... but `16` will snap to `20`. - * - * @function Phaser.Math.Snap.Ceil - * @since 3.0.0 - * - * @param {number} value - The value to snap. - * @param {number} gap - The interval gap of the grid. - * @param {number} [start=0] - Optional starting offset for gap. - * @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning. - * - * @return {number} The snapped value. + * @namespace Phaser.GameObjects.RetroFont + * @since 3.6.0 */ -var SnapCeil = function (value, gap, start, divide) -{ - if (start === undefined) { start = 0; } - if (gap === 0) - { - return value; - } +var RetroFont = { Parse: __webpack_require__(39860) }; - value -= start; - value = gap * Math.ceil(value / gap); +// Merge in the consts +RetroFont = Extend(false, RetroFont, RETRO_FONT_CONST); + +module.exports = RetroFont; + + +/***/ }), + +/***/ 66863: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var RETRO_FONT_CONST = { + + /** + * Text Set 1 = !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET1 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET1: ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~', + + /** + * Text Set 2 = !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET2 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET2: ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ', + + /** + * Text Set 3 = ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET3 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET3: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ', + + /** + * Text Set 4 = ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET4 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET4: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789', + + /** + * Text Set 5 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789 + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET5 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET5: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() \'!?-*:0123456789', + + /** + * Text Set 6 = ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789"(),-.' + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET6 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET6: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789"(),-.\' ', + + /** + * Text Set 7 = AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW")28FLRX-'39 + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET7 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET7: 'AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW")28FLRX-\'39', + + /** + * Text Set 8 = 0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET8 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET8: '0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ', + + /** + * Text Set 9 = ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'"?! + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET9 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET9: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,\'"?!', + + /** + * Text Set 10 = ABCDEFGHIJKLMNOPQRSTUVWXYZ + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET10 + * @type {string} + * @since 3.6.0 + */ + TEXT_SET10: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + + /** + * Text Set 11 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,"-+!?()':;0123456789 + * + * @name Phaser.GameObjects.RetroFont.TEXT_SET11 + * @since 3.6.0 + * @type {string} + */ + TEXT_SET11: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ.,"-+!?()\':;0123456789' - return (divide) ? (start + value) / gap : start + value; }; -module.exports = SnapCeil; +module.exports = RETRO_FONT_CONST; /***/ }), -/* 140 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 13468: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji -// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl - -var Class = __webpack_require__(0); +var BitmapText = __webpack_require__(44616); +var Class = __webpack_require__(56694); +var Render = __webpack_require__(88899); /** * @classdesc - * A representation of a vector in 4D space. + * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. * - * A four-component vector. + * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to + * match the font structure. * - * @class Vector4 - * @memberof Phaser.Math + * Dynamic Bitmap Text objects are different from Static Bitmap Text in that they invoke a callback for each + * letter being rendered during the render pass. This callback allows you to manipulate the properties of + * each letter being rendered, such as its position, scale or tint, allowing you to create interesting effects + * like jiggling text, which can't be done with Static text. This means that Dynamic Text takes more processing + * time, so only use them if you require the callback ability they have. + * + * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability + * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by + * processing the font texture in an image editor, applying fills and any other effects required. + * + * To create multi-line text insert \r, \n or \r\n escape codes into the text string. + * + * To create a BitmapText data files you need a 3rd party app such as: + * + * BMFont (Windows, free): {@link http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/} + * Glyph Designer (OS X, commercial): {@link http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner} + * Snow BMF (Web-based, free): {@link https://snowb.org//|https://snowb.org/} + * Littera (Flash-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/} + * + * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of + * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: {@link http://codebeautify.org/xmltojson|http://codebeautify.org/xmltojson} + * + * @class DynamicBitmapText + * @extends Phaser.GameObjects.BitmapText + * @memberof Phaser.GameObjects * @constructor * @since 3.0.0 * - * @param {number} [x] - The x component. - * @param {number} [y] - The y component. - * @param {number} [z] - The z component. - * @param {number} [w] - The w component. + * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. It can only belong to one Scene at any given time. + * @param {number} x - The x coordinate of this Game Object in world space. + * @param {number} y - The y coordinate of this Game Object in world space. + * @param {string} font - The key of the font to use from the Bitmap Font cache. + * @param {(string|string[])} [text] - The string, or array of strings, to be set as the content of this Bitmap Text. + * @param {number} [size] - The font size of this Bitmap Text. + * @param {number} [align=0] - The alignment of the text in a multi-line BitmapText object. */ -var Vector4 = new Class({ +var DynamicBitmapText = new Class({ + + Extends: BitmapText, + + Mixins: [ + Render + ], initialize: - function Vector4 (x, y, z, w) + function DynamicBitmapText (scene, x, y, font, text, size, align) { + BitmapText.call(this, scene, x, y, font, text, size, align); + + this.type = 'DynamicBitmapText'; + /** - * The x component of this Vector. + * The horizontal scroll position of the Bitmap Text. * - * @name Phaser.Math.Vector4#x + * @name Phaser.GameObjects.DynamicBitmapText#scrollX * @type {number} * @default 0 * @since 3.0.0 */ - this.x = 0; + this.scrollX = 0; /** - * The y component of this Vector. + * The vertical scroll position of the Bitmap Text. * - * @name Phaser.Math.Vector4#y + * @name Phaser.GameObjects.DynamicBitmapText#scrollY * @type {number} * @default 0 * @since 3.0.0 */ - this.y = 0; + this.scrollY = 0; /** - * The z component of this Vector. + * The crop width of the Bitmap Text. * - * @name Phaser.Math.Vector4#z + * @name Phaser.GameObjects.DynamicBitmapText#cropWidth * @type {number} * @default 0 * @since 3.0.0 */ - this.z = 0; + this.cropWidth = 0; /** - * The w component of this Vector. + * The crop height of the Bitmap Text. * - * @name Phaser.Math.Vector4#w + * @name Phaser.GameObjects.DynamicBitmapText#cropHeight * @type {number} * @default 0 * @since 3.0.0 */ - this.w = 0; + this.cropHeight = 0; - if (typeof x === 'object') - { - this.x = x.x || 0; - this.y = x.y || 0; - this.z = x.z || 0; - this.w = x.w || 0; - } - else - { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = w || 0; - } - }, + /** + * A callback that alters how each character of the Bitmap Text is rendered. + * + * @name Phaser.GameObjects.DynamicBitmapText#displayCallback + * @type {Phaser.Types.GameObjects.BitmapText.DisplayCallback} + * @since 3.0.0 + */ + this.displayCallback; - /** - * Make a clone of this Vector4. - * - * @method Phaser.Math.Vector4#clone - * @since 3.0.0 - * - * @return {Phaser.Math.Vector4} A clone of this Vector4. - */ - clone: function () - { - return new Vector4(this.x, this.y, this.z, this.w); + /** + * The data object that is populated during rendering, then passed to the displayCallback. + * You should modify this object then return it back from the callback. It's updated values + * will be used to render the specific glyph. + * + * Please note that if you need a reference to this object locally in your game code then you + * should shallow copy it, as it's updated and re-used for every glyph in the text. + * + * @name Phaser.GameObjects.DynamicBitmapText#callbackData + * @type {Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig} + * @since 3.11.0 + */ + this.callbackData = { + parent: this, + color: 0, + tint: { + topLeft: 0, + topRight: 0, + bottomLeft: 0, + bottomRight: 0 + }, + index: 0, + charCode: 0, + x: 0, + y: 0, + scale: 0, + rotation: 0, + data: 0 + }; }, /** - * Copy the components of a given Vector into this Vector. + * Set the crop size of this Bitmap Text. * - * @method Phaser.Math.Vector4#copy + * @method Phaser.GameObjects.DynamicBitmapText#setSize * @since 3.0.0 * - * @param {Phaser.Math.Vector4} src - The Vector to copy the components from. + * @param {number} width - The width of the crop. + * @param {number} height - The height of the crop. * - * @return {Phaser.Math.Vector4} This Vector4. + * @return {this} This Game Object. */ - copy: function (src) + setSize: function (width, height) { - this.x = src.x; - this.y = src.y; - this.z = src.z || 0; - this.w = src.w || 0; + this.cropWidth = width; + this.cropHeight = height; return this; }, /** - * Check whether this Vector is equal to a given Vector. - * - * Performs a strict quality check against each Vector's components. - * - * @method Phaser.Math.Vector4#equals - * @since 3.0.0 + * Set a callback that alters how each character of the Bitmap Text is rendered. * - * @param {Phaser.Math.Vector4} v - The vector to check equality with. + * The callback receives a {@link Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig} object that contains information about the character that's + * about to be rendered. * - * @return {boolean} A boolean indicating whether the two Vectors are equal or not. - */ - equals: function (v) - { - return ((this.x === v.x) && (this.y === v.y) && (this.z === v.z) && (this.w === v.w)); - }, - - /** - * Set the `x`, `y`, `z` and `w` components of the this Vector to the given `x`, `y`, `z` and `w` values. + * It should return an object with `x`, `y`, `scale` and `rotation` properties that will be used instead of the + * usual values when rendering. * - * @method Phaser.Math.Vector4#set + * @method Phaser.GameObjects.DynamicBitmapText#setDisplayCallback * @since 3.0.0 * - * @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y, z and w components. - * @param {number} y - The y value to set for this Vector. - * @param {number} z - The z value to set for this Vector. - * @param {number} w - The z value to set for this Vector. + * @param {Phaser.Types.GameObjects.BitmapText.DisplayCallback} callback - The display callback to set. * - * @return {Phaser.Math.Vector4} This Vector4. + * @return {this} This Game Object. */ - set: function (x, y, z, w) + setDisplayCallback: function (callback) { - if (typeof x === 'object') - { - this.x = x.x || 0; - this.y = x.y || 0; - this.z = x.z || 0; - this.w = x.w || 0; - } - else - { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = w || 0; - } + this.displayCallback = callback; return this; }, /** - * Add a given Vector to this Vector. Addition is component-wise. + * Set the horizontal scroll position of this Bitmap Text. * - * @method Phaser.Math.Vector4#add + * @method Phaser.GameObjects.DynamicBitmapText#setScrollX * @since 3.0.0 * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to add to this Vector. + * @param {number} value - The horizontal scroll position to set. * - * @return {Phaser.Math.Vector4} This Vector4. + * @return {this} This Game Object. */ - add: function (v) + setScrollX: function (value) { - this.x += v.x; - this.y += v.y; - this.z += v.z || 0; - this.w += v.w || 0; + this.scrollX = value; return this; }, /** - * Subtract the given Vector from this Vector. Subtraction is component-wise. + * Set the vertical scroll position of this Bitmap Text. * - * @method Phaser.Math.Vector4#subtract + * @method Phaser.GameObjects.DynamicBitmapText#setScrollY * @since 3.0.0 * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to subtract from this Vector. + * @param {number} value - The vertical scroll position to set. * - * @return {Phaser.Math.Vector4} This Vector4. + * @return {this} This Game Object. */ - subtract: function (v) + setScrollY: function (value) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z || 0; - this.w -= v.w || 0; + this.scrollY = value; return this; - }, + } - /** - * Scale this Vector by the given value. - * - * @method Phaser.Math.Vector4#scale - * @since 3.0.0 - * - * @param {number} scale - The value to scale this Vector by. - * - * @return {Phaser.Math.Vector4} This Vector4. - */ - scale: function (scale) - { - this.x *= scale; - this.y *= scale; - this.z *= scale; - this.w *= scale; +}); - return this; - }, +module.exports = DynamicBitmapText; - /** - * Calculate the length (or magnitude) of this Vector. - * - * @method Phaser.Math.Vector4#length - * @since 3.0.0 - * - * @return {number} The length of this Vector. - */ - length: function () - { - var x = this.x; - var y = this.y; - var z = this.z; - var w = this.w; - return Math.sqrt(x * x + y * y + z * z + w * w); - }, +/***/ }), - /** - * Calculate the length of this Vector squared. - * - * @method Phaser.Math.Vector4#lengthSq - * @since 3.0.0 - * - * @return {number} The length of this Vector, squared. - */ - lengthSq: function () - { - var x = this.x; - var y = this.y; - var z = this.z; - var w = this.w; +/***/ 93438: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return x * x + y * y + z * z + w * w; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Normalize this Vector. - * - * Makes the vector a unit length vector (magnitude of 1) in the same direction. - * - * @method Phaser.Math.Vector4#normalize - * @since 3.0.0 - * - * @return {Phaser.Math.Vector4} This Vector4. - */ - normalize: function () +var SetTransform = __webpack_require__(49584); + +/** + * 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.DynamicBitmapText#renderCanvas + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.DynamicBitmapText} 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 DynamicBitmapTextCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + var text = src._text; + var textLength = text.length; + + var ctx = renderer.currentContext; + + if (textLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) { - var x = this.x; - var y = this.y; - var z = this.z; - var w = this.w; - var len = x * x + y * y + z * z + w * w; + return; + } - if (len > 0) - { - len = 1 / Math.sqrt(len); + camera.addToRenderList(src); - this.x = x * len; - this.y = y * len; - this.z = z * len; - this.w = w * len; - } + var textureFrame = src.fromAtlas + ? src.frame + : src.texture.frames['__BASE']; - return this; - }, + var displayCallback = src.displayCallback; + var callbackData = src.callbackData; - /** - * Calculate the dot product of this Vector and the given Vector. - * - * @method Phaser.Math.Vector4#dot - * @since 3.0.0 - * - * @param {Phaser.Math.Vector4} v - The Vector4 to dot product with this Vector4. - * - * @return {number} The dot product of this Vector and the given Vector. - */ - dot: function (v) - { - return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; - }, + var chars = src.fontData.chars; + var lineHeight = src.fontData.lineHeight; + var letterSpacing = src._letterSpacing; - /** - * Linearly interpolate between this Vector and the given Vector. - * - * Interpolates this Vector towards the given Vector. - * - * @method Phaser.Math.Vector4#lerp - * @since 3.0.0 - * - * @param {Phaser.Math.Vector4} v - The Vector4 to interpolate towards. - * @param {number} [t=0] - The interpolation percentage, between 0 and 1. - * - * @return {Phaser.Math.Vector4} This Vector4. - */ - lerp: function (v, t) - { - if (t === undefined) { t = 0; } + var xAdvance = 0; + var yAdvance = 0; - var ax = this.x; - var ay = this.y; - var az = this.z; - var aw = this.w; + var charCode = 0; - this.x = ax + t * (v.x - ax); - this.y = ay + t * (v.y - ay); - this.z = az + t * (v.z - az); - this.w = aw + t * (v.w - aw); + var glyph = null; + var glyphX = 0; + var glyphY = 0; + var glyphW = 0; + var glyphH = 0; - return this; - }, + var x = 0; + var y = 0; - /** - * Perform a component-wise multiplication between this Vector and the given Vector. - * - * Multiplies this Vector by the given Vector. - * - * @method Phaser.Math.Vector4#multiply - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to multiply this Vector by. - * - * @return {Phaser.Math.Vector4} This Vector4. - */ - multiply: function (v) - { - this.x *= v.x; - this.y *= v.y; - this.z *= v.z || 1; - this.w *= v.w || 1; + var lastGlyph = null; + var lastCharCode = 0; - return this; - }, + var image = src.frame.source.image; - /** - * Perform a component-wise division between this Vector and the given Vector. - * - * Divides this Vector by the given Vector. - * - * @method Phaser.Math.Vector4#divide - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to divide this Vector by. - * - * @return {Phaser.Math.Vector4} This Vector4. - */ - divide: function (v) - { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z || 1; - this.w /= v.w || 1; + var textureX = textureFrame.cutX; + var textureY = textureFrame.cutY; - return this; - }, + var rotation = 0; + var scale = 0; + var baseScale = (src._fontSize / src.fontData.size); - /** - * Calculate the distance between this Vector and the given Vector. - * - * @method Phaser.Math.Vector4#distance - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to. - * - * @return {number} The distance from this Vector to the given Vector. - */ - distance: function (v) - { - var dx = v.x - this.x; - var dy = v.y - this.y; - var dz = v.z - this.z || 0; - var dw = v.w - this.w || 0; + var align = src._align; + var currentLine = 0; + var lineOffsetX = 0; - return Math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw); - }, + // Update the bounds - skipped internally if not dirty + src.getTextBounds(false); - /** - * Calculate the distance between this Vector and the given Vector, squared. - * - * @method Phaser.Math.Vector4#distanceSq - * @since 3.0.0 - * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to. - * - * @return {number} The distance from this Vector to the given Vector, squared. - */ - distanceSq: function (v) + var lineData = src._bounds.lines; + + if (align === 1) { - var dx = v.x - this.x; - var dy = v.y - this.y; - var dz = v.z - this.z || 0; - var dw = v.w - this.w || 0; + lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2; + } + else if (align === 2) + { + lineOffsetX = (lineData.longest - lineData.lengths[0]); + } - return dx * dx + dy * dy + dz * dz + dw * dw; - }, + ctx.translate(-src.displayOriginX, -src.displayOriginY); - /** - * Negate the `x`, `y`, `z` and `w` components of this Vector. - * - * @method Phaser.Math.Vector4#negate - * @since 3.0.0 - * - * @return {Phaser.Math.Vector4} This Vector4. - */ - negate: function () - { - this.x = -this.x; - this.y = -this.y; - this.z = -this.z; - this.w = -this.w; + var roundPixels = camera.roundPixels; - return this; - }, + if (src.cropWidth > 0 && src.cropHeight > 0) + { + ctx.beginPath(); + ctx.rect(0, 0, src.cropWidth, src.cropHeight); + ctx.clip(); + } - /** - * Transform this Vector with the given Matrix. - * - * @method Phaser.Math.Vector4#transformMat4 - * @since 3.0.0 - * - * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector4 with. - * - * @return {Phaser.Math.Vector4} This Vector4. - */ - transformMat4: function (mat) + for (var i = 0; i < textLength; i++) { - var x = this.x; - var y = this.y; - var z = this.z; - var w = this.w; - var m = mat.val; + // Reset the scale (in case the callback changed it) + scale = baseScale; + rotation = 0; - this.x = m[0] * x + m[4] * y + m[8] * z + m[12] * w; - this.y = m[1] * x + m[5] * y + m[9] * z + m[13] * w; - this.z = m[2] * x + m[6] * y + m[10] * z + m[14] * w; - this.w = m[3] * x + m[7] * y + m[11] * z + m[15] * w; + charCode = text.charCodeAt(i); - return this; - }, + if (charCode === 10) + { + currentLine++; - /** - * Transform this Vector with the given Quaternion. - * - * @method Phaser.Math.Vector4#transformQuat - * @since 3.0.0 - * - * @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with. - * - * @return {Phaser.Math.Vector4} This Vector4. - */ - transformQuat: function (q) - { - var x = this.x; - var y = this.y; - var z = this.z; - var qx = q.x; - var qy = q.y; - var qz = q.z; - var qw = q.w; + if (align === 1) + { + lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2; + } + else if (align === 2) + { + lineOffsetX = (lineData.longest - lineData.lengths[currentLine]); + } - // calculate quat * vec - var ix = qw * x + qy * z - qz * y; - var iy = qw * y + qz * x - qx * z; - var iz = qw * z + qx * y - qy * x; - var iw = -qx * x - qy * y - qz * z; + xAdvance = 0; + yAdvance += lineHeight; + lastGlyph = null; - // calculate result * inverse quat - this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; - this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; - this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + continue; + } - return this; - }, + glyph = chars[charCode]; - /** - * Make this Vector the zero vector (0, 0, 0, 0). - * - * @method Phaser.Math.Vector4#reset - * @since 3.0.0 - * - * @return {Phaser.Math.Vector4} This Vector4. - */ - reset: function () - { - this.x = 0; - this.y = 0; - this.z = 0; - this.w = 0; + if (!glyph) + { + continue; + } - return this; - } + glyphX = textureX + glyph.x; + glyphY = textureY + glyph.y; -}); + glyphW = glyph.width; + glyphH = glyph.height; -Vector4.prototype.sub = Vector4.prototype.subtract; -Vector4.prototype.mul = Vector4.prototype.multiply; -Vector4.prototype.div = Vector4.prototype.divide; -Vector4.prototype.dist = Vector4.prototype.distance; -Vector4.prototype.distSq = Vector4.prototype.distanceSq; -Vector4.prototype.len = Vector4.prototype.length; -Vector4.prototype.lenSq = Vector4.prototype.lengthSq; + x = (glyph.xOffset + xAdvance) - src.scrollX; + y = (glyph.yOffset + yAdvance) - src.scrollY; -module.exports = Vector4; + if (lastGlyph !== null) + { + var kerningOffset = glyph.kerning[lastCharCode]; + x += (kerningOffset !== undefined) ? kerningOffset : 0; + } + + if (displayCallback) + { + callbackData.index = i; + callbackData.charCode = charCode; + callbackData.x = x; + callbackData.y = y; + callbackData.scale = scale; + callbackData.rotation = rotation; + callbackData.data = glyph.data; + + var output = displayCallback(callbackData); + + x = output.x; + y = output.y; + scale = output.scale; + rotation = output.rotation; + } + + x *= scale; + y *= scale; + + x += lineOffsetX; + + xAdvance += glyph.xAdvance + letterSpacing + ((kerningOffset !== undefined) ? kerningOffset : 0); + lastGlyph = glyph; + lastCharCode = charCode; + + // Nothing to render or a space? Then skip to the next glyph + if (glyphW === 0 || glyphH === 0 || charCode === 32) + { + continue; + } + + if (roundPixels) + { + x = Math.round(x); + y = Math.round(y); + } + + ctx.save(); + + ctx.translate(x, y); + + ctx.rotate(rotation); + + ctx.scale(scale, scale); + + ctx.drawImage(image, glyphX, glyphY, glyphW, glyphH, 0, 0, glyphW, glyphH); + + ctx.restore(); + } + + ctx.restore(); +}; + +module.exports = DynamicBitmapTextCanvasRenderer; /***/ }), -/* 141 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 67513: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Events = __webpack_require__(91); +var BitmapText = __webpack_require__(13468); +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); /** - * @classdesc - * A Render Target encapsulates a WebGL framebuffer and the WebGL Texture that displays it. + * Creates a new Dynamic Bitmap Text Game Object and returns 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. + * Note: This method will only be available if the Dynamic Bitmap Text Game Object has been built into Phaser. * - * @class RenderTarget - * @memberof Phaser.Renderer.WebGL - * @constructor - * @since 3.50.0 + * @method Phaser.GameObjects.GameObjectCreator#dynamicBitmapText + * @since 3.0.0 + *² + * @param {Phaser.Types.GameObjects.BitmapText.BitmapTextConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. * - * @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? + * @return {Phaser.GameObjects.DynamicBitmapText} The Game Object that was created. */ -var RenderTarget = new Class({ +GameObjectCreator.register('dynamicBitmapText', function (config, addToScene) +{ + if (config === undefined) { config = {}; } - initialize: + var font = GetAdvancedValue(config, 'font', ''); + var text = GetAdvancedValue(config, 'text', ''); + var size = GetAdvancedValue(config, 'size', false); - function RenderTarget (renderer, width, height, scale, minFilter, autoClear, autoResize) + var bitmapText = new BitmapText(this.scene, 0, 0, font, text, size); + + if (addToScene !== undefined) { - if (scale === undefined) { scale = 1; } - if (minFilter === undefined) { minFilter = 0; } - if (autoClear === undefined) { autoClear = true; } - if (autoResize === undefined) { autoResize = false; } + config.add = addToScene; + } - /** - * A reference to the WebGLRenderer instance. - * - * @name Phaser.Renderer.WebGL.RenderTarget#renderer - * @type {Phaser.Renderer.WebGL.WebGLRenderer} - * @since 3.50.0 - */ - this.renderer = renderer; + BuildGameObject(this.scene, bitmapText, config); - /** - * 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; + return bitmapText; +}); - /** - * 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; +// When registering a factory function 'this' refers to the GameObjectCreator context. - /** - * The width of the texture. - * - * @name Phaser.Renderer.WebGL.RenderTarget#width - * @type {number} + +/***/ }), + +/***/ 94145: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var DynamicBitmapText = __webpack_require__(13468); +var GameObjectFactory = __webpack_require__(61286); + +/** + * Creates a new Dynamic Bitmap Text Game Object and adds it to the Scene. + * + * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. + * + * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to + * match the font structure. + * + * Dynamic Bitmap Text objects are different from Static Bitmap Text in that they invoke a callback for each + * letter being rendered during the render pass. This callback allows you to manipulate the properties of + * each letter being rendered, such as its position, scale or tint, allowing you to create interesting effects + * like jiggling text, which can't be done with Static text. This means that Dynamic Text takes more processing + * time, so only use them if you require the callback ability they have. + * + * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability + * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by + * processing the font texture in an image editor, applying fills and any other effects required. + * + * To create multi-line text insert \r, \n or \r\n escape codes into the text string. + * + * To create a BitmapText data files you need a 3rd party app such as: + * + * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/ + * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner + * Littera (Web-based, free): http://kvazars.com/littera/ + * + * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of + * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: http://codebeautify.org/xmltojson + * + * Note: This method will only be available if the Dynamic Bitmap Text Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#dynamicBitmapText + * @since 3.0.0 + * + * @param {number} x - The x position of the Game Object. + * @param {number} y - The y position of the Game Object. + * @param {string} font - The key of the font to use from the BitmapFont cache. + * @param {(string|string[])} [text] - The string, or array of strings, to be set as the content of this Bitmap Text. + * @param {number} [size] - The font size to set. + * + * @return {Phaser.GameObjects.DynamicBitmapText} The Game Object that was created. + */ +GameObjectFactory.register('dynamicBitmapText', function (x, y, font, text, size) +{ + return this.displayList.add(new DynamicBitmapText(this.scene, x, y, font, text, size)); +}); + +// When registering a factory function 'this' refers to the GameObjectFactory 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 + + +/***/ }), + +/***/ 88899: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(16873); +} + +if (true) +{ + renderCanvas = __webpack_require__(93438); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 16873: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetCalcMatrix = __webpack_require__(73329); +var TransformMatrix = __webpack_require__(69360); +var Utils = __webpack_require__(75512); + +var tempMatrix = 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.DynamicBitmapText#renderWebGL + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.DynamicBitmapText} 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 DynamicBitmapTextWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + var text = src.text; + var textLength = text.length; + + if (textLength === 0) + { + return; + } + + camera.addToRenderList(src); + + var pipeline = renderer.pipelines.set(src.pipeline, src); + + var result = GetCalcMatrix(src, camera, parentMatrix); + + // This causes a flush if the BitmapText has a Post Pipeline + renderer.pipelines.preBatch(src); + + var spriteMatrix = result.sprite; + var calcMatrix = result.calc; + + var fontMatrix = tempMatrix; + + var crop = (src.cropWidth > 0 || src.cropHeight > 0); + + if (crop) + { + pipeline.flush(); + + renderer.pushScissor( + calcMatrix.tx, + calcMatrix.ty, + src.cropWidth * calcMatrix.scaleX, + src.cropHeight * calcMatrix.scaleY + ); + } + + var frame = src.frame; + var texture = frame.glTexture; + + var tintEffect = src.tintFill; + var tintTL = Utils.getTintAppendFloatAlpha(src.tintTopLeft, camera.alpha * src._alphaTL); + var tintTR = Utils.getTintAppendFloatAlpha(src.tintTopRight, camera.alpha * src._alphaTR); + var tintBL = Utils.getTintAppendFloatAlpha(src.tintBottomLeft, camera.alpha * src._alphaBL); + var tintBR = Utils.getTintAppendFloatAlpha(src.tintBottomRight, camera.alpha * src._alphaBR); + + var textureUnit = pipeline.setGameObject(src); + + var xAdvance = 0; + var yAdvance = 0; + var charCode = 0; + var lastCharCode = 0; + var letterSpacing = src.letterSpacing; + var glyph; + var glyphW = 0; + var glyphH = 0; + var lastGlyph; + var scrollX = src.scrollX; + var scrollY = src.scrollY; + + var fontData = src.fontData; + var chars = fontData.chars; + var lineHeight = fontData.lineHeight; + var scale = (src.fontSize / fontData.size); + var rotation = 0; + + var align = src._align; + var currentLine = 0; + var lineOffsetX = 0; + + // Update the bounds - skipped internally if not dirty + var bounds = src.getTextBounds(false); + + // In case the method above changed it (word wrapping) + if (src.maxWidth > 0) + { + text = bounds.wrappedText; + textLength = text.length; + } + + var lineData = src._bounds.lines; + + if (align === 1) + { + lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2; + } + else if (align === 2) + { + lineOffsetX = (lineData.longest - lineData.lengths[0]); + } + + var roundPixels = camera.roundPixels; + var displayCallback = src.displayCallback; + var callbackData = src.callbackData; + + for (var i = 0; i < textLength; i++) + { + charCode = text.charCodeAt(i); + + // Carriage-return + if (charCode === 10) + { + currentLine++; + + if (align === 1) + { + lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2; + } + else if (align === 2) + { + lineOffsetX = (lineData.longest - lineData.lengths[currentLine]); + } + + xAdvance = 0; + yAdvance += lineHeight; + lastGlyph = null; + + continue; + } + + glyph = chars[charCode]; + + if (!glyph) + { + continue; + } + + glyphW = glyph.width; + glyphH = glyph.height; + + var x = (glyph.xOffset + xAdvance) - scrollX; + var y = (glyph.yOffset + yAdvance) - scrollY; + + if (lastGlyph !== null) + { + var kerningOffset = glyph.kerning[lastCharCode]; + x += (kerningOffset !== undefined) ? kerningOffset : 0; + } + + xAdvance += glyph.xAdvance + letterSpacing; + lastGlyph = glyph; + lastCharCode = charCode; + + // Nothing to render or a space? Then skip to the next glyph + if (glyphW === 0 || glyphH === 0 || charCode === 32) + { + continue; + } + + scale = (src.fontSize / src.fontData.size); + rotation = 0; + + if (displayCallback) + { + callbackData.color = 0; + callbackData.tint.topLeft = tintTL; + callbackData.tint.topRight = tintTR; + callbackData.tint.bottomLeft = tintBL; + callbackData.tint.bottomRight = tintBR; + callbackData.index = i; + callbackData.charCode = charCode; + callbackData.x = x; + callbackData.y = y; + callbackData.scale = scale; + callbackData.rotation = rotation; + callbackData.data = glyph.data; + + var output = displayCallback(callbackData); + + x = output.x; + y = output.y; + scale = output.scale; + rotation = output.rotation; + + if (output.color) + { + tintTL = output.color; + tintTR = output.color; + tintBL = output.color; + tintBR = output.color; + } + else + { + tintTL = output.tint.topLeft; + tintTR = output.tint.topRight; + tintBL = output.tint.bottomLeft; + tintBR = output.tint.bottomRight; + } + + tintTL = Utils.getTintAppendFloatAlpha(tintTL, camera.alpha * src._alphaTL); + tintTR = Utils.getTintAppendFloatAlpha(tintTR, camera.alpha * src._alphaTR); + tintBL = Utils.getTintAppendFloatAlpha(tintBL, camera.alpha * src._alphaBL); + tintBR = Utils.getTintAppendFloatAlpha(tintBR, camera.alpha * src._alphaBR); + } + + x *= scale; + y *= scale; + + x -= src.displayOriginX; + y -= src.displayOriginY; + + x += lineOffsetX; + + fontMatrix.applyITRS(x, y, rotation, scale, scale); + + calcMatrix.multiply(fontMatrix, spriteMatrix); + + var u0 = glyph.u0; + var v0 = glyph.v0; + var u1 = glyph.u1; + var v1 = glyph.v1; + + var xw = glyphW; + var yh = glyphH; + + var tx0 = spriteMatrix.e; + var ty0 = spriteMatrix.f; + + var tx1 = yh * spriteMatrix.c + spriteMatrix.e; + var ty1 = yh * spriteMatrix.d + spriteMatrix.f; + + var tx2 = xw * spriteMatrix.a + yh * spriteMatrix.c + spriteMatrix.e; + var ty2 = xw * spriteMatrix.b + yh * spriteMatrix.d + spriteMatrix.f; + + var tx3 = xw * spriteMatrix.a + spriteMatrix.e; + var ty3 = xw * spriteMatrix.b + spriteMatrix.f; + + if (roundPixels) + { + tx0 = Math.round(tx0); + ty0 = Math.round(ty0); + + tx1 = Math.round(tx1); + ty1 = Math.round(ty1); + + tx2 = Math.round(tx2); + ty2 = Math.round(ty2); + + tx3 = Math.round(tx3); + ty3 = Math.round(ty3); + } + + pipeline.batchQuad(src, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); + } + + if (crop) + { + pipeline.flush(); + + renderer.popScissor(); + } + + renderer.pipelines.postBatch(src); +}; + +module.exports = DynamicBitmapTextWebGLRenderer; + + +/***/ }), + +/***/ 44616: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Clamp = __webpack_require__(82897); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var GetBitmapTextSize = __webpack_require__(82173); +var ParseFromAtlas = __webpack_require__(68298); +var ParseXMLBitmapFont = __webpack_require__(31476); +var Rectangle = __webpack_require__(74118); +var Render = __webpack_require__(84557); + +/** + * @classdesc + * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. + * + * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to + * match the font structure. + * + * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability + * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by + * processing the font texture in an image editor, applying fills and any other effects required. + * + * To create multi-line text insert \r, \n or \r\n escape codes into the text string. + * + * To create a BitmapText data files you need a 3rd party app such as: + * + * BMFont (Windows, free): {@link http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/} + * Glyph Designer (OS X, commercial): {@link http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner} + * Snow BMF (Web-based, free): {@link https://snowb.org//|https://snowb.org/} + * Littera (Flash-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/} + * + * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of + * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: {@link http://codebeautify.org/xmltojson|http://codebeautify.org/xmltojson} + * + * @class BitmapText + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @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. It can only belong to one Scene at any given time. + * @param {number} x - The x coordinate of this Game Object in world space. + * @param {number} y - The y coordinate of this Game Object in world space. + * @param {string} font - The key of the font to use from the Bitmap Font cache. + * @param {(string|string[])} [text] - The string, or array of strings, to be set as the content of this Bitmap Text. + * @param {number} [size] - The font size of this Bitmap Text. + * @param {number} [align=0] - The alignment of the text in a multi-line BitmapText object. + */ +var BitmapText = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.Depth, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Texture, + Components.Tint, + Components.Transform, + Components.Visible, + Render + ], + + initialize: + + function BitmapText (scene, x, y, font, text, size, align) + { + if (text === undefined) { text = ''; } + if (align === undefined) { align = 0; } + + GameObject.call(this, scene, 'BitmapText'); + + /** + * The key of the Bitmap Font used by this Bitmap Text. + * To change the font after creation please use `setFont`. + * + * @name Phaser.GameObjects.BitmapText#font + * @type {string} * @readonly - * @since 3.50.0 + * @since 3.0.0 */ - this.width = 0; + this.font = font; + + var entry = this.scene.sys.cache.bitmapFont.get(font); + + if (!entry) + { + console.warn('Invalid BitmapText key: ' + font); + } /** - * The height of the texture. + * The data of the Bitmap Font used by this Bitmap Text. * - * @name Phaser.Renderer.WebGL.RenderTarget#height - * @type {number} + * @name Phaser.GameObjects.BitmapText#fontData + * @type {Phaser.Types.GameObjects.BitmapText.BitmapFontData} * @readonly + * @since 3.0.0 + */ + this.fontData = entry.data; + + /** + * The text that this Bitmap Text object displays. + * + * @name Phaser.GameObjects.BitmapText#_text + * @type {string} + * @private + * @since 3.0.0 + */ + this._text = ''; + + /** + * The font size of this Bitmap Text. + * + * @name Phaser.GameObjects.BitmapText#_fontSize + * @type {number} + * @private + * @since 3.0.0 + */ + this._fontSize = size || this.fontData.size; + + /** + * Adds / Removes spacing between characters. + * + * Can be a negative or positive number. + * + * @name Phaser.GameObjects.BitmapText#_letterSpacing + * @type {number} + * @private + * @since 3.4.0 + */ + this._letterSpacing = 0; + + /** + * Adds / Removes line spacing in a multiline BitmapText object. + * + * Can be a negative or positive number. + * + * @name Phaser.GameObjects.BitmapText#_lineSpacing + * @type {number} + * @private + * @since 3.60.0 + */ + this._lineSpacing = 0; + + /** + * Controls the alignment of each line of text in this BitmapText object. + * Only has any effect when this BitmapText contains multiple lines of text, split with carriage-returns. + * Has no effect with single-lines of text. + * + * See the methods `setLeftAlign`, `setCenterAlign` and `setRightAlign`. + * + * 0 = Left aligned (default) + * 1 = Middle aligned + * 2 = Right aligned + * + * The alignment position is based on the longest line of text. + * + * @name Phaser.GameObjects.BitmapText#_align + * @type {number} + * @private + * @since 3.11.0 + */ + this._align = align; + + /** + * An object that describes the size of this Bitmap Text. + * + * @name Phaser.GameObjects.BitmapText#_bounds + * @type {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} + * @private + * @since 3.0.0 + */ + this._bounds = GetBitmapTextSize(); + + /** + * An internal dirty flag for bounds calculation. + * + * @name Phaser.GameObjects.BitmapText#_dirty + * @type {boolean} + * @private + * @since 3.11.0 + */ + this._dirty = true; + + /** + * Internal cache var holding the maxWidth. + * + * @name Phaser.GameObjects.BitmapText#_maxWidth + * @type {number} + * @private + * @since 3.21.0 + */ + this._maxWidth = 0; + + /** + * The character code used to detect for word wrapping. + * Defaults to 32 (a space character). + * + * @name Phaser.GameObjects.BitmapText#wordWrapCharCode + * @type {number} + * @since 3.21.0 + */ + this.wordWrapCharCode = 32; + + /** + * Internal array holding the character tint color data. + * + * @name Phaser.GameObjects.BitmapText#charColors + * @type {array} + * @private * @since 3.50.0 */ - this.height = 0; + this.charColors = []; /** - * A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. + * The horizontal offset of the drop shadow. * - * A value of 1 matches it. 0.5 makes the Render Target half the size of the renderer, etc. + * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. * - * @name Phaser.Renderer.WebGL.RenderTarget#scale + * @name Phaser.GameObjects.BitmapText#dropShadowX * @type {number} * @since 3.50.0 */ - this.scale = scale; + this.dropShadowX = 0; /** - * The minFilter mode of the texture. 0 is `LINEAR`, 1 is `NEAREST`. + * The vertical offset of the drop shadow. * - * @name Phaser.Renderer.WebGL.RenderTarget#minFilter + * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. + * + * @name Phaser.GameObjects.BitmapText#dropShadowY * @type {number} * @since 3.50.0 */ - this.minFilter = minFilter; + this.dropShadowY = 0; /** - * Controls if this Render Target is automatically cleared (via `gl.COLOR_BUFFER_BIT`) - * during the `RenderTarget.bind` method. + * The color of the drop shadow. * - * 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. + * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. * - * @name Phaser.Renderer.WebGL.RenderTarget#autoClear - * @type {boolean} + * @name Phaser.GameObjects.BitmapText#dropShadowColor + * @type {number} * @since 3.50.0 */ - this.autoClear = autoClear; + this.dropShadowColor = 0x000000; /** - * Does this Render Target automatically resize when the WebGL Renderer does? + * The alpha value of the drop shadow. * - * Modify this property via the `setAutoResize` method. + * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. * - * @name Phaser.Renderer.WebGL.RenderTarget#autoResize + * @name Phaser.GameObjects.BitmapText#dropShadowAlpha + * @type {number} + * @since 3.50.0 + */ + this.dropShadowAlpha = 0.5; + + /** + * Indicates whether the font texture is from an atlas or not. + * + * @name Phaser.GameObjects.BitmapText#fromAtlas * @type {boolean} + * @since 3.54.0 * @readonly - * @since 3.50.0 */ - this.autoResize = false; + this.fromAtlas = entry.fromAtlas; - this.resize(width, height); + this.setTexture(entry.texture, entry.frame); + this.setPosition(x, y); + this.setOrigin(0, 0); + this.initPipeline(); + this.initPostPipeline(); - if (autoResize) - { - this.setAutoResize(true); - } + this.setText(text); }, /** - * 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 + * Set the lines of text in this BitmapText to be left-aligned. + * This only has any effect if this BitmapText contains more than one line of text. * - * @param {boolean} autoResize - Automatically resize this Render Target when the WebGL Renderer resizes? + * @method Phaser.GameObjects.BitmapText#setLeftAlign + * @since 3.11.0 * - * @return {this} This RenderTarget instance. + * @return {this} This BitmapText Object. */ - setAutoResize: function (autoResize) + setLeftAlign: function () { - 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._align = BitmapText.ALIGN_LEFT; - this.autoResize = false; - } + this._dirty = true; 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 + * Set the lines of text in this BitmapText to be center-aligned. + * This only has any effect if this BitmapText contains more than one line of text. * - * @param {number} width - The new width of this Render Target. - * @param {number} height - The new height of this Render Target. + * @method Phaser.GameObjects.BitmapText#setCenterAlign + * @since 3.11.0 * - * @return {this} This RenderTarget instance. + * @return {this} This BitmapText Object. */ - resize: function (width, height) + setCenterAlign: function () { - 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; - - width = Math.round(width); - height = Math.round(height); + this._align = BitmapText.ALIGN_CENTER; - if (width <= 0) - { - width = 1; - } + this._dirty = true; - if (height <= 0) - { - height = 1; - } + return this; + }, - this.texture = renderer.createTextureFromSource(null, width, height, this.minFilter); - this.framebuffer = renderer.createFramebuffer(width, height, this.texture, false); + /** + * Set the lines of text in this BitmapText to be right-aligned. + * This only has any effect if this BitmapText contains more than one line of text. + * + * @method Phaser.GameObjects.BitmapText#setRightAlign + * @since 3.11.0 + * + * @return {this} This BitmapText Object. + */ + setRightAlign: function () + { + this._align = BitmapText.ALIGN_RIGHT; - this.width = width; - this.height = height; - } + this._dirty = true; return this; }, /** - * Pushes this Render Target as the current frame buffer of the renderer. - * - * If `autoClear` is set, then clears the texture. + * Set the font size of this Bitmap Text. * - * If `adjustViewport` is `true` then it will flush the renderer and then adjust the GL viewport. + * @method Phaser.GameObjects.BitmapText#setFontSize + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.RenderTarget#bind - * @since 3.50.0 + * @param {number} size - The font size to set. * - * @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. + * @return {this} This BitmapText Object. */ - bind: function (adjustViewport, width, height) + setFontSize: function (size) { - if (adjustViewport === undefined) { adjustViewport = false; } - - if (adjustViewport) - { - this.renderer.flush(); - } + this._fontSize = size; - if (width && height) - { - this.resize(width, height); - } + this._dirty = true; - this.renderer.pushFramebuffer(this.framebuffer, false, false, false); + return this; + }, - if (adjustViewport) - { - this.adjustViewport(); - } + /** + * Sets the letter spacing between each character of this Bitmap Text. + * Can be a positive value to increase the space, or negative to reduce it. + * Spacing is applied after the kerning values have been set. + * + * @method Phaser.GameObjects.BitmapText#setLetterSpacing + * @since 3.4.0 + * + * @param {number} [spacing=0] - The amount of horizontal space to add between each character. + * + * @return {this} This BitmapText Object. + */ + setLetterSpacing: function (spacing) + { + if (spacing === undefined) { spacing = 0; } - if (this.autoClear) - { - var gl = this.renderer.gl; + this._letterSpacing = spacing; - gl.clearColor(0, 0, 0, 0); + this._dirty = true; - gl.clear(gl.COLOR_BUFFER_BIT); - } + return this; }, /** - * Adjusts the GL viewport to match the width and height of this Render Target. + * Sets the line spacing value. This value is added to the font height to + * calculate the overall line height. * - * Also disables `SCISSOR_TEST`. + * Spacing can be a negative or positive number. * - * @method Phaser.Renderer.WebGL.RenderTarget#adjustViewport - * @since 3.50.0 + * Only has an effect if this BitmapText object contains multiple lines of text. + * + * @method Phaser.GameObjects.BitmapText#setLineSpacing + * @since 3.60.0 + * + * @param {number} [spacing=0] - The amount of space to add between each line in multi-line text. + * + * @return {this} This BitmapText Object. */ - adjustViewport: function () + setLineSpacing: function (spacing) { - var gl = this.renderer.gl; + if (spacing === undefined) { spacing = 0; } - gl.viewport(0, 0, this.width, this.height); + this.lineSpacing = spacing; - gl.disable(gl.SCISSOR_TEST); + return this; }, /** - * Clears this Render Target. + * Set the textual content of this BitmapText. * - * @method Phaser.Renderer.WebGL.RenderTarget#clear - * @since 3.50.0 + * An array of strings will be converted into multi-line text. Use the align methods to change multi-line alignment. + * + * @method Phaser.GameObjects.BitmapText#setText + * @since 3.0.0 + * + * @param {(string|string[])} value - The string, or array of strings, to be set as the content of this BitmapText. + * + * @return {this} This BitmapText Object. */ - clear: function () + setText: function (value) { - var renderer = this.renderer; - var gl = renderer.gl; - - renderer.pushFramebuffer(this.framebuffer); + if (!value && value !== 0) + { + value = ''; + } - gl.disable(gl.SCISSOR_TEST); + if (Array.isArray(value)) + { + value = value.join('\n'); + } - gl.clearColor(0, 0, 0, 0); + if (value !== this.text) + { + this._text = value.toString(); - gl.clear(gl.COLOR_BUFFER_BIT); + this._dirty = true; - renderer.popFramebuffer(); + this.updateDisplayOrigin(); + } - renderer.resetScissor(); + return this; }, /** - * Unbinds this Render Target and optionally flushes the WebGL Renderer first. + * Sets a drop shadow effect on this Bitmap Text. * - * @name Phaser.Renderer.WebGL.RenderTarget#unbind + * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. + * + * You can set the vertical and horizontal offset of the shadow, as well as the color and alpha. + * + * Once a shadow has been enabled you can modify the `dropShadowX` and `dropShadowY` properties of this + * Bitmap Text directly to adjust the position of the shadow in real-time. + * + * If you wish to clear the shadow, call this method with no parameters specified. + * + * @method Phaser.GameObjects.BitmapText#setDropShadow + * @webglOnly * @since 3.50.0 * - * @param {boolean} [flush=false] - Flush the WebGL Renderer before unbinding? + * @param {number} [x=0] - The horizontal offset of the drop shadow. + * @param {number} [y=0] - The vertical offset of the drop shadow. + * @param {number} [color=0x000000] - The color of the drop shadow, given as a hex value, i.e. `0x000000` for black. + * @param {number} [alpha=0.5] - The alpha of the drop shadow, given as a float between 0 and 1. This is combined with the Bitmap Text alpha as well. * - * @return {WebGLFramebuffer} The Framebuffer that was set, or `null` if there aren't any more in the stack. + * @return {this} This BitmapText Object. */ - unbind: function (flush) + setDropShadow: function (x, y, color, alpha) { - if (flush === undefined) { flush = false; } - - var renderer = this.renderer; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (color === undefined) { color = 0x000000; } + if (alpha === undefined) { alpha = 0.5; } - if (flush) - { - renderer.flush(); - } + this.dropShadowX = x; + this.dropShadowY = y; + this.dropShadowColor = color; + this.dropShadowAlpha = alpha; - return renderer.popFramebuffer(); + return this; }, /** - * Removes all external references from this class and deletes the - * WebGL framebuffer and texture instances. + * Sets a tint on a range of characters in this Bitmap Text, starting from the `start` parameter index + * and running for `length` quantity of characters. * - * Does not remove this Render Target from the parent pipeline. + * The `start` parameter can be negative. In this case, it starts at the end of the text and counts + * backwards `start` places. * - * @name Phaser.Renderer.WebGL.RenderTarget#destroy + * You can also pass in -1 as the `length` and it will tint all characters from `start` + * up until the end of the string. + + * Remember that spaces and punctuation count as characters. + * + * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. + * + * The tint works by taking the pixel color values from the Bitmap Text texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole character will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the character range. + * + * To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`. + * + * To modify the tint color once set, call this method again with new color values. + * + * Using `setWordTint` can override tints set by this function, and vice versa. + * + * To remove a tint call this method with just the `start`, and optionally, the `length` parameters defined. + * + * @method Phaser.GameObjects.BitmapText#setCharacterTint + * @webglOnly * @since 3.50.0 + * + * @param {number} [start=0] - The starting character to begin the tint at. If negative, it counts back from the end of the text. + * @param {number} [length=1] - The number of characters to tint. Remember that spaces count as a character too. Pass -1 to tint all characters from `start` onwards. + * @param {boolean} [tintFill=false] - Use a fill-based tint (true), or an additive tint (false) + * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the character. If not other values are given this value is applied evenly, tinting the whole character. + * @param {number} [topRight] - The tint being applied to the top-right of the character. + * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the character. + * @param {number} [bottomRight] - The tint being applied to the bottom-right of the character. + * + * @return {this} This BitmapText Object. */ - destroy: function () + setCharacterTint: function (start, length, tintFill, topLeft, topRight, bottomLeft, bottomRight) { - 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; - - -/***/ }), -/* 142 */ -/***/ (function(module, exports) { + if (start === undefined) { start = 0; } + if (length === undefined) { length = 1; } + if (tintFill === undefined) { tintFill = false; } + if (topLeft === undefined) { topLeft = -1; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (topRight === undefined) + { + topRight = topLeft; + bottomLeft = topLeft; + bottomRight = topLeft; + } -/** - * Adds the given element to the DOM. If a parent is provided the element is added as a child of the parent, providing it was able to access it. - * If no parent was given it falls back to using `document.body`. - * - * @function Phaser.DOM.AddToDOM - * @since 3.0.0 - * - * @param {HTMLElement} element - The element to be added to the DOM. Usually a Canvas object. - * @param {(string|HTMLElement)} [parent] - The parent in which to add the element. Can be a string which is passed to `getElementById` or an actual DOM object. - * - * @return {HTMLElement} The element that was added to the DOM. - */ -var AddToDOM = function (element, parent) -{ - var target; + var len = this.text.length; - if (parent) - { - if (typeof parent === 'string') + if (length === -1) { - // Hopefully an element ID - target = document.getElementById(parent); + length = len; } - else if (typeof parent === 'object' && parent.nodeType === 1) + + if (start < 0) { - // Quick test for a HTMLElement - target = parent; + start = len + start; } - } - else if (element.parentElement || parent === null) - { - return element; - } - - // Fallback, covers an invalid ID and a non HTMLElement object - if (!target) - { - target = document.body; - } - target.appendChild(element); + start = Clamp(start, 0, len - 1); - return element; -}; + var end = Clamp(start + length, start, len); -module.exports = AddToDOM; + var charColors = this.charColors; + for (var i = start; i < end; i++) + { + var color = charColors[i]; -/***/ }), -/* 143 */ -/***/ (function(module, exports) { + if (topLeft === -1) + { + charColors[i] = null; + } + else + { + var tintEffect = (tintFill) ? 1 : 0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Keyboard Codes. - * - * @namespace Phaser.Input.Keyboard.KeyCodes - * @memberof Phaser.Input.Keyboard - * @since 3.0.0 - */ + if (color) + { + color.tintEffect = tintEffect; + color.tintTL = topLeft; + color.tintTR = topRight; + color.tintBL = bottomLeft; + color.tintBR = bottomRight; + } + else + { + charColors[i] = { + tintEffect: tintEffect, + tintTL: topLeft, + tintTR: topRight, + tintBL: bottomLeft, + tintBR: bottomRight + }; + } + } + } -var KeyCodes = { + return this; + }, /** - * The BACKSPACE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.BACKSPACE - * @type {number} - * @since 3.0.0 + * Sets a tint on a matching word within this Bitmap Text. + * + * The `word` parameter can be either a string or a number. + * + * If a string, it will run a string comparison against the text contents, and if matching, + * it will tint the whole word. + * + * If a number, if till that word, based on its offset within the text contents. + * + * The `count` parameter controls how many words are replaced. Pass in -1 to replace them all. + * + * This parameter is ignored if you pass a number as the `word` to be searched for. + * + * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. + * + * The tint works by taking the pixel color values from the Bitmap Text texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole character will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the character range. + * + * To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`. + * + * To modify the tint color once set, call this method again with new color values. + * + * Using `setCharacterTint` can override tints set by this function, and vice versa. + * + * @method Phaser.GameObjects.BitmapText#setWordTint + * @webglOnly + * @since 3.50.0 + * + * @param {(string|number)} word - The word to search for. Either a string, or an index of the word in the words array. + * @param {number} [count=1] - The number of matching words to tint. Pass -1 to tint all matching words. + * @param {boolean} [tintFill=false] - Use a fill-based tint (true), or an additive tint (false) + * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the word. If not other values are given this value is applied evenly, tinting the whole word. + * @param {number} [topRight] - The tint being applied to the top-right of the word. + * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the word. + * @param {number} [bottomRight] - The tint being applied to the bottom-right of the word. + * + * @return {this} This BitmapText Object. */ - BACKSPACE: 8, + setWordTint: function (word, count, tintFill, topLeft, topRight, bottomLeft, bottomRight) + { + if (count === undefined) { count = 1; } - /** - * The TAB key. - * - * @name Phaser.Input.Keyboard.KeyCodes.TAB - * @type {number} - * @since 3.0.0 - */ - TAB: 9, + var bounds = this.getTextBounds(); - /** - * The ENTER key. - * - * @name Phaser.Input.Keyboard.KeyCodes.ENTER - * @type {number} - * @since 3.0.0 - */ - ENTER: 13, + var words = bounds.words; - /** - * The SHIFT key. - * - * @name Phaser.Input.Keyboard.KeyCodes.SHIFT - * @type {number} - * @since 3.0.0 - */ - SHIFT: 16, + var wordIsNumber = (typeof(word) === 'number'); - /** - * The CTRL key. - * - * @name Phaser.Input.Keyboard.KeyCodes.CTRL - * @type {number} - * @since 3.0.0 - */ - CTRL: 17, + var total = 0; - /** - * The ALT key. - * - * @name Phaser.Input.Keyboard.KeyCodes.ALT - * @type {number} - * @since 3.0.0 - */ - ALT: 18, + for (var i = 0; i < words.length; i++) + { + var lineword = words[i]; - /** - * The PAUSE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.PAUSE - * @type {number} - * @since 3.0.0 - */ - PAUSE: 19, + if ((wordIsNumber && i === word) || (!wordIsNumber && lineword.word === word)) + { + this.setCharacterTint(lineword.i, lineword.word.length, tintFill, topLeft, topRight, bottomLeft, bottomRight); - /** - * The CAPS_LOCK key. - * - * @name Phaser.Input.Keyboard.KeyCodes.CAPS_LOCK - * @type {number} - * @since 3.0.0 - */ - CAPS_LOCK: 20, + total++; - /** - * The ESC key. - * - * @name Phaser.Input.Keyboard.KeyCodes.ESC - * @type {number} - * @since 3.0.0 - */ - ESC: 27, + if (total === count) + { + return this; + } + } + } - /** - * The SPACE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.SPACE - * @type {number} - * @since 3.0.0 - */ - SPACE: 32, + return this; + }, /** - * The PAGE_UP key. - * - * @name Phaser.Input.Keyboard.KeyCodes.PAGE_UP - * @type {number} + * Calculate the bounds of this Bitmap Text. + * + * An object is returned that contains the position, width and height of the Bitmap Text in local and global + * contexts. + * + * Local size is based on just the font size and a [0, 0] position. + * + * Global size takes into account the Game Object's scale, world position and display origin. + * + * Also in the object is data regarding the length of each line, should this be a multi-line BitmapText. + * + * @method Phaser.GameObjects.BitmapText#getTextBounds * @since 3.0.0 + * + * @param {boolean} [round=false] - Whether to round the results up to the nearest integer. + * + * @return {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} An object that describes the size of this Bitmap Text. */ - PAGE_UP: 33, + getTextBounds: function (round) + { + // local = The BitmapText based on fontSize and 0x0 coords + // global = The BitmapText, taking into account scale and world position + // lines = The BitmapText line data - /** - * The PAGE_DOWN key. - * - * @name Phaser.Input.Keyboard.KeyCodes.PAGE_DOWN - * @type {number} - * @since 3.0.0 - */ - PAGE_DOWN: 34, + var bounds = this._bounds; - /** - * The END key. - * - * @name Phaser.Input.Keyboard.KeyCodes.END - * @type {number} - * @since 3.0.0 - */ - END: 35, + if (this._dirty || round || this.scaleX !== bounds.scaleX || this.scaleY !== bounds.scaleY) + { + GetBitmapTextSize(this, round, true, bounds); - /** - * The HOME key. - * - * @name Phaser.Input.Keyboard.KeyCodes.HOME - * @type {number} - * @since 3.0.0 - */ - HOME: 36, + this._dirty = false; + } - /** - * The LEFT key. - * - * @name Phaser.Input.Keyboard.KeyCodes.LEFT - * @type {number} - * @since 3.0.0 - */ - LEFT: 37, + return bounds; + }, /** - * The UP key. - * - * @name Phaser.Input.Keyboard.KeyCodes.UP - * @type {number} - * @since 3.0.0 + * Gets the character located at the given x/y coordinate within this Bitmap Text. + * + * The coordinates you pass in are translated into the local space of the + * Bitmap Text, however, it is up to you to first translate the input coordinates to world space. + * + * If you wish to use this in combination with an input event, be sure + * to pass in `Pointer.worldX` and `worldY` so they are in world space. + * + * In some cases, based on kerning, characters can overlap. When this happens, + * the first character in the word is returned. + * + * Note that this does not work for DynamicBitmapText if you have changed the + * character positions during render. It will only scan characters in their un-translated state. + * + * @method Phaser.GameObjects.BitmapText#getCharacterAt + * @since 3.50.0 + * + * @param {number} x - The x position to check. + * @param {number} y - The y position to check. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera. + * + * @return {Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter} The character object at the given position, or `null`. */ - UP: 38, + getCharacterAt: function (x, y, camera) + { + var point = this.getLocalPoint(x, y, null, camera); - /** - * The RIGHT key. - * - * @name Phaser.Input.Keyboard.KeyCodes.RIGHT - * @type {number} - * @since 3.0.0 - */ - RIGHT: 39, + var bounds = this.getTextBounds(); - /** - * The DOWN key. - * - * @name Phaser.Input.Keyboard.KeyCodes.DOWN - * @type {number} - * @since 3.0.0 - */ - DOWN: 40, + var chars = bounds.characters; - /** - * The PRINT_SCREEN key. - * - * @name Phaser.Input.Keyboard.KeyCodes.PRINT_SCREEN - * @type {number} - * @since 3.0.0 - */ - PRINT_SCREEN: 42, + var tempRect = new Rectangle(); - /** - * The INSERT key. - * - * @name Phaser.Input.Keyboard.KeyCodes.INSERT - * @type {number} - * @since 3.0.0 - */ - INSERT: 45, + for (var i = 0; i < chars.length; i++) + { + var char = chars[i]; - /** - * The DELETE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.DELETE - * @type {number} - * @since 3.0.0 - */ - DELETE: 46, + tempRect.setTo(char.x, char.t, char.r - char.x, char.b); - /** - * The ZERO key. - * - * @name Phaser.Input.Keyboard.KeyCodes.ZERO - * @type {number} - * @since 3.0.0 - */ - ZERO: 48, + if (tempRect.contains(point.x, point.y)) + { + return char; + } + } - /** - * The ONE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.ONE - * @type {number} - * @since 3.0.0 - */ - ONE: 49, + return null; + }, /** - * The TWO key. - * - * @name Phaser.Input.Keyboard.KeyCodes.TWO - * @type {number} + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. + * + * @method Phaser.GameObjects.BitmapText#updateDisplayOrigin * @since 3.0.0 + * + * @return {this} This Game Object instance. */ - TWO: 50, + updateDisplayOrigin: function () + { + this._dirty = true; - /** - * The THREE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.THREE - * @type {number} - * @since 3.0.0 - */ - THREE: 51, + this.getTextBounds(false); - /** - * The FOUR key. - * - * @name Phaser.Input.Keyboard.KeyCodes.FOUR - * @type {number} - * @since 3.0.0 - */ - FOUR: 52, + return this; + }, /** - * The FIVE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.FIVE - * @type {number} - * @since 3.0.0 + * Changes the font this BitmapText is using to render. + * + * The new texture is loaded and applied to the BitmapText. The existing test, size and alignment are preserved, + * unless overridden via the arguments. + * + * @method Phaser.GameObjects.BitmapText#setFont + * @since 3.11.0 + * + * @param {string} font - The key of the font to use from the Bitmap Font cache. + * @param {number} [size] - The font size of this Bitmap Text. If not specified the current size will be used. + * @param {number} [align=0] - The alignment of the text in a multi-line BitmapText object. If not specified the current alignment will be used. + * + * @return {this} This BitmapText Object. */ - FIVE: 53, + setFont: function (key, size, align) + { + if (size === undefined) { size = this._fontSize; } + if (align === undefined) { align = this._align; } - /** - * The SIX key. - * - * @name Phaser.Input.Keyboard.KeyCodes.SIX - * @type {number} - * @since 3.0.0 - */ - SIX: 54, + if (key !== this.font) + { + var entry = this.scene.sys.cache.bitmapFont.get(key); - /** - * The SEVEN key. - * - * @name Phaser.Input.Keyboard.KeyCodes.SEVEN - * @type {number} - * @since 3.0.0 - */ - SEVEN: 55, + if (entry) + { + this.font = key; + this.fontData = entry.data; + this._fontSize = size; + this._align = align; + this.fromAtlas = entry.fromAtlas === true; - /** - * The EIGHT key. - * - * @name Phaser.Input.Keyboard.KeyCodes.EIGHT - * @type {number} - * @since 3.0.0 - */ - EIGHT: 56, + this.setTexture(entry.texture, entry.frame); - /** - * The NINE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NINE - * @type {number} - * @since 3.0.0 - */ - NINE: 57, + GetBitmapTextSize(this, false, true, this._bounds); + } + } - /** - * The NUMPAD_ZERO key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ZERO - * @type {number} - * @since 3.0.0 - */ - NUMPAD_ZERO: 96, + return this; + }, /** - * The NUMPAD_ONE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ONE - * @type {number} - * @since 3.0.0 + * Sets the maximum display width of this BitmapText in pixels. + * + * If `BitmapText.text` is longer than `maxWidth` then the lines will be automatically wrapped + * based on the previous whitespace character found in the line. + * + * If no whitespace was found then no wrapping will take place and consequently the `maxWidth` value will not be honored. + * + * Disable maxWidth by setting the value to 0. + * + * You can set the whitespace character to be searched for by setting the `wordWrapCharCode` parameter or property. + * + * @method Phaser.GameObjects.BitmapText#setMaxWidth + * @since 3.21.0 + * + * @param {number} value - The maximum display width of this BitmapText in pixels. Set to zero to disable. + * @param {number} [wordWrapCharCode] - The character code to check for when word wrapping. Defaults to 32 (the space character). + * + * @return {this} This BitmapText Object. */ - NUMPAD_ONE: 97, + setMaxWidth: function (value, wordWrapCharCode) + { + this._maxWidth = value; - /** - * The NUMPAD_TWO key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_TWO - * @type {number} - * @since 3.0.0 - */ - NUMPAD_TWO: 98, + this._dirty = true; - /** - * The NUMPAD_THREE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_THREE - * @type {number} - * @since 3.0.0 - */ - NUMPAD_THREE: 99, + if (wordWrapCharCode !== undefined) + { + this.wordWrapCharCode = wordWrapCharCode; + } - /** - * The NUMPAD_FOUR key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_FOUR - * @type {number} - * @since 3.0.0 - */ - NUMPAD_FOUR: 100, + return this; + }, /** - * The NUMPAD_FIVE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_FIVE + * Controls the alignment of each line of text in this BitmapText object. + * + * Only has any effect when this BitmapText contains multiple lines of text, split with carriage-returns. + * Has no effect with single-lines of text. + * + * See the methods `setLeftAlign`, `setCenterAlign` and `setRightAlign`. + * + * 0 = Left aligned (default) + * 1 = Middle aligned + * 2 = Right aligned + * + * The alignment position is based on the longest line of text. + * + * @name Phaser.GameObjects.BitmapText#align * @type {number} - * @since 3.0.0 + * @since 3.11.0 */ - NUMPAD_FIVE: 101, + align: { - /** - * The NUMPAD_SIX key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SIX - * @type {number} - * @since 3.0.0 - */ - NUMPAD_SIX: 102, + set: function (value) + { + this._align = value; + this._dirty = true; + }, - /** - * The NUMPAD_SEVEN key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SEVEN - * @type {number} - * @since 3.0.0 - */ - NUMPAD_SEVEN: 103, + get: function () + { + return this._align; + } - /** - * The NUMPAD_EIGHT key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_EIGHT - * @type {number} - * @since 3.0.0 - */ - NUMPAD_EIGHT: 104, + }, /** - * The NUMPAD_NINE key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_NINE - * @type {number} + * The text that this Bitmap Text object displays. + * + * You can also use the method `setText` if you want a chainable way to change the text content. + * + * @name Phaser.GameObjects.BitmapText#text + * @type {string} * @since 3.0.0 */ - NUMPAD_NINE: 105, - - /** - * The Numpad Addition (+) key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ADD - * @type {number} - * @since 3.21.0 - */ - NUMPAD_ADD: 107, + text: { - /** - * The Numpad Subtraction (-) key. - * - * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SUBTRACT - * @type {number} - * @since 3.21.0 - */ - NUMPAD_SUBTRACT: 109, + set: function (value) + { + this.setText(value); + }, - /** - * The A key. - * - * @name Phaser.Input.Keyboard.KeyCodes.A - * @type {number} - * @since 3.0.0 - */ - A: 65, + get: function () + { + return this._text; + } - /** - * The B key. - * - * @name Phaser.Input.Keyboard.KeyCodes.B - * @type {number} - * @since 3.0.0 - */ - B: 66, + }, /** - * The C key. - * - * @name Phaser.Input.Keyboard.KeyCodes.C + * The font size of this Bitmap Text. + * + * You can also use the method `setFontSize` if you want a chainable way to change the font size. + * + * @name Phaser.GameObjects.BitmapText#fontSize * @type {number} * @since 3.0.0 */ - C: 67, + fontSize: { - /** - * The D key. - * - * @name Phaser.Input.Keyboard.KeyCodes.D - * @type {number} - * @since 3.0.0 - */ - D: 68, + set: function (value) + { + this._fontSize = value; + this._dirty = true; + }, - /** - * The E key. - * - * @name Phaser.Input.Keyboard.KeyCodes.E - * @type {number} - * @since 3.0.0 - */ - E: 69, + get: function () + { + return this._fontSize; + } - /** - * The F key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F - * @type {number} - * @since 3.0.0 - */ - F: 70, + }, /** - * The G key. - * - * @name Phaser.Input.Keyboard.KeyCodes.G + * Adds / Removes spacing between characters. + * + * Can be a negative or positive number. + * + * You can also use the method `setLetterSpacing` if you want a chainable way to change the letter spacing. + * + * @name Phaser.GameObjects.BitmapText#letterSpacing * @type {number} * @since 3.0.0 */ - G: 71, + letterSpacing: { - /** - * The H key. - * - * @name Phaser.Input.Keyboard.KeyCodes.H - * @type {number} - * @since 3.0.0 - */ - H: 72, + set: function (value) + { + this._letterSpacing = value; + this._dirty = true; + }, - /** - * The I key. - * - * @name Phaser.Input.Keyboard.KeyCodes.I - * @type {number} - * @since 3.0.0 - */ - I: 73, + get: function () + { + return this._letterSpacing; + } - /** - * The J key. - * - * @name Phaser.Input.Keyboard.KeyCodes.J - * @type {number} - * @since 3.0.0 - */ - J: 74, + }, /** - * The K key. - * - * @name Phaser.Input.Keyboard.KeyCodes.K + * Adds / Removes spacing between lines. + * + * Can be a negative or positive number. + * + * You can also use the method `setLineSpacing` if you want a chainable way to change the line spacing. + * + * @name Phaser.GameObjects.BitmapText#lineSpacing * @type {number} - * @since 3.0.0 + * @since 3.60.0 */ - K: 75, + lineSpacing: { - /** - * The L key. - * - * @name Phaser.Input.Keyboard.KeyCodes.L - * @type {number} - * @since 3.0.0 - */ - L: 76, + set: function (value) + { + this._lineSpacing = value; + this._dirty = true; + }, - /** - * The M key. - * - * @name Phaser.Input.Keyboard.KeyCodes.M - * @type {number} - * @since 3.0.0 - */ - M: 77, + get: function () + { + return this._lineSpacing; + } - /** - * The N key. - * - * @name Phaser.Input.Keyboard.KeyCodes.N - * @type {number} - * @since 3.0.0 - */ - N: 78, + }, /** - * The O key. - * - * @name Phaser.Input.Keyboard.KeyCodes.O + * The maximum display width of this BitmapText in pixels. + * + * If BitmapText.text is longer than maxWidth then the lines will be automatically wrapped + * based on the last whitespace character found in the line. + * + * If no whitespace was found then no wrapping will take place and consequently the maxWidth value will not be honored. + * + * Disable maxWidth by setting the value to 0. + * + * @name Phaser.GameObjects.BitmapText#maxWidth * @type {number} - * @since 3.0.0 + * @since 3.21.0 */ - O: 79, + maxWidth: { - /** - * The P key. - * - * @name Phaser.Input.Keyboard.KeyCodes.P - * @type {number} - * @since 3.0.0 - */ - P: 80, + set: function (value) + { + this._maxWidth = value; + this._dirty = true; + }, - /** - * The Q key. - * - * @name Phaser.Input.Keyboard.KeyCodes.Q - * @type {number} - * @since 3.0.0 - */ - Q: 81, + get: function () + { + return this._maxWidth; + } - /** - * The R key. - * - * @name Phaser.Input.Keyboard.KeyCodes.R - * @type {number} - * @since 3.0.0 - */ - R: 82, + }, /** - * The S key. - * - * @name Phaser.Input.Keyboard.KeyCodes.S + * The width of this Bitmap Text. + * + * This property is read-only. + * + * @name Phaser.GameObjects.BitmapText#width * @type {number} + * @readonly * @since 3.0.0 */ - S: 83, + width: { - /** - * The T key. - * - * @name Phaser.Input.Keyboard.KeyCodes.T - * @type {number} - * @since 3.0.0 - */ - T: 84, + get: function () + { + this.getTextBounds(false); - /** - * The U key. - * - * @name Phaser.Input.Keyboard.KeyCodes.U - * @type {number} - * @since 3.0.0 - */ - U: 85, + return this._bounds.global.width; + } - /** - * The V key. - * - * @name Phaser.Input.Keyboard.KeyCodes.V - * @type {number} - * @since 3.0.0 - */ - V: 86, + }, /** - * The W key. - * - * @name Phaser.Input.Keyboard.KeyCodes.W + * The height of this Bitmap text. + * + * This property is read-only. + * + * @name Phaser.GameObjects.BitmapText#height * @type {number} + * @readonly * @since 3.0.0 */ - W: 87, + height: { - /** - * The X key. - * - * @name Phaser.Input.Keyboard.KeyCodes.X - * @type {number} - * @since 3.0.0 - */ - X: 88, + get: function () + { + this.getTextBounds(false); - /** - * The Y key. - * - * @name Phaser.Input.Keyboard.KeyCodes.Y - * @type {number} - * @since 3.0.0 - */ - Y: 89, + return this._bounds.global.height; + } - /** - * The Z key. - * - * @name Phaser.Input.Keyboard.KeyCodes.Z - * @type {number} - * @since 3.0.0 - */ - Z: 90, + }, /** - * The F1 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F1 + * The displayed width of this Bitmap Text. + * + * This value takes into account the scale factor. + * + * This property is read-only. + * + * @name Phaser.GameObjects.BitmapText#displayWidth * @type {number} - * @since 3.0.0 + * @readonly + * @since 3.60.0 */ - F1: 112, + displayWidth: { - /** - * The F2 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F2 - * @type {number} - * @since 3.0.0 - */ - F2: 113, + get: function () + { + return this.width; + } - /** - * The F3 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F3 - * @type {number} - * @since 3.0.0 - */ - F3: 114, + }, /** - * The F4 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F4 + * The displayed height of this Bitmap Text. + * + * This value takes into account the scale factor. + * + * This property is read-only. + * + * @name Phaser.GameObjects.BitmapText#displayHeight * @type {number} - * @since 3.0.0 + * @readonly + * @since 3.60.0 */ - F4: 115, + displayHeight: { - /** - * The F5 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F5 - * @type {number} - * @since 3.0.0 - */ - F5: 116, + get: function () + { + return this.height; + } - /** - * The F6 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F6 - * @type {number} - * @since 3.0.0 - */ - F6: 117, + }, /** - * The F7 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F7 - * @type {number} + * Build a JSON representation of this Bitmap Text. + * + * @method Phaser.GameObjects.BitmapText#toJSON * @since 3.0.0 + * + * @return {Phaser.Types.GameObjects.BitmapText.JSONBitmapText} A JSON representation of this Bitmap Text. */ - F7: 118, + toJSON: function () + { + var out = Components.ToJSON(this); - /** - * The F8 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F8 - * @type {number} - * @since 3.0.0 - */ - F8: 119, + // Extra data is added here - /** - * The F9 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F9 - * @type {number} - * @since 3.0.0 - */ - F9: 120, + var data = { + font: this.font, + text: this.text, + fontSize: this.fontSize, + letterSpacing: this.letterSpacing, + lineSpacing: this.lineSpacing, + align: this.align + }; - /** - * The F10 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F10 - * @type {number} - * @since 3.0.0 - */ - F10: 121, + out.data = data; - /** - * The F11 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F11 - * @type {number} - * @since 3.0.0 - */ - F11: 122, + return out; + }, /** - * The F12 key. - * - * @name Phaser.Input.Keyboard.KeyCodes.F12 - * @type {number} - * @since 3.0.0 + * Internal destroy handler, called as part of the destroy process. + * + * @method Phaser.GameObjects.BitmapText#preDestroy + * @protected + * @since 3.50.0 */ - F12: 123, + preDestroy: function () + { + this.charColors.length = 0; + this._bounds = null; + this.fontData = null; + } - /** - * The SEMICOLON key. - * - * @name Phaser.Input.Keyboard.KeyCodes.SEMICOLON - * @type {number} - * @since 3.0.0 - */ - SEMICOLON: 186, +}); - /** - * The PLUS key. - * - * @name Phaser.Input.Keyboard.KeyCodes.PLUS - * @type {number} - * @since 3.0.0 - */ - PLUS: 187, +/** + * Left align the text characters in a multi-line BitmapText object. + * + * @name Phaser.GameObjects.BitmapText.ALIGN_LEFT + * @type {number} + * @since 3.11.0 + */ +BitmapText.ALIGN_LEFT = 0; - /** - * The COMMA key. - * - * @name Phaser.Input.Keyboard.KeyCodes.COMMA - * @type {number} - * @since 3.0.0 - */ - COMMA: 188, +/** + * Center align the text characters in a multi-line BitmapText object. + * + * @name Phaser.GameObjects.BitmapText.ALIGN_CENTER + * @type {number} + * @since 3.11.0 + */ +BitmapText.ALIGN_CENTER = 1; - /** - * The MINUS key. - * - * @name Phaser.Input.Keyboard.KeyCodes.MINUS - * @type {number} - * @since 3.0.0 - */ - MINUS: 189, +/** + * Right align the text characters in a multi-line BitmapText object. + * + * @name Phaser.GameObjects.BitmapText.ALIGN_RIGHT + * @type {number} + * @since 3.11.0 + */ +BitmapText.ALIGN_RIGHT = 2; - /** - * The PERIOD key. - * - * @name Phaser.Input.Keyboard.KeyCodes.PERIOD - * @type {number} - * @since 3.0.0 - */ - PERIOD: 190, +/** + * Parse an XML Bitmap Font from an Atlas. + * + * Adds the parsed Bitmap Font data to the cache with the `fontName` key. + * + * @method Phaser.GameObjects.BitmapText.ParseFromAtlas + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to parse the Bitmap Font for. + * @param {string} fontName - The key of the font to add to the Bitmap Font cache. + * @param {string} textureKey - The key of the BitmapFont's texture. + * @param {string} frameKey - The key of the BitmapFont texture's frame. + * @param {string} xmlKey - The key of the XML data of the font to parse. + * @param {number} [xSpacing] - The x-axis spacing to add between each letter. + * @param {number} [ySpacing] - The y-axis spacing to add to the line height. + * + * @return {boolean} Whether the parsing was successful or not. + */ +BitmapText.ParseFromAtlas = ParseFromAtlas; - /** - * The FORWARD_SLASH key. - * - * @name Phaser.Input.Keyboard.KeyCodes.FORWARD_SLASH - * @type {number} - * @since 3.0.0 - */ - FORWARD_SLASH: 191, +/** + * Parse an XML font to Bitmap Font data for the Bitmap Font cache. + * + * @method Phaser.GameObjects.BitmapText.ParseXMLBitmapFont + * @since 3.17.0 + * + * @param {XMLDocument} xml - The XML Document to parse the font from. + * @param {Phaser.Textures.Frame} frame - The texture frame to take into account when creating the uv data. + * @param {number} [xSpacing=0] - The x-axis spacing to add between each letter. + * @param {number} [ySpacing=0] - The y-axis spacing to add to the line height. + * + * @return {Phaser.Types.GameObjects.BitmapText.BitmapFontData} The parsed Bitmap Font data. + */ +BitmapText.ParseXMLBitmapFont = ParseXMLBitmapFont; - /** - * The BACK_SLASH key. - * - * @name Phaser.Input.Keyboard.KeyCodes.BACK_SLASH - * @type {number} - * @since 3.0.0 - */ - BACK_SLASH: 220, +module.exports = BitmapText; - /** - * The QUOTES key. - * - * @name Phaser.Input.Keyboard.KeyCodes.QUOTES - * @type {number} - * @since 3.0.0 - */ - QUOTES: 222, - /** - * The BACKTICK key. - * - * @name Phaser.Input.Keyboard.KeyCodes.BACKTICK - * @type {number} - * @since 3.0.0 - */ - BACKTICK: 192, +/***/ }), - /** - * The OPEN_BRACKET key. - * - * @name Phaser.Input.Keyboard.KeyCodes.OPEN_BRACKET - * @type {number} - * @since 3.0.0 - */ - OPEN_BRACKET: 219, +/***/ 97545: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The CLOSED_BRACKET key. - * - * @name Phaser.Input.Keyboard.KeyCodes.CLOSED_BRACKET - * @type {number} - * @since 3.0.0 - */ - CLOSED_BRACKET: 221, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The SEMICOLON_FIREFOX key. - * - * @name Phaser.Input.Keyboard.KeyCodes.SEMICOLON_FIREFOX - * @type {number} - * @since 3.0.0 - */ - SEMICOLON_FIREFOX: 59, +var SetTransform = __webpack_require__(49584); - /** - * The COLON key. - * - * @name Phaser.Input.Keyboard.KeyCodes.COLON - * @type {number} - * @since 3.0.0 - */ - COLON: 58, +/** + * 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.BitmapText#renderCanvas + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.BitmapText} 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 BitmapTextCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + var text = src._text; + var textLength = text.length; - /** - * The COMMA_FIREFOX_WINDOWS key. - * - * @name Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX_WINDOWS - * @type {number} - * @since 3.0.0 - */ - COMMA_FIREFOX_WINDOWS: 60, + var ctx = renderer.currentContext; - /** - * The COMMA_FIREFOX key. - * - * @name Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX - * @type {number} - * @since 3.0.0 - */ - COMMA_FIREFOX: 62, + if (textLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + return; + } - /** - * The BRACKET_RIGHT_FIREFOX key. - * - * @name Phaser.Input.Keyboard.KeyCodes.BRACKET_RIGHT_FIREFOX - * @type {number} - * @since 3.0.0 - */ - BRACKET_RIGHT_FIREFOX: 174, + camera.addToRenderList(src); - /** - * The BRACKET_LEFT_FIREFOX key. - * - * @name Phaser.Input.Keyboard.KeyCodes.BRACKET_LEFT_FIREFOX - * @type {number} - * @since 3.0.0 - */ - BRACKET_LEFT_FIREFOX: 175 + var textureFrame = src.fromAtlas + ? src.frame + : src.texture.frames['__BASE']; + + var chars = src.fontData.chars; + var lineHeight = src.fontData.lineHeight; + var letterSpacing = src._letterSpacing; + var lineSpacing = src._lineSpacing; + + var xAdvance = 0; + var yAdvance = 0; + + var charCode = 0; + + var glyph = null; + var glyphX = 0; + var glyphY = 0; + var glyphW = 0; + var glyphH = 0; + + var x = 0; + var y = 0; + + var lastGlyph = null; + var lastCharCode = 0; + + var image = textureFrame.source.image; + + var textureX = textureFrame.cutX; + var textureY = textureFrame.cutY; + + var scale = (src._fontSize / src.fontData.size); + + var align = src._align; + var currentLine = 0; + var lineOffsetX = 0; + + // Update the bounds - skipped internally if not dirty + var bounds = src.getTextBounds(false); + + // In case the method above changed it (word wrapping) + if (src.maxWidth > 0) + { + text = bounds.wrappedText; + textLength = text.length; + } + + var lineData = src._bounds.lines; + + if (align === 1) + { + lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2; + } + else if (align === 2) + { + lineOffsetX = (lineData.longest - lineData.lengths[0]); + } + + ctx.translate(-src.displayOriginX, -src.displayOriginY); + + var roundPixels = camera.roundPixels; + + for (var i = 0; i < textLength; i++) + { + charCode = text.charCodeAt(i); + + if (charCode === 10) + { + currentLine++; + + if (align === 1) + { + lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2; + } + else if (align === 2) + { + lineOffsetX = (lineData.longest - lineData.lengths[currentLine]); + } + + xAdvance = 0; + yAdvance += lineHeight + lineSpacing; + + lastGlyph = null; + + continue; + } + + glyph = chars[charCode]; + + if (!glyph) + { + continue; + } + + glyphX = textureX + glyph.x; + glyphY = textureY + glyph.y; + + glyphW = glyph.width; + glyphH = glyph.height; + + x = glyph.xOffset + xAdvance; + y = glyph.yOffset + yAdvance; + + if (lastGlyph !== null) + { + var kerningOffset = glyph.kerning[lastCharCode]; + x += (kerningOffset !== undefined) ? kerningOffset : 0; + } + + x *= scale; + y *= scale; + + x += lineOffsetX; + + xAdvance += glyph.xAdvance + letterSpacing + ((kerningOffset !== undefined) ? kerningOffset : 0); + lastGlyph = glyph; + lastCharCode = charCode; + + // Nothing to render or a space? Then skip to the next glyph + if (glyphW === 0 || glyphH === 0 || charCode === 32) + { + continue; + } + + if (roundPixels) + { + x = Math.round(x); + y = Math.round(y); + } + + ctx.save(); + + ctx.translate(x, y); + + ctx.scale(scale, scale); + + ctx.drawImage(image, glyphX, glyphY, glyphW, glyphH, 0, 0, glyphW, glyphH); + + ctx.restore(); + } + + ctx.restore(); }; -module.exports = KeyCodes; +module.exports = BitmapTextCanvasRenderer; /***/ }), -/* 144 */ -/***/ (function(module, exports) { + +/***/ 95499: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var BitmapText = __webpack_require__(44616); +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var GetValue = __webpack_require__(10850); + /** - * Scene consts. + * Creates a new Bitmap Text Game Object and returns it. + * + * Note: This method will only be available if the Bitmap Text Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#bitmapText + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.BitmapText.BitmapTextConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. * - * @ignore + * @return {Phaser.GameObjects.BitmapText} The Game Object that was created. */ +GameObjectCreator.register('bitmapText', function (config, addToScene) +{ + if (config === undefined) { config = {}; } -var CONST = { + var font = GetValue(config, 'font', ''); + var text = GetAdvancedValue(config, 'text', ''); + var size = GetAdvancedValue(config, 'size', false); + var align = GetValue(config, 'align', 0); - /** - * Scene state. - * - * @name Phaser.Scenes.PENDING - * @readonly - * @type {number} - * @since 3.0.0 - */ - PENDING: 0, + var bitmapText = new BitmapText(this.scene, 0, 0, font, text, size, align); - /** - * Scene state. - * - * @name Phaser.Scenes.INIT - * @readonly - * @type {number} - * @since 3.0.0 - */ - INIT: 1, + if (addToScene !== undefined) + { + config.add = addToScene; + } - /** - * Scene state. - * - * @name Phaser.Scenes.START - * @readonly - * @type {number} - * @since 3.0.0 - */ - START: 2, + BuildGameObject(this.scene, bitmapText, config); - /** - * Scene state. - * - * @name Phaser.Scenes.LOADING - * @readonly - * @type {number} - * @since 3.0.0 - */ - LOADING: 3, + return bitmapText; +}); - /** - * Scene state. - * - * @name Phaser.Scenes.CREATING - * @readonly - * @type {number} - * @since 3.0.0 - */ - CREATING: 4, +// When registering a factory function 'this' refers to the GameObjectCreator context. - /** - * Scene state. - * - * @name Phaser.Scenes.RUNNING - * @readonly - * @type {number} - * @since 3.0.0 - */ - RUNNING: 5, - /** - * Scene state. - * - * @name Phaser.Scenes.PAUSED - * @readonly - * @type {number} - * @since 3.0.0 - */ - PAUSED: 6, +/***/ }), - /** - * Scene state. - * - * @name Phaser.Scenes.SLEEPING - * @readonly - * @type {number} - * @since 3.0.0 - */ - SLEEPING: 7, +/***/ 21797: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - /** - * Scene state. - * - * @name Phaser.Scenes.SHUTDOWN - * @readonly - * @type {number} - * @since 3.0.0 - */ - SHUTDOWN: 8, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Scene state. - * - * @name Phaser.Scenes.DESTROYED - * @readonly - * @type {number} - * @since 3.0.0 - */ - DESTROYED: 9 +var BitmapText = __webpack_require__(44616); +var GameObjectFactory = __webpack_require__(61286); + +/** + * Creates a new Bitmap Text Game Object and adds it to the Scene. + * + * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. + * + * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to + * match the font structure. + * + * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability + * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by + * processing the font texture in an image editor, applying fills and any other effects required. + * + * To create multi-line text insert \r, \n or \r\n escape codes into the text string. + * + * To create a BitmapText data files you need a 3rd party app such as: + * + * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/ + * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner + * Littera (Web-based, free): http://kvazars.com/littera/ + * + * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of + * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: http://codebeautify.org/xmltojson + * + * Note: This method will only be available if the Bitmap Text Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#bitmapText + * @since 3.0.0 + * + * @param {number} x - The x position of the Game Object. + * @param {number} y - The y position of the Game Object. + * @param {string} font - The key of the font to use from the BitmapFont cache. + * @param {(string|string[])} [text] - The string, or array of strings, to be set as the content of this Bitmap Text. + * @param {number} [size] - The font size to set. + * @param {number} [align=0] - The alignment of the text in a multi-line BitmapText object. + * + * @return {Phaser.GameObjects.BitmapText} The Game Object that was created. + */ +GameObjectFactory.register('bitmapText', function (x, y, font, text, size, align) +{ + return this.displayList.add(new BitmapText(this.scene, x, y, font, text, size, align)); +}); + +// When registering a factory function 'this' refers to the GameObjectFactory 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 + + +/***/ }), + +/***/ 84557: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(26372); +} + +if (true) +{ + renderCanvas = __webpack_require__(97545); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas }; -module.exports = CONST; + +/***/ }), + +/***/ 26372: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BatchChar = __webpack_require__(8810); +var GetCalcMatrix = __webpack_require__(73329); +var Utils = __webpack_require__(75512); + +/** + * 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.BitmapText#renderWebGL + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.BitmapText} 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 BitmapTextWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + var text = src._text; + var textLength = text.length; + + if (textLength === 0) + { + return; + } + + camera.addToRenderList(src); + + var pipeline = renderer.pipelines.set(src.pipeline, src); + + var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; + + // This causes a flush if the BitmapText has a Post Pipeline + renderer.pipelines.preBatch(src); + + var roundPixels = camera.roundPixels; + + var cameraAlpha = camera.alpha; + + var charColors = src.charColors; + + var tintEffect = src.tintFill; + + var getTint = Utils.getTintAppendFloatAlpha; + + var tintTL = getTint(src.tintTopLeft, cameraAlpha * src._alphaTL); + var tintTR = getTint(src.tintTopRight, cameraAlpha * src._alphaTR); + var tintBL = getTint(src.tintBottomLeft, cameraAlpha * src._alphaBL); + var tintBR = getTint(src.tintBottomRight, cameraAlpha * src._alphaBR); + + var texture = src.frame.glTexture; + var textureUnit = pipeline.setGameObject(src); + + // Update the bounds - skipped internally if not dirty + var bounds = src.getTextBounds(false); + + var i; + var char; + var glyph; + + var characters = bounds.characters; + + var dropShadowX = src.dropShadowX; + var dropShadowY = src.dropShadowY; + + var dropShadow = (dropShadowX !== 0 || dropShadowY !== 0); + + if (dropShadow) + { + var srcShadowColor = src.dropShadowColor; + var srcShadowAlpha = src.dropShadowAlpha; + + var shadowTL = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaTL); + var shadowTR = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaTR); + var shadowBL = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaBL); + var shadowBR = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaBR); + + for (i = 0; i < characters.length; i++) + { + char = characters[i]; + glyph = char.glyph; + + if (char.code === 32 || glyph.width === 0 || glyph.height === 0) + { + continue; + } + + BatchChar(pipeline, src, char, glyph, dropShadowX, dropShadowY, calcMatrix, roundPixels, shadowTL, shadowTR, shadowBL, shadowBR, 1, texture, textureUnit); + } + } + + for (i = 0; i < characters.length; i++) + { + char = characters[i]; + glyph = char.glyph; + + if (char.code === 32 || glyph.width === 0 || glyph.height === 0) + { + continue; + } + + if (charColors[char.i]) + { + var color = charColors[char.i]; + + var charTintEffect = color.tintEffect; + var charTintTL = getTint(color.tintTL, cameraAlpha * src._alphaTL); + var charTintTR = getTint(color.tintTR, cameraAlpha * src._alphaTR); + var charTintBL = getTint(color.tintBL, cameraAlpha * src._alphaBL); + var charTintBR = getTint(color.tintBR, cameraAlpha * src._alphaBR); + + BatchChar(pipeline, src, char, glyph, 0, 0, calcMatrix, roundPixels, charTintTL, charTintTR, charTintBL, charTintBR, charTintEffect, texture, textureUnit); + } + else + { + BatchChar(pipeline, src, char, glyph, 0, 0, calcMatrix, roundPixels, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); + } + + // Debug test if the characters are in the correct place when rendered: + // pipeline.drawFillRect(tx0, ty0, tx2 - tx0, ty2 - ty0, 0x00ff00, 0.5); + } + + renderer.pipelines.postBatch(src); +}; + +module.exports = BitmapTextWebGLRenderer; /***/ }), -/* 145 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 52816: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Clone = __webpack_require__(77); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(70); -var GameEvents = __webpack_require__(22); -var NOOP = __webpack_require__(1); -var GetAll = __webpack_require__(207); -var GetFirst = __webpack_require__(428); +var BlitterRender = __webpack_require__(92246); +var Bob = __webpack_require__(41664); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var Frame = __webpack_require__(82047); +var GameObject = __webpack_require__(89980); +var List = __webpack_require__(71207); + +/** + * @callback CreateCallback + * + * @param {Phaser.GameObjects.Bob} bob - The Bob that was created by the Blitter. + * @param {number} index - The position of the Bob within the Blitter display list. + */ /** * @classdesc - * Base class for other Sound Manager classes. + * A Blitter Game Object. * - * @class BaseSoundManager - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Sound + * The Blitter Game Object is a special kind of container that creates, updates and manages Bob objects. + * Bobs are designed for rendering speed rather than flexibility. They consist of a texture, or frame from a texture, + * a position and an alpha value. You cannot scale or rotate them. They use a batched drawing method for speed + * during rendering. + * + * A Blitter Game Object has one texture bound to it. Bobs created by the Blitter can use any Frame from this + * Texture to render with, but they cannot use any other Texture. It is this single texture-bind that allows + * them their speed. + * + * If you have a need to blast a large volume of frames around the screen then Blitter objects are well worth + * investigating. They are especially useful for using as a base for your own special effects systems. + * + * @class Blitter + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects * @constructor * @since 3.0.0 * - * @param {Phaser.Game} game - Reference to the current game instance. + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.Texture + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.Visible * - * @see Phaser.Sound.HTML5AudioSoundManager - * @see Phaser.Sound.NoAudioSoundManager - * @see Phaser.Sound.WebAudioSoundManager + * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. It can only belong to one Scene at any given time. + * @param {number} [x=0] - The x coordinate of this Game Object in world space. + * @param {number} [y=0] - The y coordinate of this Game Object in world space. + * @param {string} [texture='__DEFAULT'] - The key of the texture this Game Object will use for rendering. The Texture must already exist in the Texture Manager. + * @param {(string|number)} [frame=0] - The Frame of the Texture that this Game Object will use. Only set if the Texture has multiple frames, such as a Texture Atlas or Sprite Sheet. */ -var BaseSoundManager = new Class({ +var Blitter = new Class({ - Extends: EventEmitter, + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.Depth, + Components.Mask, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Size, + Components.Texture, + Components.Transform, + Components.Visible, + BlitterRender + ], initialize: - function BaseSoundManager (game) + function Blitter (scene, x, y, texture, frame) { - EventEmitter.call(this); + GameObject.call(this, scene, 'Blitter'); - /** - * Local reference to game. - * - * @name Phaser.Sound.BaseSoundManager#game - * @type {Phaser.Game} - * @readonly - * @since 3.0.0 - */ - this.game = game; + this.setTexture(texture, frame); + this.setPosition(x, y); + this.initPipeline(); + this.initPostPipeline(); /** - * Local reference to the JSON Cache, as used by Audio Sprites. + * The children of this Blitter. + * This List contains all of the Bob objects created by the Blitter. * - * @name Phaser.Sound.BaseSoundManager#jsonCache - * @type {Phaser.Cache.BaseCache} - * @readonly - * @since 3.7.0 + * @name Phaser.GameObjects.Blitter#children + * @type {Phaser.Structs.List.} + * @since 3.0.0 */ - this.jsonCache = game.cache.json; + this.children = new List(); /** - * An array containing all added sounds. + * A transient array that holds all of the Bobs that will be rendered this frame. + * The array is re-populated whenever the dirty flag is set. * - * @name Phaser.Sound.BaseSoundManager#sounds - * @type {Phaser.Sound.BaseSound[]} + * @name Phaser.GameObjects.Blitter#renderList + * @type {Phaser.GameObjects.Bob[]} * @default [] * @private * @since 3.0.0 */ - this.sounds = []; + this.renderList = []; /** - * Global mute setting. + * Is the Blitter considered dirty? + * A 'dirty' Blitter has had its child count changed since the last frame. * - * @name Phaser.Sound.BaseSoundManager#mute + * @name Phaser.GameObjects.Blitter#dirty * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.mute = false; - - /** - * Global volume setting. - * - * @name Phaser.Sound.BaseSoundManager#volume - * @type {number} - * @default 1 * @since 3.0.0 */ - this.volume = 1; + this.dirty = false; + }, - /** - * Flag indicating if sounds should be paused when game looses focus, - * for instance when user switches to another tab/program/app. - * - * @name Phaser.Sound.BaseSoundManager#pauseOnBlur - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.pauseOnBlur = true; + /** + * Creates a new Bob in this Blitter. + * + * The Bob is created at the given coordinates, relative to the Blitter and uses the given frame. + * A Bob can use any frame belonging to the texture bound to the Blitter. + * + * @method Phaser.GameObjects.Blitter#create + * @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. + * @param {boolean} [visible=true] - Should the created Bob render or not? + * @param {number} [index] - The position in the Blitters Display List to add the new Bob at. Defaults to the top of the list. + * + * @return {Phaser.GameObjects.Bob} The newly created Bob object. + */ + create: function (x, y, frame, visible, index) + { + if (visible === undefined) { visible = true; } + if (index === undefined) { index = this.children.length; } - /** - * Property that actually holds the value of global playback rate. - * - * @name Phaser.Sound.BaseSoundManager#_rate - * @type {number} - * @private - * @default 1 - * @since 3.0.0 - */ - this._rate = 1; + if (frame === undefined) + { + frame = this.frame; + } + else if (!(frame instanceof Frame)) + { + frame = this.texture.get(frame); + } - /** - * Property that actually holds the value of global detune. - * - * @name Phaser.Sound.BaseSoundManager#_detune - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._detune = 0; + var bob = new Bob(this, x, y, frame, visible); - /** - * Mobile devices require sounds to be triggered from an explicit user action, - * such as a tap, before any sound can be loaded/played on a web page. - * Set to true if the audio system is currently locked awaiting user interaction. - * - * @name Phaser.Sound.BaseSoundManager#locked - * @type {boolean} - * @readonly - * @since 3.0.0 - */ - this.locked = this.locked || false; + this.children.addAt(bob, index, false); - /** - * Flag used internally for handling when the audio system - * has been unlocked, if there ever was a need for it. - * - * @name Phaser.Sound.BaseSoundManager#unlocked - * @type {boolean} - * @default false - * @private - * @since 3.0.0 - */ - this.unlocked = false; + this.dirty = true; - game.events.on(GameEvents.BLUR, this.onGameBlur, this); - game.events.on(GameEvents.FOCUS, this.onGameFocus, this); - game.events.on(GameEvents.PRE_STEP, this.update, this); - game.events.once(GameEvents.DESTROY, this.destroy, this); + return bob; }, /** - * Adds a new sound into the sound manager. + * Creates multiple Bob objects within this Blitter and then passes each of them to the specified callback. * - * @method Phaser.Sound.BaseSoundManager#add - * @override + * @method Phaser.GameObjects.Blitter#createFromCallback * @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. + * @param {CreateCallback} callback - The callback to invoke after creating a bob. It will be sent two arguments: The Bob and the index of the Bob. + * @param {number} quantity - The quantity of Bob objects to create. + * @param {(string|number|Phaser.Textures.Frame|string[]|number[]|Phaser.Textures.Frame[])} [frame] - The Frame the Bobs will use. It must be part of the Blitter Texture. + * @param {boolean} [visible=true] - Should the created Bob render or not? * - * @return {Phaser.Sound.BaseSound} The new sound instance. + * @return {Phaser.GameObjects.Bob[]} An array of Bob objects that were created. */ - add: NOOP, + createFromCallback: function (callback, quantity, frame, visible) + { + var bobs = this.createMultiple(quantity, frame, visible); + + for (var i = 0; i < bobs.length; i++) + { + var bob = bobs[i]; + + callback.call(this, bob, i); + } + + return bobs; + }, /** - * Adds a new audio sprite sound into the sound manager. - * Audio Sprites are a combination of audio files and a JSON configuration. - * The JSON follows the format of that created by https://github.com/tonistiigi/audiosprite + * Creates multiple Bobs in one call. * - * @method Phaser.Sound.BaseSoundManager#addAudioSprite + * The amount created is controlled by a combination of the `quantity` argument and the number of frames provided. + * + * If the quantity is set to 10 and you provide 2 frames, then 20 Bobs will be created. 10 with the first + * frame and 10 with the second. + * + * @method Phaser.GameObjects.Blitter#createMultiple * @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. + * @param {number} quantity - The quantity of Bob objects to create. + * @param {(string|number|Phaser.Textures.Frame|string[]|number[]|Phaser.Textures.Frame[])} [frame] - The Frame the Bobs will use. It must be part of the Blitter Texture. + * @param {boolean} [visible=true] - Should the created Bob render or not? * - * @return {(Phaser.Sound.HTML5AudioSound|Phaser.Sound.WebAudioSound)} The new audio sprite sound instance. + * @return {Phaser.GameObjects.Bob[]} An array of Bob objects that were created. */ - addAudioSprite: function (key, config) + createMultiple: function (quantity, frame, visible) { - if (config === undefined) { config = {}; } + if (frame === undefined) { frame = this.frame.name; } + if (visible === undefined) { visible = true; } - var sound = this.add(key, config); + if (!Array.isArray(frame)) + { + frame = [ frame ]; + } - sound.spritemap = this.jsonCache.get(key).spritemap; + var bobs = []; + var _this = this; - for (var markerName in sound.spritemap) + frame.forEach(function (singleFrame) { - if (!sound.spritemap.hasOwnProperty(markerName)) + for (var i = 0; i < quantity; i++) { - continue; + bobs.push(_this.create(0, 0, singleFrame, visible)); } + }); - var markerConfig = Clone(config); - - var marker = sound.spritemap[markerName]; - - markerConfig.loop = (marker.hasOwnProperty('loop')) ? marker.loop : false; - - sound.addMarker({ - name: markerName, - start: marker.start, - duration: marker.end - marker.start, - config: markerConfig - }); - } - - return sound; + return bobs; }, /** - * Gets the first sound in the manager matching the given key, if any. + * Checks if the given child can render or not, by checking its `visible` and `alpha` values. * - * @method Phaser.Sound.BaseSoundManager#get - * @since 3.23.0 + * @method Phaser.GameObjects.Blitter#childCanRender + * @since 3.0.0 * - * @param {string} key - Sound asset key. + * @param {Phaser.GameObjects.Bob} child - The Bob to check for rendering. * - * @return {?Phaser.Sound.BaseSound} - The sound, or null. + * @return {boolean} Returns `true` if the given child can render, otherwise `false`. */ - get: function (key) + childCanRender: function (child) { - return GetFirst(this.sounds, 'key', key); + return (child.visible && child.alpha > 0); }, /** - * Gets any sounds in the manager matching the given key. - * - * @method Phaser.Sound.BaseSoundManager#getAll - * @since 3.23.0 + * Returns an array of Bobs to be rendered. + * If the Blitter is dirty then a new list is generated and stored in `renderList`. * - * @param {string} key - Sound asset key. + * @method Phaser.GameObjects.Blitter#getRenderList + * @since 3.0.0 * - * @return {Phaser.Sound.BaseSound[]} - The sounds, or an empty array. + * @return {Phaser.GameObjects.Bob[]} An array of Bob objects that will be rendered this frame. */ - getAll: function (key) + getRenderList: function () { - return GetAll(this.sounds, 'key', key); + if (this.dirty) + { + this.renderList = this.children.list.filter(this.childCanRender, this); + this.dirty = false; + } + + return this.renderList; }, /** - * Adds a new sound to the sound manager and plays it. - * The sound will be automatically removed (destroyed) once playback ends. - * This lets you play a new sound on the fly without the need to keep a reference to it. + * Removes all Bobs from the children List and clears the dirty flag. * - * @method Phaser.Sound.BaseSoundManager#play - * @listens Phaser.Sound.Events#COMPLETE + * @method Phaser.GameObjects.Blitter#clear * @since 3.0.0 - * - * @param {string} key - Asset key for the sound. - * @param {(Phaser.Types.Sound.SoundConfig|Phaser.Types.Sound.SoundMarker)} [extra] - An optional additional object containing settings to be applied to the sound. It could be either config or marker object. - * - * @return {boolean} Whether the sound started playing successfully. */ - play: function (key, extra) + clear: function () { - var sound = this.add(key); - - sound.once(Events.COMPLETE, sound.destroy, sound); - - if (extra) - { - if (extra.name) - { - sound.addMarker(extra); - - return sound.play(extra.name); - } - else - { - return sound.play(extra); - } - } - else - { - return sound.play(); - } + this.children.removeAll(); + this.dirty = true; }, /** - * Adds a new audio sprite sound to the sound manager and plays it. - * The sprite will be automatically removed (destroyed) once playback ends. - * This lets you play a new sound on the fly without the need to keep a reference to it. - * - * @method Phaser.Sound.BaseSoundManager#playAudioSprite - * @listens Phaser.Sound.Events#COMPLETE - * @since 3.0.0 - * - * @param {string} key - Asset key for the sound. - * @param {string} spriteName - The name of the sound sprite to play. - * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. + * Internal destroy handler, called as part of the destroy process. * - * @return {boolean} Whether the audio sprite sound started playing successfully. + * @method Phaser.GameObjects.Blitter#preDestroy + * @protected + * @since 3.9.0 */ - playAudioSprite: function (key, spriteName, config) + preDestroy: function () { - var sound = this.addAudioSprite(key); + this.children.destroy(); - sound.once(Events.COMPLETE, sound.destroy, sound); + this.renderList = []; + } - return sound.play(spriteName, config); - }, +}); - /** - * Removes a sound from the sound manager. - * The removed sound is destroyed before removal. - * - * @method Phaser.Sound.BaseSoundManager#remove - * @since 3.0.0 - * - * @param {Phaser.Sound.BaseSound} sound - The sound object to remove. - * - * @return {boolean} True if the sound was removed successfully, otherwise false. - */ - remove: function (sound) +module.exports = Blitter; + + +/***/ }), + +/***/ 33177: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Renders this Game Object with the Canvas Renderer to the given Camera. + * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. + * This method should not be called directly. It is a utility function of the Render module. + * + * @method Phaser.GameObjects.Blitter#renderCanvas + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Blitter} 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 BlitterCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + var list = src.getRenderList(); + + if (list.length === 0) { - var index = this.sounds.indexOf(sound); + return; + } - if (index !== -1) - { - sound.destroy(); + var ctx = renderer.currentContext; - this.sounds.splice(index, 1); + var alpha = camera.alpha * src.alpha; - return true; - } + if (alpha === 0) + { + // Nothing to see, so abort early + return; + } - return false; - }, + camera.addToRenderList(src); + // Blend Mode + Scale Mode + ctx.globalCompositeOperation = renderer.blendModes[src.blendMode]; - /** - * Removes all sounds from the manager, destroying the sounds. - * - * @method Phaser.Sound.BaseSoundManager#removeAll - * @since 3.23.0 - */ - removeAll: function () + ctx.imageSmoothingEnabled = !src.frame.source.scaleMode; + + var cameraScrollX = src.x - camera.scrollX * src.scrollFactorX; + var cameraScrollY = src.y - camera.scrollY * src.scrollFactorY; + + ctx.save(); + + if (parentMatrix) { - this.sounds.forEach(function (sound) - { - sound.destroy(); - }); + parentMatrix.copyToContext(ctx); + } - this.sounds.length = 0; - }, + var roundPixels = camera.roundPixels; - /** - * Removes all sounds from the sound manager that have an asset key matching the given value. - * The removed sounds are destroyed before removal. - * - * @method Phaser.Sound.BaseSoundManager#removeByKey - * @since 3.0.0 - * - * @param {string} key - The key to match when removing sound objects. - * - * @return {number} The number of matching sound objects that were removed. - */ - removeByKey: function (key) + // Render bobs + for (var i = 0; i < list.length; i++) { - var removed = 0; + var bob = list[i]; + var flip = (bob.flipX || bob.flipY); + var frame = bob.frame; + var cd = frame.canvasData; + var dx = frame.x; + var dy = frame.y; + var fx = 1; + var fy = 1; - for (var i = this.sounds.length - 1; i >= 0; i--) + var bobAlpha = bob.alpha * alpha; + + if (bobAlpha === 0) { - var sound = this.sounds[i]; + continue; + } - if (sound.key === key) + ctx.globalAlpha = bobAlpha; + + if (!flip) + { + if (roundPixels) { - sound.destroy(); + dx = Math.round(dx); + dy = Math.round(dy); + } - this.sounds.splice(i, 1); + if (cd.width > 0 && cd.height > 0) + { + ctx.drawImage( + frame.source.image, + cd.x, + cd.y, + cd.width, + cd.height, + dx + bob.x + cameraScrollX, + dy + bob.y + cameraScrollY, + cd.width, + cd.height + ); + } + } + else + { + if (bob.flipX) + { + fx = -1; + dx -= cd.width; + } - removed++; + if (bob.flipY) + { + fy = -1; + dy -= cd.height; + } + + if (cd.width > 0 && cd.height > 0) + { + ctx.save(); + ctx.translate(bob.x + cameraScrollX, bob.y + cameraScrollY); + ctx.scale(fx, fy); + ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, dx, dy, cd.width, cd.height); + ctx.restore(); } } + } - return removed; - }, + ctx.restore(); +}; - /** - * Pauses all the sounds in the game. - * - * @method Phaser.Sound.BaseSoundManager#pauseAll - * @fires Phaser.Sound.Events#PAUSE_ALL - * @since 3.0.0 - */ - pauseAll: function () - { - this.forEachActiveSound(function (sound) - { - sound.pause(); - }); +module.exports = BlitterCanvasRenderer; - this.emit(Events.PAUSE_ALL, this); - }, - /** - * Resumes all the sounds in the game. - * - * @method Phaser.Sound.BaseSoundManager#resumeAll - * @fires Phaser.Sound.Events#RESUME_ALL - * @since 3.0.0 - */ - resumeAll: function () - { - this.forEachActiveSound(function (sound) - { - sound.resume(); - }); +/***/ }), - this.emit(Events.RESUME_ALL, this); - }, +/***/ 68452: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - /** - * Stops all the sounds in the game. - * - * @method Phaser.Sound.BaseSoundManager#stopAll - * @fires Phaser.Sound.Events#STOP_ALL - * @since 3.0.0 - */ - stopAll: function () - { - this.forEachActiveSound(function (sound) - { - sound.stop(); - }); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.emit(Events.STOP_ALL, this); - }, +var Blitter = __webpack_require__(52816); +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); + +/** + * Creates a new Blitter Game Object and returns it. + * + * Note: This method will only be available if the Blitter Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#blitter + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Blitter} The Game Object that was created. + */ +GameObjectCreator.register('blitter', function (config, addToScene) +{ + if (config === undefined) { config = {}; } + var key = GetAdvancedValue(config, 'key', null); + var frame = GetAdvancedValue(config, 'frame', null); - /** - * Stops any sounds matching the given key. - * - * @method Phaser.Sound.BaseSoundManager#stopByKey - * @since 3.23.0 - * - * @param {string} key - Sound asset key. - * - * @return {number} - How many sounds were stopped. - */ - stopByKey: function (key) + var blitter = new Blitter(this.scene, 0, 0, key, frame); + + if (addToScene !== undefined) { - var stopped = 0; + config.add = addToScene; + } - this.getAll(key).forEach(function (sound) - { - if (sound.stop()) { stopped++; } - }); + BuildGameObject(this.scene, blitter, config); - return stopped; - }, + return blitter; +}); - /** - * Method used internally for unlocking audio playback on devices that - * require user interaction before any sound can be played on a web page. - * - * 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.BaseSoundManager#unlock - * @override - * @protected - * @since 3.0.0 - */ - unlock: NOOP, +// When registering a factory function 'this' refers to the GameObjectCreator context. - /** - * Method used internally for pausing sound manager if - * Phaser.Sound.BaseSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.BaseSoundManager#onBlur - * @override - * @protected - * @since 3.0.0 - */ - onBlur: NOOP, - /** - * Method used internally for resuming sound manager if - * Phaser.Sound.BaseSoundManager#pauseOnBlur is set to true. - * - * @method Phaser.Sound.BaseSoundManager#onFocus - * @override - * @protected - * @since 3.0.0 - */ - onFocus: NOOP, +/***/ }), - /** - * Internal handler for Phaser.Core.Events#BLUR. - * - * @method Phaser.Sound.BaseSoundManager#onGameBlur - * @private - * @since 3.23.0 - */ - onGameBlur: function () - { - if (this.pauseOnBlur) - { - this.onBlur(); - } - }, +/***/ 38906: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - /** - * Internal handler for Phaser.Core.Events#FOCUS. - * - * @method Phaser.Sound.BaseSoundManager#onGameFocus - * @private - * @since 3.23.0 - */ - onGameFocus: function () - { - if (this.pauseOnBlur) - { - this.onFocus(); - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Update method called on every game step. - * Removes destroyed sounds and updates every active sound in the game. - * - * @method Phaser.Sound.BaseSoundManager#update - * @protected - * @fires Phaser.Sound.Events#UNLOCKED - * @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 elapsed since the last frame. - */ - update: function (time, delta) - { - if (this.unlocked) - { - this.unlocked = false; - this.locked = false; +var Blitter = __webpack_require__(52816); +var GameObjectFactory = __webpack_require__(61286); - this.emit(Events.UNLOCKED, this); - } +/** + * Creates a new Blitter Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Blitter Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#blitter + * @since 3.0.0 + * + * @param {number} x - The x position of the Game Object. + * @param {number} y - The y position of the Game Object. + * @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] - The default Frame children of the Blitter will use. + * + * @return {Phaser.GameObjects.Blitter} The Game Object that was created. + */ +GameObjectFactory.register('blitter', function (x, y, texture, frame) +{ + return this.displayList.add(new Blitter(this.scene, x, y, texture, frame)); +}); - for (var i = this.sounds.length - 1; i >= 0; i--) - { - if (this.sounds[i].pendingRemove) - { - this.sounds.splice(i, 1); - } - } +// When registering a factory function 'this' refers to the GameObjectFactory 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 - this.sounds.forEach(function (sound) - { - sound.update(time, delta); - }); - }, - /** - * Destroys all the sounds in the game and all associated events. - * - * @method Phaser.Sound.BaseSoundManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.game.events.off(GameEvents.BLUR, this.onGameBlur, this); - this.game.events.off(GameEvents.FOCUS, this.onGameFocus, this); - this.game.events.off(GameEvents.PRE_STEP, this.update, this); +/***/ }), - this.removeAllListeners(); +/***/ 92246: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.removeAll(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.sounds.length = 0; - this.sounds = null; +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - this.game = null; - }, +if (true) +{ + renderWebGL = __webpack_require__(89165); +} - /** - * Method used internally for iterating only over active sounds and skipping sounds that are marked for removal. - * - * @method Phaser.Sound.BaseSoundManager#forEachActiveSound - * @private - * @since 3.0.0 - * - * @param {Phaser.Types.Sound.EachActiveSoundCallback} callback - Callback function. (manager: Phaser.Sound.BaseSoundManager, sound: Phaser.Sound.BaseSound, index: number, sounds: Phaser.Manager.BaseSound[]) => void - * @param {*} [scope] - Callback context. - */ - forEachActiveSound: function (callback, scope) - { - var _this = this; +if (true) +{ + renderCanvas = __webpack_require__(33177); +} - this.sounds.forEach(function (sound, index) - { - if (sound && !sound.pendingRemove) - { - callback.call(scope || _this, sound, index, _this.sounds); - } - }); - }, +module.exports = { - /** - * Sets the global playback rate at which all the sounds will be played. - * - * 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.BaseSoundManager#setRate - * @fires Phaser.Sound.Events#GLOBAL_RATE - * @since 3.3.0 - * - * @param {number} value - Global playback rate at which all the sounds will be played. - * - * @return {Phaser.Sound.BaseSoundManager} This Sound Manager. - */ - setRate: function (value) + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 89165: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var TransformMatrix = __webpack_require__(69360); +var Utils = __webpack_require__(75512); + +var tempMatrix = 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.Blitter#renderWebGL + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Blitter} 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 BlitterWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + var list = src.getRenderList(); + var alpha = camera.alpha * src.alpha; + + if (list.length === 0 || alpha === 0) { - this.rate = value; + // Nothing to see, so abort early + return; + } - return this; - }, + camera.addToRenderList(src); - /** - * Global playback rate at which all the sounds 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 audio's playback speed. - * - * @name Phaser.Sound.BaseSoundManager#rate - * @type {number} - * @default 1 - * @since 3.0.0 - */ - rate: { + var pipeline = renderer.pipelines.set(this.pipeline, src); - get: function () - { - return this._rate; - }, + var cameraScrollX = camera.scrollX * src.scrollFactorX; + var cameraScrollY = camera.scrollY * src.scrollFactorY; - set: function (value) - { - this._rate = value; + var calcMatrix = tempMatrix.copyFrom(camera.matrix); - this.forEachActiveSound(function (sound) - { - sound.calculateRate(); - }); + if (parentMatrix) + { + calcMatrix.multiplyWithOffset(parentMatrix, -cameraScrollX, -cameraScrollY); - this.emit(Events.GLOBAL_RATE, this, value); - } + cameraScrollX = 0; + cameraScrollY = 0; + } - }, + var blitterX = src.x - cameraScrollX; + var blitterY = src.y - cameraScrollY; + var prevTextureSourceIndex = -1; + var tintEffect = false; + var roundPixels = camera.roundPixels; - /** - * Sets the global detuning of all sounds 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.BaseSoundManager#setDetune - * @fires Phaser.Sound.Events#GLOBAL_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 {Phaser.Sound.BaseSoundManager} This Sound Manager. - */ - setDetune: function (value) + renderer.pipelines.preBatch(src); + + for (var i = 0; i < list.length; i++) { - this.detune = value; + var bob = list[i]; + var frame = bob.frame; + var bobAlpha = bob.alpha * alpha; - return this; - }, + if (bobAlpha === 0) + { + continue; + } - /** - * Global detuning of all sounds 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.BaseSoundManager#detune - * @type {number} - * @default 0 - * @since 3.0.0 - */ - detune: { + var width = frame.width; + var height = frame.height; - get: function () + var x = blitterX + bob.x + frame.x; + var y = blitterY + bob.y + frame.y; + + if (bob.flipX) { - return this._detune; - }, + width *= -1; + x += frame.width; + } - set: function (value) + if (bob.flipY) { - this._detune = value; + height *= -1; + y += frame.height; + } - this.forEachActiveSound(function (sound) - { - sound.calculateRate(); - }); + var quad = calcMatrix.setQuad(x, y, x + width, y + height, roundPixels); - this.emit(Events.GLOBAL_DETUNE, this, value); + var tint = Utils.getTintAppendFloatAlpha(bob.tint, bobAlpha); + + // Bind texture only if the Texture Source is different from before + if (frame.sourceIndex !== prevTextureSourceIndex) + { + var textureUnit = pipeline.setGameObject(src, frame); + + prevTextureSourceIndex = frame.sourceIndex; } + if (pipeline.batchQuad(src, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, tintEffect, frame.glTexture, textureUnit)) + { + prevTextureSourceIndex = -1; + } } -}); + renderer.pipelines.postBatch(src); +}; -module.exports = BaseSoundManager; +module.exports = BlitterWebGLRenderer; /***/ }), -/* 146 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 41664: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(70); -var Extend = __webpack_require__(17); -var NOOP = __webpack_require__(1); +var Class = __webpack_require__(56694); +var Frame = __webpack_require__(82047); /** * @classdesc - * Class containing all the shared state and behavior of a sound object, independent of the implementation. + * A Bob Game Object. * - * @class BaseSound - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Sound + * 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.Sound.BaseSoundManager} 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. + * @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 BaseSound = new Class({ - - Extends: EventEmitter, +var Bob = new Class({ initialize: - function BaseSound (manager, key, config) + function Bob (blitter, x, y, frame, visible) { - EventEmitter.call(this); - - /** - * Local reference to the sound manager. - * - * @name Phaser.Sound.BaseSound#manager - * @type {Phaser.Sound.BaseSoundManager} - * @private - * @since 3.0.0 - */ - this.manager = manager; - /** - * Asset key for the sound. + * The Blitter object that this Bob belongs to. * - * @name Phaser.Sound.BaseSound#key - * @type {string} - * @readonly + * @name Phaser.GameObjects.Bob#parent + * @type {Phaser.GameObjects.Blitter} * @since 3.0.0 */ - this.key = key; + this.parent = blitter; /** - * Flag indicating if sound is currently playing. + * The x position of this Bob, relative to the x position of the Blitter. * - * @name Phaser.Sound.BaseSound#isPlaying - * @type {boolean} - * @default false - * @readonly + * @name Phaser.GameObjects.Bob#x + * @type {number} * @since 3.0.0 */ - this.isPlaying = false; + this.x = x; /** - * Flag indicating if sound is currently paused. + * The y position of this Bob, relative to the y position of the Blitter. * - * @name Phaser.Sound.BaseSound#isPaused - * @type {boolean} - * @default false - * @readonly + * @name Phaser.GameObjects.Bob#y + * @type {number} * @since 3.0.0 */ - this.isPaused = false; + this.y = y; /** - * A property that holds the value of sound's actual playback rate, - * after its rate and detune values has been combined with global - * rate and detune values. + * The frame that the Bob uses to render with. + * To change the frame use the `Bob.setFrame` method. * - * @name Phaser.Sound.BaseSound#totalRate - * @type {number} - * @default 1 - * @readonly + * @name Phaser.GameObjects.Bob#frame + * @type {Phaser.Textures.Frame} + * @protected * @since 3.0.0 */ - this.totalRate = 1; + this.frame = frame; /** - * A value representing the duration, in seconds. - * It could be total sound duration or a marker duration. + * A blank object which can be used to store data related to this Bob in. * - * @name Phaser.Sound.BaseSound#duration - * @type {number} - * @readonly + * @name Phaser.GameObjects.Bob#data + * @type {object} + * @default {} * @since 3.0.0 */ - this.duration = this.duration || 0; + this.data = {}; /** - * The total duration of the sound in seconds. + * The tint value of this Bob. * - * @name Phaser.Sound.BaseSound#totalDuration + * @name Phaser.GameObjects.Bob#tint * @type {number} - * @readonly - * @since 3.0.0 + * @default 0xffffff + * @since 3.20.0 */ - this.totalDuration = this.totalDuration || 0; + this.tint = 0xffffff; /** - * A config object used to store default sound settings' values. - * Default values will be set by properties' setters. + * The visible state of this Bob. * - * @name Phaser.Sound.BaseSound#config - * @type {Phaser.Types.Sound.SoundConfig} + * @name Phaser.GameObjects.Bob#_visible + * @type {boolean} * @private * @since 3.0.0 */ - this.config = { - - mute: false, - volume: 1, - rate: 1, - detune: 0, - seek: 0, - loop: false, - delay: 0, - pan: 0 - - }; + this._visible = visible; /** - * Reference to the currently used config. - * It could be default config or marker config. + * The alpha value of this Bob. * - * @name Phaser.Sound.BaseSound#currentConfig - * @type {Phaser.Types.Sound.SoundConfig} + * @name Phaser.GameObjects.Bob#_alpha + * @type {number} * @private + * @default 1 * @since 3.0.0 */ - this.currentConfig = this.config; - - this.config = Extend(this.config, config); + this._alpha = 1; /** - * Object containing markers definitions. + * 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.Sound.BaseSound#markers - * @type {Object.} - * @default {} - * @readonly + * @name Phaser.GameObjects.Bob#flipX + * @type {boolean} * @since 3.0.0 */ - this.markers = {}; + this.flipX = false; /** - * Currently playing marker. - * 'null' if whole sound is playing. + * 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.Sound.BaseSound#currentMarker - * @type {Phaser.Types.Sound.SoundMarker} - * @default null - * @readonly + * @name Phaser.GameObjects.Bob#flipY + * @type {boolean} * @since 3.0.0 */ - this.currentMarker = null; + this.flipY = false; /** - * Flag indicating if destroy method was called on this sound. + * Private read-only property used to allow Bobs to have physics bodies. * - * @name Phaser.Sound.BaseSound#pendingRemove + * @name Phaser.GameObjects.Bob#hasTransformComponent * @type {boolean} * @private - * @default false - * @since 3.0.0 + * @readonly + * @since 3.60.0 */ - this.pendingRemove = false; + this.hasTransformComponent = true; }, /** - * Adds a marker into the current sound. A marker is represented by name, start time, duration, and optionally config object. - * This allows you to bundle multiple sounds together into a single audio file and use markers to jump between them for playback. + * 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.Sound.BaseSound#addMarker + * @method Phaser.GameObjects.Bob#setFrame * @since 3.0.0 * - * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object. + * @param {(string|number|Phaser.Textures.Frame)} [frame] - The frame to be used during rendering. * - * @return {boolean} Whether the marker was added successfully. + * @return {this} This Bob Game Object. */ - addMarker: function (marker) + setFrame: function (frame) { - if (!marker || !marker.name || typeof marker.name !== 'string') + if (frame === undefined) { - return false; + this.frame = this.parent.frame; } - - if (this.markers[marker.name]) + else if (frame instanceof Frame && frame.texture === this.parent.texture) { - // eslint-disable-next-line no-console - console.error('addMarker ' + marker.name + ' already exists in Sound'); - - return false; + this.frame = frame; + } + else + { + this.frame = this.parent.texture.get(frame); } - marker = Extend(true, { - name: '', - start: 0, - duration: this.totalDuration - (marker.start || 0), - config: { - mute: false, - volume: 1, - rate: 1, - detune: 0, - seek: 0, - loop: false, - delay: 0, - pan: 0 - } - }, marker); - - this.markers[marker.name] = marker; - - return true; + return this; }, /** - * Updates previously added marker. + * Resets the horizontal and vertical flipped state of this Bob back to their default un-flipped state. * - * @method Phaser.Sound.BaseSound#updateMarker + * @method Phaser.GameObjects.Bob#resetFlip * @since 3.0.0 * - * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object with updated values. - * - * @return {boolean} Whether the marker was updated successfully. + * @return {this} This Bob Game Object. */ - updateMarker: function (marker) + resetFlip: function () { - if (!marker || !marker.name || typeof marker.name !== 'string') - { - return false; - } - - if (!this.markers[marker.name]) - { - // eslint-disable-next-line no-console - console.warn('Audio Marker: ' + marker.name + ' missing in Sound: ' + this.key); - - return false; - } - - this.markers[marker.name] = Extend(true, this.markers[marker.name], marker); + this.flipX = false; + this.flipY = false; - return true; + return this; }, /** - * Removes a marker from the sound. + * Resets this Bob. * - * @method Phaser.Sound.BaseSound#removeMarker + * 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 {string} markerName - The name of the marker to remove. + * @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 {?Phaser.Types.Sound.SoundMarker} Removed marker object or 'null' if there was no marker with provided name. + * @return {this} This Bob Game Object. */ - removeMarker: function (markerName) + reset: function (x, y, frame) { - var marker = this.markers[markerName]; + this.x = x; + this.y = y; - if (!marker) + this.flipX = false; + this.flipY = false; + + this._alpha = 1; + this._visible = true; + + this.parent.dirty = true; + + if (frame) { - return null; + this.setFrame(frame); } - this.markers[markerName] = null; - - return marker; + return this; }, /** - * 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. + * Changes the position of this Bob to the values given. * - * @method Phaser.Sound.BaseSound#play - * @since 3.0.0 + * @method Phaser.GameObjects.Bob#setPosition + * @since 3.20.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. + * @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 {boolean} Whether the sound started playing successfully. + * @return {this} This Bob Game Object. */ - play: function (markerName, config) + setPosition: function (x, y) { - if (markerName === undefined) { markerName = ''; } - - if (typeof markerName === 'object') - { - config = markerName; - markerName = ''; - } - - if (typeof markerName !== 'string') - { - return false; - } - - if (!markerName) - { - this.currentMarker = null; - this.currentConfig = this.config; - this.duration = this.totalDuration; - } - else - { - if (!this.markers[markerName]) - { - // eslint-disable-next-line no-console - console.warn('Marker: ' + markerName + ' missing in Sound: ' + this.key); - - return false; - } - - this.currentMarker = this.markers[markerName]; - this.currentConfig = this.currentMarker.config; - this.duration = this.currentMarker.duration; - } - - this.resetConfig(); - - this.currentConfig = Extend(this.currentConfig, config); - - this.isPlaying = true; - this.isPaused = false; + this.x = x; + this.y = y; - return true; + return this; }, /** - * Pauses the sound. + * Sets the horizontal flipped state of this Bob. * - * @method Phaser.Sound.BaseSound#pause + * @method Phaser.GameObjects.Bob#setFlipX * @since 3.0.0 * - * @return {boolean} Whether the sound was paused successfully. + * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. + * + * @return {this} This Bob Game Object. */ - pause: function () + setFlipX: function (value) { - if (this.isPaused || !this.isPlaying) - { - return false; - } - - this.isPlaying = false; - this.isPaused = true; + this.flipX = value; - return true; + return this; }, /** - * Resumes the sound. + * Sets the vertical flipped state of this Bob. * - * @method Phaser.Sound.BaseSound#resume + * @method Phaser.GameObjects.Bob#setFlipY * @since 3.0.0 * - * @return {boolean} Whether the sound was resumed successfully. + * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. + * + * @return {this} This Bob Game Object. */ - resume: function () + setFlipY: function (value) { - if (!this.isPaused || this.isPlaying) - { - return false; - } - - this.isPlaying = true; - this.isPaused = false; + this.flipY = value; - return true; + return this; }, /** - * Stop playing this sound. + * Sets the horizontal and vertical flipped state of this Bob. * - * @method Phaser.Sound.BaseSound#stop + * @method Phaser.GameObjects.Bob#setFlip * @since 3.0.0 * - * @return {boolean} Whether the sound was stopped successfully. + * @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. */ - stop: function () + setFlip: function (x, y) { - if (!this.isPaused && !this.isPlaying) - { - return false; - } - - this.isPlaying = false; - this.isPaused = false; - - this.resetConfig(); + this.flipX = x; + this.flipY = y; - return true; + return this; }, /** - * Method used internally for applying config values to some of the sound properties. + * Sets the visibility of this Bob. * - * @method Phaser.Sound.BaseSound#applyConfig - * @protected + * 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. */ - applyConfig: function () + setVisible: function (value) { - this.mute = this.currentConfig.mute; - this.volume = this.currentConfig.volume; - this.rate = this.currentConfig.rate; - this.detune = this.currentConfig.detune; - this.loop = this.currentConfig.loop; - this.pan = this.currentConfig.pan; + this.visible = value; + + return this; }, /** - * Method used internally for resetting values of some of the config properties. + * 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. * - * @method Phaser.Sound.BaseSound#resetConfig - * @protected + * 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. */ - resetConfig: function () + setAlpha: function (value) { - this.currentConfig.seek = 0; - this.currentConfig.delay = 0; + this.alpha = value; + + return this; }, /** - * Update method called automatically by sound manager on every game step. + * Sets the tint of this Bob. * - * @method Phaser.Sound.BaseSound#update - * @override - * @protected - * @since 3.0.0 + * @method Phaser.GameObjects.Bob#setTint + * @since 3.20.0 * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param {number} delta - The delta time elapsed since the last frame. - */ - update: NOOP, - - /** - * Method used internally to calculate total playback rate of the sound. + * @param {number} value - The tint value used for this Bob. Between 0 and 0xffffff. * - * @method Phaser.Sound.BaseSound#calculateRate - * @protected - * @since 3.0.0 + * @return {this} This Bob Game Object. */ - calculateRate: function () + setTint: function (value) { - var cent = 1.0005777895065548; // Math.pow(2, 1/1200); - var totalDetune = this.currentConfig.detune + this.manager.detune; - var detuneRate = Math.pow(cent, totalDetune); + this.tint = value; - this.totalRate = this.currentConfig.rate * this.manager.rate * detuneRate; + return this; }, /** - * Destroys this sound and all associated events and marks it for removal from the sound manager. + * Destroys this Bob instance. + * Removes itself from the Blitter and clears the parent, frame and data properties. * - * @method Phaser.Sound.BaseSound#destroy - * @fires Phaser.Sound.Events#DESTROY + * @method Phaser.GameObjects.Bob#destroy * @since 3.0.0 */ destroy: function () { - if (this.pendingRemove) - { - return; - } - - this.emit(Events.DESTROY, this); - this.pendingRemove = true; - this.manager = null; - this.key = ''; - this.removeAllListeners(); - this.isPlaying = false; - this.isPaused = false; - this.config = null; - this.currentConfig = null; - this.markers = null; - this.currentMarker = null; - } - -}); + this.parent.dirty = true; -module.exports = BaseSound; + this.parent.children.remove(this); + this.parent = undefined; + this.frame = undefined; + this.data = undefined; + }, -/***/ }), -/* 147 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The visible state of the Bob. + * + * An invisible Bob will skip rendering. + * + * @name Phaser.GameObjects.Bob#visible + * @type {boolean} + * @since 3.0.0 + */ + visible: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this._visible; + }, -var CheckMatrix = __webpack_require__(209); -var TransposeMatrix = __webpack_require__(435); + set: function (value) + { + this.parent.dirty |= (this._visible !== value); + this._visible = value; + } -/** - * Rotates the array matrix based on the given rotation value. - * - * The value can be given in degrees: 90, -90, 270, -270 or 180, - * or a string command: `rotateLeft`, `rotateRight` or `rotate180`. - * - * Based on the routine from {@link http://jsfiddle.net/MrPolywhirl/NH42z/}. - * - * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) - * have the same length. There must be at least two rows. This is an example matrix: - * - * ``` - * [ - * [ 1, 1, 1, 1, 1, 1 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 2, 0, 1, 2, 0, 4 ], - * [ 2, 0, 3, 4, 0, 4 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 3, 3, 3, 3, 3, 3 ] - * ] - * ``` - * - * @function Phaser.Utils.Array.Matrix.RotateMatrix - * @since 3.0.0 - * - * @generic T - * @genericUse {T[][]} - [matrix,$return] - * - * @param {T[][]} [matrix] - The array to rotate. - * @param {(number|string)} [direction=90] - The amount to rotate the matrix by. - * - * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix. - */ -var RotateMatrix = function (matrix, direction) -{ - if (direction === undefined) { direction = 90; } + }, - if (!CheckMatrix(matrix)) - { - return null; - } + /** + * 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: { - if (typeof direction !== 'string') - { - direction = ((direction % 360) + 360) % 360; - } + get: function () + { + return this._alpha; + }, - if (direction === 90 || direction === -270 || direction === 'rotateLeft') - { - matrix = TransposeMatrix(matrix); - matrix.reverse(); - } - else if (direction === -90 || direction === 270 || direction === 'rotateRight') - { - matrix.reverse(); - matrix = TransposeMatrix(matrix); - } - else if (Math.abs(direction) === 180 || direction === 'rotate180') - { - for (var i = 0; i < matrix.length; i++) + set: function (value) { - matrix[i].reverse(); + this.parent.dirty |= ((this._alpha > 0) !== (value > 0)); + this._alpha = value; } - matrix.reverse(); } - return matrix; -}; +}); -module.exports = RotateMatrix; +module.exports = Bob; /***/ }), -/* 148 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 97123: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Clamp = __webpack_require__(18); -var Components = __webpack_require__(11); -var GameObject = __webpack_require__(15); -var GetBitmapTextSize = __webpack_require__(1043); -var ParseFromAtlas = __webpack_require__(1044); -var ParseXMLBitmapFont = __webpack_require__(212); -var Rectangle = __webpack_require__(10); -var Render = __webpack_require__(1045); +var Clamp = __webpack_require__(82897); + +// bitmask flag for GameObject.renderMask +var _FLAG = 2; // 0010 /** - * @classdesc - * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. - * - * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to - * match the font structure. - * - * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability - * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by - * processing the font texture in an image editor, applying fills and any other effects required. - * - * To create multi-line text insert \r, \n or \r\n escape codes into the text string. - * - * To create a BitmapText data files you need a 3rd party app such as: - * - * BMFont (Windows, free): {@link http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/} - * Glyph Designer (OS X, commercial): {@link http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner} - * Littera (Web-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/} - * - * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of - * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: {@link http://codebeautify.org/xmltojson|http://codebeautify.org/xmltojson} + * Provides methods used for setting the alpha properties of a Game Object. + * Should be applied as a mixin and not used directly. * - * @class BitmapText - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor + * @namespace Phaser.GameObjects.Components.Alpha * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @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. It can only belong to one Scene at any given time. - * @param {number} x - The x coordinate of this Game Object in world space. - * @param {number} y - The y coordinate of this Game Object in world space. - * @param {string} font - The key of the font to use from the Bitmap Font cache. - * @param {(string|string[])} [text] - The string, or array of strings, to be set as the content of this Bitmap Text. - * @param {number} [size] - The font size of this Bitmap Text. - * @param {number} [align=0] - The alignment of the text in a multi-line BitmapText object. */ -var BitmapText = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.Depth, - Components.Mask, - Components.Origin, - Components.Pipeline, - Components.ScrollFactor, - Components.Texture, - Components.Tint, - Components.Transform, - Components.Visible, - Render - ], - - initialize: - - function BitmapText (scene, x, y, font, text, size, align) - { - if (text === undefined) { text = ''; } - if (align === undefined) { align = 0; } - - GameObject.call(this, scene, 'BitmapText'); - - /** - * The key of the Bitmap Font used by this Bitmap Text. - * To change the font after creation please use `setFont`. - * - * @name Phaser.GameObjects.BitmapText#font - * @type {string} - * @readonly - * @since 3.0.0 - */ - this.font = font; - - var entry = this.scene.sys.cache.bitmapFont.get(font); - - if (!entry) - { - console.warn('Invalid BitmapText key: ' + font); - } - - /** - * The data of the Bitmap Font used by this Bitmap Text. - * - * @name Phaser.GameObjects.BitmapText#fontData - * @type {Phaser.Types.GameObjects.BitmapText.BitmapFontData} - * @readonly - * @since 3.0.0 - */ - this.fontData = entry.data; - - /** - * The text that this Bitmap Text object displays. - * - * @name Phaser.GameObjects.BitmapText#_text - * @type {string} - * @private - * @since 3.0.0 - */ - this._text = ''; - - /** - * The font size of this Bitmap Text. - * - * @name Phaser.GameObjects.BitmapText#_fontSize - * @type {number} - * @private - * @since 3.0.0 - */ - this._fontSize = size || this.fontData.size; - - /** - * Adds / Removes spacing between characters. - * - * Can be a negative or positive number. - * - * @name Phaser.GameObjects.BitmapText#_letterSpacing - * @type {number} - * @private - * @since 3.4.0 - */ - this._letterSpacing = 0; - - /** - * Controls the alignment of each line of text in this BitmapText object. - * Only has any effect when this BitmapText contains multiple lines of text, split with carriage-returns. - * Has no effect with single-lines of text. - * - * See the methods `setLeftAlign`, `setCenterAlign` and `setRightAlign`. - * - * 0 = Left aligned (default) - * 1 = Middle aligned - * 2 = Right aligned - * - * The alignment position is based on the longest line of text. - * - * @name Phaser.GameObjects.BitmapText#_align - * @type {number} - * @private - * @since 3.11.0 - */ - this._align = align; - - /** - * An object that describes the size of this Bitmap Text. - * - * @name Phaser.GameObjects.BitmapText#_bounds - * @type {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} - * @private - * @since 3.0.0 - */ - this._bounds = GetBitmapTextSize(); - - /** - * An internal dirty flag for bounds calculation. - * - * @name Phaser.GameObjects.BitmapText#_dirty - * @type {boolean} - * @private - * @since 3.11.0 - */ - this._dirty = true; - - /** - * Internal cache var holding the maxWidth. - * - * @name Phaser.GameObjects.BitmapText#_maxWidth - * @type {number} - * @private - * @since 3.21.0 - */ - this._maxWidth = 0; - - /** - * The character code used to detect for word wrapping. - * Defaults to 32 (a space character). - * - * @name Phaser.GameObjects.BitmapText#wordWrapCharCode - * @type {number} - * @since 3.21.0 - */ - this.wordWrapCharCode = 32; - - /** - * Internal array holding the character tint color data. - * - * @name Phaser.GameObjects.BitmapText#charColors - * @type {array} - * @private - * @since 3.50.0 - */ - this.charColors = []; - - /** - * The horizontal offset of the drop shadow. - * - * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. - * - * @name Phaser.GameObjects.BitmapText#dropShadowX - * @type {number} - * @since 3.50.0 - */ - this.dropShadowX = 0; - - /** - * The vertical offset of the drop shadow. - * - * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. - * - * @name Phaser.GameObjects.BitmapText#dropShadowY - * @type {number} - * @since 3.50.0 - */ - this.dropShadowY = 0; - - /** - * The color of the drop shadow. - * - * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. - * - * @name Phaser.GameObjects.BitmapText#dropShadowColor - * @type {number} - * @since 3.50.0 - */ - this.dropShadowColor = 0x000000; - - /** - * The alpha value of the drop shadow. - * - * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. - * - * @name Phaser.GameObjects.BitmapText#dropShadowAlpha - * @type {number} - * @since 3.50.0 - */ - this.dropShadowAlpha = 0.5; - - /** - * Indicates whether the font texture is from an atlas or not. - * - * @name Phaser.GameObjects.BitmapText#fromAtlas - * @type {boolean} - * @since 3.54.0 - * @readonly - */ - this.fromAtlas = entry.fromAtlas; - - this.setTexture(entry.texture, entry.frame); - this.setPosition(x, y); - this.setOrigin(0, 0); - this.initPipeline(); - this.setText(text); - }, +var Alpha = { /** - * Set the lines of text in this BitmapText to be left-aligned. - * This only has any effect if this BitmapText contains more than one line of text. - * - * @method Phaser.GameObjects.BitmapText#setLeftAlign - * @since 3.11.0 + * Private internal value. Holds the global alpha value. * - * @return {this} This BitmapText Object. + * @name Phaser.GameObjects.Components.Alpha#_alpha + * @type {number} + * @private + * @default 1 + * @since 3.0.0 */ - setLeftAlign: function () - { - this._align = BitmapText.ALIGN_LEFT; - - this._dirty = true; - - return this; - }, + _alpha: 1, /** - * Set the lines of text in this BitmapText to be center-aligned. - * This only has any effect if this BitmapText contains more than one line of text. - * - * @method Phaser.GameObjects.BitmapText#setCenterAlign - * @since 3.11.0 + * Private internal value. Holds the top-left alpha value. * - * @return {this} This BitmapText Object. + * @name Phaser.GameObjects.Components.Alpha#_alphaTL + * @type {number} + * @private + * @default 1 + * @since 3.0.0 */ - setCenterAlign: function () - { - this._align = BitmapText.ALIGN_CENTER; - - this._dirty = true; - - return this; - }, + _alphaTL: 1, /** - * Set the lines of text in this BitmapText to be right-aligned. - * This only has any effect if this BitmapText contains more than one line of text. - * - * @method Phaser.GameObjects.BitmapText#setRightAlign - * @since 3.11.0 + * Private internal value. Holds the top-right alpha value. * - * @return {this} This BitmapText Object. + * @name Phaser.GameObjects.Components.Alpha#_alphaTR + * @type {number} + * @private + * @default 1 + * @since 3.0.0 */ - setRightAlign: function () - { - this._align = BitmapText.ALIGN_RIGHT; - - this._dirty = true; - - return this; - }, + _alphaTR: 1, /** - * Set the font size of this Bitmap Text. + * Private internal value. Holds the bottom-left alpha value. * - * @method Phaser.GameObjects.BitmapText#setFontSize + * @name Phaser.GameObjects.Components.Alpha#_alphaBL + * @type {number} + * @private + * @default 1 * @since 3.0.0 - * - * @param {number} size - The font size to set. - * - * @return {this} This BitmapText Object. */ - setFontSize: function (size) - { - this._fontSize = size; - - this._dirty = true; + _alphaBL: 1, - return this; - }, + /** + * Private internal value. Holds the bottom-right alpha value. + * + * @name Phaser.GameObjects.Components.Alpha#_alphaBR + * @type {number} + * @private + * @default 1 + * @since 3.0.0 + */ + _alphaBR: 1, /** - * Sets the letter spacing between each character of this Bitmap Text. - * Can be a positive value to increase the space, or negative to reduce it. - * Spacing is applied after the kerning values have been set. + * Clears all alpha values associated with this Game Object. * - * @method Phaser.GameObjects.BitmapText#setLetterSpacing - * @since 3.4.0 + * Immediately sets the alpha levels back to 1 (fully opaque). * - * @param {number} [spacing=0] - The amount of horizontal space to add between each character. + * @method Phaser.GameObjects.Components.Alpha#clearAlpha + * @since 3.0.0 * - * @return {this} This BitmapText Object. + * @return {this} This Game Object instance. */ - setLetterSpacing: function (spacing) + clearAlpha: function () { - if (spacing === undefined) { spacing = 0; } - - this._letterSpacing = spacing; - - this._dirty = true; - - return this; + return this.setAlpha(1); }, /** - * Set the textual content of this BitmapText. + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. * - * An array of strings will be converted into multi-line text. Use the align methods to change multi-line alignment. + * If your game is running under WebGL you can optionally specify four different alpha values, each of which + * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. * - * @method Phaser.GameObjects.BitmapText#setText + * @method Phaser.GameObjects.Components.Alpha#setAlpha * @since 3.0.0 * - * @param {(string|string[])} value - The string, or array of strings, to be set as the content of this BitmapText. + * @param {number} [topLeft=1] - The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. + * @param {number} [topRight] - The alpha value used for the top-right of the Game Object. WebGL only. + * @param {number} [bottomLeft] - The alpha value used for the bottom-left of the Game Object. WebGL only. + * @param {number} [bottomRight] - The alpha value used for the bottom-right of the Game Object. WebGL only. * - * @return {this} This BitmapText Object. + * @return {this} This Game Object instance. */ - setText: function (value) + setAlpha: function (topLeft, topRight, bottomLeft, bottomRight) { - if (!value && value !== 0) - { - value = ''; - } + if (topLeft === undefined) { topLeft = 1; } - if (Array.isArray(value)) + // Treat as if there is only one alpha value for the whole Game Object + if (topRight === undefined) { - value = value.join('\n'); + this.alpha = topLeft; } - - if (value !== this.text) + else { - this._text = value.toString(); - - this._dirty = true; - - this.updateDisplayOrigin(); + this._alphaTL = Clamp(topLeft, 0, 1); + this._alphaTR = Clamp(topRight, 0, 1); + this._alphaBL = Clamp(bottomLeft, 0, 1); + this._alphaBR = Clamp(bottomRight, 0, 1); } return this; }, /** - * Sets a drop shadow effect on this Bitmap Text. - * - * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. - * - * You can set the vertical and horizontal offset of the shadow, as well as the color and alpha. - * - * Once a shadow has been enabled you can modify the `dropShadowX` and `dropShadowY` properties of this - * Bitmap Text directly to adjust the position of the shadow in real-time. - * - * If you wish to clear the shadow, call this method with no parameters specified. - * - * @method Phaser.GameObjects.BitmapText#setDropShadow - * @webglOnly - * @since 3.50.0 - * - * @param {number} [x=0] - The horizontal offset of the drop shadow. - * @param {number} [y=0] - The vertical offset of the drop shadow. - * @param {number} [color=0x000000] - The color of the drop shadow, given as a hex value, i.e. `0x000000` for black. - * @param {number} [alpha=0.5] - The alpha of the drop shadow, given as a float between 0 and 1. This is combined with the Bitmap Text alpha as well. - * - * @return {this} This BitmapText Object. - */ - setDropShadow: function (x, y, color, alpha) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (color === undefined) { color = 0x000000; } - if (alpha === undefined) { alpha = 0.5; } - - this.dropShadowX = x; - this.dropShadowY = y; - this.dropShadowColor = color; - this.dropShadowAlpha = alpha; - - return this; - }, - - /** - * Sets a tint on a range of characters in this Bitmap Text, starting from the `start` parameter index - * and running for `length` quantity of characters. - * - * The `start` parameter can be negative. In this case, it starts at the end of the text and counts - * backwards `start` places. - * - * You can also pass in -1 as the `length` and it will tint all characters from `start` - * up until the end of the string. - - * Remember that spaces and punctuation count as characters. - * - * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. - * - * The tint works by taking the pixel color values from the Bitmap Text texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole character will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the character range. - * - * To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`. - * - * To modify the tint color once set, call this method again with new color values. - * - * Using `setWordTint` can override tints set by this function, and vice versa. - * - * To remove a tint call this method with just the `start`, and optionally, the `length` parameters defined. - * - * @method Phaser.GameObjects.BitmapText#setCharacterTint - * @webglOnly - * @since 3.50.0 + * The alpha value of the Game Object. * - * @param {number} [start=0] - The starting character to begin the tint at. If negative, it counts back from the end of the text. - * @param {number} [length=1] - The number of characters to tint. Remember that spaces count as a character too. Pass -1 to tint all characters from `start` onwards. - * @param {boolean} [tintFill=false] - Use a fill-based tint (true), or an additive tint (false) - * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the character. If not other values are given this value is applied evenly, tinting the whole character. - * @param {number} [topRight] - The tint being applied to the top-right of the character. - * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the character. - * @param {number} [bottomRight] - The tint being applied to the bottom-right of the character. + * This is a global value, impacting the entire Game Object, not just a region of it. * - * @return {this} This BitmapText Object. + * @name Phaser.GameObjects.Components.Alpha#alpha + * @type {number} + * @since 3.0.0 */ - setCharacterTint: function (start, length, tintFill, topLeft, topRight, bottomLeft, bottomRight) - { - if (start === undefined) { start = 0; } - if (length === undefined) { length = 1; } - if (tintFill === undefined) { tintFill = false; } - if (topLeft === undefined) { topLeft = -1; } - - if (topRight === undefined) - { - topRight = topLeft; - bottomLeft = topLeft; - bottomRight = topLeft; - } - - var len = this.text.length; + alpha: { - if (length === -1) + get: function () { - length = len; - } + return this._alpha; + }, - if (start < 0) + set: function (value) { - start = len + start; - } - - start = Clamp(start, 0, len - 1); - - var end = Clamp(start + length, start, len); - - var charColors = this.charColors; + var v = Clamp(value, 0, 1); - for (var i = start; i < end; i++) - { - var color = charColors[i]; + this._alpha = v; + this._alphaTL = v; + this._alphaTR = v; + this._alphaBL = v; + this._alphaBR = v; - if (topLeft === -1) + if (v === 0) { - charColors[i] = null; + this.renderFlags &= ~_FLAG; } else { - var tintEffect = (tintFill) ? 1 : 0; - - if (color) - { - color.tintEffect = tintEffect; - color.tintTL = topLeft; - color.tintTR = topRight; - color.tintBL = bottomLeft; - color.tintBR = bottomRight; - } - else - { - charColors[i] = { - tintEffect: tintEffect, - tintTL: topLeft, - tintTR: topRight, - tintBL: bottomLeft, - tintBR: bottomRight - }; - } + this.renderFlags |= _FLAG; } } - return this; }, /** - * Sets a tint on a matching word within this Bitmap Text. - * - * The `word` parameter can be either a string or a number. - * - * If a string, it will run a string comparison against the text contents, and if matching, - * it will tint the whole word. - * - * If a number, if till that word, based on its offset within the text contents. - * - * The `count` parameter controls how many words are replaced. Pass in -1 to replace them all. - * - * This parameter is ignored if you pass a number as the `word` to be searched for. - * - * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. - * - * The tint works by taking the pixel color values from the Bitmap Text texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole character will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the character range. - * - * To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`. - * - * To modify the tint color once set, call this method again with new color values. - * - * Using `setCharacterTint` can override tints set by this function, and vice versa. + * The alpha value starting from the top-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. * - * @method Phaser.GameObjects.BitmapText#setWordTint + * @name Phaser.GameObjects.Components.Alpha#alphaTopLeft + * @type {number} * @webglOnly - * @since 3.50.0 - * - * @param {(string|number)} word - The word to search for. Either a string, or an index of the word in the words array. - * @param {number} [count=1] - The number of matching words to tint. Pass -1 to tint all matching words. - * @param {boolean} [tintFill=false] - Use a fill-based tint (true), or an additive tint (false) - * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the word. If not other values are given this value is applied evenly, tinting the whole word. - * @param {number} [topRight] - The tint being applied to the top-right of the word. - * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the word. - * @param {number} [bottomRight] - The tint being applied to the bottom-right of the word. - * - * @return {this} This BitmapText Object. + * @since 3.0.0 */ - setWordTint: function (word, count, tintFill, topLeft, topRight, bottomLeft, bottomRight) - { - if (count === undefined) { count = 1; } - - var bounds = this.getTextBounds(); - - var words = bounds.words; - - var wordIsNumber = (typeof(word) === 'number'); - - var total = 0; + alphaTopLeft: { - for (var i = 0; i < words.length; i++) + get: function () { - var lineword = words[i]; + return this._alphaTL; + }, - if ((wordIsNumber && i === word) || (!wordIsNumber && lineword.word === word)) - { - this.setCharacterTint(lineword.i, lineword.word.length, tintFill, topLeft, topRight, bottomLeft, bottomRight); + set: function (value) + { + var v = Clamp(value, 0, 1); - total++; + this._alphaTL = v; - if (total === count) - { - return this; - } + if (v !== 0) + { + this.renderFlags |= _FLAG; } } - return this; }, /** - * Calculate the bounds of this Bitmap Text. - * - * An object is returned that contains the position, width and height of the Bitmap Text in local and global - * contexts. - * - * Local size is based on just the font size and a [0, 0] position. - * - * Global size takes into account the Game Object's scale, world position and display origin. - * - * Also in the object is data regarding the length of each line, should this be a multi-line BitmapText. + * The alpha value starting from the top-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. * - * @method Phaser.GameObjects.BitmapText#getTextBounds + * @name Phaser.GameObjects.Components.Alpha#alphaTopRight + * @type {number} + * @webglOnly * @since 3.0.0 - * - * @param {boolean} [round=false] - Whether to round the results up to the nearest integer. - * - * @return {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} An object that describes the size of this Bitmap Text. */ - getTextBounds: function (round) - { - // local = The BitmapText based on fontSize and 0x0 coords - // global = The BitmapText, taking into account scale and world position - // lines = The BitmapText line data + alphaTopRight: { - var bounds = this._bounds; + get: function () + { + return this._alphaTR; + }, - if (this._dirty || round || this.scaleX !== bounds.scaleX || this.scaleY !== bounds.scaleY) + set: function (value) { - GetBitmapTextSize(this, round, true, bounds); + var v = Clamp(value, 0, 1); - this._dirty = false; + this._alphaTR = v; + + if (v !== 0) + { + this.renderFlags |= _FLAG; + } } - return bounds; }, /** - * Gets the character located at the given x/y coordinate within this Bitmap Text. - * - * The coordinates you pass in are translated into the local space of the - * Bitmap Text, however, it is up to you to first translate the input coordinates to world space. - * - * If you wish to use this in combination with an input event, be sure - * to pass in `Pointer.worldX` and `worldY` so they are in world space. - * - * In some cases, based on kerning, characters can overlap. When this happens, - * the first character in the word is returned. - * - * Note that this does not work for DynamicBitmapText if you have changed the - * character positions during render. It will only scan characters in their un-translated state. - * - * @method Phaser.GameObjects.BitmapText#getCharacterAt - * @since 3.50.0 - * - * @param {number} x - The x position to check. - * @param {number} y - The y position to check. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera. + * The alpha value starting from the bottom-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. * - * @return {Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter} The character object at the given position, or `null`. + * @name Phaser.GameObjects.Components.Alpha#alphaBottomLeft + * @type {number} + * @webglOnly + * @since 3.0.0 */ - getCharacterAt: function (x, y, camera) - { - var point = this.getLocalPoint(x, y, null, camera); - - var bounds = this.getTextBounds(); - - var chars = bounds.characters; + alphaBottomLeft: { - var tempRect = new Rectangle(); + get: function () + { + return this._alphaBL; + }, - for (var i = 0; i < chars.length; i++) + set: function (value) { - var char = chars[i]; + var v = Clamp(value, 0, 1); - tempRect.setTo(char.x, char.t, char.r - char.x, char.b); + this._alphaBL = v; - if (tempRect.contains(point.x, point.y)) + if (v !== 0) { - return char; + this.renderFlags |= _FLAG; } } - return null; }, /** - * Updates the Display Origin cached values internally stored on this Game Object. - * You don't usually call this directly, but it is exposed for edge-cases where you may. + * The alpha value starting from the bottom-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. * - * @method Phaser.GameObjects.BitmapText#updateDisplayOrigin + * @name Phaser.GameObjects.Components.Alpha#alphaBottomRight + * @type {number} + * @webglOnly * @since 3.0.0 - * - * @return {this} This Game Object instance. */ - updateDisplayOrigin: function () - { - this._dirty = true; - - this.getTextBounds(false); - - return this; - }, + alphaBottomRight: { - /** - * Changes the font this BitmapText is using to render. - * - * The new texture is loaded and applied to the BitmapText. The existing test, size and alignment are preserved, - * unless overridden via the arguments. - * - * @method Phaser.GameObjects.BitmapText#setFont - * @since 3.11.0 - * - * @param {string} font - The key of the font to use from the Bitmap Font cache. - * @param {number} [size] - The font size of this Bitmap Text. If not specified the current size will be used. - * @param {number} [align=0] - The alignment of the text in a multi-line BitmapText object. If not specified the current alignment will be used. - * - * @return {this} This BitmapText Object. - */ - setFont: function (key, size, align) - { - if (size === undefined) { size = this._fontSize; } - if (align === undefined) { align = this._align; } + get: function () + { + return this._alphaBR; + }, - if (key !== this.font) + set: function (value) { - var entry = this.scene.sys.cache.bitmapFont.get(key); + var v = Clamp(value, 0, 1); - if (entry) - { - this.font = key; - this.fontData = entry.data; - this._fontSize = size; - this._align = align; - this.fromAtlas = entry.fromAtlas === true; - - this.setTexture(entry.texture, entry.frame); + this._alphaBR = v; - GetBitmapTextSize(this, false, true, this._bounds); + if (v !== 0) + { + this.renderFlags |= _FLAG; } } - return this; - }, + } + +}; + +module.exports = Alpha; + + +/***/ }), + +/***/ 15720: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Clamp = __webpack_require__(82897); + +// bitmask flag for GameObject.renderMask +var _FLAG = 2; // 0010 + +/** + * Provides methods used for setting the alpha property of a Game Object. + * Should be applied as a mixin and not used directly. + * + * @namespace Phaser.GameObjects.Components.AlphaSingle + * @since 3.22.0 + */ + +var AlphaSingle = { /** - * Sets the maximum display width of this BitmapText in pixels. + * Private internal value. Holds the global alpha value. * - * If `BitmapText.text` is longer than `maxWidth` then the lines will be automatically wrapped - * based on the previous whitespace character found in the line. + * @name Phaser.GameObjects.Components.AlphaSingle#_alpha + * @type {number} + * @private + * @default 1 + * @since 3.0.0 + */ + _alpha: 1, + + /** + * Clears all alpha values associated with this Game Object. * - * If no whitespace was found then no wrapping will take place and consequently the `maxWidth` value will not be honored. + * Immediately sets the alpha levels back to 1 (fully opaque). * - * Disable maxWidth by setting the value to 0. + * @method Phaser.GameObjects.Components.AlphaSingle#clearAlpha + * @since 3.0.0 * - * You can set the whitespace character to be searched for by setting the `wordWrapCharCode` parameter or property. + * @return {this} This Game Object instance. + */ + clearAlpha: function () + { + return this.setAlpha(1); + }, + + /** + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. * - * @method Phaser.GameObjects.BitmapText#setMaxWidth - * @since 3.21.0 + * @method Phaser.GameObjects.Components.AlphaSingle#setAlpha + * @since 3.0.0 * - * @param {number} value - The maximum display width of this BitmapText in pixels. Set to zero to disable. - * @param {number} [wordWrapCharCode] - The character code to check for when word wrapping. Defaults to 32 (the space character). + * @param {number} [value=1] - The alpha value applied across the whole Game Object. * - * @return {this} This BitmapText Object. + * @return {this} This Game Object instance. */ - setMaxWidth: function (value, wordWrapCharCode) + setAlpha: function (value) { - this._maxWidth = value; - - this._dirty = true; + if (value === undefined) { value = 1; } - if (wordWrapCharCode !== undefined) - { - this.wordWrapCharCode = wordWrapCharCode; - } + this.alpha = value; return this; }, /** - * Controls the alignment of each line of text in this BitmapText object. - * - * Only has any effect when this BitmapText contains multiple lines of text, split with carriage-returns. - * Has no effect with single-lines of text. - * - * See the methods `setLeftAlign`, `setCenterAlign` and `setRightAlign`. - * - * 0 = Left aligned (default) - * 1 = Middle aligned - * 2 = Right aligned + * The alpha value of the Game Object. * - * The alignment position is based on the longest line of text. + * This is a global value, impacting the entire Game Object, not just a region of it. * - * @name Phaser.GameObjects.BitmapText#align + * @name Phaser.GameObjects.Components.AlphaSingle#alpha * @type {number} - * @since 3.11.0 + * @since 3.0.0 */ - align: { + alpha: { - set: function (value) + get: function () { - this._align = value; - this._dirty = true; + return this._alpha; }, - get: function () + set: function (value) { - return this._align; + var v = Clamp(value, 0, 1); + + this._alpha = v; + + if (v === 0) + { + this.renderFlags &= ~_FLAG; + } + else + { + this.renderFlags |= _FLAG; + } } - }, + } + +}; + +module.exports = AlphaSingle; + + +/***/ }), + +/***/ 69732: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BlendModes = __webpack_require__(95723); + +/** + * Provides methods used for setting the blend mode of a Game Object. + * Should be applied as a mixin and not used directly. + * + * @namespace Phaser.GameObjects.Components.BlendMode + * @since 3.0.0 + */ + +var BlendMode = { /** - * The text that this Bitmap Text object displays. + * Private internal value. Holds the current blend mode. * - * You can also use the method `setText` if you want a chainable way to change the text content. + * @name Phaser.GameObjects.Components.BlendMode#_blendMode + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + _blendMode: BlendModes.NORMAL, + + /** + * Sets the Blend Mode being used by this Game Object. * - * @name Phaser.GameObjects.BitmapText#text - * @type {string} + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. + * + * @name Phaser.GameObjects.Components.BlendMode#blendMode + * @type {(Phaser.BlendModes|string|number)} * @since 3.0.0 */ - text: { + blendMode: { - set: function (value) + get: function () { - this.setText(value); + return this._blendMode; }, - get: function () + set: function (value) { - return this._text; + if (typeof value === 'string') + { + value = BlendModes[value]; + } + + value |= 0; + + if (value >= -1) + { + this._blendMode = value; + } } }, /** - * The font size of this Bitmap Text. + * Sets the Blend Mode being used by this Game Object. * - * You can also use the method `setFontSize` if you want a chainable way to change the font size. + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) * - * @name Phaser.GameObjects.BitmapText#fontSize - * @type {number} + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * + * @method Phaser.GameObjects.Components.BlendMode#setBlendMode * @since 3.0.0 + * + * @param {(string|Phaser.BlendModes|number)} value - The BlendMode value. Either a string, a CONST or a number. + * + * @return {this} This Game Object instance. */ - fontSize: { + setBlendMode: function (value) + { + this.blendMode = value; - set: function (value) - { - this._fontSize = value; - this._dirty = true; - }, + return this; + } - get: function () - { - return this._fontSize; - } +}; - }, +module.exports = BlendMode; + + +/***/ }), + +/***/ 28284: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Provides methods used for calculating and setting the size of a non-Frame based Game Object. + * Should be applied as a mixin and not used directly. + * + * @namespace Phaser.GameObjects.Components.ComputedSize + * @since 3.0.0 + */ + +var ComputedSize = { /** - * Adds / Removes spacing between characters. + * The native (un-scaled) width of this Game Object. * - * Can be a negative or positive number. + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. * - * You can also use the method `setLetterSpacing` if you want a chainable way to change the letter spacing. + * @name Phaser.GameObjects.Components.ComputedSize#width + * @type {number} + * @since 3.0.0 + */ + width: 0, + + /** + * The native (un-scaled) height of this Game Object. * - * @name Phaser.GameObjects.BitmapText#letterSpacing + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. + * + * @name Phaser.GameObjects.Components.ComputedSize#height * @type {number} * @since 3.0.0 */ - letterSpacing: { + height: 0, - set: function (value) + /** + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + * + * @name Phaser.GameObjects.Components.ComputedSize#displayWidth + * @type {number} + * @since 3.0.0 + */ + displayWidth: { + + get: function () { - this._letterSpacing = value; - this._dirty = true; + return this.scaleX * this.width; }, - get: function () + set: function (value) { - return this._letterSpacing; + this.scaleX = value / this.width; } }, /** - * The maximum display width of this BitmapText in pixels. - * - * If BitmapText.text is longer than maxWidth then the lines will be automatically wrapped - * based on the last whitespace character found in the line. + * The displayed height of this Game Object. * - * If no whitespace was found then no wrapping will take place and consequently the maxWidth value will not be honored. + * This value takes into account the scale factor. * - * Disable maxWidth by setting the value to 0. + * Setting this value will adjust the Game Object's scale property. * - * @name Phaser.GameObjects.BitmapText#maxWidth + * @name Phaser.GameObjects.Components.ComputedSize#displayHeight * @type {number} - * @since 3.21.0 + * @since 3.0.0 */ - maxWidth: { + displayHeight: { - set: function (value) + get: function () { - this._maxWidth = value; - this._dirty = true; + return this.scaleY * this.height; }, - get: function () + set: function (value) { - return this._maxWidth; + this.scaleY = value / this.height; } }, /** - * The width of this Bitmap Text. + * Sets the internal size of this Game Object, as used for frame or physics body creation. * - * @name Phaser.GameObjects.BitmapText#width - * @type {number} - * @readonly - * @since 3.0.0 + * This will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or call the + * `setDisplaySize` method, which is the same thing as changing the scale but allows you + * to do so by giving pixel values. + * + * If you have enabled this Game Object for input, changing the size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * + * @method Phaser.GameObjects.Components.ComputedSize#setSize + * @since 3.4.0 + * + * @param {number} width - The width of this Game Object. + * @param {number} height - The height of this Game Object. + * + * @return {this} This Game Object instance. */ - width: { - - get: function () - { - this.getTextBounds(false); - - return this._bounds.global.width; - } + setSize: function (width, height) + { + this.width = width; + this.height = height; + return this; }, /** - * The height of this bitmap text. + * Sets the display size of this Game Object. * - * @name Phaser.GameObjects.BitmapText#height - * @type {number} - * @readonly - * @since 3.0.0 + * Calling this will adjust the scale. + * + * @method Phaser.GameObjects.Components.ComputedSize#setDisplaySize + * @since 3.4.0 + * + * @param {number} width - The width of this Game Object. + * @param {number} height - The height of this Game Object. + * + * @return {this} This Game Object instance. */ - height: { + setDisplaySize: function (width, height) + { + this.displayWidth = width; + this.displayHeight = height; - get: function () - { - this.getTextBounds(false); + return this; + } - return this._bounds.global.height; - } +}; - }, +module.exports = ComputedSize; + + +/***/ }), + +/***/ 85293: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Provides methods used for getting and setting the texture of a Game Object. + * + * @namespace Phaser.GameObjects.Components.Crop + * @since 3.12.0 + */ + +var Crop = { /** - * Build a JSON representation of this Bitmap Text. + * The Texture this Game Object is using to render with. * - * @method Phaser.GameObjects.BitmapText#toJSON + * @name Phaser.GameObjects.Components.Crop#texture + * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} * @since 3.0.0 + */ + texture: null, + + /** + * The Texture Frame this Game Object is using to render with. * - * @return {Phaser.Types.GameObjects.BitmapText.JSONBitmapText} A JSON representation of this Bitmap Text. + * @name Phaser.GameObjects.Components.Crop#frame + * @type {Phaser.Textures.Frame} + * @since 3.0.0 */ - toJSON: function () - { - var out = Components.ToJSON(this); + frame: null, - // Extra data is added here + /** + * A boolean flag indicating if this Game Object is being cropped or not. + * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. + * Equally, calling `setCrop` with no arguments will reset the crop and disable it. + * + * @name Phaser.GameObjects.Components.Crop#isCropped + * @type {boolean} + * @since 3.11.0 + */ + isCropped: false, - var data = { - font: this.font, - text: this.text, - fontSize: this.fontSize, - letterSpacing: this.letterSpacing, - align: this.align - }; + /** + * Applies a crop to a texture based Game Object, such as a Sprite or Image. + * + * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. + * + * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just + * changes what is shown when rendered. + * + * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. + * + * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left + * half of it, you could call `setCrop(0, 0, 400, 600)`. + * + * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop + * an area of 200x100 when applied to a Game Object that had a scale factor of 2. + * + * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. + * + * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. + * + * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow + * the renderer to skip several internal calculations. + * + * @method Phaser.GameObjects.Components.Crop#setCrop + * @since 3.11.0 + * + * @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. + * @param {number} [y] - The y coordinate to start the crop from. + * @param {number} [width] - The width of the crop rectangle in pixels. + * @param {number} [height] - The height of the crop rectangle in pixels. + * + * @return {this} This Game Object instance. + */ + setCrop: function (x, y, width, height) + { + if (x === undefined) + { + this.isCropped = false; + } + else if (this.frame) + { + if (typeof x === 'number') + { + this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY); + } + else + { + var rect = x; - out.data = data; + this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY); + } - return out; + this.isCropped = true; + } + + return this; }, /** - * Internal destroy handler, called as part of the destroy process. + * Internal method that returns a blank, well-formed crop object for use by a Game Object. * - * @method Phaser.GameObjects.BitmapText#preDestroy - * @protected - * @since 3.50.0 + * @method Phaser.GameObjects.Components.Crop#resetCropObject + * @private + * @since 3.12.0 + * + * @return {object} The crop object. */ - preDestroy: function () + resetCropObject: function () { - this.charColors.length = 0; - this._bounds = null; - this.fontData = null; + return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 }; } -}); +}; -/** - * Left align the text characters in a multi-line BitmapText object. - * - * @name Phaser.GameObjects.BitmapText.ALIGN_LEFT - * @type {number} - * @since 3.11.0 - */ -BitmapText.ALIGN_LEFT = 0; +module.exports = Crop; -/** - * Center align the text characters in a multi-line BitmapText object. - * - * @name Phaser.GameObjects.BitmapText.ALIGN_CENTER - * @type {number} - * @since 3.11.0 - */ -BitmapText.ALIGN_CENTER = 1; + +/***/ }), + +/***/ 14975: +/***/ ((module) => { /** - * Right align the text characters in a multi-line BitmapText object. - * - * @name Phaser.GameObjects.BitmapText.ALIGN_RIGHT - * @type {number} - * @since 3.11.0 + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -BitmapText.ALIGN_RIGHT = 2; /** - * Parse an XML Bitmap Font from an Atlas. - * - * Adds the parsed Bitmap Font data to the cache with the `fontName` key. + * Provides methods used for setting the depth of a Game Object. + * Should be applied as a mixin and not used directly. * - * @method Phaser.GameObjects.BitmapText.ParseFromAtlas + * @namespace Phaser.GameObjects.Components.Depth * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to parse the Bitmap Font for. - * @param {string} fontName - The key of the font to add to the Bitmap Font cache. - * @param {string} textureKey - The key of the BitmapFont's texture. - * @param {string} frameKey - The key of the BitmapFont texture's frame. - * @param {string} xmlKey - The key of the XML data of the font to parse. - * @param {number} [xSpacing] - The x-axis spacing to add between each letter. - * @param {number} [ySpacing] - The y-axis spacing to add to the line height. - * - * @return {boolean} Whether the parsing was successful or not. */ -BitmapText.ParseFromAtlas = ParseFromAtlas; -/** - * Parse an XML font to Bitmap Font data for the Bitmap Font cache. - * - * @method Phaser.GameObjects.BitmapText.ParseXMLBitmapFont - * @since 3.17.0 - * - * @param {XMLDocument} xml - The XML Document to parse the font from. - * @param {Phaser.Textures.Frame} frame - The texture frame to take into account when creating the uv data. - * @param {number} [xSpacing=0] - The x-axis spacing to add between each letter. - * @param {number} [ySpacing=0] - The y-axis spacing to add to the line height. - * - * @return {Phaser.Types.GameObjects.BitmapText.BitmapFontData} The parsed Bitmap Font data. - */ -BitmapText.ParseXMLBitmapFont = ParseXMLBitmapFont; +var Depth = { -module.exports = BitmapText; + /** + * Private internal value. Holds the depth of the Game Object. + * + * @name Phaser.GameObjects.Components.Depth#_depth + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + _depth: 0, + + /** + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * + * @name Phaser.GameObjects.Components.Depth#depth + * @type {number} + * @since 3.0.0 + */ + depth: { + + get: function () + { + return this._depth; + }, + + set: function (value) + { + if (this.displayList) + { + this.displayList.queueDepthSort(); + } + + this._depth = value; + } + + }, + + /** + * The depth of this Game Object within the Scene. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * + * @method Phaser.GameObjects.Components.Depth#setDepth + * @since 3.0.0 + * + * @param {number} value - The depth of this Game Object. Ensure this value is only ever a number data-type. + * + * @return {this} This Game Object instance. + */ + setDepth: function (value) + { + if (value === undefined) { value = 0; } + + this.depth = value; + + return this; + } + +}; + +module.exports = Depth; /***/ }), -/* 149 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 88677: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); +var Class = __webpack_require__(56694); +var Effects = __webpack_require__(96910); +var SpliceOne = __webpack_require__(72677); /** - * @callback EachSetCallback + * @classdesc + * The FX Component features a set of methods used for applying a range of special built-in effects to a Game Object. * - * @param {E} entry - The Set entry. - * @param {number} index - The index of the entry within the Set. + * The effects include the following: * - * @return {?boolean} The callback result. - */ - -/** - * @classdesc - * A Set is a collection of unique elements. + * * Barrel Distortion + * * Bloom + * * Blur + * * Bokeh / Tilt Shift + * * Circle Outline + * * Color Matrix + * * Glow + * * Displacement + * * Gradient + * * Pixelate + * * Shine + * * Shadow + * * Vignette + * * Wipe / Reveal * - * @class Set - * @memberof Phaser.Structs - * @constructor - * @since 3.0.0 + * All Game Objects support Post FX. These are effects applied after the Game Object has been rendered. * - * @generic T - * @genericUse {T[]} - [elements] + * Texture-based Game Objects also support Pre FX, including: * - * @param {Array.<*>} [elements] - An optional array of elements to insert into this Set. + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * And any Game Object that extends the above. + * + * The difference between Pre FX and Post FX are that all Post FX take place in a canvas (renderer) sized frame buffer, + * after the Game Object has been rendered. Pre FX, however, take place in a texture sized frame buffer, which is sized + * based on the Game Object itself. The end result is then composited back to the main game canvas. For intensive effects, + * such as blur, bloom or glow, which can require many iterations, this is a much more efficient way to apply the effect, + * as only it only has to work on a Game Object sized texture and not all pixels in the canvas. + * + * In short, you should always try and use a Pre FX if you can. + * + * Due to the way that FX work they can be stacked-up. For example, you can apply a blur to a Game Object, then apply + * a bloom effect to the same Game Object. The bloom effect will be applied to the blurred texture, not the original. + * Keep the order in mind when stacking effects. + * + * All effects are WebGL only and do not have canvas counterparts. + * + * As you can appreciate, some effects are more expensive than others. For example, a bloom effect is going to be more + * expensive than a simple color matrix effect, so please consider using them wisely and performance test your target + * platforms early on in production. + * + * This component is created automatically by the `PostPipeline` class and does not need to be instantiated directly. + * + * @class FX + * @memberof Phaser.GameObjects.Components + * @constructor + * @since 3.60.0 + * @webglOnly + * + * @param {Phaser.GameObjects.GameObject} gameObject - A reference to the Game Object that owns this FX Component. + * @param {boolean} isPost - Is this a Pre or Post FX Component? */ -var Set = new Class({ +var FX = new Class({ initialize: - function Set (elements) + function FX (gameObject, isPost) { /** - * The entries of this Set. Stored internally as an array. + * A reference to the Game Object that owns this FX Component. * - * @genericUse {T[]} - [$type] + * @name Phaser.GameObjects.Components.FX#gameObject + * @type {Phaser.GameObjects.GameObject} + * @readonly + * @since 3.60.0 + */ + this.gameObject = gameObject; + + /** + * Is this a Post FX Controller? or a Pre FX Controller? * - * @name Phaser.Structs.Set#entries - * @type {Array.<*>} - * @default [] - * @since 3.0.0 + * @name Phaser.GameObjects.Components.FX#isPost + * @type {boolean} + * @readonly + * @since 3.60.0 */ - this.entries = []; + this.isPost = isPost; - if (Array.isArray(elements)) - { - for (var i = 0; i < elements.length; i++) - { - this.set(elements[i]); - } - } + /** + * Has this FX Component been enabled? + * + * You should treat this property as read-only, although it is toggled + * automaticaly during internal use. + * + * @name Phaser.GameObjects.Components.FX#enabled + * @type {boolean} + * @since 3.60.0 + */ + this.enabled = false; + + /** + * An array containing all of the Pre FX Controllers that + * have been added to this FX Component. They are processed in + * the order they are added. + * + * This array is empty if this is a Post FX Component. + * + * @name Phaser.GameObjects.Components.FX#list + * @type {Phaser.FX.Controller[]} + * @since 3.60.0 + */ + this.list = []; + + /** + * The amount of extra padding to be applied to this Game Object + * when it is being rendered by a PreFX Pipeline. + * + * Lots of FX require additional spacing added to the texture the + * Game Object uses, for example a glow or shadow effect, and this + * method allows you to control how much extra padding is included + * in addition to the texture size. + * + * You do not need to set this if you're only using Post FX. + * + * @name Phaser.GameObjects.Components.FX#padding + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.padding = 0; }, /** - * Inserts the provided value into this Set. If the value is already contained in this Set this method will have no effect. + * Sets the amount of extra padding to be applied to this Game Object + * when it is being rendered by a PreFX Pipeline. * - * @method Phaser.Structs.Set#set - * @since 3.0.0 + * Lots of FX require additional spacing added to the texture the + * Game Object uses, for example a glow or shadow effect, and this + * method allows you to control how much extra padding is included + * in addition to the texture size. * - * @genericUse {T} - [value] - * @genericUse {Phaser.Structs.Set.} - [$return] + * You do not need to set this if you're only using Post FX. * - * @param {*} value - The value to insert into this Set. + * @method Phaser.GameObjects.Components.FX#setPadding + * @webglOnly + * @since 3.60.0 * - * @return {Phaser.Structs.Set} This Set object. + * @param {number} [padding=0] - The amount of padding to add to this Game Object. + * + * @return {this} This Game Object instance. */ - set: function (value) + setPadding: function (padding) { - if (this.entries.indexOf(value) === -1) - { - this.entries.push(value); - } + if (padding === undefined) { padding = 0; } - return this; + this.padding = padding; + + return this.gameObject; }, /** - * Get an element of this Set which has a property of the specified name, if that property is equal to the specified value. - * If no elements of this Set satisfy the condition then this method will return `null`. + * This callback is invoked when this Game Object is copied by a PreFX Pipeline. * - * @method Phaser.Structs.Set#get - * @since 3.0.0 + * This happens when the pipeline uses its `copySprite` method. * - * @genericUse {T} - [value,$return] + * It's invoked prior to the copy, allowing you to set shader uniforms, etc on the pipeline. * - * @param {string} property - The property name to check on the elements of this Set. - * @param {*} value - The value to check for. + * @method Phaser.GameObjects.Components.FX#onFXCopy + * @since 3.60.0 * - * @return {*} The first element of this Set that meets the required condition, or `null` if this Set contains no elements that meet the condition. + * @param {Phaser.Renderer.WebGL.Pipelines.PreFXPipeline} pipeline - The PreFX Pipeline that invoked this callback. */ - get: function (property, value) + onFXCopy: function () { - for (var i = 0; i < this.entries.length; i++) - { - var entry = this.entries[i]; - - if (entry[property] === value) - { - return entry; - } - } }, /** - * Returns an array containing all the values in this Set. + * This callback is invoked when this Game Object is rendered by a PreFX Pipeline. * - * @method Phaser.Structs.Set#getArray - * @since 3.0.0 + * This happens when the pipeline uses its `drawSprite` method. * - * @genericUse {T[]} - [$return] + * It's invoked prior to the draw, allowing you to set shader uniforms, etc on the pipeline. * - * @return {Array.<*>} An array containing all the values in this Set. + * @method Phaser.GameObjects.Components.FX#onFX + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.Pipelines.PreFXPipeline} pipeline - The PreFX Pipeline that invoked this callback. */ - getArray: function () + onFX: function () { - return this.entries.slice(0); }, /** - * Removes the given value from this Set if this Set contains that value. + * Enables this FX Component and applies the FXPipeline to the parent Game Object. * - * @method Phaser.Structs.Set#delete - * @since 3.0.0 + * This is called automatically whenever you call a method such as `addBloom`, etc. * - * @genericUse {T} - [value] - * @genericUse {Phaser.Structs.Set.} - [$return] + * You can check the `enabled` property to see if the Game Object is already enabled, or not. * - * @param {*} value - The value to remove from the Set. + * This only applies to Pre FX. Post FX are always enabled. * - * @return {Phaser.Structs.Set} This Set object. + * @method Phaser.GameObjects.Components.FX#enable + * @since 3.60.0 + * + * @param {number} [padding=0] - The amount of padding to add to this Game Object. */ - delete: function (value) + enable: function (padding) { - var index = this.entries.indexOf(value); - - if (index > -1) + if (this.isPost) { - this.entries.splice(index, 1); + return; } - return this; - }, + var renderer = this.gameObject.scene.sys.renderer; - /** - * Dumps the contents of this Set to the console via `console.group`. - * - * @method Phaser.Structs.Set#dump - * @since 3.0.0 - */ - dump: function () - { - // eslint-disable-next-line no-console - console.group('Set'); + if (renderer && renderer.pipelines) + { + this.gameObject.pipeline = renderer.pipelines.FX_PIPELINE; - for (var i = 0; i < this.entries.length; i++) + if (padding !== undefined) + { + this.padding = padding; + } + + this.enabled = true; + } + else { - var entry = this.entries[i]; - console.log(entry); + this.enabled = false; } - - // eslint-disable-next-line no-console - console.groupEnd(); }, /** - * Passes each value in this Set to the given callback. - * Use this function when you know this Set will be modified during the iteration, otherwise use `iterate`. + * Destroys and removes all FX Controllers that are part of this FX Component, + * then disables it. * - * @method Phaser.Structs.Set#each - * @since 3.0.0 + * If this is a Pre FX Component it will only remove Pre FX. + * If this is a Post FX Component it will only remove Post FX. * - * @genericUse {EachSetCallback.} - [callback] - * @genericUse {Phaser.Structs.Set.} - [$return] + * To remove both at once use the `GameObject.clearFX` method instead. * - * @param {EachSetCallback} callback - The callback to be invoked and passed each value this Set contains. - * @param {*} [callbackScope] - The scope of the callback. + * @method Phaser.GameObjects.Components.FX#clear + * @since 3.60.0 * - * @return {Phaser.Structs.Set} This Set object. + * @return {this} This Game Object instance. */ - each: function (callback, callbackScope) + clear: function () { - var i; - var temp = this.entries.slice(); - var len = temp.length; - - if (callbackScope) + if (this.isPost) { - for (i = 0; i < len; i++) - { - if (callback.call(callbackScope, temp[i], i) === false) - { - break; - } - } + this.gameObject.resetPostPipeline(true); } else { - for (i = 0; i < len; i++) + var list = this.list; + + for (var i = 0; i < list.length; i++) { - if (callback(temp[i], i) === false) - { - break; - } + list[i].destroy(); } + + this.list = []; } - return this; + this.enabled = false; + + return this.gameObject; }, /** - * Passes each value in this Set to the given callback. - * For when you absolutely know this Set won't be modified during the iteration. + * Searches for the given FX Controller within this FX Component. * - * @method Phaser.Structs.Set#iterate - * @since 3.0.0 + * If found, the controller is removed from this component and then destroyed. * - * @genericUse {EachSetCallback.} - [callback] - * @genericUse {Phaser.Structs.Set.} - [$return] + * @method Phaser.GameObjects.Components.FX#remove + * @since 3.60.0 * - * @param {EachSetCallback} callback - The callback to be invoked and passed each value this Set contains. - * @param {*} [callbackScope] - The scope of the callback. + * @generic {Phaser.FX.Controller} T + * @genericUse {T} - [fx] * - * @return {Phaser.Structs.Set} This Set object. + * @param {Phaser.FX.Controller} fx - The FX Controller to remove from this FX Component. + * + * @return {this} This Game Object instance. */ - iterate: function (callback, callbackScope) + remove: function (fx) { var i; - var len = this.entries.length; - if (callbackScope) + if (this.isPost) { - for (i = 0; i < len; i++) + var pipelines = this.gameObject.getPostPipeline(String(fx.type)); + + if (!Array.isArray(pipelines)) { - if (callback.call(callbackScope, this.entries[i], i) === false) + pipelines = [ pipelines ]; + } + + for (i = 0; i < pipelines.length; i++) + { + var pipeline = pipelines[i]; + + if (pipeline.controller === fx) { + this.gameObject.removePostPipeline(pipeline); + + fx.destroy(); + break; } } } else { - for (i = 0; i < len; i++) + var list = this.list; + + for (i = 0; i < list.length; i++) { - if (callback(this.entries[i], i) === false) + if (list[i] === fx) { - break; + SpliceOne(list, i); + + fx.destroy(); } } } - return this; + return this.gameObject; }, /** - * Goes through each entry in this Set and invokes the given function on them, passing in the arguments. + * Disables this FX Component. * - * @method Phaser.Structs.Set#iterateLocal - * @since 3.0.0 + * This will reset the pipeline on the Game Object that owns this component back to its + * default and flag this component as disabled. * - * @genericUse {Phaser.Structs.Set.} - [$return] + * You can re-enable it again by calling `enable` for Pre FX or by adding an FX for Post FX. * - * @param {string} callbackKey - The key of the function to be invoked on each Set entry. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + * Optionally, set `clear` to destroy all current FX Controllers. * - * @return {Phaser.Structs.Set} This Set object. + * @method Phaser.GameObjects.Components.FX#disable + * @since 3.60.0 + * + * @param {boolean} [clear=false] - Destroy and remove all FX Controllers that are part of this component. + * + * @return {this} This Game Object instance. */ - iterateLocal: function (callbackKey) + disable: function (clear) { - var i; - var args = []; + if (clear === undefined) { clear = false; } - for (i = 1; i < arguments.length; i++) + if (!this.isPost) { - args.push(arguments[i]); + this.gameObject.resetPipeline(); } - var len = this.entries.length; + this.enabled = false; - for (i = 0; i < len; i++) + if (clear) { - var entry = this.entries[i]; - - entry[callbackKey].apply(entry, args); + this.clear(); } - return this; + return this.gameObject; }, /** - * Clears this Set so that it no longer contains any values. + * Adds the given FX Controler to this FX Component. * - * @method Phaser.Structs.Set#clear - * @since 3.0.0 + * Note that adding an FX Controller does not remove any existing FX. They all stack-up + * on-top of each other. If you don't want this, make sure to call either `remove` or + * `clear` first. * - * @genericUse {Phaser.Structs.Set.} - [$return] + * @method Phaser.GameObjects.Components.FX#add + * @since 3.60.0 * - * @return {Phaser.Structs.Set} This Set object. + * @generic {Phaser.FX.Controller} T + * @genericUse {T} - [fx] + * + * @param {Phaser.FX.Controller} fx - The FX Controller to add to this FX Component. + * @param {object} [config] - Optional configuration object that is passed to the pipeline during instantiation. + * + * @return {Phaser.FX.Controller} The FX Controller. */ - clear: function () + add: function (fx, config) { - this.entries.length = 0; + if (this.isPost) + { + var type = String(fx.type); - return this; + this.gameObject.setPostPipeline(type, config); + + var pipeline = this.gameObject.getPostPipeline(type); + + if (pipeline) + { + if (Array.isArray(pipeline)) + { + pipeline = pipeline.pop(); + } + + pipeline.controller = fx; + + return fx; + } + } + else + { + if (!this.enabled) + { + this.enable(); + } + + this.list.push(fx); + + return fx; + } }, /** - * Returns `true` if this Set contains the given value, otherwise returns `false`. + * Adds a Glow effect. * - * @method Phaser.Structs.Set#contains - * @since 3.0.0 + * The glow effect is a visual technique that creates a soft, luminous halo around game objects, + * characters, or UI elements. This effect is used to emphasize importance, enhance visual appeal, + * or convey a sense of energy, magic, or otherworldly presence. The effect can also be set on + * the inside of the Game Object. The color and strength of the glow can be modified. * - * @genericUse {T} - [value] + * @method Phaser.GameObjects.Components.FX#addGlow + * @since 3.60.0 * - * @param {*} value - The value to check for in this Set. + * @param {number} [color=0xffffff] - The color of the glow effect as a number value. + * @param {number} [outerStrength=4] - The strength of the glow outward from the edge of the Sprite. + * @param {number} [innerStrength=0] - The strength of the glow inward from the edge of the Sprite. + * @param {boolean} [knockout=false] - If `true` only the glow is drawn, not the texture itself. + * @param {number} [quality=0.1] - Only available for PostFX. Sets the quality of this Glow effect. Default is 0.1. Cannot be changed post-creation. + * @param {number} [distance=10] - Only available for PostFX. Sets the distance of this Glow effect. Default is 10. Cannot be changed post-creation. * - * @return {boolean} `true` if the given value was found in this Set, otherwise `false`. + * @return {Phaser.FX.Glow} The Glow FX Controller. */ - contains: function (value) + addGlow: function (color, outerStrength, innerStrength, knockout, quality, distance) { - return (this.entries.indexOf(value) > -1); + return this.add(new Effects.Glow(this.gameObject, color, outerStrength, innerStrength, knockout), { quality: quality, distance: distance }); }, /** - * Returns a new Set containing all values that are either in this Set or in the Set provided as an argument. + * Adds a Shadow effect. * - * @method Phaser.Structs.Set#union - * @since 3.0.0 + * The shadow effect is a visual technique used to create the illusion of depth and realism by adding darker, + * offset silhouettes or shapes beneath game objects, characters, or environments. These simulated shadows + * help to enhance the visual appeal and immersion, making the 2D game world appear more dynamic and three-dimensional. * - * @genericUse {Phaser.Structs.Set.} - [set,$return] + * @method Phaser.GameObjects.Components.FX#addShadow + * @since 3.60.0 * - * @param {Phaser.Structs.Set} set - The Set to perform the union with. + * @param {number} [x=0] - The horizontal offset of the shadow effect. + * @param {number} [y=0] - The vertical offset of the shadow effect. + * @param {number} [decay=0.1] - The amount of decay for shadow effect. + * @param {number} [power=1] - The power of the shadow effect. + * @param {number} [color=0x000000] - The color of the shadow. + * @param {number} [samples=6] - The number of samples that the shadow effect will run for. An integer between 1 and 12. + * @param {number} [intensity=1] - The intensity of the shadow effect. * - * @return {Phaser.Structs.Set} A new Set containing all the values in this Set and the Set provided as an argument. + * @return {Phaser.FX.Shadow} The Shadow FX Controller. */ - union: function (set) + addShadow: function (x, y, decay, power, color, samples, intensity) { - var newSet = new Set(); - - set.entries.forEach(function (value) - { - newSet.set(value); - }); - - this.entries.forEach(function (value) - { - newSet.set(value); - }); - - return newSet; + return this.add(new Effects.Shadow(this.gameObject, x, y, decay, power, color, samples, intensity)); }, /** - * Returns a new Set that contains only the values which are in this Set and that are also in the given Set. + * Adds a Pixelate effect. * - * @method Phaser.Structs.Set#intersect - * @since 3.0.0 + * The pixelate effect is a visual technique that deliberately reduces the resolution or detail of an image, + * creating a blocky or mosaic appearance composed of large, visible pixels. This effect can be used for stylistic + * purposes, as a homage to retro gaming, or as a means to obscure certain elements within the game, such as + * during a transition or to censor specific content. * - * @genericUse {Phaser.Structs.Set.} - [set,$return] + * @method Phaser.GameObjects.Components.FX#addPixelate + * @since 3.60.0 * - * @param {Phaser.Structs.Set} set - The Set to intersect this set with. + * @param {number} [amount=1] - The amount of pixelation to apply. * - * @return {Phaser.Structs.Set} The result of the intersection, as a new Set. + * @return {Phaser.FX.Pixelate} The Pixelate FX Controller. */ - intersect: function (set) + addPixelate: function (amount) { - var newSet = new Set(); - - this.entries.forEach(function (value) - { - if (set.contains(value)) - { - newSet.set(value); - } - }); - - return newSet; + return this.add(new Effects.Pixelate(this.gameObject, amount)); }, /** - * Returns a new Set containing all the values in this Set which are *not* also in the given Set. + * Adds a Vignette effect. * - * @method Phaser.Structs.Set#difference - * @since 3.0.0 + * The vignette effect is a visual technique where the edges of the screen, or a Game Object, gradually darken or blur, + * creating a frame-like appearance. This effect is used to draw the player's focus towards the central action or subject, + * enhance immersion, and provide a cinematic or artistic quality to the game's visuals. * - * @genericUse {Phaser.Structs.Set.} - [set,$return] + * @method Phaser.GameObjects.Components.FX#addVignette + * @since 3.60.0 * - * @param {Phaser.Structs.Set} set - The Set to perform the difference with. + * @param {number} [x=0.5] - The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1. + * @param {number} [y=0.5] - The vertical offset of the vignette effect. This value is normalized to the range 0 to 1. + * @param {number} [radius=0.5] - The radius of the vignette effect. This value is normalized to the range 0 to 1. + * @param {number} [strength=0.5] - The strength of the vignette effect. * - * @return {Phaser.Structs.Set} A new Set containing all the values in this Set that are not also in the Set provided as an argument to this method. + * @return {Phaser.FX.Vignette} The Vignette FX Controller. */ - difference: function (set) + addVignette: function (x, y, radius, strength) { - var newSet = new Set(); - - this.entries.forEach(function (value) - { - if (!set.contains(value)) - { - newSet.set(value); - } - }); - - return newSet; + return this.add(new Effects.Vignette(this.gameObject, x, y, radius, strength)); }, /** - * The size of this Set. This is the number of entries within it. - * Changing the size will truncate the Set if the given value is smaller than the current size. - * Increasing the size larger than the current size has no effect. + * Adds a Shine effect. * - * @name Phaser.Structs.Set#size - * @type {number} - * @since 3.0.0 + * The shine effect is a visual technique that simulates the appearance of reflective + * or glossy surfaces by passing a light beam across a Game Object. This effect is used to + * enhance visual appeal, emphasize certain features, and create a sense of depth or + * material properties. + * + * @method Phaser.GameObjects.Components.FX#addShine + * @since 3.60.0 + * + * @param {number} [speed=0.5] - The speed of the Shine effect. + * @param {number} [lineWidth=0.5] - The line width of the Shine effect. + * @param {number} [gradient=3] - The gradient of the Shine effect. + * @param {boolean} [reveal=false] - Does this Shine effect reveal or get added to its target? + * + * @return {Phaser.FX.Shine} The Shine FX Controller. */ - size: { + addShine: function (speed, lineWidth, gradient, reveal) + { + return this.add(new Effects.Shine(this.gameObject, speed, lineWidth, gradient, reveal)); + }, - get: function () - { - return this.entries.length; - }, + /** + * Adds a Blur effect. + * + * A Gaussian blur is the result of blurring an image by a Gaussian function. It is a widely used effect, + * typically to reduce image noise and reduce detail. The visual effect of this blurring technique is a + * smooth blur resembling that of viewing the image through a translucent screen, distinctly different + * from the bokeh effect produced by an out-of-focus lens or the shadow of an object under usual illumination. + * + * @method Phaser.GameObjects.Components.FX#addBlur + * @since 3.60.0 + * + * @param {number} [quality=0] - The quality of the blur effect. Can be either 0 for Low Quality, 1 for Medium Quality or 2 for High Quality. + * @param {number} [x=2] - The horizontal offset of the blur effect. + * @param {number} [y=2] - The vertical offset of the blur effect. + * @param {number} [strength=1] - The strength of the blur effect. + * @param {number} [color=0xffffff] - The color of the blur, as a hex value. + * @param {number} [steps=4] - The number of steps to run the blur effect for. This value should always be an integer. + * + * @return {Phaser.FX.Blur} The Blur FX Controller. + */ + addBlur: function (quality, x, y, strength, color, steps) + { + return this.add(new Effects.Blur(this.gameObject, quality, x, y, strength, color, steps)); + }, - set: function (value) - { - if (value < this.entries.length) - { - return this.entries.length = value; - } - else - { - return this.entries.length; - } - } + /** + * Adds a Gradient effect. + * + * The gradient overlay effect is a visual technique where a smooth color transition is applied over Game Objects, + * such as sprites or UI components. This effect is used to enhance visual appeal, emphasize depth, or create + * stylistic and atmospheric variations. It can also be utilized to convey information, such as representing + * progress or health status through color changes. + * + * @method Phaser.GameObjects.Components.FX#addGradient + * @since 3.60.0 + * + * @param {number} [color1=0xff0000] - The first gradient color, given as a number value. + * @param {number} [color2=0x00ff00] - The second gradient color, given as a number value. + * @param {number} [alpha=0.2] - The alpha value of the gradient effect. + * @param {number} [fromX=0] - The horizontal position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + * @param {number} [fromY=0] - The vertical position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + * @param {number} [toX=0] - The horizontal position the gradient will end at. This value is noralized, between 0 and 1 and is not in pixels. + * @param {number} [toY=1] - The vertical position the gradient will end at. This value is noralized, between 0 and 1 and is not in pixels. + * @param {number} [size=0] - How many 'chunks' the gradient is divided in to, as spread over the entire height of the texture. Leave this at zero for a smooth gradient, or set higher for a more retro chunky effect. + * + * @return {Phaser.FX.Gradient} The Gradient FX Controller. + */ + addGradient: function (color1, color2, alpha, fromX, fromY, toX, toY, size) + { + return this.add(new Effects.Gradient(this.gameObject, color1, color2, alpha, fromX, fromY, toX, toY, size)); + }, + + /** + * Adds a Bloom effect. + * + * Bloom is an effect used to reproduce an imaging artifact of real-world cameras. + * The effect produces fringes of light extending from the borders of bright areas in an image, + * contributing to the illusion of an extremely bright light overwhelming the + * camera or eye capturing the scene. + * + * @method Phaser.GameObjects.Components.FX#addBloom + * @since 3.60.0 + * + * @param {number} [color] - The color of the Bloom, as a hex value. + * @param {number} [offsetX=1] - The horizontal offset of the bloom effect. + * @param {number} [offsetY=1] - The vertical offset of the bloom effect. + * @param {number} [blurStrength=1] - The strength of the blur process of the bloom effect. + * @param {number} [strength=1] - The strength of the blend process of the bloom effect. + * @param {number} [steps=4] - The number of steps to run the Bloom effect for. This value should always be an integer. + * + * @return {Phaser.FX.Bloom} The Bloom FX Controller. + */ + addBloom: function (color, offsetX, offsetY, blurStrength, strength, steps) + { + return this.add(new Effects.Bloom(this.gameObject, color, offsetX, offsetY, blurStrength, strength, steps)); + }, + + /** + * Adds a ColorMatrix effect. + * + * The color matrix effect is a visual technique that involves manipulating the colors of an image + * or scene using a mathematical matrix. This process can adjust hue, saturation, brightness, and contrast, + * allowing developers to create various stylistic appearances or mood settings within the game. + * Common applications include simulating different lighting conditions, applying color filters, + * or achieving a specific visual style. + * + * @method Phaser.GameObjects.Components.FX#addColorMatrix + * @since 3.60.0 + * + * @return {Phaser.FX.ColorMatrix} The ColorMatrix FX Controller. + */ + addColorMatrix: function () + { + return this.add(new Effects.ColorMatrix(this.gameObject)); + }, + + /** + * Adds a Circle effect. + * + * This effect will draw a circle around the texture of the Game Object, effectively masking off + * any area outside of the circle without the need for an actual mask. You can control the thickness + * of the circle, the color of the circle and the color of the background, should the texture be + * transparent. You can also control the feathering applied to the circle, allowing for a harsh or soft edge. + * + * Please note that adding this effect to a Game Object will not change the input area or physics body of + * the Game Object, should it have one. + * + * @method Phaser.GameObjects.Components.FX#addCircle + * @since 3.60.0 + * + * @param {number} [thickness=8] - The width of the circle around the texture, in pixels. + * @param {number} [color=0xfeedb6] - The color of the circular ring, given as a number value. + * @param {number} [backgroundColor=0xff0000] - The color of the background, behind the texture, given as a number value. + * @param {number} [scale=1] - The scale of the circle. The default scale is 1, which is a circle the full size of the underlying texture. + * @param {number} [feather=0.005] - The amount of feathering to apply to the circle from the ring. + * + * @return {Phaser.FX.Circle} The Circle FX Controller. + */ + addCircle: function (thickness, color, backgroundColor, scale, feather) + { + return this.add(new Effects.Circle(this.gameObject, thickness, color, backgroundColor, scale, feather)); + }, + + /** + * Adds a Barrel effect. + * + * A barrel effect allows you to apply either a 'pinch' or 'expand' distortion to + * a Game Object. The amount of the effect can be modified in real-time. + * + * @method Phaser.GameObjects.Components.FX#addBarrel + * @since 3.60.0 + * + * @param {number} [amount=1] - The amount of distortion applied to the barrel effect. A value of 1 is no distortion. Typically keep this within +- 1. + * + * @return {Phaser.FX.Barrel} The Barrel FX Controller. + */ + addBarrel: function (amount) + { + return this.add(new Effects.Barrel(this.gameObject, amount)); + }, + + /** + * Adds a Displacement effect. + * + * The displacement effect is a visual technique that alters the position of pixels in an image + * or texture based on the values of a displacement map. This effect is used to create the illusion + * of depth, surface irregularities, or distortion in otherwise flat elements. It can be applied to + * characters, objects, or backgrounds to enhance realism, convey movement, or achieve various + * stylistic appearances. + * + * @method Phaser.GameObjects.Components.FX#addDisplacement + * @since 3.60.0 + * + * @param {string} [texture='__WHITE'] - The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager. + * @param {number} [x=0.005] - The amount of horizontal displacement to apply. A very small float number, such as 0.005. + * @param {number} [y=0.005] - The amount of vertical displacement to apply. A very small float number, such as 0.005. + * + * @return {Phaser.FX.Displacement} The Displacement FX Controller. + */ + addDisplacement: function (texture, x, y) + { + return this.add(new Effects.Displacement(this.gameObject, texture, x, y)); + }, + + /** + * Adds a Wipe effect. + * + * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements + * in the game, such as images, text, or scene transitions. This effect is often used to create + * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition + * between game states. + * + * You can set both the direction and the axis of the wipe effect. The following combinations are possible: + * + * * left to right: direction 0, axis 0 + * * right to left: direction 1, axis 0 + * * top to bottom: direction 1, axis 1 + * * bottom to top: direction 1, axis 0 + * + * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect. + * + * @method Phaser.GameObjects.Components.FX#addWipe + * @since 3.60.0 + * + * @param {number} [wipeWidth=0.1] - The width of the wipe effect. This value is normalized in the range 0 to 1. + * @param {number} [direction=0] - The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. + * @param {number} [axis=0] - The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. + * + * @return {Phaser.FX.Wipe} The Wipe FX Controller. + */ + addWipe: function (wipeWidth, direction, axis) + { + return this.add(new Effects.Wipe(this.gameObject, wipeWidth, direction, axis)); + }, + + /** + * Adds a Reveal Wipe effect. + * + * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements + * in the game, such as images, text, or scene transitions. This effect is often used to create + * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition + * between game states. + * + * You can set both the direction and the axis of the wipe effect. The following combinations are possible: + * + * * left to right: direction 0, axis 0 + * * right to left: direction 1, axis 0 + * * top to bottom: direction 1, axis 1 + * * bottom to top: direction 1, axis 0 + * + * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect. + * + * @method Phaser.GameObjects.Components.FX#addReveal + * @since 3.60.0 + * + * @param {number} [wipeWidth=0.1] - The width of the wipe effect. This value is normalized in the range 0 to 1. + * @param {number} [direction=0] - The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. + * @param {number} [axis=0] - The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. + * + * @return {Phaser.FX.Wipe} The Wipe FX Controller. + */ + addReveal: function (wipeWidth, direction, axis) + { + return this.add(new Effects.Wipe(this.gameObject, wipeWidth, direction, axis, true)); + }, + /** + * Adds a Bokeh effect. + * + * Bokeh refers to a visual effect that mimics the photographic technique of creating a shallow depth of field. + * This effect is used to emphasize the game's main subject or action, by blurring the background or foreground + * elements, resulting in a more immersive and visually appealing experience. It is achieved through rendering + * techniques that simulate the out-of-focus areas, giving a sense of depth and realism to the game's graphics. + * + * See also Tilt Shift. + * + * @method Phaser.GameObjects.Components.FX#addBokeh + * @since 3.60.0 + * + * @param {number} [radius=0.5] - The radius of the bokeh effect. + * @param {number} [amount=1] - The amount of the bokeh effect. + * @param {number} [contrast=0.2] - The color contrast of the bokeh effect. + * + * @return {Phaser.FX.Bokeh} The Bokeh FX Controller. + */ + addBokeh: function (radius, amount, contrast) + { + return this.add(new Effects.Bokeh(this.gameObject, radius, amount, contrast)); + }, + + /** + * Adds a Tilt Shift effect. + * + * This Bokeh effect can also be used to generate a Tilt Shift effect, which is a technique used to create a miniature + * effect by blurring everything except a small area of the image. This effect is achieved by blurring the + * top and bottom elements, while keeping the center area in focus. + * + * See also Bokeh. + * + * @method Phaser.GameObjects.Components.FX#addTiltShift + * @since 3.60.0 + * + * @param {number} [radius=0.5] - The radius of the bokeh effect. + * @param {number} [amount=1] - The amount of the bokeh effect. + * @param {number} [contrast=0.2] - The color contrast of the bokeh effect. + * @param {number} [blurX=1] - The amount of horizontal blur. + * @param {number} [blurY=1] - The amount of vertical blur. + * @param {number} [strength=1] - The strength of the blur. + * + * @return {Phaser.FX.Bokeh} The Bokeh TiltShift FX Controller. + */ + addTiltShift: function (radius, amount, contrast, blurX, blurY, strength) + { + return this.add(new Effects.Bokeh(this.gameObject, radius, amount, contrast, true, blurX, blurY, strength)); + }, + + /** + * Destroys this FX Component. + * + * Called automatically when Game Objects are destroyed. + * + * @method Phaser.GameObjects.Components.FX#destroy + * @since 3.60.0 + */ + destroy: function () + { + this.clear(); + + this.gameObject = null; } }); -module.exports = Set; +module.exports = FX; /***/ }), -/* 150 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 92972: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 IntegerToColor = __webpack_require__(189); -var PIPELINES_CONST = __webpack_require__(92); -var Render = __webpack_require__(1182); - /** - * @classdesc - * The Point Light Game Object provides a way to add a point light effect into your game, - * without the expensive shader processing requirements of the traditional Light Game Object. - * - * The difference is that the Point Light renders using a custom shader, designed to give the - * impression of a point light source, of variable radius, intensity and color, in your game. - * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their - * normal maps for calcuations. This makes them extremely fast to render compared to Lights - * and perfect for special effects, such as flickering torches or muzzle flashes. - * - * For maximum performance you should batch Point Light Game Objects together. This means - * ensuring they follow each other consecutively on the display list. Ideally, use a Layer - * Game Object and then add just Point Lights to it, so that it can batch together the rendering - * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in - * your game then it's perfectly safe to mix them into the dislay list as normal. However, if - * you're using a large number of them, please consider how they are mixed into the display list. - * - * The renderer will automatically cull Point Lights. Those with a radius that does not intersect - * with the Camera will be skipped in the rendering list. This happens automatically and the - * culled state is refreshed every frame, for every camera. - * - * The origin of a Point Light is always 0.5 and it cannot be changed. - * - * Point Lights are a WebGL only feature and do not have a Canvas counterpart. - * - * @class PointLight - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.50.0 - * - * @extends Phaser.GameObjects.Components.AlphaSingle - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.Visible + * Provides methods used for visually flipping a Game Object. + * Should be applied as a mixin and not used directly. * - * @param {Phaser.Scene} scene - The Scene to which this Point Light belongs. A Point Light can only belong to one Scene at a time. - * @param {number} x - The horizontal position of this Point Light in the world. - * @param {number} y - The vertical position of this Point Light in the world. - * @param {number} [color=0xffffff] - The color of the Point Light, given as a hex value. - * @param {number} [radius=128] - The radius of the Point Light. - * @param {number} [intensity=1] - The intensity, or colr blend, of the Point Light. - * @param {number} [attenuation=0.1] - The attenuation of the Point Light. This is the reduction of light from the center point. + * @namespace Phaser.GameObjects.Components.Flip + * @since 3.0.0 */ -var PointLight = new Class({ - Extends: GameObject, +var Flip = { - Mixins: [ - Components.AlphaSingle, - Components.BlendMode, - Components.Depth, - Components.GetBounds, - Components.Mask, - Components.Pipeline, - Components.ScrollFactor, - Components.Transform, - Components.Visible, - Render - ], + /** + * The horizontally flipped state of the Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * + * @name Phaser.GameObjects.Components.Flip#flipX + * @type {boolean} + * @default false + * @since 3.0.0 + */ + flipX: false, - initialize: + /** + * The vertically flipped state of the Game Object. + * + * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * + * @name Phaser.GameObjects.Components.Flip#flipY + * @type {boolean} + * @default false + * @since 3.0.0 + */ + flipY: false, - function PointLight (scene, x, y, color, radius, intensity, attenuation) + /** + * Toggles the horizontal flipped state of this Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * + * @method Phaser.GameObjects.Components.Flip#toggleFlipX + * @since 3.0.0 + * + * @return {this} This Game Object instance. + */ + toggleFlipX: function () { - if (color === undefined) { color = 0xffffff; } - if (radius === undefined) { radius = 128; } - if (intensity === undefined) { intensity = 1; } - if (attenuation === undefined) { attenuation = 0.1; } - - GameObject.call(this, scene, 'PointLight'); - - this.initPipeline(PIPELINES_CONST.POINTLIGHT_PIPELINE); - - this.setPosition(x, y); - - /** - * The color of this Point Light. This property is an instance of a - * Color object, so you can use the methods within it, such as `setTo(r, g, b)` - * to change the color value. - * - * @name Phaser.GameObjects.PointLight#color - * @type {Phaser.Display.Color} - * @since 3.50.0 - */ - this.color = IntegerToColor(color); - - /** - * The intensity of the Point Light. - * - * The colors of the light are multiplied by this value during rendering. - * - * @name Phaser.GameObjects.PointLight#intensity - * @type {number} - * @since 3.50.0 - */ - this.intensity = intensity; - - /** - * The attenuation of the Point Light. - * - * This value controls the force with which the light falls-off from the center of the light. - * - * Use small float-based values, i.e. 0.1. - * - * @name Phaser.GameObjects.PointLight#attenuation - * @type {number} - * @since 3.50.0 - */ - this.attenuation = attenuation; - - // read only: - this.width = radius * 2; - this.height = radius * 2; + this.flipX = !this.flipX; - this._radius = radius; + return this; }, /** - * The radius of the Point Light. + * Toggles the vertical flipped state of this Game Object. * - * @name Phaser.GameObjects.PointLight#radius - * @type {number} - * @since 3.50.0 + * @method Phaser.GameObjects.Components.Flip#toggleFlipY + * @since 3.0.0 + * + * @return {this} This Game Object instance. */ - radius: { - - get: function () - { - return this._radius; - }, - - set: function (value) - { - this._radius = value; - this.width = value * 2; - this.height = value * 2; - } + toggleFlipY: function () + { + this.flipY = !this.flipY; + return this; }, - originX: { - - get: function () - { - return 0.5; - } + /** + * Sets the horizontal flipped state of this Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * + * @method Phaser.GameObjects.Components.Flip#setFlipX + * @since 3.0.0 + * + * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. + * + * @return {this} This Game Object instance. + */ + setFlipX: function (value) + { + this.flipX = value; + return this; }, - originY: { - - get: function () - { - return 0.5; - } + /** + * Sets the vertical flipped state of this Game Object. + * + * @method Phaser.GameObjects.Components.Flip#setFlipY + * @since 3.0.0 + * + * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. + * + * @return {this} This Game Object instance. + */ + setFlipY: function (value) + { + this.flipY = value; + return this; }, - displayOriginX: { - - get: function () - { - return this._radius; - } + /** + * Sets the horizontal and vertical flipped state of this Game Object. + * + * A Game Object that is flipped will render inversed on the flipped axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * + * @method Phaser.GameObjects.Components.Flip#setFlip + * @since 3.0.0 + * + * @param {boolean} x - The horizontal flipped state. `false` for no flip, or `true` to be flipped. + * @param {boolean} y - The horizontal flipped state. `false` for no flip, or `true` to be flipped. + * + * @return {this} This Game Object instance. + */ + setFlip: function (x, y) + { + this.flipX = x; + this.flipY = y; + return this; }, - displayOriginY: { - - get: function () - { - return this._radius; - } + /** + * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. + * + * @method Phaser.GameObjects.Components.Flip#resetFlip + * @since 3.0.0 + * + * @return {this} This Game Object instance. + */ + resetFlip: function () + { + this.flipX = false; + this.flipY = false; + return this; } -}); +}; -module.exports = PointLight; +module.exports = Flip; /***/ }), -/* 151 */ -/***/ (function(module, exports) { + +/***/ 80693: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Rectangle = __webpack_require__(74118); +var RotateAround = __webpack_require__(2386); +var Vector2 = __webpack_require__(93736); + /** - * Checks for intersection between a circle and a rectangle. + * Provides methods used for obtaining the bounds of a Game Object. + * Should be applied as a mixin and not used directly. * - * @function Phaser.Geom.Intersects.CircleToRectangle + * @namespace Phaser.GameObjects.Components.GetBounds * @since 3.0.0 - * - * @param {Phaser.Geom.Circle} circle - The circle to be checked. - * @param {Phaser.Geom.Rectangle} rect - The rectangle to be checked. - * - * @return {boolean} `true` if the two objects intersect, otherwise `false`. */ -var CircleToRectangle = function (circle, rect) -{ - var halfWidth = rect.width / 2; - var halfHeight = rect.height / 2; - var cx = Math.abs(circle.x - rect.x - halfWidth); - var cy = Math.abs(circle.y - rect.y - halfHeight); - var xDist = halfWidth + circle.radius; - var yDist = halfHeight + circle.radius; +var GetBounds = { - if (cx > xDist || cy > yDist) + /** + * Processes the bounds output vector before returning it. + * + * @method Phaser.GameObjects.Components.GetBounds#prepareBoundsOutput + * @private + * @since 3.18.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} output - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + prepareBoundsOutput: function (output, includeParent) { - return false; - } - else if (cx <= halfWidth || cy <= halfHeight) + if (includeParent === undefined) { includeParent = false; } + + if (this.rotation !== 0) + { + RotateAround(output, this.x, this.y, this.rotation); + } + + if (includeParent && this.parentContainer) + { + var parentMatrix = this.parentContainer.getBoundsTransformMatrix(); + + parentMatrix.transformPoint(output.x, output.y, output); + } + + return output; + }, + + /** + * Gets the center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * + * @method Phaser.GameObjects.Components.GetBounds#getCenter + * @since 3.0.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + getCenter: function (output, includeParent) { - return true; - } - else + if (output === undefined) { output = new Vector2(); } + + output.x = this.x - (this.displayWidth * this.originX) + (this.displayWidth / 2); + output.y = this.y - (this.displayHeight * this.originY) + (this.displayHeight / 2); + + return this.prepareBoundsOutput(output, includeParent); + }, + + /** + * Gets the top-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * + * @method Phaser.GameObjects.Components.GetBounds#getTopLeft + * @since 3.0.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + getTopLeft: function (output, includeParent) { - var xCornerDist = cx - halfWidth; - var yCornerDist = cy - halfHeight; - var xCornerDistSq = xCornerDist * xCornerDist; - var yCornerDistSq = yCornerDist * yCornerDist; - var maxCornerDistSq = circle.radius * circle.radius; + if (!output) { output = new Vector2(); } - return (xCornerDistSq + yCornerDistSq <= maxCornerDistSq); - } -}; + output.x = this.x - (this.displayWidth * this.originX); + output.y = this.y - (this.displayHeight * this.originY); -module.exports = CircleToRectangle; + return this.prepareBoundsOutput(output, includeParent); + }, + + /** + * Gets the top-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * + * @method Phaser.GameObjects.Components.GetBounds#getTopCenter + * @since 3.18.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + getTopCenter: function (output, includeParent) + { + if (!output) { output = new Vector2(); } + output.x = (this.x - (this.displayWidth * this.originX)) + (this.displayWidth / 2); + output.y = this.y - (this.displayHeight * this.originY); -/***/ }), -/* 152 */ -/***/ (function(module, exports) { + return this.prepareBoundsOutput(output, includeParent); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Gets the top-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * + * @method Phaser.GameObjects.Components.GetBounds#getTopRight + * @since 3.0.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + getTopRight: function (output, includeParent) + { + if (!output) { output = new Vector2(); } -/** - * Checks if two Rectangles intersect. - * - * A Rectangle intersects another Rectangle if any part of its bounds is within the other Rectangle's bounds. - * As such, the two Rectangles are considered "solid". - * A Rectangle with no width or no height will never intersect another Rectangle. - * - * @function Phaser.Geom.Intersects.RectangleToRectangle - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to check for intersection. - * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to check for intersection. - * - * @return {boolean} `true` if the two Rectangles intersect, otherwise `false`. - */ -var RectangleToRectangle = function (rectA, rectB) -{ - if (rectA.width <= 0 || rectA.height <= 0 || rectB.width <= 0 || rectB.height <= 0) + output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth; + output.y = this.y - (this.displayHeight * this.originY); + + return this.prepareBoundsOutput(output, includeParent); + }, + + /** + * Gets the left-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * + * @method Phaser.GameObjects.Components.GetBounds#getLeftCenter + * @since 3.18.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + getLeftCenter: function (output, includeParent) { - return false; - } + if (!output) { output = new Vector2(); } - return !(rectA.right < rectB.x || rectA.bottom < rectB.y || rectA.x > rectB.right || rectA.y > rectB.bottom); -}; + output.x = this.x - (this.displayWidth * this.originX); + output.y = (this.y - (this.displayHeight * this.originY)) + (this.displayHeight / 2); -module.exports = RectangleToRectangle; + return this.prepareBoundsOutput(output, includeParent); + }, + /** + * Gets the right-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * + * @method Phaser.GameObjects.Components.GetBounds#getRightCenter + * @since 3.18.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + getRightCenter: function (output, includeParent) + { + if (!output) { output = new Vector2(); } -/***/ }), -/* 153 */ -/***/ (function(module, exports, __webpack_require__) { + output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth; + output.y = (this.y - (this.displayHeight * this.originY)) + (this.displayHeight / 2); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this.prepareBoundsOutput(output, includeParent); + }, -var GetValue = __webpack_require__(6); + /** + * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * + * @method Phaser.GameObjects.Components.GetBounds#getBottomLeft + * @since 3.0.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + getBottomLeft: function (output, includeParent) + { + if (!output) { output = new Vector2(); } -// Contains the plugins that Phaser uses globally and locally. -// These are the source objects, not instantiated. -var inputPlugins = {}; + output.x = this.x - (this.displayWidth * this.originX); + output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight; -/** - * @namespace Phaser.Input.InputPluginCache - */ + return this.prepareBoundsOutput(output, includeParent); + }, -var InputPluginCache = {}; + /** + * Gets the bottom-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * + * @method Phaser.GameObjects.Components.GetBounds#getBottomCenter + * @since 3.18.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + getBottomCenter: function (output, includeParent) + { + if (!output) { output = new Vector2(); } -/** - * Static method called directly by the Core internal Plugins. - * Key is a reference used to get the plugin from the plugins object (i.e. InputPlugin) - * Plugin is the object to instantiate to create the plugin - * Mapping is what the plugin is injected into the Scene.Systems as (i.e. input) - * - * @function Phaser.Input.InputPluginCache.register - * @static - * @since 3.10.0 - * - * @param {string} key - A reference used to get this plugin from the plugin cache. - * @param {function} plugin - The plugin to be stored. Should be the core object, not instantiated. - * @param {string} mapping - If this plugin is to be injected into the Input Plugin, this is the property key used. - * @param {string} settingsKey - The key in the Scene Settings to check to see if this plugin should install or not. - * @param {string} configKey - The key in the Game Config to check to see if this plugin should install or not. - */ -InputPluginCache.register = function (key, plugin, mapping, settingsKey, configKey) -{ - inputPlugins[key] = { plugin: plugin, mapping: mapping, settingsKey: settingsKey, configKey: configKey }; -}; + output.x = (this.x - (this.displayWidth * this.originX)) + (this.displayWidth / 2); + output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight; -/** - * Returns the input plugin object from the cache based on the given key. - * - * @function Phaser.Input.InputPluginCache.getPlugin - * @static - * @since 3.10.0 - * - * @param {string} key - The key of the input plugin to get. - * - * @return {Phaser.Types.Input.InputPluginContainer} The input plugin object. - */ -InputPluginCache.getPlugin = function (key) -{ - return inputPlugins[key]; -}; + return this.prepareBoundsOutput(output, includeParent); + }, -/** - * Installs all of the registered Input Plugins into the given target. - * - * @function Phaser.Input.InputPluginCache.install - * @static - * @since 3.10.0 - * - * @param {Phaser.Input.InputPlugin} target - The target InputPlugin to install the plugins into. - */ -InputPluginCache.install = function (target) -{ - var sys = target.scene.sys; - var settings = sys.settings.input; - var config = sys.game.config; + /** + * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * + * @method Phaser.GameObjects.Components.GetBounds#getBottomRight + * @since 3.0.0 + * + * @generic {Phaser.Types.Math.Vector2Like} O - [output,$return] + * + * @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created. + * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? + * + * @return {Phaser.Types.Math.Vector2Like} The values stored in the output object. + */ + getBottomRight: function (output, includeParent) + { + if (!output) { output = new Vector2(); } - for (var key in inputPlugins) + output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth; + output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight; + + return this.prepareBoundsOutput(output, includeParent); + }, + + /** + * Gets the bounds of this Game Object, regardless of origin. + * + * The values are stored and returned in a Rectangle, or Rectangle-like, object. + * + * @method Phaser.GameObjects.Components.GetBounds#getBounds + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [output,$return] + * + * @param {(Phaser.Geom.Rectangle|object)} [output] - An object to store the values in. If not provided a new Rectangle will be created. + * + * @return {(Phaser.Geom.Rectangle|object)} The values stored in the output object. + */ + getBounds: function (output) { - var source = inputPlugins[key].plugin; - var mapping = inputPlugins[key].mapping; - var settingsKey = inputPlugins[key].settingsKey; - var configKey = inputPlugins[key].configKey; + if (output === undefined) { output = new Rectangle(); } - if (GetValue(settings, settingsKey, config[configKey])) + // We can use the output object to temporarily store the x/y coords in: + + var TLx, TLy, TRx, TRy, BLx, BLy, BRx, BRy; + + // Instead of doing a check if parent container is + // defined per corner we only do it once. + if (this.parentContainer) { - target[mapping] = new source(target); - } - } -}; + var parentMatrix = this.parentContainer.getBoundsTransformMatrix(); -/** - * Removes an input plugin based on the given key. - * - * @function Phaser.Input.InputPluginCache.remove - * @static - * @since 3.10.0 - * - * @param {string} key - The key of the input plugin to remove. - */ -InputPluginCache.remove = function (key) -{ - if (inputPlugins.hasOwnProperty(key)) - { - delete inputPlugins[key]; - } -}; + this.getTopLeft(output); + parentMatrix.transformPoint(output.x, output.y, output); -module.exports = InputPluginCache; + TLx = output.x; + TLy = output.y; + this.getTopRight(output); + parentMatrix.transformPoint(output.x, output.y, output); -/***/ }), -/* 154 */ -/***/ (function(module, exports, __webpack_require__) { + TRx = output.x; + TRy = output.y; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.getBottomLeft(output); + parentMatrix.transformPoint(output.x, output.y, output); -/** - * @namespace Phaser.Input.Keyboard.Events - */ + BLx = output.x; + BLy = output.y; -module.exports = { + this.getBottomRight(output); + parentMatrix.transformPoint(output.x, output.y, output); - ANY_KEY_DOWN: __webpack_require__(1323), - ANY_KEY_UP: __webpack_require__(1324), - COMBO_MATCH: __webpack_require__(1325), - DOWN: __webpack_require__(1326), - KEY_DOWN: __webpack_require__(1327), - KEY_UP: __webpack_require__(1328), - UP: __webpack_require__(1329) + BRx = output.x; + BRy = output.y; + } + else + { + this.getTopLeft(output); -}; + TLx = output.x; + TLy = output.y; + this.getTopRight(output); -/***/ }), -/* 155 */ -/***/ (function(module, exports) { + TRx = output.x; + TRy = output.y; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.getBottomLeft(output); -/** - * Given a File and a baseURL value this returns the URL the File will use to download from. - * - * @function Phaser.Loader.GetURL - * @since 3.0.0 - * - * @param {Phaser.Loader.File} file - The File object. - * @param {string} baseURL - A default base URL. - * - * @return {string} The URL the File will use. - */ -var GetURL = function (file, baseURL) -{ - if (!file.url) - { - return false; - } + BLx = output.x; + BLy = output.y; - if (file.url.match(/^(?:blob:|data:|http:\/\/|https:\/\/|\/\/)/)) - { - return file.url; - } - else - { - return baseURL + file.url; + this.getBottomRight(output); + + BRx = output.x; + BRy = output.y; + } + + output.x = Math.min(TLx, TRx, BLx, BRx); + output.y = Math.min(TLy, TRy, BLy, BRy); + output.width = Math.max(TLx, TRx, BLx, BRx) - output.x; + output.height = Math.max(TLy, TRy, BLy, BRy) - output.y; + + return output; } + }; -module.exports = GetURL; +module.exports = GetBounds; /***/ }), -/* 156 */ -/***/ (function(module, exports) { + +/***/ 39171: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var BitmapMask = __webpack_require__(76756); +var GeometryMask = __webpack_require__(63037); + /** - * Creates an XHRSettings Object with default values. + * Provides methods used for getting and setting the mask of a Game Object. * - * @function Phaser.Loader.XHRSettings + * @namespace Phaser.GameObjects.Components.Mask * @since 3.0.0 - * - * @param {XMLHttpRequestResponseType} [responseType=''] - The responseType, such as 'text'. - * @param {boolean} [async=true] - Should the XHR request use async or not? - * @param {string} [user=''] - Optional username for the XHR request. - * @param {string} [password=''] - Optional password for the XHR request. - * @param {number} [timeout=0] - Optional XHR timeout value. - * @param {boolean} [withCredentials=false] - Optional XHR withCredentials value. - * - * @return {Phaser.Types.Loader.XHRSettingsObject} The XHRSettings object as used by the Loader. */ -var XHRSettings = function (responseType, async, user, password, timeout, withCredentials) -{ - if (responseType === undefined) { responseType = ''; } - if (async === undefined) { async = true; } - if (user === undefined) { user = ''; } - if (password === undefined) { password = ''; } - if (timeout === undefined) { timeout = 0; } - if (withCredentials === undefined) { withCredentials = false; } - // Before sending a request, set the xhr.responseType to "text", - // "arraybuffer", "blob", or "document", depending on your data needs. - // Note, setting xhr.responseType = '' (or omitting) will default the response to "text". +var Mask = { - return { + /** + * The Mask this Game Object is using during render. + * + * @name Phaser.GameObjects.Components.Mask#mask + * @type {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask} + * @since 3.0.0 + */ + mask: null, - // Ignored by the Loader, only used by File. - responseType: responseType, + /** + * Sets the mask that this Game Object will use to render with. + * + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * If a mask is already set on this Game Object it will be immediately replaced. + * + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * + * @method Phaser.GameObjects.Components.Mask#setMask + * @since 3.6.2 + * + * @param {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask} mask - The mask this Game Object will use when rendering. + * + * @return {this} This Game Object instance. + */ + setMask: function (mask) + { + this.mask = mask; - async: async, + return this; + }, - // credentials - user: user, - password: password, + /** + * Clears the mask that this Game Object was using. + * + * @method Phaser.GameObjects.Components.Mask#clearMask + * @since 3.6.2 + * + * @param {boolean} [destroyMask=false] - Destroy the mask before clearing it? + * + * @return {this} This Game Object instance. + */ + clearMask: function (destroyMask) + { + if (destroyMask === undefined) { destroyMask = false; } - // timeout in ms (0 = no timeout) - timeout: timeout, + if (destroyMask && this.mask) + { + this.mask.destroy(); + } - // setRequestHeader - headers: undefined, - header: undefined, - headerValue: undefined, - requestedWith: false, + this.mask = null; - // overrideMimeType - overrideMimeType: undefined, + return this; + }, - // withCredentials - withCredentials: withCredentials + /** + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. + * + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. + * + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * + * @method Phaser.GameObjects.Components.Mask#createBitmapMask + * @since 3.6.2 + * + * @generic {Phaser.GameObjects.GameObject} G + * @generic {Phaser.Textures.DynamicTexture} T + * @genericUse {(G|T|null)} [maskObject] + * + * @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} [maskObject] - The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param {number} [x] - If creating a Game Object, the horizontal position in the world. + * @param {number} [y] - If creating a Game Object, the vertical position in the world. + * @param {(string|Phaser.Textures.Texture)} [texture] - If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param {(string|number|Phaser.Textures.Frame)} [frame] - If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.Display.Masks.BitmapMask} This Bitmap Mask that was created. + */ + createBitmapMask: function (maskObject, x, y, texture, frame) + { + if (maskObject === undefined && (this.texture || this.shader || this.geom)) + { + // eslint-disable-next-line consistent-this + maskObject = this; + } + + return new BitmapMask(this.scene, maskObject, x, y, texture, frame); + }, + + /** + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. + * + * To create the mask you need to pass in a reference to a Graphics Game Object. + * + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. + * + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * + * @method Phaser.GameObjects.Components.Mask#createGeometryMask + * @since 3.6.2 + * + * @generic {Phaser.GameObjects.Graphics} G + * @generic {Phaser.GameObjects.Shape} S + * @genericUse {(G|S)} [graphics] + * + * @param {Phaser.GameObjects.Graphics|Phaser.GameObjects.Shape} [graphics] - A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. + * + * @return {Phaser.Display.Masks.GeometryMask} This Geometry Mask that was created. + */ + createGeometryMask: function (graphics) + { + if (graphics === undefined && (this.type === 'Graphics' || this.geom)) + { + // eslint-disable-next-line consistent-this + graphics = this; + } + + return new GeometryMask(this.scene, graphics); + } - }; }; -module.exports = XHRSettings; +module.exports = Mask; /***/ }), -/* 157 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 28072: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Components = __webpack_require__(243); -var Sprite = __webpack_require__(73); - /** - * @classdesc - * An Arcade Physics Sprite is a Sprite with an Arcade Physics body and related components. - * The body can be dynamic or static. - * - * The main difference between an Arcade Sprite and an Arcade Image is that you cannot animate an Arcade Image. - * If you do not require animation then you can safely use Arcade Images instead of Arcade Sprites. + * Provides methods used for getting and setting the origin of a Game Object. + * Values are normalized, given in the range 0 to 1. + * Display values contain the calculated pixel values. + * Should be applied as a mixin and not used directly. * - * @class Sprite - * @extends Phaser.GameObjects.Sprite - * @memberof Phaser.Physics.Arcade - * @constructor + * @namespace Phaser.GameObjects.Components.Origin * @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 ArcadeSprite = new Class({ - Extends: Sprite, +var Origin = { - 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 - ], + /** + * A property indicating that a Game Object has this component. + * + * @name Phaser.GameObjects.Components.Origin#_originComponent + * @type {boolean} + * @private + * @default true + * @since 3.2.0 + */ + _originComponent: true, - initialize: + /** + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. + * + * @name Phaser.GameObjects.Components.Origin#originX + * @type {number} + * @readonly + * @default 0.5 + * @since 3.0.0 + */ + originX: 0.5, - function ArcadeSprite (scene, x, y, texture, frame) - { - Sprite.call(this, scene, x, y, texture, frame); + /** + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. + * + * @name Phaser.GameObjects.Components.Origin#originY + * @type {number} + * @readonly + * @default 0.5 + * @since 3.0.0 + */ + originY: 0.5, - /** - * This Game Object's Physics Body. - * - * @name Phaser.Physics.Arcade.Sprite#body - * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} - * @default null - * @since 3.0.0 - */ - this.body = null; - } + // private + read only + _displayOriginX: 0, + _displayOriginY: 0, -}); + /** + * The horizontal display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * + * @name Phaser.GameObjects.Components.Origin#displayOriginX + * @type {number} + * @since 3.0.0 + */ + displayOriginX: { -module.exports = ArcadeSprite; + get: function () + { + return this._displayOriginX; + }, + + set: function (value) + { + this._displayOriginX = value; + this.originX = value / this.width; + } + }, -/***/ }), -/* 158 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The vertical display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * + * @name Phaser.GameObjects.Components.Origin#displayOriginY + * @type {number} + * @since 3.0.0 + */ + displayOriginY: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this._displayOriginY; + }, -var IsInLayerBounds = __webpack_require__(119); + set: function (value) + { + this._displayOriginY = value; + this.originY = value / this.height; + } -/** - * Gets a tile at the given tile coordinates from the given layer. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid. - */ -var GetTileAt = function (tileX, tileY, nonNull, layer) -{ - if (nonNull === undefined) { nonNull = false; } + }, - if (IsInLayerBounds(tileX, tileY, layer)) + /** + * Sets the origin of this Game Object. + * + * The values are given in the range 0 to 1. + * + * @method Phaser.GameObjects.Components.Origin#setOrigin + * @since 3.0.0 + * + * @param {number} [x=0.5] - The horizontal origin value. + * @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`. + * + * @return {this} This Game Object instance. + */ + setOrigin: function (x, y) { - var tile = layer.data[tileY][tileX] || null; + if (x === undefined) { x = 0.5; } + if (y === undefined) { y = x; } - if (!tile) - { - return null; - } - else if (tile.index === -1) + this.originX = x; + this.originY = y; + + return this.updateDisplayOrigin(); + }, + + /** + * Sets the origin of this Game Object based on the Pivot values in its Frame. + * + * @method Phaser.GameObjects.Components.Origin#setOriginFromFrame + * @since 3.0.0 + * + * @return {this} This Game Object instance. + */ + setOriginFromFrame: function () + { + if (!this.frame || !this.frame.customPivot) { - return nonNull ? tile : null; + return this.setOrigin(); } else { - return tile; + this.originX = this.frame.pivotX; + this.originY = this.frame.pivotY; } - } - else + + return this.updateDisplayOrigin(); + }, + + /** + * Sets the display origin of this Game Object. + * The difference between this and setting the origin is that you can use pixel values for setting the display origin. + * + * @method Phaser.GameObjects.Components.Origin#setDisplayOrigin + * @since 3.0.0 + * + * @param {number} [x=0] - The horizontal display origin value. + * @param {number} [y=x] - The vertical display origin value. If not defined it will be set to the value of `x`. + * + * @return {this} This Game Object instance. + */ + setDisplayOrigin: function (x, y) { - return null; + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } + + this.displayOriginX = x; + this.displayOriginY = y; + + return this; + }, + + /** + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. + * + * @method Phaser.GameObjects.Components.Origin#updateDisplayOrigin + * @since 3.0.0 + * + * @return {this} This Game Object instance. + */ + updateDisplayOrigin: function () + { + this._displayOriginX = this.originX * this.width; + this._displayOriginY = this.originY * this.height; + + return this; } + }; -module.exports = GetTileAt; +module.exports = Origin; /***/ }), -/* 159 */ -/***/ (function(module, exports) { + +/***/ 54211: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var DegToRad = __webpack_require__(75606); +var GetBoolean = __webpack_require__(63130); +var GetValue = __webpack_require__(10850); +var TWEEN_CONST = __webpack_require__(55303); +var Vector2 = __webpack_require__(93736); + /** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. - * - * @function Phaser.Tilemaps.Components.RunCull - * @since 3.50.0 - * - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @param {object} bounds - An object containing the `left`, `right`, `top` and `bottom` bounds. - * @param {number} renderOrder - The rendering order constant. - * @param {array} outputArray - The array to store the Tile objects within. + * Provides methods used for managing a Game Object following a Path. + * Should be applied as a mixin and not used directly. * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + * @namespace Phaser.GameObjects.Components.PathFollower + * @since 3.17.0 */ -var RunCull = function (layer, bounds, renderOrder, outputArray) -{ - var mapData = layer.data; - var mapWidth = layer.width; - var mapHeight = layer.height; - - var tilemapLayer = layer.tilemapLayer; - - var drawLeft = Math.max(0, bounds.left); - var drawRight = Math.min(mapWidth, bounds.right); - var drawTop = Math.max(0, bounds.top); - var drawBottom = Math.min(mapHeight, bounds.bottom); - var x; - var y; - var tile; +var PathFollower = { - if (renderOrder === 0) - { - // right-down + /** + * The Path this PathFollower is following. It can only follow one Path at a time. + * + * @name Phaser.GameObjects.Components.PathFollower#path + * @type {Phaser.Curves.Path} + * @since 3.0.0 + */ + path: null, - for (y = drawTop; y < drawBottom; y++) - { - for (x = drawLeft; mapData[y] && x < drawRight; x++) - { - tile = mapData[y][x]; + /** + * Should the PathFollower automatically rotate to point in the direction of the Path? + * + * @name Phaser.GameObjects.Components.PathFollower#rotateToPath + * @type {boolean} + * @default false + * @since 3.0.0 + */ + rotateToPath: false, - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } + /** + * If the PathFollower is rotating to match the Path (@see Phaser.GameObjects.PathFollower#rotateToPath) + * this value is added to the rotation value. This allows you to rotate objects to a path but control + * the angle of the rotation as well. + * + * @name Phaser.GameObjects.PathFollower#pathRotationOffset + * @type {number} + * @default 0 + * @since 3.0.0 + */ + pathRotationOffset: 0, - outputArray.push(tile); - } - } - } - else if (renderOrder === 1) - { - // left-down + /** + * An additional vector to add to the PathFollowers position, allowing you to offset it from the + * Path coordinates. + * + * @name Phaser.GameObjects.PathFollower#pathOffset + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + pathOffset: null, - for (y = drawTop; y < drawBottom; y++) - { - for (x = drawRight; mapData[y] && x >= drawLeft; x--) - { - tile = mapData[y][x]; + /** + * A Vector2 that stores the current point of the path the follower is on. + * + * @name Phaser.GameObjects.PathFollower#pathVector + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + pathVector: null, - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } + /** + * The distance the follower has traveled from the previous point to the current one, at the last update. + * + * @name Phaser.GameObjects.PathFollower#pathDelta + * @type {Phaser.Math.Vector2} + * @since 3.23.0 + */ + pathDelta: null, - outputArray.push(tile); - } - } - } - else if (renderOrder === 2) - { - // right-up + /** + * The Tween used for following the Path. + * + * @name Phaser.GameObjects.PathFollower#pathTween + * @type {Phaser.Tweens.Tween} + * @since 3.0.0 + */ + pathTween: null, - for (y = drawBottom; y >= drawTop; y--) - { - for (x = drawLeft; mapData[y] && x < drawRight; x++) - { - tile = mapData[y][x]; + /** + * Settings for the PathFollower. + * + * @name Phaser.GameObjects.PathFollower#pathConfig + * @type {?Phaser.Types.GameObjects.PathFollower.PathConfig} + * @default null + * @since 3.0.0 + */ + pathConfig: null, - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } + /** + * Records the direction of the follower so it can change direction. + * + * @name Phaser.GameObjects.PathFollower#_prevDirection + * @type {number} + * @private + * @since 3.0.0 + */ + _prevDirection: TWEEN_CONST.PLAYING_FORWARD, - outputArray.push(tile); - } - } - } - else if (renderOrder === 3) + /** + * Set the Path that this PathFollower should follow. + * + * Optionally accepts {@link Phaser.Types.GameObjects.PathFollower.PathConfig} settings. + * + * @method Phaser.GameObjects.Components.PathFollower#setPath + * @since 3.0.0 + * + * @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time. + * @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config] - Settings for the PathFollower. + * + * @return {this} This Game Object. + */ + setPath: function (path, config) { - // left-up + if (config === undefined) { config = this.pathConfig; } - for (y = drawBottom; y >= drawTop; y--) + var tween = this.pathTween; + + if (tween && tween.isPlaying()) { - for (x = drawRight; mapData[y] && x >= drawLeft; x--) - { - tile = mapData[y][x]; + tween.stop(); + } - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } + this.path = path; - outputArray.push(tile); - } + if (config) + { + this.startFollow(config); } - } - tilemapLayer.tilesDrawn = outputArray.length; - tilemapLayer.tilesTotal = mapWidth * mapHeight; + return this; + }, - return outputArray; -}; + /** + * Set whether the PathFollower should automatically rotate to point in the direction of the Path. + * + * @method Phaser.GameObjects.Components.PathFollower#setRotateToPath + * @since 3.0.0 + * + * @param {boolean} value - Whether the PathFollower should automatically rotate to point in the direction of the Path. + * @param {number} [offset=0] - Rotation offset in degrees. + * + * @return {this} This Game Object. + */ + setRotateToPath: function (value, offset) + { + if (offset === undefined) { offset = 0; } -module.exports = RunCull; + this.rotateToPath = value; + this.pathRotationOffset = offset; -/***/ }), -/* 160 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Is this PathFollower actively following a Path or not? + * + * To be considered as `isFollowing` it must be currently moving on a Path, and not paused. + * + * @method Phaser.GameObjects.Components.PathFollower#isFollowing + * @since 3.0.0 + * + * @return {boolean} `true` is this PathFollower is actively following a Path, otherwise `false`. + */ + isFollowing: function () + { + var tween = this.pathTween; -/** - * Internally used method to keep track of the tile indexes that collide within a layer. This - * updates LayerData.collideIndexes to either contain or not contain the given `tileIndex`. - * - * @function Phaser.Tilemaps.Components.SetLayerCollisionIndex - * @since 3.0.0 - * - * @param {number} tileIndex - The tile index to set the collision boolean for. - * @param {boolean} collides - Should the tile index collide or not? - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - */ -var SetLayerCollisionIndex = function (tileIndex, collides, layer) -{ - var loc = layer.collideIndexes.indexOf(tileIndex); + return (tween && tween.isPlaying()); + }, - if (collides && loc === -1) - { - layer.collideIndexes.push(tileIndex); - } - else if (!collides && loc !== -1) + /** + * Starts this PathFollower following its given Path. + * + * @method Phaser.GameObjects.Components.PathFollower#startFollow + * @since 3.3.0 + * + * @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config={}] - The duration of the follow, or a PathFollower config object. + * @param {number} [startAt=0] - Optional start position of the follow, between 0 and 1. + * + * @return {this} This Game Object. + */ + startFollow: function (config, startAt) { - layer.collideIndexes.splice(loc, 1); - } -}; + if (config === undefined) { config = {}; } + if (startAt === undefined) { startAt = 0; } -module.exports = SetLayerCollisionIndex; + var tween = this.pathTween; + if (tween && tween.isPlaying()) + { + tween.stop(); + } -/***/ }), -/* 161 */ -/***/ (function(module, exports, __webpack_require__) { + if (typeof config === 'number') + { + config = { duration: config }; + } -/** - * @author Seth Berrier - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Override in case they've been specified in the config + config.from = GetValue(config, 'from', 0); + config.to = GetValue(config, 'to', 1); -var GetFastValue = __webpack_require__(2); + var positionOnPath = GetBoolean(config, 'positionOnPath', false); -/** - * Parse a Tiled group layer and create a state object for inheriting. - * - * @function Phaser.Tilemaps.Parsers.Tiled.CreateGroupLayer - * @since 3.21.0 - * - * @param {object} json - The Tiled JSON object. - * @param {object} [currentl] - The current group layer from the Tiled JSON file. - * @param {object} [parentstate] - The state of the parent group (if any). - * - * @return {object} A group state object with proper values for updating children layers. - */ -var CreateGroupLayer = function (json, groupl, parentstate) -{ - if (!groupl) - { - // Return a default group state object - return { - i: 0, // Current layer array iterator - layers: json.layers, // Current array of layers + this.rotateToPath = GetBoolean(config, 'rotateToPath', false); + this.pathRotationOffset = GetValue(config, 'rotationOffset', 0); - // Values inherited from parent group - name: '', - opacity: 1, - visible: true, - x: 0, - y: 0 - }; - } + // This works, but it's not an ideal way of doing it as the follower jumps position + var seek = GetValue(config, 'startAt', startAt); - // Compute group layer x, y - var layerX = groupl.x + GetFastValue(groupl, 'startx', 0) * json.tilewidth + GetFastValue(groupl, 'offsetx', 0); - var layerY = groupl.y + GetFastValue(groupl, 'starty', 0) * json.tileheight + GetFastValue(groupl, 'offsety', 0); + if (seek) + { + config.onStart = function (tween) + { + var tweenData = tween.data[0]; + tweenData.progress = seek; + tweenData.elapsed = tweenData.duration * seek; + var v = tweenData.ease(tweenData.progress); + tweenData.current = tweenData.start + ((tweenData.end - tweenData.start) * v); + tweenData.setTargetValue(); + }; + } - // Compute next state inherited from group - return { - i: 0, - layers: groupl.layers, - name: parentstate.name + groupl.name + '/', - opacity: parentstate.opacity * groupl.opacity, - visible: parentstate.visible && groupl.visible, - x: parentstate.x + layerX, - y: parentstate.y + layerY - }; -}; + if (!this.pathOffset) + { + this.pathOffset = new Vector2(this.x, this.y); + } -module.exports = CreateGroupLayer; + if (!this.pathVector) + { + this.pathVector = new Vector2(); + } + if (!this.pathDelta) + { + this.pathDelta = new Vector2(); + } -/***/ }), -/* 162 */ -/***/ (function(module, exports) { + this.pathDelta.reset(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + config.persist = true; -/** - * Internal function used by the Tween Builder to create a function that will return - * the given value from the source. - * - * @function Phaser.Tweens.Builders.GetNewValue - * @since 3.0.0 - * - * @param {any} source - The source object to get the value from. - * @param {string} key - The property to get from the source. - * @param {any} defaultValue - A default value to return should the source not have the property set. - * - * @return {function} A function which when called will return the property value from the source. - */ -var GetNewValue = function (source, key, defaultValue) -{ - var valueCallback; + this.pathTween = this.scene.sys.tweens.addCounter(config); - if (source.hasOwnProperty(key)) - { - var t = typeof(source[key]); + // The starting point of the path, relative to this follower + this.path.getStartPoint(this.pathOffset); - if (t === 'function') - { - valueCallback = function (target, targetKey, value, targetIndex, totalTargets, tween) - { - return source[key](target, targetKey, value, targetIndex, totalTargets, tween); - }; - } - else + if (positionOnPath) { - valueCallback = function () - { - return source[key]; - }; + this.x = this.pathOffset.x; + this.y = this.pathOffset.y; } - } - else if (typeof defaultValue === 'function') - { - valueCallback = defaultValue; - } - else - { - valueCallback = function () + + this.pathOffset.x = this.x - this.pathOffset.x; + this.pathOffset.y = this.y - this.pathOffset.y; + + this._prevDirection = TWEEN_CONST.PLAYING_FORWARD; + + if (this.rotateToPath) { - return defaultValue; - }; - } + // Set the rotation now (in case the tween has a delay on it, etc) + var nextPoint = this.path.getPoint(0.1); - return valueCallback; -}; + this.rotation = Math.atan2(nextPoint.y - this.y, nextPoint.x - this.x) + DegToRad(this.pathRotationOffset); + } -module.exports = GetNewValue; + this.pathConfig = config; + return this; + }, -/***/ }), -/* 163 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Pauses this PathFollower. It will still continue to render, but it will remain motionless at the + * point on the Path at which you paused it. + * + * @method Phaser.GameObjects.Components.PathFollower#pauseFollow + * @since 3.3.0 + * + * @return {this} This Game Object. + */ + pauseFollow: function () + { + var tween = this.pathTween; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (tween && tween.isPlaying()) + { + tween.pause(); + } -var Defaults = __webpack_require__(265); -var GetAdvancedValue = __webpack_require__(13); -var GetBoolean = __webpack_require__(99); -var GetEaseFunction = __webpack_require__(80); -var GetNewValue = __webpack_require__(162); -var GetProps = __webpack_require__(583); -var GetTargets = __webpack_require__(263); -var GetValue = __webpack_require__(6); -var GetValueOp = __webpack_require__(264); -var Tween = __webpack_require__(266); -var TweenData = __webpack_require__(268); + return this; + }, -/** - * Creates a new Tween. - * - * @function Phaser.Tweens.Builders.TweenBuilder - * @since 3.0.0 - * - * @param {(Phaser.Tweens.TweenManager|Phaser.Tweens.Timeline)} parent - The owner of the new Tween. - * @param {Phaser.Types.Tweens.TweenBuilderConfig|object} config - Configuration for the new Tween. - * @param {Phaser.Types.Tweens.TweenConfigDefaults} defaults - Tween configuration defaults. - * - * @return {Phaser.Tweens.Tween} The new tween. - */ -var TweenBuilder = function (parent, config, defaults) -{ - if (defaults === undefined) + /** + * Resumes a previously paused PathFollower. + * + * If the PathFollower was not paused this has no effect. + * + * @method Phaser.GameObjects.Components.PathFollower#resumeFollow + * @since 3.3.0 + * + * @return {this} This Game Object. + */ + resumeFollow: function () { - defaults = Defaults; - } + var tween = this.pathTween; - // Create arrays of the Targets and the Properties - var targets = (defaults.targets) ? defaults.targets : GetTargets(config); + if (tween && tween.isPaused()) + { + tween.resume(); + } - // var props = (defaults.props) ? defaults.props : GetProps(config); - var props = GetProps(config); + return this; + }, - // Default Tween values - 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 flipX = GetBoolean(config, 'flipX', defaults.flipX); - var flipY = GetBoolean(config, 'flipY', defaults.flipY); + /** + * Stops this PathFollower from following the path any longer. + * + * This will invoke any 'stop' conditions that may exist on the Path, or for the follower. + * + * @method Phaser.GameObjects.Components.PathFollower#stopFollow + * @since 3.3.0 + * + * @return {this} This Game Object. + */ + stopFollow: function () + { + var tween = this.pathTween; + + if (tween && tween.isPlaying()) + { + tween.stop(); + } - var data = []; + return this; + }, - // Loop through every property defined in the Tween, i.e.: props { x, y, alpha } - for (var p = 0; p < props.length; p++) + /** + * Internal update handler that advances this PathFollower along the path. + * + * Called automatically by the Scene step, should not typically be called directly. + * + * @method Phaser.GameObjects.Components.PathFollower#pathUpdate + * @since 3.17.0 + */ + pathUpdate: function () { - var key = props[p].key; - var value = props[p].value; + var tween = this.pathTween; - // Create 1 TweenData per target, per property - for (var t = 0; t < targets.length; t++) + if (tween) { - var ops = GetValueOp(key, value); + var tweenData = tween.data[0]; + var pathDelta = this.pathDelta; + var pathVector = this.pathVector; - var tweenData = TweenData( - targets[t], - t, - key, - ops.getEnd, - ops.getStart, - ops.getActive, - GetEaseFunction(GetValue(value, 'ease', ease), GetValue(value, 'easeParams', easeParams)), - GetNewValue(value, 'delay', delay), - GetNewValue(value, 'duration', duration), - GetBoolean(value, 'yoyo', yoyo), - GetNewValue(value, 'hold', hold), - GetNewValue(value, 'repeat', repeat), - GetNewValue(value, 'repeatDelay', repeatDelay), - GetBoolean(value, 'flipX', flipX), - GetBoolean(value, 'flipY', flipY) - ); + pathDelta.copy(pathVector).negate(); - data.push(tweenData); - } - } + if (tweenData.state === TWEEN_CONST.COMPLETE) + { + this.path.getPoint(tweenData.end, pathVector); - var tween = new Tween(parent, data, targets); + pathDelta.add(pathVector); + pathVector.add(this.pathOffset); - 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); + this.setPosition(pathVector.x, pathVector.y); - // Set the Callbacks - var scope = GetValue(config, 'callbackScope', tween); + return; + } + else if (tweenData.state !== TWEEN_CONST.PLAYING_FORWARD && tweenData.state !== TWEEN_CONST.PLAYING_BACKWARD) + { + // If delayed, etc then bail out + return; + } - // Callback parameters: 0 = a reference to the Tween itself, 1 = the target/s of the Tween, ... your own params - var tweenArray = [ tween, null ]; + this.path.getPoint(tween.getValue(), pathVector); - var callbacks = Tween.TYPES; + pathDelta.add(pathVector); + pathVector.add(this.pathOffset); - for (var i = 0; i < callbacks.length; i++) - { - var type = callbacks[i]; + var oldX = this.x; + var oldY = this.y; - var callback = GetValue(config, type, false); + this.setPosition(pathVector.x, pathVector.y); - if (callback) - { - var callbackScope = GetValue(config, type + 'Scope', scope); - var callbackParams = GetValue(config, type + 'Params', []); + var speedX = this.x - oldX; + var speedY = this.y - oldY; + + if (speedX === 0 && speedY === 0) + { + // Bail out early + return; + } + + if (tweenData.state !== this._prevDirection) + { + // We've changed direction, so don't do a rotate this frame + this._prevDirection = tweenData.state; - // The null is reset to be the Tween target - tween.setCallback(type, callback, tweenArray.concat(callbackParams), callbackScope); + return; + } + + if (this.rotateToPath) + { + this.rotation = Math.atan2(speedY, speedX) + DegToRad(this.pathRotationOffset); + } } } - return tween; }; -module.exports = TweenBuilder; +module.exports = PathFollower; /***/ }), -/* 164 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 58210: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CustomMap = __webpack_require__(102); -var GetFastValue = __webpack_require__(2); -var Events = __webpack_require__(132); -var Animation = __webpack_require__(185); +var DeepCopy = __webpack_require__(28699); /** - * @classdesc - * The Animation State Component. - * - * This component provides features to apply animations to Game Objects. It is responsible for - * loading, queuing animations for later playback, mixing between animations and setting - * the current animation frame to the Game Object that owns this component. - * - * This component lives as an instance within any Game Object that has it defined, such as Sprites. - * - * You can access its properties and methods via the `anims` property, i.e. `Sprite.anims`. - * - * As well as playing animations stored in the global Animation Manager, this component - * can also create animations that are stored locally within it. See the `create` method - * for more details. - * - * Prior to Phaser 3.50 this component was called just `Animation` and lived in the - * `Phaser.GameObjects.Components` namespace. It was renamed to `AnimationState` - * in 3.50 to help better identify its true purpose when browsing the documentation. + * Provides methods used for setting the WebGL rendering pipeline of a Game Object. * - * @class AnimationState - * @memberof Phaser.Animations - * @constructor + * @namespace Phaser.GameObjects.Components.Pipeline + * @webglOnly * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} parent - The Game Object to which this animation component belongs. */ -var AnimationState = new Class({ - initialize: +var Pipeline = { - function AnimationState (parent) - { - /** - * The Game Object to which this animation component belongs. - * - * You can typically access this component from the Game Object - * via the `this.anims` property. - * - * @name Phaser.Animations.AnimationState#parent - * @type {Phaser.GameObjects.GameObject} - * @since 3.0.0 - */ - this.parent = parent; + /** + * The initial WebGL pipeline of this Game Object. + * + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + * + * @name Phaser.GameObjects.Components.Pipeline#defaultPipeline + * @type {Phaser.Renderer.WebGL.WebGLPipeline} + * @default null + * @webglOnly + * @since 3.0.0 + */ + defaultPipeline: null, - /** - * A reference to the global Animation Manager. - * - * @name Phaser.Animations.AnimationState#animationManager - * @type {Phaser.Animations.AnimationManager} - * @since 3.0.0 - */ - this.animationManager = parent.scene.sys.anims; + /** + * The current WebGL pipeline of this Game Object. + * + * @name Phaser.GameObjects.Components.Pipeline#pipeline + * @type {Phaser.Renderer.WebGL.WebGLPipeline} + * @default null + * @webglOnly + * @since 3.0.0 + */ + pipeline: null, - this.animationManager.on(Events.REMOVE_ANIMATION, this.globalRemove, this); + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + * + * @name Phaser.GameObjects.Components.Pipeline#pipelineData + * @type {object} + * @webglOnly + * @since 3.50.0 + */ + pipelineData: null, - /** - * A reference to the Texture Manager. - * - * @name Phaser.Animations.AnimationState#textureManager - * @type {Phaser.Textures.TextureManager} - * @protected - * @since 3.50.0 - */ - this.textureManager = this.animationManager.textureManager; + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * + * @method Phaser.GameObjects.Components.Pipeline#initPipeline + * @webglOnly + * @since 3.0.0 + * + * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} [pipeline] - Either the string-based name of the pipeline, or a pipeline instance to set. + * + * @return {boolean} `true` if the pipeline was set successfully, otherwise `false`. + */ + initPipeline: function (pipeline) + { + this.pipelineData = {}; - /** - * The Animations stored locally in this Animation component. - * - * Do not modify the contents of this Map directly, instead use the - * `add`, `create` and `remove` methods of this class instead. - * - * @name Phaser.Animations.AnimationState#anims - * @type {Phaser.Structs.Map.} - * @protected - * @since 3.50.0 - */ - this.anims = null; + var renderer = this.scene.sys.renderer; - /** - * Is an animation currently playing or not? - * - * @name Phaser.Animations.AnimationState#isPlaying - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.isPlaying = false; + if (!renderer) + { + return false; + } - /** - * Has the current animation started playing, or is it waiting for a delay to expire? - * - * @name Phaser.Animations.AnimationState#hasStarted - * @type {boolean} - * @default false - * @since 3.50.0 - */ - this.hasStarted = false; + var pipelines = renderer.pipelines; - /** - * The current Animation loaded into this Animation component. - * - * Will by `null` if no animation is yet loaded. - * - * @name Phaser.Animations.AnimationState#currentAnim - * @type {?Phaser.Animations.Animation} - * @default null - * @since 3.0.0 - */ - this.currentAnim = null; + if (pipelines) + { + if (pipeline === undefined) + { + pipeline = pipelines.default; + } - /** - * The current AnimationFrame being displayed by this Animation component. - * - * Will by `null` if no animation is yet loaded. - * - * @name Phaser.Animations.AnimationState#currentFrame - * @type {?Phaser.Animations.AnimationFrame} - * @default null - * @since 3.0.0 - */ - this.currentFrame = null; - - /** - * The key, instance, or config of the next Animation to be loaded into this Animation component - * when the current animation completes. - * - * Will by `null` if no animation has been queued. - * - * @name Phaser.Animations.AnimationState#nextAnim - * @type {?(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} - * @default null - * @since 3.16.0 - */ - this.nextAnim = null; - - /** - * A queue of Animations to be loaded into this Animation component when the current animation completes. - * - * Populate this queue via the `chain` method. - * - * @name Phaser.Animations.AnimationState#nextAnimsQueue - * @type {array} - * @since 3.24.0 - */ - this.nextAnimsQueue = []; - - /** - * The Time Scale factor. - * - * You can adjust this value to modify the passage of time for the animation that is currently - * playing. For example, setting it to 2 will make the animation play twice as fast. Or setting - * it to 0.5 will slow the animation down. - * - * You can change this value at run-time, or set it via the `PlayAnimationConfig`. - * - * Prior to Phaser 3.50 this property was private and called `_timeScale`. - * - * @name Phaser.Animations.AnimationState#timeScale - * @type {number} - * @default 1 - * @since 3.50.0 - */ - this.timeScale = 1; - - /** - * The frame rate of playback, of the current animation, in frames per second. - * - * This value is set when a new animation is loaded into this component and should - * be treated as read-only, as changing it once playback has started will not alter - * the animation. To change the frame rate, provide a new value in the `PlayAnimationConfig` object. - * - * @name Phaser.Animations.AnimationState#frameRate - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.frameRate = 0; - - /** - * The duration of the current animation, in milliseconds. - * - * This value is set when a new animation is loaded into this component and should - * be treated as read-only, as changing it once playback has started will not alter - * the animation. To change the duration, provide a new value in the `PlayAnimationConfig` object. - * - * @name Phaser.Animations.AnimationState#duration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.duration = 0; - - /** - * The number of milliseconds per frame, not including frame specific modifiers that may be present in the - * Animation data. - * - * This value is calculated when a new animation is loaded into this component and should - * be treated as read-only. Changing it will not alter playback speed. - * - * @name Phaser.Animations.AnimationState#msPerFrame - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.msPerFrame = 0; - - /** - * Skip frames if the time lags, or always advanced anyway? - * - * @name Phaser.Animations.AnimationState#skipMissedFrames - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.skipMissedFrames = true; - - /** - * The delay before starting playback of the current animation, in milliseconds. - * - * This value is set when a new animation is loaded into this component and should - * be treated as read-only, as changing it once playback has started will not alter - * the animation. To change the delay, provide a new value in the `PlayAnimationConfig` object. - * - * Prior to Phaser 3.50 this property was private and called `_delay`. - * - * @name Phaser.Animations.AnimationState#delay - * @type {number} - * @default 0 - * @since 3.50.0 - */ - this.delay = 0; - - /** - * The number of times to repeat playback of the current animation. - * - * If -1, it means the animation will repeat forever. - * - * This value is set when a new animation is loaded into this component and should - * be treated as read-only, as changing it once playback has started will not alter - * the animation. To change the number of repeats, provide a new value in the `PlayAnimationConfig` object. - * - * Prior to Phaser 3.50 this property was private and called `_repeat`. - * - * @name Phaser.Animations.AnimationState#repeat - * @type {number} - * @default 0 - * @since 3.50.0 - */ - this.repeat = 0; - - /** - * The number of milliseconds to wait before starting the repeat playback of the current animation. - * - * This value is set when a new animation is loaded into this component, but can also be modified - * at run-time. - * - * You can change the repeat delay by providing a new value in the `PlayAnimationConfig` object. - * - * Prior to Phaser 3.50 this property was private and called `_repeatDelay`. - * - * @name Phaser.Animations.AnimationState#repeatDelay - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.repeatDelay = 0; - - /** - * Should the current animation yoyo? An animation that yoyos will play in reverse, from the end - * to the start, before then repeating or completing. An animation that does not yoyo will just - * play from the start to the end. - * - * This value is set when a new animation is loaded into this component, but can also be modified - * at run-time. - * - * You can change the yoyo by providing a new value in the `PlayAnimationConfig` object. - * - * Prior to Phaser 3.50 this property was private and called `_yoyo`. - * - * @name Phaser.Animations.AnimationState#yoyo - * @type {boolean} - * @default false - * @since 3.50.0 - */ - this.yoyo = false; - - /** - * Should the GameObject's `visible` property be set to `true` when the animation starts to play? - * - * This will happen _after_ any delay that may have been set. - * - * This value is set when a new animation is loaded into this component, but can also be modified - * at run-time, assuming the animation is currently delayed. - * - * @name Phaser.Animations.AnimationState#showOnStart - * @type {boolean} - * @since 3.50.0 - */ - this.showOnStart = false; - - /** - * Should the GameObject's `visible` property be set to `false` when the animation completes? - * - * This value is set when a new animation is loaded into this component, but can also be modified - * at run-time, assuming the animation is still actively playing. - * - * @name Phaser.Animations.AnimationState#hideOnComplete - * @type {boolean} - * @since 3.50.0 - */ - this.hideOnComplete = false; - - /** - * Is the playhead moving forwards (`true`) or in reverse (`false`) ? - * - * @name Phaser.Animations.AnimationState#forward - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.forward = true; - - /** - * An internal trigger that tells the component if it should plays the animation - * in reverse mode ('true') or not ('false'). This is used because `forward` can - * be changed by the `yoyo` feature. - * - * Prior to Phaser 3.50 this property was private and called `_reverse`. - * - * @name Phaser.Animations.AnimationState#inReverse - * @type {boolean} - * @default false - * @since 3.50.0 - */ - this.inReverse = false; - - /** - * Internal time overflow accumulator. - * - * This has the `delta` time added to it as part of the `update` step. - * - * @name Phaser.Animations.AnimationState#accumulator - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.accumulator = 0; - - /** - * The time point at which the next animation frame will change. - * - * This value is compared against the `accumulator` as part of the `update` step. - * - * @name Phaser.Animations.AnimationState#nextTick - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.nextTick = 0; - - /** - * A counter keeping track of how much delay time, in milliseconds, is left before playback begins. - * - * This is set via the `playAfterDelay` method, although it can be modified at run-time - * if required, as long as the animation has not already started playing. - * - * @name Phaser.Animations.AnimationState#delayCounter - * @type {number} - * @default 0 - * @since 3.50.0 - */ - this.delayCounter = 0; - - /** - * A counter that keeps track of how many repeats are left to run. - * - * This value is set when a new animation is loaded into this component, but can also be modified - * at run-time. - * - * @name Phaser.Animations.AnimationState#repeatCounter - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.repeatCounter = 0; - - /** - * An internal flag keeping track of pending repeats. - * - * @name Phaser.Animations.AnimationState#pendingRepeat - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.pendingRepeat = false; - - /** - * Is the Animation paused? - * - * @name Phaser.Animations.AnimationState#_paused - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this._paused = false; + var instance = pipelines.get(pipeline); - /** - * Was the animation previously playing before being paused? - * - * @name Phaser.Animations.AnimationState#_wasPlaying - * @type {boolean} - * @private - * @default false - * @since 3.0.0 - */ - this._wasPlaying = false; + if (instance) + { + this.defaultPipeline = instance; + this.pipeline = instance; - /** - * Internal property tracking if this Animation is waiting to stop. - * - * 0 = No - * 1 = Waiting for ms to pass - * 2 = Waiting for repeat - * 3 = Waiting for specific frame - * - * @name Phaser.Animations.AnimationState#_pendingStop - * @type {number} - * @private - * @since 3.4.0 - */ - this._pendingStop = 0; + return true; + } + } - /** - * Internal property used by _pendingStop. - * - * @name Phaser.Animations.AnimationState#_pendingStopValue - * @type {any} - * @private - * @since 3.4.0 - */ - this._pendingStopValue; + return false; }, /** - * Sets an animation, or an array of animations, to be played in the future, after the current one completes or stops. - * - * The current animation must enter a 'completed' state for this to happen, i.e. finish all of its repeats, delays, etc, - * or have one of the `stop` methods called. - * - * An animation set to repeat forever will never enter a completed state unless stopped. - * - * You can chain a new animation at any point, including before the current one starts playing, during it, or when it ends (via its `animationcomplete` event). - * - * Chained animations are specific to a Game Object, meaning different Game Objects can have different chained animations without impacting the global animation they're playing. + * Sets the main WebGL Pipeline of this Game Object. * - * Call this method with no arguments to reset all currently chained animations. + * Also sets the `pipelineData` property, if the parameter is given. * - * @method Phaser.Animations.AnimationState#chain - * @since 3.16.0 + * @method Phaser.GameObjects.Components.Pipeline#setPipeline + * @webglOnly + * @since 3.0.0 * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them. + * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline, or a pipeline instance to set. + * @param {object} [pipelineData] - Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param {boolean} [copyData=true] - Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @return {this} This Game Object instance. */ - chain: function (key) + setPipeline: function (pipeline, pipelineData, copyData) { - var parent = this.parent; + var renderer = this.scene.sys.renderer; - if (key === undefined) + if (!renderer) { - this.nextAnimsQueue.length = 0; - this.nextAnim = null; - - return parent; + return this; } - if (!Array.isArray(key)) - { - key = [ key ]; - } + var pipelines = renderer.pipelines; - for (var i = 0; i < key.length; i++) + if (pipelines) { - var anim = key[i]; + var instance = pipelines.get(pipeline); - if (this.nextAnim === null) + if (instance) { - this.nextAnim = anim; + this.pipeline = instance; } - else + + if (pipelineData) { - this.nextAnimsQueue.push(anim); + this.pipelineData = (copyData) ? DeepCopy(pipelineData) : pipelineData; } } - return this.parent; + return this; }, /** - * Returns the key of the animation currently loaded into this component. - * - * Prior to Phaser 3.50 this method was called `getCurrentKey`. + * Adds an entry to the `pipelineData` object belonging to this Game Object. * - * @method Phaser.Animations.AnimationState#getName - * @since 3.50.0 + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * - * @return {string} The key of the Animation currently loaded into this component, or an empty string if none loaded. - */ - getName: function () - { - return (this.currentAnim) ? this.currentAnim.key : ''; - }, - - /** - * Returns the key of the animation frame currently displayed by this component. + * If `value` is undefined, and `key` exists, `key` is removed from the data object. * - * @method Phaser.Animations.AnimationState#getFrameName + * @method Phaser.GameObjects.Components.Pipeline#setPipelineData + * @webglOnly * @since 3.50.0 * - * @return {string} The key of the Animation Frame currently displayed by this component, or an empty string if no animation has been loaded. - */ - getFrameName: function () - { - return (this.currentFrame) ? this.currentFrame.textureFrame : ''; - }, - - /** - * Internal method used to load an animation into this component. - * - * @method Phaser.Animations.AnimationState#load - * @protected - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or a `PlayAnimationConfig` object. + * @param {string} key - The key of the pipeline data to set, update, or delete. + * @param {any} [value] - The value to be set with the key. If `undefined` then `key` will be deleted from the object. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @return {this} This Game Object instance. */ - load: function (key) + setPipelineData: function (key, value) { - if (this.isPlaying) - { - this.stop(); - } - - var manager = this.animationManager; - var animKey = (typeof key === 'string') ? key : GetFastValue(key, 'key', null); - - // Get the animation, first from the local map and, if not found, from the Animation Manager - var anim = (this.exists(animKey)) ? this.get(animKey) : manager.get(animKey); + var data = this.pipelineData; - if (!anim) + if (value === undefined) { - console.warn('Missing animation: ' + animKey); + delete data[key]; } else { - this.currentAnim = anim; - - // And now override the animation values, if set in the config. - - var totalFrames = anim.getTotalFrames(); - var frameRate = GetFastValue(key, 'frameRate', anim.frameRate); - var duration = GetFastValue(key, 'duration', anim.duration); - - anim.calculateDuration(this, totalFrames, duration, frameRate); - - this.delay = GetFastValue(key, 'delay', anim.delay); - this.repeat = GetFastValue(key, 'repeat', anim.repeat); - this.repeatDelay = GetFastValue(key, 'repeatDelay', anim.repeatDelay); - this.yoyo = GetFastValue(key, 'yoyo', anim.yoyo); - this.showOnStart = GetFastValue(key, 'showOnStart', anim.showOnStart); - this.hideOnComplete = GetFastValue(key, 'hideOnComplete', anim.hideOnComplete); - this.skipMissedFrames = GetFastValue(key, 'skipMissedFrames', anim.skipMissedFrames); - - this.timeScale = GetFastValue(key, 'timeScale', this.timeScale); - - var startFrame = GetFastValue(key, 'startFrame', 0); - - if (startFrame > anim.getTotalFrames()) - { - startFrame = 0; - } - - var frame = anim.frames[startFrame]; - - if (startFrame === 0 && !this.forward) - { - frame = anim.getLastFrame(); - } - - this.currentFrame = frame; + data[key] = value; } - return this.parent; + return this; }, /** - * Pause the current animation and set the `isPlaying` property to `false`. - * You can optionally pause it at a specific frame. + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. * - * @method Phaser.Animations.AnimationState#pause + * @method Phaser.GameObjects.Components.Pipeline#resetPipeline + * @webglOnly * @since 3.0.0 * - * @param {Phaser.Animations.AnimationFrame} [atFrame] - An optional frame to set after pausing the animation. + * @param {boolean} [resetData=false] - Reset the `pipelineData` object to being an empty object? * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @return {boolean} `true` if the pipeline was reset successfully, otherwise `false`. */ - pause: function (atFrame) + resetPipeline: function (resetData) { - if (!this._paused) - { - this._paused = true; - this._wasPlaying = this.isPlaying; - this.isPlaying = false; - } + if (resetData === undefined) { resetData = false; } - if (atFrame !== undefined) + this.pipeline = this.defaultPipeline; + + if (resetData) { - this.setCurrentFrame(atFrame); + this.pipelineData = {}; } - return this.parent; + return (this.pipeline !== null); }, /** - * Resumes playback of a paused animation and sets the `isPlaying` property to `true`. - * You can optionally tell it to start playback from a specific frame. + * Gets the name of the WebGL Pipeline this Game Object is currently using. * - * @method Phaser.Animations.AnimationState#resume + * @method Phaser.GameObjects.Components.Pipeline#getPipelineName + * @webglOnly * @since 3.0.0 * - * @param {Phaser.Animations.AnimationFrame} [fromFrame] - An optional frame to set before restarting playback. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @return {string} The string-based name of the pipeline being used by this Game Object. */ - resume: function (fromFrame) + getPipelineName: function () { - if (this._paused) - { - this._paused = false; - this.isPlaying = this._wasPlaying; - } + return this.pipeline.name; + } - if (fromFrame !== undefined) - { - this.setCurrentFrame(fromFrame); - } +}; - return this.parent; - }, +module.exports = Pipeline; - /** - * Waits for the specified delay, in milliseconds, then starts playback of the given animation. - * - * If the animation _also_ has a delay value set in its config, it will be **added** to the delay given here. - * - * If an animation is already running and a new animation is given to this method, it will wait for - * the given delay before starting the new animation. - * - * If no animation is currently running, the given one begins after the delay. - * - * Prior to Phaser 3.50 this method was called 'delayedPlay' and the parameters were in the reverse order. - * - * @method Phaser.Animations.AnimationState#playAfterDelay - * @fires Phaser.Animations.Events#ANIMATION_START - * @since 3.50.0 - * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {number} delay - The delay, in milliseconds, to wait before starting the animation playing. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. - */ - playAfterDelay: function (key, delay) - { - if (!this.isPlaying) - { - this.delayCounter = delay; - this.play(key, true); - } - else - { - // If we've got a nextAnim, move it to the queue - var nextAnim = this.nextAnim; - var queue = this.nextAnimsQueue; +/***/ }), - if (nextAnim) - { - queue.unshift(nextAnim); - } +/***/ 44086: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.nextAnim = key; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this._pendingStop = 1; - this._pendingStopValue = delay; - } +var DeepCopy = __webpack_require__(28699); +var FX = __webpack_require__(88677); +var SpliceOne = __webpack_require__(72677); - return this.parent; - }, +/** + * Provides methods used for setting the WebGL rendering post pipeline of a Game Object. + * + * @namespace Phaser.GameObjects.Components.PostPipeline + * @webglOnly + * @since 3.60.0 + */ + +var PostPipeline = { /** - * Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback - * of the given animation. - * - * You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an - * idle animation to a walking animation, by making them blend smoothly into each other. + * Does this Game Object have any Post Pipelines set? * - * If no animation is currently running, the given one will start immediately. + * @name Phaser.GameObjects.Components.PostPipeline#hasPostPipeline + * @type {boolean} + * @webglOnly + * @since 3.60.0 + */ + hasPostPipeline: false, + + /** + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. * - * @method Phaser.Animations.AnimationState#playAfterRepeat - * @fires Phaser.Animations.Events#ANIMATION_START - * @since 3.50.0 + * The pipelines are processed in the order in which they appear in this array. * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {number} [repeatCount=1] - How many times should the animation repeat before the next one starts? + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @name Phaser.GameObjects.Components.PostPipeline#postPipelines + * @type {Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]} + * @webglOnly + * @since 3.60.0 */ - playAfterRepeat: function (key, repeatCount) - { - if (repeatCount === undefined) { repeatCount = 1; } - - if (!this.isPlaying) - { - this.play(key); - } - else - { - // If we've got a nextAnim, move it to the queue - var nextAnim = this.nextAnim; - var queue = this.nextAnimsQueue; - - if (nextAnim) - { - queue.unshift(nextAnim); - } - - if (this.repeatCounter !== -1 && repeatCount > this.repeatCounter) - { - repeatCount = this.repeatCounter; - } - - this.nextAnim = key; - - this._pendingStop = 2; - this._pendingStopValue = repeatCount; - } - - return this.parent; - }, + postPipelines: null, /** - * Start playing the given animation on this Sprite. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. * - * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite. + * @name Phaser.GameObjects.Components.PostPipeline#postPipelineData + * @type {object} + * @webglOnly + * @since 3.60.0 + */ + postPipelineData: null, + + /** + * The Pre FX component of this Game Object. * - * The benefit of a global animation is that multiple Sprites can all play the same animation, without - * having to duplicate the data. You can just create it once and then play it on any Sprite. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * The following code shows how to create a global repeating animation. The animation will be created - * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` * - * ```javascript - * var config = { - * key: 'run', - * frames: 'muybridge', - * frameRate: 15, - * repeat: -1 - * }; + * Only the following Game Objects support Pre FX: * - * // This code should be run from within a Scene: - * this.anims.create(config); - * ``` + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video * - * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone, - * you can call the `Animation.create` method instead. It accepts the exact same parameters as when - * creating a global animation, however the resulting data is kept locally in this Sprite. + * All FX are WebGL only and do not have Canvas counterparts. * - * With the animation created, either globally or locally, you can now play it on this Sprite: + * Please see the FX Class for more details and available methods. * - * ```javascript - * this.add.sprite(x, y).play('run'); - * ``` + * @name Phaser.GameObjects.Components.PostPipeline#preFX + * @type {?Phaser.GameObjects.Components.FX} + * @webglOnly + * @since 3.60.0 + */ + preFX: null, + + /** + * The Post FX component of this Game Object. * - * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config - * object instead: + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * ```javascript - * this.add.sprite(x, y).play({ key: 'run', frameRate: 24 }); + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); * ``` * - * When playing an animation on a Sprite it will first check to see if it can find a matching key - * locally within the Sprite. If it can, it will play the local animation. If not, it will then - * search the global Animation Manager and look for it there. + * All FX are WebGL only and do not have Canvas counterparts. * - * If you need a Sprite to be able to play both local and global animations, make sure they don't - * have conflicting keys. + * Please see the FX Class for more details and available methods. * - * See the documentation for the `PlayAnimationConfig` config object for more details about this. + * This property is always `null` until the `initPostPipeline` method is called. * - * Also, see the documentation in the Animation Manager for further details on creating animations. + * @name Phaser.GameObjects.Components.PostPipeline#postFX + * @type {Phaser.GameObjects.Components.FX} + * @webglOnly + * @since 3.60.0 + */ + postFX: null, + + /** + * This should only be called during the instantiation of the Game Object. * - * @method Phaser.Animations.AnimationState#play - * @fires Phaser.Animations.Events#ANIMATION_START - * @since 3.0.0 + * It is called by default by all core Game Objects and doesn't need + * calling again. * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {boolean} [ignoreIfPlaying=false] - If this animation is already playing then ignore this call. + * After that, use `setPostPipeline`. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @method Phaser.GameObjects.Components.PostPipeline#initPostPipeline + * @webglOnly + * @since 3.60.0 + * + * @param {boolean} [preFX=false] - Does this Game Object support Pre FX? */ - play: function (key, ignoreIfPlaying) + initPostPipeline: function (preFX) { - if (ignoreIfPlaying === undefined) { ignoreIfPlaying = false; } - - var currentAnim = this.currentAnim; - var parent = this.parent; - - // Must be either an Animation instance, or a PlayAnimationConfig object - var animKey = (typeof key === 'string') ? key : key.key; + this.postPipelines = []; + this.postPipelineData = {}; - if (ignoreIfPlaying && this.isPlaying && currentAnim.key === animKey) - { - return parent; - } + this.postFX = new FX(this, true); - // Are we mixing? - if (currentAnim && this.isPlaying) + if (preFX) { - var mix = this.animationManager.getMix(currentAnim.key, key); - - if (mix > 0) - { - return this.playAfterDelay(key, mix); - } + this.preFX = new FX(this, false); } - - this.forward = true; - this.inReverse = false; - - this._paused = false; - this._wasPlaying = true; - - return this.startAnimation(key); }, /** - * Start playing the given animation on this Sprite, in reverse. - * - * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite. - * - * The benefit of a global animation is that multiple Sprites can all play the same animation, without - * having to duplicate the data. You can just create it once and then play it on any Sprite. - * - * The following code shows how to create a global repeating animation. The animation will be created - * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': - * - * ```javascript - * var config = { - * key: 'run', - * frames: 'muybridge', - * frameRate: 15, - * repeat: -1 - * }; - * - * // This code should be run from within a Scene: - * this.anims.create(config); - * ``` - * - * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone, - * you can call the `Animation.create` method instead. It accepts the exact same parameters as when - * creating a global animation, however the resulting data is kept locally in this Sprite. - * - * With the animation created, either globally or locally, you can now play it on this Sprite: - * - * ```javascript - * this.add.sprite(x, y).playReverse('run'); - * ``` - * - * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config - * object instead: - * - * ```javascript - * this.add.sprite(x, y).playReverse({ key: 'run', frameRate: 24 }); - * ``` + * Sets one, or more, Post Pipelines on this Game Object. * - * When playing an animation on a Sprite it will first check to see if it can find a matching key - * locally within the Sprite. If it can, it will play the local animation. If not, it will then - * search the global Animation Manager and look for it there. + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. * - * If you need a Sprite to be able to play both local and global animations, make sure they don't - * have conflicting keys. + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. * - * See the documentation for the `PlayAnimationConfig` config object for more details about this. + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * Also, see the documentation in the Animation Manager for further details on creating animations. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * - * @method Phaser.Animations.AnimationState#playReverse - * @fires Phaser.Animations.Events#ANIMATION_START - * @since 3.12.0 + * @method Phaser.GameObjects.Components.PostPipeline#setPostPipeline + * @webglOnly + * @since 3.60.0 * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. + * @param {(string|string[]|function|function[]|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[])} pipelines - Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param {object} [pipelineData] - Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param {boolean} [copyData=true] - Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @return {this} This Game Object instance. */ - playReverse: function (key, ignoreIfPlaying) + setPostPipeline: function (pipelines, pipelineData, copyData) { - if (ignoreIfPlaying === undefined) { ignoreIfPlaying = false; } - - // Must be either an Animation instance, or a PlayAnimationConfig object - var animKey = (typeof key === 'string') ? key : key.key; + var renderer = this.scene.sys.renderer; - if (ignoreIfPlaying && this.isPlaying && this.currentAnim.key === animKey) + if (!renderer) { - return this.parent; + return this; } - this.forward = false; - this.inReverse = true; + var pipelineManager = renderer.pipelines; - this._paused = false; - this._wasPlaying = true; + if (pipelineManager) + { + if (!Array.isArray(pipelines)) + { + pipelines = [ pipelines ]; + } - return this.startAnimation(key); + for (var i = 0; i < pipelines.length; i++) + { + var instance = pipelineManager.getPostPipeline(pipelines[i], this, pipelineData); + + if (instance) + { + this.postPipelines.push(instance); + } + } + + if (pipelineData) + { + this.postPipelineData = (copyData) ? DeepCopy(pipelineData) : pipelineData; + } + } + + this.hasPostPipeline = (this.postPipelines.length > 0); + + return this; }, /** - * Load the animation based on the key and set-up all of the internal values - * needed for playback to start. If there is no delay, it will also fire the start events. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * - * @method Phaser.Animations.AnimationState#startAnimation - * @fires Phaser.Animations.Events#ANIMATION_START - * @since 3.50.0 + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * - * @param {(string|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or a `PlayAnimationConfig` object. + * If `value` is undefined, and `key` exists, `key` is removed from the data object. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @method Phaser.GameObjects.Components.PostPipeline#setPostPipelineData + * @webglOnly + * @since 3.60.0 + * + * @param {string} key - The key of the pipeline data to set, update, or delete. + * @param {any} [value] - The value to be set with the key. If `undefined` then `key` will be deleted from the object. + * + * @return {this} This Game Object instance. */ - startAnimation: function (key) + setPostPipelineData: function (key, value) { - this.load(key); - - var anim = this.currentAnim; - var gameObject = this.parent; + var data = this.postPipelineData; - if (!anim) + if (value === undefined) { - return gameObject; + delete data[key]; } - - // Should give us 9,007,199,254,740,991 safe repeats - this.repeatCounter = (this.repeat === -1) ? Number.MAX_VALUE : this.repeat; - - anim.getFirstTick(this); - - this.isPlaying = true; - this.pendingRepeat = false; - this.hasStarted = false; - - this._pendingStop = 0; - this._pendingStopValue = 0; - this._paused = false; - - // Add any delay the animation itself may have had as well - this.delayCounter += this.delay; - - if (this.delayCounter === 0) + else { - this.handleStart(); + data[key] = value; } - return gameObject; + return this; }, /** - * Handles the start of an animation playback. + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. * - * @method Phaser.Animations.AnimationState#handleStart - * @private - * @since 3.50.0 - */ - handleStart: function () - { - if (this.showOnStart) - { - this.parent.setVisible(true); - } - - this.setCurrentFrame(this.currentFrame); - - this.hasStarted = true; - - this.emitEvents(Events.ANIMATION_START); - }, - - /** - * Handles the repeat of an animation. + * @method Phaser.GameObjects.Components.PostPipeline#getPostPipeline + * @webglOnly + * @since 3.60.0 * - * @method Phaser.Animations.AnimationState#handleRepeat - * @private - * @since 3.50.0 - */ - handleRepeat: function () - { - this.pendingRepeat = false; - - this.emitEvents(Events.ANIMATION_REPEAT); - }, - - /** - * Handles the stop of an animation playback. + * @param {(string|function|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline)} pipeline - The string-based name of the pipeline, or a pipeline class. * - * @method Phaser.Animations.AnimationState#handleStop - * @private - * @since 3.50.0 + * @return {(Phaser.Renderer.WebGL.Pipelines.PostFXPipeline|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[])} An array of all the Post Pipelines matching the name. This array will be empty if there was no match. If there was only one single match, that pipeline is returned directly, not in an array. */ - handleStop: function () + getPostPipeline: function (pipeline) { - this._pendingStop = 0; - - this.isPlaying = false; - - this.emitEvents(Events.ANIMATION_STOP); - }, + var isString = (typeof pipeline === 'string'); - /** - * Handles the completion of an animation playback. - * - * @method Phaser.Animations.AnimationState#handleComplete - * @private - * @since 3.50.0 - */ - handleComplete: function () - { - this._pendingStop = 0; + var pipelines = this.postPipelines; - this.isPlaying = false; + var results = []; - if (this.hideOnComplete) + for (var i = 0; i < pipelines.length; i++) { - this.parent.setVisible(false); + var instance = pipelines[i]; + + if ((isString && instance.name === pipeline) || (!isString && instance instanceof pipeline)) + { + results.push(instance); + } } - this.emitEvents(Events.ANIMATION_COMPLETE, Events.ANIMATION_COMPLETE_KEY); + return (results.length === 1) ? results[0] : results; }, /** - * Fires the given animation event. + * Resets the WebGL Post Pipelines of this Game Object. It does this by calling + * the `destroy` method on each post pipeline and then clearing the local array. * - * @method Phaser.Animations.AnimationState#emitEvents - * @private - * @since 3.50.0 + * @method Phaser.GameObjects.Components.PostPipeline#resetPostPipeline + * @webglOnly + * @since 3.60.0 * - * @param {string} event - The Animation Event to dispatch. + * @param {boolean} [resetData=false] - Reset the `postPipelineData` object to being an empty object? */ - emitEvents: function (event, keyEvent) + resetPostPipeline: function (resetData) { - var anim = this.currentAnim; - var frame = this.currentFrame; - var gameObject = this.parent; + if (resetData === undefined) { resetData = false; } + + var pipelines = this.postPipelines; - var frameKey = frame.textureFrame; + for (var i = 0; i < pipelines.length; i++) + { + pipelines[i].destroy(); + } - gameObject.emit(event, anim, frame, gameObject, frameKey); + this.postPipelines = []; + this.hasPostPipeline = false; - if (keyEvent) + if (resetData) { - gameObject.emit(keyEvent + anim.key, anim, frame, gameObject, frameKey); + this.postPipelineData = {}; } }, /** - * Reverse the Animation that is already playing on the Game Object. + * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. * - * @method Phaser.Animations.AnimationState#reverse - * @since 3.12.0 + * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @method Phaser.GameObjects.Components.PostPipeline#removePostPipeline + * @webglOnly + * @since 3.60.0 + * + * @param {string|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} pipeline - The string-based name of the pipeline, or a pipeline class. + * + * @return {this} This Game Object. */ - reverse: function () + removePostPipeline: function (pipeline) { - if (this.isPlaying) + var isString = (typeof pipeline === 'string'); + + var pipelines = this.postPipelines; + + for (var i = pipelines.length - 1; i >= 0; i--) { - this.inReverse = !this.inReverse; + var instance = pipelines[i]; - this.forward = !this.forward; + if ( + (isString && instance.name === pipeline) || + (!isString && instance === pipeline)) + { + instance.destroy(); + + SpliceOne(pipelines, i); + } } - return this.parent; + this.hasPostPipeline = (this.postPipelines.length > 0); + + return this; }, /** - * Returns a value between 0 and 1 indicating how far this animation is through, ignoring repeats and yoyos. + * Removes all Pre and Post FX Controllers from this Game Object. * - * The value is based on the current frame and how far that is in the animation, it is not based on - * the duration of the animation. + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. * - * @method Phaser.Animations.AnimationState#getProgress - * @since 3.4.0 + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. * - * @return {number} The progress of the current animation in frames, between 0 and 1. + * @method Phaser.GameObjects.Components.PostPipeline#clearFX + * @webglOnly + * @since 3.60.0 + * + * @return {this} This Game Object. */ - getProgress: function () + clearFX: function () { - var frame = this.currentFrame; - - if (!frame) + if (this.preFX) { - return 0; + this.preFX.clear(); } - var p = frame.progress; - - if (this.inReverse) + if (this.postFX) { - p *= -1; + this.postFX.clear(); } - return p; - }, + return this; + } - /** - * Takes a value between 0 and 1 and uses it to set how far this animation is through playback. - * - * Does not factor in repeats or yoyos, but does handle playing forwards or backwards. - * - * The value is based on the current frame and how far that is in the animation, it is not based on - * the duration of the animation. - * - * @method Phaser.Animations.AnimationState#setProgress - * @since 3.4.0 - * - * @param {number} [value=0] - The progress value, between 0 and 1. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. - */ - setProgress: function (value) - { - if (!this.forward) - { - value = 1 - value; - } +}; - this.setCurrentFrame(this.currentAnim.getFrameByProgress(value)); +module.exports = PostPipeline; - return this.parent; - }, + +/***/ }), + +/***/ 45900: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Provides methods used for getting and setting the Scroll Factor of a Game Object. + * + * @namespace Phaser.GameObjects.Components.ScrollFactor + * @since 3.0.0 + */ + +var ScrollFactor = { /** - * Sets the number of times that the animation should repeat after its first play through. - * For example, if repeat is 1, the animation will play a total of twice: the initial play plus 1 repeat. + * The horizontal scroll factor of this Game Object. * - * To repeat indefinitely, use -1. - * The value should always be an integer. + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. * - * Calling this method only works if the animation is already running. Otherwise, any - * value specified here will be overwritten when the next animation loads in. To avoid this, - * use the `repeat` property of the `PlayAnimationConfig` object instead. + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. * - * @method Phaser.Animations.AnimationState#setRepeat - * @since 3.4.0 + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. * - * @param {number} value - The number of times that the animation should repeat. + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorX + * @type {number} + * @default 1 + * @since 3.0.0 */ - setRepeat: function (value) - { - this.repeatCounter = (value === -1) ? Number.MAX_VALUE : value; - - return this.parent; - }, + scrollFactorX: 1, /** - * Handle the removal of an animation from the Animation Manager. + * The vertical scroll factor of this Game Object. * - * @method Phaser.Animations.AnimationState#globalRemove - * @since 3.50.0 + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. * - * @param {string} [key] - The key of the removed Animation. - * @param {Phaser.Animations.Animation} [animation] - The removed Animation. + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * + * @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorY + * @type {number} + * @default 1 + * @since 3.0.0 */ - globalRemove: function (key, animation) - { - if (animation === undefined) { animation = this.currentAnim; } - - if (this.isPlaying && animation.key === this.currentAnim.key) - { - this.stop(); - - this.setCurrentFrame(this.currentAnim.frames[0]); - } - }, + scrollFactorY: 1, /** - * Restarts the current animation from its beginning. + * Sets the scroll factor of this Game Object. * - * You can optionally reset the delay and repeat counters as well. + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. * - * Calling this will fire the `ANIMATION_RESTART` event immediately. + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. * - * If you `includeDelay` then it will also fire the `ANIMATION_START` event once - * the delay has expired, otherwise, playback will just begin immediately. + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. * - * @method Phaser.Animations.AnimationState#restart - * @fires Phaser.Animations.Events#ANIMATION_RESTART + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * + * @method Phaser.GameObjects.Components.ScrollFactor#setScrollFactor * @since 3.0.0 * - * @param {boolean} [includeDelay=false] - Whether to include the delay value of the animation when restarting. - * @param {boolean} [resetRepeats=false] - Whether to reset the repeat counter or not? + * @param {number} x - The horizontal scroll factor of this Game Object. + * @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @return {this} This Game Object instance. */ - restart: function (includeDelay, resetRepeats) + setScrollFactor: function (x, y) { - if (includeDelay === undefined) { includeDelay = false; } - if (resetRepeats === undefined) { resetRepeats = false; } + if (y === undefined) { y = x; } - var anim = this.currentAnim; - var gameObject = this.parent; + this.scrollFactorX = x; + this.scrollFactorY = y; - if (!anim) - { - return gameObject; - } + return this; + } - if (resetRepeats) - { - this.repeatCounter = (this.repeat === -1) ? Number.MAX_VALUE : this.repeat; - } +}; - anim.getFirstTick(this); +module.exports = ScrollFactor; - this.emitEvents(Events.ANIMATION_RESTART); - this.isPlaying = true; - this.pendingRepeat = false; +/***/ }), - // Set this to `true` if there is no delay to include, so it skips the `hasStarted` check in `update`. - this.hasStarted = !includeDelay; +/***/ 31654: +/***/ ((module) => { - this._pendingStop = 0; - this._pendingStopValue = 0; - this._paused = false; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.setCurrentFrame(anim.frames[0]); +/** + * Provides methods used for getting and setting the size of a Game Object. + * + * @namespace Phaser.GameObjects.Components.Size + * @since 3.0.0 + */ - return this.parent; - }, +var Size = { /** - * The current animation has completed. This dispatches the `ANIMATION_COMPLETE` event. + * A property indicating that a Game Object has this component. * - * This method is called by the Animation instance and should not usually be invoked directly. + * @name Phaser.GameObjects.Components.Size#_sizeComponent + * @type {boolean} + * @private + * @default true + * @since 3.2.0 + */ + _sizeComponent: true, + + /** + * The native (un-scaled) width of this Game Object. * - * If no animation is loaded, no events will be dispatched. + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. * - * If another animation has been queued for playback, it will be started after the events fire. + * @name Phaser.GameObjects.Components.Size#width + * @type {number} + * @since 3.0.0 + */ + width: 0, + + /** + * The native (un-scaled) height of this Game Object. * - * @method Phaser.Animations.AnimationState#complete - * @fires Phaser.Animations.Events#ANIMATION_COMPLETE - * @since 3.50.0 + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @name Phaser.GameObjects.Components.Size#height + * @type {number} + * @since 3.0.0 */ - complete: function () - { - this._pendingStop = 0; + height: 0, - this.isPlaying = false; + /** + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + * + * @name Phaser.GameObjects.Components.Size#displayWidth + * @type {number} + * @since 3.0.0 + */ + displayWidth: { - if (this.currentAnim) + get: function () { - this.handleComplete(); - } + return Math.abs(this.scaleX * this.frame.realWidth); + }, - if (this.nextAnim) + set: function (value) { - var key = this.nextAnim; + this.scaleX = value / this.frame.realWidth; + } - this.nextAnim = (this.nextAnimsQueue.length > 0) ? this.nextAnimsQueue.shift() : null; + }, - this.play(key); + /** + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + * + * @name Phaser.GameObjects.Components.Size#displayHeight + * @type {number} + * @since 3.0.0 + */ + displayHeight: { + + get: function () + { + return Math.abs(this.scaleY * this.frame.realHeight); + }, + + set: function (value) + { + this.scaleY = value / this.frame.realHeight; } - return this.parent; }, /** - * Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` event. + * Sets the size of this Game Object to be that of the given Frame. * - * If no animation is running, no events will be dispatched. + * 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 there is another animation in the queue (set via the `chain` method) then it will start playing. + * 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.Animations.AnimationState#stop - * @fires Phaser.Animations.Events#ANIMATION_STOP + * @method Phaser.GameObjects.Components.Size#setSizeToFrame * @since 3.0.0 * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @param {Phaser.Textures.Frame|boolean} [frame] - The frame to base the size of this Game Object on. + * + * @return {this} This Game Object instance. */ - stop: function () + setSizeToFrame: function (frame) { - this._pendingStop = 0; + if (!frame) { frame = this.frame; } - this.isPlaying = false; + this.width = frame.realWidth; + this.height = frame.realHeight; - if (this.currentAnim) - { - this.handleStop(); - } + var input = this.input; - if (this.nextAnim) + if (input && !input.customHitArea) { - var key = this.nextAnim; - - this.nextAnim = this.nextAnimsQueue.shift(); - - this.play(key); + input.hitArea.width = this.width; + input.hitArea.height = this.height; } - return this.parent; + return this; }, /** - * Stops the current animation from playing after the specified time delay, given in milliseconds. - * - * It then dispatches the `ANIMATION_STOP` event. + * Sets the internal size of this Game Object, as used for frame or physics body creation. * - * If no animation is running, no events will be dispatched. + * 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 there is another animation in the queue (set via the `chain` method) then it will start playing, - * when the current one stops. + * 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.Animations.AnimationState#stopAfterDelay - * @fires Phaser.Animations.Events#ANIMATION_STOP - * @since 3.4.0 + * @method Phaser.GameObjects.Components.Size#setSize + * @since 3.0.0 * - * @param {number} delay - The number of milliseconds to wait before stopping this animation. + * @param {number} width - The width of this Game Object. + * @param {number} height - The height of this Game Object. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @return {this} This Game Object instance. */ - stopAfterDelay: function (delay) + setSize: function (width, height) { - this._pendingStop = 1; - this._pendingStopValue = delay; + this.width = width; + this.height = height; - return this.parent; + return this; }, /** - * Stops the current animation from playing when it next repeats. - * - * It then dispatches the `ANIMATION_STOP` event. - * - * If no animation is running, no events will be dispatched. - * - * If there is another animation in the queue (set via the `chain` method) then it will start playing, - * when the current one stops. + * Sets the display size of this Game Object. * - * Prior to Phaser 3.50 this method was called `stopOnRepeat` and had no parameters. + * Calling this will adjust the scale. * - * @method Phaser.Animations.AnimationState#stopAfterRepeat - * @fires Phaser.Animations.Events#ANIMATION_STOP - * @since 3.50.0 + * @method Phaser.GameObjects.Components.Size#setDisplaySize + * @since 3.0.0 * - * @param {number} [repeatCount=1] - How many times should the animation repeat before stopping? + * @param {number} width - The width of this Game Object. + * @param {number} height - The height of this Game Object. * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @return {this} This Game Object instance. */ - stopAfterRepeat: function (repeatCount) + setDisplaySize: function (width, height) { - if (repeatCount === undefined) { repeatCount = 1; } + this.displayWidth = width; + this.displayHeight = height; - if (this.repeatCounter !== -1 && repeatCount > this.repeatCounter) - { - repeatCount = this.repeatCounter; - } + return this; + } - this._pendingStop = 2; - this._pendingStopValue = repeatCount; +}; - return this.parent; - }, +module.exports = Size; + + +/***/ }), + +/***/ 82081: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Frame = __webpack_require__(82047); + +// bitmask flag for GameObject.renderMask +var _FLAG = 8; // 1000 + +/** + * Provides methods used for getting and setting the texture of a Game Object. + * + * @namespace Phaser.GameObjects.Components.Texture + * @since 3.0.0 + */ + +var Texture = { /** - * Stops the current animation from playing when it next sets the given frame. - * If this frame doesn't exist within the animation it will not stop it from playing. + * The Texture this Game Object is using to render with. * - * It then dispatches the `ANIMATION_STOP` event. + * @name Phaser.GameObjects.Components.Texture#texture + * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} + * @since 3.0.0 + */ + texture: null, + + /** + * The Texture Frame this Game Object is using to render with. * - * If no animation is running, no events will be dispatched. + * @name Phaser.GameObjects.Components.Texture#frame + * @type {Phaser.Textures.Frame} + * @since 3.0.0 + */ + frame: null, + + /** + * Internal flag. Not to be set by this Game Object. * - * If there is another animation in the queue (set via the `chain` method) then it will start playing, - * when the current one stops. + * @name Phaser.GameObjects.Components.Texture#isCropped + * @type {boolean} + * @private + * @since 3.11.0 + */ + isCropped: false, + + /** + * Sets the texture and frame this Game Object will use to render with. * - * @method Phaser.Animations.AnimationState#stopOnFrame - * @fires Phaser.Animations.Events#ANIMATION_STOP - * @since 3.4.0 + * Textures are referenced by their string-based keys, as stored in the Texture Manager. * - * @param {Phaser.Animations.AnimationFrame} frame - The frame to check before stopping this animation. + * @method Phaser.GameObjects.Components.Texture#setTexture + * @since 3.0.0 * - * @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component. + * @param {(string|Phaser.Textures.Texture)} key - The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. + * + * @return {this} This Game Object instance. */ - stopOnFrame: function (frame) + setTexture: function (key, frame) { - this._pendingStop = 3; - this._pendingStopValue = frame; + this.texture = this.scene.sys.textures.get(key); - return this.parent; + return this.setFrame(frame); }, /** - * Returns the total number of frames in this animation, or returns zero if no - * animation has been loaded. + * Sets the frame this Game Object will use to render with. * - * @method Phaser.Animations.AnimationState#getTotalFrames - * @since 3.4.0 + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * @return {number} The total number of frames in the current animation, or zero if no animation has been loaded. - */ - getTotalFrames: function () - { - return (this.currentAnim) ? this.currentAnim.getTotalFrames() : 0; - }, - - /** - * The internal update loop for the AnimationState Component. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * - * This is called automatically by the `Sprite.preUpdate` method. + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. * - * @method Phaser.Animations.AnimationState#update + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * + * @method Phaser.GameObjects.Components.Texture#setFrame * @since 3.0.0 * - * @param {number} time - The current timestamp. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. + * @param {(string|number|Phaser.Textures.Frame)} frame - The name or index of the frame within the Texture, or a Frame instance. + * @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object? + * @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object? + * + * @return {this} This Game Object instance. */ - update: function (time, delta) + setFrame: function (frame, updateSize, updateOrigin) { - var anim = this.currentAnim; + if (updateSize === undefined) { updateSize = true; } + if (updateOrigin === undefined) { updateOrigin = true; } - if (!this.isPlaying || !anim || anim.paused) + if (frame instanceof Frame) { - return; - } - - this.accumulator += delta * this.timeScale; + this.texture = this.scene.sys.textures.get(frame.texture.key); - if (this._pendingStop === 1) + this.frame = frame; + } + else { - this._pendingStopValue -= delta; - - if (this._pendingStopValue <= 0) - { - return this.stop(); - } + this.frame = this.texture.get(frame); } - if (!this.hasStarted) + if (!this.frame.cutWidth || !this.frame.cutHeight) { - if (this.accumulator >= this.delayCounter) - { - this.accumulator -= this.delayCounter; - - this.handleStart(); - } + this.renderFlags &= ~_FLAG; } - else if (this.accumulator >= this.nextTick) + else { - // Process one frame advance as standard + this.renderFlags |= _FLAG; + } - if (this.forward) + if (this._sizeComponent && updateSize) + { + this.setSizeToFrame(); + } + + if (this._originComponent && updateOrigin) + { + if (this.frame.customPivot) { - anim.nextFrame(this); + this.setOrigin(this.frame.pivotX, this.frame.pivotY); } else { - anim.previousFrame(this); - } - - // And only do more if we're skipping frames and have time left - if (this.isPlaying && this._pendingStop === 0 && this.skipMissedFrames && this.accumulator > this.nextTick) - { - var safetyNet = 0; - - do - { - if (this.forward) - { - anim.nextFrame(this); - } - else - { - anim.previousFrame(this); - } - - safetyNet++; - - } while (this.isPlaying && this.accumulator > this.nextTick && safetyNet < 60); + this.updateDisplayOrigin(); } } - }, - /** - * Sets the given Animation Frame as being the current frame - * and applies it to the parent Game Object, adjusting size and origin as needed. - * - * @method Phaser.Animations.AnimationState#setCurrentFrame - * @fires Phaser.Animations.Events#ANIMATION_UPDATE - * @fires Phaser.Animations.Events#ANIMATION_STOP - * @since 3.4.0 - * - * @param {Phaser.Animations.AnimationFrame} animationFrame - The animation frame to change to. - * - * @return {Phaser.GameObjects.GameObject} The Game Object this Animation Component belongs to. - */ - setCurrentFrame: function (animationFrame) - { - var gameObject = this.parent; + return this; + } - this.currentFrame = animationFrame; +}; - gameObject.texture = animationFrame.frame.texture; - gameObject.frame = animationFrame.frame; +module.exports = Texture; - if (gameObject.isCropped) - { - gameObject.frame.updateCropUVs(gameObject._crop, gameObject.flipX, gameObject.flipY); - } - if (animationFrame.setAlpha) - { - gameObject.alpha = animationFrame.alpha; - } +/***/ }), - gameObject.setSizeToFrame(); +/***/ 21850: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (gameObject._originComponent) - { - if (animationFrame.frame.customPivot) - { - gameObject.setOrigin(animationFrame.frame.pivotX, animationFrame.frame.pivotY); - } - else - { - gameObject.updateDisplayOrigin(); - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (this.isPlaying && this.hasStarted) - { - this.emitEvents(Events.ANIMATION_UPDATE); +var Frame = __webpack_require__(82047); - if (this._pendingStop === 3 && this._pendingStopValue === animationFrame) - { - this.stop(); - } - } +// bitmask flag for GameObject.renderMask +var _FLAG = 8; // 1000 - return gameObject; - }, +/** + * Provides methods used for getting and setting the texture of a Game Object. + * + * @namespace Phaser.GameObjects.Components.TextureCrop + * @since 3.0.0 + */ + +var TextureCrop = { /** - * Advances the animation to the next frame, regardless of the time or animation state. - * If the animation is set to repeat, or yoyo, this will still take effect. - * - * Calling this does not change the direction of the animation. I.e. if it was currently - * playing in reverse, calling this method doesn't then change the direction to forwards. - * - * @method Phaser.Animations.AnimationState#nextFrame - * @since 3.16.0 + * The Texture this Game Object is using to render with. * - * @return {Phaser.GameObjects.GameObject} The Game Object this Animation Component belongs to. + * @name Phaser.GameObjects.Components.TextureCrop#texture + * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} + * @since 3.0.0 */ - nextFrame: function () - { - if (this.currentAnim) - { - this.currentAnim.nextFrame(this); - } - - return this.parent; - }, + texture: null, /** - * Advances the animation to the previous frame, regardless of the time or animation state. - * If the animation is set to repeat, or yoyo, this will still take effect. - * - * Calling this does not change the direction of the animation. I.e. if it was currently - * playing in forwards, calling this method doesn't then change the direction to backwards. - * - * @method Phaser.Animations.AnimationState#previousFrame - * @since 3.16.0 + * The Texture Frame this Game Object is using to render with. * - * @return {Phaser.GameObjects.GameObject} The Game Object this Animation Component belongs to. + * @name Phaser.GameObjects.Components.TextureCrop#frame + * @type {Phaser.Textures.Frame} + * @since 3.0.0 */ - previousFrame: function () - { - if (this.currentAnim) - { - this.currentAnim.previousFrame(this); - } - - return this.parent; - }, + frame: null, /** - * Get an Animation instance that has been created locally on this Sprite. - * - * See the `create` method for more details. - * - * @method Phaser.Animations.AnimationState#get - * @since 3.50.0 - * - * @param {string} key - The key of the Animation to retrieve. + * A boolean flag indicating if this Game Object is being cropped or not. + * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. + * Equally, calling `setCrop` with no arguments will reset the crop and disable it. * - * @return {Phaser.Animations.Animation} The Animation, or `null` if the key is invalid. + * @name Phaser.GameObjects.Components.TextureCrop#isCropped + * @type {boolean} + * @since 3.11.0 */ - get: function (key) - { - return (this.anims) ? this.anims.get(key) : null; - }, + isCropped: false, /** - * Checks to see if the given key is already used locally within the animations stored on this Sprite. + * Applies a crop to a texture based Game Object, such as a Sprite or Image. * - * @method Phaser.Animations.AnimationState#exists - * @since 3.50.0 + * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. * - * @param {string} key - The key of the Animation to check. + * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just + * changes what is shown when rendered. * - * @return {boolean} `true` if the Animation exists locally, or `false` if the key is available, or there are no local animations. - */ - exists: function (key) - { - return (this.anims) ? this.anims.has(key) : false; - }, - - /** - * Creates a new Animation that is local specifically to this Sprite. + * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. * - * When a Sprite owns an animation, it is kept out of the global Animation Manager, which means - * you're free to use keys that may be already defined there. Unless you specifically need a Sprite - * to have a unique animation, you should favor using global animations instead, as they allow for - * the same animation to be used across multiple Sprites, saving on memory. However, if this Sprite - * is the only one to use this animation, it's sensible to create it here. + * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left + * half of it, you could call `setCrop(0, 0, 400, 600)`. * - * If an invalid key is given this method will return `false`. + * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop + * an area of 200x100 when applied to a Game Object that had a scale factor of 2. * - * If you pass the key of an animation that already exists locally, that animation will be returned. + * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. * - * A brand new animation is only created if the key is valid and not already in use by this Sprite. + * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. * - * If you wish to re-use an existing key, call the `remove` method first, then this method. + * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow + * the renderer to skip several internal calculations. * - * @method Phaser.Animations.AnimationState#create - * @since 3.50.0 + * @method Phaser.GameObjects.Components.TextureCrop#setCrop + * @since 3.11.0 * - * @param {Phaser.Types.Animations.Animation} config - The configuration settings for the Animation. + * @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. + * @param {number} [y] - The y coordinate to start the crop from. + * @param {number} [width] - The width of the crop rectangle in pixels. + * @param {number} [height] - The height of the crop rectangle in pixels. * - * @return {(Phaser.Animations.Animation|false)} The Animation that was created, or `false` if the key is already in use. + * @return {this} This Game Object instance. */ - create: function (config) + setCrop: function (x, y, width, height) { - var key = config.key; - - var anim = false; - - if (key) + if (x === undefined) { - anim = this.get(key); - - if (!anim) + this.isCropped = false; + } + else if (this.frame) + { + if (typeof x === 'number') { - anim = new Animation(this, key, config); - - if (!this.anims) - { - this.anims = new CustomMap(); - } + this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY); + } + else + { + var rect = x; - this.anims.set(key, anim); + this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY); } + + this.isCropped = true; } - return anim; + return this; }, /** - * Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object. - * - * Generates objects with string based frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNames}. - * - * It's a helper method, designed to make it easier for you to extract all of the frame names from texture atlases. - * If you're working with a sprite sheet, see the `generateFrameNumbers` method instead. - * - * Example: - * - * If you have a texture atlases loaded called `gems` and it contains 6 frames called `ruby_0001`, `ruby_0002`, and so on, - * then you can call this method using: `this.anims.generateFrameNames('gems', { prefix: 'ruby_', end: 6, zeroPad: 4 })`. - * - * The `end` value tells it to look for 6 frames, incrementally numbered, all starting with the prefix `ruby_`. The `zeroPad` - * value tells it how many zeroes pad out the numbers. To create an animation using this method, you can do: - * - * ```javascript - * this.anims.create({ - * key: 'ruby', - * repeat: -1, - * frames: this.anims.generateFrameNames('gems', { - * prefix: 'ruby_', - * end: 6, - * zeroPad: 4 - * }) - * }); - * ``` + * Sets the texture and frame this Game Object will use to render with. * - * Please see the animation examples for further details. + * Textures are referenced by their string-based keys, as stored in the Texture Manager. * - * @method Phaser.Animations.AnimationState#generateFrameNames - * @since 3.50.0 + * @method Phaser.GameObjects.Components.TextureCrop#setTexture + * @since 3.0.0 * - * @param {string} key - The key for the texture containing the animation frames. - * @param {Phaser.Types.Animations.GenerateFrameNames} [config] - The configuration object for the animation frame names. + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. * - * @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects. + * @return {this} This Game Object instance. */ - generateFrameNames: function (key, config) + setTexture: function (key, frame) { - return this.animationManager.generateFrameNames(key, config); + this.texture = this.scene.sys.textures.get(key); + + return this.setFrame(frame); }, /** - * Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object. - * - * Generates objects with numbered frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNumbers}. - * - * If you're working with a texture atlas, see the `generateFrameNames` method instead. - * - * It's a helper method, designed to make it easier for you to extract frames from sprite sheets. - * If you're working with a texture atlas, see the `generateFrameNames` method instead. - * - * Example: - * - * If you have a sprite sheet loaded called `explosion` and it contains 12 frames, then you can call this method using: - * `this.anims.generateFrameNumbers('explosion', { start: 0, end: 12 })`. - * - * The `end` value tells it to stop after 12 frames. To create an animation using this method, you can do: - * - * ```javascript - * this.anims.create({ - * key: 'boom', - * frames: this.anims.generateFrameNames('explosion', { - * start: 0, - * end: 12 - * }) - * }); - * ``` - * - * Note that `start` is optional and you don't need to include it if the animation starts from frame 0. - * - * To specify an animation in reverse, swap the `start` and `end` values. - * - * If the frames are not sequential, you may pass an array of frame numbers instead, for example: - * - * `this.anims.generateFrameNumbers('explosion', { frames: [ 0, 1, 2, 1, 2, 3, 4, 0, 1, 2 ] })` - * - * Please see the animation examples and `GenerateFrameNumbers` config docs for further details. + * Sets the frame this Game Object will use to render with. * - * @method Phaser.Animations.AnimationState#generateFrameNumbers - * @since 3.50.0 + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * @param {string} key - The key for the texture containing the animation frames. - * @param {Phaser.Types.Animations.GenerateFrameNumbers} config - The configuration object for the animation frames. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * - * @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects. - */ - generateFrameNumbers: function (key, config) - { - return this.animationManager.generateFrameNumbers(key, config); - }, - - /** - * Removes a locally created Animation from this Sprite, based on the given key. + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. * - * Once an Animation has been removed, this Sprite cannot play it again without re-creating it. + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. * - * @method Phaser.Animations.AnimationState#remove - * @since 3.50.0 + * @method Phaser.GameObjects.Components.TextureCrop#setFrame + * @since 3.0.0 * - * @param {string} key - The key of the animation to remove. + * @param {(string|number|Phaser.Textures.Frame)} frame - The name or index of the frame within the Texture, or a Frame instance. + * @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object? + * @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object? * - * @return {Phaser.Animations.Animation} The Animation instance that was removed from this Sprite, if the key was valid. + * @return {this} This Game Object instance. */ - remove: function (key) + setFrame: function (frame, updateSize, updateOrigin) { - var anim = this.get(key); + if (updateSize === undefined) { updateSize = true; } + if (updateOrigin === undefined) { updateOrigin = true; } - if (anim) + if (frame instanceof Frame) { - if (this.currentAnim === anim) - { - this.stop(); - } + this.texture = this.scene.sys.textures.get(frame.texture.key); - this.anims.delete(key); + this.frame = frame; + } + else + { + this.frame = this.texture.get(frame); } - return anim; - }, + if (!this.frame.cutWidth || !this.frame.cutHeight) + { + this.renderFlags &= ~_FLAG; + } + else + { + this.renderFlags |= _FLAG; + } - /** - * Destroy this Animation component. - * - * Unregisters event listeners and cleans up its references. - * - * @method Phaser.Animations.AnimationState#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.animationManager.off(Events.REMOVE_ANIMATION, this.globalRemove, this); + if (this._sizeComponent && updateSize) + { + this.setSizeToFrame(); + } - if (this.anims) + if (this._originComponent && updateOrigin) { - this.anims.clear(); + if (this.frame.customPivot) + { + this.setOrigin(this.frame.pivotX, this.frame.pivotY); + } + else + { + this.updateDisplayOrigin(); + } } - this.animationManager = null; - this.parent = null; - this.nextAnim = null; - this.nextAnimsQueue.length = 0; + if (this.isCropped) + { + this.frame.updateCropUVs(this._crop, this.flipX, this.flipY); + } - this.currentAnim = null; - this.currentFrame = null; + return this; }, /** - * `true` if the current animation is paused, otherwise `false`. + * Internal method that returns a blank, well-formed crop object for use by a Game Object. * - * @name Phaser.Animations.AnimationState#isPaused - * @readonly - * @type {boolean} - * @since 3.4.0 + * @method Phaser.GameObjects.Components.TextureCrop#resetCropObject + * @private + * @since 3.12.0 + * + * @return {object} The crop object. */ - isPaused: { - - get: function () - { - return this._paused; - } - + resetCropObject: function () + { + return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 }; } -}); +}; -module.exports = AnimationState; +module.exports = TextureCrop; /***/ }), -/* 165 */ -/***/ (function(module, exports, __webpack_require__) { -/** -* The `Matter.Sleeping` module contains methods to manage the sleeping state of bodies. -* -* @class Sleeping -*/ +/***/ 58072: +/***/ ((module) => { -var Sleeping = {}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = Sleeping; +/** + * Provides methods used for setting the tint of a Game Object. + * Should be applied as a mixin and not used directly. + * + * @namespace Phaser.GameObjects.Components.Tint + * @webglOnly + * @since 3.0.0 + */ -var Events = __webpack_require__(166); +var Tint = { -(function() { + /** + * The tint value being applied to the top-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * + * @name Phaser.GameObjects.Components.Tint#tintTopLeft + * @type {number} + * @default 0xffffff + * @since 3.0.0 + */ + tintTopLeft: 0xffffff, - Sleeping._motionWakeThreshold = 0.18; - Sleeping._motionSleepThreshold = 0.08; - Sleeping._minBias = 0.9; + /** + * The tint value being applied to the top-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * + * @name Phaser.GameObjects.Components.Tint#tintTopRight + * @type {number} + * @default 0xffffff + * @since 3.0.0 + */ + tintTopRight: 0xffffff, /** - * Puts bodies to sleep or wakes them up depending on their motion. - * @method update - * @param {body[]} bodies - * @param {number} timeScale + * The tint value being applied to the bottom-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * + * @name Phaser.GameObjects.Components.Tint#tintBottomLeft + * @type {number} + * @default 0xffffff + * @since 3.0.0 */ - Sleeping.update = function(bodies, timeScale) { - var timeFactor = timeScale * timeScale * timeScale; + tintBottomLeft: 0xffffff, - // update bodies sleeping status - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i], - motion = body.speed * body.speed + body.angularSpeed * body.angularSpeed; - - // wake up bodies if they have a force applied - if (body.force.x !== 0 || body.force.y !== 0) { - Sleeping.set(body, false); - continue; - } - - var minMotion = Math.min(body.motion, motion), - maxMotion = Math.max(body.motion, motion); - - // biased average motion estimation between frames - body.motion = Sleeping._minBias * minMotion + (1 - Sleeping._minBias) * maxMotion; - - if (body.sleepThreshold > 0 && body.motion < Sleeping._motionSleepThreshold * timeFactor) { - body.sleepCounter += 1; - - if (body.sleepCounter >= body.sleepThreshold) - Sleeping.set(body, true); - } else if (body.sleepCounter > 0) { - body.sleepCounter -= 1; - } - } - }; + /** + * The tint value being applied to the bottom-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * + * @name Phaser.GameObjects.Components.Tint#tintBottomRight + * @type {number} + * @default 0xffffff + * @since 3.0.0 + */ + tintBottomRight: 0xffffff, /** - * Given a set of colliding pairs, wakes the sleeping bodies involved. - * @method afterCollisions - * @param {pair[]} pairs - * @param {number} timeScale + * The tint fill mode. + * + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + * + * @name Phaser.GameObjects.Components.Tint#tintFill + * @type {boolean} + * @default false + * @since 3.11.0 */ - Sleeping.afterCollisions = function(pairs, timeScale) { - var timeFactor = timeScale * timeScale * timeScale; - - // wake up bodies involved in collisions - for (var i = 0; i < pairs.length; i++) { - var pair = pairs[i]; - - // don't wake inactive pairs - if (!pair.isActive) - continue; - - var collision = pair.collision, - bodyA = collision.bodyA.parent, - bodyB = collision.bodyB.parent; - - // don't wake if at least one body is static - if ((bodyA.isSleeping && bodyB.isSleeping) || bodyA.isStatic || bodyB.isStatic) - continue; - - if (bodyA.isSleeping || bodyB.isSleeping) { - var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB, - movingBody = sleepingBody === bodyA ? bodyB : bodyA; + tintFill: false, - if (!sleepingBody.isStatic && movingBody.motion > Sleeping._motionWakeThreshold * timeFactor) { - Sleeping.set(sleepingBody, false); - } - } - } - }; - /** - * Set a body as sleeping or awake. - * @method set - * @param {body} body - * @param {boolean} isSleeping + * Clears all tint values associated with this Game Object. + * + * Immediately sets the color values back to 0xffffff and the tint type to 'additive', + * which results in no visible change to the texture. + * + * @method Phaser.GameObjects.Components.Tint#clearTint + * @webglOnly + * @since 3.0.0 + * + * @return {this} This Game Object instance. */ - Sleeping.set = function(body, isSleeping) { - var wasSleeping = body.isSleeping; - - if (isSleeping) { - body.isSleeping = true; - body.sleepCounter = body.sleepThreshold; - - body.positionImpulse.x = 0; - body.positionImpulse.y = 0; - - body.positionPrev.x = body.position.x; - body.positionPrev.y = body.position.y; + clearTint: function () + { + this.setTint(0xffffff); - body.anglePrev = body.angle; - body.speed = 0; - body.angularSpeed = 0; - body.motion = 0; + return this; + }, - if (!wasSleeping) { - Events.trigger(body, 'sleepStart'); - } - } else { - body.isSleeping = false; - body.sleepCounter = 0; + /** + * Sets an additive tint on this Game Object. + * + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole Game Object will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. + * + * @method Phaser.GameObjects.Components.Tint#setTint + * @webglOnly + * @since 3.0.0 + * + * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. + * @param {number} [topRight] - The tint being applied to the top-right of the Game Object. + * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the Game Object. + * @param {number} [bottomRight] - The tint being applied to the bottom-right of the Game Object. + * + * @return {this} This Game Object instance. + */ + setTint: function (topLeft, topRight, bottomLeft, bottomRight) + { + if (topLeft === undefined) { topLeft = 0xffffff; } - if (wasSleeping) { - Events.trigger(body, 'sleepEnd'); - } + if (topRight === undefined) + { + topRight = topLeft; + bottomLeft = topLeft; + bottomRight = topLeft; } - }; - -})(); + this.tintTopLeft = topLeft; + this.tintTopRight = topRight; + this.tintBottomLeft = bottomLeft; + this.tintBottomRight = bottomRight; -/***/ }), -/* 166 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.Events` module contains methods to fire and listen to events on other objects. -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Events -*/ + this.tintFill = false; -var Events = {}; + return this; + }, -module.exports = Events; + /** + * Sets a fill-based tint on this Game Object. + * + * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture + * with those in the tint. You can use this for effects such as making a player flash 'white' + * if hit by something. You can provide either one color value, in which case the whole + * Game Object will be rendered in that color. Or you can provide a color per corner. The colors + * are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. + * + * @method Phaser.GameObjects.Components.Tint#setTintFill + * @webglOnly + * @since 3.11.0 + * + * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. + * @param {number} [topRight] - The tint being applied to the top-right of the Game Object. + * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the Game Object. + * @param {number} [bottomRight] - The tint being applied to the bottom-right of the Game Object. + * + * @return {this} This Game Object instance. + */ + setTintFill: function (topLeft, topRight, bottomLeft, bottomRight) + { + this.setTint(topLeft, topRight, bottomLeft, bottomRight); -var Common = __webpack_require__(32); + this.tintFill = true; -(function() { + return this; + }, /** - * Subscribes a callback function to the given object's `eventName`. - * @method on - * @param {} object - * @param {string} eventNames - * @param {function} callback + * The tint value being applied to the whole of the Game Object. + * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. + * + * @name Phaser.GameObjects.Components.Tint#tint + * @type {number} + * @webglOnly + * @since 3.0.0 */ - Events.on = function(object, eventNames, callback) { - var names = eventNames.split(' '), - name; + tint: { - for (var i = 0; i < names.length; i++) { - name = names[i]; - object.events = object.events || {}; - object.events[name] = object.events[name] || []; - object.events[name].push(callback); + set: function (value) + { + this.setTint(value, value, value, value); } - - return callback; - }; + }, /** - * Removes the given event callback. If no callback, clears all callbacks in `eventNames`. If no `eventNames`, clears all events. - * @method off - * @param {} object - * @param {string} eventNames - * @param {function} callback + * Does this Game Object have a tint applied? + * + * It checks to see if the 4 tint properties are set to the value 0xffffff + * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. + * + * @name Phaser.GameObjects.Components.Tint#isTinted + * @type {boolean} + * @webglOnly + * @readonly + * @since 3.11.0 */ - Events.off = function(object, eventNames, callback) { - if (!eventNames) { - object.events = {}; - return; - } + isTinted: { - // handle Events.off(object, callback) - if (typeof eventNames === 'function') { - callback = eventNames; - eventNames = Common.keys(object.events).join(' '); + get: function () + { + var white = 0xffffff; + + return ( + this.tintFill || + this.tintTopLeft !== white || + this.tintTopRight !== white || + this.tintBottomLeft !== white || + this.tintBottomRight !== white + ); } - var names = eventNames.split(' '); + } - for (var i = 0; i < names.length; i++) { - var callbacks = object.events[names[i]], - newCallbacks = []; +}; - if (callback && callbacks) { - for (var j = 0; j < callbacks.length; j++) { - if (callbacks[j] !== callback) - newCallbacks.push(callbacks[j]); - } - } +module.exports = Tint; - object.events[names[i]] = newCallbacks; - } - }; - /** - * Fires all the callbacks subscribed to the given object's `eventName`, in the order they subscribed, if any. - * @method trigger - * @param {} object - * @param {string} eventNames - * @param {} event - */ - Events.trigger = function(object, eventNames, event) { - var names, - name, - callbacks, - eventClone; +/***/ }), - var events = object.events; - - if (events && Common.keys(events).length > 0) { - if (!event) - event = {}; +/***/ 48129: +/***/ ((module) => { - names = eventNames.split(' '); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (var i = 0; i < names.length; i++) { - name = names[i]; - callbacks = events[name]; +/** + * Build a JSON representation of the given Game Object. + * + * This is typically extended further by Game Object specific implementations. + * + * @method Phaser.GameObjects.Components.ToJSON + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to export as JSON. + * + * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object. + */ +var ToJSON = function (gameObject) +{ + var out = { + name: gameObject.name, + type: gameObject.type, + x: gameObject.x, + y: gameObject.y, + depth: gameObject.depth, + scale: { + x: gameObject.scaleX, + y: gameObject.scaleY + }, + origin: { + x: gameObject.originX, + y: gameObject.originY + }, + flipX: gameObject.flipX, + flipY: gameObject.flipY, + rotation: gameObject.rotation, + alpha: gameObject.alpha, + visible: gameObject.visible, + blendMode: gameObject.blendMode, + textureKey: '', + frameKey: '', + data: {} + }; - if (callbacks) { - eventClone = Common.clone(event, false); - eventClone.name = name; - eventClone.source = object; + if (gameObject.texture) + { + out.textureKey = gameObject.texture.key; + out.frameKey = gameObject.frame.name; + } - for (var j = 0; j < callbacks.length; j++) { - callbacks[j].apply(object, [eventClone]); - } - } - } - } - }; + return out; +}; -})(); +module.exports = ToJSON; /***/ }), -/* 167 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 56584: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DeepCopy = __webpack_require__(175); -var PIPELINE_CONST = __webpack_require__(92); -var SpliceOne = __webpack_require__(74); +var MATH_CONST = __webpack_require__(83392); +var TransformMatrix = __webpack_require__(69360); +var TransformXY = __webpack_require__(64462); +var WrapAngle = __webpack_require__(35786); +var WrapAngleDegrees = __webpack_require__(62138); +var Vector2 = __webpack_require__(93736); + +// global bitmask flag for GameObject.renderMask (used by Scale) +var _FLAG = 4; // 0100 /** - * Provides methods used for setting the WebGL rendering pipeline of a Game Object. + * Provides methods used for getting and setting the position, scale and rotation of a Game Object. * - * @namespace Phaser.GameObjects.Components.Pipeline - * @webglOnly + * @namespace Phaser.GameObjects.Components.Transform * @since 3.0.0 */ -var Pipeline = { +var Transform = { /** - * The initial WebGL pipeline of this Game Object. + * A property indicating that a Game Object has this component. * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + * @name Phaser.GameObjects.Components.Transform#hasTransformComponent + * @type {boolean} + * @readonly + * @default true + * @since 3.60.0 + */ + hasTransformComponent: true, + + /** + * Private internal value. Holds the horizontal scale value. * - * @name Phaser.GameObjects.Components.Pipeline#defaultPipeline - * @type {Phaser.Renderer.WebGL.WebGLPipeline} - * @default null - * @webglOnly + * @name Phaser.GameObjects.Components.Transform#_scaleX + * @type {number} + * @private + * @default 1 * @since 3.0.0 */ - defaultPipeline: null, + _scaleX: 1, /** - * The current WebGL pipeline of this Game Object. + * Private internal value. Holds the vertical scale value. * - * @name Phaser.GameObjects.Components.Pipeline#pipeline - * @type {Phaser.Renderer.WebGL.WebGLPipeline} - * @default null - * @webglOnly + * @name Phaser.GameObjects.Components.Transform#_scaleY + * @type {number} + * @private + * @default 1 * @since 3.0.0 */ - pipeline: null, + _scaleY: 1, /** - * Does this Game Object have any Post Pipelines set? + * Private internal value. Holds the rotation value in radians. * - * @name Phaser.GameObjects.Components.Pipeline#hasPostPipeline - * @type {boolean} - * @webglOnly - * @since 3.50.0 + * @name Phaser.GameObjects.Components.Transform#_rotation + * @type {number} + * @private + * @default 0 + * @since 3.0.0 */ - hasPostPipeline: false, + _rotation: 0, /** - * The WebGL Post FX Pipelines this Game Object uses for post-render effects. - * - * The pipelines are processed in the order in which they appear in this array. - * - * If you modify this array directly, be sure to set the - * `hasPostPipeline` property accordingly. + * The x position of this Game Object. * - * @name Phaser.GameObjects.Components.Pipeline#postPipelines - * @type {Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]} - * @webglOnly - * @since 3.50.0 + * @name Phaser.GameObjects.Components.Transform#x + * @type {number} + * @default 0 + * @since 3.0.0 */ - postPipelines: null, + x: 0, /** - * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + * The y position of this Game Object. * - * @name Phaser.GameObjects.Components.Pipeline#pipelineData - * @type {object} - * @webglOnly - * @since 3.50.0 + * @name Phaser.GameObjects.Components.Transform#y + * @type {number} + * @default 0 + * @since 3.0.0 */ - pipelineData: null, + y: 0, /** - * Sets the initial WebGL Pipeline of this Game Object. + * The z position of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. * - * @method Phaser.GameObjects.Components.Pipeline#initPipeline - * @webglOnly + * @name Phaser.GameObjects.Components.Transform#z + * @type {number} + * @default 0 * @since 3.0.0 + */ + z: 0, + + /** + * The w position of this Game Object. * - * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline, or a pipeline instance to set. + * @name Phaser.GameObjects.Components.Transform#w + * @type {number} + * @default 0 + * @since 3.0.0 + */ + w: 0, + + /** + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. * - * @return {boolean} `true` if the pipeline was set successfully, otherwise `false`. + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. + * + * @name Phaser.GameObjects.Components.Transform#scale + * @type {number} + * @default 1 + * @since 3.18.0 */ - initPipeline: function (pipeline) - { - if (pipeline === undefined) { pipeline = PIPELINE_CONST.MULTI_PIPELINE; } + scale: { - var renderer = this.scene.sys.renderer; + get: function () + { + return (this._scaleX + this._scaleY) / 2; + }, - if (!renderer) + set: function (value) { - return false; + this._scaleX = value; + this._scaleY = value; + + if (value === 0) + { + this.renderFlags &= ~_FLAG; + } + else + { + this.renderFlags |= _FLAG; + } } - var pipelines = renderer.pipelines; + }, - this.postPipelines = []; - this.pipelineData = {}; + /** + * The horizontal scale of this Game Object. + * + * @name Phaser.GameObjects.Components.Transform#scaleX + * @type {number} + * @default 1 + * @since 3.0.0 + */ + scaleX: { - if (pipelines) + get: function () { - var instance = pipelines.get(pipeline); + return this._scaleX; + }, - if (instance) + set: function (value) + { + this._scaleX = value; + + if (value === 0) { - this.defaultPipeline = instance; - this.pipeline = instance; + this.renderFlags &= ~_FLAG; + } + else if (this._scaleY !== 0) + { + this.renderFlags |= _FLAG; + } + } - return true; + }, + + /** + * The vertical scale of this Game Object. + * + * @name Phaser.GameObjects.Components.Transform#scaleY + * @type {number} + * @default 1 + * @since 3.0.0 + */ + scaleY: { + + get: function () + { + return this._scaleY; + }, + + set: function (value) + { + this._scaleY = value; + + if (value === 0) + { + this.renderFlags &= ~_FLAG; + } + else if (this._scaleX !== 0) + { + this.renderFlags |= _FLAG; } } - return false; }, /** - * Sets the main WebGL Pipeline of this Game Object. + * The angle of this Game Object as expressed in degrees. * - * Also sets the `pipelineData` property, if the parameter is given. + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. * - * Both the pipeline and post pipelines share the same pipeline data object. + * If you prefer to work in radians, see the `rotation` property instead. * - * @method Phaser.GameObjects.Components.Pipeline#setPipeline - * @webglOnly + * @name Phaser.GameObjects.Components.Transform#angle + * @type {number} + * @default 0 * @since 3.0.0 - * - * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline, or a pipeline instance to set. - * @param {object} [pipelineData] - Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param {boolean} [copyData=true] - Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. - * - * @return {this} This Game Object instance. */ - setPipeline: function (pipeline, pipelineData, copyData) - { - var renderer = this.scene.sys.renderer; + angle: { - if (!renderer) + get: function () { - return this; + return WrapAngleDegrees(this._rotation * MATH_CONST.RAD_TO_DEG); + }, + + set: function (value) + { + // value is in degrees + this.rotation = WrapAngleDegrees(value) * MATH_CONST.DEG_TO_RAD; } + }, - var pipelines = renderer.pipelines; + /** + * The angle of this Game Object in radians. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. + * + * @name Phaser.GameObjects.Components.Transform#rotation + * @type {number} + * @default 1 + * @since 3.0.0 + */ + rotation: { - if (pipelines) + get: function () { - var instance = pipelines.get(pipeline); - - if (instance) - { - this.pipeline = instance; - } + return this._rotation; + }, - if (pipelineData) - { - this.pipelineData = (copyData) ? DeepCopy(pipelineData) : pipelineData; - } + set: function (value) + { + // value is in radians + this._rotation = WrapAngle(value); } + }, + + /** + * Sets the position of this Game Object. + * + * @method Phaser.GameObjects.Components.Transform#setPosition + * @since 3.0.0 + * + * @param {number} [x=0] - The x position of this Game Object. + * @param {number} [y=x] - The y position of this Game Object. If not set it will use the `x` value. + * @param {number} [z=0] - The z position of this Game Object. + * @param {number} [w=0] - The w position of this Game Object. + * + * @return {this} This Game Object instance. + */ + setPosition: function (x, y, z, w) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } + if (z === undefined) { z = 0; } + if (w === undefined) { w = 0; } + + this.x = x; + this.y = y; + this.z = z; + this.w = w; return this; }, /** - * Sets one, or more, Post Pipelines on this Game Object. + * Copies an object's coordinates to this Game Object's position. * - * Post Pipelines are invoked after this Game Object has rendered to its target and - * are commonly used for post-fx. + * @method Phaser.GameObjects.Components.Transform#copyPosition + * @since 3.50.0 * - * The post pipelines are appended to the `postPipelines` array belonging to this - * Game Object. When the renderer processes this Game Object, it iterates through the post - * pipelines in the order in which they appear in the array. If you are stacking together - * multiple effects, be aware that the order is important. + * @param {(Phaser.Types.Math.Vector2Like|Phaser.Types.Math.Vector3Like|Phaser.Types.Math.Vector4Like)} source - An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. * - * If you call this method multiple times, the new pipelines will be appended to any existing - * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * @return {this} This Game Object instance. + */ + copyPosition: function (source) + { + if (source.x !== undefined) { this.x = source.x; } + if (source.y !== undefined) { this.y = source.y; } + if (source.z !== undefined) { this.z = source.z; } + if (source.w !== undefined) { this.w = source.w; } + + return this; + }, + + /** + * Sets the position of this Game Object to be a random position within the confines of + * the given area. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. * - * Both the pipeline and post pipelines share the pipeline data object together. + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. * - * @method Phaser.GameObjects.Components.Pipeline#setPostPipeline - * @webglOnly - * @since 3.50.0 + * @method Phaser.GameObjects.Components.Transform#setRandomPosition + * @since 3.8.0 * - * @param {(string|string[]|function|function[]|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[])} pipelines - Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param {object} [pipelineData] - Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param {boolean} [copyData=true] - Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. + * @param {number} [x=0] - The x position of the top-left of the random area. + * @param {number} [y=0] - The y position of the top-left of the random area. + * @param {number} [width] - The width of the random area. + * @param {number} [height] - The height of the random area. * * @return {this} This Game Object instance. */ - setPostPipeline: function (pipelines, pipelineData, copyData) + setRandomPosition: function (x, y, width, height) { - var renderer = this.scene.sys.renderer; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.scene.sys.scale.width; } + if (height === undefined) { height = this.scene.sys.scale.height; } - if (!renderer) - { - return this; - } + this.x = x + (Math.random() * width); + this.y = y + (Math.random() * height); - var pipelineManager = renderer.pipelines; + return this; + }, - if (pipelineManager) - { - if (!Array.isArray(pipelines)) - { - pipelines = [ pipelines ]; - } + /** + * Sets the rotation of this Game Object. + * + * @method Phaser.GameObjects.Components.Transform#setRotation + * @since 3.0.0 + * + * @param {number} [radians=0] - The rotation of this Game Object, in radians. + * + * @return {this} This Game Object instance. + */ + setRotation: function (radians) + { + if (radians === undefined) { radians = 0; } - for (var i = 0; i < pipelines.length; i++) - { - var instance = pipelineManager.getPostPipeline(pipelines[i], this); + this.rotation = radians; - if (instance) - { - this.postPipelines.push(instance); - } - } + return this; + }, - if (pipelineData) - { - this.pipelineData = (copyData) ? DeepCopy(pipelineData) : pipelineData; - } - } + /** + * Sets the angle of this Game Object. + * + * @method Phaser.GameObjects.Components.Transform#setAngle + * @since 3.0.0 + * + * @param {number} [degrees=0] - The rotation of this Game Object, in degrees. + * + * @return {this} This Game Object instance. + */ + setAngle: function (degrees) + { + if (degrees === undefined) { degrees = 0; } - this.hasPostPipeline = (this.postPipelines.length > 0); + this.angle = degrees; return this; }, /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Sets the scale of this Game Object. * - * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * @method Phaser.GameObjects.Components.Transform#setScale + * @since 3.0.0 * - * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param {number} [x=1] - The horizontal scale of this Game Object. + * @param {number} [y=x] - The vertical scale of this Game Object. If not set it will use the `x` value. * - * Both the pipeline and post pipelines share the pipeline data object together. + * @return {this} This Game Object instance. + */ + setScale: function (x, y) + { + if (x === undefined) { x = 1; } + if (y === undefined) { y = x; } + + this.scaleX = x; + this.scaleY = y; + + return this; + }, + + /** + * Sets the x position of this Game Object. * - * @method Phaser.GameObjects.Components.Pipeline#setPipelineData - * @webglOnly - * @since 3.50.0 + * @method Phaser.GameObjects.Components.Transform#setX + * @since 3.0.0 * - * @param {string} key - The key of the pipeline data to set, update, or delete. - * @param {any} [value] - The value to be set with the key. If `undefined` then `key` will be deleted from the object. + * @param {number} [value=0] - The x position of this Game Object. * * @return {this} This Game Object instance. */ - setPipelineData: function (key, value) + setX: function (value) { - var data = this.pipelineData; + if (value === undefined) { value = 0; } - if (value === undefined) - { - delete data[key]; - } - else - { - data[key] = value; - } + this.x = value; return this; }, /** - * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * Sets the y position of this Game Object. * - * @method Phaser.GameObjects.Components.Pipeline#getPostPipeline - * @webglOnly - * @since 3.50.0 + * @method Phaser.GameObjects.Components.Transform#setY + * @since 3.0.0 * - * @param {(string|function|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline)} pipeline - The string-based name of the pipeline, or a pipeline class. + * @param {number} [value=0] - The y position of this Game Object. * - * @return {(Phaser.Renderer.WebGL.Pipelines.PostFXPipeline|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[])} The Post Pipeline/s matching the name, or undefined if no match. If more than one match they are returned in an array. + * @return {this} This Game Object instance. */ - getPostPipeline: function (pipeline) + setY: function (value) { - var pipelines = this.postPipelines; + if (value === undefined) { value = 0; } - var results = []; + this.y = value; - for (var i = 0; i < pipelines.length; i++) - { - var instance = pipelines[i]; + return this; + }, - if ((typeof pipeline === 'string' && instance.name === pipeline) || instance instanceof pipeline) - { - results.push(instance); - } - } + /** + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * + * @method Phaser.GameObjects.Components.Transform#setZ + * @since 3.0.0 + * + * @param {number} [value=0] - The z position of this Game Object. + * + * @return {this} This Game Object instance. + */ + setZ: function (value) + { + if (value === undefined) { value = 0; } - return (results.length === 1) ? results[0] : results; + this.z = value; + + return this; }, /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * Sets the w position of this Game Object. * - * @method Phaser.GameObjects.Components.Pipeline#resetPipeline - * @webglOnly + * @method Phaser.GameObjects.Components.Transform#setW * @since 3.0.0 * - * @param {boolean} [resetPostPipelines=false] - Reset all of the post pipelines? - * @param {boolean} [resetData=false] - Reset the `pipelineData` object to being an empty object? + * @param {number} [value=0] - The w position of this Game Object. * - * @return {boolean} `true` if the pipeline was reset successfully, otherwise `false`. + * @return {this} This Game Object instance. */ - resetPipeline: function (resetPostPipelines, resetData) + setW: function (value) { - if (resetPostPipelines === undefined) { resetPostPipelines = false; } - if (resetData === undefined) { resetData = false; } + if (value === undefined) { value = 0; } - this.pipeline = this.defaultPipeline; + this.w = value; - if (resetPostPipelines) - { - this.postPipelines = []; - this.hasPostPipeline = false; - } + return this; + }, - if (resetData) - { - this.pipelineData = {}; - } + /** + * Gets the local transform matrix for this Game Object. + * + * @method Phaser.GameObjects.Components.Transform#getLocalTransformMatrix + * @since 3.4.0 + * + * @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object. + * + * @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix. + */ + getLocalTransformMatrix: function (tempMatrix) + { + if (tempMatrix === undefined) { tempMatrix = new TransformMatrix(); } - return (this.pipeline !== null); + return tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY); }, /** - * Resets the WebGL Post Pipelines of this Game Object. It does this by calling - * the `destroy` method on each post pipeline and then clearing the local array. + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. * - * @method Phaser.GameObjects.Components.Pipeline#resetPostPipeline - * @webglOnly - * @since 3.50.0 + * @method Phaser.GameObjects.Components.Transform#getWorldTransformMatrix + * @since 3.4.0 * - * @param {boolean} [resetData=false] - Reset the `pipelineData` object to being an empty object? + * @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object. + * @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - A temporary matrix to hold parent values during the calculations. + * + * @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix. */ - resetPostPipeline: function (resetData) + getWorldTransformMatrix: function (tempMatrix, parentMatrix) { - if (resetData === undefined) { resetData = false; } + if (tempMatrix === undefined) { tempMatrix = new TransformMatrix(); } - var pipelines = this.postPipelines; + var parent = this.parentContainer; - for (var i = 0; i < pipelines.length; i++) + if (!parent) { - pipelines[i].destroy(); + return this.getLocalTransformMatrix(tempMatrix); } - this.postPipelines = []; - this.hasPostPipeline = false; + if (!parentMatrix) + { + parentMatrix = new TransformMatrix(); + } - if (resetData) + tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY); + + while (parent) { - this.pipelineData = {}; + parentMatrix.applyITRS(parent.x, parent.y, parent._rotation, parent._scaleX, parent._scaleY); + + parentMatrix.multiply(tempMatrix, tempMatrix); + + parent = parent.parentContainer; } + + return tempMatrix; }, /** - * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. * - * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. + * The returned Vector2 contains the translated point in its properties. * - * @method Phaser.GameObjects.Components.Pipeline#removePostPipeline - * @webglOnly + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * + * @method Phaser.GameObjects.Components.Transform#getLocalPoint * @since 3.50.0 * - * @param {string|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} pipeline - The string-based name of the pipeline, or a pipeline class. + * @param {number} x - The x position to translate. + * @param {number} y - The y position to translate. + * @param {Phaser.Math.Vector2} [point] - A Vector2, or point-like object, to store the results in. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera. * - * @return {this} This Game Object. + * @return {Phaser.Math.Vector2} The translated point. */ - removePostPipeline: function (pipeline) + getLocalPoint: function (x, y, point, camera) { - var pipelines = this.postPipelines; + if (!point) { point = new Vector2(); } + if (!camera) { camera = this.scene.sys.cameras.main; } - for (var i = pipelines.length - 1; i >= 0; i--) - { - var instance = pipelines[i]; + var csx = camera.scrollX; + var csy = camera.scrollY; - if ( - (typeof pipeline === 'string' && instance.name === pipeline) || - (typeof pipeline !== 'string' && instance instanceof pipeline)) - { - instance.destroy(); + var px = x + (csx * this.scrollFactorX) - csx; + var py = y + (csy * this.scrollFactorY) - csy; - SpliceOne(pipelines, i); - } + if (this.parentContainer) + { + this.getWorldTransformMatrix().applyInverse(px, py, point); + } + else + { + TransformXY(px, py, this.x, this.y, this.rotation, this.scaleX, this.scaleY, point); } - this.hasPostPipeline = (this.postPipelines.length > 0); + // Normalize origin + if (this._originComponent) + { + point.x += this._displayOriginX; + point.y += this._displayOriginY; + } - return this; + return point; }, /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Gets the sum total rotation of all of this Game Objects parent Containers. * - * @method Phaser.GameObjects.Components.Pipeline#getPipelineName - * @webglOnly - * @since 3.0.0 + * The returned value is in radians and will be zero if this Game Object has no parent container. * - * @return {string} The string-based name of the pipeline being used by this Game Object. + * @method Phaser.GameObjects.Components.Transform#getParentRotation + * @since 3.18.0 + * + * @return {number} The sum total rotation, in radians, of all parent containers of this Game Object. */ - getPipelineName: function () + getParentRotation: function () { - return this.pipeline.name; + var rotation = 0; + + var parent = this.parentContainer; + + while (parent) + { + rotation += parent.rotation; + + parent = parent.parentContainer; + } + + return rotation; } }; -module.exports = Pipeline; +module.exports = Transform; /***/ }), -/* 168 */ -/***/ (function(module, exports) { + +/***/ 69360: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var MATH_CONST = __webpack_require__(83392); +var Vector2 = __webpack_require__(93736); + /** - * Phaser Scale Modes. - * - * @namespace Phaser.ScaleModes + * @classdesc + * A Matrix used for display transformations for rendering. + * + * It is represented like so: + * + * ``` + * | a | c | tx | + * | b | d | ty | + * | 0 | 0 | 1 | + * ``` + * + * @class TransformMatrix + * @memberof Phaser.GameObjects.Components + * @constructor * @since 3.0.0 + * + * @param {number} [a=1] - The Scale X value. + * @param {number} [b=0] - The Skew Y value. + * @param {number} [c=0] - The Skew X value. + * @param {number} [d=1] - The Scale Y value. + * @param {number} [tx=0] - The Translate X value. + * @param {number} [ty=0] - The Translate Y value. */ +var TransformMatrix = new Class({ -var ScaleModes = { + initialize: - /** - * Default Scale Mode (Linear). - * - * @name Phaser.ScaleModes.DEFAULT - * @type {number} - * @readonly - * @since 3.0.0 - */ - DEFAULT: 0, + function TransformMatrix (a, b, c, d, tx, ty) + { + if (a === undefined) { a = 1; } + if (b === undefined) { b = 0; } + if (c === undefined) { c = 0; } + if (d === undefined) { d = 1; } + if (tx === undefined) { tx = 0; } + if (ty === undefined) { ty = 0; } - /** - * Linear Scale Mode. - * - * @name Phaser.ScaleModes.LINEAR - * @type {number} - * @readonly - * @since 3.0.0 - */ - LINEAR: 0, + /** + * The matrix values. + * + * @name Phaser.GameObjects.Components.TransformMatrix#matrix + * @type {Float32Array} + * @since 3.0.0 + */ + this.matrix = new Float32Array([ a, b, c, d, tx, ty, 0, 0, 1 ]); + + /** + * The decomposed matrix. + * + * @name Phaser.GameObjects.Components.TransformMatrix#decomposedMatrix + * @type {object} + * @since 3.0.0 + */ + this.decomposedMatrix = { + translateX: 0, + translateY: 0, + scaleX: 1, + scaleY: 1, + rotation: 0 + }; + + /** + * The temporary quad value cache. + * + * @name Phaser.GameObjects.Components.TransformMatrix#quad + * @type {Float32Array} + * @since 3.60.0 + */ + this.quad = new Float32Array(8); + }, /** - * Nearest Scale Mode. - * - * @name Phaser.ScaleModes.NEAREST + * The Scale X value. + * + * @name Phaser.GameObjects.Components.TransformMatrix#a * @type {number} - * @readonly - * @since 3.0.0 + * @since 3.4.0 */ - NEAREST: 1 + a: { -}; + get: function () + { + return this.matrix[0]; + }, -module.exports = ScaleModes; + set: function (value) + { + this.matrix[0] = value; + } + }, -/***/ }), -/* 169 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The Skew Y value. + * + * @name Phaser.GameObjects.Components.TransformMatrix#b + * @type {number} + * @since 3.4.0 + */ + b: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this.matrix[1]; + }, -var Point = __webpack_require__(4); + set: function (value) + { + this.matrix[1] = value; + } -/** - * Returns a Point object containing the coordinates of a point on the circumference of the Circle based on the given angle. - * - * @function Phaser.Geom.Circle.CircumferencePoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Circle} circle - The Circle to get the circumference point on. - * @param {number} angle - The angle from the center of the Circle to the circumference to return the point from. Given in radians. - * @param {(Phaser.Geom.Point|object)} [out] - A Point, or point-like object, to store the results in. If not given a Point will be created. - * - * @return {(Phaser.Geom.Point|object)} A Point object where the `x` and `y` properties are the point on the circumference. - */ -var CircumferencePoint = function (circle, angle, out) -{ - if (out === undefined) { out = new Point(); } + }, - out.x = circle.x + (circle.radius * Math.cos(angle)); - out.y = circle.y + (circle.radius * Math.sin(angle)); + /** + * The Skew X value. + * + * @name Phaser.GameObjects.Components.TransformMatrix#c + * @type {number} + * @since 3.4.0 + */ + c: { - return out; -}; + get: function () + { + return this.matrix[2]; + }, -module.exports = CircumferencePoint; + set: function (value) + { + this.matrix[2] = value; + } + }, -/***/ }), -/* 170 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The Scale Y value. + * + * @name Phaser.GameObjects.Components.TransformMatrix#d + * @type {number} + * @since 3.4.0 + */ + d: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this.matrix[3]; + }, -var Point = __webpack_require__(4); + set: function (value) + { + this.matrix[3] = value; + } -/** - * Returns a uniformly distributed random point from anywhere within the given Circle. - * - * @function Phaser.Geom.Circle.Random - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Circle} circle - The Circle to get a random point from. - * @param {(Phaser.Geom.Point|object)} [out] - 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. - */ -var Random = function (circle, out) -{ - if (out === undefined) { out = new Point(); } + }, - var t = 2 * Math.PI * Math.random(); - var u = Math.random() + Math.random(); - var r = (u > 1) ? 2 - u : u; - var x = r * Math.cos(t); - var y = r * Math.sin(t); + /** + * The Translate X value. + * + * @name Phaser.GameObjects.Components.TransformMatrix#e + * @type {number} + * @since 3.11.0 + */ + e: { - out.x = circle.x + (x * circle.radius); - out.y = circle.y + (y * circle.radius); + get: function () + { + return this.matrix[4]; + }, - return out; -}; + set: function (value) + { + this.matrix[4] = value; + } -module.exports = Random; + }, + /** + * The Translate Y value. + * + * @name Phaser.GameObjects.Components.TransformMatrix#f + * @type {number} + * @since 3.11.0 + */ + f: { -/***/ }), -/* 171 */ -/***/ (function(module, exports, __webpack_require__) { + get: function () + { + return this.matrix[5]; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + set: function (value) + { + this.matrix[5] = value; + } -var Perimeter = __webpack_require__(130); -var Point = __webpack_require__(4); + }, -/** - * Calculates the coordinates of a point at a certain `position` on the Rectangle's perimeter. - * - * The `position` is a fraction between 0 and 1 which defines how far into the perimeter the point is. - * - * A value of 0 or 1 returns the point at the top left corner of the rectangle, while a value of 0.5 returns the point at the bottom right corner of the rectangle. Values between 0 and 0.5 are on the top or the right side and values between 0.5 and 1 are on the bottom or the left side. - * - * @function Phaser.Geom.Rectangle.GetPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Rectangle} rectangle - The Rectangle to get the perimeter point from. - * @param {number} position - The normalized distance into the Rectangle's perimeter to return. - * @param {(Phaser.Geom.Point|object)} [out] - An object to update with the `x` and `y` coordinates of the point. - * - * @return {Phaser.Geom.Point} The updated `output` object, or a new Point if no `output` object was given. - */ -var GetPoint = function (rectangle, position, out) -{ - if (out === undefined) { out = new Point(); } + /** + * The Translate X value. + * + * @name Phaser.GameObjects.Components.TransformMatrix#tx + * @type {number} + * @since 3.4.0 + */ + tx: { - if (position <= 0 || position >= 1) - { - out.x = rectangle.x; - out.y = rectangle.y; + get: function () + { + return this.matrix[4]; + }, - return out; - } + set: function (value) + { + this.matrix[4] = value; + } - var p = Perimeter(rectangle) * position; + }, - if (position > 0.5) - { - p -= (rectangle.width + rectangle.height); + /** + * The Translate Y value. + * + * @name Phaser.GameObjects.Components.TransformMatrix#ty + * @type {number} + * @since 3.4.0 + */ + ty: { - if (p <= rectangle.width) + get: function () { - // Face 3 - out.x = rectangle.right - p; - out.y = rectangle.bottom; - } - else + return this.matrix[5]; + }, + + set: function (value) { - // Face 4 - out.x = rectangle.x; - out.y = rectangle.bottom - (p - rectangle.width); + this.matrix[5] = value; } - } - else if (p <= rectangle.width) - { - // Face 1 - out.x = rectangle.x + p; - out.y = rectangle.y; - } - else - { - // Face 2 - out.x = rectangle.right; - out.y = rectangle.y + (p - rectangle.width); - } - - return out; -}; -module.exports = GetPoint; + }, + /** + * The rotation of the Matrix. Value is in radians. + * + * @name Phaser.GameObjects.Components.TransformMatrix#rotation + * @type {number} + * @readonly + * @since 3.4.0 + */ + rotation: { -/***/ }), -/* 172 */ -/***/ (function(module, exports, __webpack_require__) { + get: function () + { + return Math.acos(this.a / this.scaleX) * ((Math.atan(-this.c / this.a) < 0) ? -1 : 1); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + }, -var Length = __webpack_require__(67); -var Point = __webpack_require__(4); + /** + * The rotation of the Matrix, normalized to be within the Phaser right-handed + * clockwise rotation space. Value is in radians. + * + * @name Phaser.GameObjects.Components.TransformMatrix#rotationNormalized + * @type {number} + * @readonly + * @since 3.19.0 + */ + rotationNormalized: { -/** - * Get a number of points along a line's length. - * - * Provide a `quantity` to get an exact number of points along the line. - * - * Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when - * providing a `stepRate`. - * - * @function Phaser.Geom.Line.GetPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point[]} O - [out,$return] - * - * @param {Phaser.Geom.Line} line - The line. - * @param {number} quantity - The number of points to place on the line. Set to `0` to use `stepRate` instead. - * @param {number} [stepRate] - The distance between each point on the line. When set, `quantity` is implied and should be set to `0`. - * @param {(array|Phaser.Geom.Point[])} [out] - An optional array of Points, or point-like objects, to store the coordinates of the points on the line. - * - * @return {(array|Phaser.Geom.Point[])} An array of Points, or point-like objects, containing the coordinates of the points on the line. - */ -var GetPoints = function (line, quantity, stepRate, out) -{ - if (out === undefined) { out = []; } + get: function () + { + var matrix = this.matrix; - // If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. - if (!quantity && stepRate > 0) - { - quantity = Length(line) / stepRate; - } + var a = matrix[0]; + var b = matrix[1]; + var c = matrix[2]; + var d = matrix[3]; - var x1 = line.x1; - var y1 = line.y1; + if (a || b) + { + // var r = Math.sqrt(a * a + b * b); - var x2 = line.x2; - var y2 = line.y2; + return (b > 0) ? Math.acos(a / this.scaleX) : -Math.acos(a / this.scaleX); + } + else if (c || d) + { + // var s = Math.sqrt(c * c + d * d); - for (var i = 0; i < quantity; i++) - { - var position = i / quantity; + return MATH_CONST.TAU - ((d > 0) ? Math.acos(-c / this.scaleY) : -Math.acos(c / this.scaleY)); + } + else + { + return 0; + } + } - var x = x1 + (x2 - x1) * position; - var y = y1 + (y2 - y1) * position; + }, - out.push(new Point(x, y)); - } + /** + * The decomposed horizontal scale of the Matrix. This value is always positive. + * + * @name Phaser.GameObjects.Components.TransformMatrix#scaleX + * @type {number} + * @readonly + * @since 3.4.0 + */ + scaleX: { - return out; -}; + get: function () + { + return Math.sqrt((this.a * this.a) + (this.b * this.b)); + } -module.exports = GetPoints; + }, + /** + * The decomposed vertical scale of the Matrix. This value is always positive. + * + * @name Phaser.GameObjects.Components.TransformMatrix#scaleY + * @type {number} + * @readonly + * @since 3.4.0 + */ + scaleY: { -/***/ }), -/* 173 */ -/***/ (function(module, exports, __webpack_require__) { + get: function () + { + return Math.sqrt((this.c * this.c) + (this.d * this.d)); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + }, -var Point = __webpack_require__(4); + /** + * Reset the Matrix to an identity matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#loadIdentity + * @since 3.0.0 + * + * @return {this} This TransformMatrix. + */ + loadIdentity: function () + { + var matrix = this.matrix; -/** - * Returns a random point on a given Line. - * - * @function Phaser.Geom.Line.Random - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Line} line - The Line to calculate the random Point on. - * @param {(Phaser.Geom.Point|object)} [out] - An instance of a Point to be modified. - * - * @return {(Phaser.Geom.Point|object)} A random Point on the Line. - */ -var Random = function (line, out) -{ - if (out === undefined) { out = new Point(); } + matrix[0] = 1; + matrix[1] = 0; + matrix[2] = 0; + matrix[3] = 1; + matrix[4] = 0; + matrix[5] = 0; - var t = Math.random(); + return this; + }, - out.x = line.x1 + t * (line.x2 - line.x1); - out.y = line.y1 + t * (line.y2 - line.y1); + /** + * Translate the Matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#translate + * @since 3.0.0 + * + * @param {number} x - The horizontal translation value. + * @param {number} y - The vertical translation value. + * + * @return {this} This TransformMatrix. + */ + translate: function (x, y) + { + var matrix = this.matrix; - return out; -}; + matrix[4] = matrix[0] * x + matrix[2] * y + matrix[4]; + matrix[5] = matrix[1] * x + matrix[3] * y + matrix[5]; -module.exports = Random; + return this; + }, + /** + * Scale the Matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#scale + * @since 3.0.0 + * + * @param {number} x - The horizontal scale value. + * @param {number} y - The vertical scale value. + * + * @return {this} This TransformMatrix. + */ + scale: function (x, y) + { + var matrix = this.matrix; -/***/ }), -/* 174 */ -/***/ (function(module, exports, __webpack_require__) { + matrix[0] *= x; + matrix[1] *= x; + matrix[2] *= y; + matrix[3] *= y; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var Point = __webpack_require__(4); + /** + * Rotate the Matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#rotate + * @since 3.0.0 + * + * @param {number} angle - The angle of rotation in radians. + * + * @return {this} This TransformMatrix. + */ + rotate: function (angle) + { + var sin = Math.sin(angle); + var cos = Math.cos(angle); -/** - * Returns a random point within a Rectangle. - * - * @function Phaser.Geom.Rectangle.Random - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to return a point from. - * @param {Phaser.Geom.Point} out - The object to update with the point's coordinates. - * - * @return {Phaser.Geom.Point} The modified `out` object, or a new Point if none was provided. - */ -var Random = function (rect, out) -{ - if (out === undefined) { out = new Point(); } + var matrix = this.matrix; - out.x = rect.x + (Math.random() * rect.width); - out.y = rect.y + (Math.random() * rect.height); + var a = matrix[0]; + var b = matrix[1]; + var c = matrix[2]; + var d = matrix[3]; - return out; -}; + matrix[0] = a * cos + c * sin; + matrix[1] = b * cos + d * sin; + matrix[2] = a * -sin + c * cos; + matrix[3] = b * -sin + d * cos; -module.exports = Random; + return this; + }, + /** + * Multiply this Matrix by the given Matrix. + * + * If an `out` Matrix is given then the results will be stored in it. + * If it is not given, this matrix will be updated in place instead. + * Use an `out` Matrix if you do not wish to mutate this matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#multiply + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Components.TransformMatrix} rhs - The Matrix to multiply by. + * @param {Phaser.GameObjects.Components.TransformMatrix} [out] - An optional Matrix to store the results in. + * + * @return {(this|Phaser.GameObjects.Components.TransformMatrix)} Either this TransformMatrix, or the `out` Matrix, if given in the arguments. + */ + multiply: function (rhs, out) + { + var matrix = this.matrix; + var source = rhs.matrix; -/***/ }), -/* 175 */ -/***/ (function(module, exports) { + var localA = matrix[0]; + var localB = matrix[1]; + var localC = matrix[2]; + var localD = matrix[3]; + var localE = matrix[4]; + var localF = matrix[5]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var sourceA = source[0]; + var sourceB = source[1]; + var sourceC = source[2]; + var sourceD = source[3]; + var sourceE = source[4]; + var sourceF = source[5]; -/** - * Deep Copy the given object or array. - * - * @function Phaser.Utils.Objects.DeepCopy - * @since 3.50.0 - * - * @param {object} obj - The object to deep copy. - * - * @return {object} A deep copy of the original object. - */ -var DeepCopy = function (inObject) -{ - var outObject; - var value; - var key; + var destinationMatrix = (out === undefined) ? matrix : out.matrix; - if (typeof inObject !== 'object' || inObject === null) - { - // inObject is not an object - return inObject; - } + destinationMatrix[0] = (sourceA * localA) + (sourceB * localC); + destinationMatrix[1] = (sourceA * localB) + (sourceB * localD); + destinationMatrix[2] = (sourceC * localA) + (sourceD * localC); + destinationMatrix[3] = (sourceC * localB) + (sourceD * localD); + destinationMatrix[4] = (sourceE * localA) + (sourceF * localC) + localE; + destinationMatrix[5] = (sourceE * localB) + (sourceF * localD) + localF; - // Create an array or object to hold the values - outObject = Array.isArray(inObject) ? [] : {}; + return destinationMatrix; + }, - for (key in inObject) + /** + * Multiply this Matrix by the matrix given, including the offset. + * + * The offsetX is added to the tx value: `offsetX * a + offsetY * c + tx`. + * The offsetY is added to the ty value: `offsetY * b + offsetY * d + ty`. + * + * @method Phaser.GameObjects.Components.TransformMatrix#multiplyWithOffset + * @since 3.11.0 + * + * @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from. + * @param {number} offsetX - Horizontal offset to factor in to the multiplication. + * @param {number} offsetY - Vertical offset to factor in to the multiplication. + * + * @return {this} This TransformMatrix. + */ + multiplyWithOffset: function (src, offsetX, offsetY) { - value = inObject[key]; - - // Recursively (deep) copy for nested objects, including arrays - outObject[key] = DeepCopy(value); - } - - return outObject; -}; + var matrix = this.matrix; + var otherMatrix = src.matrix; -module.exports = DeepCopy; + var a0 = matrix[0]; + var b0 = matrix[1]; + var c0 = matrix[2]; + var d0 = matrix[3]; + var tx0 = matrix[4]; + var ty0 = matrix[5]; + var pse = offsetX * a0 + offsetY * c0 + tx0; + var psf = offsetX * b0 + offsetY * d0 + ty0; -/***/ }), -/* 176 */ -/***/ (function(module, exports) { + var a1 = otherMatrix[0]; + var b1 = otherMatrix[1]; + var c1 = otherMatrix[2]; + var d1 = otherMatrix[3]; + var tx1 = otherMatrix[4]; + var ty1 = otherMatrix[5]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + matrix[0] = a1 * a0 + b1 * c0; + matrix[1] = a1 * b0 + b1 * d0; + matrix[2] = c1 * a0 + d1 * c0; + matrix[3] = c1 * b0 + d1 * d0; + matrix[4] = tx1 * a0 + ty1 * c0 + pse; + matrix[5] = tx1 * b0 + ty1 * d0 + psf; -/** - * Build a JSON representation of the given Game Object. - * - * This is typically extended further by Game Object specific implementations. - * - * @method Phaser.GameObjects.Components.ToJSON - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to export as JSON. - * - * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object. - */ -var ToJSON = function (gameObject) -{ - var out = { - name: gameObject.name, - type: gameObject.type, - x: gameObject.x, - y: gameObject.y, - depth: gameObject.depth, - scale: { - x: gameObject.scaleX, - y: gameObject.scaleY - }, - origin: { - x: gameObject.originX, - y: gameObject.originY - }, - flipX: gameObject.flipX, - flipY: gameObject.flipY, - rotation: gameObject.rotation, - alpha: gameObject.alpha, - visible: gameObject.visible, - blendMode: gameObject.blendMode, - textureKey: '', - frameKey: '', - data: {} - }; + return this; + }, - if (gameObject.texture) + /** + * Transform the Matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#transform + * @since 3.0.0 + * + * @param {number} a - The Scale X value. + * @param {number} b - The Shear Y value. + * @param {number} c - The Shear X value. + * @param {number} d - The Scale Y value. + * @param {number} tx - The Translate X value. + * @param {number} ty - The Translate Y value. + * + * @return {this} This TransformMatrix. + */ + transform: function (a, b, c, d, tx, ty) { - out.textureKey = gameObject.texture.key; - out.frameKey = gameObject.frame.name; - } - - return out; -}; - -module.exports = ToJSON; + var matrix = this.matrix; + var a0 = matrix[0]; + var b0 = matrix[1]; + var c0 = matrix[2]; + var d0 = matrix[3]; + var tx0 = matrix[4]; + var ty0 = matrix[5]; -/***/ }), -/* 177 */ -/***/ (function(module, exports, __webpack_require__) { + matrix[0] = a * a0 + b * c0; + matrix[1] = a * b0 + b * d0; + matrix[2] = c * a0 + d * c0; + matrix[3] = c * b0 + d * d0; + matrix[4] = tx * a0 + ty * c0 + tx0; + matrix[5] = tx * b0 + ty * d0 + ty0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var Vector2 = __webpack_require__(3); + /** + * Transform a point in to the local space of this Matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#transformPoint + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the point to transform. + * @param {number} y - The y coordinate of the point to transform. + * @param {Phaser.Types.Math.Vector2Like} [point] - Optional Point object to store the transformed coordinates in. + * + * @return {Phaser.Types.Math.Vector2Like} The Point containing the transformed coordinates. + */ + transformPoint: function (x, y, point) + { + if (point === undefined) { point = { x: 0, y: 0 }; } -/** - * Takes the `x` and `y` coordinates and transforms them into the same space as - * defined by the position, rotation and scale values. - * - * @function Phaser.Math.TransformXY - * @since 3.0.0 - * - * @param {number} x - The x coordinate to be transformed. - * @param {number} y - The y coordinate to be transformed. - * @param {number} positionX - Horizontal position of the transform point. - * @param {number} positionY - Vertical position of the transform point. - * @param {number} rotation - Rotation of the transform point, in radians. - * @param {number} scaleX - Horizontal scale of the transform point. - * @param {number} scaleY - Vertical scale of the transform point. - * @param {(Phaser.Math.Vector2|Phaser.Geom.Point|object)} [output] - The output vector, point or object for the translated coordinates. - * - * @return {(Phaser.Math.Vector2|Phaser.Geom.Point|object)} The translated point. - */ -var TransformXY = function (x, y, positionX, positionY, rotation, scaleX, scaleY, output) -{ - if (output === undefined) { output = new Vector2(); } + var matrix = this.matrix; - var radianSin = Math.sin(rotation); - var radianCos = Math.cos(rotation); + var a = matrix[0]; + var b = matrix[1]; + var c = matrix[2]; + var d = matrix[3]; + var tx = matrix[4]; + var ty = matrix[5]; - // Rotate and Scale - var a = radianCos * scaleX; - var b = radianSin * scaleX; - var c = -radianSin * scaleY; - var d = radianCos * scaleY; + point.x = x * a + y * c + tx; + point.y = x * b + y * d + ty; - // Invert - var id = 1 / ((a * d) + (c * -b)); + return point; + }, - output.x = (d * id * x) + (-c * id * y) + (((positionY * c) - (positionX * d)) * id); - output.y = (a * id * y) + (-b * id * x) + (((-positionY * a) + (positionX * b)) * id); + /** + * Invert the Matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#invert + * @since 3.0.0 + * + * @return {this} This TransformMatrix. + */ + invert: function () + { + var matrix = this.matrix; - return output; -}; + var a = matrix[0]; + var b = matrix[1]; + var c = matrix[2]; + var d = matrix[3]; + var tx = matrix[4]; + var ty = matrix[5]; -module.exports = TransformXY; + var n = a * d - b * c; + matrix[0] = d / n; + matrix[1] = -b / n; + matrix[2] = -c / n; + matrix[3] = a / n; + matrix[4] = (c * ty - d * tx) / n; + matrix[5] = -(a * ty - b * tx) / n; -/***/ }), -/* 178 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Set the values of this Matrix to copy those of the matrix given. + * + * @method Phaser.GameObjects.Components.TransformMatrix#copyFrom + * @since 3.11.0 + * + * @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from. + * + * @return {this} This TransformMatrix. + */ + copyFrom: function (src) + { + var matrix = this.matrix; -/** - * Moves the element at the start of the array to the end, shifting all items in the process. - * The "rotation" happens to the left. - * - * @function Phaser.Utils.Array.RotateLeft - * @since 3.0.0 - * - * @param {array} array - The array to shift to the left. This array is modified in place. - * @param {number} [total=1] - The number of times to shift the array. - * - * @return {*} The most recently shifted element. - */ -var RotateLeft = function (array, total) -{ - if (total === undefined) { total = 1; } + matrix[0] = src.a; + matrix[1] = src.b; + matrix[2] = src.c; + matrix[3] = src.d; + matrix[4] = src.e; + matrix[5] = src.f; - var element = null; + return this; + }, - for (var i = 0; i < total; i++) + /** + * Set the values of this Matrix to copy those of the array given. + * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f. + * + * @method Phaser.GameObjects.Components.TransformMatrix#copyFromArray + * @since 3.11.0 + * + * @param {array} src - The array of values to set into this matrix. + * + * @return {this} This TransformMatrix. + */ + copyFromArray: function (src) { - element = array.shift(); - array.push(element); - } - - return element; -}; - -module.exports = RotateLeft; + var matrix = this.matrix; + matrix[0] = src[0]; + matrix[1] = src[1]; + matrix[2] = src[2]; + matrix[3] = src[3]; + matrix[4] = src[4]; + matrix[5] = src[5]; -/***/ }), -/* 179 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Copy the values from this Matrix to the given Canvas Rendering Context. + * This will use the Context.transform method. + * + * @method Phaser.GameObjects.Components.TransformMatrix#copyToContext + * @since 3.12.0 + * + * @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to. + * + * @return {CanvasRenderingContext2D} The Canvas Rendering Context. + */ + copyToContext: function (ctx) + { + var matrix = this.matrix; -/** - * Moves the element at the end of the array to the start, shifting all items in the process. - * The "rotation" happens to the right. - * - * @function Phaser.Utils.Array.RotateRight - * @since 3.0.0 - * - * @param {array} array - The array to shift to the right. This array is modified in place. - * @param {number} [total=1] - The number of times to shift the array. - * - * @return {*} The most recently shifted element. - */ -var RotateRight = function (array, total) -{ - if (total === undefined) { total = 1; } + ctx.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); - var element = null; + return ctx; + }, - for (var i = 0; i < total; i++) + /** + * Copy the values from this Matrix to the given Canvas Rendering Context. + * This will use the Context.setTransform method. + * + * @method Phaser.GameObjects.Components.TransformMatrix#setToContext + * @since 3.12.0 + * + * @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to. + * + * @return {CanvasRenderingContext2D} The Canvas Rendering Context. + */ + setToContext: function (ctx) { - element = array.pop(); - array.unshift(element); - } - - return element; -}; + var matrix = this.matrix; -module.exports = RotateRight; + ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); + return ctx; + }, -/***/ }), -/* 180 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Copy the values in this Matrix to the array given. + * + * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f. + * + * @method Phaser.GameObjects.Components.TransformMatrix#copyToArray + * @since 3.12.0 + * + * @param {array} [out] - The array to copy the matrix values in to. + * + * @return {array} An array where elements 0 to 5 contain the values from this matrix. + */ + copyToArray: function (out) + { + var matrix = this.matrix; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (out === undefined) + { + out = [ matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5] ]; + } + else + { + out[0] = matrix[0]; + out[1] = matrix[1]; + out[2] = matrix[2]; + out[3] = matrix[3]; + out[4] = matrix[4]; + out[5] = matrix[5]; + } -var Point = __webpack_require__(4); + return out; + }, -/** - * Returns a uniformly distributed random point from anywhere within the given Ellipse. - * - * @function Phaser.Geom.Ellipse.Random - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get a random point from. - * @param {(Phaser.Geom.Point|object)} [out] - 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. - */ -var Random = function (ellipse, out) -{ - if (out === undefined) { out = new Point(); } + /** + * Set the values of this Matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#setTransform + * @since 3.0.0 + * + * @param {number} a - The Scale X value. + * @param {number} b - The Shear Y value. + * @param {number} c - The Shear X value. + * @param {number} d - The Scale Y value. + * @param {number} tx - The Translate X value. + * @param {number} ty - The Translate Y value. + * + * @return {this} This TransformMatrix. + */ + setTransform: function (a, b, c, d, tx, ty) + { + var matrix = this.matrix; - var p = Math.random() * Math.PI * 2; - var s = Math.sqrt(Math.random()); + matrix[0] = a; + matrix[1] = b; + matrix[2] = c; + matrix[3] = d; + matrix[4] = tx; + matrix[5] = ty; - out.x = ellipse.x + ((s * Math.cos(p)) * ellipse.width / 2); - out.y = ellipse.y + ((s * Math.sin(p)) * ellipse.height / 2); + return this; + }, - return out; -}; + /** + * Decompose this Matrix into its translation, scale and rotation values using QR decomposition. + * + * The result must be applied in the following order to reproduce the current matrix: + * + * translate -> rotate -> scale + * + * @method Phaser.GameObjects.Components.TransformMatrix#decomposeMatrix + * @since 3.0.0 + * + * @return {Phaser.Types.GameObjects.DecomposeMatrixResults} The decomposed Matrix. + */ + decomposeMatrix: function () + { + var decomposedMatrix = this.decomposedMatrix; -module.exports = Random; + var matrix = this.matrix; + // a = scale X (1) + // b = shear Y (0) + // c = shear X (0) + // d = scale Y (1) -/***/ }), -/* 181 */ -/***/ (function(module, exports, __webpack_require__) { + var a = matrix[0]; + var b = matrix[1]; + var c = matrix[2]; + var d = matrix[3]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var determ = a * d - b * c; -var Point = __webpack_require__(4); + decomposedMatrix.translateX = matrix[4]; + decomposedMatrix.translateY = matrix[5]; -/** - * Returns a random Point from within the area of the given Triangle. - * - * @function Phaser.Geom.Triangle.Random - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to get a random point from. - * @param {Phaser.Geom.Point} [out] - The Point object to store the position in. If not given, a new Point instance is created. - * - * @return {Phaser.Geom.Point} A Point object holding the coordinates of a random position within the Triangle. - */ -var Random = function (triangle, out) -{ - if (out === undefined) { out = new Point(); } + if (a || b) + { + var r = Math.sqrt(a * a + b * b); - // Basis vectors - var ux = triangle.x2 - triangle.x1; - var uy = triangle.y2 - triangle.y1; + decomposedMatrix.rotation = (b > 0) ? Math.acos(a / r) : -Math.acos(a / r); + decomposedMatrix.scaleX = r; + decomposedMatrix.scaleY = determ / r; + } + else if (c || d) + { + var s = Math.sqrt(c * c + d * d); - var vx = triangle.x3 - triangle.x1; - var vy = triangle.y3 - triangle.y1; + decomposedMatrix.rotation = Math.PI * 0.5 - (d > 0 ? Math.acos(-c / s) : -Math.acos(c / s)); + decomposedMatrix.scaleX = determ / s; + decomposedMatrix.scaleY = s; + } + else + { + decomposedMatrix.rotation = 0; + decomposedMatrix.scaleX = 0; + decomposedMatrix.scaleY = 0; + } - // Random point within the unit square - var r = Math.random(); - var s = Math.random(); + return decomposedMatrix; + }, - // Point outside the triangle? Remap it. - if (r + s >= 1) + /** + * Apply the identity, translate, rotate and scale operations on the Matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#applyITRS + * @since 3.0.0 + * + * @param {number} x - The horizontal translation. + * @param {number} y - The vertical translation. + * @param {number} rotation - The angle of rotation in radians. + * @param {number} scaleX - The horizontal scale. + * @param {number} scaleY - The vertical scale. + * + * @return {this} This TransformMatrix. + */ + applyITRS: function (x, y, rotation, scaleX, scaleY) { - r = 1 - r; - s = 1 - s; - } + var matrix = this.matrix; - out.x = triangle.x1 + ((ux * r) + (vx * s)); - out.y = triangle.y1 + ((uy * r) + (vy * s)); + var radianSin = Math.sin(rotation); + var radianCos = Math.cos(rotation); - return out; -}; + // Translate + matrix[4] = x; + matrix[5] = y; -module.exports = Random; + // Rotate and Scale + matrix[0] = radianCos * scaleX; + matrix[1] = radianSin * scaleX; + matrix[2] = -radianSin * scaleY; + matrix[3] = radianCos * scaleY; + return this; + }, -/***/ }), -/* 182 */ -/***/ (function(module, exports) { + /** + * Takes the `x` and `y` values and returns a new position in the `output` vector that is the inverse of + * the current matrix with its transformation applied. + * + * Can be used to translate points from world to local space. + * + * @method Phaser.GameObjects.Components.TransformMatrix#applyInverse + * @since 3.12.0 + * + * @param {number} x - The x position to translate. + * @param {number} y - The y position to translate. + * @param {Phaser.Math.Vector2} [output] - A Vector2, or point-like object, to store the results in. + * + * @return {Phaser.Math.Vector2} The coordinates, inverse-transformed through this matrix. + */ + applyInverse: function (x, y, output) + { + if (output === undefined) { output = new Vector2(); } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var matrix = this.matrix; -/** - * Rotate a `point` around `x` and `y` by the given `angle` and `distance`. - * - * In polar notation, this maps a point from (r, t) to (distance, t + angle), vs. the origin (x, y). - * - * @function Phaser.Math.RotateAroundDistance - * @since 3.0.0 - * - * @generic {Phaser.Types.Math.Vector2Like} T - [point,$return] - * - * @param {(Phaser.Geom.Point|object)} point - The point to be rotated. - * @param {number} x - The horizontal coordinate to rotate around. - * @param {number} y - The vertical coordinate to rotate around. - * @param {number} angle - The angle of rotation in radians. - * @param {number} distance - The distance from (x, y) to place the point at. - * - * @return {Phaser.Types.Math.Vector2Like} The given point. - */ -var RotateAroundDistance = function (point, x, y, angle, distance) -{ - var t = angle + Math.atan2(point.y - y, point.x - x); + var a = matrix[0]; + var b = matrix[1]; + var c = matrix[2]; + var d = matrix[3]; + var tx = matrix[4]; + var ty = matrix[5]; - point.x = x + (distance * Math.cos(t)); - point.y = y + (distance * Math.sin(t)); + var id = 1 / ((a * d) + (c * -b)); - return point; -}; + output.x = (d * id * x) + (-c * id * y) + (((ty * c) - (tx * d)) * id); + output.y = (a * id * y) + (-b * id * x) + (((-ty * a) + (tx * b)) * id); -module.exports = RotateAroundDistance; + return output; + }, + + /** + * Performs the 8 calculations required to create the vertices of + * a quad based on this matrix and the given x/y/xw/yh values. + * + * The result is stored in `TransformMatrix.quad`, which is returned + * from this method. + * + * @method Phaser.GameObjects.Components.TransformMatrix#setQuad + * @since 3.60.0 + * + * @param {number} x - The x value. + * @param {number} y - The y value. + * @param {number} xw - The xw value. + * @param {number} yh - The yh value. + * @param {boolean} roundPixels - Pass the results via Math.round? + * @param {Float32Array} [quad] - Optional Float32Array to store the results in. Otherwises uses the local quad array. + * + * @return {Float32Array} The quad Float32Array. + */ + setQuad: function (x, y, xw, yh, roundPixels, quad) + { + if (quad === undefined) { quad = this.quad; } + + var matrix = this.matrix; + + var a = matrix[0]; + var b = matrix[1]; + var c = matrix[2]; + var d = matrix[3]; + var e = matrix[4]; + var f = matrix[5]; + + quad[0] = x * a + y * c + e; + quad[1] = x * b + y * d + f; + + quad[2] = x * a + yh * c + e; + quad[3] = x * b + yh * d + f; + + quad[4] = xw * a + yh * c + e; + quad[5] = xw * b + yh * d + f; + + quad[6] = xw * a + y * c + e; + quad[7] = xw * b + y * d + f; + + if (roundPixels) + { + quad.forEach(function (value, index) + { + quad[index] = Math.round(value); + }); + } + + return quad; + }, + + /** + * Returns the X component of this matrix multiplied by the given values. + * This is the same as `x * a + y * c + e`. + * + * @method Phaser.GameObjects.Components.TransformMatrix#getX + * @since 3.12.0 + * + * @param {number} x - The x value. + * @param {number} y - The y value. + * + * @return {number} The calculated x value. + */ + getX: function (x, y) + { + return x * this.a + y * this.c + this.e; + }, + + /** + * Returns the Y component of this matrix multiplied by the given values. + * This is the same as `x * b + y * d + f`. + * + * @method Phaser.GameObjects.Components.TransformMatrix#getY + * @since 3.12.0 + * + * @param {number} x - The x value. + * @param {number} y - The y value. + * + * @return {number} The calculated y value. + */ + getY: function (x, y) + { + return x * this.b + y * this.d + this.f; + }, + + /** + * Returns the X component of this matrix multiplied by the given values. + * + * This is the same as `x * a + y * c + e`, optionally passing via `Math.round`. + * + * @method Phaser.GameObjects.Components.TransformMatrix#getXRound + * @since 3.50.0 + * + * @param {number} x - The x value. + * @param {number} y - The y value. + * @param {boolean} [round=false] - Math.round the resulting value? + * + * @return {number} The calculated x value. + */ + getXRound: function (x, y, round) + { + var v = this.getX(x, y); + + if (round) + { + v = Math.round(v); + } + + return v; + }, + + /** + * Returns the Y component of this matrix multiplied by the given values. + * + * This is the same as `x * b + y * d + f`, optionally passing via `Math.round`. + * + * @method Phaser.GameObjects.Components.TransformMatrix#getYRound + * @since 3.50.0 + * + * @param {number} x - The x value. + * @param {number} y - The y value. + * @param {boolean} [round=false] - Math.round the resulting value? + * + * @return {number} The calculated y value. + */ + getYRound: function (x, y, round) + { + var v = this.getY(x, y); + + if (round) + { + v = Math.round(v); + } + + return v; + }, + + /** + * Returns a string that can be used in a CSS Transform call as a `matrix` property. + * + * @method Phaser.GameObjects.Components.TransformMatrix#getCSSMatrix + * @since 3.12.0 + * + * @return {string} A string containing the CSS Transform matrix values. + */ + getCSSMatrix: function () + { + var m = this.matrix; + + return 'matrix(' + m[0] + ',' + m[1] + ',' + m[2] + ',' + m[3] + ',' + m[4] + ',' + m[5] + ')'; + }, + + /** + * Destroys this Transform Matrix. + * + * @method Phaser.GameObjects.Components.TransformMatrix#destroy + * @since 3.4.0 + */ + destroy: function () + { + this.matrix = null; + this.quad = null; + this.decomposedMatrix = null; + } + +}); + +module.exports = TransformMatrix; /***/ }), -/* 183 */ -/***/ (function(module, exports) { + +/***/ 59694: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +// bitmask flag for GameObject.renderMask +var _FLAG = 1; // 0001 + /** - * Calculate a smoother interpolation percentage of `x` between `min` and `max`. - * - * The function receives the number `x` as an argument and returns 0 if `x` is less than or equal to the left edge, - * 1 if `x` is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial, - * between 0 and 1 otherwise. - * - * Produces an even smoother interpolation than {@link Phaser.Math.SmoothStep}. + * Provides methods used for setting the visibility of a Game Object. + * Should be applied as a mixin and not used directly. * - * @function Phaser.Math.SmootherStep + * @namespace Phaser.GameObjects.Components.Visible * @since 3.0.0 - * @see {@link https://en.wikipedia.org/wiki/Smoothstep#Variations} - * - * @param {number} x - The input value. - * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'. - * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'. - * - * @return {number} The percentage of interpolation, between 0 and 1. */ -var SmootherStep = function (x, min, max) -{ - x = Math.max(0, Math.min(1, (x - min) / (max - min))); - return x * x * x * (x * (x * 6 - 15) + 10); +var Visible = { + + /** + * Private internal value. Holds the visible value. + * + * @name Phaser.GameObjects.Components.Visible#_visible + * @type {boolean} + * @private + * @default true + * @since 3.0.0 + */ + _visible: true, + + /** + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * + * @name Phaser.GameObjects.Components.Visible#visible + * @type {boolean} + * @since 3.0.0 + */ + visible: { + + get: function () + { + return this._visible; + }, + + set: function (value) + { + if (value) + { + this._visible = true; + this.renderFlags |= _FLAG; + } + else + { + this._visible = false; + this.renderFlags &= ~_FLAG; + } + } + + }, + + /** + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * + * @method Phaser.GameObjects.Components.Visible#setVisible + * @since 3.0.0 + * + * @param {boolean} value - The visible state of the Game Object. + * + * @return {this} This Game Object instance. + */ + setVisible: function (value) + { + this.visible = value; + + return this; + } }; -module.exports = SmootherStep; +module.exports = Visible; /***/ }), -/* 184 */ -/***/ (function(module, exports) { + +/***/ 64937: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Calculate a smooth interpolation percentage of `x` between `min` and `max`. - * - * The function receives the number `x` as an argument and returns 0 if `x` is less than or equal to the left edge, - * 1 if `x` is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial, - * between 0 and 1 otherwise. - * - * @function Phaser.Math.SmoothStep - * @since 3.0.0 - * @see {@link https://en.wikipedia.org/wiki/Smoothstep} - * - * @param {number} x - The input value. - * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'. - * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'. - * - * @return {number} The percentage of interpolation, between 0 and 1. + * @namespace Phaser.GameObjects.Components */ -var SmoothStep = function (x, min, max) -{ - if (x <= min) - { - return 0; - } - if (x >= max) - { - return 1; - } +module.exports = { - x = (x - min) / (max - min); + Alpha: __webpack_require__(97123), + AlphaSingle: __webpack_require__(15720), + BlendMode: __webpack_require__(69732), + ComputedSize: __webpack_require__(28284), + Crop: __webpack_require__(85293), + Depth: __webpack_require__(14975), + Flip: __webpack_require__(92972), + FX: __webpack_require__(88677), + GetBounds: __webpack_require__(80693), + Mask: __webpack_require__(39171), + Origin: __webpack_require__(28072), + PathFollower: __webpack_require__(54211), + Pipeline: __webpack_require__(58210), + PostPipeline: __webpack_require__(44086), + ScrollFactor: __webpack_require__(45900), + Size: __webpack_require__(31654), + Texture: __webpack_require__(82081), + TextureCrop: __webpack_require__(21850), + Tint: __webpack_require__(58072), + ToJSON: __webpack_require__(48129), + Transform: __webpack_require__(56584), + TransformMatrix: __webpack_require__(69360), + Visible: __webpack_require__(59694) - return x * x * (3 - 2 * x); }; -module.exports = SmoothStep; - /***/ }), -/* 185 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 70339: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var Events = __webpack_require__(132); -var FindClosestInSorted = __webpack_require__(318); -var Frame = __webpack_require__(319); -var GetValue = __webpack_require__(6); -var SortByDigits = __webpack_require__(320); +var ArrayUtils = __webpack_require__(59959); +var BlendModes = __webpack_require__(95723); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var Events = __webpack_require__(56631); +var GameObject = __webpack_require__(89980); +var Rectangle = __webpack_require__(74118); +var Render = __webpack_require__(98524); +var Union = __webpack_require__(58795); +var Vector2 = __webpack_require__(93736); /** * @classdesc - * A Frame based Animation. + * A Container Game Object. * - * Animations in Phaser consist of a sequence of `AnimationFrame` objects, which are managed by - * this class, along with properties that impact playback, such as the animations frame rate - * or delay. + * A Container, as the name implies, can 'contain' other types of Game Object. + * When a Game Object is added to a Container, the Container becomes responsible for the rendering of it. + * By default it will be removed from the Display List and instead added to the Containers own internal list. * - * This class contains all of the properties and methods needed to handle playback of the animation - * directly to an `AnimationState` instance, which is owned by a Sprite, or similar Game Object. + * The position of the Game Object automatically becomes relative to the position of the Container. * - * You don't typically create an instance of this class directly, but instead go via - * either the `AnimationManager` or the `AnimationState` and use their `create` methods, - * depending on if you need a global animation, or local to a specific Sprite. + * The transform point of a Container is 0x0 (in local space) and that cannot be changed. The children you add to the + * Container should be positioned with this value in mind. I.e. you should treat 0x0 as being the center of + * the Container, and position children positively and negative around it as required. * - * @class Animation - * @memberof Phaser.Animations + * When the Container is rendered, all of its children are rendered as well, in the order in which they exist + * within the Container. Container children can be repositioned using methods such as `MoveUp`, `MoveDown` and `SendToBack`. + * + * If you modify a transform property of the Container, such as `Container.x` or `Container.rotation` then it will + * automatically influence all children as well. + * + * Containers can include other Containers for deeply nested transforms. + * + * Containers can have masks set on them and can be used as a mask too. However, Container children cannot be masked. + * The masks do not 'stack up'. Only a Container on the root of the display list will use its mask. + * + * Containers can be enabled for input. Because they do not have a texture you need to provide a shape for them + * to use as their hit area. Container children can also be enabled for input, independent of the Container. + * + * If input enabling a _child_ you should not set both the `origin` and a **negative** scale factor on the child, + * or the input area will become misaligned. + * + * Containers can be given a physics body for either Arcade Physics, Impact Physics or Matter Physics. However, + * if Container _children_ are enabled for physics you may get unexpected results, such as offset bodies, + * if the Container itself, or any of its ancestors, is positioned anywhere other than at 0 x 0. Container children + * with physics do not factor in the Container due to the excessive extra calculations needed. Please structure + * your game to work around this. + * + * It's important to understand the impact of using Containers. They add additional processing overhead into + * every one of their children. The deeper you nest them, the more the cost escalates. This is especially true + * for input events. You also loose the ability to set the display depth of Container children in the same + * flexible manner as those not within them. In short, don't use them for the sake of it. You pay a small cost + * every time you create one, try to structure your game around avoiding that where possible. + * + * @class Container + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects * @constructor - * @since 3.0.0 + * @since 3.4.0 * - * @param {Phaser.Animations.AnimationManager} manager - A reference to the global Animation Manager - * @param {string} key - The unique identifying string for this animation. - * @param {Phaser.Types.Animations.Animation} config - The Animation configuration. + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.ComputedSize + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.Visible + * + * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. + * @param {number} [x=0] - The horizontal position of this Game Object in the world. + * @param {number} [y=0] - The vertical position of this Game Object in the world. + * @param {Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Container. */ -var Animation = new Class({ +var Container = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.ComputedSize, + Components.Depth, + Components.Mask, + Components.PostPipeline, + Components.Transform, + Components.Visible, + Render + ], initialize: - function Animation (manager, key, config) + function Container (scene, x, y, children) { - /** - * A reference to the global Animation Manager. - * - * @name Phaser.Animations.Animation#manager - * @type {Phaser.Animations.AnimationManager} - * @since 3.0.0 - */ - this.manager = manager; + GameObject.call(this, scene, 'Container'); /** - * The unique identifying string for this animation. + * An array holding the children of this Container. * - * @name Phaser.Animations.Animation#key - * @type {string} - * @since 3.0.0 + * @name Phaser.GameObjects.Container#list + * @type {Phaser.GameObjects.GameObject[]} + * @since 3.4.0 */ - this.key = key; + this.list = []; /** - * A frame based animation (as opposed to a bone based animation) + * Does this Container exclusively manage its children? * - * @name Phaser.Animations.Animation#type - * @type {string} - * @default frame - * @since 3.0.0 - */ - this.type = 'frame'; - - /** - * Extract all the frame data into the frames array. + * The default is `true` which means a child added to this Container cannot + * belong in another Container, which includes the Scene display list. * - * @name Phaser.Animations.Animation#frames - * @type {Phaser.Animations.AnimationFrame[]} - * @since 3.0.0 + * If you disable this then this Container will no longer exclusively manage its children. + * This allows you to create all kinds of interesting graphical effects, such as replicating + * Game Objects without reparenting them all over the Scene. + * However, doing so will prevent children from receiving any kind of input event or have + * their physics bodies work by default, as they're no longer a single entity on the + * display list, but are being replicated where-ever this Container is. + * + * @name Phaser.GameObjects.Container#exclusive + * @type {boolean} + * @default true + * @since 3.4.0 */ - this.frames = this.getFrames( - manager.textureManager, - GetValue(config, 'frames', []), - GetValue(config, 'defaultTextureKey', null), - GetValue(config, 'sortFrames', true) - ); + this.exclusive = true; /** - * The frame rate of playback in frames per second (default 24 if duration is null) + * Containers can have an optional maximum size. If set to anything above 0 it + * will constrict the addition of new Game Objects into the Container, capping off + * the maximum limit the Container can grow in size to. * - * @name Phaser.Animations.Animation#frameRate + * @name Phaser.GameObjects.Container#maxSize * @type {number} - * @default 24 - * @since 3.0.0 + * @default -1 + * @since 3.4.0 */ - this.frameRate = GetValue(config, 'frameRate', null); + this.maxSize = -1; /** - * How long the animation should play for, in milliseconds. - * If the `frameRate` property has been set then it overrides this value, - * otherwise the `frameRate` is derived from `duration`. + * The cursor position. * - * @name Phaser.Animations.Animation#duration + * @name Phaser.GameObjects.Container#position * @type {number} - * @since 3.0.0 + * @since 3.4.0 */ - this.duration = GetValue(config, 'duration', null); + this.position = 0; /** - * How many ms per frame, not including frame specific modifiers. + * Internal Transform Matrix used for local space conversion. * - * @name Phaser.Animations.Animation#msPerFrame - * @type {number} - * @since 3.0.0 + * @name Phaser.GameObjects.Container#localTransform + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.4.0 */ - this.msPerFrame; + this.localTransform = new Components.TransformMatrix(); /** - * Skip frames if the time lags, or always advanced anyway? + * Internal temporary Transform Matrix used to avoid object creation. * - * @name Phaser.Animations.Animation#skipMissedFrames - * @type {boolean} - * @default true - * @since 3.0.0 + * @name Phaser.GameObjects.Container#tempTransformMatrix + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.4.0 */ - this.skipMissedFrames = GetValue(config, 'skipMissedFrames', true); + this.tempTransformMatrix = new Components.TransformMatrix(); /** - * The delay in ms before the playback will begin. + * The property key to sort by. * - * @name Phaser.Animations.Animation#delay - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Container#_sortKey + * @type {string} + * @private + * @since 3.4.0 */ - this.delay = GetValue(config, 'delay', 0); + this._sortKey = ''; /** - * Number of times to repeat the animation. Set to -1 to repeat forever. + * A reference to the Scene Systems Event Emitter. * - * @name Phaser.Animations.Animation#repeat - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Container#_sysEvents + * @type {Phaser.Events.EventEmitter} + * @private + * @since 3.9.0 */ - this.repeat = GetValue(config, 'repeat', 0); + this._sysEvents = scene.sys.events; /** - * The delay in ms before the a repeat play starts. + * The horizontal scroll factor of this Container. * - * @name Phaser.Animations.Animation#repeatDelay + * The scroll factor controls the influence of the movement of a Camera upon this Container. + * + * When a camera scrolls it will change the location at which this Container is rendered on-screen. + * It does not change the Containers actual position values. + * + * For a Container, setting this value will only update the Container itself, not its children. + * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Container. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * + * @name Phaser.GameObjects.Container#scrollFactorX * @type {number} - * @default 0 - * @since 3.0.0 + * @default 1 + * @since 3.4.0 */ - this.repeatDelay = GetValue(config, 'repeatDelay', 0); + this.scrollFactorX = 1; /** - * Should the animation yoyo (reverse back down to the start) before repeating? + * The vertical scroll factor of this Container. * - * @name Phaser.Animations.Animation#yoyo - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.yoyo = GetValue(config, 'yoyo', false); - - /** - * Should the GameObject's `visible` property be set to `true` when the animation starts to play? + * The scroll factor controls the influence of the movement of a Camera upon this Container. * - * @name Phaser.Animations.Animation#showOnStart - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.showOnStart = GetValue(config, 'showOnStart', false); - - /** - * Should the GameObject's `visible` property be set to `false` when the animation finishes? + * When a camera scrolls it will change the location at which this Container is rendered on-screen. + * It does not change the Containers actual position values. * - * @name Phaser.Animations.Animation#hideOnComplete - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.hideOnComplete = GetValue(config, 'hideOnComplete', false); - - /** - * Global pause. All Game Objects using this Animation instance are impacted by this property. + * For a Container, setting this value will only update the Container itself, not its children. + * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method. * - * @name Phaser.Animations.Animation#paused - * @type {boolean} - * @default false - * @since 3.0.0 + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Container. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * + * @name Phaser.GameObjects.Container#scrollFactorY + * @type {number} + * @default 1 + * @since 3.4.0 */ - this.paused = false; + this.scrollFactorY = 1; - this.calculateDuration(this, this.getTotalFrames(), this.duration, this.frameRate); + this.initPostPipeline(); - if (this.manager.on) + this.setPosition(x, y); + + this.setBlendMode(BlendModes.SKIP_CHECK); + + if (children) { - this.manager.on(Events.PAUSE_ALL, this.pause, this); - this.manager.on(Events.RESUME_ALL, this.resume, this); + this.add(children); } }, /** - * Gets the total number of frames in this animation. - * - * @method Phaser.Animations.Animation#getTotalFrames - * @since 3.50.0 + * Internal value to allow Containers to be used for input and physics. + * Do not change this value. It has no effect other than to break things. * - * @return {number} The total number of frames in this animation. + * @name Phaser.GameObjects.Container#originX + * @type {number} + * @readonly + * @override + * @since 3.4.0 */ - getTotalFrames: function () - { - return this.frames.length; + originX: { + + get: function () + { + return 0.5; + } + }, /** - * Calculates the duration, frame rate and msPerFrame values. - * - * @method Phaser.Animations.Animation#calculateDuration - * @since 3.50.0 + * Internal value to allow Containers to be used for input and physics. + * Do not change this value. It has no effect other than to break things. * - * @param {Phaser.Animations.Animation} target - The target to set the values on. - * @param {number} totalFrames - The total number of frames in the animation. - * @param {number} duration - The duration to calculate the frame rate from. - * @param {number} frameRate - The frame ate to calculate the duration from. + * @name Phaser.GameObjects.Container#originY + * @type {number} + * @readonly + * @override + * @since 3.4.0 */ - calculateDuration: function (target, totalFrames, duration, frameRate) - { - if (duration === null && frameRate === null) - { - // No duration or frameRate given, use default frameRate of 24fps - target.frameRate = 24; - target.duration = (24 / totalFrames) * 1000; - } - else if (duration && frameRate === null) - { - // Duration given but no frameRate, so set the frameRate based on duration - // I.e. 12 frames in the animation, duration = 4000 ms - // So frameRate is 12 / (4000 / 1000) = 3 fps - target.duration = duration; - target.frameRate = totalFrames / (duration / 1000); - } - else + originY: { + + get: function () { - // frameRate given, derive duration from it (even if duration also specified) - // I.e. 15 frames in the animation, frameRate = 30 fps - // So duration is 15 / 30 = 0.5 * 1000 (half a second, or 500ms) - target.frameRate = frameRate; - target.duration = (totalFrames / frameRate) * 1000; + return 0.5; } - target.msPerFrame = 1000 / target.frameRate; }, /** - * Add frames to the end of the animation. - * - * @method Phaser.Animations.Animation#addFrame - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Animations.AnimationFrame[])} config - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects. + * Internal value to allow Containers to be used for input and physics. + * Do not change this value. It has no effect other than to break things. * - * @return {this} This Animation object. + * @name Phaser.GameObjects.Container#displayOriginX + * @type {number} + * @readonly + * @override + * @since 3.4.0 */ - addFrame: function (config) - { - return this.addFrameAt(this.frames.length, config); + displayOriginX: { + + get: function () + { + return this.width * 0.5; + } + }, /** - * Add frame/s into the animation. - * - * @method Phaser.Animations.Animation#addFrameAt - * @since 3.0.0 - * - * @param {number} index - The index to insert the frame at within the animation. - * @param {(string|Phaser.Types.Animations.AnimationFrame[])} config - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects. + * Internal value to allow Containers to be used for input and physics. + * Do not change this value. It has no effect other than to break things. * - * @return {this} This Animation object. + * @name Phaser.GameObjects.Container#displayOriginY + * @type {number} + * @readonly + * @override + * @since 3.4.0 */ - addFrameAt: function (index, config) - { - var newFrames = this.getFrames(this.manager.textureManager, config); + displayOriginY: { - if (newFrames.length > 0) + get: function () { - if (index === 0) - { - this.frames = newFrames.concat(this.frames); - } - else if (index === this.frames.length) - { - this.frames = this.frames.concat(newFrames); - } - else - { - var pre = this.frames.slice(0, index); - var post = this.frames.slice(index); - - this.frames = pre.concat(newFrames, post); - } - - this.updateFrameSequence(); + return this.height * 0.5; } - return this; }, /** - * Check if the given frame index is valid. + * Does this Container exclusively manage its children? * - * @method Phaser.Animations.Animation#checkFrame - * @since 3.0.0 + * The default is `true` which means a child added to this Container cannot + * belong in another Container, which includes the Scene display list. * - * @param {number} index - The index to be checked. + * If you disable this then this Container will no longer exclusively manage its children. + * This allows you to create all kinds of interesting graphical effects, such as replicating + * Game Objects without reparenting them all over the Scene. + * However, doing so will prevent children from receiving any kind of input event or have + * their physics bodies work by default, as they're no longer a single entity on the + * display list, but are being replicated where-ever this Container is. * - * @return {boolean} `true` if the index is valid, otherwise `false`. - */ - checkFrame: function (index) - { - return (index >= 0 && index < this.frames.length); - }, - - /** - * Called internally when this Animation first starts to play. - * Sets the accumulator and nextTick properties. + * @method Phaser.GameObjects.Container#setExclusive + * @since 3.4.0 * - * @method Phaser.Animations.Animation#getFirstTick - * @protected - * @since 3.0.0 + * @param {boolean} [value=true] - The exclusive state of this Container. * - * @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call. + * @return {this} This Container. */ - getFirstTick: function (state) + setExclusive: function (value) { - // When is the first update due? - state.accumulator = 0; + if (value === undefined) { value = true; } - state.nextTick = state.msPerFrame + state.currentFrame.duration; + this.exclusive = value; + + return this; }, /** - * Returns the AnimationFrame at the provided index + * Gets the bounds of this Container. It works by iterating all children of the Container, + * getting their respective bounds, and then working out a min-max rectangle from that. + * It does not factor in if the children render or not, all are included. * - * @method Phaser.Animations.Animation#getFrameAt - * @protected - * @since 3.0.0 + * Some children are unable to return their bounds, such as Graphics objects, in which case + * they are skipped. * - * @param {number} index - The index in the AnimationFrame array + * Depending on the quantity of children in this Container it could be a really expensive call, + * so cache it and only poll it as needed. * - * @return {Phaser.Animations.AnimationFrame} The frame at the index provided from the animation sequence - */ - getFrameAt: function (index) - { - return this.frames[index]; - }, - - /** - * Creates AnimationFrame instances based on the given frame data. + * The values are stored and returned in a Rectangle object. * - * @method Phaser.Animations.Animation#getFrames - * @since 3.0.0 + * @method Phaser.GameObjects.Container#getBounds + * @since 3.4.0 * - * @param {Phaser.Textures.TextureManager} textureManager - A reference to the global Texture Manager. - * @param {(string|Phaser.Types.Animations.AnimationFrame[])} frames - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects. - * @param {string} [defaultTextureKey] - The key to use if no key is set in the frame configuration object. + * @param {Phaser.Geom.Rectangle} [output] - A Geom.Rectangle object to store the values in. If not provided a new Rectangle will be created. * - * @return {Phaser.Animations.AnimationFrame[]} An array of newly created AnimationFrame instances. + * @return {Phaser.Geom.Rectangle} The values stored in the output object. */ - getFrames: function (textureManager, frames, defaultTextureKey, sortFrames) + getBounds: function (output) { - if (sortFrames === undefined) { sortFrames = true; } + if (output === undefined) { output = new Rectangle(); } - var out = []; - var prev; - var animationFrame; - var index = 1; - var i; - var textureKey; + output.setTo(this.x, this.y, 0, 0); - // if frames is a string, we'll get all the frames from the texture manager as if it's a sprite sheet - if (typeof frames === 'string') + if (this.parentContainer) { - textureKey = frames; + var parentMatrix = this.parentContainer.getBoundsTransformMatrix(); + var transformedPosition = parentMatrix.transformPoint(this.x, this.y); - var texture = textureManager.get(textureKey); - var frameKeys = texture.getFrameNames(); + output.setTo(transformedPosition.x, transformedPosition.y, 0, 0); + } - if (sortFrames) - { - SortByDigits(frameKeys); - } + if (this.list.length > 0) + { + var children = this.list; + var tempRect = new Rectangle(); + var hasSetFirst = false; - frames = []; + output.setEmpty(); - frameKeys.forEach(function (value) + for (var i = 0; i < children.length; i++) { - frames.push({ key: textureKey, frame: value }); - }); - } + var entry = children[i]; - if (!Array.isArray(frames) || frames.length === 0) - { - return out; + if (entry.getBounds) + { + entry.getBounds(tempRect); + + if (!hasSetFirst) + { + output.setTo(tempRect.x, tempRect.y, tempRect.width, tempRect.height); + hasSetFirst = true; + } + else + { + Union(tempRect, output, output); + } + } + } } - for (i = 0; i < frames.length; i++) - { - var item = frames[i]; + return output; + }, - var key = GetValue(item, 'key', defaultTextureKey); + /** + * Internal add handler. + * + * @method Phaser.GameObjects.Container#addHandler + * @private + * @since 3.4.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to this Container. + */ + addHandler: function (gameObject) + { + gameObject.once(Events.DESTROY, this.remove, this); - if (!key) + if (this.exclusive) + { + if (gameObject.parentContainer) { - continue; + gameObject.parentContainer.remove(gameObject); } - // Could be an integer or a string - var frame = GetValue(item, 'frame', 0); - - // The actual texture frame - var textureFrame = textureManager.getFrame(key, frame); + gameObject.parentContainer = this; - animationFrame = new Frame(key, frame, index, textureFrame); + gameObject.removeFromDisplayList(); - animationFrame.duration = GetValue(item, 'duration', 0); + gameObject.addedToScene(); + } + }, - animationFrame.isFirst = (!prev); + /** + * Internal remove handler. + * + * @method Phaser.GameObjects.Container#removeHandler + * @private + * @since 3.4.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just removed from this Container. + */ + removeHandler: function (gameObject) + { + gameObject.off(Events.DESTROY, this.remove, this); - // The previously created animationFrame - if (prev) - { - prev.nextFrame = animationFrame; + if (this.exclusive) + { + gameObject.parentContainer = null; - animationFrame.prevFrame = prev; - } + gameObject.removedFromScene(); - out.push(animationFrame); + gameObject.addToDisplayList(); + } + }, - prev = animationFrame; + /** + * Takes a Point-like object, such as a Vector2, Geom.Point or object with public x and y properties, + * and transforms it into the space of this Container, then returns it in the output object. + * + * @method Phaser.GameObjects.Container#pointToContainer + * @since 3.4.0 + * + * @param {Phaser.Types.Math.Vector2Like} source - The Source Point to be transformed. + * @param {Phaser.Types.Math.Vector2Like} [output] - A destination object to store the transformed point in. If none given a Vector2 will be created and returned. + * + * @return {Phaser.Types.Math.Vector2Like} The transformed point. + */ + pointToContainer: function (source, output) + { + if (output === undefined) { output = new Vector2(); } - index++; + if (this.parentContainer) + { + this.parentContainer.pointToContainer(source, output); } - - if (out.length > 0) + else { - animationFrame.isLast = true; - - // Link them end-to-end, so they loop - animationFrame.nextFrame = out[0]; + output.x = source.x; + output.y = source.y; + } - out[0].prevFrame = animationFrame; + var tempMatrix = this.tempTransformMatrix; - // Generate the progress data + // No need to loadIdentity because applyITRS overwrites every value anyway + tempMatrix.applyITRS(this.x, this.y, this.rotation, this.scaleX, this.scaleY); - var slice = 1 / (out.length - 1); + tempMatrix.invert(); - for (i = 0; i < out.length; i++) - { - out[i].progress = i * slice; - } - } + tempMatrix.transformPoint(source.x, source.y, output); - return out; + return output; }, /** - * Called internally. Sets the accumulator and nextTick values of the current Animation. + * Returns the world transform matrix as used for Bounds checks. * - * @method Phaser.Animations.Animation#getNextTick - * @since 3.0.0 + * The returned matrix is temporal and shouldn't be stored. * - * @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call. + * @method Phaser.GameObjects.Container#getBoundsTransformMatrix + * @since 3.4.0 + * + * @return {Phaser.GameObjects.Components.TransformMatrix} The world transform matrix. */ - getNextTick: function (state) + getBoundsTransformMatrix: function () { - state.accumulator -= state.nextTick; - - state.nextTick = state.msPerFrame + state.currentFrame.duration; + return this.getWorldTransformMatrix(this.tempTransformMatrix, this.localTransform); }, /** - * Returns the frame closest to the given progress value between 0 and 1. + * Adds the given Game Object, or array of Game Objects, to this Container. * - * @method Phaser.Animations.Animation#getFrameByProgress + * Each Game Object must be unique within the Container. + * + * @method Phaser.GameObjects.Container#add * @since 3.4.0 * - * @param {number} value - A value between 0 and 1. + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {(T|T[])} - [child] * - * @return {Phaser.Animations.AnimationFrame} The frame closest to the given progress value. + * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container. + * + * @return {this} This Container instance. */ - getFrameByProgress: function (value) + add: function (child) { - value = Clamp(value, 0, 1); + ArrayUtils.Add(this.list, child, this.maxSize, this.addHandler, this); - return FindClosestInSorted(value, this.frames, 'progress'); + return this; }, /** - * Advance the animation frame. + * Adds the given Game Object, or array of Game Objects, to this Container at the specified position. * - * @method Phaser.Animations.Animation#nextFrame - * @since 3.0.0 + * Existing Game Objects in the Container are shifted up. * - * @param {Phaser.Animations.AnimationState} state - The Animation State to advance. + * Each Game Object must be unique within the Container. + * + * @method Phaser.GameObjects.Container#addAt + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {(T|T[])} - [child] + * + * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container. + * @param {number} [index=0] - The position to insert the Game Object/s at. + * + * @return {this} This Container instance. */ - nextFrame: function (state) + addAt: function (child, index) { - var frame = state.currentFrame; - - if (frame.isLast) - { - // We're at the end of the animation + ArrayUtils.AddAt(this.list, child, index, this.maxSize, this.addHandler, this); - // Yoyo? (happens before repeat) - if (state.yoyo) - { - this.handleYoyoFrame(state, false); - } - else if (state.repeatCounter > 0) - { - // Repeat (happens before complete) + return this; + }, - if (state.inReverse && state.forward) - { - state.forward = false; - } - else - { - this.repeatAnimation(state); - } - } - else - { - state.complete(); - } - } - else - { - this.updateAndGetNextTick(state, frame.nextFrame); - } + /** + * Returns the Game Object at the given position in this Container. + * + * @method Phaser.GameObjects.Container#getAt + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [$return] + * + * @param {number} index - The position to get the Game Object from. + * + * @return {?Phaser.GameObjects.GameObject} The Game Object at the specified index, or `null` if none found. + */ + getAt: function (index) + { + return this.list[index]; }, /** - * Handle the yoyo functionality in nextFrame and previousFrame methods. + * Returns the index of the given Game Object in this Container. * - * @method Phaser.Animations.Animation#handleYoyoFrame - * @private - * @since 3.12.0 + * @method Phaser.GameObjects.Container#getIndex + * @since 3.4.0 * - * @param {Phaser.Animations.AnimationState} state - The Animation State to advance. - * @param {boolean} isReverse - Is animation in reverse mode? (Default: false) + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child] + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object to search for in this Container. + * + * @return {number} The index of the Game Object in this Container, or -1 if not found. */ - handleYoyoFrame: function (state, isReverse) + getIndex: function (child) { - if (!isReverse) { isReverse = false; } + return this.list.indexOf(child); + }, - if (state.inReverse === !isReverse && state.repeatCounter > 0) + /** + * Sort the contents of this Container so the items are in order based on the given property. + * For example: `sort('alpha')` would sort the elements based on the value of their `alpha` property. + * + * @method Phaser.GameObjects.Container#sort + * @since 3.4.0 + * + * @param {string} property - The property to lexically sort by. + * @param {function} [handler] - Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean. + * + * @return {this} This Container instance. + */ + sort: function (property, handler) + { + if (!property) { - if (state.repeatDelay === 0 || state.pendingRepeat) - { - state.forward = isReverse; - } - - this.repeatAnimation(state); - - return; + return this; } - if (state.inReverse !== isReverse && state.repeatCounter === 0) + if (handler === undefined) { - state.complete(); - - return; + handler = function (childA, childB) + { + return childA[property] - childB[property]; + }; } - state.forward = isReverse; + ArrayUtils.StableSort(this.list, handler); - var frame = (isReverse) ? state.currentFrame.nextFrame : state.currentFrame.prevFrame; + return this; + }, - this.updateAndGetNextTick(state, frame); + /** + * Searches for the first instance of a child with its `name` property matching the given argument. + * Should more than one child have the same name only the first is returned. + * + * @method Phaser.GameObjects.Container#getByName + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [$return] + * + * @param {string} name - The name to search for. + * + * @return {?Phaser.GameObjects.GameObject} The first child with a matching name, or `null` if none were found. + */ + getByName: function (name) + { + return ArrayUtils.GetFirst(this.list, 'name', name); }, /** - * Returns the animation last frame. + * Returns a random Game Object from this Container. * - * @method Phaser.Animations.Animation#getLastFrame - * @since 3.12.0 + * @method Phaser.GameObjects.Container#getRandom + * @since 3.4.0 * - * @return {Phaser.Animations.AnimationFrame} The last Animation Frame. + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [$return] + * + * @param {number} [startIndex=0] - An optional start index. + * @param {number} [length] - An optional length, the total number of elements (from the startIndex) to choose from. + * + * @return {?Phaser.GameObjects.GameObject} A random child from the Container, or `null` if the Container is empty. */ - getLastFrame: function () + getRandom: function (startIndex, length) { - return this.frames[this.frames.length - 1]; + return ArrayUtils.GetRandom(this.list, startIndex, length); }, /** - * Called internally when the Animation is playing backwards. - * Sets the previous frame, causing a yoyo, repeat, complete or update, accordingly. + * Gets the first Game Object in this Container. * - * @method Phaser.Animations.Animation#previousFrame - * @since 3.0.0 + * You can also specify a property and value to search for, in which case it will return the first + * Game Object in this Container with a matching property and / or value. * - * @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call. + * For example: `getFirst('visible', true)` would return the first Game Object that had its `visible` property set. + * + * You can limit the search to the `startIndex` - `endIndex` range. + * + * @method Phaser.GameObjects.Container#getFirst + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [$return] + * + * @param {string} property - The property to test on each Game Object in the Container. + * @param {*} value - The value to test the property against. Must pass a strict (`===`) comparison check. + * @param {number} [startIndex=0] - An optional start index to search from. + * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) + * + * @return {?Phaser.GameObjects.GameObject} The first matching Game Object, or `null` if none was found. */ - previousFrame: function (state) + getFirst: function (property, value, startIndex, endIndex) { - var frame = state.currentFrame; + return ArrayUtils.GetFirst(this.list, property, value, startIndex, endIndex); + }, - if (frame.isFirst) - { - // We're at the start of the animation - if (state.yoyo) - { - this.handleYoyoFrame(state, true); - } - else if (state.repeatCounter > 0) - { - if (state.inReverse && !state.forward) - { - this.repeatAnimation(state); - } - else - { - // Repeat (happens before complete) - state.forward = true; + /** + * Returns all Game Objects in this Container. + * + * You can optionally specify a matching criteria using the `property` and `value` arguments. + * + * For example: `getAll('body')` would return only Game Objects that have a body property. + * + * You can also specify a value to compare the property to: + * + * `getAll('visible', true)` would return only Game Objects that have their visible property set to `true`. + * + * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects, + * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only + * the first 50 Game Objects. + * + * @method Phaser.GameObjects.Container#getAll + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T[]} - [$return] + * + * @param {string} [property] - The property to test on each Game Object in the Container. + * @param {any} [value] - If property is set then the `property` must strictly equal this value to be included in the results. + * @param {number} [startIndex=0] - An optional start index to search from. + * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) + * + * @return {Phaser.GameObjects.GameObject[]} An array of matching Game Objects from this Container. + */ + getAll: function (property, value, startIndex, endIndex) + { + return ArrayUtils.GetAll(this.list, property, value, startIndex, endIndex); + }, - this.repeatAnimation(state); - } - } - else - { - state.complete(); - } - } - else - { - this.updateAndGetNextTick(state, frame.prevFrame); - } + /** + * Returns the total number of Game Objects in this Container that have a property + * matching the given value. + * + * For example: `count('visible', true)` would count all the elements that have their visible property set. + * + * You can optionally limit the operation to the `startIndex` - `endIndex` range. + * + * @method Phaser.GameObjects.Container#count + * @since 3.4.0 + * + * @param {string} property - The property to check. + * @param {any} value - The value to check. + * @param {number} [startIndex=0] - An optional start index to search from. + * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) + * + * @return {number} The total number of Game Objects in this Container with a property matching the given value. + */ + count: function (property, value, startIndex, endIndex) + { + return ArrayUtils.CountAllMatching(this.list, property, value, startIndex, endIndex); }, /** - * Update Frame and Wait next tick. + * Swaps the position of two Game Objects in this Container. + * Both Game Objects must belong to this Container. * - * @method Phaser.Animations.Animation#updateAndGetNextTick - * @private - * @since 3.12.0 + * @method Phaser.GameObjects.Container#swap + * @since 3.4.0 * - * @param {Phaser.Animations.AnimationState} state - The Animation State. - * @param {Phaser.Animations.AnimationFrame} frame - An Animation frame. + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child1,child2] + * + * @param {Phaser.GameObjects.GameObject} child1 - The first Game Object to swap. + * @param {Phaser.GameObjects.GameObject} child2 - The second Game Object to swap. + * + * @return {this} This Container instance. */ - updateAndGetNextTick: function (state, frame) + swap: function (child1, child2) { - state.setCurrentFrame(frame); + ArrayUtils.Swap(this.list, child1, child2); - this.getNextTick(state); + return this; }, /** - * Removes the given AnimationFrame from this Animation instance. - * This is a global action. Any Game Object using this Animation will be impacted by this change. + * Moves a Game Object to a new position within this Container. * - * @method Phaser.Animations.Animation#removeFrame - * @since 3.0.0 + * The Game Object must already be a child of this Container. * - * @param {Phaser.Animations.AnimationFrame} frame - The AnimationFrame to be removed. + * The Game Object is removed from its old position and inserted into the new one. + * Therefore the Container size does not change. Other children will change position accordingly. * - * @return {this} This Animation object. + * @method Phaser.GameObjects.Container#moveTo + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child] + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object to move. + * @param {number} index - The new position of the Game Object in this Container. + * + * @return {this} This Container instance. */ - removeFrame: function (frame) + moveTo: function (child, index) { - var index = this.frames.indexOf(frame); - - if (index !== -1) - { - this.removeFrameAt(index); - } + ArrayUtils.MoveTo(this.list, child, index); return this; }, /** - * Removes a frame from the AnimationFrame array at the provided index - * and updates the animation accordingly. + * Moves a Game Object above another one within this Container. * - * @method Phaser.Animations.Animation#removeFrameAt - * @since 3.0.0 + * These 2 Game Objects must already be children of this Container. * - * @param {number} index - The index in the AnimationFrame array + * @method Phaser.GameObjects.Container#moveAbove + * @since 3.55.0 * - * @return {this} This Animation object. + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child1,child2] + * + * @param {Phaser.GameObjects.GameObject} child1 - The Game Object to move above base Game Object. + * @param {Phaser.GameObjects.GameObject} child2 - The base Game Object. + * + * @return {this} This Container instance. */ - removeFrameAt: function (index) + moveAbove: function (child1, child2) { - this.frames.splice(index, 1); + ArrayUtils.MoveAbove(this.list, child1, child2); - this.updateFrameSequence(); + return this; + }, + + /** + * Moves a Game Object below another one within this Container. + * + * These 2 Game Objects must already be children of this Container. + * + * @method Phaser.GameObjects.Container#moveBelow + * @since 3.55.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child1,child2] + * + * @param {Phaser.GameObjects.GameObject} child1 - The Game Object to move below base Game Object. + * @param {Phaser.GameObjects.GameObject} child2 - The base Game Object. + * + * @return {this} This Container instance. + */ + moveBelow: function (child1, child2) + { + ArrayUtils.MoveBelow(this.list, child1, child2); return this; }, /** - * Called internally during playback. Forces the animation to repeat, providing there are enough counts left - * in the repeat counter. + * Removes the given Game Object, or array of Game Objects, from this Container. * - * @method Phaser.Animations.Animation#repeatAnimation - * @fires Phaser.Animations.Events#ANIMATION_REPEAT - * @fires Phaser.Animations.Events#SPRITE_ANIMATION_REPEAT - * @fires Phaser.Animations.Events#SPRITE_ANIMATION_KEY_REPEAT - * @since 3.0.0 + * The Game Objects must already be children of this Container. * - * @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call. + * You can also optionally call `destroy` on each Game Object that is removed from the Container. + * + * @method Phaser.GameObjects.Container#remove + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {(T|T[])} - [child] + * + * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to be removed from the Container. + * @param {boolean} [destroyChild=false] - Optionally call `destroy` on each child successfully removed from this Container. + * + * @return {this} This Container instance. */ - repeatAnimation: function (state) + remove: function (child, destroyChild) { - if (state._pendingStop === 2) - { - if (state._pendingStopValue === 0) - { - return state.stop(); - } - else - { - state._pendingStopValue--; - } - } + var removed = ArrayUtils.Remove(this.list, child, this.removeHandler, this); - if (state.repeatDelay > 0 && !state.pendingRepeat) - { - state.pendingRepeat = true; - state.accumulator -= state.nextTick; - state.nextTick += state.repeatDelay; - } - else + if (destroyChild && removed) { - state.repeatCounter--; - - if (state.forward) - { - state.setCurrentFrame(state.currentFrame.nextFrame); - } - else + if (!Array.isArray(removed)) { - state.setCurrentFrame(state.currentFrame.prevFrame); + removed = [ removed ]; } - if (state.isPlaying) + for (var i = 0; i < removed.length; i++) { - this.getNextTick(state); - - state.handleRepeat(); + removed[i].destroy(); } } + + return this; }, /** - * Converts the animation data to JSON. + * Removes the Game Object at the given position in this Container. * - * @method Phaser.Animations.Animation#toJSON - * @since 3.0.0 + * You can also optionally call `destroy` on the Game Object, if one is found. * - * @return {Phaser.Types.Animations.JSONAnimation} The resulting JSONAnimation formatted object. + * @method Phaser.GameObjects.Container#removeAt + * @since 3.4.0 + * + * @param {number} index - The index of the Game Object to be removed. + * @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container. + * + * @return {this} This Container instance. */ - toJSON: function () + removeAt: function (index, destroyChild) { - var output = { - key: this.key, - type: this.type, - frames: [], - frameRate: this.frameRate, - duration: this.duration, - skipMissedFrames: this.skipMissedFrames, - delay: this.delay, - repeat: this.repeat, - repeatDelay: this.repeatDelay, - yoyo: this.yoyo, - showOnStart: this.showOnStart, - hideOnComplete: this.hideOnComplete - }; + var removed = ArrayUtils.RemoveAt(this.list, index, this.removeHandler, this); - this.frames.forEach(function (frame) + if (destroyChild && removed) { - output.frames.push(frame.toJSON()); - }); + removed.destroy(); + } - return output; + return this; }, /** - * Called internally whenever frames are added to, or removed from, this Animation. + * Removes the Game Objects between the given positions in this Container. * - * @method Phaser.Animations.Animation#updateFrameSequence - * @since 3.0.0 + * You can also optionally call `destroy` on each Game Object that is removed from the Container. * - * @return {this} This Animation object. + * @method Phaser.GameObjects.Container#removeBetween + * @since 3.4.0 + * + * @param {number} [startIndex=0] - An optional start index to search from. + * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) + * @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container. + * + * @return {this} This Container instance. */ - updateFrameSequence: function () + removeBetween: function (startIndex, endIndex, destroyChild) { - var len = this.frames.length; - var slice = 1 / (len - 1); - - var frame; + var removed = ArrayUtils.RemoveBetween(this.list, startIndex, endIndex, this.removeHandler, this); - for (var i = 0; i < len; i++) + if (destroyChild) { - frame = this.frames[i]; + for (var i = 0; i < removed.length; i++) + { + removed[i].destroy(); + } + } - frame.index = i + 1; - frame.isFirst = false; - frame.isLast = false; - frame.progress = i * slice; + return this; + }, - if (i === 0) - { - frame.isFirst = true; + /** + * Removes all Game Objects from this Container. + * + * You can also optionally call `destroy` on each Game Object that is removed from the Container. + * + * @method Phaser.GameObjects.Container#removeAll + * @since 3.4.0 + * + * @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container. + * + * @return {this} This Container instance. + */ + removeAll: function (destroyChild) + { + var list = this.list; - if (len === 1) - { - frame.isLast = true; - frame.nextFrame = frame; - frame.prevFrame = frame; - } - else + if (destroyChild) + { + for (var i = 0; i < list.length; i++) + { + if (list[i] && list[i].scene) { - frame.isLast = false; - frame.prevFrame = this.frames[len - 1]; - frame.nextFrame = this.frames[i + 1]; + list[i].off(Events.DESTROY, this.remove, this); + + list[i].destroy(); } } - else if (i === len - 1 && len > 1) - { - frame.isLast = true; - frame.prevFrame = this.frames[len - 2]; - frame.nextFrame = this.frames[0]; - } - else if (len > 1) - { - frame.prevFrame = this.frames[i - 1]; - frame.nextFrame = this.frames[i + 1]; - } + + this.list = []; + } + else + { + ArrayUtils.RemoveBetween(list, 0, list.length, this.removeHandler, this); } return this; }, /** - * Pauses playback of this Animation. The paused state is set immediately. + * Brings the given Game Object to the top of this Container. + * This will cause it to render on-top of any other objects in the Container. * - * @method Phaser.Animations.Animation#pause - * @since 3.0.0 + * @method Phaser.GameObjects.Container#bringToTop + * @since 3.4.0 * - * @return {this} This Animation object. + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child] + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object to bring to the top of the Container. + * + * @return {this} This Container instance. */ - pause: function () + bringToTop: function (child) { - this.paused = true; + ArrayUtils.BringToTop(this.list, child); return this; }, /** - * Resumes playback of this Animation. The paused state is reset immediately. + * Sends the given Game Object to the bottom of this Container. + * This will cause it to render below any other objects in the Container. * - * @method Phaser.Animations.Animation#resume - * @since 3.0.0 + * @method Phaser.GameObjects.Container#sendToBack + * @since 3.4.0 * - * @return {this} This Animation object. + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child] + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object to send to the bottom of the Container. + * + * @return {this} This Container instance. */ - resume: function () + sendToBack: function (child) { - this.paused = false; + ArrayUtils.SendToBack(this.list, child); return this; }, /** - * Destroys this Animation instance. It will remove all event listeners, - * remove this animation and its key from the global Animation Manager, - * and then destroy all Animation Frames in turn. + * Moves the given Game Object up one place in this Container, unless it's already at the top. * - * @method Phaser.Animations.Animation#destroy - * @since 3.0.0 + * @method Phaser.GameObjects.Container#moveUp + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child] + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container. + * + * @return {this} This Container instance. */ - destroy: function () + moveUp: function (child) { - if (this.manager.off) - { - this.manager.off(Events.PAUSE_ALL, this.pause, this); - this.manager.off(Events.RESUME_ALL, this.resume, this); - } + ArrayUtils.MoveUp(this.list, child); - this.manager.remove(this.key); + return this; + }, - for (var i = 0; i < this.frames.length; i++) - { - this.frames[i].destroy(); - } + /** + * Moves the given Game Object down one place in this Container, unless it's already at the bottom. + * + * @method Phaser.GameObjects.Container#moveDown + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child] + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container. + * + * @return {this} This Container instance. + */ + moveDown: function (child) + { + ArrayUtils.MoveDown(this.list, child); - this.frames = []; + return this; + }, - this.manager = null; - } + /** + * Reverses the order of all Game Objects in this Container. + * + * @method Phaser.GameObjects.Container#reverse + * @since 3.4.0 + * + * @return {this} This Container instance. + */ + reverse: function () + { + this.list.reverse(); -}); + return this; + }, -module.exports = Animation; + /** + * Shuffles the all Game Objects in this Container using the Fisher-Yates implementation. + * + * @method Phaser.GameObjects.Container#shuffle + * @since 3.4.0 + * + * @return {this} This Container instance. + */ + shuffle: function () + { + ArrayUtils.Shuffle(this.list); + return this; + }, -/***/ }), -/* 186 */ -/***/ (function(module, exports) { + /** + * Replaces a Game Object in this Container with the new Game Object. + * The new Game Object cannot already be a child of this Container. + * + * @method Phaser.GameObjects.Container#replace + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [oldChild,newChild] + * + * @param {Phaser.GameObjects.GameObject} oldChild - The Game Object in this Container that will be replaced. + * @param {Phaser.GameObjects.GameObject} newChild - The Game Object to be added to this Container. + * @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container. + * + * @return {this} This Container instance. + */ + replace: function (oldChild, newChild, destroyChild) + { + var moved = ArrayUtils.Replace(this.list, oldChild, newChild); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (moved) + { + this.addHandler(newChild); + this.removeHandler(oldChild); -/** - * Takes the given string and pads it out, to the length required, using the character - * specified. For example if you need a string to be 6 characters long, you can call: - * - * `pad('bob', 6, '-', 2)` - * - * This would return: `bob---` as it has padded it out to 6 characters, using the `-` on the right. - * - * You can also use it to pad numbers (they are always returned as strings): - * - * `pad(512, 6, '0', 1)` - * - * Would return: `000512` with the string padded to the left. - * - * If you don't specify a direction it'll pad to both sides: - * - * `pad('c64', 7, '*')` - * - * Would return: `**c64**` - * - * @function Phaser.Utils.String.Pad - * @since 3.0.0 - * - * @param {string|number|object} str - The target string. `toString()` will be called on the string, which means you can also pass in common data types like numbers. - * @param {number} [len=0] - The number of characters to be added. - * @param {string} [pad=" "] - The string to pad it out with (defaults to a space). - * @param {number} [dir=3] - The direction dir = 1 (left), 2 (right), 3 (both). - * - * @return {string} The padded string. - */ -var Pad = function (str, len, pad, dir) -{ - if (len === undefined) { len = 0; } - if (pad === undefined) { pad = ' '; } - if (dir === undefined) { dir = 3; } + if (destroyChild) + { + oldChild.destroy(); + } + } - str = str.toString(); + return this; + }, - var padlen = 0; + /** + * Returns `true` if the given Game Object is a direct child of this Container. + * + * This check does not scan nested Containers. + * + * @method Phaser.GameObjects.Container#exists + * @since 3.4.0 + * + * @generic {Phaser.GameObjects.GameObject} T + * @genericUse {T} - [child] + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object to check for within this Container. + * + * @return {boolean} True if the Game Object is an immediate child of this Container, otherwise false. + */ + exists: function (child) + { + return (this.list.indexOf(child) > -1); + }, - if (len + 1 >= str.length) + /** + * Sets the property to the given value on all Game Objects in this Container. + * + * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects, + * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only + * the first 50 Game Objects. + * + * @method Phaser.GameObjects.Container#setAll + * @since 3.4.0 + * + * @param {string} property - The property that must exist on the Game Object. + * @param {any} value - The value to get the property to. + * @param {number} [startIndex=0] - An optional start index to search from. + * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) + * + * @return {this} This Container instance. + */ + setAll: function (property, value, startIndex, endIndex) { - switch (dir) - { - case 1: - str = new Array(len + 1 - str.length).join(pad) + str; - break; + ArrayUtils.SetAll(this.list, property, value, startIndex, endIndex); - case 3: - var right = Math.ceil((padlen = len - str.length) / 2); - var left = padlen - right; - str = new Array(left + 1).join(pad) + str + new Array(right + 1).join(pad); - break; + return this; + }, - default: - str = str + new Array(len + 1 - str.length).join(pad); - break; - } - } + /** + * @callback EachContainerCallback + * @generic I - [item] + * + * @param {*} item - The child Game Object of the Container. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + */ - return str; -}; + /** + * Passes all Game Objects in this Container to the given callback. + * + * A copy of the Container is made before passing each entry to your callback. + * This protects against the callback itself modifying the Container. + * + * If you know for sure that the callback will not change the size of this Container + * then you can use the more performant `Container.iterate` method instead. + * + * @method Phaser.GameObjects.Container#each + * @since 3.4.0 + * + * @param {function} callback - The function to call. + * @param {object} [context] - Value to use as `this` when executing callback. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + * + * @return {this} This Container instance. + */ + each: function (callback, context) + { + var args = [ null ]; + var i; + var temp = this.list.slice(); + var len = temp.length; -module.exports = Pad; + for (i = 2; i < arguments.length; i++) + { + args.push(arguments[i]); + } + for (i = 0; i < len; i++) + { + args[0] = temp[i]; -/***/ }), -/* 187 */ -/***/ (function(module, exports, __webpack_require__) { + callback.apply(context, args); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var HexStringToColor = __webpack_require__(327); -var IntegerToColor = __webpack_require__(189); -var ObjectToColor = __webpack_require__(331); -var RGBStringToColor = __webpack_require__(332); + /** + * Passes all Game Objects in this Container to the given callback. + * + * Only use this method when you absolutely know that the Container will not be modified during + * the iteration, i.e. by removing or adding to its contents. + * + * @method Phaser.GameObjects.Container#iterate + * @since 3.4.0 + * + * @param {function} callback - The function to call. + * @param {object} [context] - Value to use as `this` when executing callback. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + * + * @return {this} This Container instance. + */ + iterate: function (callback, context) + { + var args = [ null ]; + var i; -/** - * Converts the given source color value into an instance of a Color class. - * The value can be either a string, prefixed with `rgb` or a hex string, a number or an Object. - * - * @function Phaser.Display.Color.ValueToColor - * @since 3.0.0 - * - * @param {(string|number|Phaser.Types.Display.InputColorObject)} input - The source color value to convert. - * - * @return {Phaser.Display.Color} A Color object. - */ -var ValueToColor = function (input) -{ - var t = typeof input; + for (i = 2; i < arguments.length; i++) + { + args.push(arguments[i]); + } - switch (t) - { - case 'string': + for (i = 0; i < this.list.length; i++) + { + args[0] = this.list[i]; - if (input.substr(0, 3).toLowerCase() === 'rgb') - { - return RGBStringToColor(input); + callback.apply(context, args); + } + + return this; + }, + + /** + * Sets the scroll factor of this Container and optionally all of its children. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * + * @method Phaser.GameObjects.Container#setScrollFactor + * @since 3.4.0 + * + * @param {number} x - The horizontal scroll factor of this Game Object. + * @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value. + * @param {boolean} [updateChildren=false] - Apply this scrollFactor to all Container children as well? + * + * @return {this} This Game Object instance. + */ + setScrollFactor: function (x, y, updateChildren) + { + if (y === undefined) { y = x; } + if (updateChildren === undefined) { updateChildren = false; } + + this.scrollFactorX = x; + this.scrollFactorY = y; + + if (updateChildren) + { + ArrayUtils.SetAll(this.list, 'scrollFactorX', x); + ArrayUtils.SetAll(this.list, 'scrollFactorY', y); + } + + return this; + }, + + /** + * The number of Game Objects inside this Container. + * + * @name Phaser.GameObjects.Container#length + * @type {number} + * @readonly + * @since 3.4.0 + */ + length: { + + get: function () + { + return this.list.length; + } + + }, + + /** + * Returns the first Game Object within the Container, or `null` if it is empty. + * + * You can move the cursor by calling `Container.next` and `Container.previous`. + * + * @name Phaser.GameObjects.Container#first + * @type {?Phaser.GameObjects.GameObject} + * @readonly + * @since 3.4.0 + */ + first: { + + get: function () + { + this.position = 0; + + if (this.list.length > 0) + { + return this.list[0]; } else { - return HexStringToColor(input); + return null; } + } - case 'number': + }, - return IntegerToColor(input); + /** + * Returns the last Game Object within the Container, or `null` if it is empty. + * + * You can move the cursor by calling `Container.next` and `Container.previous`. + * + * @name Phaser.GameObjects.Container#last + * @type {?Phaser.GameObjects.GameObject} + * @readonly + * @since 3.4.0 + */ + last: { - case 'object': + get: function () + { + if (this.list.length > 0) + { + this.position = this.list.length - 1; - return ObjectToColor(input); + return this.list[this.position]; + } + else + { + return null; + } + } + + }, + + /** + * Returns the next Game Object within the Container, or `null` if it is empty. + * + * You can move the cursor by calling `Container.next` and `Container.previous`. + * + * @name Phaser.GameObjects.Container#next + * @type {?Phaser.GameObjects.GameObject} + * @readonly + * @since 3.4.0 + */ + next: { + + get: function () + { + if (this.position < this.list.length) + { + this.position++; + + return this.list[this.position]; + } + else + { + return null; + } + } + + }, + + /** + * Returns the previous Game Object within the Container, or `null` if it is empty. + * + * You can move the cursor by calling `Container.next` and `Container.previous`. + * + * @name Phaser.GameObjects.Container#previous + * @type {?Phaser.GameObjects.GameObject} + * @readonly + * @since 3.4.0 + */ + previous: { + + get: function () + { + if (this.position > 0) + { + this.position--; + + return this.list[this.position]; + } + else + { + return null; + } + } + + }, + + /** + * Internal destroy handler, called as part of the destroy process. + * + * @method Phaser.GameObjects.Container#preDestroy + * @protected + * @since 3.9.0 + */ + preDestroy: function () + { + this.removeAll(!!this.exclusive); + + this.localTransform.destroy(); + this.tempTransformMatrix.destroy(); + + this.list = []; } -}; -module.exports = ValueToColor; +}); + +module.exports = Container; /***/ }), -/* 188 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 13916: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetColor = __webpack_require__(103); - /** - * RGB space conversion. - * - * @ignore + * 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. * - * @param {number} n - The value to convert. - * @param {number} h - The h value. - * @param {number} s - The s value. - * @param {number} v - The v value. + * @method Phaser.GameObjects.Container#renderCanvas + * @since 3.4.0 + * @private * - * @return {number} The converted value. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested */ -function ConvertValue (n, h, s, v) +var ContainerCanvasRenderer = function (renderer, container, camera, parentMatrix) { - var k = (n + h * 6) % 6; + camera.addToRenderList(container); - var min = Math.min(k, 4 - k, 1); + var children = container.list; - return Math.round(255 * (v - v * s * Math.max(0, min))); -} + if (children.length === 0) + { + return; + } -/** - * Converts a HSV (hue, saturation and value) color set to RGB. - * - * Conversion formula from https://en.wikipedia.org/wiki/HSL_and_HSV - * - * Assumes HSV values are contained in the set [0, 1]. - * - * @function Phaser.Display.Color.HSVToRGB - * @since 3.0.0 - * - * @param {number} h - The hue, in the range 0 - 1. This is the base color. - * @param {number} s - The saturation, in the range 0 - 1. This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white. - * @param {number} v - The value, in the range 0 - 1. This controls how dark the color is. Where 1 is as bright as possible and 0 is black. - * @param {(Phaser.Types.Display.ColorObject|Phaser.Display.Color)} [out] - A Color object to store the results in. If not given a new ColorObject will be created. - * - * @return {(Phaser.Types.Display.ColorObject|Phaser.Display.Color)} An object with the red, green and blue values set in the r, g and b properties. - */ -var HSVToRGB = function (h, s, v, out) -{ - if (s === undefined) { s = 1; } - if (v === undefined) { v = 1; } + var transformMatrix = container.localTransform; - var r = ConvertValue(5, h, s, v); - var g = ConvertValue(3, h, s, v); - var b = ConvertValue(1, h, s, v); + if (parentMatrix) + { + transformMatrix.loadIdentity(); + transformMatrix.multiply(parentMatrix); + transformMatrix.translate(container.x, container.y); + transformMatrix.rotate(container.rotation); + transformMatrix.scale(container.scaleX, container.scaleY); + } + else + { + transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY); + } - if (!out) + var containerHasBlendMode = (container.blendMode !== -1); + + if (!containerHasBlendMode) { - return { r: r, g: g, b: b, color: GetColor(r, g, b) }; + // If Container is SKIP_TEST then set blend mode to be Normal + renderer.setBlendMode(0); } - else if (out.setTo) + + var alpha = container._alpha; + var scrollFactorX = container.scrollFactorX; + var scrollFactorY = container.scrollFactorY; + + if (container.mask) { - return out.setTo(r, g, b, out.alpha, false); + container.mask.preRenderCanvas(renderer, null, camera); } - else + + for (var i = 0; i < children.length; i++) { - out.r = r; - out.g = g; - out.b = b; - out.color = GetColor(r, g, b); + var child = children[i]; - return out; + if (!child.willRender(camera)) + { + continue; + } + + var childAlpha = child.alpha; + var childScrollFactorX = child.scrollFactorX; + var childScrollFactorY = child.scrollFactorY; + + if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode) + { + // If Container doesn't have its own blend mode, then a child can have one + renderer.setBlendMode(child.blendMode); + } + + // Set parent values + child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY); + child.setAlpha(childAlpha * alpha); + + // Render + child.renderCanvas(renderer, child, camera, transformMatrix); + + // Restore original values + child.setAlpha(childAlpha); + child.setScrollFactor(childScrollFactorX, childScrollFactorY); + } + + if (container.mask) + { + container.mask.postRenderCanvas(renderer); } }; -module.exports = HSVToRGB; +module.exports = ContainerCanvasRenderer; /***/ }), -/* 189 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 44516: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(38); -var IntegerToRGB = __webpack_require__(330); +var BuildGameObject = __webpack_require__(88933); +var Container = __webpack_require__(70339); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); /** - * Converts the given color value into an instance of a Color object. + * Creates a new Container Game Object and returns it. * - * @function Phaser.Display.Color.IntegerToColor - * @since 3.0.0 + * Note: This method will only be available if the Container Game Object has been built into Phaser. * - * @param {number} input - The color value to convert into a Color object. + * @method Phaser.GameObjects.GameObjectCreator#container + * @since 3.4.0 * - * @return {Phaser.Display.Color} A Color object. + * @param {Phaser.Types.GameObjects.Container.ContainerConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Container} The Game Object that was created. */ -var IntegerToColor = function (input) +GameObjectCreator.register('container', function (config, addToScene) { - var rgb = IntegerToRGB(input); + if (config === undefined) { config = {}; } - return new Color(rgb.r, rgb.g, rgb.b, rgb.a); -}; + var x = GetAdvancedValue(config, 'x', 0); + var y = GetAdvancedValue(config, 'y', 0); + var children = GetAdvancedValue(config, 'children', null); -module.exports = IntegerToColor; + var container = new Container(this.scene, x, y, children); + + if (addToScene !== undefined) + { + config.add = addToScene; + } + + BuildGameObject(this.scene, container, config); + + return container; +}); /***/ }), -/* 190 */ -/***/ (function(module, exports) { + +/***/ 23400: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// Centers this Rectangle so that the center coordinates match the given x and y values. +var Container = __webpack_require__(70339); +var GameObjectFactory = __webpack_require__(61286); /** - * Moves the top-left corner of a Rectangle so that its center is at the given coordinates. + * Creates a new Container Game Object and adds it to the Scene. * - * @function Phaser.Geom.Rectangle.CenterOn - * @since 3.0.0 + * Note: This method will only be available if the Container Game Object has been built into Phaser. * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] + * @method Phaser.GameObjects.GameObjectFactory#container + * @since 3.4.0 * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to be centered. - * @param {number} x - The X coordinate of the Rectangle's center. - * @param {number} y - The Y coordinate of the Rectangle's center. + * @param {number} [x=0] - The horizontal position of this Game Object in the world. + * @param {number} [y=0] - The vertical position of this Game Object in the world. + * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Container. * - * @return {Phaser.Geom.Rectangle} The centered rectangle. + * @return {Phaser.GameObjects.Container} The Game Object that was created. */ -var CenterOn = function (rect, x, y) +GameObjectFactory.register('container', function (x, y, children) { - rect.x = x - (rect.width / 2); - rect.y = y - (rect.height / 2); - - return rect; -}; - -module.exports = CenterOn; + return this.displayList.add(new Container(this.scene, x, y, children)); +}); /***/ }), -/* 191 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 98524: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var OS = __webpack_require__(105); -var Browser = __webpack_require__(136); -var CanvasPool = __webpack_require__(31); - -/** - * Determines the features of the browser running this Phaser Game instance. - * These values are read-only and populated during the boot sequence of the game. - * They are then referenced by internal game systems and are available for you to access - * via `this.sys.game.device.features` from within any Scene. - * - * @typedef {object} Phaser.Device.Features - * @since 3.0.0 - * - * @property {?boolean} canvasBitBltShift - True if canvas supports a 'copy' bitblt onto itself when the source and destination regions overlap. - * @property {boolean} canvas - Is canvas available? - * @property {boolean} file - Is file available? - * @property {boolean} fileSystem - Is fileSystem available? - * @property {boolean} getUserMedia - Does the device support the getUserMedia API? - * @property {boolean} littleEndian - Is the device big or little endian? (only detected if the browser supports TypedArrays) - * @property {boolean} localStorage - Is localStorage available? - * @property {boolean} pointerLock - Is Pointer Lock available? - * @property {boolean} support32bit - Does the device context support 32bit pixel manipulation using array buffer views? - * @property {boolean} vibration - Does the device support the Vibration API? - * @property {boolean} webGL - Is webGL available? - * @property {boolean} worker - Is worker available? - */ -var Features = { - - canvas: false, - canvasBitBltShift: null, - file: false, - fileSystem: false, - getUserMedia: true, - littleEndian: false, - localStorage: false, - pointerLock: false, - support32bit: false, - vibration: false, - webGL: false, - worker: false - -}; +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; -// Check Little or Big Endian system. -// @author Matt DesLauriers (@mattdesl) -function checkIsLittleEndian () +if (true) { - var a = new ArrayBuffer(4); - var b = new Uint8Array(a); - var c = new Uint32Array(a); - - b[0] = 0xa1; - b[1] = 0xb2; - b[2] = 0xc3; - b[3] = 0xd4; - - if (c[0] === 0xd4c3b2a1) - { - return true; - } - - if (c[0] === 0xa1b2c3d4) - { - return false; - } - else - { - // Could not determine endianness - return null; - } + renderWebGL = __webpack_require__(36934); } -function init () +if (true) { - if (typeof importScripts === 'function') - { - return Features; - } - - Features.canvas = !!window['CanvasRenderingContext2D']; - - try - { - Features.localStorage = !!localStorage.getItem; - } - catch (error) - { - Features.localStorage = false; - } - - Features.file = !!window['File'] && !!window['FileReader'] && !!window['FileList'] && !!window['Blob']; - Features.fileSystem = !!window['requestFileSystem']; - - var isUint8 = false; - - var testWebGL = function () - { - if (window['WebGLRenderingContext']) - { - try - { - var canvas = CanvasPool.createWebGL(this); - - var ctx = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); - - var canvas2D = CanvasPool.create2D(this); - - var ctx2D = canvas2D.getContext('2d'); - - // Can't be done on a webgl context - var image = ctx2D.createImageData(1, 1); - - // Test to see if ImageData uses CanvasPixelArray or Uint8ClampedArray. - // @author Matt DesLauriers (@mattdesl) - isUint8 = image.data instanceof Uint8ClampedArray; + renderCanvas = __webpack_require__(13916); +} - CanvasPool.remove(canvas); - CanvasPool.remove(canvas2D); +module.exports = { - return !!ctx; - } - catch (e) - { - return false; - } - } + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - return false; - }; +}; - Features.webGL = testWebGL(); - Features.worker = !!window['Worker']; +/***/ }), - Features.pointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document; +/***/ 36934: +/***/ ((module) => { - navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia; +/** + * @author Richard Davey + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL; +/** + * Renders this Game Object with the WebGL Renderer to the given Camera. + * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. + * This method should not be called directly. It is a utility function of the Render module. + * + * @method Phaser.GameObjects.Container#renderWebGL + * @since 3.4.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested + */ +var ContainerWebGLRenderer = function (renderer, container, camera, parentMatrix) +{ + camera.addToRenderList(container); - Features.getUserMedia = Features.getUserMedia && !!navigator.getUserMedia && !!window.URL; + var children = container.list; + var childCount = children.length; - // Older versions of firefox (< 21) apparently claim support but user media does not actually work - if (Browser.firefox && Browser.firefoxVersion < 21) + if (childCount === 0) { - Features.getUserMedia = false; + return; } - // Excludes iOS versions as they generally wrap UIWebView (eg. Safari WebKit) and it - // is safer to not try and use the fast copy-over method. - if (!OS.iOS && (Browser.ie || Browser.firefox || Browser.chrome)) + var transformMatrix = container.localTransform; + + if (parentMatrix) { - Features.canvasBitBltShift = true; + transformMatrix.loadIdentity(); + transformMatrix.multiply(parentMatrix); + transformMatrix.translate(container.x, container.y); + transformMatrix.rotate(container.rotation); + transformMatrix.scale(container.scaleX, container.scaleY); } - - // Known not to work - if (Browser.safari || Browser.mobileSafari) + else { - Features.canvasBitBltShift = false; + transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY); } - navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate; + renderer.pipelines.preBatch(container); - if (navigator.vibrate) - { - Features.vibration = true; - } + var containerHasBlendMode = (container.blendMode !== -1); - if (typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined' && typeof Uint32Array !== 'undefined') + if (!containerHasBlendMode) { - Features.littleEndian = checkIsLittleEndian(); + // If Container is SKIP_TEST then set blend mode to be Normal + renderer.setBlendMode(0); } - Features.support32bit = ( - typeof ArrayBuffer !== 'undefined' && - typeof Uint8ClampedArray !== 'undefined' && - typeof Int32Array !== 'undefined' && - Features.littleEndian !== null && - isUint8 - ); - - return Features; -} - -module.exports = init(); - - -/***/ }), -/* 192 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var alpha = container.alpha; -// Browser specific prefix, so not going to change between contexts, only between browsers -var prefix = ''; + var scrollFactorX = container.scrollFactorX; + var scrollFactorY = container.scrollFactorY; -/** - * @namespace Phaser.Display.Canvas.Smoothing - * @since 3.0.0 - */ -var Smoothing = function () -{ - /** - * Gets the Smoothing Enabled vendor prefix being used on the given context, or null if not set. - * - * @function Phaser.Display.Canvas.Smoothing.getPrefix - * @since 3.0.0 - * - * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The canvas context to check. - * - * @return {string} The name of the property on the context which controls image smoothing (either `imageSmoothingEnabled` or a vendor-prefixed version thereof), or `null` if not supported. - */ - var getPrefix = function (context) + for (var i = 0; i < childCount; i++) { - var vendors = [ 'i', 'webkitI', 'msI', 'mozI', 'oI' ]; + var child = children[i]; - for (var i = 0; i < vendors.length; i++) + if (!child.willRender(camera)) { - var s = vendors[i] + 'mageSmoothingEnabled'; - - if (s in context) - { - return s; - } + continue; } - return null; - }; + var childAlphaTopLeft; + var childAlphaTopRight; + var childAlphaBottomLeft; + var childAlphaBottomRight; - /** - * Sets the Image Smoothing property on the given context. Set to false to disable image smoothing. - * By default browsers have image smoothing enabled, which isn't always what you visually want, especially - * when using pixel art in a game. Note that this sets the property on the context itself, so that any image - * drawn to the context will be affected. This sets the property across all current browsers but support is - * patchy on earlier browsers, especially on mobile. - * - * @function Phaser.Display.Canvas.Smoothing.enable - * @since 3.0.0 - * - * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The context on which to enable smoothing. - * - * @return {(CanvasRenderingContext2D|WebGLRenderingContext)} The provided context. - */ - var enable = function (context) - { - if (prefix === '') + if (child.alphaTopLeft !== undefined) { - prefix = getPrefix(context); + childAlphaTopLeft = child.alphaTopLeft; + childAlphaTopRight = child.alphaTopRight; + childAlphaBottomLeft = child.alphaBottomLeft; + childAlphaBottomRight = child.alphaBottomRight; } - - if (prefix) + else { - context[prefix] = true; + var childAlpha = child.alpha; + + childAlphaTopLeft = childAlpha; + childAlphaTopRight = childAlpha; + childAlphaBottomLeft = childAlpha; + childAlphaBottomRight = childAlpha; } - return context; - }; + var childScrollFactorX = child.scrollFactorX; + var childScrollFactorY = child.scrollFactorY; - /** - * Sets the Image Smoothing property on the given context. Set to false to disable image smoothing. - * By default browsers have image smoothing enabled, which isn't always what you visually want, especially - * when using pixel art in a game. Note that this sets the property on the context itself, so that any image - * drawn to the context will be affected. This sets the property across all current browsers but support is - * patchy on earlier browsers, especially on mobile. - * - * @function Phaser.Display.Canvas.Smoothing.disable - * @since 3.0.0 - * - * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The context on which to disable smoothing. - * - * @return {(CanvasRenderingContext2D|WebGLRenderingContext)} The provided context. - */ - var disable = function (context) - { - if (prefix === '') + if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode) { - prefix = getPrefix(context); + // If Container doesn't have its own blend mode, then a child can have one + renderer.setBlendMode(child.blendMode); } - if (prefix) + var mask = child.mask; + + if (mask) { - context[prefix] = false; + mask.preRenderWebGL(renderer, child, camera); } - return context; - }; - - /** - * Returns `true` if the given context has image smoothing enabled, otherwise returns `false`. - * Returns null if no smoothing prefix is available. - * - * @function Phaser.Display.Canvas.Smoothing.isEnabled - * @since 3.0.0 - * - * @param {(CanvasRenderingContext2D|WebGLRenderingContext)} context - The context to check. - * - * @return {?boolean} `true` if smoothing is enabled on the context, otherwise `false`. `null` if not supported. - */ - var isEnabled = function (context) - { - return (prefix !== null) ? context[prefix] : null; - }; - - return { - disable: disable, - enable: enable, - getPrefix: getPrefix, - isEnabled: isEnabled - }; - -}; - -module.exports = Smoothing(); + var type = child.type; + if (type !== renderer.currentType) + { + renderer.newType = true; + renderer.currentType = type; + } -/***/ }), -/* 193 */ -/***/ (function(module, exports, __webpack_require__) { + renderer.nextTypeMatch = (i < childCount - 1) ? (children[i + 1].type === renderer.currentType) : false; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Set parent values + child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY); -var CONST = __webpack_require__(14); -var Extend = __webpack_require__(17); + child.setAlpha(childAlphaTopLeft * alpha, childAlphaTopRight * alpha, childAlphaBottomLeft * alpha, childAlphaBottomRight * alpha); -/** - * @namespace Phaser.Math - */ + // Render + child.renderWebGL(renderer, child, camera, transformMatrix, container); -var PhaserMath = { + // Restore original values - // Collections of functions - Angle: __webpack_require__(812), - Distance: __webpack_require__(821), - Easing: __webpack_require__(826), - Fuzzy: __webpack_require__(827), - Interpolation: __webpack_require__(830), - Pow2: __webpack_require__(835), - Snap: __webpack_require__(837), + child.setAlpha(childAlphaTopLeft, childAlphaTopRight, childAlphaBottomLeft, childAlphaBottomRight); - // Expose the RNG Class - RandomDataGenerator: __webpack_require__(839), + child.setScrollFactor(childScrollFactorX, childScrollFactorY); - // Single functions - Average: __webpack_require__(840), - Bernstein: __webpack_require__(356), - Between: __webpack_require__(195), - CatmullRom: __webpack_require__(194), - CeilTo: __webpack_require__(841), - Clamp: __webpack_require__(18), - DegToRad: __webpack_require__(36), - Difference: __webpack_require__(842), - Euler: __webpack_require__(843), - Factorial: __webpack_require__(357), - FloatBetween: __webpack_require__(137), - FloorTo: __webpack_require__(844), - FromPercent: __webpack_require__(98), - GetSpeed: __webpack_require__(845), - IsEven: __webpack_require__(846), - IsEvenStrict: __webpack_require__(847), - Linear: __webpack_require__(135), - MaxAdd: __webpack_require__(848), - Median: __webpack_require__(849), - MinSub: __webpack_require__(850), - Percent: __webpack_require__(851), - RadToDeg: __webpack_require__(196), - RandomXY: __webpack_require__(852), - RandomXYZ: __webpack_require__(853), - RandomXYZW: __webpack_require__(854), - Rotate: __webpack_require__(362), - RotateAround: __webpack_require__(308), - RotateAroundDistance: __webpack_require__(182), - RotateTo: __webpack_require__(855), - RoundAwayFromZero: __webpack_require__(363), - RoundTo: __webpack_require__(856), - SinCosTableGenerator: __webpack_require__(857), - SmootherStep: __webpack_require__(183), - SmoothStep: __webpack_require__(184), - ToXY: __webpack_require__(858), - TransformXY: __webpack_require__(177), - Within: __webpack_require__(859), - Wrap: __webpack_require__(68), + if (mask) + { + mask.postRenderWebGL(renderer, camera); + } - // Vector classes - Vector2: __webpack_require__(3), - Vector3: __webpack_require__(39), - Vector4: __webpack_require__(140), - Matrix3: __webpack_require__(364), - Matrix4: __webpack_require__(69), - Quaternion: __webpack_require__(365), - RotateVec3: __webpack_require__(860) + renderer.newType = false; + } + renderer.pipelines.postBatch(container); }; -// Merge in the consts - -PhaserMath = Extend(false, PhaserMath, CONST); - -// Export it - -module.exports = PhaserMath; +module.exports = ContainerWebGLRenderer; /***/ }), -/* 194 */ -/***/ (function(module, exports) { + +/***/ 2452: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Calculates a Catmull-Rom value from the given points, based on an alpha of 0.5. - * - * @function Phaser.Math.CatmullRom - * @since 3.0.0 - * - * @param {number} t - The amount to interpolate by. - * @param {number} p0 - The first control point. - * @param {number} p1 - The second control point. - * @param {number} p2 - The third control point. - * @param {number} p3 - The fourth control point. + * Phaser Blend Modes to CSS Blend Modes Map. * - * @return {number} The Catmull-Rom value. + * @name Phaser.CSSBlendModes + * @ignore + * @enum {string} + * @memberof Phaser + * @readonly + * @since 3.12.0 */ -var CatmullRom = function (t, p0, p1, p2, p3) -{ - var v0 = (p2 - p0) * 0.5; - var v1 = (p3 - p1) * 0.5; - var t2 = t * t; - var t3 = t * t2; - - return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; -}; -module.exports = CatmullRom; +module.exports = [ + 'normal', + 'multiply', + 'multiply', + 'screen', + 'overlay', + 'darken', + 'lighten', + 'color-dodge', + 'color-burn', + 'hard-light', + 'soft-light', + 'difference', + 'exclusion', + 'hue', + 'saturation', + 'color', + 'luminosity' +]; /***/ }), -/* 195 */ -/***/ (function(module, exports) { + +/***/ 38943: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var DOMElementRender = __webpack_require__(11603); +var GameObject = __webpack_require__(89980); +var IsPlainObject = __webpack_require__(42911); +var RemoveFromDOM = __webpack_require__(55638); +var SCENE_EVENTS = __webpack_require__(7599); +var Vector4 = __webpack_require__(51729); + /** - * Compute a random integer between the `min` and `max` values, inclusive. + * @classdesc + * DOM Element Game Objects are a way to control and manipulate HTML Elements over the top of your game. * - * @function Phaser.Math.Between - * @since 3.0.0 + * In order for DOM Elements to display you have to enable them by adding the following to your game + * configuration object: * - * @param {number} min - The minimum value. - * @param {number} max - The maximum value. + * ```javascript + * dom { + * createContainer: true + * } + * ``` * - * @return {number} The random integer. - */ -var Between = function (min, max) -{ - return Math.floor(Math.random() * (max - min + 1) + min); -}; - -module.exports = Between; - - -/***/ }), -/* 196 */ -/***/ (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__(14); - -/** - * Convert the given angle in radians, to the equivalent angle in degrees. + * You must also have a parent container for Phaser. This is specified by the `parent` property in the + * game config. * - * @function Phaser.Math.RadToDeg - * @since 3.0.0 + * When these two things are 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. * - * @param {number} radians - The angle in radians to convert ot degrees. + * 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. * - * @return {number} The given angle converted to degrees. + * 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 RadToDeg = function (radians) -{ - return radians * CONST.RAD_TO_DEG; -}; - -module.exports = RadToDeg; +var DOMElement = new Class({ + Extends: GameObject, -/***/ }), -/* 197 */ -/***/ (function(module, exports, __webpack_require__) { + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.Depth, + Components.Origin, + Components.ScrollFactor, + Components.Transform, + Components.Visible, + DOMElementRender + ], -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + initialize: -/** - * The Default Plugins. - * - * @namespace Phaser.Plugins.DefaultPlugins - * @memberof Phaser.Plugins - * @since 3.0.0 - */ + function DOMElement (scene, x, y, element, style, innerText) + { + GameObject.call(this, scene, 'DOMElement'); -var DefaultPlugins = { + /** + * 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; - /** - * These are the Global Managers that are created by the Phaser.Game instance. - * They are referenced from Scene.Systems so that plugins can use them. - * - * @name Phaser.Plugins.DefaultPlugins.Global - * @type {array} - * @since 3.0.0 - */ - Global: [ + /** + * 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; - 'game', - 'anims', - 'cache', - 'plugins', - 'registry', - 'scale', - 'sound', - 'textures', - 'renderer' + /** + * 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; - /** - * These are the core plugins that are installed into every Scene.Systems instance, no matter what. - * They are optionally exposed in the Scene as well (see the InjectionMap for details) - * - * They are created in the order in which they appear in this array and EventEmitter is always first. - * - * @name Phaser.Plugins.DefaultPlugins.CoreScene - * @type {array} - * @since 3.0.0 - */ - CoreScene: [ - - 'EventEmitter', - - 'CameraManager', - 'GameObjectCreator', - 'GameObjectFactory', - 'ScenePlugin', - 'DisplayList', - 'UpdateList' - - ], - - /** - * These plugins are created in Scene.Systems in addition to the CoreScenePlugins. - * - * You can elect not to have these plugins by either creating a DefaultPlugins object as part - * of the Game Config, by creating a Plugins object as part of a Scene Config, or by modifying this array - * and building your own bundle. - * - * They are optionally exposed in the Scene as well (see the InjectionMap for details) - * - * They are always created in the order in which they appear in the array. - * - * @name Phaser.Plugins.DefaultPlugins.DefaultScene - * @type {array} - * @since 3.0.0 - */ - DefaultScene: [ - - 'Clock', - 'DataManagerPlugin', - 'InputPlugin', - 'Loader', - 'TweenManager', - 'LightsPlugin' - - ] - -}; - -if (false) -{} - -if (false) -{} - -module.exports = DefaultPlugins; - - -/***/ }), -/* 198 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var Class = __webpack_require__(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(); -/** - * @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({ + /** + * 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'; - initialize: + /** + * Sets the CSS `pointerEvents` attribute on the DOM Element during rendering. + * + * This is 'auto' by default. Changing it may have unintended side-effects with + * internal Phaser input handling, such as dragging, so only change this if you + * understand the implications. + * + * @name Phaser.GameObjects.DOMElement#pointerEvents + * @type {string} + * @since 3.55.0 + */ + this.pointerEvents = 'auto'; - function ColorMatrix () - { /** - * Internal ColorMatrix array. + * The native (un-scaled) width of this Game Object. * - * @name Phaser.Display.ColorMatrix#_matrix - * @type {number[]} - * @private - * @since 3.50.0 + * 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._matrix = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; + this.width = 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) + * The native (un-scaled) height of this Game Object. * - * @name Phaser.Display.ColorMatrix#alpha + * 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} - * @since 3.50.0 + * @readonly + * @since 3.17.0 */ - this.alpha = 1; + this.height = 0; /** - * Is the ColorMatrix array dirty? + * The computed display width of this Game Object, based on the `getBoundingClientRect` DOM call. * - * @name Phaser.Display.ColorMatrix#_dirty - * @type {boolean} - * @private - * @since 3.50.0 + * 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._dirty = true; + this.displayWidth = 0; /** - * The matrix data as a Float32Array. + * The computed display height of this Game Object, based on the `getBoundingClientRect` DOM call. * - * Returned by the `getData` method. + * The property `height` holds the un-scaled height of this DOM Element. * - * @name Phaser.Display.ColorMatrix#data - * @type {Float32Array} + * @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.50.0 + * @since 3.17.0 */ - this._data; + 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); + scene.sys.events.on(SCENE_EVENTS.PRE_RENDER, this.preRender, this); }, /** - * Sets this ColorMatrix from the given array of color values. - * - * @method Phaser.Display.ColorMatrix#set - * @since 3.50.0 + * Handles a Scene Sleep and Wake event. * - * @param {number[]} value - The ColorMatrix values to set. + * @method Phaser.GameObjects.DOMElement#handleSceneEvent + * @private + * @since 3.22.0 * - * @return {this} This ColorMatrix instance. + * @param {Phaser.Scenes.Systems} sys - The Scene Systems. */ - set: function (value) + handleSceneEvent: function (sys) { - this._matrix = value; - - this._dirty = true; + var node = this.node; + var style = node.style; - return this; + if (node) + { + style.display = (sys.settings.visible) ? 'block' : 'none'; + } }, /** - * Resets the ColorMatrix. + * Sets the horizontal and vertical skew values of this DOM Element. * - * @method Phaser.Display.ColorMatrix#reset - * @since 3.50.0 + * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/transform * - * @return {this} This ColorMatrix instance. + * @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. */ - reset: function () + setSkew: function (x, y) { - // 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; + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } - this._dirty = true; + this.skewX = x; + this.skewY = y; return this; }, /** - * Gets the ColorMatrix as a Float32Array. + * 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. * - * Can be used directly as a 1fv shader uniform value. + * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective * - * @method Phaser.Display.ColorMatrix#getData - * @since 3.50.0 + * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** * - * @return {Float32Array} The ColorMatrix as a Float32Array. + * @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. */ - getData: function () + setPerspective: function (value) { - 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; - } + this.parent.style.perspective = value + 'px'; - return this._data; + return this; }, /** - * Changes the brightness of this ColorMatrix by the given amount. + * 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. * - * @method Phaser.Display.ColorMatrix#brightness - * @since 3.50.0 + * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective * - * @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`) ? + * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** * - * @return {this} This ColorMatrix instance. + * @name Phaser.GameObjects.DOMElement#perspective + * @type {number} + * @since 3.17.0 */ - brightness: function (value, multiply) - { - if (value === undefined) { value = 0; } - if (multiply === undefined) { multiply = false; } + perspective: { - var b = value; + get: function () + { + return parseFloat(this.parent.style.perspective); + }, + + set: function (value) + { + this.parent.style.perspective = value + 'px'; + } - 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. + * 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. * - * @method Phaser.Display.ColorMatrix#saturate - * @since 3.50.0 + * For example: * - * @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`) ? + * ```javascript + * var div = this.add.dom(x, y, element); * - * @return {this} This ColorMatrix instance. + * 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. */ - saturate: function (value, multiply) + addListener: function (events) { - if (value === undefined) { value = 0; } - if (multiply === undefined) { multiply = false; } + if (this.node) + { + events = events.split(' '); - var x = (value * 2 / 3) + 1; - var y = ((x - 1) * -0.5); + for (var i = 0; i < events.length; i++) + { + this.node.addEventListener(events[i], this.handler, false); + } + } - return this.multiply([ - x, y, y, 0, 0, - y, x, y, 0, 0, - y, y, x, 0, 0, - 0, 0, 0, 1, 0 - ], multiply); + return this; }, /** - * Desaturates this ColorMatrix (removes color from it). + * Removes one or more native DOM event listeners from the underlying Element of this Game Object. * - * @method Phaser.Display.ColorMatrix#saturation - * @since 3.50.0 + * @method Phaser.GameObjects.DOMElement#removeListener + * @since 3.17.0 * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @param {string} events - The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces. * - * @return {this} This ColorMatrix instance. + * @return {this} This DOM Element instance. */ - desaturate: function (multiply) + removeListener: function (events) { - if (multiply === undefined) { multiply = false; } + if (this.node) + { + events = events.split(' '); - return this.saturate(-1, multiply); + for (var i = 0; i < events.length; i++) + { + this.node.removeEventListener(events[i], this.handler); + } + } + + return this; }, /** - * Rotates the hues of this ColorMatrix by the value given. - * - * @method Phaser.Display.ColorMatrix#hue - * @since 3.50.0 + * Internal event proxy to dispatch native DOM Events via this Game Object. * - * @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`) ? + * @method Phaser.GameObjects.DOMElement#dispatchNativeEvent + * @private + * @since 3.17.0 * - * @return {this} This ColorMatrix instance. + * @param {any} event - The native DOM event. */ - hue: function (rotation, multiply) + dispatchNativeEvent: function (event) { - 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); + this.emit(event.type, event); }, /** - * Sets this ColorMatrix to be grayscale. + * 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`: * - * @method Phaser.Display.ColorMatrix#grayscale - * @since 3.50.0 + * ```javascript + * this.add.dom().createElement('div'); + * ``` * - * @param {number} [value=1] - The grayscale scale (0 is black). - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * For more details on acceptable tag names see: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement * - * @return {this} This ColorMatrix instance. + * 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. */ - grayscale: function (value, multiply) + createElement: function (tagName, style, innerText) { - if (value === undefined) { value = 1; } - if (multiply === undefined) { multiply = false; } - - return this.saturate(-value, multiply); + return this.setElement(document.createElement(tagName), style, innerText); }, /** - * Sets this ColorMatrix to be black and white. + * 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. * - * @method Phaser.Display.ColorMatrix#blackWhite - * @since 3.50.0 + * The `element` argument you pass to this method can be either a string tagName: * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * ```javascript + *

Phaser

* - * @return {this} This ColorMatrix instance. + * 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. */ - blackWhite: function (multiply) + setElement: function (element, style, innerText) { - if (multiply === undefined) { multiply = false; } + // Already got an element? Remove it first + this.removeElement(); - 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); + 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(); }, /** - * Change the contrast of this ColorMatrix by the amount given. + * 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. * - * @method Phaser.Display.ColorMatrix#contrast - * @since 3.50.0 + * Assume the following html is stored in a file called `loginform.html`: * - * @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`) ? + * ```html + * + * + * ``` * - * @return {this} This ColorMatrix instance. + * 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. */ - contrast: function (value, multiply) + createFromCache: function (key, tagName) { - if (value === undefined) { value = 0; } - if (multiply === undefined) { multiply = false; } + var html = this.cache.get(key); - var v = value + 1; - var o = -0.5 * (v - 1); + if (html) + { + this.createFromHTML(html, tagName); + } - return this.multiply([ - v, 0, 0, 0, o, - 0, v, 0, 0, o, - 0, 0, v, 0, o, - 0, 0, 0, 1, 0 - ], multiply); + return this; }, /** - * Converts this ColorMatrix to have negative values. + * 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. * - * @method Phaser.Display.ColorMatrix#negative - * @since 3.50.0 + * ```javascript + * let form = ` + * + * + * `; + * ``` * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * You can create a DOM Element from it using the string: * - * @return {this} This ColorMatrix instance. + * ```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} html - 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. */ - negative: function (multiply) + createFromHTML: function (html, tagName) { - if (multiply === undefined) { multiply = false; } + if (tagName === undefined) { tagName = 'div'; } - return this.multiply([ - -1, 0, 0, 1, 0, - 0, -1, 0, 1, 0, - 0, 0, -1, 1, 0, - 0, 0, 0, 1, 0 - ], multiply); + // 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(); }, /** - * Apply a desaturated luminance to this ColorMatrix. - * - * @method Phaser.Display.ColorMatrix#desaturateLuminance - * @since 3.50.0 + * 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`. * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @method Phaser.GameObjects.DOMElement#removeElement + * @since 3.17.0 * - * @return {this} This ColorMatrix instance. + * @return {this} This DOM Element instance. */ - desaturateLuminance: function (multiply) + removeElement: function () { - if (multiply === undefined) { multiply = false; } + if (this.node) + { + RemoveFromDOM(this.node); - 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); + this.node = null; + } + + return this; }, /** - * Applies a sepia tone to this ColorMatrix. + * 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. * - * @method Phaser.Display.ColorMatrix#sepia - * @since 3.50.0 + * This is called automatically whenever a new element is created or set. * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @method Phaser.GameObjects.DOMElement#updateSize + * @since 3.17.0 * - * @return {this} This ColorMatrix instance. + * @return {this} This DOM Element instance. */ - sepia: function (multiply) + updateSize: function () { - if (multiply === undefined) { multiply = false; } + var node = this.node; - 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); + var nodeBounds = node.getBoundingClientRect(); + + this.width = node.clientWidth; + this.height = node.clientHeight; + + this.displayWidth = nodeBounds.width || 0; + this.displayHeight = nodeBounds.height || 0; + + return this; }, /** - * Applies a night vision tone to this ColorMatrix. + * 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.Display.ColorMatrix#night - * @since 3.50.0 + * @method Phaser.GameObjects.DOMElement#getChildByProperty + * @since 3.17.0 * - * @param {number} [intensity=0.1] - The intensity of this effect. - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @param {string} property - The property to search the children for. + * @param {string} value - The value the property must strictly equal. * - * @return {this} This ColorMatrix instance. + * @return {?Element} The first matching child DOM Element, or `null` if not found. */ - night: function (intensity, multiply) + getChildByProperty: function (property, value) { - if (intensity === undefined) { intensity = 0.1; } - if (multiply === undefined) { multiply = false; } + if (this.node) + { + var children = this.node.querySelectorAll('*'); - 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); + for (var i = 0; i < children.length; i++) + { + if (children[i][property] === value) + { + return children[i]; + } + } + } + + return null; }, /** - * Applies a trippy color tone to this ColorMatrix. + * 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. * - * @method Phaser.Display.ColorMatrix#lsd - * @since 3.50.0 + * Be aware that class and id names are case-sensitive. * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @method Phaser.GameObjects.DOMElement#getChildByID + * @since 3.17.0 * - * @return {this} This ColorMatrix instance. + * @param {string} id - The id to search the children for. + * + * @return {?Element} The first matching child DOM Element, or `null` if not found. */ - lsd: function (multiply) + getChildByID: function (id) { - 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); + return this.getChildByProperty('id', id); }, /** - * Applies a brown tone to this ColorMatrix. + * 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. * - * @method Phaser.Display.ColorMatrix#brown - * @since 3.50.0 + * Be aware that class and id names are case-sensitive. * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @method Phaser.GameObjects.DOMElement#getChildByName + * @since 3.17.0 * - * @return {this} This ColorMatrix instance. + * @param {string} name - The name to search the children for. + * + * @return {?Element} The first matching child DOM Element, or `null` if not found. */ - brown: function (multiply) + getChildByName: function (name) { - 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); + return this.getChildByProperty('name', name); }, /** - * Applies a vintage pinhole color effect to this ColorMatrix. + * Sets the `className` property of the DOM Element node and updates the internal sizes. * - * @method Phaser.Display.ColorMatrix#vintagePinhole - * @since 3.50.0 + * @method Phaser.GameObjects.DOMElement#setClassName + * @since 3.17.0 * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @param {string} className - A string representing the class or space-separated classes of the element. * - * @return {this} This ColorMatrix instance. + * @return {this} This DOM Element instance. */ - vintagePinhole: function (multiply) + setClassName: function (className) { - if (multiply === undefined) { multiply = false; } + if (this.node) + { + this.node.className = className; - 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); + this.updateSize(); + } + + return this; }, /** - * Applies a kodachrome color effect to this ColorMatrix. + * Sets the `innerText` property of the DOM Element node and updates the internal sizes. * - * @method Phaser.Display.ColorMatrix#kodachrome - * @since 3.50.0 + * Note that only certain types of Elements can have `innerText` set on them. * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @method Phaser.GameObjects.DOMElement#setText + * @since 3.17.0 * - * @return {this} This ColorMatrix instance. + * @param {string} text - A DOMString representing the rendered text content of the element. + * + * @return {this} This DOM Element instance. */ - kodachrome: function (multiply) + setText: function (text) { - if (multiply === undefined) { multiply = false; } + if (this.node) + { + this.node.innerText = text; - 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); + this.updateSize(); + } + + return this; }, /** - * Applies a technicolor color effect to this ColorMatrix. + * Sets the `innerHTML` property of the DOM Element node and updates the internal sizes. * - * @method Phaser.Display.ColorMatrix#technicolor - * @since 3.50.0 + * @method Phaser.GameObjects.DOMElement#setHTML + * @since 3.17.0 * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @param {string} html - A DOMString of html to be set as the `innerHTML` property of the element. * - * @return {this} This ColorMatrix instance. + * @return {this} This DOM Element instance. */ - technicolor: function (multiply) + setHTML: function (html) { - if (multiply === undefined) { multiply = false; } + if (this.node) + { + this.node.innerHTML = html; - 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); + this.updateSize(); + } + + return this; }, /** - * 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`) ? + * Runs internal update tasks. * - * @return {this} This ColorMatrix instance. + * @method Phaser.GameObjects.DOMElement#preRender + * @private + * @since 3.60.0 */ - polaroid: function (multiply) + preRender: function () { - if (multiply === undefined) { multiply = false; } + var parent = this.parentContainer; + var node = this.node; - 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); + if (node && parent && !parent.willRender()) + { + node.style.display = 'none'; + } }, /** - * Shifts the values of this ColorMatrix into BGR order. + * Compares the renderMask with the renderFlags to see if this Game Object will render or not. * - * @method Phaser.Display.ColorMatrix#shiftToBGR - * @since 3.50.0 + * DOMElements always return `true` as they need to still set values during the render pass, even if not visible. * - * @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? + * @method Phaser.GameObjects.DOMElement#willRender + * @since 3.17.0 * - * @return {this} This ColorMatrix instance. + * @return {boolean} `true` if the Game Object should be rendered, otherwise `false`. */ - shiftToBGR: function (multiply) + willRender: function () { - 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); + return true; }, /** - * 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. + * Handles the pre-destroy step for the DOM Element, which removes the underlying node from the DOM. * - * @return {this} This ColorMatrix instance. + * @method Phaser.GameObjects.DOMElement#preDestroy + * @private + * @since 3.17.0 */ - multiply: function (a, multiply) + preDestroy: function () { - // 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; + this.removeElement(); - return this; + this.scene.sys.events.off(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); + this.scene.sys.events.off(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); + this.scene.sys.events.off(SCENE_EVENTS.PRE_RENDER, this.preRender, this); } }); -module.exports = ColorMatrix; +module.exports = DOMElement; /***/ }), -/* 199 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 66070: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Rectangle = __webpack_require__(10); -var MATH_CONST = __webpack_require__(14); +var CSSBlendModes = __webpack_require__(2452); +var GameObject = __webpack_require__(89980); +var TransformMatrix = __webpack_require__(69360); -// points is an array of Point-like objects, -// either 2 dimensional arrays, or objects with public x/y properties: -// var points = [ -// [100, 200], -// [200, 400], -// { x: 30, y: 60 } -// ] +var tempMatrix1 = new TransformMatrix(); +var tempMatrix2 = new TransformMatrix(); +var tempMatrix3 = new TransformMatrix(); /** - * Constructs new Rectangle or repositions and resizes an existing Rectangle so that all of the given points are on or within its bounds. - * - * @function Phaser.Geom.Rectangle.FromPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * 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. * - * @param {array} points - An array of points (either arrays with two elements corresponding to the X and Y coordinate or an object with public `x` and `y` properties) which should be surrounded by the Rectangle. - * @param {Phaser.Geom.Rectangle} [out] - Optional Rectangle to adjust. + * @method Phaser.GameObjects.DOMElement#renderWebGL + * @since 3.17.0 + * @private * - * @return {Phaser.Geom.Rectangle} The adjusted `out` Rectangle, or a new Rectangle if none was provided. + * @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 FromPoints = function (points, out) +var DOMElementCSSRenderer = function (renderer, src, camera, parentMatrix) { - if (out === undefined) { out = new Rectangle(); } - - if (points.length === 0) + if (!src.node) { - return out; + return; } - var minX = Number.MAX_VALUE; - var minY = Number.MAX_VALUE; + var style = src.node.style; + var settings = src.scene.sys.settings; - var maxX = MATH_CONST.MIN_SAFE_INTEGER; - var maxY = MATH_CONST.MIN_SAFE_INTEGER; + if (!style || !settings.visible || GameObject.RENDER_MASK !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)) || (src.parentContainer && !src.parentContainer.willRender())) + { + style.display = 'none'; - var p; - var px; - var py; + return; + } - for (var i = 0; i < points.length; i++) + var parent = src.parentContainer; + var alpha = camera.alpha * src.alpha; + + if (parent) { - p = points[i]; + alpha *= parent.alpha; + } - if (Array.isArray(p)) - { - px = p[0]; - py = p[1]; - } - else - { - px = p.x; - py = p.y; - } + var camMatrix = tempMatrix1; + var srcMatrix = tempMatrix2; + var calcMatrix = tempMatrix3; - minX = Math.min(minX, px); - minY = Math.min(minY, py); + var dx = 0; + var dy = 0; - maxX = Math.max(maxX, px); - maxY = Math.max(maxY, py); + 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; - out.x = minX; - out.y = minY; - out.width = maxX - minX; - out.height = maxY - minY; + srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY); - return out; + 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 = src.pointerEvents; + 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 = FromPoints; +module.exports = DOMElementCSSRenderer; /***/ }), -/* 200 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 66788: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var NOOP = __webpack_require__(1); +var DOMElement = __webpack_require__(38943); +var GameObjectFactory = __webpack_require__(61286); /** - * @classdesc - * The RGB class holds a single color value and allows for easy modification and reading of it, - * with optional on-change callback notification and a dirty flag. + * DOM Element Game Objects are a way to control and manipulate HTML Elements over the top of your game. * - * @class RGB - * @memberof Phaser.Display - * @constructor - * @since 3.50.0 + * In order for DOM Elements to display you have to enable them by adding the following to your game + * configuration object: * - * @param {number} [red=0] - The red color value. A number between 0 and 1. - * @param {number} [green=0] - The green color value. A number between 0 and 1. - * @param {number} [blue=0] - The blue color value. A number between 0 and 1. + * ```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. + * + * 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. + * + * 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. + * + * Note: This method will only be available if the DOM Element Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#dom + * @since 3.17.0 + * + * @param {number} x - The horizontal position of this DOM Element in the world. + * @param {number} y - The vertical position of this DOM Element in the world. + * @param {(HTMLElement|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. + * + * @return {Phaser.GameObjects.DOMElement} The Game Object that was created. */ -var RGB = new Class({ +GameObjectFactory.register('dom', function (x, y, element, style, innerText) +{ + var gameObject = new DOMElement(this.scene, x, y, element, style, innerText); - initialize: + this.displayList.add(gameObject); - function RGB (red, green, blue) - { - /** - * Cached RGB values. - * - * @name Phaser.Display.RGB#_rgb - * @type {number[]} - * @private - * @since 3.50.0 - */ - this._rgb = [ 0, 0, 0 ]; + return gameObject; +}); - /** - * This callback will be invoked each time one of the RGB color values change. - * - * The callback is sent the new color values as the parameters. - * - * @name Phaser.Display.RGB#onChangeCallback - * @type {function} - * @since 3.50.0 - */ - this.onChangeCallback = NOOP; - /** - * Is this color dirty? - * - * @name Phaser.Display.RGB#dirty - * @type {boolean} - * @since 3.50.0 - */ - this.dirty = false; +/***/ }), - this.set(red, green, blue); - }, +/***/ 11603: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Sets the red, green and blue values of this RGB object, flags it as being - * dirty and then invokes the `onChangeCallback`, if set. - * - * @method Phaser.Display.RGB#set - * @since 3.50.0 - * - * @param {number} [red=0] - The red color value. A number between 0 and 1. - * @param {number} [green=0] - The green color value. A number between 0 and 1. - * @param {number} [blue=0] - The blue color value. A number between 0 and 1. - * - * @return {this} This RGB instance. - */ - set: function (red, green, blue) - { - if (red === undefined) { red = 0; } - if (green === undefined) { green = 0; } - if (blue === undefined) { blue = 0; } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this._rgb = [ red, green, blue ]; +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - this.onChange(); +if (true) +{ + renderWebGL = __webpack_require__(66070); +} - return this; - }, +if (true) +{ + renderCanvas = __webpack_require__(66070); +} - /** - * Compares the given rgb parameters with those in this object and returns - * a boolean `true` value if they are equal, otherwise it returns `false`. - * - * @method Phaser.Display.RGB#equals - * @since 3.50.0 - * - * @param {number} red - The red value to compare with this object. - * @param {number} green - The green value to compare with this object. - * @param {number} blue - The blue value to compare with this object. - * - * @return {boolean} `true` if the given values match those in this object, otherwise `false`. - */ - equals: function (red, green, blue) - { - var rgb = this._rgb; +module.exports = { - return (rgb.r === red && rgb.g === green && rgb.b === blue); - }, + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - /** - * Internal on change handler. Sets this object as being dirty and - * then invokes the `onChangeCallback`, if set, passing in the - * new RGB values. - * - * @method Phaser.Display.RGB#onChange - * @since 3.50.0 - */ - onChange: function () - { - this.dirty = true; +}; - var rgb = this._rgb; - this.onChangeCallback.call(this, rgb[0], rgb[1], rgb[2]); - }, +/***/ }), - /** - * The red color value. Between 0 and 1. - * - * Changing this property will flag this RGB object as being dirty - * and invoke the `onChangeCallback` , if set. - * - * @name Phaser.Display.RGB#r - * @type {number} - * @since 3.50.0 - */ - r: { +/***/ 65492: +/***/ ((module) => { - get: function () - { - return this._rgb[0]; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - set: function (value) - { - this._rgb[0] = value; - this.onChange(); - } +/** + * The Game Object Added to Scene Event. + * + * This event is dispatched when a Game Object is added to a Scene. + * + * Listen for it on a Game Object instance using `GameObject.on('addedtoscene', listener)`. + * + * @event Phaser.GameObjects.Events#ADDED_TO_SCENE + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the Scene. + * @param {Phaser.Scene} scene - The Scene to which the Game Object was added. + */ +module.exports = 'addedtoscene'; - }, - /** - * The green color value. Between 0 and 1. - * - * Changing this property will flag this RGB object as being dirty - * and invoke the `onChangeCallback` , if set. - * - * @name Phaser.Display.RGB#g - * @type {number} - * @since 3.50.0 - */ - g: { +/***/ }), - get: function () - { - return this._rgb[1]; - }, +/***/ 98398: +/***/ ((module) => { - set: function (value) - { - this._rgb[1] = value; - this.onChange(); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - }, +/** + * The Game Object Destroy Event. + * + * This event is dispatched when a Game Object instance is being destroyed. + * + * Listen for it on a Game Object instance using `GameObject.on('destroy', listener)`. + * + * @event Phaser.GameObjects.Events#DESTROY + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object which is being destroyed. + * @param {boolean} fromScene - `True` if this Game Object is being destroyed by the Scene, `false` if not. + */ +module.exports = 'destroy'; - /** - * The blue color value. Between 0 and 1. - * - * Changing this property will flag this RGB object as being dirty - * and invoke the `onChangeCallback` , if set. - * - * @name Phaser.Display.RGB#b - * @type {number} - * @since 3.50.0 - */ - b: { - get: function () - { - return this._rgb[2]; - }, +/***/ }), - set: function (value) - { - this._rgb[2] = value; - this.onChange(); - } +/***/ 40239: +/***/ ((module) => { - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Nulls any external references this object contains. - * - * @method Phaser.Display.RGB#destroy - * @since 3.50.0 - */ - destroy: function () - { - this.onChangeCallback = null; - } +/** + * The Game Object Removed from Scene Event. + * + * This event is dispatched when a Game Object is removed from a Scene. + * + * Listen for it on a Game Object instance using `GameObject.on('removedfromscene', listener)`. + * + * @event Phaser.GameObjects.Events#REMOVED_FROM_SCENE + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the Scene. + * @param {Phaser.Scene} scene - The Scene from which the Game Object was removed. + */ +module.exports = 'removedfromscene'; -}); -module.exports = RGB; +/***/ }), + +/***/ 17286: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Video Game Object Complete Event. + * + * This event is dispatched when a Video finishes playback by reaching the end of its duration. It + * is also dispatched if a video marker sequence is being played and reaches the end. + * + * Note that not all videos can fire this event. Live streams, for example, have no fixed duration, + * so never technically 'complete'. + * + * If a video is stopped from playback, via the `Video.stop` method, it will emit the + * `VIDEO_STOP` event instead of this one. + * + * Listen for it from a Video Game Object instance using `Video.on('complete', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_COMPLETE + * @type {string} + * @since 3.20.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which completed playback. + */ +module.exports = 'complete'; /***/ }), -/* 201 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 31496: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = { +/** + * The Video Game Object Created Event. + * + * This event is dispatched when the texture for a Video has been created. This happens + * when enough of the video source has been loaded that the browser is able to render a + * frame from it. + * + * Listen for it from a Video Game Object instance using `Video.on('created', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_CREATED + * @type {string} + * @since 3.20.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event. + * @param {number} width - The width of the video. + * @param {number} height - The height of the video. + */ +module.exports = 'created'; - CENTER: __webpack_require__(403), - ORIENTATION: __webpack_require__(404), - SCALE_MODE: __webpack_require__(405), - ZOOM: __webpack_require__(406) -}; +/***/ }), -module.exports = CONST; +/***/ 89587: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Video Game Object Error Event. + * + * This event is dispatched when a Video tries to play a source that does not exist, or is the wrong file type. + * + * Listen for it from a Video Game Object instance using `Video.on('error', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_ERROR + * @type {string} + * @since 3.20.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which threw the error. + * @param {DOMException|string} event - The native DOM event the browser raised during playback. + */ +module.exports = 'error'; /***/ }), -/* 202 */ -/***/ (function(module, exports) { + +/***/ 59792: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Attempts to remove the element from its parentNode in the DOM. + * The Video Game Object Locked Event. * - * @function Phaser.DOM.RemoveFromDOM - * @since 3.0.0 + * This event is dispatched when a Video was attempted to be played, but the browser prevented it + * from doing so due to the Media Engagement Interaction policy. * - * @param {HTMLElement} element - The DOM element to remove from its parent node. + * If you get this event you will need to wait for the user to interact with the browser before + * the video will play. This is a browser security measure to prevent autoplaying videos with + * audio. An interaction includes a mouse click, a touch, or a key press. + * + * Listen for it from a Video Game Object instance using `Video.on('locked', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_LOCKED + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event. */ -var RemoveFromDOM = function (element) -{ - if (element.parentNode) - { - element.parentNode.removeChild(element); - } -}; - -module.exports = RemoveFromDOM; +module.exports = 'locked'; /***/ }), -/* 203 */ -/***/ (function(module, exports) { + +/***/ 96342: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var INPUT_CONST = { - - /** - * The mouse pointer is being held down. - * - * @name Phaser.Input.MOUSE_DOWN - * @type {number} - * @since 3.10.0 - */ - MOUSE_DOWN: 0, +/** + * The Video Game Object Loop Event. + * + * This event is dispatched when a Video that is currently playing has looped. This only + * happens if the `loop` parameter was specified, or the `setLoop` method was called, + * and if the video has a fixed duration. Video streams, for example, cannot loop, as + * they have no duration. + * + * Looping is based on the result of the Video `timeupdate` event. This event is not + * frame-accurate, due to the way browsers work, so please do not rely on this loop + * event to be time or frame precise. + * + * Listen for it from a Video Game Object instance using `Video.on('loop', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_LOOP + * @type {string} + * @since 3.20.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which has looped. + */ +module.exports = 'loop'; - /** - * The mouse pointer is being moved. - * - * @name Phaser.Input.MOUSE_MOVE - * @type {number} - * @since 3.10.0 - */ - MOUSE_MOVE: 1, - /** - * The mouse pointer is released. - * - * @name Phaser.Input.MOUSE_UP - * @type {number} - * @since 3.10.0 - */ - MOUSE_UP: 2, +/***/ }), - /** - * A touch pointer has been started. - * - * @name Phaser.Input.TOUCH_START - * @type {number} - * @since 3.10.0 - */ - TOUCH_START: 3, +/***/ 6017: +/***/ ((module) => { - /** - * A touch pointer has been started. - * - * @name Phaser.Input.TOUCH_MOVE - * @type {number} - * @since 3.10.0 - */ - TOUCH_MOVE: 4, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A touch pointer has been started. - * - * @name Phaser.Input.TOUCH_END - * @type {number} - * @since 3.10.0 - */ - TOUCH_END: 5, +/** + * The Video Game Object Playing Event. + * + * The playing event is fired after playback is first started, + * and whenever it is restarted. For example it is fired when playback + * resumes after having been paused or delayed due to lack of data. + * + * Listen for it from a Video Game Object instance using `Video.on('playing', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_PLAYING + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which started playback. + */ +module.exports = 'playing'; - /** - * The pointer lock has changed. - * - * @name Phaser.Input.POINTER_LOCK_CHANGE - * @type {number} - * @since 3.10.0 - */ - POINTER_LOCK_CHANGE: 6, - /** - * A touch pointer has been been cancelled by the browser. - * - * @name Phaser.Input.TOUCH_CANCEL - * @type {number} - * @since 3.15.0 - */ - TOUCH_CANCEL: 7, +/***/ }), - /** - * The mouse wheel changes. - * - * @name Phaser.Input.MOUSE_WHEEL - * @type {number} - * @since 3.18.0 - */ - MOUSE_WHEEL: 8 +/***/ 49614: +/***/ ((module) => { -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = INPUT_CONST; +/** + * The Video Game Object Play Event. + * + * This event is dispatched when a Video begins playback. For videos that do not require + * interaction unlocking, this is usually as soon as the `Video.play` method is called. + * However, for videos that require unlocking, it is fired once playback begins after + * they've been unlocked. + * + * Listen for it from a Video Game Object instance using `Video.on('play', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_PLAY + * @type {string} + * @since 3.20.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which started playback. + */ +module.exports = 'play'; /***/ }), -/* 204 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 24418: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(144); -var DefaultPlugins = __webpack_require__(197); -var Events = __webpack_require__(20); -var GetPhysicsPlugins = __webpack_require__(419); -var GetScenePlugins = __webpack_require__(420); -var GLOBAL_CONST = __webpack_require__(33); -var NOOP = __webpack_require__(1); -var Settings = __webpack_require__(421); - /** - * @classdesc - * The Scene Systems class. + * The Video Game Object Seeked Event. * - * This class is available from within a Scene under the property `sys`. - * It is responsible for managing all of the plugins a Scene has running, including the display list, and - * handling the update step and renderer. It also contains references to global systems belonging to Game. + * This event is dispatched when a Video completes seeking to a new point in its timeline. * - * @class Systems - * @memberof Phaser.Scenes - * @constructor - * @since 3.0.0 + * Listen for it from a Video Game Object instance using `Video.on('seeked', listener)`. * - * @param {Phaser.Scene} scene - The Scene that owns this Systems instance. - * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - Scene specific configuration settings. + * @event Phaser.GameObjects.Events#VIDEO_SEEKED + * @type {string} + * @since 3.20.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which completed seeking. */ -var Systems = new Class({ +module.exports = 'seeked'; - initialize: - function Systems (scene, config) - { - /** - * A reference to the Scene that these Systems belong to. - * - * @name Phaser.Scenes.Systems#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; +/***/ }), - /** - * A reference to the Phaser Game instance. - * - * @name Phaser.Scenes.Systems#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game; +/***/ 87318: +/***/ ((module) => { - /** - * A reference to either the Canvas or WebGL Renderer that this Game is using. - * - * @name Phaser.Scenes.Systems#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.17.0 - */ - this.renderer; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (false) - {} +/** + * The Video Game Object Seeking Event. + * + * This event is dispatched when a Video _begins_ seeking to a new point in its timeline. + * When the seek is complete, it will dispatch the `VIDEO_SEEKED` event to conclude. + * + * Listen for it from a Video Game Object instance using `Video.on('seeking', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_SEEKING + * @type {string} + * @since 3.20.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which started seeking. + */ +module.exports = 'seeking'; - /** - * The Scene Configuration object, as passed in when creating the Scene. - * - * @name Phaser.Scenes.Systems#config - * @type {(string|Phaser.Types.Scenes.SettingsConfig)} - * @since 3.0.0 - */ - this.config = config; - /** - * The Scene Settings. This is the parsed output based on the Scene configuration. - * - * @name Phaser.Scenes.Systems#settings - * @type {Phaser.Types.Scenes.SettingsObject} - * @since 3.0.0 - */ - this.settings = Settings.create(config); +/***/ }), - /** - * A handy reference to the Scene canvas / context. - * - * @name Phaser.Scenes.Systems#canvas - * @type {HTMLCanvasElement} - * @since 3.0.0 - */ - this.canvas; +/***/ 50009: +/***/ ((module) => { - /** - * A reference to the Canvas Rendering Context being used by the renderer. - * - * @name Phaser.Scenes.Systems#context - * @type {CanvasRenderingContext2D} - * @since 3.0.0 - */ - this.context; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Global Systems - these are single-instance global managers that belong to Game +/** + * The Video Game Object Stalled Event. + * + * This event is dispatched by a Video Game Object when the video playback stalls. + * + * This can happen if the video is buffering. + * + * If will fire for any of the following native DOM events: + * + * `stalled` + * `suspend` + * `waiting` + * + * Listen for it from a Video Game Object instance using `Video.on('stalled', listener)`. + * + * Note that being stalled isn't always a negative thing. A video can be stalled if it + * has downloaded enough data in to its buffer to not need to download any more until + * the current batch of frames have rendered. + * + * @event Phaser.GameObjects.Events#VIDEO_STALLED + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which threw the error. + * @param {Event} event - The native DOM event the browser raised during playback. + */ +module.exports = 'stalled'; - /** - * A reference to the global Animations Manager. - * - * In the default set-up you can access this from within a Scene via the `this.anims` property. - * - * @name Phaser.Scenes.Systems#anims - * @type {Phaser.Animations.AnimationManager} - * @since 3.0.0 - */ - this.anims; - /** - * A reference to the global Cache. The Cache stores all files bought in to Phaser via - * the Loader, with the exception of images. Images are stored in the Texture Manager. - * - * In the default set-up you can access this from within a Scene via the `this.cache` property. - * - * @name Phaser.Scenes.Systems#cache - * @type {Phaser.Cache.CacheManager} - * @since 3.0.0 - */ - this.cache; +/***/ }), - /** - * A reference to the global Plugins Manager. - * - * In the default set-up you can access this from within a Scene via the `this.plugins` property. - * - * @name Phaser.Scenes.Systems#plugins - * @type {Phaser.Plugins.PluginManager} - * @since 3.0.0 - */ - this.plugins; +/***/ 61922: +/***/ ((module) => { - /** - * A reference to the global registry. This is a game-wide instance of the Data Manager, allowing - * you to exchange data between Scenes via a universal and shared point. - * - * In the default set-up you can access this from within a Scene via the `this.registry` property. - * - * @name Phaser.Scenes.Systems#registry - * @type {Phaser.Data.DataManager} - * @since 3.0.0 - */ - this.registry; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A reference to the global Scale Manager. - * - * In the default set-up you can access this from within a Scene via the `this.scale` property. - * - * @name Phaser.Scenes.Systems#scale - * @type {Phaser.Scale.ScaleManager} - * @since 3.15.0 - */ - this.scale; +/** + * The Video Game Object Stopped Event. + * + * This event is dispatched when a Video is stopped from playback via a call to the `Video.stop` method, + * either directly via game code, or indirectly as the result of changing a video source or destroying it. + * + * Listen for it from a Video Game Object instance using `Video.on('stop', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_STOP + * @type {string} + * @since 3.20.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which stopped playback. + */ +module.exports = 'stop'; - /** - * A reference to the global Sound Manager. - * - * In the default set-up you can access this from within a Scene via the `this.sound` property. - * - * @name Phaser.Scenes.Systems#sound - * @type {(Phaser.Sound.NoAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager)} - * @since 3.0.0 - */ - this.sound; - /** - * A reference to the global Texture Manager. - * - * In the default set-up you can access this from within a Scene via the `this.textures` property. - * - * @name Phaser.Scenes.Systems#textures - * @type {Phaser.Textures.TextureManager} - * @since 3.0.0 - */ - this.textures; +/***/ }), - // Core Plugins - these are non-optional Scene plugins, needed by lots of the other systems +/***/ 79501: +/***/ ((module) => { - /** - * A reference to the Scene's Game Object Factory. - * - * Use this to quickly and easily create new Game Object's. - * - * In the default set-up you can access this from within a Scene via the `this.add` property. - * - * @name Phaser.Scenes.Systems#add - * @type {Phaser.GameObjects.GameObjectFactory} - * @since 3.0.0 - */ - this.add; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A reference to the Scene's Camera Manager. - * - * Use this to manipulate and create Cameras for this specific Scene. - * - * In the default set-up you can access this from within a Scene via the `this.cameras` property. - * - * @name Phaser.Scenes.Systems#cameras - * @type {Phaser.Cameras.Scene2D.CameraManager} - * @since 3.0.0 - */ - this.cameras; +/** + * The Video Game Object Texture Ready Event. + * + * This event is dispatched by a Video Game Object when it has finished creating its texture. + * + * This happens when the video has finished loading enough data for its first frame. + * + * If you wish to use the Video texture elsewhere in your game, such as as a Sprite texture, + * then you should listen for this event first, before creating the Sprites that use it. + * + * Listen for it from a Video Game Object instance using `Video.on('textureready', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_TEXTURE + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object that emitted the event. + * @param {Phaser.Textures.Texture} texture - The Texture that was created. + */ +module.exports = 'textureready'; - /** - * A reference to the Scene's Display List. - * - * Use this to organize the children contained in the display list. - * - * In the default set-up you can access this from within a Scene via the `this.children` property. - * - * @name Phaser.Scenes.Systems#displayList - * @type {Phaser.GameObjects.DisplayList} - * @since 3.0.0 - */ - this.displayList; - /** - * A reference to the Scene's Event Manager. - * - * Use this to listen for Scene specific events, such as `pause` and `shutdown`. - * - * In the default set-up you can access this from within a Scene via the `this.events` property. - * - * @name Phaser.Scenes.Systems#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 - */ - this.events; +/***/ }), - /** - * A reference to the Scene's Game Object Creator. - * - * Use this to quickly and easily create new Game Object's. The difference between this and the - * Game Object Factory, is that the Creator just creates and returns Game Object instances, it - * doesn't then add them to the Display List or Update List. - * - * In the default set-up you can access this from within a Scene via the `this.make` property. - * - * @name Phaser.Scenes.Systems#make - * @type {Phaser.GameObjects.GameObjectCreator} - * @since 3.0.0 - */ - this.make; +/***/ 4052: +/***/ ((module) => { - /** - * A reference to the Scene Manager Plugin. - * - * Use this to manipulate both this and other Scene's in your game, for example to launch a parallel Scene, - * or pause or resume a Scene, or switch from this Scene to another. - * - * In the default set-up you can access this from within a Scene via the `this.scene` property. - * - * @name Phaser.Scenes.Systems#scenePlugin - * @type {Phaser.Scenes.ScenePlugin} - * @since 3.0.0 - */ - this.scenePlugin; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A reference to the Scene's Update List. - * - * Use this to organize the children contained in the update list. - * - * The Update List is responsible for managing children that need their `preUpdate` methods called, - * in order to process so internal components, such as Sprites with Animations. - * - * In the default set-up there is no reference to this from within the Scene itself. - * - * @name Phaser.Scenes.Systems#updateList - * @type {Phaser.GameObjects.UpdateList} - * @since 3.0.0 - */ - this.updateList; +/** + * The Video Game Object Unlocked Event. + * + * This event is dispatched when a Video that was prevented from playback due to the browsers + * Media Engagement Interaction policy, is unlocked by a user gesture. + * + * Listen for it from a Video Game Object instance using `Video.on('unlocked', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_UNLOCKED + * @type {string} + * @since 3.20.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event. + */ +module.exports = 'unlocked'; - /** - * The Scene Update function. - * - * This starts out as NOOP during init, preload and create, and at the end of create - * it swaps to be whatever the Scene.update function is. - * - * @name Phaser.Scenes.Systems#sceneUpdate - * @type {function} - * @private - * @since 3.10.0 - */ - this.sceneUpdate = NOOP; - }, - /** - * This method is called only once by the Scene Manager when the Scene is instantiated. - * It is responsible for setting up all of the Scene plugins and references. - * It should never be called directly. - * - * @method Phaser.Scenes.Systems#init - * @protected - * @fires Phaser.Scenes.Events#BOOT - * @since 3.0.0 - * - * @param {Phaser.Game} game - A reference to the Phaser Game instance. - */ - init: function (game) - { - this.settings.status = CONST.INIT; +/***/ }), - // This will get replaced by the SceneManager with the actual update function, if it exists, once create is over. - this.sceneUpdate = NOOP; +/***/ 54857: +/***/ ((module) => { - this.game = game; - this.renderer = game.renderer; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.canvas = game.canvas; - this.context = game.context; +/** + * The Video Game Object Unsupported Event. + * + * This event is dispatched by a Video Game Object if the media source + * (which may be specified as a MediaStream, MediaSource, Blob, or File, + * for example) doesn't represent a supported media format. + * + * Listen for it from a Video Game Object instance using `Video.on('unsupported', listener)`. + * + * @event Phaser.GameObjects.Events#VIDEO_UNSUPPORTED + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Video} video - The Video Game Object which started playback. + * @param {DOMException|string} event - The native DOM event the browser raised during playback. + */ +module.exports = 'unsupported'; - var pluginManager = game.plugins; - this.plugins = pluginManager; +/***/ }), - pluginManager.addToScene(this, DefaultPlugins.Global, [ DefaultPlugins.CoreScene, GetScenePlugins(this), GetPhysicsPlugins(this) ]); +/***/ 56631: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.events.emit(Events.BOOT, this); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.settings.isBooted = true; - }, +/** + * @namespace Phaser.GameObjects.Events + */ - /** - * A single game step. Called automatically by the Scene Manager as a result of a Request Animation - * Frame or Set Timeout call to the main Game instance. - * - * @method Phaser.Scenes.Systems#step - * @fires Phaser.Scenes.Events#PRE_UPDATE - * @fires Phaser.Scenes.Events#UPDATE - * @fires Phaser.Scenes.Events#POST_UPDATE - * @since 3.0.0 - * - * @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now(). - * @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class. - */ - step: function (time, delta) - { - var events = this.events; +module.exports = { - events.emit(Events.PRE_UPDATE, time, delta); + ADDED_TO_SCENE: __webpack_require__(65492), + DESTROY: __webpack_require__(98398), + REMOVED_FROM_SCENE: __webpack_require__(40239), + VIDEO_COMPLETE: __webpack_require__(17286), + VIDEO_CREATED: __webpack_require__(31496), + VIDEO_ERROR: __webpack_require__(89587), + VIDEO_LOCKED: __webpack_require__(59792), + VIDEO_LOOP: __webpack_require__(96342), + VIDEO_PLAY: __webpack_require__(49614), + VIDEO_PLAYING: __webpack_require__(6017), + VIDEO_SEEKED: __webpack_require__(24418), + VIDEO_SEEKING: __webpack_require__(87318), + VIDEO_STALLED: __webpack_require__(50009), + VIDEO_STOP: __webpack_require__(61922), + VIDEO_TEXTURE: __webpack_require__(79501), + VIDEO_UNLOCKED: __webpack_require__(4052), + VIDEO_UNSUPPORTED: __webpack_require__(54857) - events.emit(Events.UPDATE, time, delta); +}; - this.sceneUpdate.call(this.scene, time, delta); - events.emit(Events.POST_UPDATE, time, delta); - }, +/***/ }), - /** - * Called automatically by the Scene Manager. - * Instructs the Scene to render itself via its Camera Manager to the renderer given. - * - * @method Phaser.Scenes.Systems#render - * @fires Phaser.Scenes.Events#PRE_RENDER - * @fires Phaser.Scenes.Events#RENDER - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that invoked the render call. - */ - render: function (renderer) - { - var displayList = this.displayList; +/***/ 39419: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - displayList.depthSort(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.events.emit(Events.PRE_RENDER, renderer); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var ExternRender = __webpack_require__(79394); - this.cameras.render(renderer, displayList); +/** + * @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 in a 'clean' state, ready for you to bind your own shaders, + * or draw to it, whatever you wish to do. This should all take place in the `render` method. + * The correct way to deploy an Extern object is to create a class that extends it, then + * override the `render` (and optionally `preUpdate`) methods and pass off control to your + * 3rd party libraries or custom WebGL code there. + * + * 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({ - this.events.emit(Events.RENDER, renderer); - }, + Extends: GameObject, - /** - * Force a sort of the display list on the next render. - * - * @method Phaser.Scenes.Systems#queueDepthSort - * @since 3.0.0 - */ - queueDepthSort: function () - { - this.displayList.queueDepthSort(); - }, + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.Depth, + Components.Flip, + Components.Origin, + Components.ScrollFactor, + Components.Size, + Components.Texture, + Components.Tint, + Components.Transform, + Components.Visible, + ExternRender + ], - /** - * Immediately sorts the display list if the flag is set. - * - * @method Phaser.Scenes.Systems#depthSort - * @since 3.0.0 - */ - depthSort: function () + initialize: + + function Extern (scene) { - this.displayList.depthSort(); + GameObject.call(this, scene, 'Extern'); }, - /** - * Pause this Scene. - * A paused Scene still renders, it just doesn't run ANY of its update handlers or systems. - * - * @method Phaser.Scenes.Systems#pause - * @fires Phaser.Scenes.Events#PAUSE - * @since 3.0.0 - * - * @param {object} [data] - A data object that will be passed in the 'pause' event. - * - * @return {Phaser.Scenes.Systems} This Systems object. - */ - pause: function (data) + // Overrides Game Object method + addedToScene: function () { - var events = this.events; - var settings = this.settings; - - if (this.settings.active) - { - settings.status = CONST.PAUSED; - - settings.active = false; - - events.emit(Events.PAUSE, this, data); - } - - return this; + this.scene.sys.updateList.add(this); }, - /** - * Resume this Scene from a paused state. - * - * @method Phaser.Scenes.Systems#resume - * @fires Phaser.Scenes.Events#RESUME - * @since 3.0.0 - * - * @param {object} [data] - A data object that will be passed in the 'resume' event. - * - * @return {Phaser.Scenes.Systems} This Systems object. - */ - resume: function (data) + // Overrides Game Object method + removedFromScene: function () { - var events = this.events; - var settings = this.settings; - - if (!this.settings.active) - { - settings.status = CONST.RUNNING; - - settings.active = true; - - events.emit(Events.RESUME, this, data); - } - - return this; + this.scene.sys.updateList.remove(this); }, - /** - * Send this Scene to sleep. - * - * A sleeping Scene doesn't run its update step or render anything, but it also isn't shut down - * or has any of its systems or children removed, meaning it can be re-activated at any point and - * will carry on from where it left off. It also keeps everything in memory and events and callbacks - * from other Scenes may still invoke changes within it, so be careful what is left active. - * - * @method Phaser.Scenes.Systems#sleep - * @fires Phaser.Scenes.Events#SLEEP - * @since 3.0.0 - * - * @param {object} [data] - A data object that will be passed in the 'sleep' event. - * - * @return {Phaser.Scenes.Systems} This Systems object. - */ - sleep: function (data) + preUpdate: function () { - var events = this.events; - var settings = this.settings; - - settings.status = CONST.SLEEPING; - - settings.active = false; - settings.visible = false; - - events.emit(Events.SLEEP, this, data); - - return this; + // override this! + // Arguments: time, delta }, - /** - * Wake-up this Scene if it was previously asleep. - * - * @method Phaser.Scenes.Systems#wake - * @fires Phaser.Scenes.Events#WAKE - * @since 3.0.0 - * - * @param {object} [data] - A data object that will be passed in the 'wake' event. - * - * @return {Phaser.Scenes.Systems} This Systems object. - */ - wake: function (data) + render: function () { - var events = this.events; - var settings = this.settings; - - settings.status = CONST.RUNNING; - - settings.active = true; - settings.visible = true; + // override this! + // Arguments: renderer, camera, calcMatrix + } - events.emit(Events.WAKE, this, data); +}); - if (settings.isTransition) - { - events.emit(Events.TRANSITION_WAKE, settings.transitionFrom, settings.transitionDuration); - } +module.exports = Extern; - return this; - }, - /** - * Returns any data that was sent to this Scene by another Scene. - * - * The data is also passed to `Scene.init` and in various Scene events, but - * you can access it at any point via this method. - * - * @method Phaser.Scenes.Systems#getData - * @since 3.22.0 - * - * @return {any} - */ - getData: function () - { - return this.settings.data; - }, +/***/ }), - /** - * Is this Scene sleeping? - * - * @method Phaser.Scenes.Systems#isSleeping - * @since 3.0.0 - * - * @return {boolean} `true` if this Scene is asleep, otherwise `false`. - */ - isSleeping: function () - { - return (this.settings.status === CONST.SLEEPING); - }, +/***/ 96699: +/***/ (() => { - /** - * Is this Scene running? - * - * @method Phaser.Scenes.Systems#isActive - * @since 3.0.0 - * - * @return {boolean} `true` if this Scene is running, otherwise `false`. - */ - isActive: function () - { - return (this.settings.status === CONST.RUNNING); - }, - /** - * Is this Scene paused? - * - * @method Phaser.Scenes.Systems#isPaused - * @since 3.13.0 - * - * @return {boolean} `true` if this Scene is paused, otherwise `false`. - */ - isPaused: function () - { - return (this.settings.status === CONST.PAUSED); - }, - /** - * Is this Scene currently transitioning out to, or in from another Scene? - * - * @method Phaser.Scenes.Systems#isTransitioning - * @since 3.5.0 - * - * @return {boolean} `true` if this Scene is currently transitioning, otherwise `false`. - */ - isTransitioning: function () - { - return (this.settings.isTransition || this.scenePlugin._target !== null); - }, +/***/ }), - /** - * Is this Scene currently transitioning out from itself to another Scene? - * - * @method Phaser.Scenes.Systems#isTransitionOut - * @since 3.5.0 - * - * @return {boolean} `true` if this Scene is in transition to another Scene, otherwise `false`. - */ - isTransitionOut: function () - { - return (this.scenePlugin._target !== null && this.scenePlugin._duration > 0); - }, +/***/ 41155: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - /** - * Is this Scene currently transitioning in from another Scene? - * - * @method Phaser.Scenes.Systems#isTransitionIn - * @since 3.5.0 - * - * @return {boolean} `true` if this Scene is transitioning in from another Scene, otherwise `false`. - */ - isTransitionIn: function () - { - return (this.settings.isTransition); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Is this Scene visible and rendering? - * - * @method Phaser.Scenes.Systems#isVisible - * @since 3.0.0 - * - * @return {boolean} `true` if this Scene is visible, otherwise `false`. - */ - isVisible: function () - { - return this.settings.visible; - }, +var Extern = __webpack_require__(39419); +var GameObjectFactory = __webpack_require__(61286); - /** - * Sets the visible state of this Scene. - * An invisible Scene will not render, but will still process updates. - * - * @method Phaser.Scenes.Systems#setVisible - * @since 3.0.0 - * - * @param {boolean} value - `true` to render this Scene, otherwise `false`. - * - * @return {Phaser.Scenes.Systems} This Systems object. - */ - setVisible: function (value) - { - this.settings.visible = value; +/** + * Creates a new Extern Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Extern Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#extern + * @since 3.16.0 + * + * @return {Phaser.GameObjects.Extern} The Game Object that was created. + */ +GameObjectFactory.register('extern', function () +{ + var extern = new Extern(this.scene); - return this; - }, + this.displayList.add(extern); - /** - * Set the active state of this Scene. - * - * An active Scene will run its core update loop. - * - * @method Phaser.Scenes.Systems#setActive - * @since 3.0.0 - * - * @param {boolean} value - If `true` the Scene will be resumed, if previously paused. If `false` it will be paused. - * @param {object} [data] - A data object that will be passed in the 'resume' or 'pause' events. - * - * @return {Phaser.Scenes.Systems} This Systems object. - */ - setActive: function (value, data) - { - if (value) - { - return this.resume(data); - } - else - { - return this.pause(data); - } - }, + return extern; +}); - /** - * Start this Scene running and rendering. - * Called automatically by the SceneManager. - * - * @method Phaser.Scenes.Systems#start - * @fires Phaser.Scenes.Events#START - * @fires Phaser.Scenes.Events#READY - * @since 3.0.0 - * - * @param {object} data - Optional data object that may have been passed to this Scene from another. - */ - start: function (data) - { - var events = this.events; - var settings = this.settings; +// When registering a factory function 'this' refers to the GameObjectFactory 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 - if (data) - { - settings.data = data; - } - settings.status = CONST.START; +/***/ }), - settings.active = true; - settings.visible = true; +/***/ 79394: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // For plugins to listen out for - events.emit(Events.START, this); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // For user-land code to listen out for - events.emit(Events.READY, this, data); - }, +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - /** - * Shutdown this Scene and send a shutdown event to all of its systems. - * A Scene that has been shutdown will not run its update loop or render, but it does - * not destroy any of its plugins or references. It is put into hibernation for later use. - * If you don't ever plan to use this Scene again, then it should be destroyed instead - * to free-up resources. - * - * @method Phaser.Scenes.Systems#shutdown - * @fires Phaser.Scenes.Events#SHUTDOWN - * @since 3.0.0 - * - * @param {object} [data] - A data object that will be passed in the 'shutdown' event. - */ - shutdown: function (data) - { - var events = this.events; - var settings = this.settings; +if (true) +{ + renderWebGL = __webpack_require__(81410); +} - events.off(Events.TRANSITION_INIT); - events.off(Events.TRANSITION_START); - events.off(Events.TRANSITION_COMPLETE); - events.off(Events.TRANSITION_OUT); +if (true) +{ + renderCanvas = __webpack_require__(96699); +} - settings.status = CONST.SHUTDOWN; +module.exports = { - settings.active = false; - settings.visible = false; + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - if (this.renderer === GLOBAL_CONST.WEBGL) - { - this.renderer.resetTextures(true); - } +}; - events.emit(Events.SHUTDOWN, this, data); - }, - /** - * Destroy this Scene and send a destroy event all of its systems. - * A destroyed Scene cannot be restarted. - * You should not call this directly, instead use `SceneManager.remove`. - * - * @method Phaser.Scenes.Systems#destroy - * @private - * @fires Phaser.Scenes.Events#DESTROY - * @since 3.0.0 - */ - destroy: function () - { - var events = this.events; - var settings = this.settings; +/***/ }), - settings.status = CONST.DESTROYED; +/***/ 81410: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - settings.active = false; - settings.visible = false; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - events.emit(Events.DESTROY, this); +var GetCalcMatrix = __webpack_require__(73329); - events.removeAllListeners(); +/** + * 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.Extern#renderWebGL + * @since 3.16.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Extern} 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 ExternWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + renderer.pipelines.clear(); - var props = [ 'scene', 'game', 'anims', 'cache', 'plugins', 'registry', 'sound', 'textures', 'add', 'camera', 'displayList', 'events', 'make', 'scenePlugin', 'updateList' ]; + var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; - for (var i = 0; i < props.length; i++) - { - this[props[i]] = null; - } - } + src.render.call(src, renderer, camera, calcMatrix); -}); + renderer.pipelines.rebind(); +}; -module.exports = Systems; +module.exports = ExternWebGLRenderer; /***/ }), -/* 205 */ -/***/ (function(module, exports) { + +/***/ 36266: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * Capitalizes the first letter of a string if there is one. - * @example - * UppercaseFirst('abc'); - * // returns 'Abc' - * @example - * UppercaseFirst('the happy family'); - * // returns 'The happy family' - * @example - * UppercaseFirst(''); - * // returns '' - * - * @function Phaser.Utils.String.UppercaseFirst - * @since 3.0.0 - * - * @param {string} str - The string to capitalize. - * - * @return {string} A new string, same as the first, but with the first letter capitalized. - */ -var UppercaseFirst = function (str) -{ - return str && str[0].toUpperCase() + str.slice(1); -}; +module.exports = { -module.exports = UppercaseFirst; + ARC: 0, + BEGIN_PATH: 1, + CLOSE_PATH: 2, + FILL_RECT: 3, + LINE_TO: 4, + MOVE_TO: 5, + LINE_STYLE: 6, + FILL_STYLE: 7, + FILL_PATH: 8, + STROKE_PATH: 9, + FILL_TRIANGLE: 10, + STROKE_TRIANGLE: 11, + SAVE: 14, + RESTORE: 15, + TRANSLATE: 16, + SCALE: 17, + ROTATE: 18, + GRADIENT_FILL_STYLE: 21, + GRADIENT_LINE_STYLE: 22 + +}; /***/ }), -/* 206 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 33182: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(33); -var Class = __webpack_require__(0); -var Frame = __webpack_require__(109); -var TextureSource = __webpack_require__(424); - -var TEXTURE_MISSING_ERROR = 'Texture.frame missing: '; +var BaseCamera = __webpack_require__(51052); +var Class = __webpack_require__(56694); +var Commands = __webpack_require__(36266); +var Components = __webpack_require__(64937); +var Ellipse = __webpack_require__(95669); +var GameObject = __webpack_require__(89980); +var GetFastValue = __webpack_require__(72632); +var GetValue = __webpack_require__(10850); +var MATH_CONST = __webpack_require__(83392); +var Render = __webpack_require__(60898); /** * @classdesc - * A Texture consists of a source, usually an Image from the Cache, and a collection of Frames. - * The Frames represent the different areas of the Texture. For example a texture atlas - * may have many Frames, one for each element within the atlas. Where-as a single image would have - * just one frame, that encompasses the whole image. + * A Graphics object is a way to draw primitive shapes to your game. Primitives include forms of geometry, such as + * Rectangles, Circles, and Polygons. They also include lines, arcs and curves. When you initially create a Graphics + * object it will be empty. * - * Every Texture, no matter where it comes from, always has at least 1 frame called the `__BASE` frame. - * This frame represents the entirety of the source image. + * To draw to it you must first specify a line style or fill style (or both), draw shapes using paths, and finally + * fill or stroke them. For example: * - * 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. + * ```javascript + * graphics.lineStyle(5, 0xFF00FF, 1.0); + * graphics.beginPath(); + * graphics.moveTo(100, 100); + * graphics.lineTo(200, 200); + * graphics.closePath(); + * graphics.strokePath(); + * ``` * - * Sprites and other Game Objects get the texture data they need from the TextureManager. + * There are also many helpful methods that draw and fill/stroke common shapes for you. * - * @class Texture - * @memberof Phaser.Textures + * ```javascript + * graphics.lineStyle(5, 0xFF00FF, 1.0); + * graphics.fillStyle(0xFFFFFF, 1.0); + * graphics.fillRect(50, 50, 400, 200); + * graphics.strokeRect(50, 50, 400, 200); + * ``` + * + * When a Graphics object is rendered it will render differently based on if the game is running under Canvas or WebGL. + * Under Canvas it will use the HTML Canvas context drawing operations to draw the path. + * Under WebGL the graphics data is decomposed into polygons. Both of these are expensive processes, especially with + * complex shapes. + * + * If your Graphics object doesn't change much (or at all) once you've drawn your shape to it, then you will help + * performance by calling {@link Phaser.GameObjects.Graphics#generateTexture}. This will 'bake' the Graphics object into + * a Texture, and return it. You can then use this Texture for Sprites or other display objects. If your Graphics object + * updates frequently then you should avoid doing this, as it will constantly generate new textures, which will consume + * memory. + * + * As you can tell, Graphics objects are a bit of a trade-off. While they are extremely useful, you need to be careful + * in their complexity and quantity of them in your game. + * + * @class Graphics + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects * @constructor * @since 3.0.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 {(HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[])} source - An array of sources that are used to create the texture. Usually Images, but can also be a Canvas. - * @param {number} [width] - The width of the Texture. This is optional and automatically derived from the source images. - * @param {number} [height] - The height of the Texture. This is optional and automatically derived from the source images. + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.Visible + * @extends Phaser.GameObjects.Components.ScrollFactor + * + * @param {Phaser.Scene} scene - The Scene to which this Graphics object belongs. + * @param {Phaser.Types.GameObjects.Graphics.Options} [options] - Options that set the position and default style of this Graphics object. */ -var Texture = new Class({ +var Graphics = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.Depth, + Components.Mask, + Components.Pipeline, + Components.PostPipeline, + Components.Transform, + Components.Visible, + Components.ScrollFactor, + Render + ], initialize: - function Texture (manager, key, source, width, height) + function Graphics (scene, options) { - if (!Array.isArray(source)) - { - source = [ source ]; - } + var x = GetValue(options, 'x', 0); + var y = GetValue(options, 'y', 0); + + GameObject.call(this, scene, 'Graphics'); + + this.setPosition(x, y); + this.initPipeline(); + this.initPostPipeline(); /** - * A reference to the Texture Manager this Texture belongs to. + * The horizontal display origin of the Graphics. * - * @name Phaser.Textures.Texture#manager - * @type {Phaser.Textures.TextureManager} + * @name Phaser.GameObjects.Graphics#displayOriginX + * @type {number} + * @default 0 * @since 3.0.0 */ - this.manager = manager; + this.displayOriginX = 0; /** - * The unique string-based key of this Texture. + * The vertical display origin of the Graphics. * - * @name Phaser.Textures.Texture#key - * @type {string} + * @name Phaser.GameObjects.Graphics#displayOriginY + * @type {number} + * @default 0 * @since 3.0.0 */ - this.key = key; + this.displayOriginY = 0; /** - * An array of TextureSource instances. - * These are unique to this Texture and contain the actual Image (or Canvas) data. + * The array of commands used to render the Graphics. * - * @name Phaser.Textures.Texture#source - * @type {Phaser.Textures.TextureSource[]} + * @name Phaser.GameObjects.Graphics#commandBuffer + * @type {array} + * @default [] * @since 3.0.0 */ - this.source = []; + this.commandBuffer = []; /** - * An array of TextureSource data instances. - * Used to store additional data images, such as normal maps or specular maps. + * The default fill color for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. * - * @name Phaser.Textures.Texture#dataSource - * @type {array} + * @name Phaser.GameObjects.Graphics#defaultFillColor + * @type {number} + * @readonly + * @default -1 * @since 3.0.0 */ - this.dataSource = []; + this.defaultFillColor = -1; /** - * A key-value object pair associating the unique Frame keys with the Frames objects. + * The default fill alpha for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. * - * @name Phaser.Textures.Texture#frames - * @type {object} + * @name Phaser.GameObjects.Graphics#defaultFillAlpha + * @type {number} + * @readonly + * @default 1 * @since 3.0.0 */ - this.frames = {}; + this.defaultFillAlpha = 1; /** - * Any additional data that was set in the source JSON (if any), - * or any extra data you'd like to store relating to this texture + * The default stroke width for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. * - * @name Phaser.Textures.Texture#customData - * @type {object} + * @name Phaser.GameObjects.Graphics#defaultStrokeWidth + * @type {number} + * @readonly + * @default 1 * @since 3.0.0 */ - this.customData = {}; + this.defaultStrokeWidth = 1; /** - * The name of the first frame of the Texture. + * The default stroke color for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. * - * @name Phaser.Textures.Texture#firstFrame - * @type {string} + * @name Phaser.GameObjects.Graphics#defaultStrokeColor + * @type {number} + * @readonly + * @default -1 * @since 3.0.0 */ - this.firstFrame = '__BASE'; + this.defaultStrokeColor = -1; /** - * The total number of Frames in this Texture, including the `__BASE` frame. + * The default stroke alpha for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. * - * A Texture will always contain at least 1 frame because every Texture contains a `__BASE` frame by default, - * in addition to any extra frames that have been added to it, such as when parsing a Sprite Sheet or Texture Atlas. + * @name Phaser.GameObjects.Graphics#defaultStrokeAlpha + * @type {number} + * @readonly + * @default 1 + * @since 3.0.0 + */ + this.defaultStrokeAlpha = 1; + + /** + * Internal property that keeps track of the line width style setting. * - * @name Phaser.Textures.Texture#frameTotal + * @name Phaser.GameObjects.Graphics#_lineWidth * @type {number} - * @default 0 + * @private * @since 3.0.0 */ - this.frameTotal = 0; + this._lineWidth = 1.0; - // Load the Sources - for (var i = 0; i < source.length; i++) - { - this.source.push(new TextureSource(this, source[i], width, height)); - } + this.setDefaultStyles(options); }, /** - * Adds a new Frame to this Texture. - * - * A Frame is a rectangular region of a TextureSource with a unique index or string-based key. - * - * The name given must be unique within this Texture. If it already exists, this method will return `null`. + * Set the default style settings for this Graphics object. * - * @method Phaser.Textures.Texture#add + * @method Phaser.GameObjects.Graphics#setDefaultStyles * @since 3.0.0 * - * @param {(number|string)} name - The name of this Frame. The name is unique within the Texture. - * @param {number} sourceIndex - The index of the TextureSource that this Frame is a part of. - * @param {number} x - The x coordinate of the top-left of this Frame. - * @param {number} y - The y coordinate of the top-left of this Frame. - * @param {number} width - The width of this Frame. - * @param {number} height - The height of this Frame. + * @param {Phaser.Types.GameObjects.Graphics.Styles} options - The styles to set as defaults. * - * @return {?Phaser.Textures.Frame} The Frame that was added to this Texture, or `null` if the given name already exists. + * @return {this} This Game Object. */ - add: function (name, sourceIndex, x, y, width, height) + setDefaultStyles: function (options) { - if (this.has(name)) + if (GetValue(options, 'lineStyle', null)) { - return null; - } - - var frame = new Frame(this, name, sourceIndex, x, y, width, height); + this.defaultStrokeWidth = GetValue(options, 'lineStyle.width', 1); + this.defaultStrokeColor = GetValue(options, 'lineStyle.color', 0xffffff); + this.defaultStrokeAlpha = GetValue(options, 'lineStyle.alpha', 1); - this.frames[name] = frame; + this.lineStyle(this.defaultStrokeWidth, this.defaultStrokeColor, this.defaultStrokeAlpha); + } - // Set the first frame of the Texture (other than __BASE) - // This is used to ensure we don't spam the display with entire - // atlases of sprite sheets, but instead just the first frame of them - // should the dev incorrectly specify the frame index - if (this.firstFrame === '__BASE') + if (GetValue(options, 'fillStyle', null)) { - this.firstFrame = name; - } + this.defaultFillColor = GetValue(options, 'fillStyle.color', 0xffffff); + this.defaultFillAlpha = GetValue(options, 'fillStyle.alpha', 1); - this.frameTotal++; + this.fillStyle(this.defaultFillColor, this.defaultFillAlpha); + } - return frame; + return this; }, /** - * Removes the given Frame from this Texture. The Frame is destroyed immediately. + * Set the current line style. Used for all 'stroke' related functions. * - * Any Game Objects using this Frame should stop using it _before_ you remove it, - * as it does not happen automatically. - * - * @method Phaser.Textures.Texture#remove - * @since 3.19.0 + * @method Phaser.GameObjects.Graphics#lineStyle + * @since 3.0.0 * - * @param {string} name - The key of the Frame to remove. + * @param {number} lineWidth - The stroke width. + * @param {number} color - The stroke color. + * @param {number} [alpha=1] - The stroke alpha. * - * @return {boolean} True if a Frame with the matching key was removed from this Texture. + * @return {this} This Game Object. */ - remove: function (name) + lineStyle: function (lineWidth, color, alpha) { - if (this.has(name)) - { - var frame = this.get(name); - - frame.destroy(); + if (alpha === undefined) { alpha = 1; } - delete this.frames[name]; + this.commandBuffer.push( + Commands.LINE_STYLE, + lineWidth, color, alpha + ); - return true; - } + this._lineWidth = lineWidth; - return false; + return this; }, /** - * Checks to see if a Frame matching the given key exists within this Texture. + * Set the current fill style. Used for all 'fill' related functions. * - * @method Phaser.Textures.Texture#has + * @method Phaser.GameObjects.Graphics#fillStyle * @since 3.0.0 * - * @param {string} name - The key of the Frame to check for. + * @param {number} color - The fill color. + * @param {number} [alpha=1] - The fill alpha. * - * @return {boolean} True if a Frame with the matching key exists in this Texture. + * @return {this} This Game Object. */ - has: function (name) + fillStyle: function (color, alpha) { - return (this.frames[name]); + if (alpha === undefined) { alpha = 1; } + + this.commandBuffer.push( + Commands.FILL_STYLE, + color, alpha + ); + + return this; }, /** - * Gets a Frame from this Texture based on either the key or the index of the Frame. + * Sets a gradient fill style. This is a WebGL only feature. * - * In a Texture Atlas Frames are typically referenced by a key. - * In a Sprite Sheet Frames are referenced by an index. - * Passing no value for the name returns the base texture. + * The gradient color values represent the 4 corners of an untransformed rectangle. + * The gradient is used to color all filled shapes and paths drawn after calling this method. + * If you wish to turn a gradient off, call `fillStyle` and provide a new single fill color. * - * @method Phaser.Textures.Texture#get - * @since 3.0.0 + * When filling a triangle only the first 3 color values provided are used for the 3 points of a triangle. * - * @param {(string|number)} [name] - The string-based name, or integer based index, of the Frame to get from this Texture. + * This feature is best used only on rectangles and triangles. All other shapes will give strange results. * - * @return {Phaser.Textures.Frame} The Texture Frame. + * Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used + * will be filled with a gradient on its own. There is no ability to gradient fill a shape or path as a single + * entity at this time. + * + * @method Phaser.GameObjects.Graphics#fillGradientStyle + * @webglOnly + * @since 3.12.0 + * + * @param {number} topLeft - The top left fill color. + * @param {number} topRight - The top right fill color. + * @param {number} bottomLeft - The bottom left fill color. + * @param {number} bottomRight - The bottom right fill color. Not used when filling triangles. + * @param {number} [alphaTopLeft=1] - The top left alpha value. If you give only this value, it's used for all corners. + * @param {number} [alphaTopRight=1] - The top right alpha value. + * @param {number} [alphaBottomLeft=1] - The bottom left alpha value. + * @param {number} [alphaBottomRight=1] - The bottom right alpha value. + * + * @return {this} This Game Object. */ - get: function (name) + fillGradientStyle: function (topLeft, topRight, bottomLeft, bottomRight, alphaTopLeft, alphaTopRight, alphaBottomLeft, alphaBottomRight) { - // null, undefined, empty string, zero - if (!name) - { - name = this.firstFrame; - } - - var frame = this.frames[name]; - - if (!frame) - { - console.warn(TEXTURE_MISSING_ERROR + name); + if (alphaTopLeft === undefined) { alphaTopLeft = 1; } + if (alphaTopRight === undefined) { alphaTopRight = alphaTopLeft; } + if (alphaBottomLeft === undefined) { alphaBottomLeft = alphaTopLeft; } + if (alphaBottomRight === undefined) { alphaBottomRight = alphaTopLeft; } - frame = this.frames[this.firstFrame]; - } + this.commandBuffer.push( + Commands.GRADIENT_FILL_STYLE, + alphaTopLeft, alphaTopRight, alphaBottomLeft, alphaBottomRight, + topLeft, topRight, bottomLeft, bottomRight + ); - return frame; + return this; }, /** - * Takes the given TextureSource and returns the index of it within this Texture. - * If it's not in this Texture, it returns -1. - * Unless this Texture has multiple TextureSources, such as with a multi-atlas, this - * method will always return zero or -1. + * Sets a gradient line style. This is a WebGL only feature. * - * @method Phaser.Textures.Texture#getTextureSourceIndex - * @since 3.0.0 + * The gradient color values represent the 4 corners of an untransformed rectangle. + * The gradient is used to color all stroked shapes and paths drawn after calling this method. + * If you wish to turn a gradient off, call `lineStyle` and provide a new single line color. * - * @param {Phaser.Textures.TextureSource} source - The TextureSource to check. + * This feature is best used only on single lines. All other shapes will give strange results. * - * @return {number} The index of the TextureSource within this Texture, or -1 if not in this Texture. + * Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used + * will be filled with a gradient on its own. There is no ability to gradient stroke a shape or path as a single + * entity at this time. + * + * @method Phaser.GameObjects.Graphics#lineGradientStyle + * @webglOnly + * @since 3.12.0 + * + * @param {number} lineWidth - The stroke width. + * @param {number} topLeft - The tint being applied to the top-left of the Game Object. + * @param {number} topRight - The tint being applied to the top-right of the Game Object. + * @param {number} bottomLeft - The tint being applied to the bottom-left of the Game Object. + * @param {number} bottomRight - The tint being applied to the bottom-right of the Game Object. + * @param {number} [alpha=1] - The fill alpha. + * + * @return {this} This Game Object. */ - getTextureSourceIndex: function (source) + lineGradientStyle: function (lineWidth, topLeft, topRight, bottomLeft, bottomRight, alpha) { - for (var i = 0; i < this.source.length; i++) - { - if (this.source[i] === source) - { - return i; - } - } + if (alpha === undefined) { alpha = 1; } - return -1; + this.commandBuffer.push( + Commands.GRADIENT_LINE_STYLE, + lineWidth, alpha, topLeft, topRight, bottomLeft, bottomRight + ); + + return this; }, /** - * Returns an array of all the Frames in the given TextureSource. + * Start a new shape path. * - * @method Phaser.Textures.Texture#getFramesFromTextureSource + * @method Phaser.GameObjects.Graphics#beginPath * @since 3.0.0 * - * @param {number} sourceIndex - The index of the TextureSource to get the Frames from. - * @param {boolean} [includeBase=false] - Include the `__BASE` Frame in the output array? - * - * @return {Phaser.Textures.Frame[]} An array of Texture Frames. + * @return {this} This Game Object. */ - getFramesFromTextureSource: function (sourceIndex, includeBase) + beginPath: function () { - if (includeBase === undefined) { includeBase = false; } - - var out = []; - - for (var frameName in this.frames) - { - if (frameName === '__BASE' && !includeBase) - { - continue; - } - - var frame = this.frames[frameName]; - - if (frame.sourceIndex === sourceIndex) - { - out.push(frame); - } - } + this.commandBuffer.push( + Commands.BEGIN_PATH + ); - return out; + return this; }, /** - * Returns an array with all of the names of the Frames in this Texture. - * - * Useful if you want to randomly assign a Frame to a Game Object, as you can - * pick a random element from the returned array. + * Close the current path. * - * @method Phaser.Textures.Texture#getFrameNames + * @method Phaser.GameObjects.Graphics#closePath * @since 3.0.0 * - * @param {boolean} [includeBase=false] - Include the `__BASE` Frame in the output array? - * - * @return {string[]} An array of all Frame names in this Texture. + * @return {this} This Game Object. */ - getFrameNames: function (includeBase) + closePath: function () { - if (includeBase === undefined) { includeBase = false; } - - var out = Object.keys(this.frames); + this.commandBuffer.push( + Commands.CLOSE_PATH + ); - if (!includeBase) - { - var idx = out.indexOf('__BASE'); + return this; + }, - if (idx !== -1) - { - out.splice(idx, 1); - } - } + /** + * Fill the current path. + * + * @method Phaser.GameObjects.Graphics#fillPath + * @since 3.0.0 + * + * @return {this} This Game Object. + */ + fillPath: function () + { + this.commandBuffer.push( + Commands.FILL_PATH + ); - return out; + return this; }, /** - * Given a Frame name, return the source image it uses to render with. - * - * This will return the actual DOM Image or Canvas element. + * Fill the current path. * - * @method Phaser.Textures.Texture#getSourceImage - * @since 3.0.0 + * This is an alias for `Graphics.fillPath` and does the same thing. + * It was added to match the CanvasRenderingContext 2D API. * - * @param {(string|number)} [name] - The string-based name, or integer based index, of the Frame to get from this Texture. + * @method Phaser.GameObjects.Graphics#fill + * @since 3.16.0 * - * @return {(HTMLImageElement|HTMLCanvasElement|Phaser.GameObjects.RenderTexture)} The DOM Image, Canvas Element or Render Texture. + * @return {this} This Game Object. */ - getSourceImage: function (name) + fill: function () { - if (name === undefined || name === null || this.frameTotal === 1) - { - name = '__BASE'; - } + this.commandBuffer.push( + Commands.FILL_PATH + ); - var frame = this.frames[name]; + return this; + }, - if (frame) - { - return frame.source.image; - } - else - { - console.warn(TEXTURE_MISSING_ERROR + name); + /** + * Stroke the current path. + * + * @method Phaser.GameObjects.Graphics#strokePath + * @since 3.0.0 + * + * @return {this} This Game Object. + */ + strokePath: function () + { + this.commandBuffer.push( + Commands.STROKE_PATH + ); - return this.frames['__BASE'].source.image; - } + return this; }, /** - * Given a Frame name, return the data source image it uses to render with. - * You can use this to get the normal map for an image for example. - * - * This will return the actual DOM Image. + * Stroke the current path. * - * @method Phaser.Textures.Texture#getDataSourceImage - * @since 3.7.0 + * This is an alias for `Graphics.strokePath` and does the same thing. + * It was added to match the CanvasRenderingContext 2D API. * - * @param {(string|number)} [name] - The string-based name, or integer based index, of the Frame to get from this Texture. + * @method Phaser.GameObjects.Graphics#stroke + * @since 3.16.0 * - * @return {(HTMLImageElement|HTMLCanvasElement)} The DOM Image or Canvas Element. + * @return {this} This Game Object. */ - getDataSourceImage: function (name) + stroke: function () { - if (name === undefined || name === null || this.frameTotal === 1) - { - name = '__BASE'; - } - - var frame = this.frames[name]; - var idx; - - if (!frame) - { - console.warn(TEXTURE_MISSING_ERROR + name); + this.commandBuffer.push( + Commands.STROKE_PATH + ); - idx = this.frames['__BASE'].sourceIndex; - } - else - { - idx = frame.sourceIndex; - } + return this; + }, - return this.dataSource[idx].image; + /** + * Fill the given circle. + * + * @method Phaser.GameObjects.Graphics#fillCircleShape + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The circle to fill. + * + * @return {this} This Game Object. + */ + fillCircleShape: function (circle) + { + return this.fillCircle(circle.x, circle.y, circle.radius); }, /** - * Adds a data source image to this Texture. + * Stroke the given circle. * - * An example of a data source image would be a normal map, where all of the Frames for this Texture - * equally apply to the normal map. + * @method Phaser.GameObjects.Graphics#strokeCircleShape + * @since 3.0.0 * - * @method Phaser.Textures.Texture#setDataSource + * @param {Phaser.Geom.Circle} circle - The circle to stroke. + * + * @return {this} This Game Object. + */ + strokeCircleShape: function (circle) + { + return this.strokeCircle(circle.x, circle.y, circle.radius); + }, + + /** + * Fill a circle with the given position and radius. + * + * @method Phaser.GameObjects.Graphics#fillCircle * @since 3.0.0 * - * @param {(HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[])} data - The source image. + * @param {number} x - The x coordinate of the center of the circle. + * @param {number} y - The y coordinate of the center of the circle. + * @param {number} radius - The radius of the circle. + * + * @return {this} This Game Object. */ - setDataSource: function (data) + fillCircle: function (x, y, radius) { - if (!Array.isArray(data)) - { - data = [ data ]; - } + this.beginPath(); + this.arc(x, y, radius, 0, MATH_CONST.PI2); + this.fillPath(); - for (var i = 0; i < data.length; i++) - { - var source = this.source[i]; + return this; + }, - this.dataSource.push(new TextureSource(this, data[i], source.width, source.height)); - } + /** + * Stroke a circle with the given position and radius. + * + * @method Phaser.GameObjects.Graphics#strokeCircle + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the center of the circle. + * @param {number} y - The y coordinate of the center of the circle. + * @param {number} radius - The radius of the circle. + * + * @return {this} This Game Object. + */ + strokeCircle: function (x, y, radius) + { + this.beginPath(); + this.arc(x, y, radius, 0, MATH_CONST.PI2); + this.strokePath(); + + return this; }, /** - * Sets the Filter Mode for this Texture. + * Fill the given rectangle. * - * The mode can be either Linear, the default, or Nearest. + * @method Phaser.GameObjects.Graphics#fillRectShape + * @since 3.0.0 * - * For pixel-art you should use Nearest. + * @param {Phaser.Geom.Rectangle} rect - The rectangle to fill. * - * The mode applies to the entire Texture, not just a specific Frame of it. + * @return {this} This Game Object. + */ + fillRectShape: function (rect) + { + return this.fillRect(rect.x, rect.y, rect.width, rect.height); + }, + + /** + * Stroke the given rectangle. * - * @method Phaser.Textures.Texture#setFilter + * @method Phaser.GameObjects.Graphics#strokeRectShape * @since 3.0.0 * - * @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode. + * @param {Phaser.Geom.Rectangle} rect - The rectangle to stroke. + * + * @return {this} This Game Object. */ - setFilter: function (filterMode) + strokeRectShape: function (rect) { - var i; + return this.strokeRect(rect.x, rect.y, rect.width, rect.height); + }, - for (i = 0; i < this.source.length; i++) - { - this.source[i].setFilter(filterMode); - } + /** + * Fill a rectangle with the given position and size. + * + * @method Phaser.GameObjects.Graphics#fillRect + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the top-left of the rectangle. + * @param {number} y - The y coordinate of the top-left of the rectangle. + * @param {number} width - The width of the rectangle. + * @param {number} height - The height of the rectangle. + * + * @return {this} This Game Object. + */ + fillRect: function (x, y, width, height) + { + this.commandBuffer.push( + Commands.FILL_RECT, + x, y, width, height + ); - for (i = 0; i < this.dataSource.length; i++) - { - this.dataSource[i].setFilter(filterMode); - } + return this; }, /** - * Destroys this Texture and releases references to its sources and frames. + * Stroke a rectangle with the given position and size. * - * @method Phaser.Textures.Texture#destroy + * @method Phaser.GameObjects.Graphics#strokeRect * @since 3.0.0 + * + * @param {number} x - The x coordinate of the top-left of the rectangle. + * @param {number} y - The y coordinate of the top-left of the rectangle. + * @param {number} width - The width of the rectangle. + * @param {number} height - The height of the rectangle. + * + * @return {this} This Game Object. */ - destroy: function () + strokeRect: function (x, y, width, height) { - var i; + var lineWidthHalf = this._lineWidth / 2; + var minx = x - lineWidthHalf; + var maxx = x + lineWidthHalf; - for (i = 0; i < this.source.length; i++) - { - this.source[i].destroy(); - } + this.beginPath(); + this.moveTo(x, y); + this.lineTo(x, y + height); + this.strokePath(); - for (i = 0; i < this.dataSource.length; i++) - { - this.dataSource[i].destroy(); - } + this.beginPath(); + this.moveTo(x + width, y); + this.lineTo(x + width, y + height); + this.strokePath(); - for (var frameName in this.frames) - { - var frame = this.frames[frameName]; + this.beginPath(); + this.moveTo(minx, y); + this.lineTo(maxx + width, y); + this.strokePath(); - frame.destroy(); - } + this.beginPath(); + this.moveTo(minx, y + height); + this.lineTo(maxx + width, y + height); + this.strokePath(); - this.source = []; - this.dataSource = []; - this.frames = {}; + return this; + }, - this.manager.removeKey(this.key); + /** + * Fill a rounded rectangle with the given position, size and radius. + * + * @method Phaser.GameObjects.Graphics#fillRoundedRect + * @since 3.11.0 + * + * @param {number} x - The x coordinate of the top-left of the rectangle. + * @param {number} y - The y coordinate of the top-left of the rectangle. + * @param {number} width - The width of the rectangle. + * @param {number} height - The height of the rectangle. + * @param {(Phaser.Types.GameObjects.Graphics.RoundedRectRadius|number)} [radius=20] - The corner radius; It can also be an object to specify different radius for corners. + * + * @return {this} This Game Object. + */ + fillRoundedRect: function (x, y, width, height, radius) + { + if (radius === undefined) { radius = 20; } - var renderer = this.manager.game.renderer; + var tl = radius; + var tr = radius; + var bl = radius; + var br = radius; - if (renderer && renderer.type === CONST.WEBGL) + if (typeof radius !== 'number') { - renderer.resetTextures(true); + tl = GetFastValue(radius, 'tl', 20); + tr = GetFastValue(radius, 'tr', 20); + bl = GetFastValue(radius, 'bl', 20); + br = GetFastValue(radius, 'br', 20); } - this.manager = null; - } - -}); - -module.exports = Texture; - - -/***/ }), -/* 207 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var convexTL = (tl >= 0); + var convexTR = (tr >= 0); + var convexBL = (bl >= 0); + var convexBR = (br >= 0); -var SafeRange = __webpack_require__(78); - -/** - * Returns all elements in the array. - * - * You can optionally specify a matching criteria using the `property` and `value` arguments. - * - * For example: `getAll('visible', true)` would return only elements that have their visible property set. - * - * Optionally you can specify a start and end index. For example if the array had 100 elements, - * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only - * the first 50 elements. - * - * @function Phaser.Utils.Array.GetAll - * @since 3.4.0 - * - * @param {array} array - The array to search. - * @param {string} [property] - The property to test on each array element. - * @param {*} [value] - The value to test the property against. Must pass a strict (`===`) comparison check. - * @param {number} [startIndex] - An optional start index to search from. - * @param {number} [endIndex] - An optional end index to search to. - * - * @return {array} All matching elements from the array. - */ -var GetAll = function (array, property, value, startIndex, endIndex) -{ - if (startIndex === undefined) { startIndex = 0; } - if (endIndex === undefined) { endIndex = array.length; } + tl = Math.abs(tl); + tr = Math.abs(tr); + bl = Math.abs(bl); + br = Math.abs(br); - var output = []; + this.beginPath(); + this.moveTo(x + tl, y); + this.lineTo(x + width - tr, y); - if (SafeRange(array, startIndex, endIndex)) - { - for (var i = startIndex; i < endIndex; i++) + if (convexTR) { - var child = array[i]; - - if (!property || - (property && value === undefined && child.hasOwnProperty(property)) || - (property && value !== undefined && child[property] === value)) - { - output.push(child); - } + this.arc(x + width - tr, y + tr, tr, -MATH_CONST.TAU, 0); + } + else + { + this.arc(x + width, y, tr, Math.PI, MATH_CONST.TAU, true); } - } - - return output; -}; - -module.exports = GetAll; - - -/***/ }), -/* 208 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ -/** - * @namespace Phaser.Utils.Array - */ + this.lineTo(x + width, y + height - br); -module.exports = { + if (convexBR) + { + this.arc(x + width - br, y + height - br, br, 0, MATH_CONST.TAU); + } + else + { + this.arc(x + width, y + height, br, -MATH_CONST.TAU, Math.PI, true); + } - Matrix: __webpack_require__(1013), + this.lineTo(x + bl, y + height); - Add: __webpack_require__(1021), - AddAt: __webpack_require__(1022), - BringToTop: __webpack_require__(1023), - CountAllMatching: __webpack_require__(1024), - Each: __webpack_require__(1025), - EachInRange: __webpack_require__(1026), - FindClosestInSorted: __webpack_require__(318), - GetAll: __webpack_require__(207), - GetFirst: __webpack_require__(428), - GetRandom: __webpack_require__(210), - MoveDown: __webpack_require__(1027), - MoveTo: __webpack_require__(1028), - MoveUp: __webpack_require__(1029), - MoveAbove: __webpack_require__(1030), - MoveBelow: __webpack_require__(1031), - NumberArray: __webpack_require__(322), - NumberArrayStep: __webpack_require__(1032), - QuickSelect: __webpack_require__(436), - Range: __webpack_require__(437), - Remove: __webpack_require__(93), - RemoveAt: __webpack_require__(1033), - RemoveBetween: __webpack_require__(1034), - RemoveRandomElement: __webpack_require__(1035), - Replace: __webpack_require__(1036), - RotateLeft: __webpack_require__(178), - RotateRight: __webpack_require__(179), - SafeRange: __webpack_require__(78), - SendToBack: __webpack_require__(1037), - SetAll: __webpack_require__(1038), - Shuffle: __webpack_require__(131), - SortByDigits: __webpack_require__(320), - SpliceOne: __webpack_require__(74), - StableSort: __webpack_require__(79), - Swap: __webpack_require__(1039) + if (convexBL) + { + this.arc(x + bl, y + height - bl, bl, MATH_CONST.TAU, Math.PI); + } + else + { + this.arc(x, y + height, bl, 0, -MATH_CONST.TAU, true); + } -}; + this.lineTo(x, y + tl); + if (convexTL) + { + this.arc(x + tl, y + tl, tl, -Math.PI, -MATH_CONST.TAU); + } + else + { + this.arc(x, y, tl, MATH_CONST.TAU, 0, true); + } -/***/ }), -/* 209 */ -/***/ (function(module, exports) { + this.fillPath(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * Checks if an array can be used as a matrix. - * - * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) - * have the same length. There must be at least two rows. This is an example matrix: - * - * ``` - * [ - * [ 1, 1, 1, 1, 1, 1 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 2, 0, 1, 2, 0, 4 ], - * [ 2, 0, 3, 4, 0, 4 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 3, 3, 3, 3, 3, 3 ] - * ] - * ``` - * - * @function Phaser.Utils.Array.Matrix.CheckMatrix - * @since 3.0.0 - * - * @generic T - * @genericUse {T[][]} - [matrix] - * - * @param {T[][]} [matrix] - The array to check. - * - * @return {boolean} `true` if the given `matrix` array is a valid matrix. - */ -var CheckMatrix = function (matrix) -{ - if (!Array.isArray(matrix) || matrix.length < 2 || !Array.isArray(matrix[0])) + /** + * Stroke a rounded rectangle with the given position, size and radius. + * + * @method Phaser.GameObjects.Graphics#strokeRoundedRect + * @since 3.11.0 + * + * @param {number} x - The x coordinate of the top-left of the rectangle. + * @param {number} y - The y coordinate of the top-left of the rectangle. + * @param {number} width - The width of the rectangle. + * @param {number} height - The height of the rectangle. + * @param {(Phaser.Types.GameObjects.Graphics.RoundedRectRadius|number)} [radius=20] - The corner radius; It can also be an object to specify different radii for corners. + * + * @return {this} This Game Object. + */ + strokeRoundedRect: function (x, y, width, height, radius) { - return false; - } + if (radius === undefined) { radius = 20; } - // How long is the first row? - var size = matrix[0].length; + var tl = radius; + var tr = radius; + var bl = radius; + var br = radius; - // Validate the rest of the rows are the same length - for (var i = 1; i < matrix.length; i++) - { - if (matrix[i].length !== size) + var maxRadius = Math.min(width, height) / 2; + + if (typeof radius !== 'number') { - return false; + tl = GetFastValue(radius, 'tl', 20); + tr = GetFastValue(radius, 'tr', 20); + bl = GetFastValue(radius, 'bl', 20); + br = GetFastValue(radius, 'br', 20); } - } - return true; -}; + var convexTL = (tl >= 0); + var convexTR = (tr >= 0); + var convexBL = (bl >= 0); + var convexBR = (br >= 0); -module.exports = CheckMatrix; + tl = Math.min(Math.abs(tl), maxRadius); + tr = Math.min(Math.abs(tr), maxRadius); + bl = Math.min(Math.abs(bl), maxRadius); + br = Math.min(Math.abs(br), maxRadius); + this.beginPath(); + this.moveTo(x + tl, y); + this.lineTo(x + width - tr, y); + this.moveTo(x + width - tr, y); -/***/ }), -/* 210 */ -/***/ (function(module, exports) { + if (convexTR) + { + this.arc(x + width - tr, y + tr, tr, -MATH_CONST.TAU, 0); + } + else + { + this.arc(x + width, y, tr, Math.PI, MATH_CONST.TAU, true); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.lineTo(x + width, y + height - br); + this.moveTo(x + width, y + height - br); -/** - * Returns a Random element from the array. - * - * @function Phaser.Utils.Array.GetRandom - * @since 3.0.0 - * - * @param {array} array - The array to select the random entry from. - * @param {number} [startIndex=0] - An optional start index. - * @param {number} [length=array.length] - An optional length, the total number of elements (from the startIndex) to choose from. - * - * @return {*} A random element from the array, or `null` if no element could be found in the range given. - */ -var GetRandom = function (array, startIndex, length) -{ - if (startIndex === undefined) { startIndex = 0; } - if (length === undefined) { length = array.length; } + if (convexBR) + { + this.arc(x + width - br, y + height - br, br, 0, MATH_CONST.TAU); + } + else + { + this.arc(x + width, y + height, br, -MATH_CONST.TAU, Math.PI, true); + } - var randomIndex = startIndex + Math.floor(Math.random() * length); + this.lineTo(x + bl, y + height); + this.moveTo(x + bl, y + height); - return (array[randomIndex] === undefined) ? null : array[randomIndex]; -}; + if (convexBL) + { + this.arc(x + bl, y + height - bl, bl, MATH_CONST.TAU, Math.PI); + } + else + { + this.arc(x, y + height, bl, 0, -MATH_CONST.TAU, true); + } -module.exports = GetRandom; + this.lineTo(x, y + tl); + this.moveTo(x, y + tl); + if (convexTL) + { + this.arc(x + tl, y + tl, tl, -Math.PI, -MATH_CONST.TAU); + } + else + { + this.arc(x, y, tl, MATH_CONST.TAU, 0, true); + } -/***/ }), -/* 211 */ -/***/ (function(module, exports, __webpack_require__) { + this.strokePath(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(438); + /** + * Fill the given point. + * + * Draws a square at the given position, 1 pixel in size by default. + * + * @method Phaser.GameObjects.Graphics#fillPointShape + * @since 3.0.0 + * + * @param {(Phaser.Geom.Point|Phaser.Math.Vector2|object)} point - The point to fill. + * @param {number} [size=1] - The size of the square to draw. + * + * @return {this} This Game Object. + */ + fillPointShape: function (point, size) + { + return this.fillPoint(point.x, point.y, size); + }, -/** - * @classdesc - * A Process Queue maintains three internal lists. - * - * The `pending` list is a selection of items which are due to be made 'active' in the next update. - * The `active` list is a selection of items which are considered active and should be updated. - * The `destroy` list is a selection of items that were active and are awaiting being destroyed in the next update. - * - * When new items are added to a Process Queue they are put in the pending list, rather than being added - * immediately the active list. Equally, items that are removed are put into the destroy list, rather than - * being destroyed immediately. This allows the Process Queue to carefully process each item at a specific, fixed - * time, rather than at the time of the request from the API. - * - * @class ProcessQueue - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Structs - * @constructor - * @since 3.0.0 - * - * @generic T - */ -var ProcessQueue = new Class({ + /** + * Fill a point at the given position. + * + * Draws a square at the given position, 1 pixel in size by default. + * + * @method Phaser.GameObjects.Graphics#fillPoint + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the point. + * @param {number} y - The y coordinate of the point. + * @param {number} [size=1] - The size of the square to draw. + * + * @return {this} This Game Object. + */ + fillPoint: function (x, y, size) + { + if (!size || size < 1) + { + size = 1; + } + else + { + x -= (size / 2); + y -= (size / 2); + } - Extends: EventEmitter, + this.commandBuffer.push( + Commands.FILL_RECT, + x, y, size, size + ); - initialize: + return this; + }, - function ProcessQueue () + /** + * Fill the given triangle. + * + * @method Phaser.GameObjects.Graphics#fillTriangleShape + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The triangle to fill. + * + * @return {this} This Game Object. + */ + fillTriangleShape: function (triangle) { - EventEmitter.call(this); + return this.fillTriangle(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3); + }, - /** - * The `pending` list is a selection of items which are due to be made 'active' in the next update. - * - * @genericUse {T[]} - [$type] - * - * @name Phaser.Structs.ProcessQueue#_pending - * @type {Array.<*>} - * @private - * @default [] - * @since 3.0.0 - */ - this._pending = []; + /** + * Stroke the given triangle. + * + * @method Phaser.GameObjects.Graphics#strokeTriangleShape + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The triangle to stroke. + * + * @return {this} This Game Object. + */ + strokeTriangleShape: function (triangle) + { + return this.strokeTriangle(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3); + }, - /** - * The `active` list is a selection of items which are considered active and should be updated. - * - * @genericUse {T[]} - [$type] - * - * @name Phaser.Structs.ProcessQueue#_active - * @type {Array.<*>} - * @private - * @default [] - * @since 3.0.0 - */ - this._active = []; + /** + * Fill a triangle with the given points. + * + * @method Phaser.GameObjects.Graphics#fillTriangle + * @since 3.0.0 + * + * @param {number} x0 - The x coordinate of the first point. + * @param {number} y0 - The y coordinate of the first point. + * @param {number} x1 - The x coordinate of the second point. + * @param {number} y1 - The y coordinate of the second point. + * @param {number} x2 - The x coordinate of the third point. + * @param {number} y2 - The y coordinate of the third point. + * + * @return {this} This Game Object. + */ + fillTriangle: function (x0, y0, x1, y1, x2, y2) + { + this.commandBuffer.push( + Commands.FILL_TRIANGLE, + x0, y0, x1, y1, x2, y2 + ); - /** - * The `destroy` list is a selection of items that were active and are awaiting being destroyed in the next update. - * - * @genericUse {T[]} - [$type] - * - * @name Phaser.Structs.ProcessQueue#_destroy - * @type {Array.<*>} - * @private - * @default [] - * @since 3.0.0 - */ - this._destroy = []; + return this; + }, - /** - * The total number of items awaiting processing. - * - * @name Phaser.Structs.ProcessQueue#_toProcess - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._toProcess = 0; + /** + * Stroke a triangle with the given points. + * + * @method Phaser.GameObjects.Graphics#strokeTriangle + * @since 3.0.0 + * + * @param {number} x0 - The x coordinate of the first point. + * @param {number} y0 - The y coordinate of the first point. + * @param {number} x1 - The x coordinate of the second point. + * @param {number} y1 - The y coordinate of the second point. + * @param {number} x2 - The x coordinate of the third point. + * @param {number} y2 - The y coordinate of the third point. + * + * @return {this} This Game Object. + */ + strokeTriangle: function (x0, y0, x1, y1, x2, y2) + { + this.commandBuffer.push( + Commands.STROKE_TRIANGLE, + x0, y0, x1, y1, x2, y2 + ); - /** - * If `true` only unique objects will be allowed in the queue. - * - * @name Phaser.Structs.ProcessQueue#checkQueue - * @type {boolean} - * @since 3.50.0 - */ - this.checkQueue = false; + return this; }, /** - * Adds a new item to the Process Queue. - * - * The item is added to the pending list and made active in the next update. + * Draw the given line. * - * @method Phaser.Structs.ProcessQueue#add + * @method Phaser.GameObjects.Graphics#strokeLineShape * @since 3.0.0 * - * @genericUse {T} - [item] - * @genericUse {Phaser.Structs.ProcessQueue.} - [$return] - * - * @param {*} item - The item to add to the queue. + * @param {Phaser.Geom.Line} line - The line to stroke. * - * @return {*} The item that was added. + * @return {this} This Game Object. */ - add: function (item) + strokeLineShape: function (line) { - this._pending.push(item); + return this.lineBetween(line.x1, line.y1, line.x2, line.y2); + }, - this._toProcess++; + /** + * Draw a line between the given points. + * + * @method Phaser.GameObjects.Graphics#lineBetween + * @since 3.0.0 + * + * @param {number} x1 - The x coordinate of the start point of the line. + * @param {number} y1 - The y coordinate of the start point of the line. + * @param {number} x2 - The x coordinate of the end point of the line. + * @param {number} y2 - The y coordinate of the end point of the line. + * + * @return {this} This Game Object. + */ + lineBetween: function (x1, y1, x2, y2) + { + this.beginPath(); + this.moveTo(x1, y1); + this.lineTo(x2, y2); + this.strokePath(); - return item; + return this; }, /** - * Removes an item from the Process Queue. + * Draw a line from the current drawing position to the given position. * - * The item is added to the pending destroy and fully removed in the next update. + * Moves the current drawing position to the given position. * - * @method Phaser.Structs.ProcessQueue#remove + * @method Phaser.GameObjects.Graphics#lineTo * @since 3.0.0 * - * @genericUse {T} - [item] - * @genericUse {Phaser.Structs.ProcessQueue.} - [$return] - * - * @param {*} item - The item to be removed from the queue. + * @param {number} x - The x coordinate to draw the line to. + * @param {number} y - The y coordinate to draw the line to. * - * @return {*} The item that was removed. + * @return {this} This Game Object. */ - remove: function (item) + lineTo: function (x, y) { - this._destroy.push(item); - - this._toProcess++; + this.commandBuffer.push( + Commands.LINE_TO, + x, y + ); - return item; + return this; }, /** - * Removes all active items from this Process Queue. + * Move the current drawing position to the given position. * - * All the items are marked as 'pending destroy' and fully removed in the next update. + * @method Phaser.GameObjects.Graphics#moveTo + * @since 3.0.0 * - * @method Phaser.Structs.ProcessQueue#removeAll - * @since 3.20.0 + * @param {number} x - The x coordinate to move to. + * @param {number} y - The y coordinate to move to. * - * @return {this} This Process Queue object. + * @return {this} This Game Object. */ - removeAll: function () + moveTo: function (x, y) { - var list = this._active; - var destroy = this._destroy; - var i = list.length; - - while (i--) - { - destroy.push(list[i]); - - this._toProcess++; - } + this.commandBuffer.push( + Commands.MOVE_TO, + x, y + ); return this; }, /** - * Update this queue. First it will process any items awaiting destruction, and remove them. + * Stroke the shape represented by the given array of points. * - * Then it will check to see if there are any items pending insertion, and move them to an - * active state. Finally, it will return a list of active items for further processing. + * Pass `closeShape` to automatically close the shape by joining the last to the first point. * - * @method Phaser.Structs.ProcessQueue#update + * Pass `closePath` to automatically close the path before it is stroked. + * + * @method Phaser.GameObjects.Graphics#strokePoints * @since 3.0.0 * - * @genericUse {T[]} - [$return] + * @param {(array|Phaser.Geom.Point[])} points - The points to stroke. + * @param {boolean} [closeShape=false] - When `true`, the shape is closed by joining the last point to the first point. + * @param {boolean} [closePath=false] - When `true`, the path is closed before being stroked. + * @param {number} [endIndex] - The index of `points` to stop drawing at. Defaults to `points.length`. * - * @return {Array.<*>} A list of active items. + * @return {this} This Game Object. */ - update: function () + strokePoints: function (points, closeShape, closePath, endIndex) { - if (this._toProcess === 0) + if (closeShape === undefined) { closeShape = false; } + if (closePath === undefined) { closePath = false; } + if (endIndex === undefined) { endIndex = points.length; } + + this.beginPath(); + + this.moveTo(points[0].x, points[0].y); + + for (var i = 1; i < endIndex; i++) { - // Quick bail - return this._active; + this.lineTo(points[i].x, points[i].y); } - var list = this._destroy; - var active = this._active; - var i; - var item; - - // Clear the 'destroy' list - for (i = 0; i < list.length; i++) + if (closeShape) { - item = list[i]; + this.lineTo(points[0].x, points[0].y); + } - // Remove from the 'active' array - var idx = active.indexOf(item); + if (closePath) + { + this.closePath(); + } - if (idx !== -1) - { - active.splice(idx, 1); + this.strokePath(); - this.emit(Events.PROCESS_QUEUE_REMOVE, item); - } - } + return this; + }, - list.length = 0; + /** + * Fill the shape represented by the given array of points. + * + * Pass `closeShape` to automatically close the shape by joining the last to the first point. + * + * Pass `closePath` to automatically close the path before it is filled. + * + * @method Phaser.GameObjects.Graphics#fillPoints + * @since 3.0.0 + * + * @param {(array|Phaser.Geom.Point[])} points - The points to fill. + * @param {boolean} [closeShape=false] - When `true`, the shape is closed by joining the last point to the first point. + * @param {boolean} [closePath=false] - When `true`, the path is closed before being stroked. + * @param {number} [endIndex] - The index of `points` to stop at. Defaults to `points.length`. + * + * @return {this} This Game Object. + */ + fillPoints: function (points, closeShape, closePath, endIndex) + { + if (closeShape === undefined) { closeShape = false; } + if (closePath === undefined) { closePath = false; } + if (endIndex === undefined) { endIndex = points.length; } - // Process the pending addition list - // This stops callbacks and out of sync events from populating the active array mid-way during an update + this.beginPath(); - list = this._pending; + this.moveTo(points[0].x, points[0].y); - for (i = 0; i < list.length; i++) + for (var i = 1; i < endIndex; i++) { - item = list[i]; - - if (!this.checkQueue || (this.checkQueue && active.indexOf(item) === -1)) - { - active.push(item); + this.lineTo(points[i].x, points[i].y); + } - this.emit(Events.PROCESS_QUEUE_ADD, item); - } + if (closeShape) + { + this.lineTo(points[0].x, points[0].y); } - list.length = 0; + if (closePath) + { + this.closePath(); + } - this._toProcess = 0; + this.fillPath(); - // The owner of this queue can now safely do whatever it needs to with the active list - return active; + return this; }, /** - * Returns the current list of active items. - * - * This method returns a reference to the active list array, not a copy of it. - * Therefore, be careful to not modify this array outside of the ProcessQueue. + * Stroke the given ellipse. * - * @method Phaser.Structs.ProcessQueue#getActive + * @method Phaser.GameObjects.Graphics#strokeEllipseShape * @since 3.0.0 * - * @genericUse {T[]} - [$return] + * @param {Phaser.Geom.Ellipse} ellipse - The ellipse to stroke. + * @param {number} [smoothness=32] - The number of points to draw the ellipse with. * - * @return {Array.<*>} A list of active items. + * @return {this} This Game Object. */ - getActive: function () + strokeEllipseShape: function (ellipse, smoothness) { - return this._active; + if (smoothness === undefined) { smoothness = 32; } + + var points = ellipse.getPoints(smoothness); + + return this.strokePoints(points, true); }, /** - * The number of entries in the active list. + * Stroke an ellipse with the given position and size. * - * @name Phaser.Structs.ProcessQueue#length - * @type {number} - * @readonly - * @since 3.20.0 + * @method Phaser.GameObjects.Graphics#strokeEllipse + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the center of the ellipse. + * @param {number} y - The y coordinate of the center of the ellipse. + * @param {number} width - The width of the ellipse. + * @param {number} height - The height of the ellipse. + * @param {number} [smoothness=32] - The number of points to draw the ellipse with. + * + * @return {this} This Game Object. */ - length: { + strokeEllipse: function (x, y, width, height, smoothness) + { + if (smoothness === undefined) { smoothness = 32; } - get: function () - { - return this._active.length; - } + var ellipse = new Ellipse(x, y, width, height); + var points = ellipse.getPoints(smoothness); + + return this.strokePoints(points, true); }, /** - * Immediately destroys this process queue, clearing all of its internal arrays and resetting the process totals. + * Fill the given ellipse. * - * @method Phaser.Structs.ProcessQueue#destroy + * @method Phaser.GameObjects.Graphics#fillEllipseShape * @since 3.0.0 + * + * @param {Phaser.Geom.Ellipse} ellipse - The ellipse to fill. + * @param {number} [smoothness=32] - The number of points to draw the ellipse with. + * + * @return {this} This Game Object. */ - destroy: function () + fillEllipseShape: function (ellipse, smoothness) { - this._toProcess = 0; + if (smoothness === undefined) { smoothness = 32; } - this._pending = []; - this._active = []; - this._destroy = []; - } + var points = ellipse.getPoints(smoothness); -}); + return this.fillPoints(points, true); + }, -module.exports = ProcessQueue; - - -/***/ }), -/* 212 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Read an integer value from an XML Node. - * - * @function getValue - * @since 3.0.0 - * @private - * - * @param {Node} node - The XML Node. - * @param {string} attribute - The attribute to read. - * - * @return {number} The parsed value. - */ -function getValue (node, attribute) -{ - return parseInt(node.getAttribute(attribute), 10); -} - -/** - * Parse an XML font to Bitmap Font data for the Bitmap Font cache. - * - * @function ParseXMLBitmapFont - * @since 3.0.0 - * @private - * - * @param {XMLDocument} xml - The XML Document to parse the font from. - * @param {Phaser.Textures.Frame} frame - The texture frame to take into account when creating the uv data. - * @param {number} [xSpacing=0] - The x-axis spacing to add between each letter. - * @param {number} [ySpacing=0] - The y-axis spacing to add to the line height. - * @param {Phaser.Textures.Texture} [texture] - If provided, each glyph in the Bitmap Font will be added to this texture as a frame. - * - * @return {Phaser.Types.GameObjects.BitmapText.BitmapFontData} The parsed Bitmap Font data. - */ -var ParseXMLBitmapFont = function (xml, frame, xSpacing, ySpacing, texture) -{ - if (xSpacing === undefined) { xSpacing = 0; } - if (ySpacing === undefined) { ySpacing = 0; } - - var textureX = frame.cutX; - var textureY = frame.cutY; - var textureWidth = frame.source.width; - var textureHeight = frame.source.height; - var sourceIndex = frame.sourceIndex; - - var data = {}; - var info = xml.getElementsByTagName('info')[0]; - var common = xml.getElementsByTagName('common')[0]; - - data.font = info.getAttribute('face'); - data.size = getValue(info, 'size'); - data.lineHeight = getValue(common, 'lineHeight') + ySpacing; - data.chars = {}; - - var letters = xml.getElementsByTagName('char'); - - var adjustForTrim = (frame !== undefined && frame.trimmed); - - if (adjustForTrim) - { - var top = frame.height; - var left = frame.width; - } - - for (var i = 0; i < letters.length; i++) + /** + * Fill an ellipse with the given position and size. + * + * @method Phaser.GameObjects.Graphics#fillEllipse + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the center of the ellipse. + * @param {number} y - The y coordinate of the center of the ellipse. + * @param {number} width - The width of the ellipse. + * @param {number} height - The height of the ellipse. + * @param {number} [smoothness=32] - The number of points to draw the ellipse with. + * + * @return {this} This Game Object. + */ + fillEllipse: function (x, y, width, height, smoothness) { - var node = letters[i]; - - var charCode = getValue(node, 'id'); - var letter = String.fromCharCode(charCode); - var gx = getValue(node, 'x'); - var gy = getValue(node, 'y'); - var gw = getValue(node, 'width'); - var gh = getValue(node, 'height'); - - // Handle frame trim issues - - if (adjustForTrim) - { - if (gx < left) - { - left = gx; - } - - if (gy < top) - { - top = gy; - } - } - - if (adjustForTrim && top !== 0 && left !== 0) - { - // Now we know the top and left coordinates of the glyphs in the original data - // so we can work out how much to adjust the glyphs by - - gx -= frame.x; - gy -= frame.y; - } - - var u0 = (textureX + gx) / textureWidth; - var v0 = (textureY + gy) / textureHeight; - var u1 = (textureX + gx + gw) / textureWidth; - var v1 = (textureY + gy + gh) / textureHeight; - - data.chars[charCode] = - { - x: gx, - y: gy, - width: gw, - height: gh, - centerX: Math.floor(gw / 2), - centerY: Math.floor(gh / 2), - xOffset: getValue(node, 'xoffset'), - yOffset: getValue(node, 'yoffset'), - xAdvance: getValue(node, 'xadvance') + xSpacing, - data: {}, - kerning: {}, - u0: u0, - v0: v0, - u1: u1, - v1: v1 - }; + if (smoothness === undefined) { smoothness = 32; } - if (texture && gw !== 0 && gh !== 0) - { - var charFrame = texture.add(letter, sourceIndex, gx, gy, gw, gh); + var ellipse = new Ellipse(x, y, width, height); - if (charFrame) - { - charFrame.setUVs(gw, gh, u0, v0, u1, v1); - } - } - } + var points = ellipse.getPoints(smoothness); - var kernings = xml.getElementsByTagName('kerning'); + return this.fillPoints(points, true); + }, - for (i = 0; i < kernings.length; i++) + /** + * Draw an arc. + * + * This method can be used to create circles, or parts of circles. + * + * Make sure you call `beginPath` before starting the arc unless you wish for the arc to automatically + * close when filled or stroked. + * + * Use the optional `overshoot` argument increase the number of iterations that take place when + * the arc is rendered in WebGL. This is useful if you're drawing an arc with an especially thick line, + * as it will allow the arc to fully join-up. Try small values at first, i.e. 0.01. + * + * Call {@link Phaser.GameObjects.Graphics#fillPath} or {@link Phaser.GameObjects.Graphics#strokePath} after calling + * this method to draw the arc. + * + * @method Phaser.GameObjects.Graphics#arc + * @since 3.0.0 + * + * @param {number} x - The x coordinate of the center of the circle. + * @param {number} y - The y coordinate of the center of the circle. + * @param {number} radius - The radius of the circle. + * @param {number} startAngle - The starting angle, in radians. + * @param {number} endAngle - The ending angle, in radians. + * @param {boolean} [anticlockwise=false] - Whether the drawing should be anticlockwise or clockwise. + * @param {number} [overshoot=0] - This value allows you to increase the segment iterations in WebGL rendering. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly. Use small numbers such as 0.01 to start with and increase as needed. + * + * @return {this} This Game Object. + */ + arc: function (x, y, radius, startAngle, endAngle, anticlockwise, overshoot) { - var kern = kernings[i]; - - var first = getValue(kern, 'first'); - var second = getValue(kern, 'second'); - var amount = getValue(kern, 'amount'); - - data.chars[second].kerning[first] = amount; - } - - return data; -}; - -module.exports = ParseXMLBitmapFont; - + if (anticlockwise === undefined) { anticlockwise = false; } + if (overshoot === undefined) { overshoot = 0; } -/***/ }), -/* 213 */ -/***/ (function(module, exports, __webpack_require__) { + this.commandBuffer.push( + Commands.ARC, + x, y, radius, startAngle, endAngle, anticlockwise, overshoot + ); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var BlitterRender = __webpack_require__(1049); -var Bob = __webpack_require__(440); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var Frame = __webpack_require__(109); -var GameObject = __webpack_require__(15); -var List = __webpack_require__(110); + /** + * Creates a pie-chart slice shape centered at `x`, `y` with the given radius. + * You must define the start and end angle of the slice. + * + * Setting the `anticlockwise` argument to `true` creates a shape similar to Pacman. + * Setting it to `false` creates a shape like a slice of pie. + * + * This method will begin a new path and close the path at the end of it. + * To display the actual slice you need to call either `strokePath` or `fillPath` after it. + * + * @method Phaser.GameObjects.Graphics#slice + * @since 3.4.0 + * + * @param {number} x - The horizontal center of the slice. + * @param {number} y - The vertical center of the slice. + * @param {number} radius - The radius of the slice. + * @param {number} startAngle - The start angle of the slice, given in radians. + * @param {number} endAngle - The end angle of the slice, given in radians. + * @param {boolean} [anticlockwise=false] - Whether the drawing should be anticlockwise or clockwise. + * @param {number} [overshoot=0] - This value allows you to overshoot the endAngle by this amount. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly. + * + * @return {this} This Game Object. + */ + slice: function (x, y, radius, startAngle, endAngle, anticlockwise, overshoot) + { + if (anticlockwise === undefined) { anticlockwise = false; } + if (overshoot === undefined) { overshoot = 0; } -/** - * @callback CreateCallback - * - * @param {Phaser.GameObjects.Bob} bob - The Bob that was created by the Blitter. - * @param {number} index - The position of the Bob within the Blitter display list. - */ + this.commandBuffer.push(Commands.BEGIN_PATH); -/** - * @classdesc - * A Blitter Game Object. - * - * The Blitter Game Object is a special kind of container that creates, updates and manages Bob objects. - * Bobs are designed for rendering speed rather than flexibility. They consist of a texture, or frame from a texture, - * a position and an alpha value. You cannot scale or rotate them. They use a batched drawing method for speed - * during rendering. - * - * A Blitter Game Object has one texture bound to it. Bobs created by the Blitter can use any Frame from this - * Texture to render with, but they cannot use any other Texture. It is this single texture-bind that allows - * them their speed. - * - * If you have a need to blast a large volume of frames around the screen then Blitter objects are well worth - * investigating. They are especially useful for using as a base for your own special effects systems. - * - * @class Blitter - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.Texture - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.Visible - * - * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. It can only belong to one Scene at any given time. - * @param {number} [x=0] - The x coordinate of this Game Object in world space. - * @param {number} [y=0] - The y coordinate of this Game Object in world space. - * @param {string} [texture='__DEFAULT'] - The key of the texture this Game Object will use for rendering. The Texture must already exist in the Texture Manager. - * @param {(string|number)} [frame=0] - The Frame of the Texture that this Game Object will use. Only set if the Texture has multiple frames, such as a Texture Atlas or Sprite Sheet. - */ -var Blitter = new Class({ + this.commandBuffer.push(Commands.MOVE_TO, x, y); - Extends: GameObject, + this.commandBuffer.push(Commands.ARC, x, y, radius, startAngle, endAngle, anticlockwise, overshoot); - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.Depth, - Components.Mask, - Components.Pipeline, - Components.ScrollFactor, - Components.Size, - Components.Texture, - Components.Transform, - Components.Visible, - BlitterRender - ], + this.commandBuffer.push(Commands.CLOSE_PATH); - initialize: + return this; + }, - function Blitter (scene, x, y, texture, frame) + /** + * Saves the state of the Graphics by pushing the current state onto a stack. + * + * The most recently saved state can then be restored with {@link Phaser.GameObjects.Graphics#restore}. + * + * @method Phaser.GameObjects.Graphics#save + * @since 3.0.0 + * + * @return {this} This Game Object. + */ + save: function () { - GameObject.call(this, scene, 'Blitter'); - - this.setTexture(texture, frame); - this.setPosition(x, y); - this.initPipeline(); - - /** - * The children of this Blitter. - * This List contains all of the Bob objects created by the Blitter. - * - * @name Phaser.GameObjects.Blitter#children - * @type {Phaser.Structs.List.} - * @since 3.0.0 - */ - this.children = new List(); - - /** - * A transient array that holds all of the Bobs that will be rendered this frame. - * The array is re-populated whenever the dirty flag is set. - * - * @name Phaser.GameObjects.Blitter#renderList - * @type {Phaser.GameObjects.Bob[]} - * @default [] - * @private - * @since 3.0.0 - */ - this.renderList = []; + this.commandBuffer.push( + Commands.SAVE + ); - /** - * Is the Blitter considered dirty? - * A 'dirty' Blitter has had its child count changed since the last frame. - * - * @name Phaser.GameObjects.Blitter#dirty - * @type {boolean} - * @since 3.0.0 - */ - this.dirty = false; + return this; }, /** - * Creates a new Bob in this Blitter. + * Restores the most recently saved state of the Graphics by popping from the state stack. * - * The Bob is created at the given coordinates, relative to the Blitter and uses the given frame. - * A Bob can use any frame belonging to the texture bound to the Blitter. + * Use {@link Phaser.GameObjects.Graphics#save} to save the current state, and call this afterwards to restore that state. * - * @method Phaser.GameObjects.Blitter#create - * @since 3.0.0 + * If there is no saved state, this command does nothing. * - * @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. - * @param {boolean} [visible=true] - Should the created Bob render or not? - * @param {number} [index] - The position in the Blitters Display List to add the new Bob at. Defaults to the top of the list. + * @method Phaser.GameObjects.Graphics#restore + * @since 3.0.0 * - * @return {Phaser.GameObjects.Bob} The newly created Bob object. + * @return {this} This Game Object. */ - create: function (x, y, frame, visible, index) + restore: function () { - if (visible === undefined) { visible = true; } - if (index === undefined) { index = this.children.length; } - - if (frame === undefined) - { - frame = this.frame; - } - else if (!(frame instanceof Frame)) - { - frame = this.texture.get(frame); - } - - var bob = new Bob(this, x, y, frame, visible); - - this.children.addAt(bob, index, false); - - this.dirty = true; + this.commandBuffer.push( + Commands.RESTORE + ); - return bob; + return this; }, /** - * Creates multiple Bob objects within this Blitter and then passes each of them to the specified callback. + * Inserts a translation command into this Graphics objects command buffer. * - * @method Phaser.GameObjects.Blitter#createFromCallback + * All objects drawn _after_ calling this method will be translated + * by the given amount. + * + * This does not change the position of the Graphics object itself, + * only of the objects drawn by it after calling this method. + * + * @method Phaser.GameObjects.Graphics#translateCanvas * @since 3.0.0 * - * @param {CreateCallback} callback - The callback to invoke after creating a bob. It will be sent two arguments: The Bob and the index of the Bob. - * @param {number} quantity - The quantity of Bob objects to create. - * @param {(string|number|Phaser.Textures.Frame|string[]|number[]|Phaser.Textures.Frame[])} [frame] - The Frame the Bobs will use. It must be part of the Blitter Texture. - * @param {boolean} [visible=true] - Should the created Bob render or not? + * @param {number} x - The horizontal translation to apply. + * @param {number} y - The vertical translation to apply. * - * @return {Phaser.GameObjects.Bob[]} An array of Bob objects that were created. + * @return {this} This Game Object. */ - createFromCallback: function (callback, quantity, frame, visible) + translateCanvas: function (x, y) { - var bobs = this.createMultiple(quantity, frame, visible); - - for (var i = 0; i < bobs.length; i++) - { - var bob = bobs[i]; - - callback.call(this, bob, i); - } + this.commandBuffer.push( + Commands.TRANSLATE, + x, y + ); - return bobs; + return this; }, /** - * Creates multiple Bobs in one call. + * Inserts a scale command into this Graphics objects command buffer. * - * The amount created is controlled by a combination of the `quantity` argument and the number of frames provided. + * All objects drawn _after_ calling this method will be scaled + * by the given amount. * - * If the quantity is set to 10 and you provide 2 frames, then 20 Bobs will be created. 10 with the first - * frame and 10 with the second. + * This does not change the scale of the Graphics object itself, + * only of the objects drawn by it after calling this method. * - * @method Phaser.GameObjects.Blitter#createMultiple + * @method Phaser.GameObjects.Graphics#scaleCanvas * @since 3.0.0 * - * @param {number} quantity - The quantity of Bob objects to create. - * @param {(string|number|Phaser.Textures.Frame|string[]|number[]|Phaser.Textures.Frame[])} [frame] - The Frame the Bobs will use. It must be part of the Blitter Texture. - * @param {boolean} [visible=true] - Should the created Bob render or not? + * @param {number} x - The horizontal scale to apply. + * @param {number} y - The vertical scale to apply. * - * @return {Phaser.GameObjects.Bob[]} An array of Bob objects that were created. + * @return {this} This Game Object. */ - createMultiple: function (quantity, frame, visible) + scaleCanvas: function (x, y) { - if (frame === undefined) { frame = this.frame.name; } - if (visible === undefined) { visible = true; } - - if (!Array.isArray(frame)) - { - frame = [ frame ]; - } - - var bobs = []; - var _this = this; - - frame.forEach(function (singleFrame) - { - for (var i = 0; i < quantity; i++) - { - bobs.push(_this.create(0, 0, singleFrame, visible)); - } - }); + this.commandBuffer.push( + Commands.SCALE, + x, y + ); - return bobs; + return this; }, /** - * Checks if the given child can render or not, by checking its `visible` and `alpha` values. + * Inserts a rotation command into this Graphics objects command buffer. * - * @method Phaser.GameObjects.Blitter#childCanRender + * All objects drawn _after_ calling this method will be rotated + * by the given amount. + * + * This does not change the rotation of the Graphics object itself, + * only of the objects drawn by it after calling this method. + * + * @method Phaser.GameObjects.Graphics#rotateCanvas * @since 3.0.0 * - * @param {Phaser.GameObjects.Bob} child - The Bob to check for rendering. + * @param {number} radians - The rotation angle, in radians. * - * @return {boolean} Returns `true` if the given child can render, otherwise `false`. + * @return {this} This Game Object. */ - childCanRender: function (child) + rotateCanvas: function (radians) { - return (child.visible && child.alpha > 0); + this.commandBuffer.push( + Commands.ROTATE, + radians + ); + + return this; }, /** - * Returns an array of Bobs to be rendered. - * If the Blitter is dirty then a new list is generated and stored in `renderList`. + * Clear the command buffer and reset the fill style and line style to their defaults. * - * @method Phaser.GameObjects.Blitter#getRenderList + * @method Phaser.GameObjects.Graphics#clear * @since 3.0.0 * - * @return {Phaser.GameObjects.Bob[]} An array of Bob objects that will be rendered this frame. + * @return {this} This Game Object. */ - getRenderList: function () + clear: function () { - if (this.dirty) + this.commandBuffer.length = 0; + + if (this.defaultFillColor > -1) { - this.renderList = this.children.list.filter(this.childCanRender, this); - this.dirty = false; + this.fillStyle(this.defaultFillColor, this.defaultFillAlpha); } - return this.renderList; + if (this.defaultStrokeColor > -1) + { + this.lineStyle(this.defaultStrokeWidth, this.defaultStrokeColor, this.defaultStrokeAlpha); + } + + return this; }, /** - * Removes all Bobs from the children List and clears the dirty flag. + * Generate a texture from this Graphics object. * - * @method Phaser.GameObjects.Blitter#clear + * If `key` is a string it'll generate a new texture using it and add it into the + * Texture Manager (assuming no key conflict happens). + * + * If `key` is a Canvas it will draw the texture to that canvas context. Note that it will NOT + * automatically upload it to the GPU in WebGL mode. + * + * Please understand that the texture is created via the Canvas API of the browser, therefore some + * Graphics features, such as `fillGradientStyle`, will not appear on the resulting texture, + * as they're unsupported by the Canvas API. + * + * @method Phaser.GameObjects.Graphics#generateTexture * @since 3.0.0 + * + * @param {(string|HTMLCanvasElement)} key - The key to store the texture with in the Texture Manager, or a Canvas to draw to. + * @param {number} [width] - The width of the graphics to generate. + * @param {number} [height] - The height of the graphics to generate. + * + * @return {this} This Game Object. */ - clear: function () + generateTexture: function (key, width, height) { - this.children.removeAll(); - this.dirty = true; + var sys = this.scene.sys; + var renderer = sys.game.renderer; + + if (width === undefined) { width = sys.scale.width; } + if (height === undefined) { height = sys.scale.height; } + + Graphics.TargetCamera.setScene(this.scene); + Graphics.TargetCamera.setViewport(0, 0, width, height); + Graphics.TargetCamera.scrollX = this.x; + Graphics.TargetCamera.scrollY = this.y; + + var texture; + var ctx; + var willRead = { willReadFrequently: true }; + + if (typeof key === 'string') + { + if (sys.textures.exists(key)) + { + // Key is a string, it DOES exist in the Texture Manager AND is a canvas, so draw to it + + texture = sys.textures.get(key); + + var src = texture.getSourceImage(); + + if (src instanceof HTMLCanvasElement) + { + ctx = src.getContext('2d', willRead); + } + } + else + { + // Key is a string and doesn't exist in the Texture Manager, so generate and save it + + texture = sys.textures.createCanvas(key, width, height); + + ctx = texture.getSourceImage().getContext('2d', willRead); + } + } + else if (key instanceof HTMLCanvasElement) + { + // Key is a Canvas, so draw to it + + ctx = key.getContext('2d', willRead); + } + + if (ctx) + { + // var GraphicsCanvasRenderer = function (renderer, src, camera, parentMatrix, renderTargetCtx, allowClip) + this.renderCanvas(renderer, this, Graphics.TargetCamera, null, ctx, false); + + if (texture) + { + texture.refresh(); + } + } + + return this; }, /** * Internal destroy handler, called as part of the destroy process. * - * @method Phaser.GameObjects.Blitter#preDestroy + * @method Phaser.GameObjects.Graphics#preDestroy * @protected * @since 3.9.0 */ preDestroy: function () { - this.children.destroy(); - - this.renderList = []; + this.commandBuffer = []; } }); -module.exports = Blitter; +/** + * A Camera used specifically by the Graphics system for rendering to textures. + * + * @name Phaser.GameObjects.Graphics.TargetCamera + * @type {Phaser.Cameras.Scene2D.Camera} + * @since 3.1.0 + */ +Graphics.TargetCamera = new BaseCamera(); + +module.exports = Graphics; /***/ }), -/* 214 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 91543: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayUtils = __webpack_require__(208); -var BlendModes = __webpack_require__(35); -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__(1052); -var Union = __webpack_require__(441); -var Vector2 = __webpack_require__(3); +var Commands = __webpack_require__(36266); +var SetTransform = __webpack_require__(49584); /** - * @classdesc - * A Container Game Object. - * - * A Container, as the name implies, can 'contain' other types of Game Object. - * When a Game Object is added to a Container, the Container becomes responsible for the rendering of it. - * By default it will be removed from the Display List and instead added to the Containers own internal list. - * - * The position of the Game Object automatically becomes relative to the position of the Container. - * - * The transform point of a Container is 0x0 (in local space) and that cannot be changed. The children you add to the - * Container should be positioned with this value in mind. I.e. you should treat 0x0 as being the center of - * the Container, and position children positively and negative around it as required. - * - * When the Container is rendered, all of its children are rendered as well, in the order in which they exist - * within the Container. Container children can be repositioned using methods such as `MoveUp`, `MoveDown` and `SendToBack`. - * - * If you modify a transform property of the Container, such as `Container.x` or `Container.rotation` then it will - * automatically influence all children as well. - * - * Containers can include other Containers for deeply nested transforms. - * - * Containers can have masks set on them and can be used as a mask too. However, Container children cannot be masked. - * The masks do not 'stack up'. Only a Container on the root of the display list will use its mask. - * - * Containers can be enabled for input. Because they do not have a texture you need to provide a shape for them - * to use as their hit area. Container children can also be enabled for input, independent of the Container. - * - * If input enabling a _child_ you should not set both the `origin` and a **negative** scale factor on the child, - * or the input area will become misaligned. - * - * Containers can be given a physics body for either Arcade Physics, Impact Physics or Matter Physics. However, - * if Container _children_ are enabled for physics you may get unexpected results, such as offset bodies, - * if the Container itself, or any of its ancestors, is positioned anywhere other than at 0 x 0. Container children - * with physics do not factor in the Container due to the excessive extra calculations needed. Please structure - * your game to work around this. - * - * It's important to understand the impact of using Containers. They add additional processing overhead into - * every one of their children. The deeper you nest them, the more the cost escalates. This is especially true - * for input events. You also loose the ability to set the display depth of Container children in the same - * flexible manner as those not within them. In short, don't use them for the sake of it. You pay a small cost - * every time you create one, try to structure your game around avoiding that where possible. - * - * @class Container - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.4.0 + * 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. * - * @extends Phaser.GameObjects.Components.AlphaSingle - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.ComputedSize - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.Visible + * @method Phaser.GameObjects.Graphics#renderCanvas + * @since 3.0.0 + * @private * - * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. - * @param {number} [x=0] - The horizontal position of this Game Object in the world. - * @param {number} [y=0] - The vertical position of this Game Object in the world. - * @param {Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Container. + * @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 Container = new Class({ +var GraphicsCanvasRenderer = function (renderer, src, camera, parentMatrix, renderTargetCtx, allowClip) +{ + var commandBuffer = src.commandBuffer; + var commandBufferLength = commandBuffer.length; - Extends: GameObject, + var ctx = renderTargetCtx || renderer.currentContext; - Mixins: [ - Components.AlphaSingle, - Components.BlendMode, - Components.ComputedSize, - Components.Depth, - Components.Mask, - Components.Pipeline, - Components.Transform, - Components.Visible, - Render - ], + if (commandBufferLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + return; + } - initialize: + camera.addToRenderList(src); - function Container (scene, x, y, children) - { - GameObject.call(this, scene, 'Container'); + var lineAlpha = 1; + var fillAlpha = 1; + var lineColor = 0; + var fillColor = 0; + var lineWidth = 1; + var red = 0; + var green = 0; + var blue = 0; - /** - * An array holding the children of this Container. - * - * @name Phaser.GameObjects.Container#list - * @type {Phaser.GameObjects.GameObject[]} - * @since 3.4.0 - */ - this.list = []; + // Reset any currently active paths + ctx.beginPath(); - /** - * Does this Container exclusively manage its children? - * - * The default is `true` which means a child added to this Container cannot - * belong in another Container, which includes the Scene display list. - * - * If you disable this then this Container will no longer exclusively manage its children. - * This allows you to create all kinds of interesting graphical effects, such as replicating - * Game Objects without reparenting them all over the Scene. - * However, doing so will prevent children from receiving any kind of input event or have - * their physics bodies work by default, as they're no longer a single entity on the - * display list, but are being replicated where-ever this Container is. - * - * @name Phaser.GameObjects.Container#exclusive - * @type {boolean} - * @default true - * @since 3.4.0 - */ - this.exclusive = true; + for (var index = 0; index < commandBufferLength; ++index) + { + var commandID = commandBuffer[index]; - /** - * Containers can have an optional maximum size. If set to anything above 0 it - * will constrict the addition of new Game Objects into the Container, capping off - * the maximum limit the Container can grow in size to. - * - * @name Phaser.GameObjects.Container#maxSize - * @type {number} - * @default -1 - * @since 3.4.0 - */ - this.maxSize = -1; + 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] + ); - /** - * The cursor position. - * - * @name Phaser.GameObjects.Container#position - * @type {number} - * @since 3.4.0 - */ - this.position = 0; + // +7 because overshoot is the 7th value, not used in Canvas + index += 7; + break; - /** - * Internal Transform Matrix used for local space conversion. - * - * @name Phaser.GameObjects.Container#localTransform - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.4.0 - */ - this.localTransform = new Components.TransformMatrix(); + 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; - /** - * Internal temporary Transform Matrix used to avoid object creation. - * - * @name Phaser.GameObjects.Container#tempTransformMatrix - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.4.0 - */ - this.tempTransformMatrix = new Components.TransformMatrix(); + 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; - /** - * The property key to sort by. - * - * @name Phaser.GameObjects.Container#_sortKey - * @type {string} - * @private - * @since 3.4.0 - */ - this._sortKey = ''; + case Commands.BEGIN_PATH: + ctx.beginPath(); + break; - /** - * A reference to the Scene Systems Event Emitter. - * - * @name Phaser.GameObjects.Container#_sysEvents - * @type {Phaser.Events.EventEmitter} - * @private - * @since 3.9.0 - */ - this._sysEvents = scene.sys.events; + case Commands.CLOSE_PATH: + ctx.closePath(); + break; - /** - * The horizontal scroll factor of this Container. - * - * The scroll factor controls the influence of the movement of a Camera upon this Container. - * - * When a camera scrolls it will change the location at which this Container is rendered on-screen. - * It does not change the Containers actual position values. - * - * For a Container, setting this value will only update the Container itself, not its children. - * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Container. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * - * @name Phaser.GameObjects.Container#scrollFactorX - * @type {number} - * @default 1 - * @since 3.4.0 - */ - this.scrollFactorX = 1; + case Commands.FILL_PATH: + if (!allowClip) + { + ctx.fill(); + } + break; - /** - * The vertical scroll factor of this Container. - * - * The scroll factor controls the influence of the movement of a Camera upon this Container. - * - * When a camera scrolls it will change the location at which this Container is rendered on-screen. - * It does not change the Containers actual position values. - * - * For a Container, setting this value will only update the Container itself, not its children. - * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Container. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * - * @name Phaser.GameObjects.Container#scrollFactorY - * @type {number} - * @default 1 - * @since 3.4.0 - */ - this.scrollFactorY = 1; + case Commands.STROKE_PATH: + if (!allowClip) + { + ctx.stroke(); + } + break; - this.initPipeline(); + 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; - this.setPosition(x, y); + 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; - this.clearAlpha(); + 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; - this.setBlendMode(BlendModes.SKIP_CHECK); + case Commands.LINE_TO: + ctx.lineTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; - if (children) - { - this.add(children); - } - }, + case Commands.MOVE_TO: + ctx.moveTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 2; + break; - /** - * Internal value to allow Containers to be used for input and physics. - * Do not change this value. It has no effect other than to break things. - * - * @name Phaser.GameObjects.Container#originX - * @type {number} - * @readonly - * @override - * @since 3.4.0 - */ - originX: { + case Commands.LINE_FX_TO: + ctx.lineTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 5; + break; - get: function () - { - return 0.5; - } + case Commands.MOVE_FX_TO: + ctx.moveTo( + commandBuffer[index + 1], + commandBuffer[index + 2] + ); + index += 5; + break; - }, + case Commands.SAVE: + ctx.save(); + break; - /** - * Internal value to allow Containers to be used for input and physics. - * Do not change this value. It has no effect other than to break things. - * - * @name Phaser.GameObjects.Container#originY - * @type {number} - * @readonly - * @override - * @since 3.4.0 - */ - originY: { + case Commands.RESTORE: + ctx.restore(); + break; - get: function () - { - return 0.5; - } + 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; - /** - * Internal value to allow Containers to be used for input and physics. - * Do not change this value. It has no effect other than to break things. - * - * @name Phaser.GameObjects.Container#displayOriginX - * @type {number} - * @readonly - * @override - * @since 3.4.0 - */ - displayOriginX: { + case Commands.ROTATE: + ctx.rotate( + commandBuffer[index + 1] + ); + index += 1; + break; - get: function () - { - return this.width * 0.5; + case Commands.GRADIENT_FILL_STYLE: + index += 5; + break; + + case Commands.GRADIENT_LINE_STYLE: + index += 6; + break; } + } - }, + // Restore the context saved in SetTransform + ctx.restore(); +}; - /** - * Internal value to allow Containers to be used for input and physics. - * Do not change this value. It has no effect other than to break things. - * - * @name Phaser.GameObjects.Container#displayOriginY - * @type {number} - * @readonly - * @override - * @since 3.4.0 - */ - displayOriginY: { +module.exports = GraphicsCanvasRenderer; - get: function () - { - return this.height * 0.5; - } - }, +/***/ }), - /** - * Does this Container exclusively manage its children? - * - * The default is `true` which means a child added to this Container cannot - * belong in another Container, which includes the Scene display list. - * - * If you disable this then this Container will no longer exclusively manage its children. - * This allows you to create all kinds of interesting graphical effects, such as replicating - * Game Objects without reparenting them all over the Scene. - * However, doing so will prevent children from receiving any kind of input event or have - * their physics bodies work by default, as they're no longer a single entity on the - * display list, but are being replicated where-ever this Container is. - * - * @method Phaser.GameObjects.Container#setExclusive - * @since 3.4.0 - * - * @param {boolean} [value=true] - The exclusive state of this Container. - * - * @return {this} This Container. - */ - setExclusive: function (value) +/***/ 41286: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GameObjectCreator = __webpack_require__(99325); +var Graphics = __webpack_require__(33182); + +/** + * Creates a new Graphics Game Object and returns it. + * + * Note: This method will only be available if the Graphics Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#graphics + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Graphics.Options} [config] - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Graphics} The Game Object that was created. + */ +GameObjectCreator.register('graphics', function (config, addToScene) +{ + if (config === undefined) { config = {}; } + + if (addToScene !== undefined) { - if (value === undefined) { value = true; } + config.add = addToScene; + } - this.exclusive = value; + var graphics = new Graphics(this.scene, config); - return this; - }, + if (config.add) + { + this.scene.sys.displayList.add(graphics); + } - /** - * Gets the bounds of this Container. It works by iterating all children of the Container, - * getting their respective bounds, and then working out a min-max rectangle from that. - * It does not factor in if the children render or not, all are included. - * - * Some children are unable to return their bounds, such as Graphics objects, in which case - * they are skipped. - * - * Depending on the quantity of children in this Container it could be a really expensive call, - * so cache it and only poll it as needed. - * - * The values are stored and returned in a Rectangle object. - * - * @method Phaser.GameObjects.Container#getBounds - * @since 3.4.0 - * - * @param {Phaser.Geom.Rectangle} [output] - A Geom.Rectangle object to store the values in. If not provided a new Rectangle will be created. - * - * @return {Phaser.Geom.Rectangle} The values stored in the output object. - */ - getBounds: function (output) + return graphics; +}); + +// When registering a factory function 'this' refers to the GameObjectCreator context. + + +/***/ }), + +/***/ 13122: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Graphics = __webpack_require__(33182); +var GameObjectFactory = __webpack_require__(61286); + +/** + * Creates a new Graphics Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Graphics Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#graphics + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Graphics.Options} [config] - The Graphics configuration. + * + * @return {Phaser.GameObjects.Graphics} The Game Object that was created. + */ +GameObjectFactory.register('graphics', function (config) +{ + return this.displayList.add(new Graphics(this.scene, config)); +}); + +// When registering a factory function 'this' refers to the GameObjectFactory 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 + + +/***/ }), + +/***/ 60898: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(34429); + + // Needed for Graphics.generateTexture + renderCanvas = __webpack_require__(91543); +} + +if (true) +{ + renderCanvas = __webpack_require__(91543); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 34429: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Commands = __webpack_require__(36266); +var GetCalcMatrix = __webpack_require__(73329); +var TransformMatrix = __webpack_require__(69360); +var Utils = __webpack_require__(75512); + +var Point = function (x, y, width) +{ + this.x = x; + this.y = y; + this.width = width; +}; + +var Path = function (x, y, width) +{ + this.points = []; + this.pointsLength = 1; + this.points[0] = new Point(x, y, width); +}; + +var matrixStack = []; +var tempMatrix = 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.Graphics#renderWebGL + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL 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 + */ +var GraphicsWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + if (src.commandBuffer.length === 0) { - if (output === undefined) { output = new Rectangle(); } + return; + } - output.setTo(this.x, this.y, 0, 0); + camera.addToRenderList(src); - if (this.parentContainer) - { - var parentMatrix = this.parentContainer.getBoundsTransformMatrix(); - var transformedPosition = parentMatrix.transformPoint(this.x, this.y); + var pipeline = renderer.pipelines.set(src.pipeline, src); - output.setTo(transformedPosition.x, transformedPosition.y, 0, 0); - } + renderer.pipelines.preBatch(src); - if (this.list.length > 0) + var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; + + var currentMatrix = tempMatrix.loadIdentity(); + + var commands = src.commandBuffer; + var alpha = camera.alpha * src.alpha; + + var lineWidth = 1; + var fillTint = pipeline.fillTint; + var strokeTint = pipeline.strokeTint; + + var tx = 0; + var ty = 0; + var ta = 0; + var iterStep = 0.01; + var PI2 = Math.PI * 2; + + var cmd; + + var path = []; + var pathIndex = 0; + var pathOpen = true; + var lastPath = null; + + var getTint = Utils.getTintAppendFloatAlpha; + + for (var cmdIndex = 0; cmdIndex < commands.length; cmdIndex++) + { + cmd = commands[cmdIndex]; + + switch (cmd) { - var children = this.list; - var tempRect = new Rectangle(); - var hasSetFirst = false; + case Commands.BEGIN_PATH: + { + path.length = 0; + lastPath = null; + pathOpen = true; + break; + } - output.setEmpty(); + case Commands.CLOSE_PATH: + { + pathOpen = false; - for (var i = 0; i < children.length; i++) + if (lastPath && lastPath.points.length) + { + lastPath.points.push(lastPath.points[0]); + } + break; + } + + case Commands.FILL_PATH: { - var entry = children[i]; + for (pathIndex = 0; pathIndex < path.length; pathIndex++) + { + pipeline.batchFillPath( + path[pathIndex].points, + currentMatrix, + calcMatrix + ); + } + break; + } - if (entry.getBounds) + case Commands.STROKE_PATH: + { + for (pathIndex = 0; pathIndex < path.length; pathIndex++) { - entry.getBounds(tempRect); + pipeline.batchStrokePath( + path[pathIndex].points, + lineWidth, + pathOpen, + currentMatrix, + calcMatrix + ); + } + break; + } - if (!hasSetFirst) + case Commands.LINE_STYLE: + { + lineWidth = commands[++cmdIndex]; + var strokeColor = commands[++cmdIndex]; + var strokeAlpha = commands[++cmdIndex] * alpha; + var strokeTintColor = getTint(strokeColor, strokeAlpha); + strokeTint.TL = strokeTintColor; + strokeTint.TR = strokeTintColor; + strokeTint.BL = strokeTintColor; + strokeTint.BR = strokeTintColor; + break; + } + + case Commands.FILL_STYLE: + { + var fillColor = commands[++cmdIndex]; + var fillAlpha = commands[++cmdIndex] * alpha; + var fillTintColor = getTint(fillColor, fillAlpha); + fillTint.TL = fillTintColor; + fillTint.TR = fillTintColor; + fillTint.BL = fillTintColor; + fillTint.BR = fillTintColor; + break; + } + + case Commands.GRADIENT_FILL_STYLE: + { + var alphaTL = commands[++cmdIndex] * alpha; + var alphaTR = commands[++cmdIndex] * alpha; + var alphaBL = commands[++cmdIndex] * alpha; + var alphaBR = commands[++cmdIndex] * alpha; + + fillTint.TL = getTint(commands[++cmdIndex], alphaTL); + fillTint.TR = getTint(commands[++cmdIndex], alphaTR); + fillTint.BL = getTint(commands[++cmdIndex], alphaBL); + fillTint.BR = getTint(commands[++cmdIndex], alphaBR); + break; + } + + case Commands.GRADIENT_LINE_STYLE: + { + lineWidth = commands[++cmdIndex]; + var gradientLineAlpha = commands[++cmdIndex] * alpha; + strokeTint.TL = getTint(commands[++cmdIndex], gradientLineAlpha); + strokeTint.TR = getTint(commands[++cmdIndex], gradientLineAlpha); + strokeTint.BL = getTint(commands[++cmdIndex], gradientLineAlpha); + strokeTint.BR = getTint(commands[++cmdIndex], gradientLineAlpha); + break; + } + + case Commands.ARC: + { + var iteration = 0; + var x = commands[++cmdIndex]; + var y = commands[++cmdIndex]; + var radius = commands[++cmdIndex]; + var startAngle = commands[++cmdIndex]; + var endAngle = commands[++cmdIndex]; + var anticlockwise = commands[++cmdIndex]; + var overshoot = commands[++cmdIndex]; + + endAngle -= startAngle; + + if (anticlockwise) + { + if (endAngle < -PI2) { - output.setTo(tempRect.x, tempRect.y, tempRect.width, tempRect.height); - hasSetFirst = true; + endAngle = -PI2; } - else + else if (endAngle > 0) { - Union(tempRect, output, output); + endAngle = -PI2 + endAngle % PI2; } } + else if (endAngle > PI2) + { + endAngle = PI2; + } + else if (endAngle < 0) + { + endAngle = PI2 + endAngle % PI2; + } + + if (lastPath === null) + { + lastPath = new Path(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius, lineWidth); + path.push(lastPath); + iteration += iterStep; + } + + while (iteration < 1 + overshoot) + { + ta = endAngle * iteration + startAngle; + tx = x + Math.cos(ta) * radius; + ty = y + Math.sin(ta) * radius; + + lastPath.points.push(new Point(tx, ty, lineWidth)); + + iteration += iterStep; + } + + ta = endAngle + startAngle; + tx = x + Math.cos(ta) * radius; + ty = y + Math.sin(ta) * radius; + + lastPath.points.push(new Point(tx, ty, lineWidth)); + + break; } - } - return output; - }, + case Commands.FILL_RECT: + { + pipeline.batchFillRect( + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + currentMatrix, + calcMatrix + ); + break; + } - /** - * Internal add handler. - * - * @method Phaser.GameObjects.Container#addHandler - * @private - * @since 3.4.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to this Container. - */ - addHandler: function (gameObject) - { - gameObject.once(Events.DESTROY, this.remove, this); + case Commands.FILL_TRIANGLE: + { + pipeline.batchFillTriangle( + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + currentMatrix, + calcMatrix + ); + break; + } - if (this.exclusive) - { - if (gameObject.parentContainer) + case Commands.STROKE_TRIANGLE: { - gameObject.parentContainer.remove(gameObject); + pipeline.batchStrokeTriangle( + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + commands[++cmdIndex], + lineWidth, + currentMatrix, + calcMatrix + ); + break; } - gameObject.removeFromDisplayList(); + case Commands.LINE_TO: + { + if (lastPath !== null) + { + lastPath.points.push(new Point(commands[++cmdIndex], commands[++cmdIndex], lineWidth)); + } + else + { + lastPath = new Path(commands[++cmdIndex], commands[++cmdIndex], lineWidth); + path.push(lastPath); + } + break; + } - gameObject.parentContainer = this; - } - }, + case Commands.MOVE_TO: + { + lastPath = new Path(commands[++cmdIndex], commands[++cmdIndex], lineWidth); + path.push(lastPath); + break; + } - /** - * Internal remove handler. - * - * @method Phaser.GameObjects.Container#removeHandler - * @private - * @since 3.4.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just removed from this Container. - */ - removeHandler: function (gameObject) - { - gameObject.off(Events.DESTROY, this.remove); + case Commands.SAVE: + { + matrixStack.push(currentMatrix.copyToArray()); + break; + } - if (this.exclusive) - { - gameObject.parentContainer = null; + case Commands.RESTORE: + { + currentMatrix.copyFromArray(matrixStack.pop()); + break; + } - gameObject.addToDisplayList(); + case Commands.TRANSLATE: + { + x = commands[++cmdIndex]; + y = commands[++cmdIndex]; + currentMatrix.translate(x, y); + break; + } + + case Commands.SCALE: + { + x = commands[++cmdIndex]; + y = commands[++cmdIndex]; + currentMatrix.scale(x, y); + break; + } + + case Commands.ROTATE: + { + currentMatrix.rotate(commands[++cmdIndex]); + break; + } } - }, + } - /** - * Takes a Point-like object, such as a Vector2, Geom.Point or object with public x and y properties, - * and transforms it into the space of this Container, then returns it in the output object. - * - * @method Phaser.GameObjects.Container#pointToContainer - * @since 3.4.0 - * - * @param {(object|Phaser.Geom.Point|Phaser.Math.Vector2)} source - The Source Point to be transformed. - * @param {(object|Phaser.Geom.Point|Phaser.Math.Vector2)} [output] - A destination object to store the transformed point in. If none given a Vector2 will be created and returned. - * - * @return {(object|Phaser.Geom.Point|Phaser.Math.Vector2)} The transformed point. - */ - pointToContainer: function (source, output) + renderer.pipelines.postBatch(src); +}; + +module.exports = GraphicsWebGLRenderer; + + +/***/ }), + +/***/ 59192: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Actions = __webpack_require__(83979); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(56631); +var EventEmitter = __webpack_require__(6659); +var GetAll = __webpack_require__(71608); +var GetFastValue = __webpack_require__(72632); +var GetValue = __webpack_require__(10850); +var HasValue = __webpack_require__(19256); +var IsPlainObject = __webpack_require__(42911); +var Range = __webpack_require__(75757); +var Set = __webpack_require__(58403); +var Sprite = __webpack_require__(13747); + +/** + * @classdesc + * A Group is a way for you to create, manipulate, or recycle similar Game Objects. + * + * Group membership is non-exclusive. A Game Object can belong to several groups, one group, or none. + * + * Groups themselves aren't displayable, and can't be positioned, rotated, scaled, or hidden. + * + * @class Group + * @memberof Phaser.GameObjects + * @extends Phaser.Events.EventEmitter + * @constructor + * @since 3.0.0 + * @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. If `key` is set, Phaser.GameObjects.Group#createMultiple is also called with these settings. + * + * @see Phaser.Physics.Arcade.Group + * @see Phaser.Physics.Arcade.StaticGroup + */ +var Group = new Class({ + + Extends: EventEmitter, + + initialize: + + function Group (scene, children, config) { - if (output === undefined) { output = new Vector2(); } + EventEmitter.call(this); - if (this.parentContainer) + // They can pass in any of the following as the first argument: + + // 1) A single child + // 2) An array of children + // 3) A config object + // 4) An array of config objects + + // Or they can pass in a child, or array of children AND a config object + + if (config) { - this.parentContainer.pointToContainer(source, output); + // config has been set, are the children an array? + + if (children && !Array.isArray(children)) + { + children = [ children ]; + } } - else + else if (Array.isArray(children)) + { + // No config, so let's check the children argument + + if (IsPlainObject(children[0])) + { + // It's an array of plain config objects + config = children; + children = null; + } + } + else if (IsPlainObject(children)) { - output = new Vector2(source.x, source.y); + // Children isn't an array. Is it a config object though? + config = children; + children = null; } - var tempMatrix = this.tempTransformMatrix; + /** + * This scene this group belongs to. + * + * @name Phaser.GameObjects.Group#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - // No need to loadIdentity because applyITRS overwrites every value anyway - tempMatrix.applyITRS(this.x, this.y, this.rotation, this.scaleX, this.scaleY); + /** + * Members of this group. + * + * @name Phaser.GameObjects.Group#children + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.children = new Set(); - tempMatrix.invert(); + /** + * A flag identifying this object as a group. + * + * @name Phaser.GameObjects.Group#isParent + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.isParent = true; - tempMatrix.transformPoint(source.x, source.y, output); + /** + * A textual representation of this Game Object. + * Used internally by Phaser but is available for your own custom classes to populate. + * + * @name Phaser.GameObjects.Group#type + * @type {string} + * @default 'Group' + * @since 3.21.0 + */ + this.type = 'Group'; - return output; + /** + * The class to create new group members from. + * + * @name Phaser.GameObjects.Group#classType + * @type {function} + * @since 3.0.0 + * @default Phaser.GameObjects.Sprite + * @see Phaser.Types.GameObjects.Group.GroupClassTypeConstructor + */ + this.classType = GetFastValue(config, 'classType', Sprite); + + /** + * The name of this group. + * Empty by default and never populated by Phaser, this is left for developers to use. + * + * @name Phaser.GameObjects.Group#name + * @type {string} + * @default '' + * @since 3.18.0 + */ + this.name = GetFastValue(config, 'name', ''); + + /** + * Whether this group runs its {@link Phaser.GameObjects.Group#preUpdate} method (which may update any members). + * + * @name Phaser.GameObjects.Group#active + * @type {boolean} + * @since 3.0.0 + */ + this.active = GetFastValue(config, 'active', true); + + /** + * The maximum size of this group, if used as a pool. -1 is no limit. + * + * @name Phaser.GameObjects.Group#maxSize + * @type {number} + * @since 3.0.0 + * @default -1 + */ + this.maxSize = GetFastValue(config, 'maxSize', -1); + + /** + * A default texture key to use when creating new group members. + * + * This is used in {@link Phaser.GameObjects.Group#create} + * but not in {@link Phaser.GameObjects.Group#createMultiple}. + * + * @name Phaser.GameObjects.Group#defaultKey + * @type {string} + * @since 3.0.0 + */ + this.defaultKey = GetFastValue(config, 'defaultKey', null); + + /** + * A default texture frame to use when creating new group members. + * + * @name Phaser.GameObjects.Group#defaultFrame + * @type {(string|number)} + * @since 3.0.0 + */ + this.defaultFrame = GetFastValue(config, 'defaultFrame', null); + + /** + * Whether to call the update method of any members. + * + * @name Phaser.GameObjects.Group#runChildUpdate + * @type {boolean} + * @default false + * @since 3.0.0 + * @see Phaser.GameObjects.Group#preUpdate + */ + this.runChildUpdate = GetFastValue(config, 'runChildUpdate', false); + + /** + * A function to be called when adding or creating group members. + * + * @name Phaser.GameObjects.Group#createCallback + * @type {?Phaser.Types.GameObjects.Group.GroupCallback} + * @since 3.0.0 + */ + this.createCallback = GetFastValue(config, 'createCallback', null); + + /** + * A function to be called when removing group members. + * + * @name Phaser.GameObjects.Group#removeCallback + * @type {?Phaser.Types.GameObjects.Group.GroupCallback} + * @since 3.0.0 + */ + this.removeCallback = GetFastValue(config, 'removeCallback', null); + + /** + * A function to be called when creating several group members at once. + * + * @name Phaser.GameObjects.Group#createMultipleCallback + * @type {?Phaser.Types.GameObjects.Group.GroupMultipleCreateCallback} + * @since 3.0.0 + */ + this.createMultipleCallback = GetFastValue(config, 'createMultipleCallback', null); + + /** + * A function to be called when adding or creating group members. + * For internal use only by a Group, or any class that extends it. + * + * @name Phaser.GameObjects.Group#internalCreateCallback + * @type {?Phaser.Types.GameObjects.Group.GroupCallback} + * @private + * @since 3.22.0 + */ + this.internalCreateCallback = GetFastValue(config, 'internalCreateCallback', null); + + /** + * A function to be called when removing group members. + * For internal use only by a Group, or any class that extends it. + * + * @name Phaser.GameObjects.Group#internalRemoveCallback + * @type {?Phaser.Types.GameObjects.Group.GroupCallback} + * @private + * @since 3.22.0 + */ + this.internalRemoveCallback = GetFastValue(config, 'internalRemoveCallback', null); + + if (children) + { + this.addMultiple(children); + } + + if (config) + { + this.createMultiple(config); + } + + this.on(Events.ADDED_TO_SCENE, this.addedToScene, this); + this.on(Events.REMOVED_FROM_SCENE, this.removedFromScene, this); }, - /** - * Returns the world transform matrix as used for Bounds checks. - * - * The returned matrix is temporal and shouldn't be stored. - * - * @method Phaser.GameObjects.Container#getBoundsTransformMatrix - * @since 3.4.0 - * - * @return {Phaser.GameObjects.Components.TransformMatrix} The world transform matrix. - */ - getBoundsTransformMatrix: function () + // Overrides Game Object method + addedToScene: function () { - return this.getWorldTransformMatrix(this.tempTransformMatrix, this.localTransform); + this.scene.sys.updateList.add(this); }, - /** - * Adds the given Game Object, or array of Game Objects, to this Container. - * - * Each Game Object must be unique within the Container. - * - * @method Phaser.GameObjects.Container#add - * @since 3.4.0 - * - * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container. - * - * @return {this} This Container instance. - */ - add: function (child) + // Overrides Game Object method + removedFromScene: function () { - ArrayUtils.Add(this.list, child, this.maxSize, this.addHandler, this); - - return this; + this.scene.sys.updateList.remove(this); }, /** - * Adds the given Game Object, or array of Game Objects, to this Container at the specified position. - * - * Existing Game Objects in the Container are shifted up. + * Creates a new Game Object and adds it to this group, unless the group {@link Phaser.GameObjects.Group#isFull is full}. * - * Each Game Object must be unique within the Container. + * Calls {@link Phaser.GameObjects.Group#createCallback}. * - * @method Phaser.GameObjects.Container#addAt - * @since 3.4.0 + * @method Phaser.GameObjects.Group#create + * @since 3.0.0 * - * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container. - * @param {number} [index=0] - The position to insert the Game Object/s at. + * @param {number} [x=0] - The horizontal position of the new Game Object in the world. + * @param {number} [y=0] - The vertical position of the new Game Object in the world. + * @param {string} [key=defaultKey] - The texture key of the new Game Object. + * @param {(string|number)} [frame=defaultFrame] - The texture frame of the new Game Object. + * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of the new Game Object. + * @param {boolean} [active=true] - The {@link Phaser.GameObjects.GameObject#active} state of the new Game Object. * - * @return {this} This Container instance. + * @return {any} The new Game Object (usually a Sprite, etc.). */ - addAt: function (child, index) + create: function (x, y, key, frame, visible, active) { - ArrayUtils.AddAt(this.list, child, index, this.maxSize, this.addHandler, this); + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (key === undefined) { key = this.defaultKey; } + if (frame === undefined) { frame = this.defaultFrame; } + if (visible === undefined) { visible = true; } + if (active === undefined) { active = true; } - return this; - }, + // Pool? + if (this.isFull()) + { + return null; + } - /** - * Returns the Game Object at the given position in this Container. - * - * @method Phaser.GameObjects.Container#getAt - * @since 3.4.0 - * - * @param {number} index - The position to get the Game Object from. - * - * @return {?Phaser.GameObjects.GameObject} The Game Object at the specified index, or `null` if none found. - */ - getAt: function (index) - { - return this.list[index]; + var child = new this.classType(this.scene, x, y, key, frame); + + child.addToDisplayList(this.scene.sys.displayList); + child.addToUpdateList(); + + child.visible = visible; + child.setActive(active); + + this.add(child); + + return child; }, /** - * Returns the index of the given Game Object in this Container. - * - * @method Phaser.GameObjects.Container#getIndex - * @since 3.4.0 + * Creates several Game Objects and adds them to this group. * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to search for in this Container. + * If the group becomes {@link Phaser.GameObjects.Group#isFull}, no further Game Objects are created. * - * @return {number} The index of the Game Object in this Container, or -1 if not found. - */ - getIndex: function (child) - { - return this.list.indexOf(child); - }, - - /** - * Sort the contents of this Container so the items are in order based on the given property. - * For example: `sort('alpha')` would sort the elements based on the value of their `alpha` property. + * Calls {@link Phaser.GameObjects.Group#createMultipleCallback} and {@link Phaser.GameObjects.Group#createCallback}. * - * @method Phaser.GameObjects.Container#sort - * @since 3.4.0 + * @method Phaser.GameObjects.Group#createMultiple + * @since 3.0.0 * - * @param {string} property - The property to lexically sort by. - * @param {function} [handler] - Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean. + * @param {Phaser.Types.GameObjects.Group.GroupCreateConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig[]} config - Creation settings. This can be a single configuration object or an array of such objects, which will be applied in turn. * - * @return {this} This Container instance. + * @return {any[]} The newly created Game Objects. */ - sort: function (property, handler) + createMultiple: function (config) { - if (!property) + if (this.isFull()) { - return this; + return []; } - if (handler === undefined) + if (!Array.isArray(config)) { - handler = function (childA, childB) - { - return childA[property] - childB[property]; - }; + config = [ config ]; } - ArrayUtils.StableSort(this.list, handler); + var output = []; - return this; + if (config[0].key) + { + for (var i = 0; i < config.length; i++) + { + var entries = this.createFromConfig(config[i]); + + output = output.concat(entries); + } + } + + return output; }, /** - * Searches for the first instance of a child with its `name` property matching the given argument. - * Should more than one child have the same name only the first is returned. + * A helper for {@link Phaser.GameObjects.Group#createMultiple}. * - * @method Phaser.GameObjects.Container#getByName - * @since 3.4.0 + * @method Phaser.GameObjects.Group#createFromConfig + * @since 3.0.0 * - * @param {string} name - The name to search for. + * @param {Phaser.Types.GameObjects.Group.GroupCreateConfig} options - Creation settings. * - * @return {?Phaser.GameObjects.GameObject} The first child with a matching name, or `null` if none were found. + * @return {any[]} The newly created Game Objects. */ - getByName: function (name) + createFromConfig: function (options) { - return ArrayUtils.GetFirst(this.list, 'name', name); - }, + if (this.isFull()) + { + return []; + } + + this.classType = GetFastValue(options, 'classType', this.classType); + + var key = GetFastValue(options, 'key', undefined); + var frame = GetFastValue(options, 'frame', null); + var visible = GetFastValue(options, 'visible', true); + var active = GetFastValue(options, 'active', true); + + var entries = []; + + // Can't do anything without at least a key + if (key === undefined) + { + return entries; + } + else + { + if (!Array.isArray(key)) + { + key = [ key ]; + } + + if (!Array.isArray(frame)) + { + frame = [ frame ]; + } + } + + // Build an array of key frame pairs to loop through + + var repeat = GetFastValue(options, 'repeat', 0); + var randomKey = GetFastValue(options, 'randomKey', false); + var randomFrame = GetFastValue(options, 'randomFrame', false); + var yoyo = GetFastValue(options, 'yoyo', false); + var quantity = GetFastValue(options, 'quantity', false); + var frameQuantity = GetFastValue(options, 'frameQuantity', 1); + var max = GetFastValue(options, 'max', 0); + + // If a quantity value is set we use that to override the frameQuantity + + var range = Range(key, frame, { + max: max, + qty: (quantity) ? quantity : frameQuantity, + random: randomKey, + randomB: randomFrame, + repeat: repeat, + yoyo: yoyo + }); + + if (options.createCallback) + { + this.createCallback = options.createCallback; + } + + if (options.removeCallback) + { + this.removeCallback = options.removeCallback; + } + + for (var c = 0; c < range.length; c++) + { + var created = this.create(0, 0, range[c].a, range[c].b, visible, active); + + if (!created) + { + break; + } + + entries.push(created); + } + + // Post-creation options (applied only to those items created in this call): + + if (HasValue(options, 'setXY')) + { + var x = GetValue(options, 'setXY.x', 0); + var y = GetValue(options, 'setXY.y', 0); + var stepX = GetValue(options, 'setXY.stepX', 0); + var stepY = GetValue(options, 'setXY.stepY', 0); + + Actions.SetXY(entries, x, y, stepX, stepY); + } + + if (HasValue(options, 'setRotation')) + { + var rotation = GetValue(options, 'setRotation.value', 0); + var stepRotation = GetValue(options, 'setRotation.step', 0); + + Actions.SetRotation(entries, rotation, stepRotation); + } + + if (HasValue(options, 'setScale')) + { + var scaleX = GetValue(options, 'setScale.x', 1); + var scaleY = GetValue(options, 'setScale.y', scaleX); + var stepScaleX = GetValue(options, 'setScale.stepX', 0); + var stepScaleY = GetValue(options, 'setScale.stepY', 0); + + Actions.SetScale(entries, scaleX, scaleY, stepScaleX, stepScaleY); + } + + if (HasValue(options, 'setOrigin')) + { + var originX = GetValue(options, 'setOrigin.x', 0.5); + var originY = GetValue(options, 'setOrigin.y', originX); + var stepOriginX = GetValue(options, 'setOrigin.stepX', 0); + var stepOriginY = GetValue(options, 'setOrigin.stepY', 0); + + Actions.SetOrigin(entries, originX, originY, stepOriginX, stepOriginY); + } + + if (HasValue(options, 'setAlpha')) + { + var alpha = GetValue(options, 'setAlpha.value', 1); + var stepAlpha = GetValue(options, 'setAlpha.step', 0); + + Actions.SetAlpha(entries, alpha, stepAlpha); + } + + if (HasValue(options, 'setDepth')) + { + var depth = GetValue(options, 'setDepth.value', 0); + var stepDepth = GetValue(options, 'setDepth.step', 0); + + Actions.SetDepth(entries, depth, stepDepth); + } + + if (HasValue(options, 'setScrollFactor')) + { + var scrollFactorX = GetValue(options, 'setScrollFactor.x', 1); + var scrollFactorY = GetValue(options, 'setScrollFactor.y', scrollFactorX); + var stepScrollFactorX = GetValue(options, 'setScrollFactor.stepX', 0); + var stepScrollFactorY = GetValue(options, 'setScrollFactor.stepY', 0); + + Actions.SetScrollFactor(entries, scrollFactorX, scrollFactorY, stepScrollFactorX, stepScrollFactorY); + } + + var hitArea = GetFastValue(options, 'hitArea', null); + var hitAreaCallback = GetFastValue(options, 'hitAreaCallback', null); + + if (hitArea) + { + Actions.SetHitArea(entries, hitArea, hitAreaCallback); + } + + var grid = GetFastValue(options, 'gridAlign', false); + + if (grid) + { + Actions.GridAlign(entries, grid); + } + + if (this.createMultipleCallback) + { + this.createMultipleCallback.call(this, entries); + } + + return entries; + }, /** - * Returns a random Game Object from this Container. - * - * @method Phaser.GameObjects.Container#getRandom - * @since 3.4.0 + * Updates any group members, if {@link Phaser.GameObjects.Group#runChildUpdate} is enabled. * - * @param {number} [startIndex=0] - An optional start index. - * @param {number} [length] - An optional length, the total number of elements (from the startIndex) to choose from. + * @method Phaser.GameObjects.Group#preUpdate + * @since 3.0.0 * - * @return {?Phaser.GameObjects.GameObject} A random child from the Container, or `null` if the Container is empty. + * @param {number} time - The current timestamp. + * @param {number} delta - The delta time elapsed since the last frame. */ - getRandom: function (startIndex, length) + preUpdate: function (time, delta) { - return ArrayUtils.GetRandom(this.list, startIndex, length); + if (!this.runChildUpdate || this.children.size === 0) + { + return; + } + + // Because a Group child may mess with the length of the Group during its update + var temp = this.children.entries.slice(); + + for (var i = 0; i < temp.length; i++) + { + var item = temp[i]; + + if (item.active) + { + item.update(time, delta); + } + } }, /** - * Gets the first Game Object in this Container. + * Adds a Game Object to this group. * - * You can also specify a property and value to search for, in which case it will return the first - * Game Object in this Container with a matching property and / or value. + * Calls {@link Phaser.GameObjects.Group#createCallback}. * - * For example: `getFirst('visible', true)` would return the first Game Object that had its `visible` property set. + * @method Phaser.GameObjects.Group#add + * @since 3.0.0 * - * You can limit the search to the `startIndex` - `endIndex` range. + * @param {Phaser.GameObjects.GameObject} child - The Game Object to add. + * @param {boolean} [addToScene=false] - Also add the Game Object to the scene. * - * @method Phaser.GameObjects.Container#getFirst - * @since 3.4.0 + * @return {this} This Group object. + */ + add: function (child, addToScene) + { + if (addToScene === undefined) { addToScene = false; } + + if (this.isFull()) + { + return this; + } + + this.children.set(child); + + if (this.internalCreateCallback) + { + this.internalCreateCallback.call(this, child); + } + + if (this.createCallback) + { + this.createCallback.call(this, child); + } + + if (addToScene) + { + child.addToDisplayList(this.scene.sys.displayList); + child.addToUpdateList(); + } + + child.on(Events.DESTROY, this.remove, this); + + return this; + }, + + /** + * Adds several Game Objects to this group. * - * @param {string} property - The property to test on each Game Object in the Container. - * @param {*} value - The value to test the property against. Must pass a strict (`===`) comparison check. - * @param {number} [startIndex=0] - An optional start index to search from. - * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) + * Calls {@link Phaser.GameObjects.Group#createCallback}. * - * @return {?Phaser.GameObjects.GameObject} The first matching Game Object, or `null` if none was found. + * @method Phaser.GameObjects.Group#addMultiple + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject[]} children - The Game Objects to add. + * @param {boolean} [addToScene=false] - Also add the Game Objects to the scene. + * + * @return {this} This group. */ - getFirst: function (property, value, startIndex, endIndex) + addMultiple: function (children, addToScene) { - return ArrayUtils.GetFirst(this.list, property, value, startIndex, endIndex); + if (addToScene === undefined) { addToScene = false; } + + if (Array.isArray(children)) + { + for (var i = 0; i < children.length; i++) + { + this.add(children[i], addToScene); + } + } + + return this; }, /** - * Returns all Game Objects in this Container. + * Removes a member of this Group and optionally removes it from the Scene and / or destroys it. * - * You can optionally specify a matching criteria using the `property` and `value` arguments. + * Calls {@link Phaser.GameObjects.Group#removeCallback}. * - * For example: `getAll('body')` would return only Game Objects that have a body property. + * @method Phaser.GameObjects.Group#remove + * @since 3.0.0 * - * You can also specify a value to compare the property to: + * @param {Phaser.GameObjects.GameObject} child - The Game Object to remove. + * @param {boolean} [removeFromScene=false] - Optionally remove the Group member from the Scene it belongs to. + * @param {boolean} [destroyChild=false] - Optionally call destroy on the removed Group member. * - * `getAll('visible', true)` would return only Game Objects that have their visible property set to `true`. + * @return {this} This Group object. + */ + remove: function (child, removeFromScene, destroyChild) + { + if (removeFromScene === undefined) { removeFromScene = false; } + if (destroyChild === undefined) { destroyChild = false; } + + if (!this.children.contains(child)) + { + return this; + } + + this.children.delete(child); + + if (this.internalRemoveCallback) + { + this.internalRemoveCallback.call(this, child); + } + + if (this.removeCallback) + { + this.removeCallback.call(this, child); + } + + child.off(Events.DESTROY, this.remove, this); + + if (destroyChild) + { + child.destroy(); + } + else if (removeFromScene) + { + child.removeFromDisplayList(); + child.removeFromUpdateList(); + } + + return this; + }, + + /** + * Removes all members of this Group and optionally removes them from the Scene and / or destroys them. * - * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects, - * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only - * the first 50 Game Objects. + * Does not call {@link Phaser.GameObjects.Group#removeCallback}. * - * @method Phaser.GameObjects.Container#getAll - * @since 3.4.0 + * @method Phaser.GameObjects.Group#clear + * @since 3.0.0 * - * @param {string} [property] - The property to test on each Game Object in the Container. - * @param {any} [value] - If property is set then the `property` must strictly equal this value to be included in the results. - * @param {number} [startIndex=0] - An optional start index to search from. - * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) + * @param {boolean} [removeFromScene=false] - Optionally remove each Group member from the Scene. + * @param {boolean} [destroyChild=false] - Optionally call destroy on the removed Group members. * - * @return {Phaser.GameObjects.GameObject[]} An array of matching Game Objects from this Container. + * @return {this} This group. */ - getAll: function (property, value, startIndex, endIndex) + clear: function (removeFromScene, destroyChild) { - return ArrayUtils.GetAll(this.list, property, value, startIndex, endIndex); + if (removeFromScene === undefined) { removeFromScene = false; } + if (destroyChild === undefined) { destroyChild = false; } + + var children = this.children; + + for (var i = 0; i < children.size; i++) + { + var gameObject = children.entries[i]; + + gameObject.off(Events.DESTROY, this.remove, this); + + if (destroyChild) + { + gameObject.destroy(); + } + else if (removeFromScene) + { + gameObject.removeFromDisplayList(); + gameObject.removeFromUpdateList(); + } + } + + this.children.clear(); + + return this; }, /** - * Returns the total number of Game Objects in this Container that have a property - * matching the given value. + * Tests if a Game Object is a member of this group. * - * For example: `count('visible', true)` would count all the elements that have their visible property set. + * @method Phaser.GameObjects.Group#contains + * @since 3.0.0 * - * You can optionally limit the operation to the `startIndex` - `endIndex` range. + * @param {Phaser.GameObjects.GameObject} child - A Game Object. * - * @method Phaser.GameObjects.Container#count - * @since 3.4.0 + * @return {boolean} True if the Game Object is a member of this group. + */ + contains: function (child) + { + return this.children.contains(child); + }, + + /** + * All members of the group. * - * @param {string} property - The property to check. - * @param {any} value - The value to check. - * @param {number} [startIndex=0] - An optional start index to search from. - * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) + * @method Phaser.GameObjects.Group#getChildren + * @since 3.0.0 * - * @return {number} The total number of Game Objects in this Container with a property matching the given value. + * @return {Phaser.GameObjects.GameObject[]} The group members. */ - count: function (property, value, startIndex, endIndex) + getChildren: function () { - return ArrayUtils.CountAllMatching(this.list, property, value, startIndex, endIndex); + return this.children.entries; }, /** - * Swaps the position of two Game Objects in this Container. - * Both Game Objects must belong to this Container. - * - * @method Phaser.GameObjects.Container#swap - * @since 3.4.0 + * The number of members of the group. * - * @param {Phaser.GameObjects.GameObject} child1 - The first Game Object to swap. - * @param {Phaser.GameObjects.GameObject} child2 - The second Game Object to swap. + * @method Phaser.GameObjects.Group#getLength + * @since 3.0.0 * - * @return {this} This Container instance. + * @return {number} */ - swap: function (child1, child2) + getLength: function () { - ArrayUtils.Swap(this.list, child1, child2); - - return this; + return this.children.size; }, /** - * Moves a Game Object to a new position within this Container. + * Returns all children in this Group that match the given criteria based on the `property` and `value` arguments. * - * The Game Object must already be a child of this Container. + * For example: `getMatching('visible', true)` would return only children that have their `visible` property set. * - * The Game Object is removed from its old position and inserted into the new one. - * Therefore the Container size does not change. Other children will change position accordingly. + * Optionally, you can specify a start and end index. For example if the Group has 100 elements, + * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only + * the first 50. * - * @method Phaser.GameObjects.Container#moveTo - * @since 3.4.0 + * @method Phaser.GameObjects.Group#getMatching + * @since 3.50.0 * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to move. - * @param {number} index - The new position of the Game Object in this Container. + * @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] - An optional start index to search from. + * @param {number} [endIndex] - An optional end index to search to. * - * @return {this} This Container instance. + * @return {any[]} An array of matching Group members. The array will be empty if nothing matched. */ - moveTo: function (child, index) + getMatching: function (property, value, startIndex, endIndex) { - ArrayUtils.MoveTo(this.list, child, index); - - return this; + return GetAll(this.children.entries, property, value, startIndex, endIndex); }, /** - * Moves a Game Object above another one within this Container. + * Scans the Group, from top to bottom, for the first member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, + * assigns `x` and `y`, and returns the member. * - * These 2 Game Objects must already be children of this Container. + * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. * - * @method Phaser.GameObjects.Container#moveAbove - * @since 3.55.0 + * @method Phaser.GameObjects.Group#getFirst + * @since 3.0.0 * - * @param {Phaser.GameObjects.GameObject} child1 - The Game Object to move above base Game Object. - * @param {Phaser.GameObjects.GameObject} child2 - The base Game Object. + * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. + * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. + * @param {number} [x] - The horizontal position of the Game Object in the world. + * @param {number} [y] - The vertical position of the Game Object in the world. + * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). + * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). + * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). * - * @return {this} This Container instance. + * @return {?any} The first matching group member, or a newly created member, or null. */ - moveAbove: function (child1, child2) + getFirst: function (state, createIfNull, x, y, key, frame, visible) { - ArrayUtils.MoveAbove(this.list, child1, child2); - - return this; + return this.getHandler(true, 1, state, createIfNull, x, y, key, frame, visible); }, /** - * Moves a Game Object below another one within this Container. + * Scans the Group, from top to bottom, for the nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, + * assigns `x` and `y`, and returns the member. * - * These 2 Game Objects must already be children of this Container. + * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. * - * @method Phaser.GameObjects.Container#moveBelow - * @since 3.55.0 + * @method Phaser.GameObjects.Group#getFirstNth + * @since 3.6.0 * - * @param {Phaser.GameObjects.GameObject} child1 - The Game Object to move below base Game Object. - * @param {Phaser.GameObjects.GameObject} child2 - The base Game Object. + * @param {number} nth - The nth matching Group member to search for. + * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. + * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. + * @param {number} [x] - The horizontal position of the Game Object in the world. + * @param {number} [y] - The vertical position of the Game Object in the world. + * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). + * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). + * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). * - * @return {this} This Container instance. + * @return {?any} The first matching group member, or a newly created member, or null. */ - moveBelow: function (child1, child2) + getFirstNth: function (nth, state, createIfNull, x, y, key, frame, visible) { - ArrayUtils.MoveBelow(this.list, child1, child2); + return this.getHandler(true, nth, state, createIfNull, x, y, key, frame, visible); + }, - return this; + /** + * Scans the Group for the last member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, + * assigns `x` and `y`, and returns the member. + * + * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * + * @method Phaser.GameObjects.Group#getLast + * @since 3.6.0 + * + * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. + * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. + * @param {number} [x] - The horizontal position of the Game Object in the world. + * @param {number} [y] - The vertical position of the Game Object in the world. + * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). + * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). + * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). + * + * @return {?any} The first matching group member, or a newly created member, or null. + */ + getLast: function (state, createIfNull, x, y, key, frame, visible) + { + return this.getHandler(false, 1, state, createIfNull, x, y, key, frame, visible); }, /** - * Removes the given Game Object, or array of Game Objects, from this Container. + * Scans the Group for the last nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, + * assigns `x` and `y`, and returns the member. * - * The Game Objects must already be children of this Container. + * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. * - * You can also optionally call `destroy` on each Game Object that is removed from the Container. + * @method Phaser.GameObjects.Group#getLastNth + * @since 3.6.0 * - * @method Phaser.GameObjects.Container#remove - * @since 3.4.0 + * @param {number} nth - The nth matching Group member to search for. + * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. + * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. + * @param {number} [x] - The horizontal position of the Game Object in the world. + * @param {number} [y] - The vertical position of the Game Object in the world. + * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). + * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). + * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). * - * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to be removed from the Container. - * @param {boolean} [destroyChild=false] - Optionally call `destroy` on each child successfully removed from this Container. + * @return {?any} The first matching group member, or a newly created member, or null. + */ + getLastNth: function (nth, state, createIfNull, x, y, key, frame, visible) + { + return this.getHandler(false, nth, state, createIfNull, x, y, key, frame, visible); + }, + + /** + * Scans the group for the last member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, + * assigns `x` and `y`, and returns the member. * - * @return {this} This Container instance. + * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * + * @method Phaser.GameObjects.Group#getHandler + * @private + * @since 3.6.0 + * + * @param {boolean} forwards - Search front to back or back to front? + * @param {number} nth - Stop matching after nth successful matches. + * @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match. + * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. + * @param {number} [x] - The horizontal position of the Game Object in the world. + * @param {number} [y] - The vertical position of the Game Object in the world. + * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). + * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). + * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). + * + * @return {?any} The first matching group member, or a newly created member, or null. */ - remove: function (child, destroyChild) + getHandler: function (forwards, nth, state, createIfNull, x, y, key, frame, visible) { - var removed = ArrayUtils.Remove(this.list, child, this.removeHandler, this); + if (state === undefined) { state = false; } + if (createIfNull === undefined) { createIfNull = false; } - if (destroyChild && removed) + var gameObject; + + var i; + var total = 0; + var children = this.children.entries; + + if (forwards) { - if (!Array.isArray(removed)) + for (i = 0; i < children.length; i++) { - removed = [ removed ]; + gameObject = children[i]; + + if (gameObject.active === state) + { + total++; + + if (total === nth) + { + break; + } + } + else + { + gameObject = null; + } } + } + else + { + for (i = children.length - 1; i >= 0; i--) + { + gameObject = children[i]; - for (var i = 0; i < removed.length; i++) + if (gameObject.active === state) + { + total++; + + if (total === nth) + { + break; + } + } + else + { + gameObject = null; + } + } + } + + if (gameObject) + { + if (typeof(x) === 'number') { - removed[i].destroy(); + gameObject.x = x; + } + + if (typeof(y) === 'number') + { + gameObject.y = y; } + + return gameObject; } - return this; + // Got this far? We need to create or bail + if (createIfNull) + { + return this.create(x, y, key, frame, visible); + } + else + { + return null; + } }, /** - * Removes the Game Object at the given position in this Container. + * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`, + * assigns `x` and `y`, and returns the member. * - * You can also optionally call `destroy` on the Game Object, if one is found. + * If no inactive member is found and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * The new Game Object will have its active state set to `true`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. * - * @method Phaser.GameObjects.Container#removeAt - * @since 3.4.0 + * @method Phaser.GameObjects.Group#get + * @since 3.0.0 * - * @param {number} index - The index of the Game Object to be removed. - * @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container. + * @param {number} [x] - The horizontal position of the Game Object in the world. + * @param {number} [y] - The vertical position of the Game Object in the world. + * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). + * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). + * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). * - * @return {this} This Container instance. + * @return {?any} The first inactive group member, or a newly created member, or null. */ - removeAt: function (index, destroyChild) + get: function (x, y, key, frame, visible) { - var removed = ArrayUtils.RemoveAt(this.list, index, this.removeHandler, this); - - if (destroyChild && removed) - { - removed.destroy(); - } + return this.getFirst(false, true, x, y, key, frame, visible); + }, - return this; + /** + * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `true`, + * assigns `x` and `y`, and returns the member. + * + * If no active member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * + * @method Phaser.GameObjects.Group#getFirstAlive + * @since 3.0.0 + * + * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. + * @param {number} [x] - The horizontal position of the Game Object in the world. + * @param {number} [y] - The vertical position of the Game Object in the world. + * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). + * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). + * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). + * + * @return {any} The first active group member, or a newly created member, or null. + */ + getFirstAlive: function (createIfNull, x, y, key, frame, visible) + { + return this.getFirst(true, createIfNull, x, y, key, frame, visible); }, /** - * Removes the Game Objects between the given positions in this Container. + * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`, + * assigns `x` and `y`, and returns the member. * - * You can also optionally call `destroy` on each Game Object that is removed from the Container. + * If no inactive member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`. + * The new Game Object will have an active state set to `true`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. * - * @method Phaser.GameObjects.Container#removeBetween - * @since 3.4.0 + * @method Phaser.GameObjects.Group#getFirstDead + * @since 3.0.0 * - * @param {number} [startIndex=0] - An optional start index to search from. - * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) - * @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container. + * @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments. + * @param {number} [x] - The horizontal position of the Game Object in the world. + * @param {number} [y] - The vertical position of the Game Object in the world. + * @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created). + * @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created). + * @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). * - * @return {this} This Container instance. + * @return {any} The first inactive group member, or a newly created member, or null. */ - removeBetween: function (startIndex, endIndex, destroyChild) + getFirstDead: function (createIfNull, x, y, key, frame, visible) { - var removed = ArrayUtils.RemoveBetween(this.list, startIndex, endIndex, this.removeHandler, this); + return this.getFirst(false, createIfNull, x, y, key, frame, visible); + }, - if (destroyChild) - { - for (var i = 0; i < removed.length; i++) - { - removed[i].destroy(); - } - } + /** + * {@link Phaser.GameObjects.Components.Animation#play Plays} an animation for all members of this group. + * + * @method Phaser.GameObjects.Group#playAnimation + * @since 3.0.0 + * + * @param {string} key - The string-based key of the animation to play. + * @param {string} [startFrame=0] - Optionally start the animation playing from this frame index. + * + * @return {this} This Group object. + */ + playAnimation: function (key, startFrame) + { + Actions.PlayAnimation(this.children.entries, key, startFrame); return this; }, /** - * Removes all Game Objects from this Container. + * Whether this group's size at its {@link Phaser.GameObjects.Group#maxSize maximum}. * - * You can also optionally call `destroy` on each Game Object that is removed from the Container. + * @method Phaser.GameObjects.Group#isFull + * @since 3.0.0 * - * @method Phaser.GameObjects.Container#removeAll - * @since 3.4.0 + * @return {boolean} True if the number of members equals {@link Phaser.GameObjects.Group#maxSize}. + */ + isFull: function () + { + if (this.maxSize === -1) + { + return false; + } + else + { + return (this.children.size >= this.maxSize); + } + }, + + /** + * Counts the number of active (or inactive) group members. * - * @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container. + * @method Phaser.GameObjects.Group#countActive + * @since 3.0.0 * - * @return {this} This Container instance. + * @param {boolean} [value=true] - Count active (true) or inactive (false) group members. + * + * @return {number} The number of group members with an active state matching the `active` argument. */ - removeAll: function (destroyChild) + countActive: function (value) { - var removed = ArrayUtils.RemoveBetween(this.list, 0, this.list.length, this.removeHandler, this); + if (value === undefined) { value = true; } - if (destroyChild) + var total = 0; + + for (var i = 0; i < this.children.size; i++) { - for (var i = 0; i < removed.length; i++) + if (this.children.entries[i].active === value) { - removed[i].destroy(); + total++; } } - return this; + return total; }, /** - * Brings the given Game Object to the top of this Container. - * This will cause it to render on-top of any other objects in the Container. - * - * @method Phaser.GameObjects.Container#bringToTop - * @since 3.4.0 + * Counts the number of in-use (active) group members. * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to bring to the top of the Container. + * @method Phaser.GameObjects.Group#getTotalUsed + * @since 3.0.0 * - * @return {this} This Container instance. + * @return {number} The number of group members with an active state of true. */ - bringToTop: function (child) + getTotalUsed: function () { - ArrayUtils.BringToTop(this.list, child); - - return this; + return this.countActive(); }, /** - * Sends the given Game Object to the bottom of this Container. - * This will cause it to render below any other objects in the Container. + * The difference of {@link Phaser.GameObjects.Group#maxSize} and the number of active group members. * - * @method Phaser.GameObjects.Container#sendToBack - * @since 3.4.0 + * This represents the number of group members that could be created or reactivated before reaching the size limit. * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to send to the bottom of the Container. + * @method Phaser.GameObjects.Group#getTotalFree + * @since 3.0.0 * - * @return {this} This Container instance. + * @return {number} maxSize minus the number of active group numbers; or a large number (if maxSize is -1). */ - sendToBack: function (child) + getTotalFree: function () { - ArrayUtils.SendToBack(this.list, child); + var used = this.getTotalUsed(); + var capacity = (this.maxSize === -1) ? 999999999999 : this.maxSize; - return this; + return (capacity - used); }, /** - * Moves the given Game Object up one place in this Container, unless it's already at the top. + * Sets the `active` property of this Group. + * When active, this Group runs its `preUpdate` method. * - * @method Phaser.GameObjects.Container#moveUp - * @since 3.4.0 + * @method Phaser.GameObjects.Group#setActive + * @since 3.24.0 * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container. + * @param {boolean} value - True if this Group should be set as active, false if not. * - * @return {this} This Container instance. + * @return {this} This Group object. */ - moveUp: function (child) + setActive: function (value) { - ArrayUtils.MoveUp(this.list, child); + this.active = value; return this; }, /** - * Moves the given Game Object down one place in this Container, unless it's already at the bottom. + * Sets the `name` property of this Group. + * The `name` property is not populated by Phaser and is presented for your own use. * - * @method Phaser.GameObjects.Container#moveDown - * @since 3.4.0 + * @method Phaser.GameObjects.Group#setName + * @since 3.24.0 * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container. + * @param {string} value - The name to be given to this Group. * - * @return {this} This Container instance. + * @return {this} This Group object. */ - moveDown: function (child) + setName: function (value) { - ArrayUtils.MoveDown(this.list, child); + this.name = value; return this; }, /** - * Reverses the order of all Game Objects in this Container. + * Sets the property as defined in `key` of each group member to the given value. * - * @method Phaser.GameObjects.Container#reverse - * @since 3.4.0 + * @method Phaser.GameObjects.Group#propertyValueSet + * @since 3.21.0 * - * @return {this} This Container instance. + * @param {string} key - The property to be updated. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {this} This Group object. */ - reverse: function () + propertyValueSet: function (key, value, step, index, direction) { - this.list.reverse(); + Actions.PropertyValueSet(this.children.entries, key, value, step, index, direction); return this; }, /** - * Shuffles the all Game Objects in this Container using the Fisher-Yates implementation. + * Adds the given value to the property as defined in `key` of each group member. * - * @method Phaser.GameObjects.Container#shuffle - * @since 3.4.0 + * @method Phaser.GameObjects.Group#propertyValueInc + * @since 3.21.0 * - * @return {this} This Container instance. + * @param {string} key - The property to be updated. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * + * @return {this} This Group object. */ - shuffle: function () + propertyValueInc: function (key, value, step, index, direction) { - ArrayUtils.Shuffle(this.list); + Actions.PropertyValueInc(this.children.entries, key, value, step, index, direction); return this; }, /** - * Replaces a Game Object in this Container with the new Game Object. - * The new Game Object cannot already be a child of this Container. + * Sets the x of each group member. * - * @method Phaser.GameObjects.Container#replace - * @since 3.4.0 + * @method Phaser.GameObjects.Group#setX + * @since 3.21.0 * - * @param {Phaser.GameObjects.GameObject} oldChild - The Game Object in this Container that will be replaced. - * @param {Phaser.GameObjects.GameObject} newChild - The Game Object to be added to this Container. - * @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. * - * @return {this} This Container instance. + * @return {this} This Group object. */ - replace: function (oldChild, newChild, destroyChild) + setX: function (value, step) { - var moved = ArrayUtils.Replace(this.list, oldChild, newChild); - - if (moved) - { - this.addHandler(newChild); - this.removeHandler(oldChild); - - if (destroyChild) - { - oldChild.destroy(); - } - } + Actions.SetX(this.children.entries, value, step); return this; }, /** - * Returns `true` if the given Game Object is a direct child of this Container. - * - * This check does not scan nested Containers. + * Sets the y of each group member. * - * @method Phaser.GameObjects.Container#exists - * @since 3.4.0 + * @method Phaser.GameObjects.Group#setY + * @since 3.21.0 * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to check for within this Container. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. * - * @return {boolean} True if the Game Object is an immediate child of this Container, otherwise false. + * @return {this} This Group object. */ - exists: function (child) + setY: function (value, step) { - return (this.list.indexOf(child) > -1); + Actions.SetY(this.children.entries, value, step); + + return this; }, /** - * Sets the property to the given value on all Game Objects in this Container. - * - * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects, - * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only - * the first 50 Game Objects. + * Sets the x, y of each group member. * - * @method Phaser.GameObjects.Container#setAll - * @since 3.4.0 + * @method Phaser.GameObjects.Group#setXY + * @since 3.21.0 * - * @param {string} property - The property that must exist on the Game Object. - * @param {any} value - The value to get the property to. - * @param {number} [startIndex=0] - An optional start index to search from. - * @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included) + * @param {number} x - The amount to set the `x` property to. + * @param {number} [y=x] - The amount to set the `y` property to. If `undefined` or `null` it uses the `x` value. + * @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter. * - * @return {this} This Container instance. + * @return {this} This Group object. */ - setAll: function (property, value, startIndex, endIndex) + setXY: function (x, y, stepX, stepY) { - ArrayUtils.SetAll(this.list, property, value, startIndex, endIndex); + Actions.SetXY(this.children.entries, x, y, stepX, stepY); return this; }, /** - * @callback EachContainerCallback - * @generic I - [item] + * Adds the given value to the x of each group member. * - * @param {*} item - The child Game Object of the Container. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + * @method Phaser.GameObjects.Group#incX + * @since 3.21.0 + * + * @param {number} value - The amount to be added to the `x` property. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * + * @return {this} This Group object. */ + incX: function (value, step) + { + Actions.IncX(this.children.entries, value, step); + + return this; + }, /** - * Passes all Game Objects in this Container to the given callback. - * - * A copy of the Container is made before passing each entry to your callback. - * This protects against the callback itself modifying the Container. - * - * If you know for sure that the callback will not change the size of this Container - * then you can use the more performant `Container.iterate` method instead. + * Adds the given value to the y of each group member. * - * @method Phaser.GameObjects.Container#each - * @since 3.4.0 + * @method Phaser.GameObjects.Group#incY + * @since 3.21.0 * - * @param {function} callback - The function to call. - * @param {object} [context] - Value to use as `this` when executing callback. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + * @param {number} value - The amount to be added to the `y` property. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. * - * @return {this} This Container instance. + * @return {this} This Group object. */ - each: function (callback, context) + incY: function (value, step) { - var args = [ null ]; - var i; - var temp = this.list.slice(); - var len = temp.length; - - for (i = 2; i < arguments.length; i++) - { - args.push(arguments[i]); - } - - for (i = 0; i < len; i++) - { - args[0] = temp[i]; - - callback.apply(context, args); - } + Actions.IncY(this.children.entries, value, step); return this; }, /** - * Passes all Game Objects in this Container to the given callback. - * - * Only use this method when you absolutely know that the Container will not be modified during - * the iteration, i.e. by removing or adding to its contents. + * Adds the given value to the x, y of each group member. * - * @method Phaser.GameObjects.Container#iterate - * @since 3.4.0 + * @method Phaser.GameObjects.Group#incXY + * @since 3.21.0 * - * @param {function} callback - The function to call. - * @param {object} [context] - Value to use as `this` when executing callback. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + * @param {number} x - The amount to be added to the `x` property. + * @param {number} [y=x] - The amount to be added to the `y` property. If `undefined` or `null` it uses the `x` value. + * @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter. * - * @return {this} This Container instance. + * @return {this} This Group object. */ - iterate: function (callback, context) + incXY: function (x, y, stepX, stepY) { - var args = [ null ]; - var i; - - for (i = 2; i < arguments.length; i++) - { - args.push(arguments[i]); - } - - for (i = 0; i < this.list.length; i++) - { - args[0] = this.list[i]; - - callback.apply(context, args); - } + Actions.IncXY(this.children.entries, x, y, stepX, stepY); return this; }, /** - * Sets the scroll factor of this Container and optionally all of its children. + * Iterate through the group members changing the position of each element to be that of the element that came before + * it in the array (or after it if direction = 1) * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. + * The first group member position is set to x/y. * - * @method Phaser.GameObjects.Container#setScrollFactor - * @since 3.4.0 + * @method Phaser.GameObjects.Group#shiftPosition + * @since 3.21.0 * - * @param {number} x - The horizontal scroll factor of this Game Object. - * @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value. - * @param {boolean} [updateChildren=false] - Apply this scrollFactor to all Container children as well? + * @param {number} x - The x coordinate to place the first item in the array at. + * @param {number} y - The y coordinate to place the first item in the array at. + * @param {number} [direction=0] - The iteration direction. 0 = first to last and 1 = last to first. * - * @return {this} This Game Object instance. + * @return {this} This Group object. */ - setScrollFactor: function (x, y, updateChildren) + shiftPosition: function (x, y, direction) { - if (y === undefined) { y = x; } - if (updateChildren === undefined) { updateChildren = false; } - - this.scrollFactorX = x; - this.scrollFactorY = y; - - if (updateChildren) - { - ArrayUtils.SetAll(this.list, 'scrollFactorX', x); - ArrayUtils.SetAll(this.list, 'scrollFactorY', y); - } + Actions.ShiftPosition(this.children.entries, x, y, direction); return this; }, /** - * The number of Game Objects inside this Container. - * - * @name Phaser.GameObjects.Container#length - * @type {number} - * @readonly - * @since 3.4.0 - */ - length: { - - get: function () - { - return this.list.length; - } - - }, - - /** - * Returns the first Game Object within the Container, or `null` if it is empty. - * - * You can move the cursor by calling `Container.next` and `Container.previous`. - * - * @name Phaser.GameObjects.Container#first - * @type {?Phaser.GameObjects.GameObject} - * @readonly - * @since 3.4.0 - */ - first: { - - get: function () - { - this.position = 0; - - if (this.list.length > 0) - { - return this.list[0]; - } - else - { - return null; - } - } - - }, - - /** - * Returns the last Game Object within the Container, or `null` if it is empty. - * - * You can move the cursor by calling `Container.next` and `Container.previous`. - * - * @name Phaser.GameObjects.Container#last - * @type {?Phaser.GameObjects.GameObject} - * @readonly - * @since 3.4.0 - */ - last: { - - get: function () - { - if (this.list.length > 0) - { - this.position = this.list.length - 1; - - return this.list[this.position]; - } - else - { - return null; - } - } - - }, - - /** - * Returns the next Game Object within the Container, or `null` if it is empty. - * - * You can move the cursor by calling `Container.next` and `Container.previous`. - * - * @name Phaser.GameObjects.Container#next - * @type {?Phaser.GameObjects.GameObject} - * @readonly - * @since 3.4.0 - */ - next: { - - get: function () - { - if (this.position < this.list.length) - { - this.position++; - - return this.list[this.position]; - } - else - { - return null; - } - } - - }, - - /** - * Returns the previous Game Object within the Container, or `null` if it is empty. - * - * You can move the cursor by calling `Container.next` and `Container.previous`. - * - * @name Phaser.GameObjects.Container#previous - * @type {?Phaser.GameObjects.GameObject} - * @readonly - * @since 3.4.0 - */ - previous: { - - get: function () - { - if (this.position > 0) - { - this.position--; - - return this.list[this.position]; - } - else - { - return null; - } - } - - }, - - /** - * Internal destroy handler, called as part of the destroy process. - * - * @method Phaser.GameObjects.Container#preDestroy - * @protected - * @since 3.9.0 - */ - preDestroy: function () - { - this.removeAll(!!this.exclusive); - - this.localTransform.destroy(); - this.tempTransformMatrix.destroy(); - - this.list = []; - } - -}); - -module.exports = Container; - - -/***/ }), -/* 215 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BitmapText = __webpack_require__(148); -var Class = __webpack_require__(0); -var Render = __webpack_require__(1057); - -/** - * @classdesc - * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. - * - * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to - * match the font structure. - * - * Dynamic Bitmap Text objects are different from Static Bitmap Text in that they invoke a callback for each - * letter being rendered during the render pass. This callback allows you to manipulate the properties of - * each letter being rendered, such as its position, scale or tint, allowing you to create interesting effects - * like jiggling text, which can't be done with Static text. This means that Dynamic Text takes more processing - * time, so only use them if you require the callback ability they have. - * - * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability - * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by - * processing the font texture in an image editor, applying fills and any other effects required. - * - * To create multi-line text insert \r, \n or \r\n escape codes into the text string. - * - * To create a BitmapText data files you need a 3rd party app such as: - * - * BMFont (Windows, free): {@link http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/} - * Glyph Designer (OS X, commercial): {@link http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner} - * Littera (Web-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/} - * - * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of - * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: {@link http://codebeautify.org/xmltojson|http://codebeautify.org/xmltojson} - * - * @class DynamicBitmapText - * @extends Phaser.GameObjects.BitmapText - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. It can only belong to one Scene at any given time. - * @param {number} x - The x coordinate of this Game Object in world space. - * @param {number} y - The y coordinate of this Game Object in world space. - * @param {string} font - The key of the font to use from the Bitmap Font cache. - * @param {(string|string[])} [text] - The string, or array of strings, to be set as the content of this Bitmap Text. - * @param {number} [size] - The font size of this Bitmap Text. - * @param {number} [align=0] - The alignment of the text in a multi-line BitmapText object. - */ -var DynamicBitmapText = new Class({ - - Extends: BitmapText, - - Mixins: [ - Render - ], - - initialize: - - function DynamicBitmapText (scene, x, y, font, text, size, align) - { - BitmapText.call(this, scene, x, y, font, text, size, align); - - this.type = 'DynamicBitmapText'; - - /** - * The horizontal scroll position of the Bitmap Text. - * - * @name Phaser.GameObjects.DynamicBitmapText#scrollX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.scrollX = 0; - - /** - * The vertical scroll position of the Bitmap Text. - * - * @name Phaser.GameObjects.DynamicBitmapText#scrollY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.scrollY = 0; - - /** - * The crop width of the Bitmap Text. - * - * @name Phaser.GameObjects.DynamicBitmapText#cropWidth - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.cropWidth = 0; - - /** - * The crop height of the Bitmap Text. - * - * @name Phaser.GameObjects.DynamicBitmapText#cropHeight - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.cropHeight = 0; - - /** - * A callback that alters how each character of the Bitmap Text is rendered. - * - * @name Phaser.GameObjects.DynamicBitmapText#displayCallback - * @type {Phaser.Types.GameObjects.BitmapText.DisplayCallback} - * @since 3.0.0 - */ - this.displayCallback; - - /** - * The data object that is populated during rendering, then passed to the displayCallback. - * You should modify this object then return it back from the callback. It's updated values - * will be used to render the specific glyph. - * - * Please note that if you need a reference to this object locally in your game code then you - * should shallow copy it, as it's updated and re-used for every glyph in the text. - * - * @name Phaser.GameObjects.DynamicBitmapText#callbackData - * @type {Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig} - * @since 3.11.0 - */ - this.callbackData = { - parent: this, - color: 0, - tint: { - topLeft: 0, - topRight: 0, - bottomLeft: 0, - bottomRight: 0 - }, - index: 0, - charCode: 0, - x: 0, - y: 0, - scale: 0, - rotation: 0, - data: 0 - }; - }, - - /** - * Set the crop size of this Bitmap Text. + * Sets the angle of each group member. * - * @method Phaser.GameObjects.DynamicBitmapText#setSize - * @since 3.0.0 + * @method Phaser.GameObjects.Group#angle + * @since 3.21.0 * - * @param {number} width - The width of the crop. - * @param {number} height - The height of the crop. + * @param {number} value - The amount to set the angle to, in degrees. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - setSize: function (width, height) + angle: function (value, step) { - this.cropWidth = width; - this.cropHeight = height; + Actions.Angle(this.children.entries, value, step); return this; }, /** - * Set a callback that alters how each character of the Bitmap Text is rendered. - * - * The callback receives a {@link Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig} object that contains information about the character that's - * about to be rendered. - * - * It should return an object with `x`, `y`, `scale` and `rotation` properties that will be used instead of the - * usual values when rendering. + * Sets the rotation of each group member. * - * @method Phaser.GameObjects.DynamicBitmapText#setDisplayCallback - * @since 3.0.0 + * @method Phaser.GameObjects.Group#rotate + * @since 3.21.0 * - * @param {Phaser.Types.GameObjects.BitmapText.DisplayCallback} callback - The display callback to set. + * @param {number} value - The amount to set the rotation to, in radians. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - setDisplayCallback: function (callback) + rotate: function (value, step) { - this.displayCallback = callback; + Actions.Rotate(this.children.entries, value, step); return this; }, /** - * Set the horizontal scroll position of this Bitmap Text. + * Rotates each group member around the given point by the given angle. * - * @method Phaser.GameObjects.DynamicBitmapText#setScrollX - * @since 3.0.0 + * @method Phaser.GameObjects.Group#rotateAround + * @since 3.21.0 * - * @param {number} value - The horizontal scroll position to set. + * @param {Phaser.Types.Math.Vector2Like} point - Any object with public `x` and `y` properties. + * @param {number} angle - The angle to rotate by, in radians. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - setScrollX: function (value) + rotateAround: function (point, angle) { - this.scrollX = value; + Actions.RotateAround(this.children.entries, point, angle); return this; }, /** - * Set the vertical scroll position of this Bitmap Text. + * Rotates each group member around the given point by the given angle and distance. * - * @method Phaser.GameObjects.DynamicBitmapText#setScrollY - * @since 3.0.0 + * @method Phaser.GameObjects.Group#rotateAroundDistance + * @since 3.21.0 * - * @param {number} value - The vertical scroll position to set. + * @param {Phaser.Types.Math.Vector2Like} point - Any object with public `x` and `y` properties. + * @param {number} angle - The angle to rotate by, in radians. + * @param {number} distance - The distance from the point of rotation in pixels. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - setScrollY: function (value) + rotateAroundDistance: function (point, angle, distance) { - this.scrollY = value; + Actions.RotateAroundDistance(this.children.entries, point, angle, distance); return this; - } - -}); - -module.exports = DynamicBitmapText; - - -/***/ }), -/* 216 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var BaseCamera = __webpack_require__(133); -var Class = __webpack_require__(0); -var Commands = __webpack_require__(217); -var ComponentsAlpha = __webpack_require__(303); -var ComponentsBlendMode = __webpack_require__(304); -var ComponentsDepth = __webpack_require__(305); -var ComponentsMask = __webpack_require__(309); -var ComponentsPipeline = __webpack_require__(167); -var ComponentsScrollFactor = __webpack_require__(312); -var ComponentsTransform = __webpack_require__(313); -var ComponentsVisible = __webpack_require__(314); -var Ellipse = __webpack_require__(111); -var GameObject = __webpack_require__(15); -var GetFastValue = __webpack_require__(2); -var GetValue = __webpack_require__(6); -var MATH_CONST = __webpack_require__(14); -var Render = __webpack_require__(1063); - -/** - * @classdesc - * A Graphics object is a way to draw primitive shapes to your game. Primitives include forms of geometry, such as - * Rectangles, Circles, and Polygons. They also include lines, arcs and curves. When you initially create a Graphics - * object it will be empty. - * - * To draw to it you must first specify a line style or fill style (or both), draw shapes using paths, and finally - * fill or stroke them. For example: - * - * ```javascript - * graphics.lineStyle(5, 0xFF00FF, 1.0); - * graphics.beginPath(); - * graphics.moveTo(100, 100); - * graphics.lineTo(200, 200); - * graphics.closePath(); - * graphics.strokePath(); - * ``` - * - * There are also many helpful methods that draw and fill/stroke common shapes for you. - * - * ```javascript - * graphics.lineStyle(5, 0xFF00FF, 1.0); - * graphics.fillStyle(0xFFFFFF, 1.0); - * graphics.fillRect(50, 50, 400, 200); - * graphics.strokeRect(50, 50, 400, 200); - * ``` - * - * When a Graphics object is rendered it will render differently based on if the game is running under Canvas or WebGL. - * Under Canvas it will use the HTML Canvas context drawing operations to draw the path. - * Under WebGL the graphics data is decomposed into polygons. Both of these are expensive processes, especially with - * complex shapes. - * - * If your Graphics object doesn't change much (or at all) once you've drawn your shape to it, then you will help - * performance by calling {@link Phaser.GameObjects.Graphics#generateTexture}. This will 'bake' the Graphics object into - * a Texture, and return it. You can then use this Texture for Sprites or other display objects. If your Graphics object - * updates frequently then you should avoid doing this, as it will constantly generate new textures, which will consume - * memory. - * - * As you can tell, Graphics objects are a bit of a trade-off. While they are extremely useful, you need to be careful - * in their complexity and quantity of them in your game. - * - * @class Graphics - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.AlphaSingle - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.Visible - * @extends Phaser.GameObjects.Components.ScrollFactor - * - * @param {Phaser.Scene} scene - The Scene to which this Graphics object belongs. - * @param {Phaser.Types.GameObjects.Graphics.Options} [options] - Options that set the position and default style of this Graphics object. - */ -var Graphics = new Class({ - - Extends: GameObject, - - Mixins: [ - ComponentsAlpha, - ComponentsBlendMode, - ComponentsDepth, - ComponentsMask, - ComponentsPipeline, - ComponentsTransform, - ComponentsVisible, - ComponentsScrollFactor, - Render - ], - - initialize: - - function Graphics (scene, options) - { - var x = GetValue(options, 'x', 0); - var y = GetValue(options, 'y', 0); - - GameObject.call(this, scene, 'Graphics'); - - this.setPosition(x, y); - this.initPipeline(); - - /** - * The horizontal display origin of the Graphics. - * - * @name Phaser.GameObjects.Graphics#displayOriginX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.displayOriginX = 0; - - /** - * The vertical display origin of the Graphics. - * - * @name Phaser.GameObjects.Graphics#displayOriginY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.displayOriginY = 0; - - /** - * The array of commands used to render the Graphics. - * - * @name Phaser.GameObjects.Graphics#commandBuffer - * @type {array} - * @default [] - * @since 3.0.0 - */ - this.commandBuffer = []; - - /** - * The default fill color for shapes rendered by this Graphics object. - * - * @name Phaser.GameObjects.Graphics#defaultFillColor - * @type {number} - * @default -1 - * @since 3.0.0 - */ - this.defaultFillColor = -1; - - /** - * The default fill alpha for shapes rendered by this Graphics object. - * - * @name Phaser.GameObjects.Graphics#defaultFillAlpha - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.defaultFillAlpha = 1; - - /** - * The default stroke width for shapes rendered by this Graphics object. - * - * @name Phaser.GameObjects.Graphics#defaultStrokeWidth - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.defaultStrokeWidth = 1; - - /** - * The default stroke color for shapes rendered by this Graphics object. - * - * @name Phaser.GameObjects.Graphics#defaultStrokeColor - * @type {number} - * @default -1 - * @since 3.0.0 - */ - this.defaultStrokeColor = -1; - - /** - * The default stroke alpha for shapes rendered by this Graphics object. - * - * @name Phaser.GameObjects.Graphics#defaultStrokeAlpha - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.defaultStrokeAlpha = 1; - - /** - * Internal property that keeps track of the line width style setting. - * - * @name Phaser.GameObjects.Graphics#_lineWidth - * @type {number} - * @private - * @since 3.0.0 - */ - this._lineWidth = 1.0; - - this.setDefaultStyles(options); }, /** - * Set the default style settings for this Graphics object. + * Sets the alpha of each group member. * - * @method Phaser.GameObjects.Graphics#setDefaultStyles - * @since 3.0.0 + * @method Phaser.GameObjects.Group#setAlpha + * @since 3.21.0 * - * @param {Phaser.Types.GameObjects.Graphics.Styles} options - The styles to set as defaults. + * @param {number} value - The amount to set the alpha to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - setDefaultStyles: function (options) + setAlpha: function (value, step) { - if (GetValue(options, 'lineStyle', null)) - { - this.defaultStrokeWidth = GetValue(options, 'lineStyle.width', 1); - this.defaultStrokeColor = GetValue(options, 'lineStyle.color', 0xffffff); - this.defaultStrokeAlpha = GetValue(options, 'lineStyle.alpha', 1); - - this.lineStyle(this.defaultStrokeWidth, this.defaultStrokeColor, this.defaultStrokeAlpha); - } - - if (GetValue(options, 'fillStyle', null)) - { - this.defaultFillColor = GetValue(options, 'fillStyle.color', 0xffffff); - this.defaultFillAlpha = GetValue(options, 'fillStyle.alpha', 1); - - this.fillStyle(this.defaultFillColor, this.defaultFillAlpha); - } + Actions.SetAlpha(this.children.entries, value, step); return this; }, /** - * Set the current line style. + * Sets the tint of each group member. * - * @method Phaser.GameObjects.Graphics#lineStyle - * @since 3.0.0 + * @method Phaser.GameObjects.Group#setTint + * @since 3.21.0 * - * @param {number} lineWidth - The stroke width. - * @param {number} color - The stroke color. - * @param {number} [alpha=1] - The stroke alpha. + * @param {number} topLeft - The tint being applied to top-left corner of item. If other parameters are given no value, this tint will be applied to whole item. + * @param {number} [topRight] - The tint to be applied to top-right corner of item. + * @param {number} [bottomLeft] - The tint to be applied to the bottom-left corner of item. + * @param {number} [bottomRight] - The tint to be applied to the bottom-right corner of item. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - lineStyle: function (lineWidth, color, alpha) + setTint: function (topLeft, topRight, bottomLeft, bottomRight) { - if (alpha === undefined) { alpha = 1; } - - this.commandBuffer.push( - Commands.LINE_STYLE, - lineWidth, color, alpha - ); - - this._lineWidth = lineWidth; + Actions.SetTint(this.children.entries, topLeft, topRight, bottomLeft, bottomRight); return this; }, /** - * Set the current fill style. + * Sets the originX, originY of each group member. * - * @method Phaser.GameObjects.Graphics#fillStyle - * @since 3.0.0 + * @method Phaser.GameObjects.Group#setOrigin + * @since 3.21.0 * - * @param {number} color - The fill color. - * @param {number} [alpha=1] - The fill alpha. + * @param {number} originX - The amount to set the `originX` property to. + * @param {number} [originY] - The amount to set the `originY` property to. If `undefined` or `null` it uses the `originX` value. + * @param {number} [stepX=0] - This is added to the `originX` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `originY` amount, multiplied by the iteration counter. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - fillStyle: function (color, alpha) + setOrigin: function (originX, originY, stepX, stepY) { - if (alpha === undefined) { alpha = 1; } - - this.commandBuffer.push( - Commands.FILL_STYLE, - color, alpha - ); + Actions.SetOrigin(this.children.entries, originX, originY, stepX, stepY); return this; }, /** - * Sets a gradient fill style. This is a WebGL only feature. - * - * The gradient color values represent the 4 corners of an untransformed rectangle. - * The gradient is used to color all filled shapes and paths drawn after calling this method. - * If you wish to turn a gradient off, call `fillStyle` and provide a new single fill color. - * - * When filling a triangle only the first 3 color values provided are used for the 3 points of a triangle. - * - * This feature is best used only on rectangles and triangles. All other shapes will give strange results. - * - * Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used - * will be filled with a gradient on its own. There is no ability to gradient fill a shape or path as a single - * entity at this time. + * Sets the scaleX of each group member. * - * @method Phaser.GameObjects.Graphics#fillGradientStyle - * @webglOnly - * @since 3.12.0 + * @method Phaser.GameObjects.Group#scaleX + * @since 3.21.0 * - * @param {number} topLeft - The top left fill color. - * @param {number} topRight - The top right fill color. - * @param {number} bottomLeft - The bottom left fill color. - * @param {number} bottomRight - The bottom right fill color. Not used when filling triangles. - * @param {number} [alphaTopLeft=1] - The top left alpha value. If you give only this value, it's used for all corners. - * @param {number} [alphaTopRight=1] - The top right alpha value. - * @param {number} [alphaBottomLeft=1] - The bottom left alpha value. - * @param {number} [alphaBottomRight=1] - The bottom right alpha value. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - fillGradientStyle: function (topLeft, topRight, bottomLeft, bottomRight, alphaTopLeft, alphaTopRight, alphaBottomLeft, alphaBottomRight) + scaleX: function (value, step) { - if (alphaTopLeft === undefined) { alphaTopLeft = 1; } - if (alphaTopRight === undefined) { alphaTopRight = alphaTopLeft; } - if (alphaBottomLeft === undefined) { alphaBottomLeft = alphaTopLeft; } - if (alphaBottomRight === undefined) { alphaBottomRight = alphaTopLeft; } - - this.commandBuffer.push( - Commands.GRADIENT_FILL_STYLE, - alphaTopLeft, alphaTopRight, alphaBottomLeft, alphaBottomRight, - topLeft, topRight, bottomLeft, bottomRight - ); + Actions.ScaleX(this.children.entries, value, step); return this; }, /** - * Sets a gradient line style. This is a WebGL only feature. - * - * The gradient color values represent the 4 corners of an untransformed rectangle. - * The gradient is used to color all stroked shapes and paths drawn after calling this method. - * If you wish to turn a gradient off, call `lineStyle` and provide a new single line color. - * - * This feature is best used only on single lines. All other shapes will give strange results. - * - * Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used - * will be filled with a gradient on its own. There is no ability to gradient stroke a shape or path as a single - * entity at this time. + * Sets the scaleY of each group member. * - * @method Phaser.GameObjects.Graphics#lineGradientStyle - * @webglOnly - * @since 3.12.0 + * @method Phaser.GameObjects.Group#scaleY + * @since 3.21.0 * - * @param {number} lineWidth - The stroke width. - * @param {number} topLeft - The tint being applied to the top-left of the Game Object. - * @param {number} topRight - The tint being applied to the top-right of the Game Object. - * @param {number} bottomLeft - The tint being applied to the bottom-left of the Game Object. - * @param {number} bottomRight - The tint being applied to the bottom-right of the Game Object. - * @param {number} [alpha=1] - The fill alpha. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - lineGradientStyle: function (lineWidth, topLeft, topRight, bottomLeft, bottomRight, alpha) + scaleY: function (value, step) { - if (alpha === undefined) { alpha = 1; } - - this.commandBuffer.push( - Commands.GRADIENT_LINE_STYLE, - lineWidth, alpha, topLeft, topRight, bottomLeft, bottomRight - ); + Actions.ScaleY(this.children.entries, value, step); return this; }, /** - * Start a new shape path. - * - * @method Phaser.GameObjects.Graphics#beginPath - * @since 3.0.0 + * Sets the scaleX, scaleY of each group member. * - * @return {this} This Game Object. - */ - beginPath: function () - { - this.commandBuffer.push( - Commands.BEGIN_PATH - ); - - return this; - }, - - /** - * Close the current path. + * @method Phaser.GameObjects.Group#scaleXY + * @since 3.21.0 * - * @method Phaser.GameObjects.Graphics#closePath - * @since 3.0.0 + * @param {number} scaleX - The amount to be added to the `scaleX` property. + * @param {number} [scaleY] - The amount to be added to the `scaleY` property. If `undefined` or `null` it uses the `scaleX` value. + * @param {number} [stepX=0] - This is added to the `scaleX` amount, multiplied by the iteration counter. + * @param {number} [stepY=0] - This is added to the `scaleY` amount, multiplied by the iteration counter. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - closePath: function () + scaleXY: function (scaleX, scaleY, stepX, stepY) { - this.commandBuffer.push( - Commands.CLOSE_PATH - ); + Actions.ScaleXY(this.children.entries, scaleX, scaleY, stepX, stepY); return this; }, /** - * Fill the current path. + * Sets the depth of each group member. * - * @method Phaser.GameObjects.Graphics#fillPath + * @method Phaser.GameObjects.Group#setDepth * @since 3.0.0 * - * @return {this} This Game Object. + * @param {number} value - The amount to set the property to. + * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. + * + * @return {this} This Group object. */ - fillPath: function () + setDepth: function (value, step) { - this.commandBuffer.push( - Commands.FILL_PATH - ); + Actions.SetDepth(this.children.entries, value, step); return this; }, /** - * Fill the current path. + * Sets the blendMode of each group member. * - * This is an alias for `Graphics.fillPath` and does the same thing. - * It was added to match the CanvasRenderingContext 2D API. + * @method Phaser.GameObjects.Group#setBlendMode + * @since 3.21.0 * - * @method Phaser.GameObjects.Graphics#fill - * @since 3.16.0 + * @param {number} value - The amount to set the property to. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - fill: function () + setBlendMode: function (value) { - this.commandBuffer.push( - Commands.FILL_PATH - ); + Actions.SetBlendMode(this.children.entries, value); return this; }, /** - * Stroke the current path. + * Passes all group members to the Input Manager to enable them for input with identical areas and callbacks. * - * @method Phaser.GameObjects.Graphics#strokePath - * @since 3.0.0 + * @method Phaser.GameObjects.Group#setHitArea + * @since 3.21.0 * - * @return {this} This Game Object. + * @param {*} hitArea - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. + * @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - A callback to be invoked when the Game Object is interacted with. If you provide a shape you must also provide a callback. + * + * @return {this} This Group object. */ - strokePath: function () + setHitArea: function (hitArea, hitAreaCallback) { - this.commandBuffer.push( - Commands.STROKE_PATH - ); + Actions.SetHitArea(this.children.entries, hitArea, hitAreaCallback); return this; }, /** - * Stroke the current path. - * - * This is an alias for `Graphics.strokePath` and does the same thing. - * It was added to match the CanvasRenderingContext 2D API. + * Shuffles the group members in place. * - * @method Phaser.GameObjects.Graphics#stroke - * @since 3.16.0 + * @method Phaser.GameObjects.Group#shuffle + * @since 3.21.0 * - * @return {this} This Game Object. + * @return {this} This Group object. */ - stroke: function () + shuffle: function () { - this.commandBuffer.push( - Commands.STROKE_PATH - ); + Actions.Shuffle(this.children.entries); return this; }, /** - * Fill the given circle. + * Deactivates a member of this group. * - * @method Phaser.GameObjects.Graphics#fillCircleShape + * @method Phaser.GameObjects.Group#kill * @since 3.0.0 * - * @param {Phaser.Geom.Circle} circle - The circle to fill. - * - * @return {this} This Game Object. + * @param {Phaser.GameObjects.GameObject} gameObject - A member of this group. */ - fillCircleShape: function (circle) + kill: function (gameObject) { - return this.fillCircle(circle.x, circle.y, circle.radius); + if (this.children.contains(gameObject)) + { + gameObject.setActive(false); + } }, /** - * Stroke the given circle. + * Deactivates and hides a member of this group. * - * @method Phaser.GameObjects.Graphics#strokeCircleShape + * @method Phaser.GameObjects.Group#killAndHide * @since 3.0.0 * - * @param {Phaser.Geom.Circle} circle - The circle to stroke. - * - * @return {this} This Game Object. + * @param {Phaser.GameObjects.GameObject} gameObject - A member of this group. */ - strokeCircleShape: function (circle) + killAndHide: function (gameObject) { - return this.strokeCircle(circle.x, circle.y, circle.radius); + if (this.children.contains(gameObject)) + { + gameObject.setActive(false); + gameObject.setVisible(false); + } }, /** - * Fill a circle with the given position and radius. + * Sets the visible of each group member. * - * @method Phaser.GameObjects.Graphics#fillCircle - * @since 3.0.0 + * @method Phaser.GameObjects.Group#setVisible + * @since 3.21.0 * - * @param {number} x - The x coordinate of the center of the circle. - * @param {number} y - The y coordinate of the center of the circle. - * @param {number} radius - The radius of the circle. + * @param {boolean} value - The value to set the property to. + * @param {number} [index=0] - An optional offset to start searching from within the items array. + * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. * - * @return {this} This Game Object. + * @return {this} This Group object. */ - fillCircle: function (x, y, radius) + setVisible: function (value, index, direction) { - this.beginPath(); - this.arc(x, y, radius, 0, MATH_CONST.PI2); - this.fillPath(); + Actions.SetVisible(this.children.entries, value, index, direction); return this; }, /** - * Stroke a circle with the given position and radius. + * Toggles (flips) the visible state of each member of this group. * - * @method Phaser.GameObjects.Graphics#strokeCircle + * @method Phaser.GameObjects.Group#toggleVisible * @since 3.0.0 * - * @param {number} x - The x coordinate of the center of the circle. - * @param {number} y - The y coordinate of the center of the circle. - * @param {number} radius - The radius of the circle. - * - * @return {this} This Game Object. + * @return {this} This Group object. */ - strokeCircle: function (x, y, radius) + toggleVisible: function () { - this.beginPath(); - this.arc(x, y, radius, 0, MATH_CONST.PI2); - this.strokePath(); + Actions.ToggleVisible(this.children.entries); return this; }, /** - * Fill the given rectangle. + * Empties this Group of all children and removes it from the Scene. * - * @method Phaser.GameObjects.Graphics#fillRectShape - * @since 3.0.0 + * Does not call {@link Phaser.GameObjects.Group#removeCallback}. * - * @param {Phaser.Geom.Rectangle} rect - The rectangle to fill. + * Children of this Group will _not_ be removed from the Scene by calling this method + * unless you specify the `removeFromScene` parameter. * - * @return {this} This Game Object. - */ - fillRectShape: function (rect) - { - return this.fillRect(rect.x, rect.y, rect.width, rect.height); - }, - - /** - * Stroke the given rectangle. + * Children of this Group will also _not_ be destroyed by calling this method + * unless you specify the `destroyChildren` parameter. * - * @method Phaser.GameObjects.Graphics#strokeRectShape + * @method Phaser.GameObjects.Group#destroy * @since 3.0.0 * - * @param {Phaser.Geom.Rectangle} rect - The rectangle to stroke. - * - * @return {this} This Game Object. + * @param {boolean} [destroyChildren=false] - Also {@link Phaser.GameObjects.GameObject#destroy} each Group member. + * @param {boolean} [removeFromScene=false] - Optionally remove each Group member from the Scene. */ - strokeRectShape: function (rect) + destroy: function (destroyChildren, removeFromScene) { - return this.strokeRect(rect.x, rect.y, rect.width, rect.height); - }, + if (destroyChildren === undefined) { destroyChildren = false; } + if (removeFromScene === undefined) { removeFromScene = false; } - /** - * Fill a rectangle with the given position and size. - * - * @method Phaser.GameObjects.Graphics#fillRect - * @since 3.0.0 - * - * @param {number} x - The x coordinate of the top-left of the rectangle. - * @param {number} y - The y coordinate of the top-left of the rectangle. - * @param {number} width - The width of the rectangle. - * @param {number} height - The height of the rectangle. - * - * @return {this} This Game Object. - */ - fillRect: function (x, y, width, height) - { - this.commandBuffer.push( - Commands.FILL_RECT, - x, y, width, height - ); + // This Game Object had already been destroyed + if (!this.scene || this.ignoreDestroy) + { + return; + } - return this; - }, + this.emit(Events.DESTROY, this); - /** - * Stroke a rectangle with the given position and size. - * - * @method Phaser.GameObjects.Graphics#strokeRect - * @since 3.0.0 - * - * @param {number} x - The x coordinate of the top-left of the rectangle. - * @param {number} y - The y coordinate of the top-left of the rectangle. - * @param {number} width - The width of the rectangle. - * @param {number} height - The height of the rectangle. - * - * @return {this} This Game Object. - */ - strokeRect: function (x, y, width, height) - { - var lineWidthHalf = this._lineWidth / 2; - var minx = x - lineWidthHalf; - var maxx = x + lineWidthHalf; + this.removeAllListeners(); - this.beginPath(); - this.moveTo(x, y); - this.lineTo(x, y + height); - this.strokePath(); + this.scene.sys.updateList.remove(this); - this.beginPath(); - this.moveTo(x + width, y); - this.lineTo(x + width, y + height); - this.strokePath(); + this.clear(removeFromScene, destroyChildren); - this.beginPath(); - this.moveTo(minx, y); - this.lineTo(maxx + width, y); - this.strokePath(); + this.scene = undefined; + this.children = undefined; + } - this.beginPath(); - this.moveTo(minx, y + height); - this.lineTo(maxx + width, y + height); - this.strokePath(); +}); - return this; - }, +module.exports = Group; - /** - * Fill a rounded rectangle with the given position, size and radius. - * - * @method Phaser.GameObjects.Graphics#fillRoundedRect - * @since 3.11.0 - * - * @param {number} x - The x coordinate of the top-left of the rectangle. - * @param {number} y - The y coordinate of the top-left of the rectangle. - * @param {number} width - The width of the rectangle. - * @param {number} height - The height of the rectangle. - * @param {(Phaser.Types.GameObjects.Graphics.RoundedRectRadius|number)} [radius=20] - The corner radius; It can also be an object to specify different radii for corners. - * - * @return {this} This Game Object. - */ - fillRoundedRect: function (x, y, width, height, radius) + +/***/ }), + +/***/ 61295: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GameObjectCreator = __webpack_require__(99325); +var Group = __webpack_require__(59192); + +/** + * Creates a new Group Game Object and returns it. + * + * Note: This method will only be available if the Group Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#group + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} config - The configuration object this Game Object will use to create itself. + * + * @return {Phaser.GameObjects.Group} The Game Object that was created. + */ +GameObjectCreator.register('group', function (config) +{ + return new Group(this.scene, null, config); +}); + +// When registering a factory function 'this' refers to the GameObjectCreator context. + + +/***/ }), + +/***/ 62598: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Group = __webpack_require__(59192); +var GameObjectFactory = __webpack_require__(61286); + +/** + * Creates a new Group Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Group Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#group + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|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] - A Group Configuration object. + * + * @return {Phaser.GameObjects.Group} The Game Object that was created. + */ +GameObjectFactory.register('group', function (children, config) +{ + return this.updateList.add(new Group(this.scene, children, config)); +}); + + +/***/ }), + +/***/ 1539: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var ImageRender = __webpack_require__(57322); + +/** + * @classdesc + * An Image Game Object. + * + * An Image is a light-weight Game Object useful for the display of static images in your game, + * such as logos, backgrounds, scenery or other non-animated elements. Images can have input + * events and physics bodies, or be tweened, tinted or scrolled. The main difference between an + * Image and a Sprite is that you cannot animate an Image as they do not have the Animation component. + * + * @class Image + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.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.GetBounds + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.TextureCrop + * @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 Image = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.Depth, + Components.Flip, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Size, + Components.TextureCrop, + Components.Tint, + Components.Transform, + Components.Visible, + ImageRender + ], + + initialize: + + function Image (scene, x, y, texture, frame) { - if (radius === undefined) { radius = 20; } + GameObject.call(this, scene, 'Image'); - var tl = radius; - var tr = radius; - var bl = radius; - var br = radius; + /** + * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. + * + * @name Phaser.GameObjects.Image#_crop + * @type {object} + * @private + * @since 3.11.0 + */ + this._crop = this.resetCropObject(); - if (typeof radius !== 'number') - { - tl = GetFastValue(radius, 'tl', 20); - tr = GetFastValue(radius, 'tr', 20); - bl = GetFastValue(radius, 'bl', 20); - br = GetFastValue(radius, 'br', 20); - } + this.setTexture(texture, frame); + this.setPosition(x, y); + this.setSizeToFrame(); + this.setOriginFromFrame(); + this.initPipeline(); + this.initPostPipeline(true); + } - this.beginPath(); - this.moveTo(x + tl, y); - this.lineTo(x + width - tr, y); - this.arc(x + width - tr, y + tr, tr, -MATH_CONST.TAU, 0); - this.lineTo(x + width, y + height - br); - this.arc(x + width - br, y + height - br, br, 0, MATH_CONST.TAU); - this.lineTo(x + bl, y + height); - this.arc(x + bl, y + height - bl, bl, MATH_CONST.TAU, Math.PI); - this.lineTo(x, y + tl); - this.arc(x + tl, y + tl, tl, -Math.PI, -MATH_CONST.TAU); - this.fillPath(); +}); - return this; +module.exports = Image; + + +/***/ }), + +/***/ 57786: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Renders this Game Object with the Canvas Renderer to the given Camera. + * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. + * This method should not be called directly. It is a utility function of the Render module. + * + * @method Phaser.GameObjects.Image#renderCanvas + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Image} 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 ImageCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); + + renderer.batchSprite(src, src.frame, camera, parentMatrix); +}; + +module.exports = ImageCanvasRenderer; + + +/***/ }), + +/***/ 83556: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var Image = __webpack_require__(1539); + +/** + * Creates a new Image Game Object and returns it. + * + * Note: This method will only be available if the Image Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#image + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Image} The Game Object that was created. + */ +GameObjectCreator.register('image', function (config, addToScene) +{ + if (config === undefined) { config = {}; } + + var key = GetAdvancedValue(config, 'key', null); + var frame = GetAdvancedValue(config, 'frame', null); + + var image = new Image(this.scene, 0, 0, key, frame); + + if (addToScene !== undefined) + { + config.add = addToScene; + } + + BuildGameObject(this.scene, image, config); + + return image; +}); + +// When registering a factory function 'this' refers to the GameObjectCreator context. + + +/***/ }), + +/***/ 20927: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Image = __webpack_require__(1539); +var GameObjectFactory = __webpack_require__(61286); + +/** + * Creates a new Image Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Image Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#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.GameObjects.Image} The Game Object that was created. + */ +GameObjectFactory.register('image', function (x, y, texture, frame) +{ + return this.displayList.add(new Image(this.scene, x, y, texture, frame)); +}); + +// When registering a factory function 'this' refers to the GameObjectFactory 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 + + +/***/ }), + +/***/ 57322: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(59390); +} + +if (true) +{ + renderCanvas = __webpack_require__(57786); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 59390: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Renders this Game Object with the WebGL Renderer to the given Camera. + * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. + * This method should not be called directly. It is a utility function of the Render module. + * + * @method Phaser.GameObjects.Image#renderWebGL + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Image} 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 ImageWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); + + this.pipeline.batchSprite(src, camera, parentMatrix); +}; + +module.exports = ImageWebGLRenderer; + + +/***/ }), + +/***/ 48013: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.GameObjects + */ + +var GameObjects = { + + Events: __webpack_require__(56631), + + DisplayList: __webpack_require__(91713), + GameObjectCreator: __webpack_require__(99325), + GameObjectFactory: __webpack_require__(61286), + UpdateList: __webpack_require__(92034), + + Components: __webpack_require__(64937), + GetCalcMatrix: __webpack_require__(73329), + + BuildGameObject: __webpack_require__(88933), + BuildGameObjectAnimation: __webpack_require__(32291), + GameObject: __webpack_require__(89980), + BitmapText: __webpack_require__(44616), + Blitter: __webpack_require__(52816), + Bob: __webpack_require__(41664), + Container: __webpack_require__(70339), + DOMElement: __webpack_require__(38943), + DynamicBitmapText: __webpack_require__(13468), + Extern: __webpack_require__(39419), + Graphics: __webpack_require__(33182), + Group: __webpack_require__(59192), + Image: __webpack_require__(1539), + Layer: __webpack_require__(85305), + Particles: __webpack_require__(27684), + PathFollower: __webpack_require__(29598), + RenderTexture: __webpack_require__(15996), + RetroFont: __webpack_require__(55873), + Rope: __webpack_require__(79968), + Sprite: __webpack_require__(13747), + + Text: __webpack_require__(76555), + GetTextSize: __webpack_require__(32979), + MeasureText: __webpack_require__(27030), + TextStyle: __webpack_require__(74744), + + TileSprite: __webpack_require__(35856), + Zone: __webpack_require__(71030), + Video: __webpack_require__(8630), + + // Shapes + + Shape: __webpack_require__(91461), + Arc: __webpack_require__(28593), + Curve: __webpack_require__(15220), + Ellipse: __webpack_require__(28591), + Grid: __webpack_require__(39169), + IsoBox: __webpack_require__(4415), + IsoTriangle: __webpack_require__(65159), + Line: __webpack_require__(579), + Polygon: __webpack_require__(91249), + Rectangle: __webpack_require__(517), + Star: __webpack_require__(77843), + Triangle: __webpack_require__(21873), + + // Game Object Factories + + Factories: { + Blitter: __webpack_require__(38906), + Container: __webpack_require__(23400), + DOMElement: __webpack_require__(66788), + DynamicBitmapText: __webpack_require__(94145), + Extern: __webpack_require__(41155), + Graphics: __webpack_require__(13122), + Group: __webpack_require__(62598), + Image: __webpack_require__(20927), + Layer: __webpack_require__(17676), + Particles: __webpack_require__(81212), + PathFollower: __webpack_require__(19626), + RenderTexture: __webpack_require__(29599), + Rope: __webpack_require__(31982), + Sprite: __webpack_require__(66135), + StaticBitmapText: __webpack_require__(21797), + Text: __webpack_require__(94627), + TileSprite: __webpack_require__(20509), + Zone: __webpack_require__(34546), + Video: __webpack_require__(215), + + // Shapes + Arc: __webpack_require__(10369), + Curve: __webpack_require__(10147), + Ellipse: __webpack_require__(99869), + Grid: __webpack_require__(9326), + IsoBox: __webpack_require__(88154), + IsoTriangle: __webpack_require__(67765), + Line: __webpack_require__(85665), + Polygon: __webpack_require__(88203), + Rectangle: __webpack_require__(94355), + Star: __webpack_require__(23962), + Triangle: __webpack_require__(79296) }, - /** - * Stroke a rounded rectangle with the given position, size and radius. - * - * @method Phaser.GameObjects.Graphics#strokeRoundedRect - * @since 3.11.0 - * - * @param {number} x - The x coordinate of the top-left of the rectangle. - * @param {number} y - The y coordinate of the top-left of the rectangle. - * @param {number} width - The width of the rectangle. - * @param {number} height - The height of the rectangle. - * @param {(Phaser.Types.GameObjects.Graphics.RoundedRectRadius|number)} [radius=20] - The corner radius; It can also be an object to specify different radii for corners. - * - * @return {this} This Game Object. - */ - strokeRoundedRect: function (x, y, width, height, radius) + Creators: { + Blitter: __webpack_require__(68452), + Container: __webpack_require__(44516), + DynamicBitmapText: __webpack_require__(67513), + Graphics: __webpack_require__(41286), + Group: __webpack_require__(61295), + Image: __webpack_require__(83556), + Layer: __webpack_require__(56378), + Particles: __webpack_require__(765), + RenderTexture: __webpack_require__(85692), + Rope: __webpack_require__(96027), + Sprite: __webpack_require__(89219), + StaticBitmapText: __webpack_require__(95499), + Text: __webpack_require__(75397), + TileSprite: __webpack_require__(63950), + Zone: __webpack_require__(24067), + Video: __webpack_require__(65601) + } + +}; + +// WebGL only Game Objects +if (true) +{ + GameObjects.Shader = __webpack_require__(27902); + GameObjects.Mesh = __webpack_require__(83321); + GameObjects.NineSlice = __webpack_require__(44139); + GameObjects.PointLight = __webpack_require__(13171); + GameObjects.Plane = __webpack_require__(33412); + + GameObjects.Factories.Shader = __webpack_require__(51979); + GameObjects.Factories.Mesh = __webpack_require__(8767); + GameObjects.Factories.NineSlice = __webpack_require__(53778); + GameObjects.Factories.PointLight = __webpack_require__(91201); + GameObjects.Factories.Plane = __webpack_require__(58322); + + GameObjects.Creators.Shader = __webpack_require__(13908); + GameObjects.Creators.Mesh = __webpack_require__(41839); + GameObjects.Creators.NineSlice = __webpack_require__(40964); + GameObjects.Creators.PointLight = __webpack_require__(162); + GameObjects.Creators.Plane = __webpack_require__(10912); + + GameObjects.Light = __webpack_require__(14455); + GameObjects.LightsManager = __webpack_require__(26193); + GameObjects.LightsPlugin = __webpack_require__(50296); +} + +module.exports = GameObjects; + + +/***/ }), + +/***/ 85305: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BlendModes = __webpack_require__(95723); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var ComponentsToJSON = __webpack_require__(48129); +var DataManager = __webpack_require__(81078); +var EventEmitter = __webpack_require__(6659); +var GameObjectEvents = __webpack_require__(56631); +var List = __webpack_require__(71207); +var Render = __webpack_require__(58010); +var SceneEvents = __webpack_require__(7599); +var StableSort = __webpack_require__(17922); + +/** + * @classdesc + * A Layer Game Object. + * + * A Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object + * to a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game + * Objects: + * + * ```javascript + * const spaceman = this.add.sprite(150, 300, 'spaceman'); + * const bunny = this.add.sprite(400, 300, 'bunny'); + * const elephant = this.add.sprite(650, 300, 'elephant'); + * + * const layer = this.add.layer(); + * + * layer.add([ spaceman, bunny, elephant ]); + * ``` + * + * The 3 sprites in the example above will now be managed by the Layer they were added to. Therefore, + * if you then set `layer.setVisible(false)` they would all vanish from the display. + * + * You can also control the depth of the Game Objects within the Layer. For example, calling the + * `setDepth` method of a child of a Layer will allow you to adjust the depth of that child _within the + * Layer itself_, rather than the whole Scene. The Layer, too, can have its depth set as well. + * + * The Layer class also offers many different methods for manipulating the list, such as the + * methods `moveUp`, `moveDown`, `sendToBack`, `bringToTop` and so on. These allow you to change the + * display list position of the Layers children, causing it to adjust the order in which they are + * rendered. Using `setDepth` on a child allows you to override this. + * + * Layers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across + * a whole range of children, which, depending on the effect, can often be far more efficient that doing so + * on a per-child basis. + * + * Layers have no position or size within the Scene. This means you cannot enable a Layer for + * physics or input, or change the position, rotation or scale of a Layer. They also have no scroll + * factor, texture, tint, origin, crop or bounds. + * + * If you need those kind of features then you should use a Container instead. Containers can be added + * to Layers, but Layers cannot be added to Containers. + * + * However, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings + * will impact all children being rendered by the Layer. + * + * @class Layer + * @extends Phaser.Structs.List. + * @memberof Phaser.GameObjects + * @constructor + * @since 3.50.0 + * + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.PostPipeline + * @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 {Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Layer. + */ +var Layer = new Class({ + + Extends: List, + + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.Depth, + Components.Mask, + Components.PostPipeline, + Components.Visible, + EventEmitter, + Render + ], + + initialize: + + function Layer (scene, children) { - if (radius === undefined) { radius = 20; } + List.call(this, scene); + EventEmitter.call(this); - var tl = radius; - var tr = radius; - var bl = radius; - var br = radius; + /** + * A reference to the Scene to which this Game Object belongs. + * + * Game Objects can only belong to one Scene. + * + * You should consider this property as being read-only. You cannot move a + * Game Object to another Scene by simply changing it. + * + * @name Phaser.GameObjects.Layer#scene + * @type {Phaser.Scene} + * @since 3.50.0 + */ + this.scene = scene; - if (typeof radius !== 'number') + /** + * Holds a reference to the Display List that contains this Game Object. + * + * This is set automatically when this Game Object is added to a Scene or Layer. + * + * You should treat this property as being read-only. + * + * @name Phaser.GameObjects.Layer#displayList + * @type {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} + * @default null + * @since 3.50.0 + */ + this.displayList = null; + + /** + * A textual representation of this Game Object, i.e. `sprite`. + * Used internally by Phaser but is available for your own custom classes to populate. + * + * @name Phaser.GameObjects.Layer#type + * @type {string} + * @since 3.50.0 + */ + this.type = 'Layer'; + + /** + * The current state of this Game Object. + * + * Phaser itself will never modify this value, although plugins may do so. + * + * Use this property to track the state of a Game Object during its lifetime. For example, it could change from + * a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant + * in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons. + * If you need to store complex data about your Game Object, look at using the Data Component instead. + * + * @name Phaser.GameObjects.Layer#state + * @type {(number|string)} + * @since 3.50.0 + */ + this.state = 0; + + /** + * A Layer cannot be placed inside a Container. + * + * This property is kept purely so a Layer has the same + * shape as a Game Object. + * + * @name Phaser.GameObjects.Layer#parentContainer + * @type {Phaser.GameObjects.Container} + * @since 3.51.0 + */ + this.parentContainer = null; + + /** + * The name of this Game Object. + * Empty by default and never populated by Phaser, this is left for developers to use. + * + * @name Phaser.GameObjects.Layer#name + * @type {string} + * @default '' + * @since 3.50.0 + */ + this.name = ''; + + /** + * The active state of this Game Object. + * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it. + * An active object is one which is having its logic and internal systems updated. + * + * @name Phaser.GameObjects.Layer#active + * @type {boolean} + * @default true + * @since 3.50.0 + */ + this.active = true; + + /** + * The Tab Index of the Game Object. + * Reserved for future use by plugins and the Input Manager. + * + * @name Phaser.GameObjects.Layer#tabIndex + * @type {number} + * @default -1 + * @since 3.51.0 + */ + this.tabIndex = -1; + + /** + * A Data Manager. + * It allows you to store, query and get key/value paired information specific to this Game Object. + * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`. + * + * @name Phaser.GameObjects.Layer#data + * @type {Phaser.Data.DataManager} + * @default null + * @since 3.50.0 + */ + this.data = null; + + /** + * The flags that are compared against `RENDER_MASK` to determine if this Game Object will render or not. + * The bits are 0001 | 0010 | 0100 | 1000 set by the components Visible, Alpha, Transform and Texture respectively. + * If those components are not used by your custom class then you can use this bitmask as you wish. + * + * @name Phaser.GameObjects.Layer#renderFlags + * @type {number} + * @default 15 + * @since 3.50.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.Layer#cameraFilter + * @type {number} + * @default 0 + * @since 3.50.0 + */ + this.cameraFilter = 0; + + /** + * This property is kept purely so a Layer has the same + * shape as a Game Object. You cannot input enable a Layer. + * + * @name Phaser.GameObjects.Layer#input + * @type {?Phaser.Types.Input.InteractiveObject} + * @default null + * @since 3.51.0 + */ + this.input = null; + + /** + * This property is kept purely so a Layer has the same + * shape as a Game Object. You cannot give a Layer a physics body. + * + * @name Phaser.GameObjects.Layer#body + * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|MatterJS.BodyType)} + * @default null + * @since 3.51.0 + */ + this.body = null; + + /** + * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`. + * This includes calls that may come from a Group, Container or the Scene itself. + * While it allows you to persist a Game Object across Scenes, please understand you are entirely + * responsible for managing references to and from this Game Object. + * + * @name Phaser.GameObjects.Layer#ignoreDestroy + * @type {boolean} + * @default false + * @since 3.50.0 + */ + this.ignoreDestroy = false; + + /** + * A reference to the Scene Systems. + * + * @name Phaser.GameObjects.Layer#systems + * @type {Phaser.Scenes.Systems} + * @since 3.50.0 + */ + this.systems = scene.sys; + + /** + * A reference to the Scene Event Emitter. + * + * @name Phaser.GameObjects.Layer#events + * @type {Phaser.Events.EventEmitter} + * @since 3.50.0 + */ + this.events = scene.sys.events; + + /** + * The flag the determines whether Game Objects should be sorted when `depthSort()` is called. + * + * @name Phaser.GameObjects.Layer#sortChildrenFlag + * @type {boolean} + * @default false + * @since 3.50.0 + */ + this.sortChildrenFlag = false; + + // Set the List callbacks + this.addCallback = this.addChildCallback; + this.removeCallback = this.removeChildCallback; + + this.initPostPipeline(); + + this.clearAlpha(); + + this.setBlendMode(BlendModes.SKIP_CHECK); + + if (children) { - tl = GetFastValue(radius, 'tl', 20); - tr = GetFastValue(radius, 'tr', 20); - bl = GetFastValue(radius, 'bl', 20); - br = GetFastValue(radius, 'br', 20); + this.add(children); } - this.beginPath(); - this.moveTo(x + tl, y); - this.lineTo(x + width - tr, y); - this.moveTo(x + width - tr, y); - this.arc(x + width - tr, y + tr, tr, -MATH_CONST.TAU, 0); - this.lineTo(x + width, y + height - br); - this.moveTo(x + width, y + height - br); - this.arc(x + width - br, y + height - br, br, 0, MATH_CONST.TAU); - this.lineTo(x + bl, y + height); - this.moveTo(x + bl, y + height); - this.arc(x + bl, y + height - bl, bl, MATH_CONST.TAU, Math.PI); - this.lineTo(x, y + tl); - this.moveTo(x, y + tl); - this.arc(x + tl, y + tl, tl, -Math.PI, -MATH_CONST.TAU); - this.strokePath(); - - return this; + // Tell the Scene to re-sort the children + scene.sys.queueDepthSort(); }, /** - * Fill the given point. - * - * Draws a square at the given position, 1 pixel in size by default. + * Sets the `active` property of this Game Object and returns this Game Object for further chaining. + * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList. * - * @method Phaser.GameObjects.Graphics#fillPointShape - * @since 3.0.0 + * @method Phaser.GameObjects.Layer#setActive + * @since 3.50.0 * - * @param {(Phaser.Geom.Point|Phaser.Math.Vector2|object)} point - The point to fill. - * @param {number} [size=1] - The size of the square to draw. + * @param {boolean} value - True if this Game Object should be set as active, false if not. * - * @return {this} This Game Object. + * @return {this} This GameObject. */ - fillPointShape: function (point, size) + setActive: function (value) { - return this.fillPoint(point.x, point.y, size); + this.active = value; + + return this; }, /** - * Fill a point at the given position. - * - * Draws a square at the given position, 1 pixel in size by default. + * Sets the `name` property of this Game Object and returns this Game Object for further chaining. + * The `name` property is not populated by Phaser and is presented for your own use. * - * @method Phaser.GameObjects.Graphics#fillPoint - * @since 3.0.0 + * @method Phaser.GameObjects.Layer#setName + * @since 3.50.0 * - * @param {number} x - The x coordinate of the point. - * @param {number} y - The y coordinate of the point. - * @param {number} [size=1] - The size of the square to draw. + * @param {string} value - The name to be given to this Game Object. * - * @return {this} This Game Object. + * @return {this} This GameObject. */ - fillPoint: function (x, y, size) + setName: function (value) { - if (!size || size < 1) - { - size = 1; - } - else - { - x -= (size / 2); - y -= (size / 2); - } - - this.commandBuffer.push( - Commands.FILL_RECT, - x, y, size, size - ); + this.name = value; return this; }, /** - * Fill the given triangle. + * Sets the current state of this Game Object. * - * @method Phaser.GameObjects.Graphics#fillTriangleShape - * @since 3.0.0 + * Phaser itself will never modify the State of a Game Object, although plugins may do so. * - * @param {Phaser.Geom.Triangle} triangle - The triangle to fill. + * For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'. + * The state value should typically be an integer (ideally mapped to a constant + * in your game code), but could also be a string. It is recommended to keep it light and simple. + * If you need to store complex data about your Game Object, look at using the Data Component instead. * - * @return {this} This Game Object. + * @method Phaser.GameObjects.Layer#setState + * @since 3.50.0 + * + * @param {(number|string)} value - The state of the Game Object. + * + * @return {this} This GameObject. */ - fillTriangleShape: function (triangle) + setState: function (value) { - return this.fillTriangle(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3); + this.state = value; + + return this; }, /** - * Stroke the given triangle. - * - * @method Phaser.GameObjects.Graphics#strokeTriangleShape - * @since 3.0.0 + * Adds a Data Manager component to this Game Object. * - * @param {Phaser.Geom.Triangle} triangle - The triangle to stroke. + * @method Phaser.GameObjects.Layer#setDataEnabled + * @since 3.50.0 + * @see Phaser.Data.DataManager * - * @return {this} This Game Object. + * @return {this} This GameObject. */ - strokeTriangleShape: function (triangle) + setDataEnabled: function () { - return this.strokeTriangle(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3); + if (!this.data) + { + this.data = new DataManager(this); + } + + return this; }, /** - * Fill a triangle with the given points. + * Allows you to store a key value pair within this Game Objects Data Manager. * - * @method Phaser.GameObjects.Graphics#fillTriangle - * @since 3.0.0 + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. * - * @param {number} x0 - The x coordinate of the first point. - * @param {number} y0 - The y coordinate of the first point. - * @param {number} x1 - The x coordinate of the second point. - * @param {number} y1 - The y coordinate of the second point. - * @param {number} x2 - The x coordinate of the third point. - * @param {number} y2 - The y coordinate of the third point. + * If the key doesn't already exist in the Data Manager then it is created. * - * @return {this} This Game Object. + * ```javascript + * sprite.setData('name', 'Red Gem Stone'); + * ``` + * + * You can also pass in an object of key value pairs as the first argument: + * + * ```javascript + * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); + * ``` + * + * To get a value back again you can call `getData`: + * + * ```javascript + * sprite.getData('gold'); + * ``` + * + * Or you can access the value directly via the `values` property, where it works like any other variable: + * + * ```javascript + * sprite.data.values.gold += 50; + * ``` + * + * When the value is first set, a `setdata` event is emitted from this Game Object. + * + * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. + * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. + * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. + * + * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. + * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. + * + * @method Phaser.GameObjects.Layer#setData + * @since 3.50.0 + * + * @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. + * @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored. + * + * @return {this} This GameObject. */ - fillTriangle: function (x0, y0, x1, y1, x2, y2) + setData: function (key, value) { - this.commandBuffer.push( - Commands.FILL_TRIANGLE, - x0, y0, x1, y1, x2, y2 - ); + if (!this.data) + { + this.data = new DataManager(this); + } + + this.data.set(key, value); return this; }, /** - * Stroke a triangle with the given points. + * Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0. * - * @method Phaser.GameObjects.Graphics#strokeTriangle - * @since 3.0.0 + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. * - * @param {number} x0 - The x coordinate of the first point. - * @param {number} y0 - The y coordinate of the first point. - * @param {number} x1 - The x coordinate of the second point. - * @param {number} y1 - The y coordinate of the second point. - * @param {number} x2 - The x coordinate of the third point. - * @param {number} y2 - The y coordinate of the third point. + * If the key doesn't already exist in the Data Manager then it is created. * - * @return {this} This Game Object. + * When the value is first set, a `setdata` event is emitted from this Game Object. + * + * @method Phaser.GameObjects.Layer#incData + * @since 3.50.0 + * + * @param {(string|object)} key - The key to increase the value for. + * @param {*} [data] - The value to increase for the given key. + * + * @return {this} This GameObject. */ - strokeTriangle: function (x0, y0, x1, y1, x2, y2) + incData: function (key, value) { - this.commandBuffer.push( - Commands.STROKE_TRIANGLE, - x0, y0, x1, y1, x2, y2 - ); + if (!this.data) + { + this.data = new DataManager(this); + } + + this.data.inc(key, value); return this; }, /** - * Draw the given line. + * Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false. * - * @method Phaser.GameObjects.Graphics#strokeLineShape - * @since 3.0.0 + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. * - * @param {Phaser.Geom.Line} line - The line to stroke. + * If the key doesn't already exist in the Data Manager then it is created. * - * @return {this} This Game Object. - */ - strokeLineShape: function (line) - { - return this.lineBetween(line.x1, line.y1, line.x2, line.y2); - }, - - /** - * Draw a line between the given points. + * When the value is first set, a `setdata` event is emitted from this Game Object. * - * @method Phaser.GameObjects.Graphics#lineBetween - * @since 3.0.0 + * @method Phaser.GameObjects.Layer#toggleData + * @since 3.50.0 * - * @param {number} x1 - The x coordinate of the start point of the line. - * @param {number} y1 - The y coordinate of the start point of the line. - * @param {number} x2 - The x coordinate of the end point of the line. - * @param {number} y2 - The y coordinate of the end point of the line. + * @param {(string|object)} key - The key to toggle the value for. * - * @return {this} This Game Object. + * @return {this} This GameObject. */ - lineBetween: function (x1, y1, x2, y2) + toggleData: function (key) { - this.beginPath(); - this.moveTo(x1, y1); - this.lineTo(x2, y2); - this.strokePath(); + if (!this.data) + { + this.data = new DataManager(this); + } + + this.data.toggle(key); return this; }, /** - * Draw a line from the current drawing position to the given position. + * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist. * - * Moves the current drawing position to the given position. + * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: * - * @method Phaser.GameObjects.Graphics#lineTo - * @since 3.0.0 + * ```javascript + * sprite.getData('gold'); + * ``` * - * @param {number} x - The x coordinate to draw the line to. - * @param {number} y - The y coordinate to draw the line to. + * Or access the value directly: * - * @return {this} This Game Object. + * ```javascript + * sprite.data.values.gold; + * ``` + * + * You can also pass in an array of keys, in which case an array of values will be returned: + * + * ```javascript + * sprite.getData([ 'gold', 'armor', 'health' ]); + * ``` + * + * This approach is useful for destructuring arrays in ES6. + * + * @method Phaser.GameObjects.Layer#getData + * @since 3.50.0 + * + * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys. + * + * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array. */ - lineTo: function (x, y) + getData: function (key) { - this.commandBuffer.push( - Commands.LINE_TO, - x, y - ); + if (!this.data) + { + this.data = new DataManager(this); + } - return this; + return this.data.get(key); }, /** - * Move the current drawing position to the given position. + * A Layer cannot be enabled for input. * - * @method Phaser.GameObjects.Graphics#moveTo - * @since 3.0.0 + * This method does nothing and is kept to ensure + * the Layer has the same shape as a Game Object. * - * @param {number} x - The x coordinate to move to. - * @param {number} y - The y coordinate to move to. + * @method Phaser.GameObjects.Layer#setInteractive + * @since 3.51.0 * - * @return {this} This Game Object. + * @return {this} This GameObject. */ - moveTo: function (x, y) + setInteractive: function () { - this.commandBuffer.push( - Commands.MOVE_TO, - x, y - ); - return this; }, /** - * Stroke the shape represented by the given array of points. + * A Layer cannot be enabled for input. * - * Pass `closeShape` to automatically close the shape by joining the last to the first point. + * This method does nothing and is kept to ensure + * the Layer has the same shape as a Game Object. * - * Pass `closePath` to automatically close the path before it is stroked. + * @method Phaser.GameObjects.Layer#disableInteractive + * @since 3.51.0 * - * @method Phaser.GameObjects.Graphics#strokePoints - * @since 3.0.0 - * - * @param {(array|Phaser.Geom.Point[])} points - The points to stroke. - * @param {boolean} [closeShape=false] - When `true`, the shape is closed by joining the last point to the first point. - * @param {boolean} [closePath=false] - When `true`, the path is closed before being stroked. - * @param {number} [endIndex] - The index of `points` to stop drawing at. Defaults to `points.length`. - * - * @return {this} This Game Object. + * @return {this} This GameObject. */ - strokePoints: function (points, closeShape, closePath, endIndex) + disableInteractive: function () { - if (closeShape === undefined) { closeShape = false; } - if (closePath === undefined) { closePath = false; } - if (endIndex === undefined) { endIndex = points.length; } - - this.beginPath(); - - this.moveTo(points[0].x, points[0].y); - - for (var i = 1; i < endIndex; i++) - { - this.lineTo(points[i].x, points[i].y); - } - - if (closeShape) - { - this.lineTo(points[0].x, points[0].y); - } - - if (closePath) - { - this.closePath(); - } - - this.strokePath(); - return this; }, /** - * Fill the shape represented by the given array of points. - * - * Pass `closeShape` to automatically close the shape by joining the last to the first point. - * - * Pass `closePath` to automatically close the path before it is filled. + * A Layer cannot be enabled for input. * - * @method Phaser.GameObjects.Graphics#fillPoints - * @since 3.0.0 + * This method does nothing and is kept to ensure + * the Layer has the same shape as a Game Object. * - * @param {(array|Phaser.Geom.Point[])} points - The points to fill. - * @param {boolean} [closeShape=false] - When `true`, the shape is closed by joining the last point to the first point. - * @param {boolean} [closePath=false] - When `true`, the path is closed before being stroked. - * @param {number} [endIndex] - The index of `points` to stop at. Defaults to `points.length`. + * @method Phaser.GameObjects.Layer#removeInteractive + * @since 3.51.0 * - * @return {this} This Game Object. + * @return {this} This GameObject. */ - fillPoints: function (points, closeShape, closePath, endIndex) + removeInteractive: function () { - if (closeShape === undefined) { closeShape = false; } - if (closePath === undefined) { closePath = false; } - if (endIndex === undefined) { endIndex = points.length; } - - this.beginPath(); - - this.moveTo(points[0].x, points[0].y); - - for (var i = 1; i < endIndex; i++) - { - this.lineTo(points[i].x, points[i].y); - } - - if (closeShape) - { - this.lineTo(points[0].x, points[0].y); - } - - if (closePath) - { - this.closePath(); - } - - this.fillPath(); - return this; }, /** - * Stroke the given ellipse. + * This callback is invoked when this Game Object is added to a Scene. * - * @method Phaser.GameObjects.Graphics#strokeEllipseShape - * @since 3.0.0 + * Can be overriden by custom Game Objects, but be aware of some Game Objects that + * will use this, such as Sprites, to add themselves into the Update List. * - * @param {Phaser.Geom.Ellipse} ellipse - The ellipse to stroke. - * @param {number} [smoothness=32] - The number of points to draw the ellipse with. + * You can also listen for the `ADDED_TO_SCENE` event from this Game Object. * - * @return {this} This Game Object. + * @method Phaser.GameObjects.Layer#addedToScene + * @since 3.50.0 */ - strokeEllipseShape: function (ellipse, smoothness) + addedToScene: function () { - if (smoothness === undefined) { smoothness = 32; } - - var points = ellipse.getPoints(smoothness); - - return this.strokePoints(points, true); }, /** - * Stroke an ellipse with the given position and size. + * This callback is invoked when this Game Object is removed from a Scene. * - * @method Phaser.GameObjects.Graphics#strokeEllipse - * @since 3.0.0 + * Can be overriden by custom Game Objects, but be aware of some Game Objects that + * will use this, such as Sprites, to removed themselves from the Update List. * - * @param {number} x - The x coordinate of the center of the ellipse. - * @param {number} y - The y coordinate of the center of the ellipse. - * @param {number} width - The width of the ellipse. - * @param {number} height - The height of the ellipse. - * @param {number} [smoothness=32] - The number of points to draw the ellipse with. + * You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object. * - * @return {this} This Game Object. + * @method Phaser.GameObjects.Layer#removedFromScene + * @since 3.50.0 */ - strokeEllipse: function (x, y, width, height, smoothness) + removedFromScene: function () { - if (smoothness === undefined) { smoothness = 32; } - - var ellipse = new Ellipse(x, y, width, height); - - var points = ellipse.getPoints(smoothness); - - return this.strokePoints(points, true); }, /** - * Fill the given ellipse. - * - * @method Phaser.GameObjects.Graphics#fillEllipseShape - * @since 3.0.0 + * To be overridden by custom GameObjects. Allows base objects to be used in a Pool. * - * @param {Phaser.Geom.Ellipse} ellipse - The ellipse to fill. - * @param {number} [smoothness=32] - The number of points to draw the ellipse with. + * @method Phaser.GameObjects.Layer#update + * @since 3.50.0 * - * @return {this} This Game Object. + * @param {...*} [args] - args */ - fillEllipseShape: function (ellipse, smoothness) + update: function () { - if (smoothness === undefined) { smoothness = 32; } - - var points = ellipse.getPoints(smoothness); - - return this.fillPoints(points, true); }, /** - * Fill an ellipse with the given position and size. - * - * @method Phaser.GameObjects.Graphics#fillEllipse - * @since 3.0.0 + * Returns a JSON representation of the Game Object. * - * @param {number} x - The x coordinate of the center of the ellipse. - * @param {number} y - The y coordinate of the center of the ellipse. - * @param {number} width - The width of the ellipse. - * @param {number} height - The height of the ellipse. - * @param {number} [smoothness=32] - The number of points to draw the ellipse with. + * @method Phaser.GameObjects.Layer#toJSON + * @since 3.50.0 * - * @return {this} This Game Object. + * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object. */ - fillEllipse: function (x, y, width, height, smoothness) + toJSON: function () { - if (smoothness === undefined) { smoothness = 32; } - - var ellipse = new Ellipse(x, y, width, height); - - var points = ellipse.getPoints(smoothness); - - return this.fillPoints(points, true); + return ComponentsToJSON(this); }, /** - * Draw an arc. - * - * This method can be used to create circles, or parts of circles. + * 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. * - * Make sure you call `beginPath` before starting the arc unless you wish for the arc to automatically - * close when filled or stroked. + * @method Phaser.GameObjects.Layer#willRender + * @since 3.50.0 * - * Use the optional `overshoot` argument increase the number of iterations that take place when - * the arc is rendered in WebGL. This is useful if you're drawing an arc with an especially thick line, - * as it will allow the arc to fully join-up. Try small values at first, i.e. 0.01. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object. * - * Call {@link Phaser.GameObjects.Graphics#fillPath} or {@link Phaser.GameObjects.Graphics#strokePath} after calling - * this method to draw the arc. + * @return {boolean} True if the Game Object should be rendered, otherwise false. + */ + willRender: function (camera) + { + return !(this.renderFlags !== 15 || this.list.length === 0 || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); + }, + + /** + * Returns an array containing the display list index of either this Game Object, or if it has one, + * its parent Container. It then iterates up through all of the parent containers until it hits the + * root of the display list (which is index 0 in the returned array). * - * @method Phaser.GameObjects.Graphics#arc - * @since 3.0.0 + * Used internally by the InputPlugin but also useful if you wish to find out the display depth of + * this Game Object and all of its ancestors. * - * @param {number} x - The x coordinate of the center of the circle. - * @param {number} y - The y coordinate of the center of the circle. - * @param {number} radius - The radius of the circle. - * @param {number} startAngle - The starting angle, in radians. - * @param {number} endAngle - The ending angle, in radians. - * @param {boolean} [anticlockwise=false] - Whether the drawing should be anticlockwise or clockwise. - * @param {number} [overshoot=0] - This value allows you to increase the segment iterations in WebGL rendering. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly. Use small numbers such as 0.01 to start with and increase as needed. + * @method Phaser.GameObjects.Layer#getIndexList + * @since 3.51.0 * - * @return {this} This Game Object. + * @return {number[]} An array of display list position indexes. */ - arc: function (x, y, radius, startAngle, endAngle, anticlockwise, overshoot) + getIndexList: function () { - if (anticlockwise === undefined) { anticlockwise = false; } - if (overshoot === undefined) { overshoot = 0; } + // eslint-disable-next-line consistent-this + var child = this; + var parent = this.parentContainer; - this.commandBuffer.push( - Commands.ARC, - x, y, radius, startAngle, endAngle, anticlockwise, overshoot - ); + var indexes = []; - return this; + while (parent) + { + indexes.unshift(parent.getIndex(child)); + + child = parent; + + if (!parent.parentContainer) + { + break; + } + else + { + parent = parent.parentContainer; + } + } + + indexes.unshift(this.displayList.getIndex(child)); + + return indexes; }, /** - * Creates a pie-chart slice shape centered at `x`, `y` with the given radius. - * You must define the start and end angle of the slice. - * - * Setting the `anticlockwise` argument to `true` creates a shape similar to Pacman. - * Setting it to `false` creates a shape like a slice of pie. - * - * This method will begin a new path and close the path at the end of it. - * To display the actual slice you need to call either `strokePath` or `fillPath` after it. - * - * @method Phaser.GameObjects.Graphics#slice - * @since 3.4.0 + * Internal method called from `List.addCallback`. * - * @param {number} x - The horizontal center of the slice. - * @param {number} y - The vertical center of the slice. - * @param {number} radius - The radius of the slice. - * @param {number} startAngle - The start angle of the slice, given in radians. - * @param {number} endAngle - The end angle of the slice, given in radians. - * @param {boolean} [anticlockwise=false] - Whether the drawing should be anticlockwise or clockwise. - * @param {number} [overshoot=0] - This value allows you to overshoot the endAngle by this amount. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly. + * @method Phaser.GameObjects.Layer#addChildCallback + * @private + * @fires Phaser.Scenes.Events#ADDED_TO_SCENE + * @fires Phaser.GameObjects.Events#ADDED_TO_SCENE + * @since 3.50.0 * - * @return {this} This Game Object. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the list. */ - slice: function (x, y, radius, startAngle, endAngle, anticlockwise, overshoot) + addChildCallback: function (gameObject) { - if (anticlockwise === undefined) { anticlockwise = false; } - if (overshoot === undefined) { overshoot = 0; } - - this.commandBuffer.push(Commands.BEGIN_PATH); + if (gameObject.displayList && gameObject.displayList !== this) + { + gameObject.removeFromDisplayList(); + } - this.commandBuffer.push(Commands.MOVE_TO, x, y); + if (!gameObject.displayList) + { + this.queueDepthSort(); - this.commandBuffer.push(Commands.ARC, x, y, radius, startAngle, endAngle, anticlockwise, overshoot); + gameObject.displayList = this; - this.commandBuffer.push(Commands.CLOSE_PATH); + gameObject.emit(GameObjectEvents.ADDED_TO_SCENE, gameObject, this.scene); - return this; + this.events.emit(SceneEvents.ADDED_TO_SCENE, gameObject, this.scene); + } }, /** - * Saves the state of the Graphics by pushing the current state onto a stack. - * - * The most recently saved state can then be restored with {@link Phaser.GameObjects.Graphics#restore}. + * Internal method called from `List.removeCallback`. * - * @method Phaser.GameObjects.Graphics#save - * @since 3.0.0 + * @method Phaser.GameObjects.Layer#removeChildCallback + * @private + * @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE + * @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE + * @since 3.50.0 * - * @return {this} This Game Object. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the list. */ - save: function () + removeChildCallback: function (gameObject) { - this.commandBuffer.push( - Commands.SAVE - ); + this.queueDepthSort(); - return this; + gameObject.displayList = null; + + gameObject.emit(GameObjectEvents.REMOVED_FROM_SCENE, gameObject, this.scene); + + this.events.emit(SceneEvents.REMOVED_FROM_SCENE, gameObject, this.scene); }, /** - * Restores the most recently saved state of the Graphics by popping from the state stack. - * - * Use {@link Phaser.GameObjects.Graphics#save} to save the current state, and call this afterwards to restore that state. - * - * If there is no saved state, this command does nothing. + * Force a sort of the display list on the next call to depthSort. * - * @method Phaser.GameObjects.Graphics#restore - * @since 3.0.0 + * @method Phaser.GameObjects.Layer#queueDepthSort + * @since 3.50.0 + */ + queueDepthSort: function () + { + this.sortChildrenFlag = true; + }, + + /** + * Immediately sorts the display list if the flag is set. * - * @return {this} This Game Object. + * @method Phaser.GameObjects.Layer#depthSort + * @since 3.50.0 */ - restore: function () + depthSort: function () { - this.commandBuffer.push( - Commands.RESTORE - ); + if (this.sortChildrenFlag) + { + StableSort(this.list, this.sortByDepth); - return this; + this.sortChildrenFlag = false; + } }, /** - * Inserts a translation command into this Graphics objects command buffer. - * - * All objects drawn _after_ calling this method will be translated - * by the given amount. - * - * This does not change the position of the Graphics object itself, - * only of the objects drawn by it after calling this method. + * Compare the depth of two Game Objects. * - * @method Phaser.GameObjects.Graphics#translateCanvas - * @since 3.0.0 + * @method Phaser.GameObjects.Layer#sortByDepth + * @since 3.50.0 * - * @param {number} x - The horizontal translation to apply. - * @param {number} y - The vertical translation to apply. + * @param {Phaser.GameObjects.GameObject} childA - The first Game Object. + * @param {Phaser.GameObjects.GameObject} childB - The second Game Object. * - * @return {this} This Game Object. + * @return {number} The difference between the depths of each Game Object. */ - translateCanvas: function (x, y) + sortByDepth: function (childA, childB) { - this.commandBuffer.push( - Commands.TRANSLATE, - x, y - ); - - return this; + return childA._depth - childB._depth; }, /** - * Inserts a scale command into this Graphics objects command buffer. - * - * All objects drawn _after_ calling this method will be scaled - * by the given amount. - * - * This does not change the scale of the Graphics object itself, - * only of the objects drawn by it after calling this method. + * Returns an array which contains all Game Objects within this Layer. * - * @method Phaser.GameObjects.Graphics#scaleCanvas - * @since 3.0.0 + * This is a reference to the main list array, not a copy of it, so be careful not to modify it. * - * @param {number} x - The horizontal scale to apply. - * @param {number} y - The vertical scale to apply. + * @method Phaser.GameObjects.Layer#getChildren + * @since 3.50.0 * - * @return {this} This Game Object. + * @return {Phaser.GameObjects.GameObject[]} The group members. */ - scaleCanvas: function (x, y) + getChildren: function () { - this.commandBuffer.push( - Commands.SCALE, - x, y - ); - - return this; + return this.list; }, /** - * Inserts a rotation command into this Graphics objects command buffer. + * Adds this Layer to the given Display List. * - * All objects drawn _after_ calling this method will be rotated - * by the given amount. + * If no Display List is specified, it will default to the Display List owned by the Scene to which + * this Layer belongs. * - * This does not change the rotation of the Graphics object itself, - * only of the objects drawn by it after calling this method. + * A Layer can only exist on one Display List at any given time, but may move freely between them. * - * @method Phaser.GameObjects.Graphics#rotateCanvas - * @since 3.0.0 + * If this Layer is already on another Display List when this method is called, it will first + * be removed from it, before being added to the new list. * - * @param {number} radians - The rotation angle, in radians. + * You can query which list it is on by looking at the `Phaser.GameObjects.Layer#displayList` property. * - * @return {this} This Game Object. + * If a Layer isn't on any display list, it will not be rendered. If you just wish to temporarily + * disable it from rendering, consider using the `setVisible` method, instead. + * + * @method Phaser.GameObjects.Layer#addToDisplayList + * @fires Phaser.Scenes.Events#ADDED_TO_SCENE + * @fires Phaser.GameObjects.Events#ADDED_TO_SCENE + * @since 3.60.0 + * + * @param {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} [displayList] - The Display List to add to. Defaults to the Scene Display List. + * + * @return {this} This Layer. */ - rotateCanvas: function (radians) + addToDisplayList: function (displayList) { - this.commandBuffer.push( - Commands.ROTATE, - radians - ); + if (displayList === undefined) { displayList = this.scene.sys.displayList; } + + if (this.displayList && this.displayList !== displayList) + { + this.removeFromDisplayList(); + } + + // Don't repeat if it's already on this list + if (!displayList.exists(this)) + { + this.displayList = displayList; + + displayList.add(this, true); + + displayList.queueDepthSort(); + + this.emit(GameObjectEvents.ADDED_TO_SCENE, this, this.scene); + + displayList.events.emit(SceneEvents.ADDED_TO_SCENE, this, this.scene); + } return this; }, /** - * Clear the command buffer and reset the fill style and line style to their defaults. + * Removes this Layer from the Display List it is currently on. * - * @method Phaser.GameObjects.Graphics#clear - * @since 3.0.0 + * A Layer can only exist on one Display List at any given time, but may move freely removed + * and added back at a later stage. * - * @return {this} This Game Object. + * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. + * + * If a Layer isn't on any Display List, it will not be rendered. If you just wish to temporarily + * disable it from rendering, consider using the `setVisible` method, instead. + * + * @method Phaser.GameObjects.Layer#removeFromDisplayList + * @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE + * @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE + * @since 3.60.0 + * + * @return {this} This Layer. */ - clear: function () + removeFromDisplayList: function () { - this.commandBuffer.length = 0; + var displayList = this.displayList || this.scene.sys.displayList; - if (this.defaultFillColor > -1) + if (displayList.exists(this)) { - this.fillStyle(this.defaultFillColor, this.defaultFillAlpha); - } + displayList.remove(this, true); - if (this.defaultStrokeColor > -1) - { - this.lineStyle(this.defaultStrokeWidth, this.defaultStrokeColor, this.defaultStrokeAlpha); + displayList.queueDepthSort(); + + this.displayList = null; + + this.emit(GameObjectEvents.REMOVED_FROM_SCENE, this, this.scene); + + displayList.events.emit(SceneEvents.REMOVED_FROM_SCENE, this, this.scene); } return this; }, /** - * Generate a texture from this Graphics object. - * - * If `key` is a string it'll generate a new texture using it and add it into the - * Texture Manager (assuming no key conflict happens). - * - * If `key` is a Canvas it will draw the texture to that canvas context. Note that it will NOT - * automatically upload it to the GPU in WebGL mode. + * Destroys this Layer removing it from the Display List and Update List and + * severing all ties to parent resources. * - * Please understand that the texture is created via the Canvas API of the browser, therefore some - * Graphics features, such as `fillGradientStyle`, will not appear on the resulting texture, - * as they're unsupported by the Canvas API. + * Also destroys all children of this Layer. If you do not wish for the + * children to be destroyed, you should move them from this Layer first. * - * @method Phaser.GameObjects.Graphics#generateTexture - * @since 3.0.0 + * Use this to remove this Layer from your game if you don't ever plan to use it again. + * As long as no reference to it exists within your own code it should become free for + * garbage collection by the browser. * - * @param {(string|HTMLCanvasElement)} key - The key to store the texture with in the Texture Manager, or a Canvas to draw to. - * @param {number} [width] - The width of the graphics to generate. - * @param {number} [height] - The height of the graphics to generate. + * If you just want to temporarily disable an object then look at using the + * Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected. * - * @return {this} This Game Object. + * @method Phaser.GameObjects.Layer#destroy + * @fires Phaser.GameObjects.Events#DESTROY + * @since 3.50.0 + * + * @param {boolean} [fromScene=false] - `True` if this Game Object is being destroyed by the Scene, `false` if not. */ - generateTexture: function (key, width, height) + destroy: function (fromScene) { - var sys = this.scene.sys; - var renderer = sys.game.renderer; - - if (width === undefined) { width = sys.scale.width; } - if (height === undefined) { height = sys.scale.height; } + // This Game Object has already been destroyed + if (!this.scene || this.ignoreDestroy) + { + return; + } - Graphics.TargetCamera.setScene(this.scene); - Graphics.TargetCamera.setViewport(0, 0, width, height); - Graphics.TargetCamera.scrollX = this.x; - Graphics.TargetCamera.scrollY = this.y; + this.emit(GameObjectEvents.DESTROY, this); - var texture; - var ctx; + var list = this.list; - if (typeof key === 'string') + while (list.length) { - if (sys.textures.exists(key)) - { - // Key is a string, it DOES exist in the Texture Manager AND is a canvas, so draw to it - - texture = sys.textures.get(key); - - var src = texture.getSourceImage(); + list[0].destroy(fromScene); + } - if (src instanceof HTMLCanvasElement) - { - ctx = src.getContext('2d'); - } - } - else - { - // Key is a string and doesn't exist in the Texture Manager, so generate and save it + this.removeAllListeners(); - texture = sys.textures.createCanvas(key, width, height); + this.resetPostPipeline(true); - ctx = texture.getSourceImage().getContext('2d'); - } - } - else if (key instanceof HTMLCanvasElement) + if (this.displayList) { - // Key is a Canvas, so draw to it + this.displayList.remove(this, true); - ctx = key.getContext('2d'); + this.displayList.queueDepthSort(); } - if (ctx) + if (this.data) { - // var GraphicsCanvasRenderer = function (renderer, src, camera, parentMatrix, renderTargetCtx, allowClip) - this.renderCanvas(renderer, this, Graphics.TargetCamera, null, ctx, false); + this.data.destroy(); - if (texture) - { - texture.refresh(); - } + this.data = undefined; } - return this; - }, + this.active = false; + this.visible = false; - /** - * Internal destroy handler, called as part of the destroy process. - * - * @method Phaser.GameObjects.Graphics#preDestroy - * @protected - * @since 3.9.0 - */ - preDestroy: function () - { - this.commandBuffer = []; + this.list = undefined; + this.scene = undefined; + this.displayList = undefined; + this.systems = undefined; + this.events = undefined; } }); -/** - * A Camera used specifically by the Graphics system for rendering to textures. - * - * @name Phaser.GameObjects.Graphics.TargetCamera - * @type {Phaser.Cameras.Scene2D.Camera} - * @since 3.1.0 - */ -Graphics.TargetCamera = new BaseCamera(); - -module.exports = Graphics; +module.exports = Layer; /***/ }), -/* 217 */ -/***/ (function(module, exports) { + +/***/ 834: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -module.exports = { +/** + * 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.Layer#renderCanvas + * @since 3.50.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Layer} layer - The Game Object being rendered in this call. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + */ +var LayerCanvasRenderer = function (renderer, layer, camera) +{ + var children = layer.list; - ARC: 0, - BEGIN_PATH: 1, - CLOSE_PATH: 2, - FILL_RECT: 3, - LINE_TO: 4, - MOVE_TO: 5, - LINE_STYLE: 6, - FILL_STYLE: 7, - FILL_PATH: 8, - STROKE_PATH: 9, - FILL_TRIANGLE: 10, - STROKE_TRIANGLE: 11, - SAVE: 14, - RESTORE: 15, - TRANSLATE: 16, - SCALE: 17, - ROTATE: 18, - GRADIENT_FILL_STYLE: 21, - GRADIENT_LINE_STYLE: 22 + if (children.length === 0) + { + return; + } + + layer.depthSort(); + + var layerHasBlendMode = (layer.blendMode !== -1); + + if (!layerHasBlendMode) + { + // If Layer is SKIP_TEST then set blend mode to be Normal + renderer.setBlendMode(0); + } + + var alpha = layer._alpha; + + if (layer.mask) + { + layer.mask.preRenderCanvas(renderer, null, camera); + } + + for (var i = 0; i < children.length; i++) + { + var child = children[i]; + + if (!child.willRender(camera)) + { + continue; + } + + var childAlpha = child.alpha; + + if (!layerHasBlendMode && child.blendMode !== renderer.currentBlendMode) + { + // If Layer doesn't have its own blend mode, then a child can have one + renderer.setBlendMode(child.blendMode); + } + + // Set parent values + child.setAlpha(childAlpha * alpha); + + // Render + child.renderCanvas(renderer, child, camera); + + // Restore original values + child.setAlpha(childAlpha); + } + if (layer.mask) + { + layer.mask.postRenderCanvas(renderer); + } }; +module.exports = LayerCanvasRenderer; + /***/ }), -/* 218 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 56378: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Point = __webpack_require__(4); +var BuildGameObject = __webpack_require__(88933); +var Layer = __webpack_require__(85305); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); /** - * Returns a Point object containing the coordinates of a point on the circumference of the Ellipse based on the given angle. + * Creates a new Layer Game Object and returns it. * - * @function Phaser.Geom.Ellipse.CircumferencePoint - * @since 3.0.0 + * Note: This method will only be available if the Layer Game Object has been built into Phaser. * - * @generic {Phaser.Geom.Point} O - [out,$return] + * @method Phaser.GameObjects.GameObjectCreator#layer + * @since 3.50.0 * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference point on. - * @param {number} angle - The angle from the center of the Ellipse to the circumference to return the point from. Given in radians. - * @param {(Phaser.Geom.Point|object)} [out] - A Point, or point-like object, to store the results in. If not given a Point will be created. + * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. * - * @return {(Phaser.Geom.Point|object)} A Point object where the `x` and `y` properties are the point on the circumference. + * @return {Phaser.GameObjects.Layer} The Game Object that was created. */ -var CircumferencePoint = function (ellipse, angle, out) +GameObjectCreator.register('layer', function (config, addToScene) { - if (out === undefined) { out = new Point(); } + if (config === undefined) { config = {}; } - var halfWidth = ellipse.width / 2; - var halfHeight = ellipse.height / 2; + var children = GetAdvancedValue(config, 'children', null); - out.x = ellipse.x + halfWidth * Math.cos(angle); - out.y = ellipse.y + halfHeight * Math.sin(angle); + var layer = new Layer(this.scene, children); - return out; -}; + if (addToScene !== undefined) + { + config.add = addToScene; + } -module.exports = CircumferencePoint; + BuildGameObject(this.scene, layer, config); + + return layer; +}); /***/ }), -/* 219 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 17676: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(35); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var ComponentsToJSON = __webpack_require__(176); -var DataManager = __webpack_require__(101); -var EventEmitter = __webpack_require__(9); -var GameObjectEvents = __webpack_require__(75); -var List = __webpack_require__(110); -var Render = __webpack_require__(1071); -var SceneEvents = __webpack_require__(20); -var StableSort = __webpack_require__(79); +var Layer = __webpack_require__(85305); +var GameObjectFactory = __webpack_require__(61286); /** - * @classdesc - * A Layer Game Object. - * - * A Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object - * to a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game - * Objects: + * Creates a new Layer Game Object and adds it to the Scene. * - * ```javascript - * const spaceman = this.add.sprite(150, 300, 'spaceman'); - * const bunny = this.add.sprite(400, 300, 'bunny'); - * const elephant = this.add.sprite(650, 300, 'elephant'); + * Note: This method will only be available if the Layer Game Object has been built into Phaser. * - * const layer = this.add.layer(); + * @method Phaser.GameObjects.GameObjectFactory#layer + * @since 3.50.0 * - * layer.add([ spaceman, bunny, elephant ]); - * ``` + * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Layer. * - * The 3 sprites in the example above will now be managed by the Layer they were added to. Therefore, - * if you then set `layer.setVisible(false)` they would all vanish from the display. + * @return {Phaser.GameObjects.Layer} The Game Object that was created. + */ +GameObjectFactory.register('layer', function (children) +{ + return this.displayList.add(new Layer(this.scene, children)); +}); + + +/***/ }), + +/***/ 58010: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(17576); +} + +if (true) +{ + renderCanvas = __webpack_require__(834); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 17576: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Renders this Game Object with the WebGL Renderer to the given Camera. + * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. + * This method should not be called directly. It is a utility function of the Render module. * - * You can also control the depth of the Game Objects within the Layer. For example, calling the - * `setDepth` method of a child of a Layer will allow you to adjust the depth of that child _within the - * Layer itself_, rather than the whole Scene. The Layer, too, can have its depth set as well. + * @method Phaser.GameObjects.Layer#renderWebGL + * @since 3.50.0 + * @private * - * The Layer class also offers many different methods for manipulating the list, such as the - * methods `moveUp`, `moveDown`, `sendToBack`, `bringToTop` and so on. These allow you to change the - * display list position of the Layers children, causing it to adjust the order in which they are - * rendered. Using `setDepth` on a child allows you to override this. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Layer} layer - The Game Object being rendered in this call. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + */ +var LayerWebGLRenderer = function (renderer, layer, camera) +{ + var children = layer.list; + var childCount = children.length; + + if (childCount === 0) + { + return; + } + + layer.depthSort(); + + renderer.pipelines.preBatch(layer); + + var layerHasBlendMode = (layer.blendMode !== -1); + + if (!layerHasBlendMode) + { + // If Layer is SKIP_TEST then set blend mode to be Normal + renderer.setBlendMode(0); + } + + var alpha = layer.alpha; + + for (var i = 0; i < childCount; i++) + { + var child = children[i]; + + if (!child.willRender(camera)) + { + continue; + } + + var childAlphaTopLeft; + var childAlphaTopRight; + var childAlphaBottomLeft; + var childAlphaBottomRight; + + if (child.alphaTopLeft !== undefined) + { + childAlphaTopLeft = child.alphaTopLeft; + childAlphaTopRight = child.alphaTopRight; + childAlphaBottomLeft = child.alphaBottomLeft; + childAlphaBottomRight = child.alphaBottomRight; + } + else + { + var childAlpha = child.alpha; + + childAlphaTopLeft = childAlpha; + childAlphaTopRight = childAlpha; + childAlphaBottomLeft = childAlpha; + childAlphaBottomRight = childAlpha; + } + + if (!layerHasBlendMode && child.blendMode !== renderer.currentBlendMode) + { + // If Layer doesn't have its own blend mode, then a child can have one + renderer.setBlendMode(child.blendMode); + } + + var mask = child.mask; + + if (mask) + { + mask.preRenderWebGL(renderer, child, camera); + } + + var type = child.type; + + if (type !== renderer.currentType) + { + renderer.newType = true; + renderer.currentType = type; + } + + renderer.nextTypeMatch = (i < childCount - 1) ? (children[i + 1].type === renderer.currentType) : false; + + child.setAlpha(childAlphaTopLeft * alpha, childAlphaTopRight * alpha, childAlphaBottomLeft * alpha, childAlphaBottomRight * alpha); + + // Render + child.renderWebGL(renderer, child, camera); + + // Restore original values + child.setAlpha(childAlphaTopLeft, childAlphaTopRight, childAlphaBottomLeft, childAlphaBottomRight); + + if (mask) + { + mask.postRenderWebGL(renderer, camera); + } + + renderer.newType = false; + } + + renderer.pipelines.postBatch(layer); +}; + +module.exports = LayerWebGLRenderer; + + +/***/ }), + +/***/ 14455: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Circle = __webpack_require__(26673); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var RGB = __webpack_require__(39298); +var Utils = __webpack_require__(75512); + +/** + * @classdesc + * A 2D point light. * - * Layers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across - * a whole range of children, which, depending on the effect, can often be far more efficient that doing so - * on a per-child basis. + * These are typically created by a {@link Phaser.GameObjects.LightsManager}, available from within a scene via `this.lights`. * - * Layers have no position or size within the Scene. This means you cannot enable a Layer for - * physics or input, or change the position, rotation or scale of a Layer. They also have no scroll - * factor, texture, tint, origin, crop or bounds. + * Any Game Objects using the Light2D pipeline will then be affected by these Lights as long as they have a normal map. * - * If you need those kind of features then you should use a Container instead. Containers can be added - * to Layers, but Layers cannot be added to Containers. + * They can also simply be used to represent a point light for your own purposes. * - * However, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings - * will impact all children being rendered by the Layer. + * As of Phaser 3.60 this Game Object now has the Transform and Origin components. However, changing the scale, + * rotation or origin properties will not make any difference to the Light. They are simply present to allow you + * to add this Light to a Container, or enable it for Physics. * - * @class Layer - * @extends Phaser.Structs.List. + * @class Light + * @extends Phaser.Geom.Circle * @memberof Phaser.GameObjects * @constructor - * @since 3.50.0 + * @since 3.0.0 * - * @extends Phaser.GameObjects.Components.AlphaSingle - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Pipeline + * @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 {Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Layer. + * @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 Layer = new Class({ +var Light = new Class({ - Extends: List, + Extends: Circle, Mixins: [ - Components.AlphaSingle, - Components.BlendMode, - Components.Depth, - Components.Mask, - Components.Pipeline, - Components.Visible, - EventEmitter, - Render + Components.Origin, + Components.ScrollFactor, + Components.Transform, + Components.Visible ], initialize: - function Layer (scene, children) + function Light (x, y, radius, r, g, b, intensity) { - List.call(this, scene); - EventEmitter.call(this); + Circle.call(this, x, y, radius); /** - * A reference to the Scene to which this Game Object belongs. - * - * Game Objects can only belong to one Scene. - * - * You should consider this property as being read-only. You cannot move a - * Game Object to another Scene by simply changing it. + * The color of the light. * - * @name Phaser.GameObjects.Layer#scene - * @type {Phaser.Scene} + * @name Phaser.GameObjects.Light#color + * @type {Phaser.Display.RGB} * @since 3.50.0 */ - this.scene = scene; + this.color = new RGB(r, g, b); /** - * Holds a reference to the Display List that contains this Game Object. - * - * This is set automatically when this Game Object is added to a Scene or Layer. - * - * You should treat this property as being read-only. + * The intensity of the light. * - * @name Phaser.GameObjects.Layer#displayList - * @type {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} - * @default null + * @name Phaser.GameObjects.Light#intensity + * @type {number} * @since 3.50.0 */ - this.displayList = null; + this.intensity = intensity; /** - * A textual representation of this Game Object, i.e. `sprite`. - * Used internally by Phaser but is available for your own custom classes to populate. + * 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.Layer#type - * @type {string} - * @since 3.50.0 + * @name Phaser.GameObjects.Light#renderFlags + * @type {number} + * @default 15 + * @since 3.0.0 */ - this.type = 'Layer'; + this.renderFlags = 15; /** - * The current state of this Game Object. - * - * Phaser itself will never modify this value, although plugins may do so. + * 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: * - * Use this property to track the state of a Game Object during its lifetime. For example, it could change from - * a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant - * in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons. - * If you need to store complex data about your Game Object, look at using the Data Component instead. + * @example + * this.cameraFilter |= camera.id * - * @name Phaser.GameObjects.Layer#state - * @type {(number|string)} - * @since 3.50.0 + * @name Phaser.GameObjects.Light#cameraFilter + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.state = 0; + this.cameraFilter = 0; - /** - * A Layer cannot be placed inside a Container. - * - * This property is kept purely so a Layer has the same - * shape as a Game Object. - * - * @name Phaser.GameObjects.Layer#parentContainer - * @type {Phaser.GameObjects.Container} - * @since 3.51.0 - */ - this.parentContainer = null; - - /** - * The name of this Game Object. - * Empty by default and never populated by Phaser, this is left for developers to use. - * - * @name Phaser.GameObjects.Layer#name - * @type {string} - * @default '' - * @since 3.50.0 - */ - this.name = ''; - - /** - * The active state of this Game Object. - * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it. - * An active object is one which is having its logic and internal systems updated. - * - * @name Phaser.GameObjects.Layer#active - * @type {boolean} - * @default true - * @since 3.50.0 - */ - this.active = true; + this.setScrollFactor(1, 1); + this.setOrigin(); + this.setDisplayOrigin(radius); + }, - /** - * The Tab Index of the Game Object. - * Reserved for future use by plugins and the Input Manager. - * - * @name Phaser.GameObjects.Layer#tabIndex - * @type {number} - * @default -1 - * @since 3.51.0 - */ - this.tabIndex = -1; + /** + * The width of this Light Game Object. This is the same as `Light.diameter`. + * + * @name Phaser.GameObjects.Light#displayWidth + * @type {number} + * @since 3.60.0 + */ + displayWidth: { - /** - * A Data Manager. - * It allows you to store, query and get key/value paired information specific to this Game Object. - * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`. - * - * @name Phaser.GameObjects.Layer#data - * @type {Phaser.Data.DataManager} - * @default null - * @since 3.50.0 - */ - this.data = null; + get: function () + { + return this.diameter; + }, - /** - * 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.Layer#renderFlags - * @type {number} - * @default 15 - * @since 3.50.0 - */ - this.renderFlags = 15; + set: function (value) + { + this.diameter = value; + } - /** - * 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.Layer#cameraFilter - * @type {number} - * @default 0 - * @since 3.50.0 - */ - this.cameraFilter = 0; + }, - /** - * This property is kept purely so a Layer has the same - * shape as a Game Object. You cannot input enable a Layer. - * - * @name Phaser.GameObjects.Layer#input - * @type {?Phaser.Types.Input.InteractiveObject} - * @default null - * @since 3.51.0 - */ - this.input = null; + /** + * The height of this Light Game Object. This is the same as `Light.diameter`. + * + * @name Phaser.GameObjects.Light#displayHeight + * @type {number} + * @since 3.60.0 + */ + displayHeight: { - /** - * This property is kept purely so a Layer has the same - * shape as a Game Object. You cannot give a Layer a physics body. - * - * @name Phaser.GameObjects.Layer#body - * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|MatterJS.BodyType)} - * @default null - * @since 3.51.0 - */ - this.body = null; + get: function () + { + return this.diameter; + }, - /** - * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`. - * This includes calls that may come from a Group, Container or the Scene itself. - * While it allows you to persist a Game Object across Scenes, please understand you are entirely - * responsible for managing references to and from this Game Object. - * - * @name Phaser.GameObjects.Layer#ignoreDestroy - * @type {boolean} - * @default false - * @since 3.50.0 - */ - this.ignoreDestroy = false; + set: function (value) + { + this.diameter = value; + } - /** - * A reference to the Scene Systems. - * - * @name Phaser.GameObjects.Layer#systems - * @type {Phaser.Scenes.Systems} - * @since 3.50.0 - */ - this.systems = scene.sys; + }, - /** - * A reference to the Scene Event Emitter. - * - * @name Phaser.GameObjects.Layer#events - * @type {Phaser.Events.EventEmitter} - * @since 3.50.0 - */ - this.events = scene.sys.events; + /** + * The width of this Light Game Object. This is the same as `Light.diameter`. + * + * @name Phaser.GameObjects.Light#width + * @type {number} + * @since 3.60.0 + */ + width: { - /** - * The flag the determines whether Game Objects should be sorted when `depthSort()` is called. - * - * @name Phaser.GameObjects.Layer#sortChildrenFlag - * @type {boolean} - * @default false - * @since 3.50.0 - */ - this.sortChildrenFlag = false; + get: function () + { + return this.diameter; + }, - // Set the List callbacks - this.addCallback = this.addChildCallback; - this.removeCallback = this.removeChildCallback; + set: function (value) + { + this.diameter = value; + } - this.initPipeline(); + }, - this.clearAlpha(); + /** + * The height of this Light Game Object. This is the same as `Light.diameter`. + * + * @name Phaser.GameObjects.Light#height + * @type {number} + * @since 3.60.0 + */ + height: { - this.setBlendMode(BlendModes.SKIP_CHECK); + get: function () + { + return this.diameter; + }, - if (children) + set: function (value) { - this.add(children); + this.diameter = value; } - // Tell the Scene to re-sort the children - scene.sys.queueDepthSort(); }, /** - * Sets the `active` property of this Game Object and returns this Game Object for further chaining. - * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList. + * 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.Layer#setActive + * @method Phaser.GameObjects.Light#willRender * @since 3.50.0 * - * @param {boolean} value - True if this Game Object should be set as active, false if not. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object. * - * @return {this} This GameObject. + * @return {boolean} True if the Game Object should be rendered, otherwise false. */ - setActive: function (value) + willRender: function (camera) { - this.active = value; - - return this; + return !(Light.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); }, /** - * Sets the `name` property of this Game Object and returns this Game Object for further chaining. - * The `name` property is not populated by Phaser and is presented for your own use. + * Set the color of the light from a single integer RGB value. * - * @method Phaser.GameObjects.Layer#setName - * @since 3.50.0 + * @method Phaser.GameObjects.Light#setColor + * @since 3.0.0 * - * @param {string} value - The name to be given to this Game Object. + * @param {number} rgb - The integer RGB color of the light. * - * @return {this} This GameObject. + * @return {this} This Light object. */ - setName: function (value) + setColor: function (rgb) { - this.name = value; + var color = Utils.getFloatsFromUintRGB(rgb); + + this.color.set(color[0], color[1], color[2]); return this; }, /** - * Sets the current state of this Game Object. - * - * Phaser itself will never modify the State of a Game Object, although plugins may do so. - * - * For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'. - * The state value should typically be an integer (ideally mapped to a constant - * in your game code), but could also be a string. It is recommended to keep it light and simple. - * If you need to store complex data about your Game Object, look at using the Data Component instead. + * Set the intensity of the light. * - * @method Phaser.GameObjects.Layer#setState - * @since 3.50.0 + * @method Phaser.GameObjects.Light#setIntensity + * @since 3.0.0 * - * @param {(number|string)} value - The state of the Game Object. + * @param {number} intensity - The intensity of the light. * - * @return {this} This GameObject. + * @return {this} This Light object. */ - setState: function (value) + setIntensity: function (intensity) { - this.state = value; + this.intensity = intensity; return this; }, /** - * Adds a Data Manager component to this Game Object. + * Set the radius of the light. * - * @method Phaser.GameObjects.Layer#setDataEnabled - * @since 3.50.0 - * @see Phaser.Data.DataManager + * @method Phaser.GameObjects.Light#setRadius + * @since 3.0.0 * - * @return {this} This GameObject. + * @param {number} radius - The radius of the light. + * + * @return {this} This Light object. */ - setDataEnabled: function () + setRadius: function (radius) { - if (!this.data) - { - this.data = new DataManager(this); - } + 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; + + +/***/ }), + +/***/ 26193: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CircleToRectangle = __webpack_require__(26535); +var Class = __webpack_require__(56694); +var DistanceBetween = __webpack_require__(53996); +var Light = __webpack_require__(14455); +var PointLight = __webpack_require__(13171); +var RGB = __webpack_require__(39298); +var SpliceOne = __webpack_require__(72677); +var StableSort = __webpack_require__(17922); +var Utils = __webpack_require__(75512); + +/** + * @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; }, /** - * Allows you to store a key value pair within this Game Objects Data Manager. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * ```javascript - * sprite.setData('name', 'Red Gem Stone'); - * ``` - * - * You can also pass in an object of key value pairs as the first argument: - * - * ```javascript - * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); - * ``` + * Creates a new Point Light Game Object and adds it to the Scene. * - * To get a value back again you can call `getData`: + * Note: This method will only be available if the Point Light Game Object has been built into Phaser. * - * ```javascript - * sprite.getData('gold'); - * ``` + * The Point Light Game Object provides a way to add a point light effect into your game, + * without the expensive shader processing requirements of the traditional Light Game Object. * - * Or you can access the value directly via the `values` property, where it works like any other variable: + * The difference is that the Point Light renders using a custom shader, designed to give the + * impression of a point light source, of variable radius, intensity and color, in your game. + * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their + * normal maps for calcuations. This makes them extremely fast to render compared to Lights + * and perfect for special effects, such as flickering torches or muzzle flashes. * - * ```javascript - * sprite.data.values.gold += 50; - * ``` + * For maximum performance you should batch Point Light Game Objects together. This means + * ensuring they follow each other consecutively on the display list. Ideally, use a Layer + * Game Object and then add just Point Lights to it, so that it can batch together the rendering + * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in + * your game then it's perfectly safe to mix them into the dislay list as normal. However, if + * you're using a large number of them, please consider how they are mixed into the display list. * - * When the value is first set, a `setdata` event is emitted from this Game Object. + * The renderer will automatically cull Point Lights. Those with a radius that does not intersect + * with the Camera will be skipped in the rendering list. This happens automatically and the + * culled state is refreshed every frame, for every camera. * - * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. - * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. - * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. + * The origin of a Point Light is always 0.5 and it cannot be changed. * - * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. - * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. + * Point Lights are a WebGL only feature and do not have a Canvas counterpart. * - * @method Phaser.GameObjects.Layer#setData + * @method Phaser.GameObjects.LightsManager#addPointLight * @since 3.50.0 * - * @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. - * @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored. + * @param {number} x - The horizontal position of this Point Light in the world. + * @param {number} y - The vertical position of this Point Light in the world. + * @param {number} [color=0xffffff] - The color of the Point Light, given as a hex value. + * @param {number} [radius=128] - The radius of the Point Light. + * @param {number} [intensity=1] - The intensity, or color blend, of the Point Light. + * @param {number} [attenuation=0.1] - The attenuation of the Point Light. This is the reduction of light from the center point. * - * @return {this} This GameObject. + * @return {Phaser.GameObjects.PointLight} The Game Object that was created. */ - setData: function (key, value) + addPointLight: function (x, y, color, radius, intensity, attenuation) { - if (!this.data) - { - this.data = new DataManager(this); - } - - this.data.set(key, value); - - return this; + return this.systems.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity, attenuation)); }, /** - * Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * - * @method Phaser.GameObjects.Layer#incData - * @since 3.50.0 + * Enable the Lights Manager. * - * @param {(string|object)} key - The key to increase the value for. - * @param {*} [data] - The value to increase for the given key. + * @method Phaser.GameObjects.LightsManager#enable + * @since 3.0.0 * - * @return {this} This GameObject. + * @return {this} This Lights Manager instance. */ - incData: function (key, value) + enable: function () { - if (!this.data) + if (this.maxLights === -1) { - this.data = new DataManager(this); + this.maxLights = this.systems.renderer.config.maxLights; } - this.data.inc(key, value); + this.active = true; return this; }, /** - * Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * - * @method Phaser.GameObjects.Layer#toggleData - * @since 3.50.0 + * Disable the Lights Manager. * - * @param {(string|object)} key - The key to toggle the value for. + * @method Phaser.GameObjects.LightsManager#disable + * @since 3.0.0 * - * @return {this} This GameObject. + * @return {this} This Lights Manager instance. */ - toggleData: function (key) + disable: function () { - if (!this.data) - { - this.data = new DataManager(this); - } - - this.data.toggle(key); + this.active = false; return this; }, /** - * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist. - * - * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: - * - * ```javascript - * sprite.getData('gold'); - * ``` - * - * Or access the value directly: - * - * ```javascript - * sprite.data.values.gold; - * ``` - * - * You can also pass in an array of keys, in which case an array of values will be returned: + * Get all lights that can be seen by the given Camera. * - * ```javascript - * sprite.getData([ 'gold', 'armor', 'health' ]); - * ``` + * It will automatically cull lights that are outside the world view of the Camera. * - * This approach is useful for destructuring arrays in ES6. + * 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.Layer#getData + * @method Phaser.GameObjects.LightsManager#getLights * @since 3.50.0 * - * @param {(string|string[])} key - The key of the value to retrieve, or an array of keys. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to cull Lights for. * - * @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array. + * @return {Phaser.GameObjects.Light[]} The culled Lights. */ - getData: function (key) + getLights: function (camera) { - if (!this.data) + var lights = this.lights; + var worldView = camera.worldView; + + var visibleLights = []; + + for (var i = 0; i < lights.length; i++) { - this.data = new DataManager(this); + 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) + }); + } } - return this.data.get(key); + 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; }, - /** - * A Layer cannot be enabled for input. - * - * This method does nothing and is kept to ensure - * the Layer has the same shape as a Game Object. - * - * @method Phaser.GameObjects.Layer#setInteractive - * @since 3.51.0 - * - * @return {this} This GameObject. - */ - setInteractive: function () + sortByDistance: function (a, b) { - return this; + return (a.distance >= b.distance); }, /** - * A Layer cannot be enabled for input. + * Set the ambient light color. * - * This method does nothing and is kept to ensure - * the Layer has the same shape as a Game Object. + * @method Phaser.GameObjects.LightsManager#setAmbientColor + * @since 3.0.0 * - * @method Phaser.GameObjects.Layer#disableInteractive - * @since 3.51.0 + * @param {number} rgb - The integer RGB color of the ambient light. * - * @return {this} This GameObject. + * @return {this} This Lights Manager instance. */ - disableInteractive: function () + setAmbientColor: function (rgb) { + var color = Utils.getFloatsFromUintRGB(rgb); + + this.ambientColor.set(color[0], color[1], color[2]); + return this; }, /** - * A Layer cannot be enabled for input. - * - * This method does nothing and is kept to ensure - * the Layer has the same shape as a Game Object. + * Returns the maximum number of Lights allowed to appear at once. * - * @method Phaser.GameObjects.Layer#removeInteractive - * @since 3.51.0 + * @method Phaser.GameObjects.LightsManager#getMaxVisibleLights + * @since 3.0.0 * - * @return {this} This GameObject. + * @return {number} The maximum number of Lights allowed to appear at once. */ - removeInteractive: function () + getMaxVisibleLights: function () { - return this; + return this.maxLights; }, /** - * This callback is invoked when this Game Object is added to a Scene. - * - * Can be overriden by custom Game Objects, but be aware of some Game Objects that - * will use this, such as Sprites, to add themselves into the Update List. + * Get the number of Lights managed by this Lights Manager. * - * You can also listen for the `ADDED_TO_SCENE` event from this Game Object. + * @method Phaser.GameObjects.LightsManager#getLightCount + * @since 3.0.0 * - * @method Phaser.GameObjects.Layer#addedToScene - * @since 3.50.0 + * @return {number} The number of Lights managed by this Lights Manager. */ - addedToScene: function () + getLightCount: function () { + return this.lights.length; }, /** - * This callback is invoked when this Game Object is removed from a Scene. + * Add a Light. * - * Can be overriden by custom Game Objects, but be aware of some Game Objects that - * will use this, such as Sprites, to removed themselves from the Update List. + * @method Phaser.GameObjects.LightsManager#addLight + * @since 3.0.0 * - * You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object. + * @param {number} [x=0] - The horizontal position of the Light. + * @param {number} [y=0] - The vertical position of the Light. + * @param {number} [radius=128] - 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. * - * @method Phaser.GameObjects.Layer#removedFromScene - * @since 3.50.0 + * @return {Phaser.GameObjects.Light} The Light that was added. */ - removedFromScene: function () + 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; } - /** - * To be overridden by custom GameObjects. Allows base objects to be used in a Pool. - * - * @method Phaser.GameObjects.Layer#update - * @since 3.50.0 - * - * @param {...*} [args] - args - */ - update: function () - { + 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; }, /** - * Returns a JSON representation of the Game Object. + * Remove a Light. * - * @method Phaser.GameObjects.Layer#toJSON - * @since 3.50.0 + * @method Phaser.GameObjects.LightsManager#removeLight + * @since 3.0.0 * - * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object. + * @param {Phaser.GameObjects.Light} light - The Light to remove. + * + * @return {this} This Lights Manager instance. */ - toJSON: function () + removeLight: function (light) { - return ComponentsToJSON(this); + var index = this.lights.indexOf(light); + + if (index >= 0) + { + SpliceOne(this.lights, index); + } + + return this; }, /** - * Compares the renderMask with the renderFlags to see if this Game Object will render or not. - * Also checks the Game Object against the given Cameras exclusion list. - * - * @method Phaser.GameObjects.Layer#willRender - * @since 3.50.0 + * Shut down the Lights Manager. * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object. + * Recycles all active Lights into the Light pool, resets ambient light color and clears the lists of Lights and + * culled Lights. * - * @return {boolean} True if the Game Object should be rendered, otherwise false. + * @method Phaser.GameObjects.LightsManager#shutdown + * @since 3.0.0 */ - willRender: function (camera) + shutdown: function () { - return !(this.renderFlags !== 15 || this.list.length === 0 || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); + this.lights.length = 0; }, /** - * Returns an array containing the display list index of either this Game Object, or if it has one, - * its parent Container. It then iterates up through all of the parent containers until it hits the - * root of the display list (which is index 0 in the returned array). - * - * Used internally by the InputPlugin but also useful if you wish to find out the display depth of - * this Game Object and all of its ancestors. + * Destroy the Lights Manager. * - * @method Phaser.GameObjects.Layer#getIndexList - * @since 3.51.0 + * Cleans up all references by calling {@link Phaser.GameObjects.LightsManager#shutdown}. * - * @return {number[]} An array of display list position indexes. + * @method Phaser.GameObjects.LightsManager#destroy + * @since 3.0.0 */ - getIndexList: function () + destroy: function () { - // eslint-disable-next-line consistent-this - var child = this; - var parent = this.parentContainer; - - var indexes = []; + this.shutdown(); + } - while (parent) - { - indexes.unshift(parent.getIndex(child)); +}); - child = parent; +module.exports = LightsManager; - if (!parent.parentContainer) - { - break; - } - else - { - parent = parent.parentContainer; - } - } - indexes.unshift(this.displayList.getIndex(child)); +/***/ }), - return indexes; - }, +/***/ 50296: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Internal method called from `List.addCallback`. - * - * @method Phaser.GameObjects.Layer#addChildCallback - * @private - * @fires Phaser.Scenes.Events#ADDED_TO_SCENE - * @fires Phaser.GameObjects.Events#ADDED_TO_SCENE - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the list. - */ - addChildCallback: function (gameObject) - { - if (gameObject.displayList && gameObject.displayList !== this) - { - gameObject.removeFromDisplayList(); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (!gameObject.displayList) - { - this.queueDepthSort(); +var Class = __webpack_require__(56694); +var LightsManager = __webpack_require__(26193); +var PluginCache = __webpack_require__(91963); +var SceneEvents = __webpack_require__(7599); - gameObject.displayList = this; +/** + * @classdesc + * A Scene plugin that provides a {@link Phaser.GameObjects.LightsManager} for the Light2D pipeline. + * + * Available from within a Scene via `this.lights`. + * + * Add Lights using the {@link Phaser.GameObjects.LightsManager#addLight} method: + * + * ```javascript + * // Enable the Lights Manager because it is disabled by default + * this.lights.enable(); + * + * // Create a Light at [400, 300] with a radius of 200 + * this.lights.addLight(400, 300, 200); + * ``` + * + * For Game Objects to be affected by the Lights when rendered, you will need to set them to use the `Light2D` pipeline like so: + * + * ```javascript + * sprite.setPipeline('Light2D'); + * ``` + * + * Note that you cannot use this pipeline on Graphics Game Objects or Shape Game Objects. + * + * @class LightsPlugin + * @extends Phaser.GameObjects.LightsManager + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene that this Lights Plugin belongs to. + */ +var LightsPlugin = new Class({ - gameObject.emit(GameObjectEvents.ADDED_TO_SCENE, gameObject, this.scene); + Extends: LightsManager, - this.events.emit(SceneEvents.ADDED_TO_SCENE, gameObject, this.scene); - } - }, + initialize: - /** - * Internal method called from `List.removeCallback`. - * - * @method Phaser.GameObjects.Layer#removeChildCallback - * @private - * @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE - * @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the list. - */ - removeChildCallback: function (gameObject) + function LightsPlugin (scene) { - this.queueDepthSort(); - - gameObject.displayList = null; - - gameObject.emit(GameObjectEvents.REMOVED_FROM_SCENE, gameObject, this.scene); - - this.events.emit(SceneEvents.REMOVED_FROM_SCENE, gameObject, this.scene); - }, + /** + * A reference to the Scene that this Lights Plugin belongs to. + * + * @name Phaser.GameObjects.LightsPlugin#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - /** - * Force a sort of the display list on the next call to depthSort. - * - * @method Phaser.GameObjects.Layer#queueDepthSort - * @since 3.50.0 - */ - queueDepthSort: function () - { - this.sortChildrenFlag = true; - }, + /** + * A reference to the Scene's systems. + * + * @name Phaser.GameObjects.LightsPlugin#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.systems = scene.sys; - /** - * Immediately sorts the display list if the flag is set. - * - * @method Phaser.GameObjects.Layer#depthSort - * @since 3.50.0 - */ - depthSort: function () - { - if (this.sortChildrenFlag) + if (!scene.sys.settings.isBooted) { - StableSort(this.list, this.sortByDepth); - - this.sortChildrenFlag = false; + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); } - }, - /** - * Compare the depth of two Game Objects. - * - * @method Phaser.GameObjects.Layer#sortByDepth - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} childA - The first Game Object. - * @param {Phaser.GameObjects.GameObject} childB - The second Game Object. - * - * @return {number} The difference between the depths of each Game Object. - */ - sortByDepth: function (childA, childB) - { - return childA._depth - childB._depth; + LightsManager.call(this); }, /** - * Returns an array which contains all Game Objects within this Layer. - * - * This is a reference to the main list array, not a copy of it, so be careful not to modify it. - * - * @method Phaser.GameObjects.Layer#getChildren - * @since 3.50.0 + * Boot the Lights Plugin. * - * @return {Phaser.GameObjects.GameObject[]} The group members. + * @method Phaser.GameObjects.LightsPlugin#boot + * @since 3.0.0 */ - getChildren: function () + boot: function () { - return this.list; + var eventEmitter = this.systems.events; + + eventEmitter.on(SceneEvents.SHUTDOWN, this.shutdown, this); + eventEmitter.on(SceneEvents.DESTROY, this.destroy, this); }, /** - * Destroys this Layer removing it from the Display List and Update List and - * severing all ties to parent resources. - * - * Also destroys all children of this Layer. If you do not wish for the - * children to be destroyed, you should move them from this Layer first. - * - * Use this to remove this Layer from your game if you don't ever plan to use it again. - * As long as no reference to it exists within your own code it should become free for - * garbage collection by the browser. + * Destroy the Lights Plugin. * - * If you just want to temporarily disable an object then look at using the - * Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected. + * Cleans up all references. * - * @method Phaser.GameObjects.Layer#destroy - * @fires Phaser.GameObjects.Events#DESTROY - * @since 3.50.0 + * @method Phaser.GameObjects.LightsPlugin#destroy + * @since 3.0.0 */ destroy: function () { - // This Game Object has already been destroyed - if (!this.scene || this.ignoreDestroy) - { - return; - } - - this.emit(GameObjectEvents.DESTROY, this); - - var i = this.list.length; - - while (i--) - { - this.list[i].destroy(); - } - - this.removeAllListeners(); - - this.resetPostPipeline(true); - - if (this.displayList) - { - this.displayList.remove(this, true); - - this.displayList.queueDepthSort(); - } - - if (this.data) - { - this.data.destroy(); - - this.data = undefined; - } - - this.active = false; - this.visible = false; + this.shutdown(); - this.list = undefined; this.scene = undefined; - this.displayList = undefined; this.systems = undefined; - this.events = undefined; } }); -module.exports = Layer; +PluginCache.register('LightsPlugin', LightsPlugin, 'lights'); + +module.exports = LightsPlugin; /***/ }), -/* 220 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 83321: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 GravityWell = __webpack_require__(450); -var List = __webpack_require__(110); -var ParticleEmitter = __webpack_require__(452); -var Render = __webpack_require__(1075); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var DegToRad = __webpack_require__(75606); +var Face = __webpack_require__(18693); +var GameObject = __webpack_require__(89980); +var GenerateObjVerts = __webpack_require__(53267); +var GenerateVerts = __webpack_require__(67623); +var GetCalcMatrix = __webpack_require__(73329); +var Matrix4 = __webpack_require__(16650); +var MeshRender = __webpack_require__(23464); +var RadToDeg = __webpack_require__(23701); +var StableSort = __webpack_require__(17922); +var Vector3 = __webpack_require__(70015); +var Vertex = __webpack_require__(85769); /** * @classdesc - * A Particle Emitter Manager creates and controls {@link Phaser.GameObjects.Particles.ParticleEmitter Particle Emitters} and {@link Phaser.GameObjects.Particles.GravityWell Gravity Wells}. + * A Mesh Game Object. + * + * The Mesh Game Object allows you to render a group of textured vertices and manipulate + * the view of those vertices, such as rotation, translation or scaling. + * + * Support for generating mesh data from grids, model data or Wavefront OBJ Files is included. + * + * Although you can use this to render 3D objects, its primary use is for displaying more complex + * Sprites, or Sprites where you need fine-grained control over the vertex positions in order to + * achieve special effects in your games. Note that rendering still takes place using Phaser's + * orthographic camera (after being transformed via `projectionMesh`, see `setPerspective`, + * `setOrtho`, and `panZ` methods). As a result, all depth and face tests are done in an eventually + * orthographic space. + * + * The rendering process will iterate through the faces of this Mesh and render out each face + * that is considered as being in view of the camera. No depth buffer is used, and because of this, + * you should be careful not to use model data with too many vertices, or overlapping geometry, + * or you'll probably encounter z-depth fighting. The Mesh was designed to allow for more advanced + * 2D layouts, rather than displaying 3D objects, even though it can do this to a degree. + * + * In short, if you want to remake Crysis, use a 3D engine, not a Mesh. However, if you want + * to easily add some small fun 3D elements into your game, or create some special effects involving + * vertex warping, this is the right object for you. Mesh data becomes part of the WebGL batch, + * just like standard Sprites, so doesn't introduce any additional shader overhead. Because + * the Mesh just generates vertices into the WebGL batch, like any other Sprite, you can use all of + * the common Game Object components on a Mesh too, such as a custom pipeline, mask, blend mode + * or texture. + * + * Note that the Mesh object is WebGL only and does not have a Canvas counterpart. + * + * The Mesh origin is always 0.5 x 0.5 and cannot be changed. * - * @class ParticleEmitterManager + * @class Mesh * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects.Particles + * @memberof Phaser.GameObjects * @constructor + * @webglOnly * @since 3.0.0 * + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode * @extends Phaser.GameObjects.Components.Depth * @extends Phaser.GameObjects.Components.Mask * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.Texture * @extends Phaser.GameObjects.Components.Transform * @extends Phaser.GameObjects.Components.Visible * - * @param {Phaser.Scene} scene - The Scene to which this Emitter Manager belongs. - * @param {string} texture - The key of the Texture this Emitter Manager will use to render particles, as stored in the Texture Manager. - * @param {(string|number)} [frame] - An optional frame from the Texture this Emitter Manager will use to render particles. - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig|Phaser.Types.GameObjects.Particles.ParticleEmitterConfig[]} [emitters] - Configuration settings for one or more emitters to create. + * @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. + * @param {number[]} [vertices] - The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true` (but see note). + * @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? Note: If not, it will be assumed `z=0`, see method `panZ` or `setOrtho`. + * @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. */ -var ParticleEmitterManager = new Class({ +var Mesh = new Class({ Extends: GameObject, Mixins: [ + Components.AlphaSingle, + Components.BlendMode, Components.Depth, Components.Mask, Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Size, + Components.Texture, Components.Transform, Components.Visible, - Render + MeshRender ], initialize: - // frame is optional and can contain the emitters array or object if skipped - function ParticleEmitterManager (scene, texture, frame, emitters) + function Mesh (scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas) { - GameObject.call(this, scene, 'ParticleEmitterManager'); + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (texture === undefined) { texture = '__WHITE'; } - /** - * The blend mode applied to all emitters and particles. - * - * @name Phaser.GameObjects.Particles.ParticleEmitterManager#blendMode - * @type {number} - * @default -1 - * @private - * @since 3.0.0 - */ - this.blendMode = -1; + GameObject.call(this, scene, 'Mesh'); /** - * The time scale applied to all emitters and particles, affecting flow rate, lifespan, and movement. - * Values larger than 1 are faster than normal. - * This is multiplied with any timeScale set on each individual emitter. + * An array containing the Face instances belonging to this Mesh. * - * @name Phaser.GameObjects.Particles.ParticleEmitterManager#timeScale - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.timeScale = 1; + * A Face consists of 3 Vertex objects. + * + * This array is populated during calls such as `addVertices` or `addOBJ`. + * + * @name Phaser.GameObjects.Mesh#faces + * @type {Phaser.Geom.Mesh.Face[]} + * @since 3.50.0 + */ + this.faces = []; /** - * The texture used to render this Emitter Manager's particles. + * An array containing Vertex instances. One instance per vertex in this Mesh. * - * @name Phaser.GameObjects.Particles.ParticleEmitterManager#texture - * @type {Phaser.Textures.Texture} - * @default null - * @since 3.0.0 + * This array is populated during calls such as `addVertex` or `addOBJ`. + * + * @name Phaser.GameObjects.Mesh#vertices + * @type {Phaser.Geom.Mesh.Vertex[]} + * @since 3.50.0 */ - this.texture = null; + this.vertices = []; /** - * The texture frame used to render this Emitter Manager's particles. + * The tint fill mode. * - * @name Phaser.GameObjects.Particles.ParticleEmitterManager#frame - * @type {Phaser.Textures.Frame} - * @default null - * @since 3.0.0 + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertex colors replace the texture, but respects texture alpha. + * + * @name Phaser.GameObjects.Mesh#tintFill + * @type {boolean} + * @default false + * @since 3.50.0 */ - this.frame = null; + this.tintFill = false; /** - * Names of this Emitter Manager's texture frames. + * You can optionally choose to render the vertices of this Mesh to a Graphics instance. * - * @name Phaser.GameObjects.Particles.ParticleEmitterManager#frameNames - * @type {string[]} - * @since 3.0.0 + * Achieve this by setting the `debugCallback` and the `debugGraphic` properties. + * + * You can do this in a single call via the `Mesh.setDebug` method, which will use the + * built-in debug function. You can also set it to your own callback. The callback + * will be invoked _once per render_ and sent the following parameters: + * + * `debugCallback(src, meshLength, verts)` + * + * `src` is the Mesh instance being debugged. + * `meshLength` is the number of mesh vertices in total. + * `verts` is an array of the translated vertex coordinates. + * + * To disable rendering, set this property back to `null`. + * + * Please note that high vertex count Meshes will struggle to debug properly. + * + * @name Phaser.GameObjects.Mesh#debugCallback + * @type {function} + * @since 3.50.0 */ - this.frameNames = []; + this.debugCallback = null; - // frame is optional and can contain the emitters array or object if skipped - if (frame !== null && (typeof frame === 'object' || Array.isArray(frame))) - { - emitters = frame; - frame = null; - } + /** + * The Graphics instance that the debug vertices will be drawn to, if `setDebug` has + * been called. + * + * @name Phaser.GameObjects.Mesh#debugGraphic + * @type {Phaser.GameObjects.Graphics} + * @since 3.50.0 + */ + this.debugGraphic = null; - this.setTexture(texture, frame); + /** + * When rendering, skip any Face that isn't counter clockwise? + * + * Enable this to hide backward-facing Faces during rendering. + * + * Disable it to render all Faces. + * + * @name Phaser.GameObjects.Mesh#hideCCW + * @type {boolean} + * @since 3.50.0 + */ + this.hideCCW = true; - this.initPipeline(); + /** + * A Vector3 containing the 3D position of the vertices in this Mesh. + * + * Modifying the components of this property will allow you to reposition where + * the vertices are rendered within the Mesh. This happens in the `preUpdate` phase, + * where each vertex is transformed using the view and projection matrices. + * + * Changing this property will impact all vertices being rendered by this Mesh. + * + * You can also adjust the 'view' by using the `pan` methods. + * + * @name Phaser.GameObjects.Mesh#modelPosition + * @type {Phaser.Math.Vector3} + * @since 3.50.0 + */ + this.modelPosition = new Vector3(); /** - * A list of Emitters being managed by this Emitter Manager. + * A Vector3 containing the 3D scale of the vertices in this Mesh. * - * @name Phaser.GameObjects.Particles.ParticleEmitterManager#emitters - * @type {Phaser.Structs.List.} - * @since 3.0.0 + * Modifying the components of this property will allow you to scale + * the vertices within the Mesh. This happens in the `preUpdate` phase, + * where each vertex is transformed using the view and projection matrices. + * + * Changing this property will impact all vertices being rendered by this Mesh. + * + * @name Phaser.GameObjects.Mesh#modelScale + * @type {Phaser.Math.Vector3} + * @since 3.50.0 */ - this.emitters = new List(this); + this.modelScale = new Vector3(1, 1, 1); /** - * A list of Gravity Wells being managed by this Emitter Manager. + * A Vector3 containing the 3D rotation of the vertices in this Mesh. * - * @name Phaser.GameObjects.Particles.ParticleEmitterManager#wells - * @type {Phaser.Structs.List.} - * @since 3.0.0 + * The values should be given in radians, i.e. to rotate the vertices by 90 + * degrees you can use `modelRotation.x = Phaser.Math.DegToRad(90)`. + * + * Modifying the components of this property will allow you to rotate + * the vertices within the Mesh. This happens in the `preUpdate` phase, + * where each vertex is transformed using the view and projection matrices. + * + * Changing this property will impact all vertices being rendered by this Mesh. + * + * @name Phaser.GameObjects.Mesh#modelRotation + * @type {Phaser.Math.Vector3} + * @since 3.50.0 */ - this.wells = new List(this); + this.modelRotation = new Vector3(); - if (emitters) - { - // An array of emitter configs? - if (!Array.isArray(emitters)) - { - emitters = [ emitters ]; - } + /** + * An internal cache, used to compare position, rotation, scale and face data + * each frame, to avoid math calculations in `preUpdate`. + * + * Cache structure = position xyz | rotation xyz | scale xyz | face count | view | ortho + * + * @name Phaser.GameObjects.Mesh#dirtyCache + * @type {number[]} + * @private + * @since 3.50.0 + */ + this.dirtyCache = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; - for (var i = 0; i < emitters.length; i++) - { - this.createEmitter(emitters[i]); - } + /** + * The transformation matrix for this Mesh. + * + * @name Phaser.GameObjects.Mesh#transformMatrix + * @type {Phaser.Math.Matrix4} + * @since 3.50.0 + */ + this.transformMatrix = new Matrix4(); + + /** + * The view position for this Mesh. + * + * Use the methods`panX`, `panY` and `panZ` to adjust the view. + * + * @name Phaser.GameObjects.Mesh#viewPosition + * @type {Phaser.Math.Vector3} + * @since 3.50.0 + */ + this.viewPosition = new Vector3(); + + /** + * The view matrix for this Mesh. + * + * @name Phaser.GameObjects.Mesh#viewMatrix + * @type {Phaser.Math.Matrix4} + * @since 3.50.0 + */ + this.viewMatrix = new Matrix4(); + + /** + * The projection matrix for this Mesh. + * + * Update it with the `setPerspective` or `setOrtho` methods. + * + * @name Phaser.GameObjects.Mesh#projectionMatrix + * @type {Phaser.Math.Matrix4} + * @since 3.50.0 + */ + this.projectionMatrix = new Matrix4(); + + /** + * How many faces were rendered by this Mesh Game Object in the last + * draw? This is reset in the `preUpdate` method and then incremented + * each time a face is drawn. Note that in multi-camera Scenes this + * value may exceed that found in `Mesh.getFaceCount` due to + * cameras drawing the same faces more than once. + * + * @name Phaser.GameObjects.Mesh#totalRendered + * @type {number} + * @readonly + * @since 3.50.0 + */ + this.totalRendered = 0; + + /** + * Internal cache var for the total number of faces rendered this frame. + * + * See `totalRendered` instead for the actual value. + * + * @name Phaser.GameObjects.Mesh#totalFrame + * @type {number} + * @private + * @since 3.50.0 + */ + this.totalFrame = 0; + + /** + * By default, the Mesh will check to see if its model or view transform has + * changed each frame and only recalculate the vertex positions if they have. + * + * This avoids lots of additional math in the `preUpdate` step when not required. + * + * However, if you are performing per-Face or per-Vertex manipulation on this Mesh, + * such as tweening a Face, or moving it without moving the rest of the Mesh, + * then you may need to disable the dirty cache in order for the Mesh to re-render + * correctly. You can toggle this property to do that. Please note that leaving + * this set to `true` will cause the Mesh to recalculate the position of every single + * vertex in it, every single frame. So only really do this if you know you + * need it. + * + * @name Phaser.GameObjects.Mesh#ignoreDirtyCache + * @type {boolean} + * @since 3.50.0 + */ + this.ignoreDirtyCache = false; + + /** + * The Camera fov (field of view) in degrees. + * + * This is set automatically as part of the `Mesh.setPerspective` call, but exposed + * here for additional math. + * + * Do not modify this property directly, doing so will not change the fov. For that, + * call the respective Mesh methods. + * + * @name Phaser.GameObjects.Mesh#fov + * @type {number} + * @readonly + * @since 3.60.0 + */ + this.fov; + + // Set these to allow setInteractive to work + this.displayOriginX = 0; + this.displayOriginY = 0; + + var renderer = scene.sys.renderer; + + this.setPosition(x, y); + this.setTexture(texture, frame); + this.setSize(renderer.width, renderer.height); + this.initPipeline(); + this.initPostPipeline(); + + this.setPerspective(renderer.width, renderer.height); + + if (vertices) + { + this.addVertices(vertices, uvs, indicies, containsZ, normals, colors, alphas); } }, @@ -55283,5403 +58385,5739 @@ var ParticleEmitterManager = new Class({ }, /** - * Sets the texture and frame this Emitter Manager will use to render with. - * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#setTexture - * @since 3.0.0 + * Translates the view position of this Mesh on the x axis by the given amount. * - * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. - * @param {(string|number)} [frame] - The name or index of the frame within the Texture. + * @method Phaser.GameObjects.Mesh#panX + * @since 3.50.0 * - * @return {this} This Emitter Manager. + * @param {number} v - The amount to pan by. */ - setTexture: function (key, frame) + panX: function (v) { - this.texture = this.scene.sys.textures.get(key); + this.viewPosition.addScale(Vector3.LEFT, v); - return this.setFrame(frame); + this.dirtyCache[10] = 1; + + return this; }, /** - * Sets the frame this Emitter Manager will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. - * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#setFrame - * @since 3.0.0 + * Translates the view position of this Mesh on the y axis by the given amount. * - * @param {(string|number)} [frame] - The name or index of the frame within the Texture. + * @method Phaser.GameObjects.Mesh#panY + * @since 3.50.0 * - * @return {this} This Emitter Manager. + * @param {number} v - The amount to pan by. */ - setFrame: function (frame) + panY: function (v) { - this.frame = this.texture.get(frame); - - var frames = this.texture.getFramesFromTextureSource(this.frame.sourceIndex); - - var names = []; - - frames.forEach(function (sourceFrame) - { - names.push(sourceFrame.name); - }); - - this.frameNames = names; + this.viewPosition.y += Vector3.DOWN.y * v; - this.defaultFrame = this.frame; + this.dirtyCache[10] = 1; return this; }, /** - * Assigns texture frames to an emitter. + * Translates the view position of this Mesh on the z axis by the given amount. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#setEmitterFrames - * @since 3.0.0 + * As the default `panZ` value is 0, vertices with `z=0` (the default) need special + * care or else they will not display as they are "behind" the camera. * - * @param {(Phaser.Textures.Frame|Phaser.Textures.Frame[])} frames - The texture frames. - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The particle emitter to modify. + * Consider using `mesh.panZ(mesh.height / (2 * Math.tan(Math.PI / 16)))`, + * which will interpret vertex geometry 1:1 with pixel geometry (or see `setOrtho`). * - * @return {this} This Emitter Manager. + * @method Phaser.GameObjects.Mesh#panZ + * @since 3.50.0 + * + * @param {number} v - The amount to pan by. */ - setEmitterFrames: function (frames, emitter) + panZ: function (amount) { - if (!Array.isArray(frames)) - { - frames = [ frames ]; - } - - var out = emitter.frames; - - out.length = 0; - - for (var i = 0; i < frames.length; i++) - { - var frame = frames[i]; - - if (this.frameNames.indexOf(frame) !== -1) - { - out.push(this.texture.get(frame)); - } - } + this.viewPosition.z += amount; - if (out.length > 0) - { - emitter.defaultFrame = out[0]; - } - else - { - emitter.defaultFrame = this.defaultFrame; - } + this.dirtyCache[10] = 1; return this; }, /** - * Adds an existing Particle Emitter to this Emitter Manager. + * Builds a new perspective projection matrix from the given values. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#addEmitter - * @since 3.0.0 + * These are also the initial projection matrix and parameters for `Mesh` (see `Mesh.panZ` for more discussion). + * + * See also `setOrtho`. * - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Particle Emitter to add to this Emitter Manager. + * @method Phaser.GameObjects.Mesh#setPerspective + * @since 3.50.0 * - * @return {Phaser.GameObjects.Particles.ParticleEmitter} The Particle Emitter that was added to this Emitter Manager. + * @param {number} width - The width of the projection matrix. Typically the same as the Mesh and/or Renderer. + * @param {number} height - The height of the projection matrix. Typically the same as the Mesh and/or Renderer. + * @param {number} [fov=45] - The field of view, in degrees. + * @param {number} [near=0.01] - The near value of the view. + * @param {number} [far=1000] - The far value of the view. */ - addEmitter: function (emitter) + setPerspective: function (width, height, fov, near, far) { - return this.emitters.add(emitter); + if (fov === undefined) { fov = 45; } + if (near === undefined) { near = 0.01; } + if (far === undefined) { far = 1000; } + + this.fov = fov; + + this.projectionMatrix.perspective(DegToRad(fov), width / height, near, far); + + this.dirtyCache[10] = 1; + this.dirtyCache[11] = 0; + + return this; }, /** - * Creates a new Particle Emitter object, adds it to this Emitter Manager and returns a reference to it. + * Builds a new orthographic projection matrix from the given values. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#createEmitter - * @since 3.0.0 + * If using this mode you will often need to set `Mesh.hideCCW` to `false` as well. + * + * By default, calling this method with no parameters will set the scaleX value to + * match the renderer's aspect ratio. If you would like to render vertex positions 1:1 + * to pixel positions, consider calling as `mesh.setOrtho(mesh.width, mesh.height)`. + * + * See also `setPerspective`. * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Configuration settings for the Particle Emitter to create. + * @method Phaser.GameObjects.Mesh#setOrtho + * @since 3.50.0 * - * @return {Phaser.GameObjects.Particles.ParticleEmitter} The Particle Emitter that was created. + * @param {number} [scaleX=1] - The default horizontal scale in relation to the Mesh / Renderer dimensions. + * @param {number} [scaleY=1] - The default vertical scale in relation to the Mesh / Renderer dimensions. + * @param {number} [near=-1000] - The near value of the view. + * @param {number} [far=1000] - The far value of the view. */ - createEmitter: function (config) + setOrtho: function (scaleX, scaleY, near, far) { - return this.addEmitter(new ParticleEmitter(this, config)); + if (scaleX === undefined) { scaleX = this.scene.sys.renderer.getAspectRatio(); } + if (scaleY === undefined) { scaleY = 1; } + if (near === undefined) { near = -1000; } + if (far === undefined) { far = 1000; } + + this.fov = 0; + + this.projectionMatrix.ortho(-scaleX, scaleX, -scaleY, scaleY, near, far); + + this.dirtyCache[10] = 1; + this.dirtyCache[11] = 1; + + return this; }, /** - * Removes a Particle Emitter from this Emitter Manager, if the Emitter belongs to this Manager. - * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#removeEmitter - * @since 3.22.0 + * Iterates and destroys all current Faces in this Mesh, then resets the + * `faces` and `vertices` arrays. * - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter + * @method Phaser.GameObjects.Mesh#clear + * @since 3.50.0 * - * @return {?Phaser.GameObjects.Particles.ParticleEmitter} The Particle Emitter if it was removed or null if it was not. + * @return {this} This Mesh Game Object. */ - removeEmitter: function (emitter) + clear: function () { - return this.emitters.remove(emitter, true); + this.faces.forEach(function (face) + { + face.destroy(); + }); + + this.faces = []; + this.vertices = []; + + return this; }, /** - * Adds an existing Gravity Well object to this Emitter Manager. + * This method will add the data from a triangulated Wavefront OBJ model file to this Mesh. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#addGravityWell - * @since 3.0.0 + * The data should have been loaded via the OBJFile: * - * @param {Phaser.GameObjects.Particles.GravityWell} well - The Gravity Well to add to this Emitter Manager. + * ```javascript + * this.load.obj(key, url); + * ``` * - * @return {Phaser.GameObjects.Particles.GravityWell} The Gravity Well that was added to this Emitter Manager. - */ - addGravityWell: function (well) - { - return this.wells.add(well); - }, - - /** - * Creates a new Gravity Well, adds it to this Emitter Manager and returns a reference to it. + * Then use the same `key` as the first parameter to this method. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#createGravityWell - * @since 3.0.0 + * Multiple Mesh Game Objects can use the same model data without impacting on each other. * - * @param {Phaser.Types.GameObjects.Particles.GravityWellConfig} config - Configuration settings for the Gravity Well to create. + * Make sure your 3D package has triangulated the model data prior to exporting it. * - * @return {Phaser.GameObjects.Particles.GravityWell} The Gravity Well that was created. - */ - createGravityWell: function (config) - { - return this.addGravityWell(new GravityWell(config)); - }, - - /** - * Emits particles from each active emitter. + * You can 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 too large, to see. + * You can also offset the vertices of the model via the `x`, `y` and `z` parameters. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#emitParticle - * @since 3.0.0 + * @method Phaser.GameObjects.Mesh#addVerticesFromObj + * @since 3.50.0 * - * @param {number} [count] - The number of particles to release from each emitter. The default is the emitter's own {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. - * @param {number} [x] - The x-coordinate to to emit particles from. The default is the x-coordinate of the emitter's current location. - * @param {number} [y] - The y-coordinate to to emit particles from. The default is the y-coordinate of the emitter's current location. + * @param {string} key - The key of the model data in the OBJ Cache to add to this Mesh. + * @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 {this} This Emitter Manager. + * @return {this} This Mesh Game Object. */ - emitParticle: function (count, x, y) + addVerticesFromObj: function (key, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp) { - var emitters = this.emitters.list; + var data = this.scene.sys.cache.obj.get(key); + var parsedData; - for (var i = 0; i < emitters.length; i++) + if (data) { - var emitter = emitters[i]; + parsedData = GenerateObjVerts(data, this, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp); + } - if (emitter.active) - { - emitter.emitParticle(count, x, y); - } + if (!parsedData || parsedData.verts.length === 0) + { + console.warn('Mesh.addVerticesFromObj data empty:', key); } return this; }, /** - * Emits particles from each active emitter. + * Compare the depth of two Faces. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#emitParticleAt - * @since 3.0.0 + * @method Phaser.GameObjects.Mesh#sortByDepth + * @since 3.50.0 * - * @param {number} [x] - The x-coordinate to to emit particles from. The default is the x-coordinate of the emitter's current location. - * @param {number} [y] - The y-coordinate to to emit particles from. The default is the y-coordinate of the emitter's current location. - * @param {number} [count] - The number of particles to release from each emitter. The default is the emitter's own {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. + * @param {Phaser.Geom.Mesh.Face} faceA - The first Face. + * @param {Phaser.Geom.Mesh.Face} faceB - The second Face. * - * @return {this} This Emitter Manager. + * @return {number} The difference between the depths of each Face. */ - emitParticleAt: function (x, y, count) + sortByDepth: function (faceA, faceB) { - return this.emitParticle(count, x, y); + return faceA.depth - faceB.depth; }, /** - * Pauses this Emitter Manager. - * - * This has the effect of pausing all emitters, and all particles of those emitters, currently under its control. + * Runs a depth sort across all Faces in this Mesh, comparing their averaged depth. * - * The particles will still render, but they will not have any of their logic updated. + * This is called automatically if you use any of the `rotate` methods, but you can + * also invoke it to sort the Faces should you manually position them. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#pause - * @since 3.0.0 + * @method Phaser.GameObjects.Mesh#depthSort + * @since 3.50.0 * - * @return {this} This Emitter Manager. + * @return {this} This Mesh Game Object. */ - pause: function () + depthSort: function () { - this.active = false; + StableSort(this.faces, this.sortByDepth); return this; }, /** - * Resumes this Emitter Manager, should it have been previously paused. + * Adds a new Vertex into the vertices array of this Mesh. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#resume - * @since 3.0.0 + * Just adding a vertex isn't enough to render it. You need to also + * make it part of a Face, with 3 Vertex instances per Face. + * + * @method Phaser.GameObjects.Mesh#addVertex + * @since 3.50.0 + * + * @param {number} x - The x position of the vertex. + * @param {number} y - The y position of the vertex. + * @param {number} z - The z position of the vertex. + * @param {number} u - The UV u coordinate of the vertex. + * @param {number} v - The UV v coordinate of the vertex. + * @param {number} [color=0xffffff] - The color value of the vertex. + * @param {number} [alpha=1] - The alpha value of the vertex. * - * @return {this} This Emitter Manager. + * @return {this} This Mesh Game Object. */ - resume: function () + addVertex: function (x, y, z, u, v, color, alpha) { - this.active = true; + var vert = new Vertex(x, y, z, u, v, color, alpha); - return this; + this.vertices.push(vert); + + return vert; }, /** - * Gets all active particle processors (gravity wells). + * Adds a new Face into the faces array of this Mesh. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#getProcessors - * @since 3.0.0 + * A Face consists of references to 3 Vertex instances, which must be provided. * - * @return {Phaser.GameObjects.Particles.GravityWell[]} - The active gravity wells. - */ - getProcessors: function () - { - return this.wells.getAll('active', true); - }, - - /** - * Updates all active emitters. + * @method Phaser.GameObjects.Mesh#addFace + * @since 3.50.0 * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#preUpdate - * @since 3.0.0 + * @param {Phaser.Geom.Mesh.Vertex} vertex1 - The first vertex of the Face. + * @param {Phaser.Geom.Mesh.Vertex} vertex2 - The second vertex of the Face. + * @param {Phaser.Geom.Mesh.Vertex} vertex3 - The third vertex of the Face. * - * @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. + * @return {this} This Mesh Game Object. */ - preUpdate: function (time, delta) + addFace: function (vertex1, vertex2, vertex3) { - // Scale the delta - delta *= this.timeScale; + var face = new Face(vertex1, vertex2, vertex3); - var emitters = this.emitters.list; + this.faces.push(face); - for (var i = 0; i < emitters.length; i++) - { - var emitter = emitters[i]; + this.dirtyCache[9] = -1; - if (emitter.active) - { - emitter.preUpdate(time, delta); - } - } + return face; }, /** - * A NOOP method so you can pass an EmitterManager to a Container. - * Calling this method will do nothing. It is intentionally empty. + * Adds new vertices to this Mesh by parsing the given data. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#setAlpha - * @private - * @since 3.10.0 - */ - setAlpha: function () - { - }, - - /** - * A NOOP method so you can pass an EmitterManager to a Container. - * Calling this method will do nothing. It is intentionally empty. + * This method will take vertex data in one of two formats, based on the `containsZ` parameter. * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#setScrollFactor - * @private - * @since 3.10.0 - */ - setScrollFactor: function () - { - }, - - /** - * A NOOP method so you can pass an EmitterManager to a Container. - * Calling this method will do nothing. It is intentionally empty. + * If your vertex data are `x`, `y` pairs, then `containsZ` should be `false` (this is the default, and will result in `z=0` for each vertex). * - * @method Phaser.GameObjects.Particles.ParticleEmitterManager#setBlendMode - * @private - * @since 3.15.0 + * 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 + * let mesh = new Mesh(this); // Assuming `this` is a scene! + * 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 ]; + * + * mesh.addVertices(vertices, uvs, indicies); + * // Note: Otherwise the added points will be "behind" the camera! This value will project vertex `x` & `y` values 1:1 to pixel values. + * mesh.hideCCW = false; + * mesh.setOrtho(mesh.width, mesh.height); + * ``` + * + * If the data is not indexed, it's assumed that the arrays all contain sequential data. + * + * @method Phaser.GameObjects.Mesh#addVertices + * @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? If not, it will be assumed `z=0`, see methods `panZ` or `setOrtho`. + * @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 {this} This Mesh Game Object. */ - setBlendMode: function () - { - } - -}); - -module.exports = ParticleEmitterManager; - - -/***/ }), -/* 221 */ -/***/ (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__(35); -var Camera = __webpack_require__(133); -var CanvasPool = __webpack_require__(31); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var CONST = __webpack_require__(33); -var Frame = __webpack_require__(109); -var GameObject = __webpack_require__(15); -var NOOP = __webpack_require__(1); -var PIPELINE_CONST = __webpack_require__(92); -var Render = __webpack_require__(1079); -var RenderTarget = __webpack_require__(141); -var Utils = __webpack_require__(12); -var UUID = __webpack_require__(222); - -/** - * @classdesc - * A Render Texture. - * - * A Render Texture is a special texture that allows any number of Game Objects to be drawn to it. You can take many complex objects and - * draw them all to this one texture, which can they be used as the texture for other Game Object's. It's a way to generate dynamic - * textures at run-time that are WebGL friendly and don't invoke expensive GPU uploads. - * - * Note that under WebGL a FrameBuffer, which is what the Render Texture uses internally, cannot be anti-aliased. This means - * that when drawing objects such as Shapes to a Render Texture they will appear to be drawn with no aliasing, however this - * is a technical limitation of WebGL. To get around it, create your shape as a texture in an art package, then draw that - * to the Render Texture. - * - * @class RenderTexture - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.2.0 - * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.ComputedSize - * @extends Phaser.GameObjects.Components.Crop - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @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=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=32] - The width of the Render Texture. - * @param {number} [height=32] - The height of the Render Texture. - * @param {string} [key] - The texture key to make the RenderTexture from. - * @param {string} [frame] - The frame to make the RenderTexture from. - */ -var RenderTexture = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.ComputedSize, - Components.Crop, - Components.Depth, - Components.Flip, - Components.GetBounds, - Components.Mask, - Components.Origin, - Components.Pipeline, - Components.ScrollFactor, - Components.Tint, - Components.Transform, - Components.Visible, - Render - ], - - initialize: - - function RenderTexture (scene, x, y, width, height, key, frame) + addVertices: function (vertices, uvs, indicies, containsZ, normals, colors, alphas) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 32; } - if (height === undefined) { height = 32; } - - GameObject.call(this, scene, 'RenderTexture'); - - /** - * A reference to either the Canvas or WebGL Renderer that the Game instance is using. - * - * @name Phaser.GameObjects.RenderTexture#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.2.0 - */ - this.renderer = scene.sys.renderer; - - /** - * A reference to the Texture Manager. - * - * @name Phaser.GameObjects.RenderTexture#textureManager - * @type {Phaser.Textures.TextureManager} - * @since 3.12.0 - */ - this.textureManager = scene.sys.textures; - - /** - * The tint of the Render Texture when rendered. - * - * @name Phaser.GameObjects.RenderTexture#globalTint - * @type {number} - * @default 0xffffff - * @since 3.2.0 - */ - this.globalTint = 0xffffff; - - /** - * The alpha of the Render Texture when rendered. - * - * @name Phaser.GameObjects.RenderTexture#globalAlpha - * @type {number} - * @default 1 - * @since 3.2.0 - */ - this.globalAlpha = 1; - - /** - * The HTML Canvas Element that the Render Texture is drawing to when using the Canvas Renderer. - * - * @name Phaser.GameObjects.RenderTexture#canvas - * @type {HTMLCanvasElement} - * @since 3.2.0 - */ - this.canvas = null; - - /** - * Is this Render Texture dirty or not? If not it won't spend time clearing or filling itself. - * - * @name Phaser.GameObjects.RenderTexture#dirty - * @type {boolean} - * @since 3.12.0 - */ - this.dirty = false; - - /** - * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. - * - * @name Phaser.GameObjects.RenderTexture#_crop - * @type {object} - * @private - * @since 3.12.0 - */ - this._crop = this.resetCropObject(); - - /** - * The Texture corresponding to this Render Texture. - * - * @name Phaser.GameObjects.RenderTexture#texture - * @type {Phaser.Textures.Texture} - * @since 3.12.0 - */ - this.texture = null; - - /** - * The Frame corresponding to this Render Texture. - * - * @name Phaser.GameObjects.RenderTexture#frame - * @type {Phaser.Textures.Frame} - * @since 3.12.0 - */ - this.frame = null; - - /** - * Internal saved texture flag. - * - * @name Phaser.GameObjects.RenderTexture#_saved - * @type {boolean} - * @private - * @since 3.12.0 - */ - this._saved = false; + var result = GenerateVerts(vertices, uvs, indicies, containsZ, normals, colors, alphas); - if (key === undefined) + if (result) { - this.canvas = CanvasPool.create2D(this, width, height); - - // Create a new Texture for this RenderTexture object - this.texture = scene.sys.textures.addCanvas(UUID(), this.canvas); - - // Get the frame - this.frame = this.texture.get(); + this.faces = this.faces.concat(result.faces); + this.vertices = this.vertices.concat(result.vertices); } else { - this.texture = scene.sys.textures.get(key); - - // Get the frame - this.frame = this.texture.get(frame); - - this.canvas = this.frame.source.image; - this._saved = true; - - this.dirty = true; - - this.width = this.frame.cutWidth; - this.height = this.frame.cutHeight; - } - - /** - * A reference to the Rendering Context belonging to the Canvas Element this Render Texture is drawing to. - * - * @name Phaser.GameObjects.RenderTexture#context - * @type {CanvasRenderingContext2D} - * @since 3.2.0 - */ - this.context = this.canvas.getContext('2d'); - - /** - * Internal erase mode flag. - * - * @name Phaser.GameObjects.RenderTexture#_eraseMode - * @type {boolean} - * @private - * @since 3.16.0 - */ - this._eraseMode = false; - - /** - * An internal Camera that can be used to move around the Render Texture. - * Control it just like you would any Scene Camera. The difference is that it only impacts the placement of what - * is drawn to the Render Texture. You can scroll, zoom and rotate this Camera. - * - * @name Phaser.GameObjects.RenderTexture#camera - * @type {Phaser.Cameras.Scene2D.BaseCamera} - * @since 3.12.0 - */ - this.camera = new Camera(0, 0, width, height); - - /** - * The Render Target that belongs to this Render Texture. - * - * A Render Target encapsulates a framebuffer and texture for the WebGL Renderer. - * - * This property remains `null` under Canvas. - * - * @name Phaser.GameObjects.RenderTexture#renderTarget - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @since 3.50.0 - */ - this.renderTarget = null; - - var renderer = this.renderer; - - if (!renderer) - { - this.drawGameObject = NOOP; - } - else if (renderer.type === CONST.WEBGL) - { - this.drawGameObject = this.batchGameObjectWebGL; - - this.renderTarget = new RenderTarget(renderer, width, height, 1, 0, false); - } - else if (renderer.type === CONST.CANVAS) - { - this.drawGameObject = this.batchGameObjectCanvas; - } - - this.camera.setScene(scene); - - this.setPosition(x, y); - - if (key === undefined) - { - this.setSize(width, height); + console.warn('Mesh.addVertices data empty or invalid'); } - this.setOrigin(0, 0); + this.dirtyCache[9] = -1; - this.initPipeline(PIPELINE_CONST.SINGLE_PIPELINE); + return this; }, /** - * Sets the size of this Game Object. - * - * @method Phaser.GameObjects.RenderTexture#setSize - * @since 3.0.0 + * Returns the total number of Faces in this Mesh Game Object. * - * @param {number} width - The width of this Game Object. - * @param {number} height - The height of this Game Object. + * @method Phaser.GameObjects.Mesh#getFaceCount + * @since 3.50.0 * - * @return {this} This Game Object instance. + * @return {number} The number of Faces in this Mesh Game Object. */ - setSize: function (width, height) + getFaceCount: function () { - return this.resize(width, height); + return this.faces.length; }, /** - * Resizes the Render Texture to the new dimensions given. + * Returns the total number of Vertices in this Mesh Game Object. * - * If Render Texture was created from specific frame, only the size of the frame will be changed. The size of the source - * texture will not change. + * @method Phaser.GameObjects.Mesh#getVertexCount + * @since 3.50.0 + * + * @return {number} The number of Vertices in this Mesh Game Object. + */ + getVertexCount: function () + { + return this.vertices.length; + }, + + /** + * Returns the Face at the given index in this Mesh Game Object. * - * If Render Texture was not created from specific frame, the following will happen: + * @method Phaser.GameObjects.Mesh#getFace + * @since 3.50.0 * - * In WebGL it will destroy and then re-create the frame buffer being used by the Render Texture. - * In Canvas it will resize the underlying canvas element. + * @param {number} index - The index of the Face to get. * - * Both approaches will erase everything currently drawn to the Render Texture. + * @return {Phaser.Geom.Mesh.Face} The Face at the given index, or `undefined` if index out of range. + */ + getFace: function (index) + { + return this.faces[index]; + }, + + /** + * Tests to see if _any_ face in this Mesh intersects with the given coordinates. * - * If the dimensions given are the same as those already being used, calling this method will do nothing. + * The given position is translated through the matrix of this Mesh and the given Camera, + * before being compared against the vertices. * - * @method Phaser.GameObjects.RenderTexture#resize - * @since 3.10.0 + * @method Phaser.GameObjects.Mesh#hasFaceAt + * @since 3.60.0 * - * @param {number} width - The new width of the Render Texture. - * @param {number} [height=width] - The new height of the Render Texture. If not specified, will be set the same as the `width`. + * @param {number} x - The x position to check against. + * @param {number} y - The y position to check against. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The camera to pass the coordinates through. If not give, the default Scene Camera is used. * - * @return {this} This Render Texture. + * @return {boolean} Returns `true` if _any_ face of this Mesh intersects with the given coordinate, otherwise `false`. */ - resize: function (width, height) + hasFaceAt: function (x, y, camera) { - if (height === undefined) { height = width; } - - var frame = this.frame; - - if (width !== this.width || height !== this.height) - { - if (frame.name === '__BASE') - { - // Resize the texture - - this.canvas.width = width; - this.canvas.height = height; - - this.texture.width = width; - this.texture.height = height; - - var renderTarget = this.renderTarget; - - if (renderTarget) - { - renderTarget.resize(width, height); - - frame.glTexture = renderTarget.texture; - - frame.source.isRenderTexture = true; - frame.source.isGLTexture = true; - frame.source.glTexture = renderTarget.texture; - } - - this.camera.setSize(width, height); + if (camera === undefined) { camera = this.scene.sys.cameras.main; } - frame.source.width = width; - frame.source.height = height; + var calcMatrix = GetCalcMatrix(this, camera).calc; - frame.setSize(width, height); + var faces = this.faces; - this.width = width; - this.height = height; - } - } - else + for (var i = 0; i < faces.length; i++) { - // Resize the frame - - var baseFrame = this.texture.getSourceImage(); - - if (frame.cutX + width > baseFrame.width) - { - width = baseFrame.width - frame.cutX; - } + var face = faces[i]; - if (frame.cutY + height > baseFrame.height) + if (face.contains(x, y, calcMatrix)) { - height = baseFrame.height - frame.cutY; + return true; } - - frame.setSize(width, height, frame.cutX, frame.cutY); - } - - this.updateDisplayOrigin(); - - var input = this.input; - - if (input && !input.customHitArea) - { - input.hitArea.width = width; - input.hitArea.height = height; } - return this; + return false; }, /** - * Set the tint to use when rendering this Render Texture. + * Return an array of Face objects from this Mesh that intersect with the given coordinates. * - * @method Phaser.GameObjects.RenderTexture#setGlobalTint - * @since 3.2.0 + * The given position is translated through the matrix of this Mesh and the given Camera, + * before being compared against the vertices. * - * @param {number} tint - The tint value. + * If more than one Face intersects, they will all be returned in the array, but the array will + * be depth sorted first, so the first element will always be that closest to the camera. * - * @return {this} This Render Texture. + * @method Phaser.GameObjects.Mesh#getFaceAt + * @since 3.50.0 + * + * @param {number} x - The x position to check against. + * @param {number} y - The y position to check against. + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The camera to pass the coordinates through. If not give, the default Scene Camera is used. + * + * @return {Phaser.Geom.Mesh.Face[]} An array of Face objects that intersect with the given point, ordered by depth. */ - setGlobalTint: function (tint) + getFaceAt: function (x, y, camera) { - this.globalTint = tint; + if (camera === undefined) { camera = this.scene.sys.cameras.main; } - return this; + var calcMatrix = GetCalcMatrix(this, camera).calc; + + var faces = this.faces; + var results = []; + + for (var i = 0; i < faces.length; i++) + { + var face = faces[i]; + + if (face.contains(x, y, calcMatrix)) + { + results.push(face); + } + } + + return StableSort(results, this.sortByDepth); }, /** - * Set the alpha to use when rendering this Render Texture. + * This method enables rendering of the Mesh vertices to the given Graphics instance. * - * @method Phaser.GameObjects.RenderTexture#setGlobalAlpha - * @since 3.2.0 + * If you enable this feature, you **must** call `Graphics.clear()` in your Scene `update`, + * otherwise the Graphics instance you provide to debug will fill-up with draw calls, + * eventually crashing the browser. This is not done automatically to allow you to debug + * draw multiple Mesh objects to a single Graphics instance. * - * @param {number} alpha - The alpha value. + * The Mesh class has a built-in debug rendering callback `Mesh.renderDebug`, however + * you can also provide your own callback to be used instead. Do this by setting the `callback` parameter. * - * @return {this} This Render Texture. - */ - setGlobalAlpha: function (alpha) - { - this.globalAlpha = alpha; - - return this; - }, - - /** - * Stores a copy of this Render Texture in the Texture Manager using the given key. + * The callback is invoked _once per render_ and sent the following parameters: * - * After doing this, any texture based Game Object, such as a Sprite, can use the contents of this - * Render Texture by using the texture key: + * `callback(src, faces)` * - * ```javascript - * var rt = this.add.renderTexture(0, 0, 128, 128); + * `src` is the Mesh instance being debugged. + * `faces` is an array of the Faces that were rendered. * - * // Draw something to the Render Texture + * You can get the final drawn vertex position from a Face object like this: * - * rt.saveTexture('doodle'); + * ```javascript + * let face = faces[i]; * - * this.add.image(400, 300, 'doodle'); - * ``` + * let x0 = face.vertex1.tx; + * let y0 = face.vertex1.ty; + * let x1 = face.vertex2.tx; + * let y1 = face.vertex2.ty; + * let x2 = face.vertex3.tx; + * let y2 = face.vertex3.ty; * - * Updating the contents of this Render Texture will automatically update _any_ Game Object - * that is using it as a texture. Calling `saveTexture` again will not save another copy - * of the same texture, it will just rename the key of the existing copy. + * graphic.strokeTriangle(x0, y0, x1, y1, x2, y2); + * ``` * - * By default it will create a single base texture. You can add frames to the texture - * by using the `Texture.add` method. After doing this, you can then allow Game Objects - * to use a specific frame from a Render Texture. + * If using your own callback you do not have to provide a Graphics instance to this method. * - * If you destroy this Render Texture, any Game Object using it via the Texture Manager will - * stop rendering. Ensure you remove the texture from the Texture Manager and any Game Objects - * using it first, before destroying this Render Texture. + * To disable debug rendering, to either your own callback or the built-in one, call this method + * with no arguments. * - * @method Phaser.GameObjects.RenderTexture#saveTexture - * @since 3.12.0 + * @method Phaser.GameObjects.Mesh#setDebug + * @since 3.50.0 * - * @param {string} key - The unique key to store the texture as within the global Texture Manager. + * @param {Phaser.GameObjects.Graphics} [graphic] - The Graphic instance to render to if using the built-in callback. + * @param {function} [callback] - The callback to invoke during debug render. Leave as undefined to use the built-in callback. * - * @return {Phaser.Textures.Texture} The Texture that was saved. + * @return {this} This Game Object instance. */ - saveTexture: function (key) + setDebug: function (graphic, callback) { - this.textureManager.renameTexture(this.texture.key, key); + this.debugGraphic = graphic; - this._saved = true; + if (!graphic && !callback) + { + this.debugCallback = null; + } + else if (!callback) + { + this.debugCallback = this.renderDebug; + } + else + { + this.debugCallback = callback; + } - return this.texture; + return this; }, /** - * Fills the Render Texture with the given color. + * Checks if the transformation data in this mesh is dirty. * - * @method Phaser.GameObjects.RenderTexture#fill - * @since 3.2.0 + * This is used internally by the `preUpdate` step to determine if the vertices should + * be recalculated or not. * - * @param {number} rgb - The color to fill the Render Texture with. - * @param {number} [alpha=1] - The alpha value used by the fill. - * @param {number} [x=0] - The left coordinate of the fill rectangle. - * @param {number} [y=0] - The top coordinate of the fill rectangle. - * @param {number} [width=this.frame.cutWidth] - The width of the fill rectangle. - * @param {number} [height=this.frame.cutHeight] - The height of the fill rectangle. + * @method Phaser.GameObjects.Mesh#isDirty + * @since 3.50.0 * - * @return {this} This Render Texture instance. + * @return {boolean} Returns `true` if the data of this mesh is dirty, otherwise `false`. */ - fill: function (rgb, alpha, x, y, width, height) + isDirty: function () { - var frame = this.frame; - var camera = this.camera; - var renderer = this.renderer; - - if (alpha === undefined) { alpha = 1; } - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = frame.cutWidth; } - if (height === undefined) { height = frame.cutHeight; } - - var r = (rgb >> 16 & 0xFF) / 255; - var g = (rgb >> 8 & 0xFF) / 255; - var b = (rgb & 0xFF) / 255; - - var renderTarget = this.renderTarget; - - camera.preRender(); + var position = this.modelPosition; + var rotation = this.modelRotation; + var scale = this.modelScale; + var dirtyCache = this.dirtyCache; - if (renderTarget) - { - renderTarget.bind(true); + var px = position.x; + var py = position.y; + var pz = position.z; - var pipeline = this.pipeline; + var rx = rotation.x; + var ry = rotation.y; + var rz = rotation.z; - pipeline.manager.set(pipeline); + var sx = scale.x; + var sy = scale.y; + var sz = scale.z; - var tw = renderTarget.width; - var th = renderTarget.height; + var faces = this.getFaceCount(); - var rw = renderer.width; - var rh = renderer.height; + var pxCached = dirtyCache[0]; + var pyCached = dirtyCache[1]; + var pzCached = dirtyCache[2]; - var sx = rw / tw; - var sy = rh / th; + var rxCached = dirtyCache[3]; + var ryCached = dirtyCache[4]; + var rzCached = dirtyCache[5]; - pipeline.drawFillRect( - x * sx, y * sy, width * sx, height * sy, - Utils.getTintFromFloats(b, g, r, 1), - alpha - ); + var sxCached = dirtyCache[6]; + var syCached = dirtyCache[7]; + var szCached = dirtyCache[8]; - renderTarget.unbind(true); - } - else - { - var ctx = this.context; + var fCached = dirtyCache[9]; - renderer.setContext(ctx); + dirtyCache[0] = px; + dirtyCache[1] = py; + dirtyCache[2] = pz; - ctx.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')'; - ctx.fillRect(x + frame.cutX, y + frame.cutY, width, height); + dirtyCache[3] = rx; + dirtyCache[4] = ry; + dirtyCache[5] = rz; - renderer.setContext(); - } + dirtyCache[6] = sx; + dirtyCache[7] = sy; + dirtyCache[8] = sz; - this.dirty = true; + dirtyCache[9] = faces; - return this; + return ( + pxCached !== px || pyCached !== py || pzCached !== pz || + rxCached !== rx || ryCached !== ry || rzCached !== rz || + sxCached !== sx || syCached !== sy || szCached !== sz || + fCached !== faces + ); }, /** - * Clears the Render Texture. + * The Mesh update loop. The following takes place in this method: * - * @method Phaser.GameObjects.RenderTexture#clear - * @since 3.2.0 + * First, the `totalRendered` and `totalFrame` properties are set. * - * @return {this} This Render Texture instance. + * If the view matrix of this Mesh isn't dirty, and the model position, rotate or scale properties are + * all clean, then the method returns at this point. + * + * Otherwise, if the viewPosition is dirty (i.e. from calling a method like `panZ`), then it will + * refresh the viewMatrix. + * + * After this, a new transformMatrix is built and it then iterates through all Faces in this + * Mesh, calling `transformCoordinatesLocal` on all of them. Internally, this updates every + * vertex, calculating its new transformed position, based on the new transform matrix. + * + * Finally, the faces are depth sorted. + * + * @method Phaser.GameObjects.Mesh#preUpdate + * @protected + * @since 3.50.0 + * + * @param {number} time - The current timestamp. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. */ - clear: function () + preUpdate: function () { - if (this.dirty) + this.totalRendered = this.totalFrame; + this.totalFrame = 0; + + var dirty = this.dirtyCache; + + if (!this.ignoreDirtyCache && !dirty[10] && !this.isDirty()) { - var renderTarget = this.renderTarget; + // If neither the view or the mesh is dirty we can bail out and save lots of math + return; + } - if (renderTarget) - { - renderTarget.clear(); - } - else - { - var ctx = this.context; + var width = this.width; + var height = this.height; - ctx.save(); - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.clearRect(this.frame.cutX, this.frame.cutY, this.frame.cutWidth, this.frame.cutHeight); - ctx.restore(); - } + var viewMatrix = this.viewMatrix; + var viewPosition = this.viewPosition; - this.dirty = false; + if (dirty[10]) + { + viewMatrix.identity(); + viewMatrix.translate(viewPosition); + viewMatrix.invert(); + + dirty[10] = 0; } - return this; + var transformMatrix = this.transformMatrix; + + transformMatrix.setWorldMatrix( + this.modelRotation, + this.modelPosition, + this.modelScale, + this.viewMatrix, + this.projectionMatrix + ); + + var z = viewPosition.z; + + var faces = this.faces; + + for (var i = 0; i < faces.length; i++) + { + faces[i].transformCoordinatesLocal(transformMatrix, width, height, z); + } + + this.depthSort(); }, /** - * Draws the given object, or an array of objects, to this Render Texture using a blend mode of ERASE. - * This has the effect of erasing any filled pixels in the objects from this Render Texture. - * - * It can accept any of the following: - * - * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. - * * Tilemap Layers. - * * A Group. The contents of which will be iterated and drawn in turn. - * * A Container. The contents of which will be iterated fully, and drawn in turn. - * * A Scene's Display List. Pass in `Scene.children` to draw the whole list. - * * Another Render Texture. - * * A Texture Frame instance. - * * A string. This is used to look-up a texture from the Texture Manager. - * - * Note: You cannot erase a Render Texture from itself. - * - * If passing in a Group or Container it will only draw children that return `true` - * when their `willRender()` method is called. I.e. a Container with 10 children, - * 5 of which have `visible=false` will only draw the 5 visible ones. - * - * If passing in an array of Game Objects it will draw them all, regardless if - * they pass a `willRender` check or not. - * - * You can pass in a string in which case it will look for a texture in the Texture - * Manager matching that string, and draw the base frame. - * - * You can pass in the `x` and `y` coordinates to draw the objects at. The use of - * the coordinates differ based on what objects are being drawn. If the object is - * a Group, Container or Display List, the coordinates are _added_ to the positions - * of the children. For all other types of object, the coordinates are exact. - * - * Calling this method causes the WebGL batch to flush, so it can write the texture - * data to the framebuffer being used internally. The batch is flushed at the end, - * after the entries have been iterated. So if you've a bunch of objects to draw, - * try and pass them in an array in one single call, rather than making lots of - * separate calls. + * The built-in Mesh debug rendering method. * - * @method Phaser.GameObjects.RenderTexture#erase - * @since 3.16.0 + * See `Mesh.setDebug` for more details. * - * @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these. - * @param {number} [x] - The x position to draw the Frame at, or the offset applied to the object. - * @param {number} [y] - The y position to draw the Frame at, or the offset applied to the object. + * @method Phaser.GameObjects.Mesh#renderDebug + * @since 3.50.0 * - * @return {this} This Render Texture instance. + * @param {Phaser.GameObjects.Mesh} src - The Mesh object being rendered. + * @param {Phaser.Geom.Mesh.Face[]} faces - An array of Faces. */ - erase: function (entries, x, y) + renderDebug: function (src, faces) { - this._eraseMode = true; + var graphic = src.debugGraphic; - this.draw(entries, x, y, 1, 16777215); + for (var i = 0; i < faces.length; i++) + { + var face = faces[i]; - this._eraseMode = false; + var x0 = face.vertex1.tx; + var y0 = face.vertex1.ty; + var x1 = face.vertex2.tx; + var y1 = face.vertex2.ty; + var x2 = face.vertex3.tx; + var y2 = face.vertex3.ty; - return this; + graphic.strokeTriangle(x0, y0, x1, y1, x2, y2); + } }, /** - * Draws the given object, or an array of objects, to this Render Texture. - * - * It can accept any of the following: - * - * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. - * * Tilemap Layers. - * * A Group. The contents of which will be iterated and drawn in turn. - * * A Container. The contents of which will be iterated fully, and drawn in turn. - * * A Scene's Display List. Pass in `Scene.children` to draw the whole list. - * * Another Render Texture. - * * A Texture Frame instance. - * * A string. This is used to look-up a texture from the Texture Manager. - * - * Note: You cannot draw a Render Texture to itself. - * - * If passing in a Group or Container it will only draw children that return `true` - * when their `willRender()` method is called. I.e. a Container with 10 children, - * 5 of which have `visible=false` will only draw the 5 visible ones. - * - * If passing in an array of Game Objects it will draw them all, regardless if - * they pass a `willRender` check or not. - * - * You can pass in a string in which case it will look for a texture in the Texture - * Manager matching that string, and draw the base frame. If you need to specify - * exactly which frame to draw then use the method `drawFrame` instead. - * - * You can pass in the `x` and `y` coordinates to draw the objects at. The use of - * the coordinates differ based on what objects are being drawn. If the object is - * a Group, Container or Display List, the coordinates are _added_ to the positions - * of the children. For all other types of object, the coordinates are exact. - * - * The `alpha` and `tint` values are only used by Texture Frames. - * Game Objects use their own alpha and tint values when being drawn. + * Handles the pre-destroy step for the Mesh, which removes the vertices and debug callbacks. * - * Calling this method causes the WebGL batch to flush, so it can write the texture - * data to the framebuffer being used internally. The batch is flushed at the end, - * after the entries have been iterated. So if you've a bunch of objects to draw, - * try and pass them in an array in one single call, rather than making lots of - * separate calls. - * - * @method Phaser.GameObjects.RenderTexture#draw - * @since 3.2.0 - * - * @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these. - * @param {number} [x] - The x position to draw the Frame at, or the offset applied to the object. - * @param {number} [y] - The y position to draw the Frame at, or the offset applied to the object. - * @param {number} [alpha] - The alpha value. Only used for Texture Frames and if not specified defaults to the `globalAlpha` property. Game Objects use their own current alpha value. - * @param {number} [tint] - WebGL only. The tint color value. Only used for Texture Frames and if not specified defaults to the `globalTint` property. Game Objects use their own current tint value. - * - * @return {this} This Render Texture instance. + * @method Phaser.GameObjects.Mesh#preDestroy + * @private + * @since 3.50.0 */ - draw: function (entries, x, y, alpha, tint) + preDestroy: function () { - this.beginDraw(); - this.batchDraw(entries, x, y, alpha, tint); - this.endDraw(); + this.clear(); - return this; + this.debugCallback = null; + this.debugGraphic = null; }, /** - * Draws the Texture Frame to the Render Texture at the given position. - * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * - * ```javascript - * var rt = this.add.renderTexture(0, 0, 800, 600); - * rt.drawFrame(key, frame); - * ``` - * - * You can optionally provide a position, alpha and tint value to apply to the frame - * before it is drawn. - * - * Calling this method will cause a batch flush, so if you've got a stack of things to draw - * in a tight loop, try using the `draw` method instead. - * - * If you need to draw a Sprite to this Render Texture, use the `draw` method instead. + * Clears all tint values associated with this Game Object. * - * @method Phaser.GameObjects.RenderTexture#drawFrame - * @since 3.12.0 + * Immediately sets the color values back to 0xffffff on all vertices, + * which results in no visible change to the texture. * - * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. - * @param {(string|number)} [frame] - The name or index of the frame within the Texture. - * @param {number} [x=0] - The x position to draw the frame at. - * @param {number} [y=0] - The y position to draw the frame at. - * @param {number} [alpha] - The alpha to use. If not specified it uses the `globalAlpha` property. - * @param {number} [tint] - WebGL only. The tint color to use. If not specified it uses the `globalTint` property. + * @method Phaser.GameObjects.Mesh#clearTint + * @webglOnly + * @since 3.60.0 * - * @return {this} This Render Texture instance. + * @return {this} This Game Object instance. */ - drawFrame: function (key, frame, x, y, alpha, tint) + clearTint: function () { - this.beginDraw(); - this.batchDrawFrame(key, frame, x, y, alpha, tint); - this.endDraw(); - - return this; + return this.setTint(); }, /** - * Use this method if you need to batch draw a large number of Game Objects to - * this Render Texture in a single go, or on a frequent basis. - * - * This method starts the beginning of a batched draw. - * - * It is faster than calling `draw`, but you must be very careful to manage the - * flow of code and remember to call `endDraw()`. If you don't need to draw large - * numbers of objects it's much safer and easier to use the `draw` method instead. - * - * The flow should be: - * - * ```javascript - * // Call once: - * RenderTexture.beginDraw(); - * - * // repeat n times: - * RenderTexture.batchDraw(); - * // or - * RenderTexture.batchDrawFrame(); + * Pass this Mesh Game Object to the Input Manager to enable it for Input. * - * // Call once: - * RenderTexture.endDraw(); - * ``` + * Unlike other Game Objects, the Mesh Game Object uses its own special hit area callback, which you cannot override. * - * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you - * have started a batch. Also, be very careful not to destroy this Render Texture while the - * batch is still open, or call `beginDraw` again. + * @example + * mesh.setInteractive(); * - * @method Phaser.GameObjects.RenderTexture#beginDraw - * @since 3.50.0 + * @method Phaser.GameObjects.Mesh#setInteractive + * @since 3.60.0 * - * @return {this} This Render Texture instance. + * @return {this} This GameObject. */ - beginDraw: function () + setInteractive: function () { - var camera = this.camera; - var renderer = this.renderer; - var renderTarget = this.renderTarget; - - camera.preRender(); + var faces = this.faces; - if (renderTarget) - { - renderer.beginCapture(renderTarget.width, renderTarget.height); - } - else + var hitAreaCallback = function (area, x, y) { - renderer.setContext(this.context); - } + for (var i = 0; i < faces.length; i++) + { + var face = faces[i]; + + // Don't pass a calcMatrix, as the x/y are already transformed + if (face.contains(x, y)) + { + return true; + } + } + + return false; + }; + + this.scene.sys.input.enable(this, hitAreaCallback); return this; }, /** - * Use this method if you have already called `beginDraw` and need to batch - * draw a large number of objects to this Render Texture. - * - * This method batches the drawing of the given objects to this Render Texture, - * without causing a bind or batch flush. - * - * It is faster than calling `draw`, but you must be very careful to manage the - * flow of code and remember to call `endDraw()`. If you don't need to draw large - * numbers of objects it's much safer and easier to use the `draw` method instead. - * - * The flow should be: - * - * ```javascript - * // Call once: - * RenderTexture.beginDraw(); - * - * // repeat n times: - * RenderTexture.batchDraw(); - * // or - * RenderTexture.batchDrawFrame(); - * - * // Call once: - * RenderTexture.endDraw(); - * ``` + * Sets an additive tint on all vertices of this Mesh Game Object. * - * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you - * have started a batch. Also, be very careful not to destroy this Render Texture while the - * batch is still open, or call `beginDraw` again. - * - * Draws the given object, or an array of objects, to this Render Texture. - * - * It can accept any of the following: - * - * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. - * * Tilemap Layers. - * * A Group. The contents of which will be iterated and drawn in turn. - * * A Container. The contents of which will be iterated fully, and drawn in turn. - * * A Scene's Display List. Pass in `Scene.children` to draw the whole list. - * * Another Render Texture. - * * A Texture Frame instance. - * * A string. This is used to look-up a texture from the Texture Manager. - * - * Note: You cannot draw a Render Texture to itself. - * - * If passing in a Group or Container it will only draw children that return `true` - * when their `willRender()` method is called. I.e. a Container with 10 children, - * 5 of which have `visible=false` will only draw the 5 visible ones. - * - * If passing in an array of Game Objects it will draw them all, regardless if - * they pass a `willRender` check or not. - * - * You can pass in a string in which case it will look for a texture in the Texture - * Manager matching that string, and draw the base frame. If you need to specify - * exactly which frame to draw then use the method `drawFrame` instead. + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. * - * You can pass in the `x` and `y` coordinates to draw the objects at. The use of - * the coordinates differ based on what objects are being drawn. If the object is - * a Group, Container or Display List, the coordinates are _added_ to the positions - * of the children. For all other types of object, the coordinates are exact. + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. * - * The `alpha` and `tint` values are only used by Texture Frames. - * Game Objects use their own alpha and tint values when being drawn. + * To remove a tint call `clearTint`. * - * @method Phaser.GameObjects.RenderTexture#batchDraw - * @since 3.50.0 + * @method Phaser.GameObjects.Mesh#setTint + * @webglOnly + * @since 3.60.0 * - * @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these. - * @param {number} [x] - The x position to draw the Frame at, or the offset applied to the object. - * @param {number} [y] - The y position to draw the Frame at, or the offset applied to the object. - * @param {number} [alpha] - The alpha value. Only used for Texture Frames and if not specified defaults to the `globalAlpha` property. Game Objects use their own current alpha value. - * @param {number} [tint] - WebGL only. The tint color value. Only used for Texture Frames and if not specified defaults to the `globalTint` property. Game Objects use their own current tint value. + * @param {number} [tint=0xffffff] - The tint being applied to all vertices of this Mesh Game Object. * - * @return {this} This Render Texture instance. + * @return {this} This Game Object instance. */ - batchDraw: function (entries, x, y, alpha, tint) + setTint: function (tint) { - if (alpha === undefined) { alpha = this.globalAlpha; } + if (tint === undefined) { tint = 0xffffff; } - if (tint === undefined) - { - tint = (this.globalTint >> 16) + (this.globalTint & 0xff00) + ((this.globalTint & 0xff) << 16); - } - else - { - tint = (tint >> 16) + (tint & 0xff00) + ((tint & 0xff) << 16); - } + var vertices = this.vertices; - if (!Array.isArray(entries)) + for (var i = 0; i < vertices.length; i++) { - entries = [ entries ]; + vertices[i].color = tint; } - this.batchList(entries, x, y, alpha, tint); - return this; }, /** - * Use this method if you have already called `beginDraw` and need to batch - * draw a large number of texture frames to this Render Texture. - * - * This method batches the drawing of the given frames to this Render Texture, - * without causing a bind or batch flush. - * - * It is faster than calling `drawFrame`, but you must be very careful to manage the - * flow of code and remember to call `endDraw()`. If you don't need to draw large - * numbers of frames it's much safer and easier to use the `drawFrame` method instead. - * - * The flow should be: - * - * ```javascript - * // Call once: - * RenderTexture.beginDraw(); - * - * // repeat n times: - * RenderTexture.batchDraw(); - * // or - * RenderTexture.batchDrawFrame(); - * - * // Call once: - * RenderTexture.endDraw(); - * ``` - * - * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you - * have started a batch. Also, be very careful not to destroy this Render Texture while the - * batch is still open, or call `beginDraw` again. - * - * Draws the Texture Frame to the Render Texture at the given position. + * Scrolls the UV texture coordinates of all faces in this Mesh by + * adding the given x/y amounts to them. * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * - * ```javascript - * var rt = this.add.renderTexture(0, 0, 800, 600); - * rt.drawFrame(key, frame); - * ``` + * If you only wish to scroll one coordinate, pass a value of zero + * to the other. * - * You can optionally provide a position, alpha and tint value to apply to the frame - * before it is drawn. + * Use small values for scrolling. UVs are set from the range 0 + * to 1, so you should increment (or decrement) them by suitably + * small values, such as 0.01. * - * Calling this method will cause a batch flush, so if you've got a stack of things to draw - * in a tight loop, try using the `draw` method instead. + * Due to a limitation in WebGL1 you can only UV scroll textures + * that are a power-of-two in size. Scrolling NPOT textures will + * work but will result in clamping the pixels to the edges. * - * If you need to draw a Sprite to this Render Texture, use the `draw` method instead. + * Note that if this Mesh is using a _frame_ from a texture atlas + * then you will be unable to UV scroll its texture. * - * @method Phaser.GameObjects.RenderTexture#batchDrawFrame - * @since 3.50.0 + * @method Phaser.GameObjects.Mesh#uvScroll + * @webglOnly + * @since 3.60.0 * - * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. - * @param {(string|number)} [frame] - The name or index of the frame within the Texture. - * @param {number} [x=0] - The x position to draw the frame at. - * @param {number} [y=0] - The y position to draw the frame at. - * @param {number} [alpha] - The alpha to use. If not specified it uses the `globalAlpha` property. - * @param {number} [tint] - WebGL only. The tint color to use. If not specified it uses the `globalTint` property. + * @param {number} x - The amount to horizontally shift the UV coordinates by. + * @param {number} y - The amount to vertically shift the UV coordinates by. * - * @return {this} This Render Texture instance. + * @return {this} This Game Object instance. */ - batchDrawFrame: function (key, frame, x, y, alpha, tint) + uvScroll: function (x, y) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (alpha === undefined) { alpha = this.globalAlpha; } - - if (tint === undefined) - { - tint = (this.globalTint >> 16) + (this.globalTint & 0xff00) + ((this.globalTint & 0xff) << 16); - } - else - { - tint = (tint >> 16) + (tint & 0xff00) + ((tint & 0xff) << 16); - } - - var textureFrame = this.textureManager.getFrame(key, frame); + var faces = this.faces; - if (textureFrame) + for (var i = 0; i < faces.length; i++) { - if (this.renderTarget) - { - this.pipeline.batchTextureFrame(textureFrame, x, y, tint, alpha, this.camera.matrix, null); - } - else - { - this.batchTextureFrame(textureFrame, x + this.frame.cutX, y + this.frame.cutY, alpha, tint); - } + faces[i].scrollUV(x, y); } return this; }, /** - * Use this method to finish batch drawing to this Render Texture. - * - * Never call this method without first calling `beginDraw`. - * - * It is faster than calling `draw`, but you must be very careful to manage the - * flow of code and remember to call `endDraw()`. If you don't need to draw large - * numbers of objects it's much safer and easier to use the `draw` method instead. - * - * The flow should be: - * - * ```javascript - * // Call once: - * RenderTexture.beginDraw(); + * Scales the UV texture coordinates of all faces in this Mesh by + * the exact given amounts. * - * // repeat n times: - * RenderTexture.batchDraw(); - * // or - * RenderTexture.batchDrawFrame(); + * If you only wish to scale one coordinate, pass a value of one + * to the other. * - * // Call once: - * RenderTexture.endDraw(); - * ``` + * Due to a limitation in WebGL1 you can only UV scale textures + * that are a power-of-two in size. Scaling NPOT textures will + * work but will result in clamping the pixels to the edges if + * you scale beyond a value of 1. Scaling below 1 will work + * regardless of texture size. * - * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you - * have started a batch. Also, be very careful not to destroy this Render Texture while the - * batch is still open, or call `beginDraw` again. + * Note that if this Mesh is using a _frame_ from a texture atlas + * then you will be unable to UV scale its texture. * - * @method Phaser.GameObjects.RenderTexture#endDraw - * @since 3.50.0 + * @method Phaser.GameObjects.Mesh#uvScale + * @webglOnly + * @since 3.60.0 * - * @param {boolean} [erase=false] - Draws all objects in this batch using a blend mode of ERASE. This has the effect of erasing any filled pixels in the objects being drawn. + * @param {number} x - The amount to horizontally scale the UV coordinates by. + * @param {number} y - The amount to vertically scale the UV coordinates by. * - * @return {this} This Render Texture instance. + * @return {this} This Game Object instance. */ - endDraw: function (erase) + uvScale: function (x, y) { - if (erase === undefined) { erase = this._eraseMode; } - - var renderer = this.renderer; - - var renderTarget = this.renderTarget; - - if (renderTarget) - { - var canvasTarget = renderer.endCapture(); - - var util = renderer.pipelines.setUtility(); - - util.blitFrame(canvasTarget, renderTarget, 1, false, false, erase); + var faces = this.faces; - renderer.resetScissor(); - renderer.resetViewport(); - } - else + for (var i = 0; i < faces.length; i++) { - renderer.setContext(); + faces[i].scaleUV(x, y); } - this.dirty = true; - return this; }, /** - * Internal method that handles the drawing of an array of children. - * - * @method Phaser.GameObjects.RenderTexture#batchList - * @private - * @since 3.12.0 - * - * @param {array} children - The array of Game Objects to draw. - * @param {number} [x] - The x position to offset the Game Object by. - * @param {number} [y] - The y position to offset the Game Object by. - * @param {number} [alpha] - The alpha to use. If not specified it uses the `globalAlpha` property. - * @param {number} [tint] - The tint color to use. If not specified it uses the `globalTint` property. - */ - batchList: function (children, x, y, alpha, tint) - { - for (var i = 0; i < children.length; i++) - { - var entry = children[i]; - - if (!entry || entry === this) - { - continue; - } - - if (entry.renderWebGL || entry.renderCanvas) - { - // Game Objects - this.drawGameObject(entry, x, y); - } - else if (entry.isParent || entry.list) - { - // Groups / Display Lists - this.batchGroup(entry.getChildren(), x, y); - } - else if (typeof entry === 'string') - { - // Texture key - this.batchTextureFrameKey(entry, null, x, y, alpha, tint); - } - else if (entry instanceof Frame) - { - // Texture Frame instance - this.batchTextureFrame(entry, x, y, alpha, tint); - } - else if (Array.isArray(entry)) - { - // Another Array - this.batchList(entry, x, y, alpha, tint); - } - } - }, - - /** - * Internal method that handles drawing a Phaser Group contents. - * - * @method Phaser.GameObjects.RenderTexture#batchGroup - * @private - * @since 3.12.0 + * The tint value being applied to the whole of the Game Object. + * This property is a setter-only. * - * @param {array} children - The array of Game Objects to draw. - * @param {number} [x=0] - The x position to offset the Game Object by. - * @param {number} [y=0] - The y position to offset the Game Object by. + * @method Phaser.GameObjects.Mesh#tint + * @type {number} + * @webglOnly + * @since 3.60.0 */ - batchGroup: function (children, x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - - x += this.frame.cutX; - y += this.frame.cutY; + tint: { - for (var i = 0; i < children.length; i++) + set: function (value) { - var entry = children[i]; - - if (entry.willRender(this.camera)) - { - var tx = entry.x + x; - var ty = entry.y + y; - - this.drawGameObject(entry, tx, ty); - } + this.setTint(value); } }, /** - * Internal method that handles drawing a single Phaser Game Object to this Render Texture using WebGL. + * The x rotation of the Model in 3D space, as specified in degrees. * - * @method Phaser.GameObjects.RenderTexture#batchGameObjectWebGL - * @private - * @since 3.12.0 + * If you need the value in radians use the `modelRotation.x` property directly. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to draw. - * @param {number} [x] - The x position to draw the Game Object at. - * @param {number} [y] - The y position to draw the Game Object at. + * @method Phaser.GameObjects.Mesh#rotateX + * @type {number} + * @since 3.60.0 */ - batchGameObjectWebGL: function (gameObject, x, y) - { - if (x === undefined) { x = gameObject.x; } - if (y === undefined) { y = gameObject.y; } + rotateX: { - var prevX = gameObject.x; - var prevY = gameObject.y; - - gameObject.setPosition(x + this.frame.cutX, y + this.frame.cutY); - - if (gameObject.renderDirect) + get: function () { - gameObject.renderDirect(this.renderer, gameObject, this.camera); - } - else + return RadToDeg(this.modelRotation.x); + }, + + set: function (value) { - gameObject.renderWebGL(this.renderer, gameObject, this.camera); + this.modelRotation.x = DegToRad(value); } - gameObject.setPosition(prevX, prevY); }, /** - * Internal method that handles drawing a single Phaser Game Object to this Render Texture using Canvas. + * The y rotation of the Model in 3D space, as specified in degrees. * - * @method Phaser.GameObjects.RenderTexture#batchGameObjectCanvas - * @private - * @since 3.12.0 + * If you need the value in radians use the `modelRotation.y` property directly. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to draw. - * @param {number} [x] - The x position to draw the Game Object at. - * @param {number} [y] - The y position to draw the Game Object at. + * @method Phaser.GameObjects.Mesh#rotateY + * @type {number} + * @since 3.60.0 */ - batchGameObjectCanvas: function (gameObject, x, y) - { - if (x === undefined) { x = gameObject.x; } - if (y === undefined) { y = gameObject.y; } - - var prevX = gameObject.x; - var prevY = gameObject.y; + rotateY: { - if (this._eraseMode) + get: function () { - var blendMode = gameObject.blendMode; - - gameObject.blendMode = BlendModes.ERASE; - } - - gameObject.setPosition(x + this.frame.cutX, y + this.frame.cutY); - - gameObject.renderCanvas(this.renderer, gameObject, this.camera, null); - - gameObject.setPosition(prevX, prevY); + return RadToDeg(this.modelRotation.y); + }, - if (this._eraseMode) + set: function (value) { - gameObject.blendMode = blendMode; + this.modelRotation.y = DegToRad(value); } - }, - - /** - * Internal method that handles the drawing of an array of children. - * - * @method Phaser.GameObjects.RenderTexture#batchTextureFrameKey - * @private - * @since 3.12.0 - * - * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. - * @param {(string|number)} [frame] - The name or index of the frame within the Texture. - * @param {number} [x=0] - The x position to offset the Game Object by. - * @param {number} [y=0] - The y position to offset the Game Object by. - * @param {number} [alpha] - The alpha to use. If not specified it uses the `globalAlpha` property. - * @param {number} [tint] - The tint color to use. If not specified it uses the `globalTint` property. - */ - batchTextureFrameKey: function (key, frame, x, y, alpha, tint) - { - var textureFrame = this.textureManager.getFrame(key, frame); - if (textureFrame) - { - this.batchTextureFrame(textureFrame, x, y, alpha, tint); - } }, /** - * Internal method that handles the drawing of a Texture Frame to this Render Texture. + * The z rotation of the Model in 3D space, as specified in degrees. * - * @method Phaser.GameObjects.RenderTexture#batchTextureFrame - * @private - * @since 3.12.0 + * If you need the value in radians use the `modelRotation.z` property directly. * - * @param {Phaser.Textures.Frame} textureFrame - The Texture Frame to draw. - * @param {number} [x=0] - The x position to draw the Frame at. - * @param {number} [y=0] - The y position to draw the Frame at. - * @param {number} [tint] - A tint color to be applied to the frame drawn to the Render Texture. + * @method Phaser.GameObjects.Mesh#rotateZ + * @type {number} + * @since 3.60.0 */ - batchTextureFrame: function (textureFrame, x, y, alpha, tint) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - - x += this.frame.cutX; - y += this.frame.cutY; + rotateZ: { - var renderTarget = this.renderTarget; + get: function () + { + return RadToDeg(this.modelRotation.z); + }, - if (renderTarget) + set: function (value) { - this.pipeline.batchTextureFrame(textureFrame, x, y, tint, alpha, this.camera.matrix, null); + this.modelRotation.z = DegToRad(value); } - else - { - var ctx = this.context; - var cd = textureFrame.canvasData; - var source = textureFrame.source.image; - var matrix = this.camera.matrix; + } - ctx.save(); +}); - ctx.globalCompositeOperation = (this._eraseMode) ? 'destination-out' : 'source-over'; +module.exports = Mesh; - ctx.globalAlpha = alpha; - matrix.setToContext(ctx); +/***/ }), - ctx.drawImage(source, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height); +/***/ 6317: +/***/ ((module) => { - ctx.restore(); - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Takes a snapshot of the given area of this Render Texture. - * - * The snapshot is taken immediately. - * - * To capture the whole Render Texture see the `snapshot` method. To capture a specific pixel, see `snapshotPixel`. - * - * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. - * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, - * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, - * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. - * - * @method Phaser.GameObjects.RenderTexture#snapshotArea - * @since 3.19.0 - * - * @param {number} x - The x coordinate to grab from. - * @param {number} y - The y coordinate to grab from. - * @param {number} width - The width of the area to grab. - * @param {number} height - The height of the area to grab. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. - * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. - * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. - * - * @return {this} This Render Texture instance. - */ - snapshotArea: function (x, y, width, height, callback, type, encoderOptions) - { - if (this.renderTarget) - { - this.renderer.snapshotFramebuffer(this.renderTarget.framebuffer, this.width, this.height, callback, false, x, y, width, height, type, encoderOptions); - } - else - { - this.renderer.snapshotCanvas(this.canvas, callback, false, x, y, width, height, type, encoderOptions); - } +/** + * This is a stub function for Mesh.Render. There is no Canvas renderer for Mesh objects. + * + * @method Phaser.GameObjects.Mesh#renderCanvas + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Mesh} src - The Game Object being rendered in this call. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + */ +var MeshCanvasRenderer = function () +{ +}; - return this; - }, +module.exports = MeshCanvasRenderer; - /** - * Takes a snapshot of the whole of this Render Texture. - * - * The snapshot is taken immediately. - * - * To capture just a portion of the Render Texture see the `snapshotArea` method. To capture a specific pixel, see `snapshotPixel`. - * - * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. - * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, - * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, - * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. - * - * @method Phaser.GameObjects.RenderTexture#snapshot - * @since 3.19.0 - * - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. - * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. - * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. - * - * @return {this} This Render Texture instance. - */ - snapshot: function (callback, type, encoderOptions) - { - if (this.renderTarget) - { - this.renderer.snapshotFramebuffer(this.renderTarget.framebuffer, this.width, this.height, callback, false, 0, 0, this.width, this.height, type, encoderOptions); - } - else - { - this.renderer.snapshotCanvas(this.canvas, callback, false, 0, 0, this.width, this.height, type, encoderOptions); - } - return this; - }, +/***/ }), - /** - * Takes a snapshot of the given pixel from this Render Texture. - * - * The snapshot is taken immediately. - * - * To capture the whole Render Texture see the `snapshot` method. To capture a specific portion, see `snapshotArea`. - * - * Unlike the other two snapshot methods, this one will send your callback a `Color` object containing the color data for - * the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute, - * using less memory, than the other snapshot methods. - * - * @method Phaser.GameObjects.RenderTexture#snapshotPixel - * @since 3.19.0 - * - * @param {number} x - The x coordinate of the pixel to get. - * @param {number} y - The y coordinate of the pixel to get. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted. - * - * @return {this} This Render Texture instance. - */ - snapshotPixel: function (x, y, callback) - { - if (this.renderTarget) - { - this.renderer.snapshotFramebuffer(this.renderTarget.framebuffer, this.width, this.height, callback, true, x, y); - } - else - { - this.renderer.snapshotCanvas(this.canvas, callback, true, x, y); - } +/***/ 41839: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Internal destroy handler, called as part of the destroy process. - * - * @method Phaser.GameObjects.RenderTexture#preDestroy - * @protected - * @since 3.9.0 - */ - preDestroy: function () - { - if (!this._saved) - { - CanvasPool.remove(this.canvas); +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var GetValue = __webpack_require__(10850); +var Mesh = __webpack_require__(83321); - if (this.renderTarget) - { - this.renderTarget.destroy(); - } +/** + * Creates a new Mesh Game Object and returns it. + * + * Note: This method will only be available if the Mesh Game Object and WebGL support have been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#mesh + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Mesh.MeshConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Mesh} The Game Object that was created. + */ +GameObjectCreator.register('mesh', function (config, addToScene) +{ + if (config === undefined) { config = {}; } - this.texture.destroy(); - this.camera.destroy(); + var key = GetAdvancedValue(config, 'key', null); + var frame = GetAdvancedValue(config, 'frame', null); + var vertices = GetValue(config, 'vertices', []); + var uvs = GetValue(config, 'uvs', []); + var indicies = GetValue(config, 'indicies', []); + var containsZ = GetValue(config, 'containsZ', false); + var normals = GetValue(config, 'normals', []); + var colors = GetValue(config, 'colors', 0xffffff); + var alphas = GetValue(config, 'alphas', 1); - this.canvas = null; - this.context = null; - this.texture = null; - } + var mesh = new Mesh(this.scene, 0, 0, key, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas); + + if (addToScene !== undefined) + { + config.add = addToScene; } -}); + BuildGameObject(this.scene, mesh, config); -module.exports = RenderTexture; + return mesh; +}); /***/ }), -/* 222 */ -/***/ (function(module, exports) { + +/***/ 8767: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Mesh = __webpack_require__(83321); +var GameObjectFactory = __webpack_require__(61286); + /** - * Creates and returns an RFC4122 version 4 compliant UUID. - * - * The string is in the form: `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` where each `x` is replaced with a random - * hexadecimal digit from 0 to f, and `y` is replaced with a random hexadecimal digit from 8 to b. + * Creates a new Mesh Game Object and adds it to the Scene. * - * @function Phaser.Utils.String.UUID - * @since 3.12.0 + * Note: This method will only be available if the Mesh Game Object and WebGL support have been built into Phaser. * - * @return {string} The UUID string. + * @method Phaser.GameObjects.GameObjectFactory#mesh + * @webglOnly + * @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. + * @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.GameObjects.Mesh} The Game Object that was created. */ -var UUID = function () +if (true) { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) + GameObjectFactory.register('mesh', function (x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas) { - var r = Math.random() * 16 | 0; - var v = (c === 'x') ? r : (r & 0x3 | 0x8); - - return v.toString(16); + return this.displayList.add(new Mesh(this.scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas)); }); -}; +} -module.exports = UUID; + +/***/ }), + +/***/ 23464: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(57410); +} + +if (true) +{ + renderCanvas = __webpack_require__(6317); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; /***/ }), -/* 223 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 57410: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AnimationState = __webpack_require__(164); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var GameObject = __webpack_require__(15); -var PIPELINE_CONST = __webpack_require__(92); -var RopeRender = __webpack_require__(1085); -var Vector2 = __webpack_require__(3); +var GetCalcMatrix = __webpack_require__(73329); /** - * @classdesc - * A Rope Game Object. - * - * The Rope object is WebGL only and does not have a Canvas counterpart. - * - * A Rope is a special kind of Game Object that has a texture that repeats along its entire length. - * Unlike a Sprite, it isn't restricted to using just a quad and can have as many vertices as you define - * when creating it. The vertices can be arranged in a horizontal or vertical strip and have their own - * color and alpha values as well. - * - * A Ropes origin is always 0.5 x 0.5 and cannot be changed. - * - * @class Rope - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @webglOnly - * @since 3.23.0 + * 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. * - * @extends Phaser.GameObjects.Components.AlphaSingle - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.Texture - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.Visible - * @extends Phaser.GameObjects.Components.ScrollFactor + * @method Phaser.GameObjects.Mesh#renderWebGL + * @since 3.0.0 + * @private * - * @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 {string} [texture] - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager. If not given, `__DEFAULT` is used. - * @param {(string|number|null)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * @param {(number|Phaser.Types.Math.Vector2Like[])} [points=2] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided a simple quad is created. See `setPoints` to set this post-creation. - * @param {boolean} [horizontal=true] - Should the vertices of this Rope be aligned horizontally (`true`), or vertically (`false`)? - * @param {number[]} [colors] - An optional array containing the color data for this Rope. You should provide one color value per pair of vertices. - * @param {number[]} [alphas] - An optional array containing the alpha data for this Rope. You should provide one alpha value per pair of vertices. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Mesh} 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 Rope = new Class({ +var MeshWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + var faces = src.faces; + var totalFaces = faces.length; - Extends: GameObject, + if (totalFaces === 0) + { + return; + } - Mixins: [ - Components.AlphaSingle, - Components.BlendMode, - Components.Depth, - Components.Flip, - Components.Mask, - Components.Pipeline, - Components.Size, - Components.Texture, - Components.Transform, - Components.Visible, - Components.ScrollFactor, - RopeRender - ], + camera.addToRenderList(src); - initialize: + var pipeline = renderer.pipelines.set(src.pipeline, src); - function Rope (scene, x, y, texture, frame, points, horizontal, colors, alphas) - { - if (texture === undefined) { texture = '__DEFAULT'; } - if (points === undefined) { points = 2; } - if (horizontal === undefined) { horizontal = true; } + var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; - GameObject.call(this, scene, 'Rope'); + // This causes a flush if the Mesh has a Post Pipeline + renderer.pipelines.preBatch(src); - /** - * The Animation State of this Rope. - * - * @name Phaser.GameObjects.Rope#anims - * @type {Phaser.Animations.AnimationState} - * @since 3.23.0 - */ - this.anims = new AnimationState(this); + var textureUnit = pipeline.setGameObject(src); + + var F32 = pipeline.vertexViewF32; + var U32 = pipeline.vertexViewU32; + + var vertexOffset = (pipeline.vertexCount * pipeline.currentShader.vertexComponentCount) - 1; + + var tintEffect = src.tintFill; + + var debugFaces = []; + var debugCallback = src.debugCallback; + + var a = calcMatrix.a; + var b = calcMatrix.b; + var c = calcMatrix.c; + var d = calcMatrix.d; + var e = calcMatrix.e; + var f = calcMatrix.f; + + var z = src.viewPosition.z; + + var hideCCW = src.hideCCW; + var roundPixels = camera.roundPixels; + var alpha = camera.alpha * src.alpha; + + var totalFacesRendered = 0; + + for (var i = 0; i < totalFaces; i++) + { + var face = faces[i]; + + // If face has alpha <= 0, or hideCCW + clockwise, or isn't in camera view, then don't draw it + if (!face.isInView(camera, hideCCW, z, alpha, a, b, c, d, e, f, roundPixels)) + { + continue; + } + + if (pipeline.shouldFlush(3)) + { + pipeline.flush(); + + textureUnit = pipeline.setGameObject(src); + + vertexOffset = 0; + } + + vertexOffset = face.load(F32, U32, vertexOffset, textureUnit, tintEffect); + + totalFacesRendered++; + + pipeline.vertexCount += 3; + + pipeline.currentBatch.count = (pipeline.vertexCount - pipeline.currentBatch.start); + + if (debugCallback) + { + debugFaces.push(face); + } + } + + src.totalFrame += totalFacesRendered; + + if (debugCallback) + { + debugCallback.call(src, src, debugFaces); + } + + renderer.pipelines.postBatch(src); +}; + +module.exports = MeshWebGLRenderer; + + +/***/ }), + +/***/ 44139: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var NineSliceRender = __webpack_require__(94456); +var Vertex = __webpack_require__(85769); + +/** + * @classdesc + * A Nine Slice Game Object allows you to display a texture-based object that + * can be stretched both horizontally and vertically, but that retains + * fixed-sized corners. The dimensions of the corners are set via the + * parameters to this class. + * + * This is extremely useful for UI and button like elements, where you need + * them to expand to accommodate the content without distorting the texture. + * + * The texture you provide for this Game Object should be based on the + * following layout structure: + * + * ``` + * A B + * +---+----------------------+---+ + * C | 1 | 2 | 3 | + * +---+----------------------+---+ + * | | | | + * | 4 | 5 | 6 | + * | | | | + * +---+----------------------+---+ + * D | 7 | 8 | 9 | + * +---+----------------------+---+ + * ``` + * + * When changing this objects width and / or height: + * + * areas 1, 3, 7 and 9 (the corners) will remain unscaled + * areas 2 and 8 will be stretched horizontally only + * areas 4 and 6 will be stretched vertically only + * area 5 will be stretched both horizontally and vertically + * + * You can also create a 3 slice Game Object: + * + * This works in a similar way, except you can only stretch it horizontally. + * Therefore, it requires less configuration: + * + * ``` + * A B + * +---+----------------------+---+ + * | | | | + * C | 1 | 2 | 3 | + * | | | | + * +---+----------------------+---+ + * ``` + * + * When changing this objects width (you cannot change its height) + * + * areas 1 and 3 will remain unscaled + * area 2 will be stretched horizontally + * + * The above configuration concept is adapted from the Pixi NineSlicePlane. + * + * To specify a 3 slice object instead of a 9 slice you should only + * provide the `leftWidth` and `rightWidth` parameters. To create a 9 slice + * you must supply all parameters. + * + * The _minimum_ width this Game Object can be is the total of + * `leftWidth` + `rightWidth`. The _minimum_ height this Game Object + * can be is the total of `topHeight` + `bottomHeight`. + * If you need to display this object at a smaller size, you can scale it. + * + * In terms of performance, using a 3 slice Game Object is the equivalent of + * having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent + * of having 9 Sprites in a row. The vertices of this object are all batched + * together and can co-exist with other Sprites and graphics on the display + * list, without incurring any additional overhead. + * + * As of Phaser 3.60 this Game Object is WebGL only. + * + * @class NineSlice + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.60.0 + * + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Texture + * @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 the center of this Game Object in the world. + * @param {number} y - The vertical position of the center 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. + * @param {number} [width=256] - The width of the Nine Slice Game Object. You can adjust the width post-creation. + * @param {number} [height=256] - The height of the Nine Slice Game Object. If this is a 3 slice object the height will be fixed to the height of the texture and cannot be changed. + * @param {number} [leftWidth=10] - The size of the left vertical column (A). + * @param {number} [rightWidth=10] - The size of the right vertical column (B). + * @param {number} [topHeight=0] - The size of the top horiztonal row (C). Set to zero or undefined to create a 3 slice object. + * @param {number} [bottomHeight=0] - The size of the bottom horiztonal row (D). Set to zero or undefined to create a 3 slice object. + */ +var NineSlice = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.Depth, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Texture, + Components.Transform, + Components.Visible, + NineSliceRender + ], + + initialize: + + function NineSlice (scene, x, y, texture, frame, width, height, leftWidth, rightWidth, topHeight, bottomHeight) + { + if (width === undefined) { width = 256; } + if (height === undefined) { height = 256; } + + if (leftWidth === undefined) { leftWidth = 10; } + if (rightWidth === undefined) { rightWidth = 10; } + if (topHeight === undefined) { topHeight = 0; } + if (bottomHeight === undefined) { bottomHeight = 0; } + + GameObject.call(this, scene, 'NineSlice'); /** - * An array containing the points data for this Rope. - * - * Each point should be given as a Vector2Like object (i.e. a Vector2, Geom.Point or object with public x/y properties). - * - * The point coordinates are given in local space, where 0 x 0 is the start of the Rope strip. - * - * You can modify the contents of this array directly in real-time to create interesting effects. - * If you do so, be sure to call `setDirty` _after_ modifying this array, so that the vertices data is - * updated before the next render. Alternatively, you can use the `setPoints` method instead. - * - * Should you need to change the _size_ of this array, then you should always use the `setPoints` method. + * Internal width value. Do not modify this property directly. * - * @name Phaser.GameObjects.Rope#points - * @type {Phaser.Types.Math.Vector2Like[]} - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#_width + * @private + * @type {number} + * @since 3.60.0 */ - this.points = points; + this._width; /** - * An array containing the vertices data for this Rope. - * - * This data is calculated automatically in the `updateVertices` method, based on the points provided. + * Internal height value. Do not modify this property directly. * - * @name Phaser.GameObjects.Rope#vertices - * @type {Float32Array} - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#_height + * @private + * @type {number} + * @since 3.60.0 */ - this.vertices; + this._height; /** - * An array containing the uv data for this Rope. + * Internal originX value. Do not modify this property directly. * - * This data is calculated automatically in the `setPoints` method, based on the points provided. - * - * @name Phaser.GameObjects.Rope#uv - * @type {Float32Array} - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#_originX + * @private + * @type {number} + * @since 3.60.0 */ - this.uv; + this._originX = 0.5; /** - * An array containing the color data for this Rope. - * - * Colors should be given as numeric RGB values, such as 0xff0000. - * You should provide _two_ color values for every point in the Rope, one for the top and one for the bottom of each quad. + * Internal originY value. Do not modify this property directly. * - * You can modify the contents of this array directly in real-time, however, should you need to change the _size_ - * of the array, then you should use the `setColors` method instead. - * - * @name Phaser.GameObjects.Rope#colors - * @type {Uint32Array} - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#_originY + * @private + * @type {number} + * @since 3.60.0 */ - this.colors; + this._originY = 0.5; /** - * An array containing the alpha data for this Rope. - * - * Alphas should be given as float values, such as 0.5. - * You should provide _two_ alpha values for every point in the Rope, one for the top and one for the bottom of each quad. - * - * You can modify the contents of this array directly in real-time, however, should you need to change the _size_ - * of the array, then you should use the `setAlphas` method instead. + * Internal component value. Do not modify this property directly. * - * @name Phaser.GameObjects.Rope#alphas - * @type {Float32Array} - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#_sizeComponent + * @private + * @type {boolean} + * @since 3.60.0 */ - this.alphas; + this._sizeComponent = true; /** - * The tint fill mode. + * An array of Vertex objects that correspond to the quads that make-up + * this Nine Slice Game Object. They are stored in the following order: * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + * Top Left - Indexes 0 - 5 + * Top Center - Indexes 6 - 11 + * Top Right - Indexes 12 - 17 + * Center Left - Indexes 18 - 23 + * Center - Indexes 24 - 29 + * Center Right - Indexes 30 - 35 + * Bottom Left - Indexes 36 - 41 + * Bottom Center - Indexes 42 - 47 + * Bottom Right - Indexes 48 - 53 * - * @name Phaser.GameObjects.Rope#tintFill - * @type {boolean} - * @since 3.23.0 + * Each quad is represented by 6 Vertex instances. + * + * This array will contain 18 elements for a 3 slice object + * and 54 for a nine slice object. + * + * You should never modify this array once it has been populated. + * + * @name Phaser.GameObjects.NineSlice#vertices + * @type {Phaser.Geom.Mesh.Vertex[]} + * @since 3.60.0 */ - this.tintFill = (texture === '__DEFAULT') ? true : false; + this.vertices = []; /** - * If the Rope is marked as `dirty` it will automatically recalculate its vertices - * the next time it renders. You can also force this by calling `updateVertices`. + * The size of the left vertical bar (A). * - * @name Phaser.GameObjects.Rope#dirty - * @type {boolean} - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#leftWidth + * @type {number} + * @readonly + * @since 3.60.0 */ - this.dirty = false; + this.leftWidth; /** - * Are the Rope vertices aligned horizontally, in a strip, or vertically, in a column? - * - * This property is set during instantiation and cannot be changed directly. - * See the `setVertical` and `setHorizontal` methods. + * The size of the right vertical bar (B). * - * @name Phaser.GameObjects.Rope#horizontal - * @type {boolean} + * @name Phaser.GameObjects.NineSlice#rightWidth + * @type {number} * @readonly - * @since 3.23.0 + * @since 3.60.0 */ - this.horizontal = horizontal; + this.rightWidth; /** - * The horizontally flipped state of the Game Object. + * The size of the top horizontal bar (C). * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * If this is a 3 slice object this property will be set to the + * height of the texture being used. * - * @name Phaser.GameObjects.Rope#_flipX - * @type {boolean} - * @default false - * @private - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#topHeight + * @type {number} + * @readonly + * @since 3.60.0 */ - this._flipX = false; + this.topHeight; /** - * The vertically flipped state of the Game Object. + * The size of the bottom horizontal bar (D). * - * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * If this is a 3 slice object this property will be set to zero. * - * @name Phaser.GameObjects.Rope#_flipY - * @type {boolean} - * @default false - * @private - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#bottomHeight + * @type {number} + * @readonly + * @since 3.60.0 */ - this._flipY = false; + this.bottomHeight; /** - * Internal Vector2 used for vertices updates. + * The tint value being applied to the top-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. * - * @name Phaser.GameObjects.Rope#_perp - * @type {Phaser.Math.Vector2} - * @private - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#tint + * @type {number} + * @default 0xffffff + * @since 3.60.0 */ - this._perp = new Vector2(); + this.tint = 0xffffff; /** - * You can optionally choose to render the vertices of this Rope to a Graphics instance. - * - * Achieve this by setting the `debugCallback` and the `debugGraphic` properties. - * - * You can do this in a single call via the `Rope.setDebug` method, which will use the - * built-in debug function. You can also set it to your own callback. The callback - * will be invoked _once per render_ and sent the following parameters: - * - * `debugCallback(src, meshLength, verts)` - * - * `src` is the Rope instance being debugged. - * `meshLength` is the number of mesh vertices in total. - * `verts` is an array of the translated vertex coordinates. + * The tint fill mode. * - * To disable rendering, set this property back to `null`. + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. * - * @name Phaser.GameObjects.Rope#debugCallback - * @type {function} - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#tintFill + * @type {boolean} + * @default false + * @since 3.60.0 */ - this.debugCallback = null; + this.tintFill = false; /** - * The Graphics instance that the debug vertices will be drawn to, if `setDebug` has - * been called. + * This property is `true` if this Nine Slice Game Object was configured + * with just `leftWidth` and `rightWidth` values, making it a 3-slice + * instead of a 9-slice object. * - * @name Phaser.GameObjects.Rope#debugGraphic - * @type {Phaser.GameObjects.Graphics} - * @since 3.23.0 + * @name Phaser.GameObjects.NineSlice#is3Slice + * @type {boolean} + * @since 3.60.0 */ - this.debugGraphic = null; + this.is3Slice = (topHeight === 0 && bottomHeight === 0); - this.setTexture(texture, frame); - this.setPosition(x, y); - this.setSizeToFrame(); - this.initPipeline(PIPELINE_CONST.ROPE_PIPELINE); + var size = this.is3Slice ? 18 : 54; - if (Array.isArray(points)) + for (var i = 0; i < size; i++) { - this.resizeArrays(points.length); + this.vertices.push(new Vertex()); } - this.setPoints(points, colors, alphas); + this.setPosition(x, y); - this.updateVertices(); - }, + this.setTexture(texture, frame); - // Overrides Game Object method - addedToScene: function () - { - this.scene.sys.updateList.add(this); - }, + this.setSlices(width, height, leftWidth, rightWidth, topHeight, bottomHeight); - // Overrides Game Object method - removedFromScene: function () - { - this.scene.sys.updateList.remove(this); + this.setOrigin(0.5, 0.5); + + this.initPipeline(); + this.initPostPipeline(); }, /** - * The Rope update loop. + * Resets the width, height and slices for this NineSlice Game Object. * - * @method Phaser.GameObjects.Rope#preUpdate - * @protected - * @since 3.23.0 + * This allows you to modify the texture being used by this object and then reset the slice configuration, + * to avoid having to destroy this Game Object in order to use it for a different game element. * - * @param {number} time - The current timestamp. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. + * Please note that you cannot change a 9-slice to a 3-slice or vice versa. + * + * @method Phaser.GameObjects.NineSlice#setSlices + * @since 3.60.0 + * + * @param {number} [width=256] - The width of the Nine Slice Game Object. You can adjust the width post-creation. + * @param {number} [height=256] - The height of the Nine Slice Game Object. If this is a 3 slice object the height will be fixed to the height of the texture and cannot be changed. + * @param {number} [leftWidth=10] - The size of the left vertical column (A). + * @param {number} [rightWidth=10] - The size of the right vertical column (B). + * @param {number} [topHeight=0] - The size of the top horiztonal row (C). Set to zero or undefined to create a 3 slice object. + * @param {number} [bottomHeight=0] - The size of the bottom horiztonal row (D). Set to zero or undefined to create a 3 slice object. + * + * @return {this} This Game Object instance. */ - preUpdate: function (time, delta) + setSlices: function (width, height, leftWidth, rightWidth, topHeight, bottomHeight) { - var prevFrame = this.anims.currentFrame; + if (width === undefined) { width = 256; } + if (height === undefined) { height = 256; } - this.anims.update(time, delta); + if (leftWidth === undefined) { leftWidth = 10; } + if (rightWidth === undefined) { rightWidth = 10; } + if (topHeight === undefined) { topHeight = 0; } + if (bottomHeight === undefined) { bottomHeight = 0; } - if (this.anims.currentFrame !== prevFrame) + var is3Slice = (topHeight === 0 && bottomHeight === 0); + + if (this.is3Slice !== is3Slice) { - this.updateUVs(); + console.warn('Cannot change 9 slice to 3 slice'); + } + else + { + this._width = width; + this._height = height; + + this.leftWidth = leftWidth; + this.rightWidth = rightWidth; + this.topHeight = topHeight; + this.bottomHeight = bottomHeight; + + if (this.is3Slice) + { + height = this.frame.height; + + this._height = height; + this.topHeight = height; + this.bottomHeight = 0; + } + this.updateVertices(); + this.updateUVs(); } + + return this; }, /** - * Start playing the given animation. + * Updates all of the vertice UV coordinates. This is called automatically + * when the NineSlice Game Object is created, or if the texture frame changes. * - * @method Phaser.GameObjects.Rope#play - * @since 3.23.0 - * - * @param {string} key - The string-based key of the animation to play. - * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. - * @param {number} [startFrame=0] - Optionally start the animation playing from this frame index. + * Unlike with the `updateVertice` method, you do not need to call this + * method if the Nine Slice changes size. Only if it changes texture frame. * - * @return {this} This Game Object. + * @method Phaser.GameObjects.NineSlice#updateUVs + * @since 3.60.0 */ - play: function (key, ignoreIfPlaying, startFrame) + updateUVs: function () { - this.anims.play(key, ignoreIfPlaying, startFrame); + var left = this.leftWidth; + var right = this.rightWidth; + var top = this.topHeight; + var bot = this.bottomHeight; - return this; + var width = this.frame.width; + var height = this.frame.height; + + this.updateQuadUVs(0, 0, 0, left / width, top / height); + this.updateQuadUVs(6, left / width, 0, 1 - (right / width), top / height); + this.updateQuadUVs(12, 1 - (right / width), 0, 1, top / height); + + if (!this.is3Slice) + { + this.updateQuadUVs(18, 0, top / height, left / width, 1 - (bot / height)); + this.updateQuadUVs(24, left / width, top / height, 1 - right / width, 1 - (bot / height)); + this.updateQuadUVs(30, 1 - right / width, top / height, 1, 1 - (bot / height)); + this.updateQuadUVs(36, 0, 1 - bot / height, left / width, 1); + this.updateQuadUVs(42, left / width, 1 - bot / height, 1 - right / width, 1); + this.updateQuadUVs(48, 1 - right / width, 1 - bot / height, 1, 1); + } }, /** - * Flags this Rope as being dirty. A dirty rope will recalculate all of its vertices data - * the _next_ time it renders. You should set this rope as dirty if you update the points - * array directly. + * Recalculates all of the vertices in this Nine Slice Game Object + * based on the `leftWidth`, `rightWidth`, `topHeight` and `bottomHeight` + * properties, combined with the Game Object size. * - * @method Phaser.GameObjects.Rope#setDirty - * @since 3.23.0 + * This method is called automatically when this object is created + * or if it's origin is changed. * - * @return {this} This Game Object instance. + * You should not typically need to call this method directly, but it + * is left public should you find a need to modify one of those properties + * after creation. + * + * @method Phaser.GameObjects.NineSlice#updateVertices + * @since 3.60.0 */ - setDirty: function () + updateVertices: function () { - this.dirty = true; + var left = this.leftWidth; + var right = this.rightWidth; + var top = this.topHeight; + var bot = this.bottomHeight; - return this; + var width = this.width; + var height = this.height; + + this.updateQuad(0, -0.5, 0.5, -0.5 + (left / width), 0.5 - (top / height)); + this.updateQuad(6, -0.5 + (left / width), 0.5, 0.5 - (right / width), 0.5 - (top / height)); + this.updateQuad(12, 0.5 - (right / width), 0.5, 0.5, 0.5 - (top / height)); + + if (!this.is3Slice) + { + this.updateQuad(18, -0.5, 0.5 - (top / height), -0.5 + (left / width), -0.5 + (bot / height)); + this.updateQuad(24, -0.5 + (left / width), 0.5 - (top / height), 0.5 - (right / width), -0.5 + (bot / height)); + this.updateQuad(30, 0.5 - (right / width), 0.5 - (top / height), 0.5, -0.5 + (bot / height)); + this.updateQuad(36, -0.5, -0.5 + (bot / height), -0.5 + (left / width), -0.5); + this.updateQuad(42, -0.5 + (left / width), -0.5 + (bot / height), 0.5 - (right / width), -0.5); + this.updateQuad(48, 0.5 - (right / width), -0.5 + (bot / height), 0.5, -0.5); + } }, /** - * Sets the alignment of the points in this Rope to be horizontal, in a strip format. - * - * Calling this method will reset this Rope. The current points, vertices, colors and alpha - * values will be reset to thoes values given as parameters. + * Internally updates the position coordinates across all vertices of the + * given quad offset. * - * @method Phaser.GameObjects.Rope#setHorizontal - * @since 3.23.0 + * You should not typically need to call this method directly, but it + * is left public should an extended class require it. * - * @param {(number|Phaser.Types.Math.Vector2Like[])} [points] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided the current points length is used. - * @param {(number|number[])} [colors] - Either a single color value, or an array of values. - * @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values. + * @method Phaser.GameObjects.NineSlice#updateQuad + * @since 3.60.0 * - * @return {this} This Game Object instance. + * @param {number} offset - The offset in the vertices array of the quad to update. + * @param {number} x1 - The top-left quad coordinate. + * @param {number} y1 - The top-left quad coordinate. + * @param {number} x2 - The bottom-right quad coordinate. + * @param {number} y2 - The bottom-right quad coordinate. */ - setHorizontal: function (points, colors, alphas) + updateQuad: function (offset, x1, y1, x2, y2) { - if (points === undefined) { points = this.points.length; } - - if (this.horizontal) - { - return this; - } + var width = this.width; + var height = this.height; + var originX = this.originX; + var originY = this.originY; - this.horizontal = true; + var verts = this.vertices; - return this.setPoints(points, colors, alphas); + verts[offset + 0].resize(x1, y1, width, height, originX, originY); + verts[offset + 1].resize(x1, y2, width, height, originX, originY); + verts[offset + 2].resize(x2, y1, width, height, originX, originY); + verts[offset + 3].resize(x1, y2, width, height, originX, originY); + verts[offset + 4].resize(x2, y2, width, height, originX, originY); + verts[offset + 5].resize(x2, y1, width, height, originX, originY); }, /** - * Sets the alignment of the points in this Rope to be vertical, in a column format. - * - * Calling this method will reset this Rope. The current points, vertices, colors and alpha - * values will be reset to thoes values given as parameters. + * Internally updates the UV coordinates across all vertices of the + * given quad offset, based on the frame size. * - * @method Phaser.GameObjects.Rope#setVertical - * @since 3.23.0 + * You should not typically need to call this method directly, but it + * is left public should an extended class require it. * - * @param {(number|Phaser.Types.Math.Vector2Like[])} [points] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided the current points length is used. - * @param {(number|number[])} [colors] - Either a single color value, or an array of values. - * @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values. + * @method Phaser.GameObjects.NineSlice#updateQuadUVs + * @since 3.60.0 * - * @return {this} This Game Object instance. + * @param {number} offset - The offset in the vertices array of the quad to update. + * @param {number} u1 - The top-left UV coordinate. + * @param {number} v1 - The top-left UV coordinate. + * @param {number} u2 - The bottom-right UV coordinate. + * @param {number} v2 - The bottom-right UV coordinate. */ - setVertical: function (points, colors, alphas) + updateQuadUVs: function (offset, u1, v1, u2, v2) { - if (points === undefined) { points = this.points.length; } + var verts = this.vertices; - if (!this.horizontal) + // Adjust for frame offset + // Incoming values will always be in the range 0-1 + var frame = this.frame; + + var fu1 = frame.u0; + var fv1 = frame.v0; + var fu2 = frame.u1; + var fv2 = frame.v1; + + if (fu1 !== 0 || fu2 !== 1) { - return this; + // adjust horizontal + var udiff = fu2 - fu1; + u1 = fu1 + u1 * udiff; + u2 = fu1 + u2 * udiff; } - this.horizontal = false; + if (fv1 !== 0 || fv2 !== 1) + { + // adjust vertical + var vdiff = fv2 - fv1; + v1 = fv1 + v1 * vdiff; + v2 = fv1 + v2 * vdiff; + } - return this.setPoints(points, colors, alphas); + verts[offset + 0].setUVs(u1, v1); + verts[offset + 1].setUVs(u1, v2); + verts[offset + 2].setUVs(u2, v1); + verts[offset + 3].setUVs(u1, v2); + verts[offset + 4].setUVs(u2, v2); + verts[offset + 5].setUVs(u2, v1); }, /** - * Sets the tint fill mode. - * - * Mode 0 (`false`) is an additive tint, the default, which blends the vertices colors with the texture. - * This mode respects the texture alpha. - * - * Mode 1 (`true`) is a fill tint. Unlike an additive tint, a fill-tint literally replaces the pixel colors - * from the texture with those in the tint. You can use this for effects such as making a player flash 'white' - * if hit by something. This mode respects the texture alpha. + * Clears all tint values associated with this Game Object. * - * See the `setColors` method for details of how to color each of the vertices. + * Immediately sets the color values back to 0xffffff and the tint type to 'additive', + * which results in no visible change to the texture. * - * @method Phaser.GameObjects.Rope#setTintFill + * @method Phaser.GameObjects.NineSlice#clearTint * @webglOnly - * @since 3.23.0 - * - * @param {boolean} [value=false] - Set to `false` for an Additive tint or `true` fill tint with alpha. + * @since 3.60.0 * * @return {this} This Game Object instance. */ - setTintFill: function (value) + clearTint: function () { - if (value === undefined) { value = false; } - - this.tintFill = value; + this.setTint(0xffffff); return this; }, /** - * Set the alpha values used by the Rope during rendering. - * - * You can provide the values in a number of ways: + * Sets an additive tint on this Game Object. * - * 1) One single numeric value: `setAlphas(0.5)` - This will set a single alpha for the whole Rope. - * 2) Two numeric value: `setAlphas(1, 0.5)` - This will set a 'top' and 'bottom' alpha value across the whole Rope. - * 3) An array of values: `setAlphas([ 1, 0.5, 0.2 ])` + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. * - * If you provide an array of values and the array has exactly the same number of values as `points` in the Rope, it - * will use each alpha value per rope segment. + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property. * - * If the provided array has a different number of values than `points` then it will use the values in order, from - * the first Rope segment and on, until it runs out of values. This allows you to control the alpha values at all - * vertices in the Rope. + * To remove a tint call `clearTint`, or call this method with no parameters. * - * Note this method is called `setAlphas` (plural) and not `setAlpha`. + * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. * - * @method Phaser.GameObjects.Rope#setAlphas - * @since 3.23.0 + * @method Phaser.GameObjects.NineSlice#setTint + * @webglOnly + * @since 3.60.0 * - * @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values. If nothing is provided alpha is reset to 1. - * @param {number} [bottomAlpha] - An optional bottom alpha value. See the method description for details. + * @param {number} [color=0xffffff] - The tint being applied to the entire Game Object. * * @return {this} This Game Object instance. */ - setAlphas: function (alphas, bottomAlpha) + setTint: function (color) { - var total = this.points.length; - - if (total < 1) - { - return this; - } - - var currentAlphas = this.alphas; - - if (alphas === undefined) - { - alphas = [ 1 ]; - } - else if (!Array.isArray(alphas) && bottomAlpha === undefined) - { - alphas = [ alphas ]; - } - - var i; - var index = 0; - - if (bottomAlpha !== undefined) - { - // Top / Bottom alpha pair - for (i = 0; i < total; i++) - { - index = i * 2; - - currentAlphas[index] = alphas; - currentAlphas[index + 1] = bottomAlpha; - } - } - else if (alphas.length === total) - { - // If there are exactly the same number of alphas as points, we'll combine the alphas - for (i = 0; i < total; i++) - { - index = i * 2; - - currentAlphas[index] = alphas[i]; - currentAlphas[index + 1] = alphas[i]; - } - } - else - { - var prevAlpha = alphas[0]; - - for (i = 0; i < total; i++) - { - index = i * 2; - - if (alphas.length > index) - { - prevAlpha = alphas[index]; - } - - currentAlphas[index] = prevAlpha; + if (color === undefined) { color = 0xffffff; } - if (alphas.length > index + 1) - { - prevAlpha = alphas[index + 1]; - } + this.tint = color; - currentAlphas[index + 1] = prevAlpha; - } - } + this.tintFill = false; return this; - }, /** - * Set the color values used by the Rope during rendering. - * - * Colors are used to control the level of tint applied across the Rope texture. + * Sets a fill-based tint on this Game Object. * - * You can provide the values in a number of ways: + * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture + * with those in the tint. You can use this for effects such as making a player flash 'white' + * if hit by something. The whole Game Object will be rendered in the given color. * - * * One single numeric value: `setColors(0xff0000)` - This will set a single color tint for the whole Rope. - * * An array of values: `setColors([ 0xff0000, 0x00ff00, 0x0000ff ])` + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property. * - * If you provide an array of values and the array has exactly the same number of values as `points` in the Rope, it - * will use each color per rope segment. + * To remove a tint call `clearTint`, or call this method with no parameters. * - * If the provided array has a different number of values than `points` then it will use the values in order, from - * the first Rope segment and on, until it runs out of values. This allows you to control the color values at all - * vertices in the Rope. + * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. * - * @method Phaser.GameObjects.Rope#setColors - * @since 3.23.0 + * @method Phaser.GameObjects.NineSlice#setTintFill + * @webglOnly + * @since 3.60.0 * - * @param {(number|number[])} [colors] - Either a single color value, or an array of values. If nothing is provided color is reset to 0xffffff. + * @param {number} [color=0xffffff] - The tint being applied to the entire Game Object. * * @return {this} This Game Object instance. */ - setColors: function (colors) + setTintFill: function (color) { - var total = this.points.length; - - if (total < 1) - { - return this; - } + this.setTint(color); - var currentColors = this.colors; + this.tintFill = true; - if (colors === undefined) - { - colors = [ 0xffffff ]; - } - else if (!Array.isArray(colors)) - { - colors = [ colors ]; - } + return this; + }, - var i; - var index = 0; + /** + * Does this Game Object have a tint applied? + * + * It checks to see if the tint property is set to a value other than 0xffffff. + * This indicates that a Game Object is tinted. + * + * @name Phaser.GameObjects.NineSlice#isTinted + * @type {boolean} + * @webglOnly + * @readonly + * @since 3.60.0 + */ + isTinted: { - if (colors.length === total) + get: function () { - // If there are exactly the same number of colors as points, we'll combine the colors - for (i = 0; i < total; i++) - { - index = i * 2; - - currentColors[index] = colors[i]; - currentColors[index + 1] = colors[i]; - } + return (this.tint !== 0xffffff); } - else - { - var prevColor = colors[0]; - for (i = 0; i < total; i++) - { - index = i * 2; + }, - if (colors.length > index) - { - prevColor = colors[index]; - } + /** + * The displayed width of this Game Object. + * + * Setting this value will adjust the way in which this Nine Slice + * object scales horizontally, if configured to do so. + * + * The _minimum_ width this Game Object can be is the total of + * `leftWidth` + `rightWidth`. If you need to display this object + * at a smaller size, you can also scale it. + * + * @name Phaser.GameObjects.NineSlice#width + * @type {number} + * @since 3.60.0 + */ + width: { - currentColors[index] = prevColor; + get: function () + { + return this._width; + }, - if (colors.length > index + 1) - { - prevColor = colors[index + 1]; - } + set: function (value) + { + this._width = Math.max(value, this.leftWidth + this.rightWidth); - currentColors[index + 1] = prevColor; - } + this.updateVertices(); } - return this; }, /** - * Sets the points used by this Rope. - * - * The points should be provided as an array of Vector2, or vector2-like objects (i.e. those with public x/y properties). - * - * Each point corresponds to one segment of the Rope. The more points in the array, the more segments the rope has. - * - * Point coordinates are given in local-space, not world-space, and are directly related to the size of the texture - * this Rope object is using. - * - * For example, a Rope using a 512 px wide texture, split into 4 segments (128px each) would use the following points: - * - * ```javascript - * rope.setPoints([ - * { x: 0, y: 0 }, - * { x: 128, y: 0 }, - * { x: 256, y: 0 }, - * { x: 384, y: 0 } - * ]); - * ``` - * - * Or, you can provide an integer to do the same thing: - * - * ```javascript - * rope.setPoints(4); - * ``` - * - * Which will divide the Rope into 4 equally sized segments based on the frame width. + * The displayed height of this Game Object. * - * Note that calling this method with a different number of points than the Rope has currently will - * _reset_ the color and alpha values, unless you provide them as arguments to this method. + * Setting this value will adjust the way in which this Nine Slice + * object scales vertically, if configured to do so. * - * @method Phaser.GameObjects.Rope#setPoints - * @since 3.23.0 + * The _minimum_ height this Game Object can be is the total of + * `topHeight` + `bottomHeight`. If you need to display this object + * at a smaller size, you can also scale it. * - * @param {(number|Phaser.Types.Math.Vector2Like[])} [points=2] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided a simple quad is created. - * @param {(number|number[])} [colors] - Either a single color value, or an array of values. - * @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values. + * If this is a 3-slice object, you can only stretch it horizontally + * and changing the height will be ignored. * - * @return {this} This Game Object instance. + * @name Phaser.GameObjects.NineSlice#height + * @type {number} + * @since 3.60.0 */ - setPoints: function (points, colors, alphas) - { - if (points === undefined) { points = 2; } + height: { - if (typeof points === 'number') + get: function () { - // Generate an array based on the points - var segments = points; - - if (segments < 2) - { - segments = 2; - } - - points = []; - - var s; - var frameSegment; - var offset; - - if (this.horizontal) - { - offset = -(this.frame.halfWidth); - frameSegment = this.frame.width / (segments - 1); + return this._height; + }, - for (s = 0; s < segments; s++) - { - points.push({ x: offset + s * frameSegment, y: 0 }); - } - } - else + set: function (value) + { + if (!this.is3Slice) { - offset = -(this.frame.halfHeight); - frameSegment = this.frame.height / (segments - 1); + this._height = Math.max(value, this.topHeight + this.bottomHeight); - for (s = 0; s < segments; s++) - { - points.push({ x: 0, y: offset + s * frameSegment }); - } + this.updateVertices(); } } - var total = points.length; - var currentTotal = this.points.length; + }, - if (total < 1) - { - console.warn('Rope: Not enough points given'); + /** + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + * + * @name Phaser.GameObjects.NineSlice#displayWidth + * @type {number} + * @since 3.60.0 + */ + displayWidth: { - return this; - } - else if (total === 1) + get: function () { - points.unshift({ x: 0, y: 0 }); - total++; - } + return this.scaleX * this.width; + }, - if (currentTotal !== total) + set: function (value) { - this.resizeArrays(total); + this.scaleX = value / this.width; } - this.points = points; + }, - this.updateUVs(); + /** + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + * + * @name Phaser.GameObjects.NineSlice#displayHeight + * @type {number} + * @since 3.60.0 + */ + displayHeight: { - if (colors !== undefined && colors !== null) + get: function () { - this.setColors(colors); - } + return this.scaleY * this.height; + }, - if (alphas !== undefined && alphas !== null) + set: function (value) { - this.setAlphas(alphas); + this.scaleY = value / this.height; } - return this; }, /** - * Updates all of the UVs based on the Rope.points and `flipX` and `flipY` settings. + * Sets the size of this Game Object. * - * @method Phaser.GameObjects.Rope#updateUVs - * @since 3.23.0 + * For a Nine Slice Game Object this means it will be stretched (or shrunk) horizontally + * and vertically depending on the dimensions given to this method, in accordance with + * how it has been configured for the various corner sizes. + * + * If this is a 3-slice object, you can only stretch it horizontally + * and changing the height will be ignored. + * + * If you have enabled this Game Object for input, changing the size will also change the + * size of the hit area. + * + * @method Phaser.GameObjects.NineSlice#setSize + * @since 3.60.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. */ - updateUVs: function () + setSize: function (width, height) { - var currentUVs = this.uv; - var total = this.points.length; - - var u0 = this.frame.u0; - var v0 = this.frame.v0; - var u1 = this.frame.u1; - var v1 = this.frame.v1; + this.width = width; + this.height = height; - var partH = (u1 - u0) / (total - 1); - var partV = (v1 - v0) / (total - 1); + var input = this.input; - for (var i = 0; i < total; i++) + if (input && !input.customHitArea) { - var index = i * 4; - - var uv0; - var uv1; - var uv2; - var uv3; - - if (this.horizontal) - { - if (this._flipX) - { - uv0 = u1 - (i * partH); - uv2 = u1 - (i * partH); - } - else - { - uv0 = u0 + (i * partH); - uv2 = u0 + (i * partH); - } - - if (this._flipY) - { - uv1 = v1; - uv3 = v0; - } - else - { - uv1 = v0; - uv3 = v1; - } - } - else - { - if (this._flipX) - { - uv0 = u0; - uv2 = u1; - } - else - { - uv0 = u1; - uv2 = u0; - } - - if (this._flipY) - { - uv1 = v1 - (i * partV); - uv3 = v1 - (i * partV); - } - else - { - uv1 = v0 + (i * partV); - uv3 = v0 + (i * partV); - } - } - - currentUVs[index + 0] = uv0; - currentUVs[index + 1] = uv1; - currentUVs[index + 2] = uv2; - currentUVs[index + 3] = uv3; + input.hitArea.width = this.width; + input.hitArea.height = this.height; } return this; }, /** - * Resizes all of the internal arrays: `vertices`, `uv`, `colors` and `alphas` to the new - * given Rope segment total. + * Sets the display size of this Game Object. * - * @method Phaser.GameObjects.Rope#resizeArrays - * @since 3.23.0 + * Calling this will adjust the scale. * - * @param {number} newSize - The amount of segments to split the Rope in to. + * @method Phaser.GameObjects.NineSlice#setDisplaySize + * @since 3.60.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. */ - resizeArrays: function (newSize) + setDisplaySize: function (width, height) { - var colors = this.colors; - var alphas = this.alphas; - - this.vertices = new Float32Array(newSize * 4); - this.uv = new Float32Array(newSize * 4); - - colors = new Uint32Array(newSize * 2); - alphas = new Float32Array(newSize * 2); - - for (var i = 0; i < newSize * 2; i++) - { - colors[i] = 0xffffff; - alphas[i] = 1; - } - - this.colors = colors; - this.alphas = alphas; - - // updateVertices during next render - this.dirty = true; + this.displayWidth = width; + this.displayHeight = height; return this; }, /** - * Updates the vertices based on the Rope points. - * - * This method is called automatically during rendering if `Rope.dirty` is `true`, which is set - * by the `setPoints` and `setDirty` methods. You should flag the Rope as being dirty if you modify - * the Rope points directly. - * - * @method Phaser.GameObjects.Rope#updateVertices - * @since 3.23.0 + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. * - * @return {this} This Game Object instance. + * @name Phaser.GameObjects.NineSlice#originX + * @type {number} + * @since 3.60.0 */ - updateVertices: function () - { - var perp = this._perp; - var points = this.points; - var vertices = this.vertices; - - var total = points.length; + originX: { - this.dirty = false; + get: function () + { + return this._originX; + }, - if (total < 1) + set: function (value) { - return; + this._originX = value; + this.updateVertices(); } - var nextPoint; - var lastPoint = points[0]; + }, - var frameSize = (this.horizontal) ? this.frame.halfHeight : this.frame.halfWidth; + /** + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * + * @name Phaser.GameObjects.NineSlice#originY + * @type {number} + * @since 3.60.0 + */ + originY: { - for (var i = 0; i < total; i++) + get: function () { - var point = points[i]; - var index = i * 4; - - if (i < total - 1) - { - nextPoint = points[i + 1]; - } - else - { - nextPoint = point; - } - - perp.x = nextPoint.y - lastPoint.y; - perp.y = -(nextPoint.x - lastPoint.x); - - var perpLength = perp.length(); - - perp.x /= perpLength; - perp.y /= perpLength; - - perp.x *= frameSize; - perp.y *= frameSize; - - vertices[index] = point.x + perp.x; - vertices[index + 1] = point.y + perp.y; - vertices[index + 2] = point.x - perp.x; - vertices[index + 3] = point.y - perp.y; + return this._originY; + }, - lastPoint = point; + set: function (value) + { + this._originY = value; + this.updateVertices(); } - return this; }, /** - * This method enables rendering of the Rope vertices to the given Graphics instance. - * - * If you enable this feature, you **must** call `Graphics.clear()` in your Scene `update`, - * otherwise the Graphics instance you provide to debug will fill-up with draw calls, - * eventually crashing the browser. This is not done automatically to allow you to debug - * draw multiple Rope objects to a single Graphics instance. - * - * The Rope class has a built-in debug rendering callback `Rope.renderDebugVerts`, however - * you can also provide your own callback to be used instead. Do this by setting the `callback` parameter. - * - * The callback is invoked _once per render_ and sent the following parameters: + * Sets the origin of this Game Object. * - * `callback(src, meshLength, verts)` + * The values are given in the range 0 to 1. * - * `src` is the Rope instance being debugged. - * `meshLength` is the number of mesh vertices in total. - * `verts` is an array of the translated vertex coordinates. + * @method Phaser.GameObjects.NineSlice#setOrigin + * @since 3.60.0 * - * If using your own callback you do not have to provide a Graphics instance to this method. + * @param {number} [x=0.5] - The horizontal origin value. + * @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`. * - * To disable debug rendering, to either your own callback or the built-in one, call this method - * with no arguments. + * @return {this} This Game Object instance. + */ + setOrigin: function (x, y) + { + if (x === undefined) { x = 0.5; } + if (y === undefined) { y = x; } + + this._originX = x; + this._originY = y; + + this.updateVertices(); + + return this.updateDisplayOrigin(); + }, + + /** + * This method is included but does nothing for the Nine Slice Game Object, + * because the size of the object isn't based on the texture frame. * - * @method Phaser.GameObjects.Rope#setDebug - * @since 3.23.0 + * You should not call this method. * - * @param {Phaser.GameObjects.Graphics} [graphic] - The Graphic instance to render to if using the built-in callback. - * @param {function} [callback] - The callback to invoke during debug render. Leave as undefined to use the built-in callback. + * @method Phaser.GameObjects.NineSlice#setSizeToFrame + * @since 3.60.0 * * @return {this} This Game Object instance. */ - setDebug: function (graphic, callback) + setSizeToFrame: function () { - this.debugGraphic = graphic; - - if (!graphic && !callback) - { - this.debugCallback = null; - } - else if (!callback) - { - this.debugCallback = this.renderDebugVerts; - } - else + if (this.is3Slice) { - this.debugCallback = callback; + var height = this.frame.height; + + this._height = height; + this.topHeight = height; + this.bottomHeight = 0; } + this.updateUVs(); + return this; }, /** - * The built-in Rope vertices debug rendering method. - * - * See `Rope.setDebug` for more details. + * Handles the pre-destroy step for the Nine Slice, which removes the vertices. * - * @method Phaser.GameObjects.Rope#renderDebugVerts - * @since 3.23.0 - * - * @param {Phaser.GameObjects.Rope} src - The Rope object being rendered. - * @param {number} meshLength - The number of vertices in the mesh. - * @param {number[]} verts - An array of translated vertex coordinates. + * @method Phaser.GameObjects.NineSlice#preDestroy + * @private + * @since 3.60.0 */ - renderDebugVerts: function (src, meshLength, verts) + preDestroy: function () { - var graphic = src.debugGraphic; + this.vertices = []; + } - var px0 = verts[0]; - var py0 = verts[1]; - var px1 = verts[2]; - var py1 = verts[3]; +}); - graphic.lineBetween(px0, py0, px1, py1); +module.exports = NineSlice; - for (var i = 4; i < meshLength; i += 4) + +/***/ }), + +/***/ 40964: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var GetValue = __webpack_require__(10850); +var NineSlice = __webpack_require__(44139); + +/** + * Creates a new Nine Slice Game Object and returns it. + * + * Note: This method will only be available if the Nine Slice Game Object and WebGL support have been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#nineslice + * @since 3.60.0 + * + * @param {Phaser.Types.GameObjects.NineSlice.NineSliceConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.NineSlice} The Game Object that was created. + */ +GameObjectCreator.register('nineslice', function (config, addToScene) +{ + if (config === undefined) { config = {}; } + + var key = GetAdvancedValue(config, 'key', null); + var frame = GetAdvancedValue(config, 'frame', null); + var width = GetValue(config, 'width', 256); + var height = GetValue(config, 'height', 256); + var leftWidth = GetValue(config, 'leftWidth', 10); + var rightWidth = GetValue(config, 'rightWidth', 10); + var topHeight = GetValue(config, 'topHeight', 0); + var bottomHeight = GetValue(config, 'bottomHeight', 0); + + var nineslice = new NineSlice(this.scene, 0, 0, key, frame, width, height, leftWidth, rightWidth, topHeight, bottomHeight); + + if (addToScene !== undefined) + { + config.add = addToScene; + } + + BuildGameObject(this.scene, nineslice, config); + + return nineslice; +}); + + +/***/ }), + +/***/ 53778: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NineSlice = __webpack_require__(44139); +var GameObjectFactory = __webpack_require__(61286); + +/** + * A Nine Slice Game Object allows you to display a texture-based object that + * can be stretched both horizontally and vertically, but that retains + * fixed-sized corners. The dimensions of the corners are set via the + * parameters to this class. + * + * This is extremely useful for UI and button like elements, where you need + * them to expand to accommodate the content without distorting the texture. + * + * The texture you provide for this Game Object should be based on the + * following layout structure: + * + * ``` + * A B + * +---+----------------------+---+ + * C | 1 | 2 | 3 | + * +---+----------------------+---+ + * | | | | + * | 4 | 5 | 6 | + * | | | | + * +---+----------------------+---+ + * D | 7 | 8 | 9 | + * +---+----------------------+---+ + * ``` + * + * When changing this objects width and / or height: + * + * areas 1, 3, 7 and 9 (the corners) will remain unscaled + * areas 2 and 8 will be stretched horizontally only + * areas 4 and 6 will be stretched vertically only + * area 5 will be stretched both horizontally and vertically + * + * You can also create a 3 slice Game Object: + * + * This works in a similar way, except you can only stretch it horizontally. + * Therefore, it requires less configuration: + * + * ``` + * A B + * +---+----------------------+---+ + * | | | | + * C | 1 | 2 | 3 | + * | | | | + * +---+----------------------+---+ + * ``` + * + * When changing this objects width (you cannot change its height) + * + * areas 1 and 3 will remain unscaled + * area 2 will be stretched horizontally + * + * The above configuration concept is adapted from the Pixi NineSlicePlane. + * + * To specify a 3 slice object instead of a 9 slice you should only + * provide the `leftWidth` and `rightWidth` parameters. To create a 9 slice + * you must supply all parameters. + * + * The _minimum_ width this Game Object can be is the total of + * `leftWidth` + `rightWidth`. The _minimum_ height this Game Object + * can be is the total of `topHeight` + `bottomHeight`. + * If you need to display this object at a smaller size, you can scale it. + * + * In terms of performance, using a 3 slice Game Object is the equivalent of + * having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent + * of having 9 Sprites in a row. The vertices of this object are all batched + * together and can co-exist with other Sprites and graphics on the display + * list, without incurring any additional overhead. + * + * As of Phaser 3.60 this Game Object is WebGL only. + * + * @method Phaser.GameObjects.GameObjectFactory#nineslice + * @webglOnly + * @since 3.60.0 + * + * @param {number} x - The horizontal position of the center of this Game Object in the world. + * @param {number} y - The vertical position of the center 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. + * @param {number} [width=256] - The width of the Nine Slice Game Object. You can adjust the width post-creation. + * @param {number} [height=256] - The height of the Nine Slice Game Object. If this is a 3 slice object the height will be fixed to the height of the texture and cannot be changed. + * @param {number} [leftWidth=10] - The size of the left vertical column (A). + * @param {number} [rightWidth=10] - The size of the right vertical column (B). + * @param {number} [topHeight=0] - The size of the top horiztonal row (C). Set to zero or undefined to create a 3 slice object. + * @param {number} [bottomHeight=0] - The size of the bottom horiztonal row (D). Set to zero or undefined to create a 3 slice object. + * + * @return {Phaser.GameObjects.NineSlice} The Game Object that was created. + */ +if (true) +{ + GameObjectFactory.register('nineslice', function (x, y, texture, frame, width, height, leftWidth, rightWidth, topHeight, bottomHeight) + { + return this.displayList.add(new NineSlice(this.scene, x, y, texture, frame, width, height, leftWidth, rightWidth, topHeight, bottomHeight)); + }); +} + + +/***/ }), + +/***/ 94456: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(27420); +} + +if (true) +{ + // renderCanvas = require('./MeshCanvasRenderer'); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 27420: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetCalcMatrix = __webpack_require__(73329); +var Utils = __webpack_require__(75512); + +/** + * 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.Mesh#renderWebGL + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Mesh} 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 NineSliceWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + var verts = src.vertices; + var totalVerts = verts.length; + + if (totalVerts === 0) + { + return; + } + + camera.addToRenderList(src); + + var pipeline = renderer.pipelines.set(src.pipeline, src); + + var calcMatrix = GetCalcMatrix(src, camera, parentMatrix, false).calc; + + // This causes a flush if the NineSlice has a Post Pipeline + renderer.pipelines.preBatch(src); + + var textureUnit = pipeline.setGameObject(src); + + var F32 = pipeline.vertexViewF32; + var U32 = pipeline.vertexViewU32; + + var vertexOffset = (pipeline.vertexCount * pipeline.currentShader.vertexComponentCount) - 1; + + var roundPixels = camera.roundPixels; + + var tintEffect = src.tintFill; + var alpha = camera.alpha * src.alpha; + var color = Utils.getTintAppendFloatAlpha(src.tint, alpha); + + var available = pipeline.vertexAvailable(); + var flushCount = -1; + + if (available < totalVerts) + { + flushCount = available; + } + + for (var i = 0; i < totalVerts; i++) + { + var vert = verts[i]; + + if (i === flushCount) { - var x0 = verts[i + 0]; - var y0 = verts[i + 1]; - var x1 = verts[i + 2]; - var y1 = verts[i + 3]; + pipeline.flush(); - graphic.lineBetween(px0, py0, x0, y0); - graphic.lineBetween(px1, py1, x1, y1); - graphic.lineBetween(px1, py1, x0, y0); - graphic.lineBetween(x0, y0, x1, y1); + textureUnit = pipeline.setGameObject(src); - px0 = x0; - py0 = y0; - px1 = x1; - py1 = y1; + vertexOffset = 0; } + + F32[++vertexOffset] = calcMatrix.getXRound(vert.vx, vert.vy, roundPixels); + F32[++vertexOffset] = calcMatrix.getYRound(vert.vx, vert.vy, roundPixels); + F32[++vertexOffset] = vert.u; + F32[++vertexOffset] = vert.v; + F32[++vertexOffset] = textureUnit; + F32[++vertexOffset] = tintEffect; + U32[++vertexOffset] = color; + + pipeline.vertexCount++; + + pipeline.currentBatch.count = (pipeline.vertexCount - pipeline.currentBatch.start); + } + + renderer.pipelines.postBatch(src); +}; + +module.exports = NineSliceWebGLRenderer; + + +/***/ }), + +/***/ 19737: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var EmitterOp = __webpack_require__(93025); +var GetColor = __webpack_require__(22946); +var GetEaseFunction = __webpack_require__(21902); +var GetInterpolationFunction = __webpack_require__(4840); +var IntegerToRGB = __webpack_require__(15978); + +/** + * @classdesc + * This class is responsible for taking control over the color property + * in the Particle class and managing its emission and updating functions. + * + * See the `ParticleEmitter` class for more details on emitter op configuration. + * + * @class EmitterColorOp + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.60.0 + * + * @param {string} key - The name of the property. + */ +var EmitterColorOp = new Class({ + + Extends: EmitterOp, + + initialize: + + function EmitterColorOp (key) + { + EmitterOp.call(this, key, null, false); + + this.active = false; + + this.easeName = 'Linear'; + + /** + * An array containing the red color values. + * + * Populated during the `setMethods` method. + * + * @name Phaser.GameObjects.Particles.EmitterColorOp#r + * @type {number[]} + * @since 3.60.0 + */ + this.r = []; + + /** + * An array containing the green color values. + * + * Populated during the `setMethods` method. + * + * @name Phaser.GameObjects.Particles.EmitterColorOp#g + * @type {number[]} + * @since 3.60.0 + */ + this.g = []; + + /** + * An array containing the blue color values. + * + * Populated during the `setMethods` method. + * + * @name Phaser.GameObjects.Particles.EmitterColorOp#b + * @type {number[]} + * @since 3.60.0 + */ + this.b = []; }, /** - * Handles the pre-destroy step for the Rope, which removes the Animation component and typed arrays. + * Checks the type of `EmitterOp.propertyValue` to determine which + * method is required in order to return values from this op function. * - * @method Phaser.GameObjects.Rope#preDestroy - * @private - * @since 3.23.0 + * @method Phaser.GameObjects.Particles.EmitterColorOp#getMethod + * @since 3.60.0 + * + * @return {number} A number between 0 and 9 which should be passed to `setMethods`. */ - preDestroy: function () + getMethod: function () { - this.anims.destroy(); - - this.anims = undefined; - - this.points = null; - this.vertices = null; - this.uv = null; - this.colors = null; - this.alphas = null; - - this.debugCallback = null; - this.debugGraphic = null; + return (this.propertyValue === null) ? 0 : 9; }, /** - * The horizontally flipped state of the Game Object. + * Sets the EmitterColorOp method values, if in use. * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @method Phaser.GameObjects.Particles.EmitterColorOp#setMethods + * @since 3.60.0 * - * @name Phaser.GameObjects.Rope#flipX - * @type {boolean} - * @default false - * @since 3.23.0 + * @return {this} This Emitter Op object. */ - flipX: { + setMethods: function () + { + var value = this.propertyValue; + var current = value; - get: function () - { - return this._flipX; - }, + var onEmit = this.defaultEmit; + var onUpdate = this.defaultUpdate; - set: function (value) + if (this.method === 9) { - this._flipX = value; + this.start = value[0]; + this.ease = GetEaseFunction('Linear'); + this.interpolation = GetInterpolationFunction('linear'); - return this.updateUVs(); + onEmit = this.easedValueEmit; + onUpdate = this.easeValueUpdate; + current = value[0]; + + this.active = true; + + // Populate the r,g,b arrays + for (var i = 0; i < value.length; i++) + { + // in hex format 0xff0000 + var color = IntegerToRGB(value[i]); + + this.r.push(color.r); + this.g.push(color.g); + this.b.push(color.b); + } } + this.onEmit = onEmit; + this.onUpdate = onUpdate; + this.current = current; + + return this; }, /** - * The vertically flipped state of the Game Object. + * Sets the Ease function to use for Color interpolation. * - * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @method Phaser.GameObjects.Particles.EmitterColorOp#setEase + * @since 3.60.0 * - * @name Phaser.GameObjects.Rope#flipY - * @type {boolean} - * @default false - * @since 3.23.0 + * @param {string} ease - The string-based name of the Ease function to use. */ - flipY: { + setEase: function (value) + { + this.easeName = value; - get: function () - { - return this._flipY; - }, + this.ease = GetEaseFunction(value); + }, - set: function (value) - { - this._flipY = value; + /** + * An `onEmit` callback for an eased property. + * + * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterColorOp#easeValueUpdate}. + * + * @method Phaser.GameObjects.Particles.EmitterColorOp#easedValueEmit + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * + * @return {number} {@link Phaser.GameObjects.Particles.EmitterColorOp#start}, as the new value of the property. + */ + easedValueEmit: function () + { + this.current = this.start; - return this.updateUVs(); - } + return this.start; + }, + + /** + * An `onUpdate` callback that returns an eased value between the + * {@link Phaser.GameObjects.Particles.EmitterColorOp#start} and {@link Phaser.GameObjects.Particles.EmitterColorOp#end} + * range. + * + * @method Phaser.GameObjects.Particles.EmitterColorOp#easeValueUpdate + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + * + * @return {number} The new value of the property. + */ + easeValueUpdate: function (particle, key, t) + { + var v = this.ease(t); + var r = this.interpolation(this.r, v); + var g = this.interpolation(this.g, v); + var b = this.interpolation(this.b, v); + + var current = GetColor(r, g, b); + + this.current = current; + + return current; } }); -module.exports = Rope; +module.exports = EmitterColorOp; /***/ }), -/* 224 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 93025: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddToDOM = __webpack_require__(142); -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__(458); -var GetValue = __webpack_require__(6); -var RemoveFromDOM = __webpack_require__(202); -var TextRender = __webpack_require__(1088); -var TextStyle = __webpack_require__(459); +var Between = __webpack_require__(17489); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var FloatBetween = __webpack_require__(61616); +var GetEaseFunction = __webpack_require__(21902); +var GetFastValue = __webpack_require__(72632); +var GetInterpolationFunction = __webpack_require__(4840); +var SnapTo = __webpack_require__(88462); +var Wrap = __webpack_require__(1071); /** * @classdesc - * A Text Game Object. - * - * Text objects work by creating their own internal hidden Canvas and then renders text to it using - * the standard Canvas `fillText` API. It then creates a texture from this canvas which is rendered - * to your game during the render pass. - * - * Because it uses the Canvas API you can take advantage of all the features this offers, such as - * applying gradient fills to the text, or strokes, shadows and more. You can also use custom fonts - * loaded externally, such as Google or TypeKit Web fonts. - * - * **Important:** The font name must be quoted if it contains certain combinations of digits or - * special characters, either when creating the Text object, or when setting the font via `setFont` - * or `setFontFamily`, e.g.: - * - * ```javascript - * this.add.text(0, 0, 'Hello World', { fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif' }); - * ``` - * - * ```javascript - * this.add.text(0, 0, 'Hello World', { font: '"Press Start 2P"' }); - * ``` - * - * You can only display fonts that are currently loaded and available to the browser: therefore fonts must - * be pre-loaded. Phaser does not do ths for you, so you will require the use of a 3rd party font loader, - * or have the fonts ready available in the CSS on the page in which your Phaser game resides. + * This class is responsible for taking control over a single property + * in the Particle class and managing its emission and updating functions. * - * See {@link http://www.jordanm.co.uk/tinytype this compatibility table} for the available default fonts - * across mobile browsers. + * Particles properties such as `x`, `y`, `scaleX`, `lifespan` and others all use + * EmitterOp instances to manage them, as they can be given in a variety of + * formats: from simple values, to functions, to dynamic callbacks. * - * A note on performance: Every time the contents of a Text object changes, i.e. changing the text being - * displayed, or the style of the text, it needs to remake the Text canvas, and if on WebGL, re-upload the - * new texture to the GPU. This can be an expensive operation if used often, or with large quantities of - * Text objects in your game. If you run into performance issues you would be better off using Bitmap Text - * instead, as it benefits from batching and avoids expensive Canvas API calls. + * See the `ParticleEmitter` class for more details on emitter op configuration. * - * @class Text - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects + * @class EmitterOp + * @memberof Phaser.GameObjects.Particles * @constructor * @since 3.0.0 * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.ComputedSize - * @extends Phaser.GameObjects.Components.Crop - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @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|string[])} text - The text this Text object will display. - * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The text style configuration object. - * - * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Valid_family_names + * @param {string} key - The name of the property. + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} defaultValue - The default value of the property. + * @param {boolean} [emitOnly=false] - Whether the property can only be modified when a Particle is emitted. */ -var Text = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.ComputedSize, - Components.Crop, - Components.Depth, - Components.Flip, - Components.GetBounds, - Components.Mask, - Components.Origin, - Components.Pipeline, - Components.ScrollFactor, - Components.Tint, - Components.Transform, - Components.Visible, - TextRender - ], +var EmitterOp = new Class({ initialize: - function Text (scene, x, y, text, style) + function EmitterOp (key, defaultValue, emitOnly) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - - GameObject.call(this, scene, 'Text'); + if (emitOnly === undefined) { emitOnly = false; } /** - * The renderer in use by this Text object. + * The name of this property. * - * @name Phaser.GameObjects.Text#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.EmitterOp#propertyKey + * @type {string} + * @since 3.0.0 */ - this.renderer = scene.sys.renderer; - - this.setPosition(x, y); - this.setOrigin(0, 0); - this.initPipeline(); + this.propertyKey = key; /** - * The canvas element that the text is rendered to. + * The current value of this property. * - * @name Phaser.GameObjects.Text#canvas - * @type {HTMLCanvasElement} + * This can be a simple value, an array, a function or an onEmit + * configuration object. + * + * @name Phaser.GameObjects.Particles.EmitterOp#propertyValue + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} * @since 3.0.0 */ - this.canvas = CanvasPool.create(this); + this.propertyValue = defaultValue; /** - * The context of the canvas element that the text is rendered to. + * The default value of this property. * - * @name Phaser.GameObjects.Text#context - * @type {CanvasRenderingContext2D} + * This can be a simple value, an array, a function or an onEmit + * configuration object. + * + * @name Phaser.GameObjects.Particles.EmitterOp#defaultValue + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} * @since 3.0.0 */ - this.context = this.canvas.getContext('2d'); + this.defaultValue = defaultValue; /** - * The Text Style object. - * - * Manages the style of this Text object. + * 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.Text#style - * @type {Phaser.GameObjects.TextStyle} + * @name Phaser.GameObjects.Particles.EmitterOp#steps + * @type {number} + * @default 0 * @since 3.0.0 */ - this.style = new TextStyle(this, style); + this.steps = 0; /** - * Whether to automatically round line positions. + * The step counter for stepped easing, per emit. * - * @name Phaser.GameObjects.Text#autoRound - * @type {boolean} - * @default true + * @name Phaser.GameObjects.Particles.EmitterOp#counter + * @type {number} + * @default 0 * @since 3.0.0 */ - this.autoRound = true; + this.counter = 0; /** - * The Regular Expression that is used to split the text up into lines, in - * multi-line text. By default this is `/(?:\r\n|\r|\n)/`. - * You can change this RegExp to be anything else that you may need. + * When the step counter reaches it's maximum, should it then + * yoyo back to the start again, or flip over to it? * - * @name Phaser.GameObjects.Text#splitRegExp - * @type {object} - * @since 3.0.0 + * @name Phaser.GameObjects.Particles.EmitterOp#yoyo + * @type {boolean} + * @default false + * @since 3.60.0 */ - this.splitRegExp = /(?:\r\n|\r|\n)/; + this.yoyo = false; /** - * The text to display. + * The counter direction. 0 for up and 1 for down. * - * @name Phaser.GameObjects.Text#_text - * @type {string} - * @private - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.EmitterOp#direction + * @type {number} + * @default 0 + * @since 3.60.0 */ - this._text = undefined; + this.direction = 0; /** - * Specify a padding value which is added to the line width and height when calculating the Text size. - * Allows you to add extra spacing if the browser is unable to accurately determine the true font dimensions. + * The start value for this property to ease between. * - * @name Phaser.GameObjects.Text#padding - * @type {Phaser.Types.GameObjects.Text.TextPadding} + * If an interpolation this holds a reference to the number data array. + * + * @name Phaser.GameObjects.Particles.EmitterOp#start + * @type {number|number[]} + * @default 0 * @since 3.0.0 */ - this.padding = { left: 0, right: 0, top: 0, bottom: 0 }; + this.start = 0; /** - * The width of this Text object. + * The most recently calculated value. Updated every time an + * emission or update method is called. Treat as read-only. * - * @name Phaser.GameObjects.Text#width + * @name Phaser.GameObjects.Particles.EmitterOp#current * @type {number} - * @default 1 - * @since 3.0.0 + * @since 3.60.0 */ - this.width = 1; + this.current = 0; /** - * The height of this Text object. + * The end value for this property to ease between. * - * @name Phaser.GameObjects.Text#height + * @name Phaser.GameObjects.Particles.EmitterOp#end * @type {number} - * @default 1 + * @default 0 * @since 3.0.0 */ - this.height = 1; + this.end = 0; /** - * The line spacing value. - * This value is added to the font height to calculate the overall line height. - * Only has an effect if this Text object contains multiple lines of text. + * The easing function to use for updating this property, if any. * - * If you update this property directly, instead of using the `setLineSpacing` method, then - * be sure to call `updateText` after, or you won't see the change reflected in the Text object. + * @name Phaser.GameObjects.Particles.EmitterOp#ease + * @type {?function} + * @since 3.0.0 + */ + this.ease = null; + + /** + * The interpolation function to use for updating this property, if any. * - * @name Phaser.GameObjects.Text#lineSpacing - * @type {number} - * @since 3.13.0 + * @name Phaser.GameObjects.Particles.EmitterOp#interpolation + * @type {?function} + * @since 3.60.0 */ - this.lineSpacing = 0; + this.interpolation = null; /** - * Whether the text or its settings have changed and need updating. + * Whether this property can only be modified when a Particle is emitted. * - * @name Phaser.GameObjects.Text#dirty + * 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} - * @default false * @since 3.0.0 */ - this.dirty = false; + this.emitOnly = emitOnly; - // If resolution wasn't set, force it to 1 - if (this.style.resolution === 0) - { - this.style.resolution = 1; - } + /** + * 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 internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. + * The callback to run for Particles when they are updated. * - * @name Phaser.GameObjects.Text#_crop - * @type {object} - * @private - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.EmitterOp#onUpdate + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback} + * @since 3.0.0 */ - this._crop = this.resetCropObject(); + this.onUpdate = this.defaultUpdate; - // Create a Texture for this Text object - this.texture = scene.sys.textures.addCanvas(null, this.canvas, true); + /** + * Set to `false` to disable this EmitterOp. + * + * @name Phaser.GameObjects.Particles.EmitterOp#active + * @type {boolean} + * @since 3.60.0 + */ + this.active = true; - // Get the frame - this.frame = this.texture.get(); + /** + * The onEmit method type of this EmitterOp. + * + * Set as part of `setMethod` and cached here to avoid + * re-setting when only the value changes. + * + * @name Phaser.GameObjects.Particles.EmitterOp#method + * @type {number} + * @since 3.60.0 + */ + this.method = 0; - // Set the resolution - this.frame.source.resolution = this.style.resolution; + /** + * The callback to run for Particles when they are emitted from the Particle Emitter. + * This is set during `setMethods` and used by `proxyEmit`. + * + * @name Phaser.GameObjects.Particles.EmitterOp#_onEmit + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitCallback} + * @private + * @since 3.60.0 + */ + this._onEmit; - if (this.renderer && this.renderer.gl) + /** + * The callback to run for Particles when they are updated. + * This is set during `setMethods` and used by `proxyUpdate`. + * + * @name Phaser.GameObjects.Particles.EmitterOp#_onUpdate + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback} + * @private + * @since 3.60.0 + */ + this._onUpdate; + }, + + /** + * 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) { - // Clear the default 1x1 glTexture, as we override it later - this.renderer.deleteTexture(this.frame.source.glTexture); + config = {}; + } - this.frame.source.glTexture = null; + if (newKey) + { + this.propertyKey = newKey; } - this.initRTL(); + this.propertyValue = GetFastValue( + config, + this.propertyKey, + this.defaultValue + ); - this.setText(text); + this.method = this.getMethod(); - if (style && style.padding) - { - this.setPadding(style.padding); - } + this.setMethods(); - if (style && style.lineSpacing) + if (this.emitOnly) { - this.setLineSpacing(style.lineSpacing); + // Reset it back again + this.onUpdate = this.defaultUpdate; } + }, - scene.sys.game.events.on(GameEvents.CONTEXT_RESTORED, function () - { - this.dirty = true; - }, this); + /** + * 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 JSON.stringify(this.propertyValue); }, /** - * Initialize right to left text. + * Change the current value of the property and update its callback methods. * - * @method Phaser.GameObjects.Text#initRTL + * @method Phaser.GameObjects.Particles.EmitterOp#onChange * @since 3.0.0 + * + * @param {number} value - The new numeric value of this property. + * + * @return {this} This Emitter Op object. */ - initRTL: function () + onChange: function (value) { - if (!this.style.rtl) + var current; + + switch (this.method) { - return; - } + // Number + // Custom Callback (onEmit only) + // Custom onEmit and/or onUpdate callbacks + case 1: + case 3: + case 8: + current = value; + break; - // Here is where the crazy starts. - // - // Due to browser implementation issues, you cannot fillText BiDi text to a canvas - // that is not part of the DOM. It just completely ignores the direction property. + // Random Array + case 2: + if (this.propertyValue.indexOf(value) >= 0) + { + current = value; + } + break; - this.canvas.dir = 'rtl'; + // Stepped start/end + case 4: + var step = (this.end - this.start) / this.steps; + current = SnapTo(value, step); + this.counter = current; + break; - // Experimental atm, but one day ... - this.context.direction = 'rtl'; + // Eased start/end + // min/max (random float or int) + // Random object (random integer) + case 5: + case 6: + case 7: + current = Clamp(value, this.start, this.end); + break; - // Add it to the DOM, but hidden within the parent canvas. - this.canvas.style.display = 'none'; + // Interpolation + case 9: + current = this.start[0]; + break; + } - AddToDOM(this.canvas, this.scene.sys.canvas); + this.current = current; - // And finally we set the x origin - this.originX = 1; + return this; }, /** - * Greedy wrapping algorithm that will wrap words as the line grows longer than its horizontal - * bounds. + * Checks the type of `EmitterOp.propertyValue` to determine which + * method is required in order to return values from this op function. * - * @method Phaser.GameObjects.Text#runWordWrap - * @since 3.0.0 - * - * @param {string} text - The text to perform word wrap detection against. + * @method Phaser.GameObjects.Particles.EmitterOp#getMethod + * @since 3.60.0 * - * @return {string} The text after wrapping has been applied. + * @return {number} A number between 0 and 9 which should be passed to `setMethods`. */ - runWordWrap: function (text) + getMethod: function () { - var style = this.style; + var value = this.propertyValue; - if (style.wordWrapCallback) + // `moveToX` and `moveToY` are null by default + if (value === null) { - var wrappedLines = style.wordWrapCallback.call(style.wordWrapCallbackScope, text, this); + return 0; + } - if (Array.isArray(wrappedLines)) - { - wrappedLines = wrappedLines.join('\n'); - } + var t = typeof value; - return wrappedLines; + if (t === 'number') + { + // Number + return 1; } - else if (style.wordWrapWidth) + else if (Array.isArray(value)) { - if (style.wordWrapUseAdvanced) + // Random Array + return 2; + } + else if (t === 'function') + { + // Custom Callback + return 3; + } + else if (t === 'object') + { + if (this.hasBoth(value, 'start', 'end')) { - return this.advancedWordWrap(text, this.context, this.style.wordWrapWidth); + if (this.has(value, 'steps')) + { + // Stepped start/end + return 4; + } + else + { + // Eased start/end + return 5; + } } - else + else if (this.hasBoth(value, 'min', 'max')) { - return this.basicWordWrap(text, this.context, this.style.wordWrapWidth); + // min/max + return 6; + } + else if (this.has(value, 'random')) + { + // Random object + return 7; + } + else if (this.hasEither(value, 'onEmit', 'onUpdate')) + { + // Custom onEmit onUpdate + return 8; + } + else if (this.has(value, 'interpolation')) + { + // Interpolation + return 9; } } - else - { - return text; - } + + return 0; }, /** - * Advanced wrapping algorithm that will wrap words as the line grows longer than its horizontal - * bounds. Consecutive spaces will be collapsed and replaced with a single space. Lines will be - * trimmed of white space before processing. Throws an error if wordWrapWidth is less than a - * single character. + * Update the {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and + * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks based on the method returned + * from `getMethod`. The method is stored in the `EmitterOp.method` property + * and is a number between 0 and 9 inclusively. * - * @method Phaser.GameObjects.Text#advancedWordWrap + * @method Phaser.GameObjects.Particles.EmitterOp#setMethods * @since 3.0.0 * - * @param {string} text - The text to perform word wrap detection against. - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. - * @param {number} wordWrapWidth - The word wrap width. - * - * @return {string} The wrapped text. + * @return {this} This Emitter Op object. */ - advancedWordWrap: function (text, context, wordWrapWidth) + setMethods: function () { - var output = ''; - - // Condense consecutive spaces and split into lines - var lines = text - .replace(/ +/gi, ' ') - .split(this.splitRegExp); + var value = this.propertyValue; + var current = value; - var linesCount = lines.length; + var onEmit = this.defaultEmit; + var onUpdate = this.defaultUpdate; - for (var i = 0; i < linesCount; i++) + switch (this.method) { - var line = lines[i]; - var out = ''; + // Number + case 1: + onEmit = this.staticValueEmit; + break; - // Trim whitespace - line = line.replace(/^ *|\s*$/gi, ''); + // Random Array + case 2: + onEmit = this.randomStaticValueEmit; + current = value[0]; + break; - // If entire line is less than wordWrapWidth append the entire line and exit early - var lineWidth = context.measureText(line).width; + // Custom Callback (onEmit only) + case 3: + this._onEmit = value; + onEmit = this.proxyEmit; + break; - if (lineWidth < wordWrapWidth) - { - output += line + '\n'; - continue; - } + // Stepped start/end + case 4: + this.start = value.start; + this.end = value.end; + this.steps = value.steps; + this.counter = this.start; + this.yoyo = this.has(value, 'yoyo') ? value.yoyo : false; + this.direction = 0; + onEmit = this.steppedEmit; + current = this.start; + break; - // Otherwise, calculate new lines - var currentLineWidth = wordWrapWidth; + // Eased start/end + case 5: + this.start = value.start; + this.end = value.end; + var easeType = this.has(value, 'ease') ? value.ease : 'Linear'; + this.ease = GetEaseFunction(easeType, value.easeParams); + onEmit = (this.has(value, 'random') && value.random) ? this.randomRangedValueEmit : this.easedValueEmit; + onUpdate = this.easeValueUpdate; + current = this.start; + break; - // Split into words - var words = line.split(' '); + // min/max (random float or int) + case 6: + this.start = value.min; + this.end = value.max; + onEmit = (this.has(value, 'int') && value.int) ? this.randomRangedIntEmit : this.randomRangedValueEmit; + current = this.start; + break; - for (var j = 0; j < words.length; j++) - { - var word = words[j]; - var wordWithSpace = word + ' '; - var wordWidth = context.measureText(wordWithSpace).width; + // Random object (random integer) + case 7: + var rnd = value.random; - if (wordWidth > currentLineWidth) + if (Array.isArray(rnd)) { - // Break word - if (j === 0) - { - // Shave off letters from word until it's small enough - var newWord = wordWithSpace; - - while (newWord.length) - { - newWord = newWord.slice(0, -1); - wordWidth = context.measureText(newWord).width; - - if (wordWidth <= currentLineWidth) - { - break; - } - } - - // If wordWrapWidth is too small for even a single letter, shame user - // failure with a fatal error - if (!newWord.length) - { - throw new Error('This text\'s wordWrapWidth setting is less than a single character!'); - } - - // Replace current word in array with remainder - var secondPart = word.substr(newWord.length); - - words[j] = secondPart; - - // Append first piece to output - out += newWord; - } - - // If existing word length is 0, don't include it - var offset = (words[j].length) ? j : j + 1; - - // Collapse rest of sentence and remove any trailing white space - var remainder = words.slice(offset).join(' ') - .replace(/[ \n]*$/gi, ''); - - // Prepend remainder to next line - lines[i + 1] = remainder + ' ' + (lines[i + 1] || ''); - linesCount = lines.length; + this.start = rnd[0]; + this.end = rnd[1]; + } - break; // Processing on this line + onEmit = this.randomRangedIntEmit; + current = this.start; + break; - // Append word with space to output - } - else - { - out += wordWithSpace; - currentLineWidth -= wordWidth; - } - } + // Custom onEmit and/or onUpdate callbacks + case 8: + this._onEmit = (this.has(value, 'onEmit')) ? value.onEmit : this.defaultEmit; + this._onUpdate = (this.has(value, 'onUpdate')) ? value.onUpdate : this.defaultUpdate; + onEmit = this.proxyEmit; + onUpdate = this.proxyUpdate; + break; - // Append processed line to output - output += out.replace(/[ \n]*$/gi, '') + '\n'; + // Interpolation + case 9: + this.start = value.values; + var easeTypeI = this.has(value, 'ease') ? value.ease : 'Linear'; + this.ease = GetEaseFunction(easeTypeI, value.easeParams); + this.interpolation = GetInterpolationFunction(value.interpolation); + onEmit = this.easedValueEmit; + onUpdate = this.easeValueUpdate; + current = this.start[0]; + break; } - // Trim the end of the string - output = output.replace(/[\s|\n]*$/gi, ''); + this.onEmit = onEmit; + this.onUpdate = onUpdate; + this.current = current; - return output; + return this; }, /** - * Greedy wrapping algorithm that will wrap words as the line grows longer than its horizontal - * bounds. Spaces are not collapsed and whitespace is not trimmed. + * Check whether an object has the given property. * - * @method Phaser.GameObjects.Text#basicWordWrap + * @method Phaser.GameObjects.Particles.EmitterOp#has * @since 3.0.0 * - * @param {string} text - The text to perform word wrap detection against. - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. - * @param {number} wordWrapWidth - The word wrap width. + * @param {object} object - The object to check. + * @param {string} key - The key of the property to look for in the object. * - * @return {string} The wrapped text. + * @return {boolean} `true` if the property exists in the object, `false` otherwise. */ - basicWordWrap: function (text, context, wordWrapWidth) + has: function (object, key) { - var result = ''; - var lines = text.split(this.splitRegExp); - var lastLineIndex = lines.length - 1; - var whiteSpaceWidth = context.measureText(' ').width; - - for (var i = 0; i <= lastLineIndex; i++) - { - var spaceLeft = wordWrapWidth; - var words = lines[i].split(' '); - var lastWordIndex = words.length - 1; - - for (var j = 0; j <= lastWordIndex; j++) - { - var word = words[j]; - var wordWidth = context.measureText(word).width; - var wordWidthWithSpace = wordWidth; - - if (j < lastWordIndex) - { - wordWidthWithSpace += whiteSpaceWidth; - } - - if (wordWidthWithSpace > spaceLeft) - { - // Skip printing the newline if it's the first word of the line that is greater - // than the word wrap width. - if (j > 0) - { - result += '\n'; - spaceLeft = wordWrapWidth; - } - } - - result += word; - - if (j < lastWordIndex) - { - result += ' '; - spaceLeft -= wordWidthWithSpace; - } - else - { - spaceLeft -= wordWidth; - } - } - - if (i < lastLineIndex) - { - result += '\n'; - } - } - - return result; + return object.hasOwnProperty(key); }, /** - * Runs the given text through this Text objects word wrapping and returns the results as an - * array, where each element of the array corresponds to a wrapped line of text. + * Check whether an object has both of the given properties. * - * @method Phaser.GameObjects.Text#getWrappedText + * @method Phaser.GameObjects.Particles.EmitterOp#hasBoth * @since 3.0.0 * - * @param {string} text - The text for which the wrapping will be calculated. If unspecified, the Text objects current text will be used. + * @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 {string[]} An array of strings with the pieces of wrapped text. + * @return {boolean} `true` if both properties exist in the object, `false` otherwise. */ - getWrappedText: function (text) + hasBoth: function (object, key1, key2) { - if (text === undefined) { text = this._text; } - - this.style.syncFont(this.canvas, this.context); - - var wrappedLines = this.runWordWrap(text); - - return wrappedLines.split(this.splitRegExp); + return object.hasOwnProperty(key1) && object.hasOwnProperty(key2); }, /** - * Set the text to display. - * - * An array of strings will be joined with `\n` line breaks. + * Check whether an object has at least one of the given properties. * - * @method Phaser.GameObjects.Text#setText + * @method Phaser.GameObjects.Particles.EmitterOp#hasEither * @since 3.0.0 * - * @param {(string|string[])} value - The string, or array of strings, to be set as the content of this Text object. + * @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 {this} This Text object. + * @return {boolean} `true` if at least one of the properties exists in the object, `false` if neither exist. */ - setText: function (value) + hasEither: function (object, key1, key2) { - if (!value && value !== 0) - { - value = ''; - } - - if (Array.isArray(value)) - { - value = value.join('\n'); - } - - if (value !== this._text) - { - this._text = value.toString(); - - this.updateText(); - } - - return this; + return object.hasOwnProperty(key1) || object.hasOwnProperty(key2); }, /** - * Set the text style. - * - * @example - * text.setStyle({ - * fontSize: '64px', - * fontFamily: 'Arial', - * color: '#ffffff', - * align: 'center', - * backgroundColor: '#ff00ff' - * }); + * The returned value sets what the property will be at the START of the particles life, on emit. * - * @method Phaser.GameObjects.Text#setStyle + * @method Phaser.GameObjects.Particles.EmitterOp#defaultEmit * @since 3.0.0 * - * @param {object} style - The style settings to set. + * @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 {this} This Text object. + * @return {number} The new value of the property. */ - setStyle: function (style) + defaultEmit: function (particle, key, value) { - return this.style.setStyle(style); + return value; }, /** - * 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. + * The returned value updates the property for the duration of the particles life. * - * **Important:** The font name must be quoted if it contains certain combinations of digits or - * special characters: + * @method Phaser.GameObjects.Particles.EmitterOp#defaultUpdate + * @since 3.0.0 * - * ```javascript - * Text.setFont('"Press Start 2P"'); - * ``` + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + * @param {number} value - The current value of the property. * - * Equally, if you wish to provide a list of fallback fonts, then you should ensure they are all - * quoted properly, too: - * - * ```javascript - * Text.setFont('Georgia, "Goudy Bookletter 1911", Times, serif'); - * ``` - * - * @method Phaser.GameObjects.Text#setFont - * @since 3.0.0 - * - * @param {string} font - The font family or font settings to set. - * - * @return {this} This Text object. - * - * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Valid_family_names + * @return {number} The new value of the property. */ - setFont: function (font) + defaultUpdate: function (particle, key, t, value) { - return this.style.setFont(font); + return value; }, /** - * Set the font family. - * - * **Important:** The font name must be quoted if it contains certain combinations of digits or - * special characters: - * - * ```javascript - * Text.setFont('"Press Start 2P"'); - * ``` - * - * Equally, if you wish to provide a list of fallback fonts, then you should ensure they are all - * quoted properly, too: - * - * ```javascript - * Text.setFont('Georgia, "Goudy Bookletter 1911", Times, serif'); - * ``` + * The returned value sets what the property will be at the START of the particles life, on emit. * - * @method Phaser.GameObjects.Text#setFontFamily - * @since 3.0.0 + * This method is only used when you have provided a custom emit callback. * - * @param {string} family - The font family. + * @method Phaser.GameObjects.Particles.EmitterOp#proxyEmit + * @since 3.60.0 * - * @return {this} This Text object. + * @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. * - * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Valid_family_names + * @return {number} The new value of the property. */ - setFontFamily: function (family) + proxyEmit: function (particle, key, value) { - return this.style.setFontFamily(family); - }, + var result = this._onEmit(particle, key, value); - /** - * Set the font size. - * - * @method Phaser.GameObjects.Text#setFontSize - * @since 3.0.0 - * - * @param {number} size - The font size. - * - * @return {this} This Text object. - */ - setFontSize: function (size) - { - return this.style.setFontSize(size); - }, + this.current = result; - /** - * Set the font style. - * - * @method Phaser.GameObjects.Text#setFontStyle - * @since 3.0.0 - * - * @param {string} style - The font style. - * - * @return {this} This Text object. - */ - setFontStyle: function (style) - { - return this.style.setFontStyle(style); + return result; }, /** - * 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.Text#setFixedSize - * @since 3.0.0 - * - * @param {number} width - The fixed width to set. `0` disables fixed width. - * @param {number} height - The fixed height to set. `0` disables fixed height. + * The returned value updates the property for the duration of the particles life. * - * @return {this} This Text object. - */ - setFixedSize: function (width, height) - { - return this.style.setFixedSize(width, height); - }, - - /** - * Set the background color. + * This method is only used when you have provided a custom update callback. * - * @method Phaser.GameObjects.Text#setBackgroundColor - * @since 3.0.0 + * @method Phaser.GameObjects.Particles.EmitterOp#proxyUpdate + * @since 3.60.0 * - * @param {string} color - The background color. + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + * @param {number} value - The current value of the property. * - * @return {this} This Text object. + * @return {number} The new value of the property. */ - setBackgroundColor: function (color) + proxyUpdate: function (particle, key, t, value) { - return this.style.setBackgroundColor(color); - }, + var result = this._onUpdate(particle, key, t, value); - /** - * Set the fill style to be used by the Text object. - * - * This can be any valid CanvasRenderingContext2D fillStyle value, such as - * a color (in hex, rgb, rgba, hsl or named values), a gradient or a pattern. - * - * See the [MDN fillStyle docs](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle) for more details. - * - * @method Phaser.GameObjects.Text#setFill - * @since 3.0.0 - * - * @param {(string|any)} color - The text fill style. Can be any valid CanvasRenderingContext `fillStyle` value. - * - * @return {this} This Text object. - */ - setFill: function (fillStyle) - { - return this.style.setFill(fillStyle); - }, + this.current = result; - /** - * Set the text fill color. - * - * @method Phaser.GameObjects.Text#setColor - * @since 3.0.0 - * - * @param {string} color - The text fill color. - * - * @return {this} This Text object. - */ - setColor: function (color) - { - return this.style.setColor(color); + return result; }, /** - * Set the stroke settings. + * An `onEmit` callback that returns the current value of the property. * - * @method Phaser.GameObjects.Text#setStroke + * @method Phaser.GameObjects.Particles.EmitterOp#staticValueEmit * @since 3.0.0 * - * @param {string} color - The stroke color. - * @param {number} thickness - The stroke thickness. - * - * @return {this} This Text object. + * @return {number} The current value of the property. */ - setStroke: function (color, thickness) + staticValueEmit: function () { - return this.style.setStroke(color, thickness); + return this.current; }, /** - * Set the shadow settings. + * An `onUpdate` callback that returns the current value of the property. * - * @method Phaser.GameObjects.Text#setShadow + * @method Phaser.GameObjects.Particles.EmitterOp#staticValueUpdate * @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 {this} This Text object. + * @return {number} The current value of the property. */ - setShadow: function (x, y, color, blur, shadowStroke, shadowFill) + staticValueUpdate: function () { - return this.style.setShadow(x, y, color, blur, shadowStroke, shadowFill); + return this.current; }, /** - * Set the shadow offset. + * An `onEmit` callback that returns a random value from the current value array. * - * @method Phaser.GameObjects.Text#setShadowOffset + * @method Phaser.GameObjects.Particles.EmitterOp#randomStaticValueEmit * @since 3.0.0 * - * @param {number} x - The horizontal shadow offset. - * @param {number} y - The vertical shadow offset. - * - * @return {this} This Text object. + * @return {number} The new value of the property. */ - setShadowOffset: function (x, y) + randomStaticValueEmit: function () { - return this.style.setShadowOffset(x, y); - }, + var randomIndex = Math.floor(Math.random() * this.propertyValue.length); - /** - * Set the shadow color. - * - * @method Phaser.GameObjects.Text#setShadowColor - * @since 3.0.0 - * - * @param {string} color - The shadow color. - * - * @return {this} This Text object. - */ - setShadowColor: function (color) - { - return this.style.setShadowColor(color); - }, + this.current = this.propertyValue[randomIndex]; - /** - * Set the shadow blur radius. - * - * @method Phaser.GameObjects.Text#setShadowBlur - * @since 3.0.0 - * - * @param {number} blur - The shadow blur radius. - * - * @return {this} This Text object. - */ - setShadowBlur: function (blur) - { - return this.style.setShadowBlur(blur); + return this.current; }, /** - * Enable or disable shadow stroke. + * 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.Text#setShadowStroke + * @method Phaser.GameObjects.Particles.EmitterOp#randomRangedValueEmit * @since 3.0.0 * - * @param {boolean} enabled - Whether shadow stroke is enabled or not. + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The key of the property. * - * @return {this} This Text object. + * @return {number} The new value of the property. */ - setShadowStroke: function (enabled) + randomRangedValueEmit: function (particle, key) { - return this.style.setShadowStroke(enabled); - }, + var value = FloatBetween(this.start, this.end); - /** - * Enable or disable shadow fill. - * - * @method Phaser.GameObjects.Text#setShadowFill - * @since 3.0.0 - * - * @param {boolean} enabled - Whether shadow fill is enabled or not. - * - * @return {this} This Text object. - */ - setShadowFill: function (enabled) - { - return this.style.setShadowFill(enabled); - }, + if (particle && particle.data[key]) + { + particle.data[key].min = value; + particle.data[key].max = this.end; + } - /** - * Set the width (in pixels) to use for wrapping lines. Pass in null to remove wrapping by width. - * - * @method Phaser.GameObjects.Text#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 {this} This Text object. - */ - setWordWrapWidth: function (width, useAdvancedWrap) - { - return this.style.setWordWrapWidth(width, useAdvancedWrap); - }, + this.current = value; - /** - * Set a custom callback for wrapping lines. Pass in null to remove wrapping by callback. - * - * @method Phaser.GameObjects.Text#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 {this} This Text object. - */ - setWordWrapCallback: function (callback, scope) - { - return this.style.setWordWrapCallback(callback, scope); + return value; }, /** - * 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. + * 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.Text#setAlign - * @since 3.0.0 + * @method Phaser.GameObjects.Particles.EmitterOp#randomRangedIntEmit + * @since 3.60.0 * - * @param {string} [align='left'] - The text alignment for multi-line text. + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The key of the property. * - * @return {this} This Text object. + * @return {number} The new value of the property. */ - setAlign: function (align) + randomRangedIntEmit: function (particle, key) { - return this.style.setAlign(align); - }, + var value = Between(this.start, this.end); - /** - * Set the resolution used by this 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, or by specifying it in the Text style configuration object. - * - * 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. - * - * Therefore, please use with caution, as the more high res Text you have, the more memory it uses. - * - * @method Phaser.GameObjects.Text#setResolution - * @since 3.12.0 - * - * @param {number} value - The resolution for this Text object to use. - * - * @return {this} This Text object. - */ - setResolution: function (value) - { - return this.style.setResolution(value); - }, + if (particle && particle.data[key]) + { + particle.data[key].min = value; + particle.data[key].max = this.end; + } - /** - * Sets the line spacing value. - * - * This value is _added_ to the height of the font when calculating the overall line height. - * This only has an effect if this Text object consists of multiple lines of text. - * - * @method Phaser.GameObjects.Text#setLineSpacing - * @since 3.13.0 - * - * @param {number} value - The amount to add to the font height to achieve the overall line height. - * - * @return {this} This Text object. - */ - setLineSpacing: function (value) - { - this.lineSpacing = value; + this.current = value; - return this.updateText(); + return value; }, /** - * Set the text padding. - * - * 'left' can be an object. - * - * If only 'left' and 'top' are given they are treated as 'x' and 'y'. + * 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.Text#setPadding + * @method Phaser.GameObjects.Particles.EmitterOp#steppedEmit * @since 3.0.0 * - * @param {(number|Phaser.Types.GameObjects.Text.TextPadding)} left - The left padding value, or a padding config object. - * @param {number} [top] - The top padding value. - * @param {number} [right] - The right padding value. - * @param {number} [bottom] - The bottom padding value. - * - * @return {this} This Text object. + * @return {number} The new value of the property. */ - setPadding: function (left, top, right, bottom) + steppedEmit: function () { - if (typeof left === 'object') - { - var config = left; + var current = this.counter; - // If they specify x and/or y this applies to all - var x = GetValue(config, 'x', null); + var next = current; - if (x !== null) - { - left = x; - right = x; - } - else - { - left = GetValue(config, 'left', 0); - right = GetValue(config, 'right', left); - } + var step = (this.end - this.start) / this.steps; - var y = GetValue(config, 'y', null); + if (this.yoyo) + { + var over; - if (y !== null) + if (this.direction === 0) { - top = y; - bottom = y; + // Add step to the current value + next += step; + + if (next >= this.end) + { + over = next - this.end; + + next = this.end - over; + + this.direction = 1; + } } else { - top = GetValue(config, 'top', 0); - bottom = GetValue(config, 'bottom', top); + // Down + next -= step; + + if (next <= this.start) + { + over = this.start - next; + + next = this.start + over; + + this.direction = 0; + } } + + this.counter = next; } else { - if (left === undefined) { left = 0; } - if (top === undefined) { top = left; } - if (right === undefined) { right = left; } - if (bottom === undefined) { bottom = top; } + this.counter = Wrap(next + step, this.start, this.end); } - this.padding.left = left; - this.padding.top = top; - this.padding.right = right; - this.padding.bottom = bottom; + this.current = current; - return this.updateText(); + return current; }, /** - * Set the maximum number of lines to draw. + * An `onEmit` callback for an eased property. * - * @method Phaser.GameObjects.Text#setMaxLines + * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate}. + * + * @method Phaser.GameObjects.Particles.EmitterOp#easedValueEmit * @since 3.0.0 * - * @param {number} [max=0] - The maximum number of lines to draw. + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. * - * @return {this} This Text object. + * @return {number} {@link Phaser.GameObjects.Particles.EmitterOp#start}, as the new value of the property. */ - setMaxLines: function (max) + easedValueEmit: function (particle, key) { - return this.style.setMaxLines(max); + if (particle && particle.data[key]) + { + var data = particle.data[key]; + + data.min = this.start; + data.max = this.end; + } + + this.current = this.start; + + return this.start; }, /** - * Update the displayed text. + * 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.Text#updateText + * @method Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate * @since 3.0.0 * - * @return {this} This Text object. + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle. + * @param {string} key - The name of the property. + * @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + * + * @return {number} The new value of the property. */ - updateText: function () + easeValueUpdate: function (particle, key, t) { - var canvas = this.canvas; - var context = this.context; - var style = this.style; - var resolution = style.resolution; - var size = style.metrics; - - style.syncFont(canvas, context); + var data = particle.data[key]; - var outputText = this._text; + var current; + var v = this.ease(t); - if (style.wordWrapWidth || style.wordWrapCallback) + if (this.interpolation) { - outputText = this.runWordWrap(this._text); + current = this.interpolation(this.start, v); + } + else + { + current = (data.max - data.min) * v + data.min; } - // Split text into lines - var lines = outputText.split(this.splitRegExp); - - var textSize = GetTextSize(this, size, lines); + this.current = current; - var padding = this.padding; + return current; + }, - var textWidth; + /** + * Destroys this EmitterOp instance and all of its references. + * + * Called automatically when the ParticleEmitter that owns this + * EmitterOp is destroyed. + * + * @method Phaser.GameObjects.Particles.EmitterOp#destroy + * @since 3.60.0 + */ + destroy: function () + { + this.propertyValue = null; + this.defaultValue = null; + this.ease = null; + this.interpolation = null; + this._onEmit = null; + this._onUpdate = null; + } +}); - if (style.fixedWidth === 0) - { - this.width = textSize.width + padding.left + padding.right; +module.exports = EmitterOp; - textWidth = textSize.width; - } - else - { - this.width = style.fixedWidth; - textWidth = this.width - padding.left - padding.right; +/***/ }), - if (textWidth < textSize.width) - { - textWidth = textSize.width; - } - } +/***/ 87811: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (style.fixedHeight === 0) - { - this.height = textSize.height + padding.top + padding.bottom; - } - else - { - this.height = style.fixedHeight; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var w = this.width; - var h = this.height; +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var ParticleProcessor = __webpack_require__(30891); - this.updateDisplayOrigin(); +/** + * @classdesc + * The Gravity Well Particle Processor applies a force on the particles to draw + * them towards, or repel them 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 + * @extends Phaser.GameObjects.Particles.ParticleProcessor + * @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({ - w *= resolution; - h *= resolution; + Extends: ParticleProcessor, - w = Math.max(w, 1); - h = Math.max(h, 1); + initialize: - if (canvas.width !== w || canvas.height !== h) + function GravityWell (x, y, power, epsilon, gravity) + { + if (typeof x === 'object') { - canvas.width = w; - canvas.height = h; - - this.frame.setSize(w, h); + var config = x; - // Because resizing the canvas resets the context - style.syncFont(canvas, context); + 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 { - context.clearRect(0, 0, w, h); + 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; } } - context.save(); - - context.scale(resolution, resolution); - - if (style.backgroundColor) - { - context.fillStyle = style.backgroundColor; - context.fillRect(0, 0, w, h); - } + ParticleProcessor.call(this, x, y, true); - style.syncStyle(canvas, context); + /** + * Internal gravity value. + * + * @name Phaser.GameObjects.Particles.GravityWell#_gravity + * @type {number} + * @private + * @since 3.0.0 + */ + this._gravity = gravity; - context.textBaseline = 'alphabetic'; + /** + * Internal power value. + * + * @name Phaser.GameObjects.Particles.GravityWell#_power + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._power = power * gravity; - // Apply padding - context.translate(padding.left, padding.top); + /** + * Internal epsilon value. + * + * @name Phaser.GameObjects.Particles.GravityWell#_epsilon + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._epsilon = epsilon * epsilon; + }, - var linePositionX; - var linePositionY; + /** + * 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; - // Draw text line by line - for (var i = 0; i < textSize.lines; i++) + if (dSq === 0) { - linePositionX = style.strokeThickness / 2; - linePositionY = (style.strokeThickness / 2 + i * textSize.lineHeight) + size.ascent; - - if (i > 0) - { - linePositionY += (textSize.lineSpacing * i); - } - - if (style.rtl) - { - linePositionX = w - linePositionX; - } - else if (style.align === 'right') - { - linePositionX += textWidth - textSize.lineWidths[i]; - } - else if (style.align === 'center') - { - linePositionX += (textWidth - textSize.lineWidths[i]) / 2; - } - else if (style.align === 'justify') - { - // To justify text line its width must be no less than 85% of defined width - var minimumLengthToApplyJustification = 0.85; - - if (textSize.lineWidths[i] / textSize.width >= minimumLengthToApplyJustification) - { - var extraSpace = textSize.width - textSize.lineWidths[i]; - var spaceSize = context.measureText(' ').width; - var trimmedLine = lines[i].trim(); - var array = trimmedLine.split(' '); - - extraSpace += (lines[i].length - trimmedLine.length) * spaceSize; - - var extraSpaceCharacters = Math.floor(extraSpace / spaceSize); - var idx = 0; - - while (extraSpaceCharacters > 0) - { - array[idx] += ' '; - idx = (idx + 1) % (array.length - 1 || 1); - --extraSpaceCharacters; - } - - lines[i] = array.join(' '); - } - } - - if (this.autoRound) - { - linePositionX = Math.round(linePositionX); - linePositionY = Math.round(linePositionY); - } - - if (style.strokeThickness) - { - this.style.syncShadow(context, style.shadowStroke); - - context.strokeText(lines[i], linePositionX, linePositionY); - } - - if (style.color) - { - this.style.syncShadow(context, style.shadowFill); - - context.fillText(lines[i], linePositionX, linePositionY); - } + return; } - context.restore(); + var d = Math.sqrt(dSq); - if (this.renderer && this.renderer.gl) + if (dSq < this._epsilon) { - this.frame.source.glTexture = this.renderer.canvasToTexture(canvas, this.frame.source.glTexture, true); - - this.frame.glTexture = this.frame.source.glTexture; + dSq = this._epsilon; } - this.dirty = true; - - var input = this.input; - - if (input && !input.customHitArea) - { - input.hitArea.width = this.width; - input.hitArea.height = this.height; - } + var factor = ((this._power * delta) / (dSq * d)) * 100; - return this; + particle.velocityX += x * factor; + particle.velocityY += y * factor; }, /** - * Get the current text metrics. - * - * @method Phaser.GameObjects.Text#getTextMetrics - * @since 3.0.0 + * The minimum distance for which the gravity force is calculated. * - * @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics. - */ - getTextMetrics: function () - { - return this.style.getTextMetrics(); - }, - - /** - * The text string being rendered by this Text Game Object. + * Defaults to 100. * - * @name Phaser.GameObjects.Text#text - * @type {string} + * @name Phaser.GameObjects.Particles.GravityWell#epsilon + * @type {number} * @since 3.0.0 */ - text: { + epsilon: { get: function () { - return this._text; + return Math.sqrt(this._epsilon); }, set: function (value) { - this.setText(value); + this._epsilon = value * value; } }, /** - * Build a JSON representation of the Text object. + * The strength of the gravity force - larger numbers produce a stronger force. * - * @method Phaser.GameObjects.Text#toJSON - * @since 3.0.0 + * Defaults to 0. * - * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Text object. + * @name Phaser.GameObjects.Particles.GravityWell#power + * @type {number} + * @since 3.0.0 */ - toJSON: function () - { - var out = Components.ToJSON(this); - - // Extra Text data is added here + power: { - var data = { - autoRound: this.autoRound, - text: this._text, - style: this.style.toJSON(), - padding: { - left: this.padding.left, - right: this.padding.right, - top: this.padding.top, - bottom: this.padding.bottom - } - }; + get: function () + { + return this._power / this._gravity; + }, - out.data = data; + set: function (value) + { + this._power = value * this._gravity; + } - return out; }, /** - * Internal destroy handler, called as part of the destroy process. + * The gravitational force of this Gravity Well. * - * @method Phaser.GameObjects.Text#preDestroy - * @protected + * Defaults to 50. + * + * @name Phaser.GameObjects.Particles.GravityWell#gravity + * @type {number} * @since 3.0.0 */ - preDestroy: function () - { - if (this.style.rtl) + gravity: { + + get: function () { - RemoveFromDOM(this.canvas); - } + return this._gravity; + }, - CanvasPool.remove(this.canvas); + set: function (value) + { + var pwr = this.power; + this._gravity = value; + this.power = pwr; + } - this.texture.destroy(); } - /** - * The horizontal origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the left of the Game Object. - * - * @name Phaser.GameObjects.Text#originX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - - /** - * The vertical origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the top of the Game Object. - * - * @name Phaser.GameObjects.Text#originY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - }); -module.exports = Text; +module.exports = GravityWell; /***/ }), -/* 225 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 14909: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -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 GetPowerOfTwo = __webpack_require__(361); -var Smoothing = __webpack_require__(192); -var TileSpriteRender = __webpack_require__(1091); -var Vector2 = __webpack_require__(3); - -// bitmask flag for GameObject.renderMask -var _FLAG = 8; // 1000 +var AnimationState = __webpack_require__(16569); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var DegToRad = __webpack_require__(75606); +var Rectangle = __webpack_require__(74118); +var RotateAround = __webpack_require__(2386); +var Vector2 = __webpack_require__(93736); /** * @classdesc - * A TileSprite is a Sprite that has a repeating texture. - * - * The texture can be scrolled and scaled independently of the TileSprite itself. Textures will automatically wrap and - * are designed so that you can create game backdrops using seamless textures as a source. - * - * You shouldn't ever create a TileSprite any larger than your actual canvas size. If you want to create a large repeating background - * that scrolls across the whole map of your game, then you create a TileSprite that fits the canvas size and then use the `tilePosition` - * property to scroll the texture as the player moves. If you create a TileSprite that is thousands of pixels in size then it will - * consume huge amounts of memory and cause performance issues. Remember: use `tilePosition` to scroll your texture and `tileScale` to - * adjust the scale of the texture - don't resize the sprite itself or make it larger than it needs. + * A Particle is a simple object owned and controlled by a Particle Emitter. * - * An important note about Tile Sprites and NPOT textures: Internally, TileSprite textures use GL_REPEAT to provide - * seamless repeating of the textures. This, combined with the way in which the textures are handled in WebGL, means - * they need to be POT (power-of-two) sizes in order to wrap. If you provide a NPOT (non power-of-two) texture to a - * TileSprite it will generate a POT sized canvas and draw your texture to it, scaled up to the POT size. It's then - * scaled back down again during rendering to the original dimensions. While this works, in that it allows you to use - * any size texture for a Tile Sprite, it does mean that NPOT textures are going to appear anti-aliased when rendered, - * due to the interpolation that took place when it was resized into a POT texture. This is especially visible in - * pixel art graphics. If you notice it and it becomes an issue, the only way to avoid it is to ensure that you - * provide POT textures for Tile Sprites. + * It encapsulates all of the properties required to move and update according + * to the Emitters operations. * - * @class TileSprite - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects + * @class Particle + * @memberof Phaser.GameObjects.Particles * @constructor * @since 3.0.0 * - * @extends Phaser.GameObjects.Components.Alpha - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.ComputedSize - * @extends Phaser.GameObjects.Components.Crop - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Origin - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.ScrollFactor - * @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 {number} width - The width of the Game Object. If zero it will use the size of the texture frame. - * @param {number} height - The height of the Game Object. If zero it will use the size of the texture frame. - * @param {string} textureKey - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param {(string|number)} [frameKey] - An optional frame from the Texture this Game Object is rendering with. + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to which this Particle belongs. */ -var TileSprite = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.ComputedSize, - Components.Crop, - Components.Depth, - Components.Flip, - Components.GetBounds, - Components.Mask, - Components.Origin, - Components.Pipeline, - Components.ScrollFactor, - Components.Tint, - Components.Transform, - Components.Visible, - TileSpriteRender - ], +var Particle = new Class({ initialize: - function TileSprite (scene, x, y, width, height, textureKey, frameKey) + function Particle (emitter) { - var renderer = scene.sys.renderer; - - GameObject.call(this, scene, 'TileSprite'); - - var displayTexture = scene.sys.textures.get(textureKey); - var displayFrame = displayTexture.get(frameKey); - - if (!width || !height) - { - width = displayFrame.width; - height = displayFrame.height; - } - else - { - width = Math.floor(width); - height = Math.floor(height); - } - /** - * Internal tile position vector. + * The Emitter to which this Particle belongs. * - * @name Phaser.GameObjects.TileSprite#_tilePosition - * @type {Phaser.Math.Vector2} - * @private - * @since 3.12.0 + * A Particle can only belong to a single Emitter and is created, updated and destroyed by it. + * + * @name Phaser.GameObjects.Particles.Particle#emitter + * @type {Phaser.GameObjects.Particles.ParticleEmitter} + * @since 3.0.0 */ - this._tilePosition = new Vector2(); + this.emitter = emitter; /** - * Internal tile scale vector. + * The texture used by this Particle when it renders. * - * @name Phaser.GameObjects.TileSprite#_tileScale - * @type {Phaser.Math.Vector2} - * @private - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.Particle#texture + * @type {Phaser.Textures.Texture} + * @default null + * @since 3.60.0 */ - this._tileScale = new Vector2(1, 1); + this.texture = null; /** - * Whether the Tile Sprite has changed in some way, requiring an re-render of its tile texture. - * - * Such changes include the texture frame and scroll position of the Tile Sprite. + * The texture frame used by this Particle when it renders. * - * @name Phaser.GameObjects.TileSprite#dirty - * @type {boolean} - * @default false + * @name Phaser.GameObjects.Particles.Particle#frame + * @type {Phaser.Textures.Frame} + * @default null * @since 3.0.0 */ - this.dirty = false; + this.frame = null; /** - * The renderer in use by this Tile Sprite. + * The x coordinate of this Particle. * - * @name Phaser.GameObjects.TileSprite#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @name Phaser.GameObjects.Particles.Particle#x + * @type {number} + * @default 0 * @since 3.0.0 */ - this.renderer = renderer; + this.x = 0; /** - * The Canvas element that the TileSprite renders its fill pattern in to. - * Only used in Canvas mode. + * The y coordinate of this Particle. * - * @name Phaser.GameObjects.TileSprite#canvas - * @type {?HTMLCanvasElement} - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.Particle#y + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.canvas = CanvasPool.create(this, width, height); + this.y = 0; /** - * The Context of the Canvas element that the TileSprite renders its fill pattern in to. - * Only used in Canvas mode. + * The coordinates of this Particle in world space. * - * @name Phaser.GameObjects.TileSprite#context - * @type {CanvasRenderingContext2D} - * @since 3.12.0 - */ - this.context = this.canvas.getContext('2d'); - - /** - * The Texture the TileSprite is using as its fill pattern. + * Updated as part of `computeVelocity`. * - * @name Phaser.GameObjects.TileSprite#displayTexture - * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} - * @private - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.Particle#worldPosition + * @type {Phaser.Math.Vector2} + * @since 3.60.0 */ - this.displayTexture = displayTexture; + this.worldPosition = new Vector2(); /** - * The Frame the TileSprite is using as its fill pattern. + * The x velocity of this Particle. * - * @name Phaser.GameObjects.TileSprite#displayFrame - * @type {Phaser.Textures.Frame} - * @private - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.Particle#velocityX + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.displayFrame = displayFrame; + this.velocityX = 0; /** - * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. + * The y velocity of this Particle. * - * @name Phaser.GameObjects.TileSprite#_crop - * @type {object} - * @private - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.Particle#velocityY + * @type {number} + * @default 0 + * @since 3.0.0 */ - this._crop = this.resetCropObject(); + this.velocityY = 0; /** - * The Texture this Game Object is using to render with. + * The x acceleration of this Particle. * - * @name Phaser.GameObjects.TileSprite#texture - * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} + * @name Phaser.GameObjects.Particles.Particle#accelerationX + * @type {number} + * @default 0 * @since 3.0.0 */ - this.texture = scene.sys.textures.addCanvas(null, this.canvas, true); + this.accelerationX = 0; /** - * The Texture Frame this Game Object is using to render with. + * The y acceleration of this Particle. * - * @name Phaser.GameObjects.TileSprite#frame - * @type {Phaser.Textures.Frame} + * @name Phaser.GameObjects.Particles.Particle#accelerationY + * @type {number} + * @default 0 * @since 3.0.0 */ - this.frame = this.texture.get(); + this.accelerationY = 0; /** - * The next power of two value from the width of the Fill Pattern frame. + * The maximum horizontal velocity this Particle can travel at. * - * @name Phaser.GameObjects.TileSprite#potWidth + * @name Phaser.GameObjects.Particles.Particle#maxVelocityX * @type {number} + * @default 10000 * @since 3.0.0 */ - this.potWidth = GetPowerOfTwo(displayFrame.width); + this.maxVelocityX = 10000; /** - * The next power of two value from the height of the Fill Pattern frame. + * The maximum vertical velocity this Particle can travel at. * - * @name Phaser.GameObjects.TileSprite#potHeight + * @name Phaser.GameObjects.Particles.Particle#maxVelocityY * @type {number} + * @default 10000 * @since 3.0.0 */ - this.potHeight = GetPowerOfTwo(displayFrame.height); + this.maxVelocityY = 10000; /** - * The Canvas that the TileSprites texture is rendered to. - * This is used to create a WebGL texture from. + * The bounciness, or restitution, of this Particle. * - * @name Phaser.GameObjects.TileSprite#fillCanvas - * @type {HTMLCanvasElement} - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.Particle#bounce + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.fillCanvas = CanvasPool.create2D(this, this.potWidth, this.potHeight); + this.bounce = 0; /** - * The Canvas Context used to render the TileSprites texture. + * The horizontal scale of this Particle. * - * @name Phaser.GameObjects.TileSprite#fillContext - * @type {CanvasRenderingContext2D} - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.Particle#scaleX + * @type {number} + * @default 1 + * @since 3.0.0 */ - this.fillContext = this.fillCanvas.getContext('2d'); + this.scaleX = 1; /** - * The texture that the Tile Sprite is rendered to, which is then rendered to a Scene. - * In WebGL this is a WebGLTexture. In Canvas it's a Canvas Fill Pattern. + * The vertical scale of this Particle. * - * @name Phaser.GameObjects.TileSprite#fillPattern - * @type {?(WebGLTexture|CanvasPattern)} - * @since 3.12.0 + * @name Phaser.GameObjects.Particles.Particle#scaleY + * @type {number} + * @default 1 + * @since 3.0.0 */ - this.fillPattern = null; + this.scaleY = 1; - this.setPosition(x, y); - this.setSize(width, height); - this.setFrame(frameKey); - this.setOriginFromFrame(); - this.initPipeline(); + /** + * The alpha value of this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#alpha + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.alpha = 1; - scene.sys.game.events.on(GameEvents.CONTEXT_RESTORED, function (renderer) - { - if (!renderer) - { - return; - } - - var gl = renderer.gl; + /** + * The angle of this Particle in degrees. + * + * @name Phaser.GameObjects.Particles.Particle#angle + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.angle = 0; - this.dirty = true; - this.fillPattern = null; - this.fillPattern = renderer.createTexture2D(0, gl.LINEAR, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.RGBA, this.fillCanvas, this.potWidth, this.potHeight); + /** + * The angle of this Particle in radians. + * + * @name Phaser.GameObjects.Particles.Particle#rotation + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.rotation = 0; - }, this); + /** + * 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 hold applied to this Particle before it expires, in ms. + * + * @name Phaser.GameObjects.Particles.Particle#holdCurrent + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.holdCurrent = 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 }, + alpha: { min: 1, max: 1 }, + rotate: { min: 0, max: 0 }, + scaleX: { min: 1, max: 1 }, + scaleY: { min: 1, max: 1 }, + x: { min: 0, max: 0 }, + y: { min: 0, max: 0 }, + accelerationX: { min: 0, max: 0 }, + accelerationY: { min: 0, max: 0 }, + maxVelocityX: { min: 0, max: 0 }, + maxVelocityY: { min: 0, max: 0 }, + moveToX: { min: 0, max: 0 }, + moveToY: { min: 0, max: 0 }, + bounce: { min: 0, max: 0 } + }; + + /** + * Interal private value. + * + * @name Phaser.GameObjects.Particles.Particle#isCropped + * @type {boolean} + * @private + * @readonly + * @since 3.60.0 + */ + this.isCropped = false; + + /** + * A reference to the Scene to which this Game Object belongs. + * + * Game Objects can only belong to one Scene. + * + * You should consider this property as being read-only. You cannot move a + * Game Object to another Scene by simply changing it. + * + * @name Phaser.GameObjects.Particles.Particle#scene + * @type {Phaser.Scene} + * @since 3.60.0 + */ + this.scene = emitter.scene; + + /** + * The Animation State component of this Particle. + * + * This component provides features to apply animations to this Particle. + * It is responsible for playing, loading, queuing animations for later playback, + * mixing between animations and setting the current animation frame to this Particle. + * + * @name Phaser.GameObjects.Particles.Particle#anims + * @type {Phaser.Animations.AnimationState} + * @since 3.60.0 + */ + this.anims = new AnimationState(this); + + /** + * A rectangle that holds the bounds of this Particle after a call to + * the `Particle.getBounds` method has been made. + * + * @name Phaser.GameObjects.Particles.Particle#bounds + * @type {Phaser.Geom.Rectangle} + * @since 3.60.0 + */ + this.bounds = new Rectangle(); }, /** - * Sets the texture and frame this Game Object will use to render with. + * The Event Emitter proxy. * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * Passes on all parameters to the `ParticleEmitter` to emit directly. * - * @method Phaser.GameObjects.TileSprite#setTexture - * @since 3.0.0 + * @method Phaser.GameObjects.Particles.Particle#emit + * @since 3.60.0 * - * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. - * @param {(string|number)} [frame] - The name or index of the frame within the Texture. + * @param {(string|Symbol)} event - The event name. + * @param {any} [a1] - Optional argument 1. + * @param {any} [a2] - Optional argument 2. + * @param {any} [a3] - Optional argument 3. + * @param {any} [a4] - Optional argument 4. + * @param {any} [a5] - Optional argument 5. * - * @return {this} This Game Object instance. + * @return {boolean} `true` if the event had listeners, else `false`. */ - setTexture: function (key, frame) + emit: function (event, a1, a2, a3, a4, a5) { - this.displayTexture = this.scene.sys.textures.get(key); - - return this.setFrame(frame); + return this.emitter.emit(event, a1, a2, a3, a4, a5); }, /** - * Sets the frame this Game Object will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. + * Checks to see if this Particle is alive and updating. * - * @method Phaser.GameObjects.TileSprite#setFrame + * @method Phaser.GameObjects.Particles.Particle#isAlive * @since 3.0.0 * - * @param {(string|number)} frame - The name or index of the frame within the Texture. - * - * @return {this} This Game Object instance. + * @return {boolean} `true` if this Particle is alive and updating, otherwise `false`. */ - setFrame: function (frame) + isAlive: function () { - var newFrame = this.displayTexture.get(frame); - - this.potWidth = GetPowerOfTwo(newFrame.width); - this.potHeight = GetPowerOfTwo(newFrame.height); - - // So updateCanvas is triggered - this.canvas.width = 0; - - if (!newFrame.cutWidth || !newFrame.cutHeight) - { - this.renderFlags &= ~_FLAG; - } - else - { - this.renderFlags |= _FLAG; - } - - this.displayFrame = newFrame; - - this.dirty = true; - - this.updateTileTexture(); - - return this; + return (this.lifeCurrent > 0); }, /** - * Sets {@link Phaser.GameObjects.TileSprite#tilePositionX} and {@link Phaser.GameObjects.TileSprite#tilePositionY}. - * - * @method Phaser.GameObjects.TileSprite#setTilePosition - * @since 3.3.0 + * Kills this particle. This sets the `lifeCurrent` value to 0, which forces + * the Particle to be removed the next time its parent Emitter runs an update. * - * @param {number} [x] - The x position of this sprite's tiling texture. - * @param {number} [y] - The y position of this sprite's tiling texture. - * - * @return {this} This Tile Sprite instance. + * @method Phaser.GameObjects.Particles.Particle#kill + * @since 3.60.0 */ - setTilePosition: function (x, y) + kill: function () { - if (x !== undefined) - { - this.tilePositionX = x; - } - - if (y !== undefined) - { - this.tilePositionY = y; - } - - return this; + this.lifeCurrent = 0; }, /** - * Sets {@link Phaser.GameObjects.TileSprite#tileScaleX} and {@link Phaser.GameObjects.TileSprite#tileScaleY}. + * Sets the position of this particle to the given x/y coordinates. * - * @method Phaser.GameObjects.TileSprite#setTileScale - * @since 3.12.0 + * If the parameters are left undefined, it resets the particle back to 0x0. * - * @param {number} [x] - The horizontal scale of the tiling texture. If not given it will use the current `tileScaleX` value. - * @param {number} [y=x] - The vertical scale of the tiling texture. If not given it will use the `x` value. + * @method Phaser.GameObjects.Particles.Particle#setPosition + * @since 3.60.0 * - * @return {this} This Tile Sprite instance. + * @param {number} [x=0] - The x coordinate to set this Particle to. + * @param {number} [y=0] - The y coordinate to set this Particle to. */ - setTileScale: function (x, y) + setPosition: function (x, y) { - if (x === undefined) { x = this.tileScaleX; } - if (y === undefined) { y = x; } - - this.tileScaleX = x; - this.tileScaleY = y; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } - return this; + this.x = x; + this.y = y; }, /** - * Render the tile texture if it is dirty, or if the frame has changed. + * Starts this Particle from the given coordinates. * - * @method Phaser.GameObjects.TileSprite#updateTileTexture - * @private + * @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. + * + * @return {boolean} `true` if the Particle is alive, or `false` if it was spawned inside a DeathZone. */ - updateTileTexture: function () + fire: function (x, y) { - if (!this.dirty || !this.renderer) + var emitter = this.emitter; + var ops = emitter.ops; + + var anim = emitter.getAnim(); + + if (anim) { - return; + this.anims.play(anim); + } + else + { + this.frame = emitter.getFrame(); + this.texture = this.frame.texture; } - // Draw the displayTexture to our fillCanvas + if (!this.frame) + { + throw new Error('Particle has no texture frame'); + } - var frame = this.displayFrame; + // Updates particle.x and particle.y during this call + emitter.getEmitZone(this); - if (frame.source.isRenderTexture || frame.source.isGLTexture) + if (x === undefined) { - console.warn('TileSprites can only use Image or Canvas based textures'); + this.x += ops.x.onEmit(this, 'x'); + } + else if (ops.x.steps > 0) + { + // EmitterOp is stepped but x was forced (follower?) so use it + this.x += x + ops.x.onEmit(this, 'x'); + } + else + { + this.x += x; + } - this.dirty = false; + if (y === undefined) + { + this.y += ops.y.onEmit(this, 'y'); + } + else if (ops.y.steps > 0) + { + // EmitterOp is stepped but y was forced (follower?) so use it + this.y += y + ops.y.onEmit(this, 'y'); + } + else + { + this.y += y; + } - return; + this.life = ops.lifespan.onEmit(this, 'lifespan'); + this.lifeCurrent = this.life; + this.lifeT = 0; + + this.delayCurrent = ops.delay.onEmit(this, 'delay'); + this.holdCurrent = ops.hold.onEmit(this, 'hold'); + + this.scaleX = ops.scaleX.onEmit(this, 'scaleX'); + this.scaleY = (ops.scaleY.active) ? ops.scaleY.onEmit(this, 'scaleY') : this.scaleX; + + this.angle = ops.rotate.onEmit(this, 'rotate'); + + this.rotation = DegToRad(this.angle); + + emitter.worldMatrix.transformPoint(this.x, this.y, this.worldPosition); + + // Check we didn't spawn in the middle of a DeathZone + if (this.delayCurrent === 0 && emitter.getDeathZone(this)) + { + this.lifeCurrent = 0; + + return false; } - var ctx = this.fillContext; - var canvas = this.fillCanvas; + var sx = ops.speedX.onEmit(this, 'speedX'); + var sy = (ops.speedY.active) ? ops.speedY.onEmit(this, 'speedY') : sx; - var fw = this.potWidth; - var fh = this.potHeight; + if (emitter.radial) + { + var rad = DegToRad(ops.angle.onEmit(this, 'angle')); - if (!this.renderer || !this.renderer.gl) + this.velocityX = Math.cos(rad) * Math.abs(sx); + this.velocityY = Math.sin(rad) * Math.abs(sy); + } + else if (emitter.moveTo) { - fw = frame.cutWidth; - fh = frame.cutHeight; + var mx = ops.moveToX.onEmit(this, 'moveToX'); + var my = ops.moveToY.onEmit(this, 'moveToY'); + var lifeS = this.life / 1000; + + this.velocityX = (mx - this.x) / lifeS; + this.velocityY = (my - this.y) / lifeS; + } + else + { + this.velocityX = sx; + this.velocityY = sy; } - ctx.clearRect(0, 0, fw, fh); + if (emitter.acceleration) + { + this.accelerationX = ops.accelerationX.onEmit(this, 'accelerationX'); + this.accelerationY = ops.accelerationY.onEmit(this, 'accelerationY'); + } - canvas.width = fw; - canvas.height = fh; + this.maxVelocityX = ops.maxVelocityX.onEmit(this, 'maxVelocityX'); + this.maxVelocityY = ops.maxVelocityY.onEmit(this, 'maxVelocityY'); - ctx.drawImage( - frame.source.image, - frame.cutX, frame.cutY, - frame.cutWidth, frame.cutHeight, - 0, 0, - fw, fh - ); + this.bounce = ops.bounce.onEmit(this, 'bounce'); - if (this.renderer && this.renderer.gl) + this.alpha = ops.alpha.onEmit(this, 'alpha'); + + if (ops.color.active) { - this.fillPattern = this.renderer.canvasToTexture(canvas, this.fillPattern); + this.tint = ops.color.onEmit(this, 'tint'); } else { - this.fillPattern = ctx.createPattern(canvas, 'repeat'); + this.tint = ops.tint.onEmit(this, 'tint'); } - this.updateCanvas(); - - this.dirty = false; + return true; }, /** - * Draw the fill pattern to the internal canvas. + * The main update method for this Particle. * - * @method Phaser.GameObjects.TileSprite#updateCanvas - * @private - * @since 3.12.0 + * 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 {Phaser.GameObjects.Particles.ParticleProcessor[]} processors - An array of all active Particle Processors. + * + * @return {boolean} Returns `true` if this Particle has now expired and should be removed, otherwise `false` if still active. */ - updateCanvas: function () + update: function (delta, step, processors) { - var canvas = this.canvas; - - if (canvas.width !== this.width || canvas.height !== this.height) + if (this.lifeCurrent <= 0) { - canvas.width = this.width; - canvas.height = this.height; - - this.frame.setSize(this.width, this.height); - this.updateDisplayOrigin(); + // Particle is dead via `Particle.kill` method, or being held + if (this.holdCurrent > 0) + { + this.holdCurrent -= delta; - this.dirty = true; + return (this.holdCurrent <= 0); + } + else + { + return true; + } } - if (!this.dirty || this.renderer && this.renderer.gl) + if (this.delayCurrent > 0) { - this.dirty = false; - return; + this.delayCurrent -= delta; + + return false; } - var ctx = this.context; + this.anims.update(0, delta); - if (!this.scene.sys.game.config.antialias) + var emitter = this.emitter; + var ops = emitter.ops; + + // How far along in life is this particle? (t = 0 to 1) + var t = 1 - (this.lifeCurrent / this.life); + + this.lifeT = t; + + this.x = ops.x.onUpdate(this, 'x', t, this.x); + this.y = ops.y.onUpdate(this, 'y', t, this.y); + + if (emitter.moveTo) { - Smoothing.disable(ctx); + var mx = ops.moveToX.onUpdate(this, 'moveToX', t, emitter.moveToX); + var my = ops.moveToY.onUpdate(this, 'moveToY', t, emitter.moveToY); + var lifeS = this.lifeCurrent / 1000; + + this.velocityX = (mx - this.x) / lifeS; + this.velocityY = (my - this.y) / lifeS; } - var scaleX = this._tileScale.x; - var scaleY = this._tileScale.y; + this.computeVelocity(emitter, delta, step, processors, t); - var positionX = this._tilePosition.x; - var positionY = this._tilePosition.y; + this.scaleX = ops.scaleX.onUpdate(this, 'scaleX', t, this.scaleX); + this.scaleY = this.scaleX; - ctx.clearRect(0, 0, this.width, this.height); + if (ops.scaleY.active) + { + this.scaleY = ops.scaleY.onUpdate(this, 'scaleY', t, this.scaleY); + } - ctx.save(); + this.angle = ops.rotate.onUpdate(this, 'rotate', t, this.angle); - ctx.scale(scaleX, scaleY); + this.rotation = DegToRad(this.angle); - ctx.translate(-positionX, -positionY); + if (emitter.getDeathZone(this)) + { + this.lifeCurrent = 0; - ctx.fillStyle = this.fillPattern; + // No need to go any further, particle has been killed + return true; + } - ctx.fillRect(positionX, positionY, this.width / scaleX, this.height / scaleY); + this.alpha = ops.alpha.onUpdate(this, 'alpha', t, this.alpha); - ctx.restore(); + if (ops.color.active) + { + this.tint = ops.color.onUpdate(this, 'color', t, this.tint); + } + else + { + this.tint = ops.tint.onUpdate(this, 'tint', t, this.tint); + } - this.dirty = false; + this.lifeCurrent -= delta; + + return (this.lifeCurrent <= 0 && this.holdCurrent <= 0); }, /** - * Internal destroy handler, called as part of the destroy process. + * An internal method that calculates the velocity of the Particle and + * its world position. It also runs it against any active Processors + * that are set on the Emitter. * - * @method Phaser.GameObjects.TileSprite#preDestroy - * @protected - * @since 3.9.0 + * @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 {Phaser.GameObjects.Particles.ParticleProcessor[]} processors - An array of all active Particle Processors. + * @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death). */ - preDestroy: function () + computeVelocity: function (emitter, delta, step, processors, t) { - if (this.renderer && this.renderer.gl) - { - this.renderer.deleteTexture(this.fillPattern); - } + var ops = emitter.ops; - CanvasPool.remove(this.canvas); - CanvasPool.remove(this.fillCanvas); + var vx = this.velocityX; + var vy = this.velocityY; - this.fillPattern = null; - this.fillContext = null; - this.fillCanvas = null; + var ax = ops.accelerationX.onUpdate(this, 'accelerationX', t, this.accelerationX); + var ay = ops.accelerationY.onUpdate(this, 'accelerationY', t, this.accelerationY); - this.displayTexture = null; - this.displayFrame = null; + var mx = ops.maxVelocityX.onUpdate(this, 'maxVelocityX', t, this.maxVelocityX); + var my = ops.maxVelocityY.onUpdate(this, 'maxVelocityY', t, this.maxVelocityY); - this.texture.destroy(); + this.bounce = ops.bounce.onUpdate(this, 'bounce', t, this.bounce); - this.renderer = null; - }, + vx += (emitter.gravityX * step) + (ax * step); + vy += (emitter.gravityY * step) + (ay * step); - /** - * The horizontal scroll position of the Tile Sprite. - * - * @name Phaser.GameObjects.TileSprite#tilePositionX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - tilePositionX: { + vx = Clamp(vx, -mx, mx); + vy = Clamp(vy, -my, my); - get: function () - { - return this._tilePosition.x; - }, + this.velocityX = vx; + this.velocityY = vy; - set: function (value) + // Integrate back in to the position + this.x += vx * step; + this.y += vy * step; + + emitter.worldMatrix.transformPoint(this.x, this.y, this.worldPosition); + + // Apply any additional processors (these can update velocity and/or position) + for (var i = 0; i < processors.length; i++) { - this._tilePosition.x = value; - this.dirty = true; + var processor = processors[i]; + + if (processor.active) + { + processor.update(this, delta, step, t); + } } + }, + /** + * This is a NOOP method and does nothing when called. + * + * @method Phaser.GameObjects.Particles.Particle#setSizeToFrame + * @since 3.60.0 + */ + setSizeToFrame: function () + { + // NOOP }, /** - * The vertical scroll position of the Tile Sprite. + * Gets the bounds of this particle as a Geometry Rectangle, factoring in any + * transforms of the parent emitter and anything else above it in the display list. * - * @name Phaser.GameObjects.TileSprite#tilePositionY - * @type {number} - * @default 0 - * @since 3.0.0 + * Once calculated the bounds can be accessed via the `Particle.bounds` property. + * + * @method Phaser.GameObjects.Particles.Particle#getBounds + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Components.TransformMatrix} [matrix] - Optional transform matrix to apply to this particle. + * + * @return {Phaser.Geom.Rectangle} A Rectangle containing the transformed bounds of this particle. */ - tilePositionY: { + getBounds: function (matrix) + { + if (matrix === undefined) { matrix = this.emitter.getWorldTransformMatrix(); } - get: function () - { - return this._tilePosition.y; - }, + var sx = Math.abs(matrix.scaleX) * this.scaleX; + var sy = Math.abs(matrix.scaleY) * this.scaleY; - set: function (value) + var x = this.x; + var y = this.y; + var rotation = this.rotation; + var width = (this.frame.width * sx) / 2; + var height = (this.frame.height * sy) / 2; + + var bounds = this.bounds; + + var topLeft = new Vector2(x - width, y - height); + var topRight = new Vector2(x + width, y - height); + var bottomLeft = new Vector2(x - width, y + height); + var bottomRight = new Vector2(x + width, y + height); + + if (rotation !== 0) { - this._tilePosition.y = value; - this.dirty = true; + RotateAround(topLeft, x, y, rotation); + RotateAround(topRight, x, y, rotation); + RotateAround(bottomLeft, x, y, rotation); + RotateAround(bottomRight, x, y, rotation); } + matrix.transformPoint(topLeft.x, topLeft.y, topLeft); + matrix.transformPoint(topRight.x, topRight.y, topRight); + matrix.transformPoint(bottomLeft.x, bottomLeft.y, bottomLeft); + matrix.transformPoint(bottomRight.x, bottomRight.y, bottomRight); + + bounds.x = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x); + bounds.y = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y); + bounds.width = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x) - bounds.x; + bounds.height = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y) - bounds.y; + + return bounds; }, /** - * The horizontal scale of the Tile Sprite texture. + * Destroys this Particle. * - * @name Phaser.GameObjects.TileSprite#tileScaleX - * @type {number} - * @default 1 - * @since 3.11.0 + * @method Phaser.GameObjects.Particles.Particle#destroy + * @since 3.60.0 */ - tileScaleX: { + destroy: function () + { + this.anims.destroy(); - get: function () - { - return this._tileScale.x; - }, + this.anims = null; + this.emitter = null; + this.texture = null; + this.frame = null; + this.scene = null; + } - set: function (value) - { - this._tileScale.x = value; - this.dirty = true; - } +}); + +module.exports = Particle; + + +/***/ }), + +/***/ 73106: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var ParticleProcessor = __webpack_require__(30891); +var Rectangle = __webpack_require__(74118); + +/** + * @classdesc + * The Particle Bounds Processor. + * + * Defines a rectangular region, in world space, within which particle movement + * is restrained. + * + * Use the properties `collideLeft`, `collideRight`, `collideTop` and + * `collideBottom` to control if a particle will rebound off the sides + * of this boundary, or not. + * + * This happens when the particles worldPosition x/y coordinate hits the boundary. + * + * The strength of the rebound is determined by the `Particle.bounce` property. + * + * @class ParticleBounds + * @extends Phaser.GameObjects.Particles.ParticleProcessor + * @memberof Phaser.GameObjects.Particles + * @constructor + * @since 3.60.0 + * + * @param {number} x - The x position (top-left) of the bounds, in world space. + * @param {number} y - The y position (top-left) of the bounds, in world space. + * @param {number} width - The width of the bounds. + * @param {number} height - The height of the bounds. + * @param {boolean} [collideLeft=true] - Whether particles interact with the left edge of the bounds. + * @param {boolean} [collideRight=true] - Whether particles interact with the right edge of the bounds. + * @param {boolean} [collideTop=true] - Whether particles interact with the top edge of the bounds. + * @param {boolean} [collideBottom=true] - Whether particles interact with the bottom edge of the bounds. + */ +var ParticleBounds = new Class({ + + Extends: ParticleProcessor, + + initialize: + + function ParticleBounds (x, y, width, height, collideLeft, collideRight, collideTop, collideBottom) + { + if (collideLeft === undefined) { collideLeft = true; } + if (collideRight === undefined) { collideRight = true; } + if (collideTop === undefined) { collideTop = true; } + if (collideBottom === undefined) { collideBottom = true; } + + ParticleProcessor.call(this, x, y, true); + + /** + * A rectangular boundary constraining particle movement. Use the Emitter properties `collideLeft`, + * `collideRight`, `collideTop` and `collideBottom` to control if a particle will rebound off + * the sides of this boundary, or not. This happens when the particles x/y coordinate hits + * the boundary. + * + * @name Phaser.GameObjects.Particles.ParticleBounds#bounds + * @type {Phaser.Geom.Rectangle} + * @since 3.60.0 + */ + this.bounds = new Rectangle(x, y, width, height); + + /** + * Whether particles interact with the left edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleBounds#collideLeft + * @type {boolean} + * @default true + * @since 3.60.0 + */ + this.collideLeft = collideLeft; + + /** + * Whether particles interact with the right edge of the emitter {@link Phaser.GameObjects.Particles.ParticleBounds#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleBounds#collideRight + * @type {boolean} + * @default true + * @since 3.60.0 + */ + this.collideRight = collideRight; + + /** + * Whether particles interact with the top edge of the emitter {@link Phaser.GameObjects.Particles.ParticleBounds#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleBounds#collideTop + * @type {boolean} + * @default true + * @since 3.60.0 + */ + this.collideTop = collideTop; + /** + * Whether particles interact with the bottom edge of the emitter {@link Phaser.GameObjects.Particles.ParticleBounds#bounds}. + * + * @name Phaser.GameObjects.Particles.ParticleBounds#collideBottom + * @type {boolean} + * @default true + * @since 3.60.0 + */ + this.collideBottom = collideBottom; }, /** - * The vertical scale of the Tile Sprite texture. + * Takes a Particle and updates it against the bounds. * - * @name Phaser.GameObjects.TileSprite#tileScaleY - * @type {number} - * @default 1 - * @since 3.11.0 + * @method Phaser.GameObjects.Particles.ParticleBounds#update + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to update. */ - tileScaleY: { + update: function (particle) + { + var bounds = this.bounds; + var bounce = -particle.bounce; + var pos = particle.worldPosition; - get: function () + if (pos.x < bounds.x && this.collideLeft) { - return this._tileScale.y; - }, - - set: function (value) + particle.x += bounds.x - pos.x; + particle.velocityX *= bounce; + } + else if (pos.x > bounds.right && this.collideRight) { - this._tileScale.y = value; - this.dirty = true; + particle.x -= pos.x - bounds.right; + particle.velocityX *= bounce; } + if (pos.y < bounds.y && this.collideTop) + { + particle.y += bounds.y - pos.y; + particle.velocityY *= bounce; + } + else if (pos.y > bounds.bottom && this.collideBottom) + { + particle.y -= pos.y - bounds.bottom; + particle.velocityY *= bounce; + } } }); -module.exports = TileSprite; +module.exports = ParticleBounds; /***/ }), -/* 226 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 9216: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Clamp = __webpack_require__(18); -var Components = __webpack_require__(11); -var Events = __webpack_require__(75); -var GameEvents = __webpack_require__(22); -var InputEvents = __webpack_require__(51); -var GameObject = __webpack_require__(15); -var SoundEvents = __webpack_require__(70); -var UUID = __webpack_require__(222); -var VideoRender = __webpack_require__(1094); -var MATH_CONST = __webpack_require__(14); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var ComponentsToJSON = __webpack_require__(48129); +var CopyFrom = __webpack_require__(29538); +var DeathZone = __webpack_require__(69361); +var EdgeZone = __webpack_require__(54213); +var EmitterColorOp = __webpack_require__(19737); +var EmitterOp = __webpack_require__(93025); +var Events = __webpack_require__(40629); +var GameObject = __webpack_require__(89980); +var GetFastValue = __webpack_require__(72632); +var GetRandom = __webpack_require__(72861); +var GravityWell = __webpack_require__(87811); +var HasAny = __webpack_require__(53523); +var HasValue = __webpack_require__(19256); +var Inflate = __webpack_require__(7782); +var List = __webpack_require__(71207); +var MergeRect = __webpack_require__(14655); +var Particle = __webpack_require__(14909); +var RandomZone = __webpack_require__(68433); +var Rectangle = __webpack_require__(74118); +var RectangleToRectangle = __webpack_require__(90205); +var Remove = __webpack_require__(66458); +var Render = __webpack_require__(69116); +var StableSort = __webpack_require__(17922); +var TransformMatrix = __webpack_require__(69360); +var Vector2 = __webpack_require__(93736); +var Wrap = __webpack_require__(1071); +var ParticleBounds = __webpack_require__(73106); + +/** + * Names of simple configuration properties. + * + * @ignore + */ +var configFastMap = [ + 'active', + 'advance', + 'blendMode', + 'colorEase', + 'deathCallback', + 'deathCallbackScope', + 'duration', + 'emitCallback', + 'emitCallbackScope', + 'follow', + 'frequency', + 'gravityX', + 'gravityY', + 'maxAliveParticles', + 'maxParticles', + 'name', + 'emitting', + 'particleBringToTop', + 'particleClass', + 'radial', + 'sortCallback', + 'sortOrderAsc', + 'sortProperty', + 'stopAfter', + 'tintFill', + 'timeScale', + 'trackVisible', + 'visible' +]; + +/** + * Names of complex configuration properties. + * + * @ignore + */ +var configOpMap = [ + 'accelerationX', + 'accelerationY', + 'alpha', + 'angle', + 'bounce', + 'color', + 'delay', + 'hold', + 'lifespan', + 'maxVelocityX', + 'maxVelocityY', + 'moveToX', + 'moveToY', + 'quantity', + 'rotate', + 'scaleX', + 'scaleY', + 'speedX', + 'speedY', + 'tint', + 'x', + 'y' +]; /** * @classdesc - * A Video Game Object. + * A Particle Emitter is a special kind of Game Object that controls a pool of {@link Phaser.GameObjects.Particles.Particle Particles}. * - * This Game Object is capable of handling playback of a previously loaded video from the Phaser Video Cache, - * or playing a video based on a given URL. Videos can be either local, or streamed. + * Particle Emitters are created via a configuration object. The properties of this object + * can be specified in a variety of formats, given you plenty of scope over the values they + * return, leading to complex visual effects. Here are the different forms of configuration + * value you can give: * - * ```javascript - * preload () { - * this.load.video('pixar', 'nemo.mp4'); - * } + * ## An explicit static value: * - * create () { - * this.add.video(400, 300, 'pixar'); + * ```js + * x: 400 + * ``` + * + * The x value will always be 400 when the particle is spawned. + * + * ## A random value: + * + * ```js + * x: [ 100, 200, 300, 400 ] + * ``` + * + * The x value will be one of the 4 elements in the given array, picked at random on emission. + * + * ## A custom callback: + * + * ```js + * x: (particle, key, t, value) => { + * return value + 50; * } * ``` * - * To all intents and purposes, a video is a standard Game Object, just like a Sprite. And as such, you can do - * all the usual things to it, such as scaling, rotating, cropping, tinting, making interactive, giving a - * physics body, etc. + * The x value is the result of calling this function. This is only used when the + * particle is emitted, so it provides it's initial starting value. It is not used + * when the particle is updated (see the onUpdate callback for that) * - * Transparent videos are also possible via the WebM file format. Providing the video file has was encoded with - * an alpha channel, and providing the browser supports WebM playback (not all of them do), then it will render - * in-game with full transparency. + * ## A start / end object: * - * ### Autoplaying Videos + * This allows you to control the change in value between the given start and + * end parameters over the course of the particles lifetime: * - * Videos can only autoplay if the browser has been unlocked with an interaction, or satisfies the MEI settings. - * The policies that control autoplaying are vast and vary between browser. - * You can, and should, read more about it here: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide + * ```js + * scale: { start: 0, end: 1 } + * ``` * - * If your video doesn't contain any audio, then set the `noAudio` parameter to `true` when the video is _loaded_, - * and it will often allow the video to play immediately: + * The particle scale will start at 0 when emitted and ease to a scale of 1 + * over the course of its lifetime. You can also specify the ease function + * used for this change (the default is Linear): * - * ```javascript - * preload () { - * this.load.video('pixar', 'nemo.mp4', 'loadeddata', false, true); + * ```js + * scale: { start: 0, end: 1, ease: 'bounce.out' } + * ``` + * + * ## A start / end random object: + * + * The start and end object can have an optional `random` parameter. + * This forces it to pick a random value between the two values and use + * this as the starting value, then easing to the 'end' parameter over + * its lifetime. + * + * ```js + * scale: { start: 4, end: 0.5, random: true } + * ``` + * + * The particle will start with a random scale between 0.5 and 4 and then + * scale to the end value over its lifetime. You can combine the above + * with the `ease` parameter as well to control the value easing. + * + * ## An interpolation object: + * + * You can provide an array of values which will be used for interpolation + * during the particles lifetime. You can also define the interpolation + * function to be used. There are three provided: `linear` (the default), + * `bezier` and `catmull`, or you can provide your own function. + * + * ```js + * x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull' } + * ``` + * + * The particle scale will interpolate from 50 when emitted to 800 via the other + * points over the course of its lifetime. You can also specify an ease function + * used to control the rate of change through the values (the default is Linear): + * + * ```js + * x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull', ease: 'bounce.out } + * ``` + * + * ## A stepped emitter object: + * + * The `steps` parameter allows you to control the placement of sequential + * particles across the start-end range: + * + * ```js + * x: { steps: 32, start: 0, end: 576 } + * ``` + * + * Here we have a range of 576 (start to end). This is divided into 32 steps. + * + * The first particle will emit at the x position of 0. The next will emit + * at the next 'step' along, which would be 18. The following particle will emit + * at the next step, which is 36, and so on. Because the range of 576 has been + * divided by 32, creating 18 pixels steps. When a particle reaches the 'end' + * value the next one will start from the beginning again. + * + * ## A stepped emitter object with yoyo: + * + * You can add the optional `yoyo` property to a stepped object: + * + * ```js + * x: { steps: 32, start: 0, end: 576, yoyo: true } + * ``` + * + * As with the stepped emitter, particles are emitted in sequence, from 'start' + * to 'end' in step sized jumps. Normally, when a stepped emitter reaches the + * end it snaps around to the start value again. However, if you provide the 'yoyo' + * parameter then when it reaches the end it will reverse direction and start + * emitting back down to 'start' again. Depending on the effect you require this + * can often look better. + * + * ## A min / max object: + * + * This allows you to pick a random float value between the min and max properties: + * + * ```js + * x: { min: 100, max: 700 } + * ``` + * + * The x value will be a random float between min and max. + * + * You can force it select an integer by setting the 'int' flag: + * + * ```js + * x: { min: 100, max: 700, int: true } + * ``` + * + * Or, you could use the 'random' array approach (see below) + * + * ## A random object: + * + * This allows you to pick a random integer value between the first and second array elements: + * + * ```js + * x: { random: [ 100, 700 ] } + * ``` + * + * The x value will be a random integer between 100 and 700 as it takes the first + * element in the 'random' array as the 'min' value and the 2nd element as the 'max' value. + * + * ## Custom onEmit and onUpdate callbacks: + * + * If the above won't give you the effect you're after, you can provide your own + * callbacks that will be used when the particle is both emitted and updated: + * + * ```js + * x: { + * onEmit: (particle, key, t, value) => { + * return value; + * }, + * onUpdate: (particle, key, t, value) => { + * return value; + * } * } * ``` * - * The 5th parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without - * audio can autoplay without requiring a user interaction. Video with audio cannot do this unless it satisfies - * the browsers MEI settings. See the MDN Autoplay Guide for further details. + * You can provide either one or both functions. The `onEmit` is called at the + * start of the particles life and defines the value of the property on birth. * - * Note that due to a bug in IE11 you cannot play a video texture to a Sprite in WebGL. For IE11 force Canvas mode. + * The `onUpdate` function is called every time the Particle Emitter updates + * until the particle dies. Both must return a value. * - * More details about video playback and the supported media formats can be found on MDN: + * The properties are: * - * https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement - * https://developer.mozilla.org/en-US/docs/Web/Media/Formats + * particle - A reference to the Particle instance. + * key - The string based key of the property, i.e. 'x' or 'lifespan'. + * t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + * value - The current property value. At a minimum you should return this. * - * @class Video + * By using the above configuration options you have an unlimited about of + * control over how your particles behave. + * + * ## v3.55 Differences + * + * Prior to v3.60 Phaser used a `ParticleEmitterManager`. This was removed in v3.60 + * and now calling `this.add.particles` returns a `ParticleEmitter` instance instead. + * + * In order to streamline memory and the display list we have removed the + * `ParticleEmitterManager` entirely. When you call `this.add.particles` you're now + * creating a `ParticleEmitter` instance, which is being added directly to the + * display list and can be manipulated just like any other Game Object, i.e. + * scaled, rotated, positioned, added to a Container, etc. It now extends the + * `GameObject` base class, meaning it's also an event emitter, which allowed us + * to create some handy new events for particles. + * + * So, to create an emitter, you now give it an xy coordinate, a texture and an + * emitter configuration object (you can also set this later, but most commonly + * you'd do it on creation). I.e.: + * + * ```js + * const emitter = this.add.particles(100, 300, 'flares', { + * frame: 'red', + * angle: { min: -30, max: 30 }, + * speed: 150 + * }); + * ``` + * + * This will create a 'red flare' emitter at 100 x 300. + * + * Please update your code to ensure it adheres to the new function signatures. + * + * @class ParticleEmitter * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects + * @memberof Phaser.GameObjects.Particles * @constructor - * @since 3.20.0 + * @since 3.60.0 * - * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.AlphaSingle * @extends Phaser.GameObjects.Components.BlendMode * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.GetBounds * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Origin * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.TextureCrop - * @extends Phaser.GameObjects.Components.Tint + * @extends Phaser.GameObjects.Components.Texture * @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} [key] - Optional key of the Video this Game Object will play, as stored in the Video Cache. + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. */ -var Video = new Class({ +var ParticleEmitter = new Class({ Extends: GameObject, Mixins: [ - Components.Alpha, + Components.AlphaSingle, Components.BlendMode, Components.Depth, - Components.Flip, - Components.GetBounds, Components.Mask, - Components.Origin, Components.Pipeline, + Components.PostPipeline, Components.ScrollFactor, - Components.Size, - Components.TextureCrop, - Components.Tint, + Components.Texture, Components.Transform, Components.Visible, - VideoRender + Render ], initialize: - function Video (scene, x, y, key) + function ParticleEmitter (scene, x, y, texture, config) { - GameObject.call(this, scene, 'Video'); + GameObject.call(this, scene, 'ParticleEmitter'); /** - * A reference to the HTML Video Element this Video Game Object is playing. - * Will be `null` until a video is loaded for playback. + * The Particle Class which will be emitted by this Emitter. * - * @name Phaser.GameObjects.Video#video - * @type {?HTMLVideoElement} - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleClass + * @type {function} + * @default Phaser.GameObjects.Particles.Particle + * @since 3.0.0 + * @see Phaser.Types.GameObjects.Particles.ParticleClassConstructor */ - this.video = null; + this.particleClass = Particle; /** - * The Phaser Texture this Game Object is using to render the video to. - * Will be `null` until a video is loaded for playback. + * An internal object holding all of the EmitterOp instances. + * + * These are populated as part of the Emitter configuration parsing. + * + * You typically do not access them directly, but instead use the + * provided getters and setters on this class, such as `ParticleEmitter.speedX` etc. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#ops + * @type {Phaser.Types.GameObjects.Particles.ParticleEmitterOps} + * @since 3.60.0 + */ + this.ops = { + accelerationX: new EmitterOp('accelerationX', 0), + accelerationY: new EmitterOp('accelerationY', 0), + alpha: new EmitterOp('alpha', 1), + angle: new EmitterOp('angle', { min: 0, max: 360 }, true), + bounce: new EmitterOp('bounce', 0), + color: new EmitterColorOp('color'), + delay: new EmitterOp('delay', 0, true), + hold: new EmitterOp('hold', 0, true), + lifespan: new EmitterOp('lifespan', 1000, true), + maxVelocityX: new EmitterOp('maxVelocityX', 10000), + maxVelocityY: new EmitterOp('maxVelocityY', 10000), + moveToX: new EmitterOp('moveToX', 0), + moveToY: new EmitterOp('moveToY', 0), + quantity: new EmitterOp('quantity', 1, true), + rotate: new EmitterOp('rotate', 0), + scaleX: new EmitterOp('scaleX', 1), + scaleY: new EmitterOp('scaleY', 1), + speedX: new EmitterOp('speedX', 0, true), + speedY: new EmitterOp('speedY', 0, true), + tint: new EmitterOp('tint', 0xffffff), + x: new EmitterOp('x', 0), + y: new EmitterOp('y', 0) + }; + + /** + * 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.Video#videoTexture - * @type {?Phaser.Textures.Texture} - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#radial + * @type {boolean} + * @default true + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setRadial */ - this.videoTexture = null; + this.radial = true; /** - * A reference to the TextureSource belong to the `videoTexture` Texture object. - * Will be `null` until a video is loaded for playback. + * Horizontal acceleration applied to emitted particles, in pixels per second squared. * - * @name Phaser.GameObjects.Video#videoTextureSource - * @type {?Phaser.Textures.TextureSource} - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityX + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity */ - this.videoTextureSource = null; + this.gravityX = 0; /** - * A Phaser CanvasTexture instance that holds the most recent snapshot taken from the video. - * This will only be set if `snapshot` or `snapshotArea` have been called, and will be `null` until that point. + * Vertical acceleration applied to emitted particles, in pixels per second squared. * - * @name Phaser.GameObjects.Video#snapshotTexture - * @type {?Phaser.Textures.CanvasTexture} - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityY + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity */ - this.snapshotTexture = null; + this.gravityY = 0; /** - * If you have saved this video to a texture via the `saveTexture` method, this controls if the video - * is rendered with `flipY` in WebGL or not. You often need to set this if you wish to use the video texture - * as the input source for a shader. If you find your video is appearing upside down within a shader or - * custom pipeline, flip this property. + * Whether accelerationX and accelerationY are non-zero. Set automatically during configuration. * - * @name Phaser.GameObjects.Video#flipY + * @name Phaser.GameObjects.Particles.ParticleEmitter#acceleration * @type {boolean} - * @since 3.20.0 + * @default false + * @since 3.0.0 */ - this.flipY = false; + this.acceleration = false; /** - * The key used by the texture as stored in the Texture Manager. + * Whether moveToX and moveToY are set. Set automatically during configuration. * - * @name Phaser.GameObjects.Video#_key - * @type {string} - * @private - * @since 3.20.0 + * When true the particles move toward the moveToX and moveToY coordinates and arrive at the end of their life. + * Emitter angle, speedX, and speedY are ignored. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#moveTo + * @type {boolean} + * @default false + * @since 3.0.0 */ - this._key = UUID(); + this.moveTo = false; /** - * An internal flag holding the current state of the video lock, should document interaction be required - * before playback can begin. + * A function to call when a particle is emitted. * - * @name Phaser.GameObjects.Video#touchLocked - * @type {boolean} - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallback + * @type {?Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} + * @default null + * @since 3.0.0 */ - this.touchLocked = true; + this.emitCallback = null; /** - * Should the video auto play when document interaction is required and happens? + * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#emitCallback}. * - * @name Phaser.GameObjects.Video#playWhenUnlocked - * @type {boolean} - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#emitCallbackScope + * @type {?*} + * @default null + * @since 3.0.0 */ - this.playWhenUnlocked = false; + this.emitCallbackScope = null; /** - * When starting playback of a video Phaser will monitor its `readyState` using a `setTimeout` call. - * The `setTimeout` happens once every `Video.retryInterval` ms. It will carry on monitoring the video - * state in this manner until the `retryLimit` is reached and then abort. + * A function to call when a particle dies. * - * @name Phaser.GameObjects.Video#retryLimit - * @type {number} - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallback + * @type {?Phaser.Types.GameObjects.Particles.ParticleDeathCallback} + * @default null + * @since 3.0.0 */ - this.retryLimit = 20; + this.deathCallback = null; /** - * The current retry attempt. + * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#deathCallback}. * - * @name Phaser.GameObjects.Video#retry - * @type {number} - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#deathCallbackScope + * @type {?*} + * @default null + * @since 3.0.0 */ - this.retry = 0; + this.deathCallbackScope = null; /** - * The number of ms between each retry while monitoring the ready state of a downloading video. + * Set to hard limit the amount of particle objects this emitter is allowed to create + * in total. This is the number of `Particle` instances it can create, not the number + * of 'alive' particles. * - * @name Phaser.GameObjects.Video#retryInterval + * 0 means unlimited. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxParticles * @type {number} - * @since 3.20.0 + * @default 0 + * @since 3.0.0 */ - this.retryInterval = 500; + this.maxParticles = 0; /** - * The setTimeout callback ID. + * The maximum number of alive and rendering particles this emitter will update. + * When this limit is reached, a particle needs to die before another can be emitted. + * + * 0 means no limits. * - * @name Phaser.GameObjects.Video#_retryID + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxAliveParticles * @type {number} - * @private - * @since 3.20.0 + * @default 0 + * @since 3.60.0 */ - this._retryID = null; + this.maxAliveParticles = 0; /** - * The video was muted due to a system event, such as the game losing focus. + * If set, either via the Emitter config, or by directly setting this property, + * the Particle Emitter will stop emitting particles once this total has been + * reached. It will then enter a 'stopped' state, firing the `STOP` + * event. Note that entering a stopped state doesn't mean all the particles + * have finished, just that it's not emitting any further ones. * - * @name Phaser.GameObjects.Video#_systemMuted - * @type {boolean} - * @private - * @since 3.20.0 + * To know when the final particle expires, listen for the COMPLETE event. + * + * Use this if you wish to launch an exact number of particles and then stop + * your emitter afterwards. + * + * The counter is reset each time the `ParticleEmitter.start` method is called. + * + * 0 means the emitter will not stop based on total emitted particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#stopAfter + * @type {number} + * @default 0 + * @since 3.60.0 */ - this._systemMuted = false; + this.stopAfter = 0; /** - * The video was muted due to game code, not a system event. + * The number of milliseconds this emitter will emit particles for when in flow mode, + * before it stops emission. A value of 0 (the default) means there is no duration. * - * @name Phaser.GameObjects.Video#_codeMuted - * @type {boolean} - * @private - * @since 3.20.0 + * When the duration expires the `STOP` event is emitted. Note that entering a + * stopped state doesn't mean all the particles have finished, just that it's + * not emitting any further ones. + * + * To know when the final particle expires, listen for the COMPLETE event. + * + * The counter is reset each time the `ParticleEmitter.start` method is called. + * + * 0 means the emitter will not stop based on duration. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#duration + * @type {number} + * @default 0 + * @since 3.60.0 */ - this._codeMuted = false; + this.duration = 0; /** - * The video was paused due to a system event, such as the game losing focus. + * 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.Video#_systemPaused - * @type {boolean} - * @private - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#frequency + * @type {number} + * @default 0 + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency */ - this._systemPaused = false; + this.frequency = 0; /** - * The video was paused due to game code, not a system event. + * Controls if the emitter is currently emitting a particle flow (when frequency >= 0). * - * @name Phaser.GameObjects.Video#_codePaused + * 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#emitting * @type {boolean} - * @private - * @since 3.20.0 + * @default true + * @since 3.0.0 */ - this._codePaused = false; + this.emitting = true; /** - * The locally bound event callback handlers. + * Newly emitted particles are added to the top of the particle list, i.e. rendered above those already alive. * - * @name Phaser.GameObjects.Video#_callbacks - * @type {any} - * @private - * @since 3.20.0 + * Set to false to send them to the back. + * + * Also see the `sortOrder` property for more complex particle sorting. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleBringToTop + * @type {boolean} + * @default true + * @since 3.0.0 */ - this._callbacks = { - play: this.playHandler.bind(this), - error: this.loadErrorHandler.bind(this), - end: this.completeHandler.bind(this), - time: this.timeUpdateHandler.bind(this), - seeking: this.seekingHandler.bind(this), - seeked: this.seekedHandler.bind(this) - }; + this.particleBringToTop = true; /** - * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. + * The time rate applied to active particles, affecting lifespan, movement, and tweens. Values larger than 1 are faster than normal. * - * @name Phaser.GameObjects.Video#_crop - * @type {object} - * @private - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#timeScale + * @type {number} + * @default 1 + * @since 3.0.0 */ - this._crop = this.resetCropObject(); + this.timeScale = 1; /** - * An object containing in and out markers for sequence playback. + * An array containing Particle Emission Zones. These can be either EdgeZones or RandomZones. * - * @name Phaser.GameObjects.Video#markers - * @type {any} - * @since 3.20.0 + * Particles are emitted from a randomly selected zone from this array. + * + * Prior to Phaser v3.60 an Emitter could only have one single Emission Zone. + * In 3.60 they can now have an array of Emission Zones. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#emitZones + * @type {Phaser.GameObjects.Particles.Zones.EdgeZone[]|Phaser.GameObjects.Particles.Zones.RandomZone[]} + * @since 3.60.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone */ - this.markers = {}; + this.emitZones = []; /** - * The in marker. + * An array containing Particle Death Zone objects. A particle is immediately killed as soon as its x/y coordinates + * intersect with any of the configured Death Zones. * - * @name Phaser.GameObjects.Video#_markerIn - * @type {number} - * @private - * @since 3.20.0 + * Prior to Phaser v3.60 an Emitter could only have one single Death Zone. + * In 3.60 they can now have an array of Death Zones. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#deathZones + * @type {Phaser.GameObjects.Particles.Zones.DeathZone[]} + * @since 3.60.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone */ - this._markerIn = -1; + this.deathZones = []; /** - * The out marker. + * An optional Rectangle object that is used during rendering to cull Particles from + * display. For example, if your particles are limited to only move within a 300x300 + * sized area from their origin, then you can set this Rectangle to those dimensions. * - * @name Phaser.GameObjects.Video#_markerOut - * @type {number} - * @private - * @since 3.20.0 + * The renderer will check to see if the `viewBounds` Rectangle intersects with the + * Camera bounds during the render step and if not it will skip rendering the Emitter + * entirely. + * + * This allows you to create many emitters in a Scene without the cost of + * rendering if the contents aren't visible. + * + * Note that the Emitter will not perform any checks to see if the Particles themselves + * are outside of these bounds, or not. It will simply check the bounds against the + * camera. Use the `getBounds` method with the `advance` parameter to help define + * the location and placement of the view bounds. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#viewBounds + * @type {?Phaser.Geom.Rectangle} + * @default null + * @since 3.60.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setViewBounds */ - this._markerOut = MATH_CONST.MAX_SAFE_INTEGER; + this.viewBounds = null; /** - * The last time the TextureSource was updated. + * A Game Object whose position is used as the particle origin. * - * @name Phaser.GameObjects.Video#_lastUpdate - * @type {number} - * @private - * @since 3.20.0 + * @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._lastUpdate = 0; + this.follow = null; /** - * The key of the video being played from the Video cache, if any. + * The offset of the particle origin from the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target. * - * @name Phaser.GameObjects.Video#_cacheKey - * @type {string} - * @private - * @since 3.20.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#followOffset + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow */ - this._cacheKey = ''; + this.followOffset = new Vector2(); /** - * Is the video currently seeking? + * 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.Video#_isSeeking + * @name Phaser.GameObjects.Particles.ParticleEmitter#trackVisible * @type {boolean} - * @private - * @since 3.20.0 + * @default false + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#startFollow */ - this._isSeeking = false; + this.trackVisible = false; /** - * Should the Video element that this Video is using, be removed from the DOM - * when this Video is destroyed? + * The texture frames assigned to particles. * - * @name Phaser.GameObjects.Video#removeVideoElementOnDestroy + * @name Phaser.GameObjects.Particles.ParticleEmitter#frames + * @type {Phaser.Textures.Frame[]} + * @since 3.0.0 + */ + this.frames = []; + + /** + * Whether texture {@link Phaser.GameObjects.Particles.ParticleEmitter#frames} are selected at random. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#randomFrame * @type {boolean} - * @since 3.21.0 + * @default true + * @since 3.0.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setEmitterFrame */ - this.removeVideoElementOnDestroy = false; + this.randomFrame = true; - this.setPosition(x, y); - this.initPipeline(); + /** + * 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#setEmitterFrame + */ + this.frameQuantity = 1; - if (key) - { - this.changeSource(key, false); - } + /** + * The animations assigned to particles. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#anims + * @type {string[]} + * @since 3.60.0 + */ + this.anims = []; - var game = scene.sys.game.events; + /** + * Whether animations {@link Phaser.GameObjects.Particles.ParticleEmitter#anims} are selected at random. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#randomAnim + * @type {boolean} + * @default true + * @since 3.60.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setAnim + */ + this.randomAnim = true; - game.on(GameEvents.PAUSE, this.globalPause, this); - game.on(GameEvents.RESUME, this.globalResume, this); + /** + * The number of consecutive particles that receive a single animation (per frame cycle). + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#animQuantity + * @type {number} + * @default 1 + * @since 3.60.0 + * @see Phaser.GameObjects.Particles.ParticleEmitter#setAnim + */ + this.animQuantity = 1; - var sound = scene.sys.sound; + /** + * An array containing all currently inactive Particle instances. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#dead + * @type {Phaser.GameObjects.Particles.Particle[]} + * @private + * @since 3.0.0 + */ + this.dead = []; - if (sound) + /** + * An array containing all currently live and rendering Particle instances. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#alive + * @type {Phaser.GameObjects.Particles.Particle[]} + * @private + * @since 3.0.0 + */ + this.alive = []; + + /** + * Internal array that holds counter data: + * + * 0 - flowCounter - The time until next flow cycle. + * 1 - frameCounter - Counts up to {@link Phaser.GameObjects.Particles.ParticleEmitter#frameQuantity}. + * 2 - animCounter - Counts up to animQuantity. + * 3 - elapsed - The time remaining until the `duration` limit is reached. + * 4 - stopCounter - The number of particles remaining until `stopAfter` limit is reached. + * 5 - completeFlag - Has the COMPLETE event been emitted? + * 6 - zoneIndex - The emit zone index counter. + * 7 - zoneTotal - The emit zone total counter. + * 8 - currentFrame - The current texture frame, as an index of {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. + * 9 - currentAnim - The current animation, as an index of {@link Phaser.GameObjects.Particles.ParticleEmitter#anims}. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#counters + * @type {Float32Array} + * @private + * @since 3.60.0 + */ + this.counters = new Float32Array(10); + + /** + * An internal property used to tell when the emitter is in fast-forwarc mode. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#skipping + * @type {boolean} + * @default true + * @since 3.60.0 + */ + this.skipping = false; + + /** + * An internal Transform Matrix used to cache this emitters world matrix. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#worldMatrix + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.60.0 + */ + this.worldMatrix = new TransformMatrix(); + + /** + * Optionally sort the particles before they render based on this + * property. The property must exist on the `Particle` class, such + * as `y`, `lifeT`, `scaleX`, etc. + * + * When set this overrides the `particleBringToTop` setting. + * + * To reset this and disable sorting, so this property to an empty string. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#sortProperty + * @type {string} + * @since 3.60.0 + */ + this.sortProperty = ''; + + /** + * When `sortProperty` is defined this controls the sorting order, + * either ascending or descending. Toggle to control the visual effect. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#sortOrderAsc + * @type {boolean} + * @since 3.60.0 + */ + this.sortOrderAsc = true; + + /** + * The callback used to sort the particles. Only used if `sortProperty` + * has been set. Set this via the `setSortCallback` method. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#sortCallback + * @type {?Phaser.Types.GameObjects.Particles.ParticleSortCallback} + * @since 3.60.0 + */ + this.sortCallback = this.depthSortCallback; + + /** + * A list of Particle Processors being managed by this Emitter. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#processors + * @type {Phaser.Structs.List.} + * @since 3.60.0 + */ + this.processors = new List(this); + + /** + * The tint fill mode used by the Particles in this Emitter. + * + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#tintFill + * @type {boolean} + * @default false + * @since 3.60.0 + */ + this.tintFill = false; + + this.initPipeline(); + this.initPostPipeline(); + + this.setPosition(x, y); + this.setTexture(texture); + + if (config) { - sound.on(SoundEvents.GLOBAL_MUTE, this.globalMute, this); + this.setConfig(config); } }, @@ -60696,4009 +64134,5055 @@ var Video = new Class({ }, /** - * Starts this video playing. - * - * If the video is already playing, or has been queued to play with `changeSource` then this method just returns. - * - * Videos can only autoplay if the browser has been unlocked. This happens if you have interacted with the browser, i.e. - * by clicking on it or pressing a key, or due to server settings. The policies that control autoplaying are vast and - * vary between browser. You can read more here: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide - * - * If your video doesn't contain any audio, then set the `noAudio` parameter to `true` when the video is loaded, - * and it will often allow the video to play immediately: - * - * ```javascript - * preload () { - * this.load.video('pixar', 'nemo.mp4', 'loadeddata', false, true); - * } - * ``` - * - * The 5th parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without - * audio can autoplay without requiring a user interaction. Video with audio cannot do this unless it satisfies - * the browsers MEI settings. See the MDN Autoplay Guide for details. + * Takes an Emitter Configuration file and resets this Emitter, using any + * properties defined in the config to then set it up again. * - * If you need audio in your videos, then you'll have to consider the fact that the video cannot start playing until the - * user has interacted with the browser, into your game flow. - * - * @method Phaser.GameObjects.Video#play - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#setConfig + * @since 3.60.0 * - * @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats. - * @param {number} [markerIn] - Optional in marker time, in seconds, for playback of a sequence of the video. - * @param {number} [markerOut] - Optional out marker time, in seconds, for playback of a sequence of the video. + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. * - * @return {this} This Video Game Object for method chaining. + * @return {this} This Particle Emitter. */ - play: function (loop, markerIn, markerOut) + setConfig: function (config) { - if ((this.touchLocked && this.playWhenUnlocked) || this.isPlaying()) + if (!config) { return this; } - var video = this.video; + var i = 0; + var key = ''; - if (!video) + var ops = this.ops; + + for (i = 0; i < configOpMap.length; i++) { - console.warn('Video not loaded'); + key = configOpMap[i]; - return this; + ops[key].loadConfig(config); } - if (loop === undefined) { loop = video.loop; } + for (i = 0; i < configFastMap.length; i++) + { + key = configFastMap[i]; - var sound = this.scene.sys.sound; + // Only update properties from their current state if they exist in the given config + if (HasValue(config, key)) + { + this[key] = GetFastValue(config, key); + } + } - if (sound && sound.mute) + this.acceleration = (this.accelerationX !== 0 || this.accelerationY !== 0); + + this.moveTo = (this.moveToX !== 0 && this.moveToY !== 0); + + // Special 'speed' override + + if (HasValue(config, 'speed')) { - // Mute will be set based on the global mute state of the Sound Manager (if there is one) - this.setMute(true); + ops.speedX.loadConfig(config, 'speed'); + ops.speedY.active = false; } - if (!isNaN(markerIn)) + // 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._markerIn = markerIn; + this.radial = false; } - if (!isNaN(markerOut) && markerOut > markerIn) + // Special 'scale' override + + if (HasValue(config, 'scale')) { - this._markerOut = markerOut; + ops.scaleX.loadConfig(config, 'scale'); + ops.scaleY.active = false; } - video.loop = loop; + if (HasValue(config, 'callbackScope')) + { + var callbackScope = GetFastValue(config, 'callbackScope', null); - var callbacks = this._callbacks; + this.emitCallbackScope = callbackScope; + this.deathCallbackScope = callbackScope; + } - var playPromise = video.play(); + if (HasValue(config, 'emitZone')) + { + this.addEmitZone(config.emitZone); + } - if (playPromise !== undefined) + if (HasValue(config, 'deathZone')) { - playPromise.then(this.playPromiseSuccessHandler.bind(this)).catch(this.playPromiseErrorHandler.bind(this)); + this.addDeathZone(config.deathZone); } - else + + if (HasValue(config, 'bounds')) { - // Old-school browsers with no Promises - video.addEventListener('playing', callbacks.play, true); + var bounds = this.addParticleBounds(config.bounds); - // If video hasn't downloaded properly yet ... - if (video.readyState < 2) - { - this.retry = this.retryLimit; + bounds.collideLeft = GetFastValue(config, 'collideLeft', true); + bounds.collideRight = GetFastValue(config, 'collideRight', true); + bounds.collideTop = GetFastValue(config, 'collideTop', true); + bounds.collideBottom = GetFastValue(config, 'collideBottom', true); + } - this._retryID = window.setTimeout(this.checkVideoProgress.bind(this), this.retryInterval); - } + if (HasValue(config, 'followOffset')) + { + this.followOffset.setFromObject(GetFastValue(config, 'followOffset', 0)); + } + + if (HasValue(config, 'texture')) + { + this.setTexture(config.texture); + } + + if (HasValue(config, 'frame')) + { + this.setEmitterFrame(config.frame); + } + else if (HasValue(config, 'anim')) + { + this.setAnim(config.anim); + } + + if (HasValue(config, 'reserve')) + { + this.reserve(config.reserve); + } + + if (HasValue(config, 'advance')) + { + this.fastForward(config.advance); } - // Set these _after_ calling `play` or they don't fire (useful, thanks browsers) - video.addEventListener('ended', callbacks.end, true); - video.addEventListener('timeupdate', callbacks.time, true); - video.addEventListener('seeking', callbacks.seeking, true); - video.addEventListener('seeked', callbacks.seeked, true); + this.resetCounters(this.frequency, this.emitting); + + if (this.emitting) + { + this.emit(Events.START, this); + } return this; }, /** - * This method allows you to change the source of the current video element. It works by first stopping the - * current video, if playing. Then deleting the video texture, if one has been created. Finally, it makes a - * new video texture and starts playback of the new source through the existing video element. - * - * The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked - * state, even if you change the source of the video. By changing the source to a new video you avoid having to - * go through the unlock process again. - * - * @method Phaser.GameObjects.Video#changeSource - * @since 3.20.0 + * Creates a description of this emitter suitable for JSON serialization. * - * @param {string} key - The key of the Video this Game Object will swap to playing, as stored in the Video Cache. - * @param {boolean} [autoplay=true] - Should the video start playing immediately, once the swap is complete? - * @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats. - * @param {number} [markerIn] - Optional in marker time, in seconds, for playback of a sequence of the video. - * @param {number} [markerOut] - Optional out marker time, in seconds, for playback of a sequence of the video. + * @method Phaser.GameObjects.Particles.ParticleEmitter#toJSON + * @since 3.0.0 * - * @return {this} This Video Game Object for method chaining. + * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object. */ - changeSource: function (key, autoplay, loop, markerIn, markerOut) + toJSON: function () { - if (autoplay === undefined) { autoplay = true; } + var output = ComponentsToJSON(this); - var currentVideo = this.video; + var i = 0; + var key = ''; - if (currentVideo) + for (i = 0; i < configFastMap.length; i++) { - this.stop(); + key = configFastMap[i]; + + output[key] = this[key]; } - var newVideo = this.scene.sys.cache.video.get(key); + var ops = this.ops; - if (newVideo) + for (i = 0; i < configOpMap.length; i++) { - this.video = newVideo; - - this._cacheKey = key; - - this._codePaused = newVideo.paused; - this._codeMuted = newVideo.muted; - - if (this.videoTexture) - { - this.scene.sys.textures.remove(this._key); + key = configOpMap[i]; - this.videoTexture = this.scene.sys.textures.create(this._key, newVideo, newVideo.videoWidth, newVideo.videoHeight); - this.videoTextureSource = this.videoTexture.source[0]; - this.videoTexture.add('__BASE', 0, 0, 0, newVideo.videoWidth, newVideo.videoHeight); - - this.setTexture(this.videoTexture); - this.setSizeToFrame(); - this.updateDisplayOrigin(); - - this.emit(Events.VIDEO_CREATED, this, newVideo.videoWidth, newVideo.videoHeight); - } - else + if (ops[key]) { - this.updateTexture(); + output[key] = ops[key].toJSON(); } + } - newVideo.currentTime = 0; - - this._lastUpdate = 0; - - if (autoplay) - { - this.play(loop, markerIn, markerOut); - } + // special handlers + if (!ops.speedY.active) + { + delete output.speedX; + output.speed = ops.speedX.toJSON(); } - else + + if (this.scaleX === this.scaleY) { - this.video = null; + delete output.scaleX; + delete output.scaleY; + output.scale = ops.scaleX.toJSON(); } - return this; + return output; }, /** - * Adds a sequence marker to this video. - * - * Markers allow you to split a video up into sequences, delineated by a start and end time, given in seconds. - * - * You can then play back specific markers via the `playMarker` method. - * - * Note that marker timing is _not_ frame-perfect. You should construct your videos in such a way that you allow for - * plenty of extra padding before and after each sequence to allow for discrepancies in browser seek and currentTime accuracy. + * Resets the internal counter trackers. * - * See https://github.com/w3c/media-and-entertainment/issues/4 for more details about this issue. - * - * @method Phaser.GameObjects.Video#addMarker - * @since 3.20.0 + * You shouldn't ever need to call this directly. * - * @param {string} key - A unique name to give this marker. - * @param {number} markerIn - The time, in seconds, representing the start of this marker. - * @param {number} markerOut - The time, in seconds, representing the end of this marker. + * @method Phaser.GameObjects.Particles.ParticleEmitter#resetCounters + * @since 3.60.0 * - * @return {this} This Video Game Object for method chaining. + * @param {number} frequency - The frequency counter. + * @param {boolean} on - Set the complete flag. */ - addMarker: function (key, markerIn, markerOut) + resetCounters: function (frequency, on) { - if (!isNaN(markerIn) && markerIn >= 0 && !isNaN(markerOut)) + var counters = this.counters; + + counters.fill(0); + + counters[0] = frequency; + + if (on) { - this.markers[key] = [ markerIn, markerOut ]; + counters[5] = 1; } - - return this; }, /** - * Plays a pre-defined sequence in this video. - * - * Markers allow you to split a video up into sequences, delineated by a start and end time, given in seconds and - * specified via the `addMarker` method. - * - * Note that marker timing is _not_ frame-perfect. You should construct your videos in such a way that you allow for - * plenty of extra padding before and after each sequence to allow for discrepancies in browser seek and currentTime accuracy. - * - * See https://github.com/w3c/media-and-entertainment/issues/4 for more details about this issue. + * Continuously moves the particle origin to follow a Game Object's position. * - * @method Phaser.GameObjects.Video#playMarker - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#startFollow + * @since 3.0.0 * - * @param {string} key - The name of the marker sequence to play. - * @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats. + * @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 Video Game Object for method chaining. + * @return {this} This Particle Emitter. */ - playMarker: function (key, loop) + startFollow: function (target, offsetX, offsetY, trackVisible) { - var marker = this.markers[key]; + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } + if (trackVisible === undefined) { trackVisible = false; } - if (marker) - { - this.play(loop, marker[0], marker[1]); - } + this.follow = target; + this.followOffset.set(offsetX, offsetY); + this.trackVisible = trackVisible; return this; }, /** - * Removes a previously set marker from this video. - * - * If the marker is currently playing it will _not_ stop playback. - * - * @method Phaser.GameObjects.Video#removeMarker - * @since 3.20.0 + * Stops following a Game Object. * - * @param {string} key - The name of the marker to remove. + * @method Phaser.GameObjects.Particles.ParticleEmitter#stopFollow + * @since 3.0.0 * - * @return {this} This Video Game Object for method chaining. + * @return {this} This Particle Emitter. */ - removeMarker: function (key) + stopFollow: function () { - delete this.markers[key]; + this.follow = null; + this.followOffset.set(0, 0); + this.trackVisible = false; return this; }, /** - * Takes a snapshot of the current frame of the video and renders it to a CanvasTexture object, - * which is then returned. You can optionally resize the grab by passing a width and height. - * - * This method returns a reference to the `Video.snapshotTexture` object. Calling this method - * multiple times will overwrite the previous snapshot with the most recent one. - * - * @method Phaser.GameObjects.Video#snapshot - * @since 3.20.0 + * Chooses a texture frame from {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. * - * @param {number} [width] - The width of the resulting CanvasTexture. - * @param {number} [height] - The height of the resulting CanvasTexture. + * @method Phaser.GameObjects.Particles.ParticleEmitter#getFrame + * @since 3.0.0 * - * @return {Phaser.Textures.CanvasTexture} + * @return {Phaser.Textures.Frame} The texture frame. */ - snapshot: function (width, height) + getFrame: function () { - if (width === undefined) { width = this.width; } - if (height === undefined) { height = this.height; } + var frames = this.frames; + var len = frames.length; + var current; - return this.snapshotArea(0, 0, this.width, this.height, width, height); + if (len === 1) + { + current = frames[0]; + } + else if (this.randomFrame) + { + current = GetRandom(frames); + } + else + { + current = frames[this.currentFrame]; + + this.frameCounter++; + + if (this.frameCounter === this.frameQuantity) + { + this.frameCounter = 0; + + this.currentFrame++; + + if (this.currentFrame === len) + { + this.currentFrame = 0; + } + } + } + + return this.texture.get(current); }, /** - * Takes a snapshot of the specified area of the current frame of the video and renders it to a CanvasTexture object, - * which is then returned. You can optionally resize the grab by passing a different `destWidth` and `destHeight`. + * Sets a pattern for assigning texture frames to emitted particles. The `frames` configuration can be any of: * - * This method returns a reference to the `Video.snapshotTexture` object. Calling this method - * multiple times will overwrite the previous snapshot with the most recent one. + * 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] } * - * @method Phaser.GameObjects.Video#snapshotArea - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitterFrame + * @since 3.0.0 * - * @param {number} [x=0] - The horizontal location of the top-left of the area to grab from. - * @param {number} [y=0] - The vertical location of the top-left of the area to grab from. - * @param {number} [srcWidth] - The width of area to grab from the video. If not given it will grab the full video dimensions. - * @param {number} [srcHeight] - The height of area to grab from the video. If not given it will grab the full video dimensions. - * @param {number} [destWidth] - The destination width of the grab, allowing you to resize it. - * @param {number} [destHeight] - The destination height of the grab, allowing you to resize it. + * @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 {Phaser.Textures.CanvasTexture} + * @return {this} This Particle Emitter. */ - snapshotArea: function (x, y, srcWidth, srcHeight, destWidth, destHeight) + setEmitterFrame: function (frames, pickRandom, quantity) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (srcWidth === undefined) { srcWidth = this.width; } - if (srcHeight === undefined) { srcHeight = this.height; } - if (destWidth === undefined) { destWidth = srcWidth; } - if (destHeight === undefined) { destHeight = srcHeight; } + if (pickRandom === undefined) { pickRandom = true; } + if (quantity === undefined) { quantity = 1; } - var video = this.video; - var snap = this.snapshotTexture; + this.randomFrame = pickRandom; + this.frameQuantity = quantity; - if (!snap) - { - snap = this.scene.sys.textures.createCanvas(UUID(), destWidth, destHeight); + this.currentFrame = 0; - this.snapshotTexture = snap; + var t = typeof (frames); - if (video) - { - snap.context.drawImage(video, x, y, srcWidth, srcHeight, 0, 0, destWidth, destHeight); - } + this.frames.length = 0; + + if (Array.isArray(frames)) + { + this.frames = this.frames.concat(frames); } - else + else if (t === 'string' || t === 'number') { - snap.setSize(destWidth, destHeight); + this.frames.push(frames); + } + else if (t === 'object') + { + var frameConfig = frames; - if (video) + frames = GetFastValue(frameConfig, 'frames', null); + + if (frames) { - snap.context.drawImage(video, x, y, srcWidth, srcHeight, 0, 0, destWidth, destHeight); + this.frames = this.frames.concat(frames); } + + var isCycle = GetFastValue(frameConfig, 'cycle', false); + + this.randomFrame = (isCycle) ? false : true; + + this.frameQuantity = GetFastValue(frameConfig, 'quantity', quantity); } - return snap.update(); + if (this.frames.length === 1) + { + this.frameQuantity = 1; + this.randomFrame = false; + } + + return this; }, /** - * Stores a copy of this Videos `snapshotTexture` in the Texture Manager using the given key. - * - * This texture is created when the `snapshot` or `snapshotArea` methods are called. - * - * After doing this, any texture based Game Object, such as a Sprite, can use the contents of the - * snapshot by using the texture key: - * - * ```javascript - * var vid = this.add.video(0, 0, 'intro'); - * - * vid.snapshot(); - * - * vid.saveSnapshotTexture('doodle'); - * - * this.add.image(400, 300, 'doodle'); - * ``` - * - * Updating the contents of the `snapshotTexture`, for example by calling `snapshot` again, - * will automatically update _any_ Game Object that is using it as a texture. - * Calling `saveSnapshotTexture` again will not save another copy of the same texture, - * it will just rename the existing one. - * - * By default it will create a single base texture. You can add frames to the texture - * by using the `Texture.add` method. After doing this, you can then allow Game Objects - * to use a specific frame. - * - * @method Phaser.GameObjects.Video#saveSnapshotTexture - * @since 3.20.0 + * Chooses an animation from {@link Phaser.GameObjects.Particles.ParticleEmitter#anims}, if populated. * - * @param {string} key - The unique key to store the texture as within the global Texture Manager. + * @method Phaser.GameObjects.Particles.ParticleEmitter#getAnim + * @since 3.60.0 * - * @return {Phaser.Textures.CanvasTexture} The Texture that was saved. + * @return {string} The animation to play, or `null` if there aren't any. */ - saveSnapshotTexture: function (key) + getAnim: function () { - if (this.snapshotTexture) + var anims = this.anims; + var len = anims.length; + + if (len === 0) { - this.scene.sys.textures.renameTexture(this.snapshotTexture.key, key); + return null; } - else + else if (len === 1) { - this.snapshotTexture = this.scene.sys.textures.createCanvas(key, this.width, this.height); + return anims[0]; + } + else if (this.randomAnim) + { + return GetRandom(anims); } + else + { + var anim = anims[this.currentAnim]; - return this.snapshotTexture; + this.animCounter++; + + if (this.animCounter >= this.animQuantity) + { + this.animCounter = 0; + this.currentAnim = Wrap(this.currentAnim + 1, 0, len - 1); + } + + return anim; + } }, /** - * Loads a Video from the given URL, ready for playback with the `Video.play` method. + * Sets a pattern for assigning animations to emitted particles. The `anims` configuration can be any of: * - * You can control at what point the browser determines the video as being ready for playback via - * the `loadEvent` parameter. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement - * for more details. + * anim: 'red' + * anim: [ 'red', 'green', 'blue', 'pink', 'white' ] + * anim: { anims: [ 'red', 'green', 'blue', 'pink', 'white' ], [cycle: bool], [quantity: int] } * - * @method Phaser.GameObjects.Video#loadURL - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#setAnim + * @since 3.60.0 * - * @param {string} url - The URL of the video to load or be streamed. - * @param {string} [loadEvent='loadeddata'] - The load event to listen for. Either `loadeddata`, `canplay` or `canplaythrough`. - * @param {boolean} [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it. + * @param {(array|string|Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig)} anims - One or more animations, or a configuration object. + * @param {boolean} [pickRandom=true] - Whether animations should be assigned at random from `anims`. + * @param {number} [quantity=1] - The number of consecutive particles that will receive each animation. * - * @return {this} This Video Game Object for method chaining. + * @return {this} This Particle Emitter. */ - loadURL: function (url, loadEvent, noAudio) + setAnim: function (anims, pickRandom, quantity) { - if (loadEvent === undefined) { loadEvent = 'loadeddata'; } - if (noAudio === undefined) { noAudio = false; } + if (pickRandom === undefined) { pickRandom = true; } + if (quantity === undefined) { quantity = 1; } - if (this.video) + this.randomAnim = pickRandom; + this.animQuantity = quantity; + + this.currentAnim = 0; + + var t = typeof (anims); + + this.anims.length = 0; + + if (Array.isArray(anims)) { - this.stop(); + this.anims = this.anims.concat(anims); } - - if (this.videoTexture) + else if (t === 'string') { - this.scene.sys.textures.remove(this._key); + this.anims.push(anims); } + else if (t === 'object') + { + var animConfig = anims; - var video = document.createElement('video'); + anims = GetFastValue(animConfig, 'anims', null); + + if (anims) + { + this.anims = this.anims.concat(anims); + } - video.controls = false; + var isCycle = GetFastValue(animConfig, 'cycle', false); - if (noAudio) - { - video.muted = true; - video.defaultMuted = true; + this.randomAnim = (isCycle) ? false : true; - video.setAttribute('autoplay', 'autoplay'); + this.animQuantity = GetFastValue(animConfig, 'quantity', quantity); } - video.setAttribute('playsinline', 'playsinline'); - video.setAttribute('preload', 'auto'); - - video.addEventListener('error', this._callbacks.error, true); + if (this.anims.length === 1) + { + this.animQuantity = 1; + this.randomAnim = false; + } - video.src = url; + return this; + }, - video.load(); + /** + * 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.video = video; + this.radial = value; return this; }, /** - * Loads a Video from the given MediaStream object, ready for playback with the `Video.play` method. + * Creates a Particle Bounds processor and adds it to this Emitter. * - * You can control at what point the browser determines the video as being ready for playback via - * the `loadEvent` parameter. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement - * for more details. + * This processor will check to see if any of the active Particles hit + * the defined boundary, as specified by a Rectangle shape in world-space. * - * @method Phaser.GameObjects.Video#loadMediaStream - * @since 3.50.0 + * If so, they are 'rebounded' back again by having their velocity adjusted. * - * @param {string} stream - The MediaStream object. - * @param {string} [loadEvent='loadeddata'] - The load event to listen for. Either `loadeddata`, `canplay` or `canplaythrough`. - * @param {boolean} [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it. + * The strength of the rebound is controlled by the `Particle.bounce` + * property. * - * @return {this} This Video Game Object for method chaining. + * You should be careful to ensure that you emit particles within a bounds, + * if set, otherwise it will lead to unpredictable visual results as the + * particles are hastily repositioned. + * + * The Particle Bounds processor is returned from this method. If you wish + * to modify the area you can directly change its `bounds` property, along + * with the `collideLeft` etc values. + * + * To disable the bounds you can either set its `active` property to `false`, + * or if you no longer require it, call `ParticleEmitter.removeParticleProcessor`. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#addParticleBounds + * @since 3.60.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. + * @param {boolean} [collideLeft=true] - Whether particles interact with the left edge of the bounds. + * @param {boolean} [collideRight=true] - Whether particles interact with the right edge of the bounds. + * @param {boolean} [collideTop=true] - Whether particles interact with the top edge of the bounds. + * @param {boolean} [collideBottom=true] - Whether particles interact with the bottom edge of the bounds. + * + * @return {Phaser.GameObjects.Particles.ParticleBounds} The Particle Bounds processor. */ - loadMediaStream: function (stream, loadEvent, noAudio) + addParticleBounds: function (x, y, width, height, collideLeft, collideRight, collideTop, collideBottom) { - if (loadEvent === undefined) { loadEvent = 'loadeddata'; } - if (noAudio === undefined) { noAudio = false; } - - if (this.video) + if (typeof x === 'object') { - this.stop(); - } + var obj = x; - if (this.videoTexture) - { - this.scene.sys.textures.remove(this._key); + x = obj.x; + y = obj.y; + width = (HasValue(obj, 'w')) ? obj.w : obj.width; + height = (HasValue(obj, 'h')) ? obj.h : obj.height; } - var video = document.createElement('video'); - - video.controls = false; - - if (noAudio) - { - video.muted = true; - video.defaultMuted = true; - - video.setAttribute('autoplay', 'autoplay'); - } + return this.addParticleProcessor(new ParticleBounds(x, y, width, height, collideLeft, collideRight, collideTop, collideBottom)); + }, - video.setAttribute('playsinline', 'playsinline'); - video.setAttribute('preload', 'auto'); + /** + * Sets the initial radial speed of emitted particles. + * + * Changes the emitter to radial mode. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleSpeed + * @since 3.60.0 + * + * @param {number} x - The horizontal speed of the emitted Particles. + * @param {number} [y=x] - The vertical speed of emitted Particles. If not set it will use the `x` value. + * + * @return {this} This Particle Emitter. + */ + setParticleSpeed: function (x, y) + { + if (y === undefined) { y = x; } - video.addEventListener('error', this._callbacks.error, true); + this.ops.speedX.onChange(x); - try + if (x === y) { - video.srcObject = stream; + this.ops.speedY.active = false; } - catch (error) + else { - video.src = window.URL.createObjectURL(stream); + this.ops.speedY.onChange(y); } - video.load(); - - this.video = video; + // If you specify speedX and Y then it changes the emitter from radial to a point emitter + this.radial = true; return this; }, /** - * This internal method is called automatically if the playback Promise resolves successfully. + * Sets the vertical and horizontal scale of the emitted particles. * - * @method Phaser.GameObjects.Video#playPromiseSuccessHandler - * @fires Phaser.GameObjects.Events#VIDEO_PLAY - * @private - * @since 3.20.0 + * You can also set the scale of the entire emitter via `setScale`. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleScale + * @since 3.60.0 + * + * @param {number} [x=1] - The horizontal scale of the emitted Particles. + * @param {number} [y=x] - The vertical scale of emitted Particles. If not set it will use the `x` value. + * + * @return {this} This Particle Emitter. */ - playPromiseSuccessHandler: function () + setParticleScale: function (x, y) { - this._codePaused = false; - this.touchLocked = false; + if (x === undefined) { x = 1; } + if (y === undefined) { y = x; } - this.emit(Events.VIDEO_PLAY, this); + this.ops.scaleX.onChange(x); + this.ops.scaleY.onChange(y); - if (this._markerIn > -1) - { - this.video.currentTime = this._markerIn; - } + return this; }, /** - * This internal method is called automatically if the playback Promise fails to resolve. + * Sets the gravity applied to emitted particles. * - * @method Phaser.GameObjects.Video#playPromiseErrorHandler - * @fires Phaser.GameObjects.Events#VIDEO_ERROR - * @private - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleGravity + * @since 3.60.0 * - * @param {any} error - The Promise resolution error. + * @param {number} x - Horizontal acceleration due to gravity, in pixels per second squared. Set to zero for no gravity. + * @param {number} y - Vertical acceleration due to gravity, in pixels per second squared. Set to zero for no gravity. + * + * @return {this} This Particle Emitter. */ - playPromiseErrorHandler: function (error) + setParticleGravity: function (x, y) { - this.scene.sys.input.once(InputEvents.POINTER_DOWN, this.unlockHandler, this); - - this.touchLocked = true; - this.playWhenUnlocked = true; + this.gravityX = x; + this.gravityY = y; - this.emit(Events.VIDEO_ERROR, this, error); + return this; }, /** - * Called when the video emits a `playing` event during load. + * Sets the opacity (alpha) of emitted particles. * - * This is only listened for if the browser doesn't support Promises. + * You can also set the alpha of the entire emitter via `setAlpha`. * - * @method Phaser.GameObjects.Video#playHandler - * @fires Phaser.GameObjects.Events#VIDEO_PLAY - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleAlpha + * @since 3.60.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. */ - playHandler: function () + setParticleAlpha: function (value) { - this._codePaused = false; - this.touchLocked = false; + this.ops.alpha.onChange(value); - this.emit(Events.VIDEO_PLAY, this); - - this.video.removeEventListener('playing', this._callbacks.play, true); + return this; }, /** - * This internal method is called automatically if the video fails to load. + * Sets the color tint of emitted particles. * - * @method Phaser.GameObjects.Video#loadErrorHandler - * @fires Phaser.GameObjects.Events#VIDEO_ERROR - * @private - * @since 3.20.0 + * This is a WebGL only feature. * - * @param {Event} event - The error Event. + * @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleTint + * @since 3.60.0 + * @webglOnly + * + * @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 and 0xffffff. + * + * @return {this} This Particle Emitter. */ - loadErrorHandler: function (event) + setParticleTint: function (value) { - this.stop(); + this.ops.tint.onChange(value); - this.emit(Events.VIDEO_ERROR, this, event); + return this; }, /** - * This internal method is called if the video couldn't be played because it was interaction locked - * by the browser, but an input event has since been received. + * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. * - * @method Phaser.GameObjects.Video#unlockHandler - * @fires Phaser.GameObjects.Events#VIDEO_UNLOCKED - * @fires Phaser.GameObjects.Events#VIDEO_PLAY - * @private - * @since 3.20.0 + * The value is given in degrees using Phaser's right-handed coordinate system. + * + * @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, in degrees. * - * @param {any} error - The Promise resolution error. + * @return {this} This Particle Emitter. */ - unlockHandler: function () + setEmitterAngle: function (value) { - this.touchLocked = false; - this.playWhenUnlocked = false; + this.ops.angle.onChange(value); - this.emit(Events.VIDEO_UNLOCKED, this); - - if (this._markerIn > -1) - { - this.video.currentTime = this._markerIn; - } + return this; + }, - this.video.play(); + /** + * Sets the lifespan of newly emitted particles in milliseconds. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleLifespan + * @since 3.60.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The lifespan of a particle, in ms. + * + * @return {this} This Particle Emitter. + */ + setParticleLifespan: function (value) + { + this.ops.lifespan.onChange(value); - this.emit(Events.VIDEO_PLAY, this); + return this; }, /** - * Called when the video completes playback, i.e. reaches an `ended` state. + * Sets the number of particles released at each flow cycle or explosion. * - * This will never happen if the video is coming from a live stream, where the duration is `Infinity`. + * @method Phaser.GameObjects.Particles.ParticleEmitter#setQuantity + * @since 3.0.0 * - * @method Phaser.GameObjects.Video#completeHandler - * @fires Phaser.GameObjects.Events#VIDEO_COMPLETE - * @since 3.20.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. */ - completeHandler: function () + setQuantity: function (quantity) { - this.emit(Events.VIDEO_COMPLETE, this); + this.quantity = quantity; + + return this; }, /** - * Called when the video emits a `timeUpdate` event during playback. + * 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 * - * This event is too slow and irregular to be used for actual video timing or texture updating, - * but we can use it to determine if a video has looped. + * @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. * - * @method Phaser.GameObjects.Video#timeUpdateHandler - * @fires Phaser.GameObjects.Events#VIDEO_LOOP - * @since 3.20.0 + * @return {this} This Particle Emitter. */ - timeUpdateHandler: function () + setFrequency: function (frequency, quantity) { - if (this.video && this.video.currentTime < this._lastUpdate) - { - this.emit(Events.VIDEO_LOOP, this); + this.frequency = frequency; - this._lastUpdate = 0; + this.flowCounter = (frequency > 0) ? frequency : 0; + + if (quantity) + { + this.quantity = quantity; } + + return this; }, /** - * The internal update step. + * Adds a new Particle Death Zone to this Emitter. * - * @method Phaser.GameObjects.Video#preUpdate - * @private - * @since 3.20.0 + * A particle is immediately killed as soon as its x/y coordinates intersect + * with any of the configured Death Zones. + * + * The `source` can be a Geometry Shape, such as a Circle, Rectangle or Triangle. + * Any valid object from the `Phaser.Geometry` namespace is allowed, as long as + * it supports a `contains` function. You can set the `type` to be either `onEnter` + * or `onLeave`. + * + * A single Death Zone instance can only exist once within this Emitter, but can belong + * to multiple Emitters. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#addDeathZone + * @since 3.60.0 + * + * @param {Phaser.Types.GameObjects.Particles.DeathZoneObject|Phaser.Types.GameObjects.Particles.DeathZoneObject[]} config - A Death Zone configuration object, a Death Zone instance, a valid Geometry object or an array of them. + * + * @return {Phaser.GameObjects.Particles.Zones.DeathZone} The Death Zone that was added to this Emitter. */ - preUpdate: function () + addDeathZone: function (config) { - var video = this.video; + if (!Array.isArray(config)) + { + config = [ config ]; + } - if (video) + var zone; + var deathZones = this.deathZones; + + for (var i = 0; i < config.length; i++) { - var currentTime = video.currentTime; + zone = config[i]; - // Don't render a new frame unless the video has actually changed time - if (currentTime !== this._lastUpdate) + if (zone instanceof DeathZone) + { + deathZones.push(zone); + } + else if (typeof zone.contains === 'function') { - this._lastUpdate = currentTime; + zone = new DeathZone(zone, true); - this.updateTexture(); + deathZones.push(zone); + } + else + { + var type = GetFastValue(zone, 'type', 'onEnter'); + var source = GetFastValue(zone, 'source', null); - if (currentTime >= this._markerOut) + if (source && typeof source.contains === 'function') { - if (video.loop) - { - video.currentTime = this._markerIn; - - this.updateTexture(); + var killOnEnter = (type === 'onEnter') ? true : false; - this._lastUpdate = currentTime; + zone = new DeathZone(source, killOnEnter); - this.emit(Events.VIDEO_LOOP, this); - } - else - { - this.emit(Events.VIDEO_COMPLETE, this); - - this.stop(); - } + deathZones.push(zone); } } } + + return zone; }, /** - * Internal callback that monitors the download progress of a video after changing its source. + * Removes the given Particle Death Zone from this Emitter. * - * @method Phaser.GameObjects.Video#checkVideoProgress - * @fires Phaser.GameObjects.Events#VIDEO_TIMEOUT - * @private - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#removeDeathZone + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.Zones.DeathZone} zone - The Death Zone that should be removed from this Emitter. + * + * @return {this} This Particle Emitter. + */ + removeDeathZone: function (zone) + { + Remove(this.deathZones, zone); + + return this; + }, + + /** + * Adds a new Particle Emission Zone to this Emitter. + * + * 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 the particles 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. + * + * An Emission Zone can only exist once within this Emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#addEmitZone + * @since 3.60.0 + * + * @param {Phaser.Types.GameObjects.Particles.EmitZoneObject|Phaser.Types.GameObjects.Particles.EmitZoneObject[]} zone - An Emission Zone configuration object, a RandomZone or EdgeZone instance, or an array of them. + * + * @return {Phaser.GameObjects.Particles.Zones.EdgeZone[]|Phaser.GameObjects.Particles.Zones.RandomZone[]} An array of the Emission Zones that were added to this Emitter. */ - checkVideoProgress: function () + addEmitZone: function (config) { - if (this.video.readyState >= 2) + if (!Array.isArray(config)) { - // We've got enough data to update the texture for playback - this.updateTexture(); + config = [ config ]; } - else + + var zone; + var emitZones = this.emitZones; + var output = []; + + for (var i = 0; i < config.length; i++) { - this.retry--; + zone = config[i]; - if (this.retry > 0) + if (zone instanceof RandomZone || zone instanceof EdgeZone) { - this._retryID = window.setTimeout(this.checkVideoProgress.bind(this), this.retryInterval); + emitZones.push(zone); } else { - this.emit(Events.VIDEO_TIMEOUT, this); + // 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], [total=1] } + + var type = GetFastValue(zone, 'type', 'random'); + var source = GetFastValue(zone, 'source', null); + + if (type === 'random') + { + zone = new RandomZone(source); + } + else if (type === 'edge') + { + var quantity = GetFastValue(zone, 'quantity', 1); + var stepRate = GetFastValue(zone, 'stepRate', 0); + var yoyo = GetFastValue(zone, 'yoyo', false); + var seamless = GetFastValue(zone, 'seamless', true); + var total = GetFastValue(zone, 'total', -1); + + zone = new EdgeZone(source, quantity, stepRate, yoyo, seamless, total); + } + + if (zone) + { + emitZones.push(zone); + } } + + output.push(zone); } + + return output; }, /** - * Internal method that is called when enough video data has been received in order to create a texture - * from it. The texture is assigned to the `Video.videoTexture` property and given a base frame that - * encompases the whole video size. + * Removes the given Particle Emission Zone from this Emitter. * - * @method Phaser.GameObjects.Video#updateTexture - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#removeEmitZone + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.Zones.EdgeZone|Phaser.GameObjects.Particles.Zones.RandomZone} zone - The Emission Zone that should be removed from this Emitter. + * + * @return {this} This Particle Emitter. */ - updateTexture: function () + removeEmitZone: function (zone) { - var video = this.video; + Remove(this.emitZones, zone); - var width = video.videoWidth; - var height = video.videoHeight; + this.zoneIndex = 0; - if (!this.videoTexture) - { - this.videoTexture = this.scene.sys.textures.create(this._key, video, width, height); - this.videoTextureSource = this.videoTexture.source[0]; - this.videoTexture.add('__BASE', 0, 0, 0, width, height); + return this; + }, - this.setTexture(this.videoTexture); - this.setSizeToFrame(); - this.updateDisplayOrigin(); + /** + * Takes the given particle and sets its x/y coordinates to match the next available + * emission zone, if any have been configured. This method is called automatically + * as part of the `Particle.fire` process. + * + * The Emit Zones are iterated in sequence. Once a zone has had a particle emitted + * from it, then the next zone is used and so on, in a loop. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getEmitZone + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle to set the emission zone for. + */ + getEmitZone: function (particle) + { + var zones = this.emitZones; + var len = zones.length; - this.emit(Events.VIDEO_CREATED, this, width, height); + if (len === 0) + { + return; } else { - var textureSource = this.videoTextureSource; + var zone = zones[this.zoneIndex]; - if (textureSource.source !== video) + zone.getPoint(particle); + + if (zone.total > -1) { - textureSource.source = video; - textureSource.width = width; - textureSource.height = height; - } + this.zoneTotal++; - textureSource.update(); - } - }, + if (this.zoneTotal === zone.total) + { + this.zoneTotal = 0; - /** - * Returns the key of the currently played video, as stored in the Video Cache. - * If the video did not come from the cache this will return an empty string. - * - * @method Phaser.GameObjects.Video#getVideoKey - * @since 3.20.0 - * - * @return {string} The key of the video being played from the Video Cache, if any. - */ - getVideoKey: function () - { - return this._cacheKey; + this.zoneIndex++; + + if (this.zoneIndex === len) + { + this.zoneIndex = 0; + } + } + } + } }, /** - * Seeks to a given point in the video. The value is given as a float between 0 and 1, - * where 0 represents the start of the video and 1 represents the end. - * - * Seeking only works if the video has a duration, so will not work for live streams. - * - * When seeking begins, this video will emit a `seeking` event. When the video completes - * seeking (i.e. reaches its designated timestamp) it will emit a `seeked` event. - * - * If you wish to seek based on time instead, use the `Video.setCurrentTime` method. + * Takes the given particle and checks to see if any of the configured Death Zones + * will kill it and returns the result. This method is called automatically as part + * of the `Particle.update` process. * - * @method Phaser.GameObjects.Video#seekTo - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#getDeathZone + * @fires Phaser.GameObjects.Particles.Events#DEATH_ZONE + * @since 3.60.0 * - * @param {number} value - The point in the video to seek to. A value between 0 and 1. + * @param {Phaser.GameObjects.Particles.Particle} particle - The particle to test against the Death Zones. * - * @return {this} This Video Game Object for method chaining. + * @return {boolean} `true` if the particle should be killed, otherwise `false`. */ - seekTo: function (value) + getDeathZone: function (particle) { - var video = this.video; + var zones = this.deathZones; - if (video) + for (var i = 0; i < zones.length; i++) { - var duration = video.duration; + var zone = zones[i]; - if (duration !== Infinity && !isNaN(duration)) + if (zone.willKill(particle)) { - var seekTime = duration * value; + this.emit(Events.DEATH_ZONE, this, particle, zone); - this.setCurrentTime(seekTime); + return true; } } - return this; + return false; }, /** - * A double-precision floating-point value indicating the current playback time in seconds. - * If the media has not started to play and has not been seeked, this value is the media's initial playback time. + * Changes the currently active Emission Zone. The zones should have already + * been added to this Emitter either via the emitter config, or the + * `addEmitZone` method. * - * @method Phaser.GameObjects.Video#getCurrentTime - * @since 3.20.0 + * Call this method by passing either a numeric zone index value, or + * the zone instance itself. * - * @return {number} A double-precision floating-point value indicating the current playback time in seconds. + * Prior to v3.60 an Emitter could only have a single Emit Zone and this + * method was how you set it. From 3.60 and up it now performs a different + * function and swaps between all available active zones. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone + * @since 3.0.0 + * + * @param {number|Phaser.GameObjects.Particles.Zones.EdgeZone|Phaser.GameObjects.Particles.Zones.RandomZone} zone - The Emit Zone to set as the active zone. + * + * @return {this} This Particle Emitter. */ - getCurrentTime: function () + setEmitZone: function (zone) { - return (this.video) ? this.video.currentTime : 0; + var index; + + if (isFinite(zone)) + { + index = zone; + } + else + { + index = this.emitZones.indexOf(zone); + } + + if (index >= 0) + { + this.zoneIndex = index; + } + + return this; }, /** - * Seeks to a given playback time in the video. The value is given in _seconds_ or as a string. - * - * Seeking only works if the video has a duration, so will not work for live streams. - * - * When seeking begins, this video will emit a `seeking` event. When the video completes - * seeking (i.e. reaches its designated timestamp) it will emit a `seeked` event. + * Adds a Particle Processor, such as a Gravity Well, to this Emitter. * - * You can provide a string prefixed with either a `+` or a `-`, such as `+2.5` or `-2.5`. - * In this case it will seek to +/- the value given, relative to the _current time_. - * - * If you wish to seek based on a duration percentage instead, use the `Video.seekTo` method. + * It will start processing particles from the next update as long as its `active` + * property is set. * - * @method Phaser.GameObjects.Video#setCurrentTime - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#addParticleProcessor + * @since 3.60.0 * - * @param {(string|number)} value - The playback time to seek to in seconds. Can be expressed as a string, such as `+2` to seek 2 seconds ahead from the current time. + * @generic {Phaser.GameObjects.Particles.ParticleProcessor} T + * @param {T} processor - The Particle Processor to add to this Emitter Manager. * - * @return {this} This Video Game Object for method chaining. + * @return {T} The Particle Processor that was added to this Emitter Manager. */ - setCurrentTime: function (value) + addParticleProcessor: function (processor) { - var video = this.video; - - if (video) + if (!this.processors.exists(processor)) { - if (typeof value === 'string') + if (processor.emitter) { - var op = value[0]; - var num = parseFloat(value.substr(1)); - - if (op === '+') - { - value = video.currentTime + num; - } - else if (op === '-') - { - value = video.currentTime - num; - } + processor.emitter.removeParticleProcessor(processor); } - video.currentTime = value; + this.processors.add(processor); - this._lastUpdate = value; + processor.emitter = this; } - return this; + return processor; }, /** - * Returns a boolean indicating if this Video is currently seeking, or not. + * Removes a Particle Processor from this Emitter. * - * @method Phaser.GameObjects.Video#isSeeking - * @since 3.20.0 + * The Processor must belong to this Emitter to be removed. + * + * It is not destroyed when removed, allowing you to move it to another Emitter Manager, + * so if you no longer require it you should call its `destroy` method directly. * - * @return {boolean} A boolean indicating if this Video is currently seeking, or not. + * @method Phaser.GameObjects.Particles.ParticleEmitter#removeParticleProcessor + * @since 3.60.0 + * + * @generic {Phaser.GameObjects.Particles.ParticleProcessor} T + * @param {T} processor - The Particle Processor to remove from this Emitter Manager. + * + * @return {?T} The Particle Processor that was removed, or null if it could not be found. */ - isSeeking: function () + removeParticleProcessor: function (processor) { - return this._isSeeking; + if (this.processors.exists(processor)) + { + this.processors.remove(processor, true); + + processor.emitter = null; + } + + return processor; }, /** - * Internal seeking handler. + * Gets all active Particle Processors. * - * @method Phaser.GameObjects.Video#seekingHandler - * @fires Phaser.GameObjects.Events#VIDEO_SEEKING - * @private - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#getProcessors + * @since 3.60.0 + * + * @return {Phaser.GameObjects.Particles.ParticleProcessor[]} - An array of active Particle Processors. */ - seekingHandler: function () + getProcessors: function () { - this._isSeeking = true; - - this.emit(Events.VIDEO_SEEKING, this); + return this.processors.getAll('active', true); }, /** - * Internal seeked handler. + * Creates a new Gravity Well, adds it to this Emitter and returns a reference to it. * - * @method Phaser.GameObjects.Video#seekedHandler - * @fires Phaser.GameObjects.Events#VIDEO_SEEKED - * @private - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#createGravityWell + * @since 3.60.0 + * + * @param {Phaser.Types.GameObjects.Particles.GravityWellConfig} config - Configuration settings for the Gravity Well to create. + * + * @return {Phaser.GameObjects.Particles.GravityWell} The Gravity Well that was created. */ - seekedHandler: function () + createGravityWell: function (config) { - this._isSeeking = false; - - this.emit(Events.VIDEO_SEEKED, this); - - var video = this.video; - - if (video) - { - this.updateTexture(); - } + return this.addParticleProcessor(new GravityWell(config)); }, /** - * Returns the current progress of the video. Progress is defined as a value between 0 (the start) - * and 1 (the end). + * Creates inactive particles and adds them to this emitter's pool. * - * Progress can only be returned if the video has a duration, otherwise it will always return zero. + * If `ParticleEmitter.maxParticles` is set it will limit the + * value passed to this method to make sure it's not exceeded. * - * @method Phaser.GameObjects.Video#getProgress - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#reserve + * @since 3.0.0 * - * @return {number} The current progress of playback. If the video has no duration, will always return zero. + * @param {number} count - The number of particles to create. + * + * @return {this} This Particle Emitter. */ - getProgress: function () + reserve: function (count) { - var video = this.video; + var dead = this.dead; - if (video) + if (this.maxParticles > 0) { - var now = video.currentTime; - var duration = video.duration; + var total = this.getParticleCount(); - if (duration !== Infinity && !isNaN(duration)) + if (total + count > this.maxParticles) { - return now / duration; + count = this.maxParticles - (total + count); } } - return 0; + for (var i = 0; i < count; i++) + { + dead.push(new this.particleClass(this)); + } + + return this; }, /** - * A double-precision floating-point value which indicates the duration (total length) of the media in seconds, - * on the media's timeline. If no media is present on the element, or the media is not valid, the returned value is NaN. - * - * If the media has no known end (such as for live streams of unknown duration, web radio, media incoming from WebRTC, - * and so forth), this value is +Infinity. + * Gets the number of active (in-use) particles in this emitter. * - * @method Phaser.GameObjects.Video#getDuration - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#getAliveParticleCount + * @since 3.0.0 * - * @return {number} A double-precision floating-point value indicating the duration of the media in seconds. + * @return {number} The number of particles with `active=true`. */ - getDuration: function () + getAliveParticleCount: function () { - return (this.video) ? this.video.duration : 0; + return this.alive.length; }, /** - * Sets the muted state of the currently playing video, if one is loaded. - * - * @method Phaser.GameObjects.Video#setMute - * @since 3.20.0 + * Gets the number of inactive (available) particles in this emitter. * - * @param {boolean} [value=true] - The mute value. `true` if the video should be muted, otherwise `false`. + * @method Phaser.GameObjects.Particles.ParticleEmitter#getDeadParticleCount + * @since 3.0.0 * - * @return {this} This Video Game Object for method chaining. + * @return {number} The number of particles with `active=false`. */ - setMute: function (value) + getDeadParticleCount: function () { - if (value === undefined) { value = true; } - - this._codeMuted = value; - - var video = this.video; - - if (video) - { - video.muted = (this._systemMuted) ? true : value; - } - - return this; + return this.dead.length; }, /** - * Returns a boolean indicating if this Video is currently muted. + * Gets the total number of particles in this emitter. * - * @method Phaser.GameObjects.Video#isMuted - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#getParticleCount + * @since 3.0.0 * - * @return {boolean} A boolean indicating if this Video is currently muted, or not. + * @return {number} The number of particles, including both alive and dead. */ - isMuted: function () + getParticleCount: function () { - return this._codeMuted; + return this.getAliveParticleCount() + this.getDeadParticleCount(); }, /** - * Internal global mute handler. Will mute the video, if playing, if the global sound system mutes. + * Whether this emitter is at either its hard-cap limit (maxParticles), if set, or + * the max allowed number of 'alive' particles (maxAliveParticles). * - * @method Phaser.GameObjects.Video#globalMute - * @private - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#atLimit + * @since 3.0.0 * - * @param {(Phaser.Sound.WebAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager)} soundManager - A reference to the Sound Manager that emitted the event. - * @param {boolean} mute - The mute value. `true` if the Sound Manager is now muted, otherwise `false`. + * @return {boolean} Returns `true` if this Emitter is at its limit, or `false` if no limit, or below the `maxParticles` level. */ - globalMute: function (soundManager, value) + atLimit: function () { - this._systemMuted = value; + if (this.maxParticles > 0 && this.getParticleCount() >= this.maxParticles) + { + return true; + } - var video = this.video; + return (this.maxAliveParticles > 0 && this.getAliveParticleCount() >= this.maxAliveParticles); + }, - if (video) + /** + * 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) { - video.muted = (this._codeMuted) ? true : value; + // 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; }, /** - * Internal global pause handler. Will pause the video if the Game itself pauses. + * Sets a function to call for each particle death. * - * @method Phaser.GameObjects.Video#globalPause - * @private - * @since 3.20.0 + * @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. */ - globalPause: function () + onParticleDeath: function (callback, context) { - this._systemPaused = true; - - if (this.video) + if (callback === undefined) { - this.video.pause(); + // 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; }, /** - * Internal global resume handler. Will resume a paused video if the Game itself resumes. + * Deactivates every particle in this emitter immediately. * - * @method Phaser.GameObjects.Video#globalResume - * @private - * @since 3.20.0 + * This particles are killed but do not emit an event or callback. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#killAll + * @since 3.0.0 + * + * @return {this} This Particle Emitter. */ - globalResume: function () + killAll: function () { - this._systemPaused = false; + var dead = this.dead; + var alive = this.alive; - if (this.video && !this._codePaused) + while (alive.length > 0) { - this.video.play(); + dead.push(alive.pop()); } + + return this; }, /** - * Sets the paused state of the currently loaded video. + * Calls a function for each active particle in this emitter. The function is + * sent two parameters: a reference to the Particle instance and to this Emitter. * - * If the video is playing, calling this method with `true` will pause playback. - * If the video is paused, calling this method with `false` will resume playback. + * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachAlive + * @since 3.0.0 * - * If no video is loaded, this method does nothing. + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. + * @param {*} context - The functions calling context. * - * @method Phaser.GameObjects.Video#setPaused - * @since 3.20.0 + * @return {this} This Particle Emitter. + */ + forEachAlive: function (callback, context) + { + var alive = this.alive; + var length = alive.length; + + for (var i = 0; i < length; i++) + { + // Sends the Particle and the Emitter + callback.call(context, alive[i], this); + } + + return this; + }, + + /** + * Calls a function for each inactive particle in this emitter. * - * @param {boolean} [value=true] - The paused value. `true` if the video should be paused, `false` to resume it. + * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachDead + * @since 3.0.0 * - * @return {this} This Video Game Object for method chaining. + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function. + * @param {*} context - The functions calling context. + * + * @return {this} This Particle Emitter. */ - setPaused: function (value) + forEachDead: function (callback, context) { - if (value === undefined) { value = true; } + var dead = this.dead; + var length = dead.length; - var video = this.video; + for (var i = 0; i < length; i++) + { + callback.call(context, dead[i], this); + } - this._codePaused = value; + return this; + }, - if (video) + /** + * 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. + * + * Calling this method will emit the `START` event. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#start + * @fires Phaser.GameObjects.Particles.Events#START + * @since 3.0.0 + * + * @param {number} [advance=0] - Advance this number of ms in time through the emitter. + * @param {number} [duration=0] - Limit this emitter to only emit particles for the given number of ms. Setting this parameter will override any duration already set in the Emitter configuration object. + * + * @return {this} This Particle Emitter. + */ + start: function (advance, duration) + { + if (advance === undefined) { advance = 0; } + + if (!this.emitting) { - if (value) + if (advance > 0) { - if (!video.paused) - { - video.pause(); - } + this.fastForward(advance); } - else if (!value) + + this.emitting = true; + + this.resetCounters(this.frequency, true); + + if (duration !== undefined) { - if (video.paused && !this._systemPaused) - { - video.play(); - } + this.duration = Math.abs(duration); } + + this.emit(Events.START, this); } return this; }, /** - * Returns a double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). + * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#emitting off} the emitter and + * stops it from emitting further particles. Currently alive particles will remain + * active until they naturally expire unless you set the `kill` parameter to `true`. * - * @method Phaser.GameObjects.Video#getVolume - * @since 3.20.0 + * Calling this method will emit the `STOP` event. When the final particle has + * expired the `COMPLETE` event will be emitted. * - * @return {number} A double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). + * @method Phaser.GameObjects.Particles.ParticleEmitter#stop + * @fires Phaser.GameObjects.Particles.Events#STOP + * @since 3.11.0 + * + * @param {boolean} [kill=false] - Kill all particles immediately (true), or leave them to die after their lifespan expires? (false, the default) + * + * @return {this} This Particle Emitter. */ - getVolume: function () + stop: function (kill) { - return (this.video) ? this.video.volume : 1; + if (kill === undefined) { kill = false; } + + if (this.emitting) + { + this.emitting = false; + + if (kill) + { + this.killAll(); + } + + this.emit(Events.STOP, this); + } + + return this; }, /** - * Sets the volume of the currently playing video. + * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Deactivates} the emitter. * - * The value given is a double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). + * @method Phaser.GameObjects.Particles.ParticleEmitter#pause + * @since 3.0.0 * - * @method Phaser.GameObjects.Video#setVolume - * @since 3.20.0 + * @return {this} This Particle Emitter. + */ + pause: function () + { + this.active = false; + + return this; + }, + + /** + * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Activates} the emitter. * - * @param {number} [value=1] - A double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). + * @method Phaser.GameObjects.Particles.ParticleEmitter#resume + * @since 3.0.0 * - * @return {this} This Video Game Object for method chaining. + * @return {this} This Particle Emitter. */ - setVolume: function (value) + resume: function () { - if (value === undefined) { value = 1; } - - if (this.video) - { - this.video.volume = Clamp(value, 0, 1); - } + this.active = true; return this; }, /** - * Returns a double that indicates the rate at which the media is being played back. + * Set the property by which active particles are sorted prior to be rendered. * - * @method Phaser.GameObjects.Video#getPlaybackRate - * @since 3.20.0 + * It allows you to control the rendering order of the particles. * - * @return {number} A double that indicates the rate at which the media is being played back. + * This can be any valid property of the `Particle` class, such as `y`, `alpha` + * or `lifeT`. + * + * The 'alive' particles array is sorted in place each game frame. Setting a + * sort property will override the `particleBringToTop` setting. + * + * If you wish to use your own sorting function, see `setSortCallback` instead. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setSortProperty + * @since 3.60.0 + * + * @param {string} [property] - The property on the `Particle` class to sort by. + * @param {boolean} [ascending=true] - Should the particles be sorted in ascending or descending order? + * + * @return {this} This Particle Emitter. */ - getPlaybackRate: function () + setSortProperty: function (property, ascending) { - return (this.video) ? this.video.playbackRate : 1; + if (property === undefined) { property = ''; } + if (ascending === undefined) { ascending = this.true; } + + this.sortProperty = property; + this.sortOrderAsc = ascending; + this.sortCallback = this.depthSortCallback; + + return this; }, /** - * Sets the playback rate of the current video. + * Sets a callback to be used to sort the particles before rendering each frame. * - * The value given is a double that indicates the rate at which the media is being played back. + * This allows you to define your own logic and behavior in the callback. * - * @method Phaser.GameObjects.Video#setPlaybackRate - * @since 3.20.0 + * The callback will be sent two parameters: the two Particles being compared, + * and must adhere to the criteria of the `compareFn` in `Array.sort`: * - * @param {number} [rate] - A double that indicates the rate at which the media is being played back. + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description * - * @return {this} This Video Game Object for method chaining. + * Call this method with no parameters to reset the sort callback. + * + * Setting your own callback will override both the `particleBringToTop` and + * `sortProperty` settings of this Emitter. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#setSortCallback + * @since 3.60.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleSortCallback} [callback] - The callback to invoke when the particles are sorted. Leave undefined to reset to the default. + * + * @return {this} This Particle Emitter. */ - setPlaybackRate: function (rate) + setSortCallback: function (callback) { - if (this.video) + if (this.sortProperty !== '') { - this.video.playbackRate = rate; + callback = this.depthSortCallback; + } + else + { + callback = null; } + this.sortCallback = callback; + return this; }, /** - * Returns a boolean which indicates whether the media element should start over when it reaches the end. + * Sorts active particles with {@link Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback}. * - * @method Phaser.GameObjects.Video#getLoop - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSort + * @since 3.0.0 * - * @return {boolean} A boolean which indicates whether the media element will start over when it reaches the end. + * @return {this} This Particle Emitter. */ - getLoop: function () + depthSort: function () { - return (this.video) ? this.video.loop : false; + StableSort(this.alive, this.sortCallback.bind(this)); + + return this; }, /** - * Sets the loop state of the current video. + * Calculates the difference of two particles, for sorting them by depth. * - * The value given is a boolean which indicates whether the media element will start over when it reaches the end. + * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback + * @since 3.0.0 * - * Not all videos can loop, for example live streams. + * @param {object} a - The first particle. + * @param {object} b - The second particle. * - * Please note that not all browsers support _seamless_ video looping for all encoding formats. + * @return {number} The difference of a and b's y coordinates. + */ + depthSortCallback: function (a, b) + { + var key = this.sortProperty; + + if (this.sortOrderAsc) + { + return a[key] - b[key]; + } + else + { + return b[key] - a[key]; + } + }, + + /** + * Puts the emitter in flow mode (frequency >= 0) and starts (or restarts) a particle flow. * - * @method Phaser.GameObjects.Video#setLoop - * @since 3.20.0 + * To resume a flow at the current frequency and quantity, use {@link Phaser.GameObjects.Particles.ParticleEmitter#start} instead. * - * @param {boolean} [value=true] - A boolean which indicates whether the media element will start over when it reaches the end. + * @method Phaser.GameObjects.Particles.ParticleEmitter#flow + * @fires Phaser.GameObjects.Particles.Events#START + * @since 3.0.0 * - * @return {this} This Video Game Object for method chaining. + * @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. + * @param {number} [stopAfter] - Stop this emitter from firing any more particles once this value is reached. Set to zero for unlimited. Setting this parameter will override any `stopAfter` value already set in the Emitter configuration object. + * + * @return {this} This Particle Emitter. */ - setLoop: function (value) + flow: function (frequency, count, stopAfter) { - if (value === undefined) { value = true; } + if (count === undefined) { count = 1; } - if (this.video) + this.emitting = false; + + this.frequency = frequency; + this.quantity = count; + + if (stopAfter !== undefined) { - this.video.loop = value; + this.stopAfter = stopAfter; } - return this; + return this.start(); }, /** - * Returns a boolean which indicates whether the video is currently playing. + * Puts the emitter in explode mode (frequency = -1), stopping any current particle flow, and emits several particles all at once. * - * @method Phaser.GameObjects.Video#isPlaying - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#explode + * @fires Phaser.GameObjects.Particles.Events#EXPLODE + * @since 3.0.0 * - * @return {boolean} A boolean which indicates whether the video is playing, or not. + * @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. */ - isPlaying: function () + explode: function (count, x, y) { - return (this.video) ? !(this.video.paused || this.video.ended) : false; + this.frequency = -1; + + this.resetCounters(-1, true); + + var particle = this.emitParticle(count, x, y); + + this.emit(Events.EXPLODE, this, particle); + + return particle; }, /** - * Returns a boolean which indicates whether the video is currently paused. + * Emits particles at the given position. If no position is given, it will + * emit from this Emitters current location. * - * @method Phaser.GameObjects.Video#isPaused - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticleAt + * @since 3.0.0 * - * @return {boolean} A boolean which indicates whether the video is paused, or not. + * @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. */ - isPaused: function () + emitParticleAt: function (x, y, count) { - return ((this.video && this.video.paused) || this._codePaused || this._systemPaused); + return this.emitParticle(count, x, y); }, /** - * Stores this Video in the Texture Manager using the given key as a dynamic texture, - * which any texture-based Game Object, such as a Sprite, can use as its texture: - * - * ```javascript - * var vid = this.add.video(0, 0, 'intro'); + * Emits particles at a given position (or the emitters current position). * - * vid.play(); + * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticle + * @since 3.0.0 * - * vid.saveTexture('doodle'); + * @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. * - * this.add.image(400, 300, 'doodle'); - * ``` + * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. * - * The saved texture is automatically updated as the video plays. If you pause this video, - * or change its source, then the saved texture updates instantly. + * @see Phaser.GameObjects.Particles.Particle#fire + */ + emitParticle: function (count, x, y) + { + if (this.atLimit()) + { + return; + } + + if (count === undefined) + { + count = this.ops.quantity.onEmit(); + } + + var dead = this.dead; + var stopAfter = this.stopAfter; + + 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); + } + + if (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); + } + } + else + { + this.dead.push(particle); + } + + if (stopAfter > 0) + { + this.stopCounter++; + + if (this.stopCounter >= stopAfter) + { + break; + } + } + + if (this.atLimit()) + { + break; + } + } + + return particle; + }, + + /** + * Fast forwards this Particle Emitter and all of its particles. * - * Calling `saveTexture` again will not save another copy of the same texture, it will just rename the existing one. + * Works by running the Emitter `preUpdate` handler in a loop until the `time` + * has been reached at `delta` steps per loop. * - * By default it will create a single base texture. You can add frames to the texture - * by using the `Texture.add` method. After doing this, you can then allow Game Objects - * to use a specific frame. + * All callbacks and emitter related events that would normally be fired + * will still be invoked. * - * If you intend to save the texture so you can use it as the input for a Shader, you may need to set the - * `flipY` parameter to `true` if you find the video renders upside down in your shader. + * You can make an emitter 'fast forward' via the emitter config using the + * `advance` property. Set this value to the number of ms you wish the + * emitter to be fast-forwarded by. Or, call this method post-creation. * - * @method Phaser.GameObjects.Video#saveTexture - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#fastForward + * @since 3.60.0 * - * @param {string} key - The unique key to store the texture as within the global Texture Manager. - * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y` during upload? + * @param {number} time - The number of ms to advance the Particle Emitter by. + * @param {number} [delta] - The amount of delta to use for each step. Defaults to 1000 / 60. * - * @return {Phaser.Textures.Texture} The Texture that was saved. + * @return {this} This Particle Emitter. */ - saveTexture: function (key, flipY) + fastForward: function (time, delta) { - if (flipY === undefined) { flipY = false; } - - if (this.videoTexture) - { - this.scene.sys.textures.renameTexture(this._key, key); - } + if (delta === undefined) { delta = 1000 / 60; } - this._key = key; + var total = 0; - this.flipY = flipY; + this.skipping = true; - if (this.videoTextureSource) + while (total < Math.abs(time)) { - this.videoTextureSource.setFlipY(flipY); + this.preUpdate(0, delta); + + total += delta; } - return this.videoTexture; + this.skipping = false; + + return this; }, /** - * Stops the video playing and clears all internal event listeners. - * - * If you only wish to pause playback of the video, and resume it a later time, use the `Video.pause` method instead. - * - * If the video hasn't finished downloading, calling this method will not abort the download. To do that you need to - * call `destroy` instead. + * Updates this emitter and its particles. * - * @method Phaser.GameObjects.Video#stop - * @fires Phaser.GameObjects.Events#VIDEO_STOP - * @since 3.20.0 + * @method Phaser.GameObjects.Particles.ParticleEmitter#preUpdate + * @fires Phaser.GameObjects.Particles.Events#COMPLETE + * @since 3.0.0 * - * @return {this} This Video Game Object for method chaining. + * @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. */ - stop: function () + preUpdate: function (time, delta) { - var video = this.video; + // Scale the delta + delta *= this.timeScale; - if (video) + var step = (delta / 1000); + + if (this.trackVisible) { - var callbacks = this._callbacks; + this.visible = this.follow.visible; + } - for (var callback in callbacks) + this.getWorldTransformMatrix(this.worldMatrix); + + // Any particle processors? + var processors = this.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)) { - video.removeEventListener(callback, callbacks[callback], true); + rip.push({ index: i, particle: particle }); } + } - video.pause(); + // 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.setPosition(); + } + } + + if (!this.emitting && !this.skipping) + { + if (this.completeFlag === 1 && particles.length === 0) + { + this.completeFlag = 0; + + this.emit(Events.COMPLETE, this); + } + + return; } - if (this._retryID) + if (this.frequency === 0) { - window.clearTimeout(this._retryID); + this.emitParticle(); } + else if (this.frequency > 0) + { + this.flowCounter -= delta; - this.emit(Events.VIDEO_STOP, this); + while (this.flowCounter <= 0) + { + // Emits the 'quantity' number of particles + this.emitParticle(); - return this; + // counter = frequency - remainder from previous delta + this.flowCounter += this.frequency; + } + } + + // Duration or stopAfter set? + if (!this.skipping) + { + if (this.duration > 0) + { + // elapsed + this.elapsed += delta; + + if (this.elapsed >= this.duration) + { + this.stop(); + } + } + + if (this.stopAfter > 0 && this.stopCounter >= this.stopAfter) + { + this.stop(); + } + } }, /** - * Removes the Video element from the DOM by calling parentNode.removeChild on itself. + * Takes either a Rectangle Geometry object or an Arcade Physics Body and tests + * to see if it intersects with any currently alive Particle in this Emitter. * - * Also removes the autoplay and src attributes and nulls the Video reference. + * Overlapping particles are returned in an array, where you can perform further + * processing on them. If nothing overlaps then the array will be empty. * - * You should not call this method if you were playing a video from the Video Cache that - * you wish to play again in your game, or if another Video object is also using the same - * video. + * @method Phaser.GameObjects.Particles.ParticleEmitter#overlap + * @since 3.60.0 * - * If you loaded an external video via `Video.loadURL` then you should call this function - * to clear up once you are done with the instance. + * @param {(Phaser.Geom.Rectangle|Phaser.Physics.Arcade.Body)} target - A Rectangle or Arcade Physics Body to check for intersection against all alive particles. * - * @method Phaser.GameObjects.Video#removeVideoElement - * @since 3.20.0 + * @return {Phaser.GameObjects.Particles.Particle[]} An array of Particles that overlap with the given target. */ - removeVideoElement: function () + overlap: function (target) { - var video = this.video; + var matrix = this.getWorldTransformMatrix(); - if (!video) + var alive = this.alive; + var length = alive.length; + + var output = []; + + for (var i = 0; i < length; i++) { - return; + var particle = alive[i]; + + if (RectangleToRectangle(target, particle.getBounds(matrix))) + { + output.push(particle); + } } - if (video.parentNode) + return output; + }, + + /** + * Returns a bounds Rectangle calculated from the bounds of all currently + * _active_ Particles in this Emitter. If this Emitter has only just been + * created and not yet rendered, then calling this method will return a Rectangle + * with a max safe integer for dimensions. Use the `advance` parameter to + * avoid this. + * + * Typically it takes a few seconds for a flow Emitter to 'warm up'. You can + * use the `advance` and `delta` parameters to force the Emitter to + * 'fast forward' in time to try and allow the bounds to be more accurate, + * as it will calculate the bounds based on the particle bounds across all + * timesteps, giving a better result. + * + * You can also use the `padding` parameter to increase the size of the + * bounds. Emitters with a lot of randomness in terms of direction or lifespan + * can often return a bounds smaller than their possible maximum. By using + * the `padding` (and `advance` if needed) you can help limit this. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#getBounds + * @since 3.60.0 + * + * @param {number} [padding] - The amount of padding, in pixels, to add to the bounds Rectangle. + * @param {number} [advance] - The number of ms to advance the Particle Emitter by. Defaults to 0, i.e. not used. + * @param {number} [delta] - The amount of delta to use for each step. Defaults to 1000 / 60. + * @param {Phaser.Geom.Rectangle} [output] - The Rectangle to store the results in. If not given a new one will be created. + * + * @return {Phaser.Geom.Rectangle} A Rectangle containing the calculated bounds of this Emitter. + */ + getBounds: function (padding, advance, delta, output) + { + if (padding === undefined) { padding = 0; } + if (advance === undefined) { advance = 0; } + if (delta === undefined) { delta = 1000 / 60; } + if (output === undefined) { output = new Rectangle(); } + + var matrix = this.getWorldTransformMatrix(); + + var i; + var bounds; + var alive = this.alive; + var setFirst = false; + + output.setTo(0, 0, 0, 0); + + if (advance > 0) { - video.parentNode.removeChild(video); + var total = 0; + + this.skipping = true; + + while (total < Math.abs(advance)) + { + this.preUpdate(0, delta); + + for (i = 0; i < alive.length; i++) + { + bounds = alive[i].getBounds(matrix); + + if (!setFirst) + { + setFirst = true; + + CopyFrom(bounds, output); + } + else + { + MergeRect(output, bounds); + } + } + + total += delta; + } + + this.skipping = false; + } + else + { + for (i = 0; i < alive.length; i++) + { + bounds = alive[i].getBounds(matrix); + + if (!setFirst) + { + setFirst = true; + + CopyFrom(bounds, output); + } + else + { + MergeRect(output, bounds); + } + } } - while (video.hasChildNodes()) + if (padding > 0) { - video.removeChild(video.firstChild); + Inflate(output, padding, padding); } - video.removeAttribute('autoplay'); - video.removeAttribute('src'); + return output; + }, - this.video = null; + /** + * Prints a warning to the console if you mistakenly call this function + * thinking it works the same way as Phaser v3.55. + * + * @method Phaser.GameObjects.Particles.ParticleEmitter#createEmitter + * @since 3.60.0 + */ + createEmitter: function () + { + throw new Error('createEmitter removed. See ParticleEmitter docs for info'); }, /** - * Handles the pre-destroy step for the Video object. + * The x coordinate the particles are emitted from. * - * This calls `Video.stop` and optionally `Video.removeVideoElement`. + * This is relative to the Emitters x coordinate and that of any parent. * - * If any Sprites are using this Video as their texture it is up to you to manage those. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @method Phaser.GameObjects.Video#preDestroy - * @private - * @since 3.21.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleX + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 */ - preDestroy: function () - { - this.stop(); + particleX: { - if (this.removeVideoElementOnDestroy) + get: function () { - this.removeVideoElement(); - } + return this.ops.x.current; + }, - var game = this.scene.sys.game.events; + set: function (value) + { + this.ops.x.onChange(value); + } - game.off(GameEvents.PAUSE, this.globalPause, this); - game.off(GameEvents.RESUME, this.globalResume, this); + }, - var sound = this.scene.sys.sound; + /** + * The y coordinate the particles are emitted from. + * + * This is relative to the Emitters x coordinate and that of any parent. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleY + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + particleY: { - if (sound) + get: function () { - sound.off(SoundEvents.GLOBAL_MUTE, this.globalMute, this); - } + return this.ops.y.current; + }, - if (this._retryID) + set: function (value) { - window.clearTimeout(this._retryID); + this.ops.y.onChange(value); } - } -}); + }, -module.exports = Video; + /** + * The horizontal acceleration applied to emitted particles, in pixels per second squared. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationX + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + accelerationX: { + get: function () + { + return this.ops.accelerationX.current; + }, -/***/ }), -/* 227 */ -/***/ (function(module, exports, __webpack_require__) { + set: function (value) + { + this.ops.accelerationX.onChange(value); + } -/** - * @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__(228); -var GetPoints = __webpack_require__(470); -var GEOM_CONST = __webpack_require__(56); + /** + * The vertical acceleration applied to emitted particles, in pixels per second squared. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationY + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + accelerationY: { -/** - * @classdesc - * A Polygon object - * - * The polygon is a closed shape consists of a series of connected straight lines defined by list of ordered points. - * Several formats are supported to define the list of points, check the setTo method for details. - * This is a geometry object allowing you to define and inspect the shape. - * It is not a Game Object, in that you cannot add it to the display list, and it has no texture. - * To render a Polygon you should look at the capabilities of the Graphics class. - * - * @class Polygon - * @memberof Phaser.Geom - * @constructor - * @since 3.0.0 - * - * @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - List of points defining the perimeter of this Polygon. Several formats are supported: - * - A string containing paired x y values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'` - * - An array of Point objects: `[new Phaser.Point(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], ...]` - */ -var Polygon = new Class({ + get: function () + { + return this.ops.accelerationY.current; + }, - initialize: + set: function (value) + { + this.ops.accelerationY.onChange(value); + } - function Polygon (points) - { - /** - * The geometry constant type of this object: `GEOM_CONST.POLYGON`. - * Used for fast type comparisons. - * - * @name Phaser.Geom.Polygon#type - * @type {number} - * @readonly - * @since 3.19.0 - */ - this.type = GEOM_CONST.POLYGON; + }, - /** - * The area of this Polygon. - * - * @name Phaser.Geom.Polygon#area - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.area = 0; + /** + * The maximum horizontal velocity emitted particles can reach, in pixels per second squared. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityX + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + * @default 10000 + */ + maxVelocityX: { - /** - * An array of number pair objects that make up this polygon. I.e. [ {x,y}, {x,y}, {x,y} ] - * - * @name Phaser.Geom.Polygon#points - * @type {Phaser.Geom.Point[]} - * @since 3.0.0 - */ - this.points = []; + get: function () + { + return this.ops.maxVelocityX.current; + }, - if (points) + set: function (value) { - this.setTo(points); + this.ops.maxVelocityX.onChange(value); } + }, /** - * Check to see if the Polygon contains the given x / y coordinates. - * - * @method Phaser.Geom.Polygon#contains - * @since 3.0.0 + * The maximum vertical velocity emitted particles can reach, in pixels per second squared. * - * @param {number} x - The x coordinate to check within the polygon. - * @param {number} y - The y coordinate to check within the polygon. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @return {boolean} `true` if the coordinates are within the polygon, otherwise `false`. + * @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityY + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + * @default 10000 */ - contains: function (x, y) - { - return Contains(this, x, y); + maxVelocityY: { + + get: function () + { + return this.ops.maxVelocityY.current; + }, + + set: function (value) + { + this.ops.maxVelocityY.onChange(value); + } + }, /** - * Sets this Polygon to the given points. + * The initial speed of emitted particles, in pixels per second. * - * The points can be set from a variety of formats: + * If using this as a getter it will return the `speedX` value. * - * - 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 objects: `[new Phaser.Point(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], ...]` + * If using it as a setter it will update both `speedX` and `speedY` to the + * given value. * - * `setTo` may also be called without any arguments to remove all points. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @method Phaser.Geom.Polygon#setTo - * @since 3.0.0 + * @name Phaser.GameObjects.Particles.ParticleEmitter#speed + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + speed: { + + get: function () + { + return this.ops.speedX.current; + }, + + set: function (value) + { + this.ops.speedX.onChange(value); + this.ops.speedY.onChange(value); + } + + }, + + /** + * The initial horizontal speed of emitted particles, in pixels per second. * - * @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - Points defining the perimeter of this polygon. Please check function description above for the different supported formats. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @return {this} This Polygon object. + * @name Phaser.GameObjects.Particles.ParticleEmitter#speedX + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 */ - setTo: function (points) - { - this.area = 0; - this.points = []; + speedX: { - if (typeof points === 'string') + get: function () { - points = points.split(' '); - } + return this.ops.speedX.current; + }, - if (!Array.isArray(points)) + set: function (value) { - return this; + this.ops.speedX.onChange(value); } - var p; - var y0 = Number.MAX_VALUE; + }, - // The points argument is an array, so iterate through it - for (var i = 0; i < points.length; i++) + /** + * The initial vertical speed of emitted particles, in pixels per second. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#speedY + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + speedY: { + + get: function () { - p = { x: 0, y: 0 }; + return this.ops.speedY.current; + }, - if (typeof points[i] === 'number' || typeof points[i] === 'string') - { - p.x = parseFloat(points[i]); - p.y = parseFloat(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; - } + set: function (value) + { + this.ops.speedY.onChange(value); + } - this.points.push(p); + }, - // Lowest boundary - if (p.y < y0) - { - y0 = p.y; - } - } + /** + * The x coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToX + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + moveToX: { - this.calculateArea(y0); + get: function () + { + return this.ops.moveToX.current; + }, + + set: function (value) + { + this.ops.moveToX.onChange(value); + } - return this; }, /** - * Calculates the area of the Polygon. This is available in the property Polygon.area + * The y coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. * - * @method Phaser.Geom.Polygon#calculateArea - * @since 3.0.0 + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @return {number} The area of the polygon. + * @name Phaser.GameObjects.Particles.ParticleEmitter#moveToY + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 */ - calculateArea: function () - { - if (this.points.length < 3) + moveToY: { + + get: function () { - this.area = 0; + return this.ops.moveToY.current; + }, - return this.area; + set: function (value) + { + this.ops.moveToY.onChange(value); } - var sum = 0; - var p1; - var p2; + }, - for (var i = 0; i < this.points.length - 1; i++) + /** + * The amount of velocity particles will use when rebounding off the + * emitter bounds, if set. A value of 0 means no bounce. A value of 1 + * means a full rebound. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#bounce + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + bounce: { + + get: function () { - p1 = this.points[i]; - p2 = this.points[i + 1]; + return this.ops.bounce.current; + }, - sum += (p2.x - p1.x) * (p1.y + p2.y); + set: function (value) + { + this.ops.bounce.onChange(value); } - p1 = this.points[0]; - p2 = this.points[this.points.length - 1]; + }, - sum += (p1.x - p2.x) * (p2.y + p1.y); + /** + * The horizontal scale of emitted particles. + * + * This is relative to the Emitters scale and that of any parent. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleScaleX + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + particleScaleX: { - this.area = -sum * 0.5; + get: function () + { + return this.ops.scaleX.current; + }, + + set: function (value) + { + this.ops.scaleX.onChange(value); + } - return this.area; }, /** - * 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. - * - * @method Phaser.Geom.Polygon#getPoints - * @since 3.12.0 + * The vertical scale of emitted particles. * - * @generic {Phaser.Geom.Point[]} O - [output,$return] + * This is relative to the Emitters scale and that of any parent. * - * @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|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the perimeter of the Polygon. + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleScaleY + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 */ - getPoints: function (quantity, step, output) - { - return GetPoints(this, quantity, step, output); - } + particleScaleY: { -}); + get: function () + { + return this.ops.scaleY.current; + }, -module.exports = Polygon; + set: function (value) + { + this.ops.scaleY.onChange(value); + } + }, -/***/ }), -/* 228 */ -/***/ (function(module, exports) { + /** + * A color tint value that is applied to the texture of the emitted + * particle. The value should be given in hex format, i.e. 0xff0000 + * for a red tint, and should not include the alpha channel. + * + * Tints are additive, meaning a tint value of white (0xffffff) will + * effectively reset the tint to nothing. + * + * Modify the `ParticleEmitter.tintFill` property to change between + * an additive and replacement tint mode. + * + * When you define the color via the Emitter config you should give + * it as an array of color values. The Particle will then interpolate + * through these colors over the course of its lifespan. Setting this + * will override any `tint` value that may also be given. + * + * This is a WebGL only feature. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleColor + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + particleColor: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this.ops.color.current; + }, -// Checks whether the x and y coordinates are contained within this polygon. -// Adapted from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html by Jonas Raoni Soares Silva + set: function (value) + { + this.ops.color.onChange(value); + } -/** - * Checks if a point is within the bounds of a Polygon. - * - * @function Phaser.Geom.Polygon.Contains - * @since 3.0.0 - * - * @param {Phaser.Geom.Polygon} polygon - The Polygon to check against. - * @param {number} x - The X coordinate of the point to check. - * @param {number} y - The Y coordinate of the point to check. - * - * @return {boolean} `true` if the point is within the bounds of the Polygon, otherwise `false`. - */ -var Contains = function (polygon, x, y) -{ - var inside = false; + }, - for (var i = -1, j = polygon.points.length - 1; ++i < polygon.points.length; j = i) - { - var ix = polygon.points[i].x; - var iy = polygon.points[i].y; + /** + * Controls the easing function used when you have created an + * Emitter that uses the `color` property to interpolate the + * tint of Particles over their lifetime. + * + * Setting this has no effect if you haven't also applied a + * `particleColor` to this Emitter. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#colorEase + * @type {string} + * @since 3.60.0 + */ + colorEase: { - var jx = polygon.points[j].x; - var jy = polygon.points[j].y; + get: function () + { + return this.ops.color.easeName; + }, - if (((iy <= y && y < jy) || (jy <= y && y < iy)) && (x < (jx - ix) * (y - iy) / (jy - iy) + ix)) + set: function (value) { - inside = !inside; + this.ops.color.setEase(value); } - } - return inside; -}; + }, -module.exports = Contains; + /** + * A color tint value that is applied to the texture of the emitted + * particle. The value should be given in hex format, i.e. 0xff0000 + * for a red tint, and should not include the alpha channel. + * + * Tints are additive, meaning a tint value of white (0xffffff) will + * effectively reset the tint to nothing. + * + * Modify the `ParticleEmitter.tintFill` property to change between + * an additive and replacement tint mode. + * + * The `tint` value will be overriden if a `color` array is provided. + * + * This is a WebGL only feature. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleTint + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + particleTint: { + get: function () + { + return this.ops.tint.current; + }, -/***/ }), -/* 229 */ -/***/ (function(module, exports, __webpack_require__) { + set: function (value) + { + this.ops.tint.onChange(value); + } -/** - * @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 GetFastValue = __webpack_require__(2); -var Extend = __webpack_require__(17); -var SetValue = __webpack_require__(478); -var ShaderRender = __webpack_require__(1176); -var TransformMatrix = __webpack_require__(25); + /** + * The alpha value of the emitted particles. This is a value + * between 0 and 1. Particles with alpha zero are invisible + * and are therefore not rendered, but are still processed + * by the Emitter. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleAlpha + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + particleAlpha: { -/** - * @classdesc - * A Shader Game Object. - * - * This Game Object allows you to easily add a quad with its own shader into the display list, and manipulate it - * as you would any other Game Object, including scaling, rotating, positioning and adding to Containers. Shaders - * can be masked with either Bitmap or Geometry masks and can also be used as a Bitmap Mask for a Camera or other - * Game Object. They can also be made interactive and used for input events. - * - * It works by taking a reference to a `Phaser.Display.BaseShader` instance, as found in the Shader Cache. These can - * be created dynamically at runtime, or loaded in via the GLSL File Loader: - * - * ```javascript - * function preload () - * { - * this.load.glsl('fire', 'shaders/fire.glsl.js'); - * } - * - * function create () - * { - * this.add.shader('fire', 400, 300, 512, 512); - * } - * ``` - * - * Please see the Phaser 3 Examples GitHub repo for examples of loading and creating shaders dynamically. - * - * Due to the way in which they work, you cannot directly change the alpha or blend mode of a Shader. This should - * be handled via exposed uniforms in the shader code itself. - * - * By default a Shader will be created with a standard set of uniforms. These were added to match those - * found on sites such as ShaderToy or GLSLSandbox, and provide common functionality a shader may need, - * such as the timestamp, resolution or pointer position. You can replace them by specifying your own uniforms - * in the Base Shader. - * - * These Shaders work by halting the current pipeline during rendering, creating a viewport matched to the - * size of this Game Object and then renders a quad using the bound shader. At the end, the pipeline is restored. - * - * Because it blocks the pipeline it means it will interrupt any batching that is currently going on, so you should - * use these Game Objects sparingly. If you need to have a fully batched custom shader, then please look at using - * a custom pipeline instead. However, for background or special masking effects, they are extremely effective. - * - * @class Shader - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @webglOnly - * @since 3.17.0 - * - * @extends Phaser.GameObjects.Components.ComputedSize - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.GetBounds - * @extends Phaser.GameObjects.Components.Mask - * @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 {(string|Phaser.Display.BaseShader)} key - The key of the shader to use from the shader cache, or a BaseShader instance. - * @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 Game Object. - * @param {number} [height=128] - The height of the Game Object. - * @param {string[]} [textures] - Optional array of texture keys to bind to the iChannel0...3 uniforms. The textures must already exist in the Texture Manager. - * @param {any} [textureData] - Additional texture data if you want to create shader with none NPOT textures. - */ -var Shader = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.ComputedSize, - Components.Depth, - Components.GetBounds, - Components.Mask, - Components.Origin, - Components.ScrollFactor, - Components.Transform, - Components.Visible, - ShaderRender - ], - - initialize: - - function Shader (scene, key, x, y, width, height, textures, textureData) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = 128; } - if (height === undefined) { height = 128; } - - GameObject.call(this, scene, 'Shader'); - - /** - * This Game Object cannot have a blend mode, so skip all checks. - * - * @name Phaser.GameObjects.Shader#blendMode - * @type {number} - * @private - * @since 3.17.0 - */ - this.blendMode = -1; - - /** - * The underlying shader object being used. - * Empty by default and set during a call to the `setShader` method. - * - * @name Phaser.GameObjects.Shader#shader - * @type {Phaser.Display.BaseShader} - * @since 3.17.0 - */ - this.shader; - - var renderer = scene.sys.renderer; - - /** - * A reference to the current renderer. - * Shaders only work with the WebGL Renderer. - * - * @name Phaser.GameObjects.Shader#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.17.0 - */ - this.renderer = renderer; - - /** - * The WebGL context belonging to the renderer. - * - * @name Phaser.GameObjects.Shader#gl - * @type {WebGLRenderingContext} - * @since 3.17.0 - */ - this.gl = renderer.gl; - - /** - * Raw byte buffer of vertices this Shader uses. - * - * @name Phaser.GameObjects.Shader#vertexData - * @type {ArrayBuffer} - * @since 3.17.0 - */ - this.vertexData = new ArrayBuffer(6 * (Float32Array.BYTES_PER_ELEMENT * 2)); - - /** - * The WebGL vertex buffer object this shader uses. - * - * @name Phaser.GameObjects.Shader#vertexBuffer - * @type {WebGLBuffer} - * @since 3.17.0 - */ - this.vertexBuffer = renderer.createVertexBuffer(this.vertexData.byteLength, this.gl.STREAM_DRAW); - - /** - * The WebGL shader program this shader uses. - * - * @name Phaser.GameObjects.Shader#program - * @type {WebGLProgram} - * @since 3.17.0 - */ - this.program = null; - - /** - * Uint8 view to the vertex raw buffer. Used for uploading vertex buffer resources to the GPU. - * - * @name Phaser.GameObjects.Shader#bytes - * @type {Uint8Array} - * @since 3.17.0 - */ - this.bytes = new Uint8Array(this.vertexData); - - /** - * Float32 view of the array buffer containing the shaders vertices. - * - * @name Phaser.GameObjects.Shader#vertexViewF32 - * @type {Float32Array} - * @since 3.17.0 - */ - this.vertexViewF32 = new Float32Array(this.vertexData); - - /** - * A temporary Transform Matrix, re-used internally during batching. - * - * @name Phaser.GameObjects.Shader#_tempMatrix1 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.17.0 - */ - this._tempMatrix1 = new TransformMatrix(); - - /** - * A temporary Transform Matrix, re-used internally during batching. - * - * @name Phaser.GameObjects.Shader#_tempMatrix2 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.17.0 - */ - this._tempMatrix2 = new TransformMatrix(); - - /** - * A temporary Transform Matrix, re-used internally during batching. - * - * @name Phaser.GameObjects.Shader#_tempMatrix3 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.17.0 - */ - this._tempMatrix3 = new TransformMatrix(); - - /** - * The view matrix the shader uses during rendering. - * - * @name Phaser.GameObjects.Shader#viewMatrix - * @type {Float32Array} - * @readonly - * @since 3.17.0 - */ - this.viewMatrix = new Float32Array([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); - - /** - * The projection matrix the shader uses during rendering. - * - * @name Phaser.GameObjects.Shader#projectionMatrix - * @type {Float32Array} - * @readonly - * @since 3.17.0 - */ - this.projectionMatrix = new Float32Array([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); - - /** - * The default uniform mappings. These can be added to (or replaced) by specifying your own uniforms when - * creating this shader game object. The uniforms are updated automatically during the render step. - * - * The defaults are: - * - * `resolution` (2f) - Set to the size of this shader. - * `time` (1f) - The elapsed game time, in seconds. - * `mouse` (2f) - If a pointer has been bound (with `setPointer`), this uniform contains its position each frame. - * `date` (4fv) - A vec4 containing the year, month, day and time in seconds. - * `sampleRate` (1f) - Sound sample rate. 44100 by default. - * `iChannel0...3` (sampler2D) - Input channels 0 to 3. `null` by default. - * - * @name Phaser.GameObjects.Shader#uniforms - * @type {any} - * @since 3.17.0 - */ - this.uniforms = {}; - - /** - * The pointer bound to this shader, if any. - * Set via the chainable `setPointer` method, or by modifying this property directly. - * - * @name Phaser.GameObjects.Shader#pointer - * @type {Phaser.Input.Pointer} - * @since 3.17.0 - */ - this.pointer = null; - - /** - * The cached width of the renderer. - * - * @name Phaser.GameObjects.Shader#_rendererWidth - * @type {number} - * @private - * @since 3.17.0 - */ - this._rendererWidth = renderer.width; - - /** - * The cached height of the renderer. - * - * @name Phaser.GameObjects.Shader#_rendererHeight - * @type {number} - * @private - * @since 3.17.0 - */ - this._rendererHeight = renderer.height; - - /** - * Internal texture count tracker. - * - * @name Phaser.GameObjects.Shader#_textureCount - * @type {number} - * @private - * @since 3.17.0 - */ - this._textureCount = 0; - - /** - * A reference to the GL Frame Buffer this Shader is drawing to. - * This property is only set if you have called `Shader.setRenderToTexture`. - * - * @name Phaser.GameObjects.Shader#framebuffer - * @type {?WebGLFramebuffer} - * @since 3.19.0 - */ - this.framebuffer = null; - - /** - * A reference to the WebGLTexture this Shader is rendering to. - * This property is only set if you have called `Shader.setRenderToTexture`. - * - * @name Phaser.GameObjects.Shader#glTexture - * @type {?WebGLTexture} - * @since 3.19.0 - */ - this.glTexture = null; - - /** - * A flag that indicates if this Shader has been set to render to a texture instead of the display list. - * - * This property is `true` if you have called `Shader.setRenderToTexture`, otherwise it's `false`. - * - * A Shader that is rendering to a texture _does not_ appear on the display list. - * - * @name Phaser.GameObjects.Shader#renderToTexture - * @type {boolean} - * @readonly - * @since 3.19.0 - */ - this.renderToTexture = false; + get: function () + { + return this.ops.alpha.current; + }, - /** - * A reference to the Phaser.Textures.Texture that has been stored in the Texture Manager for this Shader. - * - * This property is only set if you have called `Shader.setRenderToTexture`, otherwise it is `null`. - * - * @name Phaser.GameObjects.Shader#texture - * @type {Phaser.Textures.Texture} - * @since 3.19.0 - */ - this.texture = null; + set: function (value) + { + this.ops.alpha.onChange(value); + } - this.setPosition(x, y); - this.setSize(width, height); - this.setOrigin(0.5, 0.5); - this.setShader(key, textures, textureData); }, /** - * 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. + * The lifespan of the emitted particles. This value is given + * in milliseconds and defaults to 1000ms (1 second). When a + * particle reaches this amount it is killed. * - * @method Phaser.GameObjects.Shader#willRender - * @since 3.0.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @return {boolean} True if the Game Object should be rendered, otherwise false. + * @name Phaser.GameObjects.Particles.ParticleEmitter#lifespan + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 */ - willRender: function (camera) - { - if (this.renderToTexture) + lifespan: { + + get: function () { - return true; - } - else + return this.ops.lifespan.current; + }, + + set: function (value) { - return !(GameObject.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); + this.ops.lifespan.onChange(value); } + }, /** - * Changes this Shader so instead of rendering to the display list it renders to a - * WebGL Framebuffer and WebGL Texture instead. This allows you to use the output - * of this shader as an input for another shader, by mapping a sampler2D uniform - * to it. - * - * After calling this method the `Shader.framebuffer` and `Shader.glTexture` properties - * are populated. - * - * Additionally, you can provide a key to this method. Doing so will create a Phaser Texture - * from this Shader and save it into the Texture Manager, allowing you to then use it for - * any texture-based Game Object, such as a Sprite or Image: - * - * ```javascript - * var shader = this.add.shader('myShader', x, y, width, height); - * - * shader.setRenderToTexture('doodle'); - * - * this.add.image(400, 300, 'doodle'); - * ``` - * - * Note that it stores an active reference to this Shader. That means as this shader updates, - * so does the texture and any object using it to render with. Also, if you destroy this - * shader, be sure to clear any objects that may have been using it as a texture too. - * - * You can access the Phaser Texture that is created via the `Shader.texture` property. - * - * By default it will create a single base texture. You can add frames to the texture - * by using the `Texture.add` method. After doing this, you can then allow Game Objects - * to use a specific frame from a Render Texture. - * - * @method Phaser.GameObjects.Shader#setRenderToTexture - * @since 3.19.0 + * The angle at which the particles are emitted. The values are + * given in degrees. This allows you to control the direction + * of the emitter. If you wish instead to change the rotation + * of the particles themselves, see the `particleRotate` property. * - * @param {string} [key] - The unique key to store the texture as within the global Texture Manager. - * @param {boolean} [flipY=false] - Does this texture need vertically flipping before rendering? This should usually be set to `true` if being fed from a buffer. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleAngle + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 */ - setRenderToTexture: function (key, flipY) - { - if (flipY === undefined) { flipY = false; } + particleAngle: { - if (!this.renderToTexture) + get: function () { - var width = this.width; - var height = this.height; - var renderer = this.renderer; - - this.glTexture = renderer.createTextureFromSource(null, width, height, 0); - - this.glTexture.flipY = flipY; - - this.framebuffer = renderer.createFramebuffer(width, height, this.glTexture, false); - - this._rendererWidth = width; - this._rendererHeight = height; - - this.renderToTexture = true; - - this.projOrtho(0, this.width, this.height, 0); + return this.ops.angle.current; + }, - if (key) - { - this.texture = this.scene.sys.textures.addGLTexture(key, this.glTexture, width, height); - } + set: function (value) + { + this.ops.angle.onChange(value); } - // And now render at least once, so our texture isn't blank on the first update + }, - if (this.shader) - { - renderer.pipelines.clear(); + /** + * The rotation (or angle) of each particle when it is emitted. + * The value is given in degrees and uses a right-handed + * coordinate system, where 0 degrees points to the right, 90 degrees + * points down and -90 degrees points up. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#particleRotate + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + particleRotate: { - this.load(); - this.flush(); + get: function () + { + return this.ops.rotate.current; + }, - renderer.pipelines.rebind(); + set: function (value) + { + this.ops.rotate.onChange(value); } - return this; }, /** - * Sets the fragment and, optionally, the vertex shader source code that this Shader will use. - * This will immediately delete the active shader program, if set, and then create a new one - * with the given source. Finally, the shader uniforms are initialized. + * The number of particles that are emitted each time an emission + * occurs, i.e. from one 'explosion' or each frame in a 'flow' cycle. * - * @method Phaser.GameObjects.Shader#setShader - * @since 3.17.0 + * The default is 1. * - * @param {(string|Phaser.Display.BaseShader)} key - The key of the shader to use from the shader cache, or a BaseShader instance. - * @param {string[]} [textures] - Optional array of texture keys to bind to the iChannel0...3 uniforms. The textures must already exist in the Texture Manager. - * @param {any} [textureData] - Additional texture data. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#quantity + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency + * @see Phaser.GameObjects.Particles.ParticleEmitter#setQuantity + * @since 3.60.0 */ - setShader: function (key, textures, textureData) - { - if (textures === undefined) { textures = []; } - - if (typeof key === 'string') - { - var cache = this.scene.sys.cache.shader; - - if (!cache.has(key)) - { - console.warn('Shader missing: ' + key); - return this; - } + quantity: { - this.shader = cache.get(key); - } - else + get: function () { - this.shader = key; - } - - var gl = this.gl; - var renderer = this.renderer; + return this.ops.quantity.current; + }, - if (this.program) + set: function (value) { - gl.deleteProgram(this.program); + this.ops.quantity.onChange(value); } - var program = renderer.createProgram(this.shader.vertexSrc, this.shader.fragmentSrc); - - // The default uniforms available within the vertex shader - gl.uniformMatrix4fv(gl.getUniformLocation(program, 'uViewMatrix'), false, this.viewMatrix); - gl.uniformMatrix4fv(gl.getUniformLocation(program, 'uProjectionMatrix'), false, this.projectionMatrix); - gl.uniform2f(gl.getUniformLocation(program, 'uResolution'), this.width, this.height); - - this.program = program; - - var d = new Date(); + }, - // The default uniforms available within the fragment shader - var defaultUniforms = { - resolution: { type: '2f', value: { x: this.width, y: this.height } }, - time: { type: '1f', value: 0 }, - mouse: { type: '2f', value: { x: this.width / 2, y: this.height / 2 } }, - date: { type: '4fv', value: [ d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds() ] }, - sampleRate: { type: '1f', value: 44100.0 }, - iChannel0: { type: 'sampler2D', value: null, textureData: { repeat: true } }, - iChannel1: { type: 'sampler2D', value: null, textureData: { repeat: true } }, - iChannel2: { type: 'sampler2D', value: null, textureData: { repeat: true } }, - iChannel3: { type: 'sampler2D', value: null, textureData: { repeat: true } } - }; + /** + * The number of milliseconds to wait after emission before + * the particles start updating. This allows you to emit particles + * that appear 'static' or still on-screen and then, after this value, + * begin to move. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#delay + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 + */ + delay: { - if (this.shader.uniforms) - { - this.uniforms = Extend(true, {}, this.shader.uniforms, defaultUniforms); - } - else + get: function () { - this.uniforms = defaultUniforms; - } + return this.ops.delay.current; + }, - for (var i = 0; i < 4; i++) + set: function (value) { - if (textures[i]) - { - this.setSampler2D('iChannel' + i, textures[i], i, textureData); - } + this.ops.delay.onChange(value); } - this.initUniforms(); - - this.projOrtho(0, this._rendererWidth, this._rendererHeight, 0); - - return this; }, /** - * Binds a Phaser Pointer object to this Shader. - * - * The screen position of the pointer will be set in to the shaders `mouse` uniform - * automatically every frame. Call this method with no arguments to unbind the pointer. + * The number of milliseconds to wait after a particle has finished + * its life before it will be removed. This allows you to 'hold' a + * particle on the screen once it has reached its final state + * before it then vanishes. * - * @method Phaser.GameObjects.Shader#setPointer - * @since 3.17.0 + * Note that all particle updates will cease, including changing + * alpha, scale, movement or animation. * - * @param {Phaser.Input.Pointer} [pointer] - The Pointer to bind to this shader. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#hold + * @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} + * @since 3.60.0 */ - setPointer: function (pointer) - { - this.pointer = pointer; + hold: { + + get: function () + { + return this.ops.hold.current; + }, + + set: function (value) + { + this.ops.hold.onChange(value); + } - return this; }, /** - * Sets this shader to use an orthographic projection matrix. - * This matrix is stored locally in the `projectionMatrix` property, - * as well as being bound to the `uProjectionMatrix` uniform. + * The internal flow counter. * - * @method Phaser.GameObjects.Shader#projOrtho - * @since 3.17.0 + * Treat this property as read-only. * - * @param {number} left - The left value. - * @param {number} right - The right value. - * @param {number} bottom - The bottom value. - * @param {number} top - The top value. + * @name Phaser.GameObjects.Particles.ParticleEmitter#flowCounter + * @type {number} + * @since 3.60.0 */ - projOrtho: function (left, right, bottom, top) - { - var near = -1000; - var far = 1000; - - var leftRight = 1 / (left - right); - var bottomTop = 1 / (bottom - top); - var nearFar = 1 / (near - far); - - var pm = this.projectionMatrix; - - pm[0] = -2 * leftRight; - pm[5] = -2 * bottomTop; - pm[10] = 2 * nearFar; - pm[12] = (left + right) * leftRight; - pm[13] = (top + bottom) * bottomTop; - pm[14] = (far + near) * nearFar; + flowCounter: { - var program = this.program; - - var gl = this.gl; - var renderer = this.renderer; - - renderer.setProgram(program); + get: function () + { + return this.counters[0]; + }, - gl.uniformMatrix4fv(gl.getUniformLocation(program, 'uProjectionMatrix'), false, this.projectionMatrix); + set: function (value) + { + this.counters[0] = value; + } - this._rendererWidth = right; - this._rendererHeight = bottom; }, - // Uniforms are specified in the GLSL_ES Specification: http://www.khronos.org/registry/webgl/specs/latest/1.0/ - // http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf - /** - * Initializes all of the uniforms this shader uses. + * The internal frame counter. * - * @method Phaser.GameObjects.Shader#initUniforms - * @private - * @since 3.17.0 + * Treat this property as read-only. + * + * @name Phaser.GameObjects.Particles.ParticleEmitter#frameCounter + * @type {number} + * @since 3.60.0 */ - initUniforms: function () - { - var gl = this.gl; - var map = this.renderer.glFuncMap; - var program = this.program; - - this._textureCount = 0; + frameCounter: { - for (var key in this.uniforms) + get: function () { - var uniform = this.uniforms[key]; - - var type = uniform.type; - var data = map[type]; - - uniform.uniformLocation = gl.getUniformLocation(program, key); + return this.counters[1]; + }, - if (type !== 'sampler2D') - { - uniform.glMatrix = data.matrix; - uniform.glValueLength = data.length; - uniform.glFunc = data.func; - } + set: function (value) + { + this.counters[1] = value; } + }, /** - * Sets a sampler2D uniform on this shader where the source texture is a WebGLTexture. - * - * This allows you to feed the output from one Shader into another: - * - * ```javascript - * let shader1 = this.add.shader(baseShader1, 0, 0, 512, 512).setRenderToTexture(); - * let shader2 = this.add.shader(baseShader2, 0, 0, 512, 512).setRenderToTexture('output'); + * The internal animation counter. * - * shader1.setSampler2DBuffer('iChannel0', shader2.glTexture, 512, 512); - * shader2.setSampler2DBuffer('iChannel0', shader1.glTexture, 512, 512); - * ``` - * - * In the above code, the result of baseShader1 is fed into Shader2 as the `iChannel0` sampler2D uniform. - * The result of baseShader2 is then fed back into shader1 again, creating a feedback loop. - * - * If you wish to use an image from the Texture Manager as a sampler2D input for this shader, - * see the `Shader.setSampler2D` method. - * - * @method Phaser.GameObjects.Shader#setSampler2DBuffer - * @since 3.19.0 - * - * @param {string} uniformKey - The key of the sampler2D uniform to be updated, i.e. `iChannel0`. - * @param {WebGLTexture} texture - A WebGLTexture reference. - * @param {number} width - The width of the texture. - * @param {number} height - The height of the texture. - * @param {number} [textureIndex=0] - The texture index. - * @param {any} [textureData] - Additional texture data. + * Treat this property as read-only. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#animCounter + * @type {number} + * @since 3.60.0 */ - setSampler2DBuffer: function (uniformKey, texture, width, height, textureIndex, textureData) - { - if (textureIndex === undefined) { textureIndex = 0; } - if (textureData === undefined) { textureData = {}; } - - var uniform = this.uniforms[uniformKey]; - - uniform.value = texture; - - textureData.width = width; - textureData.height = height; + animCounter: { - uniform.textureData = textureData; - - this._textureCount = textureIndex; + get: function () + { + return this.counters[2]; + }, - this.initSampler2D(uniform); + set: function (value) + { + this.counters[2] = value; + } - return this; }, /** - * Sets a sampler2D uniform on this shader. - * - * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame - * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. - * - * If you wish to use another Shader as a sampler2D input for this shader, see the `Shader.setSampler2DBuffer` method. - * - * @method Phaser.GameObjects.Shader#setSampler2D - * @since 3.17.0 + * The internal elasped counter. * - * @param {string} uniformKey - The key of the sampler2D uniform to be updated, i.e. `iChannel0`. - * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. - * @param {number} [textureIndex=0] - The texture index. - * @param {any} [textureData] - Additional texture data. + * Treat this property as read-only. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#elapsed + * @type {number} + * @since 3.60.0 */ - setSampler2D: function (uniformKey, textureKey, textureIndex, textureData) - { - if (textureIndex === undefined) { textureIndex = 0; } - - var textureManager = this.scene.sys.textures; + elapsed: { - if (textureManager.exists(textureKey)) + get: function () { - var frame = textureManager.getFrame(textureKey); - - if (frame.glTexture && frame.glTexture.isRenderTexture) - { - return this.setSampler2DBuffer(uniformKey, frame.glTexture, frame.width, frame.height, textureIndex, textureData); - } - - var uniform = this.uniforms[uniformKey]; - var source = frame.source; - - uniform.textureKey = textureKey; - uniform.source = source.image; - uniform.value = frame.glTexture; - - if (source.isGLTexture) - { - if (!textureData) - { - textureData = {}; - } - - textureData.width = source.width; - textureData.height = source.height; - } - - if (textureData) - { - uniform.textureData = textureData; - } - - this._textureCount = textureIndex; + return this.counters[3]; + }, - this.initSampler2D(uniform); + set: function (value) + { + this.counters[3] = value; } - return this; }, /** - * Sets a property of a uniform already present on this shader. - * - * To modify the value of a uniform such as a 1f or 1i use the `value` property directly: - * - * ```javascript - * shader.setUniform('size.value', 16); - * ``` - * - * You can use dot notation to access deeper values, for example: - * - * ```javascript - * shader.setUniform('resolution.value.x', 512); - * ``` - * - * The change to the uniform will take effect the next time the shader is rendered. + * The internal stop counter. * - * @method Phaser.GameObjects.Shader#setUniform - * @since 3.17.0 - * - * @param {string} key - The key of the uniform to modify. Use dots for deep properties, i.e. `resolution.value.x`. - * @param {any} value - The value to set into the uniform. + * Treat this property as read-only. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#stopCounter + * @type {number} + * @since 3.60.0 */ - setUniform: function (key, value) - { - SetValue(this.uniforms, key, value); + stopCounter: { + + get: function () + { + return this.counters[4]; + }, + + set: function (value) + { + this.counters[4] = value; + } - return this; }, /** - * Returns the uniform object for the given key, or `null` if the uniform couldn't be found. + * The internal complete flag. * - * @method Phaser.GameObjects.Shader#getUniform - * @since 3.17.0 - * - * @param {string} key - The key of the uniform to return the value for. + * Treat this property as read-only. * - * @return {any} A reference to the uniform object. This is not a copy, so modifying it will update the original object also. + * @name Phaser.GameObjects.Particles.ParticleEmitter#completeFlag + * @type {boolean} + * @since 3.60.0 */ - getUniform: function (key) - { - return GetFastValue(this.uniforms, key, null); + completeFlag: { + + get: function () + { + return this.counters[5]; + }, + + set: function (value) + { + this.counters[5] = value; + } + }, /** - * A short-cut method that will directly set the texture being used by the `iChannel0` sampler2D uniform. - * - * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame - * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. - * - * @method Phaser.GameObjects.Shader#setChannel0 - * @since 3.17.0 + * The internal zone index. * - * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. - * @param {any} [textureData] - Additional texture data. + * Treat this property as read-only. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#zoneIndex + * @type {number} + * @since 3.60.0 */ - setChannel0: function (textureKey, textureData) - { - return this.setSampler2D('iChannel0', textureKey, 0, textureData); + zoneIndex: { + + get: function () + { + return this.counters[6]; + }, + + set: function (value) + { + this.counters[6] = value; + } + }, /** - * A short-cut method that will directly set the texture being used by the `iChannel1` sampler2D uniform. - * - * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame - * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. - * - * @method Phaser.GameObjects.Shader#setChannel1 - * @since 3.17.0 + * The internal zone total. * - * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. - * @param {any} [textureData] - Additional texture data. + * Treat this property as read-only. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#zoneTotal + * @type {number} + * @since 3.60.0 */ - setChannel1: function (textureKey, textureData) - { - return this.setSampler2D('iChannel1', textureKey, 1, textureData); + zoneTotal: { + + get: function () + { + return this.counters[7]; + }, + + set: function (value) + { + this.counters[7] = value; + } + }, /** - * A short-cut method that will directly set the texture being used by the `iChannel2` sampler2D uniform. - * - * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame - * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. + * The current frame index. * - * @method Phaser.GameObjects.Shader#setChannel2 - * @since 3.17.0 - * - * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. - * @param {any} [textureData] - Additional texture data. + * Treat this property as read-only. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#currentFrame + * @type {number} + * @since 3.60.0 */ - setChannel2: function (textureKey, textureData) - { - return this.setSampler2D('iChannel2', textureKey, 2, textureData); + currentFrame: { + + get: function () + { + return this.counters[8]; + }, + + set: function (value) + { + this.counters[8] = value; + } + }, /** - * A short-cut method that will directly set the texture being used by the `iChannel3` sampler2D uniform. + * The current animation index. * - * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame - * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. - * - * @method Phaser.GameObjects.Shader#setChannel3 - * @since 3.17.0 - * - * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. - * @param {any} [textureData] - Additional texture data. + * Treat this property as read-only. * - * @return {this} This Shader instance. + * @name Phaser.GameObjects.Particles.ParticleEmitter#currentAnim + * @type {number} + * @since 3.60.0 */ - setChannel3: function (textureKey, textureData) - { - return this.setSampler2D('iChannel3', textureKey, 3, textureData); + currentAnim: { + + get: function () + { + return this.counters[9]; + }, + + set: function (value) + { + this.counters[9] = value; + } + }, /** - * Internal method that takes a sampler2D uniform and prepares it for use by setting the - * gl texture parameters. + * Destroys this Particle Emitter and all Particles it owns. * - * @method Phaser.GameObjects.Shader#initSampler2D - * @private - * @since 3.17.0 - * - * @param {any} uniform - The sampler2D uniform to process. + * @method Phaser.GameObjects.Particles.ParticleEmitter#preDestroy + * @since 3.60.0 */ - initSampler2D: function (uniform) + preDestroy: function () { - if (!uniform.value) + this.texture = null; + this.frames = null; + this.anims = null; + this.emitCallback = null; + this.emitCallbackScope = null; + this.deathCallback = null; + this.deathCallbackScope = null; + this.emitZones = null; + this.deathZones = null; + this.bounds = null; + this.follow = null; + this.counters = null; + + var i; + + var ops = this.ops; + + for (i = 0; i < configOpMap.length; i++) { - return; + var key = configOpMap[i]; + + ops[key].destroy(); } - var gl = this.gl; + for (i = 0; i < this.alive.length; i++) + { + this.alive[i].destroy(); + } - gl.activeTexture(gl.TEXTURE0 + this._textureCount); - gl.bindTexture(gl.TEXTURE_2D, uniform.value); + for (i = 0; i < this.dead.length; i++) + { + this.dead[i].destroy(); + } - // Extended texture data + this.ops = null; + this.alive = []; + this.dead = []; + this.worldMatrix.destroy(); + } - var data = uniform.textureData; +}); - if (data && !uniform.value.isRenderTexture) - { - // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D +module.exports = ParticleEmitter; - // mag / minFilter can be: gl.LINEAR, gl.LINEAR_MIPMAP_LINEAR or gl.NEAREST - // wrapS/T can be: gl.CLAMP_TO_EDGE or gl.REPEAT - // format can be: gl.LUMINANCE or gl.RGBA - var magFilter = gl[GetFastValue(data, 'magFilter', 'linear').toUpperCase()]; - var minFilter = gl[GetFastValue(data, 'minFilter', 'linear').toUpperCase()]; - var wrapS = gl[GetFastValue(data, 'wrapS', 'repeat').toUpperCase()]; - var wrapT = gl[GetFastValue(data, 'wrapT', 'repeat').toUpperCase()]; - var format = gl[GetFastValue(data, 'format', 'rgba').toUpperCase()]; +/***/ }), - if (data.repeat) - { - wrapS = gl.REPEAT; - wrapT = gl.REPEAT; - } +/***/ 10456: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, !!data.flipY); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (data.width) - { - var width = GetFastValue(data, 'width', 512); - var height = GetFastValue(data, 'height', 2); - var border = GetFastValue(data, 'border', 0); +var RectangleToRectangle = __webpack_require__(90205); +var TransformMatrix = __webpack_require__(69360); - // texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels) - gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, border, format, gl.UNSIGNED_BYTE, null); - } - else - { - // texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, ImageData? pixels) - gl.texImage2D(gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, uniform.source); - } +var tempMatrix1 = new TransformMatrix(); +var tempMatrix2 = new TransformMatrix(); +var tempMatrix3 = new TransformMatrix(); +var tempMatrix4 = new TransformMatrix(); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT); - } +/** + * 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.Particles.Emitter#renderCanvas + * @since 3.60.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - 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 ParticleEmitterCanvasRenderer = function (renderer, emitter, camera, parentMatrix) +{ + var camMatrix = tempMatrix1; + var calcMatrix = tempMatrix2; + var particleMatrix = tempMatrix3; + var managerMatrix = tempMatrix4; - this.renderer.setProgram(this.program); + if (parentMatrix) + { + managerMatrix.loadIdentity(); + managerMatrix.multiply(parentMatrix); + managerMatrix.translate(emitter.x, emitter.y); + managerMatrix.rotate(emitter.rotation); + managerMatrix.scale(emitter.scaleX, emitter.scaleY); + } + else + { + managerMatrix.applyITRS(emitter.x, emitter.y, emitter.rotation, emitter.scaleX, emitter.scaleY); + } - gl.uniform1i(uniform.uniformLocation, this._textureCount); + var ctx = renderer.currentContext; + var roundPixels = camera.roundPixels; + var camerAlpha = camera.alpha; + var emitterAlpha = emitter.alpha; - this._textureCount++; - }, + var particles = emitter.alive; + var particleCount = particles.length; + var viewBounds = emitter.viewBounds; - /** - * Synchronizes all of the uniforms this shader uses. - * Each uniforms gl function is called in turn. - * - * @method Phaser.GameObjects.Shader#syncUniforms - * @private - * @since 3.17.0 - */ - syncUniforms: function () + if (!emitter.visible || particleCount === 0 || (viewBounds && !RectangleToRectangle(viewBounds, camera.worldView))) { - var gl = this.gl; + return; + } - var uniforms = this.uniforms; - var uniform; - var length; - var glFunc; - var location; - var value; - var textureCount = 0; + if (emitter.sortCallback) + { + emitter.depthSort(); + } - for (var key in uniforms) + camera.addToRenderList(emitter); + + var scrollFactorX = emitter.scrollFactorX; + var scrollFactorY = emitter.scrollFactorY; + + ctx.save(); + + ctx.globalCompositeOperation = renderer.blendModes[emitter.blendMode]; + + for (var i = 0; i < particleCount; i++) + { + var particle = particles[i]; + + var alpha = particle.alpha * emitterAlpha * camerAlpha; + + if (alpha <= 0 || particle.scaleX === 0 || particle.scaleY === 0) { - uniform = uniforms[key]; + continue; + } - glFunc = uniform.glFunc; - length = uniform.glValueLength; - location = uniform.uniformLocation; - value = uniform.value; + particleMatrix.applyITRS(particle.x, particle.y, particle.rotation, particle.scaleX, particle.scaleY); - if (value === null) - { - continue; - } + camMatrix.copyFrom(camera.matrix); - if (length === 1) - { - if (uniform.glMatrix) - { - glFunc.call(gl, location, uniform.transpose, value); - } - else - { - glFunc.call(gl, location, value); - } - } - else if (length === 2) - { - glFunc.call(gl, location, value.x, value.y); - } - else if (length === 3) - { - glFunc.call(gl, location, value.x, value.y, value.z); - } - else if (length === 4) + camMatrix.multiplyWithOffset(managerMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY); + + // Undo the camera scroll + particleMatrix.e = particle.x; + particleMatrix.f = particle.y; + + // Multiply by the particle matrix, store result in calcMatrix + camMatrix.multiply(particleMatrix, calcMatrix); + + var frame = particle.frame; + var cd = frame.canvasData; + + if (cd.width > 0 && cd.height > 0) + { + var x = -(frame.halfWidth); + var y = -(frame.halfHeight); + + ctx.globalAlpha = alpha; + + ctx.save(); + + calcMatrix.setToContext(ctx); + + if (roundPixels) { - glFunc.call(gl, location, value.x, value.y, value.z, value.w); + x = Math.round(x); + y = Math.round(y); } - else if (uniform.type === 'sampler2D') - { - gl.activeTexture(gl.TEXTURE0 + textureCount); - gl.bindTexture(gl.TEXTURE_2D, value); + ctx.imageSmoothingEnabled = !frame.source.scaleMode; - gl.uniform1i(location, textureCount); + ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height); - textureCount++; - } + ctx.restore(); } - }, + } - /** - * Called automatically during render. - * - * This method performs matrix ITRS and then stores the resulting value in the `uViewMatrix` uniform. - * It then sets up the vertex buffer and shader, updates and syncs the uniforms ready - * for flush to be called. - * - * @method Phaser.GameObjects.Shader#load - * @since 3.17.0 - * - * @param {Phaser.GameObjects.Components.TransformMatrix} [matrix2D] - The transform matrix to use during rendering. - */ - load: function (matrix2D) - { - // ITRS + ctx.restore(); +}; - var gl = this.gl; - var width = this.width; - var height = this.height; - var renderer = this.renderer; - var program = this.program; - var vm = this.viewMatrix; +module.exports = ParticleEmitterCanvasRenderer; - if (!this.renderToTexture) - { - var x = -this._displayOriginX; - var y = -this._displayOriginY; - vm[0] = matrix2D[0]; - vm[1] = matrix2D[1]; - vm[4] = matrix2D[2]; - vm[5] = matrix2D[3]; - vm[8] = matrix2D[4]; - vm[9] = matrix2D[5]; - vm[12] = vm[0] * x + vm[4] * y; - vm[13] = vm[1] * x + vm[5] * y; - } +/***/ }), - // Update vertex shader uniforms +/***/ 765: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - gl.useProgram(program); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - gl.uniformMatrix4fv(gl.getUniformLocation(program, 'uViewMatrix'), false, vm); - gl.uniform2f(gl.getUniformLocation(program, 'uResolution'), this.width, this.height); +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var GetFastValue = __webpack_require__(72632); +var ParticleEmitter = __webpack_require__(9216); - // Update fragment shader uniforms +/** + * Creates a new Particle Emitter Game Object and returns it. + * + * Prior to Phaser v3.60 this function would create a `ParticleEmitterManager`. These were removed + * in v3.60 and replaced with creating a `ParticleEmitter` instance directly. Please see the + * updated function parameters and class documentation for more details. + * + * Note: This method will only be available if the Particles Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#particles + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCreatorConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Particles.ParticleEmitter} The Game Object that was created. + */ +GameObjectCreator.register('particles', function (config, addToScene) +{ + if (config === undefined) { config = {}; } - var uniforms = this.uniforms; - var res = uniforms.resolution; + var key = GetAdvancedValue(config, 'key', null); + var emitterConfig = GetFastValue(config, 'config', null); - res.value.x = width; - res.value.y = height; + var emitter = new ParticleEmitter(this.scene, 0, 0, key); - uniforms.time.value = renderer.game.loop.getDuration(); + if (addToScene !== undefined) + { + config.add = addToScene; + } - var pointer = this.pointer; + BuildGameObject(this.scene, emitter, config); - if (pointer) - { - var mouse = uniforms.mouse; + if (emitterConfig) + { + emitter.setConfig(emitterConfig); + } - var px = pointer.x / width; - var py = 1 - pointer.y / height; + return emitter; +}); - mouse.value.x = px.toFixed(2); - mouse.value.y = py.toFixed(2); - } - this.syncUniforms(); - }, +/***/ }), - /** - * Called automatically during render. - * - * Sets the active shader, loads the vertex buffer and then draws. - * - * @method Phaser.GameObjects.Shader#flush - * @since 3.17.0 - */ - flush: function () +/***/ 81212: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GameObjectFactory = __webpack_require__(61286); +var ParticleEmitter = __webpack_require__(9216); + +/** + * Creates a new Particle Emitter Game Object and adds it to the Scene. + * + * If you wish to configure the Emitter after creating it, use the `ParticleEmitter.setConfig` method. + * + * Prior to Phaser v3.60 this function would create a `ParticleEmitterManager`. These were removed + * in v3.60 and replaced with creating a `ParticleEmitter` instance directly. Please see the + * updated function parameters and class documentation for more details. + * + * Note: This method will only be available if the Particles Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#particles + * @since 3.60.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 {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} [config] - Configuration settings for the Particle Emitter. + * + * @return {Phaser.GameObjects.Particles.ParticleEmitter} The Game Object that was created. + */ +GameObjectFactory.register('particles', function (x, y, texture, config) +{ + if (x !== undefined && typeof x === 'string') { - // Bind + console.warn('ParticleEmitterManager was removed in Phaser 3.60. See documentation for details'); + } - var width = this.width; - var height = this.height; - var program = this.program; + return this.displayList.add(new ParticleEmitter(this.scene, x, y, texture, config)); +}); - var gl = this.gl; - var vertexBuffer = this.vertexBuffer; - var renderer = this.renderer; - var vertexSize = Float32Array.BYTES_PER_ELEMENT * 2; - if (this.renderToTexture) - { - renderer.setFramebuffer(this.framebuffer); +/***/ }), - gl.clearColor(0, 0, 0, 0); +/***/ 69116: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - gl.clear(gl.COLOR_BUFFER_BIT); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - var location = gl.getAttribLocation(program, 'inPosition'); +if (true) +{ + renderWebGL = __webpack_require__(10275); +} - if (location !== -1) - { - gl.enableVertexAttribArray(location); +if (true) +{ + renderCanvas = __webpack_require__(10456); +} - gl.vertexAttribPointer(location, 2, gl.FLOAT, false, vertexSize, 0); - } +module.exports = { - // Draw + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - var vf = this.vertexViewF32; +}; - vf[3] = height; - vf[4] = width; - vf[5] = height; - vf[8] = width; - vf[9] = height; - vf[10] = width; - // Flush +/***/ }), - var vertexCount = 6; +/***/ 10275: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bytes.subarray(0, vertexCount * vertexSize)); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - gl.drawArrays(gl.TRIANGLES, 0, vertexCount); +var RectangleToRectangle = __webpack_require__(90205); +var TransformMatrix = __webpack_require__(69360); +var Utils = __webpack_require__(75512); - if (this.renderToTexture) - { - renderer.setFramebuffer(null, false); - } - }, +var tempMatrix1 = new TransformMatrix(); +var tempMatrix2 = new TransformMatrix(); +var tempMatrix3 = new TransformMatrix(); +var tempMatrix4 = new TransformMatrix(); - /** - * A NOOP method so you can pass a Shader to a Container. - * Calling this method will do nothing. It is intentionally empty. - * - * @method Phaser.GameObjects.Shader#setAlpha - * @private - * @since 3.17.0 - */ - setAlpha: function () +/** + * 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.Particles.Emitter#renderWebGL + * @since 3.60.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - 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 ParticleEmitterWebGLRenderer = function (renderer, emitter, camera, parentMatrix) +{ + var pipeline = renderer.pipelines.set(emitter.pipeline); + + var camMatrix = tempMatrix1; + var calcMatrix = tempMatrix2; + var particleMatrix = tempMatrix3; + var managerMatrix = tempMatrix4; + + if (parentMatrix) { - }, + managerMatrix.loadIdentity(); + managerMatrix.multiply(parentMatrix); + managerMatrix.translate(emitter.x, emitter.y); + managerMatrix.rotate(emitter.rotation); + managerMatrix.scale(emitter.scaleX, emitter.scaleY); + } + else + { + managerMatrix.applyITRS(emitter.x, emitter.y, emitter.rotation, emitter.scaleX, emitter.scaleY); + } - /** - * A NOOP method so you can pass a Shader to a Container. - * Calling this method will do nothing. It is intentionally empty. - * - * @method Phaser.GameObjects.Shader#setBlendMode - * @private - * @since 3.17.0 - */ - setBlendMode: function () + var roundPixels = camera.roundPixels; + var getTint = Utils.getTintAppendFloatAlpha; + var camerAlpha = camera.alpha; + var emitterAlpha = emitter.alpha; + var texture = emitter.frame.glTexture; + + renderer.pipelines.preBatch(emitter); + + var particles = emitter.alive; + var particleCount = particles.length; + var viewBounds = emitter.viewBounds; + + if (particleCount === 0 || (viewBounds && !RectangleToRectangle(viewBounds, camera.worldView))) { - }, + return; + } - /** - * Internal destroy handler, called as part of the destroy process. - * - * @method Phaser.GameObjects.Shader#preDestroy - * @protected - * @since 3.17.0 - */ - preDestroy: function () + if (emitter.sortCallback) { - var gl = this.gl; + emitter.depthSort(); + } - gl.deleteProgram(this.program); - gl.deleteBuffer(this.vertexBuffer); + var textureUnit = pipeline.setGameObject(emitter, emitter.frame); - if (this.renderToTexture) + camera.addToRenderList(emitter); + + camMatrix.copyFrom(camera.matrix); + + camMatrix.multiplyWithOffset(managerMatrix, -camera.scrollX * emitter.scrollFactorX, -camera.scrollY * emitter.scrollFactorY); + + renderer.setBlendMode(emitter.blendMode); + + if (emitter.mask) + { + emitter.mask.preRenderWebGL(renderer, emitter, camera); + + renderer.pipelines.set(emitter.pipeline); + } + + var tintEffect = emitter.tintFill; + + for (var i = 0; i < particleCount; i++) + { + var particle = particles[i]; + + var alpha = particle.alpha * emitterAlpha * camerAlpha; + + if (alpha <= 0 || particle.scaleX === 0 || particle.scaleY === 0) { - this.renderer.deleteFramebuffer(this.framebuffer); + continue; + } - this.texture.destroy(); + particleMatrix.applyITRS(particle.x, particle.y, particle.rotation, particle.scaleX, particle.scaleY); - this.framebuffer = null; - this.glTexture = null; - this.texture = null; + // Undo the camera scroll + particleMatrix.e = particle.x; + particleMatrix.f = particle.y; + + // Multiply by the particle matrix, store result in calcMatrix + camMatrix.multiply(particleMatrix, calcMatrix); + + var frame = particle.frame; + + var x = -frame.halfWidth; + var y = -frame.halfHeight; + + var quad = calcMatrix.setQuad(x, y, x + frame.width, y + frame.height, roundPixels); + + var tint = getTint(particle.tint, alpha); + + if (pipeline.shouldFlush(6)) + { + pipeline.flush(); + textureUnit = pipeline.setGameObject(emitter, emitter.frame); } + + pipeline.batchQuad(emitter, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, tintEffect, texture, textureUnit); } -}); + if (emitter.mask) + { + emitter.mask.postRenderWebGL(renderer, camera); + } -module.exports = Shader; + renderer.pipelines.postBatch(emitter); +}; + +module.exports = ParticleEmitterWebGLRenderer; /***/ }), -/* 230 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 30891: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var DegToRad = __webpack_require__(36); -var Face = __webpack_require__(116); -var GameObject = __webpack_require__(15); -var GenerateVerts = __webpack_require__(479); -var GenerateObjVerts = __webpack_require__(480); -var GetCalcMatrix = __webpack_require__(19); -var Matrix4 = __webpack_require__(69); -var MeshRender = __webpack_require__(1179); -var StableSort = __webpack_require__(79); -var Vector3 = __webpack_require__(39); -var Vertex = __webpack_require__(117); +var Class = __webpack_require__(56694); /** * @classdesc - * A Mesh Game Object. - * - * The Mesh Game Object allows you to render a group of textured vertices and manipulate - * the view of those vertices, such as rotation, translation or scaling. - * - * Support for generating mesh data from grids, model data or Wavefront OBJ Files is included. - * - * Although you can use this to render 3D objects, its primary use is for displaying more complex - * Sprites, or Sprites where you need fine-grained control over the vertex positions in order to - * achieve special effects in your games. Note that rendering still takes place using Phaser's - * orthographic camera (after being transformed via `projectionMesh`, see `setPerspective`, - * `setOrtho`, and `panZ` methods). As a result, all depth and face tests are done in an eventually - * orthographic space. - * - * The rendering process will iterate through the faces of this Mesh and render out each face - * that is considered as being in view of the camera. No depth buffer is used, and because of this, - * you should be careful not to use model data with too many vertices, or overlapping geometry, - * or you'll probably encounter z-depth fighting. The Mesh was designed to allow for more advanced - * 2D layouts, rather than displaying 3D objects, even though it can do this to a degree. - * - * In short, if you want to remake Crysis, use a 3D engine, not a Mesh. However, if you want - * to easily add some small fun 3D elements into your game, or create some special effects involving - * vertex warping, this is the right object for you. Mesh data becomes part of the WebGL batch, - * just like standard Sprites, so doesn't introduce any additional shader overhead. Because - * the Mesh just generates vertices into the WebGL batch, like any other Sprite, you can use all of - * the common Game Object components on a Mesh too, such as a custom pipeline, mask, blend mode - * or texture. + * This class provides the structured required for all Particle Processors. * - * Note that the Mesh object is WebGL only and does not have a Canvas counterpart. + * You should extend it and add the functionality required for your processor, + * including tidying up any resources this may create in the `destroy` method. * - * The Mesh origin is always 0.5 x 0.5 and cannot be changed. + * See the GravityWell for an example of a processor. * - * @class Mesh - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects + * @class ParticleProcessor + * @memberof Phaser.GameObjects.Particles * @constructor - * @webglOnly - * @since 3.0.0 - * - * @extends Phaser.GameObjects.Components.AlphaSingle - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Depth - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.Pipeline - * @extends Phaser.GameObjects.Components.Size - * @extends Phaser.GameObjects.Components.Texture - * @extends Phaser.GameObjects.Components.Transform - * @extends Phaser.GameObjects.Components.Visible - * @extends Phaser.GameObjects.Components.ScrollFactor + * @since 3.60.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 {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. - * @param {number[]} [vertices] - The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true` (but see note). - * @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? Note: If not, it will be assumed `z=0`, see method `panZ` or `setOrtho`. - * @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. + * @param {number} [x=0] - The x coordinate of the Particle Processor, in world space. + * @param {number} [y=0] - The y coordinate of the Particle Processor, in world space. + * @param {boolean} [active=true] - The active state of this Particle Processor. */ -var Mesh = new Class({ - - Extends: GameObject, - - Mixins: [ - Components.AlphaSingle, - Components.BlendMode, - Components.Depth, - Components.Mask, - Components.Pipeline, - Components.Size, - Components.Texture, - Components.Transform, - Components.Visible, - Components.ScrollFactor, - MeshRender - ], +var ParticleProcessor = new Class({ initialize: - function Mesh (scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas) + function ParticleProcessor (x, y, active) { if (x === undefined) { x = 0; } if (y === undefined) { y = 0; } - if (texture === undefined) { texture = '__WHITE'; } - - GameObject.call(this, scene, 'Mesh'); + if (active === undefined) { active = true; } /** - * An array containing the Face instances belonging to this Mesh. - * - * A Face consists of 3 Vertex objects. - * - * This array is populated during calls such as `addVertices` or `addOBJ`. + * A reference to the Particle Emitter that owns this Processor. + * This is set automatically when the Processor is added to an Emitter + * and nulled when removed or destroyed. * - * @name Phaser.GameObjects.Mesh#faces - * @type {Phaser.Geom.Mesh.Face[]} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.ParticleProcessor#manager + * @type {Phaser.GameObjects.Particles.ParticleEmitter} + * @since 3.60.0 */ - this.faces = []; + this.emitter; /** - * An array containing Vertex instances. One instance per vertex in this Mesh. - * - * This array is populated during calls such as `addVertex` or `addOBJ`. + * The x coordinate of the Particle Processor, in world space. * - * @name Phaser.GameObjects.Mesh#vertices - * @type {Phaser.Geom.Mesh.Vertex[]} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.ParticleProcessor#x + * @type {number} + * @since 3.60.0 */ - this.vertices = []; + this.x = x; /** - * The tint fill mode. - * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertex colors replace the texture, but respects texture alpha. + * The y coordinate of the Particle Processor, in world space. * - * @name Phaser.GameObjects.Mesh#tintFill - * @type {boolean} - * @default false - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.ParticleProcessor#y + * @type {number} + * @since 3.60.0 */ - this.tintFill = false; + this.y = y; /** - * You can optionally choose to render the vertices of this Mesh to a Graphics instance. - * - * Achieve this by setting the `debugCallback` and the `debugGraphic` properties. - * - * You can do this in a single call via the `Mesh.setDebug` method, which will use the - * built-in debug function. You can also set it to your own callback. The callback - * will be invoked _once per render_ and sent the following parameters: + * The active state of the Particle Processor. * - * `debugCallback(src, meshLength, verts)` - * - * `src` is the Mesh instance being debugged. - * `meshLength` is the number of mesh vertices in total. - * `verts` is an array of the translated vertex coordinates. - * - * To disable rendering, set this property back to `null`. - * - * Please note that high vertex count Meshes will struggle to debug properly. + * An inactive Particle Processor will be skipped for processing by + * its parent Emitter. * - * @name Phaser.GameObjects.Mesh#debugCallback - * @type {function} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.ParticleProcessor#active + * @type {boolean} + * @since 3.60.0 */ - this.debugCallback = null; + this.active = active; + }, + + /** + * The Particle Processor update method should be overriden by your own + * method and handle the processing of the particles, typically modifying + * their velocityX/Y values based on the criteria of this processor. + * + * @method Phaser.GameObjects.Particles.ParticleProcessor#update + * @since 3.60.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. + * @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + */ + update: function () + { + }, + + /** + * Destroys this Particle Processor by removing all external references. + * + * This is called automatically when the owning Particle Emitter is destroyed. + * + * @method Phaser.GameObjects.Particles.ParticleProcessor#destroy + * @since 3.60.0 + */ + destroy: function () + { + this.emitter = null; + } + +}); + +module.exports = ParticleProcessor; + + +/***/ }), + +/***/ 76100: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Particle Emitter Complete Event. + * + * This event is dispatched when the final particle, emitted from a Particle Emitter that + * has been stopped, dies. Upon receipt of this event you know that no particles are + * still rendering at this point in time. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('complete', listener)`. + * + * @event Phaser.GameObjects.Particles.Events#COMPLETE + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - A reference to the Particle Emitter that just completed. + */ +module.exports = 'complete'; + + +/***/ }), + +/***/ 26677: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Particle Emitter Death Zone Event. + * + * This event is dispatched when a Death Zone kills a Particle instance. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('deathzone', listener)`. + * + * If you wish to know when the final particle is killed, see the `COMPLETE` event. + * + * @event Phaser.GameObjects.Particles.Events#DEATH_ZONE + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - A reference to the Particle Emitter that owns the Particle and Death Zone. + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle that has been killed. + * @param {Phaser.GameObjects.Particles.Zones.DeathZone} zone - The Death Zone that killed the particle. + */ +module.exports = 'deathzone'; + + +/***/ }), + +/***/ 62736: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Particle Emitter Explode Event. + * + * This event is dispatched when a Particle Emitter explodes a set of particles. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('explode', listener)`. + * + * @event Phaser.GameObjects.Particles.Events#EXPLODE + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - A reference to the Particle Emitter that just completed. + * @param {Phaser.GameObjects.Particles.Particle} particle - The most recently emitted Particle. + */ +module.exports = 'explode'; + + +/***/ }), + +/***/ 56490: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Particle Emitter Start Event. + * + * This event is dispatched when a Particle Emitter starts emission of particles. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('start', listener)`. + * + * @event Phaser.GameObjects.Particles.Events#START + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - A reference to the Particle Emitter that just completed. + */ +module.exports = 'start'; + + +/***/ }), + +/***/ 85715: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Particle Emitter Stop Event. + * + * This event is dispatched when a Particle Emitter is stopped. This can happen either + * when you directly call the `ParticleEmitter.stop` method, or if the emitter has + * been configured to stop after a set time via the `duration` property, or after a + * set number of particles via the `stopAfter` property. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('stop', listener)`. + * + * Note that just because the emitter has stopped, that doesn't mean there aren't still + * particles alive and rendering. It just means the emitter has stopped emitting particles. + * + * If you wish to know when the final particle is killed, see the `COMPLETE` event. + * + * @event Phaser.GameObjects.Particles.Events#STOP + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - A reference to the Particle Emitter that just completed. + */ +module.exports = 'stop'; + + +/***/ }), + +/***/ 40629: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.GameObjects.Particles.Events + */ + +module.exports = { + + COMPLETE: __webpack_require__(76100), + DEATH_ZONE: __webpack_require__(26677), + EXPLODE: __webpack_require__(62736), + START: __webpack_require__(56490), + STOP: __webpack_require__(85715) + +}; + + +/***/ }), + +/***/ 27684: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.GameObjects.Particles + */ + +module.exports = { + + EmitterColorOp: __webpack_require__(19737), + EmitterOp: __webpack_require__(93025), + Events: __webpack_require__(40629), + GravityWell: __webpack_require__(87811), + Particle: __webpack_require__(14909), + ParticleBounds: __webpack_require__(73106), + ParticleEmitter: __webpack_require__(9216), + ParticleProcessor: __webpack_require__(30891), + Zones: __webpack_require__(25962) + +}; + + +/***/ }), + +/***/ 69361: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); + +/** + * @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) + { /** - * The Graphics instance that the debug vertices will be drawn to, if `setDebug` has - * been called. + * 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.Mesh#debugGraphic - * @type {Phaser.GameObjects.Graphics} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.Zones.DeathZone#source + * @type {Phaser.Types.GameObjects.Particles.DeathZoneSource} + * @since 3.0.0 */ - this.debugGraphic = null; + this.source = source; /** - * When rendering, skip any Face that isn't counter clockwise? - * - * Enable this to hide backward-facing Faces during rendering. - * - * Disable it to render all Faces. + * 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.Mesh#hideCCW + * @name Phaser.GameObjects.Particles.Zones.DeathZone#killOnEnter * @type {boolean} - * @since 3.50.0 + * @since 3.0.0 */ - this.hideCCW = true; + this.killOnEnter = killOnEnter; + }, - /** - * A Vector3 containing the 3D position of the vertices in this Mesh. - * - * Modifying the components of this property will allow you to reposition where - * the vertices are rendered within the Mesh. This happens in the `preUpdate` phase, - * where each vertex is transformed using the view and projection matrices. - * - * Changing this property will impact all vertices being rendered by this Mesh. - * - * You can also adjust the 'view' by using the `pan` methods. - * - * @name Phaser.GameObjects.Mesh#modelPosition - * @type {Phaser.Math.Vector3} - * @since 3.50.0 - */ - this.modelPosition = new Vector3(); + /** + * 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 test against this Death Zones. + * + * @return {boolean} Return `true` if the Particle is to be killed, otherwise return `false`. + */ + willKill: function (particle) + { + var pos = particle.worldPosition; + + var withinZone = this.source.contains(pos.x, pos.y); + + return (withinZone && this.killOnEnter || !withinZone && !this.killOnEnter); + } + +}); + +module.exports = DeathZone; + + +/***/ }), + +/***/ 54213: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); + +/** + * @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. + * @param {number} [total=-1] - The total number of particles this zone will emit before passing over to the next emission zone in the Emitter. -1 means it will never pass over and you must use `setEmitZone` to change it. + */ +var EdgeZone = new Class({ + + initialize: + + function EdgeZone (source, quantity, stepRate, yoyo, seamless, total) + { + if (yoyo === undefined) { yoyo = false; } + if (seamless === undefined) { seamless = true; } + if (total === undefined) { total = -1; } /** - * A Vector3 containing the 3D scale of the vertices in this Mesh. - * - * Modifying the components of this property will allow you to scale - * the vertices within the Mesh. This happens in the `preUpdate` phase, - * where each vertex is transformed using the view and projection matrices. - * - * Changing this property will impact all vertices being rendered by this Mesh. + * An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. * - * @name Phaser.GameObjects.Mesh#modelScale - * @type {Phaser.Math.Vector3} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#source + * @type {Phaser.Types.GameObjects.Particles.EdgeZoneSource|Phaser.Types.GameObjects.Particles.RandomZoneSource} + * @since 3.0.0 */ - this.modelScale = new Vector3(1, 1, 1); + this.source = source; /** - * A Vector3 containing the 3D rotation of the vertices in this Mesh. - * - * The values should be given in radians, i.e. to rotate the vertices by 90 - * degrees you can use `modelRotation.x = Phaser.Math.DegToRad(90)`. - * - * Modifying the components of this property will allow you to rotate - * the vertices within the Mesh. This happens in the `preUpdate` phase, - * where each vertex is transformed using the view and projection matrices. - * - * Changing this property will impact all vertices being rendered by this Mesh. + * The points placed on the source edge. * - * @name Phaser.GameObjects.Mesh#modelRotation - * @type {Phaser.Math.Vector3} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#points + * @type {Phaser.Geom.Point[]} + * @default [] + * @since 3.0.0 */ - this.modelRotation = new Vector3(); + this.points = []; /** - * An internal cache, used to compare position, rotation, scale and face data - * each frame, to avoid math calculations in `preUpdate`. - * - * Cache structure = position xyz | rotation xyz | scale xyz | face count | view | ortho + * The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. * - * @name Phaser.GameObjects.Mesh#dirtyCache - * @type {number[]} - * @private - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#quantity + * @type {number} + * @since 3.0.0 */ - this.dirtyCache = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + this.quantity = quantity; /** - * The transformation matrix for this Mesh. + * The distance between each particle. When set, `quantity` is implied and should be set to 0. * - * @name Phaser.GameObjects.Mesh#transformMatrix - * @type {Phaser.Math.Matrix4} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#stepRate + * @type {number} + * @since 3.0.0 */ - this.transformMatrix = new Matrix4(); + this.stepRate = stepRate; /** - * The view position for this Mesh. - * - * Use the methods`panX`, `panY` and `panZ` to adjust the view. + * Whether particles are placed from start to end and then end to start. * - * @name Phaser.GameObjects.Mesh#viewPosition - * @type {Phaser.Math.Vector3} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#yoyo + * @type {boolean} + * @since 3.0.0 */ - this.viewPosition = new Vector3(); + this.yoyo = yoyo; /** - * The view matrix for this Mesh. + * The counter used for iterating the EdgeZone's points. * - * @name Phaser.GameObjects.Mesh#viewMatrix - * @type {Phaser.Math.Matrix4} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#counter + * @type {number} + * @default -1 + * @since 3.0.0 */ - this.viewMatrix = new Matrix4(); + this.counter = -1; /** - * The projection matrix for this Mesh. - * - * Update it with the `setPerspective` or `setOrtho` methods. + * Whether one endpoint will be removed if it's identical to the other. * - * @name Phaser.GameObjects.Mesh#projectionMatrix - * @type {Phaser.Math.Matrix4} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#seamless + * @type {boolean} + * @since 3.0.0 */ - this.projectionMatrix = new Matrix4(); + this.seamless = seamless; /** - * How many faces were rendered by this Mesh Game Object in the last - * draw? This is reset in the `preUpdate` method and then incremented - * each time a face is drawn. Note that in multi-camera Scenes this - * value may exceed that found in `Mesh.getFaceCount` due to - * cameras drawing the same faces more than once. + * An internal count of the points belonging to this EdgeZone. * - * @name Phaser.GameObjects.Mesh#totalRendered + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_length * @type {number} - * @readonly - * @since 3.50.0 + * @private + * @default 0 + * @since 3.0.0 */ - this.totalRendered = 0; + this._length = 0; /** - * Internal cache var for the total number of faces rendered this frame. + * An internal value used to keep track of the current iteration direction for the EdgeZone's points. * - * See `totalRendered` instead for the actual value. + * 0 = forwards, 1 = backwards * - * @name Phaser.GameObjects.Mesh#totalFrame + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#_direction * @type {number} * @private - * @since 3.50.0 + * @default 0 + * @since 3.0.0 */ - this.totalFrame = 0; + this._direction = 0; /** - * By default, the Mesh will check to see if its model or view transform has - * changed each frame and only recalculate the vertex positions if they have. + * The total number of particles this zone will emit before the Emitter + * transfers control over to the next zone in its emission zone list. * - * This avoids lots of additional math in the `preUpdate` step when not required. + * By default this is -1, meaning it will never pass over from this + * zone to another one. You can call the `ParticleEmitter.setEmitZone` + * method to change it, or set this value to something else via the + * config, or directly at runtime. * - * However, if you are performing per-Face or per-Vertex manipulation on this Mesh, - * such as tweening a Face, or moving it without moving the rest of the Mesh, - * then you may need to disable the dirty cache in order for the Mesh to re-render - * correctly. You can toggle this property to do that. Please note that leaving - * this set to `true` will cause the Mesh to recalculate the position of every single - * vertex in it, every single frame. So only really do this if you know you - * need it. + * A value of 1 would mean the zones rotate in order, but it can + * be set to any integer value. * - * @name Phaser.GameObjects.Mesh#ignoreDirtyCache - * @type {boolean} - * @since 3.50.0 + * @name Phaser.GameObjects.Particles.Zones.EdgeZone#total + * @type {number} + * @since 3.60.0 */ - this.ignoreDirtyCache = false; - - var renderer = scene.sys.renderer; - - this.setPosition(x, y); - this.setTexture(texture, frame); - this.setSize(renderer.width, renderer.height); - this.initPipeline(); - - this.setPerspective(renderer.width, renderer.height); - - if (vertices) - { - this.addVertices(vertices, uvs, indicies, containsZ, normals, colors, alphas); - } - }, - - // Overrides Game Object method - addedToScene: function () - { - this.scene.sys.updateList.add(this); - }, + this.total = total; - // Overrides Game Object method - removedFromScene: function () - { - this.scene.sys.updateList.remove(this); + this.updateSource(); }, /** - * Translates the view position of this Mesh on the x axis by the given amount. + * Update the {@link Phaser.GameObjects.Particles.Zones.EdgeZone#points} from the EdgeZone's + * {@link Phaser.GameObjects.Particles.Zones.EdgeZone#source}. * - * @method Phaser.GameObjects.Mesh#panX - * @since 3.50.0 + * Also updates internal properties. * - * @param {number} v - The amount to pan by. + * @method Phaser.GameObjects.Particles.Zones.EdgeZone#updateSource + * @since 3.0.0 + * + * @return {this} This Edge Zone. */ - panX: function (v) + updateSource: function () { - this.viewPosition.addScale(Vector3.LEFT, v); + this.points = this.source.getPoints(this.quantity, this.stepRate); - this.dirtyCache[10] = 1; + // Remove ends? + if (this.seamless) + { + var a = this.points[0]; + var b = this.points[this.points.length - 1]; - return this; - }, + if (a.x === b.x && a.y === b.y) + { + this.points.pop(); + } + } - /** - * Translates the view position of this Mesh on the y axis by the given amount. - * - * @method Phaser.GameObjects.Mesh#panY - * @since 3.50.0 - * - * @param {number} v - The amount to pan by. - */ - panY: function (v) - { - this.viewPosition.y += Vector3.DOWN.y * v; + var oldLength = this._length; - this.dirtyCache[10] = 1; + 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; }, /** - * Translates the view position of this Mesh on the z axis by the given amount. + * Change the source of the EdgeZone. * - * As the default `panZ` value is 0, vertices with `z=0` (the default) need special care or else they will not display as they are behind the camera. - * Consider using `mesh.panZ(mesh.height / (2 * Math.tan(Math.PI / 16)))`, which will interpret vertex geometry 1:1 with pixel geometry (or see `setOrtho`). + * @method Phaser.GameObjects.Particles.Zones.EdgeZone#changeSource + * @since 3.0.0 * - * @method Phaser.GameObjects.Mesh#panZ - * @since 3.50.0 + * @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. * - * @param {number} v - The amount to pan by. + * @return {this} This Edge Zone. */ - panZ: function (amount) + changeSource: function (source) { - this.viewPosition.z += amount; - - this.dirtyCache[10] = 1; + this.source = source; - return this; + return this.updateSource(); }, /** - * Builds a new perspective projection matrix from the given values. - * - * These are also the initial projection matrix & parameters for `Mesh` (and see `panZ` for more discussion). - * - * See also `setOrtho`. + * Get the next point in the Zone and set its coordinates on the given Particle. * - * @method Phaser.GameObjects.Mesh#setPerspective - * @since 3.50.0 + * @method Phaser.GameObjects.Particles.Zones.EdgeZone#getPoint + * @since 3.0.0 * - * @param {number} width - The width of the projection matrix. Typically the same as the Mesh and/or Renderer. - * @param {number} height - The height of the projection matrix. Typically the same as the Mesh and/or Renderer. - * @param {number} [fov=45] - The field of view, in degrees. - * @param {number} [near=0.01] - The near value of the view. - * @param {number} [far=1000] - The far value of the view. + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. */ - setPerspective: function (width, height, fov, near, far) + getPoint: function (particle) { - if (fov === undefined) { fov = 45; } - if (near === undefined) { near = 0.01; } - if (far === undefined) { far = 1000; } + if (this._direction === 0) + { + this.counter++; - this.projectionMatrix.perspective(DegToRad(fov), width / height, near, far); + if (this.counter >= this._length) + { + if (this.yoyo) + { + this._direction = 1; + this.counter = this._length - 1; + } + else + { + this.counter = 0; + } + } + } + else + { + this.counter--; - this.dirtyCache[10] = 1; - this.dirtyCache[11] = 0; + if (this.counter === -1) + { + if (this.yoyo) + { + this._direction = 0; + this.counter = 0; + } + else + { + this.counter = this._length - 1; + } + } + } - return this; - }, + var point = this.points[this.counter]; - /** - * Builds a new orthographic projection matrix from the given values. - * - * If using this mode you will often need to set `Mesh.hideCCW` to `false` as well. - * - * By default, calling this method with no parameters will set the scaleX value to - * match the renderer's aspect ratio. If you would like to render vertex positions 1:1 - * to pixel positions, consider calling as `mesh.setOrtho(mesh.width, mesh.height)`. - * - * See also `setPerspective`. + if (point) + { + particle.x = point.x; + particle.y = point.y; + } + } + +}); + +module.exports = EdgeZone; + + +/***/ }), + +/***/ 68433: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Vector2 = __webpack_require__(93736); + +/** + * @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(); + + /** + * The total number of particles this zone will emit before the Emitter + * transfers control over to the next zone in its emission zone list. + * + * By default this is -1, meaning it will never pass over from this + * zone to another one. You can call the `ParticleEmitter.setEmitZone` + * method to change it, or set this value to something else via the + * config, or directly at runtime. + * + * A value of 1 would mean the zones rotate in order, but it can + * be set to any integer value. + * + * @name Phaser.GameObjects.Particles.Zones.RandomZone#total + * @type {number} + * @since 3.60.0 + */ + this.total = -1; + }, + + /** + * Get the next point in the Zone and set its coordinates on the given Particle. * - * @method Phaser.GameObjects.Mesh#setOrtho - * @since 3.50.0 + * @method Phaser.GameObjects.Particles.Zones.RandomZone#getPoint + * @since 3.0.0 * - * @param {number} [scaleX=1] - The default horizontal scale in relation to the Mesh / Renderer dimensions. - * @param {number} [scaleY=1] - The default vertical scale in relation to the Mesh / Renderer dimensions. - * @param {number} [near=-1000] - The near value of the view. - * @param {number} [far=1000] - The far value of the view. + * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. */ - setOrtho: function (scaleX, scaleY, near, far) + getPoint: function (particle) { - if (scaleX === undefined) { scaleX = this.scene.sys.renderer.getAspectRatio(); } - if (scaleY === undefined) { scaleY = 1; } - if (near === undefined) { near = -1000; } - if (far === undefined) { far = 1000; } + var vec = this._tempVec; - this.projectionMatrix.ortho(-scaleX, scaleX, -scaleY, scaleY, near, far); + this.source.getRandomPoint(vec); - this.dirtyCache[10] = 1; - this.dirtyCache[11] = 1; + particle.x = vec.x; + particle.y = vec.y; + } - return this; +}); + +module.exports = RandomZone; + + +/***/ }), + +/***/ 25962: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.GameObjects.Particles.Zones + */ + +module.exports = { + + DeathZone: __webpack_require__(69361), + EdgeZone: __webpack_require__(54213), + RandomZone: __webpack_require__(68433) + +}; + + +/***/ }), + +/***/ 29598: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var Sprite = __webpack_require__(13747); + +/** + * @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; }, /** - * Iterates and destroys all current Faces in this Mesh, then resets the - * `faces` and `vertices` arrays. + * Internal update handler that advances this PathFollower along the path. * - * @method Phaser.GameObjects.Mesh#clear - * @since 3.50.0 + * Called automatically by the Scene step, should not typically be called directly. * - * @return {this} This Mesh Game Object. + * @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. */ - clear: function () + preUpdate: function (time, delta) { - this.faces.forEach(function (face) - { - face.destroy(); - }); + this.anims.update(time, delta); + this.pathUpdate(time); + } - this.faces = []; - this.vertices = []; +}); - return this; +module.exports = PathFollower; + + +/***/ }), + +/***/ 19626: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GameObjectFactory = __webpack_require__(61286); +var PathFollower = __webpack_require__(29598); + +/** + * Creates a new PathFollower Game Object and adds it to the Scene. + * + * Note: This method will only be available if the PathFollower Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#follower + * @since 3.0.0 + * + * @param {Phaser.Curves.Path} path - The Path this PathFollower is connected to. + * @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.GameObjects.PathFollower} The Game Object that was created. + */ +GameObjectFactory.register('follower', function (path, x, y, key, frame) +{ + var sprite = new PathFollower(this.scene, path, x, y, key, frame); + + this.displayList.add(sprite); + this.updateList.add(sprite); + + return sprite; +}); + +// When registering a factory function 'this' refers to the GameObjectFactory 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 + + +/***/ }), + +/***/ 33412: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var AnimationState = __webpack_require__(16569); +var Class = __webpack_require__(56694); +var GenerateGridVerts = __webpack_require__(99425); +var IntegerToRGB = __webpack_require__(15978); +var Mesh = __webpack_require__(83321); +var UUID = __webpack_require__(76583); + +/** + * @classdesc + * A Plane Game Object. + * + * The Plane Game Object is a helper class that takes the Mesh Game Object and extends it, + * allowing for fast and easy creation of Planes. A Plane is a one-sided grid of cells, + * where you specify the number of cells in each dimension. The Plane can have a texture + * that is either repeated (tiled) across each cell, or applied to the full Plane. + * + * The Plane can then be manipulated in 3D space, with rotation across all 3 axis. + * + * This allows you to create effects not possible with regular Sprites, such as perspective + * distortion. You can also adjust the vertices on a per-vertex basis. Plane data becomes + * part of the WebGL batch, just like standard Sprites, so doesn't introduce any additional + * shader overhead. Because the Plane just generates vertices into the WebGL batch, like any + * other Sprite, you can use all of the common Game Object components on a Plane too, + * such as a custom pipeline, mask, blend mode or texture. + * + * You can use the `uvScroll` and `uvScale` methods to adjust the placement and scaling + * of the texture if this Plane is using a single texture, and not a frame from a texture + * atlas or sprite sheet. + * + * The Plane Game Object also has the Animation component, allowing you to play animations + * across the Plane just as you would with a Sprite. + * + * Note that the Plane object is WebGL only and does not have a Canvas counterpart. + * + * The Plane origin is always 0.5 x 0.5 and cannot be changed. + * + * @class Plane + * @extends Phaser.GameObjects.Mesh + * @memberof Phaser.GameObjects + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Scene} scene - The Scene to which this Plane belongs. A Plane can only belong to one Scene at a time. + * @param {number} [x] - The horizontal position of this Plane in the world. + * @param {number} [y] - The vertical position of this Plane in the world. + * @param {string|Phaser.Textures.Texture} [texture] - The key, or instance of the Texture this Plane will use to render with, as stored in the Texture Manager. + * @param {string|number} [frame] - An optional frame from the Texture this Plane is rendering with. + * @param {number} [width=8] - The width of this Plane, in cells, not pixels. + * @param {number} [height=8] - The height of this Plane, in cells, not pixels. + * @param {boolean} [tile=false] - Is the texture tiled? I.e. repeated across each cell. + */ +var Plane = new Class({ + + Extends: Mesh, + + initialize: + + function Plane (scene, x, y, texture, frame, width, height, tile) + { + if (!texture) { texture = '__DEFAULT'; } + + Mesh.call(this, scene, x, y, texture, frame); + + this.type = 'Plane'; + + /** + * The Animation State component of this Sprite. + * + * This component provides features to apply animations to this Sprite. + * It is responsible for playing, loading, queuing animations for later playback, + * mixing between animations and setting the current animation frame to this Sprite. + * + * @name Phaser.GameObjects.Plane#anims + * @type {Phaser.Animations.AnimationState} + * @since 3.60.0 + */ + this.anims = new AnimationState(this); + + /** + * The width of this Plane in cells, not pixels. + * + * This value is read-only. To adjust it, see the `setGridSize` method. + * + * @name Phaser.GameObjects.Plane#gridWidth + * @type {number} + * @readonly + * @since 3.60.0 + */ + this.gridWidth; + + /** + * The height of this Plane in cells, not pixels. + * + * This value is read-only. To adjust it, see the `setGridSize` method. + * + * @name Phaser.GameObjects.Plane#gridHeight + * @type {number} + * @readonly + * @since 3.60.0 + */ + this.gridHeight; + + /** + * Is the texture of this Plane tiled across all cells, or not? + * + * This value is read-only. To adjust it, see the `setGridSize` method. + * + * @name Phaser.GameObjects.Plane#isTiled + * @type {boolean} + * @readonly + * @since 3.60.0 + */ + this.isTiled; + + /** + * If this Plane has a checkboard texture, this is a reference to + * the WebGLTexture being used. Otherwise, it's null. + * + * @name Phaser.GameObjects.Plane#_checkerboard + * @type {?WebGLTexture} + * @private + * @since 3.60.0 + */ + this._checkerboard = null; + + this.hideCCW = false; + + this.setGridSize(width, height, tile); + this.setSizeToFrame(false); + this.setViewHeight(); }, /** - * This method will add the data from a triangulated Wavefront OBJ model file to this Mesh. - * - * The data should have been loaded via the OBJFile: - * - * ```javascript - * this.load.obj(key, url); - * ``` + * Modifies the layout of this Plane by adjusting the grid dimensions to the + * given width and height. The values are given in cells, not pixels. * - * Then use the same `key` as the first parameter to this method. - * - * Multiple Mesh Game Objects can use the same model data without impacting on each other. - * - * Make sure your 3D package has triangulated the model data prior to exporting it. - * - * You can 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 too large, to see. - * You can also offset the vertices of the model via the `x`, `y` and `z` parameters. + * The `tile` parameter allows you to control if the texture is tiled, or + * applied across the entire Plane? A tiled texture will repeat with one + * iteration per cell. A non-tiled texture will be applied across the whole + * Plane. * - * @method Phaser.GameObjects.Mesh#addVerticesFromObj - * @since 3.50.0 + * Note that if this Plane is using a single texture, not from a texture atlas + * or sprite sheet, then you can use the `Plane.uvScale` method to have much + * more fine-grained control over the texture tiling. * - * @param {string} key - The key of the model data in the OBJ Cache to add to this Mesh. - * @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)? + * @method Phaser.GameObjects.Plane#preDestroy + * @since 3.60.0 * - * @return {this} This Mesh Game Object. + * @param {number} [width=8] - The width of this Plane, in cells, not pixels. + * @param {number} [height=8] - The height of this Plane, in cells, not pixels. + * @param {boolean} [tile=false] - Is the texture tiled? I.e. repeated across each cell. */ - addVerticesFromObj: function (key, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp) + setGridSize: function (width, height, tile) { - var data = this.scene.sys.cache.obj.get(key); + if (width === undefined) { width = 8; } + if (height === undefined) { height = 8; } + if (tile === undefined) { tile = false; } - if (data) + var flipY = false; + + if (tile) { - GenerateObjVerts(data, this, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp); + flipY = true; } + this.gridWidth = width; + this.gridHeight = height; + this.isTiled = tile; + + this.clear(); + + GenerateGridVerts({ + mesh: this, + widthSegments: width, + heightSegments: height, + isOrtho: false, + tile: tile, + flipY: flipY + }); + return this; }, /** - * Compare the depth of two Faces. + * An internal method that resets the perspective projection for this Plane + * when it changes texture or frame, and also resets the cell UV coordinates, + * if required. * - * @method Phaser.GameObjects.Mesh#sortByDepth - * @since 3.50.0 + * @method Phaser.GameObjects.Plane#setSizeToFrame + * @since 3.60.0 + * @override * - * @param {Phaser.Geom.Mesh.Face} faceA - The first Face. - * @param {Phaser.Geom.Mesh.Face} faceB - The second Face. + * @param {boolean} [resetUV=true] - Reset all of the cell UV coordinates? * - * @return {number} The difference between the depths of each Face. + * @return {this} This Game Object instance. */ - sortByDepth: function (faceA, faceB) + setSizeToFrame: function (resetUV) { - return faceA.depth - faceB.depth; - }, + if (resetUV === undefined) { resetUV = true; } - /** - * Runs a depth sort across all Faces in this Mesh, comparing their averaged depth. - * - * This is called automatically if you use any of the `rotate` methods, but you can - * also invoke it to sort the Faces should you manually position them. - * - * @method Phaser.GameObjects.Mesh#depthSort - * @since 3.50.0 - * - * @return {this} This Mesh Game Object. - */ - depthSort: function () - { - StableSort(this.faces, this.sortByDepth); + var frame = this.frame; + + this.setPerspective(this.width / frame.width, this.height / frame.height); + + if (this._checkerboard && this._checkerboard !== this.texture) + { + this.removeCheckerboard(); + } + + if (!resetUV) + { + return this; + } + + // Reset UV coordinates if frame has changed + + var gridX = this.gridWidth; + var gridY = this.gridHeight; + + var verts = this.vertices; + + var frameU0 = frame.u0; + var frameU1 = frame.u1; + var frameV0 = frame.v0; + var frameV1 = frame.v1; + + var x; + var y; + var i = 0; + + if (this.isTiled) + { + // flipY + frameV0 = frame.v1; + frameV1 = frame.v0; + + for (y = 0; y < gridY; y++) + { + for (x = 0; x < gridX; x++) + { + verts[i++].setUVs(frameU0, frameV1); + verts[i++].setUVs(frameU0, frameV0); + verts[i++].setUVs(frameU1, frameV1); + verts[i++].setUVs(frameU0, frameV0); + verts[i++].setUVs(frameU1, frameV0); + verts[i++].setUVs(frameU1, frameV1); + } + } + } + else + { + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; + + var frameU = frameU1 - frameU0; + var frameV = frameV1 - frameV0; + + var uvs = []; + + for (y = 0; y < gridY1; y++) + { + for (x = 0; x < gridX1; x++) + { + var tu = frameU0 + frameU * (x / gridX); + var tv = frameV0 + frameV * (y / gridY); + + uvs.push(tu, tv); + } + } + + for (y = 0; y < gridY; y++) + { + for (x = 0; x < gridX; x++) + { + var a = (x + gridX1 * y) * 2; + var b = (x + gridX1 * (y + 1)) * 2; + var c = ((x + 1) + gridX1 * (y + 1)) * 2; + var d = ((x + 1) + gridX1 * y) * 2; + + verts[i++].setUVs(uvs[a], uvs[a + 1]); + verts[i++].setUVs(uvs[b], uvs[b + 1]); + verts[i++].setUVs(uvs[d], uvs[d + 1]); + verts[i++].setUVs(uvs[b], uvs[b + 1]); + verts[i++].setUVs(uvs[c], uvs[c + 1]); + verts[i++].setUVs(uvs[d], uvs[d + 1]); + } + } + } return this; }, /** - * Adds a new Vertex into the vertices array of this Mesh. + * Sets the height of this Plane to match the given value, in pixels. * - * Just adding a vertex isn't enough to render it. You need to also - * make it part of a Face, with 3 Vertex instances per Face. + * This adjusts the `Plane.viewPosition.z` value to achieve this. * - * @method Phaser.GameObjects.Mesh#addVertex - * @since 3.50.0 + * If no `value` parameter is given, it will set the view height to match + * that of the current texture frame the Plane is using. * - * @param {number} x - The x position of the vertex. - * @param {number} y - The y position of the vertex. - * @param {number} z - The z position of the vertex. - * @param {number} u - The UV u coordinate of the vertex. - * @param {number} v - The UV v coordinate of the vertex. - * @param {number} [color=0xffffff] - The color value of the vertex. - * @param {number} [alpha=1] - The alpha value of the vertex. + * @method Phaser.GameObjects.Plane#setViewHeight + * @since 3.60.0 * - * @return {this} This Mesh Game Object. + * @param {number} [value] - The height, in pixels, to set this Plane view height to. */ - addVertex: function (x, y, z, u, v, color, alpha) + setViewHeight: function (value) { - var vert = new Vertex(x, y, z, u, v, color, alpha); + if (value === undefined) { value = this.frame.height; } - this.vertices.push(vert); + var vFOV = this.fov * (Math.PI / 180); - return vert; + this.viewPosition.z = (this.height / value) / (Math.tan(vFOV / 2)); + + this.dirtyCache[10] = 1; }, /** - * Adds a new Face into the faces array of this Mesh. + * Creates a checkerboard style texture, based on the given colors and alpha + * values and applies it to this Plane, replacing any current texture it may + * have. * - * A Face consists of references to 3 Vertex instances, which must be provided. + * The colors are used in an alternating pattern, like a chess board. * - * @method Phaser.GameObjects.Mesh#addFace - * @since 3.50.0 + * Calling this method generates a brand new 16x16 pixel WebGLTexture internally + * and applies it to this Plane. While quite fast to do, you should still be + * mindful of calling this method either extensively, or in tight parts of + * your game. * - * @param {Phaser.Geom.Mesh.Vertex} vertex1 - The first vertex of the Face. - * @param {Phaser.Geom.Mesh.Vertex} vertex2 - The second vertex of the Face. - * @param {Phaser.Geom.Mesh.Vertex} vertex3 - The third vertex of the Face. + * @method Phaser.GameObjects.Plane#createCheckerboard + * @since 3.60.0 * - * @return {this} This Mesh Game Object. + * @param {number} [color1=0xffffff] - The odd cell color, specified as a hex value. + * @param {number} [color2=0x0000ff] - The even cell color, specified as a hex value. + * @param {number} [alpha1=255] - The odd cell alpha value, specified as a number between 0 and 255. + * @param {number} [alpha2=255] - The even cell alpha value, specified as a number between 0 and 255. + * @param {number} [height=128] - The view height of the Plane after creation, in pixels. */ - addFace: function (vertex1, vertex2, vertex3) + createCheckerboard: function (color1, color2, alpha1, alpha2, height) { - var face = new Face(vertex1, vertex2, vertex3); + if (color1 === undefined) { color1 = 0xffffff; } + if (color2 === undefined) { color2 = 0x0000ff; } + if (alpha1 === undefined) { alpha1 = 255; } + if (alpha2 === undefined) { alpha2 = 255; } + if (height === undefined) { height = 128; } - this.faces.push(face); + var gl = this.scene.sys.renderer.gl; - this.dirtyCache[9] = -1; + var glTexture = gl.createTexture(); - return face; + gl.activeTexture(gl.TEXTURE0); + + gl.bindTexture(gl.TEXTURE_2D, glTexture); + + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + + // Let's assume 16x16 for our texture size and 8x8 cell size + + var c1 = IntegerToRGB(color1); + var c2 = IntegerToRGB(color2); + + var colors = []; + + for (var h = 0; h < 16; h++) + { + for (var w = 0; w < 16; w++) + { + if ((h < 8 && w < 8) || (h > 7 && w > 7)) + { + colors.push(c1.r, c1.g, c1.b, alpha1); + } + else + { + colors.push(c2.r, c2.g, c2.b, alpha2); + } + } + } + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(colors)); + + glTexture.isAlphaPremultiplied = true; + glTexture.isRenderTexture = false; + glTexture.width = 16; + glTexture.height = 16; + + var texture = this.scene.sys.textures.addGLTexture(UUID(), glTexture, 16, 16); + + this.removeCheckerboard(); + + this._checkerboard = texture; + + gl.bindTexture(gl.TEXTURE_2D, null); + + this.setTexture(texture); + + this.setSizeToFrame(); + + this.setViewHeight(height); + + return this; }, /** - * Adds new vertices to this Mesh by parsing the given data. + * If this Plane has a Checkerboard Texture, this method will destroy it + * and reset the internal flag for it. * - * This method will take vertex data in one of two formats, based on the `containsZ` parameter. + * @method Phaser.GameObjects.Plane#removeCheckerboard + * @since 3.60.0 + */ + removeCheckerboard: function () + { + if (this._checkerboard) + { + this._checkerboard.destroy(); + + this._checkerboard = null; + } + }, + + /** + * Start playing the given animation on this Plane. * - * If your vertex data are `x`, `y` pairs, then `containsZ` should be `false` (this is the default, and will result in `z=0` for each vertex). + * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Plane. * - * If your vertex data is groups of `x`, `y` and `z` values, then the `containsZ` parameter must be true. + * The benefit of a global animation is that multiple Game Objects can all play the same animation, without + * having to duplicate the data. You can just create it once and then play it on any animating Game Object. * - * The `uvs` parameter is a numeric array consisting of `u` and `v` pairs. + * The following code shows how to create a global repeating animation. The animation will be created + * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': * - * The `normals` parameter is a numeric array consisting of `x`, `y` vertex normal values and, if `containsZ` is true, `z` values as well. + * ```javascript + * var config = { + * key: 'run', + * frames: 'muybridge', + * frameRate: 15, + * repeat: -1 + * }; * - * The `indicies` parameter is an optional array that, if given, is an indexed list of vertices to be added. + * // This code should be run from within a Scene: + * this.anims.create(config); + * ``` * - * The `colors` parameter is an optional array, or single value, that if given sets the color of each vertex created. + * However, if you wish to create an animation that is unique to this Plane, and this Plane alone, + * you can call the `Animation.create` method instead. It accepts the exact same parameters as when + * creating a global animation, however the resulting data is kept locally in this Plane. * - * The `alphas` parameter is an optional array, or single value, that if given sets the alpha of each vertex created. + * With the animation created, either globally or locally, you can now play it on this Plane: * - * When providing indexed data it is assumed that _all_ of the arrays are indexed, not just the vertices. + * ```javascript + * const plane = this.add.plane(...); + * plane.play('run'); + * ``` * - * The following example will create a 256 x 256 sized quad using an index array: + * Alternatively, if you wish to run it at a different frame rate for example, you can pass a config + * object instead: * * ```javascript - * let mesh = new Mesh(this); // Assuming `this` is a scene! - * const vertices = [ - * -128, 128, - * 128, 128, - * -128, -128, - * 128, -128 - * ]; + * const plane = this.add.plane(...); + * plane.play({ key: 'run', frameRate: 24 }); + * ``` * - * const uvs = [ - * 0, 1, - * 1, 1, - * 0, 0, - * 1, 0 - * ]; + * When playing an animation on a Plane it will first check to see if it can find a matching key + * locally within the Plane. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. * - * const indices = [ 0, 2, 1, 2, 3, 1 ]; + * If you need a Plane to be able to play both local and global animations, make sure they don't + * have conflicting keys. * - * mesh.addVertices(vertices, uvs, indicies); - * // Note: Otherwise the added points will be "behind" the camera! This value will project vertex `x` & `y` values 1:1 to pixel values. - * mesh.hideCCW = false; - * mesh.setOrtho(mesh.width, mesh.height); - * ``` + * See the documentation for the `PlayAnimationConfig` config object for more details about this. * - * If the data is not indexed, it's assumed that the arrays all contain sequential data. + * Also, see the documentation in the Animation Manager for further details on creating animations. * - * @method Phaser.GameObjects.Mesh#addVertices - * @since 3.50.0 + * @method Phaser.GameObjects.Plane#play + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.60.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? If not, it will be assumed `z=0`, see methods `panZ` or `setOrtho`. - * @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. + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. * - * @return {this} This Mesh Game Object. + * @return {this} This Game Object. */ - addVertices: function (vertices, uvs, indicies, containsZ, normals, colors, alphas) + play: function (key, ignoreIfPlaying) { - var result = GenerateVerts(vertices, uvs, indicies, containsZ, normals, colors, alphas); - - if (result) - { - this.faces = this.faces.concat(result.faces); - this.vertices = this.vertices.concat(result.vertices); - } - - this.dirtyCache[9] = -1; - - return this; + return this.anims.play(key, ignoreIfPlaying); }, /** - * Returns the total number of Faces in this Mesh Game Object. + * Start playing the given animation on this Plane, in reverse. * - * @method Phaser.GameObjects.Mesh#getFaceCount - * @since 3.50.0 + * Animations in Phaser can either belong to the global Animation Manager, or specifically to a Game Object. * - * @return {number} The number of Faces in this Mesh Game Object. - */ - getFaceCount: function () - { - return this.faces.length; - }, - - /** - * Returns the total number of Vertices in this Mesh Game Object. + * The benefit of a global animation is that multiple Game Objects can all play the same animation, without + * having to duplicate the data. You can just create it once and then play it on any animating Game Object. * - * @method Phaser.GameObjects.Mesh#getVertexCount - * @since 3.50.0 + * The following code shows how to create a global repeating animation. The animation will be created + * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': * - * @return {number} The number of Vertices in this Mesh Game Object. + * ```javascript + * var config = { + * key: 'run', + * frames: 'muybridge', + * frameRate: 15, + * repeat: -1 + * }; + * + * // This code should be run from within a Scene: + * this.anims.create(config); + * ``` + * + * However, if you wish to create an animation that is unique to this Game Object, and this Game Object alone, + * you can call the `Animation.create` method instead. It accepts the exact same parameters as when + * creating a global animation, however the resulting data is kept locally in this Game Object. + * + * With the animation created, either globally or locally, you can now play it on this Game Object: + * + * ```javascript + * const plane = this.add.plane(...); + * plane.playReverse('run'); + * ``` + * + * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config + * object instead: + * + * ```javascript + * const plane = this.add.plane(...); + * plane.playReverse({ key: 'run', frameRate: 24 }); + * ``` + * + * When playing an animation on a Game Object it will first check to see if it can find a matching key + * locally within the Game Object. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * If you need a Game Object to be able to play both local and global animations, make sure they don't + * have conflicting keys. + * + * See the documentation for the `PlayAnimationConfig` config object for more details about this. + * + * Also, see the documentation in the Animation Manager for further details on creating animations. + * + * @method Phaser.GameObjects.Plane#playReverse + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.60.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. + * + * @return {this} This Game Object. */ - getVertexCount: function () + playReverse: function (key, ignoreIfPlaying) { - return this.vertices.length; + return this.anims.playReverse(key, ignoreIfPlaying); }, /** - * Returns the Face at the given index in this Mesh Game Object. + * Waits for the specified delay, in milliseconds, then starts playback of the given animation. * - * @method Phaser.GameObjects.Mesh#getFace - * @since 3.50.0 + * If the animation _also_ has a delay value set in its config, it will be **added** to the delay given here. * - * @param {number} index - The index of the Face to get. + * If an animation is already running and a new animation is given to this method, it will wait for + * the given delay before starting the new animation. * - * @return {Phaser.Geom.Mesh.Face} The Face at the given index, or `undefined` if index out of range. + * If no animation is currently running, the given one begins after the delay. + * + * When playing an animation on a Game Object it will first check to see if it can find a matching key + * locally within the Game Object. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * @method Phaser.GameObjects.Plane#playAfterDelay + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.60.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {number} delay - The delay, in milliseconds, to wait before starting the animation playing. + * + * @return {this} This Game Object. */ - getFace: function (index) + playAfterDelay: function (key, delay) { - return this.faces[index]; + return this.anims.playAfterDelay(key, delay); }, /** - * Return an array of Face objects from this Mesh that intersect with the given coordinates. + * Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback + * of the given animation. * - * The given position is translated through the matrix of this Mesh and the given Camera, - * before being compared against the vertices. + * You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an + * idle animation to a walking animation, by making them blend smoothly into each other. * - * If more than one Face intersects, they will all be returned in the array, but the array will - * be depth sorted first, so the first element will always be that closest to the camera. + * If no animation is currently running, the given one will start immediately. * - * @method Phaser.GameObjects.Mesh#getFaceAt - * @since 3.50.0 + * When playing an animation on a Game Object it will first check to see if it can find a matching key + * locally within the Game Object. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. * - * @param {number} x - The x position to check against. - * @param {number} y - The y position to check against. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The camera to pass the coordinates through. If not give, the default Scene Camera is used. + * @method Phaser.GameObjects.Plane#playAfterRepeat + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.60.0 * - * @return {Phaser.Geom.Mesh.Face[]} An array of Face objects that intersect with the given point, ordered by depth. + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {number} [repeatCount=1] - How many times should the animation repeat before the next one starts? + * + * @return {this} This Game Object. */ - getFaceAt: function (x, y, camera) + playAfterRepeat: function (key, repeatCount) { - if (camera === undefined) { camera = this.scene.sys.cameras.main; } - - var calcMatrix = GetCalcMatrix(this, camera).calc; - - var faces = this.faces; - var results = []; - - for (var i = 0; i < faces.length; i++) - { - var face = faces[i]; - - if (face.contains(x, y, calcMatrix)) - { - results.push(face); - } - } - - return StableSort(results, this.sortByDepth); + return this.anims.playAfterRepeat(key, repeatCount); }, /** - * This method enables rendering of the Mesh vertices to the given Graphics instance. - * - * If you enable this feature, you **must** call `Graphics.clear()` in your Scene `update`, - * otherwise the Graphics instance you provide to debug will fill-up with draw calls, - * eventually crashing the browser. This is not done automatically to allow you to debug - * draw multiple Mesh objects to a single Graphics instance. - * - * The Mesh class has a built-in debug rendering callback `Mesh.renderDebug`, however - * you can also provide your own callback to be used instead. Do this by setting the `callback` parameter. - * - * The callback is invoked _once per render_ and sent the following parameters: - * - * `callback(src, faces)` + * Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` events. * - * `src` is the Mesh instance being debugged. - * `faces` is an array of the Faces that were rendered. + * If no animation is playing, no event will be dispatched. * - * You can get the final drawn vertex position from a Face object like this: + * If there is another animation queued (via the `chain` method) then it will start playing immediately. * - * ```javascript - * let face = faces[i]; + * @method Phaser.GameObjects.Plane#stop + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.60.0 * - * let x0 = face.vertex1.tx; - * let y0 = face.vertex1.ty; - * let x1 = face.vertex2.tx; - * let y1 = face.vertex2.ty; - * let x2 = face.vertex3.tx; - * let y2 = face.vertex3.ty; + * @return {this} This Game Object. + */ + stop: function () + { + return this.anims.stop(); + }, + + /** + * Stops the current animation from playing after the specified time delay, given in milliseconds. * - * graphic.strokeTriangle(x0, y0, x1, y1, x2, y2); - * ``` + * It then dispatches the `ANIMATION_STOP` event. * - * If using your own callback you do not have to provide a Graphics instance to this method. + * If no animation is running, no events will be dispatched. * - * To disable debug rendering, to either your own callback or the built-in one, call this method - * with no arguments. + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. * - * @method Phaser.GameObjects.Mesh#setDebug - * @since 3.50.0 + * @method Phaser.GameObjects.Plane#stopAfterDelay + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.60.0 * - * @param {Phaser.GameObjects.Graphics} [graphic] - The Graphic instance to render to if using the built-in callback. - * @param {function} [callback] - The callback to invoke during debug render. Leave as undefined to use the built-in callback. + * @param {number} delay - The number of milliseconds to wait before stopping this animation. * - * @return {this} This Game Object instance. + * @return {this} This Game Object. */ - setDebug: function (graphic, callback) + stopAfterDelay: function (delay) { - this.debugGraphic = graphic; - - if (!graphic && !callback) - { - this.debugCallback = null; - } - else if (!callback) - { - this.debugCallback = this.renderDebug; - } - else - { - this.debugCallback = callback; - } - - return this; + return this.anims.stopAfterDelay(delay); }, /** - * Checks if the transformation data in this mesh is dirty. + * Stops the current animation from playing after the given number of repeats. * - * This is used internally by the `preUpdate` step to determine if the vertices should - * be recalculated or not. + * It then dispatches the `ANIMATION_STOP` event. * - * @method Phaser.GameObjects.Mesh#isDirty - * @since 3.50.0 + * If no animation is running, no events will be dispatched. * - * @return {boolean} Returns `true` if the data of this mesh is dirty, otherwise `false`. + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. + * + * @method Phaser.GameObjects.Plane#stopAfterRepeat + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.60.0 + * + * @param {number} [repeatCount=1] - How many times should the animation repeat before stopping? + * + * @return {this} This Game Object. */ - isDirty: function () + stopAfterRepeat: function (repeatCount) { - var position = this.modelPosition; - var rotation = this.modelRotation; - var scale = this.modelScale; - var dirtyCache = this.dirtyCache; - - var px = position.x; - var py = position.y; - var pz = position.z; - - var rx = rotation.x; - var ry = rotation.y; - var rz = rotation.z; - - var sx = scale.x; - var sy = scale.y; - var sz = scale.z; - - var faces = this.getFaceCount(); - - var pxCached = dirtyCache[0]; - var pyCached = dirtyCache[1]; - var pzCached = dirtyCache[2]; - - var rxCached = dirtyCache[3]; - var ryCached = dirtyCache[4]; - var rzCached = dirtyCache[5]; - - var sxCached = dirtyCache[6]; - var syCached = dirtyCache[7]; - var szCached = dirtyCache[8]; - - var fCached = dirtyCache[9]; - - dirtyCache[0] = px; - dirtyCache[1] = py; - dirtyCache[2] = pz; - - dirtyCache[3] = rx; - dirtyCache[4] = ry; - dirtyCache[5] = rz; - - dirtyCache[6] = sx; - dirtyCache[7] = sy; - dirtyCache[8] = sz; - - dirtyCache[9] = faces; - - return ( - pxCached !== px || pyCached !== py || pzCached !== pz || - rxCached !== rx || ryCached !== ry || rzCached !== rz || - sxCached !== sx || syCached !== sy || szCached !== sz || - fCached !== faces - ); + return this.anims.stopAfterRepeat(repeatCount); }, /** - * The Mesh update loop. The following takes place in this method: - * - * First, the `totalRendered` and `totalFrame` properties are set. + * Stops the current animation from playing when it next sets the given frame. + * If this frame doesn't exist within the animation it will not stop it from playing. * - * If the view matrix of this Mesh isn't dirty, and the model position, rotate or scale properties are - * all clean, then the method returns at this point. + * It then dispatches the `ANIMATION_STOP` event. * - * Otherwise, if the viewPosition is dirty (i.e. from calling a method like `panZ`), then it will - * refresh the viewMatrix. + * If no animation is running, no events will be dispatched. * - * After this, a new transformMatrix is built and it then iterates through all Faces in this - * Mesh, calling `transformCoordinatesLocal` on all of them. Internally, this updates every - * vertex, calculating its new transformed position, based on the new transform matrix. + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. * - * Finally, the faces are depth sorted. + * @method Phaser.GameObjects.Plane#stopOnFrame + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.60.0 * - * @method Phaser.GameObjects.Mesh#preUpdate - * @protected - * @since 3.50.0 + * @param {Phaser.Animations.AnimationFrame} frame - The frame to check before stopping this animation. * - * @param {number} time - The current timestamp. - * @param {number} delta - The delta time, in ms, elapsed since the last frame. + * @return {this} This Game Object. */ - preUpdate: function () + stopOnFrame: function (frame) { - this.totalRendered = this.totalFrame; - this.totalFrame = 0; - - var dirty = this.dirtyCache; - - if (!this.ignoreDirtyCache && !dirty[10] && !this.isDirty()) - { - // If neither the view or the mesh is dirty we can bail out and save lots of math - return; - } - - var width = this.width; - var height = this.height; - - var viewMatrix = this.viewMatrix; - var viewPosition = this.viewPosition; - - if (dirty[10]) - { - viewMatrix.identity(); - viewMatrix.translate(viewPosition); - viewMatrix.invert(); - - dirty[10] = 0; - } - - var transformMatrix = this.transformMatrix; - - transformMatrix.setWorldMatrix( - this.modelRotation, - this.modelPosition, - this.modelScale, - this.viewMatrix, - this.projectionMatrix - ); - - var z = viewPosition.z; - - var faces = this.faces; - - for (var i = 0; i < faces.length; i++) - { - faces[i].transformCoordinatesLocal(transformMatrix, width, height, z); - } - - this.depthSort(); + return this.anims.stopOnFrame(frame); }, /** - * The built-in Mesh debug rendering method. - * - * See `Mesh.setDebug` for more details. + * Runs the preUpdate for this Plane, which will check its Animation State, + * if one is playing, and refresh view / model matrices, if updated. * - * @method Phaser.GameObjects.Mesh#renderDebug - * @since 3.50.0 + * @method Phaser.GameObjects.Plane#preUpdate + * @protected + * @since 3.60.0 * - * @param {Phaser.GameObjects.Mesh} src - The Mesh object being rendered. - * @param {Phaser.Geom.Mesh.Face[]} faces - An array of Faces. + * @param {number} time - The current timestamp. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. */ - renderDebug: function (src, faces) + preUpdate: function (time, delta) { - var graphic = src.debugGraphic; - - for (var i = 0; i < faces.length; i++) - { - var face = faces[i]; - - var x0 = face.vertex1.tx; - var y0 = face.vertex1.ty; - var x1 = face.vertex2.tx; - var y1 = face.vertex2.ty; - var x2 = face.vertex3.tx; - var y2 = face.vertex3.ty; + Mesh.prototype.preUpdate.call(this, time, delta); - graphic.strokeTriangle(x0, y0, x1, y1, x2, y2); - } + this.anims.update(time, delta); }, /** - * Handles the pre-destroy step for the Mesh, which removes the Animation component and typed arrays. + * Handles the pre-destroy step for the Plane, which removes the vertices and debug callbacks. * - * @method Phaser.GameObjects.Mesh#preDestroy + * @method Phaser.GameObjects.Plane#preDestroy * @private - * @since 3.50.0 + * @since 3.60.0 */ preDestroy: function () { this.clear(); + this.removeCheckerboard(); + + this.anims.destroy(); + + this.anims = undefined; this.debugCallback = null; this.debugGraphic = null; @@ -64706,58419 +69190,50220 @@ var Mesh = new Class({ }); -module.exports = Mesh; +module.exports = Plane; /***/ }), -/* 231 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 10912: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DistanceBetween = __webpack_require__(50); +var BuildGameObject = __webpack_require__(88933); +var BuildGameObjectAnimation = __webpack_require__(32291); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var GetValue = __webpack_require__(10850); +var Plane = __webpack_require__(33412); /** - * Checks if two Circles intersect. + * Creates a new Plane Game Object and returns it. * - * @function Phaser.Geom.Intersects.CircleToCircle - * @since 3.0.0 + * Note: This method will only be available if the Plane Game Object and WebGL support have been built into Phaser. * - * @param {Phaser.Geom.Circle} circleA - The first Circle to check for intersection. - * @param {Phaser.Geom.Circle} circleB - The second Circle to check for intersection. + * @method Phaser.GameObjects.GameObjectCreator#plane + * @since 3.60.0 * - * @return {boolean} `true` if the two Circles intersect, otherwise `false`. + * @param {Phaser.Types.GameObjects.Plane.PlaneConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Plane} The Game Object that was created. */ -var CircleToCircle = function (circleA, circleB) +GameObjectCreator.register('plane', function (config, addToScene) { - return (DistanceBetween(circleA.x, circleA.y, circleB.x, circleB.y) <= (circleA.radius + circleB.radius)); -}; + if (config === undefined) { config = {}; } -module.exports = CircleToCircle; + var key = GetAdvancedValue(config, 'key', null); + var frame = GetAdvancedValue(config, 'frame', null); + var width = GetValue(config, 'width', 8); + var height = GetValue(config, 'height', 8); + var tile = GetValue(config, 'tile', false); + + var plane = new Plane(this.scene, 0, 0, key, frame, width, height, tile); + + if (addToScene !== undefined) + { + config.add = addToScene; + } + + var checkerboard = GetValue(config, 'checkerboard', null); + + if (checkerboard) + { + var color1 = GetValue(checkerboard, 'color1', 0xffffff); + var color2 = GetValue(checkerboard, 'color2', 0x0000ff); + var alpha1 = GetValue(checkerboard, 'alpha1', 255); + var alpha2 = GetValue(checkerboard, 'alpha2', 255); + var checkheight = GetValue(checkerboard, 'height', 128); + + plane.createCheckerboard(color1, color2, alpha1, alpha2, checkheight); + } + + BuildGameObject(this.scene, plane, config); + + BuildGameObjectAnimation(plane, config); + + return plane; +}); /***/ }), -/* 232 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 58322: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Point = __webpack_require__(4); -var LineToCircle = __webpack_require__(233); +var Plane = __webpack_require__(33412); +var GameObjectFactory = __webpack_require__(61286); /** - * Checks for intersection between the line segment and circle, - * and returns the intersection points as a Point object array. + * Creates a new Plane Game Object and adds it to the Scene. * - * @function Phaser.Geom.Intersects.GetLineToCircle - * @since 3.0.0 + * Note: This method will only be available if the Plane Game Object has been built into Phaser. * - * @param {Phaser.Geom.Line} line - The line segment to check. - * @param {Phaser.Geom.Circle} circle - The circle to check against the line. - * @param {array} [out] - An optional array in which to store the points of intersection. + * @method Phaser.GameObjects.GameObjectFactory#plane + * @since 3.60.0 * - * @return {array} An array with the points of intersection if objects intersect, otherwise an empty array. + * @param {number} [x] - The horizontal position of this Plane in the world. + * @param {number} [y] - The vertical position of this Plane in the world. + * @param {string|Phaser.Textures.Texture} [texture] - The key, or instance of the Texture this Plane will use to render with, as stored in the Texture Manager. + * @param {string|number} [frame] - An optional frame from the Texture this Plane is rendering with. + * @param {number} [width=8] - The width of this Plane, in cells, not pixels. + * @param {number} [height=8] - The height of this Plane, in cells, not pixels. + * @param {boolean} [tile=false] - Is the texture tiled? I.e. repeated across each cell. + * + * @return {Phaser.GameObjects.Plane} The Plane Game Object that was created. */ -var GetLineToCircle = function (line, circle, out) +GameObjectFactory.register('plane', function (x, y, texture, frame, width, height, tile) { - if (out === undefined) { out = []; } - - if (LineToCircle(line, circle)) - { - var lx1 = line.x1; - var ly1 = line.y1; - - var lx2 = line.x2; - var ly2 = line.y2; + return this.displayList.add(new Plane(this.scene, x, y, texture, frame, width, height, tile)); +}); - var cx = circle.x; - var cy = circle.y; - var cr = circle.radius; - var lDirX = lx2 - lx1; - var lDirY = ly2 - ly1; - var oDirX = lx1 - cx; - var oDirY = ly1 - cy; +/***/ }), - var coefficientA = lDirX * lDirX + lDirY * lDirY; - var coefficientB = 2 * (lDirX * oDirX + lDirY * oDirY); - var coefficientC = oDirX * oDirX + oDirY * oDirY - cr * cr; +/***/ 13171: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var lambda = (coefficientB * coefficientB) - (4 * coefficientA * coefficientC); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var x, y; - - if (lambda === 0) - { - var root = -coefficientB / (2 * coefficientA); - x = lx1 + root * lDirX; - y = ly1 + root * lDirY; - if (root >= 0 && root <= 1) - { - out.push(new Point(x, y)); - } - } - else if (lambda > 0) - { - var root1 = (-coefficientB - Math.sqrt(lambda)) / (2 * coefficientA); - x = lx1 + root1 * lDirX; - y = ly1 + root1 * lDirY; - if (root1 >= 0 && root1 <= 1) - { - out.push(new Point(x, y)); - } - - var root2 = (-coefficientB + Math.sqrt(lambda)) / (2 * coefficientA); - x = lx1 + root2 * lDirX; - y = ly1 + root2 * lDirY; - if (root2 >= 0 && root2 <= 1) - { - out.push(new Point(x, y)); - } - } - } - - return out; -}; - -module.exports = GetLineToCircle; - - -/***/ }), -/* 233 */ -/***/ (function(module, exports, __webpack_require__) { +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var IntegerToColor = __webpack_require__(74853); +var PIPELINES_CONST = __webpack_require__(65641); +var Render = __webpack_require__(71606); /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Contains = __webpack_require__(66); -var Point = __webpack_require__(4); - -var tmp = new Point(); - -/** - * Checks for intersection between the line segment and circle. + * @classdesc + * The Point Light Game Object provides a way to add a point light effect into your game, + * without the expensive shader processing requirements of the traditional Light Game Object. * - * Based on code by [Matt DesLauriers](https://github.com/mattdesl/line-circle-collision/blob/master/LICENSE.md). + * The difference is that the Point Light renders using a custom shader, designed to give the + * impression of a point light source, of variable radius, intensity and color, in your game. + * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their + * normal maps for calcuations. This makes them extremely fast to render compared to Lights + * and perfect for special effects, such as flickering torches or muzzle flashes. * - * @function Phaser.Geom.Intersects.LineToCircle - * @since 3.0.0 + * For maximum performance you should batch Point Light Game Objects together. This means + * ensuring they follow each other consecutively on the display list. Ideally, use a Layer + * Game Object and then add just Point Lights to it, so that it can batch together the rendering + * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in + * your game then it's perfectly safe to mix them into the dislay list as normal. However, if + * you're using a large number of them, please consider how they are mixed into the display list. * - * @param {Phaser.Geom.Line} line - The line segment to check. - * @param {Phaser.Geom.Circle} circle - The circle to check against the line. - * @param {(Phaser.Geom.Point|any)} [nearest] - An optional Point-like object. If given the closest point on the Line where the circle intersects will be stored in this object. + * The renderer will automatically cull Point Lights. Those with a radius that does not intersect + * with the Camera will be skipped in the rendering list. This happens automatically and the + * culled state is refreshed every frame, for every camera. * - * @return {boolean} `true` if the two objects intersect, otherwise `false`. + * The origin of a Point Light is always 0.5 and it cannot be changed. + * + * Point Lights are a WebGL only feature and do not have a Canvas counterpart. + * + * @class PointLight + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.50.0 + * + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.Visible + * + * @param {Phaser.Scene} scene - The Scene to which this Point Light belongs. A Point Light can only belong to one Scene at a time. + * @param {number} x - The horizontal position of this Point Light in the world. + * @param {number} y - The vertical position of this Point Light in the world. + * @param {number} [color=0xffffff] - The color of the Point Light, given as a hex value. + * @param {number} [radius=128] - The radius of the Point Light. + * @param {number} [intensity=1] - The intensity, or color blend, of the Point Light. + * @param {number} [attenuation=0.1] - The attenuation of the Point Light. This is the reduction of light from the center point. */ -var LineToCircle = function (line, circle, nearest) -{ - if (nearest === undefined) { nearest = tmp; } - - if (Contains(circle, line.x1, line.y1)) - { - nearest.x = line.x1; - nearest.y = line.y1; - - return true; - } - - if (Contains(circle, line.x2, line.y2)) - { - nearest.x = line.x2; - nearest.y = line.y2; - - return true; - } +var PointLight = new Class({ - var dx = line.x2 - line.x1; - var dy = line.y2 - line.y1; + Extends: GameObject, - var lcx = circle.x - line.x1; - var lcy = circle.y - line.y1; + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.Depth, + Components.Mask, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Transform, + Components.Visible, + Render + ], - // project lc onto d, resulting in vector p - var dLen2 = (dx * dx) + (dy * dy); - var px = dx; - var py = dy; + initialize: - if (dLen2 > 0) + function PointLight (scene, x, y, color, radius, intensity, attenuation) { - var dp = ((lcx * dx) + (lcy * dy)) / dLen2; - - px *= dp; - py *= dp; - } + if (color === undefined) { color = 0xffffff; } + if (radius === undefined) { radius = 128; } + if (intensity === undefined) { intensity = 1; } + if (attenuation === undefined) { attenuation = 0.1; } - nearest.x = line.x1 + px; - nearest.y = line.y1 + py; - - // len2 of p - var pLen2 = (px * px) + (py * py); - - return ( - pLen2 <= dLen2 && - ((px * dx) + (py * dy)) >= 0 && - Contains(circle, nearest.x, nearest.y) - ); -}; + GameObject.call(this, scene, 'PointLight'); -module.exports = LineToCircle; + this.initPipeline(PIPELINES_CONST.POINTLIGHT_PIPELINE); + this.initPostPipeline(); + this.setPosition(x, y); -/***/ }), -/* 234 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The color of this Point Light. This property is an instance of a + * Color object, so you can use the methods within it, such as `setTo(r, g, b)` + * to change the color value. + * + * @name Phaser.GameObjects.PointLight#color + * @type {Phaser.Display.Color} + * @since 3.50.0 + */ + this.color = IntegerToColor(color); -/** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The intensity of the Point Light. + * + * The colors of the light are multiplied by this value during rendering. + * + * @name Phaser.GameObjects.PointLight#intensity + * @type {number} + * @since 3.50.0 + */ + this.intensity = intensity; -var Point = __webpack_require__(4); -var LineToLine = __webpack_require__(96); -var LineToRectangle = __webpack_require__(488); + /** + * The attenuation of the Point Light. + * + * This value controls the force with which the light falls-off from the center of the light. + * + * Use small float-based values, i.e. 0.1. + * + * @name Phaser.GameObjects.PointLight#attenuation + * @type {number} + * @since 3.50.0 + */ + this.attenuation = attenuation; -/** - * Checks for intersection between the Line and a Rectangle shape, - * and returns the intersection points as a Point object array. - * - * @function Phaser.Geom.Intersects.GetLineToRectangle - * @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. - * @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 GetLineToRectangle = function (line, rect, out) -{ - if (out === undefined) { out = []; } + // read only: + this.width = radius * 2; + this.height = radius * 2; - if (LineToRectangle(line, rect)) - { - var lineA = rect.getLineA(); - var lineB = rect.getLineB(); - var lineC = rect.getLineC(); - var lineD = rect.getLineD(); + this._radius = radius; + }, - var output = [ new Point(), new Point(), new Point(), new Point() ]; + /** + * The radius of the Point Light. + * + * @name Phaser.GameObjects.PointLight#radius + * @type {number} + * @since 3.50.0 + */ + radius: { - var result = [ - LineToLine(lineA, line, output[0]), - LineToLine(lineB, line, output[1]), - LineToLine(lineC, line, output[2]), - LineToLine(lineD, line, output[3]) - ]; + get: function () + { + return this._radius; + }, - for (var i = 0; i < 4; i++) + set: function (value) { - if (result[i]) { out.push(output[i]); } + this._radius = value; + this.width = value * 2; + this.height = value * 2; } - } - - return out; -}; - -module.exports = GetLineToRectangle; - -/***/ }), -/* 235 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// http://www.blackpawn.com/texts/pointinpoly/ + }, -// points is an array of Point-like objects with public x/y properties -// returns an array containing all points that are within the triangle, or an empty array if none -// if 'returnFirst' is true it will return after the first point within the triangle is found + originX: { -/** - * Filters an array of point-like objects to only those contained within a triangle. - * If `returnFirst` is true, will return an array containing only the first point in the provided array that is within the triangle (or an empty array if there are no such points). - * - * @function Phaser.Geom.Triangle.ContainsArray - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The triangle that the points are being checked in. - * @param {Phaser.Geom.Point[]} points - An array of point-like objects (objects that have an `x` and `y` property) - * @param {boolean} [returnFirst=false] - If `true`, return an array containing only the first point found that is within the triangle. - * @param {array} [out] - If provided, the points that are within the triangle will be appended to this array instead of being added to a new array. If `returnFirst` is true, only the first point found within the triangle will be appended. This array will also be returned by this function. - * - * @return {Phaser.Geom.Point[]} An array containing all the points from `points` that are within the triangle, if an array was provided as `out`, points will be appended to that array and it will also be returned here. - */ -var ContainsArray = function (triangle, points, returnFirst, out) -{ - if (returnFirst === undefined) { returnFirst = false; } - if (out === undefined) { out = []; } + get: function () + { + return 0.5; + } - var v0x = triangle.x3 - triangle.x1; - var v0y = triangle.y3 - triangle.y1; + }, - var v1x = triangle.x2 - triangle.x1; - var v1y = triangle.y2 - triangle.y1; + originY: { - var dot00 = (v0x * v0x) + (v0y * v0y); - var dot01 = (v0x * v1x) + (v0y * v1y); - var dot11 = (v1x * v1x) + (v1y * v1y); + get: function () + { + return 0.5; + } - // Compute barycentric coordinates - var b = ((dot00 * dot11) - (dot01 * dot01)); - var inv = (b === 0) ? 0 : (1 / b); + }, - var u; - var v; - var v2x; - var v2y; - var dot02; - var dot12; + displayOriginX: { - var x1 = triangle.x1; - var y1 = triangle.y1; + get: function () + { + return this._radius; + } - for (var i = 0; i < points.length; i++) - { - v2x = points[i].x - x1; - v2y = points[i].y - y1; + }, - dot02 = (v0x * v2x) + (v0y * v2y); - dot12 = (v1x * v2x) + (v1y * v2y); + displayOriginY: { - u = ((dot11 * dot02) - (dot01 * dot12)) * inv; - v = ((dot00 * dot12) - (dot01 * dot02)) * inv; - - if (u >= 0 && v >= 0 && (u + v < 1)) + get: function () { - out.push({ x: points[i].x, y: points[i].y }); - - if (returnFirst) - { - break; - } + return this._radius; } + } - return out; -}; +}); -module.exports = ContainsArray; +module.exports = PointLight; /***/ }), -/* 236 */ -/***/ (function(module, exports) { + +/***/ 162: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var PointLight = __webpack_require__(13171); + /** - * Rotate a line around the given coordinates by the given angle in radians. + * Creates a new Point Light Game Object and returns it. * - * @function Phaser.Geom.Line.RotateAroundXY - * @since 3.0.0 + * Note: This method will only be available if the Point Light Game Object has been built into Phaser. * - * @generic {Phaser.Geom.Line} O - [line,$return] + * @method Phaser.GameObjects.GameObjectCreator#pointlight + * @since 3.50.0 * - * @param {Phaser.Geom.Line} line - The line to rotate. - * @param {number} x - The horizontal coordinate to rotate the line around. - * @param {number} y - The vertical coordinate to rotate the line around. - * @param {number} angle - The angle of rotation in radians. + * @param {object} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. * - * @return {Phaser.Geom.Line} The rotated line. + * @return {Phaser.GameObjects.PointLight} The Game Object that was created. */ -var RotateAroundXY = function (line, x, y, angle) +GameObjectCreator.register('pointlight', function (config, addToScene) { - var c = Math.cos(angle); - var s = Math.sin(angle); - - var tx = line.x1 - x; - var ty = line.y1 - y; + if (config === undefined) { config = {}; } - line.x1 = tx * c - ty * s + x; - line.y1 = tx * s + ty * c + y; + var color = GetAdvancedValue(config, 'color', 0xffffff); + var radius = GetAdvancedValue(config, 'radius', 128); + var intensity = GetAdvancedValue(config, 'intensity', 1); + var attenuation = GetAdvancedValue(config, 'attenuation', 0.1); - tx = line.x2 - x; - ty = line.y2 - y; + var layer = new PointLight(this.scene, 0, 0, color, radius, intensity, attenuation); - line.x2 = tx * c - ty * s + x; - line.y2 = tx * s + ty * c + y; + if (addToScene !== undefined) + { + config.add = addToScene; + } - return line; -}; + BuildGameObject(this.scene, layer, config); -module.exports = RotateAroundXY; + return layer; +}); /***/ }), -/* 237 */ -/***/ (function(module, exports) { + +/***/ 91201: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GameObjectFactory = __webpack_require__(61286); +var PointLight = __webpack_require__(13171); + /** - * Calculates the width/height ratio of a rectangle. + * Creates a new Point Light Game Object and adds it to the Scene. * - * @function Phaser.Geom.Rectangle.GetAspectRatio - * @since 3.0.0 + * Note: This method will only be available if the Point Light Game Object has been built into Phaser. * - * @param {Phaser.Geom.Rectangle} rect - The rectangle. + * The Point Light Game Object provides a way to add a point light effect into your game, + * without the expensive shader processing requirements of the traditional Light Game Object. * - * @return {number} The width/height ratio of the rectangle. - */ -var GetAspectRatio = function (rect) -{ - return (rect.height === 0) ? NaN : rect.width / rect.height; -}; - -module.exports = GetAspectRatio; - - -/***/ }), -/* 238 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Rotates an entire Triangle at a given angle about a specific point. + * The difference is that the Point Light renders using a custom shader, designed to give the + * impression of a point light source, of variable radius, intensity and color, in your game. + * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their + * normal maps for calcuations. This makes them extremely fast to render compared to Lights + * and perfect for special effects, such as flickering torches or muzzle flashes. * - * @function Phaser.Geom.Triangle.RotateAroundXY - * @since 3.0.0 + * For maximum performance you should batch Point Light Game Objects together. This means + * ensuring they follow each other consecutively on the display list. Ideally, use a Layer + * Game Object and then add just Point Lights to it, so that it can batch together the rendering + * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in + * your game then it's perfectly safe to mix them into the dislay list as normal. However, if + * you're using a large number of them, please consider how they are mixed into the display list. * - * @generic {Phaser.Geom.Triangle} O - [triangle,$return] + * The renderer will automatically cull Point Lights. Those with a radius that does not intersect + * with the Camera will be skipped in the rendering list. This happens automatically and the + * culled state is refreshed every frame, for every camera. * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to rotate. - * @param {number} x - The X coordinate of the point to rotate the Triangle about. - * @param {number} y - The Y coordinate of the point to rotate the Triangle about. - * @param {number} angle - The angle by which to rotate the Triangle, in radians. + * The origin of a Point Light is always 0.5 and it cannot be changed. * - * @return {Phaser.Geom.Triangle} The rotated Triangle. + * Point Lights are a WebGL only feature and do not have a Canvas counterpart. + * + * @method Phaser.GameObjects.GameObjectFactory#pointlight + * @since 3.50.0 + * + * @param {number} x - The horizontal position of this Point Light in the world. + * @param {number} y - The vertical position of this Point Light in the world. + * @param {number} [color=0xffffff] - The color of the Point Light, given as a hex value. + * @param {number} [radius=128] - The radius of the Point Light. + * @param {number} [intensity=1] - The intensity, or color blend, of the Point Light. + * @param {number} [attenuation=0.1] - The attenuation of the Point Light. This is the reduction of light from the center point. + * + * @return {Phaser.GameObjects.PointLight} The Game Object that was created. */ -var RotateAroundXY = function (triangle, x, y, angle) +GameObjectFactory.register('pointlight', function (x, y, color, radius, intensity, attenuation) { - var c = Math.cos(angle); - var s = Math.sin(angle); - - var tx = triangle.x1 - x; - var ty = triangle.y1 - y; - - triangle.x1 = tx * c - ty * s + x; - triangle.y1 = tx * s + ty * c + y; - - tx = triangle.x2 - x; - ty = triangle.y2 - y; - - triangle.x2 = tx * c - ty * s + x; - triangle.y2 = tx * s + ty * c + y; - - tx = triangle.x3 - x; - ty = triangle.y3 - y; - - triangle.x3 = tx * c - ty * s + x; - triangle.y3 = tx * s + ty * c + y; - - return triangle; -}; - -module.exports = RotateAroundXY; + return this.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity, attenuation)); +}); /***/ }), -/* 239 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71606: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @namespace Phaser.Input.Gamepad.Events - */ +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(80590); +} module.exports = { - BUTTON_DOWN: __webpack_require__(1310), - BUTTON_UP: __webpack_require__(1311), - CONNECTED: __webpack_require__(1312), - DISCONNECTED: __webpack_require__(1313), - GAMEPAD_BUTTON_DOWN: __webpack_require__(1314), - GAMEPAD_BUTTON_UP: __webpack_require__(1315) + renderWebGL: renderWebGL, + renderCanvas: renderCanvas }; /***/ }), -/* 240 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 80590: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(17); -var XHRSettings = __webpack_require__(156); +var GetCalcMatrix = __webpack_require__(73329); /** - * Takes two XHRSettings Objects and creates a new XHRSettings object from them. - * - * The new object is seeded by the values given in the global settings, but any setting in - * the local object overrides the global ones. - * - * @function Phaser.Loader.MergeXHRSettings - * @since 3.0.0 + * 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. * - * @param {Phaser.Types.Loader.XHRSettingsObject} global - The global XHRSettings object. - * @param {Phaser.Types.Loader.XHRSettingsObject} local - The local XHRSettings object. + * @method Phaser.GameObjects.PointLight#renderWebGL + * @since 3.50.0 + * @private * - * @return {Phaser.Types.Loader.XHRSettingsObject} A newly formed XHRSettings object. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.PointLight} 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 MergeXHRSettings = function (global, local) +var PointLightWebGLRenderer = function (renderer, src, camera, parentMatrix) { - var output = (global === undefined) ? XHRSettings() : Extend({}, global); + camera.addToRenderList(src); - if (local) - { - for (var setting in local) - { - if (local[setting] !== undefined) - { - output[setting] = local[setting]; - } - } - } + var pipeline = renderer.pipelines.set(src.pipeline); - return output; -}; + var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; -module.exports = MergeXHRSettings; + var width = src.width; + var height = src.height; + var x = -src._radius; + var y = -src._radius; -/***/ }), -/* 241 */ -/***/ (function(module, exports, __webpack_require__) { + var xw = x + width; + var yh = y + height; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var lightX = calcMatrix.getX(0, 0); + var lightY = calcMatrix.getY(0, 0); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); -var ParseXML = __webpack_require__(408); + var tx0 = calcMatrix.getX(x, y); + var ty0 = calcMatrix.getY(x, y); -/** - * @classdesc - * A single XML File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#xml method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#xml. - * - * @class XMLFile - * @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.XMLFileConfig)} 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 `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var XMLFile = new Class({ + var tx1 = calcMatrix.getX(x, yh); + var ty1 = calcMatrix.getY(x, yh); - Extends: File, + var tx2 = calcMatrix.getX(xw, yh); + var ty2 = calcMatrix.getY(xw, yh); - initialize: + var tx3 = calcMatrix.getX(xw, y); + var ty3 = calcMatrix.getY(xw, y); - function XMLFile (loader, key, url, xhrSettings) - { - var extension = 'xml'; + renderer.pipelines.preBatch(src); - if (IsPlainObject(key)) - { - var config = key; + pipeline.batchPointLight(src, camera, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, lightX, lightY); - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - } + renderer.pipelines.postBatch(src); +}; - var fileConfig = { - type: 'xml', - cache: loader.cacheManager.xml, - extension: extension, - responseType: 'text', - key: key, - url: url, - xhrSettings: xhrSettings - }; +module.exports = PointLightWebGLRenderer; - 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.XMLFile#onProcess - * @since 3.7.0 - */ - onProcess: function () - { - this.state = CONST.FILE_PROCESSING; +/***/ }), - this.data = ParseXML(this.xhrLoader.responseText); +/***/ 15996: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (this.data) - { - this.onProcessComplete(); - } - else - { - console.warn('Invalid XMLFile: ' + this.key); - - this.onProcessError(); - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -}); +var Class = __webpack_require__(56694); +var DynamicTexture = __webpack_require__(845); +var Image = __webpack_require__(1539); /** - * Adds an XML file, or array of XML 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.xml('wavedata', 'files/AlienWaveData.xml'); - * } - * ``` - * - * 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 XML Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the XML 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 XML Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.xml({ - * key: 'wavedata', - * url: 'files/AlienWaveData.xml' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.XMLFileConfig` for more details. - * - * Once the file has finished loading you can access it from its Cache using its key: - * - * ```javascript - * this.load.xml('wavedata', 'files/AlienWaveData.xml'); - * // and later in your game ... - * var data = this.cache.xml.get('wavedata'); - * ``` + * @classdesc + * A Render Texture is a combination of Dynamic Texture and an Image Game Object, that uses the + * Dynamic Texture to display itself with. * - * 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 XML Cache. + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. * - * 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.xml". It will always add `.xml` 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. + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. * - * Note: The ability to load this type of file will only be available if the XML File type has been built into Phaser. - * It is available in the default build but can be excluded from custom builds. + * In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture + * like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to + * the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, + * the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers + * proxy methods to the features available from a Dynamic Texture. * - * @method Phaser.Loader.LoaderPlugin#xml - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 + * **When should you use a Render Texture vs. a Dynamic Texture?** * - * @param {(string|Phaser.Types.Loader.FileTypes.XMLFileConfig|Phaser.Types.Loader.FileTypes.XMLFileConfig[])} 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 `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. + * You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, + * or you want to use it across multiple Scenes, because textures are globally stored. * - * @return {this} The Loader instance. - */ -FileTypesManager.register('xml', 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 XMLFile(this, key[i])); - } - } - else - { - this.addFile(new XMLFile(this, key, url, xhrSettings)); - } - - return this; -}); - -module.exports = XMLFile; - - -/***/ }), -/* 242 */ -/***/ (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__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * A single Text File suitable for loading by the Loader. + * You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is + * instead going to be used for something like a mask or shader. * - * These are created when you use the Phaser.Loader.LoaderPlugin#text method and are not typically created directly. + * You should use a Render Texture if you need to display the texture in-game on a single Game Object, + * as it provides the convenience of wrapping an Image and Dynamic Texture together for you. * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#text. + * Under WebGL1, a FrameBuffer, which is what this Dynamic Texture uses internally, cannot be anti-aliased. + * This means that when drawing objects such as Shapes or Graphics instances to this texture, they may appear + * to be drawn with no aliasing around the edges. This is a technical limitation of WebGL1. To get around it, + * create your shape as a texture in an art package, then draw that to this texture. * - * @class TextFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes + * @class RenderTexture + * @extends Phaser.GameObjects.Image + * @memberof Phaser.GameObjects * @constructor - * @since 3.0.0 + * @since 3.2.0 * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.TextFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + * @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=32] - The width of the Render Texture. + * @param {number} [height=32] - The height of the Render Texture. */ -var TextFile = new Class({ +var RenderTexture = new Class({ - Extends: File, + Extends: Image, initialize: - function TextFile (loader, key, url, xhrSettings) + function RenderTexture (scene, x, y, width, height) { - var type = 'text'; - var extension = 'txt'; - var cache = loader.cacheManager.text; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 32; } + if (height === undefined) { height = 32; } - if (IsPlainObject(key)) - { - var config = key; + var dynamicTexture = new DynamicTexture(scene.sys.textures, '', width, height); - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - type = GetFastValue(config, 'type', type); - cache = GetFastValue(config, 'cache', cache); - } + Image.call(this, scene, x, y, dynamicTexture); - var fileConfig = { - type: type, - cache: cache, - extension: extension, - responseType: 'text', - key: key, - url: url, - xhrSettings: xhrSettings - }; + this.type = 'RenderTexture'; - File.call(this, loader, fileConfig); + /** + * An internal Camera that can be used to move around this Render Texture. + * + * Control it just like you would any Scene Camera. The difference is that it only impacts + * the placement of Game Objects that you then draw to this texture. + * + * You can scroll, zoom and rotate this Camera. + * + * This property is a reference to `RenderTexture.texture.camera`. + * + * @name Phaser.GameObjects.RenderTexture#camera + * @type {Phaser.Cameras.Scene2D.BaseCamera} + * @since 3.12.0 + */ + this.camera = this.texture.camera; + + /** + * Internal saved texture flag. + * + * @name Phaser.GameObjects.RenderTexture#_saved + * @type {boolean} + * @private + * @since 3.12.0 + */ + this._saved = false; }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * Sets the internal size of this Render Texture, as used for frame or physics body creation. * - * @method Phaser.Loader.FileTypes.TextFile#onProcess - * @since 3.7.0 + * 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.RenderTexture#setSize + * @since 3.0.0 + * + * @param {number} width - The width of this Game Object. + * @param {number} height - The height of this Game Object. + * + * @return {this} This Game Object instance. */ - onProcess: function () + setSize: function (width, height) { - this.state = CONST.FILE_PROCESSING; + this.width = width; + this.height = height; - this.data = this.xhrLoader.responseText; + this.texture.setSize(width, height); - this.onProcessComplete(); - } + this.updateDisplayOrigin(); -}); + var input = this.input; -/** - * Adds a Text file, or array of Text files, to the current load queue. - * - * You can call this method from within your Scene's `preload`, along with any other files you wish to load: - * - * ```javascript - * function preload () - * { - * this.load.text('story', 'files/IntroStory.txt'); - * } - * ``` - * - * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, - * or if it's already running, when the next free load slot becomes available. This happens automatically if you - * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued - * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. - * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the - * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been - * loaded. - * - * The key must be a unique String. It is used to add the file to the global Text Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Text Cache. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Text Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.text({ - * key: 'story', - * url: 'files/IntroStory.txt' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.TextFileConfig` for more details. - * - * Once the file has finished loading you can access it from its Cache using its key: - * - * ```javascript - * this.load.text('story', 'files/IntroStory.txt'); - * // and later in your game ... - * var data = this.cache.text.get('story'); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and - * this is what you would use to retrieve the text from the Text Cache. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story" - * and no URL is given then the Loader will set the URL to be "story.txt". It will always add `.txt` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Note: The ability to load this type of file will only be available if the Text File type has been built into Phaser. - * It is available in the default build but can be excluded from custom builds. - * - * @method Phaser.Loader.LoaderPlugin#text - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.TextFileConfig|Phaser.Types.Loader.FileTypes.TextFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. - * - * @return {this} The Loader instance. - */ -FileTypesManager.register('text', function (key, url, xhrSettings) -{ - if (Array.isArray(key)) - { - for (var i = 0; i < key.length; i++) + if (input && !input.customHitArea) { - // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(new TextFile(this, key[i])); + input.hitArea.width = width; + input.hitArea.height = height; } - } - else - { - this.addFile(new TextFile(this, key, url, xhrSettings)); - } - return this; -}); + return this; + }, -module.exports = TextFile; + /** + * Resizes the Render Texture to the new dimensions given. + * + * In WebGL it will destroy and then re-create the frame buffer being used by the Render Texture. + * In Canvas it will resize the underlying canvas element. + * + * Both approaches will erase everything currently drawn to the Render Texture. + * + * If the dimensions given are the same as those already being used, calling this method will do nothing. + * + * @method Phaser.GameObjects.RenderTexture#resize + * @since 3.10.0 + * + * @param {number} width - The new width of the Render Texture. + * @param {number} [height=width] - The new height of the Render Texture. If not specified, will be set the same as the `width`. + * + * @return {this} This Render Texture. + */ + resize: function (width, height) + { + this.setSize(width, height); + return this; + }, -/***/ }), -/* 243 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Stores a copy of this Render Texture in the Texture Manager using the given key. + * + * After doing this, any texture based Game Object, such as a Sprite, can use the contents of this + * Render Texture by using the texture key: + * + * ```javascript + * var rt = this.add.renderTexture(0, 0, 128, 128); + * + * // Draw something to the Render Texture + * + * rt.saveTexture('doodle'); + * + * this.add.image(400, 300, 'doodle'); + * ``` + * + * Updating the contents of this Render Texture will automatically update _any_ Game Object + * that is using it as a texture. Calling `saveTexture` again will not save another copy + * of the same texture, it will just rename the key of the existing copy. + * + * By default it will create a single base texture. You can add frames to the texture + * by using the `Texture.add` method. After doing this, you can then allow Game Objects + * to use a specific frame from a Render Texture. + * + * If you destroy this Render Texture, any Game Object using it via the Texture Manager will + * stop rendering. Ensure you remove the texture from the Texture Manager and any Game Objects + * using it first, before destroying this Render Texture. + * + * @method Phaser.GameObjects.RenderTexture#saveTexture + * @since 3.12.0 + * + * @param {string} key - The unique key to store the texture as within the global Texture Manager. + * + * @return {Phaser.Textures.DynamicTexture} The Texture that was saved. + */ + saveTexture: function (key) + { + var texture = this.texture; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + texture.key = key; -/** - * @namespace Phaser.Physics.Arcade.Components - */ + if (texture.manager.addDynamicTexture(texture)) + { + this._saved = true; + } -module.exports = { + return texture; + }, - Acceleration: __webpack_require__(1368), - Angular: __webpack_require__(1369), - Bounce: __webpack_require__(1370), - Debug: __webpack_require__(1371), - Drag: __webpack_require__(1372), - Enable: __webpack_require__(1373), - Friction: __webpack_require__(1374), - Gravity: __webpack_require__(1375), - Immovable: __webpack_require__(1376), - Mass: __webpack_require__(1377), - OverlapCirc: __webpack_require__(523), - OverlapRect: __webpack_require__(244), - Pushable: __webpack_require__(1378), - Size: __webpack_require__(1379), - Velocity: __webpack_require__(1380) + /** + * Fills this Render Texture with the given color. + * + * By default it will fill the entire texture, however you can set it to fill a specific + * rectangular area by using the x, y, width and height arguments. + * + * The color should be given in hex format, i.e. 0xff0000 for red, 0x00ff00 for green, etc. + * + * @method Phaser.GameObjects.RenderTexture#fill + * @since 3.2.0 + * + * @param {number} rgb - The color to fill this Render Texture with, such as 0xff0000 for red. + * @param {number} [alpha=1] - The alpha value used by the fill. + * @param {number} [x=0] - The left coordinate of the fill rectangle. + * @param {number} [y=0] - The top coordinate of the fill rectangle. + * @param {number} [width=this.width] - The width of the fill rectangle. + * @param {number} [height=this.height] - The height of the fill rectangle. + * + * @return {this} This Render Texture instance. + */ + fill: function (rgb, alpha, x, y, width, height) + { + this.texture.fill(rgb, alpha, x, y, width, height); -}; + return this; + }, + /** + * Fully clears this Render Texture, erasing everything from it and resetting it back to + * a blank, transparent, texture. + * + * @method Phaser.GameObjects.RenderTexture#clear + * @since 3.2.0 + * + * @return {this} This Render Texture instance. + */ + clear: function () + { + this.texture.clear(); -/***/ }), -/* 244 */ -/***/ (function(module, exports) { + return this; + }, -/** - * This method will search the given rectangular 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 for is extremely fast, - * otherwise the search is O(N) for Dynamic Bodies. - * - * @function Phaser.Physics.Arcade.Components.OverlapRect - * @since 3.17.0 - * - * @param {number} x - The top-left x coordinate of the area to search within. - * @param {number} y - The top-left y coordinate of the area to search within. - * @param {number} width - The width of the area to search within. - * @param {number} height - The height 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 OverlapRect = function (world, x, y, width, height, includeDynamic, includeStatic) -{ - if (includeDynamic === undefined) { includeDynamic = true; } - if (includeStatic === undefined) { includeStatic = false; } - - var dynamicBodies = []; - var staticBodies = []; - - var minMax = world.treeMinMax; - - minMax.minX = x; - minMax.minY = y; - minMax.maxX = x + width; - minMax.maxY = y + height; - - if (includeStatic) - { - staticBodies = world.staticTree.search(minMax); - } - - if (includeDynamic && world.useTree) - { - dynamicBodies = world.tree.search(minMax); - } - else if (includeDynamic) + /** + * Takes the given texture key and frame and then stamps it at the given + * x and y coordinates. You can use the optional 'config' argument to provide + * lots more options about how the stamp is applied, including the alpha, + * tint, angle, scale and origin. + * + * By default, the frame will stamp on the x/y coordinates based on its center. + * + * If you wish to stamp from the top-left, set the config `originX` and + * `originY` properties both to zero. + * + * @method Phaser.GameObjects.RenderTexture#stamp + * @since 3.60.0 + * + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param {number} [x=0] - The x position to draw the frame at. + * @param {number} [y=0] - The y position to draw the frame at. + * @param {Phaser.Types.Textures.StampConfig} [config] - The stamp configuration object, allowing you to set the alpha, tint, angle, scale and origin of the stamp. + * + * @return {this} This Render Texture instance. + */ + stamp: function (key, frame, x, y, config) { - var bodies = world.bodies; - - var fakeBody = - { - position: { - x: x, - y: y - }, - left: x, - top: y, - right: x + width, - bottom: y + height, - isCircle: false - }; + this.texture.stamp(key, frame, x, y, config); - var intersects = world.intersects; + return this; + }, - bodies.iterate(function (target) - { - if (intersects(target, fakeBody)) - { - dynamicBodies.push(target); - } + /** + * Draws the given object, or an array of objects, to this Render Texture using a blend mode of ERASE. + * This has the effect of erasing any filled pixels present in the objects from this texture. + * + * It can accept any of the following: + * + * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. + * * Tilemap Layers. + * * A Group. The contents of which will be iterated and drawn in turn. + * * A Container. The contents of which will be iterated fully, and drawn in turn. + * * A Scene Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture, or a Render Texture. + * * A Texture Frame instance. + * * A string. This is used to look-up the texture from the Texture Manager. + * + * Note: You cannot erase a Render Texture from itself. + * + * If passing in a Group or Container it will only draw children that return `true` + * when their `willRender()` method is called. I.e. a Container with 10 children, + * 5 of which have `visible=false` will only draw the 5 visible ones. + * + * If passing in an array of Game Objects it will draw them all, regardless if + * they pass a `willRender` check or not. + * + * You can pass in a string in which case it will look for a texture in the Texture + * Manager matching that string, and draw the base frame. + * + * You can pass in the `x` and `y` coordinates to draw the objects at. The use of + * the coordinates differ based on what objects are being drawn. If the object is + * a Group, Container or Display List, the coordinates are _added_ to the positions + * of the children. For all other types of object, the coordinates are exact. + * + * Calling this method causes the WebGL batch to flush, so it can write the texture + * data to the framebuffer being used internally. The batch is flushed at the end, + * after the entries have been iterated. So if you've a bunch of objects to draw, + * try and pass them in an array in one single call, rather than making lots of + * separate calls. + * + * @method Phaser.GameObjects.RenderTexture#erase + * @since 3.16.0 + * + * @param {any} entries - Any renderable Game Object, or Group, Container, Display List, Render Texture, Texture Frame, or an array of any of these. + * @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object. + * @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object. + * + * @return {this} This Render Texture instance. + */ + erase: function (entries, x, y) + { + this.texture.erase(entries, x, y); - }); - } + return this; + }, - return staticBodies.concat(dynamicBodies); -}; + /** + * Draws the given object, or an array of objects, to this Render Texture. + * + * It can accept any of the following: + * + * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. + * * Tilemap Layers. + * * A Group. The contents of which will be iterated and drawn in turn. + * * A Container. The contents of which will be iterated fully, and drawn in turn. + * * A Scene Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture, or a Render Texture. + * * A Texture Frame instance. + * * A string. This is used to look-up the texture from the Texture Manager. + * + * Note 1: You cannot draw a Render Texture to itself. + * + * Note 2: For Game Objects that have Post FX Pipelines, the pipeline _cannot_ be + * used when drawn to this texture. + * + * If passing in a Group or Container it will only draw children that return `true` + * when their `willRender()` method is called. I.e. a Container with 10 children, + * 5 of which have `visible=false` will only draw the 5 visible ones. + * + * If passing in an array of Game Objects it will draw them all, regardless if + * they pass a `willRender` check or not. + * + * You can pass in a string in which case it will look for a texture in the Texture + * Manager matching that string, and draw the base frame. If you need to specify + * exactly which frame to draw then use the method `drawFrame` instead. + * + * You can pass in the `x` and `y` coordinates to draw the objects at. The use of + * the coordinates differ based on what objects are being drawn. If the object is + * a Group, Container or Display List, the coordinates are _added_ to the positions + * of the children. For all other types of object, the coordinates are exact. + * + * The `alpha` and `tint` values are only used by Texture Frames. + * Game Objects use their own alpha and tint values when being drawn. + * + * Calling this method causes the WebGL batch to flush, so it can write the texture + * data to the framebuffer being used internally. The batch is flushed at the end, + * after the entries have been iterated. So if you've a bunch of objects to draw, + * try and pass them in an array in one single call, rather than making lots of + * separate calls. + * + * @method Phaser.GameObjects.RenderTexture#draw + * @since 3.2.0 + * + * @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these. + * @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object. + * @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. + * + * @return {this} This Render Texture instance. + */ + draw: function (entries, x, y, alpha, tint) + { + this.texture.draw(entries, x, y, alpha, tint); -module.exports = OverlapRect; + return this; + }, + /** + * Draws the Texture Frame to the Render Texture at the given position. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * + * ```javascript + * var rt = this.add.renderTexture(0, 0, 800, 600); + * rt.drawFrame(key, frame); + * ``` + * + * You can optionally provide a position, alpha and tint value to apply to the frame + * before it is drawn. + * + * Calling this method will cause a batch flush, so if you've got a stack of things to draw + * in a tight loop, try using the `draw` method instead. + * + * If you need to draw a Sprite to this Render Texture, use the `draw` method instead. + * + * @method Phaser.GameObjects.RenderTexture#drawFrame + * @since 3.12.0 + * + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param {number} [x=0] - The x position to draw the frame at. + * @param {number} [y=0] - The y position to draw the frame at. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. WebGL only. + * + * @return {this} This Render Texture instance. + */ + drawFrame: function (key, frame, x, y, alpha, tint) + { + this.texture.drawFrame(key, frame, x, y, alpha, tint); -/***/ }), -/* 245 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Takes the given Texture Frame and draws it to this Render Texture as a fill pattern, + * i.e. in a grid-layout based on the frame dimensions. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * + * You can optionally provide a position, width, height, alpha and tint value to apply to + * the frames before they are drawn. The position controls the top-left where the repeating + * fill will start from. The width and height control the size of the filled area. + * + * The position can be negative if required, but the dimensions cannot. + * + * Calling this method will cause a batch flush by default. Use the `skipBatch` argument + * to disable this if this call is part of a larger batch draw. + * + * @method Phaser.GameObjects.RenderTexture#repeat + * @since 3.60.0 + * + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param {number} [x=0] - The x position to start drawing the frames from (can be negative to offset). + * @param {number} [y=0] - The y position to start drawing the frames from (can be negative to offset). + * @param {number} [width=this.width] - The width of the area to repeat the frame within. Defaults to the width of this Dynamic Texture. + * @param {number} [height=this.height] - The height of the area to repeat the frame within. Defaults to the height of this Dynamic Texture. + * @param {number} [alpha=1] - The alpha to use. Defaults to 1, no alpha. + * @param {number} [tint=0xffffff] - WebGL only. The tint color to use. Leave as undefined, or 0xffffff to have no tint. + * @param {boolean} [skipBatch=false] - Skip beginning and ending a batch with this call. Use if this is part of a bigger batched draw. + * + * @return {this} This Render Texture instance. + */ + repeat: function (key, frame, x, y, width, height, alpha, tint, skipBatch) + { + this.texture.repeat(key, frame, x, y, width, height, alpha, tint, skipBatch); -/** - * @namespace Phaser.Physics.Arcade.Events - */ + return this; + }, -module.exports = { + /** + * Use this method if you need to batch draw a large number of Game Objects to + * this Render Texture in a single pass, or on a frequent basis. This is especially + * useful under WebGL, however, if your game is using Canvas only, it will not make + * any speed difference in that situation. + * + * This method starts the beginning of a batched draw, unless one is already open. + * + * Batched drawing is faster than calling `draw` in loop, but you must be careful + * to manage the flow of code and remember to call `endDraw()` when you're finished. + * + * If you don't need to draw large numbers of objects it's much safer and easier + * to use the `draw` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * RenderTexture.beginDraw(); + * + * // repeat n times: + * RenderTexture.batchDraw(); + * // or + * RenderTexture.batchDrawFrame(); + * + * // Call once: + * RenderTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Render Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * @method Phaser.GameObjects.RenderTexture#beginDraw + * @since 3.50.0 + * + * @return {this} This Render Texture instance. + */ + beginDraw: function () + { + this.texture.beginDraw(); - COLLIDE: __webpack_require__(1381), - OVERLAP: __webpack_require__(1382), - PAUSE: __webpack_require__(1383), - RESUME: __webpack_require__(1384), - TILE_COLLIDE: __webpack_require__(1385), - TILE_OVERLAP: __webpack_require__(1386), - WORLD_BOUNDS: __webpack_require__(1387), - WORLD_STEP: __webpack_require__(1388) + return this; + }, -}; + /** + * Use this method if you have already called `beginDraw` and need to batch + * draw a large number of objects to this Render Texture. + * + * This method batches the drawing of the given objects to this texture, + * without causing a WebGL bind or batch flush for each one. + * + * It is faster than calling `draw`, but you must be careful to manage the + * flow of code and remember to call `endDraw()`. If you don't need to draw large + * numbers of objects it's much safer and easier to use the `draw` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * RenderTexture.beginDraw(); + * + * // repeat n times: + * RenderTexture.batchDraw(); + * // or + * RenderTexture.batchDrawFrame(); + * + * // Call once: + * RenderTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Render Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * This method can accept any of the following: + * + * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. + * * Tilemap Layers. + * * A Group. The contents of which will be iterated and drawn in turn. + * * A Container. The contents of which will be iterated fully, and drawn in turn. + * * A Scene's Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture or Render Texture. + * * A Texture Frame instance. + * * A string. This is used to look-up a texture from the Texture Manager. + * + * Note: You cannot draw a Render Texture to itself. + * + * If passing in a Group or Container it will only draw children that return `true` + * when their `willRender()` method is called. I.e. a Container with 10 children, + * 5 of which have `visible=false` will only draw the 5 visible ones. + * + * If passing in an array of Game Objects it will draw them all, regardless if + * they pass a `willRender` check or not. + * + * You can pass in a string in which case it will look for a texture in the Texture + * Manager matching that string, and draw the base frame. If you need to specify + * exactly which frame to draw then use the method `drawFrame` instead. + * + * You can pass in the `x` and `y` coordinates to draw the objects at. The use of + * the coordinates differ based on what objects are being drawn. If the object is + * a Group, Container or Display List, the coordinates are _added_ to the positions + * of the children. For all other types of object, the coordinates are exact. + * + * The `alpha` and `tint` values are only used by Texture Frames. + * Game Objects use their own alpha and tint values when being drawn. + * + * @method Phaser.GameObjects.RenderTexture#batchDraw + * @since 3.50.0 + * + * @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Dynamic or Texture, Texture Frame or an array of any of these. + * @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object. + * @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. + * + * @return {this} This Render Texture instance. + */ + batchDraw: function (entries, x, y, alpha, tint) + { + this.texture.batchDraw(entries, x, y, alpha, tint); + return this; + }, -/***/ }), -/* 246 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Use this method if you have already called `beginDraw` and need to batch + * draw a large number of texture frames to this Render Texture. + * + * This method batches the drawing of the given frames to this Render Texture, + * without causing a WebGL bind or batch flush for each one. + * + * It is faster than calling `drawFrame`, but you must be careful to manage the + * flow of code and remember to call `endDraw()`. If you don't need to draw large + * numbers of frames it's much safer and easier to use the `drawFrame` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * RenderTexture.beginDraw(); + * + * // repeat n times: + * RenderTexture.batchDraw(); + * // or + * RenderTexture.batchDrawFrame(); + * + * // Call once: + * RenderTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Render Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * + * You can optionally provide a position, alpha and tint value to apply to the frame + * before it is drawn. + * + * @method Phaser.GameObjects.RenderTexture#batchDrawFrame + * @since 3.50.0 + * + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. + * @param {number} [x=0] - The x position to draw the frame at. + * @param {number} [y=0] - The y position to draw the frame at. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. + * + * @return {this} This Render Texture instance. + */ + batchDrawFrame: function (key, frame, x, y, alpha, tint) + { + this.texture.batchDrawFrame(key, frame, x, y, alpha, tint); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var CONST = __webpack_require__(62); + /** + * Use this method to finish batch drawing to this Render Texture. + * + * Doing so will stop the WebGL Renderer from capturing draws and then blit the + * framebuffer to the Render Target owned by this texture. + * + * Calling this method without first calling `beginDraw` will have no effect. + * + * Batch drawing is faster than calling `draw`, but you must be careful to manage the + * flow of code and remember to call `endDraw()` when you're finished. + * + * If you don't need to draw large numbers of objects it's much safer and easier + * to use the `draw` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * RenderTexture.beginDraw(); + * + * // repeat n times: + * RenderTexture.batchDraw(); + * // or + * RenderTexture.batchDrawFrame(); + * + * // Call once: + * RenderTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Render Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * @method Phaser.GameObjects.RenderTexture#endDraw + * @since 3.50.0 + * + * @param {boolean} [erase=false] - Draws all objects in this batch using a blend mode of ERASE. This has the effect of erasing any filled pixels in the objects being drawn. + * + * @return {this} This Render Texture instance. + */ + endDraw: function (erase) + { + this.texture.endDraw(erase); -/** - * Calculates and returns the horizontal overlap between two arcade physics bodies and sets their properties - * accordingly, including: `touching.left`, `touching.right`, `touching.none` and `overlapX'. - * - * @function Phaser.Physics.Arcade.GetOverlapX - * @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 - Is this an overlap only check, or part of separation? - * @param {number} bias - A value added to the delta values during collision checks. Increase it to prevent sprite tunneling(sprites passing through another instead of colliding). - * - * @return {number} The amount of overlap. - */ -var GetOverlapX = function (body1, body2, overlapOnly, bias) -{ - var overlap = 0; - var maxOverlap = body1.deltaAbsX() + body2.deltaAbsX() + bias; + return this; + }, - if (body1._dx === 0 && body2._dx === 0) - { - // They overlap but neither of them are moving - body1.embedded = true; - body2.embedded = true; - } - else if (body1._dx > body2._dx) + /** + * Takes a snapshot of the given area of this Render Texture. + * + * The snapshot is taken immediately, but the results are returned via the given callback. + * + * To capture the whole Render Texture see the `snapshot` method. + * To capture just a specific pixel, see the `snapshotPixel` method. + * + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer + * into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally + * creating an Image object from it, which is the image returned to the callback provided. + * + * All in all, this is a computationally expensive and blocking process, which gets more expensive + * the larger the resolution this Render Texture has, so please be careful how you employ this in your game. + * + * @method Phaser.GameObjects.RenderTexture#snapshotArea + * @since 3.19.0 + * + * @param {number} x - The x coordinate to grab from. + * @param {number} y - The y coordinate to grab from. + * @param {number} width - The width of the area to grab. + * @param {number} height - The height of the area to grab. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This Render Texture instance. + */ + snapshotArea: function (x, y, width, height, callback, type, encoderOptions) { - // Body1 is moving right and / or Body2 is moving left - overlap = body1.right - body2.x; - - if ((overlap > maxOverlap && !overlapOnly) || body1.checkCollision.right === false || body2.checkCollision.left === false) - { - overlap = 0; - } - else - { - body1.touching.none = false; - body1.touching.right = true; + this.texture.snapshotArea(x, y, width, height, callback, type, encoderOptions); - body2.touching.none = false; - body2.touching.left = true; + return this; + }, - if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) - { - body1.blocked.none = false; - body1.blocked.right = true; - } + /** + * Takes a snapshot of the whole of this Render Texture. + * + * The snapshot is taken immediately, but the results are returned via the given callback. + * + * To capture a portion of this Render Texture see the `snapshotArea` method. + * To capture just a specific pixel, see the `snapshotPixel` method. + * + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer + * into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally + * creating an Image object from it, which is the image returned to the callback provided. + * + * All in all, this is a computationally expensive and blocking process, which gets more expensive + * the larger the resolution this Render Texture has, so please be careful how you employ this in your game. + * + * @method Phaser.GameObjects.RenderTexture#snapshot + * @since 3.19.0 + * + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This Render Texture instance. + */ + snapshot: function (callback, type, encoderOptions) + { + return this.snapshotArea(0, 0, this.width, this.height, callback, type, encoderOptions); + }, - if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) - { - body2.blocked.none = false; - body2.blocked.left = true; - } - } - } - else if (body1._dx < body2._dx) + /** + * Takes a snapshot of the given pixel from this Render Texture. + * + * The snapshot is taken immediately, but the results are returned via the given callback. + * + * To capture the whole Render Texture see the `snapshot` method. + * To capture a portion of this Render Texture see the `snapshotArea` method. + * + * Unlike the two other snapshot methods, this one will send your callback a `Color` object + * containing the color data for the requested pixel. It doesn't need to create an internal + * Canvas or Image object, so is a lot faster to execute, using less memory than the other snapshot methods. + * + * @method Phaser.GameObjects.RenderTexture#snapshotPixel + * @since 3.19.0 + * + * @param {number} x - The x coordinate of the pixel to get. + * @param {number} y - The y coordinate of the pixel to get. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted. + * + * @return {this} This Render Texture instance. + */ + snapshotPixel: function (x, y, callback) { - // Body1 is moving left and/or Body2 is moving right - overlap = body1.x - body2.width - body2.x; + return this.snapshotArea(x, y, 1, 1, callback, 'pixel'); + }, - if ((-overlap > maxOverlap && !overlapOnly) || body1.checkCollision.left === false || body2.checkCollision.right === false) - { - overlap = 0; - } - else + /** + * Internal destroy handler, called as part of the destroy process. + * + * @method Phaser.GameObjects.RenderTexture#preDestroy + * @protected + * @since 3.9.0 + */ + preDestroy: function () + { + if (!this._saved) { - body1.touching.none = false; - body1.touching.left = true; - - body2.touching.none = false; - body2.touching.right = true; - - if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) - { - body1.blocked.none = false; - body1.blocked.left = true; - } - - if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) - { - body2.blocked.none = false; - body2.blocked.right = true; - } + this.texture.destroy(); } } - // Resets the overlapX to zero if there is no overlap, or to the actual pixel value if there is - body1.overlapX = overlap; - body2.overlapX = overlap; - - return overlap; -}; +}); -module.exports = GetOverlapX; +module.exports = RenderTexture; /***/ }), -/* 247 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 85692: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(62); +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var RenderTexture = __webpack_require__(15996); /** - * Calculates and returns the vertical overlap between two arcade physics bodies and sets their properties - * accordingly, including: `touching.up`, `touching.down`, `touching.none` and `overlapY'. + * Creates a new Render Texture Game Object and returns it. * - * @function Phaser.Physics.Arcade.GetOverlapY - * @since 3.0.0 + * Note: This method will only be available if the Render Texture Game Object has been built into Phaser. * - * @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 - Is this an overlap only check, or part of separation? - * @param {number} bias - A value added to the delta values during collision checks. Increase it to prevent sprite tunneling(sprites passing through another instead of colliding). + * A Render Texture is a combination of Dynamic Texture and an Image Game Object, that uses the + * Dynamic Texture to display itself with. * - * @return {number} The amount of overlap. + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. + * + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. + * + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. + * + * @method Phaser.GameObjects.GameObjectCreator#renderTexture + * @since 3.2.0 + * + * @param {Phaser.Types.GameObjects.RenderTexture.RenderTextureConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.RenderTexture} The Game Object that was created. */ -var GetOverlapY = function (body1, body2, overlapOnly, bias) +GameObjectCreator.register('renderTexture', function (config, addToScene) { - var overlap = 0; - var maxOverlap = body1.deltaAbsY() + body2.deltaAbsY() + bias; - - if (body1._dy === 0 && body2._dy === 0) - { - // They overlap but neither of them are moving - body1.embedded = true; - body2.embedded = true; - } - else if (body1._dy > body2._dy) - { - // Body1 is moving down and/or Body2 is moving up - overlap = body1.bottom - body2.y; - - if ((overlap > maxOverlap && !overlapOnly) || body1.checkCollision.down === false || body2.checkCollision.up === false) - { - overlap = 0; - } - else - { - body1.touching.none = false; - body1.touching.down = true; + if (config === undefined) { config = {}; } - body2.touching.none = false; - body2.touching.up = true; + var x = GetAdvancedValue(config, 'x', 0); + var y = GetAdvancedValue(config, 'y', 0); + var width = GetAdvancedValue(config, 'width', 32); + var height = GetAdvancedValue(config, 'height', 32); - if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) - { - body1.blocked.none = false; - body1.blocked.down = true; - } + var renderTexture = new RenderTexture(this.scene, x, y, width, height); - if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) - { - body2.blocked.none = false; - body2.blocked.up = true; - } - } - } - else if (body1._dy < body2._dy) + if (addToScene !== undefined) { - // Body1 is moving up and/or Body2 is moving down - overlap = body1.y - body2.bottom; - - if ((-overlap > maxOverlap && !overlapOnly) || body1.checkCollision.up === false || body2.checkCollision.down === false) - { - overlap = 0; - } - else - { - body1.touching.none = false; - body1.touching.up = true; - - body2.touching.none = false; - body2.touching.down = true; - - if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) - { - body1.blocked.none = false; - body1.blocked.up = true; - } - - if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) - { - body2.blocked.none = false; - body2.blocked.down = true; - } - } + config.add = addToScene; } - // Resets the overlapY to zero if there is no overlap, or to the actual pixel value if there is - body1.overlapY = overlap; - body2.overlapY = overlap; - - return overlap; -}; + BuildGameObject(this.scene, renderTexture, config); -module.exports = GetOverlapY; + return renderTexture; +}); /***/ }), -/* 248 */ -/***/ (function(module, exports) { + +/***/ 29599: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GameObjectFactory = __webpack_require__(61286); +var RenderTexture = __webpack_require__(15996); + /** - * Checks for intersection between the given tile rectangle-like object and an Arcade Physics body. + * Creates a new Render Texture Game Object and adds it to the Scene. * - * @function Phaser.Physics.Arcade.Tilemap.TileIntersectsBody - * @since 3.0.0 + * Note: This method will only be available if the Render Texture Game Object has been built into Phaser. * - * @param {{ left: number, right: number, top: number, bottom: number }} tileWorldRect - A rectangle object that defines the tile placement in the world. - * @param {Phaser.Physics.Arcade.Body} body - The body to check for intersection against. + * A Render Texture is a combination of Dynamic Texture and an Image Game Object, that uses the + * Dynamic Texture to display itself with. * - * @return {boolean} Returns `true` of the tile intersects with the body, otherwise `false`. + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. + * + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. + * + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. + * + * @method Phaser.GameObjects.GameObjectFactory#renderTexture + * @since 3.2.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 {number} [width=32] - The width of the Render Texture. + * @param {number} [height=32] - The height of the Render Texture. + * + * @return {Phaser.GameObjects.RenderTexture} The Game Object that was created. */ -var TileIntersectsBody = function (tileWorldRect, body) +GameObjectFactory.register('renderTexture', function (x, y, width, height) { - // Currently, all bodies are treated as rectangles when colliding with a Tile. - - return !( - body.right <= tileWorldRect.left || - body.bottom <= tileWorldRect.top || - body.position.x >= tileWorldRect.right || - body.position.y >= tileWorldRect.bottom - ); -}; - -module.exports = TileIntersectsBody; + return this.displayList.add(new RenderTexture(this.scene, x, y, width, height)); +}); /***/ }), -/* 249 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 79968: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var AnimationState = __webpack_require__(16569); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var PIPELINE_CONST = __webpack_require__(65641); +var RopeRender = __webpack_require__(58912); +var Vector2 = __webpack_require__(93736); + /** - * @namespace Phaser.Physics.Matter.Components + * @classdesc + * A Rope Game Object. + * + * The Rope object is WebGL only and does not have a Canvas counterpart. + * + * A Rope is a special kind of Game Object that has a texture is stretched along its entire length. + * + * Unlike a Sprite, it isn't restricted to using just a quad and can have as many vertices as you define + * when creating it. The vertices can be arranged in a horizontal or vertical strip and have their own + * color and alpha values as well. + * + * A Ropes origin is always 0.5 x 0.5 and cannot be changed. + * + * @class Rope + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @webglOnly + * @since 3.23.0 + * + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.Texture + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.Visible + * @extends Phaser.GameObjects.Components.ScrollFactor + * + * @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 {string} [texture] - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager. If not given, `__DEFAULT` is used. + * @param {(string|number|null)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * @param {(number|Phaser.Types.Math.Vector2Like[])} [points=2] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided a simple quad is created. See `setPoints` to set this post-creation. + * @param {boolean} [horizontal=true] - Should the vertices of this Rope be aligned horizontally (`true`), or vertically (`false`)? + * @param {number[]} [colors] - An optional array containing the color data for this Rope. You should provide one color value per pair of vertices. + * @param {number[]} [alphas] - An optional array containing the alpha data for this Rope. You should provide one alpha value per pair of vertices. */ +var Rope = new Class({ -module.exports = { + Extends: GameObject, - Bounce: __webpack_require__(1495), - Collision: __webpack_require__(1496), - Force: __webpack_require__(1497), - Friction: __webpack_require__(1498), - Gravity: __webpack_require__(1499), - Mass: __webpack_require__(1500), - Sensor: __webpack_require__(1501), - SetBody: __webpack_require__(1502), - Sleep: __webpack_require__(1503), - Static: __webpack_require__(1520), - Transform: __webpack_require__(1521), - Velocity: __webpack_require__(1522) + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.Depth, + Components.Flip, + Components.Mask, + Components.Pipeline, + Components.PostPipeline, + Components.Size, + Components.Texture, + Components.Transform, + Components.Visible, + Components.ScrollFactor, + RopeRender + ], -}; + initialize: + function Rope (scene, x, y, texture, frame, points, horizontal, colors, alphas) + { + if (texture === undefined) { texture = '__DEFAULT'; } + if (points === undefined) { points = 2; } + if (horizontal === undefined) { horizontal = true; } -/***/ }), -/* 250 */ -/***/ (function(module, exports) { + GameObject.call(this, scene, 'Rope'); -/** -* The `Matter.Pair` module contains methods for creating and manipulating collision pairs. -* -* @class Pair -*/ + /** + * The Animation State of this Rope. + * + * @name Phaser.GameObjects.Rope#anims + * @type {Phaser.Animations.AnimationState} + * @since 3.23.0 + */ + this.anims = new AnimationState(this); -var Pair = {}; + /** + * An array containing the points data for this Rope. + * + * Each point should be given as a Vector2Like object (i.e. a Vector2, Geom.Point or object with public x/y properties). + * + * The point coordinates are given in local space, where 0 x 0 is the start of the Rope strip. + * + * You can modify the contents of this array directly in real-time to create interesting effects. + * If you do so, be sure to call `setDirty` _after_ modifying this array, so that the vertices data is + * updated before the next render. Alternatively, you can use the `setPoints` method instead. + * + * Should you need to change the _size_ of this array, then you should always use the `setPoints` method. + * + * @name Phaser.GameObjects.Rope#points + * @type {Phaser.Types.Math.Vector2Like[]} + * @since 3.23.0 + */ + this.points = points; -module.exports = Pair; + /** + * An array containing the vertices data for this Rope. + * + * This data is calculated automatically in the `updateVertices` method, based on the points provided. + * + * @name Phaser.GameObjects.Rope#vertices + * @type {Float32Array} + * @since 3.23.0 + */ + this.vertices; -(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; + /** + * An array containing the uv data for this Rope. + * + * This data is calculated automatically in the `setPoints` method, based on the points provided. + * + * @name Phaser.GameObjects.Rope#uv + * @type {Float32Array} + * @since 3.23.0 + */ + this.uv; - 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 - }; + /** + * An array containing the color data for this Rope. + * + * Colors should be given as numeric RGB values, such as 0xff0000. + * You should provide _two_ color values for every point in the Rope, one for the top and one for the bottom of each quad. + * + * You can modify the contents of this array directly in real-time, however, should you need to change the _size_ + * of the array, then you should use the `setColors` method instead. + * + * @name Phaser.GameObjects.Rope#colors + * @type {Uint32Array} + * @since 3.23.0 + */ + this.colors; - Pair.update(pair, collision, timestamp); + /** + * An array containing the alpha data for this Rope. + * + * Alphas should be given as float values, such as 0.5. + * You should provide _two_ alpha values for every point in the Rope, one for the top and one for the bottom of each quad. + * + * You can modify the contents of this array directly in real-time, however, should you need to change the _size_ + * of the array, then you should use the `setAlphas` method instead. + * + * @name Phaser.GameObjects.Rope#alphas + * @type {Float32Array} + * @since 3.23.0 + */ + this.alphas; - return pair; - }; + /** + * The tint fill mode. + * + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + * + * @name Phaser.GameObjects.Rope#tintFill + * @type {boolean} + * @since 3.23.0 + */ + this.tintFill = (texture === '__DEFAULT') ? true : false; - /** - * 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 the Rope is marked as `dirty` it will automatically recalculate its vertices + * the next time it renders. You can also force this by calling `updateVertices`. + * + * @name Phaser.GameObjects.Rope#dirty + * @type {boolean} + * @since 3.23.0 + */ + this.dirty = false; - if (collision.collided) { - var supports = collision.supports, - activeContacts = pair.activeContacts, - parentA = collision.parentA, - parentB = collision.parentB; + /** + * Are the Rope vertices aligned horizontally, in a strip, or vertically, in a column? + * + * This property is set during instantiation and cannot be changed directly. + * See the `setVertical` and `setHorizontal` methods. + * + * @name Phaser.GameObjects.Rope#horizontal + * @type {boolean} + * @readonly + * @since 3.23.0 + */ + this.horizontal = horizontal; - 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); + /** + * The horizontally flipped state of the Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * + * @name Phaser.GameObjects.Rope#_flipX + * @type {boolean} + * @default false + * @private + * @since 3.23.0 + */ + this._flipX = false; - for (var i = 0; i < supports.length; i++) { - activeContacts[i] = supports[i].contact; - } + /** + * The vertically flipped state of the Game Object. + * + * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * + * @name Phaser.GameObjects.Rope#_flipY + * @type {boolean} + * @default false + * @private + * @since 3.23.0 + */ + this._flipY = false; - // optimise array size - var supportCount = supports.length; - if (supportCount < activeContacts.length) { - activeContacts.length = supportCount; - } + /** + * Internal Vector2 used for vertices updates. + * + * @name Phaser.GameObjects.Rope#_perp + * @type {Phaser.Math.Vector2} + * @private + * @since 3.23.0 + */ + this._perp = new Vector2(); - 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; - } - }; + /** + * You can optionally choose to render the vertices of this Rope to a Graphics instance. + * + * Achieve this by setting the `debugCallback` and the `debugGraphic` properties. + * + * You can do this in a single call via the `Rope.setDebug` method, which will use the + * built-in debug function. You can also set it to your own callback. The callback + * will be invoked _once per render_ and sent the following parameters: + * + * `debugCallback(src, meshLength, verts)` + * + * `src` is the Rope instance being debugged. + * `meshLength` is the number of mesh vertices in total. + * `verts` is an array of the translated vertex coordinates. + * + * To disable rendering, set this property back to `null`. + * + * @name Phaser.GameObjects.Rope#debugCallback + * @type {function} + * @since 3.23.0 + */ + this.debugCallback = null; - /** - * 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; - } - }; - -})(); - - -/***/ }), -/* 251 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The Graphics instance that the debug vertices will be drawn to, if `setDebug` has + * been called. + * + * @name Phaser.GameObjects.Rope#debugGraphic + * @type {Phaser.GameObjects.Graphics} + * @since 3.23.0 + */ + this.debugGraphic = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.setTexture(texture, frame); + this.setPosition(x, y); + this.setSizeToFrame(); + this.initPipeline(PIPELINE_CONST.ROPE_PIPELINE); -/** - * @namespace Phaser.Tilemaps.Components - */ + if (Array.isArray(points)) + { + this.resizeArrays(points.length); + } -module.exports = { + this.setPoints(points, colors, alphas); - CalculateFacesAt: __webpack_require__(252), - CalculateFacesWithin: __webpack_require__(63), - CheckIsoBounds: __webpack_require__(541), - Copy: __webpack_require__(1420), - CreateFromTiles: __webpack_require__(1421), - CullBounds: __webpack_require__(543), - CullTiles: __webpack_require__(544), - Fill: __webpack_require__(1422), - FilterTiles: __webpack_require__(1423), - FindByIndex: __webpack_require__(1424), - FindTile: __webpack_require__(1425), - ForEachTile: __webpack_require__(1426), - GetCullTilesFunction: __webpack_require__(1427), - GetTileAt: __webpack_require__(158), - GetTileAtWorldXY: __webpack_require__(1428), - GetTilesWithin: __webpack_require__(26), - GetTilesWithinShape: __webpack_require__(1429), - GetTilesWithinWorldXY: __webpack_require__(529), - GetTileToWorldXFunction: __webpack_require__(1430), - GetTileToWorldXYFunction: __webpack_require__(1431), - GetTileToWorldYFunction: __webpack_require__(1432), - GetWorldToTileXFunction: __webpack_require__(1433), - GetWorldToTileXYFunction: __webpack_require__(1434), - GetWorldToTileYFunction: __webpack_require__(1435), - HasTileAt: __webpack_require__(562), - HasTileAtWorldXY: __webpack_require__(1436), - HexagonalCullBounds: __webpack_require__(546), - HexagonalCullTiles: __webpack_require__(545), - HexagonalTileToWorldXY: __webpack_require__(550), - HexagonalTileToWorldY: __webpack_require__(554), - HexagonalWorldToTileXY: __webpack_require__(556), - HexagonalWorldToTileY: __webpack_require__(560), - IsInLayerBounds: __webpack_require__(119), - IsometricCullTiles: __webpack_require__(547), - IsometricTileToWorldXY: __webpack_require__(551), - IsometricWorldToTileXY: __webpack_require__(557), - PutTileAt: __webpack_require__(257), - PutTileAtWorldXY: __webpack_require__(1437), - PutTilesAt: __webpack_require__(1438), - Randomize: __webpack_require__(1439), - RemoveTileAt: __webpack_require__(563), - RemoveTileAtWorldXY: __webpack_require__(1440), - RenderDebug: __webpack_require__(1441), - ReplaceByIndex: __webpack_require__(542), - RunCull: __webpack_require__(159), - SetCollision: __webpack_require__(1442), - SetCollisionBetween: __webpack_require__(1443), - SetCollisionByExclusion: __webpack_require__(1444), - SetCollisionByProperty: __webpack_require__(1445), - SetCollisionFromCollisionGroup: __webpack_require__(1446), - SetLayerCollisionIndex: __webpack_require__(160), - SetTileCollision: __webpack_require__(72), - SetTileIndexCallback: __webpack_require__(1447), - SetTileLocationCallback: __webpack_require__(1448), - Shuffle: __webpack_require__(1449), - StaggeredCullBounds: __webpack_require__(549), - StaggeredCullTiles: __webpack_require__(548), - StaggeredTileToWorldXY: __webpack_require__(552), - StaggeredTileToWorldY: __webpack_require__(555), - StaggeredWorldToTileXY: __webpack_require__(558), - StaggeredWorldToTileY: __webpack_require__(561), - SwapByIndex: __webpack_require__(1450), - TileToWorldX: __webpack_require__(253), - TileToWorldXY: __webpack_require__(553), - TileToWorldY: __webpack_require__(254), - WeightedRandomize: __webpack_require__(1451), - WorldToTileX: __webpack_require__(255), - WorldToTileXY: __webpack_require__(559), - WorldToTileY: __webpack_require__(256) - -}; - - -/***/ }), -/* 252 */ -/***/ (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__(158); + this.updateVertices(); + }, -/** - * 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. - * - * @function Phaser.Tilemaps.Components.CalculateFacesAt - * @since 3.0.0 - * - * @param {number} tileX - The x coordinate. - * @param {number} tileY - The y coordinate. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - */ -var CalculateFacesAt = function (tileX, tileY, layer) -{ - var tile = GetTileAt(tileX, tileY, true, layer); - var above = GetTileAt(tileX, tileY - 1, true, layer); - var below = GetTileAt(tileX, tileY + 1, true, layer); - var left = GetTileAt(tileX - 1, tileY, true, layer); - var right = GetTileAt(tileX + 1, tileY, true, layer); - var tileCollides = tile && tile.collides; + // Overrides Game Object method + addedToScene: function () + { + this.scene.sys.updateList.add(this); + }, - // Assume the changed tile has all interesting edges - if (tileCollides) + // Overrides Game Object method + removedFromScene: function () { - tile.faceTop = true; - tile.faceBottom = true; - tile.faceLeft = true; - tile.faceRight = true; - } + this.scene.sys.updateList.remove(this); + }, - // Reset edges that are shared between tile and its neighbors - if (above && above.collides) + /** + * The Rope update loop. + * + * @method Phaser.GameObjects.Rope#preUpdate + * @protected + * @since 3.23.0 + * + * @param {number} time - The current timestamp. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. + */ + preUpdate: function (time, delta) { - if (tileCollides) - { - tile.faceTop = false; - } + var prevFrame = this.anims.currentFrame; - above.faceBottom = !tileCollides; - } + this.anims.update(time, delta); - if (below && below.collides) - { - if (tileCollides) + if (this.anims.currentFrame !== prevFrame) { - tile.faceBottom = false; + this.updateUVs(); + this.updateVertices(); } + }, - below.faceTop = !tileCollides; - } + /** + * Start playing the given animation. + * + * @method Phaser.GameObjects.Rope#play + * @since 3.23.0 + * + * @param {string} key - The string-based key of the animation to play. + * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. + * @param {number} [startFrame=0] - Optionally start the animation playing from this frame index. + * + * @return {this} This Game Object. + */ + play: function (key, ignoreIfPlaying, startFrame) + { + this.anims.play(key, ignoreIfPlaying, startFrame); - if (left && left.collides) + return this; + }, + + /** + * Flags this Rope as being dirty. A dirty rope will recalculate all of its vertices data + * the _next_ time it renders. You should set this rope as dirty if you update the points + * array directly. + * + * @method Phaser.GameObjects.Rope#setDirty + * @since 3.23.0 + * + * @return {this} This Game Object instance. + */ + setDirty: function () { - if (tileCollides) - { - tile.faceLeft = false; - } + this.dirty = true; - left.faceRight = !tileCollides; - } + return this; + }, - if (right && right.collides) + /** + * Sets the alignment of the points in this Rope to be horizontal, in a strip format. + * + * Calling this method will reset this Rope. The current points, vertices, colors and alpha + * values will be reset to thoes values given as parameters. + * + * @method Phaser.GameObjects.Rope#setHorizontal + * @since 3.23.0 + * + * @param {(number|Phaser.Types.Math.Vector2Like[])} [points] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided the current points length is used. + * @param {(number|number[])} [colors] - Either a single color value, or an array of values. + * @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values. + * + * @return {this} This Game Object instance. + */ + setHorizontal: function (points, colors, alphas) { - if (tileCollides) + if (points === undefined) { points = this.points.length; } + + if (this.horizontal) { - tile.faceRight = false; + return this; } - right.faceLeft = !tileCollides; - } + this.horizontal = true; - if (tile && !tile.collides) + return this.setPoints(points, colors, alphas); + }, + + /** + * Sets the alignment of the points in this Rope to be vertical, in a column format. + * + * Calling this method will reset this Rope. The current points, vertices, colors and alpha + * values will be reset to thoes values given as parameters. + * + * @method Phaser.GameObjects.Rope#setVertical + * @since 3.23.0 + * + * @param {(number|Phaser.Types.Math.Vector2Like[])} [points] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided the current points length is used. + * @param {(number|number[])} [colors] - Either a single color value, or an array of values. + * @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values. + * + * @return {this} This Game Object instance. + */ + setVertical: function (points, colors, alphas) { - tile.resetFaces(); - } + if (points === undefined) { points = this.points.length; } - return tile; -}; + if (!this.horizontal) + { + return this; + } -module.exports = CalculateFacesAt; + this.horizontal = false; + return this.setPoints(points, colors, alphas); + }, -/***/ }), -/* 253 */ -/***/ (function(module, exports) { + /** + * Sets the tint fill mode. + * + * Mode 0 (`false`) is an additive tint, the default, which blends the vertices colors with the texture. + * This mode respects the texture alpha. + * + * Mode 1 (`true`) is a fill tint. Unlike an additive tint, a fill-tint literally replaces the pixel colors + * from the texture with those in the tint. You can use this for effects such as making a player flash 'white' + * if hit by something. This mode respects the texture alpha. + * + * See the `setColors` method for details of how to color each of the vertices. + * + * @method Phaser.GameObjects.Rope#setTintFill + * @webglOnly + * @since 3.23.0 + * + * @param {boolean} [value=false] - Set to `false` for an Additive tint or `true` fill tint with alpha. + * + * @return {this} This Game Object instance. + */ + setTintFill: function (value) + { + if (value === undefined) { value = false; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.tintFill = value; -/** - * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the - * layer's position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} - */ -var TileToWorldX = function (tileX, camera, layer) -{ - var tileWidth = layer.baseTileWidth; - var tilemapLayer = layer.tilemapLayer; - var layerWorldX = 0; + return this; + }, - if (tilemapLayer) + /** + * Set the alpha values used by the Rope during rendering. + * + * You can provide the values in a number of ways: + * + * 1) One single numeric value: `setAlphas(0.5)` - This will set a single alpha for the whole Rope. + * 2) Two numeric value: `setAlphas(1, 0.5)` - This will set a 'top' and 'bottom' alpha value across the whole Rope. + * 3) An array of values: `setAlphas([ 1, 0.5, 0.2 ])` + * + * If you provide an array of values and the array has exactly the same number of values as `points` in the Rope, it + * will use each alpha value per rope segment. + * + * If the provided array has a different number of values than `points` then it will use the values in order, from + * the first Rope segment and on, until it runs out of values. This allows you to control the alpha values at all + * vertices in the Rope. + * + * Note this method is called `setAlphas` (plural) and not `setAlpha`. + * + * @method Phaser.GameObjects.Rope#setAlphas + * @since 3.23.0 + * + * @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values. If nothing is provided alpha is reset to 1. + * @param {number} [bottomAlpha] - An optional bottom alpha value. See the method description for details. + * + * @return {this} This Game Object instance. + */ + setAlphas: function (alphas, bottomAlpha) { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + var total = this.points.length; - tileWidth *= tilemapLayer.scaleX; - } + if (total < 1) + { + return this; + } - return layerWorldX + tileX * tileWidth; -}; + var currentAlphas = this.alphas; -module.exports = TileToWorldX; + if (alphas === undefined) + { + alphas = [ 1 ]; + } + else if (!Array.isArray(alphas) && bottomAlpha === undefined) + { + alphas = [ alphas ]; + } + var i; + var index = 0; -/***/ }), -/* 254 */ -/***/ (function(module, exports) { + if (bottomAlpha !== undefined) + { + // Top / Bottom alpha pair + for (i = 0; i < total; i++) + { + index = i * 2; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + currentAlphas[index] = alphas; + currentAlphas[index + 1] = bottomAlpha; + } + } + else if (alphas.length === total) + { + // If there are exactly the same number of alphas as points, we'll combine the alphas + for (i = 0; i < total; i++) + { + index = i * 2; -/** - * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layer's position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in world coordinates. - */ -var TileToWorldY = function (tileY, camera, layer) -{ - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - var layerWorldY = 0; + currentAlphas[index] = alphas[i]; + currentAlphas[index + 1] = alphas[i]; + } + } + else + { + var prevAlpha = alphas[0]; - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } + for (i = 0; i < total; i++) + { + index = i * 2; - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + if (alphas.length > index) + { + prevAlpha = alphas[index]; + } - tileHeight *= tilemapLayer.scaleY; - } + currentAlphas[index] = prevAlpha; - return layerWorldY + tileY * tileHeight; -}; + if (alphas.length > index + 1) + { + prevAlpha = alphas[index + 1]; + } -module.exports = TileToWorldY; + currentAlphas[index + 1] = prevAlpha; + } + } + return this; -/***/ }), -/* 255 */ -/***/ (function(module, exports) { + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Set the color values used by the Rope during rendering. + * + * Colors are used to control the level of tint applied across the Rope texture. + * + * You can provide the values in a number of ways: + * + * * One single numeric value: `setColors(0xff0000)` - This will set a single color tint for the whole Rope. + * * An array of values: `setColors([ 0xff0000, 0x00ff00, 0x0000ff ])` + * + * If you provide an array of values and the array has exactly the same number of values as `points` in the Rope, it + * will use each color per rope segment. + * + * If the provided array has a different number of values than `points` then it will use the values in order, from + * the first Rope segment and on, until it runs out of values. This allows you to control the color values at all + * vertices in the Rope. + * + * @method Phaser.GameObjects.Rope#setColors + * @since 3.23.0 + * + * @param {(number|number[])} [colors] - Either a single color value, or an array of values. If nothing is provided color is reset to 0xffffff. + * + * @return {this} This Game Object instance. + */ + setColors: function (colors) + { + var total = this.points.length; -/** - * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the - * layer's position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The X location in tile units. - */ -var WorldToTileX = function (worldX, snapToFloor, camera, layer) -{ - if (snapToFloor === undefined) { snapToFloor = true; } + if (total < 1) + { + return this; + } - var tileWidth = layer.baseTileWidth; - var tilemapLayer = layer.tilemapLayer; + var currentColors = this.colors; - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } + if (colors === undefined) + { + colors = [ 0xffffff ]; + } + else if (!Array.isArray(colors)) + { + colors = [ colors ]; + } - // 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)); + var i; + var index = 0; - tileWidth *= tilemapLayer.scaleX; - } + if (colors.length === total) + { + // If there are exactly the same number of colors as points, we'll combine the colors + for (i = 0; i < total; i++) + { + index = i * 2; - return (snapToFloor) ? Math.floor(worldX / tileWidth) : worldX / tileWidth; -}; + currentColors[index] = colors[i]; + currentColors[index + 1] = colors[i]; + } + } + else + { + var prevColor = colors[0]; -module.exports = WorldToTileX; + for (i = 0; i < total; i++) + { + index = i * 2; + if (colors.length > index) + { + prevColor = colors[index]; + } -/***/ }), -/* 256 */ -/***/ (function(module, exports) { + currentColors[index] = prevColor; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (colors.length > index + 1) + { + prevColor = colors[index + 1]; + } -/** - * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the - * layer's position, scale and scroll. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {number} The Y location in tile units. - */ -var WorldToTileY = function (worldY, snapToFloor, camera, layer) -{ - if (snapToFloor === undefined) { snapToFloor = true; } + currentColors[index + 1] = prevColor; + } + } - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; + return this; + }, - if (tilemapLayer) + /** + * Sets the points used by this Rope. + * + * The points should be provided as an array of Vector2, or vector2-like objects (i.e. those with public x/y properties). + * + * Each point corresponds to one segment of the Rope. The more points in the array, the more segments the rope has. + * + * Point coordinates are given in local-space, not world-space, and are directly related to the size of the texture + * this Rope object is using. + * + * For example, a Rope using a 512 px wide texture, split into 4 segments (128px each) would use the following points: + * + * ```javascript + * rope.setPoints([ + * { x: 0, y: 0 }, + * { x: 128, y: 0 }, + * { x: 256, y: 0 }, + * { x: 384, y: 0 } + * ]); + * ``` + * + * Or, you can provide an integer to do the same thing: + * + * ```javascript + * rope.setPoints(4); + * ``` + * + * Which will divide the Rope into 4 equally sized segments based on the frame width. + * + * Note that calling this method with a different number of points than the Rope has currently will + * _reset_ the color and alpha values, unless you provide them as arguments to this method. + * + * @method Phaser.GameObjects.Rope#setPoints + * @since 3.23.0 + * + * @param {(number|Phaser.Types.Math.Vector2Like[])} [points=2] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided a simple quad is created. + * @param {(number|number[])} [colors] - Either a single color value, or an array of values. + * @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values. + * + * @return {this} This Game Object instance. + */ + setPoints: function (points, colors, alphas) { - 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)); + if (points === undefined) { points = 2; } - tileHeight *= tilemapLayer.scaleY; - } + if (typeof points === 'number') + { + // Generate an array based on the points + var segments = points; - return (snapToFloor) ? Math.floor(worldY / tileHeight) : worldY / tileHeight; -}; + if (segments < 2) + { + segments = 2; + } -module.exports = WorldToTileY; + points = []; + var s; + var frameSegment; + var offset; -/***/ }), -/* 257 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.horizontal) + { + offset = -(this.frame.halfWidth); + frameSegment = this.frame.width / (segments - 1); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + for (s = 0; s < segments; s++) + { + points.push({ x: offset + s * frameSegment, y: 0 }); + } + } + else + { + offset = -(this.frame.halfHeight); + frameSegment = this.frame.height / (segments - 1); -var Tile = __webpack_require__(85); -var IsInLayerBounds = __webpack_require__(119); -var CalculateFacesAt = __webpack_require__(252); -var SetTileCollision = __webpack_require__(72); + for (s = 0; s < segments; s++) + { + points.push({ x: 0, y: offset + s * frameSegment }); + } + } + } -/** - * 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. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile} The Tile object that was created or added to this map. - */ -var PutTileAt = function (tile, tileX, tileY, recalculateFaces, layer) -{ - if (recalculateFaces === undefined) { recalculateFaces = true; } + var total = points.length; + var currentTotal = this.points.length; - if (!IsInLayerBounds(tileX, tileY, layer)) - { - return null; - } + if (total < 1) + { + console.warn('Rope: Not enough points given'); - var oldTile = layer.data[tileY][tileX]; - var oldTileCollides = oldTile && oldTile.collides; + return this; + } + else if (total === 1) + { + points.unshift({ x: 0, y: 0 }); + total++; + } - if (tile instanceof Tile) - { - if (layer.data[tileY][tileX] === null) + if (currentTotal !== total) { - layer.data[tileY][tileX] = new Tile(layer, tile.index, tileX, tileY, layer.tileWidth, layer.tileHeight); + this.resizeArrays(total); } - layer.data[tileY][tileX].copy(tile); - } - else - { - var index = tile; + this.dirty = true; - if (layer.data[tileY][tileX] === null) + this.points = points; + + this.updateUVs(); + + if (colors !== undefined && colors !== null) { - layer.data[tileY][tileX] = new Tile(layer, index, tileX, tileY, layer.tileWidth, layer.tileHeight); + this.setColors(colors); } - else + + if (alphas !== undefined && alphas !== null) { - layer.data[tileY][tileX].index = index; + this.setAlphas(alphas); } - } - - // Updating colliding flag on the new tile - var newTile = layer.data[tileY][tileX]; - var collides = layer.collideIndexes.indexOf(newTile.index) !== -1; - SetTileCollision(newTile, collides); + return this; + }, - // Recalculate faces only if the colliding flag at (tileX, tileY) has changed - if (recalculateFaces && (oldTileCollides !== newTile.collides)) + /** + * Updates all of the UVs based on the Rope.points and `flipX` and `flipY` settings. + * + * @method Phaser.GameObjects.Rope#updateUVs + * @since 3.23.0 + * + * @return {this} This Game Object instance. + */ + updateUVs: function () { - CalculateFacesAt(tileX, tileY, layer); - } + var currentUVs = this.uv; + var total = this.points.length; - return newTile; -}; + var u0 = this.frame.u0; + var v0 = this.frame.v0; + var u1 = this.frame.u1; + var v1 = this.frame.v1; -module.exports = PutTileAt; + var partH = (u1 - u0) / (total - 1); + var partV = (v1 - v0) / (total - 1); + for (var i = 0; i < total; i++) + { + var index = i * 4; -/***/ }), -/* 258 */ -/***/ (function(module, exports, __webpack_require__) { + var uv0; + var uv1; + var uv2; + var uv3; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.horizontal) + { + if (this._flipX) + { + uv0 = u1 - (i * partH); + uv2 = u1 - (i * partH); + } + else + { + uv0 = u0 + (i * partH); + uv2 = u0 + (i * partH); + } -var CONST = __webpack_require__(29); + if (this._flipY) + { + uv1 = v1; + uv3 = v0; + } + else + { + uv1 = v0; + uv3 = v1; + } + } + else + { + if (this._flipX) + { + uv0 = u0; + uv2 = u1; + } + else + { + uv0 = u1; + uv2 = u0; + } -/** - * Get the Tilemap orientation from the given string. - * - * @function Phaser.Tilemaps.Parsers.FromOrientationString - * @since 3.50.0 - * - * @param {string} [orientation] - The orientation type as a string. - * - * @return {Phaser.Tilemaps.OrientationType} The Tilemap Orientation type. - */ -var FromOrientationString = function (orientation) -{ - orientation = orientation.toLowerCase(); + if (this._flipY) + { + uv1 = v1 - (i * partV); + uv3 = v1 - (i * partV); + } + else + { + uv1 = v0 + (i * partV); + uv3 = v0 + (i * partV); + } + } - if (orientation === 'isometric') - { - return CONST.ISOMETRIC; - } - else if (orientation === 'staggered') - { - return CONST.STAGGERED; - } - else if (orientation === 'hexagonal') - { - return CONST.HEXAGONAL; - } - else - { - return CONST.ORTHOGONAL; - } -}; + currentUVs[index + 0] = uv0; + currentUVs[index + 1] = uv1; + currentUVs[index + 2] = uv2; + currentUVs[index + 3] = uv3; + } -module.exports = FromOrientationString; + return this; + }, + /** + * Resizes all of the internal arrays: `vertices`, `uv`, `colors` and `alphas` to the new + * given Rope segment total. + * + * @method Phaser.GameObjects.Rope#resizeArrays + * @since 3.23.0 + * + * @param {number} newSize - The amount of segments to split the Rope in to. + * + * @return {this} This Game Object instance. + */ + resizeArrays: function (newSize) + { + var colors = this.colors; + var alphas = this.alphas; -/***/ }), -/* 259 */ -/***/ (function(module, exports, __webpack_require__) { + this.vertices = new Float32Array(newSize * 4); + this.uv = new Float32Array(newSize * 4); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + colors = new Uint32Array(newSize * 2); + alphas = new Float32Array(newSize * 2); -var Formats = __webpack_require__(40); -var LayerData = __webpack_require__(120); -var MapData = __webpack_require__(121); -var Tile = __webpack_require__(85); + for (var i = 0; i < newSize * 2; i++) + { + colors[i] = 0xffffff; + alphas[i] = 1; + } -/** - * Parses a 2D array of tile indexes into a new MapData object with a single layer. - * - * @function Phaser.Tilemaps.Parsers.Parse2DArray - * @since 3.0.0 - * - * @param {string} name - The name of the tilemap, used to set the name on the MapData. - * @param {number[][]} data - 2D array, CSV string or Tiled JSON object. - * @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 MapData object. - */ -var Parse2DArray = function (name, data, tileWidth, tileHeight, insertNull) -{ - var layerData = new LayerData({ - tileWidth: tileWidth, - tileHeight: tileHeight - }); - - var mapData = new MapData({ - name: name, - tileWidth: tileWidth, - tileHeight: tileHeight, - format: Formats.ARRAY_2D, - layers: [ layerData ] - }); + this.colors = colors; + this.alphas = alphas; - var tiles = []; - var height = data.length; - var width = 0; + // updateVertices during next render + this.dirty = true; - for (var y = 0; y < data.length; y++) + return this; + }, + + /** + * Updates the vertices based on the Rope points. + * + * This method is called automatically during rendering if `Rope.dirty` is `true`, which is set + * by the `setPoints` and `setDirty` methods. You should flag the Rope as being dirty if you modify + * the Rope points directly. + * + * @method Phaser.GameObjects.Rope#updateVertices + * @since 3.23.0 + * + * @return {this} This Game Object instance. + */ + updateVertices: function () { - tiles[y] = []; - var row = data[y]; + var perp = this._perp; + var points = this.points; + var vertices = this.vertices; - for (var x = 0; x < row.length; x++) + var total = points.length; + + this.dirty = false; + + if (total < 1) { - var tileIndex = parseInt(row[x], 10); + return; + } - if (isNaN(tileIndex) || tileIndex === -1) + var nextPoint; + var lastPoint = points[0]; + + var frameSize = (this.horizontal) ? this.frame.halfHeight : this.frame.halfWidth; + + for (var i = 0; i < total; i++) + { + var point = points[i]; + var index = i * 4; + + if (i < total - 1) { - tiles[y][x] = insertNull - ? null - : new Tile(layerData, -1, x, y, tileWidth, tileHeight); + nextPoint = points[i + 1]; } else { - tiles[y][x] = new Tile(layerData, tileIndex, x, y, tileWidth, tileHeight); + nextPoint = point; } - } - - if (width === 0) - { - width = row.length; - } - } - mapData.width = layerData.width = width; - mapData.height = layerData.height = height; - mapData.widthInPixels = layerData.widthInPixels = width * tileWidth; - mapData.heightInPixels = layerData.heightInPixels = height * tileHeight; - layerData.data = tiles; + perp.x = nextPoint.y - lastPoint.y; + perp.y = -(nextPoint.x - lastPoint.x); - return mapData; -}; + var perpLength = perp.length(); -module.exports = Parse2DArray; + perp.x /= perpLength; + perp.y /= perpLength; + perp.x *= frameSize; + perp.y *= frameSize; -/***/ }), -/* 260 */ -/***/ (function(module, exports, __webpack_require__) { + vertices[index] = point.x + perp.x; + vertices[index + 1] = point.y + perp.y; + vertices[index + 2] = point.x - perp.x; + vertices[index + 3] = point.y - perp.y; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + lastPoint = point; + } -var Pick = __webpack_require__(571); -var ParseGID = __webpack_require__(261); + return this; + }, -var copyPoints = function (p) { return { x: p.x, y: p.y }; }; + /** + * This method enables rendering of the Rope vertices to the given Graphics instance. + * + * If you enable this feature, you **must** call `Graphics.clear()` in your Scene `update`, + * otherwise the Graphics instance you provide to debug will fill-up with draw calls, + * eventually crashing the browser. This is not done automatically to allow you to debug + * draw multiple Rope objects to a single Graphics instance. + * + * The Rope class has a built-in debug rendering callback `Rope.renderDebugVerts`, however + * you can also provide your own callback to be used instead. Do this by setting the `callback` parameter. + * + * The callback is invoked _once per render_ and sent the following parameters: + * + * `callback(src, meshLength, verts)` + * + * `src` is the Rope instance being debugged. + * `meshLength` is the number of mesh vertices in total. + * `verts` is an array of the translated vertex coordinates. + * + * If using your own callback you do not have to provide a Graphics instance to this method. + * + * To disable debug rendering, to either your own callback or the built-in one, call this method + * with no arguments. + * + * @method Phaser.GameObjects.Rope#setDebug + * @since 3.23.0 + * + * @param {Phaser.GameObjects.Graphics} [graphic] - The Graphic instance to render to if using the built-in callback. + * @param {function} [callback] - The callback to invoke during debug render. Leave as undefined to use the built-in callback. + * + * @return {this} This Game Object instance. + */ + setDebug: function (graphic, callback) + { + this.debugGraphic = graphic; -var commonObjectProps = [ 'id', 'name', 'type', 'rotation', 'properties', 'visible', 'x', 'y', 'width', 'height' ]; + if (!graphic && !callback) + { + this.debugCallback = null; + } + else if (!callback) + { + this.debugCallback = this.renderDebugVerts; + } + else + { + this.debugCallback = callback; + } -/** - * Convert a Tiled object to an internal parsed object normalising and copying properties over, while applying optional x and y offsets. The parsed object will always have the properties `id`, `name`, `type`, `rotation`, `properties`, `visible`, `x`, `y`, `width` and `height`. Other properties will be added according to the object type (such as text, polyline, gid etc.) - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseObject - * @since 3.0.0 - * - * @param {object} tiledObject - Tiled object to convert to an internal parsed object normalising and copying properties over. - * @param {number} [offsetX=0] - Optional additional offset to apply to the object's x property. Defaults to 0. - * @param {number} [offsetY=0] - Optional additional offset to apply to the object's y property. Defaults to 0. - * - * @return {object} The parsed object containing properties read from the Tiled object according to it's type with x and y values updated according to the given offsets. - */ -var ParseObject = function (tiledObject, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + return this; + }, - var parsedObject = Pick(tiledObject, commonObjectProps); + /** + * The built-in Rope vertices debug rendering method. + * + * See `Rope.setDebug` for more details. + * + * @method Phaser.GameObjects.Rope#renderDebugVerts + * @since 3.23.0 + * + * @param {Phaser.GameObjects.Rope} src - The Rope object being rendered. + * @param {number} meshLength - The number of vertices in the mesh. + * @param {number[]} verts - An array of translated vertex coordinates. + */ + renderDebugVerts: function (src, meshLength, verts) + { + var graphic = src.debugGraphic; - parsedObject.x += offsetX; - parsedObject.y += offsetY; + var px0 = verts[0]; + var py0 = verts[1]; + var px1 = verts[2]; + var py1 = verts[3]; - if (tiledObject.gid) - { - // Object tiles - var gidInfo = ParseGID(tiledObject.gid); - parsedObject.gid = gidInfo.gid; - parsedObject.flippedHorizontal = gidInfo.flippedHorizontal; - parsedObject.flippedVertical = gidInfo.flippedVertical; - parsedObject.flippedAntiDiagonal = gidInfo.flippedAntiDiagonal; - } - else if (tiledObject.polyline) - { - parsedObject.polyline = tiledObject.polyline.map(copyPoints); - } - else if (tiledObject.polygon) - { - parsedObject.polygon = tiledObject.polygon.map(copyPoints); - } - else if (tiledObject.ellipse) - { - parsedObject.ellipse = tiledObject.ellipse; - } - else if (tiledObject.text) - { - parsedObject.text = tiledObject.text; - } - else if (tiledObject.point) - { - parsedObject.point = true; - } - else + graphic.lineBetween(px0, py0, px1, py1); + + for (var i = 4; i < meshLength; i += 4) + { + var x0 = verts[i + 0]; + var y0 = verts[i + 1]; + var x1 = verts[i + 2]; + var y1 = verts[i + 3]; + + graphic.lineBetween(px0, py0, x0, y0); + graphic.lineBetween(px1, py1, x1, y1); + graphic.lineBetween(px1, py1, x0, y0); + graphic.lineBetween(x0, y0, x1, y1); + + px0 = x0; + py0 = y0; + px1 = x1; + py1 = y1; + } + }, + + /** + * Handles the pre-destroy step for the Rope, which removes the Animation component and typed arrays. + * + * @method Phaser.GameObjects.Rope#preDestroy + * @private + * @since 3.23.0 + */ + preDestroy: function () { - // Otherwise, assume it is a rectangle - parsedObject.rectangle = true; + this.anims.destroy(); + + this.anims = undefined; + + this.points = null; + this.vertices = null; + this.uv = null; + this.colors = null; + this.alphas = null; + + this.debugCallback = null; + this.debugGraphic = null; + }, + + /** + * The horizontally flipped state of the Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * + * @name Phaser.GameObjects.Rope#flipX + * @type {boolean} + * @default false + * @since 3.23.0 + */ + flipX: { + + get: function () + { + return this._flipX; + }, + + set: function (value) + { + this._flipX = value; + + return this.updateUVs(); + } + + }, + + /** + * The vertically flipped state of the Game Object. + * + * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * + * @name Phaser.GameObjects.Rope#flipY + * @type {boolean} + * @default false + * @since 3.23.0 + */ + flipY: { + + get: function () + { + return this._flipY; + }, + + set: function (value) + { + this._flipY = value; + + return this.updateUVs(); + } + } - return parsedObject; -}; +}); -module.exports = ParseObject; +module.exports = Rope; /***/ }), -/* 261 */ -/***/ (function(module, exports) { + +/***/ 44598: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FLIPPED_HORIZONTAL = 0x80000000; -var FLIPPED_VERTICAL = 0x40000000; -var FLIPPED_ANTI_DIAGONAL = 0x20000000; // Top-right is swapped with bottom-left corners - /** - * See Tiled documentation on tile flipping: - * http://docs.mapeditor.org/en/latest/reference/tmx-map-format/ - * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseGID - * @since 3.0.0 + * This is a stub function for Rope.Render. There is no Canvas renderer for Rope objects. * - * @param {number} gid - A Tiled GID. + * @method Phaser.GameObjects.Rope#renderCanvas + * @since 3.23.0 + * @private * - * @return {Phaser.Types.Tilemaps.GIDData} The GID Data. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Rope} src - The Game Object being rendered in this call. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. */ -var ParseGID = function (gid) +var RopeCanvasRenderer = function () { - var flippedHorizontal = Boolean(gid & FLIPPED_HORIZONTAL); - var flippedVertical = Boolean(gid & FLIPPED_VERTICAL); - var flippedAntiDiagonal = Boolean(gid & FLIPPED_ANTI_DIAGONAL); - gid = gid & ~(FLIPPED_HORIZONTAL | FLIPPED_VERTICAL | FLIPPED_ANTI_DIAGONAL); - - // Parse the flip flags into something Phaser can use - var rotation = 0; - var flipped = false; - - if (flippedHorizontal && flippedVertical && flippedAntiDiagonal) - { - rotation = Math.PI / 2; - flipped = true; - } - else if (flippedHorizontal && flippedVertical && !flippedAntiDiagonal) - { - rotation = Math.PI; - flipped = false; - } - else if (flippedHorizontal && !flippedVertical && flippedAntiDiagonal) - { - rotation = Math.PI / 2; - flipped = false; - } - else if (flippedHorizontal && !flippedVertical && !flippedAntiDiagonal) - { - rotation = 0; - flipped = true; - } - else if (!flippedHorizontal && flippedVertical && flippedAntiDiagonal) - { - rotation = 3 * Math.PI / 2; - flipped = false; - } - else if (!flippedHorizontal && flippedVertical && !flippedAntiDiagonal) - { - rotation = Math.PI; - flipped = true; - } - else if (!flippedHorizontal && !flippedVertical && flippedAntiDiagonal) - { - rotation = 3 * Math.PI / 2; - flipped = true; - } - else if (!flippedHorizontal && !flippedVertical && !flippedAntiDiagonal) - { - rotation = 0; - flipped = false; - } - - return { - gid: gid, - flippedHorizontal: flippedHorizontal, - flippedVertical: flippedVertical, - flippedAntiDiagonal: flippedAntiDiagonal, - rotation: rotation, - flipped: flipped - }; }; -module.exports = ParseGID; +module.exports = RopeCanvasRenderer; /***/ }), -/* 262 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 96027: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Formats = __webpack_require__(40); -var MapData = __webpack_require__(121); -var Parse = __webpack_require__(564); -var Tilemap = __webpack_require__(580); +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var GetValue = __webpack_require__(10850); +var Rope = __webpack_require__(79968); /** - * Create a Tilemap from the given key or data. If neither is given, make a blank Tilemap. When - * loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing from - * a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map data. For - * an empty map, you should specify tileWidth, tileHeight, width & height. + * Creates a new Rope Game Object and returns it. * - * @function Phaser.Tilemaps.ParseToTilemap - * @since 3.0.0 + * Note: This method will only be available if the Rope Game Object and WebGL support have been built into Phaser. * - * @param {Phaser.Scene} scene - The Scene to which this Tilemap belongs. - * @param {string} [key] - The key in the Phaser cache that corresponds to the loaded tilemap data. - * @param {number} [tileWidth=32] - The width of a tile in pixels. - * @param {number} [tileHeight=32] - The height of a tile in pixels. - * @param {number} [width=10] - The width of the map in tiles. - * @param {number} [height=10] - The height of the map in tiles. - * @param {number[][]} [data] - Instead of loading from the cache, you can also load directly from - * a 2D array of tile indexes. - * @param {boolean} [insertNull=false] - 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. + * @method Phaser.GameObjects.GameObjectCreator#rope + * @since 3.23.0 * - * @return {Phaser.Tilemaps.Tilemap} + * @param {Phaser.Types.GameObjects.Rope.RopeConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Rope} The Game Object that was created. */ -var ParseToTilemap = function (scene, key, tileWidth, tileHeight, width, height, data, insertNull) +GameObjectCreator.register('rope', function (config, addToScene) { - if (tileWidth === undefined) { tileWidth = 32; } - if (tileHeight === undefined) { tileHeight = 32; } - if (width === undefined) { width = 10; } - if (height === undefined) { height = 10; } - if (insertNull === undefined) { insertNull = false; } - - var mapData = null; + if (config === undefined) { config = {}; } - if (Array.isArray(data)) - { - var name = key !== undefined ? key : 'map'; - mapData = Parse(name, Formats.ARRAY_2D, data, tileWidth, tileHeight, insertNull); - } - else if (key !== undefined) - { - var tilemapData = scene.cache.tilemap.get(key); + var key = GetAdvancedValue(config, 'key', null); + var frame = GetAdvancedValue(config, 'frame', null); + var horizontal = GetAdvancedValue(config, 'horizontal', true); + var points = GetValue(config, 'points', undefined); + var colors = GetValue(config, 'colors', undefined); + var alphas = GetValue(config, 'alphas', undefined); - if (!tilemapData) - { - console.warn('No map data found for key ' + key); - } - else - { - mapData = Parse(key, tilemapData.format, tilemapData.data, tileWidth, tileHeight, insertNull); - } - } + var rope = new Rope(this.scene, 0, 0, key, frame, points, horizontal, colors, alphas); - if (mapData === null) + if (addToScene !== undefined) { - mapData = new MapData({ - tileWidth: tileWidth, - tileHeight: tileHeight, - width: width, - height: height - }); + config.add = addToScene; } - return new Tilemap(scene, mapData); -}; + BuildGameObject(this.scene, rope, config); -module.exports = ParseToTilemap; + return rope; +}); + +// When registering a factory function 'this' refers to the GameObjectCreator context. /***/ }), -/* 263 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 31982: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetValue = __webpack_require__(6); +var Rope = __webpack_require__(79968); +var GameObjectFactory = __webpack_require__(61286); /** - * Extracts an array of targets from a Tween configuration object. + * Creates a new Rope Game Object and adds it to the Scene. * - * The targets will be looked for in a `targets` property. If it's a function, its return value will be used as the result. + * Note: This method will only be available if the Rope Game Object and WebGL support have been built into Phaser. * - * @function Phaser.Tweens.Builders.GetTargets - * @since 3.0.0 + * @method Phaser.GameObjects.GameObjectFactory#rope + * @webglOnly + * @since 3.23.0 * - * @param {object} config - The configuration object to use. + * @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. + * @param {Phaser.Types.Math.Vector2Like[]} [points] - An array containing the vertices data for this Rope. If none is provided a simple quad is created. See `setPoints` to set this post-creation. + * @param {boolean} [horizontal=true] - Should the vertices of this Rope be aligned horizontally (`true`), or vertically (`false`)? + * @param {number[]} [colors] - An optional array containing the color data for this Rope. You should provide one color value per pair of vertices. + * @param {number[]} [alphas] - An optional array containing the alpha data for this Rope. You should provide one alpha value per pair of vertices. * - * @return {array} An array of targets (may contain only one element), or `null` if no targets were specified. + * @return {Phaser.GameObjects.Rope} The Game Object that was created. */ -var GetTargets = function (config) +if (true) { - var targets = GetValue(config, 'targets', null); - - if (targets === null) - { - return targets; - } - - if (typeof targets === 'function') - { - targets = targets.call(); - } - - if (!Array.isArray(targets)) + GameObjectFactory.register('rope', function (x, y, texture, frame, points, horizontal, colors, alphas) { - targets = [ targets ]; - } - - return targets; -}; - -module.exports = GetTargets; + return this.displayList.add(new Rope(this.scene, x, y, texture, frame, points, horizontal, colors, alphas)); + }); +} /***/ }), -/* 264 */ -/***/ (function(module, exports) { + +/***/ 58912: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @ignore - */ -function hasGetActive (def) -{ - return (!!def.getActive && typeof def.getActive === 'function'); -} +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; -/** - * @ignore - */ -function hasGetStart (def) +if (true) { - return (!!def.getStart && typeof def.getStart === 'function'); + renderWebGL = __webpack_require__(49489); } -/** - * @ignore - */ -function hasGetEnd (def) +if (true) { - return (!!def.getEnd && typeof def.getEnd === 'function'); + renderCanvas = __webpack_require__(44598); } +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 49489: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + /** - * @ignore + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -function hasGetters (def) -{ - return hasGetStart(def) || hasGetEnd(def) || hasGetActive(def); -} + +var GetCalcMatrix = __webpack_require__(73329); +var Utils = __webpack_require__(75512); /** - * Returns `getActive`, `getStart` and `getEnd` functions for a TweenData based on a target property and end value. - * - * `getActive` if not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. - * `getEnd` is invoked once any start delays have expired and returns what the value should tween to. - * `getStart` is invoked when the tween reaches the end and needs to either repeat or yoyo, it returns the value to go back to. - * - * If the end value is a number, it will be treated as an absolute value and the property will be tweened to it. - * A string can be provided to specify a relative end value which consists of an operation - * (`+=` to add to the current value, `-=` to subtract from the current value, `*=` to multiply the current - * value, or `/=` to divide the current value) followed by its operand. - * - * A function can be provided to allow greater control over the end value; it will receive the target - * object being tweened, the name of the property being tweened, and the current value of the property - * as its arguments. - * - * If both the starting and the ending values need to be controlled, an object with `getStart` and `getEnd` - * callbacks, which will receive the same arguments, can be provided instead. If an object with a `value` - * property is provided, the property will be used as the effective value under the same rules described here. - * - * @function Phaser.Tweens.Builders.GetValueOp - * @since 3.0.0 + * 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. * - * @param {string} key - The name of the property to modify. - * @param {*} propertyValue - The ending value of the property, as described above. + * @method Phaser.GameObjects.Rope#renderWebGL + * @since 3.23.0 + * @private * - * @return {function} An array of functions, `getActive`, `getStart` and `getEnd`, which return the starting and the ending value of the property based on the provided value. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Rope} 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 GetValueOp = function (key, propertyValue) +var RopeWebGLRenderer = function (renderer, src, camera, parentMatrix) { - var callbacks; + camera.addToRenderList(src); - // The returned value sets what the property will be at the END of the Tween (usually called at the start of the Tween) - var getEnd = function (target, key, value) { return value; }; + var pipeline = renderer.pipelines.set(src.pipeline, src); - // The returned value sets what the property will be at the START of the Tween (usually called at the end of the Tween) - var getStart = function (target, key, value) { return value; }; + var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; - // What to set the property to the moment the TweenData is invoked - var getActive = null; + var vertices = src.vertices; + var uvs = src.uv; + var colors = src.colors; + var alphas = src.alphas; + var alpha = src.alpha; + var getTint = Utils.getTintAppendFloatAlpha; + var roundPixels = camera.roundPixels; - var t = typeof(propertyValue); + var meshVerticesLength = vertices.length; + var vertexCount = Math.floor(meshVerticesLength * 0.5); - if (t === 'number') - { - // props: { - // x: 400, - // y: 300 - // } + // Because it's a triangle strip and we don't want lots of degenerate triangles joining things up + pipeline.flush(); - getEnd = function () - { - return propertyValue; - }; - } - else if (t === 'string') - { - // props: { - // x: '+=400', - // y: '-=300', - // z: '*=2', - // w: '/=2' - // } + renderer.pipelines.preBatch(src); - var op = propertyValue[0]; - var num = parseFloat(propertyValue.substr(2)); + var textureUnit = pipeline.setGameObject(src); - switch (op) - { - case '+': - getEnd = function (target, key, value) - { - return value + num; - }; - break; + var vertexViewF32 = pipeline.vertexViewF32; + var vertexViewU32 = pipeline.vertexViewU32; - case '-': - getEnd = function (target, key, value) - { - return value - num; - }; - break; + var vertexOffset = (pipeline.vertexCount * pipeline.currentShader.vertexComponentCount) - 1; - case '*': - getEnd = function (target, key, value) - { - return value * num; - }; - break; + var colorIndex = 0; - case '/': - getEnd = function (target, key, value) - { - return value / num; - }; - break; + var tintEffect = src.tintFill; - default: - getEnd = function () - { - return parseFloat(propertyValue); - }; - } - } - else if (t === 'function') + if (src.dirty) { - // The same as setting just the getEnd function and no getStart - - // props: { - // x: function (target, key, value, targetIndex, totalTargets, tween) { return value + 50); }, - // } - - getEnd = propertyValue; + src.updateVertices(); } - else if (t === 'object') - { - if (hasGetters(propertyValue)) - { - /* - x: { - // Called the moment Tween is active. The returned value sets the property on the target immediately. - getActive: function (target, key, value, targetIndex, totalTargets, tween) - { - return value; - }, - // Called at the start of the Tween. The returned value sets what the property will be at the END of the Tween. - getEnd: function (target, key, value, targetIndex, totalTargets, tween) - { - return value; - }, - - // Called at the end of the Tween. The returned value sets what the property will be at the START of the Tween. - getStart: function (target, key, value, targetIndex, totalTargets, tween) - { - return value; - } - } - */ + var debugCallback = src.debugCallback; + var debugVerts = []; - if (hasGetActive(propertyValue)) - { - getActive = propertyValue.getActive; - } + for (var i = 0; i < meshVerticesLength; i += 2) + { + var x = vertices[i + 0]; + var y = vertices[i + 1]; - if (hasGetEnd(propertyValue)) - { - getEnd = propertyValue.getEnd; - } + var tx = x * calcMatrix.a + y * calcMatrix.c + calcMatrix.e; + var ty = x * calcMatrix.b + y * calcMatrix.d + calcMatrix.f; - if (hasGetStart(propertyValue)) - { - getStart = propertyValue.getStart; - } - } - else if (propertyValue.hasOwnProperty('value')) + if (roundPixels) { - // 'value' may still be a string, function or a number - // props: { - // x: { value: 400, ... }, - // y: { value: 300, ... } - // } - - callbacks = GetValueOp(key, propertyValue.value); + tx = Math.round(tx); + ty = Math.round(ty); } - else - { - // 'from' and 'to' may still be a string, function or a number - // props: { - // x: { from: 400, to: 600 }, - // y: { from: 300, to: 500 } - // } - - // Same as above, but the 'start' value is set immediately on the target - // props: { - // x: { start: 400, to: 600 }, - // y: { start: 300, to: 500 } - // } - // 'start' value is set immediately, then it goes 'from' to 'to' during the tween - // props: { - // x: { start: 200, from: 400, to: 600 }, - // y: { start: 300, from: 300, to: 500 } - // } - - var hasTo = propertyValue.hasOwnProperty('to'); - var hasFrom = propertyValue.hasOwnProperty('from'); - var hasStart = propertyValue.hasOwnProperty('start'); + vertexViewF32[++vertexOffset] = tx; + vertexViewF32[++vertexOffset] = ty; + vertexViewF32[++vertexOffset] = uvs[i + 0]; + vertexViewF32[++vertexOffset] = uvs[i + 1]; + vertexViewF32[++vertexOffset] = textureUnit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = getTint(colors[colorIndex], camera.alpha * (alphas[colorIndex] * alpha)); - if (hasTo && (hasFrom || hasStart)) - { - callbacks = GetValueOp(key, propertyValue.to); + colorIndex++; - if (hasStart) - { - var startCallbacks = GetValueOp(key, propertyValue.start); - - callbacks.getActive = startCallbacks.getEnd; - } - - if (hasFrom) - { - var fromCallbacks = GetValueOp(key, propertyValue.from); - - callbacks.getStart = fromCallbacks.getEnd; - } - } + if (debugCallback) + { + debugVerts[i + 0] = tx; + debugVerts[i + 1] = ty; } } - // If callback not set by the else if block above then set it here and return it - if (!callbacks) + if (debugCallback) { - callbacks = { - getActive: getActive, - getEnd: getEnd, - getStart: getStart - }; + debugCallback.call(src, src, meshVerticesLength, debugVerts); } - return callbacks; -}; - -module.exports = GetValueOp; - - -/***/ }), -/* 265 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + pipeline.vertexCount += vertexCount; -/** - * @typedef {object} Phaser.Types.Tweens.TweenConfigDefaults - * @since 3.0.0 - * - * @property {(object|object[])} targets - The object, or an array of objects, to run the tween on. - * @property {number} [delay=0] - The number of milliseconds to delay before the tween will start. - * @property {number} [duration=1000] - The duration of the tween in milliseconds. - * @property {string} [ease='Power0'] - The easing equation to use for the tween. - * @property {array} [easeParams] - Optional easing parameters. - * @property {number} [hold=0] - The number of milliseconds to hold the tween for before yoyo'ing. - * @property {number} [repeat=0] - The number of times to repeat the tween. - * @property {number} [repeatDelay=0] - The number of milliseconds to pause before a tween will repeat. - * @property {boolean} [yoyo=false] - Should the tween complete, then reverse the values incrementally to get back to the starting tween values? The reverse tweening will also take `duration` milliseconds to complete. - * @property {boolean} [flipX=false] - Horizontally flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipX` property. - * @property {boolean} [flipY=false] - Vertically flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipY` property. - */ + pipeline.currentBatch.count = (pipeline.vertexCount - pipeline.currentBatch.start); -var TWEEN_DEFAULTS = { - targets: null, - delay: 0, - duration: 1000, - ease: 'Power0', - easeParams: null, - hold: 0, - repeat: 0, - repeatDelay: 0, - yoyo: false, - flipX: false, - flipY: false + renderer.pipelines.postBatch(src); }; -module.exports = TWEEN_DEFAULTS; +module.exports = RopeWebGLRenderer; /***/ }), -/* 266 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 27902: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(267); -var GameObjectCreator = __webpack_require__(16); -var GameObjectFactory = __webpack_require__(5); -var TWEEN_CONST = __webpack_require__(100); -var MATH_CONST = __webpack_require__(14); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var GetFastValue = __webpack_require__(72632); +var Extend = __webpack_require__(98611); +var SetValue = __webpack_require__(22440); +var ShaderRender = __webpack_require__(24252); +var TransformMatrix = __webpack_require__(69360); /** * @classdesc - * A Tween is able to manipulate the properties of one or more objects to any given value, based - * on a duration and type of ease. They are rarely instantiated directly and instead should be - * created via the TweenManager. + * A Shader Game Object. * - * @class Tween - * @memberof Phaser.Tweens - * @extends Phaser.Events.EventEmitter + * This Game Object allows you to easily add a quad with its own shader into the display list, and manipulate it + * as you would any other Game Object, including scaling, rotating, positioning and adding to Containers. Shaders + * can be masked with either Bitmap or Geometry masks and can also be used as a Bitmap Mask for a Camera or other + * Game Object. They can also be made interactive and used for input events. + * + * It works by taking a reference to a `Phaser.Display.BaseShader` instance, as found in the Shader Cache. These can + * be created dynamically at runtime, or loaded in via the GLSL File Loader: + * + * ```javascript + * function preload () + * { + * this.load.glsl('fire', 'shaders/fire.glsl.js'); + * } + * + * function create () + * { + * this.add.shader('fire', 400, 300, 512, 512); + * } + * ``` + * + * Please see the Phaser 3 Examples GitHub repo for examples of loading and creating shaders dynamically. + * + * Due to the way in which they work, you cannot directly change the alpha or blend mode of a Shader. This should + * be handled via exposed uniforms in the shader code itself. + * + * By default a Shader will be created with a standard set of uniforms. These were added to match those + * found on sites such as ShaderToy or GLSLSandbox, and provide common functionality a shader may need, + * such as the timestamp, resolution or pointer position. You can replace them by specifying your own uniforms + * in the Base Shader. + * + * These Shaders work by halting the current pipeline during rendering, creating a viewport matched to the + * size of this Game Object and then renders a quad using the bound shader. At the end, the pipeline is restored. + * + * Because it blocks the pipeline it means it will interrupt any batching that is currently going on, so you should + * use these Game Objects sparingly. If you need to have a fully batched custom shader, then please look at using + * a custom pipeline instead. However, for background or special masking effects, they are extremely effective. + * + * @class Shader + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects * @constructor - * @since 3.0.0 + * @webglOnly + * @since 3.17.0 + * + * @extends Phaser.GameObjects.Components.ComputedSize + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.Visible * - * @param {(Phaser.Tweens.TweenManager|Phaser.Tweens.Timeline)} parent - A reference to the parent of this Tween. Either the Tween Manager or a Tween Timeline instance. - * @param {Phaser.Types.Tweens.TweenDataConfig[]} data - An array of TweenData objects, each containing a unique property to be tweened. - * @param {array} targets - An array of targets to be tweened. + * @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 {(string|Phaser.Display.BaseShader)} key - The key of the shader to use from the shader cache, or a BaseShader instance. + * @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 Game Object. + * @param {number} [height=128] - The height of the Game Object. + * @param {string[]} [textures] - Optional array of texture keys to bind to the iChannel0...3 uniforms. The textures must already exist in the Texture Manager. + * @param {any} [textureData] - Additional texture data if you want to create shader with none NPOT textures. */ -var Tween = new Class({ +var Shader = new Class({ - Extends: EventEmitter, + Extends: GameObject, + + Mixins: [ + Components.ComputedSize, + Components.Depth, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.ScrollFactor, + Components.Transform, + Components.Visible, + ShaderRender + ], initialize: - function Tween (parent, data, targets) + function Shader (scene, key, x, y, width, height, textures, textureData) { - EventEmitter.call(this); + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 128; } + if (height === undefined) { height = 128; } + + GameObject.call(this, scene, 'Shader'); /** - * A reference to the parent of this Tween. - * Either the Tween Manager or a Tween Timeline instance. + * This Game Object cannot have a blend mode, so skip all checks. * - * @name Phaser.Tweens.Tween#parent - * @type {(Phaser.Tweens.TweenManager|Phaser.Tweens.Timeline)} - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#blendMode + * @type {number} + * @private + * @since 3.17.0 */ - this.parent = parent; + this.blendMode = -1; /** - * Is the parent of this Tween a Timeline? + * The underlying shader object being used. + * Empty by default and set during a call to the `setShader` method. * - * @name Phaser.Tweens.Tween#parentIsTimeline - * @type {boolean} - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#shader + * @type {Phaser.Display.BaseShader} + * @since 3.17.0 */ - this.parentIsTimeline = parent.hasOwnProperty('isTimeline'); + this.shader; + + var renderer = scene.sys.renderer; /** - * An array of TweenData objects, each containing a unique property and target being tweened. + * A reference to the current renderer. + * Shaders only work with the WebGL Renderer. * - * @name Phaser.Tweens.Tween#data - * @type {Phaser.Types.Tweens.TweenDataConfig[]} - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.17.0 */ - this.data = data; + this.renderer = renderer; /** - * The cached length of the data array. + * The WebGL context belonging to the renderer. * - * @name Phaser.Tweens.Tween#totalData - * @type {number} - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#gl + * @type {WebGLRenderingContext} + * @since 3.17.0 */ - this.totalData = data.length; + this.gl = renderer.gl; /** - * An array of references to the target/s this Tween is operating on. + * Raw byte buffer of vertices this Shader uses. * - * @name Phaser.Tweens.Tween#targets - * @type {object[]} - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#vertexData + * @type {ArrayBuffer} + * @since 3.17.0 */ - this.targets = targets; + this.vertexData = new ArrayBuffer(6 * (Float32Array.BYTES_PER_ELEMENT * 2)); /** - * Cached target total (not necessarily the same as the data total) + * The WebGL vertex buffer object this shader uses. * - * @name Phaser.Tweens.Tween#totalTargets - * @type {number} - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#vertexBuffer + * @type {WebGLBuffer} + * @since 3.17.0 */ - this.totalTargets = targets.length; + this.vertexBuffer = renderer.createVertexBuffer(this.vertexData.byteLength, this.gl.STREAM_DRAW); /** - * If `true` then duration, delay, etc values are all frame totals. + * The WebGL shader program this shader uses. * - * @name Phaser.Tweens.Tween#useFrames - * @type {boolean} - * @default false - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#program + * @type {WebGLProgram} + * @since 3.17.0 */ - this.useFrames = false; + this.program = null; /** - * Scales the time applied to this Tween. 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 tween, it's a run-time delta adjustment only. + * Uint8 view to the vertex raw buffer. Used for uploading vertex buffer resources to the GPU. * - * @name Phaser.Tweens.Tween#timeScale - * @type {number} - * @default 1 - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#bytes + * @type {Uint8Array} + * @since 3.17.0 */ - this.timeScale = 1; + this.bytes = new Uint8Array(this.vertexData); /** - * Loop this tween? Can be -1 for an infinite loop, or an integer. - * When enabled it will play through ALL TweenDatas again. Use TweenData.repeat to loop a single element. + * Float32 view of the array buffer containing the shaders vertices. * - * @name Phaser.Tweens.Tween#loop - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#vertexViewF32 + * @type {Float32Array} + * @since 3.17.0 */ - this.loop = 0; + this.vertexViewF32 = new Float32Array(this.vertexData); /** - * Time in ms/frames before the tween loops. + * A temporary Transform Matrix, re-used internally during batching. * - * @name Phaser.Tweens.Tween#loopDelay - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#_tempMatrix1 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.17.0 */ - this.loopDelay = 0; + this._tempMatrix1 = new TransformMatrix(); /** - * How many loops are left to run? + * A temporary Transform Matrix, re-used internally during batching. * - * @name Phaser.Tweens.Tween#loopCounter - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#_tempMatrix2 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.17.0 */ - this.loopCounter = 0; + this._tempMatrix2 = new TransformMatrix(); /** - * Time in ms/frames before the 'onStart' event fires. - * This is the shortest `delay` value across all of the TweenDatas of this Tween. + * A temporary Transform Matrix, re-used internally during batching. * - * @name Phaser.Tweens.Tween#startDelay - * @type {number} - * @default 0 - * @since 3.19.0 + * @name Phaser.GameObjects.Shader#_tempMatrix3 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.17.0 */ - this.startDelay = 0; + this._tempMatrix3 = new TransformMatrix(); /** - * Has this Tween started playback yet? - * This boolean is toggled when the Tween leaves the 'delayed' state and starts running. + * The view matrix the shader uses during rendering. * - * @name Phaser.Tweens.Tween#hasStarted - * @type {boolean} + * @name Phaser.GameObjects.Shader#viewMatrix + * @type {Float32Array} * @readonly - * @since 3.19.0 + * @since 3.17.0 */ - this.hasStarted = false; + this.viewMatrix = new Float32Array([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); /** - * Is this Tween currently seeking? - * This boolean is toggled in the `Tween.seek` method. - * When a tween is seeking it will not dispatch any events or callbacks. + * The projection matrix the shader uses during rendering. * - * @name Phaser.Tweens.Tween#isSeeking - * @type {boolean} + * @name Phaser.GameObjects.Shader#projectionMatrix + * @type {Float32Array} * @readonly - * @since 3.19.0 + * @since 3.17.0 */ - this.isSeeking = false; + this.projectionMatrix = new Float32Array([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); /** - * Time in ms/frames before the 'onComplete' event fires. This never fires if loop = -1 (as it never completes) + * The default uniform mappings. These can be added to (or replaced) by specifying your own uniforms when + * creating this shader game object. The uniforms are updated automatically during the render step. * - * @name Phaser.Tweens.Tween#completeDelay - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.completeDelay = 0; - - /** - * Countdown timer (used by timeline offset, loopDelay and completeDelay) + * The defaults are: * - * @name Phaser.Tweens.Tween#countdown - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.countdown = 0; - - /** - * Set only if this Tween is part of a Timeline. + * `resolution` (2f) - Set to the size of this shader. + * `time` (1f) - The elapsed game time, in seconds. + * `mouse` (2f) - If a pointer has been bound (with `setPointer`), this uniform contains its position each frame. + * `date` (4fv) - A vec4 containing the year, month, day and time in seconds. + * `sampleRate` (1f) - Sound sample rate. 44100 by default. + * `iChannel0...3` (sampler2D) - Input channels 0 to 3. `null` by default. * - * @name Phaser.Tweens.Tween#offset - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#uniforms + * @type {any} + * @since 3.17.0 */ - this.offset = 0; + this.uniforms = {}; /** - * Set only if this Tween is part of a Timeline. The calculated offset amount. + * The pointer bound to this shader, if any. + * Set via the chainable `setPointer` method, or by modifying this property directly. * - * @name Phaser.Tweens.Tween#calculatedOffset - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#pointer + * @type {Phaser.Input.Pointer} + * @since 3.17.0 */ - this.calculatedOffset = 0; + this.pointer = null; /** - * The current state of the tween + * The cached width of the renderer. * - * @name Phaser.Tweens.Tween#state + * @name Phaser.GameObjects.Shader#_rendererWidth * @type {number} - * @since 3.0.0 + * @private + * @since 3.17.0 */ - this.state = TWEEN_CONST.PENDING_ADD; + this._rendererWidth = renderer.width; /** - * The state of the tween when it was paused (used by Resume) + * The cached height of the renderer. * - * @name Phaser.Tweens.Tween#_pausedState + * @name Phaser.GameObjects.Shader#_rendererHeight * @type {number} * @private - * @since 3.0.0 - */ - this._pausedState = TWEEN_CONST.INIT; - - /** - * Does the Tween start off paused? (if so it needs to be started with Tween.play) - * - * @name Phaser.Tweens.Tween#paused - * @type {boolean} - * @default false - * @since 3.0.0 + * @since 3.17.0 */ - this.paused = false; + this._rendererHeight = renderer.height; /** - * Elapsed time in ms/frames of this run through the Tween. + * Internal texture count tracker. * - * @name Phaser.Tweens.Tween#elapsed + * @name Phaser.GameObjects.Shader#_textureCount * @type {number} - * @default 0 - * @since 3.0.0 + * @private + * @since 3.17.0 */ - this.elapsed = 0; + this._textureCount = 0; /** - * Total elapsed time in ms/frames of the entire Tween, including looping. + * A reference to the GL Frame Buffer this Shader is drawing to. + * This property is only set if you have called `Shader.setRenderToTexture`. * - * @name Phaser.Tweens.Tween#totalElapsed - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#framebuffer + * @type {?WebGLFramebuffer} + * @since 3.19.0 */ - this.totalElapsed = 0; + this.framebuffer = null; /** - * Time in ms/frames for the whole Tween to play through once, excluding loop amounts and loop delays. + * A reference to the WebGLTexture this Shader is rendering to. + * This property is only set if you have called `Shader.setRenderToTexture`. * - * @name Phaser.Tweens.Tween#duration - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#glTexture + * @type {?WebGLTexture} + * @since 3.19.0 */ - this.duration = 0; + this.glTexture = null; /** - * Value between 0 and 1. The amount through the Tween, excluding loops. + * A flag that indicates if this Shader has been set to render to a texture instead of the display list. * - * @name Phaser.Tweens.Tween#progress - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.progress = 0; - - /** - * Time in ms/frames for the Tween to complete (including looping) + * This property is `true` if you have called `Shader.setRenderToTexture`, otherwise it's `false`. * - * @name Phaser.Tweens.Tween#totalDuration - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalDuration = 0; - - /** - * Value between 0 and 1. The amount through the entire Tween, including looping. + * A Shader that is rendering to a texture _does not_ appear on the display list. * - * @name Phaser.Tweens.Tween#totalProgress - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#renderToTexture + * @type {boolean} + * @readonly + * @since 3.19.0 */ - this.totalProgress = 0; + this.renderToTexture = false; /** - * An object containing the different Tween callback functions. - * - * You can either set these in the Tween config, or by calling the `Tween.setCallback` method. + * A reference to the Phaser.Textures.Texture that has been stored in the Texture Manager for this Shader. * - * `onActive` When the Tween is moved from the pending to the active list in the Tween Manager, even if playback paused. - * `onStart` When the Tween starts playing after a delayed state. Will happen at the same time as `onActive` if it has no delay. - * `onYoyo` When a TweenData starts a yoyo. This happens _after_ the `hold` delay expires, if set. - * `onRepeat` When a TweenData repeats playback. This happens _after_ the `repeatDelay` expires, if set. - * `onComplete` When the Tween finishes playback fully. Never invoked if tween is set to repeat infinitely. - * `onUpdate` When a TweenData updates a property on a source target during playback. - * `onLoop` When a Tween loops. This happens _after_ the `loopDelay` expires, if set. + * This property is only set if you have called `Shader.setRenderToTexture`, otherwise it is `null`. * - * @name Phaser.Tweens.Tween#callbacks - * @type {object} - * @since 3.0.0 + * @name Phaser.GameObjects.Shader#texture + * @type {Phaser.Textures.Texture} + * @since 3.19.0 */ - this.callbacks = { - onActive: null, - onComplete: null, - onLoop: null, - onRepeat: null, - onStart: null, - onStop: null, - onUpdate: null, - onYoyo: null - }; + this.texture = null; - /** - * The context in which all callbacks are invoked. - * - * @name Phaser.Tweens.Tween#callbackScope - * @type {any} - * @since 3.0.0 - */ - this.callbackScope; + this.setPosition(x, y); + this.setSize(width, height); + this.setOrigin(0.5, 0.5); + this.setShader(key, textures, textureData); }, /** - * Returns the current value of the specified Tween Data. + * 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.Tweens.Tween#getValue - * @since 3.0.0 - * - * @param {number} [index=0] - The Tween Data to return the value from. - * - * @return {number} The value of the requested Tween Data. - */ - getValue: function (index) - { - if (index === undefined) { index = 0; } - - return this.data[index].current; - }, - - /** - * Set the scale the time applied to this Tween. A value of 1 runs in real-time. A value of 0.5 runs 50% slower, and so on. - * - * @method Phaser.Tweens.Tween#setTimeScale + * @method Phaser.GameObjects.Shader#willRender * @since 3.0.0 * - * @param {number} value - The scale factor for timescale. - * - * @return {this} - This Tween instance. - */ - setTimeScale: function (value) - { - this.timeScale = value; - - return this; - }, - - /** - * Returns the scale of the time applied to this Tween. - * - * @method Phaser.Tweens.Tween#getTimeScale - * @since 3.0.0 + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object. * - * @return {number} The timescale of this tween (between 0 and 1) + * @return {boolean} True if the Game Object should be rendered, otherwise false. */ - getTimeScale: function () + willRender: function (camera) { - return this.timeScale; + if (this.renderToTexture) + { + return true; + } + else + { + return !(GameObject.RENDER_MASK !== this.renderFlags || (this.cameraFilter !== 0 && (this.cameraFilter & camera.id))); + } }, /** - * Checks if the Tween is currently active. - * - * @method Phaser.Tweens.Tween#isPlaying - * @since 3.0.0 + * Changes this Shader so instead of rendering to the display list it renders to a + * WebGL Framebuffer and WebGL Texture instead. This allows you to use the output + * of this shader as an input for another shader, by mapping a sampler2D uniform + * to it. * - * @return {boolean} `true` if the Tween is active, otherwise `false`. - */ - isPlaying: function () - { - return (this.state === TWEEN_CONST.ACTIVE); - }, - - /** - * Checks if the Tween is currently paused. + * After calling this method the `Shader.framebuffer` and `Shader.glTexture` properties + * are populated. * - * @method Phaser.Tweens.Tween#isPaused - * @since 3.0.0 + * Additionally, you can provide a key to this method. Doing so will create a Phaser Texture + * from this Shader and save it into the Texture Manager, allowing you to then use it for + * any texture-based Game Object, such as a Sprite or Image: * - * @return {boolean} `true` if the Tween is paused, otherwise `false`. - */ - isPaused: function () - { - return (this.state === TWEEN_CONST.PAUSED); - }, - - /** - * See if this Tween is currently acting upon the given target. + * ```javascript + * var shader = this.add.shader('myShader', x, y, width, height); * - * @method Phaser.Tweens.Tween#hasTarget - * @since 3.0.0 + * shader.setRenderToTexture('doodle'); * - * @param {object} target - The target to check against this Tween. + * this.add.image(400, 300, 'doodle'); + * ``` * - * @return {boolean} `true` if the given target is a target of this Tween, otherwise `false`. - */ - hasTarget: function (target) - { - return (this.targets.indexOf(target) !== -1); - }, - - /** - * Updates the 'end' value of the given property across all matching targets. + * Note that it stores an active reference to this Shader. That means as this shader updates, + * so does the texture and any object using it to render with. Also, if you destroy this + * shader, be sure to clear any objects that may have been using it as a texture too. * - * Calling this does not adjust the duration of the tween, or the current progress. + * You can access the Phaser Texture that is created via the `Shader.texture` property. * - * You can optionally tell it to set the 'start' value to be the current value (before the change). + * By default it will create a single base texture. You can add frames to the texture + * by using the `Texture.add` method. After doing this, you can then allow Game Objects + * to use a specific frame from a Render Texture. * - * @method Phaser.Tweens.Tween#updateTo - * @since 3.0.0 + * @method Phaser.GameObjects.Shader#setRenderToTexture + * @since 3.19.0 * - * @param {string} key - The property to set the new value for. - * @param {*} value - The new value of the property. - * @param {boolean} [startToCurrent=false] - Should this change set the start value to be the current value? + * @param {string} [key] - The unique key to store the texture as within the global Texture Manager. + * @param {boolean} [flipY=false] - Does this texture need vertically flipping before rendering? This should usually be set to `true` if being fed from a buffer. * - * @return {this} - This Tween instance. + * @return {this} This Shader instance. */ - updateTo: function (key, value, startToCurrent) + setRenderToTexture: function (key, flipY) { - if (startToCurrent === undefined) { startToCurrent = false; } + if (flipY === undefined) { flipY = false; } - for (var i = 0; i < this.totalData; i++) + if (!this.renderToTexture) { - var tweenData = this.data[i]; + var width = this.width; + var height = this.height; + var renderer = this.renderer; - if (tweenData.key === key) - { - tweenData.end = value; + this.glTexture = renderer.createTextureFromSource(null, width, height, 0); - if (startToCurrent) - { - tweenData.start = tweenData.current; - } + this.glTexture.flipY = flipY; + + this.framebuffer = renderer.createFramebuffer(width, height, this.glTexture, false); + + this._rendererWidth = width; + this._rendererHeight = height; + + this.renderToTexture = true; + + this.projOrtho(0, this.width, this.height, 0); + + if (key) + { + this.texture = this.scene.sys.textures.addGLTexture(key, this.glTexture, width, height); } } + // And now render at least once, so our texture isn't blank on the first update + + if (this.shader) + { + renderer.pipelines.clear(); + + this.load(); + this.flush(); + + renderer.pipelines.rebind(); + } + return this; }, /** - * Restarts the tween from the beginning. + * Sets the fragment and, optionally, the vertex shader source code that this Shader will use. + * This will immediately delete the active shader program, if set, and then create a new one + * with the given source. Finally, the shader uniforms are initialized. * - * @method Phaser.Tweens.Tween#restart - * @since 3.0.0 + * @method Phaser.GameObjects.Shader#setShader + * @since 3.17.0 * - * @return {this} This Tween instance. + * @param {(string|Phaser.Display.BaseShader)} key - The key of the shader to use from the shader cache, or a BaseShader instance. + * @param {string[]} [textures] - Optional array of texture keys to bind to the iChannel0...3 uniforms. The textures must already exist in the Texture Manager. + * @param {any} [textureData] - Additional texture data. + * + * @return {this} This Shader instance. */ - restart: function () + setShader: function (key, textures, textureData) { - // Reset these so they're ready for the next update - this.elapsed = 0; - this.progress = 0; - this.totalElapsed = 0; - this.totalProgress = 0; + if (textures === undefined) { textures = []; } - if (this.state === TWEEN_CONST.ACTIVE) - { - return this.seek(0); - } - else if (this.state === TWEEN_CONST.REMOVED) + if (typeof key === 'string') { - this.seek(0); - this.parent.makeActive(this); + var cache = this.scene.sys.cache.shader; - return this; - } - else if (this.state === TWEEN_CONST.PENDING_ADD) - { - return this; + if (!cache.has(key)) + { + console.warn('Shader missing: ' + key); + return this; + } + + this.shader = cache.get(key); } else { - return this.play(); + this.shader = key; } - }, - - /** - * Internal method that calculates the overall duration of the Tween. - * - * @method Phaser.Tweens.Tween#calcDuration - * @since 3.0.0 - */ - calcDuration: function () - { - var maxDuration = 0; - var minDelay = MATH_CONST.MAX_SAFE_INTEGER; - var data = this.data; + var gl = this.gl; + var renderer = this.renderer; - for (var i = 0; i < this.totalData; i++) + if (this.program) { - var tweenData = data[i]; + gl.deleteProgram(this.program); + } - // Set t1 (duration + hold + yoyo) - tweenData.t1 = tweenData.duration + tweenData.hold; + var program = renderer.createProgram(this.shader.vertexSrc, this.shader.fragmentSrc); - if (tweenData.yoyo) - { - tweenData.t1 += tweenData.duration; - } + // The default uniforms available within the vertex shader + gl.uniformMatrix4fv(gl.getUniformLocation(program, 'uViewMatrix'), false, this.viewMatrix); + gl.uniformMatrix4fv(gl.getUniformLocation(program, 'uProjectionMatrix'), false, this.projectionMatrix); + gl.uniform2f(gl.getUniformLocation(program, 'uResolution'), this.width, this.height); - // Set t2 (repeatDelay + duration + hold + yoyo) - tweenData.t2 = tweenData.t1 + tweenData.repeatDelay; + this.program = program; - // Total Duration - tweenData.totalDuration = tweenData.delay + tweenData.t1; + var d = new Date(); - if (tweenData.repeat === -1) - { - tweenData.totalDuration += (tweenData.t2 * 999999999999); - } - else if (tweenData.repeat > 0) - { - tweenData.totalDuration += (tweenData.t2 * tweenData.repeat); - } + // The default uniforms available within the fragment shader + var defaultUniforms = { + resolution: { type: '2f', value: { x: this.width, y: this.height } }, + time: { type: '1f', value: 0 }, + mouse: { type: '2f', value: { x: this.width / 2, y: this.height / 2 } }, + date: { type: '4fv', value: [ d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds() ] }, + sampleRate: { type: '1f', value: 44100.0 }, + iChannel0: { type: 'sampler2D', value: null, textureData: { repeat: true } }, + iChannel1: { type: 'sampler2D', value: null, textureData: { repeat: true } }, + iChannel2: { type: 'sampler2D', value: null, textureData: { repeat: true } }, + iChannel3: { type: 'sampler2D', value: null, textureData: { repeat: true } } + }; - if (tweenData.totalDuration > maxDuration) - { - // Get the longest TweenData from the Tween, used to calculate the Tween TD - maxDuration = tweenData.totalDuration; - } + if (this.shader.uniforms) + { + this.uniforms = Extend(true, {}, this.shader.uniforms, defaultUniforms); + } + else + { + this.uniforms = defaultUniforms; + } - if (tweenData.delay < minDelay) + for (var i = 0; i < 4; i++) + { + if (textures[i]) { - minDelay = tweenData.delay; + this.setSampler2D('iChannel' + i, textures[i], i, textureData); } } - // Excludes loop values + this.initUniforms(); - // If duration has been set to 0 then we give it a super-low value so that it always - // renders at least 1 frame, but no more, without causing divided by zero errors elsewhere. - this.duration = Math.max(maxDuration, 0.001); + this.projOrtho(0, this._rendererWidth, this._rendererHeight, 0); - this.loopCounter = (this.loop === -1) ? 999999999999 : this.loop; + return this; + }, - if (this.loopCounter > 0) - { - this.totalDuration = this.duration + this.completeDelay + ((this.duration + this.loopDelay) * this.loopCounter); - } - else - { - this.totalDuration = this.duration + this.completeDelay; - } + /** + * Binds a Phaser Pointer object to this Shader. + * + * The screen position of the pointer will be set in to the shaders `mouse` uniform + * automatically every frame. Call this method with no arguments to unbind the pointer. + * + * @method Phaser.GameObjects.Shader#setPointer + * @since 3.17.0 + * + * @param {Phaser.Input.Pointer} [pointer] - The Pointer to bind to this shader. + * + * @return {this} This Shader instance. + */ + setPointer: function (pointer) + { + this.pointer = pointer; - // How long before this Tween starts playback? - this.startDelay = minDelay; + return this; }, /** - * Called by TweenManager.preUpdate as part of its loop to check pending and active tweens. - * Should not be called directly. + * Sets this shader to use an orthographic projection matrix. + * This matrix is stored locally in the `projectionMatrix` property, + * as well as being bound to the `uProjectionMatrix` uniform. * - * @method Phaser.Tweens.Tween#init - * @since 3.0.0 + * @method Phaser.GameObjects.Shader#projOrtho + * @since 3.17.0 * - * @return {boolean} Returns `true` if this Tween should be moved from the pending list to the active list by the Tween Manager. + * @param {number} left - The left value. + * @param {number} right - The right value. + * @param {number} bottom - The bottom value. + * @param {number} top - The top value. */ - init: function () + projOrtho: function (left, right, bottom, top) { - // You can't have a paused Tween if it's part of a Timeline - if (this.paused && !this.parentIsTimeline) - { - this.state = TWEEN_CONST.PENDING_ADD; - this._pausedState = TWEEN_CONST.INIT; - - return false; - } + var near = -1000; + var far = 1000; - var data = this.data; - var totalTargets = this.totalTargets; + var leftRight = 1 / (left - right); + var bottomTop = 1 / (bottom - top); + var nearFar = 1 / (near - far); - for (var i = 0; i < this.totalData; i++) - { - var tweenData = data[i]; - var target = tweenData.target; - var gen = tweenData.gen; - var key = tweenData.key; - var targetIndex = tweenData.index; + var pm = this.projectionMatrix; - // Old function signature: i, totalTargets, target - // New function signature: target, key, value, index, total, tween + pm[0] = -2 * leftRight; + pm[5] = -2 * bottomTop; + pm[10] = 2 * nearFar; + pm[12] = (left + right) * leftRight; + pm[13] = (top + bottom) * bottomTop; + pm[14] = (far + near) * nearFar; - tweenData.delay = gen.delay(target, key, 0, targetIndex, totalTargets, this); - tweenData.duration = Math.max(gen.duration(target, key, 0, targetIndex, totalTargets, this), 0.001); - tweenData.hold = gen.hold(target, key, 0, targetIndex, totalTargets, this); - tweenData.repeat = gen.repeat(target, key, 0, targetIndex, totalTargets, this); - tweenData.repeatDelay = gen.repeatDelay(target, key, 0, targetIndex, totalTargets, this); - } + var program = this.program; - this.calcDuration(); + var gl = this.gl; + var renderer = this.renderer; - this.progress = 0; - this.totalProgress = 0; - this.elapsed = 0; - this.totalElapsed = 0; + renderer.setProgram(program); - this.state = TWEEN_CONST.INIT; + gl.uniformMatrix4fv(gl.getUniformLocation(program, 'uProjectionMatrix'), false, this.projectionMatrix); - return true; + this._rendererWidth = right; + this._rendererHeight = bottom; }, + // Uniforms are specified in the GLSL_ES Specification: http://www.khronos.org/registry/webgl/specs/latest/1.0/ + // http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf + /** - * Internal method that makes this Tween active within the TweenManager - * and emits the onActive event and callback. + * Initializes all of the uniforms this shader uses. * - * @method Phaser.Tweens.Tween#makeActive - * @fires Phaser.Tweens.Events#TWEEN_ACTIVE - * @since 3.19.0 + * @method Phaser.GameObjects.Shader#initUniforms + * @private + * @since 3.17.0 */ - makeActive: function () + initUniforms: function () { - this.parent.makeActive(this); + var gl = this.gl; + var map = this.renderer.glFuncMap; + var program = this.program; - this.dispatchTweenEvent(Events.TWEEN_ACTIVE, this.callbacks.onActive); - }, + this._textureCount = 0; - /** - * Internal method that advances to the next state of the Tween during playback. - * - * @method Phaser.Tweens.Tween#nextState - * @fires Phaser.Tweens.Events#TWEEN_COMPLETE - * @fires Phaser.Tweens.Events#TWEEN_LOOP - * @since 3.0.0 - */ - nextState: function () - { - if (this.loopCounter > 0) + for (var key in this.uniforms) { - this.elapsed = 0; - this.progress = 0; - this.loopCounter--; + var uniform = this.uniforms[key]; - this.resetTweenData(true); + var type = uniform.type; + var data = map[type]; - if (this.loopDelay > 0) - { - this.countdown = this.loopDelay; - this.state = TWEEN_CONST.LOOP_DELAY; - } - else - { - this.state = TWEEN_CONST.ACTIVE; + uniform.uniformLocation = gl.getUniformLocation(program, key); - this.dispatchTweenEvent(Events.TWEEN_LOOP, this.callbacks.onLoop); + if (type !== 'sampler2D') + { + uniform.glMatrix = data.matrix; + uniform.glValueLength = data.length; + uniform.glFunc = data.func; } } - else if (this.completeDelay > 0) - { - this.state = TWEEN_CONST.COMPLETE_DELAY; - - this.countdown = this.completeDelay; - } - else - { - this.state = TWEEN_CONST.PENDING_REMOVE; - - this.dispatchTweenEvent(Events.TWEEN_COMPLETE, this.callbacks.onComplete); - } }, /** - * Pauses the Tween immediately. Use `resume` to continue playback. + * Sets a sampler2D uniform on this shader where the source texture is a WebGLTexture. * - * @method Phaser.Tweens.Tween#pause - * @since 3.0.0 + * This allows you to feed the output from one Shader into another: * - * @return {this} - This Tween instance. - */ - pause: function () - { - if (this.state === TWEEN_CONST.PAUSED) - { - return this; - } - - this.paused = true; - - this._pausedState = this.state; - - this.state = TWEEN_CONST.PAUSED; - - return this; - }, - - /** - * Starts a Tween playing. + * ```javascript + * let shader1 = this.add.shader(baseShader1, 0, 0, 512, 512).setRenderToTexture(); + * let shader2 = this.add.shader(baseShader2, 0, 0, 512, 512).setRenderToTexture('output'); * - * You only need to call this method if you have configured the tween to be paused on creation. + * shader1.setSampler2DBuffer('iChannel0', shader2.glTexture, 512, 512); + * shader2.setSampler2DBuffer('iChannel0', shader1.glTexture, 512, 512); + * ``` * - * If the Tween is already playing, calling this method again will have no effect. If you wish to - * restart the Tween, use `Tween.restart` instead. + * In the above code, the result of baseShader1 is fed into Shader2 as the `iChannel0` sampler2D uniform. + * The result of baseShader2 is then fed back into shader1 again, creating a feedback loop. * - * Calling this method after the Tween has completed will start the Tween playing again from the start. - * This is the same as calling `Tween.seek(0)` and then `Tween.play()`. + * If you wish to use an image from the Texture Manager as a sampler2D input for this shader, + * see the `Shader.setSampler2D` method. * - * @method Phaser.Tweens.Tween#play - * @since 3.0.0 + * @method Phaser.GameObjects.Shader#setSampler2DBuffer + * @since 3.19.0 * - * @param {boolean} [resetFromTimeline=false] - Is this Tween being played as part of a Timeline? + * @param {string} uniformKey - The key of the sampler2D uniform to be updated, i.e. `iChannel0`. + * @param {WebGLTexture} texture - A WebGLTexture reference. + * @param {number} width - The width of the texture. + * @param {number} height - The height of the texture. + * @param {number} [textureIndex=0] - The texture index. + * @param {any} [textureData] - Additional texture data. * - * @return {this} This Tween instance. + * @return {this} This Shader instance. */ - play: function (resetFromTimeline) + setSampler2DBuffer: function (uniformKey, texture, width, height, textureIndex, textureData) { - if (resetFromTimeline === undefined) { resetFromTimeline = false; } - - var state = this.state; - - if (state === TWEEN_CONST.INIT && !this.parentIsTimeline) - { - this.resetTweenData(false); - - this.state = TWEEN_CONST.ACTIVE; - - return this; - } - else if (state === TWEEN_CONST.ACTIVE || (state === TWEEN_CONST.PENDING_ADD && this._pausedState === TWEEN_CONST.PENDING_ADD)) - { - return this; - } - else if (!this.parentIsTimeline && (state === TWEEN_CONST.PENDING_REMOVE || state === TWEEN_CONST.REMOVED)) - { - this.seek(0); - this.parent.makeActive(this); - - return this; - } + if (textureIndex === undefined) { textureIndex = 0; } + if (textureData === undefined) { textureData = {}; } - if (this.parentIsTimeline) - { - this.resetTweenData(resetFromTimeline); + var uniform = this.uniforms[uniformKey]; - if (this.calculatedOffset === 0) - { - this.state = TWEEN_CONST.ACTIVE; - } - else - { - this.countdown = this.calculatedOffset; + uniform.value = texture; - this.state = TWEEN_CONST.OFFSET_DELAY; - } - } - else if (this.paused) - { - this.paused = false; + textureData.width = width; + textureData.height = height; - this.makeActive(); - } - else - { - this.resetTweenData(resetFromTimeline); + uniform.textureData = textureData; - this.state = TWEEN_CONST.ACTIVE; + this._textureCount = textureIndex; - this.makeActive(); - } + this.initSampler2D(uniform); return this; }, /** - * Internal method that resets all of the Tween Data, including the progress and elapsed values. + * Sets a sampler2D uniform on this shader. * - * @method Phaser.Tweens.Tween#resetTweenData - * @since 3.0.0 + * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame + * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. + * + * If you wish to use another Shader as a sampler2D input for this shader, see the `Shader.setSampler2DBuffer` method. + * + * @method Phaser.GameObjects.Shader#setSampler2D + * @since 3.17.0 + * + * @param {string} uniformKey - The key of the sampler2D uniform to be updated, i.e. `iChannel0`. + * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. + * @param {number} [textureIndex=0] - The texture index. + * @param {any} [textureData] - Additional texture data. * - * @param {boolean} resetFromLoop - Has this method been called as part of a loop? + * @return {this} This Shader instance. */ - resetTweenData: function (resetFromLoop) + setSampler2D: function (uniformKey, textureKey, textureIndex, textureData) { - var data = this.data; - var total = this.totalData; - var totalTargets = this.totalTargets; - - for (var i = 0; i < total; i++) - { - var tweenData = data[i]; - - var target = tweenData.target; - var key = tweenData.key; - var targetIndex = tweenData.index; + if (textureIndex === undefined) { textureIndex = 0; } - tweenData.progress = 0; - tweenData.elapsed = 0; + var textureManager = this.scene.sys.textures; - tweenData.repeatCounter = (tweenData.repeat === -1) ? 999999999999 : tweenData.repeat; + if (textureManager.exists(textureKey)) + { + var frame = textureManager.getFrame(textureKey); - if (resetFromLoop) + if (frame.glTexture && frame.glTexture.isRenderTexture) { - tweenData.start = tweenData.getStartValue(target, key, tweenData.start, targetIndex, totalTargets, this); - - tweenData.end = tweenData.getEndValue(target, key, tweenData.end, targetIndex, totalTargets, this); + return this.setSampler2DBuffer(uniformKey, frame.glTexture, frame.width, frame.height, textureIndex, textureData); + } - tweenData.current = tweenData.start; + var uniform = this.uniforms[uniformKey]; + var source = frame.source; - tweenData.state = TWEEN_CONST.PLAYING_FORWARD; - } - else - { - tweenData.state = TWEEN_CONST.PENDING_RENDER; - } + uniform.textureKey = textureKey; + uniform.source = source.image; + uniform.value = frame.glTexture; - if (tweenData.delay > 0) + if (source.isGLTexture) { - tweenData.elapsed = tweenData.delay; + if (!textureData) + { + textureData = {}; + } - tweenData.state = TWEEN_CONST.DELAY; + textureData.width = source.width; + textureData.height = source.height; } - if (tweenData.getActiveValue) + if (textureData) { - target[key] = tweenData.getActiveValue(tweenData.target, tweenData.key, tweenData.start); + uniform.textureData = textureData; } - } - }, - /** - * Resumes the playback of a previously paused Tween. - * - * @method Phaser.Tweens.Tween#resume - * @since 3.0.0 - * - * @return {this} - This Tween instance. - */ - resume: function () - { - if (this.state === TWEEN_CONST.PAUSED) - { - this.paused = false; + this._textureCount = textureIndex; - this.state = this._pausedState; - } - else - { - this.play(); + this.initSampler2D(uniform); } return this; }, /** - * Seeks to a specific point in the Tween. + * Sets a property of a uniform already present on this shader. * - * **Note:** Be careful when seeking a Tween that repeats or loops forever, - * or that has an unusually long total duration, as it's possible to hang the browser. + * To modify the value of a uniform such as a 1f or 1i use the `value` property directly: + * + * ```javascript + * shader.setUniform('size.value', 16); + * ``` * - * The given position is a value between 0 and 1 which represents how far through the Tween to seek to. - * A value of 0.5 would seek to half-way through the Tween, where-as a value of zero would seek to the start. + * You can use dot notation to access deeper values, for example: * - * Note that the seek takes the entire duration of the Tween into account, including delays, loops and repeats. - * For example, a Tween that lasts for 2 seconds, but that loops 3 times, would have a total duration of 6 seconds, - * so seeking to 0.5 would seek to 3 seconds into the Tween, as that's half-way through its _entire_ duration. + * ```javascript + * shader.setUniform('resolution.value.x', 512); + * ``` * - * Seeking works by resetting the Tween to its initial values and then iterating through the Tween at `delta` - * jumps per step. The longer the Tween, the longer this can take. + * The change to the uniform will take effect the next time the shader is rendered. * - * @method Phaser.Tweens.Tween#seek - * @since 3.0.0 + * @method Phaser.GameObjects.Shader#setUniform + * @since 3.17.0 * - * @param {number} toPosition - A value between 0 and 1 which represents the progress point to seek to. - * @param {number} [delta=16.6] - The size of each step when seeking through the Tween. A higher value completes faster but at a cost of less precision. + * @param {string} key - The key of the uniform to modify. Use dots for deep properties, i.e. `resolution.value.x`. + * @param {any} value - The value to set into the uniform. * - * @return {this} This Tween instance. + * @return {this} This Shader instance. */ - seek: function (toPosition, delta) + setUniform: function (key, value) { - if (delta === undefined) { delta = 16.6; } - - if (this.state === TWEEN_CONST.REMOVED) - { - this.makeActive(); - } - - this.elapsed = 0; - this.progress = 0; - this.totalElapsed = 0; - this.totalProgress = 0; - - var data = this.data; - var totalTargets = this.totalTargets; - - for (var i = 0; i < this.totalData; i++) - { - var tweenData = data[i]; - var target = tweenData.target; - var gen = tweenData.gen; - var key = tweenData.key; - var targetIndex = tweenData.index; - - tweenData.progress = 0; - tweenData.elapsed = 0; - - tweenData.repeatCounter = (tweenData.repeat === -1) ? 999999999999 : tweenData.repeat; - - // Old function signature: i, totalTargets, target - // New function signature: target, key, value, index, total, tween - - tweenData.delay = gen.delay(target, key, 0, targetIndex, totalTargets, this); - tweenData.duration = Math.max(gen.duration(target, key, 0, targetIndex, totalTargets, this), 0.001); - tweenData.hold = gen.hold(target, key, 0, targetIndex, totalTargets, this); - tweenData.repeat = gen.repeat(target, key, 0, targetIndex, totalTargets, this); - tweenData.repeatDelay = gen.repeatDelay(target, key, 0, targetIndex, totalTargets, this); - - tweenData.current = tweenData.start; - tweenData.state = TWEEN_CONST.PLAYING_FORWARD; - - this.updateTweenData(this, tweenData, 0, targetIndex, totalTargets); - - if (tweenData.delay > 0) - { - tweenData.elapsed = tweenData.delay; - tweenData.state = TWEEN_CONST.DELAY; - } - } - - this.calcDuration(); - - var wasPaused = false; - - if (this.state === TWEEN_CONST.PAUSED) - { - wasPaused = true; - - this.state = TWEEN_CONST.ACTIVE; - } - - this.isSeeking = true; - - do - { - this.update(0, delta); - - } while (this.totalProgress < toPosition); - - this.isSeeking = false; - - if (wasPaused) - { - this.state = TWEEN_CONST.PAUSED; - } + SetValue(this.uniforms, key, value); return this; }, /** - * Sets an event based callback to be invoked during playback. + * Returns the uniform object for the given key, or `null` if the uniform couldn't be found. * - * Calling this method will replace a previously set callback for the given type, if any exists. + * @method Phaser.GameObjects.Shader#getUniform + * @since 3.17.0 * - * The types available are: + * @param {string} key - The key of the uniform to return the value for. + * + * @return {any} A reference to the uniform object. This is not a copy, so modifying it will update the original object also. + */ + getUniform: function (key) + { + return GetFastValue(this.uniforms, key, null); + }, + + /** + * A short-cut method that will directly set the texture being used by the `iChannel0` sampler2D uniform. * - * `onActive` When the Tween is moved from the pending to the active list in the Tween Manager, even if playback paused. - * `onStart` When the Tween starts playing after a delayed state. Will happen at the same time as `onActive` if it has no delay. - * `onYoyo` When a TweenData starts a yoyo. This happens _after_ the `hold` delay expires, if set. - * `onRepeat` When a TweenData repeats playback. This happens _after_ the `repeatDelay` expires, if set. - * `onComplete` When the Tween finishes playback fully or `Tween.stop` is called. Never invoked if tween is set to repeat infinitely. - * `onUpdate` When a TweenData updates a property on a source target during playback. - * `onLoop` When a Tween loops. This happens _after_ the `loopDelay` expires, if set. + * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame + * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. * - * @method Phaser.Tweens.Tween#setCallback - * @since 3.0.0 + * @method Phaser.GameObjects.Shader#setChannel0 + * @since 3.17.0 * - * @param {string} type - Type of the callback to set. - * @param {function} callback - The function to invoke when this callback happens. - * @param {array} [params] - An array of parameters for specified callbacks types. - * @param {any} [scope] - The context the callback will be invoked in. + * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. + * @param {any} [textureData] - Additional texture data. * - * @return {this} This Tween instance. + * @return {this} This Shader instance. */ - setCallback: function (type, callback, params, scope) + setChannel0: function (textureKey, textureData) { - this.callbacks[type] = { func: callback, scope: scope, params: params }; - - return this; + return this.setSampler2D('iChannel0', textureKey, 0, textureData); }, /** - * Flags the Tween as being complete, whatever stage of progress it is at. - * - * If an onComplete callback has been defined it will automatically invoke it, unless a `delay` - * argument is provided, in which case the Tween will delay for that period of time before calling the callback. + * A short-cut method that will directly set the texture being used by the `iChannel1` sampler2D uniform. * - * If you don't need a delay, or have an onComplete callback, then call `Tween.stop` instead. + * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame + * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. * - * @method Phaser.Tweens.Tween#complete - * @fires Phaser.Tweens.Events#TWEEN_COMPLETE - * @since 3.2.0 + * @method Phaser.GameObjects.Shader#setChannel1 + * @since 3.17.0 * - * @param {number} [delay=0] - The time to wait before invoking the complete callback. If zero it will fire immediately. + * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. + * @param {any} [textureData] - Additional texture data. * - * @return {this} This Tween instance. + * @return {this} This Shader instance. */ - complete: function (delay) + setChannel1: function (textureKey, textureData) { - if (delay === undefined) { delay = 0; } - - if (delay) - { - this.state = TWEEN_CONST.COMPLETE_DELAY; - - this.countdown = delay; - } - else - { - this.state = TWEEN_CONST.PENDING_REMOVE; - - this.dispatchTweenEvent(Events.TWEEN_COMPLETE, this.callbacks.onComplete); - } - - return this; + return this.setSampler2D('iChannel1', textureKey, 1, textureData); }, /** - * Immediately removes this Tween from the TweenManager and all of its internal arrays, - * no matter what stage it as it. Then sets the tween state to `REMOVED`. + * A short-cut method that will directly set the texture being used by the `iChannel2` sampler2D uniform. * - * You should dispose of your reference to this tween after calling this method, to - * free it from memory. + * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame + * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. * - * @method Phaser.Tweens.Tween#remove + * @method Phaser.GameObjects.Shader#setChannel2 * @since 3.17.0 * - * @return {this} This Tween instance. + * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. + * @param {any} [textureData] - Additional texture data. + * + * @return {this} This Shader instance. */ - remove: function () + setChannel2: function (textureKey, textureData) { - this.parent.remove(this); - - return this; + return this.setSampler2D('iChannel2', textureKey, 2, textureData); }, /** - * Stops the Tween immediately, whatever stage of progress it is at and flags it for removal by the TweenManager. + * A short-cut method that will directly set the texture being used by the `iChannel3` sampler2D uniform. * - * @method Phaser.Tweens.Tween#stop - * @since 3.0.0 + * The textureKey given is the key from the Texture Manager cache. You cannot use a single frame + * from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized. * - * @param {number} [resetTo] - If you want to seek the tween, provide a value between 0 and 1. + * @method Phaser.GameObjects.Shader#setChannel3 + * @since 3.17.0 * - * @return {this} This Tween instance. + * @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded. + * @param {any} [textureData] - Additional texture data. + * + * @return {this} This Shader instance. */ - stop: function (resetTo) + setChannel3: function (textureKey, textureData) { - if (this.state === TWEEN_CONST.ACTIVE) - { - if (resetTo !== undefined) - { - this.seek(resetTo); - } - } - - if (this.state !== TWEEN_CONST.REMOVED) - { - if (this.state === TWEEN_CONST.PAUSED || this.state === TWEEN_CONST.PENDING_ADD) - { - if (this.parentIsTimeline) - { - this.parent.manager._destroy.push(this); - this.parent.manager._toProcess++; - } - else - { - this.parent._destroy.push(this); - this.parent._toProcess++; - } - } - - this.dispatchTweenEvent(Events.TWEEN_STOP, this.callbacks.onStop); - - this.removeAllListeners(); - - this.state = TWEEN_CONST.PENDING_REMOVE; - } - - return this; + return this.setSampler2D('iChannel3', textureKey, 3, textureData); }, /** - * Internal method that advances the Tween based on the time values. - * - * @method Phaser.Tweens.Tween#update - * @fires Phaser.Tweens.Events#TWEEN_COMPLETE - * @fires Phaser.Tweens.Events#TWEEN_LOOP - * @fires Phaser.Tweens.Events#TWEEN_START - * @since 3.0.0 + * Internal method that takes a sampler2D uniform and prepares it for use by setting the + * gl texture parameters. * - * @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. + * @method Phaser.GameObjects.Shader#initSampler2D + * @private + * @since 3.17.0 * - * @return {boolean} Returns `true` if this Tween has finished and should be removed from the Tween Manager, otherwise returns `false`. + * @param {any} uniform - The sampler2D uniform to process. */ - update: function (timestamp, delta) + initSampler2D: function (uniform) { - if (this.state === TWEEN_CONST.PAUSED) + if (!uniform.value) { - return false; + return; } - if (this.useFrames) - { - delta = 1 * this.parent.timeScale; - } + var gl = this.gl; - delta *= this.timeScale; + gl.activeTexture(gl.TEXTURE0 + this._textureCount); + gl.bindTexture(gl.TEXTURE_2D, uniform.value); - this.elapsed += delta; - this.progress = Math.min(this.elapsed / this.duration, 1); + // Extended texture data - this.totalElapsed += delta; - this.totalProgress = Math.min(this.totalElapsed / this.totalDuration, 1); + var data = uniform.textureData; - switch (this.state) + if (data && !uniform.value.isRenderTexture) { - case TWEEN_CONST.ACTIVE: - - if (!this.hasStarted && !this.isSeeking) - { - this.startDelay -= delta; - - if (this.startDelay <= 0) - { - this.hasStarted = true; - - this.dispatchTweenEvent(Events.TWEEN_START, this.callbacks.onStart); - } - } - - var stillRunning = false; - - for (var i = 0; i < this.totalData; i++) - { - var tweenData = this.data[i]; - - if (this.updateTweenData(this, tweenData, delta)) - { - stillRunning = true; - } - } - - // Anything still running? If not, we're done - if (!stillRunning) - { - this.nextState(); - } - - break; - - case TWEEN_CONST.LOOP_DELAY: - - this.countdown -= delta; - - if (this.countdown <= 0) - { - this.state = TWEEN_CONST.ACTIVE; - - this.dispatchTweenEvent(Events.TWEEN_LOOP, this.callbacks.onLoop); - } - - break; - - case TWEEN_CONST.OFFSET_DELAY: - - this.countdown -= delta; + // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D - if (this.countdown <= 0) - { - this.state = TWEEN_CONST.ACTIVE; - } + // mag / minFilter can be: gl.LINEAR, gl.LINEAR_MIPMAP_LINEAR or gl.NEAREST + // wrapS/T can be: gl.CLAMP_TO_EDGE or gl.REPEAT + // format can be: gl.LUMINANCE or gl.RGBA - break; + var magFilter = gl[GetFastValue(data, 'magFilter', 'linear').toUpperCase()]; + var minFilter = gl[GetFastValue(data, 'minFilter', 'linear').toUpperCase()]; + var wrapS = gl[GetFastValue(data, 'wrapS', 'repeat').toUpperCase()]; + var wrapT = gl[GetFastValue(data, 'wrapT', 'repeat').toUpperCase()]; + var format = gl[GetFastValue(data, 'format', 'rgba').toUpperCase()]; - case TWEEN_CONST.COMPLETE_DELAY: + if (data.repeat) + { + wrapS = gl.REPEAT; + wrapT = gl.REPEAT; + } - this.countdown -= delta; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, !!data.flipY); - if (this.countdown <= 0) - { - this.state = TWEEN_CONST.PENDING_REMOVE; + if (data.width) + { + var width = GetFastValue(data, 'width', 512); + var height = GetFastValue(data, 'height', 2); + var border = GetFastValue(data, 'border', 0); - this.dispatchTweenEvent(Events.TWEEN_COMPLETE, this.callbacks.onComplete); - } + // texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels) + gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, border, format, gl.UNSIGNED_BYTE, null); + } + else + { + // texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, ImageData? pixels) + gl.texImage2D(gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, uniform.source); + } - break; + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT); } - return (this.state === TWEEN_CONST.PENDING_REMOVE); - }, - - /** - * Internal method that will emit a TweenData based Event and invoke the given callback. - * - * @method Phaser.Tweens.Tween#dispatchTweenDataEvent - * @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. - * @param {Phaser.Types.Tweens.TweenDataConfig} tweenData - The TweenData object that caused this event. - */ - dispatchTweenDataEvent: function (event, callback, tweenData) - { - if (!this.isSeeking) - { - this.emit(event, this, tweenData.key, tweenData.target, tweenData.current, tweenData.previous); + this.renderer.setProgram(this.program); - if (callback) - { - callback.params[1] = tweenData.target; + gl.uniform1i(uniform.uniformLocation, this._textureCount); - callback.func.apply(callback.scope, callback.params); - } - } + this._textureCount++; }, /** - * Internal method that will emit a Tween based Event and invoke the given callback. - * - * @method Phaser.Tweens.Tween#dispatchTweenEvent - * @since 3.19.0 + * Synchronizes all of the uniforms this shader uses. + * Each uniforms gl function is called in turn. * - * @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. + * @method Phaser.GameObjects.Shader#syncUniforms + * @private + * @since 3.17.0 */ - dispatchTweenEvent: function (event, callback) + syncUniforms: function () { - if (!this.isSeeking) - { - this.emit(event, this, this.targets); - - if (callback) - { - callback.params[1] = this.targets; + var gl = this.gl; - callback.func.apply(callback.scope, callback.params); - } - } - }, + var uniforms = this.uniforms; + var uniform; + var length; + var glFunc; + var location; + var value; + var textureCount = 0; - /** - * Internal method used as part of the playback process that sets a tween to play in reverse. - * - * @method Phaser.Tweens.Tween#setStateFromEnd - * @fires Phaser.Tweens.Events#TWEEN_REPEAT - * @fires Phaser.Tweens.Events#TWEEN_YOYO - * @since 3.0.0 - * - * @param {Phaser.Tweens.Tween} tween - The Tween to update. - * @param {Phaser.Types.Tweens.TweenDataConfig} tweenData - The TweenData property to update. - * @param {number} diff - Any extra time that needs to be accounted for in the elapsed and progress values. - * - * @return {number} The state of this Tween. - */ - setStateFromEnd: function (tween, tweenData, diff) - { - if (tweenData.yoyo) + for (var key in uniforms) { - // We've hit the end of a Playing Forward TweenData and we have a yoyo + uniform = uniforms[key]; - // Account for any extra time we got from the previous frame - tweenData.elapsed = diff; - tweenData.progress = diff / tweenData.duration; + glFunc = uniform.glFunc; + length = uniform.glValueLength; + location = uniform.uniformLocation; + value = uniform.value; - if (tweenData.flipX) + if (value === null) { - tweenData.target.toggleFlipX(); + continue; } - if (tweenData.flipY) + if (length === 1) { - tweenData.target.toggleFlipY(); + if (uniform.glMatrix) + { + glFunc.call(gl, location, uniform.transpose, value); + } + else + { + glFunc.call(gl, location, value); + } } - - this.dispatchTweenDataEvent(Events.TWEEN_YOYO, tween.callbacks.onYoyo, tweenData); - - tweenData.start = tweenData.getStartValue(tweenData.target, tweenData.key, tweenData.start, tweenData.index, tween.totalTargets, tween); - - return TWEEN_CONST.PLAYING_BACKWARD; - } - else if (tweenData.repeatCounter > 0) - { - // We've hit the end of a Playing Forward TweenData and we have a Repeat. - // So we're going to go right back to the start to repeat it again. - - tweenData.repeatCounter--; - - // Account for any extra time we got from the previous frame - tweenData.elapsed = diff; - tweenData.progress = diff / tweenData.duration; - - if (tweenData.flipX) + else if (length === 2) { - tweenData.target.toggleFlipX(); + glFunc.call(gl, location, value.x, value.y); } - - if (tweenData.flipY) + else if (length === 3) { - tweenData.target.toggleFlipY(); + glFunc.call(gl, location, value.x, value.y, value.z); } - - tweenData.start = tweenData.getStartValue(tweenData.target, tweenData.key, tweenData.start, tweenData.index, tween.totalTargets, tween); - - tweenData.end = tweenData.getEndValue(tweenData.target, tweenData.key, tweenData.start, tweenData.index, tween.totalTargets, tween); - - // Delay? - if (tweenData.repeatDelay > 0) + else if (length === 4) { - tweenData.elapsed = tweenData.repeatDelay - diff; - - tweenData.current = tweenData.start; - - tweenData.target[tweenData.key] = tweenData.current; - - return TWEEN_CONST.REPEAT_DELAY; + glFunc.call(gl, location, value.x, value.y, value.z, value.w); } - else + else if (uniform.type === 'sampler2D') { - this.dispatchTweenDataEvent(Events.TWEEN_REPEAT, tween.callbacks.onRepeat, tweenData); + gl.activeTexture(gl.TEXTURE0 + textureCount); + + gl.bindTexture(gl.TEXTURE_2D, value); + + gl.uniform1i(location, textureCount); - return TWEEN_CONST.PLAYING_FORWARD; + textureCount++; } } - - return TWEEN_CONST.COMPLETE; }, /** - * Internal method used as part of the playback process that sets a tween to play from the start. + * Called automatically during render. * - * @method Phaser.Tweens.Tween#setStateFromStart - * @fires Phaser.Tweens.Events#TWEEN_REPEAT - * @since 3.0.0 + * This method performs matrix ITRS and then stores the resulting value in the `uViewMatrix` uniform. + * It then sets up the vertex buffer and shader, updates and syncs the uniforms ready + * for flush to be called. * - * @param {Phaser.Tweens.Tween} tween - The Tween to update. - * @param {Phaser.Types.Tweens.TweenDataConfig} tweenData - The TweenData property to update. - * @param {number} diff - Any extra time that needs to be accounted for in the elapsed and progress values. + * @method Phaser.GameObjects.Shader#load + * @since 3.17.0 * - * @return {number} The state of this Tween. + * @param {Phaser.GameObjects.Components.TransformMatrix} [matrix2D] - The transform matrix to use during rendering. */ - setStateFromStart: function (tween, tweenData, diff) + load: function (matrix2D) { - if (tweenData.repeatCounter > 0) + // ITRS + + var gl = this.gl; + var width = this.width; + var height = this.height; + var renderer = this.renderer; + var program = this.program; + var vm = this.viewMatrix; + + if (!this.renderToTexture) { - tweenData.repeatCounter--; + var x = -this._displayOriginX; + var y = -this._displayOriginY; + + vm[0] = matrix2D[0]; + vm[1] = matrix2D[1]; + vm[4] = matrix2D[2]; + vm[5] = matrix2D[3]; + vm[8] = matrix2D[4]; + vm[9] = matrix2D[5]; + vm[12] = vm[0] * x + vm[4] * y; + vm[13] = vm[1] * x + vm[5] * y; + } - // Account for any extra time we got from the previous frame - tweenData.elapsed = diff; - tweenData.progress = diff / tweenData.duration; + // Update vertex shader uniforms - if (tweenData.flipX) - { - tweenData.target.toggleFlipX(); - } + gl.useProgram(program); - if (tweenData.flipY) - { - tweenData.target.toggleFlipY(); - } + gl.uniformMatrix4fv(gl.getUniformLocation(program, 'uViewMatrix'), false, vm); + gl.uniform2f(gl.getUniformLocation(program, 'uResolution'), this.width, this.height); - tweenData.end = tweenData.getEndValue(tweenData.target, tweenData.key, tweenData.start, tweenData.index, tween.totalTargets, tween); + // Update fragment shader uniforms - // Delay? - if (tweenData.repeatDelay > 0) - { - tweenData.elapsed = tweenData.repeatDelay - diff; + var uniforms = this.uniforms; + var res = uniforms.resolution; - tweenData.current = tweenData.start; + res.value.x = width; + res.value.y = height; - tweenData.target[tweenData.key] = tweenData.current; + uniforms.time.value = renderer.game.loop.getDuration(); - return TWEEN_CONST.REPEAT_DELAY; - } - else - { - this.dispatchTweenDataEvent(Events.TWEEN_REPEAT, tween.callbacks.onRepeat, tweenData); + var pointer = this.pointer; - return TWEEN_CONST.PLAYING_FORWARD; - } + if (pointer) + { + var mouse = uniforms.mouse; + + var px = pointer.x / width; + var py = 1 - pointer.y / height; + + mouse.value.x = px.toFixed(2); + mouse.value.y = py.toFixed(2); } - return TWEEN_CONST.COMPLETE; + this.syncUniforms(); }, /** - * Internal method that advances the TweenData based on the time value given. - * - * @method Phaser.Tweens.Tween#updateTweenData - * @fires Phaser.Tweens.Events#TWEEN_UPDATE - * @fires Phaser.Tweens.Events#TWEEN_REPEAT - * @since 3.0.0 + * Called automatically during render. * - * @param {Phaser.Tweens.Tween} tween - The Tween to update. - * @param {Phaser.Types.Tweens.TweenDataConfig} tweenData - The TweenData property to update. - * @param {number} delta - Either a value in ms, or 1 if Tween.useFrames is true. + * Sets the active shader, loads the vertex buffer and then draws. * - * @return {boolean} True if the tween is not complete (e.g., playing), or false if the tween is complete. + * @method Phaser.GameObjects.Shader#flush + * @since 3.17.0 */ - updateTweenData: function (tween, tweenData, delta) + flush: function () { - var target = tweenData.target; - - switch (tweenData.state) - { - case TWEEN_CONST.PLAYING_FORWARD: - case TWEEN_CONST.PLAYING_BACKWARD: - - if (!target) - { - tweenData.state = TWEEN_CONST.COMPLETE; - break; - } - - var elapsed = tweenData.elapsed; - var duration = tweenData.duration; - var diff = 0; - - elapsed += delta; - - if (elapsed > duration) - { - diff = elapsed - duration; - elapsed = duration; - } + // Bind - var forward = (tweenData.state === TWEEN_CONST.PLAYING_FORWARD); - var progress = elapsed / duration; + var width = this.width; + var height = this.height; + var program = this.program; - tweenData.elapsed = elapsed; - tweenData.progress = progress; - tweenData.previous = tweenData.current; + var gl = this.gl; + var vertexBuffer = this.vertexBuffer; + var renderer = this.renderer; + var vertexSize = Float32Array.BYTES_PER_ELEMENT * 2; - if (progress === 1) - { - if (forward) - { - tweenData.current = tweenData.end; - target[tweenData.key] = tweenData.end; + if (this.renderToTexture) + { + renderer.setFramebuffer(this.framebuffer); - if (tweenData.hold > 0) - { - tweenData.elapsed = tweenData.hold - diff; + gl.clearColor(0, 0, 0, 0); - tweenData.state = TWEEN_CONST.HOLD_DELAY; - } - else - { - tweenData.state = this.setStateFromEnd(tween, tweenData, diff); - } - } - else - { - tweenData.current = tweenData.start; - target[tweenData.key] = tweenData.start; + gl.clear(gl.COLOR_BUFFER_BIT); + } - tweenData.state = this.setStateFromStart(tween, tweenData, diff); - } - } - else - { - var v = (forward) ? tweenData.ease(progress) : tweenData.ease(1 - progress); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); - tweenData.current = tweenData.start + ((tweenData.end - tweenData.start) * v); + var location = gl.getAttribLocation(program, 'inPosition'); - target[tweenData.key] = tweenData.current; - } + if (location !== -1) + { + gl.enableVertexAttribArray(location); - this.dispatchTweenDataEvent(Events.TWEEN_UPDATE, tween.callbacks.onUpdate, tweenData); + gl.vertexAttribPointer(location, 2, gl.FLOAT, false, vertexSize, 0); + } - break; + // Draw - case TWEEN_CONST.DELAY: + var vf = this.vertexViewF32; - tweenData.elapsed -= delta; + vf[3] = height; + vf[4] = width; + vf[5] = height; + vf[8] = width; + vf[9] = height; + vf[10] = width; - if (tweenData.elapsed <= 0) - { - tweenData.elapsed = Math.abs(tweenData.elapsed); + // Flush - tweenData.state = TWEEN_CONST.PENDING_RENDER; - } + var vertexCount = 6; - break; + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bytes.subarray(0, vertexCount * vertexSize)); - case TWEEN_CONST.REPEAT_DELAY: + gl.drawArrays(gl.TRIANGLES, 0, vertexCount); - tweenData.elapsed -= delta; + if (this.renderToTexture) + { + renderer.setFramebuffer(null, false); + } + }, - if (tweenData.elapsed <= 0) - { - tweenData.elapsed = Math.abs(tweenData.elapsed); - - tweenData.state = TWEEN_CONST.PLAYING_FORWARD; - - this.dispatchTweenDataEvent(Events.TWEEN_REPEAT, tween.callbacks.onRepeat, tweenData); - } - - break; - - case TWEEN_CONST.HOLD_DELAY: - - tweenData.elapsed -= delta; - - if (tweenData.elapsed <= 0) - { - tweenData.state = this.setStateFromEnd(tween, tweenData, Math.abs(tweenData.elapsed)); - } - - break; - - case TWEEN_CONST.PENDING_RENDER: + /** + * A NOOP method so you can pass a Shader to a Container. + * Calling this method will do nothing. It is intentionally empty. + * + * @method Phaser.GameObjects.Shader#setAlpha + * @private + * @since 3.17.0 + */ + setAlpha: function () + { + }, - if (target) - { - tweenData.start = tweenData.getStartValue(target, tweenData.key, target[tweenData.key], tweenData.index, tween.totalTargets, tween); + /** + * A NOOP method so you can pass a Shader to a Container. + * Calling this method will do nothing. It is intentionally empty. + * + * @method Phaser.GameObjects.Shader#setBlendMode + * @private + * @since 3.17.0 + */ + setBlendMode: function () + { + }, - tweenData.end = tweenData.getEndValue(target, tweenData.key, tweenData.start, tweenData.index, tween.totalTargets, tween); + /** + * Internal destroy handler, called as part of the destroy process. + * + * @method Phaser.GameObjects.Shader#preDestroy + * @protected + * @since 3.17.0 + */ + preDestroy: function () + { + var gl = this.gl; - tweenData.current = tweenData.start; + gl.deleteProgram(this.program); + gl.deleteBuffer(this.vertexBuffer); - target[tweenData.key] = tweenData.start; + if (this.renderToTexture) + { + this.renderer.deleteFramebuffer(this.framebuffer); - tweenData.state = TWEEN_CONST.PLAYING_FORWARD; - } - else - { - tweenData.state = TWEEN_CONST.COMPLETE; - } + this.texture.destroy(); - break; + this.framebuffer = null; + this.glTexture = null; + this.texture = null; } - - // Return TRUE if this TweenData still playing, otherwise return FALSE - return (tweenData.state !== TWEEN_CONST.COMPLETE); } }); -// onActive = 'active' event = When the Tween is moved from the pending to the active list in the manager, even if playback delayed -// onStart = 'start' event = When the Tween starts playing from a delayed state (will happen same time as onActive if no delay) -// onStop = 'stop' event = When the Tween is stopped -// onYoyo = 'yoyo' event = When the Tween starts a yoyo -// onRepeat = 'repeat' event = When a TweenData repeats playback (if any) -// onComplete = 'complete' event = When the Tween finishes all playback (can sometimes never happen if repeat -1), also when 'stop' called -// onUpdate = 'update' event = When the Tween updates a TweenData during playback (expensive!) -// onLoop = 'loop' event = Used to loop ALL TweenDatas in a Tween +module.exports = Shader; + -Tween.TYPES = [ - 'onActive', - 'onComplete', - 'onLoop', - 'onRepeat', - 'onStart', - 'onStop', - 'onUpdate', - 'onYoyo' -]; +/***/ }), + +/***/ 10612: +/***/ ((module) => { /** - * Creates a new Tween object. - * - * Note: This method will only be available if Tweens have been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#tween - * @since 3.0.0 - * - * @param {Phaser.Types.Tweens.TweenBuilderConfig|object} config - The Tween configuration. - * - * @return {Phaser.Tweens.Tween} The Tween that was created. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -GameObjectFactory.register('tween', function (config) -{ - return this.scene.sys.tweens.add(config); -}); - -// When registering a factory function 'this' refers to the GameObjectFactory 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 /** - * Creates a new Tween object and returns it. - * - * Note: This method will only be available if Tweens have been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectCreator#tween - * @since 3.0.0 + * This is a stub function for Shader.Render. There is no Canvas renderer for Shader objects. * - * @param {Phaser.Types.Tweens.TweenBuilderConfig|object} config - The Tween configuration. + * @method Phaser.GameObjects.Shader#renderCanvas + * @since 3.17.0 + * @private * - * @return {Phaser.Tweens.Tween} The Tween that was created. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Shader} src - The Game Object being rendered in this call. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. */ -GameObjectCreator.register('tween', function (config) +var ShaderCanvasRenderer = function () { - return this.scene.sys.tweens.create(config); -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +}; -module.exports = Tween; +module.exports = ShaderCanvasRenderer; /***/ }), -/* 267 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 13908: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var Shader = __webpack_require__(27902); + /** - * @namespace Phaser.Tweens.Events + * Creates a new Shader Game Object and returns it. + * + * Note: This method will only be available if the Shader Game Object and WebGL support have been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#shader + * @since 3.17.0 + * + * @param {Phaser.Types.GameObjects.Shader.ShaderConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Shader} The Game Object that was created. */ +GameObjectCreator.register('shader', function (config, addToScene) +{ + if (config === undefined) { config = {}; } -module.exports = { + var key = GetAdvancedValue(config, 'key', null); + var x = GetAdvancedValue(config, 'x', 0); + var y = GetAdvancedValue(config, 'y', 0); + var width = GetAdvancedValue(config, 'width', 128); + var height = GetAdvancedValue(config, 'height', 128); - TIMELINE_COMPLETE: __webpack_require__(1466), - TIMELINE_LOOP: __webpack_require__(1467), - TIMELINE_PAUSE: __webpack_require__(1468), - TIMELINE_RESUME: __webpack_require__(1469), - TIMELINE_START: __webpack_require__(1470), - TIMELINE_UPDATE: __webpack_require__(1471), - TWEEN_ACTIVE: __webpack_require__(1472), - TWEEN_COMPLETE: __webpack_require__(1473), - TWEEN_LOOP: __webpack_require__(1474), - TWEEN_REPEAT: __webpack_require__(1475), - TWEEN_START: __webpack_require__(1476), - TWEEN_STOP: __webpack_require__(1477), - TWEEN_UPDATE: __webpack_require__(1478), - TWEEN_YOYO: __webpack_require__(1479) + var shader = new Shader(this.scene, key, x, y, width, height); -}; + if (addToScene !== undefined) + { + config.add = addToScene; + } + + BuildGameObject(this.scene, shader, config); + + return shader; +}); + +// When registering a factory function 'this' refers to the GameObjectCreator context. /***/ }), -/* 268 */ -/***/ (function(module, exports) { + +/***/ 51979: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Shader = __webpack_require__(27902); +var GameObjectFactory = __webpack_require__(61286); + /** - * Returns a TweenDataConfig object that describes the tween data for a unique property of a unique target. - * A single Tween consists of multiple TweenDatas, depending on how many properties are being changed by the Tween. + * Creates a new Shader Game Object and adds it to the Scene. * - * This is an internal function used by the TweenBuilder and should not be accessed directly, instead, - * Tweens should be created using the GameObjectFactory or GameObjectCreator. + * Note: This method will only be available if the Shader Game Object and WebGL support have been built into Phaser. * - * @function Phaser.Tweens.TweenData - * @since 3.0.0 + * @method Phaser.GameObjects.GameObjectFactory#shader + * @webglOnly + * @since 3.17.0 * - * @param {any} target - The target to tween. - * @param {number} index - The target index within the Tween targets array. - * @param {string} key - The property of the target to tween. - * @param {function} getEnd - What the property will be at the END of the Tween. - * @param {function} getStart - What the property will be at the START of the Tween. - * @param {?function} getActive - If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. - * @param {function} ease - The ease function this tween uses. - * @param {number} delay - Time in ms/frames before tween will start. - * @param {number} duration - Duration of the tween in ms/frames. - * @param {boolean} yoyo - Determines whether the tween should return back to its start value after hold has expired. - * @param {number} hold - Time in ms/frames the tween will pause before repeating or returning to its starting value if yoyo is set to true. - * @param {number} repeat - Number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. - * @param {number} repeatDelay - Time in ms/frames before the repeat will start. - * @param {boolean} flipX - Should toggleFlipX be called when yoyo or repeat happens? - * @param {boolean} flipY - Should toggleFlipY be called when yoyo or repeat happens? + * @param {(string|Phaser.Display.BaseShader)} key - The key of the shader to use from the shader cache, or a BaseShader instance. + * @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 Game Object. + * @param {number} [height=128] - The height of the Game Object. + * @param {string[]} [textures] - Optional array of texture keys to bind to the iChannel0...3 uniforms. The textures must already exist in the Texture Manager. + * @param {object} [textureData] - Optional additional texture data. * - * @return {Phaser.Types.Tweens.TweenDataConfig} The config object describing this TweenData. + * @return {Phaser.GameObjects.Shader} The Game Object that was created. */ -var TweenData = function (target, index, key, getEnd, getStart, getActive, ease, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY) +if (true) { - return { - - // The target to tween - target: target, - - // The index of the target within the tween targets array - index: index, + GameObjectFactory.register('shader', function (key, x, y, width, height, textures, textureData) + { + return this.displayList.add(new Shader(this.scene, key, x, y, width, height, textures, textureData)); + }); +} - // The property of the target to tween - key: key, - // What to set the property to the moment the TweenData is invoked. - getActiveValue: getActive, +/***/ }), - // The returned value sets what the property will be at the END of the Tween. - getEndValue: getEnd, +/***/ 24252: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // The returned value sets what the property will be at the START of the Tween. - getStartValue: getStart, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // The ease function this tween uses. - ease: ease, +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - // Duration of the tween in ms/frames, excludes time for yoyo or repeats. - duration: 0, +if (true) +{ + renderWebGL = __webpack_require__(19782); +} - // The total calculated duration of this TweenData (based on duration, repeat, delay and yoyo) - totalDuration: 0, +if (true) +{ + renderCanvas = __webpack_require__(10612); +} - // Time in ms/frames before tween will start. - delay: 0, +module.exports = { - // Cause the tween to return back to its start value after hold has expired. - yoyo: yoyo, + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - // Time in ms/frames the tween will pause before running the yoyo or starting a repeat. - hold: 0, +}; - // Number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. - repeat: 0, - // Time in ms/frames before the repeat will start. - repeatDelay: 0, +/***/ }), - // Automatically call toggleFlipX when the TweenData yoyos or repeats - flipX: flipX, +/***/ 19782: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Automatically call toggleFlipY when the TweenData yoyos or repeats - flipY: flipY, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Between 0 and 1 showing completion of this TweenData. - progress: 0, +var GetCalcMatrix = __webpack_require__(73329); - // Delta counter. - elapsed: 0, +/** + * 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.Shader#renderWebGL + * @since 3.17.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Shader} 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 ShaderWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + if (!src.shader) + { + return; + } - // How many repeats are left to run? - repeatCounter: 0, + camera.addToRenderList(src); - // Ease Value Data: + renderer.pipelines.clear(); - start: 0, - previous: 0, - current: 0, - end: 0, + if (src.renderToTexture) + { + src.load(); + src.flush(); + } + else + { + var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; - // Time Durations - t1: 0, - t2: 0, + // Renderer size changed? + if (renderer.width !== src._rendererWidth || renderer.height !== src._rendererHeight) + { + src.projOrtho(0, renderer.width, renderer.height, 0); + } - // LoadValue generation functions - gen: { - delay: delay, - duration: duration, - hold: hold, - repeat: repeat, - repeatDelay: repeatDelay - }, + src.load(calcMatrix.matrix); + src.flush(); + } - // TWEEN_CONST.CREATED - state: 0 - }; + renderer.pipelines.rebind(); }; -module.exports = TweenData; +module.exports = ShaderWebGLRenderer; /***/ }), -/* 269 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 19543: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MathWrap = __webpack_require__(68); +var Utils = __webpack_require__(75512); /** - * Wrap an angle. - * - * Wraps the angle to a value in the range of -PI to PI. - * - * @function Phaser.Math.Angle.Wrap - * @since 3.0.0 + * Renders a filled path for the given Shape. * - * @param {number} angle - The angle to wrap, in radians. + * @method Phaser.GameObjects.Shape#FillPathWebGL + * @since 3.13.0 + * @private * - * @return {number} The wrapped angle, in radians. + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The WebGL Pipeline used to render this Shape. + * @param {Phaser.GameObjects.Components.TransformMatrix} calcMatrix - The transform matrix used to get the position values. + * @param {Phaser.GameObjects.Shape} src - The Game Object shape being rendered in this call. + * @param {number} alpha - The base alpha value. + * @param {number} dx - The source displayOriginX. + * @param {number} dy - The source displayOriginY. */ -var Wrap = function (angle) +var FillPathWebGL = function (pipeline, calcMatrix, src, alpha, dx, dy) { - return MathWrap(angle, -Math.PI, Math.PI); + var fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha); + + var path = src.pathData; + var pathIndexes = src.pathIndexes; + + for (var i = 0; i < pathIndexes.length; i += 3) + { + var p0 = pathIndexes[i] * 2; + var p1 = pathIndexes[i + 1] * 2; + var p2 = pathIndexes[i + 2] * 2; + + var x0 = path[p0 + 0] - dx; + var y0 = path[p0 + 1] - dy; + var x1 = path[p1 + 0] - dx; + var y1 = path[p1 + 1] - dy; + var x2 = path[p2 + 0] - dx; + var y2 = path[p2 + 1] - dy; + + var tx0 = calcMatrix.getX(x0, y0); + var ty0 = calcMatrix.getY(x0, y0); + + var tx1 = calcMatrix.getX(x1, y1); + var ty1 = calcMatrix.getY(x1, y1); + + var tx2 = calcMatrix.getX(x2, y2); + var ty2 = calcMatrix.getY(x2, y2); + + pipeline.batchTri(src, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, 2); + } }; -module.exports = Wrap; +module.exports = FillPathWebGL; /***/ }), -/* 270 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 15608: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Wrap = __webpack_require__(68); - /** - * Wrap an angle in degrees. - * - * Wraps the angle to a value in the range of -180 to 180. - * - * @function Phaser.Math.Angle.WrapDegrees - * @since 3.0.0 + * Sets the fillStyle on the target context based on the given Shape. * - * @param {number} angle - The angle to wrap, in degrees. + * @method Phaser.GameObjects.Shape#FillStyleCanvas + * @since 3.13.0 + * @private * - * @return {number} The wrapped angle, in degrees. + * @param {CanvasRenderingContext2D} ctx - The context to set the fill style on. + * @param {Phaser.GameObjects.Shape} src - The Game Object to set the fill style from. + * @param {number} [altColor] - An alternative color to render with. + * @param {number} [altAlpha] - An alternative alpha to render with. */ -var WrapDegrees = function (angle) +var FillStyleCanvas = function (ctx, src, altColor, altAlpha) { - return Wrap(angle, -180, 180); -}; - -module.exports = WrapDegrees; - - -/***/ }), -/* 271 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.Axes` module contains methods for creating and manipulating sets of axes. -* -* @class Axes -*/ - -var Axes = {}; - -module.exports = Axes; - -var Vector = __webpack_require__(83); -var Common = __webpack_require__(32); - -(function() { - - /** - * Creates a new set of axes from the given vertices. - * @method fromVertices - * @param {vertices} vertices - * @return {axes} A new axes from the given vertices - */ - Axes.fromVertices = function(vertices) { - var axes = {}; - - // find the unique axes, using edge normal gradients - for (var i = 0; i < vertices.length; i++) { - var j = (i + 1) % vertices.length, - normal = Vector.normalise({ - x: vertices[j].y - vertices[i].y, - y: vertices[i].x - vertices[j].x - }), - gradient = (normal.y === 0) ? Infinity : (normal.x / normal.y); - - // limit precision - gradient = gradient.toFixed(3).toString(); - axes[gradient] = normal; - } - - return Common.values(axes); - }; + var fillColor = (altColor) ? altColor : src.fillColor; + var fillAlpha = (altAlpha) ? altAlpha : src.fillAlpha; - /** - * Rotates a set of axes by the given angle. - * @method rotate - * @param {axes} axes - * @param {number} angle - */ - Axes.rotate = function(axes, angle) { - if (angle === 0) - return; - - var cos = Math.cos(angle), - sin = Math.sin(angle); + var red = ((fillColor & 0xFF0000) >>> 16); + var green = ((fillColor & 0xFF00) >>> 8); + var blue = (fillColor & 0xFF); - for (var i = 0; i < axes.length; i++) { - var axis = axes[i], - xx; - xx = axis.x * cos - axis.y * sin; - axis.y = axis.x * sin + axis.y * cos; - axis.x = xx; - } - }; + ctx.fillStyle = 'rgba(' + red + ',' + green + ',' + blue + ',' + fillAlpha + ')'; +}; -})(); +module.exports = FillStyleCanvas; /***/ }), -/* 272 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 17876: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Physics.Matter.Events + * 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; -module.exports = { - - AFTER_ADD: __webpack_require__(1504), - AFTER_REMOVE: __webpack_require__(1505), - AFTER_UPDATE: __webpack_require__(1506), - BEFORE_ADD: __webpack_require__(1507), - BEFORE_REMOVE: __webpack_require__(1508), - BEFORE_UPDATE: __webpack_require__(1509), - COLLISION_ACTIVE: __webpack_require__(1510), - COLLISION_END: __webpack_require__(1511), - COLLISION_START: __webpack_require__(1512), - DRAG_END: __webpack_require__(1513), - DRAG: __webpack_require__(1514), - DRAG_START: __webpack_require__(1515), - PAUSE: __webpack_require__(1516), - RESUME: __webpack_require__(1517), - SLEEP_END: __webpack_require__(1518), - SLEEP_START: __webpack_require__(1519) + 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; -/***/ }), -/* 273 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter.Detector` module contains methods for detecting collisions given a set of pairs. -* -* @class Detector -*/ - -// TODO: speculative contacts - -var Detector = {}; - -module.exports = Detector; -var SAT = __webpack_require__(274); -var Pair = __webpack_require__(250); -var Bounds = __webpack_require__(84); +/***/ }), -(function() { +/***/ 91461: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Finds all collisions given a list of pairs. - * @method collisions - * @param {pair[]} broadphasePairs - * @param {engine} engine - * @return {array} collisions - */ - Detector.collisions = function(broadphasePairs, engine) { - var collisions = [], - pairsTable = engine.pairs.table; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // @if DEBUG - var metrics = engine.metrics; - // @endif - - for (var i = 0; i < broadphasePairs.length; i++) { - var bodyA = broadphasePairs[i][0], - bodyB = broadphasePairs[i][1]; +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var Line = __webpack_require__(88829); - if ((bodyA.isStatic || bodyA.isSleeping) && (bodyB.isStatic || bodyB.isSleeping)) - continue; - - if (!Detector.canCollide(bodyA.collisionFilter, bodyB.collisionFilter)) - continue; +/** + * @classdesc + * The Shape Game Object is a base class for the various different shapes, such as the Arc, Star or Polygon. + * You cannot add a Shape directly to your Scene, it is meant as a base for your own custom Shape classes. + * + * @class Shape + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 + * + * @extends Phaser.GameObjects.Components.AlphaSingle + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @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 {string} [type] - The internal type of the Shape. + * @param {any} [data] - The data of the source shape geometry, if any. + */ +var Shape = new Class({ - // @if DEBUG - metrics.midphaseTests += 1; - // @endif + Extends: GameObject, - // mid phase - if (Bounds.overlaps(bodyA.bounds, bodyB.bounds)) { - for (var j = bodyA.parts.length > 1 ? 1 : 0; j < bodyA.parts.length; j++) { - var partA = bodyA.parts[j]; + Mixins: [ + Components.AlphaSingle, + Components.BlendMode, + Components.Depth, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Transform, + Components.Visible + ], - for (var k = bodyB.parts.length > 1 ? 1 : 0; k < bodyB.parts.length; k++) { - var partB = bodyB.parts[k]; + initialize: - if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) { - // find a previous collision we could reuse - var pairId = Pair.id(partA, partB), - pair = pairsTable[pairId], - previousCollision; + function Shape (scene, type, data) + { + if (type === undefined) { type = 'Shape'; } - if (pair && pair.isActive) { - previousCollision = pair.collision; - } else { - previousCollision = null; - } + GameObject.call(this, scene, type); - // narrow phase - var collision = SAT.collides(partA, partB, previousCollision); + /** + * The source Shape data. Typically a geometry object. + * You should not manipulate this directly. + * + * @name Phaser.GameObjects.Shape#geom + * @type {any} + * @readonly + * @since 3.13.0 + */ + this.geom = data; - // @if DEBUG - metrics.narrowphaseTests += 1; - if (collision.reused) - metrics.narrowReuseCount += 1; - // @endif + /** + * Holds the polygon path data for filled rendering. + * + * @name Phaser.GameObjects.Shape#pathData + * @type {number[]} + * @readonly + * @since 3.13.0 + */ + this.pathData = []; - if (collision.collided) { - collisions.push(collision); - // @if DEBUG - metrics.narrowDetections += 1; - // @endif - } - } - } - } - } - } + /** + * Holds the earcut polygon path index data for filled rendering. + * + * @name Phaser.GameObjects.Shape#pathIndexes + * @type {number[]} + * @readonly + * @since 3.13.0 + */ + this.pathIndexes = []; - return collisions; - }; + /** + * The fill color used by this Shape. + * + * @name Phaser.GameObjects.Shape#fillColor + * @type {number} + * @since 3.13.0 + */ + this.fillColor = 0xffffff; - /** - * Returns `true` if both supplied collision filters will allow a collision to occur. - * See `body.collisionFilter` for more information. - * @method canCollide - * @param {} filterA - * @param {} filterB - * @return {bool} `true` if collision can occur - */ - Detector.canCollide = function(filterA, filterB) { - if (filterA.group === filterB.group && filterA.group !== 0) - return filterA.group > 0; + /** + * The fill alpha value used by this Shape. + * + * @name Phaser.GameObjects.Shape#fillAlpha + * @type {number} + * @since 3.13.0 + */ + this.fillAlpha = 1; - return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0; - }; + /** + * The stroke color used by this Shape. + * + * @name Phaser.GameObjects.Shape#strokeColor + * @type {number} + * @since 3.13.0 + */ + this.strokeColor = 0xffffff; -})(); + /** + * The stroke alpha value used by this Shape. + * + * @name Phaser.GameObjects.Shape#strokeAlpha + * @type {number} + * @since 3.13.0 + */ + this.strokeAlpha = 1; + /** + * The stroke line width used by this Shape. + * + * @name Phaser.GameObjects.Shape#lineWidth + * @type {number} + * @since 3.13.0 + */ + this.lineWidth = 1; -/***/ }), -/* 274 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Controls if this Shape is filled or not. + * Note that some Shapes do not support being filled (such as Line shapes) + * + * @name Phaser.GameObjects.Shape#isFilled + * @type {boolean} + * @since 3.13.0 + */ + this.isFilled = false; -/** -* The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem. -* -* @class SAT -*/ + /** + * Controls if this Shape is stroked or not. + * Note that some Shapes do not support being stroked (such as Iso Box shapes) + * + * @name Phaser.GameObjects.Shape#isStroked + * @type {boolean} + * @since 3.13.0 + */ + this.isStroked = false; -// TODO: true circles and curves + /** + * Controls if this Shape path is closed during rendering when stroked. + * Note that some Shapes are always closed when stroked (such as Ellipse shapes) + * + * @name Phaser.GameObjects.Shape#closePath + * @type {boolean} + * @since 3.13.0 + */ + this.closePath = true; -var SAT = {}; + /** + * Private internal value. + * A Line used when parsing internal path data to avoid constant object re-creation. + * + * @name Phaser.GameObjects.Shape#_tempLine + * @type {Phaser.Geom.Line} + * @private + * @since 3.13.0 + */ + this._tempLine = new Line(); -module.exports = SAT; + /** + * The native (un-scaled) width of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. + * + * @name Phaser.GameObjects.Shape#width + * @type {number} + * @since 3.13.0 + */ + this.width = 0; -var Vertices = __webpack_require__(64); -var Vector = __webpack_require__(83); + /** + * The native (un-scaled) height of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. + * + * @name Phaser.GameObjects.Shape#height + * @type {number} + * @since 3.0.0 + */ + this.height = 0; -(function() { + this.initPipeline(); + this.initPostPipeline(); + }, /** - * Detect collision between two bodies using the Separating Axis Theorem. - * @method collides - * @param {body} bodyA - * @param {body} bodyB - * @param {collision} previousCollision - * @return {collision} collision + * Sets the fill color and alpha for this Shape. + * + * If you wish for the Shape to not be filled then call this method with no arguments, or just set `isFilled` to `false`. + * + * Note that some Shapes do not support fill colors, such as the Line shape. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Shape#setFillStyle + * @since 3.13.0 + * + * @param {number} [color] - The color used to fill this shape. If not provided the Shape will not be filled. + * @param {number} [alpha=1] - The alpha value used when filling this shape, if a fill color is given. + * + * @return {this} This Game Object instance. */ - SAT.collides = function(bodyA, bodyB, previousCollision) { - var overlapAB, - overlapBA, - minOverlap, - collision, - canReusePrevCol = false; - - if (previousCollision) { - // estimate total motion - var parentA = bodyA.parent, - parentB = bodyB.parent, - motion = parentA.speed * parentA.speed + parentA.angularSpeed * parentA.angularSpeed - + parentB.speed * parentB.speed + parentB.angularSpeed * parentB.angularSpeed; - - // we may be able to (partially) reuse collision result - // but only safe if collision was resting - canReusePrevCol = previousCollision && previousCollision.collided && motion < 0.2; + setFillStyle: function (color, alpha) + { + if (alpha === undefined) { alpha = 1; } - // reuse collision object - collision = previousCollision; - } else { - collision = { collided: false, bodyA: bodyA, bodyB: bodyB }; + if (color === undefined) + { + this.isFilled = false; + } + else + { + this.fillColor = color; + this.fillAlpha = alpha; + this.isFilled = true; } - if (previousCollision && canReusePrevCol) { - // if we can reuse the collision result - // we only need to test the previously found axis - var axisBodyA = collision.axisBody, - axisBodyB = axisBodyA === bodyA ? bodyB : bodyA, - axes = [axisBodyA.axes[previousCollision.axisNumber]]; - - minOverlap = SAT._overlapAxes(axisBodyA.vertices, axisBodyB.vertices, axes); - collision.reused = true; - - if (minOverlap.overlap <= 0) { - collision.collided = false; - return collision; - } - } else { - // if we can't reuse a result, perform a full SAT test - - overlapAB = SAT._overlapAxes(bodyA.vertices, bodyB.vertices, bodyA.axes); - - if (overlapAB.overlap <= 0) { - collision.collided = false; - return collision; - } - - overlapBA = SAT._overlapAxes(bodyB.vertices, bodyA.vertices, bodyB.axes); - - if (overlapBA.overlap <= 0) { - collision.collided = false; - return collision; - } + return this; + }, - if (overlapAB.overlap < overlapBA.overlap) { - minOverlap = overlapAB; - collision.axisBody = bodyA; - } else { - minOverlap = overlapBA; - collision.axisBody = bodyB; - } + /** + * Sets the stroke color and alpha for this Shape. + * + * If you wish for the Shape to not be stroked then call this method with no arguments, or just set `isStroked` to `false`. + * + * Note that some Shapes do not support being stroked, such as the Iso Box shape. + * + * This call can be chained. + * + * @method Phaser.GameObjects.Shape#setStrokeStyle + * @since 3.13.0 + * + * @param {number} [lineWidth] - The width of line to stroke with. If not provided or undefined the Shape will not be stroked. + * @param {number} [color] - The color used to stroke this shape. If not provided the Shape will not be stroked. + * @param {number} [alpha=1] - The alpha value used when stroking this shape, if a stroke color is given. + * + * @return {this} This Game Object instance. + */ + setStrokeStyle: function (lineWidth, color, alpha) + { + if (alpha === undefined) { alpha = 1; } - // important for reuse later - collision.axisNumber = minOverlap.axisNumber; + if (lineWidth === undefined) + { + this.isStroked = false; } - - collision.bodyA = bodyA.id < bodyB.id ? bodyA : bodyB; - collision.bodyB = bodyA.id < bodyB.id ? bodyB : bodyA; - collision.collided = true; - collision.depth = minOverlap.overlap; - collision.parentA = collision.bodyA.parent; - collision.parentB = collision.bodyB.parent; - - bodyA = collision.bodyA; - bodyB = collision.bodyB; - - // ensure normal is facing away from bodyA - if (Vector.dot(minOverlap.axis, Vector.sub(bodyB.position, bodyA.position)) < 0) { - collision.normal = { - x: minOverlap.axis.x, - y: minOverlap.axis.y - }; - } else { - collision.normal = { - x: -minOverlap.axis.x, - y: -minOverlap.axis.y - }; + else + { + this.lineWidth = lineWidth; + this.strokeColor = color; + this.strokeAlpha = alpha; + this.isStroked = true; } - collision.tangent = Vector.perp(collision.normal); - - collision.penetration = collision.penetration || {}; - collision.penetration.x = collision.normal.x * collision.depth; - collision.penetration.y = collision.normal.y * collision.depth; - - // find support points, there is always either exactly one or two - var verticesB = SAT._findSupports(bodyA, bodyB, collision.normal), - supports = []; - - // find the supports from bodyB that are inside bodyA - if (Vertices.contains(bodyA.vertices, verticesB[0])) - supports.push(verticesB[0]); - - if (Vertices.contains(bodyA.vertices, verticesB[1])) - supports.push(verticesB[1]); - - // find the supports from bodyA that are inside bodyB - if (supports.length < 2) { - var verticesA = SAT._findSupports(bodyB, bodyA, Vector.neg(collision.normal)); - - if (Vertices.contains(bodyB.vertices, verticesA[0])) - supports.push(verticesA[0]); - - if (supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1])) - supports.push(verticesA[1]); - } + return this; + }, - // account for the edge case of overlapping but no vertex containment - if (supports.length < 1) - supports = [verticesB[0]]; - - collision.supports = supports; + /** + * Sets if this Shape path is closed during rendering when stroked. + * Note that some Shapes are always closed when stroked (such as Ellipse shapes) + * + * This call can be chained. + * + * @method Phaser.GameObjects.Shape#setClosePath + * @since 3.13.0 + * + * @param {boolean} value - Set to `true` if the Shape should be closed when stroked, otherwise `false`. + * + * @return {this} This Game Object instance. + */ + setClosePath: function (value) + { + this.closePath = value; - return collision; - }; + return this; + }, /** - * Find the overlap between two sets of vertices. - * @method _overlapAxes + * 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.Shape#setSize * @private - * @param {} verticesA - * @param {} verticesB - * @param {} axes - * @return result - */ - SAT._overlapAxes = function(verticesA, verticesB, axes) { - var projectionA = Vector._temp[0], - projectionB = Vector._temp[1], - result = { overlap: Number.MAX_VALUE }, - overlap, - axis; - - for (var i = 0; i < axes.length; i++) { - axis = axes[i]; - - SAT._projectToAxis(projectionA, verticesA, axis); - SAT._projectToAxis(projectionB, verticesB, axis); + * @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; - overlap = Math.min(projectionA.max - projectionB.min, projectionB.max - projectionA.min); + return this; + }, - if (overlap <= 0) { - result.overlap = overlap; - return result; - } + /** + * Sets the display size of this Shape. + * + * Calling this will adjust the scale. + * + * @method Phaser.GameObjects.Shape#setDisplaySize + * @since 3.53.0 + * + * @param {number} width - The display width of this Shape. + * @param {number} height - The display height of this Shape. + * + * @return {this} This Shape instance. + */ + setDisplaySize: function (width, height) + { + this.displayWidth = width; + this.displayHeight = height; - if (overlap < result.overlap) { - result.overlap = overlap; - result.axis = axis; - result.axisNumber = i; - } - } + return this; + }, - return result; - }; + /** + * Internal destroy handler, called as part of the destroy process. + * + * @method Phaser.GameObjects.Shape#preDestroy + * @protected + * @since 3.13.0 + */ + preDestroy: function () + { + this.geom = null; + this._tempLine = null; + this.pathData = []; + this.pathIndexes = []; + }, /** - * Projects vertices on an axis and returns an interval. - * @method _projectToAxis - * @private - * @param {} projection - * @param {} vertices - * @param {} axis + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + * + * @name Phaser.GameObjects.Shape#displayWidth + * @type {number} + * @since 3.13.0 */ - SAT._projectToAxis = function(projection, vertices, axis) { - var min = Vector.dot(vertices[0], axis), - max = min; + displayWidth: { - for (var i = 1; i < vertices.length; i += 1) { - var dot = Vector.dot(vertices[i], axis); + get: function () + { + return this.scaleX * this.width; + }, - if (dot > max) { - max = dot; - } else if (dot < min) { - min = dot; - } + set: function (value) + { + this.scaleX = value / this.width; } - projection.min = min; - projection.max = max; - }; - + }, + /** - * Finds supporting vertices given two bodies along a given direction using hill-climbing. - * @method _findSupports - * @private - * @param {} bodyA - * @param {} bodyB - * @param {} normal - * @return [vector] + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + * + * @name Phaser.GameObjects.Shape#displayHeight + * @type {number} + * @since 3.13.0 */ - SAT._findSupports = function(bodyA, bodyB, normal) { - var nearestDistance = Number.MAX_VALUE, - vertexToBody = Vector._temp[0], - vertices = bodyB.vertices, - bodyAPosition = bodyA.position, - distance, - vertex, - vertexA, - vertexB; + displayHeight: { - // find closest vertex on bodyB - for (var i = 0; i < vertices.length; i++) { - vertex = vertices[i]; - vertexToBody.x = vertex.x - bodyAPosition.x; - vertexToBody.y = vertex.y - bodyAPosition.y; - distance = -Vector.dot(normal, vertexToBody); + get: function () + { + return this.scaleY * this.height; + }, - if (distance < nearestDistance) { - nearestDistance = distance; - vertexA = vertex; - } + set: function (value) + { + this.scaleY = value / this.height; } - // find next closest vertex using the two connected to it - var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1; - vertex = vertices[prevIndex]; - vertexToBody.x = vertex.x - bodyAPosition.x; - vertexToBody.y = vertex.y - bodyAPosition.y; - nearestDistance = -Vector.dot(normal, vertexToBody); - vertexB = vertex; - - var nextIndex = (vertexA.index + 1) % vertices.length; - vertex = vertices[nextIndex]; - vertexToBody.x = vertex.x - bodyAPosition.x; - vertexToBody.y = vertex.y - bodyAPosition.y; - distance = -Vector.dot(normal, vertexToBody); - if (distance < nearestDistance) { - vertexB = vertex; - } + } - return [vertexA, vertexB]; - }; +}); -})(); +module.exports = Shape; /***/ }), -/* 275 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 50262: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Utils = __webpack_require__(75512); + /** - * @namespace Phaser.Actions + * Renders a stroke outline around the given Shape. + * + * @method Phaser.GameObjects.Shape#StrokePathWebGL + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The WebGL Pipeline used to render this Shape. + * @param {Phaser.GameObjects.Shape} src - The Game Object shape being rendered in this call. + * @param {number} alpha - The base alpha value. + * @param {number} dx - The source displayOriginX. + * @param {number} dy - The source displayOriginY. */ +var StrokePathWebGL = function (pipeline, src, alpha, dx, dy) +{ + var strokeTint = pipeline.strokeTint; + var strokeTintColor = Utils.getTintAppendFloatAlpha(src.strokeColor, src.strokeAlpha * alpha); -module.exports = { + strokeTint.TL = strokeTintColor; + strokeTint.TR = strokeTintColor; + strokeTint.BL = strokeTintColor; + strokeTint.BR = strokeTintColor; - AlignTo: __webpack_require__(601), - Angle: __webpack_require__(602), - Call: __webpack_require__(603), - GetFirst: __webpack_require__(604), - GetLast: __webpack_require__(605), - GridAlign: __webpack_require__(606), - IncAlpha: __webpack_require__(678), - IncX: __webpack_require__(679), - IncXY: __webpack_require__(680), - IncY: __webpack_require__(681), - PlaceOnCircle: __webpack_require__(682), - PlaceOnEllipse: __webpack_require__(683), - PlaceOnLine: __webpack_require__(684), - PlaceOnRectangle: __webpack_require__(685), - PlaceOnTriangle: __webpack_require__(686), - PlayAnimation: __webpack_require__(687), - PropertyValueInc: __webpack_require__(46), - PropertyValueSet: __webpack_require__(27), - RandomCircle: __webpack_require__(688), - RandomEllipse: __webpack_require__(689), - RandomLine: __webpack_require__(690), - RandomRectangle: __webpack_require__(691), - RandomTriangle: __webpack_require__(692), - Rotate: __webpack_require__(693), - RotateAround: __webpack_require__(694), - RotateAroundDistance: __webpack_require__(695), - ScaleX: __webpack_require__(696), - ScaleXY: __webpack_require__(697), - ScaleY: __webpack_require__(698), - SetAlpha: __webpack_require__(699), - SetBlendMode: __webpack_require__(700), - SetDepth: __webpack_require__(701), - SetHitArea: __webpack_require__(702), - SetOrigin: __webpack_require__(703), - SetRotation: __webpack_require__(704), - SetScale: __webpack_require__(705), - SetScaleX: __webpack_require__(706), - SetScaleY: __webpack_require__(707), - SetScrollFactor: __webpack_require__(708), - SetScrollFactorX: __webpack_require__(709), - SetScrollFactorY: __webpack_require__(710), - SetTint: __webpack_require__(711), - SetVisible: __webpack_require__(712), - SetX: __webpack_require__(713), - SetXY: __webpack_require__(714), - SetY: __webpack_require__(715), - ShiftPosition: __webpack_require__(716), - Shuffle: __webpack_require__(717), - SmootherStep: __webpack_require__(718), - SmoothStep: __webpack_require__(719), - Spread: __webpack_require__(720), - ToggleVisible: __webpack_require__(721), - WrapInRectangle: __webpack_require__(722) - -}; - - -/***/ }), -/* 276 */ -/***/ (function(module, exports, __webpack_require__) { + var path = src.pathData; + var pathLength = path.length - 1; + var lineWidth = src.lineWidth; + var halfLineWidth = lineWidth / 2; -/** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var px1 = path[0] - dx; + var py1 = path[1] - dy; -var ALIGN_CONST = __webpack_require__(123); + if (!src.closePath) + { + pathLength -= 2; + } -var AlignToMap = []; + for (var i = 2; i < pathLength; i += 2) + { + var px2 = path[i] - dx; + var py2 = path[i + 1] - dy; -AlignToMap[ALIGN_CONST.BOTTOM_CENTER] = __webpack_require__(277); -AlignToMap[ALIGN_CONST.BOTTOM_LEFT] = __webpack_require__(278); -AlignToMap[ALIGN_CONST.BOTTOM_RIGHT] = __webpack_require__(279); -AlignToMap[ALIGN_CONST.LEFT_BOTTOM] = __webpack_require__(280); -AlignToMap[ALIGN_CONST.LEFT_CENTER] = __webpack_require__(281); -AlignToMap[ALIGN_CONST.LEFT_TOP] = __webpack_require__(282); -AlignToMap[ALIGN_CONST.RIGHT_BOTTOM] = __webpack_require__(283); -AlignToMap[ALIGN_CONST.RIGHT_CENTER] = __webpack_require__(284); -AlignToMap[ALIGN_CONST.RIGHT_TOP] = __webpack_require__(285); -AlignToMap[ALIGN_CONST.TOP_CENTER] = __webpack_require__(286); -AlignToMap[ALIGN_CONST.TOP_LEFT] = __webpack_require__(287); -AlignToMap[ALIGN_CONST.TOP_RIGHT] = __webpack_require__(288); + pipeline.batchLine( + px1, + py1, + px2, + py2, + halfLineWidth, + halfLineWidth, + lineWidth, + i - 2, + (src.closePath) ? (i === pathLength - 1) : false + ); -/** - * Takes a Game Object and aligns it next to another, at the given position. - * The alignment used is based on the `position` argument, which is a `Phaser.Display.Align` property such as `LEFT_CENTER` or `TOP_RIGHT`. - * - * @function Phaser.Display.Align.To.QuickSet - * @since 3.22.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [child,$return] - * - * @param {Phaser.GameObjects.GameObject} child - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} position - The position to align the Game Object with. This is an align constant, such as `Phaser.Display.Align.LEFT_CENTER`. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var QuickSet = function (child, alignTo, position, offsetX, offsetY) -{ - return AlignToMap[position](child, alignTo, offsetX, offsetY); + px1 = px2; + py1 = py2; + } }; -module.exports = QuickSet; +module.exports = StrokePathWebGL; /***/ }), -/* 277 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 28593: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetBottom = __webpack_require__(42); -var GetCenterX = __webpack_require__(87); -var SetCenterX = __webpack_require__(88); -var SetTop = __webpack_require__(52); +var ArcRender = __webpack_require__(2213); +var Class = __webpack_require__(56694); +var DegToRad = __webpack_require__(75606); +var Earcut = __webpack_require__(11117); +var GeomCircle = __webpack_require__(26673); +var MATH_CONST = __webpack_require__(83392); +var Shape = __webpack_require__(91461); /** - * Takes given Game Object and aligns it so that it is positioned next to the bottom center position of the other. + * @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. * - * @function Phaser.Display.Align.To.BottomCenter - * @since 3.0.0 + * This shape supports both fill and stroke colors. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * 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. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. + * 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. * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var BottomCenter = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } - - SetCenterX(gameObject, GetCenterX(alignTo) + offsetX); - SetTop(gameObject, GetBottom(alignTo) + offsetY); + * @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({ - return gameObject; -}; + Extends: Shape, -module.exports = BottomCenter; + Mixins: [ + ArcRender + ], + initialize: -/***/ }), -/* 278 */ -/***/ (function(module, exports, __webpack_require__) { + 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; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + Shape.call(this, scene, 'Arc', new GeomCircle(0, 0, radius)); -var GetBottom = __webpack_require__(42); -var GetLeft = __webpack_require__(43); -var SetLeft = __webpack_require__(53); -var SetTop = __webpack_require__(52); + /** + * Private internal value. Holds the start angle in degrees. + * + * @name Phaser.GameObjects.Arc#_startAngle + * @type {number} + * @private + * @since 3.13.0 + */ + this._startAngle = startAngle; -/** - * Takes given Game Object and aligns it so that it is positioned next to the bottom left position of the other. - * - * @function Phaser.Display.Align.To.BottomLeft - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var BottomLeft = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + /** + * Private internal value. Holds the end angle in degrees. + * + * @name Phaser.GameObjects.Arc#_endAngle + * @type {number} + * @private + * @since 3.13.0 + */ + this._endAngle = endAngle; - SetLeft(gameObject, GetLeft(alignTo) - offsetX); - SetTop(gameObject, GetBottom(alignTo) + offsetY); + /** + * 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; - return gameObject; -}; + /** + * 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; -module.exports = BottomLeft; + this.setPosition(x, y); + var diameter = this.geom.radius * 2; + this.setSize(diameter, diameter); -/***/ }), -/* 279 */ -/***/ (function(module, exports, __webpack_require__) { + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.updateDisplayOrigin(); + this.updateData(); + }, -var GetBottom = __webpack_require__(42); -var GetRight = __webpack_require__(44); -var SetRight = __webpack_require__(54); -var SetTop = __webpack_require__(52); + /** + * 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: { -/** - * Takes given Game Object and aligns it so that it is positioned next to the bottom right position of the other. - * - * @function Phaser.Display.Align.To.BottomRight - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var BottomRight = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + get: function () + { + return this._iterations; + }, - SetRight(gameObject, GetRight(alignTo) + offsetX); - SetTop(gameObject, GetBottom(alignTo) + offsetY); + set: function (value) + { + this._iterations = value; - return gameObject; -}; + this.updateData(); + } -module.exports = BottomRight; + }, + /** + * The radius of the arc. + * + * @name Phaser.GameObjects.Arc#radius + * @type {number} + * @since 3.13.0 + */ + radius: { -/***/ }), -/* 280 */ -/***/ (function(module, exports, __webpack_require__) { + get: function () + { + return this.geom.radius; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + set: function (value) + { + this.geom.radius = value; -var GetBottom = __webpack_require__(42); -var GetLeft = __webpack_require__(43); -var SetBottom = __webpack_require__(55); -var SetRight = __webpack_require__(54); + var diameter = value * 2; + this.setSize(diameter, diameter); + this.updateDisplayOrigin(); + this.updateData(); + } -/** - * Takes given Game Object and aligns it so that it is positioned next to the left bottom position of the other. - * - * @function Phaser.Display.Align.To.LeftBottom - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var LeftBottom = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + }, - SetRight(gameObject, GetLeft(alignTo) - offsetX); - SetBottom(gameObject, GetBottom(alignTo) + offsetY); + /** + * The start angle of the arc, in degrees. + * + * @name Phaser.GameObjects.Arc#startAngle + * @type {number} + * @since 3.13.0 + */ + startAngle: { - return gameObject; -}; + get: function () + { + return this._startAngle; + }, -module.exports = LeftBottom; + set: function (value) + { + this._startAngle = value; + this.updateData(); + } -/***/ }), -/* 281 */ -/***/ (function(module, exports, __webpack_require__) { + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The end angle of the arc, in degrees. + * + * @name Phaser.GameObjects.Arc#endAngle + * @type {number} + * @since 3.13.0 + */ + endAngle: { -var GetCenterY = __webpack_require__(89); -var GetLeft = __webpack_require__(43); -var SetCenterY = __webpack_require__(90); -var SetRight = __webpack_require__(54); + get: function () + { + return this._endAngle; + }, -/** - * Takes given Game Object and aligns it so that it is positioned next to the left center position of the other. - * - * @function Phaser.Display.Align.To.LeftCenter - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var LeftCenter = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + set: function (value) + { + this._endAngle = value; - SetRight(gameObject, GetLeft(alignTo) - offsetX); - SetCenterY(gameObject, GetCenterY(alignTo) + offsetY); + this.updateData(); + } - return gameObject; -}; + }, -module.exports = LeftCenter; + /** + * 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; + }, -/***/ }), -/* 282 */ -/***/ (function(module, exports, __webpack_require__) { + set: function (value) + { + this._anticlockwise = value; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.updateData(); + } -var GetLeft = __webpack_require__(43); -var GetTop = __webpack_require__(45); -var SetRight = __webpack_require__(54); -var SetTop = __webpack_require__(52); + }, -/** - * Takes given Game Object and aligns it so that it is positioned next to the left top position of the other. - * - * @function Phaser.Display.Align.To.LeftTop - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var LeftTop = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + /** + * 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; - SetRight(gameObject, GetLeft(alignTo) - offsetX); - SetTop(gameObject, GetTop(alignTo) - offsetY); + return this; + }, - return gameObject; -}; + /** + * 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; } -module.exports = LeftTop; + this.iterations = value; + return this; + }, -/***/ }), -/* 283 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (anticlockwise !== undefined) + { + this._anticlockwise = anticlockwise; + } -var GetBottom = __webpack_require__(42); -var GetRight = __webpack_require__(44); -var SetBottom = __webpack_require__(55); -var SetLeft = __webpack_require__(53); + return this.updateData(); + }, -/** - * Takes given Game Object and aligns it so that it is positioned next to the right bottom position of the other. - * - * @function Phaser.Display.Align.To.RightBottom - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var RightBottom = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + /** + * 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; - SetLeft(gameObject, GetRight(alignTo) + offsetX); - SetBottom(gameObject, GetBottom(alignTo) + offsetY); + if (anticlockwise !== undefined) + { + this._anticlockwise = anticlockwise; + } - return gameObject; -}; + return this.updateData(); + }, -module.exports = RightBottom; + /** + * 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; -/***/ }), -/* 284 */ -/***/ (function(module, exports, __webpack_require__) { + var x = radius; + var y = radius; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + endAngle -= startAngle; -var GetCenterY = __webpack_require__(89); -var GetRight = __webpack_require__(44); -var SetCenterY = __webpack_require__(90); -var SetLeft = __webpack_require__(53); + 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; + } -/** - * Takes given Game Object and aligns it so that it is positioned next to the right center position of the other. - * - * @function Phaser.Display.Align.To.RightCenter - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var RightCenter = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + var path = [ x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius ]; - SetLeft(gameObject, GetRight(alignTo) + offsetX); - SetCenterY(gameObject, GetCenterY(alignTo) + offsetY); + var ta; - return gameObject; -}; + while (iteration < 1) + { + ta = endAngle * iteration + startAngle; -module.exports = RightCenter; + path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); + iteration += step; + } -/***/ }), -/* 285 */ -/***/ (function(module, exports, __webpack_require__) { + ta = endAngle + startAngle; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); -var GetRight = __webpack_require__(44); -var GetTop = __webpack_require__(45); -var SetLeft = __webpack_require__(53); -var SetTop = __webpack_require__(52); + path.push(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius); -/** - * Takes given Game Object and aligns it so that it is positioned next to the right top position of the other. - * - * @function Phaser.Display.Align.To.RightTop - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var RightTop = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + this.pathIndexes = Earcut(path); + this.pathData = path; - SetLeft(gameObject, GetRight(alignTo) + offsetX); - SetTop(gameObject, GetTop(alignTo) - offsetY); + return this; + } - return gameObject; -}; +}); -module.exports = RightTop; +module.exports = Arc; /***/ }), -/* 286 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 23560: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCenterX = __webpack_require__(87); -var GetTop = __webpack_require__(45); -var SetBottom = __webpack_require__(55); -var SetCenterX = __webpack_require__(88); +var DegToRad = __webpack_require__(75606); +var FillStyleCanvas = __webpack_require__(15608); +var LineStyleCanvas = __webpack_require__(17876); +var SetTransform = __webpack_require__(49584); /** - * Takes given Game Object and aligns it so that it is positioned next to the top center position of the other. - * - * @function Phaser.Display.Align.To.TopCenter - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * 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. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. + * @method Phaser.GameObjects.Arc#renderCanvas + * @since 3.13.0 + * @private * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Arc} 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 TopCenter = function (gameObject, alignTo, offsetX, offsetY) +var ArcCanvasRenderer = function (renderer, src, camera, parentMatrix) { - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + camera.addToRenderList(src); - SetCenterX(gameObject, GetCenterX(alignTo) + offsetX); - SetBottom(gameObject, GetTop(alignTo) - offsetY); + var ctx = renderer.currentContext; - return gameObject; -}; + if (SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + var radius = src.radius; -module.exports = TopCenter; + ctx.beginPath(); + ctx.arc( + (radius) - src.originX * (radius * 2), + (radius) - src.originY * (radius * 2), + radius, + DegToRad(src._startAngle), + DegToRad(src._endAngle), + src.anticlockwise + ); -/***/ }), -/* 287 */ -/***/ (function(module, exports, __webpack_require__) { + if (src.closePath) + { + ctx.closePath(); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (src.isFilled) + { + FillStyleCanvas(ctx, src); -var GetLeft = __webpack_require__(43); -var GetTop = __webpack_require__(45); -var SetBottom = __webpack_require__(55); -var SetLeft = __webpack_require__(53); + ctx.fill(); + } -/** - * Takes given Game Object and aligns it so that it is positioned next to the top left position of the other. - * - * @function Phaser.Display.Align.To.TopLeft - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var TopLeft = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + if (src.isStroked) + { + LineStyleCanvas(ctx, src); - SetLeft(gameObject, GetLeft(alignTo) - offsetX); - SetBottom(gameObject, GetTop(alignTo) - offsetY); + ctx.stroke(); + } - return gameObject; + // Restore the context saved in SetTransform + ctx.restore(); + } }; -module.exports = TopLeft; +module.exports = ArcCanvasRenderer; /***/ }), -/* 288 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 10369: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetRight = __webpack_require__(44); -var GetTop = __webpack_require__(45); -var SetBottom = __webpack_require__(55); -var SetRight = __webpack_require__(54); +var Arc = __webpack_require__(28593); +var GameObjectFactory = __webpack_require__(61286); /** - * Takes given Game Object and aligns it so that it is positioned next to the top right position of the other. - * - * @function Phaser.Display.Align.To.TopRight - * @since 3.0.0 + * Creates a new Arc Shape Game Object and adds it to the Scene. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * Note: This method will only be available if the Arc Game Object has been built into Phaser. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignTo - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. + * 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. * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var TopRight = function (gameObject, alignTo, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } - - SetRight(gameObject, GetRight(alignTo) + offsetX); - SetBottom(gameObject, GetTop(alignTo) - offsetY); - - return gameObject; -}; - -module.exports = TopRight; - - -/***/ }), -/* 289 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ALIGN_CONST = __webpack_require__(123); - -var AlignInMap = []; - -AlignInMap[ALIGN_CONST.BOTTOM_CENTER] = __webpack_require__(290); -AlignInMap[ALIGN_CONST.BOTTOM_LEFT] = __webpack_require__(291); -AlignInMap[ALIGN_CONST.BOTTOM_RIGHT] = __webpack_require__(292); -AlignInMap[ALIGN_CONST.CENTER] = __webpack_require__(293); -AlignInMap[ALIGN_CONST.LEFT_CENTER] = __webpack_require__(295); -AlignInMap[ALIGN_CONST.RIGHT_CENTER] = __webpack_require__(296); -AlignInMap[ALIGN_CONST.TOP_CENTER] = __webpack_require__(297); -AlignInMap[ALIGN_CONST.TOP_LEFT] = __webpack_require__(298); -AlignInMap[ALIGN_CONST.TOP_RIGHT] = __webpack_require__(299); -AlignInMap[ALIGN_CONST.LEFT_BOTTOM] = AlignInMap[ALIGN_CONST.BOTTOM_LEFT]; -AlignInMap[ALIGN_CONST.LEFT_TOP] = AlignInMap[ALIGN_CONST.TOP_LEFT]; -AlignInMap[ALIGN_CONST.RIGHT_BOTTOM] = AlignInMap[ALIGN_CONST.BOTTOM_RIGHT]; -AlignInMap[ALIGN_CONST.RIGHT_TOP] = AlignInMap[ALIGN_CONST.TOP_RIGHT]; - -/** - * Takes given Game Object and aligns it so that it is positioned relative to the other. - * The alignment used is based on the `position` argument, which is an `ALIGN_CONST` value, such as `LEFT_CENTER` or `TOP_RIGHT`. + * This shape supports both fill and stroke colors. * - * @function Phaser.Display.Align.In.QuickSet - * @since 3.0.0 + * 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. * - * @generic {Phaser.GameObjects.GameObject} G - [child,$return] + * @method Phaser.GameObjects.GameObjectFactory#arc + * @since 3.13.0 * - * @param {Phaser.GameObjects.GameObject} child - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} position - The position to align the Game Object with. This is an align constant, such as `ALIGN_CONST.LEFT_CENTER`. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. + * @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. * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + * @return {Phaser.GameObjects.Arc} The Game Object that was created. */ -var QuickSet = function (child, alignIn, position, offsetX, offsetY) +GameObjectFactory.register('arc', function (x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha) { - return AlignInMap[position](child, alignIn, offsetX, offsetY); -}; - -module.exports = QuickSet; - - -/***/ }), -/* 290 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetBottom = __webpack_require__(42); -var GetCenterX = __webpack_require__(87); -var SetBottom = __webpack_require__(55); -var SetCenterX = __webpack_require__(88); + return this.displayList.add(new Arc(this.scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha)); +}); /** - * Takes given Game Object and aligns it so that it is positioned in the bottom center of the other. + * Creates a new Circle Shape Game Object and adds it to the Scene. * - * @function Phaser.Display.Align.In.BottomCenter - * @since 3.0.0 + * A Circle is an Arc with no defined start and end angle, making it render as a complete circle. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * Note: This method will only be available if the Arc Game Object has been built into Phaser. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. + * @method Phaser.GameObjects.GameObjectFactory#circle + * @since 3.13.0 * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + * @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 circle. + * @param {number} [fillColor] - The color the circle will be filled with, i.e. 0xff0000 for red. + * @param {number} [fillAlpha] - The alpha the circle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * + * @return {Phaser.GameObjects.Arc} The Game Object that was created. */ -var BottomCenter = function (gameObject, alignIn, offsetX, offsetY) +GameObjectFactory.register('circle', function (x, y, radius, fillColor, fillAlpha) { - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } - - SetCenterX(gameObject, GetCenterX(alignIn) + offsetX); - SetBottom(gameObject, GetBottom(alignIn) + offsetY); - - return gameObject; -}; - -module.exports = BottomCenter; + return this.displayList.add(new Arc(this.scene, x, y, radius, 0, 360, false, fillColor, fillAlpha)); +}); /***/ }), -/* 291 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 2213: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetBottom = __webpack_require__(42); -var GetLeft = __webpack_require__(43); -var SetBottom = __webpack_require__(55); -var SetLeft = __webpack_require__(53); +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; -/** - * Takes given Game Object and aligns it so that it is positioned in the bottom left of the other. - * - * @function Phaser.Display.Align.In.BottomLeft - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var BottomLeft = function (gameObject, alignIn, offsetX, offsetY) +if (true) { - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + renderWebGL = __webpack_require__(58356); +} - SetLeft(gameObject, GetLeft(alignIn) - offsetX); - SetBottom(gameObject, GetBottom(alignIn) + offsetY); +if (true) +{ + renderCanvas = __webpack_require__(23560); +} - return gameObject; -}; +module.exports = { -module.exports = BottomLeft; + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; /***/ }), -/* 292 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 58356: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetBottom = __webpack_require__(42); -var GetRight = __webpack_require__(44); -var SetBottom = __webpack_require__(55); -var SetRight = __webpack_require__(54); +var GetCalcMatrix = __webpack_require__(73329); +var FillPathWebGL = __webpack_require__(19543); +var StrokePathWebGL = __webpack_require__(50262); /** - * Takes given Game Object and aligns it so that it is positioned in the bottom right of the other. - * - * @function Phaser.Display.Align.In.BottomRight - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * 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. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. + * @method Phaser.GameObjects.Arc#renderWebGL + * @since 3.13.0 + * @private * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Arc} 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 BottomRight = function (gameObject, alignIn, offsetX, offsetY) +var ArcWebGLRenderer = function (renderer, src, camera, parentMatrix) { - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } - - SetRight(gameObject, GetRight(alignIn) + offsetX); - SetBottom(gameObject, GetBottom(alignIn) + offsetY); + camera.addToRenderList(src); - return gameObject; -}; + var pipeline = renderer.pipelines.set(src.pipeline); -module.exports = BottomRight; + var result = GetCalcMatrix(src, camera, parentMatrix); + var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); -/***/ }), -/* 293 */ -/***/ (function(module, exports, __webpack_require__) { + var dx = src._displayOriginX; + var dy = src._displayOriginY; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var alpha = camera.alpha * src.alpha; -var CenterOn = __webpack_require__(294); -var GetCenterX = __webpack_require__(87); -var GetCenterY = __webpack_require__(89); + renderer.pipelines.preBatch(src); -/** - * Takes given Game Object and aligns it so that it is positioned in the center of the other. - * - * @function Phaser.Display.Align.In.Center - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var Center = function (gameObject, alignIn, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + if (src.isFilled) + { + FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); + } - CenterOn(gameObject, GetCenterX(alignIn) + offsetX, GetCenterY(alignIn) + offsetY); + if (src.isStroked) + { + StrokePathWebGL(pipeline, src, alpha, dx, dy); + } - return gameObject; + renderer.pipelines.postBatch(src); }; -module.exports = Center; +module.exports = ArcWebGLRenderer; /***/ }), -/* 294 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 15220: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetCenterX = __webpack_require__(88); -var SetCenterY = __webpack_require__(90); +var Class = __webpack_require__(56694); +var CurveRender = __webpack_require__(87203); +var Earcut = __webpack_require__(11117); +var Rectangle = __webpack_require__(74118); +var Shape = __webpack_require__(91461); /** - * Positions the Game Object so that it is centered on the given coordinates. + * @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. * - * @function Phaser.Display.Bounds.CenterOn - * @since 3.0.0 + * This shape supports both fill and stroke colors. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * To render a Curve Shape you must first create a `Phaser.Curves.Curve` object, then pass it to + * the Curve Shape in the constructor. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be re-positioned. - * @param {number} x - The horizontal coordinate to position the Game Object on. - * @param {number} y - The vertical coordinate to position the Game Object on. + * 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. * - * @return {Phaser.GameObjects.GameObject} The Game Object that was positioned. + * @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 CenterOn = function (gameObject, x, y) -{ - SetCenterX(gameObject, x); +var Curve = new Class({ - return SetCenterY(gameObject, y); -}; + Extends: Shape, -module.exports = CenterOn; + Mixins: [ + CurveRender + ], + initialize: -/***/ }), -/* 295 */ -/***/ (function(module, exports, __webpack_require__) { + function Curve (scene, x, y, curve, fillColor, fillAlpha) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + Shape.call(this, scene, 'Curve', curve); -var GetCenterY = __webpack_require__(89); -var GetLeft = __webpack_require__(43); -var SetCenterY = __webpack_require__(90); -var SetLeft = __webpack_require__(53); + /** + * 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; -/** - * Takes given Game Object and aligns it so that it is positioned in the left center of the other. - * - * @function Phaser.Display.Align.In.LeftCenter - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var LeftCenter = function (gameObject, alignIn, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + /** + * 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(); - SetLeft(gameObject, GetLeft(alignIn) - offsetX); - SetCenterY(gameObject, GetCenterY(alignIn) + offsetY); + this.closePath = false; - return gameObject; -}; + this.setPosition(x, y); -module.exports = LeftCenter; + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + this.updateData(); + }, -/***/ }), -/* 296 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this._smoothness; + }, -var GetCenterY = __webpack_require__(89); -var GetRight = __webpack_require__(44); -var SetCenterY = __webpack_require__(90); -var SetRight = __webpack_require__(54); + set: function (value) + { + this._smoothness = value; -/** - * Takes given Game Object and aligns it so that it is positioned in the right center of the other. - * - * @function Phaser.Display.Align.In.RightCenter - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var RightCenter = function (gameObject, alignIn, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + this.updateData(); + } - SetRight(gameObject, GetRight(alignIn) + offsetX); - SetCenterY(gameObject, GetCenterY(alignIn) + offsetY); + }, - return gameObject; -}; + /** + * 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; -module.exports = RightCenter; + 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; -/***/ }), -/* 297 */ -/***/ (function(module, exports, __webpack_require__) { + // Update the bounds in case the underlying data has changed + this.geom.getBounds(bounds, smoothness); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.setSize(bounds.width, bounds.height); + this.updateDisplayOrigin(); -var GetCenterX = __webpack_require__(87); -var GetTop = __webpack_require__(45); -var SetCenterX = __webpack_require__(88); -var SetTop = __webpack_require__(52); + var path = []; + var points = this.geom.getPoints(smoothness); -/** - * Takes given Game Object and aligns it so that it is positioned in the top center of the other. - * - * @function Phaser.Display.Align.In.TopCenter - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. - */ -var TopCenter = function (gameObject, alignIn, offsetX, offsetY) -{ - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + for (var i = 0; i < points.length; i++) + { + path.push(points[i].x, points[i].y); + } - SetCenterX(gameObject, GetCenterX(alignIn) + offsetX); - SetTop(gameObject, GetTop(alignIn) - offsetY); + path.push(points[0].x, points[0].y); - return gameObject; -}; + this.pathIndexes = Earcut(path); + this.pathData = path; -module.exports = TopCenter; + return this; + } + +}); + +module.exports = Curve; /***/ }), -/* 298 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 4024: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetLeft = __webpack_require__(43); -var GetTop = __webpack_require__(45); -var SetLeft = __webpack_require__(53); -var SetTop = __webpack_require__(52); +var FillStyleCanvas = __webpack_require__(15608); +var LineStyleCanvas = __webpack_require__(17876); +var SetTransform = __webpack_require__(49584); /** - * Takes given Game Object and aligns it so that it is positioned in the top left of the other. - * - * @function Phaser.Display.Align.In.TopLeft - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * 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. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. + * @method Phaser.GameObjects.Curve#renderCanvas + * @since 3.13.0 + * @private * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Curve} 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 TopLeft = function (gameObject, alignIn, offsetX, offsetY) +var CurveCanvasRenderer = function (renderer, src, camera, parentMatrix) { - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } + camera.addToRenderList(src); - SetLeft(gameObject, GetLeft(alignIn) - offsetX); - SetTop(gameObject, GetTop(alignIn) - offsetY); + var ctx = renderer.currentContext; - return gameObject; + if (SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + var dx = src._displayOriginX + src._curveBounds.x; + var dy = src._displayOriginY + src._curveBounds.y; + + var path = src.pathData; + var pathLength = path.length - 1; + + var px1 = path[0] - dx; + var py1 = path[1] - dy; + + ctx.beginPath(); + + ctx.moveTo(px1, py1); + + if (!src.closePath) + { + pathLength -= 2; + } + + for (var i = 2; i < pathLength; i += 2) + { + var px2 = path[i] - dx; + var py2 = path[i + 1] - dy; + + ctx.lineTo(px2, py2); + } + + if (src.closePath) + { + ctx.closePath(); + } + + if (src.isFilled) + { + FillStyleCanvas(ctx, src); + + ctx.fill(); + } + + if (src.isStroked) + { + LineStyleCanvas(ctx, src); + + ctx.stroke(); + } + + // Restore the context saved in SetTransform + ctx.restore(); + } }; -module.exports = TopLeft; +module.exports = CurveCanvasRenderer; /***/ }), -/* 299 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 10147: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetRight = __webpack_require__(44); -var GetTop = __webpack_require__(45); -var SetRight = __webpack_require__(54); -var SetTop = __webpack_require__(52); +var GameObjectFactory = __webpack_require__(61286); +var Curve = __webpack_require__(15220); /** - * Takes given Game Object and aligns it so that it is positioned in the top right of the other. + * Creates a new Curve Shape Game Object and adds it to the Scene. * - * @function Phaser.Display.Align.In.TopRight - * @since 3.0.0 + * Note: This method will only be available if the Curve Game Object has been built into Phaser. * - * @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return] + * 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. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will be positioned. - * @param {Phaser.GameObjects.GameObject} alignIn - The Game Object to base the alignment position on. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. + * This shape supports both fill and stroke colors. * - * @return {Phaser.GameObjects.GameObject} The Game Object that was aligned. + * 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. + * + * @method Phaser.GameObjects.GameObjectFactory#curve + * @since 3.13.0 + * + * @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. + * + * @return {Phaser.GameObjects.Curve} The Game Object that was created. */ -var TopRight = function (gameObject, alignIn, offsetX, offsetY) +GameObjectFactory.register('curve', function (x, y, curve, fillColor, fillAlpha) { - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } - - SetRight(gameObject, GetRight(alignIn) + offsetX); - SetTop(gameObject, GetTop(alignIn) - offsetY); - - return gameObject; -}; - -module.exports = TopRight; + return this.displayList.add(new Curve(this.scene, x, y, curve, fillColor, fillAlpha)); +}); /***/ }), -/* 300 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 87203: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CircumferencePoint = __webpack_require__(169); -var FromPercent = __webpack_require__(98); -var MATH_CONST = __webpack_require__(14); -var Point = __webpack_require__(4); +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; -/** - * 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. - * - * @function Phaser.Geom.Circle.GetPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Circle} circle - The Circle 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 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. - */ -var GetPoint = function (circle, position, out) +if (true) { - if (out === undefined) { out = new Point(); } + renderWebGL = __webpack_require__(82958); +} - var angle = FromPercent(position, 0, MATH_CONST.PI2); +if (true) +{ + renderCanvas = __webpack_require__(4024); +} - return CircumferencePoint(circle, angle, out); -}; +module.exports = { -module.exports = GetPoint; + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; /***/ }), -/* 301 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 82958: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circumference = __webpack_require__(302); -var CircumferencePoint = __webpack_require__(169); -var FromPercent = __webpack_require__(98); -var MATH_CONST = __webpack_require__(14); +var FillPathWebGL = __webpack_require__(19543); +var GetCalcMatrix = __webpack_require__(73329); +var StrokePathWebGL = __webpack_require__(50262); /** - * 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. - * - * @function Phaser.Geom.Circle.GetPoints - * @since 3.0.0 + * 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. * - * @param {Phaser.Geom.Circle} circle - The Circle 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 circle 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. + * @method Phaser.GameObjects.Curve#renderWebGL + * @since 3.13.0 + * @private * - * @return {Phaser.Geom.Point[]} An array of Point objects pertaining to the points around the circumference of the circle. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Curve} 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 GetPoints = function (circle, quantity, stepRate, out) +var CurveWebGLRenderer = function (renderer, src, camera, parentMatrix) { - if (out === undefined) { out = []; } + camera.addToRenderList(src); - // If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. - if (!quantity && stepRate > 0) + var pipeline = renderer.pipelines.set(src.pipeline); + + var result = GetCalcMatrix(src, camera, parentMatrix); + + var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); + + var dx = src._displayOriginX + src._curveBounds.x; + var dy = src._displayOriginY + src._curveBounds.y; + + var alpha = camera.alpha * src.alpha; + + renderer.pipelines.preBatch(src); + + if (src.isFilled) { - quantity = Circumference(circle) / stepRate; + FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); } - for (var i = 0; i < quantity; i++) + if (src.isStroked) { - var angle = FromPercent(i / quantity, 0, MATH_CONST.PI2); - - out.push(CircumferencePoint(circle, angle)); + StrokePathWebGL(pipeline, src, alpha, dx, dy); } - return out; + renderer.pipelines.postBatch(src); }; -module.exports = GetPoints; +module.exports = CurveWebGLRenderer; /***/ }), -/* 302 */ -/***/ (function(module, exports) { + +/***/ 28591: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var Earcut = __webpack_require__(11117); +var EllipseRender = __webpack_require__(84171); +var GeomEllipse = __webpack_require__(95669); +var Shape = __webpack_require__(91461); + /** - * Returns the circumference of the given Circle. + * @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. * - * @function Phaser.Geom.Circle.Circumference - * @since 3.0.0 + * This shape supports both fill and stroke colors. * - * @param {Phaser.Geom.Circle} circle - The Circle to get the circumference of. + * 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. * - * @return {number} The circumference of the Circle. + * 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 Circumference = function (circle) -{ - return 2 * (Math.PI * circle.radius); -}; +var Ellipse = new Class({ -module.exports = Circumference; + Extends: Shape, + Mixins: [ + EllipseRender + ], -/***/ }), -/* 303 */ -/***/ (function(module, exports, __webpack_require__) { + initialize: -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + 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; } -var Clamp = __webpack_require__(18); + Shape.call(this, scene, 'Ellipse', new GeomEllipse(width / 2, height / 2, width, height)); -// bitmask flag for GameObject.renderMask -var _FLAG = 2; // 0010 + /** + * 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; -/** - * Provides methods used for setting the alpha property of a Game Object. - * Should be applied as a mixin and not used directly. - * - * @namespace Phaser.GameObjects.Components.AlphaSingle - * @since 3.22.0 - */ + this.setPosition(x, y); -var AlphaSingle = { + this.width = width; + this.height = height; + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); + }, /** - * Private internal value. Holds the global alpha value. + * 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.Components.AlphaSingle#_alpha + * @name Phaser.GameObjects.Ellipse#smoothness * @type {number} - * @private - * @default 1 - * @since 3.0.0 + * @default 64 + * @since 3.13.0 */ - _alpha: 1, + smoothness: { + + get: function () + { + return this._smoothness; + }, + + set: function (value) + { + this._smoothness = value; + + this.updateData(); + } + + }, /** - * Clears all alpha values associated with this Game Object. + * Sets the size of the ellipse by changing the underlying geometry data, rather than scaling the object. + * This call can be chained. * - * Immediately sets the alpha levels back to 1 (fully opaque). + * @method Phaser.GameObjects.Ellipse#setSize + * @since 3.13.0 * - * @method Phaser.GameObjects.Components.AlphaSingle#clearAlpha - * @since 3.0.0 + * @param {number} width - The width of the ellipse. + * @param {number} height - The height of the ellipse. * * @return {this} This Game Object instance. */ - clearAlpha: function () + setSize: function (width, height) { - return this.setAlpha(1); + this.width = width; + this.height = height; + this.geom.setPosition(width / 2, height / 2); + this.geom.setSize(width, height); + + return this.updateData(); }, /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * 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.Components.AlphaSingle#setAlpha - * @since 3.0.0 + * @method Phaser.GameObjects.Ellipse#setSmoothness + * @since 3.13.0 * - * @param {number} [value=1] - The alpha value applied across the whole Game Object. + * @param {number} value - The value to set the smoothness to. * * @return {this} This Game Object instance. */ - setAlpha: function (value) + setSmoothness: function (value) { - if (value === undefined) { value = 1; } - - this.alpha = value; + this._smoothness = value; - return this; + return this.updateData(); }, /** - * The alpha value of the Game Object. + * Internal method that updates the data and path values. * - * This is a global value, impacting the entire Game Object, not just a region of it. + * @method Phaser.GameObjects.Ellipse#updateData + * @private + * @since 3.13.0 * - * @name Phaser.GameObjects.Components.AlphaSingle#alpha - * @type {number} - * @since 3.0.0 + * @return {this} This Game Object instance. */ - alpha: { - - get: function () - { - return this._alpha; - }, + updateData: function () + { + var path = []; + var points = this.geom.getPoints(this._smoothness); - set: function (value) + for (var i = 0; i < points.length; i++) { - var v = Clamp(value, 0, 1); + path.push(points[i].x, points[i].y); + } - this._alpha = v; + path.push(points[0].x, points[0].y); - if (v === 0) - { - this.renderFlags &= ~_FLAG; - } - else - { - this.renderFlags |= _FLAG; - } - } + this.pathIndexes = Earcut(path); + this.pathData = path; + return this; } -}; +}); -module.exports = AlphaSingle; +module.exports = Ellipse; /***/ }), -/* 304 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 55881: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(35); +var FillStyleCanvas = __webpack_require__(15608); +var LineStyleCanvas = __webpack_require__(17876); +var SetTransform = __webpack_require__(49584); /** - * Provides methods used for setting the blend mode of a Game Object. - * Should be applied as a mixin and not used directly. + * 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. * - * @namespace Phaser.GameObjects.Components.BlendMode - * @since 3.0.0 + * @method Phaser.GameObjects.Ellipse#renderCanvas + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Ellipse} 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 EllipseCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); -var BlendMode = { + var ctx = renderer.currentContext; - /** - * Private internal value. Holds the current blend mode. - * - * @name Phaser.GameObjects.Components.BlendMode#_blendMode - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - _blendMode: BlendModes.NORMAL, + if (SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + var dx = src._displayOriginX; + var dy = src._displayOriginY; - /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. - * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency of which blend modes - * are used. - * - * @name Phaser.GameObjects.Components.BlendMode#blendMode - * @type {(Phaser.BlendModes|string)} - * @since 3.0.0 - */ - blendMode: { + var path = src.pathData; + var pathLength = path.length - 1; - get: function () + var px1 = path[0] - dx; + var py1 = path[1] - dy; + + ctx.beginPath(); + + ctx.moveTo(px1, py1); + + if (!src.closePath) { - return this._blendMode; - }, + pathLength -= 2; + } - set: function (value) + for (var i = 2; i < pathLength; i += 2) { - if (typeof value === 'string') - { - value = BlendModes[value]; - } + var px2 = path[i] - dx; + var py2 = path[i + 1] - dy; - value |= 0; + ctx.lineTo(px2, py2); + } - if (value >= -1) - { - this._blendMode = value; - } + ctx.closePath(); + + if (src.isFilled) + { + FillStyleCanvas(ctx, src); + + ctx.fill(); } - }, + if (src.isStroked) + { + LineStyleCanvas(ctx, src); - /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE (only works when rendering to a framebuffer, like a Render Texture) - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. - * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency in which blend modes - * are used. - * - * @method Phaser.GameObjects.Components.BlendMode#setBlendMode - * @since 3.0.0 - * - * @param {(string|Phaser.BlendModes)} value - The BlendMode value. Either a string or a CONST. - * - * @return {this} This Game Object instance. - */ - setBlendMode: function (value) - { - this.blendMode = value; + ctx.stroke(); + } - return this; + // Restore the context saved in SetTransform + ctx.restore(); } - }; -module.exports = BlendMode; +module.exports = EllipseCanvasRenderer; /***/ }), -/* 305 */ -/***/ (function(module, exports) { + +/***/ 99869: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Ellipse = __webpack_require__(28591); +var GameObjectFactory = __webpack_require__(61286); + /** - * Provides methods used for setting the depth of a Game Object. - * Should be applied as a mixin and not used directly. + * Creates a new Ellipse Shape Game Object and adds it to the Scene. * - * @namespace Phaser.GameObjects.Components.Depth - * @since 3.0.0 + * Note: This method will only be available if the Ellipse Game Object has been built into Phaser. + * + * 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. + * + * @method Phaser.GameObjects.GameObjectFactory#ellipse + * @since 3.13.0 + * + * @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. + * + * @return {Phaser.GameObjects.Ellipse} The Game Object that was created. */ +GameObjectFactory.register('ellipse', function (x, y, width, height, fillColor, fillAlpha) +{ + return this.displayList.add(new Ellipse(this.scene, x, y, width, height, fillColor, fillAlpha)); +}); -var Depth = { - - /** - * Private internal value. Holds the depth of the Game Object. - * - * @name Phaser.GameObjects.Components.Depth#_depth - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - _depth: 0, - /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. - * - * Setting the depth will queue a depth sort event within the Scene. - * - * @name Phaser.GameObjects.Components.Depth#depth - * @type {number} - * @since 3.0.0 - */ - depth: { +/***/ }), - get: function () - { - return this._depth; - }, +/***/ 84171: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - set: function (value) - { - if (this.displayList) - { - this.displayList.queueDepthSort(); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this._depth = value; - } +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - }, +if (true) +{ + renderWebGL = __webpack_require__(17554); +} - /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. - * - * Setting the depth will queue a depth sort event within the Scene. - * - * @method Phaser.GameObjects.Components.Depth#setDepth - * @since 3.0.0 - * - * @param {number} value - The depth of this Game Object. - * - * @return {this} This Game Object instance. - */ - setDepth: function (value) - { - if (value === undefined) { value = 0; } +if (true) +{ + renderCanvas = __webpack_require__(55881); +} - this.depth = value; +module.exports = { - return this; - } + renderWebGL: renderWebGL, + renderCanvas: renderCanvas }; -module.exports = Depth; - /***/ }), -/* 306 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 17554: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetPoint = __webpack_require__(171); -var Perimeter = __webpack_require__(130); - -// Return an array of points from the perimeter of the rectangle -// each spaced out based on the quantity or step required +var FillPathWebGL = __webpack_require__(19543); +var GetCalcMatrix = __webpack_require__(73329); +var StrokePathWebGL = __webpack_require__(50262); /** - * Return an array of points from the perimeter of the rectangle, each spaced out based on the quantity or step required. - * - * @function Phaser.Geom.Rectangle.GetPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point[]} O - [out,$return] + * 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. * - * @param {Phaser.Geom.Rectangle} rectangle - The Rectangle object to get the points from. - * @param {number} step - Step between points. Used to calculate the number of points to return when quantity is falsey. Ignored if quantity is positive. - * @param {number} quantity - The number of evenly spaced points from the rectangles perimeter to return. If falsey, step param will be used to calculate the number of points. - * @param {(array|Phaser.Geom.Point[])} [out] - An optional array to store the points in. + * @method Phaser.GameObjects.Ellipse#renderWebGL + * @since 3.13.0 + * @private * - * @return {(array|Phaser.Geom.Point[])} An array of Points from the perimeter of the rectangle. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Ellipse} 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 GetPoints = function (rectangle, quantity, stepRate, out) +var EllipseWebGLRenderer = function (renderer, src, camera, parentMatrix) { - if (out === undefined) { out = []; } + camera.addToRenderList(src); - // If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. - if (!quantity && stepRate > 0) + var pipeline = renderer.pipelines.set(src.pipeline); + + var result = GetCalcMatrix(src, camera, parentMatrix); + + var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); + + var dx = src._displayOriginX; + var dy = src._displayOriginY; + + var alpha = camera.alpha * src.alpha; + + renderer.pipelines.preBatch(src); + + if (src.isFilled) { - quantity = Perimeter(rectangle) / stepRate; + FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); } - for (var i = 0; i < quantity; i++) + if (src.isStroked) { - var position = i / quantity; - - out.push(GetPoint(rectangle, position)); + StrokePathWebGL(pipeline, src, alpha, dx, dy); } - return out; + renderer.pipelines.postBatch(src); }; -module.exports = GetPoints; +module.exports = EllipseWebGLRenderer; /***/ }), -/* 307 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 39169: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Point = __webpack_require__(4); +var Class = __webpack_require__(56694); +var Shape = __webpack_require__(91461); +var GridRender = __webpack_require__(88059); /** - * Get a point on a line that's a given percentage along its length. + * @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. * - * @function Phaser.Geom.Line.GetPoint - * @since 3.0.0 + * This shape supports only fill colors and cannot be stroked. * - * @generic {Phaser.Geom.Point} O - [out,$return] + * 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. * - * @param {Phaser.Geom.Line} line - The line. - * @param {number} position - A value between 0 and 1, where 0 is the start, 0.5 is the middle and 1 is the end of the line. - * @param {(Phaser.Geom.Point|object)} [out] - An optional point, or point-like object, to store the coordinates of the point on the line. + * @class Grid + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects + * @constructor + * @since 3.13.0 * - * @return {(Phaser.Geom.Point|object)} The point on the line. + * @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 GetPoint = function (line, position, out) -{ - if (out === undefined) { out = new Point(); } +var Grid = new Class({ - out.x = line.x1 + (line.x2 - line.x1) * position; - out.y = line.y1 + (line.y2 - line.y1) * position; + Extends: Shape, - return out; -}; + Mixins: [ + GridRender + ], -module.exports = GetPoint; + 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; } -/***/ }), -/* 308 */ -/***/ (function(module, exports) { + Shape.call(this, scene, 'Grid', null); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -/** - * Rotate a `point` around `x` and `y` to the given `angle`, at the same distance. - * - * In polar notation, this maps a point from (r, t) to (r, angle), vs. the origin (x, y). - * - * @function Phaser.Math.RotateAround - * @since 3.0.0 - * - * @generic {Phaser.Types.Math.Vector2Like} T - [point,$return] - * - * @param {(Phaser.Geom.Point|object)} point - The point to be rotated. - * @param {number} x - The horizontal coordinate to rotate around. - * @param {number} y - The vertical coordinate to rotate around. - * @param {number} angle - The angle of rotation in radians. - * - * @return {Phaser.Types.Math.Vector2Like} The given point. - */ -var RotateAround = function (point, x, y, angle) -{ - var c = Math.cos(angle); - var s = Math.sin(angle); + /** + * 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; - var tx = point.x - x; - var ty = point.y - y; + /** + * Will the grid render its cells in the `fillColor`? + * + * @name Phaser.GameObjects.Grid#showCells + * @type {boolean} + * @since 3.13.0 + */ + this.showCells = true; - point.x = tx * c - ty * s + x; - point.y = tx * s + ty * c + y; + /** + * The color of the lines between each grid cell. + * + * @name Phaser.GameObjects.Grid#outlineFillColor + * @type {number} + * @since 3.13.0 + */ + this.outlineFillColor = 0; - return point; -}; + /** + * 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; -module.exports = RotateAround; + /** + * 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; -/***/ }), -/* 309 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var BitmapMask = __webpack_require__(310); -var GeometryMask = __webpack_require__(311); + this.setPosition(x, y); + this.setSize(width, height); -/** - * Provides methods used for getting and setting the mask of a Game Object. - * - * @namespace Phaser.GameObjects.Components.Mask - * @since 3.0.0 - */ + this.setFillStyle(fillColor, fillAlpha); -var Mask = { + if (outlineFillColor !== undefined) + { + this.setOutlineStyle(outlineFillColor, outlineFillAlpha); + } - /** - * The Mask this Game Object is using during render. - * - * @name Phaser.GameObjects.Components.Mask#mask - * @type {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask} - * @since 3.0.0 - */ - mask: null, + this.updateDisplayOrigin(); + }, /** - * Sets the mask that this Game Object will use to render with. + * Sets the fill color and alpha level the grid cells will use when rendering. * - * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * If 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. * - * If a mask is already set on this Game Object it will be immediately replaced. + * Also see the `setOutlineStyle` and `setAltFillStyle` methods. * - * Masks are positioned in global space and are not relative to the Game Object to which they - * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * This call can be chained. * - * Masks have no impact on physics or input detection. They are purely a rendering component - * that allows you to limit what is visible during the render pass. + * @method Phaser.GameObjects.Grid#setFillStyle + * @since 3.13.0 * - * @method Phaser.GameObjects.Components.Mask#setMask - * @since 3.6.2 - * - * @param {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask} mask - The mask this Game Object will use when rendering. + * @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. */ - setMask: function (mask) + setFillStyle: function (fillColor, fillAlpha) { - this.mask = mask; + if (fillAlpha === undefined) { fillAlpha = 1; } + + if (fillColor === undefined) + { + this.showCells = false; + } + else + { + this.fillColor = fillColor; + this.fillAlpha = fillAlpha; + this.showCells = true; + } return this; }, /** - * Clears the mask that this Game Object was using. + * Sets the fill color and alpha level that the alternating grid cells will use. * - * @method Phaser.GameObjects.Components.Mask#clearMask - * @since 3.6.2 + * If this method is called with no values then alternating grid cells will not be rendered in a different color. * - * @param {boolean} [destroyMask=false] - Destroy the mask before clearing it? + * 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. */ - clearMask: function (destroyMask) + setAltFillStyle: function (fillColor, fillAlpha) { - if (destroyMask === undefined) { destroyMask = false; } + if (fillAlpha === undefined) { fillAlpha = 1; } - if (destroyMask && this.mask) + if (fillColor === undefined) { - this.mask.destroy(); + this.showAltCells = false; + } + else + { + this.altFillColor = fillColor; + this.altFillAlpha = fillAlpha; + this.showAltCells = true; } - - this.mask = null; return this; }, /** - * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * Sets the fill color and alpha level that the lines between each grid cell will use. * - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * 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. * - * To create the mask you need to pass in a reference to a renderable Game Object. - * A renderable Game Object is one that uses a texture to render with, such as an - * Image, Sprite, Render Texture or BitmapText. + * Also see the `setFillStyle` and `setAltFillStyle` methods. * - * If you do not provide a renderable object, and this Game Object has a texture, - * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. + * This call can be chained. * - * @method Phaser.GameObjects.Components.Mask#createBitmapMask - * @since 3.6.2 + * @method Phaser.GameObjects.Grid#setOutlineStyle + * @since 3.13.0 * - * @param {Phaser.GameObjects.GameObject} [renderable] - A renderable Game Object that uses a texture, such as a Sprite. + * @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 {Phaser.Display.Masks.BitmapMask} This Bitmap Mask that was created. + * @return {this} This Game Object instance. */ - createBitmapMask: function (renderable) + setOutlineStyle: function (fillColor, fillAlpha) { - if (renderable === undefined && (this.texture || this.shader)) + if (fillAlpha === undefined) { fillAlpha = 1; } + + if (fillColor === undefined) { - // eslint-disable-next-line consistent-this - renderable = this; + this.showOutline = false; + } + else + { + this.outlineFillColor = fillColor; + this.outlineFillAlpha = fillAlpha; + this.showOutline = true; } - return new BitmapMask(this.scene, renderable); - }, + return this; + } - /** - * Creates and returns a Geometry Mask. This mask can be used by any Game Object, - * including this one. - * - * To create the mask you need to pass in a reference to a Graphics Game Object. - * - * If you do not provide a graphics object, and this Game Object is an instance - * of a Graphics object, then it will use itself to create the mask. - * - * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * - * @method Phaser.GameObjects.Components.Mask#createGeometryMask - * @since 3.6.2 - * - * @param {Phaser.GameObjects.Graphics} [graphics] - A Graphics Game Object. The geometry within it will be used as the mask. - * - * @return {Phaser.Display.Masks.GeometryMask} This Geometry Mask that was created. - */ - createGeometryMask: function (graphics) +}); + +module.exports = Grid; + + +/***/ }), + +/***/ 95525: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var FillStyleCanvas = __webpack_require__(15608); +var LineStyleCanvas = __webpack_require__(17876); +var SetTransform = __webpack_require__(49584); + +/** + * 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.Grid#renderCanvas + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Grid} 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 GridCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); + + var ctx = renderer.currentContext; + + if (SetTransform(renderer, ctx, src, camera, parentMatrix)) { - if (graphics === undefined && this.type === 'Graphics') + var dx = -src._displayOriginX; + var dy = -src._displayOriginY; + + var alpha = camera.alpha * src.alpha; + + // Work out the grid size + + var width = src.width; + var height = src.height; + + var cellWidth = src.cellWidth; + var cellHeight = src.cellHeight; + + var gridWidth = Math.ceil(width / cellWidth); + var gridHeight = Math.ceil(height / cellHeight); + + var cellWidthA = cellWidth; + var cellHeightA = cellHeight; + + var cellWidthB = cellWidth - ((gridWidth * cellWidth) - width); + var cellHeightB = cellHeight - ((gridHeight * cellHeight) - height); + + var showCells = src.showCells; + var showAltCells = src.showAltCells; + var showOutline = src.showOutline; + + var x = 0; + var y = 0; + var r = 0; + var cw = 0; + var ch = 0; + + if (showOutline) { - // eslint-disable-next-line consistent-this - graphics = this; + // To make room for the grid lines (in case alpha < 1) + cellWidthA--; + cellHeightA--; + + if (cellWidthB === cellWidth) + { + cellWidthB--; + } + + if (cellHeightB === cellHeight) + { + cellHeightB--; + } } - return new GeometryMask(this.scene, graphics); - } + if (showCells && src.fillAlpha > 0) + { + FillStyleCanvas(ctx, src); + + for (y = 0; y < gridHeight; y++) + { + if (showAltCells) + { + r = y % 2; + } + + for (x = 0; x < gridWidth; x++) + { + if (showAltCells && r) + { + r = 0; + continue; + } + + r++; + + cw = (x < gridWidth - 1) ? cellWidthA : cellWidthB; + ch = (y < gridHeight - 1) ? cellHeightA : cellHeightB; + + ctx.fillRect( + dx + x * cellWidth, + dy + y * cellHeight, + cw, + ch + ); + } + } + } + + if (showAltCells && src.altFillAlpha > 0) + { + FillStyleCanvas(ctx, src, src.altFillColor, src.altFillAlpha * alpha); + + for (y = 0; y < gridHeight; y++) + { + if (showAltCells) + { + r = y % 2; + } + + for (x = 0; x < gridWidth; x++) + { + if (showAltCells && !r) + { + r = 1; + continue; + } + + r = 0; + + cw = (x < gridWidth - 1) ? cellWidthA : cellWidthB; + ch = (y < gridHeight - 1) ? cellHeightA : cellHeightB; + + ctx.fillRect( + dx + x * cellWidth, + dy + y * cellHeight, + cw, + ch + ); + } + } + } + if (showOutline && src.outlineFillAlpha > 0) + { + LineStyleCanvas(ctx, src, src.outlineFillColor, src.outlineFillAlpha * alpha); + + for (x = 1; x < gridWidth; x++) + { + var x1 = x * cellWidth; + + ctx.beginPath(); + + ctx.moveTo(x1 + dx, dy); + ctx.lineTo(x1 + dx, height + dy); + + ctx.stroke(); + } + + for (y = 1; y < gridHeight; y++) + { + var y1 = y * cellHeight; + + ctx.beginPath(); + + ctx.moveTo(dx, y1 + dy); + ctx.lineTo(dx + width, y1 + dy); + + ctx.stroke(); + } + } + + // Restore the context saved in SetTransform + ctx.restore(); + } }; -module.exports = Mask; +module.exports = GridCanvasRenderer; /***/ }), -/* 310 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 9326: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GameEvents = __webpack_require__(22); -var RenderEvents = __webpack_require__(91); +var GameObjectFactory = __webpack_require__(61286); +var Grid = __webpack_require__(39169); /** - * @classdesc - * A Bitmap Mask combines the alpha (opacity) of a masked pixel with the alpha of another pixel. - * Unlike the Geometry Mask, which is a clipping path, a Bitmap Mask behaves like an alpha mask, - * not a clipping path. It is only available when using the WebGL Renderer. + * Creates a new Grid Shape Game Object and adds it to the Scene. * - * A Bitmap Mask can use any Game Object to determine the alpha of each pixel of the masked Game Object(s). - * For any given point of a masked Game Object's texture, the pixel's alpha will be multiplied by the alpha - * of the pixel at the same position in the Bitmap Mask's Game Object. The color of the pixel from the - * Bitmap Mask doesn't matter. + * Note: This method will only be available if the Grid Game Object has been built into Phaser. * - * For example, if a pure blue pixel with an alpha of 0.95 is masked with a pure red pixel with an - * alpha of 0.5, the resulting pixel will be pure blue with an alpha of 0.475. Naturally, this means - * that a pixel in the mask with an alpha of 0 will hide the corresponding pixel in all masked Game Objects - * A pixel with an alpha of 1 in the masked Game Object will receive the same alpha as the - * corresponding pixel in the mask. + * 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. * - * Note: You cannot combine Bitmap Masks and Blend Modes on the same Game Object. You can, however, - * combine Geometry Masks and Blend Modes together. + * This shape supports only fill colors and cannot be stroked. * - * The Bitmap Mask's location matches the location of its Game Object, not the location of the - * masked objects. Moving or transforming the underlying Game Object will change the mask - * (and affect the visibility of any masked objects), whereas moving or transforming a masked object - * will not affect the mask. + * 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. * - * The Bitmap Mask will not render its Game Object by itself. If the Game Object is not in a - * Scene's display list, it will only be used for the mask and its full texture will not be directly - * visible. Adding the underlying Game Object to a Scene will not cause any problems - it will - * render as a normal Game Object and will also serve as a mask. + * @method Phaser.GameObjects.GameObjectFactory#grid + * @since 3.13.0 * - * @class BitmapMask - * @memberof Phaser.Display.Masks - * @constructor - * @since 3.0.0 + * @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. + * @param {number} [outlineFillAlpha] - The alpha of the lines between the grid cells. * - * @param {Phaser.Scene} scene - The Scene which this Bitmap Mask will be used in. - * @param {Phaser.GameObjects.GameObject} renderable - A renderable Game Object that uses a texture, such as a Sprite. + * @return {Phaser.GameObjects.Grid} The Game Object that was created. */ -var BitmapMask = new Class({ +GameObjectFactory.register('grid', function (x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha) +{ + return this.displayList.add(new Grid(this.scene, x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha)); +}); - initialize: - function BitmapMask (scene, renderable) - { - var renderer = scene.sys.renderer; +/***/ }), - /** - * A reference to either the Canvas or WebGL Renderer that this Mask is using. - * - * @name Phaser.Display.Masks.BitmapMask#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.11.0 - */ - this.renderer = renderer; +/***/ 88059: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A renderable Game Object that uses a texture, such as a Sprite. - * - * @name Phaser.Display.Masks.BitmapMask#bitmapMask - * @type {Phaser.GameObjects.GameObject} - * @since 3.0.0 - */ - this.bitmapMask = renderable; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The texture used for the masks framebuffer. - * - * @name Phaser.Display.Masks.BitmapMask#maskTexture - * @type {WebGLTexture} - * @default null - * @since 3.0.0 - */ - this.maskTexture = null; +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - /** - * The texture used for the main framebuffer. - * - * @name Phaser.Display.Masks.BitmapMask#mainTexture - * @type {WebGLTexture} - * @default null - * @since 3.0.0 - */ - this.mainTexture = null; +if (true) +{ + renderWebGL = __webpack_require__(50639); +} - /** - * Whether the Bitmap Mask is dirty and needs to be updated. - * - * @name Phaser.Display.Masks.BitmapMask#dirty - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.dirty = true; +if (true) +{ + renderCanvas = __webpack_require__(95525); +} - /** - * The framebuffer to which a masked Game Object is rendered. - * - * @name Phaser.Display.Masks.BitmapMask#mainFramebuffer - * @type {WebGLFramebuffer} - * @since 3.0.0 - */ - this.mainFramebuffer = null; +module.exports = { - /** - * The framebuffer to which the Bitmap Mask's masking Game Object is rendered. - * - * @name Phaser.Display.Masks.BitmapMask#maskFramebuffer - * @type {WebGLFramebuffer} - * @since 3.0.0 - */ - this.maskFramebuffer = null; + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - /** - * Whether to invert the masks alpha. - * - * If `true`, the alpha of the masking pixel will be inverted before it's multiplied with the masked pixel. - * Essentially, this means that a masked area will be visible only if the corresponding area in the mask is invisible. - * - * @name Phaser.Display.Masks.BitmapMask#invertAlpha - * @type {boolean} - * @since 3.1.2 - */ - this.invertAlpha = false; +}; - /** - * Is this mask a stencil mask? - * - * @name Phaser.Display.Masks.BitmapMask#isStencil - * @type {boolean} - * @readonly - * @since 3.17.0 - */ - this.isStencil = false; - this.createMask(); +/***/ }), - scene.sys.game.events.on(GameEvents.CONTEXT_RESTORED, this.createMask, this); +/***/ 50639: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (renderer) - { - renderer.on(RenderEvents.RESIZE, this.createMask, this); - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Creates the WebGL Texture2D objects and Framebuffers required for this - * mask. If this mask has already been created, then `clearMask` is called first. - * - * @method Phaser.Display.Masks.BitmapMask#createMask - * @since 3.50.0 - */ - createMask: function () +var GetCalcMatrix = __webpack_require__(73329); +var Utils = __webpack_require__(75512); + +/** + * 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.Grid#renderWebGL + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Grid} 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 GridWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); + + var pipeline = renderer.pipelines.set(src.pipeline); + + var result = GetCalcMatrix(src, camera, parentMatrix); + + var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); + + calcMatrix.translate(-src._displayOriginX, -src._displayOriginY); + + var alpha = camera.alpha * src.alpha; + + // Work out the grid size + + var width = src.width; + var height = src.height; + + var cellWidth = src.cellWidth; + var cellHeight = src.cellHeight; + + var gridWidth = Math.ceil(width / cellWidth); + var gridHeight = Math.ceil(height / cellHeight); + + var cellWidthA = cellWidth; + var cellHeightA = cellHeight; + + var cellWidthB = cellWidth - ((gridWidth * cellWidth) - width); + var cellHeightB = cellHeight - ((gridHeight * cellHeight) - height); + + var fillTint; + var fillTintColor; + + var showCells = src.showCells; + var showAltCells = src.showAltCells; + var showOutline = src.showOutline; + + var x = 0; + var y = 0; + var r = 0; + var cw = 0; + var ch = 0; + + if (showOutline) { - var renderer = this.renderer; + // To make room for the grid lines (in case alpha < 1) + cellWidthA--; + cellHeightA--; - if (!renderer || !renderer.gl) + if (cellWidthB === cellWidth) { - return; + cellWidthB--; } - if (this.mainTexture) + if (cellHeightB === cellHeight) { - this.clearMask(); + cellHeightB--; } + } - var width = renderer.width; - var height = renderer.height; - var pot = ((width & (width - 1)) === 0 && (height & (height - 1)) === 0); - var gl = renderer.gl; - var wrap = pot ? gl.REPEAT : gl.CLAMP_TO_EDGE; - var filter = gl.LINEAR; - - this.mainTexture = renderer.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, null, width, height); - this.maskTexture = renderer.createTexture2D(0, filter, filter, wrap, wrap, gl.RGBA, null, width, height); - this.mainFramebuffer = renderer.createFramebuffer(width, height, this.mainTexture, true); - this.maskFramebuffer = renderer.createFramebuffer(width, height, this.maskTexture, true); - }, + renderer.pipelines.preBatch(src); - /** - * Deletes the `mainTexture` and `maskTexture` WebGL Textures and deletes - * the `mainFramebuffer` and `maskFramebuffer` too, nulling all references. - * - * This is called when this mask is destroyed, or if you try to creat a new - * mask from this object when one is already set. - * - * @method Phaser.Display.Masks.BitmapMask#clearMask - * @since 3.50.0 - */ - clearMask: function () + if (showCells && src.fillAlpha > 0) { - var renderer = this.renderer; + fillTint = pipeline.fillTint; + fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha); + + fillTint.TL = fillTintColor; + fillTint.TR = fillTintColor; + fillTint.BL = fillTintColor; + fillTint.BR = fillTintColor; - if (!renderer || !renderer.gl || !this.mainTexture) + for (y = 0; y < gridHeight; y++) { - return; - } + if (showAltCells) + { + r = y % 2; + } - renderer.deleteTexture(this.mainTexture); - renderer.deleteTexture(this.maskTexture); - renderer.deleteFramebuffer(this.mainFramebuffer); - renderer.deleteFramebuffer(this.maskFramebuffer); + for (x = 0; x < gridWidth; x++) + { + if (showAltCells && r) + { + r = 0; + continue; + } - this.mainTexture = null; - this.maskTexture = null; - this.mainFramebuffer = null; - this.maskFramebuffer = null; - }, + r++; - /** - * Sets a new masking Game Object for the Bitmap Mask. - * - * @method Phaser.Display.Masks.BitmapMask#setBitmap - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} renderable - A renderable Game Object that uses a texture, such as a Sprite. - */ - setBitmap: function (renderable) - { - this.bitmapMask = renderable; - }, + cw = (x < gridWidth - 1) ? cellWidthA : cellWidthB; + ch = (y < gridHeight - 1) ? cellHeightA : cellHeightB; - /** - * Prepares the WebGL Renderer to render a Game Object with this mask applied. - * - * This renders the masking Game Object to the mask framebuffer and switches to the main framebuffer so that the masked Game Object will be rendered to it instead of being rendered directly to the frame. - * - * @method Phaser.Display.Masks.BitmapMask#preRenderWebGL - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to prepare. - * @param {Phaser.GameObjects.GameObject} maskedObject - The masked Game Object which will be drawn. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to. - */ - preRenderWebGL: function (renderer, maskedObject, camera) - { - renderer.pipelines.BITMAPMASK_PIPELINE.beginMask(this, maskedObject, camera); - }, + pipeline.batchFillRect( + x * cellWidth, + y * cellHeight, + cw, + ch + ); + } + } + } - /** - * Finalizes rendering of a masked Game Object. - * - * This resets the previously bound framebuffer and switches the WebGL Renderer to the Bitmap Mask Pipeline, which uses a special fragment shader to apply the masking effect. - * - * @method Phaser.Display.Masks.BitmapMask#postRenderWebGL - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to clean up. - */ - postRenderWebGL: function (renderer, camera) + if (showAltCells && src.altFillAlpha > 0) { - renderer.pipelines.BITMAPMASK_PIPELINE.endMask(this, camera); - }, + fillTint = pipeline.fillTint; + fillTintColor = Utils.getTintAppendFloatAlpha(src.altFillColor, src.altFillAlpha * alpha); - /** - * This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer. - * - * @method Phaser.Display.Masks.BitmapMask#preRenderCanvas - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to. - * @param {Phaser.GameObjects.GameObject} mask - The masked Game Object which would be rendered. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to. - */ - preRenderCanvas: function () - { - // NOOP - }, + fillTint.TL = fillTintColor; + fillTint.TR = fillTintColor; + fillTint.BL = fillTintColor; + fillTint.BR = fillTintColor; - /** - * This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer. - * - * @method Phaser.Display.Masks.BitmapMask#postRenderCanvas - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to. - */ - postRenderCanvas: function () - { - // NOOP - }, + for (y = 0; y < gridHeight; y++) + { + if (showAltCells) + { + r = y % 2; + } - /** - * Destroys this BitmapMask and nulls any references it holds. - * - * Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it, - * so be sure to call `clearMask` on any Game Object using it, before destroying it. - * - * @method Phaser.Display.Masks.BitmapMask#destroy - * @since 3.7.0 - */ - destroy: function () + for (x = 0; x < gridWidth; x++) + { + if (showAltCells && !r) + { + r = 1; + continue; + } + + r = 0; + + cw = (x < gridWidth - 1) ? cellWidthA : cellWidthB; + ch = (y < gridHeight - 1) ? cellHeightA : cellHeightB; + + pipeline.batchFillRect( + x * cellWidth, + y * cellHeight, + cw, + ch + ); + } + } + } + + if (showOutline && src.outlineFillAlpha > 0) { - this.clearMask(); + var strokeTint = pipeline.strokeTint; + var color = Utils.getTintAppendFloatAlpha(src.outlineFillColor, src.outlineFillAlpha * alpha); - if (this.renderer) + strokeTint.TL = color; + strokeTint.TR = color; + strokeTint.BL = color; + strokeTint.BR = color; + + for (x = 1; x < gridWidth; x++) { - this.renderer.off(RenderEvents.RESIZE, this.createMask, this); + var x1 = x * cellWidth; + + pipeline.batchLine(x1, 0, x1, height, 1, 1, 1, 0, false); + } + + for (y = 1; y < gridHeight; y++) + { + var y1 = y * cellHeight; + + pipeline.batchLine(0, y1, width, y1, 1, 1, 1, 0, false); } - - this.bitmapMask = null; - this.prevFramebuffer = null; - this.renderer = null; } -}); + renderer.pipelines.postBatch(src); +}; -module.exports = BitmapMask; +module.exports = GridWebGLRenderer; /***/ }), -/* 311 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 4415: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); +var IsoBoxRender = __webpack_require__(72296); +var Class = __webpack_require__(56694); +var Shape = __webpack_require__(91461); /** * @classdesc - * A Geometry Mask can be applied to a Game Object to hide any pixels of it which don't intersect - * a visible pixel from the geometry mask. The mask is essentially a clipping path which can only - * make a masked pixel fully visible or fully invisible without changing its alpha (opacity). + * 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. * - * A Geometry Mask uses a Graphics Game Object to determine which pixels of the masked Game Object(s) - * should be clipped. For any given point of a masked Game Object's texture, the pixel will only be displayed - * if the Graphics Game Object of the Geometry Mask has a visible pixel at the same position. The color and - * alpha of the pixel from the Geometry Mask do not matter. + * This shape supports only fill colors and cannot be stroked. * - * The Geometry Mask's location matches the location of its Graphics object, not the location of the masked objects. - * Moving or transforming the underlying Graphics object will change the mask (and affect the visibility - * of any masked objects), whereas moving or transforming a masked object will not affect the mask. - * You can think of the Geometry Mask (or rather, of its Graphics object) as an invisible curtain placed - * in front of all masked objects which has its own visual properties and, naturally, respects the camera's - * visual properties, but isn't affected by and doesn't follow the masked objects by itself. + * 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. * - * @class GeometryMask - * @memberof Phaser.Display.Masks + * 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.0.0 + * @since 3.13.0 * - * @param {Phaser.Scene} scene - This parameter is not used. - * @param {Phaser.GameObjects.Graphics} graphicsGeometry - The Graphics Game Object to use for the Geometry Mask. Doesn't have to be in the Display List. + * @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 GeometryMask = new Class({ +var IsoBox = new Class({ + + Extends: Shape, + + Mixins: [ + IsoBoxRender + ], initialize: - function GeometryMask (scene, graphicsGeometry) + 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 Graphics object which describes the Geometry Mask. + * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. * - * @name Phaser.Display.Masks.GeometryMask#geometryMask - * @type {Phaser.GameObjects.Graphics} - * @since 3.0.0 + * @name Phaser.GameObjects.IsoBox#projection + * @type {number} + * @default 4 + * @since 3.13.0 */ - this.geometryMask = graphicsGeometry; + this.projection = 4; /** - * Similar to the BitmapMasks invertAlpha setting this to true will then hide all pixels - * drawn to the Geometry Mask. + * The color used to fill in the top of the iso box. * - * This is a WebGL only feature. + * @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.Display.Masks.GeometryMask#invertAlpha + * @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} - * @since 3.16.0 + * @default true + * @since 3.13.0 */ - this.invertAlpha = false; + this.showTop = true; /** - * Is this mask a stencil mask? + * Controls if the left-face of the iso box be rendered. * - * @name Phaser.Display.Masks.GeometryMask#isStencil + * @name Phaser.GameObjects.IsoBox#showLeft * @type {boolean} - * @readonly - * @since 3.17.0 + * @default true + * @since 3.13.0 */ - this.isStencil = true; + this.showLeft = true; /** - * The current stencil level. + * Controls if the right-face of the iso box be rendered. * - * @name Phaser.Display.Masks.GeometryMask#level + * @name Phaser.GameObjects.IsoBox#showRight * @type {boolean} - * @private - * @since 3.17.0 + * @default true + * @since 3.13.0 */ - this.level = 0; + this.showRight = true; + + this.isFilled = true; + + this.setPosition(x, y); + this.setSize(size, height); + + this.updateDisplayOrigin(); }, /** - * Sets a new Graphics object for the Geometry Mask. + * 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.Display.Masks.GeometryMask#setShape - * @since 3.0.0 + * @method Phaser.GameObjects.IsoBox#setProjection + * @since 3.13.0 * - * @param {Phaser.GameObjects.Graphics} graphicsGeometry - The Graphics object which will be used for the Geometry Mask. + * @param {number} value - The value to set the projection to. * - * @return {this} This Geometry Mask + * @return {this} This Game Object instance. */ - setShape: function (graphicsGeometry) + setProjection: function (value) { - this.geometryMask = graphicsGeometry; + this.projection = value; return this; }, /** - * Sets the `invertAlpha` property of this Geometry Mask. - * - * Inverting the alpha essentially flips the way the mask works. - * - * This is a WebGL only feature. + * Sets which faces of the iso box will be rendered. + * This call can be chained. * - * @method Phaser.Display.Masks.GeometryMask#setInvertAlpha - * @since 3.17.0 + * @method Phaser.GameObjects.IsoBox#setFaces + * @since 3.13.0 * - * @param {boolean} [value=true] - Invert the alpha of this mask? + * @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 Geometry Mask + * @return {this} This Game Object instance. */ - setInvertAlpha: function (value) + setFaces: function (showTop, showLeft, showRight) { - if (value === undefined) { value = true; } + if (showTop === undefined) { showTop = true; } + if (showLeft === undefined) { showLeft = true; } + if (showRight === undefined) { showRight = true; } - this.invertAlpha = value; + this.showTop = showTop; + this.showLeft = showLeft; + this.showRight = showRight; return this; }, /** - * Renders the Geometry Mask's underlying Graphics object to the OpenGL stencil buffer and enables the stencil test, which clips rendered pixels according to the mask. + * Sets the fill colors for each face of the iso box. + * This call can be chained. * - * @method Phaser.Display.Masks.GeometryMask#preRenderWebGL - * @since 3.0.0 + * @method Phaser.GameObjects.IsoBox#setFillStyle + * @since 3.13.0 * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to. - * @param {Phaser.GameObjects.GameObject} child - The Game Object being rendered. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through. + * @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. */ - preRenderWebGL: function (renderer, child, camera) + setFillStyle: function (fillTop, fillLeft, fillRight) { - var gl = renderer.gl; + this.fillTop = fillTop; + this.fillLeft = fillLeft; + this.fillRight = fillRight; - // Force flushing before drawing to stencil buffer - renderer.flush(); + this.isFilled = true; - if (renderer.maskStack.length === 0) - { - gl.enable(gl.STENCIL_TEST); - gl.clear(gl.STENCIL_BUFFER_BIT); + return this; + } - renderer.maskCount = 0; - } +}); - if (renderer.currentCameraMask.mask !== this) - { - renderer.currentMask.mask = this; - } +module.exports = IsoBox; - renderer.maskStack.push({ mask: this, camera: camera }); - this.applyStencil(renderer, camera, true); +/***/ }), - renderer.maskCount++; - }, +/***/ 32884: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Applies the current stencil mask to the renderer. - * - * @method Phaser.Display.Masks.GeometryMask#applyStencil - * @since 3.17.0 - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through. - * @param {boolean} inc - Is this an INCR stencil or a DECR stencil? - */ - applyStencil: function (renderer, camera, inc) - { - var gl = renderer.gl; - var geometryMask = this.geometryMask; - var level = renderer.maskCount; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - gl.colorMask(false, false, false, false); +var FillStyleCanvas = __webpack_require__(15608); +var SetTransform = __webpack_require__(49584); - if (inc) - { - gl.stencilFunc(gl.EQUAL, level, 0xFF); - gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR); - } - else - { - gl.stencilFunc(gl.EQUAL, level + 1, 0xFF); - gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR); - } +/** + * 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.IsoBox#renderCanvas + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.IsoBox} 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 IsoBoxCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); - // Write stencil buffer - geometryMask.renderWebGL(renderer, geometryMask, camera); + var ctx = renderer.currentContext; - renderer.flush(); + if (SetTransform(renderer, ctx, src, camera, parentMatrix) && src.isFilled) + { + var size = src.width; + var height = src.height; - gl.colorMask(true, true, true, true); - gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); + var sizeA = size / 2; + var sizeB = size / src.projection; - if (inc) - { - if (this.invertAlpha) - { - gl.stencilFunc(gl.NOTEQUAL, level + 1, 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL, level + 1, 0xFF); - } - } - else if (this.invertAlpha) - { - gl.stencilFunc(gl.NOTEQUAL, level, 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL, level, 0xFF); - } - }, + // Top Face - /** - * Flushes all rendered pixels and disables the stencil test of a WebGL context, thus disabling the mask for it. - * - * @method Phaser.Display.Masks.GeometryMask#postRenderWebGL - * @since 3.0.0 - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw flush. - */ - postRenderWebGL: function (renderer) - { - var gl = renderer.gl; + if (src.showTop) + { + FillStyleCanvas(ctx, src, src.fillTop); - renderer.maskStack.pop(); + ctx.beginPath(); - renderer.maskCount--; + ctx.moveTo(-sizeA, -height); + ctx.lineTo(0, -sizeB - height); + ctx.lineTo(sizeA, -height); + ctx.lineTo(sizeA, -1); + ctx.lineTo(0, sizeB - 1); + ctx.lineTo(-sizeA, -1); + ctx.lineTo(-sizeA, -height); - // Force flush before disabling stencil test - renderer.flush(); + ctx.fill(); + } - var current = renderer.currentMask; + // Left Face - if (renderer.maskStack.length === 0) + if (src.showLeft) { - // If this is the only mask in the stack, flush and disable - current.mask = null; + FillStyleCanvas(ctx, src, src.fillLeft); - gl.disable(gl.STENCIL_TEST); - } - else - { - var prev = renderer.maskStack[renderer.maskStack.length - 1]; + ctx.beginPath(); - prev.mask.applyStencil(renderer, prev.camera, false); + ctx.moveTo(-sizeA, 0); + ctx.lineTo(0, sizeB); + ctx.lineTo(0, sizeB - height); + ctx.lineTo(-sizeA, -height); + ctx.lineTo(-sizeA, 0); - if (renderer.currentCameraMask.mask !== prev.mask) - { - current.mask = prev.mask; - current.camera = prev.camera; - } - else - { - current.mask = null; - } + ctx.fill(); } - }, - /** - * Sets the clipping path of a 2D canvas context to the Geometry Mask's underlying Graphics object. - * - * @method Phaser.Display.Masks.GeometryMask#preRenderCanvas - * @since 3.0.0 - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance to set the clipping path on. - * @param {Phaser.GameObjects.GameObject} mask - The Game Object being rendered. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through. - */ - preRenderCanvas: function (renderer, mask, camera) - { - var geometryMask = this.geometryMask; + // Right Face - renderer.currentContext.save(); + if (src.showRight) + { + FillStyleCanvas(ctx, src, src.fillRight); - geometryMask.renderCanvas(renderer, geometryMask, camera, null, null, true); + ctx.beginPath(); - renderer.currentContext.clip(); - }, + ctx.moveTo(sizeA, 0); + ctx.lineTo(0, sizeB); + ctx.lineTo(0, sizeB - height); + ctx.lineTo(sizeA, -height); + ctx.lineTo(sizeA, 0); - /** - * Restore the canvas context's previous clipping path, thus turning off the mask for it. - * - * @method Phaser.Display.Masks.GeometryMask#postRenderCanvas - * @since 3.0.0 - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance being restored. - */ - postRenderCanvas: function (renderer) - { - renderer.currentContext.restore(); - }, + ctx.fill(); + } - /** - * Destroys this GeometryMask and nulls any references it holds. - * - * Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it, - * so be sure to call `clearMask` on any Game Object using it, before destroying it. - * - * @method Phaser.Display.Masks.GeometryMask#destroy - * @since 3.7.0 - */ - destroy: function () - { - this.geometryMask = null; + // Restore the context saved in SetTransform + ctx.restore(); } +}; -}); - -module.exports = GeometryMask; +module.exports = IsoBoxCanvasRenderer; /***/ }), -/* 312 */ -/***/ (function(module, exports) { + +/***/ 88154: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GameObjectFactory = __webpack_require__(61286); +var IsoBox = __webpack_require__(4415); + /** - * Provides methods used for getting and setting the Scroll Factor of a Game Object. + * Creates a new IsoBox Shape Game Object and adds it to the Scene. * - * @namespace Phaser.GameObjects.Components.ScrollFactor - * @since 3.0.0 + * Note: This method will only be available if the IsoBox Game Object has been built into Phaser. + * + * 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. + * + * @method Phaser.GameObjects.GameObjectFactory#isobox + * @since 3.13.0 + * + * @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. + * + * @return {Phaser.GameObjects.IsoBox} The Game Object that was created. */ +GameObjectFactory.register('isobox', function (x, y, size, height, fillTop, fillLeft, fillRight) +{ + return this.displayList.add(new IsoBox(this.scene, x, y, size, height, fillTop, fillLeft, fillRight)); +}); -var ScrollFactor = { - /** - * The horizontal scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * - * @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorX - * @type {number} - * @default 1 - * @since 3.0.0 - */ - scrollFactorX: 1, +/***/ }), - /** - * The vertical scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * - * @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorY - * @type {number} - * @default 1 - * @since 3.0.0 - */ - scrollFactorY: 1, +/***/ 72296: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Sets the scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * - * @method Phaser.GameObjects.Components.ScrollFactor#setScrollFactor - * @since 3.0.0 - * - * @param {number} x - The horizontal scroll factor of this Game Object. - * @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value. - * - * @return {this} This Game Object instance. - */ - setScrollFactor: function (x, y) - { - if (y === undefined) { y = x; } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.scrollFactorX = x; - this.scrollFactorY = y; +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - return this; - } +if (true) +{ + renderWebGL = __webpack_require__(33101); +} -}; +if (true) +{ + renderCanvas = __webpack_require__(32884); +} -module.exports = ScrollFactor; +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; /***/ }), -/* 313 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 33101: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MATH_CONST = __webpack_require__(14); -var TransformMatrix = __webpack_require__(25); -var TransformXY = __webpack_require__(177); -var WrapAngle = __webpack_require__(269); -var WrapAngleDegrees = __webpack_require__(270); -var Vector2 = __webpack_require__(3); - -// global bitmask flag for GameObject.renderMask (used by Scale) -var _FLAG = 4; // 0100 +var GetCalcMatrix = __webpack_require__(73329); +var Utils = __webpack_require__(75512); /** - * Provides methods used for getting and setting the position, scale and rotation of a Game Object. + * 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. * - * @namespace Phaser.GameObjects.Components.Transform - * @since 3.0.0 + * @method Phaser.GameObjects.IsoBox#renderWebGL + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.IsoBox} 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 IsoBoxWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); -var Transform = { + var pipeline = renderer.pipelines.set(src.pipeline); - /** - * Private internal value. Holds the horizontal scale value. - * - * @name Phaser.GameObjects.Components.Transform#_scaleX - * @type {number} - * @private - * @default 1 - * @since 3.0.0 - */ - _scaleX: 1, + var result = GetCalcMatrix(src, camera, parentMatrix); - /** - * Private internal value. Holds the vertical scale value. - * - * @name Phaser.GameObjects.Components.Transform#_scaleY - * @type {number} - * @private - * @default 1 - * @since 3.0.0 - */ - _scaleY: 1, + var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); - /** - * Private internal value. Holds the rotation value in radians. - * - * @name Phaser.GameObjects.Components.Transform#_rotation - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - _rotation: 0, + var size = src.width; + var height = src.height; - /** - * The x position of this Game Object. - * - * @name Phaser.GameObjects.Components.Transform#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - x: 0, + var sizeA = size / 2; + var sizeB = size / src.projection; - /** - * The y position of this Game Object. - * - * @name Phaser.GameObjects.Components.Transform#y - * @type {number} - * @default 0 - * @since 3.0.0 - */ - y: 0, + var alpha = camera.alpha * src.alpha; - /** - * The z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#depth} instead. - * - * @name Phaser.GameObjects.Components.Transform#z - * @type {number} - * @default 0 - * @since 3.0.0 - */ - z: 0, + if (!src.isFilled) + { + return; + } - /** - * The w position of this Game Object. - * - * @name Phaser.GameObjects.Components.Transform#w - * @type {number} - * @default 0 - * @since 3.0.0 - */ - w: 0, + var tint; - /** - * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object - * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. - * - * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this - * isn't the case, use the `scaleX` or `scaleY` properties instead. - * - * @name Phaser.GameObjects.Components.Transform#scale - * @type {number} - * @default 1 - * @since 3.18.0 - */ - scale: { + var x0; + var y0; - get: function () - { - return (this._scaleX + this._scaleY) / 2; - }, + var x1; + var y1; - set: function (value) - { - this._scaleX = value; - this._scaleY = value; + var x2; + var y2; - if (value === 0) - { - this.renderFlags &= ~_FLAG; - } - else - { - this.renderFlags |= _FLAG; - } - } + var x3; + var y3; - }, - /** - * The horizontal scale of this Game Object. - * - * @name Phaser.GameObjects.Components.Transform#scaleX - * @type {number} - * @default 1 - * @since 3.0.0 - */ - scaleX: { + renderer.pipelines.preBatch(src); - get: function () - { - return this._scaleX; - }, + // Top Face - set: function (value) - { - this._scaleX = value; + if (src.showTop) + { + tint = Utils.getTintAppendFloatAlpha(src.fillTop, alpha); - if (value === 0) - { - this.renderFlags &= ~_FLAG; - } - else - { - this.renderFlags |= _FLAG; - } - } + x0 = calcMatrix.getX(-sizeA, -height); + y0 = calcMatrix.getY(-sizeA, -height); - }, + x1 = calcMatrix.getX(0, -sizeB - height); + y1 = calcMatrix.getY(0, -sizeB - height); - /** - * The vertical scale of this Game Object. - * - * @name Phaser.GameObjects.Components.Transform#scaleY - * @type {number} - * @default 1 - * @since 3.0.0 - */ - scaleY: { + x2 = calcMatrix.getX(sizeA, -height); + y2 = calcMatrix.getY(sizeA, -height); - get: function () - { - return this._scaleY; - }, + x3 = calcMatrix.getX(0, sizeB - height); + y3 = calcMatrix.getY(0, sizeB - height); - set: function (value) - { - this._scaleY = value; + pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); + } - if (value === 0) - { - this.renderFlags &= ~_FLAG; - } - else - { - this.renderFlags |= _FLAG; - } - } + // Left Face - }, + if (src.showLeft) + { + tint = Utils.getTintAppendFloatAlpha(src.fillLeft, alpha); - /** - * The angle of this Game Object as expressed in degrees. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left - * and -90 is up. - * - * If you prefer to work in radians, see the `rotation` property instead. - * - * @name Phaser.GameObjects.Components.Transform#angle - * @type {number} - * @default 0 - * @since 3.0.0 - */ - angle: { + x0 = calcMatrix.getX(-sizeA, 0); + y0 = calcMatrix.getY(-sizeA, 0); - get: function () - { - return WrapAngleDegrees(this._rotation * MATH_CONST.RAD_TO_DEG); - }, + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); - set: function (value) - { - // value is in degrees - this.rotation = WrapAngleDegrees(value) * MATH_CONST.DEG_TO_RAD; - } - }, + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); - /** - * The angle of this Game Object in radians. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left - * and -PI/2 is up. - * - * If you prefer to work in degrees, see the `angle` property instead. - * - * @name Phaser.GameObjects.Components.Transform#rotation - * @type {number} - * @default 1 - * @since 3.0.0 - */ - rotation: { + x3 = calcMatrix.getX(-sizeA, -height); + y3 = calcMatrix.getY(-sizeA, -height); - get: function () - { - return this._rotation; - }, + pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); + } - set: function (value) - { - // value is in radians - this._rotation = WrapAngle(value); - } - }, + // Right Face - /** - * Sets the position of this Game Object. - * - * @method Phaser.GameObjects.Components.Transform#setPosition - * @since 3.0.0 - * - * @param {number} [x=0] - The x position of this Game Object. - * @param {number} [y=x] - The y position of this Game Object. If not set it will use the `x` value. - * @param {number} [z=0] - The z position of this Game Object. - * @param {number} [w=0] - The w position of this Game Object. - * - * @return {this} This Game Object instance. - */ - setPosition: function (x, y, z, w) + if (src.showRight) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } - if (z === undefined) { z = 0; } - if (w === undefined) { w = 0; } + tint = Utils.getTintAppendFloatAlpha(src.fillRight, alpha); - this.x = x; - this.y = y; - this.z = z; - this.w = w; + x0 = calcMatrix.getX(sizeA, 0); + y0 = calcMatrix.getY(sizeA, 0); - return this; - }, + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); - /** - * Copies an object's coordinates to this Game Object's position. - * - * @method Phaser.GameObjects.Components.Transform#copyPosition - * @since 3.50.0 - * - * @param {(Phaser.Types.Math.Vector2Like|Phaser.Types.Math.Vector3Like|Phaser.Types.Math.Vector4Like)} source - An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. - * - * @return {this} This Game Object instance. - */ - copyPosition: function (source) - { - if (source.x !== undefined) { this.x = source.x; } - if (source.y !== undefined) { this.y = source.y; } - if (source.z !== undefined) { this.z = source.z; } - if (source.w !== undefined) { this.w = source.w; } + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); - return this; - }, + x3 = calcMatrix.getX(sizeA, -height); + y3 = calcMatrix.getY(sizeA, -height); - /** - * Sets the position of this Game Object to be a random position within the confines of - * the given area. - * - * If no area is specified a random position between 0 x 0 and the game width x height is used instead. - * - * The position does not factor in the size of this Game Object, meaning that only the origin is - * guaranteed to be within the area. - * - * @method Phaser.GameObjects.Components.Transform#setRandomPosition - * @since 3.8.0 - * - * @param {number} [x=0] - The x position of the top-left of the random area. - * @param {number} [y=0] - The y position of the top-left of the random area. - * @param {number} [width] - The width of the random area. - * @param {number} [height] - The height of the random area. - * - * @return {this} This Game Object instance. - */ - setRandomPosition: function (x, y, width, height) + pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); + } + + renderer.pipelines.postBatch(src); +}; + +module.exports = IsoBoxWebGLRenderer; + + +/***/ }), + +/***/ 65159: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var IsoTriangleRender = __webpack_require__(93387); +var Shape = __webpack_require__(91461); + +/** + * @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 (width === undefined) { width = this.scene.sys.scale.width; } - if (height === undefined) { height = this.scene.sys.scale.height; } + 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; } - this.x = x + (Math.random() * width); - this.y = y + (Math.random() * height); + Shape.call(this, scene, 'IsoTriangle', null); - return this; - }, + /** + * 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; - /** - * Sets the rotation of this Game Object. - * - * @method Phaser.GameObjects.Components.Transform#setRotation - * @since 3.0.0 - * - * @param {number} [radians=0] - The rotation of this Game Object, in radians. - * - * @return {this} This Game Object instance. - */ - setRotation: function (radians) - { - if (radians === undefined) { radians = 0; } + /** + * 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; - this.rotation = radians; + /** + * 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; - return this; - }, + /** + * 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; - /** - * Sets the angle of this Game Object. - * - * @method Phaser.GameObjects.Components.Transform#setAngle - * @since 3.0.0 - * - * @param {number} [degrees=0] - The rotation of this Game Object, in degrees. - * - * @return {this} This Game Object instance. - */ - setAngle: function (degrees) - { - if (degrees === undefined) { degrees = 0; } + /** + * 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; - this.angle = degrees; + /** + * 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; - return this; - }, + /** + * 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 the scale of this Game Object. - * - * @method Phaser.GameObjects.Components.Transform#setScale - * @since 3.0.0 - * - * @param {number} x - The horizontal scale of this Game Object. - * @param {number} [y=x] - The vertical scale of this Game Object. If not set it will use the `x` value. - * - * @return {this} This Game Object instance. - */ - setScale: function (x, y) - { - if (x === undefined) { x = 1; } - if (y === undefined) { y = x; } + /** + * 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.scaleX = x; - this.scaleY = y; + this.isFilled = true; - return this; + this.setPosition(x, y); + this.setSize(size, height); + + this.updateDisplayOrigin(); }, /** - * Sets the x position of this Game Object. + * 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.Components.Transform#setX - * @since 3.0.0 + * @method Phaser.GameObjects.IsoTriangle#setProjection + * @since 3.13.0 * - * @param {number} [value=0] - The x position of this Game Object. + * @param {number} value - The value to set the projection to. * * @return {this} This Game Object instance. */ - setX: function (value) + setProjection: function (value) { - if (value === undefined) { value = 0; } - - this.x = value; + this.projection = value; return this; }, /** - * Sets the y position of this Game Object. + * Sets if the iso triangle will be rendered upside down or not. + * This call can be chained. * - * @method Phaser.GameObjects.Components.Transform#setY - * @since 3.0.0 + * @method Phaser.GameObjects.IsoTriangle#setReversed + * @since 3.13.0 * - * @param {number} [value=0] - The y position of this Game Object. + * @param {boolean} reversed - Sets if the iso triangle will be rendered upside down or not. * * @return {this} This Game Object instance. */ - setY: function (value) + setReversed: function (reversed) { - if (value === undefined) { value = 0; } - - this.y = value; + this.isReversed = reversed; return this; }, /** - * Sets the z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * Sets which faces of the iso triangle will be rendered. + * This call can be chained. * - * @method Phaser.GameObjects.Components.Transform#setZ - * @since 3.0.0 + * @method Phaser.GameObjects.IsoTriangle#setFaces + * @since 3.13.0 * - * @param {number} [value=0] - The z position of this Game Object. + * @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. */ - setZ: function (value) + setFaces: function (showTop, showLeft, showRight) { - if (value === undefined) { value = 0; } + if (showTop === undefined) { showTop = true; } + if (showLeft === undefined) { showLeft = true; } + if (showRight === undefined) { showRight = true; } - this.z = value; + this.showTop = showTop; + this.showLeft = showLeft; + this.showRight = showRight; return this; }, /** - * Sets the w position of this Game Object. + * Sets the fill colors for each face of the iso triangle. + * This call can be chained. * - * @method Phaser.GameObjects.Components.Transform#setW - * @since 3.0.0 + * @method Phaser.GameObjects.IsoTriangle#setFillStyle + * @since 3.13.0 * - * @param {number} [value=0] - The w position of this Game Object. + * @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. */ - setW: function (value) + setFillStyle: function (fillTop, fillLeft, fillRight) { - if (value === undefined) { value = 0; } + this.fillTop = fillTop; + this.fillLeft = fillLeft; + this.fillRight = fillRight; - this.w = value; + this.isFilled = true; return this; - }, - - /** - * Gets the local transform matrix for this Game Object. - * - * @method Phaser.GameObjects.Components.Transform#getLocalTransformMatrix - * @since 3.4.0 - * - * @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object. - * - * @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix. - */ - getLocalTransformMatrix: function (tempMatrix) - { - if (tempMatrix === undefined) { tempMatrix = new TransformMatrix(); } + } - return tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY); - }, +}); - /** - * Gets the world transform matrix for this Game Object, factoring in any parent Containers. - * - * @method Phaser.GameObjects.Components.Transform#getWorldTransformMatrix - * @since 3.4.0 - * - * @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object. - * @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - A temporary matrix to hold parent values during the calculations. - * - * @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix. - */ - getWorldTransformMatrix: function (tempMatrix, parentMatrix) - { - if (tempMatrix === undefined) { tempMatrix = new TransformMatrix(); } - if (parentMatrix === undefined) { parentMatrix = new TransformMatrix(); } +module.exports = IsoTriangle; - var parent = this.parentContainer; - if (!parent) - { - return this.getLocalTransformMatrix(tempMatrix); - } +/***/ }), - tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY); +/***/ 9923: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - while (parent) - { - parentMatrix.applyITRS(parent.x, parent.y, parent._rotation, parent._scaleX, parent._scaleY); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - parentMatrix.multiply(tempMatrix, tempMatrix); +var FillStyleCanvas = __webpack_require__(15608); +var SetTransform = __webpack_require__(49584); - parent = parent.parentContainer; - } +/** + * 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.IsoTriangle#renderCanvas + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.IsoTriangle} 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 IsoTriangleCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); - return tempMatrix; - }, + var ctx = renderer.currentContext; - /** - * Takes the given `x` and `y` coordinates and converts them into local space for this - * Game Object, taking into account parent and local transforms, and the Display Origin. - * - * The returned Vector2 contains the translated point in its properties. - * - * A Camera needs to be provided in order to handle modified scroll factors. If no - * camera is specified, it will use the `main` camera from the Scene to which this - * Game Object belongs. - * - * @method Phaser.GameObjects.Components.Transform#getLocalPoint - * @since 3.50.0 - * - * @param {number} x - The x position to translate. - * @param {number} y - The y position to translate. - * @param {Phaser.Math.Vector2} [point] - A Vector2, or point-like object, to store the results in. - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera. - * - * @return {Phaser.Math.Vector2} The translated point. - */ - getLocalPoint: function (x, y, point, camera) + if (SetTransform(renderer, ctx, src, camera, parentMatrix) && src.isFilled) { - if (!point) { point = new Vector2(); } - if (!camera) { camera = this.scene.sys.cameras.main; } + var size = src.width; + var height = src.height; - var csx = camera.scrollX; - var csy = camera.scrollY; + var sizeA = size / 2; + var sizeB = size / src.projection; - var px = x + (csx * this.scrollFactorX) - csx; - var py = y + (csy * this.scrollFactorY) - csy; + var reversed = src.isReversed; - if (this.parentContainer) - { - this.getWorldTransformMatrix().applyInverse(px, py, point); - } - else + // Top Face + + if (src.showTop && reversed) { - TransformXY(px, py, this.x, this.y, this.rotation, this.scaleX, this.scaleY, point); + FillStyleCanvas(ctx, src, src.fillTop); + + ctx.beginPath(); + + ctx.moveTo(-sizeA, -height); + ctx.lineTo(0, -sizeB - height); + ctx.lineTo(sizeA, -height); + ctx.lineTo(0, sizeB - height); + + ctx.fill(); } - // Normalize origin - if (this._originComponent) + // Left Face + + if (src.showLeft) { - point.x += this._displayOriginX; - point.y += this._displayOriginY; - } + FillStyleCanvas(ctx, src, src.fillLeft); - return point; - }, + ctx.beginPath(); - /** - * Gets the sum total rotation of all of this Game Objects parent Containers. - * - * The returned value is in radians and will be zero if this Game Object has no parent container. - * - * @method Phaser.GameObjects.Components.Transform#getParentRotation - * @since 3.18.0 - * - * @return {number} The sum total rotation, in radians, of all parent containers of this Game Object. - */ - getParentRotation: function () - { - var rotation = 0; + if (reversed) + { + ctx.moveTo(-sizeA, -height); + ctx.lineTo(0, sizeB); + ctx.lineTo(0, sizeB - height); + } + else + { + ctx.moveTo(-sizeA, 0); + ctx.lineTo(0, sizeB); + ctx.lineTo(0, sizeB - height); + } - var parent = this.parentContainer; + ctx.fill(); + } - while (parent) + // Right Face + + if (src.showRight) { - rotation += parent.rotation; + FillStyleCanvas(ctx, src, src.fillRight); - parent = parent.parentContainer; + ctx.beginPath(); + + if (reversed) + { + ctx.moveTo(sizeA, -height); + ctx.lineTo(0, sizeB); + ctx.lineTo(0, sizeB - height); + } + else + { + ctx.moveTo(sizeA, 0); + ctx.lineTo(0, sizeB); + ctx.lineTo(0, sizeB - height); + } + + ctx.fill(); } - return rotation; + // Restore the context saved in SetTransform + ctx.restore(); } - }; -module.exports = Transform; +module.exports = IsoTriangleCanvasRenderer; /***/ }), -/* 314 */ -/***/ (function(module, exports) { + +/***/ 67765: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// bitmask flag for GameObject.renderMask -var _FLAG = 1; // 0001 +var GameObjectFactory = __webpack_require__(61286); +var IsoTriangle = __webpack_require__(65159); /** - * Provides methods used for setting the visibility of a Game Object. - * Should be applied as a mixin and not used directly. - * - * @namespace Phaser.GameObjects.Components.Visible - * @since 3.0.0 + * Creates a new IsoTriangle Shape Game Object and adds it to the Scene. + * + * Note: This method will only be available if the IsoTriangle Game Object has been built into Phaser. + * + * 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. + * + * @method Phaser.GameObjects.GameObjectFactory#isotriangle + * @since 3.13.0 + * + * @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. + * + * @return {Phaser.GameObjects.IsoTriangle} The Game Object that was created. */ - -var Visible = { - - /** - * Private internal value. Holds the visible value. - * - * @name Phaser.GameObjects.Components.Visible#_visible - * @type {boolean} - * @private - * @default true - * @since 3.0.0 - */ - _visible: true, - - /** - * The visible state of the Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - * - * @name Phaser.GameObjects.Components.Visible#visible - * @type {boolean} - * @since 3.0.0 - */ - visible: { - - get: function () - { - return this._visible; - }, - - set: function (value) - { - if (value) - { - this._visible = true; - this.renderFlags |= _FLAG; - } - else - { - this._visible = false; - this.renderFlags &= ~_FLAG; - } - } - - }, - - /** - * Sets the visibility of this Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - * - * @method Phaser.GameObjects.Components.Visible#setVisible - * @since 3.0.0 - * - * @param {boolean} value - The visible state of the Game Object. - * - * @return {this} This Game Object instance. - */ - setVisible: function (value) - { - this.visible = value; - - return this; - } -}; - -module.exports = Visible; +GameObjectFactory.register('isotriangle', function (x, y, size, height, reversed, fillTop, fillLeft, fillRight) +{ + return this.displayList.add(new IsoTriangle(this.scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight)); +}); /***/ }), -/* 315 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 93387: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @namespace Phaser.Data.Events - */ +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(54946); +} + +if (true) +{ + renderCanvas = __webpack_require__(9923); +} module.exports = { - CHANGE_DATA: __webpack_require__(638), - CHANGE_DATA_KEY: __webpack_require__(639), - DESTROY: __webpack_require__(640), - REMOVE_DATA: __webpack_require__(641), - SET_DATA: __webpack_require__(642) + renderWebGL: renderWebGL, + renderCanvas: renderCanvas }; /***/ }), -/* 316 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 54946: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Perimeter = __webpack_require__(130); -var Point = __webpack_require__(4); - +var GetCalcMatrix = __webpack_require__(73329); +var Utils = __webpack_require__(75512); /** - * Returns an array of points from the perimeter of the Rectangle, where each point is spaced out based - * on either the `step` value, or the `quantity`. - * - * @function Phaser.Geom.Rectangle.MarchingAnts - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point[]} O - [out,$return] + * 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. * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to get the perimeter points from. - * @param {number} [step] - The distance between each point of the perimeter. Set to `null` if you wish to use the `quantity` parameter instead. - * @param {number} [quantity] - The total number of points to return. The step is then calculated based on the length of the Rectangle, divided by this value. - * @param {(array|Phaser.Geom.Point[])} [out] - An array in which the perimeter points will be stored. If not given, a new array instance is created. + * @method Phaser.GameObjects.IsoTriangle#renderWebGL + * @since 3.13.0 + * @private * - * @return {(array|Phaser.Geom.Point[])} An array containing the perimeter points from the Rectangle. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.IsoTriangle} 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 MarchingAnts = function (rect, step, quantity, out) +var IsoTriangleWebGLRenderer = function (renderer, src, camera, parentMatrix) { - if (out === undefined) { out = []; } - - if (!step && !quantity) - { - // Bail out - return out; - } - - // If step is a falsey value (false, null, 0, undefined, etc) then we calculate - // it based on the quantity instead, otherwise we always use the step value - if (!step) - { - step = Perimeter(rect) / quantity; - } - else - { - quantity = Math.round(Perimeter(rect) / step); - } - - var x = rect.x; - var y = rect.y; - var face = 0; + camera.addToRenderList(src); - // Loop across each face of the rectangle + var pipeline = renderer.pipelines.set(src.pipeline); - for (var i = 0; i < quantity; i++) - { - out.push(new Point(x, y)); + var result = GetCalcMatrix(src, camera, parentMatrix); - switch (face) - { + var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); - // Top face - case 0: - x += step; + var size = src.width; + var height = src.height; - if (x >= rect.right) - { - face = 1; - y += (x - rect.right); - x = rect.right; - } - break; + var sizeA = size / 2; + var sizeB = size / src.projection; - // Right face - case 1: - y += step; + var reversed = src.isReversed; - if (y >= rect.bottom) - { - face = 2; - x -= (y - rect.bottom); - y = rect.bottom; - } - break; + var alpha = camera.alpha * src.alpha; - // Bottom face - case 2: - x -= step; + if (!src.isFilled) + { + return; + } - if (x <= rect.left) - { - face = 3; - y -= (rect.left - x); - x = rect.left; - } - break; + renderer.pipelines.preBatch(src); - // Left face - case 3: - y -= step; + var tint; - if (y <= rect.top) - { - face = 0; - y = rect.top; - } - break; - } - } + var x0; + var y0; - return out; -}; + var x1; + var y1; -module.exports = MarchingAnts; + var x2; + var y2; + // Top Face -/***/ }), -/* 317 */ -/***/ (function(module, exports) { + if (src.showTop && reversed) + { + tint = Utils.getTintAppendFloatAlpha(src.fillTop, alpha); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + x0 = calcMatrix.getX(-sizeA, -height); + y0 = calcMatrix.getY(-sizeA, -height); -/** - * Using Bresenham's line algorithm this will return an array of all coordinates on this line. - * - * The `start` and `end` points are rounded before this runs as the algorithm works on integers. - * - * @function Phaser.Geom.Line.BresenhamPoints - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The line. - * @param {number} [stepRate=1] - The optional step rate for the points on the line. - * @param {Phaser.Types.Math.Vector2Like[]} [results] - An optional array to push the resulting coordinates into. - * - * @return {Phaser.Types.Math.Vector2Like[]} The array of coordinates on the line. - */ -var BresenhamPoints = function (line, stepRate, results) -{ - if (stepRate === undefined) { stepRate = 1; } - if (results === undefined) { results = []; } + x1 = calcMatrix.getX(0, -sizeB - height); + y1 = calcMatrix.getY(0, -sizeB - height); - var x1 = Math.round(line.x1); - var y1 = Math.round(line.y1); - var x2 = Math.round(line.x2); - var y2 = Math.round(line.y2); + x2 = calcMatrix.getX(sizeA, -height); + y2 = calcMatrix.getY(sizeA, -height); - var dx = Math.abs(x2 - x1); - var dy = Math.abs(y2 - y1); - var sx = (x1 < x2) ? 1 : -1; - var sy = (y1 < y2) ? 1 : -1; - var err = dx - dy; + var x3 = calcMatrix.getX(0, sizeB - height); + var y3 = calcMatrix.getY(0, sizeB - height); - results.push({ x: x1, y: y1 }); + pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); + } - var i = 1; + // Left Face - while (!((x1 === x2) && (y1 === y2))) + if (src.showLeft) { - var e2 = err << 1; + tint = Utils.getTintAppendFloatAlpha(src.fillLeft, alpha); - if (e2 > -dy) + if (reversed) { - err -= dy; - x1 += sx; - } + x0 = calcMatrix.getX(-sizeA, -height); + y0 = calcMatrix.getY(-sizeA, -height); - if (e2 < dx) - { - err += dx; - y1 += sy; - } + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); - if (i % stepRate === 0) - { - results.push({ x: x1, y: y1 }); + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); } + else + { + x0 = calcMatrix.getX(-sizeA, 0); + y0 = calcMatrix.getY(-sizeA, 0); - i++; - } - - return results; -}; - -module.exports = BresenhamPoints; - - -/***/ }), -/* 318 */ -/***/ (function(module, exports) { + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); + } -/** - * Searches a pre-sorted array for the closet value to the given number. - * - * If the `key` argument is given it will assume the array contains objects that all have the required `key` property name, - * and will check for the closest value of those to the given number. - * - * @function Phaser.Utils.Array.FindClosestInSorted - * @since 3.0.0 - * - * @param {number} value - The value to search for in the array. - * @param {array} array - The array to search, which must be sorted. - * @param {string} [key] - An optional property key. If specified the array elements property will be checked against value. - * - * @return {(number|any)} The nearest value found in the array, or if a `key` was given, the nearest object with the matching property value. - */ -var FindClosestInSorted = function (value, array, key) -{ - if (!array.length) - { - return NaN; - } - else if (array.length === 1) - { - return array[0]; + pipeline.batchTri(src, x0, y0, x1, y1, x2, y2, 0, 0, 1, 1, tint, tint, tint, 2); } - var i = 1; - var low; - var high; + // Right Face - if (key) + if (src.showRight) { - if (value < array[0][key]) - { - return array[0]; - } + tint = Utils.getTintAppendFloatAlpha(src.fillRight, alpha); - while (array[i][key] < value) + if (reversed) { - i++; + x0 = calcMatrix.getX(sizeA, -height); + y0 = calcMatrix.getY(sizeA, -height); + + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); + + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); } - } - else - { - while (array[i] < value) + else { - i++; - } - } + x0 = calcMatrix.getX(sizeA, 0); + y0 = calcMatrix.getY(sizeA, 0); - if (i > array.length) - { - i = array.length; - } + x1 = calcMatrix.getX(0, sizeB); + y1 = calcMatrix.getY(0, sizeB); - if (key) - { - low = array[i - 1][key]; - high = array[i][key]; + x2 = calcMatrix.getX(0, sizeB - height); + y2 = calcMatrix.getY(0, sizeB - height); + } - return ((high - value) <= (value - low)) ? array[i] : array[i - 1]; + pipeline.batchTri(src, x0, y0, x1, y1, x2, y2, 0, 0, 1, 1, tint, tint, tint, 2); } - else - { - low = array[i - 1]; - high = array[i]; - return ((high - value) <= (value - low)) ? high : low; - } + renderer.pipelines.postBatch(src); }; -module.exports = FindClosestInSorted; +module.exports = IsoTriangleWebGLRenderer; /***/ }), -/* 319 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 579: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); +var Class = __webpack_require__(56694); +var Shape = __webpack_require__(91461); +var GeomLine = __webpack_require__(88829); +var LineRender = __webpack_require__(52660); /** * @classdesc - * A single frame in an Animation sequence. + * 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. * - * An AnimationFrame consists of a reference to the Texture it uses for rendering, references to other - * frames in the animation, and index data. It also has the ability to modify the animation timing. + * This shape supports only stroke colors and cannot be filled. * - * AnimationFrames are generated automatically by the Animation class. + * 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. * - * @class AnimationFrame - * @memberof Phaser.Animations + * 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.0.0 + * @since 3.13.0 * - * @param {string} textureKey - The key of the Texture this AnimationFrame uses. - * @param {(string|number)} textureFrame - The key of the Frame within the Texture that this AnimationFrame uses. - * @param {number} index - The index of this AnimationFrame within the Animation sequence. - * @param {Phaser.Textures.Frame} frame - A reference to the Texture Frame this AnimationFrame uses for rendering. - * @param {boolean} [isKeyFrame=false] - Is this Frame a Keyframe within the Animation? + * @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 AnimationFrame = new Class({ +var Line = new Class({ + + Extends: Shape, + + Mixins: [ + LineRender + ], initialize: - function AnimationFrame (textureKey, textureFrame, index, frame, isKeyFrame) + function Line (scene, x, y, x1, y1, x2, y2, strokeColor, strokeAlpha) { - if (isKeyFrame === undefined) { isKeyFrame = false; } + 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; } - /** - * The key of the Texture this AnimationFrame uses. - * - * @name Phaser.Animations.AnimationFrame#textureKey - * @type {string} - * @since 3.0.0 - */ - this.textureKey = textureKey; + Shape.call(this, scene, 'Line', new GeomLine(x1, y1, x2, y2)); - /** - * The key of the Frame within the Texture that this AnimationFrame uses. - * - * @name Phaser.Animations.AnimationFrame#textureFrame - * @type {(string|number)} - * @since 3.0.0 - */ - this.textureFrame = textureFrame; + var width = Math.max(1, this.geom.right - this.geom.left); + var height = Math.max(1, this.geom.bottom - this.geom.top); /** - * The index of this AnimationFrame within the Animation sequence. + * The width (or thickness) of the line. + * See the setLineWidth method for extra details on changing this on WebGL. * - * @name Phaser.Animations.AnimationFrame#index + * @name Phaser.GameObjects.Line#lineWidth * @type {number} - * @since 3.0.0 - */ - this.index = index; - - /** - * A reference to the Texture Frame this AnimationFrame uses for rendering. - * - * @name Phaser.Animations.AnimationFrame#frame - * @type {Phaser.Textures.Frame} - * @since 3.0.0 - */ - this.frame = frame; - - /** - * Is this the first frame in an animation sequence? - * - * @name Phaser.Animations.AnimationFrame#isFirst - * @type {boolean} - * @default false - * @readonly - * @since 3.0.0 - */ - this.isFirst = false; - - /** - * Is this the last frame in an animation sequence? - * - * @name Phaser.Animations.AnimationFrame#isLast - * @type {boolean} - * @default false - * @readonly - * @since 3.0.0 - */ - this.isLast = false; - - /** - * A reference to the AnimationFrame that comes before this one in the animation, if any. - * - * @name Phaser.Animations.AnimationFrame#prevFrame - * @type {?Phaser.Animations.AnimationFrame} - * @default null - * @readonly - * @since 3.0.0 - */ - this.prevFrame = null; - - /** - * A reference to the AnimationFrame that comes after this one in the animation, if any. - * - * @name Phaser.Animations.AnimationFrame#nextFrame - * @type {?Phaser.Animations.AnimationFrame} - * @default null - * @readonly - * @since 3.0.0 + * @since 3.13.0 */ - this.nextFrame = null; + this.lineWidth = 1; /** - * Additional time (in ms) that this frame should appear for during playback. - * The value is added onto the msPerFrame set by the animation. + * Private internal value. Holds the start width of the line. * - * @name Phaser.Animations.AnimationFrame#duration + * @name Phaser.GameObjects.Line#_startWidth * @type {number} - * @default 0 - * @since 3.0.0 + * @private + * @since 3.13.0 */ - this.duration = 0; + this._startWidth = 1; /** - * What % through the animation does this frame come? - * This value is generated when the animation is created and cached here. + * Private internal value. Holds the end width of the line. * - * @name Phaser.Animations.AnimationFrame#progress + * @name Phaser.GameObjects.Line#_endWidth * @type {number} - * @default 0 - * @readonly - * @since 3.0.0 + * @private + * @since 3.13.0 */ - this.progress = 0; + this._endWidth = 1; - /** - * Is this Frame a KeyFrame within the Animation? - * - * @name Phaser.Animations.AnimationFrame#isKeyFrame - * @type {boolean} - * @since 3.50.0 - */ - this.isKeyFrame = isKeyFrame; + this.setPosition(x, y); + this.setSize(width, height); + + if (strokeColor !== undefined) + { + this.setStrokeStyle(1, strokeColor, strokeAlpha); + } + + this.updateDisplayOrigin(); }, /** - * Generates a JavaScript object suitable for converting to JSON. + * Sets the width of the line. * - * @method Phaser.Animations.AnimationFrame#toJSON - * @since 3.0.0 + * 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. * - * @return {Phaser.Types.Animations.JSONAnimationFrame} The AnimationFrame data. + * 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. */ - toJSON: function () + setLineWidth: function (startWidth, endWidth) { - return { - key: this.textureKey, - frame: this.textureFrame, - duration: this.duration, - keyframe: this.isKeyFrame - }; + if (endWidth === undefined) { endWidth = startWidth; } + + this._startWidth = startWidth; + this._endWidth = endWidth; + + this.lineWidth = startWidth; + + return this; }, /** - * Destroys this object by removing references to external resources and callbacks. + * Sets the start and end coordinates of this Line. * - * @method Phaser.Animations.AnimationFrame#destroy - * @since 3.0.0 + * @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. */ - destroy: function () + setTo: function (x1, y1, x2, y2) { - this.frame = undefined; + this.geom.setTo(x1, y1, x2, y2); + + return this; } }); -module.exports = AnimationFrame; +module.exports = Line; /***/ }), -/* 320 */ -/***/ (function(module, exports) { + +/***/ 52044: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var LineStyleCanvas = __webpack_require__(17876); +var SetTransform = __webpack_require__(49584); + /** - * Takes the given array and runs a numeric sort on it, ignoring any non-digits that - * may be in the entries. - * - * You should only run this on arrays containing strings. - * - * @function Phaser.Utils.Array.SortByDigits - * @since 3.50.0 + * 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. * - * @param {string[]} array - The input array of strings. + * @method Phaser.GameObjects.Line#renderCanvas + * @since 3.13.0 + * @private * - * @return {string[]} The sorted input array. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Line} 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 SortByDigits = function (array) +var LineCanvasRenderer = function (renderer, src, camera, parentMatrix) { - var re = /\D/g; + camera.addToRenderList(src); - array.sort(function (a, b) + var ctx = renderer.currentContext; + + if (SetTransform(renderer, ctx, src, camera, parentMatrix)) { - return (parseInt(a.replace(re, ''), 10) - parseInt(b.replace(re, ''), 10)); - }); + var dx = src._displayOriginX; + var dy = src._displayOriginY; - return array; + if (src.isStroked) + { + LineStyleCanvas(ctx, src); + + ctx.beginPath(); + + ctx.moveTo(src.geom.x1 - dx, src.geom.y1 - dy); + ctx.lineTo(src.geom.x2 - dx, src.geom.y2 - dy); + + ctx.stroke(); + } + + // Restore the context saved in SetTransform + ctx.restore(); + } }; -module.exports = SortByDigits; +module.exports = LineCanvasRenderer; /***/ }), -/* 321 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 85665: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Animation = __webpack_require__(185); -var Class = __webpack_require__(0); -var CustomMap = __webpack_require__(102); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(132); -var GameEvents = __webpack_require__(22); -var GetFastValue = __webpack_require__(2); -var GetValue = __webpack_require__(6); -var Pad = __webpack_require__(186); -var NumberArray = __webpack_require__(322); +var GameObjectFactory = __webpack_require__(61286); +var Line = __webpack_require__(579); /** - * @classdesc - * The Animation Manager. + * Creates a new Line Shape Game Object and adds it to the Scene. * - * Animations are managed by the global Animation Manager. This is a singleton class that is - * responsible for creating and delivering animations and their corresponding data to all Game Objects. - * Unlike plugins it is owned by the Game instance, not the Scene. + * Note: This method will only be available if the Line Game Object has been built into Phaser. * - * Sprites and other Game Objects get the data they need from the AnimationManager. + * 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. * - * @class AnimationManager - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Animations - * @constructor - * @since 3.0.0 + * This shape supports only stroke colors and cannot be filled. * - * @param {Phaser.Game} game - A reference to the Phaser.Game instance. + * 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. + * + * @method Phaser.GameObjects.GameObjectFactory#line + * @since 3.13.0 + * + * @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. + * + * @return {Phaser.GameObjects.Line} The Game Object that was created. */ -var AnimationManager = new Class({ +GameObjectFactory.register('line', function (x, y, x1, y1, x2, y2, strokeColor, strokeAlpha) +{ + return this.displayList.add(new Line(this.scene, x, y, x1, y1, x2, y2, strokeColor, strokeAlpha)); +}); - Extends: EventEmitter, - initialize: +/***/ }), - function AnimationManager (game) - { - EventEmitter.call(this); +/***/ 52660: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A reference to the Phaser.Game instance. - * - * @name Phaser.Animations.AnimationManager#game - * @type {Phaser.Game} - * @protected - * @since 3.0.0 - */ - this.game = game; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A reference to the Texture Manager. - * - * @name Phaser.Animations.AnimationManager#textureManager - * @type {Phaser.Textures.TextureManager} - * @protected - * @since 3.0.0 - */ - this.textureManager = null; +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - /** - * The global time scale of the Animation Manager. - * - * This scales the time delta between two frames, thus influencing the speed of time for the Animation Manager. - * - * @name Phaser.Animations.AnimationManager#globalTimeScale - * @type {number} - * @default 1 - * @since 3.0.0 - */ - this.globalTimeScale = 1; +if (true) +{ + renderWebGL = __webpack_require__(46952); +} - /** - * The Animations registered in the Animation Manager. - * - * This map should be modified with the {@link #add} and {@link #create} methods of the Animation Manager. - * - * @name Phaser.Animations.AnimationManager#anims - * @type {Phaser.Structs.Map.} - * @protected - * @since 3.0.0 - */ - this.anims = new CustomMap(); +if (true) +{ + renderCanvas = __webpack_require__(52044); +} - /** - * A list of animation mix times. - * - * See the {@link #setMix} method for more details. - * - * @name Phaser.Animations.AnimationManager#mixes - * @type {Phaser.Structs.Map.} - * @since 3.50.0 - */ - this.mixes = new CustomMap(); +module.exports = { - /** - * Whether the Animation Manager is paused along with all of its Animations. - * - * @name Phaser.Animations.AnimationManager#paused - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.paused = false; + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - /** - * The name of this Animation Manager. - * - * @name Phaser.Animations.AnimationManager#name - * @type {string} - * @since 3.0.0 - */ - this.name = 'AnimationManager'; +}; - game.events.once(GameEvents.BOOT, this.boot, this); - }, - /** - * Registers event listeners after the Game boots. - * - * @method Phaser.Animations.AnimationManager#boot - * @listens Phaser.Core.Events#DESTROY - * @since 3.0.0 - */ - boot: function () - { - this.textureManager = this.game.textures; +/***/ }), - this.game.events.once(GameEvents.DESTROY, this.destroy, this); - }, +/***/ 46952: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Adds a mix between two animations. - * - * Mixing allows you to specify a unique delay between a pairing of animations. - * - * When playing Animation A on a Game Object, if you then play Animation B, and a - * mix exists, it will wait for the specified delay to be over before playing Animation B. - * - * This allows you to customise smoothing between different types of animation, such - * as blending between an idle and a walk state, or a running and a firing state. - * - * Note that mixing is only applied if you use the `Sprite.play` method. If you opt to use - * `playAfterRepeat` or `playAfterDelay` instead, those will take priority and the mix - * delay will not be used. - * - * To update an existing mix, just call this method with the new delay. - * - * To remove a mix pairing, see the `removeMix` method. - * - * @method Phaser.Animations.AnimationManager#addMix - * @since 3.50.0 - * - * @param {(string|Phaser.Animations.Animation)} animA - The string-based key, or instance of, Animation A. - * @param {(string|Phaser.Animations.Animation)} animB - The string-based key, or instance of, Animation B. - * @param {number} delay - The delay, in milliseconds, to wait when transitioning from Animation A to B. - * - * @return {this} This Animation Manager. - */ - addMix: function (animA, animB, delay) - { - var anims = this.anims; - var mixes = this.mixes; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var keyA = (typeof(animA) === 'string') ? animA : animA.key; - var keyB = (typeof(animB) === 'string') ? animB : animB.key; +var GetCalcMatrix = __webpack_require__(73329); +var Utils = __webpack_require__(75512); - if (anims.has(keyA) && anims.has(keyB)) - { - var mixObj = mixes.get(keyA); +/** + * 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.Line#renderWebGL + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Line} 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 LineWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); - if (!mixObj) - { - mixObj = {}; - } + var pipeline = renderer.pipelines.set(src.pipeline); - mixObj[keyB] = delay; + var result = GetCalcMatrix(src, camera, parentMatrix); - mixes.set(keyA, mixObj); - } + pipeline.calcMatrix.copyFrom(result.calc); - return this; - }, + var dx = src._displayOriginX; + var dy = src._displayOriginY; + var alpha = camera.alpha * src.alpha; - /** - * Removes a mix between two animations. - * - * Mixing allows you to specify a unique delay between a pairing of animations. - * - * Calling this method lets you remove those pairings. You can either remove - * it between `animA` and `animB`, or if you do not provide the `animB` parameter, - * it will remove all `animA` mixes. - * - * If you wish to update an existing mix instead, call the `addMix` method with the - * new delay. - * - * @method Phaser.Animations.AnimationManager#removeMix - * @since 3.50.0 - * - * @param {(string|Phaser.Animations.Animation)} animA - The string-based key, or instance of, Animation A. - * @param {(string|Phaser.Animations.Animation)} [animB] - The string-based key, or instance of, Animation B. If not given, all mixes for Animation A will be removed. - * - * @return {this} This Animation Manager. - */ - removeMix: function (animA, animB) + renderer.pipelines.preBatch(src); + + if (src.isStroked) { - var mixes = this.mixes; + var strokeTint = pipeline.strokeTint; + var color = Utils.getTintAppendFloatAlpha(src.strokeColor, src.strokeAlpha * alpha); - var keyA = (typeof(animA) === 'string') ? animA : animA.key; + strokeTint.TL = color; + strokeTint.TR = color; + strokeTint.BL = color; + strokeTint.BR = color; - var mixObj = mixes.get(keyA); + var startWidth = src._startWidth; + var endWidth = src._endWidth; - if (mixObj) - { - if (animB) - { - var keyB = (typeof(animB) === 'string') ? animB : animB.key; + pipeline.batchLine( + src.geom.x1 - dx, + src.geom.y1 - dy, + src.geom.x2 - dx, + src.geom.y2 - dy, + startWidth, + endWidth, + 1, + 0, + false, + result.sprite, + result.camera + ); + } - if (mixObj.hasOwnProperty(keyB)) - { - // Remove just this pairing - delete mixObj[keyB]; - } - } - else if (!animB) - { - // Remove everything for animA - mixes.delete(keyA); - } - } + renderer.pipelines.postBatch(src); +}; - return this; - }, +module.exports = LineWebGLRenderer; - /** - * Returns the mix delay between two animations. - * - * If no mix has been set-up, this method will return zero. - * - * If you wish to create, or update, a new mix, call the `addMix` method. - * If you wish to remove a mix, call the `removeMix` method. - * - * @method Phaser.Animations.AnimationManager#getMix - * @since 3.50.0 - * - * @param {(string|Phaser.Animations.Animation)} animA - The string-based key, or instance of, Animation A. - * @param {(string|Phaser.Animations.Animation)} animB - The string-based key, or instance of, Animation B. - * - * @return {number} The mix duration, or zero if no mix exists. - */ - getMix: function (animA, animB) - { - var mixes = this.mixes; - var keyA = (typeof(animA) === 'string') ? animA : animA.key; - var keyB = (typeof(animB) === 'string') ? animB : animB.key; +/***/ }), - var mixObj = mixes.get(keyA); +/***/ 91249: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (mixObj && mixObj.hasOwnProperty(keyB)) - { - return mixObj[keyB]; - } - else - { - return 0; - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Adds an existing Animation to the Animation Manager. - * - * @method Phaser.Animations.AnimationManager#add - * @fires Phaser.Animations.Events#ADD_ANIMATION - * @since 3.0.0 - * - * @param {string} key - The key under which the Animation should be added. The Animation will be updated with it. Must be unique. - * @param {Phaser.Animations.Animation} animation - The Animation which should be added to the Animation Manager. - * - * @return {this} This Animation Manager. - */ - add: function (key, animation) +var PolygonRender = __webpack_require__(70573); +var Class = __webpack_require__(56694); +var Earcut = __webpack_require__(11117); +var GetAABB = __webpack_require__(14045); +var GeomPolygon = __webpack_require__(8580); +var Shape = __webpack_require__(91461); +var Smooth = __webpack_require__(18974); + +/** + * @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 (this.anims.has(key)) - { - console.warn('Animation key exists: ' + key); + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } - return this; - } + Shape.call(this, scene, 'Polygon', new GeomPolygon(points)); - animation.key = key; + var bounds = GetAABB(this.geom); - this.anims.set(key, animation); + this.setPosition(x, y); + this.setSize(bounds.width, bounds.height); - this.emit(Events.ADD_ANIMATION, key, animation); + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } - return this; + this.updateDisplayOrigin(); + this.updateData(); }, /** - * Checks to see if the given key is already in use within the Animation Manager or not. - * - * Animations are global. Keys created in one scene can be used from any other Scene in your game. They are not Scene specific. + * 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.Animations.AnimationManager#exists - * @since 3.16.0 + * @method Phaser.GameObjects.Polygon#smooth + * @since 3.13.0 * - * @param {string} key - The key of the Animation to check. + * @param {number} [iterations=1] - The number of times to apply the polygon smoothing. * - * @return {boolean} `true` if the Animation already exists in the Animation Manager, or `false` if the key is available. + * @return {this} This Game Object instance. */ - exists: function (key) + smooth: function (iterations) { - return this.anims.has(key); + if (iterations === undefined) { iterations = 1; } + + for (var i = 0; i < iterations; i++) + { + Smooth(this.geom); + } + + return this.updateData(); }, /** - * Create one, or more animations from a loaded Aseprite JSON file. - * - * Aseprite is a powerful animated sprite editor and pixel art tool. - * - * You can find more details at https://www.aseprite.org/ - * - * To export a compatible JSON file in Aseprite, please do the following: - * - * 1. Go to "File - Export Sprite Sheet" - * - * 2. On the **Layout** tab: - * 2a. Set the "Sheet type" to "Packed" - * 2b. Set the "Constraints" to "None" - * 2c. Check the "Merge Duplicates" checkbox - * - * 3. On the **Sprite** tab: - * 3a. Set "Layers" to "Visible layers" - * 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags - * - * 4. On the **Borders** tab: - * 4a. Check the "Trim Sprite" and "Trim Cells" options - * 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough) - * - * 5. On the **Output** tab: - * 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type - * 5b. Check "JSON Data" and give your json file a name - * 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind. - * 5d. Make sure "Tags" is checked in the Meta options - * 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more. - * - * 6. Click export - * - * This was tested with Aseprite 1.2.25. - * - * This will export a png and json file which you can load using the Aseprite Loader, i.e.: - * - * ```javascript - * function preload () - * { - * this.load.path = 'assets/animations/aseprite/'; - * this.load.aseprite('paladin', 'paladin.png', 'paladin.json'); - * } - * ``` - * - * Once loaded, you can call this method from within a Scene with the 'atlas' key: + * Sets this Polygon to the given points. * - * ```javascript - * this.anims.createFromAseprite('paladin'); - * ``` + * The points can be set from a variety of formats: * - * Any animations defined in the JSON will now be available to use in Phaser and you play them - * via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline, - * you can play it in Phaser using that Tag name: + * - 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 objects: `[new Phaser.Point(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], ...]` * - * ```javascript - * this.add.sprite(400, 300).play('War Cry'); - * ``` + * Calling this method will reset the size (width, height) and display origin of this Shape. * - * When calling this method you can optionally provide an array of tag names, and only those animations - * will be created. For example: + * It also runs both GetAABB and EarCut on the given points, so please be careful not to do this + * at a high frequency, or with too many points. * - * ```javascript - * this.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]); - * ``` + * @method Phaser.GameObjects.Polygon#setTo + * @since 3.60.0 * - * This will only create the 3 animations defined. Note that the tag names are case-sensitive. + * @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - Points defining the perimeter of this polygon. Please check function description above for the different supported formats. * - * @method Phaser.Animations.AnimationManager#createFromAseprite - * @since 3.50.0 + * @return {this} This Game Object instance. + */ + setTo: function (points) + { + this.geom.setTo(points); + + var bounds = GetAABB(this.geom); + + this.setSize(bounds.width, bounds.height); + + this.updateDisplayOrigin(); + + return this.updateData(); + }, + + /** + * Internal method that updates the data and path values. * - * @param {string} key - The key of the loaded Aseprite atlas. It must have been loaded prior to calling this method. - * @param {string[]} [tags] - An array of Tag names. If provided, only animations found in this array will be created. + * @method Phaser.GameObjects.Polygon#updateData + * @private + * @since 3.13.0 * - * @return {Phaser.Animations.Animation[]} An array of Animation instances that were successfully created. + * @return {this} This Game Object instance. */ - createFromAseprite: function (key, tags) + updateData: function () { - var output = []; - - var data = this.game.cache.json.get(key); + var path = []; + var points = this.geom.points; - if (!data) + for (var i = 0; i < points.length; i++) { - return output; + path.push(points[i].x, points[i].y); } - var _this = this; + path.push(points[0].x, points[0].y); - var meta = GetValue(data, 'meta', null); - var frames = GetValue(data, 'frames', null); + this.pathIndexes = Earcut(path); + this.pathData = path; - if (meta && frames) - { - var frameTags = GetValue(meta, 'frameTags', []); + return this; + } - frameTags.forEach(function (tag) - { - var animFrames = []; +}); - var name = GetFastValue(tag, 'name', null); - var from = GetFastValue(tag, 'from', 0); - var to = GetFastValue(tag, 'to', 0); - var direction = GetFastValue(tag, 'direction', 'forward'); +module.exports = Polygon; - if (!name) - { - // Skip if no name - return; - } - if (!tags || (tags && tags.indexOf(name) > -1)) - { - // Get all the frames for this tag - var tempFrames = []; - var minDuration = Number.MAX_SAFE_INTEGER; +/***/ }), - for (var i = from; i <= to; i++) - { - var frameKey = i.toString(); - var frame = frames[frameKey]; +/***/ 40834: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (frame) - { - var frameDuration = GetFastValue(frame, 'duration', Number.MAX_SAFE_INTEGER); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (frameDuration < minDuration) - { - minDuration = frameDuration; - } +var FillStyleCanvas = __webpack_require__(15608); +var LineStyleCanvas = __webpack_require__(17876); +var SetTransform = __webpack_require__(49584); - tempFrames.push({ frame: frameKey, duration: frameDuration }); - } - } +/** + * 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.Polygon#renderCanvas + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Polygon} 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 PolygonCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); - tempFrames.forEach(function (entry) - { - animFrames.push({ - key: key, - frame: entry.frame, - duration: (minDuration - entry.duration) - }); - }); + var ctx = renderer.currentContext; - var totalDuration = (minDuration * animFrames.length); + if (SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + var dx = src._displayOriginX; + var dy = src._displayOriginY; - if (direction === 'reverse') - { - animFrames = animFrames.reverse(); - } + var path = src.pathData; + var pathLength = path.length - 1; - // Create the animation - var createConfig = { - key: name, - frames: animFrames, - duration: totalDuration, - yoyo: (direction === 'pingpong') - }; + var px1 = path[0] - dx; + var py1 = path[1] - dy; - var result = _this.create(createConfig); + ctx.beginPath(); - if (result) - { - output.push(result); - } - } - }); + ctx.moveTo(px1, py1); + + if (!src.closePath) + { + pathLength -= 2; } - return output; - }, + for (var i = 2; i < pathLength; i += 2) + { + var px2 = path[i] - dx; + var py2 = path[i + 1] - dy; - /** - * Creates a new Animation and adds it to the Animation Manager. - * - * Animations are global. Once created, you can use them in any Scene in your game. They are not Scene specific. - * - * If an invalid key is given this method will return `false`. - * - * If you pass the key of an animation that already exists in the Animation Manager, that animation will be returned. - * - * A brand new animation is only created if the key is valid and not already in use. - * - * If you wish to re-use an existing key, call `AnimationManager.remove` first, then this method. - * - * @method Phaser.Animations.AnimationManager#create - * @fires Phaser.Animations.Events#ADD_ANIMATION - * @since 3.0.0 - * - * @param {Phaser.Types.Animations.Animation} config - The configuration settings for the Animation. - * - * @return {(Phaser.Animations.Animation|false)} The Animation that was created, or `false` if the key is already in use. - */ - create: function (config) - { - var key = config.key; + ctx.lineTo(px2, py2); + } - var anim = false; + if (src.closePath) + { + ctx.closePath(); + } - if (key) + if (src.isFilled) { - anim = this.get(key); + FillStyleCanvas(ctx, src); - if (!anim) - { - anim = new Animation(this, key, config); + ctx.fill(); + } - this.anims.set(key, anim); + if (src.isStroked) + { + LineStyleCanvas(ctx, src); - this.emit(Events.ADD_ANIMATION, key, anim); - } + ctx.stroke(); } - return anim; - }, + // Restore the context saved in SetTransform + ctx.restore(); + } +}; - /** - * Loads this Animation Manager's Animations and settings from a JSON object. - * - * @method Phaser.Animations.AnimationManager#fromJSON - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Animations.JSONAnimations|Phaser.Types.Animations.JSONAnimation)} data - The JSON object to parse. - * @param {boolean} [clearCurrentAnimations=false] - If set to `true`, the current animations will be removed (`anims.clear()`). If set to `false` (default), the animations in `data` will be added. - * - * @return {Phaser.Animations.Animation[]} An array containing all of the Animation objects that were created as a result of this call. - */ - fromJSON: function (data, clearCurrentAnimations) - { - if (clearCurrentAnimations === undefined) { clearCurrentAnimations = false; } +module.exports = PolygonCanvasRenderer; - if (clearCurrentAnimations) - { - this.anims.clear(); - } - // Do we have a String (i.e. from JSON, or an Object?) - if (typeof data === 'string') - { - data = JSON.parse(data); - } +/***/ }), - var output = []; +/***/ 88203: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - // Array of animations, or a single animation? - if (data.hasOwnProperty('anims') && Array.isArray(data.anims)) - { - for (var i = 0; i < data.anims.length; i++) - { - output.push(this.create(data.anims[i])); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (data.hasOwnProperty('globalTimeScale')) - { - this.globalTimeScale = data.globalTimeScale; - } - } - else if (data.hasOwnProperty('key') && data.type === 'frame') - { - output.push(this.create(data)); - } +var GameObjectFactory = __webpack_require__(61286); +var Polygon = __webpack_require__(91249); - return output; - }, +/** + * Creates a new Polygon Shape Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Polygon Game Object has been built into Phaser. + * + * 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: + * + * - 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. + * + * @method Phaser.GameObjects.GameObjectFactory#polygon + * @since 3.13.0 + * + * @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. + * + * @return {Phaser.GameObjects.Polygon} The Game Object that was created. + */ +GameObjectFactory.register('polygon', function (x, y, points, fillColor, fillAlpha) +{ + return this.displayList.add(new Polygon(this.scene, x, y, points, fillColor, fillAlpha)); +}); - /** - * Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object. - * - * Generates objects with string based frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNames}. - * - * It's a helper method, designed to make it easier for you to extract all of the frame names from texture atlases. - * If you're working with a sprite sheet, see the `generateFrameNumbers` method instead. - * - * Example: - * - * If you have a texture atlases loaded called `gems` and it contains 6 frames called `ruby_0001`, `ruby_0002`, and so on, - * then you can call this method using: `this.anims.generateFrameNames('gems', { prefix: 'ruby_', end: 6, zeroPad: 4 })`. - * - * The `end` value tells it to look for 6 frames, incrementally numbered, all starting with the prefix `ruby_`. The `zeroPad` - * value tells it how many zeroes pad out the numbers. To create an animation using this method, you can do: - * - * ```javascript - * this.anims.create({ - * key: 'ruby', - * repeat: -1, - * frames: this.anims.generateFrameNames('gems', { - * prefix: 'ruby_', - * end: 6, - * zeroPad: 4 - * }) - * }); - * ``` - * - * Please see the animation examples for further details. - * - * @method Phaser.Animations.AnimationManager#generateFrameNames - * @since 3.0.0 - * - * @param {string} key - The key for the texture containing the animation frames. - * @param {Phaser.Types.Animations.GenerateFrameNames} [config] - The configuration object for the animation frame names. - * - * @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects. - */ - generateFrameNames: function (key, config) - { - var prefix = GetValue(config, 'prefix', ''); - var start = GetValue(config, 'start', 0); - var end = GetValue(config, 'end', 0); - var suffix = GetValue(config, 'suffix', ''); - var zeroPad = GetValue(config, 'zeroPad', 0); - var out = GetValue(config, 'outputArray', []); - var frames = GetValue(config, 'frames', false); - var texture = this.textureManager.get(key); +/***/ }), - if (!texture) - { - return out; - } +/***/ 70573: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var i; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (!config) - { - // Use every frame in the atlas - frames = texture.getFrameNames(); +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - for (i = 0; i < frames.length; i++) - { - out.push({ key: key, frame: frames[i] }); - } - } - else - { - if (!frames) - { - frames = NumberArray(start, end); - } +if (true) +{ + renderWebGL = __webpack_require__(72841); +} - for (i = 0; i < frames.length; i++) - { - var frame = prefix + Pad(frames[i], zeroPad, '0', 1) + suffix; +if (true) +{ + renderCanvas = __webpack_require__(40834); +} - if (texture.has(frame)) - { - out.push({ key: key, frame: frame }); - } - else - { - console.warn('generateFrameNames: Frame missing: ' + frame + ' from texture: ' + key); - } - } - } +module.exports = { - return out; - }, + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - /** - * Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object. - * - * Generates objects with numbered frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNumbers}. - * - * If you're working with a texture atlas, see the `generateFrameNames` method instead. - * - * It's a helper method, designed to make it easier for you to extract frames from sprite sheets. - * If you're working with a texture atlas, see the `generateFrameNames` method instead. - * - * Example: - * - * If you have a sprite sheet loaded called `explosion` and it contains 12 frames, then you can call this method using: - * - * `this.anims.generateFrameNumbers('explosion', { start: 0, end: 11 })`. - * - * The `end` value of 11 tells it to stop after the 12th frame has been added, because it started at zero. - * - * To create an animation using this method, you can do: - * - * ```javascript - * this.anims.create({ - * key: 'boom', - * frames: this.anims.generateFrameNames('explosion', { - * start: 0, - * end: 11 - * }) - * }); - * ``` - * - * Note that `start` is optional and you don't need to include it if the animation starts from frame 0. - * - * To specify an animation in reverse, swap the `start` and `end` values. - * - * If the frames are not sequential, you may pass an array of frame numbers instead, for example: - * - * `this.anims.generateFrameNumbers('explosion', { frames: [ 0, 1, 2, 1, 2, 3, 4, 0, 1, 2 ] })` - * - * Please see the animation examples and `GenerateFrameNumbers` config docs for further details. - * - * @method Phaser.Animations.AnimationManager#generateFrameNumbers - * @since 3.0.0 - * - * @param {string} key - The key for the texture containing the animation frames. - * @param {Phaser.Types.Animations.GenerateFrameNumbers} config - The configuration object for the animation frames. - * - * @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects. - */ - generateFrameNumbers: function (key, config) - { - var start = GetValue(config, 'start', 0); - var end = GetValue(config, 'end', -1); - var first = GetValue(config, 'first', false); - var out = GetValue(config, 'outputArray', []); - var frames = GetValue(config, 'frames', false); +}; - var texture = this.textureManager.get(key); - if (!texture) - { - return out; - } +/***/ }), - if (first && texture.has(first)) - { - out.push({ key: key, frame: first }); - } +/***/ 72841: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // No 'frames' array? Then generate one automatically - if (!frames) - { - if (end === -1) - { - // -1 because of __BASE, which we don't want in our results - // and -1 because frames are zero based - end = texture.frameTotal - 2; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - frames = NumberArray(start, end); - } +var FillPathWebGL = __webpack_require__(19543); +var GetCalcMatrix = __webpack_require__(73329); +var StrokePathWebGL = __webpack_require__(50262); - for (var i = 0; i < frames.length; i++) - { - if (texture.has(frames[i])) - { - out.push({ key: key, frame: frames[i] }); - } - else - { - console.warn('generateFrameNumbers: Frame ' + i + ' missing from texture: ' + key); - } - } +/** + * 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.Polygon#renderWebGL + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Polygon} 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 PolygonWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); - return out; - }, + var pipeline = renderer.pipelines.set(src.pipeline); - /** - * Get an Animation. - * - * @method Phaser.Animations.AnimationManager#get - * @since 3.0.0 - * - * @param {string} key - The key of the Animation to retrieve. - * - * @return {Phaser.Animations.Animation} The Animation. - */ - get: function (key) + var result = GetCalcMatrix(src, camera, parentMatrix); + + var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); + + var dx = src._displayOriginX; + var dy = src._displayOriginY; + + var alpha = camera.alpha * src.alpha; + + renderer.pipelines.preBatch(src); + + if (src.isFilled) { - return this.anims.get(key); - }, + FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); + } - /** - * Pause all animations. - * - * @method Phaser.Animations.AnimationManager#pauseAll - * @fires Phaser.Animations.Events#PAUSE_ALL - * @since 3.0.0 - * - * @return {this} This Animation Manager. - */ - pauseAll: function () + if (src.isStroked) { - if (!this.paused) - { - this.paused = true; + StrokePathWebGL(pipeline, src, alpha, dx, dy); + } - this.emit(Events.PAUSE_ALL); - } + renderer.pipelines.postBatch(src); +}; - return this; - }, +module.exports = PolygonWebGLRenderer; - /** - * Play an animation on the given Game Objects that have an Animation Component. - * - * @method Phaser.Animations.AnimationManager#play - * @since 3.0.0 - * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} children - An array of Game Objects to play the animation on. They must have an Animation Component. - * - * @return {this} This Animation Manager. - */ - play: function (key, children) - { - if (!Array.isArray(children)) - { - children = [ children ]; - } - for (var i = 0; i < children.length; i++) - { - children[i].anims.play(key); - } +/***/ }), - return this; - }, +/***/ 517: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Takes an array of Game Objects that have an Animation Component and then - * starts the given animation playing on them. The start time of each Game Object - * is offset, incrementally, by the `stagger` amount. - * - * For example, if you pass an array with 4 children and a stagger time of 1000, - * the delays will be: - * - * child 1: 1000ms delay - * child 2: 2000ms delay - * child 3: 3000ms delay - * child 4: 4000ms delay - * - * If you set the `staggerFirst` parameter to `false` they would be: - * - * child 1: 0ms delay - * child 2: 1000ms delay - * child 3: 2000ms delay - * child 4: 3000ms delay - * - * You can also set `stagger` to be a negative value. If it was -1000, the above would be: - * - * child 1: 3000ms delay - * child 2: 2000ms delay - * child 3: 1000ms delay - * child 4: 0ms delay - * - * @method Phaser.Animations.AnimationManager#staggerPlay - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} children - An array of Game Objects to play the animation on. They must have an Animation Component. - * @param {number} stagger - The amount of time, in milliseconds, to offset each play time by. If a negative value is given, it's applied to the children in reverse order. - * @param {boolean} [staggerFirst=true] -Should the first child be staggered as well? - * - * @return {this} This Animation Manager. - */ - staggerPlay: function (key, children, stagger, staggerFirst) - { - if (stagger === undefined) { stagger = 0; } - if (staggerFirst === undefined) { staggerFirst = true; } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (!Array.isArray(children)) - { - children = [ children ]; - } +var Class = __webpack_require__(56694); +var GeomRectangle = __webpack_require__(74118); +var Shape = __webpack_require__(91461); +var RectangleRender = __webpack_require__(37673); - var len = children.length; +/** + * @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({ - if (!staggerFirst) - { - len--; - } + Extends: Shape, - for (var i = 0; i < children.length; i++) - { - var time = (stagger < 0) ? Math.abs(stagger) * (len - i) : stagger * i; + Mixins: [ + RectangleRender + ], - children[i].anims.playAfterDelay(key, time); + 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); } - return this; + this.updateDisplayOrigin(); + this.updateData(); }, /** - * Removes an Animation from this Animation Manager, based on the given key. + * Sets the internal size of this Rectangle, as used for frame or physics body creation. * - * This is a global action. Once an Animation has been removed, no Game Objects - * can carry on using it. + * If you have assigned a custom input hit area for this Rectangle, changing the Rectangle size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * - * @method Phaser.Animations.AnimationManager#remove - * @fires Phaser.Animations.Events#REMOVE_ANIMATION - * @since 3.0.0 + * @method Phaser.GameObjects.Rectangle#setSize + * @since 3.13.0 * - * @param {string} key - The key of the animation to remove. + * @param {number} width - The width of this Game Object. + * @param {number} height - The height of this Game Object. * - * @return {Phaser.Animations.Animation} The Animation instance that was removed from the Animation Manager. + * @return {this} This Game Object instance. */ - remove: function (key) + setSize: function (width, height) { - var anim = this.get(key); + this.width = width; + this.height = height; - if (anim) - { - this.emit(Events.REMOVE_ANIMATION, key, anim); + this.geom.setSize(width, height); - this.anims.delete(key); + this.updateData(); - this.removeMix(key); - } + this.updateDisplayOrigin(); - return anim; - }, + var input = this.input; - /** - * Resume all paused animations. - * - * @method Phaser.Animations.AnimationManager#resumeAll - * @fires Phaser.Animations.Events#RESUME_ALL - * @since 3.0.0 - * - * @return {this} This Animation Manager. - */ - resumeAll: function () - { - if (this.paused) + if (input && !input.customHitArea) { - this.paused = false; - - this.emit(Events.RESUME_ALL); + input.hitArea.width = width; + input.hitArea.height = height; } return this; }, /** - * Returns the Animation data as JavaScript object based on the given key. - * Or, if not key is defined, it will return the data of all animations as array of objects. - * - * @method Phaser.Animations.AnimationManager#toJSON - * @since 3.0.0 + * Internal method that updates the data and path values. * - * @param {string} [key] - The animation to get the JSONAnimation data from. If not provided, all animations are returned as an array. + * @method Phaser.GameObjects.Rectangle#updateData + * @private + * @since 3.13.0 * - * @return {Phaser.Types.Animations.JSONAnimations} The resulting JSONAnimations formatted object. + * @return {this} This Game Object instance. */ - toJSON: function (key) + updateData: function () { - var output = { - anims: [], - globalTimeScale: this.globalTimeScale - }; + var path = []; + var rect = this.geom; + var line = this._tempLine; - if (key !== undefined && key !== '') - { - output.anims.push(this.anims.get(key).toJSON()); - } - else - { - this.anims.each(function (animationKey, animation) - { - output.anims.push(animation.toJSON()); - }); - } + rect.getLineA(line); - return output; - }, + path.push(line.x1, line.y1, line.x2, line.y2); - /** - * Destroy this Animation Manager and clean up animation definitions and references to other objects. - * This method should not be called directly. It will be called automatically as a response to a `destroy` event from the Phaser.Game instance. - * - * @method Phaser.Animations.AnimationManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.anims.clear(); - this.mixes.clear(); + rect.getLineB(line); - this.textureManager = null; + path.push(line.x2, line.y2); - this.game = null; + 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 = AnimationManager; +module.exports = Rectangle; /***/ }), -/* 322 */ -/***/ (function(module, exports) { + +/***/ 4091: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var FillStyleCanvas = __webpack_require__(15608); +var LineStyleCanvas = __webpack_require__(17876); +var SetTransform = __webpack_require__(49584); + /** - * Create an array representing the range of numbers (usually integers), between, and inclusive of, - * the given `start` and `end` arguments. For example: - * - * `var array = Phaser.Utils.Array.NumberArray(2, 4); // array = [2, 3, 4]` - * `var array = Phaser.Utils.Array.NumberArray(0, 9); // array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]` - * `var array = Phaser.Utils.Array.NumberArray(8, 2); // array = [8, 7, 6, 5, 4, 3, 2]` - * - * This is equivalent to `Phaser.Utils.Array.NumberArrayStep(start, end, 1)`. - * - * You can optionally provide a prefix and / or suffix string. If given the array will contain - * strings, not integers. For example: - * - * `var array = Phaser.Utils.Array.NumberArray(1, 4, 'Level '); // array = ["Level 1", "Level 2", "Level 3", "Level 4"]` - * `var array = Phaser.Utils.Array.NumberArray(5, 7, 'HD-', '.png'); // array = ["HD-5.png", "HD-6.png", "HD-7.png"]` - * - * @function Phaser.Utils.Array.NumberArray - * @since 3.0.0 + * 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. * - * @param {number} start - The minimum value the array starts with. - * @param {number} end - The maximum value the array contains. - * @param {string} [prefix] - Optional prefix to place before the number. If provided the array will contain strings, not integers. - * @param {string} [suffix] - Optional suffix to place after the number. If provided the array will contain strings, not integers. + * @method Phaser.GameObjects.Rectangle#renderCanvas + * @since 3.13.0 + * @private * - * @return {(number[]|string[])} The array of number values, or strings if a prefix or suffix was provided. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Rectangle} 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 NumberArray = function (start, end, prefix, suffix) +var RectangleCanvasRenderer = function (renderer, src, camera, parentMatrix) { - var result = []; + camera.addToRenderList(src); - var i; - var asString = false; + var ctx = renderer.currentContext; - if (prefix || suffix) + if (SetTransform(renderer, ctx, src, camera, parentMatrix)) { - asString = true; + var dx = src._displayOriginX; + var dy = src._displayOriginY; - if (!prefix) + if (src.isFilled) { - prefix = ''; - } + FillStyleCanvas(ctx, src); - if (!suffix) - { - suffix = ''; + ctx.fillRect( + -dx, + -dy, + src.width, + src.height + ); } - } - if (end < start) - { - for (i = start; i >= end; i--) + if (src.isStroked) { - if (asString) - { - result.push(prefix + i.toString() + suffix); - } - else - { - result.push(i); - } + LineStyleCanvas(ctx, src); + + ctx.beginPath(); + + ctx.rect( + -dx, + -dy, + src.width, + src.height + ); + + ctx.stroke(); } + + // Restore the context saved in SetTransform + ctx.restore(); } - else +}; + +module.exports = RectangleCanvasRenderer; + + +/***/ }), + +/***/ 94355: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GameObjectFactory = __webpack_require__(61286); +var Rectangle = __webpack_require__(517); + +/** + * Creates a new Rectangle Shape Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Rectangle Game Object has been built into Phaser. + * + * 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. + * + * @method Phaser.GameObjects.GameObjectFactory#rectangle + * @since 3.13.0 + * + * @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 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. + * + * @return {Phaser.GameObjects.Rectangle} The Game Object that was created. + */ +GameObjectFactory.register('rectangle', function (x, y, width, height, fillColor, fillAlpha) +{ + return this.displayList.add(new Rectangle(this.scene, x, y, width, height, fillColor, fillAlpha)); +}); + + +/***/ }), + +/***/ 37673: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(43532); +} + +if (true) +{ + renderCanvas = __webpack_require__(4091); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 43532: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetCalcMatrix = __webpack_require__(73329); +var StrokePathWebGL = __webpack_require__(50262); +var Utils = __webpack_require__(75512); + +/** + * 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.Rectangle#renderWebGL + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Rectangle} 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 RectangleWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); + + var pipeline = renderer.pipelines.set(src.pipeline); + + var result = GetCalcMatrix(src, camera, parentMatrix); + + pipeline.calcMatrix.copyFrom(result.calc); + + var dx = src._displayOriginX; + var dy = src._displayOriginY; + var alpha = camera.alpha * src.alpha; + + renderer.pipelines.preBatch(src); + + if (src.isFilled) { - for (i = start; i <= end; i++) - { - if (asString) - { - result.push(prefix + i.toString() + suffix); - } - else - { - result.push(i); - } - } + var fillTint = pipeline.fillTint; + var fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha); + + fillTint.TL = fillTintColor; + fillTint.TR = fillTintColor; + fillTint.BL = fillTintColor; + fillTint.BR = fillTintColor; + + pipeline.batchFillRect( + -dx, + -dy, + src.width, + src.height + ); } - return result; + if (src.isStroked) + { + StrokePathWebGL(pipeline, src, alpha, dx, dy); + } + + renderer.pipelines.postBatch(src); }; -module.exports = NumberArray; +module.exports = RectangleWebGLRenderer; /***/ }), -/* 323 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 77843: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CustomMap = __webpack_require__(102); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(324); +var StarRender = __webpack_require__(87956); +var Class = __webpack_require__(56694); +var Earcut = __webpack_require__(11117); +var Shape = __webpack_require__(91461); /** * @classdesc - * The BaseCache is a base Cache class that can be used for storing references to any kind of data. + * 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. * - * Data can be added, retrieved and removed based on the given keys. + * This shape supports both fill and stroke colors. * - * Keys are string-based. + * 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. * - * @class BaseCache - * @memberof Phaser.Cache + * 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.0.0 + * @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 BaseCache = new Class({ +var Star = new Class({ + + Extends: Shape, + + Mixins: [ + StarRender + ], initialize: - function BaseCache () + 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); + /** - * The Map in which the cache objects are stored. + * Private internal value. + * The number of points in the star. * - * You can query the Map directly or use the BaseCache methods. + * @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.Cache.BaseCache#entries - * @type {Phaser.Structs.Map.} - * @since 3.0.0 + * @name Phaser.GameObjects.Star#_innerRadius + * @type {number} + * @private + * @since 3.13.0 */ - this.entries = new CustomMap(); + this._innerRadius = innerRadius; /** - * An instance of EventEmitter used by the cache to emit related events. + * Private internal value. + * The outer radius of the star. * - * @name Phaser.Cache.BaseCache#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 + * @name Phaser.GameObjects.Star#_outerRadius + * @type {number} + * @private + * @since 3.13.0 */ - this.events = new EventEmitter(); + this._outerRadius = outerRadius; + + this.setPosition(x, y); + this.setSize(outerRadius * 2, outerRadius * 2); + + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } + + this.updateDisplayOrigin(); + this.updateData(); }, /** - * Adds an item to this cache. The item is referenced by a unique string, which you are responsible - * for setting and keeping track of. The item can only be retrieved by using this string. + * Sets the number of points that make up the Star shape. + * This call can be chained. * - * @method Phaser.Cache.BaseCache#add - * @fires Phaser.Cache.Events#ADD - * @since 3.0.0 + * @method Phaser.GameObjects.Star#setPoints + * @since 3.13.0 * - * @param {string} key - The unique key by which the data added to the cache will be referenced. - * @param {*} data - The data to be stored in the cache. + * @param {number} value - The amount of points the Star will have. * - * @return {this} This BaseCache object. + * @return {this} This Game Object instance. */ - add: function (key, data) + setPoints: function (value) { - this.entries.set(key, data); - - this.events.emit(Events.ADD, this, key, data); + this._points = value; - return this; + return this.updateData(); }, /** - * Checks if this cache contains an item matching the given key. - * This performs the same action as `BaseCache.exists`. + * Sets the inner radius of the Star shape. + * This call can be chained. * - * @method Phaser.Cache.BaseCache#has - * @since 3.0.0 + * @method Phaser.GameObjects.Star#setInnerRadius + * @since 3.13.0 * - * @param {string} key - The unique key of the item to be checked in this cache. + * @param {number} value - The amount to set the inner radius to. * - * @return {boolean} Returns `true` if the cache contains an item matching the given key, otherwise `false`. + * @return {this} This Game Object instance. */ - has: function (key) + setInnerRadius: function (value) { - return this.entries.has(key); + this._innerRadius = value; + + return this.updateData(); }, /** - * Checks if this cache contains an item matching the given key. - * This performs the same action as `BaseCache.has` and is called directly by the Loader. + * Sets the outer radius of the Star shape. + * This call can be chained. * - * @method Phaser.Cache.BaseCache#exists - * @since 3.7.0 + * @method Phaser.GameObjects.Star#setOuterRadius + * @since 3.13.0 * - * @param {string} key - The unique key of the item to be checked in this cache. + * @param {number} value - The amount to set the outer radius to. * - * @return {boolean} Returns `true` if the cache contains an item matching the given key, otherwise `false`. + * @return {this} This Game Object instance. */ - exists: function (key) + setOuterRadius: function (value) { - return this.entries.has(key); + this._outerRadius = value; + + return this.updateData(); }, /** - * Gets an item from this cache based on the given key. - * - * @method Phaser.Cache.BaseCache#get - * @since 3.0.0 - * - * @param {string} key - The unique key of the item to be retrieved from this cache. + * The number of points that make up the Star shape. * - * @return {*} The item in the cache, or `null` if no item matching the given key was found. + * @name Phaser.GameObjects.Star#points + * @type {number} + * @default 5 + * @since 3.13.0 */ - get: function (key) - { - return this.entries.get(key); + points: { + + get: function () + { + return this._points; + }, + + set: function (value) + { + this._points = value; + + this.updateData(); + } + }, /** - * Removes and item from this cache based on the given key. - * - * If an entry matching the key is found it is removed from the cache and a `remove` event emitted. - * No additional checks are done on the item removed. If other systems or parts of your game code - * are relying on this item, it is up to you to sever those relationships prior to removing the item. - * - * @method Phaser.Cache.BaseCache#remove - * @fires Phaser.Cache.Events#REMOVE - * @since 3.0.0 - * - * @param {string} key - The unique key of the item to remove from the cache. + * The inner radius of the Star shape. * - * @return {this} This BaseCache object. + * @name Phaser.GameObjects.Star#innerRadius + * @type {number} + * @default 32 + * @since 3.13.0 */ - remove: function (key) - { - var entry = this.get(key); + innerRadius: { - if (entry) + get: function () { - this.entries.delete(key); + return this._innerRadius; + }, - this.events.emit(Events.REMOVE, this, key, entry.data); + set: function (value) + { + this._innerRadius = value; + + this.updateData(); } - return this; }, /** - * Returns all keys in use in this cache. - * - * @method Phaser.Cache.BaseCache#getKeys - * @since 3.17.0 + * The outer radius of the Star shape. * - * @return {string[]} Array containing all the keys. + * @name Phaser.GameObjects.Star#outerRadius + * @type {number} + * @default 64 + * @since 3.13.0 */ - getKeys: function () - { - return this.entries.keys(); + outerRadius: { + + get: function () + { + return this._outerRadius; + }, + + set: function (value) + { + this._outerRadius = value; + + this.updateData(); + } + }, /** - * Destroys this cache and all items within it. + * Internal method that updates the data and path values. * - * @method Phaser.Cache.BaseCache#destroy - * @since 3.0.0 + * @method Phaser.GameObjects.Star#updateData + * @private + * @since 3.13.0 + * + * @return {this} This Game Object instance. */ - destroy: function () + updateData: function () { - this.entries.clear(); - this.events.removeAllListeners(); + var path = []; - this.entries = null; - this.events = null; + 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 = BaseCache; +module.exports = Star; /***/ }), -/* 324 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 11401: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var FillStyleCanvas = __webpack_require__(15608); +var LineStyleCanvas = __webpack_require__(17876); +var SetTransform = __webpack_require__(49584); + /** - * @namespace Phaser.Cache.Events + * 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.Star#renderCanvas + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Star} 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 StarCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); -module.exports = { + var ctx = renderer.currentContext; + + if (SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + var dx = src._displayOriginX; + var dy = src._displayOriginY; + + var path = src.pathData; + var pathLength = path.length - 1; + + var px1 = path[0] - dx; + var py1 = path[1] - dy; + + ctx.beginPath(); + + ctx.moveTo(px1, py1); + + if (!src.closePath) + { + pathLength -= 2; + } + + for (var i = 2; i < pathLength; i += 2) + { + var px2 = path[i] - dx; + var py2 = path[i + 1] - dy; + + ctx.lineTo(px2, py2); + } + + ctx.closePath(); + + if (src.isFilled) + { + FillStyleCanvas(ctx, src); + + ctx.fill(); + } + + if (src.isStroked) + { + LineStyleCanvas(ctx, src); - ADD: __webpack_require__(736), - REMOVE: __webpack_require__(737) + ctx.stroke(); + } + // Restore the context saved in SetTransform + ctx.restore(); + } }; +module.exports = StarCanvasRenderer; + /***/ }), -/* 325 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 23962: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BaseCache = __webpack_require__(323); -var Class = __webpack_require__(0); -var GameEvents = __webpack_require__(22); +var Star = __webpack_require__(77843); +var GameObjectFactory = __webpack_require__(61286); /** - * @classdesc - * The Cache Manager is the global cache owned and maintained by the Game instance. + * Creates a new Star Shape Game Object and adds it to the Scene. * - * Various systems, such as the file Loader, rely on this cache in order to store the files - * it has loaded. The manager itself doesn't store any files, but instead owns multiple BaseCache - * instances, one per type of file. You can also add your own custom caches. + * Note: This method will only be available if the Star Game Object has been built into Phaser. * - * @class CacheManager - * @memberof Phaser.Cache - * @constructor - * @since 3.0.0 + * 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. * - * @param {Phaser.Game} game - A reference to the Phaser.Game instance that owns this CacheManager. + * 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. + * + * @method Phaser.GameObjects.GameObjectFactory#star + * @since 3.13.0 + * + * @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. + * + * @return {Phaser.GameObjects.Star} The Game Object that was created. */ -var CacheManager = new Class({ +GameObjectFactory.register('star', function (x, y, points, innerRadius, outerRadius, fillColor, fillAlpha) +{ + return this.displayList.add(new Star(this.scene, x, y, points, innerRadius, outerRadius, fillColor, fillAlpha)); +}); - initialize: - function CacheManager (game) - { - /** - * A reference to the Phaser.Game instance that owns this CacheManager. - * - * @name Phaser.Cache.CacheManager#game - * @type {Phaser.Game} - * @protected - * @since 3.0.0 - */ - this.game = game; +/***/ }), - /** - * A Cache storing all binary files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#binary - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.binary = new BaseCache(); +/***/ 87956: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A Cache storing all bitmap font data files, typically added via the Loader. - * Only the font data is stored in this cache, the textures are part of the Texture Manager. - * - * @name Phaser.Cache.CacheManager#bitmapFont - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.bitmapFont = new BaseCache(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A Cache storing all JSON data files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#json - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.json = new BaseCache(); +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - /** - * A Cache storing all physics data files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#physics - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.physics = new BaseCache(); +if (true) +{ + renderWebGL = __webpack_require__(12037); +} - /** - * A Cache storing all shader source files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#shader - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.shader = new BaseCache(); +if (true) +{ + renderCanvas = __webpack_require__(11401); +} - /** - * A Cache storing all non-streaming audio files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#audio - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.audio = new BaseCache(); +module.exports = { - /** - * A Cache storing all non-streaming video files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#video - * @type {Phaser.Cache.BaseCache} - * @since 3.20.0 - */ - this.video = new BaseCache(); + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - /** - * A Cache storing all text files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#text - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.text = new BaseCache(); +}; - /** - * A Cache storing all html files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#html - * @type {Phaser.Cache.BaseCache} - * @since 3.12.0 - */ - this.html = new BaseCache(); - /** - * A Cache storing all WaveFront OBJ files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#obj - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.obj = new BaseCache(); +/***/ }), - /** - * A Cache storing all tilemap data files, typically added via the Loader. - * Only the data is stored in this cache, the textures are part of the Texture Manager. - * - * @name Phaser.Cache.CacheManager#tilemap - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.tilemap = new BaseCache(); +/***/ 12037: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A Cache storing all xml data files, typically added via the Loader. - * - * @name Phaser.Cache.CacheManager#xml - * @type {Phaser.Cache.BaseCache} - * @since 3.0.0 - */ - this.xml = new BaseCache(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * An object that contains your own custom BaseCache entries. - * Add to this via the `addCustom` method. - * - * @name Phaser.Cache.CacheManager#custom - * @type {Object.} - * @since 3.0.0 - */ - this.custom = {}; +var FillPathWebGL = __webpack_require__(19543); +var GetCalcMatrix = __webpack_require__(73329); +var StrokePathWebGL = __webpack_require__(50262); - this.game.events.once(GameEvents.DESTROY, this.destroy, this); - }, +/** + * 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.Star#renderWebGL + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Star} 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 StarWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); - /** - * Add your own custom Cache for storing your own files. - * The cache will be available under `Cache.custom.key`. - * The cache will only be created if the key is not already in use. - * - * @method Phaser.Cache.CacheManager#addCustom - * @since 3.0.0 - * - * @param {string} key - The unique key of your custom cache. - * - * @return {Phaser.Cache.BaseCache} A reference to the BaseCache that was created. If the key was already in use, a reference to the existing cache is returned instead. - */ - addCustom: function (key) - { - if (!this.custom.hasOwnProperty(key)) - { - this.custom[key] = new BaseCache(); - } + var pipeline = renderer.pipelines.set(src.pipeline); - return this.custom[key]; - }, + var result = GetCalcMatrix(src, camera, parentMatrix); - /** - * Removes all entries from all BaseCaches and destroys all custom caches. - * - * @method Phaser.Cache.CacheManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - var keys = [ - 'binary', - 'bitmapFont', - 'json', - 'physics', - 'shader', - 'audio', - 'video', - 'text', - 'html', - 'obj', - 'tilemap', - 'xml' - ]; + var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); - for (var i = 0; i < keys.length; i++) - { - this[keys[i]].destroy(); - this[keys[i]] = null; - } + var dx = src._displayOriginX; + var dy = src._displayOriginY; - for (var key in this.custom) - { - this.custom[key].destroy(); - } + var alpha = camera.alpha * src.alpha; - this.custom = null; + renderer.pipelines.preBatch(src); - this.game = null; + if (src.isFilled) + { + FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); } -}); + if (src.isStroked) + { + StrokePathWebGL(pipeline, src, alpha, dx, dy); + } -module.exports = CacheManager; + renderer.pipelines.postBatch(src); +}; + +module.exports = StarWebGLRenderer; /***/ }), -/* 326 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 21873: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BaseCamera = __webpack_require__(133); -var CenterOn = __webpack_require__(190); -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var Effects = __webpack_require__(333); -var Events = __webpack_require__(37); -var Linear = __webpack_require__(135); -var Rectangle = __webpack_require__(10); -var Vector2 = __webpack_require__(3); +var Class = __webpack_require__(56694); +var Shape = __webpack_require__(91461); +var GeomTriangle = __webpack_require__(66349); +var TriangleRender = __webpack_require__(70498); /** * @classdesc - * A Camera. - * - * The Camera is the way in which all games are rendered in Phaser. They provide a view into your game world, - * and can be positioned, rotated, zoomed and scrolled accordingly. - * - * A Camera consists of two elements: The viewport and the scroll values. - * - * The viewport is the physical position and size of the Camera within your game. Cameras, by default, are - * created the same size as your game, but their position and size can be set to anything. This means if you - * wanted to create a camera that was 320x200 in size, positioned in the bottom-right corner of your game, - * you'd adjust the viewport to do that (using methods like `setViewport` and `setSize`). - * - * If you wish to change where the Camera is looking in your game, then you scroll it. You can do this - * via the properties `scrollX` and `scrollY` or the method `setScroll`. Scrolling has no impact on the - * viewport, and changing the viewport has no impact on the scrolling. + * 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. * - * By default a Camera will render all Game Objects it can see. You can change this using the `ignore` method, - * allowing you to filter Game Objects out on a per-Camera basis. + * This shape supports both fill and stroke colors. * - * A Camera also has built-in special effects including Fade, Flash and Camera Shake. + * 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 Camera - * @memberof Phaser.Cameras.Scene2D + * @class Triangle + * @extends Phaser.GameObjects.Shape + * @memberof Phaser.GameObjects * @constructor - * @since 3.0.0 - * - * @extends Phaser.Cameras.Scene2D.BaseCamera - * @extends Phaser.GameObjects.Components.Flip - * @extends Phaser.GameObjects.Components.Tint - * @extends Phaser.GameObjects.Components.Pipeline + * @since 3.13.0 * - * @param {number} x - The x position of the Camera, relative to the top-left of the game canvas. - * @param {number} y - The y position of the Camera, relative to the top-left of the game canvas. - * @param {number} width - The width of the Camera, in pixels. - * @param {number} height - The height of the Camera, in pixels. + * @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 Camera = new Class({ +var Triangle = new Class({ - Extends: BaseCamera, + Extends: Shape, Mixins: [ - Components.Flip, - Components.Tint, - Components.Pipeline + TriangleRender ], initialize: - function Camera (x, y, width, height) + function Triangle (scene, x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha) { - BaseCamera.call(this, x, y, width, height); + 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; } - this.postPipelines = []; - this.pipelineData = {}; + Shape.call(this, scene, 'Triangle', new GeomTriangle(x1, y1, x2, y2, x3, y3)); - /** - * Does this Camera allow the Game Objects it renders to receive input events? - * - * @name Phaser.Cameras.Scene2D.Camera#inputEnabled - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.inputEnabled = true; + var width = this.geom.right - this.geom.left; + var height = this.geom.bottom - this.geom.top; - /** - * The Camera Fade effect handler. - * To fade this camera see the `Camera.fade` methods. - * - * @name Phaser.Cameras.Scene2D.Camera#fadeEffect - * @type {Phaser.Cameras.Scene2D.Effects.Fade} - * @since 3.5.0 - */ - this.fadeEffect = new Effects.Fade(this); + this.setPosition(x, y); + this.setSize(width, height); - /** - * The Camera Flash effect handler. - * To flash this camera see the `Camera.flash` method. - * - * @name Phaser.Cameras.Scene2D.Camera#flashEffect - * @type {Phaser.Cameras.Scene2D.Effects.Flash} - * @since 3.5.0 - */ - this.flashEffect = new Effects.Flash(this); + if (fillColor !== undefined) + { + this.setFillStyle(fillColor, fillAlpha); + } - /** - * The Camera Shake effect handler. - * To shake this camera see the `Camera.shake` method. - * - * @name Phaser.Cameras.Scene2D.Camera#shakeEffect - * @type {Phaser.Cameras.Scene2D.Effects.Shake} - * @since 3.5.0 - */ - this.shakeEffect = new Effects.Shake(this); + this.updateDisplayOrigin(); + this.updateData(); + }, - /** - * The Camera Pan effect handler. - * To pan this camera see the `Camera.pan` method. - * - * @name Phaser.Cameras.Scene2D.Camera#panEffect - * @type {Phaser.Cameras.Scene2D.Effects.Pan} - * @since 3.11.0 - */ - this.panEffect = new Effects.Pan(this); + /** + * 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); - /** - * The Camera Rotate To effect handler. - * To rotate this camera see the `Camera.rotateTo` method. - * - * @name Phaser.Cameras.Scene2D.Camera#rotateToEffect - * @type {Phaser.Cameras.Scene2D.Effects.RotateTo} - * @since 3.23.0 - */ - this.rotateToEffect = new Effects.RotateTo(this); + return this.updateData(); + }, - /** - * The Camera Zoom effect handler. - * To zoom this camera see the `Camera.zoom` method. - * - * @name Phaser.Cameras.Scene2D.Camera#zoomEffect - * @type {Phaser.Cameras.Scene2D.Effects.Zoom} - * @since 3.11.0 - */ - this.zoomEffect = new Effects.Zoom(this); + /** + * 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; - /** - * The linear interpolation value to use when following a target. - * - * Can also be set via `setLerp` or as part of the `startFollow` call. - * - * The default values of 1 means the camera will instantly snap to the target coordinates. - * A lower value, such as 0.1 means the camera will more slowly track the target, giving - * a smooth transition. You can set the horizontal and vertical values independently, and also - * adjust this value in real-time during your game. - * - * Be sure to keep the value between 0 and 1. A value of zero will disable tracking on that axis. - * - * @name Phaser.Cameras.Scene2D.Camera#lerp - * @type {Phaser.Math.Vector2} - * @since 3.9.0 - */ - this.lerp = new Vector2(1, 1); + tri.getLineA(line); - /** - * The values stored in this property are subtracted from the Camera targets position, allowing you to - * offset the camera from the actual target x/y coordinates by this amount. - * Can also be set via `setFollowOffset` or as part of the `startFollow` call. - * - * @name Phaser.Cameras.Scene2D.Camera#followOffset - * @type {Phaser.Math.Vector2} - * @since 3.9.0 - */ - this.followOffset = new Vector2(); + path.push(line.x1, line.y1, line.x2, line.y2); - /** - * The Camera dead zone. - * - * The deadzone is only used when the camera is following a target. - * - * It defines a rectangular region within which if the target is present, the camera will not scroll. - * If the target moves outside of this area, the camera will begin scrolling in order to follow it. - * - * The `lerp` values that you can set for a follower target also apply when using a deadzone. - * - * You can directly set this property to be an instance of a Rectangle. Or, you can use the - * `setDeadzone` method for a chainable approach. - * - * The rectangle you provide can have its dimensions adjusted dynamically, however, please - * note that its position is updated every frame, as it is constantly re-centered on the cameras mid point. - * - * Calling `setDeadzone` with no arguments will reset an active deadzone, as will setting this property - * to `null`. + 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; + + +/***/ }), + +/***/ 60213: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var FillStyleCanvas = __webpack_require__(15608); +var LineStyleCanvas = __webpack_require__(17876); +var SetTransform = __webpack_require__(49584); + +/** + * 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.Triangle#renderCanvas + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Triangle} 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 TriangleCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); + + var ctx = renderer.currentContext; + + if (SetTransform(renderer, ctx, src, camera, parentMatrix)) + { + var dx = src._displayOriginX; + var dy = src._displayOriginY; + + var x1 = src.geom.x1 - dx; + var y1 = src.geom.y1 - dy; + var x2 = src.geom.x2 - dx; + var y2 = src.geom.y2 - dy; + var x3 = src.geom.x3 - dx; + var y3 = src.geom.y3 - dy; + + ctx.beginPath(); + + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.lineTo(x3, y3); + + ctx.closePath(); + + if (src.isFilled) + { + FillStyleCanvas(ctx, src); + + ctx.fill(); + } + + if (src.isStroked) + { + LineStyleCanvas(ctx, src); + + ctx.stroke(); + } + + // Restore the context saved in SetTransform + ctx.restore(); + } +}; + +module.exports = TriangleCanvasRenderer; + + +/***/ }), + +/***/ 79296: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GameObjectFactory = __webpack_require__(61286); +var Triangle = __webpack_require__(21873); + +/** + * Creates a new Triangle Shape Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Triangle Game Object has been built into Phaser. + * + * 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. + * + * @method Phaser.GameObjects.GameObjectFactory#triangle + * @since 3.13.0 + * + * @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. + * + * @return {Phaser.GameObjects.Triangle} The Game Object that was created. + */ +GameObjectFactory.register('triangle', function (x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha) +{ + return this.displayList.add(new Triangle(this.scene, x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha)); +}); + + +/***/ }), + +/***/ 70498: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(72291); +} + +if (true) +{ + renderCanvas = __webpack_require__(60213); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 72291: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetCalcMatrix = __webpack_require__(73329); +var StrokePathWebGL = __webpack_require__(50262); +var Utils = __webpack_require__(75512); + +/** + * 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.Triangle#renderWebGL + * @since 3.13.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Triangle} 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 TriangleWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); + + var pipeline = renderer.pipelines.set(src.pipeline); + + var result = GetCalcMatrix(src, camera, parentMatrix); + + pipeline.calcMatrix.copyFrom(result.calc); + + var dx = src._displayOriginX; + var dy = src._displayOriginY; + var alpha = camera.alpha * src.alpha; + + renderer.pipelines.preBatch(src); + + if (src.isFilled) + { + var fillTint = pipeline.fillTint; + var fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha); + + fillTint.TL = fillTintColor; + fillTint.TR = fillTintColor; + fillTint.BL = fillTintColor; + fillTint.BR = fillTintColor; + + var x1 = src.geom.x1 - dx; + var y1 = src.geom.y1 - dy; + var x2 = src.geom.x2 - dx; + var y2 = src.geom.y2 - dy; + var x3 = src.geom.x3 - dx; + var y3 = src.geom.y3 - dy; + + pipeline.batchFillTriangle( + x1, + y1, + x2, + y2, + x3, + y3, + result.sprite, + result.camera + ); + } + + if (src.isStroked) + { + StrokePathWebGL(pipeline, src, alpha, dx, dy); + } + + renderer.pipelines.postBatch(src); +}; + +module.exports = TriangleWebGLRenderer; + + +/***/ }), + +/***/ 13747: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var AnimationState = __webpack_require__(16569); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var SpriteRender = __webpack_require__(20791); + +/** + * @classdesc + * A Sprite Game Object. + * + * A Sprite Game Object is used for the display of both static and animated images in your game. + * Sprites can have input events and physics bodies. They can also be tweened, tinted, scrolled + * and animated. + * + * The main difference between a Sprite and an Image Game Object is that you cannot animate Images. + * As such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation + * Component. If you do not require animation then you can safely use Images to replace Sprites in all cases. + * + * @class Sprite + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.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.GetBounds + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.TextureCrop + * @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 Sprite = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.Depth, + Components.Flip, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Size, + Components.TextureCrop, + Components.Tint, + Components.Transform, + Components.Visible, + SpriteRender + ], + + initialize: + + function Sprite (scene, x, y, texture, frame) + { + GameObject.call(this, scene, 'Sprite'); + + /** + * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. * - * @name Phaser.Cameras.Scene2D.Camera#deadzone - * @type {?Phaser.Geom.Rectangle} + * @name Phaser.GameObjects.Sprite#_crop + * @type {object} + * @private * @since 3.11.0 */ - this.deadzone = null; + this._crop = this.resetCropObject(); /** - * Internal follow target reference. + * The Animation State component of this Sprite. * - * @name Phaser.Cameras.Scene2D.Camera#_follow - * @type {?any} - * @private - * @default null + * This component provides features to apply animations to this Sprite. + * It is responsible for playing, loading, queuing animations for later playback, + * mixing between animations and setting the current animation frame to this Sprite. + * + * @name Phaser.GameObjects.Sprite#anims + * @type {Phaser.Animations.AnimationState} * @since 3.0.0 */ - this._follow = null; + this.anims = new AnimationState(this); + + this.setTexture(texture, frame); + this.setPosition(x, y); + this.setSizeToFrame(); + this.setOriginFromFrame(); + this.initPipeline(); + this.initPostPipeline(true); + }, + + // Overrides Game Object method + addedToScene: function () + { + this.scene.sys.updateList.add(this); + }, + + // Overrides Game Object method + removedFromScene: function () + { + this.scene.sys.updateList.remove(this); }, /** - * Sets the Camera dead zone. + * Update this Sprite's animations. * - * The deadzone is only used when the camera is following a target. + * @method Phaser.GameObjects.Sprite#preUpdate + * @protected + * @since 3.0.0 * - * It defines a rectangular region within which if the target is present, the camera will not scroll. - * If the target moves outside of this area, the camera will begin scrolling in order to follow it. + * @param {number} time - The current timestamp. + * @param {number} delta - The delta time, in ms, elapsed since the last frame. + */ + preUpdate: function (time, delta) + { + this.anims.update(time, delta); + }, + + /** + * Start playing the given animation on this Sprite. * - * The deadzone rectangle is re-positioned every frame so that it is centered on the mid-point - * of the camera. This allows you to use the object for additional game related checks, such as - * testing if an object is within it or not via a Rectangle.contains call. + * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite. * - * The `lerp` values that you can set for a follower target also apply when using a deadzone. + * The benefit of a global animation is that multiple Sprites can all play the same animation, without + * having to duplicate the data. You can just create it once and then play it on any Sprite. * - * Calling this method with no arguments will reset an active deadzone. + * The following code shows how to create a global repeating animation. The animation will be created + * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': * - * @method Phaser.Cameras.Scene2D.Camera#setDeadzone - * @since 3.11.0 + * ```javascript + * var config = { + * key: 'run', + * frames: 'muybridge', + * frameRate: 15, + * repeat: -1 + * }; * - * @param {number} [width] - The width of the deadzone rectangle in pixels. If not specified the deadzone is removed. - * @param {number} [height] - The height of the deadzone rectangle in pixels. + * // This code should be run from within a Scene: + * this.anims.create(config); + * ``` * - * @return {this} This Camera instance. + * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone, + * you can call the `Animation.create` method instead. It accepts the exact same parameters as when + * creating a global animation, however the resulting data is kept locally in this Sprite. + * + * With the animation created, either globally or locally, you can now play it on this Sprite: + * + * ```javascript + * this.add.sprite(x, y).play('run'); + * ``` + * + * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config + * object instead: + * + * ```javascript + * this.add.sprite(x, y).play({ key: 'run', frameRate: 24 }); + * ``` + * + * When playing an animation on a Sprite it will first check to see if it can find a matching key + * locally within the Sprite. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * If you need a Sprite to be able to play both local and global animations, make sure they don't + * have conflicting keys. + * + * See the documentation for the `PlayAnimationConfig` config object for more details about this. + * + * Also, see the documentation in the Animation Manager for further details on creating animations. + * + * @method Phaser.GameObjects.Sprite#play + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.0.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. + * + * @return {this} This Game Object. */ - setDeadzone: function (width, height) + play: function (key, ignoreIfPlaying) { - if (width === undefined) - { - this.deadzone = null; - } - else - { - if (this.deadzone) - { - this.deadzone.width = width; - this.deadzone.height = height; - } - else - { - this.deadzone = new Rectangle(0, 0, width, height); - } - - if (this._follow) - { - var originX = this.width / 2; - var originY = this.height / 2; - - var fx = this._follow.x - this.followOffset.x; - var fy = this._follow.y - this.followOffset.y; - - this.midPoint.set(fx, fy); - - this.scrollX = fx - originX; - this.scrollY = fy - originY; - } - - CenterOn(this.deadzone, this.midPoint.x, this.midPoint.y); - } - - return this; + return this.anims.play(key, ignoreIfPlaying); }, /** - * Fades the Camera in from the given color over the duration specified. + * Start playing the given animation on this Sprite, in reverse. * - * @method Phaser.Cameras.Scene2D.Camera#fadeIn - * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_START - * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE - * @since 3.3.0 + * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite. * - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. - * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. - * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. - * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * The benefit of a global animation is that multiple Sprites can all play the same animation, without + * having to duplicate the data. You can just create it once and then play it on any Sprite. * - * @return {this} This Camera instance. + * The following code shows how to create a global repeating animation. The animation will be created + * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': + * + * ```javascript + * var config = { + * key: 'run', + * frames: 'muybridge', + * frameRate: 15, + * repeat: -1 + * }; + * + * // This code should be run from within a Scene: + * this.anims.create(config); + * ``` + * + * However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone, + * you can call the `Animation.create` method instead. It accepts the exact same parameters as when + * creating a global animation, however the resulting data is kept locally in this Sprite. + * + * With the animation created, either globally or locally, you can now play it on this Sprite: + * + * ```javascript + * this.add.sprite(x, y).playReverse('run'); + * ``` + * + * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config + * object instead: + * + * ```javascript + * this.add.sprite(x, y).playReverse({ key: 'run', frameRate: 24 }); + * ``` + * + * When playing an animation on a Sprite it will first check to see if it can find a matching key + * locally within the Sprite. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * If you need a Sprite to be able to play both local and global animations, make sure they don't + * have conflicting keys. + * + * See the documentation for the `PlayAnimationConfig` config object for more details about this. + * + * Also, see the documentation in the Animation Manager for further details on creating animations. + * + * @method Phaser.GameObjects.Sprite#playReverse + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.50.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call. + * + * @return {this} This Game Object. */ - fadeIn: function (duration, red, green, blue, callback, context) + playReverse: function (key, ignoreIfPlaying) { - return this.fadeEffect.start(false, duration, red, green, blue, true, callback, context); + return this.anims.playReverse(key, ignoreIfPlaying); }, /** - * Fades the Camera out to the given color over the duration specified. - * This is an alias for Camera.fade that forces the fade to start, regardless of existing fades. + * Waits for the specified delay, in milliseconds, then starts playback of the given animation. * - * @method Phaser.Cameras.Scene2D.Camera#fadeOut - * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_START - * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE - * @since 3.3.0 + * If the animation _also_ has a delay value set in its config, it will be **added** to the delay given here. * - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. - * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. - * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. - * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * If an animation is already running and a new animation is given to this method, it will wait for + * the given delay before starting the new animation. * - * @return {this} This Camera instance. + * If no animation is currently running, the given one begins after the delay. + * + * When playing an animation on a Sprite it will first check to see if it can find a matching key + * locally within the Sprite. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * Prior to Phaser 3.50 this method was called 'delayedPlay'. + * + * @method Phaser.GameObjects.Sprite#playAfterDelay + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.50.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {number} delay - The delay, in milliseconds, to wait before starting the animation playing. + * + * @return {this} This Game Object. */ - fadeOut: function (duration, red, green, blue, callback, context) + playAfterDelay: function (key, delay) { - return this.fadeEffect.start(true, duration, red, green, blue, true, callback, context); + return this.anims.playAfterDelay(key, delay); }, /** - * Fades the Camera from the given color to transparent over the duration specified. + * Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback + * of the given animation. * - * @method Phaser.Cameras.Scene2D.Camera#fadeFrom - * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_START - * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE - * @since 3.5.0 + * You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an + * idle animation to a walking animation, by making them blend smoothly into each other. * - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. - * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. - * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. - * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. - * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * If no animation is currently running, the given one will start immediately. * - * @return {this} This Camera instance. + * When playing an animation on a Sprite it will first check to see if it can find a matching key + * locally within the Sprite. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * @method Phaser.GameObjects.Sprite#playAfterRepeat + * @fires Phaser.Animations.Events#ANIMATION_START + * @since 3.50.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param {number} [repeatCount=1] - How many times should the animation repeat before the next one starts? + * + * @return {this} This Game Object. */ - fadeFrom: function (duration, red, green, blue, force, callback, context) + playAfterRepeat: function (key, repeatCount) { - return this.fadeEffect.start(false, duration, red, green, blue, force, callback, context); + return this.anims.playAfterRepeat(key, repeatCount); }, /** - * Fades the Camera from transparent to the given color over the duration specified. + * Sets an animation, or an array of animations, to be played immediately after the current one completes or stops. * - * @method Phaser.Cameras.Scene2D.Camera#fade - * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_START - * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE - * @since 3.0.0 + * The current animation must enter a 'completed' state for this to happen, i.e. finish all of its repeats, delays, etc, + * or have the `stop` method called directly on it. * - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. - * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. - * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. - * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. - * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * An animation set to repeat forever will never enter a completed state. * - * @return {this} This Camera instance. + * You can chain a new animation at any point, including before the current one starts playing, during it, + * or when it ends (via its `animationcomplete` event). + * + * Chained animations are specific to a Game Object, meaning different Game Objects can have different chained + * animations without impacting the animation they're playing. + * + * Call this method with no arguments to reset all currently chained animations. + * + * When playing an animation on a Sprite it will first check to see if it can find a matching key + * locally within the Sprite. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * @method Phaser.GameObjects.Sprite#chain + * @since 3.50.0 + * + * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} [key] - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them. + * + * @return {this} This Game Object. */ - fade: function (duration, red, green, blue, force, callback, context) + chain: function (key) { - return this.fadeEffect.start(true, duration, red, green, blue, force, callback, context); + return this.anims.chain(key); }, /** - * Flashes the Camera by setting it to the given color immediately and then fading it away again quickly over the duration specified. + * Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` events. * - * @method Phaser.Cameras.Scene2D.Camera#flash - * @fires Phaser.Cameras.Scene2D.Events#FLASH_START - * @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE - * @since 3.0.0 + * If no animation is playing, no event will be dispatched. * - * @param {number} [duration=250] - The duration of the effect in milliseconds. - * @param {number} [red=255] - The amount to fade the red channel towards. A value between 0 and 255. - * @param {number} [green=255] - The amount to fade the green channel towards. A value between 0 and 255. - * @param {number} [blue=255] - The amount to fade the blue channel towards. A value between 0 and 255. - * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. - * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * If there is another animation queued (via the `chain` method) then it will start playing immediately. * - * @return {this} This Camera instance. + * @method Phaser.GameObjects.Sprite#stop + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.50.0 + * + * @return {this} This Game Object. */ - flash: function (duration, red, green, blue, force, callback, context) + stop: function () { - return this.flashEffect.start(duration, red, green, blue, force, callback, context); + return this.anims.stop(); }, /** - * Shakes the Camera by the given intensity over the duration specified. + * Stops the current animation from playing after the specified time delay, given in milliseconds. * - * @method Phaser.Cameras.Scene2D.Camera#shake - * @fires Phaser.Cameras.Scene2D.Events#SHAKE_START - * @fires Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE - * @since 3.0.0 + * It then dispatches the `ANIMATION_STOP` event. * - * @param {number} [duration=100] - The duration of the effect in milliseconds. - * @param {(number|Phaser.Math.Vector2)} [intensity=0.05] - The intensity of the shake. - * @param {boolean} [force=false] - Force the shake effect to start immediately, even if already running. - * @param {function} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * If no animation is running, no events will be dispatched. * - * @return {this} This Camera instance. + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. + * + * @method Phaser.GameObjects.Sprite#stopAfterDelay + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.50.0 + * + * @param {number} delay - The number of milliseconds to wait before stopping this animation. + * + * @return {this} This Game Object. */ - shake: function (duration, intensity, force, callback, context) + stopAfterDelay: function (delay) { - return this.shakeEffect.start(duration, intensity, force, callback, context); + return this.anims.stopAfterDelay(delay); }, /** - * This effect will scroll the Camera so that the center of its viewport finishes at the given destination, - * over the duration and with the ease specified. + * Stops the current animation from playing after the given number of repeats. * - * @method Phaser.Cameras.Scene2D.Camera#pan - * @fires Phaser.Cameras.Scene2D.Events#PAN_START - * @fires Phaser.Cameras.Scene2D.Events#PAN_COMPLETE - * @since 3.11.0 + * It then dispatches the `ANIMATION_STOP` event. * - * @param {number} x - The destination x coordinate to scroll the center of the Camera viewport to. - * @param {number} y - The destination y coordinate to scroll the center of the Camera viewport to. - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {(string|function)} [ease='Linear'] - The ease to use for the pan. Can be any of the Phaser Easing constants or a custom function. - * @param {boolean} [force=false] - Force the pan effect to start immediately, even if already running. - * @param {Phaser.Types.Cameras.Scene2D.CameraPanCallback} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, - * the current camera scroll x coordinate and the current camera scroll y coordinate. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * If no animation is running, no events will be dispatched. * - * @return {this} This Camera instance. + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. + * + * @method Phaser.GameObjects.Sprite#stopAfterRepeat + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.50.0 + * + * @param {number} [repeatCount=1] - How many times should the animation repeat before stopping? + * + * @return {this} This Game Object. */ - pan: function (x, y, duration, ease, force, callback, context) + stopAfterRepeat: function (repeatCount) { - return this.panEffect.start(x, y, duration, ease, force, callback, context); + return this.anims.stopAfterRepeat(repeatCount); }, /** - * This effect will rotate the Camera so that the viewport finishes at the given angle in radians, - * over the duration and with the ease specified. + * Stops the current animation from playing when it next sets the given frame. + * If this frame doesn't exist within the animation it will not stop it from playing. * - * @method Phaser.Cameras.Scene2D.Camera#rotateTo - * @since 3.23.0 + * It then dispatches the `ANIMATION_STOP` event. * - * @param {number} radians - The destination angle in radians to rotate the Camera viewport to. If the angle is positive then the rotation is clockwise else anticlockwise - * @param {boolean} [shortestPath=false] - If shortest path is set to true the camera will rotate in the quickest direction clockwise or anti-clockwise. - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {(string|function)} [ease='Linear'] - The ease to use for the rotation. Can be any of the Phaser Easing constants or a custom function. - * @param {boolean} [force=false] - Force the rotation effect to start immediately, even if already running. - * @param {CameraRotateCallback} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, - * the current camera rotation angle in radians. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * If no animation is running, no events will be dispatched. * - * @return {Phaser.Cameras.Scene2D.Camera} This Camera instance. + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. + * + * @method Phaser.GameObjects.Sprite#stopOnFrame + * @fires Phaser.Animations.Events#ANIMATION_STOP + * @since 3.50.0 + * + * @param {Phaser.Animations.AnimationFrame} frame - The frame to check before stopping this animation. + * + * @return {this} This Game Object. */ - rotateTo: function (radians, shortestPath, duration, ease, force, callback, context) + stopOnFrame: function (frame) { - return this.rotateToEffect.start(radians, shortestPath, duration, ease, force, callback, context); + return this.anims.stopOnFrame(frame); }, /** - * This effect will zoom the Camera to the given scale, over the duration and with the ease specified. - * - * @method Phaser.Cameras.Scene2D.Camera#zoomTo - * @fires Phaser.Cameras.Scene2D.Events#ZOOM_START - * @fires Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE - * @since 3.11.0 + * Build a JSON representation of this Sprite. * - * @param {number} zoom - The target Camera zoom value. - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {(string|function)} [ease='Linear'] - The ease to use for the pan. Can be any of the Phaser Easing constants or a custom function. - * @param {boolean} [force=false] - Force the pan effect to start immediately, even if already running. - * @param {Phaser.Types.Cameras.Scene2D.CameraPanCallback} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, - * the current camera scroll x coordinate and the current camera scroll y coordinate. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * @method Phaser.GameObjects.Sprite#toJSON + * @since 3.0.0 * - * @return {this} This Camera instance. + * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object. */ - zoomTo: function (zoom, duration, ease, force, callback, context) + toJSON: function () { - return this.zoomEffect.start(zoom, duration, ease, force, callback, context); + return Components.ToJSON(this); }, /** - * Internal preRender step. + * Handles the pre-destroy step for the Sprite, which removes the Animation component. * - * @method Phaser.Cameras.Scene2D.Camera#preRender - * @protected - * @since 3.0.0 + * @method Phaser.GameObjects.Sprite#preDestroy + * @private + * @since 3.14.0 */ - preRender: function () + preDestroy: function () { - this.renderList.length = 0; + this.anims.destroy(); - var width = this.width; - var height = this.height; + this.anims = undefined; + } - var halfWidth = width * 0.5; - var halfHeight = height * 0.5; +}); - var zoom = this.zoom; - var matrix = this.matrix; +module.exports = Sprite; - var originX = width * this.originX; - var originY = height * this.originY; - var follow = this._follow; - var deadzone = this.deadzone; +/***/ }), - var sx = this.scrollX; - var sy = this.scrollY; +/***/ 27573: +/***/ ((module) => { - if (deadzone) - { - CenterOn(deadzone, this.midPoint.x, this.midPoint.y); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var emitFollowEvent = false; +/** + * 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.Sprite#renderCanvas + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Sprite} 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 SpriteCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + camera.addToRenderList(src); - if (follow && !this.panEffect.isRunning) - { - var fx = (follow.x - this.followOffset.x); - var fy = (follow.y - this.followOffset.y); + renderer.batchSprite(src, src.frame, camera, parentMatrix); +}; - if (deadzone) - { - if (fx < deadzone.x) - { - sx = Linear(sx, sx - (deadzone.x - fx), this.lerp.x); - } - else if (fx > deadzone.right) - { - sx = Linear(sx, sx + (fx - deadzone.right), this.lerp.x); - } +module.exports = SpriteCanvasRenderer; - if (fy < deadzone.y) - { - sy = Linear(sy, sy - (deadzone.y - fy), this.lerp.y); - } - else if (fy > deadzone.bottom) - { - sy = Linear(sy, sy + (fy - deadzone.bottom), this.lerp.y); - } - } - else - { - sx = Linear(sx, fx - originX, this.lerp.x); - sy = Linear(sy, fy - originY, this.lerp.y); - } - emitFollowEvent = true; - } +/***/ }), - if (this.useBounds) - { - sx = this.clampX(sx); - sy = this.clampY(sy); - } +/***/ 89219: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - if (this.roundPixels) - { - originX = Math.round(originX); - originY = Math.round(originY); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - sx = Math.round(sx); - sy = Math.round(sy); - } +var BuildGameObject = __webpack_require__(88933); +var BuildGameObjectAnimation = __webpack_require__(32291); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var Sprite = __webpack_require__(13747); - // Values are in pixels and not impacted by zooming the Camera - this.scrollX = sx; - this.scrollY = sy; +/** + * Creates a new Sprite Game Object and returns it. + * + * Note: This method will only be available if the Sprite Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#sprite + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Sprite} The Game Object that was created. + */ +GameObjectCreator.register('sprite', function (config, addToScene) +{ + if (config === undefined) { config = {}; } - var midX = sx + halfWidth; - var midY = sy + halfHeight; + var key = GetAdvancedValue(config, 'key', null); + var frame = GetAdvancedValue(config, 'frame', null); - // The center of the camera, in world space, so taking zoom into account - // Basically the pixel value of what it's looking at in the middle of the cam - this.midPoint.set(midX, midY); + var sprite = new Sprite(this.scene, 0, 0, key, frame); - var displayWidth = width / zoom; - var displayHeight = height / zoom; + if (addToScene !== undefined) + { + config.add = addToScene; + } - var vwx = midX - (displayWidth / 2); - var vwy = midY - (displayHeight / 2); + BuildGameObject(this.scene, sprite, config); - if (this.roundPixels) - { - vwx = Math.round(vwx); - vwy = Math.round(vwy); - } + // Sprite specific config options: - this.worldView.setTo(vwx, vwy, displayWidth, displayHeight); + BuildGameObjectAnimation(sprite, config); - matrix.applyITRS(this.x + originX, this.y + originY, this.rotation, zoom, zoom); - matrix.translate(-originX, -originY); + return sprite; +}); - this.shakeEffect.preRender(); - if (emitFollowEvent) - { - this.emit(Events.FOLLOW_UPDATE, this, follow); - } - }, +/***/ }), - /** - * Sets the linear interpolation value to use when following a target. - * - * The default values of 1 means the camera will instantly snap to the target coordinates. - * A lower value, such as 0.1 means the camera will more slowly track the target, giving - * a smooth transition. You can set the horizontal and vertical values independently, and also - * adjust this value in real-time during your game. - * - * Be sure to keep the value between 0 and 1. A value of zero will disable tracking on that axis. - * - * @method Phaser.Cameras.Scene2D.Camera#setLerp - * @since 3.9.0 - * - * @param {number} [x=1] - The amount added to the horizontal linear interpolation of the follow target. - * @param {number} [y=1] - The amount added to the vertical linear interpolation of the follow target. - * - * @return {this} This Camera instance. - */ - setLerp: function (x, y) - { - if (x === undefined) { x = 1; } - if (y === undefined) { y = x; } +/***/ 66135: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - this.lerp.set(x, y); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +var GameObjectFactory = __webpack_require__(61286); +var Sprite = __webpack_require__(13747); - /** - * Sets the horizontal and vertical offset of the camera from its follow target. - * The values are subtracted from the targets position during the Cameras update step. - * - * @method Phaser.Cameras.Scene2D.Camera#setFollowOffset - * @since 3.9.0 - * - * @param {number} [x=0] - The horizontal offset from the camera follow target.x position. - * @param {number} [y=0] - The vertical offset from the camera follow target.y position. - * - * @return {this} This Camera instance. - */ - setFollowOffset: function (x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } +/** + * Creates a new Sprite Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Sprite Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#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|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.GameObjects.Sprite} The Game Object that was created. + */ +GameObjectFactory.register('sprite', function (x, y, texture, frame) +{ + return this.displayList.add(new Sprite(this.scene, x, y, texture, frame)); +}); - this.followOffset.set(x, y); - - return this; - }, - - /** - * Sets the Camera to follow a Game Object. - * - * When enabled the Camera will automatically adjust its scroll position to keep the target Game Object - * in its center. - * - * You can set the linear interpolation value used in the follow code. - * Use low lerp values (such as 0.1) to automatically smooth the camera motion. - * - * If you find you're getting a slight "jitter" effect when following an object it's probably to do with sub-pixel - * rendering of the targets position. This can be rounded by setting the `roundPixels` argument to `true` to - * force full pixel rounding rendering. Note that this can still be broken if you have specified a non-integer zoom - * value on the camera. So be sure to keep the camera zoom to integers. - * - * @method Phaser.Cameras.Scene2D.Camera#startFollow - * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|object)} target - The target for the Camera to follow. - * @param {boolean} [roundPixels=false] - Round the camera position to whole integers to avoid sub-pixel rendering? - * @param {number} [lerpX=1] - A value between 0 and 1. This value specifies the amount of linear interpolation to use when horizontally tracking the target. The closer the value to 1, the faster the camera will track. - * @param {number} [lerpY=1] - A value between 0 and 1. This value specifies the amount of linear interpolation to use when vertically tracking the target. The closer the value to 1, the faster the camera will track. - * @param {number} [offsetX=0] - The horizontal offset from the camera follow target.x position. - * @param {number} [offsetY=0] - The vertical offset from the camera follow target.y position. - * - * @return {this} This Camera instance. - */ - startFollow: function (target, roundPixels, lerpX, lerpY, offsetX, offsetY) - { - if (roundPixels === undefined) { roundPixels = false; } - if (lerpX === undefined) { lerpX = 1; } - if (lerpY === undefined) { lerpY = lerpX; } - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = offsetX; } - - this._follow = target; - - this.roundPixels = roundPixels; - - lerpX = Clamp(lerpX, 0, 1); - lerpY = Clamp(lerpY, 0, 1); - - this.lerp.set(lerpX, lerpY); - - this.followOffset.set(offsetX, offsetY); - - var originX = this.width / 2; - var originY = this.height / 2; - - var fx = target.x - offsetX; - var fy = target.y - offsetY; - - this.midPoint.set(fx, fy); - - this.scrollX = fx - originX; - this.scrollY = fy - originY; - - if (this.useBounds) - { - this.scrollX = this.clampX(this.scrollX); - this.scrollY = this.clampY(this.scrollY); - } - - return this; - }, - - /** - * Stops a Camera from following a Game Object, if previously set via `Camera.startFollow`. - * - * @method Phaser.Cameras.Scene2D.Camera#stopFollow - * @since 3.0.0 - * - * @return {this} This Camera instance. - */ - stopFollow: function () - { - this._follow = null; - - return this; - }, - - /** - * Resets any active FX, such as a fade, flash or shake. Useful to call after a fade in order to - * remove the fade. - * - * @method Phaser.Cameras.Scene2D.Camera#resetFX - * @since 3.0.0 - * - * @return {this} This Camera instance. - */ - resetFX: function () - { - this.rotateToEffect.reset(); - this.panEffect.reset(); - this.shakeEffect.reset(); - this.flashEffect.reset(); - this.fadeEffect.reset(); - - return this; - }, - - /** - * Internal method called automatically by the Camera Manager. - * - * @method Phaser.Cameras.Scene2D.Camera#update - * @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. - */ - update: function (time, delta) - { - if (this.visible) - { - this.rotateToEffect.update(time, delta); - this.panEffect.update(time, delta); - this.zoomEffect.update(time, delta); - this.shakeEffect.update(time, delta); - this.flashEffect.update(time, delta); - this.fadeEffect.update(time, delta); - } - }, - - /** - * Destroys this Camera instance. You rarely need to call this directly. - * - * Called by the Camera Manager. If you wish to destroy a Camera please use `CameraManager.remove` as - * cameras are stored in a pool, ready for recycling later, and calling this directly will prevent that. - * - * @method Phaser.Cameras.Scene2D.Camera#destroy - * @fires Phaser.Cameras.Scene2D.Events#DESTROY - * @since 3.0.0 - */ - destroy: function () - { - this.resetFX(); - - BaseCamera.prototype.destroy.call(this); - - this._follow = null; - - this.deadzone = null; - } - -}); - -module.exports = Camera; +// When registering a factory function 'this' refers to the GameObjectFactory 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 /***/ }), -/* 327 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 20791: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(38); +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; -/** - * Converts a hex string into a Phaser Color object. - * - * The hex string can supplied as `'#0033ff'` or the short-hand format of `'#03f'`; it can begin with an optional "#" or "0x", or be unprefixed. - * - * An alpha channel is _not_ supported. - * - * @function Phaser.Display.Color.HexStringToColor - * @since 3.0.0 - * - * @param {string} hex - The hex color value to convert, such as `#0033ff` or the short-hand format: `#03f`. - * - * @return {Phaser.Display.Color} A Color object populated by the values of the given string. - */ -var HexStringToColor = function (hex) +if (true) { - var color = new Color(); - - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - hex = hex.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i, function (m, r, g, b) - { - return r + r + g + g + b + b; - }); + renderWebGL = __webpack_require__(21034); +} - var result = (/^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i).exec(hex); +if (true) +{ + renderCanvas = __webpack_require__(27573); +} - if (result) - { - var r = parseInt(result[1], 16); - var g = parseInt(result[2], 16); - var b = parseInt(result[3], 16); +module.exports = { - color.setTo(r, g, b); - } + renderWebGL: renderWebGL, + renderCanvas: renderCanvas - return color; }; -module.exports = HexStringToColor; - /***/ }), -/* 328 */ -/***/ (function(module, exports) { + +/***/ 21034: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Given an alpha and 3 color values this will return an integer representation of it. + * 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. * - * @function Phaser.Display.Color.GetColor32 + * @method Phaser.GameObjects.Sprite#renderWebGL * @since 3.0.0 + * @private * - * @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 - The alpha color value. A number between 0 and 255. - * - * @return {number} The combined color value. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Sprite} 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 GetColor32 = function (red, green, blue, alpha) +var SpriteWebGLRenderer = function (renderer, src, camera, parentMatrix) { - return alpha << 24 | red << 16 | green << 8 | blue; + camera.addToRenderList(src); + + src.pipeline.batchSprite(src, camera, parentMatrix); }; -module.exports = GetColor32; +module.exports = SpriteWebGLRenderer; /***/ }), -/* 329 */ -/***/ (function(module, exports) { + +/***/ 32979: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Converts an RGB color value to HSV (hue, saturation and value). - * Conversion formula from http://en.wikipedia.org/wiki/HSL_color_space. - * Assumes RGB values are contained in the set [0, 255] and returns h, s and v in the set [0, 1]. - * Based on code by Michael Jackson (https://github.com/mjijackson) + * Returns an object containing dimensions of the Text object. * - * @function Phaser.Display.Color.RGBToHSV + * @function Phaser.GameObjects.GetTextSize * @since 3.0.0 * - * @param {number} r - The red color value. A number between 0 and 255. - * @param {number} g - The green color value. A number between 0 and 255. - * @param {number} b - The blue color value. A number between 0 and 255. - * @param {(Phaser.Types.Display.HSVColorObject|Phaser.Display.Color)} [out] - An object to store the color values in. If not given an HSV Color Object will be created. + * @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.Display.HSVColorObject|Phaser.Display.Color)} An object with the properties `h`, `s` and `v` set. + * @return {Phaser.Types.GameObjects.Text.GetTextSizeObject} An object containing dimensions of the Text object. */ -var RGBToHSV = function (r, g, b, out) +var GetTextSize = function (text, size, lines) { - if (out === undefined) { out = { h: 0, s: 0, v: 0 }; } - - r /= 255; - g /= 255; - b /= 255; - - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var d = max - min; - - // achromatic by default - var h = 0; - var s = (max === 0) ? 0 : d / max; - var v = max; - - if (max !== min) - { - if (max === r) - { - h = (g - b) / d + ((g < b) ? 6 : 0); - } - else if (max === g) - { - h = (b - r) / d + 2; - } - else if (max === b) - { - h = (r - g) / d + 4; - } + var canvas = text.canvas; + var context = text.context; + var style = text.style; - h /= 6; - } + var lineWidths = []; + var maxLineWidth = 0; + var drawnLines = lines.length; - if (out.hasOwnProperty('_h')) - { - out._h = h; - out._s = s; - out._v = v; - } - else + if (style.maxLines > 0 && style.maxLines < lines.length) { - out.h = h; - out.s = s; - out.v = v; + drawnLines = style.maxLines; } - return out; -}; + style.syncFont(canvas, context); -module.exports = RGBToHSV; + // Text Width + for (var i = 0; i < drawnLines; i++) + { + var lineWidth = style.strokeThickness; -/***/ }), -/* 330 */ -/***/ (function(module, exports) { + lineWidth += context.measureText(lines[i]).width; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Adjust for wrapped text + if (style.wordWrap) + { + lineWidth -= context.measureText(' ').width; + } -/** - * Return the component parts of a color as an Object with the properties alpha, red, green, blue. - * - * Alpha will only be set if it exists in the given color (0xAARRGGBB) - * - * @function Phaser.Display.Color.IntegerToRGB - * @since 3.0.0 - * - * @param {number} input - The color value to convert into a Color object. - * - * @return {Phaser.Types.Display.ColorObject} An object with the red, green and blue values set in the r, g and b properties. - */ -var IntegerToRGB = function (color) -{ - if (color > 16777215) - { - // The color value has an alpha component - return { - a: color >>> 24, - r: color >> 16 & 0xFF, - g: color >> 8 & 0xFF, - b: color & 0xFF - }; - } - else - { - return { - a: 255, - r: color >> 16 & 0xFF, - g: color >> 8 & 0xFF, - b: color & 0xFF - }; + lineWidths[i] = Math.ceil(lineWidth); + maxLineWidth = Math.max(maxLineWidth, lineWidths[i]); } -}; -module.exports = IntegerToRGB; - - -/***/ }), -/* 331 */ -/***/ (function(module, exports, __webpack_require__) { + // Text Height -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var lineHeight = size.fontSize + style.strokeThickness; + var height = lineHeight * drawnLines; + var lineSpacing = text.lineSpacing; -var Color = __webpack_require__(38); + // Adjust for line spacing + if (drawnLines > 1) + { + height += lineSpacing * (drawnLines - 1); + } -/** - * Converts an object containing `r`, `g`, `b` and `a` properties into a Color class instance. - * - * @function Phaser.Display.Color.ObjectToColor - * @since 3.0.0 - * - * @param {Phaser.Types.Display.InputColorObject} input - An object containing `r`, `g`, `b` and `a` properties in the range 0 to 255. - * - * @return {Phaser.Display.Color} A Color object. - */ -var ObjectToColor = function (input) -{ - return new Color(input.r, input.g, input.b, input.a); + return { + width: maxLineWidth, + height: height, + lines: drawnLines, + lineWidths: lineWidths, + lineSpacing: lineSpacing, + lineHeight: lineHeight + }; }; -module.exports = ObjectToColor; +module.exports = GetTextSize; /***/ }), -/* 332 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 27030: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(38); +var CanvasPool = __webpack_require__(61068); /** - * Converts a CSS 'web' string into a Phaser Color object. - * - * The web string can be in the format `'rgb(r,g,b)'` or `'rgba(r,g,b,a)'` where r/g/b are in the range [0..255] and a is in the range [0..1]. + * Calculates the ascent, descent and fontSize of a given font style. * - * @function Phaser.Display.Color.RGBStringToColor + * @function Phaser.GameObjects.MeasureText * @since 3.0.0 * - * @param {string} rgb - The CSS format color string, using the `rgb` or `rgba` format. + * @param {Phaser.GameObjects.TextStyle} textStyle - The TextStyle object to measure. * - * @return {Phaser.Display.Color} A Color object. + * @return {Phaser.Types.GameObjects.Text.TextMetrics} An object containing the ascent, descent and fontSize of the TextStyle. */ -var RGBStringToColor = function (rgb) +var MeasureText = function (textStyle) { - var color = new Color(); - - var result = (/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/).exec(rgb.toLowerCase()); - - if (result) - { - var r = parseInt(result[1], 10); - var g = parseInt(result[2], 10); - var b = parseInt(result[3], 10); - var a = (result[4] !== undefined) ? parseFloat(result[4]) : 1; - - color.setTo(r, g, b, a * 255); - } - - return color; -}; - -module.exports = RGBStringToColor; - - -/***/ }), -/* 333 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Cameras.Scene2D.Effects - */ - -module.exports = { - - Fade: __webpack_require__(761), - Flash: __webpack_require__(762), - Pan: __webpack_require__(763), - Shake: __webpack_require__(796), - RotateTo: __webpack_require__(797), - Zoom: __webpack_require__(798) - -}; - - -/***/ }), -/* 334 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Math.Easing.Back - */ - -module.exports = { - - In: __webpack_require__(764), - Out: __webpack_require__(765), - InOut: __webpack_require__(766) - -}; - - -/***/ }), -/* 335 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Math.Easing.Bounce - */ - -module.exports = { - - In: __webpack_require__(767), - Out: __webpack_require__(768), - InOut: __webpack_require__(769) - -}; - - -/***/ }), -/* 336 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Math.Easing.Circular - */ - -module.exports = { - - In: __webpack_require__(770), - Out: __webpack_require__(771), - InOut: __webpack_require__(772) - -}; - - -/***/ }), -/* 337 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Math.Easing.Cubic - */ - -module.exports = { - - In: __webpack_require__(773), - Out: __webpack_require__(774), - InOut: __webpack_require__(775) - -}; - - -/***/ }), -/* 338 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Math.Easing.Elastic - */ - -module.exports = { - - In: __webpack_require__(776), - Out: __webpack_require__(777), - InOut: __webpack_require__(778) - -}; - - -/***/ }), -/* 339 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Math.Easing.Expo - */ - -module.exports = { - - In: __webpack_require__(779), - Out: __webpack_require__(780), - InOut: __webpack_require__(781) + var canvas = CanvasPool.create(this); + var context = canvas.getContext('2d', { willReadFrequently: true }); -}; + textStyle.syncFont(canvas, context); + var metrics = context.measureText(textStyle.testString); -/***/ }), -/* 340 */ -/***/ (function(module, exports, __webpack_require__) { + if ('actualBoundingBoxAscent' in metrics) + { + var ascent = metrics.actualBoundingBoxAscent; + var descent = metrics.actualBoundingBoxDescent; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + CanvasPool.remove(canvas); -module.exports = __webpack_require__(782); + return { + ascent: ascent, + descent: descent, + fontSize: ascent + descent + }; + } + var width = Math.ceil(metrics.width * textStyle.baselineX); + var baseline = width; + var height = 2 * baseline; -/***/ }), -/* 341 */ -/***/ (function(module, exports, __webpack_require__) { + baseline = baseline * textStyle.baselineY | 0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + canvas.width = width; + canvas.height = height; -/** - * @namespace Phaser.Math.Easing.Quadratic - */ + context.fillStyle = '#f00'; + context.fillRect(0, 0, width, height); -module.exports = { + context.font = textStyle._font; - In: __webpack_require__(783), - Out: __webpack_require__(784), - InOut: __webpack_require__(785) + context.textBaseline = 'alphabetic'; + context.fillStyle = '#000'; + context.fillText(textStyle.testString, 0, baseline); -}; + var output = { + ascent: 0, + descent: 0, + fontSize: 0 + }; + var imagedata = context.getImageData(0, 0, width, height); -/***/ }), -/* 342 */ -/***/ (function(module, exports, __webpack_require__) { + if (!imagedata) + { + output.ascent = baseline; + output.descent = baseline + 6; + output.fontSize = output.ascent + output.descent; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + CanvasPool.remove(canvas); -/** - * @namespace Phaser.Math.Easing.Quartic - */ + return output; + } -module.exports = { + var pixels = imagedata.data; + var numPixels = pixels.length; + var line = width * 4; + var i; + var j; + var idx = 0; + var stop = false; - In: __webpack_require__(786), - Out: __webpack_require__(787), - InOut: __webpack_require__(788) + // 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 (pixels[idx + j] !== 255) + { + stop = true; + break; + } + } -}; + if (!stop) + { + idx += line; + } + else + { + break; + } + } + output.ascent = baseline - i; -/***/ }), -/* 343 */ -/***/ (function(module, exports, __webpack_require__) { + idx = numPixels - line; + stop = false; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // 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 (pixels[idx + j] !== 255) + { + stop = true; + break; + } + } -/** - * @namespace Phaser.Math.Easing.Quintic - */ + if (!stop) + { + idx -= line; + } + else + { + break; + } + } -module.exports = { + output.descent = (i - baseline); + output.fontSize = output.ascent + output.descent; - In: __webpack_require__(789), - Out: __webpack_require__(790), - InOut: __webpack_require__(791) + CanvasPool.remove(canvas); + return output; }; - -/***/ }), -/* 344 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Math.Easing.Sine - */ - -module.exports = { - - In: __webpack_require__(792), - Out: __webpack_require__(793), - InOut: __webpack_require__(794) - -}; +module.exports = MeasureText; /***/ }), -/* 345 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Math.Easing.Stepped - */ - -module.exports = __webpack_require__(795); - -/***/ }), -/* 346 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 76555: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(33); -var Device = __webpack_require__(347); -var GetFastValue = __webpack_require__(2); -var GetValue = __webpack_require__(6); -var IsPlainObject = __webpack_require__(7); -var PhaserMath = __webpack_require__(193); -var NOOP = __webpack_require__(1); -var DefaultPlugins = __webpack_require__(197); -var ValueToColor = __webpack_require__(187); +var AddToDOM = __webpack_require__(99584); +var CanvasPool = __webpack_require__(61068); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var GetTextSize = __webpack_require__(32979); +var GetValue = __webpack_require__(10850); +var RemoveFromDOM = __webpack_require__(55638); +var TextRender = __webpack_require__(80032); +var TextStyle = __webpack_require__(74744); /** * @classdesc - * The active game configuration settings, parsed from a {@link Phaser.Types.Core.GameConfig} object. + * A Text Game Object. * - * @class Config - * @memberof Phaser.Core + * Text objects work by creating their own internal hidden Canvas and then renders text to it using + * the standard Canvas `fillText` API. It then creates a texture from this canvas which is rendered + * to your game during the render pass. + * + * Because it uses the Canvas API you can take advantage of all the features this offers, such as + * applying gradient fills to the text, or strokes, shadows and more. You can also use custom fonts + * loaded externally, such as Google or TypeKit Web fonts. + * + * **Important:** The font name must be quoted if it contains certain combinations of digits or + * special characters, either when creating the Text object, or when setting the font via `setFont` + * or `setFontFamily`, e.g.: + * + * ```javascript + * this.add.text(0, 0, 'Hello World', { fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif' }); + * ``` + * + * ```javascript + * this.add.text(0, 0, 'Hello World', { font: '"Press Start 2P"' }); + * ``` + * + * You can only display fonts that are currently loaded and available to the browser: therefore fonts must + * be pre-loaded. Phaser does not do this for you, so you will require the use of a 3rd party font loader, + * or have the fonts ready available in the CSS on the page in which your Phaser game resides. + * + * See {@link http://www.jordanm.co.uk/tinytype this compatibility table} for the available default fonts + * across mobile browsers. + * + * A note on performance: Every time the contents of a Text object changes, i.e. changing the text being + * displayed, or the style of the text, it needs to remake the Text canvas, and if on WebGL, re-upload the + * new texture to the GPU. This can be an expensive operation if used often, or with large quantities of + * Text objects in your game. If you run into performance issues you would be better off using Bitmap Text + * instead, as it benefits from batching and avoids expensive Canvas API calls. + * + * @class Text + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects * @constructor * @since 3.0.0 * - * @param {Phaser.Types.Core.GameConfig} [GameConfig] - The configuration object for your Phaser Game instance. + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.ComputedSize + * @extends Phaser.GameObjects.Components.Crop + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Tint + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.Visible * - * @see Phaser.Game#config + * @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|string[])} text - The text this Text object will display. + * @param {Phaser.Types.GameObjects.Text.TextStyle} style - The text style configuration object. + * + * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Valid_family_names */ -var Config = new Class({ +var Text = new Class({ - initialize: + Extends: GameObject, - function Config (config) - { - if (config === undefined) { config = {}; } + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.ComputedSize, + Components.Crop, + Components.Depth, + Components.Flip, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Tint, + Components.Transform, + Components.Visible, + TextRender + ], - var defaultBannerColor = [ - '#ff0000', - '#ffff00', - '#00ff00', - '#00ffff', - '#000000' - ]; + initialize: - var defaultBannerTextColor = '#ffffff'; + function Text (scene, x, y, text, style) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } - /** - * @const {(number|string)} Phaser.Core.Config#width - The width of the underlying canvas, in pixels. - */ - this.width = GetValue(config, 'width', 1024); + GameObject.call(this, scene, 'Text'); /** - * @const {(number|string)} Phaser.Core.Config#height - The height of the underlying canvas, in pixels. + * The renderer in use by this Text object. + * + * @name Phaser.GameObjects.Text#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.12.0 */ - this.height = GetValue(config, 'height', 768); + this.renderer = scene.sys.renderer; - /** - * @const {(Phaser.Scale.ZoomType|number)} Phaser.Core.Config#zoom - The zoom factor, as used by the Scale Manager. - */ - this.zoom = GetValue(config, 'zoom', 1); + this.setPosition(x, y); + this.setOrigin(0, 0); + this.initPipeline(); + this.initPostPipeline(true); /** - * @const {?*} Phaser.Core.Config#parent - A parent DOM element into which the canvas created by the renderer will be injected. + * The canvas element that the text is rendered to. + * + * @name Phaser.GameObjects.Text#canvas + * @type {HTMLCanvasElement} + * @since 3.0.0 */ - this.parent = GetValue(config, 'parent', undefined); + this.canvas = CanvasPool.create(this); /** - * @const {Phaser.Scale.ScaleModeType} Phaser.Core.Config#scaleMode - The scale mode as used by the Scale Manager. The default is zero, which is no scaling. + * The context of the canvas element that the text is rendered to. + * + * @name Phaser.GameObjects.Text#context + * @type {CanvasRenderingContext2D} + * @since 3.0.0 */ - this.scaleMode = GetValue(config, 'scaleMode', 0); + this.context = this.canvas.getContext('2d', { willReadFrequently: true }); /** - * @const {boolean} Phaser.Core.Config#expandParent - Is the Scale Manager allowed to adjust the CSS height property of the parent to be 100%? + * The Text Style object. + * + * Manages the style of this Text object. + * + * @name Phaser.GameObjects.Text#style + * @type {Phaser.GameObjects.TextStyle} + * @since 3.0.0 */ - this.expandParent = GetValue(config, 'expandParent', true); + this.style = new TextStyle(this, style); /** - * @const {boolean} Phaser.Core.Config#autoRound - Automatically round the display and style sizes of the canvas. This can help with performance in lower-powered devices. + * Whether to automatically round line positions. + * + * @name Phaser.GameObjects.Text#autoRound + * @type {boolean} + * @default true + * @since 3.0.0 */ - this.autoRound = GetValue(config, 'autoRound', false); + this.autoRound = true; /** - * @const {Phaser.Scale.CenterType} Phaser.Core.Config#autoCenter - Automatically center the canvas within the parent? + * The Regular Expression that is used to split the text up into lines, in + * multi-line text. By default this is `/(?:\r\n|\r|\n)/`. + * You can change this RegExp to be anything else that you may need. + * + * @name Phaser.GameObjects.Text#splitRegExp + * @type {object} + * @since 3.0.0 */ - this.autoCenter = GetValue(config, 'autoCenter', 0); + this.splitRegExp = /(?:\r\n|\r|\n)/; /** - * @const {number} Phaser.Core.Config#resizeInterval - How many ms should elapse before checking if the browser size has changed? + * The text to display. + * + * @name Phaser.GameObjects.Text#_text + * @type {string} + * @private + * @since 3.12.0 */ - this.resizeInterval = GetValue(config, 'resizeInterval', 500); + this._text = undefined; /** - * @const {?(HTMLElement|string)} Phaser.Core.Config#fullscreenTarget - The DOM element that will be sent into full screen mode, or its `id`. If undefined Phaser will create its own div and insert the canvas into it when entering fullscreen mode. + * Specify a padding value which is added to the line width and height when calculating the Text size. + * Allows you to add extra spacing if the browser is unable to accurately determine the true font dimensions. + * + * @name Phaser.GameObjects.Text#padding + * @type {Phaser.Types.GameObjects.Text.TextPadding} + * @since 3.0.0 */ - this.fullscreenTarget = GetValue(config, 'fullscreenTarget', null); + this.padding = { left: 0, right: 0, top: 0, bottom: 0 }; /** - * @const {number} Phaser.Core.Config#minWidth - The minimum width, in pixels, the canvas will scale down to. A value of zero means no minimum. + * The width of this Text object. + * + * @name Phaser.GameObjects.Text#width + * @type {number} + * @default 1 + * @since 3.0.0 */ - this.minWidth = GetValue(config, 'minWidth', 0); + this.width = 1; /** - * @const {number} Phaser.Core.Config#maxWidth - The maximum width, in pixels, the canvas will scale up to. A value of zero means no maximum. + * The height of this Text object. + * + * @name Phaser.GameObjects.Text#height + * @type {number} + * @default 1 + * @since 3.0.0 */ - this.maxWidth = GetValue(config, 'maxWidth', 0); + this.height = 1; /** - * @const {number} Phaser.Core.Config#minHeight - The minimum height, in pixels, the canvas will scale down to. A value of zero means no minimum. + * The line spacing value. + * This value is added to the font height to calculate the overall line height. + * Only has an effect if this Text object contains multiple lines of text. + * + * If you update this property directly, instead of using the `setLineSpacing` method, then + * be sure to call `updateText` after, or you won't see the change reflected in the Text object. + * + * @name Phaser.GameObjects.Text#lineSpacing + * @type {number} + * @since 3.13.0 */ - this.minHeight = GetValue(config, 'minHeight', 0); + this.lineSpacing = 0; /** - * @const {number} Phaser.Core.Config#maxHeight - The maximum height, in pixels, the canvas will scale up to. A value of zero means no maximum. + * Whether the text or its settings have changed and need updating. + * + * @name Phaser.GameObjects.Text#dirty + * @type {boolean} + * @default false + * @since 3.0.0 */ - this.maxHeight = GetValue(config, 'maxHeight', 0); - - // Scale Manager - Anything set in here over-rides anything set above - - var scaleConfig = GetValue(config, 'scale', null); + this.dirty = false; - if (scaleConfig) + // If resolution wasn't set, force it to 1 + if (this.style.resolution === 0) { - this.width = GetValue(scaleConfig, 'width', this.width); - this.height = GetValue(scaleConfig, 'height', this.height); - this.zoom = GetValue(scaleConfig, 'zoom', this.zoom); - this.parent = GetValue(scaleConfig, 'parent', this.parent); - this.scaleMode = GetValue(scaleConfig, 'mode', this.scaleMode); - this.expandParent = GetValue(scaleConfig, 'expandParent', this.expandParent); - this.autoRound = GetValue(scaleConfig, 'autoRound', this.autoRound); - this.autoCenter = GetValue(scaleConfig, 'autoCenter', this.autoCenter); - this.resizeInterval = GetValue(scaleConfig, 'resizeInterval', this.resizeInterval); - this.fullscreenTarget = GetValue(scaleConfig, 'fullscreenTarget', this.fullscreenTarget); - this.minWidth = GetValue(scaleConfig, 'min.width', this.minWidth); - this.maxWidth = GetValue(scaleConfig, 'max.width', this.maxWidth); - this.minHeight = GetValue(scaleConfig, 'min.height', this.minHeight); - this.maxHeight = GetValue(scaleConfig, 'max.height', this.maxHeight); + this.style.resolution = 1; } /** - * @const {number} Phaser.Core.Config#renderType - Force Phaser to use a specific renderer. Can be `CONST.CANVAS`, `CONST.WEBGL`, `CONST.HEADLESS` or `CONST.AUTO` (default) + * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. + * + * @name Phaser.GameObjects.Text#_crop + * @type {object} + * @private + * @since 3.12.0 */ - this.renderType = GetValue(config, 'type', CONST.AUTO); + this._crop = this.resetCropObject(); - /** - * @const {?HTMLCanvasElement} Phaser.Core.Config#canvas - Force Phaser to use your own Canvas element instead of creating one. - */ - this.canvas = GetValue(config, 'canvas', null); + // Create a Texture for this Text object + this.texture = scene.sys.textures.addCanvas(null, this.canvas, true); - /** - * @const {?(CanvasRenderingContext2D|WebGLRenderingContext)} Phaser.Core.Config#context - Force Phaser to use your own Canvas context instead of creating one. - */ - this.context = GetValue(config, 'context', null); + // Get the frame + this.frame = this.texture.get(); - /** - * @const {?string} Phaser.Core.Config#canvasStyle - Optional CSS attributes to be set on the canvas object created by the renderer. - */ - this.canvasStyle = GetValue(config, 'canvasStyle', null); + // Set the resolution + this.frame.source.resolution = this.style.resolution; - /** - * @const {boolean} Phaser.Core.Config#customEnvironment - Is Phaser running under a custom (non-native web) environment? If so, set this to `true` to skip internal Feature detection. If `true` the `renderType` cannot be left as `AUTO`. - */ - this.customEnvironment = GetValue(config, 'customEnvironment', false); + if (this.renderer && this.renderer.gl) + { + // Clear the default 1x1 glTexture, as we override it later + this.renderer.deleteTexture(this.frame.source.glTexture); - /** - * @const {?object} Phaser.Core.Config#sceneConfig - The default Scene configuration object. - */ - this.sceneConfig = GetValue(config, 'scene', null); + this.frame.source.glTexture = null; + } - /** - * @const {string[]} Phaser.Core.Config#seed - A seed which the Random Data Generator will use. If not given, a dynamic seed based on the time is used. - */ - this.seed = GetValue(config, 'seed', [ (Date.now() * Math.random()).toString() ]); + this.initRTL(); - PhaserMath.RND = new PhaserMath.RandomDataGenerator(this.seed); + this.setText(text); - /** - * @const {string} Phaser.Core.Config#gameTitle - The title of the game. - */ - this.gameTitle = GetValue(config, 'title', ''); + if (style && style.padding) + { + this.setPadding(style.padding); + } - /** - * @const {string} Phaser.Core.Config#gameURL - The URL of the game. - */ - this.gameURL = GetValue(config, 'url', 'https://phaser.io'); + if (style && style.lineSpacing) + { + this.setLineSpacing(style.lineSpacing); + } + }, - /** - * @const {string} Phaser.Core.Config#gameVersion - The version of the game. - */ - this.gameVersion = GetValue(config, 'version', ''); + /** + * Initialize right to left text. + * + * @method Phaser.GameObjects.Text#initRTL + * @since 3.0.0 + */ + initRTL: function () + { + if (!this.style.rtl) + { + return; + } - /** - * @const {boolean} Phaser.Core.Config#autoFocus - If `true` the window will automatically be given focus immediately and on any future mousedown event. - */ - this.autoFocus = GetValue(config, 'autoFocus', true); + // Here is where the crazy starts. + // + // Due to browser implementation issues, you cannot fillText BiDi text to a canvas + // that is not part of the DOM. It just completely ignores the direction property. - // DOM Element Container + this.canvas.dir = 'rtl'; - /** - * @const {?boolean} Phaser.Core.Config#domCreateContainer - Should the game create a div element to act as a DOM Container? Only enable if you're using DOM Element objects. You must provide a parent object if you use this feature. - */ - this.domCreateContainer = GetValue(config, 'dom.createContainer', false); + // Experimental atm, but one day ... + this.context.direction = 'rtl'; - /** - * @const {?boolean} Phaser.Core.Config#domBehindCanvas - Should the DOM Container that is created (if `dom.createContainer` is true) be positioned behind (true) or over the top (false, the default) of the game canvas? - */ - this.domBehindCanvas = GetValue(config, 'dom.behindCanvas', false); + // Add it to the DOM, but hidden within the parent canvas. + this.canvas.style.display = 'none'; - /** - * @const {?string} Phaser.Core.Config#domPointerEvents - The default `pointerEvents` attribute set on the DOM Container. - */ - this.domPointerEvents = GetValue(config, 'dom.pointerEvents', 'none'); + AddToDOM(this.canvas, this.scene.sys.canvas); - // Input + // And finally we set the x origin + this.originX = 1; + }, - /** - * @const {boolean} Phaser.Core.Config#inputKeyboard - Enable the Keyboard Plugin. This can be disabled in games that don't need keyboard input. - */ - this.inputKeyboard = GetValue(config, 'input.keyboard', true); + /** + * Greedy wrapping algorithm that will wrap words as the line grows longer than its horizontal + * bounds. + * + * @method Phaser.GameObjects.Text#runWordWrap + * @since 3.0.0 + * + * @param {string} text - The text to perform word wrap detection against. + * + * @return {string} The text after wrapping has been applied. + */ + runWordWrap: function (text) + { + var style = this.style; - /** - * @const {*} Phaser.Core.Config#inputKeyboardEventTarget - The DOM Target to listen for keyboard events on. Defaults to `window` if not specified. - */ - this.inputKeyboardEventTarget = GetValue(config, 'input.keyboard.target', window); - - /** - * @const {?number[]} Phaser.Core.Config#inputKeyboardCapture - `preventDefault` will be called on every non-modified key which has a key code in this array. By default, it is empty. - */ - this.inputKeyboardCapture = GetValue(config, 'input.keyboard.capture', []); - - /** - * @const {(boolean|object)} Phaser.Core.Config#inputMouse - Enable the Mouse Plugin. This can be disabled in games that don't need mouse input. - */ - this.inputMouse = GetValue(config, 'input.mouse', true); - - /** - * @const {?*} Phaser.Core.Config#inputMouseEventTarget - The DOM Target to listen for mouse events on. Defaults to the game canvas if not specified. - */ - this.inputMouseEventTarget = GetValue(config, 'input.mouse.target', null); - - /** - * @const {boolean} Phaser.Core.Config#inputMousePreventDefaultDown - Should `mousedown` DOM events have `preventDefault` called on them? - */ - this.inputMousePreventDefaultDown = GetValue(config, 'input.mouse.preventDefaultDown', true); - - /** - * @const {boolean} Phaser.Core.Config#inputMousePreventDefaultUp - Should `mouseup` DOM events have `preventDefault` called on them? - */ - this.inputMousePreventDefaultUp = GetValue(config, 'input.mouse.preventDefaultUp', true); - - /** - * @const {boolean} Phaser.Core.Config#inputMousePreventDefaultMove - Should `mousemove` DOM events have `preventDefault` called on them? - */ - this.inputMousePreventDefaultMove = GetValue(config, 'input.mouse.preventDefaultMove', true); - - /** - * @const {boolean} Phaser.Core.Config#inputMousePreventDefaultWheel - Should `wheel` DOM events have `preventDefault` called on them? - */ - this.inputMousePreventDefaultWheel = GetValue(config, 'input.mouse.preventDefaultWheel', true); - - /** - * @const {boolean} Phaser.Core.Config#inputTouch - Enable the Touch Plugin. This can be disabled in games that don't need touch input. - */ - this.inputTouch = GetValue(config, 'input.touch', Device.input.touch); - - /** - * @const {?*} Phaser.Core.Config#inputTouchEventTarget - The DOM Target to listen for touch events on. Defaults to the game canvas if not specified. - */ - this.inputTouchEventTarget = GetValue(config, 'input.touch.target', null); - - /** - * @const {boolean} Phaser.Core.Config#inputTouchCapture - Should touch events be captured? I.e. have prevent default called on them. - */ - this.inputTouchCapture = GetValue(config, 'input.touch.capture', true); - - /** - * @const {number} Phaser.Core.Config#inputActivePointers - The number of Pointer objects created by default. In a mouse-only, or non-multi touch game, you can leave this as 1. - */ - this.inputActivePointers = GetValue(config, 'input.activePointers', 1); - - /** - * @const {number} Phaser.Core.Config#inputSmoothFactor - The smoothing factor to apply during Pointer movement. See {@link Phaser.Input.Pointer#smoothFactor}. - */ - this.inputSmoothFactor = GetValue(config, 'input.smoothFactor', 0); - - /** - * @const {boolean} Phaser.Core.Config#inputWindowEvents - Should Phaser listen for input events on the Window? If you disable this, events like 'POINTER_UP_OUTSIDE' will no longer fire. - */ - this.inputWindowEvents = GetValue(config, 'input.windowEvents', true); - - /** - * @const {boolean} Phaser.Core.Config#inputGamepad - Enable the Gamepad Plugin. This can be disabled in games that don't need gamepad input. - */ - this.inputGamepad = GetValue(config, 'input.gamepad', false); - - /** - * @const {*} Phaser.Core.Config#inputGamepadEventTarget - The DOM Target to listen for gamepad events on. Defaults to `window` if not specified. - */ - this.inputGamepadEventTarget = GetValue(config, 'input.gamepad.target', window); - - /** - * @const {boolean} Phaser.Core.Config#disableContextMenu - Set to `true` to disable the right-click context menu. - */ - this.disableContextMenu = GetValue(config, 'disableContextMenu', false); - - /** - * @const {Phaser.Types.Core.AudioConfig} Phaser.Core.Config#audio - The Audio Configuration object. - */ - this.audio = GetValue(config, 'audio', {}); - - // If you do: { banner: false } it won't display any banner at all - - /** - * @const {boolean} Phaser.Core.Config#hideBanner - Don't write the banner line to the console.log. - */ - this.hideBanner = (GetValue(config, 'banner', null) === false); - - /** - * @const {boolean} Phaser.Core.Config#hidePhaser - Omit Phaser's name and version from the banner. - */ - this.hidePhaser = GetValue(config, 'banner.hidePhaser', false); - - /** - * @const {string} Phaser.Core.Config#bannerTextColor - The color of the banner text. - */ - this.bannerTextColor = GetValue(config, 'banner.text', defaultBannerTextColor); + if (style.wordWrapCallback) + { + var wrappedLines = style.wordWrapCallback.call(style.wordWrapCallbackScope, text, this); - /** - * @const {string[]} Phaser.Core.Config#bannerBackgroundColor - The background colors of the banner. - */ - this.bannerBackgroundColor = GetValue(config, 'banner.background', defaultBannerColor); + if (Array.isArray(wrappedLines)) + { + wrappedLines = wrappedLines.join('\n'); + } - if (this.gameTitle === '' && this.hidePhaser) + return wrappedLines; + } + else if (style.wordWrapWidth) { - this.hideBanner = true; + if (style.wordWrapUseAdvanced) + { + return this.advancedWordWrap(text, this.context, this.style.wordWrapWidth); + } + else + { + return this.basicWordWrap(text, this.context, this.style.wordWrapWidth); + } } - - /** - * @const {Phaser.Types.Core.FPSConfig} Phaser.Core.Config#fps - The Frame Rate Configuration object, as parsed by the Timestep class. - */ - this.fps = GetValue(config, 'fps', null); - - // Renderer Settings - // These can either be in a `render` object within the Config, or specified on their own - - var renderConfig = GetValue(config, 'render', config); - - /** - * @const {Phaser.Types.Core.PipelineConfig} Phaser.Core.Config#pipeline - An object mapping WebGL names to WebGLPipeline classes. These should be class constructors, not instances. - */ - this.pipeline = GetValue(renderConfig, 'pipeline', null); - - /** - * @const {boolean} Phaser.Core.Config#antialias - When set to `true`, WebGL uses linear interpolation to draw scaled or rotated textures, giving a smooth appearance. When set to `false`, WebGL uses nearest-neighbor interpolation, giving a crisper appearance. `false` also disables antialiasing of the game canvas itself, if the browser supports it, when the game canvas is scaled. - */ - this.antialias = GetValue(renderConfig, 'antialias', true); - - /** - * @const {boolean} Phaser.Core.Config#antialiasGL - Sets the `antialias` property when the WebGL context is created. Setting this value does not impact any subsequent textures that are created, or the canvas style attributes. - */ - this.antialiasGL = GetValue(renderConfig, 'antialiasGL', true); - - /** - * @const {string} Phaser.Core.Config#mipmapFilter - Sets the `mipmapFilter` property when the WebGL renderer is created. - */ - this.mipmapFilter = GetValue(renderConfig, 'mipmapFilter', 'LINEAR'); - - /** - * @const {boolean} Phaser.Core.Config#desynchronized - When set to `true` it will create a desynchronized context for both 2D and WebGL. See https://developers.google.com/web/updates/2019/05/desynchronized for details. - */ - this.desynchronized = GetValue(renderConfig, 'desynchronized', false); - - /** - * @const {boolean} Phaser.Core.Config#roundPixels - Draw texture-based Game Objects at only whole-integer positions. Game Objects without textures, like Graphics, ignore this property. - */ - this.roundPixels = GetValue(renderConfig, 'roundPixels', false); - - /** - * @const {boolean} Phaser.Core.Config#pixelArt - Prevent pixel art from becoming blurred when scaled. It will remain crisp (tells the WebGL renderer to automatically create textures using a linear filter mode). - */ - this.pixelArt = GetValue(renderConfig, 'pixelArt', this.zoom !== 1); - - if (this.pixelArt) + else { - this.antialias = false; - this.antialiasGL = false; - this.roundPixels = true; + return text; } + }, - /** - * @const {boolean} Phaser.Core.Config#transparent - Whether the game canvas will have a transparent background. - */ - this.transparent = GetValue(renderConfig, 'transparent', false); + /** + * Advanced wrapping algorithm that will wrap words as the line grows longer than its horizontal + * bounds. Consecutive spaces will be collapsed and replaced with a single space. Lines will be + * trimmed of white space before processing. Throws an error if wordWrapWidth is less than a + * single character. + * + * @method Phaser.GameObjects.Text#advancedWordWrap + * @since 3.0.0 + * + * @param {string} text - The text to perform word wrap detection against. + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + * @param {number} wordWrapWidth - The word wrap width. + * + * @return {string} The wrapped text. + */ + advancedWordWrap: function (text, context, wordWrapWidth) + { + var output = ''; - /** - * @const {boolean} Phaser.Core.Config#clearBeforeRender - Whether the game canvas will be cleared between each rendering frame. You can disable this if you have a full-screen background image or game object. - */ - this.clearBeforeRender = GetValue(renderConfig, 'clearBeforeRender', true); + // Condense consecutive spaces and split into lines + var lines = text + .replace(/ +/gi, ' ') + .split(this.splitRegExp); - /** - * @const {boolean} Phaser.Core.Config#preserveDrawingBuffer - If the value is true the WebGL buffers will not be cleared and will preserve their values until cleared or overwritten by the author. - */ - this.preserveDrawingBuffer = GetValue(renderConfig, 'preserveDrawingBuffer', false); + var linesCount = lines.length; - /** - * @const {boolean} Phaser.Core.Config#premultipliedAlpha - In WebGL mode, sets the drawing buffer to contain colors with pre-multiplied alpha. - */ - this.premultipliedAlpha = GetValue(renderConfig, 'premultipliedAlpha', true); + for (var i = 0; i < linesCount; i++) + { + var line = lines[i]; + var out = ''; - /** - * @const {boolean} Phaser.Core.Config#failIfMajorPerformanceCaveat - Let the browser abort creating a WebGL context if it judges performance would be unacceptable. - */ - this.failIfMajorPerformanceCaveat = GetValue(renderConfig, 'failIfMajorPerformanceCaveat', false); + // Trim whitespace + line = line.replace(/^ *|\s*$/gi, ''); - /** - * @const {string} Phaser.Core.Config#powerPreference - "high-performance", "low-power" or "default". A hint to the browser on how much device power the game might use. - */ - this.powerPreference = GetValue(renderConfig, 'powerPreference', 'default'); + // If entire line is less than wordWrapWidth append the entire line and exit early + var lineWidth = context.measureText(line).width; - /** - * @const {number} Phaser.Core.Config#batchSize - The default WebGL Batch size. Represents the number of _quads_ that can be added to a single batch. - */ - this.batchSize = GetValue(renderConfig, 'batchSize', 4096); + if (lineWidth < wordWrapWidth) + { + output += line + '\n'; + continue; + } - /** - * @const {number} Phaser.Core.Config#maxTextures - When in WebGL mode, this sets the maximum number of GPU Textures to use. The default, -1, will use all available units. The WebGL1 spec says all browsers should provide a minimum of 8. - */ - this.maxTextures = GetValue(renderConfig, 'maxTextures', -1); + // Otherwise, calculate new lines + var currentLineWidth = wordWrapWidth; - /** - * @const {number} Phaser.Core.Config#maxLights - The maximum number of lights allowed to be visible within range of a single Camera in the LightManager. - */ - this.maxLights = GetValue(renderConfig, 'maxLights', 10); + // Split into words + var words = line.split(' '); - var bgc = GetValue(config, 'backgroundColor', 0); + for (var j = 0; j < words.length; j++) + { + var word = words[j]; + var wordWithSpace = word + ' '; + var wordWidth = context.measureText(wordWithSpace).width; - /** - * @const {Phaser.Display.Color} Phaser.Core.Config#backgroundColor - The background color of the game canvas. The default is black. This value is ignored if `transparent` is set to `true`. - */ - this.backgroundColor = ValueToColor(bgc); + if (wordWidth > currentLineWidth) + { + // Break word + if (j === 0) + { + // Shave off letters from word until it's small enough + var newWord = wordWithSpace; - if (this.transparent) - { - this.backgroundColor = ValueToColor(0x000000); - this.backgroundColor.alpha = 0; - } + while (newWord.length) + { + newWord = newWord.slice(0, -1); + wordWidth = context.measureText(newWord).width; - /** - * @const {Phaser.Types.Core.BootCallback} Phaser.Core.Config#preBoot - Called before Phaser boots. Useful for initializing anything not related to Phaser that Phaser may require while booting. - */ - this.preBoot = GetValue(config, 'callbacks.preBoot', NOOP); + if (wordWidth <= currentLineWidth) + { + break; + } + } - /** - * @const {Phaser.Types.Core.BootCallback} Phaser.Core.Config#postBoot - A function to run at the end of the boot sequence. At this point, all the game systems have started and plugins have been loaded. - */ - this.postBoot = GetValue(config, 'callbacks.postBoot', NOOP); + // If wordWrapWidth is too small for even a single letter, shame user + // failure with a fatal error + if (!newWord.length) + { + throw new Error('wordWrapWidth < a single character'); + } - /** - * @const {Phaser.Types.Core.PhysicsConfig} Phaser.Core.Config#physics - The Physics Configuration object. - */ - this.physics = GetValue(config, 'physics', {}); + // Replace current word in array with remainder + var secondPart = word.substr(newWord.length); - /** - * @const {(boolean|string)} Phaser.Core.Config#defaultPhysicsSystem - The default physics system. It will be started for each scene. Either 'arcade', 'impact' or 'matter'. - */ - this.defaultPhysicsSystem = GetValue(this.physics, 'default', false); + words[j] = secondPart; - /** - * @const {string} Phaser.Core.Config#loaderBaseURL - A URL used to resolve paths given to the loader. Example: 'http://labs.phaser.io/assets/'. - */ - this.loaderBaseURL = GetValue(config, 'loader.baseURL', ''); + // Append first piece to output + out += newWord; + } - /** - * @const {string} Phaser.Core.Config#loaderPath - A URL path used to resolve relative paths given to the loader. Example: 'images/sprites/'. - */ - this.loaderPath = GetValue(config, 'loader.path', ''); + // If existing word length is 0, don't include it + var offset = (words[j].length) ? j : j + 1; - /** - * @const {number} Phaser.Core.Config#loaderMaxParallelDownloads - Maximum parallel downloads allowed for resources (Default to 32). - */ - var defaultParallel = (Device.os.android) ? 6 : 32; + // Collapse rest of sentence and remove any trailing white space + var remainder = words.slice(offset).join(' ').replace(/[ \n]*$/gi, ''); - this.loaderMaxParallelDownloads = GetValue(config, 'loader.maxParallelDownloads', defaultParallel); + // Prepend remainder to next line + lines.splice(i + 1, 0, remainder); - /** - * @const {(string|undefined)} Phaser.Core.Config#loaderCrossOrigin - 'anonymous', 'use-credentials', or `undefined`. If you're not making cross-origin requests, leave this as `undefined`. See {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes}. - */ - this.loaderCrossOrigin = GetValue(config, 'loader.crossOrigin', undefined); + linesCount = lines.length; - /** - * @const {string} Phaser.Core.Config#loaderResponseType - The response type of the XHR request, e.g. `blob`, `text`, etc. - */ - this.loaderResponseType = GetValue(config, 'loader.responseType', ''); + break; // Processing on this line - /** - * @const {boolean} Phaser.Core.Config#loaderAsync - Should the XHR request use async or not? - */ - this.loaderAsync = GetValue(config, 'loader.async', true); + // Append word with space to output + } + else + { + out += wordWithSpace; + currentLineWidth -= wordWidth; + } + } - /** - * @const {string} Phaser.Core.Config#loaderUser - Optional username for all XHR requests. - */ - this.loaderUser = GetValue(config, 'loader.user', ''); + // Append processed line to output + output += out.replace(/[ \n]*$/gi, '') + '\n'; + } - /** - * @const {string} Phaser.Core.Config#loaderPassword - Optional password for all XHR requests. - */ - this.loaderPassword = GetValue(config, 'loader.password', ''); + // Trim the end of the string + output = output.replace(/[\s|\n]*$/gi, ''); - /** - * @const {number} Phaser.Core.Config#loaderTimeout - Optional XHR timeout value, in ms. - */ - this.loaderTimeout = GetValue(config, 'loader.timeout', 0); + return output; + }, - /** - * @const {boolean} Phaser.Core.Config#loaderWithCredentials - Optional XHR withCredentials value. - */ - this.loaderWithCredentials = GetValue(config, 'loader.withCredentials', false); + /** + * Greedy wrapping algorithm that will wrap words as the line grows longer than its horizontal + * bounds. Spaces are not collapsed and whitespace is not trimmed. + * + * @method Phaser.GameObjects.Text#basicWordWrap + * @since 3.0.0 + * + * @param {string} text - The text to perform word wrap detection against. + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + * @param {number} wordWrapWidth - The word wrap width. + * + * @return {string} The wrapped text. + */ + basicWordWrap: function (text, context, wordWrapWidth) + { + var result = ''; + var lines = text.split(this.splitRegExp); + var lastLineIndex = lines.length - 1; + var whiteSpaceWidth = context.measureText(' ').width; - /* - * Allows `plugins` property to either be an array, in which case it just replaces - * the default plugins like previously, or a config object. - * - * plugins: { - * global: [ - * { key: 'TestPlugin', plugin: TestPlugin, start: true, data: { msg: 'The plugin is alive' } }, - * ], - * scene: [ - * { key: 'WireFramePlugin', plugin: WireFramePlugin, systemKey: 'wireFramePlugin', sceneKey: 'wireframe' } - * ], - * default: [], OR - * defaultMerge: [ - * 'ModPlayer' - * ] - * } - */ + for (var i = 0; i <= lastLineIndex; i++) + { + var spaceLeft = wordWrapWidth; + var words = lines[i].split(' '); + var lastWordIndex = words.length - 1; - /** - * @const {any} Phaser.Core.Config#installGlobalPlugins - An array of global plugins to be installed. - */ - this.installGlobalPlugins = []; + for (var j = 0; j <= lastWordIndex; j++) + { + var word = words[j]; + var wordWidth = context.measureText(word).width; + var wordWidthWithSpace = wordWidth; - /** - * @const {any} Phaser.Core.Config#installScenePlugins - An array of Scene level plugins to be installed. - */ - this.installScenePlugins = []; + if (j < lastWordIndex) + { + wordWidthWithSpace += whiteSpaceWidth; + } - var plugins = GetValue(config, 'plugins', null); - var defaultPlugins = DefaultPlugins.DefaultScene; + if (wordWidthWithSpace > spaceLeft) + { + // Skip printing the newline if it's the first word of the line that is greater + // than the word wrap width. + if (j > 0) + { + result += '\n'; + spaceLeft = wordWrapWidth; + } + } - if (plugins) - { - // Old 3.7 array format? - if (Array.isArray(plugins)) - { - this.defaultPlugins = plugins; - } - else if (IsPlainObject(plugins)) - { - this.installGlobalPlugins = GetFastValue(plugins, 'global', []); - this.installScenePlugins = GetFastValue(plugins, 'scene', []); + result += word; - if (Array.isArray(plugins.default)) + if (j < lastWordIndex) { - defaultPlugins = plugins.default; + result += ' '; + spaceLeft -= wordWidthWithSpace; } - else if (Array.isArray(plugins.defaultMerge)) + else { - defaultPlugins = defaultPlugins.concat(plugins.defaultMerge); + spaceLeft -= wordWidth; } } - } - - /** - * @const {any} Phaser.Core.Config#defaultPlugins - The plugins installed into every Scene (in addition to CoreScene and Global). - */ - this.defaultPlugins = defaultPlugins; - - // Default / Missing Images - var pngPrefix = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg'; - - /** - * @const {string} Phaser.Core.Config#defaultImage - A base64 encoded PNG that will be used as the default blank texture. - */ - this.defaultImage = GetValue(config, 'images.default', pngPrefix + 'AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=='); - - /** - * @const {string} Phaser.Core.Config#missingImage - A base64 encoded PNG that will be used as the default texture when a texture is assigned that is missing or not loaded. - */ - this.missingImage = GetValue(config, 'images.missing', pngPrefix + 'CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=='); - - /** - * @const {string} Phaser.Core.Config#whiteImage - A base64 encoded PNG that will be used as the default texture when a texture is assigned that is white or not loaded. - */ - this.whiteImage = GetValue(config, 'images.white', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC'); - if (window) - { - if (window.FORCE_WEBGL) - { - this.renderType = CONST.WEBGL; - } - else if (window.FORCE_CANVAS) + if (i < lastLineIndex) { - this.renderType = CONST.CANVAS; + result += '\n'; } } - } - -}); -module.exports = Config; + return result; + }, + /** + * Runs the given text through this Text objects word wrapping and returns the results as an + * array, where each element of the array corresponds to a wrapped line of text. + * + * @method Phaser.GameObjects.Text#getWrappedText + * @since 3.0.0 + * + * @param {string} [text] - The text for which the wrapping will be calculated. If unspecified, the Text objects current text will be used. + * + * @return {string[]} An array of strings with the pieces of wrapped text. + */ + getWrappedText: function (text) + { + if (text === undefined) { text = this._text; } -/***/ }), -/* 347 */ -/***/ (function(module, exports, __webpack_require__) { + this.style.syncFont(this.canvas, this.context); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var wrappedLines = this.runWordWrap(text); -// This singleton is instantiated as soon as Phaser loads, -// before a Phaser.Game instance has even been created. -// Which means all instances of Phaser Games can share it, -// without having to re-poll the device all over again + return wrappedLines.split(this.splitRegExp); + }, -/** - * @namespace Phaser.Device - * @since 3.0.0 - */ + /** + * Set the text to display. + * + * An array of strings will be joined with `\n` line breaks. + * + * @method Phaser.GameObjects.Text#setText + * @since 3.0.0 + * + * @param {(string|string[])} value - The string, or array of strings, to be set as the content of this Text object. + * + * @return {this} This Text object. + */ + setText: function (value) + { + if (!value && value !== 0) + { + value = ''; + } -/** - * @typedef {object} Phaser.DeviceConf - * - * @property {Phaser.Device.OS} os - The OS Device functions. - * @property {Phaser.Device.Browser} browser - The Browser Device functions. - * @property {Phaser.Device.Features} features - The Features Device functions. - * @property {Phaser.Device.Input} input - The Input Device functions. - * @property {Phaser.Device.Audio} audio - The Audio Device functions. - * @property {Phaser.Device.Video} video - The Video Device functions. - * @property {Phaser.Device.Fullscreen} fullscreen - The Fullscreen Device functions. - * @property {Phaser.Device.CanvasFeatures} canvasFeatures - The Canvas Device functions. - */ + if (Array.isArray(value)) + { + value = value.join('\n'); + } -module.exports = { + if (value !== this._text) + { + this._text = value.toString(); - os: __webpack_require__(105), - browser: __webpack_require__(136), - features: __webpack_require__(191), - input: __webpack_require__(808), - audio: __webpack_require__(809), - video: __webpack_require__(810), - fullscreen: __webpack_require__(811), - canvasFeatures: __webpack_require__(348) + this.updateText(); + } -}; + return this; + }, + /** + * Appends the given text to the content already being displayed by this Text object. + * + * An array of strings will be joined with `\n` line breaks. + * + * @method Phaser.GameObjects.Text#appendText + * @since 3.60.0 + * + * @param {(string|string[])} value - The string, or array of strings, to be appended to the existing content of this Text object. + * @param {boolean} [addCR=true] - Insert a carriage-return before the string value. + * + * @return {this} This Text object. + */ + appendText: function (value, addCR) + { + if (addCR === undefined) { addCR = true; } -/***/ }), -/* 348 */ -/***/ (function(module, exports, __webpack_require__) { + if (!value && value !== 0) + { + value = ''; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (Array.isArray(value)) + { + value = value.join('\n'); + } -var CanvasPool = __webpack_require__(31); + value = value.toString(); -/** - * Determines the canvas features of the browser running this Phaser Game instance. - * These values are read-only and populated during the boot sequence of the game. - * They are then referenced by internal game systems and are available for you to access - * via `this.sys.game.device.canvasFeatures` from within any Scene. - * - * @typedef {object} Phaser.Device.CanvasFeatures - * @since 3.0.0 - * - * @property {boolean} supportInverseAlpha - Set to true if the browser supports inversed alpha. - * @property {boolean} supportNewBlendModes - Set to true if the browser supports new canvas blend modes. - */ -var CanvasFeatures = { + var newText = this._text.concat((addCR) ? '\n' + value : value); - supportInverseAlpha: false, - supportNewBlendModes: false + if (newText !== this._text) + { + this._text = newText; -}; + this.updateText(); + } -function checkBlendMode () -{ - var pngHead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/'; - var pngEnd = 'AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=='; + return this; + }, - var magenta = new Image(); + /** + * Set the text style. + * + * @example + * text.setStyle({ + * fontSize: '64px', + * fontFamily: 'Arial', + * color: '#ffffff', + * align: 'center', + * backgroundColor: '#ff00ff' + * }); + * + * @method Phaser.GameObjects.Text#setStyle + * @since 3.0.0 + * + * @param {object} style - The style settings to set. + * + * @return {this} This Text object. + */ + setStyle: function (style) + { + return this.style.setStyle(style); + }, - magenta.onload = function () + /** + * 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. + * + * **Important:** The font name must be quoted if it contains certain combinations of digits or + * special characters: + * + * ```javascript + * Text.setFont('"Press Start 2P"'); + * ``` + * + * Equally, if you wish to provide a list of fallback fonts, then you should ensure they are all + * quoted properly, too: + * + * ```javascript + * Text.setFont('Georgia, "Goudy Bookletter 1911", Times, serif'); + * ``` + * + * @method Phaser.GameObjects.Text#setFont + * @since 3.0.0 + * + * @param {string} font - The font family or font settings to set. + * + * @return {this} This Text object. + * + * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Valid_family_names + */ + setFont: function (font) { - var yellow = new Image(); + return this.style.setFont(font); + }, - yellow.onload = function () - { - var canvas = CanvasPool.create(yellow, 6, 1); - var context = canvas.getContext('2d'); + /** + * Set the font family. + * + * **Important:** The font name must be quoted if it contains certain combinations of digits or + * special characters: + * + * ```javascript + * Text.setFont('"Press Start 2P"'); + * ``` + * + * Equally, if you wish to provide a list of fallback fonts, then you should ensure they are all + * quoted properly, too: + * + * ```javascript + * Text.setFont('Georgia, "Goudy Bookletter 1911", Times, serif'); + * ``` + * + * @method Phaser.GameObjects.Text#setFontFamily + * @since 3.0.0 + * + * @param {string} family - The font family. + * + * @return {this} This Text object. + * + * @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Valid_family_names + */ + setFontFamily: function (family) + { + return this.style.setFontFamily(family); + }, - context.globalCompositeOperation = 'multiply'; + /** + * Set the font size. Can be a string with a valid CSS unit, i.e. `16px`, or a number. + * + * @method Phaser.GameObjects.Text#setFontSize + * @since 3.0.0 + * + * @param {(string|number)} size - The font size. + * + * @return {this} This Text object. + */ + setFontSize: function (size) + { + return this.style.setFontSize(size); + }, - context.drawImage(magenta, 0, 0); - context.drawImage(yellow, 2, 0); + /** + * Set the font style. + * + * @method Phaser.GameObjects.Text#setFontStyle + * @since 3.0.0 + * + * @param {string} style - The font style. + * + * @return {this} This Text object. + */ + setFontStyle: function (style) + { + return this.style.setFontStyle(style); + }, - if (!context.getImageData(2, 0, 1, 1)) - { - return false; - } + /** + * 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.Text#setFixedSize + * @since 3.0.0 + * + * @param {number} width - The fixed width to set. `0` disables fixed width. + * @param {number} height - The fixed height to set. `0` disables fixed height. + * + * @return {this} This Text object. + */ + setFixedSize: function (width, height) + { + return this.style.setFixedSize(width, height); + }, - var data = context.getImageData(2, 0, 1, 1).data; + /** + * Set the background color. + * + * @method Phaser.GameObjects.Text#setBackgroundColor + * @since 3.0.0 + * + * @param {string} color - The background color. + * + * @return {this} This Text object. + */ + setBackgroundColor: function (color) + { + return this.style.setBackgroundColor(color); + }, - CanvasPool.remove(yellow); + /** + * Set the fill style to be used by the Text object. + * + * This can be any valid CanvasRenderingContext2D fillStyle value, such as + * a color (in hex, rgb, rgba, hsl or named values), a gradient or a pattern. + * + * See the [MDN fillStyle docs](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle) for more details. + * + * @method Phaser.GameObjects.Text#setFill + * @since 3.0.0 + * + * @param {(string|any)} color - The text fill style. Can be any valid CanvasRenderingContext `fillStyle` value. + * + * @return {this} This Text object. + */ + setFill: function (fillStyle) + { + return this.style.setFill(fillStyle); + }, - CanvasFeatures.supportNewBlendModes = (data[0] === 255 && data[1] === 0 && data[2] === 0); - }; + /** + * Set the text fill color. + * + * @method Phaser.GameObjects.Text#setColor + * @since 3.0.0 + * + * @param {string} color - The text fill color. + * + * @return {this} This Text object. + */ + setColor: function (color) + { + return this.style.setColor(color); + }, - yellow.src = pngHead + '/wCKxvRF' + pngEnd; - }; + /** + * Set the stroke settings. + * + * @method Phaser.GameObjects.Text#setStroke + * @since 3.0.0 + * + * @param {string} color - The stroke color. + * @param {number} thickness - The stroke thickness. + * + * @return {this} This Text object. + */ + setStroke: function (color, thickness) + { + return this.style.setStroke(color, thickness); + }, - magenta.src = pngHead + 'AP804Oa6' + pngEnd; + /** + * Set the shadow settings. + * + * @method Phaser.GameObjects.Text#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 {this} This Text object. + */ + setShadow: function (x, y, color, blur, shadowStroke, shadowFill) + { + return this.style.setShadow(x, y, color, blur, shadowStroke, shadowFill); + }, - return false; -} + /** + * Set the shadow offset. + * + * @method Phaser.GameObjects.Text#setShadowOffset + * @since 3.0.0 + * + * @param {number} x - The horizontal shadow offset. + * @param {number} y - The vertical shadow offset. + * + * @return {this} This Text object. + */ + setShadowOffset: function (x, y) + { + return this.style.setShadowOffset(x, y); + }, -function checkInverseAlpha () -{ - var canvas = CanvasPool.create(this, 2, 1); - var context = canvas.getContext('2d'); + /** + * Set the shadow color. + * + * @method Phaser.GameObjects.Text#setShadowColor + * @since 3.0.0 + * + * @param {string} color - The shadow color. + * + * @return {this} This Text object. + */ + setShadowColor: function (color) + { + return this.style.setShadowColor(color); + }, - context.fillStyle = 'rgba(10, 20, 30, 0.5)'; + /** + * Set the shadow blur radius. + * + * @method Phaser.GameObjects.Text#setShadowBlur + * @since 3.0.0 + * + * @param {number} blur - The shadow blur radius. + * + * @return {this} This Text object. + */ + setShadowBlur: function (blur) + { + return this.style.setShadowBlur(blur); + }, - // Draw a single pixel - context.fillRect(0, 0, 1, 1); + /** + * Enable or disable shadow stroke. + * + * @method Phaser.GameObjects.Text#setShadowStroke + * @since 3.0.0 + * + * @param {boolean} enabled - Whether shadow stroke is enabled or not. + * + * @return {this} This Text object. + */ + setShadowStroke: function (enabled) + { + return this.style.setShadowStroke(enabled); + }, - // Get the color values - var s1 = context.getImageData(0, 0, 1, 1); + /** + * Enable or disable shadow fill. + * + * @method Phaser.GameObjects.Text#setShadowFill + * @since 3.0.0 + * + * @param {boolean} enabled - Whether shadow fill is enabled or not. + * + * @return {this} This Text object. + */ + setShadowFill: function (enabled) + { + return this.style.setShadowFill(enabled); + }, - if (s1 === null) + /** + * Set the width (in pixels) to use for wrapping lines. Pass in null to remove wrapping by width. + * + * @method Phaser.GameObjects.Text#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 {this} This Text object. + */ + setWordWrapWidth: function (width, useAdvancedWrap) { - return false; - } + return this.style.setWordWrapWidth(width, useAdvancedWrap); + }, - // Plot them to x2 - context.putImageData(s1, 1, 0); + /** + * Set a custom callback for wrapping lines. Pass in null to remove wrapping by callback. + * + * @method Phaser.GameObjects.Text#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 {this} This Text object. + */ + setWordWrapCallback: function (callback, scope) + { + return this.style.setWordWrapCallback(callback, scope); + }, - // Get those values - var s2 = context.getImageData(1, 0, 1, 1); + /** + * 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.Text#setAlign + * @since 3.0.0 + * + * @param {string} [align='left'] - The text alignment for multi-line text. + * + * @return {this} This Text object. + */ + setAlign: function (align) + { + return this.style.setAlign(align); + }, - // Compare and return - return (s2.data[0] === s1.data[0] && s2.data[1] === s1.data[1] && s2.data[2] === s1.data[2] && s2.data[3] === s1.data[3]); -} + /** + * Set the resolution used by this 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, or by specifying it in the Text style configuration object. + * + * 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. + * + * Therefore, please use with caution, as the more high res Text you have, the more memory it uses. + * + * @method Phaser.GameObjects.Text#setResolution + * @since 3.12.0 + * + * @param {number} value - The resolution for this Text object to use. + * + * @return {this} This Text object. + */ + setResolution: function (value) + { + return this.style.setResolution(value); + }, -function init () -{ - if (typeof importScripts !== 'function' && document !== undefined) + /** + * Sets the line spacing value. + * + * This value is _added_ to the height of the font when calculating the overall line height. + * This only has an effect if this Text object consists of multiple lines of text. + * + * @method Phaser.GameObjects.Text#setLineSpacing + * @since 3.13.0 + * + * @param {number} value - The amount to add to the font height to achieve the overall line height. + * + * @return {this} This Text object. + */ + setLineSpacing: function (value) { - CanvasFeatures.supportNewBlendModes = checkBlendMode(); - CanvasFeatures.supportInverseAlpha = checkInverseAlpha(); - } + this.lineSpacing = value; - return CanvasFeatures; -} - -module.exports = init(); - - -/***/ }), -/* 349 */ -/***/ (function(module, exports) { + return this.updateText(); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Set the text padding. + * + * 'left' can be an object. + * + * If only 'left' and 'top' are given they are treated as 'x' and 'y'. + * + * @method Phaser.GameObjects.Text#setPadding + * @since 3.0.0 + * + * @param {(number|Phaser.Types.GameObjects.Text.TextPadding)} left - The left padding value, or a padding config object. + * @param {number} [top] - The top padding value. + * @param {number} [right] - The right padding value. + * @param {number} [bottom] - The bottom padding value. + * + * @return {this} This Text object. + */ + setPadding: function (left, top, right, bottom) + { + if (typeof left === 'object') + { + var config = left; -/** - * Find the angle of a segment from (x1, y1) -> (x2, y2). - * - * @function Phaser.Math.Angle.Between - * @since 3.0.0 - * - * @param {number} x1 - The x coordinate of the first point. - * @param {number} y1 - The y coordinate of the first point. - * @param {number} x2 - The x coordinate of the second point. - * @param {number} y2 - The y coordinate of the second point. - * - * @return {number} The angle in radians. - */ -var Between = function (x1, y1, x2, y2) -{ - return Math.atan2(y2 - y1, x2 - x1); -}; + // If they specify x and/or y this applies to all + var x = GetValue(config, 'x', null); -module.exports = Between; + if (x !== null) + { + left = x; + right = x; + } + else + { + left = GetValue(config, 'left', 0); + right = GetValue(config, 'right', left); + } + var y = GetValue(config, 'y', null); -/***/ }), -/* 350 */ -/***/ (function(module, exports) { + if (y !== null) + { + top = y; + bottom = y; + } + else + { + top = GetValue(config, 'top', 0); + bottom = GetValue(config, 'bottom', top); + } + } + else + { + if (left === undefined) { left = 0; } + if (top === undefined) { top = left; } + if (right === undefined) { right = left; } + if (bottom === undefined) { bottom = top; } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.padding.left = left; + this.padding.top = top; + this.padding.right = right; + this.padding.bottom = bottom; -/** - * Find the angle of a segment from (point1.x, point1.y) -> (point2.x, point2.y). - * - * Calculates the angle of the vector from the first point to the second point. - * - * @function Phaser.Math.Angle.BetweenPoints - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} point1 - The first point. - * @param {Phaser.Types.Math.Vector2Like} point2 - The second point. - * - * @return {number} The angle in radians. - */ -var BetweenPoints = function (point1, point2) -{ - return Math.atan2(point2.y - point1.y, point2.x - point1.x); -}; + return this.updateText(); + }, -module.exports = BetweenPoints; + /** + * Set the maximum number of lines to draw. + * + * @method Phaser.GameObjects.Text#setMaxLines + * @since 3.0.0 + * + * @param {number} [max=0] - The maximum number of lines to draw. + * + * @return {this} This Text object. + */ + setMaxLines: function (max) + { + return this.style.setMaxLines(max); + }, + /** + * Update the displayed text. + * + * @method Phaser.GameObjects.Text#updateText + * @since 3.0.0 + * + * @return {this} This Text object. + */ + updateText: function () + { + var canvas = this.canvas; + var context = this.context; + var style = this.style; + var resolution = style.resolution; + var size = style.metrics; -/***/ }), -/* 351 */ -/***/ (function(module, exports) { + style.syncFont(canvas, context); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var outputText = this._text; -/** - * Normalize an angle to the [0, 2pi] range. - * - * @function Phaser.Math.Angle.Normalize - * @since 3.0.0 - * - * @param {number} angle - The angle to normalize, in radians. - * - * @return {number} The normalized angle, in radians. - */ -var Normalize = function (angle) -{ - angle = angle % (2 * Math.PI); + if (style.wordWrapWidth || style.wordWrapCallback) + { + outputText = this.runWordWrap(this._text); + } - if (angle >= 0) - { - return angle; - } - else - { - return angle + 2 * Math.PI; - } -}; + // Split text into lines + var lines = outputText.split(this.splitRegExp); -module.exports = Normalize; + var textSize = GetTextSize(this, size, lines); + var padding = this.padding; -/***/ }), -/* 352 */ -/***/ (function(module, exports) { + var textWidth; -/** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (style.fixedWidth === 0) + { + this.width = textSize.width + padding.left + padding.right; -/** - * Calculate the distance between two points. - * - * @function Phaser.Math.Distance.BetweenPoints - * @since 3.22.0 - * - * @param {Phaser.Types.Math.Vector2Like} a - The first point. - * @param {Phaser.Types.Math.Vector2Like} b - The second point. - * - * @return {number} The distance between the points. - */ -var DistanceBetweenPoints = function (a, b) -{ - var dx = a.x - b.x; - var dy = a.y - b.y; + textWidth = textSize.width; + } + else + { + this.width = style.fixedWidth; - return Math.sqrt(dx * dx + dy * dy); -}; + textWidth = this.width - padding.left - padding.right; -module.exports = DistanceBetweenPoints; + if (textWidth < textSize.width) + { + textWidth = textSize.width; + } + } + if (style.fixedHeight === 0) + { + this.height = textSize.height + padding.top + padding.bottom; + } + else + { + this.height = style.fixedHeight; + } -/***/ }), -/* 353 */ -/***/ (function(module, exports) { + var w = this.width; + var h = this.height; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.updateDisplayOrigin(); -/** - * Calculate the distance between two sets of coordinates (points), squared. - * - * @function Phaser.Math.Distance.Squared - * @since 3.0.0 - * - * @param {number} x1 - The x coordinate of the first point. - * @param {number} y1 - The y coordinate of the first point. - * @param {number} x2 - The x coordinate of the second point. - * @param {number} y2 - The y coordinate of the second point. - * - * @return {number} The distance between each point, squared. - */ -var DistanceSquared = function (x1, y1, x2, y2) -{ - var dx = x1 - x2; - var dy = y1 - y2; + w *= resolution; + h *= resolution; - return dx * dx + dy * dy; -}; + w = Math.max(w, 1); + h = Math.max(h, 1); -module.exports = DistanceSquared; + if (canvas.width !== w || canvas.height !== h) + { + canvas.width = w; + canvas.height = h; + this.frame.setSize(w, h); -/***/ }), -/* 354 */ -/***/ (function(module, exports) { + // Because resizing the canvas resets the context + style.syncFont(canvas, context); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (style.rtl) + { + context.direction = 'rtl'; + } + } + else + { + context.clearRect(0, 0, w, h); + } -/** - * Check whether `a` is fuzzily greater than `b`. - * - * `a` is fuzzily greater than `b` if it is more than `b - epsilon`. - * - * @function Phaser.Math.Fuzzy.GreaterThan - * @since 3.0.0 - * - * @param {number} a - The first value. - * @param {number} b - The second value. - * @param {number} [epsilon=0.0001] - The epsilon. - * - * @return {boolean} `true` if `a` is fuzzily greater than than `b`, otherwise `false`. - */ -var GreaterThan = function (a, b, epsilon) -{ - if (epsilon === undefined) { epsilon = 0.0001; } + context.save(); - return a > b - epsilon; -}; + context.scale(resolution, resolution); -module.exports = GreaterThan; + if (style.backgroundColor) + { + context.fillStyle = style.backgroundColor; + context.fillRect(0, 0, w, h); + } + style.syncStyle(canvas, context); -/***/ }), -/* 355 */ -/***/ (function(module, exports) { + // Apply padding + context.translate(padding.left, padding.top); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var linePositionX; + var linePositionY; -/** - * Check whether `a` is fuzzily less than `b`. - * - * `a` is fuzzily less than `b` if it is less than `b + epsilon`. - * - * @function Phaser.Math.Fuzzy.LessThan - * @since 3.0.0 - * - * @param {number} a - The first value. - * @param {number} b - The second value. - * @param {number} [epsilon=0.0001] - The epsilon. - * - * @return {boolean} `true` if `a` is fuzzily less than `b`, otherwise `false`. - */ -var LessThan = function (a, b, epsilon) -{ - if (epsilon === undefined) { epsilon = 0.0001; } + // Draw text line by line + for (var i = 0; i < textSize.lines; i++) + { + linePositionX = style.strokeThickness / 2; + linePositionY = (style.strokeThickness / 2 + i * textSize.lineHeight) + size.ascent; - return a < b + epsilon; -}; + if (i > 0) + { + linePositionY += (textSize.lineSpacing * i); + } -module.exports = LessThan; + if (style.rtl) + { + linePositionX = w - linePositionX - padding.left - padding.right; + } + else if (style.align === 'right') + { + linePositionX += textWidth - textSize.lineWidths[i]; + } + else if (style.align === 'center') + { + linePositionX += (textWidth - textSize.lineWidths[i]) / 2; + } + else if (style.align === 'justify') + { + // To justify text line its width must be no less than 85% of defined width + var minimumLengthToApplyJustification = 0.85; + if (textSize.lineWidths[i] / textSize.width >= minimumLengthToApplyJustification) + { + var extraSpace = textSize.width - textSize.lineWidths[i]; + var spaceSize = context.measureText(' ').width; + var trimmedLine = lines[i].trim(); + var array = trimmedLine.split(' '); -/***/ }), -/* 356 */ -/***/ (function(module, exports, __webpack_require__) { + extraSpace += (lines[i].length - trimmedLine.length) * spaceSize; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var extraSpaceCharacters = Math.floor(extraSpace / spaceSize); + var idx = 0; -var Factorial = __webpack_require__(357); + while (extraSpaceCharacters > 0) + { + array[idx] += ' '; + idx = (idx + 1) % (array.length - 1 || 1); + --extraSpaceCharacters; + } -/** - * Calculates the Bernstein basis from the three factorial coefficients. - * - * @function Phaser.Math.Bernstein - * @since 3.0.0 - * - * @param {number} n - The first value. - * @param {number} i - The second value. - * - * @return {number} The Bernstein basis of Factorial(n) / Factorial(i) / Factorial(n - i) - */ -var Bernstein = function (n, i) -{ - return Factorial(n) / Factorial(i) / Factorial(n - i); -}; + lines[i] = array.join(' '); + } + } -module.exports = Bernstein; + if (this.autoRound) + { + linePositionX = Math.round(linePositionX); + linePositionY = Math.round(linePositionY); + } + if (style.strokeThickness) + { + style.syncShadow(context, style.shadowStroke); -/***/ }), -/* 357 */ -/***/ (function(module, exports) { + context.strokeText(lines[i], linePositionX, linePositionY); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (style.color) + { + style.syncShadow(context, style.shadowFill); -/** - * Calculates the factorial of a given number for integer values greater than 0. - * - * @function Phaser.Math.Factorial - * @since 3.0.0 - * - * @param {number} value - A positive integer to calculate the factorial of. - * - * @return {number} The factorial of the given number. - */ -var Factorial = function (value) -{ - if (value === 0) - { - return 1; - } + context.fillText(lines[i], linePositionX, linePositionY); + } + } - var res = value; + context.restore(); - while (--value) - { - res *= value; - } + if (this.renderer && this.renderer.gl) + { + this.frame.source.glTexture = this.renderer.canvasToTexture(canvas, this.frame.source.glTexture, true); - return res; -}; + this.frame.glTexture = this.frame.source.glTexture; -module.exports = Factorial; + if (false) + {} + } + this.dirty = true; -/***/ }), -/* 358 */ -/***/ (function(module, exports) { + var input = this.input; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (input && !input.customHitArea) + { + input.hitArea.width = this.width; + input.hitArea.height = this.height; + } -/** - * @ignore - */ -function P0 (t, p) -{ - var k = 1 - t; + return this; + }, - return k * k * k * p; -} + /** + * Get the current text metrics. + * + * @method Phaser.GameObjects.Text#getTextMetrics + * @since 3.0.0 + * + * @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics. + */ + getTextMetrics: function () + { + return this.style.getTextMetrics(); + }, -/** - * @ignore - */ -function P1 (t, p) -{ - var k = 1 - t; + /** + * The text string being rendered by this Text Game Object. + * + * @name Phaser.GameObjects.Text#text + * @type {string} + * @since 3.0.0 + */ + text: { - return 3 * k * k * t * p; -} + get: function () + { + return this._text; + }, -/** - * @ignore - */ -function P2 (t, p) -{ - return 3 * (1 - t) * t * t * p; -} + set: function (value) + { + this.setText(value); + } -/** - * @ignore - */ -function P3 (t, p) -{ - return t * t * t * p; -} + }, -/** - * A cubic bezier interpolation method. - * - * https://medium.com/@adrian_cooney/bezier-interpolation-13b68563313a - * - * @function Phaser.Math.Interpolation.CubicBezier - * @since 3.0.0 - * - * @param {number} t - The percentage of interpolation, between 0 and 1. - * @param {number} p0 - The start point. - * @param {number} p1 - The first control point. - * @param {number} p2 - The second control point. - * @param {number} p3 - The end point. - * - * @return {number} The interpolated value. - */ -var CubicBezierInterpolation = function (t, p0, p1, p2, p3) -{ - return P0(t, p0) + P1(t, p1) + P2(t, p2) + P3(t, p3); -}; + /** + * Build a JSON representation of the Text object. + * + * @method Phaser.GameObjects.Text#toJSON + * @since 3.0.0 + * + * @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Text object. + */ + toJSON: function () + { + var out = Components.ToJSON(this); -module.exports = CubicBezierInterpolation; + // Extra Text data is added here + var data = { + autoRound: this.autoRound, + text: this._text, + style: this.style.toJSON(), + padding: { + left: this.padding.left, + right: this.padding.right, + top: this.padding.top, + bottom: this.padding.bottom + } + }; -/***/ }), -/* 359 */ -/***/ (function(module, exports) { + out.data = data; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return out; + }, -/** - * @ignore - */ -function P0 (t, p) -{ - var k = 1 - t; + /** + * Internal destroy handler, called as part of the destroy process. + * + * @method Phaser.GameObjects.Text#preDestroy + * @protected + * @since 3.0.0 + */ + preDestroy: function () + { + if (this.style.rtl) + { + RemoveFromDOM(this.canvas); + } - return k * k * p; -} + CanvasPool.remove(this.canvas); -/** - * @ignore - */ -function P1 (t, p) -{ - return 2 * (1 - t) * t * p; -} + this.texture.destroy(); + } -/** - * @ignore - */ -function P2 (t, p) -{ - return t * t * p; -} + /** + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. + * + * @name Phaser.GameObjects.Text#originX + * @type {number} + * @default 0 + * @since 3.0.0 + */ -// https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js + /** + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * + * @name Phaser.GameObjects.Text#originY + * @type {number} + * @default 0 + * @since 3.0.0 + */ -/** - * A quadratic bezier interpolation method. - * - * @function Phaser.Math.Interpolation.QuadraticBezier - * @since 3.2.0 - * - * @param {number} t - The percentage of interpolation, between 0 and 1. - * @param {number} p0 - The start point. - * @param {number} p1 - The control point. - * @param {number} p2 - The end point. - * - * @return {number} The interpolated value. - */ -var QuadraticBezierInterpolation = function (t, p0, p1, p2) -{ - return P0(t, p0) + P1(t, p1) + P2(t, p2); -}; +}); -module.exports = QuadraticBezierInterpolation; +module.exports = Text; /***/ }), -/* 360 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71649: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SmoothStep = __webpack_require__(184); - /** - * A Smooth Step interpolation method. - * - * @function Phaser.Math.Interpolation.SmoothStep - * @since 3.9.0 - * @see {@link https://en.wikipedia.org/wiki/Smoothstep} + * 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. * - * @param {number} t - The percentage of interpolation, between 0 and 1. - * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'. - * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'. + * @method Phaser.GameObjects.Text#renderCanvas + * @since 3.0.0 + * @private * - * @return {number} The interpolated value. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Text} 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 SmoothStepInterpolation = function (t, min, max) +var TextCanvasRenderer = function (renderer, src, camera, parentMatrix) { - return min + (max - min) * SmoothStep(t, 0, 1); + if (src.width === 0 || src.height === 0) + { + return; + } + + camera.addToRenderList(src); + + renderer.batchSprite(src, src.frame, camera, parentMatrix); }; -module.exports = SmoothStepInterpolation; +module.exports = TextCanvasRenderer; /***/ }), -/* 361 */ -/***/ (function(module, exports) { + +/***/ 75397: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var Text = __webpack_require__(76555); + /** - * Returns the nearest power of 2 to the given `value`. + * Creates a new Text Game Object and returns it. * - * @function Phaser.Math.Pow2.GetNext + * Note: This method will only be available if the Text Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#text * @since 3.0.0 * - * @param {number} value - The value. + * @param {Phaser.Types.GameObjects.Text.TextConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. * - * @return {number} The nearest power of 2 to `value`. + * @return {Phaser.GameObjects.Text} The Game Object that was created. */ -var GetPowerOfTwo = function (value) +GameObjectCreator.register('text', function (config, addToScene) { - var index = Math.log(value) / 0.6931471805599453; + if (config === undefined) { config = {}; } - return (1 << Math.ceil(index)); -}; + // style Object = { + // font: [ 'font', '16px Courier' ], + // backgroundColor: [ 'backgroundColor', null ], + // fill: [ 'fill', '#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', false ], + // fixedHeight: [ 'fixedHeight', false ], + // rtl: [ 'rtl', false ] + // } -module.exports = GetPowerOfTwo; + var content = GetAdvancedValue(config, 'text', ''); + var style = GetAdvancedValue(config, 'style', null); + + // Padding + // { padding: 2 } + // { padding: { x: , y: }} + // { padding: { left: , top: }} + // { padding: { left: , right: , top: , bottom: }} + + var padding = GetAdvancedValue(config, 'padding', null); + + if (padding !== null) + { + style.padding = padding; + } + + var text = new Text(this.scene, 0, 0, content, style); + + if (addToScene !== undefined) + { + config.add = addToScene; + } + + BuildGameObject(this.scene, text, config); + + // Text specific config options: + + text.autoRound = GetAdvancedValue(config, 'autoRound', true); + text.resolution = GetAdvancedValue(config, 'resolution', 1); + + return text; +}); + +// When registering a factory function 'this' refers to the GameObjectCreator context. /***/ }), -/* 362 */ -/***/ (function(module, exports) { + +/***/ 94627: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Text = __webpack_require__(76555); +var GameObjectFactory = __webpack_require__(61286); + /** - * Rotate a given point by a given angle around the origin (0, 0), in an anti-clockwise direction. + * Creates a new Text Game Object and adds it to the Scene. * - * @function Phaser.Math.Rotate + * A Text Game Object. + * + * Text objects work by creating their own internal hidden Canvas and then renders text to it using + * the standard Canvas `fillText` API. It then creates a texture from this canvas which is rendered + * to your game during the render pass. + * + * Because it uses the Canvas API you can take advantage of all the features this offers, such as + * applying gradient fills to the text, or strokes, shadows and more. You can also use custom fonts + * loaded externally, such as Google or TypeKit Web fonts. + * + * You can only display fonts that are currently loaded and available to the browser: therefore fonts must + * be pre-loaded. Phaser does not do ths for you, so you will require the use of a 3rd party font loader, + * or have the fonts ready available in the CSS on the page in which your Phaser game resides. + * + * See {@link http://www.jordanm.co.uk/tinytype this compatibility table} for the available default fonts + * across mobile browsers. + * + * A note on performance: Every time the contents of a Text object changes, i.e. changing the text being + * displayed, or the style of the text, it needs to remake the Text canvas, and if on WebGL, re-upload the + * new texture to the GPU. This can be an expensive operation if used often, or with large quantities of + * Text objects in your game. If you run into performance issues you would be better off using Bitmap Text + * instead, as it benefits from batching and avoids expensive Canvas API calls. + * + * Note: This method will only be available if the Text Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#text * @since 3.0.0 * - * @param {(Phaser.Geom.Point|object)} point - The point to be rotated. - * @param {number} angle - The angle to be rotated by in an anticlockwise direction. + * @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|string[])} text - The text this Text object will display. + * @param {Phaser.Types.GameObjects.Text.TextStyle} [style] - The Text style configuration object. * - * @return {Phaser.Geom.Point} The given point, rotated by the given angle in an anticlockwise direction. + * @return {Phaser.GameObjects.Text} The Game Object that was created. */ -var Rotate = function (point, angle) +GameObjectFactory.register('text', function (x, y, text, style) { - var x = point.x; - var y = point.y; - - point.x = (x * Math.cos(angle)) - (y * Math.sin(angle)); - point.y = (x * Math.sin(angle)) + (y * Math.cos(angle)); - - return point; -}; + return this.displayList.add(new Text(this.scene, x, y, text, style)); +}); -module.exports = Rotate; +// When registering a factory function 'this' refers to the GameObjectFactory 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 /***/ }), -/* 363 */ -/***/ (function(module, exports) { + +/***/ 80032: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * Round a given number so it is further away from zero. That is, positive numbers are rounded up, and negative numbers are rounded down. - * - * @function Phaser.Math.RoundAwayFromZero - * @since 3.0.0 - * - * @param {number} value - The number to round. - * - * @return {number} The rounded number, rounded away from zero. - */ -var RoundAwayFromZero = function (value) +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) { - // "Opposite" of truncate. - return (value > 0) ? Math.ceil(value) : Math.floor(value); -}; + renderWebGL = __webpack_require__(76128); +} -module.exports = RoundAwayFromZero; +if (true) +{ + renderCanvas = __webpack_require__(71649); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; /***/ }), -/* 364 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 74744: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji -// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl +var Class = __webpack_require__(56694); +var GetAdvancedValue = __webpack_require__(20494); +var GetValue = __webpack_require__(10850); +var MeasureText = __webpack_require__(27030); -var Class = __webpack_require__(0); +// 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 three-dimensional matrix. + * A TextStyle class manages all of the style settings for a Text object. * - * Defaults to the identity matrix when instantiated. + * 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 Matrix3 - * @memberof Phaser.Math + * @class TextStyle + * @memberof Phaser.GameObjects * @constructor * @since 3.0.0 * - * @param {Phaser.Math.Matrix3} [m] - Optional Matrix3 to copy values from. + * @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 Matrix3 = new Class({ +var TextStyle = new Class({ initialize: - function Matrix3 (m) + function TextStyle (text, style) { /** - * The matrix values. + * The Text object that this TextStyle is styling. * - * @name Phaser.Math.Matrix3#val - * @type {Float32Array} + * @name Phaser.GameObjects.TextStyle#parent + * @type {Phaser.GameObjects.Text} * @since 3.0.0 */ - this.val = new Float32Array(9); + this.parent = text; - if (m) - { - // Assume Matrix3 with val: - this.copy(m); - } - else - { - // Default to identity - this.identity(); - } - }, + /** + * The font family. + * + * @name Phaser.GameObjects.TextStyle#fontFamily + * @type {string} + * @default 'Courier' + * @since 3.0.0 + */ + this.fontFamily; - /** - * Make a clone of this Matrix3. - * - * @method Phaser.Math.Matrix3#clone - * @since 3.0.0 - * - * @return {Phaser.Math.Matrix3} A clone of this Matrix3. - */ - clone: function () - { - return new Matrix3(this); - }, + /** + * The font size. + * + * @name Phaser.GameObjects.TextStyle#fontSize + * @type {(string|number)} + * @default '16px' + * @since 3.0.0 + */ + this.fontSize; - /** - * This method is an alias for `Matrix3.copy`. - * - * @method Phaser.Math.Matrix3#set - * @since 3.0.0 - * - * @param {Phaser.Math.Matrix3} src - The Matrix to set the values of this Matrix's from. - * - * @return {Phaser.Math.Matrix3} This Matrix3. - */ - set: function (src) - { - return this.copy(src); - }, + /** + * The font style. + * + * @name Phaser.GameObjects.TextStyle#fontStyle + * @type {string} + * @since 3.0.0 + */ + this.fontStyle; - /** - * Copy the values of a given Matrix into this Matrix. - * - * @method Phaser.Math.Matrix3#copy - * @since 3.0.0 - * - * @param {Phaser.Math.Matrix3} src - The Matrix to copy the values from. - * - * @return {Phaser.Math.Matrix3} This Matrix3. - */ - copy: function (src) - { - var out = this.val; - var a = src.val; + /** + * The background color. + * + * @name Phaser.GameObjects.TextStyle#backgroundColor + * @type {string} + * @since 3.0.0 + */ + this.backgroundColor; - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - out[6] = a[6]; - out[7] = a[7]; - out[8] = a[8]; + /** + * The text fill color. + * + * @name Phaser.GameObjects.TextStyle#color + * @type {string} + * @default '#fff' + * @since 3.0.0 + */ + this.color; - return this; - }, + /** + * The text stroke color. + * + * @name Phaser.GameObjects.TextStyle#stroke + * @type {string} + * @default '#fff' + * @since 3.0.0 + */ + this.stroke; - /** - * Copy the values of a given Matrix4 into this Matrix3. - * - * @method Phaser.Math.Matrix3#fromMat4 - * @since 3.0.0 - * - * @param {Phaser.Math.Matrix4} m - The Matrix4 to copy the values from. - * - * @return {Phaser.Math.Matrix3} This Matrix3. - */ - fromMat4: function (m) - { - var a = m.val; - var out = this.val; - - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[4]; - out[4] = a[5]; - out[5] = a[6]; - out[6] = a[8]; - out[7] = a[9]; - out[8] = a[10]; - - return this; - }, + /** + * The text stroke thickness. + * + * @name Phaser.GameObjects.TextStyle#strokeThickness + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.strokeThickness; - /** - * Set the values of this Matrix from the given array. - * - * @method Phaser.Math.Matrix3#fromArray - * @since 3.0.0 - * - * @param {array} a - The array to copy the values from. - * - * @return {Phaser.Math.Matrix3} This Matrix3. - */ - fromArray: function (a) - { - var out = this.val; + /** + * The horizontal shadow offset. + * + * @name Phaser.GameObjects.TextStyle#shadowOffsetX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.shadowOffsetX; - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - out[6] = a[6]; - out[7] = a[7]; - out[8] = a[8]; + /** + * The vertical shadow offset. + * + * @name Phaser.GameObjects.TextStyle#shadowOffsetY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.shadowOffsetY; - return this; - }, + /** + * The shadow color. + * + * @name Phaser.GameObjects.TextStyle#shadowColor + * @type {string} + * @default '#000' + * @since 3.0.0 + */ + this.shadowColor; - /** - * Reset this Matrix to an identity (default) matrix. - * - * @method Phaser.Math.Matrix3#identity - * @since 3.0.0 - * - * @return {Phaser.Math.Matrix3} This Matrix3. - */ - identity: function () - { - var out = this.val; + /** + * The shadow blur radius. + * + * @name Phaser.GameObjects.TextStyle#shadowBlur + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.shadowBlur; - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 1; - out[5] = 0; - out[6] = 0; - out[7] = 0; - out[8] = 1; + /** + * Whether shadow stroke is enabled or not. + * + * @name Phaser.GameObjects.TextStyle#shadowStroke + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.shadowStroke; - return this; - }, + /** + * Whether shadow fill is enabled or not. + * + * @name Phaser.GameObjects.TextStyle#shadowFill + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.shadowFill; - /** - * Transpose this Matrix. - * - * @method Phaser.Math.Matrix3#transpose - * @since 3.0.0 - * - * @return {Phaser.Math.Matrix3} This Matrix3. - */ - transpose: function () - { - var a = this.val; - var a01 = a[1]; - var a02 = a[2]; - var a12 = a[5]; + /** + * The text alignment. + * + * @name Phaser.GameObjects.TextStyle#align + * @type {string} + * @default 'left' + * @since 3.0.0 + */ + this.align; - a[1] = a[3]; - a[2] = a[6]; - a[3] = a01; - a[5] = a[7]; - a[6] = a02; - a[7] = a12; + /** + * The maximum number of lines to draw. + * + * @name Phaser.GameObjects.TextStyle#maxLines + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.maxLines; - return this; - }, + /** + * 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; - /** - * Invert this Matrix. - * - * @method Phaser.Math.Matrix3#invert - * @since 3.0.0 - * - * @return {Phaser.Math.Matrix3} This Matrix3. - */ - invert: function () - { - var a = this.val; + /** + * 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; - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a10 = a[3]; - var a11 = a[4]; - var a12 = a[5]; - var a20 = a[6]; - var a21 = a[7]; - var a22 = a[8]; + /** + * 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; - var b01 = a22 * a11 - a12 * a21; - var b11 = -a22 * a10 + a12 * a20; - var b21 = a21 * a10 - a11 * a20; + /** + * Whether the text should render right to left. + * + * @name Phaser.GameObjects.TextStyle#rtl + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.rtl; - // Calculate the determinant - var det = a00 * b01 + a01 * b11 + a02 * b21; + /** + * 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; - if (!det) - { - return null; - } + /** + * 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; - det = 1 / det; + /** + * 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; - a[0] = b01 * det; - a[1] = (-a22 * a01 + a02 * a21) * det; - a[2] = (a12 * a01 - a02 * a11) * det; - a[3] = b11 * det; - a[4] = (a22 * a00 - a02 * a20) * det; - a[5] = (-a12 * a00 + a02 * a10) * det; - a[6] = b21 * det; - a[7] = (-a21 * a00 + a01 * a20) * det; - a[8] = (a11 * a00 - a01 * a10) * det; + /** + * 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; - return this; - }, + /** + * 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; - /** - * Calculate the adjoint, or adjugate, of this Matrix. - * - * @method Phaser.Math.Matrix3#adjoint - * @since 3.0.0 - * - * @return {Phaser.Math.Matrix3} This Matrix3. - */ - adjoint: function () - { - var a = this.val; + /** + * 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; - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a10 = a[3]; - var a11 = a[4]; - var a12 = a[5]; - var a20 = a[6]; - var a21 = a[7]; - var a22 = a[8]; + /** + * 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; - a[0] = (a11 * a22 - a12 * a21); - a[1] = (a02 * a21 - a01 * a22); - a[2] = (a01 * a12 - a02 * a11); - a[3] = (a12 * a20 - a10 * a22); - a[4] = (a00 * a22 - a02 * a20); - a[5] = (a02 * a10 - a00 * a12); - a[6] = (a10 * a21 - a11 * a20); - a[7] = (a01 * a20 - a00 * a21); - a[8] = (a00 * a11 - a01 * a10); + /** + * The font style, size and family. + * + * @name Phaser.GameObjects.TextStyle#_font + * @type {string} + * @private + * @since 3.0.0 + */ + this._font; - return this; + // Set to defaults + user style + this.setStyle(style, false, true); }, /** - * Calculate the determinant of this Matrix. + * Set the text style. * - * @method Phaser.Math.Matrix3#determinant + * @example + * text.setStyle({ + * fontSize: '64px', + * fontFamily: 'Arial', + * color: '#ffffff', + * align: 'center', + * backgroundColor: '#ff00ff' + * }); + * + * @method Phaser.GameObjects.TextStyle#setStyle * @since 3.0.0 * - * @return {number} The determinant of this Matrix. + * @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. */ - determinant: function () + setStyle: function (style, updateText, setDefaults) { - var a = this.val; + if (updateText === undefined) { updateText = true; } + if (setDefaults === undefined) { setDefaults = false; } - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a10 = a[3]; - var a11 = a[4]; - var a12 = a[5]; - var a20 = a[6]; - var a21 = a[7]; - var a22 = a[8]; + // 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'; + } - return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); - }, + for (var key in propertyMap) + { + var value = (setDefaults) ? propertyMap[key][1] : this[key]; - /** - * Multiply this Matrix by the given Matrix. - * - * @method Phaser.Math.Matrix3#multiply - * @since 3.0.0 - * - * @param {Phaser.Math.Matrix3} src - The Matrix to multiply this Matrix by. - * - * @return {Phaser.Math.Matrix3} This Matrix3. - */ - multiply: function (src) - { - var a = this.val; + 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); + } + } - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a10 = a[3]; - var a11 = a[4]; - var a12 = a[5]; - var a20 = a[6]; - var a21 = a[7]; - var a22 = a[8]; + // Allow for 'font' override + var font = GetValue(style, 'font', null); - var b = src.val; + if (font !== null) + { + this.setFont(font, false); + } - var b00 = b[0]; - var b01 = b[1]; - var b02 = b[2]; - var b10 = b[3]; - var b11 = b[4]; - var b12 = b[5]; - var b20 = b[6]; - var b21 = b[7]; - var b22 = b[8]; + this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); - a[0] = b00 * a00 + b01 * a10 + b02 * a20; - a[1] = b00 * a01 + b01 * a11 + b02 * a21; - a[2] = b00 * a02 + b01 * a12 + b02 * a22; + // Allow for 'fill' to be used in place of 'color' + var fill = GetValue(style, 'fill', null); - a[3] = b10 * a00 + b11 * a10 + b12 * a20; - a[4] = b10 * a01 + b11 * a11 + b12 * a21; - a[5] = b10 * a02 + b11 * a12 + b12 * a22; + if (fill !== null) + { + this.color = fill; + } - a[6] = b20 * a00 + b21 * a10 + b22 * a20; - a[7] = b20 * a01 + b21 * a11 + b22 * a21; - a[8] = b20 * a02 + b21 * a12 + b22 * a22; + var metrics = GetValue(style, 'metrics', false); - return this; + // 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 if (updateText || !this.metrics) + { + this.metrics = MeasureText(this); + } + + if (updateText) + { + return this.parent.updateText(); + } + else + { + return this.parent; + } }, /** - * Translate this Matrix using the given Vector. + * Synchronize the font settings to the given Canvas Rendering Context. * - * @method Phaser.Math.Matrix3#translate + * @method Phaser.GameObjects.TextStyle#syncFont * @since 3.0.0 * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to translate this Matrix with. - * - * @return {Phaser.Math.Matrix3} This Matrix3. + * @param {HTMLCanvasElement} canvas - The Canvas Element. + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. */ - translate: function (v) + syncFont: function (canvas, context) { - var a = this.val; - var x = v.x; - var y = v.y; - - a[6] = x * a[0] + y * a[3] + a[6]; - a[7] = x * a[1] + y * a[4] + a[7]; - a[8] = x * a[2] + y * a[5] + a[8]; - - return this; + context.font = this._font; }, /** - * Apply a rotation transformation to this Matrix. + * Synchronize the text style settings to the given Canvas Rendering Context. * - * @method Phaser.Math.Matrix3#rotate + * @method Phaser.GameObjects.TextStyle#syncStyle * @since 3.0.0 * - * @param {number} rad - The angle in radians to rotate by. - * - * @return {Phaser.Math.Matrix3} This Matrix3. + * @param {HTMLCanvasElement} canvas - The Canvas Element. + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. */ - rotate: function (rad) + syncStyle: function (canvas, context) { - var a = this.val; - - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a10 = a[3]; - var a11 = a[4]; - var a12 = a[5]; - - var s = Math.sin(rad); - var c = Math.cos(rad); - - a[0] = c * a00 + s * a10; - a[1] = c * a01 + s * a11; - a[2] = c * a02 + s * a12; + context.textBaseline = 'alphabetic'; - a[3] = c * a10 - s * a00; - a[4] = c * a11 - s * a01; - a[5] = c * a12 - s * a02; + context.fillStyle = this.color; + context.strokeStyle = this.stroke; - return this; + context.lineWidth = this.strokeThickness; + context.lineCap = 'round'; + context.lineJoin = 'round'; }, /** - * Apply a scale transformation to this Matrix. - * - * Uses the `x` and `y` components of the given Vector to scale the Matrix. + * Synchronize the shadow settings to the given Canvas Rendering Context. * - * @method Phaser.Math.Matrix3#scale + * @method Phaser.GameObjects.TextStyle#syncShadow * @since 3.0.0 * - * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to scale this Matrix with. - * - * @return {Phaser.Math.Matrix3} This Matrix3. + * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + * @param {boolean} enabled - Whether shadows are enabled or not. */ - scale: function (v) + syncShadow: function (context, enabled) { - var a = this.val; - var x = v.x; - var y = v.y; - - a[0] = x * a[0]; - a[1] = x * a[1]; - a[2] = x * a[2]; - - a[3] = y * a[3]; - a[4] = y * a[4]; - a[5] = y * a[5]; - - return this; + 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; + } }, /** - * Set the values of this Matrix from the given Quaternion. + * Update the style settings for the parent Text object. * - * @method Phaser.Math.Matrix3#fromQuat + * @method Phaser.GameObjects.TextStyle#update * @since 3.0.0 * - * @param {Phaser.Math.Quaternion} q - The Quaternion to set the values of this Matrix from. + * @param {boolean} recalculateMetrics - Whether to recalculate font and text metrics. * - * @return {Phaser.Math.Matrix3} This Matrix3. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - fromQuat: function (q) + update: function (recalculateMetrics) { - var x = q.x; - var y = q.y; - var z = q.z; - var w = q.w; - - var x2 = x + x; - var y2 = y + y; - var z2 = z + z; - - var xx = x * x2; - var xy = x * y2; - var xz = x * z2; - - var yy = y * y2; - var yz = y * z2; - var zz = z * z2; - - var wx = w * x2; - var wy = w * y2; - var wz = w * z2; - - var out = this.val; - - out[0] = 1 - (yy + zz); - out[3] = xy + wz; - out[6] = xz - wy; - - out[1] = xy - wz; - out[4] = 1 - (xx + zz); - out[7] = yz + wx; + if (recalculateMetrics) + { + this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); - out[2] = xz + wy; - out[5] = yz - wx; - out[8] = 1 - (xx + yy); + this.metrics = MeasureText(this); + } - return this; + return this.parent.updateText(); }, /** - * Set the values of this Matrix3 to be normalized from the given Matrix4. + * Set the font. * - * @method Phaser.Math.Matrix3#normalFromMat4 + * 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 {Phaser.Math.Matrix4} m - The Matrix4 to normalize the values from. + * @param {(string|object)} font - The font family or font settings to set. + * @param {boolean} [updateText=true] - Whether to update the text immediately. * - * @return {Phaser.Math.Matrix3} This Matrix3. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - normalFromMat4: function (m) + setFont: function (font, updateText) { - var a = m.val; - var out = this.val; - - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a03 = a[3]; - - var a10 = a[4]; - var a11 = a[5]; - var a12 = a[6]; - var a13 = a[7]; - - var a20 = a[8]; - var a21 = a[9]; - var a22 = a[10]; - var a23 = a[11]; - - var a30 = a[12]; - var a31 = a[13]; - var a32 = a[14]; - var a33 = a[15]; - - var b00 = a00 * a11 - a01 * a10; - var b01 = a00 * a12 - a02 * a10; - var b02 = a00 * a13 - a03 * a10; - var b03 = a01 * a12 - a02 * a11; - - var b04 = a01 * a13 - a03 * a11; - var b05 = a02 * a13 - a03 * a12; - var b06 = a20 * a31 - a21 * a30; - var b07 = a20 * a32 - a22 * a30; - - var b08 = a20 * a33 - a23 * a30; - var b09 = a21 * a32 - a22 * a31; - var b10 = a21 * a33 - a23 * a31; - var b11 = a22 * a33 - a23 * a32; + if (updateText === undefined) { updateText = true; } - // Calculate the determinant - var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + var fontFamily = font; + var fontSize = ''; + var fontStyle = ''; - if (!det) + if (typeof font !== 'string') { - return null; + fontFamily = GetValue(font, 'fontFamily', 'Courier'); + fontSize = GetValue(font, 'fontSize', '16px'); + fontStyle = GetValue(font, 'fontStyle', ''); } + else + { + var fontSplit = font.split(' '); - det = 1 / det; - - out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; - out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; - out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; - - out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; - out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; - out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; - - out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; - out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; - out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; - - return this; - } - -}); - -module.exports = Matrix3; - - -/***/ }), -/* 365 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji -// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl - -var Class = __webpack_require__(0); -var Matrix3 = __webpack_require__(364); -var NOOP = __webpack_require__(1); -var Vector3 = __webpack_require__(39); - -var EPSILON = 0.000001; - -// Some shared 'private' arrays -var siNext = new Int8Array([ 1, 2, 0 ]); -var tmp = new Float32Array([ 0, 0, 0 ]); - -var xUnitVec3 = new Vector3(1, 0, 0); -var yUnitVec3 = new Vector3(0, 1, 0); - -var tmpvec = new Vector3(); -var tmpMat3 = new Matrix3(); - -/** - * @classdesc - * A quaternion. - * - * @class Quaternion - * @memberof Phaser.Math - * @constructor - * @since 3.0.0 - * - * @param {number} [x=0] - The x component. - * @param {number} [y=0] - The y component. - * @param {number} [z=0] - The z component. - * @param {number} [w=1] - The w component. - */ -var Quaternion = new Class({ - - initialize: - - function Quaternion (x, y, z, w) - { - /** - * The x component of this Quaternion. - * - * @name Phaser.Math.Quaternion#_x - * @type {number} - * @default 0 - * @private - * @since 3.50.0 - */ - - /** - * The y component of this Quaternion. - * - * @name Phaser.Math.Quaternion#_y - * @type {number} - * @default 0 - * @private - * @since 3.50.0 - */ - - /** - * The z component of this Quaternion. - * - * @name Phaser.Math.Quaternion#_z - * @type {number} - * @default 0 - * @private - * @since 3.50.0 - */ - - /** - * The w component of this Quaternion. - * - * @name Phaser.Math.Quaternion#_w - * @type {number} - * @default 0 - * @private - * @since 3.50.0 - */ - - /** - * This callback is invoked, if set, each time a value in this quaternion is changed. - * The callback is passed one argument, a reference to this quaternion. - * - * @name Phaser.Math.Quaternion#onChangeCallback - * @type {function} - * @since 3.50.0 - */ - this.onChangeCallback = NOOP; - - this.set(x, y, z, w); - }, + var i = 0; - /** - * The x component of this Quaternion. - * - * @name Phaser.Math.Quaternion#x - * @type {number} - * @default 0 - * @since 3.0.0 - */ - x: { - get: function () - { - return this._x; - }, + fontStyle = (fontSplit.length > 2) ? fontSplit[i++] : ''; + fontSize = fontSplit[i++] || '16px'; + fontFamily = fontSplit[i++] || 'Courier'; + } - set: function (value) + if (fontFamily !== this.fontFamily || fontSize !== this.fontSize || fontStyle !== this.fontStyle) { - this._x = value; + this.fontFamily = fontFamily; + this.fontSize = fontSize; + this.fontStyle = fontStyle; - this.onChangeCallback(this); + if (updateText) + { + this.update(true); + } } + + return this.parent; }, /** - * The y component of this Quaternion. + * Set the font family. * - * @name Phaser.Math.Quaternion#y - * @type {number} - * @default 0 + * @method Phaser.GameObjects.TextStyle#setFontFamily * @since 3.0.0 + * + * @param {string} family - The font family. + * + * @return {Phaser.GameObjects.Text} The parent Text object. */ - y: { - get: function () - { - return this._y; - }, - - set: function (value) + setFontFamily: function (family) + { + if (this.fontFamily !== family) { - this._y = value; + this.fontFamily = family; - this.onChangeCallback(this); + this.update(true); } + + return this.parent; }, /** - * The z component of this Quaternion. + * Set the font style. * - * @name Phaser.Math.Quaternion#z - * @type {number} - * @default 0 + * @method Phaser.GameObjects.TextStyle#setFontStyle * @since 3.0.0 + * + * @param {string} style - The font style. + * + * @return {Phaser.GameObjects.Text} The parent Text object. */ - z: { - get: function () - { - return this._z; - }, - - set: function (value) + setFontStyle: function (style) + { + if (this.fontStyle !== style) { - this._z = value; + this.fontStyle = style; - this.onChangeCallback(this); + this.update(true); } + + return this.parent; }, /** - * The w component of this Quaternion. + * Set the font size. Can be a string with a valid CSS unit, i.e. `16px`, or a number. * - * @name Phaser.Math.Quaternion#w - * @type {number} - * @default 0 + * @method Phaser.GameObjects.TextStyle#setFontSize * @since 3.0.0 + * + * @param {(number|string)} size - The font size. + * + * @return {Phaser.GameObjects.Text} The parent Text object. */ - w: { - get: function () + setFontSize: function (size) + { + if (typeof size === 'number') { - return this._w; - }, + size = size.toString() + 'px'; + } - set: function (value) + if (this.fontSize !== size) { - this._w = value; + this.fontSize = size; - this.onChangeCallback(this); + this.update(true); } + + return this.parent; }, /** - * Copy the components of a given Quaternion or Vector into this Quaternion. + * Set the test string to use when measuring the font. * - * @method Phaser.Math.Quaternion#copy + * @method Phaser.GameObjects.TextStyle#setTestString * @since 3.0.0 * - * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} src - The Quaternion or Vector to copy the components from. + * @param {string} string - The test string to use when measuring the font. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - copy: function (src) + setTestString: function (string) { - return this.set(src); + this.testString = string; + + return this.update(true); }, /** - * Set the components of this Quaternion and optionally call the `onChangeCallback`. + * Set a fixed width and height for the text. * - * @method Phaser.Math.Quaternion#set + * 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|object)} [x=0] - The x component, or an object containing x, y, z, and w components. - * @param {number} [y=0] - The y component. - * @param {number} [z=0] - The z component. - * @param {number} [w=0] - The w component. - * @param {boolean} [update=true] - Call the `onChangeCallback`? + * @param {number} width - The fixed width to set. + * @param {number} height - The fixed height to set. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - set: function (x, y, z, w, update) + setFixedSize: function (width, height) { - if (update === undefined) { update = true; } + this.fixedWidth = width; + this.fixedHeight = height; - if (typeof x === 'object') - { - this._x = x.x || 0; - this._y = x.y || 0; - this._z = x.z || 0; - this._w = x.w || 0; - } - else + if (width) { - this._x = x || 0; - this._y = y || 0; - this._z = z || 0; - this._w = w || 0; + this.parent.width = width; } - if (update) + if (height) { - this.onChangeCallback(this); + this.parent.height = height; } - return this; + return this.update(false); }, /** - * Add a given Quaternion or Vector to this Quaternion. Addition is component-wise. + * Set the background color. * - * @method Phaser.Math.Quaternion#add + * @method Phaser.GameObjects.TextStyle#setBackgroundColor * @since 3.0.0 * - * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to add to this Quaternion. + * @param {string} color - The background color. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - add: function (v) + setBackgroundColor: function (color) { - this._x += v.x; - this._y += v.y; - this._z += v.z; - this._w += v.w; - - this.onChangeCallback(this); + this.backgroundColor = color; - return this; + return this.update(false); }, /** - * Subtract a given Quaternion or Vector from this Quaternion. Subtraction is component-wise. + * Set the text fill color. * - * @method Phaser.Math.Quaternion#subtract + * @method Phaser.GameObjects.TextStyle#setFill * @since 3.0.0 * - * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to subtract from this Quaternion. + * @param {string} color - The text fill color. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - subtract: function (v) + setFill: function (color) { - this._x -= v.x; - this._y -= v.y; - this._z -= v.z; - this._w -= v.w; - - this.onChangeCallback(this); + this.color = color; - return this; + return this.update(false); }, /** - * Scale this Quaternion by the given value. + * Set the text fill color. * - * @method Phaser.Math.Quaternion#scale + * @method Phaser.GameObjects.TextStyle#setColor * @since 3.0.0 * - * @param {number} scale - The value to scale this Quaternion by. + * @param {string} color - The text fill color. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - scale: function (scale) + setColor: function (color) { - this._x *= scale; - this._y *= scale; - this._z *= scale; - this._w *= scale; - - this.onChangeCallback(this); + this.color = color; - return this; + return this.update(false); }, /** - * Calculate the length of this Quaternion. + * Set the resolution used by the Text object. * - * @method Phaser.Math.Quaternion#length - * @since 3.0.0 + * 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. * - * @return {number} The length of this Quaternion. - */ - length: function () - { - var x = this.x; - var y = this.y; - var z = this.z; - var w = this.w; - - return Math.sqrt(x * x + y * y + z * z + w * w); - }, - - /** - * Calculate the length of this Quaternion squared. + * Please use with caution, as the more high res Text you have, the more memory it uses up. * - * @method Phaser.Math.Quaternion#lengthSq - * @since 3.0.0 + * @method Phaser.GameObjects.TextStyle#setResolution + * @since 3.12.0 * - * @return {number} The length of this Quaternion, squared. + * @param {number} value - The resolution for this Text object to use. + * + * @return {Phaser.GameObjects.Text} The parent Text object. */ - lengthSq: function () + setResolution: function (value) { - var x = this.x; - var y = this.y; - var z = this.z; - var w = this.w; + this.resolution = value; - return x * x + y * y + z * z + w * w; + return this.update(false); }, /** - * Normalize this Quaternion. + * Set the stroke settings. * - * @method Phaser.Math.Quaternion#normalize + * @method Phaser.GameObjects.TextStyle#setStroke * @since 3.0.0 * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @param {string} color - The stroke color. + * @param {number} thickness - The stroke thickness. + * + * @return {Phaser.GameObjects.Text} The parent Text object. */ - normalize: function () + setStroke: function (color, thickness) { - var x = this.x; - var y = this.y; - var z = this.z; - var w = this.w; - var len = x * x + y * y + z * z + w * w; + if (thickness === undefined) { thickness = this.strokeThickness; } - if (len > 0) + if (color === undefined && this.strokeThickness !== 0) { - len = 1 / Math.sqrt(len); + // Reset the stroke to zero (disabling it) + this.strokeThickness = 0; - this._x = x * len; - this._y = y * len; - this._z = z * len; - this._w = w * len; + this.update(true); } + else if (this.stroke !== color || this.strokeThickness !== thickness) + { + this.stroke = color; + this.strokeThickness = thickness; - this.onChangeCallback(this); + this.update(true); + } - return this; + return this.parent; }, /** - * Calculate the dot product of this Quaternion and the given Quaternion or Vector. - * - * @method Phaser.Math.Quaternion#dot - * @since 3.0.0 - * - * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to dot product with this Quaternion. + * Set the shadow settings. * - * @return {number} The dot product of this Quaternion and the given Quaternion or Vector. - */ - dot: function (v) - { - return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; - }, - - /** - * Linearly interpolate this Quaternion towards the given Quaternion or Vector. + * Calling this method always re-measures the parent Text object, + * so only call it when you actually change the shadow settings. * - * @method Phaser.Math.Quaternion#lerp + * @method Phaser.GameObjects.TextStyle#setShadow * @since 3.0.0 * - * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to interpolate towards. - * @param {number} [t=0] - The percentage of interpolation. + * @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.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - lerp: function (v, t) + setShadow: function (x, y, color, blur, shadowStroke, shadowFill) { - if (t === undefined) { t = 0; } + 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; } - var ax = this.x; - var ay = this.y; - var az = this.z; - var aw = this.w; + this.shadowOffsetX = x; + this.shadowOffsetY = y; + this.shadowColor = color; + this.shadowBlur = blur; + this.shadowStroke = shadowStroke; + this.shadowFill = shadowFill; - return this.set( - ax + t * (v.x - ax), - ay + t * (v.y - ay), - az + t * (v.z - az), - aw + t * (v.w - aw) - ); + return this.update(false); }, /** - * Rotates this Quaternion based on the two given vectors. + * Set the shadow offset. * - * @method Phaser.Math.Quaternion#rotationTo + * @method Phaser.GameObjects.TextStyle#setShadowOffset * @since 3.0.0 * - * @param {Phaser.Math.Vector3} a - The transform rotation vector. - * @param {Phaser.Math.Vector3} b - The target rotation vector. + * @param {number} [x=0] - The horizontal shadow offset. + * @param {number} [y=0] - The vertical shadow offset. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - rotationTo: function (a, b) + setShadowOffset: function (x, y) { - var dot = a.x * b.x + a.y * b.y + a.z * b.z; - - if (dot < -0.999999) - { - if (tmpvec.copy(xUnitVec3).cross(a).length() < EPSILON) - { - tmpvec.copy(yUnitVec3).cross(a); - } - - tmpvec.normalize(); - - return this.setAxisAngle(tmpvec, Math.PI); - - } - else if (dot > 0.999999) - { - return this.set(0, 0, 0, 1); - } - else - { - tmpvec.copy(a).cross(b); + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } - this._x = tmpvec.x; - this._y = tmpvec.y; - this._z = tmpvec.z; - this._w = 1 + dot; + this.shadowOffsetX = x; + this.shadowOffsetY = y; - return this.normalize(); - } + return this.update(false); }, /** - * Set the axes of this Quaternion. + * Set the shadow color. * - * @method Phaser.Math.Quaternion#setAxes + * @method Phaser.GameObjects.TextStyle#setShadowColor * @since 3.0.0 * - * @param {Phaser.Math.Vector3} view - The view axis. - * @param {Phaser.Math.Vector3} right - The right axis. - * @param {Phaser.Math.Vector3} up - The upwards axis. + * @param {string} [color='#000'] - The shadow color. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - setAxes: function (view, right, up) + setShadowColor: function (color) { - var m = tmpMat3.val; - - m[0] = right.x; - m[3] = right.y; - m[6] = right.z; - - m[1] = up.x; - m[4] = up.y; - m[7] = up.z; - - m[2] = -view.x; - m[5] = -view.y; - m[8] = -view.z; + if (color === undefined) { color = '#000'; } - return this.fromMat3(tmpMat3).normalize(); - }, + this.shadowColor = color; - /** - * Reset this Matrix to an identity (default) Quaternion. - * - * @method Phaser.Math.Quaternion#identity - * @since 3.0.0 - * - * @return {Phaser.Math.Quaternion} This Quaternion. - */ - identity: function () - { - return this.set(0, 0, 0, 1); + return this.update(false); }, /** - * Set the axis angle of this Quaternion. + * Set the shadow blur radius. * - * @method Phaser.Math.Quaternion#setAxisAngle + * @method Phaser.GameObjects.TextStyle#setShadowBlur * @since 3.0.0 * - * @param {Phaser.Math.Vector3} axis - The axis. - * @param {number} rad - The angle in radians. + * @param {number} [blur=0] - The shadow blur radius. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - setAxisAngle: function (axis, rad) + setShadowBlur: function (blur) { - rad = rad * 0.5; + if (blur === undefined) { blur = 0; } - var s = Math.sin(rad); + this.shadowBlur = blur; - return this.set( - s * axis.x, - s * axis.y, - s * axis.z, - Math.cos(rad) - ); + return this.update(false); }, /** - * Multiply this Quaternion by the given Quaternion or Vector. + * Enable or disable shadow stroke. * - * @method Phaser.Math.Quaternion#multiply + * @method Phaser.GameObjects.TextStyle#setShadowStroke * @since 3.0.0 * - * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to multiply this Quaternion by. + * @param {boolean} enabled - Whether shadow stroke is enabled or not. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - multiply: function (b) + setShadowStroke: function (enabled) { - var ax = this.x; - var ay = this.y; - var az = this.z; - var aw = this.w; - - var bx = b.x; - var by = b.y; - var bz = b.z; - var bw = b.w; + this.shadowStroke = enabled; - return this.set( - ax * bw + aw * bx + ay * bz - az * by, - ay * bw + aw * by + az * bx - ax * bz, - az * bw + aw * bz + ax * by - ay * bx, - aw * bw - ax * bx - ay * by - az * bz - ); + return this.update(false); }, /** - * Smoothly linearly interpolate this Quaternion towards the given Quaternion or Vector. + * Enable or disable shadow fill. * - * @method Phaser.Math.Quaternion#slerp + * @method Phaser.GameObjects.TextStyle#setShadowFill * @since 3.0.0 * - * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to interpolate towards. - * @param {number} t - The percentage of interpolation. + * @param {boolean} enabled - Whether shadow fill is enabled or not. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - slerp: function (b, t) + setShadowFill: function (enabled) { - // benchmarks: http://jsperf.com/quaternion-slerp-implementations - - var ax = this.x; - var ay = this.y; - var az = this.z; - var aw = this.w; - - var bx = b.x; - var by = b.y; - var bz = b.z; - var bw = b.w; - - // calc cosine - var cosom = ax * bx + ay * by + az * bz + aw * bw; - - // adjust signs (if necessary) - if (cosom < 0) - { - cosom = -cosom; - bx = - bx; - by = - by; - bz = - bz; - bw = - bw; - } - - // "from" and "to" quaternions are very close - // ... so we can do a linear interpolation - var scale0 = 1 - t; - var scale1 = t; - - // calculate coefficients - if ((1 - cosom) > EPSILON) - { - // standard case (slerp) - var omega = Math.acos(cosom); - var sinom = Math.sin(omega); - - scale0 = Math.sin((1.0 - t) * omega) / sinom; - scale1 = Math.sin(t * omega) / sinom; - } + this.shadowFill = enabled; - // calculate final values - return this.set( - scale0 * ax + scale1 * bx, - scale0 * ay + scale1 * by, - scale0 * az + scale1 * bz, - scale0 * aw + scale1 * bw - ); + return this.update(false); }, /** - * Invert this Quaternion. + * Set the width (in pixels) to use for wrapping lines. * - * @method Phaser.Math.Quaternion#invert + * Pass in null to remove wrapping by width. + * + * @method Phaser.GameObjects.TextStyle#setWordWrapWidth * @since 3.0.0 * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @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. */ - invert: function () + setWordWrapWidth: function (width, useAdvancedWrap) { - var a0 = this.x; - var a1 = this.y; - var a2 = this.z; - var a3 = this.w; + if (useAdvancedWrap === undefined) { useAdvancedWrap = false; } - var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3; - var invDot = (dot) ? 1 / dot : 0; + this.wordWrapWidth = width; + this.wordWrapUseAdvanced = useAdvancedWrap; - return this.set( - -a0 * invDot, - -a1 * invDot, - -a2 * invDot, - a3 * invDot - ); + return this.update(false); }, /** - * Convert this Quaternion into its conjugate. + * Set a custom callback for wrapping lines. * - * Sets the x, y and z components. + * Pass in null to remove wrapping by callback. * - * @method Phaser.Math.Quaternion#conjugate + * @method Phaser.GameObjects.TextStyle#setWordWrapCallback * @since 3.0.0 * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @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. */ - conjugate: function () + setWordWrapCallback: function (callback, scope) { - this._x = -this.x; - this._y = -this.y; - this._z = -this.z; + if (scope === undefined) { scope = null; } - this.onChangeCallback(this); + this.wordWrapCallback = callback; + this.wordWrapCallbackScope = scope; - return this; + return this.update(false); }, /** - * Rotate this Quaternion on the X axis. - * - * @method Phaser.Math.Quaternion#rotateX - * @since 3.0.0 + * Set the alignment of the text in this Text object. * - * @param {number} rad - The rotation angle in radians. + * The argument can be one of: `left`, `right`, `center` or `justify`. * - * @return {Phaser.Math.Quaternion} This Quaternion. - */ - rotateX: function (rad) - { - rad *= 0.5; - - var ax = this.x; - var ay = this.y; - var az = this.z; - var aw = this.w; - - var bx = Math.sin(rad); - var bw = Math.cos(rad); - - return this.set( - ax * bw + aw * bx, - ay * bw + az * bx, - az * bw - ay * bx, - aw * bw - ax * bx - ); - }, - - /** - * Rotate this Quaternion on the Y axis. + * Alignment only works if the Text object has more than one line of text. * - * @method Phaser.Math.Quaternion#rotateY + * @method Phaser.GameObjects.TextStyle#setAlign * @since 3.0.0 * - * @param {number} rad - The rotation angle in radians. + * @param {string} [align='left'] - The text alignment for multi-line text. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - rotateY: function (rad) + setAlign: function (align) { - rad *= 0.5; - - var ax = this.x; - var ay = this.y; - var az = this.z; - var aw = this.w; + if (align === undefined) { align = 'left'; } - var by = Math.sin(rad); - var bw = Math.cos(rad); + this.align = align; - return this.set( - ax * bw - az * by, - ay * bw + aw * by, - az * bw + ax * by, - aw * bw - ay * by - ); + return this.update(false); }, /** - * Rotate this Quaternion on the Z axis. + * Set the maximum number of lines to draw. * - * @method Phaser.Math.Quaternion#rotateZ + * @method Phaser.GameObjects.TextStyle#setMaxLines * @since 3.0.0 * - * @param {number} rad - The rotation angle in radians. + * @param {number} [max=0] - The maximum number of lines to draw. * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.GameObjects.Text} The parent Text object. */ - rotateZ: function (rad) + setMaxLines: function (max) { - rad *= 0.5; - - var ax = this.x; - var ay = this.y; - var az = this.z; - var aw = this.w; + if (max === undefined) { max = 0; } - var bz = Math.sin(rad); - var bw = Math.cos(rad); + this.maxLines = max; - return this.set( - ax * bw + ay * bz, - ay * bw - ax * bz, - az * bw + aw * bz, - aw * bw - az * bz - ); + return this.update(false); }, /** - * Create a unit (or rotation) Quaternion from its x, y, and z components. - * - * Sets the w component. + * Get the current text metrics. * - * @method Phaser.Math.Quaternion#calculateW + * @method Phaser.GameObjects.TextStyle#getTextMetrics * @since 3.0.0 * - * @return {Phaser.Math.Quaternion} This Quaternion. - */ - calculateW: function () - { - var x = this.x; - var y = this.y; - var z = this.z; - - this.w = -Math.sqrt(1.0 - x * x - y * y - z * z); - - return this; - }, - - /** - * Set this Quaternion from the given Euler, based on Euler order. - * - * @method Phaser.Math.Quaternion#setFromEuler - * @since 3.50.0 - * - * @param {Phaser.Math.Euler} euler - The Euler to convert from. - * @param {boolean} [update=true] - Run the `onChangeCallback`? - * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics. */ - setFromEuler: function (euler, update) + getTextMetrics: function () { - var x = euler.x / 2; - var y = euler.y / 2; - var z = euler.z / 2; - - var c1 = Math.cos(x); - var c2 = Math.cos(y); - var c3 = Math.cos(z); - - var s1 = Math.sin(x); - var s2 = Math.sin(y); - var s3 = Math.sin(z); - - switch (euler.order) - { - case 'XYZ': - { - this.set( - s1 * c2 * c3 + c1 * s2 * s3, - c1 * s2 * c3 - s1 * c2 * s3, - c1 * c2 * s3 + s1 * s2 * c3, - c1 * c2 * c3 - s1 * s2 * s3, - update - ); - - break; - } - - case 'YXZ': - { - this.set( - s1 * c2 * c3 + c1 * s2 * s3, - c1 * s2 * c3 - s1 * c2 * s3, - c1 * c2 * s3 - s1 * s2 * c3, - c1 * c2 * c3 + s1 * s2 * s3, - update - ); - - break; - } - - case 'ZXY': - { - this.set( - s1 * c2 * c3 - c1 * s2 * s3, - c1 * s2 * c3 + s1 * c2 * s3, - c1 * c2 * s3 + s1 * s2 * c3, - c1 * c2 * c3 - s1 * s2 * s3, - update - ); - - break; - } - - case 'ZYX': - { - this.set( - s1 * c2 * c3 - c1 * s2 * s3, - c1 * s2 * c3 + s1 * c2 * s3, - c1 * c2 * s3 - s1 * s2 * c3, - c1 * c2 * c3 + s1 * s2 * s3, - update - ); - - break; - } - - case 'YZX': - { - this.set( - s1 * c2 * c3 + c1 * s2 * s3, - c1 * s2 * c3 + s1 * c2 * s3, - c1 * c2 * s3 - s1 * s2 * c3, - c1 * c2 * c3 - s1 * s2 * s3, - update - ); - - break; - } - - case 'XZY': - { - this.set( - s1 * c2 * c3 - c1 * s2 * s3, - c1 * s2 * c3 - s1 * c2 * s3, - c1 * c2 * s3 + s1 * s2 * c3, - c1 * c2 * c3 + s1 * s2 * s3, - update - ); - - break; - } - } + var metrics = this.metrics; - return this; + return { + ascent: metrics.ascent, + descent: metrics.descent, + fontSize: metrics.fontSize + }; }, /** - * Sets the rotation of this Quaternion from the given Matrix4. - * - * @method Phaser.Math.Quaternion#setFromRotationMatrix - * @since 3.50.0 + * Build a JSON representation of this Text Style. * - * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to set the rotation from. + * @method Phaser.GameObjects.TextStyle#toJSON + * @since 3.0.0 * - * @return {Phaser.Math.Quaternion} This Quaternion. + * @return {object} A JSON representation of this Text Style. */ - setFromRotationMatrix: function (mat4) + toJSON: function () { - var m = mat4.val; - - var m11 = m[0]; - var m12 = m[4]; - var m13 = m[8]; - var m21 = m[1]; - var m22 = m[5]; - var m23 = m[9]; - var m31 = m[2]; - var m32 = m[6]; - var m33 = m[10]; - - var trace = m11 + m22 + m33; - var s; - - if (trace > 0) - { - s = 0.5 / Math.sqrt(trace + 1.0); - - this.set( - (m32 - m23) * s, - (m13 - m31) * s, - (m21 - m12) * s, - 0.25 / s - ); - } - else if (m11 > m22 && m11 > m33) - { - s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33); + var output = {}; - this.set( - 0.25 * s, - (m12 + m21) / s, - (m13 + m31) / s, - (m32 - m23) / s - ); - } - else if (m22 > m33) + for (var key in propertyMap) { - s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33); - - this.set( - (m12 + m21) / s, - 0.25 * s, - (m23 + m32) / s, - (m13 - m31) / s - ); + output[key] = this[key]; } - else - { - s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22); - this.set( - (m13 + m31) / s, - (m23 + m32) / s, - 0.25 * s, - (m21 - m12) / s - ); - } + output.metrics = this.getTextMetrics(); - return this; + return output; }, /** - * Convert the given Matrix into this Quaternion. + * Destroy this Text Style. * - * @method Phaser.Math.Quaternion#fromMat3 + * @method Phaser.GameObjects.TextStyle#destroy * @since 3.0.0 - * - * @param {Phaser.Math.Matrix3} mat - The Matrix to convert from. - * - * @return {Phaser.Math.Quaternion} This Quaternion. */ - fromMat3: function (mat) + destroy: function () { - // benchmarks: - // http://jsperf.com/typed-array-access-speed - // http://jsperf.com/conversion-of-3x3-matrix-to-quaternion - - // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes - // article "Quaternion Calculus and Fast Animation". - var m = mat.val; - var fTrace = m[0] + m[4] + m[8]; - var fRoot; - - if (fTrace > 0) - { - // |w| > 1/2, may as well choose w > 1/2 - fRoot = Math.sqrt(fTrace + 1.0); // 2w - - this.w = 0.5 * fRoot; - - fRoot = 0.5 / fRoot; // 1/(4w) - - this._x = (m[7] - m[5]) * fRoot; - this._y = (m[2] - m[6]) * fRoot; - this._z = (m[3] - m[1]) * fRoot; - } - else - { - // |w| <= 1/2 - var i = 0; - - if (m[4] > m[0]) - { - i = 1; - } - - if (m[8] > m[i * 3 + i]) - { - i = 2; - } - - var j = siNext[i]; - var k = siNext[j]; - - // This isn't quite as clean without array access - fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1); - tmp[i] = 0.5 * fRoot; - - fRoot = 0.5 / fRoot; - - tmp[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; - tmp[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; - - this._x = tmp[0]; - this._y = tmp[1]; - this._z = tmp[2]; - this._w = (m[k * 3 + j] - m[j * 3 + k]) * fRoot; - } - - this.onChangeCallback(this); - - return this; + this.parent = undefined; } }); -module.exports = Quaternion; +module.exports = TextStyle; /***/ }), -/* 366 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 76128: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CanvasInterpolation = __webpack_require__(367); -var CanvasPool = __webpack_require__(31); -var CONST = __webpack_require__(33); -var Features = __webpack_require__(191); +var Utils = __webpack_require__(75512); /** - * Called automatically by Phaser.Game and responsible for creating the renderer it will use. - * - * Relies upon two webpack global flags to be defined: `WEBGL_RENDERER` and `CANVAS_RENDERER` during build time, but not at run-time. + * 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. * - * @function Phaser.Core.CreateRenderer + * @method Phaser.GameObjects.Text#renderWebGL * @since 3.0.0 + * @private * - * @param {Phaser.Game} game - The Phaser.Game instance on which the renderer will be set. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Text} 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 CreateRenderer = function (game) +var TextWebGLRenderer = function (renderer, src, camera, parentMatrix) { - var config = game.config; - - if ((config.customEnvironment || config.canvas) && config.renderType === CONST.AUTO) - { - throw new Error('Must set explicit renderType in custom environment'); - } - - // Not a custom environment, didn't provide their own canvas and not headless, so determine the renderer: - if (!config.customEnvironment && !config.canvas && config.renderType !== CONST.HEADLESS) - { - if (config.renderType === CONST.CANVAS || (config.renderType !== CONST.CANVAS && !Features.webGL)) - { - if (Features.canvas) - { - // They requested Canvas and their browser supports it - config.renderType = CONST.CANVAS; - } - else - { - throw new Error('Cannot create Canvas or WebGL context, aborting.'); - } - } - else - { - // Game requested WebGL and browser says it supports it - config.renderType = CONST.WEBGL; - } - } - - // Pixel Art mode? - if (!config.antialias) - { - CanvasPool.disableSmoothing(); - } - - var baseSize = game.scale.baseSize; - - var width = baseSize.width; - var height = baseSize.height; - - // Does the game config provide its own canvas element to use? - if (config.canvas) - { - game.canvas = config.canvas; - - game.canvas.width = width; - game.canvas.height = height; - } - else - { - game.canvas = CanvasPool.create(game, width, height, config.renderType); - } - - // Does the game config provide some canvas css styles to use? - if (config.canvasStyle) - { - game.canvas.style = config.canvasStyle; - } - - // Pixel Art mode? - if (!config.antialias) - { - CanvasInterpolation.setCrisp(game.canvas); - } - - if (config.renderType === CONST.HEADLESS) + if (src.width === 0 || src.height === 0) { - // Nothing more to do here return; } - var CanvasRenderer; - var WebGLRenderer; - - if (true) - { - CanvasRenderer = __webpack_require__(368); - WebGLRenderer = __webpack_require__(371); + camera.addToRenderList(src); - // Let the config pick the renderer type, as both are included - if (config.renderType === CONST.WEBGL) - { - game.renderer = new WebGLRenderer(game); - } - else - { - game.renderer = new CanvasRenderer(game); - game.context = game.renderer.gameContext; - } - } + var frame = src.frame; + var width = frame.width; + var height = frame.height; + var getTint = Utils.getTintAppendFloatAlpha; + var pipeline = renderer.pipelines.set(src.pipeline, src); - if (false) - {} + var textureUnit = pipeline.setTexture2D(frame.glTexture, src); - if (false) - {} + pipeline.batchTexture( + src, + frame.glTexture, + width, height, + src.x, src.y, + width / src.style.resolution, height / src.style.resolution, + src.scaleX, src.scaleY, + src.rotation, + src.flipX, src.flipY, + src.scrollFactorX, src.scrollFactorY, + src.displayOriginX, src.displayOriginY, + 0, 0, width, height, + getTint(src.tintTopLeft, camera.alpha * src._alphaTL), + getTint(src.tintTopRight, camera.alpha * src._alphaTR), + getTint(src.tintBottomLeft, camera.alpha * src._alphaBL), + getTint(src.tintBottomRight, camera.alpha * src._alphaBR), + src.tintFill, + 0, 0, + camera, + parentMatrix, + false, + textureUnit + ); }; -module.exports = CreateRenderer; +module.exports = TextWebGLRenderer; /***/ }), -/* 367 */ -/***/ (function(module, exports) { + +/***/ 35856: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CanvasPool = __webpack_require__(61068); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var GetPowerOfTwo = __webpack_require__(3504); +var Smoothing = __webpack_require__(8213); +var TileSpriteRender = __webpack_require__(9271); +var Vector2 = __webpack_require__(93736); + +// bitmask flag for GameObject.renderMask +var _FLAG = 8; // 1000 + /** - * @namespace Phaser.Display.Canvas.CanvasInterpolation + * @classdesc + * A TileSprite is a Sprite that has a repeating texture. + * + * The texture can be scrolled and scaled independently of the TileSprite itself. Textures will automatically wrap and + * are designed so that you can create game backdrops using seamless textures as a source. + * + * You shouldn't ever create a TileSprite any larger than your actual canvas size. If you want to create a large repeating background + * that scrolls across the whole map of your game, then you create a TileSprite that fits the canvas size and then use the `tilePosition` + * property to scroll the texture as the player moves. If you create a TileSprite that is thousands of pixels in size then it will + * consume huge amounts of memory and cause performance issues. Remember: use `tilePosition` to scroll your texture and `tileScale` to + * adjust the scale of the texture - don't resize the sprite itself or make it larger than it needs. + * + * An important note about Tile Sprites and NPOT textures: Internally, TileSprite textures use GL_REPEAT to provide + * seamless repeating of the textures. This, combined with the way in which the textures are handled in WebGL, means + * they need to be POT (power-of-two) sizes in order to wrap. If you provide a NPOT (non power-of-two) texture to a + * TileSprite it will generate a POT sized canvas and draw your texture to it, scaled up to the POT size. It's then + * scaled back down again during rendering to the original dimensions. While this works, in that it allows you to use + * any size texture for a Tile Sprite, it does mean that NPOT textures are going to appear anti-aliased when rendered, + * due to the interpolation that took place when it was resized into a POT texture. This is especially visible in + * pixel art graphics. If you notice it and it becomes an issue, the only way to avoid it is to ensure that you + * provide POT textures for Tile Sprites. + * + * @class TileSprite + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor * @since 3.0.0 + * + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.BlendMode + * @extends Phaser.GameObjects.Components.ComputedSize + * @extends Phaser.GameObjects.Components.Crop + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @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 {number} width - The width of the Game Object. If zero it will use the size of the texture frame. + * @param {number} height - The height of the Game Object. If zero it will use the size of the texture frame. + * @param {string} textureKey - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager. Cannot be a DynamicTexture. + * @param {(string|number)} [frameKey] - An optional frame from the Texture this Game Object is rendering with. */ -var CanvasInterpolation = { - - /** - * Sets the CSS image-rendering property on the given canvas to be 'crisp' (aka 'optimize contrast' on webkit). - * - * @function Phaser.Display.Canvas.CanvasInterpolation.setCrisp - * @since 3.0.0 - * - * @param {HTMLCanvasElement} canvas - The canvas object to have the style set on. - * - * @return {HTMLCanvasElement} The canvas. - */ - setCrisp: function (canvas) - { - var types = [ 'optimizeSpeed', '-moz-crisp-edges', '-o-crisp-edges', '-webkit-optimize-contrast', 'optimize-contrast', 'crisp-edges', 'pixelated' ]; +var TileSprite = new Class({ - types.forEach(function (type) - { - canvas.style['image-rendering'] = type; - }); + Extends: GameObject, - canvas.style.msInterpolationMode = 'nearest-neighbor'; + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.ComputedSize, + Components.Crop, + Components.Depth, + Components.Flip, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Tint, + Components.Transform, + Components.Visible, + TileSpriteRender + ], - return canvas; - }, + initialize: - /** - * Sets the CSS image-rendering property on the given canvas to be 'bicubic' (aka 'auto'). - * - * @function Phaser.Display.Canvas.CanvasInterpolation.setBicubic - * @since 3.0.0 - * - * @param {HTMLCanvasElement} canvas - The canvas object to have the style set on. - * - * @return {HTMLCanvasElement} The canvas. - */ - setBicubic: function (canvas) + function TileSprite (scene, x, y, width, height, textureKey, frameKey) { - canvas.style['image-rendering'] = 'auto'; - canvas.style.msInterpolationMode = 'bicubic'; - - return canvas; - } + var renderer = scene.sys.renderer; -}; + GameObject.call(this, scene, 'TileSprite'); -module.exports = CanvasInterpolation; + var displayTexture = scene.sys.textures.get(textureKey); + var displayFrame = displayTexture.get(frameKey); + if (displayFrame.source.compressionAlgorithm) + { + console.warn('TileSprite cannot use compressed texture'); + displayTexture = scene.sys.textures.get('__MISSING'); + displayFrame = displayTexture.get(); + } -/***/ }), -/* 368 */ -/***/ (function(module, exports, __webpack_require__) { + if (displayTexture.type === 'DynamicTexture') + { + console.warn('TileSprite cannot use Dynamic Texture'); + displayTexture = scene.sys.textures.get('__MISSING'); + displayFrame = displayTexture.get(); + } -/** - * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CameraEvents = __webpack_require__(37); -var CanvasSnapshot = __webpack_require__(369); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(33); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(91); -var GetBlendModes = __webpack_require__(370); -var ScaleEvents = __webpack_require__(104); -var TextureEvents = __webpack_require__(106); -var TransformMatrix = __webpack_require__(25); - -/** - * @classdesc - * The Canvas Renderer is responsible for managing 2D canvas rendering contexts, - * including the one used by the Games canvas. It tracks the internal state of a - * given context and can renderer textured Game Objects to it, taking into - * account alpha, blending, and scaling. - * - * @class CanvasRenderer - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Renderer.Canvas - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Game} game - The Phaser Game instance that owns this renderer. - */ -var CanvasRenderer = new Class({ - - Extends: EventEmitter, - - initialize: - - function CanvasRenderer (game) - { - EventEmitter.call(this); - - var gameConfig = game.config; + if (!width || !height) + { + width = displayFrame.width; + height = displayFrame.height; + } + else + { + width = Math.floor(width); + height = Math.floor(height); + } /** - * The local configuration settings of the CanvasRenderer. + * Internal tile position vector. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#config - * @type {object} - * @since 3.0.0 + * @name Phaser.GameObjects.TileSprite#_tilePosition + * @type {Phaser.Math.Vector2} + * @private + * @since 3.12.0 */ - this.config = { - clearBeforeRender: gameConfig.clearBeforeRender, - backgroundColor: gameConfig.backgroundColor, - antialias: gameConfig.antialias, - roundPixels: gameConfig.roundPixels - }; + this._tilePosition = new Vector2(); /** - * The Phaser Game instance that owns this renderer. + * Internal tile scale vector. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#game - * @type {Phaser.Game} - * @since 3.0.0 + * @name Phaser.GameObjects.TileSprite#_tileScale + * @type {Phaser.Math.Vector2} + * @private + * @since 3.12.0 */ - this.game = game; + this._tileScale = new Vector2(1, 1); /** - * A constant which allows the renderer to be easily identified as a Canvas Renderer. + * Whether the Tile Sprite has changed in some way, requiring an re-render of its tile texture. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#type - * @type {number} + * Such changes include the texture frame and scroll position of the Tile Sprite. + * + * @name Phaser.GameObjects.TileSprite#dirty + * @type {boolean} + * @default false * @since 3.0.0 */ - this.type = CONST.CANVAS; + this.dirty = false; /** - * The total number of Game Objects which were rendered in a frame. + * The renderer in use by this Tile Sprite. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#drawCount - * @type {number} - * @default 0 + * @name Phaser.GameObjects.TileSprite#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} * @since 3.0.0 */ - this.drawCount = 0; + this.renderer = renderer; /** - * The width of the canvas being rendered to. + * The Canvas element that the TileSprite renders its fill pattern in to. + * Only used in Canvas mode. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#width - * @type {number} - * @since 3.0.0 + * @name Phaser.GameObjects.TileSprite#canvas + * @type {?HTMLCanvasElement} + * @since 3.12.0 */ - this.width = 0; + this.canvas = CanvasPool.create(this, width, height); /** - * The height of the canvas being rendered to. + * The Context of the Canvas element that the TileSprite renders its fill pattern in to. + * Only used in Canvas mode. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#height - * @type {number} - * @since 3.0.0 + * @name Phaser.GameObjects.TileSprite#context + * @type {CanvasRenderingContext2D} + * @since 3.12.0 */ - this.height = 0; + this.context = this.canvas.getContext('2d', { willReadFrequently: false }); /** - * The canvas element which the Game uses. + * The Texture the TileSprite is using as its fill pattern. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#gameCanvas - * @type {HTMLCanvasElement} - * @since 3.0.0 + * @name Phaser.GameObjects.TileSprite#displayTexture + * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} + * @private + * @since 3.12.0 */ - this.gameCanvas = game.canvas; - - var contextOptions = { - alpha: game.config.transparent, - desynchronized: game.config.desynchronized - }; + this.displayTexture = displayTexture; /** - * The canvas context used to render all Cameras in all Scenes during the game loop. + * The Frame the TileSprite is using as its fill pattern. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#gameContext - * @type {CanvasRenderingContext2D} - * @since 3.0.0 + * @name Phaser.GameObjects.TileSprite#displayFrame + * @type {Phaser.Textures.Frame} + * @private + * @since 3.12.0 */ - this.gameContext = (gameConfig.context) ? gameConfig.context : this.gameCanvas.getContext('2d', contextOptions); + this.displayFrame = displayFrame; /** - * The canvas context currently used by the CanvasRenderer for all rendering operations. + * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#currentContext - * @type {CanvasRenderingContext2D} - * @since 3.0.0 + * @name Phaser.GameObjects.TileSprite#_crop + * @type {object} + * @private + * @since 3.12.0 */ - this.currentContext = this.gameContext; + this._crop = this.resetCropObject(); /** - * Should the Canvas use Image Smoothing or not when drawing Sprites? + * The Texture this Game Object is using to render with. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#antialias - * @type {boolean} - * @since 3.20.0 + * @name Phaser.GameObjects.TileSprite#texture + * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} + * @since 3.0.0 */ - this.antialias = game.config.antialias; + this.texture = scene.sys.textures.addCanvas(null, this.canvas, true); /** - * The blend modes supported by the Canvas Renderer. - * - * This object maps the {@link Phaser.BlendModes} to canvas compositing operations. + * The Texture Frame this Game Object is using to render with. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#blendModes - * @type {array} + * @name Phaser.GameObjects.TileSprite#frame + * @type {Phaser.Textures.Frame} * @since 3.0.0 */ - this.blendModes = GetBlendModes(); + this.frame = this.texture.get(); /** - * Details about the currently scheduled snapshot. - * - * If a non-null `callback` is set in this object, a snapshot of the canvas will be taken after the current frame is fully rendered. + * The next power of two value from the width of the Fill Pattern frame. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#snapshotState - * @type {Phaser.Types.Renderer.Snapshot.SnapshotState} - * @since 3.16.0 + * @name Phaser.GameObjects.TileSprite#potWidth + * @type {number} + * @since 3.0.0 */ - this.snapshotState = { - x: 0, - y: 0, - width: 1, - height: 1, - getPixel: false, - callback: null, - type: 'image/png', - encoder: 0.92 - }; + this.potWidth = GetPowerOfTwo(displayFrame.width); /** - * A temporary Transform Matrix, re-used internally during batching. + * The next power of two value from the height of the Fill Pattern frame. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#_tempMatrix1 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.11.0 + * @name Phaser.GameObjects.TileSprite#potHeight + * @type {number} + * @since 3.0.0 */ - this._tempMatrix1 = new TransformMatrix(); + this.potHeight = GetPowerOfTwo(displayFrame.height); /** - * A temporary Transform Matrix, re-used internally during batching. + * The Canvas that the TileSprites texture is rendered to. + * This is used to create a WebGL texture from. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#_tempMatrix2 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.11.0 + * @name Phaser.GameObjects.TileSprite#fillCanvas + * @type {HTMLCanvasElement} + * @since 3.12.0 */ - this._tempMatrix2 = new TransformMatrix(); + this.fillCanvas = CanvasPool.create2D(this, this.potWidth, this.potHeight); /** - * A temporary Transform Matrix, re-used internally during batching. + * The Canvas Context used to render the TileSprites texture. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#_tempMatrix3 - * @private - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.11.0 + * @name Phaser.GameObjects.TileSprite#fillContext + * @type {CanvasRenderingContext2D} + * @since 3.12.0 */ - this._tempMatrix3 = new TransformMatrix(); + this.fillContext = this.fillCanvas.getContext('2d', { willReadFrequently: false }); /** - * Has this renderer fully booted yet? + * The texture that the Tile Sprite is rendered to, which is then rendered to a Scene. + * In WebGL this is a WebGLTexture. In Canvas it's a Canvas Fill Pattern. * - * @name Phaser.Renderer.Canvas.CanvasRenderer#isBooted - * @type {boolean} - * @since 3.50.0 + * @name Phaser.GameObjects.TileSprite#fillPattern + * @type {?(WebGLTexture|CanvasPattern)} + * @since 3.12.0 */ - this.isBooted = false; + this.fillPattern = null; - this.init(); + this.setPosition(x, y); + this.setSize(width, height); + this.setFrame(frameKey); + this.setOriginFromFrame(); + this.initPipeline(); + this.initPostPipeline(true); }, /** - * Prepares the game canvas for rendering. + * Sets the texture and frame this Game Object will use to render with. * - * @method Phaser.Renderer.Canvas.CanvasRenderer#init + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * + * @method Phaser.GameObjects.TileSprite#setTexture * @since 3.0.0 - */ - init: function () - { - this.game.textures.once(TextureEvents.READY, this.boot, this); - }, - - /** - * Internal boot handler. * - * @method Phaser.Renderer.Canvas.CanvasRenderer#boot - * @private - * @since 3.50.0 + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. + * + * @return {this} This Game Object instance. */ - boot: function () + setTexture: function (key, frame) { - var game = this.game; - - var baseSize = game.scale.baseSize; - - this.width = baseSize.width; - this.height = baseSize.height; - - this.isBooted = true; - - game.scale.on(ScaleEvents.RESIZE, this.onResize, this); + this.displayTexture = this.scene.sys.textures.get(key); - this.resize(baseSize.width, baseSize.height); + return this.setFrame(frame); }, /** - * The event handler that manages the `resize` event dispatched by the Scale Manager. + * Sets the frame this Game Object will use to render with. * - * @method Phaser.Renderer.Canvas.CanvasRenderer#onResize - * @since 3.16.0 + * The Frame has to belong to the current Texture being used. * - * @param {Phaser.Structs.Size} gameSize - The default Game Size object. This is the un-modified game dimensions. - * @param {Phaser.Structs.Size} baseSize - The base Size object. The game dimensions multiplied by the resolution. The canvas width / height values match this. - */ - onResize: function (gameSize, baseSize) - { - // Has the underlying canvas size changed? - if (baseSize.width !== this.width || baseSize.height !== this.height) - { - this.resize(baseSize.width, baseSize.height); - } - }, - - /** - * Resize the main game canvas. + * It can be either a string or an index. * - * @method Phaser.Renderer.Canvas.CanvasRenderer#resize - * @fires Phaser.Renderer.Events#RESIZE + * @method Phaser.GameObjects.TileSprite#setFrame * @since 3.0.0 * - * @param {number} [width] - The new width of the renderer. - * @param {number} [height] - The new height of the renderer. + * @param {(string|number)} frame - The name or index of the frame within the Texture. + * + * @return {this} This Game Object instance. */ - resize: function (width, height) + setFrame: function (frame) { - this.width = width; - this.height = height; + var newFrame = this.displayTexture.get(frame); - this.emit(Events.RESIZE, width, height); - }, + this.potWidth = GetPowerOfTwo(newFrame.width); + this.potHeight = GetPowerOfTwo(newFrame.height); - /** - * Resets the transformation matrix of the current context to the identity matrix, thus resetting any transformation. - * - * @method Phaser.Renderer.Canvas.CanvasRenderer#resetTransform - * @since 3.0.0 - */ - resetTransform: function () - { - this.currentContext.setTransform(1, 0, 0, 1, 0, 0); - }, + // So updateCanvas is triggered + this.canvas.width = 0; - /** - * Sets the blend mode (compositing operation) of the current context. - * - * @method Phaser.Renderer.Canvas.CanvasRenderer#setBlendMode - * @since 3.0.0 - * - * @param {string} blendMode - The new blend mode which should be used. - * - * @return {this} This CanvasRenderer object. - */ - setBlendMode: function (blendMode) - { - this.currentContext.globalCompositeOperation = blendMode; + if (!newFrame.cutWidth || !newFrame.cutHeight) + { + this.renderFlags &= ~_FLAG; + } + else + { + this.renderFlags |= _FLAG; + } + + this.displayFrame = newFrame; + + this.dirty = true; + + this.updateTileTexture(); return this; }, /** - * Changes the Canvas Rendering Context that all draw operations are performed against. + * Sets {@link Phaser.GameObjects.TileSprite#tilePositionX} and {@link Phaser.GameObjects.TileSprite#tilePositionY}. * - * @method Phaser.Renderer.Canvas.CanvasRenderer#setContext - * @since 3.12.0 + * @method Phaser.GameObjects.TileSprite#setTilePosition + * @since 3.3.0 * - * @param {?CanvasRenderingContext2D} [ctx] - The new Canvas Rendering Context to draw everything to. Leave empty to reset to the Game Canvas. + * @param {number} [x] - The x position of this sprite's tiling texture. + * @param {number} [y] - The y position of this sprite's tiling texture. * - * @return {this} The Canvas Renderer instance. + * @return {this} This Tile Sprite instance. */ - setContext: function (ctx) + setTilePosition: function (x, y) { - this.currentContext = (ctx) ? ctx : this.gameContext; + if (x !== undefined) + { + this.tilePositionX = x; + } + + if (y !== undefined) + { + this.tilePositionY = y; + } return this; }, /** - * Sets the global alpha of the current context. + * Sets {@link Phaser.GameObjects.TileSprite#tileScaleX} and {@link Phaser.GameObjects.TileSprite#tileScaleY}. * - * @method Phaser.Renderer.Canvas.CanvasRenderer#setAlpha - * @since 3.0.0 + * @method Phaser.GameObjects.TileSprite#setTileScale + * @since 3.12.0 * - * @param {number} alpha - The new alpha to use, where 0 is fully transparent and 1 is fully opaque. + * @param {number} [x] - The horizontal scale of the tiling texture. If not given it will use the current `tileScaleX` value. + * @param {number} [y=x] - The vertical scale of the tiling texture. If not given it will use the `x` value. * - * @return {this} This CanvasRenderer object. + * @return {this} This Tile Sprite instance. */ - setAlpha: function (alpha) + setTileScale: function (x, y) { - this.currentContext.globalAlpha = alpha; + if (x === undefined) { x = this.tileScaleX; } + if (y === undefined) { y = x; } + + this.tileScaleX = x; + this.tileScaleY = y; return this; }, /** - * Called at the start of the render loop. + * Render the tile texture if it is dirty, or if the frame has changed. * - * @method Phaser.Renderer.Canvas.CanvasRenderer#preRender - * @fires Phaser.Renderer.Events#PRE_RENDER + * @method Phaser.GameObjects.TileSprite#updateTileTexture + * @private * @since 3.0.0 */ - preRender: function () + updateTileTexture: function () { - var ctx = this.gameContext; - var config = this.config; + if (!this.dirty || !this.renderer) + { + return; + } - var width = this.width; - var height = this.height; + // Draw the displayTexture to our fillCanvas - ctx.globalAlpha = 1; - ctx.globalCompositeOperation = 'source-over'; - ctx.setTransform(1, 0, 0, 1, 0, 0); + var frame = this.displayFrame; - if (config.clearBeforeRender) + if (frame.source.isRenderTexture || frame.source.isGLTexture) { - ctx.clearRect(0, 0, width, height); + console.warn('TileSprites can only use Image or Canvas based textures'); - if (!config.transparent) - { - ctx.fillStyle = config.backgroundColor.rgba; - ctx.fillRect(0, 0, width, height); - } - } + this.dirty = false; - ctx.save(); + return; + } - this.drawCount = 0; + var ctx = this.fillContext; + var canvas = this.fillCanvas; - this.emit(Events.PRE_RENDER); - }, + var fw = this.potWidth; + var fh = this.potHeight; - /** - * The core render step for a Scene Camera. - * - * Iterates through the given array of Game Objects and renders them with the given Camera. - * - * This is called by the `CameraManager.render` method. The Camera Manager instance belongs to a Scene, and is invoked - * by the Scene Systems.render method. - * - * This method is not called if `Camera.visible` is `false`, or `Camera.alpha` is zero. - * - * @method Phaser.Renderer.Canvas.CanvasRenderer#render - * @fires Phaser.Renderer.Events#RENDER - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to render. - * @param {Phaser.GameObjects.GameObject[]} children - An array of filtered Game Objects that can be rendered by the given Camera. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera to render with. - */ - render: function (scene, children, camera) - { - var childCount = children.length; + if (!this.renderer || !this.renderer.gl) + { + fw = frame.cutWidth; + fh = frame.cutHeight; + } - this.emit(Events.RENDER, scene, camera); + ctx.clearRect(0, 0, fw, fh); - var cx = camera.x; - var cy = camera.y; - var cw = camera.width; - var ch = camera.height; + canvas.width = fw; + canvas.height = fh; - var ctx = (camera.renderToTexture) ? camera.context : scene.sys.context; + ctx.drawImage( + frame.source.image, + frame.cutX, frame.cutY, + frame.cutWidth, frame.cutHeight, + 0, 0, + fw, fh + ); - // Save context pre-clip - ctx.save(); + if (this.renderer && this.renderer.gl) + { + this.fillPattern = this.renderer.canvasToTexture(canvas, this.fillPattern); - if (this.game.scene.customViewports) + if (false) + {} + } + else { - ctx.beginPath(); - ctx.rect(cx, cy, cw, ch); - ctx.clip(); + this.fillPattern = ctx.createPattern(canvas, 'repeat'); } - this.currentContext = ctx; + this.updateCanvas(); - var mask = camera.mask; + this.dirty = false; + }, - if (mask) - { - mask.preRenderCanvas(this, null, camera._maskCamera); - } + /** + * Draw the fill pattern to the internal canvas. + * + * @method Phaser.GameObjects.TileSprite#updateCanvas + * @private + * @since 3.12.0 + */ + updateCanvas: function () + { + var canvas = this.canvas; - if (!camera.transparent) + if (canvas.width !== this.width || canvas.height !== this.height) { - ctx.fillStyle = camera.backgroundColor.rgba; - ctx.fillRect(cx, cy, cw, ch); - } - - ctx.globalAlpha = camera.alpha; + canvas.width = this.width; + canvas.height = this.height; - ctx.globalCompositeOperation = 'source-over'; + this.frame.setSize(this.width, this.height); + this.updateDisplayOrigin(); - this.drawCount += childCount; + this.dirty = true; + } - if (camera.renderToTexture) + if (!this.dirty || this.renderer && this.renderer.gl) { - camera.emit(CameraEvents.PRE_RENDER, camera); + this.dirty = false; + return; } - camera.matrix.copyToContext(ctx); + var ctx = this.context; - for (var i = 0; i < childCount; i++) + if (!this.scene.sys.game.config.antialias) { - var child = children[i]; + Smoothing.disable(ctx); + } - if (child.mask) - { - child.mask.preRenderCanvas(this, child, camera); - } + var scaleX = this._tileScale.x; + var scaleY = this._tileScale.y; - child.renderCanvas(this, child, camera); + var positionX = this._tilePosition.x; + var positionY = this._tilePosition.y; - if (child.mask) - { - child.mask.postRenderCanvas(this, child, camera); - } - } + ctx.clearRect(0, 0, this.width, this.height); - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.globalCompositeOperation = 'source-over'; - ctx.globalAlpha = 1; + ctx.save(); - camera.flashEffect.postRenderCanvas(ctx); - camera.fadeEffect.postRenderCanvas(ctx); + ctx.scale(scaleX, scaleY); - camera.dirty = false; + ctx.translate(-positionX, -positionY); - if (mask) - { - mask.postRenderCanvas(this); - } + ctx.fillStyle = this.fillPattern; - // Restore pre-clip context - ctx.restore(); + ctx.fillRect(positionX, positionY, this.width / scaleX, this.height / scaleY); - if (camera.renderToTexture) - { - camera.emit(CameraEvents.POST_RENDER, camera); + ctx.restore(); - if (camera.renderToGame) - { - scene.sys.context.drawImage(camera.canvas, cx, cy); - } - } + this.dirty = false; }, /** - * Restores the game context's global settings and takes a snapshot if one is scheduled. - * - * The post-render step happens after all Cameras in all Scenes have been rendered. + * Internal destroy handler, called as part of the destroy process. * - * @method Phaser.Renderer.Canvas.CanvasRenderer#postRender - * @fires Phaser.Renderer.Events#POST_RENDER - * @since 3.0.0 + * @method Phaser.GameObjects.TileSprite#preDestroy + * @protected + * @since 3.9.0 */ - postRender: function () + preDestroy: function () { - var ctx = this.gameContext; + if (this.renderer && this.renderer.gl) + { + this.renderer.deleteTexture(this.fillPattern); + } - ctx.restore(); + CanvasPool.remove(this.canvas); + CanvasPool.remove(this.fillCanvas); - this.emit(Events.POST_RENDER); + this.fillPattern = null; + this.fillContext = null; + this.fillCanvas = null; - var state = this.snapshotState; + this.displayTexture = null; + this.displayFrame = null; - if (state.callback) - { - CanvasSnapshot(this.gameCanvas, state); + this.texture.destroy(); - state.callback = null; - } + this.renderer = null; }, /** - * Takes a snapshot of the given area of the given canvas. - * - * Unlike the other snapshot methods, this one is processed immediately and doesn't wait for the next render. - * - * Snapshots work by creating an Image object from the canvas data, this is a blocking process, which gets - * more expensive the larger the canvas size gets, so please be careful how you employ this in your game. - * - * @method Phaser.Renderer.Canvas.CanvasRenderer#snapshotCanvas - * @since 3.19.0 - * - * @param {HTMLCanvasElement} canvas - The canvas to grab from. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. - * @param {boolean} [getPixel=false] - Grab a single pixel as a Color object, or an area as an Image object? - * @param {number} [x=0] - The x coordinate to grab from. - * @param {number} [y=0] - The y coordinate to grab from. - * @param {number} [width=canvas.width] - The width of the area to grab. - * @param {number} [height=canvas.height] - The height of the area to grab. - * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. - * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * The horizontal scroll position of the Tile Sprite. * - * @return {this} This Canvas Renderer. + * @name Phaser.GameObjects.TileSprite#tilePositionX + * @type {number} + * @default 0 + * @since 3.0.0 */ - snapshotCanvas: function (canvas, callback, getPixel, x, y, width, height, type, encoderOptions) - { - if (getPixel === undefined) { getPixel = false; } - - this.snapshotArea(x, y, width, height, callback, type, encoderOptions); - - var state = this.snapshotState; - - state.getPixel = getPixel; + tilePositionX: { - CanvasSnapshot(this.canvas, state); + get: function () + { + return this._tilePosition.x; + }, - state.callback = null; + set: function (value) + { + this._tilePosition.x = value; + this.dirty = true; + } - return this; }, /** - * Schedules a snapshot of the entire game viewport to be taken after the current frame is rendered. - * - * To capture a specific area see the `snapshotArea` method. To capture a specific pixel, see `snapshotPixel`. - * - * Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then - * calling this method will override it. - * - * Snapshots work by creating an Image object from the canvas data, this is a blocking process, which gets - * more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * The vertical scroll position of the Tile Sprite. * - * @method Phaser.Renderer.Canvas.CanvasRenderer#snapshot + * @name Phaser.GameObjects.TileSprite#tilePositionY + * @type {number} + * @default 0 * @since 3.0.0 - * - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. - * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. - * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. - * - * @return {this} This WebGL Renderer. */ - snapshot: function (callback, type, encoderOptions) - { - return this.snapshotArea(0, 0, this.gameCanvas.width, this.gameCanvas.height, callback, type, encoderOptions); - }, + tilePositionY: { - /** - * Schedules a snapshot of the given area of the game viewport to be taken after the current frame is rendered. - * - * To capture the whole game viewport see the `snapshot` method. To capture a specific pixel, see `snapshotPixel`. - * - * Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then - * calling this method will override it. - * - * Snapshots work by creating an Image object from the canvas data, this is a blocking process, which gets - * more expensive the larger the canvas size gets, so please be careful how you employ this in your game. - * - * @method Phaser.Renderer.Canvas.CanvasRenderer#snapshotArea - * @since 3.16.0 - * - * @param {number} x - The x coordinate to grab from. - * @param {number} y - The y coordinate to grab from. - * @param {number} width - The width of the area to grab. - * @param {number} height - The height of the area to grab. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. - * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. - * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. - * - * @return {this} This WebGL Renderer. - */ - snapshotArea: function (x, y, width, height, callback, type, encoderOptions) - { - var state = this.snapshotState; + get: function () + { + return this._tilePosition.y; + }, - state.callback = callback; - state.type = type; - state.encoder = encoderOptions; - state.getPixel = false; - state.x = x; - state.y = y; - state.width = Math.min(width, this.gameCanvas.width); - state.height = Math.min(height, this.gameCanvas.height); + set: function (value) + { + this._tilePosition.y = value; + this.dirty = true; + } - return this; }, /** - * Schedules a snapshot of the given pixel from the game viewport to be taken after the current frame is rendered. - * - * To capture the whole game viewport see the `snapshot` method. To capture a specific area, see `snapshotArea`. - * - * Only one snapshot can be active _per frame_. If you have already called `snapshotArea`, for example, then - * calling this method will override it. - * - * Unlike the other two snapshot methods, this one will return a `Color` object containing the color data for - * the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute, - * using less memory. - * - * @method Phaser.Renderer.Canvas.CanvasRenderer#snapshotPixel - * @since 3.16.0 - * - * @param {number} x - The x coordinate of the pixel to get. - * @param {number} y - The y coordinate of the pixel to get. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted. + * The horizontal scale of the Tile Sprite texture. * - * @return {this} This WebGL Renderer. + * @name Phaser.GameObjects.TileSprite#tileScaleX + * @type {number} + * @default 1 + * @since 3.11.0 */ - snapshotPixel: function (x, y, callback) - { - this.snapshotArea(x, y, 1, 1, callback); + tileScaleX: { - this.snapshotState.getPixel = true; + get: function () + { + return this._tileScale.x; + }, + + set: function (value) + { + this._tileScale.x = value; + this.dirty = true; + } - return this; }, /** - * Takes a Sprite Game Object, or any object that extends it, and draws it to the current context. - * - * @method Phaser.Renderer.Canvas.CanvasRenderer#batchSprite - * @since 3.12.0 + * The vertical scale of the Tile Sprite texture. * - * @param {Phaser.GameObjects.GameObject} sprite - The texture based Game Object to draw. - * @param {Phaser.Textures.Frame} frame - The frame to draw, doesn't have to be that owned by the Game Object. - * @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. + * @name Phaser.GameObjects.TileSprite#tileScaleY + * @type {number} + * @default 1 + * @since 3.11.0 */ - batchSprite: function (sprite, frame, camera, parentTransformMatrix) - { - var alpha = camera.alpha * sprite.alpha; + tileScaleY: { - if (alpha === 0) + get: function () { - // Nothing to see, so abort early - return; + return this._tileScale.y; + }, + + set: function (value) + { + this._tileScale.y = value; + this.dirty = true; } - var ctx = this.currentContext; + } - var camMatrix = this._tempMatrix1; - var spriteMatrix = this._tempMatrix2; +}); - var cd = frame.canvasData; +module.exports = TileSprite; - var frameX = cd.x; - var frameY = cd.y; - var frameWidth = frame.cutWidth; - var frameHeight = frame.cutHeight; - var customPivot = frame.customPivot; - var res = frame.source.resolution; +/***/ }), - var displayOriginX = sprite.displayOriginX; - var displayOriginY = sprite.displayOriginY; +/***/ 93305: +/***/ ((module) => { - var x = -displayOriginX + frame.x; - var y = -displayOriginY + frame.y; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (sprite.isCropped) - { - var crop = sprite._crop; +/** + * 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.TileSprite#renderCanvas + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.TileSprite} 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 TileSpriteCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + src.updateCanvas(); - if (crop.flipX !== sprite.flipX || crop.flipY !== sprite.flipY) - { - frame.updateCropUVs(crop, sprite.flipX, sprite.flipY); - } + camera.addToRenderList(src); - frameWidth = crop.cw; - frameHeight = crop.ch; + renderer.batchSprite(src, src.frame, camera, parentMatrix); +}; - frameX = crop.cx; - frameY = crop.cy; +module.exports = TileSpriteCanvasRenderer; - x = -displayOriginX + crop.x; - y = -displayOriginY + crop.y; - if (sprite.flipX) - { - if (x >= 0) - { - x = -(x + frameWidth); - } - else if (x < 0) - { - x = (Math.abs(x) - frameWidth); - } - } +/***/ }), - if (sprite.flipY) - { - if (y >= 0) - { - y = -(y + frameHeight); - } - else if (y < 0) - { - y = (Math.abs(y) - frameHeight); - } - } - } +/***/ 63950: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - var flipX = 1; - var flipY = 1; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (sprite.flipX) - { - if (!customPivot) - { - x += (-frame.realWidth + (displayOriginX * 2)); - } +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var TileSprite = __webpack_require__(35856); - flipX = -1; - } +/** + * Creates a new TileSprite Game Object and returns it. + * + * Note: This method will only be available if the TileSprite Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#tileSprite + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.TileSprite.TileSpriteConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.TileSprite} The Game Object that was created. + */ +GameObjectCreator.register('tileSprite', function (config, addToScene) +{ + if (config === undefined) { config = {}; } - // Auto-invert the flipY if this is coming from a GLTexture - if (sprite.flipY) - { - if (!customPivot) - { - y += (-frame.realHeight + (displayOriginY * 2)); - } + var x = GetAdvancedValue(config, 'x', 0); + var y = GetAdvancedValue(config, 'y', 0); + var width = GetAdvancedValue(config, 'width', 512); + var height = GetAdvancedValue(config, 'height', 512); + var key = GetAdvancedValue(config, 'key', ''); + var frame = GetAdvancedValue(config, 'frame', ''); - flipY = -1; - } + var tile = new TileSprite(this.scene, x, y, width, height, key, frame); - spriteMatrix.applyITRS(sprite.x, sprite.y, sprite.rotation, sprite.scaleX * flipX, sprite.scaleY * flipY); + if (addToScene !== undefined) + { + config.add = addToScene; + } - camMatrix.copyFrom(camera.matrix); + BuildGameObject(this.scene, tile, config); - if (parentTransformMatrix) - { - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * sprite.scrollFactorX, -camera.scrollY * sprite.scrollFactorY); + return tile; +}); - // Undo the camera scroll - spriteMatrix.e = sprite.x; - spriteMatrix.f = sprite.y; - } - else - { - spriteMatrix.e -= camera.scrollX * sprite.scrollFactorX; - spriteMatrix.f -= camera.scrollY * sprite.scrollFactorY; - } - // Multiply by the Sprite matrix - camMatrix.multiply(spriteMatrix); +/***/ }), - ctx.save(); +/***/ 20509: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - camMatrix.setToContext(ctx); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - ctx.globalCompositeOperation = this.blendModes[sprite.blendMode]; +var TileSprite = __webpack_require__(35856); +var GameObjectFactory = __webpack_require__(61286); - ctx.globalAlpha = alpha; +/** + * Creates a new TileSprite Game Object and adds it to the Scene. + * + * Note: This method will only be available if the TileSprite Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#tileSprite + * @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 {number} width - The width of the Game Object. If zero it will use the size of the texture frame. + * @param {number} height - The height of the Game Object. If zero it will use the size of the texture frame. + * @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. Cannot be a DynamicTexture. + * @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. + * + * @return {Phaser.GameObjects.TileSprite} The Game Object that was created. + */ +GameObjectFactory.register('tileSprite', function (x, y, width, height, texture, frame) +{ + return this.displayList.add(new TileSprite(this.scene, x, y, width, height, texture, frame)); +}); - ctx.imageSmoothingEnabled = !(!this.antialias || frame.source.scaleMode); +// When registering a factory function 'this' refers to the GameObjectFactory 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 - if (sprite.mask) - { - sprite.mask.preRenderCanvas(this, sprite, camera); - } - ctx.drawImage(frame.source.image, frameX, frameY, frameWidth, frameHeight, x, y, frameWidth / res, frameHeight / res); +/***/ }), - if (sprite.mask) - { - sprite.mask.postRenderCanvas(this, sprite, camera); - } +/***/ 9271: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - ctx.restore(); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Destroys all object references in the Canvas Renderer. - * - * @method Phaser.Renderer.Canvas.CanvasRenderer#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.removeAllListeners(); +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; - this.game = null; - this.gameCanvas = null; - this.gameContext = null; - } +if (true) +{ + renderWebGL = __webpack_require__(74287); +} -}); +if (true) +{ + renderCanvas = __webpack_require__(93305); +} -module.exports = CanvasRenderer; +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; /***/ }), -/* 369 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 74287: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CanvasPool = __webpack_require__(31); -var Color = __webpack_require__(38); -var GetFastValue = __webpack_require__(2); +var Utils = __webpack_require__(75512); /** - * Takes a snapshot of an area from the current frame displayed by a canvas. - * - * This is then copied to an Image object. When this loads, the results are sent - * to the callback provided in the Snapshot Configuration object. + * 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. * - * @function Phaser.Renderer.Snapshot.Canvas + * @method Phaser.GameObjects.TileSprite#renderWebGL * @since 3.0.0 + * @private * - * @param {HTMLCanvasElement} sourceCanvas - The canvas to take a snapshot of. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotState} config - The snapshot configuration object. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.TileSprite} 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 CanvasSnapshot = function (canvas, config) +var TileSpriteWebGLRenderer = function (renderer, src, camera, parentMatrix) { - var callback = GetFastValue(config, 'callback'); - var type = GetFastValue(config, 'type', 'image/png'); - var encoderOptions = GetFastValue(config, 'encoder', 0.92); - var x = Math.abs(Math.round(GetFastValue(config, 'x', 0))); - var y = Math.abs(Math.round(GetFastValue(config, 'y', 0))); - var width = GetFastValue(config, 'width', canvas.width); - var height = GetFastValue(config, 'height', canvas.height); - var getPixel = GetFastValue(config, 'getPixel', false); + src.updateCanvas(); - if (getPixel) - { - var context = canvas.getContext('2d'); - var imageData = context.getImageData(x, y, 1, 1); - var data = imageData.data; + var width = src.width; + var height = src.height; - callback.call(null, new Color(data[0], data[1], data[2], data[3] / 255)); - } - else if (x !== 0 || y !== 0 || width !== canvas.width || height !== canvas.height) + if (width === 0 || height === 0) { - // Area Grab - var copyCanvas = CanvasPool.createWebGL(this, width, height); - var ctx = copyCanvas.getContext('2d'); - - ctx.drawImage(canvas, x, y, width, height, 0, 0, width, height); - - var image1 = new Image(); - - image1.onerror = function () - { - callback.call(null); - - CanvasPool.remove(copyCanvas); - }; + return; + } - image1.onload = function () - { - callback.call(null, image1); + camera.addToRenderList(src); - CanvasPool.remove(copyCanvas); - }; + var getTint = Utils.getTintAppendFloatAlpha; - image1.src = copyCanvas.toDataURL(type, encoderOptions); - } - else - { - // Full Grab - var image2 = new Image(); - - image2.onerror = function () - { - callback.call(null); - }; + var pipeline = renderer.pipelines.set(src.pipeline, src); - image2.onload = function () - { - callback.call(null, image2); - }; + var textureUnit = pipeline.setTexture2D(src.fillPattern, src); - image2.src = canvas.toDataURL(type, encoderOptions); - } + pipeline.batchTexture( + src, + src.fillPattern, + src.displayFrame.width * src.tileScaleX, src.displayFrame.height * src.tileScaleY, + src.x, src.y, + width, height, + src.scaleX, src.scaleY, + src.rotation, + src.flipX, src.flipY, + src.scrollFactorX, src.scrollFactorY, + src.originX * width, src.originY * height, + 0, 0, width, height, + getTint(src.tintTopLeft, camera.alpha * src._alphaTL), + getTint(src.tintTopRight, camera.alpha * src._alphaTR), + getTint(src.tintBottomLeft, camera.alpha * src._alphaBL), + getTint(src.tintBottomRight, camera.alpha * src._alphaBR), + src.tintFill, + (src.tilePositionX % src.displayFrame.width) / src.displayFrame.width, + (src.tilePositionY % src.displayFrame.height) / src.displayFrame.height, + camera, + parentMatrix, + false, + textureUnit + ); }; -module.exports = CanvasSnapshot; +module.exports = TileSpriteWebGLRenderer; /***/ }), -/* 370 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 8630: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var modes = __webpack_require__(35); -var CanvasFeatures = __webpack_require__(348); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var Events = __webpack_require__(56631); +var GameEvents = __webpack_require__(97081); +var GameObject = __webpack_require__(89980); +var MATH_CONST = __webpack_require__(83392); +var SoundEvents = __webpack_require__(76038); +var UUID = __webpack_require__(76583); +var VideoRender = __webpack_require__(77974); /** - * Returns an array which maps the default blend modes to supported Canvas blend modes. + * @classdesc + * A Video Game Object. * - * If the browser doesn't support a blend mode, it will default to the normal `source-over` blend mode. + * This Game Object is capable of handling playback of a video file, video stream or media stream. * - * @function Phaser.Renderer.Canvas.GetBlendModes - * @since 3.0.0 + * You can optionally 'preload' the video into the Phaser Video Cache: * - * @return {array} Which Canvas blend mode corresponds to which default Phaser blend mode. - */ -var GetBlendModes = function () -{ - var output = []; - var useNew = CanvasFeatures.supportNewBlendModes; - var so = 'source-over'; - - output[modes.NORMAL] = so; - output[modes.ADD] = 'lighter'; - output[modes.MULTIPLY] = (useNew) ? 'multiply' : so; - output[modes.SCREEN] = (useNew) ? 'screen' : so; - output[modes.OVERLAY] = (useNew) ? 'overlay' : so; - output[modes.DARKEN] = (useNew) ? 'darken' : so; - output[modes.LIGHTEN] = (useNew) ? 'lighten' : so; - output[modes.COLOR_DODGE] = (useNew) ? 'color-dodge' : so; - output[modes.COLOR_BURN] = (useNew) ? 'color-burn' : so; - output[modes.HARD_LIGHT] = (useNew) ? 'hard-light' : so; - output[modes.SOFT_LIGHT] = (useNew) ? 'soft-light' : so; - output[modes.DIFFERENCE] = (useNew) ? 'difference' : so; - output[modes.EXCLUSION] = (useNew) ? 'exclusion' : so; - output[modes.HUE] = (useNew) ? 'hue' : so; - output[modes.SATURATION] = (useNew) ? 'saturation' : so; - output[modes.COLOR] = (useNew) ? 'color' : so; - output[modes.LUMINOSITY] = (useNew) ? 'luminosity' : so; - output[modes.ERASE] = 'destination-out'; - output[modes.SOURCE_IN] = 'source-in'; - output[modes.SOURCE_OUT] = 'source-out'; - output[modes.SOURCE_ATOP] = 'source-atop'; - output[modes.DESTINATION_OVER] = 'destination-over'; - output[modes.DESTINATION_IN] = 'destination-in'; - output[modes.DESTINATION_OUT] = 'destination-out'; - output[modes.DESTINATION_ATOP] = 'destination-atop'; - output[modes.LIGHTER] = 'lighter'; - output[modes.COPY] = 'copy'; - output[modes.XOR] = 'xor'; - - return output; -}; - -module.exports = GetBlendModes; - - -/***/ }), -/* 371 */ -/***/ (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 ArrayRemove = __webpack_require__(93); -var CameraEvents = __webpack_require__(37); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(33); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(91); -var GameEvents = __webpack_require__(22); -var IsSizePowerOfTwo = __webpack_require__(138); -var Matrix4 = __webpack_require__(69); -var NOOP = __webpack_require__(1); -var PipelineManager = __webpack_require__(372); -var RenderTarget = __webpack_require__(141); -var ScaleEvents = __webpack_require__(104); -var TextureEvents = __webpack_require__(106); -var Utils = __webpack_require__(12); -var WebGLSnapshot = __webpack_require__(383); - -/** - * @callback WebGLContextCallback + * ```javascript + * preload () { + * this.load.video('ripley', 'assets/aliens.mp4'); + * } * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer which owns the context. - */ - -/** - * @classdesc - * WebGLRenderer is a class that contains the needed functionality to keep the - * WebGLRenderingContext state clean. The main idea of the WebGLRenderer is to keep track of - * any context change that happens for WebGL rendering inside of Phaser. This means - * if raw webgl functions are called outside the WebGLRenderer of the Phaser WebGL - * rendering ecosystem they might pollute the current WebGLRenderingContext state producing - * unexpected behavior. It's recommended that WebGL interaction is done through - * WebGLRenderer and/or WebGLPipeline. + * create () { + * this.add.video(400, 300, 'ripley'); + * } + * ``` * - * @class WebGLRenderer - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Renderer.WebGL + * You don't have to 'preload' the video. You can also play it directly from a URL: + * + * ```javascript + * create () { + * this.add.video(400, 300).loadURL('assets/aliens.mp4'); + * } + * ``` + * + * To all intents and purposes, a video is a standard Game Object, just like a Sprite. And as such, you can do + * all the usual things to it, such as scaling, rotating, cropping, tinting, making interactive, giving a + * physics body, etc. + * + * Transparent videos are also possible via the WebM file format. Providing the video file has was encoded with + * an alpha channel, and providing the browser supports WebM playback (not all of them do), then it will render + * in-game with full transparency. + * + * Playback is handled entirely via the Request Video Frame API, which is supported by most modern browsers. + * A polyfill is provided for older browsers. + * + * ### Autoplaying Videos + * + * Videos can only autoplay if the browser has been unlocked with an interaction, or satisfies the MEI settings. + * The policies that control autoplaying are vast and vary between browser. You can, and should, read more about + * it here: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide + * + * If your video doesn't contain any audio, then set the `noAudio` parameter to `true` when the video is _loaded_, + * and it will often allow the video to play immediately: + * + * ```javascript + * preload () { + * this.load.video('pixar', 'nemo.mp4', true); + * } + * ``` + * + * The 3rd parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without + * audio can autoplay without requiring a user interaction. Video with audio cannot do this unless it satisfies + * the browsers MEI settings. See the MDN Autoplay Guide for further details. + * + * Or: + * + * ```javascript + * create () { + * this.add.video(400, 300).loadURL('assets/aliens.mp4', true); + * } + * ``` + * + * You can set the `noAudio` parameter to `true` even if the video does contain audio. It will still allow the video + * to play immediately, but the audio will not start. + * + * Note that due to a bug in IE11 you cannot play a video texture to a Sprite in WebGL. For IE11 force Canvas mode. + * + * More details about video playback and the supported media formats can be found on MDN: + * + * https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement + * https://developer.mozilla.org/en-US/docs/Web/Media/Formats + * + * @class Video + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects * @constructor - * @since 3.0.0 + * @since 3.20.0 * - * @param {Phaser.Game} game - The Game instance which owns this WebGL Renderer. + * @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.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Size + * @extends Phaser.GameObjects.Components.TextureCrop + * @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} [key] - Optional key of the Video this Game Object will play, as stored in the Video Cache. */ -var WebGLRenderer = new Class({ +var Video = new Class({ - Extends: EventEmitter, + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.Depth, + Components.Flip, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.Pipeline, + Components.PostPipeline, + Components.ScrollFactor, + Components.Size, + Components.TextureCrop, + Components.Tint, + Components.Transform, + Components.Visible, + VideoRender + ], initialize: - function WebGLRenderer (game) + function Video (scene, x, y, key) { - EventEmitter.call(this); - - var gameConfig = game.config; - - var contextCreationConfig = { - alpha: gameConfig.transparent, - desynchronized: gameConfig.desynchronized, - depth: false, - antialias: gameConfig.antialiasGL, - premultipliedAlpha: gameConfig.premultipliedAlpha, - stencil: true, - failIfMajorPerformanceCaveat: gameConfig.failIfMajorPerformanceCaveat, - powerPreference: gameConfig.powerPreference, - preserveDrawingBuffer: gameConfig.preserveDrawingBuffer - }; - - /** - * The local configuration settings of this WebGL Renderer. - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#config - * @type {object} - * @since 3.0.0 - */ - this.config = { - clearBeforeRender: gameConfig.clearBeforeRender, - antialias: gameConfig.antialias, - backgroundColor: gameConfig.backgroundColor, - contextCreation: contextCreationConfig, - roundPixels: gameConfig.roundPixels, - maxTextures: gameConfig.maxTextures, - maxTextureSize: gameConfig.maxTextureSize, - batchSize: gameConfig.batchSize, - maxLights: gameConfig.maxLights, - mipmapFilter: gameConfig.mipmapFilter - }; + GameObject.call(this, scene, 'Video'); /** - * The Game instance which owns this WebGL Renderer. + * A reference to the HTML Video Element this Video Game Object is playing. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#game - * @type {Phaser.Game} - * @since 3.0.0 - */ - this.game = game; - - /** - * A constant which allows the renderer to be easily identified as a WebGL Renderer. + * Will be `undefined` until a video is loaded for playback. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#type - * @type {number} - * @since 3.0.0 + * @name Phaser.GameObjects.Video#video + * @type {?HTMLVideoElement} + * @since 3.20.0 */ - this.type = CONST.WEBGL; + this.video; /** - * An instance of the Pipeline Manager class, that handles all WebGL Pipelines. - * - * Use this to manage all of your interactions with pipelines, such as adding, getting, - * setting and rendering them. - * - * The Pipeline Manager class is created in the `init` method and then populated - * with pipelines during the `boot` method. + * The Phaser Texture this Game Object is using to render the video to. * - * Prior to Phaser v3.50.0 this was just a plain JavaScript object, not a class. + * Will be `undefined` until a video is loaded for playback. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#pipelines - * @type {Phaser.Renderer.WebGL.PipelineManager} - * @since 3.50.0 + * @name Phaser.GameObjects.Video#videoTexture + * @type {?Phaser.Textures.Texture} + * @since 3.20.0 */ - this.pipelines = null; + this.videoTexture; /** - * The width of the canvas being rendered to. - * This is populated in the onResize event handler. + * A reference to the TextureSource backing the `videoTexture` Texture object. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#width - * @type {number} - * @since 3.0.0 - */ - this.width = 0; - - /** - * The height of the canvas being rendered to. - * This is populated in the onResize event handler. + * Will be `undefined` until a video is loaded for playback. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#height - * @type {number} - * @since 3.0.0 + * @name Phaser.GameObjects.Video#videoTextureSource + * @type {?Phaser.Textures.TextureSource} + * @since 3.20.0 */ - this.height = 0; + this.videoTextureSource; /** - * The canvas which this WebGL Renderer draws to. + * A Phaser `CanvasTexture` instance that holds the most recent snapshot taken from the video. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#canvas - * @type {HTMLCanvasElement} - * @since 3.0.0 - */ - this.canvas = game.canvas; - - /** - * An array of blend modes supported by the WebGL Renderer. + * This will only be set if the `snapshot` or `snapshotArea` methods have been called. * - * This array includes the default blend modes as well as any custom blend modes added through {@link #addBlendMode}. + * Until those methods are called, this property will be `undefined`. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#blendModes - * @type {array} - * @default [] - * @since 3.0.0 + * @name Phaser.GameObjects.Video#snapshotTexture + * @type {?Phaser.Textures.CanvasTexture} + * @since 3.20.0 */ - this.blendModes = []; + this.snapshotTexture; /** - * This property is set to `true` if the WebGL context of the renderer is lost. + * If you have saved this video to a texture via the `saveTexture` method, this controls if the video + * is rendered with `flipY` in WebGL or not. You often need to set this if you wish to use the video texture + * as the input source for a shader. If you find your video is appearing upside down within a shader or + * custom pipeline, flip this property. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#contextLost + * @name Phaser.GameObjects.Video#flipY * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.contextLost = false; - - /** - * Details about the currently scheduled snapshot. - * - * If a non-null `callback` is set in this object, a snapshot of the canvas will be taken after the current frame is fully rendered. - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#snapshotState - * @type {Phaser.Types.Renderer.Snapshot.SnapshotState} - * @since 3.0.0 + * @since 3.20.0 */ - this.snapshotState = { - x: 0, - y: 0, - width: 1, - height: 1, - getPixel: false, - callback: null, - type: 'image/png', - encoder: 0.92, - isFramebuffer: false, - bufferWidth: 0, - bufferHeight: 0 - }; + this.flipY = false; /** - * Cached value for the last texture unit that was used. + * The key used by the texture as stored in the Texture Manager. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#currentActiveTexture - * @type {number} - * @since 3.1.0 + * @name Phaser.GameObjects.Video#_key + * @type {string} + * @private + * @since 3.20.0 */ - this.currentActiveTexture = 0; + this._key = UUID(); /** - * Contains the current starting active texture unit. - * This value is constantly updated and should be treated as read-only by your code. + * An internal flag holding the current state of the video lock, should document interaction be required + * before playback can begin. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#startActiveTexture - * @type {number} - * @since 3.50.0 + * @name Phaser.GameObjects.Video#touchLocked + * @type {boolean} + * @readonly + * @since 3.20.0 */ - this.startActiveTexture = 0; + this.touchLocked = false; /** - * The maximum number of textures the GPU can handle. The minimum under the WebGL1 spec is 8. - * This is set via the Game Config `maxTextures` property and should never be changed after boot. + * Should the video auto play when document interaction is required and happens? * - * @name Phaser.Renderer.WebGL.WebGLRenderer#maxTextures - * @type {number} - * @since 3.50.0 + * @name Phaser.GameObjects.Video#playWhenUnlocked + * @type {boolean} + * @since 3.20.0 */ - this.maxTextures = 0; + this.playWhenUnlocked = false; /** - * An array of the available WebGL texture units, used to populate the uSampler uniforms. - * - * This array is populated during the init phase and should never be changed after boot. + * Has the video created its texture and populated it with the first frame of video? * - * @name Phaser.Renderer.WebGL.WebGLRenderer#textureIndexes - * @type {array} - * @since 3.50.0 + * @name Phaser.GameObjects.Video#frameReady + * @type {boolean} + * @since 3.60.0 */ - this.textureIndexes; + this.frameReady = false; /** - * An array of default temporary WebGL Textures. + * This read-only property returns `true` if the video is currently stalled, i.e. it has stopped + * playing due to a lack of data, or too much data, but hasn't yet reached the end of the video. * - * This array is populated during the init phase and should never be changed after boot. - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#tempTextures - * @type {array} - * @since 3.50.0 - */ - this.tempTextures; - - /** - * The currently bound texture at texture unit zero, if any. + * This is set if the Video DOM element emits any of the following events: * - * @name Phaser.Renderer.WebGL.WebGLRenderer#textureZero - * @type {?WebGLTexture} - * @since 3.50.0 - */ - this.textureZero; - - /** - * The currently bound normal map texture at texture unit one, if any. + * `stalled` + * `suspend` + * `waiting` * - * @name Phaser.Renderer.WebGL.WebGLRenderer#normalTexture - * @type {?WebGLTexture} - * @since 3.50.0 - */ - this.normalTexture; - - /** - * The currently bound framebuffer in use. + * And is cleared if the Video DOM element emits the `playing` event, or handles + * a requestVideoFrame call. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#currentFramebuffer - * @type {WebGLFramebuffer} - * @default null - * @since 3.0.0 - */ - this.currentFramebuffer = null; - - /** - * A stack into which the frame buffer objects are pushed and popped. + * Listen for the Phaser Event `VIDEO_STALLED` to be notified and inspect the event + * to see which DOM event caused it. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#fboStack - * @type {WebGLFramebuffer[]} - * @since 3.50.0 - */ - this.fboStack = []; - - /** - * Current WebGLProgram in use. + * Note that being stalled isn't always a negative thing. A video can be stalled if it + * has downloaded enough data in to its buffer to not need to download any more until + * the current batch of frames have rendered. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#currentProgram - * @type {WebGLProgram} - * @default null - * @since 3.0.0 + * @name Phaser.GameObjects.Video#isStalled + * @type {boolean} + * @readonly + * @since 3.60.0 */ - this.currentProgram = null; + this.isStalled = false; /** - * Current blend mode in use + * Records the number of times the video has failed to play, + * typically because the user hasn't interacted with the page yet. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#currentBlendMode + * @name Phaser.GameObjects.Video#failedPlayAttempts * @type {number} - * @since 3.0.0 - */ - this.currentBlendMode = Infinity; - - /** - * Indicates if the the scissor state is enabled in WebGLRenderingContext - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#currentScissorEnabled - * @type {boolean} - * @default false - * @since 3.0.0 + * @since 3.60.0 */ - this.currentScissorEnabled = false; + this.failedPlayAttempts = 0; /** - * Stores the current scissor data + * If the browser supports the Request Video Frame API then this + * property will hold the metadata that is returned from + * the callback each time it is invoked. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#currentScissor - * @type {Uint32Array} - * @since 3.0.0 - */ - this.currentScissor = null; - - /** - * Stack of scissor data + * See https://wicg.github.io/video-rvfc/#video-frame-metadata-callback + * for a complete list of all properties that will be in this object. + * Likely of most interest is the `mediaTime` property: * - * @name Phaser.Renderer.WebGL.WebGLRenderer#scissorStack - * @type {Uint32Array} - * @since 3.0.0 - */ - this.scissorStack = []; - - /** - * The handler to invoke when the context is lost. - * This should not be changed and is set in the boot method. + * The media presentation timestamp (PTS) in seconds of the frame presented + * (e.g. its timestamp on the video.currentTime timeline). MAY have a zero + * value for live-streams or WebRTC applications. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#contextLostHandler - * @type {function} - * @since 3.19.0 - */ - this.contextLostHandler = NOOP; - - /** - * The handler to invoke when the context is restored. - * This should not be changed and is set in the boot method. + * If the browser doesn't support the API then this property will be undefined. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#contextRestoredHandler - * @type {function} - * @since 3.19.0 + * @name Phaser.GameObjects.Video#metadata + * @type {VideoFrameCallbackMetadata} + * @since 3.60.0 */ - this.contextRestoredHandler = NOOP; + this.metadata; /** - * The underlying WebGL context of the renderer. + * The current retry elapsed time. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#gl - * @type {WebGLRenderingContext} - * @default null - * @since 3.0.0 + * @name Phaser.GameObjects.Video#retry + * @type {number} + * @since 3.20.0 */ - this.gl = null; + this.retry = 0; /** - * Array of strings that indicate which WebGL extensions are supported by the browser. - * This is populated in the `boot` method. + * If a video fails to play due to a lack of user interaction, this is the + * amount of time, in ms, that the video will wait before trying again to + * play. The default is 500ms. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#supportedExtensions - * @type {string[]} - * @default null - * @since 3.0.0 + * @name Phaser.GameObjects.Video#retryInterval + * @type {number} + * @since 3.20.0 */ - this.supportedExtensions = null; + this.retryInterval = 500; /** - * If the browser supports the `ANGLE_instanced_arrays` extension, this property will hold - * a reference to the glExtension for it. + * The video was muted due to a system event, such as the game losing focus. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#instancedArraysExtension - * @type {ANGLE_instanced_arrays} - * @default null - * @since 3.50.0 + * @name Phaser.GameObjects.Video#_systemMuted + * @type {boolean} + * @private + * @since 3.20.0 */ - this.instancedArraysExtension = null; + this._systemMuted = false; /** - * If the browser supports the `OES_vertex_array_object` extension, this property will hold - * a reference to the glExtension for it. + * The video was muted due to game code, not a system event. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#vaoExtension - * @type {OES_vertex_array_object} - * @default null - * @since 3.50.0 + * @name Phaser.GameObjects.Video#_codeMuted + * @type {boolean} + * @private + * @since 3.20.0 */ - this.vaoExtension = null; + this._codeMuted = false; /** - * The WebGL Extensions loaded into the current context. + * The video was paused due to a system event, such as the game losing focus. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#extensions - * @type {object} - * @default {} - * @since 3.0.0 + * @name Phaser.GameObjects.Video#_systemPaused + * @type {boolean} + * @private + * @since 3.20.0 */ - this.extensions = {}; + this._systemPaused = false; /** - * Stores the current WebGL component formats for further use. + * The video was paused due to game code, not a system event. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#glFormats - * @type {array} - * @default [] - * @since 3.2.0 + * @name Phaser.GameObjects.Video#_codePaused + * @type {boolean} + * @private + * @since 3.20.0 */ - this.glFormats = []; + this._codePaused = false; /** - * Stores the supported WebGL texture compression formats. + * The locally bound event callback handlers. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#compression - * @type {Phaser.Types.Renderer.WebGL.WebGLTextureCompression} - * @since 3.8.0 + * @name Phaser.GameObjects.Video#_callbacks + * @type {any} + * @private + * @since 3.20.0 */ - this.compression = { - ETC1: false, - PVRTC: false, - S3TC: false + this._callbacks = { + ended: this.completeHandler.bind(this), + legacy: this.legacyPlayHandler.bind(this), + playing: this.playingHandler.bind(this), + seeked: this.seekedHandler.bind(this), + seeking: this.seekingHandler.bind(this), + stalled: this.stalledHandler.bind(this), + suspend: this.stalledHandler.bind(this), + waiting: this.stalledHandler.bind(this) }; /** - * Cached drawing buffer height to reduce gl calls. + * The locally bound callback handler specifically for load and load error events. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#drawingBufferHeight - * @type {number} - * @readonly - * @since 3.11.0 + * @name Phaser.GameObjects.Video#_loadCallbackHandler + * @type {function} + * @private + * @since 3.60.0 */ - this.drawingBufferHeight = 0; + this._loadCallbackHandler = this.loadErrorHandler.bind(this); /** - * A blank 32x32 transparent texture, as used by the Graphics system where needed. - * This is set in the `boot` method. + * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#blankTexture - * @type {WebGLTexture} - * @readonly - * @since 3.12.0 + * @name Phaser.GameObjects.Video#_crop + * @type {object} + * @private + * @since 3.20.0 */ - this.blankTexture = null; + this._crop = this.resetCropObject(); /** - * A pure white 4x4 texture, as used by the Graphics system where needed. - * This is set in the `boot` method. + * An object containing in and out markers for sequence playback. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#whiteTexture - * @type {WebGLTexture} - * @readonly - * @since 3.50.0 + * @name Phaser.GameObjects.Video#markers + * @type {any} + * @since 3.20.0 */ - this.whiteTexture = null; + this.markers = {}; /** - * The total number of masks currently stacked. + * The in marker. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#maskCount + * @name Phaser.GameObjects.Video#_markerIn * @type {number} - * @since 3.17.0 + * @private + * @since 3.20.0 */ - this.maskCount = 0; + this._markerIn = 0; /** - * The mask stack. + * The out marker. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#maskStack - * @type {Phaser.Display.Masks.GeometryMask[]} - * @since 3.17.0 + * @name Phaser.GameObjects.Video#_markerOut + * @type {number} + * @private + * @since 3.20.0 */ - this.maskStack = []; + this._markerOut = 0; /** - * Internal property that tracks the currently set mask. + * Are we playing a marked segment of the video? * - * @name Phaser.Renderer.WebGL.WebGLRenderer#currentMask - * @type {any} - * @since 3.17.0 + * @name Phaser.GameObjects.Video#_playingMarker + * @type {boolean} + * @private + * @since 3.60.0 */ - this.currentMask = { mask: null, camera: null }; + this._playingMarker = false; /** - * Internal property that tracks the currently set camera mask. + * The previous frames mediaTime. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#currentCameraMask - * @type {any} - * @since 3.17.0 - */ - this.currentCameraMask = { mask: null, camera: null }; + * @name Phaser.GameObjects.Video#_lastUpdate + * @type {number} + * @private + * @since 3.60.0 + */ + this._lastUpdate = 0; /** - * Internal gl function mapping for uniform look-up. - * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniform + * The key of the current video as stored in the Video cache. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#glFuncMap - * @type {any} - * @since 3.17.0 - */ - this.glFuncMap = null; - - /** - * The `type` of the Game Object being currently rendered. - * This can be used by advanced render functions for batching look-ahead. + * If the video did not come from the cache this will be an empty string. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#currentType + * @name Phaser.GameObjects.Video#cacheKey * @type {string} - * @since 3.19.0 + * @readonly + * @since 3.60.0 */ - this.currentType = ''; + this.cacheKey = ''; /** - * Is the `type` of the Game Object being currently rendered different than the - * type of the object before it in the display list? I.e. it's a 'new' type. + * Is the video currently seeking? * - * @name Phaser.Renderer.WebGL.WebGLRenderer#newType - * @type {boolean} - * @since 3.19.0 - */ - this.newType = false; - - /** - * Does the `type` of the next Game Object in the display list match that - * of the object being currently rendered? + * This is set to `true` when the `seeking` event is fired, + * and set to `false` when the `seeked` event is fired. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#nextTypeMatch + * @name Phaser.GameObjects.Video#isSeeking * @type {boolean} - * @since 3.19.0 + * @readonly + * @since 3.60.0 */ - this.nextTypeMatch = false; + this.isSeeking = false; /** - * Is the Game Object being currently rendered the final one in the list? + * Has Video.play been called? This is reset if a new Video is loaded. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#finalType + * @name Phaser.GameObjects.Video#_playCalled * @type {boolean} - * @since 3.50.0 - */ - this.finalType = false; - - /** - * The mipmap magFilter to be used when creating textures. - * - * You can specify this as a string in the game config, i.e.: - * - * `renderer: { mipmapFilter: 'NEAREST_MIPMAP_LINEAR' }` - * - * The 6 options for WebGL1 are, in order from least to most computationally expensive: - * - * NEAREST (for pixel art) - * LINEAR (the default) - * NEAREST_MIPMAP_NEAREST - * LINEAR_MIPMAP_NEAREST - * NEAREST_MIPMAP_LINEAR - * LINEAR_MIPMAP_LINEAR - * - * Mipmaps only work with textures that are fully power-of-two in size. - * - * For more details see https://webglfundamentals.org/webgl/lessons/webgl-3d-textures.html - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#mipmapFilter - * @type {GLenum} - * @since 3.21.0 + * @private + * @since 3.60.0 */ - this.mipmapFilter = null; + this._playCalled = false; /** - * The number of times the renderer had to flush this frame, due to running out of texture units. + * The Callback ID returned by Request Video Frame. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#textureFlush + * @name Phaser.GameObjects.Video#_rfvCallbackId * @type {number} - * @since 3.50.0 + * @private + * @since 3.60.0 */ - this.textureFlush = 0; + this._rfvCallbackId = 0; - /** - * Are the WebGL Textures in their default state? - * - * Used to avoid constant gl binds. - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#isTextureClean - * @type {boolean} - * @since 3.51.0 - */ - this.isTextureClean = false; + var game = scene.sys.game; /** - * The default scissor, set during `preRender` and modified during `resize`. + * A reference to Device.Video. * - * @name Phaser.Renderer.WebGL.WebGLRenderer#defaultScissor - * @type {number[]} + * @name Phaser.GameObjects.Video#_device + * @type {string[]} * @private - * @since 3.50.0 + * @since 3.60.0 */ - this.defaultScissor = [ 0, 0, 0, 0 ]; + this._device = game.device.video; - /** - * Has this renderer fully booted yet? - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#isBooted - * @type {boolean} - * @since 3.50.0 - */ - this.isBooted = false; + this.setPosition(x, y); + this.setSize(256, 256); + this.initPipeline(); + this.initPostPipeline(true); - /** - * A Render Target you can use to capture the current state of the Renderer. - * - * A Render Target encapsulates a framebuffer and texture for the WebGL Renderer. - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#renderTarget - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @since 3.50.0 - */ - this.renderTarget = null; + game.events.on(GameEvents.PAUSE, this.globalPause, this); + game.events.on(GameEvents.RESUME, this.globalResume, this); - /** - * The global game Projection matrix, used by shaders as 'uProjectionMatrix' uniform. - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#projectionMatrix - * @type {Phaser.Math.Matrix4} - * @since 3.50.0 - */ - this.projectionMatrix; + var sound = scene.sys.sound; - /** - * The cached width of the Projection matrix. - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#projectionWidth - * @type {number} - * @since 3.50.0 - */ - this.projectionWidth = 0; + if (sound) + { + sound.on(SoundEvents.GLOBAL_MUTE, this.globalMute, this); + } - /** - * The cached height of the Projection matrix. - * - * @name Phaser.Renderer.WebGL.WebGLRenderer#projectionHeight - * @type {number} - * @since 3.50.0 - */ - this.projectionHeight = 0; + if (key) + { + this.load(key); + } + }, - this.init(this.config); + // Overrides Game Object method + addedToScene: function () + { + this.scene.sys.updateList.add(this); + }, + + // Overrides Game Object method + removedFromScene: function () + { + this.scene.sys.updateList.remove(this); }, /** - * Creates a new WebGLRenderingContext and initializes all internal state. + * Loads a Video from the Video Cache, ready for playback with the `Video.play` method. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#init - * @since 3.0.0 + * If a video is already playing, this method allows you to change the source of the current video element. + * It works by first stopping the current video and then starts playback of the new source through the existing video element. * - * @param {object} config - The configuration object for the renderer. + * The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked + * state, even if you change the source of the video. By changing the source to a new video you avoid having to + * go through the unlock process again. * - * @return {this} This WebGLRenderer instance. + * @method Phaser.GameObjects.Video#load + * @since 3.60.0 + * + * @param {string} key - The key of the Video this Game Object will play, as stored in the Video Cache. + * + * @return {this} This Video Game Object for method chaining. */ - init: function (config) + load: function (key) { - var gl; - var game = this.game; - var canvas = this.canvas; - var clearColor = config.backgroundColor; + var video = this.scene.sys.cache.video.get(key); - // Did they provide their own context? - if (game.config.context) + if (video) { - gl = game.config.context; + this.cacheKey = key; + + this.loadHandler(video.url, video.noAudio, video.crossOrigin); } else { - gl = canvas.getContext('webgl', config.contextCreation) || canvas.getContext('experimental-webgl', config.contextCreation); - } - - if (!gl || gl.isContextLost()) - { - this.contextLost = true; - - throw new Error('WebGL unsupported'); + console.warn('No video in cache for key: ' + key); } - this.gl = gl; - - var _this = this; - - this.contextLostHandler = function (event) - { - _this.contextLost = true; - - _this.game.events.emit(GameEvents.CONTEXT_LOST, _this); + return this; + }, - event.preventDefault(); - }; + /** + * This method allows you to change the source of the current video element. It works by first stopping the + * current video, if playing. Then deleting the video texture, if one has been created. Finally, it makes a + * new video texture and starts playback of the new source through the existing video element. + * + * The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked + * state, even if you change the source of the video. By changing the source to a new video you avoid having to + * go through the unlock process again. + * + * @method Phaser.GameObjects.Video#changeSource + * @since 3.20.0 + * + * @param {string} key - The key of the Video this Game Object will swap to playing, as stored in the Video Cache. + * @param {boolean} [autoplay=true] - Should the video start playing immediately, once the swap is complete? + * @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats. + * @param {number} [markerIn] - Optional in marker time, in seconds, for playback of a sequence of the video. + * @param {number} [markerOut] - Optional out marker time, in seconds, for playback of a sequence of the video. + * + * @return {this} This Video Game Object for method chaining. + */ + changeSource: function (key, autoplay, loop, markerIn, markerOut) + { + if (autoplay === undefined) { autoplay = true; } + if (loop === undefined) { loop = false; } - this.contextRestoredHandler = function () + if (this.cacheKey !== key) { - _this.contextLost = false; + this.load(key); - _this.init(_this.config); + if (autoplay) + { + this.play(loop, markerIn, markerOut); + } + } + }, - _this.game.events.emit(GameEvents.CONTEXT_RESTORED, _this); - }; + /** + * Returns the key of the currently played video, as stored in the Video Cache. + * + * If the video did not come from the cache this will return an empty string. + * + * @method Phaser.GameObjects.Video#getVideoKey + * @since 3.20.0 + * + * @return {string} The key of the video being played from the Video Cache, if any. + */ + getVideoKey: function () + { + return this.cacheKey; + }, - canvas.addEventListener('webglcontextlost', this.contextLostHandler, false); - canvas.addEventListener('webglcontextrestored', this.contextRestoredHandler, false); + /** + * Loads a Video from the given URL, ready for playback with the `Video.play` method. + * + * If a video is already playing, this method allows you to change the source of the current video element. + * It works by first stopping the current video and then starts playback of the new source through the existing video element. + * + * The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked + * state, even if you change the source of the video. By changing the source to a new video you avoid having to + * go through the unlock process again. + * + * @method Phaser.GameObjects.Video#loadURL + * @since 3.60.0 + * + * @param {(string|string[]|Phaser.Types.Loader.FileTypes.VideoFileURLConfig|Phaser.Types.Loader.FileTypes.VideoFileURLConfig[])} [urls] - The absolute or relative URL to load the video files from. + * @param {boolean} [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it. + * @param {string} [crossOrigin] - The value to use for the `crossOrigin` property in the video load request. Either undefined, `anonymous` or `use-credentials`. If no value is given, `crossorigin` will not be set in the request. + * + * @return {this} This Video Game Object for method chaining. + */ + loadURL: function (urls, noAudio, crossOrigin) + { + if (noAudio === undefined) { noAudio = false; } - // Set it back into the Game, so developers can access it from there too - game.context = gl; + var urlConfig = this._device.getVideoURL(urls); - for (var i = 0; i <= 27; i++) + if (!urlConfig) { - this.blendModes.push({ func: [ gl.ONE, gl.ONE_MINUS_SRC_ALPHA ], equation: gl.FUNC_ADD }); + console.warn('No supported video format found for ' + urls); } + else + { + this.cacheKey = ''; - // ADD - this.blendModes[1].func = [ gl.ONE, gl.DST_ALPHA ]; + this.loadHandler(urlConfig.url, noAudio, crossOrigin); + } - // MULTIPLY - this.blendModes[2].func = [ gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA ]; + return this; + }, - // SCREEN - this.blendModes[3].func = [ gl.ONE, gl.ONE_MINUS_SRC_COLOR ]; + /** + * Loads a Video from the given MediaStream object, ready for playback with the `Video.play` method. + * + * @method Phaser.GameObjects.Video#loadMediaStream + * @since 3.50.0 + * + * @param {string} stream - The MediaStream object. + * @param {boolean} [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it. + * @param {string} [crossOrigin] - The value to use for the `crossOrigin` property in the video load request. Either undefined, `anonymous` or `use-credentials`. If no value is given, `crossorigin` will not be set in the request. + * + * @return {this} This Video Game Object for method chaining. + */ + loadMediaStream: function (stream, noAudio, crossOrigin) + { + return this.loadHandler(null, noAudio, crossOrigin, stream); + }, - // ERASE - this.blendModes[17] = { func: [ gl.ZERO, gl.ONE_MINUS_SRC_ALPHA ], equation: gl.FUNC_REVERSE_SUBTRACT }; + /** + * Internal method that loads a Video from the given URL, ready for playback with the + * `Video.play` method. + * + * Normally you don't call this method directly, but instead use the `Video.loadURL` method, + * or the `Video.load` method if you have preloaded the video. + * + * Calling this method will skip checking if the browser supports the given format in + * the URL, where-as the other two methods enforce these checks. + * + * @method Phaser.GameObjects.Video#loadHandler + * @since 3.60.0 + * + * @param {string} [url] - The absolute or relative URL to load the video file from. Set to `null` if passing in a MediaStream object. + * @param {boolean} [noAudio] - Does the video have an audio track? If not you can enable auto-playing on it. + * @param {string} [crossOrigin] - The value to use for the `crossOrigin` property in the video load request. Either undefined, `anonymous` or `use-credentials`. If no value is given, `crossorigin` will not be set in the request. + * @param {string} [stream] - A MediaStream object if this is playing a stream instead of a file. + * + * @return {this} This Video Game Object for method chaining. + */ + loadHandler: function (url, noAudio, crossOrigin, stream) + { + if (!noAudio) { noAudio = false; } - this.glFormats[0] = gl.BYTE; - this.glFormats[1] = gl.SHORT; - this.glFormats[2] = gl.UNSIGNED_BYTE; - this.glFormats[3] = gl.UNSIGNED_SHORT; - this.glFormats[4] = gl.FLOAT; + var video = this.video; - // Set the gl function map - this.glFuncMap = { + if (video) + { + // Re-use the existing video element - mat2: { func: gl.uniformMatrix2fv, length: 1, matrix: true }, - mat3: { func: gl.uniformMatrix3fv, length: 1, matrix: true }, - mat4: { func: gl.uniformMatrix4fv, length: 1, matrix: true }, + this.removeLoadEventHandlers(); - '1f': { func: gl.uniform1f, length: 1 }, - '1fv': { func: gl.uniform1fv, length: 1 }, - '1i': { func: gl.uniform1i, length: 1 }, - '1iv': { func: gl.uniform1iv, length: 1 }, + this.stop(); + } + else + { + video = document.createElement('video'); - '2f': { func: gl.uniform2f, length: 2 }, - '2fv': { func: gl.uniform2fv, length: 1 }, - '2i': { func: gl.uniform2i, length: 2 }, - '2iv': { func: gl.uniform2iv, length: 1 }, + video.controls = false; - '3f': { func: gl.uniform3f, length: 3 }, - '3fv': { func: gl.uniform3fv, length: 1 }, - '3i': { func: gl.uniform3i, length: 3 }, - '3iv': { func: gl.uniform3iv, length: 1 }, + video.setAttribute('playsinline', 'playsinline'); + video.setAttribute('preload', 'auto'); + video.setAttribute('disablePictureInPicture', 'true'); + } - '4f': { func: gl.uniform4f, length: 4 }, - '4fv': { func: gl.uniform4fv, length: 1 }, - '4i': { func: gl.uniform4i, length: 4 }, - '4iv': { func: gl.uniform4iv, length: 1 } + if (noAudio) + { + video.muted = true; + video.defaultMuted = true; - }; + video.setAttribute('autoplay', 'autoplay'); + } + else + { + video.muted = false; + video.defaultMuted = false; - // Load supported extensions - var exts = gl.getSupportedExtensions(); + video.removeAttribute('autoplay'); + } - if (!config.maxTextures || config.maxTextures === -1) + if (!crossOrigin) { - config.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + video.removeAttribute('crossorigin'); } - - if (!config.maxTextureSize) + else { - config.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + video.setAttribute('crossorigin', crossOrigin); } - var extString = 'WEBGL_compressed_texture_'; - var wkExtString = 'WEBKIT_' + extString; + if (stream) + { + if ('srcObject' in video) + { + try + { + video.srcObject = stream; + } + catch (err) + { + if (err.name !== 'TypeError') + { + throw err; + } - this.compression.ETC1 = gl.getExtension(extString + 'etc1') || gl.getExtension(wkExtString + 'etc1'); - this.compression.PVRTC = gl.getExtension(extString + 'pvrtc') || gl.getExtension(wkExtString + 'pvrtc'); - this.compression.S3TC = gl.getExtension(extString + 's3tc') || gl.getExtension(wkExtString + 's3tc'); + video.src = URL.createObjectURL(stream); + } + } + else + { + video.src = URL.createObjectURL(stream); + } + } + else + { + video.src = url; + } - this.supportedExtensions = exts; + this.addLoadEventHandlers(); - var angleString = 'ANGLE_instanced_arrays'; + this.retry = 0; + this.video = video; - this.instancedArraysExtension = (exts.indexOf(angleString) > -1) ? gl.getExtension(angleString) : null; + this._playCalled = false; - var vaoString = 'OES_vertex_array_object'; + video.load(); - this.vaoExtension = (exts.indexOf(vaoString) > -1) ? gl.getExtension(vaoString) : null; + return this; + }, - // Setup initial WebGL state - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.CULL_FACE); + /** + * This method handles the Request Video Frame callback. + * + * It is called by the browser when a new video frame is ready to be displayed. + * + * It's also responsible for the creation of the video texture, if it doesn't + * already exist. If it does, it updates the texture as required. + * + * For more details about the Request Video Frame callback, see: + * https://web.dev/requestvideoframecallback-rvfc + * + * @method Phaser.GameObjects.Video#requestVideoFrame + * @fires Phaser.GameObjects.Events#VIDEO_CREATED + * @fires Phaser.GameObjects.Events#VIDEO_LOOP + * @fires Phaser.GameObjects.Events#VIDEO_COMPLETE + * @fires Phaser.GameObjects.Events#VIDEO_PLAY + * @fires Phaser.GameObjects.Events#VIDEO_TEXTURE + * @since 3.60.0 + * + * @param {DOMHighResTimeStamp} now - The current time in milliseconds. + * @param {VideoFrameCallbackMetadata} metadata - Useful metadata about the video frame that was most recently presented for composition. See https://wicg.github.io/video-rvfc/#video-frame-metadata-callback + */ + requestVideoFrame: function (now, metadata) + { + var video = this.video; - gl.enable(gl.BLEND); + if (!video) + { + return; + } - gl.clearColor(clearColor.redGL, clearColor.greenGL, clearColor.blueGL, clearColor.alphaGL); + var width = metadata.width; + var height = metadata.height; - // Mipmaps - this.mipmapFilter = gl[config.mipmapFilter]; + var texture = this.videoTexture; + var textureSource = this.videoTextureSource; + var newVideo = (!texture || textureSource.source !== video); - // Check maximum supported textures - this.maxTextures = Utils.checkShaderMax(gl, config.maxTextures); + if (newVideo) + { + // First frame of a new video + this._codePaused = video.paused; + this._codeMuted = video.muted; - this.textureIndexes = []; + if (!texture) + { + texture = this.scene.sys.textures.create(this._key, video, width, height); - // Create temporary WebGL textures - var tempTextures = this.tempTextures; + texture.add('__BASE', 0, 0, 0, width, height); - if (Array.isArray(tempTextures)) - { - for (var t = 0; i < this.maxTextures; t++) + this.setTexture(texture); + + this.videoTexture = texture; + this.videoTextureSource = texture.source[0]; + + this.videoTextureSource.setFlipY(this.flipY); + + this.emit(Events.VIDEO_TEXTURE, this, texture); + } + else { - gl.deleteTexture(tempTextures[t]); + // Re-use the existing texture + textureSource.source = video; + textureSource.width = width; + textureSource.height = height; + + // Resize base frame + texture.get().setSize(width, height); } + + this.setSizeToFrame(); + this.updateDisplayOrigin(); } else { - tempTextures = new Array(this.maxTextures); + textureSource.update(); } - // Create temp textures to stop WebGL errors on mac os - for (var index = 0; index < this.maxTextures; index++) - { - var tempTexture = gl.createTexture(); - - gl.activeTexture(gl.TEXTURE0 + index); + this.isStalled = false; - gl.bindTexture(gl.TEXTURE_2D, tempTexture); + this.metadata = metadata; - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([ 0, 0, 255, 255 ])); + var currentTime = metadata.mediaTime; - tempTextures[index] = tempTexture; + if (newVideo) + { + this._lastUpdate = currentTime; - this.textureIndexes.push(index); - } + this.emit(Events.VIDEO_CREATED, this, width, height); - this.tempTextures = tempTextures; + if (!this.frameReady) + { + this.frameReady = true; - // Reset to texture 1 (texture zero is reserved for framebuffers) - this.currentActiveTexture = 1; - this.startActiveTexture++; - gl.activeTexture(gl.TEXTURE1); + this.emit(Events.VIDEO_PLAY, this); + } + } - this.pipelines = new PipelineManager(this); + if (this._playingMarker) + { + if (currentTime >= this._markerOut) + { + if (video.loop) + { + video.currentTime = this._markerIn; - this.setBlendMode(CONST.BlendModes.NORMAL); + this.emit(Events.VIDEO_LOOP, this); + } + else + { + this.stop(false); - this.projectionMatrix = new Matrix4().identity(); + this.emit(Events.VIDEO_COMPLETE, this); + } + } + } + else if (currentTime < this._lastUpdate) + { + this.emit(Events.VIDEO_LOOP, this); + } - game.textures.once(TextureEvents.READY, this.boot, this); + this._lastUpdate = currentTime; - return this; + this._rfvCallbackId = this.video.requestVideoFrameCallback(this.requestVideoFrame.bind(this)); }, /** - * Internal boot handler. Calls 'boot' on each pipeline. + * Starts this video playing. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#boot - * @private - * @since 3.11.0 + * If the video is already playing, or has been queued to play with `changeSource` then this method just returns. + * + * Videos can only autoplay if the browser has been unlocked. This happens if you have interacted with the browser, i.e. + * by clicking on it or pressing a key, or due to server settings. The policies that control autoplaying are vast and + * vary between browser. You can read more here: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide + * + * If your video doesn't contain any audio, then set the `noAudio` parameter to `true` when the video is loaded, + * and it will often allow the video to play immediately: + * + * ```javascript + * preload () { + * this.load.video('pixar', 'nemo.mp4', true); + * } + * ``` + * + * The 3rd parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without + * audio can autoplay without requiring a user interaction. Video with audio cannot do this unless it satisfies + * the browsers MEI settings. See the MDN Autoplay Guide for details. + * + * If you need audio in your videos, then you'll have to consider the fact that the video cannot start playing until the + * user has interacted with the browser, into your game flow. + * + * @method Phaser.GameObjects.Video#play + * @since 3.20.0 + * + * @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats. + * @param {number} [markerIn] - Optional in marker time, in seconds, for playback of a sequence of the video. + * @param {number} [markerOut] - Optional out marker time, in seconds, for playback of a sequence of the video. + * + * @return {this} This Video Game Object for method chaining. */ - boot: function () + play: function (loop, markerIn, markerOut) { - var game = this.game; - var pipelineManager = this.pipelines; - - var baseSize = game.scale.baseSize; + if (markerIn === undefined) { markerIn = -1; } + if (markerOut === undefined) { markerOut = MATH_CONST.MAX_SAFE_INTEGER; } - this.width = baseSize.width; - this.height = baseSize.height; + var video = this.video; - this.isBooted = true; + if (!video || this.isPlaying()) + { + if (!video) + { + console.warn('Video not loaded'); + } - this.renderTarget = new RenderTarget(this, this.width, this.height, 1, 0, true, true); + return this; + } - // Set-up pipelines + // We can reset these each time play is called, even if the video hasn't started yet - pipelineManager.boot(game.config.pipeline); + if (loop === undefined) { loop = video.loop; } - // Set-up default textures, fbo and scissor + video.loop = loop; - this.blankTexture = game.textures.getFrame('__DEFAULT'); - this.whiteTexture = game.textures.getFrame('__WHITE'); + this._markerIn = markerIn; + this._markerOut = markerOut; + this._playingMarker = (markerIn > -1 && markerOut > markerIn && markerOut < MATH_CONST.MAX_SAFE_INTEGER); - var gl = this.gl; + // But we go no further if play has already been called - gl.bindFramebuffer(gl.FRAMEBUFFER, null); + if (!this._playCalled) + { + this._rfvCallbackId = video.requestVideoFrameCallback(this.requestVideoFrame.bind(this)); - gl.enable(gl.SCISSOR_TEST); + this._playCalled = true; - game.scale.on(ScaleEvents.RESIZE, this.onResize, this); + this.createPlayPromise(); + } - this.resize(baseSize.width, baseSize.height); + return this; }, /** - * The event handler that manages the `resize` event dispatched by the Scale Manager. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#onResize - * @since 3.16.0 + * Adds the loading specific event handlers to the video element. * - * @param {Phaser.Structs.Size} gameSize - The default Game Size object. This is the un-modified game dimensions. - * @param {Phaser.Structs.Size} baseSize - The base Size object. The game dimensions. The canvas width / height values match this. + * @method Phaser.GameObjects.Video#addLoadEventHandlers + * @since 3.60.0 */ - onResize: function (gameSize, baseSize) + addLoadEventHandlers: function () { - // Has the underlying canvas size changed? - if (baseSize.width !== this.width || baseSize.height !== this.height) + var video = this.video; + + if (video) { - this.resize(baseSize.width, baseSize.height); + video.addEventListener('error', this._loadCallbackHandler); + video.addEventListener('abort', this._loadCallbackHandler); } }, /** - * Binds the WebGL Renderers Render Target, so all drawn content is now redirected to it. - * - * Make sure to call `endCapture` when you are finished. + * Removes the loading specific event handlers from the video element. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#beginCapture - * @since 3.50.0 + * @method Phaser.GameObjects.Video#removeLoadEventHandlers + * @since 3.60.0 + */ + removeLoadEventHandlers: function () + { + var video = this.video; + + if (video) + { + video.removeEventListener('error', this._loadCallbackHandler); + video.removeEventListener('abort', this._loadCallbackHandler); + } + }, + + /** + * Adds the playback specific event handlers to the video element. * - * @param {number} [width] - Optional new width of the Render Target. - * @param {number} [height] - Optional new height of the Render Target. + * @method Phaser.GameObjects.Video#addEventHandlers + * @since 3.60.0 */ - beginCapture: function (width, height) + addEventHandlers: function () { - if (width === undefined) { width = this.width; } - if (height === undefined) { height = this.height; } + var video = this.video; - this.renderTarget.bind(true, width, height); + // Set these _after_ calling `video.play` or they don't fire + // (really useful, thanks browsers!) - this.setProjectionMatrix(width, height); + if (video) + { + var callbacks = this._callbacks; - this.resetTextures(); + for (var callback in callbacks) + { + video.addEventListener(callback, callbacks[callback]); + } + } }, /** - * Unbinds the WebGL Renderers Render Target and returns it, stopping any further content being drawn to it. - * - * If the viewport or scissors were modified during the capture, you should reset them by calling - * `resetViewport` and `resetScissor` accordingly. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#endCapture - * @since 3.50.0 + * Removes the playback specific event handlers from the video element. * - * @return {Phaser.Renderer.WebGL.RenderTarget} A reference to the WebGL Renderer Render Target. + * @method Phaser.GameObjects.Video#removeEventHandlers + * @since 3.60.0 */ - endCapture: function () + removeEventHandlers: function () { - this.renderTarget.unbind(true); + var video = this.video; - this.resetProjectionMatrix(); + if (video) + { + var callbacks = this._callbacks; - return this.renderTarget; + for (var callback in callbacks) + { + video.removeEventListener(callback, callbacks[callback]); + } + } }, /** - * Resizes the drawing buffer to match that required by the Scale Manager. + * Creates the video.play promise and adds the success and error handlers to it. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#resize - * @fires Phaser.Renderer.Events#RESIZE - * @since 3.0.0 + * Not all browsers support the video.play promise, so this method will fall back to + * the old-school way of handling the video.play call. * - * @param {number} [width] - The new width of the renderer. - * @param {number} [height] - The new height of the renderer. + * See https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play#browser_compatibility for details. * - * @return {this} This WebGLRenderer instance. + * @method Phaser.GameObjects.Video#createPlayPromise + * @since 3.60.0 + * + * @param {boolean} [catchError=true] - Should the error be caught and the video marked as failed to play? */ - resize: function (width, height) + createPlayPromise: function (catchError) { - var gl = this.gl; - - this.width = width; - this.height = height; + if (catchError === undefined) { catchError = true; } - this.setProjectionMatrix(width, height); + var video = this.video; - gl.viewport(0, 0, width, height); + var playPromise = video.play(); - this.drawingBufferHeight = gl.drawingBufferHeight; + if (playPromise !== undefined) + { + var success = this.playSuccess.bind(this); + var error = this.playError.bind(this); - gl.scissor(0, (gl.drawingBufferHeight - height), width, height); + if (!catchError) + { + var _this = this; - this.defaultScissor[2] = width; - this.defaultScissor[3] = height; + error = function () + { + _this.failedPlayAttempts++; + }; + } - this.emit(Events.RESIZE, width, height); + playPromise.then(success).catch(error); + } + else + { + // Old-school fallback here for pre-2019 browsers + video.addEventListener('playing', this._callbacks.legacy); - return this; + if (!catchError) + { + this.failedPlayAttempts++; + } + } }, /** - * Gets the aspect ratio of the WebGLRenderer dimensions. + * Adds a sequence marker to this video. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#getAspectRatio - * @since 3.50.0 + * Markers allow you to split a video up into sequences, delineated by a start and end time, given in seconds. * - * @return {number} The aspect ratio of the WebGLRenderer dimensions. + * You can then play back specific markers via the `playMarker` method. + * + * Note that marker timing is _not_ frame-perfect. You should construct your videos in such a way that you allow for + * plenty of extra padding before and after each sequence to allow for discrepancies in browser seek and currentTime accuracy. + * + * See https://github.com/w3c/media-and-entertainment/issues/4 for more details about this issue. + * + * @method Phaser.GameObjects.Video#addMarker + * @since 3.20.0 + * + * @param {string} key - A unique name to give this marker. + * @param {number} markerIn - The time, in seconds, representing the start of this marker. + * @param {number} markerOut - The time, in seconds, representing the end of this marker. + * + * @return {this} This Video Game Object for method chaining. */ - getAspectRatio: function () + addMarker: function (key, markerIn, markerOut) { - return this.width / this.height; + if (!isNaN(markerIn) && markerIn >= 0 && !isNaN(markerOut) && markerOut > markerIn) + { + this.markers[key] = [ markerIn, markerOut ]; + } + + return this; }, /** - * Sets the Projection Matrix of this renderer to the given dimensions. + * Plays a pre-defined sequence in this video. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setProjectionMatrix - * @since 3.50.0 + * Markers allow you to split a video up into sequences, delineated by a start and end time, given in seconds and + * specified via the `addMarker` method. * - * @param {number} width - The new width of the Projection Matrix. - * @param {number} height - The new height of the Projection Matrix. + * Note that marker timing is _not_ frame-perfect. You should construct your videos in such a way that you allow for + * plenty of extra padding before and after each sequence to allow for discrepancies in browser seek and currentTime accuracy. * - * @return {this} This WebGLRenderer instance. + * See https://github.com/w3c/media-and-entertainment/issues/4 for more details about this issue. + * + * @method Phaser.GameObjects.Video#playMarker + * @since 3.20.0 + * + * @param {string} key - The name of the marker sequence to play. + * @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats. + * + * @return {this} This Video Game Object for method chaining. */ - setProjectionMatrix: function (width, height) + playMarker: function (key, loop) { - if (width !== this.projectionWidth || height !== this.projectionHeight) - { - this.projectionWidth = width; - this.projectionHeight = height; + var marker = this.markers[key]; - this.projectionMatrix.ortho(0, width, height, 0, -1000, 1000); + if (marker) + { + this.play(loop, marker[0], marker[1]); } return this; }, /** - * Resets the Projection Matrix back to this renderers width and height. + * Removes a previously set marker from this video. * - * This is called during `endCapture`, should the matrix have been changed - * as a result of the capture process. + * If the marker is currently playing it will _not_ stop playback. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#resetProjectionMatrix - * @since 3.50.0 + * @method Phaser.GameObjects.Video#removeMarker + * @since 3.20.0 + * + * @param {string} key - The name of the marker to remove. + * + * @return {this} This Video Game Object for method chaining. */ - resetProjectionMatrix: function () + removeMarker: function (key) { - this.projectionWidth = this.width; - this.projectionHeight = this.height; + delete this.markers[key]; - this.projectionMatrix.ortho(0, this.width, this.height, 0, -1000, 1000); + return this; }, /** - * Checks if a WebGL extension is supported + * Takes a snapshot of the current frame of the video and renders it to a CanvasTexture object, + * which is then returned. You can optionally resize the grab by passing a width and height. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#hasExtension - * @since 3.0.0 + * This method returns a reference to the `Video.snapshotTexture` object. Calling this method + * multiple times will overwrite the previous snapshot with the most recent one. * - * @param {string} extensionName - Name of the WebGL extension + * @method Phaser.GameObjects.Video#snapshot + * @since 3.20.0 * - * @return {boolean} `true` if the extension is supported, otherwise `false`. + * @param {number} [width] - The width of the resulting CanvasTexture. + * @param {number} [height] - The height of the resulting CanvasTexture. + * + * @return {Phaser.Textures.CanvasTexture} */ - hasExtension: function (extensionName) + snapshot: function (width, height) { - return this.supportedExtensions ? this.supportedExtensions.indexOf(extensionName) : false; + if (width === undefined) { width = this.width; } + if (height === undefined) { height = this.height; } + + return this.snapshotArea(0, 0, this.width, this.height, width, height); }, /** - * Loads a WebGL extension + * Takes a snapshot of the specified area of the current frame of the video and renders it to a CanvasTexture object, + * which is then returned. You can optionally resize the grab by passing a different `destWidth` and `destHeight`. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#getExtension - * @since 3.0.0 + * This method returns a reference to the `Video.snapshotTexture` object. Calling this method + * multiple times will overwrite the previous snapshot with the most recent one. * - * @param {string} extensionName - The name of the extension to load. + * @method Phaser.GameObjects.Video#snapshotArea + * @since 3.20.0 * - * @return {object} WebGL extension if the extension is supported + * @param {number} [x=0] - The horizontal location of the top-left of the area to grab from. + * @param {number} [y=0] - The vertical location of the top-left of the area to grab from. + * @param {number} [srcWidth] - The width of area to grab from the video. If not given it will grab the full video dimensions. + * @param {number} [srcHeight] - The height of area to grab from the video. If not given it will grab the full video dimensions. + * @param {number} [destWidth] - The destination width of the grab, allowing you to resize it. + * @param {number} [destHeight] - The destination height of the grab, allowing you to resize it. + * + * @return {Phaser.Textures.CanvasTexture} */ - getExtension: function (extensionName) + snapshotArea: function (x, y, srcWidth, srcHeight, destWidth, destHeight) { - if (!this.hasExtension(extensionName)) { return null; } + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (srcWidth === undefined) { srcWidth = this.width; } + if (srcHeight === undefined) { srcHeight = this.height; } + if (destWidth === undefined) { destWidth = srcWidth; } + if (destHeight === undefined) { destHeight = srcHeight; } - if (!(extensionName in this.extensions)) + var video = this.video; + var snap = this.snapshotTexture; + + if (!snap) { - this.extensions[extensionName] = this.gl.getExtension(extensionName); + snap = this.scene.sys.textures.createCanvas(UUID(), destWidth, destHeight); + + this.snapshotTexture = snap; + + if (video) + { + snap.context.drawImage(video, x, y, srcWidth, srcHeight, 0, 0, destWidth, destHeight); + } + } + else + { + snap.setSize(destWidth, destHeight); + + if (video) + { + snap.context.drawImage(video, x, y, srcWidth, srcHeight, 0, 0, destWidth, destHeight); + } } - return this.extensions[extensionName]; + return snap.update(); }, /** - * Flushes the current pipeline if the pipeline is bound + * Stores a copy of this Videos `snapshotTexture` in the Texture Manager using the given key. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#flush - * @since 3.0.0 + * This texture is created when the `snapshot` or `snapshotArea` methods are called. + * + * After doing this, any texture based Game Object, such as a Sprite, can use the contents of the + * snapshot by using the texture key: + * + * ```javascript + * var vid = this.add.video(0, 0, 'intro'); + * + * vid.snapshot(); + * + * vid.saveSnapshotTexture('doodle'); + * + * this.add.image(400, 300, 'doodle'); + * ``` + * + * Updating the contents of the `snapshotTexture`, for example by calling `snapshot` again, + * will automatically update _any_ Game Object that is using it as a texture. + * Calling `saveSnapshotTexture` again will not save another copy of the same texture, + * it will just rename the existing one. + * + * By default it will create a single base texture. You can add frames to the texture + * by using the `Texture.add` method. After doing this, you can then allow Game Objects + * to use a specific frame. + * + * @method Phaser.GameObjects.Video#saveSnapshotTexture + * @since 3.20.0 + * + * @param {string} key - The unique key to store the texture as within the global Texture Manager. + * + * @return {Phaser.Textures.CanvasTexture} The Texture that was saved. */ - flush: function () + saveSnapshotTexture: function (key) { - this.pipelines.flush(); + if (this.snapshotTexture) + { + this.scene.sys.textures.renameTexture(this.snapshotTexture.key, key); + } + else + { + this.snapshotTexture = this.scene.sys.textures.createCanvas(key, this.width, this.height); + } + + return this.snapshotTexture; }, /** - * Pushes a new scissor state. This is used to set nested scissor states. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#pushScissor - * @since 3.0.0 - * - * @param {number} x - The x position of the scissor. - * @param {number} y - The y position of the scissor. - * @param {number} width - The width of the scissor. - * @param {number} height - The height of the scissor. - * @param {number} [drawingBufferHeight] - Optional drawingBufferHeight override value. + * This internal method is called automatically if the playback Promise resolves successfully. * - * @return {number[]} An array containing the scissor values. + * @method Phaser.GameObjects.Video#playSuccess + * @fires Phaser.GameObjects.Events#VIDEO_UNLOCKED + * @since 3.60.0 */ - pushScissor: function (x, y, width, height, drawingBufferHeight) + playSuccess: function () { - if (drawingBufferHeight === undefined) { drawingBufferHeight = this.drawingBufferHeight; } + if (!this._playCalled) + { + // The stop method has been called but the Promise has resolved + // after this, so we need to just abort. + return; + } - var scissorStack = this.scissorStack; + this.addEventHandlers(); - var scissor = [ x, y, width, height ]; + this._codePaused = false; - scissorStack.push(scissor); + if (this.touchLocked) + { + this.touchLocked = false; - this.setScissor(x, y, width, height, drawingBufferHeight); + this.emit(Events.VIDEO_UNLOCKED, this); + } - this.currentScissor = scissor; + var sound = this.scene.sys.sound; - return scissor; + if (sound && sound.mute) + { + // Mute will be set based on the global mute state of the Sound Manager (if there is one) + this.setMute(true); + } + + if (this._markerIn > -1) + { + this.video.currentTime = this._markerIn; + } }, /** - * Sets the current scissor state. + * This internal method is called automatically if the playback Promise fails to resolve. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setScissor - * @since 3.0.0 + * @method Phaser.GameObjects.Video#playError + * @fires Phaser.GameObjects.Events#VIDEO_ERROR + * @fires Phaser.GameObjects.Events#VIDEO_UNSUPPORTED + * @fires Phaser.GameObjects.Events#VIDEO_LOCKED + * @since 3.60.0 * - * @param {number} x - The x position of the scissor. - * @param {number} y - The y position of the scissor. - * @param {number} width - The width of the scissor. - * @param {number} height - The height of the scissor. - * @param {number} [drawingBufferHeight] - Optional drawingBufferHeight override value. + * @param {DOMException} error - The Promise DOM Exception error. */ - setScissor: function (x, y, width, height, drawingBufferHeight) + playError: function (error) { - if (drawingBufferHeight === undefined) { drawingBufferHeight = this.drawingBufferHeight; } - - var gl = this.gl; - - var current = this.currentScissor; - - var setScissor = (width > 0 && height > 0); + var name = error.name; - if (current && setScissor) + if (name === 'NotAllowedError') { - var cx = current[0]; - var cy = current[1]; - var cw = current[2]; - var ch = current[3]; + this.touchLocked = true; + this.playWhenUnlocked = true; + this.failedPlayAttempts = 1; - setScissor = (cx !== x || cy !== y || cw !== width || ch !== height); + this.emit(Events.VIDEO_LOCKED, this); } + else if (name === 'NotSupportedError') + { + this.stop(false); - if (setScissor) + this.emit(Events.VIDEO_UNSUPPORTED, this, error); + } + else { - this.flush(); + this.stop(false); - // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/scissor - gl.scissor(x, (drawingBufferHeight - y - height), width, height); + this.emit(Events.VIDEO_ERROR, this, error); } }, /** - * Resets the gl scissor state to be whatever the current scissor is, if there is one, without - * modifying the scissor stack. + * Called when the video emits a `playing` event. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#resetScissor - * @since 3.50.0 + * This is the legacy handler for browsers that don't support Promise based playback. + * + * @method Phaser.GameObjects.Video#legacyPlayHandler + * @since 3.60.0 */ - resetScissor: function () + legacyPlayHandler: function () { - var gl = this.gl; - - gl.enable(gl.SCISSOR_TEST); - - var current = this.currentScissor; + var video = this.video; - if (current) + if (video) { - var x = current[0]; - var y = current[1]; - var width = current[2]; - var height = current[3]; + this.playSuccess(); - if (width > 0 && height > 0) - { - gl.scissor(x, (this.drawingBufferHeight - y - height), width, height); - } + video.removeEventListener('playing', this._callbacks.legacy); } }, /** - * Pops the last scissor state and sets it. + * Called when the video emits a `playing` event. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#popScissor - * @since 3.0.0 + * @method Phaser.GameObjects.Video#playingHandler + * @fires Phaser.GameObjects.Events#VIDEO_PLAYING + * @since 3.60.0 */ - popScissor: function () + playingHandler: function () { - var scissorStack = this.scissorStack; + this.isStalled = false; - // Remove the current scissor - scissorStack.pop(); + this.emit(Events.VIDEO_PLAYING, this); + }, - // Reset the previous scissor - var scissor = scissorStack[scissorStack.length - 1]; + /** + * This internal method is called automatically if the video fails to load. + * + * @method Phaser.GameObjects.Video#loadErrorHandler + * @fires Phaser.GameObjects.Events#VIDEO_ERROR + * @since 3.20.0 + * + * @param {Event} event - The error Event. + */ + loadErrorHandler: function (event) + { + this.stop(false); - if (scissor) - { - this.setScissor(scissor[0], scissor[1], scissor[2], scissor[3]); - } + this.emit(Events.VIDEO_ERROR, this, event); + }, - this.currentScissor = scissor; + /** + * This internal method is called automatically if the video stalls, for whatever reason. + * + * @method Phaser.GameObjects.Video#stalledHandler + * @fires Phaser.GameObjects.Events#VIDEO_STALLED + * @since 3.60.0 + * + * @param {Event} event - The error Event. + */ + stalledHandler: function (event) + { + this.isStalled = true; + + this.emit(Events.VIDEO_STALLED, this, event); }, /** - * Is there an active stencil mask? + * Called when the video completes playback, i.e. reaches an `ended` state. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#hasActiveStencilMask - * @since 3.17.0 + * This will never happen if the video is coming from a live stream, where the duration is `Infinity`. * - * @return {boolean} `true` if there is an active stencil mask, otherwise `false`. + * @method Phaser.GameObjects.Video#completeHandler + * @fires Phaser.GameObjects.Events#VIDEO_COMPLETE + * @since 3.20.0 */ - hasActiveStencilMask: function () + completeHandler: function () { - var mask = this.currentMask.mask; - var camMask = this.currentCameraMask.mask; + this._playCalled = false; - return ((mask && mask.isStencil) || (camMask && camMask.isStencil)); + this.emit(Events.VIDEO_COMPLETE, this); }, /** - * Resets the gl viewport to the current renderer dimensions. + * The internal update step. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#resetViewport - * @since 3.50.0 + * @method Phaser.GameObjects.Video#preUpdate + * @private + * @since 3.20.0 + * + * @param {number} time - The current timestamp. + * @param {number} delta - The delta time in ms since the last frame. */ - resetViewport: function () + preUpdate: function (time, delta) { - var gl = this.gl; + var video = this.video; - gl.viewport(0, 0, this.width, this.height); + if (!video || !this._playCalled) + { + return; + } - this.drawingBufferHeight = gl.drawingBufferHeight; + if (this.touchLocked && this.playWhenUnlocked) + { + this.retry += delta; + + if (this.retry >= this.retryInterval) + { + this.createPlayPromise(false); + + this.retry = 0; + } + } }, /** - * Sets the blend mode to the value given. + * Seeks to a given point in the video. The value is given as a float between 0 and 1, + * where 0 represents the start of the video and 1 represents the end. * - * If the current blend mode is different from the one given, the pipeline is flushed and the new - * blend mode is enabled. + * Seeking only works if the video has a duration, so will not work for live streams. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setBlendMode - * @since 3.0.0 + * When seeking begins, this video will emit a `seeking` event. When the video completes + * seeking (i.e. reaches its designated timestamp) it will emit a `seeked` event. * - * @param {number} blendModeId - The blend mode to be set. Can be a `BlendModes` const or an integer value. - * @param {boolean} [force=false] - Force the blend mode to be set, regardless of the currently set blend mode. + * If you wish to seek based on time instead, use the `Video.setCurrentTime` method. * - * @return {boolean} `true` if the blend mode was changed as a result of this call, forcing a flush, otherwise `false`. + * Unfortunately, the DOM video element does not guarantee frame-accurate seeking. + * This has been an ongoing subject of discussion: https://github.com/w3c/media-and-entertainment/issues/4 + * + * @method Phaser.GameObjects.Video#seekTo + * @since 3.20.0 + * + * @param {number} value - The point in the video to seek to. A value between 0 and 1. + * + * @return {this} This Video Game Object for method chaining. */ - setBlendMode: function (blendModeId, force) + seekTo: function (value) { - if (force === undefined) { force = false; } - - var gl = this.gl; - var blendMode = this.blendModes[blendModeId]; + var video = this.video; - if (force || (blendModeId !== CONST.BlendModes.SKIP_CHECK && this.currentBlendMode !== blendModeId)) + if (video) { - this.flush(); - - gl.enable(gl.BLEND); - gl.blendEquation(blendMode.equation); + var duration = video.duration; - if (blendMode.func.length > 2) - { - gl.blendFuncSeparate(blendMode.func[0], blendMode.func[1], blendMode.func[2], blendMode.func[3]); - } - else + if (duration !== Infinity && !isNaN(duration)) { - gl.blendFunc(blendMode.func[0], blendMode.func[1]); - } - - this.currentBlendMode = blendModeId; + var seekTime = duration * value; - return true; + this.setCurrentTime(seekTime); + } } - return false; + return this; }, /** - * Creates a new custom blend mode for the renderer. + * A double-precision floating-point value indicating the current playback time in seconds. * - * See https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Blending_modes + * If the media has not started to play and has not been seeked, this value is the media's initial playback time. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#addBlendMode - * @since 3.0.0 + * For a more accurate value, use the `Video.metadata.mediaTime` property instead. * - * @param {GLenum[]} func - An array containing the WebGL functions to use for the source and the destination blending factors, respectively. See the possible constants for {@link WebGLRenderingContext#blendFunc()}. - * @param {GLenum} equation - The equation to use for combining the RGB and alpha components of a new pixel with a rendered one. See the possible constants for {@link WebGLRenderingContext#blendEquation()}. + * @method Phaser.GameObjects.Video#getCurrentTime + * @since 3.20.0 * - * @return {number} The index of the new blend mode, used for referencing it in the future. + * @return {number} A double-precision floating-point value indicating the current playback time in seconds. */ - addBlendMode: function (func, equation) + getCurrentTime: function () { - var index = this.blendModes.push({ func: func, equation: equation }); - - return index - 1; + return (this.video) ? this.video.currentTime : 0; }, /** - * Updates the function bound to a given custom blend mode. + * Seeks to a given playback time in the video. The value is given in _seconds_ or as a string. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#updateBlendMode - * @since 3.0.0 + * Seeking only works if the video has a duration, so will not work for live streams. * - * @param {number} index - The index of the custom blend mode. - * @param {function} func - The function to use for the blend mode. - * @param {function} equation - The equation to use for the blend mode. + * When seeking begins, this video will emit a `seeking` event. When the video completes + * seeking (i.e. reaches its designated timestamp) it will emit a `seeked` event. * - * @return {this} This WebGLRenderer instance. + * You can provide a string prefixed with either a `+` or a `-`, such as `+2.5` or `-2.5`. + * In this case it will seek to +/- the value given, relative to the _current time_. + * + * If you wish to seek based on a duration percentage instead, use the `Video.seekTo` method. + * + * @method Phaser.GameObjects.Video#setCurrentTime + * @since 3.20.0 + * + * @param {(string|number)} value - The playback time to seek to in seconds. Can be expressed as a string, such as `+2` to seek 2 seconds ahead from the current time. + * + * @return {this} This Video Game Object for method chaining. */ - updateBlendMode: function (index, func, equation) + setCurrentTime: function (value) { - if (this.blendModes[index]) - { - this.blendModes[index].func = func; + var video = this.video; - if (equation) + if (video) + { + if (typeof value === 'string') { - this.blendModes[index].equation = equation; + var op = value[0]; + var num = parseFloat(value.substr(1)); + + if (op === '+') + { + value = video.currentTime + num; + } + else if (op === '-') + { + value = video.currentTime - num; + } } + + video.currentTime = value; } return this; }, /** - * Removes a custom blend mode from the renderer. - * Any Game Objects still using this blend mode will error, so be sure to clear them first. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#removeBlendMode - * @since 3.0.0 - * - * @param {number} index - The index of the custom blend mode to be removed. + * Internal seeking handler. * - * @return {this} This WebGLRenderer instance. + * @method Phaser.GameObjects.Video#seekingHandler + * @fires Phaser.GameObjects.Events#VIDEO_SEEKING + * @private + * @since 3.20.0 */ - removeBlendMode: function (index) + seekingHandler: function () { - if (index > 17 && this.blendModes[index]) - { - this.blendModes.splice(index, 1); - } + this.isSeeking = true; - return this; + this.emit(Events.VIDEO_SEEKING, this); }, /** - * Sets the current active texture for texture unit zero to be a blank texture. - * This only happens if there isn't a texture already in use by texture unit zero. + * Internal seeked handler. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setBlankTexture + * @method Phaser.GameObjects.Video#seekedHandler + * @fires Phaser.GameObjects.Events#VIDEO_SEEKED * @private - * @since 3.12.0 + * @since 3.20.0 */ - setBlankTexture: function () + seekedHandler: function () { - this.setTexture2D(this.blankTexture.glTexture); + this.isSeeking = false; + + this.emit(Events.VIDEO_SEEKED, this); }, /** - * Activates the Texture Source and assigns it the next available texture unit. - * If none are available, it will flush the current pipeline first. + * Returns the current progress of the video as a float. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setTextureSource - * @since 3.50.0 + * Progress is defined as a value between 0 (the start) and 1 (the end). + * + * Progress can only be returned if the video has a duration. Some videos, + * such as those coming from a live stream, do not have a duration. In this + * case the method will return -1. * - * @param {Phaser.Textures.TextureSource} textureSource - The Texture Source to be assigned the texture unit. + * @method Phaser.GameObjects.Video#getProgress + * @since 3.20.0 * - * @return {number} The texture unit that was assigned to the Texture Source. + * @return {number} The current progress of playback. If the video has no duration, will always return -1. */ - setTextureSource: function (textureSource) + getProgress: function () { - if (this.pipelines.forceZero()) - { - this.setTextureZero(textureSource.glTexture, true); - - return 0; - } - - var gl = this.gl; - var currentActiveTexture = this.currentActiveTexture; + var video = this.video; - if (textureSource.glIndexCounter < this.startActiveTexture) + if (video) { - textureSource.glIndexCounter = this.startActiveTexture; - - if (currentActiveTexture < this.maxTextures) - { - textureSource.glIndex = currentActiveTexture; - - gl.activeTexture(gl.TEXTURE0 + currentActiveTexture); - gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture); + var duration = video.duration; - this.currentActiveTexture++; - } - else + if (duration !== Infinity && !isNaN(duration)) { - // We're out of textures, so flush the batch and reset back to 0 - this.flush(); - - this.startActiveTexture++; - - this.textureFlush++; - - textureSource.glIndexCounter = this.startActiveTexture; - - textureSource.glIndex = 1; - - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture); - - this.currentActiveTexture = 2; + return video.currentTime / duration; } } - this.isTextureClean = false; - - return textureSource.glIndex; + return -1; }, /** - * Checks to see if the given diffuse and normal map textures are already bound, or not. + * A double-precision floating-point value which indicates the duration (total length) of the media in seconds, + * on the media's timeline. If no media is present on the element, or the media is not valid, the returned value is NaN. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#isNewNormalMap - * @since 3.50.0 + * If the media has no known end (such as for live streams of unknown duration, web radio, media incoming from WebRTC, + * and so forth), this value is +Infinity. * - * @param {WebGLTexture} texture - The WebGL diffuse texture. - * @param {WebGLTexture} normalMap - The WebGL normal map texture. + * If no video has been loaded, this method will return 0. * - * @return {boolean} Returns `false` if this combination is already set, or `true` if it's a new combination. + * @method Phaser.GameObjects.Video#getDuration + * @since 3.20.0 + * + * @return {number} A double-precision floating-point value indicating the duration of the media in seconds. */ - isNewNormalMap: function (texture, normalMap) + getDuration: function () { - return (this.textureZero !== texture || this.normalTexture !== normalMap); + return (this.video) ? this.video.duration : 0; }, /** - * Binds a texture directly to texture unit zero then activates it. - * If the texture is already at unit zero, it skips the bind. - * Make sure to call `clearTextureZero` after using this method. + * Sets the muted state of the currently playing video, if one is loaded. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setTextureZero - * @since 3.50.0 + * @method Phaser.GameObjects.Video#setMute + * @since 3.20.0 + * + * @param {boolean} [value=true] - The mute value. `true` if the video should be muted, otherwise `false`. * - * @param {WebGLTexture} texture - The WebGL texture that needs to be bound. - * @param {boolean} [flush=false] - Flush the pipeline if the texture is different? + * @return {this} This Video Game Object for method chaining. */ - setTextureZero: function (texture, flush) + setMute: function (value) { - if (this.textureZero !== texture) - { - if (flush) - { - this.flush(); - } + if (value === undefined) { value = true; } - var gl = this.gl; + this._codeMuted = value; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture); + var video = this.video; - this.textureZero = texture; + if (video) + { + video.muted = (this._systemMuted) ? true : value; } + + return this; }, /** - * Clears the texture that was directly bound to texture unit zero. + * Returns a boolean indicating if this Video is currently muted. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#clearTextureZero - * @since 3.50.0 + * @method Phaser.GameObjects.Video#isMuted + * @since 3.20.0 + * + * @return {boolean} A boolean indicating if this Video is currently muted, or not. */ - clearTextureZero: function () + isMuted: function () { - this.textureZero = null; + return this._codeMuted; }, /** - * Binds a texture directly to texture unit one then activates it. - * If the texture is already at unit one, it skips the bind. - * Make sure to call `clearNormalMap` after using this method. + * Internal global mute handler. Will mute the video, if playing, if the global sound system mutes. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setNormalMap - * @since 3.50.0 + * @method Phaser.GameObjects.Video#globalMute + * @private + * @since 3.20.0 * - * @param {WebGLTexture} texture - The WebGL texture that needs to be bound. + * @param {(Phaser.Sound.WebAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager)} soundManager - A reference to the Sound Manager that emitted the event. + * @param {boolean} mute - The mute value. `true` if the Sound Manager is now muted, otherwise `false`. */ - setNormalMap: function (texture) + globalMute: function (soundManager, value) { - if (this.normalTexture !== texture) - { - var gl = this.gl; - - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, texture); + this._systemMuted = value; - this.normalTexture = texture; + var video = this.video; - if (this.currentActiveTexture === 1) - { - this.currentActiveTexture = 2; - } + if (video) + { + video.muted = (this._codeMuted) ? true : value; } }, /** - * Clears the texture that was directly bound to texture unit one and - * increases the start active texture counter. + * Internal global pause handler. Will pause the video if the Game itself pauses. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#clearNormalMap - * @since 3.50.0 + * @method Phaser.GameObjects.Video#globalPause + * @private + * @since 3.20.0 */ - clearNormalMap: function () + globalPause: function () { - this.normalTexture = null; - this.startActiveTexture++; - this.currentActiveTexture = 1; + this._systemPaused = true; + + if (this.video && !this.video.ended) + { + this.removeEventHandlers(); - this.textureFlush++; + this.video.pause(); + } }, /** - * Activates each texture, in turn, then binds them all to `null`. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#unbindTextures - * @since 3.50.0 + * Internal global resume handler. Will resume a paused video if the Game itself resumes. * - * @param {boolean} [all=false] - Reset all textures, or just the first two? + * @method Phaser.GameObjects.Video#globalResume + * @private + * @since 3.20.0 */ - unbindTextures: function () + globalResume: function () { - var gl = this.gl; - var temp = this.tempTextures; + this._systemPaused = false; - for (var i = 0; i < temp.length; i++) + if (this.video && !this._codePaused && !this.video.ended) { - gl.activeTexture(gl.TEXTURE0 + i); - gl.bindTexture(gl.TEXTURE_2D, null); + this.createPlayPromise(); } - - this.normalTexture = null; - this.textureZero = null; - - this.currentActiveTexture = 1; - this.startActiveTexture++; - - this.textureFlush++; }, /** - * Flushes the current pipeline, then resets the first two textures - * back to the default temporary textures, resets the start active - * counter and sets texture unit 1 as being active. + * Sets the paused state of the currently loaded video. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#resetTextures - * @since 3.50.0 + * If the video is playing, calling this method with `true` will pause playback. + * If the video is paused, calling this method with `false` will resume playback. + * + * If no video is loaded, this method does nothing. + * + * If the video has not yet been played, `Video.play` will be called with no parameters. + * + * If the video has ended, this method will do nothing. + * + * @method Phaser.GameObjects.Video#setPaused + * @since 3.20.0 + * + * @param {boolean} [value=true] - The paused value. `true` if the video should be paused, `false` to resume it. * - * @param {boolean} [all=false] - Reset all textures, or just the first two? + * @return {this} This Video Game Object for method chaining. */ - resetTextures: function (all) + setPaused: function (value) { - if (all === undefined) { all = false; } - - if (this.isTextureClean) - { - // No need to do this if the textures are already clean - return; - } + if (value === undefined) { value = true; } - this.flush(); + var video = this.video; - var gl = this.gl; - var temp = this.tempTextures; + this._codePaused = value; - if (all) + if (video && !video.ended) { - for (var i = 0; i < temp.length; i++) + if (value) { - gl.activeTexture(gl.TEXTURE0 + i); - gl.bindTexture(gl.TEXTURE_2D, temp[i]); - } - - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, temp[1]); - - this.isTextureClean = true; - } - else - { - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, temp[0]); + if (!video.paused) + { + this.removeEventHandlers(); - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, temp[1]); + video.pause(); + } + } + else if (!value) + { + if (!this._playCalled) + { + this.play(); + } + else if (video.paused && !this._systemPaused) + { + this.createPlayPromise(); + } + } } - this.normalTexture = null; - this.textureZero = null; - - this.currentActiveTexture = 1; - this.startActiveTexture++; - - this.textureFlush++; + return this; }, /** - * Binds a texture at a texture unit. If a texture is already - * bound to that unit it will force a flush on the current pipeline. + * Pauses the current Video, if one is playing. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setTexture2D - * @since 3.0.0 - * @version 2.0 - Updated in 3.50.0 to remove the `textureUnit` and `flush` parameters. + * If no video is loaded, this method does nothing. * - * @param {WebGLTexture} texture - The WebGL texture that needs to be bound. + * Call `Video.resume` to resume playback. * - * @return {number} The texture unit that was assigned to the Texture Source. + * @method Phaser.GameObjects.Video#pause + * @since 3.60.0 + * + * @return {this} This Video Game Object for method chaining. */ - setTexture2D: function (texture) + pause: function () { - if (this.pipelines.forceZero()) - { - this.setTextureZero(texture, true); - - return 0; - } - - var gl = this.gl; - var currentActiveTexture = this.currentActiveTexture; - - if (texture.glIndexCounter < this.startActiveTexture) - { - texture.glIndexCounter = this.startActiveTexture; - - if (currentActiveTexture < this.maxTextures) - { - texture.glIndex = currentActiveTexture; - - gl.activeTexture(gl.TEXTURE0 + currentActiveTexture); - gl.bindTexture(gl.TEXTURE_2D, texture); - - this.currentActiveTexture++; - } - else - { - // We're out of textures, so flush the batch and reset back to 1 (0 is reserved for fbos) - this.flush(); - - this.startActiveTexture++; - - this.textureFlush++; - - texture.glIndexCounter = this.startActiveTexture; - - texture.glIndex = 1; - - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, texture); - - this.currentActiveTexture = 2; - } - } - - this.isTextureClean = false; - - return texture.glIndex; + return this.setPaused(true); }, /** - * Pushes a new framebuffer onto the FBO stack and makes it the currently bound framebuffer. - * - * If there was another framebuffer already bound it will force a pipeline flush. + * Resumes the current Video, if one was previously playing and has been paused. * - * Call `popFramebuffer` to remove it again. + * If no video is loaded, this method does nothing. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#pushFramebuffer - * @since 3.50.0 + * Call `Video.pause` to pause playback. * - * @param {WebGLFramebuffer} framebuffer - The framebuffer that needs to be bound. - * @param {boolean} [updateScissor=false] - Set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. - * @param {boolean} [resetTextures=false] - Should the WebGL Textures be reset after the new framebuffer is bound? - * @param {boolean} [setViewport=true] - Should the WebGL viewport be set? + * @method Phaser.GameObjects.Video#resume + * @since 3.60.0 * - * @return {this} This WebGLRenderer instance. + * @return {this} This Video Game Object for method chaining. */ - pushFramebuffer: function (framebuffer, updateScissor, resetTextures, setViewport) + resume: function () { - if (framebuffer === this.currentFramebuffer) - { - return this; - } - - this.fboStack.push(framebuffer); - - return this.setFramebuffer(framebuffer, updateScissor, resetTextures, setViewport); + return this.setPaused(false); }, /** - * Sets the given framebuffer as the active and currently bound framebuffer. + * Returns a double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). * - * If there was another framebuffer already bound it will force a pipeline flush. + * @method Phaser.GameObjects.Video#getVolume + * @since 3.20.0 * - * Typically, you should call `pushFramebuffer` instead of this method. + * @return {number} A double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). + */ + getVolume: function () + { + return (this.video) ? this.video.volume : 1; + }, + + /** + * Sets the volume of the currently playing video. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setFramebuffer - * @since 3.0.0 + * The value given is a double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). * - * @param {WebGLFramebuffer} framebuffer - The framebuffer that needs to be bound. - * @param {boolean} [updateScissor=false] - If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. - * @param {boolean} [resetTextures=false] - Should the WebGL Textures be reset after the new framebuffer is bound? - * @param {boolean} [setViewport=true] - Should the WebGL viewport be set? + * @method Phaser.GameObjects.Video#setVolume + * @since 3.20.0 * - * @return {this} This WebGLRenderer instance. + * @param {number} [value=1] - A double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). + * + * @return {this} This Video Game Object for method chaining. */ - setFramebuffer: function (framebuffer, updateScissor, resetTextures, setViewport) + setVolume: function (value) { - if (updateScissor === undefined) { updateScissor = false; } - if (resetTextures === undefined) { resetTextures = false; } - if (setViewport === undefined) { setViewport = true; } + if (value === undefined) { value = 1; } - if (framebuffer === this.currentFramebuffer) + if (this.video) { - return this; + this.video.volume = Clamp(value, 0, 1); } - var gl = this.gl; + return this; + }, - var width = this.width; - var height = this.height; + /** + * Returns a double that indicates the rate at which the media is being played back. + * + * @method Phaser.GameObjects.Video#getPlaybackRate + * @since 3.20.0 + * + * @return {number} A double that indicates the rate at which the media is being played back. + */ + getPlaybackRate: function () + { + return (this.video) ? this.video.playbackRate : 1; + }, - if (framebuffer && framebuffer.renderTexture && setViewport) - { - width = framebuffer.renderTexture.width; - height = framebuffer.renderTexture.height; - } - else - { - this.flush(); - } - - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - - if (setViewport) + /** + * Sets the playback rate of the current video. + * + * The value given is a double that indicates the rate at which the media is being played back. + * + * @method Phaser.GameObjects.Video#setPlaybackRate + * @since 3.20.0 + * + * @param {number} [rate] - A double that indicates the rate at which the media is being played back. + * + * @return {this} This Video Game Object for method chaining. + */ + setPlaybackRate: function (rate) + { + if (this.video) { - gl.viewport(0, 0, width, height); + this.video.playbackRate = rate; } - if (updateScissor) - { - if (framebuffer) - { - this.drawingBufferHeight = height; - - this.pushScissor(0, 0, width, height); - } - else - { - this.drawingBufferHeight = this.height; + return this; + }, - this.popScissor(); - } - } + /** + * Returns a boolean which indicates whether the media element should start over when it reaches the end. + * + * @method Phaser.GameObjects.Video#getLoop + * @since 3.20.0 + * + * @return {boolean} A boolean which indicates whether the media element will start over when it reaches the end. + */ + getLoop: function () + { + return (this.video) ? this.video.loop : false; + }, - this.currentFramebuffer = framebuffer; + /** + * Sets the loop state of the current video. + * + * The value given is a boolean which indicates whether the media element will start over when it reaches the end. + * + * Not all videos can loop, for example live streams. + * + * Please note that not all browsers support _seamless_ video looping for all encoding formats. + * + * @method Phaser.GameObjects.Video#setLoop + * @since 3.20.0 + * + * @param {boolean} [value=true] - A boolean which indicates whether the media element will start over when it reaches the end. + * + * @return {this} This Video Game Object for method chaining. + */ + setLoop: function (value) + { + if (value === undefined) { value = true; } - if (resetTextures) + if (this.video) { - this.resetTextures(); + this.video.loop = value; } return this; }, /** - * Pops the previous framebuffer from the fbo stack and sets it. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#popFramebuffer - * @since 3.50.0 + * Returns a boolean which indicates whether the video is currently playing. * - * @param {boolean} [updateScissor=false] - If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. - * @param {boolean} [resetTextures=false] - Should the WebGL Textures be reset after the new framebuffer is bound? - * @param {boolean} [setViewport=true] - Should the WebGL viewport be set? + * @method Phaser.GameObjects.Video#isPlaying + * @since 3.20.0 * - * @return {WebGLFramebuffer} The Framebuffer that was set, or `null` if there aren't any more in the stack. + * @return {boolean} A boolean which indicates whether the video is playing, or not. */ - popFramebuffer: function (updateScissor, resetTextures, setViewport) + isPlaying: function () { - if (updateScissor === undefined) { updateScissor = false; } - if (resetTextures === undefined) { resetTextures = false; } - if (setViewport === undefined) { setViewport = true; } - - var fboStack = this.fboStack; + return (this.video) ? !(this.video.paused || this.video.ended) : false; + }, - // Remove the current fbo - fboStack.pop(); + /** + * Returns a boolean which indicates whether the video is currently paused. + * + * @method Phaser.GameObjects.Video#isPaused + * @since 3.20.0 + * + * @return {boolean} A boolean which indicates whether the video is paused, or not. + */ + isPaused: function () + { + return ((this.video && this._playCalled && this.video.paused) || this._codePaused || this._systemPaused); + }, - // Reset the previous framebuffer - var framebuffer = fboStack[fboStack.length - 1]; + /** + * Stores this Video in the Texture Manager using the given key as a dynamic texture, + * which any texture-based Game Object, such as a Sprite, can use as its source: + * + * ```javascript + * const vid = this.add.video(0, 0, 'intro'); + * + * vid.play(); + * + * vid.saveTexture('doodle'); + * + * this.add.image(400, 300, 'doodle'); + * ``` + * + * If the video is not yet playing then you need to listen for the `TEXTURE_READY` event before + * you can use this texture on a Game Object: + * + * ```javascript + * const vid = this.add.video(0, 0, 'intro'); + * + * vid.play(); + * + * vid.once('textureready', (video, texture, key) => { + * + * this.add.image(400, 300, key); + * + * }); + * + * vid.saveTexture('doodle'); + * ``` + * + * The saved texture is automatically updated as the video plays. If you pause this video, + * or change its source, then the saved texture updates instantly. + * + * Calling `saveTexture` again will not save another copy of the same texture, it will just rename the existing one. + * + * By default it will create a single base texture. You can add frames to the texture + * by using the `Texture.add` method. After doing this, you can then allow Game Objects + * to use a specific frame. + * + * If you intend to save the texture so you can use it as the input for a Shader, you may need to set the + * `flipY` parameter to `true` if you find the video renders upside down in your shader. + * + * @method Phaser.GameObjects.Video#saveTexture + * @since 3.20.0 + * + * @param {string} key - The unique key to store the texture as within the global Texture Manager. + * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y` during upload? + * + * @return {boolean} Returns `true` if the texture is available immediately, otherwise returns `false` and you should listen for the `TEXTURE_READY` event. + */ + saveTexture: function (key, flipY) + { + if (flipY === undefined) { flipY = false; } - if (!framebuffer) + if (this.videoTexture) { - framebuffer = null; + this.scene.sys.textures.renameTexture(this._key, key); + this.videoTextureSource.setFlipY(flipY); } - this.setFramebuffer(framebuffer, updateScissor, resetTextures, setViewport); + this._key = key; + this.flipY = flipY; - return framebuffer; + return (this.videoTexture) ? true : false; }, /** - * Binds a shader program. + * Stops the video playing and clears all internal event listeners. * - * If there was a different program already bound it will force a pipeline flush first. + * If you only wish to pause playback of the video, and resume it a later time, use the `Video.pause` method instead. * - * If the same program given to this method is already set as the current program, no change - * will take place and this method will return `false`. + * If the video hasn't finished downloading, calling this method will not abort the download. To do that you need to + * call `destroy` instead. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setProgram - * @since 3.0.0 + * @method Phaser.GameObjects.Video#stop + * @fires Phaser.GameObjects.Events#VIDEO_STOP + * @since 3.20.0 * - * @param {WebGLProgram} program - The program that needs to be bound. + * @param {boolean} [emitStopEvent=true] - Should the `VIDEO_STOP` event be emitted? * - * @return {boolean} `true` if the given program was bound, otherwise `false`. + * @return {this} This Video Game Object for method chaining. */ - setProgram: function (program) + stop: function (emitStopEvent) { - if (program !== this.currentProgram) - { - this.flush(); + if (emitStopEvent === undefined) { emitStopEvent = true; } - this.gl.useProgram(program); + var video = this.video; - this.currentProgram = program; + if (video) + { + this.removeEventHandlers(); - return true; + video.cancelVideoFrameCallback(this._rfvCallbackId); + + video.pause(); } - return false; - }, + this.retry = 0; + this._playCalled = false; - /** - * Rebinds whatever program `WebGLRenderer.currentProgram` is set as, without - * changing anything, or flushing. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#resetProgram - * @since 3.50.0 - * - * @return {this} This WebGLRenderer instance. - */ - resetProgram: function () - { - this.gl.useProgram(this.currentProgram); + if (emitStopEvent) + { + this.emit(Events.VIDEO_STOP, this); + } return this; }, /** - * Creates a texture from an image source. If the source is not valid it creates an empty texture. + * Removes the Video element from the DOM by calling parentNode.removeChild on itself. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#createTextureFromSource - * @since 3.0.0 + * Also removes the autoplay and src attributes and nulls the `Video.video` reference. * - * @param {object} source - The source of the texture. - * @param {number} width - The width of the texture. - * @param {number} height - The height of the texture. - * @param {number} scaleMode - The scale mode to be used by the texture. + * If you loaded an external video via `Video.loadURL` then you should call this function + * to clear up once you are done with the instance, but don't want to destroy this + * Video Game Object. * - * @return {?WebGLTexture} The WebGL Texture that was created, or `null` if it couldn't be created. + * This method is called automatically by `Video.destroy`. + * + * @method Phaser.GameObjects.Video#removeVideoElement + * @since 3.20.0 */ - createTextureFromSource: function (source, width, height, scaleMode) + removeVideoElement: function () { - var gl = this.gl; - var minFilter = gl.NEAREST; - var magFilter = gl.NEAREST; - var wrap = gl.CLAMP_TO_EDGE; - var texture = null; - - width = source ? source.width : width; - height = source ? source.height : height; - - var pow = IsSizePowerOfTwo(width, height); + var video = this.video; - if (pow) + if (!video) { - wrap = gl.REPEAT; + return; } - if (scaleMode === CONST.ScaleModes.LINEAR && this.config.antialias) + if (video.parentNode) { - minFilter = (pow) ? this.mipmapFilter : gl.LINEAR; - magFilter = gl.LINEAR; + video.parentNode.removeChild(video); } - if (!source && typeof width === 'number' && typeof height === 'number') - { - texture = this.createTexture2D(0, minFilter, magFilter, wrap, wrap, gl.RGBA, null, width, height); - } - else + while (video.hasChildNodes()) { - texture = this.createTexture2D(0, minFilter, magFilter, wrap, wrap, gl.RGBA, source); + video.removeChild(video.firstChild); } - return texture; + video.removeAttribute('autoplay'); + video.removeAttribute('src'); + + this.video = null; }, /** - * A wrapper for creating a WebGLTexture. If no pixel data is passed it will create an empty texture. + * Handles the pre-destroy step for the Video object. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#createTexture2D - * @since 3.0.0 + * This calls `Video.stop` and optionally `Video.removeVideoElement`. * - * @param {number} mipLevel - Mip level of the texture. - * @param {number} minFilter - Filtering of the texture. - * @param {number} magFilter - Filtering of the texture. - * @param {number} wrapT - Wrapping mode of the texture. - * @param {number} wrapS - Wrapping mode of the texture. - * @param {number} format - Which format does the texture use. - * @param {?object} pixels - pixel data. - * @param {number} width - Width of the texture in pixels. - * @param {number} height - Height of the texture in pixels. - * @param {boolean} [pma=true] - Does the texture have premultiplied alpha? - * @param {boolean} [forceSize=false] - If `true` it will use the width and height passed to this method, regardless of the pixels dimension. - * @param {boolean} [flipY=false] - Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. + * If any Sprites are using this Video as their texture it is up to you to manage those. * - * @return {WebGLTexture} The WebGLTexture that was created. + * @method Phaser.GameObjects.Video#preDestroy + * @private + * @since 3.21.0 */ - createTexture2D: function (mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height, pma, forceSize, flipY) + preDestroy: function () { - pma = (pma === undefined || pma === null) ? true : pma; - if (forceSize === undefined) { forceSize = false; } - if (flipY === undefined) { flipY = false; } - - var gl = this.gl; - var texture = gl.createTexture(); + this.stop(false); - gl.activeTexture(gl.TEXTURE0); + this.removeLoadEventHandlers(); - var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D); + this.removeVideoElement(); - gl.bindTexture(gl.TEXTURE_2D, texture); + var game = this.scene.sys.game.events; - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT); + game.off(GameEvents.PAUSE, this.globalPause, this); + game.off(GameEvents.RESUME, this.globalResume, this); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, pma); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); + var sound = this.scene.sys.sound; - if (pixels === null || pixels === undefined) + if (sound) { - gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, width, height, 0, format, gl.UNSIGNED_BYTE, null); + sound.off(SoundEvents.GLOBAL_MUTE, this.globalMute, this); } - else - { - if (!forceSize) - { - width = pixels.width; - height = pixels.height; - } + } - gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, format, gl.UNSIGNED_BYTE, pixels); - } +}); - if (IsSizePowerOfTwo(width, height)) - { - gl.generateMipmap(gl.TEXTURE_2D); - } +module.exports = Video; - if (currentTexture) - { - gl.bindTexture(gl.TEXTURE_2D, currentTexture); - } - texture.isAlphaPremultiplied = pma; - texture.isRenderTexture = false; - texture.width = width; - texture.height = height; - texture.glIndex = 0; - texture.glIndexCounter = -1; +/***/ }), - return texture; - }, +/***/ 56933: +/***/ ((module) => { - /** - * Creates a WebGL Framebuffer object and optionally binds a depth stencil render buffer. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#createFramebuffer - * @since 3.0.0 - * - * @param {number} width - If `addDepthStencilBuffer` is true, this controls the width of the depth stencil. - * @param {number} height - If `addDepthStencilBuffer` is true, this controls the height of the depth stencil. - * @param {WebGLTexture} renderTexture - The color texture where the color pixels are written. - * @param {boolean} [addDepthStencilBuffer=false] - Create a Renderbuffer for the depth stencil? - * - * @return {WebGLFramebuffer} Raw WebGLFramebuffer - */ - createFramebuffer: function (width, height, renderTexture, addDepthStencilBuffer) +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Renders this Game Object with the Canvas Renderer to the given Camera. + * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. + * This method should not be called directly. It is a utility function of the Render module. + * + * @method Phaser.GameObjects.Video#renderCanvas + * @since 3.20.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Video} 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 VideoCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + if (src.videoTexture) { - var gl = this.gl; - var framebuffer = gl.createFramebuffer(); - var complete = 0; + camera.addToRenderList(src); - this.setFramebuffer(framebuffer); + renderer.batchSprite(src, src.frame, camera, parentMatrix); + } +}; - if (addDepthStencilBuffer) - { - var depthStencilBuffer = gl.createRenderbuffer(); +module.exports = VideoCanvasRenderer; - gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer); - gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); - gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer); - } - renderTexture.isRenderTexture = true; - renderTexture.isAlphaPremultiplied = false; +/***/ }), - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, renderTexture, 0); +/***/ 65601: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (complete !== gl.FRAMEBUFFER_COMPLETE) - { - var errors = { - 36054: 'Incomplete Attachment', - 36055: 'Missing Attachment', - 36057: 'Incomplete Dimensions', - 36061: 'Framebuffer Unsupported' - }; +var BuildGameObject = __webpack_require__(88933); +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var Video = __webpack_require__(8630); - throw new Error('Framebuffer status: ' + errors[complete]); - } +/** + * Creates a new Video Game Object and returns it. + * + * Note: This method will only be available if the Video Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#video + * @since 3.20.0 + * + * @param {Phaser.Types.GameObjects.Video.VideoConfig} config - The configuration object this Game Object will use to create itself. + * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * + * @return {Phaser.GameObjects.Video} The Game Object that was created. + */ +GameObjectCreator.register('video', function (config, addToScene) +{ + if (config === undefined) { config = {}; } - framebuffer.renderTexture = renderTexture; + var key = GetAdvancedValue(config, 'key', null); - this.setFramebuffer(null); + var video = new Video(this.scene, 0, 0, key); - this.resetTextures(); + if (addToScene !== undefined) + { + config.add = addToScene; + } - return framebuffer; - }, + BuildGameObject(this.scene, video, config); - /** - * Creates a WebGLProgram instance based on the given vertex and fragment shader source. - * - * Then compiles, attaches and links the program before returning it. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#createProgram - * @since 3.0.0 - * - * @param {string} vertexShader - The vertex shader source code as a single string. - * @param {string} fragmentShader - The fragment shader source code as a single string. - * - * @return {WebGLProgram} The linked WebGLProgram created from the given shader source. - */ - createProgram: function (vertexShader, fragmentShader) + return video; +}); + +// When registering a factory function 'this' refers to the GameObjectCreator context. + + +/***/ }), + +/***/ 215: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Video = __webpack_require__(8630); +var GameObjectFactory = __webpack_require__(61286); + +/** + * Creates a new Video Game Object and adds it to the Scene. + * + * This Game Object is capable of handling playback of a video file, video stream or media stream. + * + * You can optionally 'preload' the video into the Phaser Video Cache: + * + * ```javascript + * preload () { + * this.load.video('ripley', 'assets/aliens.mp4'); + * } + * + * create () { + * this.add.video(400, 300, 'ripley'); + * } + * ``` + * + * You don't have to 'preload' the video. You can also play it directly from a URL: + * + * ```javascript + * create () { + * this.add.video(400, 300).loadURL('assets/aliens.mp4'); + * } + * ``` + * + * To all intents and purposes, a video is a standard Game Object, just like a Sprite. And as such, you can do + * all the usual things to it, such as scaling, rotating, cropping, tinting, making interactive, giving a + * physics body, etc. + * + * Transparent videos are also possible via the WebM file format. Providing the video file has was encoded with + * an alpha channel, and providing the browser supports WebM playback (not all of them do), then it will render + * in-game with full transparency. + * + * ### Autoplaying Videos + * + * Videos can only autoplay if the browser has been unlocked with an interaction, or satisfies the MEI settings. + * The policies that control autoplaying are vast and vary between browser. You can, and should, read more about + * it here: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide + * + * If your video doesn't contain any audio, then set the `noAudio` parameter to `true` when the video is _loaded_, + * and it will often allow the video to play immediately: + * + * ```javascript + * preload () { + * this.load.video('pixar', 'nemo.mp4', true); + * } + * ``` + * + * The 3rd parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without + * audio can autoplay without requiring a user interaction. Video with audio cannot do this unless it satisfies + * the browsers MEI settings. See the MDN Autoplay Guide for further details. + * + * Or: + * + * ```javascript + * create () { + * this.add.video(400, 300).loadURL('assets/aliens.mp4', true); + * } + * ``` + * + * You can set the `noAudio` parameter to `true` even if the video does contain audio. It will still allow the video + * to play immediately, but the audio will not start. + * + * Note that due to a bug in IE11 you cannot play a video texture to a Sprite in WebGL. For IE11 force Canvas mode. + * + * More details about video playback and the supported media formats can be found on MDN: + * + * https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement + * https://developer.mozilla.org/en-US/docs/Web/Media/Formats + * + * Note: This method will only be available if the Video Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#video + * @since 3.20.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] - Optional key of the Video this Game Object will play, as stored in the Video Cache. + * + * @return {Phaser.GameObjects.Video} The Game Object that was created. + */ +GameObjectFactory.register('video', function (x, y, key) +{ + return this.displayList.add(new Video(this.scene, x, y, key)); +}); + + +/***/ }), + +/***/ 77974: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(83572); +} + +if (true) +{ + renderCanvas = __webpack_require__(56933); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; + + +/***/ }), + +/***/ 83572: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Renders this Game Object with the WebGL Renderer to the given Camera. + * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. + * This method should not be called directly. It is a utility function of the Render module. + * + * @method Phaser.GameObjects.Video#renderWebGL + * @since 3.20.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Video} 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 VideoWebGLRenderer = function (renderer, src, camera, parentMatrix) +{ + if (src.videoTexture) { - var gl = this.gl; - var program = gl.createProgram(); - var vs = gl.createShader(gl.VERTEX_SHADER); - var fs = gl.createShader(gl.FRAGMENT_SHADER); + camera.addToRenderList(src); - gl.shaderSource(vs, vertexShader); - gl.shaderSource(fs, fragmentShader); - gl.compileShader(vs); - gl.compileShader(fs); + src.pipeline.batchSprite(src, camera, parentMatrix); + } +}; - if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) - { - throw new Error('Vertex Shader failed:\n' + gl.getShaderInfoLog(vs)); - } +module.exports = VideoWebGLRenderer; - if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) - { - throw new Error('Fragment Shader failed:\n' + gl.getShaderInfoLog(fs)); - } - gl.attachShader(program, vs); - gl.attachShader(program, fs); - gl.linkProgram(program); +/***/ }), - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) - { - throw new Error('Link Program failed:\n' + gl.getProgramInfoLog(program)); - } +/***/ 71030: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - gl.useProgram(program); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return program; +var BlendModes = __webpack_require__(95723); +var Circle = __webpack_require__(26673); +var CircleContains = __webpack_require__(65650); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var Rectangle = __webpack_require__(74118); +var RectangleContains = __webpack_require__(94287); + +/** + * @classdesc + * A Zone Game Object. + * + * A Zone is a non-rendering rectangular Game Object that has a position and size. + * It has no texture and never displays, but does live on the display list and + * can be moved, scaled and rotated like any other Game Object. + * + * Its primary use is for creating Drop Zones and Input Hit Areas and it has a couple of helper methods + * specifically for this. It is also useful for object overlap checks, or as a base for your own + * non-displaying Game Objects. + + * The default origin is 0.5, the center of the Zone, the same as with Game Objects. + * + * @class Zone + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.GameObjects + * @constructor + * @since 3.0.0 + * + * @extends Phaser.GameObjects.Components.Depth + * @extends Phaser.GameObjects.Components.GetBounds + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Transform + * @extends Phaser.GameObjects.Components.ScrollFactor + * @extends Phaser.GameObjects.Components.Visible + * + * @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. + * @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=1] - The width of the Game Object. + * @param {number} [height=1] - The height of the Game Object. + */ +var Zone = new Class({ + + Extends: GameObject, + + Mixins: [ + Components.Depth, + Components.GetBounds, + Components.Origin, + Components.Transform, + Components.ScrollFactor, + Components.Visible + ], + + initialize: + + function Zone (scene, x, y, width, height) + { + if (width === undefined) { width = 1; } + if (height === undefined) { height = width; } + + GameObject.call(this, scene, 'Zone'); + + this.setPosition(x, y); + + /** + * The native (un-scaled) width of this Game Object. + * + * @name Phaser.GameObjects.Zone#width + * @type {number} + * @since 3.0.0 + */ + this.width = width; + + /** + * The native (un-scaled) height of this Game Object. + * + * @name Phaser.GameObjects.Zone#height + * @type {number} + * @since 3.0.0 + */ + this.height = height; + + /** + * The Blend Mode of the Game Object. + * Although a Zone never renders, it still has a blend mode to allow it to fit seamlessly into + * display lists without causing a batch flush. + * + * @name Phaser.GameObjects.Zone#blendMode + * @type {number} + * @since 3.0.0 + */ + this.blendMode = BlendModes.NORMAL; + + this.updateDisplayOrigin(); }, /** - * Wrapper for creating a vertex buffer. + * The displayed width of this Game Object. + * This value takes into account the scale factor. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#createVertexBuffer + * @name Phaser.GameObjects.Zone#displayWidth + * @type {number} * @since 3.0.0 - * - * @param {ArrayBuffer} initialDataOrSize - It's either ArrayBuffer or an integer indicating the size of the vbo - * @param {number} bufferUsage - How the buffer is used. gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW - * - * @return {WebGLBuffer} Raw vertex buffer */ - createVertexBuffer: function (initialDataOrSize, bufferUsage) - { - var gl = this.gl; - var vertexBuffer = gl.createBuffer(); + displayWidth: { - gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, initialDataOrSize, bufferUsage); - gl.bindBuffer(gl.ARRAY_BUFFER, null); + get: function () + { + return this.scaleX * this.width; + }, + + set: function (value) + { + this.scaleX = value / this.width; + } - return vertexBuffer; }, /** - * Wrapper for creating a vertex buffer. + * The displayed height of this Game Object. + * This value takes into account the scale factor. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#createIndexBuffer + * @name Phaser.GameObjects.Zone#displayHeight + * @type {number} * @since 3.0.0 - * - * @param {ArrayBuffer} initialDataOrSize - Either ArrayBuffer or an integer indicating the size of the vbo. - * @param {number} bufferUsage - How the buffer is used. gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW. - * - * @return {WebGLBuffer} Raw index buffer */ - createIndexBuffer: function (initialDataOrSize, bufferUsage) - { - var gl = this.gl; - var indexBuffer = gl.createBuffer(); + displayHeight: { - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, initialDataOrSize, bufferUsage); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + get: function () + { + return this.scaleY * this.height; + }, + + set: function (value) + { + this.scaleY = value / this.height; + } - return indexBuffer; }, /** - * Calls `GL.deleteTexture` on the given WebGLTexture and also optionally - * resets the currently defined textures. + * Sets the size of this Game Object. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#deleteTexture + * @method Phaser.GameObjects.Zone#setSize * @since 3.0.0 * - * @param {WebGLTexture} texture - The WebGL Texture to be deleted. - * @param {boolean} [reset=false] - Call the `resetTextures` method after deleting this texture? + * @param {number} width - The width of this Game Object. + * @param {number} height - The height of this Game Object. + * @param {boolean} [resizeInput=true] - If this Zone has a Rectangle for a hit area this argument will resize the hit area as well. * - * @return {this} This WebGLRenderer instance. + * @return {this} This Game Object. */ - deleteTexture: function (texture, reset) + setSize: function (width, height, resizeInput) { - if (reset) - { - this.resetTextures(true); - } + if (resizeInput === undefined) { resizeInput = true; } - if (texture) + this.width = width; + this.height = height; + + this.updateDisplayOrigin(); + + var input = this.input; + + if (resizeInput && input && !input.customHitArea) { - this.gl.deleteTexture(texture); + input.hitArea.width = width; + input.hitArea.height = height; } return this; }, /** - * Deletes a WebGLFramebuffer from the GL instance. + * Sets the display size of this Game Object. + * Calling this will adjust the scale. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#deleteFramebuffer + * @method Phaser.GameObjects.Zone#setDisplaySize * @since 3.0.0 * - * @param {WebGLFramebuffer} framebuffer - The Framebuffer to be deleted. + * @param {number} width - The width of this Game Object. + * @param {number} height - The height of this Game Object. * - * @return {this} This WebGLRenderer instance. + * @return {this} This Game Object. */ - deleteFramebuffer: function (framebuffer) + setDisplaySize: function (width, height) { - if (framebuffer) - { - this.gl.deleteFramebuffer(framebuffer); - - ArrayRemove(this.fboStack, framebuffer); - - if (this.currentFramebuffer === framebuffer) - { - this.currentFramebuffer = null; - } - } + this.displayWidth = width; + this.displayHeight = height; return this; }, /** - * Deletes a WebGLProgram from the GL instance. + * Sets this Zone to be a Circular Drop Zone. + * The circle is centered on this Zones `x` and `y` coordinates. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#deleteProgram + * @method Phaser.GameObjects.Zone#setCircleDropZone * @since 3.0.0 * - * @param {WebGLProgram} program - The shader program to be deleted. + * @param {number} radius - The radius of the Circle that will form the Drop Zone. * - * @return {this} This WebGLRenderer instance. + * @return {this} This Game Object. */ - deleteProgram: function (program) + setCircleDropZone: function (radius) { - if (program) - { - this.gl.deleteProgram(program); - } - - return this; + return this.setDropZone(new Circle(0, 0, radius), CircleContains); }, /** - * Deletes a WebGLBuffer from the GL instance. + * Sets this Zone to be a Rectangle Drop Zone. + * The rectangle is centered on this Zones `x` and `y` coordinates. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#deleteBuffer + * @method Phaser.GameObjects.Zone#setRectangleDropZone * @since 3.0.0 * - * @param {WebGLBuffer} vertexBuffer - The WebGLBuffer to be deleted. + * @param {number} width - The width of the rectangle drop zone. + * @param {number} height - The height of the rectangle drop zone. * - * @return {this} This WebGLRenderer instance. + * @return {this} This Game Object. */ - deleteBuffer: function (buffer) + setRectangleDropZone: function (width, height) { - this.gl.deleteBuffer(buffer); - - return this; + return this.setDropZone(new Rectangle(0, 0, width, height), RectangleContains); }, /** - * Controls the pre-render operations for the given camera. - * Handles any clipping needed by the camera and renders the background color if a color is visible. + * Allows you to define your own Geometry shape to be used as a Drop Zone. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#preRenderCamera + * @method Phaser.GameObjects.Zone#setDropZone * @since 3.0.0 * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to pre-render. + * @param {object} [hitArea] - A Geometry shape instance, such as Phaser.Geom.Ellipse, or your own custom shape. If not given it will try to create a Rectangle based on the size of this zone. + * @param {Phaser.Types.Input.HitAreaCallback} [hitAreaCallback] - A function that will return `true` if the given x/y coords it is sent are within the shape. If you provide a shape you must also provide a callback. + * + * @return {this} This Game Object. */ - preRenderCamera: function (camera) + setDropZone: function (hitArea, hitAreaCallback) { - var cx = camera.x; - var cy = camera.y; - var cw = camera.width; - var ch = camera.height; - - var color = camera.backgroundColor; - - camera.emit(CameraEvents.PRE_RENDER, camera); - - this.pipelines.preBatchCamera(camera); - - this.pushScissor(cx, cy, cw, ch); - - if (camera.mask) + if (!this.input) { - this.currentCameraMask.mask = camera.mask; - this.currentCameraMask.camera = camera._maskCamera; - - camera.mask.preRenderWebGL(this, camera, camera._maskCamera); + this.setInteractive(hitArea, hitAreaCallback, true); } - if (color.alphaGL > 0) - { - var pipeline = this.pipelines.setMulti(); - - pipeline.drawFillRect( - cx, cy, cw, ch, - Utils.getTintFromFloats(color.blueGL, color.greenGL, color.redGL, 1), - color.alphaGL - ); - } + return this; }, /** - * Return the current stencil mask. + * A NOOP method so you can pass a Zone to a Container. + * Calling this method will do nothing. It is intentionally empty. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#getCurrentStencilMask + * @method Phaser.GameObjects.Zone#setAlpha * @private - * @since 3.50.0 + * @since 3.11.0 */ - getCurrentStencilMask: function () + setAlpha: function () { - var prev = null; - var stack = this.maskStack; - var cameraMask = this.currentCameraMask; - - if (stack.length > 0) - { - prev = stack[stack.length - 1]; - } - else if (cameraMask.mask && cameraMask.mask.isStencil) - { - prev = cameraMask; - } - - return prev; }, /** - * Controls the post-render operations for the given camera. + * A NOOP method so you can pass a Zone to a Container in Canvas. + * Calling this method will do nothing. It is intentionally empty. * - * Renders the foreground camera effects like flash and fading, then resets the current scissor state. + * @method Phaser.GameObjects.Zone#setBlendMode + * @private + * @since 3.16.2 + */ + setBlendMode: function () + { + }, + + /** + * A Zone does not render. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#postRenderCamera - * @since 3.0.0 + * @method Phaser.GameObjects.Zone#renderCanvas + * @private + * @since 3.53.0 * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to post-render. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.GameObjects.Image} 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 */ - postRenderCamera: function (camera) + renderCanvas: function (renderer, src, camera) { - var flashEffect = camera.flashEffect; - var fadeEffect = camera.fadeEffect; - - if (flashEffect.isRunning || (fadeEffect.isRunning || fadeEffect.isComplete)) - { - var pipeline = this.pipelines.setMulti(); - - flashEffect.postRenderWebGL(pipeline, Utils.getTintFromFloats); - fadeEffect.postRenderWebGL(pipeline, Utils.getTintFromFloats); - } - - camera.dirty = false; - - this.popScissor(); - - if (camera.mask) - { - this.currentCameraMask.mask = null; - - camera.mask.postRenderWebGL(this, camera._maskCamera); - } - - this.pipelines.postBatchCamera(camera); - - camera.emit(CameraEvents.POST_RENDER, camera); + camera.addToRenderList(src); }, /** - * Clears the current vertex buffer and updates pipelines. + * A Zone does not render. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#preRender - * @fires Phaser.Renderer.Events#PRE_RENDER - * @since 3.0.0 + * @method Phaser.GameObjects.Zone#renderWebGL + * @private + * @since 3.53.0 + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Image} 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 */ - preRender: function () + renderWebGL: function (renderer, src, camera) { - if (this.contextLost) { return; } + camera.addToRenderList(src); + } - var gl = this.gl; +}); - // Make sure we are bound to the main frame buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, null); +module.exports = Zone; - if (this.config.clearBeforeRender) - { - var clearColor = this.config.backgroundColor; - gl.clearColor(clearColor.redGL, clearColor.greenGL, clearColor.blueGL, clearColor.alphaGL); +/***/ }), - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); - } +/***/ 24067: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - gl.enable(gl.SCISSOR_TEST); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.currentScissor = this.defaultScissor; +var GameObjectCreator = __webpack_require__(99325); +var GetAdvancedValue = __webpack_require__(20494); +var Zone = __webpack_require__(71030); - this.scissorStack.length = 0; - this.scissorStack.push(this.currentScissor); +/** + * Creates a new Zone Game Object and returns it. + * + * Note: This method will only be available if the Zone Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#zone + * @since 3.0.0 + * + * @param {Phaser.Types.GameObjects.Zone.ZoneConfig} config - The configuration object this Game Object will use to create itself. + * + * @return {Phaser.GameObjects.Zone} The Game Object that was created. + */ +GameObjectCreator.register('zone', function (config) +{ + var x = GetAdvancedValue(config, 'x', 0); + var y = GetAdvancedValue(config, 'y', 0); + var width = GetAdvancedValue(config, 'width', 1); + var height = GetAdvancedValue(config, 'height', width); - if (this.game.scene.customViewports) - { - gl.scissor(0, (this.drawingBufferHeight - this.height), this.width, this.height); - } + return new Zone(this.scene, x, y, width, height); +}); - this.currentMask.mask = null; - this.currentCameraMask.mask = null; - this.maskStack.length = 0; +// When registering a factory function 'this' refers to the GameObjectCreator context. - this.textureFlush = 0; - this.emit(Events.PRE_RENDER); - }, +/***/ }), - /** - * The core render step for a Scene Camera. - * - * Iterates through the given array of Game Objects and renders them with the given Camera. - * - * This is called by the `CameraManager.render` method. The Camera Manager instance belongs to a Scene, and is invoked - * by the Scene Systems.render method. - * - * This method is not called if `Camera.visible` is `false`, or `Camera.alpha` is zero. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#render - * @fires Phaser.Renderer.Events#RENDER - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene to render. - * @param {Phaser.GameObjects.GameObject[]} children - An array of filtered Game Objects that can be rendered by the given Camera. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera to render with. - */ - render: function (scene, children, camera) - { - if (this.contextLost) { return; } - - var childCount = children.length; +/***/ 34546: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - this.emit(Events.RENDER, scene, camera); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Apply scissor for cam region + render background color, if not transparent - this.preRenderCamera(camera); +var Zone = __webpack_require__(71030); +var GameObjectFactory = __webpack_require__(61286); - // Nothing to render, so bail out - if (childCount === 0) - { - this.setBlendMode(CONST.BlendModes.NORMAL); +/** + * Creates a new Zone Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Zone Game Object has been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#zone + * @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 {number} width - The width of the Game Object. + * @param {number} height - The height of the Game Object. + * + * @return {Phaser.GameObjects.Zone} The Game Object that was created. + */ +GameObjectFactory.register('zone', function (x, y, width, height) +{ + return this.displayList.add(new Zone(this.scene, x, y, width, height)); +}); - // Applies camera effects and pops the scissor, if set - this.postRenderCamera(camera); +// When registering a factory function 'this' refers to the GameObjectFactory 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 - return; - } - // Reset the current type - this.currentType = ''; +/***/ }), - var current = this.currentMask; +/***/ 95847: +/***/ ((module) => { - for (var i = 0; i < childCount; i++) - { - this.finalType = (i === childCount - 1); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var child = children[i]; +/** + * Calculates the area of the circle. + * + * @function Phaser.Geom.Circle.Area + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The Circle to get the area of. + * + * @return {number} The area of the Circle. + */ +var Area = function (circle) +{ + return (circle.radius > 0) ? Math.PI * circle.radius * circle.radius : 0; +}; - var mask = child.mask; +module.exports = Area; - current = this.currentMask; - if (current.mask && current.mask !== mask) - { - // Render out the previously set mask - current.mask.postRenderWebGL(this, current.camera); - } +/***/ }), - if (mask && current.mask !== mask) - { - mask.preRenderWebGL(this, child, camera); - } +/***/ 26673: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (child.blendMode !== this.currentBlendMode) - { - this.setBlendMode(child.blendMode); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var type = child.type; +var Class = __webpack_require__(56694); +var Contains = __webpack_require__(65650); +var GetPoint = __webpack_require__(94026); +var GetPoints = __webpack_require__(62941); +var GEOM_CONST = __webpack_require__(52394); +var Random = __webpack_require__(30977); - if (type !== this.currentType) - { - this.newType = true; - this.currentType = type; - } +/** + * @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({ - if (!this.finalType) - { - this.nextTypeMatch = (children[i + 1].type === this.currentType); - } - else - { - this.nextTypeMatch = false; - } + initialize: - child.renderWebGL(this, child, camera); + function Circle (x, y, radius) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (radius === undefined) { radius = 0; } - this.newType = false; - } + /** + * 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; - current = this.currentMask; + /** + * 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; - if (current.mask) - { - // Render out the previously set mask, if it was the last item in the display list - current.mask.postRenderWebGL(this, current.camera); - } + /** + * 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; - this.setBlendMode(CONST.BlendModes.NORMAL); + /** + * The internal radius of the circle. + * + * @name Phaser.Geom.Circle#_radius + * @type {number} + * @private + * @since 3.0.0 + */ + this._radius = radius; - // Applies camera effects and pops the scissor, if set - this.postRenderCamera(camera); + /** + * The internal diameter of the circle. + * + * @name Phaser.Geom.Circle#_diameter + * @type {number} + * @private + * @since 3.0.0 + */ + this._diameter = radius * 2; }, /** - * The post-render step happens after all Cameras in all Scenes have been rendered. + * Check to see if the Circle contains the given x / y coordinates. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#postRender - * @fires Phaser.Renderer.Events#POST_RENDER + * @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. */ - postRender: function () + contains: function (x, y) { - if (this.contextLost) { return; } - - this.flush(); - - this.emit(Events.POST_RENDER); - - var state = this.snapshotState; - - if (state.callback) - { - WebGLSnapshot(this.canvas, state); - - state.callback = null; - } - - if (this.textureFlush > 0) - { - this.startActiveTexture++; - this.currentActiveTexture = 1; - } + return Contains(this, x, y); }, /** - * Schedules a snapshot of the entire game viewport to be taken after the current frame is rendered. - * - * To capture a specific area see the `snapshotArea` method. To capture a specific pixel, see `snapshotPixel`. - * - * Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then - * calling this method will override it. - * - * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. - * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, - * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, - * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * 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.Renderer.WebGL.WebGLRenderer#snapshot + * @method Phaser.Geom.Circle#getPoint * @since 3.0.0 * - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. - * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. - * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * @generic {Phaser.Geom.Point} O - [out,$return] * - * @return {this} This WebGL Renderer. + * @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. */ - snapshot: function (callback, type, encoderOptions) + getPoint: function (position, point) { - return this.snapshotArea(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight, callback, type, encoderOptions); + return GetPoint(this, position, point); }, /** - * Schedules a snapshot of the given area of the game viewport to be taken after the current frame is rendered. - * - * To capture the whole game viewport see the `snapshot` method. To capture a specific pixel, see `snapshotPixel`. - * - * Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then - * calling this method will override it. + * 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. * - * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. - * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, - * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, - * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * @method Phaser.Geom.Circle#getPoints + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.WebGLRenderer#snapshotArea - * @since 3.16.0 + * @generic {Phaser.Geom.Point[]} O - [output,$return] * - * @param {number} x - The x coordinate to grab from. - * @param {number} y - The y coordinate to grab from. - * @param {number} width - The width of the area to grab. - * @param {number} height - The height of the area to grab. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. - * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. - * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * @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 {this} This WebGL Renderer. + * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the circle. */ - snapshotArea: function (x, y, width, height, callback, type, encoderOptions) + getPoints: function (quantity, stepRate, output) { - var state = this.snapshotState; - - state.callback = callback; - state.type = type; - state.encoder = encoderOptions; - state.getPixel = false; - state.x = x; - state.y = y; - state.width = Math.min(width, this.gl.drawingBufferWidth); - state.height = Math.min(height, this.gl.drawingBufferHeight); - - return this; + return GetPoints(this, quantity, stepRate, output); }, /** - * Schedules a snapshot of the given pixel from the game viewport to be taken after the current frame is rendered. - * - * To capture the whole game viewport see the `snapshot` method. To capture a specific area, see `snapshotArea`. - * - * Only one snapshot can be active _per frame_. If you have already called `snapshotArea`, for example, then - * calling this method will override it. + * Returns a uniformly distributed random point from anywhere within the Circle. * - * Unlike the other two snapshot methods, this one will return a `Color` object containing the color data for - * the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute, - * using less memory. + * @method Phaser.Geom.Circle#getRandomPoint + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.WebGLRenderer#snapshotPixel - * @since 3.16.0 + * @generic {Phaser.Geom.Point} O - [point,$return] * - * @param {number} x - The x coordinate of the pixel to get. - * @param {number} y - The y coordinate of the pixel to get. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted. + * @param {(Phaser.Geom.Point|object)} [point] - A Point or point-like object to set the random `x` and `y` values in. * - * @return {this} This WebGL Renderer. + * @return {(Phaser.Geom.Point|object)} A Point object with the random values set in the `x` and `y` properties. */ - snapshotPixel: function (x, y, callback) + getRandomPoint: function (point) { - this.snapshotArea(x, y, 1, 1, callback); - - this.snapshotState.getPixel = true; - - return this; + return Random(this, point); }, /** - * Takes a snapshot of the given area of the given frame buffer. - * - * Unlike the other snapshot methods, this one is processed immediately and doesn't wait for the next render. - * - * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. - * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, - * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, - * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * Sets the x, y and radius of this circle. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#snapshotFramebuffer - * @since 3.19.0 + * @method Phaser.Geom.Circle#setTo + * @since 3.0.0 * - * @param {WebGLFramebuffer} framebuffer - The framebuffer to grab from. - * @param {number} bufferWidth - The width of the framebuffer. - * @param {number} bufferHeight - The height of the framebuffer. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. - * @param {boolean} [getPixel=false] - Grab a single pixel as a Color object, or an area as an Image object? - * @param {number} [x=0] - The x coordinate to grab from. - * @param {number} [y=0] - The y coordinate to grab from. - * @param {number} [width=bufferWidth] - The width of the area to grab. - * @param {number} [height=bufferHeight] - The height of the area to grab. - * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. - * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * @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 WebGL Renderer. + * @return {this} This Circle object. */ - snapshotFramebuffer: function (framebuffer, bufferWidth, bufferHeight, callback, getPixel, x, y, width, height, type, encoderOptions) + setTo: function (x, y, radius) { - if (getPixel === undefined) { getPixel = false; } - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = bufferWidth; } - if (height === undefined) { height = bufferHeight; } - - var currentFramebuffer = this.currentFramebuffer; - - this.snapshotArea(x, y, width, height, callback, type, encoderOptions); - - var state = this.snapshotState; - - state.getPixel = getPixel; - - state.isFramebuffer = true; - state.bufferWidth = bufferWidth; - state.bufferHeight = bufferHeight; - - this.setFramebuffer(framebuffer); - - WebGLSnapshot(this.canvas, state); - - this.setFramebuffer(currentFramebuffer); - - state.callback = null; - state.isFramebuffer = false; + this.x = x; + this.y = y; + this._radius = radius; + this._diameter = radius * 2; return this; }, /** - * Creates a new WebGL Texture based on the given Canvas Element. - * - * If the `dstTexture` parameter is given, the WebGL Texture is updated, rather than created fresh. + * Sets this Circle to be empty with a radius of zero. + * Does not change its position. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#canvasToTexture + * @method Phaser.Geom.Circle#setEmpty * @since 3.0.0 * - * @param {HTMLCanvasElement} srcCanvas - The Canvas to create the WebGL Texture from - * @param {WebGLTexture} [dstTexture] - The destination WebGL Texture to set. - * @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT` (such as for Text objects?) - * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? - * - * @return {WebGLTexture} The newly created, or updated, WebGL Texture. + * @return {this} This Circle object. */ - canvasToTexture: function (srcCanvas, dstTexture, noRepeat, flipY) + setEmpty: function () { - if (noRepeat === undefined) { noRepeat = false; } - if (flipY === undefined) { flipY = false; } + this._radius = 0; + this._diameter = 0; - if (!dstTexture) - { - return this.createCanvasTexture(srcCanvas, noRepeat, flipY); - } - else - { - return this.updateCanvasTexture(srcCanvas, dstTexture, flipY); - } + return this; }, /** - * Creates a new WebGL Texture based on the given Canvas Element. + * Sets the position of this Circle. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#createCanvasTexture - * @since 3.20.0 + * @method Phaser.Geom.Circle#setPosition + * @since 3.0.0 * - * @param {HTMLCanvasElement} srcCanvas - The Canvas to create the WebGL Texture from - * @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT` (such as for Text objects?) - * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? + * @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 {WebGLTexture} The newly created WebGL Texture. + * @return {this} This Circle object. */ - createCanvasTexture: function (srcCanvas, noRepeat, flipY) + setPosition: function (x, y) { - if (noRepeat === undefined) { noRepeat = false; } - if (flipY === undefined) { flipY = false; } - - var gl = this.gl; - var minFilter = gl.NEAREST; - var magFilter = gl.NEAREST; - - var width = srcCanvas.width; - var height = srcCanvas.height; - - var wrapping = gl.CLAMP_TO_EDGE; - - var pow = IsSizePowerOfTwo(width, height); - - if (!noRepeat && pow) - { - wrapping = gl.REPEAT; - } + if (y === undefined) { y = x; } - if (this.config.antialias) - { - minFilter = (pow) ? this.mipmapFilter : gl.LINEAR; - magFilter = gl.LINEAR; - } + this.x = x; + this.y = y; - return this.createTexture2D(0, minFilter, magFilter, wrapping, wrapping, gl.RGBA, srcCanvas, width, height, true, false, flipY); + return this; }, /** - * Updates a WebGL Texture based on the given Canvas Element. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#updateCanvasTexture - * @since 3.20.0 + * Checks to see if the Circle is empty: has a radius of zero. * - * @param {HTMLCanvasElement} srcCanvas - The Canvas to update the WebGL Texture from. - * @param {WebGLTexture} dstTexture - The destination WebGL Texture to update. - * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? + * @method Phaser.Geom.Circle#isEmpty + * @since 3.0.0 * - * @return {WebGLTexture} The updated WebGL Texture. + * @return {boolean} True if the Circle is empty, otherwise false. */ - updateCanvasTexture: function (srcCanvas, dstTexture, flipY) + isEmpty: function () { - if (flipY === undefined) { flipY = false; } - - var gl = this.gl; + return (this._radius <= 0); + }, - var width = srcCanvas.width; - var height = srcCanvas.height; + /** + * The radius of the Circle. + * + * @name Phaser.Geom.Circle#radius + * @type {number} + * @since 3.0.0 + */ + radius: { - if (width > 0 && height > 0) + get: function () { - gl.activeTexture(gl.TEXTURE0); - var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D); - gl.bindTexture(gl.TEXTURE_2D, dstTexture); - - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); - - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas); - - dstTexture.width = width; - dstTexture.height = height; + return this._radius; + }, - if (currentTexture) - { - gl.bindTexture(gl.TEXTURE_2D, currentTexture); - } + set: function (value) + { + this._radius = value; + this._diameter = value * 2; } - return dstTexture; }, /** - * Creates a new WebGL Texture based on the given HTML Video Element. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#createVideoTexture - * @since 3.20.0 - * - * @param {HTMLVideoElement} srcVideo - The Video to create the WebGL Texture from - * @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT`? - * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? + * The diameter of the Circle. * - * @return {WebGLTexture} The newly created WebGL Texture. + * @name Phaser.Geom.Circle#diameter + * @type {number} + * @since 3.0.0 */ - createVideoTexture: function (srcVideo, noRepeat, flipY) - { - if (noRepeat === undefined) { noRepeat = false; } - if (flipY === undefined) { flipY = false; } - - var gl = this.gl; - var minFilter = gl.NEAREST; - var magFilter = gl.NEAREST; - - var width = srcVideo.videoWidth; - var height = srcVideo.videoHeight; - - var wrapping = gl.CLAMP_TO_EDGE; - - var pow = IsSizePowerOfTwo(width, height); + diameter: { - if (!noRepeat && pow) + get: function () { - wrapping = gl.REPEAT; - } + return this._diameter; + }, - if (this.config.antialias) + set: function (value) { - minFilter = (pow) ? this.mipmapFilter : gl.LINEAR; - magFilter = gl.LINEAR; + this._diameter = value; + this._radius = value * 0.5; } - return this.createTexture2D(0, minFilter, magFilter, wrapping, wrapping, gl.RGBA, srcVideo, width, height, true, true, flipY); }, /** - * Updates a WebGL Texture based on the given HTML Video Element. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#updateVideoTexture - * @since 3.20.0 - * - * @param {HTMLVideoElement} srcVideo - The Video to update the WebGL Texture with. - * @param {WebGLTexture} dstTexture - The destination WebGL Texture to update. - * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? + * The left position of the Circle. * - * @return {WebGLTexture} The updated WebGL Texture. + * @name Phaser.Geom.Circle#left + * @type {number} + * @since 3.0.0 */ - updateVideoTexture: function (srcVideo, dstTexture, flipY) - { - if (flipY === undefined) { flipY = false; } - - var gl = this.gl; - - var width = srcVideo.videoWidth; - var height = srcVideo.videoHeight; + left: { - if (width > 0 && height > 0) + get: function () { - gl.activeTexture(gl.TEXTURE0); - var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D); - gl.bindTexture(gl.TEXTURE_2D, dstTexture); - - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); - - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, srcVideo); - - dstTexture.width = width; - dstTexture.height = height; + return this.x - this._radius; + }, - if (currentTexture) - { - gl.bindTexture(gl.TEXTURE_2D, currentTexture); - } + set: function (value) + { + this.x = value + this._radius; } - return dstTexture; }, /** - * Sets the minification and magnification filter for a texture. + * The right position of the Circle. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#setTextureFilter + * @name Phaser.Geom.Circle#right + * @type {number} * @since 3.0.0 - * - * @param {number} texture - The texture to set the filter for. - * @param {number} filter - The filter to set. 0 for linear filtering, 1 for nearest neighbor (blocky) filtering. - * - * @return {this} This WebGL Renderer instance. */ - setTextureFilter: function (texture, filter) - { - var gl = this.gl; - var glFilter = [ gl.LINEAR, gl.NEAREST ][filter]; - - gl.activeTexture(gl.TEXTURE0); - - var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D); - - gl.bindTexture(gl.TEXTURE_2D, texture); + right: { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter); + get: function () + { + return this.x + this._radius; + }, - if (currentTexture) + set: function (value) { - gl.bindTexture(gl.TEXTURE_2D, currentTexture); + this.x = value - this._radius; } - return this; }, /** - * Returns the largest texture size (either width or height) that can be created. - * Note that VRAM may not allow a texture of any given size, it just expresses - * hardware / driver support for a given size. - * - * @method Phaser.Renderer.WebGL.WebGLRenderer#getMaxTextureSize - * @since 3.8.0 + * The top position of the Circle. * - * @return {number} The maximum supported texture size. + * @name Phaser.Geom.Circle#top + * @type {number} + * @since 3.0.0 */ - getMaxTextureSize: function () - { - return this.config.maxTextureSize; + top: { + + get: function () + { + return this.y - this._radius; + }, + + set: function (value) + { + this.y = value + this._radius; + } + }, /** - * Destroy this WebGLRenderer, cleaning up all related resources such as pipelines, native textures, etc. + * The bottom position of the Circle. * - * @method Phaser.Renderer.WebGL.WebGLRenderer#destroy + * @name Phaser.Geom.Circle#bottom + * @type {number} * @since 3.0.0 */ - destroy: function () - { - this.canvas.removeEventListener('webglcontextlost', this.contextLostHandler, false); - this.canvas.removeEventListener('webglcontextrestored', this.contextRestoredHandler, false); - - var gl = this.gl; + bottom: { - var temp = this.tempTextures; + get: function () + { + return this.y + this._radius; + }, - for (var i = 0; i < temp.length; i++) + set: function (value) { - gl.deleteTexture(temp[i]); + this.y = value - this._radius; } - this.pipelines.destroy(); - - this.removeAllListeners(); - - this.fboStack = []; - this.maskStack = []; - this.extensions = {}; - this.textureIndexes = []; - - this.gl = null; - this.game = null; - this.canvas = null; - this.contextLost = true; - this.currentMask = null; - this.currentCameraMask = null; } }); -module.exports = WebGLRenderer; +module.exports = Circle; /***/ }), -/* 372 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 37964: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(92); -var CustomMap = __webpack_require__(102); - -// Default Phaser 3 Pipelines -var BitmapMaskPipeline = __webpack_require__(373); -var GraphicsPipeline = __webpack_require__(376); -var LightPipeline = __webpack_require__(377); -var MultiPipeline = __webpack_require__(108); -var PointLightPipeline = __webpack_require__(378); -var RopePipeline = __webpack_require__(379); -var SinglePipeline = __webpack_require__(380); -var UtilityPipeline = __webpack_require__(381); - /** - * @classdesc - * The Pipeline Manager is responsible for the creation, activation, running and destruction - * of WebGL Pipelines and Post FX Pipelines in Phaser 3. - * - * The `WebGLRenderer` owns a single instance of the Pipeline Manager, which you can access - * via the `WebGLRenderer.pipelines` property. - * - * By default, there are 8 pipelines installed into the Pipeline Manager when Phaser boots: - * - * 1. The Multi Pipeline. Responsible for all multi-texture rendering, i.e. Sprites and Tilemaps. - * 2. The Graphics Pipeline. Responsible for rendering Graphics and Shape objects. - * 3. The Rope Pipeline. Responsible for rendering the Rope Game Object. - * 4. The Light Pipeline. Responsible for rendering the Light Game Object. - * 5. The Point Light Pipeline. Responsible for rendering the Point Light Game Object. - * 6. The Single Pipeline. Responsible for rendering Game Objects that explicitly require one bound texture. - * 7. The Bitmap Mask Pipeline. Responsible for Bitmap Mask rendering. - * 8. The Utility Pipeline. Responsible for providing lots of handy texture manipulation functions. + * Returns the circumference of the given Circle. * - * You can add your own custom pipeline via the `PipelineManager.add` method. Pipelines are - * identified by unique string-based keys. + * @function Phaser.Geom.Circle.Circumference + * @since 3.0.0 * - * @class PipelineManager - * @memberof Phaser.Renderer.WebGL - * @constructor - * @since 3.50.0 + * @param {Phaser.Geom.Circle} circle - The Circle to get the circumference of. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the WebGL Renderer that owns this Pipeline Manager. + * @return {number} The circumference of the Circle. */ -var PipelineManager = new Class({ +var Circumference = function (circle) +{ + return 2 * (Math.PI * circle.radius); +}; - initialize: +module.exports = Circumference; - function PipelineManager (renderer) - { - /** - * A reference to the Game instance. - * - * @name Phaser.Renderer.WebGL.PipelineManager#game - * @type {Phaser.Game} - * @since 3.50.0 - */ - this.game = renderer.game; - /** - * A reference to the WebGL Renderer instance. - * - * @name Phaser.Renderer.WebGL.PipelineManager#renderer - * @type {Phaser.Renderer.WebGL.WebGLRenderer} - * @since 3.50.0 - */ - this.renderer = renderer; +/***/ }), - /** - * This map stores all pipeline classes available in this manager. - * - * The Utility Class must always come first. - * - * @name Phaser.Renderer.WebGL.PipelineManager#classes - * @type {Phaser.Structs.Map.} - * @since 3.50.0 - */ - this.classes = new CustomMap([ - [ CONST.UTILITY_PIPELINE, UtilityPipeline ], - [ CONST.MULTI_PIPELINE, MultiPipeline ], - [ CONST.BITMAPMASK_PIPELINE, BitmapMaskPipeline ], - [ CONST.SINGLE_PIPELINE, SinglePipeline ], - [ CONST.ROPE_PIPELINE, RopePipeline ], - [ CONST.LIGHT_PIPELINE, LightPipeline ], - [ CONST.POINTLIGHT_PIPELINE, PointLightPipeline ], - [ CONST.GRAPHICS_PIPELINE, GraphicsPipeline ] - ]); +/***/ 72233: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * This map stores all Post FX Pipeline classes available in this manager. - * - * @name Phaser.Renderer.WebGL.PipelineManager#postPipelineClasses - * @type {Phaser.Structs.Map.} - * @since 3.50.0 - */ - this.postPipelineClasses = new CustomMap(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * This map stores all pipeline instances in this manager. - * - * This is populated with the default pipelines in the `boot` method. - * - * @name Phaser.Renderer.WebGL.PipelineManager#pipelines - * @type {Phaser.Structs.Map.} - * @since 3.50.0 - */ - this.pipelines = new CustomMap(); +var Point = __webpack_require__(79967); - /** - * Current pipeline in use by the WebGLRenderer. - * - * @name Phaser.Renderer.WebGL.PipelineManager#current - * @type {Phaser.Renderer.WebGL.WebGLPipeline} - * @default null - * @since 3.50.0 - */ - this.current = null; +/** + * Returns a Point object containing the coordinates of a point on the circumference of the Circle based on the given angle. + * + * @function Phaser.Geom.Circle.CircumferencePoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Circle} circle - The Circle to get the circumference point on. + * @param {number} angle - The angle from the center of the Circle to the circumference to return the point from. Given in radians. + * @param {(Phaser.Geom.Point|object)} [out] - A Point, or point-like object, to store the results in. If not given a Point will be created. + * + * @return {(Phaser.Geom.Point|object)} A Point object where the `x` and `y` properties are the point on the circumference. + */ +var CircumferencePoint = function (circle, angle, out) +{ + if (out === undefined) { out = new Point(); } - /** - * The previous WebGLPipeline that was in use. - * - * This is set when `clearPipeline` is called and restored in `rebindPipeline` if none is given. - * - * @name Phaser.Renderer.WebGL.PipelineManager#previous - * @type {Phaser.Renderer.WebGL.WebGLPipeline} - * @default null - * @since 3.50.0 - */ - this.previous = null; + out.x = circle.x + (circle.radius * Math.cos(angle)); + out.y = circle.y + (circle.radius * Math.sin(angle)); - /** - * A constant-style reference to the Multi Pipeline Instance. - * - * This is the default Phaser 3 pipeline and is used by the WebGL Renderer to manage - * camera effects and more. This property is set during the `boot` method. - * - * @name Phaser.Renderer.WebGL.PipelineManager#MULTI_PIPELINE - * @type {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} - * @default null - * @since 3.50.0 - */ - this.MULTI_PIPELINE = null; + return out; +}; - /** - * A constant-style reference to the Bitmap Mask Pipeline Instance. - * - * This is the default Phaser 3 mask pipeline and is used Game Objects using - * a Bitmap Mask. This property is set during the `boot` method. - * - * @name Phaser.Renderer.WebGL.PipelineManager#BITMAPMASK_PIPELINE - * @type {Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline} - * @default null - * @since 3.50.0 - */ - this.BITMAPMASK_PIPELINE = null; +module.exports = CircumferencePoint; - /** - * A constant-style reference to the Utility Pipeline Instance. - * - * @name Phaser.Renderer.WebGL.PipelineManager#UTILITY_PIPELINE - * @type {Phaser.Renderer.WebGL.Pipelines.UtilityPipeline} - * @default null - * @since 3.50.0 - */ - this.UTILITY_PIPELINE = null; - /** - * 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.PipelineManager#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.PipelineManager#fullFrame2 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 - */ - this.fullFrame2; +/***/ 61761: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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.PipelineManager#halfFrame1 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 - */ - this.halfFrame1; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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.PipelineManager#halfFrame2 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 - */ - this.halfFrame2; - }, +var Circle = __webpack_require__(26673); - /** - * Internal boot handler, called by the WebGLRenderer durings its boot process. - * - * Adds all of the default pipelines, based on the game config, and then calls - * the `boot` method on each one of them. - * - * Finally, the default pipeline is set. - * - * @method Phaser.Renderer.WebGL.PipelineManager#boot - * @since 3.50.0 - * - * @param {Phaser.Types.Core.PipelineConfig} [pipelineConfig] - The pipeline configuration object as set in the Game Config. - */ - boot: function (pipelineConfig) - { - // Install each of the default pipelines +/** + * Creates a new Circle instance based on the values contained in the given source. + * + * @function Phaser.Geom.Circle.Clone + * @since 3.0.0 + * + * @param {(Phaser.Geom.Circle|object)} source - The Circle to be cloned. Can be an instance of a Circle or a circle-like object, with x, y and radius properties. + * + * @return {Phaser.Geom.Circle} A clone of the source Circle. + */ +var Clone = function (source) +{ + return new Circle(source.x, source.y, source.radius); +}; - var instance; - var pipelineName; +module.exports = Clone; - var _this = this; - var game = this.game; - this.classes.each(function (pipelineName, pipeline) - { - instance = _this.add(pipelineName, new pipeline({ game: game })); +/***/ }), - if (pipelineName === CONST.UTILITY_PIPELINE) - { - _this.UTILITY_PIPELINE = instance; +/***/ 65650: +/***/ ((module) => { - // FBO references - _this.fullFrame1 = instance.fullFrame1; - _this.fullFrame2 = instance.fullFrame2; - _this.halfFrame1 = instance.halfFrame1; - _this.halfFrame2 = instance.halfFrame2; - } - }); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Our const-like references - this.MULTI_PIPELINE = this.get(CONST.MULTI_PIPELINE); - this.BITMAPMASK_PIPELINE = this.get(CONST.BITMAPMASK_PIPELINE); +/** + * 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); - // And now the ones in the config, if any + return (dx + dy) <= (circle.radius * circle.radius); + } + else + { + return false; + } +}; - if (pipelineConfig) - { - for (pipelineName in pipelineConfig) - { - var pipelineClass = pipelineConfig[pipelineName]; +module.exports = Contains; - instance = new pipelineClass(game); - if (instance.isPostFX) - { - this.postPipelineClasses.set(pipelineName, pipelineClass); - } - else if (!this.has(pipelineName)) - { - this.classes.set(pipelineName, pipelineClass); +/***/ }), - this.add(pipelineName, instance); - } - } - } - }, +/***/ 39187: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Adds a pipeline instance to this Pipeline Manager. - * - * The name of the instance must be unique within this manager. - * - * Make sure to pass an instance to this method, not a base class. - * - * For example, you should pass it like this: - * - * ```javascript - * this.add('yourName', new CustomPipeline());` - * ``` - * - * and **not** like this: - * - * ```javascript - * this.add('yourName', CustomPipeline);` - * ``` - * - * To add a **Post Pipeline**, see `addPostPipeline` instead. - * - * @method Phaser.Renderer.WebGL.PipelineManager#add - * @since 3.50.0 - * - * @param {string} name - A unique string-based key for the pipeline within the manager. - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - A pipeline _instance_ which must extend `WebGLPipeline`. - * - * @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance that was passed. - */ - add: function (name, pipeline) - { - if (pipeline.isPostFX) - { - console.warn(name + ' is a Post Pipeline. Use `addPostPipeline` instead'); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return; - } +var Contains = __webpack_require__(65650); - var pipelines = this.pipelines; - var renderer = this.renderer; +/** + * Check to see if the Circle contains the given Point object. + * + * @function Phaser.Geom.Circle.ContainsPoint + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The Circle to check. + * @param {(Phaser.Geom.Point|object)} point - The Point object to check if it's within the Circle or not. + * + * @return {boolean} True if the Point coordinates are within the circle, otherwise false. + */ +var ContainsPoint = function (circle, point) +{ + return Contains(circle, point.x, point.y); +}; - if (!pipelines.has(name)) - { - pipeline.name = name; - pipeline.manager = this; +module.exports = ContainsPoint; - pipelines.set(name, pipeline); - } - else - { - console.warn('Pipeline exists: ' + name); - } - if (!pipeline.hasBooted) - { - pipeline.boot(); - } +/***/ }), - if (renderer.width !== 0 && renderer.height !== 0) - { - pipeline.resize(renderer.width, renderer.height); - } +/***/ 58672: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return pipeline; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Adds a Post Pipeline to this Pipeline Manager. - * - * Make sure to pass a base class to this method, not an instance. - * - * For example, you should pass it like this: - * - * ```javascript - * this.addPostPipeline('yourName', CustomPipeline);` - * ``` - * - * and **not** like this: - * - * ```javascript - * this.addPostPipeline('yourName', new CustomPipeline());` - * ``` - * - * To add a regular pipeline, see the `add` method instead. - * - * @method Phaser.Renderer.WebGL.PipelineManager#addPostPipeline - * @since 3.50.0 - * - * @param {string} name - A unique string-based key for the pipeline within the manager. - * @param {function} pipeline - A pipeline class which must extend `PostFXPipeline`. - * - * @return {this} This Pipeline Manager. - */ - addPostPipeline: function (name, pipeline) - { - if (!this.postPipelineClasses.has(name)) - { - this.postPipelineClasses.set(name, pipeline); - } - }, +var Contains = __webpack_require__(65650); - /** - * Flushes the current pipeline, if one is bound. - * - * @method Phaser.Renderer.WebGL.PipelineManager#flush - * @since 3.50.0 - */ - flush: function () - { - if (this.current) - { - this.current.flush(); - } - }, +/** + * Check to see if the Circle contains all four points of the given Rectangle object. + * + * @function Phaser.Geom.Circle.ContainsRect + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The Circle to check. + * @param {(Phaser.Geom.Rectangle|object)} rect - The Rectangle object to check if it's within the Circle or not. + * + * @return {boolean} True if all of the Rectangle coordinates are within the circle, otherwise false. + */ +var ContainsRect = function (circle, rect) +{ + return ( + Contains(circle, rect.x, rect.y) && + Contains(circle, rect.right, rect.y) && + Contains(circle, rect.x, rect.bottom) && + Contains(circle, rect.right, rect.bottom) + ); +}; - /** - * Checks if a pipeline is present in this Pipeline Manager. - * - * @method Phaser.Renderer.WebGL.PipelineManager#has - * @since 3.50.0 - * - * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up. - * - * @return {boolean} `true` if the given pipeline is loaded, otherwise `false`. - */ - has: function (pipeline) - { - var pipelines = this.pipelines; +module.exports = ContainsRect; - if (typeof pipeline === 'string') - { - return pipelines.has(pipeline); - } - else if (pipelines.contains(pipeline)) - { - return true; - } - return false; - }, +/***/ }), - /** - * Returns the pipeline instance based on the given name, or instance. - * - * If no instance, or matching name, exists in this manager, it returns `undefined`. - * - * @method Phaser.Renderer.WebGL.PipelineManager#get - * @since 3.50.0 - * - * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up. - * - * @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance, or `undefined` if not found. - */ - get: function (pipeline) - { - var pipelines = this.pipelines; +/***/ 42997: +/***/ ((module) => { - if (typeof pipeline === 'string') - { - return pipelines.get(pipeline); - } - else if (pipelines.contains(pipeline)) - { - return pipeline; - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Returns a _new instance_ of the post pipeline based on the given name, or class. - * - * If no instance, or matching name, exists in this manager, it returns `undefined`. - * - * @method Phaser.Renderer.WebGL.PipelineManager#getPostPipeline - * @since 3.50.0 - * - * @param {(string|function|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance, or class to look-up. - * @param {Phaser.GameObjects.GameObject} [gameObject] - If this post pipeline is being installed into a Game Object or Camera, this is a reference to it. - * - * @return {Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} The pipeline instance, or `undefined` if not found. - */ - getPostPipeline: function (pipeline, gameObject) - { - var pipelineClasses = this.postPipelineClasses; +/** + * Copies the `x`, `y` and `radius` properties from the `source` Circle + * into the given `dest` Circle, then returns the `dest` Circle. + * + * @function Phaser.Geom.Circle.CopyFrom + * @since 3.0.0 + * + * @generic {Phaser.Geom.Circle} O - [dest,$return] + * + * @param {Phaser.Geom.Circle} source - The source Circle to copy the values from. + * @param {Phaser.Geom.Circle} dest - The destination Circle to copy the values to. + * + * @return {Phaser.Geom.Circle} The destination Circle. + */ +var CopyFrom = function (source, dest) +{ + return dest.setTo(source.x, source.y, source.radius); +}; - var instance; +module.exports = CopyFrom; - if (typeof pipeline === 'string') - { - instance = pipelineClasses.get(pipeline); - } - else if (typeof pipeline === 'function') - { - // A class - if (pipelineClasses.contains(pipeline)) - { - instance = pipeline; - } - } - else if (typeof pipeline === 'object') - { - // Instance - instance = pipelineClasses.get(pipeline.name); - } - if (instance) - { - var newPipeline = new instance(this.game); +/***/ }), - if (gameObject) - { - newPipeline.gameObject = gameObject; - } +/***/ 94894: +/***/ ((module) => { - return newPipeline; - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Removes a pipeline instance based on the given name. - * - * If no pipeline matches the name, this method does nothing. - * - * Note that the pipeline will not be flushed or destroyed, it's simply removed from - * this manager. - * - * @method Phaser.Renderer.WebGL.PipelineManager#remove - * @since 3.50.0 - * - * @param {string} name - The name of the pipeline to be removed. - * @param {boolean} [removeClass=true] - Remove the pipeline class as well as the instance? - * @param {boolean} [removePostPipelineClass=true] - Remove the post pipeline class as well as the instance? - */ - remove: function (name, removeClass, removePostPipelineClass) - { - if (removeClass === undefined) { removeClass = true; } - if (removePostPipelineClass === undefined) { removePostPipelineClass = true; } +/** + * Compares the `x`, `y` and `radius` properties of the two given Circles. + * Returns `true` if they all match, otherwise returns `false`. + * + * @function Phaser.Geom.Circle.Equals + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The first Circle to compare. + * @param {Phaser.Geom.Circle} toCompare - The second Circle to compare. + * + * @return {boolean} `true` if the two Circles equal each other, otherwise `false`. + */ +var Equals = function (circle, toCompare) +{ + return ( + circle.x === toCompare.x && + circle.y === toCompare.y && + circle.radius === toCompare.radius + ); +}; - this.pipelines.delete(name); +module.exports = Equals; - if (removeClass) - { - this.classes.delete(name); - } - if (removePostPipelineClass) - { - this.postPipelineClasses.delete(name); - } - }, +/***/ }), - /** - * Sets the current pipeline to be used by the `WebGLRenderer`. - * - * This method accepts a pipeline instance as its parameter, not the name. - * - * If the pipeline isn't already the current one it will call `WebGLPipeline.bind` and then `onBind`. - * - * You cannot set Post FX Pipelines using this method. To use a Post FX Pipeline, you should - * apply it to either a Camera, Container or other supporting Game Object. - * - * @method Phaser.Renderer.WebGL.PipelineManager#set - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline instance to be set as current. - * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. - * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. - * - * @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline that was set, or undefined if it couldn't be set. - */ - set: function (pipeline, gameObject, currentShader) - { - if (pipeline.isPostFX) - { - return; - } +/***/ 48027: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!this.isCurrent(pipeline, currentShader)) - { - this.flush(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (this.current) - { - this.current.unbind(); - } +var Rectangle = __webpack_require__(74118); - this.current = pipeline; +/** + * Returns the bounds of the Circle object. + * + * @function Phaser.Geom.Circle.GetBounds + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * + * @param {Phaser.Geom.Circle} circle - The Circle to get the bounds from. + * @param {(Phaser.Geom.Rectangle|object)} [out] - A Rectangle, or rectangle-like object, to store the circle bounds in. If not given a new Rectangle will be created. + * + * @return {(Phaser.Geom.Rectangle|object)} The Rectangle object containing the Circles bounds. + */ +var GetBounds = function (circle, out) +{ + if (out === undefined) { out = new Rectangle(); } - pipeline.bind(currentShader); - } + out.x = circle.left; + out.y = circle.top; + out.width = circle.diameter; + out.height = circle.diameter; - pipeline.updateProjectionMatrix(); + return out; +}; - pipeline.onBind(gameObject); +module.exports = GetBounds; - return pipeline; - }, - /** - * This method is called by the `WebGLPipeline.batchQuad` method, right before a quad - * belonging to a Game Object is about to be added to the batch. It causes a batch - * flush, then calls the `preBatch` method on the post-fx pipelines belonging to the - * Game Object. - * - * @method Phaser.Renderer.WebGL.PipelineManager#preBatch - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object about to be batched. - */ - preBatch: function (gameObject) - { - if (gameObject.hasPostPipeline) - { - this.flush(); +/***/ }), - var pipelines = gameObject.postPipelines; +/***/ 94026: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Iterate in reverse because we need them stacked in the order they're in the array - for (var i = pipelines.length - 1; i >= 0; i--) - { - var pipeline = pipelines[i]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (pipeline.active) - { - pipeline.preBatch(gameObject); - } - } - } - }, +var CircumferencePoint = __webpack_require__(72233); +var FromPercent = __webpack_require__(91806); +var MATH_CONST = __webpack_require__(83392); +var Point = __webpack_require__(79967); - /** - * This method is called by the `WebGLPipeline.batchQuad` method, right after a quad - * belonging to a Game Object has been added to the batch. It causes a batch - * flush, then calls the `postBatch` method on the post-fx pipelines belonging to the - * Game Object. - * - * @method Phaser.Renderer.WebGL.PipelineManager#postBatch - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to the batch. - */ - postBatch: function (gameObject) - { - if (gameObject.hasPostPipeline) - { - this.flush(); +/** + * 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. + * + * @function Phaser.Geom.Circle.GetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Circle} circle - The Circle 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 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. + */ +var GetPoint = function (circle, position, out) +{ + if (out === undefined) { out = new Point(); } - var pipelines = gameObject.postPipelines; + var angle = FromPercent(position, 0, MATH_CONST.PI2); - for (var i = 0; i < pipelines.length; i++) - { - var pipeline = pipelines[i]; + return CircumferencePoint(circle, angle, out); +}; - if (pipeline.active) - { - pipeline.postBatch(gameObject); - } - } - } - }, +module.exports = GetPoint; - /** - * Called at the start of the `WebGLRenderer.preRenderCamera` method. - * - * If the Camera has post pipelines set, it will flush the batch and then call the - * `preBatch` method on the post-fx pipelines belonging to the Camera. - * - * @method Phaser.Renderer.WebGL.PipelineManager#preBatchCamera - * @since 3.50.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera about to be rendered. - */ - preBatchCamera: function (camera) - { - if (camera.hasPostPipeline) - { - this.flush(); - var pipelines = camera.postPipelines; +/***/ }), - // Iterate in reverse because we need them stacked in the order they're in the array - for (var i = pipelines.length - 1; i >= 0; i--) - { - var pipeline = pipelines[i]; +/***/ 62941: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (pipeline.active) - { - pipeline.preBatch(camera); - } - } - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Called at the end of the `WebGLRenderer.postRenderCamera` method. - * - * If the Camera has post pipelines set, it will flush the batch and then call the - * `postBatch` method on the post-fx pipelines belonging to the Camera. - * - * @method Phaser.Renderer.WebGL.PipelineManager#postBatchCamera - * @since 3.50.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that was just rendered. - */ - postBatchCamera: function (camera) +var Circumference = __webpack_require__(37964); +var CircumferencePoint = __webpack_require__(72233); +var FromPercent = __webpack_require__(91806); +var MATH_CONST = __webpack_require__(83392); + +/** + * 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. + * + * @function Phaser.Geom.Circle.GetPoints + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The Circle 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 circle 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 circumference of the circle. + */ +var GetPoints = function (circle, 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) { - if (camera.hasPostPipeline) - { - this.flush(); + quantity = Circumference(circle) / stepRate; + } - var pipelines = camera.postPipelines; + for (var i = 0; i < quantity; i++) + { + var angle = FromPercent(i / quantity, 0, MATH_CONST.PI2); - for (var i = 0; i < pipelines.length; i++) - { - var pipeline = pipelines[i]; + out.push(CircumferencePoint(circle, angle)); + } - if (pipeline.active) - { - pipeline.postBatch(camera); - } - } - } - }, + return out; +}; - /** - * Checks to see if the given pipeline is already the active pipeline, both within this - * Pipeline Manager and also has the same shader set in the Renderer. - * - * @method Phaser.Renderer.WebGL.PipelineManager#isCurrent - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline instance to be checked. - * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. - * - * @return {boolean} `true` if the given pipeline is already the current pipeline, otherwise `false`. - */ - isCurrent: function (pipeline, currentShader) - { - var renderer = this.renderer; - var current = this.current; +module.exports = GetPoints; - if (current && !currentShader) - { - currentShader = current.currentShader; - } - return !(current !== pipeline || currentShader.program !== renderer.currentProgram); - }, +/***/ }), - /** - * 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. - * - * The copy itself is handled by the Utility Pipeline. - * - * @method Phaser.Renderer.WebGL.PipelineManager#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? - * - * @return {this} This Pipeline Manager instance. - */ - copyFrame: function (source, target, brightness, clear, clearAlpha) - { - this.setUtility(this.UTILITY_PIPELINE.copyShader).copyFrame(source, target, brightness, clear, clearAlpha); +/***/ 34585: +/***/ ((module) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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.PipelineManager#copyToGame - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. - */ - copyToGame: function (source) - { - this.setUtility(this.UTILITY_PIPELINE.copyShader).copyToGame(source); +/** + * Offsets the Circle by the values given. + * + * @function Phaser.Geom.Circle.Offset + * @since 3.0.0 + * + * @generic {Phaser.Geom.Circle} O - [circle,$return] + * + * @param {Phaser.Geom.Circle} circle - The Circle to be offset (translated.) + * @param {number} x - The amount to horizontally offset the Circle by. + * @param {number} y - The amount to vertically offset the Circle by. + * + * @return {Phaser.Geom.Circle} The Circle that was offset. + */ +var Offset = function (circle, x, y) +{ + circle.x += x; + circle.y += y; - return this; - }, + return circle; +}; - /** - * 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. - * - * The copy itself is handled by the Utility Pipeline. - * - * @method Phaser.Renderer.WebGL.PipelineManager#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? - * @param {Phaser.Display.ColorMatrix} [colorMatrix] - The Color Matrix to use when performing the draw. - * - * @return {this} This Pipeline Manager instance. - */ - drawFrame: function (source, target, clearAlpha, colorMatrix) - { - this.setUtility(this.UTILITY_PIPELINE.colorMatrixShader).drawFrame(source, target, clearAlpha, colorMatrix); +module.exports = Offset; - return this; - }, - /** - * Draws the `source1` and `source2` Render Targets to the `target` Render Target - * using a linear blend effect, which is controlled by the `strength` parameter. - * - * The draw itself is handled by the Utility Pipeline. - * - * @method Phaser.Renderer.WebGL.PipelineManager#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? - * - * @return {this} This Pipeline Manager instance. - */ - blendFrames: function (source1, source2, target, strength, clearAlpha) - { - this.setUtility(this.UTILITY_PIPELINE.linearShader).blendFrames(source1, source2, target, strength, clearAlpha); +/***/ }), - return this; - }, +/***/ 88665: +/***/ ((module) => { - /** - * Draws the `source1` and `source2` Render Targets to the `target` Render Target - * using an additive blend effect, which is controlled by the `strength` parameter. - * - * The draw itself is handled by the Utility Pipeline. - * - * @method Phaser.Renderer.WebGL.PipelineManager#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? - * - * @return {this} This Pipeline Manager instance. - */ - blendFramesAdditive: function (source1, source2, target, strength, clearAlpha) - { - this.setUtility(this.UTILITY_PIPELINE.addShader).blendFramesAdditive(source1, source2, target, strength, clearAlpha); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Offsets the Circle by the values given in the `x` and `y` properties of the Point object. + * + * @function Phaser.Geom.Circle.OffsetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Circle} O - [circle,$return] + * + * @param {Phaser.Geom.Circle} circle - The Circle to be offset (translated.) + * @param {(Phaser.Geom.Point|object)} point - The Point object containing the values to offset the Circle by. + * + * @return {Phaser.Geom.Circle} The Circle that was offset. + */ +var OffsetPoint = function (circle, point) +{ + circle.x += point.x; + circle.y += point.y; + + return circle; +}; + +module.exports = OffsetPoint; + + +/***/ }), + +/***/ 30977: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(79967); + +/** + * Returns a uniformly distributed random point from anywhere within the given Circle. + * + * @function Phaser.Geom.Circle.Random + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Circle} circle - The Circle to get a random point from. + * @param {(Phaser.Geom.Point|object)} [out] - 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. + */ +var Random = function (circle, out) +{ + if (out === undefined) { out = new Point(); } + + var t = 2 * Math.PI * Math.random(); + var u = Math.random() + Math.random(); + var r = (u > 1) ? 2 - u : u; + var x = r * Math.cos(t); + var y = r * Math.sin(t); + + out.x = circle.x + (x * circle.radius); + out.y = circle.y + (y * circle.radius); + + return out; +}; + +module.exports = Random; + + +/***/ }), + +/***/ 6112: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Circle = __webpack_require__(26673); + +Circle.Area = __webpack_require__(95847); +Circle.Circumference = __webpack_require__(37964); +Circle.CircumferencePoint = __webpack_require__(72233); +Circle.Clone = __webpack_require__(61761); +Circle.Contains = __webpack_require__(65650); +Circle.ContainsPoint = __webpack_require__(39187); +Circle.ContainsRect = __webpack_require__(58672); +Circle.CopyFrom = __webpack_require__(42997); +Circle.Equals = __webpack_require__(94894); +Circle.GetBounds = __webpack_require__(48027); +Circle.GetPoint = __webpack_require__(94026); +Circle.GetPoints = __webpack_require__(62941); +Circle.Offset = __webpack_require__(34585); +Circle.OffsetPoint = __webpack_require__(88665); +Circle.Random = __webpack_require__(30977); + +module.exports = Circle; - return this; - }, + +/***/ }), + +/***/ 52394: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GEOM_CONST = { /** - * Clears the given Render Target. - * - * @method Phaser.Renderer.WebGL.PipelineManager#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? + * A Circle Geometry object type. * - * @return {this} This Pipeline Manager instance. + * @name Phaser.Geom.CIRCLE + * @type {number} + * @since 3.19.0 */ - clearFrame: function (target, clearAlpha) - { - this.UTILITY_PIPELINE.clearFrame(target, clearAlpha); - - return this; - }, + CIRCLE: 0, /** - * 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.PipelineManager#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? + * An Ellipse Geometry object type. * - * @return {this} This Pipeline Manager instance. + * @name Phaser.Geom.ELLIPSE + * @type {number} + * @since 3.19.0 */ - blitFrame: function (source, target, brightness, clear, clearAlpha, eraseMode) - { - this.setUtility(this.UTILITY_PIPELINE.copyShader).blitFrame(source, target, brightness, clear, clearAlpha, eraseMode); - - return this; - }, + ELLIPSE: 1, /** - * 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.PipelineManager#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? + * A Line Geometry object type. * - * @return {this} This Pipeline Manager instance. + * @name Phaser.Geom.LINE + * @type {number} + * @since 3.19.0 */ - copyFrameRect: function (source, target, x, y, width, height, clear, clearAlpha) - { - this.UTILITY_PIPELINE.copyFrameRect(source, target, x, y, width, height, clear, clearAlpha); - - return this; - }, + LINE: 2, /** - * Returns `true` if the current pipeline is forced to use texture unit zero. - * - * @method Phaser.Renderer.WebGL.PipelineManager#forceZero - * @since 3.50.0 + * A Point Geometry object type. * - * @return {boolean} `true` if the current pipeline is forced to use texture unit zero. + * @name Phaser.Geom.POINT + * @type {number} + * @since 3.19.0 */ - forceZero: function () - { - return (this.current && this.current.forceZero); - }, + POINT: 3, /** - * Sets the Multi Pipeline to be the currently bound pipeline. - * - * This is the default Phaser 3 rendering pipeline. - * - * @method Phaser.Renderer.WebGL.PipelineManager#setMulti - * @since 3.50.0 + * A Polygon Geometry object type. * - * @return {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} The Multi Pipeline instance. + * @name Phaser.Geom.POLYGON + * @type {number} + * @since 3.19.0 */ - setMulti: function () - { - return this.set(this.MULTI_PIPELINE); - }, + POLYGON: 4, /** - * Sets the Utility Pipeline to be the currently bound pipeline. - * - * @method Phaser.Renderer.WebGL.PipelineManager#setUtility - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. + * A Rectangle Geometry object type. * - * @return {Phaser.Renderer.WebGL.Pipelines.UtilityPipeline} The Utility Pipeline instance. + * @name Phaser.Geom.RECTANGLE + * @type {number} + * @since 3.19.0 */ - setUtility: function (currentShader) - { - return this.UTILITY_PIPELINE.bind(currentShader); - }, + RECTANGLE: 5, /** - * Use this to reset the gl context to the state that Phaser requires to continue rendering. - * - * Calling this will: - * - * * Disable `DEPTH_TEST`, `CULL_FACE` and `STENCIL_TEST`. - * * Clear the depth buffer and stencil buffers. - * * Reset the viewport size. - * * Reset the blend mode. - * * Bind a blank texture as the active texture on texture unit zero. - * * Rebinds the given pipeline instance. - * - * You should call this if you have previously called `clear`, and then wish to return - * rendering control to Phaser again. - * - * @method Phaser.Renderer.WebGL.PipelineManager#rebind - * @since 3.50.0 + * A Triangle Geometry object type. * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} [pipeline] - The pipeline instance to be rebound. If not given, the previous pipeline will be bound. + * @name Phaser.Geom.TRIANGLE + * @type {number} + * @since 3.19.0 */ - rebind: function (pipeline) - { - if (pipeline === undefined && this.previous) - { - pipeline = this.previous; - } + TRIANGLE: 6 - var renderer = this.renderer; - var gl = renderer.gl; +}; - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.CULL_FACE); +module.exports = GEOM_CONST; - if (renderer.hasActiveStencilMask()) - { - gl.clear(gl.DEPTH_BUFFER_BIT); - } - else - { - // If there wasn't a stencil mask set before this call, we can disable it safely - gl.disable(gl.STENCIL_TEST); - gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); - } - gl.viewport(0, 0, renderer.width, renderer.height); +/***/ }), - renderer.currentProgram = null; +/***/ 58605: +/***/ ((module) => { - renderer.setBlendMode(0, true); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var entries = this.pipelines.entries; +/** + * Calculates the area of the Ellipse. + * + * @function Phaser.Geom.Ellipse.Area + * @since 3.0.0 + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the area of. + * + * @return {number} The area of the Ellipse. + */ +var Area = function (ellipse) +{ + if (ellipse.isEmpty()) + { + return 0; + } - for (var key in entries) - { - entries[key].glReset = true; - } + // units squared + return (ellipse.getMajorRadius() * ellipse.getMinorRadius() * Math.PI); +}; - if (pipeline) - { - this.current = pipeline; +module.exports = Area; - pipeline.rebind(); - } - renderer.resetTextures(); - }, +/***/ }), - /** - * Flushes the current pipeline being used and then clears it, along with the - * the current shader program and vertex buffer from the `WebGLRenderer`. - * - * Then resets the blend mode to NORMAL. - * - * Call this before jumping to your own gl context handler, and then call `rebind` when - * you wish to return control to Phaser again. - * - * @method Phaser.Renderer.WebGL.PipelineManager#clear - * @since 3.50.0 - */ - clear: function () - { - var renderer = this.renderer; - - this.flush(); - - if (this.current) - { - this.current.unbind(); - this.previous = this.current; - this.current = null; - } - else - { - this.previous = null; - } - - renderer.currentProgram = null; - - renderer.setBlendMode(0, true); - }, - - /** - * Destroy the Pipeline Manager, cleaning up all related resources and references. - * - * @method Phaser.Renderer.WebGL.PipelineManager#destroy - * @since 3.50.0 - */ - destroy: function () - { - this.flush(); +/***/ 39507: +/***/ ((module) => { - this.classes.clear(); - this.postPipelineClasses.clear(); - this.pipelines.clear(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.renderer = null; - this.game = null; - this.classes = null; - this.postPipelineClasses = null; - this.pipelines = null; - this.current = null; - this.previous = null; - } +/** + * 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 = PipelineManager; +module.exports = Circumference; /***/ }), -/* 373 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 86998: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(866); -var ShaderSourceVS = __webpack_require__(867); -var WEBGL_CONST = __webpack_require__(107); -var WebGLPipeline = __webpack_require__(58); +var Point = __webpack_require__(79967); /** - * @classdesc - * The Bitmap Mask Pipeline handles all of the bitmap mask rendering in WebGL for applying - * alpha masks to Game Objects. It works by sampling two texture on the fragment shader and - * using the fragments alpha to clip the region. - * - * The fragment shader it uses can be found in `shaders/src/BitmapMask.frag`. - * The vertex shader it uses can be found in `shaders/src/BitmapMask.vert`. - * - * The default shader attributes for this pipeline are: - * - * `inPosition` (vec2, offset 0) + * Returns a Point object containing the coordinates of a point on the circumference of the Ellipse based on the given angle. * - * The default shader uniforms for this pipeline are: + * @function Phaser.Geom.Ellipse.CircumferencePoint + * @since 3.0.0 * - * `uResolution` (vec2) - * `uMainSampler` (sampler2D) - * `uMaskSampler` (sampler2D) - * `uInvertMaskAlpha` (bool) + * @generic {Phaser.Geom.Point} O - [out,$return] * - * @class BitmapMaskPipeline - * @extends Phaser.Renderer.WebGL.WebGLPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.0.0 + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference point on. + * @param {number} angle - The angle from the center of the Ellipse to the circumference to return the point from. Given in radians. + * @param {(Phaser.Geom.Point|object)} [out] - A Point, or point-like object, to store the results in. If not given a Point will be created. * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + * @return {(Phaser.Geom.Point|object)} A Point object where the `x` and `y` properties are the point on the circumference. */ -var BitmapMaskPipeline = new Class({ +var CircumferencePoint = function (ellipse, angle, out) +{ + if (out === undefined) { out = new Point(); } - Extends: WebGLPipeline, + var halfWidth = ellipse.width / 2; + var halfHeight = ellipse.height / 2; - initialize: + out.x = ellipse.x + halfWidth * Math.cos(angle); + out.y = ellipse.y + halfHeight * Math.sin(angle); - function BitmapMaskPipeline (config) - { - config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS), - config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS), - config.batchSize = GetFastValue(config, 'batchSize', 1), - config.vertices = GetFastValue(config, 'vertices', [ -1, 1, -1, -7, 7, 1 ]), - config.attributes = GetFastValue(config, 'attributes', [ - { - name: 'inPosition', - size: 2, - type: WEBGL_CONST.FLOAT - } - ]); + return out; +}; - WebGLPipeline.call(this, config); - }, +module.exports = CircumferencePoint; - boot: function () - { - WebGLPipeline.prototype.boot.call(this); - this.set1i('uMainSampler', 0); - this.set1i('uMaskSampler', 1); - }, +/***/ }), - resize: function (width, height) - { - WebGLPipeline.prototype.resize.call(this, width, height); +/***/ 81773: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.set2f('uResolution', width, height); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Binds necessary resources and renders the mask to a separated framebuffer. - * The framebuffer for the masked object is also bound for further use. - * - * @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#beginMask - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} mask - GameObject used as mask. - * @param {Phaser.GameObjects.GameObject} maskedObject - GameObject masked by the mask GameObject. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the current mask. - */ - beginMask: function (mask, maskedObject, camera) - { - var gl = this.gl; +var Ellipse = __webpack_require__(95669); - // The renderable Game Object that is being used for the bitmap mask - if (mask.bitmapMask && gl) - { - var renderer = this.renderer; +/** + * Creates a new Ellipse instance based on the values contained in the given source. + * + * @function Phaser.Geom.Ellipse.Clone + * @since 3.0.0 + * + * @param {Phaser.Geom.Ellipse} source - The Ellipse to be cloned. Can be an instance of an Ellipse or a ellipse-like object, with x, y, width and height properties. + * + * @return {Phaser.Geom.Ellipse} A clone of the source Ellipse. + */ +var Clone = function (source) +{ + return new Ellipse(source.x, source.y, source.width, source.height); +}; - renderer.flush(); +module.exports = Clone; - renderer.pushFramebuffer(mask.mainFramebuffer); - gl.disable(gl.STENCIL_TEST); - gl.clearColor(0, 0, 0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); +/***/ }), - if (renderer.currentCameraMask.mask !== mask) - { - renderer.currentMask.mask = mask; - renderer.currentMask.camera = camera; - } - } - }, +/***/ 72313: +/***/ ((module) => { - /** - * The masked game objects framebuffer is unbound and its texture - * is bound together with the mask texture and the mask shader and - * a draw call with a single quad is processed. Here is where the - * masking effect is applied. - * - * @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#endMask - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} mask - GameObject used as a mask. - */ - endMask: function (mask, camera) - { - var gl = this.gl; - var renderer = this.renderer; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // The renderable Game Object that is being used for the bitmap mask - var bitmapMask = mask.bitmapMask; +/** + * Check to see if the Ellipse contains the given x / y coordinates. + * + * @function Phaser.Geom.Ellipse.Contains + * @since 3.0.0 + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to check. + * @param {number} x - The x coordinate to check within the ellipse. + * @param {number} y - The y coordinate to check within the ellipse. + * + * @return {boolean} True if the coordinates are within the ellipse, otherwise false. + */ +var Contains = function (ellipse, x, y) +{ + if (ellipse.width <= 0 || ellipse.height <= 0) + { + return false; + } - if (bitmapMask && gl) - { - // mask.mainFramebuffer should now contain all the Game Objects we want masked - renderer.flush(); + // Normalize the coords to an ellipse with center 0,0 and a radius of 0.5 + var normx = ((x - ellipse.x) / ellipse.width); + var normy = ((y - ellipse.y) / ellipse.height); - // Swap to the mask framebuffer (push, in case the bitmapMask GO has a post-pipeline) - renderer.pushFramebuffer(mask.maskFramebuffer); + normx *= normx; + normy *= normy; - // Clear it and draw the Game Object that is acting as a mask to it - gl.clearColor(0, 0, 0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); + return (normx + normy < 0.25); +}; - renderer.setBlendMode(0, true); +module.exports = Contains; - bitmapMask.renderWebGL(renderer, bitmapMask, camera); - renderer.flush(); +/***/ }), - // Clear the mask framebuffer + main framebuffer - renderer.popFramebuffer(); - renderer.popFramebuffer(); +/***/ 34368: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Is there a stencil further up the stack? - var prev = renderer.getCurrentStencilMask(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (prev) - { - gl.enable(gl.STENCIL_TEST); +var Contains = __webpack_require__(72313); - prev.mask.applyStencil(renderer, prev.camera, true); - } - else - { - renderer.currentMask.mask = null; - } +/** + * Check to see if the Ellipse contains the given Point object. + * + * @function Phaser.Geom.Ellipse.ContainsPoint + * @since 3.0.0 + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to check. + * @param {(Phaser.Geom.Point|object)} point - The Point object to check if it's within the Circle or not. + * + * @return {boolean} True if the Point coordinates are within the circle, otherwise false. + */ +var ContainsPoint = function (ellipse, point) +{ + return Contains(ellipse, point.x, point.y); +}; - // Bind this pipeline and draw - renderer.pipelines.set(this); +module.exports = ContainsPoint; - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, mask.maskTexture); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, mask.mainTexture); +/***/ }), - this.set1i('uInvertMaskAlpha', mask.invertAlpha); +/***/ 71431: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Finally, draw a triangle filling the whole screen - gl.drawArrays(this.topology, 0, 3); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - renderer.resetTextures(); - } - } +var Contains = __webpack_require__(72313); -}); +/** + * Check to see if the Ellipse contains all four points of the given Rectangle object. + * + * @function Phaser.Geom.Ellipse.ContainsRect + * @since 3.0.0 + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to check. + * @param {(Phaser.Geom.Rectangle|object)} rect - The Rectangle object to check if it's within the Ellipse or not. + * + * @return {boolean} True if all of the Rectangle coordinates are within the ellipse, otherwise false. + */ +var ContainsRect = function (ellipse, rect) +{ + return ( + Contains(ellipse, rect.x, rect.y) && + Contains(ellipse, rect.right, rect.y) && + Contains(ellipse, rect.x, rect.bottom) && + Contains(ellipse, rect.right, rect.bottom) + ); +}; -module.exports = BitmapMaskPipeline; +module.exports = ContainsRect; /***/ }), -/* 374 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 75459: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Renderer.WebGL.Pipelines.Events + * Copies the `x`, `y`, `width` and `height` properties from the `source` Ellipse + * into the given `dest` Ellipse, then returns the `dest` Ellipse. + * + * @function Phaser.Geom.Ellipse.CopyFrom + * @since 3.0.0 + * + * @generic {Phaser.Geom.Ellipse} O - [dest,$return] + * + * @param {Phaser.Geom.Ellipse} source - The source Ellipse to copy the values from. + * @param {Phaser.Geom.Ellipse} dest - The destination Ellipse to copy the values to. + * + * @return {Phaser.Geom.Ellipse} The destination Ellipse. */ - -module.exports = { - - AFTER_FLUSH: __webpack_require__(868), - BEFORE_FLUSH: __webpack_require__(869), - BIND: __webpack_require__(870), - BOOT: __webpack_require__(871), - DESTROY: __webpack_require__(872), - REBIND: __webpack_require__(873), - RESIZE: __webpack_require__(874) - +var CopyFrom = function (source, dest) +{ + return dest.setTo(source.x, source.y, source.width, source.height); }; +module.exports = CopyFrom; + /***/ }), -/* 375 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 95669: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); -var WEBGL_CONST = __webpack_require__(107); +var Class = __webpack_require__(56694); +var Contains = __webpack_require__(72313); +var GetPoint = __webpack_require__(95340); +var GetPoints = __webpack_require__(54978); +var GEOM_CONST = __webpack_require__(52394); +var Random = __webpack_require__(72006); /** * @classdesc - * Instances of the WebGLShader class belong to the WebGL Pipeline classes. When the pipeline is - * created it will create an instance of this class for each one of its shaders, as defined in - * the pipeline configuration. - * - * This class encapsulates everything needed to manage a shader in a pipeline, including the - * shader attributes and uniforms, as well as lots of handy methods such as `set2f`, for setting - * uniform values on this shader. + * An Ellipse object. * - * Typically, you do not create an instance of this class directly, as it works in unison with - * the pipeline to which it belongs. You can gain access to this class via a pipeline's `shaders` - * array, post-creation. + * 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 an Ellipse you should look at the capabilities of the Graphics class. * - * @class WebGLShader - * @memberof Phaser.Renderer.WebGL + * @class Ellipse + * @memberof Phaser.Geom * @constructor - * @since 3.50.0 + * @since 3.0.0 * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The WebGLPipeline to which this Shader belongs. - * @param {string} name - The name of this Shader. - * @param {string} vertexShader - The vertex shader source code as a single string. - * @param {string} fragmentShader - The fragment shader source code as a single string. - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineAttributeConfig[]} attributes - An array of attributes. + * @param {number} [x=0] - The x position of the center of the ellipse. + * @param {number} [y=0] - The y position of the center of the ellipse. + * @param {number} [width=0] - The width of the ellipse. + * @param {number} [height=0] - The height of the ellipse. */ -var WebGLShader = new Class({ +var Ellipse = new Class({ initialize: - function WebGLShader (pipeline, name, vertexShader, fragmentShader, attributes) + function Ellipse (x, y, width, height) { - /** - * A reference to the WebGLPipeline that owns this Shader. - * - * A Shader class can only belong to a single pipeline. - * - * @name Phaser.Renderer.WebGL.WebGLShader#pipeline - * @type {Phaser.Renderer.WebGL.WebGLPipeline} - * @since 3.50.0 - */ - this.pipeline = pipeline; - - /** - * The name of this shader. - * - * @name Phaser.Renderer.WebGL.WebGLShader#name - * @type {string} - * @since 3.50.0 - */ - this.name = name; - - /** - * A reference to the WebGLRenderer instance. - * - * @name Phaser.Renderer.WebGL.WebGLShader#renderer - * @type {Phaser.Renderer.WebGL.WebGLRenderer} - * @since 3.50.0 - */ - this.renderer = pipeline.renderer; - - /** - * A reference to the WebGL Rendering Context the WebGL Renderer is using. - * - * @name Phaser.Renderer.WebGL.WebGLShader#gl - * @type {WebGLRenderingContext} - * @since 3.50.0 - */ - this.gl = this.renderer.gl; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = 0; } + if (height === undefined) { height = 0; } /** - * The WebGLProgram created from the vertex and fragment shaders. + * The geometry constant type of this object: `GEOM_CONST.ELLIPSE`. + * Used for fast type comparisons. * - * @name Phaser.Renderer.WebGL.WebGLShader#program - * @type {WebGLProgram} - * @since 3.50.0 + * @name Phaser.Geom.Ellipse#type + * @type {number} + * @readonly + * @since 3.19.0 */ - this.program = this.renderer.createProgram(vertexShader, fragmentShader); + this.type = GEOM_CONST.ELLIPSE; /** - * Array of objects that describe the vertex attributes. + * The x position of the center of the ellipse. * - * @name Phaser.Renderer.WebGL.WebGLShader#attributes - * @type {Phaser.Types.Renderer.WebGL.WebGLPipelineAttribute[]} - * @since 3.50.0 + * @name Phaser.Geom.Ellipse#x + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.attributes; + this.x = x; /** - * The amount of vertex attribute components of 32 bit length. + * The y position of the center of the ellipse. * - * @name Phaser.Renderer.WebGL.WebGLShader#vertexComponentCount + * @name Phaser.Geom.Ellipse#y * @type {number} - * @since 3.50.0 + * @default 0 + * @since 3.0.0 */ - this.vertexComponentCount = 0; + this.y = y; /** - * The size, in bytes, of a single vertex. - * - * This is derived by adding together all of the vertex attributes. - * - * For example, the Multi Pipeline has the following attributes: - * - * inPosition - (size 2 x gl.FLOAT) = 8 - * inTexCoord - (size 2 x gl.FLOAT) = 8 - * inTexId - (size 1 x gl.FLOAT) = 4 - * inTintEffect - (size 1 x gl.FLOAT) = 4 - * inTint - (size 4 x gl.UNSIGNED_BYTE) = 4 - * - * The total, in this case, is 8 + 8 + 4 + 4 + 4 = 28. - * - * This is calculated automatically during the `createAttributes` method. + * The width of the ellipse. * - * @name Phaser.Renderer.WebGL.WebGLShader#vertexSize + * @name Phaser.Geom.Ellipse#width * @type {number} - * @readonly - * @since 3.50.0 + * @default 0 + * @since 3.0.0 */ - this.vertexSize = 0; + this.width = width; /** - * The active uniforms that this shader has. - * - * This is an object that maps the uniform names to their WebGL location and cached values. - * - * It is populated automatically via the `createUniforms` method. + * The height of the ellipse. * - * @name Phaser.Renderer.WebGL.WebGLShader#uniforms - * @type {Phaser.Types.Renderer.WebGL.WebGLPipelineUniformsConfig} - * @since 3.50.0 + * @name Phaser.Geom.Ellipse#height + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.uniforms = {}; - - this.createAttributes(attributes); - this.createUniforms(); + this.height = height; }, /** - * Takes the vertex attributes config and parses it, creating the resulting array that is stored - * in this shaders `attributes` property, calculating the offset, normalization and location - * in the process. - * - * Calling this method resets `WebGLShader.attributes`, `WebGLShader.vertexSize` and - * `WebGLShader.vertexComponentCount`. + * Check to see if the Ellipse contains the given x / y coordinates. * - * It is called automatically when this class is created, but can be called manually if required. + * @method Phaser.Geom.Ellipse#contains + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.WebGLShader#createAttributes - * @since 3.50.0 + * @param {number} x - The x coordinate to check within the ellipse. + * @param {number} y - The y coordinate to check within the ellipse. * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineAttributeConfig[]} attributes - An array of attributes configs. + * @return {boolean} True if the coordinates are within the ellipse, otherwise false. */ - createAttributes: function (attributes) + contains: function (x, y) { - var count = 0; - var offset = 0; - var result = []; - - this.vertexComponentCount = 0; - - for (var i = 0; i < attributes.length; i++) - { - var element = attributes[i]; - - var name = element.name; - var size = GetFastValue(element, 'size', 1); // i.e. 1 for a float, 2 for a vec2, 4 for a vec4, etc - var glType = GetFastValue(element, 'type', WEBGL_CONST.FLOAT); - var type = glType.enum; // The GLenum - var typeSize = glType.size; // The size in bytes of the type - - var normalized = (element.normalized) ? true : false; - - result.push({ - name: name, - size: size, - type: type, - normalized: normalized, - offset: offset, - enabled: false, - location: -1 - }); - - if (typeSize === 4) - { - count += size; - } - else - { - count++; - } - - offset += size * typeSize; - } - - this.vertexSize = offset; - this.vertexComponentCount = count; - this.attributes = result; + return Contains(this, x, y); }, /** - * Sets the program this shader uses as being the active shader in the WebGL Renderer. + * 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. * - * This method is called every time the parent pipeline is made the current active pipeline. + * @method Phaser.Geom.Ellipse#getPoint + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.WebGLShader#bind - * @since 3.50.0 + * @generic {Phaser.Geom.Point} O - [out,$return] * - * @param {boolean} [setAttributes=false] - Should the vertex attribute pointers be set? - * @param {boolean} [flush=false] - Flush the pipeline before binding this shader? + * @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 {this} This WebGLShader instance. + * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the ellipse. */ - bind: function (setAttributes, flush) + getPoint: function (position, point) { - if (setAttributes === undefined) { setAttributes = false; } - if (flush === undefined) { flush = false; } - - if (flush) - { - this.pipeline.flush(); - } - - this.renderer.setProgram(this.program); - - if (setAttributes) - { - this.setAttribPointers(); - } - - return this; + return GetPoint(this, position, point); }, /** - * Sets the program this shader uses as being the active shader in the WebGL Renderer. + * 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. * - * Then resets all of the attribute pointers. + * @method Phaser.Geom.Ellipse#getPoints + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.WebGLShader#rebind - * @since 3.50.0 + * @generic {Phaser.Geom.Point[]} O - [output,$return] * - * @return {this} This WebGLShader instance. + * @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[])} [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 ellipse. */ - rebind: function () + getPoints: function (quantity, stepRate, output) { - this.renderer.setProgram(this.program); - - this.setAttribPointers(true); - - return this; + return GetPoints(this, quantity, stepRate, output); }, /** - * Sets the vertex attribute pointers. - * - * This should only be called after the vertex buffer has been bound. + * Returns a uniformly distributed random point from anywhere within the given Ellipse. * - * It is called automatically during the `bind` method. + * @method Phaser.Geom.Ellipse#getRandomPoint + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.WebGLShader#setAttribPointers - * @since 3.50.0 + * @generic {Phaser.Geom.Point} O - [point,$return] * - * @param {boolean} [reset=false] - Reset the vertex attribute locations? + * @param {(Phaser.Geom.Point|object)} [point] - A Point or point-like object to set the random `x` and `y` values in. * - * @return {this} This WebGLShader instance. + * @return {(Phaser.Geom.Point|object)} A Point object with the random values set in the `x` and `y` properties. */ - setAttribPointers: function (reset) + getRandomPoint: function (point) { - if (reset === undefined) { reset = false; } - - var gl = this.gl; - var vertexSize = this.vertexSize; - var attributes = this.attributes; - var program = this.program; - - for (var i = 0; i < attributes.length; i++) - { - var element = attributes[i]; - - var size = element.size; - var type = element.type; - var offset = element.offset; - var enabled = element.enabled; - var location = element.location; - var normalized = (element.normalized) ? true : false; - - if (reset) - { - var attribLocation = gl.getAttribLocation(program, element.name); - - if (attribLocation >= 0) - { - gl.enableVertexAttribArray(attribLocation); - - gl.vertexAttribPointer(attribLocation, size, type, normalized, vertexSize, offset); - - element.enabled = true; - element.location = attribLocation; - } - else if (attribLocation !== -1) - { - gl.disableVertexAttribArray(attribLocation); - } - } - else if (enabled) - { - gl.vertexAttribPointer(location, size, type, normalized, vertexSize, offset); - } - else if (!enabled && location > -1) - { - gl.disableVertexAttribArray(location); - - element.location = -1; - } - } - - return this; + return Random(this, point); }, /** - * Sets up the `WebGLShader.uniforms` object, populating it with the names - * and locations of the shader uniforms this shader requires. - * - * It works by first calling `gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS)` to - * find out how many active uniforms this shader has. It then iterates through them, - * calling `gl.getActiveUniform` to get the WebGL Active Info from each one. Finally, - * the name and location are stored in the local array. + * Sets the x, y, width and height of this ellipse. * - * This method is called automatically when this class is created. + * @method Phaser.Geom.Ellipse#setTo + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.WebGLShader#createUniforms - * @since 3.50.0 + * @param {number} x - The x position of the center of the ellipse. + * @param {number} y - The y position of the center of the ellipse. + * @param {number} width - The width of the ellipse. + * @param {number} height - The height of the ellipse. * - * @return {this} This WebGLShader instance. + * @return {this} This Ellipse object. */ - createUniforms: function () + setTo: function (x, y, width, height) { - var gl = this.gl; - var program = this.program; - var uniforms = this.uniforms; - - var i; - var name; - var location; - - // Look-up all active uniforms - - var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); - - for (i = 0; i < totalUniforms; i++) - { - var info = gl.getActiveUniform(program, i); - - if (info) - { - name = info.name; - - location = gl.getUniformLocation(program, name); - - if (location !== null) - { - uniforms[name] = - { - name: name, - location: location, - value1: null, - value2: null, - value3: null, - value4: null - }; - } - - // If the uniform name contains [] for an array struct, - // we'll add an entry for the non-struct name as well. - // Such as uMainSampler[12] = uMainSampler - - var struct = name.indexOf('['); - - if (struct > 0) - { - name = name.substr(0, struct); - - if (!uniforms.hasOwnProperty(name)) - { - location = gl.getUniformLocation(program, name); - - if (location !== null) - { - uniforms[name] = - { - name: name, - location: location, - value1: null, - value2: null, - value3: null, - value4: null - }; - } - } - } - } - } + this.x = x; + this.y = y; + this.width = width; + this.height = height; return this; }, /** - * Checks to see if the given uniform name exists and is active in this shader. - * - * @method Phaser.Renderer.WebGL.WebGLShader#hasUniform - * @since 3.50.0 + * Sets this Ellipse to be empty with a width and height of zero. + * Does not change its position. * - * @param {string} name - The name of the uniform to check for. + * @method Phaser.Geom.Ellipse#setEmpty + * @since 3.0.0 * - * @return {boolean} `true` if the uniform exists, otherwise `false`. + * @return {this} This Ellipse object. */ - hasUniform: function (name) + setEmpty: function () { - return this.uniforms.hasOwnProperty(name); + this.width = 0; + this.height = 0; + + return this; }, /** - * Resets the cached values of the given uniform. + * Sets the position of this Ellipse. * - * @method Phaser.Renderer.WebGL.WebGLShader#resetUniform - * @since 3.50.0 + * @method Phaser.Geom.Ellipse#setPosition + * @since 3.0.0 * - * @param {string} name - The name of the uniform to reset. + * @param {number} x - The x position of the center of the ellipse. + * @param {number} y - The y position of the center of the ellipse. * - * @return {this} This WebGLShader instance. + * @return {this} This Ellipse object. */ - resetUniform: function (name) + setPosition: function (x, y) { - var uniform = this.uniforms[name]; + if (y === undefined) { y = x; } - if (uniform) - { - uniform.value1 = null; - uniform.value2 = null; - uniform.value3 = null; - uniform.value4 = null; - } + this.x = x; + this.y = y; return this; }, /** - * Sets the given uniform value/s based on the name and GL function. - * - * This method is called internally by other methods such as `set1f` and `set3iv`. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. + * Sets the size of this Ellipse. + * Does not change its position. * - * @method Phaser.Renderer.WebGL.WebGLShader#setUniform1 - * @since 3.50.0 + * @method Phaser.Geom.Ellipse#setSize + * @since 3.0.0 * - * @param {function} setter - The GL function to call. - * @param {string} name - The name of the uniform to set. - * @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform. - * @param {boolean} [skipCheck=false] - Skip the value comparison? + * @param {number} width - The width of the ellipse. + * @param {number} [height=width] - The height of the ellipse. * - * @return {this} This WebGLShader instance. + * @return {this} This Ellipse object. */ - setUniform1: function (setter, name, value1, skipCheck) + setSize: function (width, height) { - var uniform = this.uniforms[name]; - - if (!uniform) - { - return this; - } - - if (skipCheck || uniform.value1 !== value1) - { - uniform.value1 = value1; - - this.renderer.setProgram(this.program); - - setter.call(this.gl, uniform.location, value1); + if (height === undefined) { height = width; } - this.pipeline.currentShader = this; - } + this.width = width; + this.height = height; return this; }, /** - * Sets the given uniform value/s based on the name and GL function. + * Checks to see if the Ellipse is empty: has a width or height equal to zero. * - * This method is called internally by other methods such as `set1f` and `set3iv`. + * @method Phaser.Geom.Ellipse#isEmpty + * @since 3.0.0 * - * The uniform is only set if the value/s given are different to those previously set. + * @return {boolean} True if the Ellipse is empty, otherwise false. + */ + isEmpty: function () + { + return (this.width <= 0 || this.height <= 0); + }, + + /** + * Returns the minor radius of the ellipse. Also known as the Semi Minor Axis. * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. + * @method Phaser.Geom.Ellipse#getMinorRadius + * @since 3.0.0 * - * @method Phaser.Renderer.WebGL.WebGLShader#setUniform2 - * @since 3.50.0 + * @return {number} The minor radius. + */ + getMinorRadius: function () + { + return Math.min(this.width, this.height) / 2; + }, + + /** + * Returns the major radius of the ellipse. Also known as the Semi Major Axis. * - * @param {function} setter - The GL function to call. - * @param {string} name - The name of the uniform to set. - * @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform. - * @param {(boolean|number|number[]|Float32Array)} value2 - The new value of the uniform. - * @param {boolean} [skipCheck=false] - Skip the value comparison? + * @method Phaser.Geom.Ellipse#getMajorRadius + * @since 3.0.0 * - * @return {this} This WebGLShader instance. + * @return {number} The major radius. */ - setUniform2: function (setter, name, value1, value2, skipCheck) + getMajorRadius: function () { - var uniform = this.uniforms[name]; + return Math.max(this.width, this.height) / 2; + }, - if (!uniform) - { - return this; - } + /** + * The left position of the Ellipse. + * + * @name Phaser.Geom.Ellipse#left + * @type {number} + * @since 3.0.0 + */ + left: { - if (skipCheck || uniform.value1 !== value1 || uniform.value2 !== value2) + get: function () { - uniform.value1 = value1; - uniform.value2 = value2; - - this.renderer.setProgram(this.program); - - setter.call(this.gl, uniform.location, value1, value2); + return this.x - (this.width / 2); + }, - this.pipeline.currentShader = this; + set: function (value) + { + this.x = value + (this.width / 2); } - return this; }, /** - * Sets the given uniform value/s based on the name and GL function. - * - * This method is called internally by other methods such as `set1f` and `set3iv`. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#setUniform3 - * @since 3.50.0 - * - * @param {function} setter - The GL function to call. - * @param {string} name - The name of the uniform to set. - * @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform. - * @param {(boolean|number|number[]|Float32Array)} value2 - The new value of the uniform. - * @param {(boolean|number|number[]|Float32Array)} value3 - The new value of the uniform. - * @param {boolean} [skipCheck=false] - Skip the value comparison? + * The right position of the Ellipse. * - * @return {this} This WebGLShader instance. + * @name Phaser.Geom.Ellipse#right + * @type {number} + * @since 3.0.0 */ - setUniform3: function (setter, name, value1, value2, value3, skipCheck) - { - var uniform = this.uniforms[name]; + right: { - if (!uniform) + get: function () { - return this; - } + return this.x + (this.width / 2); + }, - if (skipCheck || uniform.value1 !== value1 || uniform.value2 !== value2 || uniform.value3 !== value3) + set: function (value) { - uniform.value1 = value1; - uniform.value2 = value2; - uniform.value3 = value3; + this.x = value - (this.width / 2); + } - this.renderer.setProgram(this.program); + }, - setter.call(this.gl, uniform.location, value1, value2, value3); + /** + * The top position of the Ellipse. + * + * @name Phaser.Geom.Ellipse#top + * @type {number} + * @since 3.0.0 + */ + top: { - this.pipeline.currentShader = this; + get: function () + { + return this.y - (this.height / 2); + }, + + set: function (value) + { + this.y = value + (this.height / 2); } - return this; }, /** - * Sets the given uniform value/s based on the name and GL function. - * - * This method is called internally by other methods such as `set1f` and `set3iv`. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#setUniform4 - * @since 3.50.0 - * - * @param {function} setter - The GL function to call. - * @param {string} name - The name of the uniform to set. - * @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform. - * @param {(boolean|number|number[]|Float32Array)} value2 - The new value of the uniform. - * @param {(boolean|number|number[]|Float32Array)} value3 - The new value of the uniform. - * @param {(boolean|number|number[]|Float32Array)} value4 - The new value of the uniform. - * @param {boolean} [skipCheck=false] - Skip the value comparison? + * The bottom position of the Ellipse. * - * @return {this} This WebGLShader instance. + * @name Phaser.Geom.Ellipse#bottom + * @type {number} + * @since 3.0.0 */ - setUniform4: function (setter, name, value1, value2, value3, value4, skipCheck) - { - var uniform = this.uniforms[name]; + bottom: { - if (!uniform) + get: function () { - return this; - } + return this.y + (this.height / 2); + }, - if (skipCheck || uniform.value1 !== value1 || uniform.value2 !== value2 || uniform.value3 !== value3 || uniform.value4 !== value4) + set: function (value) { - uniform.value1 = value1; - uniform.value2 = value2; - uniform.value3 = value3; - uniform.value4 = value4; + this.y = value - (this.height / 2); + } - this.renderer.setProgram(this.program); + } - setter.call(this.gl, uniform.location, value1, value2, value3, value4); +}); - this.pipeline.currentShader = this; - } +module.exports = Ellipse; - return this; - }, - /** - * Sets a 1f uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set1f - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new value of the `float` uniform. - * - * @return {this} This WebGLShader instance. - */ - set1f: function (name, x) - { - return this.setUniform1(this.gl.uniform1f, name, x); - }, +/***/ }), - /** - * Sets a 2f uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set2f - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new X component of the `vec2` uniform. - * @param {number} y - The new Y component of the `vec2` uniform. - * - * @return {this} This WebGLShader instance. - */ - set2f: function (name, x, y) - { - return this.setUniform2(this.gl.uniform2f, name, x, y); - }, +/***/ 98068: +/***/ ((module) => { - /** - * Sets a 3f uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set3f - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new X component of the `vec3` uniform. - * @param {number} y - The new Y component of the `vec3` uniform. - * @param {number} z - The new Z component of the `vec3` uniform. - * - * @return {this} This WebGLShader instance. - */ - set3f: function (name, x, y, z) - { - return this.setUniform3(this.gl.uniform3f, name, x, y, z); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Sets a 4f uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set4f - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - X component of the uniform - * @param {number} y - Y component of the uniform - * @param {number} z - Z component of the uniform - * @param {number} w - W component of the uniform - * - * @return {this} This WebGLShader instance. - */ - set4f: function (name, x, y, z, w) - { - return this.setUniform4(this.gl.uniform4f, name, x, y, z, w); - }, +/** + * Compares the `x`, `y`, `width` and `height` properties of the two given Ellipses. + * Returns `true` if they all match, otherwise returns `false`. + * + * @function Phaser.Geom.Ellipse.Equals + * @since 3.0.0 + * + * @param {Phaser.Geom.Ellipse} ellipse - The first Ellipse to compare. + * @param {Phaser.Geom.Ellipse} toCompare - The second Ellipse to compare. + * + * @return {boolean} `true` if the two Ellipse equal each other, otherwise `false`. + */ +var Equals = function (ellipse, toCompare) +{ + return ( + ellipse.x === toCompare.x && + ellipse.y === toCompare.y && + ellipse.width === toCompare.width && + ellipse.height === toCompare.height + ); +}; - /** - * Sets a 1fv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set1fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * - * @return {this} This WebGLShader instance. - */ - set1fv: function (name, arr) - { - return this.setUniform1(this.gl.uniform1fv, name, arr, true); - }, +module.exports = Equals; - /** - * Sets a 2fv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set2fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * - * @return {this} This WebGLShader instance. - */ - set2fv: function (name, arr) - { - return this.setUniform1(this.gl.uniform2fv, name, arr, true); - }, - /** - * Sets a 3fv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set3fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * - * @return {this} This WebGLShader instance. - */ - set3fv: function (name, arr) - { - return this.setUniform1(this.gl.uniform3fv, name, arr, true); - }, +/***/ }), - /** - * Sets a 4fv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set4fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * - * @return {this} This WebGLShader instance. - */ - set4fv: function (name, arr) - { - return this.setUniform1(this.gl.uniform4fv, name, arr, true); - }, +/***/ 72897: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Sets a 1iv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set1iv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * - * @return {this} This WebGLShader instance. - */ - set1iv: function (name, arr) - { - return this.setUniform1(this.gl.uniform1iv, name, arr, true); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Sets a 2iv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set2iv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * - * @return {this} This WebGLShader instance. - */ - set2iv: function (name, arr) - { - return this.setUniform1(this.gl.uniform2iv, name, arr, true); - }, +var Rectangle = __webpack_require__(74118); - /** - * Sets a 3iv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set3iv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * - * @return {this} This WebGLShader instance. - */ - set3iv: function (name, arr) - { - return this.setUniform1(this.gl.uniform3iv, name, arr, true); - }, +/** + * Returns the bounds of the Ellipse object. + * + * @function Phaser.Geom.Ellipse.GetBounds + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the bounds from. + * @param {(Phaser.Geom.Rectangle|object)} [out] - A Rectangle, or rectangle-like object, to store the ellipse bounds in. If not given a new Rectangle will be created. + * + * @return {(Phaser.Geom.Rectangle|object)} The Rectangle object containing the Ellipse bounds. + */ +var GetBounds = function (ellipse, out) +{ + if (out === undefined) { out = new Rectangle(); } - /** - * Sets a 4iv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set4iv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. - * - * @return {this} This WebGLShader instance. - */ - set4iv: function (name, arr) - { - return this.setUniform1(this.gl.uniform4iv, name, arr, true); - }, + out.x = ellipse.left; + out.y = ellipse.top; + out.width = ellipse.width; + out.height = ellipse.height; - /** - * Sets a 1i uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set1i - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new value of the `int` uniform. - * - * @return {this} This WebGLShader instance. - */ - set1i: function (name, x) - { - return this.setUniform1(this.gl.uniform1i, name, x); - }, + return out; +}; - /** - * Sets a 2i uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set2i - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new X component of the `ivec2` uniform. - * @param {number} y - The new Y component of the `ivec2` uniform. - * - * @return {this} This WebGLShader instance. - */ - set2i: function (name, x, y) - { - return this.setUniform2(this.gl.uniform2i, name, x, y); - }, +module.exports = GetBounds; - /** - * Sets a 3i uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set3i - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - The new X component of the `ivec3` uniform. - * @param {number} y - The new Y component of the `ivec3` uniform. - * @param {number} z - The new Z component of the `ivec3` uniform. - * - * @return {this} This WebGLShader instance. - */ - set3i: function (name, x, y, z) - { - return this.setUniform3(this.gl.uniform3i, name, x, y, z); - }, - /** - * Sets a 4i uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#set4i - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {number} x - X component of the uniform - * @param {number} y - Y component of the uniform - * @param {number} z - Z component of the uniform - * @param {number} w - W component of the uniform - * - * @return {this} This WebGLShader instance. - */ - set4i: function (name, x, y, z, w) - { - return this.setUniform4(this.gl.uniform4i, name, x, y, z, w); - }, +/***/ }), - /** - * Sets a matrix 2fv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#setMatrix2fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {boolean} transpose - Whether to transpose the matrix. Should be `false`. - * @param {number[]|Float32Array} matrix - The new values for the `mat2` uniform. - * - * @return {this} This WebGLShader instance. - */ - setMatrix2fv: function (name, transpose, matrix) - { - return this.setUniform2(this.gl.uniformMatrix2fv, name, transpose, matrix, true); - }, +/***/ 95340: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Sets a matrix 3fv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#setMatrix3fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {boolean} transpose - Whether to transpose the matrix. Should be `false`. - * @param {Float32Array} matrix - The new values for the `mat3` uniform. - * - * @return {this} This WebGLShader instance. - */ - setMatrix3fv: function (name, transpose, matrix) - { - return this.setUniform2(this.gl.uniformMatrix3fv, name, transpose, matrix, true); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Sets a matrix 4fv uniform value based on the given name on this shader. - * - * The uniform is only set if the value/s given are different to those previously set. - * - * This method works by first setting this shader as being the current shader within the - * WebGL Renderer, if it isn't already. It also sets this shader as being the current - * one within the pipeline it belongs to. - * - * @method Phaser.Renderer.WebGL.WebGLShader#setMatrix4fv - * @since 3.50.0 - * - * @param {string} name - The name of the uniform to set. - * @param {boolean} transpose - Should the matrix be transpose - * @param {Float32Array} matrix - Matrix data - * - * @return {this} This WebGLShader instance. - */ - setMatrix4fv: function (name, transpose, matrix) - { - return this.setUniform2(this.gl.uniformMatrix4fv, name, transpose, matrix, true); - }, +var CircumferencePoint = __webpack_require__(86998); +var FromPercent = __webpack_require__(91806); +var MATH_CONST = __webpack_require__(83392); +var Point = __webpack_require__(79967); - /** - * Removes all external references from this class and deletes the WebGL program from the WebGL context. - * - * Does not remove this shader from the parent pipeline. - * - * @method Phaser.Renderer.WebGL.WebGLShader#destroy - * @since 3.50.0 - */ - destroy: function () - { - this.gl.deleteProgram(this.program); +/** + * 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(); } - this.pipeline = null; - this.renderer = null; - this.gl = null; - this.program = null; - this.attributes = null; - this.uniforms = null; - } + var angle = FromPercent(position, 0, MATH_CONST.PI2); -}); + return CircumferencePoint(ellipse, angle, out); +}; -module.exports = WebGLShader; +module.exports = GetPoint; /***/ }), -/* 376 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 54978: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(59); -var GetFastValue = __webpack_require__(2); -var ShaderSourceFS = __webpack_require__(875); -var ShaderSourceVS = __webpack_require__(876); -var TransformMatrix = __webpack_require__(25); -var WEBGL_CONST = __webpack_require__(107); -var WebGLPipeline = __webpack_require__(58); +var Circumference = __webpack_require__(39507); +var CircumferencePoint = __webpack_require__(86998); +var FromPercent = __webpack_require__(91806); +var MATH_CONST = __webpack_require__(83392); /** - * @classdesc - * The Graphics Pipeline is the rendering pipeline used by Phaser in WebGL when drawing - * primitive geometry objects, such as the Graphics Game Object, or the Shape Game Objects - * such as Arc, Line, Rectangle and Star. It handles the preperation and batching of related vertices. + * 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. * - * Prior to Phaser v3.50 the functions of this pipeline were merged with the `TextureTintPipeline`. + * @function Phaser.Geom.Ellipse.GetPoints + * @since 3.0.0 * - * The fragment shader it uses can be found in `shaders/src/Graphics.frag`. - * The vertex shader it uses can be found in `shaders/src/Graphics.vert`. + * @generic {Phaser.Geom.Point[]} O - [out,$return] * - * The default shader attributes for this pipeline are: + * @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. * - * `inPosition` (vec2) - * `inColor` (vec4, normalized) + * @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; + + +/***/ }), + +/***/ 77951: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Offsets the Ellipse by the values given. * - * The default shader uniforms for this pipeline are: + * @function Phaser.Geom.Ellipse.Offset + * @since 3.0.0 * - * `uProjectionMatrix` (mat4) + * @generic {Phaser.Geom.Ellipse} O - [ellipse,$return] * - * @class GraphicsPipeline - * @extends Phaser.Renderer.WebGL.WebGLPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.50.0 + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to be offset (translated.) + * @param {number} x - The amount to horizontally offset the Ellipse by. + * @param {number} y - The amount to vertically offset the Ellipse by. * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + * @return {Phaser.Geom.Ellipse} The Ellipse that was offset. */ -var GraphicsPipeline = new Class({ +var Offset = function (ellipse, x, y) +{ + ellipse.x += x; + ellipse.y += y; - Extends: WebGLPipeline, + return ellipse; +}; - initialize: +module.exports = Offset; - function GraphicsPipeline (config) - { - config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS); - config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS); - config.attributes = GetFastValue(config, 'attributes', [ - { - name: 'inPosition', - size: 2 - }, - { - name: 'inColor', - size: 4, - type: WEBGL_CONST.UNSIGNED_BYTE, - normalized: true - } - ]); - WebGLPipeline.call(this, config); +/***/ }), - /** - * A temporary Transform Matrix, re-used internally during batching by the - * Shape Game Objects. - * - * @name Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#calcMatrix - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @since 3.50.0 - */ - this.calcMatrix = new TransformMatrix(); +/***/ 36233: +/***/ ((module) => { - /** - * Used internally to draw stroked triangles. - * - * @name Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#tempTriangle - * @type {array} - * @private - * @since 3.50.0 - */ - this.tempTriangle = [ - { x: 0, y: 0, width: 0 }, - { x: 0, y: 0, width: 0 }, - { x: 0, y: 0, width: 0 }, - { x: 0, y: 0, width: 0 } - ]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Cached stroke tint. - * - * @name Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#strokeTint - * @type {object} - * @private - * @since 3.50.0 - */ - this.strokeTint = { TL: 0, TR: 0, BL: 0, BR: 0 }; +/** + * Offsets the Ellipse by the values given in the `x` and `y` properties of the Point object. + * + * @function Phaser.Geom.Ellipse.OffsetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Ellipse} O - [ellipse,$return] + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to be offset (translated.) + * @param {(Phaser.Geom.Point|object)} point - The Point object containing the values to offset the Ellipse by. + * + * @return {Phaser.Geom.Ellipse} The Ellipse that was offset. + */ +var OffsetPoint = function (ellipse, point) +{ + ellipse.x += point.x; + ellipse.y += point.y; - /** - * Cached fill tint. - * - * @name Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#fillTint - * @type {object} - * @private - * @since 3.50.0 - */ - this.fillTint = { TL: 0, TR: 0, BL: 0, BR: 0 }; + return ellipse; +}; - /** - * Internal texture frame reference. - * - * @name Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#currentFrame - * @type {Phaser.Textures.Frame} - * @private - * @since 3.50.0 - */ - this.currentFrame = { u0: 0, v0: 0, u1: 1, v1: 1 }; +module.exports = OffsetPoint; - /** - * Internal path quad cache. - * - * @name Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#firstQuad - * @type {number[]} - * @private - * @since 3.50.0 - */ - this.firstQuad = [ 0, 0, 0, 0, 0 ]; - /** - * Internal path quad cache. - * - * @name Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#prevQuad - * @type {number[]} - * @private - * @since 3.50.0 - */ - this.prevQuad = [ 0, 0, 0, 0, 0 ]; +/***/ }), - /** - * Used internally for triangulating a polygon. - * - * @name Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#polygonCache - * @type {array} - * @private - * @since 3.50.0 - */ - this.polygonCache = []; - }, +/***/ 72006: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Pushes a filled rectangle into the vertex batch. - * - * Rectangle factors in the given transform matrices before adding to the batch. - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#batchFillRect - * @since 3.50.0 - * - * @param {number} x - Horizontal top left coordinate of the rectangle. - * @param {number} y - Vertical top left coordinate of the rectangle. - * @param {number} width - Width of the rectangle. - * @param {number} height - Height of the rectangle. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchFillRect: function (x, y, width, height, currentMatrix, parentMatrix) - { - this.renderer.pipelines.set(this); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var calcMatrix = this.calcMatrix; +var Point = __webpack_require__(79967); - // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix - if (parentMatrix) - { - parentMatrix.multiply(currentMatrix, calcMatrix); - } +/** + * Returns a uniformly distributed random point from anywhere within the given Ellipse. + * + * @function Phaser.Geom.Ellipse.Random + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get a random point from. + * @param {(Phaser.Geom.Point|object)} [out] - 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. + */ +var Random = function (ellipse, out) +{ + if (out === undefined) { out = new Point(); } - var xw = x + width; - var yh = y + height; + var p = Math.random() * Math.PI * 2; + var s = Math.sqrt(Math.random()); - var x0 = calcMatrix.getX(x, y); - var y0 = calcMatrix.getY(x, y); + out.x = ellipse.x + ((s * Math.cos(p)) * ellipse.width / 2); + out.y = ellipse.y + ((s * Math.sin(p)) * ellipse.height / 2); - var x1 = calcMatrix.getX(x, yh); - var y1 = calcMatrix.getY(x, yh); + return out; +}; - var x2 = calcMatrix.getX(xw, yh); - var y2 = calcMatrix.getY(xw, yh); +module.exports = Random; - var x3 = calcMatrix.getX(xw, y); - var y3 = calcMatrix.getY(xw, y); - var tint = this.fillTint; +/***/ }), - this.batchQuad(x0, y0, x1, y1, x2, y2, x3, y3, tint.TL, tint.TR, tint.BL, tint.BR); - }, +/***/ 40652: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Pushes a filled triangle into the vertex batch. - * - * Triangle factors in the given transform matrices before adding to the batch. - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#batchFillTriangle - * @since 3.50.0 - * - * @param {number} x0 - Point 0 x coordinate. - * @param {number} y0 - Point 0 y coordinate. - * @param {number} x1 - Point 1 x coordinate. - * @param {number} y1 - Point 1 y coordinate. - * @param {number} x2 - Point 2 x coordinate. - * @param {number} y2 - Point 2 y coordinate. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchFillTriangle: function (x0, y0, x1, y1, x2, y2, currentMatrix, parentMatrix) - { - this.renderer.pipelines.set(this); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var calcMatrix = this.calcMatrix; +var Ellipse = __webpack_require__(95669); - // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix - if (parentMatrix) - { - parentMatrix.multiply(currentMatrix, calcMatrix); - } +Ellipse.Area = __webpack_require__(58605); +Ellipse.Circumference = __webpack_require__(39507); +Ellipse.CircumferencePoint = __webpack_require__(86998); +Ellipse.Clone = __webpack_require__(81773); +Ellipse.Contains = __webpack_require__(72313); +Ellipse.ContainsPoint = __webpack_require__(34368); +Ellipse.ContainsRect = __webpack_require__(71431); +Ellipse.CopyFrom = __webpack_require__(75459); +Ellipse.Equals = __webpack_require__(98068); +Ellipse.GetBounds = __webpack_require__(72897); +Ellipse.GetPoint = __webpack_require__(95340); +Ellipse.GetPoints = __webpack_require__(54978); +Ellipse.Offset = __webpack_require__(77951); +Ellipse.OffsetPoint = __webpack_require__(36233); +Ellipse.Random = __webpack_require__(72006); - var tx0 = calcMatrix.getX(x0, y0); - var ty0 = calcMatrix.getY(x0, y0); +module.exports = Ellipse; - var tx1 = calcMatrix.getX(x1, y1); - var ty1 = calcMatrix.getY(x1, y1); - var tx2 = calcMatrix.getX(x2, y2); - var ty2 = calcMatrix.getY(x2, y2); +/***/ }), - var tint = this.fillTint; +/***/ 84068: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.batchTri(tx0, ty0, tx1, ty1, tx2, ty2, tint.TL, tint.TR, tint.BL); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Pushes a stroked triangle into the vertex batch. - * - * Triangle factors in the given transform matrices before adding to the batch. - * - * The triangle is created from 3 lines and drawn using the `batchStrokePath` method. - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#batchStrokeTriangle - * @since 3.50.0 - * - * @param {number} x0 - Point 0 x coordinate. - * @param {number} y0 - Point 0 y coordinate. - * @param {number} x1 - Point 1 x coordinate. - * @param {number} y1 - Point 1 y coordinate. - * @param {number} x2 - Point 2 x coordinate. - * @param {number} y2 - Point 2 y coordinate. - * @param {number} lineWidth - The width of the line in pixels. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchStrokeTriangle: function (x0, y0, x1, y1, x2, y2, lineWidth, currentMatrix, parentMatrix) - { - var tempTriangle = this.tempTriangle; +var CONST = __webpack_require__(52394); +var Extend = __webpack_require__(98611); - tempTriangle[0].x = x0; - tempTriangle[0].y = y0; - tempTriangle[0].width = lineWidth; +/** + * @namespace Phaser.Geom + */ - tempTriangle[1].x = x1; - tempTriangle[1].y = y1; - tempTriangle[1].width = lineWidth; +var Geom = { - tempTriangle[2].x = x2; - tempTriangle[2].y = y2; - tempTriangle[2].width = lineWidth; + Circle: __webpack_require__(6112), + Ellipse: __webpack_require__(40652), + Intersects: __webpack_require__(7563), + Line: __webpack_require__(28482), + Mesh: __webpack_require__(14293), + Point: __webpack_require__(63472), + Polygon: __webpack_require__(44359), + Rectangle: __webpack_require__(66658), + Triangle: __webpack_require__(87619) - tempTriangle[3].x = x0; - tempTriangle[3].y = y0; - tempTriangle[3].width = lineWidth; +}; - this.batchStrokePath(tempTriangle, lineWidth, false, currentMatrix, parentMatrix); - }, +// Merge in the consts +Geom = Extend(false, Geom, CONST); - /** - * Adds the given path to the vertex batch for rendering. - * - * It works by taking the array of path data and then passing it through Earcut, which - * creates a list of polygons. Each polygon is then added to the batch. - * - * The path is always automatically closed because it's filled. - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#batchFillPath - * @since 3.50.0 - * - * @param {Phaser.Types.Math.Vector2Like[]} path - Collection of points that represent the path. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchFillPath: function (path, currentMatrix, parentMatrix) - { - this.renderer.pipelines.set(this); +module.exports = Geom; - var calcMatrix = this.calcMatrix; - // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix - if (parentMatrix) - { - parentMatrix.multiply(currentMatrix, calcMatrix); - } +/***/ }), - var length = path.length; - var polygonCache = this.polygonCache; - var polygonIndexArray; - var point; +/***/ 22184: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var tintTL = this.fillTint.TL; - var tintTR = this.fillTint.TR; - var tintBL = this.fillTint.BL; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (var pathIndex = 0; pathIndex < length; ++pathIndex) - { - point = path[pathIndex]; - polygonCache.push(point.x, point.y); - } +var DistanceBetween = __webpack_require__(53996); - polygonIndexArray = Earcut(polygonCache); - length = polygonIndexArray.length; +/** + * Checks if two Circles intersect. + * + * @function Phaser.Geom.Intersects.CircleToCircle + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circleA - The first Circle to check for intersection. + * @param {Phaser.Geom.Circle} circleB - The second Circle to check for intersection. + * + * @return {boolean} `true` if the two Circles intersect, otherwise `false`. + */ +var CircleToCircle = function (circleA, circleB) +{ + return (DistanceBetween(circleA.x, circleA.y, circleB.x, circleB.y) <= (circleA.radius + circleB.radius)); +}; - for (var index = 0; index < length; index += 3) - { - var p0 = polygonIndexArray[index + 0] * 2; - var p1 = polygonIndexArray[index + 1] * 2; - var p2 = polygonIndexArray[index + 2] * 2; +module.exports = CircleToCircle; - var x0 = polygonCache[p0 + 0]; - var y0 = polygonCache[p0 + 1]; - var x1 = polygonCache[p1 + 0]; - var y1 = polygonCache[p1 + 1]; - var x2 = polygonCache[p2 + 0]; - var y2 = polygonCache[p2 + 1]; - var tx0 = calcMatrix.getX(x0, y0); - var ty0 = calcMatrix.getY(x0, y0); +/***/ }), - var tx1 = calcMatrix.getX(x1, y1); - var ty1 = calcMatrix.getY(x1, y1); +/***/ 26535: +/***/ ((module) => { - var tx2 = calcMatrix.getX(x2, y2); - var ty2 = calcMatrix.getY(x2, y2); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.batchTri(tx0, ty0, tx1, ty1, tx2, ty2, tintTL, tintTR, tintBL); - } +/** + * Checks for intersection between a circle and a rectangle. + * + * @function Phaser.Geom.Intersects.CircleToRectangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The circle to be checked. + * @param {Phaser.Geom.Rectangle} rect - The rectangle to be checked. + * + * @return {boolean} `true` if the two objects intersect, otherwise `false`. + */ +var CircleToRectangle = function (circle, rect) +{ + var halfWidth = rect.width / 2; + var halfHeight = rect.height / 2; - polygonCache.length = 0; - }, + var cx = Math.abs(circle.x - rect.x - halfWidth); + var cy = Math.abs(circle.y - rect.y - halfHeight); + var xDist = halfWidth + circle.radius; + var yDist = halfHeight + circle.radius; - /** - * Adds the given path to the vertex batch for rendering. - * - * It works by taking the array of path data and calling `batchLine` for each section - * of the path. - * - * The path is optionally closed at the end. - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#batchStrokePath - * @since 3.50.0 - * - * @param {Phaser.Types.Math.Vector2Like[]} path - Collection of points that represent the path. - * @param {number} lineWidth - The width of the line segments in pixels. - * @param {boolean} pathOpen - Indicates if the path should be closed or left open. - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchStrokePath: function (path, lineWidth, pathOpen, currentMatrix, parentMatrix) + if (cx > xDist || cy > yDist) { - this.renderer.pipelines.set(this); + return false; + } + else if (cx <= halfWidth || cy <= halfHeight) + { + return true; + } + else + { + var xCornerDist = cx - halfWidth; + var yCornerDist = cy - halfHeight; + var xCornerDistSq = xCornerDist * xCornerDist; + var yCornerDistSq = yCornerDist * yCornerDist; + var maxCornerDistSq = circle.radius * circle.radius; - // Reset the closePath booleans - this.prevQuad[4] = 0; - this.firstQuad[4] = 0; + return (xCornerDistSq + yCornerDistSq <= maxCornerDistSq); + } +}; - var pathLength = path.length - 1; +module.exports = CircleToRectangle; - for (var pathIndex = 0; pathIndex < pathLength; pathIndex++) - { - var point0 = path[pathIndex]; - var point1 = path[pathIndex + 1]; - this.batchLine( - point0.x, - point0.y, - point1.x, - point1.y, - point0.width / 2, - point1.width / 2, - lineWidth, - pathIndex, - !pathOpen && (pathIndex === pathLength - 1), - currentMatrix, - parentMatrix - ); - } - }, +/***/ }), - /** - * Creates a line out of 4 quads and adds it to the vertex batch based on the given line values. - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#batchLine - * @since 3.50.0 - * - * @param {number} ax - x coordinate of the start of the line. - * @param {number} ay - y coordinate of the start of the line. - * @param {number} bx - x coordinate of the end of the line. - * @param {number} by - y coordinate of the end of the line. - * @param {number} aLineWidth - Width of the start of the line. - * @param {number} bLineWidth - Width of the end of the line. - * @param {number} index - If this line is part of a multi-line draw, the index of the line in the draw. - * @param {boolean} closePath - Does this line close a multi-line path? - * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. - */ - batchLine: function (ax, ay, bx, by, aLineWidth, bLineWidth, lineWidth, index, closePath, currentMatrix, parentMatrix) - { - this.renderer.pipelines.set(this); +/***/ 71145: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var calcMatrix = this.calcMatrix; +/** + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix - if (parentMatrix) - { - parentMatrix.multiply(currentMatrix, calcMatrix); - } +var Point = __webpack_require__(79967); +var CircleToCircle = __webpack_require__(22184); - var dx = bx - ax; - var dy = by - ay; +/** + * Checks if two Circles intersect and returns the intersection points as a Point object array. + * + * @function Phaser.Geom.Intersects.GetCircleToCircle + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circleA - The first Circle to check for intersection. + * @param {Phaser.Geom.Circle} circleB - The second Circle to check for intersection. + * @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 GetCircleToCircle = function (circleA, circleB, out) +{ + if (out === undefined) { out = []; } - var len = Math.sqrt(dx * dx + dy * dy); - var al0 = aLineWidth * (by - ay) / len; - var al1 = aLineWidth * (ax - bx) / len; - var bl0 = bLineWidth * (by - ay) / len; - var bl1 = bLineWidth * (ax - bx) / len; + if (CircleToCircle(circleA, circleB)) + { + var x0 = circleA.x; + var y0 = circleA.y; + var r0 = circleA.radius; - var lx0 = bx - bl0; - var ly0 = by - bl1; - var lx1 = ax - al0; - var ly1 = ay - al1; - var lx2 = bx + bl0; - var ly2 = by + bl1; - var lx3 = ax + al0; - var ly3 = ay + al1; + var x1 = circleB.x; + var y1 = circleB.y; + var r1 = circleB.radius; - // tx0 = bottom right - var brX = calcMatrix.getX(lx0, ly0); - var brY = calcMatrix.getY(lx0, ly0); + var coefficientA, coefficientB, coefficientC, lambda, x; - // tx1 = bottom left - var blX = calcMatrix.getX(lx1, ly1); - var blY = calcMatrix.getY(lx1, ly1); + if (y0 === y1) + { + x = ((r1 * r1) - (r0 * r0) - (x1 * x1) + (x0 * x0)) / (2 * (x0 - x1)); - // tx2 = top right - var trX = calcMatrix.getX(lx2, ly2); - var trY = calcMatrix.getY(lx2, ly2); + coefficientA = 1; + coefficientB = -2 * y1; + coefficientC = (x1 * x1) + (x * x) - (2 * x1 * x) + (y1 * y1) - (r1 * r1); - // tx3 = top left - var tlX = calcMatrix.getX(lx3, ly3); - var tlY = calcMatrix.getY(lx3, ly3); + lambda = (coefficientB * coefficientB) - (4 * coefficientA * coefficientC); - var tint = this.strokeTint; + if (lambda === 0) + { + out.push(new Point(x, (-coefficientB / (2 * coefficientA)))); + } + else if (lambda > 0) + { + out.push(new Point(x, (-coefficientB + Math.sqrt(lambda)) / (2 * coefficientA))); + out.push(new Point(x, (-coefficientB - Math.sqrt(lambda)) / (2 * coefficientA))); + } + } + else + { + var v1 = (x0 - x1) / (y0 - y1); + var n = (r1 * r1 - r0 * r0 - x1 * x1 + x0 * x0 - y1 * y1 + y0 * y0) / (2 * (y0 - y1)); - var tintTL = tint.TL; - var tintTR = tint.TR; - var tintBL = tint.BL; - var tintBR = tint.BR; + coefficientA = (v1 * v1) + 1; + coefficientB = (2 * y0 * v1) - (2 * n * v1) - (2 * x0); + coefficientC = (x0 * x0) + (y0 * y0) + (n * n) - (r0 * r0) - (2 * y0 * n); - // TL, BL, BR, TR - this.batchQuad(tlX, tlY, blX, blY, brX, brY, trX, trY, tintTL, tintTR, tintBL, tintBR); + lambda = (coefficientB * coefficientB) - (4 * coefficientA * coefficientC); - if (lineWidth <= 2) - { - // No point doing a linejoin if the line isn't thick enough - return; + if (lambda === 0) + { + x = (-coefficientB / (2 * coefficientA)); + out.push(new Point(x, (n - (x * v1)))); + } + else if (lambda > 0) + { + x = (-coefficientB + Math.sqrt(lambda)) / (2 * coefficientA); + out.push(new Point(x, (n - (x * v1)))); + x = (-coefficientB - Math.sqrt(lambda)) / (2 * coefficientA); + out.push(new Point(x, (n - (x * v1)))); + } } + } - var prev = this.prevQuad; - var first = this.firstQuad; + return out; +}; - if (index > 0 && prev[4]) - { - this.batchQuad(tlX, tlY, blX, blY, prev[0], prev[1], prev[2], prev[3], tintTL, tintTR, tintBL, tintBR); - } - else - { - first[0] = tlX; - first[1] = tlY; - first[2] = blX; - first[3] = blY; - first[4] = 1; - } +module.exports = GetCircleToCircle; - if (closePath && first[4]) - { - // Add a join for the final path segment - this.batchQuad(brX, brY, trX, trY, first[0], first[1], first[2], first[3], tintTL, tintTR, tintBL, tintBR); - } - else - { - // Store it - prev[0] = brX; - prev[1] = brY; - prev[2] = trX; - prev[3] = trY; - prev[4] = 1; - } - }, +/***/ }), - /** - * Adds a single vertex to the current vertex buffer and increments the - * `vertexCount` property by 1. - * - * This method is called directly by `batchTri` and `batchQuad`. - * - * It does not perform any batch limit checking itself, so if you need to call - * this method directly, do so in the same way that `batchQuad` does, for example. - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#batchVert - * @since 3.50.0 - * - * @param {number} x - The vertex x position. - * @param {number} y - The vertex y position. - * @param {number} tint - The tint color value. - */ - batchVert: function (x, y, tint) - { - var vertexViewF32 = this.vertexViewF32; - var vertexViewU32 = this.vertexViewU32; +/***/ 62508: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var vertexOffset = (this.vertexCount * this.currentShader.vertexComponentCount) - 1; +/** + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - vertexViewF32[++vertexOffset] = x; - vertexViewF32[++vertexOffset] = y; - vertexViewU32[++vertexOffset] = tint; +var GetLineToCircle = __webpack_require__(26111); +var CircleToRectangle = __webpack_require__(26535); - this.vertexCount++; - }, +/** + * Checks for intersection between a circle and a rectangle, + * and returns the intersection points as a Point object array. + * + * @function Phaser.Geom.Intersects.GetCircleToRectangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Circle} circle - The circle to be checked. + * @param {Phaser.Geom.Rectangle} rect - The rectangle to be checked. + * @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 GetCircleToRectangle = function (circle, rect, out) +{ + if (out === undefined) { out = []; } - /** - * Adds the vertices data into the batch and flushes if full. - * - * Assumes 6 vertices in the following arrangement: - * - * ``` - * 0----3 - * |\ B| - * | \ | - * | \ | - * | A \| - * | \ - * 1----2 - * ``` - * - * Where tx0/ty0 = 0, tx1/ty1 = 1, tx2/ty2 = 2 and tx3/ty3 = 3 - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#batchQuad - * @override - * @since 3.50.0 - * - * @param {number} x0 - The top-left x position. - * @param {number} y0 - The top-left y position. - * @param {number} x1 - The bottom-left x position. - * @param {number} y1 - The bottom-left y position. - * @param {number} x2 - The bottom-right x position. - * @param {number} y2 - The bottom-right y position. - * @param {number} x3 - The top-right x position. - * @param {number} y3 - The top-right y position. - * @param {number} tintTL - The top-left tint color value. - * @param {number} tintTR - The top-right tint color value. - * @param {number} tintBL - The bottom-left tint color value. - * @param {number} tintBR - The bottom-right tint color value. - * - * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`. - */ - batchQuad: function (x0, y0, x1, y1, x2, y2, x3, y3, tintTL, tintTR, tintBL, tintBR) + if (CircleToRectangle(circle, rect)) { - var hasFlushed = false; + var lineA = rect.getLineA(); + var lineB = rect.getLineB(); + var lineC = rect.getLineC(); + var lineD = rect.getLineD(); - if (this.shouldFlush(6)) - { - this.flush(); + GetLineToCircle(lineA, circle, out); + GetLineToCircle(lineB, circle, out); + GetLineToCircle(lineC, circle, out); + GetLineToCircle(lineD, circle, out); + } - hasFlushed = true; - } + return out; +}; - this.batchVert(x0, y0, tintTL); - this.batchVert(x1, y1, tintBL); - this.batchVert(x2, y2, tintBR); - this.batchVert(x0, y0, tintTL); - this.batchVert(x2, y2, tintBR); - this.batchVert(x3, y3, tintTR); +module.exports = GetCircleToRectangle; - return hasFlushed; - }, - /** - * Adds the vertices data into the batch and flushes if full. - * - * Assumes 3 vertices in the following arrangement: - * - * ``` - * 0 - * |\ - * | \ - * | \ - * | \ - * | \ - * 1-----2 - * ``` - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#batchTri - * @override - * @since 3.50.0 - * - * @param {number} x1 - The bottom-left x position. - * @param {number} y1 - The bottom-left y position. - * @param {number} x2 - The bottom-right x position. - * @param {number} y2 - The bottom-right y position. - * @param {number} x3 - The top-right x position. - * @param {number} y3 - The top-right y position. - * @param {number} tintTL - The top-left tint color value. - * @param {number} tintTR - The top-right tint color value. - * @param {number} tintBL - The bottom-left tint color value. - * - * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`. - */ - batchTri: function (x0, y0, x1, y1, x2, y2, tintTL, tintTR, tintBL) - { - var hasFlushed = false; +/***/ }), - if (this.shouldFlush(3)) - { - this.flush(); +/***/ 26111: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - hasFlushed = true; - } +/** + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.batchVert(x0, y0, tintTL); - this.batchVert(x1, y1, tintTR); - this.batchVert(x2, y2, tintBL); +var Point = __webpack_require__(79967); +var LineToCircle = __webpack_require__(61472); - return hasFlushed; - }, +/** + * Checks for intersection between the line segment and circle, + * and returns the intersection points as a Point object array. + * + * @function Phaser.Geom.Intersects.GetLineToCircle + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The line segment to check. + * @param {Phaser.Geom.Circle} circle - The circle to check against the line. + * @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 GetLineToCircle = function (line, circle, out) +{ + if (out === undefined) { out = []; } - /** - * Destroys all shader instances, removes all object references and nulls all external references. - * - * @method Phaser.Renderer.WebGL.Pipelines.GraphicsPipeline#destroy - * @since 3.50.0 - * - * @return {this} This WebGLPipeline instance. - */ - destroy: function () + if (LineToCircle(line, circle)) { - WebGLPipeline.prototype.destroy.call(this); + var lx1 = line.x1; + var ly1 = line.y1; - this.polygonCache = null; + var lx2 = line.x2; + var ly2 = line.y2; - return this; + var cx = circle.x; + var cy = circle.y; + var cr = circle.radius; + + var lDirX = lx2 - lx1; + var lDirY = ly2 - ly1; + var oDirX = lx1 - cx; + var oDirY = ly1 - cy; + + var coefficientA = lDirX * lDirX + lDirY * lDirY; + var coefficientB = 2 * (lDirX * oDirX + lDirY * oDirY); + var coefficientC = oDirX * oDirX + oDirY * oDirY - cr * cr; + + var lambda = (coefficientB * coefficientB) - (4 * coefficientA * coefficientC); + + var x, y; + + if (lambda === 0) + { + var root = -coefficientB / (2 * coefficientA); + x = lx1 + root * lDirX; + y = ly1 + root * lDirY; + if (root >= 0 && root <= 1) + { + out.push(new Point(x, y)); + } + } + else if (lambda > 0) + { + var root1 = (-coefficientB - Math.sqrt(lambda)) / (2 * coefficientA); + x = lx1 + root1 * lDirX; + y = ly1 + root1 * lDirY; + if (root1 >= 0 && root1 <= 1) + { + out.push(new Point(x, y)); + } + + var root2 = (-coefficientB + Math.sqrt(lambda)) / (2 * coefficientA); + x = lx1 + root2 * lDirX; + y = ly1 + root2 * lDirY; + if (root2 >= 0 && root2 <= 1) + { + out.push(new Point(x, y)); + } + } } -}); + return out; +}; -module.exports = GraphicsPipeline; +module.exports = GetLineToCircle; /***/ }), -/* 377 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 96537: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); -var LightShaderSourceFS = __webpack_require__(877); -var MultiPipeline = __webpack_require__(108); -var Vec2 = __webpack_require__(3); -var WebGLPipeline = __webpack_require__(58); - -var LIGHT_COUNT = 10; -var tempVec2 = new Vec2(); +var Vector3 = __webpack_require__(70015); /** - * @classdesc - * The Light Pipeline is an extension of the Multi Pipeline and uses a custom shader - * designed to handle forward diffused rendering of 2D lights in a Scene. - * - * The shader works in tandem with Light Game Objects, and optionally texture normal maps, - * to provide an ambient illumination effect. - * - * If you wish to provide your own shader, you can use the `%LIGHT_COUNT%` declaration in the source, - * and it will be automatically replaced at run-time with the total number of configured lights. - * - * The maximum number of lights can be set in the Render Config `maxLights` property and defaults to 10. - * - * Prior to Phaser v3.50 this pipeline was called the `ForwardDiffuseLightPipeline`. - * - * The fragment shader it uses can be found in `shaders/src/Light.frag`. - * The vertex shader it uses can be found in `shaders/src/Multi.vert`. - * - * The default shader attributes for this pipeline are: + * Checks for intersection between the two line segments, or a ray and a line segment, + * and returns the intersection point as a Vector3, or `null` if the lines are parallel, or do not intersect. * - * `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 those from the Multi Pipeline, plus: - * - * `uMainSampler` (sampler2D) - * `uNormSampler` (sampler2D) - * `uCamera` (vec4) - * `uResolution` (vec2) - * `uAmbientLightColor` (vec3) - * `uInverseRotationMatrix` (mat3) - * `uLights` (Light struct) + * 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. * - * @class LightPipeline - * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor + * @function Phaser.Geom.Intersects.GetLineToLine * @since 3.50.0 * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + * @param {Phaser.Geom.Line} line1 - The first line segment, or a ray, to check. + * @param {Phaser.Geom.Line} line2 - The second line segment to check. + * @param {boolean} [isRay=false] - Is `line1` a ray or a line segment? + * @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 LightPipeline = new Class({ +var GetLineToLine = function (line1, line2, isRay, out) +{ + if (isRay === undefined) { isRay = false; } - Extends: MultiPipeline, + var x1 = line1.x1; + var y1 = line1.y1; + var x2 = line1.x2; + var y2 = line1.y2; - initialize: + var x3 = line2.x1; + var y3 = line2.y1; + var x4 = line2.x2; + var y4 = line2.y2; - function LightPipeline (config) + var dx1 = x2 - x1; + var dy1 = y2 - y1; + + var dx2 = x4 - x3; + var dy2 = y4 - y3; + + var denom = (dx1 * dy2 - dy1 * dx2); + + // Add co-linear check + + // 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 (denom === 0) { - LIGHT_COUNT = config.game.renderer.config.maxLights; + return null; + } - var fragShader = GetFastValue(config, 'fragShader', LightShaderSourceFS); + var t; + var u; + var s; - var shaders = []; + if (isRay) + { + t = (dx1 * (y3 - y1) + dy1 * (x1 - x3)) / (dx2 * dy1 - dy2 * dx1); + u = (x3 + dx2 * t - x1) / dx1; - for (var i = 1; i <= LIGHT_COUNT; i++) + // Intersects? + if (u < 0 || t < 0 || t > 1) { - shaders.push({ - name: 'lights' + i, - fragShader: fragShader.replace('%LIGHT_COUNT%', i.toString()) - }); + return null; } - config.shaders = shaders; + s = u; + } + else + { + t = ((x3 - x1) * dy2 - (y3 - y1) * dx2) / denom; + u = ((y1 - y3) * dx1 - (x1 - x3) * dy1) / denom; - MultiPipeline.call(this, config); + // Intersects? + if (t < 0 || t > 1 || u < 0 || u > 1) + { + return null; + } - /** - * Inverse rotation matrix for normal map rotations. - * - * @name Phaser.Renderer.WebGL.Pipelines.LightPipeline#inverseRotationMatrix - * @type {Float32Array} - * @private - * @since 3.16.0 - */ - this.inverseRotationMatrix = new Float32Array([ - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 - ]); + s = t; + } - /** - * Stores a default normal map, which is an object with a `glTexture` property that - * maps to a 1x1 texture of the color #7f7fff created in the `boot` method. - * - * @name Phaser.Renderer.WebGL.Pipelines.LightPipeline#defaultNormalMap - * @type {object} - * @since 3.50.0 - */ - this.defaultNormalMap; + if (out === undefined) + { + out = new Vector3(); + } - /** - * A boolean that is set automatically during `onRender` that determines - * if the Scene LightManager is active, or not. - * - * @name Phaser.Renderer.WebGL.Pipelines.LightPipeline#lightsActive - * @type {boolean} - * @readonly - * @since 3.53.0 - */ - this.lightsActive = true; - }, + return out.set( + x1 + dx1 * s, + y1 + dy1 * s, + s + ); +}; - /** - * Called when the Game has fully booted and the Renderer has finished setting up. - * - * By this stage all Game level systems are now in place and you can perform any final - * tasks that the pipeline may need that relied on game systems such as the Texture Manager. - * - * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#boot - * @since 3.11.0 - */ - boot: function () - { - WebGLPipeline.prototype.boot.call(this); +module.exports = GetLineToLine; - var gl = this.gl; - var tempTexture = gl.createTexture(); +/***/ }), - gl.activeTexture(gl.TEXTURE0); +/***/ 17647: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - gl.bindTexture(gl.TEXTURE_2D, tempTexture); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([ 127, 127, 255, 255 ])); +var GetLineToLine = __webpack_require__(96537); +var Line = __webpack_require__(88829); +var Vector3 = __webpack_require__(70015); - this.defaultNormalMap = { glTexture: tempTexture }; +// Temp calculation segment +var segment = new Line(); - // Set the lights shaders - for (var i = 0; i < this.shaders.length; i++) - { - this['lightShader' + (i + 1)] = this.shaders[i]; - } - }, +// Temp vec3 +var tempIntersect = new Vector3(); - /** - * This function sets all the needed resources for each camera pass. - * - * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#onRender - * @ignore - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene being rendered. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered with. - */ - onRender: function (scene, camera) +/** + * 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, or ray, to check. If a ray, set the `isRay` parameter to `true`. + * @param {Phaser.Math.Vector2[] | Phaser.Geom.Point[]} points - An array of points to check. + * @param {boolean} [isRay=false] - Is `line` a ray or a line segment? + * @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, isRay, out) +{ + if (isRay === undefined) { isRay = false; } + 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 lightManager = scene.sys.lights; + var current = points[i]; - this.lightsActive = false; + segment.setTo(prev.x, prev.y, current.x, current.y); - if (!lightManager || !lightManager.active) + prev = current; + + if (GetLineToLine(line, segment, isRay, tempIntersect)) { - return; + if (!closestIntersect || tempIntersect.z < out.z) + { + out.copy(tempIntersect); + + closestIntersect = true; + } } + } - var lights = lightManager.getLights(camera); - var lightsCount = lights.length; + return (closestIntersect) ? out : null; +}; - if (lightsCount === 0) - { - return; - } +module.exports = GetLineToPoints; - // Ok, we're good to go ... - this.lightsActive = true; +/***/ }), - this.setShader(this['lightShader' + lightsCount], true); +/***/ 68439: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var i; - var renderer = this.renderer; - var height = renderer.height; - var cameraMatrix = camera.matrix; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.set1i('uMainSampler', 0); - this.set1i('uNormSampler', 1); - this.set2f('uResolution', this.width / 2, this.height / 2); - this.set4f('uCamera', camera.x, camera.y, camera.rotation, camera.zoom); - this.set3f('uAmbientLightColor', lightManager.ambientColor.r, lightManager.ambientColor.g, lightManager.ambientColor.b); +var Vector3 = __webpack_require__(70015); +var Vector4 = __webpack_require__(51729); +var GetLineToPoints = __webpack_require__(17647); - for (i = 0; i < lightsCount; i++) - { - var light = lights[i].light; - var color = light.color; +// Temp vec3 +var tempIntersect = new Vector3(); - var lightName = 'uLights[' + i + '].'; +/** + * 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, or ray, to check. If a ray, set the `isRay` parameter to `true`. + * @param {Phaser.Geom.Polygon | Phaser.Geom.Polygon[]} polygons - A single polygon, or array of polygons, to check. + * @param {boolean} [isRay=false] - Is `line` a ray or a line segment? + * @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, isRay, out) +{ + if (out === undefined) { out = new Vector4(); } - cameraMatrix.transformPoint(light.x, light.y, tempVec2); + if (!Array.isArray(polygons)) + { + polygons = [ polygons ]; + } - this.set2f(lightName + 'position', tempVec2.x - (camera.scrollX * light.scrollFactorX * camera.zoom), height - (tempVec2.y - (camera.scrollY * light.scrollFactorY) * camera.zoom)); - this.set3f(lightName + 'color', color.r, color.g, color.b); - this.set1f(lightName + 'intensity', light.intensity); - this.set1f(lightName + 'radius', light.radius); - } + var closestIntersect = false; - this.currentNormalMapRotation = null; - }, + // Reset our vec4s + out.set(); + tempIntersect.set(); - /** - * Rotates the normal map vectors inversely by the given angle. - * Only works in 2D space. - * - * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#setNormalMapRotation - * @since 3.16.0 - * - * @param {number} rotation - The angle of rotation in radians. - */ - setNormalMapRotation: function (rotation) + for (var i = 0; i < polygons.length; i++) { - if (rotation !== this.currentNormalMapRotation || this.vertexCount === 0) + if (GetLineToPoints(line, polygons[i].points, isRay, tempIntersect)) { - if (this.vertexCount > 0) + if (!closestIntersect || tempIntersect.z < out.z) { - this.flush(); + out.set(tempIntersect.x, tempIntersect.y, tempIntersect.z, i); + + closestIntersect = true; } + } + } - var inverseRotationMatrix = this.inverseRotationMatrix; + return (closestIntersect) ? out : null; +}; - if (rotation) - { - var rot = -rotation; - var c = Math.cos(rot); - var s = Math.sin(rot); +module.exports = GetLineToPolygon; - inverseRotationMatrix[1] = s; - inverseRotationMatrix[3] = -s; - inverseRotationMatrix[0] = inverseRotationMatrix[4] = c; - } - else - { - inverseRotationMatrix[0] = inverseRotationMatrix[4] = 1; - inverseRotationMatrix[1] = inverseRotationMatrix[3] = 0; - } - this.setMatrix3fv('uInverseRotationMatrix', false, inverseRotationMatrix); +/***/ }), - this.currentNormalMapRotation = rotation; - } - }, +/***/ 9569: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Assigns a texture to the current batch. If a different texture is already set it creates a new batch object. - * - * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#setTexture2D - * @ignore - * @since 3.50.0 - * - * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch. If not given uses blankTexture. - * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object being rendered or added to the batch. - */ - setTexture2D: function (texture, gameObject) +/** + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(79967); +var LineToLine = __webpack_require__(25227); +var LineToRectangle = __webpack_require__(47910); + +/** + * Checks for intersection between the Line and a Rectangle shape, + * and returns the intersection points as a Point object array. + * + * @function Phaser.Geom.Intersects.GetLineToRectangle + * @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. + * @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 GetLineToRectangle = function (line, rect, out) +{ + if (out === undefined) { out = []; } + + if (LineToRectangle(line, rect)) { - var renderer = this.renderer; + var lineA = rect.getLineA(); + var lineB = rect.getLineB(); + var lineC = rect.getLineC(); + var lineD = rect.getLineD(); - if (texture === undefined) { texture = renderer.tempTextures[0]; } + var output = [ new Point(), new Point(), new Point(), new Point() ]; - var normalTexture = this.getNormalMap(gameObject); + var result = [ + LineToLine(lineA, line, output[0]), + LineToLine(lineB, line, output[1]), + LineToLine(lineC, line, output[2]), + LineToLine(lineD, line, output[3]) + ]; - if (renderer.isNewNormalMap(texture, normalTexture)) + for (var i = 0; i < 4; i++) { - this.flush(); - - renderer.setTextureZero(texture); - renderer.setNormalMap(normalTexture); + if (result[i]) { out.push(output[i]); } } + } - var rotation = (gameObject) ? gameObject.rotation : 0; + return out; +}; - this.setNormalMapRotation(rotation); +module.exports = GetLineToRectangle; - this.currentUnit = 0; - return 0; - }, +/***/ }), - /** - * Custom pipelines can use this method in order to perform any required pre-batch tasks - * for the given Game Object. It must return the texture unit the Game Object was assigned. - * - * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#setGameObject - * @ignore - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object being rendered or added to the batch. - * @param {Phaser.Textures.Frame} [frame] - Optional frame to use. Can override that of the Game Object. - * - * @return {number} The texture unit the Game Object has been assigned. - */ - setGameObject: function (gameObject, frame) - { - if (frame === undefined) { frame = gameObject.frame; } +/***/ 7449: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var renderer = this.renderer; - var texture = frame.glTexture; - var normalTexture = this.getNormalMap(gameObject); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (renderer.isNewNormalMap()) - { - this.flush(); +var Vector4 = __webpack_require__(51729); +var GetLineToPolygon = __webpack_require__(68439); +var Line = __webpack_require__(88829); - renderer.setTextureZero(texture); - renderer.setNormalMap(normalTexture); - } +// Temp calculation segment +var segment = new Line(); - this.setNormalMapRotation(gameObject.rotation); +/** + * @ignore + */ +function CheckIntersects (angle, x, y, polygons, intersects) +{ + var dx = Math.cos(angle); + var dy = Math.sin(angle); - this.currentUnit = 0; + segment.setTo(x, y, x + dx, y + dy); - return 0; - }, + var closestIntersect = GetLineToPolygon(segment, polygons, true); - /** - * Returns the normal map WebGLTexture from the given Game Object. - * If the Game Object doesn't have one, it returns the default normal map from this pipeline instead. - * - * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#getNormalMap - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object to get the normal map from. - * - * @return {WebGLTexture} The normal map texture. - */ - getNormalMap: function (gameObject) + if (closestIntersect) { - var normalTexture; + intersects.push(new Vector4(closestIntersect.x, closestIntersect.y, angle, closestIntersect.w)); + } +} - if (!gameObject) - { - normalTexture = this.defaultNormalMap; - } - else if (gameObject.displayTexture) - { - normalTexture = gameObject.displayTexture.dataSource[gameObject.displayFrame.sourceIndex]; - } - else if (gameObject.texture) - { - normalTexture = gameObject.texture.dataSource[gameObject.frame.sourceIndex]; - } - else if (gameObject.tileset) - { - if (Array.isArray(gameObject.tileset)) - { - normalTexture = gameObject.tileset[0].image.dataSource[0]; - } - else - { - normalTexture = gameObject.tileset.image.dataSource[0]; - } - } +/** + * @ignore + */ +function SortIntersects (a, b) +{ + return a.z - b.z; +} - if (!normalTexture) - { - normalTexture = this.defaultNormalMap; - } +/** + * Projects rays out from the given point to each line segment of the polygons. + * + * If the rays intersect with the polygons, the points of intersection are returned in an array. + * + * If no intersections are found, the returned array will be empty. + * + * Each Vector4 intersection result has the following properties: + * + * The `x` and `y` components contain the point of the intersection. + * The `z` component contains the angle of intersection. + * The `w` component contains the index of the polygon, in the given array, that triggered the intersection. + * + * @function Phaser.Geom.Intersects.GetRaysFromPointToPolygon + * @since 3.50.0 + * + * @param {number} x - The x coordinate to project the rays from. + * @param {number} y - The y coordinate to project the rays from. + * @param {Phaser.Geom.Polygon | Phaser.Geom.Polygon[]} polygons - A single polygon, or array of polygons, to check against the rays. + * + * @return {Phaser.Math.Vector4[]} An array containing all intersections in Vector4s. + */ +var GetRaysFromPointToPolygon = function (x, y, polygons) +{ + if (!Array.isArray(polygons)) + { + polygons = [ polygons ]; + } - return normalTexture.glTexture; - }, + var intersects = []; + var angles = []; - /** - * Takes a Sprite Game Object, or any object that extends it, and adds it to the batch. - * - * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#batchSprite - * @since 3.50.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) + for (var i = 0; i < polygons.length; i++) { - if (this.lightsActive) - { - MultiPipeline.prototype.batchSprite.call(this, gameObject, camera, parentTransformMatrix); - } - }, + var points = polygons[i].points; - /** - * Generic function for batching a textured quad using argument values instead of a Game Object. - * - * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#batchTexture - * @since 3.50.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) - { - if (this.lightsActive) + for (var p = 0; p < points.length; p++) { - MultiPipeline.prototype.batchTexture.call( - this, - 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 - ); - } - }, + var angle = Math.atan2(points[p].y - y, points[p].x - x); - /** - * Adds a Texture Frame into the batch for rendering. - * - * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#batchTextureFrame - * @since 3.50.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 - ) - { - if (this.lightsActive) - { - MultiPipeline.prototype.batchTextureFrame.call( - this, - frame, - x, y, - tint, alpha, - transformMatrix, - parentTransformMatrix - ); + if (angles.indexOf(angle) === -1) + { + // +- 0.00001 rads to catch lines behind segment corners + + CheckIntersects(angle, x, y, polygons, intersects); + CheckIntersects(angle - 0.00001, x, y, polygons, intersects); + CheckIntersects(angle + 0.00001, x, y, polygons, intersects); + + angles.push(angle); + } } } -}); - -LightPipeline.LIGHT_COUNT = LIGHT_COUNT; + return intersects.sort(SortIntersects); +}; -module.exports = LightPipeline; +module.exports = GetRaysFromPointToPolygon; /***/ }), -/* 378 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 82931: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); -var PointLightShaderSourceFS = __webpack_require__(880); -var PointLightShaderSourceVS = __webpack_require__(881); -var WebGLPipeline = __webpack_require__(58); +var Rectangle = __webpack_require__(74118); +var RectangleToRectangle = __webpack_require__(90205); /** - * @classdesc - * The Point Light Pipeline handles rendering the Point Light Game Objects in WebGL. + * Checks if two Rectangle shapes intersect and returns the area of this intersection as Rectangle object. * - * The fragment shader it uses can be found in `shaders/src/PointLight.frag`. - * The vertex shader it uses can be found in `shaders/src/PointLight.vert`. + * If optional `output` parameter is omitted, new Rectangle object is created and returned. If there is intersection, it will contain intersection area. If there is no intersection, it wil be empty Rectangle (all values set to zero). * - * The default shader attributes for this pipeline are: + * If Rectangle object is passed as `output` and there is intersection, then intersection area data will be loaded into it and it will be returned. If there is no intersection, it will be returned without any change. * - * `inPosition` (vec2) - * `inLightPosition` (vec2) - * `inLightRadius` (float) - * `inLightAttenuation` (float) - * `inLightColor` (vec4) - * - * The default shader uniforms for this pipeline are: + * @function Phaser.Geom.Intersects.GetRectangleIntersection + * @since 3.0.0 * - * `uProjectionMatrix` (mat4) - * `uResolution` (vec2) - * `uCameraZoom` (sampler2D) + * @generic {Phaser.Geom.Rectangle} O - [output,$return] * - * @class PointLightPipeline - * @extends Phaser.Renderer.WebGL.WebGLPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.50.0 + * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle object. + * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle object. + * @param {Phaser.Geom.Rectangle} [output] - Optional Rectangle object. If given, the intersection data will be loaded into it (in case of no intersection, it will be left unchanged). Otherwise, new Rectangle object will be created and returned with either intersection data or empty (all values set to zero), if there is no intersection. * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + * @return {Phaser.Geom.Rectangle} A rectangle object with intersection data. */ -var PointLightPipeline = new Class({ - - Extends: WebGLPipeline, - - initialize: +var GetRectangleIntersection = function (rectA, rectB, output) +{ + if (output === undefined) { output = new Rectangle(); } - function PointLightPipeline (config) + if (RectangleToRectangle(rectA, rectB)) { - config.vertShader = GetFastValue(config, 'vertShader', PointLightShaderSourceVS); - config.fragShader = GetFastValue(config, 'fragShader', PointLightShaderSourceFS); - config.attributes = GetFastValue(config, 'attributes', [ - { - name: 'inPosition', - size: 2 - }, - { - name: 'inLightPosition', - size: 2 - }, - { - name: 'inLightRadius' - }, - { - name: 'inLightAttenuation' - }, - { - name: 'inLightColor', - size: 4 - } - ]); + output.x = Math.max(rectA.x, rectB.x); + output.y = Math.max(rectA.y, rectB.y); + output.width = Math.min(rectA.right, rectB.right) - output.x; + output.height = Math.min(rectA.bottom, rectB.bottom) - output.y; + } - WebGLPipeline.call(this, config); - }, + return output; +}; - onRender: function (scene, camera) - { - this.set2f('uResolution', this.width, this.height); - this.set1f('uCameraZoom', camera.zoom); - }, +module.exports = GetRectangleIntersection; - /** - * Adds a Point Light Game Object to the batch, flushing if required. - * - * @method Phaser.Renderer.WebGL.Pipelines.PointLightPipeline#batchPointLight - * @since 3.50.0 - * - * @param {Phaser.GameObjects.PointLight} light - The Point Light Game Object. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the Point Light. - * @param {number} x0 - The top-left x position. - * @param {number} y0 - The top-left y position. - * @param {number} x1 - The bottom-left x position. - * @param {number} y1 - The bottom-left y position. - * @param {number} x2 - The bottom-right x position. - * @param {number} y2 - The bottom-right y position. - * @param {number} x3 - The top-right x position. - * @param {number} y3 - The top-right y position. - * @param {number} lightX - The horizontal center of the light. - * @param {number} lightY - The vertical center of the light. - */ - batchPointLight: function (light, camera, x0, y0, x1, y1, x2, y2, x3, y3, lightX, lightY) - { - var color = light.color; - var intensity = light.intensity; - var radius = light.radius; - var attenuation = light.attenuation; - var r = color.r * intensity; - var g = color.g * intensity; - var b = color.b * intensity; - var a = camera.alpha * light.alpha; +/***/ }), - if (this.shouldFlush(6)) - { - this.flush(); - } +/***/ 1946: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.batchLightVert(x0, y0, lightX, lightY, radius, attenuation, r, g, b, a); - this.batchLightVert(x1, y1, lightX, lightY, radius, attenuation, r, g, b, a); - this.batchLightVert(x2, y2, lightX, lightY, radius, attenuation, r, g, b, a); - this.batchLightVert(x0, y0, lightX, lightY, radius, attenuation, r, g, b, a); - this.batchLightVert(x2, y2, lightX, lightY, radius, attenuation, r, g, b, a); - this.batchLightVert(x3, y3, lightX, lightY, radius, attenuation, r, g, b, a); - }, +/** + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Adds a single Point Light vertex to the current vertex buffer and increments the - * `vertexCount` property by 1. - * - * This method is called directly by `batchPointLight`. - * - * @method Phaser.Renderer.WebGL.Pipelines.PointLightPipeline#batchLightVert - * @since 3.50.0 - * - * @param {number} x - The vertex x position. - * @param {number} y - The vertex y position. - * @param {number} lightX - The horizontal center of the light. - * @param {number} lightY - The vertical center of the light. - * @param {number} radius - The radius of the light. - * @param {number} attenuation - The attenuation of the light. - * @param {number} r - The red color channel of the light. - * @param {number} g - The green color channel of the light. - * @param {number} b - The blue color channel of the light. - * @param {number} a - The alpha color channel of the light. - */ - batchLightVert: function (x, y, lightX, lightY, radius, attenuation, r, g, b, a) - { - var vertexViewF32 = this.vertexViewF32; +var GetLineToRectangle = __webpack_require__(9569); +var RectangleToRectangle = __webpack_require__(90205); - var vertexOffset = (this.vertexCount * this.currentShader.vertexComponentCount) - 1; +/** + * Checks if two Rectangles intersect and returns the intersection points as a Point object array. + * + * A Rectangle intersects another Rectangle if any part of its bounds is within the other Rectangle's bounds. As such, the two Rectangles are considered "solid". A Rectangle with no width or no height will never intersect another Rectangle. + * + * @function Phaser.Geom.Intersects.GetRectangleToRectangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to check for intersection. + * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to check for intersection. + * @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 GetRectangleToRectangle = function (rectA, rectB, out) +{ + if (out === undefined) { out = []; } - vertexViewF32[++vertexOffset] = x; - vertexViewF32[++vertexOffset] = y; - vertexViewF32[++vertexOffset] = lightX; - vertexViewF32[++vertexOffset] = lightY; - vertexViewF32[++vertexOffset] = radius; - vertexViewF32[++vertexOffset] = attenuation; - vertexViewF32[++vertexOffset] = r; - vertexViewF32[++vertexOffset] = g; - vertexViewF32[++vertexOffset] = b; - vertexViewF32[++vertexOffset] = a; + if (RectangleToRectangle(rectA, rectB)) + { + var lineA = rectA.getLineA(); + var lineB = rectA.getLineB(); + var lineC = rectA.getLineC(); + var lineD = rectA.getLineD(); - this.vertexCount++; + GetLineToRectangle(lineA, rectB, out); + GetLineToRectangle(lineB, rectB, out); + GetLineToRectangle(lineC, rectB, out); + GetLineToRectangle(lineD, rectB, out); } -}); + return out; +}; -module.exports = PointLightPipeline; +module.exports = GetRectangleToRectangle; /***/ }), -/* 379 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 34211: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); -var MultiPipeline = __webpack_require__(108); +var RectangleToTriangle = __webpack_require__(20370); +var GetLineToRectangle = __webpack_require__(9569); /** - * @classdesc - * The Rope Pipeline is a variation of the Multi Pipeline that uses a `TRIANGLE_STRIP` for - * its topology, instead of TRIANGLES. This is primarily used by the Rope Game Object, - * or anything that extends it. - * - * Prior to Phaser v3.50 this pipeline was called the `TextureTintStripPipeline`. - * - * 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) + * Checks for intersection between Rectangle shape and Triangle shape, + * and returns the intersection points as a Point object array. * - * The pipeline is structurally identical to the Multi Pipeline and should be treated as such. + * @function Phaser.Geom.Intersects.GetRectangleToTriangle + * @since 3.0.0 * - * @class RopePipeline - * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.50.0 + * @param {Phaser.Geom.Rectangle} rect - Rectangle object to test. + * @param {Phaser.Geom.Triangle} triangle - Triangle object to test. + * @param {array} [out] - An optional array in which to store the points of intersection. * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + * @return {array} An array with the points of intersection if objects intersect, otherwise an empty array. */ -var RopePipeline = new Class({ - - Extends: MultiPipeline, - - initialize: +var GetRectangleToTriangle = function (rect, triangle, out) +{ + if (out === undefined) { out = []; } - function RopePipeline (config) + if (RectangleToTriangle(rect, triangle)) { - // GLenum 5 = TRIANGLE_STRIP - config.topology = 5; - config.batchSize = GetFastValue(config, 'batchSize', 256); + var lineA = triangle.getLineA(); + var lineB = triangle.getLineB(); + var lineC = triangle.getLineC(); - MultiPipeline.call(this, config); + GetLineToRectangle(lineA, rect, out); + GetLineToRectangle(lineB, rect, out); + GetLineToRectangle(lineC, rect, out); } -}); -module.exports = RopePipeline; + return out; +}; + +module.exports = GetRectangleToTriangle; /***/ }), -/* 380 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 80511: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); -var MultiPipeline = __webpack_require__(108); -var ShaderSourceFS = __webpack_require__(882); -var ShaderSourceVS = __webpack_require__(883); -var WebGLPipeline = __webpack_require__(58); +var GetLineToCircle = __webpack_require__(26111); +var TriangleToCircle = __webpack_require__(48411); /** - * @classdesc - * The Single Pipeline is a special version of the Multi Pipeline that only ever - * uses one texture, bound to texture unit zero. Although not as efficient as the - * Multi Pipeline, it provides an easier way to create custom pipelines that only require - * a single bound texture. - * - * Prior to Phaser v3.50 this pipeline didn't exist, but could be compared to the old `TextureTintPipeline`. - * - * The fragment shader it uses can be found in `shaders/src/Single.frag`. - * The vertex shader it uses can be found in `shaders/src/Single.vert`. - * - * The default shader attributes for this pipeline are: - * - * `inPosition` (vec2, offset 0) - * `inTexCoord` (vec2, offset 8) - * `inTexId` (float, offset 16) - this value is always zero in the Single Pipeline - * `inTintEffect` (float, offset 20) - * `inTint` (vec4, offset 24, normalized) + * Checks if a Triangle and a Circle intersect, and returns the intersection points as a Point object array. * - * The default shader uniforms for this pipeline are: + * 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. * - * `uProjectionMatrix` (mat4) - * `uMainSampler` (sampler2D) + * @function Phaser.Geom.Intersects.GetTriangleToCircle + * @since 3.0.0 * - * @class SinglePipeline - * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.50.0 + * @param {Phaser.Geom.Triangle} triangle - The Triangle to check for intersection. + * @param {Phaser.Geom.Circle} circle - The Circle to check for intersection. + * @param {array} [out] - An optional array in which to store the points of intersection. * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + * @return {array} An array with the points of intersection if objects intersect, otherwise an empty array. */ -var SinglePipeline = new Class({ - - Extends: MultiPipeline, - - initialize: - - function SinglePipeline (config) - { - config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS), - config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS), - config.forceZero = true; - - MultiPipeline.call(this, config); - }, +var GetTriangleToCircle = function (triangle, circle, out) +{ + if (out === undefined) { out = []; } - boot: function () + if (TriangleToCircle(triangle, circle)) { - WebGLPipeline.prototype.boot.call(this); + var lineA = triangle.getLineA(); + var lineB = triangle.getLineB(); + var lineC = triangle.getLineC(); - this.set1i('uMainSampler', 0); + GetLineToCircle(lineA, circle, out); + GetLineToCircle(lineB, circle, out); + GetLineToCircle(lineC, circle, out); } -}); + return out; +}; -module.exports = SinglePipeline; +module.exports = GetTriangleToCircle; /***/ }), -/* 381 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 31343: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddBlendFS = __webpack_require__(884); -var BlendModes = __webpack_require__(35); -var Class = __webpack_require__(0); -var ColorMatrix = __webpack_require__(198); -var ColorMatrixFS = __webpack_require__(885); -var CopyFS = __webpack_require__(886); -var GetFastValue = __webpack_require__(2); -var LinearBlendFS = __webpack_require__(887); -var QuadVS = __webpack_require__(382); -var WebGLPipeline = __webpack_require__(58); +var Point = __webpack_require__(79967); +var TriangleToLine = __webpack_require__(86117); +var LineToLine = __webpack_require__(25227); /** - * @classdesc - * The Utility Pipeline is a special-use pipeline that belongs to the Pipeline Manager. - * - * It provides 4 shaders and handy associated methods: - * - * 1) Copy Shader. A fast texture to texture copy shader with optional brightness setting. - * 2) Additive Blend Mode Shader. Blends two textures using an additive blend mode. - * 3) Linear Blend Mode Shader. Blends two textures using a linear blend mode. - * 4) Color Matrix Copy Shader. Draws a texture to a target using a Color Matrix. - * - * You do not extend this pipeline, but instead get a reference to it from the Pipeline - * Manager via the `setUtility` method. You can also access methods such as `copyFrame` - * directly from the Pipeline Manager. - * - * This pipeline provides methods for manipulating framebuffer backed textures, such as - * copying or blending one texture to another, copying a portion of a texture, additively - * blending two textures, flipping textures and more. - * - * The default shader attributes for this pipeline are: + * Checks if a Triangle and a Line intersect, and returns the intersection points as a Point object array. * - * `inPosition` (vec2, offset 0) - * `inTexCoord` (vec2, offset 8) + * 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". * - * This pipeline has a hard-coded batch size of 1 and a hard coded set of vertices. + * @function Phaser.Geom.Intersects.GetTriangleToLine + * @since 3.0.0 * - * @class UtilityPipeline - * @extends Phaser.Renderer.WebGL.WebGLPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines - * @constructor - * @since 3.50.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. * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + * @return {array} An array with the points of intersection if objects intersect, otherwise an empty array. */ -var UtilityPipeline = new Class({ - - Extends: WebGLPipeline, - - initialize: +var GetTriangleToLine = function (triangle, line, out) +{ + if (out === undefined) { out = []; } - function UtilityPipeline (config) + if (TriangleToLine(triangle, line)) { - config.renderTarget = GetFastValue(config, 'renderTarget', [ - { - scale: 1 - }, - { - scale: 1 - }, - { - scale: 0.5 - }, - { - scale: 0.5 - } - ]); + var lineA = triangle.getLineA(); + var lineB = triangle.getLineB(); + var lineC = triangle.getLineC(); - config.vertShader = GetFastValue(config, 'vertShader', QuadVS); + var output = [ new Point(), new Point(), new Point() ]; - config.shaders = GetFastValue(config, 'shaders', [ - { - name: 'Copy', - fragShader: CopyFS - }, - { - name: 'AddBlend', - fragShader: AddBlendFS - }, - { - name: 'LinearBlend', - fragShader: LinearBlendFS - }, - { - name: 'ColorMatrix', - fragShader: ColorMatrixFS - } - ]); + var result = [ + LineToLine(lineA, line, output[0]), + LineToLine(lineB, line, output[1]), + LineToLine(lineC, line, output[2]) + ]; - config.attributes = GetFastValue(config, 'attributes', [ - { - name: 'inPosition', - size: 2 - }, - { - name: 'inTexCoord', - size: 2 - } - ]); + for (var i = 0; i < 3; i++) + { + if (result[i]) { out.push(output[i]); } + } + } - 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 - ]; + return out; +}; - config.batchSize = 1; +module.exports = GetTriangleToLine; - WebGLPipeline.call(this, config); - /** - * A default Color Matrix, used by the Color Matrix Shader when one - * isn't provided. - * - * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#colorMatrix - * @type {Phaser.Display.ColorMatrix} - * @since 3.50.0 - */ - this.colorMatrix = new ColorMatrix(); +/***/ }), - /** - * A reference to the Copy Shader belonging to this Utility Pipeline. - * - * This property is set during the `boot` method. - * - * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#copyShader - * @type {Phaser.Renderer.WebGL.WebGLShader} - * @default null - * @since 3.50.0 - */ - this.copyShader; +/***/ 70534: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A reference to the Additive Blend Shader belonging to this Utility Pipeline. - * - * This property is set during the `boot` method. - * - * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#addShader - * @type {Phaser.Renderer.WebGL.WebGLShader} - * @since 3.50.0 - */ - this.addShader; +/** + * @author Florian Vazelle + * @author Geoffrey Glaive + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A reference to the Linear Blend Shader belonging to this Utility Pipeline. - * - * This property is set during the `boot` method. - * - * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#linearShader - * @type {Phaser.Renderer.WebGL.WebGLShader} - * @since 3.50.0 - */ - this.linearShader; +var TriangleToTriangle = __webpack_require__(23589); +var GetTriangleToLine = __webpack_require__(31343); - /** - * A reference to the Color Matrix Shader belonging to this Utility Pipeline. - * - * This property is set during the `boot` method. - * - * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#colorMatrixShader - * @type {Phaser.Renderer.WebGL.WebGLShader} - * @since 3.50.0 - */ - this.colorMatrixShader; +/** + * Checks if two Triangles intersect, and returns the intersection points as a Point object array. + * + * 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.GetTriangleToTriangle + * @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. + * @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 GetTriangleToTriangle = function (triangleA, triangleB, out) +{ + if (out === undefined) { out = []; } - /** - * A reference to the Full Frame 1 Render Target. - * - * 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.UtilityPipeline#fullFrame1 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @since 3.50.0 - */ - this.fullFrame1; + if (TriangleToTriangle(triangleA, triangleB)) + { + var lineA = triangleB.getLineA(); + var lineB = triangleB.getLineB(); + var lineC = triangleB.getLineC(); - /** - * A reference to the Full Frame 2 Render Target. - * - * 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.UtilityPipeline#fullFrame2 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @since 3.50.0 - */ - this.fullFrame2; + GetTriangleToLine(triangleA, lineA, out); + GetTriangleToLine(triangleA, lineB, out); + GetTriangleToLine(triangleA, lineC, out); + } - /** - * A reference to the Half Frame 1 Render Target. - * - * 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.UtilityPipeline#halfFrame1 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @since 3.50.0 - */ - this.halfFrame1; + return out; +}; - /** - * A reference to the Half Frame 2 Render Target. - * - * 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.UtilityPipeline#halfFrame2 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @since 3.50.0 - */ - this.halfFrame2; - }, +module.exports = GetTriangleToTriangle; - boot: function () - { - WebGLPipeline.prototype.boot.call(this); - var shaders = this.shaders; - var targets = this.renderTargets; +/***/ }), - this.copyShader = shaders[0]; - this.addShader = shaders[1]; - this.linearShader = shaders[2]; - this.colorMatrixShader = shaders[3]; +/***/ 61472: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.fullFrame1 = targets[0]; - this.fullFrame2 = targets[1]; - this.halfFrame1 = targets[2]; - this.halfFrame2 = targets[3]; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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.UtilityPipeline#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) - { - if (brightness === undefined) { brightness = 1; } - if (clear === undefined) { clear = true; } - if (clearAlpha === undefined) { clearAlpha = true; } +var Contains = __webpack_require__(65650); +var Point = __webpack_require__(79967); - var gl = this.gl; +var tmp = new Point(); - this.setShader(this.copyShader); +/** + * Checks for intersection between the line segment and circle. + * + * Based on code by [Matt DesLauriers](https://github.com/mattdesl/line-circle-collision/blob/master/LICENSE.md). + * + * @function Phaser.Geom.Intersects.LineToCircle + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The line segment to check. + * @param {Phaser.Geom.Circle} circle - The circle to check against the line. + * @param {(Phaser.Geom.Point|any)} [nearest] - An optional Point-like object. If given the closest point on the Line where the circle intersects will be stored in this object. + * + * @return {boolean} `true` if the two objects intersect, otherwise `false`. + */ +var LineToCircle = function (line, circle, nearest) +{ + if (nearest === undefined) { nearest = tmp; } - this.set1i('uMainSampler', 0); - this.set1f('uBrightness', brightness); + if (Contains(circle, line.x1, line.y1)) + { + nearest.x = line.x1; + nearest.y = line.y1; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, source.texture); + return true; + } - 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); - } - else - { - gl.viewport(0, 0, source.width, source.height); - } + if (Contains(circle, line.x2, line.y2)) + { + nearest.x = line.x2; + nearest.y = line.y2; - if (clear) - { - if (clearAlpha) - { - gl.clearColor(0, 0, 0, 0); - } - else - { - gl.clearColor(0, 0, 0, 1); - } + return true; + } - gl.clear(gl.COLOR_BUFFER_BIT); - } + var dx = line.x2 - line.x1; + var dy = line.y2 - line.y1; - gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); - gl.drawArrays(gl.TRIANGLES, 0, 6); + var lcx = circle.x - line.x1; + var lcy = circle.y - line.y1; - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.bindTexture(gl.TEXTURE_2D, null); - }, + // project lc onto d, resulting in vector p + var dLen2 = (dx * dx) + (dy * dy); + var px = dx; + var py = dy; - /** - * 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.UtilityPipeline#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) + if (dLen2 > 0) { - if (brightness === undefined) { brightness = 1; } - if (clear === undefined) { clear = true; } - if (clearAlpha === undefined) { clearAlpha = true; } - if (eraseMode === undefined) { eraseMode = false; } - - var gl = this.gl; + var dp = ((lcx * dx) + (lcy * dy)) / dLen2; - this.setShader(this.copyShader); + px *= dp; + py *= dp; + } - this.set1i('uMainSampler', 0); - this.set1f('uBrightness', brightness); + nearest.x = line.x1 + px; + nearest.y = line.y1 + py; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, source.texture); + // len2 of p + var pLen2 = (px * px) + (py * py); - if (source.height > target.height) - { - gl.viewport(0, 0, source.width, source.height); + return ( + pLen2 <= dLen2 && + ((px * dx) + (py * dy)) >= 0 && + Contains(circle, nearest.x, nearest.y) + ); +}; - this.setTargetUVs(source, target); - } - else - { - var diff = target.height - source.height; +module.exports = LineToCircle; - gl.viewport(0, diff, source.width, source.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); - } +/***/ 25227: +/***/ ((module) => { - gl.clear(gl.COLOR_BUFFER_BIT); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (eraseMode) - { - var blendMode = this.renderer.currentBlendMode; +// This is based off an explanation and expanded math presented by Paul Bourke: +// See http://paulbourke.net/geometry/pointlineplane/ - this.renderer.setBlendMode(BlendModes.ERASE); - } +/** + * Checks if two Lines intersect. If the Lines are identical, they will be treated as parallel and thus non-intersecting. + * + * @function Phaser.Geom.Intersects.LineToLine + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line1 - The first Line to check. + * @param {Phaser.Geom.Line} line2 - The second Line to check. + * @param {Phaser.Types.Math.Vector2Like} [out] - An optional point-like object in which to store the coordinates of intersection, if needed. + * + * @return {boolean} `true` if the two Lines intersect, and the `out` object will be populated, if given. Otherwise, `false`. + */ +var LineToLine = function (line1, line2, out) +{ + var x1 = line1.x1; + var y1 = line1.y1; + var x2 = line1.x2; + var y2 = line1.y2; - gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); - gl.drawArrays(gl.TRIANGLES, 0, 6); + var x3 = line2.x1; + var y3 = line2.y1; + var x4 = line2.x2; + var y4 = line2.y2; - if (eraseMode) - { - this.renderer.setBlendMode(blendMode); - } + // Check that none of the lines are length zero + if ((x1 === x2 && y1 === y2) || (x3 === x4 && y3 === y4)) + { + return false; + } - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.bindTexture(gl.TEXTURE_2D, null); + var denom = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); - this.resetUVs(); - }, + // 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). - /** - * 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.UtilityPipeline#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) + if (denom === 0) { - if (clear === undefined) { clear = true; } - if (clearAlpha === undefined) { clearAlpha = true; } + // Lines are parallel + return false; + } - var gl = this.gl; + // Calculate the intermediate fractional point that the lines potentially intersect. - gl.bindFramebuffer(gl.FRAMEBUFFER, source.framebuffer); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, source.texture, 0); + var ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom; + var ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom; - if (clear) - { - if (clearAlpha) - { - gl.clearColor(0, 0, 0, 0); - } - else - { - gl.clearColor(0, 0, 0, 1); - } + // The fractional point will be between 0 and 1 inclusive if the lines intersect. + // If the fractional calculation is larger than 1 or smaller than 0 the lines would need to be longer to intersect. - gl.clear(gl.COLOR_BUFFER_BIT); + if (ua < 0 || ua > 1 || ub < 0 || ub > 1) + { + return false; + } + else + { + if (out) + { + out.x = x1 + ua * (x2 - x1); + out.y = y1 + ua * (y2 - y1); } - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, target.texture); - - gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, x, y, width, height); - - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.bindTexture(gl.TEXTURE_2D, null); - }, + return true; + } +}; - /** - * 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.UtilityPipeline#copyToGame - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. - */ - copyToGame: function (source) - { - var gl = this.gl; +module.exports = LineToLine; - this.setShader(this.copyShader); - this.set1i('uMainSampler', 0); - this.set1f('uBrightness', 1); +/***/ }), - this.renderer.popFramebuffer(); +/***/ 47910: +/***/ ((module) => { - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, source.texture); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); - gl.drawArrays(gl.TRIANGLES, 0, 6); +/** + * 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; - this.renderer.resetTextures(); - }, + var x2 = line.x2; + var y2 = line.y2; - /** - * 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.UtilityPipeline#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? - * @param {Phaser.Display.ColorMatrix} [colorMatrix] - The Color Matrix to use when performing the draw. - */ - drawFrame: function (source, target, clearAlpha, colorMatrix) - { - if (clearAlpha === undefined) { clearAlpha = true; } - if (colorMatrix === undefined) { colorMatrix = this.colorMatrix; } + var bx1 = rect.x; + var by1 = rect.y; + var bx2 = rect.right; + var by2 = rect.bottom; - var gl = this.gl; + var t = 0; - this.setShader(this.colorMatrixShader); + // If the start or end of the line is inside the rect then we assume + // collision, as rects are solid for our use-case. - this.set1i('uMainSampler', 0); - this.set1fv('uColorMatrix', colorMatrix.getData()); - this.set1f('uAlpha', colorMatrix.alpha); + if ((x1 >= bx1 && x1 <= bx2 && y1 >= by1 && y1 <= by2) || + (x2 >= bx1 && x2 <= bx2 && y2 >= by1 && y2 <= by2)) + { + return true; + } - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, source.texture); + if (x1 < bx1 && x2 >= bx1) + { + // Left edge + t = y1 + (y2 - y1) * (bx1 - x1) / (x2 - x1); - if (target) + if (t > by1 && t <= by2) { - 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); + return true; } - else + } + else if (x1 > bx2 && x2 <= bx2) + { + // Right edge + t = y1 + (y2 - y1) * (bx2 - x1) / (x2 - x1); + + if (t >= by1 && t <= by2) { - gl.viewport(0, 0, source.width, source.height); + return true; } + } - if (clearAlpha) + if (y1 < by1 && y2 >= by1) + { + // Top edge + t = x1 + (x2 - x1) * (by1 - y1) / (y2 - y1); + + if (t >= bx1 && t <= bx2) { - gl.clearColor(0, 0, 0, 0); + return true; } - else + } + else if (y1 > by2 && y2 <= by2) + { + // Bottom edge + t = x1 + (x2 - x1) * (by2 - y1) / (y2 - y1); + + if (t >= bx1 && t <= bx2) { - gl.clearColor(0, 0, 0, 1); + return true; } + } - gl.clear(gl.COLOR_BUFFER_BIT); + return false; +}; - gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); - gl.drawArrays(gl.TRIANGLES, 0, 6); +module.exports = LineToRectangle; - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.bindTexture(gl.TEXTURE_2D, null); - }, - /** - * 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.UtilityPipeline#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? - * @param {Phaser.Renderer.WebGL.WebGLShader} [blendShader] - The shader to use during the blend copy. - */ - blendFrames: function (source1, source2, target, strength, clearAlpha, blendShader) - { - if (strength === undefined) { strength = 1; } - if (clearAlpha === undefined) { clearAlpha = true; } - if (blendShader === undefined) { blendShader = this.linearShader; } - - var gl = this.gl; +/***/ }), - this.setShader(blendShader); +/***/ 34426: +/***/ ((module) => { - this.set1i('uMainSampler1', 0); - this.set1i('uMainSampler2', 1); - this.set1f('uStrength', strength); +/** + * @author Richard Davey + * @author Florian Mertens + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, source1.texture); +/** + * 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; } - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, source2.texture); + var x1 = line.x1; + var y1 = line.y1; - if (target) - { - gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture, 0); - gl.viewport(0, 0, target.width, target.height); - } - else - { - gl.viewport(0, 0, source1.width, source1.height); - } + var x2 = line.x2; + var y2 = line.y2; - if (clearAlpha) - { - gl.clearColor(0, 0, 0, 0); - } - else - { - gl.clearColor(0, 0, 0, 1); - } + var px = point.x; + var py = point.y; - gl.clear(gl.COLOR_BUFFER_BIT); + var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); - gl.drawArrays(gl.TRIANGLES, 0, 6); + if (L2 === 0) + { + return false; + } - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.bindTexture(gl.TEXTURE_2D, null); - }, + var r = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1))) / L2; - /** - * 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.UtilityPipeline#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) + // Assume line thickness is circular + if (r < 0) { - this.blendFrames(source1, source2, target, strength, clearAlpha, this.addShader); - }, - - /** - * Clears the given Render Target. - * - * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#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) + // Outside line1 + return (Math.sqrt(((x1 - px) * (x1 - px)) + ((y1 - py) * (y1 - py))) <= lineThickness); + } + else if ((r >= 0) && (r <= 1)) { - if (clearAlpha === undefined) { clearAlpha = true; } + // On the line segment + var s = (((y1 - py) * (x2 - x1)) - ((x1 - px) * (y2 - y1))) / L2; - var gl = this.gl; + return (Math.abs(s) * Math.sqrt(L2) <= lineThickness); + } + else + { + // Outside line2 + return (Math.sqrt(((x2 - px) * (x2 - px)) + ((y2 - py) * (y2 - py))) <= lineThickness); + } +}; - gl.viewport(0, 0, target.width, target.height); +module.exports = PointToLine; - gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); - if (clearAlpha) - { - gl.clearColor(0, 0, 0, 0); - } - else - { - gl.clearColor(0, 0, 0, 1); - } +/***/ }), - gl.clear(gl.COLOR_BUFFER_BIT); +/***/ 81414: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var fbo = this.renderer.currentFramebuffer; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); - }, +var PointToLine = __webpack_require__(34426); - /** - * Set the UV values for the 6 vertices that make up the quad used by the shaders - * in the Utility Pipeline. - * - * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. - * - * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#setUVs - * @since 3.50.0 - * - * @param {number} uA - The u value of vertex A. - * @param {number} vA - The v value of vertex A. - * @param {number} uB - The u value of vertex B. - * @param {number} vB - The v value of vertex B. - * @param {number} uC - The u value of vertex C. - * @param {number} vC - The v value of vertex C. - * @param {number} uD - The u value of vertex D. - * @param {number} vD - The v value of vertex D. - */ - setUVs: function (uA, vA, uB, vB, uC, vC, uD, vD) +/** + * Checks if a Point is located on the given line segment. + * + * @function Phaser.Geom.Intersects.PointToLineSegment + * @since 3.0.0 + * + * @param {Phaser.Geom.Point} point - The Point to check for intersection. + * @param {Phaser.Geom.Line} line - The line segment to check for intersection. + * + * @return {boolean} `true` if the Point is on the given line segment, otherwise `false`. + */ +var PointToLineSegment = function (point, line) +{ + if (!PointToLine(point, line)) { - var vertexViewF32 = this.vertexViewF32; + return false; + } - vertexViewF32[2] = uA; - vertexViewF32[3] = vA; - vertexViewF32[6] = uB; - vertexViewF32[7] = vB; - vertexViewF32[10] = uC; - vertexViewF32[11] = vC; - vertexViewF32[14] = uA; - vertexViewF32[15] = vA; - vertexViewF32[18] = uC; - vertexViewF32[19] = vC; - vertexViewF32[22] = uD; - vertexViewF32[23] = vD; - }, + var xMin = Math.min(line.x1, line.x2); + var xMax = Math.max(line.x1, line.x2); + var yMin = Math.min(line.y1, line.y2); + var yMax = Math.max(line.y1, line.y2); - /** - * Sets the vertex UV coordinates of the quad used by the shaders in the Utility Pipeline - * so that they correctly adjust the texture coordinates for a blit frame effect. - * - * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. - * - * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#setTargetUVs - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. - * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. - */ - setTargetUVs: function (source, target) - { - var diff = (target.height / source.height); + return ((point.x >= xMin && point.x <= xMax) && (point.y >= yMin && point.y <= yMax)); +}; - if (diff > 0.5) - { - diff = 0.5 - (diff - 0.5); - } - else - { - diff = 0.5 + (0.5 - diff); - } +module.exports = PointToLineSegment; - this.setUVs(0, diff, 0, 1 + diff, 1, 1 + diff, 1, diff); - }, - /** - * Horizontally flips the UV coordinates of the quad used by the shaders in this - * Utility Pipeline. - * - * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. - * - * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#flipX - * @since 3.50.0 - */ - flipX: function () - { - this.setUVs(1, 0, 1, 1, 0, 1, 0, 0); - }, +/***/ }), - /** - * Vertically flips the UV coordinates of the quad used by the shaders in this - * Utility Pipeline. - * - * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. - * - * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#flipY - * @since 3.50.0 - */ - flipY: function () - { - this.setUVs(0, 1, 0, 0, 1, 0, 1, 1); - }, +/***/ 90205: +/***/ ((module) => { - /** - * Resets the quad vertice UV values to their default settings. - * - * The quad is used by all shaders of the Utility Pipeline. - * - * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#resetUVs - * @since 3.50.0 - */ - resetUVs: function () +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks if two Rectangles intersect. + * + * A Rectangle intersects another Rectangle if any part of its bounds is within the other Rectangle's bounds. + * As such, the two Rectangles are considered "solid". + * A Rectangle with no width or no height will never intersect another Rectangle. + * + * @function Phaser.Geom.Intersects.RectangleToRectangle + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to check for intersection. + * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to check for intersection. + * + * @return {boolean} `true` if the two Rectangles intersect, otherwise `false`. + */ +var RectangleToRectangle = function (rectA, rectB) +{ + if (rectA.width <= 0 || rectA.height <= 0 || rectB.width <= 0 || rectB.height <= 0) { - this.setUVs(0, 0, 0, 1, 1, 1, 1, 0); + return false; } -}); + return !(rectA.right < rectB.x || rectA.bottom < rectB.y || rectA.x > rectB.right || rectA.y > rectB.bottom); +}; -module.exports = UtilityPipeline; +module.exports = RectangleToRectangle; /***/ }), -/* 382 */ -/***/ (function(module, exports) { - -module.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'); - -/***/ }), -/* 383 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 20370: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CanvasPool = __webpack_require__(31); -var Color = __webpack_require__(38); -var GetFastValue = __webpack_require__(2); +var LineToLine = __webpack_require__(25227); +var Contains = __webpack_require__(94287); +var ContainsArray = __webpack_require__(86875); +var Decompose = __webpack_require__(87279); /** - * Takes a snapshot of an area from the current frame displayed by a WebGL canvas. - * - * This is then copied to an Image object. When this loads, the results are sent - * to the callback provided in the Snapshot Configuration object. + * Checks for intersection between Rectangle shape and Triangle shape. * - * @function Phaser.Renderer.Snapshot.WebGL + * @function Phaser.Geom.Intersects.RectangleToTriangle * @since 3.0.0 * - * @param {HTMLCanvasElement} sourceCanvas - The canvas to take a snapshot of. - * @param {Phaser.Types.Renderer.Snapshot.SnapshotState} config - The snapshot configuration object. + * @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 WebGLSnapshot = function (sourceCanvas, config) +var RectangleToTriangle = function (rect, triangle) { - var gl = sourceCanvas.getContext('experimental-webgl'); - - var callback = GetFastValue(config, 'callback'); - var type = GetFastValue(config, 'type', 'image/png'); - var encoderOptions = GetFastValue(config, 'encoder', 0.92); - var x = GetFastValue(config, 'x', 0); - var y = GetFastValue(config, 'y', 0); - - var getPixel = GetFastValue(config, 'getPixel', false); - - var isFramebuffer = GetFastValue(config, 'isFramebuffer', false); - - var bufferWidth = (isFramebuffer) ? GetFastValue(config, 'bufferWidth', 1) : gl.drawingBufferWidth; - var bufferHeight = (isFramebuffer) ? GetFastValue(config, 'bufferHeight', 1) : gl.drawingBufferHeight; + // First the cheapest ones: - if (getPixel) + if ( + triangle.left > rect.right || + triangle.right < rect.left || + triangle.top > rect.bottom || + triangle.bottom < rect.top) { - var pixel = new Uint8Array(4); + return false; + } - var destY = (isFramebuffer) ? y : bufferHeight - y; + var triA = triangle.getLineA(); + var triB = triangle.getLineB(); + var triC = triangle.getLineC(); - gl.readPixels(x, destY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel); + // Are any of the triangle points within the rectangle? - callback.call(null, new Color(pixel[0], pixel[1], pixel[2], pixel[3] / 255)); + if (Contains(rect, triA.x1, triA.y1) || Contains(rect, triA.x2, triA.y2)) + { + return true; } - else + + if (Contains(rect, triB.x1, triB.y1) || Contains(rect, triB.x2, triB.y2)) { - var width = GetFastValue(config, 'width', bufferWidth); - var height = GetFastValue(config, 'height', bufferHeight); + return true; + } - var total = width * height * 4; + if (Contains(rect, triC.x1, triC.y1) || Contains(rect, triC.x2, triC.y2)) + { + return true; + } - var pixels = new Uint8Array(total); + // Cheap tests over, now to see if any of the lines intersect ... - gl.readPixels(x, bufferHeight - y - height, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + var rectA = rect.getLineA(); + var rectB = rect.getLineB(); + var rectC = rect.getLineC(); + var rectD = rect.getLineD(); - var canvas = CanvasPool.createWebGL(this, width, height); - var ctx = canvas.getContext('2d'); + if (LineToLine(triA, rectA) || LineToLine(triA, rectB) || LineToLine(triA, rectC) || LineToLine(triA, rectD)) + { + return true; + } - var imageData = ctx.getImageData(0, 0, width, height); + if (LineToLine(triB, rectA) || LineToLine(triB, rectB) || LineToLine(triB, rectC) || LineToLine(triB, rectD)) + { + return true; + } - var data = imageData.data; + if (LineToLine(triC, rectA) || LineToLine(triC, rectB) || LineToLine(triC, rectC) || LineToLine(triC, rectD)) + { + return true; + } - // var destIndex = (isFramebuffer) ? total - ((py * width + (width - px)) * 4) : (py * width + px) * 4; + // None of the lines intersect, so are any rectangle points within the triangle? - for (var py = 0; py < height; py++) - { - for (var px = 0; px < width; px++) - { - var sourceIndex = ((height - py - 1) * width + px) * 4; - var destIndex = (py * width + px) * 4; + var points = Decompose(rect); + var within = ContainsArray(triangle, points, true); - data[destIndex + 0] = pixels[sourceIndex + 0]; - data[destIndex + 1] = pixels[sourceIndex + 1]; - data[destIndex + 2] = pixels[sourceIndex + 2]; - data[destIndex + 3] = pixels[sourceIndex + 3]; - } - } + return (within.length > 0); +}; - ctx.putImageData(imageData, 0, 0); +module.exports = RectangleToTriangle; - var image = new Image(); - image.onerror = function () - { - callback.call(null); +/***/ }), - CanvasPool.remove(canvas); - }; +/***/ 8786: +/***/ ((module) => { - image.onload = function () - { - callback.call(null, image); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - CanvasPool.remove(canvas); - }; +/** + * Check if rectangle intersects with values. + * + * @function Phaser.Geom.Intersects.RectangleToValues + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - The rectangle object + * @param {number} left - The x coordinate of the left of the Rectangle. + * @param {number} right - The x coordinate of the right of the Rectangle. + * @param {number} top - The y coordinate of the top of the Rectangle. + * @param {number} bottom - The y coordinate of the bottom of the Rectangle. + * @param {number} [tolerance=0] - Tolerance allowed in the calculation, expressed in pixels. + * + * @return {boolean} Returns true if there is an intersection. + */ +var RectangleToValues = function (rect, left, right, top, bottom, tolerance) +{ + if (tolerance === undefined) { tolerance = 0; } - image.src = canvas.toDataURL(type, encoderOptions); - } + return !( + left > rect.right + tolerance || + right < rect.left - tolerance || + top > rect.bottom + tolerance || + bottom < rect.top - tolerance + ); }; -module.exports = WebGLSnapshot; +module.exports = RectangleToValues; /***/ }), -/* 384 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 48411: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(33); +var LineToCircle = __webpack_require__(61472); +var Contains = __webpack_require__(60689); /** - * Called automatically by Phaser.Game and responsible for creating the console.log debug header. + * Checks if a Triangle and a Circle intersect. * - * You can customize or disable the header via the Game Config object. + * 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.Core.DebugHeader + * @function Phaser.Geom.Intersects.TriangleToCircle * @since 3.0.0 * - * @param {Phaser.Game} game - The Phaser.Game instance which will output this debug header. + * @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 DebugHeader = function (game) +var TriangleToCircle = function (triangle, circle) { - var config = game.config; + // First the cheapest ones: - if (config.hideBanner) + if ( + triangle.left > circle.right || + triangle.right < circle.left || + triangle.top > circle.bottom || + triangle.bottom < circle.top) { - return; + return false; } - var renderType = 'WebGL'; + if (Contains(triangle, circle.x, circle.y)) + { + return true; + } - if (config.renderType === CONST.CANVAS) + if (LineToCircle(triangle.getLineA(), circle)) { - renderType = 'Canvas'; + return true; } - else if (config.renderType === CONST.HEADLESS) + + if (LineToCircle(triangle.getLineB(), circle)) { - renderType = 'Headless'; + return true; } - var audioConfig = config.audio; - var deviceAudio = game.device.audio; + if (LineToCircle(triangle.getLineC(), circle)) + { + return true; + } - var audioType; + return false; +}; - if (deviceAudio.webAudio && !audioConfig.disableWebAudio) +module.exports = TriangleToCircle; + + +/***/ }), + +/***/ 86117: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var LineToLine = __webpack_require__(25227); + +/** + * 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)) { - audioType = 'Web Audio'; + return true; } - else if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) + + // Now check the line against each line of the Triangle + if (LineToLine(triangle.getLineA(), line)) { - audioType = 'No Audio'; + return true; } - else + + if (LineToLine(triangle.getLineB(), line)) { - audioType = 'HTML5 Audio'; + return true; } - if (!game.device.browser.ie) + if (LineToLine(triangle.getLineC(), line)) { - var c = ''; - var args = [ c ]; + return true; + } - if (Array.isArray(config.bannerBackgroundColor)) - { - var lastColor; + return false; +}; - config.bannerBackgroundColor.forEach(function (color) - { - c = c.concat('%c '); +module.exports = TriangleToLine; - args.push('background: ' + color); - lastColor = color; +/***/ }), - }); +/***/ 23589: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // inject the text color - args[args.length - 1] = 'color: ' + config.bannerTextColor + '; background: ' + lastColor; - } - else - { - c = c.concat('%c '); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - args.push('color: ' + config.bannerTextColor + '; background: ' + config.bannerBackgroundColor); - } +var ContainsArray = __webpack_require__(86875); +var Decompose = __webpack_require__(18680); +var LineToLine = __webpack_require__(25227); - // URL link background color (always transparent to support different browser themes) - args.push('background: transparent'); +/** + * 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 (config.gameTitle) - { - c = c.concat(config.gameTitle); + if ( + triangleA.left > triangleB.right || + triangleA.right < triangleB.left || + triangleA.top > triangleB.bottom || + triangleA.bottom < triangleB.top) + { + return false; + } - if (config.gameVersion) - { - c = c.concat(' v' + config.gameVersion); - } + var lineAA = triangleA.getLineA(); + var lineAB = triangleA.getLineB(); + var lineAC = triangleA.getLineC(); - if (!config.hidePhaser) - { - c = c.concat(' / '); - } - } + var lineBA = triangleB.getLineA(); + var lineBB = triangleB.getLineB(); + var lineBC = triangleB.getLineC(); - var fb = ( false) ? undefined : ''; + // Now check the lines against each line of TriangleB + if (LineToLine(lineAA, lineBA) || LineToLine(lineAA, lineBB) || LineToLine(lineAA, lineBC)) + { + return true; + } - if (!config.hidePhaser) - { - c = c.concat('Phaser v' + CONST.VERSION + fb + ' (' + renderType + ' | ' + audioType + ')'); - } + if (LineToLine(lineAB, lineBA) || LineToLine(lineAB, lineBB) || LineToLine(lineAB, lineBC)) + { + return true; + } - c = c.concat(' %c ' + config.gameURL); + if (LineToLine(lineAC, lineBA) || LineToLine(lineAC, lineBB) || LineToLine(lineAC, lineBC)) + { + return true; + } - // Inject the new string back into the args array - args[0] = c; + // Nope, so check to see if any of the points of triangleA are within triangleB - console.log.apply(console, args); + var points = Decompose(triangleA); + var within = ContainsArray(triangleB, points, true); + + if (within.length > 0) + { + return true; } - else if (window['console']) + + // 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) { - console.log('Phaser v' + CONST.VERSION + ' / https://phaser.io'); + return true; } + + return false; }; -module.exports = DebugHeader; +module.exports = TriangleToTriangle; /***/ }), -/* 385 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 7563: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(386); +/** + * @namespace Phaser.Geom.Intersects + */ + +module.exports = { + + CircleToCircle: __webpack_require__(22184), + CircleToRectangle: __webpack_require__(26535), + GetCircleToCircle: __webpack_require__(71145), + GetCircleToRectangle: __webpack_require__(62508), + GetLineToCircle: __webpack_require__(26111), + GetLineToLine: __webpack_require__(96537), + GetLineToPoints: __webpack_require__(17647), + GetLineToPolygon: __webpack_require__(68439), + GetLineToRectangle: __webpack_require__(9569), + GetRaysFromPointToPolygon: __webpack_require__(7449), + GetRectangleIntersection: __webpack_require__(82931), + GetRectangleToRectangle: __webpack_require__(1946), + GetRectangleToTriangle: __webpack_require__(34211), + GetTriangleToCircle: __webpack_require__(80511), + GetTriangleToLine: __webpack_require__(31343), + GetTriangleToTriangle: __webpack_require__(70534), + LineToCircle: __webpack_require__(61472), + LineToLine: __webpack_require__(25227), + LineToRectangle: __webpack_require__(47910), + PointToLine: __webpack_require__(34426), + PointToLineSegment: __webpack_require__(81414), + RectangleToRectangle: __webpack_require__(90205), + RectangleToTriangle: __webpack_require__(20370), + RectangleToValues: __webpack_require__(8786), + TriangleToCircle: __webpack_require__(48411), + TriangleToLine: __webpack_require__(86117), + TriangleToTriangle: __webpack_require__(23589) + +}; -// http://www.testufo.com/#test=animation-time-graph + +/***/ }), + +/***/ 50599: +/***/ ((module) => { /** - * @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. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the angle of the line in radians. * - * @class TimeStep - * @memberof Phaser.Core - * @constructor + * @function Phaser.Geom.Line.Angle * @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 + * @param {Phaser.Geom.Line} line - The line to calculate the angle of. + * + * @return {number} The angle of the line, in radians. */ -var TimeStep = new Class({ +var Angle = function (line) +{ + return Math.atan2(line.y2 - line.y1, line.x2 - line.x1); +}; - initialize: +module.exports = Angle; - 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; +/***/ 58813: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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); +/** + * Using Bresenham's line algorithm this will return an array of all coordinates on this line. + * + * The `start` and `end` points are rounded before this runs as the algorithm works on integers. + * + * @function Phaser.Geom.Line.BresenhamPoints + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The line. + * @param {number} [stepRate=1] - The optional step rate for the points on the line. + * @param {Phaser.Types.Math.Vector2Like[]} [results] - An optional array to push the resulting coordinates into. + * + * @return {Phaser.Types.Math.Vector2Like[]} The array of coordinates on the line. + */ +var BresenhamPoints = function (line, stepRate, results) +{ + if (stepRate === undefined) { stepRate = 1; } + if (results === undefined) { results = []; } - /** - * 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); + var x1 = Math.round(line.x1); + var y1 = Math.round(line.y1); + var x2 = Math.round(line.x2); + var y2 = Math.round(line.y2); - /** - * 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; + var dx = Math.abs(x2 - x1); + var dy = Math.abs(y2 - y1); + var sx = (x1 < x2) ? 1 : -1; + var sy = (y1 < y2) ? 1 : -1; + var err = dx - dy; - /** - * 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; + results.push({ x: x1, y: y1 }); - /** - * 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; + var i = 1; - /** - * 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; + while (!((x1 === x2) && (y1 === y2))) + { + var e2 = err << 1; - /** - * The number of frames processed this second. - * - * @name Phaser.Core.TimeStep#framesThisSecond - * @type {number} - * @readonly - * @default 0 - * @since 3.0.0 - */ - this.framesThisSecond = 0; + if (e2 > -dy) + { + err -= dy; + x1 += sx; + } - /** - * 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; + if (e2 < dx) + { + err += dx; + y1 += sy; + } - /** - * 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); + if (i % stepRate === 0) + { + results.push({ x: x1, y: y1 }); + } - /** - * 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; + i++; + } - /** - * 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; + return results; +}; - /** - * 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; +module.exports = BresenhamPoints; - /** - * 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; +/***/ 88513: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +/** + * Center a line on the given coordinates. + * + * @function Phaser.Geom.Line.CenterOn + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The line to center. + * @param {number} x - The horizontal coordinate to center the line on. + * @param {number} y - The vertical coordinate to center the line on. + * + * @return {Phaser.Geom.Line} The centered line. + */ +var CenterOn = function (line, x, y) +{ + var tx = x - ((line.x1 + line.x2) / 2); + var ty = y - ((line.y1 + line.y2) / 2); - /** - * Internal array holding the previous delta values, used for delta smoothing. - * - * @name Phaser.Core.TimeStep#deltaHistory - * @type {number[]} - * @since 3.0.0 - */ - this.deltaHistory = []; + line.x1 += tx; + line.y1 += ty; - /** - * 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; + line.x2 += tx; + line.y2 += ty; - /** - * 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; + return line; +}; - /** - * 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); - }, +module.exports = CenterOn; - /** - * 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(); - }, +/***/ 26718: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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(); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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(); +var Line = __webpack_require__(88829); - this.startTime += this.time - this._pauseTime; - }, +/** + * Clone the given line. + * + * @function Phaser.Geom.Line.Clone + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} source - The source line to clone. + * + * @return {Phaser.Geom.Line} The cloned line. + */ +var Clone = function (source) +{ + return new Line(source.x1, source.y1, source.x2, source.y2); +}; - /** - * 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(); +module.exports = Clone; - 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]); - } +/***/ 88930: +/***/ ((module) => { - this.delta = 0; - this.deltaIndex = 0; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this._coolDown = this.panicMax; - }, +/** + * Copy the values of one line to a destination line. + * + * @function Phaser.Geom.Line.CopyFrom + * @since 3.0.0 + * + * @generic {Phaser.Geom.Line} O - [dest,$return] + * + * @param {Phaser.Geom.Line} source - The source line to copy the values from. + * @param {Phaser.Geom.Line} dest - The destination line to copy the values to. + * + * @return {Phaser.Geom.Line} The destination line. + */ +var CopyFrom = function (source, dest) +{ + return dest.setTo(source.x1, source.y1, source.x2, source.y2); +}; - /** - * 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; - } +module.exports = CopyFrom; - this.started = true; - this.running = true; - for (var i = 0; i < this.deltaSmoothingMax; i++) - { - this.deltaHistory[i] = this._target; - } +/***/ }), - this.resetDelta(); +/***/ 90656: +/***/ ((module) => { - this.startTime = window.performance.now(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.callback = callback; +/** + * Compare two lines for strict equality. + * + * @function Phaser.Geom.Line.Equals + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The first line to compare. + * @param {Phaser.Geom.Line} toCompare - The second line to compare. + * + * @return {boolean} Whether the two lines are equal. + */ +var Equals = function (line, toCompare) +{ + return ( + line.x1 === toCompare.x1 && + line.y1 === toCompare.y1 && + line.x2 === toCompare.x2 && + line.y2 === toCompare.y2 + ); +}; - this.raf.start(this.step.bind(this), this.forceSetTimeOut, this._target); - }, +module.exports = Equals; - /** - * 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; +/***/ 30897: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var before = time - this.lastTime; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (before < 0) - { - // Because, Chrome. - before = 0; - } +var Length = __webpack_require__(16028); - this.rawDelta = before; +/** + * Extends the start and end points of a Line by the given amounts. + * + * The amounts can be positive or negative. Positive points will increase the length of the line, + * while negative ones will decrease it. + * + * If no `right` value is provided it will extend the length of the line equally in both directions. + * + * Pass a value of zero to leave the start or end point unchanged. + * + * @function Phaser.Geom.Line.Extend + * @since 3.16.0 + * + * @param {Phaser.Geom.Line} line - The line instance to extend. + * @param {number} left - The amount to extend the start of the line by. + * @param {number} [right] - The amount to extend the end of the line by. If not given it will be set to the `left` value. + * + * @return {Phaser.Geom.Line} The modified Line instance. + */ +var Extend = function (line, left, right) +{ + if (right === undefined) { right = left; } - var idx = this.deltaIndex; - var history = this.deltaHistory; - var max = this.deltaSmoothingMax; + var length = Length(line); - // delta time (time is in ms) - var dt = before; + var slopX = line.x2 - line.x1; + var slopY = line.y2 - line.y1; - // Delta Average - var avg = before; + if (left) + { + line.x1 = line.x1 - slopX / length * left; + line.y1 = line.y1 - slopY / length * left; + } - // 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 (right) + { + line.x2 = line.x2 + slopX / length * right; + line.y2 = line.y2 + slopY / length * right; + } - 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; - } + return line; +}; - // Set as the world delta value - this.delta = avg; +module.exports = Extend; - // 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; - } +/***/ 30684: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.framesThisSecond++; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Interpolation - how far between what is expected and where we are? - var interpolation = avg / this._target; +var DistanceBetweenPoints = __webpack_require__(92951); +var GetEaseFunction = __webpack_require__(21902); +var Point = __webpack_require__(79967); - this.callback(time, avg, interpolation); +/** + * Returns an array of `quantity` Points where each point is taken from the given Line, + * spaced out according to the ease function specified. + * + * ```javascript + * const line = new Phaser.Geom.Line(100, 300, 700, 300); + * const points = Phaser.Geom.Line.GetEasedPoints(line, 'sine.out', 32) + * ``` + * + * In the above example, the `points` array will contain 32 points spread-out across + * the length of `line`, where the position of each point is determined by the `Sine.out` + * ease function. + * + * You can optionally provide a collinear threshold. In this case, the resulting points + * are checked against each other, and if they are `< collinearThreshold` distance apart, + * they are dropped from the results. This can help avoid lots of clustered points at + * far ends of the line with tightly-packed eases such as Quartic. Leave the value set + * to zero to skip this check. + * + * Note that if you provide a collinear threshold, the resulting array may not always + * contain `quantity` points. + * + * @function Phaser.Geom.Line.GetEasedPoints + * @since 3.23.0 + * + * @generic {Phaser.Geom.Point[]} O - [out,$return] + * + * @param {Phaser.Geom.Line} line - The Line object. + * @param {(string|function)} ease - The ease to use. This can be either a string from the EaseMap, or a custom function. + * @param {number} quantity - The number of points to return. Note that if you provide a `collinearThreshold`, the resulting array may not always contain this number of points. + * @param {number} [collinearThreshold=0] - An optional threshold. The final array is reduced so that each point is spaced out at least this distance apart. This helps reduce clustering in noisey eases. + * @param {number[]} [easeParams] - An optional array of ease parameters to go with the ease. + * + * @return {Phaser.Geom.Point[]} An array of Geom.Points containing the coordinates of the points on the line. + */ +var GetEasedPoints = function (line, ease, quantity, collinearThreshold, easeParams) +{ + if (collinearThreshold === undefined) { collinearThreshold = 0; } + if (easeParams === undefined) { easeParams = []; } - // Shift time value over - this.lastTime = time; + var results = []; - this.frame++; - }, + var x1 = line.x1; + var y1 = line.y1; - /** - * Manually calls `TimeStep.step`. - * - * @method Phaser.Core.TimeStep#tick - * @since 3.0.0 - */ - tick: function () - { - this.step(); - }, + var spaceX = line.x2 - x1; + var spaceY = line.y2 - y1; - /** - * 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(); + var easeFunc = GetEaseFunction(ease, easeParams); - this.running = false; - } - }, + var i; + var v; + var q = quantity - 1; - /** - * 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) + for (i = 0; i < q; i++) { - if (this.running) - { - return; - } - else if (seamless) - { - this.startTime += -this.lastTime + (this.lastTime + window.performance.now()); - } + v = easeFunc(i / q); - this.raf.start(this.step.bind(this), this.useRAF); + results.push(new Point(x1 + (spaceX * v), y1 + (spaceY * v))); + } - this.running = true; + // Always include the end of the line + v = easeFunc(1); - this.step(); - }, + results.push(new Point(x1 + (spaceX * v), y1 + (spaceY * v))); - /** - * 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 () + // Remove collinear parts + if (collinearThreshold > 0) { - return Math.round(this.lastTime - this.startTime) / 1000; - }, + var prevPoint = results[0]; - /** - * 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); - }, + // Store the new results here + var sortedResults = [ prevPoint ]; - /** - * 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; + for (i = 1; i < results.length - 1; i++) + { + var point = results[i]; - this.raf.stop(); + if (DistanceBetweenPoints(prevPoint, point) >= collinearThreshold) + { + sortedResults.push(point); + prevPoint = point; + } + } - return this; - }, + // Top and tail + var endPoint = results[results.length - 1]; - /** - * 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(); + if (DistanceBetweenPoints(prevPoint, endPoint) < collinearThreshold) + { + sortedResults.pop(); + } - this.callback = NOOP; + sortedResults.push(endPoint); - this.raf = null; - this.game = null; + return sortedResults; } + else + { + return results; + } +}; -}); - -module.exports = TimeStep; +module.exports = GetEasedPoints; /***/ }), -/* 386 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 20487: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var NOOP = __webpack_require__(1); +var Point = __webpack_require__(79967); /** - * @classdesc - * Abstracts away the use of RAF or setTimeOut for the core game update loop. - * This is invoked automatically by the Phaser.Game instance. + * Get the midpoint of the given line. * - * @class RequestAnimationFrame - * @memberof Phaser.DOM - * @constructor + * @function Phaser.Geom.Line.GetMidPoint * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Line} line - The line to get the midpoint of. + * @param {(Phaser.Geom.Point|object)} [out] - An optional point object to store the midpoint in. + * + * @return {(Phaser.Geom.Point|object)} The midpoint of the Line. */ -var RequestAnimationFrame = new Class({ +var GetMidPoint = function (line, out) +{ + if (out === undefined) { out = new Point(); } - initialize: + out.x = (line.x1 + line.x2) / 2; + out.y = (line.y1 + line.y2) / 2; - 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; + return out; +}; - /** - * The callback to be invoked each step. - * - * @name Phaser.DOM.RequestAnimationFrame#callback - * @type {FrameRequestCallback} - * @since 3.0.0 - */ - this.callback = NOOP; +module.exports = GetMidPoint; - /** - * 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; +/***/ 11222: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The previous time the step was called. - * - * @name Phaser.DOM.RequestAnimationFrame#lastTime - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.lastTime = 0; +/** + * @author Richard Davey + * @author Florian Mertens + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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 Point = __webpack_require__(79967); - var _this = this; +/** + * Get the nearest point on a line perpendicular to the given point. + * + * @function Phaser.Geom.Line.GetNearestPoint + * @since 3.16.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Line} line - The line to get the nearest point on. + * @param {(Phaser.Geom.Point|object)} point - The point to get the nearest point to. + * @param {(Phaser.Geom.Point|object)} [out] - An optional point, or point-like object, to store the coordinates of the nearest point on the line. + * + * @return {(Phaser.Geom.Point|object)} The nearest point on the line. + */ +var GetNearestPoint = function (line, point, out) +{ + if (out === undefined) { out = new Point(); } - /** - * 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(); + var x1 = line.x1; + var y1 = line.y1; - // DOMHighResTimeStamp - _this.lastTime = _this.tick; + var x2 = line.x2; + var y2 = line.y2; - _this.tick = timestamp; + var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); - _this.callback(timestamp); + if (L2 === 0) + { + return out; + } - _this.timeOutID = window.requestAnimationFrame(step); - }; + var r = (((point.x - x1) * (x2 - x1)) + ((point.y - y1) * (y2 - y1))) / L2; - /** - * 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(); + out.x = x1 + (r * (x2 - x1)); + out.y = y1 + (r * (y2 - y1)); - var delay = Math.min(Math.max(_this.target * 2 + _this.tick - d, 0), _this.target); + return out; +}; - _this.lastTime = _this.tick; +module.exports = GetNearestPoint; - _this.tick = d; - _this.callback(d); +/***/ }), - _this.timeOutID = window.setTimeout(stepTimeout, delay); - }; - }, +/***/ 7377: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.callback = callback; +var MATH_CONST = __webpack_require__(83392); +var Angle = __webpack_require__(50599); +var Point = __webpack_require__(79967); - this.isSetTimeOut = forceSetTimeOut; +/** + * Calculate the normal of the given line. + * + * The normal of a line is a vector that points perpendicular from it. + * + * @function Phaser.Geom.Line.GetNormal + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Line} line - The line to calculate the normal of. + * @param {(Phaser.Geom.Point|object)} [out] - An optional point object to store the normal in. + * + * @return {(Phaser.Geom.Point|object)} The normal of the Line. + */ +var GetNormal = function (line, out) +{ + if (out === undefined) { out = new Point(); } - this.target = targetFPS; + var a = Angle(line) - MATH_CONST.TAU; - this.isRunning = true; + out.x = Math.cos(a); + out.y = Math.sin(a); - this.timeOutID = (forceSetTimeOut) ? window.setTimeout(this.stepTimeout, 0) : window.requestAnimationFrame(this.step); - }, + return out; +}; - /** - * Stops the requestAnimationFrame or setTimeout from running. - * - * @method Phaser.DOM.RequestAnimationFrame#stop - * @since 3.0.0 - */ - stop: function () - { - this.isRunning = false; +module.exports = GetNormal; - 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; - } +/***/ 66464: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -}); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = RequestAnimationFrame; +var Point = __webpack_require__(79967); + +/** + * Get a point on a line that's a given percentage along its length. + * + * @function Phaser.Geom.Line.GetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Line} line - The line. + * @param {number} position - A value between 0 and 1, where 0 is the start, 0.5 is the middle and 1 is the end of the line. + * @param {(Phaser.Geom.Point|object)} [out] - An optional point, or point-like object, to store the coordinates of the point on the line. + * + * @return {(Phaser.Geom.Point|object)} The point on the line. + */ +var GetPoint = function (line, position, out) +{ + if (out === undefined) { out = new Point(); } + + out.x = line.x1 + (line.x2 - line.x1) * position; + out.y = line.y1 + (line.y2 - line.y1) * position; + + return out; +}; + +module.exports = GetPoint; /***/ }), -/* 387 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 8570: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Events = __webpack_require__(22); +var Length = __webpack_require__(16028); +var Point = __webpack_require__(79967); /** - * 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. + * Get a number of points along a line's length. * - * @function Phaser.Core.VisibilityHandler - * @fires Phaser.Core.Events#BLUR - * @fires Phaser.Core.Events#FOCUS - * @fires Phaser.Core.Events#HIDDEN - * @fires Phaser.Core.Events#VISIBLE + * Provide a `quantity` to get an exact number of points along the line. + * + * Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when + * providing a `stepRate`. + * + * @function Phaser.Geom.Line.GetPoints * @since 3.0.0 * - * @param {Phaser.Game} game - The Game instance this Visibility Handler is working on. + * @generic {Phaser.Geom.Point[]} O - [out,$return] + * + * @param {Phaser.Geom.Line} line - The line. + * @param {number} quantity - The number of points to place on the line. Set to `0` to use `stepRate` instead. + * @param {number} [stepRate] - The distance between each point on the line. When set, `quantity` is implied and should be set to `0`. + * @param {(array|Phaser.Geom.Point[])} [out] - An optional array of Points, or point-like objects, to store the coordinates of the points on the line. + * + * @return {(array|Phaser.Geom.Point[])} An array of Points, or point-like objects, containing the coordinates of the points on the line. */ -var VisibilityHandler = function (game) +var GetPoints = function (line, quantity, stepRate, out) { - var hiddenVar; - var eventEmitter = game.events; + if (out === undefined) { out = []; } - if (document.hidden !== undefined) - { - hiddenVar = 'visibilitychange'; - } - else + // If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. + if (!quantity && stepRate > 0) { - var vendors = [ 'webkit', 'moz', 'ms' ]; - - vendors.forEach(function (prefix) - { - if (document[prefix + 'Hidden'] !== undefined) - { - document.hidden = function () - { - return document[prefix + 'Hidden']; - }; - - hiddenVar = prefix + 'visibilitychange'; - } - - }); + quantity = Length(line) / stepRate; } - var onChange = function (event) - { - if (document.hidden || event.type === 'pause') - { - eventEmitter.emit(Events.HIDDEN); - } - else - { - eventEmitter.emit(Events.VISIBLE); - } - }; + var x1 = line.x1; + var y1 = line.y1; - if (hiddenVar) - { - document.addEventListener(hiddenVar, onChange, false); - } + var x2 = line.x2; + var y2 = line.y2; - window.onblur = function () + for (var i = 0; i < quantity; i++) { - eventEmitter.emit(Events.BLUR); - }; + var position = i / quantity; - window.onfocus = function () - { - eventEmitter.emit(Events.FOCUS); - }; + var x = x1 + (x2 - x1) * position; + var y = y1 + (y2 - y1) * position; - // Automatically give the window focus unless config says otherwise - if (window.focus && game.config.autoFocus) - { - window.focus(); + out.push(new Point(x, y)); } + + return out; }; -module.exports = VisibilityHandler; +module.exports = GetPoints; /***/ }), -/* 388 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 65269: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Florian Mertens + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Arne16 = __webpack_require__(389); -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. + * Get the shortest distance from a Line to the given Point. * - * @function Phaser.Create.GenerateTexture - * @since 3.0.0 + * @function Phaser.Geom.Line.GetShortestDistance + * @since 3.16.0 * - * @param {Phaser.Types.Create.GenerateTextureConfig} config - The Generate Texture Configuration object. + * @param {Phaser.Geom.Line} line - The line to get the distance from. + * @param {Phaser.Types.Math.Vector2Like} point - The point to get the shortest distance to. * - * @return {HTMLCanvasElement} An HTMLCanvasElement which contains the generated texture drawn to it. + * @return {(boolean|number)} The shortest distance from the line to the point, or `false`. */ -var GenerateTexture = function (config) +var GetShortestDistance = function (line, point) { - 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 x1 = line.x1; + var y1 = line.y1; - var width = Math.floor(Math.abs(data[0].length * pixelWidth)); - var height = Math.floor(Math.abs(data.length * pixelHeight)); + var x2 = line.x2; + var y2 = line.y2; - if (!canvas) - { - canvas = CanvasPool.create2D(this, width, height); - resizeCanvas = false; - clearCanvas = false; - } + var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); - if (resizeCanvas) + if (L2 === 0) { - canvas.width = width; - canvas.height = height; + return false; } - var ctx = canvas.getContext('2d'); + var s = (((y1 - point.y) * (x2 - x1)) - ((x1 - point.x) * (y2 - y1))) / L2; - if (clearCanvas) - { - ctx.clearRect(0, 0, width, height); - } + return Math.abs(s) * Math.sqrt(L2); +}; - // preRender Callback? - if (preRender) - { - preRender(canvas, ctx); - } +module.exports = GetShortestDistance; - // 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); - } - } - } +/***/ 82996: +/***/ ((module) => { - // postRender Callback? - if (postRender) - { - postRender(canvas, ctx); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return canvas; +/** + * Calculate the height of the given line. + * + * @function Phaser.Geom.Line.Height + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The line to calculate the height of. + * + * @return {number} The height of the line. + */ +var Height = function (line) +{ + return Math.abs(line.y1 - line.y2); }; -module.exports = GenerateTexture; +module.exports = Height; /***/ }), -/* 389 */ -/***/ (function(module, exports) { + +/***/ 16028: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * A 16 color palette by [Arne](http://androidarts.com/palette/16pal.htm) + * Calculate the length of the given line. * - * @name Phaser.Create.Palettes.ARNE16 + * @function Phaser.Geom.Line.Length * @since 3.0.0 * - * @type {Phaser.Types.Create.Palette} + * @param {Phaser.Geom.Line} line - The line to calculate the length of. + * + * @return {number} The length of the line. */ -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' +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; + /***/ }), -/* 390 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 88829: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(358); -var Curve = __webpack_require__(94); -var Vector2 = __webpack_require__(3); +var Class = __webpack_require__(56694); +var GetPoint = __webpack_require__(66464); +var GetPoints = __webpack_require__(8570); +var GEOM_CONST = __webpack_require__(52394); +var Random = __webpack_require__(74077); +var Vector2 = __webpack_require__(93736); /** * @classdesc - * A higher-order Bézier curve constructed of four points. + * Defines a Line segment, a part of a line between two endpoints. * - * @class CubicBezier - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves + * @class Line + * @memberof Phaser.Geom * @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. + * @param {number} [x1=0] - The x coordinate of the lines starting point. + * @param {number} [y1=0] - The y coordinate of the lines starting point. + * @param {number} [x2=0] - The x coordinate of the lines ending point. + * @param {number} [y2=0] - The y coordinate of the lines ending point. */ -var CubicBezierCurve = new Class({ - - Extends: Curve, +var Line = new Class({ initialize: - function CubicBezierCurve (p0, p1, p2, p3) + function Line (x1, y1, x2, y2) { - 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; - - -/***/ }), -/* 391 */ -/***/ (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__(94); -var DegToRad = __webpack_require__(36); -var GetValue = __webpack_require__(6); -var RadToDeg = __webpack_require__(196); -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); + if (x1 === undefined) { x1 = 0; } + if (y1 === undefined) { y1 = 0; } + if (x2 === undefined) { x2 = 0; } + if (y2 === undefined) { y2 = 0; } /** - * The horizontal radius of the ellipse. + * The geometry constant type of this object: `GEOM_CONST.LINE`. + * Used for fast type comparisons. * - * @name Phaser.Curves.Ellipse#_xRadius + * @name Phaser.Geom.Line#type * @type {number} - * @private - * @since 3.0.0 + * @readonly + * @since 3.19.0 */ - this._xRadius = xRadius; + this.type = GEOM_CONST.LINE; /** - * The vertical radius of the ellipse. + * The x coordinate of the lines starting point. * - * @name Phaser.Curves.Ellipse#_yRadius + * @name Phaser.Geom.Line#x1 * @type {number} - * @private * @since 3.0.0 */ - this._yRadius = yRadius; - - // Radians + this.x1 = x1; /** - * The starting angle of the ellipse in radians. + * The y coordinate of the lines starting point. * - * @name Phaser.Curves.Ellipse#_startAngle + * @name Phaser.Geom.Line#y1 * @type {number} - * @private * @since 3.0.0 */ - this._startAngle = DegToRad(startAngle); + this.y1 = y1; /** - * The end angle of the ellipse in radians. + * The x coordinate of the lines ending point. * - * @name Phaser.Curves.Ellipse#_endAngle + * @name Phaser.Geom.Line#x2 * @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; + this.x2 = x2; /** - * The rotation of the arc. + * The y coordinate of the lines ending point. * - * @name Phaser.Curves.Ellipse#_rotation + * @name Phaser.Geom.Line#y2 * @type {number} - * @private * @since 3.0.0 */ - this._rotation = DegToRad(rotation); + this.y2 = y2; }, /** - * Gets the starting point on the curve. + * Get a point on a line that's a given percentage along its length. * - * @method Phaser.Curves.Ellipse#getStartPoint + * @method Phaser.Geom.Line#getPoint * @since 3.0.0 * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * @generic {Phaser.Geom.Point} O - [output,$return] * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * @param {number} position - A value between 0 and 1, where 0 is the start, 0.5 is the middle and 1 is the end of the line. + * @param {(Phaser.Geom.Point|object)} [output] - An optional point, or point-like object, to store the coordinates of the point on the line. * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point on the line. */ - getStartPoint: function (out) + getPoint: function (position, output) { - if (out === undefined) { out = new Vector2(); } - - return this.getPoint(0, out); + return GetPoint(this, position, output); }, /** - * Get the resolution of the curve. - * - * @method Phaser.Curves.Ellipse#getResolution - * @since 3.0.0 + * Get a number of points along a line's length. * - * @param {number} divisions - Optional divisions value. + * Provide a `quantity` to get an exact number of points along the line. * - * @return {number} The curve resolution. - */ - getResolution: function (divisions) - { - return divisions * 2; - }, - - /** - * Get point at relative position in curve according to length. + * Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when + * providing a `stepRate`. * - * @method Phaser.Curves.Ellipse#getPoint + * @method Phaser.Geom.Line#getPoints * @since 3.0.0 * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * @generic {Phaser.Geom.Point[]} O - [output,$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. + * @param {number} quantity - The number of points to place on the line. Set to `0` to use `stepRate` instead. + * @param {number} [stepRate] - The distance between each point on the line. When set, `quantity` is implied and should be set to `0`. + * @param {(array|Phaser.Geom.Point[])} [output] - An optional array of Points, or point-like objects, to store the coordinates of the points on the line. * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + * @return {(array|Phaser.Geom.Point[])} An array of Points, or point-like objects, containing the coordinates of the points on the line. */ - getPoint: function (t, out) + getPoints: function (quantity, stepRate, output) { - 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); + return GetPoints(this, quantity, stepRate, output); }, /** - * Sets the horizontal radius of this curve. + * Get a random Point on the Line. * - * @method Phaser.Curves.Ellipse#setXRadius + * @method Phaser.Geom.Line#getRandomPoint * @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 + * @generic {Phaser.Geom.Point} O - [point,$return] * - * @param {number} value - The vertical radius of this curve. + * @param {(Phaser.Geom.Point|object)} [point] - An instance of a Point to be modified. * - * @return {this} This curve object. + * @return {Phaser.Geom.Point} A random Point on the Line. */ - setYRadius: function (value) + getRandomPoint: function (point) { - this.yRadius = value; - - return this; + return Random(this, point); }, /** - * Sets the width of this curve. + * Set new coordinates for the line endpoints. * - * @method Phaser.Curves.Ellipse#setWidth + * @method Phaser.Geom.Line#setTo * @since 3.0.0 * - * @param {number} value - The width of this curve. + * @param {number} [x1=0] - The x coordinate of the lines starting point. + * @param {number} [y1=0] - The y coordinate of the lines starting point. + * @param {number} [x2=0] - The x coordinate of the lines ending point. + * @param {number} [y2=0] - The y coordinate of the lines ending point. * - * @return {this} This curve object. + * @return {this} This Line object. */ - setWidth: function (value) + setTo: function (x1, y1, x2, y2) { - this.xRadius = value / 2; + if (x1 === undefined) { x1 = 0; } + if (y1 === undefined) { y1 = 0; } + if (x2 === undefined) { x2 = 0; } + if (y2 === undefined) { y2 = 0; } - return this; - }, + this.x1 = x1; + this.y1 = y1; - /** - * 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; + this.x2 = x2; + this.y2 = y2; return this; }, /** - * Sets the start angle of this curve. + * Returns a Vector2 object that corresponds to the start of this Line. * - * @method Phaser.Curves.Ellipse#setStartAngle + * @method Phaser.Geom.Line#getPointA * @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 + * @generic {Phaser.Math.Vector2} O - [vec2,$return] * - * @param {number} value - The end angle of this curve, in radians. + * @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created. * - * @return {this} This curve object. + * @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the start of this Line. */ - setEndAngle: function (value) + getPointA: function (vec2) { - this.endAngle = value; - - return this; - }, + if (vec2 === undefined) { vec2 = new Vector2(); } - /** - * 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; + vec2.set(this.x1, this.y1); - return this; + return vec2; }, /** - * Sets the rotation of this curve. + * Returns a Vector2 object that corresponds to the end of this Line. * - * @method Phaser.Curves.Ellipse#setRotation + * @method Phaser.Geom.Line#getPointB * @since 3.0.0 * - * @param {number} value - The rotation of this curve, in radians. + * @generic {Phaser.Math.Vector2} O - [vec2,$return] * - * @return {this} This curve object. + * @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created. + * + * @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the end of this Line. */ - setRotation: function (value) + getPointB: function (vec2) { - this.rotation = value; + if (vec2 === undefined) { vec2 = new Vector2(); } - return this; + vec2.set(this.x2, this.y2); + + return vec2; }, /** - * The x coordinate of the center of the ellipse. + * The left position of the Line. * - * @name Phaser.Curves.Ellipse#x + * @name Phaser.Geom.Line#left * @type {number} * @since 3.0.0 */ - x: { + left: { get: function () { - return this.p0.x; + return Math.min(this.x1, this.x2); }, set: function (value) { - this.p0.x = value; + if (this.x1 <= this.x2) + { + this.x1 = value; + } + else + { + this.x2 = value; + } } }, /** - * The y coordinate of the center of the ellipse. + * The right position of the Line. * - * @name Phaser.Curves.Ellipse#y + * @name Phaser.Geom.Line#right * @type {number} * @since 3.0.0 */ - y: { + right: { get: function () { - return this.p0.y; + return Math.max(this.x1, this.x2); }, set: function (value) { - this.p0.y = value; + if (this.x1 > this.x2) + { + this.x1 = value; + } + else + { + this.x2 = value; + } } }, /** - * The horizontal radius of the ellipse. + * The top position of the Line. * - * @name Phaser.Curves.Ellipse#xRadius + * @name Phaser.Geom.Line#top * @type {number} * @since 3.0.0 */ - xRadius: { + top: { get: function () { - return this._xRadius; + return Math.min(this.y1, this.y2); }, set: function (value) { - this._xRadius = value; + if (this.y1 <= this.y2) + { + this.y1 = value; + } + else + { + this.y2 = value; + } } }, /** - * The vertical radius of the ellipse. + * The bottom position of the Line. * - * @name Phaser.Curves.Ellipse#yRadius + * @name Phaser.Geom.Line#bottom * @type {number} * @since 3.0.0 */ - yRadius: { + bottom: { get: function () { - return this._yRadius; + return Math.max(this.y1, this.y2); }, set: function (value) { - this._yRadius = value; + if (this.y1 > this.y2) + { + this.y1 = value; + } + else + { + this.y2 = 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); - }, +module.exports = Line; - 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: { +/***/ 73273: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - get: function () - { - return RadToDeg(this._endAngle); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - set: function (value) - { - this._endAngle = DegToRad(value); - } +var MATH_CONST = __webpack_require__(83392); +var Wrap = __webpack_require__(1071); +var Angle = __webpack_require__(50599); - }, +/** + * 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; - /** - * `true` if the ellipse rotation is clockwise or `false` if anti-clockwise. - * - * @name Phaser.Curves.Ellipse#clockwise - * @type {boolean} - * @since 3.0.0 - */ - clockwise: { + return Wrap(angle, -Math.PI, Math.PI); +}; - get: function () - { - return this._clockwise; - }, +module.exports = NormalAngle; - 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: { +/***/ 96936: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - get: function () - { - return RadToDeg(this._rotation); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - set: function (value) - { - this._rotation = DegToRad(value); - } +var MATH_CONST = __webpack_require__(83392); +var Angle = __webpack_require__(50599); - }, +/** + * Returns the x component of the normal vector of the given line. + * + * @function Phaser.Geom.Line.NormalX + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The Line object to get the normal value from. + * + * @return {number} The x component of the normal vector of the line. + */ +var NormalX = function (line) +{ + return Math.cos(Angle(line) - MATH_CONST.TAU); +}; - /** - * The rotation of the ellipse, relative to the center, in radians. - * - * @name Phaser.Curves.Ellipse#rotation - * @type {number} - * @since 3.0.0 - */ - rotation: { +module.exports = NormalX; - get: function () - { - return this._rotation; - }, - set: function (value) - { - this._rotation = value; - } +/***/ }), - }, +/***/ 43581: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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) - }; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -}); +var MATH_CONST = __webpack_require__(83392); +var Angle = __webpack_require__(50599); /** - * Creates a curve from the provided Ellipse Curve Configuration object. + * The Y value of the normal of the given line. + * The normal of a line is a vector that points perpendicular from it. * - * @function Phaser.Curves.Ellipse.fromJSON + * @function Phaser.Geom.Line.NormalY * @since 3.0.0 * - * @param {Phaser.Types.Curves.JSONEllipseCurve} data - The JSON object containing this curve data. + * @param {Phaser.Geom.Line} line - The line to calculate the normal of. * - * @return {Phaser.Curves.Ellipse} The ellipse curve constructed from the configuration object. + * @return {number} The Y value of the normal of the Line. */ -EllipseCurve.fromJSON = function (data) +var NormalY = function (line) { - return new EllipseCurve(data); + return Math.sin(Angle(line) - MATH_CONST.TAU); }; -module.exports = EllipseCurve; +module.exports = NormalY; /***/ }), -/* 392 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 13990: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(94); -var FromPoints = __webpack_require__(199); -var Rectangle = __webpack_require__(10); -var Vector2 = __webpack_require__(3); - /** - * @classdesc - * A LineCurve is a "curve" comprising exactly two points (a line segment). + * Offset a line by the given amount. * - * @class Line - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves - * @constructor + * @function Phaser.Geom.Line.Offset * @since 3.0.0 * - * @param {(Phaser.Math.Vector2|number[])} p0 - The first endpoint. - * @param {Phaser.Math.Vector2} [p1] - The second endpoint. + * @generic {Phaser.Geom.Line} O - [line,$return] + * + * @param {Phaser.Geom.Line} line - The line to offset. + * @param {number} x - The horizontal offset to add to the line. + * @param {number} y - The vertical offset to add to the line. + * + * @return {Phaser.Geom.Line} The offset line. */ -var LineCurve = new Class({ +var Offset = function (line, x, y) +{ + line.x1 += x; + line.y1 += y; - Extends: Curve, + line.x2 += x; + line.y2 += y; - initialize: + return line; +}; - // vec2s or array - function LineCurve (p0, p1) - { - Curve.call(this, 'LineCurve'); +module.exports = Offset; - 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; +/***/ 1298: +/***/ ((module) => { - // Override default Curve.arcLengthDivisions +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; - }, +/** + * Calculate the perpendicular slope of the given line. + * + * @function Phaser.Geom.Line.PerpSlope + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The line to calculate the perpendicular slope of. + * + * @return {number} The perpendicular slope of the line. + */ +var PerpSlope = function (line) +{ + return -((line.x2 - line.x1) / (line.y2 - line.y1)); +}; - /** - * 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(); } +module.exports = PerpSlope; - 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); - }, +/***/ 74077: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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; } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return divisions; - }, +var Point = __webpack_require__(79967); - /** - * 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(); } +/** + * Returns a random point on a given Line. + * + * @function Phaser.Geom.Line.Random + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Line} line - The Line to calculate the random Point on. + * @param {(Phaser.Geom.Point|object)} [out] - An instance of a Point to be modified. + * + * @return {(Phaser.Geom.Point|object)} A random Point on the Line. + */ +var Random = function (line, out) +{ + if (out === undefined) { out = new Point(); } - if (t === 1) - { - return out.copy(this.p1); - } + var t = Math.random(); - out.copy(this.p1).subtract(this.p0).scale(t).add(this.p0); + out.x = line.x1 + t * (line.x2 - line.x1); + out.y = line.y1 + t * (line.y2 - line.y1); - return out; - }, + return out; +}; - // Line curve is linear, so we can overwrite default getPointAt +module.exports = Random; - /** - * 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] - * - * @param {number} [t] - The relative position on the line, [0..1]. - * @param {Phaser.Math.Vector2} [out] - A vector to store the result in. - * - * @return {Phaser.Math.Vector2} The tangent vector. - */ - getTangent: function (t, out) - { - if (out === undefined) { out = new Vector2(); } +/***/ }), - out.copy(this.p1).subtract(this.p0).normalize(); +/***/ 30473: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return out; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +var Angle = __webpack_require__(50599); +var NormalAngle = __webpack_require__(73273); - if (distance) - { - var arcLengths = this.getLengths(divisions); - var lineLength = arcLengths[arcLengths.length - 1]; +/** + * Calculate the reflected angle between two lines. + * + * This is the outgoing angle based on the angle of Line 1 and the normalAngle of Line 2. + * + * @function Phaser.Geom.Line.ReflectAngle + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} lineA - The first line. + * @param {Phaser.Geom.Line} lineB - The second line. + * + * @return {number} The reflected angle between each line. + */ +var ReflectAngle = function (lineA, lineB) +{ + return (2 * NormalAngle(lineB) - Math.PI - Angle(lineA)); +}; - // Cannot overshoot the curve - var targetLineLength = Math.min(distance, lineLength); +module.exports = ReflectAngle; - t = targetLineLength / lineLength; - } - else - { - t = u; - } - return t; - }, +/***/ }), - // Override default Curve.draw because this is better than calling getPoints on a line! +/***/ 25968: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // So you can chain graphics calls - return graphics; - }, +var RotateAroundXY = __webpack_require__(1809); - /** - * 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 - ] - }; - } +/** + * Rotate a line around its midpoint by the given angle in radians. + * + * @function Phaser.Geom.Line.Rotate + * @since 3.0.0 + * + * @generic {Phaser.Geom.Line} O - [line,$return] + * + * @param {Phaser.Geom.Line} line - The line to rotate. + * @param {number} angle - The angle of rotation in radians. + * + * @return {Phaser.Geom.Line} The rotated line. + */ +var Rotate = function (line, angle) +{ + var x = (line.x1 + line.x2) / 2; + var y = (line.y1 + line.y2) / 2; -}); + return RotateAroundXY(line, x, y, angle); +}; + +module.exports = Rotate; + + +/***/ }), + +/***/ 24296: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Configures this line from a JSON representation. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var RotateAroundXY = __webpack_require__(1809); + +/** + * Rotate a line around a point by the given angle in radians. * - * @function Phaser.Curves.Line.fromJSON + * @function Phaser.Geom.Line.RotateAroundPoint * @since 3.0.0 * - * @param {Phaser.Types.Curves.JSONCurve} data - The JSON object containing this curve data. + * @generic {Phaser.Geom.Line} O - [line,$return] * - * @return {Phaser.Curves.Line} A new LineCurve object. + * @param {Phaser.Geom.Line} line - The line to rotate. + * @param {(Phaser.Geom.Point|object)} point - The point to rotate the line around. + * @param {number} angle - The angle of rotation in radians. + * + * @return {Phaser.Geom.Line} The rotated line. */ -LineCurve.fromJSON = function (data) +var RotateAroundPoint = function (line, point, angle) { - var points = data.points; + return RotateAroundXY(line, point.x, point.y, angle); +}; - var p0 = new Vector2(points[0], points[1]); - var p1 = new Vector2(points[2], points[3]); +module.exports = RotateAroundPoint; - return new LineCurve(p0, p1); + +/***/ }), + +/***/ 1809: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Rotate a line around the given coordinates by the given angle in radians. + * + * @function Phaser.Geom.Line.RotateAroundXY + * @since 3.0.0 + * + * @generic {Phaser.Geom.Line} O - [line,$return] + * + * @param {Phaser.Geom.Line} line - The line to rotate. + * @param {number} x - The horizontal coordinate to rotate the line around. + * @param {number} y - The vertical coordinate to rotate the line around. + * @param {number} angle - The angle of rotation in radians. + * + * @return {Phaser.Geom.Line} The rotated line. + */ +var RotateAroundXY = function (line, x, y, angle) +{ + var c = Math.cos(angle); + var s = Math.sin(angle); + + var tx = line.x1 - x; + var ty = line.y1 - y; + + line.x1 = tx * c - ty * s + x; + line.y1 = tx * s + ty * c + y; + + tx = line.x2 - x; + ty = line.y2 - y; + + line.x2 = tx * c - ty * s + x; + line.y2 = tx * s + ty * c + y; + + return line; }; -module.exports = LineCurve; +module.exports = RotateAroundXY; /***/ }), -/* 393 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 88171: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Vector2 = __webpack_require__(3); +/** + * Set a line to a given position, angle and length. + * + * @function Phaser.Geom.Line.SetToAngle + * @since 3.0.0 + * + * @generic {Phaser.Geom.Line} O - [line,$return] + * + * @param {Phaser.Geom.Line} line - The line to set. + * @param {number} x - The horizontal start position of the line. + * @param {number} y - The vertical start position of the line. + * @param {number} angle - The angle of the line in radians. + * @param {number} length - The length of the line. + * + * @return {Phaser.Geom.Line} The updated line. + */ +var SetToAngle = function (line, x, y, angle, length) +{ + line.x1 = x; + line.y1 = y; + + line.x2 = x + (Math.cos(angle) * length); + line.y2 = y + (Math.sin(angle) * length); + + return line; +}; + +module.exports = SetToAngle; + + +/***/ }), + +/***/ 82797: +/***/ ((module) => { /** - * @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. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the slope of the given line. * - * @class MoveTo - * @memberof Phaser.Curves - * @constructor + * @function Phaser.Geom.Line.Slope * @since 3.0.0 * - * @param {number} [x=0] - `x` pixel coordinate. - * @param {number} [y=0] - `y` pixel coordinate. + * @param {Phaser.Geom.Line} line - The line to calculate the slope of. + * + * @return {number} The slope of the line. */ -var MoveTo = new Class({ +var Slope = function (line) +{ + return (line.y2 - line.y1) / (line.x2 - line.x1); +}; - initialize: +module.exports = Slope; - 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(); } +/***/ 41067: +/***/ ((module) => { - return out.copy(this.p0); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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); - }, +/** + * Calculate the width of the given line. + * + * @function Phaser.Geom.Line.Width + * @since 3.0.0 + * + * @param {Phaser.Geom.Line} line - The line to calculate the width of. + * + * @return {number} The width of the line. + */ +var Width = function (line) +{ + return Math.abs(line.x1 - line.x2); +}; - /** - * 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; - }, +module.exports = Width; - /** - * 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 - ] - }; - } +/***/ }), -}); +/***/ 28482: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -module.exports = MoveTo; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Line = __webpack_require__(88829); + +Line.Angle = __webpack_require__(50599); +Line.BresenhamPoints = __webpack_require__(58813); +Line.CenterOn = __webpack_require__(88513); +Line.Clone = __webpack_require__(26718); +Line.CopyFrom = __webpack_require__(88930); +Line.Equals = __webpack_require__(90656); +Line.Extend = __webpack_require__(30897); +Line.GetEasedPoints = __webpack_require__(30684); +Line.GetMidPoint = __webpack_require__(20487); +Line.GetNearestPoint = __webpack_require__(11222); +Line.GetNormal = __webpack_require__(7377); +Line.GetPoint = __webpack_require__(66464); +Line.GetPoints = __webpack_require__(8570); +Line.GetShortestDistance = __webpack_require__(65269); +Line.Height = __webpack_require__(82996); +Line.Length = __webpack_require__(16028); +Line.NormalAngle = __webpack_require__(73273); +Line.NormalX = __webpack_require__(96936); +Line.NormalY = __webpack_require__(43581); +Line.Offset = __webpack_require__(13990); +Line.PerpSlope = __webpack_require__(1298); +Line.Random = __webpack_require__(74077); +Line.ReflectAngle = __webpack_require__(30473); +Line.Rotate = __webpack_require__(25968); +Line.RotateAroundPoint = __webpack_require__(24296); +Line.RotateAroundXY = __webpack_require__(1809); +Line.SetToAngle = __webpack_require__(88171); +Line.Slope = __webpack_require__(82797); +Line.Width = __webpack_require__(41067); + +module.exports = Line; /***/ }), -/* 394 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 18693: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Curve = __webpack_require__(94); -var QuadraticBezierInterpolation = __webpack_require__(359); -var Vector2 = __webpack_require__(3); +var Class = __webpack_require__(56694); +var Rectangle = __webpack_require__(74118); +var Vector2 = __webpack_require__(93736); + +/** + * Returns the length of the line. + * + * @ignore + * @private + * + * @param {number} x1 - The x1 coordinate. + * @param {number} y1 - The y1 coordinate. + * @param {number} x2 - The x2 coordinate. + * @param {number} y2 - The y2 coordinate. + * + * @return {number} The length of the line. + */ +function GetLength (x1, y1, x2, y2) +{ + var x = x1 - x2; + var y = y1 - y2; + var magnitude = (x * x) + (y * y); + + return Math.sqrt(magnitude); +} /** * @classdesc - * A quadratic Bézier curve constructed from two control points. + * A Face Geometry Object. * - * @class QuadraticBezier - * @extends Phaser.Curves.Curve - * @memberof Phaser.Curves + * A Face is used by the Mesh Game Object. A Mesh consists of one, or more, faces that are + * used to render the Mesh Game Objects in WebGL. + * + * A Face consists of 3 Vertex instances, for the 3 corners of the face and methods to help + * you modify and test them. + * + * @class Face + * @memberof Phaser.Geom.Mesh * @constructor - * @since 3.2.0 + * @since 3.50.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. + * @param {Phaser.Geom.Mesh.Vertex} vertex1 - The first vertex of the Face. + * @param {Phaser.Geom.Mesh.Vertex} vertex2 - The second vertex of the Face. + * @param {Phaser.Geom.Mesh.Vertex} vertex3 - The third vertex of the Face. */ -var QuadraticBezier = new Class({ - - Extends: Curve, +var Face = new Class({ initialize: - function QuadraticBezier (p0, p1, p2) + function Face (vertex1, vertex2, vertex3) { - Curve.call(this, 'QuadraticBezier'); + /** + * The first vertex in this Face. + * + * @name Phaser.Geom.Mesh.Face#vertex1 + * @type {Phaser.Geom.Mesh.Vertex} + * @since 3.50.0 + */ + this.vertex1 = vertex1; - 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 second vertex in this Face. + * + * @name Phaser.Geom.Mesh.Face#vertex2 + * @type {Phaser.Geom.Mesh.Vertex} + * @since 3.50.0 + */ + this.vertex2 = vertex2; /** - * The start point. + * The third vertex in this Face. * - * @name Phaser.Curves.QuadraticBezier#p0 - * @type {Phaser.Math.Vector2} - * @since 3.2.0 + * @name Phaser.Geom.Mesh.Face#vertex3 + * @type {Phaser.Geom.Mesh.Vertex} + * @since 3.50.0 */ - this.p0 = p0; + this.vertex3 = vertex3; /** - * The first control point. + * The bounds of this Face. * - * @name Phaser.Curves.QuadraticBezier#p1 - * @type {Phaser.Math.Vector2} - * @since 3.2.0 + * Be sure to call the `Face.updateBounds` method _before_ using this property. + * + * @name Phaser.Geom.Mesh.Face#bounds + * @type {Phaser.Geom.Rectangle} + * @since 3.50.0 */ - this.p1 = p1; + this.bounds = new Rectangle(); /** - * The second control point. + * The face inCenter. Do not access directly, instead use the `getInCenter` method. * - * @name Phaser.Curves.QuadraticBezier#p2 + * @name Phaser.Geom.Mesh.Face#_inCenter * @type {Phaser.Math.Vector2} - * @since 3.2.0 + * @private + * @since 3.50.0 */ - this.p2 = p2; + this._inCenter = new Vector2(); }, /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.QuadraticBezier#getStartPoint - * @since 3.2.0 + * Calculates and returns the in-center position of this Face. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * @method Phaser.Geom.Mesh.Face#getInCenter + * @since 3.50.0 * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * @param {boolean} [local=true] Return the in center from the un-transformed vertex positions (`true`), or transformed? (`false`) * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + * @return {Phaser.Math.Vector2} A Vector2 containing the in center position of this Face. */ - getStartPoint: function (out) + getInCenter: function (local) { - if (out === undefined) { out = new Vector2(); } + if (local === undefined) { local = true; } - return out.copy(this.p0); + var v1 = this.vertex1; + var v2 = this.vertex2; + var v3 = this.vertex3; + + var v1x; + var v1y; + + var v2x; + var v2y; + + var v3x; + var v3y; + + if (local) + { + v1x = v1.x; + v1y = v1.y; + + v2x = v2.x; + v2y = v2.y; + + v3x = v3.x; + v3y = v3.y; + } + else + { + v1x = v1.vx; + v1y = v1.vy; + + v2x = v2.vx; + v2y = v2.vy; + + v3x = v3.vx; + v3y = v3.vy; + } + + var d1 = GetLength(v3x, v3y, v2x, v2y); + var d2 = GetLength(v1x, v1y, v3x, v3y); + var d3 = GetLength(v2x, v2y, v1x, v1y); + + var p = d1 + d2 + d3; + + return this._inCenter.set( + (v1x * d1 + v2x * d2 + v3x * d3) / p, + (v1y * d1 + v2y * d2 + v3y * d3) / p + ); }, /** - * Get the resolution of the curve. + * Checks if the given coordinates are within this Face. * - * @method Phaser.Curves.QuadraticBezier#getResolution - * @since 3.2.0 + * You can optionally provide a transform matrix. If given, the Face vertices + * will be transformed first, before being checked against the coordinates. * - * @param {number} divisions - Optional divisions value. + * @method Phaser.Geom.Mesh.Face#contains + * @since 3.50.0 * - * @return {number} The curve resolution. + * @param {number} x - The horizontal position to check. + * @param {number} y - The vertical position to check. + * @param {Phaser.GameObjects.Components.TransformMatrix} [calcMatrix] - Optional transform matrix to apply to the vertices before comparison. + * + * @return {boolean} `true` if the coordinates lay within this Face, otherwise `false`. */ - getResolution: function (divisions) + contains: function (x, y, calcMatrix) { - return divisions; + var vertex1 = this.vertex1; + var vertex2 = this.vertex2; + var vertex3 = this.vertex3; + + var v1x = vertex1.vx; + var v1y = vertex1.vy; + + var v2x = vertex2.vx; + var v2y = vertex2.vy; + + var v3x = vertex3.vx; + var v3y = vertex3.vy; + + if (calcMatrix) + { + var a = calcMatrix.a; + var b = calcMatrix.b; + var c = calcMatrix.c; + var d = calcMatrix.d; + var e = calcMatrix.e; + var f = calcMatrix.f; + + v1x = vertex1.vx * a + vertex1.vy * c + e; + v1y = vertex1.vx * b + vertex1.vy * d + f; + + v2x = vertex2.vx * a + vertex2.vy * c + e; + v2y = vertex2.vx * b + vertex2.vy * d + f; + + v3x = vertex3.vx * a + vertex3.vy * c + e; + v3y = vertex3.vx * b + vertex3.vy * d + f; + } + + var t0x = v3x - v1x; + var t0y = v3y - v1y; + + var t1x = v2x - v1x; + var t1y = v2y - v1y; + + var t2x = x - v1x; + var t2y = y - v1y; + + var dot00 = (t0x * t0x) + (t0y * t0y); + var dot01 = (t0x * t1x) + (t0y * t1y); + var dot02 = (t0x * t2x) + (t0y * t2y); + var dot11 = (t1x * t1x) + (t1y * t1y); + var dot12 = (t1x * t2x) + (t1y * t2y); + + // Compute barycentric coordinates + var bc = ((dot00 * dot11) - (dot01 * dot01)); + var inv = (bc === 0) ? 0 : (1 / bc); + var u = ((dot11 * dot02) - (dot01 * dot12)) * inv; + var v = ((dot00 * dot12) - (dot01 * dot02)) * inv; + + return (u >= 0 && v >= 0 && (u + v < 1)); }, /** - * Get point at relative position in curve according to length. + * Checks if the vertices in this Face are orientated counter-clockwise, or not. * - * @method Phaser.Curves.QuadraticBezier#getPoint - * @since 3.2.0 + * It checks the transformed position of the vertices, not the local one. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * @method Phaser.Geom.Mesh.Face#isCounterClockwise + * @since 3.50.0 * - * @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. + * @param {number} z - The z-axis value to test against. Typically the `Mesh.modelPosition.z`. * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + * @return {boolean} `true` if the vertices in this Face run counter-clockwise, otherwise `false`. */ - getPoint: function (t, out) + isCounterClockwise: function (z) { - if (out === undefined) { out = new Vector2(); } + var v1 = this.vertex1; + var v2 = this.vertex2; + var v3 = this.vertex3; - var p0 = this.p0; - var p1 = this.p1; - var p2 = this.p2; + var d = (v2.vx - v1.vx) * (v3.vy - v1.vy) - (v2.vy - v1.vy) * (v3.vx - v1.vx); - return out.set( - QuadraticBezierInterpolation(t, p0.x, p1.x, p2.x), - QuadraticBezierInterpolation(t, p0.y, p1.y, p2.y) - ); + return (z <= 0) ? d >= 0 : d < 0; }, /** - * 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 + * Loads the data from this Vertex into the given Typed Arrays. * - * @generic {Phaser.GameObjects.Graphics} G - [graphics,$return] + * @method Phaser.Geom.Mesh.Face#load + * @since 3.50.0 * - * @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. + * @param {Float32Array} F32 - A Float32 Array to insert the position, UV and unit data in to. + * @param {Uint32Array} U32 - A Uint32 Array to insert the color and alpha data in to. + * @param {number} offset - The index of the array to insert this Vertex to. + * @param {number} textureUnit - The texture unit currently in use. + * @param {number} tintEffect - The tint effect to use. * - * @return {Phaser.GameObjects.Graphics} `Graphics` object that was drawn to. + * @return {number} The new vertex index array offset. */ - draw: function (graphics, pointsTotal) + load: function (F32, U32, offset, textureUnit, tintEffect) { - 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(); + offset = this.vertex1.load(F32, U32, offset, textureUnit, tintEffect); + offset = this.vertex2.load(F32, U32, offset, textureUnit, tintEffect); + offset = this.vertex3.load(F32, U32, offset, textureUnit, tintEffect); - // So you can chain graphics calls - return graphics; + return offset; }, /** - * Converts the curve into a JSON compatible object. + * Transforms all Face vertices by the given matrix, storing the results in their `vx`, `vy` and `vz` properties. * - * @method Phaser.Curves.QuadraticBezier#toJSON - * @since 3.2.0 + * @method Phaser.Geom.Mesh.Face#transformCoordinatesLocal + * @since 3.50.0 * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + * @param {Phaser.Math.Matrix4} transformMatrix - The transform matrix to apply to this vertex. + * @param {number} width - The width of the parent Mesh. + * @param {number} height - The height of the parent Mesh. + * @param {number} cameraZ - The z position of the MeshCamera. + * + * @return {this} This Face instance. */ - toJSON: function () + transformCoordinatesLocal: function (transformMatrix, width, height, cameraZ) { - 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]); + this.vertex1.transformCoordinatesLocal(transformMatrix, width, height, cameraZ); + this.vertex2.transformCoordinatesLocal(transformMatrix, width, height, cameraZ); + this.vertex3.transformCoordinatesLocal(transformMatrix, width, height, cameraZ); - return new QuadraticBezier(p0, p1, p2); -}; + return this; + }, -module.exports = QuadraticBezier; + /** + * Updates the bounds of this Face, based on the translated values of the vertices. + * + * Call this method prior to accessing the `Face.bounds` property. + * + * @method Phaser.Geom.Mesh.Face#updateBounds + * @since 3.50.0 + * + * @return {this} This Face instance. + */ + updateBounds: function () + { + var v1 = this.vertex1; + var v2 = this.vertex2; + var v3 = this.vertex3; + var bounds = this.bounds; -/***/ }), -/* 395 */ -/***/ (function(module, exports, __webpack_require__) { + bounds.x = Math.min(v1.vx, v2.vx, v3.vx); + bounds.y = Math.min(v1.vy, v2.vy, v3.vy); + bounds.width = Math.max(v1.vx, v2.vx, v3.vx) - bounds.x; + bounds.height = Math.max(v1.vy, v2.vy, v3.vy) - bounds.y; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog) + /** + * Checks if this Face is within the view of the given Camera. + * + * This method is called in the `MeshWebGLRenderer` function. It performs the following tasks: + * + * First, the `Vertex.update` method is called on each of the vertices. This populates them + * with the new translated values, updating their `tx`, `ty` and `ta` properties. + * + * Then it tests to see if this face is visible due to the alpha values, if not, it returns. + * + * After this, if `hideCCW` is set, it calls `isCounterClockwise` and returns if not. + * + * Finally, it will update the `Face.bounds` based on the newly translated vertex values + * and return the results of an intersection test between the bounds and the camera world view + * rectangle. + * + * @method Phaser.Geom.Mesh.Face#isInView + * @since 3.50.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against. + * @param {boolean} hideCCW - Test the counter-clockwise orientation of the verts? + * @param {number} z - The Cameras z position, used in the CCW test. + * @param {number} alpha - The alpha of the parent object. + * @param {number} a - The parent transform matrix data a component. + * @param {number} b - The parent transform matrix data b component. + * @param {number} c - The parent transform matrix data c component. + * @param {number} d - The parent transform matrix data d component. + * @param {number} e - The parent transform matrix data e component. + * @param {number} f - The parent transform matrix data f component. + * @param {boolean} roundPixels - Round the vertex position or not? + * + * @return {boolean} `true` if this Face can be seen by the Camera. + */ + isInView: function (camera, hideCCW, z, alpha, a, b, c, d, e, f, roundPixels) + { + this.update(alpha, a, b, c, d, e, f, roundPixels); -var CatmullRom = __webpack_require__(194); -var Class = __webpack_require__(0); -var Curve = __webpack_require__(94); -var Vector2 = __webpack_require__(3); + var v1 = this.vertex1; + var v2 = this.vertex2; + var v3 = this.vertex3; -/** - * @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({ + // Alpha check first + if (v1.ta <= 0 && v2.ta <= 0 && v3.ta <= 0) + { + return false; + } - Extends: Curve, + // CCW check + if (hideCCW && !this.isCounterClockwise(z)) + { + return false; + } - initialize: + // Bounds check + var bounds = this.bounds; - function SplineCurve (points) - { - if (points === undefined) { points = []; } + bounds.x = Math.min(v1.tx, v2.tx, v3.tx); + bounds.y = Math.min(v1.ty, v2.ty, v3.ty); + bounds.width = Math.max(v1.tx, v2.tx, v3.tx) - bounds.x; + bounds.height = Math.max(v1.ty, v2.ty, v3.ty) - bounds.y; - Curve.call(this, 'SplineCurve'); + var cr = camera.x + camera.width; + var cb = camera.y + camera.height; - /** - * The Vector2 points that configure the curve. - * - * @name Phaser.Curves.Spline#points - * @type {Phaser.Math.Vector2[]} - * @default [] - * @since 3.0.0 - */ - this.points = []; + if (bounds.width <= 0 || bounds.height <= 0 || camera.width <= 0 || camera.height <= 0) + { + return false; + } - this.addPoints(points); + return !(bounds.right < camera.x || bounds.bottom < camera.y || bounds.x > cr || bounds.y > cb); }, /** - * Add a list of points to the current list of Vector2 points of the curve. + * Translates the original UV positions of each vertex by the given amounts. * - * @method Phaser.Curves.Spline#addPoints - * @since 3.0.0 + * The original properties `Vertex.u` and `Vertex.v` + * remain unchanged, only the translated properties + * `Vertex.tu` and `Vertex.tv`, as used in rendering, + * are updated. * - * @param {(Phaser.Math.Vector2[]|number[]|number[][])} points - The points that configure the curve. + * @method Phaser.Geom.Mesh.Face#scrollUV + * @since 3.60.0 * - * @return {this} This curve object. + * @param {number} x - The amount to scroll the UV u coordinate by. + * @param {number} y - The amount to scroll the UV v coordinate by. + * + * @return {this} This Face instance. */ - addPoints: function (points) + scrollUV: function (x, y) { - 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); - } + this.vertex1.scrollUV(x, y); + this.vertex2.scrollUV(x, y); + this.vertex3.scrollUV(x, y); return this; }, /** - * Add a point to the current list of Vector2 points of the curve. + * Scales the original UV values of each vertex by the given amounts. * - * @method Phaser.Curves.Spline#addPoint - * @since 3.0.0 + * The original properties `Vertex.u` and `Vertex.v` + * remain unchanged, only the translated properties + * `Vertex.tu` and `Vertex.tv`, as used in rendering, + * are updated. * - * @param {number} x - The x coordinate of this curve - * @param {number} y - The y coordinate of this curve + * @method Phaser.Geom.Mesh.Face#scaleUV + * @since 3.60.0 * - * @return {Phaser.Math.Vector2} The new Vector2 added to the curve + * @param {number} x - The amount to scale the UV u coordinate by. + * @param {number} y - The amount to scale the UV v coordinate by. + * + * @return {this} This Face instance. */ - addPoint: function (x, y) + scaleUV: function (x, y) { - var vec = new Vector2(x, y); - - this.points.push(vec); + this.vertex1.scaleUV(x, y); + this.vertex2.scaleUV(x, y); + this.vertex3.scaleUV(x, y); - return vec; + return this; }, /** - * Gets the starting point on the curve. - * - * @method Phaser.Curves.Spline#getStartPoint - * @since 3.0.0 + * Sets the color value for each Vertex in this Face. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * @method Phaser.Geom.Mesh.Face#setColor + * @since 3.60.0 * - * @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created. + * @param {number} color - The color value for each vertex. * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + * @return {this} This Face instance. */ - getStartPoint: function (out) + setColor: function (color) { - if (out === undefined) { out = new Vector2(); } + this.vertex1.color = color; + this.vertex2.color = color; + this.vertex3.color = color; - return out.copy(this.points[0]); + return this; }, /** - * Get the resolution of the curve. + * Calls the `Vertex.update` method on each of the vertices. This populates them + * with the new translated values, updating their `tx`, `ty` and `ta` properties. * - * @method Phaser.Curves.Spline#getResolution - * @since 3.0.0 + * @method Phaser.Geom.Mesh.Face#update + * @since 3.60.0 * - * @param {number} divisions - Optional divisions value. + * @param {number} alpha - The alpha of the parent object. + * @param {number} a - The parent transform matrix data a component. + * @param {number} b - The parent transform matrix data b component. + * @param {number} c - The parent transform matrix data c component. + * @param {number} d - The parent transform matrix data d component. + * @param {number} e - The parent transform matrix data e component. + * @param {number} f - The parent transform matrix data f component. + * @param {boolean} roundPixels - Round the vertex position or not? * - * @return {number} The curve resolution. + * @return {this} This Face instance. */ - getResolution: function (divisions) + update: function (alpha, a, b, c, d, e, f, roundPixels) { - return divisions * this.points.length; + this.vertex1.update(a, b, c, d, e, f, roundPixels, alpha); + this.vertex2.update(a, b, c, d, e, f, roundPixels, alpha); + this.vertex3.update(a, b, c, d, e, f, roundPixels, alpha); + + return this; }, /** - * Get point at relative position in curve according to length. + * Translates the vertices of this Face by the given amounts. * - * @method Phaser.Curves.Spline#getPoint - * @since 3.0.0 + * The actual vertex positions are adjusted, not their transformed position. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * Therefore, this updates the vertex data directly. * - * @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. + * @method Phaser.Geom.Mesh.Face#translate + * @since 3.50.0 * - * @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned. + * @param {number} x - The amount to horizontally translate by. + * @param {number} [y=0] - The amount to vertically translate by. + * + * @return {this} This Face instance. */ - getPoint: function (t, out) + translate: function (x, y) { - if (out === undefined) { out = new Vector2(); } - - var points = this.points; + if (y === undefined) { y = 0; } - var point = (points.length - 1) * t; + var v1 = this.vertex1; + var v2 = this.vertex2; + var v3 = this.vertex3; - var intPoint = Math.floor(point); + v1.x += x; + v1.y += y; - var weight = point - intPoint; + v2.x += x; + v2.y += y; - 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]; + v3.x += x; + v3.y += y; - return out.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y)); + return this; }, /** - * Exports a JSON object containing this curve data. - * - * @method Phaser.Curves.Spline#toJSON - * @since 3.0.0 + * The x coordinate of this Face, based on the in center position of the Face. * - * @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data. + * @name Phaser.Geom.Mesh.Face#x + * @type {number} + * @since 3.50.0 */ - toJSON: function () - { - var points = []; + x: { - for (var i = 0; i < this.points.length; i++) + get: function () { - points.push(this.points[i].x); - points.push(this.points[i].y); - } + return this.getInCenter().x; + }, - return { - type: this.type, - points: points - }; - } + set: function (value) + { + var current = this.getInCenter(); -}); + this.translate(value - current.x, 0); + } -/** - * 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; + /** + * The y coordinate of this Face, based on the in center position of the Face. + * + * @name Phaser.Geom.Mesh.Face#y + * @type {number} + * @since 3.50.0 + */ + y: { + get: function () + { + return this.getInCenter().y; + }, -/***/ }), -/* 396 */ -/***/ (function(module, exports, __webpack_require__) { + set: function (value) + { + var current = this.getInCenter(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Class = __webpack_require__(0); + this.translate(0, value - current.y); + } -/** - * @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: + /** + * Set the alpha value of this Face. + * + * Each vertex is given the same value. If you need to adjust the alpha on a per-vertex basis + * then use the `Vertex.alpha` property instead. + * + * When getting the alpha of this Face, it will return an average of the alpha + * component of all three vertices. + * + * @name Phaser.Geom.Mesh.Face#alpha + * @type {number} + * @since 3.50.0 + */ + alpha: { - function BaseShader (key, fragmentSrc, vertexSrc, uniforms) - { - if (!fragmentSrc || fragmentSrc === '') + get: function () { - fragmentSrc = [ - 'precision mediump float;', - - 'uniform vec2 resolution;', - - 'varying vec2 fragCoord;', + var v1 = this.vertex1; + var v2 = this.vertex2; + var v3 = this.vertex3; - 'void main () {', - ' vec2 uv = fragCoord / resolution.xy;', - ' gl_FragColor = vec4(uv.xyx, 1.0);', - '}' - ].join('\n'); - } + return (v1.alpha + v2.alpha + v3.alpha) / 3; + }, - if (!vertexSrc || vertexSrc === '') + set: function (value) { - vertexSrc = [ - 'precision mediump float;', + this.vertex1.alpha = value; + this.vertex2.alpha = value; + this.vertex3.alpha = value; + } - 'uniform mat4 uProjectionMatrix;', - 'uniform mat4 uViewMatrix;', - 'uniform vec2 uResolution;', + }, - 'attribute vec2 inPosition;', + /** + * The depth of this Face, which is an average of the z component of all three vertices. + * + * The depth is calculated based on the transformed z value, not the local one. + * + * @name Phaser.Geom.Mesh.Face#depth + * @type {number} + * @readonly + * @since 3.50.0 + */ + depth: { - 'varying vec2 fragCoord;', - 'varying vec2 outTexCoord;', + get: function () + { + var v1 = this.vertex1; + var v2 = this.vertex2; + var v3 = this.vertex3; - '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'); + return (v1.vz + v2.vz + v3.vz) / 3; } - 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; + /** + * Destroys this Face and nulls the references to the vertices. + * + * @method Phaser.Geom.Mesh.Face#destroy + * @since 3.50.0 + */ + destroy: function () + { + this.vertex1 = null; + this.vertex2 = null; + this.vertex3 = null; } }); -module.exports = BaseShader; +module.exports = Face; /***/ }), -/* 397 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 99425: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Color = __webpack_require__(38); +var Face = __webpack_require__(18693); +var GetFastValue = __webpack_require__(72632); +var Matrix4 = __webpack_require__(16650); +var Vector3 = __webpack_require__(70015); +var Vertex = __webpack_require__(85769); -Color.ColorSpectrum = __webpack_require__(909); -Color.ColorToRGBA = __webpack_require__(910); -Color.ComponentToHex = __webpack_require__(398); -Color.GetColor = __webpack_require__(103); -Color.GetColor32 = __webpack_require__(328); -Color.HexStringToColor = __webpack_require__(327); -Color.HSLToColor = __webpack_require__(911); -Color.HSVColorWheel = __webpack_require__(912); -Color.HSVToRGB = __webpack_require__(188); -Color.HueToComponent = __webpack_require__(399); -Color.IntegerToColor = __webpack_require__(189); -Color.IntegerToRGB = __webpack_require__(330); -Color.Interpolate = __webpack_require__(913); -Color.ObjectToColor = __webpack_require__(331); -Color.RandomRGB = __webpack_require__(914); -Color.RGBStringToColor = __webpack_require__(332); -Color.RGBToHSV = __webpack_require__(329); -Color.RGBToString = __webpack_require__(915); -Color.ValueToColor = __webpack_require__(187); - -module.exports = Color; - - -/***/ }), -/* 398 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +var tempPosition = new Vector3(); +var tempRotation = new Vector3(); +var tempMatrix = new Matrix4(); /** - * Returns a string containing a hex representation of the given color component. + * Creates a grid of vertices based on the given configuration object and optionally adds it to a Mesh. * - * @function Phaser.Display.Color.ComponentToHex - * @since 3.0.0 + * The size of the grid is given in pixels. An example configuration may be: * - * @param {number} color - The color channel to get the hex value for, must be a value between 0 and 255. + * `{ width: 256, height: 256, widthSegments: 2, heightSegments: 2, tile: true }` * - * @return {string} A string of length 2 characters, i.e. 255 = ff, 100 = 64. + * This will create a grid 256 x 256 pixels in size, split into 2 x 2 segments, with + * the texture tiling across the cells. + * + * You can split the grid into segments both vertically and horizontally. This will + * generate two faces per grid segment as a result. + * + * The `tile` parameter allows you to control if the tile will repeat across the grid + * segments, or be displayed in full. + * + * If adding this grid to a Mesh you can offset the grid via the `x` and `y` properties. + * + * UV coordinates are generated based on the given texture and frame in the config. For + * example, no frame is given, the UVs will be in the range 0 to 1. If a frame is given, + * such as from a texture atlas, the UVs will be generated within the range of that frame. + * + * @function Phaser.Geom.Mesh.GenerateGridVerts + * @since 3.50.0 + * + * @param {Phaser.Types.Geom.Mesh.GenerateGridConfig} config - A Grid configuration object. + * + * @return {Phaser.Types.Geom.Mesh.GenerateGridVertsResult} A Grid Result object, containing the generated vertices and indicies. */ -var ComponentToHex = function (color) +var GenerateGridVerts = function (config) { - var hex = color.toString(16); - - return (hex.length === 1) ? '0' + hex : hex; -}; + var mesh = GetFastValue(config, 'mesh'); + var texture = GetFastValue(config, 'texture', null); + var frame = GetFastValue(config, 'frame'); + var width = GetFastValue(config, 'width', 1); + var height = GetFastValue(config, 'height', width); + var widthSegments = GetFastValue(config, 'widthSegments', 1); + var heightSegments = GetFastValue(config, 'heightSegments', widthSegments); + var posX = GetFastValue(config, 'x', 0); + var posY = GetFastValue(config, 'y', 0); + var posZ = GetFastValue(config, 'z', 0); + var rotateX = GetFastValue(config, 'rotateX', 0); + var rotateY = GetFastValue(config, 'rotateY', 0); + var rotateZ = GetFastValue(config, 'rotateZ', 0); + var zIsUp = GetFastValue(config, 'zIsUp', true); + var isOrtho = GetFastValue(config, 'isOrtho', (mesh) ? mesh.dirtyCache[11] : false); + var colors = GetFastValue(config, 'colors', [ 0xffffff ]); + var alphas = GetFastValue(config, 'alphas', [ 1 ]); + var tile = GetFastValue(config, 'tile', false); + var flipY = GetFastValue(config, 'flipY', false); -module.exports = ComponentToHex; + var widthSet = GetFastValue(config, 'width', null); + var result = { + faces: [], + verts: [] + }; -/***/ }), -/* 399 */ -/***/ (function(module, exports) { + tempPosition.set(posX, posY, posZ); + tempRotation.set(rotateX, rotateY, rotateZ); + tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var textureFrame; -/** - * 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) + if (!texture && mesh) { - t += 1; - } + texture = mesh.texture; - if (t > 1) + if (!frame) + { + textureFrame = mesh.frame; + } + } + else if (mesh && typeof(texture) === 'string') { - t -= 1; + texture = mesh.scene.sys.textures.get(texture); } - - if (t < 1 / 6) + else if (!texture) { - return p + (q - p) * 6 * t; + // There's nothing more we can do without a texture + return result; } - if (t < 1 / 2) + if (!textureFrame) { - return q; + textureFrame = texture.get(frame); } - if (t < 2 / 3) + // If the Mesh is ortho and no width / height is given, we'll default to texture sizes (if set!) + if (!widthSet && isOrtho && texture && mesh) { - return p + (q - p) * (2 / 3 - t) * 6; + width = textureFrame.width / mesh.height; + height = textureFrame.height / mesh.height; } - return p; -}; + var halfWidth = width / 2; + var halfHeight = height / 2; -module.exports = HueToComponent; + var gridX = Math.floor(widthSegments); + var gridY = Math.floor(heightSegments); + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; -/***/ }), -/* 400 */ -/***/ (function(module, exports, __webpack_require__) { + var segmentWidth = width / gridX; + var segmentHeight = height / gridY; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var uvs = []; + var vertices = []; -var OS = __webpack_require__(105); + var ix; + var iy; -/** - * @callback ContentLoadedCallback - */ + var frameU0 = 0; + var frameU1 = 1; + var frameV0 = 0; + var frameV1 = 1; -/** - * 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') + if (textureFrame) { - callback(); + frameU0 = textureFrame.u0; + frameU1 = textureFrame.u1; - return; + if (!flipY) + { + frameV0 = textureFrame.v0; + frameV1 = textureFrame.v1; + } + else + { + frameV0 = textureFrame.v1; + frameV1 = textureFrame.v0; + } } - var check = function () + var frameU = frameU1 - frameU0; + var frameV = frameV1 - frameV0; + + for (iy = 0; iy < gridY1; iy++) { - document.removeEventListener('deviceready', check, true); - document.removeEventListener('DOMContentLoaded', check, true); - window.removeEventListener('load', check, true); + var y = iy * segmentHeight - halfHeight; - callback(); - }; + for (ix = 0; ix < gridX1; ix++) + { + var x = ix * segmentWidth - halfWidth; - if (!document.body) + vertices.push(x, -y); + + var tu = frameU0 + frameU * (ix / gridX); + var tv = frameV0 + frameV * (iy / gridY); + + uvs.push(tu, tv); + } + } + + if (!Array.isArray(colors)) { - window.setTimeout(check, 20); + colors = [ colors ]; } - else if (OS.cordova) + + if (!Array.isArray(alphas)) { - // Ref. http://docs.phonegap.com/en/3.5.0/cordova_events_events.md.html#deviceready - document.addEventListener('deviceready', check, false); + alphas = [ alphas ]; } - else + + var alphaIndex = 0; + var colorIndex = 0; + + for (iy = 0; iy < gridY; iy++) { - document.addEventListener('DOMContentLoaded', check, true); - window.addEventListener('load', check, true); + for (ix = 0; ix < gridX; ix++) + { + var a = (ix + gridX1 * iy) * 2; + var b = (ix + gridX1 * (iy + 1)) * 2; + var c = ((ix + 1) + gridX1 * (iy + 1)) * 2; + var d = ((ix + 1) + gridX1 * iy) * 2; + + var color = colors[colorIndex]; + var alpha = alphas[alphaIndex]; + + var vert1 = new Vertex(vertices[a], vertices[a + 1], 0, uvs[a], uvs[a + 1], color, alpha).transformMat4(tempMatrix); + var vert2 = new Vertex(vertices[b], vertices[b + 1], 0, uvs[b], uvs[b + 1], color, alpha).transformMat4(tempMatrix); + var vert3 = new Vertex(vertices[d], vertices[d + 1], 0, uvs[d], uvs[d + 1], color, alpha).transformMat4(tempMatrix); + var vert4 = new Vertex(vertices[b], vertices[b + 1], 0, uvs[b], uvs[b + 1], color, alpha).transformMat4(tempMatrix); + var vert5 = new Vertex(vertices[c], vertices[c + 1], 0, uvs[c], uvs[c + 1], color, alpha).transformMat4(tempMatrix); + var vert6 = new Vertex(vertices[d], vertices[d + 1], 0, uvs[d], uvs[d + 1], color, alpha).transformMat4(tempMatrix); + + if (tile) + { + vert1.setUVs(frameU0, frameV1); + vert2.setUVs(frameU0, frameV0); + vert3.setUVs(frameU1, frameV1); + vert4.setUVs(frameU0, frameV0); + vert5.setUVs(frameU1, frameV0); + vert6.setUVs(frameU1, frameV1); + } + + colorIndex++; + + if (colorIndex === colors.length) + { + colorIndex = 0; + } + + alphaIndex++; + + if (alphaIndex === alphas.length) + { + alphaIndex = 0; + } + + result.verts.push(vert1, vert2, vert3, vert4, vert5, vert6); + + result.faces.push( + new Face(vert1, vert2, vert3), + new Face(vert4, vert5, vert6) + ); + } + } + + if (mesh) + { + mesh.faces = mesh.faces.concat(result.faces); + mesh.vertices = mesh.vertices.concat(result.verts); } + + return result; }; -module.exports = DOMContentLoaded; +module.exports = GenerateGridVerts; /***/ }), -/* 401 */ -/***/ (function(module, exports) { + +/***/ 53267: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Face = __webpack_require__(18693); +var Matrix4 = __webpack_require__(16650); +var Vector3 = __webpack_require__(70015); +var Vertex = __webpack_require__(85769); + +var tempPosition = new Vector3(); +var tempRotation = new Vector3(); +var tempMatrix = new Matrix4(); + /** - * Attempts to determine the document inner height across iOS and standard devices. - * Based on code by @tylerjpeterson + * This method will return an object containing Face and Vertex instances, generated + * from the parsed triangulated OBJ Model data given to this function. * - * @function Phaser.DOM.GetInnerHeight - * @since 3.16.0 + * The obj data should have been parsed in advance via the ParseObj function: * - * @param {boolean} iOS - Is this running on iOS? + * ```javascript + * var data = Phaser.Geom.Mesh.ParseObj(rawData, flipUV); * - * @return {number} The inner height value. + * 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 GetInnerHeight = function (iOS) +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; } - if (!iOS) + 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++) { - return window.innerHeight; - } + var model = data.models[m]; - var axis = Math.abs(window.orientation); + var vertices = model.vertices; + var textureCoords = model.textureCoords; + var faces = model.faces; - var size = { w: 0, h: 0 }; - - var ruler = document.createElement('div'); + for (var i = 0; i < faces.length; i++) + { + var face = faces[i]; - ruler.setAttribute('style', 'position: fixed; height: 100vh; width: 0; top: 0'); + var v1 = face.vertices[0]; + var v2 = face.vertices[1]; + var v3 = face.vertices[2]; - document.documentElement.appendChild(ruler); + var m1 = vertices[v1.vertexIndex]; + var m2 = vertices[v2.vertexIndex]; + var m3 = vertices[v3.vertexIndex]; - size.w = (axis === 90) ? ruler.offsetHeight : window.innerWidth; - size.h = (axis === 90) ? window.innerWidth : ruler.offsetHeight; + var t1 = v1.textureCoordsIndex; + var t2 = v2.textureCoordsIndex; + var t3 = v3.textureCoordsIndex; - document.documentElement.removeChild(ruler); + 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]; - ruler = null; + var color = 0xffffff; - if (Math.abs(window.orientation) !== 90) - { - return size.h; + 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)); + } } - else + + if (mesh) { - return size.w; + mesh.faces = mesh.faces.concat(result.faces); + mesh.vertices = mesh.vertices.concat(result.verts); } + + return result; }; -module.exports = GetInnerHeight; +module.exports = GenerateObjVerts; /***/ }), -/* 402 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 67623: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(201); +var Face = __webpack_require__(18693); +var Vertex = __webpack_require__(85769); /** - * Attempts to determine the screen orientation using the Orientation API. + * Generates a set of Face and Vertex objects by parsing the given data. * - * @function Phaser.DOM.GetScreenOrientation - * @since 3.16.0 + * This method will take vertex data in one of two formats, based on the `containsZ` parameter. * - * @param {number} width - The width of the viewport. - * @param {number} height - The height of the viewport. + * If your vertex data are `x`, `y` pairs, then `containsZ` should be `false` (this is the default) * - * @return {string} The orientation. + * 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. + * @param {boolean} [flipUV=false] - Flip the UV coordinates? + * + * @return {Phaser.Types.Geom.Mesh.GenerateVertsResult} The parsed Face and Vertex objects. */ -var GetScreenOrientation = function (width, height) +var GenerateVerts = function (vertices, uvs, indicies, containsZ, normals, colors, alphas, flipUV) { - var screen = window.screen; - var orientation = (screen) ? screen.orientation || screen.mozOrientation || screen.msOrientation : false; + if (containsZ === undefined) { containsZ = false; } + if (colors === undefined) { colors = 0xffffff; } + if (alphas === undefined) { alphas = 1; } + if (flipUV === undefined) { flipUV = false; } - if (orientation && typeof orientation.type === 'string') - { - // Screen Orientation API specification - return orientation.type; - } - else if (typeof orientation === 'string') + if (vertices.length !== uvs.length && !containsZ) { - // moz / ms-orientation are strings - return orientation; + console.warn('GenerateVerts: vertices and uvs count not equal'); + return; } - 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) + var result = { + faces: [], + vertices: [] + }; + + 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) { - if (window.matchMedia('(orientation: portrait)').matches) + for (i = 0; i < indicies.length; i++) { - return CONST.ORIENTATION.PORTRAIT; + 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]; + + if (flipUV) + { + v = 1 - v; + } + + 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.vertices.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); } - else if (window.matchMedia('(orientation: landscape)').matches) + } + else + { + var uvIndex = 0; + var colorIndex = 0; + + for (i = 0; i < vertices.length; i += iInc) { - return CONST.ORIENTATION.LANDSCAPE; + 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.vertices.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); + + uvIndex += 2; + colorIndex++; } } - else + + for (i = 0; i < result.vertices.length; i += 3) { - return (height > width) ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE; + var vert1 = result.vertices[i]; + var vert2 = result.vertices[i + 1]; + var vert3 = result.vertices[i + 2]; + + result.faces.push(new Face(vert1, vert2, vert3)); } + + return result; }; -module.exports = GetScreenOrientation; +module.exports = GenerateVerts; /***/ }), -/* 403 */ -/***/ (function(module, exports) { + +/***/ 27291: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 - */ +var flip = true; + +var defaultModelName = 'untitled'; +var currentGroup = ''; +var currentMaterial = ''; /** - * 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 + * @ignore */ +function stripComments (line) +{ + var idx = line.indexOf('#'); -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, + return (idx > -1) ? line.substring(0, idx) : line; +} - /** - * 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, +/** + * @ignore + */ +function currentModel (result) +{ + if (result.models.length === 0) + { + result.models.push({ + faces: [], + name: defaultModelName, + textureCoords: [], + vertexNormals: [], + vertices: [] + }); + } - /** - * 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, + currentGroup = ''; - /** - * 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 + 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: [] + }); -/***/ }), -/* 404 */ -/***/ (function(module, exports) { + currentGroup = ''; +} /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @ignore */ +function parseGroup (lineItems) +{ + if (lineItems.length === 2) + { + currentGroup = lineItems[1]; + } +} /** - * Phaser Scale Manager constants for orientation. - * - * @namespace Phaser.Scale.Orientation - * @memberof Phaser.Scale - * @since 3.16.0 + * @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 }); +} /** - * 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 + * @ignore */ +function parseTextureCoords (lineItems, result) +{ + var len = lineItems.length; -module.exports = { + var u = (len >= 2) ? parseFloat(lineItems[1]) : 0; + var v = (len >= 3) ? parseFloat(lineItems[2]) : 0; + var w = (len >= 4) ? parseFloat(lineItems[3]) : 0; - /** - * A landscape orientation. - * - * @name Phaser.Scale.Orientation.LANDSCAPE - * @type {string} - * @const - * @since 3.16.0 - */ - LANDSCAPE: 'landscape-primary', + if (isNaN(u)) + { + u = 0; + } - /** - * A portrait orientation. - * - * @name Phaser.Scale.Orientation.PORTRAIT - * @type {string} - * @const - * @since 3.16.0 - */ - PORTRAIT: 'portrait-primary' + if (isNaN(v)) + { + v = 0; + } -}; + if (isNaN(w)) + { + w = 0; + } + if (flip) + { + v = 1 - v; + } -/***/ }), -/* 405 */ -/***/ (function(module, exports) { + currentModel(result).textureCoords.push({ u: u, v: v, w: w }); +} /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @ignore */ +function parseVertexNormal (lineItems, result) +{ + var len = lineItems.length; -/** - * Phaser Scale Manager constants for the different scale modes available. - * - * @namespace Phaser.Scale.ScaleModes - * @memberof Phaser.Scale - * @since 3.16.0 - */ + 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 }); +} /** - * 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 + * @ignore */ +function parsePolygon (lineItems, result) +{ + var totalVertices = lineItems.length - 1; -module.exports = { + if (totalVertices < 3) + { + return; + } - /** - * 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, + var face = { + group: currentGroup, + material: currentMaterial, + vertices: [] + }; - /** - * 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, + for (var i = 0; i < totalVertices; i++) + { + var vertexString = lineItems[i + 1]; + var vertexValues = vertexString.split('/'); + var vvLen = vertexValues.length; - /** - * 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, + if (vvLen < 1 || vvLen > 3) + { + continue; + } - /** - * 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, + var vertexIndex = 0; + var textureCoordsIndex = 0; + var vertexNormalIndex = 0; - /** - * 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, + vertexIndex = parseInt(vertexValues[0], 10); - /** - * 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 + 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; -/***/ }), -/* 406 */ -/***/ (function(module, exports) { + face.vertices.push({ + textureCoordsIndex: textureCoordsIndex, + vertexIndex: vertexIndex, + vertexNormalIndex: vertexNormalIndex + }); + } + } + + currentModel(result).faces.push(face); +} /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @ignore */ +function parseMtlLib (lineItems, result) +{ + if (lineItems.length >= 2) + { + result.materialLibraries.push(lineItems[1]); + } +} /** - * Phaser Scale Manager constants for zoom modes. - * - * @namespace Phaser.Scale.Zoom - * @memberof Phaser.Scale - * @since 3.16.0 + * @ignore */ +function parseUseMtl (lineItems) +{ + if (lineItems.length >= 2) + { + currentMaterial = lineItems[1]; + } +} /** - * 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 + * 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; } -module.exports = { + flip = flipUV; - /** - * 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, + // Store results in here + var result = { + materials: {}, + materialLibraries: [], + models: [] + }; - /** - * 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, + currentGroup = ''; + currentMaterial = ''; - /** - * 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, + var lines = data.split('\n'); - /** - * 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 + 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; + /***/ }), -/* 407 */ -/***/ (function(module, exports) { + +/***/ 76799: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetColor = __webpack_require__(22946); + /** - * 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. + * Takes a Wavefront Material file and extracts the diffuse reflectivity of the named + * materials, converts them to integer color values and returns them. * - * @function Phaser.DOM.GetTarget - * @since 3.16.0 + * This is used internally by the `addOBJ` and `addModel` methods, but is exposed for + * public consumption as well. * - * @param {HTMLElement} element - The DOM element to look-up. + * 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 GetTarget = function (element) +var ParseObjMaterial = function (mtl) { - var target; + var output = {}; - if (element !== '') + var lines = mtl.split('\n'); + + var currentMaterial = ''; + + for (var i = 0; i < lines.length; i++) { - if (typeof element === 'string') + var line = lines[i].trim(); + + if (line.indexOf('#') === 0 || line === '') { - // Hopefully an element ID - target = document.getElementById(element); + continue; } - else if (element && element.nodeType === 1) + + var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); + + switch (lineItems[0].toLowerCase()) { - // Quick test for a HTMLElement - target = element; - } - } + case 'newmtl': + { + currentMaterial = lineItems[1]; + break; + } - // Fallback to the document body. Covers an invalid ID and a non HTMLElement object. - if (!target) - { - // Use the full window - target = document.body; + // 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 target; + return output; }; -module.exports = GetTarget; +module.exports = ParseObjMaterial; /***/ }), -/* 408 */ -/***/ (function(module, exports) { + +/***/ 15313: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * Rotates the vertices of a Face to the given angle. * - * @function Phaser.DOM.ParseXML - * @since 3.0.0 + * The actual vertex positions are adjusted, not their transformed positions. * - * @param {string} data - The XML source stored in a string. + * Therefore, this updates the vertex data directly. * - * @return {?(DOMParser|ActiveXObject)} The parsed XML data, or `null` if the data could not be parsed. + * @function Phaser.Geom.Mesh.RotateFace + * @since 3.50.0 + * + * @param {Phaser.Geom.Mesh.Face} face - The Face to rotate. + * @param {number} angle - The angle to rotate to, in radians. + * @param {number} [cx] - An optional center of rotation. If not given, the Face in-center is used. + * @param {number} [cy] - An optional center of rotation. If not given, the Face in-center is used. */ -var ParseXML = function (data) +var RotateFace = function (face, angle, cx, cy) { - var xml = ''; + var x; + var y; - 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) + // No point of rotation? Use the inCenter instead, then. + if (cx === undefined && cy === undefined) { - xml = null; - } + var inCenter = face.getInCenter(); - if (!xml || !xml.documentElement || xml.getElementsByTagName('parsererror').length) - { - return null; - } - else - { - return xml; + x = inCenter.x; + y = inCenter.y; } + + var c = Math.cos(angle); + var s = Math.sin(angle); + + var v1 = face.vertex1; + var v2 = face.vertex2; + var v3 = face.vertex3; + + var tx = v1.x - x; + var ty = v1.y - y; + + v1.set(tx * c - ty * s + x, tx * s + ty * c + y); + + tx = v2.x - x; + ty = v2.y - y; + + v2.set(tx * c - ty * s + x, tx * s + ty * c + y); + + tx = v3.x - x; + ty = v3.y - y; + + v3.set(tx * c - ty * s + x, tx * s + ty * c + y); }; -module.exports = ParseXML; +module.exports = RotateFace; /***/ }), -/* 409 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 85769: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(203); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(51); -var GameEvents = __webpack_require__(22); -var Keyboard = __webpack_require__(410); -var Mouse = __webpack_require__(411); -var Pointer = __webpack_require__(412); -var Touch = __webpack_require__(413); -var TransformMatrix = __webpack_require__(25); -var TransformXY = __webpack_require__(177); +var Class = __webpack_require__(56694); +var Utils = __webpack_require__(75512); +var Vector3 = __webpack_require__(70015); /** * @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. + * A Vertex Geometry Object. * - * It then manages the events, pointer creation and general hit test related operations. + * This class consists of all the information required for a single vertex within a Face Geometry Object. * - * 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. + * Faces, and thus Vertex objects, are used by the Mesh Game Object in order to render objects in WebGL. * - * @class InputManager - * @memberof Phaser.Input + * @class Vertex + * @memberof Phaser.Geom.Mesh * @constructor - * @since 3.0.0 + * @extends Phaser.Math.Vector3 + * @since 3.50.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. + * @param {number} x - The x position of the vertex. + * @param {number} y - The y position of the vertex. + * @param {number} z - The z position of the vertex. + * @param {number} u - The UV u coordinate of the vertex. + * @param {number} v - The UV v coordinate of the vertex. + * @param {number} [color=0xffffff] - The color value of the vertex. + * @param {number} [alpha=1] - The alpha value of the vertex. + * @param {number} [nx=0] - The x normal value of the vertex. + * @param {number} [ny=0] - The y normal value of the vertex. + * @param {number} [nz=0] - The z normal value of the vertex. */ -var InputManager = new Class({ +var Vertex = new Class({ + + Extends: Vector3, initialize: - function InputManager (game, config) + function Vertex (x, y, z, u, v, color, alpha, nx, ny, nz) { - /** - * 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; + if (color === undefined) { color = 0xffffff; } + if (alpha === undefined) { alpha = 1; } + if (nx === undefined) { nx = 0; } + if (ny === undefined) { ny = 0; } + if (nz === undefined) { nz = 0; } - /** - * 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 = ''; + Vector3.call(this, x, y, z); /** - * A reference to the Keyboard Manager class, if enabled via the `input.keyboard` Game Config property. + * The projected x coordinate of this vertex. * - * @name Phaser.Input.InputManager#keyboard - * @type {?Phaser.Input.Keyboard.KeyboardManager} - * @since 3.16.0 + * @name Phaser.Geom.Mesh.Vertex#vx + * @type {number} + * @since 3.50.0 */ - this.keyboard = (config.inputKeyboard) ? new Keyboard(this) : null; + this.vx = 0; /** - * A reference to the Mouse Manager class, if enabled via the `input.mouse` Game Config property. + * The projected y coordinate of this vertex. * - * @name Phaser.Input.InputManager#mouse - * @type {?Phaser.Input.Mouse.MouseManager} - * @since 3.0.0 + * @name Phaser.Geom.Mesh.Vertex#vy + * @type {number} + * @since 3.50.0 */ - this.mouse = (config.inputMouse) ? new Mouse(this) : null; + this.vy = 0; /** - * A reference to the Touch Manager class, if enabled via the `input.touch` Game Config property. + * The projected z coordinate of this vertex. * - * @name Phaser.Input.InputManager#touch - * @type {Phaser.Input.Touch.TouchManager} - * @since 3.0.0 + * @name Phaser.Geom.Mesh.Vertex#vz + * @type {number} + * @since 3.50.0 */ - this.touch = (config.inputTouch) ? new Touch(this) : null; + this.vz = 0; /** - * 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. + * The normalized projected x coordinate of this vertex. * - * @name Phaser.Input.InputManager#pointers - * @type {Phaser.Input.Pointer[]} - * @since 3.10.0 + * @name Phaser.Geom.Mesh.Vertex#nx + * @type {number} + * @since 3.50.0 */ - this.pointers = []; + this.nx = nx; /** - * 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. + * The normalized projected y coordinate of this vertex. * - * @name Phaser.Input.InputManager#pointersTotal + * @name Phaser.Geom.Mesh.Vertex#ny * @type {number} - * @readonly - * @since 3.10.0 + * @since 3.50.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); - } + this.ny = ny; /** - * 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. + * The normalized projected z coordinate of this vertex. * - * @name Phaser.Input.InputManager#mousePointer - * @type {?Phaser.Input.Pointer} - * @since 3.10.0 + * @name Phaser.Geom.Mesh.Vertex#nz + * @type {number} + * @since 3.50.0 */ - this.mousePointer = (config.inputMouse) ? this.pointers[0] : null; + this.nz = nz; /** - * 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. + * UV u coordinate of this vertex. * - * @name Phaser.Input.InputManager#activePointer - * @type {Phaser.Input.Pointer} - * @since 3.0.0 + * @name Phaser.Geom.Mesh.Vertex#u + * @type {number} + * @since 3.50.0 */ - this.activePointer = this.pointers[0]; + this.u = u; /** - * 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. + * UV v coordinate of this vertex. * - * @name Phaser.Input.InputManager#globalTopOnly - * @type {boolean} - * @default true - * @since 3.0.0 + * @name Phaser.Geom.Mesh.Vertex#v + * @type {number} + * @since 3.50.0 */ - this.globalTopOnly = true; + this.v = v; /** - * The time this Input Manager was last updated. - * This value is populated by the Game Step each frame. + * The color value of this vertex. * - * @name Phaser.Input.InputManager#time + * @name Phaser.Geom.Mesh.Vertex#color * @type {number} - * @readonly - * @since 3.16.2 + * @since 3.50.0 */ - this.time = 0; + this.color = color; /** - * A re-cycled point-like object to store hit test values in. + * The alpha value of this vertex. * - * @name Phaser.Input.InputManager#_tempPoint - * @type {{x:number, y:number}} - * @private - * @since 3.0.0 + * @name Phaser.Geom.Mesh.Vertex#alpha + * @type {number} + * @since 3.50.0 */ - this._tempPoint = { x: 0, y: 0 }; + this.alpha = alpha; /** - * A re-cycled array to store hit results in. + * The translated x coordinate of this vertex. * - * @name Phaser.Input.InputManager#_tempHitTest - * @type {array} - * @private - * @default [] - * @since 3.0.0 + * @name Phaser.Geom.Mesh.Vertex#tx + * @type {number} + * @since 3.50.0 */ - this._tempHitTest = []; + this.tx = 0; /** - * A re-cycled matrix used in hit test calculations. + * The translated y coordinate of this vertex. * - * @name Phaser.Input.InputManager#_tempMatrix - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.4.0 + * @name Phaser.Geom.Mesh.Vertex#ty + * @type {number} + * @since 3.50.0 */ - this._tempMatrix = new TransformMatrix(); + this.ty = 0; /** - * A re-cycled matrix used in hit test calculations. + * The translated alpha value of this vertex. * - * @name Phaser.Input.InputManager#_tempMatrix2 - * @type {Phaser.GameObjects.Components.TransformMatrix} - * @private - * @since 3.12.0 + * @name Phaser.Geom.Mesh.Vertex#ta + * @type {number} + * @since 3.50.0 */ - this._tempMatrix2 = new TransformMatrix(); + this.ta = 0; /** - * An internal private var that records Scenes aborting event processing. + * The translated uv u coordinate of this vertex. * - * @name Phaser.Input.InputManager#_tempSkip - * @type {boolean} - * @private - * @since 3.18.0 + * @name Phaser.Geom.Mesh.Vertex#tu + * @type {number} + * @since 3.60.0 */ - this._tempSkip = false; + this.tu = u; /** - * An internal private array that avoids needing to create a new array on every DOM mouse event. + * The translated uv v coordinate of this vertex. * - * @name Phaser.Input.InputManager#mousePointerContainer - * @type {Phaser.Input.Pointer[]} - * @private - * @since 3.18.0 + * @name Phaser.Geom.Mesh.Vertex#tv + * @type {number} + * @since 3.60.0 */ - this.mousePointerContainer = [ this.mousePointer ]; - - game.events.once(GameEvents.BOOT, this.boot, this); + this.tv = v; }, /** - * The Boot handler is called by Phaser.Game when it first starts up. - * The renderer is available by now. + * Sets the U and V properties. * - * @method Phaser.Input.InputManager#boot - * @protected - * @fires Phaser.Input.Events#MANAGER_BOOT - * @since 3.0.0 + * Also resets the translated uv properties, undoing any scale + * or shift they may have had. + * + * @method Phaser.Geom.Mesh.Vertex#setUVs + * @since 3.50.0 + * + * @param {number} u - The UV u coordinate of the vertex. + * @param {number} v - The UV v coordinate of the vertex. + * + * @return {this} This Vertex. */ - boot: function () + setUVs: function (u, v) { - this.canvas = this.game.canvas; - - this.scaleManager = this.game.scale; - - this.events.emit(Events.MANAGER_BOOT); + this.u = u; + this.v = v; - this.game.events.on(GameEvents.PRE_RENDER, this.preRender, this); + this.tu = u; + this.tv = v; - this.game.events.once(GameEvents.DESTROY, this.destroy, this); + return this; }, /** - * Internal canvas state change, called automatically by the Mouse Manager. + * Translates the original UV positions by the given amounts. * - * @method Phaser.Input.InputManager#setCanvasOver - * @fires Phaser.Input.Events#GAME_OVER - * @private - * @since 3.16.0 + * The original properties `Vertex.u` and `Vertex.v` + * remain unchanged, only the translated properties + * `Vertex.tu` and `Vertex.tv`, as used in rendering, + * are updated. * - * @param {(MouseEvent|TouchEvent)} event - The DOM Event. + * @method Phaser.Geom.Mesh.Vertex#scrollUV + * @since 3.60.0 + * + * @param {number} x - The amount to scroll the UV u coordinate by. + * @param {number} y - The amount to scroll the UV v coordinate by. + * + * @return {this} This Vertex. */ - setCanvasOver: function (event) + scrollUV: function (x, y) { - this.isOver = true; + this.tu += x; + this.tv += y; - this.events.emit(Events.GAME_OVER, event); + return this; }, /** - * Internal canvas state change, called automatically by the Mouse Manager. + * Scales the original UV values by the given amounts. * - * @method Phaser.Input.InputManager#setCanvasOut - * @fires Phaser.Input.Events#GAME_OUT - * @private - * @since 3.16.0 + * The original properties `Vertex.u` and `Vertex.v` + * remain unchanged, only the translated properties + * `Vertex.tu` and `Vertex.tv`, as used in rendering, + * are updated. * - * @param {(MouseEvent|TouchEvent)} event - The DOM Event. + * @method Phaser.Geom.Mesh.Vertex#scaleUV + * @since 3.60.0 + * + * @param {number} x - The amount to scale the UV u coordinate by. + * @param {number} y - The amount to scale the UV v coordinate by. + * + * @return {this} This Vertex. */ - setCanvasOut: function (event) + scaleUV: function (x, y) { - this.isOver = false; + this.tu = this.u * x; + this.tv = this.v * y; - this.events.emit(Events.GAME_OUT, event); + return this; }, /** - * Internal update, called automatically by the Game Step right at the start. + * Transforms this vertex by the given matrix, storing the results in `vx`, `vy` and `vz`. * - * @method Phaser.Input.InputManager#preRender - * @private - * @since 3.18.0 + * @method Phaser.Geom.Mesh.Vertex#transformCoordinatesLocal + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix4} transformMatrix - The transform matrix to apply to this vertex. + * @param {number} width - The width of the parent Mesh. + * @param {number} height - The height of the parent Mesh. + * @param {number} cameraZ - The z position of the MeshCamera. */ - preRender: function () + transformCoordinatesLocal: function (transformMatrix, width, height, cameraZ) { - var time = this.game.loop.now; - var delta = this.game.loop.delta; - var scenes = this.game.scene.getScenes(true, true); + var x = this.x; + var y = this.y; + var z = this.z; - this.time = time; + var m = transformMatrix.val; - this.events.emit(Events.MANAGER_UPDATE); + var tx = (x * m[0]) + (y * m[4]) + (z * m[8]) + m[12]; + var ty = (x * m[1]) + (y * m[5]) + (z * m[9]) + m[13]; + var tz = (x * m[2]) + (y * m[6]) + (z * m[10]) + m[14]; + var tw = (x * m[3]) + (y * m[7]) + (z * m[11]) + m[15]; - for (var i = 0; i < scenes.length; i++) - { - var scene = scenes[i]; + this.vx = (tx / tw) * width; + this.vy = -(ty / tw) * height; - 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; - } + if (cameraZ <= 0) + { + this.vz = (tz / tw); + } + else + { + this.vz = -(tz / tw); } }, /** - * 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: + * Resizes this Vertex by setting the x and y coordinates, then transforms this vertex + * by an identity matrix and dimensions, storing the results in `vx`, `vy` and `vz`. * - * 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.Geom.Mesh.Vertex#resize + * @since 3.60.0 * - * @method Phaser.Input.InputManager#setDefaultCursor - * @since 3.10.0 + * @param {number} x - The x position of the vertex. + * @param {number} y - The y position of the vertex. + * @param {number} width - The width of the parent Mesh. + * @param {number} height - The height of the parent Mesh. + * @param {number} originX - The originX of the parent Mesh. + * @param {number} originY - The originY of the parent Mesh. * - * @param {string} cursor - The CSS to be used when setting the default cursor. + * @return {this} This Vertex. */ - setDefaultCursor: function (cursor) + resize: function (x, y, width, height, originX, originY) { - this.defaultCursor = cursor; + this.x = x; + this.y = y; - if (this.canvas.style.cursor !== cursor) + this.vx = this.x * width; + this.vy = -this.y * height; + this.vz = 0; + + if (originX < 0.5) { - this.canvas.style.cursor = cursor; + this.vx += width * (0.5 - originX); } - }, - - /** - * 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) + else if (originX > 0.5) { - this.canvas.style.cursor = interactiveObject.cursor; + this.vx -= width * (originX - 0.5); } - }, - /** - * 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) + if (originY < 0.5) { - this.canvas.style.cursor = this.defaultCursor; + this.vy += height * (0.5 - originY); + } + else if (originY > 0.5) + { + this.vy -= height * (originY - 0.5); } + + return this; }, /** - * 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. + * Updates this Vertex based on the given transform. * - * @method Phaser.Input.InputManager#addPointer - * @since 3.10.0 + * @method Phaser.Geom.Mesh.Vertex#update + * @since 3.50.0 * - * @param {number} [quantity=1] The number of new Pointers to create. A maximum of 10 is allowed in total. + * @param {number} a - The parent transform matrix data a component. + * @param {number} b - The parent transform matrix data b component. + * @param {number} c - The parent transform matrix data c component. + * @param {number} d - The parent transform matrix data d component. + * @param {number} e - The parent transform matrix data e component. + * @param {number} f - The parent transform matrix data f component. + * @param {boolean} roundPixels - Round the vertex position or not? + * @param {number} alpha - The alpha of the parent object. * - * @return {Phaser.Input.Pointer[]} An array containing all of the new Pointer objects that were created. + * @return {this} This Vertex. */ - addPointer: function (quantity) + update: function (a, b, c, d, e, f, roundPixels, alpha) { - if (quantity === undefined) { quantity = 1; } - - var output = []; + var tx = this.vx * a + this.vy * c + e; + var ty = this.vx * b + this.vy * d + f; - if (this.pointersTotal + quantity > 10) + if (roundPixels) { - quantity = 10 - this.pointersTotal; + tx = Math.round(tx); + ty = Math.round(ty); } - 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); - } + this.tx = tx; + this.ty = ty; + this.ta = this.alpha * alpha; - return output; + return this; }, /** - * 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. + * Loads the data from this Vertex into the given Typed Arrays. * - * @method Phaser.Input.InputManager#updateInputPlugins - * @since 3.16.0 + * @method Phaser.Geom.Mesh.Vertex#load + * @since 3.50.0 * - * @param {number} type - The type of event to process. - * @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred. + * @param {Float32Array} F32 - A Float32 Array to insert the position, UV and unit data in to. + * @param {Uint32Array} U32 - A Uint32 Array to insert the color and alpha data in to. + * @param {number} offset - The index of the array to insert this Vertex to. + * @param {number} textureUnit - The texture unit currently in use. + * @param {number} tintEffect - The tint effect to use. + * + * @return {number} The new array offset. */ - updateInputPlugins: function (type, pointers) + load: function (F32, U32, offset, textureUnit, tintEffect) { - var scenes = this.game.scene.getScenes(true, true); + F32[++offset] = this.tx; + F32[++offset] = this.ty; + F32[++offset] = this.tu; + F32[++offset] = this.tv; + F32[++offset] = textureUnit; + F32[++offset] = tintEffect; + U32[++offset] = Utils.getTintAppendFloatAlpha(this.color, this.ta); - this._tempSkip = false; + return offset; + } - for (var i = 0; i < scenes.length; i++) - { - var scene = scenes[i]; +}); - if (scene.sys.input) - { - var capture = scene.sys.input.update(type, pointers); +module.exports = Vertex; - 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 = []; +/***/ 14293: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; +/** + * @namespace Phaser.Geom.Mesh + */ - if (!pointer.active) - { - pointer.touchstart(changedTouch, event); +var Mesh = { - this.activePointer = pointer; + Face: __webpack_require__(18693), + GenerateGridVerts: __webpack_require__(99425), + GenerateObjVerts: __webpack_require__(53267), + GenerateVerts: __webpack_require__(67623), + ParseObj: __webpack_require__(27291), + ParseObjMaterial: __webpack_require__(76799), + RotateFace: __webpack_require__(15313), + Vertex: __webpack_require__(85769) - changed.push(pointer); +}; - break; - } - } - } +module.exports = Mesh; - 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]; +/***/ 77601: +/***/ ((module) => { - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (pointer.active && pointer.identifier === changedTouch.identifier) - { - pointer.touchmove(changedTouch, event); +/** + * Apply `Math.ceil()` to each coordinate of the given Point. + * + * @function Phaser.Geom.Point.Ceil + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [point,$return] + * + * @param {Phaser.Geom.Point} point - The Point to ceil. + * + * @return {Phaser.Geom.Point} The Point with `Math.ceil()` applied to its coordinates. + */ +var Ceil = function (point) +{ + return point.setTo(Math.ceil(point.x), Math.ceil(point.y)); +}; - this.activePointer = pointer; +module.exports = Ceil; - 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 = []; +/***/ 38933: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; +var Point = __webpack_require__(79967); - if (pointer.active && pointer.identifier === changedTouch.identifier) - { - pointer.touchend(changedTouch, event); +/** + * Clone the given Point. + * + * @function Phaser.Geom.Point.Clone + * @since 3.0.0 + * + * @param {Phaser.Geom.Point} source - The source Point to clone. + * + * @return {Phaser.Geom.Point} The cloned Point. + */ +var Clone = function (source) +{ + return new Point(source.x, source.y); +}; - changed.push(pointer); +module.exports = Clone; - 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 = []; +/***/ 47103: +/***/ ((module) => { - for (var c = 0; c < event.changedTouches.length; c++) - { - var changedTouch = event.changedTouches[c]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (var i = 1; i < this.pointersTotal; i++) - { - var pointer = pointers[i]; +/** + * Copy the values of one Point to a destination Point. + * + * @function Phaser.Geom.Point.CopyFrom + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [dest,$return] + * + * @param {Phaser.Geom.Point} source - The source Point to copy the values from. + * @param {Phaser.Geom.Point} dest - The destination Point to copy the values to. + * + * @return {Phaser.Geom.Point} The destination Point. + */ +var CopyFrom = function (source, dest) +{ + return dest.setTo(source.x, source.y); +}; - if (pointer.active && pointer.identifier === changedTouch.identifier) - { - pointer.touchcancel(changedTouch, event); +module.exports = CopyFrom; - changed.push(pointer); - break; - } - } - } +/***/ }), - this.updateInputPlugins(CONST.TOUCH_CANCEL, changed); - }, +/***/ 13625: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - mousePointer.down(event); +/** + * A comparison of two `Point` objects to see if they are equal. + * + * @function Phaser.Geom.Point.Equals + * @since 3.0.0 + * + * @param {Phaser.Geom.Point} point - The original `Point` to compare against. + * @param {Phaser.Geom.Point} toCompare - The second `Point` to compare. + * + * @return {boolean} Returns true if the both `Point` objects are equal. + */ +var Equals = function (point, toCompare) +{ + return (point.x === toCompare.x && point.y === toCompare.y); +}; - mousePointer.updateMotion(); +module.exports = Equals; - 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; +/***/ 12536: +/***/ ((module) => { - mousePointer.move(event); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - mousePointer.updateMotion(); +/** + * Apply `Math.ceil()` to each coordinate of the given Point. + * + * @function Phaser.Geom.Point.Floor + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [point,$return] + * + * @param {Phaser.Geom.Point} point - The Point to floor. + * + * @return {Phaser.Geom.Point} The Point with `Math.floor()` applied to its coordinates. + */ +var Floor = function (point) +{ + return point.setTo(Math.floor(point.x), Math.floor(point.y)); +}; - this.activePointer = mousePointer; +module.exports = Floor; - 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); +/***/ 54205: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - mousePointer.updateMotion(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.activePointer = mousePointer; +var Point = __webpack_require__(79967); - this.updateInputPlugins(CONST.MOUSE_UP, this.mousePointerContainer); - }, +/** + * Get the centroid or geometric center of a plane figure (the arithmetic mean position of all the points in the figure). + * Informally, it is the point at which a cutout of the shape could be perfectly balanced on the tip of a pin. + * + * @function Phaser.Geom.Point.GetCentroid + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Types.Math.Vector2Like[]} points - An array of Vector2Like objects to get the geometric center of. + * @param {Phaser.Geom.Point} [out] - A Point object to store the output coordinates in. If not given, a new Point instance is created. + * + * @return {Phaser.Geom.Point} A Point object representing the geometric center of the given points. + */ +var GetCentroid = function (points, out) +{ + if (out === undefined) { out = new Point(); } - /** - * 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) + if (!Array.isArray(points)) { - var mousePointer = this.mousePointer; - - mousePointer.wheel(event); - - this.activePointer = mousePointer; + throw new Error('GetCentroid points argument must be an array'); + } - this.updateInputPlugins(CONST.MOUSE_WHEEL, this.mousePointerContainer); - }, + var len = points.length; - /** - * 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) + if (len < 1) { - 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) + throw new Error('GetCentroid points array must not be empty'); + } + else if (len === 1) { - var input = gameObject.input; - - if (!input || !input.enabled || (!input.alwaysEnabled && !gameObject.willRender(camera))) + out.x = points[0].x; + out.y = points[0].y; + } + else + { + for (var i = 0; i < len; i++) { - return false; + out.x += points[i].x; + out.y += points[i].y; } - var visible = true; - var parent = gameObject.parentContainer; + out.x /= len; + out.y /= len; + } - if (parent) - { - do - { - if (!parent.willRender(camera)) - { - visible = false; - break; - } + return out; +}; - parent = parent.parentContainer; +module.exports = GetCentroid; - } 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; } +/***/ 50083: +/***/ ((module) => { - var tempPoint = this._tempPoint; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var csx = camera.scrollX; - var csy = camera.scrollY; +/** + * 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)); +}; - output.length = 0; +module.exports = GetMagnitude; - 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; +/***/ 82712: +/***/ ((module) => { - var point = { x: 0, y: 0 }; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var matrix = this._tempMatrix; - var parentMatrix = this._tempMatrix2; +/** + * 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); +}; - for (var i = 0; i < gameObjects.length; i++) - { - var gameObject = gameObjects[i]; +module.exports = GetMagnitudeSq; - // 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); +/***/ 20052: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - matrix.applyInverse(px, py, point); - } - else - { - TransformXY(px, py, gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX, gameObject.scaleY, point); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (this.pointWithinHitArea(gameObject, point.x, point.y)) - { - output.push(gameObject); - } - } +var Rectangle = __webpack_require__(74118); - return output; - }, +/** + * Calculates the Axis Aligned Bounding Box (or aabb) from an array of points. + * + * @function Phaser.Geom.Point.GetRectangleFromPoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * + * @param {Phaser.Types.Math.Vector2Like[]} points - An array of Vector2Like objects to get the AABB from. + * @param {Phaser.Geom.Rectangle} [out] - A Rectangle object to store the results in. If not given, a new Rectangle instance is created. + * + * @return {Phaser.Geom.Rectangle} A Rectangle object holding the AABB values for the given points. + */ +var GetRectangleFromPoints = function (points, out) +{ + if (out === undefined) { out = new Rectangle(); } - /** - * 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 xMax = Number.NEGATIVE_INFINITY; + var xMin = Number.POSITIVE_INFINITY; + var yMax = Number.NEGATIVE_INFINITY; + var yMin = Number.POSITIVE_INFINITY; - var input = gameObject.input; + for (var i = 0; i < points.length; i++) + { + var point = points[i]; - if (input && input.hitAreaCallback(input.hitArea, x, y, gameObject)) + if (point.x > xMax) { - input.localX = x; - input.localY = y; + xMax = point.x; + } - return true; + if (point.x < xMin) + { + xMin = point.x; } - else + + if (point.y > yMax) { - return false; + yMax = point.y; } - }, - /** - * 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) + if (point.y < yMin) { - return false; + yMin = point.y; } + } - // Normalize the origin - x += object.gameObject.displayOriginX; - y += object.gameObject.displayOriginY; + out.x = xMin; + out.y = yMin; + out.width = xMax - xMin; + out.height = yMax - yMin; - object.localX = x; - object.localY = y; + return out; +}; - return object.hitAreaCallback(object.hitArea, x, y, object); - }, +module.exports = GetRectangleFromPoints; - /** - * 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); +/***/ 77154: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var a = pointer.smoothFactor; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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); - } - }, +var Point = __webpack_require__(79967); - /** - * 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(); +/** + * Returns the linear interpolation point between the two given points, based on `t`. + * + * @function Phaser.Geom.Point.Interpolate + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Point} pointA - The starting `Point` for the interpolation. + * @param {Phaser.Geom.Point} pointB - The target `Point` for the interpolation. + * @param {number} [t=0] - The amount to interpolate between the two points. Generally, a value between 0 (returns the starting `Point`) and 1 (returns the target `Point`). If omitted, 0 is used. + * @param {(Phaser.Geom.Point|object)} [out] - An optional `Point` object whose `x` and `y` values will be set to the result of the interpolation (can also be any object with `x` and `y` properties). If omitted, a new `Point` created and returned. + * + * @return {(Phaser.Geom.Point|object)} Either the object from the `out` argument with the properties `x` and `y` set to the result of the interpolation or a newly created `Point` object. + */ +var Interpolate = function (pointA, pointB, t, out) +{ + if (t === undefined) { t = 0; } + if (out === undefined) { out = new Point(); } - this.game.events.off(GameEvents.PRE_RENDER); + out.x = pointA.x + ((pointB.x - pointA.x) * t); + out.y = pointA.y + ((pointB.y - pointA.y) * t); - if (this.keyboard) - { - this.keyboard.destroy(); - } + return out; +}; - if (this.mouse) - { - this.mouse.destroy(); - } +module.exports = Interpolate; - 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; - } +/***/ 42397: +/***/ ((module) => { -}); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = InputManager; +/** + * Swaps the X and the Y coordinate of a point. + * + * @function Phaser.Geom.Point.Invert + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [point,$return] + * + * @param {Phaser.Geom.Point} point - The Point to modify. + * + * @return {Phaser.Geom.Point} The modified `point`. + */ +var Invert = function (point) +{ + return point.setTo(point.y, point.x); +}; + +module.exports = Invert; /***/ }), -/* 410 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 59464: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayRemove = __webpack_require__(93); -var Class = __webpack_require__(0); -var GameEvents = __webpack_require__(22); -var InputEvents = __webpack_require__(51); -var KeyCodes = __webpack_require__(143); -var NOOP = __webpack_require__(1); +var Point = __webpack_require__(79967); /** - * @classdesc - * The Keyboard Manager is a helper class that belongs to the global Input Manager. + * Inverts a Point's coordinates. * - * Its role is to listen for native DOM Keyboard Events and then store them for further processing by the Keyboard Plugin. + * @function Phaser.Geom.Point.Negative + * @since 3.0.0 * - * 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. + * @generic {Phaser.Geom.Point} O - [out,$return] * - * @class KeyboardManager - * @memberof Phaser.Input.Keyboard - * @constructor - * @since 3.16.0 + * @param {Phaser.Geom.Point} point - The Point to invert. + * @param {Phaser.Geom.Point} [out] - The Point to return the inverted coordinates in. * - * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. + * @return {Phaser.Geom.Point} The modified `out` Point, or a new Point if none was provided. */ -var KeyboardManager = new Class({ +var Negative = function (point, out) +{ + if (out === undefined) { out = new Point(); } - initialize: + return out.setTo(-point.x, -point.y); +}; - 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; +module.exports = Negative; - /** - * 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 = []; +/***/ 79967: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var GEOM_CONST = __webpack_require__(52394); + +/** + * @classdesc + * Defines a Point in 2D space, with an x and y component. + * + * @class Point + * @memberof Phaser.Geom + * @constructor + * @since 3.0.0 + * + * @param {number} [x=0] - The x coordinate of this Point. + * @param {number} [y=x] - The y coordinate of this Point. + */ +var Point = new Class({ + + initialize: + + function Point (x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } /** - * The 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. + * The geometry constant type of this object: `GEOM_CONST.POINT`. + * Used for fast type comparisons. * - * @name Phaser.Input.Keyboard.KeyboardManager#target - * @type {any} - * @since 3.16.0 + * @name Phaser.Geom.Point#type + * @type {number} + * @readonly + * @since 3.19.0 */ - this.target; + this.type = GEOM_CONST.POINT; /** - * The Key Down Event handler. - * This function is sent the native DOM KeyEvent. - * Initially empty and bound in the `startListeners` method. + * The x coordinate of this Point. * - * @name Phaser.Input.Keyboard.KeyboardManager#onKeyDown - * @type {function} - * @since 3.16.00 + * @name Phaser.Geom.Point#x + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.onKeyDown = NOOP; + this.x = x; /** - * The Key Up Event handler. - * This function is sent the native DOM KeyEvent. - * Initially empty and bound in the `startListeners` method. + * The y coordinate of this Point. * - * @name Phaser.Input.Keyboard.KeyboardManager#onKeyUp - * @type {function} - * @since 3.16.00 + * @name Phaser.Geom.Point#y + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.onKeyUp = NOOP; - - inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); + this.y = y; }, /** - * The Keyboard Manager boot process. + * Set the x and y coordinates of the point to the given values. * - * @method Phaser.Input.Keyboard.KeyboardManager#boot - * @private - * @since 3.16.0 + * @method Phaser.Geom.Point#setTo + * @since 3.0.0 + * + * @param {number} [x=0] - The x coordinate of this Point. + * @param {number} [y=x] - The y coordinate of this Point. + * + * @return {this} This Point object. */ - boot: function () + setTo: function (x, y) { - var config = this.manager.config; + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } - this.enabled = config.inputKeyboard; - this.target = config.inputKeyboardEventTarget; + this.x = x; + this.y = y; - this.addCapture(config.inputKeyboardCapture); + return this; + } - if (!this.target && window) - { - this.target = window; - } +}); - if (this.enabled && this.target) - { - this.startListeners(); - } +module.exports = Point; - 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; - } +/***/ 53581: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - _this.queue.push(event); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - _this.manager.events.emit(InputEvents.MANAGER_PROCESS); +var Point = __webpack_require__(79967); +var GetMagnitudeSq = __webpack_require__(82712); - var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); +/** + * Calculates the vector projection of `pointA` onto the nonzero `pointB`. This is the + * orthogonal projection of `pointA` onto a straight line parallel to `pointB`. + * + * @function Phaser.Geom.Point.Project + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Point} pointA - Point A, to be projected onto Point B. + * @param {Phaser.Geom.Point} pointB - Point B, to have Point A projected upon it. + * @param {Phaser.Geom.Point} [out] - The Point object to store the position in. If not given, a new Point instance is created. + * + * @return {Phaser.Geom.Point} A Point object holding the coordinates of the vector projection of `pointA` onto `pointB`. + */ +var Project = function (pointA, pointB, out) +{ + if (out === undefined) { out = new Point(); } - if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) - { - event.preventDefault(); - } - }; + var dot = ((pointA.x * pointB.x) + (pointA.y * pointB.y)); + var amt = dot / GetMagnitudeSq(pointB); - this.onKeyUp = function (event) - { - if (event.defaultPrevented || !_this.enabled || !_this.manager) - { - // Do nothing if event already handled - return; - } + if (amt !== 0) + { + out.x = amt * pointB.x; + out.y = amt * pointB.y; + } - _this.queue.push(event); + return out; +}; - _this.manager.events.emit(InputEvents.MANAGER_PROCESS); +module.exports = Project; - 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; +/***/ 50817: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (target) - { - target.addEventListener('keydown', this.onKeyDown, false); - target.addEventListener('keyup', this.onKeyUp, false); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.enabled = true; - } - }, +var Point = __webpack_require__(79967); - /** - * 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 () +/** + * Calculates the vector projection of `pointA` onto the nonzero `pointB`. This is the + * orthogonal projection of `pointA` onto a straight line paralle to `pointB`. + * + * @function Phaser.Geom.Point.ProjectUnit + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Point} pointA - Point A, to be projected onto Point B. Must be a normalized point with a magnitude of 1. + * @param {Phaser.Geom.Point} pointB - Point B, to have Point A projected upon it. + * @param {Phaser.Geom.Point} [out] - The Point object to store the position in. If not given, a new Point instance is created. + * + * @return {Phaser.Geom.Point} A unit Point object holding the coordinates of the vector projection of `pointA` onto `pointB`. + */ +var ProjectUnit = function (pointA, pointB, out) +{ + if (out === undefined) { out = new Point(); } + + var amt = ((pointA.x * pointB.x) + (pointA.y * pointB.y)); + + if (amt !== 0) { - var target = this.target; + out.x = amt * pointB.x; + out.y = amt * pointB.y; + } - target.removeEventListener('keydown', this.onKeyDown, false); - target.removeEventListener('keyup', this.onKeyUp, false); + return out; +}; - this.enabled = false; - }, +module.exports = ProjectUnit; - /** - * Clears the event queue. - * Called automatically by the Input Manager. - * - * @method Phaser.Input.Keyboard.KeyboardManager#postUpdate - * @private - * @since 3.16.0 - */ - postUpdate: function () + +/***/ }), + +/***/ 40525: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetMagnitude = __webpack_require__(50083); + +/** + * Changes the magnitude (length) of a two-dimensional vector without changing its direction. + * + * @function Phaser.Geom.Point.SetMagnitude + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [point,$return] + * + * @param {Phaser.Geom.Point} point - The Point to treat as the end point of the vector. + * @param {number} magnitude - The new magnitude of the vector. + * + * @return {Phaser.Geom.Point} The modified Point. + */ +var SetMagnitude = function (point, magnitude) +{ + if (point.x !== 0 || point.y !== 0) { - this.queue = []; - }, + var m = GetMagnitude(point); - /** - * 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(','); - } + point.x /= m; + point.y /= m; + } - if (!Array.isArray(keycode)) - { - keycode = [ keycode ]; - } + point.x *= magnitude; + point.y *= magnitude; - var captures = this.captures; + return point; +}; - for (var i = 0; i < keycode.length; i++) - { - var code = keycode[i]; +module.exports = SetMagnitude; - if (typeof code === 'string') - { - code = KeyCodes[code.trim().toUpperCase()]; - } - if (captures.indexOf(code) === -1) - { - captures.push(code); - } - } +/***/ }), - this.preventDefault = captures.length > 0; - }, +/***/ 63472: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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(','); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (!Array.isArray(keycode)) - { - keycode = [ keycode ]; - } +var Point = __webpack_require__(79967); - var captures = this.captures; +Point.Ceil = __webpack_require__(77601); +Point.Clone = __webpack_require__(38933); +Point.CopyFrom = __webpack_require__(47103); +Point.Equals = __webpack_require__(13625); +Point.Floor = __webpack_require__(12536); +Point.GetCentroid = __webpack_require__(54205); +Point.GetMagnitude = __webpack_require__(50083); +Point.GetMagnitudeSq = __webpack_require__(82712); +Point.GetRectangleFromPoints = __webpack_require__(20052); +Point.Interpolate = __webpack_require__(77154); +Point.Invert = __webpack_require__(42397); +Point.Negative = __webpack_require__(59464); +Point.Project = __webpack_require__(53581); +Point.ProjectUnit = __webpack_require__(50817); +Point.SetMagnitude = __webpack_require__(40525); - for (var i = 0; i < keycode.length; i++) - { - var code = keycode[i]; +module.exports = Point; - if (typeof code === 'string') - { - code = KeyCodes[code.toUpperCase()]; - } - ArrayRemove(captures, code); - } +/***/ }), - this.preventDefault = captures.length > 0; - }, +/***/ 19631: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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 = []; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.preventDefault = false; - }, +var Polygon = __webpack_require__(8580); - /** - * Destroys this Keyboard Manager instance. - * - * @method Phaser.Input.Keyboard.KeyboardManager#destroy - * @since 3.16.0 - */ - destroy: function () - { - this.stopListeners(); +/** + * Create a new polygon which is a copy of the specified polygon + * + * @function Phaser.Geom.Polygon.Clone + * @since 3.0.0 + * + * @param {Phaser.Geom.Polygon} polygon - The polygon to create a clone of + * + * @return {Phaser.Geom.Polygon} A new separate Polygon cloned from the specified polygon, based on the same points. + */ +var Clone = function (polygon) +{ + return new Polygon(polygon.points); +}; - this.clearCaptures(); +module.exports = Clone; - this.queue = []; - this.manager.game.events.off(GameEvents.POST_RENDER, this.postUpdate, this); +/***/ }), - this.target = null; - this.enabled = false; - this.manager = null; +/***/ 45604: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Checks whether the x and y coordinates are contained within this polygon. +// Adapted from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html by Jonas Raoni Soares Silva + +/** + * Checks if a point is within the bounds of a Polygon. + * + * @function Phaser.Geom.Polygon.Contains + * @since 3.0.0 + * + * @param {Phaser.Geom.Polygon} polygon - The Polygon to check against. + * @param {number} x - The X coordinate of the point to check. + * @param {number} y - The Y coordinate of the point to check. + * + * @return {boolean} `true` if the point is within the bounds of the Polygon, otherwise `false`. + */ +var Contains = function (polygon, x, y) +{ + var inside = false; + + for (var i = -1, j = polygon.points.length - 1; ++i < polygon.points.length; j = i) + { + var ix = polygon.points[i].x; + var iy = polygon.points[i].y; + + var jx = polygon.points[j].x; + var jy = polygon.points[j].y; + + if (((iy <= y && y < jy) || (jy <= y && y < iy)) && (x < (jx - ix) * (y - iy) / (jy - iy) + ix)) + { + inside = !inside; + } } -}); + return inside; +}; -module.exports = KeyboardManager; +module.exports = Contains; /***/ }), -/* 411 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 87289: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Features = __webpack_require__(191); -var InputEvents = __webpack_require__(51); -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 +var Contains = __webpack_require__(45604); /** - * @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. + * Checks the given Point again the Polygon to see if the Point lays within its vertices. * - * @class MouseManager - * @memberof Phaser.Input.Mouse - * @constructor + * @function Phaser.Geom.Polygon.ContainsPoint * @since 3.0.0 * - * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. + * @param {Phaser.Geom.Polygon} polygon - The Polygon to check. + * @param {Phaser.Geom.Point} point - The Point to check if it's within the Polygon. + * + * @return {boolean} `true` if the Point is within the Polygon, otherwise `false`. */ -var MouseManager = new Class({ +var ContainsPoint = function (polygon, point) +{ + return Contains(polygon, point.x, point.y); +}; - initialize: +module.exports = ContainsPoint; - 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; +/***/ 11117: +/***/ ((module) => { - /** - * 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; +"use strict"; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +/** + * This module implements a modified ear slicing algorithm, optimized by z-order curve hashing and extended to + * handle holes, twisted polygons, degeneracies and self-intersections in a way that doesn't guarantee correctness + * of triangulation, but attempts to always produce acceptable results for practical data. + * + * Example: + * + * ```javascript + * const triangles = Phaser.Geom.Polygon.Earcut([10,0, 0,50, 60,60, 70,10]); // returns [1,0,3, 3,2,1] + * ``` + * + * Each group of three vertex indices in the resulting array forms a triangle. + * + * ```javascript + * // triangulating a polygon with a hole + * earcut([0,0, 100,0, 100,100, 0,100, 20,20, 80,20, 80,80, 20,80], [4]); + * // [3,0,4, 5,4,0, 3,4,7, 5,0,1, 2,3,7, 6,5,1, 2,7,6, 6,1,2] + * + * // triangulating a polygon with 3d coords + * earcut([10,0,1, 0,50,2, 60,60,3, 70,10,4], null, 3); + * // [1,0,3, 3,2,1] + * ``` + * + * If you pass a single vertex as a hole, Earcut treats it as a Steiner point. + * + * If your input is a multi-dimensional array (e.g. GeoJSON Polygon), you can convert it to the format + * expected by Earcut with `Phaser.Geom.Polygon.Earcut.flatten`: + * + * ```javascript + * var data = earcut.flatten(geojson.geometry.coordinates); + * var triangles = earcut(data.vertices, data.holes, data.dimensions); + * ``` + * + * After getting a triangulation, you can verify its correctness with `Phaser.Geom.Polygon.Earcut.deviation`: + * + * ```javascript + * var deviation = earcut.deviation(vertices, holes, dimensions, triangles); + * ``` + * Returns the relative difference between the total area of triangles and the area of the input polygon. + * 0 means the triangulation is fully correct. + * + * For more information see https://github.com/mapbox/earcut + * + * @function Phaser.Geom.Polygon.Earcut + * @since 3.50.0 + * + * @param {number[]} data - A flat array of vertex coordinate, like [x0,y0, x1,y1, x2,y2, ...] + * @param {number[]} [holeIndices] - An array of hole indices if any (e.g. [5, 8] for a 12-vertex input would mean one hole with vertices 5–7 and another with 8–11). + * @param {number} [dimensions=2] - The number of coordinates per vertex in the input array (2 by default). + * + * @return {number[]} An array of triangulated data. + */ - /** - * 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; + // Earcut 2.2.4 (July 5th 2022) - /** - * 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; +/* + * ISC License + * + * Copyright (c) 2016, Mapbox + * + * Permission to use, copy, modify, and/or distribute this software for any purpose + * with or without fee is hereby granted, provided that the above copyright notice + * and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ - /** - * 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; +function earcut(data, holeIndices, dim) { - /** - * 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; + dim = dim || 2; - /** - * 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; + var hasHoles = holeIndices && holeIndices.length, + outerLen = hasHoles ? holeIndices[0] * dim : data.length, + outerNode = linkedList(data, 0, outerLen, dim, true), + triangles = []; - /** - * 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; + if (!outerNode || outerNode.next === outerNode.prev) return triangles; - /** - * 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; + var minX, minY, maxX, maxY, x, y, invSize; - /** - * 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; + if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); - /** - * 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; + // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox + if (data.length > 80 * dim) { + minX = maxX = data[0]; + minY = maxY = data[1]; - /** - * 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; + for (var i = dim; i < outerLen; i += dim) { + x = data[i]; + y = data[i + 1]; + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + } - /** - * 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; + // minX, minY and invSize are later used to transform coords into integers for z-order calculation + invSize = Math.max(maxX - minX, maxY - minY); + invSize = invSize !== 0 ? 32767 / invSize : 0; + } - inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); - }, + earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0); - /** - * The Touch Manager boot process. - * - * @method Phaser.Input.Mouse.MouseManager#boot - * @private - * @since 3.0.0 - */ - boot: function () - { - var config = this.manager.config; + return triangles; +} - this.enabled = config.inputMouse; - this.target = config.inputMouseEventTarget; - this.passive = config.inputMousePassive; +// create a circular doubly linked list from polygon points in the specified winding order +function linkedList(data, start, end, dim, clockwise) { + var i, last; - this.preventDefaultDown = config.inputMousePreventDefaultDown; - this.preventDefaultUp = config.inputMousePreventDefaultUp; - this.preventDefaultMove = config.inputMousePreventDefaultMove; - this.preventDefaultWheel = config.inputMousePreventDefaultWheel; + if (clockwise === (signedArea(data, start, end, dim) > 0)) { + for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); + } else { + for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); + } - if (!this.target) - { - this.target = this.manager.game.canvas; - } - else if (typeof this.target === 'string') - { - this.target = document.getElementById(this.target); - } + if (last && equals(last, last.next)) { + removeNode(last); + last = last.next; + } - if (config.disableContextMenu) - { - this.disableContextMenu(); - } + return last; +} - if (this.enabled && this.target) - { - this.startListeners(); +// eliminate colinear or duplicate points +function filterPoints(start, end) { + if (!start) return start; + if (!end) end = start; + + var p = start, + again; + do { + again = false; + + if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { + removeNode(p); + p = end = p.prev; + if (p === p.next) break; + again = true; + + } else { + p = p.next; } - }, + } while (again || p !== end); - /** - * 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 end; +} - return this; - }, +// main ear slicing loop which triangulates a polygon (given as a linked list) +function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { + if (!ear) return; - /** - * 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; + // interlink polygon nodes in z-order + if (!pass && invSize) indexCurve(ear, minX, minY, invSize); - element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock; + var stop = ear, + prev, next; - element.requestPointerLock(); - } - }, + // iterate through ears, slicing them one by one + while (ear.prev !== ear.next) { + prev = ear.prev; + next = ear.next; - /** - * 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(); - } - }, + if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { + // cut off the triangle + triangles.push(prev.i / dim | 0); + triangles.push(ear.i / dim | 0); + triangles.push(next.i / dim | 0); - /** - * 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; + removeNode(ear); - if (!target) - { - return; + // skipping the next vertex leads to less sliver triangles + ear = next.next; + stop = next.next; + + continue; } - var _this = this; - var manager = this.manager; - var canvas = manager.canvas; - var autoFocus = (window && window.focus && manager.game.config.autoFocus); + ear = next; - this.onMouseMove = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseMove(event); + // if we looped through the whole remaining polygon and can't find any more ears + if (ear === stop) { + // try filtering points and slicing again + if (!pass) { + earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); - if (_this.preventDefaultMove) - { - event.preventDefault(); - } - } - }; + // if this didn't work, try curing all small self-intersections locally + } else if (pass === 1) { + ear = cureLocalIntersections(filterPoints(ear), triangles, dim); + earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); - this.onMouseDown = function (event) - { - if (autoFocus) - { - window.focus(); + // as a last resort, try splitting the remaining polygon into two + } else if (pass === 2) { + splitEarcut(ear, triangles, dim, minX, minY, invSize); } - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseDown(event); + break; + } + } +} - if (_this.preventDefaultDown && event.target === canvas) - { - event.preventDefault(); - } - } - }; +// check whether a polygon node forms a valid ear with adjacent nodes +function isEar(ear) { + var a = ear.prev, + b = ear, + c = ear.next; - 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); - } - }; + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - this.onMouseUp = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseUp(event); + // now make sure we don't have other points inside the potential ear + var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; - if (_this.preventDefaultUp && event.target === canvas) - { - event.preventDefault(); - } - } - }; + // triangle bbox; min & max are calculated like this for speed + var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx), + y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy), + x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx), + y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy); + + var p = c.next; + while (p !== a) { + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && + pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.next; + } - 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); - } - }; + return true; +} - this.onMouseOver = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.setCanvasOver(event); - } - }; +function isEarHashed(ear, minX, minY, invSize) { + var a = ear.prev, + b = ear, + c = ear.next; - this.onMouseOut = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.setCanvasOut(event); - } - }; + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear - this.onMouseWheel = function (event) - { - if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) - { - manager.onMouseWheel(event); - } + var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y; - if (_this.preventDefaultWheel && event.target === canvas) - { - event.preventDefault(); - } - }; + // triangle bbox; min & max are calculated like this for speed + var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx), + y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy), + x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx), + y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy); - var passive = { passive: true }; + // z-order range for the current triangle bbox; + var minZ = zOrder(x0, y0, minX, minY, invSize), + maxZ = zOrder(x1, y1, minX, minY, invSize); - 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); + var p = ear.prevZ, + n = ear.nextZ; - if (this.preventDefaultWheel) - { - target.addEventListener('wheel', this.onMouseWheel, { passive: false }); - } - else - { - target.addEventListener('wheel', this.onMouseWheel, passive); - } + // look for points inside the triangle in both directions + while (p && p.z >= minZ && n && n.z <= maxZ) { + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && + pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; - 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); + if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && + pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; + n = n.nextZ; + } - this.isTop = false; - } - } + // look for remaining points in decreasing z-order + while (p && p.z >= minZ) { + if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && + pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; + } - if (Features.pointerLock) - { - this.pointerLockChange = function (event) - { - var element = _this.target; + // look for remaining points in increasing z-order + while (n && n.z <= maxZ) { + if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && + pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; + n = n.nextZ; + } - _this.locked = (document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element) ? true : false; + return true; +} - manager.onPointerLockChange(event); - }; +// go through all polygon nodes and cure small local self-intersections +function cureLocalIntersections(start, triangles, dim) { + var p = start; + do { + var a = p.prev, + b = p.next.next; - document.addEventListener('pointerlockchange', this.pointerLockChange, true); - document.addEventListener('mozpointerlockchange', this.pointerLockChange, true); - document.addEventListener('webkitpointerlockchange', this.pointerLockChange, true); - } + if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { - this.enabled = true; - }, + triangles.push(a.i / dim | 0); + triangles.push(p.i / dim | 0); + triangles.push(b.i / dim | 0); - /** - * 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; + // remove two nodes involved + removeNode(p); + removeNode(p.next); - 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); + p = start = b; + } + p = p.next; + } while (p !== start); - if (window) - { - target = (this.isTop) ? window.top : window; + return filterPoints(p); +} - target.removeEventListener('mousedown', this.onMouseDownWindow); - target.removeEventListener('mouseup', this.onMouseUpWindow); - } +// try splitting polygon into two and triangulate them independently +function splitEarcut(start, triangles, dim, minX, minY, invSize) { + // look for a valid diagonal that divides the polygon into two + var a = start; + do { + var b = a.next.next; + while (b !== a.prev) { + if (a.i !== b.i && isValidDiagonal(a, b)) { + // split the polygon in two by the diagonal + var c = splitPolygon(a, b); - if (Features.pointerLock) - { - document.removeEventListener('pointerlockchange', this.pointerLockChange, true); - document.removeEventListener('mozpointerlockchange', this.pointerLockChange, true); - document.removeEventListener('webkitpointerlockchange', this.pointerLockChange, true); + // filter colinear points around the cuts + a = filterPoints(a, a.next); + c = filterPoints(c, c.next); + + // run earcut on each half + earcutLinked(a, triangles, dim, minX, minY, invSize, 0); + earcutLinked(c, triangles, dim, minX, minY, invSize, 0); + return; + } + b = b.next; } - }, + a = a.next; + } while (a !== start); +} - /** - * Destroys this Mouse Manager instance. - * - * @method Phaser.Input.Mouse.MouseManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.stopListeners(); +// link every hole into the outer loop, producing a single-ring polygon without holes +function eliminateHoles(data, holeIndices, outerNode, dim) { + var queue = [], + i, len, start, end, list; - this.target = null; - this.enabled = false; - this.manager = null; + for (i = 0, len = holeIndices.length; i < len; i++) { + start = holeIndices[i] * dim; + end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + list = linkedList(data, start, end, dim, false); + if (list === list.next) list.steiner = true; + queue.push(getLeftmost(list)); } -}); + queue.sort(compareX); -module.exports = MouseManager; + // process holes from left to right + for (i = 0; i < queue.length; i++) { + outerNode = eliminateHole(queue[i], outerNode); + } + return outerNode; +} -/***/ }), -/* 412 */ -/***/ (function(module, exports, __webpack_require__) { +function compareX(a, b) { + return a.x - b.x; +} -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +// find a bridge between vertices that connects hole with an outer ring and and link it +function eliminateHole(hole, outerNode) { + var bridge = findHoleBridge(hole, outerNode); + if (!bridge) { + return outerNode; + } -var Angle = __webpack_require__(349); -var Class = __webpack_require__(0); -var Distance = __webpack_require__(50); -var FuzzyEqual = __webpack_require__(124); -var SmoothStepInterpolation = __webpack_require__(360); -var Vector2 = __webpack_require__(3); -var OS = __webpack_require__(105); + var bridgeReverse = splitPolygon(bridge, hole); -/** - * @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({ + // filter collinear points around the cuts + filterPoints(bridgeReverse, bridgeReverse.next); + return filterPoints(bridge, bridge.next); +} - initialize: +// David Eberly's algorithm for finding a bridge between hole and outer polygon +function findHoleBridge(hole, outerNode) { + var p = outerNode, + hx = hole.x, + hy = hole.y, + qx = -Infinity, + m; - 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; + // find a segment intersected by a ray from the hole's leftmost point to the left; + // segment's endpoint with lesser x will be potential connection point + do { + if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { + var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); + if (x <= hx && x > qx) { + qx = x; + m = p.x < p.next.x ? p : p.next; + if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint + } + } + p = p.next; + } while (p !== outerNode); - /** - * 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|WheelEvent)} - * @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; + if (!m) return null; - /** - * 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; + // look for points inside the triangle of hole point, segment intersection and endpoint; + // if there are no points found, we have a valid connection; + // otherwise choose the point of the minimum angle with the ray as connection point - /** - * 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; + var stop = m, + mx = m.x, + my = m.y, + tanMin = Infinity, + tan; - /** - * 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; + p = m; - /** - * 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(); + do { + if (hx >= p.x && p.x >= mx && hx !== p.x && + pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { - /** - * 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(); + tan = Math.abs(hy - p.y) / (hx - p.x); // tangential - /** - * 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); + if (locallyInside(p, hole) && + (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) { + m = p; + tanMin = tan; + } + } - /** - * 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(); + p = p.next; + } while (p !== stop); - /** - * 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; + return m; +} - /** - * 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; +// whether sector in vertex m contains sector in vertex p in the same coordinates +function sectorContainsSector(m, p) { + return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 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; +// interlink polygon nodes in z-order +function indexCurve(start, minX, minY, invSize) { + var p = start; + do { + if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize); + p.prevZ = p.prev; + p.nextZ = p.next; + p = p.next; + } while (p !== start); - /** - * 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; + p.prevZ.nextZ = null; + p.prevZ = null; - /** - * 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; + sortLinked(p); +} - /** - * 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; +// Simon Tatham's linked list merge sort algorithm +// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html +function sortLinked(list) { + var i, p, q, e, tail, numMerges, pSize, qSize, + inSize = 1; - /** - * 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; + do { + p = list; + list = null; + tail = null; + numMerges = 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; + while (p) { + numMerges++; + q = p; + pSize = 0; + for (i = 0; i < inSize; i++) { + pSize++; + q = q.nextZ; + if (!q) break; + } + qSize = inSize; - /** - * 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; + while (pSize > 0 || (qSize > 0 && q)) { - /** - * 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; + if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { + e = p; + p = p.nextZ; + pSize--; + } else { + e = q; + q = q.nextZ; + qSize--; + } - /** - * 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; + if (tail) tail.nextZ = e; + else list = e; - /** - * 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; + e.prevZ = tail; + tail = e; + } - /** - * 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; + p = q; + } - /** - * 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; + tail.nextZ = null; + inSize *= 2; - /** - * 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; + } while (numMerges > 1); - /** - * 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; + return list; +} - /** - * 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; +// z-order of a point given coords and inverse of the longer side of data bbox +function zOrder(x, y, minX, minY, invSize) { + // coords are transformed into non-negative 15-bit integer range + x = (x - minX) * invSize | 0; + y = (y - minY) * invSize | 0; - /** - * 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; + x = (x | (x << 8)) & 0x00FF00FF; + x = (x | (x << 4)) & 0x0F0F0F0F; + x = (x | (x << 2)) & 0x33333333; + x = (x | (x << 1)) & 0x55555555; - /** - * 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; + y = (y | (y << 8)) & 0x00FF00FF; + y = (y | (y << 4)) & 0x0F0F0F0F; + y = (y | (y << 2)) & 0x33333333; + y = (y | (y << 1)) & 0x55555555; - /** - * 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; + return x | (y << 1); +} - /** - * 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; +// find the leftmost node of a polygon ring +function getLeftmost(start) { + var p = start, + leftmost = start; + do { + if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p; + p = p.next; + } while (p !== start); - /** - * 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; + return leftmost; +} - /** - * 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; +// check if a point lies within a convex triangle +function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { + return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && + (ax - px) * (by - py) >= (bx - px) * (ay - py) && + (bx - px) * (cy - py) >= (cx - px) * (by - py); +} - /** - * 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; +// check if a diagonal between two polygon nodes is valid (lies in polygon interior) +function isValidDiagonal(a, b) { + return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges + (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible + (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors + equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case +} - /** - * 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; +// signed area of a triangle +function area(p, q, r) { + return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); +} - /** - * 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; - }, +// check if two points are equal +function equals(p1, p2) { + return p1.x === p2.x && p1.y === p2.y; +} - /** - * 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); +// check if two segments intersect +function intersects(p1, q1, p2, q2) { + var o1 = sign(area(p1, q1, p2)); + var o2 = sign(area(p1, q1, q2)); + var o3 = sign(area(p2, q2, p1)); + var o4 = sign(area(p2, q2, q1)); - this.worldX = temp.x; - this.worldY = temp.y; + if (o1 !== o2 && o3 !== o4) return true; // general case - return this; - }, + if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1 + if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1 + if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2 + if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2 - /** - * 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); - }, + return false; +} - /** - * 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; +// for collinear points p, q, r, check if point q lies on segment pr +function onSegment(p, q, r) { + return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y); +} - var mx = this.midPoint.x; - var my = this.midPoint.y; +function sign(num) { + return num > 0 ? 1 : num < 0 ? -1 : 0; +} - if (cx === mx && cy === my) - { - // Nothing to do here - return; - } +// check if a polygon diagonal intersects any polygon segments +function intersectsPolygon(a, b) { + var p = a; + do { + if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && + intersects(p, p.next, a, b)) return true; + p = p.next; + } while (p !== a); - // Moving towards our goal ... - var vx = SmoothStepInterpolation(this.motionFactor, mx, cx); - var vy = SmoothStepInterpolation(this.motionFactor, my, cy); + return false; +} - if (FuzzyEqual(vx, cx, 0.1)) - { - vx = cx; - } +// check if a polygon diagonal is locally inside the polygon +function locallyInside(a, b) { + return area(a.prev, a, a.next) < 0 ? + area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : + area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; +} - if (FuzzyEqual(vy, cy, 0.1)) - { - vy = cy; - } +// check if the middle point of a polygon diagonal is inside the polygon +function middleInside(a, b) { + var p = a, + inside = false, + px = (a.x + b.x) / 2, + py = (a.y + b.y) / 2; + do { + if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y && + (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) + inside = !inside; + p = p.next; + } while (p !== a); - this.midPoint.set(vx, vy); + return inside; +} - var dx = cx - vx; - var dy = cy - vy; +// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; +// if one belongs to the outer ring and another to a hole, it merges it into a single ring +function splitPolygon(a, b) { + var a2 = new Node(a.i, a.x, a.y), + b2 = new Node(b.i, b.x, b.y), + an = a.next, + bp = b.prev; - this.velocity.set(dx, dy); + a.next = b; + b.prev = a; - this.angle = Angle(vx, vy, cx, cy); + a2.next = an; + an.prev = a2; - this.distance = Math.sqrt(dx * dx + dy * dy); - }, + b2.next = a2; + a2.prev = b2; - /** - * 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; - } + bp.next = b2; + b2.prev = bp; - this.event = event; + return b2; +} - this.button = event.button; +// create a node and optionally link it with previous one (in a circular doubly linked list) +function insertNode(i, x, y, last) { + var p = new Node(i, x, y); - this.upElement = event.target; + if (!last) { + p.prev = p; + p.next = p; - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, false); + } else { + p.next = last.next; + p.prev = last; + last.next.prev = p; + last.next = p; + } + return p; +} - // 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; - } +function removeNode(p) { + p.next.prev = p.prev; + p.prev.next = p.next; - if (this.buttons === 0) - { - // No more buttons are still down - this.isDown = false; + if (p.prevZ) p.prevZ.nextZ = p.nextZ; + if (p.nextZ) p.nextZ.prevZ = p.prevZ; +} - this.upTime = event.timeStamp; +function Node(i, x, y) { + // vertex index in coordinates array + this.i = i; - this.wasTouch = false; - } - }, + // vertex coordinates + this.x = x; + this.y = y; - /** - * 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; - } + // previous and next vertex nodes in a polygon ring + this.prev = null; + this.next = null; - this.event = event; + // z-order curve value + this.z = 0; - this.button = event.button; + // previous and next nodes in z-order + this.prevZ = null; + this.nextZ = null; - this.downElement = event.target; + // indicates whether this is a steiner point + this.steiner = false; +} - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, false); +// return a percentage difference between the polygon area and its triangulation area; +// used to verify correctness of triangulation +earcut.deviation = function (data, holeIndices, dim, triangles) { + var hasHoles = holeIndices && holeIndices.length; + var outerLen = hasHoles ? holeIndices[0] * dim : data.length; - // 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; + var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); + if (hasHoles) { + for (var i = 0, len = holeIndices.length; i < len; i++) { + var start = holeIndices[i] * dim; + var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + polygonArea -= Math.abs(signedArea(data, start, end, dim)); } + } - if (OS.macOS && event.ctrlKey) - { - // Override button settings on macOS - this.buttons = 2; - this.primaryDown = false; - } + var trianglesArea = 0; + for (i = 0; i < triangles.length; i += 3) { + var a = triangles[i] * dim; + var b = triangles[i + 1] * dim; + var c = triangles[i + 2] * dim; + trianglesArea += Math.abs( + (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - + (data[a] - data[b]) * (data[c + 1] - data[a + 1])); + } - if (!this.isDown) - { - this.isDown = true; + return polygonArea === 0 && trianglesArea === 0 ? 0 : + Math.abs((trianglesArea - polygonArea) / polygonArea); +}; - this.downTime = event.timeStamp; - } +function signedArea(data, start, end, dim) { + var sum = 0; + for (var i = start, j = end - dim; i < end; i += dim) { + sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); + j = i; + } + return sum; +} - this.wasTouch = false; - }, +// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts +earcut.flatten = function (data) { + var dim = data[0][0].length, + result = {vertices: [], holes: [], dimensions: dim}, + holeIndex = 0; - /** - * 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; + for (var i = 0; i < data.length; i++) { + for (var j = 0; j < data[i].length; j++) { + for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); } - - 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; + if (i > 0) { + holeIndex += data[i - 1].length; + result.holes.push(holeIndex); } + } + return result; +}; - this.moveTime = event.timeStamp; +module.exports = earcut; - 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; +/***/ 14045: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Sets the local x/y properties - this.manager.transformPointer(this, event.pageX, event.pageY, false); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.deltaX = event.deltaX; - this.deltaY = event.deltaY; - this.deltaZ = event.deltaZ; +var Rectangle = __webpack_require__(74118); - this.wasTouch = false; - }, +/** + * 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(); } - /** - * 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) + var minX = Infinity; + var minY = Infinity; + var maxX = -minX; + var maxY = -minY; + var p; + + for (var i = 0; i < polygon.points.length; i++) { - if (touch['pointerId']) - { - this.pointerId = touch.pointerId; - } + p = polygon.points[i]; - this.identifier = touch.identifier; - this.target = touch.target; - this.active = true; + minX = Math.min(minX, p.x); + minY = Math.min(minY, p.y); + maxX = Math.max(maxX, p.x); + maxY = Math.max(maxY, p.y); + } - this.buttons = 1; + out.x = minX; + out.y = minY; + out.width = maxX - minX; + out.height = maxY - minY; - this.event = event; + return out; +}; - this.downElement = touch.target; +module.exports = GetAABB; - // 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; +/***/ 98286: +/***/ ((module) => { - this.wasTouch = true; - this.wasCanceled = false; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.updateMotion(); - }, +// Export the points as an array of flat numbers, following the sequence [ x,y, x,y, x,y ] - /** - * 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) +/** + * Stores all of the points of a Polygon into a flat array of numbers following the sequence [ x,y, x,y, x,y ], + * i.e. each point of the Polygon, in the order it's defined, corresponds to two elements of the resultant + * array for the point's X and Y coordinate. + * + * @function Phaser.Geom.Polygon.GetNumberArray + * @since 3.0.0 + * + * @generic {number[]} O - [output,$return] + * + * @param {Phaser.Geom.Polygon} polygon - The Polygon whose points to export. + * @param {(array|number[])} [output] - An array to which the points' coordinates should be appended. + * + * @return {(array|number[])} The modified `output` array, or a new array if none was given. + */ +var GetNumberArray = function (polygon, output) +{ + if (output === undefined) { output = []; } + + for (var i = 0; i < polygon.points.length; i++) { - this.event = event; + output.push(polygon.points[i].x); + output.push(polygon.points[i].y); + } - // Sets the local x/y properties - this.manager.transformPointer(this, touch.pageX, touch.pageY, true); + return output; +}; - this.moveTime = event.timeStamp; +module.exports = GetNumberArray; - 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; +/***/ 89294: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.event = event; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.upElement = touch.target; +var Length = __webpack_require__(16028); +var Line = __webpack_require__(88829); +var Perimeter = __webpack_require__(5159); - // 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); - } - }, +/** + * 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 = []; } - /** - * 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); - } - }, + var points = polygon.points; + var perimeter = Perimeter(polygon); - /** - * 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 quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. + if (!quantity && stepRate > 0) { - if (this.isDown) - { - return Math.abs(this.downY - this.y); - } - else - { - return Math.abs(this.downY - this.upY); - } - }, + quantity = perimeter / stepRate; + } - /** - * 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 () + for (var i = 0; i < quantity; i++) { - if (this.isDown) - { - return (this.manager.time - this.downTime); - } - else - { - return (this.upTime - this.downTime); - } - }, + var position = perimeter * (i / quantity); + var accumulatedPerimeter = 0; - /** - * 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 + for (var j = 0; j < points.length; j++) { - 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 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); - var curX = this.position.x; - var curY = this.position.y; + if (position < accumulatedPerimeter || position > accumulatedPerimeter + length) + { + accumulatedPerimeter += length; + continue; + } - for (var i = 0; i < steps; i++) - { - var t = (1 / steps) * i; + var point = line.getPoint((position - accumulatedPerimeter) / length); + out.push(point); - out[i] = { x: SmoothStepInterpolation(t, prevX, curX), y: SmoothStepInterpolation(t, prevY, curY) }; + break; } + } - 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; - }, + return out; +}; - set: function (value) - { - this.position.x = value; - } +module.exports = GetPoints; - }, - /** - * 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; - }, +/***/ 5159: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - set: function (value) - { - this.position.y = value; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - }, +var Length = __webpack_require__(16028); +var Line = __webpack_require__(88829); - /** - * 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: { +/** + * 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; - get: function () - { - return (this.event) ? this.event.timeStamp : 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 = Pointer; +module.exports = Perimeter; /***/ }), -/* 413 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 8580: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var InputEvents = __webpack_require__(51); -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/ +var Class = __webpack_require__(56694); +var Contains = __webpack_require__(45604); +var GetPoints = __webpack_require__(89294); +var GEOM_CONST = __webpack_require__(52394); /** * @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. + * A Polygon object * - * @class TouchManager - * @memberof Phaser.Input.Touch + * The polygon is a closed shape consists of a series of connected straight lines defined by list of ordered points. + * Several formats are supported to define the list of points, check the setTo method for details. + * This is a geometry object allowing you to define and inspect the shape. + * It is not a Game Object, in that you cannot add it to the display list, and it has no texture. + * To render a Polygon you should look at the capabilities of the Graphics class. + * + * @class Polygon + * @memberof Phaser.Geom * @constructor * @since 3.0.0 * - * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. + * @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - List of points defining the perimeter of this Polygon. Several formats are supported: + * - A string containing paired x y values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'` + * - An array of Point objects: `[new Phaser.Point(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], ...]` */ -var TouchManager = new Class({ +var Polygon = new Class({ initialize: - function TouchManager (inputManager) + function Polygon (points) { /** - * 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. + * The geometry constant type of this object: `GEOM_CONST.POLYGON`. + * Used for fast type comparisons. * - * @name Phaser.Input.Touch.TouchManager#onTouchStartWindow - * @type {function} - * @since 3.17.0 + * @name Phaser.Geom.Polygon#type + * @type {number} + * @readonly + * @since 3.19.0 */ - this.onTouchStartWindow = NOOP; + this.type = GEOM_CONST.POLYGON; /** - * The Touch Move event handler function. - * Initially empty and bound in the `startListeners` method. + * The area of this Polygon. * - * @name Phaser.Input.Touch.TouchManager#onTouchMove - * @type {function} + * @name Phaser.Geom.Polygon#area + * @type {number} + * @default 0 * @since 3.0.0 */ - this.onTouchMove = NOOP; + this.area = 0; /** - * The Touch End event handler function. - * Initially empty and bound in the `startListeners` method. + * An array of number pair objects that make up this polygon. I.e. [ {x,y}, {x,y}, {x,y} ] * - * @name Phaser.Input.Touch.TouchManager#onTouchEnd - * @type {function} + * @name Phaser.Geom.Polygon#points + * @type {Phaser.Geom.Point[]} * @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(); - } + this.points = []; - if (this.enabled && this.target) + if (points) { - this.startListeners(); + this.setTo(points); } }, /** - * 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. + * Check to see if the Polygon contains the given x / y coordinates. * - * @method Phaser.Input.Touch.TouchManager#disableContextMenu - * @since 3.20.0 + * @method Phaser.Geom.Polygon#contains + * @since 3.0.0 * - * @return {this} This Touch Manager instance. + * @param {number} x - The x coordinate to check within the polygon. + * @param {number} y - The y coordinate to check within the polygon. + * + * @return {boolean} `true` if the coordinates are within the polygon, otherwise `false`. */ - disableContextMenu: function () + contains: function (x, y) { - document.body.addEventListener('contextmenu', function (event) - { - event.preventDefault(); - return false; - }); - - return this; + return Contains(this, x, y); }, /** - * 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. + * Sets this Polygon to the given points. * - * @method Phaser.Input.Touch.TouchManager#startListeners + * 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 objects: `[new Phaser.Point(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], ...]` + * + * `setTo` may also be called without any arguments to remove all points. + * + * @method Phaser.Geom.Polygon#setTo * @since 3.0.0 + * + * @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - Points defining the perimeter of this polygon. Please check function description above for the different supported formats. + * + * @return {this} This Polygon object. */ - startListeners: function () + setTo: function (points) { - var _this = this; - var canvas = this.manager.canvas; - var autoFocus = (window && window.focus && this.manager.game.config.autoFocus); + this.area = 0; + this.points = []; - this.onTouchStart = function (event) + if (typeof points === 'string') { - 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(); - } - } - }; + points = points.split(' '); + } - this.onTouchStartWindow = function (event) + if (!Array.isArray(points)) { - 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); - } - }; + return this; + } - 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(); - } - } - }; + var p; + var y0 = Number.MAX_VALUE; - this.onTouchEnd = function (event) + // The points argument is an array, so iterate through it + for (var i = 0; i < points.length; i++) { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.onTouchEnd(event); - - if (_this.capture && event.cancelable && event.target === canvas) - { - event.preventDefault(); - } - } - }; + p = { x: 0, y: 0 }; - this.onTouchEndWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled && event.target !== canvas) + if (typeof points[i] === 'number' || typeof points[i] === 'string') { - // Only process the event if the target isn't the canvas - _this.manager.onTouchEnd(event); + p.x = parseFloat(points[i]); + p.y = parseFloat(points[i + 1]); + i++; } - }; - - this.onTouchCancel = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + else if (Array.isArray(points[i])) { - _this.manager.onTouchCancel(event); - - if (_this.capture) - { - event.preventDefault(); - } + // An array of arrays? + p.x = points[i][0]; + p.y = points[i][1]; } - }; - - this.onTouchCancelWindow = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + else { - _this.manager.onTouchCancel(event); + p.x = points[i].x; + p.y = points[i].y; } - }; - this.onTouchOver = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) - { - _this.manager.setCanvasOver(event); - } - }; + this.points.push(p); - this.onTouchOut = function (event) - { - if (!event.defaultPrevented && _this.enabled && _this.manager && _this.manager.enabled) + // Lowest boundary + if (p.y < y0) { - _this.manager.setCanvasOut(event); + y0 = p.y; } - }; - - 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.calculateArea(y0); - this.enabled = true; + return this; }, /** - * Stops the Touch Event listeners. - * This is called automatically and does not need to be manually invoked. + * Calculates the area of the Polygon. This is available in the property Polygon.area * - * @method Phaser.Input.Touch.TouchManager#stopListeners + * @method Phaser.Geom.Polygon#calculateArea * @since 3.0.0 + * + * @return {number} The area of the polygon. */ - stopListeners: function () + calculateArea: function () { - var target = this.target; + if (this.points.length < 3) + { + this.area = 0; - 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); + return this.area; + } - if (window) + var sum = 0; + var p1; + var p2; + + for (var i = 0; i < this.points.length - 1; i++) { - window.removeEventListener('touchstart', this.onTouchStartWindow); - window.removeEventListener('touchend', this.onTouchEndWindow); + p1 = this.points[i]; + p2 = this.points[i + 1]; + + sum += (p2.x - p1.x) * (p1.y + p2.y); } + + p1 = this.points[0]; + p2 = this.points[this.points.length - 1]; + + sum += (p1.x - p2.x) * (p2.y + p1.y); + + this.area = -sum * 0.5; + + return this.area; }, /** - * Destroys this Touch Manager instance. + * 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. * - * @method Phaser.Input.Touch.TouchManager#destroy - * @since 3.0.0 + * @method Phaser.Geom.Polygon#getPoints + * @since 3.12.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 perimeter of the Polygon 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 perimeter of the Polygon. */ - destroy: function () + getPoints: function (quantity, step, output) { - this.stopListeners(); - - this.target = null; - this.enabled = false; - this.manager = null; + return GetPoints(this, quantity, step, output); } }); -module.exports = TouchManager; +module.exports = Polygon; /***/ }), -/* 414 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 32244: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(93); - /** - * @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 + * Reverses the order of the points of a Polygon. * - * 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. + * @function Phaser.Geom.Polygon.Reverse + * @since 3.0.0 * - * 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. + * @generic {Phaser.Geom.Polygon} O - [polygon,$return] * - * You can add a plugin to Phaser in three different ways: + * @param {Phaser.Geom.Polygon} polygon - The Polygon to modify. * - * 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 + * @return {Phaser.Geom.Polygon} The modified Polygon. + */ +var Reverse = function (polygon) +{ + polygon.points.reverse(); + + return polygon; +}; + +module.exports = Reverse; + + +/***/ }), + +/***/ 95874: +/***/ ((module) => { + +/** + * @author Richard Davey + * @author Vladimir Agafonkin + * @see Based on Simplify.js mourner.github.io/simplify-js + */ + +/** + * Copyright (c) 2017, Vladimir Agafonkin + * All rights reserved. * - * For examples of all of these approaches please see the Phaser 3 Examples Repo `plugins` folder. + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: * - * For information on creating your own plugin please see the Phaser 3 Plugin Template. + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. * - * @class PluginManager - * @memberof Phaser.Plugins - * @constructor - * @since 3.0.0 + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. * - * @param {Phaser.Game} game - The game instance that owns this Plugin Manager. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var PluginManager = new Class({ - Extends: EventEmitter, +/** + * @ignore + */ +function getSqDist (p1, p2) +{ + var dx = p1.x - p2.x, + dy = p1.y - p2.y; - initialize: + return dx * dx + dy * dy; +} - function PluginManager (game) +/** + * Square distance from a point to a segment + * + * @ignore + */ +function getSqSegDist (p, p1, p2) +{ + var x = p1.x, + y = p1.y, + dx = p2.x - x, + dy = p2.y - y; + + if (dx !== 0 || dy !== 0) { - EventEmitter.call(this); + var t = ((p.x - x) * dx + (p.y - y) * dy) / (dx * dx + dy * dy); - /** - * 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) + if (t > 1) { - this.boot(); + x = p2.x; + y = p2.y; } - else + else if (t > 0) { - game.events.once(GameEvents.BOOT, this.boot, this); + x += dx * t; + y += dy * t; } - }, - - /** - * 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); - } + dx = p.x - x; + dy = p.y - y; - } - } + return dx * dx + dy * dy; +} - // Any scene plugins to install? - list = config.installScenePlugins; +/** + * Basic distance-based simplification + * + * @ignore + */ +function simplifyRadialDist (points, sqTolerance) +{ + var prevPoint = points[0], + newPoints = [ prevPoint ], + point; - // Any plugins added outside of the game config, but before the game booted? - list = list.concat(this._pendingScene); + for (var i = 1, len = points.length; i < len; i++) + { + point = points[i]; - for (i = 0; i < list.length; i++) + if (getSqDist(point, prevPoint) > sqTolerance) { - 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); - } - } + newPoints.push(point); + prevPoint = point; } + } - 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) + if (prevPoint !== point) { - var i; - var pluginKey; - var pluginList; - var game = this.game; - var scene = sys.scene; - var map = sys.settings.map; - var isBooted = sys.settings.isBooted; + newPoints.push(point); + } - // Reference the GlobalPlugins from Game into Scene.Systems - for (i = 0; i < globalPlugins.length; i++) - { - pluginKey = globalPlugins[i]; + return newPoints; +} - if (game[pluginKey]) - { - sys[pluginKey] = game[pluginKey]; +/** + * @ignore + */ +function simplifyDPStep (points, first, last, sqTolerance, simplified) +{ + var maxSqDist = sqTolerance, + index; - // 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 i = first + 1; i < last; i++) + { + var sqDist = getSqSegDist(points[i], points[first], points[last]); - for (var s = 0; s < scenePlugins.length; s++) + if (sqDist > maxSqDist) { - pluginList = scenePlugins[s]; - - for (i = 0; i < pluginList.length; i++) - { - pluginKey = pluginList[i]; - - if (!PluginCache.hasCore(pluginKey)) - { - continue; - } - - var source = PluginCache.getCore(pluginKey); - - var mapKey = source.mapping; - - var plugin = new source.plugin(scene, this, mapKey); - - sys[mapKey] = plugin; - - // Scene level injection - if (source.custom) - { - scene[mapKey] = plugin; - } - else if (map.hasOwnProperty(mapKey)) - { - scene[map[mapKey]] = plugin; - } - - // Scene is already booted, usually because this method is being called at run-time, so boot the plugin - if (isBooted) - { - plugin.boot(); - } - } + index = i; + maxSqDist = sqDist; } + } - // And finally, inject any 'global scene plugins' - pluginList = this.plugins; - - for (i = 0; i < pluginList.length; i++) + if (maxSqDist > sqTolerance) + { + if (index - first > 1) { - var entry = pluginList[i]; - - if (entry.mapping) - { - scene[entry.mapping] = entry.plugin; - } + simplifyDPStep(points, first, index, sqTolerance, simplified); } - }, - - /** - * 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; } + simplified.push(points[index]); - if (typeof plugin !== 'function') + if (last - index > 1) { - console.warn('Invalid Scene Plugin: ' + key); - return; + simplifyDPStep(points, index, last, sqTolerance, simplified); } + } +} - if (!PluginCache.hasCore(key)) - { - // Plugin is freshly loaded - PluginCache.register(key, plugin, mapping, true); +/** + * Simplification using Ramer-Douglas-Peucker algorithm + * + * @ignore + */ +function simplifyDouglasPeucker (points, sqTolerance) +{ + var last = points.length - 1; - 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; - } + var simplified = [ points[0] ]; - if (addToScene) - { - var instance = new plugin(addToScene, this, key); + simplifyDPStep(points, 0, last, sqTolerance, simplified); - addToScene.sys[key] = instance; + simplified.push(points[last]); - if (mapping && mapping !== '') - { - addToScene[mapping] = instance; - } + return simplified; +} - instance.boot(); - } - }, +/** + * Takes a Polygon object and simplifies the points by running them through a combination of + * Douglas-Peucker and Radial Distance algorithms. Simplification dramatically reduces the number of + * points in a polygon while retaining its shape, giving a huge performance boost when processing + * it and also reducing visual noise. + * + * @function Phaser.Geom.Polygon.Simplify + * @since 3.50.0 + * + * @generic {Phaser.Geom.Polygon} O - [polygon,$return] + * + * @param {Phaser.Geom.Polygon} polygon - The polygon to be simplified. The polygon will be modified in-place and returned. + * @param {number} [tolerance=1] - Affects the amount of simplification (in the same metric as the point coordinates). + * @param {boolean} [highestQuality=false] - Excludes distance-based preprocessing step which leads to highest quality simplification but runs ~10-20 times slower. + * + * @return {Phaser.Geom.Polygon} The input polygon. + */ +var Simplify = function (polygon, tolerance, highestQuality) +{ + if (tolerance === undefined) { tolerance = 1; } + if (highestQuality === undefined) { highestQuality = false; } - /** - * 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; } + var points = polygon.points; - if (typeof plugin !== 'function') - { - console.warn('Invalid Plugin: ' + key); - return null; - } + if (points.length > 2) + { + var sqTolerance = tolerance * tolerance; - if (PluginCache.hasCustom(key)) + if (!highestQuality) { - console.warn('Plugin key in use: ' + key); - return null; + points = simplifyRadialDist(points, sqTolerance); } - if (mapping !== null) - { - start = true; - } + polygon.setTo(simplifyDouglasPeucker(points, sqTolerance)); + } - 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); + return polygon; +}; - if (start) - { - return this.start(key); - } - } +module.exports = Simplify; - 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]; +/***/ 18974: +/***/ ((module) => { - if (entry.key === key) - { - return i; - } - } +/** + * @author Richard Davey + * @author Igor Ognichenko + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return -1; - }, +/** + * @ignore + */ +var copy = function (out, a) +{ + out[0] = a[0]; + out[1] = a[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); + return out; +}; - if (idx !== -1) - { - return this.plugins[idx]; - } - }, +/** + * 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; - /** - * 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) + for (i = 0; i < data.length; i++) { - var entry = this.getEntry(key); + points.push([ data[i].x, data[i].y ]); + } - return (entry && entry.active); - }, + var output = []; - /** - * 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 (points.length > 0) { - if (runAs === undefined) { runAs = key; } - - var entry = this.getEntry(runAs); + output.push(copy([ 0, 0 ], points[0])); + } - // 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); - } + 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]; - return (entry) ? entry.plugin : null; - }, + 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 ]); + } - /** - * 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) + if (points.length > 1) { - var entry = PluginCache.getCustom(key); - - if (entry) - { - var instance = new entry.plugin(this); + output.push(copy([ 0, 0 ], points[points.length - 1])); + } - entry = { - key: runAs, - plugin: instance, - active: true, - mapping: entry.mapping, - data: entry.data - }; + return polygon.setTo(output); +}; - this.plugins.push(entry); +module.exports = Smooth; - 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); +/***/ 23490: +/***/ ((module) => { - if (entry && entry.active) - { - entry.active = false; - entry.plugin.stop(); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +/** + * Tranlates the points of the given Polygon. + * + * @function Phaser.Geom.Polygon.Translate + * @since 3.50.0 + * + * @generic {Phaser.Geom.Polygon} O - [polygon,$return] + * + * @param {Phaser.Geom.Polygon} polygon - The Polygon to modify. + * @param {number} x - The amount to horizontally translate the points by. + * @param {number} y - The amount to vertically translate the points by. + * + * @return {Phaser.Geom.Polygon} The modified Polygon. + */ +var Translate = function (polygon, x, y) +{ + var points = polygon.points; - /** - * 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) + for (var i = 0; i < points.length; i++) { - if (autoStart === undefined) { autoStart = true; } + points[i].x += x; + points[i].y += y; + } - var entry = this.getEntry(key); + return polygon; +}; - if (entry) - { - return entry.plugin; - } - else - { - var plugin = this.getClass(key); +module.exports = Translate; - if (plugin && autoStart) - { - entry = this.createEntry(key, key); - return (entry) ? entry.plugin : null; - } - else if (plugin) - { - return plugin; - } - } +/***/ }), - return null; - }, +/***/ 44359: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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); +var Polygon = __webpack_require__(8580); - if (entry) - { - Remove(this.plugins, entry); - } +Polygon.Clone = __webpack_require__(19631); +Polygon.Contains = __webpack_require__(45604); +Polygon.ContainsPoint = __webpack_require__(87289); +Polygon.Earcut = __webpack_require__(11117); +Polygon.GetAABB = __webpack_require__(14045); +Polygon.GetNumberArray = __webpack_require__(98286); +Polygon.GetPoints = __webpack_require__(89294); +Polygon.Perimeter = __webpack_require__(5159); +Polygon.Reverse = __webpack_require__(32244); +Polygon.Simplify = __webpack_require__(95874); +Polygon.Smooth = __webpack_require__(18974); +Polygon.Translate = __webpack_require__(23490); - PluginCache.removeCustom(key); - }, +module.exports = Polygon; - /** - * 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); - } +/***/ 1653: +/***/ ((module) => { - if (creatorCallback) - { - GameObjectCreator.register(key, creatorCallback); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +/** + * Calculates the area of the given Rectangle object. + * + * @function Phaser.Geom.Rectangle.Area + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - The rectangle to calculate the area of. + * + * @return {number} The area of the Rectangle object. + */ +var Area = function (rect) +{ + return rect.width * rect.height; +}; - /** - * 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; } +module.exports = Area; - if (removeFromFactory) - { - GameObjectFactory.remove(key); - } - if (removeFromCreator) - { - GameObjectCreator.remove(key); - } +/***/ }), - return this; - }, +/***/ 33943: +/***/ ((module) => { - /** - * 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); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (addToScene && addToScene.sys.load) - { - addToScene.sys.load[key] = callback; - } - }, +/** + * Rounds a Rectangle's position up to the smallest integer greater than or equal to each current coordinate. + * + * @function Phaser.Geom.Rectangle.Ceil + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to adjust. + * + * @return {Phaser.Geom.Rectangle} The adjusted Rectangle. + */ +var Ceil = function (rect) +{ + rect.x = Math.ceil(rect.x); + rect.y = Math.ceil(rect.y); - /** - * 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(); - } + return rect; +}; - PluginCache.destroyCustomPlugins(); +module.exports = Ceil; - if (this.game.noReturn) - { - PluginCache.destroyCorePlugins(); - } - this.game = null; - this.plugins = []; - this.scenePlugins = []; - } +/***/ }), -}); +/***/ 58662: +/***/ ((module) => { -/* - * "Sometimes, the elegant implementation is just a function. - * Not a method. Not a class. Not a framework. Just a function." - * -- John Carmack +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -module.exports = PluginManager; +/** + * Rounds a Rectangle's position and size up to the smallest integer greater than or equal to each respective value. + * + * @function Phaser.Geom.Rectangle.CeilAll + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to modify. + * + * @return {Phaser.Geom.Rectangle} The modified Rectangle. + */ +var CeilAll = function (rect) +{ + rect.x = Math.ceil(rect.x); + rect.y = Math.ceil(rect.y); + rect.width = Math.ceil(rect.width); + rect.height = Math.ceil(rect.height); + + return rect; +}; + +module.exports = CeilAll; /***/ }), -/* 415 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 79993: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(201); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(104); -var GameEvents = __webpack_require__(22); -var GetInnerHeight = __webpack_require__(401); -var GetTarget = __webpack_require__(407); -var GetScreenOrientation = __webpack_require__(402); -var NOOP = __webpack_require__(1); -var Rectangle = __webpack_require__(10); -var Size = __webpack_require__(416); -var SnapFloor = __webpack_require__(76); -var Vector2 = __webpack_require__(3); - /** - * @classdesc - * The Scale Manager handles the scaling, resizing and alignment of the game canvas. + * Moves the top-left corner of a Rectangle so that its center is at the given coordinates. * - * 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. + * @function Phaser.Geom.Rectangle.CenterOn + * @since 3.0.0 * - * 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. + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] * - * #### Parent and Display canvas containment guidelines: + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to be centered. + * @param {number} x - The X coordinate of the Rectangle's center. + * @param {number} y - The Y coordinate of the Rectangle's center. * - * - 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 + * @return {Phaser.Geom.Rectangle} The centered rectangle. + */ +var CenterOn = function (rect, x, y) +{ + rect.x = x - (rect.width / 2); + rect.y = y - (rect.height / 2); + + return rect; +}; + +module.exports = CenterOn; + + +/***/ }), + +/***/ 81572: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(74118); + +/** + * Creates a new Rectangle which is identical to the given one. * - * 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: + * @function Phaser.Geom.Rectangle.Clone + * @since 3.0.0 * - * ```javascript - * scale: { - * parent: 'yourgamediv', - * autoCenter: Phaser.Scale.CENTER_BOTH, - * width: 800, - * height: 600 - * } - * ``` + * @param {Phaser.Geom.Rectangle} source - The Rectangle to clone. * - * #### Fullscreen API + * @return {Phaser.Geom.Rectangle} The newly created Rectangle, which is separate from the given one. + */ +var Clone = function (source) +{ + return new Rectangle(source.x, source.y, source.width, source.height); +}; + +module.exports = Clone; + + +/***/ }), + +/***/ 94287: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks if a given point is inside a Rectangle's bounds. * - * 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. + * @function Phaser.Geom.Rectangle.Contains + * @since 3.0.0 * - * @class ScaleManager - * @memberof Phaser.Scale - * @extends Phaser.Events.EventEmitter - * @constructor - * @since 3.16.0 + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to check. + * @param {number} x - The X coordinate of the point to check. + * @param {number} y - The Y coordinate of the point to check. * - * @param {Phaser.Game} game - A reference to the Phaser.Game instance. + * @return {boolean} `true` if the point is within the Rectangle's bounds, otherwise `false`. */ -var ScaleManager = new Class({ +var Contains = function (rect, x, y) +{ + if (rect.width <= 0 || rect.height <= 0) + { + return false; + } - Extends: EventEmitter, + return (rect.x <= x && rect.x + rect.width >= x && rect.y <= y && rect.y + rect.height >= y); +}; - initialize: +module.exports = Contains; - 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; +/***/ 28687: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The DOM bounds of the canvas element. - * - * @name Phaser.Scale.ScaleManager#canvasBounds - * @type {Phaser.Geom.Rectangle} - * @since 3.16.0 - */ - this.canvasBounds = new Rectangle(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +var Contains = __webpack_require__(94287); - /** - * Is the parent element the browser window? - * - * @name Phaser.Scale.ScaleManager#parentIsWindow - * @type {boolean} - * @since 3.16.0 - */ - this.parentIsWindow = false; +/** + * Determines whether the specified point is contained within the rectangular region defined by this Rectangle object. + * + * @function Phaser.Geom.Rectangle.ContainsPoint + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle object. + * @param {Phaser.Geom.Point} point - The point object to be checked. Can be a Phaser Point object or any object with x and y values. + * + * @return {boolean} A value of true if the Rectangle object contains the specified point, otherwise false. + */ +var ContainsPoint = function (rect, point) +{ + return Contains(rect, point.x, point.y); +}; - /** - * The Parent Size component. - * - * @name Phaser.Scale.ScaleManager#parentSize - * @type {Phaser.Structs.Size} - * @since 3.16.0 - */ - this.parentSize = new Size(); +module.exports = ContainsPoint; - /** - * 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(); +/***/ 73222: +/***/ ((module) => { - /** - * The game scale mode. - * - * @name Phaser.Scale.ScaleManager#scaleMode - * @type {Phaser.Scale.ScaleModeType} - * @since 3.16.0 - */ - this.scaleMode = CONST.SCALE_MODE.NONE; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +/** + * 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; + } - /** - * 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; + 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) + ); +}; - /** - * 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); +module.exports = ContainsRect; - /** - * 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; +/***/ 29538: +/***/ ((module) => { - /** - * A reference to the Device.Fullscreen object. - * - * @name Phaser.Scale.ScaleManager#fullscreen - * @type {Phaser.Device.Fullscreen} - * @since 3.16.0 - */ - this.fullscreen; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The DOM Element which is sent into fullscreen mode. - * - * @name Phaser.Scale.ScaleManager#fullscreenTarget - * @type {?any} - * @since 3.16.0 - */ - this.fullscreenTarget = null; +/** + * Copy the values of one Rectangle to a destination Rectangle. + * + * @function Phaser.Geom.Rectangle.CopyFrom + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [dest,$return] + * + * @param {Phaser.Geom.Rectangle} source - The source Rectangle to copy the values from. + * @param {Phaser.Geom.Rectangle} dest - The destination Rectangle to copy the values to. + * + * @return {Phaser.Geom.Rectangle} The destination Rectangle. + */ +var CopyFrom = function (source, dest) +{ + return dest.setTo(source.x, source.y, source.width, source.height); +}; - /** - * 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; +module.exports = CopyFrom; - /** - * 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; +/***/ 87279: +/***/ ((module) => { - /** - * Internal flag to check orientation state. - * - * @name Phaser.Scale.ScaleManager#_checkOrientation - * @type {boolean} - * @private - * @since 3.16.0 - */ - this._checkOrientation = false; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Internal object containing our defined event listeners. - * - * @name Phaser.Scale.ScaleManager#listeners - * @type {object} - * @private - * @since 3.16.0 - */ - this.listeners = { +/** + * 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 = []; } - orientationChange: NOOP, - windowResize: NOOP, - fullScreenChange: NOOP, - fullScreenError: NOOP + 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; +}; - /** - * 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); +module.exports = Decompose; - 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; +/***/ 19989: +/***/ ((module) => { - this.fullscreen = game.device.fullscreen; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (this.scaleMode !== CONST.SCALE_MODE.RESIZE) - { - this.displaySize.setAspectMode(this.scaleMode); - } +/** + * Compares the `x`, `y`, `width` and `height` properties of two rectangles. + * + * @function Phaser.Geom.Rectangle.Equals + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - Rectangle A + * @param {Phaser.Geom.Rectangle} toCompare - Rectangle B + * + * @return {boolean} `true` if the rectangles' properties are an exact match, otherwise `false`. + */ +var Equals = function (rect, toCompare) +{ + return ( + rect.x === toCompare.x && + rect.y === toCompare.y && + rect.width === toCompare.width && + rect.height === toCompare.height + ); +}; - if (this.scaleMode === CONST.SCALE_MODE.NONE) - { - this.resize(this.width, this.height); - } - else - { - this.getParentBounds(); +module.exports = Equals; - // 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); +/***/ 92628: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.startListeners(); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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); +var GetAspectRatio = __webpack_require__(6700); - // Get the size of the parent element - // This can often set a height of zero (especially for un-styled divs) - this.getParentBounds(); +/** + * Adjusts the target rectangle, changing its width, height and position, + * so that it fits inside the area of the source rectangle, while maintaining its original + * aspect ratio. + * + * Unlike the `FitOutside` function, there may be some space inside the source area not covered. + * + * @function Phaser.Geom.Rectangle.FitInside + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [target,$return] + * + * @param {Phaser.Geom.Rectangle} target - The target rectangle to adjust. + * @param {Phaser.Geom.Rectangle} source - The source rectangle to envelop the target in. + * + * @return {Phaser.Geom.Rectangle} The modified target rectangle instance. + */ +var FitInside = function (target, source) +{ + var ratio = GetAspectRatio(target); - var width = config.width; - var height = config.height; - var scaleMode = config.scaleMode; - var zoom = config.zoom; - var autoRound = config.autoRound; + if (ratio < GetAspectRatio(source)) + { + // Taller than Wide + target.setSize(source.height * ratio, source.height); + } + else + { + // Wider than Tall + target.setSize(source.width, source.width / ratio); + } - // 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; + return target.setPosition( + source.centerX - (target.width / 2), + source.centerY - (target.height / 2) + ); +}; - if (parentWidth === 0) - { - parentWidth = window.innerWidth; - } +module.exports = FitInside; - 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; +/***/ 85028: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (parentHeight === 0) - { - parentHeight = window.innerHeight; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var parentScaleY = parseInt(height, 10) / 100; +var GetAspectRatio = __webpack_require__(6700); - height = Math.floor(parentHeight * parentScaleY); - } +/** + * Adjusts the target rectangle, changing its width, height and position, + * so that it fully covers the area of the source rectangle, while maintaining its original + * aspect ratio. + * + * Unlike the `FitInside` function, the target rectangle may extend further out than the source. + * + * @function Phaser.Geom.Rectangle.FitOutside + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [target,$return] + * + * @param {Phaser.Geom.Rectangle} target - The target rectangle to adjust. + * @param {Phaser.Geom.Rectangle} source - The source rectangle to envelope the target in. + * + * @return {Phaser.Geom.Rectangle} The modified target rectangle instance. + */ +var FitOutside = function (target, source) +{ + var ratio = GetAspectRatio(target); - this.scaleMode = scaleMode; + if (ratio > GetAspectRatio(source)) + { + // Wider than Tall + target.setSize(source.height * ratio, source.height); + } + else + { + // Taller than Wide + target.setSize(source.width, source.width / ratio); + } - this.autoRound = autoRound; + return target.setPosition( + source.centerX - target.width / 2, + source.centerY - target.height / 2 + ); +}; - this.autoCenter = config.autoCenter; +module.exports = FitOutside; - 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); +/***/ 71356: +/***/ ((module) => { - if (zoom === CONST.ZOOM.MAX_ZOOM) - { - zoom = this.getMaxZoom(); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.zoom = zoom; +/** + * Rounds down (floors) the top left X and Y coordinates of the given Rectangle to the largest integer less than or equal to them + * + * @function Phaser.Geom.Rectangle.Floor + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The rectangle to floor the top left X and Y coordinates of + * + * @return {Phaser.Geom.Rectangle} The rectangle that was passed to this function with its coordinates floored. + */ +var Floor = function (rect) +{ + rect.x = Math.floor(rect.x); + rect.y = Math.floor(rect.y); - if (zoom !== 1) - { - this._resetZoom = true; - } + return rect; +}; - // The modified game size - this.baseSize.setSize(width, height); +module.exports = Floor; - 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); - } +/***/ 21687: +/***/ ((module) => { - // 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); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.orientation = GetScreenOrientation(width, height); - }, +/** + * Rounds a Rectangle's position and size down to the largest integer less than or equal to each current coordinate or dimension. + * + * @function Phaser.Geom.Rectangle.FloorAll + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to adjust. + * + * @return {Phaser.Geom.Rectangle} The adjusted Rectangle. + */ +var FloorAll = function (rect) +{ + rect.x = Math.floor(rect.x); + rect.y = Math.floor(rect.y); + rect.width = Math.floor(rect.width); + rect.height = Math.floor(rect.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; + return rect; +}; - if (parent === null) - { - // User is responsible for managing the parent - return; - } +module.exports = FloorAll; - 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%'; +/***/ 80222: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - DOMRect = this.parent.getBoundingClientRect(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // 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%'; - } - } - } +var Rectangle = __webpack_require__(74118); +var MATH_CONST = __webpack_require__(83392); - // And now get the fullscreenTarget - if (config.fullscreenTarget && !this.fullscreenTarget) - { - this.fullscreenTarget = GetTarget(config.fullscreenTarget); - } - }, +/** + * Constructs new Rectangle or repositions and resizes an existing Rectangle so that all of the given points are on or within its bounds. + * + * The `points` parameter is an array of Point-like objects: + * + * ```js + * const points = [ + * [100, 200], + * [200, 400], + * { x: 30, y: 60 } + * ] + * ``` + * + * @function Phaser.Geom.Rectangle.FromPoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * + * @param {array} points - An array of points (either arrays with two elements corresponding to the X and Y coordinate or an object with public `x` and `y` properties) which should be surrounded by the Rectangle. + * @param {Phaser.Geom.Rectangle} [out] - Optional Rectangle to adjust. + * + * @return {Phaser.Geom.Rectangle} The adjusted `out` Rectangle, or a new Rectangle if none was provided. + */ +var FromPoints = function (points, out) +{ + if (out === undefined) { out = new Rectangle(); } - /** - * 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 (points.length === 0) { - if (!this.parent) - { - return false; - } - - var parentSize = this.parentSize; + return out; + } - // Ref. http://msdn.microsoft.com/en-us/library/hh781509(v=vs.85).aspx for getBoundingClientRect + var minX = Number.MAX_VALUE; + var minY = Number.MAX_VALUE; - var DOMRect = this.parent.getBoundingClientRect(); + var maxX = MATH_CONST.MIN_SAFE_INTEGER; + var maxY = MATH_CONST.MIN_SAFE_INTEGER; - if (this.parentIsWindow && this.game.device.os.iOS) - { - DOMRect.height = GetInnerHeight(true); - } + var p; + var px; + var py; - var newWidth = DOMRect.width; - var newHeight = DOMRect.height; + for (var i = 0; i < points.length; i++) + { + p = points[i]; - if (parentSize.width !== newWidth || parentSize.height !== newHeight) + if (Array.isArray(p)) { - parentSize.setSize(newWidth, newHeight); - - return true; + px = p[0]; + py = p[1]; } else { - return false; + px = p.x; + py = p.y; } - }, - /** - * 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; + minX = Math.min(minX, px); + minY = Math.min(minY, py); - if (lock) - { - return lock.call(screen, orientation); - } + maxX = Math.max(maxX, px); + maxY = Math.max(maxY, py); + } - return false; - }, + out.x = minX; + out.y = minY; + out.width = maxX - minX; + out.height = maxY - minY; - /** - * 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 out; +}; - return this.refresh(); - }, +module.exports = FromPoints; - /** - * 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; +/***/ 75785: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // 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); +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // The modified game size - this.baseSize.resize(width, height); +var Rectangle = __webpack_require__(74118); - if (autoRound) - { - this.baseSize.width = Math.floor(this.baseSize.width); - this.baseSize.height = Math.floor(this.baseSize.height); - } +/** + * Create the smallest Rectangle containing two coordinate pairs. + * + * @function Phaser.Geom.Rectangle.FromXY + * @since 3.23.0 + * + * @generic {Phaser.Geom.Rectangle} O - [out,$return] + * + * @param {number} x1 - The X coordinate of the first point. + * @param {number} y1 - The Y coordinate of the first point. + * @param {number} x2 - The X coordinate of the second point. + * @param {number} y2 - The Y coordinate of the second point. + * @param {Phaser.Geom.Rectangle} [out] - Optional Rectangle to adjust. + * + * @return {Phaser.Geom.Rectangle} The adjusted `out` Rectangle, or a new Rectangle if none was provided. + */ +var FromXY = function (x1, y1, x2, y2, out) +{ + if (out === undefined) { out = new Rectangle(); } - // 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); + return out.setTo( + Math.min(x1, x2), + Math.min(y1, y2), + Math.abs(x1 - x2), + Math.abs(y1 - y2) + ); +}; - this.canvas.width = this.baseSize.width; - this.canvas.height = this.baseSize.height; +module.exports = FromXY; - 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); - } +/***/ 6700: +/***/ ((module) => { - var previousWidth = this.width; - var previousHeight = this.height; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // 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); +/** + * Calculates the width/height ratio of a rectangle. + * + * @function Phaser.Geom.Rectangle.GetAspectRatio + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - The rectangle. + * + * @return {number} The width/height ratio of the rectangle. + */ +var GetAspectRatio = function (rect) +{ + return (rect.height === 0) ? NaN : rect.width / rect.height; +}; - // The modified game size - this.baseSize.resize(width, height); +module.exports = GetAspectRatio; - 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; +/***/ 35242: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var style = this.canvas.style; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var styleWidth = width * zoom; - var styleHeight = height * zoom; +var Point = __webpack_require__(79967); - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } +/** + * Returns the center of a Rectangle as a Point. + * + * @function Phaser.Geom.Rectangle.GetCenter + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to get the center of. + * @param {(Phaser.Geom.Point|object)} [out] - Optional point-like object to update with the center coordinates. + * + * @return {(Phaser.Geom.Point|object)} The modified `out` object, or a new Point if none was provided. + */ +var GetCenter = function (rect, out) +{ + if (out === undefined) { out = new Point(); } - if (styleWidth !== width || styleHeight !== height) - { - style.width = styleWidth + 'px'; - style.height = styleHeight + 'px'; - } + out.x = rect.centerX; + out.y = rect.centerY; - return this.refresh(previousWidth, previousHeight); - }, + return out; +}; - /** - * 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; +module.exports = GetCenter; - 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(); - }, +/***/ 47698: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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) +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Perimeter = __webpack_require__(85876); +var Point = __webpack_require__(79967); + +/** + * Calculates the coordinates of a point at a certain `position` on the Rectangle's perimeter. + * + * The `position` is a fraction between 0 and 1 which defines how far into the perimeter the point is. + * + * A value of 0 or 1 returns the point at the top left corner of the rectangle, while a value of 0.5 returns the point at the bottom right corner of the rectangle. Values between 0 and 0.5 are on the top or the right side and values between 0.5 and 1 are on the bottom or the left side. + * + * @function Phaser.Geom.Rectangle.GetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} rectangle - The Rectangle to get the perimeter point from. + * @param {number} position - The normalized distance into the Rectangle's perimeter to return. + * @param {(Phaser.Geom.Point|object)} [out] - An object to update with the `x` and `y` coordinates of the point. + * + * @return {Phaser.Geom.Point} The updated `output` object, or a new Point if no `output` object was given. + */ +var GetPoint = function (rectangle, position, out) +{ + if (out === undefined) { out = new Point(); } + + if (position <= 0 || position >= 1) { - if (previousWidth === undefined) { previousWidth = this.width; } - if (previousHeight === undefined) { previousHeight = this.height; } + out.x = rectangle.x; + out.y = rectangle.y; - this.updateScale(); - this.updateBounds(); - this.updateOrientation(); + return out; + } - this.displayScale.set(this.baseSize.width / this.canvasBounds.width, this.baseSize.height / this.canvasBounds.height); + var p = Perimeter(rectangle) * position; - var domContainer = this.game.domContainer; + if (position > 0.5) + { + p -= (rectangle.width + rectangle.height); - if (domContainer) + if (p <= rectangle.width) { - this.baseSize.setCSS(domContainer); + // Face 3 + out.x = rectangle.right - p; + out.y = rectangle.bottom; + } + else + { + // Face 4 + out.x = rectangle.x; + out.y = rectangle.bottom - (p - rectangle.width); + } + } + else if (p <= rectangle.width) + { + // Face 1 + out.x = rectangle.x + p; + out.y = rectangle.y; + } + else + { + // Face 2 + out.x = rectangle.right; + out.y = rectangle.y + (p - rectangle.width); + } - var canvasStyle = this.canvas.style; - var domStyle = domContainer.style; + return out; +}; - domStyle.transform = 'scale(' + this.displaySize.width / this.baseSize.width + ',' + this.displaySize.height / this.baseSize.height + ')'; +module.exports = GetPoint; - domStyle.marginLeft = canvasStyle.marginLeft; - domStyle.marginTop = canvasStyle.marginTop; - } - this.emit(Events.RESIZE, this.gameSize, this.baseSize, this.displaySize, previousWidth, previousHeight); +/***/ }), - return this; - }, +/***/ 54932: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var newOrientation = GetScreenOrientation(this.width, this.height); +var GetPoint = __webpack_require__(47698); +var Perimeter = __webpack_require__(85876); - if (newOrientation !== this.orientation) - { - this.orientation = newOrientation; +/** + * Return an array of points from the perimeter of the rectangle, each spaced out based on the quantity or step required. + * + * @function Phaser.Geom.Rectangle.GetPoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point[]} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} rectangle - The Rectangle object to get the points from. + * @param {number} step - Step between points. Used to calculate the number of points to return when quantity is falsey. Ignored if quantity is positive. + * @param {number} quantity - The number of evenly spaced points from the rectangles perimeter to return. If falsey, step param will be used to calculate the number of points. + * @param {(array|Phaser.Geom.Point[])} [out] - An optional array to store the points in. + * + * @return {(array|Phaser.Geom.Point[])} An array of Points from the perimeter of the rectangle. + */ +var GetPoints = function (rectangle, quantity, stepRate, out) +{ + if (out === undefined) { out = []; } - this.emit(Events.ORIENTATION_CHANGE, newOrientation); - } - } - }, + // If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. + if (!quantity && stepRate > 0) + { + quantity = Perimeter(rectangle) / stepRate; + } - /** - * Internal method that manages updating the size components based on the scale mode. - * - * @method Phaser.Scale.ScaleManager#updateScale - * @since 3.16.0 - */ - updateScale: function () + for (var i = 0; i < quantity; i++) { - var style = this.canvas.style; + var position = i / quantity; - var width = this.gameSize.width; - var height = this.gameSize.height; + out.push(GetPoint(rectangle, position)); + } - var styleWidth; - var styleHeight; + return out; +}; - var zoom = this.zoom; - var autoRound = this.autoRound; +module.exports = GetPoints; - 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); - } +/***/ 31591: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (this._resetZoom) - { - style.width = styleWidth + 'px'; - style.height = styleHeight + 'px'; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this._resetZoom = false; - } - } - else if (this.scaleMode === CONST.SCALE_MODE.RESIZE) - { - // Resize to match parent +var Point = __webpack_require__(79967); - // This will constrain using min/max - this.displaySize.setSize(this.parentSize.width, this.parentSize.height); +/** + * Returns the size of the Rectangle, expressed as a Point object. + * With the value of the `width` as the `x` property and the `height` as the `y` property. + * + * @function Phaser.Geom.Rectangle.GetSize + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to get the size from. + * @param {(Phaser.Geom.Point|object)} [out] - The Point object to store the size in. If not given, a new Point instance is created. + * + * @return {(Phaser.Geom.Point|object)} A Point object where `x` holds the width and `y` holds the height of the Rectangle. + */ +var GetSize = function (rect, out) +{ + if (out === undefined) { out = new Point(); } - this.gameSize.setSize(this.displaySize.width, this.displaySize.height); + out.x = rect.width; + out.y = rect.height; - this.baseSize.setSize(this.displaySize.width, this.displaySize.height); + return out; +}; - styleWidth = this.displaySize.width; - styleHeight = this.displaySize.height; +module.exports = GetSize; - 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; +/***/ 7782: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (autoRound) - { - styleWidth = Math.floor(styleWidth); - styleHeight = Math.floor(styleHeight); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - style.width = styleWidth + 'px'; - style.height = styleHeight + 'px'; - } +var CenterOn = __webpack_require__(79993); - // Update the parentSize in case the canvas / style change modified it - this.getParentBounds(); +/** + * Increases the size of a Rectangle by a specified amount. + * + * The center of the Rectangle stays the same. The amounts are added to each side, so the actual increase in width or height is two times bigger than the respective argument. + * + * @function Phaser.Geom.Rectangle.Inflate + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to inflate. + * @param {number} x - How many pixels the left and the right side should be moved by horizontally. + * @param {number} y - How many pixels the top and the bottom side should be moved by vertically. + * + * @return {Phaser.Geom.Rectangle} The inflated Rectangle. + */ +var Inflate = function (rect, x, y) +{ + var cx = rect.centerX; + var cy = rect.centerY; - // Finally, update the centering - this.updateCenter(); - }, + rect.setSize(rect.width + (x * 2), rect.height + (y * 2)); - /** - * 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 CenterOn(rect, cx, cy); +}; - return Math.max(Math.min(zoomH, zoomV), 1); - }, +module.exports = Inflate; - /** - * 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; +/***/ 66217: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var style = canvas.style; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var bounds = canvas.getBoundingClientRect(); +var Rectangle = __webpack_require__(74118); +var Intersects = __webpack_require__(90205); - // var width = parseInt(canvas.style.width, 10) || canvas.width; - // var height = parseInt(canvas.style.height, 10) || canvas.height; +/** + * Takes two Rectangles and first checks to see if they intersect. + * If they intersect it will return the area of intersection in the `out` Rectangle. + * If they do not intersect, the `out` Rectangle will have a width and height of zero. + * + * @function Phaser.Geom.Rectangle.Intersection + * @since 3.11.0 + * + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] + * + * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to get the intersection from. + * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to get the intersection from. + * @param {Phaser.Geom.Rectangle} [out] - A Rectangle to store the intersection results in. + * + * @return {Phaser.Geom.Rectangle} The intersection result. If the width and height are zero, no intersection occurred. + */ +var Intersection = function (rectA, rectB, out) +{ + if (out === undefined) { out = new Rectangle(); } - var width = bounds.width; - var height = bounds.height; + if (Intersects(rectA, rectB)) + { + out.x = Math.max(rectA.x, rectB.x); + out.y = Math.max(rectA.y, rectB.y); + out.width = Math.min(rectA.right, rectB.right) - out.x; + out.height = Math.min(rectA.bottom, rectB.bottom) - out.y; + } + else + { + out.setEmpty(); + } - var offsetX = Math.floor((this.parentSize.width - width) / 2); - var offsetY = Math.floor((this.parentSize.height - height) / 2); + return out; +}; - if (autoCenter === CONST.CENTER.CENTER_HORIZONTALLY) - { - offsetY = 0; - } - else if (autoCenter === CONST.CENTER.CENTER_VERTICALLY) - { - offsetX = 0; - } +module.exports = Intersection; - 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; - }, +/***/ 40053: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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) +var Perimeter = __webpack_require__(85876); +var Point = __webpack_require__(79967); + +/** + * Returns an array of points from the perimeter of the Rectangle, where each point is spaced out based + * on either the `step` value, or the `quantity`. + * + * @function Phaser.Geom.Rectangle.MarchingAnts + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point[]} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to get the perimeter points from. + * @param {number} [step] - The distance between each point of the perimeter. Set to `null` if you wish to use the `quantity` parameter instead. + * @param {number} [quantity] - The total number of points to return. The step is then calculated based on the length of the Rectangle, divided by this value. + * @param {(array|Phaser.Geom.Point[])} [out] - An array in which the perimeter points will be stored. If not given, a new array instance is created. + * + * @return {(array|Phaser.Geom.Point[])} An array containing the perimeter points from the Rectangle. + */ +var MarchingAnts = function (rect, step, quantity, out) +{ + if (out === undefined) { out = []; } + + if (!step && !quantity) { - return (pageY - this.canvasBounds.top) * this.displayScale.y; - }, + // Bail out + return out; + } - /** - * 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 step is a falsey value (false, null, 0, undefined, etc) then we calculate + // it based on the quantity instead, otherwise we always use the step value + if (!step) { - if (fullscreenOptions === undefined) { fullscreenOptions = { navigationUI: 'hide' }; } + step = Perimeter(rect) / quantity; + } + else + { + quantity = Math.round(Perimeter(rect) / step); + } - var fullscreen = this.fullscreen; + var x = rect.x; + var y = rect.y; + var face = 0; - if (!fullscreen.available) - { - this.emit(Events.FULLSCREEN_UNSUPPORTED); + // Loop across each face of the rectangle - return; - } + for (var i = 0; i < quantity; i++) + { + out.push(new Point(x, y)); - if (!fullscreen.active) + switch (face) { - var fsTarget = this.getFullscreenTarget(); - if (fullscreen.keyboard) - { - fsTarget[fullscreen.request](Element.ALLOW_KEYBOARD_INPUT); - } - else - { - fsTarget[fullscreen.request](fullscreenOptions); - } - } - }, + // Top face + case 0: + x += step; - /** - * 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(); + if (x >= rect.right) + { + face = 1; + y += (x - rect.right); + x = rect.right; + } + break; - this.refresh(); + // Right face + case 1: + y += step; - this.emit(Events.ENTER_FULLSCREEN); - }, + if (y >= rect.bottom) + { + face = 2; + x -= (y - rect.bottom); + y = rect.bottom; + } + break; - /** - * 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(); + // Bottom face + case 2: + x -= step; - this.emit(Events.FULLSCREEN_FAILED, error); - }, + if (x <= rect.left) + { + face = 3; + y -= (rect.left - x); + x = rect.left; + } + break; - /** - * 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'); + // Left face + case 3: + y -= step; - fsTarget.style.margin = '0'; - fsTarget.style.padding = '0'; - fsTarget.style.width = '100%'; - fsTarget.style.height = '100%'; + if (y <= rect.top) + { + face = 0; + y = rect.top; + } + break; + } + } - this.fullscreenTarget = fsTarget; + return out; +}; - this._createdFullscreenTarget = true; - } +module.exports = MarchingAnts; - if (this._createdFullscreenTarget) - { - var canvasParent = this.canvas.parentNode; - canvasParent.insertBefore(this.fullscreenTarget, this.canvas); +/***/ }), - this.fullscreenTarget.appendChild(this.canvas); - } +/***/ 86673: +/***/ ((module) => { - return this.fullscreenTarget; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Removes the fullscreen target that was added to the DOM. - * - * @method Phaser.Scale.ScaleManager#removeFullscreenTarget - * @since 3.17.0 - */ - removeFullscreenTarget: function () +/** + * Merges a Rectangle with a list of points by repositioning and/or resizing it such that all points are located on or within its bounds. + * + * @function Phaser.Geom.Rectangle.MergePoints + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [target,$return] + * + * @param {Phaser.Geom.Rectangle} target - The Rectangle which should be merged. + * @param {Phaser.Geom.Point[]} points - An array of Points (or any object with public `x` and `y` properties) which should be merged with the Rectangle. + * + * @return {Phaser.Geom.Rectangle} The modified Rectangle. + */ +var MergePoints = function (target, points) +{ + var minX = target.x; + var maxX = target.right; + var minY = target.y; + var maxY = target.bottom; + + for (var i = 0; i < points.length; i++) { - if (this._createdFullscreenTarget) - { - var fsTarget = this.fullscreenTarget; + minX = Math.min(minX, points[i].x); + maxX = Math.max(maxX, points[i].x); + minY = Math.min(minY, points[i].y); + maxY = Math.max(maxY, points[i].y); + } - if (fsTarget && fsTarget.parentNode) - { - var parent = fsTarget.parentNode; + target.x = minX; + target.y = minY; + target.width = maxX - minX; + target.height = maxY - minY; - parent.insertBefore(this.canvas, fsTarget); + return target; +}; - parent.removeChild(fsTarget); - } - } - }, +module.exports = MergePoints; - /** - * 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; - } +/***/ 14655: +/***/ ((module) => { - if (fullscreen.active) - { - document[fullscreen.cancel](); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.removeFullscreenTarget(); +/** + * Merges the source rectangle into the target rectangle and returns the target. + * Neither rectangle should have a negative width or height. + * + * @function Phaser.Geom.Rectangle.MergeRect + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [target,$return] + * + * @param {Phaser.Geom.Rectangle} target - Target rectangle. Will be modified to include source rectangle. + * @param {Phaser.Geom.Rectangle} source - Rectangle that will be merged into target rectangle. + * + * @return {Phaser.Geom.Rectangle} Modified target rectangle that contains source rectangle. + */ +var MergeRect = function (target, source) +{ + var minX = Math.min(target.x, source.x); + var maxX = Math.max(target.right, source.right); - // Get the parent size again as it will have changed - this.getParentBounds(); + target.x = minX; + target.width = maxX - minX; - this.emit(Events.LEAVE_FULLSCREEN); + var minY = Math.min(target.y, source.y); + var maxY = Math.max(target.bottom, source.bottom); - this.refresh(); - }, + target.y = minY; + target.height = maxY - minY; - /** - * 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); - } - }, + return target; +}; - /** - * 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; +module.exports = MergeRect; - listeners.orientationChange = function () - { - _this.updateBounds(); - _this._checkOrientation = true; - _this.dirty = true; - }; +/***/ }), - listeners.windowResize = function () - { - _this.updateBounds(); +/***/ 44755: +/***/ ((module) => { - _this.dirty = true; - }; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Only dispatched on mobile devices - window.addEventListener('orientationchange', listeners.orientationChange, false); +/** + * Merges a Rectangle with a point by repositioning and/or resizing it so that the point is on or within its bounds. + * + * @function Phaser.Geom.Rectangle.MergeXY + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [target,$return] + * + * @param {Phaser.Geom.Rectangle} target - The Rectangle which should be merged and modified. + * @param {number} x - The X coordinate of the point which should be merged. + * @param {number} y - The Y coordinate of the point which should be merged. + * + * @return {Phaser.Geom.Rectangle} The modified `target` Rectangle. + */ +var MergeXY = function (target, x, y) +{ + var minX = Math.min(target.x, x); + var maxX = Math.max(target.right, x); - window.addEventListener('resize', listeners.windowResize, false); + target.x = minX; + target.width = maxX - minX; - if (this.fullscreen.available) - { - listeners.fullScreenChange = function (event) - { - return _this.onFullScreenChange(event); - }; + var minY = Math.min(target.y, y); + var maxY = Math.max(target.bottom, y); - listeners.fullScreenError = function (event) - { - return _this.onFullScreenError(event); - }; + target.y = minY; + target.height = maxY - minY; - var vendors = [ 'webkit', 'moz', '' ]; + return target; +}; - vendors.forEach(function (prefix) - { - document.addEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); - document.addEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); - }); +module.exports = MergeXY; - // 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(); - }, +/***/ 74466: +/***/ ((module) => { - /** - * 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; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this._lastCheck += delta; +/** + * Nudges (translates) the top left corner of a Rectangle by a given offset. + * + * @function Phaser.Geom.Rectangle.Offset + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to adjust. + * @param {number} x - The distance to move the Rectangle horizontally. + * @param {number} y - The distance to move the Rectangle vertically. + * + * @return {Phaser.Geom.Rectangle} The adjusted Rectangle. + */ +var Offset = function (rect, x, y) +{ + rect.x += x; + rect.y += y; - if (this.dirty || this._lastCheck > this.resizeInterval) - { - // Returns true if the parent bounds have changed size - if (this.getParentBounds()) - { - this.refresh(); - } + return rect; +}; - this.dirty = false; - this._lastCheck = 0; - } - }, +module.exports = Offset; - /** - * 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', '' ]; +/***/ 55946: +/***/ ((module) => { - vendors.forEach(function (prefix) - { - document.removeEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); - document.removeEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); - }); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // MS Specific - document.removeEventListener('MSFullscreenChange', listeners.fullScreenChange, false); - document.removeEventListener('MSFullscreenError', listeners.fullScreenError, false); - }, +/** + * Nudges (translates) the top-left corner of a Rectangle by the coordinates of a point (translation vector). + * + * @function Phaser.Geom.Rectangle.OffsetPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to adjust. + * @param {(Phaser.Geom.Point|Phaser.Math.Vector2)} point - The point whose coordinates should be used as an offset. + * + * @return {Phaser.Geom.Rectangle} The adjusted Rectangle. + */ +var OffsetPoint = function (rect, point) +{ + rect.x += point.x; + rect.y += point.y; - /** - * 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 () + return rect; +}; + +module.exports = OffsetPoint; + + +/***/ }), + +/***/ 97474: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks if two Rectangles overlap. If a Rectangle is within another Rectangle, the two will be considered overlapping. Thus, the Rectangles are treated as "solid". + * + * @function Phaser.Geom.Rectangle.Overlaps + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to check. + * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to check. + * + * @return {boolean} `true` if the two Rectangles overlap, `false` otherwise. + */ +var Overlaps = function (rectA, rectB) +{ + return ( + rectA.x < rectB.right && + rectA.right > rectB.x && + rectA.y < rectB.bottom && + rectA.bottom > rectB.y + ); +}; + +module.exports = Overlaps; + + +/***/ }), + +/***/ 85876: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculates the perimeter of a Rectangle. + * + * @function Phaser.Geom.Rectangle.Perimeter + * @since 3.0.0 + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to use. + * + * @return {number} The perimeter of the Rectangle, equal to `(width * 2) + (height * 2)`. + */ +var Perimeter = function (rect) +{ + return 2 * (rect.width + rect.height); +}; + +module.exports = Perimeter; + + +/***/ }), + +/***/ 20243: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Point = __webpack_require__(79967); +var DegToRad = __webpack_require__(75606); + +/** + * Returns a Point from the perimeter of a Rectangle based on the given angle. + * + * @function Phaser.Geom.Rectangle.PerimeterPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} rectangle - The Rectangle to get the perimeter point from. + * @param {number} angle - The angle of the point, in degrees. + * @param {Phaser.Geom.Point} [out] - The Point object to store the position in. If not given, a new Point instance is created. + * + * @return {Phaser.Geom.Point} A Point object holding the coordinates of the Rectangle perimeter. + */ +var PerimeterPoint = function (rectangle, angle, out) +{ + if (out === undefined) { out = new Point(); } + + angle = DegToRad(angle); + + var s = Math.sin(angle); + var c = Math.cos(angle); + + var dx = (c > 0) ? rectangle.width / 2 : rectangle.width / -2; + var dy = (s > 0) ? rectangle.height / 2 : rectangle.height / -2; + + if (Math.abs(dx * s) < Math.abs(dy * c)) { - this.removeAllListeners(); + dy = (dx * s) / c; + } + else + { + dx = (dy * c) / s; + } - this.stopListeners(); + out.x = dx + rectangle.centerX; + out.y = dy + rectangle.centerY; - this.game = null; - this.canvas = null; - this.canvasBounds = null; - this.parent = null; - this.fullscreenTarget = null; + return out; +}; - this.parentSize.destroy(); - this.gameSize.destroy(); - this.baseSize.destroy(); - this.displaySize.destroy(); - }, +module.exports = PerimeterPoint; - /** - * 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; - } +/***/ }), - }, +/***/ 30001: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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: { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - get: function () - { - return this.gameSize.width; - } +var Point = __webpack_require__(79967); - }, +/** + * Returns a random point within a Rectangle. + * + * @function Phaser.Geom.Rectangle.Random + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} rect - The Rectangle to return a point from. + * @param {Phaser.Geom.Point} out - The object to update with the point's coordinates. + * + * @return {Phaser.Geom.Point} The modified `out` object, or a new Point if none was provided. + */ +var Random = function (rect, out) +{ + if (out === undefined) { out = new Point(); } - /** - * 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: { + out.x = rect.x + (Math.random() * rect.width); + out.y = rect.y + (Math.random() * rect.height); - get: function () - { - return this.gameSize.height; - } + return out; +}; - }, +module.exports = Random; - /** - * 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); - } +/***/ }), - }, +/***/ 97691: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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: { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - get: function () - { - return (this.orientation === CONST.ORIENTATION.LANDSCAPE); - } +var Between = __webpack_require__(17489); +var ContainsRect = __webpack_require__(73222); +var Point = __webpack_require__(79967); - }, +/** + * Calculates a random point that lies within the `outer` Rectangle, but outside of the `inner` Rectangle. + * The inner Rectangle must be fully contained within the outer rectangle. + * + * @function Phaser.Geom.Rectangle.RandomOutside + * @since 3.10.0 + * + * @generic {Phaser.Geom.Point} O - [out,$return] + * + * @param {Phaser.Geom.Rectangle} outer - The outer Rectangle to get the random point within. + * @param {Phaser.Geom.Rectangle} inner - The inner Rectangle to exclude from the returned point. + * @param {Phaser.Geom.Point} [out] - A Point, or Point-like object to store the result in. If not specified, a new Point will be created. + * + * @return {Phaser.Geom.Point} A Point object containing the random values in its `x` and `y` properties. + */ +var RandomOutside = function (outer, inner, out) +{ + if (out === undefined) { out = new Point(); } - /** - * 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: { + if (ContainsRect(outer, inner)) + { + // Pick a random quadrant + // + // The quadrants don't extend the full widths / heights of the outer rect to give + // us a better uniformed distribution, otherwise you get clumping in the corners where + // the 4 quads would overlap - get: function () + switch (Between(0, 3)) { - return (this.height > this.width); - } + case 0: // Top + out.x = outer.x + (Math.random() * (inner.right - outer.x)); + out.y = outer.y + (Math.random() * (inner.top - outer.y)); + break; - }, + case 1: // Bottom + out.x = inner.x + (Math.random() * (outer.right - inner.x)); + out.y = inner.bottom + (Math.random() * (outer.bottom - inner.bottom)); + break; - /** - * 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: { + case 2: // Left + out.x = outer.x + (Math.random() * (inner.x - outer.x)); + out.y = inner.y + (Math.random() * (outer.bottom - inner.y)); + break; - get: function () - { - return (this.width > this.height); + case 3: // Right + out.x = inner.right + (Math.random() * (outer.right - inner.right)); + out.y = outer.y + (Math.random() * (inner.bottom - outer.y)); + break; } - } -}); + return out; +}; -module.exports = ScaleManager; +module.exports = RandomOutside; /***/ }), -/* 416 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 74118: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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); +var Class = __webpack_require__(56694); +var Contains = __webpack_require__(94287); +var GetPoint = __webpack_require__(47698); +var GetPoints = __webpack_require__(54932); +var GEOM_CONST = __webpack_require__(52394); +var Line = __webpack_require__(88829); +var Random = __webpack_require__(30001); /** * @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. + * Encapsulates a 2D rectangle defined by its corner point in the top-left and its extends in x (width) and y (height) * - * @class Size - * @memberof Phaser.Structs + * @class Rectangle + * @memberof Phaser.Geom * @constructor - * @since 3.16.0 + * @since 3.0.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. + * @param {number} [x=0] - The X coordinate of the top left corner of the Rectangle. + * @param {number} [y=0] - The Y coordinate of the top left corner of the Rectangle. + * @param {number} [width=0] - The width of the Rectangle. + * @param {number} [height=0] - The height of the Rectangle. */ -var Size = new Class({ +var Rectangle = new Class({ initialize: - function Size (width, height, aspectMode, parent) + function Rectangle (x, y, width, height) { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } if (width === undefined) { width = 0; } - if (height === undefined) { height = 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; + if (height === undefined) { height = 0; } /** - * 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. + * The geometry constant type of this object: `GEOM_CONST.RECTANGLE`. + * Used for fast type comparisons. * - * @name Phaser.Structs.Size#aspectRatio + * @name Phaser.Geom.Rectangle#type * @type {number} * @readonly - * @since 3.16.0 + * @since 3.19.0 */ - this.aspectRatio = (height === 0) ? 1 : width / height; + this.type = GEOM_CONST.RECTANGLE; /** - * The minimum allowed width. - * Cannot be less than zero. - * This value is read-only. To change it see the `setMin` method. + * The X coordinate of the top left corner of the Rectangle. * - * @name Phaser.Structs.Size#minWidth + * @name Phaser.Geom.Rectangle#x * @type {number} - * @readonly - * @since 3.16.0 + * @default 0 + * @since 3.0.0 */ - this.minWidth = 0; + this.x = x; /** - * The minimum allowed height. - * Cannot be less than zero. - * This value is read-only. To change it see the `setMin` method. + * The Y coordinate of the top left corner of the Rectangle. * - * @name Phaser.Structs.Size#minHeight + * @name Phaser.Geom.Rectangle#y * @type {number} - * @readonly - * @since 3.16.0 + * @default 0 + * @since 3.0.0 */ - this.minHeight = 0; + this.y = y; /** - * The maximum allowed width. - * This value is read-only. To change it see the `setMax` method. + * The width of the Rectangle, i.e. the distance between its left side (defined by `x`) and its right side. * - * @name Phaser.Structs.Size#maxWidth + * @name Phaser.Geom.Rectangle#width * @type {number} - * @readonly - * @since 3.16.0 + * @default 0 + * @since 3.0.0 */ - this.maxWidth = Number.MAX_VALUE; + this.width = width; /** - * The maximum allowed height. - * This value is read-only. To change it see the `setMax` method. + * The height of the Rectangle, i.e. the distance between its top side (defined by `y`) and its bottom side. * - * @name Phaser.Structs.Size#maxHeight + * @name Phaser.Geom.Rectangle#height * @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 + * @default 0 + * @since 3.0.0 */ - this.snapTo = new Vector2(); + this.height = height; }, /** - * 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 + * Checks if the given point is inside the Rectangle's bounds. * - * @param {number} [value=0] - The aspect mode value. + * @method Phaser.Geom.Rectangle#contains + * @since 3.0.0 * - * @return {this} This Size component instance. + * @param {number} x - The X coordinate of the point to check. + * @param {number} y - The Y coordinate of the point to check. + * + * @return {boolean} `true` if the point is within the Rectangle's bounds, otherwise `false`. */ - setAspectMode: function (value) + contains: function (x, y) { - if (value === undefined) { value = 0; } - - this.aspectMode = value; - - return this.setSize(this._width, this._height); + return Contains(this, x, y); }, /** - * 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 + * Calculates the coordinates of a point at a certain `position` on the Rectangle's perimeter. * - * @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. + * The `position` is a fraction between 0 and 1 which defines how far into the perimeter the point is. * - * @return {this} This Size component instance. + * A value of 0 or 1 returns the point at the top left corner of the rectangle, while a value of 0.5 returns the point at the bottom right corner of the rectangle. Values between 0 and 0.5 are on the top or the right side and values between 0.5 and 1 are on the bottom or the left side. + * + * @method Phaser.Geom.Rectangle#getPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [output,$return] + * + * @param {number} position - The normalized distance into the Rectangle's perimeter to return. + * @param {(Phaser.Geom.Point|object)} [output] - An object to update with the `x` and `y` coordinates of the point. + * + * @return {(Phaser.Geom.Point|object)} The updated `output` object, or a new Point if no `output` object was given. */ - setSnap: function (snapWidth, snapHeight) + getPoint: function (position, output) { - if (snapWidth === undefined) { snapWidth = 0; } - if (snapHeight === undefined) { snapHeight = snapWidth; } - - this.snapTo.set(snapWidth, snapHeight); - - return this.setSize(this._width, this._height); + return GetPoint(this, position, output); }, /** - * 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`. + * Returns an array of points from the perimeter of the Rectangle, each spaced out based on the quantity or step required. * - * @method Phaser.Structs.Size#setParent - * @since 3.16.0 + * @method Phaser.Geom.Rectangle#getPoints + * @since 3.0.0 * - * @param {any} [parent] - Sets the parent of this Size component. Don't provide a value to clear an existing parent. + * @generic {Phaser.Geom.Point[]} O - [output,$return] * - * @return {this} This Size component instance. + * @param {number} quantity - The number of points to return. Set to `false` or 0 to return an arbitrary number of points (`perimeter / stepRate`) evenly spaced around the Rectangle based on the `stepRate`. + * @param {number} [stepRate] - If `quantity` is 0, determines the normalized distance between each returned point. + * @param {(array|Phaser.Geom.Point[])} [output] - An array to which to append the points. + * + * @return {(array|Phaser.Geom.Point[])} The modified `output` array, or a new array if none was provided. */ - setParent: function (parent) + getPoints: function (quantity, stepRate, output) { - this._parent = parent; + return GetPoints(this, quantity, stepRate, output); + }, - return this.setSize(this._width, this._height); + /** + * Returns a random point within the Rectangle's bounds. + * + * @method Phaser.Geom.Rectangle#getRandomPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [point,$return] + * + * @param {Phaser.Geom.Point} [point] - The object in which to store the `x` and `y` coordinates of the point. + * + * @return {Phaser.Geom.Point} The updated `point`, or a new Point if none was provided. + */ + getRandomPoint: function (point) + { + return Random(this, point); }, /** - * 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. + * Sets the position, width, and height of the Rectangle. * - * @method Phaser.Structs.Size#setMin - * @since 3.16.0 + * @method Phaser.Geom.Rectangle#setTo + * @since 3.0.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`. + * @param {number} x - The X coordinate of the top left corner of the Rectangle. + * @param {number} y - The Y coordinate of the top left corner of the Rectangle. + * @param {number} width - The width of the Rectangle. + * @param {number} height - The height of the Rectangle. * - * @return {this} This Size component instance. + * @return {this} This Rectangle object. */ - setMin: function (width, height) + setTo: function (x, y, width, height) { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } + this.x = x; + this.y = y; + this.width = width; + this.height = height; - this.minWidth = Clamp(width, 0, this.maxWidth); - this.minHeight = Clamp(height, 0, this.maxHeight); + return this; + }, - return this.setSize(this._width, this._height); + /** + * Resets the position, width, and height of the Rectangle to 0. + * + * @method Phaser.Geom.Rectangle#setEmpty + * @since 3.0.0 + * + * @return {this} This Rectangle object. + */ + setEmpty: function () + { + return this.setTo(0, 0, 0, 0); }, /** - * 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. + * Sets the position of the Rectangle. * - * @method Phaser.Structs.Size#setMax - * @since 3.16.0 + * @method Phaser.Geom.Rectangle#setPosition + * @since 3.0.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`. + * @param {number} x - The X coordinate of the top left corner of the Rectangle. + * @param {number} [y=x] - The Y coordinate of the top left corner of the Rectangle. * - * @return {this} This Size component instance. + * @return {this} This Rectangle object. */ - setMax: function (width, height) + setPosition: function (x, y) { - if (width === undefined) { width = Number.MAX_VALUE; } - if (height === undefined) { height = width; } + if (y === undefined) { y = x; } - this.maxWidth = Clamp(width, this.minWidth, Number.MAX_VALUE); - this.maxHeight = Clamp(height, this.minHeight, Number.MAX_VALUE); + this.x = x; + this.y = y; - return this.setSize(this._width, this._height); + return this; }, /** - * 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. + * Sets the width and height of the Rectangle. * - * @method Phaser.Structs.Size#setSize - * @since 3.16.0 + * @method Phaser.Geom.Rectangle#setSize + * @since 3.0.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`. + * @param {number} width - The width to set the Rectangle to. + * @param {number} [height=width] - The height to set the Rectangle to. * - * @return {this} This Size component instance. + * @return {this} This Rectangle object. */ 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; - } + this.width = width; + this.height = height; 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 + * Determines if the Rectangle is empty. A Rectangle is empty if its width or height is less than or equal to 0. * - * @param {number} ratio - The new aspect ratio. + * @method Phaser.Geom.Rectangle#isEmpty + * @since 3.0.0 * - * @return {this} This Size component instance. + * @return {boolean} `true` if the Rectangle is empty. A Rectangle object is empty if its width or height is less than or equal to 0. */ - setAspectRatio: function (ratio) + isEmpty: function () { - this.aspectRatio = ratio; - - return this.setSize(this._width, this._height); + return (this.width <= 0 || this.height <= 0); }, /** - * 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. + * Returns a Line object that corresponds to the top of this Rectangle. * - * @method Phaser.Structs.Size#resize - * @since 3.16.0 + * @method Phaser.Geom.Rectangle#getLineA + * @since 3.0.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`. + * @generic {Phaser.Geom.Line} O - [line,$return] * - * @return {this} This Size component instance. + * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. + * + * @return {Phaser.Geom.Line} A Line object that corresponds to the top of this Rectangle. */ - resize: function (width, height) + getLineA: function (line) { - 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; + if (line === undefined) { line = new Line(); } - return this; + line.setTo(this.x, this.y, this.right, this.y); + + return line; }, /** - * Takes a new width and passes it through the min/max clamp and then checks it doesn't exceed the parent width. + * Returns a Line object that corresponds to the right of this Rectangle. * - * @method Phaser.Structs.Size#getNewWidth - * @since 3.16.0 + * @method Phaser.Geom.Rectangle#getLineB + * @since 3.0.0 * - * @param {number} value - The value to clamp and check. - * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. + * @generic {Phaser.Geom.Line} O - [line,$return] * - * @return {number} The modified width value. + * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. + * + * @return {Phaser.Geom.Line} A Line object that corresponds to the right of this Rectangle. */ - getNewWidth: function (value, checkParent) + getLineB: function (line) { - if (checkParent === undefined) { checkParent = true; } - - value = Clamp(value, this.minWidth, this.maxWidth); + if (line === undefined) { line = new Line(); } - if (checkParent && this._parent && value > this._parent.width) - { - value = Math.max(this.minWidth, this._parent.width); - } + line.setTo(this.right, this.y, this.right, this.bottom); - return value; + return line; }, /** - * Takes a new height and passes it through the min/max clamp and then checks it doesn't exceed the parent height. + * Returns a Line object that corresponds to the bottom of this Rectangle. * - * @method Phaser.Structs.Size#getNewHeight - * @since 3.16.0 + * @method Phaser.Geom.Rectangle#getLineC + * @since 3.0.0 * - * @param {number} value - The value to clamp and check. - * @param {boolean} [checkParent=true] - Check the given value against the parent, if set. + * @generic {Phaser.Geom.Line} O - [line,$return] * - * @return {number} The modified height value. + * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. + * + * @return {Phaser.Geom.Line} A Line object that corresponds to the bottom of this Rectangle. */ - getNewHeight: function (value, checkParent) + getLineC: function (line) { - if (checkParent === undefined) { checkParent = true; } - - value = Clamp(value, this.minHeight, this.maxHeight); + if (line === undefined) { line = new Line(); } - if (checkParent && this._parent && value > this._parent.height) - { - value = Math.max(this.minHeight, this._parent.height); - } + line.setTo(this.right, this.bottom, this.x, this.bottom); - return value; + return line; }, /** - * 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. + * Returns a Line object that corresponds to the left of this Rectangle. * - * @method Phaser.Structs.Size#constrain - * @since 3.16.0 + * @method Phaser.Geom.Rectangle#getLineD + * @since 3.0.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. + * @generic {Phaser.Geom.Line} O - [line,$return] * - * @return {this} This Size component instance. + * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. + * + * @return {Phaser.Geom.Line} A Line object that corresponds to the left of this Rectangle. */ - constrain: function (width, height, fit) + getLineD: function (line) { - if (width === undefined) { width = 0; } - if (height === undefined) { height = width; } - if (fit === undefined) { fit = true; } - - width = this.getNewWidth(width); - height = this.getNewHeight(height); + if (line === undefined) { line = new Line(); } - var snap = this.snapTo; - var newRatio = (height === 0) ? 1 : width / height; + line.setTo(this.x, this.bottom, this.x, this.y); - if ((fit && this.aspectRatio > newRatio) || (!fit && this.aspectRatio < newRatio)) - { - // We need to change the height to fit the width + return line; + }, - width = SnapFloor(width, snap.x); + /** + * The x coordinate of the left of the Rectangle. + * Changing the left property of a Rectangle object has no effect on the y and height properties. However it does affect the width property, whereas changing the x value does not affect the width property. + * + * @name Phaser.Geom.Rectangle#left + * @type {number} + * @since 3.0.0 + */ + left: { - height = width / this.aspectRatio; + get: function () + { + return this.x; + }, - if (snap.y > 0) + set: function (value) + { + if (value >= this.right) { - height = SnapFloor(height, snap.y); - - // Reduce the width accordingly - width = height * this.aspectRatio; + this.width = 0; + } + else + { + this.width = this.right - value; } + + this.x = value; } - 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; + /** + * The sum of the x and width properties. + * Changing the right property of a Rectangle object has no effect on the x, y and height properties, however it does affect the width property. + * + * @name Phaser.Geom.Rectangle#right + * @type {number} + * @since 3.0.0 + */ + right: { - if (snap.x > 0) - { - width = SnapFloor(width, snap.x); + get: function () + { + return this.x + this.width; + }, - // Reduce the height accordingly - height = width * (1 / this.aspectRatio); + set: function (value) + { + if (value <= this.x) + { + this.width = 0; + } + else + { + this.width = value - this.x; } } - 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. + * The y coordinate of the top of the Rectangle. Changing the top property of a Rectangle object has no effect on the x and width properties. + * However it does affect the height property, whereas changing the y value does not affect the height property. * - * @return {this} This Size component instance. + * @name Phaser.Geom.Rectangle#top + * @type {number} + * @since 3.0.0 */ - fitTo: function (width, height) - { - return this.constrain(width, height, true); - }, + top: { - /** - * 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 + ') }]'; - }, + get: function () + { + return this.y; + }, - /** - * 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) + set: function (value) { - element.style.width = this._width + 'px'; - element.style.height = this._height + 'px'; + if (value >= this.bottom) + { + this.height = 0; + } + else + { + this.height = (this.bottom - value); + } + + this.y = value; } + }, /** - * 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. + * The sum of the y and height properties. + * Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property. * - * @return {Phaser.Structs.Size} The updated destination Size component. + * @name Phaser.Geom.Rectangle#bottom + * @type {number} + * @since 3.0.0 */ - copy: function (destination) - { - destination.setAspectMode(this.aspectMode); + bottom: { - destination.aspectRatio = this.aspectRatio; + get: function () + { + return this.y + this.height; + }, - return destination.setSize(this.width, this.height); - }, + set: function (value) + { + if (value <= this.y) + { + this.height = 0; + } + else + { + this.height = value - this.y; + } + } - /** - * 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. + * The x coordinate of the center of the Rectangle. * - * @name Phaser.Structs.Size#width + * @name Phaser.Geom.Rectangle#centerX * @type {number} - * @since 3.16.0 + * @since 3.0.0 */ - width: { + centerX: { get: function () { - return this._width; + return this.x + (this.width / 2); }, set: function (value) { - this.setSize(value, this._height); + this.x = value - (this.width / 2); } }, /** - * 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. + * The y coordinate of the center of the Rectangle. * - * @name Phaser.Structs.Size#height + * @name Phaser.Geom.Rectangle#centerY * @type {number} - * @since 3.16.0 + * @since 3.0.0 */ - height: { + centerY: { get: function () { - return this._height; + return this.y + (this.height / 2); }, set: function (value) { - this.setSize(this._width, value); + this.y = value - (this.height / 2); } } }); -/** - * 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; +module.exports = Rectangle; -/** - * 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; +/***/ }), + +/***/ 51828: +/***/ ((module) => { /** - * 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 + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -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 + * Determines if the two objects (either Rectangles or Rectangle-like) have the same width and height values under strict equality. + * + * @function Phaser.Geom.Rectangle.SameDimensions + * @since 3.15.0 + * + * @param {Phaser.Geom.Rectangle} rect - The first Rectangle object. + * @param {Phaser.Geom.Rectangle} toCompare - The second Rectangle object. + * + * @return {boolean} `true` if the objects have equivalent values for the `width` and `height` properties, otherwise `false`. */ -Size.ENVELOP = 4; +var SameDimensions = function (rect, toCompare) +{ + return (rect.width === toCompare.width && rect.height === toCompare.height); +}; -module.exports = Size; +module.exports = SameDimensions; /***/ }), -/* 417 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 5691: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(144); -var Events = __webpack_require__(20); -var GameEvents = __webpack_require__(22); -var GetValue = __webpack_require__(6); -var LoaderEvents = __webpack_require__(95); -var NOOP = __webpack_require__(1); -var Scene = __webpack_require__(418); -var Systems = __webpack_require__(204); - /** - * @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. + * Scales the width and height of this Rectangle by the given amounts. * - * You should not usually interact directly with the Scene Manager at all. Instead, you should use - * the Scene Plugin, which is available from every Scene in your game via the `this.scene` property. + * @function Phaser.Geom.Rectangle.Scale + * @since 3.0.0 * - * Using methods in this Scene Manager directly will break queued operations and can cause runtime - * errors. Instead, go via the Scene Plugin. Every feature this Scene Manager provides is also - * available via the Scene Plugin. + * @generic {Phaser.Geom.Rectangle} O - [rect,$return] * - * @class SceneManager - * @memberof Phaser.Scenes - * @constructor - * @since 3.0.0 + * @param {Phaser.Geom.Rectangle} rect - The `Rectangle` object that will be scaled by the specified amount(s). + * @param {number} x - The factor by which to scale the rectangle horizontally. + * @param {number} y - The amount by which to scale the rectangle vertically. If this is not specified, the rectangle will be scaled by the factor `x` in both directions. * - * @param {Phaser.Game} game - The Phaser.Game instance this Scene Manager belongs to. - * @param {object} sceneConfig - Scene specific configuration settings. + * @return {Phaser.Geom.Rectangle} The rectangle object with updated `width` and `height` properties as calculated from the scaling factor(s). */ -var SceneManager = new Class({ +var Scale = function (rect, x, y) +{ + if (y === undefined) { y = x; } - initialize: + rect.width *= x; + rect.height *= y; - 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; + return rect; +}; - /** - * 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 {Record} - * @since 3.0.0 - */ - this.keys = {}; +module.exports = Scale; - /** - * The array in which all of the scenes are kept. - * - * @name Phaser.Scenes.SceneManager#scenes - * @type {Phaser.Scene[]} - * @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 = []; +/***/ 58795: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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 = []; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Boot time data to merge. - * - * @name Phaser.Scenes.SceneManager#_data - * @type {object} - * @private - * @since 3.4.0 - */ - this._data = {}; +var Rectangle = __webpack_require__(74118); - /** - * 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; +/** + * 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(); } - /** - * Has the Scene Manager properly started? - * - * @name Phaser.Scenes.SceneManager#isBooted - * @type {boolean} - * @default false - * @readonly - * @since 3.4.0 - */ - this.isBooted = false; + // 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; - /** - * 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; + return out.setTo(x, y, w, h); +}; - if (sceneConfig) - { - if (!Array.isArray(sceneConfig)) - { - sceneConfig = [ sceneConfig ]; - } +module.exports = Union; - 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; - } +/***/ 66658: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(74118); + +Rectangle.Area = __webpack_require__(1653); +Rectangle.Ceil = __webpack_require__(33943); +Rectangle.CeilAll = __webpack_require__(58662); +Rectangle.CenterOn = __webpack_require__(79993); +Rectangle.Clone = __webpack_require__(81572); +Rectangle.Contains = __webpack_require__(94287); +Rectangle.ContainsPoint = __webpack_require__(28687); +Rectangle.ContainsRect = __webpack_require__(73222); +Rectangle.CopyFrom = __webpack_require__(29538); +Rectangle.Decompose = __webpack_require__(87279); +Rectangle.Equals = __webpack_require__(19989); +Rectangle.FitInside = __webpack_require__(92628); +Rectangle.FitOutside = __webpack_require__(85028); +Rectangle.Floor = __webpack_require__(71356); +Rectangle.FloorAll = __webpack_require__(21687); +Rectangle.FromPoints = __webpack_require__(80222); +Rectangle.FromXY = __webpack_require__(75785); +Rectangle.GetAspectRatio = __webpack_require__(6700); +Rectangle.GetCenter = __webpack_require__(35242); +Rectangle.GetPoint = __webpack_require__(47698); +Rectangle.GetPoints = __webpack_require__(54932); +Rectangle.GetSize = __webpack_require__(31591); +Rectangle.Inflate = __webpack_require__(7782); +Rectangle.Intersection = __webpack_require__(66217); +Rectangle.MarchingAnts = __webpack_require__(40053); +Rectangle.MergePoints = __webpack_require__(86673); +Rectangle.MergeRect = __webpack_require__(14655); +Rectangle.MergeXY = __webpack_require__(44755); +Rectangle.Offset = __webpack_require__(74466); +Rectangle.OffsetPoint = __webpack_require__(55946); +Rectangle.Overlaps = __webpack_require__(97474); +Rectangle.Perimeter = __webpack_require__(85876); +Rectangle.PerimeterPoint = __webpack_require__(20243); +Rectangle.Random = __webpack_require__(30001); +Rectangle.RandomOutside = __webpack_require__(97691); +Rectangle.SameDimensions = __webpack_require__(51828); +Rectangle.Scale = __webpack_require__(5691); +Rectangle.Union = __webpack_require__(58795); - var i; - var entry; - var key; - var sceneConfig; +module.exports = Rectangle; - for (i = 0; i < this._pending.length; i++) - { - entry = this._pending[i]; - key = entry.key; - sceneConfig = entry.scene; +/***/ }), - var newScene; +/***/ 19108: +/***/ ((module) => { - 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); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Replace key in case the scene changed it - key = newScene.sys.settings.key; +// The 2D area of a triangle. The area value is always non-negative. - this.keys[key] = newScene; +/** + * Returns the area of a Triangle. + * + * @function Phaser.Geom.Triangle.Area + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to use. + * + * @return {number} The area of the Triangle, always non-negative. + */ +var Area = function (triangle) +{ + var x1 = triangle.x1; + var y1 = triangle.y1; - this.scenes.push(newScene); + var x2 = triangle.x2; + var y2 = triangle.y2; - // Any data to inject? - if (this._data[key]) - { - newScene.sys.settings.data = this._data[key].data; + var x3 = triangle.x3; + var y3 = triangle.y3; - if (this._data[key].autoStart) - { - entry.autoStart = true; - } - } + return Math.abs(((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1)) / 2); +}; - if (entry.autoStart || newScene.sys.settings.active) - { - this._start.push(key); - } - } +module.exports = Area; - // Clear the pending lists - this._pending.length = 0; - this._data = {}; +/***/ }), - this.isBooted = true; +/***/ 41199: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // _start might have been populated by the above - for (i = 0; i < this._start.length; i++) - { - entry = this._start[i]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.start(entry); - } +var Triangle = __webpack_require__(66349); - this._start.length = 0; - }, +/** + * Builds an equilateral triangle. In the equilateral triangle, all the sides are the same length (congruent) and all the angles are the same size (congruent). + * The x/y specifies the top-middle of the triangle (x1/y1) and length is the length of each side. + * + * @function Phaser.Geom.Triangle.BuildEquilateral + * @since 3.0.0 + * + * @param {number} x - x coordinate of the top point of the triangle. + * @param {number} y - y coordinate of the top point of the triangle. + * @param {number} length - Length of each side of the triangle. + * + * @return {Phaser.Geom.Triangle} The Triangle object of the given size. + */ +var BuildEquilateral = function (x, y, length) +{ + var height = length * (Math.sqrt(3) / 2); - /** - * 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; + var x1 = x; + var y1 = y; - if (pendingLength === 0 && queueLength === 0) - { - return; - } + var x2 = x + (length / 2); + var y2 = y + height; - var i; - var entry; + var x3 = x - (length / 2); + var y3 = y + height; - if (pendingLength) - { - for (i = 0; i < pendingLength; i++) - { - entry = this._pending[i]; + return new Triangle(x1, y1, x2, y2, x3, y3); +}; - this.add(entry.key, entry.scene, entry.autoStart, entry.data); - } +module.exports = BuildEquilateral; - // _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; +/***/ 88730: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (i = 0; i < this._queue.length; i++) - { - entry = this._queue[i]; +var EarCut = __webpack_require__(11117); +var Triangle = __webpack_require__(66349); - this[entry.op](entry.keyA, entry.keyB); - } +/** + * Takes an array of vertex coordinates, and optionally an array of hole indices, then returns an array + * of Triangle instances, where the given vertices have been decomposed into a series of triangles. + * + * @function Phaser.Geom.Triangle.BuildFromPolygon + * @since 3.0.0 + * + * @generic {Phaser.Geom.Triangle[]} O - [out,$return] + * + * @param {array} data - A flat array of vertex coordinates like [x0,y0, x1,y1, x2,y2, ...] + * @param {array} [holes=null] - An array of hole indices if any (e.g. [5, 8] for a 12-vertex input would mean one hole with vertices 5–7 and another with 8–11). + * @param {number} [scaleX=1] - Horizontal scale factor to multiply the resulting points by. + * @param {number} [scaleY=1] - Vertical scale factor to multiply the resulting points by. + * @param {(array|Phaser.Geom.Triangle[])} [out] - An array to store the resulting Triangle instances in. If not provided, a new array is created. + * + * @return {(array|Phaser.Geom.Triangle[])} An array of Triangle instances, where each triangle is based on the decomposed vertices data. + */ +var BuildFromPolygon = function (data, holes, scaleX, scaleY, out) +{ + if (holes === undefined) { holes = null; } + if (scaleX === undefined) { scaleX = 1; } + if (scaleY === undefined) { scaleY = 1; } + if (out === undefined) { out = []; } - this._queue.length = 0; - }, + var tris = EarCut(data, holes); - /** - * 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 = {}; } + var a; + var b; + var c; - // 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 - }); + var x1; + var y1; - if (!this.isBooted) - { - this._data[key] = { data: data }; - } + var x2; + var y2; - return null; - } + var x3; + var y3; - key = this.getKey(key, sceneConfig); + for (var i = 0; i < tris.length; i += 3) + { + a = tris[i]; + b = tris[i + 1]; + c = tris[i + 2]; - var newScene; + x1 = data[a * 2] * scaleX; + y1 = data[(a * 2) + 1] * scaleY; - if (sceneConfig instanceof Scene) - { - newScene = this.createSceneFromInstance(key, sceneConfig); - } - else if (typeof sceneConfig === 'object') - { - sceneConfig.key = key; + x2 = data[b * 2] * scaleX; + y2 = data[(b * 2) + 1] * scaleY; - newScene = this.createSceneFromObject(key, sceneConfig); - } - else if (typeof sceneConfig === 'function') - { - newScene = this.createSceneFromFunction(key, sceneConfig); - } + x3 = data[c * 2] * scaleX; + y3 = data[(c * 2) + 1] * scaleY; - // Any data to inject? - newScene.sys.settings.data = data; + out.push(new Triangle(x1, y1, x2, y2, x3, y3)); + } - // Replace key in case the scene changed it - key = newScene.sys.settings.key; + return out; +}; - this.keys[key] = newScene; +module.exports = BuildFromPolygon; - this.scenes.push(newScene); - if (autoStart || newScene.sys.settings.active) - { - if (this._pending.length) - { - this._start.push(key); - } - else - { - this.start(key); - } - } +/***/ }), - return newScene; - }, +/***/ 3635: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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 {this} This Scene Manager instance. - */ - remove: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'remove', keyA: key, keyB: null }); - } - else - { - var sceneToRemove = this.getScene(key); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (!sceneToRemove || sceneToRemove.sys.isTransitioning()) - { - return this; - } +var Triangle = __webpack_require__(66349); - var index = this.scenes.indexOf(sceneToRemove); - var sceneKey = sceneToRemove.sys.settings.key; +// Builds a right triangle, with one 90 degree angle and two acute angles +// The x/y is the coordinate of the 90 degree angle (and will map to x1/y1 in the resulting Triangle) +// w/h can be positive or negative and represent the length of each side - if (index > -1) - { - delete this.keys[sceneKey]; - this.scenes.splice(index, 1); +/** + * Builds a right triangle, i.e. one which has a 90-degree angle and two acute angles. + * + * @function Phaser.Geom.Triangle.BuildRight + * @since 3.0.0 + * + * @param {number} x - The X coordinate of the right angle, which will also be the first X coordinate of the constructed Triangle. + * @param {number} y - The Y coordinate of the right angle, which will also be the first Y coordinate of the constructed Triangle. + * @param {number} width - The length of the side which is to the left or to the right of the right angle. + * @param {number} height - The length of the side which is above or below the right angle. + * + * @return {Phaser.Geom.Triangle} The constructed right Triangle. + */ +var BuildRight = function (x, y, width, height) +{ + if (height === undefined) { height = width; } - if (this._start.indexOf(sceneKey) > -1) - { - index = this._start.indexOf(sceneKey); - this._start.splice(index, 1); - } + // 90 degree angle + var x1 = x; + var y1 = y; - sceneToRemove.sys.destroy(); - } - } + var x2 = x; + var y2 = y - height; - return this; - }, + var x3 = x + width; + var y3 = y; - /** - * 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; + return new Triangle(x1, y1, x2, y2, x3, y3); +}; - sys.sceneUpdate = NOOP; +module.exports = BuildRight; - 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); - } - } +/***/ 1882: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var loader; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (sys.load) - { - loader = sys.load; +var Centroid = __webpack_require__(56595); +var Offset = __webpack_require__(9640); - loader.reset(); - } +/** + * @callback CenterFunction + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to return the center coordinates of. + * + * @return {Phaser.Math.Vector2} The center point of the Triangle according to the function. + */ - if (loader && scene.preload) - { - scene.preload.call(scene); +/** + * Positions the Triangle so that it is centered on the given coordinates. + * + * @function Phaser.Geom.Triangle.CenterOn + * @since 3.0.0 + * + * @generic {Phaser.Geom.Triangle} O - [triangle,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The triangle to be positioned. + * @param {number} x - The horizontal coordinate to center on. + * @param {number} y - The vertical coordinate to center on. + * @param {CenterFunction} [centerFunc] - The function used to center the triangle. Defaults to Centroid centering. + * + * @return {Phaser.Geom.Triangle} The Triangle that was centered. + */ +var CenterOn = function (triangle, x, y, centerFunc) +{ + if (centerFunc === undefined) { centerFunc = Centroid; } - // Is the loader empty? - if (loader.list.size === 0) - { - this.create(scene); - } - else - { - settings.status = CONST.LOADING; + // Get the center of the triangle + var center = centerFunc(triangle); - // Start the loader going as we have something in the queue - loader.once(LoaderEvents.COMPLETE, this.loadComplete, this); + // Difference + var diffX = x - center.x; + var diffY = y - center.y; - loader.start(); - } - } - else - { - // No preload? Then there was nothing to load either - this.create(scene); - } - }, + return Offset(triangle, diffX, diffY); +}; - /** - * 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) - { - this.create(loader.scene); - }, +module.exports = CenterOn; - /** - * 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; +/***/ 56595: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Loop through the active scenes in reverse order - for (var i = this.scenes.length - 1; i >= 0; i--) - { - var sys = this.scenes[i].sys; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (sys.settings.status > CONST.START && sys.settings.status <= CONST.RUNNING) - { - sys.step(time, delta); - } - } - }, +var Point = __webpack_require__(79967); - /** - * 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; +// 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 - if (sys.settings.visible && sys.settings.status >= CONST.LOADING && sys.settings.status < CONST.SLEEPING) - { - sys.render(renderer); - } - } +/** + * 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(); } - this.isProcessing = false; - }, + out.x = (triangle.x1 + triangle.x2 + triangle.x3) / 3; + out.y = (triangle.y1 + triangle.y2 + triangle.y3) / 3; - /** - * 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; + return out; +}; - if (scene.create) - { - settings.status = CONST.CREATING; +module.exports = Centroid; - 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); - } +/***/ 91835: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // 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; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - settings.status = CONST.RUNNING; +var Vector2 = __webpack_require__(93736); - sys.events.emit(Events.CREATE, scene); - }, +// Adapted from http://bjornharrtell.github.io/jsts/doc/api/jsts_geom_Triangle.js.html - /** - * 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(); +/** + * Computes the determinant of a 2x2 matrix. Uses standard double-precision arithmetic, so is susceptible to round-off error. + * + * @function det + * @private + * @since 3.0.0 + * + * @param {number} m00 - The [0,0] entry of the matrix. + * @param {number} m01 - The [0,1] entry of the matrix. + * @param {number} m10 - The [1,0] entry of the matrix. + * @param {number} m11 - The [1,1] entry of the matrix. + * + * @return {number} the determinant. + */ +function det (m00, m01, m10, m11) +{ + return (m00 * m11) - (m01 * m10); +} - if (newScene instanceof Scene) - { - var configKey = newScene.sys.settings.key; +/** + * Computes the circumcentre of a triangle. The circumcentre is the centre of + * the circumcircle, the smallest circle which encloses the triangle. It is also + * the common intersection point of the perpendicular bisectors of the sides of + * the triangle, and is the only point which has equal distance to all three + * vertices of the triangle. + * + * @function Phaser.Geom.Triangle.CircumCenter + * @since 3.0.0 + * + * @generic {Phaser.Math.Vector2} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the circumcenter of. + * @param {Phaser.Math.Vector2} [out] - The Vector2 object to store the position in. If not given, a new Vector2 instance is created. + * + * @return {Phaser.Math.Vector2} A Vector2 object holding the coordinates of the circumcenter of the Triangle. + */ +var CircumCenter = function (triangle, out) +{ + if (out === undefined) { out = new Vector2(); } - if (configKey !== '') - { - key = configKey; - } + var cx = triangle.x3; + var cy = triangle.y3; - if (this.keys.hasOwnProperty(key)) - { - throw new Error('Cannot add a Scene with duplicate key: ' + key); - } + var ax = triangle.x1 - cx; + var ay = triangle.y1 - cy; - return this.createSceneFromInstance(key, newScene); - } - else - { - newScene.sys = new Systems(newScene); + var bx = triangle.x2 - cx; + var by = triangle.y2 - cy; - newScene.sys.settings.key = key; + var denom = 2 * det(ax, ay, bx, by); + var numx = det(ay, ax * ax + ay * ay, by, bx * bx + by * by); + var numy = det(ax, ax * ax + ay * ay, bx, bx * bx + by * by); - newScene.sys.init(this.game); + out.x = cx - numx / denom; + out.y = cy + numy / denom; - return newScene; - } - }, + return out; +}; - /** - * 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; +module.exports = CircumCenter; - if (configKey === '') - { - newScene.sys.settings.key = key; - } - newScene.sys.init(this.game); +/***/ }), - return newScene; - }, +/***/ 97073: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var configKey = newScene.sys.settings.key; +var Circle = __webpack_require__(26673); - if (configKey !== '') - { - key = configKey; - } - else - { - newScene.sys.settings.key = key; - } +// Adapted from https://gist.github.com/mutoo/5617691 - newScene.sys.init(this.game); +/** + * Finds the circumscribed circle (circumcircle) of a Triangle object. The circumcircle is the circle which touches all of the triangle's vertices. + * + * @function Phaser.Geom.Triangle.CircumCircle + * @since 3.0.0 + * + * @generic {Phaser.Geom.Circle} O - [out,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to use as input. + * @param {Phaser.Geom.Circle} [out] - An optional Circle to store the result in. + * + * @return {Phaser.Geom.Circle} The updated `out` Circle, or a new Circle if none was provided. + */ +var CircumCircle = function (triangle, out) +{ + if (out === undefined) { out = new Circle(); } - // Extract callbacks + // A + var x1 = triangle.x1; + var y1 = triangle.y1; - var defaults = [ 'init', 'preload', 'create', 'update', 'render' ]; + // B + var x2 = triangle.x2; + var y2 = triangle.y2; - for (var i = 0; i < defaults.length; i++) - { - var sceneCallback = GetValue(sceneConfig, defaults[i], null); + // C + var x3 = triangle.x3; + var y3 = triangle.y3; - if (sceneCallback) - { - newScene[defaults[i]] = sceneCallback; - } - } + var A = x2 - x1; + var B = y2 - y1; + var C = x3 - x1; + var D = y3 - y1; + var E = A * (x1 + x2) + B * (y1 + y2); + var F = C * (x1 + x3) + D * (y1 + y3); + var G = 2 * (A * (y3 - y2) - B * (x3 - x2)); - // Now let's move across any other functions or properties that may exist in the extend object: + var dx; + var dy; - /* - scene: { - preload: preload, - create: create, - extend: { - hello: 1, - test: 'atari', - addImage: addImage - } - } - */ + // If the points of the triangle are collinear, then just find the + // extremes and use the midpoint as the center of the circumcircle. - if (sceneConfig.hasOwnProperty('extend')) - { - for (var propertyKey in sceneConfig.extend) - { - if (!sceneConfig.extend.hasOwnProperty(propertyKey)) - { - continue; - } + if (Math.abs(G) < 0.000001) + { + var minX = Math.min(x1, x2, x3); + var minY = Math.min(y1, y2, y3); + dx = (Math.max(x1, x2, x3) - minX) * 0.5; + dy = (Math.max(y1, y2, y3) - minY) * 0.5; - var value = sceneConfig.extend[propertyKey]; + out.x = minX + dx; + out.y = minY + dy; + out.radius = Math.sqrt(dx * dx + dy * dy); + } + else + { + out.x = (D * E - B * F) / G; + out.y = (A * F - C * E) / G; + dx = out.x - x1; + dy = out.y - y1; + out.radius = Math.sqrt(dx * dx + dy * dy); + } - if (propertyKey === 'data' && newScene.hasOwnProperty('data') && typeof value === 'object') - { - // Populate the DataManager - newScene.data.merge(value); - } - else if (propertyKey !== 'sys') - { - newScene[propertyKey] = value; - } - } - } + return out; +}; - return newScene; - }, +module.exports = CircumCircle; - /** - * 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 +/***/ 75974: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (this.keys.hasOwnProperty(key)) - { - throw new Error('Cannot add a Scene with duplicate key: ' + key); - } - else - { - return key; - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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 Triangle = __webpack_require__(66349); - var out = []; - var scenes = this.scenes; +/** + * Clones a Triangle object. + * + * @function Phaser.Geom.Triangle.Clone + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} source - The Triangle to clone. + * + * @return {Phaser.Geom.Triangle} A new Triangle identical to the given one but separate from it. + */ +var Clone = function (source) +{ + return new Triangle(source.x1, source.y1, source.x2, source.y2, source.x3, source.y3); +}; - for (var i = 0; i < scenes.length; i++) - { - var scene = scenes[i]; +module.exports = Clone; - 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; - } - } - } +/***/ 60689: +/***/ ((module) => { - return null; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Determines whether a Scene is running. - * - * @method Phaser.Scenes.SceneManager#isActive - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to check. - * - * @return {boolean} Whether the Scene is running, or `null` if no matching Scene was found. - */ - isActive: function (key) - { - var scene = this.getScene(key); +// http://www.blackpawn.com/texts/pointinpoly/ - if (scene) - { - return scene.sys.isActive(); - } +/** + * Checks if a point (as a pair of coordinates) is inside a Triangle's bounds. + * + * @function Phaser.Geom.Triangle.Contains + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to check. + * @param {number} x - The X coordinate of the point to check. + * @param {number} y - The Y coordinate of the point to check. + * + * @return {boolean} `true` if the point is inside the Triangle, otherwise `false`. + */ +var Contains = function (triangle, x, y) +{ + var v0x = triangle.x3 - triangle.x1; + var v0y = triangle.y3 - triangle.y1; - return null; - }, + var v1x = triangle.x2 - triangle.x1; + var v1y = triangle.y2 - triangle.y1; - /** - * Determines whether a Scene is paused. - * - * @method Phaser.Scenes.SceneManager#isPaused - * @since 3.17.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to check. - * - * @return {boolean} Whether the Scene is paused, or `null` if no matching Scene was found. - */ - isPaused: function (key) - { - var scene = this.getScene(key); + var v2x = x - triangle.x1; + var v2y = y - triangle.y1; - if (scene) - { - return scene.sys.isPaused(); - } + var dot00 = (v0x * v0x) + (v0y * v0y); + var dot01 = (v0x * v1x) + (v0y * v1y); + var dot02 = (v0x * v2x) + (v0y * v2y); + var dot11 = (v1x * v1x) + (v1y * v1y); + var dot12 = (v1x * v2x) + (v1y * v2y); - return null; - }, + // Compute barycentric coordinates + var b = ((dot00 * dot11) - (dot01 * dot01)); + var inv = (b === 0) ? 0 : (1 / b); + var u = ((dot11 * dot02) - (dot01 * dot12)) * inv; + var v = ((dot00 * dot12) - (dot01 * dot02)) * inv; - /** - * Determines whether a Scene is visible. - * - * @method Phaser.Scenes.SceneManager#isVisible - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to check. - * - * @return {boolean} Whether the Scene is visible, or `null` if no matching Scene was found. - */ - isVisible: function (key) - { - var scene = this.getScene(key); + return (u >= 0 && v >= 0 && (u + v < 1)); +}; - if (scene) - { - return scene.sys.isVisible(); - } +module.exports = Contains; - return null; - }, - /** - * Determines whether a Scene is sleeping. - * - * @method Phaser.Scenes.SceneManager#isSleeping - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to check. - * - * @return {boolean} Whether the Scene is sleeping, or `null` if no matching Scene was found. - */ - isSleeping: function (key) - { - var scene = this.getScene(key); +/***/ }), - if (scene) - { - return scene.sys.isSleeping(); - } +/***/ 86875: +/***/ ((module) => { - return null; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Pauses the given Scene. - * - * @method Phaser.Scenes.SceneManager#pause - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} 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 {this} This Scene Manager instance. - */ - pause: function (key, data) - { - var scene = this.getScene(key); +// http://www.blackpawn.com/texts/pointinpoly/ - if (scene) - { - scene.sys.pause(data); - } +// points is an array of Point-like objects with public x/y properties +// returns an array containing all points that are within the triangle, or an empty array if none +// if 'returnFirst' is true it will return after the first point within the triangle is found - return this; - }, +/** + * Filters an array of point-like objects to only those contained within a triangle. + * If `returnFirst` is true, will return an array containing only the first point in the provided array that is within the triangle (or an empty array if there are no such points). + * + * @function Phaser.Geom.Triangle.ContainsArray + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The triangle that the points are being checked in. + * @param {Phaser.Geom.Point[]} points - An array of point-like objects (objects that have an `x` and `y` property) + * @param {boolean} [returnFirst=false] - If `true`, return an array containing only the first point found that is within the triangle. + * @param {array} [out] - If provided, the points that are within the triangle will be appended to this array instead of being added to a new array. If `returnFirst` is true, only the first point found within the triangle will be appended. This array will also be returned by this function. + * + * @return {Phaser.Geom.Point[]} An array containing all the points from `points` that are within the triangle, if an array was provided as `out`, points will be appended to that array and it will also be returned here. + */ +var ContainsArray = function (triangle, points, returnFirst, out) +{ + if (returnFirst === undefined) { returnFirst = false; } + if (out === undefined) { out = []; } - /** - * Resumes the given Scene. - * - * @method Phaser.Scenes.SceneManager#resume - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} 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 {this} This Scene Manager instance. - */ - resume: function (key, data) - { - var scene = this.getScene(key); + var v0x = triangle.x3 - triangle.x1; + var v0y = triangle.y3 - triangle.y1; - if (scene) - { - scene.sys.resume(data); - } + var v1x = triangle.x2 - triangle.x1; + var v1y = triangle.y2 - triangle.y1; - return this; - }, + var dot00 = (v0x * v0x) + (v0y * v0y); + var dot01 = (v0x * v1x) + (v0y * v1y); + var dot11 = (v1x * v1x) + (v1y * v1y); - /** - * Puts the given Scene to sleep. - * - * @method Phaser.Scenes.SceneManager#sleep - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} 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 {this} This Scene Manager instance. - */ - sleep: function (key, data) - { - var scene = this.getScene(key); + // Compute barycentric coordinates + var b = ((dot00 * dot11) - (dot01 * dot01)); + var inv = (b === 0) ? 0 : (1 / b); - if (scene && !scene.sys.isTransitioning()) - { - scene.sys.sleep(data); - } + var u; + var v; + var v2x; + var v2y; + var dot02; + var dot12; - return this; - }, + var x1 = triangle.x1; + var y1 = triangle.y1; - /** - * Awakens the given Scene. - * - * @method Phaser.Scenes.SceneManager#wake - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} 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 {this} This Scene Manager instance. - */ - wake: function (key, data) + for (var i = 0; i < points.length; i++) { - var scene = this.getScene(key); - - if (scene) - { - scene.sys.wake(data); - } + v2x = points[i].x - x1; + v2y = points[i].y - y1; - return this; - }, + dot02 = (v0x * v2x) + (v0y * v2y); + dot12 = (v1x * v2x) + (v1y * v2y); - /** - * 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|Phaser.Scene)} key - The Scene to run. - * @param {object} [data] - A data object that will be passed to the Scene on start, wake, or resume. - * - * @return {this} This Scene Manager instance. - */ - run: function (key, data) - { - var scene = this.getScene(key); + u = ((dot11 * dot02) - (dot01 * dot12)) * inv; + v = ((dot00 * dot12) - (dot01 * dot02)) * inv; - if (!scene) + if (u >= 0 && v >= 0 && (u + v < 1)) { - for (var i = 0; i < this._pending.length; i++) + out.push({ x: points[i].x, y: points[i].y }); + + if (returnFirst) { - if (this._pending[i].key === key) - { - this.queueOp('start', key, data); - break; - } + 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); - } - }, + return out; +}; - /** - * Starts the given Scene. - * - * @method Phaser.Scenes.SceneManager#start - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to start. - * @param {object} [data] - Optional data object to pass to `Scene.Settings` and `Scene.init`, and `Scene.create`. - * - * @return {this} This Scene Manager instance. - */ - 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 - }; +module.exports = ContainsArray; - return this; - } - var scene = this.getScene(key); +/***/ }), - if (scene) - { - var sys = scene.sys; +/***/ 51532: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // 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(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - sys.sceneUpdate = NOOP; +var Contains = __webpack_require__(60689); - sys.start(data); - } - else - { - sys.sceneUpdate = NOOP; +/** + * Tests if a triangle contains a point. + * + * @function Phaser.Geom.Triangle.ContainsPoint + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The triangle. + * @param {(Phaser.Geom.Point|Phaser.Math.Vector2|any)} point - The point to test, or any point-like object with public `x` and `y` properties. + * + * @return {boolean} `true` if the point is within the triangle, otherwise `false`. + */ +var ContainsPoint = function (triangle, point) +{ + return Contains(triangle, point.x, point.y); +}; - sys.start(data); +module.exports = ContainsPoint; - var loader; - if (sys.load) - { - loader = sys.load; - } +/***/ }), - // Files payload? - if (loader && sys.settings.hasOwnProperty('pack')) - { - loader.reset(); +/***/ 42538: +/***/ ((module) => { - if (loader.addPack({ payload: sys.settings.pack })) - { - sys.settings.status = CONST.LOADING; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - loader.once(LoaderEvents.COMPLETE, this.payloadComplete, this); +/** + * Copy the values of one Triangle to a destination Triangle. + * + * @function Phaser.Geom.Triangle.CopyFrom + * @since 3.0.0 + * + * @generic {Phaser.Geom.Triangle} O - [dest,$return] + * + * @param {Phaser.Geom.Triangle} source - The source Triangle to copy the values from. + * @param {Phaser.Geom.Triangle} dest - The destination Triangle to copy the values to. + * + * @return {Phaser.Geom.Triangle} The destination Triangle. + */ +var CopyFrom = function (source, dest) +{ + return dest.setTo(source.x1, source.y1, source.x2, source.y2, source.x3, source.y3); +}; - loader.start(); +module.exports = CopyFrom; - return this; - } - } - } - this.bootScene(scene); - } +/***/ }), - return this; - }, +/***/ 18680: +/***/ ((module) => { - /** - * Stops the given Scene. - * - * @method Phaser.Scenes.SceneManager#stop - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} key - The Scene to stop. - * @param {object} [data] - Optional data object to pass to Scene.shutdown. - * - * @return {this} This Scene Manager instance. - */ - stop: function (key, data) - { - var scene = this.getScene(key); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (scene && !scene.sys.isTransitioning()) - { - scene.sys.shutdown(data); - } +/** + * 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 = []; } - return this; - }, + out.push({ x: triangle.x1, y: triangle.y1 }); + out.push({ x: triangle.x2, y: triangle.y2 }); + out.push({ x: triangle.x3, y: triangle.y3 }); - /** - * Sleeps one one Scene and starts the other. - * - * @method Phaser.Scenes.SceneManager#switch - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} from - The Scene to sleep. - * @param {(string|Phaser.Scene)} to - The Scene to start. - * - * @return {this} This Scene Manager instance. - */ - switch: function (from, to) - { - var sceneA = this.getScene(from); - var sceneB = this.getScene(to); + return out; +}; - if (sceneA && sceneB && sceneA !== sceneB) - { - this.sleep(from); +module.exports = Decompose; - 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]; - }, +/***/ 29977: +/***/ ((module) => { - /** - * 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); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this.scenes.indexOf(scene); - }, +/** + * Returns true if two triangles have the same coordinates. + * + * @function Phaser.Geom.Triangle.Equals + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The first triangle to check. + * @param {Phaser.Geom.Triangle} toCompare - The second triangle to check. + * + * @return {boolean} `true` if the two given triangles have the exact same coordinates, otherwise `false`. + */ +var Equals = function (triangle, toCompare) +{ + return ( + triangle.x1 === toCompare.x1 && + triangle.y1 === toCompare.y1 && + triangle.x2 === toCompare.x2 && + triangle.y2 === toCompare.y2 && + triangle.x3 === toCompare.x3 && + triangle.y3 === toCompare.y3 + ); +}; - /** - * 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 {this} This Scene Manager instance. - */ - bringToTop: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'bringToTop', keyA: key, keyB: null }); - } - else - { - var index = this.getIndex(key); +module.exports = Equals; - if (index !== -1 && index < this.scenes.length) - { - var scene = this.getScene(key); - this.scenes.splice(index, 1); - this.scenes.push(scene); - } - } +/***/ }), - return this; - }, +/***/ 56088: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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 {this} This Scene Manager instance. - */ - sendToBack: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'sendToBack', keyA: key, keyB: null }); - } - else - { - var index = this.getIndex(key); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (index !== -1 && index > 0) - { - var scene = this.getScene(key); +var Point = __webpack_require__(79967); +var Length = __webpack_require__(16028); - this.scenes.splice(index, 1); - this.scenes.unshift(scene); - } - } +/** + * 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(); } - return this; - }, + var line1 = triangle.getLineA(); + var line2 = triangle.getLineB(); + var line3 = triangle.getLineC(); - /** - * 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 {this} This Scene Manager instance. - */ - moveDown: function (key) + if (position <= 0 || position >= 1) { - 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); + out.x = line1.x1; + out.y = line1.y1; - this.scenes[indexA] = sceneB; - this.scenes[indexB] = sceneA; - } - } + return out; + } - return this; - }, + var length1 = Length(line1); + var length2 = Length(line2); + var length3 = Length(line3); - /** - * 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 {this} This Scene Manager instance. - */ - moveUp: function (key) - { - if (this.isProcessing) - { - this._queue.push({ op: 'moveUp', keyA: key, keyB: null }); - } - else - { - var indexA = this.getIndex(key); + var perimeter = length1 + length2 + length3; - if (indexA < this.scenes.length - 1) - { - var indexB = indexA + 1; - var sceneA = this.getScene(key); - var sceneB = this.getAt(indexB); + var p = perimeter * position; + var localPosition = 0; - this.scenes[indexA] = sceneB; - this.scenes[indexB] = sceneA; - } - } + // Which line is it on? - return this; - }, + if (p < length1) + { + // Line 1 + localPosition = p / length1; - /** - * 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 {this} This Scene Manager instance. - */ - moveAbove: function (keyA, keyB) + out.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; + out.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; + } + else if (p > length1 + length2) { - if (keyA === keyB) - { - return this; - } + // Line 3 + p -= length1 + length2; + localPosition = p / length3; - if (this.isProcessing) - { - this._queue.push({ op: 'moveAbove', keyA: keyA, keyB: keyB }); - } - else - { - var indexA = this.getIndex(keyA); - var indexB = this.getIndex(keyB); + 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; - if (indexA !== -1 && indexB !== -1) - { - var tempScene = this.getAt(indexB); + out.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; + out.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; + } - // Remove - this.scenes.splice(indexB, 1); + return out; +}; - // Add in new location - this.scenes.splice(indexA + 1, 0, tempScene); - } - } +module.exports = GetPoint; - 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 {this} This Scene Manager instance. - */ - 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); +/***/ 24402: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (indexA !== -1 && indexB !== -1) - { - var tempScene = this.getAt(indexB); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Remove - this.scenes.splice(indexB, 1); +var Length = __webpack_require__(16028); +var Point = __webpack_require__(79967); - if (indexA === 0) - { - this.scenes.unshift(tempScene); - } - else - { - // Add in new location - this.scenes.splice(indexA, 0, tempScene); - } - } - } +/** + * 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 = []; } - return this; - }, + var line1 = triangle.getLineA(); + var line2 = triangle.getLineB(); + var line3 = triangle.getLineC(); - /** - * 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 {this} This Scene Manager instance. - */ - queueOp: function (op, keyA, keyB) - { - this._queue.push({ op: op, keyA: keyA, keyB: keyB }); + var length1 = Length(line1); + var length2 = Length(line2); + var length3 = Length(line3); - return this; - }, + var perimeter = length1 + length2 + length3; - /** - * 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 {this} This Scene Manager instance. - */ - swapPosition: function (keyA, keyB) + // If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. + if (!quantity && stepRate > 0) { - 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); + quantity = perimeter / stepRate; + } - this.scenes[indexA] = this.scenes[indexB]; - this.scenes[indexB] = tempScene; - } - } + for (var i = 0; i < quantity; i++) + { + var p = perimeter * (i / quantity); + var localPosition = 0; - return this; - }, + var point = new Point(); - /** - * 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' ]; + // Which line is it on? - for (var i = 0; i < this.scenes.length; i++) + if (p < length1) { - 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] + ')'; + // Line 1 + localPosition = p / length1; - out.push(key); + point.x = line1.x1 + (line1.x2 - line1.x1) * localPosition; + point.y = line1.y1 + (line1.y2 - line1.y1) * localPosition; } - - console.log(out.join('\n')); - }, - - /** - * Destroy this Scene Manager and all of its systems. - * - * This process cannot be reversed. - * - * This method is called automatically when a Phaser Game instance is destroyed. - * - * @method Phaser.Scenes.SceneManager#destroy - * @since 3.0.0 - */ - destroy: function () - { - for (var i = 0; i < this.scenes.length; i++) + else if (p > length1 + length2) { - var sys = this.scenes[i].sys; + // Line 3 + p -= length1 + length2; + localPosition = p / length3; - sys.destroy(); + 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; - this.update = NOOP; - - this.scenes = []; - - this._pending = []; - this._start = []; - this._queue = []; + point.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; + point.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; + } - this.game = null; + out.push(point); } -}); + return out; +}; -module.exports = SceneManager; +module.exports = GetPoints; /***/ }), -/* 418 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 83648: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Systems = __webpack_require__(204); +var Point = __webpack_require__(79967); + +// 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); +} /** - * @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()}. + * 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. * - * @class Scene - * @memberof Phaser - * @constructor + * @function Phaser.Geom.Triangle.InCenter * @since 3.0.0 * - * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - Scene specific configuration settings. + * @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 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; +var InCenter = function (triangle, out) +{ + if (out === undefined) { out = new Point(); } - /** - * 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; + var x1 = triangle.x1; + var y1 = triangle.y1; - /** - * A reference to the global 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; + var x2 = triangle.x2; + var y2 = triangle.y2; - /** - * 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.NoAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager)} - * @since 3.0.0 - */ - this.sound; + var x3 = triangle.x3; + var y3 = triangle.y3; - /** - * 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; + var d1 = getLength(x3, y3, x2, y2); + var d2 = getLength(x1, y1, x3, y3); + var d3 = getLength(x2, y2, x1, y1); - /** - * A Scene specific 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; + var p = d1 + d2 + d3; - /** - * The Scene Camera Manager. - * - * 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; + out.x = (x1 * d1 + x2 * d2 + x3 * d3) / p; + out.y = (y1 * d1 + y2 * d2 + y3 * d3) / p; - /** - * The Scene 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; + return out; +}; - /** - * The Scene 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; +module.exports = InCenter; - /** - * 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; - /** - * The Game Object Display List belonging to this Scene. - * - * 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; +/***/ }), - /** - * The Scene 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; +/***/ 9640: +/***/ ((module) => { - /** - * A Scene specific Data Manager Plugin. - * - * See the `registry` property for the global Data Manager. - * - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The Scene 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; +/** + * 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; - /** - * The Scene 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; + triangle.x2 += x; + triangle.y2 += y; - /** - * The Scene 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; + triangle.x3 += x; + triangle.y3 += y; - /** - * The Scene 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; + return triangle; +}; - /** - * The Scene 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; +module.exports = Offset; - /** - * The Scene 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; +/***/ 95290: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A reference to the global 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A reference to the renderer instance Phaser is using, either Canvas Renderer or WebGL Renderer. - * - * @name Phaser.Scene#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.50.0 - */ - this.renderer; - }, +var Length = __webpack_require__(16028); - /** - * This method 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 () - { - } +/** + * Gets the length of the perimeter of the given triangle. + * Calculated by adding together the length of each of the three sides. + * + * @function Phaser.Geom.Triangle.Perimeter + * @since 3.0.0 + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the length from. + * + * @return {number} The length of the Triangle. + */ +var Perimeter = function (triangle) +{ + var line1 = triangle.getLineA(); + var line2 = triangle.getLineB(); + var line3 = triangle.getLineC(); -}); + return (Length(line1) + Length(line2) + Length(line3)); +}; -module.exports = Scene; +module.exports = Perimeter; /***/ }), -/* 419 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 99761: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetFastValue = __webpack_require__(2); -var UppercaseFirst = __webpack_require__(205); +var Point = __webpack_require__(79967); /** - * Builds an array of which physics plugins should be activated for the given Scene. + * Returns a random Point from within the area of the given Triangle. * - * @function Phaser.Scenes.GetPhysicsPlugins + * @function Phaser.Geom.Triangle.Random * @since 3.0.0 * - * @param {Phaser.Scenes.Systems} sys - The scene system to get the physics systems of. + * @generic {Phaser.Geom.Point} O - [out,$return] * - * @return {array} An array of Physics systems to start for this Scene. + * @param {Phaser.Geom.Triangle} triangle - The Triangle to get a random point from. + * @param {Phaser.Geom.Point} [out] - The Point object to store the position in. If not given, a new Point instance is created. + * + * @return {Phaser.Geom.Point} A Point object holding the coordinates of a random position within the Triangle. */ -var GetPhysicsPlugins = function (sys) +var Random = function (triangle, out) { - var defaultSystem = sys.game.config.defaultPhysicsSystem; - var sceneSystems = GetFastValue(sys.settings, 'physics', false); + if (out === undefined) { out = new Point(); } - if (!defaultSystem && !sceneSystems) - { - // No default physics system or systems in this scene - return; - } + // Basis vectors + var ux = triangle.x2 - triangle.x1; + var uy = triangle.y2 - triangle.y1; - // Let's build the systems array - var output = []; + var vx = triangle.x3 - triangle.x1; + var vy = triangle.y3 - triangle.y1; - if (defaultSystem) - { - output.push(UppercaseFirst(defaultSystem + 'Physics')); - } + // Random point within the unit square + var r = Math.random(); + var s = Math.random(); - if (sceneSystems) + // Point outside the triangle? Remap it. + if (r + s >= 1) { - for (var key in sceneSystems) - { - key = UppercaseFirst(key.concat('Physics')); - - if (output.indexOf(key) === -1) - { - output.push(key); - } - } + r = 1 - r; + s = 1 - s; } - // An array of Physics systems to start for this Scene - return output; + out.x = triangle.x1 + ((ux * r) + (vx * s)); + out.y = triangle.y1 + ((uy * r) + (vy * s)); + + return out; }; -module.exports = GetPhysicsPlugins; +module.exports = Random; /***/ }), -/* 420 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 21934: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetFastValue = __webpack_require__(2); +var RotateAroundXY = __webpack_require__(19211); +var InCenter = __webpack_require__(83648); /** - * Builds an array of which plugins (not including physics plugins) should be activated for the given Scene. + * Rotates a Triangle about its incenter, which is the point at which its three angle bisectors meet. * - * @function Phaser.Scenes.GetScenePlugins + * @function Phaser.Geom.Triangle.Rotate * @since 3.0.0 * - * @param {Phaser.Scenes.Systems} sys - The Scene Systems object to check for plugins. + * @generic {Phaser.Geom.Triangle} O - [triangle,$return] * - * @return {array} An array of all plugins which should be activated, either the default ones or the ones configured in the Scene Systems object. + * @param {Phaser.Geom.Triangle} triangle - The Triangle to rotate. + * @param {number} angle - The angle by which to rotate the Triangle, in radians. + * + * @return {Phaser.Geom.Triangle} The rotated Triangle. */ -var GetScenePlugins = function (sys) +var Rotate = function (triangle, angle) { - var defaultPlugins = sys.plugins.getDefaultScenePlugins(); - - var scenePlugins = GetFastValue(sys.settings, 'plugins', false); + var point = InCenter(triangle); - // 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 []; - } + return RotateAroundXY(triangle, point.x, point.y, angle); }; -module.exports = GetScenePlugins; +module.exports = Rotate; /***/ }), -/* 421 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 68454: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(144); -var GetValue = __webpack_require__(6); -var Merge = __webpack_require__(127); -var InjectionMap = __webpack_require__(978); +var RotateAroundXY = __webpack_require__(19211); /** - * @namespace Phaser.Scenes.Settings + * Rotates a Triangle at a certain angle about a given Point or object with public `x` and `y` properties. + * + * @function Phaser.Geom.Triangle.RotateAroundPoint + * @since 3.0.0 + * + * @generic {Phaser.Geom.Triangle} O - [triangle,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to rotate. + * @param {Phaser.Geom.Point} point - The Point to rotate the Triangle about. + * @param {number} angle - The angle by which to rotate the Triangle, in radians. + * + * @return {Phaser.Geom.Triangle} The rotated Triangle. */ +var RotateAroundPoint = function (triangle, point, angle) +{ + return RotateAroundXY(triangle, point.x, point.y, angle); +}; -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), +module.exports = RotateAroundPoint; - // Scene Property Injection Map - map: GetValue(config, 'map', Merge(InjectionMap, GetValue(config, 'mapAdd', {}))), +/***/ }), - // Physics +/***/ 19211: +/***/ ((module) => { - physics: GetValue(config, 'physics', {}), +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Loader +/** + * Rotates an entire Triangle at a given angle about a specific point. + * + * @function Phaser.Geom.Triangle.RotateAroundXY + * @since 3.0.0 + * + * @generic {Phaser.Geom.Triangle} O - [triangle,$return] + * + * @param {Phaser.Geom.Triangle} triangle - The Triangle to rotate. + * @param {number} x - The X coordinate of the point to rotate the Triangle about. + * @param {number} y - The Y coordinate of the point to rotate the Triangle about. + * @param {number} angle - The angle by which to rotate the Triangle, in radians. + * + * @return {Phaser.Geom.Triangle} The rotated Triangle. + */ +var RotateAroundXY = function (triangle, x, y, angle) +{ + var c = Math.cos(angle); + var s = Math.sin(angle); - loader: GetValue(config, 'loader', {}), + var tx = triangle.x1 - x; + var ty = triangle.y1 - y; - // Plugins + triangle.x1 = tx * c - ty * s + x; + triangle.y1 = tx * s + ty * c + y; - plugins: GetValue(config, 'plugins', false), + tx = triangle.x2 - x; + ty = triangle.y2 - y; - // Input + triangle.x2 = tx * c - ty * s + x; + triangle.y2 = tx * s + ty * c + y; - input: GetValue(config, 'input', {}) + tx = triangle.x3 - x; + ty = triangle.y3 - y; - }; - } + triangle.x3 = tx * c - ty * s + x; + triangle.y3 = tx * s + ty * c + y; + return triangle; }; -module.exports = Settings; +module.exports = RotateAroundXY; /***/ }), -/* 422 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 66349: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CanvasPool = __webpack_require__(31); -var CanvasTexture = __webpack_require__(423); -var Class = __webpack_require__(0); -var Color = __webpack_require__(38); -var CONST = __webpack_require__(33); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(106); -var GameEvents = __webpack_require__(22); -var GenerateTexture = __webpack_require__(388); -var GetValue = __webpack_require__(6); -var Parser = __webpack_require__(425); -var Texture = __webpack_require__(206); - -/** - * @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. - */ +var Class = __webpack_require__(56694); +var Contains = __webpack_require__(60689); +var GetPoint = __webpack_require__(56088); +var GetPoints = __webpack_require__(24402); +var GEOM_CONST = __webpack_require__(52394); +var Line = __webpack_require__(88829); +var Random = __webpack_require__(99761); /** * @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`. + * A triangle is a plane created by connecting three points. + * The first two arguments specify the first point, the middle two arguments + * specify the second point, and the last two arguments specify the third point. * - * @class TextureManager - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Textures + * @class Triangle + * @memberof Phaser.Geom * @constructor * @since 3.0.0 * - * @param {Phaser.Game} game - The Phaser.Game instance this Texture Manager belongs to. + * @param {number} [x1=0] - `x` coordinate of the first point. + * @param {number} [y1=0] - `y` coordinate of the first point. + * @param {number} [x2=0] - `x` coordinate of the second point. + * @param {number} [y2=0] - `y` coordinate of the second point. + * @param {number} [x3=0] - `x` coordinate of the third point. + * @param {number} [y3=0] - `y` coordinate of the third point. */ -var TextureManager = new Class({ - - Extends: EventEmitter, +var Triangle = new Class({ initialize: - function TextureManager (game) + function Triangle (x1, y1, x2, y2, x3, y3) { - EventEmitter.call(this); + if (x1 === undefined) { x1 = 0; } + if (y1 === undefined) { y1 = 0; } + if (x2 === undefined) { x2 = 0; } + if (y2 === undefined) { y2 = 0; } + if (x3 === undefined) { x3 = 0; } + if (y3 === undefined) { y3 = 0; } /** - * The Game that this TextureManager belongs to. + * The geometry constant type of this object: `GEOM_CONST.TRIANGLE`. + * Used for fast type comparisons. * - * @name Phaser.Textures.TextureManager#game - * @type {Phaser.Game} - * @since 3.0.0 + * @name Phaser.Geom.Triangle#type + * @type {number} + * @readonly + * @since 3.19.0 */ - this.game = game; + this.type = GEOM_CONST.TRIANGLE; /** - * The name of this manager. + * `x` coordinate of the first point. * - * @name Phaser.Textures.TextureManager#name - * @type {string} + * @name Phaser.Geom.Triangle#x1 + * @type {number} + * @default 0 * @since 3.0.0 */ - this.name = 'TextureManager'; + this.x1 = x1; /** - * 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. + * `y` coordinate of the first point. * - * @name Phaser.Textures.TextureManager#list - * @type {object} - * @default {} + * @name Phaser.Geom.Triangle#y1 + * @type {number} + * @default 0 * @since 3.0.0 */ - this.list = {}; + this.y1 = y1; /** - * The temporary canvas element to save an pixel data of an arbitrary texture in getPixel() and getPixelAlpha() method. + * `x` coordinate of the second point. * - * @name Phaser.Textures.TextureManager#_tempCanvas - * @type {HTMLCanvasElement} - * @private + * @name Phaser.Geom.Triangle#x2 + * @type {number} + * @default 0 * @since 3.0.0 */ - this._tempCanvas = CanvasPool.create2D(this, 1, 1); + this.x2 = x2; /** - * The context of the temporary canvas element made to save an pixel data in getPixel() and getPixelAlpha() method. + * `y` coordinate of the second point. * - * @name Phaser.Textures.TextureManager#_tempContext - * @type {CanvasRenderingContext2D} - * @private + * @name Phaser.Geom.Triangle#y2 + * @type {number} + * @default 0 * @since 3.0.0 */ - this._tempContext = this._tempCanvas.getContext('2d'); + this.y2 = y2; /** - * An counting value used for emitting 'ready' event after all of managers in game is loaded. + * `x` coordinate of the third point. * - * @name Phaser.Textures.TextureManager#_pending + * @name Phaser.Geom.Triangle#x3 * @type {number} - * @private * @default 0 * @since 3.0.0 */ - this._pending = 0; + this.x3 = x3; - game.events.once(GameEvents.BOOT, this.boot, this); + /** + * `y` coordinate of the third point. + * + * @name Phaser.Geom.Triangle#y3 + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.y3 = y3; }, /** - * The Boot Handler called by Phaser.Game when it first starts up. + * Checks whether a given points lies within the triangle. * - * @method Phaser.Textures.TextureManager#boot - * @private + * @method Phaser.Geom.Triangle#contains * @since 3.0.0 + * + * @param {number} x - The x coordinate of the point to check. + * @param {number} y - The y coordinate of the point to check. + * + * @return {boolean} `true` if the coordinate pair is within the triangle, otherwise `false`. */ - boot: function () + contains: function (x, y) { - this._pending = 3; - - 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.game.events.once(GameEvents.DESTROY, this.destroy, this); + return Contains(this, x, y); }, /** - * After 'onload' or 'onerror' invoked twice, emit 'ready' event. + * Returns a specific point on the triangle. * - * @method Phaser.Textures.TextureManager#updatePending - * @private + * @method Phaser.Geom.Triangle#getPoint * @since 3.0.0 + * + * @generic {Phaser.Geom.Point} O - [output,$return] + * + * @param {number} position - Position as float within `0` and `1`. `0` equals the first point. + * @param {(Phaser.Geom.Point|object)} [output] - Optional Point, or point-like object, that the calculated point will be written to. + * + * @return {(Phaser.Geom.Point|object)} Calculated `Point` that represents the requested position. It is the same as `output` when this parameter has been given. */ - updatePending: function () + getPoint: function (position, output) { - this._pending--; - - if (this._pending === 0) - { - this.off(Events.LOAD); - this.off(Events.ERROR); - - this.emit(Events.READY); - } + return GetPoint(this, position, output); }, /** - * 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. + * Calculates a list of evenly distributed points on the triangle. It is either possible to pass an amount of points to be generated (`quantity`) or the distance between two points (`stepRate`). * - * @method Phaser.Textures.TextureManager#checkKey - * @since 3.7.0 + * @method Phaser.Geom.Triangle#getPoints + * @since 3.0.0 * - * @param {string} key - The texture key to check. + * @generic {Phaser.Geom.Point[]} O - [output,$return] * - * @return {boolean} `true` if it's safe to use the texture key, otherwise `false`. + * @param {number} quantity - Number of points to be generated. Can be falsey when `stepRate` should be used. All points have the same distance along the triangle. + * @param {number} [stepRate] - Distance between two points. Will only be used when `quantity` is falsey. + * @param {(array|Phaser.Geom.Point[])} [output] - Optional Array for writing the calculated points into. Otherwise a new array will be created. + * + * @return {(array|Phaser.Geom.Point[])} Returns a list of calculated `Point` instances or the filled array passed as parameter `output`. */ - checkKey: function (key) + getPoints: function (quantity, stepRate, output) { - if (this.exists(key)) - { - // eslint-disable-next-line no-console - console.error('Texture key already in use: ' + key); - - return false; - } - - return true; + return GetPoints(this, quantity, stepRate, output); }, /** - * 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. + * Returns a random point along the triangle. * - * 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.Geom.Triangle#getRandomPoint + * @since 3.0.0 * - * @method Phaser.Textures.TextureManager#remove - * @fires Phaser.Textures.Events#REMOVE - * @since 3.7.0 + * @generic {Phaser.Geom.Point} O - [point,$return] * - * @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. + * @param {Phaser.Geom.Point} [point] - Optional `Point` that should be modified. Otherwise a new one will be created. * - * @return {Phaser.Textures.TextureManager} The Texture Manager. + * @return {Phaser.Geom.Point} Random `Point`. When parameter `point` has been provided it will be returned. */ - removeKey: function (key) + getRandomPoint: function (point) { - if (this.list.hasOwnProperty(key)) - { - delete this.list[key]; - } - - return this; + return Random(this, point); }, /** - * 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. + * Sets all three points of the triangle. Leaving out any coordinate sets it to be `0`. * - * @method Phaser.Textures.TextureManager#addBase64 - * @fires Phaser.Textures.Events#ADD - * @fires Phaser.Textures.Events#ERROR - * @fires Phaser.Textures.Events#LOAD + * @method Phaser.Geom.Triangle#setTo * @since 3.0.0 * - * @param {string} key - The unique string-based key of the Texture. - * @param {*} data - The Base64 encoded data. + * @param {number} [x1=0] - `x` coordinate of the first point. + * @param {number} [y1=0] - `y` coordinate of the first point. + * @param {number} [x2=0] - `x` coordinate of the second point. + * @param {number} [y2=0] - `y` coordinate of the second point. + * @param {number} [x3=0] - `x` coordinate of the third point. + * @param {number} [y3=0] - `y` coordinate of the third point. * - * @return {this} This Texture Manager instance. + * @return {this} This Triangle object. */ - addBase64: function (key, data) + setTo: function (x1, y1, x2, y2, x3, y3) { - 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); + if (x1 === undefined) { x1 = 0; } + if (y1 === undefined) { y1 = 0; } + if (x2 === undefined) { x2 = 0; } + if (y2 === undefined) { y2 = 0; } + if (x3 === undefined) { x3 = 0; } + if (y3 === undefined) { y3 = 0; } - _this.emit(Events.ADD, key, texture); + this.x1 = x1; + this.y1 = y1; - _this.emit(Events.LOAD, key, texture); - }; + this.x2 = x2; + this.y2 = y2; - image.src = data; - } + this.x3 = x3; + this.y3 = y3; 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. + * Returns a Line object that corresponds to Line A of this Triangle. * - * 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.Geom.Triangle#getLineA + * @since 3.0.0 * - * @method Phaser.Textures.TextureManager#getBase64 - * @since 3.12.0 + * @generic {Phaser.Geom.Line} O - [line,$return] * - * @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. + * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. * - * @return {string} The base64 encoded data, or an empty string if the texture frame could not be found. + * @return {Phaser.Geom.Line} A Line object that corresponds to line A of this Triangle. */ - getBase64: function (key, frame, type, encoderOptions) + getLineA: function (line) { - 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); + if (line === undefined) { line = new Line(); } - CanvasPool.remove(canvas); - } + line.setTo(this.x1, this.y1, this.x2, this.y2); - return data; + return line; }, /** - * Adds a new Texture to the Texture Manager created from the given Image element. + * Returns a Line object that corresponds to Line B of this Triangle. * - * @method Phaser.Textures.TextureManager#addImage - * @fires Phaser.Textures.Events#ADD + * @method Phaser.Geom.Triangle#getLineB * @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 + * @generic {Phaser.Geom.Line} O - [line,$return] * - * @param {string} key - The unique string-based key of the Texture. - * @param {Phaser.GameObjects.RenderTexture} renderTexture - The source Render Texture. + * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + * @return {Phaser.Geom.Line} A Line object that corresponds to line B of this Triangle. */ - addRenderTexture: function (key, renderTexture) + getLineB: function (line) { - var texture = null; - - if (this.checkKey(key)) - { - texture = this.create(key, renderTexture); - - texture.add('__BASE', 0, 0, 0, renderTexture.width, renderTexture.height); + if (line === undefined) { line = new Line(); } - this.emit(Events.ADD, key, texture); - } + line.setTo(this.x2, this.y2, this.x3, this.y3); - return texture; + return line; }, /** - * 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. + * Returns a Line object that corresponds to Line C of this Triangle. * - * @method Phaser.Textures.TextureManager#generate + * @method Phaser.Geom.Triangle#getLineC * @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 + * @generic {Phaser.Geom.Line} O - [line,$return] * - * @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. + * @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created. * - * @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use. + * @return {Phaser.Geom.Line} A Line object that corresponds to line C of this Triangle. */ - createCanvas: function (key, width, height) + getLineC: function (line) { - if (width === undefined) { width = 256; } - if (height === undefined) { height = 256; } - - if (this.checkKey(key)) - { - var canvas = CanvasPool.create(this, width, height, CONST.CANVAS, true); + if (line === undefined) { line = new Line(); } - return this.addCanvas(key, canvas); - } + line.setTo(this.x3, this.y3, this.x1, this.y1); - return null; + return line; }, /** - * Creates a new Canvas Texture object from an existing Canvas element - * and adds it to this Texture Manager, unless `skipCache` is true. + * Left most X coordinate of the triangle. Setting it moves the triangle on the X axis accordingly. * - * @method Phaser.Textures.TextureManager#addCanvas - * @fires Phaser.Textures.Events#ADD + * @name Phaser.Geom.Triangle#left + * @type {number} * @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; - }, + left: { - /** - * 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 + get: function () { - 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; + return Math.min(this.x1, this.x2, this.x3); + }, - if (this.checkKey(key)) + set: function (value) { - texture = this.create(key, source); + var diff = 0; - // Multi-Atlas? - if (Array.isArray(data)) + if (this.x1 <= this.x2 && this.x1 <= this.x3) { - 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); - } + diff = this.x1 - value; } - else + else if (this.x2 <= this.x1 && this.x2 <= this.x3) { - Parser.JSONArray(texture, 0, data); + diff = this.x2 - value; } - - if (dataSource) + else { - texture.setDataSource(dataSource); + diff = this.x3 - value; } - this.emit(Events.ADD, key, texture); + this.x1 -= diff; + this.x2 -= diff; + this.x3 -= diff; } - 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. + * Right most X coordinate of the triangle. Setting it moves the triangle on the X axis accordingly. * - * @method Phaser.Textures.TextureManager#addAtlasJSONHash - * @fires Phaser.Textures.Events#ADD + * @name Phaser.Geom.Triangle#right + * @type {number} * @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; + right: { - if (this.checkKey(key)) + get: function () { - texture = this.create(key, source); + return Math.max(this.x1, this.x2, this.x3); + }, - if (Array.isArray(data)) + set: function (value) + { + var diff = 0; + + if (this.x1 >= this.x2 && this.x1 >= this.x3) { - for (var i = 0; i < data.length; i++) - { - Parser.JSONHash(texture, i, data[i]); - } + diff = this.x1 - value; } - else + else if (this.x2 >= this.x1 && this.x2 >= this.x3) { - Parser.JSONHash(texture, 0, data); + diff = this.x2 - value; } - - if (dataSource) + else { - texture.setDataSource(dataSource); + diff = this.x3 - value; } - this.emit(Events.ADD, key, texture); + this.x1 -= diff; + this.x2 -= diff; + this.x3 -= diff; } - 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. + * Top most Y coordinate of the triangle. Setting it moves the triangle on the Y axis accordingly. * - * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + * @name Phaser.Geom.Triangle#top + * @type {number} + * @since 3.0.0 */ - addAtlasXML: function (key, source, data, dataSource) - { - var texture = null; + top: { - if (this.checkKey(key)) + get: function () { - texture = this.create(key, source); + return Math.min(this.y1, this.y2, this.y3); + }, - Parser.AtlasXML(texture, 0, data); + set: function (value) + { + var diff = 0; - if (dataSource) + if (this.y1 <= this.y2 && this.y1 <= this.y3) { - texture.setDataSource(dataSource); + diff = this.y1 - value; } - - 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) + else if (this.y2 <= this.y1 && this.y2 <= this.y3) { - texture.setDataSource(dataSource); + diff = this.y2 - value; + } + else + { + diff = this.y3 - value; } - 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); + this.y1 -= diff; + this.y2 -= diff; + this.y3 -= diff; } - 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. + * Bottom most Y coordinate of the triangle. Setting it moves the triangle on the Y axis accordingly. * - * @method Phaser.Textures.TextureManager#addSpriteSheetFromAtlas - * @fires Phaser.Textures.Events#ADD + * @name Phaser.Geom.Triangle#bottom + * @type {number} * @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); + bottom: { - if (!atlasKey || !atlasFrame) + get: function () { - return; - } - - var atlas = this.get(atlasKey); - var sheet = atlas.get(atlasFrame); + return Math.max(this.y1, this.y2, this.y3); + }, - if (sheet) + set: function (value) { - var texture = this.create(key, sheet.source.image); + var diff = 0; - if (sheet.trimmed) + if (this.y1 >= this.y2 && this.y1 >= this.y3) { - // If trimmed we need to help the parser adjust - Parser.SpriteSheetFromAtlas(texture, sheet, config); + diff = this.y1 - value; + } + else if (this.y2 >= this.y1 && this.y2 >= this.y3) + { + diff = this.y2 - value; } else { - Parser.SpriteSheet(texture, 0, sheet.cutX, sheet.cutY, sheet.cutWidth, sheet.cutHeight, config); + diff = this.y3 - value; } - this.emit(Events.ADD, key, texture); - - return texture; + this.y1 -= diff; + this.y2 -= diff; + this.y3 -= diff; } - }, - - /** - * 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; - }, +module.exports = Triangle; - /** - * 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']; - } - }, +/***/ 87619: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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(); - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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); - } - }, +var Triangle = __webpack_require__(66349); - /** - * 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 = []; +Triangle.Area = __webpack_require__(19108); +Triangle.BuildEquilateral = __webpack_require__(41199); +Triangle.BuildFromPolygon = __webpack_require__(88730); +Triangle.BuildRight = __webpack_require__(3635); +Triangle.CenterOn = __webpack_require__(1882); +Triangle.Centroid = __webpack_require__(56595); +Triangle.CircumCenter = __webpack_require__(91835); +Triangle.CircumCircle = __webpack_require__(97073); +Triangle.Clone = __webpack_require__(75974); +Triangle.Contains = __webpack_require__(60689); +Triangle.ContainsArray = __webpack_require__(86875); +Triangle.ContainsPoint = __webpack_require__(51532); +Triangle.CopyFrom = __webpack_require__(42538); +Triangle.Decompose = __webpack_require__(18680); +Triangle.Equals = __webpack_require__(29977); +Triangle.GetPoint = __webpack_require__(56088); +Triangle.GetPoints = __webpack_require__(24402); +Triangle.InCenter = __webpack_require__(83648); +Triangle.Perimeter = __webpack_require__(95290); +Triangle.Offset = __webpack_require__(9640); +Triangle.Random = __webpack_require__(99761); +Triangle.Rotate = __webpack_require__(21934); +Triangle.RotateAroundPoint = __webpack_require__(68454); +Triangle.RotateAroundXY = __webpack_require__(19211); - for (var key in this.list) - { - if (key !== '__DEFAULT' && key !== '__MISSING') - { - output.push(key); - } - } +module.exports = Triangle; - 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; +/***/ 27395: +/***/ ((module) => { - var data = textureFrame.data.cut; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - x += data.x; - y += data.y; +/** + * 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 { - if (x >= data.x && x < data.r && y >= data.y && y < data.b) - { - var ctx = this._tempContext; + gameObject: gameObject, - ctx.clearRect(0, 0, 1, 1); - ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); + enabled: true, + draggable: false, + dropZone: false, + cursor: false, - var rgb = ctx.getImageData(0, 0, 1, 1); + target: null, - return new Color(rgb.data[0], rgb.data[1], rgb.data[2], rgb.data[3]); - } - } + camera: null, - return null; - }, + hitArea: hitArea, + hitAreaCallback: hitAreaCallback, + hitAreaDebug: 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); + // Has the dev specified their own shape, or is this bound to the texture size? + customHitArea: false, - if (textureFrame) - { - // Adjust for trim (if not trimmed x and y are just zero) - x -= textureFrame.x; - y -= textureFrame.y; + localX: 0, + localY: 0, - var data = textureFrame.data.cut; + // 0 = Not being dragged + // 1 = Being checked for dragging + // 2 = Being dragged + dragState: 0, - x += data.x; - y += data.y; + dragStartX: 0, + dragStartY: 0, + dragStartXGlobal: 0, + dragStartYGlobal: 0, - if (x >= data.x && x < data.r && y >= data.y && y < data.b) - { - var ctx = this._tempContext; + dragX: 0, + dragY: 0 - 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); +module.exports = CreateInteractiveObject; - 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); - } +/***/ 18104: +/***/ ((module) => { - return gameObject; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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) +/** + * 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 texture = this.get(currentKey); - - if (texture && currentKey !== newKey) - { - texture.key = newKey; + var alpha = textureManager.getPixelAlpha(x, y, gameObject.texture.key, gameObject.frame.name); - this.list[newKey] = texture; + return (alpha && alpha >= alphaTolerance); + }; +}; - delete this.list[currentKey]; +module.exports = CreatePixelPerfectHandler; - 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 ]; +/***/ 69898: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (var i = 1; i < arguments.length; i++) - { - args.push(arguments[i]); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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; - - -/***/ }), -/* 423 */ -/***/ (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__(38); -var CONST = __webpack_require__(33); -var IsSizePowerOfTwo = __webpack_require__(138); -var Texture = __webpack_require__(206); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(72687); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(33963); +var GameEvents = __webpack_require__(97081); +var Keyboard = __webpack_require__(71064); +var Mouse = __webpack_require__(7905); +var Pointer = __webpack_require__(40398); +var Touch = __webpack_require__(37579); +var TransformMatrix = __webpack_require__(69360); +var TransformXY = __webpack_require__(64462); /** * @classdesc - * A Canvas Texture is a special kind of Texture that is backed by an HTML Canvas Element as its source. + * The Input Manager is responsible for handling the pointer related systems in a single Phaser Game instance. * - * 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. + * Based on the Game Config it will create handlers for mouse and touch support. * - * 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. + * Keyboard and Gamepad are plugins, handled directly by the InputPlugin class. * - * 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. + * It then manages the events, pointer creation and general hit test related operations. * - * 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. + * 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 CanvasTexture - * @extends Phaser.Textures.Texture - * @memberof Phaser.Textures + * @class InputManager + * @memberof Phaser.Input * @constructor - * @since 3.7.0 + * @since 3.0.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. + * @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 CanvasTexture = new Class({ - - Extends: Texture, +var InputManager = new Class({ initialize: - function CanvasTexture (manager, key, source, width, height) + function InputManager (game, config) { - Texture.call(this, manager, key, source, width, height); - - this.add('__BASE', 0, 0, 0, width, height); + /** + * 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 Texture Source of this Canvas. + * A reference to the global Game Scale Manager. + * Used for all bounds checks and pointer scaling. * - * @name Phaser.Textures.CanvasTexture#_source - * @type {Phaser.Textures.TextureSource} - * @private - * @since 3.7.0 + * @name Phaser.Input.InputManager#scaleManager + * @type {Phaser.Scale.ScaleManager} + * @since 3.16.0 */ - this._source = this.frames['__BASE'].source; + this.scaleManager; /** - * The source Canvas Element. + * The Canvas that is used for all DOM event input listeners. * - * @name Phaser.Textures.CanvasTexture#canvas - * @readonly + * @name Phaser.Input.InputManager#canvas * @type {HTMLCanvasElement} - * @since 3.7.0 + * @since 3.0.0 */ - this.canvas = this._source.image; + this.canvas; /** - * The 2D Canvas Rendering Context. + * The Game Configuration object, as set during the game boot. * - * @name Phaser.Textures.CanvasTexture#context - * @readonly - * @type {CanvasRenderingContext2D} - * @since 3.7.0 + * @name Phaser.Input.InputManager#config + * @type {Phaser.Core.Config} + * @since 3.0.0 */ - this.context = this.canvas.getContext('2d'); + this.config = config; /** - * The width of the Canvas. - * This property is read-only, if you wish to change it use the `setSize` method. + * If set, the Input Manager will run its update loop every frame. * - * @name Phaser.Textures.CanvasTexture#width - * @readonly - * @type {number} - * @since 3.7.0 + * @name Phaser.Input.InputManager#enabled + * @type {boolean} + * @default true + * @since 3.0.0 */ - this.width = width; + this.enabled = true; /** - * The height of the Canvas. - * This property is read-only, if you wish to change it use the `setSize` method. + * The Event Emitter instance that the Input Manager uses to emit events from. * - * @name Phaser.Textures.CanvasTexture#height + * @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 - * @type {number} - * @since 3.7.0 + * @since 3.16.0 */ - this.height = height; + this.isOver = true; /** - * The context image data. - * Use the `update` method to populate this when the canvas changes. + * The default CSS cursor to be used when interacting with your game. * - * @name Phaser.Textures.CanvasTexture#imageData - * @type {ImageData} - * @since 3.13.0 + * See the `setDefaultCursor` method for more details. + * + * @name Phaser.Input.InputManager#defaultCursor + * @type {string} + * @since 3.10.0 */ - this.imageData = this.context.getImageData(0, 0, width, height); + this.defaultCursor = ''; /** - * 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. + * A reference to the Keyboard Manager class, if enabled via the `input.keyboard` Game Config property. * - * @name Phaser.Textures.CanvasTexture#data - * @type {Uint8ClampedArray} - * @since 3.13.0 + * @name Phaser.Input.InputManager#keyboard + * @type {?Phaser.Input.Keyboard.KeyboardManager} + * @since 3.16.0 */ - this.data = null; + this.keyboard = (config.inputKeyboard) ? new Keyboard(this) : null; - if (this.imageData) - { - this.data = this.imageData.data; - } + /** + * 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; /** - * An Uint32Array view into the `buffer`. + * A reference to the Touch Manager class, if enabled via the `input.touch` Game Config property. * - * @name Phaser.Textures.CanvasTexture#pixels - * @type {Uint32Array} - * @since 3.13.0 + * @name Phaser.Input.InputManager#touch + * @type {Phaser.Input.Touch.TouchManager} + * @since 3.0.0 */ - this.pixels = null; + this.touch = (config.inputTouch) ? new Touch(this) : null; /** - * An ArrayBuffer the same size as the context ImageData. + * 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. * - * @name Phaser.Textures.CanvasTexture#buffer - * @type {ArrayBuffer} - * @since 3.13.0 + * 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.buffer; + this.pointers = []; - if (this.data) + /** + * 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) { - 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.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); }, /** - * 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 + * The Boot handler is called by Phaser.Game when it first starts up. + * The renderer is available by now. * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + * @method Phaser.Input.InputManager#boot + * @protected + * @fires Phaser.Input.Events#MANAGER_BOOT + * @since 3.0.0 */ - update: function () + boot: function () { - this.imageData = this.context.getImageData(0, 0, this.width, this.height); + var game = this.game; + var events = game.events; - this.data = this.imageData.data; + this.canvas = game.canvas; - 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.scaleManager = game.scale; - if (this.manager.game.config.renderType === CONST.WEBGL) - { - this.refresh(); - } + this.events.emit(Events.MANAGER_BOOT); - return this; + events.on(GameEvents.PRE_RENDER, this.preRender, this); + + events.once(GameEvents.DESTROY, this.destroy, 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 + * Internal canvas state change, called automatically by the Mouse Manager. * - * @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. + * @method Phaser.Input.InputManager#setCanvasOver + * @fires Phaser.Input.Events#GAME_OVER + * @private + * @since 3.16.0 * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + * @param {(MouseEvent|TouchEvent)} event - The DOM Event. */ - draw: function (x, y, source) + setCanvasOver: function (event) { - this.context.drawImage(source, x, y); + this.isOver = true; - return this.update(); + this.events.emit(Events.GAME_OVER, event); }, /** - * Draws the given texture frame to this CanvasTexture, then updates the internal - * ImageData buffer and arrays. + * Internal canvas state change, called automatically by the Mouse Manager. * - * @method Phaser.Textures.CanvasTexture#drawFrame + * @method Phaser.Input.InputManager#setCanvasOut + * @fires Phaser.Input.Events#GAME_OUT + * @private * @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. + * @param {(MouseEvent|TouchEvent)} event - The DOM Event. */ - drawFrame: function (key, frame, x, y) + setCanvasOut: function (event) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } + this.isOver = false; - var textureFrame = this.manager.getFrame(key, frame); + this.events.emit(Events.GAME_OUT, event); + }, - if (textureFrame) - { - var cd = textureFrame.canvasData; + /** + * 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); - var width = textureFrame.cutWidth; - var height = textureFrame.cutHeight; - var res = textureFrame.source.resolution; + this.time = time; - this.context.drawImage( - textureFrame.source.image, - cd.x, cd.y, - width, - height, - x, y, - width / res, - height / res - ); + this.events.emit(Events.MANAGER_UPDATE); - return this.update(); - } - else + for (var i = 0; i < scenes.length; i++) { - return this; + 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; + } } }, /** - * Sets a pixel in the CanvasTexture to the given color and alpha values. + * Tells the Input system to set a custom cursor. * - * This is an expensive operation to run in large quantities, so use sparingly. + * This cursor will be the default cursor used when interacting with the game canvas. * - * @method Phaser.Textures.CanvasTexture#setPixel - * @since 3.16.0 + * If an Interactive Object also sets a custom cursor, this is the cursor that is reset after its use. * - * @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. + * Any valid CSS cursor value is allowed, including paths to image files, i.e.: * - * @return {this} This CanvasTexture. + * ```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. */ - setPixel: function (x, y, red, green, blue, alpha) + setDefaultCursor: function (cursor) { - if (alpha === undefined) { alpha = 255; } - - x = Math.abs(Math.floor(x)); - y = Math.abs(Math.floor(y)); - - var index = this.getIndex(x, y); + this.defaultCursor = cursor; - if (index > -1) + if (this.canvas.style.cursor !== cursor) { - 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); + this.canvas.style.cursor = cursor; } - - return this; }, /** - * Puts the ImageData into the context of this CanvasTexture at the given coordinates. + * Called by the InputPlugin when processing over and out events. * - * @method Phaser.Textures.CanvasTexture#putData - * @since 3.16.0 + * Tells the Input Manager to set a custom cursor during its postUpdate step. * - * @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. + * https://developer.mozilla.org/en-US/docs/Web/CSS/cursor * - * @return {this} This CanvasTexture. + * @method Phaser.Input.InputManager#setCursor + * @private + * @since 3.10.0 + * + * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. */ - putData: function (imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) + setCursor: function (interactiveObject) { - 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; + if (interactiveObject.cursor) + { + this.canvas.style.cursor = interactiveObject.cursor; + } }, /** - * Gets an ImageData region from this CanvasTexture from the position and size specified. - * You can write this back using `CanvasTexture.putData`, or manipulate it. + * Called by the InputPlugin when processing over and out events. * - * @method Phaser.Textures.CanvasTexture#getData - * @since 3.16.0 + * Tells the Input Manager to clear the hand cursor, if set, during its postUpdate step. * - * @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. + * @method Phaser.Input.InputManager#resetCursor + * @private + * @since 3.10.0 * - * @return {ImageData} The ImageData extracted from this CanvasTexture. + * @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. */ - getData: function (x, y, width, height) + resetCursor: function (interactiveObject) { - 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; + if (interactiveObject.cursor && this.canvas) + { + this.canvas.style.cursor = this.defaultCursor; + } }, /** - * Get the color of a specific pixel from this texture and store it in a Color object. + * Adds new Pointer objects to the Input Manager. * - * 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. + * By default Phaser creates 2 pointer objects: `mousePointer` and `pointer1`. * - * @method Phaser.Textures.CanvasTexture#getPixel - * @since 3.13.0 + * 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. * - * @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. + * The first 10 pointers are available via the `InputPlugin.pointerX` properties, once they have been added + * via this method. * - * @return {Phaser.Display.Color} An object with the red, green, blue and alpha values set in the r, g, b and a properties. + * @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. */ - getPixel: function (x, y, out) + addPointer: function (quantity) { - if (!out) + if (quantity === undefined) { quantity = 1; } + + var output = []; + + if (this.pointersTotal + quantity > 10) { - out = new Color(); + quantity = 10 - this.pointersTotal; } - var index = this.getIndex(x, y); - - if (index > -1) + for (var i = 0; i < quantity; i++) { - var data = this.data; + var id = this.pointers.length; - var r = data[index + 0]; - var g = data[index + 1]; - var b = data[index + 2]; - var a = data[index + 3]; + var pointer = new Pointer(this, id); - out.setTo(r, g, b, a); + pointer.smoothFactor = this.config.inputSmoothFactor; + + this.pointers.push(pointer); + + this.pointersTotal++; + + output.push(pointer); } - return out; + return output; }, /** - * 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. + * 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.Textures.CanvasTexture#getPixels + * @method Phaser.Input.InputManager#updateInputPlugins * @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. + * @param {number} type - The type of event to process. + * @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred. */ - getPixels: function (x, y, width, height) + updateInputPlugins: function (type, pointers) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.width; } - if (height === undefined) { height = width; } + var scenes = this.game.scene.getScenes(false, true); - x = Math.abs(Math.round(x)); - y = Math.abs(Math.round(y)); + this._tempSkip = false; - 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); + for (var i = 0; i < scenes.length; i++) + { + var scene = scenes[i]; - var pixel = new Color(); + if (scene.sys.input) + { + var capture = scene.sys.input.update(type, pointers); - var out = []; + 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; + } + } + } + }, - for (var py = top; py < bottom; py++) + // 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 row = []; + var changedTouch = event.changedTouches[c]; - for (var px = left; px < right; px++) + for (var i = 1; i < this.pointersTotal; i++) { - pixel = this.getPixel(px, py, pixel); + var pointer = pointers[i]; - row.push({ x: px, y: py, color: pixel.color, alpha: pixel.alphaGL }); - } + if (!pointer.active) + { + pointer.touchstart(changedTouch, event); - out.push(row); + this.activePointer = pointer; + + changed.push(pointer); + + break; + } + } } - return out; + this.updateInputPlugins(CONST.TOUCH_START, changed); }, /** - * 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. + * Processes a touch move event, as passed in by the TouchManager. * - * The index points to the red value in the array. The subsequent 3 indexes - * point to green, blue and alpha respectively. + * @method Phaser.Input.InputManager#onTouchMove + * @private + * @since 3.18.0 * - * @method Phaser.Textures.CanvasTexture#getIndex - * @since 3.16.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) + { + var element = document.elementFromPoint(changedTouch.pageX, changedTouch.pageY); + var overCanvas = element === this.canvas; + + if (!this.isOver && overCanvas) + { + this.setCanvasOver(event); + } + else if (this.isOver && !overCanvas) + { + this.setCanvasOut(event); + } + + if (this.isOver) + { + 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. * - * @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. + * @method Phaser.Input.InputManager#onTouchEnd + * @private + * @since 3.18.0 * - * @return {number} + * @param {TouchEvent} event - The native DOM Touch event. */ - getIndex: function (x, y) + onTouchEnd: function (event) { - x = Math.abs(Math.round(x)); - y = Math.abs(Math.round(y)); + var pointers = this.pointers; + var changed = []; - if (x < this.width && y < this.height) + for (var c = 0; c < event.changedTouches.length; c++) { - return (x + y * this.width) * 4; + 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; + } + } } - else + + 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++) { - return -1; + 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); }, /** - * 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. + * Processes a mouse down event, as passed in by the MouseManager. * - * @method Phaser.Textures.CanvasTexture#refresh - * @since 3.7.0 + * @method Phaser.Input.InputManager#onMouseDown + * @private + * @since 3.18.0 * - * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. + * @param {MouseEvent} event - The native DOM Mouse event. */ - refresh: function () + onMouseDown: function (event) { - this._source.update(); + var mousePointer = this.mousePointer; - return this; + mousePointer.down(event); + + mousePointer.updateMotion(); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_DOWN, this.mousePointerContainer); }, /** - * Gets the Canvas Element. + * Processes a mouse move event, as passed in by the MouseManager. * - * @method Phaser.Textures.CanvasTexture#getCanvas - * @since 3.7.0 + * @method Phaser.Input.InputManager#onMouseMove + * @private + * @since 3.18.0 * - * @return {HTMLCanvasElement} The Canvas DOM element this texture is using. + * @param {MouseEvent} event - The native DOM Mouse event. */ - getCanvas: function () + onMouseMove: function (event) { - return this.canvas; + var mousePointer = this.mousePointer; + + mousePointer.move(event); + + mousePointer.updateMotion(); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_MOVE, this.mousePointerContainer); }, /** - * Gets the 2D Canvas Rendering Context. + * Processes a mouse up event, as passed in by the MouseManager. * - * @method Phaser.Textures.CanvasTexture#getContext - * @since 3.7.0 + * @method Phaser.Input.InputManager#onMouseUp + * @private + * @since 3.18.0 * - * @return {CanvasRenderingContext2D} The Canvas Rendering Context this texture is using. + * @param {MouseEvent} event - The native DOM Mouse event. */ - getContext: function () + onMouseUp: function (event) { - return this.context; + var mousePointer = this.mousePointer; + + mousePointer.up(event); + + mousePointer.updateMotion(); + + this.activePointer = mousePointer; + + this.updateInputPlugins(CONST.MOUSE_UP, this.mousePointerContainer); }, /** - * Clears the given region of this Canvas Texture, resetting it back to transparent. - * If no region is given, the whole Canvas Texture is cleared. + * Processes a mouse wheel event, as passed in by the MouseManager. * - * @method Phaser.Textures.CanvasTexture#clear - * @since 3.7.0 + * @method Phaser.Input.InputManager#onMouseWheel + * @private + * @since 3.18.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. + * @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. * - * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. + * @method Phaser.Input.InputManager#onPointerLockChange + * @fires Phaser.Input.Events#POINTERLOCK_CHANGE + * @private + * @since 3.19.0 + * + * @param {MouseEvent} event - The native DOM Mouse event. */ - clear: function (x, y, width, height) + onPointerLockChange: function (event) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.width; } - if (height === undefined) { height = this.height; } + var isLocked = this.mouse.locked; - this.context.clearRect(x, y, width, height); + this.mousePointer.locked = isLocked; - return this.update(); + this.events.emit(Events.POINTERLOCK_CHANGE, event, isLocked); }, /** - * Changes the size of this Canvas Texture. + * Checks if the given Game Object should be considered as a candidate for input or not. * - * @method Phaser.Textures.CanvasTexture#setSize - * @since 3.7.0 + * 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. * - * @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. + * @method Phaser.Input.InputManager#inputCandidate + * @private + * @since 3.10.0 * - * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. + * @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`. */ - setSize: function (width, height) + inputCandidate: function (gameObject, camera) { - if (height === undefined) { height = width; } + var input = gameObject.input; - if (width !== this.width || height !== this.height) + if (!input || !input.enabled || !gameObject.willRender(camera)) { - // Update the Canvas - this.canvas.width = width; - this.canvas.height = height; + return false; + } - // Update the Texture Source - this._source.width = width; - this._source.height = height; - this._source.isPowerOf2 = IsSizePowerOfTwo(width, height); + var visible = true; + var parent = gameObject.parentContainer; - // Update the Frame - this.frames['__BASE'].setSize(width, height, 0, 0); + if (parent) + { + do + { + if (!parent.willRender(camera)) + { + visible = false; + break; + } - // Update this - this.width = width; - this.height = height; + parent = parent.parentContainer; - this.refresh(); + } while (parent); } - return this; + return visible; }, /** - * Destroys this Texture and releases references to its sources and frames. + * Performs a hit test using the given Pointer and camera, against an array of interactive Game Objects. * - * @method Phaser.Textures.CanvasTexture#destroy - * @since 3.16.0 + * 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 () { - Texture.prototype.destroy.call(this); + this.events.removeAllListeners(); - this._source = null; + 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.context = null; - this.imageData = null; - this.data = null; - this.pixels = null; - this.buffer = null; + this.game = null; } }); -module.exports = CanvasTexture; +module.exports = InputManager; /***/ }), -/* 424 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 12499: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(138); -var ScaleModes = __webpack_require__(168); +var Circle = __webpack_require__(26673); +var CircleContains = __webpack_require__(65650); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(72687); +var CreateInteractiveObject = __webpack_require__(27395); +var CreatePixelPerfectHandler = __webpack_require__(18104); +var DistanceBetween = __webpack_require__(53996); +var Ellipse = __webpack_require__(95669); +var EllipseContains = __webpack_require__(72313); +var Events = __webpack_require__(33963); +var EventEmitter = __webpack_require__(6659); +var GetFastValue = __webpack_require__(72632); +var GEOM_CONST = __webpack_require__(52394); +var InputPluginCache = __webpack_require__(63399); +var IsPlainObject = __webpack_require__(42911); +var PluginCache = __webpack_require__(91963); +var Rectangle = __webpack_require__(74118); +var RectangleContains = __webpack_require__(94287); +var SceneEvents = __webpack_require__(7599); +var Triangle = __webpack_require__(66349); +var TriangleContains = __webpack_require__(60689); /** * @classdesc - * A Texture Source is the encapsulation of the actual source data for a Texture. + * The Input Plugin belongs to a Scene and handles all input related events and operations for it. * - * This is typically an Image Element, loaded from the file system or network, a Canvas Element or a Video Element. + * You can access it from within a Scene using `this.input`. * - * A Texture can contain multiple Texture Sources, which only happens when a multi-atlas is loaded. + * It emits events directly. For example, you can do: * - * @class TextureSource - * @memberof Phaser.Textures + * ```javascript + * this.input.on('pointerdown', callback, context); + * ``` + * + * To listen for a pointer down event anywhere on the game canvas. + * + * Game Objects can be enabled for input by calling their `setInteractive` method. After which they + * will directly emit input events: + * + * ```javascript + * var sprite = this.add.sprite(x, y, texture); + * sprite.setInteractive(); + * sprite.on('pointerdown', callback, context); + * ``` + * + * There are lots of game configuration options available relating to input. + * See the [Input Config object]{@linkcode Phaser.Types.Core.InputConfig} for more details, including how to deal with Phaser + * listening for input events outside of the canvas, how to set a default number of pointers, input + * capture settings and more. + * + * Please also see the Input examples and tutorials for further information. + * + * **Incorrect input coordinates with Angular** + * + * If you are using Phaser within Angular, and use nglf or the router, to make the component in which the Phaser game resides + * change state (i.e. appear or disappear) then you'll need to notify the Scale Manager about this, as Angular will mess with + * the DOM in a way in which Phaser can't detect directly. Call `this.scale.updateBounds()` as part of your game init in order + * to refresh the canvas DOM bounds values, which Phaser uses for input point position calculations. + * + * @class InputPlugin + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Input * @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. + * @param {Phaser.Scene} scene - A reference to the Scene that this Input Plugin is responsible for. */ -var TextureSource = new Class({ +var InputPlugin = new Class({ + + Extends: EventEmitter, initialize: - function TextureSource (texture, source, width, height, flipY) + function InputPlugin (scene) { - if (flipY === undefined) { flipY = false; } + EventEmitter.call(this); - var game = texture.manager.game; + /** + * A reference to the Scene that this Input Plugin is responsible for. + * + * @name Phaser.Input.InputPlugin#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; /** - * The Texture this TextureSource belongs to. + * A reference to the Scene Systems class. * - * @name Phaser.Textures.TextureSource#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.7.0 + * @name Phaser.Input.InputPlugin#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 */ - this.renderer = game.renderer; + this.systems = scene.sys; + + /** + * A reference to the Scene Systems Settings. + * + * @name Phaser.Input.InputPlugin#settings + * @type {Phaser.Types.Scenes.SettingsObject} + * @since 3.5.0 + */ + this.settings = scene.sys.settings; /** - * The Texture this TextureSource belongs to. + * A reference to the Game Input Manager. * - * @name Phaser.Textures.TextureSource#texture - * @type {Phaser.Textures.Texture} + * @name Phaser.Input.InputPlugin#manager + * @type {Phaser.Input.InputManager} * @since 3.0.0 */ - this.texture = texture; + this.manager = scene.sys.game.input; /** - * The source of the image data. + * Internal event queue used for plugins only. * - * This is either an Image Element, a Canvas Element, a Video Element, a RenderTexture or a WebGLTexture. + * @name Phaser.Input.InputPlugin#pluginEvents + * @type {Phaser.Events.EventEmitter} + * @private + * @since 3.10.0 + */ + this.pluginEvents = new EventEmitter(); + + /** + * If `true` this Input Plugin will process DOM input events. * - * @name Phaser.Textures.TextureSource#source - * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture)} - * @since 3.12.0 + * @name Phaser.Input.InputPlugin#enabled + * @type {boolean} + * @default true + * @since 3.5.0 */ - this.source = source; + this.enabled = true; /** - * The image data. + * A reference to the Scene Display List. This property is set during the `boot` method. * - * This is either an Image element, Canvas element or a Video Element. + * @name Phaser.Input.InputPlugin#displayList + * @type {Phaser.GameObjects.DisplayList} + * @since 3.0.0 + */ + this.displayList; + + /** + * A reference to the Scene Cameras Manager. This property is set during the `boot` method. * - * @name Phaser.Textures.TextureSource#image - * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement)} + * @name Phaser.Input.InputPlugin#cameras + * @type {Phaser.Cameras.Scene2D.CameraManager} * @since 3.0.0 */ - this.image = source; + this.cameras; + + // Inject the available input plugins into this class + InputPluginCache.install(this); /** - * Currently un-used. + * A reference to the Mouse Manager. * - * @name Phaser.Textures.TextureSource#compressionAlgorithm - * @type {number} - * @default null + * This property is only set if Mouse support has been enabled in your Game Configuration file. + * + * If you just wish to get access to the mouse pointer, use the `mousePointer` property instead. + * + * @name Phaser.Input.InputPlugin#mouse + * @type {?Phaser.Input.Mouse.MouseManager} * @since 3.0.0 */ - this.compressionAlgorithm = null; + this.mouse = this.manager.mouse; /** - * The resolution of the source image. + * When set to `true` (the default) the Input Plugin will emulate DOM behavior by only emitting events from + * the top-most Game Objects in the Display List. * - * @name Phaser.Textures.TextureSource#resolution + * If set to `false` it will emit events from all Game Objects below a Pointer, not just the top one. + * + * @name Phaser.Input.InputPlugin#topOnly + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.topOnly = true; + + /** + * How often should the Pointers be checked? + * + * The value is a time, given in ms, and is the time that must have elapsed between game steps before + * the Pointers will be polled again. When a pointer is polled it runs a hit test to see which Game + * Objects are currently below it, or being interacted with it. + * + * Pointers will *always* be checked if they have been moved by the user, or press or released. + * + * This property only controls how often they will be polled if they have not been updated. + * You should set this if you want to have Game Objects constantly check against the pointers, even + * if the pointer didn't itself move. + * + * Set to 0 to poll constantly. Set to -1 to only poll on user movement. + * + * @name Phaser.Input.InputPlugin#pollRate * @type {number} - * @default 1 + * @default -1 * @since 3.0.0 */ - this.resolution = 1; + this.pollRate = -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. + * Internal poll timer value. * - * @name Phaser.Textures.TextureSource#width + * @name Phaser.Input.InputPlugin#_pollTimer * @type {number} + * @private + * @default 0 * @since 3.0.0 */ - this.width = width || source.naturalWidth || source.videoWidth || source.width || 0; + this._pollTimer = 0; + + var _eventData = { cancelled: false }; /** - * 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. + * Internal event propagation callback container. * - * @name Phaser.Textures.TextureSource#height + * @name Phaser.Input.InputPlugin#_eventContainer + * @type {Phaser.Types.Input.EventData} + * @private + * @since 3.13.0 + */ + this._eventContainer = { + stopPropagation: function () + { + _eventData.cancelled = true; + } + }; + + /** + * Internal event propagation data object. + * + * @name Phaser.Input.InputPlugin#_eventData + * @type {object} + * @private + * @since 3.13.0 + */ + this._eventData = _eventData; + + /** + * The distance, in pixels, a pointer has to move while being held down, before it thinks it is being dragged. + * + * @name Phaser.Input.InputPlugin#dragDistanceThreshold * @type {number} + * @default 0 * @since 3.0.0 */ - this.height = height || source.naturalHeight || source.videoHeight || source.height || 0; + this.dragDistanceThreshold = 0; /** - * The Scale Mode the image will use when rendering. - * Either Linear or Nearest. + * The amount of time, in ms, a pointer has to be held down before it thinks it is dragging. * - * @name Phaser.Textures.TextureSource#scaleMode + * The default polling rate is to poll only on move so once the time threshold is reached the + * drag event will not start until you move the mouse. If you want it to start immediately + * when the time threshold is reached, you must increase the polling rate by calling + * [setPollAlways]{@linkcode Phaser.Input.InputPlugin#setPollAlways} or + * [setPollRate]{@linkcode Phaser.Input.InputPlugin#setPollRate}. + * + * @name Phaser.Input.InputPlugin#dragTimeThreshold * @type {number} + * @default 0 * @since 3.0.0 */ - this.scaleMode = ScaleModes.DEFAULT; + this.dragTimeThreshold = 0; /** - * Is the source image a Canvas Element? + * Used to temporarily store the results of the Hit Test * - * @name Phaser.Textures.TextureSource#isCanvas - * @type {boolean} + * @name Phaser.Input.InputPlugin#_temp + * @type {array} + * @private + * @default [] * @since 3.0.0 */ - this.isCanvas = (source instanceof HTMLCanvasElement); + this._temp = []; /** - * Is the source image a Video Element? + * Used to temporarily store the results of the Hit Test dropZones * - * @name Phaser.Textures.TextureSource#isVideo - * @type {boolean} - * @since 3.20.0 + * @name Phaser.Input.InputPlugin#_tempZones + * @type {array} + * @private + * @default [] + * @since 3.0.0 */ - this.isVideo = (window.hasOwnProperty('HTMLVideoElement') && source instanceof HTMLVideoElement); + this._tempZones = []; /** - * Is the source image a Render Texture? + * A list of all Game Objects that have been set to be interactive in the Scene this Input Plugin is managing. * - * @name Phaser.Textures.TextureSource#isRenderTexture - * @type {boolean} - * @since 3.12.0 + * @name Phaser.Input.InputPlugin#_list + * @type {Phaser.GameObjects.GameObject[]} + * @private + * @default [] + * @since 3.0.0 */ - this.isRenderTexture = (source.type === 'RenderTexture'); + this._list = []; /** - * Is the source image a WebGLTexture? + * Objects waiting to be inserted to the list on the next call to 'begin'. * - * @name Phaser.Textures.TextureSource#isGLTexture - * @type {boolean} - * @since 3.19.0 + * @name Phaser.Input.InputPlugin#_pendingInsertion + * @type {Phaser.GameObjects.GameObject[]} + * @private + * @default [] + * @since 3.0.0 */ - this.isGLTexture = (window.hasOwnProperty('WebGLTexture') && source instanceof WebGLTexture); + this._pendingInsertion = []; /** - * Are the source image dimensions a power of two? + * Objects waiting to be removed from the list on the next call to 'begin'. * - * @name Phaser.Textures.TextureSource#isPowerOf2 - * @type {boolean} + * @name Phaser.Input.InputPlugin#_pendingRemoval + * @type {Phaser.GameObjects.GameObject[]} + * @private + * @default [] * @since 3.0.0 */ - this.isPowerOf2 = IsSizePowerOfTwo(this.width, this.height); + this._pendingRemoval = []; /** - * The WebGL Texture of the source image. If this TextureSource is driven from a WebGLTexture - * already, then this is a reference to that WebGLTexture. + * A list of all Game Objects that have been enabled for dragging. * - * @name Phaser.Textures.TextureSource#glTexture - * @type {?WebGLTexture} - * @default null + * @name Phaser.Input.InputPlugin#_draggable + * @type {Phaser.GameObjects.GameObject[]} + * @private + * @default [] * @since 3.0.0 */ - this.glTexture = null; + this._draggable = []; /** - * The current texture unit index as assigned by the WebGL Renderer. - * Un-used in canvas. Should be treated as read-only. + * A list of all Interactive Objects currently considered as being 'draggable' by any pointer, indexed by pointer ID. * - * @name Phaser.Textures.TextureSource#glIndex - * @type {number} - * @default 0 - * @since 3.50.0 + * @name Phaser.Input.InputPlugin#_drag + * @type {{0:Array,1:Array,2:Array,3:Array,4:Array,5:Array,6:Array,7:Array,8:Array,9:Array,10:Array}} + * @private + * @since 3.0.0 */ - this.glIndex = 0; + this._drag = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: [] }; /** - * 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. + * A array containing the dragStates, for this Scene, index by the Pointer ID. * - * @name Phaser.Textures.TextureSource#glIndexCounter - * @type {number} - * @default -1 - * @since 3.50.0 + * @name Phaser.Input.InputPlugin#_dragState + * @type {number[]} + * @private + * @since 3.16.0 */ - this.glIndexCounter = -1; + this._dragState = []; /** - * Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. + * A list of all Interactive Objects currently considered as being 'over' by any pointer, indexed by pointer ID. * - * @name Phaser.Textures.TextureSource#flipY + * @name Phaser.Input.InputPlugin#_over + * @type {{0:Array,1:Array,2:Array,3:Array,4:Array,5:Array,6:Array,7:Array,8:Array,9:Array,10:Array}} + * @private + * @since 3.0.0 + */ + this._over = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: [] }; + + /** + * A list of valid DOM event types. + * + * @name Phaser.Input.InputPlugin#_validTypes + * @type {string[]} + * @private + * @since 3.0.0 + */ + this._validTypes = [ 'onDown', 'onUp', 'onOver', 'onOut', 'onMove', 'onDragStart', 'onDrag', 'onDragEnd', 'onDragEnter', 'onDragLeave', 'onDragOver', 'onDrop' ]; + + /** + * Internal property that tracks frame event state. + * + * @name Phaser.Input.InputPlugin#_updatedThisFrame * @type {boolean} - * @since 3.20.0 + * @private + * @since 3.18.0 */ - this.flipY = flipY; + this._updatedThisFrame = false; - this.init(game); + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + scene.sys.events.on(SceneEvents.START, this.start, this); }, /** - * Creates a WebGL Texture, if required, and sets the Texture filter mode. - * - * @method Phaser.Textures.TextureSource#init - * @since 3.0.0 + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. * - * @param {Phaser.Game} game - A reference to the Phaser Game instance. + * @method Phaser.Input.InputPlugin#boot + * @fires Phaser.Input.Events#BOOT + * @private + * @since 3.5.1 */ - init: function (game) + boot: function () { - var renderer = this.renderer; + this.cameras = this.systems.cameras; - 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.displayList = this.systems.displayList; - 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; - } - } + this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); - if (!game.config.antialias) - { - this.setFilter(1); - } + // Registered input plugins listen for this + this.pluginEvents.emit(Events.BOOT); }, /** - * Sets the Filter Mode for this Texture. - * - * The mode can be either Linear, the default, or Nearest. - * - * For pixel-art you should use Nearest. + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. * - * @method Phaser.Textures.TextureSource#setFilter - * @since 3.0.0 + * @method Phaser.Input.InputPlugin#start + * @fires Phaser.Input.Events#START + * @private + * @since 3.5.0 + */ + start: function () + { + var eventEmitter = this.systems.events; + + eventEmitter.on(SceneEvents.TRANSITION_START, this.transitionIn, this); + eventEmitter.on(SceneEvents.TRANSITION_OUT, this.transitionOut, this); + eventEmitter.on(SceneEvents.TRANSITION_COMPLETE, this.transitionComplete, this); + eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this); + eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); + + this.manager.events.on(Events.GAME_OUT, this.onGameOut, this); + this.manager.events.on(Events.GAME_OVER, this.onGameOver, this); + + this.enabled = true; + + // Populate the pointer drag states + this._dragState = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + + // Registered input plugins listen for this + this.pluginEvents.emit(Events.START); + }, + + /** + * Game Over handler. * - * @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode. + * @method Phaser.Input.InputPlugin#onGameOver + * @fires Phaser.Input.Events#GAME_OVER + * @private + * @since 3.16.2 */ - setFilter: function (filterMode) + onGameOver: function (event) { - if (this.renderer.gl) + if (this.isActive()) { - this.renderer.setTextureFilter(this.glTexture, filterMode); + this.emit(Events.GAME_OVER, event.timeStamp, event); } - - 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 + * Game Out handler. * - * @param {boolean} [value=true] - Should the WebGL Texture be flipped on the Y axis on texture upload or not? + * @method Phaser.Input.InputPlugin#onGameOut + * @fires Phaser.Input.Events#GAME_OUT + * @private + * @since 3.16.2 */ - setFlipY: function (value) + onGameOut: function (event) { - if (value === undefined) { value = true; } - - this.flipY = value; - - return this; + if (this.isActive()) + { + this.emit(Events.GAME_OUT, event.timeStamp, event); + } }, /** - * If this TextureSource is backed by a Canvas and is running under WebGL, - * it updates the WebGLTexture using the canvas data. + * The pre-update handler is responsible for checking the pending removal and insertion lists and + * deleting old Game Objects. * - * @method Phaser.Textures.TextureSource#update - * @since 3.7.0 + * @method Phaser.Input.InputPlugin#preUpdate + * @private + * @fires Phaser.Input.Events#PRE_UPDATE + * @since 3.0.0 */ - update: function () + preUpdate: function () { - var gl = this.renderer.gl; + // Registered input plugins listen for this + this.pluginEvents.emit(Events.PRE_UPDATE); - if (gl && this.isCanvas) + var removeList = this._pendingRemoval; + var insertList = this._pendingInsertion; + + var toRemove = removeList.length; + var toInsert = insertList.length; + + if (toRemove === 0 && toInsert === 0) { - this.glTexture = this.renderer.updateCanvasTexture(this.image, this.glTexture, this.flipY); + // Quick bail + return; } - else if (gl && this.isVideo) + + var current = this._list; + + // Delete old gameObjects + for (var i = 0; i < toRemove; i++) { - this.glTexture = this.renderer.updateVideoTexture(this.image, this.glTexture, this.flipY); + var gameObject = removeList[i]; + + var index = current.indexOf(gameObject); + + if (index > -1) + { + current.splice(index, 1); + + this.clear(gameObject, true); + } } + + // Clear the removal list + this._pendingRemoval.length = 0; + + // Move pendingInsertion to list (also clears pendingInsertion at the same time) + this._list = current.concat(insertList.splice(0)); }, /** - * Destroys this Texture Source and nulls the references. + * Checks to see if both this plugin and the Scene to which it belongs is active. * - * @method Phaser.Textures.TextureSource#destroy - * @since 3.0.0 + * @method Phaser.Input.InputPlugin#isActive + * @since 3.10.0 + * + * @return {boolean} `true` if the plugin and the Scene it belongs to is active. */ - destroy: function () + isActive: function () { - if (this.glTexture) + return (this.enabled && this.scene.sys.canInput()); + }, + + /** + * This is called automatically by the Input Manager. + * It emits events for plugins to listen to and also handles polling updates, if enabled. + * + * @method Phaser.Input.InputPlugin#updatePoll + * @since 3.18.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. + * + * @return {boolean} `true` if the plugin and the Scene it belongs to is active. + */ + updatePoll: function (time, delta) + { + if (!this.isActive()) { - this.renderer.deleteTexture(this.glTexture, true); + return false; } - if (this.isCanvas) + // The plugins should update every frame, regardless if there has been + // any DOM input events or not (such as the Gamepad and Keyboard) + this.pluginEvents.emit(Events.UPDATE, time, delta); + + // We can leave now if we've already updated once this frame via the immediate DOM event handlers + if (this._updatedThisFrame) { - CanvasPool.remove(this.image); + this._updatedThisFrame = false; + + return false; } - this.renderer = null; - this.texture = null; - this.source = null; - this.image = null; - this.glTexture = null; - } + var i; + var manager = this.manager; -}); + var pointers = manager.pointers; + var pointersTotal = manager.pointersTotal; -module.exports = TextureSource; + for (i = 0; i < pointersTotal; i++) + { + pointers[i].updateMotion(); + } + // No point going any further if there aren't any interactive objects + if (this._list.length === 0) + { + return false; + } -/***/ }), -/* 425 */ -/***/ (function(module, exports, __webpack_require__) { + var rate = this.pollRate; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (rate === -1) + { + return false; + } + else if (rate > 0) + { + this._pollTimer -= delta; -/** - * @namespace Phaser.Textures.Parsers - */ + if (this._pollTimer < 0) + { + // Discard timer diff, we're ready to poll again + this._pollTimer = this.pollRate; + } + else + { + // Not enough time has elapsed since the last poll, so abort now + return false; + } + } -module.exports = { + // We got this far? Then we should poll for movement + var captured = false; - AtlasXML: __webpack_require__(979), - Canvas: __webpack_require__(980), - Image: __webpack_require__(981), - JSONArray: __webpack_require__(982), - JSONHash: __webpack_require__(983), - SpriteSheet: __webpack_require__(984), - SpriteSheetFromAtlas: __webpack_require__(985), - UnityYAML: __webpack_require__(986) + for (i = 0; i < pointersTotal; i++) + { + var total = 0; -}; + var pointer = pointers[i]; + // Always reset this array + this._tempZones = []; -/***/ }), -/* 426 */ -/***/ (function(module, exports, __webpack_require__) { + // _temp contains a hit tested and camera culled list of IO objects + this._temp = this.hitTestPointer(pointer); -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.sortGameObjects(this._temp, pointer); + this.sortDropZones(this._tempZones); -var HTML5AudioSoundManager = __webpack_require__(427); -var NoAudioSoundManager = __webpack_require__(430); -var WebAudioSoundManager = __webpack_require__(432); + if (this.topOnly) + { + // Only the top-most one counts now, so safely ignore the rest + if (this._temp.length) + { + this._temp.splice(1); + } -/** - * 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 = { + if (this._tempZones.length) + { + this._tempZones.splice(1); + } + } - create: function (game) - { - var audioConfig = game.config.audio; - var deviceAudio = game.device.audio; + total += this.processOverOutEvents(pointer); - if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) - { - return new NoAudioSoundManager(game); + if (this.getDragState(pointer) === 2) + { + this.processDragThresholdEvent(pointer, time); + } + + if (total > 0) + { + // We interacted with an event in this Scene, so block any Scenes below us from doing the same this frame + captured = true; + } } - if (deviceAudio.webAudio && !audioConfig.disableWebAudio) + return captured; + }, + + /** + * This method is called when a DOM Event is received by the Input Manager. It handles dispatching the events + * to relevant input enabled Game Objects in this scene. + * + * @method Phaser.Input.InputPlugin#update + * @private + * @fires Phaser.Input.Events#UPDATE + * @since 3.0.0 + * + * @param {number} type - The type of event to process. + * @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred. + * + * @return {boolean} `true` if this Scene has captured the input events from all other Scenes, otherwise `false`. + */ + update: function (type, pointers) + { + if (!this.isActive()) { - return new WebAudioSoundManager(game); + return false; } - return new HTML5AudioSoundManager(game); - } + var pointersTotal = pointers.length; + var captured = false; -}; + for (var i = 0; i < pointersTotal; i++) + { + var total = 0; + var pointer = pointers[i]; -module.exports = SoundManagerCreator; + // Always reset this array + this._tempZones = []; + // _temp contains a hit tested and camera culled list of IO objects + this._temp = this.hitTestPointer(pointer); -/***/ }), -/* 427 */ -/***/ (function(module, exports, __webpack_require__) { + this.sortGameObjects(this._temp, pointer); + this.sortDropZones(this._tempZones); -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.topOnly) + { + // Only the top-most one counts now, so safely ignore the rest + if (this._temp.length) + { + this._temp.splice(1); + } -var BaseSoundManager = __webpack_require__(145); -var Class = __webpack_require__(0); -var Events = __webpack_require__(70); -var HTML5AudioSound = __webpack_require__(429); + if (this._tempZones.length) + { + this._tempZones.splice(1); + } + } -/** - * 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({ + switch (type) + { + case CONST.MOUSE_DOWN: + total += this.processDragDownEvent(pointer); + total += this.processDownEvents(pointer); + total += this.processOverOutEvents(pointer); + break; - Extends: BaseSoundManager, + case CONST.MOUSE_UP: + total += this.processDragUpEvent(pointer); + total += this.processUpEvents(pointer); + total += this.processOverOutEvents(pointer); + break; - initialize: + case CONST.TOUCH_START: + total += this.processDragDownEvent(pointer); + total += this.processDownEvents(pointer); + total += this.processOverEvents(pointer); + break; - 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; + case CONST.TOUCH_END: + case CONST.TOUCH_CANCEL: + total += this.processDragUpEvent(pointer); + total += this.processUpEvents(pointer); + total += this.processOutEvents(pointer); + break; - /** - * 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; + case CONST.MOUSE_MOVE: + case CONST.TOUCH_MOVE: + total += this.processDragMoveEvent(pointer); + total += this.processMoveEvents(pointer); + total += this.processOverOutEvents(pointer); + break; - /** - * 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; + case CONST.MOUSE_WHEEL: + total += this.processWheelEvent(pointer); + break; + } - /** - * 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; + if (total > 0) + { + // We interacted with an event in this Scene, so block any Scenes below us from doing the same this frame + captured = true; + } + } - /** - * 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; + this._updatedThisFrame = true; - BaseSoundManager.call(this, game); + return captured; }, /** - * Adds a new sound into the sound manager. + * Clears a Game Object so it no longer has an Interactive Object associated with it. + * The Game Object is then queued for removal from the Input Plugin on the next update. * - * @method Phaser.Sound.HTML5AudioSoundManager#add + * @method Phaser.Input.InputPlugin#clear * @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. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will have its Interactive Object removed. + * @param {boolean} [skipQueue=false] - Skip adding this Game Object into the removal queue? * - * @return {Phaser.Sound.HTML5AudioSound} The new sound instance. + * @return {Phaser.GameObjects.GameObject} The Game Object that had its Interactive Object removed. */ - add: function (key, config) + clear: function (gameObject, skipQueue) { - var sound = new HTML5AudioSound(this, key, config); - - this.sounds.push(sound); - - return sound; - }, + if (skipQueue === undefined) { skipQueue = false; } - /** - * 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; + this.disable(gameObject); - var _this = this; + var input = gameObject.input; - this.game.cache.audio.entries.each(function (key, tags) + // If GameObject.input already cleared from higher class + if (input) { - for (var i = 0; i < tags.length; i++) - { - if (tags[i].dataset.locked === 'true') - { - _this.locked = true; + this.removeDebug(gameObject); - return false; - } - } + input.gameObject = undefined; + input.target = undefined; + input.hitArea = undefined; + input.hitAreaCallback = undefined; + input.callbackContext = undefined; - return true; - }); + gameObject.input = null; + } - if (!this.locked) + if (!skipQueue) { - return; + this.queueForRemoval(gameObject); } - var moved = false; - - var detectMove = function () - { - moved = true; - }; + var index = this._draggable.indexOf(gameObject); - var unlock = function () + if (index > -1) { - 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; - }); + this._draggable.splice(index, 1); + } - if (lockedTags.length === 0) - { - return; - } + return gameObject; + }, - var lastTag = lockedTags[lockedTags.length - 1]; + /** + * Disables Input on a single Game Object. + * + * An input disabled Game Object still retains its Interactive Object component and can be re-enabled + * at any time, by passing it to `InputPlugin.enable`. + * + * @method Phaser.Input.InputPlugin#disable + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to have its input system disabled. + * + * @return {this} This Input Plugin. + */ + disable: function (gameObject) + { + var input = gameObject.input; - lastTag.oncanplaythrough = function () - { - lastTag.oncanplaythrough = null; + if (input) + { + input.enabled = false; + input.dragState = 0; + } - lockedTags.forEach(function (tag) - { - tag.dataset.locked = 'false'; - }); + // Clear from _temp, _drag and _over + var temp = this._temp; + var drag = this._drag; + var over = this._over; + var manager = this.manager; - _this.unlocked = true; - }; + var index = temp.indexOf(gameObject); - lockedTags.forEach(function (tag) - { - tag.load(); - }); - }; + if (index > -1) + { + temp.splice(index, 1); + } - this.once(Events.UNLOCKED, function () + for (var i = 0; i < manager.pointersTotal; i++) { - this.forEachActiveSound(function (sound) + index = drag[i].indexOf(gameObject); + + if (index > -1) { - if (sound.currentMarker === null && sound.duration === 0) - { - sound.duration = sound.tags[0].duration; - } + drag[i].splice(index, 1); + } - sound.totalDuration = sound.tags[0].duration; - }); + index = over[i].indexOf(gameObject); - while (this.lockedActionsQueue.length) + if (index > -1) { - var lockedAction = this.lockedActionsQueue.shift(); + over[i].splice(index, 1); - if (lockedAction.sound[lockedAction.prop].apply) - { - lockedAction.sound[lockedAction.prop].apply(lockedAction.sound, lockedAction.value || []); - } - else - { - lockedAction.sound[lockedAction.prop] = lockedAction.value; - } + manager.resetCursor(input); } + } - }, this); - - document.body.addEventListener('touchmove', detectMove, false); - document.body.addEventListener('touchend', unlock, false); + return this; }, /** - * Method used internally for pausing sound manager if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * Enable a Game Object for interaction. * - * @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. + * If the Game Object already has an Interactive Object component, it is enabled and returned. * - * @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. + * Otherwise, a new Interactive Object component is created and assigned to the Game Object's `input` property. * - * @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. + * Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area + * for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced + * input detection. * - * @method Phaser.Sound.HTML5AudioSoundManager#isLocked - * @protected + * If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If + * this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific + * shape for it to use. + * + * You can also provide an Input Configuration Object as the only argument to this method. + * + * @method Phaser.Input.InputPlugin#enable * @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. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to be enabled for input. + * @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. + * @param {Phaser.Types.Input.HitAreaCallback} [hitAreaCallback] - The 'contains' function to invoke to check if the pointer is within the hit area. + * @param {boolean} [dropZone=false] - Is this Game Object a drop zone or not? * - * @return {boolean} Whether the sound manager is locked. + * @return {this} This Input Plugin. */ - isLocked: function (sound, prop, value) + enable: function (gameObject, hitArea, hitAreaCallback, dropZone) { - if (sound.tags[0].dataset.locked === 'true') + if (dropZone === undefined) { dropZone = false; } + + if (gameObject.input) { - this.lockedActionsQueue.push({ - sound: sound, - prop: prop, - value: value - }); + // If it is already has an InteractiveObject then just enable it and return + gameObject.input.enabled = true; + } + else + { + // Create an InteractiveObject and enable it + this.setHitArea(gameObject, hitArea, hitAreaCallback); + } - return true; + if (gameObject.input && dropZone && !gameObject.input.dropZone) + { + gameObject.input.dropZone = dropZone; } - return false; + return this; }, /** - * Sets the muted state of all this Sound Manager. + * Takes the given Pointer and performs a hit test against it, to see which interactive Game Objects + * it is currently above. * - * @method Phaser.Sound.HTML5AudioSoundManager#setMute - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.3.0 + * The hit test is performed against which-ever Camera the Pointer is over. If it is over multiple + * cameras, it starts checking the camera at the top of the camera list, and if nothing is found, iterates down the list. * - * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. + * @method Phaser.Input.InputPlugin#hitTestPointer + * @since 3.0.0 * - * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. + * @param {Phaser.Input.Pointer} pointer - The Pointer to check against the Game Objects. + * + * @return {Phaser.GameObjects.GameObject[]} An array of all the interactive Game Objects the Pointer was above. */ - setMute: function (value) + hitTestPointer: function (pointer) { - this.mute = value; + var cameras = this.cameras.getCamerasBelowPointer(pointer); - return this; - }, + for (var c = 0; c < cameras.length; c++) + { + var camera = cameras[c]; - /** - * @name Phaser.Sound.HTML5AudioSoundManager#mute - * @type {boolean} - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.0.0 - */ - mute: { + // Get a list of all objects that can be seen by the camera below the pointer in the scene and store in 'over' array. + // All objects in this array are input enabled, as checked by the hitTest method, so we don't need to check later on as well. + var over = this.manager.hitTest(pointer, this._list, camera); - get: function () - { - return this._mute; - }, + // Filter out the drop zones + for (var i = 0; i < over.length; i++) + { + var obj = over[i]; - set: function (value) - { - this._mute = value; + if (obj.input.dropZone) + { + this._tempZones.push(obj); + } + } - this.forEachActiveSound(function (sound) + if (over.length > 0) { - sound.updateMute(); - }); + pointer.camera = camera; - this.emit(Events.GLOBAL_MUTE, this, value); + return over; + } } + // If we got this far then there were no Game Objects below the pointer, but it was still over + // a camera, so set that the top-most one into the pointer + + pointer.camera = cameras[0]; + + return []; }, /** - * Sets the volume of this Sound Manager. + * An internal method that handles the Pointer down event. * - * @method Phaser.Sound.HTML5AudioSoundManager#setVolume - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.3.0 + * @method Phaser.Input.InputPlugin#processDownEvents + * @private + * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_DOWN + * @fires Phaser.Input.Events#GAMEOBJECT_DOWN + * @fires Phaser.Input.Events#POINTER_DOWN + * @fires Phaser.Input.Events#POINTER_DOWN_OUTSIDE + * @since 3.0.0 * - * @param {number} value - The global volume of this Sound Manager. + * @param {Phaser.Input.Pointer} pointer - The Pointer being tested. * - * @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager. + * @return {number} The total number of objects interacted with. */ - setVolume: function (value) + processDownEvents: function (pointer) { - this.volume = value; + var total = 0; + var currentlyOver = this._temp; - return this; - }, + var _eventData = this._eventData; + var _eventContainer = this._eventContainer; - /** - * @name Phaser.Sound.HTML5AudioSoundManager#volume - * @type {number} - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.0.0 - */ - volume: { + _eventData.cancelled = false; - get: function () - { - return this._volume; - }, + var aborted = false; - set: function (value) + // Go through all objects the pointer was over and fire their events / callbacks + for (var i = 0; i < currentlyOver.length; i++) { - this._volume = value; + var gameObject = currentlyOver[i]; - this.forEachActiveSound(function (sound) + if (!gameObject.input || !gameObject.input.enabled) { - sound.updateVolume(); - }); - - this.emit(Events.GLOBAL_VOLUME, this, value); - } - - } - -}); - -module.exports = HTML5AudioSoundManager; - - -/***/ }), -/* 428 */ -/***/ (function(module, exports, __webpack_require__) { + continue; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + total++; -var SafeRange = __webpack_require__(78); + gameObject.emit(Events.GAMEOBJECT_POINTER_DOWN, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); -/** - * 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 (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } - if (SafeRange(array, startIndex, endIndex)) - { - for (var i = startIndex; i < endIndex; i++) - { - var child = array[i]; + this.emit(Events.GAMEOBJECT_DOWN, pointer, gameObject, _eventContainer); - if (!property || - (property && value === undefined && child.hasOwnProperty(property)) || - (property && value !== undefined && child[property] === value)) + if (_eventData.cancelled || !gameObject.input) { - return child; + aborted = true; + break; } } - } - - return null; -}; - -module.exports = GetFirst; - - -/***/ }), -/* 429 */ -/***/ (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__(146); -var Class = __webpack_require__(0); -var Events = __webpack_require__(70); -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) + // If they released outside the canvas, but pressed down inside it, we'll still dispatch the event. + if (!aborted && this.manager) { - throw new Error('There is no audio asset with key "' + key + '" in the audio cache'); + if (pointer.downElement === this.manager.game.canvas) + { + this.emit(Events.POINTER_DOWN, pointer, currentlyOver); + } + else + { + this.emit(Events.POINTER_DOWN_OUTSIDE, pointer); + } } - /** - * 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); + return total; }, /** - * 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. + * Returns the drag state of the given Pointer for this Input Plugin. * - * @method Phaser.Sound.HTML5AudioSound#play - * @fires Phaser.Sound.Events#PLAY - * @since 3.0.0 + * The state will be one of the following: * - * @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. + * 0 = Not dragging anything + * 1 = Primary button down and objects below, so collect a draglist + * 2 = Pointer being checked if meets drag criteria + * 3 = Pointer meets criteria, notify the draglist + * 4 = Pointer actively dragging the draglist and has moved + * 5 = Pointer actively dragging but has been released, notify draglist * - * @return {boolean} Whether the sound started playing successfully. + * @method Phaser.Input.InputPlugin#getDragState + * @since 3.16.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer to get the drag state for. + * + * @return {number} The drag state of the given Pointer. */ - play: function (markerName, config) + getDragState: function (pointer) { - 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; + return this._dragState[pointer.id]; }, /** - * Pauses the sound. + * Sets the drag state of the given Pointer for this Input Plugin. * - * @method Phaser.Sound.HTML5AudioSound#pause - * @fires Phaser.Sound.Events#PAUSE - * @since 3.0.0 + * The state must be one of the following values: * - * @return {boolean} Whether the sound was paused successfully. + * 0 = Not dragging anything + * 1 = Primary button down and objects below, so collect a draglist + * 2 = Pointer being checked if meets drag criteria + * 3 = Pointer meets criteria, notify the draglist + * 4 = Pointer actively dragging the draglist and has moved + * 5 = Pointer actively dragging but has been released, notify draglist + * + * @method Phaser.Input.InputPlugin#setDragState + * @since 3.16.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer to set the drag state for. + * @param {number} state - The drag state value. An integer between 0 and 5. */ - pause: function () + setDragState: function (pointer, state) { - 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; + this._dragState[pointer.id] = state; }, /** - * Resumes the sound. + * Checks to see if a Pointer is ready to drag the objects below it, based on either a distance + * or time threshold. * - * @method Phaser.Sound.HTML5AudioSound#resume - * @fires Phaser.Sound.Events#RESUME - * @since 3.0.0 + * @method Phaser.Input.InputPlugin#processDragThresholdEvent + * @private + * @since 3.18.0 * - * @return {boolean} Whether the sound was resumed successfully. + * @param {Phaser.Input.Pointer} pointer - The Pointer to check the drag thresholds on. + * @param {number} time - The current time. */ - resume: function () + processDragThresholdEvent: function (pointer, time) { - if (this.manager.isLocked(this, 'resume')) - { - return false; - } + var passed = false; + var timeThreshold = this.dragTimeThreshold; + var distanceThreshold = this.dragDistanceThreshold; - if (this.startTime > 0) + if (distanceThreshold > 0 && DistanceBetween(pointer.x, pointer.y, pointer.downX, pointer.downY) >= distanceThreshold) { - return false; + // It has moved far enough to be considered a drag + passed = true; } - - if (!BaseSound.prototype.resume.call(this)) + else if (timeThreshold > 0 && (time >= pointer.downTime + timeThreshold)) { - return false; + // It has been held down long enough to be considered a drag + passed = true; } - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - if (!this.pickAndPlayAudioTag()) + if (passed) { - return false; - } - - this.emit(Events.RESUME, this); + this.setDragState(pointer, 3); - return true; + return this.processDragStartList(pointer); + } }, /** - * Stop playing this sound. + * Processes the drag list for the given pointer and dispatches the start events for each object on it. * - * @method Phaser.Sound.HTML5AudioSound#stop - * @fires Phaser.Sound.Events#STOP - * @since 3.0.0 + * @method Phaser.Input.InputPlugin#processDragStartList + * @private + * @fires Phaser.Input.Events#DRAG_START + * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_START + * @since 3.18.0 * - * @return {boolean} Whether the sound was stopped successfully. + * @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on. + * + * @return {number} The number of items that DRAG_START was called on. */ - stop: function () + processDragStartList: function (pointer) { - if (this.manager.isLocked(this, 'stop')) + // 3 = Pointer meets criteria and is freshly down, notify the draglist + if (this.getDragState(pointer) !== 3) { - return false; + return 0; } - if (!BaseSound.prototype.stop.call(this)) + var list = this._drag[pointer.id]; + + for (var i = 0; i < list.length; i++) { - return false; - } + var gameObject = list[i]; - // \/\/\/ isPlaying = false, isPaused = false \/\/\/ - this.stopAndReleaseAudioTag(); + var input = gameObject.input; - this.emit(Events.STOP, this); + input.dragState = 2; - return true; + input.dragStartX = gameObject.x; + input.dragStartY = gameObject.y; + + input.dragStartXGlobal = pointer.worldX; + input.dragStartYGlobal = pointer.worldY; + + input.dragX = input.dragStartXGlobal - input.dragStartX; + input.dragY = input.dragStartYGlobal - input.dragStartY; + + gameObject.emit(Events.GAMEOBJECT_DRAG_START, pointer, input.dragX, input.dragY); + + this.emit(Events.DRAG_START, pointer, gameObject); + } + + this.setDragState(pointer, 4); + + return list.length; }, /** - * Used internally to do what the name says. + * Processes a 'drag down' event for the given pointer. Checks the pointer state, builds-up the drag list + * and prepares them all for interaction. * - * @method Phaser.Sound.HTML5AudioSound#pickAndPlayAudioTag + * @method Phaser.Input.InputPlugin#processDragDownEvent * @private - * @since 3.0.0 + * @since 3.18.0 * - * @return {boolean} Whether the sound was assigned an audio tag successfully. + * @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on. + * + * @return {number} The number of items that were collected on the drag list. */ - pickAndPlayAudioTag: function () + processDragDownEvent: function (pointer) { - if (!this.pickAudioTag()) + var currentlyOver = this._temp; + + if (this._draggable.length === 0 || currentlyOver.length === 0 || !pointer.primaryDown || this.getDragState(pointer) !== 0) { - this.reset(); - return false; + // There are no draggable items, no over items or the pointer isn't down, so let's not even bother going further + return 0; } - var seek = this.currentConfig.seek; - var delay = this.currentConfig.delay; - var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; + // 1 = Primary button down and objects below, so collect a draglist + this.setDragState(pointer, 1); - this.previousTime = offset; - this.audio.currentTime = offset; - this.applyConfig(); + // Get draggable objects, sort them, pick the top (or all) and store them somewhere + var draglist = []; - if (delay === 0) + for (var i = 0; i < currentlyOver.length; i++) { - this.startTime = 0; + var gameObject = currentlyOver[i]; - if (this.audio.paused) + if (gameObject.input.draggable && (gameObject.input.dragState === 0)) { - this.playCatchPromise(); + draglist.push(gameObject); } } - else + + if (draglist.length === 0) { - this.startTime = window.performance.now() + delay * 1000; + this.setDragState(pointer, 0); - if (!this.audio.paused) + return 0; + } + else if (draglist.length > 1) + { + this.sortGameObjects(draglist, pointer); + + if (this.topOnly) { - this.audio.pause(); + draglist.splice(1); } } - this.resetConfig(); + // draglist now contains all potential candidates for dragging + this._drag[pointer.id] = draglist; - return true; + if (this.dragDistanceThreshold === 0 && this.dragTimeThreshold === 0) + { + // No drag criteria, so snap immediately to mode 3 + this.setDragState(pointer, 3); + + return this.processDragStartList(pointer); + } + else + { + // Check the distance / time on the next event + this.setDragState(pointer, 2); + + return 0; + } }, /** - * 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. + * Processes a 'drag move' event for the given pointer. * - * @method Phaser.Sound.HTML5AudioSound#pickAudioTag + * @method Phaser.Input.InputPlugin#processDragMoveEvent * @private - * @since 3.0.0 + * @fires Phaser.Input.Events#DRAG_ENTER + * @fires Phaser.Input.Events#DRAG + * @fires Phaser.Input.Events#DRAG_LEAVE + * @fires Phaser.Input.Events#DRAG_OVER + * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_ENTER + * @fires Phaser.Input.Events#GAMEOBJECT_DRAG + * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_LEAVE + * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_OVER + * @since 3.18.0 * - * @return {boolean} Whether the sound was assigned an audio tag successfully. + * @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on. + * + * @return {number} The number of items that were updated by this drag event. */ - pickAudioTag: function () + processDragMoveEvent: function (pointer) { - if (this.audio) + // 2 = Pointer being checked if meets drag criteria + if (this.getDragState(pointer) === 2) { - return true; + this.processDragThresholdEvent(pointer, this.manager.game.loop.now); } - for (var i = 0; i < this.tags.length; i++) + if (this.getDragState(pointer) !== 4) { - var audio = this.tags[i]; - - if (audio.dataset.used === 'false') - { - audio.dataset.used = 'true'; - this.audio = audio; - return true; - } + return 0; } - if (!this.manager.override) - { - return false; - } + // 4 = Pointer actively dragging the draglist and has moved + var dropZones = this._tempZones; - var otherSounds = []; + var list = this._drag[pointer.id]; - this.manager.forEachActiveSound(function (sound) + for (var i = 0; i < list.length; i++) { - if (sound.key === this.key && sound.audio) - { - otherSounds.push(sound); - } - }, this); + var gameObject = list[i]; - otherSounds.sort(function (a1, a2) - { - if (a1.loop === a2.loop) + var input = gameObject.input; + + var target = input.target; + + // If this GO has a target then let's check it + if (target) { - // sort by progress - return (a2.seek / a2.duration) - (a1.seek / a1.duration); - } - return a1.loop ? 1 : -1; - }); + var index = dropZones.indexOf(target); - var selectedSound = otherSounds[0]; + // Got a target, are we still over it? + if (index === 0) + { + // We're still over it, and it's still the top of the display list, phew ... + gameObject.emit(Events.GAMEOBJECT_DRAG_OVER, pointer, target); - this.audio = selectedSound.audio; + this.emit(Events.DRAG_OVER, pointer, gameObject, target); + } + else if (index > 0) + { + // Still over it but it's no longer top of the display list (targets must always be at the top) + gameObject.emit(Events.GAMEOBJECT_DRAG_LEAVE, pointer, target); - selectedSound.reset(); - selectedSound.audio = null; - selectedSound.startTime = 0; - selectedSound.previousTime = 0; + this.emit(Events.DRAG_LEAVE, pointer, gameObject, target); - return true; - }, + input.target = dropZones[0]; - /** - * 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(); + target = input.target; - if (playPromise) - { - // eslint-disable-next-line no-unused-vars - playPromise.catch(function (reason) - { - console.warn(reason); - }); - } - }, + gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, target); - /** - * 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; + this.emit(Events.DRAG_ENTER, pointer, gameObject, target); + } + else + { + // Nope, we've moved on (or the target has!), leave the old target + gameObject.emit(Events.GAMEOBJECT_DRAG_LEAVE, pointer, target); - if (this.audio) - { - this.audio.pause(); - this.audio.dataset.used = 'false'; - this.audio = null; - } - }, + this.emit(Events.DRAG_LEAVE, pointer, gameObject, target); - /** - * 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); + // Anything new to replace it? + // Yup! + if (dropZones[0]) + { + input.target = dropZones[0]; + + target = input.target; + + gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, target); + + this.emit(Events.DRAG_ENTER, pointer, gameObject, target); + } + else + { + // Nope + input.target = null; + } + } + } + else if (!target && dropZones[0]) + { + input.target = dropZones[0]; + + target = input.target; + + gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, target); + + this.emit(Events.DRAG_ENTER, pointer, gameObject, target); + } + + var dragX; + var dragY; + + if (!gameObject.parentContainer) + { + dragX = pointer.worldX - input.dragX; + dragY = pointer.worldY - input.dragY; + } + else + { + var dx = pointer.worldX - input.dragStartXGlobal; + var dy = pointer.worldY - input.dragStartYGlobal; + + var rotation = gameObject.getParentRotation(); + + var dxRotated = dx * Math.cos(rotation) + dy * Math.sin(rotation); + var dyRotated = dy * Math.cos(rotation) - dx * Math.sin(rotation); + + dxRotated *= (1 / gameObject.parentContainer.scaleX); + dyRotated *= (1 / gameObject.parentContainer.scaleY); + + dragX = dxRotated + input.dragStartX; + dragY = dyRotated + input.dragStartY; + } + + gameObject.emit(Events.GAMEOBJECT_DRAG, pointer, dragX, dragY); + + this.emit(Events.DRAG, pointer, gameObject, dragX, dragY); + } + + return list.length; }, /** - * Method used internally by sound manager for pausing sound if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * Processes a 'drag down' event for the given pointer. Checks the pointer state, builds-up the drag list + * and prepares them all for interaction. * - * @method Phaser.Sound.HTML5AudioSoundManager#onBlur + * @method Phaser.Input.InputPlugin#processDragUpEvent + * @fires Phaser.Input.Events#DRAG_END + * @fires Phaser.Input.Events#DROP + * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_END + * @fires Phaser.Input.Events#GAMEOBJECT_DROP * @private - * @since 3.0.0 + * @since 3.18.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on. + * + * @return {number} The number of items that were updated by this drag event. */ - onBlur: function () + processDragUpEvent: function (pointer) { - this.isPlaying = false; - this.isPaused = true; + // 5 = Pointer was actively dragging but has been released, notify draglist + var list = this._drag[pointer.id]; - this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); + for (var i = 0; i < list.length; i++) + { + var gameObject = list[i]; - this.currentConfig.delay = Math.max(0, (this.startTime - window.performance.now()) / 1000); + var input = gameObject.input; - this.stopAndReleaseAudioTag(); + if (input && input.dragState === 2) + { + input.dragState = 0; + + input.dragX = input.localX - gameObject.displayOriginX; + input.dragY = input.localY - gameObject.displayOriginY; + + var dropped = false; + + var target = input.target; + + if (target) + { + gameObject.emit(Events.GAMEOBJECT_DROP, pointer, target); + + this.emit(Events.DROP, pointer, gameObject, target); + + input.target = null; + + dropped = true; + } + + // And finally the dragend event + + if (gameObject.input && gameObject.input.enabled) + { + gameObject.emit(Events.GAMEOBJECT_DRAG_END, pointer, input.dragX, input.dragY, dropped); + + this.emit(Events.DRAG_END, pointer, gameObject, dropped); + } + } + } + + this.setDragState(pointer, 0); + + list.splice(0); + + return 0; }, /** - * Method used internally by sound manager for resuming sound if - * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * An internal method that handles the Pointer movement event. * - * @method Phaser.Sound.HTML5AudioSound#onFocus + * @method Phaser.Input.InputPlugin#processMoveEvents * @private + * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_MOVE + * @fires Phaser.Input.Events#GAMEOBJECT_MOVE + * @fires Phaser.Input.Events#POINTER_MOVE * @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 {Phaser.Input.Pointer} pointer - The pointer to check for events against. * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @return {number} The total number of objects interacted with. */ - update: function (time) + processMoveEvents: function (pointer) { - if (!this.isPlaying) - { - return; - } + var total = 0; + var currentlyOver = this._temp; - // handling delayed playback - if (this.startTime > 0) + var _eventData = this._eventData; + var _eventContainer = this._eventContainer; + + _eventData.cancelled = false; + + var aborted = false; + + // Go through all objects the pointer was over and fire their events / callbacks + for (var i = 0; i < currentlyOver.length; i++) { - if (this.startTime < time - this.manager.audioPlayDelay) + var gameObject = currentlyOver[i]; + + if (!gameObject.input || !gameObject.input.enabled) { - this.audio.currentTime += Math.max(0, time - this.startTime) / 1000; - this.startTime = 0; - this.previousTime = this.audio.currentTime; - this.playCatchPromise(); + continue; } - return; - } + total++; - // handle looping and ending - var startTime = this.currentMarker ? this.currentMarker.start : 0; - var endTime = startTime + this.duration; - var currentTime = this.audio.currentTime; + gameObject.emit(Events.GAMEOBJECT_POINTER_MOVE, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); - if (this.currentConfig.loop) - { - if (currentTime >= endTime - this.manager.loopEndOffset) + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) { - this.audio.currentTime = startTime + Math.max(0, currentTime - endTime); - currentTime = this.audio.currentTime; + aborted = true; + break; } - else if (currentTime < startTime) + + this.emit(Events.GAMEOBJECT_MOVE, pointer, gameObject, _eventContainer); + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) { - this.audio.currentTime += startTime; - currentTime = this.audio.currentTime; + aborted = true; + break; } - if (currentTime < this.previousTime) + if (this.topOnly) { - this.emit(Events.LOOPED, this); + break; } } - else if (currentTime >= endTime) - { - this.reset(); - - this.stopAndReleaseAudioTag(); - - this.emit(Events.COMPLETE, this); - return; + if (!aborted) + { + this.emit(Events.POINTER_MOVE, pointer, currentlyOver); } - this.previousTime = currentTime; + return total; }, /** - * Calls Phaser.Sound.BaseSound#destroy method - * and cleans up all HTML5 Audio related stuff. + * An internal method that handles a mouse wheel event. * - * @method Phaser.Sound.HTML5AudioSound#destroy - * @since 3.0.0 + * @method Phaser.Input.InputPlugin#processWheelEvent + * @private + * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_WHEEL + * @fires Phaser.Input.Events#GAMEOBJECT_WHEEL + * @fires Phaser.Input.Events#POINTER_WHEEL + * @since 3.18.0 + * + * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. + * + * @return {number} The total number of objects interacted with. */ - destroy: function () + processWheelEvent: function (pointer) { - BaseSound.prototype.destroy.call(this); + var total = 0; + var currentlyOver = this._temp; - this.tags = null; + var _eventData = this._eventData; + var _eventContainer = this._eventContainer; - if (this.audio) + _eventData.cancelled = false; + + var aborted = false; + + var dx = pointer.deltaX; + var dy = pointer.deltaY; + var dz = pointer.deltaZ; + + // Go through all objects the pointer was over and fire their events / callbacks + for (var i = 0; i < currentlyOver.length; i++) { - this.stopAndReleaseAudioTag(); + var gameObject = currentlyOver[i]; + + if (!gameObject.input || !gameObject.input.enabled) + { + continue; + } + + total++; + + gameObject.emit(Events.GAMEOBJECT_POINTER_WHEEL, pointer, dx, dy, dz, _eventContainer); + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } + + this.emit(Events.GAMEOBJECT_WHEEL, pointer, gameObject, dx, dy, dz, _eventContainer); + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } } - }, - /** - * 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) + if (!aborted) { - this.audio.muted = this.currentConfig.mute || this.manager.mute; + this.emit(Events.POINTER_WHEEL, pointer, currentlyOver, dx, dy, dz); } + + return total; }, /** - * Method used internally to calculate total volume of the sound. + * An internal method that handles the Pointer over events. + * This is called when a touch input hits the canvas, having previously been off of it. * - * @method Phaser.Sound.HTML5AudioSound#updateVolume + * @method Phaser.Input.InputPlugin#processOverEvents * @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. + * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OVER + * @fires Phaser.Input.Events#GAMEOBJECT_OVER + * @fires Phaser.Input.Events#POINTER_OVER + * @since 3.18.0 * - * @method Phaser.Sound.HTML5AudioSound#calculateRate - * @protected - * @since 3.0.0 + * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. + * + * @return {number} The total number of objects interacted with. */ - calculateRate: function () + processOverEvents: function (pointer) { - BaseSound.prototype.calculateRate.call(this); + var currentlyOver = this._temp; - if (this.audio) - { - this.audio.playbackRate = this.totalRate; - } - }, + var totalInteracted = 0; - /** - * 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: { + var total = currentlyOver.length; - get: function () - { - return this.currentConfig.mute; - }, + var justOver = []; - set: function (value) + if (total > 0) { - this.currentConfig.mute = value; + var manager = this.manager; - if (this.manager.isLocked(this, 'mute', value)) + var _eventData = this._eventData; + var _eventContainer = this._eventContainer; + + _eventData.cancelled = false; + + var aborted = false; + + for (var i = 0; i < total; i++) { - return; - } + var gameObject = currentlyOver[i]; - this.updateMute(); + if (!gameObject.input || !gameObject.input.enabled) + { + continue; + } - this.emit(Events.MUTE, this, value); + justOver.push(gameObject); + + manager.setCursor(gameObject.input); + + gameObject.emit(Events.GAMEOBJECT_POINTER_OVER, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); + + totalInteracted++; + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } + + this.emit(Events.GAMEOBJECT_OVER, pointer, gameObject, _eventContainer); + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } + } + + if (!aborted) + { + this.emit(Events.POINTER_OVER, pointer, justOver); + } } + + // Then sort it into display list order + this._over[pointer.id] = justOver; + + return totalInteracted; }, /** - * Sets the muted state of this Sound. + * An internal method that handles the Pointer out events. + * This is called when a touch input leaves the canvas, as it can never be 'over' in this case. * - * @method Phaser.Sound.HTML5AudioSound#setMute - * @fires Phaser.Sound.Events#MUTE - * @since 3.4.0 + * @method Phaser.Input.InputPlugin#processOutEvents + * @private + * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OUT + * @fires Phaser.Input.Events#GAMEOBJECT_OUT + * @fires Phaser.Input.Events#POINTER_OUT + * @since 3.18.0 * - * @param {boolean} value - `true` to mute this sound, `false` to unmute it. + * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. * - * @return {this} This Sound instance. + * @return {number} The total number of objects interacted with. */ - setMute: function (value) + processOutEvents: function (pointer) { - this.mute = value; + var previouslyOver = this._over[pointer.id]; - return this; - }, + var totalInteracted = 0; - /** - * 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: { + var total = previouslyOver.length; - get: function () + if (total > 0) { - return this.currentConfig.volume; - }, + var manager = this.manager; - set: function (value) - { - this.currentConfig.volume = value; + var _eventData = this._eventData; + var _eventContainer = this._eventContainer; - if (this.manager.isLocked(this, 'volume', value)) + _eventData.cancelled = false; + + var aborted = false; + + this.sortGameObjects(previouslyOver, pointer); + + for (var i = 0; i < total; i++) { - return; - } + var gameObject = previouslyOver[i]; - this.updateVolume(); + // Call onOut for everything in the previouslyOver array + gameObject = previouslyOver[i]; - this.emit(Events.VOLUME, this, value); + if (!gameObject.input || !gameObject.input.enabled) + { + continue; + } + + manager.resetCursor(gameObject.input); + + gameObject.emit(Events.GAMEOBJECT_POINTER_OUT, pointer, _eventContainer); + + totalInteracted++; + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } + + this.emit(Events.GAMEOBJECT_OUT, pointer, gameObject, _eventContainer); + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } + + if (!aborted) + { + this.emit(Events.POINTER_OUT, pointer, previouslyOver); + } + } + + this._over[pointer.id] = []; } + + return totalInteracted; }, /** - * Sets the volume of this Sound. + * An internal method that handles the Pointer over and out events. * - * @method Phaser.Sound.HTML5AudioSound#setVolume - * @fires Phaser.Sound.Events#VOLUME - * @since 3.4.0 + * @method Phaser.Input.InputPlugin#processOverOutEvents + * @private + * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OVER + * @fires Phaser.Input.Events#GAMEOBJECT_OVER + * @fires Phaser.Input.Events#POINTER_OVER + * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OUT + * @fires Phaser.Input.Events#GAMEOBJECT_OUT + * @fires Phaser.Input.Events#POINTER_OUT + * @since 3.0.0 * - * @param {number} value - The volume of the sound. + * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. * - * @return {this} This Sound instance. + * @return {number} The total number of objects interacted with. */ - setVolume: function (value) + processOverOutEvents: function (pointer) { - this.volume = value; + var currentlyOver = this._temp; - return this; - }, + var i; + var gameObject; + var justOut = []; + var justOver = []; + var stillOver = []; + var previouslyOver = this._over[pointer.id]; + var currentlyDragging = this._drag[pointer.id]; - /** - * 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: { + var manager = this.manager; - get: function () - { - return this.currentConfig.rate; - }, + // Go through all objects the pointer was previously over, and see if it still is. + // Splits the previouslyOver array into two parts: justOut and stillOver - set: function (value) + for (i = 0; i < previouslyOver.length; i++) { - this.currentConfig.rate = value; + gameObject = previouslyOver[i]; - if (this.manager.isLocked(this, Events.RATE, value)) + if (currentlyOver.indexOf(gameObject) === -1 && currentlyDragging.indexOf(gameObject) === -1) { - return; + // Not in the currentlyOver array, so must be outside of this object now + justOut.push(gameObject); } else { - this.calculateRate(); + // In the currentlyOver array + stillOver.push(gameObject); + } + } - this.emit(Events.RATE, this, value); + // Go through all objects the pointer is currently over (the hit test results) + // and if not in the previouslyOver array we know it's a new entry, so add to justOver + for (i = 0; i < currentlyOver.length; i++) + { + gameObject = currentlyOver[i]; + + // Is this newly over? + + if (previouslyOver.indexOf(gameObject) === -1) + { + justOver.push(gameObject); } } - }, + // By this point the arrays are filled, so now we can process what happened... - /** - * 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; + // Process the Just Out objects + var total = justOut.length; - return this; - }, + var totalInteracted = 0; - /** - * 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: { + var _eventData = this._eventData; + var _eventContainer = this._eventContainer; - get: function () - { - return this.currentConfig.detune; - }, + _eventData.cancelled = false; - set: function (value) + var aborted = false; + + if (total > 0) { - this.currentConfig.detune = value; + this.sortGameObjects(justOut, pointer); - if (this.manager.isLocked(this, Events.DETUNE, value)) + // Call onOut for everything in the justOut array + for (i = 0; i < total; i++) { - return; + gameObject = justOut[i]; + + if (!gameObject.input || !gameObject.input.enabled) + { + continue; + } + + // Reset cursor before we emit the event, in case they want to change it during the event + manager.resetCursor(gameObject.input); + + gameObject.emit(Events.GAMEOBJECT_POINTER_OUT, pointer, _eventContainer); + + totalInteracted++; + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } + + this.emit(Events.GAMEOBJECT_OUT, pointer, gameObject, _eventContainer); + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } } - else + + if (!aborted) { - this.calculateRate(); + this.emit(Events.POINTER_OUT, pointer, justOut); + } + } - this.emit(Events.DETUNE, this, value); + // Process the Just Over objects + total = justOver.length; + + _eventData.cancelled = false; + + aborted = false; + + if (total > 0) + { + this.sortGameObjects(justOver, pointer); + + // Call onOver for everything in the justOver array + for (i = 0; i < total; i++) + { + gameObject = justOver[i]; + + if (!gameObject.input || !gameObject.input.enabled) + { + continue; + } + + // Set cursor before we emit the event, in case they want to change it during the event + manager.setCursor(gameObject.input); + + gameObject.emit(Events.GAMEOBJECT_POINTER_OVER, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); + + totalInteracted++; + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } + + this.emit(Events.GAMEOBJECT_OVER, pointer, gameObject, _eventContainer); + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) + { + aborted = true; + break; + } + } + + if (!aborted) + { + this.emit(Events.POINTER_OVER, pointer, justOver); } } + // Add the contents of justOver to the previously over array + previouslyOver = stillOver.concat(justOver); + + // Then sort it into display list order + this._over[pointer.id] = this.sortGameObjects(previouslyOver, pointer); + + return totalInteracted; }, /** - * 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). + * An internal method that handles the Pointer up events. * - * @method Phaser.Sound.HTML5AudioSound#setDetune - * @fires Phaser.Sound.Events#DETUNE - * @since 3.3.0 + * @method Phaser.Input.InputPlugin#processUpEvents + * @private + * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_UP + * @fires Phaser.Input.Events#GAMEOBJECT_UP + * @fires Phaser.Input.Events#POINTER_UP + * @fires Phaser.Input.Events#POINTER_UP_OUTSIDE + * @since 3.0.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). + * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. * - * @return {this} This Sound instance. + * @return {number} The total number of objects interacted with. */ - setDetune: function (value) + processUpEvents: function (pointer) { - this.detune = value; + var currentlyOver = this._temp; - return this; - }, + var _eventData = this._eventData; + var _eventContainer = this._eventContainer; - /** - * 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: { + _eventData.cancelled = false; - get: function () + var aborted = false; + + // Go through all objects the pointer was over and fire their events / callbacks + for (var i = 0; i < currentlyOver.length; i++) { - if (this.isPlaying) + var gameObject = currentlyOver[i]; + + if (!gameObject.input || !gameObject.input.enabled) { - return this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); + continue; } - else if (this.isPaused) + + gameObject.emit(Events.GAMEOBJECT_POINTER_UP, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) { - return this.currentConfig.seek; + aborted = true; + break; } - else + + this.emit(Events.GAMEOBJECT_UP, pointer, gameObject, _eventContainer); + + if (_eventData.cancelled || !gameObject.input || !gameObject.input.enabled) { - return 0; + aborted = true; + break; } - }, + } - set: function (value) + // If they released outside the canvas, but pressed down inside it, we'll still dispatch the event. + if (!aborted && this.manager) { - if (this.manager.isLocked(this, 'seek', value)) + if (pointer.upElement === this.manager.game.canvas) { - return; + this.emit(Events.POINTER_UP, pointer, currentlyOver); } - - if (this.startTime > 0) + else { - return; + this.emit(Events.POINTER_UP_OUTSIDE, pointer); } + } - 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; - } + return currentlyOver.length; + }, - this.emit(Events.SEEK, this, value); - } + /** + * Queues a Game Object for insertion into this Input Plugin on the next update. + * + * @method Phaser.Input.InputPlugin#queueForInsertion + * @private + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} child - The Game Object to add. + * + * @return {this} This InputPlugin object. + */ + queueForInsertion: function (child) + { + if (this._pendingInsertion.indexOf(child) === -1 && this._list.indexOf(child) === -1) + { + this._pendingInsertion.push(child); } + + return this; }, /** - * Seeks to a specific point in this sound. + * Queues a Game Object for removal from this Input Plugin on the next update. * - * @method Phaser.Sound.HTML5AudioSound#setSeek - * @fires Phaser.Sound.Events#SEEK - * @since 3.4.0 + * @method Phaser.Input.InputPlugin#queueForRemoval + * @private + * @since 3.0.0 * - * @param {number} value - The point in the sound to seek to. + * @param {Phaser.GameObjects.GameObject} child - The Game Object to remove. * - * @return {this} This Sound instance. + * @return {this} This InputPlugin object. */ - setSeek: function (value) + queueForRemoval: function (child) { - this.seek = value; + this._pendingRemoval.push(child); return this; }, /** - * Flag indicating whether or not the sound or current sound marker will loop. + * Sets the draggable state of the given array of Game Objects. * - * @name Phaser.Sound.HTML5AudioSound#loop - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#LOOP + * They can either be set to be draggable, or can have their draggable state removed by passing `false`. + * + * A Game Object will not fire drag events unless it has been specifically enabled for drag. + * + * @method Phaser.Input.InputPlugin#setDraggable * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to change the draggable state on. + * @param {boolean} [value=true] - Set to `true` if the Game Objects should be made draggable, `false` if they should be unset. + * + * @return {this} This InputPlugin object. */ - loop: { + setDraggable: function (gameObjects, value) + { + if (value === undefined) { value = true; } - get: function () + if (!Array.isArray(gameObjects)) { - return this.currentConfig.loop; - }, + gameObjects = [ gameObjects ]; + } - set: function (value) + for (var i = 0; i < gameObjects.length; i++) { - this.currentConfig.loop = value; + var gameObject = gameObjects[i]; - if (this.manager.isLocked(this, 'loop', value)) + gameObject.input.draggable = value; + + var index = this._draggable.indexOf(gameObject); + + if (value && index === -1) { - return; + this._draggable.push(gameObject); } - - if (this.audio) + else if (!value && index > -1) { - this.audio.loop = value; + this._draggable.splice(index, 1); } - - this.emit(Events.LOOP, this, value); } + return this; }, /** - * Sets the loop state of this Sound. + * Creates a function that can be passed to `setInteractive`, `enable` or `setHitArea` that will handle + * pixel-perfect input detection on an Image or Sprite based Game Object, or any custom class that extends them. * - * @method Phaser.Sound.HTML5AudioSound#setLoop - * @fires Phaser.Sound.Events#LOOP - * @since 3.4.0 + * The following will create a sprite that is clickable on any pixel that has an alpha value >= 1. * - * @param {boolean} value - `true` to loop this sound, `false` to not loop it. + * ```javascript + * this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect()); + * ``` * - * @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). + * The following will create a sprite that is clickable on any pixel that has an alpha value >= 150. * - * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. + * ```javascript + * this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect(150)); + * ``` * - * @name Phaser.Sound.HTML5AudioSound#pan - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 + * Once you have made an Interactive Object pixel perfect it impacts all input related events for it: down, up, + * dragstart, drag, etc. + * + * As a pointer interacts with the Game Object it will constantly poll the texture, extracting a single pixel from + * the given coordinates and checking its color values. This is an expensive process, so should only be enabled on + * Game Objects that really need it. + * + * You cannot make non-texture based Game Objects pixel perfect. So this will not work on Graphics, BitmapText, + * Render Textures, Text, Tilemaps, Containers or Particles. + * + * @method Phaser.Input.InputPlugin#makePixelPerfect + * @since 3.10.0 + * + * @param {number} [alphaTolerance=1] - The alpha level that the pixel should be above to be included as a successful interaction. + * + * @return {function} A Pixel Perfect Handler for use as a hitArea shape callback. */ - pan: { - - get: function () - { - return this.currentConfig.pan; - }, + makePixelPerfect: function (alphaTolerance) + { + if (alphaTolerance === undefined) { alphaTolerance = 1; } - set: function (value) - { - this.currentConfig.pan = value; + var textureManager = this.systems.textures; - this.emit(Events.PAN, this, value); - } + return CreatePixelPerfectHandler(textureManager, alphaTolerance); }, /** - * Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan). + * Sets the hit area for the given array of Game Objects. * - * Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event. + * A hit area is typically one of the geometric shapes Phaser provides, such as a `Phaser.Geom.Rectangle` + * or `Phaser.Geom.Circle`. However, it can be any object as long as it works with the provided callback. * - * @method Phaser.Sound.HTML5AudioSound#setPan - * @fires Phaser.Sound.Events#PAN - * @since 3.50.0 + * If no hit area is provided a Rectangle is created based on the size of the Game Object, if possible + * to calculate. * - * @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). + * The hit area callback is the function that takes an `x` and `y` coordinate and returns a boolean if + * those values fall within the area of the shape or not. All of the Phaser geometry objects provide this, + * such as `Phaser.Geom.Rectangle.Contains`. * - * @return {this} This Sound instance. + * @method Phaser.Input.InputPlugin#setHitArea + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set the hit area on. + * @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. + * @param {Phaser.Types.Input.HitAreaCallback} [hitAreaCallback] - The 'contains' function to invoke to check if the pointer is within the hit area. + * + * @return {this} This InputPlugin object. */ - setPan: function (value) + setHitArea: function (gameObjects, hitArea, hitAreaCallback) { - this.pan = value; + if (hitArea === undefined) + { + return this.setHitAreaFromTexture(gameObjects); + } - return this; - } + if (!Array.isArray(gameObjects)) + { + gameObjects = [ gameObjects ]; + } -}); + var draggable = false; + var dropZone = false; + var cursor = false; + var useHandCursor = false; + var pixelPerfect = false; + var customHitArea = true; -module.exports = HTML5AudioSound; + // Config object? + if (IsPlainObject(hitArea)) + { + var config = hitArea; + hitArea = GetFastValue(config, 'hitArea', null); + hitAreaCallback = GetFastValue(config, 'hitAreaCallback', null); + draggable = GetFastValue(config, 'draggable', false); + dropZone = GetFastValue(config, 'dropZone', false); + cursor = GetFastValue(config, 'cursor', false); + useHandCursor = GetFastValue(config, 'useHandCursor', false); -/***/ }), -/* 430 */ -/***/ (function(module, exports, __webpack_require__) { + pixelPerfect = GetFastValue(config, 'pixelPerfect', false); + var alphaTolerance = GetFastValue(config, 'alphaTolerance', 1); -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (pixelPerfect) + { + hitArea = {}; + hitAreaCallback = this.makePixelPerfect(alphaTolerance); + } -var BaseSoundManager = __webpack_require__(145); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var NoAudioSound = __webpack_require__(431); -var NOOP = __webpack_require__(1); + // Still no hitArea or callback? + if (!hitArea || !hitAreaCallback) + { + this.setHitAreaFromTexture(gameObjects); + customHitArea = false; + } + } + else if (typeof hitArea === 'function' && !hitAreaCallback) + { + hitAreaCallback = hitArea; + hitArea = {}; + } -/** - * @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); + for (var i = 0; i < gameObjects.length; i++) + { + var gameObject = gameObjects[i]; - this.game = game; - this.sounds = []; - this.mute = false; - this.volume = 1; - this.rate = 1; - this.detune = 0; - this.pauseOnBlur = true; - this.locked = false; - }, + if (pixelPerfect && gameObject.type === 'Container') + { + console.warn('Cannot pixelPerfect test a Container. Use a custom callback.'); + continue; + } - add: function (key, config) - { - var sound = new NoAudioSound(this, key, config); + var io = (!gameObject.input) ? CreateInteractiveObject(gameObject, hitArea, hitAreaCallback) : gameObject.input; - this.sounds.push(sound); + io.customHitArea = customHitArea; + io.dropZone = dropZone; + io.cursor = (useHandCursor) ? 'pointer' : cursor; - return sound; - }, + gameObject.input = io; - addAudioSprite: function (key, config) - { - var sound = this.add(key, config); + if (draggable) + { + this.setDraggable(gameObject); + } - sound.spritemap = {}; + this.queueForInsertion(gameObject); + } - return sound; + return this; }, - // eslint-disable-next-line no-unused-vars - play: function (key, extra) + /** + * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Circle` shape, using + * the given coordinates and radius to control its position and size. + * + * @method Phaser.Input.InputPlugin#setHitAreaCircle + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a circle hit area. + * @param {number} x - The center of the circle. + * @param {number} y - The center of the circle. + * @param {number} radius - The radius of the circle. + * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Circle.Contains. + * + * @return {this} This InputPlugin object. + */ + setHitAreaCircle: function (gameObjects, x, y, radius, callback) { - return false; - }, + if (callback === undefined) { callback = CircleContains; } - // eslint-disable-next-line no-unused-vars - playAudioSprite: function (key, spriteName, config) - { - return false; - }, + var shape = new Circle(x, y, radius); - remove: function (sound) - { - return BaseSoundManager.prototype.remove.call(this, sound); + return this.setHitArea(gameObjects, shape, callback); }, - removeByKey: function (key) + /** + * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Ellipse` shape, using + * the given coordinates and dimensions to control its position and size. + * + * @method Phaser.Input.InputPlugin#setHitAreaEllipse + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having an ellipse hit area. + * @param {number} x - The center of the ellipse. + * @param {number} y - The center of the ellipse. + * @param {number} width - The width of the ellipse. + * @param {number} height - The height of the ellipse. + * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Ellipse.Contains. + * + * @return {this} This InputPlugin object. + */ + setHitAreaEllipse: function (gameObjects, x, y, width, height, callback) { - return BaseSoundManager.prototype.removeByKey.call(this, key); - }, + if (callback === undefined) { callback = EllipseContains; } - pauseAll: NOOP, - resumeAll: NOOP, - stopAll: NOOP, - update: NOOP, - setRate: NOOP, - setDetune: NOOP, - setMute: NOOP, - setVolume: NOOP, + var shape = new Ellipse(x, y, width, height); - forEachActiveSound: function (callbackfn, scope) - { - BaseSoundManager.prototype.forEachActiveSound.call(this, callbackfn, scope); + return this.setHitArea(gameObjects, shape, callback); }, - destroy: function () + /** + * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Rectangle` shape, using + * the Game Objects texture frame to define the position and size of the hit area. + * + * @method Phaser.Input.InputPlugin#setHitAreaFromTexture + * @since 3.0.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having an ellipse hit area. + * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Rectangle.Contains. + * + * @return {this} This InputPlugin object. + */ + setHitAreaFromTexture: function (gameObjects, callback) { - BaseSoundManager.prototype.destroy.call(this); - } - -}); - -module.exports = NoAudioSoundManager; - - -/***/ }), -/* 431 */ -/***/ (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__(146); -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; -}; + if (callback === undefined) { callback = RectangleContains; } -var returnThis = function () -{ - return this; -}; + if (!Array.isArray(gameObjects)) + { + gameObjects = [ gameObjects ]; + } -/** - * @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({ + for (var i = 0; i < gameObjects.length; i++) + { + var gameObject = gameObjects[i]; - Extends: EventEmitter, + var frame = gameObject.frame; - initialize: + var width = 0; + var height = 0; - function NoAudioSound (manager, key, config) - { - if (config === void 0) { config = {}; } + if (gameObject.width) + { + width = gameObject.width; + height = gameObject.height; + } + else if (frame) + { + width = frame.realWidth; + height = frame.realHeight; + } - EventEmitter.call(this); + if (gameObject.type === 'Container' && (width === 0 || height === 0)) + { + console.warn('Container.setInteractive must specify a Shape or call setSize() first'); + continue; + } - this.manager = manager; - this.key = key; - this.isPlaying = false; - this.isPaused = false; - this.totalRate = 1; - this.duration = 0; - this.totalDuration = 0; + if (width !== 0 && height !== 0) + { + gameObject.input = CreateInteractiveObject(gameObject, new Rectangle(0, 0, width, height), callback); - this.config = Extend({ - mute: false, - volume: 1, - rate: 1, - detune: 0, - seek: 0, - loop: false, - delay: 0, - pan: 0 - }, config); + this.queueForInsertion(gameObject); + } + } - 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; + return this; }, /** - * @method Phaser.Sound.NoAudioSound#addMarker + * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Rectangle` shape, using + * the given coordinates and dimensions to control its position and size. + * + * @method Phaser.Input.InputPlugin#setHitAreaRectangle * @since 3.0.0 * - * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object. + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a rectangular hit area. + * @param {number} x - The top-left of the rectangle. + * @param {number} y - The top-left of the rectangle. + * @param {number} width - The width of the rectangle. + * @param {number} height - The height of the rectangle. + * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Rectangle.Contains. * - * @return {boolean} false + * @return {this} This InputPlugin object. */ - addMarker: returnFalse, + setHitAreaRectangle: function (gameObjects, x, y, width, height, callback) + { + if (callback === undefined) { callback = RectangleContains; } + + var shape = new Rectangle(x, y, width, height); + + return this.setHitArea(gameObjects, shape, callback); + }, /** - * @method Phaser.Sound.NoAudioSound#updateMarker + * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Triangle` shape, using + * the given coordinates to control the position of its points. + * + * @method Phaser.Input.InputPlugin#setHitAreaTriangle * @since 3.0.0 * - * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object with updated values. + * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a triangular hit area. + * @param {number} x1 - The x coordinate of the first point of the triangle. + * @param {number} y1 - The y coordinate of the first point of the triangle. + * @param {number} x2 - The x coordinate of the second point of the triangle. + * @param {number} y2 - The y coordinate of the second point of the triangle. + * @param {number} x3 - The x coordinate of the third point of the triangle. + * @param {number} y3 - The y coordinate of the third point of the triangle. + * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Triangle.Contains. * - * @return {boolean} false + * @return {this} This InputPlugin object. */ - updateMarker: returnFalse, + setHitAreaTriangle: function (gameObjects, x1, y1, x2, y2, x3, y3, callback) + { + if (callback === undefined) { callback = TriangleContains; } + + var shape = new Triangle(x1, y1, x2, y2, x3, y3); + + return this.setHitArea(gameObjects, shape, callback); + }, /** - * @method Phaser.Sound.NoAudioSound#removeMarker - * @since 3.0.0 + * Creates an Input Debug Shape for the given Game Object. * - * @param {string} markerName - The name of the marker to remove. + * The Game Object must have _already_ been enabled for input prior to calling this method. * - * @return {null} null - */ - removeMarker: returnNull, - - /** - * @method Phaser.Sound.NoAudioSound#play - * @since 3.0.0 + * This is intended to assist you during development and debugging. * - * @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. + * Debug Shapes can only be created for Game Objects that are using standard Phaser Geometry for input, + * including: Circle, Ellipse, Line, Polygon, Rectangle and Triangle. * - * @return {boolean} false - */ - play: returnFalse, - - /** - * @method Phaser.Sound.NoAudioSound#pause - * @since 3.0.0 + * Game Objects that are using their automatic hit areas are using Rectangles by default, so will also work. * - * @return {boolean} false - */ - pause: returnFalse, - - /** - * Resumes the sound. + * The Debug Shape is created and added to the display list and is then kept in sync with the Game Object + * it is connected with. Should you need to modify it yourself, such as to hide it, you can access it via + * the Game Object property: `GameObject.input.hitAreaDebug`. * - * @method Phaser.Sound.NoAudioSound#resume - * @since 3.0.0 + * Calling this method on a Game Object that already has a Debug Shape will first destroy the old shape, + * before creating a new one. If you wish to remove the Debug Shape entirely, you should call the + * method `InputPlugin.removeDebug`. * - * @return {boolean} false - */ - resume: returnFalse, - - /** - * Stop playing this sound. + * Note that the debug shape will only show the outline of the input area. If the input test is using a + * pixel perfect check, for example, then this is not displayed. If you are using a custom shape, that + * doesn't extend one of the base Phaser Geometry objects, as your hit area, then this method will not + * work. * - * @method Phaser.Sound.NoAudioSound#stop - * @since 3.0.0 + * @method Phaser.Input.InputPlugin#enableDebug + * @since 3.19.0 * - * @return {boolean} false - */ - stop: returnFalse, - - /** - * Destroys this sound and all associated events and marks it for removal from the sound manager. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to create the input debug shape for. + * @param {number} [color=0x00ff00] - The outline color of the debug shape. * - * @method Phaser.Sound.NoAudioSound#destroy - * @fires Phaser.Sound.Events#DESTROY - * @since 3.0.0 + * @return {this} This Input Plugin. */ - destroy: function () + enableDebug: function (gameObject, color) { - BaseSound.prototype.destroy.call(this); - }, - - setMute: returnThis, - - setVolume: returnThis, - - setRate: returnThis, + if (color === undefined) { color = 0x00ff00; } - setDetune: returnThis, + var input = gameObject.input; - setSeek: returnThis, + if (!input || !input.hitArea) + { + return this; + } - setLoop: returnThis, + var shape = input.hitArea; + var shapeType = shape.type; + var debug = input.hitAreaDebug; + var factory = this.systems.add; + var updateList = this.systems.updateList; - setPan: returnThis + if (debug) + { + updateList.remove(debug); -}); + debug.destroy(); -module.exports = NoAudioSound; + debug = null; + } + var offsetx = 0; + var offsety = 0; -/***/ }), -/* 432 */ -/***/ (function(module, exports, __webpack_require__) { + switch (shapeType) + { + case GEOM_CONST.CIRCLE: + debug = factory.arc(0, 0, shape.radius); + offsetx = shape.x - shape.radius; + offsety = shape.y - shape.radius; + break; -/** - * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + case GEOM_CONST.ELLIPSE: + debug = factory.ellipse(0, 0, shape.width, shape.height); + offsetx = shape.x - shape.width / 2; + offsety = shape.y - shape.height / 2; + break; -var Base64ToArrayBuffer = __webpack_require__(433); -var BaseSoundManager = __webpack_require__(145); -var Class = __webpack_require__(0); -var Events = __webpack_require__(70); -var GameEvents = __webpack_require__(22); -var WebAudioSound = __webpack_require__(434); + case GEOM_CONST.LINE: + debug = factory.line(0, 0, shape.x1, shape.y1, shape.x2, shape.y2); + break; -/** - * @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({ + case GEOM_CONST.POLYGON: + debug = factory.polygon(0, 0, shape.points); + break; - Extends: BaseSoundManager, + case GEOM_CONST.RECTANGLE: + debug = factory.rectangle(0, 0, shape.width, shape.height); + offsetx = shape.x; + offsety = shape.y; + break; - initialize: + case GEOM_CONST.TRIANGLE: + debug = factory.triangle(0, 0, shape.x1, shape.y1, shape.x2, shape.y2, shape.x3, shape.y3); + break; + } - function WebAudioSoundManager (game) - { - /** - * The AudioContext being used for playback. - * - * @name Phaser.Sound.WebAudioSoundManager#context - * @type {AudioContext} - * @since 3.0.0 - */ - this.context = this.createAudioContext(game); + if (debug) + { + debug.isFilled = false; + debug.strokeColor = color; - /** - * Gain node responsible for controlling global muting. - * - * @name Phaser.Sound.WebAudioSoundManager#masterMuteNode - * @type {GainNode} - * @since 3.0.0 - */ - this.masterMuteNode = this.context.createGain(); + debug.preUpdate = function () + { + debug.setStrokeStyle(1 / gameObject.scale, debug.strokeColor); - /** - * Gain node responsible for controlling global volume. - * - * @name Phaser.Sound.WebAudioSoundManager#masterVolumeNode - * @type {GainNode} - * @since 3.0.0 - */ - this.masterVolumeNode = this.context.createGain(); + debug.setDisplayOrigin(gameObject.displayOriginX, gameObject.displayOriginY); - this.masterMuteNode.connect(this.masterVolumeNode); + var x = gameObject.x; + var y = gameObject.y; + var rotation = gameObject.rotation; + var scaleX = gameObject.scaleX; + var scaleY = gameObject.scaleY; - this.masterVolumeNode.connect(this.context.destination); + if (gameObject.parentContainer) + { + var matrix = gameObject.getWorldTransformMatrix(); - /** - * Destination node for connecting individual sounds to. - * - * @name Phaser.Sound.WebAudioSoundManager#destination - * @type {AudioNode} - * @since 3.0.0 - */ - this.destination = this.masterMuteNode; + x = matrix.tx; + y = matrix.ty; + rotation = matrix.rotation; + scaleX = matrix.scaleX; + scaleY = matrix.scaleY; + } - this.locked = this.context.state === 'suspended' && ('ontouchstart' in window || 'onclick' in window); + debug.setRotation(rotation); + debug.setScale(scaleX, scaleY); + debug.setPosition(x + offsetx * scaleX, y + offsety * scaleY); + debug.setScrollFactor(gameObject.scrollFactorX, gameObject.scrollFactorY); + debug.setDepth(gameObject.depth); + }; - BaseSoundManager.call(this, game); + updateList.add(debug); - if (this.locked && game.isBooted) - { - this.unlock(); - } - else - { - game.events.once(GameEvents.BOOT, this.unlock, this); + input.hitAreaDebug = debug; } + + return 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. + * Removes an Input Debug Shape from the given Game Object. * - * @method Phaser.Sound.WebAudioSoundManager#createAudioContext - * @since 3.0.0 + * The shape is destroyed immediately and the `hitAreaDebug` property is set to `null`. * - * @param {Phaser.Game} game - Reference to the current game instance. + * @method Phaser.Input.InputPlugin#removeDebug + * @since 3.19.0 * - * @return {AudioContext} The AudioContext instance to be used for playback. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to remove the input debug shape from. + * + * @return {this} This Input Plugin. */ - createAudioContext: function (game) + removeDebug: function (gameObject) { - var audioConfig = game.config.audio; + var input = gameObject.input; - if (audioConfig.context) + if (input && input.hitAreaDebug) { - audioConfig.context.resume(); + var debug = input.hitAreaDebug; - return audioConfig.context; - } + this.systems.updateList.remove(debug); - if (window.hasOwnProperty('AudioContext')) - { - return new AudioContext(); - } - else if (window.hasOwnProperty('webkitAudioContext')) - { - return new window.webkitAudioContext(); + debug.destroy(); + + input.hitAreaDebug = null; } + + return this; }, /** - * This method takes a new AudioContext reference and then sets - * this Sound Manager to use that context for all playback. + * Sets the Pointers to always poll. * - * As part of this call it also disconnects the master mute and volume - * nodes and then re-creates them on the new given context. + * When a pointer is polled it runs a hit test to see which Game Objects are currently below it, + * or being interacted with it, regardless if the Pointer has actually moved or not. * - * @method Phaser.Sound.WebAudioSoundManager#setAudioContext - * @since 3.21.0 + * You should enable this if you want objects in your game to fire over / out events, and the objects + * are constantly moving, but the pointer may not have. Polling every frame has additional computation + * costs, especially if there are a large number of interactive objects in your game. * - * @param {AudioContext} context - Reference to an already created AudioContext instance. + * @method Phaser.Input.InputPlugin#setPollAlways + * @since 3.0.0 * - * @return {this} The WebAudioSoundManager instance. + * @return {this} This InputPlugin object. */ - setAudioContext: function (context) + setPollAlways: function () { - 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; + return this.setPollRate(0); }, /** - * Adds a new sound into the sound manager. + * Sets the Pointers to only poll when they are moved or updated. * - * @method Phaser.Sound.WebAudioSoundManager#add - * @since 3.0.0 + * When a pointer is polled it runs a hit test to see which Game Objects are currently below it, + * or being interacted with it. * - * @param {string} key - Asset key for the sound. - * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. + * @method Phaser.Input.InputPlugin#setPollOnMove + * @since 3.0.0 * - * @return {Phaser.Sound.WebAudioSound} The new sound instance. + * @return {this} This InputPlugin object. */ - add: function (key, config) + setPollOnMove: function () { - var sound = new WebAudioSound(this, key, config); - - this.sounds.push(sound); - - return sound; + return this.setPollRate(-1); }, /** - * 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. + * Sets the poll rate value. This is the amount of time that should have elapsed before a pointer + * will be polled again. See the `setPollAlways` and `setPollOnMove` methods. * - * Once the audio has decoded it can be added to the Sound Manager or played via its key. + * @method Phaser.Input.InputPlugin#setPollRate + * @since 3.0.0 * - * @method Phaser.Sound.WebAudioSoundManager#decodeAudio - * @fires Phaser.Sound.Events#DECODED - * @fires Phaser.Sound.Events#DECODED_ALL - * @since 3.18.0 + * @param {number} value - The amount of time, in ms, that should elapsed before re-polling the pointers. * - * @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. + * @return {this} This InputPlugin object. */ - decodeAudio: function (audioKey, audioData) + setPollRate: function (value) { - 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.pollRate = value; + this._pollTimer = 0; - this.context.decodeAudioData(data, success, failure); - } + return this; }, /** - * 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). + * When set to `true` the global Input Manager will emulate DOM behavior by only emitting events from + * the top-most Scene in the Scene List. By default, if a Scene receives an input event it will then stop the event + * from flowing down to any Scenes below it in the Scene list. To disable this behavior call this method with `false`. * - * @method Phaser.Sound.WebAudioSoundManager#unlock + * @method Phaser.Input.InputPlugin#setGlobalTopOnly * @since 3.0.0 + * + * @param {boolean} value - Set to `true` to stop processing input events on the Scene that receives it, or `false` to let the event continue down the Scene list. + * + * @return {this} This InputPlugin object. */ - unlock: function () + setGlobalTopOnly: function (value) { - var _this = this; - - var body = document.body; - - var unlockHandler = function unlockHandler () - { - if (_this.context && body) - { - var bodyRemove = body.removeEventListener; - - _this.context.resume().then(function () - { - bodyRemove('touchstart', unlockHandler); - bodyRemove('touchend', unlockHandler); - bodyRemove('click', unlockHandler); - bodyRemove('keydown', unlockHandler); - - _this.unlocked = true; - }, function () - { - bodyRemove('touchstart', unlockHandler); - bodyRemove('touchend', unlockHandler); - bodyRemove('click', unlockHandler); - bodyRemove('keydown', unlockHandler); - }); - } - }; + this.manager.globalTopOnly = value; - if (body) - { - body.addEventListener('touchstart', unlockHandler, false); - body.addEventListener('touchend', unlockHandler, false); - body.addEventListener('click', unlockHandler, false); - body.addEventListener('keydown', unlockHandler, false); - } + return this; }, /** - * Method used internally for pausing sound manager if - * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. + * When set to `true` this Input Plugin will emulate DOM behavior by only emitting events from + * the top-most Game Objects in the Display List. * - * @method Phaser.Sound.WebAudioSoundManager#onBlur - * @protected + * If set to `false` it will emit events from all Game Objects below a Pointer, not just the top one. + * + * @method Phaser.Input.InputPlugin#setTopOnly * @since 3.0.0 + * + * @param {boolean} value - `true` to only include the top-most Game Object, or `false` to include all Game Objects in a hit test. + * + * @return {this} This InputPlugin object. */ - onBlur: function () + setTopOnly: function (value) { - if (!this.locked) - { - this.context.suspend(); - } + this.topOnly = value; + + return this; }, /** - * Method used internally for resuming sound manager if - * Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true. + * Given an array of Game Objects and a Pointer, sort the array and return it, + * so that the objects are in render order with the lowest at the bottom. * - * @method Phaser.Sound.WebAudioSoundManager#onFocus - * @protected + * @method Phaser.Input.InputPlugin#sortGameObjects * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject[]} gameObjects - An array of Game Objects to be sorted. + * @param {Phaser.Input.Pointer} pointer - The Pointer to check against the Game Objects. + * + * @return {Phaser.GameObjects.GameObject[]} The sorted array of Game Objects. */ - onFocus: function () + sortGameObjects: function (gameObjects, pointer) { - var context = this.context; - - if ((context.state === 'suspended' || context.state === 'interrupted') && !this.locked) + if (gameObjects.length < 2 || !pointer.camera) { - context.resume(); + return gameObjects; } + + var list = pointer.camera.renderList; + + return gameObjects.sort(function (childA, childB) + { + var indexA = Math.max(list.indexOf(childA), 0); + var indexB = Math.max(list.indexOf(childB), 0); + + return indexB - indexA; + }); }, /** - * Update method called on every game step. - * Removes destroyed sounds and updates every active sound in the game. + * Given an array of Drop Zone Game Objects, sort the array and return it, + * so that the objects are in depth index order with the lowest at the bottom. * - * @method Phaser.Sound.WebAudioSoundManager#update - * @protected - * @fires Phaser.Sound.Events#UNLOCKED - * @since 3.0.0 + * @method Phaser.Input.InputPlugin#sortDropZones + * @since 3.52.0 * - * @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param {number} delta - The delta time elapsed since the last frame. + * @param {Phaser.GameObjects.GameObject[]} gameObjects - An array of Game Objects to be sorted. + * + * @return {Phaser.GameObjects.GameObject[]} The sorted array of Game Objects. */ - update: function (time, delta) + sortDropZones: function (gameObjects) { - BaseSoundManager.prototype.update.call(this, time, delta); - - var context = this.context; - - // Resume interrupted audio on iOS - if (context && context.state === 'interrupted') + if (gameObjects.length < 2) { - context.resume(); + return gameObjects; } + + this.scene.sys.depthSort(); + + return gameObjects.sort(this.sortDropZoneHandler.bind(this)); }, /** - * Calls Phaser.Sound.BaseSoundManager#destroy method - * and cleans up all Web Audio API related stuff. + * Return the child lowest down the display list (with the smallest index) + * Will iterate through all parent containers, if present. * - * @method Phaser.Sound.WebAudioSoundManager#destroy - * @since 3.0.0 + * Prior to version 3.52.0 this method was called `sortHandlerGO`. + * + * @method Phaser.Input.InputPlugin#sortDropZoneHandler + * @private + * @since 3.52.0 + * + * @param {Phaser.GameObjects.GameObject} childA - The first Game Object to compare. + * @param {Phaser.GameObjects.GameObject} childB - The second Game Object to compare. + * + * @return {number} Returns either a negative or positive integer, or zero if they match. */ - destroy: function () + sortDropZoneHandler: function (childA, childB) { - this.destination = null; - this.masterVolumeNode.disconnect(); - this.masterVolumeNode = null; - this.masterMuteNode.disconnect(); - this.masterMuteNode = null; - - if (this.game.config.audio.context) + if (!childA.parentContainer && !childB.parentContainer) { - this.context.suspend(); + // Quick bail out when neither child has a container + return this.displayList.getIndex(childB) - this.displayList.getIndex(childA); + } + else if (childA.parentContainer === childB.parentContainer) + { + // Quick bail out when both children have the same container + return childB.parentContainer.getIndex(childB) - childA.parentContainer.getIndex(childA); + } + else if (childA.parentContainer === childB) + { + // Quick bail out when childA is a child of childB + return -1; + } + else if (childB.parentContainer === childA) + { + // Quick bail out when childA is a child of childB + return 1; } else { - var _this = this; + // Container index check + var listA = childA.getIndexList(); + var listB = childB.getIndexList(); + var len = Math.min(listA.length, listB.length); - this.context.close().then(function () + for (var i = 0; i < len; i++) { - _this.context = null; - }); + var indexA = listA[i]; + var indexB = listB[i]; + + if (indexA === indexB) + { + // Go to the next level down + continue; + } + else + { + // Non-matching parents, so return + return indexB - indexA; + } + } + + return listB.length - listA.length; } - BaseSoundManager.prototype.destroy.call(this); + // Technically this shouldn't happen, but ... + // eslint-disable-next-line no-unreachable + return 0; }, /** - * Sets the muted state of all this Sound Manager. + * This method should be called from within an input event handler, such as `pointerdown`. * - * @method Phaser.Sound.WebAudioSoundManager#setMute - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.3.0 + * When called, it stops the Input Manager from allowing _this specific event_ to be processed by any other Scene + * not yet handled in the scene list. * - * @param {boolean} value - `true` to mute all sounds, `false` to unmute them. + * @method Phaser.Input.InputPlugin#stopPropagation + * @since 3.0.0 * - * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. + * @return {this} This InputPlugin object. */ - setMute: function (value) + stopPropagation: function () { - this.mute = value; + this.manager._tempSkip = true; return this; }, /** - * @name Phaser.Sound.WebAudioSoundManager#mute - * @type {boolean} - * @fires Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.0.0 + * 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.InputPlugin#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. */ - 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); - } - + addPointer: function (quantity) + { + return this.manager.addPointer(quantity); }, /** - * Sets the volume of this Sound Manager. + * Tells the Input system to set a custom cursor. * - * @method Phaser.Sound.WebAudioSoundManager#setVolume - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.3.0 + * This cursor will be the default cursor used when interacting with the game canvas. * - * @param {number} value - The global volume of this Sound Manager. + * If an Interactive Object also sets a custom cursor, this is the cursor that is reset after its use. * - * @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager. + * 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.InputPlugin#setDefaultCursor + * @since 3.10.0 + * + * @param {string} cursor - The CSS to be used when setting the default cursor. + * + * @return {this} This Input instance. */ - setVolume: function (value) + setDefaultCursor: function (cursor) { - this.volume = value; + this.manager.setDefaultCursor(cursor); return this; }, /** - * @name Phaser.Sound.WebAudioSoundManager#volume - * @type {number} - * @fires Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.0.0 + * The Scene that owns this plugin is transitioning in. + * + * @method Phaser.Input.InputPlugin#transitionIn + * @private + * @since 3.5.0 */ - volume: { + transitionIn: function () + { + this.enabled = this.settings.transitionAllowInput; + }, - get: function () + /** + * The Scene that owns this plugin has finished transitioning in. + * + * @method Phaser.Input.InputPlugin#transitionComplete + * @private + * @since 3.5.0 + */ + transitionComplete: function () + { + if (!this.settings.transitionAllowInput) { - return this.masterVolumeNode.gain.value; - }, - - set: function (value) - { - this.masterVolumeNode.gain.setValueAtTime(value, 0); - - this.emit(Events.GLOBAL_VOLUME, this, value); - } - - } - -}); - -module.exports = WebAudioSoundManager; - - -/***/ }), -/* 433 */ -/***/ (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; - - -/***/ }), -/* 434 */ -/***/ (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__(146); -var Class = __webpack_require__(0); -var Events = __webpack_require__(70); - -/** - * @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} - * @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} - * @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} - * @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} - * @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} - * @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} - * @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} - * @readonly - * @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} - * @readonly - * @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); - }, + this.enabled = true; + } + }, /** - * 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. + * The Scene that owns this plugin is transitioning out. * - * @return {boolean} Whether the sound started playing successfully. + * @method Phaser.Input.InputPlugin#transitionOut + * @private + * @since 3.5.0 */ - play: function (markerName, config) + transitionOut: function () { - 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; + this.enabled = this.settings.transitionAllowInput; }, /** - * Pauses the sound. + * The Scene that owns this plugin is shutting down. + * We need to kill and reset all internal properties as well as stop listening to Scene events. * - * @method Phaser.Sound.WebAudioSound#pause - * @fires Phaser.Sound.Events#PAUSE + * @method Phaser.Input.InputPlugin#shutdown + * @fires Phaser.Input.Events#SHUTDOWN + * @private * @since 3.0.0 - * - * @return {boolean} Whether the sound was paused successfully. */ - pause: function () + shutdown: function () { - if (this.manager.context.currentTime < this.startTime) - { - return false; - } + // Registered input plugins listen for this + this.pluginEvents.emit(Events.SHUTDOWN); - if (!BaseSound.prototype.pause.call(this)) + this._temp.length = 0; + this._list.length = 0; + this._draggable.length = 0; + this._pendingRemoval.length = 0; + this._pendingInsertion.length = 0; + this._dragState.length = 0; + + for (var i = 0; i < 10; i++) { - return false; + this._drag[i] = []; + this._over[i] = []; } - // \/\/\/ isPlaying = false, isPaused = true \/\/\/ - this.currentConfig.seek = this.getCurrentTime(); // Equivalent to setting paused time - this.stopAndRemoveBufferSource(); - - this.emit(Events.PAUSE, this); + this.removeAllListeners(); - return true; - }, + var manager = this.manager; - /** - * 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; - } + manager.canvas.style.cursor = manager.defaultCursor; - if (!BaseSound.prototype.resume.call(this)) - { - return false; - } + var eventEmitter = this.systems.events; - // \/\/\/ isPlaying = true, isPaused = false \/\/\/ - this.createAndStartBufferSource(); + eventEmitter.off(SceneEvents.TRANSITION_START, this.transitionIn, this); + eventEmitter.off(SceneEvents.TRANSITION_OUT, this.transitionOut, this); + eventEmitter.off(SceneEvents.TRANSITION_COMPLETE, this.transitionComplete, this); + eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this); - this.emit(Events.RESUME, this); + manager.events.off(Events.GAME_OUT, this.onGameOut, this); + manager.events.off(Events.GAME_OVER, this.onGameOver, this); - return true; + eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * Stop playing this sound. + * Loops through all of the Input Manager Pointer instances and calls `reset` on them. * - * @method Phaser.Sound.WebAudioSound#stop - * @fires Phaser.Sound.Events#STOP - * @since 3.0.0 + * Use this function if you find that input has been stolen from Phaser via a 3rd + * party component, such as Vue, and you need to tell Phaser to reset the Pointer states. * - * @return {boolean} Whether the sound was stopped successfully. + * @method Phaser.Input.InputPlugin#resetPointers + * @since 3.60.0 */ - stop: function () + resetPointers: function () { - if (!BaseSound.prototype.stop.call(this)) + var pointers = this.manager.pointers; + + for (var i = 0; i < pointers.length; i++) { - return false; + pointers[i].reset(); } - - // \/\/\/ isPlaying = false, isPaused = false \/\/\/ - this.stopAndRemoveBufferSource(); - - this.emit(Events.STOP, this); - - return true; }, /** - * Used internally. + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. * - * @method Phaser.Sound.WebAudioSound#createAndStartBufferSource + * @method Phaser.Input.InputPlugin#destroy + * @fires Phaser.Input.Events#DESTROY * @private * @since 3.0.0 */ - createAndStartBufferSource: function () + destroy: 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.shutdown(); - this.source.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); + // Registered input plugins listen for this + this.pluginEvents.emit(Events.DESTROY); - this.resetConfig(); - }, + this.pluginEvents.removeAllListeners(); - /** - * 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.scene.sys.events.off(SceneEvents.START, this.start, this); - 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)); + this.scene = null; + this.cameras = null; + this.manager = null; + this.events = null; + this.mouse = null; }, /** - * Used internally. + * The x coordinates of the ActivePointer based on the first camera in the camera list. + * This is only safe to use if your game has just 1 non-transformed camera and doesn't use multi-touch. * - * @method Phaser.Sound.WebAudioSound#createBufferSource - * @private + * @name Phaser.Input.InputPlugin#x + * @type {number} + * @readonly * @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); + x: { - source.onended = function (ev) + get: function () { - if (ev.target === _this.source) - { - // sound ended - if (_this.currentConfig.loop) - { - _this.hasLooped = true; - } - else - { - _this.hasEnded = true; - } - } - - // else was stopped - }; + return this.manager.activePointer.x; + } - return source; }, /** - * Used internally. + * The y coordinates of the ActivePointer based on the first camera in the camera list. + * This is only safe to use if your game has just 1 non-transformed camera and doesn't use multi-touch. * - * @method Phaser.Sound.WebAudioSound#stopAndRemoveBufferSource - * @private + * @name Phaser.Input.InputPlugin#y + * @type {number} + * @readonly * @since 3.0.0 */ - stopAndRemoveBufferSource: function () - { - if (this.source) + y: { + + get: function () { - this.source.stop(); - this.source.disconnect(); - this.source = null; + return this.manager.activePointer.y; } - this.playTime = 0; - this.startTime = 0; - - this.stopAndRemoveLoopBufferSource(); }, /** - * Used internally. + * Are any mouse or touch pointers currently over the game canvas? * - * @method Phaser.Sound.WebAudioSound#stopAndRemoveLoopBufferSource - * @private - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#isOver + * @type {boolean} + * @readonly + * @since 3.16.0 */ - stopAndRemoveLoopBufferSource: function () - { - if (this.loopSource) + isOver: { + + get: function () { - this.loopSource.stop(); - this.loopSource.disconnect(); - this.loopSource = null; + return this.manager.isOver; } - this.loopTime = 0; }, /** - * Method used internally for applying config values to some of the sound properties. + * 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. * - * @method Phaser.Sound.WebAudioSound#applyConfig - * @protected - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#mousePointer + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - applyConfig: function () - { - this.rateUpdates.length = 0; - - this.rateUpdates.push({ - time: 0, - rate: 1 - }); - - BaseSound.prototype.applyConfig.call(this); - }, + mousePointer: { - /** - * 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) + get: function () { - this.hasEnded = false; - - BaseSound.prototype.stop.call(this); - - this.stopAndRemoveBufferSource(); - - this.emit(Events.COMPLETE, this); + return this.manager.mousePointer; } - 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. + * The current active input Pointer. * - * @method Phaser.Sound.WebAudioSound#destroy + * @name Phaser.Input.InputPlugin#activePointer + * @type {Phaser.Input.Pointer} + * @readonly * @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; + activePointer: { - if (this.pannerNode) + get: function () { - this.pannerNode.disconnect(); - this.pannerNode = null; + return this.manager.activePointer; } - this.rateUpdates.length = 0; - this.rateUpdates = null; }, /** - * Method used internally to calculate total playback rate of the sound. + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @method Phaser.Sound.WebAudioSound#calculateRate - * @protected - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#pointer1 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - calculateRate: function () - { - BaseSound.prototype.calculateRate.call(this); - - var now = this.manager.context.currentTime; + pointer1: { - if (this.source && typeof this.totalRate === 'number') + get: function () { - this.source.playbackRate.setValueAtTime(this.totalRate, now); + return this.manager.pointers[1]; } - 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. + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @method Phaser.Sound.WebAudioSound#getCurrentTime - * @private - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#pointer2 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - getCurrentTime: function () - { - var currentTime = 0; + pointer2: { - for (var i = 0; i < this.rateUpdates.length; i++) + get: function () { - 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 this.manager.pointers[2]; } - return currentTime; }, /** - * Method used internally for calculating the time - * at witch the loop source should start playing. + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @method Phaser.Sound.WebAudioSound#getLoopTime - * @private - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#pointer3 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - getLoopTime: function () - { - var lastRateUpdateCurrentTime = 0; + pointer3: { - for (var i = 0; i < this.rateUpdates.length - 1; i++) + get: function () { - lastRateUpdateCurrentTime += (this.rateUpdates[i + 1].time - this.rateUpdates[i].time) * this.rateUpdates[i].rate; + return this.manager.pointers[3]; } - 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. + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @name Phaser.Sound.WebAudioSound#rate - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#RATE - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#pointer4 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - rate: { + pointer4: { get: function () { - return this.currentConfig.rate; - }, - - set: function (value) - { - this.currentConfig.rate = value; - - this.calculateRate(); - - this.emit(Events.RATE, this, value); + return this.manager.pointers[4]; } }, /** - * 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). + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @name Phaser.Sound.WebAudioSound#detune - * @type {number} - * @default 0 - * @fires Phaser.Sound.Events#DETUNE - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#pointer5 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - detune: { + pointer5: { get: function () { - return this.currentConfig.detune; - }, - - set: function (value) - { - this.currentConfig.detune = value; - - this.calculateRate(); - - this.emit(Events.DETUNE, this, value); + return this.manager.pointers[5]; } }, /** - * 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). + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @return {this} This Sound instance. + * @name Phaser.Input.InputPlugin#pointer6 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - setDetune: function (value) - { - this.detune = value; + pointer6: { + + get: function () + { + return this.manager.pointers[6]; + } - return this; }, /** - * Boolean indicating whether the sound is muted or not. - * Gets or sets the muted state of this sound. + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @name Phaser.Sound.WebAudioSound#mute - * @type {boolean} - * @default false - * @fires Phaser.Sound.Events#MUTE - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#pointer7 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - mute: { + pointer7: { 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); + return this.manager.pointers[7]; } }, /** - * 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. + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @return {this} This Sound instance. + * @name Phaser.Input.InputPlugin#pointer8 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - setMute: function (value) - { - this.mute = value; + pointer8: { + + get: function () + { + return this.manager.pointers[8]; + } - return this; }, /** - * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @name Phaser.Sound.WebAudioSound#volume - * @type {number} - * @default 1 - * @fires Phaser.Sound.Events#VOLUME - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#pointer9 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - volume: { + pointer9: { 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); + return this.manager.pointers[9]; } - }, - - /** - * 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. + * A touch-based Pointer object. + * This will be `undefined` by default unless you add a new Pointer using `addPointer`. * - * @name Phaser.Sound.WebAudioSound#seek - * @type {number} - * @fires Phaser.Sound.Events#SEEK - * @since 3.0.0 + * @name Phaser.Input.InputPlugin#pointer10 + * @type {Phaser.Input.Pointer} + * @readonly + * @since 3.10.0 */ - seek: { + pointer10: { 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; - } - }, + return this.manager.pointers[10]; + } - 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; +PluginCache.register('InputPlugin', InputPlugin, 'input'); - if (this.isPlaying) - { - this.stopAndRemoveBufferSource(); - this.createAndStartBufferSource(); - } +module.exports = InputPlugin; - 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; - }, +/***/ 63399: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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: { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - get: function () - { - return this.currentConfig.loop; - }, +var GetValue = __webpack_require__(10850); - set: function (value) - { - this.currentConfig.loop = value; +// Contains the plugins that Phaser uses globally and locally. +// These are the source objects, not instantiated. +var inputPlugins = {}; - if (this.isPlaying) - { - this.stopAndRemoveLoopBufferSource(); +/** + * @namespace Phaser.Input.InputPluginCache + */ - if (value) - { - this.createAndStartLoopBufferSource(); - } - } +var InputPluginCache = {}; - 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; - - -/***/ }), -/* 435 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/** + * Static method called directly by the Core internal Plugins. + * Key is a reference used to get the plugin from the plugins object (i.e. InputPlugin) + * Plugin is the object to instantiate to create the plugin + * Mapping is what the plugin is injected into the Scene.Systems as (i.e. input) + * + * @function Phaser.Input.InputPluginCache.register + * @static + * @since 3.10.0 + * + * @param {string} key - A reference used to get this plugin from the plugin cache. + * @param {function} plugin - The plugin to be stored. Should be the core object, not instantiated. + * @param {string} mapping - If this plugin is to be injected into the Input Plugin, this is the property key used. + * @param {string} settingsKey - The key in the Scene Settings to check to see if this plugin should install or not. + * @param {string} configKey - The key in the Game Config to check to see if this plugin should install or not. + */ +InputPluginCache.register = function (key, plugin, mapping, settingsKey, configKey) +{ + inputPlugins[key] = { plugin: plugin, mapping: mapping, settingsKey: settingsKey, configKey: configKey }; +}; /** - * 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 + * Returns the input plugin object from the cache based on the given key. * - * @generic T - * @genericUse {T[][]} - [array,$return] + * @function Phaser.Input.InputPluginCache.getPlugin + * @static + * @since 3.10.0 * - * @param {T[][]} [array] - The array matrix to transpose. + * @param {string} key - The key of the input plugin to get. * - * @return {T[][]} A new array matrix which is a transposed version of the given array. + * @return {Phaser.Types.Input.InputPluginContainer} The input plugin object. */ -var TransposeMatrix = function (array) +InputPluginCache.getPlugin = function (key) { - 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; + return inputPlugins[key]; }; -module.exports = TransposeMatrix; - - -/***/ }), -/* 436 */ -/***/ (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) + * Installs all of the registered Input Plugins into the given target. * - * @function Phaser.Utils.Array.QuickSelect - * @since 3.0.0 + * @function Phaser.Input.InputPluginCache.install + * @static + * @since 3.10.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. + * @param {Phaser.Input.InputPlugin} target - The target InputPlugin to install the plugins into. */ -var QuickSelect = function (arr, k, left, right, compare) +InputPluginCache.install = function (target) { - if (left === undefined) { left = 0; } - if (right === undefined) { right = arr.length - 1; } - if (compare === undefined) { compare = defaultCompare; } + var sys = target.scene.sys; + var settings = sys.settings.input; + var config = sys.game.config; - while (right > left) + for (var key in inputPlugins) { - 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; - - -/***/ }), -/* 437 */ -/***/ (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__(131); - -var BuildChunk = function (a, b, qty) -{ - var out = []; + var source = inputPlugins[key].plugin; + var mapping = inputPlugins[key].mapping; + var settingsKey = inputPlugins[key].settingsKey; + var configKey = inputPlugins[key].configKey; - for (var aIndex = 0; aIndex < a.length; aIndex++) - { - for (var bIndex = 0; bIndex < b.length; bIndex++) + if (GetValue(settings, settingsKey, config[configKey])) { - for (var i = 0; i < qty; i++) - { - out.push({ a: a[aIndex], b: b[bIndex] }); - } + target[mapping] = new source(target); } } - - 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 + * Removes an input plugin based on the given key. * - * @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. + * @function Phaser.Input.InputPluginCache.remove + * @static + * @since 3.10.0 * - * @return {array} An array of arranged elements. + * @param {string} key - The key of the input plugin to remove. */ -var Range = function (a, b, options) +InputPluginCache.remove = function (key) { - 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) + if (inputPlugins.hasOwnProperty(key)) { - out.splice(max); + delete inputPlugins[key]; } - - return out; }; -module.exports = Range; +module.exports = InputPluginCache; /***/ }), -/* 438 */ -/***/ (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__(1041), - PROCESS_QUEUE_REMOVE: __webpack_require__(1042) - -}; - - -/***/ }), -/* 439 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 40398: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetAdvancedValue = __webpack_require__(13); +var Angle = __webpack_require__(90447); +var Class = __webpack_require__(56694); +var Distance = __webpack_require__(53996); +var FuzzyEqual = __webpack_require__(88456); +var SmoothStepInterpolation = __webpack_require__(44521); +var Vector2 = __webpack_require__(93736); +var OS = __webpack_require__(36580); /** - * Adds an Animation component to a Sprite and populates it based on the given config. + * @classdesc + * A Pointer object encapsulates both mouse and touch input within Phaser. * - * @function Phaser.GameObjects.BuildGameObjectAnimation - * @since 3.0.0 + * 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. * - * @param {Phaser.GameObjects.Sprite} sprite - The sprite to add an Animation component to. - * @param {object} config - The animation config. + * 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. * - * @return {Phaser.GameObjects.Sprite} The updated Sprite. + * 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 BuildGameObjectAnimation = function (sprite, config) -{ - var animConfig = GetAdvancedValue(config, 'anims', null); +var Pointer = new Class({ - if (animConfig === null) - { - return sprite; - } + initialize: - if (typeof animConfig === 'string') - { - // { anims: 'key' } - sprite.anims.play(animConfig); - } - else if (typeof animConfig === 'object') + function Pointer (manager, id) { - // { anims: { - // key: string - // startFrame: [string|number] - // delay: [float] - // repeat: [integer] - // repeatDelay: [float] - // yoyo: [boolean] - // play: [boolean] - // delayedPlay: [boolean] - // } - // } + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Pointer#manager + * @type {Phaser.Input.InputManager} + * @since 3.0.0 + */ + this.manager = manager; - var anims = sprite.anims; + /** + * The internal ID of this Pointer. + * + * @name Phaser.Input.Pointer#id + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.id = id; - var key = GetAdvancedValue(animConfig, 'key', undefined); + /** + * The most recent native DOM Event this Pointer has processed. + * + * @name Phaser.Input.Pointer#event + * @type {(TouchEvent|MouseEvent|WheelEvent)} + * @since 3.0.0 + */ + this.event; - if (key) - { - var startFrame = GetAdvancedValue(animConfig, 'startFrame', undefined); + /** + * 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; - var delay = GetAdvancedValue(animConfig, 'delay', 0); - var repeat = GetAdvancedValue(animConfig, 'repeat', 0); - var repeatDelay = GetAdvancedValue(animConfig, 'repeatDelay', 0); - var yoyo = GetAdvancedValue(animConfig, 'yoyo', false); + /** + * 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; - var play = GetAdvancedValue(animConfig, 'play', false); - var delayedPlay = GetAdvancedValue(animConfig, 'delayedPlay', 0); + /** + * 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; - var playConfig = { - key: key, - delay: delay, - repeat: repeat, - repeatDelay: repeatDelay, - yoyo: yoyo, - startFrame: startFrame - }; + /** + * 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; - if (play) - { - anims.play(playConfig); - } - else if (delayedPlay > 0) - { - anims.playAfterDelay(playConfig, delayedPlay); - } - else - { - anims.load(playConfig); - } - } - } + /** + * 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; - return sprite; -}; + /** + * 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(); -module.exports = BuildGameObjectAnimation; + /** + * 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); -/***/ }), -/* 440 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var Class = __webpack_require__(0); -var Frame = __webpack_require__(109); + /** + * 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; -/** - * @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({ + /** + * 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; - initialize: + /** + * 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; - function Bob (blitter, x, y, frame, visible) - { /** - * The Blitter object that this Bob belongs to. + * The y position of this Pointer, translated into the coordinate space of the most recent Camera it interacted with. * - * @name Phaser.GameObjects.Bob#parent - * @type {Phaser.GameObjects.Blitter} + * 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.parent = blitter; + this.moveTime = 0; /** - * The x position of this Bob, relative to the x position of the Blitter. + * X coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. * - * @name Phaser.GameObjects.Bob#x + * @name Phaser.Input.Pointer#downX * @type {number} + * @default 0 * @since 3.0.0 */ - this.x = x; + this.downX = 0; /** - * The y position of this Bob, relative to the y position of the Blitter. + * Y coordinate of the Pointer when Button 1 (left button), or Touch, was pressed, used for dragging objects. * - * @name Phaser.GameObjects.Bob#y + * @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.y = y; + this.downTime = 0; /** - * The frame that the Bob uses to render with. - * To change the frame use the `Bob.setFrame` method. + * X coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. * - * @name Phaser.GameObjects.Bob#frame - * @type {Phaser.Textures.Frame} - * @protected + * @name Phaser.Input.Pointer#upX + * @type {number} + * @default 0 * @since 3.0.0 */ - this.frame = frame; + this.upX = 0; /** - * A blank object which can be used to store data related to this Bob in. + * Y coordinate of the Pointer when Button 1 (left button), or Touch, was released, used for dragging objects. * - * @name Phaser.GameObjects.Bob#data - * @type {object} - * @default {} + * @name Phaser.Input.Pointer#upY + * @type {number} + * @default 0 * @since 3.0.0 */ - this.data = {}; + this.upY = 0; /** - * The tint value of this Bob. + * The Event timestamp when the final button, or Touch input, was released. Used for dragging objects. * - * @name Phaser.GameObjects.Bob#tint + * @name Phaser.Input.Pointer#upTime * @type {number} - * @default 0xffffff - * @since 3.20.0 + * @default 0 + * @since 3.0.0 */ - this.tint = 0xffffff; + this.upTime = 0; /** - * The visible state of this Bob. + * Is the primary button down? (usually button 0, the left mouse button) * - * @name Phaser.GameObjects.Bob#_visible + * @name Phaser.Input.Pointer#primaryDown * @type {boolean} - * @private + * @default false * @since 3.0.0 */ - this._visible = visible; + this.primaryDown = false; /** - * The alpha value of this Bob. + * Is _any_ button on this pointer considered as being down? * - * @name Phaser.GameObjects.Bob#_alpha - * @type {number} - * @private - * @default 1 + * @name Phaser.Input.Pointer#isDown + * @type {boolean} + * @default false * @since 3.0.0 */ - this._alpha = 1; + this.isDown = false; /** - * 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. + * Did the previous input event come from a Touch input (true) or Mouse? (false) * - * @name Phaser.GameObjects.Bob#flipX + * @name Phaser.Input.Pointer#wasTouch * @type {boolean} + * @default false * @since 3.0.0 */ - this.flipX = false; + this.wasTouch = 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. + * Did this Pointer get canceled by a touchcancel event? * - * @name Phaser.GameObjects.Bob#flipY + * 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.flipY = false; + 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; }, /** - * 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. + * Takes a Camera and updates this Pointer's `worldX` and `worldY` values so they are + * the result of a translation through the given Camera. * - * @method Phaser.GameObjects.Bob#setFrame - * @since 3.0.0 + * 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. * - * @param {(string|number|Phaser.Textures.Frame)} [frame] - The frame to be used during rendering. + * @method Phaser.Input.Pointer#updateWorldPoint + * @since 3.19.0 * - * @return {this} This Bob Game Object. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against. + * + * @return {this} This Pointer object. */ - setFrame: function (frame) + updateWorldPoint: function (camera) { - 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); - } + // 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; }, /** - * Resets the horizontal and vertical flipped state of this Bob back to their default un-flipped state. + * 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.GameObjects.Bob#resetFlip + * @method Phaser.Input.Pointer#positionToCamera * @since 3.0.0 * - * @return {this} This Bob Game Object. + * @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. */ - resetFlip: function () + positionToCamera: function (camera, output) { - this.flipX = false; - this.flipY = false; - - return this; + return camera.getWorldPoint(this.x, this.y, output); }, /** - * 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. + * Calculates the motion of this Pointer, including its velocity and angle of movement. + * This method is called automatically each frame by the Input Manager. * - * @return {this} This Bob Game Object. + * @method Phaser.Input.Pointer#updateMotion + * @private + * @since 3.16.0 */ - reset: function (x, y, frame) + updateMotion: function () { - this.x = x; - this.y = y; + var cx = this.position.x; + var cy = this.position.y; - this.flipX = false; - this.flipY = false; + var mx = this.midPoint.x; + var my = this.midPoint.y; - this._alpha = 1; - this._visible = true; + if (cx === mx && cy === my) + { + // Nothing to do here + return; + } - this.parent.dirty = true; + // Moving towards our goal ... + var vx = SmoothStepInterpolation(this.motionFactor, mx, cx); + var vy = SmoothStepInterpolation(this.motionFactor, my, cy); - if (frame) + if (FuzzyEqual(vx, cx, 0.1)) { - this.setFrame(frame); + vx = cx; } - return this; - }, + if (FuzzyEqual(vy, cy, 0.1)) + { + vy = cy; + } - /** - * 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; + this.midPoint.set(vx, vy); - return this; - }, + var dx = cx - vx; + var dy = cy - vy; - /** - * 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; + this.velocity.set(dx, dy); - return this; + this.angle = Angle(vx, vy, cx, cy); + + this.distance = Math.sqrt(dx * dx + dy * dy); }, /** - * Sets the vertical flipped state of this Bob. + * Internal method to handle a Mouse Up Event. * - * @method Phaser.GameObjects.Bob#setFlipY + * @method Phaser.Input.Pointer#up + * @private * @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. + * @param {MouseEvent} event - The Mouse Event to process. */ - setFlipY: function (value) + up: function (event) { - this.flipY = value; + if ('buttons' in event) + { + this.buttons = event.buttons; + } - return this; - }, + this.event = event; - /** - * 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; + this.button = event.button; - return this; - }, + this.upElement = event.target; - /** - * 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; + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, false); - return this; + // 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; + } }, /** - * 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. + * Internal method to handle a Mouse Down Event. * - * @method Phaser.GameObjects.Bob#setAlpha + * @method Phaser.Input.Pointer#down + * @private * @since 3.0.0 * - * @param {number} value - The alpha value used for this Bob. Between 0 and 1. - * - * @return {this} This Bob Game Object. + * @param {MouseEvent} event - The Mouse Event to process. */ - setAlpha: function (value) + down: function (event) { - this.alpha = value; + if ('buttons' in event) + { + this.buttons = event.buttons; + } - return this; - }, + this.event = event; - /** - * 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; + this.button = event.button; - return this; - }, + this.downElement = event.target; - /** - * 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; + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, false); - this.parent.children.remove(this); + // 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; + } - this.parent = undefined; - this.frame = undefined; - this.data = undefined; + 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; }, /** - * The visible state of the Bob. - * - * An invisible Bob will skip rendering. + * Internal method to handle a Mouse Move Event. * - * @name Phaser.GameObjects.Bob#visible - * @type {boolean} + * @method Phaser.Input.Pointer#move + * @private * @since 3.0.0 + * + * @param {MouseEvent} event - The Mouse Event to process. */ - visible: { - - get: function () + move: function (event) + { + if ('buttons' in event) { - return this._visible; - }, + this.buttons = event.buttons; + } - set: function (value) + this.event = event; + + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, true); + + if (this.locked) { - this.parent.dirty |= (this._visible !== value); - this._visible = value; + // 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; }, /** - * The alpha value of the Bob, between 0 and 1. + * Internal method to handle a Mouse Wheel Event. * - * A Bob with alpha 0 will skip rendering. + * @method Phaser.Input.Pointer#wheel + * @private + * @since 3.18.0 * - * @name Phaser.GameObjects.Bob#alpha - * @type {number} - * @since 3.0.0 + * @param {WheelEvent} event - The Wheel Event to process. */ - alpha: { - - get: function () - { - return this._alpha; - }, - - set: function (value) + wheel: function (event) + { + if ('buttons' in event) { - this.parent.dirty |= ((this._alpha > 0) !== (value > 0)); - this._alpha = value; + this.buttons = event.buttons; } - } + this.event = event; -}); + // Sets the local x/y properties + this.manager.transformPointer(this, event.pageX, event.pageY, false); -module.exports = Bob; + this.deltaX = event.deltaX; + this.deltaY = event.deltaY; + this.deltaZ = event.deltaZ; + this.wasTouch = false; + }, -/***/ }), -/* 441 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.identifier = touch.identifier; + this.target = touch.target; + this.active = true; -var Rectangle = __webpack_require__(10); + this.buttons = 1; -/** - * 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(); } + this.event = event; - // 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; + this.downElement = touch.target; - return out.setTo(x, y, w, h); -}; + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, false); -module.exports = Union; + this.primaryDown = true; + this.downX = this.x; + this.downY = this.y; + this.downTime = event.timeStamp; + this.isDown = true; -/***/ }), -/* 442 */ -/***/ (function(module, exports, __webpack_require__) { + this.wasTouch = true; + this.wasCanceled = false; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.updateMotion(); + }, -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var DOMElementRender = __webpack_require__(1055); -var GameObject = __webpack_require__(15); -var IsPlainObject = __webpack_require__(7); -var RemoveFromDOM = __webpack_require__(202); -var SCENE_EVENTS = __webpack_require__(20); -var Vector4 = __webpack_require__(140); + /** + * 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; -/** - * @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({ + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, true); - Extends: GameObject, + this.moveTime = event.timeStamp; - Mixins: [ - Components.AlphaSingle, - Components.BlendMode, - Components.Depth, - Components.Origin, - Components.ScrollFactor, - Components.Transform, - Components.Visible, - DOMElementRender - ], + this.wasTouch = true; - initialize: + this.updateMotion(); + }, - function DOMElement (scene, x, y, element, style, innerText) + /** + * 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) { - 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; + this.buttons = 0; - /** - * 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; + this.event = event; - /** - * 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; + this.upElement = touch.target; - /** - * 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; + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, 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; + this.primaryDown = false; + this.upX = this.x; + this.upY = this.y; + this.upTime = event.timeStamp; - /** - * 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; + this.isDown = false; - /** - * 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(); + this.wasTouch = true; + this.wasCanceled = false; - /** - * 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'; + this.active = false; - /** - * Sets the CSS `pointerEvents` attribute on the DOM Element during rendering. - * - * This is 'auto' by default. Changing it may have unintended side-effects with - * internal Phaser input handling, such as dragging, so only change this if you - * understand the implications. - * - * @name Phaser.GameObjects.DOMElement#pointerEvents - * @type {string} - * @since 3.55.0 - */ - this.pointerEvents = 'auto'; + this.updateMotion(); + }, - /** - * 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; + /** + * 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; - /** - * 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; + this.event = event; - /** - * 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; + this.upElement = touch.target; - /** - * 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; + // Sets the local x/y properties + this.manager.transformPointer(this, touch.pageX, touch.pageY, false); - /** - * Internal native event handler. - * - * @name Phaser.GameObjects.DOMElement#handler - * @type {number} - * @private - * @since 3.17.0 - */ - this.handler = this.dispatchNativeEvent.bind(this); + this.primaryDown = false; + this.upX = this.x; + this.upY = this.y; + this.upTime = event.timeStamp; - this.setPosition(x, y); + this.isDown = false; - 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); - } + this.wasTouch = true; + this.wasCanceled = true; - scene.sys.events.on(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); - scene.sys.events.on(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); + this.active = false; }, - // Overrides Game Object method - addedToScene: function () + /** + * 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 () { - this.scene.sys.updateList.add(this); + return (this.buttons === 0); }, - // Overrides Game Object method - removedFromScene: function () + /** + * 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 () { - this.scene.sys.updateList.remove(this); + return (this.buttons & 1) ? true : false; }, /** - * Handles a Scene Sleep and Wake event. + * Checks to see if the right button is being held down on this Pointer. * - * @method Phaser.GameObjects.DOMElement#handleSceneEvent - * @private - * @since 3.22.0 + * @method Phaser.Input.Pointer#rightButtonDown + * @since 3.0.0 * - * @param {Phaser.Scenes.Systems} sys - The Scene Systems. + * @return {boolean} `true` if the right button is being held down. */ - handleSceneEvent: function (sys) + rightButtonDown: function () { - var node = this.node; - var style = node.style; - - if (node) - { - style.display = (sys.settings.visible) ? 'block' : 'none'; - } + return (this.buttons & 2) ? true : false; }, /** - * Sets the horizontal and vertical skew values of this DOM Element. + * Checks to see if the middle button is being held down on this Pointer. * - * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * @method Phaser.Input.Pointer#middleButtonDown + * @since 3.0.0 * - * @method Phaser.GameObjects.DOMElement#setSkew - * @since 3.17.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. * - * @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. + * @method Phaser.Input.Pointer#backButtonDown + * @since 3.0.0 * - * @return {this} This DOM Element instance. + * @return {boolean} `true` if the back button is being held down. */ - setSkew: function (x, y) + backButtonDown: function () { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } - - this.skewX = x; - this.skewY = y; - - return this; + return (this.buttons & 8) ? true : false; }, /** - * 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 + * Checks to see if the forward button is being held down on this Pointer. * - * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** + * @method Phaser.Input.Pointer#forwardButtonDown + * @since 3.0.0 * - * @method Phaser.GameObjects.DOMElement#setPerspective - * @since 3.17.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. * - * @param {number} value - The perspective value, in pixels, that determines the distance between the z plane and the user. + * @method Phaser.Input.Pointer#leftButtonReleased + * @since 3.18.0 * - * @return {this} This DOM Element instance. + * @return {boolean} `true` if the left button was just released. */ - setPerspective: function (value) + leftButtonReleased: function () { - this.parent.style.perspective = value + 'px'; - - return this; + return (this.button === 0 && !this.isDown); }, /** - * 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 + * Checks to see if the right button was just released on this Pointer. * - * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** + * @method Phaser.Input.Pointer#rightButtonReleased + * @since 3.18.0 * - * @name Phaser.GameObjects.DOMElement#perspective - * @type {number} - * @since 3.17.0 + * @return {boolean} `true` if the right button was just released. */ - perspective: { - - get: function () - { - return parseFloat(this.parent.style.perspective); - }, - - set: function (value) - { - this.parent.style.perspective = value + 'px'; - } + 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); }, /** - * 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. + * Checks to see if the back button was just released on this Pointer. * - * For example: + * @method Phaser.Input.Pointer#backButtonReleased + * @since 3.18.0 * - * ```javascript - * var div = this.add.dom(x, y, element); + * @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. * - * div.addListener('click'); + * @method Phaser.Input.Pointer#forwardButtonReleased + * @since 3.18.0 * - * div.on('click', handler); - * ``` + * @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. * - * @method Phaser.GameObjects.DOMElement#addListener - * @since 3.17.0 + * If no button is held down, it will return the last recorded distance, based on where + * the Pointer was when the button was released. * - * @param {string} events - The DOM event/s to listen for. You can specify multiple events by separating them with spaces. + * If you wish to get the distance being travelled currently, based on the velocity of the Pointer, + * then see the `Pointer.distance` property. * - * @return {this} This DOM Element instance. + * @method Phaser.Input.Pointer#getDistance + * @since 3.13.0 + * + * @return {number} The distance the Pointer moved. */ - addListener: function (events) + getDistance: function () { - if (this.node) + if (this.isDown) { - events = events.split(' '); - - for (var i = 0; i < events.length; i++) - { - this.node.addEventListener(events[i], this.handler, false); - } + return Distance(this.downX, this.downY, this.x, this.y); + } + else + { + return Distance(this.downX, this.downY, this.upX, this.upY); } - - return this; }, /** - * Removes one or more native DOM event listeners from the underlying Element of this Game Object. + * 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. * - * @method Phaser.GameObjects.DOMElement#removeListener - * @since 3.17.0 + * 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. * - * @param {string} events - The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces. + * @method Phaser.Input.Pointer#getDistanceX + * @since 3.16.0 * - * @return {this} This DOM Element instance. + * @return {number} The horizontal distance the Pointer moved. */ - removeListener: function (events) + getDistanceX: function () { - if (this.node) + if (this.isDown) { - events = events.split(' '); - - for (var i = 0; i < events.length; i++) - { - this.node.removeEventListener(events[i], this.handler); - } + return Math.abs(this.downX - this.x); + } + else + { + return Math.abs(this.downX - this.upX); } - - return this; }, /** - * Internal event proxy to dispatch native DOM Events via this Game Object. + * 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. * - * @method Phaser.GameObjects.DOMElement#dispatchNativeEvent - * @private - * @since 3.17.0 + * 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. * - * @param {any} event - The native DOM event. + * @method Phaser.Input.Pointer#getDistanceY + * @since 3.16.0 + * + * @return {number} The vertical distance the Pointer moved. */ - dispatchNativeEvent: function (event) + getDistanceY: function () { - this.emit(event.type, event); + if (this.isDown) + { + return Math.abs(this.downY - this.y); + } + else + { + return Math.abs(this.downY - this.upY); + } }, /** - * 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. + * 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. * - * @method Phaser.GameObjects.DOMElement#createElement - * @since 3.17.0 + * 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. * - * @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. + * @method Phaser.Input.Pointer#getDuration + * @since 3.16.0 * - * @return {this} This DOM Element instance. + * @return {number} The duration the Pointer was held down for in milliseconds. */ - createElement: function (tagName, style, innerText) + getDuration: function () { - return this.setElement(document.createElement(tagName), style, innerText); + if (this.isDown) + { + return (this.manager.time - this.downTime); + } + else + { + return (this.upTime - this.downTime); + } }, /** - * 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. + * 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. * - * The `element` argument you pass to this method can be either a string tagName: + * If no button is held down, it will return the last recorded angle, based on where + * the Pointer was when the button was released. * - * ```javascript - *

Phaser

+ * The angle is based on the old position facing to the current position. * - * this.add.dom().setElement('heading'); - * ``` + * If you wish to get the current angle, based on the velocity of the Pointer, then + * see the `Pointer.angle` property. * - * Or a reference to an Element instance: + * @method Phaser.Input.Pointer#getAngle + * @since 3.16.0 * - * ```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. + * @return {number} The angle between the Pointer's coordinates in radians. */ - setElement: function (element, style, innerText) + getAngle: function () { - // 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) + if (this.isDown) { - this.parent.appendChild(target); + return Angle(this.downX, this.downY, this.x, this.y); } - - // InnerText - - if (innerText) + else { - target.innerText = innerText; + return Angle(this.downX, this.downY, this.upX, this.upY); } - - 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 - * - * - * ``` + * 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. * - * Which is loaded into your game using the cache key 'login': + * ```javaScript + * var points = pointer.getInterpolatedPosition(4); * - * ```javascript - * this.load.html('login', 'assets/loginform.html'); + * // points[0] = { x: 0, y: 0 } + * // points[1] = { x: 2, y: 1 } + * // points[2] = { x: 3, y: 2 } + * // points[3] = { x: 6, y: 3 } * ``` * - * You can create a DOM Element from it using the cache key: - * - * ```javascript - * this.add.dom().createFromCache('login'); - * ``` + * 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. * - * 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. + * 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. * - * 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. + * Internally it uses the Smooth Step interpolation calculation. * - * @method Phaser.GameObjects.DOMElement#createFromCache - * @since 3.17.0 + * @method Phaser.Input.Pointer#getInterpolatedPosition + * @since 3.11.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. + * @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 {this} This DOM Element instance. + * @return {array} An array of interpolated values. */ - createFromCache: function (key, tagName) + getInterpolatedPosition: function (steps, out) { - var html = this.cache.get(key); + if (steps === undefined) { steps = 10; } + if (out === undefined) { out = []; } - if (html) + 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++) { - this.createFromHTML(html, tagName); + var t = (1 / steps) * i; + + out[i] = { x: SmoothStepInterpolation(t, prevX, curX), y: SmoothStepInterpolation(t, prevY, curY) }; } - return this; + return out; }, /** - * 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} html - 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. + * Fully reset this Pointer back to its unitialized state. * - * @return {this} This DOM Element instance. + * @method Phaser.Input.Pointer#reset + * @since 3.60.0 */ - createFromHTML: function (html, tagName) + reset: function () { - if (tagName === undefined) { tagName = 'div'; } + this.event = null; + this.downElement = null; + this.upElement = null; - // Already got an element? Remove it first - this.removeElement(); + this.button = 0; + this.buttons = 0; - var element = document.createElement(tagName); + this.position.set(0, 0); + this.prevPosition.set(0, 0); + this.midPoint.set(-1, -1); + this.velocity.set(0, 0); + this.angle = 0; + this.distance = 0; + this.worldX = 0; + this.worldY = 0; + this.downX = 0; + this.downY = 0; + this.upX = 0; + this.upY = 0; + this.moveTime = 0; + this.upTime = 0; + this.downTime = 0; + this.primaryDown = false; + this.isDown = false; + this.wasTouch = false; + this.wasCanceled = false; + this.movementX = 0; + this.movementY = 0; + this.identifier = 0; + this.pointerId = null; + this.deltaX = 0; + this.deltaY = 0; + this.deltaZ = 0; - this.node = element; + this.active = (this.id === 0) ? true : false; + }, - element.style.zIndex = '0'; - element.style.display = 'inline'; - element.style.position = 'absolute'; + /** + * 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; + }, - // Node handler + /** + * 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: { - element.phaser = this; + get: function () + { + return this.position.x; + }, - if (this.parent) + set: function (value) { - this.parent.appendChild(element); + this.position.x = value; } - 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 + * The y position of this Pointer. + * The value is in screen space. + * See `worldY` to get a camera converted position. * - * @return {this} This DOM Element instance. + * @name Phaser.Input.Pointer#y + * @type {number} + * @since 3.0.0 */ - removeElement: function () - { - if (this.node) + y: { + + get: function () { - RemoveFromDOM(this.node); + return this.position.y; + }, - this.node = null; + set: function (value) + { + this.position.y = value; } - 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 + * 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. * - * @return {this} This DOM Element instance. + * @name Phaser.Input.Pointer#time + * @type {number} + * @readonly + * @since 3.16.0 */ - updateSize: function () - { - var node = this.node; + time: { - var nodeBounds = node.getBoundingClientRect(); + get: function () + { + return (this.event) ? this.event.timeStamp : 0; + } - this.width = node.clientWidth; - this.height = node.clientHeight; + } - this.displayWidth = nodeBounds.width || 0; - this.displayHeight = nodeBounds.height || 0; +}); - return this; - }, +module.exports = Pointer; - /** - * 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; - }, +/***/ 72687: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var INPUT_CONST = { /** - * 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. + * The mouse pointer is being held down. * - * @return {?Element} The first matching child DOM Element, or `null` if not found. + * @name Phaser.Input.MOUSE_DOWN + * @type {number} + * @since 3.10.0 */ - getChildByID: function (id) - { - return this.getChildByProperty('id', id); - }, + MOUSE_DOWN: 0, /** - * 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. + * The mouse pointer is being moved. * - * @return {?Element} The first matching child DOM Element, or `null` if not found. + * @name Phaser.Input.MOUSE_MOVE + * @type {number} + * @since 3.10.0 */ - getChildByName: function (name) - { - return this.getChildByProperty('name', name); - }, + MOUSE_MOVE: 1, /** - * 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. + * The mouse pointer is released. * - * @return {this} This DOM Element instance. + * @name Phaser.Input.MOUSE_UP + * @type {number} + * @since 3.10.0 */ - setClassName: function (className) - { - if (this.node) - { - this.node.className = className; - - this.updateSize(); - } - - return this; - }, + MOUSE_UP: 2, /** - * 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. + * A touch pointer has been started. * - * @return {this} This DOM Element instance. + * @name Phaser.Input.TOUCH_START + * @type {number} + * @since 3.10.0 */ - setText: function (text) - { - if (this.node) - { - this.node.innerText = text; - - this.updateSize(); - } - - return this; - }, + TOUCH_START: 3, /** - * 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. + * A touch pointer has been started. * - * @return {this} This DOM Element instance. + * @name Phaser.Input.TOUCH_MOVE + * @type {number} + * @since 3.10.0 */ - setHTML: function (html) - { - if (this.node) - { - this.node.innerHTML = html; - - this.updateSize(); - } - - return this; - }, + TOUCH_MOVE: 4, /** - * Runs internal update tasks. + * A touch pointer has been started. * - * @method Phaser.GameObjects.DOMElement#preUpdate - * @private - * @since 3.17.0 + * @name Phaser.Input.TOUCH_END + * @type {number} + * @since 3.10.0 */ - preUpdate: function () - { - var parent = this.parentContainer; - var node = this.node; - - if (node && parent && !parent.willRender()) - { - node.style.display = 'none'; - } - }, + TOUCH_END: 5, /** - * 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 + * The pointer lock has changed. * - * @return {boolean} `true` if the Game Object should be rendered, otherwise `false`. + * @name Phaser.Input.POINTER_LOCK_CHANGE + * @type {number} + * @since 3.10.0 */ - willRender: function () - { - return true; - }, + POINTER_LOCK_CHANGE: 6, /** - * Handles the pre-destroy step for the DOM Element, which removes the underlying node from the DOM. + * A touch pointer has been been cancelled by the browser. * - * @method Phaser.GameObjects.DOMElement#preDestroy - * @private - * @since 3.17.0 + * @name Phaser.Input.TOUCH_CANCEL + * @type {number} + * @since 3.15.0 */ - preDestroy: function () - { - this.removeElement(); + TOUCH_CANCEL: 7, - this.scene.sys.events.off(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this); - this.scene.sys.events.off(SCENE_EVENTS.WAKE, this.handleSceneEvent, this); - } + /** + * The mouse wheel changes. + * + * @name Phaser.Input.MOUSE_WHEEL + * @type {number} + * @since 3.18.0 + */ + MOUSE_WHEEL: 8 -}); +}; -module.exports = DOMElement; +module.exports = INPUT_CONST; /***/ }), -/* 443 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 14874: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CSSBlendModes = __webpack_require__(1056); -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. + * The Input Plugin Boot Event. * - * @method Phaser.GameObjects.DOMElement#renderWebGL - * @since 3.17.0 - * @private + * This internal event is dispatched by the Input Plugin when it boots, signalling to all of its systems to create themselves. * - * @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 + * @event Phaser.Input.Events#BOOT + * @type {string} + * @since 3.0.0 */ -var DOMElementCSSRenderer = function (renderer, src, camera, parentMatrix) -{ - if (!src.node) - { - return; - } - - var style = src.node.style; - var settings = src.scene.sys.settings; - - if (!style || !settings.visible || GameObject.RENDER_MASK !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)) || (src.parentContainer && !src.parentContainer.willRender())) - { - style.display = 'none'; - - return; - } - - var parent = src.parentContainer; - var alpha = camera.alpha * src.alpha; +module.exports = 'boot'; - if (parent) - { - alpha *= parent.alpha; - } - var camMatrix = tempMatrix1; - var srcMatrix = tempMatrix2; - var calcMatrix = tempMatrix3; +/***/ }), - var dx = 0; - var dy = 0; +/***/ 54168: +/***/ ((module) => { - var tx = '0%'; - var ty = '0%'; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (parentMatrix) - { - dx = (src.width * src.scaleX) * src.originX; - dy = (src.height * src.scaleY) * src.originY; +/** + * The Input Plugin Destroy Event. + * + * This internal event is dispatched by the Input Plugin when it is destroyed, signalling to all of its systems to destroy themselves. + * + * @event Phaser.Input.Events#DESTROY + * @type {string} + * @since 3.0.0 + */ +module.exports = 'destroy'; - 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); +/***/ 526: +/***/ ((module) => { - // Undo the camera scroll - srcMatrix.e = src.x - dx; - srcMatrix.f = src.y - dy; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Multiply by the src matrix, store result in calcMatrix - camMatrix.multiply(srcMatrix, calcMatrix); - } - else - { - dx = (src.width) * src.originX; - dy = (src.height) * src.originY; +/** + * The Pointer Drag End Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer stops dragging a Game Object. + * + * Listen to this event from within a Scene using: `this.input.on('dragend', listener)`. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_END]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_END} event instead. + * + * @event Phaser.Input.Events#DRAG_END + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer stopped dragging. + */ +module.exports = 'dragend'; - 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) + '%'; +/***/ 81623: +/***/ ((module) => { - srcMatrix.e -= camera.scrollX * src.scrollFactorX; - srcMatrix.f -= camera.scrollY * src.scrollFactorY; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Multiply by the src matrix, store result in calcMatrix - camMatrix.multiply(srcMatrix, calcMatrix); - } +/** + * The Pointer Drag Enter Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer drags a Game Object into a Drag Target. + * + * Listen to this event from within a Scene using: `this.input.on('dragenter', listener)`. + * + * A Pointer can only drag a single Game Object at once. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_ENTER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_ENTER} event instead. + * + * @event Phaser.Input.Events#DRAG_ENTER + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. + * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has moved into. + */ +module.exports = 'dragenter'; - if (!src.transformOnly) - { - style.display = 'block'; - style.opacity = alpha; - style.zIndex = src._depth; - style.pointerEvents = src.pointerEvents; - 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 + ')'; +/***/ 94472: +/***/ ((module) => { - style.transformOrigin = tx + ' ' + ty; -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = DOMElementCSSRenderer; +/** + * The Pointer Drag Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves while dragging a Game Object. + * + * Listen to this event from within a Scene using: `this.input.on('drag', listener)`. + * + * A Pointer can only drag a single Game Object at once. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG} event instead. + * + * @event Phaser.Input.Events#DRAG + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. + * @param {number} dragX - The x coordinate where the Pointer is currently dragging the Game Object, in world space. + * @param {number} dragY - The y coordinate where the Pointer is currently dragging the Game Object, in world space. + */ +module.exports = 'drag'; /***/ }), -/* 444 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 9304: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(1060); - /** - * @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 Pointer Drag Leave Input Event. * - * The WebGL context is then left in a 'clean' state, ready for you to bind your own shaders, - * or draw to it, whatever you wish to do. This should all take place in the `render` method. - * The correct way to deploy an Extern object is to create a class that extends it, then - * override the `render` (and optionally `preUpdate`) methods and pass off control to your - * 3rd party libraries or custom WebGL code there. + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer drags a Game Object out of a Drag Target. * - * 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. + * Listen to this event from within a Scene using: `this.input.on('dragleave', listener)`. * - * 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. + * A Pointer can only drag a single Game Object at once. * - * @class Extern - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.GameObjects - * @constructor - * @since 3.16.0 + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_LEAVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_LEAVE} event instead. * - * @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 + * @event Phaser.Input.Events#DRAG_LEAVE + * @type {string} + * @since 3.0.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 {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. + * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has left. */ -var Extern = new Class({ +module.exports = 'dragleave'; - 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: +/***/ 34265: +/***/ ((module) => { - function Extern (scene) - { - GameObject.call(this, scene, 'Extern'); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Overrides Game Object method - addedToScene: function () - { - this.scene.sys.updateList.add(this); - }, +/** + * The Pointer Drag Over Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer drags a Game Object over a Drag Target. + * + * When the Game Object first enters the drag target it will emit a `dragenter` event. If it then moves while within + * the drag target, it will emit this event instead. + * + * Listen to this event from within a Scene using: `this.input.on('dragover', listener)`. + * + * A Pointer can only drag a single Game Object at once. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_OVER} event instead. + * + * @event Phaser.Input.Events#DRAG_OVER + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. + * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has moved over. + */ +module.exports = 'dragover'; - // 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 - } +/***/ 50151: +/***/ ((module) => { -}); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = Extern; +/** + * The Pointer Drag Start Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer starts to drag any Game Object. + * + * Listen to this event from within a Scene using: `this.input.on('dragstart', listener)`. + * + * A Pointer can only drag a single Game Object at once. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_START]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_START} event instead. + * + * @event Phaser.Input.Events#DRAG_START + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. + */ +module.exports = 'dragstart'; /***/ }), -/* 445 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 98134: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CircumferencePoint = __webpack_require__(218); -var FromPercent = __webpack_require__(98); -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. + * The Pointer Drop Input Event. * - * @function Phaser.Geom.Ellipse.GetPoint - * @since 3.0.0 + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer drops a Game Object on a Drag Target. * - * @generic {Phaser.Geom.Point} O - [out,$return] + * Listen to this event from within a Scene using: `this.input.on('drop', listener)`. * - * @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. + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DROP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DROP} event instead. * - * @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the ellipse. + * @event Phaser.Input.Events#DROP + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer was dragging. + * @param {Phaser.GameObjects.GameObject} target - The Drag Target the `gameObject` has been dropped on. */ -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; +module.exports = 'drop'; /***/ }), -/* 446 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 56773: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circumference = __webpack_require__(447); -var CircumferencePoint = __webpack_require__(218); -var FromPercent = __webpack_require__(98); -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. + * The Game Object Down Input Event. * - * @function Phaser.Geom.Ellipse.GetPoints - * @since 3.0.0 + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is pressed down on _any_ interactive Game Object. * - * @generic {Phaser.Geom.Point[]} O - [out,$return] + * Listen to this event from within a Scene using: `this.input.on('gameobjectdown', listener)`. * - * @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. + * To receive this event, the Game Objects must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. * - * @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the ellipse. + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} event instead. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} + * 2. [GAMEOBJECT_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DOWN} + * 3. [POINTER_DOWN]{@linkcode Phaser.Input.Events#event:POINTER_DOWN} or [POINTER_DOWN_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_DOWN_OUTSIDE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_DOWN + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer was pressed down on. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. */ -var GetPoints = function (ellipse, quantity, stepRate, out) -{ - if (out === undefined) { out = []; } +module.exports = 'gameobjectdown'; - // 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)); - } +/***/ 45824: +/***/ ((module) => { - return out; -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = GetPoints; +/** + * The Game Object Drag End Event. + * + * This event is dispatched by an interactive Game Object if a pointer stops dragging it. + * + * Listen to this event from a Game Object using: `gameObject.on('dragend', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive and enabled for drag. + * See [GameObject.setInteractive](Phaser.GameObjects.GameObject#setInteractive) for more details. + * + * @event Phaser.Input.Events#GAMEOBJECT_DRAG_END + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {number} dragX - The x coordinate where the Pointer stopped dragging the Game Object, in world space. + * @param {number} dragY - The y coordinate where the Pointer stopped dragging the Game Object, in world space. + */ +module.exports = 'dragend'; /***/ }), -/* 447 */ -/***/ (function(module, exports) { + +/***/ 39578: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Returns the circumference of the given Ellipse. + * The Game Object Drag Enter Event. * - * @function Phaser.Geom.Ellipse.Circumference - * @since 3.0.0 + * This event is dispatched by an interactive Game Object if a pointer drags it into a drag target. * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the circumference of. + * Listen to this event from a Game Object using: `gameObject.on('dragenter', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. * - * @return {number} The circumference of th Ellipse. + * To receive this event, the Game Object must have been set as interactive and enabled for drag. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * @event Phaser.Input.Events#GAMEOBJECT_DRAG_ENTER + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has moved into. */ -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; +module.exports = 'dragenter'; /***/ }), -/* 448 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72072: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Commands = __webpack_require__(217); -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. + * The Game Object Drag Event. * - * @method Phaser.GameObjects.Graphics#renderCanvas + * This event is dispatched by an interactive Game Object if a pointer moves while dragging it. + * + * Listen to this event from a Game Object using: `gameObject.on('drag', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive and enabled for drag. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * @event Phaser.Input.Events#GAMEOBJECT_DRAG + * @type {string} * @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. + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {number} dragX - The x coordinate where the Pointer is currently dragging the Game Object, in world space. + * @param {number} dragY - The y coordinate where the Pointer is currently dragging the Game Object, in world space. */ -var GraphicsCanvasRenderer = function (renderer, src, camera, parentMatrix, renderTargetCtx, allowClip) -{ - var commandBuffer = src.commandBuffer; - var commandBufferLength = commandBuffer.length; +module.exports = 'drag'; - var ctx = renderTargetCtx || renderer.currentContext; - if (commandBufferLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - return; - } +/***/ }), - camera.addToRenderList(src); +/***/ 82569: +/***/ ((module) => { - var lineAlpha = 1; - var fillAlpha = 1; - var lineColor = 0; - var fillColor = 0; - var lineWidth = 1; - var red = 0; - var green = 0; - var blue = 0; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Reset any currently active paths - ctx.beginPath(); +/** + * The Game Object Drag Leave Event. + * + * This event is dispatched by an interactive Game Object if a pointer drags it out of a drag target. + * + * Listen to this event from a Game Object using: `gameObject.on('dragleave', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive and enabled for drag. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * @event Phaser.Input.Events#GAMEOBJECT_DRAG_LEAVE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has left. + */ +module.exports = 'dragleave'; - 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; +/***/ 70833: +/***/ ((module) => { - 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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; +/** + * The Game Object Drag Over Event. + * + * This event is dispatched by an interactive Game Object if a pointer drags it over a drag target. + * + * When the Game Object first enters the drag target it will emit a `dragenter` event. If it then moves while within + * the drag target, it will emit this event instead. + * + * Listen to this event from a Game Object using: `gameObject.on('dragover', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive and enabled for drag. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * @event Phaser.Input.Events#GAMEOBJECT_DRAG_OVER + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has moved over. + */ +module.exports = 'dragover'; - case Commands.BEGIN_PATH: - ctx.beginPath(); - break; - case Commands.CLOSE_PATH: - ctx.closePath(); - break; +/***/ }), - case Commands.FILL_PATH: - if (!allowClip) - { - ctx.fill(); - } - break; +/***/ 81442: +/***/ ((module) => { - case Commands.STROKE_PATH: - if (!allowClip) - { - ctx.stroke(); - } - break; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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; +/** + * The Game Object Drag Start Event. + * + * This event is dispatched by an interactive Game Object if a pointer starts to drag it. + * + * Listen to this event from a Game Object using: `gameObject.on('dragstart', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive and enabled for drag. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * There are lots of useful drag related properties that are set within the Game Object when dragging occurs. + * For example, `gameObject.input.dragStartX`, `dragStartY` and so on. + * + * @event Phaser.Input.Events#GAMEOBJECT_DRAG_START + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {number} dragX - The x coordinate where the Pointer is currently dragging the Game Object, in world space. + * @param {number} dragY - The y coordinate where the Pointer is currently dragging the Game Object, in world space. + */ +module.exports = 'dragstart'; - 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; +/***/ 32936: +/***/ ((module) => { - case Commands.MOVE_TO: - ctx.moveTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - case Commands.LINE_FX_TO: - ctx.lineTo( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 5; - break; +/** + * The Game Object Drop Event. + * + * This event is dispatched by an interactive Game Object if a pointer drops it on a Drag Target. + * + * Listen to this event from a Game Object using: `gameObject.on('drop', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive and enabled for drag. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * @event Phaser.Input.Events#GAMEOBJECT_DROP + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} target - The Drag Target the `gameObject` has been dropped on. + */ +module.exports = 'drop'; - 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; +/***/ 99658: +/***/ ((module) => { - case Commands.TRANSLATE: - ctx.translate( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - case Commands.SCALE: - ctx.scale( - commandBuffer[index + 1], - commandBuffer[index + 2] - ); - index += 2; - break; +/** + * The Game Object Move Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is moved across _any_ interactive Game Object. + * + * Listen to this event from within a Scene using: `this.input.on('gameobjectmove', listener)`. + * + * To receive this event, the Game Objects must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_MOVE} event instead. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_MOVE} + * 2. [GAMEOBJECT_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_MOVE} + * 3. [POINTER_MOVE]{@linkcode Phaser.Input.Events#event:POINTER_MOVE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_MOVE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer was moved on. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'gameobjectmove'; - 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; - } - } +/***/ 60515: +/***/ ((module) => { - // Restore the context saved in SetTransform - ctx.restore(); -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = GraphicsCanvasRenderer; +/** + * The Game Object Out Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves out of _any_ interactive Game Object. + * + * Listen to this event from within a Scene using: `this.input.on('gameobjectout', listener)`. + * + * To receive this event, the Game Objects must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OUT} event instead. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OUT} + * 2. [GAMEOBJECT_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OUT} + * 3. [POINTER_OUT]{@linkcode Phaser.Input.Events#event:POINTER_OUT} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * If the pointer leaves the game canvas itself, it will not trigger an this event. To handle those cases, + * please listen for the [GAME_OUT]{@linkcode Phaser.Input.Events#event:GAME_OUT} event. + * + * @event Phaser.Input.Events#GAMEOBJECT_OUT + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer moved out of. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'gameobjectout'; /***/ }), -/* 449 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 55254: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var FloatBetween = __webpack_require__(137); -var GetEaseFunction = __webpack_require__(80); -var GetFastValue = __webpack_require__(2); -var Wrap = __webpack_require__(68); - /** - * @classdesc - * A Particle Emitter property. + * The Game Object Over Input Event. * - * Facilitates changing Particle properties as they are emitted and throughout their lifetime. + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves over _any_ interactive Game Object. * - * @class EmitterOp - * @memberof Phaser.GameObjects.Particles - * @constructor + * Listen to this event from within a Scene using: `this.input.on('gameobjectover', listener)`. + * + * To receive this event, the Game Objects must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OVER} event instead. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OVER} + * 2. [GAMEOBJECT_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OVER} + * 3. [POINTER_OVER]{@linkcode Phaser.Input.Events#event:POINTER_OVER} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_OVER + * @type {string} * @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. + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer moved over. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. */ -var EmitterOp = new Class({ +module.exports = 'gameobjectover'; - 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; +/***/ 34782: +/***/ ((module) => { - /** - * The value of this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#propertyValue - * @type {number} - * @since 3.0.0 - */ - this.propertyValue = defaultValue; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The default value of this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#defaultValue - * @type {number} - * @since 3.0.0 - */ - this.defaultValue = defaultValue; +/** + * The Game Object Pointer Down Event. + * + * This event is dispatched by an interactive Game Object if a pointer is pressed down on it. + * + * Listen to this event from a Game Object using: `gameObject.on('pointerdown', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} + * 2. [GAMEOBJECT_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DOWN} + * 3. [POINTER_DOWN]{@linkcode Phaser.Input.Events#event:POINTER_DOWN} or [POINTER_DOWN_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_DOWN_OUTSIDE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_POINTER_DOWN + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {number} localX - The x coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. + * @param {number} localY - The y coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'pointerdown'; - /** - * 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; +/***/ 41769: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The easing function to use for updating this property. - * - * @name Phaser.GameObjects.Particles.EmitterOp#ease - * @type {?function} - * @since 3.0.0 - */ - this.ease; +/** + * The Game Object Pointer Move Event. + * + * This event is dispatched by an interactive Game Object if a pointer is moved while over it. + * + * Listen to this event from a Game Object using: `gameObject.on('pointermove', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_MOVE} + * 2. [GAMEOBJECT_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_MOVE} + * 3. [POINTER_MOVE]{@linkcode Phaser.Input.Events#event:POINTER_MOVE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_POINTER_MOVE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {number} localX - The x coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. + * @param {number} localY - The y coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'pointermove'; - /** - * 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; +/***/ 65588: +/***/ ((module) => { - this.loadConfig(config); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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 = {}; - } +/** + * The Game Object Pointer Out Event. + * + * This event is dispatched by an interactive Game Object if a pointer moves out of it. + * + * Listen to this event from a Game Object using: `gameObject.on('pointerout', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OUT} + * 2. [GAMEOBJECT_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OUT} + * 3. [POINTER_OUT]{@linkcode Phaser.Input.Events#event:POINTER_OUT} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * If the pointer leaves the game canvas itself, it will not trigger an this event. To handle those cases, + * please listen for the [GAME_OUT]{@linkcode Phaser.Input.Events#event:GAME_OUT} event. + * + * @event Phaser.Input.Events#GAMEOBJECT_POINTER_OUT + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'pointerout'; - if (newKey) - { - this.propertyKey = newKey; - } - this.propertyValue = GetFastValue( - config, - this.propertyKey, - this.defaultValue - ); +/***/ }), - this.setMethods(); +/***/ 61640: +/***/ ((module) => { - if (this.emitOnly) - { - // Reset it back again - this.onUpdate = this.defaultUpdate; - } - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; - }, +/** + * The Game Object Pointer Over Event. + * + * This event is dispatched by an interactive Game Object if a pointer moves over it. + * + * Listen to this event from a Game Object using: `gameObject.on('pointerover', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OVER} + * 2. [GAMEOBJECT_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OVER} + * 3. [POINTER_OVER]{@linkcode Phaser.Input.Events#event:POINTER_OVER} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_POINTER_OVER + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {number} localX - The x coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. + * @param {number} localY - The y coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'pointerover'; - /** - * 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; +/***/ 49342: +/***/ ((module) => { - var t = typeof value; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Reset them in case they're not changed below - this.onEmit = this.defaultEmit; - this.onUpdate = this.defaultUpdate; +/** + * The Game Object Pointer Up Event. + * + * This event is dispatched by an interactive Game Object if a pointer is released while over it. + * + * Listen to this event from a Game Object using: `gameObject.on('pointerup', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} + * 2. [GAMEOBJECT_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_UP} + * 3. [POINTER_UP]{@linkcode Phaser.Input.Events#event:POINTER_UP} or [POINTER_UP_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_UP_OUTSIDE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_POINTER_UP + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {number} localX - The x coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. + * @param {number} localY - The y coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'pointerup'; - 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: +/***/ 82662: +/***/ ((module) => { - /* - x: function (particle, key, t, value) - { - return value + 50; - } - */ +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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; +/** + * The Game Object Pointer Wheel Event. + * + * This event is dispatched by an interactive Game Object if a pointer has its wheel moved while over it. + * + * Listen to this event from a Game Object using: `gameObject.on('wheel', listener)`. + * Note that the scope of the listener is automatically set to be the Game Object instance itself. + * + * To receive this event, the Game Object must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_WHEEL} + * 2. [GAMEOBJECT_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_WHEEL} + * 3. [POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:POINTER_WHEEL} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_POINTER_WHEEL + * @type {string} + * @since 3.18.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {number} deltaX - The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * @param {number} deltaY - 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. + * @param {number} deltaZ - The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'wheel'; - // 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; - } +/***/ 13058: +/***/ ((module) => { - if (this.has(value, 'steps')) - { - // A stepped (per emit) range +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // x: { start: 100, end: 400, steps: 64 } +/** + * The Game Object Up Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is released while over _any_ interactive Game Object. + * + * Listen to this event from within a Scene using: `this.input.on('gameobjectup', listener)`. + * + * To receive this event, the Game Objects must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} event instead. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} + * 2. [GAMEOBJECT_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_UP} + * 3. [POINTER_UP]{@linkcode Phaser.Input.Events#event:POINTER_UP} or [POINTER_UP_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_UP_OUTSIDE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_UP + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer was over when released. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'gameobjectup'; - // 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) +/***/ 52426: +/***/ ((module) => { - // x: { start: 100, end: 400, [ ease: 'Linear' ] } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var easeType = this.has(value, 'ease') ? value.ease : 'Linear'; +/** + * The Game Object Wheel Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer has its wheel moved while over _any_ interactive Game Object. + * + * Listen to this event from within a Scene using: `this.input.on('gameobjectwheel', listener)`. + * + * To receive this event, the Game Objects must have been set as interactive. + * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. + * + * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_WHEEL} event instead. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_WHEEL} + * 2. [GAMEOBJECT_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_WHEEL} + * 3. [POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:POINTER_WHEEL} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#GAMEOBJECT_WHEEL + * @type {string} + * @since 3.18.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer was over when the wheel changed. + * @param {number} deltaX - The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * @param {number} deltaY - 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. + * @param {number} deltaZ - The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. + */ +module.exports = 'gameobjectwheel'; - 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 +/***/ 78072: +/***/ ((module) => { - 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 +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var rnd = value.random; +/** + * The Input Plugin Game Out Event. + * + * This event is dispatched by the Input Plugin if the active pointer leaves the game canvas and is now + * outside of it, elsewhere on the web page. + * + * Listen to this event from within a Scene using: `this.input.on('gameout', listener)`. + * + * @event Phaser.Input.Events#GAME_OUT + * @type {string} + * @since 3.16.1 + * + * @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 {(MouseEvent|TouchEvent)} event - The DOM Event that triggered the canvas out. + */ +module.exports = 'gameout'; - 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; - }, +/***/ 1545: +/***/ ((module) => { - // Called during the particles life on each update - onUpdate: function (particle, key, t, value) - { - return value; - } - } - */ +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (this.has(value, 'onEmit')) - { - this.onEmit = value.onEmit; - } +/** + * The Input Plugin Game Over Event. + * + * This event is dispatched by the Input Plugin if the active pointer enters the game canvas and is now + * over of it, having previously been elsewhere on the web page. + * + * Listen to this event from within a Scene using: `this.input.on('gameover', listener)`. + * + * @event Phaser.Input.Events#GAME_OVER + * @type {string} + * @since 3.16.1 + * + * @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 {(MouseEvent|TouchEvent)} event - The DOM Event that triggered the canvas over. + */ +module.exports = 'gameover'; - 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); - }, +/***/ 67137: +/***/ ((module) => { - /** - * 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); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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 Input Manager Boot Event. + * + * This internal event is dispatched by the Input Manager when it boots. + * + * @event Phaser.Input.Events#MANAGER_BOOT + * @type {string} + * @since 3.0.0 + */ +module.exports = 'boot'; - /** - * 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; - }, +/***/ 27678: +/***/ ((module) => { - /** - * 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; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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); +/** + * The Input Manager Process Event. + * + * This internal event is dispatched by the Input Manager when not using the legacy queue system, + * and it wants the Input Plugins to update themselves. + * + * @event Phaser.Input.Events#MANAGER_PROCESS + * @type {string} + * @since 3.0.0 + * + * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ +module.exports = 'process'; - 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) +/***/ }), + +/***/ 22257: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Input Manager Update Event. + * + * This internal event is dispatched by the Input Manager as part of its update step. + * + * @event Phaser.Input.Events#MANAGER_UPDATE + * @type {string} + * @since 3.0.0 + */ +module.exports = 'update'; + + +/***/ }), + +/***/ 90379: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Input Manager Pointer Lock Change Event. + * + * This event is dispatched by the Input Manager when it is processing a native Pointer Lock Change DOM Event. + * + * @event Phaser.Input.Events#POINTERLOCK_CHANGE + * @type {string} + * @since 3.0.0 + * + * @param {Event} event - The native DOM Event. + * @param {boolean} locked - The locked state of the Mouse Pointer. + */ +module.exports = 'pointerlockchange'; + + +/***/ }), + +/***/ 88909: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Pointer Down Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is pressed down anywhere. + * + * Listen to this event from within a Scene using: `this.input.on('pointerdown', listener)`. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} + * 2. [GAMEOBJECT_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DOWN} + * 3. [POINTER_DOWN]{@linkcode Phaser.Input.Events#event:POINTER_DOWN} or [POINTER_DOWN_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_DOWN_OUTSIDE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#POINTER_DOWN + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject[]} currentlyOver - An array containing all interactive Game Objects that the pointer was over when the event was created. + */ +module.exports = 'pointerdown'; + + +/***/ }), + +/***/ 36548: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Pointer Down Outside Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is pressed down anywhere outside of the game canvas. + * + * Listen to this event from within a Scene using: `this.input.on('pointerdownoutside', listener)`. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} + * 2. [GAMEOBJECT_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DOWN} + * 3. [POINTER_DOWN]{@linkcode Phaser.Input.Events#event:POINTER_DOWN} or [POINTER_DOWN_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_DOWN_OUTSIDE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#POINTER_DOWN_OUTSIDE + * @type {string} + * @since 3.16.1 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + */ +module.exports = 'pointerdownoutside'; + + +/***/ }), + +/***/ 18483: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Pointer Move Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is moved anywhere. + * + * Listen to this event from within a Scene using: `this.input.on('pointermove', listener)`. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_MOVE} + * 2. [GAMEOBJECT_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_MOVE} + * 3. [POINTER_MOVE]{@linkcode Phaser.Input.Events#event:POINTER_MOVE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#POINTER_MOVE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject[]} currentlyOver - An array containing all interactive Game Objects that the pointer was over when the event was created. + */ +module.exports = 'pointermove'; + + +/***/ }), + +/***/ 22355: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Pointer Out Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves out of any interactive Game Object. + * + * Listen to this event from within a Scene using: `this.input.on('pointerout', listener)`. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OUT} + * 2. [GAMEOBJECT_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OUT} + * 3. [POINTER_OUT]{@linkcode Phaser.Input.Events#event:POINTER_OUT} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * If the pointer leaves the game canvas itself, it will not trigger an this event. To handle those cases, + * please listen for the [GAME_OUT]{@linkcode Phaser.Input.Events#event:GAME_OUT} event. + * + * @event Phaser.Input.Events#POINTER_OUT + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject[]} justOut - An array containing all interactive Game Objects that the pointer moved out of when the event was created. + */ +module.exports = 'pointerout'; + + +/***/ }), + +/***/ 7997: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Pointer Over Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves over any interactive Game Object. + * + * Listen to this event from within a Scene using: `this.input.on('pointerover', listener)`. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OVER} + * 2. [GAMEOBJECT_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OVER} + * 3. [POINTER_OVER]{@linkcode Phaser.Input.Events#event:POINTER_OVER} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#POINTER_OVER + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject[]} justOver - An array containing all interactive Game Objects that the pointer moved over when the event was created. + */ +module.exports = 'pointerover'; + + +/***/ }), + +/***/ 66318: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Pointer Up Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is released anywhere. + * + * Listen to this event from within a Scene using: `this.input.on('pointerup', listener)`. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} + * 2. [GAMEOBJECT_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_UP} + * 3. [POINTER_UP]{@linkcode Phaser.Input.Events#event:POINTER_UP} or [POINTER_UP_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_UP_OUTSIDE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#POINTER_UP + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject[]} currentlyOver - An array containing all interactive Game Objects that the pointer was over when the event was created. + */ +module.exports = 'pointerup'; + + +/***/ }), + +/***/ 94812: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Pointer Up Outside Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is released anywhere outside of the game canvas. + * + * Listen to this event from within a Scene using: `this.input.on('pointerupoutside', listener)`. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} + * 2. [GAMEOBJECT_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_UP} + * 3. [POINTER_UP]{@linkcode Phaser.Input.Events#event:POINTER_UP} or [POINTER_UP_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_UP_OUTSIDE} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#POINTER_UP_OUTSIDE + * @type {string} + * @since 3.16.1 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + */ +module.exports = 'pointerupoutside'; + + +/***/ }), + +/***/ 37310: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Pointer Wheel Input Event. + * + * This event is dispatched by the Input Plugin belonging to a Scene if a pointer has its wheel updated. + * + * Listen to this event from within a Scene using: `this.input.on('wheel', listener)`. + * + * The event hierarchy is as follows: + * + * 1. [GAMEOBJECT_POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_WHEEL} + * 2. [GAMEOBJECT_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_WHEEL} + * 3. [POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:POINTER_WHEEL} + * + * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop + * the propagation of this event. + * + * @event Phaser.Input.Events#POINTER_WHEEL + * @type {string} + * @since 3.18.0 + * + * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. + * @param {Phaser.GameObjects.GameObject[]} currentlyOver - An array containing all interactive Game Objects that the pointer was over when the event was created. + * @param {number} deltaX - The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * @param {number} deltaY - 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. + * @param {number} deltaZ - The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. + */ +module.exports = 'wheel'; + + +/***/ }), + +/***/ 24196: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Input Plugin Pre-Update Event. + * + * This internal event is dispatched by the Input Plugin at the start of its `preUpdate` method. + * This hook is designed specifically for input plugins, but can also be listened to from user-land code. + * + * @event Phaser.Input.Events#PRE_UPDATE + * @type {string} + * @since 3.0.0 + */ +module.exports = 'preupdate'; + + +/***/ }), + +/***/ 27053: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Input Plugin Shutdown Event. + * + * This internal event is dispatched by the Input Plugin when it shuts down, signalling to all of its systems to shut themselves down. + * + * @event Phaser.Input.Events#SHUTDOWN + * @type {string} + * @since 3.0.0 + */ +module.exports = 'shutdown'; + + +/***/ }), + +/***/ 29413: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Input Plugin Start Event. + * + * This internal event is dispatched by the Input Plugin when it has finished setting-up, + * signalling to all of its internal systems to start. + * + * @event Phaser.Input.Events#START + * @type {string} + * @since 3.0.0 + */ +module.exports = 'start'; + + +/***/ }), + +/***/ 25165: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Input Plugin Update Event. + * + * This internal event is dispatched by the Input Plugin at the start of its `update` method. + * This hook is designed specifically for input plugins, but can also be listened to from user-land code. + * + * @event Phaser.Input.Events#UPDATE + * @type {string} + * @since 3.0.0 + * + * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ +module.exports = 'update'; + + +/***/ }), + +/***/ 33963: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Input.Events + */ + +module.exports = { + + BOOT: __webpack_require__(14874), + DESTROY: __webpack_require__(54168), + DRAG_END: __webpack_require__(526), + DRAG_ENTER: __webpack_require__(81623), + DRAG: __webpack_require__(94472), + DRAG_LEAVE: __webpack_require__(9304), + DRAG_OVER: __webpack_require__(34265), + DRAG_START: __webpack_require__(50151), + DROP: __webpack_require__(98134), + GAME_OUT: __webpack_require__(78072), + GAME_OVER: __webpack_require__(1545), + GAMEOBJECT_DOWN: __webpack_require__(56773), + GAMEOBJECT_DRAG_END: __webpack_require__(45824), + GAMEOBJECT_DRAG_ENTER: __webpack_require__(39578), + GAMEOBJECT_DRAG: __webpack_require__(72072), + GAMEOBJECT_DRAG_LEAVE: __webpack_require__(82569), + GAMEOBJECT_DRAG_OVER: __webpack_require__(70833), + GAMEOBJECT_DRAG_START: __webpack_require__(81442), + GAMEOBJECT_DROP: __webpack_require__(32936), + GAMEOBJECT_MOVE: __webpack_require__(99658), + GAMEOBJECT_OUT: __webpack_require__(60515), + GAMEOBJECT_OVER: __webpack_require__(55254), + GAMEOBJECT_POINTER_DOWN: __webpack_require__(34782), + GAMEOBJECT_POINTER_MOVE: __webpack_require__(41769), + GAMEOBJECT_POINTER_OUT: __webpack_require__(65588), + GAMEOBJECT_POINTER_OVER: __webpack_require__(61640), + GAMEOBJECT_POINTER_UP: __webpack_require__(49342), + GAMEOBJECT_POINTER_WHEEL: __webpack_require__(82662), + GAMEOBJECT_UP: __webpack_require__(13058), + GAMEOBJECT_WHEEL: __webpack_require__(52426), + MANAGER_BOOT: __webpack_require__(67137), + MANAGER_PROCESS: __webpack_require__(27678), + MANAGER_UPDATE: __webpack_require__(22257), + POINTER_DOWN: __webpack_require__(88909), + POINTER_DOWN_OUTSIDE: __webpack_require__(36548), + POINTER_MOVE: __webpack_require__(18483), + POINTER_OUT: __webpack_require__(22355), + POINTER_OVER: __webpack_require__(7997), + POINTER_UP: __webpack_require__(66318), + POINTER_UP_OUTSIDE: __webpack_require__(94812), + POINTER_WHEEL: __webpack_require__(37310), + POINTERLOCK_CHANGE: __webpack_require__(90379), + PRE_UPDATE: __webpack_require__(24196), + SHUTDOWN: __webpack_require__(27053), + START: __webpack_require__(29413), + UPDATE: __webpack_require__(25165) + +}; + + +/***/ }), + +/***/ 70848: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); + +/** + * @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) { - var value = FloatBetween(this.start, this.end); + /** + * 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; - if (particle && particle.data[key]) - { - particle.data[key].min = value; - } + /** + * 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; - return value; + /** + * 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; }, /** - * An `onEmit` callback that returns a stepped value between the - * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} - * range. + * Internal update handler for this Axis. + * Called automatically by the Gamepad as part of its update. * - * @method Phaser.GameObjects.Particles.EmitterOp#steppedEmit + * @method Phaser.Input.Gamepad.Axis#update + * @private * @since 3.0.0 * - * @return {number} The new value of the property. + * @param {number} value - The value of the axis movement. */ - steppedEmit: function () + update: function (value) { - var current = this.counter; - - var next = this.counter + (this.end - this.start) / this.steps; - - this.counter = Wrap(next, this.start, this.end); - - return current; + this.value = value; }, /** - * An `onEmit` callback for an eased property. - * - * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate}. + * Applies the `threshold` value to the axis and returns it. * - * @method Phaser.GameObjects.Particles.EmitterOp#easedValueEmit + * @method Phaser.Input.Gamepad.Axis#getValue * @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. + * @return {number} The axis value, adjusted for the movement threshold. */ - easedValueEmit: function (particle, key) + getValue: function () { - if (particle && particle.data[key]) - { - var data = particle.data[key]; - - data.min = this.start; - data.max = this.end; - } - - return this.start; + return (Math.abs(this.value) < this.threshold) ? 0 : this.value; }, /** - * 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) + * Destroys this Axis instance and releases external references it holds. * - * @return {number} The new value of the property. + * @method Phaser.Input.Gamepad.Axis#destroy + * @since 3.10.0 */ - easeValueUpdate: function (particle, key, t) + destroy: function () { - var data = particle.data[key]; - - return (data.max - data.min) * this.ease(t) + data.min; + this.pad = null; + this.events = null; } + }); -module.exports = EmitterOp; +module.exports = Axis; /***/ }), -/* 450 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 21274: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(43200); /** * @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). + * Contains information about a specific button on a Gamepad. + * Button objects are created automatically by the Gamepad as they are needed. * - * @class GravityWell - * @memberof Phaser.GameObjects.Particles + * @class Button + * @memberof Phaser.Input.Gamepad * @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. + * @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 GravityWell = new Class({ +var Button = new Class({ initialize: - function GravityWell (x, y, power, epsilon, gravity) + function Button (pad, index) { - 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. + * A reference to the Gamepad that this Button belongs to. * - * @name Phaser.GameObjects.Particles.GravityWell#active - * @type {boolean} - * @default true + * @name Phaser.Input.Gamepad.Button#pad + * @type {Phaser.Input.Gamepad.Gamepad} * @since 3.0.0 */ - this.active = true; + this.pad = pad; /** - * Internal gravity value. + * An event emitter to use to emit the button events. * - * @name Phaser.GameObjects.Particles.GravityWell#_gravity - * @type {number} - * @private + * @name Phaser.Input.Gamepad.Button#events + * @type {Phaser.Events.EventEmitter} * @since 3.0.0 */ - this._gravity = gravity; + this.events = pad.manager; /** - * Internal power value. + * The index of this Button. * - * @name Phaser.GameObjects.Particles.GravityWell#_power + * @name Phaser.Input.Gamepad.Button#index * @type {number} - * @private - * @default 0 * @since 3.0.0 */ - this._power = 0; + this.index = index; /** - * Internal epsilon value. + * Between 0 and 1. * - * @name Phaser.GameObjects.Particles.GravityWell#_epsilon + * @name Phaser.Input.Gamepad.Button#value * @type {number} - * @private * @default 0 * @since 3.0.0 */ - this._epsilon = 0; + this.value = 0; /** - * The strength of the gravity force - larger numbers produce a stronger force. + * Can be set for analogue buttons to enable a 'pressure' threshold, + * before a button is considered as being 'pressed'. * - * @name Phaser.GameObjects.Particles.GravityWell#power + * @name Phaser.Input.Gamepad.Button#threshold * @type {number} + * @default 1 * @since 3.0.0 */ - this.power = power; + this.threshold = 1; /** - * The minimum distance for which the gravity force is calculated. + * Is the Button being pressed down or not? * - * @name Phaser.GameObjects.Particles.GravityWell#epsilon - * @type {number} + * @name Phaser.Input.Gamepad.Button#pressed + * @type {boolean} + * @default false * @since 3.0.0 */ - this.epsilon = epsilon; + this.pressed = false; }, /** - * Takes a Particle and updates it based on the properties of this Gravity Well. + * Internal update handler for this Button. + * Called automatically by the Gamepad as part of its update. * - * @method Phaser.GameObjects.Particles.GravityWell#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 {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. + * @param {number} value - The value of the button. Between 0 and 1. */ - update: function (particle, delta) + update: function (value) { - 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: { + this.value = value; - get: function () - { - return Math.sqrt(this._epsilon); - }, + var pad = this.pad; + var index = this.index; - set: function (value) + if (value >= this.threshold) { - this._epsilon = value * value; + 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); + } } - - }, - - power: { - - get: function () - { - return this._power / this._gravity; - }, - - set: function (value) + else if (this.pressed) { - this._power = value * this._gravity; + this.pressed = false; + this.events.emit(Events.BUTTON_UP, pad, this, value); + this.pad.emit(Events.GAMEPAD_BUTTON_UP, index, value, this); } - }, - gravity: { - - get: function () - { - return this._gravity; - }, - - set: function (value) - { - var pwr = this.power; - this._gravity = value; - this.power = pwr; - } - + /** + * 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 = GravityWell; +module.exports = Button; /***/ }), -/* 451 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 75956: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(36); -var DistanceBetween = __webpack_require__(50); +var Axis = __webpack_require__(70848); +var Button = __webpack_require__(21274); +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var Vector2 = __webpack_require__(93736); /** * @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. + * A single Gamepad. * - * @class Particle - * @memberof Phaser.GameObjects.Particles + * 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.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to which this Particle belongs. + * @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 Particle = new Class({ +var Gamepad = new Class({ + + Extends: EventEmitter, initialize: - function Particle (emitter) + function Gamepad (manager, pad) { + EventEmitter.call(this); + /** - * The Emitter to which this Particle belongs. - * - * A Particle can only belong to a single Emitter and is created, updated and destroyed via it. + * A reference to the Gamepad Plugin. * - * @name Phaser.GameObjects.Particles.Particle#emitter - * @type {Phaser.GameObjects.Particles.ParticleEmitter} + * @name Phaser.Input.Gamepad.Gamepad#manager + * @type {Phaser.Input.Gamepad.GamepadPlugin} * @since 3.0.0 */ - this.emitter = emitter; + this.manager = manager; /** - * The texture frame used to render this Particle. + * A reference to the native Gamepad object that is connected to the browser. * - * @name Phaser.GameObjects.Particles.Particle#frame - * @type {Phaser.Textures.Frame} - * @default null - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#pad + * @type {any} + * @since 3.10.0 */ - this.frame = null; + this.pad = pad; /** - * The x coordinate of this Particle. + * A string containing some information about the controller. * - * @name Phaser.GameObjects.Particles.Particle#x - * @type {number} - * @default 0 + * 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.x = 0; + this.id = pad.id; /** - * The y coordinate of this Particle. + * 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.GameObjects.Particles.Particle#y + * @name Phaser.Input.Gamepad.Gamepad#index * @type {number} - * @default 0 * @since 3.0.0 */ - this.y = 0; + this.index = pad.index; + + var buttons = []; + + for (var i = 0; i < pad.buttons.length; i++) + { + buttons.push(new Button(this, i)); + } /** - * The x velocity of this Particle. + * An array of Gamepad Button objects, corresponding to the different buttons available on the Gamepad. * - * @name Phaser.GameObjects.Particles.Particle#velocityX - * @type {number} - * @default 0 + * @name Phaser.Input.Gamepad.Gamepad#buttons + * @type {Phaser.Input.Gamepad.Button[]} * @since 3.0.0 */ - this.velocityX = 0; + this.buttons = buttons; + + var axes = []; + + for (i = 0; i < pad.axes.length; i++) + { + axes.push(new Axis(this, i)); + } /** - * The y velocity of this Particle. + * An array of Gamepad Axis objects, corresponding to the different axes available on the Gamepad, if any. * - * @name Phaser.GameObjects.Particles.Particle#velocityY - * @type {number} - * @default 0 + * @name Phaser.Input.Gamepad.Gamepad#axes + * @type {Phaser.Input.Gamepad.Axis[]} * @since 3.0.0 */ - this.velocityY = 0; + this.axes = axes; /** - * The x acceleration of this Particle. + * 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.GameObjects.Particles.Particle#accelerationX - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#vibration + * @type {GamepadHapticActuator} + * @since 3.10.0 */ - this.accelerationX = 0; + this.vibration = pad.vibrationActuator; + + // https://w3c.github.io/gamepad/#remapping + + var _noButton = { value: 0, pressed: false }; /** - * The y acceleration of this Particle. + * A reference to the Left Button in the Left Cluster. * - * @name Phaser.GameObjects.Particles.Particle#accelerationY - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_LCLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.accelerationY = 0; + this._LCLeft = (buttons[14]) ? buttons[14] : _noButton; /** - * The maximum horizontal velocity this Particle can travel at. + * A reference to the Right Button in the Left Cluster. * - * @name Phaser.GameObjects.Particles.Particle#maxVelocityX - * @type {number} - * @default 10000 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_LCRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.maxVelocityX = 10000; + this._LCRight = (buttons[15]) ? buttons[15] : _noButton; /** - * The maximum vertical velocity this Particle can travel at. + * A reference to the Top Button in the Left Cluster. * - * @name Phaser.GameObjects.Particles.Particle#maxVelocityY - * @type {number} - * @default 10000 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_LCTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.maxVelocityY = 10000; + this._LCTop = (buttons[12]) ? buttons[12] : _noButton; /** - * The bounciness, or restitution, of this Particle. + * A reference to the Bottom Button in the Left Cluster. * - * @name Phaser.GameObjects.Particles.Particle#bounce - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_LCBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.bounce = 0; + this._LCBottom = (buttons[13]) ? buttons[13] : _noButton; /** - * The horizontal scale of this Particle. + * A reference to the Left Button in the Right Cluster. * - * @name Phaser.GameObjects.Particles.Particle#scaleX - * @type {number} - * @default 1 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_RCLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.scaleX = 1; + this._RCLeft = (buttons[2]) ? buttons[2] : _noButton; /** - * The vertical scale of this Particle. + * A reference to the Right Button in the Right Cluster. * - * @name Phaser.GameObjects.Particles.Particle#scaleY - * @type {number} - * @default 1 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_RCRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.scaleY = 1; + this._RCRight = (buttons[1]) ? buttons[1] : _noButton; /** - * The alpha value of this Particle. + * A reference to the Top Button in the Right Cluster. * - * @name Phaser.GameObjects.Particles.Particle#alpha - * @type {number} - * @default 1 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_RCTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.alpha = 1; + this._RCTop = (buttons[3]) ? buttons[3] : _noButton; /** - * The angle of this Particle in degrees. + * A reference to the Bottom Button in the Right Cluster. * - * @name Phaser.GameObjects.Particles.Particle#angle - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_RCBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.angle = 0; + this._RCBottom = (buttons[0]) ? buttons[0] : _noButton; /** - * The angle of this Particle in radians. + * A reference to the Top Left Front Button (L1 Shoulder Button) * - * @name Phaser.GameObjects.Particles.Particle#rotation - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_FBLeftTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.rotation = 0; + this._FBLeftTop = (buttons[4]) ? buttons[4] : _noButton; /** - * The tint applied to this Particle. + * A reference to the Bottom Left Front Button (L2 Shoulder Button) * - * @name Phaser.GameObjects.Particles.Particle#tint - * @type {number} - * @webglOnly - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_FBLeftBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.tint = 0xffffff; + this._FBLeftBottom = (buttons[6]) ? buttons[6] : _noButton; /** - * The lifespan of this Particle in ms. + * A reference to the Top Right Front Button (R1 Shoulder Button) * - * @name Phaser.GameObjects.Particles.Particle#life - * @type {number} - * @default 1000 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_FBRightTop + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.life = 1000; + this._FBRightTop = (buttons[5]) ? buttons[5] : _noButton; /** - * The current life of this Particle in ms. + * A reference to the Bottom Right Front Button (R2 Shoulder Button) * - * @name Phaser.GameObjects.Particles.Particle#lifeCurrent - * @type {number} - * @default 1000 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_FBRightBottom + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.lifeCurrent = 1000; + this._FBRightBottom = (buttons[7]) ? buttons[7] : _noButton; + + var _noAxis = { value: 0 }; /** - * The delay applied to this Particle upon emission, in ms. + * A reference to the Horizontal Axis for the Left Stick. * - * @name Phaser.GameObjects.Particles.Particle#delayCurrent - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_HAxisLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.delayCurrent = 0; + this._HAxisLeft = (axes[0]) ? axes[0] : _noAxis; /** - * The normalized lifespan T value, where 0 is the start and 1 is the end. + * A reference to the Vertical Axis for the Left Stick. * - * @name Phaser.GameObjects.Particles.Particle#lifeT - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_VAxisLeft + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.0 */ - this.lifeT = 0; + this._VAxisLeft = (axes[1]) ? axes[1] : _noAxis; /** - * The data used by the ease equation. + * A reference to the Horizontal Axis for the Right Stick. * - * @name Phaser.GameObjects.Particles.Particle#data - * @type {object} - * @since 3.0.0 + * @name Phaser.Input.Gamepad.Gamepad#_HAxisRight + * @type {Phaser.Input.Gamepad.Button} + * @private + * @since 3.10.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 } - }; + 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(); }, /** - * Checks to see if this Particle is alive and updating. + * Gets the total number of axis this Gamepad claims to support. * - * @method Phaser.GameObjects.Particles.Particle#isAlive - * @since 3.0.0 + * @method Phaser.Input.Gamepad.Gamepad#getAxisTotal + * @since 3.10.0 * - * @return {boolean} `true` if this Particle is alive and updating, otherwise `false`. + * @return {number} The total number of axes this Gamepad claims to support. */ - isAlive: function () + getAxisTotal: function () { - return (this.lifeCurrent > 0); + return this.axes.length; }, /** - * Resets the position of this particle back to zero. + * 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.GameObjects.Particles.Particle#resetPosition - * @since 3.16.0 + * @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. */ - resetPosition: function () + getAxisValue: function (index) { - this.x = 0; - this.y = 0; + return this.axes[index].getValue(); }, /** - * Starts this Particle from the given coordinates. + * 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.GameObjects.Particles.Particle#fire - * @since 3.0.0 + * @method Phaser.Input.Gamepad.Gamepad#setAxisThreshold + * @since 3.10.0 * - * @param {number} x - The x coordinate to launch this Particle from. - * @param {number} y - The y coordinate to launch this Particle from. + * @param {number} value - A value between 0 and 1. */ - fire: function (x, y) + setAxisThreshold: function (value) { - 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 + for (var i = 0; i < this.axes.length; i++) { - this.x += x; + this.axes[i].threshold = value; } + }, - if (y === undefined) - { - this.y += emitter.y.onEmit(this, 'y'); - } - else - { - this.y += y; - } + /** + * 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; + }, - this.life = emitter.lifespan.onEmit(this, 'lifespan'); - this.lifeCurrent = this.life; - this.lifeT = 0; + /** + * 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; + }, - var sx = emitter.speedX.onEmit(this, 'speedX'); - var sy = (emitter.speedY) ? emitter.speedY.onEmit(this, 'speedY') : sx; + /** + * 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; + }, - if (emitter.radial) + /** + * 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) { - var rad = DegToRad(emitter.angle.onEmit(this, 'angle')); - - this.velocityX = Math.cos(rad) * Math.abs(sx); - this.velocityY = Math.sin(rad) * Math.abs(sy); + return; } - 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 i; - var speed = DistanceBetween(this.x, this.y, mx, my) / (this.life / 1000); + // Sync the button values - // We know how many pixels we need to move, but how fast? - // var speed = this.distanceToXY(displayObject, x, y) / (maxTime / 1000); + var localButtons = this.buttons; + var gamepadButtons = pad.buttons; - this.velocityX = Math.cos(angle) * speed; - this.velocityY = Math.sin(angle) * speed; - } - else - { - this.velocityX = sx; - this.velocityY = sy; - } + var len = localButtons.length; - if (emitter.acceleration) + for (i = 0; i < len; i++) { - this.accelerationX = emitter.accelerationX.onEmit(this, 'accelerationX'); - this.accelerationY = emitter.accelerationY.onEmit(this, 'accelerationY'); + localButtons[i].update(gamepadButtons[i].value); } - this.maxVelocityX = emitter.maxVelocityX.onEmit(this, 'maxVelocityX'); - this.maxVelocityY = emitter.maxVelocityY.onEmit(this, 'maxVelocityY'); - - this.delayCurrent = emitter.delay.onEmit(this, 'delay'); + // Sync the axis values - this.scaleX = emitter.scaleX.onEmit(this, 'scaleX'); - this.scaleY = (emitter.scaleY) ? emitter.scaleY.onEmit(this, 'scaleY') : this.scaleX; + var localAxes = this.axes; + var gamepadAxes = pad.axes; - this.angle = emitter.rotate.onEmit(this, 'rotate'); - this.rotation = DegToRad(this.angle); + len = localAxes.length; - this.bounce = emitter.bounce.onEmit(this, 'bounce'); + for (i = 0; i < len; i++) + { + localAxes[i].update(gamepadAxes[i]); + } - this.alpha = emitter.alpha.onEmit(this, 'alpha'); + if (len >= 2) + { + this.leftStick.set(localAxes[0].getValue(), localAxes[1].getValue()); - this.tint = emitter.tint.onEmit(this, 'tint'); + if (len >= 4) + { + this.rightStick.set(localAxes[2].getValue(), localAxes[3].getValue()); + } + } }, /** - * An internal method that calculates the velocity of the Particle. - * - * @method Phaser.GameObjects.Particles.Particle#computeVelocity - * @since 3.0.0 + * Destroys this Gamepad instance, its buttons and axes, and releases external references it holds. * - * @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). + * @method Phaser.Input.Gamepad.Gamepad#destroy + * @since 3.10.0 */ - computeVelocity: function (emitter, delta, step, processors) + destroy: function () { - var vx = this.velocityX; - var vy = this.velocityY; - - var ax = this.accelerationX; - var ay = this.accelerationY; + this.removeAllListeners(); - var mx = this.maxVelocityX; - var my = this.maxVelocityY; + this.manager = null; + this.pad = null; - vx += (emitter.gravityX * step); - vy += (emitter.gravityY * step); + var i; - if (ax) + for (i = 0; i < this.buttons.length; i++) { - vx += (ax * step); + this.buttons[i].destroy(); } - if (ay) + for (i = 0; i < this.axes.length; i++) { - vy += (ay * step); + this.axes[i].destroy(); } - if (vx > mx) - { - vx = mx; - } - else if (vx < -mx) - { - vx = -mx; - } + 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: { - if (vy > my) + get: function () { - vy = my; + return this.pad.connected; } - else if (vy < -my) + + }, + + /** + * 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 () { - vy = -my; + return this.pad.timestamp; } - this.velocityX = vx; - this.velocityY = vy; + }, - // Apply any additional processors - for (var i = 0; i < processors.length; i++) + /** + * 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 () { - processors[i].update(this, delta, step); + return this._LCLeft.pressed; } + }, /** - * 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 + * 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. * - * @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter to check the bounds against. + * @name Phaser.Input.Gamepad.Gamepad#right + * @type {boolean} + * @since 3.10.0 */ - checkBounds: function (emitter) - { - var bounds = emitter.bounds; - var bounce = -this.bounce; + right: { - if (this.x < bounds.x && emitter.collideLeft) + get: function () { - this.x = bounds.x; - this.velocityX *= bounce; + return this._LCRight.pressed; } - else if (this.x > bounds.right && emitter.collideRight) + + }, + + /** + * 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 () { - this.x = bounds.right; - this.velocityX *= bounce; + return this._LCTop.pressed; } - if (this.y < bounds.y && emitter.collideTop) + }, + + /** + * 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 () { - this.y = bounds.y; - this.velocityY *= bounce; + return this._LCBottom.pressed; } - else if (this.y > bounds.bottom && emitter.collideBottom) + + }, + + /** + * 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 () { - this.y = bounds.bottom; - this.velocityY *= bounce; + return this._RCBottom.pressed; } + }, /** - * 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. + * 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. * - * @return {boolean} Returns `true` if this Particle has now expired and should be removed, otherwise `false` if still active. + * @name Phaser.Input.Gamepad.Gamepad#Y + * @type {boolean} + * @since 3.10.0 */ - update: function (delta, step, processors) - { - if (this.delayCurrent > 0) - { - this.delayCurrent -= delta; + Y: { - return false; + get: function () + { + return this._RCTop.pressed; } - var emitter = this.emitter; + }, - // How far along in life is this particle? (t = 0 to 1) - var t = 1 - (this.lifeCurrent / this.life); + /** + * 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: { - this.lifeT = t; + get: function () + { + return this._RCLeft.pressed; + } - this.computeVelocity(emitter, delta, step, processors); + }, - this.x += this.velocityX * step; - this.y += this.velocityY * step; + /** + * 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: { - if (emitter.bounds) + get: function () { - this.checkBounds(emitter); + return this._RCRight.pressed; } - if (emitter.deathZone && emitter.deathZone.willKill(this)) - { - this.lifeCurrent = 0; + }, - // No need to go any further, particle has been killed - return true; + /** + * 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; } - this.scaleX = emitter.scaleX.onUpdate(this, 'scaleX', t, this.scaleX); + }, + + /** + * 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: { - if (emitter.scaleY) + get: function () { - this.scaleY = emitter.scaleY.onUpdate(this, 'scaleY', t, this.scaleY); + return this._FBLeftBottom.value; } - else + + }, + + /** + * 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 () { - this.scaleY = this.scaleX; + return this._FBRightTop.value; } - 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); + /** + * 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: { - this.lifeCurrent -= delta; + get: function () + { + return this._FBRightBottom.value; + } - return (this.lifeCurrent <= 0); } }); -module.exports = Particle; +module.exports = Gamepad; /***/ }), -/* 452 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 1379: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BlendModes = __webpack_require__(35); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var DeathZone = __webpack_require__(453); -var EdgeZone = __webpack_require__(454); -var EmitterOp = __webpack_require__(449); -var GetFastValue = __webpack_require__(2); -var GetRandom = __webpack_require__(210); -var HasAny = __webpack_require__(455); -var HasValue = __webpack_require__(126); -var Particle = __webpack_require__(451); -var RandomZone = __webpack_require__(456); -var Rectangle = __webpack_require__(10); -var StableSort = __webpack_require__(79); -var Vector2 = __webpack_require__(3); -var Wrap = __webpack_require__(68); +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(43200); +var Gamepad = __webpack_require__(75956); +var GetValue = __webpack_require__(10850); +var InputPluginCache = __webpack_require__(63399); +var InputEvents = __webpack_require__(33963); /** * @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}. + * The Gamepad Plugin is an input plugin that belongs to the Scene-owned Input system. * - * @class ParticleEmitter - * @memberof Phaser.GameObjects.Particles - * @constructor - * @since 3.0.0 + * Its role is to listen for native DOM Gamepad Events and then process them. * - * @extends Phaser.GameObjects.Components.BlendMode - * @extends Phaser.GameObjects.Components.Mask - * @extends Phaser.GameObjects.Components.ScrollFactor - * @extends Phaser.GameObjects.Components.Visible + * You do not need to create this class directly, the Input system will create an instance of it automatically. * - * @param {Phaser.GameObjects.Particles.ParticleEmitterManager} manager - The Emitter Manager this Emitter belongs to. - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. + * You can access it from within a Scene using `this.input.gamepad`. + * + * To listen for a gamepad being connected: + * + * ```javascript + * this.input.gamepad.once('connected', function (pad) { + * // 'pad' is a reference to the gamepad that was just connected + * }); + * ``` + * + * Note that the browser may require you to press a button on a gamepad before it will allow you to access it, + * this is for security reasons. However, it may also trust the page already, in which case you won't get the + * 'connected' event and instead should check `GamepadPlugin.total` to see if it thinks there are any gamepads + * already connected. + * + * Once you have received the connected event, or polled the gamepads and found them enabled, you can access + * them via the built-in properties `GamepadPlugin.pad1` to `pad4`, for up to 4 game pads. With a reference + * to the gamepads you can poll its buttons and axis sticks. See the properties and methods available on + * the `Gamepad` class for more details. + * + * As of September 2020 Chrome, and likely other browsers, will soon start to require that games requesting + * access to the Gamepad API are running under SSL. They will actively block API access if they are not. + * + * For more information about Gamepad support in browsers see the following resources: + * + * https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API + * https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API + * https://www.smashingmagazine.com/2015/11/gamepad-api-in-web-games/ + * http://html5gamepad.com/ + * + * @class GamepadPlugin + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Input.Gamepad + * @constructor + * @since 3.10.0 + * + * @param {Phaser.Input.InputPlugin} sceneInputPlugin - A reference to the Scene Input Plugin that the KeyboardPlugin belongs to. */ -var ParticleEmitter = new Class({ +var GamepadPlugin = new Class({ - Mixins: [ - Components.BlendMode, - Components.Mask, - Components.ScrollFactor, - Components.Visible - ], + Extends: EventEmitter, initialize: - function ParticleEmitter (manager, config) + function GamepadPlugin (sceneInputPlugin) { - /** - * 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; + EventEmitter.call(this); /** - * The texture assigned to particles. + * A reference to the Scene that this Input Plugin is responsible for. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#texture - * @type {Phaser.Textures.Texture} - * @since 3.0.0 + * @name Phaser.Input.Gamepad.GamepadPlugin#scene + * @type {Phaser.Scene} + * @since 3.10.0 */ - this.texture = manager.texture; + this.scene = sceneInputPlugin.scene; /** - * The texture frames assigned to particles. + * A reference to the Scene Systems Settings. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#frames - * @type {Phaser.Textures.Frame[]} - * @since 3.0.0 + * @name Phaser.Input.Gamepad.GamepadPlugin#settings + * @type {Phaser.Types.Scenes.SettingsObject} + * @since 3.10.0 */ - this.frames = [ manager.defaultFrame ]; + this.settings = this.scene.sys.settings; /** - * The default texture frame assigned to particles. + * A reference to the Scene Input Plugin that created this Keyboard Plugin. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#defaultFrame - * @type {Phaser.Textures.Frame} - * @since 3.0.0 + * @name Phaser.Input.Gamepad.GamepadPlugin#sceneInputPlugin + * @type {Phaser.Input.InputPlugin} + * @since 3.10.0 */ - this.defaultFrame = manager.defaultFrame; + this.sceneInputPlugin = sceneInputPlugin; /** - * Names of simple configuration properties. + * A boolean that controls if the Gamepad Manager is enabled or not. + * Can be toggled on the fly. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#configFastMap - * @type {object} - * @since 3.0.0 + * @name Phaser.Input.Gamepad.GamepadPlugin#enabled + * @type {boolean} + * @default true + * @since 3.10.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' - ]; + this.enabled = true; /** - * Names of complex configuration properties. + * The Gamepad Event target, as defined in the Game Config. + * Typically the browser window, but can be any interactive DOM element. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#configOpMap - * @type {object} - * @since 3.0.0 + * @name Phaser.Input.Gamepad.GamepadPlugin#target + * @type {any} + * @since 3.10.0 */ - this.configOpMap = [ - 'accelerationX', - 'accelerationY', - 'angle', - 'alpha', - 'bounce', - 'delay', - 'lifespan', - 'maxVelocityX', - 'maxVelocityY', - 'moveToX', - 'moveToY', - 'quantity', - 'rotate', - 'scaleX', - 'scaleY', - 'speedX', - 'speedY', - 'tint', - 'x', - 'y' - ]; + this.target; /** - * The name of this Particle Emitter. - * - * Empty by default and never populated by Phaser, this is left for developers to use. + * An array of the connected Gamepads. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#name - * @type {string} - * @default '' - * @since 3.0.0 + * @name Phaser.Input.Gamepad.GamepadPlugin#gamepads + * @type {Phaser.Input.Gamepad.Gamepad[]} + * @default [] + * @since 3.10.0 */ - this.name = ''; + this.gamepads = []; /** - * The Particle Class which will be emitted by this Emitter. + * An internal event queue. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#particleClass - * @type {Phaser.GameObjects.Particles.Particle} - * @default Phaser.GameObjects.Particles.Particle - * @since 3.0.0 + * @name Phaser.Input.Gamepad.GamepadPlugin#queue + * @type {GamepadEvent[]} + * @private + * @since 3.10.0 */ - this.particleClass = Particle; + this.queue = []; /** - * The x-coordinate of the particle origin (where particles will be emitted). + * Internal event handler. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#x - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition + * @name Phaser.Input.Gamepad.GamepadPlugin#onGamepadHandler + * @type {function} + * @private + * @since 3.10.0 */ - this.x = new EmitterOp(config, 'x', 0, true); + this.onGamepadHandler; /** - * The y-coordinate of the particle origin (where particles will be emitted). + * Internal Gamepad reference. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#y - * @type {Phaser.GameObjects.Particles.EmitterOp} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setPosition + * @name Phaser.Input.Gamepad.GamepadPlugin#_pad1 + * @type {Phaser.Input.Gamepad.Gamepad} + * @private + * @since 3.10.0 */ - this.y = new EmitterOp(config, 'y', 0, true); + this._pad1; /** - * 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. + * Internal Gamepad reference. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#radial - * @type {boolean} - * @default true - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setRadial + * @name Phaser.Input.Gamepad.GamepadPlugin#_pad2 + * @type {Phaser.Input.Gamepad.Gamepad} + * @private + * @since 3.10.0 */ - this.radial = true; + this._pad2; /** - * Horizontal acceleration applied to emitted particles, in pixels per second squared. + * Internal Gamepad reference. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityX - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity + * @name Phaser.Input.Gamepad.GamepadPlugin#_pad3 + * @type {Phaser.Input.Gamepad.Gamepad} + * @private + * @since 3.10.0 */ - this.gravityX = 0; + this._pad3; /** - * Vertical acceleration applied to emitted particles, in pixels per second squared. + * Internal Gamepad reference. * - * @name Phaser.GameObjects.Particles.ParticleEmitter#gravityY - * @type {number} - * @default 0 - * @since 3.0.0 - * @see Phaser.GameObjects.Particles.ParticleEmitter#setGravity + * @name Phaser.Input.Gamepad.GamepadPlugin#_pad4 + * @type {Phaser.Input.Gamepad.Gamepad} + * @private + * @since 3.10.0 */ - this.gravityY = 0; + this._pad4; - /** - * 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; + sceneInputPlugin.pluginEvents.once(InputEvents.BOOT, this.boot, this); + sceneInputPlugin.pluginEvents.on(InputEvents.START, this.start, this); + }, - /** - * 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); + /** + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#boot + * @private + * @since 3.10.0 + */ + boot: function () + { + var game = this.scene.sys.game; + var settings = this.settings.input; + var config = game.config; - /** - * 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); + this.enabled = GetValue(settings, 'gamepad', config.inputGamepad) && game.device.input.gamepads; + this.target = GetValue(settings, 'gamepad.target', config.inputGamepadEventTarget); - /** - * 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); + this.sceneInputPlugin.pluginEvents.once(InputEvents.DESTROY, this.destroy, this); + }, - /** - * 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); + /** + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#start + * @private + * @since 3.10.0 + */ + start: function () + { + if (this.enabled) + { + this.startListeners(); - /** - * 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); + this.refreshPads(); + } - /** - * 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); + this.sceneInputPlugin.pluginEvents.once(InputEvents.SHUTDOWN, this.shutdown, this); + }, - /** - * 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; + /** + * Checks to see if both this plugin and the Scene to which it belongs is active. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#isActive + * @since 3.10.0 + * + * @return {boolean} `true` if the plugin and the Scene it belongs to is active. + */ + isActive: function () + { + return (this.enabled && this.scene.sys.isActive()); + }, - /** - * 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); + /** + * Starts the Gamepad Event listeners running. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#startListeners + * @private + * @since 3.10.0 + */ + startListeners: function () + { + var _this = this; + var target = this.target; - /** - * 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); + var handler = function (event) + { + if (event.defaultPrevented || !_this.isActive()) + { + // Do nothing if event already handled + return; + } - /** - * 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); + _this.refreshPads(); - /** - * 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); + _this.queue.push(event); + }; - /** - * 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); + this.onGamepadHandler = handler; - /** - * 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); + target.addEventListener('gamepadconnected', handler, false); + target.addEventListener('gamepaddisconnected', handler, false); - /** - * 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); + // FF also supports gamepadbuttondown, gamepadbuttonup and gamepadaxismove but + // nothing else does, and we can get those values via the gamepads anyway, so we will + // until more browsers support this - /** - * 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); + // Finally, listen for an update event from the Input Plugin + this.sceneInputPlugin.pluginEvents.on(InputEvents.UPDATE, this.update, this); + }, - /** - * 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); + /** + * Stops the Gamepad Event listeners. + * This is called automatically and does not need to be manually invoked. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#stopListeners + * @private + * @since 3.10.0 + */ + stopListeners: function () + { + this.target.removeEventListener('gamepadconnected', this.onGamepadHandler); + this.target.removeEventListener('gamepaddisconnected', this.onGamepadHandler); - /** - * 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); + this.sceneInputPlugin.pluginEvents.off(InputEvents.UPDATE, this.update); - /** - * 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; + for (var i = 0; i < this.gamepads.length; i++) + { + this.gamepads[i].removeAllListeners(); + } + }, - /** - * 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; + /** + * Disconnects all current Gamepads. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#disconnectAll + * @since 3.10.0 + */ + disconnectAll: function () + { + for (var i = 0; i < this.gamepads.length; i++) + { + this.gamepads[i].pad.connected = false; + } + }, - /** - * 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; + /** + * Refreshes the list of connected Gamepads. + * + * This is called automatically when a gamepad is connected or disconnected, + * and during the update loop. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#refreshPads + * @private + * @since 3.10.0 + */ + refreshPads: function () + { + var connectedPads = navigator.getGamepads(); - /** - * 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; + if (!connectedPads) + { + this.disconnectAll(); + } + else + { + var currentPads = this.gamepads; - /** - * 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; + for (var i = 0; i < connectedPads.length; i++) + { + var livePad = connectedPads[i]; - /** - * 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); + // Because sometimes they're null (yes, really) + if (!livePad) + { + continue; + } - /** - * 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); + var id = livePad.id; + var index = livePad.index; + var currentPad = currentPads[index]; - /** - * 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 = []; + if (!currentPad) + { + // A new Gamepad, not currently stored locally + var newPad = new Gamepad(this, livePad); - /** - * 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; + currentPads[index] = newPad; - /** - * 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 (!this._pad1) + { + this._pad1 = newPad; + } + else if (!this._pad2) + { + this._pad2 = newPad; + } + else if (!this._pad3) + { + this._pad3 = newPad; + } + else if (!this._pad4) + { + this._pad4 = newPad; + } + } + else if (currentPad.id !== id) + { + // A new Gamepad with a different vendor string, but it has got the same index as an old one + currentPad.destroy(); - if (config) - { - this.fromJSON(config); + currentPads[index] = new Gamepad(this, livePad); + } + else + { + // If neither of these, it's a pad we've already got, so update it + currentPad.update(livePad); + } + } } }, /** - * Merges configuration settings into the emitter's current settings. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#fromJSON - * @since 3.0.0 + * Returns an array of all currently connected Gamepads. * - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter. + * @method Phaser.Input.Gamepad.GamepadPlugin#getAll + * @since 3.10.0 * - * @return {this} This Particle Emitter. + * @return {Phaser.Input.Gamepad.Gamepad[]} An array of all currently connected Gamepads. */ - fromJSON: function (config) + getAll: function () { - 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); - } - } + var out = []; + var pads = this.gamepads; - for (i = 0; i < this.configOpMap.length; i++) + for (var i = 0; i < pads.length; i++) { - key = this.configOpMap[i]; - - if (HasValue(config, key)) + if (pads[i]) { - this[key].loadConfig(config); + out.push(pads[i]); } } - 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; - } + return out; + }, - // Special 'scale' override + /** + * Looks-up a single Gamepad based on the given index value. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#getPad + * @since 3.10.0 + * + * @param {number} index - The index of the Gamepad to get. + * + * @return {Phaser.Input.Gamepad.Gamepad} The Gamepad matching the given index, or undefined if none were found. + */ + getPad: function (index) + { + var pads = this.gamepads; - if (HasValue(config, 'scale')) + for (var i = 0; i < pads.length; i++) { - this.scaleX.loadConfig(config, 'scale'); - this.scaleY = null; + if (pads[i] && pads[i].index === index) + { + return pads[i]; + } } + }, - if (HasValue(config, 'callbackScope')) + /** + * The internal update loop. Refreshes all connected gamepads and processes their events. + * + * Called automatically by the Input Manager, invoked from the Game step. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#update + * @private + * @fires Phaser.Input.Gamepad.Events#CONNECTED + * @fires Phaser.Input.Gamepad.Events#DISCONNECTED + * @since 3.10.0 + */ + update: function () + { + if (!this.enabled) { - var callbackScope = GetFastValue(config, 'callbackScope', null); - - this.emitCallbackScope = callbackScope; - this.deathCallbackScope = callbackScope; + return; } - if (HasValue(config, 'emitZone')) - { - this.setEmitZone(config.emitZone); - } + this.refreshPads(); - if (HasValue(config, 'deathZone')) - { - this.setDeathZone(config.deathZone); - } + var len = this.queue.length; - if (HasValue(config, 'bounds')) + if (len === 0) { - this.setBounds(config.bounds); + return; } - if (HasValue(config, 'followOffset')) - { - this.followOffset.setFromObject(GetFastValue(config, 'followOffset', 0)); - } + var queue = this.queue.splice(0, len); - if (HasValue(config, 'frame')) + // Process the event queue, dispatching all of the events that have stored up + for (var i = 0; i < len; i++) { - this.setFrame(config.frame); - } + var event = queue[i]; + var pad = this.getPad(event.gamepad.index); - if (HasValue(config, 'reserve')) - { - this.reserve(config.reserve); + if (event.type === 'gamepadconnected') + { + this.emit(Events.CONNECTED, pad, event); + } + else if (event.type === 'gamepaddisconnected') + { + this.emit(Events.DISCONNECTED, pad, event); + } } - - 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. + * Shuts the Gamepad Plugin down. + * All this does is remove any listeners bound to it. * - * @return {object} - The output object. + * @method Phaser.Input.Gamepad.GamepadPlugin#shutdown + * @private + * @since 3.10.0 */ - toJSON: function (output) + shutdown: function () { - if (output === undefined) { output = {}; } - - var i = 0; - var key = ''; + this.stopListeners(); - for (i = 0; i < this.configFastMap.length; i++) - { - key = this.configFastMap[i]; + this.removeAllListeners(); + }, - output[key] = this[key]; - } + /** + * Destroys this Gamepad Plugin, disconnecting all Gamepads and releasing internal references. + * + * @method Phaser.Input.Gamepad.GamepadPlugin#destroy + * @private + * @since 3.10.0 + */ + destroy: function () + { + this.shutdown(); - for (i = 0; i < this.configOpMap.length; i++) + for (var i = 0; i < this.gamepads.length; i++) { - key = this.configOpMap[i]; - - if (this[key]) + if (this.gamepads[i]) { - output[key] = this[key].toJSON(); + this.gamepads[i].destroy(); } } - // special handlers - if (!this.speedY) - { - delete output.speedX; - output.speed = this.speedX.toJSON(); - } + this.gamepads = []; + + this.scene = null; + this.settings = null; + this.sceneInputPlugin = null; + this.target = null; + }, + + /** + * The total number of connected game pads. + * + * @name Phaser.Input.Gamepad.GamepadPlugin#total + * @type {number} + * @since 3.10.0 + */ + total: { - if (!this.scaleY) + get: function () { - delete output.scaleX; - output.scale = this.scaleX.toJSON(); + return this.gamepads.length; } - return output; }, /** - * Continuously moves the particle origin to follow a Game Object's position. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#startFollow - * @since 3.0.0 + * A reference to the first connected Gamepad. * - * @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. + * This will be undefined if either no pads are connected, or the browser + * has not yet issued a gamepadconnect, which can happen even if a Gamepad + * is plugged in, but hasn't yet had any buttons pressed on it. * - * @return {this} This Particle Emitter. + * @name Phaser.Input.Gamepad.GamepadPlugin#pad1 + * @type {Phaser.Input.Gamepad.Gamepad} + * @since 3.10.0 */ - startFollow: function (target, offsetX, offsetY, trackVisible) - { - if (offsetX === undefined) { offsetX = 0; } - if (offsetY === undefined) { offsetY = 0; } - if (trackVisible === undefined) { trackVisible = false; } + pad1: { - this.follow = target; - this.followOffset.set(offsetX, offsetY); - this.trackVisible = trackVisible; + get: function () + { + return this._pad1; + } - return this; }, /** - * Stops following a Game Object. + * A reference to the second connected Gamepad. * - * @method Phaser.GameObjects.Particles.ParticleEmitter#stopFollow - * @since 3.0.0 + * This will be undefined if either no pads are connected, or the browser + * has not yet issued a gamepadconnect, which can happen even if a Gamepad + * is plugged in, but hasn't yet had any buttons pressed on it. * - * @return {this} This Particle Emitter. + * @name Phaser.Input.Gamepad.GamepadPlugin#pad2 + * @type {Phaser.Input.Gamepad.Gamepad} + * @since 3.10.0 */ - stopFollow: function () - { - this.follow = null; - this.followOffset.set(0, 0); - this.trackVisible = false; + pad2: { + + get: function () + { + return this._pad2; + } - return this; }, /** - * Chooses a texture frame from {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. + * A reference to the third connected Gamepad. * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getFrame - * @since 3.0.0 + * This will be undefined if either no pads are connected, or the browser + * has not yet issued a gamepadconnect, which can happen even if a Gamepad + * is plugged in, but hasn't yet had any buttons pressed on it. * - * @return {Phaser.Textures.Frame} The texture frame. + * @name Phaser.Input.Gamepad.GamepadPlugin#pad3 + * @type {Phaser.Input.Gamepad.Gamepad} + * @since 3.10.0 */ - getFrame: function () - { - if (this.frames.length === 1) - { - return this.defaultFrame; - } - else if (this.randomFrame) + pad3: { + + get: function () { - return GetRandom(this.frames); + return this._pad3; } - 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 + * A reference to the fourth connected Gamepad. * - * @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. + * This will be undefined if either no pads are connected, or the browser + * has not yet issued a gamepadconnect, which can happen even if a Gamepad + * is plugged in, but hasn't yet had any buttons pressed on it. * - * @return {this} This Particle Emitter. + * @name Phaser.Input.Gamepad.GamepadPlugin#pad4 + * @type {Phaser.Input.Gamepad.Gamepad} + * @since 3.10.0 */ - 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); + pad4: { - if (Array.isArray(frames) || t === 'string' || t === 'number') + get: function () { - this.manager.setEmitterFrames(frames, this); + return this._pad4; } - 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); +/** + * An instance of the Gamepad Plugin class, if enabled via the `input.gamepad` Scene or Game Config property. + * Use this to create access Gamepads connected to the browser and respond to gamepad buttons. + * + * @name Phaser.Input.InputPlugin#gamepad + * @type {?Phaser.Input.Gamepad.GamepadPlugin} + * @since 3.10.0 + */ +InputPluginCache.register('GamepadPlugin', GamepadPlugin, 'gamepad', 'gamepad', 'inputGamepad'); - this.randomFrame = (isCycle) ? false : true; +module.exports = GamepadPlugin; - this.frameQuantity = GetFastValue(frameConfig, 'quantity', quantity); - } - this._frameLength = this.frames.length; +/***/ }), - if (this._frameLength === 1) - { - this.frameQuantity = 1; - this.randomFrame = false; - } +/***/ 33171: +/***/ ((module) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Tatar SNES USB Controller Gamepad Configuration. + * USB Gamepad (STANDARD GAMEPAD Vendor: 0079 Product: 0011) + * + * @name Phaser.Input.Gamepad.Configs.SNES_USB + * @namespace + * @since 3.0.0 + */ +module.exports = { /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle movement on or off. + * D-Pad up * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setRadial + * @name Phaser.Input.Gamepad.Configs.SNES_USB.UP + * @const + * @type {number} * @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; - }, + UP: 12, /** - * Sets the position of the emitter's particle origin. - * New particles will be emitted here. + * D-Pad down * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setPosition + * @name Phaser.Input.Gamepad.Configs.SNES_USB.DOWN + * @const + * @type {number} * @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; - }, + DOWN: 13, /** - * Sets or modifies a rectangular boundary constraining the particles. + * D-Pad left * - * To remove the boundary, set {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds} to null. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setBounds + * @name Phaser.Input.Gamepad.Configs.SNES_USB.LEFT + * @const + * @type {number} * @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; - }, + LEFT: 14, /** - * Sets the initial horizontal speed of emitted particles. - * Changes the emitter to point mode. + * D-Pad right * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedX + * @name Phaser.Input.Gamepad.Configs.SNES_USB.RIGHT + * @const + * @type {number} * @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; - }, + RIGHT: 15, /** - * Sets the initial vertical speed of emitted particles. - * Changes the emitter to point mode. + * Select button * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeedY + * @name Phaser.Input.Gamepad.Configs.SNES_USB.SELECT + * @const + * @type {number} * @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; - }, + SELECT: 8, /** - * Sets the initial radial speed of emitted particles. - * Changes the emitter to radial mode. + * Start button * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setSpeed + * @name Phaser.Input.Gamepad.Configs.SNES_USB.START + * @const + * @type {number} * @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; - }, + START: 9, /** - * Sets the horizontal scale of emitted particles. + * B Button (Bottom) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleX + * @name Phaser.Input.Gamepad.Configs.SNES_USB.B + * @const + * @type {number} * @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; - }, + B: 0, /** - * Sets the vertical scale of emitted particles. + * A Button (Right) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setScaleY + * @name Phaser.Input.Gamepad.Configs.SNES_USB.A + * @const + * @type {number} * @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; - }, + A: 1, /** - * Sets the scale of emitted particles. + * Y Button (Left) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setScale + * @name Phaser.Input.Gamepad.Configs.SNES_USB.Y + * @const + * @type {number} * @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; - }, + Y: 2, /** - * Sets the horizontal gravity applied to emitted particles. + * X Button (Top) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityX + * @name Phaser.Input.Gamepad.Configs.SNES_USB.X + * @const + * @type {number} * @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; - }, + X: 3, /** - * Sets the vertical gravity applied to emitted particles. + * Left bumper * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravityY + * @name Phaser.Input.Gamepad.Configs.SNES_USB.LEFT_SHOULDER + * @const + * @type {number} * @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; - }, + LEFT_SHOULDER: 4, /** - * Sets the gravity applied to emitted particles. + * Right bumper * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setGravity + * @name Phaser.Input.Gamepad.Configs.SNES_USB.RIGHT_SHOULDER + * @const + * @type {number} * @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; + RIGHT_SHOULDER: 5 - return this; - }, +}; + + +/***/ }), + +/***/ 74982: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * PlayStation DualShock 4 Gamepad Configuration. + * Sony PlayStation DualShock 4 (v2) wireless controller + * + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4 + * @namespace + * @since 3.0.0 + */ +module.exports = { /** - * Sets the opacity of emitted particles. + * D-Pad up * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setAlpha + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.UP + * @const + * @type {number} * @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; - }, + UP: 12, /** - * 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. + * D-Pad down * - * @return {this} This Particle Emitter. + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.DOWN + * @const + * @type {number} + * @since 3.0.0 */ - setTint: function (value) - { - this.tint.onChange(value); - - return this; - }, + DOWN: 13, /** - * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. + * D-Pad left * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitterAngle + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.LEFT + * @const + * @type {number} * @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; - }, + LEFT: 14, /** - * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. + * D-Pad up * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setAngle + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.RIGHT + * @const + * @type {number} * @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; - }, + RIGHT: 15, /** - * Sets the lifespan of newly emitted particles. + * Share button * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setLifespan + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.SHARE + * @const + * @type {number} * @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; - }, + SHARE: 8, /** - * Sets the number of particles released at each flow cycle or explosion. + * Options button * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setQuantity + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.OPTIONS + * @const + * @type {number} * @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; - }, + OPTIONS: 9, /** - * Sets the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#frequency} - * and {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. + * PlayStation logo button * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setFrequency + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.PS + * @const + * @type {number} * @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; - }, + PS: 16, /** - * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#emitZone}. + * Touchpad click * - * 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 + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.TOUCHBAR + * @const + * @type {number} * @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; - }, + TOUCHBAR: 17, /** - * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#deathZone}. + * Cross button (Bottom) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#setDeathZone + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.X + * @const + * @type {number} * @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; - }, + X: 0, /** - * Creates inactive particles and adds them to this emitter's pool. + * Circle button (Right) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#reserve + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.CIRCLE + * @const + * @type {number} * @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; - }, + CIRCLE: 1, /** - * Gets the number of active (in-use) particles in this emitter. + * Square button (Left) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getAliveParticleCount + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.SQUARE + * @const + * @type {number} * @since 3.0.0 - * - * @return {number} The number of particles with `active=true`. */ - getAliveParticleCount: function () - { - return this.alive.length; - }, + SQUARE: 2, /** - * Gets the number of inactive (available) particles in this emitter. + * Triangle button (Top) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getDeadParticleCount + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.TRIANGLE + * @const + * @type {number} * @since 3.0.0 - * - * @return {number} The number of particles with `active=false`. */ - getDeadParticleCount: function () - { - return this.dead.length; - }, + TRIANGLE: 3, /** - * Gets the total number of particles in this emitter. + * Left bumper (L1) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#getParticleCount + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.L1 + * @const + * @type {number} * @since 3.0.0 - * - * @return {number} The number of particles, including both alive and dead. */ - getParticleCount: function () - { - return this.getAliveParticleCount() + this.getDeadParticleCount(); - }, + L1: 4, /** - * Whether this emitter is at its limit (if set). + * Right bumper (R1) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#atLimit + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.R1 + * @const + * @type {number} * @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); - }, + R1: 5, /** - * Sets a function to call for each newly emitted particle. + * Left trigger (L2) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleEmit + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.L2 + * @const + * @type {number} * @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; - }, + L2: 6, /** - * Sets a function to call for each particle death. + * Right trigger (R2) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleDeath + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.R2 + * @const + * @type {number} * @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; - }, + R2: 7, /** - * Deactivates every particle in this emitter. + * Left stick click (L3) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#killAll + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.L3 + * @const + * @type {number} * @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; - }, + L3: 10, /** - * Calls a function for each active particle in this emitter. + * Right stick click (R3) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachAlive + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.R3 + * @const + * @type {number} * @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; - }, + R3: 11, /** - * Calls a function for each inactive particle in this emitter. + * Left stick horizontal * - * @method Phaser.GameObjects.Particles.ParticleEmitter#forEachDead + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.LEFT_STICK_H + * @const + * @type {number} * @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; - }, + LEFT_STICK_H: 0, /** - * 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). + * Left stick vertical * - * 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. + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.LEFT_STICK_V + * @const + * @type {number} + * @since 3.0.0 + */ + LEFT_STICK_V: 1, + + /** + * Right stick horizontal * - * @method Phaser.GameObjects.Particles.ParticleEmitter#start + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.RIGHT_STICK_H + * @const + * @type {number} * @since 3.0.0 + */ + RIGHT_STICK_H: 2, + + /** + * Right stick vertical * - * @return {this} This Particle Emitter. + * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.RIGHT_STICK_V + * @const + * @type {number} + * @since 3.0.0 */ - start: function () - { - this.on = true; + RIGHT_STICK_V: 3 + +}; - this._counter = 0; - return this; - }, +/***/ }), + +/***/ 43247: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * XBox 360 Gamepad Configuration. + * + * @name Phaser.Input.Gamepad.Configs.XBOX_360 + * @namespace + * @since 3.0.0 + */ +module.exports = { /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on off} the emitter. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#stop - * @since 3.11.0 + * D-Pad up * - * @return {this} This Particle Emitter. + * @name Phaser.Input.Gamepad.Configs.XBOX_360.UP + * @const + * @type {number} + * @since 3.0.0 */ - stop: function () - { - this.on = false; - - return this; - }, + UP: 12, /** - * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Deactivates} the emitter. + * D-Pad down * - * @method Phaser.GameObjects.Particles.ParticleEmitter#pause + * @name Phaser.Input.Gamepad.Configs.XBOX_360.DOWN + * @const + * @type {number} * @since 3.0.0 - * - * @return {this} This Particle Emitter. */ - pause: function () - { - this.active = false; - - return this; - }, + DOWN: 13, /** - * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Activates} the emitter. + * D-Pad left * - * @method Phaser.GameObjects.Particles.ParticleEmitter#resume + * @name Phaser.Input.Gamepad.Configs.XBOX_360.LEFT + * @const + * @type {number} * @since 3.0.0 - * - * @return {this} This Particle Emitter. */ - resume: function () - { - this.active = true; - - return this; - }, + LEFT: 14, /** - * Removes the emitter from its manager and the scene. - * - * @method Phaser.GameObjects.Particles.ParticleEmitter#remove - * @since 3.22.0 + * D-Pad right * - * @return {this} This Particle Emitter. + * @name Phaser.Input.Gamepad.Configs.XBOX_360.RIGHT + * @const + * @type {number} + * @since 3.0.0 */ - remove: function () - { - this.manager.removeEmitter(this); - - return this; - }, + RIGHT: 15, /** - * Sorts active particles with {@link Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback}. + * XBox menu button * - * @method Phaser.GameObjects.Particles.ParticleEmitter#depthSort + * @name Phaser.Input.Gamepad.Configs.XBOX_360.MENU + * @const + * @type {number} * @since 3.0.0 - * - * @return {this} This Particle Emitter. */ - depthSort: function () - { - StableSort(this.alive, this.depthSortCallback); - - return this; - }, + MENU: 16, /** - * 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. + * A button (Bottom) * - * @method Phaser.GameObjects.Particles.ParticleEmitter#flow + * @name Phaser.Input.Gamepad.Configs.XBOX_360.A + * @const + * @type {number} * @since 3.0.0 + */ + A: 0, + + /** + * B button (Right) * - * @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. + * @name Phaser.Input.Gamepad.Configs.XBOX_360.B + * @const + * @type {number} + * @since 3.0.0 */ - flow: function (frequency, count) - { - if (count === undefined) { count = 1; } + B: 1, - this.frequency = frequency; + /** + * X button (Left) + * + * @name Phaser.Input.Gamepad.Configs.XBOX_360.X + * @const + * @type {number} + * @since 3.0.0 + */ + X: 2, - this.quantity.onChange(count); + /** + * Y button (Top) + * + * @name Phaser.Input.Gamepad.Configs.XBOX_360.Y + * @const + * @type {number} + * @since 3.0.0 + */ + Y: 3, - return this.start(); - }, + /** + * Left Bumper + * + * @name Phaser.Input.Gamepad.Configs.XBOX_360.LB + * @const + * @type {number} + * @since 3.0.0 + */ + LB: 4, /** - * Puts the emitter in explode mode (frequency = -1), stopping any current particle flow, and emits several particles all at once. + * Right Bumper * - * @method Phaser.GameObjects.Particles.ParticleEmitter#explode + * @name Phaser.Input.Gamepad.Configs.XBOX_360.RB + * @const + * @type {number} * @since 3.0.0 + */ + RB: 5, + + /** + * Left Trigger * - * @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. + * @name Phaser.Input.Gamepad.Configs.XBOX_360.LT + * @const + * @type {number} + * @since 3.0.0 + */ + LT: 6, + + /** + * Right Trigger * - * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. + * @name Phaser.Input.Gamepad.Configs.XBOX_360.RT + * @const + * @type {number} + * @since 3.0.0 */ - explode: function (count, x, y) - { - this.frequency = -1; + RT: 7, - return this.emitParticle(count, x, y); - }, + /** + * Back / Change View button + * + * @name Phaser.Input.Gamepad.Configs.XBOX_360.BACK + * @const + * @type {number} + * @since 3.0.0 + */ + BACK: 8, /** - * Emits particles at a given position (or the emitter's current position). + * Start button * - * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticleAt + * @name Phaser.Input.Gamepad.Configs.XBOX_360.START + * @const + * @type {number} * @since 3.0.0 + */ + START: 9, + + /** + * Left Stick press * - * @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. + * @name Phaser.Input.Gamepad.Configs.XBOX_360.LS + * @const + * @type {number} + * @since 3.0.0 + */ + LS: 10, + + /** + * Right stick press * - * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. + * @name Phaser.Input.Gamepad.Configs.XBOX_360.RS + * @const + * @type {number} + * @since 3.0.0 */ - emitParticleAt: function (x, y, count) - { - return this.emitParticle(count, x, y); - }, + RS: 11, /** - * Emits particles at a given position (or the emitter's current position). + * Left Stick horizontal * - * @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticle + * @name Phaser.Input.Gamepad.Configs.XBOX_360.LEFT_STICK_H + * @const + * @type {number} * @since 3.0.0 + */ + LEFT_STICK_H: 0, + + /** + * Left Stick vertical * - * @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. + * @name Phaser.Input.Gamepad.Configs.XBOX_360.LEFT_STICK_V + * @const + * @type {number} + * @since 3.0.0 + */ + LEFT_STICK_V: 1, + + /** + * Right Stick horizontal * - * @return {Phaser.GameObjects.Particles.Particle} The most recently emitted Particle. + * @name Phaser.Input.Gamepad.Configs.XBOX_360.RIGHT_STICK_H + * @const + * @type {number} + * @since 3.0.0 + */ + RIGHT_STICK_H: 2, + + /** + * Right Stick vertical * - * @see Phaser.GameObjects.Particles.Particle#fire + * @name Phaser.Input.Gamepad.Configs.XBOX_360.RIGHT_STICK_V + * @const + * @type {number} + * @since 3.0.0 */ - emitParticle: function (count, x, y) - { - if (this.atLimit()) - { - return; - } + RIGHT_STICK_V: 3 - 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(); +/***/ 4898: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!particle) - { - particle = new this.particleClass(this); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - particle.fire(followX, followY); +/** + * @namespace Phaser.Input.Gamepad.Configs + */ - if (this.particleBringToTop) - { - this.alive.push(particle); - } - else - { - this.alive.unshift(particle); - } +module.exports = { - if (this.emitCallback) - { - this.emitCallback.call(this.emitCallbackScope, particle, this); - } + DUALSHOCK_4: __webpack_require__(74982), + SNES_USB: __webpack_require__(33171), + XBOX_360: __webpack_require__(43247) - 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); +/***/ 17344: +/***/ ((module) => { - if (this.trackVisible) - { - this.visible = this.follow.visible; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Any particle processors? - var processors = this.manager.getProcessors(); +/** + * The Gamepad Button Down Event. + * + * This event is dispatched by the Gamepad Plugin when a button has been pressed on any active Gamepad. + * + * Listen to this event from within a Scene using: `this.input.gamepad.on('down', listener)`. + * + * You can also listen for a DOWN event from a Gamepad instance. See the [GAMEPAD_BUTTON_DOWN]{@linkcode Phaser.Input.Gamepad.Events#event:GAMEPAD_BUTTON_DOWN} event for details. + * + * @event Phaser.Input.Gamepad.Events#BUTTON_DOWN + * @type {string} + * @since 3.10.0 + * + * @param {Phaser.Input.Gamepad} pad - A reference to the Gamepad on which the button was pressed. + * @param {Phaser.Input.Gamepad.Button} button - A reference to the Button which was pressed. + * @param {number} value - The value of the button at the time it was pressed. Between 0 and 1. Some Gamepads have pressure-sensitive buttons. + */ +module.exports = 'down'; - 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]; +/***/ 36635: +/***/ ((module) => { - // update returns `true` if the particle is now dead (lifeCurrent <= 0) - if (particle.update(delta, step, processors)) - { - rip.push({ index: i, particle: particle }); - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Move dead particles to the dead array - length = rip.length; +/** + * The Gamepad Button Up Event. + * + * This event is dispatched by the Gamepad Plugin when a button has been released on any active Gamepad. + * + * Listen to this event from within a Scene using: `this.input.gamepad.on('up', listener)`. + * + * You can also listen for an UP event from a Gamepad instance. See the [GAMEPAD_BUTTON_UP]{@linkcode Phaser.Input.Gamepad.Events#event:GAMEPAD_BUTTON_UP} event for details. + * + * @event Phaser.Input.Gamepad.Events#BUTTON_UP + * @type {string} + * @since 3.10.0 + * + * @param {Phaser.Input.Gamepad} pad - A reference to the Gamepad on which the button was released. + * @param {Phaser.Input.Gamepad.Button} button - A reference to the Button which was released. + * @param {number} value - The value of the button at the time it was released. Between 0 and 1. Some Gamepads have pressure-sensitive buttons. + */ +module.exports = 'up'; - 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); +/***/ 85724: +/***/ ((module) => { - // Add to dead array - dead.push(entry.particle); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Callback - if (deathCallback) - { - deathCallback.call(deathCallbackScope, entry.particle); - } +/** + * The Gamepad Connected Event. + * + * This event is dispatched by the Gamepad Plugin when a Gamepad has been connected. + * + * Listen to this event from within a Scene using: `this.input.gamepad.once('connected', listener)`. + * + * Note that the browser may require you to press a button on a gamepad before it will allow you to access it, + * this is for security reasons. However, it may also trust the page already, in which case you won't get the + * 'connected' event and instead should check `GamepadPlugin.total` to see if it thinks there are any gamepads + * already connected. + * + * @event Phaser.Input.Gamepad.Events#CONNECTED + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Gamepad} pad - A reference to the Gamepad which was connected. + * @param {Event} event - The native DOM Event that triggered the connection. + */ +module.exports = 'connected'; - entry.particle.resetPosition(); - } - } - if (!this.on) - { - return; - } +/***/ }), - if (this.frequency === 0) - { - this.emitParticle(); - } - else if (this.frequency > 0) - { - this._counter -= delta; +/***/ 55832: +/***/ ((module) => { - if (this._counter <= 0) - { - this.emitParticle(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // counter = frequency - remained from previous delta - this._counter = (this.frequency - Math.abs(this._counter)); - } - } - }, +/** + * The Gamepad Disconnected Event. + * + * This event is dispatched by the Gamepad Plugin when a Gamepad has been disconnected. + * + * Listen to this event from within a Scene using: `this.input.gamepad.once('disconnected', listener)`. + * + * @event Phaser.Input.Gamepad.Events#DISCONNECTED + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Gamepad} pad - A reference to the Gamepad which was disconnected. + * @param {Event} event - The native DOM Event that triggered the disconnection. + */ +module.exports = 'disconnected'; - /** - * 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; +/***/ 772: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Gamepad Button Down Event. + * + * This event is dispatched by a Gamepad instance when a button has been pressed on it. + * + * Listen to this event from a Gamepad instance. Once way to get this is from the `pad1`, `pad2`, etc properties on the Gamepad Plugin: + * `this.input.gamepad.pad1.on('down', listener)`. + * + * Note that you will not receive any Gamepad button events until the browser considers the Gamepad as being 'connected'. + * + * You can also listen for a DOWN event from the Gamepad Plugin. See the [BUTTON_DOWN]{@linkcode Phaser.Input.Gamepad.Events#event:BUTTON_DOWN} event for details. + * + * @event Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_DOWN + * @type {string} + * @since 3.10.0 + * + * @param {number} index - The index of the button that was pressed. + * @param {number} value - The value of the button at the time it was pressed. Between 0 and 1. Some Gamepads have pressure-sensitive buttons. + * @param {Phaser.Input.Gamepad.Button} button - A reference to the Button which was pressed. + */ +module.exports = 'down'; /***/ }), -/* 453 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 33608: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); - /** - * @classdesc - * A Death Zone. + * The Gamepad Button Up Event. * - * A Death Zone is a special type of zone that will kill a Particle as soon as it either enters, or leaves, the zone. + * This event is dispatched by a Gamepad instance when a button has been released on it. * - * 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. + * Listen to this event from a Gamepad instance. Once way to get this is from the `pad1`, `pad2`, etc properties on the Gamepad Plugin: + * `this.input.gamepad.pad1.on('up', listener)`. * - * @class DeathZone - * @memberof Phaser.GameObjects.Particles.Zones - * @constructor - * @since 3.0.0 + * Note that you will not receive any Gamepad button events until the browser considers the Gamepad as being 'connected'. * - * @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` + * You can also listen for an UP event from the Gamepad Plugin. See the [BUTTON_UP]{@linkcode Phaser.Input.Gamepad.Events#event:BUTTON_UP} event for details. + * + * @event Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_UP + * @type {string} + * @since 3.10.0 + * + * @param {number} index - The index of the button that was released. + * @param {number} value - The value of the button at the time it was released. Between 0 and 1. Some Gamepads have pressure-sensitive buttons. + * @param {Phaser.Input.Gamepad.Button} button - A reference to the Button which was released. */ -var DeathZone = new Class({ +module.exports = 'up'; - 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; - }, +/***/ 43200: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return (withinZone && this.killOnEnter || !withinZone && !this.killOnEnter); - } +/** + * @namespace Phaser.Input.Gamepad.Events + */ -}); +module.exports = { -module.exports = DeathZone; + BUTTON_DOWN: __webpack_require__(17344), + BUTTON_UP: __webpack_require__(36635), + CONNECTED: __webpack_require__(85724), + DISCONNECTED: __webpack_require__(55832), + GAMEPAD_BUTTON_DOWN: __webpack_require__(772), + GAMEPAD_BUTTON_UP: __webpack_require__(33608) + +}; + + +/***/ }), + +/***/ 92636: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Input.Gamepad + */ + +module.exports = { + + Axis: __webpack_require__(70848), + Button: __webpack_require__(21274), + Events: __webpack_require__(43200), + Gamepad: __webpack_require__(75956), + GamepadPlugin: __webpack_require__(1379), + + Configs: __webpack_require__(4898) +}; + + +/***/ }), + +/***/ 20873: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(72687); +var Extend = __webpack_require__(98611); + +/** + * @namespace Phaser.Input + */ + +var Input = { + + CreatePixelPerfectHandler: __webpack_require__(18104), + CreateInteractiveObject: __webpack_require__(27395), + Events: __webpack_require__(33963), + Gamepad: __webpack_require__(92636), + InputManager: __webpack_require__(69898), + InputPlugin: __webpack_require__(12499), + InputPluginCache: __webpack_require__(63399), + Keyboard: __webpack_require__(28388), + Mouse: __webpack_require__(11343), + Pointer: __webpack_require__(40398), + Touch: __webpack_require__(77423) + +}; + +// Merge in the consts +Input = Extend(false, Input, CONST); + +module.exports = Input; /***/ }), -/* 454 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71064: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); +var ArrayRemove = __webpack_require__(66458); +var Class = __webpack_require__(56694); +var GameEvents = __webpack_require__(97081); +var InputEvents = __webpack_require__(33963); +var KeyCodes = __webpack_require__(11873); +var NOOP = __webpack_require__(72283); /** * @classdesc - * A zone that places particles on a shape's edges. + * The Keyboard Manager is a helper class that belongs to the global Input Manager. * - * @class EdgeZone - * @memberof Phaser.GameObjects.Particles.Zones + * 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.0.0 + * @since 3.16.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. + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. */ -var EdgeZone = new Class({ +var KeyboardManager = new Class({ initialize: - function EdgeZone (source, quantity, stepRate, yoyo, seamless) + function KeyboardManager (inputManager) { - if (yoyo === undefined) { yoyo = false; } - if (seamless === undefined) { seamless = true; } - /** - * An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + * A reference to the Input Manager. * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#source - * @type {Phaser.Types.GameObjects.Particles.EdgeZoneSource|Phaser.Types.GameObjects.Particles.RandomZoneSource} - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardManager#manager + * @type {Phaser.Input.InputManager} + * @since 3.16.0 */ - this.source = source; + this.manager = inputManager; /** - * The points placed on the source edge. + * An internal event queue. * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#points - * @type {Phaser.Geom.Point[]} - * @default [] - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardManager#queue + * @type {KeyboardEvent[]} + * @private + * @since 3.16.0 */ - this.points = []; + this.queue = []; /** - * The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. + * A flag that controls if the non-modified keys, matching those stored in the `captures` array, + * have `preventDefault` called on them or not. * - * @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. + * 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. * - * @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. + * 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.GameObjects.Particles.Zones.EdgeZone#yoyo + * @name Phaser.Input.Keyboard.KeyboardManager#preventDefault * @type {boolean} - * @since 3.0.0 + * @since 3.16.0 */ - this.yoyo = yoyo; + this.preventDefault = true; /** - * The counter used for iterating the EdgeZone's points. + * 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`. * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#counter - * @type {number} - * @default -1 - * @since 3.0.0 + * 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.counter = -1; + this.captures = []; /** - * Whether one endpoint will be removed if it's identical to the other. + * A boolean that controls if the Keyboard Manager is enabled or not. + * Can be toggled on the fly. * - * @name Phaser.GameObjects.Particles.Zones.EdgeZone#seamless + * @name Phaser.Input.Keyboard.KeyboardManager#enabled * @type {boolean} - * @since 3.0.0 + * @default false + * @since 3.16.0 */ - this.seamless = seamless; + this.enabled = false; /** - * An internal count of the points belonging to this EdgeZone. + * 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.GameObjects.Particles.Zones.EdgeZone#_length - * @type {number} - * @private - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardManager#target + * @type {any} + * @since 3.16.0 */ - this._length = 0; + this.target; /** - * An internal value used to keep track of the current iteration direction for the EdgeZone's points. + * The Key Down Event handler. + * This function is sent the native DOM KeyEvent. + * Initially empty and bound in the `startListeners` method. * - * 0 = forwards, 1 = backwards + * @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.GameObjects.Particles.Zones.EdgeZone#_direction - * @type {number} - * @private - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardManager#onKeyUp + * @type {function} + * @since 3.16.00 */ - this._direction = 0; + this.onKeyUp = NOOP; - this.updateSource(); + inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); }, /** - * 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 + * The Keyboard Manager boot process. * - * @return {this} This Edge Zone. + * @method Phaser.Input.Keyboard.KeyboardManager#boot + * @private + * @since 3.16.0 */ - updateSource: function () + boot: 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]; + var config = this.manager.config; - if (a.x === b.x && a.y === b.y) - { - this.points.pop(); - } - } + this.enabled = config.inputKeyboard; + this.target = config.inputKeyboardEventTarget; - var oldLength = this._length; + this.addCapture(config.inputKeyboardCapture); - this._length = this.points.length; + if (!this.target && window) + { + this.target = window; + } - // Adjust counter if we now have less points than before - if (this._length < oldLength && this.counter > this._length) + if (this.enabled && this.target) { - this.counter = this._length - 1; + this.startListeners(); } - return this; + this.manager.game.events.on(GameEvents.POST_STEP, this.postUpdate, 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. + * Starts the Keyboard Event listeners running. + * This is called automatically and does not need to be manually invoked. * - * @return {this} This Edge Zone. + * @method Phaser.Input.Keyboard.KeyboardManager#startListeners + * @since 3.16.0 */ - changeSource: function (source) + startListeners: function () { - this.source = source; - - return this.updateSource(); - }, + var _this = this; - /** - * 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.onKeyDown = function (event) { - this.counter++; - - if (this.counter >= this._length) + if (event.defaultPrevented || !_this.enabled || !_this.manager) { - if (this.yoyo) - { - this._direction = 1; - this.counter = this._length - 1; - } - else - { - this.counter = 0; - } + // Do nothing if event already handled + return; } - } - else - { - this.counter--; - if (this.counter === -1) + _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) { - if (this.yoyo) - { - this._direction = 0; - this.counter = 0; - } - else - { - this.counter = this._length - 1; - } + event.preventDefault(); } - } - - var point = this.points[this.counter]; + }; - if (point) + this.onKeyUp = function (event) { - particle.x = point.x; - particle.y = point.y; - } - } + if (event.defaultPrevented || !_this.enabled || !_this.manager) + { + // Do nothing if event already handled + return; + } -}); + _this.queue.push(event); -module.exports = EdgeZone; + _this.manager.events.emit(InputEvents.MANAGER_PROCESS); + var modified = (event.altKey || event.ctrlKey || event.shiftKey || event.metaKey); -/***/ }), -/* 455 */ -/***/ (function(module, exports) { + if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) + { + event.preventDefault(); + } + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var target = this.target; -/** - * 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])) + if (target) { - return true; - } - } - - return false; -}; - -module.exports = HasAny; + target.addEventListener('keydown', this.onKeyDown, false); + target.addEventListener('keyup', this.onKeyUp, false); + this.enabled = true; + } + }, -/***/ }), -/* 456 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + target.removeEventListener('keydown', this.onKeyDown, false); + target.removeEventListener('keyup', this.onKeyUp, false); -var Class = __webpack_require__(0); -var Vector2 = __webpack_require__(3); + this.enabled = false; + }, -/** - * @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(); - }, + /** + * 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 = []; + }, /** - * Get the next point in the Zone and set its coordinates on the given Particle. + * 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. * - * @method Phaser.GameObjects.Particles.Zones.RandomZone#getPoint - * @since 3.0.0 + * 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. * - * @param {Phaser.GameObjects.Particles.Particle} particle - The Particle. + * 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. */ - getPoint: function (particle) + addCapture: function (keycode) { - var vec = this._tempVec; - - this.source.getRandomPoint(vec); - - particle.x = vec.x; - particle.y = vec.y; - } - -}); - -module.exports = RandomZone; - - -/***/ }), -/* 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 Components = __webpack_require__(11); -var Sprite = __webpack_require__(73); + if (typeof keycode === 'string') + { + keycode = keycode.split(','); + } -/** - * @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({ + if (!Array.isArray(keycode)) + { + keycode = [ keycode ]; + } - Extends: Sprite, + var captures = this.captures; - Mixins: [ - Components.PathFollower - ], + for (var i = 0; i < keycode.length; i++) + { + var code = keycode[i]; - initialize: + if (typeof code === 'string') + { + code = KeyCodes[code.trim().toUpperCase()]; + } - function PathFollower (scene, path, x, y, texture, frame) - { - Sprite.call(this, scene, x, y, texture, frame); + if (captures.indexOf(code) === -1) + { + captures.push(code); + } + } - this.path = path; + this.preventDefault = captures.length > 0; }, /** - * Internal update handler that advances this PathFollower along the path. + * Removes an existing key capture. * - * Called automatically by the Scene step, should not typically be called directly. + * 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. * - * @method Phaser.GameObjects.PathFollower#preUpdate - * @protected - * @since 3.0.0 + * You can pass in a single key code value, or an array of key codes, or a string: * - * @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. + * ```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. */ - preUpdate: function (time, delta) + removeCapture: function (keycode) { - this.anims.update(time, delta); - this.pathUpdate(time); - } - -}); + if (typeof keycode === 'string') + { + keycode = keycode.split(','); + } -module.exports = PathFollower; + if (!Array.isArray(keycode)) + { + keycode = [ keycode ]; + } + var captures = this.captures; -/***/ }), -/* 458 */ -/***/ (function(module, exports) { + for (var i = 0; i < keycode.length; i++) + { + var code = keycode[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (typeof code === 'string') + { + code = KeyCodes[code.toUpperCase()]; + } -/** - * 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; + ArrayRemove(captures, code); + } - var lineWidths = []; - var maxLineWidth = 0; - var drawnLines = lines.length; + this.preventDefault = captures.length > 0; + }, - if (style.maxLines > 0 && style.maxLines < lines.length) + /** + * Removes all keyboard captures and sets the `preventDefault` property to `false`. + * + * @method Phaser.Input.Keyboard.KeyboardManager#clearCaptures + * @since 3.16.0 + */ + clearCaptures: function () { - drawnLines = style.maxLines; - } - - style.syncFont(canvas, context); + this.captures = []; - // Text Width + this.preventDefault = false; + }, - for (var i = 0; i < drawnLines; i++) + /** + * Destroys this Keyboard Manager instance. + * + * @method Phaser.Input.Keyboard.KeyboardManager#destroy + * @since 3.16.0 + */ + destroy: function () { - var lineWidth = style.strokeThickness; - - lineWidth += context.measureText(lines[i]).width; - - // Adjust for wrapped text - if (style.wordWrap) - { - lineWidth -= context.measureText(' ').width; - } + this.stopListeners(); - lineWidths[i] = Math.ceil(lineWidth); - maxLineWidth = Math.max(maxLineWidth, lineWidths[i]); - } + this.clearCaptures(); - // Text Height + this.queue = []; - var lineHeight = size.fontSize + style.strokeThickness; - var height = lineHeight * drawnLines; - var lineSpacing = text.lineSpacing; + this.manager.game.events.off(GameEvents.POST_RENDER, this.postUpdate, this); - // Adjust for line spacing - if (drawnLines > 1) - { - height += lineSpacing * (drawnLines - 1); + this.target = null; + this.enabled = false; + this.manager = null; } - return { - width: maxLineWidth, - height: height, - lines: drawnLines, - lineWidths: lineWidths, - lineSpacing: lineSpacing, - lineHeight: lineHeight - }; -}; +}); -module.exports = GetTextSize; +module.exports = KeyboardManager; /***/ }), -/* 459 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 89666: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(460); - -// 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 ] -}; +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(94030); +var GameEvents = __webpack_require__(97081); +var GetValue = __webpack_require__(10850); +var InputEvents = __webpack_require__(33963); +var InputPluginCache = __webpack_require__(63399); +var Key = __webpack_require__(50165); +var KeyCodes = __webpack_require__(11873); +var KeyCombo = __webpack_require__(95625); +var KeyMap = __webpack_require__(48044); +var SceneEvents = __webpack_require__(7599); +var SnapFloor = __webpack_require__(84314); /** * @classdesc - * A TextStyle class manages all of the style settings for a Text object. + * The Keyboard Plugin is an input plugin that belongs to the Scene-owned Input system. * - * 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. + * Its role is to listen for native DOM Keyboard Events and then process them. * - * @class TextStyle - * @memberof Phaser.GameObjects + * You do not need to create this class directly, the Input system will create an instance of it automatically. + * + * You can access it from within a Scene using `this.input.keyboard`. For example, you can do: + * + * ```javascript + * this.input.keyboard.on('keydown', callback, context); + * ``` + * + * Or, to listen for a specific key: + * + * ```javascript + * this.input.keyboard.on('keydown-A', callback, context); + * ``` + * + * You can also create Key objects, which you can then poll in your game loop: + * + * ```javascript + * var spaceBar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); + * ``` + * + * If you have multiple parallel Scenes, each trying to get keyboard input, be sure to disable capture on them to stop them from + * stealing input from another Scene in the list. You can do this with `this.input.keyboard.enabled = false` within the + * Scene to stop all input, or `this.input.keyboard.preventDefault = false` to stop a Scene halting input on another Scene. + * + * _Note_: Many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting. + * See http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/ for more details + * and use the site https://w3c.github.io/uievents/tools/key-event-viewer.html to test your n-key support in browser. + * + * Also please be aware that certain browser extensions can disable or override Phaser keyboard handling. + * For example the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. + * And there are others. So, please check your extensions before opening Phaser issues about keys that don't work. + * + * @class KeyboardPlugin + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Input.Keyboard * @constructor - * @since 3.0.0 + * @since 3.10.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. + * @param {Phaser.Input.InputPlugin} sceneInputPlugin - A reference to the Scene Input Plugin that the KeyboardPlugin belongs to. */ -var TextStyle = new Class({ +var KeyboardPlugin = new Class({ + + Extends: EventEmitter, initialize: - function TextStyle (text, style) + function KeyboardPlugin (sceneInputPlugin) { - /** - * 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; + EventEmitter.call(this); /** - * The horizontal shadow offset. + * A reference to the core game, so we can listen for visibility events. * - * @name Phaser.GameObjects.TextStyle#shadowOffsetX - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardPlugin#game + * @type {Phaser.Game} + * @since 3.16.0 */ - this.shadowOffsetX; + this.game = sceneInputPlugin.systems.game; /** - * The vertical shadow offset. + * A reference to the Scene that this Input Plugin is responsible for. * - * @name Phaser.GameObjects.TextStyle#shadowOffsetY - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardPlugin#scene + * @type {Phaser.Scene} + * @since 3.10.0 */ - this.shadowOffsetY; + this.scene = sceneInputPlugin.scene; /** - * The shadow color. + * A reference to the Scene Systems Settings. * - * @name Phaser.GameObjects.TextStyle#shadowColor - * @type {string} - * @default '#000' - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardPlugin#settings + * @type {Phaser.Types.Scenes.SettingsObject} + * @since 3.10.0 */ - this.shadowColor; + this.settings = this.scene.sys.settings; /** - * The shadow blur radius. + * A reference to the Scene Input Plugin that created this Keyboard Plugin. * - * @name Phaser.GameObjects.TextStyle#shadowBlur - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardPlugin#sceneInputPlugin + * @type {Phaser.Input.InputPlugin} + * @since 3.10.0 */ - this.shadowBlur; + this.sceneInputPlugin = sceneInputPlugin; /** - * Whether shadow stroke is enabled or not. + * A reference to the global Keyboard Manager. * - * @name Phaser.GameObjects.TextStyle#shadowStroke - * @type {boolean} - * @default false - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardPlugin#manager + * @type {Phaser.Input.Keyboard.KeyboardManager} + * @since 3.16.0 */ - this.shadowStroke; + this.manager = sceneInputPlugin.manager.keyboard; /** - * Whether shadow fill is enabled or not. + * A boolean that controls if this Keyboard Plugin is enabled or not. + * Can be toggled on the fly. * - * @name Phaser.GameObjects.TextStyle#shadowFill + * @name Phaser.Input.Keyboard.KeyboardPlugin#enabled * @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 + * @default true + * @since 3.10.0 */ - this.fixedHeight; + this.enabled = true; /** - * 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. + * An array of Key objects to process. * - * @name Phaser.GameObjects.TextStyle#resolution - * @type {number} - * @default 0 - * @since 3.12.0 + * @name Phaser.Input.Keyboard.KeyboardPlugin#keys + * @type {Phaser.Input.Keyboard.Key[]} + * @since 3.10.0 */ - this.resolution; + this.keys = []; /** - * Whether the text should render right to left. + * An array of KeyCombo objects to process. * - * @name Phaser.GameObjects.TextStyle#rtl - * @type {boolean} - * @default false - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardPlugin#combos + * @type {Phaser.Input.Keyboard.KeyCombo[]} + * @since 3.10.0 */ - this.rtl; + this.combos = []; /** - * The test string to use when measuring the font. + * Internal repeat key flag. * - * @name Phaser.GameObjects.TextStyle#testString + * @name Phaser.Input.Keyboard.KeyboardPlugin#prevCode * @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 + * @private + * @since 3.50.0 */ - this.baselineX; + this.prevCode = null; /** - * The amount of vertical padding added to the height of the text when calculating the font metrics. + * Internal repeat key flag. * - * @name Phaser.GameObjects.TextStyle#baselineY + * @name Phaser.Input.Keyboard.KeyboardPlugin#prevTime * @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 + * @private + * @since 3.50.0 */ - this.wordWrapUseAdvanced; + this.prevTime = 0; /** - * The font style, size and family. + * Internal repeat key flag. * - * @name Phaser.GameObjects.TextStyle#_font + * @name Phaser.Input.Keyboard.KeyboardPlugin#prevType * @type {string} * @private - * @since 3.0.0 + * @since 3.50.1 */ - this._font; - - // Set to defaults + user style - this.setStyle(style, false, true); - - var metrics = GetValue(style, 'metrics', false); + this.prevType = null; - // 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); - } + sceneInputPlugin.pluginEvents.once(InputEvents.BOOT, this.boot, this); + sceneInputPlugin.pluginEvents.on(InputEvents.START, this.start, 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. + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @method Phaser.Input.Keyboard.KeyboardPlugin#boot + * @private + * @since 3.10.0 */ - setStyle: function (style, updateText, setDefaults) + boot: function () { - 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); - } + var settings = this.settings.input; - this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); + this.enabled = GetValue(settings, 'keyboard', true); - // Allow for 'fill' to be used in place of 'color' - var fill = GetValue(style, 'fill', null); + var captures = GetValue(settings, 'keyboard.capture', null); - if (fill !== null) + if (captures) { - this.color = fill; + this.addCaptures(captures); } - if (updateText) - { - return this.update(true); - } - else - { - return this.parent; - } + this.sceneInputPlugin.pluginEvents.once(InputEvents.DESTROY, this.destroy, this); }, /** - * Synchronize the font settings to the given Canvas Rendering Context. - * - * @method Phaser.GameObjects.TextStyle#syncFont - * @since 3.0.0 + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. * - * @param {HTMLCanvasElement} canvas - The Canvas Element. - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. + * @method Phaser.Input.Keyboard.KeyboardPlugin#start + * @private + * @since 3.10.0 */ - syncFont: function (canvas, context) + start: function () { - context.font = this._font; - }, + this.sceneInputPlugin.manager.events.on(InputEvents.MANAGER_PROCESS, this.update, this); - /** - * 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'; + this.sceneInputPlugin.pluginEvents.once(InputEvents.SHUTDOWN, this.shutdown, this); - context.fillStyle = this.color; - context.strokeStyle = this.stroke; + this.game.events.on(GameEvents.BLUR, this.resetKeys, this); - context.lineWidth = this.strokeThickness; - context.lineCap = 'round'; - context.lineJoin = 'round'; + this.scene.sys.events.on(SceneEvents.PAUSE, this.resetKeys, this); + this.scene.sys.events.on(SceneEvents.SLEEP, this.resetKeys, this); }, /** - * Synchronize the shadow settings to the given Canvas Rendering Context. + * Checks to see if both this plugin and the Scene to which it belongs is active. * - * @method Phaser.GameObjects.TextStyle#syncShadow - * @since 3.0.0 + * @method Phaser.Input.Keyboard.KeyboardPlugin#isActive + * @since 3.10.0 * - * @param {CanvasRenderingContext2D} context - The Canvas Rendering Context. - * @param {boolean} enabled - Whether shadows are enabled or not. + * @return {boolean} `true` if the plugin and the Scene it belongs to is active. */ - syncShadow: function (context, enabled) + isActive: function () { - 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; - } + return (this.enabled && this.scene.sys.canInput()); }, /** - * Update the style settings for the parent Text object. + * 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. * - * @method Phaser.GameObjects.TextStyle#update - * @since 3.0.0 + * This `addCapture` method enables consuming keyboard events for specific keys, so they don't bubble up the browser + * and cause the default behaviors. * - * @param {boolean} recalculateMetrics - Whether to recalculate font and text metrics. + * 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. * - * @return {Phaser.GameObjects.Text} The parent Text object. + * You can pass a single key code value: + * + * ```javascript + * this.input.keyboard.addCapture(62); + * ``` + * + * An array of key codes: + * + * ```javascript + * this.input.keyboard.addCapture([ 62, 63, 64 ]); + * ``` + * + * Or, a comma-delimited 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. + * + * @method Phaser.Input.Keyboard.KeyboardPlugin#addCapture + * @since 3.16.0 + * + * @param {(string|number|number[]|any[])} keycode - The Key Codes to enable event capture for. + * + * @return {this} This KeyboardPlugin object. */ - update: function (recalculateMetrics) + addCapture: function (keycode) { - if (recalculateMetrics) - { - this._font = [ this.fontStyle, this.fontSize, this.fontFamily ].join(' ').trim(); - - this.metrics = MeasureText(this); - } + this.manager.addCapture(keycode); - return this.parent.updateText(); + return this; }, /** - * Set the font. + * Removes an existing key capture. * - * If a string is given, the font family is set. + * 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. * - * If an object is given, the `fontFamily`, `fontSize` and `fontStyle` - * properties of that object are set. + * You can pass a single key code value: * - * @method Phaser.GameObjects.TextStyle#setFont - * @since 3.0.0 + * ```javascript + * this.input.keyboard.removeCapture(62); + * ``` * - * @param {(string|object)} font - The font family or font settings to set. - * @param {boolean} [updateText=true] - Whether to update the text immediately. + * An array of key codes: * - * @return {Phaser.GameObjects.Text} The parent Text object. + * ```javascript + * this.input.keyboard.removeCapture([ 62, 63, 64 ]); + * ``` + * + * Or, a comma-delimited 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. + * + * @method Phaser.Input.Keyboard.KeyboardPlugin#removeCapture + * @since 3.16.0 + * + * @param {(string|number|number[]|any[])} keycode - The Key Codes to disable event capture for. + * + * @return {this} This KeyboardPlugin object. */ - setFont: function (font, updateText) + removeCapture: function (keycode) { - 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); - } - } + this.manager.removeCapture(keycode); - return this.parent; + return this; }, /** - * Set the font family. - * - * @method Phaser.GameObjects.TextStyle#setFontFamily - * @since 3.0.0 + * Returns an array that contains all of the keyboard captures currently enabled. * - * @param {string} family - The font family. + * @method Phaser.Input.Keyboard.KeyboardPlugin#getCaptures + * @since 3.16.0 * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @return {number[]} An array of all the currently capturing key codes. */ - setFontFamily: function (family) + getCaptures: function () { - if (this.fontFamily !== family) - { - this.fontFamily = family; - - this.update(true); - } - - return this.parent; + return this.manager.captures; }, /** - * Set the font style. - * - * @method Phaser.GameObjects.TextStyle#setFontStyle - * @since 3.0.0 + * Allows Phaser to prevent any key captures you may have defined from bubbling up the browser. + * You can use this to re-enable event capturing if you had paused it via `disableGlobalCapture`. * - * @param {string} style - The font style. + * @method Phaser.Input.Keyboard.KeyboardPlugin#enableGlobalCapture + * @since 3.16.0 * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @return {this} This KeyboardPlugin object. */ - setFontStyle: function (style) + enableGlobalCapture: function () { - if (this.fontStyle !== style) - { - this.fontStyle = style; - - this.update(true); - } + this.manager.preventDefault = true; - return this.parent; + return this; }, /** - * Set the font size. - * - * @method Phaser.GameObjects.TextStyle#setFontSize - * @since 3.0.0 + * Disables Phaser from preventing any key captures you may have defined, without actually removing them. + * You can use this to temporarily disable event capturing if, for example, you swap to a DOM element. * - * @param {(number|string)} size - The font size. + * @method Phaser.Input.Keyboard.KeyboardPlugin#disableGlobalCapture + * @since 3.16.0 * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @return {this} This KeyboardPlugin object. */ - setFontSize: function (size) + disableGlobalCapture: function () { - if (typeof size === 'number') - { - size = size.toString() + 'px'; - } - - if (this.fontSize !== size) - { - this.fontSize = size; - - this.update(true); - } + this.manager.preventDefault = false; - return this.parent; + return this; }, /** - * Set the test string to use when measuring the font. + * Removes all keyboard captures. * - * @method Phaser.GameObjects.TextStyle#setTestString - * @since 3.0.0 + * Note that this is a global change. It will clear all event captures across your game, not just for this specific Scene. * - * @param {string} string - The test string to use when measuring the font. + * @method Phaser.Input.Keyboard.KeyboardPlugin#clearCaptures + * @since 3.16.0 * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @return {this} This KeyboardPlugin object. */ - setTestString: function (string) + clearCaptures: function () { - this.testString = string; + this.manager.clearCaptures(); - return this.update(true); + return this; }, /** - * 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 + * Creates and returns an object containing 4 hotkeys for Up, Down, Left and Right, and also Space Bar and shift. * - * @param {number} width - The fixed width to set. - * @param {number} height - The fixed height to set. + * @method Phaser.Input.Keyboard.KeyboardPlugin#createCursorKeys + * @since 3.10.0 * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @return {Phaser.Types.Input.Keyboard.CursorKeys} An object containing the properties: `up`, `down`, `left`, `right`, `space` and `shift`. */ - setFixedSize: function (width, height) + createCursorKeys: function () { - this.fixedWidth = width; - this.fixedHeight = height; - - if (width) - { - this.parent.width = width; - } - - if (height) - { - this.parent.height = height; - } - - return this.update(false); + return this.addKeys({ + up: KeyCodes.UP, + down: KeyCodes.DOWN, + left: KeyCodes.LEFT, + right: KeyCodes.RIGHT, + space: KeyCodes.SPACE, + shift: KeyCodes.SHIFT + }); }, /** - * Set the background color. + * A practical way to create an object containing user selected hotkeys. * - * @method Phaser.GameObjects.TextStyle#setBackgroundColor - * @since 3.0.0 + * For example: * - * @param {string} color - The background color. + * ```javascript + * this.input.keyboard.addKeys({ 'up': Phaser.Input.Keyboard.KeyCodes.W, 'down': Phaser.Input.Keyboard.KeyCodes.S }); + * ``` * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setBackgroundColor: function (color) - { - this.backgroundColor = color; - - return this.update(false); - }, - - /** - * Set the text fill color. + * would return an object containing the properties (`up` and `down`) mapped to W and S {@link Phaser.Input.Keyboard.Key} objects. * - * @method Phaser.GameObjects.TextStyle#setFill - * @since 3.0.0 + * You can also pass in a comma-separated string: * - * @param {string} color - The text fill color. + * ```javascript + * this.input.keyboard.addKeys('W,S,A,D'); + * ``` * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setFill: function (color) - { - this.color = color; - - return this.update(false); - }, - - /** - * Set the text fill color. + * Which will return an object with the properties W, S, A and D mapped to the relevant Key objects. * - * @method Phaser.GameObjects.TextStyle#setColor - * @since 3.0.0 + * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. * - * @param {string} color - The text fill color. + * @method Phaser.Input.Keyboard.KeyboardPlugin#addKeys + * @since 3.10.0 * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @param {(object|string)} keys - An object containing Key Codes, or a comma-separated string. + * @param {boolean} [enableCapture=true] - Automatically call `preventDefault` on the native DOM browser event for the key codes being added. + * @param {boolean} [emitOnRepeat=false] - Controls if the Key will continuously emit a 'down' event while being held down (true), or emit the event just once (false, the default). + * + * @return {object} An object containing Key objects mapped to the input properties. */ - setColor: function (color) + addKeys: function (keys, enableCapture, emitOnRepeat) { - this.color = color; + if (enableCapture === undefined) { enableCapture = true; } + if (emitOnRepeat === undefined) { emitOnRepeat = false; } - return this.update(false); + var output = {}; + + if (typeof keys === 'string') + { + keys = keys.split(','); + + for (var i = 0; i < keys.length; i++) + { + var currentKey = keys[i].trim(); + + if (currentKey) + { + output[currentKey] = this.addKey(currentKey, enableCapture, emitOnRepeat); + } + } + } + else + { + for (var key in keys) + { + output[key] = this.addKey(keys[key], enableCapture, emitOnRepeat); + } + } + + return output; }, /** - * Set the resolution used by the Text object. + * Adds a Key object to this Keyboard Plugin. * - * 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. + * The given argument can be either an existing Key object, a string, such as `A` or `SPACE`, or a key code value. * - * Please use with caution, as the more high res Text you have, the more memory it uses up. + * If a Key object is given, and one already exists matching the same key code, the existing one is replaced with the new one. * - * @method Phaser.GameObjects.TextStyle#setResolution - * @since 3.12.0 + * @method Phaser.Input.Keyboard.KeyboardPlugin#addKey + * @since 3.10.0 * - * @param {number} value - The resolution for this Text object to use. + * @param {(Phaser.Input.Keyboard.Key|string|number)} key - Either a Key object, a string, such as `A` or `SPACE`, or a key code value. + * @param {boolean} [enableCapture=true] - Automatically call `preventDefault` on the native DOM browser event for the key codes being added. + * @param {boolean} [emitOnRepeat=false] - Controls if the Key will continuously emit a 'down' event while being held down (true), or emit the event just once (false, the default). * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @return {Phaser.Input.Keyboard.Key} The newly created Key object, or a reference to it if it already existed in the keys array. */ - setResolution: function (value) + addKey: function (key, enableCapture, emitOnRepeat) { - this.resolution = value; - - return this.update(false); - }, + if (enableCapture === undefined) { enableCapture = true; } + if (emitOnRepeat === undefined) { emitOnRepeat = 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; } + var keys = this.keys; - if (color === undefined && this.strokeThickness !== 0) + if (key instanceof Key) { - // Reset the stroke to zero (disabling it) - this.strokeThickness = 0; + var idx = keys.indexOf(key); - this.update(true); + if (idx > -1) + { + keys[idx] = key; + } + else + { + keys[key.keyCode] = key; + } + + if (enableCapture) + { + this.addCapture(key.keyCode); + } + + key.setEmitOnRepeat(emitOnRepeat); + + return key; } - else if (this.stroke !== color || this.strokeThickness !== thickness) + + if (typeof key === 'string') { - this.stroke = color; - this.strokeThickness = thickness; + key = KeyCodes[key.toUpperCase()]; + } - this.update(true); + if (!keys[key]) + { + keys[key] = new Key(this, key); + + if (enableCapture) + { + this.addCapture(key); + } + + keys[key].setEmitOnRepeat(emitOnRepeat); } - return this.parent; + return keys[key]; }, /** - * Set the shadow settings. + * Removes a Key object from this Keyboard Plugin. * - * Calling this method always re-measures the parent Text object, - * so only call it when you actually change the shadow settings. + * The given argument can be either a Key object, a string, such as `A` or `SPACE`, or a key code value. * - * @method Phaser.GameObjects.TextStyle#setShadow - * @since 3.0.0 + * @method Phaser.Input.Keyboard.KeyboardPlugin#removeKey + * @since 3.10.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. + * @param {(Phaser.Input.Keyboard.Key|string|number)} key - Either a Key object, a string, such as `A` or `SPACE`, or a key code value. + * @param {boolean} [destroy=false] - Call `Key.destroy` on the removed Key object? + * @param {boolean} [removeCapture=false] - Remove this Key from being captured? Only applies if set to capture when created. * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @return {this} This KeyboardPlugin object. */ - setShadow: function (x, y, color, blur, shadowStroke, shadowFill) + removeKey: function (key, destroy, removeCapture) { - 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; } + if (destroy === undefined) { destroy = false; } + if (removeCapture === undefined) { removeCapture = false; } - this.shadowOffsetX = x; - this.shadowOffsetY = y; - this.shadowColor = color; - this.shadowBlur = blur; - this.shadowStroke = shadowStroke; - this.shadowFill = shadowFill; + var keys = this.keys; + var ref; - return this.update(false); - }, + if (key instanceof Key) + { + var idx = keys.indexOf(key); - /** - * 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; } + if (idx > -1) + { + ref = this.keys[idx]; - this.shadowOffsetX = x; - this.shadowOffsetY = y; + this.keys[idx] = undefined; + } + } + else if (typeof key === 'string') + { + key = KeyCodes[key.toUpperCase()]; + } - return this.update(false); - }, + if (keys[key]) + { + ref = keys[key]; - /** - * 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'; } + keys[key] = undefined; + } - this.shadowColor = color; + if (ref) + { + ref.plugin = null; - return this.update(false); + if (removeCapture) + { + this.removeCapture(ref.keyCode); + } + + if (destroy) + { + ref.destroy(); + } + } + + return this; }, /** - * Set the shadow blur radius. + * Removes all Key objects created by _this_ Keyboard Plugin. * - * @method Phaser.GameObjects.TextStyle#setShadowBlur - * @since 3.0.0 + * @method Phaser.Input.Keyboard.KeyboardPlugin#removeAllKeys + * @since 3.24.0 * - * @param {number} [blur=0] - The shadow blur radius. + * @param {boolean} [destroy=false] - Call `Key.destroy` on each removed Key object? + * @param {boolean} [removeCapture=false] - Remove all key captures for Key objects owened by this plugin? * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @return {this} This KeyboardPlugin object. */ - setShadowBlur: function (blur) + removeAllKeys: function (destroy, removeCapture) { - if (blur === undefined) { blur = 0; } + if (destroy === undefined) { destroy = false; } + if (removeCapture === undefined) { removeCapture = false; } - this.shadowBlur = blur; + var keys = this.keys; - return this.update(false); + for (var i = 0; i < keys.length; i++) + { + var key = keys[i]; + + if (key) + { + keys[i] = undefined; + + if (removeCapture) + { + this.removeCapture(key.keyCode); + } + + if (destroy) + { + key.destroy(); + } + } + } + + return this; }, /** - * Enable or disable shadow stroke. + * Creates a new KeyCombo. * - * @method Phaser.GameObjects.TextStyle#setShadowStroke - * @since 3.0.0 + * 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 this Keyboard Plugin. * - * @param {boolean} enabled - Whether shadow stroke is enabled or not. + * The keys to be listened for can be defined as: * - * @return {Phaser.GameObjects.Text} The parent Text object. - */ - setShadowStroke: function (enabled) - { - this.shadowStroke = enabled; - - return this.update(false); - }, - - /** - * Enable or disable shadow fill. + * 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 * - * @method Phaser.GameObjects.TextStyle#setShadowFill - * @since 3.0.0 + * 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: * - * @param {boolean} enabled - Whether shadow fill is enabled or not. + * ```javascript + * this.input.keyboard.createCombo([ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13 ], { resetOnMatch: true }); * - * @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. + * this.input.keyboard.on('keycombomatch', function (event) { + * console.log('Konami Code entered!'); + * }); + * ``` * - * Pass in null to remove wrapping by width. + * Or, to listen for the user entering the word PHASER: * - * @method Phaser.GameObjects.TextStyle#setWordWrapWidth - * @since 3.0.0 + * ```javascript + * this.input.keyboard.createCombo('PHASER'); + * ``` * - * @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. + * @method Phaser.Input.Keyboard.KeyboardPlugin#createCombo + * @since 3.10.0 * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @param {(string|number[]|object[])} keys - The keys that comprise this combo. + * @param {Phaser.Types.Input.Keyboard.KeyComboConfig} [config] - A Key Combo configuration object. + * + * @return {Phaser.Input.Keyboard.KeyCombo} The new KeyCombo object. */ - setWordWrapWidth: function (width, useAdvancedWrap) + createCombo: function (keys, config) { - if (useAdvancedWrap === undefined) { useAdvancedWrap = false; } - - this.wordWrapWidth = width; - this.wordWrapUseAdvanced = useAdvancedWrap; - - return this.update(false); + return new KeyCombo(this, keys, config); }, /** - * Set a custom callback for wrapping lines. + * Checks if the given Key object is currently being held down. * - * Pass in null to remove wrapping by callback. + * The difference between this method and checking the `Key.isDown` property directly is that you can provide + * a duration to this method. For example, if you wanted a key press to fire a bullet, but you only wanted + * it to be able to fire every 100ms, then you can call this method with a `duration` of 100 and it + * will only return `true` every 100ms. * - * @method Phaser.GameObjects.TextStyle#setWordWrapCallback - * @since 3.0.0 + * If the Keyboard Plugin has been disabled, this method will always return `false`. * - * @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. + * @method Phaser.Input.Keyboard.KeyboardPlugin#checkDown + * @since 3.11.0 * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @param {Phaser.Input.Keyboard.Key} key - A Key object. + * @param {number} [duration=0] - The duration which must have elapsed before this Key is considered as being down. + * + * @return {boolean} `true` if the Key is down within the duration specified, otherwise `false`. */ - setWordWrapCallback: function (callback, scope) + checkDown: function (key, duration) { - if (scope === undefined) { scope = null; } + if (duration === undefined) { duration = 0; } - this.wordWrapCallback = callback; - this.wordWrapCallbackScope = scope; + if (this.enabled && key.isDown) + { + var t = SnapFloor(this.time - key.timeDown, duration); - return this.update(false); + if (t > key._tick) + { + key._tick = t; + + return true; + } + } + + return 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. + * Internal update handler called by the Input Plugin, which is in turn invoked by the Game step. * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @method Phaser.Input.Keyboard.KeyboardPlugin#update + * @private + * @since 3.10.0 */ - setAlign: function (align) + update: function () { - if (align === undefined) { align = 'left'; } + var queue = this.manager.queue; + var len = queue.length; - this.align = align; + if (!this.isActive() || len === 0) + { + return; + } - return this.update(false); + var keys = this.keys; + + // Process the event queue, dispatching all of the events that have stored up + for (var i = 0; i < len; i++) + { + var event = queue[i]; + var code = event.keyCode; + var key = keys[code]; + var repeat = false; + + // Override the default functions (it's too late for the browser to use them anyway, so we may as well) + if (event.cancelled === undefined) + { + // Event allowed to flow across all handlers in this Scene, and any other Scene in the Scene list + event.cancelled = 0; + + // Won't reach any more local (Scene level) handlers + event.stopImmediatePropagation = function () + { + event.cancelled = 1; + }; + + // Won't reach any more handlers in any Scene further down the Scene list + event.stopPropagation = function () + { + event.cancelled = -1; + }; + } + + if (event.cancelled === -1) + { + // This event has been stopped from broadcasting to any other Scene, so abort. + continue; + } + + // Duplicate event bailout + if (code === this.prevCode && event.timeStamp === this.prevTime && event.type === this.prevType) + { + // On some systems, the exact same event will fire multiple times. This prevents it. + continue; + } + + this.prevCode = code; + this.prevTime = event.timeStamp; + this.prevType = event.type; + + if (event.type === 'keydown') + { + // Key specific callback first + if (key) + { + repeat = key.isDown; + + key.onDown(event); + } + + if (!event.cancelled && (!key || !repeat)) + { + if (KeyMap[code]) + { + this.emit(Events.KEY_DOWN + KeyMap[code], event); + } + + if (!event.cancelled) + { + this.emit(Events.ANY_KEY_DOWN, event); + } + } + } + else + { + // Key specific callback first + if (key) + { + key.onUp(event); + } + + if (!event.cancelled) + { + if (KeyMap[code]) + { + this.emit(Events.KEY_UP + KeyMap[code], event); + } + + if (!event.cancelled) + { + this.emit(Events.ANY_KEY_UP, event); + } + } + } + + // Reset the cancel state for other Scenes to use + if (event.cancelled === 1) + { + event.cancelled = 0; + } + } }, /** - * Set the maximum number of lines to draw. + * Resets all Key objects created by _this_ Keyboard Plugin back to their default un-pressed states. + * This can only reset keys created via the `addKey`, `addKeys` or `createCursorKeys` methods. + * If you have created a Key object directly you'll need to reset it yourself. * - * @method Phaser.GameObjects.TextStyle#setMaxLines - * @since 3.0.0 + * This method is called automatically when the Keyboard Plugin shuts down, but can be + * invoked directly at any time you require. * - * @param {number} [max=0] - The maximum number of lines to draw. + * @method Phaser.Input.Keyboard.KeyboardPlugin#resetKeys + * @since 3.15.0 * - * @return {Phaser.GameObjects.Text} The parent Text object. + * @return {this} This KeyboardPlugin object. */ - setMaxLines: function (max) + resetKeys: function () { - if (max === undefined) { max = 0; } + var keys = this.keys; - this.maxLines = max; + for (var i = 0; i < keys.length; i++) + { + // Because it's a sparsely populated array + if (keys[i]) + { + keys[i].reset(); + } + } - return this.update(false); + return this; }, /** - * Get the current text metrics. + * Shuts this Keyboard Plugin down. This performs the following tasks: * - * @method Phaser.GameObjects.TextStyle#getTextMetrics - * @since 3.0.0 + * 1 - Removes all keys created by this Keyboard plugin. + * 2 - Stops and removes the keyboard event listeners. + * 3 - Clears out any pending requests in the queue, without processing them. * - * @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics. + * @method Phaser.Input.Keyboard.KeyboardPlugin#shutdown + * @private + * @since 3.10.0 */ - getTextMetrics: function () + shutdown: function () { - var metrics = this.metrics; + this.removeAllKeys(true); + this.removeAllListeners(); - return { - ascent: metrics.ascent, - descent: metrics.descent, - fontSize: metrics.fontSize - }; + this.sceneInputPlugin.manager.events.off(InputEvents.MANAGER_PROCESS, this.update, this); + + this.game.events.off(GameEvents.BLUR, this.resetKeys); + + this.scene.sys.events.off(SceneEvents.PAUSE, this.resetKeys, this); + this.scene.sys.events.off(SceneEvents.SLEEP, this.resetKeys, this); + + this.queue = []; }, /** - * Build a JSON representation of this Text Style. - * - * @method Phaser.GameObjects.TextStyle#toJSON - * @since 3.0.0 + * Destroys this Keyboard Plugin instance and all references it holds, plus clears out local arrays. * - * @return {object} A JSON representation of this Text Style. + * @method Phaser.Input.Keyboard.KeyboardPlugin#destroy + * @private + * @since 3.10.0 */ - toJSON: function () + destroy: function () { - var output = {}; + this.shutdown(); - for (var key in propertyMap) + var keys = this.keys; + + for (var i = 0; i < keys.length; i++) { - output[key] = this[key]; + // Because it's a sparsely populated array + if (keys[i]) + { + keys[i].destroy(); + } } - output.metrics = this.getTextMetrics(); + this.keys = []; + this.combos = []; + this.queue = []; - return output; + this.scene = null; + this.settings = null; + this.sceneInputPlugin = null; + this.manager = null; }, /** - * Destroy this Text Style. + * Internal time value. * - * @method Phaser.GameObjects.TextStyle#destroy - * @since 3.0.0 + * @name Phaser.Input.Keyboard.KeyboardPlugin#time + * @type {number} + * @private + * @since 3.11.0 */ - destroy: function () - { - this.parent = undefined; + time: { + + get: function () + { + return this.sceneInputPlugin.manager.time; + } + } }); -module.exports = TextStyle; +/** + * An instance of the Keyboard Plugin class, if enabled via the `input.keyboard` Scene or Game Config property. + * Use this to create Key objects and listen for keyboard specific events. + * + * @name Phaser.Input.InputPlugin#keyboard + * @type {?Phaser.Input.Keyboard.KeyboardPlugin} + * @since 3.10.0 + */ +InputPluginCache.register('KeyboardPlugin', KeyboardPlugin, 'keyboard', 'keyboard', 'inputKeyboard'); + +module.exports = KeyboardPlugin; /***/ }), -/* 460 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 60258: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * Used internally by the KeyCombo class. + * Return `true` if it reached the end of the combo, `false` if not. * - * @function Phaser.GameObjects.MeasureText + * @function Phaser.Input.Keyboard.AdvanceKeyCombo + * @private * @since 3.0.0 * - * @param {Phaser.GameObjects.TextStyle} textStyle - The TextStyle object to measure. + * @param {KeyboardEvent} event - The native Keyboard Event. + * @param {Phaser.Input.Keyboard.KeyCombo} combo - The KeyCombo object to advance. * - * @return {Phaser.Types.GameObjects.Text.TextMetrics} An object containing the ascent, descent and fontSize of the TextStyle. + * @return {boolean} `true` if it reached the end of the combo, `false` if not. */ -var MeasureText = function (textStyle) +var AdvanceKeyCombo = function (event, combo) { - var canvas = CanvasPool.create(this); - var context = canvas.getContext('2d'); - - textStyle.syncFont(canvas, context); - - var metrics = context.measureText(textStyle.testString); - - if ('actualBoundingBoxAscent' in metrics) - { - 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 - }; - - var imagedata = context.getImageData(0, 0, width, height); - if (!imagedata) - { - output.ascent = baseline; - output.descent = baseline + 6; - output.fontSize = output.ascent + output.descent; - - CanvasPool.remove(canvas); - - return output; - } - - var pixels = imagedata.data; - var numPixels = pixels.length; - var line = width * 4; - var i; - var j; - var idx = 0; - var stop = false; + combo.timeLastMatched = event.timeStamp; + combo.index++; - // ascent. scan from top to bottom until we find a non red pixel - for (i = 0; i < baseline; i++) + if (combo.index === combo.size) { - for (j = 0; j < line; j += 4) - { - if (pixels[idx + j] !== 255) - { - stop = true; - break; - } - } - - if (!stop) - { - idx += line; - } - else - { - break; - } + return true; } - - output.ascent = baseline - i; - - idx = numPixels - line; - stop = false; - - // descent. scan from bottom to top until we find a non red pixel - for (i = height; i > baseline; i--) + else { - for (j = 0; j < line; j += 4) - { - if (pixels[idx + j] !== 255) - { - stop = true; - break; - } - } - - if (!stop) - { - idx -= line; - } - else - { - break; - } + combo.current = combo.keyCodes[combo.index]; + return false; } - - output.descent = (i - baseline); - output.fontSize = output.ascent + output.descent; - - CanvasPool.remove(canvas); - - return output; }; -module.exports = MeasureText; +module.exports = AdvanceKeyCombo; /***/ }), -/* 461 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 95625: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArcRender = __webpack_require__(1097); -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(36); -var Earcut = __webpack_require__(59); -var GeomCircle = __webpack_require__(65); -var MATH_CONST = __webpack_require__(14); -var Shape = __webpack_require__(34); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(94030); +var GetFastValue = __webpack_require__(72632); +var ProcessKeyCombo = __webpack_require__(2544); +var ResetKeyCombo = __webpack_require__(88754); /** * @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. + * 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. * - * @class Arc - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects + * 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 - * @since 3.13.0 + * @listens Phaser.Input.Keyboard.Events#ANY_KEY_DOWN + * @since 3.0.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. + * @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 Arc = new Class({ - - Extends: Shape, - - Mixins: [ - ArcRender - ], +var KeyCombo = new Class({ initialize: - function Arc (scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha) + function KeyCombo (keyboardPlugin, keys, config) { - 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)); + if (config === undefined) { config = {}; } - /** - * Private internal value. Holds the start angle in degrees. - * - * @name Phaser.GameObjects.Arc#_startAngle - * @type {number} - * @private - * @since 3.13.0 - */ - this._startAngle = startAngle; + // Can't have a zero or single length combo (string or array based) + if (keys.length < 2) + { + return false; + } /** - * Private internal value. Holds the end angle in degrees. + * A reference to the Keyboard Manager * - * @name Phaser.GameObjects.Arc#_endAngle - * @type {number} - * @private - * @since 3.13.0 + * @name Phaser.Input.Keyboard.KeyCombo#manager + * @type {Phaser.Input.Keyboard.KeyboardPlugin} + * @since 3.0.0 */ - this._endAngle = endAngle; + this.manager = keyboardPlugin; /** - * Private internal value. Holds the winding order of the start and end angles. + * A flag that controls if this Key Combo is actively processing keys or not. * - * @name Phaser.GameObjects.Arc#_anticlockwise + * @name Phaser.Input.Keyboard.KeyCombo#enabled * @type {boolean} - * @private - * @since 3.13.0 + * @default true + * @since 3.0.0 */ - this._anticlockwise = anticlockwise; + this.enabled = true; /** - * Private internal value. Holds the number of iterations used when drawing the arc. + * An array of the keycodes that comprise this combo. * - * @name Phaser.GameObjects.Arc#_iterations - * @type {number} - * @default 0.01 - * @private - * @since 3.13.0 + * @name Phaser.Input.Keyboard.KeyCombo#keyCodes + * @type {array} + * @default [] + * @since 3.0.0 */ - this._iterations = 0.01; - - this.setPosition(x, y); + this.keyCodes = []; - var diameter = this.geom.radius * 2; - this.setSize(diameter, diameter); + // if 'keys' is a string we need to get the keycode of each character in it - if (fillColor !== undefined) + for (var i = 0; i < keys.length; i++) { - this.setFillStyle(fillColor, fillAlpha); + 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); + } } - this.updateDisplayOrigin(); - this.updateData(); - }, + /** + * 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 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; - }, + /** + * 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; - set: function (value) - { - this._iterations = value; + /** + * The length of this combo (in keycodes) + * + * @name Phaser.Input.Keyboard.KeyCombo#size + * @type {number} + * @since 3.0.0 + */ + this.size = this.keyCodes.length; - this.updateData(); - } + /** + * 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 radius of the arc. - * - * @name Phaser.GameObjects.Arc#radius - * @type {number} - * @since 3.13.0 - */ - radius: { + /** + * The time the entire combo was matched. + * + * @name Phaser.Input.Keyboard.KeyCombo#timeMatched + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.timeMatched = 0; - get: function () - { - return this.geom.radius; - }, + /** + * 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); - set: function (value) - { - this.geom.radius = value; + /** + * 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); - var diameter = value * 2; - this.setSize(diameter, diameter); - this.updateDisplayOrigin(); - this.updateData(); - } + /** + * 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); - /** - * The start angle of the arc, in degrees. - * - * @name Phaser.GameObjects.Arc#startAngle - * @type {number} - * @since 3.13.0 - */ - startAngle: { + var _this = this; - get: function () + var onKeyDownHandler = function (event) { - return this._startAngle; - }, + if (_this.matched || !_this.enabled) + { + return; + } - set: function (value) - { - this._startAngle = value; + var matched = ProcessKeyCombo(event, _this); - this.updateData(); - } + 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); }, /** - * The end angle of the arc, in degrees. + * How far complete is this combo? A value between 0 and 1. * - * @name Phaser.GameObjects.Arc#endAngle + * @name Phaser.Input.Keyboard.KeyCombo#progress * @type {number} - * @since 3.13.0 + * @readonly + * @since 3.0.0 */ - endAngle: { + progress: { get: function () { - return this._endAngle; - }, - - set: function (value) - { - this._endAngle = value; - - this.updateData(); + return this.index / this.size; } }, /** - * The winding order of the start and end angles. + * Destroys this Key Combo and all of its references. * - * @name Phaser.GameObjects.Arc#anticlockwise - * @type {boolean} - * @since 3.13.0 + * @method Phaser.Input.Keyboard.KeyCombo#destroy + * @since 3.0.0 */ - anticlockwise: { + destroy: function () + { + this.enabled = false; + this.keyCodes = []; - get: function () - { - return this._anticlockwise; - }, + this.manager.off(Events.ANY_KEY_DOWN, this.onKeyDown); - set: function (value) - { - this._anticlockwise = value; + this.manager = null; + } - this.updateData(); - } +}); - }, +module.exports = KeyCombo; - /** - * 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; } +/***/ 2544: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.iterations = value; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +var AdvanceKeyCombo = __webpack_require__(60258); - /** - * 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) +/** + * 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) { - this._startAngle = angle; - - if (anticlockwise !== undefined) - { - this._anticlockwise = anticlockwise; - } + return true; + } - return this.updateData(); - }, + var comboMatched = false; + var keyMatched = false; - /** - * 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) + if (event.keyCode === combo.current) { - this._endAngle = angle; + // Key was correct - if (anticlockwise !== undefined) + if (combo.index > 0 && combo.maxKeyDelay > 0) { - 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; + // We have to check to see if the delay between + // the new key and the old one was too long (if enabled) - endAngle -= startAngle; + var timeLimit = combo.timeLastMatched + combo.maxKeyDelay; - if (anticlockwise) - { - if (endAngle < -MATH_CONST.PI2) - { - endAngle = -MATH_CONST.PI2; - } - else if (endAngle > 0) + // Check if they pressed it in time or not + if (event.timeStamp <= timeLimit) { - endAngle = -MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; + keyMatched = true; + comboMatched = AdvanceKeyCombo(event, combo); } } - else if (endAngle > MATH_CONST.PI2) - { - endAngle = MATH_CONST.PI2; - } - else if (endAngle < 0) + else { - endAngle = MATH_CONST.PI2 + endAngle % MATH_CONST.PI2; - } + keyMatched = true; - var path = [ x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius ]; + // We don't check the time for the first key pressed, so just advance it + comboMatched = AdvanceKeyCombo(event, combo); + } + } - var ta; + if (!keyMatched && combo.resetOnWrongKey) + { + // Wrong key was pressed + combo.index = 0; + combo.current = combo.keyCodes[0]; + } - while (iteration < 1) - { - ta = endAngle * iteration + startAngle; + if (comboMatched) + { + combo.timeLastMatched = event.timeStamp; + combo.matched = true; + combo.timeMatched = event.timeStamp; + } - path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius); + return comboMatched; +}; - iteration += step; - } +module.exports = ProcessKeyCombo; - 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); +/***/ 88754: +/***/ ((module) => { - this.pathIndexes = Earcut(path); - this.pathData = path; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - } +/** + * 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 = Arc; +module.exports = ResetKeyCombo; /***/ }), -/* 462 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 5044: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CurveRender = __webpack_require__(1100); -var Earcut = __webpack_require__(59); -var Rectangle = __webpack_require__(10); -var Shape = __webpack_require__(34); - /** - * @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. + * The Global Key Down Event. * - * @class Curve - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 + * This event is dispatched by the Keyboard Plugin when any key on the keyboard is pressed down. * - * @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. + * Listen to this event from within a Scene using: `this.input.keyboard.on('keydown', listener)`. + * + * You can also listen for a specific key being pressed. See [Keyboard.Events.KEY_DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:KEY_DOWN} for details. + * + * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:DOWN} for details. + * + * _Note_: Many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting. + * Read [this article on ghosting]{@link http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/} for details. + * + * Also, please be aware that some browser extensions can disable or override Phaser keyboard handling. + * For example, the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. + * There are others. So, please check your extensions if you find you have specific keys that don't work. + * + * @event Phaser.Input.Keyboard.Events#ANY_KEY_DOWN + * @type {string} + * @since 3.0.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about the key that was pressed, any modifiers, etc. */ -var Curve = new Class({ - - Extends: Shape, - - Mixins: [ - CurveRender - ], - - initialize: +module.exports = 'keydown'; - 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; +/***/ 40813: +/***/ ((module) => { - /** - * 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(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.closePath = false; +/** + * The Global Key Up Event. + * + * This event is dispatched by the Keyboard Plugin when any key on the keyboard is released. + * + * Listen to this event from within a Scene using: `this.input.keyboard.on('keyup', listener)`. + * + * You can also listen for a specific key being released. See [Keyboard.Events.KEY_UP]{@linkcode Phaser.Input.Keyboard.Events#event:KEY_UP} for details. + * + * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.UP]{@linkcode Phaser.Input.Keyboard.Events#event:UP} for details. + * + * @event Phaser.Input.Keyboard.Events#ANY_KEY_UP + * @type {string} + * @since 3.0.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about the key that was released, any modifiers, etc. + */ +module.exports = 'keyup'; - this.setPosition(x, y); - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } +/***/ }), - this.updateData(); - }, +/***/ 89319: +/***/ ((module) => { - /** - * 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: { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - get: function () - { - return this._smoothness; - }, +/** + * The Key Combo Match Event. + * + * This event is dispatched by the Keyboard Plugin when a [Key Combo]{@link Phaser.Input.Keyboard.KeyCombo} is matched. + * + * Listen for this event from the Key Plugin after a combo has been created: + * + * ```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!'); + * }); + * ``` + * + * @event Phaser.Input.Keyboard.Events#COMBO_MATCH + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.KeyCombo} keycombo - The Key Combo object that was matched. + * @param {KeyboardEvent} event - The native DOM Keyboard Event of the final key in the combo. You can inspect this to learn more about any modifiers, etc. + */ +module.exports = 'keycombomatch'; - set: function (value) - { - this._smoothness = value; - this.updateData(); - } +/***/ }), - }, +/***/ 43267: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this.updateData(); - }, +/** + * The Key Down Event. + * + * This event is dispatched by a [Key]{@link Phaser.Input.Keyboard.Key} object when it is pressed. + * + * Listen for this event from the Key object instance directly: + * + * ```javascript + * var spaceBar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); + * + * spaceBar.on('down', listener) + * ``` + * + * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_DOWN} for details. + * + * @event Phaser.Input.Keyboard.Events#DOWN + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.Key} key - The Key object that was pressed. + * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about any modifiers, etc. + */ +module.exports = 'down'; - /** - * 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(); +/***/ 78595: +/***/ ((module) => { - var path = []; - var points = this.geom.getPoints(smoothness); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (var i = 0; i < points.length; i++) - { - path.push(points[i].x, points[i].y); - } +/** + * The Key Down Event. + * + * This event is dispatched by the Keyboard Plugin when any key on the keyboard is pressed down. + * + * Unlike the `ANY_KEY_DOWN` event, this one has a special dynamic event name. For example, to listen for the `A` key being pressed + * use the following from within a Scene: `this.input.keyboard.on('keydown-A', listener)`. You can replace the `-A` part of the event + * name with any valid [Key Code string]{@link Phaser.Input.Keyboard.KeyCodes}. For example, this will listen for the space bar: + * `this.input.keyboard.on('keydown-SPACE', listener)`. + * + * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_DOWN} for details. + * + * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:DOWN} for details. + * + * _Note_: Many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting. + * Read [this article on ghosting]{@link http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/} for details. + * + * Also, please be aware that some browser extensions can disable or override Phaser keyboard handling. + * For example, the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. + * There are others. So, please check your extensions if you find you have specific keys that don't work. + * + * @event Phaser.Input.Keyboard.Events#KEY_DOWN + * @type {string} + * @since 3.0.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about the key that was pressed, any modifiers, etc. + */ +module.exports = 'keydown-'; - path.push(points[0].x, points[0].y); - this.pathIndexes = Earcut(path); - this.pathData = path; +/***/ }), - return this; - } +/***/ 30056: +/***/ ((module) => { -}); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = Curve; +/** + * The Key Up Event. + * + * This event is dispatched by the Keyboard Plugin when any key on the keyboard is released. + * + * Unlike the `ANY_KEY_UP` event, this one has a special dynamic event name. For example, to listen for the `A` key being released + * use the following from within a Scene: `this.input.keyboard.on('keyup-A', listener)`. You can replace the `-A` part of the event + * name with any valid [Key Code string]{@link Phaser.Input.Keyboard.KeyCodes}. For example, this will listen for the space bar: + * `this.input.keyboard.on('keyup-SPACE', listener)`. + * + * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_UP]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_UP} for details. + * + * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.UP]{@linkcode Phaser.Input.Keyboard.Events#event:UP} for details. + * + * @event Phaser.Input.Keyboard.Events#KEY_UP + * @type {string} + * @since 3.0.0 + * + * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about the key that was released, any modifiers, etc. + */ +module.exports = 'keyup-'; /***/ }), -/* 463 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 81939: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(59); -var EllipseRender = __webpack_require__(1103); -var GeomEllipse = __webpack_require__(111); -var Shape = __webpack_require__(34); - /** - * @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. + * The Key Up Event. * - * @class Ellipse - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 + * This event is dispatched by a [Key]{@link Phaser.Input.Keyboard.Key} object when it is released. * - * @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. + * Listen for this event from the Key object instance directly: + * + * ```javascript + * var spaceBar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); + * + * spaceBar.on('up', listener) + * ``` + * + * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_UP]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_UP} for details. + * + * @event Phaser.Input.Keyboard.Events#UP + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.Key} key - The Key object that was released. + * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about any modifiers, etc. */ -var Ellipse = new Class({ +module.exports = 'up'; - Extends: Shape, - Mixins: [ - EllipseRender - ], +/***/ }), - initialize: +/***/ 94030: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - 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; } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - Shape.call(this, scene, 'Ellipse', new GeomEllipse(width / 2, height / 2, width, height)); +/** + * @namespace Phaser.Input.Keyboard.Events + */ - /** - * 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; +module.exports = { - this.setPosition(x, y); + ANY_KEY_DOWN: __webpack_require__(5044), + ANY_KEY_UP: __webpack_require__(40813), + COMBO_MATCH: __webpack_require__(89319), + DOWN: __webpack_require__(43267), + KEY_DOWN: __webpack_require__(78595), + KEY_UP: __webpack_require__(30056), + UP: __webpack_require__(81939) - 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: { +/***/ 28388: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - get: function () - { - return this._smoothness; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - set: function (value) - { - this._smoothness = value; +/** + * @namespace Phaser.Input.Keyboard + */ - this.updateData(); - } +module.exports = { - }, + Events: __webpack_require__(94030), - /** - * 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); + KeyboardManager: __webpack_require__(71064), + KeyboardPlugin: __webpack_require__(89666), - return this.updateData(); - }, + Key: __webpack_require__(50165), + KeyCodes: __webpack_require__(11873), - /** - * 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; + KeyCombo: __webpack_require__(95625), - return this.updateData(); - }, + AdvanceKeyCombo: __webpack_require__(60258), + ProcessKeyCombo: __webpack_require__(2544), + ResetKeyCombo: __webpack_require__(88754), - /** - * 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); + JustDown: __webpack_require__(42460), + JustUp: __webpack_require__(53162), + DownDuration: __webpack_require__(64964), + UpDuration: __webpack_require__(70331) - 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; - } +/***/ 64964: +/***/ ((module) => { -}); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = Ellipse; +/** + * Returns `true` if the Key was pressed down within the `duration` value given, based on the current + * game clock time. Or `false` if it either isn't down, or was pressed down longer ago than the given duration. + * + * @function Phaser.Input.Keyboard.DownDuration + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.Key} key - The Key object to test. + * @param {number} [duration=50] - The duration, in ms, within which the key must have been pressed down. + * + * @return {boolean} `true` if the Key was pressed down within `duration` ms ago, otherwise `false`. + */ +var DownDuration = function (key, duration) +{ + if (duration === undefined) { duration = 50; } + + var current = key.plugin.game.loop.time - key.timeDown; + + return (key.isDown && current < duration); +}; + +module.exports = DownDuration; /***/ }), -/* 464 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 42460: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Shape = __webpack_require__(34); -var GridRender = __webpack_require__(1106); - /** - * @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. + * The justDown value allows you to test if this Key has just been pressed down or not. * - * This shape supports only fill colors and cannot be stroked. + * When you check this value it will return `true` if the Key is down, otherwise `false`. * - * 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. + * You can only call justDown once per key press. It will only return `true` once, until the Key is released and pressed down again. + * This allows you to use it in situations where you want to check if this key is down without using an event, such as in a core game loop. * - * @class Grid - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects - * @constructor - * @since 3.13.0 + * @function Phaser.Input.Keyboard.JustDown + * @since 3.0.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. + * @param {Phaser.Input.Keyboard.Key} key - The Key to check to see if it's just down or not. + * + * @return {boolean} `true` if the Key was just pressed, otherwise `false`. */ -var Grid = new Class({ - - Extends: Shape, - - Mixins: [ - GridRender - ], - - initialize: +var JustDown = function (key) +{ + if (key._justDown) + { + key._justDown = false; - function Grid (scene, x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha) + return true; + } + else { - 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; } + return false; + } +}; - Shape.call(this, scene, 'Grid', null); +module.exports = JustDown; - /** - * 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; +/***/ 53162: +/***/ ((module) => { - /** - * 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; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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) +/** + * The justUp value allows you to test if this Key has just been released or not. + * + * When you check this value it will return `true` if the Key is up, otherwise `false`. + * + * You can only call JustUp once per key release. It will only return `true` once, until the Key is pressed down and released again. + * This allows you to use it in situations where you want to check if this key is up without using an event, such as in a core game loop. + * + * @function Phaser.Input.Keyboard.JustUp + * @since 3.0.0 + * + * @param {Phaser.Input.Keyboard.Key} key - The Key to check to see if it's just up or not. + * + * @return {boolean} `true` if the Key was just released, otherwise `false`. + */ +var JustUp = function (key) +{ + if (key._justUp) { - if (fillAlpha === undefined) { fillAlpha = 1; } - - if (fillColor === undefined) - { - this.showAltCells = false; - } - else - { - this.altFillColor = fillColor; - this.altFillAlpha = fillAlpha; - this.showAltCells = true; - } - - return this; - }, + key._justUp = false; - /** - * 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) + return true; + } + else { - if (fillAlpha === undefined) { fillAlpha = 1; } - - if (fillColor === undefined) - { - this.showOutline = false; - } - else - { - this.outlineFillColor = fillColor; - this.outlineFillAlpha = fillAlpha; - this.showOutline = true; - } - - return this; + return false; } +}; -}); - -module.exports = Grid; +module.exports = JustUp; /***/ }), -/* 465 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 50165: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var IsoBoxRender = __webpack_require__(1109); -var Class = __webpack_require__(0); -var Shape = __webpack_require__(34); +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(94030); /** * @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. + * A generic Key object which can be passed to the Process functions (and so on) + * keycode must be an integer * - * @class IsoBox - * @extends Phaser.GameObjects.Shape - * @memberof Phaser.GameObjects + * @class Key + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Input.Keyboard * @constructor - * @since 3.13.0 + * @since 3.0.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. + * @param {Phaser.Input.Keyboard.KeyboardPlugin} plugin - The Keyboard Plugin instance that owns this Key object. + * @param {number} keyCode - The keycode of this key. */ -var IsoBox = new Class({ - - Extends: Shape, +var Key = new Class({ - Mixins: [ - IsoBoxRender - ], + Extends: EventEmitter, initialize: - function IsoBox (scene, x, y, size, height, fillTop, fillLeft, fillRight) + function Key (plugin, keyCode) { - 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); + EventEmitter.call(this); /** - * The projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. + * The Keyboard Plugin instance that owns this Key object. * - * @name Phaser.GameObjects.IsoBox#projection - * @type {number} - * @default 4 - * @since 3.13.0 + * @name Phaser.Input.Keyboard.Key#plugin + * @type {Phaser.Input.Keyboard.KeyboardPlugin} + * @since 3.17.0 */ - this.projection = 4; + this.plugin = plugin; /** - * The color used to fill in the top of the iso box. + * The keycode of this key. * - * @name Phaser.GameObjects.IsoBox#fillTop + * @name Phaser.Input.Keyboard.Key#keyCode * @type {number} - * @since 3.13.0 + * @since 3.0.0 */ - this.fillTop = fillTop; + this.keyCode = keyCode; /** - * The color used to fill in the left-facing side of the iso box. + * The original DOM event. * - * @name Phaser.GameObjects.IsoBox#fillLeft - * @type {number} - * @since 3.13.0 + * @name Phaser.Input.Keyboard.Key#originalEvent + * @type {KeyboardEvent} + * @since 3.0.0 */ - this.fillLeft = fillLeft; + this.originalEvent = undefined; /** - * The color used to fill in the right-facing side of the iso box. + * Can this Key be processed? * - * @name Phaser.GameObjects.IsoBox#fillRight - * @type {number} - * @since 3.13.0 + * @name Phaser.Input.Keyboard.Key#enabled + * @type {boolean} + * @default true + * @since 3.0.0 */ - this.fillRight = fillRight; + this.enabled = true; /** - * Controls if the top-face of the iso box be rendered. + * The "down" state of the key. This will remain `true` for as long as the keyboard thinks this key is held down. * - * @name Phaser.GameObjects.IsoBox#showTop + * @name Phaser.Input.Keyboard.Key#isDown * @type {boolean} - * @default true - * @since 3.13.0 + * @default false + * @since 3.0.0 */ - this.showTop = true; + this.isDown = false; /** - * Controls if the left-face of the iso box be rendered. + * The "up" state of the key. This will remain `true` for as long as the keyboard thinks this key is up. * - * @name Phaser.GameObjects.IsoBox#showLeft + * @name Phaser.Input.Keyboard.Key#isUp * @type {boolean} * @default true - * @since 3.13.0 + * @since 3.0.0 */ - this.showLeft = true; + this.isUp = true; /** - * Controls if the right-face of the iso box be rendered. + * The down state of the ALT key, if pressed at the same time as this key. * - * @name Phaser.GameObjects.IsoBox#showRight + * @name Phaser.Input.Keyboard.Key#altKey * @type {boolean} - * @default true - * @since 3.13.0 + * @default false + * @since 3.0.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; - - -/***/ }), -/* 466 */ -/***/ (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__(1112); -var Shape = __webpack_require__(34); - -/** - * @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 - ], + this.altKey = false; - initialize: + /** + * 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; - 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; } + /** + * 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; - Shape.call(this, scene, 'IsoTriangle', null); + /** + * 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 projection level of the iso box. Change this to change the 'angle' at which you are looking at the box. + * The location of the modifier key. 0 for standard (or unknown), 1 for left, 2 for right, 3 for numpad. * - * @name Phaser.GameObjects.IsoTriangle#projection + * @name Phaser.Input.Keyboard.Key#location * @type {number} - * @default 4 - * @since 3.13.0 + * @default 0 + * @since 3.0.0 */ - this.projection = 4; + this.location = 0; /** - * The color used to fill in the top of the iso triangle. This is only used if the triangle is reversed. + * The timestamp when the key was last pressed down. * - * @name Phaser.GameObjects.IsoTriangle#fillTop + * @name Phaser.Input.Keyboard.Key#timeDown * @type {number} - * @since 3.13.0 + * @default 0 + * @since 3.0.0 */ - this.fillTop = fillTop; + this.timeDown = 0; /** - * The color used to fill in the left-facing side of the iso triangle. + * 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.GameObjects.IsoTriangle#fillLeft + * @name Phaser.Input.Keyboard.Key#duration * @type {number} - * @since 3.13.0 + * @default 0 + * @since 3.0.0 */ - this.fillLeft = fillLeft; + this.duration = 0; /** - * The color used to fill in the right-facing side of the iso triangle. + * The timestamp when the key was last released. * - * @name Phaser.GameObjects.IsoTriangle#fillRight + * @name Phaser.Input.Keyboard.Key#timeUp * @type {number} - * @since 3.13.0 + * @default 0 + * @since 3.0.0 */ - this.fillRight = fillRight; + this.timeUp = 0; /** - * Controls if the top-face of the iso triangle be rendered. + * When a key is held down should it continuously fire the `down` event each time it repeats? * - * @name Phaser.GameObjects.IsoTriangle#showTop + * 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 true - * @since 3.13.0 + * @default false + * @since 3.16.0 */ - this.showTop = true; + this.emitOnRepeat = false; /** - * Controls if the left-face of the iso triangle be rendered. + * If a key is held down this holds down the number of times the key has 'repeated'. * - * @name Phaser.GameObjects.IsoTriangle#showLeft - * @type {boolean} - * @default true - * @since 3.13.0 + * @name Phaser.Input.Keyboard.Key#repeats + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.showLeft = true; + this.repeats = 0; /** - * Controls if the right-face of the iso triangle be rendered. + * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) * - * @name Phaser.GameObjects.IsoTriangle#showRight + * @name Phaser.Input.Keyboard.Key#_justDown * @type {boolean} - * @default true - * @since 3.13.0 + * @private + * @default false + * @since 3.0.0 */ - this.showRight = true; + this._justDown = false; /** - * Sets if the iso triangle will be rendered upside down or not. + * True if the key has just been pressed (NOTE: requires to be reset, see justDown getter) * - * @name Phaser.GameObjects.IsoTriangle#isReversed + * @name Phaser.Input.Keyboard.Key#_justUp * @type {boolean} + * @private * @default false - * @since 3.13.0 + * @since 3.0.0 */ - this.isReversed = reversed; - - this.isFilled = true; - - this.setPosition(x, y); - this.setSize(size, height); + this._justUp = false; - this.updateDisplayOrigin(); + /** + * Internal tick counter. + * + * @name Phaser.Input.Keyboard.Key#_tick + * @type {number} + * @private + * @since 3.11.0 + */ + this._tick = -1; }, /** - * 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. + * 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.GameObjects.IsoTriangle#setProjection - * @since 3.13.0 - * - * @param {number} value - The value to set the projection to. + * @method Phaser.Input.Keyboard.Key#setEmitOnRepeat + * @since 3.16.0 * - * @return {this} This Game Object instance. + * @param {boolean} value - Emit `down` events on repeated key down actions, or just once? + * + * @return {this} This Key instance. */ - setProjection: function (value) + setEmitOnRepeat: function (value) { - this.projection = value; + this.emitOnRepeat = value; return this; }, /** - * Sets if the iso triangle will be rendered upside down or not. - * This call can be chained. + * Processes the Key Down action for this Key. + * Called automatically by the Keyboard Plugin. * - * @method Phaser.GameObjects.IsoTriangle#setReversed - * @since 3.13.0 - * - * @param {boolean} reversed - Sets if the iso triangle will be rendered upside down or not. + * @method Phaser.Input.Keyboard.Key#onDown + * @fires Phaser.Input.Keyboard.Events#DOWN + * @since 3.16.0 * - * @return {this} This Game Object instance. + * @param {KeyboardEvent} event - The native DOM Keyboard event. */ - setReversed: function (reversed) + onDown: function (event) { - this.isReversed = reversed; + this.originalEvent = event; - return this; + 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); + } }, /** - * Sets which faces of the iso triangle will be rendered. - * This call can be chained. + * Processes the Key Up action for this Key. + * Called automatically by the Keyboard Plugin. * - * @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. + * @method Phaser.Input.Keyboard.Key#onUp + * @fires Phaser.Input.Keyboard.Events#UP + * @since 3.16.0 * - * @return {this} This Game Object instance. + * @param {KeyboardEvent} event - The native DOM Keyboard event. */ - setFaces: function (showTop, showLeft, showRight) + onUp: function (event) { - if (showTop === undefined) { showTop = true; } - if (showLeft === undefined) { showLeft = true; } - if (showRight === undefined) { showRight = true; } + this.originalEvent = event; - this.showTop = showTop; - this.showLeft = showLeft; - this.showRight = showRight; + if (!this.enabled) + { + return; + } - return this; + 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); }, /** - * Sets the fill colors for each face of the iso triangle. - * This call can be chained. + * Resets this Key object back to its default un-pressed state. * - * @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. + * As of version 3.60.0 it no longer resets the `enabled` or `preventDefault` flags. * - * @return {this} This Game Object instance. + * @method Phaser.Input.Keyboard.Key#reset + * @since 3.6.0 + * + * @return {this} This Key instance. */ - setFillStyle: function (fillTop, fillLeft, fillRight) + reset: function () { - this.fillTop = fillTop; - this.fillLeft = fillLeft; - this.fillRight = fillRight; - - this.isFilled = 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; - } - -}); - -module.exports = IsoTriangle; - - -/***/ }), -/* 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 Shape = __webpack_require__(34); -var GeomLine = __webpack_require__(47); -var LineRender = __webpack_require__(1115); - -/** - * @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. + * Returns the duration, in ms, that the Key has been held down for. * - * This call can be chained. + * If the key is not currently down it will return zero. * - * @method Phaser.GameObjects.Line#setLineWidth - * @since 3.13.0 + * To get the duration the Key was held down for in the previous up-down cycle, + * use the `Key.duration` property value instead. * - * @param {number} startWidth - The start width of the line. - * @param {number} [endWidth] - The end width of the line. Only used in WebGL. + * @method Phaser.Input.Keyboard.Key#getDuration + * @since 3.17.0 * - * @return {this} This Game Object instance. + * @return {number} The duration, in ms, that the Key has been held down for if currently down. */ - setLineWidth: function (startWidth, endWidth) + getDuration: function () { - if (endWidth === undefined) { endWidth = startWidth; } - - this._startWidth = startWidth; - this._endWidth = endWidth; - - this.lineWidth = startWidth; - - return this; + if (this.isDown) + { + return (this.plugin.game.loop.time - this.timeDown); + } + else + { + return 0; + } }, /** - * 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. + * Removes any bound event handlers and removes local references. * - * @return {this} This Line object. + * @method Phaser.Input.Keyboard.Key#destroy + * @since 3.16.0 */ - setTo: function (x1, y1, x2, y2) + destroy: function () { - this.geom.setTo(x1, y1, x2, y2); + this.removeAllListeners(); - return this; + this.originalEvent = null; + + this.plugin = null; } }); -module.exports = Line; +module.exports = Key; /***/ }), -/* 468 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 11873: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var PolygonRender = __webpack_require__(1118); -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(59); -var GetAABB = __webpack_require__(469); -var GeomPolygon = __webpack_require__(227); -var Shape = __webpack_require__(34); -var Smooth = __webpack_require__(472); - /** - * @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 + * Keyboard Codes. * - * @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. + * @namespace Phaser.Input.Keyboard.KeyCodes + * @memberof Phaser.Input.Keyboard + * @since 3.0.0 */ -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(); - }, +var KeyCodes = { /** - * 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. + * The BACKSPACE key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.BACKSPACE + * @type {number} + * @since 3.0.0 */ - smooth: function (iterations) - { - if (iterations === undefined) { iterations = 1; } + BACKSPACE: 8, - for (var i = 0; i < iterations; i++) - { - Smooth(this.geom); - } + /** + * The TAB key. + * + * @name Phaser.Input.Keyboard.KeyCodes.TAB + * @type {number} + * @since 3.0.0 + */ + TAB: 9, - return this.updateData(); - }, + /** + * The ENTER key. + * + * @name Phaser.Input.Keyboard.KeyCodes.ENTER + * @type {number} + * @since 3.0.0 + */ + ENTER: 13, /** - * Internal method that updates the data and path values. + * The SHIFT key. * - * @method Phaser.GameObjects.Polygon#updateData - * @private - * @since 3.13.0 + * @name Phaser.Input.Keyboard.KeyCodes.SHIFT + * @type {number} + * @since 3.0.0 + */ + SHIFT: 16, + + /** + * The CTRL key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.CTRL + * @type {number} + * @since 3.0.0 */ - 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; - - -/***/ }), -/* 469 */ -/***/ (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; - - -/***/ }), -/* 470 */ -/***/ (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__(67); -var Line = __webpack_require__(47); -var Perimeter = __webpack_require__(471); - -/** - * 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; - - -/***/ }), -/* 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__(67); -var Line = __webpack_require__(47); - -/** - * 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; - - -/***/ }), -/* 472 */ -/***/ (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; - - -/***/ }), -/* 473 */ -/***/ (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__(34); -var RectangleRender = __webpack_require__(1121); - -/** - * @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(); - }, + CTRL: 17, /** - * Sets the internal size of this Game Object, as used for frame or physics body creation. + * The ALT key. * - * 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. + * @name Phaser.Input.Keyboard.KeyCodes.ALT + * @type {number} + * @since 3.0.0 + */ + ALT: 18, + + /** + * The PAUSE key. * - * 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. + * @name Phaser.Input.Keyboard.KeyCodes.PAUSE + * @type {number} + * @since 3.0.0 + */ + PAUSE: 19, + + /** + * The CAPS_LOCK key. * - * @method Phaser.GameObjects.Rectangle#setSize - * @since 3.13.0 + * @name Phaser.Input.Keyboard.KeyCodes.CAPS_LOCK + * @type {number} + * @since 3.0.0 + */ + CAPS_LOCK: 20, + + /** + * The ESC key. * - * @param {number} width - The width of this Game Object. - * @param {number} height - The height of this Game Object. + * @name Phaser.Input.Keyboard.KeyCodes.ESC + * @type {number} + * @since 3.0.0 + */ + ESC: 27, + + /** + * The SPACE key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.SPACE + * @type {number} + * @since 3.0.0 */ - setSize: function (width, height) - { - this.width = width; - this.height = height; + SPACE: 32, - this.geom.setSize(width, height); + /** + * The PAGE_UP key. + * + * @name Phaser.Input.Keyboard.KeyCodes.PAGE_UP + * @type {number} + * @since 3.0.0 + */ + PAGE_UP: 33, - this.updateData(); + /** + * The PAGE_DOWN key. + * + * @name Phaser.Input.Keyboard.KeyCodes.PAGE_DOWN + * @type {number} + * @since 3.0.0 + */ + PAGE_DOWN: 34, - return this; - }, + /** + * The END key. + * + * @name Phaser.Input.Keyboard.KeyCodes.END + * @type {number} + * @since 3.0.0 + */ + END: 35, /** - * Internal method that updates the data and path values. + * The HOME key. * - * @method Phaser.GameObjects.Rectangle#updateData - * @private - * @since 3.13.0 + * @name Phaser.Input.Keyboard.KeyCodes.HOME + * @type {number} + * @since 3.0.0 + */ + HOME: 36, + + /** + * The LEFT key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.LEFT + * @type {number} + * @since 3.0.0 */ - updateData: function () - { - var path = []; - var rect = this.geom; - var line = this._tempLine; + LEFT: 37, - rect.getLineA(line); + /** + * The UP key. + * + * @name Phaser.Input.Keyboard.KeyCodes.UP + * @type {number} + * @since 3.0.0 + */ + UP: 38, - path.push(line.x1, line.y1, line.x2, line.y2); + /** + * The RIGHT key. + * + * @name Phaser.Input.Keyboard.KeyCodes.RIGHT + * @type {number} + * @since 3.0.0 + */ + RIGHT: 39, - rect.getLineB(line); + /** + * The DOWN key. + * + * @name Phaser.Input.Keyboard.KeyCodes.DOWN + * @type {number} + * @since 3.0.0 + */ + DOWN: 40, - path.push(line.x2, line.y2); + /** + * The PRINT_SCREEN key. + * + * @name Phaser.Input.Keyboard.KeyCodes.PRINT_SCREEN + * @type {number} + * @since 3.0.0 + */ + PRINT_SCREEN: 42, - rect.getLineC(line); + /** + * The INSERT key. + * + * @name Phaser.Input.Keyboard.KeyCodes.INSERT + * @type {number} + * @since 3.0.0 + */ + INSERT: 45, - path.push(line.x2, line.y2); + /** + * The DELETE key. + * + * @name Phaser.Input.Keyboard.KeyCodes.DELETE + * @type {number} + * @since 3.0.0 + */ + DELETE: 46, - rect.getLineD(line); + /** + * The ZERO key. + * + * @name Phaser.Input.Keyboard.KeyCodes.ZERO + * @type {number} + * @since 3.0.0 + */ + ZERO: 48, - path.push(line.x2, line.y2); + /** + * The ONE key. + * + * @name Phaser.Input.Keyboard.KeyCodes.ONE + * @type {number} + * @since 3.0.0 + */ + ONE: 49, - this.pathData = path; + /** + * The TWO key. + * + * @name Phaser.Input.Keyboard.KeyCodes.TWO + * @type {number} + * @since 3.0.0 + */ + TWO: 50, - return this; - } + /** + * The THREE key. + * + * @name Phaser.Input.Keyboard.KeyCodes.THREE + * @type {number} + * @since 3.0.0 + */ + THREE: 51, -}); + /** + * The FOUR key. + * + * @name Phaser.Input.Keyboard.KeyCodes.FOUR + * @type {number} + * @since 3.0.0 + */ + FOUR: 52, -module.exports = Rectangle; + /** + * The FIVE key. + * + * @name Phaser.Input.Keyboard.KeyCodes.FIVE + * @type {number} + * @since 3.0.0 + */ + FIVE: 53, + /** + * The SIX key. + * + * @name Phaser.Input.Keyboard.KeyCodes.SIX + * @type {number} + * @since 3.0.0 + */ + SIX: 54, -/***/ }), -/* 474 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The SEVEN key. + * + * @name Phaser.Input.Keyboard.KeyCodes.SEVEN + * @type {number} + * @since 3.0.0 + */ + SEVEN: 55, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The EIGHT key. + * + * @name Phaser.Input.Keyboard.KeyCodes.EIGHT + * @type {number} + * @since 3.0.0 + */ + EIGHT: 56, -var StarRender = __webpack_require__(1124); -var Class = __webpack_require__(0); -var Earcut = __webpack_require__(59); -var Shape = __webpack_require__(34); + /** + * The NINE key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NINE + * @type {number} + * @since 3.0.0 + */ + NINE: 57, -/** - * @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({ + /** + * The NUMPAD_ZERO key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ZERO + * @type {number} + * @since 3.0.0 + */ + NUMPAD_ZERO: 96, - Extends: Shape, + /** + * The NUMPAD_ONE key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ONE + * @type {number} + * @since 3.0.0 + */ + NUMPAD_ONE: 97, - Mixins: [ - StarRender - ], + /** + * The NUMPAD_TWO key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_TWO + * @type {number} + * @since 3.0.0 + */ + NUMPAD_TWO: 98, - initialize: + /** + * The NUMPAD_THREE key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_THREE + * @type {number} + * @since 3.0.0 + */ + NUMPAD_THREE: 99, - 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; } + /** + * The NUMPAD_FOUR key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_FOUR + * @type {number} + * @since 3.0.0 + */ + NUMPAD_FOUR: 100, - Shape.call(this, scene, 'Star', null); + /** + * The NUMPAD_FIVE key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_FIVE + * @type {number} + * @since 3.0.0 + */ + NUMPAD_FIVE: 101, - /** - * 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; + /** + * The NUMPAD_SIX key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SIX + * @type {number} + * @since 3.0.0 + */ + NUMPAD_SIX: 102, - /** - * Private internal value. - * The inner radius of the star. - * - * @name Phaser.GameObjects.Star#_innerRadius - * @type {number} - * @private - * @since 3.13.0 - */ - this._innerRadius = innerRadius; + /** + * The NUMPAD_SEVEN key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SEVEN + * @type {number} + * @since 3.0.0 + */ + NUMPAD_SEVEN: 103, - /** - * Private internal value. - * The outer radius of the star. - * - * @name Phaser.GameObjects.Star#_outerRadius - * @type {number} - * @private - * @since 3.13.0 - */ - this._outerRadius = outerRadius; + /** + * The NUMPAD_EIGHT key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_EIGHT + * @type {number} + * @since 3.0.0 + */ + NUMPAD_EIGHT: 104, - this.setPosition(x, y); - this.setSize(outerRadius * 2, outerRadius * 2); + /** + * The NUMPAD_NINE key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_NINE + * @type {number} + * @since 3.0.0 + */ + NUMPAD_NINE: 105, - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } + /** + * The Numpad Addition (+) key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ADD + * @type {number} + * @since 3.21.0 + */ + NUMPAD_ADD: 107, - this.updateDisplayOrigin(); - this.updateData(); - }, + /** + * The Numpad Subtraction (-) key. + * + * @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SUBTRACT + * @type {number} + * @since 3.21.0 + */ + NUMPAD_SUBTRACT: 109, /** - * Sets the number of points that make up the Star shape. - * This call can be chained. + * The A key. * - * @method Phaser.GameObjects.Star#setPoints - * @since 3.13.0 - * - * @param {number} value - The amount of points the Star will have. + * @name Phaser.Input.Keyboard.KeyCodes.A + * @type {number} + * @since 3.0.0 + */ + A: 65, + + /** + * The B key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.B + * @type {number} + * @since 3.0.0 */ - setPoints: function (value) - { - this._points = value; + B: 66, - return this.updateData(); - }, + /** + * The C key. + * + * @name Phaser.Input.Keyboard.KeyCodes.C + * @type {number} + * @since 3.0.0 + */ + C: 67, /** - * Sets the inner radius of the Star shape. - * This call can be chained. + * The D key. * - * @method Phaser.GameObjects.Star#setInnerRadius - * @since 3.13.0 - * - * @param {number} value - The amount to set the inner radius to. + * @name Phaser.Input.Keyboard.KeyCodes.D + * @type {number} + * @since 3.0.0 + */ + D: 68, + + /** + * The E key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.E + * @type {number} + * @since 3.0.0 */ - setInnerRadius: function (value) - { - this._innerRadius = value; + E: 69, - return this.updateData(); - }, + /** + * The F key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F + * @type {number} + * @since 3.0.0 + */ + F: 70, /** - * Sets the outer radius of the Star shape. - * This call can be chained. + * The G key. * - * @method Phaser.GameObjects.Star#setOuterRadius - * @since 3.13.0 - * - * @param {number} value - The amount to set the outer radius to. + * @name Phaser.Input.Keyboard.KeyCodes.G + * @type {number} + * @since 3.0.0 + */ + G: 71, + + /** + * The H key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.H + * @type {number} + * @since 3.0.0 */ - setOuterRadius: function (value) - { - this._outerRadius = value; + H: 72, - return this.updateData(); - }, + /** + * The I key. + * + * @name Phaser.Input.Keyboard.KeyCodes.I + * @type {number} + * @since 3.0.0 + */ + I: 73, /** - * The number of points that make up the Star shape. + * The J key. * - * @name Phaser.GameObjects.Star#points + * @name Phaser.Input.Keyboard.KeyCodes.J * @type {number} - * @default 5 - * @since 3.13.0 + * @since 3.0.0 */ - points: { + J: 74, - get: function () - { - return this._points; - }, + /** + * The K key. + * + * @name Phaser.Input.Keyboard.KeyCodes.K + * @type {number} + * @since 3.0.0 + */ + K: 75, - set: function (value) - { - this._points = value; + /** + * The L key. + * + * @name Phaser.Input.Keyboard.KeyCodes.L + * @type {number} + * @since 3.0.0 + */ + L: 76, - this.updateData(); - } + /** + * The M key. + * + * @name Phaser.Input.Keyboard.KeyCodes.M + * @type {number} + * @since 3.0.0 + */ + M: 77, - }, + /** + * The N key. + * + * @name Phaser.Input.Keyboard.KeyCodes.N + * @type {number} + * @since 3.0.0 + */ + N: 78, /** - * The inner radius of the Star shape. + * The O key. * - * @name Phaser.GameObjects.Star#innerRadius + * @name Phaser.Input.Keyboard.KeyCodes.O * @type {number} - * @default 32 - * @since 3.13.0 + * @since 3.0.0 */ - innerRadius: { + O: 79, - get: function () - { - return this._innerRadius; - }, + /** + * The P key. + * + * @name Phaser.Input.Keyboard.KeyCodes.P + * @type {number} + * @since 3.0.0 + */ + P: 80, - set: function (value) - { - this._innerRadius = value; + /** + * The Q key. + * + * @name Phaser.Input.Keyboard.KeyCodes.Q + * @type {number} + * @since 3.0.0 + */ + Q: 81, - this.updateData(); - } + /** + * The R key. + * + * @name Phaser.Input.Keyboard.KeyCodes.R + * @type {number} + * @since 3.0.0 + */ + R: 82, - }, + /** + * The S key. + * + * @name Phaser.Input.Keyboard.KeyCodes.S + * @type {number} + * @since 3.0.0 + */ + S: 83, /** - * The outer radius of the Star shape. + * The T key. * - * @name Phaser.GameObjects.Star#outerRadius + * @name Phaser.Input.Keyboard.KeyCodes.T * @type {number} - * @default 64 - * @since 3.13.0 + * @since 3.0.0 */ - outerRadius: { + T: 84, - get: function () - { - return this._outerRadius; - }, + /** + * The U key. + * + * @name Phaser.Input.Keyboard.KeyCodes.U + * @type {number} + * @since 3.0.0 + */ + U: 85, - set: function (value) - { - this._outerRadius = value; + /** + * The V key. + * + * @name Phaser.Input.Keyboard.KeyCodes.V + * @type {number} + * @since 3.0.0 + */ + V: 86, - this.updateData(); - } + /** + * The W key. + * + * @name Phaser.Input.Keyboard.KeyCodes.W + * @type {number} + * @since 3.0.0 + */ + W: 87, - }, + /** + * The X key. + * + * @name Phaser.Input.Keyboard.KeyCodes.X + * @type {number} + * @since 3.0.0 + */ + X: 88, /** - * Internal method that updates the data and path values. + * The Y key. * - * @method Phaser.GameObjects.Star#updateData - * @private - * @since 3.13.0 + * @name Phaser.Input.Keyboard.KeyCodes.Y + * @type {number} + * @since 3.0.0 + */ + Y: 89, + + /** + * The Z key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.Z + * @type {number} + * @since 3.0.0 */ - updateData: function () - { - var path = []; + Z: 90, - 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); + /** + * The F1 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F1 + * @type {number} + * @since 3.0.0 + */ + F1: 112, - rot += step; + /** + * The F2 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F2 + * @type {number} + * @since 3.0.0 + */ + F2: 113, - path.push(x + Math.cos(rot) * innerRadius, y + Math.sin(rot) * innerRadius); - - rot += step; - } + /** + * The F3 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F3 + * @type {number} + * @since 3.0.0 + */ + F3: 114, - path.push(x, y + -outerRadius); + /** + * The F4 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F4 + * @type {number} + * @since 3.0.0 + */ + F4: 115, - this.pathIndexes = Earcut(path); - this.pathData = path; + /** + * The F5 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F5 + * @type {number} + * @since 3.0.0 + */ + F5: 116, - return this; - } + /** + * The F6 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F6 + * @type {number} + * @since 3.0.0 + */ + F6: 117, -}); + /** + * The F7 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F7 + * @type {number} + * @since 3.0.0 + */ + F7: 118, -module.exports = Star; + /** + * The F8 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F8 + * @type {number} + * @since 3.0.0 + */ + F8: 119, + /** + * The F9 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F9 + * @type {number} + * @since 3.0.0 + */ + F9: 120, -/***/ }), -/* 475 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The F10 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F10 + * @type {number} + * @since 3.0.0 + */ + F10: 121, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The F11 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F11 + * @type {number} + * @since 3.0.0 + */ + F11: 122, -var Class = __webpack_require__(0); -var Shape = __webpack_require__(34); -var GeomTriangle = __webpack_require__(82); -var TriangleRender = __webpack_require__(1127); + /** + * The F12 key. + * + * @name Phaser.Input.Keyboard.KeyCodes.F12 + * @type {number} + * @since 3.0.0 + */ + F12: 123, -/** - * @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({ + /** + * The SEMICOLON key. + * + * @name Phaser.Input.Keyboard.KeyCodes.SEMICOLON + * @type {number} + * @since 3.0.0 + */ + SEMICOLON: 186, - Extends: Shape, + /** + * The PLUS key. + * + * @name Phaser.Input.Keyboard.KeyCodes.PLUS + * @type {number} + * @since 3.0.0 + */ + PLUS: 187, - Mixins: [ - TriangleRender - ], + /** + * The COMMA key. + * + * @name Phaser.Input.Keyboard.KeyCodes.COMMA + * @type {number} + * @since 3.0.0 + */ + COMMA: 188, - initialize: + /** + * The MINUS key. + * + * @name Phaser.Input.Keyboard.KeyCodes.MINUS + * @type {number} + * @since 3.0.0 + */ + MINUS: 189, - 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; } + /** + * The PERIOD key. + * + * @name Phaser.Input.Keyboard.KeyCodes.PERIOD + * @type {number} + * @since 3.0.0 + */ + PERIOD: 190, - Shape.call(this, scene, 'Triangle', new GeomTriangle(x1, y1, x2, y2, x3, y3)); + /** + * The FORWARD_SLASH key. + * + * @name Phaser.Input.Keyboard.KeyCodes.FORWARD_SLASH + * @type {number} + * @since 3.0.0 + */ + FORWARD_SLASH: 191, - var width = this.geom.right - this.geom.left; - var height = this.geom.bottom - this.geom.top; + /** + * The BACK_SLASH key. + * + * @name Phaser.Input.Keyboard.KeyCodes.BACK_SLASH + * @type {number} + * @since 3.0.0 + */ + BACK_SLASH: 220, - this.setPosition(x, y); - this.setSize(width, height); + /** + * The QUOTES key. + * + * @name Phaser.Input.Keyboard.KeyCodes.QUOTES + * @type {number} + * @since 3.0.0 + */ + QUOTES: 222, - if (fillColor !== undefined) - { - this.setFillStyle(fillColor, fillAlpha); - } + /** + * The BACKTICK key. + * + * @name Phaser.Input.Keyboard.KeyCodes.BACKTICK + * @type {number} + * @since 3.0.0 + */ + BACKTICK: 192, - this.updateDisplayOrigin(); - this.updateData(); - }, + /** + * The OPEN_BRACKET key. + * + * @name Phaser.Input.Keyboard.KeyCodes.OPEN_BRACKET + * @type {number} + * @since 3.0.0 + */ + OPEN_BRACKET: 219, /** - * Sets the data for the lines that make up this Triangle shape. + * The CLOSED_BRACKET key. * - * @method Phaser.GameObjects.Triangle#setTo - * @since 3.13.0 + * @name Phaser.Input.Keyboard.KeyCodes.CLOSED_BRACKET + * @type {number} + * @since 3.0.0 + */ + CLOSED_BRACKET: 221, + + /** + * The SEMICOLON_FIREFOX key. * - * @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. + * @name Phaser.Input.Keyboard.KeyCodes.SEMICOLON_FIREFOX + * @type {number} + * @since 3.0.0 + */ + SEMICOLON_FIREFOX: 59, + + /** + * The COLON key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.COLON + * @type {number} + * @since 3.0.0 */ - setTo: function (x1, y1, x2, y2, x3, y3) - { - this.geom.setTo(x1, y1, x2, y2, x3, y3); + COLON: 58, - return this.updateData(); - }, + /** + * The COMMA_FIREFOX_WINDOWS key. + * + * @name Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX_WINDOWS + * @type {number} + * @since 3.0.0 + */ + COMMA_FIREFOX_WINDOWS: 60, /** - * Internal method that updates the data and path values. + * The COMMA_FIREFOX key. * - * @method Phaser.GameObjects.Triangle#updateData - * @private - * @since 3.13.0 + * @name Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX + * @type {number} + * @since 3.0.0 + */ + COMMA_FIREFOX: 62, + + /** + * The BRACKET_RIGHT_FIREFOX key. * - * @return {this} This Game Object instance. + * @name Phaser.Input.Keyboard.KeyCodes.BRACKET_RIGHT_FIREFOX + * @type {number} + * @since 3.0.0 */ - updateData: function () - { - var path = []; - var tri = this.geom; - var line = this._tempLine; + BRACKET_RIGHT_FIREFOX: 174, - tri.getLineA(line); + /** + * The BRACKET_LEFT_FIREFOX key. + * + * @name Phaser.Input.Keyboard.KeyCodes.BRACKET_LEFT_FIREFOX + * @type {number} + * @since 3.0.0 + */ + BRACKET_LEFT_FIREFOX: 175 +}; - path.push(line.x1, line.y1, line.x2, line.y2); +module.exports = KeyCodes; - tri.getLineB(line); - path.push(line.x2, line.y2); +/***/ }), - tri.getLineC(line); +/***/ 48044: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - path.push(line.x2, line.y2); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.pathData = path; +var KeyCodes = __webpack_require__(11873); - return this; - } +var KeyMap = {}; -}); +for (var key in KeyCodes) +{ + KeyMap[KeyCodes[key]] = key; +} -module.exports = Triangle; +module.exports = KeyMap; /***/ }), -/* 476 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 70331: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Point = __webpack_require__(4); -var Length = __webpack_require__(67); - /** - * Returns a Point from around the perimeter of a Triangle. + * Returns `true` if the Key was released within the `duration` value given, based on the current + * game clock time. Or returns `false` if it either isn't up, or was released longer ago than the given duration. * - * @function Phaser.Geom.Triangle.GetPoint + * @function Phaser.Input.Keyboard.UpDuration * @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. + * @param {Phaser.Input.Keyboard.Key} key - The Key object to test. + * @param {number} [duration=50] - The duration, in ms, within which the key must have been released. * - * @return {(Phaser.Geom.Point|object)} A Point object containing the given position from the perimeter of the triangle. + * @return {boolean} `true` if the Key was released within `duration` ms ago, otherwise `false`. */ -var GetPoint = function (triangle, position, out) +var UpDuration = function (key, duration) { - 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; + if (duration === undefined) { duration = 50; } - out.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; - out.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; - } + var current = key.plugin.game.loop.time - key.timeUp; - return out; + return (key.isUp && current < duration); }; -module.exports = GetPoint; +module.exports = UpDuration; /***/ }), -/* 477 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 7905: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Length = __webpack_require__(67); -var Point = __webpack_require__(4); +var Class = __webpack_require__(56694); +var Features = __webpack_require__(90185); +var InputEvents = __webpack_require__(33963); +var NOOP = __webpack_require__(72283); + +// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent +// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md /** - * Returns an array of evenly spaced points on the perimeter of a Triangle. + * @classdesc + * The Mouse Manager is a helper class that belongs to the Input Manager. * - * @function Phaser.Geom.Triangle.GetPoints - * @since 3.0.0 + * Its role is to listen for native DOM Mouse Events and then pass them onto the Input Manager for further processing. * - * @generic {Phaser.Geom.Point} O - [out,$return] + * You do not need to create this class directly, the Input Manager will create an instance of it automatically. * - * @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. + * @class MouseManager + * @memberof Phaser.Input.Mouse + * @constructor + * @since 3.0.0 * - * @return {(array|Phaser.Geom.Point[])} The modified `out` array, or a new array if none was provided. + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. */ -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 MouseManager = new Class({ - var perimeter = length1 + length2 + length3; + initialize: - // If quantity is a falsey value (false, null, 0, undefined, etc) then we calculate it based on the stepRate instead. - if (!quantity && stepRate > 0) + function MouseManager (inputManager) { - quantity = perimeter / stepRate; - } + /** + * A reference to the Input Manager. + * + * @name Phaser.Input.Mouse.MouseManager#manager + * @type {Phaser.Input.InputManager} + * @since 3.0.0 + */ + this.manager = inputManager; - for (var i = 0; i < quantity; i++) - { - var p = perimeter * (i / quantity); - var localPosition = 0; + /** + * 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; - var point = new Point(); + /** + * 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; - // Which line is it on? + /** + * 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 (p < length1) - { - // Line 1 - localPosition = p / length1; + /** + * 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; - 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; + /** + * 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; - 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; + /** + * 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; - point.x = line2.x1 + (line2.x2 - line2.x1) * localPosition; - point.y = line2.y1 + (line2.y2 - line2.y1) * localPosition; - } + /** + * 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; - out.push(point); - } + /** + * 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; - return out; -}; + /** + * 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; -module.exports = GetPoints; + /** + * 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; -/***/ }), -/* 478 */ -/***/ (function(module, exports) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -/** - * 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; + /** + * 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; - return true; - } - else if (key.indexOf('.') !== -1) - { - var keys = key.split('.'); - var parent = source; - var prev = source; + /** + * 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; - // 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; - } - } + /** + * 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; - prev[keys[keys.length - 1]] = value; + /** + * 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; - return true; - } - - return false; -}; + inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); + }, -module.exports = SetValue; + /** + * 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; -/***/ }), -/* 479 */ -/***/ (function(module, exports, __webpack_require__) { + this.preventDefaultDown = config.inputMousePreventDefaultDown; + this.preventDefaultUp = config.inputMousePreventDefaultUp; + this.preventDefaultMove = config.inputMousePreventDefaultMove; + this.preventDefaultWheel = config.inputMousePreventDefaultWheel; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!this.target) + { + this.target = this.manager.game.canvas; + } + else if (typeof this.target === 'string') + { + this.target = document.getElementById(this.target); + } -var Face = __webpack_require__(116); -var Vertex = __webpack_require__(117); + if (config.disableContextMenu) + { + this.disableContextMenu(); + } -/** - * 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 (this.enabled && this.target) + { + this.startListeners(); + } + }, - if (vertices.length !== uvs.length) + /** + * Attempts to disable the context menu from appearing if you right-click on the game canvas, or specified input target. + * + * 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 context + * menu keeps getting in the way. + * + * @method Phaser.Input.Mouse.MouseManager#disableContextMenu + * @since 3.0.0 + * + * @return {this} This Mouse Manager instance. + */ + disableContextMenu: function () { - console.warn('GenerateVerts: vertices and uvs count not equal'); - return; - } + this.target.addEventListener('contextmenu', function (event) + { + event.preventDefault(); + return false; + }); - var result = { - faces: [], - vertices: [] - }; + return this; + }, - var i; + /** + * 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; - var x; - var y; - var z; + element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock; - var u; - var v; + element.requestPointerLock(); + } + }, - var color; - var alpha; + /** + * 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(); + } + }, - var normalX; - var normalY; - var normalZ; + /** + * 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; - var iInc = (containsZ) ? 3 : 2; + if (!target) + { + return; + } - var isColorArray = Array.isArray(colors); - var isAlphaArray = Array.isArray(alphas); + var _this = this; + var manager = this.manager; + var canvas = manager.canvas; + var autoFocus = (window && window.focus && manager.game.config.autoFocus); - if (Array.isArray(indicies) && indicies.length > 0) - { - for (i = 0; i < indicies.length; i++) + this.onMouseMove = function (event) { - var index1 = indicies[i]; - var index2 = indicies[i] * 2; - var index3 = indicies[i] * iInc; + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseMove(event); - x = vertices[index3]; - y = vertices[index3 + 1]; - z = (containsZ) ? vertices[index3 + 2] : 0; + if (_this.preventDefaultMove) + { + event.preventDefault(); + } + } + }; - u = uvs[index2]; - v = uvs[index2 + 1]; + this.onMouseDown = function (event) + { + if (autoFocus) + { + window.focus(); + } - color = (isColorArray) ? colors[index1] : colors; - alpha = (isAlphaArray) ? alphas[index1] : alphas; + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseDown(event); - normalX = 0; - normalY = 0; - normalZ = 0; + if (_this.preventDefaultDown && event.target === canvas) + { + event.preventDefault(); + } + } + }; - if (normals) + this.onMouseDownWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) { - normalX = normals[index3]; - normalY = normals[index3 + 1]; - normalZ = (containsZ) ? normals[index3 + 2] : 0; + // Only process the event if the target isn't the canvas + manager.onMouseDown(event); } + }; - result.vertices.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); - } - } - else - { - var uvIndex = 0; - var colorIndex = 0; + this.onMouseUp = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseUp(event); - for (i = 0; i < vertices.length; i += iInc) + if (_this.preventDefaultUp && event.target === canvas) + { + event.preventDefault(); + } + } + }; + + this.onMouseUpWindow = function (event) { - x = vertices[i]; - y = vertices[i + 1]; - z = (containsZ) ? vertices[i + 2] : 0; + 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); + } + }; - u = uvs[uvIndex]; - v = uvs[uvIndex + 1]; + this.onMouseOver = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.setCanvasOver(event); + } + }; - color = (isColorArray) ? colors[colorIndex] : colors; - alpha = (isAlphaArray) ? alphas[colorIndex] : alphas; + this.onMouseOut = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.setCanvasOut(event); + } + }; - normalX = 0; - normalY = 0; - normalZ = 0; + this.onMouseWheel = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onMouseWheel(event); + } - if (normals) + if (_this.preventDefaultWheel && event.target === canvas) { - normalX = normals[i]; - normalY = normals[i + 1]; - normalZ = (containsZ) ? normals[i + 2] : 0; + event.preventDefault(); } + }; - result.vertices.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ)); + var passive = { passive: true }; - uvIndex += 2; - colorIndex++; - } - } + 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); - for (i = 0; i < result.vertices.length; i += 3) - { - var vert1 = result.vertices[i]; - var vert2 = result.vertices[i + 1]; - var vert3 = result.vertices[i + 2]; + if (this.preventDefaultWheel) + { + target.addEventListener('wheel', this.onMouseWheel, { passive: false }); + } + else + { + target.addEventListener('wheel', this.onMouseWheel, passive); + } - result.faces.push(new Face(vert1, vert2, vert3)); - } + 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); - return result; -}; + this.isTop = false; + } + } -module.exports = GenerateVerts; + if (Features.pointerLock) + { + this.pointerLockChange = function (event) + { + var element = _this.target; + _this.locked = (document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element) ? true : false; -/***/ }), -/* 480 */ -/***/ (function(module, exports, __webpack_require__) { + manager.onPointerLockChange(event); + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + document.addEventListener('pointerlockchange', this.pointerLockChange, true); + document.addEventListener('mozpointerlockchange', this.pointerLockChange, true); + document.addEventListener('webkitpointerlockchange', this.pointerLockChange, true); + } -var Face = __webpack_require__(116); -var Matrix4 = __webpack_require__(69); -var Vector3 = __webpack_require__(39); -var Vertex = __webpack_require__(117); + this.enabled = true; + }, -var tempPosition = new Vector3(); -var tempRotation = new Vector3(); -var tempMatrix = new Matrix4(); + /** + * 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; -/** - * 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; } + 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); - var result = { - faces: [], - verts: [] - }; + if (window) + { + target = (this.isTop) ? window.top : window; - var materials = data.materials; + target.removeEventListener('mousedown', this.onMouseDownWindow); + target.removeEventListener('mouseup', this.onMouseUpWindow); + } - tempPosition.set(x, y, z); - tempRotation.set(rotateX, rotateY, rotateZ); - tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp); + if (Features.pointerLock) + { + document.removeEventListener('pointerlockchange', this.pointerLockChange, true); + document.removeEventListener('mozpointerlockchange', this.pointerLockChange, true); + document.removeEventListener('webkitpointerlockchange', this.pointerLockChange, true); + } + }, - for (var m = 0; m < data.models.length; m++) + /** + * Destroys this Mouse Manager instance. + * + * @method Phaser.Input.Mouse.MouseManager#destroy + * @since 3.0.0 + */ + destroy: function () { - var model = data.models[m]; - - var vertices = model.vertices; - var textureCoords = model.textureCoords; - var faces = model.faces; + this.stopListeners(); - for (var i = 0; i < faces.length; i++) - { - var face = faces[i]; + this.target = null; + this.enabled = false; + this.manager = null; + } - 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]; +module.exports = MouseManager; - 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; +/***/ 11343: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (face.material !== '' && materials[face.material]) - { - color = materials[face.material]; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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); +/** + * @namespace Phaser.Input.Mouse + */ - result.verts.push(vert1, vert2, vert3); - result.faces.push(new Face(vert1, vert2, vert3)); - } - } +/* eslint-disable */ +module.exports = { - if (mesh) - { - mesh.faces = mesh.faces.concat(result.faces); - mesh.vertices = mesh.vertices.concat(result.verts); - } + MouseManager: __webpack_require__(7905) - return result; }; - -module.exports = GenerateObjVerts; +/* eslint-enable */ /***/ }), -/* 481 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 37579: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(65); -var Class = __webpack_require__(0); -var Components = __webpack_require__(11); -var RGB = __webpack_require__(200); -var Utils = __webpack_require__(12); +var Class = __webpack_require__(56694); +var InputEvents = __webpack_require__(33963); +var NOOP = __webpack_require__(72283); + +// 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 - * A 2D point light. - * - * These are typically created by a {@link Phaser.GameObjects.LightsManager}, available from within a scene via `this.lights`. + * The Touch Manager is a helper class that belongs to the Input Manager. * - * Any Game Objects using the Light2D pipeline will then be affected by these Lights as long as they have a normal map. + * Its role is to listen for native DOM Touch Events and then pass them onto the Input Manager for further processing. * - * They can also simply be used to represent a point light for your own purposes. + * You do not need to create this class directly, the Input Manager will create an instance of it automatically. * - * @class Light - * @extends Phaser.Geom.Circle - * @memberof Phaser.GameObjects + * @class TouchManager + * @memberof Phaser.Input.Touch * @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. + * @param {Phaser.Input.InputManager} inputManager - A reference to the Input Manager. */ -var Light = new Class({ - - Extends: Circle, - - Mixins: [ - Components.ScrollFactor, - Components.Visible - ], +var TouchManager = new Class({ initialize: - function Light (x, y, radius, r, g, b, intensity) + function TouchManager (inputManager) { - Circle.call(this, x, y, radius); - /** - * The color of the light. + * A reference to the Input Manager. * - * @name Phaser.GameObjects.Light#color - * @type {Phaser.Display.RGB} - * @since 3.50.0 + * @name Phaser.Input.Touch.TouchManager#manager + * @type {Phaser.Input.InputManager} + * @since 3.0.0 */ - this.color = new RGB(r, g, b); + this.manager = inputManager; /** - * The intensity of the light. + * If true the DOM events will have event.preventDefault applied to them, if false they will propagate fully. * - * @name Phaser.GameObjects.Light#intensity - * @type {number} - * @since 3.50.0 + * @name Phaser.Input.Touch.TouchManager#capture + * @type {boolean} + * @default true + * @since 3.0.0 */ - this.intensity = intensity; + this.capture = true; /** - * 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. + * A boolean that controls if the Touch Manager is enabled or not. + * Can be toggled on the fly. * - * @name Phaser.GameObjects.GameObject#renderFlags - * @type {number} - * @default 15 + * @name Phaser.Input.Touch.TouchManager#enabled + * @type {boolean} + * @default false * @since 3.0.0 */ - this.renderFlags = 15; + this.enabled = false; /** - * 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 + * 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.GameObjects.GameObject#cameraFilter - * @type {number} - * @default 0 + * @name Phaser.Input.Touch.TouchManager#target + * @type {any} * @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; - - -/***/ }), -/* 482 */ -/***/ (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__(151); -var Class = __webpack_require__(0); -var DistanceBetween = __webpack_require__(50); -var Light = __webpack_require__(481); -var PointLight = __webpack_require__(150); -var RGB = __webpack_require__(200); -var SpliceOne = __webpack_require__(74); -var StableSort = __webpack_require__(79); -var Utils = __webpack_require__(12); - -/** - * @callback LightForEach - * - * @param {Phaser.GameObjects.Light} light - The Light. - */ + this.target; -/** - * @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({ + /** + * 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; - initialize: + /** + * 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; - function LightsManager () - { /** - * The Lights in the Scene. + * The Touch Move event handler function. + * Initially empty and bound in the `startListeners` method. * - * @name Phaser.GameObjects.LightsManager#lights - * @type {Phaser.GameObjects.Light[]} - * @default [] + * @name Phaser.Input.Touch.TouchManager#onTouchMove + * @type {function} * @since 3.0.0 */ - this.lights = []; + this.onTouchMove = NOOP; /** - * The ambient color. + * The Touch End event handler function. + * Initially empty and bound in the `startListeners` method. * - * @name Phaser.GameObjects.LightsManager#ambientColor - * @type {Phaser.Display.RGB} - * @since 3.50.0 + * @name Phaser.Input.Touch.TouchManager#onTouchEnd + * @type {function} + * @since 3.0.0 */ - this.ambientColor = new RGB(0.1, 0.1, 0.1); + this.onTouchEnd = NOOP; /** - * Whether the Lights Manager is enabled. + * The Touch End event handler function specifically for events on the Window. + * Initially empty and bound in the `startListeners` method. * - * @name Phaser.GameObjects.LightsManager#active - * @type {boolean} - * @default false - * @since 3.0.0 + * @name Phaser.Input.Touch.TouchManager#onTouchEndWindow + * @type {function} + * @since 3.17.0 */ - this.active = false; + this.onTouchEndWindow = NOOP; /** - * 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. + * The Touch Cancel event handler function. + * Initially empty and bound in the `startListeners` method. * - * @name Phaser.GameObjects.LightsManager#maxLights - * @type {number} - * @readonly + * @name Phaser.Input.Touch.TouchManager#onTouchCancel + * @type {function} * @since 3.15.0 */ - this.maxLights = -1; + this.onTouchCancel = NOOP; /** - * The number of lights that the LightPipeline processed in the _previous_ frame. + * The Touch Cancel event handler function specifically for events on the Window. + * Initially empty and bound in the `startListeners` method. * - * @name Phaser.GameObjects.LightsManager#visibleLights - * @type {number} + * @name Phaser.Input.Touch.TouchManager#onTouchCancelWindow + * @type {function} + * @since 3.18.0 + */ + this.onTouchCancelWindow = 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.Touch.TouchManager#isTop + * @type {boolean} * @readonly - * @since 3.50.0 + * @since 3.60.0 */ - this.visibleLights = 0; - }, + this.isTop = true; - /** - * Creates a new Point Light Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Point Light Game Object has been built into Phaser. - * - * The Point Light Game Object provides a way to add a point light effect into your game, - * without the expensive shader processing requirements of the traditional Light Game Object. - * - * The difference is that the Point Light renders using a custom shader, designed to give the - * impression of a point light source, of variable radius, intensity and color, in your game. - * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their - * normal maps for calcuations. This makes them extremely fast to render compared to Lights - * and perfect for special effects, such as flickering torches or muzzle flashes. - * - * For maximum performance you should batch Point Light Game Objects together. This means - * ensuring they follow each other consecutively on the display list. Ideally, use a Layer - * Game Object and then add just Point Lights to it, so that it can batch together the rendering - * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in - * your game then it's perfectly safe to mix them into the dislay list as normal. However, if - * you're using a large number of them, please consider how they are mixed into the display list. - * - * The renderer will automatically cull Point Lights. Those with a radius that does not intersect - * with the Camera will be skipped in the rendering list. This happens automatically and the - * culled state is refreshed every frame, for every camera. - * - * The origin of a Point Light is always 0.5 and it cannot be changed. - * - * Point Lights are a WebGL only feature and do not have a Canvas counterpart. - * - * @method Phaser.GameObjects.LightsManager#addPointLight - * @since 3.50.0 - * - * @param {number} x - The horizontal position of this Point Light in the world. - * @param {number} y - The vertical position of this Point Light in the world. - * @param {number} [color=0xffffff] - The color of the Point Light, given as a hex value. - * @param {number} [radius=128] - The radius of the Point Light. - * @param {number} [intensity=1] - The intensity, or colr blend, of the Point Light. - * @param {number} [attenuation=0.1] - The attenuation of the Point Light. This is the reduction of light from the center point. - * - * @return {Phaser.GameObjects.PointLight} The Game Object that was created. - */ - addPointLight: function (x, y, color, radius, intensity, attenuation) - { - return this.systems.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity, attenuation)); + inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this); }, /** - * Enable the Lights Manager. + * The Touch Manager boot process. * - * @method Phaser.GameObjects.LightsManager#enable + * @method Phaser.Input.Touch.TouchManager#boot + * @private * @since 3.0.0 - * - * @return {this} This Lights Manager instance. */ - enable: function () + boot: function () { - if (this.maxLights === -1) + var config = this.manager.config; + + this.enabled = config.inputTouch; + this.target = config.inputTouchEventTarget; + this.capture = config.inputTouchCapture; + + if (!this.target) { - this.maxLights = this.systems.renderer.config.maxLights; + this.target = this.manager.game.canvas; + } + else if (typeof this.target === 'string') + { + this.target = document.getElementById(this.target); } - this.active = true; + if (config.disableContextMenu) + { + this.disableContextMenu(); + } - return this; + if (this.enabled && this.target) + { + this.startListeners(); + } }, /** - * Disable the Lights Manager. + * Attempts to disable the context menu from appearing if you touch-hold on the browser. * - * @method Phaser.GameObjects.LightsManager#disable - * @since 3.0.0 + * Works by listening for the `contextmenu` event and prevent defaulting it. * - * @return {this} This Lights Manager instance. + * 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. */ - disable: function () + disableContextMenu: function () { - this.active = false; + this.target.addEventListener('contextmenu', function (event) + { + event.preventDefault(); + return 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 + * Starts the Touch Event listeners running as long as an input target is set. * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to cull Lights for. + * 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. * - * @return {Phaser.GameObjects.Light[]} The culled Lights. + * @method Phaser.Input.Touch.TouchManager#startListeners + * @since 3.0.0 */ - getLights: function (camera) + startListeners: function () { - var lights = this.lights; - var worldView = camera.worldView; - - var visibleLights = []; + var target = this.target; - for (var i = 0; i < lights.length; i++) + if (!target) { - var light = lights[i]; + return; + } - if (light.willRender(camera) && CircleToRectangle(light, worldView)) + var _this = this; + var manager = this.manager; + var canvas = manager.canvas; + var autoFocus = (window && window.focus && manager.game.config.autoFocus); + + this.onTouchMove = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) { - visibleLights.push({ - light: light, - distance: DistanceBetween(light.x, light.y, worldView.centerX, worldView.centerY) - }); + manager.onTouchMove(event); + + if (_this.capture && event.cancelable) + { + event.preventDefault(); + } } - } + }; - if (visibleLights.length > this.maxLights) + this.onTouchStart = function (event) { - // 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); + if (autoFocus) + { + window.focus(); + } - visibleLights = visibleLights.slice(0, this.maxLights); - } + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onTouchStart(event); - this.visibleLights = visibleLights.length; + if (_this.capture && event.cancelable && event.target === canvas) + { + event.preventDefault(); + } + } + }; - return visibleLights; - }, + this.onTouchStartWindow = 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.onTouchStart(event); + } + }; - sortByDistance: function (a, b) - { - return (a.distance >= b.distance); - }, + this.onTouchEnd = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onTouchEnd(event); - /** - * 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 {this} This Lights Manager instance. - */ - setAmbientColor: function (rgb) - { - var color = Utils.getFloatsFromUintRGB(rgb); + if (_this.capture && event.cancelable && event.target === canvas) + { + event.preventDefault(); + } + } + }; - this.ambientColor.set(color[0], color[1], color[2]); + this.onTouchEndWindow = 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.onTouchEnd(event); + } + }; - return this; - }, + this.onTouchCancel = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onTouchCancel(event); - /** - * 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; - }, + if (_this.capture) + { + event.preventDefault(); + } + } + }; - /** - * 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; - }, + this.onTouchCancelWindow = function (event) + { + if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) + { + manager.onTouchCancel(event); + } + }; - /** - * 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=128] - 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 capture = this.capture; + var passive = { passive: true }; + var nonPassive = { passive: false }; - var color = Utils.getFloatsFromUintRGB(rgb); + target.addEventListener('touchstart', this.onTouchStart, (capture) ? nonPassive : passive); + target.addEventListener('touchmove', this.onTouchMove, (capture) ? nonPassive : passive); + target.addEventListener('touchend', this.onTouchEnd, (capture) ? nonPassive : passive); + target.addEventListener('touchcancel', this.onTouchCancel, (capture) ? nonPassive : passive); - var light = new Light(x, y, radius, color[0], color[1], color[2], intensity); + if (window && manager.game.config.inputWindowEvents) + { + try + { + window.top.addEventListener('touchstart', this.onTouchStartWindow, nonPassive); + window.top.addEventListener('touchend', this.onTouchEndWindow, nonPassive); + window.top.addEventListener('touchcancel', this.onTouchCancelWindow, nonPassive); + } + catch (exception) + { + window.addEventListener('touchstart', this.onTouchStartWindow, nonPassive); + window.addEventListener('touchend', this.onTouchEndWindow, nonPassive); + window.addEventListener('touchcancel', this.onTouchCancelWindow, nonPassive); - this.lights.push(light); + this.isTop = false; + } + } - return light; + this.enabled = true; }, /** - * Remove a Light. + * Stops the Touch Event listeners. + * This is called automatically and does not need to be manually invoked. * - * @method Phaser.GameObjects.LightsManager#removeLight + * @method Phaser.Input.Touch.TouchManager#stopListeners * @since 3.0.0 - * - * @param {Phaser.GameObjects.Light} light - The Light to remove. - * - * @return {this} This Lights Manager instance. */ - removeLight: function (light) + stopListeners: function () { - var index = this.lights.indexOf(light); + var target = this.target; - if (index >= 0) - { - SpliceOne(this.lights, index); - } + target.removeEventListener('touchstart', this.onTouchStart); + target.removeEventListener('touchmove', this.onTouchMove); + target.removeEventListener('touchend', this.onTouchEnd); + target.removeEventListener('touchcancel', this.onTouchCancel); - return this; - }, + if (window) + { + target = (this.isTop) ? window.top : window; - /** - * 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; + target.removeEventListener('touchstart', this.onTouchStartWindow); + target.removeEventListener('touchend', this.onTouchEndWindow); + target.removeEventListener('touchcancel', this.onTouchCancelWindow); + } }, /** - * Destroy the Lights Manager. - * - * Cleans up all references by calling {@link Phaser.GameObjects.LightsManager#shutdown}. + * Destroys this Touch Manager instance. * - * @method Phaser.GameObjects.LightsManager#destroy + * @method Phaser.Input.Touch.TouchManager#destroy * @since 3.0.0 */ destroy: function () { - this.shutdown(); + this.stopListeners(); + + this.target = null; + this.enabled = false; + this.manager = null; } }); -module.exports = LightsManager; +module.exports = TouchManager; /***/ }), -/* 483 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 77423: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(56); -var Extend = __webpack_require__(17); - /** - * @namespace Phaser.Geom + * @namespace Phaser.Input.Touch */ -var Geom = { +/* eslint-disable */ +module.exports = { - Circle: __webpack_require__(1191), - Ellipse: __webpack_require__(1201), - Intersects: __webpack_require__(484), - Line: __webpack_require__(1221), - Mesh: __webpack_require__(1243), - Point: __webpack_require__(1246), - Polygon: __webpack_require__(1260), - Rectangle: __webpack_require__(502), - Triangle: __webpack_require__(1293) + TouchManager: __webpack_require__(37579) }; - -// Merge in the consts -Geom = Extend(false, Geom, CONST); - -module.exports = Geom; +/* eslint-enable */ /***/ }), -/* 484 */ -/***/ (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__(231), - CircleToRectangle: __webpack_require__(151), - GetCircleToCircle: __webpack_require__(1211), - GetCircleToRectangle: __webpack_require__(1212), - GetLineToCircle: __webpack_require__(232), - GetLineToLine: __webpack_require__(485), - GetLineToPoints: __webpack_require__(486), - GetLineToPolygon: __webpack_require__(487), - GetLineToRectangle: __webpack_require__(234), - GetRaysFromPointToPolygon: __webpack_require__(1213), - GetRectangleIntersection: __webpack_require__(1214), - GetRectangleToRectangle: __webpack_require__(1215), - GetRectangleToTriangle: __webpack_require__(1216), - GetTriangleToCircle: __webpack_require__(1217), - GetTriangleToLine: __webpack_require__(492), - GetTriangleToTriangle: __webpack_require__(1218), - LineToCircle: __webpack_require__(233), - LineToLine: __webpack_require__(96), - LineToRectangle: __webpack_require__(488), - PointToLine: __webpack_require__(496), - PointToLineSegment: __webpack_require__(1219), - RectangleToRectangle: __webpack_require__(152), - RectangleToTriangle: __webpack_require__(489), - RectangleToValues: __webpack_require__(1220), - TriangleToCircle: __webpack_require__(491), - TriangleToLine: __webpack_require__(493), - TriangleToTriangle: __webpack_require__(494) - -}; - - -/***/ }), -/* 485 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 98035: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Vector3 = __webpack_require__(39); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var Events = __webpack_require__(683); +var GetFastValue = __webpack_require__(72632); +var GetURL = __webpack_require__(30750); +var MergeXHRSettings = __webpack_require__(43531); +var XHRLoader = __webpack_require__(88490); +var XHRSettings = __webpack_require__(33868); /** - * 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 + * @classdesc + * The base File class used by all File Types that the Loader can support. + * You shouldn't create an instance of a File directly, but should extend it with your own class, setting a custom type and processing methods. * - * @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. + * @class File + * @memberof Phaser.Loader + * @constructor + * @since 3.0.0 * - * @return {Phaser.Math.Vector3} A Vector3 containing the intersection results, or `null`. + * @param {Phaser.Loader.LoaderPlugin} loader - The Loader that is going to load this File. + * @param {Phaser.Types.Loader.FileConfig} fileConfig - The file configuration object, as created by the file type. */ -var 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 File = new Class({ - var dx1 = x2 - x1; - var dy1 = y2 - y1; + initialize: - var dx2 = x4 - x3; - var dy2 = y4 - y3; + function File (loader, fileConfig) + { + /** + * A reference to the Loader that is going to load this file. + * + * @name Phaser.Loader.File#loader + * @type {Phaser.Loader.LoaderPlugin} + * @since 3.0.0 + */ + this.loader = loader; - var denom = dy2 * dx1 - dx2 * dy1; + /** + * A reference to the Cache, or Texture Manager, that is going to store this file if it loads. + * + * @name Phaser.Loader.File#cache + * @type {(Phaser.Cache.BaseCache|Phaser.Textures.TextureManager)} + * @since 3.7.0 + */ + this.cache = GetFastValue(fileConfig, 'cache', false); - // 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). + /** + * The file type string (image, json, etc) for sorting within the Loader. + * + * @name Phaser.Loader.File#type + * @type {string} + * @since 3.0.0 + */ + this.type = GetFastValue(fileConfig, 'type', false); - if (dx1 === 0 || denom === 0) - { - return false; - } + if (!this.type) + { + throw new Error('Invalid File type: ' + this.type); + } - var T2 = (dx1 * (y3 - y1) + dy1 * (x1 - x3)) / (dx2 * dy1 - dy2 * dx1); - var T1 = (x3 + dx2 * T2 - x1) / dx1; + /** + * Unique cache key (unique within its file type) + * + * @name Phaser.Loader.File#key + * @type {string} + * @since 3.0.0 + */ + this.key = GetFastValue(fileConfig, 'key', false); - // Intersects? - if (T1 < 0 || T2 < 0 || T2 > 1) - { - return null; - } + var loadKey = this.key; - if (out === undefined) - { - out = new Vector3(); - } - - return out.set( - x1 + dx1 * T1, - y1 + dy1 * T1, - T1 - ); -}; + if (loader.prefix && loader.prefix !== '') + { + this.key = loader.prefix + loadKey; + } -module.exports = GetLineToLine; + if (!this.key) + { + throw new Error('Invalid File key: ' + this.key); + } + var url = GetFastValue(fileConfig, 'url'); -/***/ }), -/* 486 */ -/***/ (function(module, exports, __webpack_require__) { + if (url === undefined) + { + url = loader.path + loadKey + '.' + GetFastValue(fileConfig, 'extension', ''); + } + else if (typeof url === 'string' && !url.match(/^(?:blob:|data:|capacitor:\/\/|http:\/\/|https:\/\/|\/\/)/)) + { + url = loader.path + url; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The URL of the file, not including baseURL. + * + * Automatically has Loader.path prepended to it if a string. + * + * Can also be a JavaScript Object, such as the results of parsing JSON data. + * + * @name Phaser.Loader.File#url + * @type {object|string} + * @since 3.0.0 + */ + this.url = url; -var Vector3 = __webpack_require__(39); -var GetLineToLine = __webpack_require__(485); -var Line = __webpack_require__(47); + /** + * The final URL this file will load from, including baseURL and path. + * Set automatically when the Loader calls 'load' on this file. + * + * @name Phaser.Loader.File#src + * @type {string} + * @since 3.0.0 + */ + this.src = ''; -// Temp calculation segment -var segment = new Line(); + /** + * The merged XHRSettings for this file. + * + * @name Phaser.Loader.File#xhrSettings + * @type {Phaser.Types.Loader.XHRSettingsObject} + * @since 3.0.0 + */ + this.xhrSettings = XHRSettings(GetFastValue(fileConfig, 'responseType', undefined)); -// Temp vec3 -var tempIntersect = new Vector3(); + if (GetFastValue(fileConfig, 'xhrSettings', false)) + { + this.xhrSettings = MergeXHRSettings(this.xhrSettings, GetFastValue(fileConfig, 'xhrSettings', {})); + } -/** - * 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(); } + /** + * The XMLHttpRequest instance (as created by XHR Loader) that is loading this File. + * + * @name Phaser.Loader.File#xhrLoader + * @type {?XMLHttpRequest} + * @since 3.0.0 + */ + this.xhrLoader = null; - var closestIntersect = false; + /** + * The current state of the file. One of the FILE_CONST values. + * + * @name Phaser.Loader.File#state + * @type {number} + * @since 3.0.0 + */ + this.state = (typeof(this.url) === 'function') ? CONST.FILE_POPULATED : CONST.FILE_PENDING; - // Reset our vec3s - out.set(); - tempIntersect.set(); + /** + * The total size of this file. + * Set by onProgress and only if loading via XHR. + * + * @name Phaser.Loader.File#bytesTotal + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.bytesTotal = 0; - var prev = points[0]; + /** + * Updated as the file loads. + * Only set if loading via XHR. + * + * @name Phaser.Loader.File#bytesLoaded + * @type {number} + * @default -1 + * @since 3.0.0 + */ + this.bytesLoaded = -1; - for (var i = 1; i < points.length; i++) - { - var current = points[i]; + /** + * A percentage value between 0 and 1 indicating how much of this file has loaded. + * Only set if loading via XHR. + * + * @name Phaser.Loader.File#percentComplete + * @type {number} + * @default -1 + * @since 3.0.0 + */ + this.percentComplete = -1; - segment.setTo(prev.x, prev.y, current.x, current.y); + /** + * For CORs based loading. + * If this is undefined then the File will check BaseLoader.crossOrigin and use that (if set) + * + * @name Phaser.Loader.File#crossOrigin + * @type {(string|undefined)} + * @since 3.0.0 + */ + this.crossOrigin = undefined; - prev = current; + /** + * The processed file data, stored here after the file has loaded. + * + * @name Phaser.Loader.File#data + * @type {*} + * @since 3.0.0 + */ + this.data = undefined; - if (GetLineToLine(line, segment, tempIntersect)) - { - if (!closestIntersect || tempIntersect.z < out.z) - { - out.copy(tempIntersect); + /** + * A config object that can be used by file types to store transitional data. + * + * @name Phaser.Loader.File#config + * @type {*} + * @since 3.0.0 + */ + this.config = GetFastValue(fileConfig, 'config', {}); - closestIntersect = true; - } - } - } + /** + * If this is a multipart file, i.e. an atlas and its json together, then this is a reference + * to the parent MultiFile. Set and used internally by the Loader or specific file types. + * + * @name Phaser.Loader.File#multiFile + * @type {?Phaser.Loader.MultiFile} + * @since 3.7.0 + */ + this.multiFile; - return (closestIntersect) ? out : null; -}; + /** + * Does this file have an associated linked file? Such as an image and a normal map. + * Atlases and Bitmap Fonts use the multiFile, because those files need loading together but aren't + * actually bound by data, where-as a linkFile is. + * + * @name Phaser.Loader.File#linkFile + * @type {?Phaser.Loader.File} + * @since 3.7.0 + */ + this.linkFile; + }, -module.exports = GetLineToPoints; + /** + * Links this File with another, so they depend upon each other for loading and processing. + * + * @method Phaser.Loader.File#setLink + * @since 3.7.0 + * + * @param {Phaser.Loader.File} fileB - The file to link to this one. + */ + setLink: function (fileB) + { + this.linkFile = fileB; + fileB.linkFile = this; + }, -/***/ }), -/* 487 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Resets the XHRLoader instance this file is using. + * + * @method Phaser.Loader.File#resetXHR + * @since 3.0.0 + */ + resetXHR: function () + { + if (this.xhrLoader) + { + this.xhrLoader.onload = undefined; + this.xhrLoader.onerror = undefined; + this.xhrLoader.onprogress = undefined; + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Called by the Loader, starts the actual file downloading. + * During the load the methods onLoad, onError and onProgress are called, based on the XHR events. + * You shouldn't normally call this method directly, it's meant to be invoked by the Loader. + * + * @method Phaser.Loader.File#load + * @since 3.0.0 + */ + load: function () + { + if (this.state === CONST.FILE_POPULATED) + { + // Can happen for example in a JSONFile if they've provided a JSON object instead of a URL + this.loader.nextFile(this, true); + } + else + { + this.state = CONST.FILE_LOADING; -var Vector3 = __webpack_require__(39); -var Vector4 = __webpack_require__(140); -var GetLineToPoints = __webpack_require__(486); + this.src = GetURL(this, this.loader.baseURL); -// Temp vec3 -var tempIntersect = new Vector3(); + if (this.src.indexOf('data:') === 0) + { + console.warn('Local data URIs are not supported: ' + this.key); + } + else + { + // The creation of this XHRLoader starts the load process going. + // It will automatically call the following, based on the load outcome: + // + // xhr.onload = this.onLoad + // xhr.onerror = this.onError + // xhr.onprogress = this.onProgress -/** - * 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(); } + this.xhrLoader = XHRLoader(this, this.loader.xhr); + } + } + }, - if (!Array.isArray(polygons)) + /** + * Called when the file finishes loading, is sent a DOM ProgressEvent. + * + * @method Phaser.Loader.File#onLoad + * @since 3.0.0 + * + * @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event. + * @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this load. + */ + onLoad: function (xhr, event) { - polygons = [ polygons ]; - } + var isLocalFile = xhr.responseURL && this.loader.localSchemes.some(function (scheme) + { + return xhr.responseURL.indexOf(scheme) === 0; + }); - var closestIntersect = false; + var localFileOk = (isLocalFile && event.target.status === 0); - // Reset our vec4s - out.set(); - tempIntersect.set(); + var success = !(event.target && event.target.status !== 200) || localFileOk; - for (var i = 0; i < polygons.length; i++) - { - if (GetLineToPoints(line, polygons[i].points, tempIntersect)) + // Handle HTTP status codes of 4xx and 5xx as errors, even if xhr.onerror was not called. + if (xhr.readyState === 4 && xhr.status >= 400 && xhr.status <= 599) { - if (!closestIntersect || tempIntersect.z < out.z) - { - out.set(tempIntersect.x, tempIntersect.y, tempIntersect.z, i); - - closestIntersect = true; - } + success = false; } - } - - return (closestIntersect) ? out : null; -}; - -module.exports = GetLineToPolygon; + this.state = CONST.FILE_LOADED; -/***/ }), -/* 488 */ -/***/ (function(module, exports) { + this.resetXHR(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.loader.nextFile(this, success); + }, -/** - * 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; + /** + * Called if the file errors while loading, is sent a DOM ProgressEvent. + * + * @method Phaser.Loader.File#onError + * @since 3.0.0 + * + * @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event. + * @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this error. + */ + onError: function () + { + this.resetXHR(); - var x2 = line.x2; - var y2 = line.y2; + this.loader.nextFile(this, false); + }, - var bx1 = rect.x; - var by1 = rect.y; - var bx2 = rect.right; - var by2 = rect.bottom; + /** + * Called during the file load progress. Is sent a DOM ProgressEvent. + * + * @method Phaser.Loader.File#onProgress + * @fires Phaser.Loader.Events#FILE_PROGRESS + * @since 3.0.0 + * + * @param {ProgressEvent} event - The DOM ProgressEvent. + */ + onProgress: function (event) + { + if (event.lengthComputable) + { + this.bytesLoaded = event.loaded; + this.bytesTotal = event.total; - var t = 0; + this.percentComplete = Math.min((this.bytesLoaded / this.bytesTotal), 1); - // If the start or end of the line is inside the rect then we assume - // collision, as rects are solid for our use-case. + this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete); + } + }, - if ((x1 >= bx1 && x1 <= bx2 && y1 >= by1 && y1 <= by2) || - (x2 >= bx1 && x2 <= bx2 && y2 >= by1 && y2 <= by2)) + /** + * Usually overridden by the FileTypes and is called by Loader.nextFile. + * This method controls what extra work this File does with its loaded data, for example a JSON file will parse itself during this stage. + * + * @method Phaser.Loader.File#onProcess + * @since 3.0.0 + */ + onProcess: function () { - return true; - } + this.state = CONST.FILE_PROCESSING; - if (x1 < bx1 && x2 >= bx1) + this.onProcessComplete(); + }, + + /** + * Called when the File has completed processing. + * Checks on the state of its multifile, if set. + * + * @method Phaser.Loader.File#onProcessComplete + * @since 3.7.0 + */ + onProcessComplete: function () { - // Left edge - t = y1 + (y2 - y1) * (bx1 - x1) / (x2 - x1); + this.state = CONST.FILE_COMPLETE; - if (t > by1 && t <= by2) + if (this.multiFile) { - return true; + this.multiFile.onFileComplete(this); } - } - else if (x1 > bx2 && x2 <= bx2) + + this.loader.fileProcessComplete(this); + }, + + /** + * Called when the File has completed processing but it generated an error. + * Checks on the state of its multifile, if set. + * + * @method Phaser.Loader.File#onProcessError + * @since 3.7.0 + */ + onProcessError: function () { - // Right edge - t = y1 + (y2 - y1) * (bx2 - x1) / (x2 - x1); + // eslint-disable-next-line no-console + console.error('Failed to process file: %s "%s"', this.type, this.key); - if (t >= by1 && t <= by2) + this.state = CONST.FILE_ERRORED; + + if (this.multiFile) { - return true; + this.multiFile.onFileFailed(this); } - } - if (y1 < by1 && y2 >= by1) + this.loader.fileProcessComplete(this); + }, + + /** + * Checks if a key matching the one used by this file exists in the target Cache or not. + * This is called automatically by the LoaderPlugin to decide if the file can be safely + * loaded or will conflict. + * + * @method Phaser.Loader.File#hasCacheConflict + * @since 3.7.0 + * + * @return {boolean} `true` if adding this file will cause a conflict, otherwise `false`. + */ + hasCacheConflict: function () { - // Top edge - t = x1 + (x2 - x1) * (by1 - y1) / (y2 - y1); + return (this.cache && this.cache.exists(this.key)); + }, - if (t >= bx1 && t <= bx2) + /** + * Adds this file to its target cache upon successful loading and processing. + * This method is often overridden by specific file types. + * + * @method Phaser.Loader.File#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + if (this.cache && this.data) { - return true; + this.cache.add(this.key, this.data); } - } - else if (y1 > by2 && y2 <= by2) - { - // Bottom edge - t = x1 + (x2 - x1) * (by2 - y1) / (y2 - y1); + }, - if (t >= bx1 && t <= bx2) + /** + * Called once the file has been added to its cache and is now ready for deletion from the Loader. + * It will emit a `filecomplete` event from the LoaderPlugin. + * + * @method Phaser.Loader.File#pendingDestroy + * @fires Phaser.Loader.Events#FILE_COMPLETE + * @fires Phaser.Loader.Events#FILE_KEY_COMPLETE + * @since 3.7.0 + */ + pendingDestroy: function (data) + { + if (this.state === CONST.FILE_PENDING_DESTROY) { - return true; + return; } - } - return false; -}; + if (data === undefined) { data = this.data; } -module.exports = LineToRectangle; + var key = this.key; + var type = this.type; + this.loader.emit(Events.FILE_COMPLETE, key, type, data); + this.loader.emit(Events.FILE_KEY_COMPLETE + type + '-' + key, key, type, data); -/***/ }), -/* 489 */ -/***/ (function(module, exports, __webpack_require__) { + this.loader.flagForRemoval(this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.state = CONST.FILE_PENDING_DESTROY; + }, + + /** + * Destroy this File and any references it holds. + * + * @method Phaser.Loader.File#destroy + * @since 3.7.0 + */ + destroy: function () + { + this.loader = null; + this.cache = null; + this.xhrSettings = null; + this.multiFile = null; + this.linkFile = null; + this.data = null; + } -var LineToLine = __webpack_require__(96); -var Contains = __webpack_require__(57); -var ContainsArray = __webpack_require__(235); -var Decompose = __webpack_require__(490); +}); /** - * Checks for intersection between Rectangle shape and Triangle shape. - * - * @function Phaser.Geom.Intersects.RectangleToTriangle - * @since 3.0.0 + * Static method for creating object URL using URL API and setting it as image 'src' attribute. + * If URL API is not supported (usually on old browsers) it falls back to creating Base64 encoded url using FileReader. * - * @param {Phaser.Geom.Rectangle} rect - Rectangle object to test. - * @param {Phaser.Geom.Triangle} triangle - Triangle object to test. + * @method Phaser.Loader.File.createObjectURL + * @static + * @since 3.7.0 * - * @return {boolean} A value of `true` if objects intersect; otherwise `false`. + * @param {HTMLImageElement} image - Image object which 'src' attribute should be set to object URL. + * @param {Blob} blob - A Blob object to create an object URL for. + * @param {string} defaultType - Default mime type used if blob type is not available. */ -var RectangleToTriangle = function (rect, triangle) +File.createObjectURL = function (image, blob, defaultType) { - // 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)) + if (typeof URL === 'function') { - return true; + image.src = URL.createObjectURL(blob); } - - if (Contains(rect, triC.x1, triC.y1) || Contains(rect, triC.x2, triC.y2)) + else { - 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(); + var reader = new FileReader(); - if (LineToLine(triA, rectA) || LineToLine(triA, rectB) || LineToLine(triA, rectC) || LineToLine(triA, rectD)) - { - return true; - } + reader.onload = function () + { + image.removeAttribute('crossOrigin'); + image.src = 'data:' + (blob.type || defaultType) + ';base64,' + reader.result.split(',')[1]; + }; - if (LineToLine(triB, rectA) || LineToLine(triB, rectB) || LineToLine(triB, rectC) || LineToLine(triB, rectD)) - { - return true; - } + reader.onerror = image.onerror; - if (LineToLine(triC, rectA) || LineToLine(triC, rectB) || LineToLine(triC, rectC) || LineToLine(triC, rectD)) - { - return true; + reader.readAsDataURL(blob); } - - // 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; - - -/***/ }), -/* 490 */ -/***/ (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 + * Static method for releasing an existing object URL which was previously created + * by calling {@link File#createObjectURL} method. * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle object to be decomposed. - * @param {array} [out] - If provided, each point will be added to this array. + * @method Phaser.Loader.File.revokeObjectURL + * @static + * @since 3.7.0 * - * @return {array} Will return the array you specified or a new array containing the points of the Rectangle. + * @param {HTMLImageElement} image - Image object which 'src' attribute should be revoked. */ -var Decompose = function (rect, out) +File.revokeObjectURL = function (image) { - 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; + if (typeof URL === 'function') + { + URL.revokeObjectURL(image.src); + } }; -module.exports = Decompose; +module.exports = File; /***/ }), -/* 491 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 76846: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var LineToCircle = __webpack_require__(233); -var Contains = __webpack_require__(115); +var types = {}; /** - * 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`. + * @namespace Phaser.Loader.FileTypesManager */ -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; - } +var FileTypesManager = { - if (LineToCircle(triangle.getLineA(), circle)) + /** + * Static method called when a LoaderPlugin is created. + * + * Loops through the local types object and injects all of them as + * properties into the LoaderPlugin instance. + * + * @method Phaser.Loader.FileTypesManager.install + * @since 3.0.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - The LoaderPlugin to install the types into. + */ + install: function (loader) { - return true; - } + for (var key in types) + { + loader[key] = types[key]; + } + }, - if (LineToCircle(triangle.getLineB(), circle)) + /** + * Static method called directly by the File Types. + * + * The key is a reference to the function used to load the files via the Loader, i.e. `image`. + * + * @method Phaser.Loader.FileTypesManager.register + * @since 3.0.0 + * + * @param {string} key - The key that will be used as the method name in the LoaderPlugin. + * @param {function} factoryFunction - The function that will be called when LoaderPlugin.key is invoked. + */ + register: function (key, factoryFunction) { - return true; - } + types[key] = factoryFunction; + }, - if (LineToCircle(triangle.getLineC(), circle)) + /** + * Removed all associated file types. + * + * @method Phaser.Loader.FileTypesManager.destroy + * @since 3.0.0 + */ + destroy: function () { - return true; + types = {}; } - return false; }; -module.exports = TriangleToCircle; +module.exports = FileTypesManager; /***/ }), -/* 492 */ -/***/ (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__(493); -var LineToLine = __webpack_require__(96); - -/** - * 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; - - -/***/ }), -/* 493 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 30750: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var LineToLine = __webpack_require__(96); - /** - * 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". + * Given a File and a baseURL value this returns the URL the File will use to download from. * - * @function Phaser.Geom.Intersects.TriangleToLine + * @function Phaser.Loader.GetURL * @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 {Phaser.Loader.File} file - The File object. + * @param {string} baseURL - A default base URL. * - * @return {boolean} `true` if the Triangle and the Line intersect, otherwise `false`. + * @return {string} The URL the File will use. */ -var TriangleToLine = function (triangle, line) +var GetURL = function (file, baseURL) { - // 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)) + if (!file.url) { - return true; + return false; } - if (LineToLine(triangle.getLineB(), line)) + if (file.url.match(/^(?:blob:|data:|capacitor:\/\/|http:\/\/|https:\/\/|\/\/)/)) { - return true; + return file.url; } - - if (LineToLine(triangle.getLineC(), line)) + else { - return true; + return baseURL + file.url; } - - return false; }; -module.exports = TriangleToLine; +module.exports = GetURL; /***/ }), -/* 494 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 67285: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ContainsArray = __webpack_require__(235); -var Decompose = __webpack_require__(495); -var LineToLine = __webpack_require__(96); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var CustomSet = __webpack_require__(58403); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(683); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var GetValue = __webpack_require__(10850); +var PluginCache = __webpack_require__(91963); +var SceneEvents = __webpack_require__(7599); +var XHRSettings = __webpack_require__(33868); /** - * Checks if two Triangles intersect. + * @classdesc + * The Loader handles loading all external content such as Images, Sounds, Texture Atlases and data files. + * You typically interact with it via `this.load` in your Scene. Scenes can have a `preload` method, which is always + * called before the Scenes `create` method, allowing you to preload assets that the Scene may need. * - * 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". + * If you call any `this.load` methods from outside of `Scene.preload` then you need to start the Loader going + * yourself by calling `Loader.start()`. It's only automatically started during the Scene preload. * - * @function Phaser.Geom.Intersects.TriangleToTriangle - * @since 3.0.0 + * The Loader uses a combination of tag loading (eg. Audio elements) and XHR and provides progress and completion events. + * Files are loaded in parallel by default. The amount of concurrent connections can be controlled in your Game Configuration. * - * @param {Phaser.Geom.Triangle} triangleA - The first Triangle to check for intersection. - * @param {Phaser.Geom.Triangle} triangleB - The second Triangle to check for intersection. + * Once the Loader has started loading you are still able to add files to it. These can be injected as a result of a loader + * event, the type of file being loaded (such as a pack file) or other external events. As long as the Loader hasn't finished + * simply adding a new file to it, while running, will ensure it's added into the current queue. * - * @return {boolean} `true` if the Triangles intersect, otherwise `false`. + * Every Scene has its own instance of the Loader and they are bound to the Scene in which they are created. However, + * assets loaded by the Loader are placed into global game-level caches. For example, loading an XML file will place that + * file inside `Game.cache.xml`, which is accessible from every Scene in your game, no matter who was responsible + * for loading it. The same is true of Textures. A texture loaded in one Scene is instantly available to all other Scenes + * in your game. + * + * The Loader works by using custom File Types. These are stored in the FileTypesManager, which injects them into the Loader + * when it's instantiated. You can create your own custom file types by extending either the File or MultiFile classes. + * See those files for more details. + * + * @class LoaderPlugin + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Loader + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene which owns this Loader instance. */ -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 LoaderPlugin = new Class({ - var lineAA = triangleA.getLineA(); - var lineAB = triangleA.getLineB(); - var lineAC = triangleA.getLineC(); + Extends: EventEmitter, - var lineBA = triangleB.getLineA(); - var lineBB = triangleB.getLineB(); - var lineBC = triangleB.getLineC(); + initialize: - // Now check the lines against each line of TriangleB - if (LineToLine(lineAA, lineBA) || LineToLine(lineAA, lineBB) || LineToLine(lineAA, lineBC)) + function LoaderPlugin (scene) { - return true; - } + EventEmitter.call(this); - if (LineToLine(lineAB, lineBA) || LineToLine(lineAB, lineBB) || LineToLine(lineAB, lineBC)) - { - return true; - } + var gameConfig = scene.sys.game.config; + var sceneConfig = scene.sys.settings.loader; - if (LineToLine(lineAC, lineBA) || LineToLine(lineAC, lineBB) || LineToLine(lineAC, lineBC)) - { - return true; - } + /** + * The Scene which owns this Loader instance. + * + * @name Phaser.Loader.LoaderPlugin#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - // Nope, so check to see if any of the points of triangleA are within triangleB + /** + * A reference to the Scene Systems. + * + * @name Phaser.Loader.LoaderPlugin#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.systems = scene.sys; - var points = Decompose(triangleA); - var within = ContainsArray(triangleB, points, true); + /** + * A reference to the global Cache Manager. + * + * @name Phaser.Loader.LoaderPlugin#cacheManager + * @type {Phaser.Cache.CacheManager} + * @since 3.7.0 + */ + this.cacheManager = scene.sys.cache; - if (within.length > 0) - { - return true; - } + /** + * A reference to the global Texture Manager. + * + * @name Phaser.Loader.LoaderPlugin#textureManager + * @type {Phaser.Textures.TextureManager} + * @since 3.7.0 + */ + this.textureManager = scene.sys.textures; - // Finally check to see if any of the points of triangleB are within triangleA + /** + * A reference to the global Scene Manager. + * + * @name Phaser.Loader.LoaderPlugin#sceneManager + * @type {Phaser.Scenes.SceneManager} + * @protected + * @since 3.16.0 + */ + this.sceneManager = scene.sys.game.scene; - points = Decompose(triangleB); - within = ContainsArray(triangleA, points, true); + // Inject the available filetypes into the Loader + FileTypesManager.install(this); - if (within.length > 0) - { - return true; - } + /** + * An optional prefix that is automatically prepended to the start of every file key. + * If prefix was `MENU.` and you load an image with the key 'Background' the resulting key would be `MENU.Background`. + * You can set this directly, or call `Loader.setPrefix()`. It will then affect every file added to the Loader + * from that point on. It does _not_ change any file already in the load queue. + * + * @name Phaser.Loader.LoaderPlugin#prefix + * @type {string} + * @default '' + * @since 3.7.0 + */ + this.prefix = ''; - return false; -}; + /** + * The value of `path`, if set, is placed before any _relative_ file path given. For example: + * + * ```javascript + * this.load.path = "images/sprites/"; + * this.load.image("ball", "ball.png"); + * this.load.image("tree", "level1/oaktree.png"); + * this.load.image("boom", "http://server.com/explode.png"); + * ``` + * + * Would load the `ball` file from `images/sprites/ball.png` and the tree from + * `images/sprites/level1/oaktree.png` but the file `boom` would load from the URL + * given as it's an absolute URL. + * + * Please note that the path is added before the filename but *after* the baseURL (if set.) + * + * If you set this property directly then it _must_ end with a "/". Alternatively, call `setPath()` and it'll do it for you. + * + * @name Phaser.Loader.LoaderPlugin#path + * @type {string} + * @default '' + * @since 3.0.0 + */ + this.path = ''; -module.exports = TriangleToTriangle; + /** + * If you want to append a URL before the path of any asset you can set this here. + * + * Useful if allowing the asset base url to be configured outside of the game code. + * + * If you set this property directly then it _must_ end with a "/". Alternatively, call `setBaseURL()` and it'll do it for you. + * + * @name Phaser.Loader.LoaderPlugin#baseURL + * @type {string} + * @default '' + * @since 3.0.0 + */ + this.baseURL = ''; + this.setBaseURL(GetFastValue(sceneConfig, 'baseURL', gameConfig.loaderBaseURL)); -/***/ }), -/* 495 */ -/***/ (function(module, exports) { + this.setPath(GetFastValue(sceneConfig, 'path', gameConfig.loaderPath)); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.setPrefix(GetFastValue(sceneConfig, 'prefix', gameConfig.loaderPrefix)); -/** - * 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 = []; } + /** + * The number of concurrent / parallel resources to try and fetch at once. + * + * Old browsers limit 6 requests per domain; modern ones, especially those with HTTP/2 don't limit it at all. + * + * The default is 32 but you can change this in your Game Config, or by changing this property before the Loader starts. + * + * @name Phaser.Loader.LoaderPlugin#maxParallelDownloads + * @type {number} + * @since 3.0.0 + */ + this.maxParallelDownloads = GetFastValue(sceneConfig, 'maxParallelDownloads', gameConfig.loaderMaxParallelDownloads); - out.push({ x: triangle.x1, y: triangle.y1 }); - out.push({ x: triangle.x2, y: triangle.y2 }); - out.push({ x: triangle.x3, y: triangle.y3 }); + /** + * xhr specific global settings (can be overridden on a per-file basis) + * + * @name Phaser.Loader.LoaderPlugin#xhr + * @type {Phaser.Types.Loader.XHRSettingsObject} + * @since 3.0.0 + */ + this.xhr = XHRSettings( + GetFastValue(sceneConfig, 'responseType', gameConfig.loaderResponseType), + GetFastValue(sceneConfig, 'async', gameConfig.loaderAsync), + GetFastValue(sceneConfig, 'user', gameConfig.loaderUser), + GetFastValue(sceneConfig, 'password', gameConfig.loaderPassword), + GetFastValue(sceneConfig, 'timeout', gameConfig.loaderTimeout), + GetFastValue(sceneConfig, 'withCredentials', gameConfig.loaderWithCredentials) + ); - return out; -}; + /** + * The crossOrigin value applied to loaded images. Very often this needs to be set to 'anonymous'. + * + * @name Phaser.Loader.LoaderPlugin#crossOrigin + * @type {string} + * @since 3.0.0 + */ + this.crossOrigin = GetFastValue(sceneConfig, 'crossOrigin', gameConfig.loaderCrossOrigin); -module.exports = Decompose; + /** + * Optional load type for image files. `XHR` is the default. Set to `HTMLImageElement` to load images using the Image tag instead. + * + * @name Phaser.Loader.LoaderPlugin#imageLoadType + * @type {string} + * @since 3.60.0 + */ + this.imageLoadType = GetFastValue(sceneConfig, 'imageLoadType', gameConfig.loaderImageLoadType); + /** + * An array of all schemes that the Loader considers as being 'local'. + * + * This is populated by the `Phaser.Core.Config#loaderLocalScheme` game configuration setting and defaults to + * `[ 'file://', 'capacitor://' ]`. Additional local schemes can be added to this array as needed. + * + * @name Phaser.Loader.LoaderPlugin#localSchemes + * @type {string[]} + * @since 3.60.0 + */ + this.localSchemes = GetFastValue(sceneConfig, 'localScheme', gameConfig.loaderLocalScheme); -/***/ }), -/* 496 */ -/***/ (function(module, exports) { + /** + * The total number of files to load. It may not always be accurate because you may add to the Loader during the process + * of loading, especially if you load a Pack File. Therefore this value can change, but in most cases remains static. + * + * @name Phaser.Loader.LoaderPlugin#totalToLoad + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.totalToLoad = 0; -/** - * @author Richard Davey - * @author Florian Mertens - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The progress of the current load queue, as a float value between 0 and 1. + * This is updated automatically as files complete loading. + * Note that it is possible for this value to go down again if you add content to the current load queue during a load. + * + * @name Phaser.Loader.LoaderPlugin#progress + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.progress = 0; -/** - * 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; } + /** + * Files are placed in this Set when they're added to the Loader via `addFile`. + * + * They are moved to the `inflight` Set when they start loading, and assuming a successful + * load, to the `queue` Set for further processing. + * + * By the end of the load process this Set will be empty. + * + * @name Phaser.Loader.LoaderPlugin#list + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.list = new CustomSet(); - var x1 = line.x1; - var y1 = line.y1; + /** + * Files are stored in this Set while they're in the process of being loaded. + * + * Upon a successful load they are moved to the `queue` Set. + * + * By the end of the load process this Set will be empty. + * + * @name Phaser.Loader.LoaderPlugin#inflight + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.inflight = new CustomSet(); - var x2 = line.x2; - var y2 = line.y2; + /** + * Files are stored in this Set while they're being processed. + * + * If the process is successful they are moved to their final destination, which could be + * a Cache or the Texture Manager. + * + * At the end of the load process this Set will be empty. + * + * @name Phaser.Loader.LoaderPlugin#queue + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.queue = new CustomSet(); - var px = point.x; - var py = point.y; + /** + * A temporary Set in which files are stored after processing, + * awaiting destruction at the end of the load process. + * + * @name Phaser.Loader.LoaderPlugin#_deleteQueue + * @type {Phaser.Structs.Set.} + * @private + * @since 3.7.0 + */ + this._deleteQueue = new CustomSet(); - var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); + /** + * The total number of files that failed to load during the most recent load. + * This value is reset when you call `Loader.start`. + * + * @name Phaser.Loader.LoaderPlugin#totalFailed + * @type {number} + * @default 0 + * @since 3.7.0 + */ + this.totalFailed = 0; - if (L2 === 0) - { - return false; - } + /** + * The total number of files that successfully loaded during the most recent load. + * This value is reset when you call `Loader.start`. + * + * @name Phaser.Loader.LoaderPlugin#totalComplete + * @type {number} + * @default 0 + * @since 3.7.0 + */ + this.totalComplete = 0; - var r = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1))) / L2; + /** + * The current state of the Loader. + * + * @name Phaser.Loader.LoaderPlugin#state + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.state = CONST.LOADER_IDLE; - // Assume line thickness is circular - if (r < 0) + /** + * The current index being used by multi-file loaders to avoid key clashes. + * + * @name Phaser.Loader.LoaderPlugin#multiKeyIndex + * @type {number} + * @private + * @since 3.20.0 + */ + this.multiKeyIndex = 0; + + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + scene.sys.events.on(SceneEvents.START, this.pluginStart, this); + }, + + /** + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. + * + * @method Phaser.Loader.LoaderPlugin#boot + * @private + * @since 3.5.1 + */ + boot: function () { - // Outside line1 - return (Math.sqrt(((x1 - px) * (x1 - px)) + ((y1 - py) * (y1 - py))) <= lineThickness); - } - else if ((r >= 0) && (r <= 1)) + this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); + }, + + /** + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. + * + * @method Phaser.Loader.LoaderPlugin#pluginStart + * @private + * @since 3.5.1 + */ + pluginStart: function () { - // On the line segment - var s = (((y1 - py) * (x2 - x1)) - ((x1 - px) * (y2 - y1))) / L2; + this.systems.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); + }, - return (Math.abs(s) * Math.sqrt(L2) <= lineThickness); - } - else + /** + * If you want to append a URL before the path of any asset you can set this here. + * + * Useful if allowing the asset base url to be configured outside of the game code. + * + * Once a base URL is set it will affect every file loaded by the Loader from that point on. It does _not_ change any + * file _already_ being loaded. To reset it, call this method with no arguments. + * + * @method Phaser.Loader.LoaderPlugin#setBaseURL + * @since 3.0.0 + * + * @param {string} [url] - The URL to use. Leave empty to reset. + * + * @return {this} This Loader object. + */ + setBaseURL: function (url) { - // Outside line2 - return (Math.sqrt(((x2 - px) * (x2 - px)) + ((y2 - py) * (y2 - py))) <= lineThickness); - } -}; + if (url === undefined) { url = ''; } -module.exports = PointToLine; + if (url !== '' && url.substr(-1) !== '/') + { + url = url.concat('/'); + } + this.baseURL = url; -/***/ }), -/* 497 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The value of `path`, if set, is placed before any _relative_ file path given. For example: + * + * ```javascript + * this.load.setPath("images/sprites/"); + * this.load.image("ball", "ball.png"); + * this.load.image("tree", "level1/oaktree.png"); + * this.load.image("boom", "http://server.com/explode.png"); + * ``` + * + * Would load the `ball` file from `images/sprites/ball.png` and the tree from + * `images/sprites/level1/oaktree.png` but the file `boom` would load from the URL + * given as it's an absolute URL. + * + * Please note that the path is added before the filename but *after* the baseURL (if set.) + * + * Once a path is set it will then affect every file added to the Loader from that point on. It does _not_ change any + * file _already_ in the load queue. To reset it, call this method with no arguments. + * + * @method Phaser.Loader.LoaderPlugin#setPath + * @since 3.0.0 + * + * @param {string} [path] - The path to use. Leave empty to reset. + * + * @return {this} This Loader object. + */ + setPath: function (path) + { + if (path === undefined) { path = ''; } -var MATH_CONST = __webpack_require__(14); -var Wrap = __webpack_require__(68); -var Angle = __webpack_require__(97); + if (path !== '' && path.substr(-1) !== '/') + { + path = path.concat('/'); + } -/** - * 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; + this.path = path; - return Wrap(angle, -Math.PI, Math.PI); -}; + return this; + }, -module.exports = NormalAngle; + /** + * An optional prefix that is automatically prepended to the start of every file key. + * + * If prefix was `MENU.` and you load an image with the key 'Background' the resulting key would be `MENU.Background`. + * + * Once a prefix is set it will then affect every file added to the Loader from that point on. It does _not_ change any + * file _already_ in the load queue. To reset it, call this method with no arguments. + * + * @method Phaser.Loader.LoaderPlugin#setPrefix + * @since 3.7.0 + * + * @param {string} [prefix] - The prefix to use. Leave empty to reset. + * + * @return {this} This Loader object. + */ + setPrefix: function (prefix) + { + if (prefix === undefined) { prefix = ''; } + this.prefix = prefix; -/***/ }), -/* 498 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Sets the Cross Origin Resource Sharing value used when loading files. + * + * Files can override this value on a per-file basis by specifying an alternative `crossOrigin` value in their file config. + * + * Once CORs is set it will then affect every file loaded by the Loader from that point on, as long as they don't have + * their own CORs setting. To reset it, call this method with no arguments. + * + * For more details about CORs see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS + * + * @method Phaser.Loader.LoaderPlugin#setCORS + * @since 3.0.0 + * + * @param {string} [crossOrigin] - The value to use for the `crossOrigin` property in the load request. + * + * @return {this} This Loader object. + */ + setCORS: function (crossOrigin) + { + this.crossOrigin = crossOrigin; -var flip = true; + return this; + }, -var defaultModelName = 'untitled'; -var currentGroup = ''; -var currentMaterial = ''; + /** + * Adds a file, or array of files, into the load queue. + * + * The file must be an instance of `Phaser.Loader.File`, or a class that extends it. The Loader will check that the key + * used by the file won't conflict with any other key either in the loader, the inflight queue or the target cache. + * If allowed it will then add the file into the pending list, read for the load to start. Or, if the load has already + * started, ready for the next batch of files to be pulled from the list to the inflight queue. + * + * You should not normally call this method directly, but rather use one of the Loader methods like `image` or `atlas`, + * however you can call this as long as the file given to it is well formed. + * + * @method Phaser.Loader.LoaderPlugin#addFile + * @fires Phaser.Loader.Events#ADD + * @since 3.0.0 + * + * @param {(Phaser.Loader.File|Phaser.Loader.File[])} file - The file, or array of files, to be added to the load queue. + */ + addFile: function (file) + { + if (!Array.isArray(file)) + { + file = [ file ]; + } -/** - * @ignore - */ -function stripComments (line) -{ - var idx = line.indexOf('#'); + for (var i = 0; i < file.length; i++) + { + var item = file[i]; - return (idx > -1) ? line.substring(0, idx) : line; -} + // Does the file already exist in the cache or texture manager? + // Or will it conflict with a file already in the queue or inflight? + if (!this.keyExists(item)) + { + this.list.set(item); -/** - * @ignore - */ -function currentModel (result) -{ - if (result.models.length === 0) - { - result.models.push({ - faces: [], - name: defaultModelName, - textureCoords: [], - vertexNormals: [], - vertices: [] - }); - } + this.emit(Events.ADD, item.key, item.type, this, item); - currentGroup = ''; + if (this.isLoading()) + { + this.totalToLoad++; + this.updateProgress(); + } + } + } + }, - return result.models[result.models.length - 1]; -} + /** + * Checks the key and type of the given file to see if it will conflict with anything already + * in a Cache, the Texture Manager, or the list or inflight queues. + * + * @method Phaser.Loader.LoaderPlugin#keyExists + * @since 3.7.0 + * + * @param {Phaser.Loader.File} file - The file to check the key of. + * + * @return {boolean} `true` if adding this file will cause a cache or queue conflict, otherwise `false`. + */ + keyExists: function (file) + { + var keyConflict = file.hasCacheConflict(); -/** - * @ignore - */ -function parseObject (lineItems, result) -{ - var modelName = lineItems.length >= 2 ? lineItems[1] : defaultModelName; + if (!keyConflict) + { + this.list.iterate(function (item) + { + if (item.type === file.type && item.key === file.key) + { + keyConflict = true; - result.models.push({ - faces: [], - name: modelName, - textureCoords: [], - vertexNormals: [], - vertices: [] - }); + return false; + } - currentGroup = ''; -} + }); + } -/** - * @ignore - */ -function parseGroup (lineItems) -{ - if (lineItems.length === 2) - { - currentGroup = lineItems[1]; - } -} + if (!keyConflict && this.isLoading()) + { + this.inflight.iterate(function (item) + { + if (item.type === file.type && item.key === file.key) + { + keyConflict = true; -/** - * @ignore - */ -function parseVertexCoords (lineItems, result) -{ - var len = lineItems.length; + return false; + } - 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 }); -} + this.queue.iterate(function (item) + { + if (item.type === file.type && item.key === file.key) + { + keyConflict = true; -/** - * @ignore - */ -function parseTextureCoords (lineItems, result) -{ - var len = lineItems.length; + return false; + } - 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; - } + return keyConflict; + }, - if (isNaN(v)) + /** + * Takes a well formed, fully parsed pack file object and adds its entries into the load queue. Usually you do not call + * this method directly, but instead use `Loader.pack` and supply a path to a JSON file that holds the + * pack data. However, if you've got the data prepared you can pass it to this method. + * + * You can also provide an optional key. If you do then it will only add the entries from that part of the pack into + * to the load queue. If not specified it will add all entries it finds. For more details about the pack file format + * see the `LoaderPlugin.pack` method. + * + * @method Phaser.Loader.LoaderPlugin#addPack + * @since 3.7.0 + * + * @param {any} pack - The Pack File data to be parsed and each entry of it to added to the load queue. + * @param {string} [packKey] - An optional key to use from the pack file data. + * + * @return {boolean} `true` if any files were added to the queue, otherwise `false`. + */ + addPack: function (pack, packKey) { - v = 0; - } + // if no packKey provided we'll add everything to the queue + if (typeof(packKey) === 'string') + { + var subPack = GetValue(pack, packKey); - if (isNaN(w)) - { - w = 0; - } + if (subPack) + { + pack = { packKey: subPack }; + } + } - if (flip) - { - v = 1 - v; - } + var total = 0; - currentModel(result).textureCoords.push({ u: u, v: v, w: w }); -} + // Store the loader settings in case this pack replaces them + var currentBaseURL = this.baseURL; + var currentPath = this.path; + var currentPrefix = this.prefix; -/** - * @ignore - */ -function parseVertexNormal (lineItems, result) -{ - var len = lineItems.length; + // Here we go ... + for (var key in pack) + { + if (!Object.prototype.hasOwnProperty.call(pack, key)) + { + continue; + } - var x = (len >= 2) ? parseFloat(lineItems[1]) : 0; - var y = (len >= 3) ? parseFloat(lineItems[2]) : 0; - var z = (len >= 4) ? parseFloat(lineItems[3]) : 0; + var config = pack[key]; - currentModel(result).vertexNormals.push({ x: x, y: y, z: z }); -} + // Any meta data to process? + var baseURL = GetFastValue(config, 'baseURL', currentBaseURL); + var path = GetFastValue(config, 'path', currentPath); + var prefix = GetFastValue(config, 'prefix', currentPrefix); + var files = GetFastValue(config, 'files', null); + var defaultType = GetFastValue(config, 'defaultType', 'void'); -/** - * @ignore - */ -function parsePolygon (lineItems, result) -{ - var totalVertices = lineItems.length - 1; + if (Array.isArray(files)) + { + this.setBaseURL(baseURL); + this.setPath(path); + this.setPrefix(prefix); - if (totalVertices < 3) - { - return; - } + for (var i = 0; i < files.length; i++) + { + var file = files[i]; + var type = (file.hasOwnProperty('type')) ? file.type : defaultType; - var face = { - group: currentGroup, - material: currentMaterial, - vertices: [] - }; + if (this[type]) + { + this[type](file); + total++; + } + } + } + } - for (var i = 0; i < totalVertices; i++) + // Reset the loader settings + this.setBaseURL(currentBaseURL); + this.setPath(currentPath); + this.setPrefix(currentPrefix); + + return (total > 0); + }, + + /** + * Is the Loader actively loading, or processing loaded files? + * + * @method Phaser.Loader.LoaderPlugin#isLoading + * @since 3.0.0 + * + * @return {boolean} `true` if the Loader is busy loading or processing, otherwise `false`. + */ + isLoading: function () { - var vertexString = lineItems[i + 1]; - var vertexValues = vertexString.split('/'); - var vvLen = vertexValues.length; + return (this.state === CONST.LOADER_LOADING || this.state === CONST.LOADER_PROCESSING); + }, - if (vvLen < 1 || vvLen > 3) + /** + * Is the Loader ready to start a new load? + * + * @method Phaser.Loader.LoaderPlugin#isReady + * @since 3.0.0 + * + * @return {boolean} `true` if the Loader is ready to start a new load, otherwise `false`. + */ + isReady: function () + { + return (this.state === CONST.LOADER_IDLE || this.state === CONST.LOADER_COMPLETE); + }, + + /** + * Starts the Loader running. This will reset the progress and totals and then emit a `start` event. + * If there is nothing in the queue the Loader will immediately complete, otherwise it will start + * loading the first batch of files. + * + * The Loader is started automatically if the queue is populated within your Scenes `preload` method. + * + * However, outside of this, you need to call this method to start it. + * + * If the Loader is already running this method will simply return. + * + * @method Phaser.Loader.LoaderPlugin#start + * @fires Phaser.Loader.Events#START + * @since 3.0.0 + */ + start: function () + { + if (!this.isReady()) { - continue; + return; } - var vertexIndex = 0; - var textureCoordsIndex = 0; - var vertexNormalIndex = 0; + this.progress = 0; - vertexIndex = parseInt(vertexValues[0], 10); + this.totalFailed = 0; + this.totalComplete = 0; + this.totalToLoad = this.list.size; - if (vvLen > 1 && vertexValues[1] !== '') - { - textureCoordsIndex = parseInt(vertexValues[1], 10); - } + this.emit(Events.START, this); - if (vvLen > 2) + if (this.list.size === 0) { - vertexNormalIndex = parseInt(vertexValues[2], 10); + this.loadComplete(); } - - if (vertexIndex !== 0) + else { - // 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; - } + this.state = CONST.LOADER_LOADING; - textureCoordsIndex -= 1; - vertexIndex -= 1; - vertexNormalIndex -= 1; + this.inflight.clear(); + this.queue.clear(); - face.vertices.push({ - textureCoordsIndex: textureCoordsIndex, - vertexIndex: vertexIndex, - vertexNormalIndex: vertexNormalIndex - }); - } - } + this.updateProgress(); - currentModel(result).faces.push(face); -} + this.checkLoadQueue(); -/** - * @ignore - */ -function parseMtlLib (lineItems, result) -{ - if (lineItems.length >= 2) - { - result.materialLibraries.push(lineItems[1]); - } -} + this.systems.events.on(SceneEvents.UPDATE, this.update, this); + } + }, -/** - * @ignore - */ -function parseUseMtl (lineItems) -{ - if (lineItems.length >= 2) + /** + * Called automatically during the load process. + * It updates the `progress` value and then emits a progress event, which you can use to + * display a loading bar in your game. + * + * @method Phaser.Loader.LoaderPlugin#updateProgress + * @fires Phaser.Loader.Events#PROGRESS + * @since 3.0.0 + */ + updateProgress: function () { - 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 = ''; + this.progress = 1 - ((this.list.size + this.inflight.size) / this.totalToLoad); - var lines = data.split('\n'); + this.emit(Events.PROGRESS, this.progress); + }, - for (var i = 0; i < lines.length; i++) + /** + * Called automatically during the load process. + * + * @method Phaser.Loader.LoaderPlugin#update + * @since 3.10.0 + */ + update: function () { - var line = stripComments(lines[i]); - - var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); - - switch (lineItems[0].toLowerCase()) + if (this.state === CONST.LOADER_LOADING && this.list.size > 0 && this.inflight.size < this.maxParallelDownloads) { - case 'o': - // Start A New Model - parseObject(lineItems, result); - break; + this.checkLoadQueue(); + } + }, - case 'g': - // Start a new polygon group - parseGroup(lineItems); - break; + /** + * An internal method called by the Loader. + * + * It will check to see if there are any more files in the pending list that need loading, and if so it will move + * them from the list Set into the inflight Set, set their CORs flag and start them loading. + * + * It will carrying on doing this for each file in the pending list until it runs out, or hits the max allowed parallel downloads. + * + * @method Phaser.Loader.LoaderPlugin#checkLoadQueue + * @private + * @since 3.7.0 + */ + checkLoadQueue: function () + { + this.list.each(function (file) + { + if (file.state === CONST.FILE_POPULATED || (file.state === CONST.FILE_PENDING && this.inflight.size < this.maxParallelDownloads)) + { + this.inflight.set(file); - case 'v': - // Define a vertex for the current model - parseVertexCoords(lineItems, result); - break; + this.list.delete(file); - case 'vt': - // Texture Coords - parseTextureCoords(lineItems, result); - break; + // If the file doesn't have its own crossOrigin set, we'll use the Loaders (which is undefined by default) + if (!file.crossOrigin) + { + file.crossOrigin = this.crossOrigin; + } - case 'vn': - // Define a vertex normal for the current model - parseVertexNormal(lineItems, result); - break; + file.load(); + } - case 'f': - // Define a Face/Polygon - parsePolygon(lineItems, result); - break; + if (this.inflight.size === this.maxParallelDownloads) + { + // Tells the Set iterator to abort + return false; + } - case 'mtllib': - // Reference to a material library file (.mtl) - parseMtlLib(lineItems, result); - break; + }, this); + }, - case 'usemtl': - // Sets the current material to be applied to polygons defined from this point forward - parseUseMtl(lineItems); - break; + /** + * An internal method called automatically by the XHRLoader belong to a File. + * + * This method will remove the given file from the inflight Set and update the load progress. + * If the file was successful its `onProcess` method is called, otherwise it is added to the delete queue. + * + * @method Phaser.Loader.LoaderPlugin#nextFile + * @fires Phaser.Loader.Events#FILE_LOAD + * @fires Phaser.Loader.Events#FILE_LOAD_ERROR + * @since 3.0.0 + * + * @param {Phaser.Loader.File} file - The File that just finished loading, or errored during load. + * @param {boolean} success - `true` if the file loaded successfully, otherwise `false`. + */ + nextFile: function (file, success) + { + // Has the game been destroyed during load? If so, bail out now. + if (!this.inflight) + { + return; } - } - return result; -}; + this.inflight.delete(file); -module.exports = ParseObj; + this.updateProgress(); + if (success) + { + this.totalComplete++; -/***/ }), -/* 499 */ -/***/ (function(module, exports, __webpack_require__) { + this.queue.set(file); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.emit(Events.FILE_LOAD, file); -var GetColor = __webpack_require__(103); + file.onProcess(); + } + else + { + this.totalFailed++; -/** - * 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 = {}; + this._deleteQueue.set(file); - var lines = mtl.split('\n'); + this.emit(Events.FILE_LOAD_ERROR, file); - var currentMaterial = ''; + this.fileProcessComplete(file); + } + }, - for (var i = 0; i < lines.length; i++) + /** + * An internal method that is called automatically by the File when it has finished processing. + * + * If the process was successful, and the File isn't part of a MultiFile, its `addToCache` method is called. + * + * It this then removed from the queue. If there are no more files to load `loadComplete` is called. + * + * @method Phaser.Loader.LoaderPlugin#fileProcessComplete + * @since 3.7.0 + * + * @param {Phaser.Loader.File} file - The file that has finished processing. + */ + fileProcessComplete: function (file) { - var line = lines[i].trim(); - - if (line.indexOf('#') === 0 || line === '') + // Has the game been destroyed during load? If so, bail out now. + if (!this.scene || !this.systems || !this.systems.game || this.systems.game.pendingDestroy) { - continue; + return; } - var lineItems = line.replace(/\s\s+/g, ' ').trim().split(' '); - - switch (lineItems[0].toLowerCase()) + // This file has failed, so move it to the failed Set + if (file.state === CONST.FILE_ERRORED) { - case 'newmtl': + if (file.multiFile) { - currentMaterial = lineItems[1]; - break; + file.multiFile.onFileFailed(file); } - - // The diffuse reflectivity of the current material - // Support r, [g], [b] format, where g and b are optional - case 'kd': + } + else if (file.state === CONST.FILE_COMPLETE) + { + if (file.multiFile) { - 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; + if (file.multiFile.isReadyToProcess()) + { + // If we got here then all files the link file needs are ready to add to the cache + file.multiFile.addToCache(); + file.multiFile.pendingDestroy(); + } + } + else + { + // If we got here, then the file processed, so let it add itself to its cache + file.addToCache(); + file.pendingDestroy(); } } - } - return output; -}; - -module.exports = ParseObjMaterial; + // Remove it from the queue + this.queue.delete(file); + // Nothing left to do? -/***/ }), -/* 500 */ -/***/ (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; - + if (this.list.size === 0 && this.inflight.size === 0 && this.queue.size === 0) + { + this.loadComplete(); + } + }, -/***/ }), -/* 501 */ -/***/ (function(module, exports) { + /** + * Called at the end when the load queue is exhausted and all files have either loaded or errored. + * By this point every loaded file will now be in its associated cache and ready for use. + * + * Also clears down the Sets, puts progress to 1 and clears the deletion queue. + * + * @method Phaser.Loader.LoaderPlugin#loadComplete + * @fires Phaser.Loader.Events#COMPLETE + * @fires Phaser.Loader.Events#POST_PROCESS + * @since 3.7.0 + */ + loadComplete: function () + { + this.emit(Events.POST_PROCESS, this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.list.clear(); + this.inflight.clear(); + this.queue.clear(); -/** - * 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); -}; + this.progress = 1; -module.exports = GetMagnitudeSq; + this.state = CONST.LOADER_COMPLETE; + this.systems.events.off(SceneEvents.UPDATE, this.update, this); -/***/ }), -/* 502 */ -/***/ (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__(1267); -Rectangle.Ceil = __webpack_require__(1268); -Rectangle.CeilAll = __webpack_require__(1269); -Rectangle.CenterOn = __webpack_require__(190); -Rectangle.Clone = __webpack_require__(1270); -Rectangle.Contains = __webpack_require__(57); -Rectangle.ContainsPoint = __webpack_require__(1271); -Rectangle.ContainsRect = __webpack_require__(503); -Rectangle.CopyFrom = __webpack_require__(1272); -Rectangle.Decompose = __webpack_require__(490); -Rectangle.Equals = __webpack_require__(1273); -Rectangle.FitInside = __webpack_require__(1274); -Rectangle.FitOutside = __webpack_require__(1275); -Rectangle.Floor = __webpack_require__(1276); -Rectangle.FloorAll = __webpack_require__(1277); -Rectangle.FromPoints = __webpack_require__(199); -Rectangle.FromXY = __webpack_require__(1278); -Rectangle.GetAspectRatio = __webpack_require__(237); -Rectangle.GetCenter = __webpack_require__(1279); -Rectangle.GetPoint = __webpack_require__(171); -Rectangle.GetPoints = __webpack_require__(306); -Rectangle.GetSize = __webpack_require__(1280); -Rectangle.Inflate = __webpack_require__(1281); -Rectangle.Intersection = __webpack_require__(1282); -Rectangle.MarchingAnts = __webpack_require__(316); -Rectangle.MergePoints = __webpack_require__(1283); -Rectangle.MergeRect = __webpack_require__(1284); -Rectangle.MergeXY = __webpack_require__(1285); -Rectangle.Offset = __webpack_require__(1286); -Rectangle.OffsetPoint = __webpack_require__(1287); -Rectangle.Overlaps = __webpack_require__(1288); -Rectangle.Perimeter = __webpack_require__(130); -Rectangle.PerimeterPoint = __webpack_require__(1289); -Rectangle.Random = __webpack_require__(174); -Rectangle.RandomOutside = __webpack_require__(1290); -Rectangle.SameDimensions = __webpack_require__(1291); -Rectangle.Scale = __webpack_require__(1292); -Rectangle.Union = __webpack_require__(441); + // Call 'destroy' on each file ready for deletion + this._deleteQueue.iterateLocal('destroy'); -module.exports = Rectangle; + this._deleteQueue.clear(); + this.emit(Events.COMPLETE, this, this.totalComplete, this.totalFailed); + }, -/***/ }), -/* 503 */ -/***/ (function(module, exports) { + /** + * Adds a File into the pending-deletion queue. + * + * @method Phaser.Loader.LoaderPlugin#flagForRemoval + * @since 3.7.0 + * + * @param {Phaser.Loader.File} file - The File to be queued for deletion when the Loader completes. + */ + flagForRemoval: function (file) + { + this._deleteQueue.set(file); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Converts the given JSON data into a file that the browser then prompts you to download so you can save it locally. + * + * The data must be well formed JSON and ready-parsed, not a JavaScript object. + * + * @method Phaser.Loader.LoaderPlugin#saveJSON + * @since 3.0.0 + * + * @param {*} data - The JSON data, ready parsed. + * @param {string} [filename=file.json] - The name to save the JSON file as. + * + * @return {this} This Loader plugin. + */ + saveJSON: function (data, filename) + { + return this.save(JSON.stringify(data), filename); + }, -/** - * 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)) + /** + * Causes the browser to save the given data as a file to its default Downloads folder. + * + * Creates a DOM level anchor link, assigns it as being a `download` anchor, sets the href + * to be an ObjectURL based on the given data, and then invokes a click event. + * + * @method Phaser.Loader.LoaderPlugin#save + * @since 3.0.0 + * + * @param {*} data - The data to be saved. Will be passed through URL.createObjectURL. + * @param {string} [filename=file.json] - The filename to save the file as. + * @param {string} [filetype=application/json] - The file type to use when saving the file. Defaults to JSON. + * + * @return {this} This Loader plugin. + */ + save: function (data, filename, filetype) { - return false; - } + if (filename === undefined) { filename = 'file.json'; } + if (filetype === undefined) { filetype = 'application/json'; } - 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) - ); -}; + var blob = new Blob([ data ], { type: filetype }); -module.exports = ContainsRect; + var url = URL.createObjectURL(blob); + var a = document.createElement('a'); -/***/ }), -/* 504 */ -/***/ (function(module, exports, __webpack_require__) { + a.download = filename; + a.textContent = 'Download ' + filename; + a.href = url; + a.click(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var Point = __webpack_require__(4); + /** + * Resets the Loader. + * + * This will clear all lists and reset the base URL, path and prefix. + * + * Warning: If the Loader is currently downloading files, or has files in its queue, they will be aborted. + * + * @method Phaser.Loader.LoaderPlugin#reset + * @since 3.0.0 + */ + reset: function () + { + this.list.clear(); + this.inflight.clear(); + this.queue.clear(); -// 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 + var gameConfig = this.systems.game.config; + var sceneConfig = this.systems.settings.loader; -/** - * 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(); } + this.setBaseURL(GetFastValue(sceneConfig, 'baseURL', gameConfig.loaderBaseURL)); + this.setPath(GetFastValue(sceneConfig, 'path', gameConfig.loaderPath)); + this.setPrefix(GetFastValue(sceneConfig, 'prefix', gameConfig.loaderPrefix)); - out.x = (triangle.x1 + triangle.x2 + triangle.x3) / 3; - out.y = (triangle.y1 + triangle.y2 + triangle.y3) / 3; + this.state = CONST.LOADER_IDLE; + }, - return out; -}; + /** + * The Scene that owns this plugin is shutting down. + * We need to kill and reset all internal properties as well as stop listening to Scene events. + * + * @method Phaser.Loader.LoaderPlugin#shutdown + * @private + * @since 3.0.0 + */ + shutdown: function () + { + this.reset(); -module.exports = Centroid; + this.state = CONST.LOADER_SHUTDOWN; + this.systems.events.off(SceneEvents.UPDATE, this.update, this); + this.systems.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); + }, -/***/ }), -/* 505 */ -/***/ (function(module, exports) { + /** + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. + * + * @method Phaser.Loader.LoaderPlugin#destroy + * @private + * @since 3.0.0 + */ + destroy: function () + { + this.shutdown(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.state = CONST.LOADER_DESTROYED; -/** - * 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; + this.systems.events.off(SceneEvents.UPDATE, this.update, this); + this.systems.events.off(SceneEvents.START, this.pluginStart, this); - triangle.x2 += x; - triangle.y2 += y; + this.list = null; + this.inflight = null; + this.queue = null; - triangle.x3 += x; - triangle.y3 += y; + this.scene = null; + this.systems = null; + this.textureManager = null; + this.cacheManager = null; + this.sceneManager = null; + } - return triangle; -}; +}); -module.exports = Offset; +PluginCache.register('Loader', LoaderPlugin, 'load'); + +module.exports = LoaderPlugin; /***/ }), -/* 506 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 43531: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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); -} +var Extend = __webpack_require__(98611); +var XHRSettings = __webpack_require__(33868); /** - * 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. + * Takes two XHRSettings Objects and creates a new XHRSettings object from them. * - * @function Phaser.Geom.Triangle.InCenter - * @since 3.0.0 + * The new object is seeded by the values given in the global settings, but any setting in + * the local object overrides the global ones. * - * @generic {Phaser.Geom.Point} O - [out,$return] + * @function Phaser.Loader.MergeXHRSettings + * @since 3.0.0 * - * @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. + * @param {Phaser.Types.Loader.XHRSettingsObject} global - The global XHRSettings object. + * @param {Phaser.Types.Loader.XHRSettingsObject} local - The local XHRSettings object. * - * @return {Phaser.Geom.Point} Point (x, y) of the center pixel of the triangle. + * @return {Phaser.Types.Loader.XHRSettingsObject} A newly formed XHRSettings object. */ -var InCenter = function (triangle, out) +var MergeXHRSettings = function (global, local) { - 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; - - -/***/ }), -/* 507 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var output = (global === undefined) ? XHRSettings() : Extend({}, global); -/** - * 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) + if (local) { - var alpha = textureManager.getPixelAlpha(x, y, gameObject.texture.key, gameObject.frame.name); + for (var setting in local) + { + if (local[setting] !== undefined) + { + output[setting] = local[setting]; + } + } + } - return (alpha && alpha >= alphaTolerance); - }; + return output; }; -module.exports = CreatePixelPerfectHandler; +module.exports = MergeXHRSettings; /***/ }), -/* 508 */ -/***/ (function(module, exports) { + +/***/ 45176: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var Events = __webpack_require__(683); + /** - * 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. + * @classdesc + * A MultiFile is a special kind of parent that contains two, or more, Files as children and looks after + * the loading and processing of them all. It is commonly extended and used as a base class for file types such as AtlasJSON or BitmapFont. * - * @function Phaser.Input.CreateInteractiveObject - * @since 3.0.0 + * You shouldn't create an instance of a MultiFile directly, but should extend it with your own class, setting a custom type and processing methods. * - * @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. + * @class MultiFile + * @memberof Phaser.Loader + * @constructor + * @since 3.7.0 * - * @return {Phaser.Types.Input.InteractiveObject} The new Interactive Object. + * @param {Phaser.Loader.LoaderPlugin} loader - The Loader that is going to load this File. + * @param {string} type - The file type string for sorting within the Loader. + * @param {string} key - The key of the file within the loader. + * @param {Phaser.Loader.File[]} files - An array of Files that make-up this MultiFile. */ -var 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, +var MultiFile = new Class({ - localX: 0, - localY: 0, + initialize: - // 0 = Not being dragged - // 1 = Being checked for dragging - // 2 = Being dragged - dragState: 0, + function MultiFile (loader, type, key, files) + { + var finalFiles = []; - dragStartX: 0, - dragStartY: 0, - dragStartXGlobal: 0, - dragStartYGlobal: 0, + // Clean out any potential 'null' or 'undefined' file entries + files.forEach(function (file) + { + if (file) + { + finalFiles.push(file); + } + }); - dragX: 0, - dragY: 0 + /** + * A reference to the Loader that is going to load this file. + * + * @name Phaser.Loader.MultiFile#loader + * @type {Phaser.Loader.LoaderPlugin} + * @since 3.7.0 + */ + this.loader = loader; - }; -}; + /** + * The file type string for sorting within the Loader. + * + * @name Phaser.Loader.MultiFile#type + * @type {string} + * @since 3.7.0 + */ + this.type = type; -module.exports = CreateInteractiveObject; + /** + * Unique cache key (unique within its file type) + * + * @name Phaser.Loader.MultiFile#key + * @type {string} + * @since 3.7.0 + */ + this.key = key; + /** + * The current index being used by multi-file loaders to avoid key clashes. + * + * @name Phaser.Loader.MultiFile#multiKeyIndex + * @type {number} + * @private + * @since 3.20.0 + */ + this.multiKeyIndex = loader.multiKeyIndex++; -/***/ }), -/* 509 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Array of files that make up this MultiFile. + * + * @name Phaser.Loader.MultiFile#files + * @type {Phaser.Loader.File[]} + * @since 3.7.0 + */ + this.files = finalFiles; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The current state of the file. One of the FILE_CONST values. + * + * @name Phaser.Loader.MultiFile#state + * @type {number} + * @since 3.60.0 + */ + this.state = CONST.FILE_PENDING; -var Class = __webpack_require__(0); + /** + * The completion status of this MultiFile. + * + * @name Phaser.Loader.MultiFile#complete + * @type {boolean} + * @default false + * @since 3.7.0 + */ + this.complete = false; -/** - * @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({ + /** + * The number of files to load. + * + * @name Phaser.Loader.MultiFile#pending + * @type {number} + * @since 3.7.0 + */ - initialize: + this.pending = finalFiles.length; - function Axis (pad, index) - { /** - * A reference to the Gamepad that this Axis belongs to. + * The number of files that failed to load. * - * @name Phaser.Input.Gamepad.Axis#pad - * @type {Phaser.Input.Gamepad.Gamepad} - * @since 3.0.0 + * @name Phaser.Loader.MultiFile#failed + * @type {number} + * @default 0 + * @since 3.7.0 */ - this.pad = pad; + this.failed = 0; /** - * An event emitter to use to emit the axis events. + * A storage container for transient data that the loading files need. * - * @name Phaser.Input.Gamepad.Axis#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 + * @name Phaser.Loader.MultiFile#config + * @type {any} + * @since 3.7.0 */ - this.events = pad.events; + this.config = {}; /** - * The index of this Axis. + * A reference to the Loaders baseURL at the time this MultiFile was created. + * Used to populate child-files. * - * @name Phaser.Input.Gamepad.Axis#index - * @type {number} - * @since 3.0.0 + * @name Phaser.Loader.MultiFile#baseURL + * @type {string} + * @since 3.20.0 */ - this.index = index; + this.baseURL = loader.baseURL; /** - * 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. + * A reference to the Loaders path at the time this MultiFile was created. + * Used to populate child-files. * - * @name Phaser.Input.Gamepad.Axis#value - * @type {number} - * @default 0 - * @since 3.0.0 + * @name Phaser.Loader.MultiFile#path + * @type {string} + * @since 3.20.0 */ - this.value = 0; + this.path = loader.path; /** - * Movement tolerance threshold below which axis values are ignored in `getValue`. + * A reference to the Loaders prefix at the time this MultiFile was created. + * Used to populate child-files. * - * @name Phaser.Input.Gamepad.Axis#threshold - * @type {number} - * @default 0.1 - * @since 3.0.0 + * @name Phaser.Loader.MultiFile#prefix + * @type {string} + * @since 3.20.0 */ - this.threshold = 0.1; + this.prefix = loader.prefix; + + // Link the files + for (var i = 0; i < finalFiles.length; i++) + { + finalFiles[i].multiFile = this; + } }, /** - * Internal update handler for this Axis. - * Called automatically by the Gamepad as part of its update. + * Checks if this MultiFile is ready to process its children or not. * - * @method Phaser.Input.Gamepad.Axis#update - * @private - * @since 3.0.0 + * @method Phaser.Loader.MultiFile#isReadyToProcess + * @since 3.7.0 * - * @param {number} value - The value of the axis movement. + * @return {boolean} `true` if all children of this MultiFile have loaded, otherwise `false`. */ - update: function (value) + isReadyToProcess: function () { - this.value = value; + return (this.pending === 0 && this.failed === 0 && !this.complete); }, /** - * Applies the `threshold` value to the axis and returns it. + * Adds another child to this MultiFile, increases the pending count and resets the completion status. * - * @method Phaser.Input.Gamepad.Axis#getValue - * @since 3.0.0 + * @method Phaser.Loader.MultiFile#addToMultiFile + * @since 3.7.0 * - * @return {number} The axis value, adjusted for the movement threshold. + * @param {Phaser.Loader.File} files - The File to add to this MultiFile. + * + * @return {Phaser.Loader.MultiFile} This MultiFile instance. */ - getValue: function () + addToMultiFile: function (file) { - return (Math.abs(this.value) < this.threshold) ? 0 : this.value; + this.files.push(file); + + file.multiFile = this; + + this.pending++; + + this.complete = false; + + return this; }, /** - * Destroys this Axis instance and releases external references it holds. + * Called by each File when it finishes loading. * - * @method Phaser.Input.Gamepad.Axis#destroy - * @since 3.10.0 + * @method Phaser.Loader.MultiFile#onFileComplete + * @since 3.7.0 + * + * @param {Phaser.Loader.File} file - The File that has completed processing. + */ + onFileComplete: function (file) + { + var index = this.files.indexOf(file); + + if (index !== -1) + { + this.pending--; + } + }, + + /** + * Called by each File that fails to load. + * + * @method Phaser.Loader.MultiFile#onFileFailed + * @since 3.7.0 + * + * @param {Phaser.Loader.File} file - The File that has failed to load. + */ + onFileFailed: function (file) + { + var index = this.files.indexOf(file); + + if (index !== -1) + { + this.failed++; + + // eslint-disable-next-line no-console + console.error('File failed: %s "%s" (via %s "%s")', this.type, this.key, file.type, file.key); + } + }, + + /** + * Called once all children of this multi file have been added to their caches and is now + * ready for deletion from the Loader. + * + * It will emit a `filecomplete` event from the LoaderPlugin. + * + * @method Phaser.Loader.MultiFile#pendingDestroy + * @fires Phaser.Loader.Events#FILE_COMPLETE + * @fires Phaser.Loader.Events#FILE_KEY_COMPLETE + * @since 3.60.0 + */ + pendingDestroy: function () + { + if (this.state === CONST.FILE_PENDING_DESTROY) + { + return; + } + + var key = this.key; + var type = this.type; + + this.loader.emit(Events.FILE_COMPLETE, key, type); + this.loader.emit(Events.FILE_KEY_COMPLETE + type + '-' + key, key, type); + + this.loader.flagForRemoval(this); + + for (var i = 0; i < this.files.length; i++) + { + this.files[i].pendingDestroy(); + } + + this.state = CONST.FILE_PENDING_DESTROY; + }, + + /** + * Destroy this Multi File and any references it holds. + * + * @method Phaser.Loader.MultiFile#destroy + * @since 3.60.0 */ destroy: function () { - this.pad = null; - this.events = null; + this.loader = null; + this.files = null; + this.config = null; } }); -module.exports = Axis; +module.exports = MultiFile; /***/ }), -/* 510 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 88490: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Events = __webpack_require__(239); +var MergeXHRSettings = __webpack_require__(43531); /** - * @classdesc - * Contains information about a specific button on a Gamepad. - * Button objects are created automatically by the Gamepad as they are needed. + * 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. * - * @class Button - * @memberof Phaser.Input.Gamepad - * @constructor + * @function Phaser.Loader.XHRLoader * @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. + * @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 Button = new Class({ +var XHRLoader = function (file, globalXHRSettings) +{ + var config = MergeXHRSettings(globalXHRSettings, file.xhrSettings); - initialize: + var xhr = new XMLHttpRequest(); - 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; + xhr.open('GET', file.src, config.async, config.user, config.password); - /** - * 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; + xhr.responseType = file.xhrSettings.responseType; + xhr.timeout = config.timeout; - /** - * The index of this Button. - * - * @name Phaser.Input.Gamepad.Button#index - * @type {number} - * @since 3.0.0 - */ - this.index = index; + if (config.headers) + { + for (var key in config.headers) + { + xhr.setRequestHeader(key, config.headers[key]); + } + } - /** - * Between 0 and 1. - * - * @name Phaser.Input.Gamepad.Button#value - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.value = 0; + if (config.header && config.headerValue) + { + xhr.setRequestHeader(config.header, config.headerValue); + } - /** - * 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; + if (config.requestedWith) + { + xhr.setRequestHeader('X-Requested-With', config.requestedWith); + } - /** - * 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; - }, + if (config.overrideMimeType) + { + xhr.overrideMimeType(config.overrideMimeType); + } - /** - * 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) + if (config.withCredentials) { - this.value = value; + xhr.withCredentials = true; + } - var pad = this.pad; - var index = this.index; + // 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.) - 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); - } - }, + xhr.onload = file.onLoad.bind(file, xhr); + xhr.onerror = file.onError.bind(file, xhr); + xhr.onprogress = file.onProgress.bind(file); - /** - * 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; - } + // This is the only standard method, the ones above are browser additions (maybe not universal?) + // xhr.onreadystatechange -}); + xhr.send(); -module.exports = Button; + return xhr; +}; + +module.exports = XHRLoader; /***/ }), -/* 511 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 33868: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Axis = __webpack_require__(509); -var Button = __webpack_require__(510); -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. + * Creates an XHRSettings Object with default values. * - * @class Gamepad - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Input.Gamepad - * @constructor + * @function Phaser.Loader.XHRSettings * @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. + * @param {XMLHttpRequestResponseType} [responseType=''] - The responseType, such as 'text'. + * @param {boolean} [async=true] - Should the XHR request use async or not? + * @param {string} [user=''] - Optional username for the XHR request. + * @param {string} [password=''] - Optional password for the XHR request. + * @param {number} [timeout=0] - Optional XHR timeout value. + * @param {boolean} [withCredentials=false] - Optional XHR withCredentials value. + * + * @return {Phaser.Types.Loader.XHRSettingsObject} The XHRSettings object as used by the Loader. */ -var Gamepad = new Class({ - - Extends: EventEmitter, +var XHRSettings = function (responseType, async, user, password, timeout, withCredentials) +{ + if (responseType === undefined) { responseType = ''; } + if (async === undefined) { async = true; } + if (user === undefined) { user = ''; } + if (password === undefined) { password = ''; } + if (timeout === undefined) { timeout = 0; } + if (withCredentials === undefined) { withCredentials = false; } - initialize: + // Before sending a request, set the xhr.responseType to "text", + // "arraybuffer", "blob", or "document", depending on your data needs. + // Note, setting xhr.responseType = '' (or omitting) will default the response to "text". - function Gamepad (manager, pad) - { - EventEmitter.call(this); + return { - /** - * A reference to the Gamepad Plugin. - * - * @name Phaser.Input.Gamepad.Gamepad#manager - * @type {Phaser.Input.Gamepad.GamepadPlugin} - * @since 3.0.0 - */ - this.manager = manager; + // Ignored by the Loader, only used by File. + responseType: responseType, - /** - * 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; + async: async, - /** - * 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; + // credentials + user: user, + password: password, - /** - * 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; + // timeout in ms (0 = no timeout) + timeout: timeout, - var buttons = []; + // setRequestHeader + headers: undefined, + header: undefined, + headerValue: undefined, + requestedWith: false, - for (var i = 0; i < pad.buttons.length; i++) - { - buttons.push(new Button(this, i)); - } + // overrideMimeType + overrideMimeType: undefined, - /** - * 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; + // withCredentials + withCredentials: withCredentials - var axes = []; + }; +}; - for (i = 0; i < pad.axes.length; i++) - { - axes.push(new Axis(this, i)); - } +module.exports = XHRSettings; - /** - * 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 +/***/ 12117: +/***/ ((module) => { - var _noButton = { value: 0, pressed: false }; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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(); - }, +var FILE_CONST = { /** - * Gets the total number of axis this Gamepad claims to support. - * - * @method Phaser.Input.Gamepad.Gamepad#getAxisTotal - * @since 3.10.0 + * The Loader is idle. * - * @return {number} The total number of axes this Gamepad claims to support. + * @name Phaser.Loader.LOADER_IDLE + * @type {number} + * @since 3.0.0 */ - getAxisTotal: function () - { - return this.axes.length; - }, + LOADER_IDLE: 0, /** - * 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. + * The Loader is actively loading. * - * @return {number} The value of the axis, between 0 and 1. + * @name Phaser.Loader.LOADER_LOADING + * @type {number} + * @since 3.0.0 */ - getAxisValue: function (index) - { - return this.axes[index].getValue(); - }, + LOADER_LOADING: 1, /** - * 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 + * The Loader is processing files is has loaded. * - * @param {number} value - A value between 0 and 1. + * @name Phaser.Loader.LOADER_PROCESSING + * @type {number} + * @since 3.0.0 */ - setAxisThreshold: function (value) - { - for (var i = 0; i < this.axes.length; i++) - { - this.axes[i].threshold = value; - } - }, + LOADER_PROCESSING: 2, /** - * Gets the total number of buttons this Gamepad claims to have. - * - * @method Phaser.Input.Gamepad.Gamepad#getButtonTotal - * @since 3.10.0 + * The Loader has completed loading and processing. * - * @return {number} The total number of buttons this Gamepad claims to have. + * @name Phaser.Loader.LOADER_COMPLETE + * @type {number} + * @since 3.0.0 */ - getButtonTotal: function () - { - return this.buttons.length; - }, + LOADER_COMPLETE: 3, /** - * 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. + * The Loader is shutting down. * - * @return {number} The value of the button, between 0 and 1. + * @name Phaser.Loader.LOADER_SHUTDOWN + * @type {number} + * @since 3.0.0 */ - getButtonValue: function (index) - { - return this.buttons[index].value; - }, + LOADER_SHUTDOWN: 4, /** - * 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. + * The Loader has been destroyed. * - * @return {boolean} `true` if the button is considered as being pressed down, otherwise `false`. + * @name Phaser.Loader.LOADER_DESTROYED + * @type {number} + * @since 3.0.0 */ - isButtonDown: function (index) - { - return this.buttons[index].pressed; - }, + LOADER_DESTROYED: 5, /** - * Internal update handler for this Gamepad. - * Called automatically by the Gamepad Manager as part of its update. + * File is in the load queue but not yet started. * - * @method Phaser.Input.Gamepad.Gamepad#update - * @private + * @name Phaser.Loader.FILE_PENDING + * @type {number} * @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()); - } - } - }, + FILE_PENDING: 10, /** - * Destroys this Gamepad instance, its buttons and axes, and releases external references it holds. + * File has been started to load by the loader (onLoad called) * - * @method Phaser.Input.Gamepad.Gamepad#destroy - * @since 3.10.0 + * @name Phaser.Loader.FILE_LOADING + * @type {number} + * @since 3.0.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 = []; - }, + FILE_LOADING: 11, /** - * Is this Gamepad currently connected or not? + * File has loaded successfully, awaiting processing. * - * @name Phaser.Input.Gamepad.Gamepad#connected - * @type {boolean} - * @default true + * @name Phaser.Loader.FILE_LOADED + * @type {number} * @since 3.0.0 */ - connected: { - - get: function () - { - return this.pad.connected; - } - - }, + FILE_LOADED: 12, /** - * A timestamp containing the most recent time this Gamepad was updated. + * File failed to load. * - * @name Phaser.Input.Gamepad.Gamepad#timestamp + * @name Phaser.Loader.FILE_FAILED * @type {number} * @since 3.0.0 */ - timestamp: { - - get: function () - { - return this.pad.timestamp; - } - - }, + FILE_FAILED: 13, /** - * 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. + * File is being processed (onProcess callback) * - * @name Phaser.Input.Gamepad.Gamepad#left - * @type {boolean} - * @since 3.10.0 + * @name Phaser.Loader.FILE_PROCESSING + * @type {number} + * @since 3.0.0 */ - left: { - - get: function () - { - return this._LCLeft.pressed; - } - - }, + FILE_PROCESSING: 14, /** - * 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. + * The File has errored somehow during processing. * - * @name Phaser.Input.Gamepad.Gamepad#right - * @type {boolean} - * @since 3.10.0 + * @name Phaser.Loader.FILE_ERRORED + * @type {number} + * @since 3.0.0 */ - right: { - - get: function () - { - return this._LCRight.pressed; - } - - }, + FILE_ERRORED: 16, /** - * 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. + * File has finished processing. * - * @name Phaser.Input.Gamepad.Gamepad#up - * @type {boolean} - * @since 3.10.0 + * @name Phaser.Loader.FILE_COMPLETE + * @type {number} + * @since 3.0.0 */ - up: { - - get: function () - { - return this._LCTop.pressed; - } - - }, + FILE_COMPLETE: 17, /** - * 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. + * File has been destroyed. * - * @name Phaser.Input.Gamepad.Gamepad#down - * @type {boolean} - * @since 3.10.0 + * @name Phaser.Loader.FILE_DESTROYED + * @type {number} + * @since 3.0.0 */ - down: { - - get: function () - { - return this._LCBottom.pressed; - } - - }, + FILE_DESTROYED: 18, /** - * 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. + * File was populated from local data and doesn't need an HTTP request. * - * @name Phaser.Input.Gamepad.Gamepad#A - * @type {boolean} - * @since 3.10.0 + * @name Phaser.Loader.FILE_POPULATED + * @type {number} + * @since 3.0.0 */ - A: { - - get: function () - { - return this._RCBottom.pressed; - } - - }, + FILE_POPULATED: 19, /** - * 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. + * File is pending being destroyed. * - * @name Phaser.Input.Gamepad.Gamepad#Y - * @type {boolean} - * @since 3.10.0 + * @name Phaser.Loader.FILE_PENDING_DESTROY + * @type {number} + * @since 3.60.0 */ - Y: { + FILE_PENDING_DESTROY: 20 - get: function () - { - return this._RCTop.pressed; - } +}; - }, +module.exports = FILE_CONST; - /** - * 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; - } +/***/ }), - }, +/***/ 7398: +/***/ ((module) => { - /** - * 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: { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - get: function () - { - return this._RCRight.pressed; - } +/** + * The Loader Plugin Add File Event. + * + * This event is dispatched when a new file is successfully added to the Loader and placed into the load queue. + * + * Listen to it from a Scene using: `this.load.on('addfile', listener)`. + * + * If you add lots of files to a Loader from a `preload` method, it will dispatch this event for each one of them. + * + * @event Phaser.Loader.Events#ADD + * @type {string} + * @since 3.0.0 + * + * @param {string} key - The unique key of the file that was added to the Loader. + * @param {string} type - The [file type]{@link Phaser.Loader.File#type} string of the file that was added to the Loader, i.e. `image`. + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event. + * @param {Phaser.Loader.File} file - A reference to the File which was added to the Loader. + */ +module.exports = 'addfile'; - }, - /** - * 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; - } +/***/ 52187: +/***/ ((module) => { - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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: { +/** + * The Loader Plugin Complete Event. + * + * This event is dispatched when the Loader has fully processed everything in the load queue. + * By this point every loaded file will now be in its associated cache and ready for use. + * + * Listen to it from a Scene using: `this.load.on('complete', listener)`. + * + * @event Phaser.Loader.Events#COMPLETE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event. + * @param {number} totalComplete - The total number of files that successfully loaded. + * @param {number} totalFailed - The total number of files that failed to load. + */ +module.exports = 'complete'; - 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: { +/***/ 36627: +/***/ ((module) => { - get: function () - { - return this._FBRightTop.value; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - }, +/** + * The File Load Complete Event. + * + * This event is dispatched by the Loader Plugin when _any_ file in the queue finishes loading. + * + * Listen to it from a Scene using: `this.load.on('filecomplete', listener)`. + * + * Make sure you remove this listener when you have finished, or it will continue to fire if the Scene reloads. + * + * You can also listen for the completion of a specific file. See the [FILE_KEY_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_KEY_COMPLETE} event. + * + * @event Phaser.Loader.Events#FILE_COMPLETE + * @type {string} + * @since 3.0.0 + * + * @param {string} key - The key of the file that just loaded and finished processing. + * @param {string} type - The [file type]{@link Phaser.Loader.File#type} of the file that just loaded, i.e. `image`. + * @param {any} [data] - The raw data the file contained. If the file was a multi-file, like an atlas or bitmap font, this parameter will be undefined. + */ +module.exports = 'filecomplete'; - /** - * 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; - } +/***/ }), - } +/***/ 81925: +/***/ ((module) => { -}); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = Gamepad; +/** + * The File Load Complete Event. + * + * This event is dispatched by the Loader Plugin when any file in the queue finishes loading. + * + * It uses a special dynamic event name constructed from the key and type of the file. + * + * For example, if you have loaded an `image` with a key of `monster`, you can listen for it + * using the following: + * + * ```javascript + * this.load.on('filecomplete-image-monster', function (key, type, data) { + * // Your handler code + * }); + * ``` + * + * Or, if you have loaded a texture `atlas` with a key of `Level1`: + * + * ```javascript + * this.load.on('filecomplete-atlasjson-Level1', function (key, type, data) { + * // Your handler code + * }); + * ``` + * + * Or, if you have loaded a sprite sheet with a key of `Explosion` and a prefix of `GAMEOVER`: + * + * ```javascript + * this.load.on('filecomplete-spritesheet-GAMEOVERExplosion', function (key, type, data) { + * // Your handler code + * }); + * ``` + * + * Make sure you remove your listeners when you have finished, or they will continue to fire if the Scene reloads. + * + * You can also listen for the generic completion of files. See the [FILE_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_COMPLETE} event. + * + * @event Phaser.Loader.Events#FILE_KEY_COMPLETE + * @type {string} + * @since 3.0.0 + * + * @param {string} key - The key of the file that just loaded and finished processing. + * @param {string} type - The [file type]{@link Phaser.Loader.File#type} of the file that just loaded, i.e. `image`. + * @param {any} [data] - The raw data the file contained. If the file was a multi-file, like an atlas or bitmap font, this parameter will be undefined. + */ +module.exports = 'filecomplete-'; /***/ }), -/* 512 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 29774: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(154); - /** - * @classdesc - * A generic Key object which can be passed to the Process functions (and so on) - * keycode must be an integer + * The File Load Error Event. * - * @class Key - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Input.Keyboard - * @constructor + * This event is dispatched by the Loader Plugin when a file fails to load. + * + * Listen to it from a Scene using: `this.load.on('loaderror', listener)`. + * + * @event Phaser.Loader.Events#FILE_LOAD_ERROR + * @type {string} * @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. + * @param {Phaser.Loader.File} file - A reference to the File which errored during load. */ -var Key = new Class({ +module.exports = 'loaderror'; - Extends: EventEmitter, - initialize: +/***/ }), - function Key (plugin, keyCode) - { - EventEmitter.call(this); +/***/ 20943: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * The keycode of this key. - * - * @name Phaser.Input.Keyboard.Key#keyCode - * @type {number} - * @since 3.0.0 - */ - this.keyCode = keyCode; +/** + * The File Load Event. + * + * This event is dispatched by the Loader Plugin when a file finishes loading, + * but _before_ it is processed and added to the internal Phaser caches. + * + * Listen to it from a Scene using: `this.load.on('load', listener)`. + * + * @event Phaser.Loader.Events#FILE_LOAD + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Loader.File} file - A reference to the File which just finished loading. + */ +module.exports = 'load'; - /** - * 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; +/***/ 74693: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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 File Load Progress Event. + * + * This event is dispatched by the Loader Plugin during the load of a file, if the browser receives a DOM ProgressEvent and + * the `lengthComputable` event property is true. Depending on the size of the file and browser in use, this may, or may not happen. + * + * Listen to it from a Scene using: `this.load.on('fileprogress', listener)`. + * + * @event Phaser.Loader.Events#FILE_PROGRESS + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Loader.File} file - A reference to the File which errored during load. + * @param {number} percentComplete - A value between 0 and 1 indicating how 'complete' this file is. + */ +module.exports = 'fileprogress'; - /** - * 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; +/***/ 71176: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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 Loader Plugin Post Process Event. + * + * This event is dispatched by the Loader Plugin when the Loader has finished loading everything in the load queue. + * It is dispatched before the internal lists are cleared and each File is destroyed. + * + * Use this hook to perform any last minute processing of files that can only happen once the + * Loader has completed, but prior to it emitting the `complete` event. + * + * Listen to it from a Scene using: `this.load.on('postprocess', listener)`. + * + * @event Phaser.Loader.Events#POST_PROCESS + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event. + */ +module.exports = 'postprocess'; - /** - * 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; +/***/ 88984: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +/** + * The Loader Plugin Progress Event. + * + * This event is dispatched when the Loader updates its load progress, typically as a result of a file having completed loading. + * + * Listen to it from a Scene using: `this.load.on('progress', listener)`. + * + * @event Phaser.Loader.Events#PROGRESS + * @type {string} + * @since 3.0.0 + * + * @param {number} progress - The current progress of the load. A value between 0 and 1. + */ +module.exports = 'progress'; - /** - * 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; +/***/ 72753: +/***/ ((module) => { - 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; - - -/***/ }), -/* 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__(154); -var GetFastValue = __webpack_require__(2); -var ProcessKeyCombo = __webpack_require__(514); -var ResetKeyCombo = __webpack_require__(516); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ /** - * @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 }); + * The Loader Plugin Start Event. * - * this.input.keyboard.on('keycombomatch', function (event) { - * console.log('Konami Code entered!'); - * }); - * ``` + * This event is dispatched when the Loader starts running. At this point load progress is zero. * - * Or, to listen for the user entering the word PHASER: + * This event is dispatched even if there aren't any files in the load queue. * - * ```javascript - * this.input.keyboard.createCombo('PHASER'); - * ``` + * Listen to it from a Scene using: `this.load.on('start', listener)`. * - * @class KeyCombo - * @memberof Phaser.Input.Keyboard - * @constructor - * @listens Phaser.Input.Keyboard.Events#ANY_KEY_DOWN + * @event Phaser.Loader.Events#START + * @type {string} * @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. + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event. */ -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; +module.exports = 'start'; /***/ }), -/* 514 */ -/***/ (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__(515); - -/** - * 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; - - -/***/ }), -/* 515 */ -/***/ (function(module, exports) { +/***/ 683: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * @namespace Phaser.Loader.Events */ -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; +module.exports = { -/***/ }), -/* 516 */ -/***/ (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; + ADD: __webpack_require__(7398), + COMPLETE: __webpack_require__(52187), + FILE_COMPLETE: __webpack_require__(36627), + FILE_KEY_COMPLETE: __webpack_require__(81925), + FILE_LOAD_ERROR: __webpack_require__(29774), + FILE_LOAD: __webpack_require__(20943), + FILE_PROGRESS: __webpack_require__(74693), + POST_PROCESS: __webpack_require__(71176), + PROGRESS: __webpack_require__(88984), + START: __webpack_require__(72753) - return combo; }; -module.exports = ResetKeyCombo; - /***/ }), -/* 517 */ -/***/ (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__(240); - -/** - * 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; - -/***/ }), -/* 518 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 46468: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var HTML5AudioFile = __webpack_require__(519); -var IsPlainObject = __webpack_require__(7); +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var JSONFile = __webpack_require__(70806); +var LoaderEvents = __webpack_require__(683); /** * @classdesc - * A single Audio File suitable for loading by the Loader. + * A single Animation JSON 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. + * These are created when you use the Phaser.Loader.LoaderPlugin#animation method and are not typically created directly. * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audio. + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#animation. * - * @class AudioFile + * @class AnimationJSONFile * @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 {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig)} 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 `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". * @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. + * @param {string} [dataKey] - When the JSON file loads only this property will be stored in the Cache. */ -var AudioFile = new Class({ +var AnimationJSONFile = new Class({ - Extends: File, + Extends: JSONFile, 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); - } + // 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 - var fileConfig = { - type: 'audio', - cache: loader.cacheManager.audio, - extension: urlConfig.type, - responseType: 'arraybuffer', - key: key, - url: urlConfig.url, - xhrSettings: xhrSettings, - config: { context: audioContext } - }; + function AnimationJSONFile (loader, key, url, xhrSettings, dataKey) + { + JSONFile.call(this, loader, key, url, xhrSettings, dataKey); - File.call(this, loader, fileConfig); + this.type = 'animationJSON'; }, /** * 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 + * @method Phaser.Loader.FileTypes.AnimationJSONFile#onProcess + * @since 3.7.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); - } -}; + // We need to hook into this event: + this.loader.once(LoaderEvents.POST_PROCESS, this.onLoadComplete, this); -AudioFile.getAudioURL = function (game, urls) -{ - if (!Array.isArray(urls)) - { - urls = [ urls ]; - } + // But the rest is the same as a normal JSON file + JSONFile.prototype.onProcess.call(this); + }, - for (var i = 0; i < urls.length; i++) + /** + * Called at the end of the load process, after the Loader has finished all files in its queue. + * + * @method Phaser.Loader.FileTypes.AnimationJSONFile#onLoadComplete + * @since 3.7.0 + */ + onLoadComplete: function () { - 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 - }; - } + this.loader.systems.anims.fromJSON(this.data); } - return null; -}; +}); /** - * Adds an Audio or HTML5Audio file, or array of audio files, to the current load queue. + * Adds an Animation JSON Data file, or array of Animation 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.audio('title', [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ]); + * this.load.animation('baddieAnims', 'files/BaddieAnims.json'); * } * ``` * @@ -123130,392 +119415,500 @@ AudioFile.getAudioURL = function (game, urls) * 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. + * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring + * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. + * + * 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 Audio Cache first, before loading a new one. + * 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.audio({ - * key: 'title', - * url: [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ] + * this.load.animation({ + * key: 'baddieAnims', + * url: 'files/BaddieAnims.json' * }); * ``` * - * See the documentation for `Phaser.Types.Loader.FileTypes.AudioFileConfig` for more details. + * See the documentation for `Phaser.Types.Loader.FileTypes.JSONFileConfig` 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. + * Once the file has finished loading it will automatically be passed to the global Animation Managers `fromJSON` method. + * This will parse all of the JSON data and create animation data from it. This process happens at the very end + * of the Loader, once every other file in the load queue has finished. The reason for this is to allow you to load + * both animation data and the images it relies upon in the same load call. * - * 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. + * Once the animation data has been parsed you will be able to play animations using that data. + * Please see the Animation Manager `fromJSON` method for more details about the format and playback. * - * 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. + * You can also access the raw animation data from its Cache using its key: * - * Note: The ability to load this type of file will only be available if the Audio File type has been built into Phaser. + * ```javascript + * this.load.animation('baddieAnims', 'files/BaddieAnims.json'); + * // and later in your game ... + * var data = this.cache.json.get('baddieAnims'); + * ``` + * + * 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 if you only wanted to create animations from the `boss` data, 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#audio + * @method Phaser.Loader.LoaderPlugin#animation * @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 {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig|Phaser.Types.Loader.FileTypes.JSONFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string} [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". + * @param {string} [dataKey] - When the Animation JSON file loads only this property will be stored in the Cache and used to create animation data. * @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) +FileTypesManager.register('animation', function (key, url, dataKey, 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; + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined 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); - } + this.addFile(new AnimationJSONFile(this, key[i])); } } else { - audioFile = AudioFile.create(this, key, urls, config, xhrSettings); - - if (audioFile) - { - this.addFile(audioFile); - } + this.addFile(new AnimationJSONFile(this, key, url, xhrSettings, dataKey)); } return this; }); -module.exports = AudioFile; +module.exports = AnimationJSONFile; /***/ }), -/* 519 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 31648: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Events = __webpack_require__(95); -var File = __webpack_require__(23); -var GetFastValue = __webpack_require__(2); -var GetURL = __webpack_require__(155); -var IsPlainObject = __webpack_require__(7); +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var ImageFile = __webpack_require__(42927); +var IsPlainObject = __webpack_require__(42911); +var JSONFile = __webpack_require__(70806); +var MultiFile = __webpack_require__(45176); /** * @classdesc - * A single Audio File suitable for loading by the Loader. + * A single JSON based Texture Atlas 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. + * These are created when you use the Phaser.Loader.LoaderPlugin#atlas method and are not typically created directly. * - * @class HTML5AudioFile - * @extends Phaser.Loader.File + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#atlas. + * + * https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?source=photonstorm + * + * @class AsepriteFile + * @extends Phaser.Loader.MultiFile * @memberof Phaser.Loader.FileTypes * @constructor - * @since 3.0.0 + * @since 3.50.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. + * @param {(string|Phaser.Types.Loader.FileTypes.AsepriteFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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, a well formed JSON object. + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. */ -var HTML5AudioFile = new Class({ +var AsepriteFile = new Class({ - Extends: File, + Extends: MultiFile, initialize: - function HTML5AudioFile (loader, key, urlConfig, audioConfig) + function AsepriteFile (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) { + var image; + var data; + 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; - }, + image = new ImageFile(loader, { + key: key, + url: GetFastValue(config, 'textureURL'), + extension: GetFastValue(config, 'textureExtension', 'png'), + normalMap: GetFastValue(config, 'normalMap'), + xhrSettings: GetFastValue(config, 'textureXhrSettings') + }); - /** - * Called when the file finishes loading. - * - * @method Phaser.Loader.FileTypes.HTML5AudioFile#onLoad - * @since 3.0.0 - */ - onLoad: function () - { - if (this.loaded) + data = new JSONFile(loader, { + key: key, + url: GetFastValue(config, 'atlasURL'), + extension: GetFastValue(config, 'atlasExtension', 'json'), + xhrSettings: GetFastValue(config, 'atlasXhrSettings') + }); + } + else { - return; + image = new ImageFile(loader, key, textureURL, textureXhrSettings); + data = new JSONFile(loader, key, atlasURL, atlasXhrSettings); } - 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++) + if (image.linkFile) { - var audio = this.data[i]; - - audio.oncanplaythrough = null; - audio.onerror = null; + // Image has a normal map + MultiFile.call(this, loader, 'atlasjson', key, [ image, data, image.linkFile ]); + } + else + { + MultiFile.call(this, loader, 'atlasjson', key, [ image, data ]); } - - this.loader.nextFile(this, false); }, /** - * Called during the file load progress. Is sent a DOM ProgressEvent. + * Adds this file to its target cache upon successful loading and processing. * - * @method Phaser.Loader.FileTypes.HTML5AudioFile#onProgress - * @fires Phaser.Loader.Events#FILE_PROGRESS - * @since 3.0.0 + * @method Phaser.Loader.FileTypes.AsepriteFile#addToCache + * @since 3.7.0 */ - onProgress: function (event) + addToCache: function () { - var audio = event.target; + if (this.isReadyToProcess()) + { + var image = this.files[0]; + var json = this.files[1]; + var normalMap = (this.files[2]) ? this.files[2].data : null; - audio.oncanplaythrough = null; - audio.onerror = null; + this.loader.textureManager.addAtlas(image.key, image.data, json.data, normalMap); - this.filesLoaded++; + json.addToCache(); - 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(); + this.complete = true; } - }, - - /** - * 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); - } +/** + * Aseprite is a powerful animated sprite editor and pixel art tool. + * + * You can find more details at https://www.aseprite.org/ + * + * Adds a JSON based Aseprite Animation, or array of animations, 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.aseprite('gladiator', 'images/Gladiator.png', 'images/Gladiator.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. + * + * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring + * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. + * + * To export a compatible JSON file in Aseprite, please do the following: + * + * 1. Go to "File - Export Sprite Sheet" + * + * 2. On the **Layout** tab: + * 2a. Set the "Sheet type" to "Packed" + * 2b. Set the "Constraints" to "None" + * 2c. Check the "Merge Duplicates" checkbox + * + * 3. On the **Sprite** tab: + * 3a. Set "Layers" to "Visible layers" + * 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags + * + * 4. On the **Borders** tab: + * 4a. Check the "Trim Sprite" and "Trim Cells" options + * 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough) + * + * 5. On the **Output** tab: + * 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type + * 5b. Check "JSON Data" and give your json file a name + * 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind. + * 5d. Make sure "Tags" is checked in the Meta options + * 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more. + * + * 6. Click export + * + * This was tested with Aseprite 1.2.25. + * + * This will export a png and json file which you can load using the Aseprite Loader, i.e.: + * + * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. + * + * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.aseprite({ + * key: 'gladiator', + * textureURL: 'images/Gladiator.png', + * atlasURL: 'images/Gladiator.json' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.AsepriteFileConfig` for more details. + * + * Instead of passing a URL for the JSON data you can also pass in a well formed JSON object instead. + * + * Once loaded, you can call this method from within a Scene with the 'atlas' key: + * + * ```javascript + * this.anims.createFromAseprite('paladin'); + * ``` + * + * Any animations defined in the JSON will now be available to use in Phaser and you play them + * via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline, + * you can play it in Phaser using that Tag name: + * + * ```javascript + * this.add.sprite(400, 300).play('War Cry'); + * ``` + * + * When calling this method you can optionally provide an array of tag names, and only those animations + * will be created. For example: + * + * ```javascript + * this.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]); + * ``` + * + * This will only create the 3 animations defined. Note that the tag names are case-sensitive. + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use to retrieve the image from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" + * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Note: The ability to load this type of file will only be available if the Aseprite 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#aseprite + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.50.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.AsepriteFileConfig|Phaser.Types.Loader.FileTypes.AsepriteFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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, a well formed JSON object. + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. + * + * @return {this} The Loader instance. + */ +FileTypesManager.register('aseprite', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) +{ + var multifile; - this.data.push(audio); - } + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined - for (i = 0; i < this.data.length; i++) + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) { - audio = this.data[i]; - audio.src = GetURL(this, this.loader.baseURL); + multifile = new AsepriteFile(this, key[i]); - if (!this.locked) - { - audio.load(); - } + this.addFile(multifile.files); } + } + else + { + multifile = new AsepriteFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); - if (this.locked) - { - // This is super-dangerous but works. Race condition potential high. - // Is there another way? - setTimeout(this.onLoad.bind(this)); - } + this.addFile(multifile.files); } + return this; }); -module.exports = HTML5AudioFile; +module.exports = AsepriteFile; /***/ }), -/* 520 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 73152: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var ImageFile = __webpack_require__(42927); +var IsPlainObject = __webpack_require__(42911); +var JSONFile = __webpack_require__(70806); +var MultiFile = __webpack_require__(45176); /** * @classdesc - * A single Script File suitable for loading by the Loader. + * A single JSON based Texture Atlas 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. + * These are created when you use the Phaser.Loader.LoaderPlugin#atlas method and are not typically created directly. * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#script. + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#atlas. * - * @class ScriptFile - * @extends Phaser.Loader.File + * https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?source=photonstorm + * + * @class AtlasJSONFile + * @extends Phaser.Loader.MultiFile * @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. + * @param {(string|Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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, a well formed JSON object. + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. */ -var ScriptFile = new Class({ +var AtlasJSONFile = new Class({ - Extends: File, + Extends: MultiFile, initialize: - function ScriptFile (loader, key, url, xhrSettings) + function AtlasJSONFile (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) { - var extension = 'js'; + var image; + var data; 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 - }; + image = new ImageFile(loader, { + key: key, + url: GetFastValue(config, 'textureURL'), + extension: GetFastValue(config, 'textureExtension', 'png'), + normalMap: GetFastValue(config, 'normalMap'), + xhrSettings: GetFastValue(config, 'textureXhrSettings') + }); - File.call(this, loader, fileConfig); + data = new JSONFile(loader, { + key: key, + url: GetFastValue(config, 'atlasURL'), + extension: GetFastValue(config, 'atlasExtension', 'json'), + xhrSettings: GetFastValue(config, 'atlasXhrSettings') + }); + } + else + { + image = new ImageFile(loader, key, textureURL, textureXhrSettings); + data = new JSONFile(loader, key, atlasURL, atlasXhrSettings); + } + + if (image.linkFile) + { + // Image has a normal map + MultiFile.call(this, loader, 'atlasjson', key, [ image, data, image.linkFile ]); + } + else + { + MultiFile.call(this, loader, 'atlasjson', key, [ image, data ]); + } }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * Adds this file to its target cache upon successful loading and processing. * - * @method Phaser.Loader.FileTypes.ScriptFile#onProcess + * @method Phaser.Loader.FileTypes.AtlasJSONFile#addToCache * @since 3.7.0 */ - onProcess: function () + addToCache: 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; + if (this.isReadyToProcess()) + { + var image = this.files[0]; + var json = this.files[1]; + var normalMap = (this.files[2]) ? this.files[2].data : null; - document.head.appendChild(this.data); + this.loader.textureManager.addAtlas(image.key, image.data, json.data, normalMap); - this.onProcessComplete(); + this.complete = true; + } } }); /** - * Adds a Script file, or array of Script files, to the current load queue. + * Adds a JSON based Texture Atlas, or array of atlases, 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'); + * this.load.atlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.json'); * } * ``` * @@ -123527,5863 +119920,25704 @@ var ScriptFile = new Class({ * 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. + * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring + * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. + * + * Phaser expects the atlas data to be provided in a JSON file, using either the JSON Hash or JSON Array format. + * + * These files are created by software such as: + * + * * [Texture Packer](https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?source=photonstorm) + * * [Shoebox](https://renderhjs.net/shoebox/) + * * [Gamma Texture Packer](https://gammafp.com/tool/atlas-packer/) + * * [Adobe Flash / Animate](https://www.adobe.com/uk/products/animate.html) + * * [Free Texture Packer](http://free-tex-packer.com/) + * * [Leshy SpriteSheet Tool](https://www.leshylabs.com/apps/sstool/) + * + * If you are using Texture Packer and have enabled multi-atlas support, then please use the Phaser Multi Atlas loader + * instead of this one. + * + * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. + * + * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. * * Instead of passing arguments you can pass a configuration object, such as: * * ```javascript - * this.load.script({ - * key: 'aliens', - * url: 'lib/aliens.js' + * this.load.atlas({ + * key: 'mainmenu', + * textureURL: 'images/MainMenu.png', + * atlasURL: 'images/MainMenu.json' * }); * ``` * - * See the documentation for `Phaser.Types.Loader.FileTypes.ScriptFileConfig` for more details. + * See the documentation for `Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig` 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. + * Instead of passing a URL for the atlas JSON data you can also pass in a well formed JSON object instead. + * + * Once the atlas has finished loading you can use frames from it as textures for a Game Object by referencing its key: + * + * ```javascript + * this.load.atlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.json'); + * // and later in your game ... + * this.add.image(x, y, 'mainmenu', 'background'); + * ``` + * + * To get a list of all available frames within an atlas please consult your Texture Atlas software. + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use to retrieve the image from the Texture Manager. * * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. * * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.js". It will always add `.js` as the extension, although + * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. * - * Note: The ability to load this type of file will only be available if the Script File type has been built into Phaser. + * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, + * then you can specify it by providing an array as the `url` where the second element is the normal map: + * + * ```javascript + * this.load.atlas('mainmenu', [ 'images/MainMenu.png', 'images/MainMenu-n.png' ], 'images/MainMenu.json'); + * ``` + * + * Or, if you are using a config object use the `normalMap` property: + * + * ```javascript + * this.load.atlas({ + * key: 'mainmenu', + * textureURL: 'images/MainMenu.png', + * normalMap: 'images/MainMenu-n.png', + * atlasURL: 'images/MainMenu.json' + * }); + * ``` + * + * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. + * Normal maps are a WebGL only feature. + * + * Note: The ability to load this type of file will only be available if the Atlas 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#script + * @method Phaser.Loader.LoaderPlugin#atlas * @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. + * @param {(string|Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig|Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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, a well formed JSON object. + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. * * @return {this} The Loader instance. */ -FileTypesManager.register('script', function (key, url, xhrSettings) +FileTypesManager.register('atlas', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) { + var multifile; + + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined + 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])); + multifile = new AtlasJSONFile(this, key[i]); + + this.addFile(multifile.files); } } else { - this.addFile(new ScriptFile(this, key, url, xhrSettings)); + multifile = new AtlasJSONFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); + + this.addFile(multifile.files); } return this; }); -module.exports = ScriptFile; +module.exports = AtlasJSONFile; /***/ }), -/* 521 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 24616: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArcadeImage = __webpack_require__(522); -var ArcadeSprite = __webpack_require__(157); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(62); -var PhysicsGroup = __webpack_require__(524); -var StaticPhysicsGroup = __webpack_require__(525); +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var ImageFile = __webpack_require__(42927); +var IsPlainObject = __webpack_require__(42911); +var MultiFile = __webpack_require__(45176); +var XMLFile = __webpack_require__(15297); /** * @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. + * A single XML based Texture Atlas File suitable for loading by the Loader. * - * @class Factory - * @memberof Phaser.Physics.Arcade + * These are created when you use the Phaser.Loader.LoaderPlugin#atlasXML method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#atlasXML. + * + * @class AtlasXMLFile + * @extends Phaser.Loader.MultiFile + * @memberof Phaser.Loader.FileTypes * @constructor - * @since 3.0.0 + * @since 3.7.0 * - * @param {Phaser.Physics.Arcade.World} world - The Arcade Physics World instance. + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas xml file. Used in replacement of the Loaders default XHR Settings. */ -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; +var AtlasXMLFile = new Class({ - this.world.enableBody(gameObject, type); + Extends: MultiFile, - return gameObject; - }, + initialize: - /** - * 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) + function AtlasXMLFile (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) { - var image = new ArcadeImage(this.scene, x, y, key, frame); - - this.sys.displayList.add(image); - - this.world.enableBody(image, CONST.STATIC_BODY); + var image; + var data; - return image; - }, + if (IsPlainObject(key)) + { + var config = key; - /** - * 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); + key = GetFastValue(config, 'key'); - this.sys.displayList.add(image); + image = new ImageFile(loader, { + key: key, + url: GetFastValue(config, 'textureURL'), + extension: GetFastValue(config, 'textureExtension', 'png'), + normalMap: GetFastValue(config, 'normalMap'), + xhrSettings: GetFastValue(config, 'textureXhrSettings') + }); - this.world.enableBody(image, CONST.DYNAMIC_BODY); + data = new XMLFile(loader, { + key: key, + url: GetFastValue(config, 'atlasURL'), + extension: GetFastValue(config, 'atlasExtension', 'xml'), + xhrSettings: GetFastValue(config, 'atlasXhrSettings') + }); + } + else + { + image = new ImageFile(loader, key, textureURL, textureXhrSettings); + data = new XMLFile(loader, key, atlasURL, atlasXhrSettings); + } - return image; + if (image.linkFile) + { + // Image has a normal map + MultiFile.call(this, loader, 'atlasxml', key, [ image, data, image.linkFile ]); + } + else + { + MultiFile.call(this, loader, 'atlasxml', key, [ image, data ]); + } }, /** - * 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. + * Adds this file to its target cache upon successful loading and processing. * - * @return {Phaser.Types.Physics.Arcade.SpriteWithStaticBody} The Sprite object that was created. + * @method Phaser.Loader.FileTypes.AtlasXMLFile#addToCache + * @since 3.7.0 */ - staticSprite: function (x, y, key, frame) + addToCache: function () { - 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); + if (this.isReadyToProcess()) + { + var image = this.files[0]; + var xml = this.files[1]; + var normalMap = (this.files[2]) ? this.files[2].data : null; - return sprite; - }, + this.loader.textureManager.addAtlasXML(image.key, image.data, xml.data, normalMap); - /** - * 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.complete = true; + } + } - this.sys.displayList.add(sprite); - this.sys.updateList.add(sprite); +}); - this.world.enableBody(sprite, CONST.DYNAMIC_BODY); +/** + * Adds an XML based Texture Atlas, or array of atlases, 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.atlasXML('mainmenu', 'images/MainMenu.png', 'images/MainMenu.xml'); + * } + * ``` + * + * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, + * or if it's already running, when the next free load slot becomes available. This happens automatically if you + * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued + * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. + * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the + * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been + * loaded. + * + * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring + * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. + * + * Phaser expects the atlas data to be provided in an XML file format. + * These files are created by software such as Shoebox and Adobe Flash / Animate. + * + * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. + * + * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.atlasXML({ + * key: 'mainmenu', + * textureURL: 'images/MainMenu.png', + * atlasURL: 'images/MainMenu.xml' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig` for more details. + * + * Once the atlas has finished loading you can use frames from it as textures for a Game Object by referencing its key: + * + * ```javascript + * this.load.atlasXML('mainmenu', 'images/MainMenu.png', 'images/MainMenu.xml'); + * // and later in your game ... + * this.add.image(x, y, 'mainmenu', 'background'); + * ``` + * + * To get a list of all available frames within an atlas please consult your Texture Atlas software. + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use to retrieve the image from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" + * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, + * then you can specify it by providing an array as the `url` where the second element is the normal map: + * + * ```javascript + * this.load.atlasXML('mainmenu', [ 'images/MainMenu.png', 'images/MainMenu-n.png' ], 'images/MainMenu.xml'); + * ``` + * + * Or, if you are using a config object use the `normalMap` property: + * + * ```javascript + * this.load.atlasXML({ + * key: 'mainmenu', + * textureURL: 'images/MainMenu.png', + * normalMap: 'images/MainMenu-n.png', + * atlasURL: 'images/MainMenu.xml' + * }); + * ``` + * + * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. + * Normal maps are a WebGL only feature. + * + * Note: The ability to load this type of file will only be available if the Atlas XML 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#atlasXML + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.7.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig|Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas xml file. Used in replacement of the Loaders default XHR Settings. + * + * @return {this} The Loader instance. + */ +FileTypesManager.register('atlasXML', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) +{ + var multifile; - return sprite; - }, + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined - /** - * 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) + if (Array.isArray(key)) { - return this.sys.updateList.add(new StaticPhysicsGroup(this.world, this.world.scene, children, config)); - }, + for (var i = 0; i < key.length; i++) + { + multifile = new AtlasXMLFile(this, key[i]); - /** - * 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) + this.addFile(multifile.files); + } + } + else { - return this.sys.updateList.add(new PhysicsGroup(this.world, this.world.scene, children, config)); - }, + multifile = new AtlasXMLFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); - /** - * Destroys this Factory. - * - * @method Phaser.Physics.Arcade.Factory#destroy - * @since 3.5.0 - */ - destroy: function () - { - this.world = null; - this.scene = null; - this.sys = null; + this.addFile(multifile.files); } + return this; }); -module.exports = Factory; +module.exports = AtlasXMLFile; /***/ }), -/* 522 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 67448: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Components = __webpack_require__(243); -var Image = __webpack_require__(125); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var HTML5AudioFile = __webpack_require__(30929); +var IsPlainObject = __webpack_require__(42911); /** * @classdesc - * An Arcade Physics Image is an Image with an Arcade Physics body and related components. - * The body can be dynamic or static. + * A single Audio File suitable for loading by the Loader. * - * The main difference between an Arcade Image and an Arcade Sprite is that you cannot animate an Arcade Image. + * These are created when you use the Phaser.Loader.LoaderPlugin#audio method and are not typically created directly. * - * @class Image - * @extends Phaser.GameObjects.Image - * @memberof Phaser.Physics.Arcade + * 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 * - * @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. + * @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 {Phaser.Types.Loader.FileTypes.AudioFileURLConfig} [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 ArcadeImage = new Class({ - - Extends: Image, +var AudioFile = new Class({ - 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 - ], + Extends: File, initialize: - function ArcadeImage (scene, x, y, texture, frame) + // URL is an object created by AudioFile.findAudioURL + function AudioFile (loader, key, urlConfig, xhrSettings, audioContext) { - Image.call(this, scene, x, y, texture, frame); + if (IsPlainObject(key)) + { + var config = key; - /** - * 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; - } + 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 } + }; -module.exports = ArcadeImage; + 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; -/***/ }), -/* 523 */ -/***/ (function(module, exports, __webpack_require__) { + // interesting read https://github.com/WebAudio/web-audio-api/issues/1305 + this.config.context.decodeAudioData(this.xhrLoader.response, + function (audioBuffer) + { + _this.data = audioBuffer; -var OverlapRect = __webpack_require__(244); -var Circle = __webpack_require__(65); -var CircleToCircle = __webpack_require__(231); -var CircleToRectangle = __webpack_require__(151); + _this.onProcessComplete(); + }, + function (e) + { + // eslint-disable-next-line no-console + console.error('Error decoding audio: ' + _this.key + ' - ', e ? e.message : null); -/** - * 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) + _this.onProcessError(); + } + ); + + this.config.context = null; + } + +}); + +AudioFile.create = function (loader, key, urls, config, xhrSettings) { - var bodiesInRect = OverlapRect(world, x - radius, y - radius, 2 * radius, 2 * radius, includeDynamic, includeStatic); + var game = loader.systems.game; + var audioConfig = game.config.audio; + var deviceAudio = game.device.audio; - if (bodiesInRect.length === 0) + // url may be inside key, which may be an object + if (IsPlainObject(key)) { - return bodiesInRect; + urls = GetFastValue(key, 'url', []); + config = GetFastValue(key, 'config', {}); } - var area = new Circle(x, y, radius); - var circFromBody = new Circle(); - var bodiesInArea = []; + var urlConfig = AudioFile.getAudioURL(game, urls); - for (var i = 0; i < bodiesInRect.length; i++) + if (!urlConfig) { - var body = bodiesInRect[i]; + console.warn('No audio URLs for "%s" matched this device', key); - 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 null; } - return bodiesInArea; -}; + // https://developers.google.com/web/updates/2012/02/HTML5-audio-and-the-Web-Audio-API-are-BFFs + // var stream = GetFastValue(config, 'stream', false); -module.exports = OverlapCirc; + 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 ]; + } -/***/ }), -/* 524 */ -/***/ (function(module, exports, __webpack_require__) { + for (var i = 0; i < urls.length; i++) + { + var url = GetFastValue(urls[i], 'url', urls[i]); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + 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 + }; + } + } -var ArcadeSprite = __webpack_require__(157); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(62); -var GetFastValue = __webpack_require__(2); -var Group = __webpack_require__(113); -var IsPlainObject = __webpack_require__(7); + return null; +}; /** - * @classdesc - * An Arcade Physics Group object. + * Adds an Audio or HTML5Audio file, or array of audio files, to the current load queue. * - * 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. + * You can call this method from within your Scene's `preload`, along with any other files you wish to load: * - * 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}. + * ```javascript + * function preload () + * { + * this.load.audio('title', [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ]); + * } + * ``` * - * 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. + * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, + * or if it's already running, when the next free load slot becomes available. This happens automatically if you + * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued + * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. + * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the + * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been + * loaded. * - * If you wish to create a Group filled with Static Bodies, please see {@link Phaser.Physics.Arcade.StaticGroup}. + * 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. * - * @class Group - * @extends Phaser.GameObjects.Group - * @memberof Phaser.Physics.Arcade - * @constructor + * 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 {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. + * @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[]|Phaser.Types.Loader.FileTypes.AudioFileURLConfig|Phaser.Types.Loader.FileTypes.AudioFileURLConfig[])} [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. */ -var PhysicsGroup = new Class({ +FileTypesManager.register('audio', function (key, urls, config, xhrSettings) +{ + var game = this.systems.game; + var audioConfig = game.config.audio; + var deviceAudio = game.device.audio; - Extends: Group, + if (audioConfig.noAudio || (!deviceAudio.webAudio && !deviceAudio.audioData)) + { + // Sounds are disabled, so skip loading audio + return this; + } - initialize: + var audioFile; - function PhysicsGroup (world, scene, children, config) + if (Array.isArray(key)) { - if (!children && !config) - { - config = { - internalCreateCallback: this.createCallbackHandler, - internalRemoveCallback: this.removeCallbackHandler - }; - } - else if (IsPlainObject(children)) + for (var i = 0; i < key.length; i++) { - // children is a plain object, so swizzle them: - config = children; - children = null; + // 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]); - config.internalCreateCallback = this.createCallbackHandler; - config.internalRemoveCallback = this.removeCallbackHandler; + if (audioFile) + { + this.addFile(audioFile); + } } - else if (Array.isArray(children) && IsPlainObject(children[0])) + } + else + { + audioFile = AudioFile.create(this, key, urls, config, xhrSettings); + + if (audioFile) { - // children is an array of plain objects (i.e., configs) - config = children[0]; + this.addFile(audioFile); + } + } - var _this = this; + return this; +}); - children.forEach(function (singleConfig) - { - singleConfig.internalCreateCallback = _this.createCallbackHandler; - singleConfig.internalRemoveCallback = _this.removeCallbackHandler; - }); +module.exports = AudioFile; - 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); +/***/ 66109: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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) - }; +var AudioFile = __webpack_require__(67448); +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); +var JSONFile = __webpack_require__(70806); +var MultiFile = __webpack_require__(45176); - Group.call(this, scene, children, config); +/** + * @classdesc + * An Audio Sprite File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#audioSprite method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audioSprite. + * + * @class AudioSpriteFile + * @extends Phaser.Loader.MultiFile + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.7.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string} jsonURL - The absolute or relative URL to load the json file from. Or a well formed JSON object to use instead. + * @param {{(string|string[])}} [audioURL] - The absolute or relative URL to load the audio file from. If empty it will be obtained by parsing the JSON file. + * @param {any} [audioConfig] - The audio configuration options. + * @param {Phaser.Types.Loader.XHRSettingsObject} [audioXhrSettings] - An XHR Settings configuration object for the audio file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings. + */ +var AudioSpriteFile = new Class({ - /** - * 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'; - }, + Extends: MultiFile, - /** - * 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) + initialize: + + function AudioSpriteFile (loader, key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings) { - if (!child.body) + if (IsPlainObject(key)) { - this.world.enableBody(child, CONST.DYNAMIC_BODY); + var config = key; + + key = GetFastValue(config, 'key'); + jsonURL = GetFastValue(config, 'jsonURL'); + audioURL = GetFastValue(config, 'audioURL'); + audioConfig = GetFastValue(config, 'audioConfig'); + audioXhrSettings = GetFastValue(config, 'audioXhrSettings'); + jsonXhrSettings = GetFastValue(config, 'jsonXhrSettings'); } - var body = child.body; + var data; - for (var key in this.defaults) + // No url? then we're going to do a json load and parse it from that + if (!audioURL) { - body[key](this.defaults[key]); - } - }, + data = new JSONFile(loader, key, jsonURL, jsonXhrSettings); - /** - * 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) + MultiFile.call(this, loader, 'audiosprite', key, [ data ]); + + this.config.resourceLoad = true; + this.config.audioConfig = audioConfig; + this.config.audioXhrSettings = audioXhrSettings; + } + else { - this.world.disableBody(child); + var audio = AudioFile.create(loader, key, audioURL, audioConfig, audioXhrSettings); + + if (audio) + { + data = new JSONFile(loader, key, jsonURL, jsonXhrSettings); + + MultiFile.call(this, loader, 'audiosprite', key, [ audio, data ]); + + this.config.resourceLoad = false; + } } }, /** - * Sets the velocity of each Group member. - * - * @method Phaser.Physics.Arcade.Group#setVelocity - * @since 3.0.0 + * Called by each File when it finishes loading. * - * @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. + * @method Phaser.Loader.FileTypes.AudioSpriteFile#onFileComplete + * @since 3.7.0 * - * @return {Phaser.Physics.Arcade.Group} This Physics Group object. + * @param {Phaser.Loader.File} file - The File that has completed processing. */ - setVelocity: function (x, y, step) + onFileComplete: function (file) { - if (step === undefined) { step = 0; } - - var items = this.getChildren(); + var index = this.files.indexOf(file); - for (var i = 0; i < items.length; i++) + if (index !== -1) { - items[i].body.velocity.set(x + (i * step), y + (i * step)); - } + this.pending--; - return this; + if (this.config.resourceLoad && file.type === 'json' && file.data.hasOwnProperty('resources')) + { + // Inspect the data for the files to now load + var urls = file.data.resources; + + var audioConfig = GetFastValue(this.config, 'audioConfig'); + var audioXhrSettings = GetFastValue(this.config, 'audioXhrSettings'); + + var audio = AudioFile.create(this.loader, file.key, urls, audioConfig, audioXhrSettings); + + if (audio) + { + this.addToMultiFile(audio); + + this.loader.addFile(audio); + } + } + } }, /** - * 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. + * Adds this file to its target cache upon successful loading and processing. * - * @return {Phaser.Physics.Arcade.Group} This Physics Group object. + * @method Phaser.Loader.FileTypes.AudioSpriteFile#addToCache + * @since 3.7.0 */ - setVelocityX: function (value, step) + addToCache: function () { - if (step === undefined) { step = 0; } + if (this.isReadyToProcess()) + { + var fileA = this.files[0]; + var fileB = this.files[1]; - var items = this.getChildren(); + fileA.addToCache(); + fileB.addToCache(); - for (var i = 0; i < items.length; i++) - { - items[i].body.velocity.x = value + (i * step); + this.complete = true; } + } - 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) +/** + * Adds a JSON based Audio Sprite, or array of audio sprites, 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.audioSprite('kyobi', 'kyobi.json', [ + * 'kyobi.ogg', + * 'kyobi.mp3', + * 'kyobi.m4a' + * ]); + * } + * ``` + * + * Audio Sprites are a combination of audio files and a JSON configuration. + * The JSON follows the format of that created by https://github.com/tonistiigi/audiosprite + * + * If the JSON file includes a 'resource' object then you can let Phaser parse it and load the audio + * files automatically based on its content. To do this exclude the audio URLs from the load: + * + * ```javascript + * function preload () + * { + * this.load.audioSprite('kyobi', 'kyobi.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. + * + * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring + * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. + * + * 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.audioSprite({ + * key: 'kyobi', + * jsonURL: 'audio/Kyobi.json', + * audioURL: [ + * 'audio/Kyobi.ogg', + * 'audio/Kyobi.mp3', + * 'audio/Kyobi.m4a' + * ] + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig` for more details. + * + * Instead of passing a URL for the audio JSON data you can also pass in a well formed JSON object instead. + * + * Once the audio has finished loading you can use it create an Audio Sprite by referencing its key: + * + * ```javascript + * this.load.audioSprite('kyobi', 'kyobi.json'); + * // and later in your game ... + * var music = this.sound.addAudioSprite('kyobi'); + * music.play('title'); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use to retrieve the image from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * 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 Sprite 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#audioSprite + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig|Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig[])} key - The key to use for this file, or a file configuration object, or an array of objects. + * @param {string} jsonURL - The absolute or relative URL to load the json file from. Or a well formed JSON object to use instead. + * @param {(string|string[])} [audioURL] - The absolute or relative URL to load the audio file from. If empty it will be obtained by parsing the JSON file. + * @param {any} [audioConfig] - The audio configuration options. + * @param {Phaser.Types.Loader.XHRSettingsObject} [audioXhrSettings] - An XHR Settings configuration object for the audio file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings. + * + * @return {this} The Loader. + */ +FileTypesManager.register('audioSprite', function (key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings) +{ + var game = this.systems.game; + var gameAudioConfig = game.config.audio; + var deviceAudio = game.device.audio; + + if ((gameAudioConfig && gameAudioConfig.noAudio) || (!deviceAudio.webAudio && !deviceAudio.audioData)) { - if (step === undefined) { step = 0; } + // Sounds are disabled, so skip loading audio + return this; + } - var items = this.getChildren(); + var multifile; - for (var i = 0; i < items.length; i++) + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined + + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) { - items[i].body.velocity.y = value + (i * step); + multifile = new AudioSpriteFile(this, key[i]); + + if (multifile.files) + { + this.addFile(multifile.files); + } } + } + else + { + multifile = new AudioSpriteFile(this, key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings); - return this; + if (multifile.files) + { + this.addFile(multifile.files); + } } + return this; }); -module.exports = PhysicsGroup; - /***/ }), -/* 525 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 40612: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArcadeSprite = __webpack_require__(157); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(62); -var GetFastValue = __webpack_require__(2); -var Group = __webpack_require__(113); -var IsPlainObject = __webpack_require__(7); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); /** * @classdesc - * An Arcade Physics Static Group object. + * A single Binary File suitable for loading by the Loader. * - * All Game Objects created by or added to this Group will automatically be given static Arcade Physics bodies, if they have no body. + * These are created when you use the Phaser.Loader.LoaderPlugin#binary method and are not typically created directly. * - * Its dynamic counterpart is {@link Phaser.Physics.Arcade.Group}. + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#binary. * - * @class StaticGroup - * @extends Phaser.GameObjects.Group - * @memberof Phaser.Physics.Arcade + * @class BinaryFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes * @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. + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.BinaryFileConfig)} 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 `.bin`, i.e. if `key` was "alien" then the URL will be "alien.bin". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + * @param {any} [dataType] - Optional type to cast the binary file to once loaded. For example, `Uint8Array`. */ -var StaticPhysicsGroup = new Class({ +var BinaryFile = new Class({ - Extends: Group, + Extends: File, initialize: - function StaticPhysicsGroup (world, scene, children, config) + function BinaryFile (loader, key, url, xhrSettings, dataType) { - 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; + var extension = 'bin'; - 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])) + if (IsPlainObject(key)) { - // children is an array of plain objects - config = children; - children = null; + var config = key; - 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 - }; + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + extension = GetFastValue(config, 'extension', extension); + dataType = GetFastValue(config, 'dataType', dataType); } - /** - * 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); + var fileConfig = { + type: 'binary', + cache: loader.cacheManager.binary, + extension: extension, + responseType: 'arraybuffer', + key: key, + url: url, + xhrSettings: xhrSettings, + config: { dataType: dataType } + }; - /** - * 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'; + File.call(this, loader, fileConfig); }, /** - * 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. + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. * - * @see Phaser.Physics.Arcade.World#enableBody + * @method Phaser.Loader.FileTypes.BinaryFile#onProcess + * @since 3.7.0 */ - createCallbackHandler: function (child) + onProcess: function () { - if (!child.body) - { - this.world.enableBody(child, CONST.STATIC_BODY); - } - }, + this.state = CONST.FILE_PROCESSING; - /** - * 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); - } - }, + var ctor = this.config.dataType; - /** - * 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(); - }, + this.data = (ctor) ? new ctor(this.xhrLoader.response) : this.xhrLoader.response; - /** - * 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; + this.onProcessComplete(); + } - for (var i = 0; i < children.length; i++) +}); + +/** + * Adds a Binary file, or array of Binary 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.binary('doom', 'files/Doom.wad'); + * } + * ``` + * + * 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 Binary Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Binary 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 Binary Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.binary({ + * key: 'doom', + * url: 'files/Doom.wad', + * dataType: Uint8Array + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.BinaryFileConfig` for more details. + * + * Once the file has finished loading you can access it from its Cache using its key: + * + * ```javascript + * this.load.binary('doom', 'files/Doom.wad'); + * // and later in your game ... + * var data = this.cache.binary.get('doom'); + * ``` + * + * 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 `Data` the final key will be `LEVEL1.Data` and + * this is what you would use to retrieve the text from the Binary 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 "doom" + * and no URL is given then the Loader will set the URL to be "doom.bin". It will always add `.bin` 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 Binary 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#binary + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.BinaryFileConfig|Phaser.Types.Loader.FileTypes.BinaryFileConfig[])} 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 `.bin`, i.e. if `key` was "alien" then the URL will be "alien.bin". + * @param {any} [dataType] - Optional type to cast the binary file to once loaded. For example, `Uint8Array`. + * @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('binary', function (key, url, dataType, xhrSettings) +{ + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) { - children[i].body.reset(); + // 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 BinaryFile(this, key[i])); } - - return this; + } + else + { + this.addFile(new BinaryFile(this, key, url, xhrSettings, dataType)); } + return this; }); -module.exports = StaticPhysicsGroup; +module.exports = BinaryFile; /***/ }), -/* 526 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 54565: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AngleBetweenPoints = __webpack_require__(350); -var Body = __webpack_require__(527); -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var Collider = __webpack_require__(528); -var CONST = __webpack_require__(62); -var DistanceBetween = __webpack_require__(50); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(245); -var FuzzyEqual = __webpack_require__(124); -var FuzzyGreaterThan = __webpack_require__(354); -var FuzzyLessThan = __webpack_require__(355); -var GetOverlapX = __webpack_require__(246); -var GetOverlapY = __webpack_require__(247); -var GetTilesWithinWorldXY = __webpack_require__(529); -var GetValue = __webpack_require__(6); -var MATH_CONST = __webpack_require__(14); -var ProcessQueue = __webpack_require__(211); -var ProcessTileCallbacks = __webpack_require__(530); -var Rectangle = __webpack_require__(10); -var RTree = __webpack_require__(531); -var SeparateTile = __webpack_require__(532); -var SeparateX = __webpack_require__(537); -var SeparateY = __webpack_require__(538); -var Set = __webpack_require__(149); -var StaticBody = __webpack_require__(539); -var TileIntersectsBody = __webpack_require__(248); -var TransformMatrix = __webpack_require__(25); -var Vector2 = __webpack_require__(3); -var Wrap = __webpack_require__(68); +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var ImageFile = __webpack_require__(42927); +var IsPlainObject = __webpack_require__(42911); +var MultiFile = __webpack_require__(45176); +var ParseXMLBitmapFont = __webpack_require__(31476); +var XMLFile = __webpack_require__(15297); /** * @classdesc - * The Arcade Physics World. + * A single Bitmap Font based File suitable for loading by the Loader. * - * The World is responsible for creating, managing, colliding and updating all of the bodies within it. + * These are created when you use the Phaser.Loader.LoaderPlugin#bitmapFont method and are not typically created directly. * - * An instance of the World belongs to a Phaser.Scene and is accessed via the property `physics.world`. + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#bitmapFont. * - * @class World - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Physics.Arcade + * @class BitmapFontFile + * @extends Phaser.Loader.MultiFile + * @memberof Phaser.Loader.FileTypes * @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. + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.BitmapFontFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the font image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {string} [fontDataURL] - The absolute or relative URL to load the font xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the font image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [fontDataXhrSettings] - An XHR Settings configuration object for the font data xml file. Used in replacement of the Loaders default XHR Settings. */ -var World = new Class({ +var BitmapFontFile = new Class({ - Extends: EventEmitter, + Extends: MultiFile, initialize: - function World (scene, config) + function BitmapFontFile (loader, key, textureURL, fontDataURL, textureXhrSettings, fontDataXhrSettings) { - EventEmitter.call(this); + var image; + var data; - /** - * The Scene this simulation belongs to. - * - * @name Phaser.Physics.Arcade.World#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; + if (IsPlainObject(key)) + { + var config = key; - /** - * Dynamic Bodies in this simulation. - * - * @name Phaser.Physics.Arcade.World#bodies - * @type {Phaser.Structs.Set.} - * @since 3.0.0 - */ - this.bodies = new Set(); + key = GetFastValue(config, 'key'); - /** - * Static Bodies in this simulation. - * - * @name Phaser.Physics.Arcade.World#staticBodies - * @type {Phaser.Structs.Set.} - * @since 3.0.0 - */ - this.staticBodies = new Set(); + image = new ImageFile(loader, { + key: key, + url: GetFastValue(config, 'textureURL'), + extension: GetFastValue(config, 'textureExtension', 'png'), + normalMap: GetFastValue(config, 'normalMap'), + xhrSettings: GetFastValue(config, 'textureXhrSettings') + }); - /** - * 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(); + data = new XMLFile(loader, { + key: key, + url: GetFastValue(config, 'fontDataURL'), + extension: GetFastValue(config, 'fontDataExtension', 'xml'), + xhrSettings: GetFastValue(config, 'fontDataXhrSettings') + }); + } + else + { + image = new ImageFile(loader, key, textureURL, textureXhrSettings); + data = new XMLFile(loader, key, fontDataURL, fontDataXhrSettings); + } - /** - * This simulation's collision processors. - * - * @name Phaser.Physics.Arcade.World#colliders - * @type {Phaser.Structs.ProcessQueue.} - * @since 3.0.0 - */ - this.colliders = new ProcessQueue(); + if (image.linkFile) + { + // Image has a normal map + MultiFile.call(this, loader, 'bitmapfont', key, [ image, data, image.linkFile ]); + } + else + { + MultiFile.call(this, loader, 'bitmapfont', key, [ image, data ]); + } + }, - /** - * 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)); + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.BitmapFontFile#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + if (this.isReadyToProcess()) + { + var image = this.files[0]; + var xml = this.files[1]; - /** - * 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) - ); + image.addToCache(); - /** - * 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) - }; + var texture = image.cache.get(image.key); - /** - * 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); + var data = ParseXMLBitmapFont(xml.data, image.cache.getFrame(image.key), 0, 0, texture); - /** - * 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); + this.loader.cacheManager.bitmapFont.add(image.key, { data: data, texture: image.key, frame: null }); - /** - * 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; + this.complete = true; + } + } - /** - * 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; +/** + * Adds an XML based Bitmap Font, or array of fonts, 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: - /** - * 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); + * ```javascript + * function preload () + * { + * this.load.bitmapFont('goldenFont', 'images/GoldFont.png', 'images/GoldFont.xml'); + * } + * ``` + * + * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, + * or if it's already running, when the next free load slot becomes available. This happens automatically if you + * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued + * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. + * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the + * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been + * loaded. + * + * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring + * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. + * + * Phaser expects the font data to be provided in an XML file format. + * These files are created by software such as the [Angelcode Bitmap Font Generator](http://www.angelcode.com/products/bmfont/), + * [Littera](http://kvazars.com/littera/) or [Glyph Designer](https://71squared.com/glyphdesigner) + * + * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. + * + * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.bitmapFont({ + * key: 'goldenFont', + * textureURL: 'images/GoldFont.png', + * fontDataURL: 'images/GoldFont.xml' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.BitmapFontFileConfig` for more details. + * + * Once the atlas has finished loading you can use key of it when creating a Bitmap Text Game Object: + * + * ```javascript + * this.load.bitmapFont('goldenFont', 'images/GoldFont.png', 'images/GoldFont.xml'); + * // and later in your game ... + * this.add.bitmapText(x, y, 'goldenFont', 'Hello World'); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use when creating a Bitmap Text object. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" + * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, + * then you can specify it by providing an array as the `url` where the second element is the normal map: + * + * ```javascript + * this.load.bitmapFont('goldenFont', [ 'images/GoldFont.png', 'images/GoldFont-n.png' ], 'images/GoldFont.xml'); + * ``` + * + * Or, if you are using a config object use the `normalMap` property: + * + * ```javascript + * this.load.bitmapFont({ + * key: 'goldenFont', + * textureURL: 'images/GoldFont.png', + * normalMap: 'images/GoldFont-n.png', + * fontDataURL: 'images/GoldFont.xml' + * }); + * ``` + * + * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. + * Normal maps are a WebGL only feature. + * + * Note: The ability to load this type of file will only be available if the Bitmap Font 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#bitmapFont + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.BitmapFontFileConfig|Phaser.Types.Loader.FileTypes.BitmapFontFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the font image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {string} [fontDataURL] - The absolute or relative URL to load the font xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the font image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [fontDataXhrSettings] - An XHR Settings configuration object for the font data xml file. Used in replacement of the Loaders default XHR Settings. + * + * @return {this} The Loader instance. + */ +FileTypesManager.register('bitmapFont', function (key, textureURL, fontDataURL, textureXhrSettings, fontDataXhrSettings) +{ + var multifile; - /** - * 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); + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined - /** - * 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); + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + multifile = new BitmapFontFile(this, key[i]); - /** - * 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); + this.addFile(multifile.files); + } + } + else + { + multifile = new BitmapFontFile(this, key, textureURL, fontDataURL, textureXhrSettings, fontDataXhrSettings); - /** - * 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); + this.addFile(multifile.files); + } - /** - * Temporary total of colliding Bodies. - * - * @name Phaser.Physics.Arcade.World#_total - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._total = 0; + return this; +}); - /** - * Enables the debug display. - * - * @name Phaser.Physics.Arcade.World#drawDebug - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.drawDebug = GetValue(config, 'debug', false); +module.exports = BitmapFontFile; - /** - * 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); +/***/ 99898: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); - /** - * 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); +/** + * @classdesc + * A single CSS File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#css method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#css. + * + * @class CSSFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.17.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.CSSFileConfig)} 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 CSSFile = new Class({ - /** - * 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 }; + Extends: File, - /** - * 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(); + initialize: - /** - * 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(); + function CSSFile (loader, key, url, xhrSettings) + { + var extension = 'css'; - if (this.drawDebug) + if (IsPlainObject(key)) { - this.createDebugGraphic(); + 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); }, /** - * 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 + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. * - * @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`. + * @method Phaser.Loader.FileTypes.CSSFile#onProcess + * @since 3.17.0 */ - enable: function (object, bodyType) + onProcess: function () { - if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } - - if (!Array.isArray(object)) - { - object = [ object ]; - } + this.state = CONST.FILE_PROCESSING; - for (var i = 0; i < object.length; i++) - { - var entry = object[i]; + this.data = document.createElement('style'); + this.data.defer = false; + this.data.innerHTML = this.xhrLoader.responseText; - if (entry.isParent) - { - var children = entry.getChildren(); + document.head.appendChild(this.data); - for (var c = 0; c < children.length; c++) - { - var child = children[c]; + this.onProcessComplete(); + } - 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) +/** + * Adds a CSS file, or array of CSS 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.css('headers', 'styles/headers.css'); + * } + * ``` + * + * 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.css({ + * key: 'headers', + * url: 'styles/headers.css' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.CSSFileConfig` for more details. + * + * Once the file has finished loading it will automatically be converted into a style DOM element + * via `document.createElement('style')`. It will have its `defer` property set to false and then the + * resulting element will be appended to `document.head`. The CSS styles are then applied to the current document. + * + * 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.css". It will always add `.css` 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 CSS 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#css + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.17.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.CSSFileConfig|Phaser.Types.Loader.FileTypes.CSSFileConfig[])} 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 `.css`, i.e. if `key` was "alien" then the URL will be "alien.css". + * @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('css', function (key, url, xhrSettings) +{ + if (Array.isArray(key)) { - if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } - - if (!object.body) + for (var i = 0; i < key.length; i++) { - if (bodyType === CONST.DYNAMIC_BODY) - { - object.body = new Body(this, object); - } - else if (bodyType === CONST.STATIC_BODY) - { - object.body = new StaticBody(this, object); - } + // 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 CSSFile(this, key[i])); } + } + else + { + this.addFile(new CSSFile(this, key, url, xhrSettings)); + } - this.add(object.body); + return this; +}); - return object; - }, +module.exports = CSSFile; - /** - * 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; +/***/ 47375: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return body; - }, +/** + * @author Richard Davey + * @copyright 2021 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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) +var AtlasJSONFile = __webpack_require__(73152); +var BinaryFile = __webpack_require__(40612); +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var ImageFile = __webpack_require__(42927); +var IsPlainObject = __webpack_require__(42911); +var JSONFile = __webpack_require__(70806); +var KTXParser = __webpack_require__(67409); +var Merge = __webpack_require__(30657); +var MultiAtlasFile = __webpack_require__(80802); +var MultiFile = __webpack_require__(45176); +var PVRParser = __webpack_require__(24904); + +/** + * @classdesc + * A Compressed Texture File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#texture method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#texture. + * + * @class CompressedTextureFile + * @extends Phaser.Loader.MultiFile + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {string} key - The key to use for this file. + * @param {Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry} entry - The compressed texture file entry to load. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var CompressedTextureFile = new Class({ + + Extends: MultiFile, + + initialize: + + function CompressedTextureFile (loader, key, entry, xhrSettings) { - if (!Array.isArray(object)) + if (entry.multiAtlasURL) { - object = [ object ]; - } + var multi = new JSONFile(loader, { + key: key, + url: entry.multiAtlasURL, + xhrSettings: xhrSettings, + config: entry + }); - for (var i = 0; i < object.length; i++) + MultiFile.call(this, loader, 'texture', key, [ multi ]); + } + else { - var entry = object[i]; + var extension = entry.textureURL.substr(entry.textureURL.length - 3); - if (entry.isParent) + if (!entry.type) { - var children = entry.getChildren(); + entry.type = (extension.toLowerCase() === 'ktx') ? 'KTX' : 'PVR'; + } - for (var c = 0; c < children.length; c++) - { - var child = children[c]; + var image = new BinaryFile(loader, { + key: key, + url: entry.textureURL, + extension: extension, + xhrSettings: xhrSettings, + config: entry + }); - if (child.isParent) - { - // Handle Groups nested inside of Groups - this.disable(child); - } - else - { - this.disableBody(child.body); - } - } + if (entry.atlasURL) + { + var data = new JSONFile(loader, { + key: key, + url: entry.atlasURL, + xhrSettings: xhrSettings, + config: entry + }); + + MultiFile.call(this, loader, 'texture', key, [ image, data ]); } else { - this.disableBody(entry.body); + MultiFile.call(this, loader, 'texture', key, [ image ]); } } - }, - /** - * 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; + this.config = entry; }, /** - * 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`. + * Called by each File when it finishes loading. * - * @method Phaser.Physics.Arcade.World#remove - * @since 3.0.0 + * @method Phaser.Loader.FileTypes.CompressedTextureFile#onFileComplete + * @since 3.60.0 * - * @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The body to be removed from the simulation. + * @param {Phaser.Loader.File} file - The File that has completed processing. */ - remove: function (body) + onFileComplete: function (file) { - if (body.physicsType === CONST.DYNAMIC_BODY) - { - this.tree.remove(body); - this.bodies.delete(body); - } - else if (body.physicsType === CONST.STATIC_BODY) + var index = this.files.indexOf(file); + + if (index !== -1) { - this.staticBodies.delete(body); - this.staticTree.remove(body); - } - }, + this.pending--; - /** - * 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 }); + if (!this.config.multiAtlasURL) + { + return; + } - graphic.setDepth(Number.MAX_VALUE); + if (file.type === 'json' && file.data.hasOwnProperty('textures')) + { + // Inspect the data for the files to now load + var textures = file.data.textures; - this.debugGraphic = graphic; + var config = this.config; + var loader = this.loader; - this.drawDebug = true; + var currentBaseURL = loader.baseURL; + var currentPath = loader.path; + var currentPrefix = loader.prefix; - return graphic; - }, + var baseURL = GetFastValue(config, 'multiBaseURL', this.baseURL); + var path = GetFastValue(config, 'multiPath', this.path); + var prefix = GetFastValue(config, 'prefix', this.prefix); + var textureXhrSettings = GetFastValue(config, 'textureXhrSettings'); - /** - * 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 (baseURL) + { + loader.setBaseURL(baseURL); + } - if (checkLeft !== undefined) - { - this.setBoundsCollision(checkLeft, checkRight, checkUp, checkDown); - } + if (path) + { + loader.setPath(path); + } - return this; - }, + if (prefix) + { + loader.setPrefix(prefix); + } - /** - * 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; } + for (var i = 0; i < textures.length; i++) + { + // "image": "texture-packer-multi-atlas-0.png", + var textureURL = textures[i].image; - this.checkCollision.left = left; - this.checkCollision.right = right; - this.checkCollision.up = up; - this.checkCollision.down = down; + var key = 'CMA' + this.multiKeyIndex + '_' + textureURL; - return this; - }, + var image = new BinaryFile(loader, key, textureURL, textureXhrSettings); - /** - * 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.addToMultiFile(image); - this.emit(Events.PAUSE); + loader.addFile(image); - return this; - }, + // "normalMap": "texture-packer-multi-atlas-0_n.png", + if (textures[i].normalMap) + { + var normalMap = new BinaryFile(loader, key, textures[i].normalMap, textureXhrSettings); - /** - * 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; + normalMap.type = 'normalMap'; - this.emit(Events.RESUME); + image.setLink(normalMap); - return this; + this.addToMultiFile(normalMap); + + loader.addFile(normalMap); + } + } + + // Reset the loader settings + loader.setBaseURL(currentBaseURL); + loader.setPath(currentPath); + loader.setPrefix(currentPrefix); + } + } }, /** - * 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. + * Adds this file to its target cache upon successful loading and processing. * - * @return {Phaser.Physics.Arcade.Collider} The Collider that was created. + * @method Phaser.Loader.FileTypes.CompressedTextureFile#addToCache + * @since 3.60.0 */ - addCollider: function (object1, object2, collideCallback, processCallback, callbackContext) + addToCache: function () { - if (collideCallback === undefined) { collideCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = collideCallback; } + if (this.isReadyToProcess()) + { + var entry = this.config; - var collider = new Collider(this, false, object1, object2, collideCallback, processCallback, callbackContext); + if (entry.multiAtlasURL) + { + this.addMultiToCache(); + } + else + { + var renderer = this.loader.systems.renderer; + var textureManager = this.loader.textureManager; + var textureData; - this.colliders.add(collider); + var image = this.files[0]; + var json = this.files[1]; - return collider; - }, + if (entry.type === 'PVR') + { + textureData = PVRParser(image.data); + } + else if (entry.type === 'KTX') + { + textureData = KTXParser(image.data); + } - /** - * 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; } + if (textureData && renderer.supportsCompressedTexture(entry.format, textureData.internalFormat)) + { + textureData.format = renderer.getCompressedTextureName(entry.format, textureData.internalFormat); - var collider = new Collider(this, true, object1, object2, collideCallback, processCallback, callbackContext); + var atlasData = (json && json.data) ? json.data : null; - this.colliders.add(collider); + textureManager.addCompressedTexture(image.key, textureData, atlasData); + } + } - return collider; + this.complete = true; + } }, /** - * 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. + * Adds all of the multi-file entties to their target caches upon successful loading and processing. * - * @return {Phaser.Physics.Arcade.World} This World object. + * @method Phaser.Loader.FileTypes.CompressedTextureFile#addMultiToCache + * @since 3.60.0 */ - removeCollider: function (collider) + addMultiToCache: function () { - this.colliders.remove(collider); - - return this; - }, + var entry = this.config; + var json = this.files[0]; - /** - * 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; + var data = []; + var images = []; + var normalMaps = []; - return this; - }, + var renderer = this.loader.systems.renderer; + var textureManager = this.loader.textureManager; + var textureData; - /** - * 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) + for (var i = 1; i < this.files.length; i++) { - return; - } + var file = this.files[i]; - var i; - var fixedDelta = this._frameTime; - var msPerFrame = this._frameTimeMS * this.timeScale; + if (file.type === 'normalMap') + { + continue; + } - this._elapsed += delta; + var pos = file.key.indexOf('_'); + var key = file.key.substr(pos + 1); - // Update all active bodies - var body; - var bodies = this.bodies.entries; + var image = file.data; - // Will a step happen this frame? - var willStep = (this._elapsed >= msPerFrame); + // Now we need to find out which json entry this mapped to + for (var t = 0; t < json.data.textures.length; t++) + { + var item = json.data.textures[t]; - if (!this.fixedStep) - { - fixedDelta = delta * 0.001; - willStep = true; - this._elapsed = 0; - } + if (item.image === key) + { + if (entry.type === 'PVR') + { + textureData = PVRParser(image); + } + else if (entry.type === 'KTX') + { + textureData = KTXParser(image); + } - for (i = 0; i < bodies.length; i++) - { - body = bodies[i]; + if (textureData && renderer.supportsCompressedTexture(entry.format, textureData.internalFormat)) + { + textureData.format = renderer.getCompressedTextureName(entry.format, textureData.internalFormat); - if (body.enable) - { - body.preUpdate(willStep, fixedDelta); + images.push(textureData); + + data.push(item); + + if (file.linkFile) + { + normalMaps.push(file.linkFile.data); + } + } + + break; + } } } - // We know that a step will happen this frame, so let's bundle it all together to save branching and iteration costs - if (willStep) + if (normalMaps.length === 0) { - this._elapsed -= msPerFrame; - this.stepsLastFrame = 1; + normalMaps = undefined; + } - // Optionally populate our dynamic collision tree - if (this.useTree) - { - this.tree.clear(); - this.tree.load(bodies); - } + textureManager.addAtlasJSONArray(this.key, images, data, normalMaps); - // Process any colliders - var colliders = this.colliders.update(); + this.complete = true; + } - for (i = 0; i < colliders.length; i++) - { - var collider = colliders[i]; +}); - if (collider.active) - { - collider.update(); - } - } +/** + * Adds a Compressed Texture file to the current load queue. This feature is WebGL only. + * + * This method takes a key and a configuration object, which lists the different formats + * and files associated with them. + * + * The texture format object should be ordered in GPU priority order, with IMG as the last entry. + * + * You can call this method from within your Scene's `preload`, along with any other files you wish to load: + * + * ```javascript + * preload () + * { + * this.load.texture('yourPic', { + * ASTC: { type: 'PVR', textureURL: 'pic-astc-4x4.pvr' }, + * PVRTC: { type: 'PVR', textureURL: 'pic-pvrtc-4bpp-rgba.pvr' }, + * S3TC: { type: 'PVR', textureURL: 'pic-dxt5.pvr' }, + * IMG: { textureURL: 'pic.png' } + * }); + * ``` + * + * If you wish to load a texture atlas, provide the `atlasURL` property: + * + * ```javascript + * preload () + * { + * const path = 'assets/compressed'; + * + * this.load.texture('yourAtlas', { + * 'ASTC': { type: 'PVR', textureURL: `${path}/textures-astc-4x4.pvr`, atlasURL: `${path}/textures.json` }, + * 'PVRTC': { type: 'PVR', textureURL: `${path}/textures-pvrtc-4bpp-rgba.pvr`, atlasURL: `${path}/textures-pvrtc-4bpp-rgba.json` }, + * 'S3TC': { type: 'PVR', textureURL: `${path}/textures-dxt5.pvr`, atlasURL: `${path}/textures-dxt5.json` }, + * 'IMG': { textureURL: `${path}/textures.png`, atlasURL: `${path}/textures.json` } + * }); + * } + * ``` + * + * If you wish to load a Multi Atlas, as exported from Texture Packer Pro, use the `multiAtlasURL` property instead: + * + * ```javascript + * preload () + * { + * const path = 'assets/compressed'; + * + * this.load.texture('yourAtlas', { + * 'ASTC': { type: 'PVR', atlasURL: `${path}/textures.json` }, + * 'PVRTC': { type: 'PVR', atlasURL: `${path}/textures-pvrtc-4bpp-rgba.json` }, + * 'S3TC': { type: 'PVR', atlasURL: `${path}/textures-dxt5.json` }, + * 'IMG': { atlasURL: `${path}/textures.json` } + * }); + * } + * ``` + * + * When loading a Multi Atlas you do not need to specify the `textureURL` property as it will be read from the JSON file. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.texture({ + * key: 'yourPic', + * url: { + * ASTC: { type: 'PVR', textureURL: 'pic-astc-4x4.pvr' }, + * PVRTC: { type: 'PVR', textureURL: 'pic-pvrtc-4bpp-rgba.pvr' }, + * S3TC: { type: 'PVR', textureURL: 'pic-dxt5.pvr' }, + * IMG: { textureURL: 'pic.png' } + * } + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.CompressedTextureFileConfig` for more details. + * + * The number of formats you provide to this function is up to you, but you should ensure you + * cover the primary platforms where appropriate. + * + * The 'IMG' entry is a fallback to a JPG or PNG, should the browser be unable to load any of the other + * formats presented to this function. You should really always include this, although it is optional. + * + * Phaser supports loading both the PVR and KTX container formats. Within those, it can parse + * the following texture compression formats: + * + * ETC + * ETC1 + * ATC + * ASTC + * BPTC + * RGTC + * PVRTC + * S3TC + * S3TCSRGB + * + * For more information about the benefits of compressed textures please see the + * following articles: + * + * Texture Compression in 2020 (https://aras-p.info/blog/2020/12/08/Texture-Compression-in-2020/) + * Compressed GPU Texture Formats (https://themaister.net/blog/2020/08/12/compressed-gpu-texture-formats-a-review-and-compute-shader-decoders-part-1/) + * + * To create compressed texture files use a 3rd party application such as: + * + * Texture Packer (https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?utm_source=ad&utm_medium=banner&utm_campaign=phaser-2018-10-16) + * PVRTexTool (https://developer.imaginationtech.com/pvrtextool/) - available for Windows, macOS and Linux. + * Mali Texture Compression Tool (https://developer.arm.com/tools-and-software/graphics-and-gaming/mali-texture-compression-tool) + * ASTC Encoder (https://github.com/ARM-software/astc-encoder) + * + * ASTCs must have a Channel Type of Unsigned Normalized Bytes (UNorm) and a Linear RGB Color Space. + * + * 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 Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * 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 `Data` the final key will be `LEVEL1.Data` and + * this is what you would use to retrieve the text from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * Unlike other file loaders in Phaser, the URLs must include the file extension. + * + * Note: The ability to load this type of file will only be available if the Compressed Texture 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#texture + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.60.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.CompressedTextureFileConfig|Phaser.Types.Loader.FileTypes.CompressedTextureFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {Phaser.Types.Loader.FileTypes.CompressedTextureFileConfig} [url] - The compressed texture configuration object. Not required if passing a config object as the `key` parameter. + * @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('texture', function (key, url, xhrSettings) +{ + var renderer = this.systems.renderer; - this.emit(Events.WORLD_STEP, fixedDelta); - } + var AddEntry = function (loader, key, urls, xhrSettings) + { + var entry = { + format: null, + type: null, + textureURL: undefined, + atlasURL: undefined, + multiAtlasURL: undefined, + multiPath: undefined, + multiBaseURL: undefined + }; - // Process any additional steps this frame - while (this._elapsed >= msPerFrame) + if (IsPlainObject(key)) { - this._elapsed -= msPerFrame; + var config = key; - this.step(fixedDelta); + key = GetFastValue(config, 'key'); + urls = GetFastValue(config, 'url'), + xhrSettings = GetFastValue(config, 'xhrSettings'); } - }, - /** - * 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; + var matched = false; - for (i = 0; i < len; i++) + for (var textureBaseFormat in urls) { - body = bodies[i]; - - if (body.enable) + if (renderer.supportsCompressedTexture(textureBaseFormat)) { - body.update(delta); - } - } + var urlEntry = urls[textureBaseFormat]; - // Optionally populate our dynamic collision tree - if (this.useTree) - { - this.tree.clear(); - this.tree.load(bodies); - } + if (typeof urlEntry === 'string') + { + entry.textureURL = urlEntry; + } + else + { + entry = Merge(urlEntry, entry); + } - // Process any colliders - var colliders = this.colliders.update(); + entry.format = textureBaseFormat.toUpperCase(); - for (i = 0; i < colliders.length; i++) - { - var collider = colliders[i]; + matched = true; - if (collider.active) - { - collider.update(); + break; } } - this.emit(Events.WORLD_STEP, delta); + if (!matched) + { + console.warn('No supported compressed texture format or IMG fallback', key); + } + else if (entry.format === 'IMG') + { + var file; + var multifile; - this.stepsLastFrame++; - }, + if (entry.multiAtlasURL) + { + multifile = new MultiAtlasFile(loader, key, entry.multiAtlasURL, entry.multiPath, entry.multiBaseURL, xhrSettings); - /** - * 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; + file = multifile.files; + } + else if (entry.atlasURL) + { + multifile = new AtlasJSONFile(loader, key, entry.textureURL, entry.atlasURL, xhrSettings); - var dynamic = this.bodies; - var staticBodies = this.staticBodies; + file = multifile.files; + } + else + { + file = new ImageFile(loader, key, entry.textureURL, xhrSettings); + } - // We don't need to postUpdate if there wasn't a step this frame - if (this.stepsLastFrame) + loader.addFile(file); + } + else { - this.stepsLastFrame = 0; - - for (i = 0; i < len; i++) - { - body = bodies[i]; + var texture = new CompressedTextureFile(loader, key, entry, xhrSettings); - if (body.enable) - { - body.postUpdate(); - } - } + loader.addFile(texture.files); } + }; - if (this.drawDebug) + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) { - var graphics = this.debugGraphic; + AddEntry(this, key[i]); + } + } + else + { + AddEntry(this, key, url, xhrSettings); + } - graphics.clear(); + return this; +}); - for (i = 0; i < len; i++) - { - body = bodies[i]; +module.exports = CompressedTextureFile; - if (body.willDrawDebug()) - { - body.drawDebug(graphics); - } - } - bodies = staticBodies.entries; - len = bodies.length; +/***/ }), - for (i = 0; i < len; i++) - { - body = bodies[i]; +/***/ 46568: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (body.willDrawDebug()) - { - body.drawDebug(graphics); - } - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var pending = this.pendingDestroy; +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); +var Shader = __webpack_require__(31053); - if (pending.size > 0) - { - var dynamicTree = this.tree; - var staticTree = this.staticTree; +/** + * @classdesc + * A single GLSL File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#glsl method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#glsl. + * + * @class GLSLFile + * @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.GLSLFileConfig)} 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 `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". + * @param {string} [shaderType='fragment'] - The type of shader. Either `fragment` for a fragment shader, or `vertex` for a vertex shader. This is ignored if you load a shader bundle. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var GLSLFile = new Class({ - bodies = pending.entries; - len = bodies.length; + Extends: File, - for (i = 0; i < len; i++) - { - body = bodies[i]; + initialize: - 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); - } + function GLSLFile (loader, key, url, shaderType, xhrSettings) + { + var extension = 'glsl'; - body.world = undefined; - body.gameObject = undefined; - } + if (IsPlainObject(key)) + { + var config = key; - pending.clear(); + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url'); + shaderType = GetFastValue(config, 'shaderType', 'fragment'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + extension = GetFastValue(config, 'extension', extension); } - }, - - /** - * 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) + else if (shaderType === undefined) { - this.computeAngularVelocity(body, delta); + shaderType = 'fragment'; } - this.computeVelocity(body, delta); + var fileConfig = { + type: 'glsl', + cache: loader.cacheManager.shader, + extension: extension, + responseType: 'text', + key: key, + url: url, + config: { + shaderType: shaderType + }, + xhrSettings: xhrSettings + }; + + File.call(this, loader, fileConfig); }, /** - * Calculates a Body's angular velocity. - * - * @method Phaser.Physics.Arcade.World#computeAngularVelocity - * @since 3.10.0 + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. * - * @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. + * @method Phaser.Loader.FileTypes.GLSLFile#onProcess + * @since 3.7.0 */ - computeAngularVelocity: function (body, delta) + onProcess: function () { - 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); + this.state = CONST.FILE_PROCESSING; - var velocityDelta = velocity - body.angularVelocity; + this.data = this.xhrLoader.responseText; - body.angularVelocity += velocityDelta; - body.rotation += (body.angularVelocity * delta); + this.onProcessComplete(); }, /** - * Calculates a Body's per-axis velocity. - * - * @method Phaser.Physics.Arcade.World#computeVelocity - * @since 3.0.0 + * Adds this file to its target cache upon successful loading and processing. * - * @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. + * @method Phaser.Loader.FileTypes.GLSLFile#addToCache + * @since 3.17.0 */ - computeVelocity: function (body, delta) + addToCache: function () { - 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; + var data = this.data.split('\n'); - if (body.allowGravity) - { - velocityX += (this.gravity.x + body.gravity.x) * delta; - velocityY += (this.gravity.y + body.gravity.y) * delta; - } + // Check to see if this is a shader bundle, or raw glsl file. + var block = this.extractBlock(data, 0); - if (accelerationX) - { - velocityX += accelerationX * delta; - } - else if (allowDrag && dragX) + if (block) { - if (useDamping) + while (block) { - // Damping based deceleration - dragX = Math.pow(dragX, delta); - - velocityX *= dragX; - - speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); + var key = this.getShaderName(block.header); + var shaderType = this.getShaderType(block.header); + var uniforms = this.getShaderUniforms(block.header); + var shaderSrc = block.shader; - if (FuzzyEqual(speed, 0, 0.001)) + if (this.cache.has(key)) { - velocityX = 0; - } - } - else - { - // Linear deceleration - dragX *= delta; + var shader = this.cache.get(key); - if (FuzzyGreaterThan(velocityX - dragX, 0, 0.01)) - { - velocityX -= dragX; + if (shaderType === 'fragment') + { + shader.fragmentSrc = shaderSrc; + } + else + { + shader.vertexSrc = shaderSrc; + } + + if (!shader.uniforms) + { + shader.uniforms = uniforms; + } } - else if (FuzzyLessThan(velocityX + dragX, 0, 0.01)) + else if (shaderType === 'fragment') { - velocityX += dragX; + this.cache.add(key, new Shader(key, shaderSrc, '', uniforms)); } else { - velocityX = 0; + this.cache.add(key, new Shader(key, '', shaderSrc, uniforms)); } - } - } - if (accelerationY) - { - velocityY += accelerationY * delta; + block = this.extractBlock(data, block.offset); + } } - else if (allowDrag && dragY) + else if (this.config.shaderType === 'fragment') { - 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; - } - } + // Single shader + this.cache.add(this.key, new Shader(this.key, this.data)); } - - velocityX = Clamp(velocityX, -maxX, maxX); - velocityY = Clamp(velocityY, -maxY, maxY); - - body.velocity.set(velocityX, velocityY); - - if (maxSpeed > -1 && speed > maxSpeed) + else { - body.velocity.normalize().scale(maxSpeed); - speed = maxSpeed; + this.cache.add(this.key, new Shader(this.key, '', this.data)); } - - body.speed = speed; }, /** - * Separates two Bodies. + * Returns the name of the shader from the header block. * - * @method Phaser.Physics.Arcade.World#separate - * @fires Phaser.Physics.Arcade.Events#COLLIDE - * @fires Phaser.Physics.Arcade.Events#OVERLAP - * @since 3.0.0 + * @method Phaser.Loader.FileTypes.GLSLFile#getShaderName + * @since 3.17.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. + * @param {string[]} headerSource - The header data. * - * @return {boolean} True if separation occurred, otherwise false. + * @return {string} The shader name. */ - separate: function (body1, body2, processCallback, callbackContext, overlapOnly, intersects) + getShaderName: function (headerSource) { - 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) + for (var i = 0; i < headerSource.length; i++) { - 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; + var line = headerSource[i].trim(); - if (circle.y < rect.y || circle.y > rect.bottom) + if (line.substring(0, 5) === 'name:') { - if (circle.x < rect.x || circle.x > rect.right) - { - return this.separateCircle(body1, body2, overlapOnly); - } + return line.substring(5).trim(); } } - var resultX = false; - var resultY = false; + return this.key; + }, - // 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)) + /** + * Returns the type of the shader from the header block. + * + * @method Phaser.Loader.FileTypes.GLSLFile#getShaderType + * @since 3.17.0 + * + * @param {string[]} headerSource - The header data. + * + * @return {string} The shader type. Either 'fragment' or 'vertex'. + */ + getShaderType: function (headerSource) + { + for (var i = 0; i < headerSource.length; i++) { - resultX = SeparateX(body1, body2, overlapOnly, this.OVERLAP_BIAS); + var line = headerSource[i].trim(); - // Are they still intersecting? Let's do the other axis then - if (this.intersects(body1, body2)) + if (line.substring(0, 5) === 'type:') { - resultY = SeparateY(body1, body2, overlapOnly, this.OVERLAP_BIAS); + return line.substring(5).trim(); } } - 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); - } - } + return this.config.shaderType; + }, - var result = (resultX || resultY); + /** + * Returns the shader uniforms from the header block. + * + * @method Phaser.Loader.FileTypes.GLSLFile#getShaderUniforms + * @since 3.17.0 + * + * @param {string[]} headerSource - The header data. + * + * @return {any} The shader uniforms object. + */ + getShaderUniforms: function (headerSource) + { + var uniforms = {}; - if (result) + for (var i = 0; i < headerSource.length; i++) { - if (overlapOnly) + var line = headerSource[i].trim(); + + if (line.substring(0, 8) === 'uniform.') { - if (body1.onOverlap || body2.onOverlap) + var pos = line.indexOf(':'); + + if (pos) { - this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2); + var key = line.substring(8, pos); + + try + { + uniforms[key] = JSON.parse(line.substring(pos + 1)); + } + catch (e) + { + console.warn('Invalid uniform JSON: ' + key); + } } } - else if (body1.onCollide || body2.onCollide) - { - this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); - } } - return result; + return uniforms; }, /** - * Separates two Bodies, when both are circular. + * Processes the shader file and extracts the relevant data. * - * @method Phaser.Physics.Arcade.World#separateCircle - * @fires Phaser.Physics.Arcade.Events#COLLIDE - * @fires Phaser.Physics.Arcade.Events#OVERLAP - * @since 3.0.0 + * @method Phaser.Loader.FileTypes.GLSLFile#extractBlock + * @private + * @since 3.17.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. + * @param {string[]} data - The array of shader data to process. + * @param {number} offset - The offset to start processing from. * - * @return {boolean} True if separation occurred, otherwise false. + * @return {any} The processed shader block, or null. */ - separateCircle: function (body1, body2, overlapOnly, bias) + extractBlock: function (data, offset) { - // 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; + var headerStart = -1; + var headerEnd = -1; + var blockEnd = -1; + var headerOpen = false; + var captureSource = false; + var headerSource = []; + var shaderSource = []; - if (body1.isCircle !== body2.isCircle) + for (var i = offset; i < data.length; i++) { - 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 - }; + var line = data[i].trim(); - if (circle.y < rect.y) + if (line === '---') { - if (circle.x < rect.x) - { - overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.y) - circle.radius; - } - else if (circle.x > rect.right) + if (headerStart === -1) { - overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.y) - circle.radius; + headerStart = i; + headerOpen = true; } - } - else if (circle.y > rect.bottom) - { - if (circle.x < rect.x) + else if (headerOpen) { - overlap = DistanceBetween(circle.x, circle.y, rect.x, rect.bottom) - circle.radius; + headerEnd = i; + headerOpen = false; + captureSource = true; } - else if (circle.x > rect.right) + else { - overlap = DistanceBetween(circle.x, circle.y, rect.right, rect.bottom) - circle.radius; + // We've hit another --- delimiter, break out + captureSource = false; + break; } } + else if (headerOpen) + { + headerSource.push(line); + } + else if (captureSource) + { + shaderSource.push(line); + blockEnd = i; + } + } - overlap *= -1; + if (!headerOpen && headerEnd !== -1) + { + return { header: headerSource, shader: shaderSource.join('\n'), offset: blockEnd }; } else { - overlap = (body1.halfWidth + body2.halfWidth) - DistanceBetween(body1.center.x, body1.center.y, body2.center.x, body2.center.y); + return null; } + } - 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) +/** + * Adds a GLSL file, or array of GLSL files, to the current load queue. + * In Phaser 3 GLSL files are just plain Text files at the current moment in time. + * + * 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.glsl('plasma', 'shaders/Plasma.glsl'); + * } + * ``` + * + * 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 Shader Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Shader 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 Shader Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.glsl({ + * key: 'plasma', + * shaderType: 'fragment', + * url: 'shaders/Plasma.glsl' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.GLSLFileConfig` for more details. + * + * Once the file has finished loading you can access it from its Cache using its key: + * + * ```javascript + * this.load.glsl('plasma', 'shaders/Plasma.glsl'); + * // and later in your game ... + * var data = this.cache.shader.get('plasma'); + * ``` + * + * 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 `FX.` and the key was `Plasma` the final key will be `FX.Plasma` and + * this is what you would use to retrieve the text from the Shader 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 "plasma" + * and no URL is given then the Loader will set the URL to be "plasma.glsl". It will always add `.glsl` 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 GLSL 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#glsl + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.GLSLFileConfig|Phaser.Types.Loader.FileTypes.GLSLFileConfig[])} 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 `.glsl`, i.e. if `key` was "alien" then the URL will be "alien.glsl". + * @param {string} [shaderType='fragment'] - The type of shader. Either `fragment` for a fragment shader, or `vertex` for a vertex shader. This is ignored if you load a shader bundle. + * @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('glsl', function (key, url, shaderType, xhrSettings) +{ + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) { - 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); + // 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 GLSLFile(this, key[i])); } + } + else + { + this.addFile(new GLSLFile(this, key, url, shaderType, xhrSettings)); + } - 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); + return this; +}); - if (body1.immovable || body2.immovable) - { - p *= 2; - } +module.exports = GLSLFile; - 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; - } +/***/ 30929: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Note: This is inadequate for circle-rectangle separation +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(683); +var File = __webpack_require__(98035); +var GetFastValue = __webpack_require__(72632); +var GetURL = __webpack_require__(30750); +var IsPlainObject = __webpack_require__(42911); - if (!body1.immovable) - { - body1.x -= overlapX; - body1.y -= overlapY; +/** + * @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({ - body1.updateCenter(); - } + Extends: File, + + initialize: - if (!body2.immovable) + function HTML5AudioFile (loader, key, urlConfig, audioConfig) + { + if (IsPlainObject(key)) { - body2.x += overlapX; - body2.y += overlapY; + var config = key; - body2.updateCenter(); + key = GetFastValue(config, 'key'); + audioConfig = GetFastValue(config, 'config', audioConfig); } - body1.velocity.x *= body1.bounce.x; - body1.velocity.y *= body1.bounce.y; - body2.velocity.x *= body2.bounce.x; - body2.velocity.y *= body2.bounce.y; + var fileConfig = { + type: 'audio', + cache: loader.cacheManager.audio, + extension: urlConfig.type, + key: key, + url: urlConfig.url, + config: audioConfig + }; - if (body1.onCollide || body2.onCollide) - { - this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2); - } + File.call(this, loader, fileConfig); - return true; + // New properties specific to this class + this.locked = 'ontouchstart' in window; + this.loaded = false; + this.filesLoaded = 0; + this.filesTotal = 0; }, /** - * Checks to see if two Bodies intersect at all. + * Called when the file finishes loading. * - * @method Phaser.Physics.Arcade.World#intersects + * @method Phaser.Loader.FileTypes.HTML5AudioFile#onLoad * @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) + onLoad: function () { - if (body1 === body2) + if (this.loaded) { - return false; + return; } - 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); - } + this.loaded = true; + + this.loader.nextFile(this, true); }, /** - * Tests if a circular Body intersects with another Body. + * Called if the file errors while loading. * - * @method Phaser.Physics.Arcade.World#circleBodyIntersects + * @method Phaser.Loader.FileTypes.HTML5AudioFile#onError * @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) + onError: function () { - var x = Clamp(circle.center.x, body.left, body.right); - var y = Clamp(circle.center.y, body.top, body.bottom); + for (var i = 0; i < this.data.length; i++) + { + var audio = this.data[i]; - var dx = (circle.center.x - x) * (circle.center.x - x); - var dy = (circle.center.y - y) * (circle.center.y - y); + audio.oncanplaythrough = null; + audio.onerror = null; + } - return (dx + dy) <= (circle.halfWidth * circle.halfWidth); + this.loader.nextFile(this, false); }, /** - * Tests if Game Objects overlap. - * - * See details in {@link Phaser.Physics.Arcade.World#collide}. + * Called during the file load progress. Is sent a DOM ProgressEvent. * - * @method Phaser.Physics.Arcade.World#overlap + * @method Phaser.Loader.FileTypes.HTML5AudioFile#onProgress + * @fires Phaser.Loader.Events#FILE_PROGRESS * @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) + onProgress: function (event) { - if (overlapCallback === undefined) { overlapCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = overlapCallback; } + var audio = event.target; - return this.collideObjects(object1, object2, overlapCallback, processCallback, callbackContext, true); - }, + audio.oncanplaythrough = null; + audio.onerror = null; - /** - * 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; } + this.filesLoaded++; - return this.collideObjects(object1, object2, collideCallback, processCallback, callbackContext, false); + 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(); + } }, /** - * Internal helper function. Please use Phaser.Physics.Arcade.World#collide instead. + * 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.Physics.Arcade.World#collideObjects - * @private + * @method Phaser.Loader.FileTypes.HTML5AudioFile#load * @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) + load: function () { - var i; - var j; + this.data = []; - if (object1.isParent && object1.physicsType === undefined) - { - object1 = object1.children.entries; - } + var instances = (this.config && this.config.instances) || 1; - if (object2 && object2.isParent && object2.physicsType === undefined) + this.filesTotal = instances; + this.filesLoaded = 0; + this.percentComplete = 0; + + for (var i = 0; i < instances; i++) { - object2 = object2.children.entries; - } + var audio = new Audio(); - var object1isArray = Array.isArray(object1); - var object2isArray = Array.isArray(object2); + if (!audio.dataset) + { + audio.dataset = {}; + } - this._total = 0; + audio.dataset.name = this.key + ('0' + i).slice(-2); + audio.dataset.used = 'false'; - 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++) + if (this.locked) { - this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, overlapOnly); + audio.dataset.locked = 'true'; } - } - else if (object1isArray && !object2isArray) - { - // Object 1 is an Array - if (!object2) + else { - // 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; - } + audio.dataset.locked = 'false'; - 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); - } + audio.preload = 'auto'; + audio.oncanplaythrough = this.onProgress.bind(this); + audio.onerror = this.onError.bind(this); } - } - - 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); + this.data.push(audio); } - // If neither of the objects are set then bail out - if (!object1 || !object2) + for (i = 0; i < this.data.length; i++) { - return false; - } + audio = this.data[i]; + audio.src = GetURL(this, this.loader.baseURL); - // 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) + if (!this.locked) { - return this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + audio.load(); } } - // GROUPS - else if (object1.isParent) + if (this.locked) { - 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); - } + // This is super-dangerous but works. Race condition potential high. + // Is there another way? + setTimeout(this.onLoad.bind(this)); } + } - // 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) +module.exports = HTML5AudioFile; + + +/***/ }), + +/***/ 77459: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); + +/** + * @classdesc + * A single HTML File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#html method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#html. + * + * @class HTMLFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.12.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.HTMLFileConfig)} 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 `.html`, i.e. if `key` was "alien" then the URL will be "alien.html". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var HTMLFile = new Class({ + + Extends: File, + + initialize: + + function HTMLFile (loader, key, url, xhrSettings) { - if (!sprite1.body || !sprite2.body) - { - return false; - } + var extension = 'html'; - if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly)) + if (IsPlainObject(key)) { - if (collideCallback) - { - collideCallback.call(callbackContext, sprite1, sprite2); - } + var config = key; - this._total++; + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + extension = GetFastValue(config, 'extension', extension); } - return true; + var fileConfig = { + type: 'text', + cache: loader.cacheManager.html, + extension: extension, + responseType: 'text', + key: key, + url: url, + xhrSettings: xhrSettings + }; + + File.call(this, loader, fileConfig); }, /** - * 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. + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. * - * @return {boolean} `true` if the Sprite collided with the given Group, otherwise `false`. + * @method Phaser.Loader.FileTypes.HTMLFile#onProcess + * @since 3.7.0 */ - collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) + onProcess: function () { - var bodyA = sprite.body; + this.state = CONST.FILE_PROCESSING; - if (group.length === 0 || !bodyA || !bodyA.enable || bodyA.checkCollision.none) + this.data = this.xhrLoader.responseText; + + this.onProcessComplete(); + } + +}); + +/** + * Adds an HTML file, or array of HTML 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.html('story', 'files/LoginForm.html'); + * } + * ``` + * + * 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 HTML Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the HTML 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 HTML Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.html({ + * key: 'login', + * url: 'files/LoginForm.html' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.HTMLFileConfig` for more details. + * + * Once the file has finished loading you can access it from its Cache using its key: + * + * ```javascript + * this.load.html('login', 'files/LoginForm.html'); + * // and later in your game ... + * var data = this.cache.html.get('login'); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and + * this is what you would use to retrieve the html from the HTML Cache. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story" + * and no URL is given then the Loader will set the URL to be "story.html". It will always add `.html` 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 HTML 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#html + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.12.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.HTMLFileConfig|Phaser.Types.Loader.FileTypes.HTMLFileConfig[])} 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 `.html`, i.e. if `key` was "alien" then the URL will be "alien.html". + * @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('html', function (key, url, xhrSettings) +{ + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) { - return; + // 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 HTMLFile(this, key[i])); } + } + else + { + this.addFile(new HTMLFile(this, key, url, xhrSettings)); + } - // Does sprite collide with anything? + return this; +}); - var i; - var len; - var bodyB; +module.exports = HTMLFile; - 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); +/***/ 9755: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - len = results.length; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (i = 0; i < len; i++) - { - bodyB = results[i]; +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); - 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; - } +/** + * @classdesc + * A single HTML File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#htmlTexture method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#htmlTexture. + * + * @class HTMLTextureFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.12.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.HTMLTextureFileConfig)} 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 `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {number} [width] - The width of the texture the HTML will be rendered to. + * @param {number} [height] - The height of the texture the HTML will be rendered to. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var HTMLTextureFile = new Class({ - if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly, true)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); - } + Extends: File, - this._total++; - } - } - } - else - { - var children = group.getChildren(); - var skipIndex = group.children.entries.indexOf(sprite); + initialize: - len = children.length; + function HTMLTextureFile (loader, key, url, width, height, xhrSettings) + { + if (width === undefined) { width = 512; } + if (height === undefined) { height = 512; } - for (i = 0; i < len; i++) - { - bodyB = children[i].body; + var extension = 'html'; - if (!bodyB || i === skipIndex || !bodyB.enable) - { - continue; - } + if (IsPlainObject(key)) + { + var config = key; - if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly)) - { - if (collideCallback) - { - collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject); - } + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + extension = GetFastValue(config, 'extension', extension); + width = GetFastValue(config, 'width', width); + height = GetFastValue(config, 'height', height); + } - this._total++; - } + var fileConfig = { + type: 'html', + cache: loader.textureManager, + extension: extension, + responseType: 'text', + key: key, + url: url, + xhrSettings: xhrSettings, + config: { + width: width, + height: height } - } + }; + + File.call(this, loader, fileConfig); }, /** - * 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. + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + * @method Phaser.Loader.FileTypes.HTMLTextureFile#onProcess + * @since 3.7.0 */ - collideGroupVsTilemapLayer: function (group, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) + onProcess: function () { - var children = group.getChildren(); + this.state = CONST.FILE_PROCESSING; - if (children.length === 0) - { - return false; - } + var w = this.config.width; + var h = this.config.height; - var didCollide = false; + var data = []; - for (var i = 0; i < children.length; i++) - { - if (children[i].body) - { - if (this.collideSpriteVsTilemapLayer(children[i], tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)) - { - didCollide = true; - } - } - } + data.push(''); + data.push(''); + data.push(''); + data.push(this.xhrLoader.responseText); + data.push(''); + data.push(''); + data.push(''); - return didCollide; - }, + var svg = [ data.join('\n') ]; + var _this = this; - /** - * 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) + try { - return false; + var blob = new window.Blob(svg, { type: 'image/svg+xml;charset=utf-8' }); } - else + catch (e) { - return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, false, false); + _this.state = CONST.FILE_ERRORED; + + _this.onProcessComplete(); + + return; } - }, - /** - * 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) + this.data = new Image(); + + this.data.crossOrigin = this.crossOrigin; + + this.data.onload = function () { - return false; - } - else + File.revokeObjectURL(_this.data); + + _this.onProcessComplete(); + }; + + this.data.onerror = function () { - return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, true, false); - } + File.revokeObjectURL(_this.data); + + _this.onProcessError(); + }; + + File.createObjectURL(this.data, blob, 'image/svg+xml'); }, /** - * 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. + * Adds this file to its target cache upon successful loading and processing. * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + * @method Phaser.Loader.FileTypes.HTMLTextureFile#addToCache + * @since 3.7.0 */ - collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) + addToCache: function () { - var body = sprite.body; + this.cache.addImage(this.key, this.data); + } - if (!body.enable || body.checkCollision.none) +}); + +/** + * Adds an HTML File, or array of HTML Files, to the current load queue. When the files are loaded they + * will be rendered to textures and stored in the Texture Manager. + * + * 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.htmlTexture('instructions', 'content/intro.html', 256, 512); + * } + * ``` + * + * 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 Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.htmlTexture({ + * key: 'instructions', + * url: 'content/intro.html', + * width: 256, + * height: 512 + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.HTMLTextureFileConfig` for more details. + * + * Once the file has finished loading you can use it as a texture for a Game Object by referencing its key: + * + * ```javascript + * this.load.htmlTexture('instructions', 'content/intro.html', 256, 512); + * // and later in your game ... + * this.add.image(x, y, 'instructions'); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use to retrieve the image from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" + * and no URL is given then the Loader will set the URL to be "alien.html". It will always add `.html` 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. + * + * The width and height are the size of the texture to which the HTML will be rendered. It's not possible to determine these + * automatically, so you will need to provide them, either as arguments or in the file config object. + * When the HTML file has loaded a new SVG element is created with a size and viewbox set to the width and height given. + * The SVG file has a body tag added to it, with the HTML file contents included. It then calls `window.Blob` on the SVG, + * and if successful is added to the Texture Manager, otherwise it fails processing. The overall quality of the rendered + * HTML depends on your browser, and some of them may not even support the svg / blob process used. Be aware that there are + * limitations on what HTML can be inside an SVG. You can find out more details in this + * [Mozilla MDN entry](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas). + * + * Note: The ability to load this type of file will only be available if the HTMLTextureFile 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#htmlTexture + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.12.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.HTMLTextureFileConfig|Phaser.Types.Loader.FileTypes.HTMLTextureFileConfig[])} 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 `.html`, i.e. if `key` was "alien" then the URL will be "alien.html". + * @param {number} [width=512] - The width of the texture the HTML will be rendered to. + * @param {number} [height=512] - The height of the texture the HTML will be rendered to. + * @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('htmlTexture', function (key, url, width, height, xhrSettings) +{ + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) { - return false; + // 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 HTMLTextureFile(this, key[i])); } + } + else + { + this.addFile(new HTMLTextureFile(this, key, url, width, height, xhrSettings)); + } - var x = body.position.x; - var y = body.position.y; - var w = body.width; - var h = body.height; + return this; +}); - var layerData = tilemapLayer.layer; +module.exports = HTMLTextureFile; - if (layerData.tileWidth > layerData.baseTileWidth) + +/***/ }), + +/***/ 42927: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); +var GetURL = __webpack_require__(30750); + +/** + * @classdesc + * A single Image File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#image method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#image. + * + * @class ImageFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.ImageFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + * @param {Phaser.Types.Loader.FileTypes.ImageFrameConfig} [frameConfig] - The frame configuration object. Only provided for, and used by, Sprite Sheets. + */ +var ImageFile = new Class({ + + Extends: File, + + initialize: + + function ImageFile (loader, key, url, xhrSettings, frameConfig) + { + var extension = 'png'; + var normalMapURL; + + if (IsPlainObject(key)) { - // 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; + var config = key; + + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url'); + normalMapURL = GetFastValue(config, 'normalMap'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + extension = GetFastValue(config, 'extension', extension); + frameConfig = GetFastValue(config, 'frameConfig'); } - if (layerData.tileHeight > layerData.baseTileHeight) + if (Array.isArray(url)) { - // 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; + normalMapURL = url[1]; + url = url[0]; } - var mapData = GetTilesWithinWorldXY(x, y, w, h, null, tilemapLayer.scene.cameras.main, tilemapLayer.layer); + var fileConfig = { + type: 'image', + cache: loader.textureManager, + extension: extension, + responseType: 'blob', + key: key, + url: url, + xhrSettings: xhrSettings, + config: frameConfig + }; + + File.call(this, loader, fileConfig); - if (mapData.length === 0) + // Do we have a normal map to load as well? + if (normalMapURL) { - return false; + var normalMap = new ImageFile(loader, this.key, normalMapURL, xhrSettings, frameConfig); + + normalMap.type = 'normalMap'; + + this.setLink(normalMap); + + loader.addFile(normalMap); } - else + + this.useImageElementLoad = loader.imageLoadType === 'HTMLImageElement'; + + if (this.useImageElementLoad) { - return this.collideSpriteVsTilesHandler(sprite, mapData, collideCallback, processCallback, callbackContext, overlapOnly, true); + this.load = this.loadImage; + this.onProcess = this.onProcessImage; } }, /** - * 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? + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. * - * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. + * @method Phaser.Loader.FileTypes.ImageFile#onProcess + * @since 3.7.0 */ - collideSpriteVsTilesHandler: function (sprite, tiles, collideCallback, processCallback, callbackContext, overlapOnly, isLayer) + onProcess: function () { - 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); + this.state = CONST.FILE_PROCESSING; - tileWorldRect.left = point.x; - tileWorldRect.top = point.y; + this.data = new Image(); - // 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; - } + this.data.crossOrigin = this.crossOrigin; - tileWorldRect.right = tileWorldRect.left + tile.width * tilemapLayer.scaleX; - tileWorldRect.bottom = tileWorldRect.top + tile.height * tilemapLayer.scaleY; + var _this = this; - 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++; + this.data.onload = function () + { + File.revokeObjectURL(_this.data); - collision = true; + _this.onProcessComplete(); + }; - if (collideCallback) - { - collideCallback.call(callbackContext, sprite, tile); - } + this.data.onerror = function () + { + File.revokeObjectURL(_this.data); - if (overlapOnly && body.onOverlap) - { - this.emit(Events.TILE_OVERLAP, sprite, tile, body); - } - else if (body.onCollide) - { - this.emit(Events.TILE_COLLIDE, sprite, tile, body); - } - } - } + _this.onProcessError(); + }; - return collision; + File.createObjectURL(this.data, this.xhrLoader.response, 'image/png'); }, /** - * Internal helper for Group vs. Group collisions. - * Please use Phaser.Physics.Arcade.World#collide instead. + * Handles image load processing. * - * @method Phaser.Physics.Arcade.World#collideGroupVsGroup + * @method Phaser.Loader.FileTypes.ImageFile#onProcessImage * @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. + * @since 3.60.0 */ - collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) + onProcessImage: function () { - if (group1.length === 0 || group2.length === 0) - { - return; - } - - var children = group1.getChildren(); + var result = this.state; - for (var i = 0; i < children.length; i++) - { - this.collideSpriteVsGroup(children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly); - } - }, + this.state = CONST.FILE_PROCESSING; - /** - * 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)) + if (result === CONST.FILE_LOADED) { - this.wrapArray(object, padding); + this.onProcessComplete(); } else { - this.wrapObject(object, padding); + this.onProcessError(); } }, /** - * Wrap each object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}. - * - * @method Phaser.Physics.Arcade.World#wrapArray - * @since 3.3.0 + * Loads the image using either XHR or an Image tag. * - * @param {Array.<*>} objects - An array of objects to be wrapped. - * @param {number} [padding=0] - An amount added to the boundary. + * @method Phaser.Loader.FileTypes.ImageFile#loadImage + * @private + * @since 3.60.0 */ - wrapArray: function (objects, padding) + loadImage: function () { - for (var i = 0; i < objects.length; i++) + this.state = CONST.FILE_LOADING; + + this.src = GetURL(this, this.loader.baseURL); + + if (this.src.indexOf('data:') === 0) { - this.wrapObject(objects[i], padding); + console.warn('Local data URIs are not supported: ' + this.key); } - }, + else + { + this.data = new Image(); - /** - * 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; } + this.data.crossOrigin = this.crossOrigin; - 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); - }, + var _this = this; - /** - * 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.data.onload = function () + { + _this.state = CONST.FILE_LOADED; - this.removeAllListeners(); + _this.loader.nextFile(_this, true); + }; + + this.data.onerror = function () + { + _this.loader.nextFile(_this, false); + }; + + this.data.src = this.src; + } }, /** - * Shuts down the simulation and disconnects it from the current scene. + * Adds this file to its target cache upon successful loading and processing. * - * @method Phaser.Physics.Arcade.World#destroy - * @since 3.0.0 + * @method Phaser.Loader.FileTypes.ImageFile#addToCache + * @since 3.7.0 */ - destroy: function () + addToCache: function () { - this.shutdown(); + // Check if we have a linked normal map + var linkFile = this.linkFile; - this.scene = null; + if (linkFile) + { + // We do, but has it loaded? + if (linkFile.state >= CONST.FILE_COMPLETE) + { + // Both files have loaded + if (this.type === 'normalMap') + { + // linkFile.data = Image + // this.data = Normal Map + this.cache.addImage(this.key, linkFile.data, this.data); + } + else + { + // linkFile.data = Normal Map + // this.data = Image + this.cache.addImage(this.key, this.data, linkFile.data); + } + } + + // Nothing to do here, we'll use the linkFile `addToCache` call + // to process this pair + } + else + { + this.cache.addImage(this.key, this.data); + } } }); -module.exports = World; - - -/***/ }), -/* 527 */ -/***/ (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__(62); -var Events = __webpack_require__(245); -var RadToDeg = __webpack_require__(196); -var Rectangle = __webpack_require__(10); -var RectangleContains = __webpack_require__(57); -var Vector2 = __webpack_require__(3); - /** - * @classdesc - * A Dynamic Arcade Body. + * Adds an Image, or array of Images, to the current load queue. * - * Its static counterpart is {@link Phaser.Physics.Arcade.StaticBody}. + * You can call this method from within your Scene's `preload`, along with any other files you wish to load: * - * @class Body - * @memberof Phaser.Physics.Arcade - * @constructor - * @since 3.0.0 + * ```javascript + * function preload () + * { + * this.load.image('logo', 'images/phaserLogo.png'); + * } + * ``` * - * @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 + * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, + * or if it's already running, when the next free load slot becomes available. This happens automatically if you + * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued + * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. + * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the + * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been + * loaded. + * + * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. + * If you try to load an animated gif only the first frame will be rendered. Browsers do not natively support playback + * of animated gifs to Canvas elements. + * + * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.image({ + * key: 'logo', + * url: 'images/AtariLogo.png' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.ImageFileConfig` for more details. + * + * Once the file has finished loading you can use it as a texture for a Game Object by referencing its key: + * + * ```javascript + * this.load.image('logo', 'images/AtariLogo.png'); + * // and later in your game ... + * this.add.image(x, y, 'logo'); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use to retrieve the image from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" + * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, + * then you can specify it by providing an array as the `url` where the second element is the normal map: + * + * ```javascript + * this.load.image('logo', [ 'images/AtariLogo.png', 'images/AtariLogo-n.png' ]); + * ``` + * + * Or, if you are using a config object use the `normalMap` property: + * + * ```javascript + * this.load.image({ + * key: 'logo', + * url: 'images/AtariLogo.png', + * normalMap: 'images/AtariLogo-n.png' + * }); + * ``` + * + * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. + * Normal maps are a WebGL only feature. + * + * In Phaser 3.60 a new property was added that allows you to control how images are loaded. By default, images are loaded via XHR as Blobs. + * However, you can set `loader.imageLoadType: "HTMLImageElement"` in the Game Configuration and instead, the Loader will load all images + * via the Image tag instead. + * + * Note: The ability to load this type of file will only be available if the Image File type has been built into Phaser. + * It is available in the default build but can be excluded from custom builds. + * + * @method Phaser.Loader.LoaderPlugin#image + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.ImageFileConfig|Phaser.Types.Loader.FileTypes.ImageFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. + * + * @return {this} The Loader instance. + */ +FileTypesManager.register('image', function (key, url, xhrSettings) +{ + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object + this.addFile(new ImageFile(this, key[i])); + } + } + else + { + this.addFile(new ImageFile(this, key, url, xhrSettings)); + } + + return this; +}); + +module.exports = ImageFile; + + +/***/ }), + +/***/ 70806: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var GetValue = __webpack_require__(10850); +var IsPlainObject = __webpack_require__(42911); + +/** + * @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 }; - /** - * 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; + File.call(this, loader, fileConfig); + + // A JSON object has been provided (instead of a URL), so we'll use it directly as the File.data. No need to load it. + if (IsPlainObject(url)) + { + 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; + + try + { + var json = JSON.parse(this.xhrLoader.responseText); + } + catch (e) + { + this.onProcessError(); + + throw e; + } + + 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; + + +/***/ }), + +/***/ 80802: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var ImageFile = __webpack_require__(42927); +var IsPlainObject = __webpack_require__(42911); +var JSONFile = __webpack_require__(70806); +var MultiFile = __webpack_require__(45176); + +/** + * @classdesc + * A single Multi Texture Atlas File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#multiatlas method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#multiatlas. + * + * @class MultiAtlasFile + * @extends Phaser.Loader.MultiFile + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.7.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.MultiAtlasFileConfig)} key - The key of the file. Must be unique within both the Loader and the Texture Manager. Or a config object. + * @param {string} [atlasURL] - The absolute or relative URL to load the multi atlas json file from. + * @param {string} [path] - Optional path to use when loading the textures defined in the atlas data. + * @param {string} [baseURL] - Optional Base URL to use when loading the textures defined in the atlas data. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - Extra XHR Settings specifically for the atlas json file. + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - Extra XHR Settings specifically for the texture files. + */ +var MultiAtlasFile = new Class({ + + Extends: MultiFile, + + initialize: + + function MultiAtlasFile (loader, key, atlasURL, path, baseURL, atlasXhrSettings, textureXhrSettings) + { + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + + if (GetFastValue(config, 'url', false)) + { + atlasURL = GetFastValue(config, 'url'); + } + else + { + atlasURL = GetFastValue(config, 'atlasURL'); + } + + atlasXhrSettings = GetFastValue(config, 'xhrSettings'); + path = GetFastValue(config, 'path'); + baseURL = GetFastValue(config, 'baseURL'); + textureXhrSettings = GetFastValue(config, 'textureXhrSettings'); + } + + var data = new JSONFile(loader, key, atlasURL, atlasXhrSettings); + + MultiFile.call(this, loader, 'multiatlas', key, [ data ]); + + this.config.path = path; + this.config.baseURL = baseURL; + this.config.textureXhrSettings = textureXhrSettings; + }, + + /** + * Called by each File when it finishes loading. + * + * @method Phaser.Loader.FileTypes.MultiAtlasFile#onFileComplete + * @since 3.7.0 + * + * @param {Phaser.Loader.File} file - The File that has completed processing. + */ + onFileComplete: function (file) + { + var index = this.files.indexOf(file); + + if (index !== -1) + { + this.pending--; + + if (file.type === 'json' && file.data.hasOwnProperty('textures')) + { + // Inspect the data for the files to now load + var textures = file.data.textures; + + var config = this.config; + var loader = this.loader; + + var currentBaseURL = loader.baseURL; + var currentPath = loader.path; + var currentPrefix = loader.prefix; + + var baseURL = GetFastValue(config, 'baseURL', this.baseURL); + var path = GetFastValue(config, 'path', this.path); + var prefix = GetFastValue(config, 'prefix', this.prefix); + var textureXhrSettings = GetFastValue(config, 'textureXhrSettings'); + + loader.setBaseURL(baseURL); + loader.setPath(path); + loader.setPrefix(prefix); + + for (var i = 0; i < textures.length; i++) + { + // "image": "texture-packer-multi-atlas-0.png", + var textureURL = textures[i].image; + + var key = 'MA' + this.multiKeyIndex + '_' + textureURL; + + var image = new ImageFile(loader, key, textureURL, textureXhrSettings); + + this.addToMultiFile(image); + + loader.addFile(image); + + // "normalMap": "texture-packer-multi-atlas-0_n.png", + if (textures[i].normalMap) + { + var normalMap = new ImageFile(loader, key, textures[i].normalMap, textureXhrSettings); + + normalMap.type = 'normalMap'; + + image.setLink(normalMap); + + this.addToMultiFile(normalMap); + + loader.addFile(normalMap); + } + } + + // Reset the loader settings + loader.setBaseURL(currentBaseURL); + loader.setPath(currentPath); + loader.setPrefix(currentPrefix); + } + } + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.MultiAtlasFile#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + if (this.isReadyToProcess()) + { + var fileJSON = this.files[0]; + + var data = []; + var images = []; + var normalMaps = []; + + for (var i = 1; i < this.files.length; i++) + { + var file = this.files[i]; + + if (file.type === 'normalMap') + { + continue; + } + + var pos = file.key.indexOf('_'); + var key = file.key.substr(pos + 1); + + var image = file.data; + + // Now we need to find out which json entry this mapped to + for (var t = 0; t < fileJSON.data.textures.length; t++) + { + var item = fileJSON.data.textures[t]; + + if (item.image === key) + { + images.push(image); + + data.push(item); + + if (file.linkFile) + { + normalMaps.push(file.linkFile.data); + } + + break; + } + } + } + + if (normalMaps.length === 0) + { + normalMaps = undefined; + } + + this.loader.textureManager.addAtlasJSONArray(this.key, images, data, normalMaps); + + this.complete = true; + } + } + +}); + +/** + * Adds a Multi Texture Atlas, or array of multi atlases, 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.multiatlas('level1', 'images/Level1.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. + * + * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring + * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. + * + * Phaser expects the atlas data to be provided in a JSON file as exported from the application Texture Packer, + * version 4.6.3 or above, where you have made sure to use the Phaser 3 Export option. + * + * The way it works internally is that you provide a URL to the JSON file. Phaser then loads this JSON, parses it and + * extracts which texture files it also needs to load to complete the process. If the JSON also defines normal maps, + * Phaser will load those as well. + * + * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.multiatlas({ + * key: 'level1', + * atlasURL: 'images/Level1.json' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.MultiAtlasFileConfig` for more details. + * + * Instead of passing a URL for the atlas JSON data you can also pass in a well formed JSON object instead. + * + * Once the atlas has finished loading you can use frames from it as textures for a Game Object by referencing its key: + * + * ```javascript + * this.load.multiatlas('level1', 'images/Level1.json'); + * // and later in your game ... + * this.add.image(x, y, 'level1', 'background'); + * ``` + * + * To get a list of all available frames within an atlas please consult your Texture Atlas software. + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use to retrieve the image from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" + * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Note: The ability to load this type of file will only be available if the Multi Atlas 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#multiatlas + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.7.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.MultiAtlasFileConfig|Phaser.Types.Loader.FileTypes.MultiAtlasFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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". + * @param {string} [path] - Optional path to use when loading the textures defined in the atlas data. + * @param {string} [baseURL] - Optional Base URL to use when loading the textures defined in the atlas data. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. + * + * @return {this} The Loader instance. + */ +FileTypesManager.register('multiatlas', function (key, atlasURL, path, baseURL, atlasXhrSettings) +{ + var multifile; + + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined + + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + multifile = new MultiAtlasFile(this, key[i]); + + this.addFile(multifile.files); + } + } + else + { + multifile = new MultiAtlasFile(this, key, atlasURL, path, baseURL, atlasXhrSettings); + + this.addFile(multifile.files); + } + + return this; +}); + +module.exports = MultiAtlasFile; + + +/***/ }), + +/***/ 39034: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); +var MultiFile = __webpack_require__(45176); +var ScriptFile = __webpack_require__(55188); + +/** + * @classdesc + * A Multi Script File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#scripts method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#scripts. + * + * @class MultiScriptFile + * @extends Phaser.Loader.MultiFile + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.17.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.MultiScriptFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string[]} [url] - An array of absolute or relative URLs to load the script files from. They are processed in the order given in the array. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object for the script files. Used in replacement of the Loaders default XHR Settings. + */ +var MultiScriptFile = new Class({ + + Extends: MultiFile, + + initialize: + + function MultiScriptFile (loader, key, url, xhrSettings) + { + var extension = 'js'; + var files = []; + + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + extension = GetFastValue(config, 'extension', extension); + } + + if (!Array.isArray(url)) + { + url = [ url ]; + } + + for (var i = 0; i < url.length; i++) + { + var scriptFile = new ScriptFile(loader, { + key: key + '_' + i.toString(), + url: url[i], + extension: extension, + xhrSettings: xhrSettings + }); + + // Override the default onProcess function + scriptFile.onProcess = function () + { + this.onProcessComplete(); + }; + + files.push(scriptFile); + } + + MultiFile.call(this, loader, 'scripts', key, files); + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.MultiScriptFile#addToCache + * @since 3.17.0 + */ + addToCache: function () + { + if (this.isReadyToProcess()) + { + for (var i = 0; i < this.files.length; i++) + { + var file = this.files[i]; + + file.data = document.createElement('script'); + file.data.language = 'javascript'; + file.data.type = 'text/javascript'; + file.data.defer = false; + file.data.text = file.xhrLoader.responseText; + + document.head.appendChild(file.data); + } + + this.complete = true; + } + } + +}); + +/** + * Adds an array of Script files to the current load queue. + * + * The difference between this and the `ScriptFile` file type is that you give an array of scripts to this method, + * and the scripts are then processed _exactly_ in that order. This allows you to load a bunch of scripts that + * may have dependencies on each other without worrying about the async nature of traditional script loading. + * + * 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.scripts('PostProcess', [ + * 'libs/shaders/CopyShader.js', + * 'libs/postprocessing/EffectComposer.js', + * 'libs/postprocessing/RenderPass.js', + * 'libs/postprocessing/MaskPass.js', + * 'libs/postprocessing/ShaderPass.js', + * 'libs/postprocessing/AfterimagePass.js' + * ]); + * } + * ``` + * + * In the code above the script files will all be loaded in parallel but only processed (i.e. invoked) in the exact + * order given in the array. + * + * The files are **not** loaded right away. They are 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 files are queued + * it means you cannot use the files immediately after calling this method, but must wait for the files 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.scripts({ + * key: 'PostProcess', + * url: [ + * 'libs/shaders/CopyShader.js', + * 'libs/postprocessing/EffectComposer.js', + * 'libs/postprocessing/RenderPass.js', + * 'libs/postprocessing/MaskPass.js', + * 'libs/postprocessing/ShaderPass.js', + * 'libs/postprocessing/AfterimagePass.js' + * ] + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.MultiScriptFileConfig` for more details. + * + * Once all the files have finished loading they will automatically be converted into a script element + * via `document.createElement('script')`. They will have their 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. This is done in the exact order the files are specified in the url array. + * + * The URLs can be relative or absolute. If the URLs are relative the `Loader.baseURL` and `Loader.path` values will be prepended to them. + * + * Note: The ability to load this type of file will only be available if the MultiScript 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#scripts + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.17.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.MultiScriptFileConfig|Phaser.Types.Loader.FileTypes.MultiScriptFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string[]} [url] - An array of absolute or relative URLs to load the script files from. They are processed in the order given in the array. + * @param {string} [extension='js'] - The default file extension to use if no url is provided. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for these files. + * + * @return {this} The Loader instance. + */ +FileTypesManager.register('scripts', function (key, url, xhrSettings) +{ + var multifile; + + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined + + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + multifile = new MultiScriptFile(this, key[i]); + + this.addFile(multifile.files); + } + } + else + { + multifile = new MultiScriptFile(this, key, url, xhrSettings); + + this.addFile(multifile.files); + } + + return this; +}); + +module.exports = MultiScriptFile; + + +/***/ }), + +/***/ 85527: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); +var MultiFile = __webpack_require__(45176); +var ParseObj = __webpack_require__(27291); +var ParseObjMaterial = __webpack_require__(76799); +var TextFile = __webpack_require__(86897); + +/** + * @classdesc + * A single Wavefront OBJ File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#obj method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#obj. + * + * @class OBJFile + * @extends Phaser.Loader.MultiFile + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.OBJFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string} [objURL] - The absolute or relative URL to load the obj file from. If undefined or `null` it will be set to `.obj`, i.e. if `key` was "alien" then the URL will be "alien.obj". + * @param {string} [matURL] - The absolute or relative URL to load the material file from. If undefined or `null` it will be set to `.mat`, i.e. if `key` was "alien" then the URL will be "alien.mat". + * @param {boolean} [flipUV] - Flip the UV coordinates stored in the model data? + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for these files. + */ +var OBJFile = new Class({ + + Extends: MultiFile, + + initialize: + + function OBJFile (loader, key, objURL, matURL, flipUV, xhrSettings) + { + var obj; + var mat; + + var cache = loader.cacheManager.obj; + + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + + obj = new TextFile(loader, { + key: key, + type: 'obj', + cache: cache, + url: GetFastValue(config, 'url'), + extension: GetFastValue(config, 'extension', 'obj'), + xhrSettings: GetFastValue(config, 'xhrSettings'), + config: { + flipUV: GetFastValue(config, 'flipUV', flipUV) + } + }); + + matURL = GetFastValue(config, 'matURL'); + + if (matURL) + { + mat = new TextFile(loader, { + key: key, + type: 'mat', + cache: cache, + url: matURL, + extension: GetFastValue(config, 'matExtension', 'mat'), + xhrSettings: GetFastValue(config, 'xhrSettings') + }); + } + } + else + { + obj = new TextFile(loader, { + key: key, + url: objURL, + type: 'obj', + cache: cache, + extension: 'obj', + xhrSettings: xhrSettings, + config: { + flipUV: flipUV + } + }); + + if (matURL) + { + mat = new TextFile(loader, { + key: key, + url: matURL, + type: 'mat', + cache: cache, + extension: 'mat', + xhrSettings: xhrSettings + }); + } + } + + MultiFile.call(this, loader, 'obj', key, [ obj, mat ]); + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.OBJFile#addToCache + * @since 3.50.0 + */ + addToCache: function () + { + if (this.isReadyToProcess()) + { + var obj = this.files[0]; + var mat = this.files[1]; + + var objData = ParseObj(obj.data, obj.config.flipUV); + + if (mat) + { + objData.materials = ParseObjMaterial(mat.data); + } + + obj.cache.add(obj.key, objData); + + this.complete = true; + } + } + +}); + +/** + * Adds a Wavefront OBJ file, or array of OBJ files, to the current load queue. + * + * Note: You should ensure your 3D package has triangulated the OBJ file prior to export. + * + * 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.obj('ufo', 'files/spaceship.obj'); + * } + * ``` + * + * You can optionally also load a Wavefront Material file as well, by providing the 3rd parameter: + * + * ```javascript + * function preload () + * { + * this.load.obj('ufo', 'files/spaceship.obj', 'files/spaceship.mtl'); + * } + * ``` + * + * If given, the material will be parsed and stored along with the obj data in the cache. + * + * 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 OBJ Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the OBJ 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 OBJ Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.obj({ + * key: 'ufo', + * url: 'files/spaceship.obj', + * matURL: 'files/spaceship.mtl', + * flipUV: true + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.OBJFileConfig` for more details. + * + * Once the file has finished loading you can access it from its Cache using its key: + * + * ```javascript + * this.load.obj('ufo', 'files/spaceship.obj'); + * // and later in your game ... + * var data = this.cache.obj.get('ufo'); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and + * this is what you would use to retrieve the obj from the OBJ Cache. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story" + * and no URL is given then the Loader will set the URL to be "story.obj". It will always add `.obj` 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 OBJ 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#obj + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.50.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.OBJFileConfig|Phaser.Types.Loader.FileTypes.OBJFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string} [objURL] - The absolute or relative URL to load the obj file from. If undefined or `null` it will be set to `.obj`, i.e. if `key` was "alien" then the URL will be "alien.obj". + * @param {string} [matURL] - Optional absolute or relative URL to load the obj material file from. + * @param {boolean} [flipUV] - Flip the UV coordinates stored in the model data? + * @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('obj', function (key, objURL, matURL, flipUVs, xhrSettings) +{ + var multifile; + + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + multifile = new OBJFile(this, key[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(multifile.files); + } + } + else + { + multifile = new OBJFile(this, key, objURL, matURL, flipUVs, xhrSettings); + + this.addFile(multifile.files); + } + + return this; +}); + +module.exports = OBJFile; + + +/***/ }), + +/***/ 3616: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var FileTypesManager = __webpack_require__(76846); +var JSONFile = __webpack_require__(70806); + +/** + * @classdesc + * A single JSON Pack File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#pack method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#pack. + * + * @class PackFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.7.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.PackFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {(string|any)} [url] - The absolute or relative URL to load this file from or a ready formed JSON object. If undefined or `null` it will be set to `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". + * @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 PackFile = new Class({ + + Extends: JSONFile, + + 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 PackFile (loader, key, url, xhrSettings, dataKey) + { + JSONFile.call(this, loader, key, url, xhrSettings, dataKey); + + this.type = 'packfile'; + }, + + /** + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. + * + * @method Phaser.Loader.FileTypes.PackFile#onProcess + * @since 3.7.0 + */ + onProcess: function () + { + if (this.state !== CONST.FILE_POPULATED) + { + this.state = CONST.FILE_PROCESSING; + + this.data = JSON.parse(this.xhrLoader.responseText); + } + + if (this.data.hasOwnProperty('files') && this.config) + { + var newData = {}; + + newData[this.config] = this.data; + + this.data = newData; + } + + // Let's pass the pack file data over to the Loader ... + this.loader.addPack(this.data, this.config); + + this.onProcessComplete(); + } + +}); + +/** + * Adds a JSON File Pack, or array of packs, 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.pack('level1', 'data/Level1Files.json'); + * } + * ``` + * + * A File Pack is a JSON file (or object) that contains details about other files that should be added into the Loader. + * Here is a small example: + * + * ```json + * { + * "test1": { + * "files": [ + * { + * "type": "image", + * "key": "taikodrummaster", + * "url": "assets/pics/taikodrummaster.jpg" + * }, + * { + * "type": "image", + * "key": "sukasuka-chtholly", + * "url": "assets/pics/sukasuka-chtholly.png" + * } + * ] + * }, + * "meta": { + * "generated": "1401380327373", + * "app": "Phaser 3 Asset Packer", + * "url": "https://phaser.io", + * "version": "1.0", + * "copyright": "Photon Storm Ltd. 2018" + * } + * } + * ``` + * + * The pack can be split into sections. In the example above you'll see a section called `test1. You can tell + * the `load.pack` method to parse only a particular section of a pack. The pack is stored in the JSON Cache, + * so you can pass it to the Loader to process additional sections as needed in your game, or you can just load + * them all at once without specifying anything. + * + * The pack file can contain an entry for any type of file that Phaser can load. The object structures exactly + * match that of the file type configs, and all properties available within the file type configs can be used + * in the pack file too. + * + * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, + * or if it's already running, when the next free load slot becomes available. This happens automatically if you + * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued + * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. + * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the + * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been + * loaded. + * + * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring + * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. + * + * 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.pack({ + * key: 'level1', + * url: 'data/Level1Files.json' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.PackFileConfig` for more details. + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `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 Pack 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#pack + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.7.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.PackFileConfig|Phaser.Types.Loader.FileTypes.PackFileConfig[])} 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 `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". + * @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('pack', function (key, url, dataKey, xhrSettings) +{ + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined + + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + this.addFile(new PackFile(this, key[i])); + } + } + else + { + this.addFile(new PackFile(this, key, url, xhrSettings, dataKey)); + } + + return this; +}); + +module.exports = PackFile; + + +/***/ }), + +/***/ 12217: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); + +/** + * @classdesc + * A single Plugin Script File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#plugin method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#plugin. + * + * @class PluginFile + * @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.PluginFileConfig)} 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 {boolean} [start=false] - Automatically start the plugin after loading? + * @param {string} [mapping] - If this plugin is to be injected into the Scene, this is the property key used. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var PluginFile = new Class({ + + Extends: File, + + initialize: + + function PluginFile (loader, key, url, start, mapping, 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); + start = GetFastValue(config, 'start'); + mapping = GetFastValue(config, 'mapping'); + } + + var fileConfig = { + type: 'plugin', + cache: false, + extension: extension, + responseType: 'text', + key: key, + url: url, + xhrSettings: xhrSettings, + config: { + start: start, + mapping: mapping + } + }; + + File.call(this, loader, fileConfig); + + // If the url variable refers to a class, add the plugin directly + if (typeof url === 'function') + { + 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.PluginFile#onProcess + * @since 3.7.0 + */ + onProcess: function () + { + var pluginManager = this.loader.systems.plugins; + var config = this.config; + + var start = GetFastValue(config, 'start', false); + var mapping = GetFastValue(config, 'mapping', null); + + if (this.state === CONST.FILE_POPULATED) + { + pluginManager.install(this.key, this.data, start, mapping); + } + else + { + // Plugin added via a js file + 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); + + var plugin = pluginManager.install(this.key, window[this.key], start, mapping); + + if (start || mapping) + { + // Install into the current Scene Systems and Scene + this.loader.systems[mapping] = plugin; + this.loader.scene[mapping] = plugin; + } + } + + this.onProcessComplete(); + } + +}); + +/** + * Adds a Plugin Script file, or array of plugin 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.plugin('modplayer', 'plugins/ModPlayer.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.plugin({ + * key: 'modplayer', + * url: 'plugins/ModPlayer.js' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.PluginFileConfig` 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. It will then be passed to the Phaser PluginCache.register method. + * + * 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 Plugin 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#plugin + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.PluginFileConfig|Phaser.Types.Loader.FileTypes.PluginFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {(string|function)} [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". Or, a plugin function. + * @param {boolean} [start] - Automatically start the plugin after loading? + * @param {string} [mapping] - If this plugin is to be injected into the Scene, this is the property key used. + * @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('plugin', function (key, url, start, mapping, 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 PluginFile(this, key[i])); + } + } + else + { + this.addFile(new PluginFile(this, key, url, start, mapping, xhrSettings)); + } + + return this; +}); + +module.exports = PluginFile; + + +/***/ }), + +/***/ 4474: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); + +/** + * @classdesc + * A single SVG File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#svg method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#svg. + * + * @class SVGFile + * @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.SVGFileConfig)} 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 `.svg`, i.e. if `key` was "alien" then the URL will be "alien.svg". + * @param {Phaser.Types.Loader.FileTypes.SVGSizeConfig} [svgConfig] - The svg size configuration object. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var SVGFile = new Class({ + + Extends: File, + + initialize: + + function SVGFile (loader, key, url, svgConfig, xhrSettings) + { + var extension = 'svg'; + + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url'); + svgConfig = GetFastValue(config, 'svgConfig', {}); + xhrSettings = GetFastValue(config, 'xhrSettings'); + extension = GetFastValue(config, 'extension', extension); + } + + var fileConfig = { + type: 'svg', + cache: loader.textureManager, + extension: extension, + responseType: 'text', + key: key, + url: url, + xhrSettings: xhrSettings, + config: { + width: GetFastValue(svgConfig, 'width'), + height: GetFastValue(svgConfig, 'height'), + scale: GetFastValue(svgConfig, 'scale') + } + }; + + 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.SVGFile#onProcess + * @since 3.7.0 + */ + onProcess: function () + { + this.state = CONST.FILE_PROCESSING; + + var text = this.xhrLoader.responseText; + var svg = [ text ]; + var width = this.config.width; + var height = this.config.height; + var scale = this.config.scale; + + resize: if (width && height || scale) + { + var xml = null; + var parser = new DOMParser(); + xml = parser.parseFromString(text, 'text/xml'); + var svgXML = xml.getElementsByTagName('svg')[0]; + + var hasViewBox = svgXML.hasAttribute('viewBox'); + var svgWidth = parseFloat(svgXML.getAttribute('width')); + var svgHeight = parseFloat(svgXML.getAttribute('height')); + + if (!hasViewBox && svgWidth && svgHeight) + { + // If there's no viewBox attribute, set one + svgXML.setAttribute('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight); + } + else if (hasViewBox && !svgWidth && !svgHeight) + { + // Get the w/h from the viewbox + var viewBox = svgXML.getAttribute('viewBox').split(/\s+|,/); + + svgWidth = viewBox[2]; + svgHeight = viewBox[3]; + } + + if (scale) + { + if (svgWidth && svgHeight) + { + width = svgWidth * scale; + height = svgHeight * scale; + } + else + { + break resize; + } + } + + svgXML.setAttribute('width', width.toString() + 'px'); + svgXML.setAttribute('height', height.toString() + 'px'); + + svg = [ (new XMLSerializer()).serializeToString(svgXML) ]; + } + + try + { + var blob = new window.Blob(svg, { type: 'image/svg+xml;charset=utf-8' }); + } + catch (e) + { + this.onProcessError(); + + return; + } + + this.data = new Image(); + + this.data.crossOrigin = this.crossOrigin; + + var _this = this; + var retry = false; + + this.data.onload = function () + { + if (!retry) + { + File.revokeObjectURL(_this.data); + } + + _this.onProcessComplete(); + }; + + this.data.onerror = function () + { + // Safari 8 re-try + if (!retry) + { + retry = true; + + File.revokeObjectURL(_this.data); + + _this.data.src = 'data:image/svg+xml,' + encodeURIComponent(svg.join('')); + } + else + { + _this.onProcessError(); + } + }; + + File.createObjectURL(this.data, blob, 'image/svg+xml'); + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.SVGFile#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + this.cache.addImage(this.key, this.data); + } + +}); + +/** + * Adds an SVG File, or array of SVG Files, to the current load queue. When the files are loaded they + * will be rendered to bitmap textures and stored in the Texture Manager. + * + * 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.svg('morty', 'images/Morty.svg'); + * } + * ``` + * + * 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 Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.svg({ + * key: 'morty', + * url: 'images/Morty.svg' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.SVGFileConfig` for more details. + * + * Once the file has finished loading you can use it as a texture for a Game Object by referencing its key: + * + * ```javascript + * this.load.svg('morty', 'images/Morty.svg'); + * // and later in your game ... + * this.add.image(x, y, 'morty'); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use to retrieve the image from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" + * and no URL is given then the Loader will set the URL to be "alien.html". It will always add `.html` 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 optionally pass an SVG Resize Configuration object when you load an SVG file. By default the SVG will be rendered to a texture + * at the same size defined in the SVG file attributes. However, this isn't always desirable. You may wish to resize the SVG (either down + * or up) to improve texture clarity, or reduce texture memory consumption. You can either specify an exact width and height to resize + * the SVG to: + * + * ```javascript + * function preload () + * { + * this.load.svg('morty', 'images/Morty.svg', { width: 300, height: 600 }); + * } + * ``` + * + * Or when using a configuration object: + * + * ```javascript + * this.load.svg({ + * key: 'morty', + * url: 'images/Morty.svg', + * svgConfig: { + * width: 300, + * height: 600 + * } + * }); + * ``` + * + * Alternatively, you can just provide a scale factor instead: + * + * ```javascript + * function preload () + * { + * this.load.svg('morty', 'images/Morty.svg', { scale: 2.5 }); + * } + * ``` + * + * Or when using a configuration object: + * + * ```javascript + * this.load.svg({ + * key: 'morty', + * url: 'images/Morty.svg', + * svgConfig: { + * scale: 2.5 + * } + * }); + * ``` + * + * If scale, width and height values are all given, the scale has priority and the width and height values are ignored. + * + * Note: The ability to load this type of file will only be available if the SVG 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#svg + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.SVGFileConfig|Phaser.Types.Loader.FileTypes.SVGFileConfig[])} 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 `.svg`, i.e. if `key` was "alien" then the URL will be "alien.svg". + * @param {Phaser.Types.Loader.FileTypes.SVGSizeConfig} [svgConfig] - The svg size configuration object. + * @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('svg', function (key, url, svgConfig, 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 SVGFile(this, key[i])); + } + } + else + { + this.addFile(new SVGFile(this, key, url, svgConfig, xhrSettings)); + } + + return this; +}); + +module.exports = SVGFile; + + + +/***/ }), + +/***/ 95171: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); + +/** + * @classdesc + * An external Scene JavaScript File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#sceneFile method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#sceneFile. + * + * @class SceneFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.16.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.SceneFileConfig)} 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 SceneFile = new Class({ + + Extends: File, + + initialize: + + function SceneFile (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: 'text', + extension: extension, + responseType: 'text', + key: key, + url: url, + xhrSettings: xhrSettings + }; + + File.call(this, loader, fileConfig); + }, + + /** + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. + * + * @method Phaser.Loader.FileTypes.SceneFile#onProcess + * @since 3.16.0 + */ + onProcess: function () + { + this.state = CONST.FILE_PROCESSING; + + this.data = this.xhrLoader.responseText; + + this.onProcessComplete(); + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.SceneFile#addToCache + * @since 3.16.0 + */ + addToCache: function () + { + var code = this.data.concat('(function(){\n' + 'return new ' + this.key + '();\n' + '}).call(this);'); + + // Stops rollup from freaking out during build + var eval2 = eval; + + this.loader.sceneManager.add(this.key, eval2(code)); + + this.complete = true; + } + +}); + +/** + * Adds an external Scene file, or array of Scene 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.sceneFile('Level1', 'src/Level1.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. It is used to add the file to the global Scene Manager upon a successful load. + * + * For a Scene File it's vitally important that the key matches the class name in the JavaScript file. + * + * For example here is the source file: + * + * ```javascript + * class ExternalScene extends Phaser.Scene { + * + * constructor () + * { + * super('myScene'); + * } + * + * } + * ``` + * + * Because the class is called `ExternalScene` that is the exact same key you must use when loading it: + * + * ```javascript + * function preload () + * { + * this.load.sceneFile('ExternalScene', 'src/yourScene.js'); + * } + * ``` + * + * The key that is used within the Scene Manager can either be set to the same, or you can override it in the Scene + * constructor, as we've done in the example above, where the Scene key was changed to `myScene`. + * + * The key should be unique both in terms of files being loaded and Scenes already present in the Scene Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Scene Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.sceneFile({ + * key: 'Level1', + * url: 'src/Level1.js' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.SceneFileConfig` for more details. + * + * Once the file has finished loading it will be added to the Scene Manager. + * + * ```javascript + * this.load.sceneFile('Level1', 'src/Level1.js'); + * // and later in your game ... + * this.scene.start('Level1'); + * ``` + * + * 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 `WORLD1.` and the key was `Story` the final key will be `WORLD1.Story` and + * this is what you would use to retrieve the text from the Scene Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story" + * and no URL is given then the Loader will set the URL to be "story.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 Scene 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#sceneFile + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.16.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.SceneFileConfig|Phaser.Types.Loader.FileTypes.SceneFileConfig[])} 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('sceneFile', 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 SceneFile(this, key[i])); + } + } + else + { + this.addFile(new SceneFile(this, key, url, xhrSettings)); + } + + return this; +}); + +module.exports = SceneFile; + + +/***/ }), + +/***/ 82458: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); + +/** + * @classdesc + * A single Scene Plugin Script File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#scenePlugin method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#scenePlugin. + * + * @class ScenePluginFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.8.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.ScenePluginFileConfig)} 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 {string} [systemKey] - If this plugin is to be added to Scene.Systems, this is the property key for it. + * @param {string} [sceneKey] - If this plugin is to be added to the Scene, this is the property key for it. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var ScenePluginFile = new Class({ + + Extends: File, + + initialize: + + function ScenePluginFile (loader, key, url, systemKey, sceneKey, 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); + systemKey = GetFastValue(config, 'systemKey'); + sceneKey = GetFastValue(config, 'sceneKey'); + } + + var fileConfig = { + type: 'scenePlugin', + cache: false, + extension: extension, + responseType: 'text', + key: key, + url: url, + xhrSettings: xhrSettings, + config: { + systemKey: systemKey, + sceneKey: sceneKey + } + }; + + File.call(this, loader, fileConfig); + + // If the url variable refers to a class, add the plugin directly + if (typeof url === 'function') + { + 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.ScenePluginFile#onProcess + * @since 3.8.0 + */ + onProcess: function () + { + var pluginManager = this.loader.systems.plugins; + var config = this.config; + + var key = this.key; + var systemKey = GetFastValue(config, 'systemKey', key); + var sceneKey = GetFastValue(config, 'sceneKey', key); + + if (this.state === CONST.FILE_POPULATED) + { + pluginManager.installScenePlugin(systemKey, this.data, sceneKey, this.loader.scene, true); + } + else + { + // Plugin added via a js file + 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); + + pluginManager.installScenePlugin(systemKey, window[this.key], sceneKey, this.loader.scene, true); + } + + this.onProcessComplete(); + } + +}); + +/** + * Adds a Scene Plugin Script file, or array of plugin 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.scenePlugin('ModPlayer', 'plugins/ModPlayer.js', 'modPlayer', 'mods'); + * } + * ``` + * + * 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.scenePlugin({ + * key: 'modplayer', + * url: 'plugins/ModPlayer.js' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.ScenePluginFileConfig` 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. It will then be passed to the Phaser PluginCache.register method. + * + * 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#scenePlugin + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.8.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.ScenePluginFileConfig|Phaser.Types.Loader.FileTypes.ScenePluginFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {(string|function)} [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". Or, set to a plugin function. + * @param {string} [systemKey] - If this plugin is to be added to Scene.Systems, this is the property key for it. + * @param {string} [sceneKey] - If this plugin is to be added to the Scene, this is the property key for it. + * @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('scenePlugin', function (key, url, systemKey, sceneKey, 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 ScenePluginFile(this, key[i])); + } + } + else + { + this.addFile(new ScenePluginFile(this, key, url, systemKey, sceneKey, xhrSettings)); + } + + return this; +}); + +module.exports = ScenePluginFile; + + +/***/ }), + +/***/ 55188: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); + +/** + * @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 {string} [type='script'] - The script type. Should be either 'script' for classic JavaScript, or 'module' if the file contains an exported module. + * @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, type, xhrSettings) + { + var extension = 'js'; + + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url'); + type = GetFastValue(config, 'type', 'script'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + extension = GetFastValue(config, 'extension', extension); + } + else if (type === undefined) + { + type = 'script'; + } + + var fileConfig = { + type: type, + 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'); + * } + * ``` + * + * If the script file contains a module, then you should specify that using the 'type' parameter: + * + * ```javascript + * function preload () + * { + * this.load.script('aliens', 'lib/aliens.js', 'module'); + * } + * ``` + * + * 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', + * type: 'script' // or 'module' + * }); + * ``` + * + * 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 {string} [type='script'] - The script type. Should be either 'script' for classic JavaScript, or 'module' if the file contains an exported module. + * @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, type, 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, type, xhrSettings)); + } + + return this; +}); + +module.exports = ScriptFile; + + +/***/ }), + +/***/ 33536: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var FileTypesManager = __webpack_require__(76846); +var ImageFile = __webpack_require__(42927); + +/** + * @classdesc + * A single Sprite Sheet Image File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#spritesheet method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#spritesheet. + * + * @class SpriteSheetFile + * @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.SpriteSheetFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {Phaser.Types.Loader.FileTypes.ImageFrameConfig} [frameConfig] - The frame configuration object. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var SpriteSheetFile = new Class({ + + Extends: ImageFile, + + initialize: + + function SpriteSheetFile (loader, key, url, frameConfig, xhrSettings) + { + ImageFile.call(this, loader, key, url, xhrSettings, frameConfig); + + this.type = 'spritesheet'; + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.SpriteSheetFile#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + // Check if we have a linked normal map + var linkFile = this.linkFile; + + if (linkFile) + { + // We do, but has it loaded? + if (linkFile.state >= CONST.FILE_COMPLETE) + { + // Both files have loaded + if (this.type === 'normalMap') + { + // linkFile.data = Image + // this.data = Normal Map + this.cache.addSpriteSheet(this.key, linkFile.data, this.config, this.data); + } + else + { + // linkFile.data = Normal Map + // this.data = Image + this.cache.addSpriteSheet(this.key, this.data, this.config, linkFile.data); + } + } + + // Nothing to do here, we'll use the linkFile `addToCache` call + // to process this pair + } + else + { + this.cache.addSpriteSheet(this.key, this.data, this.config); + } + } + +}); + +/** + * Adds a Sprite Sheet Image, or array of Sprite Sheet Images, to the current load queue. + * + * The term 'Sprite Sheet' in Phaser means a fixed-size sheet. Where every frame in the sheet is the exact same size, + * and you reference those frames using numbers, not frame names. This is not the same thing as a Texture Atlas, where + * the frames are packed in a way where they take up the least amount of space, and are referenced by their names, + * not numbers. Some articles and software use the term 'Sprite Sheet' to mean Texture Atlas, so please be aware of + * what sort of file you're actually trying to load. + * + * 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.spritesheet('bot', 'images/robot.png', { frameWidth: 32, frameHeight: 38 }); + * } + * ``` + * + * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, + * or if it's already running, when the next free load slot becomes available. This happens automatically if you + * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued + * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. + * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the + * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been + * loaded. + * + * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. + * If you try to load an animated gif only the first frame will be rendered. Browsers do not natively support playback + * of animated gifs to Canvas elements. + * + * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.spritesheet({ + * key: 'bot', + * url: 'images/robot.png', + * frameConfig: { + * frameWidth: 32, + * frameHeight: 38, + * startFrame: 0, + * endFrame: 8 + * } + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.SpriteSheetFileConfig` for more details. + * + * Once the file has finished loading you can use it as a texture for a Game Object by referencing its key: + * + * ```javascript + * this.load.spritesheet('bot', 'images/robot.png', { frameWidth: 32, frameHeight: 38 }); + * // and later in your game ... + * this.add.image(x, y, 'bot', 0); + * ``` + * + * 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 `PLAYER.` and the key was `Running` the final key will be `PLAYER.Running` and + * this is what you would use to retrieve the image from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" + * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, + * then you can specify it by providing an array as the `url` where the second element is the normal map: + * + * ```javascript + * this.load.spritesheet('logo', [ 'images/AtariLogo.png', 'images/AtariLogo-n.png' ], { frameWidth: 256, frameHeight: 80 }); + * ``` + * + * Or, if you are using a config object use the `normalMap` property: + * + * ```javascript + * this.load.spritesheet({ + * key: 'logo', + * url: 'images/AtariLogo.png', + * normalMap: 'images/AtariLogo-n.png', + * frameConfig: { + * frameWidth: 256, + * frameHeight: 80 + * } + * }); + * ``` + * + * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. + * Normal maps are a WebGL only feature. + * + * Note: The ability to load this type of file will only be available if the Sprite Sheet 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#spritesheet + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.SpriteSheetFileConfig|Phaser.Types.Loader.FileTypes.SpriteSheetFileConfig[])} 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 `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {Phaser.Types.Loader.FileTypes.ImageFrameConfig} [frameConfig] - The frame configuration object. At a minimum it should have a `frameWidth` property. + * @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('spritesheet', function (key, url, frameConfig, 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 SpriteSheetFile(this, key[i])); + } + } + else + { + this.addFile(new SpriteSheetFile(this, key, url, frameConfig, xhrSettings)); + } + + return this; +}); + +module.exports = SpriteSheetFile; + + +/***/ }), + +/***/ 86897: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); + +/** + * @classdesc + * A single Text File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#text method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#text. + * + * @class TextFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.TextFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var TextFile = new Class({ + + Extends: File, + + initialize: + + function TextFile (loader, key, url, xhrSettings) + { + var type = 'text'; + var extension = 'txt'; + var cache = loader.cacheManager.text; + + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url'); + xhrSettings = GetFastValue(config, 'xhrSettings'); + extension = GetFastValue(config, 'extension', extension); + type = GetFastValue(config, 'type', type); + cache = GetFastValue(config, 'cache', cache); + } + + var fileConfig = { + type: type, + cache: cache, + extension: extension, + responseType: 'text', + key: key, + url: url, + xhrSettings: xhrSettings + }; + + File.call(this, loader, fileConfig); + }, + + /** + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. + * + * @method Phaser.Loader.FileTypes.TextFile#onProcess + * @since 3.7.0 + */ + onProcess: function () + { + this.state = CONST.FILE_PROCESSING; + + this.data = this.xhrLoader.responseText; + + this.onProcessComplete(); + } + +}); + +/** + * Adds a Text file, or array of Text files, to the current load queue. + * + * You can call this method from within your Scene's `preload`, along with any other files you wish to load: + * + * ```javascript + * function preload () + * { + * this.load.text('story', 'files/IntroStory.txt'); + * } + * ``` + * + * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, + * or if it's already running, when the next free load slot becomes available. This happens automatically if you + * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued + * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. + * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the + * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been + * loaded. + * + * The key must be a unique String. It is used to add the file to the global Text Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Text Cache. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Text Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.text({ + * key: 'story', + * url: 'files/IntroStory.txt' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.TextFileConfig` for more details. + * + * Once the file has finished loading you can access it from its Cache using its key: + * + * ```javascript + * this.load.text('story', 'files/IntroStory.txt'); + * // and later in your game ... + * var data = this.cache.text.get('story'); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and + * this is what you would use to retrieve the text from the Text Cache. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story" + * and no URL is given then the Loader will set the URL to be "story.txt". It will always add `.txt` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Note: The ability to load this type of file will only be available if the Text File type has been built into Phaser. + * It is available in the default build but can be excluded from custom builds. + * + * @method Phaser.Loader.LoaderPlugin#text + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.TextFileConfig|Phaser.Types.Loader.FileTypes.TextFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. + * + * @return {this} The Loader instance. + */ +FileTypesManager.register('text', function (key, url, xhrSettings) +{ + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object + this.addFile(new TextFile(this, key[i])); + } + } + else + { + this.addFile(new TextFile(this, key, url, xhrSettings)); + } + + return this; +}); + +module.exports = TextFile; + + +/***/ }), + +/***/ 58673: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); +var TILEMAP_FORMATS = __webpack_require__(93560); + +/** + * @classdesc + * A single Tilemap CSV File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#tilemapCSV method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#tilemapCSV. + * + * @class TilemapCSVFile + * @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.TilemapCSVFileConfig)} 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 `.csv`, i.e. if `key` was "alien" then the URL will be "alien.csv". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var TilemapCSVFile = new Class({ + + Extends: File, + + initialize: + + function TilemapCSVFile (loader, key, url, xhrSettings) + { + var extension = 'csv'; + + 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: 'tilemapCSV', + cache: loader.cacheManager.tilemap, + extension: extension, + responseType: 'text', + key: key, + url: url, + xhrSettings: xhrSettings + }; + + File.call(this, loader, fileConfig); + + this.tilemapFormat = TILEMAP_FORMATS.CSV; + }, + + /** + * Called automatically by Loader.nextFile. + * This method controls what extra work this File does with its loaded data. + * + * @method Phaser.Loader.FileTypes.TilemapCSVFile#onProcess + * @since 3.7.0 + */ + onProcess: function () + { + this.state = CONST.FILE_PROCESSING; + + this.data = this.xhrLoader.responseText; + + this.onProcessComplete(); + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.TilemapCSVFile#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + var tiledata = { format: this.tilemapFormat, data: this.data }; + + this.cache.add(this.key, tiledata); + } + +}); + +/** + * Adds a CSV Tilemap file, or array of CSV 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.tilemapCSV('level1', 'maps/Level1.csv'); + * } + * ``` + * + * Tilemap CSV data can be created in a text editor, or a 3rd party app that exports as CSV. + * + * 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 Tilemap Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Tilemap Cache. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Text Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.tilemapCSV({ + * key: 'level1', + * url: 'maps/Level1.csv' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.TilemapCSVFileConfig` for more details. + * + * Once the file has finished loading you can access it from its Cache using its key: + * + * ```javascript + * this.load.tilemapCSV('level1', 'maps/Level1.csv'); + * // and later in your game ... + * var map = this.make.tilemap({ key: 'level1' }); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and + * this is what you would use to retrieve the text from the Tilemap 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 "level" + * and no URL is given then the Loader will set the URL to be "level.csv". It will always add `.csv` 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 Tilemap CSV 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#tilemapCSV + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.TilemapCSVFileConfig|Phaser.Types.Loader.FileTypes.TilemapCSVFileConfig[])} 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 `.csv`, i.e. if `key` was "alien" then the URL will be "alien.csv". + * @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('tilemapCSV', 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 TilemapCSVFile(this, key[i])); + } + } + else + { + this.addFile(new TilemapCSVFile(this, key, url, xhrSettings)); + } + + return this; +}); + +module.exports = TilemapCSVFile; + + +/***/ }), + +/***/ 98896: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var JSONFile = __webpack_require__(70806); +var TILEMAP_FORMATS = __webpack_require__(93560); + +/** + * @classdesc + * A single Impact.js Tilemap JSON File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#tilemapImpact method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#tilemapImpact. + * + * @class TilemapImpactFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.7.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.TilemapImpactFileConfig)} 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 `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var TilemapImpactFile = new Class({ + + Extends: JSONFile, + + initialize: + + function TilemapImpactFile (loader, key, url, xhrSettings) + { + JSONFile.call(this, loader, key, url, xhrSettings); + + this.type = 'tilemapJSON'; + + this.cache = loader.cacheManager.tilemap; + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.TilemapImpactFile#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + var tiledata = { format: TILEMAP_FORMATS.WELTMEISTER, data: this.data }; + + this.cache.add(this.key, tiledata); + } + +}); + +/** + * Adds an Impact.js Tilemap file, or array of map 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.tilemapImpact('level1', 'maps/Level1.json'); + * } + * ``` + * + * Impact Tilemap data is created the Impact.js Map Editor called Weltmeister. + * + * 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 Tilemap Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Tilemap Cache. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Text Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.tilemapImpact({ + * key: 'level1', + * url: 'maps/Level1.json' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.TilemapImpactFileConfig` for more details. + * + * Once the file has finished loading you can access it from its Cache using its key: + * + * ```javascript + * this.load.tilemapImpact('level1', 'maps/Level1.json'); + * // and later in your game ... + * var map = this.make.tilemap({ key: 'level1' }); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and + * this is what you would use to retrieve the text from the Tilemap 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 "level" + * and no URL is given then the Loader will set the URL to be "level.json". It will always add `.json` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Note: The ability to load this type of file will only be available if the Tilemap Impact 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#tilemapImpact + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.7.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.TilemapImpactFileConfig|Phaser.Types.Loader.FileTypes.TilemapImpactFileConfig[])} 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 `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". + * @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('tilemapImpact', 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 TilemapImpactFile(this, key[i])); + } + } + else + { + this.addFile(new TilemapImpactFile(this, key, url, xhrSettings)); + } + + return this; +}); + +module.exports = TilemapImpactFile; + + +/***/ }), + +/***/ 50563: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var JSONFile = __webpack_require__(70806); +var TILEMAP_FORMATS = __webpack_require__(93560); + +/** + * @classdesc + * A single Tiled Tilemap JSON File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#tilemapTiledJSON method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#tilemapTiledJSON. + * + * @class TilemapJSONFile + * @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.TilemapJSONFileConfig)} 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, a well formed JSON object. + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var TilemapJSONFile = new Class({ + + Extends: JSONFile, + + initialize: + + function TilemapJSONFile (loader, key, url, xhrSettings) + { + JSONFile.call(this, loader, key, url, xhrSettings); + + this.type = 'tilemapJSON'; + + this.cache = loader.cacheManager.tilemap; + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.TilemapJSONFile#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + var tiledata = { format: TILEMAP_FORMATS.TILED_JSON, data: this.data }; + + this.cache.add(this.key, tiledata); + } + +}); + +/** + * Adds a Tiled JSON Tilemap file, or array of map 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.tilemapTiledJSON('level1', 'maps/Level1.json'); + * } + * ``` + * + * The Tilemap data is created using the Tiled Map Editor and selecting JSON as the export format. + * + * 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 Tilemap Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Tilemap Cache. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Text Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.tilemapTiledJSON({ + * key: 'level1', + * url: 'maps/Level1.json' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.TilemapJSONFileConfig` for more details. + * + * Once the file has finished loading you can access it from its Cache using its key: + * + * ```javascript + * this.load.tilemapTiledJSON('level1', 'maps/Level1.json'); + * // and later in your game ... + * var map = this.make.tilemap({ key: 'level1' }); + * ``` + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and + * this is what you would use to retrieve the text from the Tilemap 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 "level" + * and no URL is given then the Loader will set the URL to be "level.json". It will always add `.json` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Note: The ability to load this type of file will only be available if the Tilemap 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#tilemapTiledJSON + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.TilemapJSONFileConfig|Phaser.Types.Loader.FileTypes.TilemapJSONFileConfig[])} 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, a well formed JSON object. + * @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('tilemapTiledJSON', 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 TilemapJSONFile(this, key[i])); + } + } + else + { + this.addFile(new TilemapJSONFile(this, key, url, xhrSettings)); + } + + return this; +}); + +module.exports = TilemapJSONFile; + + +/***/ }), + +/***/ 82857: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var ImageFile = __webpack_require__(42927); +var IsPlainObject = __webpack_require__(42911); +var MultiFile = __webpack_require__(45176); +var TextFile = __webpack_require__(86897); + +/** + * @classdesc + * A single text file based Unity Texture Atlas File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#unityAtlas method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#unityAtlas. + * + * @class UnityAtlasFile + * @extends Phaser.Loader.MultiFile + * @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.UnityAtlasFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas data file from. If undefined or `null` it will be set to `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings. + */ +var UnityAtlasFile = new Class({ + + Extends: MultiFile, + + initialize: + + function UnityAtlasFile (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) + { + var image; + var data; + + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + + image = new ImageFile(loader, { + key: key, + url: GetFastValue(config, 'textureURL'), + extension: GetFastValue(config, 'textureExtension', 'png'), + normalMap: GetFastValue(config, 'normalMap'), + xhrSettings: GetFastValue(config, 'textureXhrSettings') + }); + + data = new TextFile(loader, { + key: key, + url: GetFastValue(config, 'atlasURL'), + extension: GetFastValue(config, 'atlasExtension', 'txt'), + xhrSettings: GetFastValue(config, 'atlasXhrSettings') + }); + } + else + { + image = new ImageFile(loader, key, textureURL, textureXhrSettings); + data = new TextFile(loader, key, atlasURL, atlasXhrSettings); + } + + if (image.linkFile) + { + // Image has a normal map + MultiFile.call(this, loader, 'unityatlas', key, [ image, data, image.linkFile ]); + } + else + { + MultiFile.call(this, loader, 'unityatlas', key, [ image, data ]); + } + }, + + /** + * Adds this file to its target cache upon successful loading and processing. + * + * @method Phaser.Loader.FileTypes.UnityAtlasFile#addToCache + * @since 3.7.0 + */ + addToCache: function () + { + if (this.isReadyToProcess()) + { + var image = this.files[0]; + var text = this.files[1]; + var normalMap = (this.files[2]) ? this.files[2].data : null; + + this.loader.textureManager.addUnityAtlas(image.key, image.data, text.data, normalMap); + + this.complete = true; + } + } + +}); + +/** + * Adds a Unity YAML based Texture Atlas, or array of atlases, 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.unityAtlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.txt'); + * } + * ``` + * + * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, + * or if it's already running, when the next free load slot becomes available. This happens automatically if you + * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued + * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. + * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the + * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been + * loaded. + * + * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring + * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. + * + * Phaser expects the atlas data to be provided in a YAML formatted text file as exported from Unity. + * + * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. + * + * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.unityAtlas({ + * key: 'mainmenu', + * textureURL: 'images/MainMenu.png', + * atlasURL: 'images/MainMenu.txt' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.UnityAtlasFileConfig` for more details. + * + * Once the atlas has finished loading you can use frames from it as textures for a Game Object by referencing its key: + * + * ```javascript + * this.load.unityAtlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.json'); + * // and later in your game ... + * this.add.image(x, y, 'mainmenu', 'background'); + * ``` + * + * To get a list of all available frames within an atlas please consult your Texture Atlas software. + * + * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files + * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and + * this is what you would use to retrieve the image from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" + * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although + * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. + * + * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, + * then you can specify it by providing an array as the `url` where the second element is the normal map: + * + * ```javascript + * this.load.unityAtlas('mainmenu', [ 'images/MainMenu.png', 'images/MainMenu-n.png' ], 'images/MainMenu.txt'); + * ``` + * + * Or, if you are using a config object use the `normalMap` property: + * + * ```javascript + * this.load.unityAtlas({ + * key: 'mainmenu', + * textureURL: 'images/MainMenu.png', + * normalMap: 'images/MainMenu-n.png', + * atlasURL: 'images/MainMenu.txt' + * }); + * ``` + * + * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. + * Normal maps are a WebGL only feature. + * + * Note: The ability to load this type of file will only be available if the Unity Atlas 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#unityAtlas + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.UnityAtlasFileConfig|Phaser.Types.Loader.FileTypes.UnityAtlasFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". + * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas data file from. If undefined or `null` it will be set to `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". + * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings. + * + * @return {this} The Loader instance. + */ +FileTypesManager.register('unityAtlas', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) +{ + var multifile; + + // Supports an Object file definition in the key argument + // Or an array of objects in the key argument + // Or a single entry where all arguments have been defined + + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + multifile = new UnityAtlasFile(this, key[i]); + + this.addFile(multifile.files); + } + } + else + { + multifile = new UnityAtlasFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); + + this.addFile(multifile.files); + } + + return this; +}); + +module.exports = UnityAtlasFile; + + +/***/ }), + +/***/ 22833: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetURL = __webpack_require__(30750); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); + +/** + * @classdesc + * A single Video File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#video method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#video. + * + * @class VideoFile + * @extends Phaser.Loader.File + * @memberof Phaser.Loader.FileTypes + * @constructor + * @since 3.20.0 + * + * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. + * @param {(string|Phaser.Types.Loader.FileTypes.VideoFileConfig)} key - The key to use for this file, or a file configuration object. + * @param {(string|string[]|Phaser.Types.Loader.FileTypes.VideoFileURLConfig|Phaser.Types.Loader.FileTypes.VideoFileURLConfig[])} [urls] - The absolute or relative URL to load the video files from. + * @param {boolean} [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it. + */ +var VideoFile = new Class({ + + Extends: File, + + initialize: + + function VideoFile (loader, key, url, noAudio) + { + if (noAudio === undefined) { noAudio = false; } + + if (IsPlainObject(key)) + { + var config = key; + + key = GetFastValue(config, 'key'); + url = GetFastValue(config, 'url', []); + noAudio = GetFastValue(config, 'noAudio', false); + } + + var urlConfig = loader.systems.game.device.video.getVideoURL(url); + + if (!urlConfig) + { + console.warn('VideoFile: No supported format for ' + key); + } + + var fileConfig = { + type: 'video', + cache: loader.cacheManager.video, + extension: urlConfig.type, + key: key, + url: urlConfig.url, + config: { + noAudio: noAudio + } + }; + + 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.VideoFile#onProcess + * @since 3.20.0 + */ + onProcess: function () + { + this.data = { + url: this.src, + noAudio: this.config.noAudio, + crossOrigin: this.crossOrigin + }; + + this.onProcessComplete(); + }, + + /** + * 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.VideoFile#load + * @since 3.20.0 + */ + load: function () + { + // We set these, but we don't actually load anything (the Video Game Object does that) + + this.src = GetURL(this, this.loader.baseURL); + + this.state = CONST.FILE_LOADED; + + this.loader.nextFile(this, true); + } + +}); + +/** + * Adds a Video file, or array of video 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.video('intro', [ 'video/level1.mp4', 'video/level1.webm', 'video/level1.mov' ]); + * } + * ``` + * + * 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 Video Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Video 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 Video Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.video({ + * key: 'intro', + * url: [ 'video/level1.mp4', 'video/level1.webm', 'video/level1.mov' ], + * noAudio: true + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.VideoFileConfig` 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 video file types you should usually provide your video files in a variety of formats. + * mp4, mov and webm 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, starting with the first in the array and progressing to the end. + * + * Unlike most asset-types, videos do not _need_ to be preloaded. You can create a Video Game Object and then call its `loadURL` method, + * to load a video at run-time, rather than in advance. + * + * Note: The ability to load this type of file will only be available if the Video 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#video + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.20.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.VideoFileConfig|Phaser.Types.Loader.FileTypes.VideoFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. + * @param {(string|string[]|Phaser.Types.Loader.FileTypes.VideoFileURLConfig|Phaser.Types.Loader.FileTypes.VideoFileURLConfig[])} [urls] - The absolute or relative URL to load the video files from. + * @param {boolean} [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it. + * + * @return {this} The Loader instance. + */ +FileTypesManager.register('video', function (key, urls, noAudio) +{ + if (Array.isArray(key)) + { + for (var i = 0; i < key.length; i++) + { + this.addFile(new VideoFile(this, key[i])); + } + } + else + { + this.addFile(new VideoFile(this, key, urls, noAudio)); + } + + return this; +}); + +module.exports = VideoFile; + + +/***/ }), + +/***/ 15297: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12117); +var File = __webpack_require__(98035); +var FileTypesManager = __webpack_require__(76846); +var GetFastValue = __webpack_require__(72632); +var IsPlainObject = __webpack_require__(42911); +var ParseXML = __webpack_require__(89200); + +/** + * @classdesc + * A single XML File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#xml method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#xml. + * + * @class XMLFile + * @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.XMLFileConfig)} 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 `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". + * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + */ +var XMLFile = new Class({ + + Extends: File, + + initialize: + + function XMLFile (loader, key, url, xhrSettings) + { + var extension = 'xml'; + + 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: 'xml', + cache: loader.cacheManager.xml, + 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.XMLFile#onProcess + * @since 3.7.0 + */ + onProcess: function () + { + this.state = CONST.FILE_PROCESSING; + + this.data = ParseXML(this.xhrLoader.responseText); + + if (this.data) + { + this.onProcessComplete(); + } + else + { + this.onProcessError(); + } + } + +}); + +/** + * Adds an XML file, or array of XML 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.xml('wavedata', 'files/AlienWaveData.xml'); + * } + * ``` + * + * 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 XML Cache upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the XML 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 XML Cache first, before loading a new one. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.xml({ + * key: 'wavedata', + * url: 'files/AlienWaveData.xml' + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.XMLFileConfig` for more details. + * + * Once the file has finished loading you can access it from its Cache using its key: + * + * ```javascript + * this.load.xml('wavedata', 'files/AlienWaveData.xml'); + * // and later in your game ... + * var data = this.cache.xml.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 XML 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.xml". It will always add `.xml` 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 XML 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#xml + * @fires Phaser.Loader.LoaderPlugin#ADD + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Loader.FileTypes.XMLFileConfig|Phaser.Types.Loader.FileTypes.XMLFileConfig[])} 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 `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". + * @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('xml', 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 XMLFile(this, key[i])); + } + } + else + { + this.addFile(new XMLFile(this, key, url, xhrSettings)); + } + + return this; +}); + +module.exports = XMLFile; + + +/***/ }), + +/***/ 34034: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Loader.FileTypes + */ + +module.exports = { + + AnimationJSONFile: __webpack_require__(46468), + AsepriteFile: __webpack_require__(31648), + AtlasJSONFile: __webpack_require__(73152), + AtlasXMLFile: __webpack_require__(24616), + AudioFile: __webpack_require__(67448), + AudioSpriteFile: __webpack_require__(66109), + BinaryFile: __webpack_require__(40612), + BitmapFontFile: __webpack_require__(54565), + CompressedTextureFile: __webpack_require__(47375), + CSSFile: __webpack_require__(99898), + GLSLFile: __webpack_require__(46568), + HTML5AudioFile: __webpack_require__(30929), + HTMLFile: __webpack_require__(77459), + HTMLTextureFile: __webpack_require__(9755), + ImageFile: __webpack_require__(42927), + JSONFile: __webpack_require__(70806), + MultiAtlasFile: __webpack_require__(80802), + MultiScriptFile: __webpack_require__(39034), + OBJFile: __webpack_require__(85527), + PackFile: __webpack_require__(3616), + PluginFile: __webpack_require__(12217), + SceneFile: __webpack_require__(95171), + ScenePluginFile: __webpack_require__(82458), + ScriptFile: __webpack_require__(55188), + SpriteSheetFile: __webpack_require__(33536), + SVGFile: __webpack_require__(4474), + TextFile: __webpack_require__(86897), + TilemapCSVFile: __webpack_require__(58673), + TilemapImpactFile: __webpack_require__(98896), + TilemapJSONFile: __webpack_require__(50563), + UnityAtlasFile: __webpack_require__(82857), + VideoFile: __webpack_require__(22833), + XMLFile: __webpack_require__(15297) + +}; + + +/***/ }), + +/***/ 95695: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(12117); +var Extend = __webpack_require__(98611); + +/** + * @namespace Phaser.Loader + */ + +var Loader = { + + Events: __webpack_require__(683), + + FileTypes: __webpack_require__(34034), + + File: __webpack_require__(98035), + FileTypesManager: __webpack_require__(76846), + GetURL: __webpack_require__(30750), + LoaderPlugin: __webpack_require__(67285), + MergeXHRSettings: __webpack_require__(43531), + MultiFile: __webpack_require__(45176), + XHRLoader: __webpack_require__(88490), + XHRSettings: __webpack_require__(33868) + +}; + +// Merge in the consts +Loader = Extend(false, Loader, CONST); + +module.exports = Loader; + + +/***/ }), + +/***/ 26042: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the mean average of the given values. + * + * @function Phaser.Math.Average + * @since 3.0.0 + * + * @param {number[]} values - The values to average. + * + * @return {number} The average value. + */ +var Average = function (values) +{ + var sum = 0; + + for (var i = 0; i < values.length; i++) + { + sum += (+values[i]); + } + + return sum / values.length; +}; + +module.exports = Average; + + +/***/ }), + +/***/ 22824: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Factorial = __webpack_require__(8034); + +/** + * Calculates the Bernstein basis from the three factorial coefficients. + * + * @function Phaser.Math.Bernstein + * @since 3.0.0 + * + * @param {number} n - The first value. + * @param {number} i - The second value. + * + * @return {number} The Bernstein basis of Factorial(n) / Factorial(i) / Factorial(n - i) + */ +var Bernstein = function (n, i) +{ + return Factorial(n) / Factorial(i) / Factorial(n - i); +}; + +module.exports = Bernstein; + + +/***/ }), + +/***/ 17489: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Compute a random integer between the `min` and `max` values, inclusive. + * + * @function Phaser.Math.Between + * @since 3.0.0 + * + * @param {number} min - The minimum value. + * @param {number} max - The maximum value. + * + * @return {number} The random integer. + */ +var Between = function (min, max) +{ + return Math.floor(Math.random() * (max - min + 1) + min); +}; + +module.exports = Between; + + +/***/ }), + +/***/ 14976: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculates a Catmull-Rom value from the given points, based on an alpha of 0.5. + * + * @function Phaser.Math.CatmullRom + * @since 3.0.0 + * + * @param {number} t - The amount to interpolate by. + * @param {number} p0 - The first control point. + * @param {number} p1 - The second control point. + * @param {number} p2 - The third control point. + * @param {number} p3 - The fourth control point. + * + * @return {number} The Catmull-Rom value. + */ +var CatmullRom = function (t, p0, p1, p2, p3) +{ + var v0 = (p2 - p0) * 0.5; + var v1 = (p3 - p1) * 0.5; + var t2 = t * t; + var t3 = t * t2; + + return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; +}; + +module.exports = CatmullRom; + + +/***/ }), + +/***/ 89129: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Ceils to some place comparative to a `base`, default is 10 for decimal place. + * + * The `place` is represented by the power applied to `base` to get that place. + * + * @function Phaser.Math.CeilTo + * @since 3.0.0 + * + * @param {number} value - The value to round. + * @param {number} [place=0] - The place to round to. + * @param {number} [base=10] - The base to round in. Default is 10 for decimal. + * + * @return {number} The rounded value. + */ +var CeilTo = function (value, place, base) +{ + if (place === undefined) { place = 0; } + if (base === undefined) { base = 10; } + + var p = Math.pow(base, -place); + + return Math.ceil(value * p) / p; +}; + +module.exports = CeilTo; + + +/***/ }), + +/***/ 82897: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 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; + + +/***/ }), + +/***/ 75606: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(83392); + +/** + * Convert the given angle from degrees, to the equivalent angle in radians. + * + * @function Phaser.Math.DegToRad + * @since 3.0.0 + * + * @param {number} degrees - The angle (in degrees) to convert to radians. + * + * @return {number} The given angle converted to radians. + */ +var DegToRad = function (degrees) +{ + return degrees * CONST.DEG_TO_RAD; +}; + +module.exports = DegToRad; + + +/***/ }), + +/***/ 767: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculates the positive difference of two given numbers. + * + * @function Phaser.Math.Difference + * @since 3.0.0 + * + * @param {number} a - The first number in the calculation. + * @param {number} b - The second number in the calculation. + * + * @return {number} The positive difference of the two given numbers. + */ +var Difference = function (a, b) +{ + return Math.abs(a - b); +}; + +module.exports = Difference; + + +/***/ }), + +/***/ 9849: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Matrix4 = __webpack_require__(16650); +var NOOP = __webpack_require__(72283); + +var tempMatrix = new Matrix4(); + +/** + * @classdesc + * + * @class Euler + * @memberof Phaser.Math + * @constructor + * @since 3.50.0 + * + * @param {number} [x] - The x component. + * @param {number} [y] - The y component. + * @param {number} [z] - The z component. + */ +var Euler = new Class({ + + initialize: + + function Euler (x, y, z, order) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (z === undefined) { z = 0; } + if (order === undefined) { order = Euler.DefaultOrder; } + + this._x = x; + this._y = y; + this._z = z; + this._order = order; + + this.onChangeCallback = NOOP; + }, + + x: { + get: function () + { + return this._x; + }, + + set: function (value) + { + this._x = value; + + this.onChangeCallback(this); + } + }, + + y: { + get: function () + { + return this._y; + }, + + set: function (value) + { + this._y = value; + + this.onChangeCallback(this); + } + }, + + z: { + get: function () + { + return this._z; + }, + + set: function (value) + { + this._z = value; + + this.onChangeCallback(this); + } + }, + + order: { + get: function () + { + return this._order; + }, + + set: function (value) + { + this._order = value; + + this.onChangeCallback(this); + } + }, + + set: function (x, y, z, order) + { + if (order === undefined) { order = this._order; } + + this._x = x; + this._y = y; + this._z = z; + this._order = order; + + this.onChangeCallback(this); + + return this; + }, + + copy: function (euler) + { + return this.set(euler.x, euler.y, euler.z, euler.order); + }, + + setFromQuaternion: function (quaternion, order, update) + { + if (order === undefined) { order = this._order; } + if (update === undefined) { update = false; } + + tempMatrix.fromQuat(quaternion); + + return this.setFromRotationMatrix(tempMatrix, order, update); + }, + + setFromRotationMatrix: function (matrix, order, update) + { + if (order === undefined) { order = this._order; } + if (update === undefined) { update = false; } + + var elements = matrix.val; + + // Upper 3x3 of matrix is un-scaled rotation matrix + var m11 = elements[0]; + var m12 = elements[4]; + var m13 = elements[8]; + var m21 = elements[1]; + var m22 = elements[5]; + var m23 = elements[9]; + var m31 = elements[2]; + var m32 = elements[6]; + var m33 = elements[10]; + + var x = 0; + var y = 0; + var z = 0; + var epsilon = 0.99999; + + switch (order) + { + case 'XYZ': + { + y = Math.asin(Clamp(m13, -1, 1)); + + if (Math.abs(m13) < epsilon) + { + x = Math.atan2(-m23, m33); + z = Math.atan2(-m12, m11); + } + else + { + x = Math.atan2(m32, m22); + } + + break; + } + + case 'YXZ': + { + x = Math.asin(-Clamp(m23, -1, 1)); + + if (Math.abs(m23) < epsilon) + { + y = Math.atan2(m13, m33); + z = Math.atan2(m21, m22); + } + else + { + y = Math.atan2(-m31, m11); + } + + break; + } + + case 'ZXY': + { + x = Math.asin(Clamp(m32, -1, 1)); + + if (Math.abs(m32) < epsilon) + { + y = Math.atan2(-m31, m33); + z = Math.atan2(-m12, m22); + } + else + { + z = Math.atan2(m21, m11); + } + + break; + } + + case 'ZYX': + { + y = Math.asin(-Clamp(m31, -1, 1)); + + if (Math.abs(m31) < epsilon) + { + x = Math.atan2(m32, m33); + z = Math.atan2(m21, m11); + } + else + { + z = Math.atan2(-m12, m22); + } + + break; + } + + case 'YZX': + { + z = Math.asin(Clamp(m21, -1, 1)); + + if (Math.abs(m21) < epsilon) + { + x = Math.atan2(-m23, m22); + y = Math.atan2(-m31, m11); + } + else + { + y = Math.atan2(m13, m33); + } + + break; + } + + case 'XZY': + { + z = Math.asin(-Clamp(m12, -1, 1)); + + if (Math.abs(m12) < epsilon) + { + x = Math.atan2(m32, m22); + y = Math.atan2(m13, m11); + } + else + { + x = Math.atan2(-m23, m33); + } + + break; + } + } + + this._x = x; + this._y = y; + this._z = z; + this._order = order; + + if (update) + { + this.onChangeCallback(this); + } + + return this; + } + +}); + +Euler.RotationOrders = [ 'XYZ', 'YXZ', 'ZXY', 'ZYX', 'YZX', 'XZY' ]; + +Euler.DefaultOrder = 'XYZ'; + +module.exports = Euler; + + +/***/ }), + +/***/ 8034: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculates the factorial of a given number for integer values greater than 0. + * + * @function Phaser.Math.Factorial + * @since 3.0.0 + * + * @param {number} value - A positive integer to calculate the factorial of. + * + * @return {number} The factorial of the given number. + */ +var Factorial = function (value) +{ + if (value === 0) + { + return 1; + } + + var res = value; + + while (--value) + { + res *= value; + } + + return res; +}; + +module.exports = Factorial; + + +/***/ }), + +/***/ 61616: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Generate a random floating point number between the two given bounds, minimum inclusive, maximum exclusive. + * + * @function Phaser.Math.FloatBetween + * @since 3.0.0 + * + * @param {number} min - The lower bound for the float, inclusive. + * @param {number} max - The upper bound for the float exclusive. + * + * @return {number} A random float within the given range. + */ +var FloatBetween = function (min, max) +{ + return Math.random() * (max - min) + min; +}; + +module.exports = FloatBetween; + + +/***/ }), + +/***/ 60679: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Floors to some place comparative to a `base`, default is 10 for decimal place. + * + * The `place` is represented by the power applied to `base` to get that place. + * + * @function Phaser.Math.FloorTo + * @since 3.0.0 + * + * @param {number} value - The value to round. + * @param {number} [place=0] - The place to round to. + * @param {number} [base=10] - The base to round in. Default is 10 for decimal. + * + * @return {number} The rounded value. + */ +var FloorTo = function (value, place, base) +{ + if (place === undefined) { place = 0; } + if (base === undefined) { base = 10; } + + var p = Math.pow(base, -place); + + return Math.floor(value * p) / p; +}; + +module.exports = FloorTo; + + +/***/ }), + +/***/ 91806: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Clamp = __webpack_require__(82897); + +/** + * Return a value based on the range between `min` and `max` and the percentage given. + * + * @function Phaser.Math.FromPercent + * @since 3.0.0 + * + * @param {number} percent - A value between 0 and 1 representing the percentage. + * @param {number} min - The minimum value. + * @param {number} [max] - The maximum value. + * + * @return {number} The value that is `percent` percent between `min` and `max`. + */ +var FromPercent = function (percent, min, max) +{ + percent = Clamp(percent, 0, 1); + + return (max - min) * percent + min; +}; + +module.exports = FromPercent; + + +/***/ }), + +/***/ 79366: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate a per-ms speed from a distance and time (given in seconds). + * + * @function Phaser.Math.GetSpeed + * @since 3.0.0 + * + * @param {number} distance - The distance. + * @param {number} time - The time, in seconds. + * + * @return {number} The speed, in distance per ms. + * + * @example + * // 400px over 1 second is 0.4 px/ms + * Phaser.Math.GetSpeed(400, 1) // -> 0.4 + */ +var GetSpeed = function (distance, time) +{ + return (distance / time) / 1000; +}; + +module.exports = GetSpeed; + + +/***/ }), + +/***/ 43776: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Check if a given value is an even number. + * + * @function Phaser.Math.IsEven + * @since 3.0.0 + * + * @param {number} value - The number to perform the check with. + * + * @return {boolean} Whether the number is even or not. + */ +var IsEven = function (value) +{ + // Use abstract equality == for "is number" test + + // eslint-disable-next-line eqeqeq + return (value == parseFloat(value)) ? !(value % 2) : void 0; +}; + +module.exports = IsEven; + + +/***/ }), + +/***/ 58442: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Check if a given value is an even number using a strict type check. + * + * @function Phaser.Math.IsEvenStrict + * @since 3.0.0 + * + * @param {number} value - The number to perform the check with. + * + * @return {boolean} Whether the number is even or not. + */ +var IsEvenStrict = function (value) +{ + // Use strict equality === for "is number" test + return (value === parseFloat(value)) ? !(value % 2) : void 0; +}; + +module.exports = IsEvenStrict; + + +/***/ }), + +/***/ 42798: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculates a linear (interpolation) value over t. + * + * @function Phaser.Math.Linear + * @since 3.0.0 + * + * @param {number} p0 - The first point. + * @param {number} p1 - The second point. + * @param {number} t - The percentage between p0 and p1 to return, represented as a number between 0 and 1. + * + * @return {number} The step t% of the way between p0 and p1. + */ +var Linear = function (p0, p1, t) +{ + return (p1 - p0) * t + p0; +}; + +module.exports = Linear; + + +/***/ }), + +/***/ 61072: +/***/ ((module) => { + +/** + * @author Greg McLean + * @copyright 2021 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Interpolates two given Vectors and returns a new Vector between them. + * + * Does not modify either of the passed Vectors. + * + * @function Phaser.Math.LinearXY + * @since 3.60.0 + * + * @param {Phaser.Math.Vector2} vector1 - Starting vector + * @param {Phaser.Math.Vector2} vector2 - Ending vector + * @param {number} [t=0] - The percentage between vector1 and vector2 to return, represented as a number between 0 and 1. + * + * @return {Phaser.Math.Vector2} The step t% of the way between vector1 and vector2. + */ +var LinearXY = function (vector1, vector2, t) +{ + if (t === undefined) { t = 0; } + + return vector1.clone().lerp(vector2, t); +}; + +module.exports = LinearXY; + + +/***/ }), + +/***/ 5341: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji +// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl + +var Class = __webpack_require__(56694); + +/** + * @classdesc + * A three-dimensional matrix. + * + * Defaults to the identity matrix when instantiated. + * + * @class Matrix3 + * @memberof Phaser.Math + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix3} [m] - Optional Matrix3 to copy values from. + */ +var Matrix3 = new Class({ + + initialize: + + function Matrix3 (m) + { + /** + * The matrix values. + * + * @name Phaser.Math.Matrix3#val + * @type {Float32Array} + * @since 3.0.0 + */ + this.val = new Float32Array(9); + + if (m) + { + // Assume Matrix3 with val: + this.copy(m); + } + else + { + // Default to identity + this.identity(); + } + }, + + /** + * Make a clone of this Matrix3. + * + * @method Phaser.Math.Matrix3#clone + * @since 3.0.0 + * + * @return {Phaser.Math.Matrix3} A clone of this Matrix3. + */ + clone: function () + { + return new Matrix3(this); + }, + + /** + * This method is an alias for `Matrix3.copy`. + * + * @method Phaser.Math.Matrix3#set + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix3} src - The Matrix to set the values of this Matrix's from. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + set: function (src) + { + return this.copy(src); + }, + + /** + * Copy the values of a given Matrix into this Matrix. + * + * @method Phaser.Math.Matrix3#copy + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix3} src - The Matrix to copy the values from. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + copy: function (src) + { + var out = this.val; + var a = src.val; + + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + + return this; + }, + + /** + * Copy the values of a given Matrix4 into this Matrix3. + * + * @method Phaser.Math.Matrix3#fromMat4 + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix4} m - The Matrix4 to copy the values from. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + fromMat4: function (m) + { + var a = m.val; + var out = this.val; + + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[4]; + out[4] = a[5]; + out[5] = a[6]; + out[6] = a[8]; + out[7] = a[9]; + out[8] = a[10]; + + return this; + }, + + /** + * Set the values of this Matrix from the given array. + * + * @method Phaser.Math.Matrix3#fromArray + * @since 3.0.0 + * + * @param {array} a - The array to copy the values from. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + fromArray: function (a) + { + var out = this.val; + + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + + return this; + }, + + /** + * Reset this Matrix to an identity (default) matrix. + * + * @method Phaser.Math.Matrix3#identity + * @since 3.0.0 + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + identity: function () + { + var out = this.val; + + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 1; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + + return this; + }, + + /** + * Transpose this Matrix. + * + * @method Phaser.Math.Matrix3#transpose + * @since 3.0.0 + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + transpose: function () + { + var a = this.val; + var a01 = a[1]; + var a02 = a[2]; + var a12 = a[5]; + + a[1] = a[3]; + a[2] = a[6]; + a[3] = a01; + a[5] = a[7]; + a[6] = a02; + a[7] = a12; + + return this; + }, + + /** + * Invert this Matrix. + * + * @method Phaser.Math.Matrix3#invert + * @since 3.0.0 + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + invert: function () + { + var a = this.val; + + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a10 = a[3]; + var a11 = a[4]; + var a12 = a[5]; + var a20 = a[6]; + var a21 = a[7]; + var a22 = a[8]; + + var b01 = a22 * a11 - a12 * a21; + var b11 = -a22 * a10 + a12 * a20; + var b21 = a21 * a10 - a11 * a20; + + // Calculate the determinant + var det = a00 * b01 + a01 * b11 + a02 * b21; + + if (!det) + { + return null; + } + + det = 1 / det; + + a[0] = b01 * det; + a[1] = (-a22 * a01 + a02 * a21) * det; + a[2] = (a12 * a01 - a02 * a11) * det; + a[3] = b11 * det; + a[4] = (a22 * a00 - a02 * a20) * det; + a[5] = (-a12 * a00 + a02 * a10) * det; + a[6] = b21 * det; + a[7] = (-a21 * a00 + a01 * a20) * det; + a[8] = (a11 * a00 - a01 * a10) * det; + + return this; + }, + + /** + * Calculate the adjoint, or adjugate, of this Matrix. + * + * @method Phaser.Math.Matrix3#adjoint + * @since 3.0.0 + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + adjoint: function () + { + var a = this.val; + + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a10 = a[3]; + var a11 = a[4]; + var a12 = a[5]; + var a20 = a[6]; + var a21 = a[7]; + var a22 = a[8]; + + a[0] = (a11 * a22 - a12 * a21); + a[1] = (a02 * a21 - a01 * a22); + a[2] = (a01 * a12 - a02 * a11); + a[3] = (a12 * a20 - a10 * a22); + a[4] = (a00 * a22 - a02 * a20); + a[5] = (a02 * a10 - a00 * a12); + a[6] = (a10 * a21 - a11 * a20); + a[7] = (a01 * a20 - a00 * a21); + a[8] = (a00 * a11 - a01 * a10); + + return this; + }, + + /** + * Calculate the determinant of this Matrix. + * + * @method Phaser.Math.Matrix3#determinant + * @since 3.0.0 + * + * @return {number} The determinant of this Matrix. + */ + determinant: function () + { + var a = this.val; + + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a10 = a[3]; + var a11 = a[4]; + var a12 = a[5]; + var a20 = a[6]; + var a21 = a[7]; + var a22 = a[8]; + + return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); + }, + + /** + * Multiply this Matrix by the given Matrix. + * + * @method Phaser.Math.Matrix3#multiply + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix3} src - The Matrix to multiply this Matrix by. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + multiply: function (src) + { + var a = this.val; + + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a10 = a[3]; + var a11 = a[4]; + var a12 = a[5]; + var a20 = a[6]; + var a21 = a[7]; + var a22 = a[8]; + + var b = src.val; + + var b00 = b[0]; + var b01 = b[1]; + var b02 = b[2]; + var b10 = b[3]; + var b11 = b[4]; + var b12 = b[5]; + var b20 = b[6]; + var b21 = b[7]; + var b22 = b[8]; + + a[0] = b00 * a00 + b01 * a10 + b02 * a20; + a[1] = b00 * a01 + b01 * a11 + b02 * a21; + a[2] = b00 * a02 + b01 * a12 + b02 * a22; + + a[3] = b10 * a00 + b11 * a10 + b12 * a20; + a[4] = b10 * a01 + b11 * a11 + b12 * a21; + a[5] = b10 * a02 + b11 * a12 + b12 * a22; + + a[6] = b20 * a00 + b21 * a10 + b22 * a20; + a[7] = b20 * a01 + b21 * a11 + b22 * a21; + a[8] = b20 * a02 + b21 * a12 + b22 * a22; + + return this; + }, + + /** + * Translate this Matrix using the given Vector. + * + * @method Phaser.Math.Matrix3#translate + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to translate this Matrix with. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + translate: function (v) + { + var a = this.val; + var x = v.x; + var y = v.y; + + a[6] = x * a[0] + y * a[3] + a[6]; + a[7] = x * a[1] + y * a[4] + a[7]; + a[8] = x * a[2] + y * a[5] + a[8]; + + return this; + }, + + /** + * Apply a rotation transformation to this Matrix. + * + * @method Phaser.Math.Matrix3#rotate + * @since 3.0.0 + * + * @param {number} rad - The angle in radians to rotate by. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + rotate: function (rad) + { + var a = this.val; + + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a10 = a[3]; + var a11 = a[4]; + var a12 = a[5]; + + var s = Math.sin(rad); + var c = Math.cos(rad); + + a[0] = c * a00 + s * a10; + a[1] = c * a01 + s * a11; + a[2] = c * a02 + s * a12; + + a[3] = c * a10 - s * a00; + a[4] = c * a11 - s * a01; + a[5] = c * a12 - s * a02; + + return this; + }, + + /** + * Apply a scale transformation to this Matrix. + * + * Uses the `x` and `y` components of the given Vector to scale the Matrix. + * + * @method Phaser.Math.Matrix3#scale + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to scale this Matrix with. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + scale: function (v) + { + var a = this.val; + var x = v.x; + var y = v.y; + + a[0] = x * a[0]; + a[1] = x * a[1]; + a[2] = x * a[2]; + + a[3] = y * a[3]; + a[4] = y * a[4]; + a[5] = y * a[5]; + + return this; + }, + + /** + * Set the values of this Matrix from the given Quaternion. + * + * @method Phaser.Math.Matrix3#fromQuat + * @since 3.0.0 + * + * @param {Phaser.Math.Quaternion} q - The Quaternion to set the values of this Matrix from. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + fromQuat: function (q) + { + var x = q.x; + var y = q.y; + var z = q.z; + var w = q.w; + + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + + var out = this.val; + + out[0] = 1 - (yy + zz); + out[3] = xy + wz; + out[6] = xz - wy; + + out[1] = xy - wz; + out[4] = 1 - (xx + zz); + out[7] = yz + wx; + + out[2] = xz + wy; + out[5] = yz - wx; + out[8] = 1 - (xx + yy); + + return this; + }, + + /** + * Set the values of this Matrix3 to be normalized from the given Matrix4. + * + * @method Phaser.Math.Matrix3#normalFromMat4 + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix4} m - The Matrix4 to normalize the values from. + * + * @return {Phaser.Math.Matrix3} This Matrix3. + */ + normalFromMat4: function (m) + { + var a = m.val; + var out = this.val; + + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + + var a30 = a[12]; + var a31 = a[13]; + var a32 = a[14]; + var a33 = a[15]; + + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; + + // Calculate the determinant + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) + { + return null; + } + + det = 1 / det; + + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + + out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + + out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + + return this; + } + +}); + +module.exports = Matrix3; + + +/***/ }), + +/***/ 16650: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Vector3 = __webpack_require__(70015); + +/** + * @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; + + +/***/ }), + +/***/ 69635: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Add an `amount` to a `value`, limiting the maximum result to `max`. + * + * @function Phaser.Math.MaxAdd + * @since 3.0.0 + * + * @param {number} value - The value to add to. + * @param {number} amount - The amount to add. + * @param {number} max - The maximum value to return. + * + * @return {number} The resulting value. + */ +var MaxAdd = function (value, amount, max) +{ + return Math.min(value + amount, max); +}; + +module.exports = MaxAdd; + + +/***/ }), + +/***/ 37394: +/***/ ((module) => { + +/** + * @author Vladislav Forsh + * @copyright 2021 RoboWhale + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the median of the given values. The values are sorted and the middle value is returned. + * In case of an even number of values, the average of the two middle values is returned. + * + * @function Phaser.Math.Median + * @since 3.54.0 + * + * @param {number[]} values - The values to average. + * + * @return {number} The median value. + */ +var Median = function (values) +{ + var valuesNum = values.length; + if (valuesNum === 0) + { + return 0; + } + + values.sort(function (a, b) { return a - b; }); + + var halfIndex = Math.floor(valuesNum / 2); + + return valuesNum % 2 === 0 + ? (values[halfIndex] + values[halfIndex - 1]) / 2 + : values[halfIndex]; +}; + +module.exports = Median; + + +/***/ }), + +/***/ 17259: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Subtract an `amount` from `value`, limiting the minimum result to `min`. + * + * @function Phaser.Math.MinSub + * @since 3.0.0 + * + * @param {number} value - The value to subtract from. + * @param {number} amount - The amount to subtract. + * @param {number} min - The minimum value to return. + * + * @return {number} The resulting value. + */ +var MinSub = function (value, amount, min) +{ + return Math.max(value - amount, min); +}; + +module.exports = MinSub; + + +/***/ }), + +/***/ 61820: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Work out what percentage `value` is of the range between `min` and `max`. + * If `max` isn't given then it will return the percentage of `value` to `min`. + * + * You can optionally specify an `upperMax` value, which is a mid-way point in the range that represents 100%, after which the % starts to go down to zero again. + * + * @function Phaser.Math.Percent + * @since 3.0.0 + * + * @param {number} value - The value to determine the percentage of. + * @param {number} min - The minimum value. + * @param {number} [max] - The maximum value. + * @param {number} [upperMax] - The mid-way point in the range that represents 100%. + * + * @return {number} A value between 0 and 1 representing the percentage. + */ +var Percent = function (value, min, max, upperMax) +{ + if (max === undefined) { max = min + 1; } + + var percentage = (value - min) / (max - min); + + if (percentage > 1) + { + if (upperMax !== undefined) + { + percentage = ((upperMax - value)) / (upperMax - max); + + if (percentage < 0) + { + percentage = 0; + } + } + else + { + percentage = 1; + } + } + else if (percentage < 0) + { + percentage = 0; + } + + return percentage; +}; + +module.exports = Percent; + + +/***/ }), + +/***/ 75003: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji +// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl + +var Class = __webpack_require__(56694); +var Matrix3 = __webpack_require__(5341); +var NOOP = __webpack_require__(72283); +var Vector3 = __webpack_require__(70015); + +var EPSILON = 0.000001; + +// Some shared 'private' arrays +var siNext = new Int8Array([ 1, 2, 0 ]); +var tmp = new Float32Array([ 0, 0, 0 ]); + +var xUnitVec3 = new Vector3(1, 0, 0); +var yUnitVec3 = new Vector3(0, 1, 0); + +var tmpvec = new Vector3(); +var tmpMat3 = new Matrix3(); + +/** + * @classdesc + * A quaternion. + * + * @class Quaternion + * @memberof Phaser.Math + * @constructor + * @since 3.0.0 + * + * @param {number} [x=0] - The x component. + * @param {number} [y=0] - The y component. + * @param {number} [z=0] - The z component. + * @param {number} [w=1] - The w component. + */ +var Quaternion = new Class({ + + initialize: + + function Quaternion (x, y, z, w) + { + /** + * The x component of this Quaternion. + * + * @name Phaser.Math.Quaternion#_x + * @type {number} + * @default 0 + * @private + * @since 3.50.0 + */ + + /** + * The y component of this Quaternion. + * + * @name Phaser.Math.Quaternion#_y + * @type {number} + * @default 0 + * @private + * @since 3.50.0 + */ + + /** + * The z component of this Quaternion. + * + * @name Phaser.Math.Quaternion#_z + * @type {number} + * @default 0 + * @private + * @since 3.50.0 + */ + + /** + * The w component of this Quaternion. + * + * @name Phaser.Math.Quaternion#_w + * @type {number} + * @default 0 + * @private + * @since 3.50.0 + */ + + /** + * This callback is invoked, if set, each time a value in this quaternion is changed. + * The callback is passed one argument, a reference to this quaternion. + * + * @name Phaser.Math.Quaternion#onChangeCallback + * @type {function} + * @since 3.50.0 + */ + this.onChangeCallback = NOOP; + + this.set(x, y, z, w); + }, + + /** + * The x component of this Quaternion. + * + * @name Phaser.Math.Quaternion#x + * @type {number} + * @default 0 + * @since 3.0.0 + */ + x: { + get: function () + { + return this._x; + }, + + set: function (value) + { + this._x = value; + + this.onChangeCallback(this); + } + }, + + /** + * The y component of this Quaternion. + * + * @name Phaser.Math.Quaternion#y + * @type {number} + * @default 0 + * @since 3.0.0 + */ + y: { + get: function () + { + return this._y; + }, + + set: function (value) + { + this._y = value; + + this.onChangeCallback(this); + } + }, + + /** + * The z component of this Quaternion. + * + * @name Phaser.Math.Quaternion#z + * @type {number} + * @default 0 + * @since 3.0.0 + */ + z: { + get: function () + { + return this._z; + }, + + set: function (value) + { + this._z = value; + + this.onChangeCallback(this); + } + }, + + /** + * The w component of this Quaternion. + * + * @name Phaser.Math.Quaternion#w + * @type {number} + * @default 0 + * @since 3.0.0 + */ + w: { + get: function () + { + return this._w; + }, + + set: function (value) + { + this._w = value; + + this.onChangeCallback(this); + } + }, + + /** + * Copy the components of a given Quaternion or Vector into this Quaternion. + * + * @method Phaser.Math.Quaternion#copy + * @since 3.0.0 + * + * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} src - The Quaternion or Vector to copy the components from. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + copy: function (src) + { + return this.set(src); + }, + + /** + * Set the components of this Quaternion and optionally call the `onChangeCallback`. + * + * @method Phaser.Math.Quaternion#set + * @since 3.0.0 + * + * @param {(number|object)} [x=0] - The x component, or an object containing x, y, z, and w components. + * @param {number} [y=0] - The y component. + * @param {number} [z=0] - The z component. + * @param {number} [w=0] - The w component. + * @param {boolean} [update=true] - Call the `onChangeCallback`? + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + set: function (x, y, z, w, update) + { + if (update === undefined) { update = true; } + + if (typeof x === 'object') + { + this._x = x.x || 0; + this._y = x.y || 0; + this._z = x.z || 0; + this._w = x.w || 0; + } + else + { + this._x = x || 0; + this._y = y || 0; + this._z = z || 0; + this._w = w || 0; + } + + if (update) + { + this.onChangeCallback(this); + } + + return this; + }, + + /** + * Add a given Quaternion or Vector to this Quaternion. Addition is component-wise. + * + * @method Phaser.Math.Quaternion#add + * @since 3.0.0 + * + * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to add to this Quaternion. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + add: function (v) + { + this._x += v.x; + this._y += v.y; + this._z += v.z; + this._w += v.w; + + this.onChangeCallback(this); + + return this; + }, + + /** + * Subtract a given Quaternion or Vector from this Quaternion. Subtraction is component-wise. + * + * @method Phaser.Math.Quaternion#subtract + * @since 3.0.0 + * + * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to subtract from this Quaternion. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + subtract: function (v) + { + this._x -= v.x; + this._y -= v.y; + this._z -= v.z; + this._w -= v.w; + + this.onChangeCallback(this); + + return this; + }, + + /** + * Scale this Quaternion by the given value. + * + * @method Phaser.Math.Quaternion#scale + * @since 3.0.0 + * + * @param {number} scale - The value to scale this Quaternion by. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + scale: function (scale) + { + this._x *= scale; + this._y *= scale; + this._z *= scale; + this._w *= scale; + + this.onChangeCallback(this); + + return this; + }, + + /** + * Calculate the length of this Quaternion. + * + * @method Phaser.Math.Quaternion#length + * @since 3.0.0 + * + * @return {number} The length of this Quaternion. + */ + length: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; + + return Math.sqrt(x * x + y * y + z * z + w * w); + }, + + /** + * Calculate the length of this Quaternion squared. + * + * @method Phaser.Math.Quaternion#lengthSq + * @since 3.0.0 + * + * @return {number} The length of this Quaternion, squared. + */ + lengthSq: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; + + return x * x + y * y + z * z + w * w; + }, + + /** + * Normalize this Quaternion. + * + * @method Phaser.Math.Quaternion#normalize + * @since 3.0.0 + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + normalize: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; + var len = x * x + y * y + z * z + w * w; + + if (len > 0) + { + len = 1 / Math.sqrt(len); + + this._x = x * len; + this._y = y * len; + this._z = z * len; + this._w = w * len; + } + + this.onChangeCallback(this); + + return this; + }, + + /** + * Calculate the dot product of this Quaternion and the given Quaternion or Vector. + * + * @method Phaser.Math.Quaternion#dot + * @since 3.0.0 + * + * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to dot product with this Quaternion. + * + * @return {number} The dot product of this Quaternion and the given Quaternion or Vector. + */ + dot: function (v) + { + return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; + }, + + /** + * Linearly interpolate this Quaternion towards the given Quaternion or Vector. + * + * @method Phaser.Math.Quaternion#lerp + * @since 3.0.0 + * + * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to interpolate towards. + * @param {number} [t=0] - The percentage of interpolation. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + lerp: function (v, t) + { + if (t === undefined) { t = 0; } + + var ax = this.x; + var ay = this.y; + var az = this.z; + var aw = this.w; + + return this.set( + ax + t * (v.x - ax), + ay + t * (v.y - ay), + az + t * (v.z - az), + aw + t * (v.w - aw) + ); + }, + + /** + * Rotates this Quaternion based on the two given vectors. + * + * @method Phaser.Math.Quaternion#rotationTo + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} a - The transform rotation vector. + * @param {Phaser.Math.Vector3} b - The target rotation vector. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + rotationTo: function (a, b) + { + var dot = a.x * b.x + a.y * b.y + a.z * b.z; + + if (dot < -0.999999) + { + if (tmpvec.copy(xUnitVec3).cross(a).length() < EPSILON) + { + tmpvec.copy(yUnitVec3).cross(a); + } + + tmpvec.normalize(); + + return this.setAxisAngle(tmpvec, Math.PI); + + } + else if (dot > 0.999999) + { + return this.set(0, 0, 0, 1); + } + else + { + tmpvec.copy(a).cross(b); + + this._x = tmpvec.x; + this._y = tmpvec.y; + this._z = tmpvec.z; + this._w = 1 + dot; + + return this.normalize(); + } + }, + + /** + * Set the axes of this Quaternion. + * + * @method Phaser.Math.Quaternion#setAxes + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} view - The view axis. + * @param {Phaser.Math.Vector3} right - The right axis. + * @param {Phaser.Math.Vector3} up - The upwards axis. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + setAxes: function (view, right, up) + { + var m = tmpMat3.val; + + m[0] = right.x; + m[3] = right.y; + m[6] = right.z; + + m[1] = up.x; + m[4] = up.y; + m[7] = up.z; + + m[2] = -view.x; + m[5] = -view.y; + m[8] = -view.z; + + return this.fromMat3(tmpMat3).normalize(); + }, + + /** + * Reset this Matrix to an identity (default) Quaternion. + * + * @method Phaser.Math.Quaternion#identity + * @since 3.0.0 + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + identity: function () + { + return this.set(0, 0, 0, 1); + }, + + /** + * Set the axis angle of this Quaternion. + * + * @method Phaser.Math.Quaternion#setAxisAngle + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} axis - The axis. + * @param {number} rad - The angle in radians. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + setAxisAngle: function (axis, rad) + { + rad = rad * 0.5; + + var s = Math.sin(rad); + + return this.set( + s * axis.x, + s * axis.y, + s * axis.z, + Math.cos(rad) + ); + }, + + /** + * Multiply this Quaternion by the given Quaternion or Vector. + * + * @method Phaser.Math.Quaternion#multiply + * @since 3.0.0 + * + * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to multiply this Quaternion by. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + multiply: function (b) + { + var ax = this.x; + var ay = this.y; + var az = this.z; + var aw = this.w; + + var bx = b.x; + var by = b.y; + var bz = b.z; + var bw = b.w; + + return this.set( + ax * bw + aw * bx + ay * bz - az * by, + ay * bw + aw * by + az * bx - ax * bz, + az * bw + aw * bz + ax * by - ay * bx, + aw * bw - ax * bx - ay * by - az * bz + ); + }, + + /** + * Smoothly linearly interpolate this Quaternion towards the given Quaternion or Vector. + * + * @method Phaser.Math.Quaternion#slerp + * @since 3.0.0 + * + * @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to interpolate towards. + * @param {number} t - The percentage of interpolation. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + slerp: function (b, t) + { + // benchmarks: http://jsperf.com/quaternion-slerp-implementations + + var ax = this.x; + var ay = this.y; + var az = this.z; + var aw = this.w; + + var bx = b.x; + var by = b.y; + var bz = b.z; + var bw = b.w; + + // calc cosine + var cosom = ax * bx + ay * by + az * bz + aw * bw; + + // adjust signs (if necessary) + if (cosom < 0) + { + cosom = -cosom; + bx = - bx; + by = - by; + bz = - bz; + bw = - bw; + } + + // "from" and "to" quaternions are very close + // ... so we can do a linear interpolation + var scale0 = 1 - t; + var scale1 = t; + + // calculate coefficients + if ((1 - cosom) > EPSILON) + { + // standard case (slerp) + var omega = Math.acos(cosom); + var sinom = Math.sin(omega); + + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } + + // calculate final values + return this.set( + scale0 * ax + scale1 * bx, + scale0 * ay + scale1 * by, + scale0 * az + scale1 * bz, + scale0 * aw + scale1 * bw + ); + }, + + /** + * Invert this Quaternion. + * + * @method Phaser.Math.Quaternion#invert + * @since 3.0.0 + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + invert: function () + { + var a0 = this.x; + var a1 = this.y; + var a2 = this.z; + var a3 = this.w; + + var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3; + var invDot = (dot) ? 1 / dot : 0; + + return this.set( + -a0 * invDot, + -a1 * invDot, + -a2 * invDot, + a3 * invDot + ); + }, + + /** + * Convert this Quaternion into its conjugate. + * + * Sets the x, y and z components. + * + * @method Phaser.Math.Quaternion#conjugate + * @since 3.0.0 + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + conjugate: function () + { + this._x = -this.x; + this._y = -this.y; + this._z = -this.z; + + this.onChangeCallback(this); + + return this; + }, + + /** + * Rotate this Quaternion on the X axis. + * + * @method Phaser.Math.Quaternion#rotateX + * @since 3.0.0 + * + * @param {number} rad - The rotation angle in radians. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + rotateX: function (rad) + { + rad *= 0.5; + + var ax = this.x; + var ay = this.y; + var az = this.z; + var aw = this.w; + + var bx = Math.sin(rad); + var bw = Math.cos(rad); + + return this.set( + ax * bw + aw * bx, + ay * bw + az * bx, + az * bw - ay * bx, + aw * bw - ax * bx + ); + }, + + /** + * Rotate this Quaternion on the Y axis. + * + * @method Phaser.Math.Quaternion#rotateY + * @since 3.0.0 + * + * @param {number} rad - The rotation angle in radians. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + rotateY: function (rad) + { + rad *= 0.5; + + var ax = this.x; + var ay = this.y; + var az = this.z; + var aw = this.w; + + var by = Math.sin(rad); + var bw = Math.cos(rad); + + return this.set( + ax * bw - az * by, + ay * bw + aw * by, + az * bw + ax * by, + aw * bw - ay * by + ); + }, + + /** + * Rotate this Quaternion on the Z axis. + * + * @method Phaser.Math.Quaternion#rotateZ + * @since 3.0.0 + * + * @param {number} rad - The rotation angle in radians. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + rotateZ: function (rad) + { + rad *= 0.5; + + var ax = this.x; + var ay = this.y; + var az = this.z; + var aw = this.w; + + var bz = Math.sin(rad); + var bw = Math.cos(rad); + + return this.set( + ax * bw + ay * bz, + ay * bw - ax * bz, + az * bw + aw * bz, + aw * bw - az * bz + ); + }, + + /** + * Create a unit (or rotation) Quaternion from its x, y, and z components. + * + * Sets the w component. + * + * @method Phaser.Math.Quaternion#calculateW + * @since 3.0.0 + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + calculateW: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + + this.w = -Math.sqrt(1.0 - x * x - y * y - z * z); + + return this; + }, + + /** + * Set this Quaternion from the given Euler, based on Euler order. + * + * @method Phaser.Math.Quaternion#setFromEuler + * @since 3.50.0 + * + * @param {Phaser.Math.Euler} euler - The Euler to convert from. + * @param {boolean} [update=true] - Run the `onChangeCallback`? + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + setFromEuler: function (euler, update) + { + var x = euler.x / 2; + var y = euler.y / 2; + var z = euler.z / 2; + + var c1 = Math.cos(x); + var c2 = Math.cos(y); + var c3 = Math.cos(z); + + var s1 = Math.sin(x); + var s2 = Math.sin(y); + var s3 = Math.sin(z); + + switch (euler.order) + { + case 'XYZ': + { + this.set( + s1 * c2 * c3 + c1 * s2 * s3, + c1 * s2 * c3 - s1 * c2 * s3, + c1 * c2 * s3 + s1 * s2 * c3, + c1 * c2 * c3 - s1 * s2 * s3, + update + ); + + break; + } + + case 'YXZ': + { + this.set( + s1 * c2 * c3 + c1 * s2 * s3, + c1 * s2 * c3 - s1 * c2 * s3, + c1 * c2 * s3 - s1 * s2 * c3, + c1 * c2 * c3 + s1 * s2 * s3, + update + ); + + break; + } + + case 'ZXY': + { + this.set( + s1 * c2 * c3 - c1 * s2 * s3, + c1 * s2 * c3 + s1 * c2 * s3, + c1 * c2 * s3 + s1 * s2 * c3, + c1 * c2 * c3 - s1 * s2 * s3, + update + ); + + break; + } + + case 'ZYX': + { + this.set( + s1 * c2 * c3 - c1 * s2 * s3, + c1 * s2 * c3 + s1 * c2 * s3, + c1 * c2 * s3 - s1 * s2 * c3, + c1 * c2 * c3 + s1 * s2 * s3, + update + ); + + break; + } + + case 'YZX': + { + this.set( + s1 * c2 * c3 + c1 * s2 * s3, + c1 * s2 * c3 + s1 * c2 * s3, + c1 * c2 * s3 - s1 * s2 * c3, + c1 * c2 * c3 - s1 * s2 * s3, + update + ); + + break; + } + + case 'XZY': + { + this.set( + s1 * c2 * c3 - c1 * s2 * s3, + c1 * s2 * c3 - s1 * c2 * s3, + c1 * c2 * s3 + s1 * s2 * c3, + c1 * c2 * c3 + s1 * s2 * s3, + update + ); + + break; + } + } + + return this; + }, + + /** + * Sets the rotation of this Quaternion from the given Matrix4. + * + * @method Phaser.Math.Quaternion#setFromRotationMatrix + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to set the rotation from. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + setFromRotationMatrix: function (mat4) + { + var m = mat4.val; + + var m11 = m[0]; + var m12 = m[4]; + var m13 = m[8]; + var m21 = m[1]; + var m22 = m[5]; + var m23 = m[9]; + var m31 = m[2]; + var m32 = m[6]; + var m33 = m[10]; + + var trace = m11 + m22 + m33; + var s; + + if (trace > 0) + { + s = 0.5 / Math.sqrt(trace + 1.0); + + this.set( + (m32 - m23) * s, + (m13 - m31) * s, + (m21 - m12) * s, + 0.25 / s + ); + } + else if (m11 > m22 && m11 > m33) + { + s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33); + + this.set( + 0.25 * s, + (m12 + m21) / s, + (m13 + m31) / s, + (m32 - m23) / s + ); + } + else if (m22 > m33) + { + s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33); + + this.set( + (m12 + m21) / s, + 0.25 * s, + (m23 + m32) / s, + (m13 - m31) / s + ); + } + else + { + s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22); + + this.set( + (m13 + m31) / s, + (m23 + m32) / s, + 0.25 * s, + (m21 - m12) / s + ); + } + + return this; + }, + + /** + * Convert the given Matrix into this Quaternion. + * + * @method Phaser.Math.Quaternion#fromMat3 + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix3} mat - The Matrix to convert from. + * + * @return {Phaser.Math.Quaternion} This Quaternion. + */ + fromMat3: function (mat) + { + // benchmarks: + // http://jsperf.com/typed-array-access-speed + // http://jsperf.com/conversion-of-3x3-matrix-to-quaternion + + // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes + // article "Quaternion Calculus and Fast Animation". + var m = mat.val; + var fTrace = m[0] + m[4] + m[8]; + var fRoot; + + if (fTrace > 0) + { + // |w| > 1/2, may as well choose w > 1/2 + fRoot = Math.sqrt(fTrace + 1.0); // 2w + + this.w = 0.5 * fRoot; + + fRoot = 0.5 / fRoot; // 1/(4w) + + this._x = (m[7] - m[5]) * fRoot; + this._y = (m[2] - m[6]) * fRoot; + this._z = (m[3] - m[1]) * fRoot; + } + else + { + // |w| <= 1/2 + var i = 0; + + if (m[4] > m[0]) + { + i = 1; + } + + if (m[8] > m[i * 3 + i]) + { + i = 2; + } + + var j = siNext[i]; + var k = siNext[j]; + + // This isn't quite as clean without array access + fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1); + tmp[i] = 0.5 * fRoot; + + fRoot = 0.5 / fRoot; + + tmp[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; + tmp[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; + + this._x = tmp[0]; + this._y = tmp[1]; + this._z = tmp[2]; + this._w = (m[k * 3 + j] - m[j * 3 + k]) * fRoot; + } + + this.onChangeCallback(this); + + return this; + } + +}); + +module.exports = Quaternion; + + +/***/ }), + +/***/ 23701: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(83392); + +/** + * Convert the given angle in radians, to the equivalent angle in degrees. + * + * @function Phaser.Math.RadToDeg + * @since 3.0.0 + * + * @param {number} radians - The angle in radians to convert ot degrees. + * + * @return {number} The given angle converted to degrees. + */ +var RadToDeg = function (radians) +{ + return radians * CONST.RAD_TO_DEG; +}; + +module.exports = RadToDeg; + + +/***/ }), + +/***/ 16906: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Compute a random unit vector. + * + * Computes random values for the given vector between -1 and 1 that can be used to represent a direction. + * + * Optionally accepts a scale value to scale the resulting vector by. + * + * @function Phaser.Math.RandomXY + * @since 3.0.0 + * + * @param {Phaser.Math.Vector2} vector - The Vector to compute random values for. + * @param {number} [scale=1] - The scale of the random values. + * + * @return {Phaser.Math.Vector2} The given Vector. + */ +var RandomXY = function (vector, scale) +{ + if (scale === undefined) { scale = 1; } + + var r = Math.random() * 2 * Math.PI; + + vector.x = Math.cos(r) * scale; + vector.y = Math.sin(r) * scale; + + return vector; +}; + +module.exports = RandomXY; + + +/***/ }), + +/***/ 52417: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Compute a random position vector in a spherical area, optionally defined by the given radius. + * + * @function Phaser.Math.RandomXYZ + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} vec3 - The Vector to compute random values for. + * @param {number} [radius=1] - The radius. + * + * @return {Phaser.Math.Vector3} The given Vector. + */ +var RandomXYZ = function (vec3, radius) +{ + if (radius === undefined) { radius = 1; } + + var r = Math.random() * 2 * Math.PI; + var z = (Math.random() * 2) - 1; + var zScale = Math.sqrt(1 - z * z) * radius; + + vec3.x = Math.cos(r) * zScale; + vec3.y = Math.sin(r) * zScale; + vec3.z = z * radius; + + return vec3; +}; + +module.exports = RandomXYZ; + + +/***/ }), + +/***/ 17915: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Compute a random four-dimensional vector. + * + * @function Phaser.Math.RandomXYZW + * @since 3.0.0 + * + * @param {Phaser.Math.Vector4} vec4 - The Vector to compute random values for. + * @param {number} [scale=1] - The scale of the random values. + * + * @return {Phaser.Math.Vector4} The given Vector. + */ +var RandomXYZW = function (vec4, scale) +{ + if (scale === undefined) { scale = 1; } + + vec4.x = (Math.random() * 2 - 1) * scale; + vec4.y = (Math.random() * 2 - 1) * scale; + vec4.z = (Math.random() * 2 - 1) * scale; + vec4.w = (Math.random() * 2 - 1) * scale; + + return vec4; +}; + +module.exports = RandomXYZW; + + +/***/ }), + +/***/ 52257: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Rotate a given point by a given angle around the origin (0, 0), in an anti-clockwise direction. + * + * @function Phaser.Math.Rotate + * @since 3.0.0 + * + * @param {(Phaser.Geom.Point|object)} point - The point to be rotated. + * @param {number} angle - The angle to be rotated by in an anticlockwise direction. + * + * @return {Phaser.Geom.Point} The given point, rotated by the given angle in an anticlockwise direction. + */ +var Rotate = function (point, angle) +{ + var x = point.x; + var y = point.y; + + point.x = (x * Math.cos(angle)) - (y * Math.sin(angle)); + point.y = (x * Math.sin(angle)) + (y * Math.cos(angle)); + + return point; +}; + +module.exports = Rotate; + + +/***/ }), + +/***/ 2386: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Rotate a `point` around `x` and `y` to the given `angle`, at the same distance. + * + * In polar notation, this maps a point from (r, t) to (r, angle), vs. the origin (x, y). + * + * @function Phaser.Math.RotateAround + * @since 3.0.0 + * + * @generic {Phaser.Types.Math.Vector2Like} T - [point,$return] + * + * @param {(Phaser.Geom.Point|object)} point - The point to be rotated. + * @param {number} x - The horizontal coordinate to rotate around. + * @param {number} y - The vertical coordinate to rotate around. + * @param {number} angle - The angle of rotation in radians. + * + * @return {Phaser.Types.Math.Vector2Like} The given point. + */ +var RotateAround = function (point, x, y, angle) +{ + var c = Math.cos(angle); + var s = Math.sin(angle); + + var tx = point.x - x; + var ty = point.y - y; + + point.x = tx * c - ty * s + x; + point.y = tx * s + ty * c + y; + + return point; +}; + +module.exports = RotateAround; + + +/***/ }), + +/***/ 72395: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Rotate a `point` around `x` and `y` by the given `angle` and `distance`. + * + * In polar notation, this maps a point from (r, t) to (distance, t + angle), vs. the origin (x, y). + * + * @function Phaser.Math.RotateAroundDistance + * @since 3.0.0 + * + * @generic {Phaser.Types.Math.Vector2Like} T - [point,$return] + * + * @param {(Phaser.Geom.Point|object)} point - The point to be rotated. + * @param {number} x - The horizontal coordinate to rotate around. + * @param {number} y - The vertical coordinate to rotate around. + * @param {number} angle - The angle of rotation in radians. + * @param {number} distance - The distance from (x, y) to place the point at. + * + * @return {Phaser.Types.Math.Vector2Like} The given point. + */ +var RotateAroundDistance = function (point, x, y, angle, distance) +{ + var t = angle + Math.atan2(point.y - y, point.x - x); + + point.x = x + (distance * Math.cos(t)); + point.y = y + (distance * Math.sin(t)); + + return point; +}; + +module.exports = RotateAroundDistance; + + +/***/ }), + +/***/ 41061: +/***/ ((module) => { + +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Position a `point` at the given `angle` and `distance` to (`x`, `y`). + * + * @function Phaser.Math.RotateTo + * @since 3.24.0 + * + * @generic {Phaser.Types.Math.Vector2Like} T - [point,$return] + * + * @param {Phaser.Types.Math.Vector2Like} point - The point to be positioned. + * @param {number} x - The horizontal coordinate to position from. + * @param {number} y - The vertical coordinate to position from. + * @param {number} angle - The angle of rotation in radians. + * @param {number} distance - The distance from (x, y) to place the point at. + * + * @return {Phaser.Types.Math.Vector2Like} The given point. + */ +var RotateTo = function (point, x, y, angle, distance) +{ + point.x = x + (distance * Math.cos(angle)); + point.y = y + (distance * Math.sin(angle)); + + return point; +}; + +module.exports = RotateTo; + + +/***/ }), + +/***/ 93709: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector3 = __webpack_require__(70015); +var Matrix4 = __webpack_require__(16650); +var Quaternion = __webpack_require__(75003); + +var tmpMat4 = new Matrix4(); +var tmpQuat = new Quaternion(); +var tmpVec3 = new Vector3(); + +/** + * Rotates a vector in place by axis angle. + * + * This is the same as transforming a point by an + * axis-angle quaternion, but it has higher precision. + * + * @function Phaser.Math.RotateVec3 + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} vec - The vector to be rotated. + * @param {Phaser.Math.Vector3} axis - The axis to rotate around. + * @param {number} radians - The angle of rotation in radians. + * + * @return {Phaser.Math.Vector3} The given vector. + */ +var RotateVec3 = function (vec, axis, radians) +{ + // Set the quaternion to our axis angle + tmpQuat.setAxisAngle(axis, radians); + + // Create a rotation matrix from the axis angle + tmpMat4.fromRotationTranslation(tmpQuat, tmpVec3.set(0, 0, 0)); + + // Multiply our vector by the rotation matrix + return vec.transformMat4(tmpMat4); +}; + +module.exports = RotateVec3; + + +/***/ }), + +/***/ 67233: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Round a given number so it is further away from zero. That is, positive numbers are rounded up, and negative numbers are rounded down. + * + * @function Phaser.Math.RoundAwayFromZero + * @since 3.0.0 + * + * @param {number} value - The number to round. + * + * @return {number} The rounded number, rounded away from zero. + */ +var RoundAwayFromZero = function (value) +{ + // "Opposite" of truncate. + return (value > 0) ? Math.ceil(value) : Math.floor(value); +}; + +module.exports = RoundAwayFromZero; + + +/***/ }), + +/***/ 64333: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Round a value to the given precision. + * + * For example: + * + * ```javascript + * RoundTo(123.456, 0) = 123 + * RoundTo(123.456, 1) = 120 + * RoundTo(123.456, 2) = 100 + * ``` + * + * To round the decimal, i.e. to round to precision, pass in a negative `place`: + * + * ```javascript + * RoundTo(123.456789, 0) = 123 + * RoundTo(123.456789, -1) = 123.5 + * RoundTo(123.456789, -2) = 123.46 + * RoundTo(123.456789, -3) = 123.457 + * ``` + * + * @function Phaser.Math.RoundTo + * @since 3.0.0 + * + * @param {number} value - The value to round. + * @param {number} [place=0] - The place to round to. Positive to round the units, negative to round the decimal. + * @param {number} [base=10] - The base to round in. Default is 10 for decimal. + * + * @return {number} The rounded value. + */ +var RoundTo = function (value, place, base) +{ + if (place === undefined) { place = 0; } + if (base === undefined) { base = 10; } + + var p = Math.pow(base, -place); + + return Math.round(value * p) / p; +}; + +module.exports = RoundTo; + + +/***/ }), + +/***/ 59533: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Generate a series of sine and cosine values. + * + * @function Phaser.Math.SinCosTableGenerator + * @since 3.0.0 + * + * @param {number} length - The number of values to generate. + * @param {number} [sinAmp=1] - The sine value amplitude. + * @param {number} [cosAmp=1] - The cosine value amplitude. + * @param {number} [frequency=1] - The frequency of the values. + * + * @return {Phaser.Types.Math.SinCosTable} The generated values. + */ +var SinCosTableGenerator = function (length, sinAmp, cosAmp, frequency) +{ + if (sinAmp === undefined) { sinAmp = 1; } + if (cosAmp === undefined) { cosAmp = 1; } + if (frequency === undefined) { frequency = 1; } + + frequency *= Math.PI / length; + + var cos = []; + var sin = []; + + for (var c = 0; c < length; c++) + { + cosAmp -= sinAmp * frequency; + sinAmp += cosAmp * frequency; + + cos[c] = cosAmp; + sin[c] = sinAmp; + } + + return { + sin: sin, + cos: cos, + length: length + }; +}; + +module.exports = SinCosTableGenerator; + + +/***/ }), + +/***/ 5514: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate a smooth interpolation percentage of `x` between `min` and `max`. + * + * The function receives the number `x` as an argument and returns 0 if `x` is less than or equal to the left edge, + * 1 if `x` is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial, + * between 0 and 1 otherwise. + * + * @function Phaser.Math.SmoothStep + * @since 3.0.0 + * @see {@link https://en.wikipedia.org/wiki/Smoothstep} + * + * @param {number} x - The input value. + * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'. + * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'. + * + * @return {number} The percentage of interpolation, between 0 and 1. + */ +var SmoothStep = function (x, min, max) +{ + if (x <= min) + { + return 0; + } + + if (x >= max) + { + return 1; + } + + x = (x - min) / (max - min); + + return x * x * (3 - 2 * x); +}; + +module.exports = SmoothStep; + + +/***/ }), + +/***/ 87736: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate a smoother interpolation percentage of `x` between `min` and `max`. + * + * The function receives the number `x` as an argument and returns 0 if `x` is less than or equal to the left edge, + * 1 if `x` is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial, + * between 0 and 1 otherwise. + * + * Produces an even smoother interpolation than {@link Phaser.Math.SmoothStep}. + * + * @function Phaser.Math.SmootherStep + * @since 3.0.0 + * @see {@link https://en.wikipedia.org/wiki/Smoothstep#Variations} + * + * @param {number} x - The input value. + * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'. + * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'. + * + * @return {number} The percentage of interpolation, between 0 and 1. + */ +var SmootherStep = function (x, min, max) +{ + x = Math.max(0, Math.min(1, (x - min) / (max - min))); + + return x * x * x * (x * (x * 6 - 15) + 10); +}; + +module.exports = SmootherStep; + + +/***/ }), + +/***/ 55805: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(93736); + +/** + * Returns a Vector2 containing the x and y position of the given index in a `width` x `height` sized grid. + * + * For example, in a 6 x 4 grid, index 16 would equal x: 4 y: 2. + * + * If the given index is out of range an empty Vector2 is returned. + * + * @function Phaser.Math.ToXY + * @since 3.19.0 + * + * @param {number} index - The position within the grid to get the x/y value for. + * @param {number} width - The width of the grid. + * @param {number} height - The height of the grid. + * @param {Phaser.Math.Vector2} [out] - An optional Vector2 to store the result in. If not given, a new Vector2 instance will be created. + * + * @return {Phaser.Math.Vector2} A Vector2 where the x and y properties contain the given grid index. + */ +var ToXY = function (index, width, height, out) +{ + if (out === undefined) { out = new Vector2(); } + + var x = 0; + var y = 0; + var total = width * height; + + if (index > 0 && index <= total) + { + if (index > width - 1) + { + y = Math.floor(index / width); + x = index - (y * width); + } + else + { + x = index; + } + } + + return out.set(x, y); +}; + +module.exports = ToXY; + + +/***/ }), + +/***/ 64462: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(93736); + +/** + * Takes the `x` and `y` coordinates and transforms them into the same space as + * defined by the position, rotation and scale values. + * + * @function Phaser.Math.TransformXY + * @since 3.0.0 + * + * @param {number} x - The x coordinate to be transformed. + * @param {number} y - The y coordinate to be transformed. + * @param {number} positionX - Horizontal position of the transform point. + * @param {number} positionY - Vertical position of the transform point. + * @param {number} rotation - Rotation of the transform point, in radians. + * @param {number} scaleX - Horizontal scale of the transform point. + * @param {number} scaleY - Vertical scale of the transform point. + * @param {(Phaser.Math.Vector2|Phaser.Geom.Point|object)} [output] - The output vector, point or object for the translated coordinates. + * + * @return {(Phaser.Math.Vector2|Phaser.Geom.Point|object)} The translated point. + */ +var TransformXY = function (x, y, positionX, positionY, rotation, scaleX, scaleY, output) +{ + if (output === undefined) { output = new Vector2(); } + + var radianSin = Math.sin(rotation); + var radianCos = Math.cos(rotation); + + // Rotate and Scale + var a = radianCos * scaleX; + var b = radianSin * scaleX; + var c = -radianSin * scaleY; + var d = radianCos * scaleY; + + // Invert + var id = 1 / ((a * d) + (c * -b)); + + output.x = (d * id * x) + (-c * id * y) + (((positionY * c) - (positionX * d)) * id); + output.y = (a * id * y) + (-b * id * x) + (((-positionY * a) + (positionX * b)) * id); + + return output; +}; + +module.exports = TransformXY; + + +/***/ }), + +/***/ 93736: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji +// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl + +var Class = __webpack_require__(56694); +var FuzzyEqual = __webpack_require__(88456); + +/** + * @classdesc + * A representation of a vector in 2D space. + * + * A two-component vector. + * + * @class Vector2 + * @memberof Phaser.Math + * @constructor + * @since 3.0.0 + * + * @param {number|Phaser.Types.Math.Vector2Like} [x=0] - The x component, or an object with `x` and `y` properties. + * @param {number} [y=x] - The y component. + */ +var Vector2 = new Class({ + + initialize: + + function Vector2 (x, y) + { + /** + * The x component of this Vector. + * + * @name Phaser.Math.Vector2#x + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.x = 0; + + /** + * The y component of this Vector. + * + * @name Phaser.Math.Vector2#y + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.y = 0; + + if (typeof x === 'object') + { + this.x = x.x || 0; + this.y = x.y || 0; + } + else + { + if (y === undefined) { y = x; } + + this.x = x || 0; + this.y = y || 0; + } + }, + + /** + * Make a clone of this Vector2. + * + * @method Phaser.Math.Vector2#clone + * @since 3.0.0 + * + * @return {Phaser.Math.Vector2} A clone of this Vector2. + */ + clone: function () + { + return new Vector2(this.x, this.y); + }, + + /** + * Copy the components of a given Vector into this Vector. + * + * @method Phaser.Math.Vector2#copy + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector to copy the components from. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + copy: function (src) + { + this.x = src.x || 0; + this.y = src.y || 0; + + return this; + }, + + /** + * Set the component values of this Vector from a given Vector2Like object. + * + * @method Phaser.Math.Vector2#setFromObject + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} obj - The object containing the component values to set for this Vector. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + setFromObject: function (obj) + { + this.x = obj.x || 0; + this.y = obj.y || 0; + + return this; + }, + + /** + * Set the `x` and `y` components of the this Vector to the given `x` and `y` values. + * + * @method Phaser.Math.Vector2#set + * @since 3.0.0 + * + * @param {number} x - The x value to set for this Vector. + * @param {number} [y=x] - The y value to set for this Vector. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + set: function (x, y) + { + if (y === undefined) { y = x; } + + this.x = x; + this.y = y; + + return this; + }, + + /** + * This method is an alias for `Vector2.set`. + * + * @method Phaser.Math.Vector2#setTo + * @since 3.4.0 + * + * @param {number} x - The x value to set for this Vector. + * @param {number} [y=x] - The y value to set for this Vector. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + setTo: function (x, y) + { + return this.set(x, y); + }, + + /** + * Sets the `x` and `y` values of this object from a given polar coordinate. + * + * @method Phaser.Math.Vector2#setToPolar + * @since 3.0.0 + * + * @param {number} azimuth - The angular coordinate, in radians. + * @param {number} [radius=1] - The radial coordinate (length). + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + setToPolar: function (azimuth, radius) + { + if (radius == null) { radius = 1; } + + this.x = Math.cos(azimuth) * radius; + this.y = Math.sin(azimuth) * radius; + + return this; + }, + + /** + * Check whether this Vector is equal to a given Vector. + * + * Performs a strict equality check against each Vector's components. + * + * @method Phaser.Math.Vector2#equals + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector. + * + * @return {boolean} Whether the given Vector is equal to this Vector. + */ + equals: function (v) + { + return ((this.x === v.x) && (this.y === v.y)); + }, + + /** + * Check whether this Vector is approximately equal to a given Vector. + * + * @method Phaser.Math.Vector2#fuzzyEquals + * @since 3.23.0 + * + * @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector. + * @param {number} [epsilon=0.0001] - The tolerance value. + * + * @return {boolean} Whether both absolute differences of the x and y components are smaller than `epsilon`. + */ + fuzzyEquals: function (v, epsilon) + { + return (FuzzyEqual(this.x, v.x, epsilon) && FuzzyEqual(this.y, v.y, epsilon)); + }, + + /** + * Calculate the angle between this Vector and the positive x-axis, in radians. + * + * @method Phaser.Math.Vector2#angle + * @since 3.0.0 + * + * @return {number} The angle between this Vector, and the positive x-axis, given in radians. + */ + angle: function () + { + // computes the angle in radians with respect to the positive x-axis + + var angle = Math.atan2(this.y, this.x); + + if (angle < 0) + { + angle += 2 * Math.PI; + } + + return angle; + }, + + /** + * Set the angle of this Vector. + * + * @method Phaser.Math.Vector2#setAngle + * @since 3.23.0 + * + * @param {number} angle - The angle, in radians. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + setAngle: function (angle) + { + return this.setToPolar(angle, this.length()); + }, + + /** + * Add a given Vector to this Vector. Addition is component-wise. + * + * @method Phaser.Math.Vector2#add + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector to add to this Vector. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + add: function (src) + { + this.x += src.x; + this.y += src.y; + + return this; + }, + + /** + * Subtract the given Vector from this Vector. Subtraction is component-wise. + * + * @method Phaser.Math.Vector2#subtract + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector to subtract from this Vector. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + subtract: function (src) + { + this.x -= src.x; + this.y -= src.y; + + return this; + }, + + /** + * Perform a component-wise multiplication between this Vector and the given Vector. + * + * Multiplies this Vector by the given Vector. + * + * @method Phaser.Math.Vector2#multiply + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector to multiply this Vector by. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + multiply: function (src) + { + this.x *= src.x; + this.y *= src.y; + + return this; + }, + + /** + * Scale this Vector by the given value. + * + * @method Phaser.Math.Vector2#scale + * @since 3.0.0 + * + * @param {number} value - The value to scale this Vector by. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + scale: function (value) + { + if (isFinite(value)) + { + this.x *= value; + this.y *= value; + } + else + { + this.x = 0; + this.y = 0; + } + + return this; + }, + + /** + * Perform a component-wise division between this Vector and the given Vector. + * + * Divides this Vector by the given Vector. + * + * @method Phaser.Math.Vector2#divide + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector to divide this Vector by. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + divide: function (src) + { + this.x /= src.x; + this.y /= src.y; + + return this; + }, + + /** + * Negate the `x` and `y` components of this Vector. + * + * @method Phaser.Math.Vector2#negate + * @since 3.0.0 + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + negate: function () + { + this.x = -this.x; + this.y = -this.y; + + return this; + }, + + /** + * Calculate the distance between this Vector and the given Vector. + * + * @method Phaser.Math.Vector2#distance + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to. + * + * @return {number} The distance from this Vector to the given Vector. + */ + distance: function (src) + { + var dx = src.x - this.x; + var dy = src.y - this.y; + + return Math.sqrt(dx * dx + dy * dy); + }, + + /** + * Calculate the distance between this Vector and the given Vector, squared. + * + * @method Phaser.Math.Vector2#distanceSq + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to. + * + * @return {number} The distance from this Vector to the given Vector, squared. + */ + distanceSq: function (src) + { + var dx = src.x - this.x; + var dy = src.y - this.y; + + return dx * dx + dy * dy; + }, + + /** + * Calculate the length (or magnitude) of this Vector. + * + * @method Phaser.Math.Vector2#length + * @since 3.0.0 + * + * @return {number} The length of this Vector. + */ + length: function () + { + var x = this.x; + var y = this.y; + + return Math.sqrt(x * x + y * y); + }, + + /** + * Set the length (or magnitude) of this Vector. + * + * @method Phaser.Math.Vector2#setLength + * @since 3.23.0 + * + * @param {number} length + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + setLength: function (length) + { + return this.normalize().scale(length); + }, + + /** + * Calculate the length of this Vector squared. + * + * @method Phaser.Math.Vector2#lengthSq + * @since 3.0.0 + * + * @return {number} The length of this Vector, squared. + */ + lengthSq: function () + { + var x = this.x; + var y = this.y; + + return x * x + y * y; + }, + + /** + * Normalize this Vector. + * + * Makes the vector a unit length vector (magnitude of 1) in the same direction. + * + * @method Phaser.Math.Vector2#normalize + * @since 3.0.0 + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + normalize: function () + { + var x = this.x; + var y = this.y; + var len = x * x + y * y; + + if (len > 0) + { + len = 1 / Math.sqrt(len); + + this.x = x * len; + this.y = y * len; + } + + return this; + }, + + /** + * Rotate this Vector to its perpendicular, in the positive direction. + * + * @method Phaser.Math.Vector2#normalizeRightHand + * @since 3.0.0 + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + normalizeRightHand: function () + { + var x = this.x; + + this.x = this.y * -1; + this.y = x; + + return this; + }, + + /** + * Rotate this Vector to its perpendicular, in the negative direction. + * + * @method Phaser.Math.Vector2#normalizeLeftHand + * @since 3.23.0 + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + normalizeLeftHand: function () + { + var x = this.x; + + this.x = this.y; + this.y = x * -1; + + return this; + }, + + /** + * Calculate the dot product of this Vector and the given Vector. + * + * @method Phaser.Math.Vector2#dot + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to dot product with this Vector2. + * + * @return {number} The dot product of this Vector and the given Vector. + */ + dot: function (src) + { + return this.x * src.x + this.y * src.y; + }, + + /** + * Calculate the cross product of this Vector and the given Vector. + * + * @method Phaser.Math.Vector2#cross + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to cross with this Vector2. + * + * @return {number} The cross product of this Vector and the given Vector. + */ + cross: function (src) + { + return this.x * src.y - this.y * src.x; + }, + + /** + * Linearly interpolate between this Vector and the given Vector. + * + * Interpolates this Vector towards the given Vector. + * + * @method Phaser.Math.Vector2#lerp + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to interpolate towards. + * @param {number} [t=0] - The interpolation percentage, between 0 and 1. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + lerp: function (src, t) + { + if (t === undefined) { t = 0; } + + var ax = this.x; + var ay = this.y; + + this.x = ax + t * (src.x - ax); + this.y = ay + t * (src.y - ay); + + return this; + }, + + /** + * Transform this Vector with the given Matrix. + * + * @method Phaser.Math.Vector2#transformMat3 + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector2 with. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + transformMat3: function (mat) + { + var x = this.x; + var y = this.y; + var m = mat.val; + + this.x = m[0] * x + m[3] * y + m[6]; + this.y = m[1] * x + m[4] * y + m[7]; + + return this; + }, + + /** + * Transform this Vector with the given Matrix. + * + * @method Phaser.Math.Vector2#transformMat4 + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector2 with. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + transformMat4: function (mat) + { + var x = this.x; + var y = this.y; + var m = mat.val; + + this.x = m[0] * x + m[4] * y + m[12]; + this.y = m[1] * x + m[5] * y + m[13]; + + return this; + }, + + /** + * Make this Vector the zero vector (0, 0). + * + * @method Phaser.Math.Vector2#reset + * @since 3.0.0 + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + reset: function () + { + this.x = 0; + this.y = 0; + + return this; + }, + + /** + * Limit the length (or magnitude) of this Vector. + * + * @method Phaser.Math.Vector2#limit + * @since 3.23.0 + * + * @param {number} max - The maximum length. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + limit: function (max) + { + var len = this.length(); + + if (len && len > max) + { + this.scale(max / len); + } + + return this; + }, + + /** + * Reflect this Vector off a line defined by a normal. + * + * @method Phaser.Math.Vector2#reflect + * @since 3.23.0 + * + * @param {Phaser.Math.Vector2} normal - A vector perpendicular to the line. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + reflect: function (normal) + { + normal = normal.clone().normalize(); + + return this.subtract(normal.scale(2 * this.dot(normal))); + }, + + /** + * Reflect this Vector across another. + * + * @method Phaser.Math.Vector2#mirror + * @since 3.23.0 + * + * @param {Phaser.Math.Vector2} axis - A vector to reflect across. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + mirror: function (axis) + { + return this.reflect(axis).negate(); + }, + + /** + * Rotate this Vector by an angle amount. + * + * @method Phaser.Math.Vector2#rotate + * @since 3.23.0 + * + * @param {number} delta - The angle to rotate by, in radians. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + rotate: function (delta) + { + var cos = Math.cos(delta); + var sin = Math.sin(delta); + + return this.set(cos * this.x - sin * this.y, sin * this.x + cos * this.y); + }, + + /** + * Project this Vector onto another. + * + * @method Phaser.Math.Vector2#project + * @since 3.60.0 + * + * @param {Phaser.Math.Vector2} src - The vector to project onto. + * + * @return {Phaser.Math.Vector2} This Vector2. + */ + project: function (src) + { + var scalar = this.dot(src) / src.dot(src); + + return this.copy(src).scale(scalar); + } + +}); + +/** + * A static zero Vector2 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector2.ZERO + * @type {Phaser.Math.Vector2} + * @since 3.1.0 + */ +Vector2.ZERO = new Vector2(); + +/** + * A static right Vector2 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector2.RIGHT + * @type {Phaser.Math.Vector2} + * @since 3.16.0 + */ +Vector2.RIGHT = new Vector2(1, 0); + +/** + * A static left Vector2 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector2.LEFT + * @type {Phaser.Math.Vector2} + * @since 3.16.0 + */ +Vector2.LEFT = new Vector2(-1, 0); + +/** + * A static up Vector2 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector2.UP + * @type {Phaser.Math.Vector2} + * @since 3.16.0 + */ +Vector2.UP = new Vector2(0, -1); + +/** + * A static down Vector2 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector2.DOWN + * @type {Phaser.Math.Vector2} + * @since 3.16.0 + */ +Vector2.DOWN = new Vector2(0, 1); + +/** + * A static one Vector2 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector2.ONE + * @type {Phaser.Math.Vector2} + * @since 3.16.0 + */ +Vector2.ONE = new Vector2(1, 1); + +module.exports = Vector2; + + +/***/ }), + +/***/ 70015: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji +// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl + +var Class = __webpack_require__(56694); + +/** + * @classdesc + * A representation of a vector in 3D space. + * + * A three-component vector. + * + * @class Vector3 + * @memberof Phaser.Math + * @constructor + * @since 3.0.0 + * + * @param {number} [x] - The x component. + * @param {number} [y] - The y component. + * @param {number} [z] - The z component. + */ +var Vector3 = new Class({ + + initialize: + + function Vector3 (x, y, z) + { + /** + * The x component of this Vector. + * + * @name Phaser.Math.Vector3#x + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.x = 0; + + /** + * The y component of this Vector. + * + * @name Phaser.Math.Vector3#y + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.y = 0; + + /** + * The z component of this Vector. + * + * @name Phaser.Math.Vector3#z + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.z = 0; + + if (typeof x === 'object') + { + this.x = x.x || 0; + this.y = x.y || 0; + this.z = x.z || 0; + } + else + { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + } + }, + + /** + * Set this Vector to point up. + * + * Sets the y component of the vector to 1, and the others to 0. + * + * @method Phaser.Math.Vector3#up + * @since 3.0.0 + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + up: function () + { + this.x = 0; + this.y = 1; + this.z = 0; + + return this; + }, + + /** + * Sets the components of this Vector to be the `Math.min` result from the given vector. + * + * @method Phaser.Math.Vector3#min + * @since 3.50.0 + * + * @param {Phaser.Math.Vector3} v - The Vector3 to check the minimum values against. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + min: function (v) + { + this.x = Math.min(this.x, v.x); + this.y = Math.min(this.y, v.y); + this.z = Math.min(this.z, v.z); + + return this; + }, + + /** + * Sets the components of this Vector to be the `Math.max` result from the given vector. + * + * @method Phaser.Math.Vector3#max + * @since 3.50.0 + * + * @param {Phaser.Math.Vector3} v - The Vector3 to check the maximum values against. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + max: function (v) + { + this.x = Math.max(this.x, v.x); + this.y = Math.max(this.y, v.y); + this.z = Math.max(this.z, v.z); + + return this; + }, + + /** + * Make a clone of this Vector3. + * + * @method Phaser.Math.Vector3#clone + * @since 3.0.0 + * + * @return {Phaser.Math.Vector3} A new Vector3 object containing this Vectors values. + */ + clone: function () + { + return new Vector3(this.x, this.y, this.z); + }, + + /** + * Adds the two given Vector3s and sets the results into this Vector3. + * + * @method Phaser.Math.Vector3#addVectors + * @since 3.50.0 + * + * @param {Phaser.Math.Vector3} a - The first Vector to add. + * @param {Phaser.Math.Vector3} b - The second Vector to add. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + addVectors: function (a, b) + { + this.x = a.x + b.x; + this.y = a.y + b.y; + this.z = a.z + b.z; + + return this; + }, + + /** + * Calculate the cross (vector) product of two given Vectors. + * + * @method Phaser.Math.Vector3#crossVectors + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} a - The first Vector to multiply. + * @param {Phaser.Math.Vector3} b - The second Vector to multiply. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + crossVectors: function (a, b) + { + var ax = a.x; + var ay = a.y; + var az = a.z; + var bx = b.x; + var by = b.y; + var bz = b.z; + + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; + + return this; + }, + + /** + * Check whether this Vector is equal to a given Vector. + * + * Performs a strict equality check against each Vector's components. + * + * @method Phaser.Math.Vector3#equals + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} v - The Vector3 to compare against. + * + * @return {boolean} True if the two vectors strictly match, otherwise false. + */ + equals: function (v) + { + return ((this.x === v.x) && (this.y === v.y) && (this.z === v.z)); + }, + + /** + * Copy the components of a given Vector into this Vector. + * + * @method Phaser.Math.Vector3#copy + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} src - The Vector to copy the components from. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + copy: function (src) + { + this.x = src.x; + this.y = src.y; + this.z = src.z || 0; + + return this; + }, + + /** + * Set the `x`, `y`, and `z` components of this Vector to the given `x`, `y`, and `z` values. + * + * @method Phaser.Math.Vector3#set + * @since 3.0.0 + * + * @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y and z components. + * @param {number} [y] - The y value to set for this Vector. + * @param {number} [z] - The z value to set for this Vector. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + set: function (x, y, z) + { + if (typeof x === 'object') + { + this.x = x.x || 0; + this.y = x.y || 0; + this.z = x.z || 0; + } + else + { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + } + + return this; + }, + + /** + * Sets the components of this Vector3 from the position of the given Matrix4. + * + * @method Phaser.Math.Vector3#setFromMatrixPosition + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the position from. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + setFromMatrixPosition: function (m) + { + return this.fromArray(m.val, 12); + }, + + /** + * Sets the components of this Vector3 from the Matrix4 column specified. + * + * @method Phaser.Math.Vector3#setFromMatrixColumn + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the column from. + * @param {number} index - The column index. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + setFromMatrixColumn: function (mat4, index) + { + return this.fromArray(mat4.val, index * 4); + }, + + /** + * Sets the components of this Vector3 from the given array, based on the offset. + * + * Vector3.x = array[offset] + * Vector3.y = array[offset + 1] + * Vector3.z = array[offset + 2] + * + * @method Phaser.Math.Vector3#fromArray + * @since 3.50.0 + * + * @param {number[]} array - The array of values to get this Vector from. + * @param {number} [offset=0] - The offset index into the array. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + fromArray: function (array, offset) + { + if (offset === undefined) { offset = 0; } + + this.x = array[offset]; + this.y = array[offset + 1]; + this.z = array[offset + 2]; + + return this; + }, + + /** + * Add a given Vector to this Vector. Addition is component-wise. + * + * @method Phaser.Math.Vector3#add + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + add: function (v) + { + this.x += v.x; + this.y += v.y; + this.z += v.z || 0; + + return this; + }, + + /** + * Add the given value to each component of this Vector. + * + * @method Phaser.Math.Vector3#addScalar + * @since 3.50.0 + * + * @param {number} s - The amount to add to this Vector. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + addScalar: function (s) + { + this.x += s; + this.y += s; + this.z += s; + + return this; + }, + + /** + * Add and scale a given Vector to this Vector. Addition is component-wise. + * + * @method Phaser.Math.Vector3#addScale + * @since 3.50.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector. + * @param {number} scale - The amount to scale `v` by. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + addScale: function (v, scale) + { + this.x += v.x * scale; + this.y += v.y * scale; + this.z += v.z * scale || 0; + + return this; + }, + + /** + * Subtract the given Vector from this Vector. Subtraction is component-wise. + * + * @method Phaser.Math.Vector3#subtract + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to subtract from this Vector. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + subtract: function (v) + { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z || 0; + + return this; + }, + + /** + * Perform a component-wise multiplication between this Vector and the given Vector. + * + * Multiplies this Vector by the given Vector. + * + * @method Phaser.Math.Vector3#multiply + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to multiply this Vector by. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + multiply: function (v) + { + this.x *= v.x; + this.y *= v.y; + this.z *= v.z || 1; + + return this; + }, + + /** + * Scale this Vector by the given value. + * + * @method Phaser.Math.Vector3#scale + * @since 3.0.0 + * + * @param {number} scale - The value to scale this Vector by. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + scale: function (scale) + { + if (isFinite(scale)) + { + this.x *= scale; + this.y *= scale; + this.z *= scale; + } + else + { + this.x = 0; + this.y = 0; + this.z = 0; + } + + return this; + }, + + /** + * Perform a component-wise division between this Vector and the given Vector. + * + * Divides this Vector by the given Vector. + * + * @method Phaser.Math.Vector3#divide + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to divide this Vector by. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + divide: function (v) + { + this.x /= v.x; + this.y /= v.y; + this.z /= v.z || 1; + + return this; + }, + + /** + * Negate the `x`, `y` and `z` components of this Vector. + * + * @method Phaser.Math.Vector3#negate + * @since 3.0.0 + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + negate: function () + { + this.x = -this.x; + this.y = -this.y; + this.z = -this.z; + + return this; + }, + + /** + * Calculate the distance between this Vector and the given Vector. + * + * @method Phaser.Math.Vector3#distance + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to. + * + * @return {number} The distance from this Vector to the given Vector. + */ + distance: function (v) + { + var dx = v.x - this.x; + var dy = v.y - this.y; + var dz = v.z - this.z || 0; + + return Math.sqrt(dx * dx + dy * dy + dz * dz); + }, + + /** + * Calculate the distance between this Vector and the given Vector, squared. + * + * @method Phaser.Math.Vector3#distanceSq + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to. + * + * @return {number} The distance from this Vector to the given Vector, squared. + */ + distanceSq: function (v) + { + var dx = v.x - this.x; + var dy = v.y - this.y; + var dz = v.z - this.z || 0; + + return dx * dx + dy * dy + dz * dz; + }, + + /** + * Calculate the length (or magnitude) of this Vector. + * + * @method Phaser.Math.Vector3#length + * @since 3.0.0 + * + * @return {number} The length of this Vector. + */ + length: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + + return Math.sqrt(x * x + y * y + z * z); + }, + + /** + * Calculate the length of this Vector squared. + * + * @method Phaser.Math.Vector3#lengthSq + * @since 3.0.0 + * + * @return {number} The length of this Vector, squared. + */ + lengthSq: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + + return x * x + y * y + z * z; + }, + + /** + * Normalize this Vector. + * + * Makes the vector a unit length vector (magnitude of 1) in the same direction. + * + * @method Phaser.Math.Vector3#normalize + * @since 3.0.0 + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + normalize: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + var len = x * x + y * y + z * z; + + if (len > 0) + { + len = 1 / Math.sqrt(len); + + this.x = x * len; + this.y = y * len; + this.z = z * len; + } + + return this; + }, + + /** + * Calculate the dot product of this Vector and the given Vector. + * + * @method Phaser.Math.Vector3#dot + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} v - The Vector3 to dot product with this Vector3. + * + * @return {number} The dot product of this Vector and `v`. + */ + dot: function (v) + { + return this.x * v.x + this.y * v.y + this.z * v.z; + }, + + /** + * Calculate the cross (vector) product of this Vector (which will be modified) and the given Vector. + * + * @method Phaser.Math.Vector3#cross + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} v - The Vector to cross product with. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + cross: function (v) + { + var ax = this.x; + var ay = this.y; + var az = this.z; + var bx = v.x; + var by = v.y; + var bz = v.z; + + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; + + return this; + }, + + /** + * Linearly interpolate between this Vector and the given Vector. + * + * Interpolates this Vector towards the given Vector. + * + * @method Phaser.Math.Vector3#lerp + * @since 3.0.0 + * + * @param {Phaser.Math.Vector3} v - The Vector3 to interpolate towards. + * @param {number} [t=0] - The interpolation percentage, between 0 and 1. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + lerp: function (v, t) + { + if (t === undefined) { t = 0; } + + var ax = this.x; + var ay = this.y; + var az = this.z; + + this.x = ax + t * (v.x - ax); + this.y = ay + t * (v.y - ay); + this.z = az + t * (v.z - az); + + return this; + }, + + /** + * Takes a Matrix3 and applies it to this Vector3. + * + * @method Phaser.Math.Vector3#applyMatrix3 + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix3} mat3 - The Matrix3 to apply to this Vector3. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + applyMatrix3: function (mat3) + { + var x = this.x; + var y = this.y; + var z = this.z; + var m = mat3.val; + + this.x = m[0] * x + m[3] * y + m[6] * z; + this.y = m[1] * x + m[4] * y + m[7] * z; + this.z = m[2] * x + m[5] * y + m[8] * z; + + return this; + }, + + /** + * Takes a Matrix4 and applies it to this Vector3. + * + * @method Phaser.Math.Vector3#applyMatrix4 + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to apply to this Vector3. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + applyMatrix4: function (mat4) + { + var x = this.x; + var y = this.y; + var z = this.z; + var m = mat4.val; + + var w = 1 / (m[3] * x + m[7] * y + m[11] * z + m[15]); + + this.x = (m[0] * x + m[4] * y + m[8] * z + m[12]) * w; + this.y = (m[1] * x + m[5] * y + m[9] * z + m[13]) * w; + this.z = (m[2] * x + m[6] * y + m[10] * z + m[14]) * w; + + return this; + }, + + /** + * Transform this Vector with the given Matrix. + * + * @method Phaser.Math.Vector3#transformMat3 + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector3 with. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + transformMat3: function (mat) + { + var x = this.x; + var y = this.y; + var z = this.z; + var m = mat.val; + + this.x = x * m[0] + y * m[3] + z * m[6]; + this.y = x * m[1] + y * m[4] + z * m[7]; + this.z = x * m[2] + y * m[5] + z * m[8]; + + return this; + }, + + /** + * Transform this Vector with the given Matrix4. + * + * @method Phaser.Math.Vector3#transformMat4 + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + transformMat4: function (mat) + { + var x = this.x; + var y = this.y; + var z = this.z; + var m = mat.val; + + this.x = m[0] * x + m[4] * y + m[8] * z + m[12]; + this.y = m[1] * x + m[5] * y + m[9] * z + m[13]; + this.z = m[2] * x + m[6] * y + m[10] * z + m[14]; + + return this; + }, + + /** + * Transforms the coordinates of this Vector3 with the given Matrix4. + * + * @method Phaser.Math.Vector3#transformCoordinates + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + transformCoordinates: function (mat) + { + var x = this.x; + var y = this.y; + var z = this.z; + var m = mat.val; + + var tx = (x * m[0]) + (y * m[4]) + (z * m[8]) + m[12]; + var ty = (x * m[1]) + (y * m[5]) + (z * m[9]) + m[13]; + var tz = (x * m[2]) + (y * m[6]) + (z * m[10]) + m[14]; + var tw = (x * m[3]) + (y * m[7]) + (z * m[11]) + m[15]; + + this.x = tx / tw; + this.y = ty / tw; + this.z = tz / tw; + + return this; + }, + + /** + * Transform this Vector with the given Quaternion. + * + * @method Phaser.Math.Vector3#transformQuat + * @since 3.0.0 + * + * @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + transformQuat: function (q) + { + // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations + var x = this.x; + var y = this.y; + var z = this.z; + var qx = q.x; + var qy = q.y; + var qz = q.z; + var qw = q.w; + + // calculate quat * vec + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; + + // calculate result * inverse quat + this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + + return this; + }, + + /** + * Multiplies this Vector3 by the specified matrix, applying a W divide. This is useful for projection, + * e.g. unprojecting a 2D point into 3D space. + * + * @method Phaser.Math.Vector3#project + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix4} mat - The Matrix4 to multiply this Vector3 with. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + project: function (mat) + { + var x = this.x; + var y = this.y; + var z = this.z; + var m = mat.val; + + var a00 = m[0]; + var a01 = m[1]; + var a02 = m[2]; + var a03 = m[3]; + var a10 = m[4]; + var a11 = m[5]; + var a12 = m[6]; + var a13 = m[7]; + var a20 = m[8]; + var a21 = m[9]; + var a22 = m[10]; + var a23 = m[11]; + var a30 = m[12]; + var a31 = m[13]; + var a32 = m[14]; + var a33 = m[15]; + + var lw = 1 / (x * a03 + y * a13 + z * a23 + a33); + + this.x = (x * a00 + y * a10 + z * a20 + a30) * lw; + this.y = (x * a01 + y * a11 + z * a21 + a31) * lw; + this.z = (x * a02 + y * a12 + z * a22 + a32) * lw; + + return this; + }, + + /** + * Multiplies this Vector3 by the given view and projection matrices. + * + * @method Phaser.Math.Vector3#projectViewMatrix + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix4} viewMatrix - A View Matrix. + * @param {Phaser.Math.Matrix4} projectionMatrix - A Projection Matrix. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + projectViewMatrix: function (viewMatrix, projectionMatrix) + { + return this.applyMatrix4(viewMatrix).applyMatrix4(projectionMatrix); + }, + + /** + * Multiplies this Vector3 by the given inversed projection matrix and world matrix. + * + * @method Phaser.Math.Vector3#unprojectViewMatrix + * @since 3.50.0 + * + * @param {Phaser.Math.Matrix4} projectionMatrix - An inversed Projection Matrix. + * @param {Phaser.Math.Matrix4} worldMatrix - A World View Matrix. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + unprojectViewMatrix: function (projectionMatrix, worldMatrix) + { + return this.applyMatrix4(projectionMatrix).applyMatrix4(worldMatrix); + }, + + /** + * Unproject this point from 2D space to 3D space. + * The point should have its x and y properties set to + * 2D screen space, and the z either at 0 (near plane) + * or 1 (far plane). The provided matrix is assumed to already + * be combined, i.e. projection * view * model. + * + * After this operation, this vector's (x, y, z) components will + * represent the unprojected 3D coordinate. + * + * @method Phaser.Math.Vector3#unproject + * @since 3.0.0 + * + * @param {Phaser.Math.Vector4} viewport - Screen x, y, width and height in pixels. + * @param {Phaser.Math.Matrix4} invProjectionView - Combined projection and view matrix. + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + unproject: function (viewport, invProjectionView) + { + var viewX = viewport.x; + var viewY = viewport.y; + var viewWidth = viewport.z; + var viewHeight = viewport.w; + + var x = this.x - viewX; + var y = (viewHeight - this.y - 1) - viewY; + var z = this.z; + + this.x = (2 * x) / viewWidth - 1; + this.y = (2 * y) / viewHeight - 1; + this.z = 2 * z - 1; + + return this.project(invProjectionView); + }, + + /** + * Make this Vector the zero vector (0, 0, 0). + * + * @method Phaser.Math.Vector3#reset + * @since 3.0.0 + * + * @return {Phaser.Math.Vector3} This Vector3. + */ + reset: function () + { + this.x = 0; + this.y = 0; + this.z = 0; + + return this; + } + +}); + +/** + * A static zero Vector3 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector3.ZERO + * @type {Phaser.Math.Vector3} + * @since 3.16.0 + */ +Vector3.ZERO = new Vector3(); + +/** + * A static right Vector3 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector3.RIGHT + * @type {Phaser.Math.Vector3} + * @since 3.16.0 + */ +Vector3.RIGHT = new Vector3(1, 0, 0); + +/** + * A static left Vector3 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector3.LEFT + * @type {Phaser.Math.Vector3} + * @since 3.16.0 + */ +Vector3.LEFT = new Vector3(-1, 0, 0); + +/** + * A static up Vector3 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector3.UP + * @type {Phaser.Math.Vector3} + * @since 3.16.0 + */ +Vector3.UP = new Vector3(0, -1, 0); + +/** + * A static down Vector3 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector3.DOWN + * @type {Phaser.Math.Vector3} + * @since 3.16.0 + */ +Vector3.DOWN = new Vector3(0, 1, 0); + +/** + * A static forward Vector3 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector3.FORWARD + * @type {Phaser.Math.Vector3} + * @since 3.16.0 + */ +Vector3.FORWARD = new Vector3(0, 0, 1); + +/** + * A static back Vector3 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector3.BACK + * @type {Phaser.Math.Vector3} + * @since 3.16.0 + */ +Vector3.BACK = new Vector3(0, 0, -1); + +/** + * A static one Vector3 for use by reference. + * + * This constant is meant for comparison operations and should not be modified directly. + * + * @constant + * @name Phaser.Math.Vector3.ONE + * @type {Phaser.Math.Vector3} + * @since 3.16.0 + */ +Vector3.ONE = new Vector3(1, 1, 1); + +module.exports = Vector3; + + +/***/ }), + +/***/ 51729: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Adapted from [gl-matrix](https://github.com/toji/gl-matrix) by toji +// and [vecmath](https://github.com/mattdesl/vecmath) by mattdesl + +var Class = __webpack_require__(56694); + +/** + * @classdesc + * A representation of a vector in 4D space. + * + * A four-component vector. + * + * @class Vector4 + * @memberof Phaser.Math + * @constructor + * @since 3.0.0 + * + * @param {number} [x] - The x component. + * @param {number} [y] - The y component. + * @param {number} [z] - The z component. + * @param {number} [w] - The w component. + */ +var Vector4 = new Class({ + + initialize: + + function Vector4 (x, y, z, w) + { + /** + * The x component of this Vector. + * + * @name Phaser.Math.Vector4#x + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.x = 0; + + /** + * The y component of this Vector. + * + * @name Phaser.Math.Vector4#y + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.y = 0; + + /** + * The z component of this Vector. + * + * @name Phaser.Math.Vector4#z + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.z = 0; + + /** + * The w component of this Vector. + * + * @name Phaser.Math.Vector4#w + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.w = 0; + + if (typeof x === 'object') + { + this.x = x.x || 0; + this.y = x.y || 0; + this.z = x.z || 0; + this.w = x.w || 0; + } + else + { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w || 0; + } + }, + + /** + * Make a clone of this Vector4. + * + * @method Phaser.Math.Vector4#clone + * @since 3.0.0 + * + * @return {Phaser.Math.Vector4} A clone of this Vector4. + */ + clone: function () + { + return new Vector4(this.x, this.y, this.z, this.w); + }, + + /** + * Copy the components of a given Vector into this Vector. + * + * @method Phaser.Math.Vector4#copy + * @since 3.0.0 + * + * @param {Phaser.Math.Vector4} src - The Vector to copy the components from. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + copy: function (src) + { + this.x = src.x; + this.y = src.y; + this.z = src.z || 0; + this.w = src.w || 0; + + return this; + }, + + /** + * Check whether this Vector is equal to a given Vector. + * + * Performs a strict quality check against each Vector's components. + * + * @method Phaser.Math.Vector4#equals + * @since 3.0.0 + * + * @param {Phaser.Math.Vector4} v - The vector to check equality with. + * + * @return {boolean} A boolean indicating whether the two Vectors are equal or not. + */ + equals: function (v) + { + return ((this.x === v.x) && (this.y === v.y) && (this.z === v.z) && (this.w === v.w)); + }, + + /** + * Set the `x`, `y`, `z` and `w` components of the this Vector to the given `x`, `y`, `z` and `w` values. + * + * @method Phaser.Math.Vector4#set + * @since 3.0.0 + * + * @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y, z and w components. + * @param {number} y - The y value to set for this Vector. + * @param {number} z - The z value to set for this Vector. + * @param {number} w - The z value to set for this Vector. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + set: function (x, y, z, w) + { + if (typeof x === 'object') + { + this.x = x.x || 0; + this.y = x.y || 0; + this.z = x.z || 0; + this.w = x.w || 0; + } + else + { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w || 0; + } + + return this; + }, + + /** + * Add a given Vector to this Vector. Addition is component-wise. + * + * @method Phaser.Math.Vector4#add + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to add to this Vector. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + add: function (v) + { + this.x += v.x; + this.y += v.y; + this.z += v.z || 0; + this.w += v.w || 0; + + return this; + }, + + /** + * Subtract the given Vector from this Vector. Subtraction is component-wise. + * + * @method Phaser.Math.Vector4#subtract + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to subtract from this Vector. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + subtract: function (v) + { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z || 0; + this.w -= v.w || 0; + + return this; + }, + + /** + * Scale this Vector by the given value. + * + * @method Phaser.Math.Vector4#scale + * @since 3.0.0 + * + * @param {number} scale - The value to scale this Vector by. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + scale: function (scale) + { + this.x *= scale; + this.y *= scale; + this.z *= scale; + this.w *= scale; + + return this; + }, + + /** + * Calculate the length (or magnitude) of this Vector. + * + * @method Phaser.Math.Vector4#length + * @since 3.0.0 + * + * @return {number} The length of this Vector. + */ + length: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; + + return Math.sqrt(x * x + y * y + z * z + w * w); + }, + + /** + * Calculate the length of this Vector squared. + * + * @method Phaser.Math.Vector4#lengthSq + * @since 3.0.0 + * + * @return {number} The length of this Vector, squared. + */ + lengthSq: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; + + return x * x + y * y + z * z + w * w; + }, + + /** + * Normalize this Vector. + * + * Makes the vector a unit length vector (magnitude of 1) in the same direction. + * + * @method Phaser.Math.Vector4#normalize + * @since 3.0.0 + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + normalize: function () + { + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; + var len = x * x + y * y + z * z + w * w; + + if (len > 0) + { + len = 1 / Math.sqrt(len); + + this.x = x * len; + this.y = y * len; + this.z = z * len; + this.w = w * len; + } + + return this; + }, + + /** + * Calculate the dot product of this Vector and the given Vector. + * + * @method Phaser.Math.Vector4#dot + * @since 3.0.0 + * + * @param {Phaser.Math.Vector4} v - The Vector4 to dot product with this Vector4. + * + * @return {number} The dot product of this Vector and the given Vector. + */ + dot: function (v) + { + return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; + }, + + /** + * Linearly interpolate between this Vector and the given Vector. + * + * Interpolates this Vector towards the given Vector. + * + * @method Phaser.Math.Vector4#lerp + * @since 3.0.0 + * + * @param {Phaser.Math.Vector4} v - The Vector4 to interpolate towards. + * @param {number} [t=0] - The interpolation percentage, between 0 and 1. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + lerp: function (v, t) + { + if (t === undefined) { t = 0; } + + var ax = this.x; + var ay = this.y; + var az = this.z; + var aw = this.w; + + this.x = ax + t * (v.x - ax); + this.y = ay + t * (v.y - ay); + this.z = az + t * (v.z - az); + this.w = aw + t * (v.w - aw); + + return this; + }, + + /** + * Perform a component-wise multiplication between this Vector and the given Vector. + * + * Multiplies this Vector by the given Vector. + * + * @method Phaser.Math.Vector4#multiply + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to multiply this Vector by. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + multiply: function (v) + { + this.x *= v.x; + this.y *= v.y; + this.z *= v.z || 1; + this.w *= v.w || 1; + + return this; + }, + + /** + * Perform a component-wise division between this Vector and the given Vector. + * + * Divides this Vector by the given Vector. + * + * @method Phaser.Math.Vector4#divide + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to divide this Vector by. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + divide: function (v) + { + this.x /= v.x; + this.y /= v.y; + this.z /= v.z || 1; + this.w /= v.w || 1; + + return this; + }, + + /** + * Calculate the distance between this Vector and the given Vector. + * + * @method Phaser.Math.Vector4#distance + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to. + * + * @return {number} The distance from this Vector to the given Vector. + */ + distance: function (v) + { + var dx = v.x - this.x; + var dy = v.y - this.y; + var dz = v.z - this.z || 0; + var dw = v.w - this.w || 0; + + return Math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw); + }, + + /** + * Calculate the distance between this Vector and the given Vector, squared. + * + * @method Phaser.Math.Vector4#distanceSq + * @since 3.0.0 + * + * @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to. + * + * @return {number} The distance from this Vector to the given Vector, squared. + */ + distanceSq: function (v) + { + var dx = v.x - this.x; + var dy = v.y - this.y; + var dz = v.z - this.z || 0; + var dw = v.w - this.w || 0; + + return dx * dx + dy * dy + dz * dz + dw * dw; + }, + + /** + * Negate the `x`, `y`, `z` and `w` components of this Vector. + * + * @method Phaser.Math.Vector4#negate + * @since 3.0.0 + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + negate: function () + { + this.x = -this.x; + this.y = -this.y; + this.z = -this.z; + this.w = -this.w; + + return this; + }, + + /** + * Transform this Vector with the given Matrix. + * + * @method Phaser.Math.Vector4#transformMat4 + * @since 3.0.0 + * + * @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector4 with. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + transformMat4: function (mat) + { + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; + var m = mat.val; + + this.x = m[0] * x + m[4] * y + m[8] * z + m[12] * w; + this.y = m[1] * x + m[5] * y + m[9] * z + m[13] * w; + this.z = m[2] * x + m[6] * y + m[10] * z + m[14] * w; + this.w = m[3] * x + m[7] * y + m[11] * z + m[15] * w; + + return this; + }, + + /** + * Transform this Vector with the given Quaternion. + * + * @method Phaser.Math.Vector4#transformQuat + * @since 3.0.0 + * + * @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with. + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + transformQuat: function (q) + { + var x = this.x; + var y = this.y; + var z = this.z; + var qx = q.x; + var qy = q.y; + var qz = q.z; + var qw = q.w; + + // calculate quat * vec + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; + + // calculate result * inverse quat + this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + + return this; + }, + + /** + * Make this Vector the zero vector (0, 0, 0, 0). + * + * @method Phaser.Math.Vector4#reset + * @since 3.0.0 + * + * @return {Phaser.Math.Vector4} This Vector4. + */ + reset: function () + { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 0; + + return this; + } + +}); + +Vector4.prototype.sub = Vector4.prototype.subtract; +Vector4.prototype.mul = Vector4.prototype.multiply; +Vector4.prototype.div = Vector4.prototype.divide; +Vector4.prototype.dist = Vector4.prototype.distance; +Vector4.prototype.distSq = Vector4.prototype.distanceSq; +Vector4.prototype.len = Vector4.prototype.length; +Vector4.prototype.lenSq = Vector4.prototype.lengthSq; + +module.exports = Vector4; + + +/***/ }), + +/***/ 9557: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks if the two values are within the given `tolerance` of each other. + * + * @function Phaser.Math.Within + * @since 3.0.0 + * + * @param {number} a - The first value to use in the calculation. + * @param {number} b - The second value to use in the calculation. + * @param {number} tolerance - The tolerance. Anything equal to or less than this value is considered as being within range. + * + * @return {boolean} Returns `true` if `a` is less than or equal to the tolerance of `b`. + */ +var Within = function (a, b, tolerance) +{ + return (Math.abs(a - b) <= tolerance); +}; + +module.exports = Within; + + +/***/ }), + +/***/ 1071: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 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) +{ + if (value >= min && value <= max) + { + // Skip modulo if already in range + return value; + } + + var range = max - min; + + return (min + ((((value - min) % range) + range) % range)); +}; + +module.exports = Wrap; + + +/***/ }), + +/***/ 90447: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Find the angle of a segment from (x1, y1) -> (x2, y2). + * + * @function Phaser.Math.Angle.Between + * @since 3.0.0 + * + * @param {number} x1 - The x coordinate of the first point. + * @param {number} y1 - The y coordinate of the first point. + * @param {number} x2 - The x coordinate of the second point. + * @param {number} y2 - The y coordinate of the second point. + * + * @return {number} The angle in radians. + */ +var Between = function (x1, y1, x2, y2) +{ + return Math.atan2(y2 - y1, x2 - x1); +}; + +module.exports = Between; + + +/***/ }), + +/***/ 94240: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Find the angle of a segment from (point1.x, point1.y) -> (point2.x, point2.y). + * + * Calculates the angle of the vector from the first point to the second point. + * + * @function Phaser.Math.Angle.BetweenPoints + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} point1 - The first point. + * @param {Phaser.Types.Math.Vector2Like} point2 - The second point. + * + * @return {number} The angle in radians. + */ +var BetweenPoints = function (point1, point2) +{ + return Math.atan2(point2.y - point1.y, point2.x - point1.x); +}; + +module.exports = BetweenPoints; + + +/***/ }), + +/***/ 84066: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Find the angle of a segment from (point1.x, point1.y) -> (point2.x, point2.y). + * + * The difference between this method and {@link Phaser.Math.Angle.BetweenPoints} is that this assumes the y coordinate + * travels down the screen. + * + * @function Phaser.Math.Angle.BetweenPointsY + * @since 3.0.0 + * + * @param {Phaser.Types.Math.Vector2Like} point1 - The first point. + * @param {Phaser.Types.Math.Vector2Like} point2 - The second point. + * + * @return {number} The angle in radians. + */ +var BetweenPointsY = function (point1, point2) +{ + return Math.atan2(point2.x - point1.x, point2.y - point1.y); +}; + +module.exports = BetweenPointsY; + + +/***/ }), + +/***/ 9678: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Find the angle of a segment from (x1, y1) -> (x2, y2). + * + * The difference between this method and {@link Phaser.Math.Angle.Between} is that this assumes the y coordinate + * travels down the screen. + * + * @function Phaser.Math.Angle.BetweenY + * @since 3.0.0 + * + * @param {number} x1 - The x coordinate of the first point. + * @param {number} y1 - The y coordinate of the first point. + * @param {number} x2 - The x coordinate of the second point. + * @param {number} y2 - The y coordinate of the second point. + * + * @return {number} The angle in radians. + */ +var BetweenY = function (x1, y1, x2, y2) +{ + return Math.atan2(x2 - x1, y2 - y1); +}; + +module.exports = BetweenY; + + +/***/ }), + +/***/ 76861: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(83392); + +/** + * Takes an angle in Phasers default clockwise format and converts it so that + * 0 is North, 90 is West, 180 is South and 270 is East, + * therefore running counter-clockwise instead of clockwise. + * + * You can pass in the angle from a Game Object using: + * + * ```javascript + * var converted = CounterClockwise(gameobject.rotation); + * ``` + * + * All values for this function are in radians. + * + * @function Phaser.Math.Angle.CounterClockwise + * @since 3.16.0 + * + * @param {number} angle - The angle to convert, in radians. + * + * @return {number} The converted angle, in radians. + */ +var CounterClockwise = function (angle) +{ + if (angle > Math.PI) + { + angle -= CONST.PI2; + } + + return Math.abs((((angle + CONST.TAU) % CONST.PI2) - CONST.PI2) % CONST.PI2); +}; + +module.exports = CounterClockwise; + + +/***/ }), + +/***/ 37570: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Normalize an angle to the [0, 2pi] range. + * + * @function Phaser.Math.Angle.Normalize + * @since 3.0.0 + * + * @param {number} angle - The angle to normalize, in radians. + * + * @return {number} The normalized angle, in radians. + */ +var Normalize = function (angle) +{ + angle = angle % (2 * Math.PI); + + if (angle >= 0) + { + return angle; + } + else + { + return angle + 2 * Math.PI; + } +}; + +module.exports = Normalize; + + +/***/ }), + +/***/ 87597: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @author @samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var FloatBetween = __webpack_require__(61616); + +/** + * Returns a random angle in the range [-pi, pi]. + * + * @function Phaser.Math.Angle.Random + * @since 3.23.0 + * + * @return {number} The angle, in radians. + */ +var Random = function () +{ + return FloatBetween(-Math.PI, Math.PI); +}; + +module.exports = Random; + + +/***/ }), + +/***/ 74493: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @author @samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var FloatBetween = __webpack_require__(61616); + +/** + * Returns a random angle in the range [-180, 180]. + * + * @function Phaser.Math.Angle.RandomDegrees + * @since 3.23.0 + * + * @return {number} The angle, in degrees. + */ +var RandomDegrees = function () +{ + return FloatBetween(-180, 180); +}; + +module.exports = RandomDegrees; + + +/***/ }), + +/***/ 19049: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Normalize = __webpack_require__(37570); + +/** + * Reverse the given angle. + * + * @function Phaser.Math.Angle.Reverse + * @since 3.0.0 + * + * @param {number} angle - The angle to reverse, in radians. + * + * @return {number} The reversed angle, in radians. + */ +var Reverse = function (angle) +{ + return Normalize(angle + Math.PI); +}; + +module.exports = Reverse; + + +/***/ }), + +/***/ 90612: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var MATH_CONST = __webpack_require__(83392); + +/** + * Rotates `currentAngle` towards `targetAngle`, taking the shortest rotation distance. The `lerp` argument is the amount to rotate by in this call. + * + * @function Phaser.Math.Angle.RotateTo + * @since 3.0.0 + * + * @param {number} currentAngle - The current angle, in radians. + * @param {number} targetAngle - The target angle to rotate to, in radians. + * @param {number} [lerp=0.05] - The lerp value to add to the current angle. + * + * @return {number} The adjusted angle. + */ +var RotateTo = function (currentAngle, targetAngle, lerp) +{ + if (lerp === undefined) { lerp = 0.05; } + + if (currentAngle === targetAngle) + { + return currentAngle; + } + + if (Math.abs(targetAngle - currentAngle) <= lerp || Math.abs(targetAngle - currentAngle) >= (MATH_CONST.PI2 - lerp)) + { + currentAngle = targetAngle; + } + else + { + if (Math.abs(targetAngle - currentAngle) > Math.PI) + { + if (targetAngle < currentAngle) + { + targetAngle += MATH_CONST.PI2; + } + else + { + targetAngle -= MATH_CONST.PI2; + } + } + + if (targetAngle > currentAngle) + { + currentAngle += lerp; + } + else if (targetAngle < currentAngle) + { + currentAngle -= lerp; + } + } + + return currentAngle; +}; + +module.exports = RotateTo; + + +/***/ }), + +/***/ 93954: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Gets the shortest angle between `angle1` and `angle2`. + * + * Both angles must be in the range -180 to 180, which is the same clamped + * range that `sprite.angle` uses, so you can pass in two sprite angles to + * this method and get the shortest angle back between the two of them. + * + * The angle returned will be in the same range. If the returned angle is + * greater than 0 then it's a counter-clockwise rotation, if < 0 then it's + * a clockwise rotation. + * + * @function Phaser.Math.Angle.ShortestBetween + * @since 3.0.0 + * + * @param {number} angle1 - The first angle in the range -180 to 180. + * @param {number} angle2 - The second angle in the range -180 to 180. + * + * @return {number} The shortest angle, in degrees. If greater than zero it's a counter-clockwise rotation. + */ +var ShortestBetween = function (angle1, angle2) +{ + var difference = angle2 - angle1; + + if (difference === 0) + { + return 0; + } + + var times = Math.floor((difference - (-180)) / 360); + + return difference - (times * 360); + +}; + +module.exports = ShortestBetween; + + +/***/ }), + +/***/ 35786: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var MathWrap = __webpack_require__(1071); + +/** + * Wrap an angle. + * + * Wraps the angle to a value in the range of -PI to PI. + * + * @function Phaser.Math.Angle.Wrap + * @since 3.0.0 + * + * @param {number} angle - The angle to wrap, in radians. + * + * @return {number} The wrapped angle, in radians. + */ +var Wrap = function (angle) +{ + return MathWrap(angle, -Math.PI, Math.PI); +}; + +module.exports = Wrap; + + +/***/ }), + +/***/ 62138: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Wrap = __webpack_require__(1071); + +/** + * Wrap an angle in degrees. + * + * Wraps the angle to a value in the range of -180 to 180. + * + * @function Phaser.Math.Angle.WrapDegrees + * @since 3.0.0 + * + * @param {number} angle - The angle to wrap, in degrees. + * + * @return {number} The wrapped angle, in degrees. + */ +var WrapDegrees = function (angle) +{ + return Wrap(angle, -180, 180); +}; + +module.exports = WrapDegrees; + + +/***/ }), + +/***/ 22153: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Angle + */ + +module.exports = { + + Between: __webpack_require__(90447), + BetweenPoints: __webpack_require__(94240), + BetweenPointsY: __webpack_require__(84066), + BetweenY: __webpack_require__(9678), + CounterClockwise: __webpack_require__(76861), + Normalize: __webpack_require__(37570), + Random: __webpack_require__(87597), + RandomDegrees: __webpack_require__(74493), + Reverse: __webpack_require__(19049), + RotateTo: __webpack_require__(90612), + ShortestBetween: __webpack_require__(93954), + Wrap: __webpack_require__(35786), + WrapDegrees: __webpack_require__(62138) + +}; + + +/***/ }), + +/***/ 83392: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var MATH_CONST = { + + /** + * The value of PI * 2. + * + * @name Phaser.Math.PI2 + * @type {number} + * @since 3.0.0 + */ + PI2: Math.PI * 2, + + /** + * The value of PI * 0.5. + * + * Yes, we understand that this should actually be PI * 2, but + * it has been like this for so long we can't change it now. + * If you need PI * 2, use the PI2 constant instead. + * + * @name Phaser.Math.TAU + * @type {number} + * @since 3.0.0 + */ + TAU: Math.PI * 0.5, + + /** + * An epsilon value (1.0e-6) + * + * @name Phaser.Math.EPSILON + * @type {number} + * @since 3.0.0 + */ + EPSILON: 1.0e-6, + + /** + * For converting degrees to radians (PI / 180) + * + * @name Phaser.Math.DEG_TO_RAD + * @type {number} + * @since 3.0.0 + */ + DEG_TO_RAD: Math.PI / 180, + + /** + * For converting radians to degrees (180 / PI) + * + * @name Phaser.Math.RAD_TO_DEG + * @type {number} + * @since 3.0.0 + */ + RAD_TO_DEG: 180 / Math.PI, + + /** + * An instance of the Random Number Generator. + * This is not set until the Game boots. + * + * @name Phaser.Math.RND + * @type {Phaser.Math.RandomDataGenerator} + * @since 3.0.0 + */ + RND: null, + + /** + * The minimum safe integer this browser supports. + * We use a const for backward compatibility with Internet Explorer. + * + * @name Phaser.Math.MIN_SAFE_INTEGER + * @type {number} + * @since 3.21.0 + */ + MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER || -9007199254740991, + + /** + * The maximum safe integer this browser supports. + * We use a const for backward compatibility with Internet Explorer. + * + * @name Phaser.Math.MAX_SAFE_INTEGER + * @type {number} + * @since 3.21.0 + */ + MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER || 9007199254740991 + +}; + +module.exports = MATH_CONST; + + +/***/ }), + +/***/ 53996: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the distance between two sets of coordinates (points). + * + * @function Phaser.Math.Distance.Between + * @since 3.0.0 + * + * @param {number} x1 - The x coordinate of the first point. + * @param {number} y1 - The y coordinate of the first point. + * @param {number} x2 - The x coordinate of the second point. + * @param {number} y2 - The y coordinate of the second point. + * + * @return {number} The distance between each point. + */ +var DistanceBetween = function (x1, y1, x2, y2) +{ + var dx = x1 - x2; + var dy = y1 - y2; + + return Math.sqrt(dx * dx + dy * dy); +}; + +module.exports = DistanceBetween; + + +/***/ }), + +/***/ 92951: +/***/ ((module) => { + +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the distance between two points. + * + * @function Phaser.Math.Distance.BetweenPoints + * @since 3.22.0 + * + * @param {Phaser.Types.Math.Vector2Like} a - The first point. + * @param {Phaser.Types.Math.Vector2Like} b - The second point. + * + * @return {number} The distance between the points. + */ +var DistanceBetweenPoints = function (a, b) +{ + var dx = a.x - b.x; + var dy = a.y - b.y; + + return Math.sqrt(dx * dx + dy * dy); +}; + +module.exports = DistanceBetweenPoints; + + +/***/ }), + +/***/ 12161: +/***/ ((module) => { + +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the squared distance between two points. + * + * @function Phaser.Math.Distance.BetweenPointsSquared + * @since 3.22.0 + * + * @param {Phaser.Types.Math.Vector2Like} a - The first point. + * @param {Phaser.Types.Math.Vector2Like} b - The second point. + * + * @return {number} The squared distance between the points. + */ +var DistanceBetweenPointsSquared = function (a, b) +{ + var dx = a.x - b.x; + var dy = a.y - b.y; + + return dx * dx + dy * dy; +}; + +module.exports = DistanceBetweenPointsSquared; + + +/***/ }), + +/***/ 38057: +/***/ ((module) => { + +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the Chebyshev distance between two sets of coordinates (points). + * + * Chebyshev distance (or chessboard distance) is the maximum of the horizontal and vertical distances. + * It's the effective distance when movement can be horizontal, vertical, or diagonal. + * + * @function Phaser.Math.Distance.Chebyshev + * @since 3.22.0 + * + * @param {number} x1 - The x coordinate of the first point. + * @param {number} y1 - The y coordinate of the first point. + * @param {number} x2 - The x coordinate of the second point. + * @param {number} y2 - The y coordinate of the second point. + * + * @return {number} The distance between each point. + */ +var ChebyshevDistance = function (x1, y1, x2, y2) +{ + return Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)); +}; + +module.exports = ChebyshevDistance; + + +/***/ }), + +/***/ 33297: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the distance between two sets of coordinates (points) to the power of `pow`. + * + * @function Phaser.Math.Distance.Power + * @since 3.0.0 + * + * @param {number} x1 - The x coordinate of the first point. + * @param {number} y1 - The y coordinate of the first point. + * @param {number} x2 - The x coordinate of the second point. + * @param {number} y2 - The y coordinate of the second point. + * @param {number} pow - The exponent. + * + * @return {number} The distance between each point. + */ +var DistancePower = function (x1, y1, x2, y2, pow) +{ + if (pow === undefined) { pow = 2; } + + return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow)); +}; + +module.exports = DistancePower; + + +/***/ }), + +/***/ 90366: +/***/ ((module) => { + +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the snake distance between two sets of coordinates (points). + * + * Snake distance (rectilinear distance, Manhattan distance) is the sum of the horizontal and vertical distances. + * It's the effective distance when movement is allowed only horizontally or vertically (but not both). + * + * @function Phaser.Math.Distance.Snake + * @since 3.22.0 + * + * @param {number} x1 - The x coordinate of the first point. + * @param {number} y1 - The y coordinate of the first point. + * @param {number} x2 - The x coordinate of the second point. + * @param {number} y2 - The y coordinate of the second point. + * + * @return {number} The distance between each point. + */ +var SnakeDistance = function (x1, y1, x2, y2) +{ + return Math.abs(x1 - x2) + Math.abs(y1 - y2); +}; + +module.exports = SnakeDistance; + + +/***/ }), + +/***/ 35032: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the distance between two sets of coordinates (points), squared. + * + * @function Phaser.Math.Distance.Squared + * @since 3.0.0 + * + * @param {number} x1 - The x coordinate of the first point. + * @param {number} y1 - The y coordinate of the first point. + * @param {number} x2 - The x coordinate of the second point. + * @param {number} y2 - The y coordinate of the second point. + * + * @return {number} The distance between each point, squared. + */ +var DistanceSquared = function (x1, y1, x2, y2) +{ + var dx = x1 - x2; + var dy = y1 - y2; + + return dx * dx + dy * dy; +}; + +module.exports = DistanceSquared; + + +/***/ }), + +/***/ 10130: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Distance + */ + +module.exports = { + + Between: __webpack_require__(53996), + BetweenPoints: __webpack_require__(92951), + BetweenPointsSquared: __webpack_require__(12161), + Chebyshev: __webpack_require__(38057), + Power: __webpack_require__(33297), + Snake: __webpack_require__(90366), + Squared: __webpack_require__(35032) + +}; + + +/***/ }), + +/***/ 35060: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Back = __webpack_require__(25265); +var Bounce = __webpack_require__(57428); +var Circular = __webpack_require__(73214); +var Cubic = __webpack_require__(71778); +var Elastic = __webpack_require__(36468); +var Expo = __webpack_require__(88258); +var Linear = __webpack_require__(52910); +var Quadratic = __webpack_require__(67799); +var Quartic = __webpack_require__(74083); +var Quintic = __webpack_require__(92284); +var Sine = __webpack_require__(28035); +var Stepped = __webpack_require__(8754); + +// EaseMap +module.exports = { + + Power0: Linear, + Power1: Quadratic.Out, + Power2: Cubic.Out, + Power3: Quartic.Out, + Power4: Quintic.Out, + + Linear: Linear, + Quad: Quadratic.Out, + Cubic: Cubic.Out, + Quart: Quartic.Out, + Quint: Quintic.Out, + Sine: Sine.Out, + Expo: Expo.Out, + Circ: Circular.Out, + Elastic: Elastic.Out, + Back: Back.Out, + Bounce: Bounce.Out, + Stepped: Stepped, + + 'Quad.easeIn': Quadratic.In, + 'Cubic.easeIn': Cubic.In, + 'Quart.easeIn': Quartic.In, + 'Quint.easeIn': Quintic.In, + 'Sine.easeIn': Sine.In, + 'Expo.easeIn': Expo.In, + 'Circ.easeIn': Circular.In, + 'Elastic.easeIn': Elastic.In, + 'Back.easeIn': Back.In, + 'Bounce.easeIn': Bounce.In, + + 'Quad.easeOut': Quadratic.Out, + 'Cubic.easeOut': Cubic.Out, + 'Quart.easeOut': Quartic.Out, + 'Quint.easeOut': Quintic.Out, + 'Sine.easeOut': Sine.Out, + 'Expo.easeOut': Expo.Out, + 'Circ.easeOut': Circular.Out, + 'Elastic.easeOut': Elastic.Out, + 'Back.easeOut': Back.Out, + 'Bounce.easeOut': Bounce.Out, + + 'Quad.easeInOut': Quadratic.InOut, + 'Cubic.easeInOut': Cubic.InOut, + 'Quart.easeInOut': Quartic.InOut, + 'Quint.easeInOut': Quintic.InOut, + 'Sine.easeInOut': Sine.InOut, + 'Expo.easeInOut': Expo.InOut, + 'Circ.easeInOut': Circular.InOut, + 'Elastic.easeInOut': Elastic.InOut, + 'Back.easeInOut': Back.InOut, + 'Bounce.easeInOut': Bounce.InOut + +}; + + +/***/ }), + +/***/ 25860: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Back ease-in. + * + * @function Phaser.Math.Easing.Back.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * @param {number} [overshoot=1.70158] - The overshoot amount. + * + * @return {number} The tweened value. + */ +var In = function (v, overshoot) +{ + if (overshoot === undefined) { overshoot = 1.70158; } + + return v * v * ((overshoot + 1) * v - overshoot); +}; + +module.exports = In; + + +/***/ }), + +/***/ 45264: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Back ease-in/out. + * + * @function Phaser.Math.Easing.Back.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * @param {number} [overshoot=1.70158] - The overshoot amount. + * + * @return {number} The tweened value. + */ +var InOut = function (v, overshoot) +{ + if (overshoot === undefined) { overshoot = 1.70158; } + + var s = overshoot * 1.525; + + if ((v *= 2) < 1) + { + return 0.5 * (v * v * ((s + 1) * v - s)); + } + else + { + return 0.5 * ((v -= 2) * v * ((s + 1) * v + s) + 2); + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 36699: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Back ease-out. + * + * @function Phaser.Math.Easing.Back.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * @param {number} [overshoot=1.70158] - The overshoot amount. + * + * @return {number} The tweened value. + */ +var Out = function (v, overshoot) +{ + if (overshoot === undefined) { overshoot = 1.70158; } + + return --v * v * ((overshoot + 1) * v + overshoot) + 1; +}; + +module.exports = Out; + + +/***/ }), + +/***/ 25265: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Back + */ + +module.exports = { + + In: __webpack_require__(25860), + Out: __webpack_require__(36699), + InOut: __webpack_require__(45264) + +}; + + +/***/ }), + +/***/ 62191: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Bounce ease-in. + * + * @function Phaser.Math.Easing.Bounce.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var In = function (v) +{ + v = 1 - v; + + if (v < 1 / 2.75) + { + return 1 - (7.5625 * v * v); + } + else if (v < 2 / 2.75) + { + return 1 - (7.5625 * (v -= 1.5 / 2.75) * v + 0.75); + } + else if (v < 2.5 / 2.75) + { + return 1 - (7.5625 * (v -= 2.25 / 2.75) * v + 0.9375); + } + else + { + return 1 - (7.5625 * (v -= 2.625 / 2.75) * v + 0.984375); + } +}; + +module.exports = In; + + +/***/ }), + +/***/ 24799: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Bounce ease-in/out. + * + * @function Phaser.Math.Easing.Bounce.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var InOut = function (v) +{ + var reverse = false; + + if (v < 0.5) + { + v = 1 - (v * 2); + reverse = true; + } + else + { + v = (v * 2) - 1; + } + + if (v < 1 / 2.75) + { + v = 7.5625 * v * v; + } + else if (v < 2 / 2.75) + { + v = 7.5625 * (v -= 1.5 / 2.75) * v + 0.75; + } + else if (v < 2.5 / 2.75) + { + v = 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375; + } + else + { + v = 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375; + } + + if (reverse) + { + return (1 - v) * 0.5; + } + else + { + return v * 0.5 + 0.5; + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 60819: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Bounce ease-out. + * + * @function Phaser.Math.Easing.Bounce.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var Out = function (v) +{ + if (v < 1 / 2.75) + { + return 7.5625 * v * v; + } + else if (v < 2 / 2.75) + { + return 7.5625 * (v -= 1.5 / 2.75) * v + 0.75; + } + else if (v < 2.5 / 2.75) + { + return 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375; + } + else + { + return 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375; + } +}; + +module.exports = Out; + + +/***/ }), + +/***/ 57428: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Bounce + */ + +module.exports = { + + In: __webpack_require__(62191), + Out: __webpack_require__(60819), + InOut: __webpack_require__(24799) + +}; + + +/***/ }), + +/***/ 86855: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Circular ease-in. + * + * @function Phaser.Math.Easing.Circular.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var In = function (v) +{ + return 1 - Math.sqrt(1 - v * v); +}; + +module.exports = In; + + +/***/ }), + +/***/ 7280: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Circular ease-in/out. + * + * @function Phaser.Math.Easing.Circular.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var InOut = function (v) +{ + if ((v *= 2) < 1) + { + return -0.5 * (Math.sqrt(1 - v * v) - 1); + } + else + { + return 0.5 * (Math.sqrt(1 - (v -= 2) * v) + 1); + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 18058: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Circular ease-out. + * + * @function Phaser.Math.Easing.Circular.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var Out = function (v) +{ + return Math.sqrt(1 - (--v * v)); +}; + +module.exports = Out; + + +/***/ }), + +/***/ 73214: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Circular + */ + +module.exports = { + + In: __webpack_require__(86855), + Out: __webpack_require__(18058), + InOut: __webpack_require__(7280) + +}; + + +/***/ }), + +/***/ 91532: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Cubic ease-in. + * + * @function Phaser.Math.Easing.Cubic.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var In = function (v) +{ + return v * v * v; +}; + +module.exports = In; + + +/***/ }), + +/***/ 63180: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Cubic ease-in/out. + * + * @function Phaser.Math.Easing.Cubic.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var InOut = function (v) +{ + if ((v *= 2) < 1) + { + return 0.5 * v * v * v; + } + else + { + return 0.5 * ((v -= 2) * v * v + 2); + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 16518: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Cubic ease-out. + * + * @function Phaser.Math.Easing.Cubic.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var Out = function (v) +{ + return --v * v * v + 1; +}; + +module.exports = Out; + + +/***/ }), + +/***/ 71778: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Cubic + */ + +module.exports = { + + In: __webpack_require__(91532), + Out: __webpack_require__(16518), + InOut: __webpack_require__(63180) + +}; + + +/***/ }), + +/***/ 24729: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Elastic ease-in. + * + * @function Phaser.Math.Easing.Elastic.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * @param {number} [amplitude=0.1] - The amplitude of the elastic ease. + * @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles. + * + * @return {number} The tweened value. + */ +var In = function (v, amplitude, period) +{ + if (amplitude === undefined) { amplitude = 0.1; } + if (period === undefined) { period = 0.1; } + + if (v === 0) + { + return 0; + } + else if (v === 1) + { + return 1; + } + else + { + var s = period / 4; + + if (amplitude < 1) + { + amplitude = 1; + } + else + { + s = period * Math.asin(1 / amplitude) / (2 * Math.PI); + } + + return -(amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period)); + } +}; + +module.exports = In; + + +/***/ }), + +/***/ 50325: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Elastic ease-in/out. + * + * @function Phaser.Math.Easing.Elastic.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * @param {number} [amplitude=0.1] - The amplitude of the elastic ease. + * @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles. + * + * @return {number} The tweened value. + */ +var InOut = function (v, amplitude, period) +{ + if (amplitude === undefined) { amplitude = 0.1; } + if (period === undefined) { period = 0.1; } + + if (v === 0) + { + return 0; + } + else if (v === 1) + { + return 1; + } + else + { + var s = period / 4; + + if (amplitude < 1) + { + amplitude = 1; + } + else + { + s = period * Math.asin(1 / amplitude) / (2 * Math.PI); + } + + if ((v *= 2) < 1) + { + return -0.5 * (amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period)); + } + else + { + return amplitude * Math.pow(2, -10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period) * 0.5 + 1; + } + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 84074: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Elastic ease-out. + * + * @function Phaser.Math.Easing.Elastic.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * @param {number} [amplitude=0.1] - The amplitude of the elastic ease. + * @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles. + * + * @return {number} The tweened value. + */ +var Out = function (v, amplitude, period) +{ + if (amplitude === undefined) { amplitude = 0.1; } + if (period === undefined) { period = 0.1; } + + if (v === 0) + { + return 0; + } + else if (v === 1) + { + return 1; + } + else + { + var s = period / 4; + + if (amplitude < 1) + { + amplitude = 1; + } + else + { + s = period * Math.asin(1 / amplitude) / (2 * Math.PI); + } + + return (amplitude * Math.pow(2, -10 * v) * Math.sin((v - s) * (2 * Math.PI) / period) + 1); + } +}; + +module.exports = Out; + + +/***/ }), + +/***/ 36468: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Elastic + */ + +module.exports = { + + In: __webpack_require__(24729), + Out: __webpack_require__(84074), + InOut: __webpack_require__(50325) + +}; + + +/***/ }), + +/***/ 95638: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Exponential ease-in. + * + * @function Phaser.Math.Easing.Expo.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var In = function (v) +{ + return Math.pow(2, 10 * (v - 1)) - 0.001; +}; + +module.exports = In; + + +/***/ }), + +/***/ 10357: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Exponential ease-in/out. + * + * @function Phaser.Math.Easing.Expo.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var InOut = function (v) +{ + if ((v *= 2) < 1) + { + return 0.5 * Math.pow(2, 10 * (v - 1)); + } + else + { + return 0.5 * (2 - Math.pow(2, -10 * (v - 1))); + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 14894: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Exponential ease-out. + * + * @function Phaser.Math.Easing.Expo.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var Out = function (v) +{ + return 1 - Math.pow(2, -10 * v); +}; + +module.exports = Out; + + +/***/ }), + +/***/ 88258: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Expo + */ + +module.exports = { + + In: __webpack_require__(95638), + Out: __webpack_require__(14894), + InOut: __webpack_require__(10357) + +}; + + +/***/ }), + +/***/ 33063: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing + */ + +module.exports = { + + Back: __webpack_require__(25265), + Bounce: __webpack_require__(57428), + Circular: __webpack_require__(73214), + Cubic: __webpack_require__(71778), + Elastic: __webpack_require__(36468), + Expo: __webpack_require__(88258), + Linear: __webpack_require__(52910), + Quadratic: __webpack_require__(67799), + Quartic: __webpack_require__(74083), + Quintic: __webpack_require__(92284), + Sine: __webpack_require__(28035), + Stepped: __webpack_require__(8754) + +}; + + +/***/ }), + +/***/ 43927: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Linear easing (no variation). + * + * @function Phaser.Math.Easing.Linear + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var Linear = function (v) +{ + return v; +}; + +module.exports = Linear; + + +/***/ }), + +/***/ 52910: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +module.exports = __webpack_require__(43927); + + +/***/ }), + +/***/ 77471: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Quadratic ease-in. + * + * @function Phaser.Math.Easing.Quadratic.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var In = function (v) +{ + return v * v; +}; + +module.exports = In; + + +/***/ }), + +/***/ 83863: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Quadratic ease-in/out. + * + * @function Phaser.Math.Easing.Quadratic.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var InOut = function (v) +{ + if ((v *= 2) < 1) + { + return 0.5 * v * v; + } + else + { + return -0.5 * (--v * (v - 2) - 1); + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 44383: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Quadratic ease-out. + * + * @function Phaser.Math.Easing.Quadratic.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var Out = function (v) +{ + return v * (2 - v); +}; + +module.exports = Out; + + +/***/ }), + +/***/ 67799: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Quadratic + */ + +module.exports = { + + In: __webpack_require__(77471), + Out: __webpack_require__(44383), + InOut: __webpack_require__(83863) + +}; + + +/***/ }), + +/***/ 48311: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Quartic ease-in. + * + * @function Phaser.Math.Easing.Quartic.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var In = function (v) +{ + return v * v * v * v; +}; + +module.exports = In; + + +/***/ }), + +/***/ 55248: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Quartic ease-in/out. + * + * @function Phaser.Math.Easing.Quartic.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var InOut = function (v) +{ + if ((v *= 2) < 1) + { + return 0.5 * v * v * v * v; + } + else + { + return -0.5 * ((v -= 2) * v * v * v - 2); + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 23135: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Quartic ease-out. + * + * @function Phaser.Math.Easing.Quartic.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var Out = function (v) +{ + return 1 - (--v * v * v * v); +}; + +module.exports = Out; + + +/***/ }), + +/***/ 74083: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Quartic + */ + +module.exports = { + + In: __webpack_require__(48311), + Out: __webpack_require__(23135), + InOut: __webpack_require__(55248) + +}; + + +/***/ }), + +/***/ 7313: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Quintic ease-in. + * + * @function Phaser.Math.Easing.Quintic.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var In = function (v) +{ + return v * v * v * v * v; +}; + +module.exports = In; + + +/***/ }), + +/***/ 98759: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Quintic ease-in/out. + * + * @function Phaser.Math.Easing.Quintic.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var InOut = function (v) +{ + if ((v *= 2) < 1) + { + return 0.5 * v * v * v * v * v; + } + else + { + return 0.5 * ((v -= 2) * v * v * v * v + 2); + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 26670: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Quintic ease-out. + * + * @function Phaser.Math.Easing.Quintic.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var Out = function (v) +{ + return --v * v * v * v * v + 1; +}; + +module.exports = Out; + + +/***/ }), + +/***/ 92284: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Quintic + */ + +module.exports = { + + In: __webpack_require__(7313), + Out: __webpack_require__(26670), + InOut: __webpack_require__(98759) + +}; + + +/***/ }), + +/***/ 52929: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Sinusoidal ease-in. + * + * @function Phaser.Math.Easing.Sine.In + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var In = function (v) +{ + if (v === 0) + { + return 0; + } + else if (v === 1) + { + return 1; + } + else + { + return 1 - Math.cos(v * Math.PI / 2); + } +}; + +module.exports = In; + + +/***/ }), + +/***/ 66333: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Sinusoidal ease-in/out. + * + * @function Phaser.Math.Easing.Sine.InOut + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var InOut = function (v) +{ + if (v === 0) + { + return 0; + } + else if (v === 1) + { + return 1; + } + else + { + return 0.5 * (1 - Math.cos(Math.PI * v)); + } +}; + +module.exports = InOut; + + +/***/ }), + +/***/ 37255: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Sinusoidal ease-out. + * + * @function Phaser.Math.Easing.Sine.Out + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * + * @return {number} The tweened value. + */ +var Out = function (v) +{ + if (v === 0) + { + return 0; + } + else if (v === 1) + { + return 1; + } + else + { + return Math.sin(v * Math.PI / 2); + } +}; + +module.exports = Out; + + +/***/ }), + +/***/ 28035: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Sine + */ + +module.exports = { + + In: __webpack_require__(52929), + Out: __webpack_require__(37255), + InOut: __webpack_require__(66333) + +}; + + +/***/ }), + +/***/ 52770: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Stepped easing. + * + * @function Phaser.Math.Easing.Stepped + * @since 3.0.0 + * + * @param {number} v - The value to be tweened. + * @param {number} [steps=1] - The number of steps in the ease. + * + * @return {number} The tweened value. + */ +var Stepped = function (v, steps) +{ + if (steps === undefined) { steps = 1; } + + if (v <= 0) + { + return 0; + } + else if (v >= 1) + { + return 1; + } + else + { + return (((steps * v) | 0) + 1) * (1 / steps); + } +}; + +module.exports = Stepped; + + +/***/ }), + +/***/ 8754: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Easing.Stepped + */ + +module.exports = __webpack_require__(52770); + + +/***/ }), + +/***/ 17247: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the fuzzy ceiling of the given value. + * + * @function Phaser.Math.Fuzzy.Ceil + * @since 3.0.0 + * + * @param {number} value - The value. + * @param {number} [epsilon=0.0001] - The epsilon. + * + * @return {number} The fuzzy ceiling of the value. + */ +var Ceil = function (value, epsilon) +{ + if (epsilon === undefined) { epsilon = 0.0001; } + + return Math.ceil(value - epsilon); +}; + +module.exports = Ceil; + + +/***/ }), + +/***/ 88456: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Check whether the given values are fuzzily equal. + * + * Two numbers are fuzzily equal if their difference is less than `epsilon`. + * + * @function Phaser.Math.Fuzzy.Equal + * @since 3.0.0 + * + * @param {number} a - The first value. + * @param {number} b - The second value. + * @param {number} [epsilon=0.0001] - The epsilon. + * + * @return {boolean} `true` if the values are fuzzily equal, otherwise `false`. + */ +var Equal = function (a, b, epsilon) +{ + if (epsilon === undefined) { epsilon = 0.0001; } + + return Math.abs(a - b) < epsilon; +}; + +module.exports = Equal; + + +/***/ }), + +/***/ 61824: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Calculate the fuzzy floor of the given value. + * + * @function Phaser.Math.Fuzzy.Floor + * @since 3.0.0 + * + * @param {number} value - The value. + * @param {number} [epsilon=0.0001] - The epsilon. + * + * @return {number} The floor of the value. + */ +var Floor = function (value, epsilon) +{ + if (epsilon === undefined) { epsilon = 0.0001; } + + return Math.floor(value + epsilon); +}; + +module.exports = Floor; + + +/***/ }), + +/***/ 41935: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Check whether `a` is fuzzily greater than `b`. + * + * `a` is fuzzily greater than `b` if it is more than `b - epsilon`. + * + * @function Phaser.Math.Fuzzy.GreaterThan + * @since 3.0.0 + * + * @param {number} a - The first value. + * @param {number} b - The second value. + * @param {number} [epsilon=0.0001] - The epsilon. + * + * @return {boolean} `true` if `a` is fuzzily greater than than `b`, otherwise `false`. + */ +var GreaterThan = function (a, b, epsilon) +{ + if (epsilon === undefined) { epsilon = 0.0001; } + + return a > b - epsilon; +}; + +module.exports = GreaterThan; + + +/***/ }), + +/***/ 54726: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Check whether `a` is fuzzily less than `b`. + * + * `a` is fuzzily less than `b` if it is less than `b + epsilon`. + * + * @function Phaser.Math.Fuzzy.LessThan + * @since 3.0.0 + * + * @param {number} a - The first value. + * @param {number} b - The second value. + * @param {number} [epsilon=0.0001] - The epsilon. + * + * @return {boolean} `true` if `a` is fuzzily less than `b`, otherwise `false`. + */ +var LessThan = function (a, b, epsilon) +{ + if (epsilon === undefined) { epsilon = 0.0001; } + + return a < b + epsilon; +}; + +module.exports = LessThan; + + +/***/ }), + +/***/ 52778: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Fuzzy + */ + +module.exports = { + + Ceil: __webpack_require__(17247), + Equal: __webpack_require__(88456), + Floor: __webpack_require__(61824), + GreaterThan: __webpack_require__(41935), + LessThan: __webpack_require__(54726) + +}; + + +/***/ }), + +/***/ 5923: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(83392); +var Extend = __webpack_require__(98611); + +/** + * @namespace Phaser.Math + */ + +var PhaserMath = { + + // Collections of functions + Angle: __webpack_require__(22153), + Distance: __webpack_require__(10130), + Easing: __webpack_require__(33063), + Fuzzy: __webpack_require__(52778), + Interpolation: __webpack_require__(48528), + Pow2: __webpack_require__(73773), + Snap: __webpack_require__(23679), + + // Expose the RNG Class + RandomDataGenerator: __webpack_require__(81429), + + // Single functions + Average: __webpack_require__(26042), + Bernstein: __webpack_require__(22824), + Between: __webpack_require__(17489), + CatmullRom: __webpack_require__(14976), + CeilTo: __webpack_require__(89129), + Clamp: __webpack_require__(82897), + DegToRad: __webpack_require__(75606), + Difference: __webpack_require__(767), + Euler: __webpack_require__(9849), + Factorial: __webpack_require__(8034), + FloatBetween: __webpack_require__(61616), + FloorTo: __webpack_require__(60679), + FromPercent: __webpack_require__(91806), + GetSpeed: __webpack_require__(79366), + IsEven: __webpack_require__(43776), + IsEvenStrict: __webpack_require__(58442), + Linear: __webpack_require__(42798), + LinearXY: __webpack_require__(61072), + MaxAdd: __webpack_require__(69635), + Median: __webpack_require__(37394), + MinSub: __webpack_require__(17259), + Percent: __webpack_require__(61820), + RadToDeg: __webpack_require__(23701), + RandomXY: __webpack_require__(16906), + RandomXYZ: __webpack_require__(52417), + RandomXYZW: __webpack_require__(17915), + Rotate: __webpack_require__(52257), + RotateAround: __webpack_require__(2386), + RotateAroundDistance: __webpack_require__(72395), + RotateTo: __webpack_require__(41061), + RoundAwayFromZero: __webpack_require__(67233), + RoundTo: __webpack_require__(64333), + SinCosTableGenerator: __webpack_require__(59533), + SmootherStep: __webpack_require__(87736), + SmoothStep: __webpack_require__(5514), + ToXY: __webpack_require__(55805), + TransformXY: __webpack_require__(64462), + Within: __webpack_require__(9557), + Wrap: __webpack_require__(1071), + + // Vector classes + Vector2: __webpack_require__(93736), + Vector3: __webpack_require__(70015), + Vector4: __webpack_require__(51729), + Matrix3: __webpack_require__(5341), + Matrix4: __webpack_require__(16650), + Quaternion: __webpack_require__(75003), + RotateVec3: __webpack_require__(93709) + +}; + +// Merge in the consts + +PhaserMath = Extend(false, PhaserMath, CONST); + +// Export it + +module.exports = PhaserMath; + + +/***/ }), + +/***/ 63210: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Bernstein = __webpack_require__(22824); + +/** + * A bezier interpolation method. + * + * @function Phaser.Math.Interpolation.Bezier + * @since 3.0.0 + * + * @param {number[]} v - The input array of values to interpolate between. + * @param {number} k - The percentage of interpolation, between 0 and 1. + * + * @return {number} The interpolated value. + */ +var BezierInterpolation = function (v, k) +{ + var b = 0; + var n = v.length - 1; + + for (var i = 0; i <= n; i++) + { + b += Math.pow(1 - k, n - i) * Math.pow(k, i) * v[i] * Bernstein(n, i); + } + + return b; +}; + +module.exports = BezierInterpolation; + + +/***/ }), + +/***/ 88332: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CatmullRom = __webpack_require__(14976); + +/** + * A Catmull-Rom interpolation method. + * + * @function Phaser.Math.Interpolation.CatmullRom + * @since 3.0.0 + * + * @param {number[]} v - The input array of values to interpolate between. + * @param {number} k - The percentage of interpolation, between 0 and 1. + * + * @return {number} The interpolated value. + */ +var CatmullRomInterpolation = function (v, k) +{ + var m = v.length - 1; + var f = m * k; + var i = Math.floor(f); + + if (v[0] === v[m]) + { + if (k < 0) + { + i = Math.floor(f = m * (1 + k)); + } + + return CatmullRom(f - i, v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m]); + } + else + { + if (k < 0) + { + return v[0] - (CatmullRom(-f, v[0], v[0], v[1], v[1]) - v[0]); + } + + if (k > 1) + { + return v[m] - (CatmullRom(f - m, v[m], v[m], v[m - 1], v[m - 1]) - v[m]); + } + + return CatmullRom(f - i, v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2]); + } +}; + +module.exports = CatmullRomInterpolation; + + +/***/ }), + +/***/ 34631: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @ignore + */ +function P0 (t, p) +{ + var k = 1 - t; + + return k * k * k * p; +} + +/** + * @ignore + */ +function P1 (t, p) +{ + var k = 1 - t; + + return 3 * k * k * t * p; +} + +/** + * @ignore + */ +function P2 (t, p) +{ + return 3 * (1 - t) * t * t * p; +} + +/** + * @ignore + */ +function P3 (t, p) +{ + return t * t * t * p; +} + +/** + * A cubic bezier interpolation method. + * + * https://medium.com/@adrian_cooney/bezier-interpolation-13b68563313a + * + * @function Phaser.Math.Interpolation.CubicBezier + * @since 3.0.0 + * + * @param {number} t - The percentage of interpolation, between 0 and 1. + * @param {number} p0 - The start point. + * @param {number} p1 - The first control point. + * @param {number} p2 - The second control point. + * @param {number} p3 - The end point. + * + * @return {number} The interpolated value. + */ +var CubicBezierInterpolation = function (t, p0, p1, p2, p3) +{ + return P0(t, p0) + P1(t, p1) + P2(t, p2) + P3(t, p3); +}; + +module.exports = CubicBezierInterpolation; + + +/***/ }), + +/***/ 47614: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Linear = __webpack_require__(42798); + +/** + * A linear interpolation method. + * + * @function Phaser.Math.Interpolation.Linear + * @since 3.0.0 + * @see {@link https://en.wikipedia.org/wiki/Linear_interpolation} + * + * @param {number[]} v - The input array of values to interpolate between. + * @param {!number} k - The percentage of interpolation, between 0 and 1. + * + * @return {!number} The interpolated value. + */ +var LinearInterpolation = function (v, k) +{ + var m = v.length - 1; + var f = m * k; + var i = Math.floor(f); + + if (k < 0) + { + return Linear(v[0], v[1], f); + } + else if (k > 1) + { + return Linear(v[m], v[m - 1], m - f); + } + else + { + return Linear(v[i], v[(i + 1 > m) ? m : i + 1], f - i); + } +}; + +module.exports = LinearInterpolation; + + +/***/ }), + +/***/ 16252: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @ignore + */ +function P0 (t, p) +{ + var k = 1 - t; + + return k * k * p; +} + +/** + * @ignore + */ +function P1 (t, p) +{ + return 2 * (1 - t) * t * p; +} + +/** + * @ignore + */ +function P2 (t, p) +{ + return t * t * p; +} + +// https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js + +/** + * A quadratic bezier interpolation method. + * + * @function Phaser.Math.Interpolation.QuadraticBezier + * @since 3.2.0 + * + * @param {number} t - The percentage of interpolation, between 0 and 1. + * @param {number} p0 - The start point. + * @param {number} p1 - The control point. + * @param {number} p2 - The end point. + * + * @return {number} The interpolated value. + */ +var QuadraticBezierInterpolation = function (t, p0, p1, p2) +{ + return P0(t, p0) + P1(t, p1) + P2(t, p2); +}; + +module.exports = QuadraticBezierInterpolation; + + +/***/ }), + +/***/ 44521: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var SmoothStep = __webpack_require__(5514); + +/** + * A Smooth Step interpolation method. + * + * @function Phaser.Math.Interpolation.SmoothStep + * @since 3.9.0 + * @see {@link https://en.wikipedia.org/wiki/Smoothstep} + * + * @param {number} t - The percentage of interpolation, between 0 and 1. + * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'. + * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'. + * + * @return {number} The interpolated value. + */ +var SmoothStepInterpolation = function (t, min, max) +{ + return min + (max - min) * SmoothStep(t, 0, 1); +}; + +module.exports = SmoothStepInterpolation; + + +/***/ }), + +/***/ 45507: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var SmootherStep = __webpack_require__(87736); + +/** + * A Smoother Step interpolation method. + * + * @function Phaser.Math.Interpolation.SmootherStep + * @since 3.9.0 + * @see {@link https://en.wikipedia.org/wiki/Smoothstep#Variations} + * + * @param {number} t - The percentage of interpolation, between 0 and 1. + * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'. + * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'. + * + * @return {number} The interpolated value. + */ +var SmootherStepInterpolation = function (t, min, max) +{ + return min + (max - min) * SmootherStep(t, 0, 1); +}; + +module.exports = SmootherStepInterpolation; + + +/***/ }), + +/***/ 48528: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Interpolation + */ + +module.exports = { + + Bezier: __webpack_require__(63210), + CatmullRom: __webpack_require__(88332), + CubicBezier: __webpack_require__(34631), + Linear: __webpack_require__(47614), + QuadraticBezier: __webpack_require__(16252), + SmoothStep: __webpack_require__(44521), + SmootherStep: __webpack_require__(45507) + +}; + + +/***/ }), + +/***/ 3504: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Returns the nearest power of 2 to the given `value`. + * + * @function Phaser.Math.Pow2.GetNext + * @since 3.0.0 + * + * @param {number} value - The value. + * + * @return {number} The nearest power of 2 to `value`. + */ +var GetPowerOfTwo = function (value) +{ + var index = Math.log(value) / 0.6931471805599453; + + return (1 << Math.ceil(index)); +}; + +module.exports = GetPowerOfTwo; + + +/***/ }), + +/***/ 28621: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks if the given `width` and `height` are a power of two. + * Useful for checking texture dimensions. + * + * @function Phaser.Math.Pow2.IsSize + * @since 3.0.0 + * + * @param {number} width - The width. + * @param {number} height - The height. + * + * @return {boolean} `true` if `width` and `height` are a power of two, otherwise `false`. + */ +var IsSizePowerOfTwo = function (width, height) +{ + return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0); +}; + +module.exports = IsSizePowerOfTwo; + + +/***/ }), + +/***/ 2018: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Tests the value and returns `true` if it is a power of two. + * + * @function Phaser.Math.Pow2.IsValue + * @since 3.0.0 + * + * @param {number} value - The value to check if it's a power of two. + * + * @return {boolean} Returns `true` if `value` is a power of two, otherwise `false`. + */ +var IsValuePowerOfTwo = function (value) +{ + return (value > 0 && (value & (value - 1)) === 0); +}; + +module.exports = IsValuePowerOfTwo; + + +/***/ }), + +/***/ 73773: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Pow2 + */ + +module.exports = { + + GetNext: __webpack_require__(3504), + IsSize: __webpack_require__(28621), + IsValue: __webpack_require__(2018) + +}; + + +/***/ }), + +/***/ 81429: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); + +/** + * @classdesc + * A seeded Random Data Generator. + * + * Access via `Phaser.Math.RND` which is an instance of this class pre-defined + * by Phaser. Or, create your own instance to use as you require. + * + * The `Math.RND` generator is seeded by the Game Config property value `seed`. + * If no such config property exists, a random number is used. + * + * If you create your own instance of this class you should provide a seed for it. + * If no seed is given it will use a 'random' one based on Date.now. + * + * @class RandomDataGenerator + * @memberof Phaser.Math + * @constructor + * @since 3.0.0 + * + * @param {(string|string[])} [seeds] - The seeds to use for the random number generator. + */ +var RandomDataGenerator = new Class({ + + initialize: + + function RandomDataGenerator (seeds) + { + if (seeds === undefined) { seeds = [ (Date.now() * Math.random()).toString() ]; } + + /** + * Internal var. + * + * @name Phaser.Math.RandomDataGenerator#c + * @type {number} + * @default 1 + * @private + * @since 3.0.0 + */ + this.c = 1; + + /** + * Internal var. + * + * @name Phaser.Math.RandomDataGenerator#s0 + * @type {number} + * @default 0 + * @private + * @since 3.0.0 + */ + this.s0 = 0; + + /** + * Internal var. + * + * @name Phaser.Math.RandomDataGenerator#s1 + * @type {number} + * @default 0 + * @private + * @since 3.0.0 + */ + this.s1 = 0; + + /** + * Internal var. + * + * @name Phaser.Math.RandomDataGenerator#s2 + * @type {number} + * @default 0 + * @private + * @since 3.0.0 + */ + this.s2 = 0; + + /** + * Internal var. + * + * @name Phaser.Math.RandomDataGenerator#n + * @type {number} + * @default 0 + * @private + * @since 3.2.0 + */ + this.n = 0; + + /** + * Signs to choose from. + * + * @name Phaser.Math.RandomDataGenerator#signs + * @type {number[]} + * @since 3.0.0 + */ + this.signs = [ -1, 1 ]; + + if (seeds) + { + this.init(seeds); + } + }, + + /** + * Private random helper. + * + * @method Phaser.Math.RandomDataGenerator#rnd + * @since 3.0.0 + * @private + * + * @return {number} A random number. + */ + rnd: function () + { + var t = 2091639 * this.s0 + this.c * 2.3283064365386963e-10; // 2^-32 + + this.c = t | 0; + this.s0 = this.s1; + this.s1 = this.s2; + this.s2 = t - this.c; + + return this.s2; + }, + + /** + * Internal method that creates a seed hash. + * + * @method Phaser.Math.RandomDataGenerator#hash + * @since 3.0.0 + * @private + * + * @param {string} data - The value to hash. + * + * @return {number} The hashed value. + */ + hash: function (data) + { + var h; + var n = this.n; + + data = data.toString(); + + for (var i = 0; i < data.length; i++) + { + n += data.charCodeAt(i); + h = 0.02519603282416938 * n; + n = h >>> 0; + h -= n; + h *= n; + n = h >>> 0; + h -= n; + n += h * 0x100000000;// 2^32 + } + + this.n = n; + + return (n >>> 0) * 2.3283064365386963e-10;// 2^-32 + }, + + /** + * Initialize the state of the random data generator. + * + * @method Phaser.Math.RandomDataGenerator#init + * @since 3.0.0 + * + * @param {(string|string[])} seeds - The seeds to initialize the random data generator with. + */ + init: function (seeds) + { + if (typeof seeds === 'string') + { + this.state(seeds); + } + else + { + this.sow(seeds); + } + }, + + /** + * Reset the seed of the random data generator. + * + * _Note_: the seed array is only processed up to the first `undefined` (or `null`) value, should such be present. + * + * @method Phaser.Math.RandomDataGenerator#sow + * @since 3.0.0 + * + * @param {string[]} seeds - The array of seeds: the `toString()` of each value is used. + */ + sow: function (seeds) + { + // Always reset to default seed + this.n = 0xefc8249d; + this.s0 = this.hash(' '); + this.s1 = this.hash(' '); + this.s2 = this.hash(' '); + this.c = 1; + + if (!seeds) + { + return; + } + + // Apply any seeds + for (var i = 0; i < seeds.length && (seeds[i] != null); i++) + { + var seed = seeds[i]; + + this.s0 -= this.hash(seed); + this.s0 += ~~(this.s0 < 0); + this.s1 -= this.hash(seed); + this.s1 += ~~(this.s1 < 0); + this.s2 -= this.hash(seed); + this.s2 += ~~(this.s2 < 0); + } + }, + + /** + * Returns a random integer between 0 and 2^32. + * + * @method Phaser.Math.RandomDataGenerator#integer + * @since 3.0.0 + * + * @return {number} A random integer between 0 and 2^32. + */ + integer: function () + { + // 2^32 + return this.rnd() * 0x100000000; + }, + + /** + * Returns a random real number between 0 and 1. + * + * @method Phaser.Math.RandomDataGenerator#frac + * @since 3.0.0 + * + * @return {number} A random real number between 0 and 1. + */ + frac: function () + { + // 2^-53 + return this.rnd() + (this.rnd() * 0x200000 | 0) * 1.1102230246251565e-16; + }, + + /** + * Returns a random real number between 0 and 2^32. + * + * @method Phaser.Math.RandomDataGenerator#real + * @since 3.0.0 + * + * @return {number} A random real number between 0 and 2^32. + */ + real: function () + { + return this.integer() + this.frac(); + }, + + /** + * Returns a random integer between and including min and max. + * + * @method Phaser.Math.RandomDataGenerator#integerInRange + * @since 3.0.0 + * + * @param {number} min - The minimum value in the range. + * @param {number} max - The maximum value in the range. + * + * @return {number} A random number between min and max. + */ + integerInRange: function (min, max) + { + return Math.floor(this.realInRange(0, max - min + 1) + min); + }, + + /** + * Returns a random integer between and including min and max. + * This method is an alias for RandomDataGenerator.integerInRange. + * + * @method Phaser.Math.RandomDataGenerator#between + * @since 3.0.0 + * + * @param {number} min - The minimum value in the range. + * @param {number} max - The maximum value in the range. + * + * @return {number} A random number between min and max. + */ + between: function (min, max) + { + return Math.floor(this.realInRange(0, max - min + 1) + min); + }, + + /** + * Returns a random real number between min and max. + * + * @method Phaser.Math.RandomDataGenerator#realInRange + * @since 3.0.0 + * + * @param {number} min - The minimum value in the range. + * @param {number} max - The maximum value in the range. + * + * @return {number} A random number between min and max. + */ + realInRange: function (min, max) + { + return this.frac() * (max - min) + min; + }, + + /** + * Returns a random real number between -1 and 1. + * + * @method Phaser.Math.RandomDataGenerator#normal + * @since 3.0.0 + * + * @return {number} A random real number between -1 and 1. + */ + normal: function () + { + return 1 - (2 * this.frac()); + }, + + /** + * Returns a valid RFC4122 version4 ID hex string from https://gist.github.com/1308368 + * + * @method Phaser.Math.RandomDataGenerator#uuid + * @since 3.0.0 + * + * @return {string} A valid RFC4122 version4 ID hex string + */ + uuid: function () + { + var a = ''; + var b = ''; + + for (b = a = ''; a++ < 36; b += ~a % 5 | a * 3 & 4 ? (a ^ 15 ? 8 ^ this.frac() * (a ^ 20 ? 16 : 4) : 4).toString(16) : '-') + { + // eslint-disable-next-line no-empty + } + + return b; + }, + + /** + * Returns a random element from within the given array. + * + * @method Phaser.Math.RandomDataGenerator#pick + * @since 3.0.0 + * + * @generic T + * @genericUse {T[]} - [array] + * @genericUse {T} - [$return] + * + * @param {T[]} array - The array to pick a random element from. + * + * @return {T} A random member of the array. + */ + pick: function (array) + { + return array[this.integerInRange(0, array.length - 1)]; + }, + + /** + * Returns a sign to be used with multiplication operator. + * + * @method Phaser.Math.RandomDataGenerator#sign + * @since 3.0.0 + * + * @return {number} -1 or +1. + */ + sign: function () + { + return this.pick(this.signs); + }, + + /** + * Returns a random element from within the given array, favoring the earlier entries. + * + * @method Phaser.Math.RandomDataGenerator#weightedPick + * @since 3.0.0 + * + * @generic T + * @genericUse {T[]} - [array] + * @genericUse {T} - [$return] + * + * @param {T[]} array - The array to pick a random element from. + * + * @return {T} A random member of the array. + */ + weightedPick: function (array) + { + return array[~~(Math.pow(this.frac(), 2) * (array.length - 1) + 0.5)]; + }, + + /** + * Returns a random timestamp between min and max, or between the beginning of 2000 and the end of 2020 if min and max aren't specified. + * + * @method Phaser.Math.RandomDataGenerator#timestamp + * @since 3.0.0 + * + * @param {number} min - The minimum value in the range. + * @param {number} max - The maximum value in the range. + * + * @return {number} A random timestamp between min and max. + */ + timestamp: function (min, max) + { + return this.realInRange(min || 946684800000, max || 1577862000000); + }, + + /** + * Returns a random angle between -180 and 180. + * + * @method Phaser.Math.RandomDataGenerator#angle + * @since 3.0.0 + * + * @return {number} A random number between -180 and 180. + */ + angle: function () + { + return this.integerInRange(-180, 180); + }, + + /** + * Returns a random rotation in radians, between -3.141 and 3.141 + * + * @method Phaser.Math.RandomDataGenerator#rotation + * @since 3.0.0 + * + * @return {number} A random number between -3.141 and 3.141 + */ + rotation: function () + { + return this.realInRange(-3.1415926, 3.1415926); + }, + + /** + * Gets or Sets the state of the generator. This allows you to retain the values + * that the generator is using between games, i.e. in a game save file. + * + * To seed this generator with a previously saved state you can pass it as the + * `seed` value in your game config, or call this method directly after Phaser has booted. + * + * Call this method with no parameters to return the current state. + * + * If providing a state it should match the same format that this method + * returns, which is a string with a header `!rnd` followed by the `c`, + * `s0`, `s1` and `s2` values respectively, each comma-delimited. + * + * @method Phaser.Math.RandomDataGenerator#state + * @since 3.0.0 + * + * @param {string} [state] - Generator state to be set. + * + * @return {string} The current state of the generator. + */ + state: function (state) + { + if (typeof state === 'string' && state.match(/^!rnd/)) + { + state = state.split(','); + + this.c = parseFloat(state[1]); + this.s0 = parseFloat(state[2]); + this.s1 = parseFloat(state[3]); + this.s2 = parseFloat(state[4]); + } + + return [ '!rnd', this.c, this.s0, this.s1, this.s2 ].join(','); + }, + + /** + * Shuffles the given array, using the current seed. + * + * @method Phaser.Math.RandomDataGenerator#shuffle + * @since 3.7.0 + * + * @generic T + * @genericUse {T[]} - [array,$return] + * + * @param {T[]} [array] - The array to be shuffled. + * + * @return {T[]} The shuffled array. + */ + shuffle: function (array) + { + var len = array.length - 1; + + for (var i = len; i > 0; i--) + { + var randomIndex = Math.floor(this.frac() * (i + 1)); + var itemAtIndex = array[randomIndex]; + + array[randomIndex] = array[i]; + array[i] = itemAtIndex; + } + + return array; + } + +}); + +module.exports = RandomDataGenerator; + + +/***/ }), + +/***/ 82127: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Snap a value to nearest grid slice, using ceil. + * + * Example: if you have an interval gap of `5` and a position of `12`... you will snap to `15`. + * As will `14` snap to `15`... but `16` will snap to `20`. + * + * @function Phaser.Math.Snap.Ceil + * @since 3.0.0 + * + * @param {number} value - The value to snap. + * @param {number} gap - The interval gap of the grid. + * @param {number} [start=0] - Optional starting offset for gap. + * @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning. + * + * @return {number} The snapped value. + */ +var SnapCeil = function (value, gap, start, divide) +{ + if (start === undefined) { start = 0; } + + if (gap === 0) + { + return value; + } + + value -= start; + value = gap * Math.ceil(value / gap); + + return (divide) ? (start + value) / gap : start + value; +}; + +module.exports = SnapCeil; + + +/***/ }), + +/***/ 84314: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Snap a value to nearest grid slice, using floor. + * + * Example: if you have an interval gap of `5` and a position of `12`... you will snap to `10`. + * As will `14` snap to `10`... but `16` will snap to `15`. + * + * @function Phaser.Math.Snap.Floor + * @since 3.0.0 + * + * @param {number} value - The value to snap. + * @param {number} gap - The interval gap of the grid. + * @param {number} [start=0] - Optional starting offset for gap. + * @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning. + * + * @return {number} The snapped value. + */ +var SnapFloor = function (value, gap, start, divide) +{ + if (start === undefined) { start = 0; } + + if (gap === 0) + { + return value; + } + + value -= start; + value = gap * Math.floor(value / gap); + + return (divide) ? (start + value) / gap : start + value; +}; + +module.exports = SnapFloor; + + +/***/ }), + +/***/ 88462: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Snap a value to nearest grid slice, using rounding. + * + * Example: if you have an interval gap of `5` and a position of `12`... you will snap to `10` whereas `14` will snap to `15`. + * + * @function Phaser.Math.Snap.To + * @since 3.0.0 + * + * @param {number} value - The value to snap. + * @param {number} gap - The interval gap of the grid. + * @param {number} [start=0] - Optional starting offset for gap. + * @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning. + * + * @return {number} The snapped value. + */ +var SnapTo = function (value, gap, start, divide) +{ + if (start === undefined) { start = 0; } + + if (gap === 0) + { + return value; + } + + value -= start; + value = gap * Math.round(value / gap); + + return (divide) ? (start + value) / gap : start + value; +}; + +module.exports = SnapTo; + + +/***/ }), + +/***/ 23679: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Math.Snap + */ + +module.exports = { + + Ceil: __webpack_require__(82127), + Floor: __webpack_require__(84314), + To: __webpack_require__(88462) + +}; + + +/***/ }), + +/***/ 92491: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +__webpack_require__(75205); + +var CONST = __webpack_require__(86459); +var Extend = __webpack_require__(98611); + +/** + * @namespace Phaser + */ + +var Phaser = { + + Actions: __webpack_require__(83979), + Animations: __webpack_require__(13517), + BlendModes: __webpack_require__(95723), + Cache: __webpack_require__(45820), + Cameras: __webpack_require__(44143), + Core: __webpack_require__(80293), + Class: __webpack_require__(56694), + Create: __webpack_require__(84106), + Curves: __webpack_require__(73962), + Data: __webpack_require__(1999), + Display: __webpack_require__(24816), + DOM: __webpack_require__(3590), + Events: __webpack_require__(95146), + FX: __webpack_require__(96910), + Game: __webpack_require__(15213), + GameObjects: __webpack_require__(48013), + Geom: __webpack_require__(84068), + Input: __webpack_require__(20873), + Loader: __webpack_require__(95695), + Math: __webpack_require__(5923), + Physics: __webpack_require__(53954), + Plugins: __webpack_require__(45615), + Renderer: __webpack_require__(42069), + Scale: __webpack_require__(86754), + ScaleModes: __webpack_require__(27394), + Scene: __webpack_require__(87157), + Scenes: __webpack_require__(20436), + Structs: __webpack_require__(20010), + Textures: __webpack_require__(87499), + Tilemaps: __webpack_require__(52678), + Time: __webpack_require__(97121), + Tweens: __webpack_require__(75193), + Utils: __webpack_require__(22178) + +}; + +// Merge in the optional plugins and WebGL only features + +if (true) +{ + Phaser.Sound = __webpack_require__(56751); +} + +if (false) +{} + +if (false) +{} + +// Merge in the consts + +Phaser = Extend(false, Phaser, CONST); + +/** + * The root types namespace. + * + * @namespace Phaser.Types + * @since 3.17.0 + */ + +// Export it + +module.exports = Phaser; + +__webpack_require__.g.Phaser = Phaser; + +/* + * "Documentation is like pizza: when it is good, it is very, very good; + * and when it is bad, it is better than nothing." + * -- Dick Brandon + */ + + +/***/ }), + +/***/ 62832: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Components = __webpack_require__(7864); +var Image = __webpack_require__(1539); + +/** + * @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.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @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; + + +/***/ }), + +/***/ 66150: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var DegToRad = __webpack_require__(75606); +var DistanceBetween = __webpack_require__(53996); +var DistanceSquared = __webpack_require__(35032); +var Factory = __webpack_require__(99523); +var GetFastValue = __webpack_require__(72632); +var Merge = __webpack_require__(30657); +var OverlapCirc = __webpack_require__(2732); +var OverlapRect = __webpack_require__(15147); +var PluginCache = __webpack_require__(91963); +var SceneEvents = __webpack_require__(7599); +var Vector2 = __webpack_require__(93736); +var World = __webpack_require__(85233); + +/** + * @classdesc + * The Arcade Physics Plugin belongs to a Scene and sets up and manages the Scene's physics simulation. + * It also holds some useful methods for moving and rotating Arcade Physics Bodies. + * + * You can access it from within a Scene using `this.physics`. + * + * 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. + * + * @class ArcadePhysics + * @memberof Phaser.Physics.Arcade + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene that this Plugin belongs to. + */ +var ArcadePhysics = new Class({ + + initialize: + + function ArcadePhysics (scene) + { + /** + * The Scene that this Plugin belongs to. + * + * @name Phaser.Physics.Arcade.ArcadePhysics#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; + + /** + * The Scene's Systems. + * + * @name Phaser.Physics.Arcade.ArcadePhysics#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.systems = scene.sys; + + /** + * A configuration object. Union of the `physics.arcade.*` properties of the GameConfig and SceneConfig objects. + * + * @name Phaser.Physics.Arcade.ArcadePhysics#config + * @type {Phaser.Types.Physics.Arcade.ArcadeWorldConfig} + * @since 3.0.0 + */ + this.config = this.getConfig(); + + /** + * The physics simulation. + * + * @name Phaser.Physics.Arcade.ArcadePhysics#world + * @type {Phaser.Physics.Arcade.World} + * @since 3.0.0 + */ + this.world; + + /** + * An object holding the Arcade Physics factory methods. + * + * @name Phaser.Physics.Arcade.ArcadePhysics#add + * @type {Phaser.Physics.Arcade.Factory} + * @since 3.0.0 + */ + this.add; + + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + scene.sys.events.on(SceneEvents.START, this.start, this); + }, + + /** + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#boot + * @private + * @since 3.5.1 + */ + boot: function () + { + this.world = new World(this.scene, this.config); + this.add = new Factory(this.world); + + this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); + }, + + /** + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#start + * @private + * @since 3.5.0 + */ + start: function () + { + if (!this.world) + { + this.world = new World(this.scene, this.config); + this.add = new Factory(this.world); + } + + var eventEmitter = this.systems.events; + + if (!GetFastValue(this.config, 'customUpdate', false)) + { + eventEmitter.on(SceneEvents.UPDATE, this.world.update, this.world); + } + + eventEmitter.on(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world); + eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); + }, + + /** + * Causes `World.update` to be automatically called each time the Scene + * emits and `UPDATE` event. This is the default setting, so only needs + * calling if you have specifically disabled it. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#enableUpdate + * @since 3.50.0 + */ + enableUpdate: function () + { + this.systems.events.on(SceneEvents.UPDATE, this.world.update, this.world); + }, + + /** + * Causes `World.update` to **not** be automatically called each time the Scene + * emits and `UPDATE` event. + * + * If you wish to run the World update at your own rate, or from your own + * component, then you should call this method to disable the built-in link, + * and then call `World.update(delta, time)` accordingly. + * + * Note that `World.postUpdate` is always automatically called when the Scene + * emits a `POST_UPDATE` event, regardless of this setting. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#disableUpdate + * @since 3.50.0 + */ + disableUpdate: function () + { + this.systems.events.off(SceneEvents.UPDATE, this.world.update, this.world); + }, + + /** + * Creates the physics configuration for the current Scene. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#getConfig + * @since 3.0.0 + * + * @return {Phaser.Types.Physics.Arcade.ArcadeWorldConfig} The physics configuration. + */ + getConfig: function () + { + var gameConfig = this.systems.game.config.physics; + var sceneConfig = this.systems.settings.physics; + + var config = Merge( + GetFastValue(sceneConfig, 'arcade', {}), + GetFastValue(gameConfig, 'arcade', {}) + ); + + return config; + }, + + /** + * Tests if Game Objects overlap. See {@link Phaser.Physics.Arcade.World#overlap} + * + * @method Phaser.Physics.Arcade.ArcadePhysics#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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the objects overlap. + * @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they overlap. If this is set then `collideCallback` 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#overlap + */ + overlap: function (object1, object2, overlapCallback, processCallback, callbackContext) + { + if (overlapCallback === undefined) { overlapCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = overlapCallback; } + + return this.world.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 #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. The `collideCallback` is invoked if a collision occurs and the two colliding + * objects are passed to it. + * + * 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.ArcadePhysics#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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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 {*} [callbackContext] - The context in which to run the callbacks. + * + * @return {boolean} True if any overlapping Game Objects were separated, otherwise false. + * + * @see Phaser.Physics.Arcade.World#collide + */ + collide: function (object1, object2, collideCallback, processCallback, callbackContext) + { + if (collideCallback === undefined) { collideCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = collideCallback; } + + return this.world.collideObjects(object1, object2, collideCallback, processCallback, callbackContext, false); + }, + + /** + * 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.ArcadePhysics#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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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) + { + return this.world.collideTiles(sprite, tiles, collideCallback, processCallback, callbackContext); + }, + + /** + * 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.ArcadePhysics#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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects overlap. + * @param {Phaser.Types.Physics.Arcade.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) + { + return this.world.overlapTiles(sprite, tiles, collideCallback, processCallback, callbackContext); + }, + + /** + * Pauses the simulation. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#pause + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.World} The simulation. + */ + pause: function () + { + return this.world.pause(); + }, + + /** + * Resumes the simulation (if paused). + * + * @method Phaser.Physics.Arcade.ArcadePhysics#resume + * @since 3.0.0 + * + * @return {Phaser.Physics.Arcade.World} The simulation. + */ + resume: function () + { + return this.world.resume(); + }, + + /** + * Sets the acceleration.x/y property on the game object so it will move towards the x/y coordinates at the given rate (in pixels per second squared) + * + * You must give a maximum speed value, beyond which the game object won't go any faster. + * + * Note: The game object does not continuously track the target. If the target changes location during transit the game object will not modify its course. + * Note: The game object doesn't stop moving once it reaches the destination coordinates. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#accelerateTo + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body. + * @param {number} x - The x coordinate to accelerate towards. + * @param {number} y - The y coordinate to accelerate towards. + * @param {number} [speed=60] - The acceleration (change in speed) in pixels per second squared. + * @param {number} [xSpeedMax=500] - The maximum x velocity the game object can reach. + * @param {number} [ySpeedMax=500] - The maximum y velocity the game object can reach. + * + * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. + */ + accelerateTo: function (gameObject, x, y, speed, xSpeedMax, ySpeedMax) + { + if (speed === undefined) { speed = 60; } + + var angle = Math.atan2(y - gameObject.y, x - gameObject.x); + + gameObject.body.acceleration.setToPolar(angle, speed); + + if (xSpeedMax !== undefined && ySpeedMax !== undefined) + { + gameObject.body.maxVelocity.set(xSpeedMax, ySpeedMax); + } + + return angle; + }, + + /** + * Sets the acceleration.x/y property on the game object so it will move towards the x/y coordinates at the given rate (in pixels per second squared) + * + * You must give a maximum speed value, beyond which the game object won't go any faster. + * + * Note: The game object does not continuously track the target. If the target changes location during transit the game object will not modify its course. + * Note: The game object doesn't stop moving once it reaches the destination coordinates. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#accelerateToObject + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body. + * @param {Phaser.GameObjects.GameObject} destination - The Game Object to move towards. Can be any object but must have visible x/y properties. + * @param {number} [speed=60] - The acceleration (change in speed) in pixels per second squared. + * @param {number} [xSpeedMax=500] - The maximum x velocity the game object can reach. + * @param {number} [ySpeedMax=500] - The maximum y velocity the game object can reach. + * + * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. + */ + accelerateToObject: function (gameObject, destination, speed, xSpeedMax, ySpeedMax) + { + return this.accelerateTo(gameObject, destination.x, destination.y, speed, xSpeedMax, ySpeedMax); + }, + + /** + * Finds the Body or Game Object closest to a source point or object. + * + * If a `targets` argument is passed, this method finds the closest of those. + * The targets can be Arcade Physics Game Objects, Dynamic Bodies, or Static Bodies. + * + * If no `targets` argument is passed, this method finds the closest Dynamic Body. + * + * If two or more targets are the exact same distance from the source point, only the first target + * is returned. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#closest + * @since 3.0.0 + * + * @generic {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|Phaser.GameObjects.GameObject} Target + * @param {Phaser.Types.Math.Vector2Like} source - Any object with public `x` and `y` properties, such as a Game Object or Geometry object. + * @param {Target[]} [targets] - The targets. + * + * @return {Target|null} The target closest to the given source point. + */ + closest: function (source, targets) + { + if (!targets) + { + targets = this.world.bodies.entries; + } + + var min = Number.MAX_VALUE; + var closest = null; + var x = source.x; + var y = source.y; + var len = targets.length; + + for (var i = 0; i < len; i++) + { + var target = targets[i]; + var body = target.body || target; + + if (source === target || source === body || source === body.gameObject || source === body.center) + { + continue; + } + + var distance = DistanceSquared(x, y, body.center.x, body.center.y); + + if (distance < min) + { + closest = target; + min = distance; + } + } + + return closest; + }, + + /** + * Finds the Body or Game Object farthest from a source point or object. + * + * If a `targets` argument is passed, this method finds the farthest of those. + * The targets can be Arcade Physics Game Objects, Dynamic Bodies, or Static Bodies. + * + * If no `targets` argument is passed, this method finds the farthest Dynamic Body. + * + * If two or more targets are the exact same distance from the source point, only the first target + * is returned. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#furthest + * @since 3.0.0 + * + * @param {any} source - Any object with public `x` and `y` properties, such as a Game Object or Geometry object. + * @param {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[]|Phaser.GameObjects.GameObject[])} [targets] - The targets. + * + * @return {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|Phaser.GameObjects.GameObject)} The target farthest from the given source point. + */ + furthest: function (source, targets) + { + if (!targets) + { + targets = this.world.bodies.entries; + } + + var max = -1; + var farthest = null; + var x = source.x; + var y = source.y; + var len = targets.length; + + for (var i = 0; i < len; i++) + { + var target = targets[i]; + var body = target.body || target; + + if (source === target || source === body || source === body.gameObject || source === body.center) + { + continue; + } + + var distance = DistanceSquared(x, y, body.center.x, body.center.y); + + if (distance > max) + { + farthest = target; + max = distance; + } + + } + + return farthest; + }, + + /** + * Move the given display object towards the x/y coordinates at a steady velocity. + * If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds. + * Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms. + * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course. + * Note: The display object doesn't stop moving once it reaches the destination coordinates. + * Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all) + * + * @method Phaser.Physics.Arcade.ArcadePhysics#moveTo + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body. + * @param {number} x - The x coordinate to move towards. + * @param {number} y - The y coordinate to move towards. + * @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec) + * @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms. + * + * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. + */ + moveTo: function (gameObject, x, y, speed, maxTime) + { + if (speed === undefined) { speed = 60; } + if (maxTime === undefined) { maxTime = 0; } + + var angle = Math.atan2(y - gameObject.y, x - gameObject.x); + + if (maxTime > 0) + { + // We know how many pixels we need to move, but how fast? + speed = DistanceBetween(gameObject.x, gameObject.y, x, y) / (maxTime / 1000); + } + + gameObject.body.velocity.setToPolar(angle, speed); + + return angle; + }, + + /** + * Move the given display object towards the destination object at a steady velocity. + * If you specify a maxTime then it will adjust the speed (overwriting what you set) so it arrives at the destination in that number of seconds. + * Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms. + * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course. + * Note: The display object doesn't stop moving once it reaches the destination coordinates. + * Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all) + * + * @method Phaser.Physics.Arcade.ArcadePhysics#moveToObject + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body. + * @param {object} destination - Any object with public `x` and `y` properties, such as a Game Object or Geometry object. + * @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec) + * @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms. + * + * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. + */ + moveToObject: function (gameObject, destination, speed, maxTime) + { + return this.moveTo(gameObject, destination.x, destination.y, speed, maxTime); + }, + + /** + * Given the angle (in degrees) and speed calculate the velocity and return it as a vector, or set it to the given vector object. + * One way to use this is: velocityFromAngle(angle, 200, sprite.body.velocity) which will set the values directly to the sprite's velocity and not create a new vector object. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#velocityFromAngle + * @since 3.0.0 + * + * @param {number} angle - The angle in degrees calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative) + * @param {number} [speed=60] - The speed it will move, in pixels per second squared. + * @param {Phaser.Math.Vector2} [vec2] - The Vector2 in which the x and y properties will be set to the calculated velocity. + * + * @return {Phaser.Math.Vector2} The Vector2 that stores the velocity. + */ + velocityFromAngle: function (angle, speed, vec2) + { + if (speed === undefined) { speed = 60; } + if (vec2 === undefined) { vec2 = new Vector2(); } + + return vec2.setToPolar(DegToRad(angle), speed); + }, + + /** + * Given the rotation (in radians) and speed calculate the velocity and return it as a vector, or set it to the given vector object. + * One way to use this is: velocityFromRotation(rotation, 200, sprite.body.velocity) which will set the values directly to the sprite's velocity and not create a new vector object. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#velocityFromRotation + * @since 3.0.0 + * + * @param {number} rotation - The angle in radians. + * @param {number} [speed=60] - The speed it will move, in pixels per second squared + * @param {Phaser.Math.Vector2} [vec2] - The Vector2 in which the x and y properties will be set to the calculated velocity. + * + * @return {Phaser.Math.Vector2} The Vector2 that stores the velocity. + */ + velocityFromRotation: function (rotation, speed, vec2) + { + if (speed === undefined) { speed = 60; } + if (vec2 === undefined) { vec2 = new Vector2(); } + + return vec2.setToPolar(rotation, speed); + }, + + /** + * This method will search the given rectangular 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 for is extremely fast, + * otherwise the search is O(N) for Dynamic Bodies. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#overlapRect + * @since 3.17.0 + * + * @param {number} x - The top-left x coordinate of the area to search within. + * @param {number} y - The top-left y coordinate of the area to search within. + * @param {number} width - The width of the area to search within. + * @param {number} height - The height 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. + */ + overlapRect: function (x, y, width, height, includeDynamic, includeStatic) + { + return OverlapRect(this.world, x, y, width, height, includeDynamic, includeStatic); + }, + + /** + * 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. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#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. + */ + overlapCirc: function (x, y, radius, includeDynamic, includeStatic) + { + return OverlapCirc(this.world, x, y, radius, includeDynamic, includeStatic); + }, + + /** + * The Scene that owns this plugin is shutting down. + * We need to kill and reset all internal properties as well as stop listening to Scene events. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#shutdown + * @since 3.0.0 + */ + shutdown: function () + { + if (!this.world) + { + // Already destroyed + return; + } + + var eventEmitter = this.systems.events; + + eventEmitter.off(SceneEvents.UPDATE, this.world.update, this.world); + eventEmitter.off(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world); + eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); + + this.add.destroy(); + this.world.destroy(); + + this.add = null; + this.world = null; + }, + + /** + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. + * + * @method Phaser.Physics.Arcade.ArcadePhysics#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.shutdown(); + + this.scene.sys.events.off(SceneEvents.START, this.start, this); + + this.scene = null; + this.systems = null; + } + +}); + +PluginCache.register('ArcadePhysics', ArcadePhysics, 'arcadePhysics'); + +module.exports = ArcadePhysics; + + +/***/ }), + +/***/ 25084: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var Components = __webpack_require__(7864); +var Sprite = __webpack_require__(13747); + +/** + * @classdesc + * An Arcade Physics Sprite is a Sprite with an Arcade Physics body and related components. + * The body can be dynamic or static. + * + * The main difference between an Arcade Sprite and an Arcade Image is that you cannot animate an Arcade Image. + * If you do not require animation then you can safely use Arcade Images instead of Arcade Sprites. + * + * @class Sprite + * @extends Phaser.GameObjects.Sprite + * @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.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @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 ArcadeSprite = new Class({ + + Extends: Sprite, + + 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 ArcadeSprite (scene, x, y, texture, frame) + { + Sprite.call(this, scene, x, y, texture, frame); + + /** + * This Game Object's Physics Body. + * + * @name Phaser.Physics.Arcade.Sprite#body + * @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} + * @default null + * @since 3.0.0 + */ + this.body = null; + } + +}); + +module.exports = ArcadeSprite; + + +/***/ }), + +/***/ 97602: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @author Benjamin D. Richards + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(47401); +var Events = __webpack_require__(27037); +var RadToDeg = __webpack_require__(23701); +var Rectangle = __webpack_require__(74118); +var RectangleContains = __webpack_require__(94287); +var Vector2 = __webpack_require__(93736); + +/** + * @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. As of Phaser 3.60 this is now optional. + */ +var Body = new Class({ + + initialize: + + function Body (world, gameObject) + { + var width = 64; + var height = 64; + + var dummyGameObject = { + x: 0, + y: 0, + angle: 0, + rotation: 0, + scaleX: 1, + scaleY: 1, + displayOriginX: 0, + displayOriginY: 0 + }; + + var hasGameObject = (gameObject !== undefined); + + if (hasGameObject && gameObject.displayWidth) + { + width = gameObject.displayWidth; + height = gameObject.displayHeight; + } + + if (!hasGameObject) + { + gameObject = dummyGameObject; + } + + /** + * 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. + * + * As of Phaser 3.60 this is now optional and can be undefined. + * + * @name Phaser.Physics.Arcade.Body#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.0.0 + */ + this.gameObject = (hasGameObject) ? gameObject : undefined; + + /** + * A quick-test flag that signifies this is a Body, used in the World collision handler. + * + * @name Phaser.Physics.Arcade.Body#isBody + * @type {boolean} + * @readonly + * @since 3.60.0 + */ + this.isBody = true; + + /** + * 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 keeps 1% of its velocity per second, losing 99%. + * A value of 0.1 means the Body keeps 10% of its velocity per second, losing 90%. + * A value of 1 means the Body loses no velocity. + * You can use very small values (e.g., 0.001) to stop the Body quickly. + * + * 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; + + /** + * 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 absolute maximum velocity of this body, 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(); + } + + if (this.gameObject) + { + 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; + var gameObject = this.gameObject; + + 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; + } + } + + if (gameObject) + { + gameObject.x += dx; + 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 && gameObject) + { + 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; + }, + + /** + * Assign this Body to a new Game Object. + * + * Removes this body from the Physics World, assigns to the new Game Object, calls `setSize` and then + * adds this body back into the World again, setting it enabled, unless the `enable` argument is set to `false`. + * + * If this body already has a Game Object, then it will remove itself from that Game Object first. + * + * Only if the given `gameObject` has a `body` property will this Body be assigned to it. + * + * @method Phaser.Physics.Arcade.Body#setGameObject + * @since 3.60.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Body belongs to. + * @param {boolean} [enable=true] - Automatically enable this Body for physics. + * + * @return {Phaser.Physics.Arcade.Body} This Body object. + */ + setGameObject: function (gameObject, enable) + { + if (enable === undefined) { enable = true; } + + // Remove from the World + this.world.remove(this); + + if (this.gameObject && this.gameObject.body) + { + // Disconnect the current Game Object + this.gameObject.body = null; + } + + this.gameObject = gameObject; + + if (gameObject.body) + { + gameObject.body = this; + } + + this.setSize(); + + this.world.add(this); + + this.enable = enable; + + 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 (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 && 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; + + if (gameObject) + { + gameObject.setPosition(x, y); + + this.rotation = gameObject.angle; + this.preRotation = gameObject.angle; + } + + var pos = this.position; + + if (gameObject && gameObject.getTopLeft) + { + gameObject.getTopLeft(pos); + } + else + { + pos.set(x, y); + } + + this.prev.copy(pos); + this.prevFrame.copy(pos); + + if (gameObject) + { + this.updateBounds(); + } + + this.updateCenter(); + + if (this.collideWorldBounds) + { + this.checkWorldBounds(); + } + + 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) + { + return this.setVelocity(value, this.velocity.y); + }, + + /** + * 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) + { + return this.setVelocity(this.velocity.x, value); + }, + + /** + * 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=x] - 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=x] - 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=x] - 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=x] - 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=x] - 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; + blocked.none = false; + } + + if (right) + { + blocked.right = true; + blocked.none = false; + } + }, + + /** + * 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; + blocked.none = false; + } + + if (down) + { + blocked.down = true; + blocked.none = false; + } + }, + + /** + * 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; + + +/***/ }), + +/***/ 3909: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); + +/** + * @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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. + * @param {Phaser.Types.Physics.Arcade.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 {Phaser.Types.Physics.Arcade.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 {Phaser.Types.Physics.Arcade.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; + + +/***/ }), + +/***/ 99523: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var ArcadeImage = __webpack_require__(62832); +var ArcadeSprite = __webpack_require__(25084); +var Body = __webpack_require__(97602); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(47401); +var PhysicsGroup = __webpack_require__(10481); +var StaticBody = __webpack_require__(66634); +var StaticPhysicsGroup = __webpack_require__(46346); + +/** + * @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.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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. + * @param {Phaser.Types.Physics.Arcade.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.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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. + * @param {Phaser.Types.Physics.Arcade.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)); + }, + + /** + * Creates a new physics Body with the given position and size. + * + * This Body is not associated with any Game Object, but still exists within the world + * and can be tested for collision, have velocity, etc. + * + * @method Phaser.Physics.Arcade.Factory#body + * @since 3.60.0 + * + * @param {number} x - The horizontal position of this Body in the physics world. + * @param {number} y - The vertical position of this Body in the physics world. + * @param {number} [width=64] - The width of the Body in pixels. Cannot be negative or zero. + * @param {number} [height=64] - The height of the Body in pixels. Cannot be negative or zero. + * + * @return {Phaser.Physics.Arcade.Body} The Body that was created. + */ + body: function (x, y, width, height) + { + var body = new Body(this.world); + + body.position.set(x, y); + + if (width && height) + { + body.setSize(width, height); + } + + this.world.add(body, CONST.DYNAMIC_BODY); + + return body; + }, + + /** + * Creates a new static physics Body with the given position and size. + * + * This Body is not associated with any Game Object, but still exists within the world + * and can be tested for collision, etc. + * + * @method Phaser.Physics.Arcade.Factory#staticBody + * @since 3.60.0 + * + * @param {number} x - The horizontal position of this Body in the physics world. + * @param {number} y - The vertical position of this Body in the physics world. + * @param {number} [width=64] - The width of the Body in pixels. Cannot be negative or zero. + * @param {number} [height=64] - The height of the Body in pixels. Cannot be negative or zero. + * + * @return {Phaser.Physics.Arcade.Body} The Body that was created. + */ + staticBody: function (x, y, width, height) + { + var body = new StaticBody(this.world); + + body.position.set(x, y); + + if (width && height) + { + body.setSize(width, height); + } + + this.world.add(body, CONST.STATIC_BODY); + + return body; + }, + + /** + * 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; + + +/***/ }), + +/***/ 75671: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(47401); + +/** + * Calculates and returns the horizontal overlap between two arcade physics bodies and sets their properties + * accordingly, including: `touching.left`, `touching.right`, `touching.none` and `overlapX'. + * + * @function Phaser.Physics.Arcade.GetOverlapX + * @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 - Is this an overlap only check, or part of separation? + * @param {number} bias - A value added to the delta values during collision checks. Increase it to prevent sprite tunneling(sprites passing through another instead of colliding). + * + * @return {number} The amount of overlap. + */ +var GetOverlapX = function (body1, body2, overlapOnly, bias) +{ + var overlap = 0; + var maxOverlap = body1.deltaAbsX() + body2.deltaAbsX() + bias; + + if (body1._dx === 0 && body2._dx === 0) + { + // They overlap but neither of them are moving + body1.embedded = true; + body2.embedded = true; + } + else if (body1._dx > body2._dx) + { + // Body1 is moving right and / or Body2 is moving left + overlap = body1.right - body2.x; + + if ((overlap > maxOverlap && !overlapOnly) || body1.checkCollision.right === false || body2.checkCollision.left === false) + { + overlap = 0; + } + else + { + body1.touching.none = false; + body1.touching.right = true; + + body2.touching.none = false; + body2.touching.left = true; + + if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) + { + body1.blocked.none = false; + body1.blocked.right = true; + } + + if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) + { + body2.blocked.none = false; + body2.blocked.left = true; + } + } + } + else if (body1._dx < body2._dx) + { + // Body1 is moving left and/or Body2 is moving right + overlap = body1.x - body2.width - body2.x; + + if ((-overlap > maxOverlap && !overlapOnly) || body1.checkCollision.left === false || body2.checkCollision.right === false) + { + overlap = 0; + } + else + { + body1.touching.none = false; + body1.touching.left = true; + + body2.touching.none = false; + body2.touching.right = true; + + if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) + { + body1.blocked.none = false; + body1.blocked.left = true; + } + + if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) + { + body2.blocked.none = false; + body2.blocked.right = true; + } + } + } + + // Resets the overlapX to zero if there is no overlap, or to the actual pixel value if there is + body1.overlapX = overlap; + body2.overlapX = overlap; + + return overlap; +}; + +module.exports = GetOverlapX; + + +/***/ }), + +/***/ 66185: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(47401); + +/** + * Calculates and returns the vertical overlap between two arcade physics bodies and sets their properties + * accordingly, including: `touching.up`, `touching.down`, `touching.none` and `overlapY'. + * + * @function Phaser.Physics.Arcade.GetOverlapY + * @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 - Is this an overlap only check, or part of separation? + * @param {number} bias - A value added to the delta values during collision checks. Increase it to prevent sprite tunneling(sprites passing through another instead of colliding). + * + * @return {number} The amount of overlap. + */ +var GetOverlapY = function (body1, body2, overlapOnly, bias) +{ + var overlap = 0; + var maxOverlap = body1.deltaAbsY() + body2.deltaAbsY() + bias; + + if (body1._dy === 0 && body2._dy === 0) + { + // They overlap but neither of them are moving + body1.embedded = true; + body2.embedded = true; + } + else if (body1._dy > body2._dy) + { + // Body1 is moving down and/or Body2 is moving up + overlap = body1.bottom - body2.y; + + if ((overlap > maxOverlap && !overlapOnly) || body1.checkCollision.down === false || body2.checkCollision.up === false) + { + overlap = 0; + } + else + { + body1.touching.none = false; + body1.touching.down = true; - /** - * 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; + body2.touching.none = false; + body2.touching.up = true; - /** - * 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; + if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) + { + body1.blocked.none = false; + body1.blocked.down = true; + } - /** - * 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; + if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) + { + body2.blocked.none = false; + body2.blocked.up = true; + } + } + } + else if (body1._dy < body2._dy) + { + // Body1 is moving up and/or Body2 is moving down + overlap = body1.y - body2.bottom; - /** - * 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 ((-overlap > maxOverlap && !overlapOnly) || body1.checkCollision.up === false || body2.checkCollision.down === false) + { + overlap = 0; + } + else + { + body1.touching.none = false; + body1.touching.up = true; - /** - * 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; + body2.touching.none = false; + body2.touching.down = true; - /** - * 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(); + if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) + { + body1.blocked.none = false; + body1.blocked.up = true; + } - /** - * 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 - ); + if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) + { + body2.blocked.none = false; + body2.blocked.down = true; + } + } + } - /** - * 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(); + // Resets the overlapY to zero if there is no overlap, or to the actual pixel value if there is + body1.overlapY = overlap; + body2.overlapY = overlap; - /** - * 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(); + return overlap; +}; - /** - * 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; +module.exports = GetOverlapY; - /** - * 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; +/***/ 10481: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +var ArcadeSprite = __webpack_require__(25084); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(47401); +var GetFastValue = __webpack_require__(72632); +var Group = __webpack_require__(59192); +var IsPlainObject = __webpack_require__(42911); - /** - * 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; +/** + * @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({ - if (gameObject.frame) + Extends: Group, + + initialize: + + function PhysicsGroup (world, scene, children, config) + { + if (!children && !config) { - this.sourceWidth = gameObject.frame.realWidth; - this.sourceHeight = gameObject.frame.realHeight; + config = { + internalCreateCallback: this.createCallbackHandler, + internalRemoveCallback: this.removeCallbackHandler + }; } + else if (IsPlainObject(children)) + { + // children is a plain object, so swizzle them: + config = children; + children = null; - /** - * 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); + 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]; - /** - * 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); + var _this = this; - /** - * 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); + children.forEach(function (singleConfig) + { + singleConfig.internalCreateCallback = _this.createCallbackHandler; + singleConfig.internalRemoveCallback = _this.removeCallbackHandler; + }); - /** - * 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(); + 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 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. + * The physics simulation. * - * @name Phaser.Physics.Arcade.Body#newVelocity - * @type {Phaser.Math.Vector2} - * @readonly + * @name Phaser.Physics.Arcade.Group#world + * @type {Phaser.Physics.Arcade.World} * @since 3.0.0 */ - this.newVelocity = new Vector2(); + this.world = world; /** - * The Body's absolute maximum change in position, in pixels per step. + * The class to create new Group members from. * - * @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. + * This should be either `Phaser.Physics.Arcade.Image`, `Phaser.Physics.Arcade.Sprite`, or a class extending one of those. * - * @name Phaser.Physics.Arcade.Body#acceleration - * @type {Phaser.Math.Vector2} + * @name Phaser.Physics.Arcade.Group#classType + * @type {function} + * @default ArcadeSprite * @since 3.0.0 + * @see Phaser.Types.GameObjects.Group.GroupClassTypeConstructor */ - this.acceleration = new Vector2(); + config.classType = GetFastValue(config, 'classType', ArcadeSprite); /** - * Whether this Body's velocity is affected by its `drag`. + * The physics type of the Group's members. * - * @name Phaser.Physics.Arcade.Body#allowDrag - * @type {boolean} - * @default true + * @name Phaser.Physics.Arcade.Group#physicsType + * @type {number} + * @default Phaser.Physics.Arcade.DYNAMIC_BODY * @since 3.0.0 */ - this.allowDrag = true; + this.physicsType = CONST.DYNAMIC_BODY; /** - * 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 keeps 1% of its velocity per second, losing 99%. - * A value of 0.1 means the Body keeps 10% of its velocity per second, losing 90%. - * A value of 1 means the Body loses no velocity. - * You can use very small values (e.g., 0.001) to stop the Body quickly. - * - * The x and y components are applied separately. + * Default physics properties applied to Game Objects added to the Group or created by the Group. Derived from the `config` argument. * - * Drag is applied only when `acceleration` is zero. + * You can remove the default values by setting this property to `{}`. * - * @name Phaser.Physics.Arcade.Body#drag - * @type {Phaser.Math.Vector2} + * @name Phaser.Physics.Arcade.Group#defaults + * @type {Phaser.Types.Physics.Arcade.PhysicsGroupDefaults} * @since 3.0.0 */ - this.drag = new Vector2(); + 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), + setDamping: GetFastValue(config, 'useDamping', false), + 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), + setMaxSpeed: GetFastValue(config, 'maxSpeed', -1), + 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) + }; - /** - * 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; + Group.call(this, scene, children, config); /** - * 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`. + * 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.Body#gravity - * @type {Phaser.Math.Vector2} - * @since 3.0.0 - * @see Phaser.Physics.Arcade.World#gravity + * @name Phaser.Physics.Arcade.Group#type + * @type {string} + * @default 'PhysicsGroup' + * @since 3.21.0 */ - this.gravity = new Vector2(); + this.type = 'PhysicsGroup'; + }, - /** - * 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(); + /** + * 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); + } - /** - * 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; + var body = child.body; - /** - * 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; + for (var key in this.defaults) + { + body[key](this.defaults[key]); + } + }, - // If true this Body will dispatch events + /** + * 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); + } + }, - /** - * 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; + /** + * 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; } - /** - * 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; + var items = this.getChildren(); - /** - * 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; + for (var i = 0; i < items.length; i++) + { + items[i].body.velocity.set(x + (i * step), y + (i * step)); + } - /** - * 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); + return this; + }, - /** - * 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; + /** + * 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; } - /** - * 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); + var items = this.getChildren(); - /** - * 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; + for (var i = 0; i < items.length; i++) + { + items[i].body.velocity.x = value + (i * step); + } - /** - * 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; + return this; + }, - /** - * 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; + /** + * 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; } - /** - * 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; + var items = this.getChildren(); - /** - * 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; + for (var i = 0; i < items.length; i++) + { + items[i].body.velocity.y = value + (i * step); + } - /** - * 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; + return this; + } - /** - * 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; +module.exports = PhysicsGroup; - /** - * 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; +/***/ 22916: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +var body1; +var body2; +var body1Pushable; +var body2Pushable; +var body1MassImpact; +var body2MassImpact; +var body1FullImpact; +var body2FullImpact; +var body1MovingLeft; +var body1MovingRight; +var body1Stationary; +var body2MovingLeft; +var body2MovingRight; +var body2Stationary; +var body1OnLeft; +var body2OnLeft; +var overlap; - /** - * 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; +/** + * Sets all of the local processing values and calculates the velocity exchanges. + * + * Then runs `BlockCheck` and returns the value from it. + * + * This method is called by `Phaser.Physics.Arcade.SeparateX` and should not be + * called directly. + * + * @function Phaser.Physics.Arcade.ProcessX.Set + * @ignore + * @since 3.50.0 + * + * @param {Phaser.Physics.Arcade.Body} b1 - The first Body to separate. + * @param {Phaser.Physics.Arcade.Body} b2 - The second Body to separate. + * @param {number} ov - The overlap value. + * + * @return {number} The BlockCheck result. 0 = not blocked. 1 = Body 1 blocked. 2 = Body 2 blocked. + */ +var Set = function (b1, b2, ov) +{ + body1 = b1; + body2 = b2; - /** - * 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; + var v1 = body1.velocity.x; + var v2 = body2.velocity.x; - /** - * 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; + body1Pushable = body1.pushable; + body1MovingLeft = body1._dx < 0; + body1MovingRight = body1._dx > 0; + body1Stationary = body1._dx === 0; + body1OnLeft = Math.abs(body1.right - body2.x) <= Math.abs(body2.right - body1.x); + body1FullImpact = v2 - v1 * body1.bounce.x; - /** - * 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; + body2Pushable = body2.pushable; + body2MovingLeft = body2._dx < 0; + body2MovingRight = body2._dx > 0; + body2Stationary = body2._dx === 0; + body2OnLeft = !body1OnLeft; + body2FullImpact = v1 - v2 * body2.bounce.x; - /** - * 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; + // negative delta = up, positive delta = down (inc. gravity) + overlap = Math.abs(ov); - /** - * 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; + return BlockCheck(); +}; - /** - * 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 }; +/** + * Blocked Direction checks, because it doesn't matter if an object can be pushed + * or not, blocked is blocked. + * + * @function Phaser.Physics.Arcade.ProcessX.BlockCheck + * @ignore + * @since 3.50.0 + * + * @return {number} The BlockCheck result. 0 = not blocked. 1 = Body 1 blocked. 2 = Body 2 blocked. + */ +var BlockCheck = function () +{ + // Body1 is moving right and Body2 is blocked from going right any further + if (body1MovingRight && body1OnLeft && body2.blocked.right) + { + body1.processX(-overlap, body1FullImpact, false, 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 }; + return 1; + } - /** - * 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 }; + // Body1 is moving up and Body2 is blocked from going up any further + if (body1MovingLeft && body2OnLeft && body2.blocked.left) + { + body1.processX(overlap, body1FullImpact, true); - /** - * 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 }; + return 1; + } - /** - * 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; + // Body2 is moving right and Body1 is blocked from going right any further + if (body2MovingRight && body2OnLeft && body1.blocked.right) + { + body2.processX(-overlap, body2FullImpact, false, true); - /** - * 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; + return 2; + } - /** - * 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; + // Body2 is moving up and Body1 is blocked from going up any further + if (body2MovingLeft && body1OnLeft && body1.blocked.left) + { + body2.processX(overlap, body2FullImpact, true); - /** - * 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; + return 2; + } + + return 0; +}; + +/** + * The main check function. Runs through one of the four possible tests and returns the results. + * + * @function Phaser.Physics.Arcade.ProcessX.Check + * @ignore + * @since 3.50.0 + * + * @return {boolean} `true` if a check passed, otherwise `false`. + */ +var Check = function () +{ + var v1 = body1.velocity.x; + var v2 = body2.velocity.x; - /** - * 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; + var nv1 = Math.sqrt((v2 * v2 * body2.mass) / body1.mass) * ((v2 > 0) ? 1 : -1); + var nv2 = Math.sqrt((v1 * v1 * body1.mass) / body2.mass) * ((v1 > 0) ? 1 : -1); + var avg = (nv1 + nv2) * 0.5; - /** - * 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; + nv1 -= avg; + nv2 -= avg; - /** - * 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; + body1MassImpact = avg + nv1 * body1.bounce.x; + body2MassImpact = avg + nv2 * body2.bounce.x; - /** - * 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; + // Body1 hits Body2 on the right hand side + if (body1MovingLeft && body2OnLeft) + { + return Run(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(); - }, + // Body2 hits Body1 on the right hand side + if (body2MovingLeft && body1OnLeft) + { + return Run(1); + } - /** - * 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 () + // Body1 hits Body2 on the left hand side + if (body1MovingRight && body1OnLeft) { - var sprite = this.gameObject; + return Run(2); + } - // Container? + // Body2 hits Body1 on the left hand side + if (body2MovingRight && body2OnLeft) + { + return Run(3); + } - var transform = this.transform; + return false; +}; - if (sprite.parentContainer) - { - var matrix = sprite.getWorldTransformMatrix(this.world._tempMatrix, this.world._tempMatrix2); +/** + * The main check function. Runs through one of the four possible tests and returns the results. + * + * @function Phaser.Physics.Arcade.ProcessX.Run + * @ignore + * @since 3.50.0 + * + * @param {number} side - The side to test. As passed in by the `Check` function. + * + * @return {boolean} Always returns `true`. + */ +var Run = function (side) +{ + if (body1Pushable && body2Pushable) + { + // Both pushable, or both moving at the same time, so equal rebound + overlap *= 0.5; - 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; + if (side === 0 || side === 3) + { + // body1MovingLeft && body2OnLeft + // body2MovingRight && body2OnLeft + body1.processX(overlap, body1MassImpact); + body2.processX(-overlap, body2MassImpact); } 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; + // body2MovingLeft && body1OnLeft + // body1MovingRight && body1OnLeft + body1.processX(-overlap, body1MassImpact); + body2.processX(overlap, body2MassImpact); } + } + else if (body1Pushable && !body2Pushable) + { + // Body1 pushable, Body2 not - var recalc = false; - - if (this.syncBounds) + if (side === 0 || side === 3) { - var b = sprite.getBounds(this._bounds); - - this.width = b.width; - this.height = b.height; - recalc = true; + // body1MovingLeft && body2OnLeft + // body2MovingRight && body2OnLeft + body1.processX(overlap, body1FullImpact, 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; - } + // body2MovingLeft && body1OnLeft + // body1MovingRight && body1OnLeft + body1.processX(-overlap, body1FullImpact, false, true); } + } + else if (!body1Pushable && body2Pushable) + { + // Body2 pushable, Body1 not - if (recalc) + if (side === 0 || side === 3) { - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - this.updateCenter(); + // body1MovingLeft && body2OnLeft + // body2MovingRight && body2OnLeft + body2.processX(-overlap, body2FullImpact, false, true); } - }, - - /** - * 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 () + else + { + // body2MovingLeft && body1OnLeft + // body1MovingRight && body1OnLeft + body2.processX(overlap, body2FullImpact, true); + } + } + else { - 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); + // Neither body is pushable, so base it on movement - this.updateCenter(); - }, + var halfOverlap = overlap * 0.5; - /** - * 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) + if (side === 0) { - clear = false; - } + // body1MovingLeft && body2OnLeft - // Store and reset collision flags - var wasTouching = this.wasTouching; - var touching = this.touching; - var blocked = this.blocked; + if (body2Stationary) + { + body1.processX(overlap, 0, true); + body2.processX(0, null, false, true); + } + else if (body2MovingRight) + { + body1.processX(halfOverlap, 0, true); + body2.processX(-halfOverlap, 0, false, true); + } + else + { + // Body2 moving same direction as Body1 + body1.processX(halfOverlap, body2.velocity.x, true); + body2.processX(-halfOverlap, null, false, true); + } + } + else if (side === 1) + { + // body2MovingLeft && body1OnLeft - if (clear) + if (body1Stationary) + { + body1.processX(0, null, false, true); + body2.processX(overlap, 0, true); + } + else if (body1MovingRight) + { + body1.processX(-halfOverlap, 0, false, true); + body2.processX(halfOverlap, 0, true); + } + else + { + // Body1 moving same direction as Body2 + body1.processX(-halfOverlap, null, false, true); + body2.processX(halfOverlap, body1.velocity.x, true); + } + } + else if (side === 2) { - wasTouching.none = true; - wasTouching.up = false; - wasTouching.down = false; - wasTouching.left = false; - wasTouching.right = false; + // body1MovingRight && body1OnLeft + + if (body2Stationary) + { + body1.processX(-overlap, 0, false, true); + body2.processX(0, null, true); + } + else if (body2MovingLeft) + { + body1.processX(-halfOverlap, 0, false, true); + body2.processX(halfOverlap, 0, true); + } + else + { + // Body2 moving same direction as Body1 + body1.processX(-halfOverlap, body2.velocity.x, false, true); + body2.processX(halfOverlap, null, true); + } } - else + else if (side === 3) { - wasTouching.none = touching.none; - wasTouching.up = touching.up; - wasTouching.down = touching.down; - wasTouching.left = touching.left; - wasTouching.right = touching.right; + // body2MovingRight && body2OnLeft + + if (body1Stationary) + { + body1.processX(0, null, true); + body2.processX(-overlap, 0, false, true); + } + else if (body1MovingLeft) + { + body1.processX(halfOverlap, 0, true); + body2.processX(-halfOverlap, 0, false, true); + } + else + { + // Body1 moving same direction as Body2 + body1.processX(halfOverlap, body2.velocity.y, true); + body2.processX(-halfOverlap, null, false, true); + } } + } - touching.none = true; - touching.up = false; - touching.down = false; - touching.left = false; - touching.right = false; + return true; +}; - blocked.none = true; - blocked.up = false; - blocked.down = false; - blocked.left = false; - blocked.right = false; +/** + * This function is run when Body1 is Immovable and Body2 is not. + * + * @function Phaser.Physics.Arcade.ProcessX.RunImmovableBody1 + * @ignore + * @since 3.50.0 + * + * @param {number} blockedState - The block state value. + */ +var RunImmovableBody1 = function (blockedState) +{ + if (blockedState === 1) + { + // But Body2 cannot go anywhere either, so we cancel out velocity + // Separation happened in the block check + body2.velocity.x = 0; + } + else if (body1OnLeft) + { + body2.processX(overlap, body2FullImpact, true); + } + else + { + body2.processX(-overlap, body2FullImpact, false, true); + } - this.overlapR = 0; - this.overlapX = 0; - this.overlapY = 0; + // This is special case code that handles things like vertically moving platforms you can ride + if (body1.moves) + { + body2.y += (body1.y - body1.prev.y) * body1.friction.y; + body2._dy = body2.y - body2.prev.y; + } +}; - this.embedded = false; - }, +/** + * This function is run when Body2 is Immovable and Body1 is not. + * + * @function Phaser.Physics.Arcade.ProcessX.RunImmovableBody2 + * @ignore + * @since 3.50.0 + * + * @param {number} blockedState - The block state value. + */ +var RunImmovableBody2 = function (blockedState) +{ + if (blockedState === 2) + { + // But Body1 cannot go anywhere either, so we cancel out velocity + // Separation happened in the block check + body1.velocity.x = 0; + } + else if (body2OnLeft) + { + body1.processX(overlap, body1FullImpact, true); + } + else + { + body1.processX(-overlap, body1FullImpact, false, true); + } - /** - * 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) + // This is special case code that handles things like vertically moving platforms you can ride + if (body2.moves) { - if (willStep) - { - this.resetFlags(); - } + body1.y += (body2.y - body2.prev.y) * body2.friction.y; + body1._dy = body1.y - body1.prev.y; + } +}; - this.updateFromGameObject(); +/** + * @namespace Phaser.Physics.Arcade.ProcessX + * @ignore + */ - this.rotation = this.transform.rotation; - this.preRotation = this.rotation; +module.exports = { + BlockCheck: BlockCheck, + Check: Check, + Set: Set, + Run: Run, + RunImmovableBody1: RunImmovableBody1, + RunImmovableBody2: RunImmovableBody2 +}; - 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; +/***/ 67050: +/***/ ((module) => { - if (this.moves) - { - this.world.updateMotion(this, delta); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var vx = this.velocity.x; - var vy = this.velocity.y; +var body1; +var body2; +var body1Pushable; +var body2Pushable; +var body1MassImpact; +var body2MassImpact; +var body1FullImpact; +var body2FullImpact; +var body1MovingUp; +var body1MovingDown; +var body1Stationary; +var body2MovingUp; +var body2MovingDown; +var body2Stationary; +var body1OnTop; +var body2OnTop; +var overlap; - this.newVelocity.set(vx * delta, vy * delta); +/** + * Sets all of the local processing values and calculates the velocity exchanges. + * + * Then runs `BlockCheck` and returns the value from it. + * + * This method is called by `Phaser.Physics.Arcade.SeparateY` and should not be + * called directly. + * + * @function Phaser.Physics.Arcade.ProcessY.Set + * @ignore + * @since 3.50.0 + * + * @param {Phaser.Physics.Arcade.Body} b1 - The first Body to separate. + * @param {Phaser.Physics.Arcade.Body} b2 - The second Body to separate. + * @param {number} ov - The overlap value. + * + * @return {number} The BlockCheck result. 0 = not blocked. 1 = Body 1 blocked. 2 = Body 2 blocked. + */ +var Set = function (b1, b2, ov) +{ + body1 = b1; + body2 = b2; - this.position.add(this.newVelocity); + var v1 = body1.velocity.y; + var v2 = body2.velocity.y; - this.updateCenter(); + body1Pushable = body1.pushable; + body1MovingUp = body1._dy < 0; + body1MovingDown = body1._dy > 0; + body1Stationary = body1._dy === 0; + body1OnTop = Math.abs(body1.bottom - body2.y) <= Math.abs(body2.bottom - body1.y); + body1FullImpact = v2 - v1 * body1.bounce.y; - this.angle = Math.atan2(vy, vx); - this.speed = Math.sqrt(vx * vx + vy * vy); + body2Pushable = body2.pushable; + body2MovingUp = body2._dy < 0; + body2MovingDown = body2._dy > 0; + body2Stationary = body2._dy === 0; + body2OnTop = !body1OnTop; + body2FullImpact = v1 - v2 * body2.bounce.y; - // Now the update will throw collision checks at the Body - // And finally we'll integrate the new position back to the Sprite in postUpdate + // negative delta = up, positive delta = down (inc. gravity) + overlap = Math.abs(ov); - 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); - } - } + return BlockCheck(); +}; - this._dx = this.position.x - this.prev.x; - this._dy = this.position.y - this.prev.y; - }, +/** + * Blocked Direction checks, because it doesn't matter if an object can be pushed + * or not, blocked is blocked. + * + * @function Phaser.Physics.Arcade.ProcessY.BlockCheck + * @ignore + * @since 3.50.0 + * + * @return {number} The BlockCheck result. 0 = not blocked. 1 = Body 1 blocked. 2 = Body 2 blocked. + */ +var BlockCheck = function () +{ + // Body1 is moving down and Body2 is blocked from going down any further + if (body1MovingDown && body1OnTop && body2.blocked.down) + { + body1.processY(-overlap, body1FullImpact, false, true); - /** - * 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 () + return 1; + } + + // Body1 is moving up and Body2 is blocked from going up any further + if (body1MovingUp && body2OnTop && body2.blocked.up) { - var dx = this.position.x - this.prevFrame.x; - var dy = this.position.y - this.prevFrame.y; + body1.processY(overlap, body1FullImpact, true); - if (this.moves) - { - var mx = this.deltaMax.x; - var my = this.deltaMax.y; + return 1; + } - if (mx !== 0 && dx !== 0) - { - if (dx < 0 && dx < -mx) - { - dx = -mx; - } - else if (dx > 0 && dx > mx) - { - dx = mx; - } - } + // Body2 is moving down and Body1 is blocked from going down any further + if (body2MovingDown && body2OnTop && body1.blocked.down) + { + body2.processY(-overlap, body2FullImpact, false, true); - if (my !== 0 && dy !== 0) - { - if (dy < 0 && dy < -my) - { - dy = -my; - } - else if (dy > 0 && dy > my) - { - dy = my; - } - } + return 2; + } - this.gameObject.x += dx; - this.gameObject.y += dy; - } + // Body2 is moving up and Body1 is blocked from going up any further + if (body2MovingUp && body1OnTop && body1.blocked.up) + { + body2.processY(overlap, body2FullImpact, true); - if (dx < 0) - { - this.facing = CONST.FACING_LEFT; - } - else if (dx > 0) - { - this.facing = CONST.FACING_RIGHT; - } + return 2; + } - if (dy < 0) - { - this.facing = CONST.FACING_UP; - } - else if (dy > 0) - { - this.facing = CONST.FACING_DOWN; - } + return 0; +}; - if (this.allowRotation) - { - this.gameObject.angle += this.deltaZ(); - } +/** + * The main check function. Runs through one of the four possible tests and returns the results. + * + * @function Phaser.Physics.Arcade.ProcessY.Check + * @ignore + * @since 3.50.0 + * + * @return {boolean} `true` if a check passed, otherwise `false`. + */ +var Check = function () +{ + var v1 = body1.velocity.y; + var v2 = body2.velocity.y; - this._tx = dx; - this._ty = dy; - }, + var nv1 = Math.sqrt((v2 * v2 * body2.mass) / body1.mass) * ((v2 > 0) ? 1 : -1); + var nv2 = Math.sqrt((v1 * v1 * body1.mass) / body2.mass) * ((v1 > 0) ? 1 : -1); + var avg = (nv1 + nv2) * 0.5; - /** - * 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) + nv1 -= avg; + nv2 -= avg; + + body1MassImpact = avg + nv1 * body1.bounce.y; + body2MassImpact = avg + nv2 * body2.bounce.y; + + // Body1 hits Body2 on the bottom side + if (body1MovingUp && body2OnTop) { - this.customBoundsRectangle = (!bounds) ? this.world.bounds : bounds; + return Run(0); + } - return this; - }, + // Body2 hits Body1 on the bottom side + if (body2MovingUp && body1OnTop) + { + return Run(1); + } - /** - * 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 () + // Body1 hits Body2 on the top side + if (body1MovingDown && body1OnTop) { - var pos = this.position; - var bounds = this.customBoundsRectangle; - var check = this.world.checkCollision; + return Run(2); + } - var bx = (this.worldBounce) ? -this.worldBounce.x : -this.bounce.x; - var by = (this.worldBounce) ? -this.worldBounce.y : -this.bounce.y; + // Body2 hits Body1 on the top side + if (body2MovingDown && body2OnTop) + { + return Run(3); + } - var wasSet = false; + return false; +}; - if (pos.x < bounds.x && check.left) +/** + * The main check function. Runs through one of the four possible tests and returns the results. + * + * @function Phaser.Physics.Arcade.ProcessY.Run + * @ignore + * @since 3.50.0 + * + * @param {number} side - The side to test. As passed in by the `Check` function. + * + * @return {boolean} Always returns `true`. + */ +var Run = function (side) +{ + if (body1Pushable && body2Pushable) + { + // Both pushable, or both moving at the same time, so equal rebound + overlap *= 0.5; + + if (side === 0 || side === 3) { - pos.x = bounds.x; - this.velocity.x *= bx; - this.blocked.left = true; - wasSet = true; + // body1MovingUp && body2OnTop + // body2MovingDown && body2OnTop + body1.processY(overlap, body1MassImpact); + body2.processY(-overlap, body2MassImpact); } - else if (this.right > bounds.right && check.right) + else { - pos.x = bounds.right - this.width; - this.velocity.x *= bx; - this.blocked.right = true; - wasSet = true; + // body2MovingUp && body1OnTop + // body1MovingDown && body1OnTop + body1.processY(-overlap, body1MassImpact); + body2.processY(overlap, body2MassImpact); } + } + else if (body1Pushable && !body2Pushable) + { + // Body1 pushable, Body2 not - if (pos.y < bounds.y && check.up) + if (side === 0 || side === 3) { - pos.y = bounds.y; - this.velocity.y *= by; - this.blocked.up = true; - wasSet = true; + // body1MovingUp && body2OnTop + // body2MovingDown && body2OnTop + body1.processY(overlap, body1FullImpact, true); } - else if (this.bottom > bounds.bottom && check.down) + else { - pos.y = bounds.bottom - this.height; - this.velocity.y *= by; - this.blocked.down = true; - wasSet = true; + // body2MovingUp && body1OnTop + // body1MovingDown && body1OnTop + body1.processY(-overlap, body1FullImpact, false, true); } + } + else if (!body1Pushable && body2Pushable) + { + // Body2 pushable, Body1 not - if (wasSet) + if (side === 0 || side === 3) { - this.blocked.none = false; - this.updateCenter(); + // body1MovingUp && body2OnTop + // body2MovingDown && body2OnTop + body2.processY(-overlap, body2FullImpact, false, true); } - - 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) + else + { + // body2MovingUp && body1OnTop + // body1MovingDown && body1OnTop + body2.processY(overlap, body2FullImpact, true); + } + } + else { - if (y === undefined) { y = x; } - - this.offset.set(x, y); - - return this; - }, + // Neither body is pushable, so base it on movement - /** - * 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 halfOverlap = overlap * 0.5; - var gameObject = this.gameObject; + if (side === 0) + { + // body1MovingUp && body2OnTop - if (!width && gameObject.frame) + if (body2Stationary) + { + body1.processY(overlap, 0, true); + body2.processY(0, null, false, true); + } + else if (body2MovingDown) + { + body1.processY(halfOverlap, 0, true); + body2.processY(-halfOverlap, 0, false, true); + } + else + { + // Body2 moving same direction as Body1 + body1.processY(halfOverlap, body2.velocity.y, true); + body2.processY(-halfOverlap, null, false, true); + } + } + else if (side === 1) { - width = gameObject.frame.realWidth; + // body2MovingUp && body1OnTop + + if (body1Stationary) + { + body1.processY(0, null, false, true); + body2.processY(overlap, 0, true); + } + else if (body1MovingDown) + { + body1.processY(-halfOverlap, 0, false, true); + body2.processY(halfOverlap, 0, true); + } + else + { + // Body1 moving same direction as Body2 + body1.processY(-halfOverlap, null, false, true); + body2.processY(halfOverlap, body1.velocity.y, true); + } } + else if (side === 2) + { + // body1MovingDown && body1OnTop - if (!height && gameObject.frame) + if (body2Stationary) + { + body1.processY(-overlap, 0, false, true); + body2.processY(0, null, true); + } + else if (body2MovingUp) + { + body1.processY(-halfOverlap, 0, false, true); + body2.processY(halfOverlap, 0, true); + } + else + { + // Body2 moving same direction as Body1 + body1.processY(-halfOverlap, body2.velocity.y, false, true); + body2.processY(halfOverlap, null, true); + } + } + else if (side === 3) { - height = gameObject.frame.realHeight; + // body2MovingDown && body2OnTop + + if (body1Stationary) + { + body1.processY(0, null, true); + body2.processY(-overlap, 0, false, true); + } + else if (body1MovingUp) + { + body1.processY(halfOverlap, 0, true); + body2.processY(-halfOverlap, 0, false, true); + } + else + { + // Body1 moving same direction as Body2 + body1.processY(halfOverlap, body2.velocity.y, true); + body2.processY(-halfOverlap, null, false, true); + } } + } - this.sourceWidth = width; - this.sourceHeight = height; + return true; +}; - this.width = this.sourceWidth * this._sx; - this.height = this.sourceHeight * this._sy; +/** + * This function is run when Body1 is Immovable and Body2 is not. + * + * @function Phaser.Physics.Arcade.ProcessY.RunImmovableBody1 + * @ignore + * @since 3.50.0 + * + * @param {number} blockedState - The block state value. + */ +var RunImmovableBody1 = function (blockedState) +{ + if (blockedState === 1) + { + // But Body2 cannot go anywhere either, so we cancel out velocity + // Separation happened in the block check + body2.velocity.y = 0; + } + else if (body1OnTop) + { + body2.processY(overlap, body2FullImpact, true); + } + else + { + body2.processY(-overlap, body2FullImpact, false, true); + } - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); + // This is special case code that handles things like horizontally moving platforms you can ride + if (body1.moves) + { + body2.x += (body1.x - body1.prev.x) * body1.friction.x; + body2._dx = body2.x - body2.prev.x; + } +}; - this.updateCenter(); +/** + * This function is run when Body2 is Immovable and Body1 is not. + * + * @function Phaser.Physics.Arcade.ProcessY.RunImmovableBody2 + * @ignore + * @since 3.50.0 + * + * @param {number} blockedState - The block state value. + */ +var RunImmovableBody2 = function (blockedState) +{ + if (blockedState === 2) + { + // But Body1 cannot go anywhere either, so we cancel out velocity + // Separation happened in the block check + body1.velocity.y = 0; + } + else if (body2OnTop) + { + body1.processY(overlap, body1FullImpact, true); + } + else + { + body1.processY(-overlap, body1FullImpact, false, true); + } - if (center && gameObject.getCenter) - { - var ox = (gameObject.width - width) / 2; - var oy = (gameObject.height - height) / 2; + // This is special case code that handles things like horizontally moving platforms you can ride + if (body2.moves) + { + body1.x += (body2.x - body2.prev.x) * body2.friction.x; + body1._dx = body1.x - body1.prev.x; + } +}; - this.offset.set(ox, oy); - } +/** + * @namespace Phaser.Physics.Arcade.ProcessY + * @ignore + */ - this.isCircle = false; - this.radius = 0; +module.exports = { + BlockCheck: BlockCheck, + Check: Check, + Set: Set, + Run: Run, + RunImmovableBody1: RunImmovableBody1, + RunImmovableBody2: RunImmovableBody2 +}; - 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; } +/***/ }), + +/***/ 61777: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (radius > 0) - { - this.isCircle = true; - this.radius = radius; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.sourceWidth = radius * 2; - this.sourceHeight = radius * 2; +var GetOverlapX = __webpack_require__(75671); +var ProcessX = __webpack_require__(22916); - this.width = this.sourceWidth * this._sx; - this.height = this.sourceHeight * this._sy; +/** + * 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. + * @param {number} [overlap] - If given then this value will be used as the overlap and no check will be run. + * + * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. + */ +var SeparateX = function (body1, body2, overlapOnly, bias, overlap) +{ + if (overlap === undefined) { overlap = GetOverlapX(body1, body2, overlapOnly, bias); } - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); + var body1Immovable = body1.immovable; + var body2Immovable = body2.immovable; - this.offset.set(offsetX, offsetY); + // 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); + } - this.updateCenter(); - } - else + var blockedState = ProcessX.Set(body1, body2, overlap); + + if (!body1Immovable && !body2Immovable) + { + if (blockedState > 0) { - this.isCircle = false; + return true; } - 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) + return ProcessX.Check(); + } + else if (body1Immovable) { - this.stop(); + ProcessX.RunImmovableBody1(blockedState); + } + else if (body2Immovable) + { + ProcessX.RunImmovableBody2(blockedState); + } - var gameObject = this.gameObject; + // If we got this far then there WAS overlap, and separation is complete, so return true + return true; +}; - gameObject.setPosition(x, y); +module.exports = SeparateX; - 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; +/***/ 25299: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.updateBounds(); - this.updateCenter(); - this.resetFlags(true); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; +var GetOverlapY = __webpack_require__(66185); +var ProcessY = __webpack_require__(67050); - return this; - }, +/** + * 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. + * @param {number} [overlap] - If given then this value will be used as the overlap and no check will be run. + * + * @return {boolean} `true` if the two bodies overlap vertically, otherwise `false`. + */ +var SeparateY = function (body1, body2, overlapOnly, bias, overlap) +{ + if (overlap === undefined) { overlap = GetOverlapY(body1, body2, overlapOnly, bias); } - /** - * 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) + 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) { - obj.x = this.x; - obj.y = this.y; - obj.right = this.right; - obj.bottom = this.bottom; + // return true if there was some overlap, otherwise false + return (overlap !== 0) || (body1.embedded && body2.embedded); + } - return obj; - }, + var blockedState = ProcessY.Set(body1, body2, overlap); - /** - * 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 (!body1Immovable && !body2Immovable) { - if (!this.isCircle) + if (blockedState > 0) { - return RectangleContains(this, x, y); + return true; } - // 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 ProcessY.Check(); + } + else if (body1Immovable) + { + ProcessY.RunImmovableBody1(blockedState); + } + else if (body2Immovable) + { + ProcessY.RunImmovableBody2(blockedState); + } - return false; - }, + // If we got this far then there WAS overlap, and separation is complete, so return true + return true; +}; - /** - * 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; - }, +module.exports = SeparateY; - /** - * 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; - }, +/***/ 66634: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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; - }, +var CircleContains = __webpack_require__(65650); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(47401); +var RectangleContains = __webpack_require__(94287); +var Vector2 = __webpack_require__(93736); - /** - * 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; - }, +/** + * @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 Body belongs to. As of Phaser 3.60 this is now optional. + */ +var StaticBody = new Class({ - /** - * 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; - }, + initialize: - /** - * 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 () + function StaticBody (world, gameObject) { - return this._ty; - }, + var width = 64; + var height = 64; - /** - * 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; - }, + var dummyGameObject = { + x: 0, + y: 0, + angle: 0, + rotation: 0, + scaleX: 1, + scaleY: 1, + displayOriginX: 0, + displayOriginY: 0 + }; - /** - * 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; + var hasGameObject = (gameObject !== undefined); - if (this.world) + if (hasGameObject && gameObject.displayWidth) { - this.world.pendingDestroy.set(this); + width = gameObject.displayWidth; + height = gameObject.displayHeight; } - }, - - /** - * 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) + if (!hasGameObject) { - graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor); + gameObject = dummyGameObject; + } - 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); - } + /** + * 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; - if (this.checkCollision.right) - { - graphic.lineBetween(pos.x + this.width, pos.y, pos.x + this.width, pos.y + this.height); - } + /** + * The Game Object this Static Body belongs to. + * + * As of Phaser 3.60 this is now optional and can be undefined. + * + * @name Phaser.Physics.Arcade.StaticBody#gameObject + * @type {Phaser.GameObjects.GameObject} + * @since 3.0.0 + */ + this.gameObject = (hasGameObject) ? gameObject : undefined; - 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); - } - } - } + /** + * A quick-test flag that signifies this is a Body, used in the World collision handler. + * + * @name Phaser.Physics.Arcade.StaticBody#isBody + * @type {boolean} + * @readonly + * @since 3.60.0 + */ + this.isBody = true; - 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 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; - /** - * 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); - }, + /** + * 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; - /** - * 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; } + /** + * 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; - this.collideWorldBounds = value; + /** + * 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; - var setBounceX = (bounceX !== undefined); - var setBounceY = (bounceY !== undefined); + /** + * 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; - if (setBounceX || setBounceY) - { - if (!this.worldBounce) - { - this.worldBounce = new Vector2(); - } + /** + * 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(); - if (setBounceX) - { - this.worldBounce.x = bounceX; - } + /** + * 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)); - if (setBounceY) - { - this.worldBounce.y = bounceY; - } - } + /** + * 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; - if (onWorldBounds !== undefined) - { - this.onWorldBounds = onWorldBounds; - } + /** + * 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; - return this; - }, + /** + * 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); - /** - * 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); + /** + * 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); - x = this.velocity.x; - y = this.velocity.y; + /** + * 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); - this.speed = Math.sqrt(x * x + y * y); + /** + * 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; - return this; - }, + /** + * 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; - /** - * 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; + /** + * 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; - var x = value; - var y = this.velocity.y; + /** + * 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; - this.speed = Math.sqrt(x * x + y * y); + // If true this Body will dispatch events - return this; - }, + /** + * 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; - /** - * 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; + /** + * 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; - var x = this.velocity.x; - var y = value; + /** + * 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; - this.speed = Math.sqrt(x * x + y * y); + /** + * 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; - return this; - }, + /** + * 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 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); + /** + * 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; - return this; - }, + /** + * 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; - /** - * 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; + /** + * 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; - return this; - }, + /** + * 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; - /** - * 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; + /** + * 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; - return this; - }, + /** + * 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; - /** - * 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; + /** + * 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; - return this; - }, + /** + * 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; - /** - * 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); + /** + * 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 }; - return this; - }, + /** + * 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 }; - /** - * 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; + /** + * 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 }; - return this; - }, + /** + * 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 }; - /** - * 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; + /** + * 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; - return this; + /** + * 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; }, /** - * Sets the Body's acceleration. + * 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.Body#setAcceleration - * @since 3.0.0 + * @method Phaser.Physics.Arcade.StaticBody#setGameObject + * @since 3.1.0 * - * @param {number} x - The horizontal component, in pixels per second squared. - * @param {number} y - The vertical component, in pixels per second squared. + * @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.Body} This Body object. + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * + * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject */ - setAcceleration: function (x, y) + setGameObject: function (gameObject, update) { - this.acceleration.set(x, y); + if (gameObject && gameObject !== this.gameObject) + { + // Remove this body from the old game object + this.gameObject.body = null; - return this; - }, + gameObject.body = 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; + // Update our reference + this.gameObject = gameObject; + } + + if (update) + { + this.updateFromGameObject(); + } return this; }, /** - * Sets the Body's vertical acceleration. - * - * @method Phaser.Physics.Arcade.Body#setAccelerationY - * @since 3.0.0 + * Syncs the Static Body's position and size with its parent Game Object. * - * @param {number} value - The acceleration, in pixels per second squared. + * @method Phaser.Physics.Arcade.StaticBody#updateFromGameObject + * @since 3.1.0 * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. */ - setAccelerationY: function (value) + updateFromGameObject: function () { - this.acceleration.y = value; + this.world.staticTree.remove(this); - return this; - }, + var gameObject = this.gameObject; - /** - * 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; } + gameObject.getTopLeft(this.position); - this.allowDrag = value; + this.width = gameObject.displayWidth; + this.height = gameObject.displayHeight; - return this; - }, + this.halfWidth = Math.abs(this.width / 2); + this.halfHeight = Math.abs(this.height / 2); - /** - * 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.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); - this.allowGravity = value; + this.world.staticTree.insert(this); return this; }, /** - * Enables or disables rotation. + * Positions the Static Body at an offset from its Game Object. * - * @method Phaser.Physics.Arcade.Body#setAllowRotation - * @since 3.9.0 - * @see Phaser.Physics.Arcade.Body#allowRotation + * @method Phaser.Physics.Arcade.StaticBody#setOffset + * @since 3.4.0 * - * @param {boolean} [value=true] - `true` to allow rotation on this body, or `false` to disable it. + * @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.Body} This Body object. + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. */ - setAllowRotation: function (value) + setOffset: function (x, y) { - if (value === undefined) { value = true; } + if (y === undefined) { y = x; } - this.allowRotation = value; + 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 Body's drag. + * 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.Body#setDrag + * @method Phaser.Physics.Arcade.StaticBody#setSize * @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. + * @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.Body} This Body object. + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. */ - setDrag: function (x, y) + setSize: function (width, height, center) { - this.drag.set(x, y); + if (center === undefined) { center = true; } - return this; - }, + var gameObject = this.gameObject; - /** - * 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; + 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 the Body's horizontal drag. + * Sets this Static Body to have a circular body and sets its size and position. * - * @method Phaser.Physics.Arcade.Body#setDragX + * @method Phaser.Physics.Arcade.StaticBody#setCircle * @since 3.0.0 * - * @param {number} value - The drag, in pixels per second squared. + * @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.Body} This Body object. + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. */ - setDragX: function (value) + setCircle: function (radius, offsetX, offsetY) { - this.drag.x = value; + 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; }, /** - * Sets the Body's vertical drag. + * Updates the StaticBody's `center` from its `position` and dimensions. * - * @method Phaser.Physics.Arcade.Body#setDragY + * @method Phaser.Physics.Arcade.StaticBody#updateCenter * @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) + updateCenter: function () { - this.drag.y = value; - - return this; + this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); }, /** - * Sets the Body's gravity. + * Resets this Body to the given coordinates. Also positions its parent Game Object to the same coordinates. * - * @method Phaser.Physics.Arcade.Body#setGravity + * @method Phaser.Physics.Arcade.StaticBody#reset * @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. + * @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. */ - setGravity: function (x, y) + reset: function (x, y) { - this.gravity.set(x, y); + var gameObject = this.gameObject; - return this; + 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); }, /** - * Sets the Body's horizontal gravity. + * NOOP function. A Static Body cannot be stopped. * - * @method Phaser.Physics.Arcade.Body#setGravityX + * @method Phaser.Physics.Arcade.StaticBody#stop * @since 3.0.0 * - * @param {number} value - The gravity, in pixels per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. */ - setGravityX: function (value) + stop: function () { - this.gravity.x = value; - return this; }, /** - * Sets the Body's vertical gravity. + * Returns the x and y coordinates of the top left and bottom right points of the StaticBody. * - * @method Phaser.Physics.Arcade.Body#setGravityY + * @method Phaser.Physics.Arcade.StaticBody#getBounds * @since 3.0.0 * - * @param {number} value - The gravity, in pixels per second squared. + * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - The object which will hold the coordinates of the bounds. * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @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. */ - setGravityY: function (value) + getBounds: function (obj) { - this.gravity.y = value; + obj.x = this.x; + obj.y = this.y; + obj.right = this.right; + obj.bottom = this.bottom; - return this; + return obj; }, /** - * Sets the Body's friction. + * Checks to see if a given x,y coordinate is colliding with this Static Body. * - * @method Phaser.Physics.Arcade.Body#setFriction + * @method Phaser.Physics.Arcade.StaticBody#hitTest * @since 3.0.0 * - * @param {number} x - The horizontal component, relative to 1. - * @param {number} y - The vertical component, relative to 1. + * @param {number} x - The x coordinate to check against this body. + * @param {number} y - The y coordinate to check against this body. * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @return {boolean} `true` if the given coordinate lies within this body, otherwise `false`. */ - setFriction: function (x, y) + hitTest: function (x, y) { - this.friction.set(x, y); - - return this; + return (this.isCircle) ? CircleContains(this, x, y) : RectangleContains(this, x, y); }, /** - * 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. + * NOOP * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @method Phaser.Physics.Arcade.StaticBody#postUpdate + * @since 3.12.0 */ - setFrictionX: function (value) + postUpdate: function () { - this.friction.x = value; - - return this; }, /** - * Sets the Body's vertical friction. + * The absolute (non-negative) change in this StaticBody's horizontal position from the previous step. Always zero. * - * @method Phaser.Physics.Arcade.Body#setFrictionY + * @method Phaser.Physics.Arcade.StaticBody#deltaAbsX * @since 3.0.0 * - * @param {number} value - The friction value, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @return {number} Always zero for a Static Body. */ - setFrictionY: function (value) + deltaAbsX: function () { - this.friction.y = value; - - return this; + return 0; }, /** - * Sets the Body's angular velocity. + * The absolute (non-negative) change in this StaticBody's vertical position from the previous step. Always zero. * - * @method Phaser.Physics.Arcade.Body#setAngularVelocity + * @method Phaser.Physics.Arcade.StaticBody#deltaAbsY * @since 3.0.0 * - * @param {number} value - The velocity, in degrees per second. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @return {number} Always zero for a Static Body. */ - setAngularVelocity: function (value) + deltaAbsY: function () { - this.angularVelocity = value; - - return this; + return 0; }, /** - * Sets the Body's angular acceleration. + * The change in this StaticBody's horizontal position from the previous step. Always zero. * - * @method Phaser.Physics.Arcade.Body#setAngularAcceleration + * @method Phaser.Physics.Arcade.StaticBody#deltaX * @since 3.0.0 * - * @param {number} value - The acceleration, in degrees per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. */ - setAngularAcceleration: function (value) + deltaX: function () { - this.angularAcceleration = value; - - return this; + return 0; }, /** - * Sets the Body's angular drag. + * The change in this StaticBody's vertical position from the previous step. Always zero. * - * @method Phaser.Physics.Arcade.Body#setAngularDrag + * @method Phaser.Physics.Arcade.StaticBody#deltaY * @since 3.0.0 * - * @param {number} value - The drag, in degrees per second squared. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. */ - setAngularDrag: function (value) + deltaY: function () { - this.angularDrag = value; - - return this; + return 0; }, /** - * Sets the Body's mass. + * The change in this StaticBody's rotation from the previous step. Always zero. * - * @method Phaser.Physics.Arcade.Body#setMass + * @method Phaser.Physics.Arcade.StaticBody#deltaZ * @since 3.0.0 * - * @param {number} value - The mass value, relative to 1. - * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @return {number} The change in this StaticBody's rotation from the previous step. Always zero. */ - setMass: function (value) + deltaZ: function () { - this.mass = value; - - return this; + return 0; }, /** - * Sets the Body's `immovable` property. + * Disables this Body and marks it for destruction during the next step. * - * @method Phaser.Physics.Arcade.Body#setImmovable + * @method Phaser.Physics.Arcade.StaticBody#destroy * @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) + destroy: function () { - if (value === undefined) { value = true; } - - this.immovable = value; + this.enable = false; - return this; + this.world.pendingDestroy.set(this); }, /** - * Sets the Body's `enable` property. - * - * @method Phaser.Physics.Arcade.Body#setEnable - * @since 3.15.0 + * Draws a graphical representation of the StaticBody for visual debugging purposes. * - * @param {boolean} [value=true] - The value to assign to `enable`. + * @method Phaser.Physics.Arcade.StaticBody#drawDebug + * @since 3.0.0 * - * @return {Phaser.Physics.Arcade.Body} This Body object. + * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to use for the debug drawing of the StaticBody. */ - setEnable: function (value) + drawDebug: function (graphic) { - if (value === undefined) { value = true; } + var pos = this.position; - this.enable = value; + var x = pos.x + this.halfWidth; + var y = pos.y + this.halfHeight; - return this; + 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); + } + + } }, /** - * This is an internal handler, called by the `ProcessX` function as part - * of the collision step. You should almost never call this directly. + * Indicates whether the StaticBody is going to be showing a debug visualization during postUpdate. * - * @method Phaser.Physics.Arcade.Body#processX - * @since 3.50.0 + * @method Phaser.Physics.Arcade.StaticBody#willDrawDebug + * @since 3.0.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? + * @return {boolean} Whether or not the StaticBody is going to show the debug visualization during postUpdate. */ - processX: function (x, vx, left, right) + willDrawDebug: function () { - 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; - } + return this.debugShowBody; }, /** - * This is an internal handler, called by the `ProcessY` function as part - * of the collision step. You should almost never call this directly. + * 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.Body#processY - * @since 3.50.0 + * @method Phaser.Physics.Arcade.StaticBody#setMass + * @since 3.0.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? + * @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. */ - processY: function (y, vy, up, down) + setMass: function (value) { - this.y += y; - - this.updateCenter(); - - if (vy !== null) + if (value <= 0) { - this.velocity.y = vy; + // Causes havoc otherwise + value = 0.1; } - var blocked = this.blocked; - - if (up) - { - blocked.up = true; - } + this.mass = value; - if (down) - { - blocked.down = true; - } + return this; }, /** - * The Bodys horizontal position (left edge). + * The x coordinate of the StaticBody. * - * @name Phaser.Physics.Arcade.Body#x + * @name Phaser.Physics.Arcade.StaticBody#x * @type {number} * @since 3.0.0 */ @@ -129396,15 +145630,19 @@ var Body = new Class({ set: function (value) { + this.world.staticTree.remove(this); + this.position.x = value; + + this.world.staticTree.insert(this); } }, /** - * The Bodys vertical position (top edge). + * The y coordinate of the StaticBody. * - * @name Phaser.Physics.Arcade.Body#y + * @name Phaser.Physics.Arcade.StaticBody#y * @type {number} * @since 3.0.0 */ @@ -129417,15 +145655,19 @@ var Body = new Class({ set: function (value) { + this.world.staticTree.remove(this); + this.position.y = value; + + this.world.staticTree.insert(this); } }, /** - * The left edge of the Body. Identical to x. + * Returns the left-most x coordinate of the area of the StaticBody. * - * @name Phaser.Physics.Arcade.Body#left + * @name Phaser.Physics.Arcade.StaticBody#left * @type {number} * @readonly * @since 3.0.0 @@ -129440,9 +145682,9 @@ var Body = new Class({ }, /** - * The right edge of the Body. + * The right-most x coordinate of the area of the StaticBody. * - * @name Phaser.Physics.Arcade.Body#right + * @name Phaser.Physics.Arcade.StaticBody#right * @type {number} * @readonly * @since 3.0.0 @@ -129457,9 +145699,9 @@ var Body = new Class({ }, /** - * The top edge of the Body. Identical to y. + * The highest y coordinate of the area of the StaticBody. * - * @name Phaser.Physics.Arcade.Body#top + * @name Phaser.Physics.Arcade.StaticBody#top * @type {number} * @readonly * @since 3.0.0 @@ -129474,9 +145716,9 @@ var Body = new Class({ }, /** - * The bottom edge of this Body. + * The lowest y coordinate of the area of the StaticBody. (y + height) * - * @name Phaser.Physics.Arcade.Body#bottom + * @name Phaser.Physics.Arcade.StaticBody#bottom * @type {number} * @readonly * @since 3.0.0 @@ -129492,12923 +145734,16065 @@ var Body = new Class({ }); -module.exports = Body; +module.exports = StaticBody; /***/ }), -/* 528 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 46346: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); +var ArcadeSprite = __webpack_require__(25084); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(47401); +var GetFastValue = __webpack_require__(72632); +var Group = __webpack_require__(59192); +var IsPlainObject = __webpack_require__(42911); /** * @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. + * An Arcade Physics Static Group object. * - * @class Collider + * 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 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. + * @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 Collider = new Class({ +var StaticPhysicsGroup = new Class({ + + Extends: Group, initialize: - function Collider (world, overlapOnly, object1, object2, collideCallback, processCallback, callbackContext) + function StaticPhysicsGroup (world, scene, children, config) { - /** - * 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; + 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; - /** - * Whether to check for collisions or overlaps. - * - * @name Phaser.Physics.Arcade.Collider#overlapOnly - * @type {boolean} - * @since 3.0.0 - */ - this.overlapOnly = overlapOnly; + 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; - /** - * 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; + 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 second object to check for collision. + * The physics simulation. * - * @name Phaser.Physics.Arcade.Collider#object2 - * @type {Phaser.Types.Physics.Arcade.ArcadeColliderType} + * @name Phaser.Physics.Arcade.StaticGroup#world + * @type {Phaser.Physics.Arcade.World} * @since 3.0.0 */ - this.object2 = object2; + this.world = world; /** - * The callback to invoke when the two objects collide. + * The scene this group belongs to. * - * @name Phaser.Physics.Arcade.Collider#collideCallback - * @type {ArcadePhysicsCallback} + * @name Phaser.Physics.Arcade.StaticGroup#physicsType + * @type {number} + * @default Phaser.Physics.Arcade.STATIC_BODY * @since 3.0.0 */ - this.collideCallback = collideCallback; + this.physicsType = CONST.STATIC_BODY; - /** - * 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; + Group.call(this, scene, children, config); /** - * The context the collideCallback and processCallback will run in. + * 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.Collider#callbackContext - * @type {object} - * @since 3.0.0 + * @name Phaser.Physics.Arcade.StaticGroup#type + * @type {string} + * @default 'StaticPhysicsGroup' + * @since 3.21.0 */ - this.callbackContext = callbackContext; + this.type = 'StaticPhysicsGroup'; }, /** - * A name for the Collider. - * - * Phaser does not use this value, it's for your own reference. + * Adds a static physics body to the new group member (if it lacks one) and adds it to the simulation. * - * @method Phaser.Physics.Arcade.Collider#setName - * @since 3.1.0 + * @method Phaser.Physics.Arcade.StaticGroup#createCallbackHandler + * @since 3.0.0 * - * @param {string} name - The name to assign to the Collider. + * @param {Phaser.GameObjects.GameObject} child - The new group member. * - * @return {Phaser.Physics.Arcade.Collider} This Collider instance. + * @see Phaser.Physics.Arcade.World#enableBody */ - setName: function (name) + createCallbackHandler: function (child) { - this.name = name; - - return this; + if (!child.body) + { + this.world.enableBody(child, CONST.STATIC_BODY); + } }, /** - * Called by World as part of its step processing, initial operation of collision checking. + * Disables the group member's physics body, removing it from the simulation. * - * @method Phaser.Physics.Arcade.Collider#update + * @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 */ - update: function () + removeCallbackHandler: function (child) { - this.world.collideObjects( - this.object1, - this.object2, - this.collideCallback, - this.processCallback, - this.callbackContext, - this.overlapOnly - ); + if (child.body) + { + this.world.disableBody(child); + } }, /** - * Removes Collider from World and disposes of its resources. + * Refreshes the group. * - * @method Phaser.Physics.Arcade.Collider#destroy + * @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 */ - destroy: function () + createMultipleCallbackHandler: function () { - this.world.removeCollider(this); - - this.active = false; + this.refresh(); + }, - this.world = null; + /** + * 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; - this.object1 = null; - this.object2 = null; + for (var i = 0; i < children.length; i++) + { + children[i].body.reset(); + } - this.collideCallback = null; - this.processCallback = null; - this.callbackContext = null; + return this; } }); -module.exports = Collider; - - -/***/ }), -/* 529 */ -/***/ (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; +module.exports = StaticPhysicsGroup; /***/ }), -/* 530 */ -/***/ (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; - -/***/ }), -/* 531 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 85233: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Vladimir Agafonkin * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var quickselect = __webpack_require__(436); +var AngleBetweenPoints = __webpack_require__(94240); +var Body = __webpack_require__(97602); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Collider = __webpack_require__(3909); +var CONST = __webpack_require__(47401); +var DistanceBetween = __webpack_require__(53996); +var DistanceBetweenPoints = __webpack_require__(92951); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(27037); +var FuzzyEqual = __webpack_require__(88456); +var FuzzyGreaterThan = __webpack_require__(41935); +var FuzzyLessThan = __webpack_require__(54726); +var GetOverlapX = __webpack_require__(75671); +var GetOverlapY = __webpack_require__(66185); +var GetTilesWithinWorldXY = __webpack_require__(44662); +var GetValue = __webpack_require__(10850); +var MATH_CONST = __webpack_require__(83392); +var ProcessQueue = __webpack_require__(74623); +var ProcessTileCallbacks = __webpack_require__(25163); +var Rectangle = __webpack_require__(74118); +var RTree = __webpack_require__(68687); +var SeparateTile = __webpack_require__(27354); +var SeparateX = __webpack_require__(61777); +var SeparateY = __webpack_require__(25299); +var Set = __webpack_require__(58403); +var StaticBody = __webpack_require__(66634); +var TileIntersectsBody = __webpack_require__(28808); +var TransformMatrix = __webpack_require__(69360); +var Vector2 = __webpack_require__(93736); +var Wrap = __webpack_require__(1071); /** * @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. + * The Arcade Physics World. * - * 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). + * The World is responsible for creating, managing, colliding and updating all of the bodies within it. * - * 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 + * An instance of the World belongs to a Phaser.Scene and is accessed via the property `physics.world`. * - * @class RTree - * @memberof Phaser.Structs + * @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({ -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; - }, + Extends: EventEmitter, - insert: function (item) - { - if (item) this._insert(item, this.data.height - 1); - return this; - }, + initialize: - clear: function () + function World (scene, config) { - this.data = createNode([]); - return this; - }, + EventEmitter.call(this); - remove: function (item, equalsFn) - { - if (!item) return this; + /** + * The Scene this simulation belongs to. + * + * @name Phaser.Physics.Arcade.World#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - var node = this.data, - bbox = this.toBBox(item), - path = [], - indexes = [], - i, parent, index, goingUp; + /** + * Dynamic Bodies in this simulation. + * + * @name Phaser.Physics.Arcade.World#bodies + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.bodies = new Set(); - // depth-first iterative tree traversal - while (node || path.length) { + /** + * Static Bodies in this simulation. + * + * @name Phaser.Physics.Arcade.World#staticBodies + * @type {Phaser.Structs.Set.} + * @since 3.0.0 + */ + this.staticBodies = new Set(); - if (!node) { // go up - node = path.pop(); - parent = path[path.length - 1]; - i = indexes.pop(); - goingUp = true; - } + /** + * 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(); - if (node.leaf) { // check current node - index = findItem(item, node.children, equalsFn); + /** + * This simulation's collision processors. + * + * @name Phaser.Physics.Arcade.World#colliders + * @type {Phaser.Structs.ProcessQueue.} + * @since 3.0.0 + */ + this.colliders = new ProcessQueue(); - 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; - } - } + /** + * 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)); - if (!goingUp && !node.leaf && contains(node, bbox)) { // go down - path.push(node); - indexes.push(i); - i = 0; - parent = node; - node = node.children[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) + ); - } else if (parent) { // go right - i++; - node = parent.children[i]; - goingUp = false; + /** + * 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) + }; - } else node = null; // nothing found - } + /** + * 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); - return this; - }, + /** + * 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); - toBBox: function (item) { return item; }, + /** + * 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; - compareMinX: compareNodeMinX, - compareMinY: compareNodeMinY, + /** + * Internal frame time value. + * + * @name Phaser.Physics.Arcade.World#_frameTime + * @private + * @type {number} + * @since 3.10.0 + */ + this._frameTime = 1 / this.fps; - toJSON: function () { return this.data; }, + /** + * Internal frame time ms value. + * + * @name Phaser.Physics.Arcade.World#_frameTimeMS + * @private + * @type {number} + * @since 3.10.0 + */ + this._frameTimeMS = 1000 * this._frameTime; - fromJSON: function (data) - { - this.data = data; - return this; - }, + /** + * 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; - _all: function (node, result) - { - var nodesToSearch = []; - while (node) { - if (node.leaf) result.push.apply(result, node.children); - else nodesToSearch.push.apply(nodesToSearch, node.children); + /** + * 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); - node = nodesToSearch.pop(); - } - return result; - }, + /** + * 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); - _build: function (items, left, right, height) - { - var N = right - left + 1, - M = this._maxEntries, - node; + /** + * 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); - if (N <= M) { - // reached leaf level; return leaf - node = createNode(items.slice(left, right + 1)); - calcBBox(node, this.toBBox); - return node; - } + /** + * 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); - if (!height) { - // target height of the bulk-loaded tree - height = Math.ceil(Math.log(N) / Math.log(M)); + /** + * 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); - // target number of root entries to maximize storage utilization - M = Math.ceil(N / Math.pow(M, height - 1)); - } + /** + * Temporary total of colliding Bodies. + * + * @name Phaser.Physics.Arcade.World#_total + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._total = 0; - node = createNode([]); - node.leaf = false; - node.height = height; + /** + * Enables the debug display. + * + * @name Phaser.Physics.Arcade.World#drawDebug + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.drawDebug = GetValue(config, 'debug', false); - // split the items into M mostly square tiles + /** + * The graphics object drawing the debug display. + * + * @name Phaser.Physics.Arcade.World#debugGraphic + * @type {Phaser.GameObjects.Graphics} + * @since 3.0.0 + */ + this.debugGraphic; - var N2 = Math.ceil(N / M), - N1 = N2 * Math.ceil(Math.sqrt(M)), - i, j, right2, right3; + /** + * 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) + }; - multiSelect(items, left, right, N1, this.compareMinX); + /** + * 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); - for (i = left; i <= right; i += N1) { + /** + * 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); - right2 = Math.min(i + N1 - 1, right); + /** + * 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); - multiSelect(items, i, right2, N2, this.compareMinY); + /** + * 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); - for (j = i; j <= right2; j += N2) { + /** + * 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 }; - right3 = Math.min(j + N2 - 1, right2); + /** + * 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(); - // pack each entry recursively - node.children.push(this._build(items, j, right3, height - 1)); - } - } + /** + * 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(); - calcBBox(node, this.toBBox); + /** + * The Filtering Options passed to `GetTilesWithinWorldXY` as part of the `collideSpriteVsTilemapLayer` check. + * + * @name Phaser.Physics.Arcade.World#tileFilterOptions + * @type {Phaser.Types.Tilemaps.FilteringOptions} + * @since 3.60.0 + */ + this.tileFilterOptions = { isColliding: true, isNotEmpty: true, hasInterestingFace: true }; - return node; + if (this.drawDebug) + { + this.createDebugGraphic(); + } }, - _chooseSubtree: function (bbox, node, level, path) + /** + * 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) { - var i, len, child, targetNode, area, enlargement, minArea, minEnlargement; - - while (true) { - path.push(node); + if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } - if (node.leaf || path.length - 1 === level) break; + if (!Array.isArray(object)) + { + object = [ object ]; + } - minArea = minEnlargement = Infinity; + for (var i = 0; i < object.length; i++) + { + var entry = object[i]; - for (i = 0, len = node.children.length; i < len; i++) { - child = node.children[i]; - area = bboxArea(child); - enlargement = enlargedArea(bbox, child) - area; + if (entry.isParent) + { + var children = entry.getChildren(); - // choose entry with the least area enlargement - if (enlargement < minEnlargement) { - minEnlargement = enlargement; - minArea = area < minArea ? area : minArea; - targetNode = child; + for (var c = 0; c < children.length; c++) + { + var child = children[c]; - } else if (enlargement === minEnlargement) { - // otherwise choose one with the smallest area - if (area < minArea) { - minArea = area; - targetNode = child; + if (child.isParent) + { + // Handle Groups nested inside of Groups + this.enable(child, bodyType); + } + else + { + this.enableBody(child, bodyType); } } } - - node = targetNode || node.children[0]; + else + { + this.enableBody(entry, bodyType); + } } - - return node; }, - _insert: function (item, level, isNode) + /** + * 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) { - 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); + if (bodyType === undefined) { bodyType = CONST.DYNAMIC_BODY; } - // put the item into the node - node.children.push(item); - extend(node, bbox); + if (object.hasTransformComponent) + { + 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); + } + } - // 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; + this.add(object.body); } - // adjust bboxes along the insertion path - this._adjustParentBBoxes(bbox, insertPath, level); + return object; }, - // split overflowed node into two - _split: function (insertPath, level) + /** + * 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) { - 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; + if (body.physicsType === CONST.DYNAMIC_BODY) + { + this.bodies.set(body); + } + else if (body.physicsType === CONST.STATIC_BODY) + { + this.staticBodies.set(body); - calcBBox(node, this.toBBox); - calcBBox(newNode, this.toBBox); + this.staticTree.insert(body); + } - if (level) insertPath[level - 1].children.push(newNode); - else this._splitRoot(node, newNode); - }, + body.enable = true; - _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); + return body; }, - _chooseSplitIndex: function (node, m, M) + /** + * 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) { - 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); + if (!Array.isArray(object)) + { + object = [ object ]; + } - overlap = intersectionArea(bbox1, bbox2); - area = bboxArea(bbox1) + bboxArea(bbox2); + for (var i = 0; i < object.length; i++) + { + var entry = object[i]; - // choose distribution with minimum overlap - if (overlap < minOverlap) { - minOverlap = overlap; - index = i; + if (entry.isParent) + { + var children = entry.getChildren(); - minArea = area < minArea ? area : minArea; + for (var c = 0; c < children.length; c++) + { + var child = children[c]; - } else if (overlap === minOverlap) { - // otherwise choose distribution with minimum area - if (area < minArea) { - minArea = area; - index = i; + if (child.isParent) + { + // Handle Groups nested inside of Groups + this.disable(child); + } + else + { + this.disableBody(child.body); + } } } + else + { + this.disableBody(entry.body); + } } - - return index; }, - // sorts node children by the best axis for split - _chooseSplitAxis: function (node, m, M) + /** + * 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) { - 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); + this.remove(body); - // 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); + body.enable = false; }, - // total margin of all possible split distributions where each node is at least m full - _allDistMargin: function (node, m, M, compare) + /** + * 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) { - 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); + if (body.physicsType === CONST.DYNAMIC_BODY) + { + this.tree.remove(body); + this.bodies.delete(body); } - - 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); + else if (body.physicsType === CONST.STATIC_BODY) + { + this.staticBodies.delete(body); + this.staticTree.remove(body); } }, - _condense: function (path) + /** + * 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 () { - // 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); + var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 }); - } else this.clear(); + graphic.setDepth(Number.MAX_VALUE); - } else calcBBox(path[i], this.toBBox); - } - }, + this.debugGraphic = graphic; - compareMinX: function (a, b) - { - return a.left - b.left; - }, + this.drawDebug = true; - compareMinY: function (a, b) - { - return a.top - b.top; + return graphic; }, - toBBox: function (a) + /** + * 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) { - 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; -} + this.bounds.setTo(x, y, width, height); -// calculate node's bbox from bboxes of its children -function calcBBox (node, toBBox) -{ - distBBox(node, 0, node.children.length, toBBox, node); -} + if (checkLeft !== undefined) + { + this.setBoundsCollision(checkLeft, checkRight, checkUp, checkDown); + } -// 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; + return this; + }, - for (var i = k, child; i < p; i++) { - child = node.children[i]; - extend(destNode, node.leaf ? toBBox(child) : child); - } + /** + * 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; } - return destNode; -} + this.checkCollision.left = left; + this.checkCollision.right = right; + this.checkCollision.up = up; + this.checkCollision.down = down; -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; -} + return this; + }, -function compareNodeMinX (a, b) { return a.minX - b.minX; } -function compareNodeMinY (a, b) { return a.minY - b.minY; } + /** + * 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; -function bboxArea (a) { return (a.maxX - a.minX) * (a.maxY - a.minY); } -function bboxMargin (a) { return (a.maxX - a.minX) + (a.maxY - a.minY); } + this.emit(Events.PAUSE); -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)); -} + return this; + }, -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); + /** + * 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; - return Math.max(0, maxX - minX) * - Math.max(0, maxY - minY); -} + this.emit(Events.RESUME); -function contains (a, b) -{ - return a.minX <= b.minX && - a.minY <= b.minY && - b.maxX <= a.maxX && - b.maxY <= a.maxY; -} + return this; + }, -function intersects (a, b) -{ - return b.minX <= a.maxX && - b.minY <= a.maxY && - b.maxX >= a.minX && - b.maxY >= a.minY; -} + /** + * 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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide. + * @param {Phaser.Types.Physics.Arcade.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; } -function createNode (children) -{ - return { - children: children, - height: 1, - leaf: true, - minX: Infinity, - minY: Infinity, - maxX: -Infinity, - maxY: -Infinity - }; -} + var collider = new Collider(this, false, object1, object2, collideCallback, processCallback, callbackContext); -// 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 + this.colliders.add(collider); -function multiSelect (arr, left, right, n, compare) -{ - var stack = [left, right], - mid; + return collider; + }, - while (stack.length) + /** + * 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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects overlap. + * @param {Phaser.Types.Physics.Arcade.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) { - right = stack.pop(); - left = stack.pop(); - - if (right - left <= n) continue; + if (collideCallback === undefined) { collideCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = collideCallback; } - mid = left + Math.ceil((right - left) / n / 2) * n; - quickselect(arr, mid, left, right, compare); + var collider = new Collider(this, true, object1, object2, collideCallback, processCallback, callbackContext); - stack.push(left, mid, mid, right); - } -} + this.colliders.add(collider); -module.exports = rbush; + return collider; + }, -/***/ }), -/* 532 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var TileCheckX = __webpack_require__(533); -var TileCheckY = __webpack_require__(535); -var TileIntersectsBody = __webpack_require__(248); + /** + * 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; -/** - * 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; + return this; + }, - if (!isLayer) + /** + * 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) { - faceHorizontal = true; - faceVertical = true; - } + if (this.isPaused || this.bodies.size === 0) + { + return; + } - // 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 i; + var fixedDelta = this._frameTime; + var msPerFrame = this._frameTimeMS * this.timeScale; - var ox = 0; - var oy = 0; - var minX = 0; - var minY = 1; + this._elapsed += delta; - 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; - } + // Update all active bodies + var body; + var bodies = this.bodies.entries; - 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)); - } + // Will a step happen this frame? + var willStep = (this._elapsed >= msPerFrame); - if (minX < minY) - { - if (faceHorizontal) + if (!this.fixedStep) { - 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; - } + fixedDelta = delta * 0.001; + willStep = true; + this._elapsed = 0; } - if (faceVertical) - { - oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); - } - } - else - { - if (faceVertical) + for (i = 0; i < bodies.length; i++) { - oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); + body = bodies[i]; - // That's vertical done, check if we still intersects? If not then we can return now - if (oy !== 0 && !TileIntersectsBody(tileWorldRect, body)) + if (body.enable) { - return true; + body.preUpdate(willStep, fixedDelta); } } - if (faceHorizontal) + // We know that a step will happen this frame, so let's bundle it all together to save branching and iteration costs + if (willStep) { - ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); - } - } - - return (ox !== 0 || oy !== 0); -}; - -module.exports = SeparateTile; - - -/***/ }), -/* 533 */ -/***/ (function(module, exports, __webpack_require__) { + this._elapsed -= msPerFrame; + this.stepsLastFrame = 1; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Optionally populate our dynamic collision tree + if (this.useTree) + { + this.tree.clear(); + this.tree.load(bodies); + } -var ProcessTileSeparationX = __webpack_require__(534); + // Process any colliders + var colliders = this.colliders.update(); -/** - * 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; + for (i = 0; i < colliders.length; i++) + { + var collider = colliders[i]; - var faceLeft = tile.faceLeft; - var faceRight = tile.faceRight; - var collideLeft = tile.collideLeft; - var collideRight = tile.collideRight; + if (collider.active) + { + collider.update(); + } + } - if (!isLayer) - { - faceLeft = true; - faceRight = true; - collideLeft = true; - collideRight = true; - } + this.emit(Events.WORLD_STEP, fixedDelta); + } - if (body.deltaX() < 0 && collideRight && body.checkCollision.left) - { - // Body is moving LEFT - if (faceRight && body.x < tileRight) + // Process any additional steps this frame + while (this._elapsed >= msPerFrame) { - ox = body.x - tileRight; + this._elapsed -= msPerFrame; - if (ox < -tileBias) - { - ox = 0; - } + this.step(fixedDelta); } - } - else if (body.deltaX() > 0 && collideLeft && body.checkCollision.right) + }, + + /** + * 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) { - // Body is moving RIGHT - if (faceLeft && body.right > tileLeft) + // Update all active bodies + var i; + var body; + var bodies = this.bodies.entries; + var len = bodies.length; + + for (i = 0; i < len; i++) { - ox = body.right - tileLeft; + body = bodies[i]; - if (ox > tileBias) + if (body.enable) { - ox = 0; + body.update(delta); } } - } - if (ox !== 0) - { - if (body.customSeparateX) - { - body.overlapX = ox; - } - else + // Optionally populate our dynamic collision tree + if (this.useTree) { - ProcessTileSeparationX(body, ox); + this.tree.clear(); + this.tree.load(bodies); } - } - - return ox; -}; - -module.exports = TileCheckX; + // Process any colliders + var colliders = this.colliders.update(); -/***/ }), -/* 534 */ -/***/ (function(module, exports) { + for (i = 0; i < colliders.length; i++) + { + var collider = colliders[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (collider.active) + { + collider.update(); + } + } -/** - * 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; - } + this.emit(Events.WORLD_STEP, delta); - body.position.x -= x; + this.stepsLastFrame++; + }, - if (body.bounce.x === 0) - { - body.velocity.x = 0; - } - else + /** + * Updates bodies, draws the debug display, and handles pending queue operations. + * + * @method Phaser.Physics.Arcade.World#postUpdate + * @since 3.0.0 + */ + postUpdate: function () { - body.velocity.x = -body.velocity.x * body.bounce.x; - } -}; + var i; + var body; + var bodies = this.bodies.entries; + var len = bodies.length; -module.exports = ProcessTileSeparationX; + 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; -/***/ }), -/* 535 */ -/***/ (function(module, exports, __webpack_require__) { + for (i = 0; i < len; i++) + { + body = bodies[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (body.enable) + { + body.postUpdate(); + } + } + } -var ProcessTileSeparationY = __webpack_require__(536); + if (this.drawDebug) + { + var graphics = this.debugGraphic; -/** - * 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; + graphics.clear(); - var faceTop = tile.faceTop; - var faceBottom = tile.faceBottom; - var collideUp = tile.collideUp; - var collideDown = tile.collideDown; + for (i = 0; i < len; i++) + { + body = bodies[i]; - if (!isLayer) - { - faceTop = true; - faceBottom = true; - collideUp = true; - collideDown = true; - } + if (body.willDrawDebug()) + { + body.drawDebug(graphics); + } + } - if (body.deltaY() < 0 && collideDown && body.checkCollision.up) - { - // Body is moving UP - if (faceBottom && body.y < tileBottom) - { - oy = body.y - tileBottom; + bodies = staticBodies.entries; + len = bodies.length; - if (oy < -tileBias) + for (i = 0; i < len; i++) { - oy = 0; + body = bodies[i]; + + if (body.willDrawDebug()) + { + body.drawDebug(graphics); + } } } - } - else if (body.deltaY() > 0 && collideUp && body.checkCollision.down) - { - // Body is moving DOWN - if (faceTop && body.bottom > tileTop) + + var pending = this.pendingDestroy; + + if (pending.size > 0) { - oy = body.bottom - tileTop; + var dynamicTree = this.tree; + var staticTree = this.staticTree; - if (oy > tileBias) + bodies = pending.entries; + len = bodies.length; + + for (i = 0; i < len; i++) { - oy = 0; + 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(); } - } + }, - if (oy !== 0) + /** + * 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.customSeparateY) - { - body.overlapY = oy; - } - else + if (body.allowRotation) { - ProcessTileSeparationY(body, oy); + this.computeAngularVelocity(body, delta); } - } - return oy; -}; + this.computeVelocity(body, delta); + }, -module.exports = TileCheckY; + /** + * 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; -/***/ }), -/* 536 */ -/***/ (function(module, exports) { + if (FuzzyGreaterThan(velocity - drag, 0, 0.1)) + { + velocity -= drag; + } + else if (FuzzyLessThan(velocity + drag, 0, 0.1)) + { + velocity += drag; + } + else + { + velocity = 0; + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + velocity = Clamp(velocity, -max, max); -/** - * 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; - } + var velocityDelta = velocity - body.angularVelocity; - body.position.y -= y; + body.angularVelocity += velocityDelta; + body.rotation += (body.angularVelocity * delta); + }, - if (body.bounce.y === 0) - { - body.velocity.y = 0; - } - else + /** + * 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) { - body.velocity.y = -body.velocity.y * body.bounce.y; - } -}; - -module.exports = ProcessTileSeparationY; + 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; -/***/ }), -/* 537 */ -/***/ (function(module, exports, __webpack_require__) { + var speed = body.speed; + var maxSpeed = body.maxSpeed; + var allowDrag = body.allowDrag; + var useDamping = body.useDamping; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (body.allowGravity) + { + velocityX += (this.gravity.x + body.gravity.x) * delta; + velocityY += (this.gravity.y + body.gravity.y) * delta; + } -var GetOverlapX = __webpack_require__(246); -var ProcessX = __webpack_require__(1389); + if (accelerationX) + { + velocityX += accelerationX * delta; + } + else if (allowDrag && dragX) + { + if (useDamping) + { + // Damping based deceleration + dragX = Math.pow(dragX, delta); -/** - * 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); + velocityX *= dragX; - var body1Immovable = body1.immovable; - var body2Immovable = body2.immovable; + speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); - // 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); - } + if (FuzzyEqual(speed, 0, 0.001)) + { + velocityX = 0; + } + } + else + { + // Linear deceleration + dragX *= delta; - var blockedState = ProcessX.Set(body1, body2, overlap); + if (FuzzyGreaterThan(velocityX - dragX, 0, 0.01)) + { + velocityX -= dragX; + } + else if (FuzzyLessThan(velocityX + dragX, 0, 0.01)) + { + velocityX += dragX; + } + else + { + velocityX = 0; + } + } + } - if (!body1Immovable && !body2Immovable) - { - if (blockedState > 0) + if (accelerationY) { - return true; + velocityY += accelerationY * delta; } + else if (allowDrag && dragY) + { + if (useDamping) + { + // Damping based deceleration + dragY = Math.pow(dragY, delta); - 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; -}; + velocityY *= dragY; -module.exports = SeparateX; + speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY); + if (FuzzyEqual(speed, 0, 0.001)) + { + velocityY = 0; + } + } + else + { + // Linear deceleration + dragY *= delta; -/***/ }), -/* 538 */ -/***/ (function(module, exports, __webpack_require__) { + if (FuzzyGreaterThan(velocityY - dragY, 0, 0.01)) + { + velocityY -= dragY; + } + else if (FuzzyLessThan(velocityY + dragY, 0, 0.01)) + { + velocityY += dragY; + } + else + { + velocityY = 0; + } + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + velocityX = Clamp(velocityX, -maxX, maxX); + velocityY = Clamp(velocityY, -maxY, maxY); -var GetOverlapY = __webpack_require__(247); -var ProcessY = __webpack_require__(1390); + body.velocity.set(velocityX, velocityY); -/** - * 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); + if (maxSpeed > -1 && body.velocity.length() > maxSpeed) + { + body.velocity.normalize().scale(maxSpeed); + speed = maxSpeed; + } - var body1Immovable = body1.immovable; - var body2Immovable = body2.immovable; + body.speed = speed; + }, - // 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) + /** + * 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 {Phaser.Types.Physics.Arcade.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? + * + * @return {boolean} True if separation occurred, otherwise false. + */ + separate: function (body1, body2, processCallback, callbackContext, overlapOnly) { - // return true if there was some overlap, otherwise false - return (overlap !== 0) || (body1.embedded && body2.embedded); - } + var overlapX; + var overlapY; - var blockedState = ProcessY.Set(body1, body2, overlap); + var result = false; + var runSeparation = true; - if (!body1Immovable && !body2Immovable) - { - if (blockedState > 0) + if ( + !body1.enable || + !body2.enable || + body1.checkCollision.none || + body2.checkCollision.none || + !this.intersects(body1, body2)) { - return true; + return result; } - 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; -}; + // 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 result; + } -module.exports = SeparateY; + // Circle vs. Circle, or Circle vs. Rect + if (body1.isCircle || body2.isCircle) + { + var circleResults = this.separateCircle(body1, body2, overlapOnly); + if (circleResults.result) + { + // We got a satisfactory result from the separateCircle method + result = true; + runSeparation = false; + } + else + { + // Further processing required + overlapX = circleResults.x; + overlapY = circleResults.y; + runSeparation = true; + } + } -/***/ }), -/* 539 */ -/***/ (function(module, exports, __webpack_require__) { + if (runSeparation) + { + var resultX = false; + var resultY = false; + var bias = this.OVERLAP_BIAS; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // 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, bias, overlapX); + resultY = SeparateY(body1, body2, overlapOnly, bias, overlapY); + } + 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, bias, overlapX); -var CircleContains = __webpack_require__(66); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(62); -var RectangleContains = __webpack_require__(57); -var Vector2 = __webpack_require__(3); + // Are they still intersecting? Let's do the other axis then + if (this.intersects(body1, body2)) + { + resultY = SeparateY(body1, body2, overlapOnly, bias, overlapY); + } + } + else + { + resultY = SeparateY(body1, body2, overlapOnly, bias, overlapY); -/** - * @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({ + // Are they still intersecting? Let's do the other axis then + if (this.intersects(body1, body2)) + { + resultX = SeparateX(body1, body2, overlapOnly, bias, overlapX); + } + } - initialize: + result = (resultX || resultY); + } - function StaticBody (world, gameObject) - { - var width = (gameObject.displayWidth) ? gameObject.displayWidth : 64; - var height = (gameObject.displayHeight) ? gameObject.displayHeight : 64; + 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); + } + } - /** - * 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; + return result; + }, - /** - * 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; + /** + * 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? + * + * @return {boolean} True if separation occurred, otherwise false. + */ + separateCircle: function (body1, body2, overlapOnly) + { + // Set the AABB overlap, blocked and touching values into the bodies (we don't use the return values here) + GetOverlapX(body1, body2, false, 0); + GetOverlapY(body1, body2, false, 0); - /** - * 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; + var body1IsCircle = body1.isCircle; + var body2IsCircle = body2.isCircle; + var body1Center = body1.center; + var body2Center = body2.center; + var body1Immovable = body1.immovable; + var body2Immovable = body2.immovable; + var body1Velocity = body1.velocity; + var body2Velocity = body2.velocity; - /** - * 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; + var overlap = 0; + var twoCircles = true; - /** - * 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; + if (body1IsCircle !== body2IsCircle) + { + twoCircles = false; - /** - * 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; + var circleX = body1Center.x; + var circleY = body1Center.y; + var circleRadius = body1.halfWidth; - /** - * 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; + var rectX = body2.position.x; + var rectY = body2.position.y; + var rectRight = body2.right; + var rectBottom = body2.bottom; - /** - * 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(); + if (body2IsCircle) + { + circleX = body2Center.x; + circleY = body2Center.y; + circleRadius = body2.halfWidth; - /** - * 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)); + rectX = body1.position.x; + rectY = body1.position.y; + rectRight = body1.right; + rectBottom = body1.bottom; + } - /** - * 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; + if (circleY < rectY) + { + if (circleX < rectX) + { + overlap = DistanceBetween(circleX, circleY, rectX, rectY) - circleRadius; + } + else if (circleX > rectRight) + { + overlap = DistanceBetween(circleX, circleY, rectRight, rectY) - circleRadius; + } + } + else if (circleY > rectBottom) + { + if (circleX < rectX) + { + overlap = DistanceBetween(circleX, circleY, rectX, rectBottom) - circleRadius; + } + else if (circleX > rectRight) + { + overlap = DistanceBetween(circleX, circleY, rectRight, rectBottom) - circleRadius; + } + } - /** - * 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; + // If a collision occurs in the corner points of the rectangle + // then the bodies behave like circles + overlap *= -1; + } + else + { + overlap = (body1.halfWidth + body2.halfWidth) - DistanceBetweenPoints(body1Center, body2Center); + } - /** - * 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); + body1.overlapR = overlap; + body2.overlapR = overlap; - /** - * 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); + var angle = AngleBetweenPoints(body1Center, body2Center); + var overlapX = (overlap + MATH_CONST.EPSILON) * Math.cos(angle); + var overlapY = (overlap + MATH_CONST.EPSILON) * Math.sin(angle); - /** - * 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); + var results = { overlap: overlap, result: false, x: overlapX, y: overlapY }; - /** - * 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; + // We know the AABBs already intersect before we enter this method + if (overlapOnly && (!twoCircles || (twoCircles && overlap !== 0))) + { + // Now we know the rect vs circle overlaps, or two circles do + results.result = true; - /** - * 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; + return results; + } - /** - * 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; + // Can't separate (in this method): + // Two immovable bodies + // A body with its own custom separation logic + // A circle vs. a rect with a face-on collision + if ((!twoCircles && overlap === 0) || (body1Immovable && body2Immovable) || body1.customSeparateX || body2.customSeparateX) + { + // Let SeparateX / SeparateY handle this + results.x = undefined; + results.y = undefined; - /** - * 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; + return results; + } - // If true this Body will dispatch events + // If we get this far we either have circle vs. circle + // or circle vs. rect with corner collision - /** - * 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; + var deadlock = (!body1.pushable && !body2.pushable); - /** - * 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; + if (twoCircles) + { + var dx = body1Center.x - body2Center.x; + var dy = body1Center.y - body2Center.y; + var d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + var nx = ((body2Center.x - body1Center.x) / d) || 0; + var ny = ((body2Center.y - body1Center.y) / d) || 0; + var p = 2 * (body1Velocity.x * nx + body1Velocity.y * ny - body2Velocity.x * nx - body2Velocity.y * ny) / (body1.mass + body2.mass); - /** - * 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; + if (body1Immovable || body2Immovable) + { + p *= 2; + } - /** - * 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; + if (!body1Immovable) + { + body1Velocity.x = (body1Velocity.x - p / body1.mass * nx); + body1Velocity.y = (body1Velocity.y - p / body1.mass * ny); + body1Velocity.multiply(body1.bounce); + } - /** - * 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; + if (!body2Immovable) + { + body2Velocity.x = (body2Velocity.x + p / body2.mass * nx); + body2Velocity.y = (body2Velocity.y + p / body2.mass * ny); + body2Velocity.multiply(body2.bounce); + } - /** - * 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; + if (!body1Immovable && !body2Immovable) + { + overlapX *= 0.5; + overlapY *= 0.5; + } - /** - * 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; + if (!body1Immovable) + { + body1.x -= overlapX; + body1.y -= overlapY; - /** - * 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; + body1.updateCenter(); + } - /** - * 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; + if (!body2Immovable) + { + body2.x += overlapX; + body2.y += overlapY; - /** - * 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; + body2.updateCenter(); + } - /** - * 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; + results.result = true; + } + else + { + // Circle vs. Rect + // We'll only move the circle (if we can) and let + // the runSeparation handle the rectangle - /** - * 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; + if (!body1Immovable || body1.pushable || deadlock) + { + body1.x -= overlapX; + body1.y -= overlapY; - /** - * 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; + body1.updateCenter(); + } + else if (!body2Immovable || body2.pushable || deadlock) + { + body2.x += overlapX; + body2.y += overlapY; - /** - * 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 }; + body2.updateCenter(); + } - /** - * 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 }; + // Let SeparateX / SeparateY handle this further + results.x = undefined; + results.y = undefined; + } - /** - * 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 }; + return results; + }, - /** - * 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 }; + /** + * 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; + } - /** - * 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; + if (!body1.isCircle && !body2.isCircle) + { + // Rect vs. Rect + return !( + body1.right <= body2.left || + body1.bottom <= body2.top || + body1.left >= body2.right || + body1.top >= body2.bottom + ); + } + else if (body1.isCircle) + { + if (body2.isCircle) + { + // Circle vs. Circle + return DistanceBetweenPoints(body1.center, body2.center) <= (body1.halfWidth + body2.halfWidth); + } + else + { + // Circle vs. Rect + return this.circleBodyIntersects(body1, body2); + } + } + else + { + // Rect vs. Circle + return this.circleBodyIntersects(body2, body1); + } + }, - /** - * 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; + /** + * 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); - /** - * 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; + 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); }, /** - * 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. + * Tests if Game Objects overlap. * - * @method Phaser.Physics.Arcade.StaticBody#setGameObject - * @since 3.1.0 + * See details in {@link Phaser.Physics.Arcade.World#collide}. * - * @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? + * @method Phaser.Physics.Arcade.World#overlap + * @since 3.0.0 * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * @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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the objects overlap. + * @param {Phaser.Types.Physics.Arcade.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. * - * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject + * @return {boolean} True if at least one Game Object overlaps another. + * + * @see Phaser.Physics.Arcade.World#collide */ - setGameObject: function (gameObject, update) + overlap: function (object1, object2, overlapCallback, processCallback, callbackContext) { - if (gameObject && gameObject !== this.gameObject) + 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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. + * @param {Phaser.Types.Physics.Arcade.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 || object2 === undefined || object1 === object2)) { - // Remove this body from the old game object - this.gameObject.body = null; + object1 = object1.children.entries; + } - gameObject.body = this; + if (object2 && object2.isParent && object2.physicsType === undefined) + { + object2 = object2.children.entries; + } - // Update our reference - this.gameObject = gameObject; + 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]; - if (update) + 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 { - this.updateFromGameObject(); + // 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; + return (this._total > 0); }, /** - * Syncs the Static Body's position and size with its parent Game Object. + * Internal helper function. Please use Phaser.Physics.Arcade.World#collide and Phaser.Physics.Arcade.World#overlap instead. * - * @method Phaser.Physics.Arcade.StaticBody#updateFromGameObject - * @since 3.1.0 + * @method Phaser.Physics.Arcade.World#collideHandler + * @private + * @since 3.0.0 * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * @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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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. */ - updateFromGameObject: function () + collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) { - this.world.staticTree.remove(this); + // Collide Group with Self + // Only collide valid objects + if (object2 === undefined && object1.isParent) + { + return this.collideGroupVsGroup(object1, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } - var gameObject = this.gameObject; + // If neither of the objects are set then bail out + if (!object1 || !object2) + { + return false; + } - gameObject.getTopLeft(this.position); + // SPRITE + if (object1.body || object1.isBody) + { + if (object2.body || object2.isBody) + { + 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); + } + } - this.width = gameObject.displayWidth; - this.height = gameObject.displayHeight; + // GROUPS + else if (object1.isParent) + { + if (object2.body || object2.isBody) + { + 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); + } + } - this.halfWidth = Math.abs(this.width / 2); - this.halfHeight = Math.abs(this.height / 2); + // TILEMAP LAYERS + else if (object1.isTilemap) + { + if (object2.body || object2.isBody) + { + return this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.isParent) + { + return this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + } + }, - this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + /** + * 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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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) + { + var body1 = (sprite1.isBody) ? sprite1 : sprite1.body; + var body2 = (sprite2.isBody) ? sprite2 : sprite2.body; - this.world.staticTree.insert(this); + if (!body1 || !body2) + { + return false; + } - return this; + if (this.separate(body1, body2, processCallback, callbackContext, overlapOnly)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, sprite1, sprite2); + } + + this._total++; + } + + return true; }, /** - * Positions the Static Body at an offset from its Game Object. + * Internal handler for Sprite vs. Group collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. * - * @method Phaser.Physics.Arcade.StaticBody#setOffset - * @since 3.4.0 + * @method Phaser.Physics.Arcade.World#collideSpriteVsGroup + * @private + * @since 3.0.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`. + * @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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide. + * @param {Phaser.Types.Physics.Arcade.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 {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * @return {boolean} `true` if the Sprite collided with the given Group, otherwise `false`. */ - setOffset: function (x, y) + collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) { - if (y === undefined) { y = x; } + var bodyA = (sprite.isBody) ? sprite : sprite.body; - this.world.staticTree.remove(this); + if (group.length === 0 || !bodyA || !bodyA.enable || bodyA.checkCollision.none) + { + return; + } - this.position.x -= this.offset.x; - this.position.y -= this.offset.y; + // Does sprite collide with anything? - this.offset.set(x, y); + var i; + var len; + var bodyB; - this.position.x += this.offset.x; - this.position.y += this.offset.y; + if (this.useTree || group.physicsType === CONST.STATIC_BODY) + { + var minMax = this.treeMinMax; - this.updateCenter(); + minMax.minX = bodyA.left; + minMax.minY = bodyA.top; + minMax.maxX = bodyA.right; + minMax.maxY = bodyA.bottom; - this.world.staticTree.insert(this); + var results = (group.physicsType === CONST.DYNAMIC_BODY) ? this.tree.search(minMax) : this.staticTree.search(minMax); - return this; + 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)) + { + 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++; + } + } + } }, /** - * 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. + * Internal handler for Group vs. Tilemap collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. * - * @method Phaser.Physics.Arcade.StaticBody#setSize + * @method Phaser.Physics.Arcade.World#collideGroupVsTilemapLayer + * @private * @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. + * @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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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 {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. */ - setSize: function (width, height, center) + collideGroupVsTilemapLayer: function (group, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) { - if (center === undefined) { center = true; } - - var gameObject = this.gameObject; + var children = group.getChildren(); - if (!width && gameObject.frame) + if (children.length === 0) { - width = gameObject.frame.realWidth; + return false; } - if (!height && gameObject.frame) + var didCollide = false; + + for (var i = 0; i < children.length; i++) { - height = gameObject.frame.realHeight; + if (children[i].body || children[i].isBody) + { + if (this.collideSpriteVsTilemapLayer(children[i], tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)) + { + didCollide = true; + } + } } - this.world.staticTree.remove(this); + return didCollide; + }, - this.width = width; - this.height = height; + /** + * 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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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 (tiles.length === 0 || (sprite.body && !sprite.body.enable) || (sprite.isBody && !sprite.enable)) + { + return false; + } + else + { + return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, false, false); + } + }, - this.halfWidth = Math.floor(width / 2); - this.halfHeight = Math.floor(height / 2); + /** + * 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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects overlap. + * @param {Phaser.Types.Physics.Arcade.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 (tiles.length === 0 || (sprite.body && !sprite.body.enable) || (sprite.isBody && !sprite.enable)) + { + return false; + } + else + { + return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, true, false); + } + }, - if (center && gameObject.getCenter) + /** + * 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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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.isBody) ? sprite : sprite.body; + + if (!body.enable || body.checkCollision.none) { - var ox = gameObject.displayWidth / 2; - var oy = gameObject.displayHeight / 2; + return false; + } - this.position.x -= this.offset.x; - this.position.y -= this.offset.y; + var x = body.x; + var y = body.y; + var w = body.width; + var h = body.height; - this.offset.set(ox - this.halfWidth, oy - this.halfHeight); + var layerData = tilemapLayer.layer; - this.position.x += this.offset.x; - this.position.y += this.offset.y; + 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; } - this.updateCenter(); + 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; + } - this.isCircle = false; - this.radius = 0; + var options = (overlapOnly) ? null : this.tileFilterOptions; - this.world.staticTree.insert(this); + var mapData = GetTilesWithinWorldXY(x, y, w, h, options, tilemapLayer.scene.cameras.main, tilemapLayer.layer); - return this; + if (mapData.length === 0) + { + return false; + } + else + { + return this.collideSpriteVsTilesHandler(sprite, mapData, collideCallback, processCallback, callbackContext, overlapOnly, true); + } }, /** - * Sets this Static Body to have a circular body and sets its size and position. + * Internal handler for Sprite vs. Tilemap collisions. + * Please use Phaser.Physics.Arcade.World#collide instead. * - * @method Phaser.Physics.Arcade.StaticBody#setCircle - * @since 3.0.0 + * @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 {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. + * @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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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 {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated. */ - setCircle: function (radius, offsetX, offsetY) + collideSpriteVsTilesHandler: function (sprite, tiles, collideCallback, processCallback, callbackContext, overlapOnly, isLayer) { - if (offsetX === undefined) { offsetX = this.offset.x; } - if (offsetY === undefined) { offsetY = this.offset.y; } + var body = (sprite.isBody) ? sprite : sprite.body; - if (radius > 0) + 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++) { - this.world.staticTree.remove(this); + tile = tiles[i]; - this.isCircle = true; + tilemapLayer = tile.tilemapLayer; - this.radius = radius; + var point = tilemapLayer.tileToWorldXY(tile.x, tile.y); - this.width = radius * 2; - this.height = radius * 2; + tileWorldRect.left = point.x; + tileWorldRect.top = point.y; - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); + // 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; + } - this.offset.set(offsetX, offsetY); + tileWorldRect.right = tileWorldRect.left + tile.width * tilemapLayer.scaleX; + tileWorldRect.bottom = tileWorldRect.top + tile.height * tilemapLayer.scaleY; - this.updateCenter(); + 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++; - this.world.staticTree.insert(this); + 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 {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide. + * @param {Phaser.Types.Physics.Arcade.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.isCircle = false; + 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); } + }, - return this; + /** + * 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); }, /** - * Updates the StaticBody's `center` from its `position` and dimensions. + * Shuts down the simulation, clearing physics data and removing listeners. * - * @method Phaser.Physics.Arcade.StaticBody#updateCenter + * @method Phaser.Physics.Arcade.World#shutdown * @since 3.0.0 */ - updateCenter: function () + shutdown: function () { - this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); + this.tree.clear(); + this.staticTree.clear(); + this.bodies.clear(); + this.staticBodies.clear(); + this.colliders.destroy(); + + this.removeAllListeners(); }, /** - * Resets this Body to the given coordinates. Also positions its parent Game Object to the same coordinates. + * Shuts down the simulation and disconnects it from the current scene. * - * @method Phaser.Physics.Arcade.StaticBody#reset + * @method Phaser.Physics.Arcade.World#destroy * @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) + destroy: function () { - var gameObject = this.gameObject; + this.shutdown(); - if (x === undefined) { x = gameObject.x; } - if (y === undefined) { y = gameObject.y; } + this.scene = null; - this.world.staticTree.remove(this); + if (this.debugGraphic) + { + this.debugGraphic.destroy(); + this.debugGraphic = null; + } + } - gameObject.setPosition(x, y); +}); - gameObject.getTopLeft(this.position); +module.exports = World; - this.updateCenter(); - this.world.staticTree.insert(this); - }, +/***/ }), + +/***/ 5321: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Provides methods used for setting the acceleration properties of an Arcade Physics Body. + * + * @namespace Phaser.Physics.Arcade.Components.Acceleration + * @since 3.0.0 + */ +var Acceleration = { /** - * NOOP function. A Static Body cannot be stopped. + * Sets the body's horizontal and vertical acceleration. If the vertical acceleration value is not provided, the vertical acceleration is set to the same value as the horizontal acceleration. * - * @method Phaser.Physics.Arcade.StaticBody#stop + * @method Phaser.Physics.Arcade.Components.Acceleration#setAcceleration * @since 3.0.0 * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * @param {number} x - The horizontal acceleration + * @param {number} [y=x] - The vertical acceleration + * + * @return {this} This Game Object. */ - stop: function () + setAcceleration: function (x, y) { + this.body.acceleration.set(x, y); + return this; }, /** - * Returns the x and y coordinates of the top left and bottom right points of the StaticBody. + * Sets the body's horizontal acceleration. * - * @method Phaser.Physics.Arcade.StaticBody#getBounds + * @method Phaser.Physics.Arcade.Components.Acceleration#setAccelerationX * @since 3.0.0 * - * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - The object which will hold the coordinates of the bounds. + * @param {number} value - The horizontal acceleration * - * @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. + * @return {this} This Game Object. */ - getBounds: function (obj) + setAccelerationX: function (value) { - obj.x = this.x; - obj.y = this.y; - obj.right = this.right; - obj.bottom = this.bottom; + this.body.acceleration.x = value; - return obj; + return this; }, /** - * Checks to see if a given x,y coordinate is colliding with this Static Body. + * Sets the body's vertical acceleration. * - * @method Phaser.Physics.Arcade.StaticBody#hitTest + * @method Phaser.Physics.Arcade.Components.Acceleration#setAccelerationY * @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. + * @param {number} value - The vertical acceleration * - * @return {boolean} `true` if the given coordinate lies within this body, otherwise `false`. + * @return {this} This Game Object. */ - hitTest: function (x, y) + setAccelerationY: function (value) { - return (this.isCircle) ? CircleContains(this, x, y) : RectangleContains(this, x, y); - }, + this.body.acceleration.y = value; - /** - * NOOP - * - * @method Phaser.Physics.Arcade.StaticBody#postUpdate - * @since 3.12.0 - */ - postUpdate: function () - { - }, + return this; + } + +}; + +module.exports = Acceleration; + + +/***/ }), + +/***/ 29257: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Provides methods used for setting the angular acceleration properties of an Arcade Physics Body. + * + * @namespace Phaser.Physics.Arcade.Components.Angular + * @since 3.0.0 + */ +var Angular = { /** - * The absolute (non-negative) change in this StaticBody's horizontal position from the previous step. Always zero. + * Sets the angular velocity of the body. * - * @method Phaser.Physics.Arcade.StaticBody#deltaAbsX + * In Arcade Physics, bodies cannot rotate. They are always axis-aligned. + * However, they can have angular motion, which is passed on to the Game Object bound to the body, + * causing them to visually rotate, even though the body remains axis-aligned. + * + * @method Phaser.Physics.Arcade.Components.Angular#setAngularVelocity * @since 3.0.0 * - * @return {number} Always zero for a Static Body. + * @param {number} value - The amount of angular velocity. + * + * @return {this} This Game Object. */ - deltaAbsX: function () + setAngularVelocity: function (value) { - return 0; + this.body.angularVelocity = value; + + return this; }, /** - * The absolute (non-negative) change in this StaticBody's vertical position from the previous step. Always zero. + * Sets the angular acceleration of the body. * - * @method Phaser.Physics.Arcade.StaticBody#deltaAbsY + * In Arcade Physics, bodies cannot rotate. They are always axis-aligned. + * However, they can have angular motion, which is passed on to the Game Object bound to the body, + * causing them to visually rotate, even though the body remains axis-aligned. + * + * @method Phaser.Physics.Arcade.Components.Angular#setAngularAcceleration * @since 3.0.0 * - * @return {number} Always zero for a Static Body. + * @param {number} value - The amount of angular acceleration. + * + * @return {this} This Game Object. */ - deltaAbsY: function () + setAngularAcceleration: function (value) { - return 0; + this.body.angularAcceleration = value; + + return this; }, /** - * The change in this StaticBody's horizontal position from the previous step. Always zero. + * Sets the angular drag of the body. Drag is applied to the current velocity, providing a form of deceleration. * - * @method Phaser.Physics.Arcade.StaticBody#deltaX + * @method Phaser.Physics.Arcade.Components.Angular#setAngularDrag * @since 3.0.0 * - * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. + * @param {number} value - The amount of drag. + * + * @return {this} This Game Object. */ - deltaX: function () + setAngularDrag: function (value) { - return 0; - }, + this.body.angularDrag = value; + + return this; + } + +}; + +module.exports = Angular; + + +/***/ }), + +/***/ 62122: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Provides methods used for setting the bounce properties of an Arcade Physics Body. + * + * @namespace Phaser.Physics.Arcade.Components.Bounce + * @since 3.0.0 + */ +var Bounce = { /** - * The change in this StaticBody's vertical position from the previous step. Always zero. + * Sets the bounce values of this body. * - * @method Phaser.Physics.Arcade.StaticBody#deltaY + * Bounce is the amount of restitution, or elasticity, the body has when it collides with another object. + * A value of 1 means that it will retain its full velocity after the rebound. A value of 0 means it will not rebound at all. + * + * @method Phaser.Physics.Arcade.Components.Bounce#setBounce * @since 3.0.0 * - * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. + * @param {number} x - The amount of horizontal bounce to apply on collision. A float, typically between 0 and 1. + * @param {number} [y=x] - The amount of vertical bounce to apply on collision. A float, typically between 0 and 1. + * + * @return {this} This Game Object. */ - deltaY: function () + setBounce: function (x, y) { - return 0; + this.body.bounce.set(x, y); + + return this; }, /** - * The change in this StaticBody's rotation from the previous step. Always zero. + * Sets the horizontal bounce value for this body. * - * @method Phaser.Physics.Arcade.StaticBody#deltaZ + * @method Phaser.Physics.Arcade.Components.Bounce#setBounceX * @since 3.0.0 * - * @return {number} The change in this StaticBody's rotation from the previous step. Always zero. + * @param {number} value - The amount of horizontal bounce to apply on collision. A float, typically between 0 and 1. + * + * @return {this} This Game Object. */ - deltaZ: function () + setBounceX: function (value) { - return 0; + this.body.bounce.x = value; + + return this; }, /** - * Disables this Body and marks it for destruction during the next step. + * Sets the vertical bounce value for this body. * - * @method Phaser.Physics.Arcade.StaticBody#destroy + * @method Phaser.Physics.Arcade.Components.Bounce#setBounceY * @since 3.0.0 + * + * @param {number} value - The amount of vertical bounce to apply on collision. A float, typically between 0 and 1. + * + * @return {this} This Game Object. */ - destroy: function () + setBounceY: function (value) { - this.enable = false; + this.body.bounce.y = value; - this.world.pendingDestroy.set(this); + return this; }, /** - * Draws a graphical representation of the StaticBody for visual debugging purposes. + * Sets whether this Body collides with the world boundary. * - * @method Phaser.Physics.Arcade.StaticBody#drawDebug + * Optionally also sets the World Bounce values. If the `Body.worldBounce` is null, it's set to a new Phaser.Math.Vector2 first. + * + * @method Phaser.Physics.Arcade.Components.Bounce#setCollideWorldBounds * @since 3.0.0 * - * @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to use for the debug drawing of the StaticBody. + * @param {boolean} [value=true] - `true` if this body should collide with the world bounds, otherwise `false`. + * @param {number} [bounceX] - If given this will be replace the `worldBounce.x` value. + * @param {number} [bounceY] - If given this will be replace the `worldBounce.y` value. + * @param {boolean} [onWorldBounds] - If given this replaces the Body's `onWorldBounds` value. + * + * @return {this} This Game Object. */ - drawDebug: function (graphic) + setCollideWorldBounds: function (value, bounceX, bounceY, onWorldBounds) { - var pos = this.position; + this.body.setCollideWorldBounds(value, bounceX, bounceY, onWorldBounds); - var x = pos.x + this.halfWidth; - var y = pos.y + this.halfHeight; + return this; + } - 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); - } +module.exports = Bounce; - } - }, + +/***/ }), + +/***/ 99803: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Provides methods used for setting the debug properties of an Arcade Physics Body. + * + * @namespace Phaser.Physics.Arcade.Components.Debug + * @since 3.0.0 + */ +var Debug = { /** - * Indicates whether the StaticBody is going to be showing a debug visualization during postUpdate. + * Sets the debug values of this body. * - * @method Phaser.Physics.Arcade.StaticBody#willDrawDebug + * Bodies will only draw their debug if debug has been enabled for Arcade Physics as a whole. + * Note that there is a performance cost in drawing debug displays. It should never be used in production. + * + * @method Phaser.Physics.Arcade.Components.Debug#setDebug * @since 3.0.0 * - * @return {boolean} Whether or not the StaticBody is going to show the debug visualization during postUpdate. + * @param {boolean} showBody - Set to `true` to have this body render its outline to the debug display. + * @param {boolean} showVelocity - Set to `true` to have this body render a velocity marker to the debug display. + * @param {number} bodyColor - The color of the body outline when rendered to the debug display. + * + * @return {this} This Game Object. */ - willDrawDebug: function () + setDebug: function (showBody, showVelocity, bodyColor) { - return this.debugShowBody; + this.debugShowBody = showBody; + this.debugShowVelocity = showVelocity; + this.debugBodyColor = bodyColor; + + return this; }, /** - * Sets the Mass of the StaticBody. Will set the Mass to 0.1 if the value passed is less than or equal to zero. + * Sets the color of the body outline when it renders to the debug display. * - * @method Phaser.Physics.Arcade.StaticBody#setMass + * @method Phaser.Physics.Arcade.Components.Debug#setDebugBodyColor * @since 3.0.0 * - * @param {number} value - The value to set the Mass to. Values of zero or less are changed to 0.1. + * @param {number} value - The color of the body outline when rendered to the debug display. * - * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. + * @return {this} This Game Object. */ - setMass: function (value) + setDebugBodyColor: function (value) { - if (value <= 0) - { - // Causes havoc otherwise - value = 0.1; - } - - this.mass = value; + this.body.debugBodyColor = value; return this; }, /** - * The x coordinate of the StaticBody. + * Set to `true` to have this body render its outline to the debug display. * - * @name Phaser.Physics.Arcade.StaticBody#x - * @type {number} + * @name Phaser.Physics.Arcade.Components.Debug#debugShowBody + * @type {boolean} * @since 3.0.0 */ - x: { + debugShowBody: { get: function () { - return this.position.x; + return this.body.debugShowBody; }, set: function (value) { - this.world.staticTree.remove(this); - - this.position.x = value; - - this.world.staticTree.insert(this); + this.body.debugShowBody = value; } }, /** - * The y coordinate of the StaticBody. + * Set to `true` to have this body render a velocity marker to the debug display. * - * @name Phaser.Physics.Arcade.StaticBody#y - * @type {number} + * @name Phaser.Physics.Arcade.Components.Debug#debugShowVelocity + * @type {boolean} * @since 3.0.0 */ - y: { + debugShowVelocity: { get: function () { - return this.position.y; + return this.body.debugShowVelocity; }, set: function (value) { - this.world.staticTree.remove(this); - - this.position.y = value; - - this.world.staticTree.insert(this); + this.body.debugShowVelocity = value; } }, /** - * Returns the left-most x coordinate of the area of the StaticBody. + * The color of the body outline when it renders to the debug display. * - * @name Phaser.Physics.Arcade.StaticBody#left + * @name Phaser.Physics.Arcade.Components.Debug#debugBodyColor * @type {number} - * @readonly * @since 3.0.0 */ - left: { + debugBodyColor: { get: function () { - return this.position.x; + return this.body.debugBodyColor; + }, + + set: function (value) + { + this.body.debugBodyColor = value; } - }, + } + +}; + +module.exports = Debug; + + +/***/ }), + +/***/ 87145: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Provides methods used for setting the drag properties of an Arcade Physics Body. + * + * @namespace Phaser.Physics.Arcade.Components.Drag + * @since 3.0.0 + */ +var Drag = { /** - * The right-most x coordinate of the area of the StaticBody. + * Sets the body's horizontal and vertical drag. If the vertical drag value is not provided, the vertical drag is set to the same value as the horizontal drag. * - * @name Phaser.Physics.Arcade.StaticBody#right - * @type {number} - * @readonly + * Drag can be considered as a form of deceleration that will return the velocity of a body back to zero over time. + * It is the absolute loss of velocity due to movement, in pixels per second squared. + * The x and y components are applied separately. + * + * When `useDamping` is true, this is 1 minus the damping factor. + * A value of 1 means the Body loses no velocity. + * A value of 0.95 means the Body loses 5% of its velocity per step. + * A value of 0.5 means the Body loses 50% of its velocity per step. + * + * Drag is applied only when `acceleration` is zero. + * + * @method Phaser.Physics.Arcade.Components.Drag#setDrag * @since 3.0.0 + * + * @param {number} x - The amount of horizontal drag to apply. + * @param {number} [y=x] - The amount of vertical drag to apply. + * + * @return {this} This Game Object. */ - right: { - - get: function () - { - return this.position.x + this.width; - } + setDrag: function (x, y) + { + this.body.drag.set(x, y); + return this; }, /** - * The highest y coordinate of the area of the StaticBody. + * Sets the body's horizontal drag. * - * @name Phaser.Physics.Arcade.StaticBody#top - * @type {number} - * @readonly + * Drag can be considered as a form of deceleration that will return the velocity of a body back to zero over time. + * It is the absolute loss of velocity due to movement, in pixels per second squared. + * The x and y components are applied separately. + * + * When `useDamping` is true, this is 1 minus the damping factor. + * A value of 1 means the Body loses no velocity. + * A value of 0.95 means the Body loses 5% of its velocity per step. + * A value of 0.5 means the Body loses 50% of its velocity per step. + * + * Drag is applied only when `acceleration` is zero. + * + * @method Phaser.Physics.Arcade.Components.Drag#setDragX * @since 3.0.0 + * + * @param {number} value - The amount of horizontal drag to apply. + * + * @return {this} This Game Object. */ - top: { - - get: function () - { - return this.position.y; - } + setDragX: function (value) + { + this.body.drag.x = value; + return this; }, /** - * The lowest y coordinate of the area of the StaticBody. (y + height) + * Sets the body's vertical drag. * - * @name Phaser.Physics.Arcade.StaticBody#bottom - * @type {number} - * @readonly + * Drag can be considered as a form of deceleration that will return the velocity of a body back to zero over time. + * It is the absolute loss of velocity due to movement, in pixels per second squared. + * The x and y components are applied separately. + * + * When `useDamping` is true, this is 1 minus the damping factor. + * A value of 1 means the Body loses no velocity. + * A value of 0.95 means the Body loses 5% of its velocity per step. + * A value of 0.5 means the Body loses 50% of its velocity per step. + * + * Drag is applied only when `acceleration` is zero. + * + * @method Phaser.Physics.Arcade.Components.Drag#setDragY * @since 3.0.0 + * + * @param {number} value - The amount of vertical drag to apply. + * + * @return {this} This Game Object. */ - bottom: { + setDragY: function (value) + { + this.body.drag.y = value; - get: function () - { - return this.position.y + this.height; - } + return this; + }, + + /** + * If this Body is using `drag` for deceleration this function 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.Components.Drag#setDamping + * @since 3.10.0 + * + * @param {boolean} value - `true` to use damping for deceleration, or `false` to use linear deceleration. + * + * @return {this} This Game Object. + */ + setDamping: function (value) + { + this.body.useDamping = value; + return this; } -}); +}; -module.exports = StaticBody; +module.exports = Drag; /***/ }), -/* 540 */ -/***/ (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} -*/ +/***/ 96174: +/***/ ((module) => { -var Class = __webpack_require__(0); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ /** - * @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 + * Provides methods used for setting the enable properties of an Arcade Physics Body. * - * @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Plugin Manager. + * @namespace Phaser.Physics.Arcade.Components.Enable + * @since 3.0.0 */ -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; - }, +var Enable = { /** - * 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. + * Enables this Game Object's Body. + * If you reset the Body you must also pass `x` and `y`. * - * @method Phaser.Plugins.BasePlugin#init - * @since 3.8.0 + * @method Phaser.Physics.Arcade.Components.Enable#enableBody + * @since 3.0.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. + * @param {boolean} [reset] - Also reset the Body and place the Game Object at (x, y). + * @param {number} [x] - The horizontal position to place the Game Object, if `reset` is true. + * @param {number} [y] - The horizontal position to place the Game Object, if `reset` is true. + * @param {boolean} [enableGameObject] - Also set this Game Object's `active` to true. + * @param {boolean} [showGameObject] - Also set this Game Object's `visible` to true. * - * @method Phaser.Plugins.BasePlugin#start - * @since 3.8.0 + * @return {this} This Game Object. + * + * @see Phaser.Physics.Arcade.Body#enable + * @see Phaser.Physics.Arcade.StaticBody#enable + * @see Phaser.Physics.Arcade.Body#reset + * @see Phaser.Physics.Arcade.StaticBody#reset + * @see Phaser.GameObjects.GameObject#active + * @see Phaser.GameObjects.GameObject#visible */ - start: function () + enableBody: function (reset, x, y, enableGameObject, showGameObject) { - // 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. + if (reset) + { + this.body.reset(x, y); + } - // var eventEmitter = this.game.events; + if (enableGameObject) + { + this.body.gameObject.active = true; + } - // 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); + if (showGameObject) + { + this.body.gameObject.visible = true; + } + + this.body.enable = true; + + return 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. + * Stops and disables this Game Object's Body. * - * @method Phaser.Plugins.BasePlugin#stop - * @since 3.8.0 + * @method Phaser.Physics.Arcade.Components.Enable#disableBody + * @since 3.0.0 + * + * @param {boolean} [disableGameObject=false] - Also set this Game Object's `active` to false. + * @param {boolean} [hideGameObject=false] - Also set this Game Object's `visible` to false. + * + * @return {this} This Game Object. + * + * @see Phaser.Physics.Arcade.Body#enable + * @see Phaser.Physics.Arcade.StaticBody#enable + * @see Phaser.GameObjects.GameObject#active + * @see Phaser.GameObjects.GameObject#visible */ - stop: function () + disableBody: function (disableGameObject, hideGameObject) { + if (disableGameObject === undefined) { disableGameObject = false; } + if (hideGameObject === undefined) { hideGameObject = false; } + + this.body.stop(); + + this.body.enable = false; + + if (disableGameObject) + { + this.body.gameObject.active = false; + } + + if (hideGameObject) + { + this.body.gameObject.visible = false; + } + + return this; }, /** - * Game instance has been destroyed. - * You must release everything in here, all references, all objects, free it all up. + * Syncs the Body's position and size with its parent Game Object. + * You don't need to call this for Dynamic Bodies, as it happens automatically. + * But for Static bodies it's a useful way of modifying the position of a Static Body + * in the Physics World, based on its Game Object. * - * @method Phaser.Plugins.BasePlugin#destroy - * @since 3.8.0 + * @method Phaser.Physics.Arcade.Components.Enable#refreshBody + * @since 3.1.0 + * + * @return {this} This Game Object. + * + * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject */ - destroy: function () + refreshBody: function () { - this.pluginManager = null; - this.game = null; - this.scene = null; - this.systems = null; + this.body.updateFromGameObject(); + + return this; } -}); +}; -module.exports = BasePlugin; +module.exports = Enable; /***/ }), -/* 541 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 51702: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * Methods for setting the friction of an Arcade Physics Body. * - * @function Phaser.Tilemaps.Components.CheckIsoBounds - * @since 3.50.0 + * In Arcade Physics, friction is a special case of motion transfer from an "immovable" body to a riding body. * - * @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. + * @namespace Phaser.Physics.Arcade.Components.Friction + * @since 3.0.0 * - * @return {boolean} Returns `true` if the coordinates are within the iso bounds. + * @see Phaser.Physics.Arcade.Body#friction */ -var CheckIsoBounds = function (tileX, tileY, layer, camera) -{ - var tilemapLayer = layer.tilemapLayer; +var Friction = { - var cullPaddingX = tilemapLayer.cullPaddingX; - var cullPaddingY = tilemapLayer.cullPaddingY; + /** + * Sets the friction of this game object's physics body. + * In Arcade Physics, friction is a special case of motion transfer from an "immovable" body to a riding body. + * + * @method Phaser.Physics.Arcade.Components.Friction#setFriction + * @since 3.0.0 + * + * @param {number} x - The amount of horizontal friction to apply, [0, 1]. + * @param {number} [y=x] - The amount of vertical friction to apply, [0, 1]. + * + * @return {this} This Game Object. + * + * @see Phaser.Physics.Arcade.Body#friction + */ + setFriction: function (x, y) + { + this.body.friction.set(x, y); - var pos = tilemapLayer.tilemap.tileToWorldXY(tileX, tileY, point, camera, tilemapLayer); + return this; + }, + + /** + * Sets the horizontal friction of this game object's physics body. + * This can move a riding body horizontally when it collides with this one on the vertical axis. + * + * @method Phaser.Physics.Arcade.Components.Friction#setFrictionX + * @since 3.0.0 + * + * @param {number} x - The amount of friction to apply, [0, 1]. + * + * @return {this} This Game Object. + * + * @see Phaser.Physics.Arcade.Body#friction + */ + setFrictionX: function (x) + { + this.body.friction.x = x; + + return this; + }, + + /** + * Sets the vertical friction of this game object's physics body. + * This can move a riding body vertically when it collides with this one on the horizontal axis. + * + * @method Phaser.Physics.Arcade.Components.Friction#setFrictionY + * @since 3.0.0 + * + * @param {number} y - The amount of friction to apply, [0, 1]. + * + * @return {this} This Game Object. + * + * @see Phaser.Physics.Arcade.Body#friction + */ + setFrictionY: function (y) + { + this.body.friction.y = y; + + return this; + } - // 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; +module.exports = Friction; /***/ }), -/* 542 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 25578: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * Provides methods for setting the gravity properties of an Arcade Physics Game Object. + * Should be applied as a mixin and not used directly. * - * @function Phaser.Tilemaps.Components.ReplaceByIndex + * @namespace Phaser.Physics.Arcade.Components.Gravity * @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); +var Gravity = { - for (var i = 0; i < tiles.length; i++) + /** + * Set the X and Y values of the gravitational pull to act upon this Arcade Physics Game Object. Values can be positive or negative. Larger values result in a stronger effect. + * + * If only one value is provided, this value will be used for both the X and Y axis. + * + * @method Phaser.Physics.Arcade.Components.Gravity#setGravity + * @since 3.0.0 + * + * @param {number} x - The gravitational force to be applied to the X-axis. + * @param {number} [y=x] - The gravitational force to be applied to the Y-axis. If this is not specified, the X value will be used. + * + * @return {this} This Game Object. + */ + setGravity: function (x, y) { - if (tiles[i] && tiles[i].index === findIndex) - { - tiles[i].index = newIndex; - } - } -}; - -module.exports = ReplaceByIndex; - - -/***/ }), -/* 543 */ -/***/ (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__(139); -var SnapFloor = __webpack_require__(76); + this.body.gravity.set(x, y); -var bounds = new Rectangle(); + return this; + }, -/** - * 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; + /** + * Set the gravitational force to be applied to the X axis. Value can be positive or negative. Larger values result in a stronger effect. + * + * @method Phaser.Physics.Arcade.Components.Gravity#setGravityX + * @since 3.0.0 + * + * @param {number} x - The gravitational force to be applied to the X-axis. + * + * @return {this} This Game Object. + */ + setGravityX: function (x) + { + this.body.gravity.x = x; - // 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); + return this; + }, - 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; + /** + * Set the gravitational force to be applied to the Y axis. Value can be positive or negative. Larger values result in a stronger effect. + * + * @method Phaser.Physics.Arcade.Components.Gravity#setGravityY + * @since 3.0.0 + * + * @param {number} y - The gravitational force to be applied to the Y-axis. + * + * @return {this} This Game Object. + */ + setGravityY: function (y) + { + this.body.gravity.y = y; - 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 this; + } - return bounds.setTo( - boundsLeft, - boundsTop, - (boundsRight - boundsLeft), - (boundsBottom - boundsTop) - ); }; -module.exports = CullBounds; +module.exports = Gravity; /***/ }), -/* 544 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72029: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CullBounds = __webpack_require__(543); -var RunCull = __webpack_require__(159); - /** - * 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. + * Provides methods used for setting the immovable properties of an Arcade Physics Body. * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + * @namespace Phaser.Physics.Arcade.Components.Immovable + * @since 3.0.0 */ -var CullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; +var Immovable = { - var tilemapLayer = layer.tilemapLayer; + /** + * Sets if this Body can be separated during collisions with other bodies. + * + * When a body is immovable it means it won't move at all, not even to separate it from collision + * overlap. If you just wish to prevent a body from being knocked around by other bodies, see + * the `setPushable` method instead. + * + * @method Phaser.Physics.Arcade.Components.Immovable#setImmovable + * @since 3.0.0 + * + * @param {boolean} [value=true] - Sets if this body will be separated during collisions with other bodies. + * + * @return {this} This Game Object. + */ + setImmovable: function (value) + { + if (value === undefined) { value = true; } - // Camera world view bounds, snapped for scaled tile size - // Cull Padding values are given in tiles, not pixels - var bounds = CullBounds(layer, camera); + this.body.immovable = value; - if (tilemapLayer.skipCull || tilemapLayer.scrollFactorX !== 1 || tilemapLayer.scrollFactorY !== 1) - { - bounds.left = 0; - bounds.right = layer.width; - bounds.top = 0; - bounds.bottom = layer.height; + return this; } - RunCull(layer, bounds, renderOrder, outputArray); - - return outputArray; }; -module.exports = CullTiles; +module.exports = Immovable; /***/ }), -/* 545 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 34566: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CullBounds = __webpack_require__(546); -var RunCull = __webpack_require__(159); - /** - * 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. + * Provides methods used for setting the mass properties of an Arcade Physics Body. * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + * @namespace Phaser.Physics.Arcade.Components.Mass + * @since 3.0.0 */ -var HexagonalCullTiles = function (layer, camera, outputArray, renderOrder) -{ - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; - - var tilemapLayer = layer.tilemapLayer; +var Mass = { - if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) + /** + * Sets the mass of the physics body + * + * @method Phaser.Physics.Arcade.Components.Mass#setMass + * @since 3.0.0 + * + * @param {number} value - New value for the mass of the body. + * + * @return {this} This Game Object. + */ + setMass: function (value) { - // Camera world view bounds, snapped for scaled tile size - // Cull Padding values are given in tiles, not pixels - - var bounds = CullBounds(layer, camera); + this.body.mass = value; - RunCull(layer, bounds, renderOrder, outputArray); + return this; } - return outputArray; }; -module.exports = HexagonalCullTiles; +module.exports = Mass; /***/ }), -/* 546 */ -/***/ (function(module, exports, __webpack_require__) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 2732: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var SnapCeil = __webpack_require__(139); -var SnapFloor = __webpack_require__(76); +var OverlapRect = __webpack_require__(15147); +var Circle = __webpack_require__(26673); +var CircleToCircle = __webpack_require__(22184); +var CircleToRectangle = __webpack_require__(26535); /** - * Returns the bounds in the given layer that are within the camera's viewport. - * This is used internally by the cull tiles function. + * 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. * - * @function Phaser.Tilemaps.Components.HexagonalCullBounds - * @since 3.50.0 + * A body only has to intersect with the search area to be considered, it doesn't have to be fully + * contained within it. * - * @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. + * 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. * - * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. + * @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 HexagonalCullBounds = function (layer, camera) +var OverlapCirc = function (world, x, y, radius, includeDynamic, includeStatic) { - var tilemap = layer.tilemapLayer.tilemap; - var tilemapLayer = layer.tilemapLayer; + var bodiesInRect = OverlapRect(world, x - radius, y - radius, 2 * radius, 2 * radius, includeDynamic, includeStatic); - // 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); + if (bodiesInRect.length === 0) + { + return bodiesInRect; + } - var len = layer.hexSideLength; - var rowH = ((tileH - len) / 2 + len); + var area = new Circle(x, y, radius); + var circFromBody = new Circle(); + var bodiesInArea = []; - 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; + for (var i = 0; i < bodiesInRect.length; i++) + { + var body = bodiesInRect[i]; - 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; + if (body.isCircle) + { + circFromBody.setTo(body.center.x, body.center.y, body.halfWidth); - return { - left: boundsLeft, - right: boundsRight, - top: boundsTop, - bottom: boundsBottom - }; + if (CircleToCircle(area, circFromBody)) + { + bodiesInArea.push(body); + } + } + else if (CircleToRectangle(area, body)) + { + bodiesInArea.push(body); + } + } + + return bodiesInArea; }; -module.exports = HexagonalCullBounds; +module.exports = OverlapCirc; /***/ }), -/* 547 */ -/***/ (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__(541); +/***/ 15147: +/***/ ((module) => { /** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * This method will search the given rectangular 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 for is extremely fast, + * otherwise the search is O(N) for Dynamic Bodies. * - * @function Phaser.Tilemaps.Components.IsometricCullTiles - * @since 3.50.0 + * @function Phaser.Physics.Arcade.Components.OverlapRect + * @since 3.17.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. + * @param {number} x - The top-left x coordinate of the area to search within. + * @param {number} y - The top-left y coordinate of the area to search within. + * @param {number} width - The width of the area to search within. + * @param {number} height - The height 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.Tilemaps.Tile[]} An array of Tile objects. + * @return {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[])} An array of bodies that overlap with the given area. */ -var IsometricCullTiles = function (layer, camera, outputArray, renderOrder) +var OverlapRect = function (world, x, y, width, height, includeDynamic, includeStatic) { - if (outputArray === undefined) { outputArray = []; } - if (renderOrder === undefined) { renderOrder = 0; } - - outputArray.length = 0; + if (includeDynamic === undefined) { includeDynamic = true; } + if (includeStatic === undefined) { includeStatic = false; } - var tilemapLayer = layer.tilemapLayer; + var dynamicBodies = []; + var staticBodies = []; - var mapData = layer.data; - var mapWidth = layer.width; - var mapHeight = layer.height; + var minMax = world.treeMinMax; - var drawLeft = 0; - var drawRight = mapWidth; - var drawTop = 0; - var drawBottom = mapHeight; + minMax.minX = x; + minMax.minY = y; + minMax.maxX = x + width; + minMax.maxY = y + height; - if (!tilemapLayer.skipCull) + if (includeStatic) { - 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]; + staticBodies = world.staticTree.search(minMax); + } - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } + if (includeDynamic && world.useTree) + { + dynamicBodies = world.tree.search(minMax); + } + else if (includeDynamic) + { + var bodies = world.bodies; - outputArray.push(tile); - } - } - } - } - else if (renderOrder === 1) + var fakeBody = { - // 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]; + position: { + x: x, + y: y + }, + left: x, + top: y, + right: x + width, + bottom: y + height, + isCircle: false + }; - if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) - { - continue; - } + var intersects = world.intersects; - outputArray.push(tile); - } - } - } - } - else if (renderOrder === 2) + bodies.iterate(function (target) { - // right-up - - for (y = drawBottom; y >= drawTop; y--) + if (intersects(target, fakeBody)) { - 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); - } - } + dynamicBodies.push(target); } - } - 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; + return staticBodies.concat(dynamicBodies); }; -module.exports = IsometricCullTiles; +module.exports = OverlapRect; /***/ }), -/* 548 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 57527: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CullBounds = __webpack_require__(549); -var RunCull = __webpack_require__(159); - /** - * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * Provides methods used for setting the pushable property of an Arcade Physics Body. * - * @function Phaser.Tilemaps.Components.StaggeredCullTiles + * @namespace Phaser.Physics.Arcade.Components.Pushable * @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; +var Pushable = { - if (!tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) + /** + * 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. + * + * @method Phaser.Physics.Arcade.Components.Pushable#setPushable + * @since 3.50.0 + * + * @param {boolean} [value=true] - Sets if this body can be pushed by collisions with another Body. + * + * @return {this} This Game Object. + */ + setPushable: function (value) { - // Camera world view bounds, snapped for scaled tile size - // Cull Padding values are given in tiles, not pixels + if (value === undefined) { value = true; } - var bounds = CullBounds(layer, camera); + this.body.pushable = value; - RunCull(layer, bounds, renderOrder, outputArray); + return this; } - return outputArray; }; -module.exports = StaggeredCullTiles; +module.exports = Pushable; /***/ }), -/* 549 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 77687: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SnapCeil = __webpack_require__(139); -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. + * Provides methods for setting the size of an Arcade Physics Game Object. + * Should be applied as a mixin and not used directly. * - * @return {object} An object containing the `left`, `right`, `top` and `bottom` bounds. + * @namespace Phaser.Physics.Arcade.Components.Size + * @since 3.0.0 */ -var StaggeredCullBounds = function (layer, camera) -{ - var tilemap = layer.tilemapLayer.tilemap; - var tilemapLayer = layer.tilemapLayer; +var Size = { - // 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); + /** + * Sets the body offset. This allows you to adjust the difference between the center of the body + * and the x and y coordinates of the parent Game Object. + * + * @method Phaser.Physics.Arcade.Components.Size#setOffset + * @since 3.0.0 + * + * @param {number} x - The amount to offset the body from the parent Game Object along the x-axis. + * @param {number} [y=x] - The amount to offset the body from the parent Game Object along the y-axis. Defaults to the value given for the x-axis. + * + * @return {this} This Game Object. + */ + setOffset: function (x, y) + { + this.body.setOffset(x, y); - 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; + return this; + }, - 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; + /** + * **DEPRECATED**: Please use `setBodySize` instead. + * + * Sets the size of this physics body. Setting the size does not adjust the dimensions of the parent Game Object. + * + * @method Phaser.Physics.Arcade.Components.Size#setSize + * @since 3.0.0 + * @deprecated + * + * @param {number} width - The new width of the physics body, in pixels. + * @param {number} height - The new height of the physics body, in pixels. + * @param {boolean} [center=true] - Should the body be re-positioned so its center aligns with the parent Game Object? + * + * @return {this} This Game Object. + */ + setSize: function (width, height, center) + { + this.body.setSize(width, height, center); + + return this; + }, + + /** + * Sets the size of this physics body. Setting the size does not adjust the dimensions of the parent Game Object. + * + * @method Phaser.Physics.Arcade.Components.Size#setBodySize + * @since 3.24.0 + * + * @param {number} width - The new width of the physics body, in pixels. + * @param {number} height - The new height of the physics body, in pixels. + * @param {boolean} [center=true] - Should the body be re-positioned so its center aligns with the parent Game Object? + * + * @return {this} This Game Object. + */ + setBodySize: function (width, height, center) + { + this.body.setSize(width, height, center); + + return this; + }, + + /** + * Sets this physics body to use a circle for collision instead of a rectangle. + * + * @method Phaser.Physics.Arcade.Components.Size#setCircle + * @since 3.0.0 + * + * @param {number} radius - The radius of the physics body, in pixels. + * @param {number} [offsetX] - The amount to offset the body from the parent Game Object along the x-axis. + * @param {number} [offsetY] - The amount to offset the body from the parent Game Object along the y-axis. + * + * @return {this} This Game Object. + */ + setCircle: function (radius, offsetX, offsetY) + { + this.body.setCircle(radius, offsetX, offsetY); + + return this; + } - return { - left: boundsLeft, - right: boundsRight, - top: boundsTop, - bottom: boundsBottom - }; }; -module.exports = StaggeredCullBounds; +module.exports = Size; /***/ }), -/* 550 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 66536: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 + * Provides methods for modifying the velocity of an Arcade Physics body. * - * @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. + * Should be applied as a mixin and not used directly. * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. + * @namespace Phaser.Physics.Arcade.Components.Velocity + * @since 3.0.0 */ -var HexagonalTileToWorldXY = function (tileX, tileY, point, camera, layer) -{ - if (!point) { point = new Vector2(); } +var Velocity = { - var tileWidth = layer.baseTileWidth; - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; + /** + * Sets the velocity of the Body. + * + * @method Phaser.Physics.Arcade.Components.Velocity#setVelocity + * @since 3.0.0 + * + * @param {number} x - The horizontal velocity of the body. Positive values move the body to the right, while negative values move it to the left. + * @param {number} [y=x] - The vertical velocity of the body. Positive values move the body down, while negative values move it up. + * + * @return {this} This Game Object. + */ + setVelocity: function (x, y) + { + this.body.setVelocity(x, y); - var layerWorldX = 0; - var layerWorldY = 0; + return this; + }, - if (tilemapLayer) + /** + * Sets the horizontal component of the body's velocity. + * + * Positive values move the body to the right, while negative values move it to the left. + * + * @method Phaser.Physics.Arcade.Components.Velocity#setVelocityX + * @since 3.0.0 + * + * @param {number} x - The new horizontal velocity. + * + * @return {this} This Game Object. + */ + setVelocityX: function (x) { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } - - layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + this.body.setVelocityX(x); - tileWidth *= tilemapLayer.scaleX; + return this; + }, - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + /** + * Sets the vertical component of the body's velocity. + * + * Positive values move the body down, while negative values move it up. + * + * @method Phaser.Physics.Arcade.Components.Velocity#setVelocityY + * @since 3.0.0 + * + * @param {number} y - The new vertical velocity of the body. + * + * @return {this} This Game Object. + */ + setVelocityY: function (y) + { + this.body.setVelocityY(y); - tileHeight *= tilemapLayer.scaleY; - } + return this; + }, - var len = layer.hexSideLength; - var rowHeight = ((tileHeight - len) / 2 + len); + /** + * Sets the maximum velocity of the body. + * + * @method Phaser.Physics.Arcade.Components.Velocity#setMaxVelocity + * @since 3.0.0 + * + * @param {number} x - The new maximum horizontal velocity. + * @param {number} [y=x] - The new maximum vertical velocity. + * + * @return {this} This Game Object. + */ + setMaxVelocity: function (x, y) + { + this.body.maxVelocity.set(x, y); - // similar to staggered, because Tiled uses the oddr representation. - var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); - var y = layerWorldY + tileY * rowHeight; + return this; + } - return point.set(x, y); }; -module.exports = HexagonalTileToWorldXY; +module.exports = Velocity; /***/ }), -/* 551 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 7864: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * @namespace Phaser.Physics.Arcade.Components */ -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; - } +module.exports = { - var x = layerWorldX + (tileX - tileY) * (tileWidth / 2); - var y = layerWorldY + (tileX + tileY) * (tileHeight / 2); + Acceleration: __webpack_require__(5321), + Angular: __webpack_require__(29257), + Bounce: __webpack_require__(62122), + Debug: __webpack_require__(99803), + Drag: __webpack_require__(87145), + Enable: __webpack_require__(96174), + Friction: __webpack_require__(51702), + Gravity: __webpack_require__(25578), + Immovable: __webpack_require__(72029), + Mass: __webpack_require__(34566), + OverlapCirc: __webpack_require__(2732), + OverlapRect: __webpack_require__(15147), + Pushable: __webpack_require__(57527), + Size: __webpack_require__(77687), + Velocity: __webpack_require__(66536) - return point.set(x, y); }; -module.exports = IsometricTileToWorldXY; - /***/ }), -/* 552 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 47401: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * Arcade Physics consts. * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. + * @ignore */ -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 CONST = { - var layerWorldX = 0; - var layerWorldY = 0; + /** + * 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, - if (tilemapLayer) - { - if (!camera) { camera = tilemapLayer.scene.cameras.main; } + /** + * 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, - layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + /** + * Arcade Physics Group containing Dynamic Bodies. + * + * @name Phaser.Physics.Arcade.GROUP + * @readonly + * @type {number} + * @since 3.0.0 + */ + GROUP: 2, - tileWidth *= tilemapLayer.scaleX; + /** + * A Tilemap Layer. + * + * @name Phaser.Physics.Arcade.TILEMAPLAYER + * @readonly + * @type {number} + * @since 3.0.0 + */ + TILEMAPLAYER: 3, - layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + /** + * 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, - tileHeight *= tilemapLayer.scaleY; - } + /** + * Facing up. + * + * @name Phaser.Physics.Arcade.FACING_UP + * @readonly + * @type {number} + * @since 3.0.0 + * + * @see Phaser.Physics.Arcade.Body#facing + */ + FACING_UP: 11, - var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); - var y = layerWorldY + tileY * (tileHeight / 2); + /** + * 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 - return point.set(x, y); }; -module.exports = StaggeredTileToWorldXY; +module.exports = CONST; /***/ }), -/* 553 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 22346: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var TileToWorldX = __webpack_require__(253); -var TileToWorldY = __webpack_require__(254); -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. + * The Arcade Physics World Collide Event. * - * @function Phaser.Tilemaps.Components.TileToWorldXY - * @since 3.0.0 + * This event is dispatched by an Arcade Physics World instance if two bodies collide _and_ at least + * one of them has their [onCollide]{@link Phaser.Physics.Arcade.Body#onCollide} property set to `true`. * - * @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. + * It provides an alternative means to handling collide events rather than using the callback approach. * - * @return {Phaser.Math.Vector2} The XY location in world coordinates. + * Listen to it from a Scene using: `this.physics.world.on('collide', listener)`. + * + * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. + * + * @event Phaser.Physics.Arcade.Events#COLLIDE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject1 - The first Game Object involved in the collision. This is the parent of `body1`. + * @param {Phaser.GameObjects.GameObject} gameObject2 - The second Game Object involved in the collision. This is the parent of `body2`. + * @param {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody} body1 - The first Physics Body involved in the collision. + * @param {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody} body2 - The second Physics Body involved in the collision. */ -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; +module.exports = 'collide'; /***/ }), -/* 554 */ -/***/ (function(module, exports) { + +/***/ 95092: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * The Arcade Physics World Overlap Event. * - * @function Phaser.Tilemaps.Components.HexagonalTileToWorldY - * @since 3.50.0 + * This event is dispatched by an Arcade Physics World instance if two bodies overlap _and_ at least + * one of them has their [onOverlap]{@link Phaser.Physics.Arcade.Body#onOverlap} property set to `true`. * - * @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. + * It provides an alternative means to handling overlap events rather than using the callback approach. * - * @return {number} The Y location in world coordinates. + * Listen to it from a Scene using: `this.physics.world.on('overlap', listener)`. + * + * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. + * + * @event Phaser.Physics.Arcade.Events#OVERLAP + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject1 - The first Game Object involved in the overlap. This is the parent of `body1`. + * @param {Phaser.GameObjects.GameObject} gameObject2 - The second Game Object involved in the overlap. This is the parent of `body2`. + * @param {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody} body1 - The first Physics Body involved in the overlap. + * @param {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody} body2 - The second Physics Body involved in the overlap. */ -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; +module.exports = 'overlap'; /***/ }), -/* 555 */ -/***/ (function(module, exports) { + +/***/ 15775: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * The Arcade Physics World Pause Event. * - * @function Phaser.Tilemaps.Components.StaggeredTileToWorldY - * @since 3.50.0 + * This event is dispatched by an Arcade Physics World instance when it is paused. * - * @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. + * Listen to it from a Scene using: `this.physics.world.on('pause', listener)`. * - * @return {number} The Y location in world coordinates. + * @event Phaser.Physics.Arcade.Events#PAUSE + * @type {string} + * @since 3.0.0 */ -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; +module.exports = 'pause'; /***/ }), -/* 556 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 74142: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * The Arcade Physics World Resume Event. * - * @function Phaser.Tilemaps.Components.HexagonalWorldToTileXY - * @since 3.50.0 + * This event is dispatched by an Arcade Physics World instance when it resumes from a paused state. * - * @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. + * Listen to it from a Scene using: `this.physics.world.on('resume', listener)`. * - * @return {Phaser.Math.Vector2} The XY location in tile units. + * @event Phaser.Physics.Arcade.Events#RESUME + * @type {string} + * @since 3.0.0 */ -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; +module.exports = 'resume'; /***/ }), -/* 557 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 22825: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * The Arcade Physics Tile Collide Event. * - * @function Phaser.Tilemaps.Components.IsometricWorldToTileXY - * @since 3.50.0 + * This event is dispatched by an Arcade Physics World instance if a body collides with a Tile _and_ + * has its [onCollide]{@link Phaser.Physics.Arcade.Body#onCollide} property set to `true`. * - * @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. + * It provides an alternative means to handling collide events rather than using the callback approach. * - * @return {Phaser.Math.Vector2} The XY location in tile units. + * Listen to it from a Scene using: `this.physics.world.on('tilecollide', listener)`. + * + * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. + * + * @event Phaser.Physics.Arcade.Events#TILE_COLLIDE + * @type {string} + * @since 3.16.1 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object involved in the collision. This is the parent of `body`. + * @param {Phaser.Tilemaps.Tile} tile - The tile the body collided with. + * @param {Phaser.Physics.Arcade.Body} body - The Arcade Physics Body of the Game Object involved in the collision. */ -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; - } - - 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; +module.exports = 'tilecollide'; /***/ }), -/* 558 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 10851: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * The Arcade Physics Tile Overlap Event. * - * @function Phaser.Tilemaps.Components.StaggeredWorldToTileXY - * @since 3.50.0 + * This event is dispatched by an Arcade Physics World instance if a body overlaps with a Tile _and_ + * has its [onOverlap]{@link Phaser.Physics.Arcade.Body#onOverlap} property set to `true`. * - * @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. + * It provides an alternative means to handling overlap events rather than using the callback approach. * - * @return {Phaser.Math.Vector2} The XY location in tile units. + * Listen to it from a Scene using: `this.physics.world.on('tileoverlap', listener)`. + * + * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. + * + * @event Phaser.Physics.Arcade.Events#TILE_OVERLAP + * @type {string} + * @since 3.16.1 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object involved in the overlap. This is the parent of `body`. + * @param {Phaser.Tilemaps.Tile} tile - The tile the body overlapped. + * @param {Phaser.Physics.Arcade.Body} body - The Arcade Physics Body of the Game Object involved in the overlap. */ -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; +module.exports = 'tileoverlap'; - 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)); +/***/ 7543: +/***/ ((module) => { - tileHeight *= tilemapLayer.scaleY; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Find the world position relative to the static or dynamic layer's top left origin, - // factoring in the camera's horizontal scroll +/** + * The Arcade Physics World Bounds Event. + * + * This event is dispatched by an Arcade Physics World instance if a body makes contact with the world bounds _and_ + * it has its [onWorldBounds]{@link Phaser.Physics.Arcade.Body#onWorldBounds} property set to `true`. + * + * It provides an alternative means to handling collide events rather than using the callback approach. + * + * Listen to it from a Scene using: `this.physics.world.on('worldbounds', listener)`. + * + * @event Phaser.Physics.Arcade.Events#WORLD_BOUNDS + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Physics.Arcade.Body} body - The Arcade Physics Body that hit the world bounds. + * @param {boolean} up - Is the Body blocked up? I.e. collided with the top of the world bounds. + * @param {boolean} down - Is the Body blocked down? I.e. collided with the bottom of the world bounds. + * @param {boolean} left - Is the Body blocked left? I.e. collided with the left of the world bounds. + * @param {boolean} right - Is the Body blocked right? I.e. collided with the right of the world bounds. + */ +module.exports = 'worldbounds'; - 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; +/***/ 1487: +/***/ ((module) => { - return point.set(x, y); -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = StaggeredWorldToTileXY; +/** + * The Arcade Physics World Step Event. + * + * This event is dispatched by an Arcade Physics World instance whenever a physics step is run. + * It is emitted _after_ the bodies and colliders have been updated. + * + * In high framerate settings this can be multiple times per game frame. + * + * Listen to it from a Scene using: `this.physics.world.on('worldstep', listener)`. + * + * @event Phaser.Physics.Arcade.Events#WORLD_STEP + * @type {string} + * @since 3.18.0 + * + * @param {number} delta - The delta time amount of this step, in seconds. + */ +module.exports = 'worldstep'; /***/ }), -/* 559 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 27037: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var WorldToTileX = __webpack_require__(255); -var WorldToTileY = __webpack_require__(256); -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. + * @namespace Phaser.Physics.Arcade.Events */ -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); +module.exports = { + + COLLIDE: __webpack_require__(22346), + OVERLAP: __webpack_require__(95092), + PAUSE: __webpack_require__(15775), + RESUME: __webpack_require__(74142), + TILE_COLLIDE: __webpack_require__(22825), + TILE_OVERLAP: __webpack_require__(10851), + WORLD_BOUNDS: __webpack_require__(7543), + WORLD_STEP: __webpack_require__(1487) - return point; }; -module.exports = WorldToTileXY; - /***/ }), -/* 560 */ -/***/ (function(module, exports) { + +/***/ 39977: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CONST = __webpack_require__(47401); +var Extend = __webpack_require__(98611); + /** - * 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. + * @namespace Phaser.Physics.Arcade */ -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 Arcade = { - var rowHeight = ((tileHeight - len) / 2 + len); + ArcadePhysics: __webpack_require__(66150), + Body: __webpack_require__(97602), + Collider: __webpack_require__(3909), + Components: __webpack_require__(7864), + Events: __webpack_require__(27037), + Factory: __webpack_require__(99523), + GetOverlapX: __webpack_require__(75671), + GetOverlapY: __webpack_require__(66185), + SeparateX: __webpack_require__(61777), + SeparateY: __webpack_require__(25299), + Group: __webpack_require__(10481), + Image: __webpack_require__(62832), + Sprite: __webpack_require__(25084), + StaticBody: __webpack_require__(66634), + StaticGroup: __webpack_require__(46346), + Tilemap: __webpack_require__(8413), + World: __webpack_require__(85233) - return (snapToFloor) ? Math.floor(worldY / rowHeight) : worldY / rowHeight; }; -module.exports = HexagonalWorldToTileY; +// Merge in the consts +Arcade = Extend(false, Arcade, CONST); + +module.exports = Arcade; /***/ }), -/* 561 */ -/***/ (function(module, exports) { + +/***/ 25163: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * A function to process the collision callbacks between a single tile and an Arcade Physics enabled Game Object. * - * @function Phaser.Tilemaps.Components.StaggeredWorldToTileY - * @since 3.50.0 + * @function Phaser.Physics.Arcade.Tilemap.ProcessTileCallbacks + * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Tilemaps.Tile} tile - The Tile to process. + * @param {Phaser.GameObjects.Sprite} sprite - The Game Object to process with the Tile. * - * @return {number} The Y location in tile units. + * @return {boolean} The result of the callback, `true` for further processing, or `false` to skip this pair. */ -var StaggeredWorldToTileY = function (worldY, snapToFloor, camera, layer) +var ProcessTileCallbacks = function (tile, sprite) { - var tileHeight = layer.baseTileHeight; - var tilemapLayer = layer.tilemapLayer; - - if (tilemapLayer) + // Tile callbacks take priority over layer level callbacks + if (tile.collisionCallback) { - 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 !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 (snapToFloor) ? Math.floor(worldY / (tileHeight / 2)) : worldY / (tileHeight / 2); + return true; }; -module.exports = StaggeredWorldToTileY; +module.exports = ProcessTileCallbacks; /***/ }), -/* 562 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 98209: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var IsInLayerBounds = __webpack_require__(119); - /** - * 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. + * Internal function to process the separation of a physics body from a tile. * - * @function Phaser.Tilemaps.Components.HasTileAt + * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationX * @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. + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {number} x - The x separation amount. */ -var HasTileAt = function (tileX, tileY, layer) +var ProcessTileSeparationX = function (body, x) { - if (IsInLayerBounds(tileX, tileY, layer)) + if (x < 0) { - var tile = layer.data[tileY][tileX]; + body.blocked.none = false; + body.blocked.left = true; + } + else if (x > 0) + { + body.blocked.none = false; + body.blocked.right = true; + } - return (tile !== null && tile.index > -1); + body.position.x -= x; + body.updateCenter(); + + if (body.bounce.x === 0) + { + body.velocity.x = 0; } else { - return false; + body.velocity.x = -body.velocity.x * body.bounce.x; } }; -module.exports = HasTileAt; +module.exports = ProcessTileSeparationX; /***/ }), -/* 563 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72792: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Tile = __webpack_require__(85); -var IsInLayerBounds = __webpack_require__(119); -var CalculateFacesAt = __webpack_require__(252); - /** - * Removes the tile at the given tile coordinates in the specified layer and updates the layer's - * collision information. + * Internal function to process the separation of a physics body from a tile. * - * @function Phaser.Tilemaps.Components.RemoveTileAt + * @function Phaser.Physics.Arcade.Tilemap.ProcessTileSeparationY * @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. + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {number} y - The y separation amount. */ -var RemoveTileAt = function (tileX, tileY, replaceWithNull, recalculateFaces, layer) +var ProcessTileSeparationY = function (body, y) { - if (replaceWithNull === undefined) { replaceWithNull = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - if (!IsInLayerBounds(tileX, tileY, layer)) + if (y < 0) { - return null; + body.blocked.none = false; + body.blocked.up = true; + } + else if (y > 0) + { + body.blocked.none = false; + body.blocked.down = true; } - var tile = layer.data[tileY][tileX]; + body.position.y -= y; + body.updateCenter(); - if (!tile) + if (body.bounce.y === 0) { - return null; + body.velocity.y = 0; } 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); + body.velocity.y = -body.velocity.y * body.bounce.y; } - - return tile; }; -module.exports = RemoveTileAt; +module.exports = ProcessTileSeparationY; /***/ }), -/* 564 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 27354: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Formats = __webpack_require__(40); -var Parse2DArray = __webpack_require__(259); -var ParseCSV = __webpack_require__(565); -var ParseJSONTiled = __webpack_require__(566); -var ParseWeltmeister = __webpack_require__(577); +var TileCheckX = __webpack_require__(14405); +var TileCheckY = __webpack_require__(52926); +var TileIntersectsBody = __webpack_require__(28808); /** - * 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. + * The core separation function to separate a physics body and a tile. * - * @function Phaser.Tilemaps.Parsers.Parse + * @function Phaser.Physics.Arcade.Tilemap.SeparateTile * @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. + * @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 {Phaser.Tilemaps.MapData} The created `MapData` object. + * @return {boolean} `true` if the body was separated, otherwise `false`. */ -var Parse = function (name, mapFormat, data, tileWidth, tileHeight, insertNull) +var SeparateTile = function (i, body, tile, tileWorldRect, tilemapLayer, tileBias, isLayer) { - var newMap; + 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; - switch (mapFormat) + if (!isLayer) { - 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; + faceHorizontal = true; + faceVertical = true; } - return newMap; -}; + // 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; + } -module.exports = Parse; + 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; + } -/***/ }), -/* 565 */ -/***/ (function(module, exports, __webpack_require__) { + 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)); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (minX < minY) + { + if (faceHorizontal) + { + ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); -var Formats = __webpack_require__(40); -var Parse2DArray = __webpack_require__(259); + // That's horizontal done, check if we still intersects? If not then we can return now + if (ox !== 0 && !TileIntersectsBody(tileWorldRect, body)) + { + return true; + } + } -/** - * 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(','); }); + if (faceVertical) + { + oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); + } + } + else + { + if (faceVertical) + { + oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer); - var map = Parse2DArray(name, array2D, tileWidth, tileHeight, insertNull); - map.format = Formats.CSV; + // That's vertical done, check if we still intersects? If not then we can return now + if (oy !== 0 && !TileIntersectsBody(tileWorldRect, body)) + { + return true; + } + } - return map; + if (faceHorizontal) + { + ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer); + } + } + + return (ox !== 0 || oy !== 0); }; -module.exports = ParseCSV; +module.exports = SeparateTile; /***/ }), -/* 566 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 14405: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AssignTileProperties = __webpack_require__(567); -var BuildTilesetIndex = __webpack_require__(568); -var CONST = __webpack_require__(29); -var Formats = __webpack_require__(40); -var FromOrientationString = __webpack_require__(258); -var MapData = __webpack_require__(121); -var ParseImageLayers = __webpack_require__(569); -var ParseObjectLayers = __webpack_require__(570); -var ParseTileLayers = __webpack_require__(573); -var ParseTilesets = __webpack_require__(575); +var ProcessTileSeparationX = __webpack_require__(98209); /** - * Parses a Tiled JSON object into a new MapData object. + * Check the body against the given tile on the X axis. + * Used internally by the SeparateTile function. * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled + * @function Phaser.Physics.Arcade.Tilemap.TileCheckX * @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. + * @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 {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. + * @return {number} The amount of separation that occurred. */ -var ParseJSONTiled = function (name, json, insertNull) +var TileCheckX = function (body, tile, tileLeft, tileRight, tileBias, isLayer) { - // 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 - }); + var ox = 0; - if (mapData.orientation === CONST.HEXAGONAL) + var faceLeft = tile.faceLeft; + var faceRight = tile.faceRight; + var collideLeft = tile.collideLeft; + var collideRight = tile.collideRight; + + if (!isLayer) { - mapData.hexSideLength = json.hexsidelength; + faceLeft = true; + faceRight = true; + collideLeft = true; + collideRight = true; } - mapData.layers = ParseTileLayers(json, insertNull); - mapData.images = ParseImageLayers(json); - - var sets = ParseTilesets(json); - - mapData.tilesets = sets.tilesets; - mapData.imageCollections = sets.imageCollections; + if (body.deltaX() < 0 && collideRight && body.checkCollision.left) + { + // Body is moving LEFT + if (faceRight && body.x < tileRight) + { + ox = body.x - tileRight; - mapData.objects = ParseObjectLayers(json); + 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; - mapData.tiles = BuildTilesetIndex(mapData); + if (ox > tileBias) + { + ox = 0; + } + } + } - AssignTileProperties(mapData); + if (ox !== 0) + { + if (body.customSeparateX) + { + body.overlapX = ox; + } + else + { + ProcessTileSeparationX(body, ox); + } + } - return mapData; + return ox; }; -module.exports = ParseJSONTiled; +module.exports = TileCheckX; /***/ }), -/* 567 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 52926: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(17); +var ProcessTileSeparationY = __webpack_require__(72792); /** - * Copy properties from tileset to tiles. + * Check the body against the given tile on the Y axis. + * Used internally by the SeparateTile function. * - * @function Phaser.Tilemaps.Parsers.Tiled.AssignTileProperties + * @function Phaser.Physics.Arcade.Tilemap.TileCheckY * @since 3.0.0 * - * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. + * @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 AssignTileProperties = function (mapData) +var TileCheckY = function (body, tile, tileTop, tileBottom, tileBias, isLayer) { - var layerData; - var tile; - var sid; - var set; - var row; + var oy = 0; - // go through each of the map data layers - for (var i = 0; i < mapData.layers.length; i++) - { - layerData = mapData.layers[i]; + var faceTop = tile.faceTop; + var faceBottom = tile.faceBottom; + var collideUp = tile.collideUp; + var collideDown = tile.collideDown; - set = null; + if (!isLayer) + { + faceTop = true; + faceBottom = true; + collideUp = true; + collideDown = true; + } - // rows of tiles - for (var j = 0; j < layerData.data.length; j++) + if (body.deltaY() < 0 && collideDown && body.checkCollision.up) + { + // Body is moving UP + if (faceBottom && body.y < tileBottom) { - row = layerData.data[j]; + oy = body.y - tileBottom; - // individual tiles - for (var k = 0; k < row.length; k++) + if (oy < -tileBias) { - 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; + 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 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] - ); - } + if (oy > tileBias) + { + oy = 0; } } } + + if (oy !== 0) + { + if (body.customSeparateY) + { + body.overlapY = oy; + } + else + { + ProcessTileSeparationY(body, oy); + } + } + + return oy; }; -module.exports = AssignTileProperties; +module.exports = TileCheckY; /***/ }), -/* 568 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 28808: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Tileset = __webpack_require__(122); - /** - * Master list of tiles -> x, y, index in tileset. + * Checks for intersection between the given tile rectangle-like object and an Arcade Physics body. * - * @function Phaser.Tilemaps.Parsers.Tiled.BuildTilesetIndex + * @function Phaser.Physics.Arcade.Tilemap.TileIntersectsBody * @since 3.0.0 * - * @param {Phaser.Tilemaps.MapData} mapData - The Map Data object. + * @param {{ left: number, right: number, top: number, bottom: number }} tileWorldRect - A rectangle object that defines the tile placement in the world. + * @param {Phaser.Physics.Arcade.Body} body - The body to check for intersection against. * - * @return {array} An array of Tileset objects. + * @return {boolean} Returns `true` of the tile intersects with the body, otherwise `false`. */ -var BuildTilesetIndex = function (mapData) +var TileIntersectsBody = function (tileWorldRect, body) { - var i; - var set; - var tiles = []; + // Currently, all bodies are treated as rectangles when colliding with a Tile. - for (i = 0; i < mapData.imageCollections.length; i++) - { - var collection = mapData.imageCollections[i]; - var images = collection.images; + return !( + body.right <= tileWorldRect.left || + body.bottom <= tileWorldRect.top || + body.position.x >= tileWorldRect.right || + body.position.y >= tileWorldRect.bottom + ); +}; - for (var j = 0; j < images.length; j++) - { - var image = images[j]; +module.exports = TileIntersectsBody; - set = new Tileset(image.image, image.gid, collection.imageWidth, collection.imageHeight, 0, 0); - set.updateTileData(collection.imageWidth, collection.imageHeight); +/***/ }), - mapData.tilesets.push(set); - } - } +/***/ 8413: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (i = 0; i < mapData.tilesets.length; i++) - { - set = mapData.tilesets[i]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var x = set.tileMargin; - var y = set.tileMargin; +/** + * @namespace Phaser.Physics.Arcade.Tilemap + */ - var count = 0; - var countX = 0; - var countY = 0; +var Tilemap = { - for (var t = set.firstgid; t < set.firstgid + set.total; t++) - { - // Can add extra properties here as needed - tiles[t] = [ x, y, i ]; + ProcessTileCallbacks: __webpack_require__(25163), + ProcessTileSeparationX: __webpack_require__(98209), + ProcessTileSeparationY: __webpack_require__(72792), + SeparateTile: __webpack_require__(27354), + TileCheckX: __webpack_require__(14405), + TileCheckY: __webpack_require__(52926), + TileIntersectsBody: __webpack_require__(28808) - x += set.tileWidth + set.tileSpacing; +}; - count++; +module.exports = Tilemap; - if (count === set.total) - { - break; - } - countX++; +/***/ }), - if (countX === set.columns) - { - x = set.tileMargin; - y += set.tileHeight + set.tileSpacing; +/***/ 53954: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - countX = 0; - countY++; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (countY === set.rows) - { - break; - } - } - } - } +/** + * @namespace Phaser.Physics + */ - return tiles; -}; +/** + * @namespace Phaser.Types.Physics + */ -module.exports = BuildTilesetIndex; +module.exports = { + + Arcade: __webpack_require__(39977), + Matter: __webpack_require__(45949) + +}; /***/ }), -/* 569 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 63568: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetFastValue = __webpack_require__(2); -var CreateGroupLayer = __webpack_require__(161); +var Class = __webpack_require__(56694); +var Vector2 = __webpack_require__(93736); /** - * Parses a Tiled JSON object into an array of objects with details about the image layers. + * @classdesc * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseImageLayers - * @since 3.0.0 + * The Body Bounds class contains methods to help you extract the world coordinates from various points around + * the bounds of a Matter Body. Because Matter bodies are positioned based on their center of mass, and not a + * dimension based center, you often need to get the bounds coordinates in order to properly align them in the world. * - * @param {object} json - The Tiled JSON object. + * You can access this class via the MatterPhysics class from a Scene, i.e.: * - * @return {array} Array of objects that include critical info about the map's image layers + * ```javascript + * this.matter.bodyBounds.getTopLeft(body); + * ``` + * + * See also the `MatterPhysics.alignBody` method. + * + * @class BodyBounds + * @memberof Phaser.Physics.Matter + * @constructor + * @since 3.22.0 */ -var ParseImageLayers = function (json) -{ - var images = []; +var BodyBounds = new Class({ - // State inherited from a parent group - var groupStack = []; - var curGroupState = CreateGroupLayer(json); + initialize: - while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + function BodyBounds () { - if (curGroupState.i >= curGroupState.layers.length) + /** + * A Vector2 that stores the temporary bounds center value during calculations by methods in this class. + * + * @name Phaser.Physics.Matter.BodyBounds#boundsCenter + * @type {Phaser.Math.Vector2} + * @since 3.22.0 + */ + this.boundsCenter = new Vector2(); + + /** + * A Vector2 that stores the temporary center diff values during calculations by methods in this class. + * + * @name Phaser.Physics.Matter.BodyBounds#centerDiff + * @type {Phaser.Math.Vector2} + * @since 3.22.0 + */ + this.centerDiff = new Vector2(); + }, + + /** + * Parses the given body to get the bounds diff values from it. + * + * They're stored in this class in the temporary properties `boundsCenter` and `centerDiff`. + * + * This method is called automatically by all other methods in this class. + * + * @method Phaser.Physics.Matter.BodyBounds#parseBody + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the bounds position from. + * + * @return {boolean} `true` if it was able to get the bounds, otherwise `false`. + */ + parseBody: function (body) + { + body = (body.hasOwnProperty('body')) ? body.body : body; + + if (!body.hasOwnProperty('bounds') || !body.hasOwnProperty('centerOfMass')) { - // Ensure recursion stack is not empty first - if (groupStack.length < 1) - { - console.warn( - 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' - ); - break; - } + return false; + } - // Return to previous recursive state - curGroupState = groupStack.pop(); - continue; + var boundsCenter = this.boundsCenter; + var centerDiff = this.centerDiff; + + var boundsWidth = body.bounds.max.x - body.bounds.min.x; + var boundsHeight = body.bounds.max.y - body.bounds.min.y; + + var bodyCenterX = boundsWidth * body.centerOfMass.x; + var bodyCenterY = boundsHeight * body.centerOfMass.y; + + boundsCenter.set(boundsWidth / 2, boundsHeight / 2); + centerDiff.set(bodyCenterX - boundsCenter.x, bodyCenterY - boundsCenter.y); + + return true; + }, + + /** + * Takes a Body and returns the world coordinates of the top-left of its _bounds_. + * + * Body bounds are updated by Matter each step and factor in scale and rotation. + * This will return the world coordinate based on the bodies _current_ position and bounds. + * + * @method Phaser.Physics.Matter.BodyBounds#getTopLeft + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. + * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. + * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. + * + * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. + */ + getTopLeft: function (body, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + if (this.parseBody(body)) + { + var center = this.boundsCenter; + var diff = this.centerDiff; + + return new Vector2( + x + center.x + diff.x, + y + center.y + diff.y + ); } - // Get current layer and advance iterator - var curi = curGroupState.layers[curGroupState.i]; - curGroupState.i++; + return false; + }, - if (curi.type !== 'imagelayer') + /** + * Takes a Body and returns the world coordinates of the top-center of its _bounds_. + * + * Body bounds are updated by Matter each step and factor in scale and rotation. + * This will return the world coordinate based on the bodies _current_ position and bounds. + * + * @method Phaser.Physics.Matter.BodyBounds#getTopCenter + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. + * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. + * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. + * + * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. + */ + getTopCenter: function (body, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + if (this.parseBody(body)) { - if (curi.type === 'group') - { - // Compute next state inherited from group - var nextGroupState = CreateGroupLayer(json, curi, curGroupState); + var center = this.boundsCenter; + var diff = this.centerDiff; - // Preserve current state before recursing - groupStack.push(curGroupState); - curGroupState = nextGroupState; - } + return new Vector2( + x + diff.x, + y + center.y + diff.y + ); + } - // Skip this layer OR 'recurse' (iterative style) into the group - continue; + return false; + }, + + /** + * Takes a Body and returns the world coordinates of the top-right of its _bounds_. + * + * Body bounds are updated by Matter each step and factor in scale and rotation. + * This will return the world coordinate based on the bodies _current_ position and bounds. + * + * @method Phaser.Physics.Matter.BodyBounds#getTopRight + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. + * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. + * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. + * + * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. + */ + getTopRight: function (body, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + if (this.parseBody(body)) + { + var center = this.boundsCenter; + var diff = this.centerDiff; + + return new Vector2( + x - (center.x - diff.x), + y + center.y + diff.y + ); } - 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 false; + }, - return images; -}; + /** + * Takes a Body and returns the world coordinates of the left-center of its _bounds_. + * + * Body bounds are updated by Matter each step and factor in scale and rotation. + * This will return the world coordinate based on the bodies _current_ position and bounds. + * + * @method Phaser.Physics.Matter.BodyBounds#getLeftCenter + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. + * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. + * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. + * + * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. + */ + getLeftCenter: function (body, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } -module.exports = ParseImageLayers; + if (this.parseBody(body)) + { + var center = this.boundsCenter; + var diff = this.centerDiff; + return new Vector2( + x + center.x + diff.x, + y + diff.y + ); + } -/***/ }), -/* 570 */ -/***/ (function(module, exports, __webpack_require__) { + return false; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Takes a Body and returns the world coordinates of the center of its _bounds_. + * + * Body bounds are updated by Matter each step and factor in scale and rotation. + * This will return the world coordinate based on the bodies _current_ position and bounds. + * + * @method Phaser.Physics.Matter.BodyBounds#getCenter + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. + * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. + * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. + * + * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. + */ + getCenter: function (body, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } -var GetFastValue = __webpack_require__(2); -var ParseObject = __webpack_require__(260); -var ObjectLayer = __webpack_require__(572); -var CreateGroupLayer = __webpack_require__(161); + if (this.parseBody(body)) + { + var diff = this.centerDiff; -/** - * 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 = []; + return new Vector2( + x + diff.x, + y + diff.y + ); + } - // State inherited from a parent group - var groupStack = []; - var curGroupState = CreateGroupLayer(json); + return false; + }, - while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + /** + * Takes a Body and returns the world coordinates of the right-center of its _bounds_. + * + * Body bounds are updated by Matter each step and factor in scale and rotation. + * This will return the world coordinate based on the bodies _current_ position and bounds. + * + * @method Phaser.Physics.Matter.BodyBounds#getRightCenter + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. + * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. + * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. + * + * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. + */ + getRightCenter: function (body, x, y) { - if (curGroupState.i >= curGroupState.layers.length) + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + if (this.parseBody(body)) { - // Ensure recursion stack is not empty first - if (groupStack.length < 1) - { - console.warn( - 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' - ); - break; - } + var center = this.boundsCenter; + var diff = this.centerDiff; - // Return to previous recursive state - curGroupState = groupStack.pop(); - continue; + return new Vector2( + x - (center.x - diff.x), + y + diff.y + ); } - // Get current layer and advance iterator - var curo = curGroupState.layers[curGroupState.i]; - curGroupState.i++; + return false; + }, - // Modify inherited properties - curo.opacity *= curGroupState.opacity; - curo.visible = curGroupState.visible && curo.visible; + /** + * Takes a Body and returns the world coordinates of the bottom-left of its _bounds_. + * + * Body bounds are updated by Matter each step and factor in scale and rotation. + * This will return the world coordinate based on the bodies _current_ position and bounds. + * + * @method Phaser.Physics.Matter.BodyBounds#getBottomLeft + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. + * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. + * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. + * + * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. + */ + getBottomLeft: function (body, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } - if (curo.type !== 'objectgroup') + if (this.parseBody(body)) { - if (curo.type === 'group') - { - // Compute next state inherited from group - var nextGroupState = CreateGroupLayer(json, curo, curGroupState); + var center = this.boundsCenter; + var diff = this.centerDiff; + + return new Vector2( + x + center.x + diff.x, + y - (center.y - diff.y) + ); + } + + return false; + }, + + /** + * Takes a Body and returns the world coordinates of the bottom-center of its _bounds_. + * + * Body bounds are updated by Matter each step and factor in scale and rotation. + * This will return the world coordinate based on the bodies _current_ position and bounds. + * + * @method Phaser.Physics.Matter.BodyBounds#getBottomCenter + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. + * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. + * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. + * + * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. + */ + getBottomCenter: function (body, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } - // Preserve current state before recursing - groupStack.push(curGroupState); - curGroupState = nextGroupState; - } + if (this.parseBody(body)) + { + var center = this.boundsCenter; + var diff = this.centerDiff; - // Skip this layer OR 'recurse' (iterative style) into the group - continue; + return new Vector2( + x + diff.x, + y - (center.y - diff.y) + ); } - 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); + return false; + }, - var objects = []; - for (var j = 0; j < curo.objects.length; j++) + /** + * Takes a Body and returns the world coordinates of the bottom-right of its _bounds_. + * + * Body bounds are updated by Matter each step and factor in scale and rotation. + * This will return the world coordinate based on the bodies _current_ position and bounds. + * + * @method Phaser.Physics.Matter.BodyBounds#getBottomRight + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. + * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. + * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. + * + * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. + */ + getBottomRight: function (body, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + + if (this.parseBody(body)) { - var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY); + var center = this.boundsCenter; + var diff = this.centerDiff; - objects.push(parsedObject); + return new Vector2( + x - (center.x - diff.x), + y - (center.y - diff.y) + ); } - var objectLayer = new ObjectLayer(curo); - objectLayer.objects = objects; - - objectLayers.push(objectLayer); + return false; } - return objectLayers; -}; +}); -module.exports = ParseObjectLayers; +module.exports = BodyBounds; /***/ }), -/* 571 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 18171: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var HasValue = __webpack_require__(126); - /** - * 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. + * @namespace Phaser.Physics.Matter.Matter */ -var Pick = function (object, keys) -{ - var obj = {}; - for (var i = 0; i < keys.length; i++) - { - var key = keys[i]; +var Matter = __webpack_require__(16929); - if (HasValue(object, key)) - { - obj[key] = object[key]; - } - } +Matter.Body = __webpack_require__(84125); +Matter.Composite = __webpack_require__(11299); +Matter.World = __webpack_require__(72005); - return obj; -}; +Matter.Collision = __webpack_require__(63454); +Matter.Detector = __webpack_require__(13657); +Matter.Pairs = __webpack_require__(91327); +Matter.Pair = __webpack_require__(70584); +Matter.Query = __webpack_require__(13390); +Matter.Resolver = __webpack_require__(44272); -module.exports = Pick; +Matter.Constraint = __webpack_require__(52838); + +Matter.Common = __webpack_require__(68758); +Matter.Engine = __webpack_require__(45775); +Matter.Events = __webpack_require__(39073); +Matter.Sleeping = __webpack_require__(22806); +Matter.Plugin = __webpack_require__(84474); + +Matter.Bodies = __webpack_require__(68516); +Matter.Composites = __webpack_require__(56643); + +Matter.Axes = __webpack_require__(50658); +Matter.Bounds = __webpack_require__(84091); +Matter.Svg = __webpack_require__(92765); +Matter.Vector = __webpack_require__(10438); +Matter.Vertices = __webpack_require__(39745); + +// aliases + +Matter.World.add = Matter.Composite.add; +Matter.World.remove = Matter.Composite.remove; +Matter.World.addComposite = Matter.Composite.addComposite; +Matter.World.addBody = Matter.Composite.addBody; +Matter.World.addConstraint = Matter.Composite.addConstraint; +Matter.World.clear = Matter.Composite.clear; + +module.exports = Matter; /***/ }), -/* 572 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72653: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); +var Bodies = __webpack_require__(68516); +var Class = __webpack_require__(56694); +var Composites = __webpack_require__(56643); +var Constraint = __webpack_require__(52838); +var Svg = __webpack_require__(92765); +var MatterGameObject = __webpack_require__(3860); +var MatterImage = __webpack_require__(7030); +var MatterSprite = __webpack_require__(73658); +var MatterTileBody = __webpack_require__(84720); +var PhysicsEditorParser = __webpack_require__(10998); +var PhysicsJSONParser = __webpack_require__(72829); +var PointerConstraint = __webpack_require__(88596); +var Vertices = __webpack_require__(39745); /** * @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. + * The Matter Factory is responsible for quickly creating a variety of different types of + * bodies, constraints and Game Objects and adding them into the physics world. * - * @class ObjectLayer - * @memberof Phaser.Tilemaps + * You access the factory from within a Scene using `add`: + * + * ```javascript + * this.matter.add.rectangle(x, y, width, height); + * ``` + * + * Use of the Factory is optional. All of the objects it creates can also be created + * directly via your own code or constructors. It is provided as a means to keep your + * code concise. + * + * @class Factory + * @memberof Phaser.Physics.Matter * @constructor * @since 3.0.0 * - * @param {Phaser.Types.Tilemaps.ObjectLayerConfig} [config] - The data for the layer from the Tiled JSON object. + * @param {Phaser.Physics.Matter.World} world - The Matter World which this Factory adds to. */ -var ObjectLayer = new Class({ +var Factory = new Class({ initialize: - function ObjectLayer (config) + function Factory (world) { - if (config === undefined) { config = {}; } - /** - * The name of the Object Layer. + * The Matter World which this Factory adds to. * - * @name Phaser.Tilemaps.ObjectLayer#name - * @type {string} + * @name Phaser.Physics.Matter.Factory#world + * @type {Phaser.Physics.Matter.World} * @since 3.0.0 */ - this.name = GetFastValue(config, 'name', 'object layer'); + this.world = world; /** - * The opacity of the layer, between 0 and 1. + * The Scene which this Factory's Matter World belongs to. * - * @name Phaser.Tilemaps.ObjectLayer#opacity - * @type {number} + * @name Phaser.Physics.Matter.Factory#scene + * @type {Phaser.Scene} * @since 3.0.0 */ - this.opacity = GetFastValue(config, 'opacity', 1); + this.scene = world.scene; /** - * The custom properties defined on the Object Layer, keyed by their name. + * A reference to the Scene.Systems this Matter Physics instance belongs to. * - * @name Phaser.Tilemaps.ObjectLayer#properties - * @type {object} + * @name Phaser.Physics.Matter.Factory#sys + * @type {Phaser.Scenes.Systems} * @since 3.0.0 */ - this.properties = GetFastValue(config, 'properties', {}); + this.sys = world.scene.sys; + }, - /** - * 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', {}); + /** + * Creates a new rigid rectangular Body and adds it to the World. + * + * @method Phaser.Physics.Matter.Factory#rectangle + * @since 3.0.0 + * + * @param {number} x - The X coordinate of the center of the Body. + * @param {number} y - The Y coordinate of the center of the Body. + * @param {number} width - The width of the Body. + * @param {number} height - The height of the Body. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {MatterJS.BodyType} A Matter JS Body. + */ + rectangle: function (x, y, width, height, options) + { + var body = Bodies.rectangle(x, y, width, height, options); - /** - * 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'); + this.world.add(body); - /** - * 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); + return body; + }, - /** - * 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', []); - } + /** + * Creates a new rigid trapezoidal Body and adds it to the World. + * + * @method Phaser.Physics.Matter.Factory#trapezoid + * @since 3.0.0 + * + * @param {number} x - The X coordinate of the center of the Body. + * @param {number} y - The Y coordinate of the center of the Body. + * @param {number} width - The width of the trapezoid Body. + * @param {number} height - The height of the trapezoid Body. + * @param {number} slope - The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {MatterJS.BodyType} A Matter JS Body. + */ + trapezoid: function (x, y, width, height, slope, options) + { + var body = Bodies.trapezoid(x, y, width, height, slope, options); -}); + this.world.add(body); -module.exports = ObjectLayer; + return body; + }, + /** + * Creates a new rigid circular Body and adds it to the World. + * + * @method Phaser.Physics.Matter.Factory#circle + * @since 3.0.0 + * + * @param {number} x - The X coordinate of the center of the Body. + * @param {number} y - The Y coordinate of the center of the Body. + * @param {number} radius - The radius of the circle. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * @param {number} [maxSides] - The maximum amount of sides to use for the polygon which will approximate this circle. + * + * @return {MatterJS.BodyType} A Matter JS Body. + */ + circle: function (x, y, radius, options, maxSides) + { + var body = Bodies.circle(x, y, radius, options, maxSides); -/***/ }), -/* 573 */ -/***/ (function(module, exports, __webpack_require__) { + this.world.add(body); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return body; + }, -var Base64Decode = __webpack_require__(574); -var CONST = __webpack_require__(29); -var CreateGroupLayer = __webpack_require__(161); -var FromOrientationString = __webpack_require__(258); -var GetFastValue = __webpack_require__(2); -var LayerData = __webpack_require__(120); -var ParseGID = __webpack_require__(261); -var Tile = __webpack_require__(85); + /** + * Creates a new rigid polygonal Body and adds it to the World. + * + * @method Phaser.Physics.Matter.Factory#polygon + * @since 3.0.0 + * + * @param {number} x - The X coordinate of the center of the Body. + * @param {number} y - The Y coordinate of the center of the Body. + * @param {number} sides - The number of sides the polygon will have. + * @param {number} radius - The "radius" of the polygon, i.e. the distance from its center to any vertex. This is also the radius of its circumcircle. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {MatterJS.BodyType} A Matter JS Body. + */ + polygon: function (x, y, sides, radius, options) + { + var body = Bodies.polygon(x, y, sides, radius, options); -/** - * 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 = []; + this.world.add(body); - // State inherited from a parent group - var groupStack = []; - var curGroupState = CreateGroupLayer(json); + return body; + }, - while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + /** + * Creates a body using the supplied vertices (or an array containing multiple sets of vertices) and adds it to the World. + * If the vertices are convex, they will pass through as supplied. Otherwise, if the vertices are concave, they will be decomposed. Note that this process is not guaranteed to support complex sets of vertices, e.g. ones with holes. + * + * @method Phaser.Physics.Matter.Factory#fromVertices + * @since 3.0.0 + * + * @param {number} x - The X coordinate of the center of the Body. + * @param {number} y - The Y coordinate of the center of the Body. + * @param {(string|array)} vertexSets - The vertices data. Either a path string or an array of vertices. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * @param {boolean} [flagInternal=false] - Flag internal edges (coincident part edges) + * @param {number} [removeCollinear=0.01] - Whether Matter.js will discard collinear edges (to improve performance). + * @param {number} [minimumArea=10] - During decomposition discard parts that have an area less than this. + * + * @return {MatterJS.BodyType} A Matter JS Body. + */ + fromVertices: function (x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) { - if (curGroupState.i >= curGroupState.layers.length) + if (typeof vertexSets === 'string') { - // 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; + vertexSets = Vertices.fromPath(vertexSets); } - 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); + var body = Bodies.fromVertices(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea); - // Preserve current state before recursing - groupStack.push(curGroupState); - curGroupState = nextGroupState; - } + this.world.add(body); - // Skip this layer OR 'recurse' (iterative style) into the group - continue; - } + return body; + }, - // 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); - } - } + /** + * Creates a body using data exported from the application PhysicsEditor (https://www.codeandweb.com/physicseditor) + * + * The PhysicsEditor file should be loaded as JSON: + * + * ```javascript + * preload () + * { + * this.load.json('vehicles', 'assets/vehicles.json); + * } + * + * create () + * { + * const vehicleShapes = this.cache.json.get('vehicles'); + * this.matter.add.fromPhysicsEditor(400, 300, vehicleShapes.truck); + * } + * ``` + * + * Do not pass the entire JSON file to this method, but instead pass one of the shapes contained within it. + * + * If you pas in an `options` object, any settings in there will override those in the PhysicsEditor config object. + * + * @method Phaser.Physics.Matter.Factory#fromPhysicsEditor + * @since 3.22.0 + * + * @param {number} x - The horizontal world location of the body. + * @param {number} y - The vertical world location of the body. + * @param {any} config - The JSON data exported from PhysicsEditor. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World? + * + * @return {MatterJS.BodyType} A Matter JS Body. + */ + fromPhysicsEditor: function (x, y, config, options, addToWorld) + { + if (addToWorld === undefined) { addToWorld = true; } - // Non-infinite map data - if (curl.data) - { - curl.data = Base64Decode(curl.data); - } + var body = PhysicsEditorParser.parseBody(x, y, config, options); - delete curl.encoding; // Allow the same map to be parsed multiple times + if (addToWorld && !this.world.has(body)) + { + this.world.add(body); } - // 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. + return body; + }, - var layerData; - var gidInfo; - var tile; - var blankTile; + /** + * Creates a body using the path data from an SVG file. + * + * SVG Parsing requires the pathseg polyfill from https://github.com/progers/pathseg + * + * The SVG file should be loaded as XML, as this method requires the ability to extract + * the path data from it. I.e.: + * + * ```javascript + * preload () + * { + * this.load.xml('face', 'assets/face.svg); + * } + * + * create () + * { + * this.matter.add.fromSVG(400, 300, this.cache.xml.get('face')); + * } + * ``` + * + * @method Phaser.Physics.Matter.Factory#fromSVG + * @since 3.22.0 + * + * @param {number} x - The X coordinate of the body. + * @param {number} y - The Y coordinate of the body. + * @param {object} xml - The SVG Path data. + * @param {number} [scale=1] - Scale the vertices by this amount after creation. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World? + * + * @return {MatterJS.BodyType} A Matter JS Body. + */ + fromSVG: function (x, y, xml, scale, options, addToWorld) + { + if (scale === undefined) { scale = 1; } + if (options === undefined) { options = {}; } + if (addToWorld === undefined) { addToWorld = true; } - var output = []; - var x = 0; + var path = xml.getElementsByTagName('path'); + var vertexSets = []; - if (infiniteMap) + for (var i = 0; i < path.length; i++) { - 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; - } + var points = Svg.pathToVertices(path[i], 30); - for (var c = 0; c < curl.height; c++) + if (scale !== 1) { - output.push([ null ]); - - for (var j = 0; j < curl.width; j++) - { - output[c][j] = null; - } + Vertices.scale(points, scale, scale); } - 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; - } - } - } + vertexSets.push(points); } - 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++; + var body = Bodies.fromVertices(x, y, vertexSets, options); - if (x === curl.width) - { - output.push(row); - x = 0; - row = []; - } - } + if (addToWorld) + { + this.world.add(body); } - layerData.data = output; - tileLayers.push(layerData); - } - - return tileLayers; -}; - -module.exports = ParseTileLayers; - - -/***/ }), -/* 574 */ -/***/ (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); + return body; + }, - // Interpret binaryString as an array of bytes representing little-endian encoded uint32 values. - for (var i = 0; i < len; i += 4) + /** + * Creates a body using the supplied physics data, as provided by a JSON file. + * + * The data file should be loaded as JSON: + * + * ```javascript + * preload () + * { + * this.load.json('ninjas', 'assets/ninjas.json); + * } + * + * create () + * { + * const ninjaShapes = this.cache.json.get('ninjas'); + * + * this.matter.add.fromJSON(400, 300, ninjaShapes.shinobi); + * } + * ``` + * + * Do not pass the entire JSON file to this method, but instead pass one of the shapes contained within it. + * + * If you pas in an `options` object, any settings in there will override those in the config object. + * + * The structure of the JSON file is as follows: + * + * ```text + * { + * 'generator_info': // The name of the application that created the JSON data + * 'shapeName': { + * 'type': // The type of body + * 'label': // Optional body label + * 'vertices': // An array, or an array of arrays, containing the vertex data in x/y object pairs + * } + * } + * ``` + * + * At the time of writing, only the Phaser Physics Tracer App exports in this format. + * + * @method Phaser.Physics.Matter.Factory#fromJSON + * @since 3.22.0 + * + * @param {number} x - The X coordinate of the body. + * @param {number} y - The Y coordinate of the body. + * @param {any} config - The JSON physics data. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World? + * + * @return {MatterJS.BodyType} A Matter JS Body. + */ + fromJSON: function (x, y, config, options, addToWorld) { - 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; - - -/***/ }), -/* 575 */ -/***/ (function(module, exports, __webpack_require__) { + if (options === undefined) { options = {}; } + if (addToWorld === undefined) { addToWorld = true; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var body = PhysicsJSONParser.parseBody(x, y, config, options); -var Tileset = __webpack_require__(122); -var ImageCollection = __webpack_require__(576); -var ParseObject = __webpack_require__(260); -var ParseWangsets = __webpack_require__(1453); + if (body && addToWorld) + { + this.world.add(body); + } -/** - * 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; + return body; + }, - for (var i = 0; i < json.tilesets.length; i++) + /** + * Create a new composite containing Matter Image objects created in a grid arrangement. + * This function uses the body bounds to prevent overlaps. + * + * @method Phaser.Physics.Matter.Factory#imageStack + * @since 3.0.0 + * + * @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. Set to `null` to skip this value. + * @param {number} x - The horizontal position of this composite in the world. + * @param {number} y - The vertical position of this composite in the world. + * @param {number} columns - The number of columns in the grid. + * @param {number} rows - The number of rows in the grid. + * @param {number} [columnGap=0] - The distance between each column. + * @param {number} [rowGap=0] - The distance between each row. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {MatterJS.CompositeType} A Matter JS Composite Stack. + */ + imageStack: function (key, frame, x, y, columns, rows, columnGap, rowGap, options) { - // name, firstgid, width, height, margin, spacing, properties - var set = json.tilesets[i]; + if (columnGap === undefined) { columnGap = 0; } + if (rowGap === undefined) { rowGap = 0; } + if (options === undefined) { options = {}; } - 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); + var world = this.world; + var displayList = this.sys.displayList; - if (json.version > 1) - { - var datas = undefined; - var props = undefined; + options.addToWorld = false; - if (Array.isArray(set.tiles)) - { - datas = datas || {}; - props = props || {}; + var stack = Composites.stack(x, y, columns, rows, columnGap, rowGap, function (x, y) + { + var image = new MatterImage(world, x, y, key, frame, options); - // Tiled 1.2+ - for (var t = 0; t < set.tiles.length; t++) - { - var tile = set.tiles[t]; + displayList.add(image); - // Convert tileproperties. - if (tile.properties) - { - var newPropData = {}; + return image.body; + }); - tile.properties.forEach(function (propData) - { - newPropData[propData['name']] = propData['value']; - }); + world.add(stack); - props[tile.id] = newPropData; - } + return stack; + }, - // Convert objectgroup - if (tile.objectgroup) - { - (datas[tile.id] || (datas[tile.id] = {})).objectgroup = tile.objectgroup; + /** + * Create a new composite containing bodies created in the callback in a grid arrangement. + * + * This function uses the body bounds to prevent overlaps. + * + * @method Phaser.Physics.Matter.Factory#stack + * @since 3.0.0 + * + * @param {number} x - The horizontal position of this composite in the world. + * @param {number} y - The vertical position of this composite in the world. + * @param {number} columns - The number of columns in the grid. + * @param {number} rows - The number of rows in the grid. + * @param {number} columnGap - The distance between each column. + * @param {number} rowGap - The distance between each row. + * @param {function} callback - The callback that creates the stack. + * + * @return {MatterJS.CompositeType} A new composite containing objects created in the callback. + */ + stack: function (x, y, columns, rows, columnGap, rowGap, callback) + { + var stack = Composites.stack(x, y, columns, rows, columnGap, rowGap, callback); - if (tile.objectgroup.objects) - { - var parsedObjects2 = tile.objectgroup.objects.map(function (obj) - { - return ParseObject(obj); - }); + this.world.add(stack); - datas[tile.id].objectgroup.objects = parsedObjects2; - } - } + return stack; + }, - // Copy animation data - if (tile.animation) - { - (datas[tile.id] || (datas[tile.id] = {})).animation = tile.animation; - } + /** + * Create a new composite containing bodies created in the callback in a pyramid arrangement. + * This function uses the body bounds to prevent overlaps. + * + * @method Phaser.Physics.Matter.Factory#pyramid + * @since 3.0.0 + * + * @param {number} x - The horizontal position of this composite in the world. + * @param {number} y - The vertical position of this composite in the world. + * @param {number} columns - The number of columns in the pyramid. + * @param {number} rows - The number of rows in the pyramid. + * @param {number} columnGap - The distance between each column. + * @param {number} rowGap - The distance between each row. + * @param {function} callback - The callback function to be invoked. + * + * @return {MatterJS.CompositeType} A Matter JS Composite pyramid. + */ + pyramid: function (x, y, columns, rows, columnGap, rowGap, callback) + { + var stack = Composites.pyramid(x, y, columns, rows, columnGap, rowGap, callback); - // Copy tile `type` field - // (see https://doc.mapeditor.org/en/latest/manual/custom-properties/#typed-tiles). - if (tile.type) - { - (datas[tile.id] || (datas[tile.id] = {})).type = tile.type; - } - } - } + this.world.add(stack); - if (Array.isArray(set.wangsets)) - { - datas = datas || {}; - props = props || {}; + return stack; + }, - ParseWangsets(set.wangsets, datas); - } + /** + * Chains all bodies in the given composite together using constraints. + * + * @method Phaser.Physics.Matter.Factory#chain + * @since 3.0.0 + * + * @param {MatterJS.CompositeType} composite - The composite in which all bodies will be chained together sequentially. + * @param {number} xOffsetA - The horizontal offset of the BodyA constraint. This is a percentage based on the body size, not a world position. + * @param {number} yOffsetA - The vertical offset of the BodyA constraint. This is a percentage based on the body size, not a world position. + * @param {number} xOffsetB - The horizontal offset of the BodyB constraint. This is a percentage based on the body size, not a world position. + * @param {number} yOffsetB - The vertical offset of the BodyB constraint. This is a percentage based on the body size, not a world position. + * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. + * + * @return {MatterJS.CompositeType} The original composite that was passed to this method. + */ + chain: function (composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) + { + return Composites.chain(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options); + }, - if (datas) // Implies also props is set. - { - newSet.tileData = datas; - newSet.tileProperties = props; - } - } - else - { - // Tiled 1 + /** + * Connects bodies in the composite with constraints in a grid pattern, with optional cross braces. + * + * @method Phaser.Physics.Matter.Factory#mesh + * @since 3.0.0 + * + * @param {MatterJS.CompositeType} composite - The composite in which all bodies will be chained together. + * @param {number} columns - The number of columns in the mesh. + * @param {number} rows - The number of rows in the mesh. + * @param {boolean} crossBrace - Create cross braces for the mesh as well? + * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. + * + * @return {MatterJS.CompositeType} The original composite that was passed to this method. + */ + mesh: function (composite, columns, rows, crossBrace, options) + { + return Composites.mesh(composite, columns, rows, crossBrace, options); + }, - // Properties stored per-tile in object with string indexes starting at "0" - if (set.tileproperties) - { - newSet.tileProperties = set.tileproperties; - } + /** + * Creates a composite with a Newton's Cradle setup of bodies and constraints. + * + * @method Phaser.Physics.Matter.Factory#newtonsCradle + * @since 3.0.0 + * + * @param {number} x - The horizontal position of the start of the cradle. + * @param {number} y - The vertical position of the start of the cradle. + * @param {number} number - The number of balls in the cradle. + * @param {number} size - The radius of each ball in the cradle. + * @param {number} length - The length of the 'string' the balls hang from. + * + * @return {MatterJS.CompositeType} A Newton's cradle composite. + */ + newtonsCradle: function (x, y, number, size, length) + { + var composite = Composites.newtonsCradle(x, y, number, size, length); - // Object & terrain shapes stored per-tile in object with string indexes starting at "0" - if (set.tiles) - { - newSet.tileData = set.tiles; + this.world.add(composite); - // Parse the objects into Phaser format to match handling of other Tiled objects - for (stringID in newSet.tileData) - { - var objectGroup = newSet.tileData[stringID].objectgroup; + return composite; + }, - if (objectGroup && objectGroup.objects) - { - var parsedObjects1 = objectGroup.objects.map(function (obj) - { - return ParseObject(obj); - }); + /** + * Creates a composite with simple car setup of bodies and constraints. + * + * @method Phaser.Physics.Matter.Factory#car + * @since 3.0.0 + * + * @param {number} x - The horizontal position of the car in the world. + * @param {number} y - The vertical position of the car in the world. + * @param {number} width - The width of the car chasis. + * @param {number} height - The height of the car chasis. + * @param {number} wheelSize - The radius of the car wheels. + * + * @return {MatterJS.CompositeType} A new composite car body. + */ + car: function (x, y, width, height, wheelSize) + { + var composite = Composites.car(x, y, width, height, wheelSize); - newSet.tileData[stringID].objectgroup.objects = parsedObjects1; - } - } - } - } + this.world.add(composite); - // 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); + return composite; + }, - tilesets.push(newSet); - } - else - { - var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties); + /** + * Creates a simple soft body like object. + * + * @method Phaser.Physics.Matter.Factory#softBody + * @since 3.0.0 + * + * @param {number} x - The horizontal position of this composite in the world. + * @param {number} y - The vertical position of this composite in the world. + * @param {number} columns - The number of columns in the Composite. + * @param {number} rows - The number of rows in the Composite. + * @param {number} columnGap - The distance between each column. + * @param {number} rowGap - The distance between each row. + * @param {boolean} crossBrace - `true` to create cross braces between the bodies, or `false` to create just straight braces. + * @param {number} particleRadius - The radius of this circlular composite. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [particleOptions] - An optional Body configuration object that is used to set initial Body properties on creation. + * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [constraintOptions] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. + * + * @return {MatterJS.CompositeType} A new composite simple soft body. + */ + softBody: function (x, y, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) + { + var composite = Composites.softBody(x, y, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions); - var maxId = 0; + this.world.add(composite); - for (t = 0; t < set.tiles.length; t++) - { - tile = set.tiles[t]; + return composite; + }, - var image = tile.image; - var tileId = parseInt(tile.id, 10); - var gid = set.firstgid + tileId; - newCollection.addImage(gid, image); + /** + * This method is an alias for `Factory.constraint`. + * + * Constraints (or joints) are used for specifying that a fixed distance must be maintained + * between two bodies, or a body and a fixed world-space position. + * + * The stiffness of constraints can be modified to create springs or elastic. + * + * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` + * value (e.g. `0.7` or above). + * + * If the constraint is unstable, try lowering the `stiffness` value and / or increasing + * `constraintIterations` within the Matter Config. + * + * For compound bodies, constraints must be applied to the parent body and not one of its parts. + * + * @method Phaser.Physics.Matter.Factory#joint + * @since 3.0.0 + * + * @param {MatterJS.BodyType} bodyA - The first possible `Body` that this constraint is attached to. + * @param {MatterJS.BodyType} bodyB - The second possible `Body` that this constraint is attached to. + * @param {number} [length] - A Number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. + * @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring. + * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. + * + * @return {MatterJS.ConstraintType} A Matter JS Constraint. + */ + joint: function (bodyA, bodyB, length, stiffness, options) + { + return this.constraint(bodyA, bodyB, length, stiffness, options); + }, - maxId = Math.max(tileId, maxId); - } + /** + * This method is an alias for `Factory.constraint`. + * + * Constraints (or joints) are used for specifying that a fixed distance must be maintained + * between two bodies, or a body and a fixed world-space position. + * + * The stiffness of constraints can be modified to create springs or elastic. + * + * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` + * value (e.g. `0.7` or above). + * + * If the constraint is unstable, try lowering the `stiffness` value and / or increasing + * `constraintIterations` within the Matter Config. + * + * For compound bodies, constraints must be applied to the parent body and not one of its parts. + * + * @method Phaser.Physics.Matter.Factory#spring + * @since 3.0.0 + * + * @param {MatterJS.BodyType} bodyA - The first possible `Body` that this constraint is attached to. + * @param {MatterJS.BodyType} bodyB - The second possible `Body` that this constraint is attached to. + * @param {number} [length] - A Number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. + * @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring. + * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. + * + * @return {MatterJS.ConstraintType} A Matter JS Constraint. + */ + spring: function (bodyA, bodyB, length, stiffness, options) + { + return this.constraint(bodyA, bodyB, length, stiffness, options); + }, - newCollection.maxId = maxId; + /** + * Constraints (or joints) are used for specifying that a fixed distance must be maintained + * between two bodies, or a body and a fixed world-space position. + * + * The stiffness of constraints can be modified to create springs or elastic. + * + * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` + * value (e.g. `0.7` or above). + * + * If the constraint is unstable, try lowering the `stiffness` value and / or increasing + * `constraintIterations` within the Matter Config. + * + * For compound bodies, constraints must be applied to the parent body and not one of its parts. + * + * @method Phaser.Physics.Matter.Factory#constraint + * @since 3.0.0 + * + * @param {MatterJS.BodyType} bodyA - The first possible `Body` that this constraint is attached to. + * @param {MatterJS.BodyType} bodyB - The second possible `Body` that this constraint is attached to. + * @param {number} [length] - A Number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. + * @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring. + * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. + * + * @return {MatterJS.ConstraintType} A Matter JS Constraint. + */ + constraint: function (bodyA, bodyB, length, stiffness, options) + { + if (stiffness === undefined) { stiffness = 1; } + if (options === undefined) { options = {}; } - imageCollections.push(newCollection); - } + options.bodyA = (bodyA.type === 'body') ? bodyA : bodyA.body; + options.bodyB = (bodyB.type === 'body') ? bodyB : bodyB.body; - // We've got a new Tileset, so set the lastgid into the previous one - if (lastSet) + if (!isNaN(length)) { - lastSet.lastgid = set.firstgid - 1; + options.length = length; } - lastSet = set; - } + options.stiffness = stiffness; - return { tilesets: tilesets, imageCollections: imageCollections }; -}; + var constraint = Constraint.create(options); -module.exports = ParseTilesets; + this.world.add(constraint); + return constraint; + }, -/***/ }), -/* 576 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Constraints (or joints) are used for specifying that a fixed distance must be maintained + * between two bodies, or a body and a fixed world-space position. + * + * A world constraint has only one body, you should specify a `pointA` position in + * the constraint options parameter to attach the constraint to the world. + * + * The stiffness of constraints can be modified to create springs or elastic. + * + * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` + * value (e.g. `0.7` or above). + * + * If the constraint is unstable, try lowering the `stiffness` value and / or increasing + * `constraintIterations` within the Matter Config. + * + * For compound bodies, constraints must be applied to the parent body and not one of its parts. + * + * @method Phaser.Physics.Matter.Factory#worldConstraint + * @since 3.0.0 + * + * @param {MatterJS.BodyType} body - The Matter `Body` that this constraint is attached to. + * @param {number} [length] - A number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. + * @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring. + * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. + * + * @return {MatterJS.ConstraintType} A Matter JS Constraint. + */ + worldConstraint: function (body, length, stiffness, options) + { + if (stiffness === undefined) { stiffness = 1; } + if (options === undefined) { options = {}; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + options.bodyB = (body.type === 'body') ? body : body.body; -var Class = __webpack_require__(0); + if (!isNaN(length)) + { + options.length = length; + } -/** - * @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({ + options.stiffness = stiffness; - initialize: + var constraint = Constraint.create(options); - 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; } + this.world.add(constraint); - /** - * The name of the Image Collection. - * - * @name Phaser.Tilemaps.ImageCollection#name - * @type {string} - * @since 3.0.0 - */ - this.name = name; + return constraint; + }, - /** - * 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; + /** + * This method is an alias for `Factory.pointerConstraint`. + * + * A Pointer Constraint is a special type of constraint that allows you to click + * and drag bodies in a Matter World. It monitors the active Pointers in a Scene, + * and when one is pressed down it checks to see if that hit any part of any active + * body in the world. If it did, and the body has input enabled, it will begin to + * drag it until either released, or you stop it via the `stopDrag` method. + * + * You can adjust the stiffness, length and other properties of the constraint via + * the `options` object on creation. + * + * @method Phaser.Physics.Matter.Factory#mouseSpring + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. + * + * @return {MatterJS.ConstraintType} A Matter JS Constraint. + */ + mouseSpring: function (options) + { + return this.pointerConstraint(options); + }, - /** - * The width of the widest image (in pixels). - * - * @name Phaser.Tilemaps.ImageCollection#imageWidth - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageWidth = width | 0; + /** + * A Pointer Constraint is a special type of constraint that allows you to click + * and drag bodies in a Matter World. It monitors the active Pointers in a Scene, + * and when one is pressed down it checks to see if that hit any part of any active + * body in the world. If it did, and the body has input enabled, it will begin to + * drag it until either released, or you stop it via the `stopDrag` method. + * + * You can adjust the stiffness, length and other properties of the constraint via + * the `options` object on creation. + * + * @method Phaser.Physics.Matter.Factory#pointerConstraint + * @since 3.0.0 + * + * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. + * + * @return {MatterJS.ConstraintType} A Matter JS Constraint. + */ + pointerConstraint: function (options) + { + if (options === undefined) { options = {}; } - /** - * The height of the tallest image (in pixels). - * - * @name Phaser.Tilemaps.ImageCollection#imageHeight - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.imageHeight = height | 0; + if (!options.hasOwnProperty('render')) + { + options.render = { visible: false }; + } - /** - * 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; + var pointerConstraint = new PointerConstraint(this.scene, this.world, options); - /** - * 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; + this.world.add(pointerConstraint.constraint); - /** - * 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 || {}; + return pointerConstraint; + }, - /** - * The cached images that are a part of this collection. - * - * @name Phaser.Tilemaps.ImageCollection#images - * @type {array} - * @readonly - * @since 3.0.0 - */ - this.images = []; + /** + * Creates a Matter Physics Image Game Object. + * + * An Image is a light-weight Game Object useful for the display of static images in your game, + * such as logos, backgrounds, scenery or other non-animated elements. Images can have input + * events and physics bodies, or be tweened, tinted or scrolled. The main difference between an + * Image and a Sprite is that you cannot animate an Image as they do not have the Animation component. + * + * @method Phaser.Physics.Matter.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} 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. Set to `null` to skip this value. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {Phaser.Physics.Matter.Image} The Matter Image Game Object. + */ + image: function (x, y, key, frame, options) + { + var image = new MatterImage(this.world, x, y, key, frame, options); - /** - * The total number of images in the image collection. - * - * @name Phaser.Tilemaps.ImageCollection#total - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.total = 0; + this.sys.displayList.add(image); + + return image; }, /** - * Returns true if and only if this image collection contains the given image index. + * Creates a wrapper around a Tile that provides access to a corresponding Matter body. A tile can only + * have one Matter body associated with it. You can either pass in an existing Matter body for + * the tile or allow the constructor to create the corresponding body for you. If the Tile has a + * collision group (defined in Tiled), those shapes will be used to create the body. If not, the + * tile's rectangle bounding box will be used. * - * @method Phaser.Tilemaps.ImageCollection#containsImageIndex + * The corresponding body will be accessible on the Tile itself via Tile.physics.matterBody. + * + * Note: not all Tiled collision shapes are supported. See + * Phaser.Physics.Matter.TileBody#setFromTileCollision for more information. + * + * @method Phaser.Physics.Matter.Factory#tileBody * @since 3.0.0 - * - * @param {number} imageIndex - The image index to search for. - * - * @return {boolean} True if this Image Collection contains the given index. + * + * @param {Phaser.Tilemaps.Tile} tile - The target tile that should have a Matter body. + * @param {Phaser.Types.Physics.Matter.MatterTileOptions} [options] - Options to be used when creating the Matter body. + * + * @return {Phaser.Physics.Matter.TileBody} The Matter Tile Body Game Object. */ - containsImageIndex: function (imageIndex) + tileBody: function (tile, options) { - return (imageIndex >= this.firstgid && imageIndex < (this.firstgid + this.total)); + return new MatterTileBody(this.world, tile, options); }, /** - * Add an image to this Image Collection. + * Creates a Matter Physics Sprite Game Object. * - * @method Phaser.Tilemaps.ImageCollection#addImage + * A Sprite Game Object is used for the display of both static and animated images in your game. + * Sprites can have input events and physics bodies. They can also be tweened, tinted, scrolled + * and animated. + * + * The main difference between a Sprite and an Image Game Object is that you cannot animate Images. + * As such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation + * Component. If you do not require animation then you can safely use Images to replace Sprites in all cases. + * + * @method Phaser.Physics.Matter.Factory#sprite * @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. + * @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. Set to `null` to skip this value. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {Phaser.Physics.Matter.Sprite} The Matter Sprite Game Object. */ - addImage: function (gid, image) + sprite: function (x, y, key, frame, options) { - this.images.push({ gid: gid, image: image }); - this.total++; + var sprite = new MatterSprite(this.world, x, y, key, frame, options); - return this; + this.sys.displayList.add(sprite); + this.sys.updateList.add(sprite); + + return sprite; + }, + + /** + * Takes an existing Game Object and injects all of the Matter Components into it. + * + * This enables you to use component methods such as `setVelocity` or `isSensor` directly from + * this Game Object. + * + * You can also pass in either a Matter Body Configuration object, or a Matter Body instance + * to link with this Game Object. + * + * @method Phaser.Physics.Matter.Factory#gameObject + * @since 3.3.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to inject the Matter Components in to. + * @param {(Phaser.Types.Physics.Matter.MatterBodyConfig|MatterJS.Body)} [options] - A Matter Body configuration object, or an instance of a Matter Body. + * @param {boolean} [addToWorld=true] - Add this Matter Body to the World? + * + * @return {(Phaser.Physics.Matter.Image|Phaser.Physics.Matter.Sprite|Phaser.GameObjects.GameObject)} The Game Object that had the Matter Components injected into it. + */ + gameObject: function (gameObject, options, addToWorld) + { + return MatterGameObject(this.world, gameObject, options, addToWorld); + }, + + /** + * Destroys this Factory. + * + * @method Phaser.Physics.Matter.Factory#destroy + * @since 3.5.0 + */ + destroy: function () + { + this.world = null; + this.scene = null; + this.sys = null; } }); -module.exports = ImageCollection; +module.exports = Factory; /***/ }), -/* 577 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 3860: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Formats = __webpack_require__(40); -var MapData = __webpack_require__(121); -var ParseTileLayers = __webpack_require__(578); -var ParseTilesets = __webpack_require__(579); +var Components = __webpack_require__(74527); +var GetFastValue = __webpack_require__(72632); +var Vector2 = __webpack_require__(93736); /** - * Parses a Weltmeister JSON object into a new MapData object. + * Internal function to check if the object has a getter or setter. * - * @function Phaser.Tilemaps.Parsers.Impact.ParseWeltmeister - * @since 3.0.0 + * @function hasGetterOrSetter + * @private * - * @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. + * @param {object} def - The object to check. * - * @return {?Phaser.Tilemaps.MapData} The created MapData object, or `null` if the data can't be parsed. + * @return {boolean} True if it has a getter or setter, otherwise false. */ -var ParseWeltmeister = function (name, json, insertNull) +function hasGetterOrSetter (def) { - 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; - - -/***/ }), -/* 578 */ -/***/ (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__(120); -var Tile = __webpack_require__(85); + return (!!def.get && typeof def.get === 'function') || (!!def.set && typeof def.set === 'function'); +} /** - * Parses all tilemap layers in an Impact JSON object into new LayerData objects. + * A Matter Game Object is a generic object that allows you to combine any Phaser Game Object, + * including those you have extended or created yourself, with all of the Matter Components. * - * @function Phaser.Tilemaps.Parsers.Impact.ParseTileLayers - * @since 3.0.0 + * This enables you to use component methods such as `setVelocity` or `isSensor` directly from + * this Game Object. * - * @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}). + * @function Phaser.Physics.Matter.MatterGameObject + * @since 3.3.0 * - * @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in - * json.layers with the type 'tilelayer'. + * @param {Phaser.Physics.Matter.World} world - The Matter world to add the body to. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will have the Matter body applied to it. + * @param {(Phaser.Types.Physics.Matter.MatterBodyConfig|MatterJS.Body)} [options] - A Matter Body configuration object, or an instance of a Matter Body. + * @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World? + * + * @return {Phaser.GameObjects.GameObject} The Game Object that was created with the Matter body. */ -var ParseTileLayers = function (json, insertNull) +var MatterGameObject = function (world, gameObject, options, addToWorld) { - var tileLayers = []; + if (options === undefined) { options = {}; } + if (addToWorld === undefined) { addToWorld = true; } - for (var i = 0; i < json.layer.length; i++) - { - var layer = json.layer[i]; + var x = gameObject.x; + var y = gameObject.y; - var layerData = new LayerData({ - name: layer.name, - width: layer.width, - height: layer.height, - tileWidth: layer.tilesize, - tileHeight: layer.tilesize, - visible: layer.visible === 1 - }); + // Temp body pos to avoid body null checks + gameObject.body = { + temp: true, + position: { + x: x, + y: y + } + }; - var row = []; - var tileGrid = []; + var mixins = [ + Components.Bounce, + Components.Collision, + Components.Force, + Components.Friction, + Components.Gravity, + Components.Mass, + Components.Sensor, + Components.SetBody, + Components.Sleep, + Components.Static, + Components.Transform, + Components.Velocity + ]; - // 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++) + // First let's inject all of the components into the Game Object + mixins.forEach(function (mixin) + { + for (var key in mixin) { - for (var x = 0; x < layer.data[y].length; x++) + if (hasGetterOrSetter(mixin[key])) { - // In Weltmeister, 0 = no tile, but the Tilemap API expects -1 = no tile. - var index = layer.data[y][x] - 1; + Object.defineProperty(gameObject, key, { + get: mixin[key].get, + set: mixin[key].set + }); + } + else + { + Object.defineProperty(gameObject, key, {value: mixin[key]}); + } + } - 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); - } + gameObject.world = world; - row.push(tile); - } + gameObject._tempVec2 = new Vector2(x, y); - tileGrid.push(row); - row = []; + if (options.hasOwnProperty('type') && options.type === 'body') + { + gameObject.setExistingBody(options, addToWorld); + } + else + { + var shape = GetFastValue(options, 'shape', null); + + if (!shape) + { + shape = 'rectangle'; } - layerData.data = tileGrid; + options.addToWorld = addToWorld; - tileLayers.push(layerData); + gameObject.setBody(shape, options); } - return tileLayers; + return gameObject; }; -module.exports = ParseTileLayers; +module.exports = MatterGameObject; /***/ }), -/* 579 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 7030: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Tileset = __webpack_require__(122); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(74527); +var GameObject = __webpack_require__(89980); +var GetFastValue = __webpack_require__(72632); +var Image = __webpack_require__(1539); +var Pipeline = __webpack_require__(58210); +var Vector2 = __webpack_require__(93736); /** - * Tilesets and Image Collections + * @classdesc + * A Matter Physics Image Game Object. * - * @function Phaser.Tilemaps.Parsers.Impact.ParseTilesets + * An Image is a light-weight Game Object useful for the display of static images in your game, + * such as logos, backgrounds, scenery or other non-animated elements. Images can have input + * events and physics bodies, or be tweened, tinted or scrolled. The main difference between an + * Image and a Sprite is that you cannot animate an Image as they do not have the Animation component. + * + * @class Image + * @extends Phaser.GameObjects.Image + * @memberof Phaser.Physics.Matter + * @constructor * @since 3.0.0 * - * @param {object} json - The Impact JSON data. + * @extends Phaser.Physics.Matter.Components.Bounce + * @extends Phaser.Physics.Matter.Components.Collision + * @extends Phaser.Physics.Matter.Components.Force + * @extends Phaser.Physics.Matter.Components.Friction + * @extends Phaser.Physics.Matter.Components.Gravity + * @extends Phaser.Physics.Matter.Components.Mass + * @extends Phaser.Physics.Matter.Components.Sensor + * @extends Phaser.Physics.Matter.Components.SetBody + * @extends Phaser.Physics.Matter.Components.Sleep + * @extends Phaser.Physics.Matter.Components.Static + * @extends Phaser.Physics.Matter.Components.Transform + * @extends Phaser.Physics.Matter.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.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @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 * - * @return {array} An array of Tilesets. + * @param {Phaser.Physics.Matter.World} world - A reference to the Matter.World instance that this body belongs to. + * @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. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. */ -var ParseTilesets = function (json) -{ - var tilesets = []; - var tilesetsNames = []; +var MatterImage = new Class({ - for (var i = 0; i < json.layer.length; i++) + Extends: Image, + + Mixins: [ + Components.Bounce, + Components.Collision, + Components.Force, + Components.Friction, + Components.Gravity, + Components.Mass, + Components.Sensor, + Components.SetBody, + Components.Sleep, + Components.Static, + Components.Transform, + Components.Velocity, + Pipeline + ], + + initialize: + + function MatterImage (world, x, y, texture, frame, options) { - var layer = json.layer[i]; + GameObject.call(this, world.scene, 'Image'); - // A relative filepath to the source image (within Weltmeister) is used for the name - var tilesetName = layer.tilesetName; + /** + * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. + * + * @name Phaser.Physics.Matter.Image#_crop + * @type {object} + * @private + * @since 3.24.0 + */ + this._crop = this.resetCropObject(); - // 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); + this.setTexture(texture, frame); + this.setSizeToFrame(); + this.setOrigin(); - // 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)); + /** + * A reference to the Matter.World instance that this body belongs to. + * + * @name Phaser.Physics.Matter.Image#world + * @type {Phaser.Physics.Matter.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * An internal temp vector used for velocity and force calculations. + * + * @name Phaser.Physics.Matter.Image#_tempVec2 + * @type {Phaser.Math.Vector2} + * @private + * @since 3.0.0 + */ + this._tempVec2 = new Vector2(x, y); + + var shape = GetFastValue(options, 'shape', null); + + if (shape) + { + this.setBody(shape, options); } + else + { + this.setRectangle(this.width, this.height, options); + } + + this.setPosition(x, y); + + this.initPipeline(); + this.initPostPipeline(true); } - return tilesets; -}; +}); -module.exports = ParseTilesets; +module.exports = MatterImage; /***/ }), -/* 580 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 50583: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(36); -var Formats = __webpack_require__(40); -var GetFastValue = __webpack_require__(2); -var LayerData = __webpack_require__(120); -var ORIENTATION = __webpack_require__(29); -var Rotate = __webpack_require__(362); -var SpliceOne = __webpack_require__(74); -var Sprite = __webpack_require__(73); -var Tile = __webpack_require__(85); -var TilemapComponents = __webpack_require__(251); -var TilemapLayer = __webpack_require__(581); -var Tileset = __webpack_require__(122); - -/** - * @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. - */ +var ALIGN_CONST = __webpack_require__(84093); +var Axes = __webpack_require__(50658); +var Bodies = __webpack_require__(68516); +var Body = __webpack_require__(84125); +var BodyBounds = __webpack_require__(63568); +var Bounds = __webpack_require__(84091); +var Class = __webpack_require__(56694); +var Collision = __webpack_require__(63454); +var Common = __webpack_require__(68758); +var Composite = __webpack_require__(11299); +var Composites = __webpack_require__(56643); +var Constraint = __webpack_require__(52838); +var Detector = __webpack_require__(13657); +var DistanceBetween = __webpack_require__(53996); +var Factory = __webpack_require__(72653); +var GetFastValue = __webpack_require__(72632); +var GetValue = __webpack_require__(10850); +var MatterAttractors = __webpack_require__(1675); +var MatterCollisionEvents = __webpack_require__(80391); +var MatterLib = __webpack_require__(16929); +var MatterWrap = __webpack_require__(44097); +var Merge = __webpack_require__(30657); +var Pair = __webpack_require__(70584); +var Pairs = __webpack_require__(91327); +var Plugin = __webpack_require__(84474); +var PluginCache = __webpack_require__(91963); +var Query = __webpack_require__(13390); +var Resolver = __webpack_require__(44272); +var SceneEvents = __webpack_require__(7599); +var Svg = __webpack_require__(92765); +var Vector = __webpack_require__(10438); +var Vertices = __webpack_require__(39745); +var World = __webpack_require__(31468); -/** - * @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`. - */ +Common.setDecomp(__webpack_require__(81084)); /** * @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. + * The Phaser Matter plugin provides the ability to use the Matter JS Physics Engine within your Phaser games. * - * 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. + * Unlike Arcade Physics, the other physics system provided with Phaser, Matter JS is a full-body physics system. + * It features: * - * 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. + * * Rigid bodies + * * Compound bodies + * * Composite bodies + * * Concave and convex hulls + * * Physical properties (mass, area, density etc.) + * * Restitution (elastic and inelastic collisions) + * * Collisions (broad-phase, mid-phase and narrow-phase) + * * Stable stacking and resting + * * Conservation of momentum + * * Friction and resistance + * * Constraints + * * Gravity + * * Sleeping and static bodies + * * Rounded corners (chamfering) + * * Views (translate, zoom) + * * Collision queries (raycasting, region tests) + * * Time scaling (slow-mo, speed-up) * - * 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: + * Configuration of Matter is handled via the Matter World Config object, which can be passed in either the + * Phaser Game Config, or Phaser Scene Config. Here is a basic example: * - * - Opacity (blended with parent) and visibility (parent overrides child) - * - Vertical and horizontal offset + * ```js + * physics: { + * default: 'matter', + * matter: { + * enableSleeping: true, + * gravity: { + * y: 0 + * }, + * debug: { + * showBody: true, + * showStaticBody: true + * } + * } + * } + * ``` * - * The grouping hierarchy is not preserved and all layers will be flattened into a single array. + * This class acts as an interface between a Phaser Scene and a single instance of the Matter Engine. * - * Group layers are parsed during Tilemap construction but are discarded after parsing so dynamic - * layers will NOT continue to be affected by a parent. + * Use it to access the most common Matter features and helper functions. * - * 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'. + * You can find details, documentation and examples on the Matter JS website: https://brm.io/matter-js/ * - * @class Tilemap - * @memberof Phaser.Tilemaps + * @class MatterPhysics + * @memberof Phaser.Physics.Matter * @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. + * @param {Phaser.Scene} scene - The Phaser Scene that owns this Matter Physics instance. */ -var Tilemap = new Class({ +var MatterPhysics = new Class({ initialize: - function Tilemap (scene, mapData) + function MatterPhysics (scene) { /** - * @name Phaser.Tilemaps.Tilemap#scene + * The Phaser Scene that owns this Matter Physics instance + * + * @name Phaser.Physics.Matter.MatterPhysics#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. + * A reference to the Scene Systems that belong to the Scene owning this Matter Physics instance. * - * @name Phaser.Tilemaps.Tilemap#tileWidth - * @type {number} + * @name Phaser.Physics.Matter.MatterPhysics#systems + * @type {Phaser.Scenes.Systems} * @since 3.0.0 */ - this.tileWidth = mapData.tileWidth; + this.systems = scene.sys; /** - * The base height of a tile in pixels. Note that individual layers may have a different - * tile height. + * The parsed Matter Configuration object. * - * @name Phaser.Tilemaps.Tilemap#tileHeight - * @type {number} + * @name Phaser.Physics.Matter.MatterPhysics#config + * @type {Phaser.Types.Physics.Matter.MatterWorldConfig} * @since 3.0.0 */ - this.tileHeight = mapData.tileHeight; + this.config = this.getConfig(); /** - * The width of the map (in tiles). + * An instance of the Matter World class. This class is responsible for the updating of the + * Matter Physics world, as well as handling debug drawing functions. * - * @name Phaser.Tilemaps.Tilemap#width - * @type {number} + * @name Phaser.Physics.Matter.MatterPhysics#world + * @type {Phaser.Physics.Matter.World} * @since 3.0.0 */ - this.width = mapData.width; + this.world; /** - * The height of the map (in tiles). + * An instance of the Matter Factory. This class provides lots of functions for creating a + * wide variety of physics objects and adds them automatically to the Matter World. * - * @name Phaser.Tilemaps.Tilemap#height - * @type {number} + * You can use this class to cut-down on the amount of code required in your game, however, + * use of the Factory is entirely optional and should be seen as a development aid. It's + * perfectly possible to create and add components to the Matter world without using it. + * + * @name Phaser.Physics.Matter.MatterPhysics#add + * @type {Phaser.Physics.Matter.Factory} * @since 3.0.0 */ - this.height = mapData.height; + this.add; /** - * The orientation of the map data (as specified in Tiled), usually 'orthogonal'. + * An instance of the Body Bounds class. This class contains functions used for getting the + * world position from various points around the bounds of a physics body. * - * @name Phaser.Tilemaps.Tilemap#orientation - * @type {string} - * @since 3.0.0 + * @name Phaser.Physics.Matter.MatterPhysics#bodyBounds + * @type {Phaser.Physics.Matter.BodyBounds} + * @since 3.22.0 */ - this.orientation = mapData.orientation; + this.bodyBounds; + + // Body /** - * The render (draw) order of the map data (as specified in Tiled), usually 'right-down'. + * A reference to the `Matter.Body` module. * - * The draw orders are: + * The `Matter.Body` module contains methods for creating and manipulating body models. + * A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`. + * Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the `Bodies` module. * - * right-down - * left-down - * right-up - * left-up + * @name Phaser.Physics.Matter.MatterPhysics#body + * @type {MatterJS.BodyFactory} + * @since 3.18.0 + */ + this.body = Body; + + /** + * A reference to the `Matter.Composite` module. * - * This can be changed via the `setRenderOrder` method. + * The `Matter.Composite` module contains methods for creating and manipulating composite bodies. + * A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure. + * It is important to use the functions in this module to modify composites, rather than directly modifying their properties. + * Note that the `Matter.World` object is also a type of `Matter.Composite` and as such all composite methods here can also operate on a `Matter.World`. * - * @name Phaser.Tilemaps.Tilemap#renderOrder - * @type {string} - * @since 3.12.0 + * @name Phaser.Physics.Matter.MatterPhysics#composite + * @type {MatterJS.CompositeFactory} + * @since 3.22.0 */ - this.renderOrder = mapData.renderOrder; + this.composite = Composite; + + // Collision: /** - * The format of the map data. + * A reference to the `Matter.Collision` module. * - * @name Phaser.Tilemaps.Tilemap#format - * @type {number} - * @since 3.0.0 + * The `Matter.Collision` module contains methods for detecting collisions between a given pair of bodies. + * + * For efficient detection between a list of bodies, see `Matter.Detector` and `Matter.Query`. + * + * @name Phaser.Physics.Matter.MatterPhysics#collision + * @type {MatterJS.Collision} + * @since 3.60.0 */ - this.format = mapData.format; + this.collision = Collision; /** - * The version of the map data (as specified in Tiled, usually 1). + * A reference to the `Matter.Detector` module. * - * @name Phaser.Tilemaps.Tilemap#version - * @type {number} - * @since 3.0.0 + * The `Matter.Detector` module contains methods for detecting collisions given a set of pairs. + * + * @name Phaser.Physics.Matter.MatterPhysics#detector + * @type {MatterJS.DetectorFactory} + * @since 3.22.0 + */ + this.detector = Detector; + + /** + * A reference to the `Matter.Pair` module. + * + * The `Matter.Pair` module contains methods for creating and manipulating collision pairs. + * + * @name Phaser.Physics.Matter.MatterPhysics#pair + * @type {MatterJS.PairFactory} + * @since 3.22.0 + */ + this.pair = Pair; + + /** + * A reference to the `Matter.Pairs` module. + * + * The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets. + * + * @name Phaser.Physics.Matter.MatterPhysics#pairs + * @type {MatterJS.PairsFactory} + * @since 3.22.0 + */ + this.pairs = Pairs; + + /** + * A reference to the `Matter.Query` module. + * + * The `Matter.Query` module contains methods for performing collision queries. + * + * @name Phaser.Physics.Matter.MatterPhysics#query + * @type {MatterJS.QueryFactory} + * @since 3.22.0 */ - this.version = mapData.version; + this.query = Query; /** - * Map specific properties as specified in Tiled. + * A reference to the `Matter.Resolver` module. * - * @name Phaser.Tilemaps.Tilemap#properties - * @type {object} - * @since 3.0.0 + * The `Matter.Resolver` module contains methods for resolving collision pairs. + * + * @name Phaser.Physics.Matter.MatterPhysics#resolver + * @type {MatterJS.ResolverFactory} + * @since 3.22.0 */ - this.properties = mapData.properties; + this.resolver = Resolver; + + // Constraint /** - * The width of the map in pixels based on width * tileWidth. + * A reference to the `Matter.Constraint` module. * - * @name Phaser.Tilemaps.Tilemap#widthInPixels - * @type {number} - * @since 3.0.0 + * The `Matter.Constraint` module contains methods for creating and manipulating constraints. + * Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position). + * The stiffness of constraints can be modified to create springs or elastic. + * + * @name Phaser.Physics.Matter.MatterPhysics#constraint + * @type {MatterJS.ConstraintFactory} + * @since 3.22.0 */ - this.widthInPixels = mapData.widthInPixels; + this.constraint = Constraint; + + // Factory /** - * The height of the map in pixels based on height * tileHeight. + * A reference to the `Matter.Bodies` module. * - * @name Phaser.Tilemaps.Tilemap#heightInPixels - * @type {number} - * @since 3.0.0 + * The `Matter.Bodies` module contains factory methods for creating rigid bodies + * with commonly used body configurations (such as rectangles, circles and other polygons). + * + * @name Phaser.Physics.Matter.MatterPhysics#bodies + * @type {MatterJS.BodiesFactory} + * @since 3.18.0 */ - this.heightInPixels = mapData.heightInPixels; + this.bodies = Bodies; /** - * A collection of Images, as parsed from Tiled map data. + * A reference to the `Matter.Composites` module. * - * @name Phaser.Tilemaps.Tilemap#imageCollections - * @type {Phaser.Tilemaps.ImageCollection[]} - * @since 3.0.0 + * The `Matter.Composites` module contains factory methods for creating composite bodies + * with commonly used configurations (such as stacks and chains). + * + * @name Phaser.Physics.Matter.MatterPhysics#composites + * @type {MatterJS.CompositesFactory} + * @since 3.22.0 */ - this.imageCollections = mapData.imageCollections; + this.composites = Composites; + + // Geometry /** - * An array of Tiled Image Layers. + * A reference to the `Matter.Axes` module. * - * @name Phaser.Tilemaps.Tilemap#images - * @type {array} - * @since 3.0.0 + * The `Matter.Axes` module contains methods for creating and manipulating sets of axes. + * + * @name Phaser.Physics.Matter.MatterPhysics#axes + * @type {MatterJS.AxesFactory} + * @since 3.22.0 */ - this.images = mapData.images; + this.axes = Axes; /** - * An array of Tilemap layer data. + * A reference to the `Matter.Bounds` module. * - * @name Phaser.Tilemaps.Tilemap#layers - * @type {Phaser.Tilemaps.LayerData[]} - * @since 3.0.0 + * The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB). + * + * @name Phaser.Physics.Matter.MatterPhysics#bounds + * @type {MatterJS.BoundsFactory} + * @since 3.22.0 */ - this.layers = mapData.layers; + this.bounds = Bounds; /** - * An array of Tilesets used in the map. + * A reference to the `Matter.Svg` module. * - * @name Phaser.Tilemaps.Tilemap#tilesets - * @type {Phaser.Tilemaps.Tileset[]} - * @since 3.0.0 + * The `Matter.Svg` module contains methods for converting SVG images into an array of vector points. + * + * To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg + * + * @name Phaser.Physics.Matter.MatterPhysics#svg + * @type {MatterJS.SvgFactory} + * @since 3.22.0 */ - this.tilesets = mapData.tilesets; + this.svg = Svg; /** - * An array of ObjectLayer instances parsed from Tiled object layers. + * A reference to the `Matter.Vector` module. * - * @name Phaser.Tilemaps.Tilemap#objects - * @type {Phaser.Tilemaps.ObjectLayer[]} - * @since 3.0.0 + * The `Matter.Vector` module contains methods for creating and manipulating vectors. + * Vectors are the basis of all the geometry related operations in the engine. + * A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`. + * + * @name Phaser.Physics.Matter.MatterPhysics#vector + * @type {MatterJS.VectorFactory} + * @since 3.22.0 */ - this.objects = mapData.objects; + this.vector = Vector; /** - * The index of the currently selected LayerData object. + * A reference to the `Matter.Vertices` module. * - * @name Phaser.Tilemaps.Tilemap#currentLayerIndex - * @type {number} - * @since 3.0.0 + * The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices. + * A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`. + * A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull). + * + * @name Phaser.Physics.Matter.MatterPhysics#vertices + * @type {MatterJS.VerticesFactory} + * @since 3.22.0 */ - this.currentLayerIndex = 0; + this.vertices = Vertices; /** - * The length of the horizontal sides of the hexagon. - * Only used for hexagonal orientation Tilemaps. + * A reference to the `Matter.Vertices` module. * - * @name Phaser.Tilemaps.Tilemap#hexSideLength - * @type {number} - * @since 3.50.0 + * The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices. + * A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`. + * A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull). + * + * @name Phaser.Physics.Matter.MatterPhysics#verts + * @type {MatterJS.VerticesFactory} + * @since 3.14.0 */ - this.hexSideLength = mapData.hexSideLength; - - var orientation = this.orientation; + this.verts = Vertices; /** - * Functions used to handle world to tile, and tile to world, conversion. - * Cached here for internal use by public methods such as `worldToTileXY`, etc. + * An internal temp vector used for velocity and force calculations. * - * @name Phaser.Tilemaps.Tilemap#_convert + * @name Phaser.Physics.Matter.MatterPhysics#_tempVec2 + * @type {MatterJS.Vector} * @private - * @type {object} - * @since 3.50.0 + * @since 3.22.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) - }; - }, + this._tempVec2 = Vector.create(); - /** - * @ignore - */ - createBlankDynamicLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) - { - console.warn('createBlankDynamicLayer is deprecated. Use createBlankLayer'); + // Matter plugins - return this.createBlankLayer(name, tileset, x, y, width, height, tileWidth, tileHeight); - }, + if (GetValue(this.config, 'plugins.collisionevents', true)) + { + this.enableCollisionEventsPlugin(); + } - /** - * @ignore - */ - createDynamicLayer: function (layerID, tileset, x, y) - { - console.warn('createDynamicLayer is deprecated. Use createLayer'); + if (GetValue(this.config, 'plugins.attractors', false)) + { + this.enableAttractorPlugin(); + } - return this.createLayer(layerID, tileset, x, y); - }, + if (GetValue(this.config, 'plugins.wrap', false)) + { + this.enableWrapPlugin(); + } - /** - * @ignore - */ - createStaticLayer: function (layerID, tileset, x, y) - { - console.warn('createStaticLayer is deprecated. Use createLayer'); + Resolver._restingThresh = GetValue(this.config, 'restingThresh', 4); + Resolver._restingThreshTangent = GetValue(this.config, 'restingThreshTangent', 6); + Resolver._positionDampen = GetValue(this.config, 'positionDampen', 0.9); + Resolver._positionWarming = GetValue(this.config, 'positionWarming', 0.8); + Resolver._frictionNormalMultiplier = GetValue(this.config, 'frictionNormalMultiplier', 5); - return this.createLayer(layerID, tileset, x, y); + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + scene.sys.events.on(SceneEvents.START, this.start, this); }, /** - * 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'. + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. * - * @return {this} This Tilemap object. + * @method Phaser.Physics.Matter.MatterPhysics#boot + * @private + * @since 3.5.1 */ - setRenderOrder: function (renderOrder) + boot: function () { - 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; - } + this.world = new World(this.scene, this.config); + this.add = new Factory(this.world); + this.bodyBounds = new BodyBounds(); - return this; + this.systems.events.once(SceneEvents.DESTROY, this.destroy, 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. + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. * - * @return {?Phaser.Tilemaps.Tileset} Returns the Tileset object that was created or updated, or null if it - * failed. + * @method Phaser.Physics.Matter.MatterPhysics#start + * @private + * @since 3.5.0 */ - addTilesetImage: function (tilesetName, key, tileWidth, tileHeight, tileMargin, tileSpacing, gid) + start: function () { - 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) + if (!this.world) { - tileset.setTileSize(tileWidth, tileHeight); - tileset.setSpacing(tileMargin, tileSpacing); - tileset.setImage(texture); - - return tileset; + this.world = new World(this.scene, this.config); + this.add = new Factory(this.world); } - 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); + var eventEmitter = this.systems.events; - return tileset; + eventEmitter.on(SceneEvents.UPDATE, this.world.update, this.world); + eventEmitter.on(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world); + eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * 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. + * This internal method is called when this class starts and retrieves the final Matter World Config. * - * @method Phaser.Tilemaps.Tilemap#copy + * @method Phaser.Physics.Matter.MatterPhysics#getConfig * @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. + * @return {Phaser.Types.Physics.Matter.MatterWorldConfig} The Matter World Config. */ - copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) + getConfig: function () { - layer = this.getLayer(layer); + var gameConfig = this.systems.game.config.physics; + var sceneConfig = this.systems.settings.physics; - if (layer !== null) - { - TilemapComponents.Copy( - srcTileX, srcTileY, - width, height, - destTileX, destTileY, - recalculateFaces, layer - ); + var config = Merge( + GetFastValue(sceneConfig, 'matter', {}), + GetFastValue(gameConfig, 'matter', {}) + ); - return this; - } - else - { - return null; - } + return config; }, /** - * Creates a new and empty Tilemap Layer. The currently selected layer in the map is set to this new layer. + * Enables the Matter Attractors Plugin. * - * Prior to v3.50.0 this method was called `createBlankDynamicLayer`. + * The attractors plugin that makes it easy to apply continual forces on bodies. + * It's possible to simulate effects such as wind, gravity and magnetism. * - * @method Phaser.Tilemaps.Tilemap#createBlankLayer - * @since 3.0.0 + * https://github.com/liabru/matter-attractors * - * @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. + * This method is called automatically if `plugins.attractors` is set in the Matter World Config. + * However, you can also call it directly from within your game. * - * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer that was created, or `null` if it failed. + * @method Phaser.Physics.Matter.MatterPhysics#enableAttractorPlugin + * @since 3.0.0 + * + * @return {this} This Matter Physics instance. */ - createBlankLayer: function (name, tileset, x, y, width, height, tileWidth, tileHeight) + enableAttractorPlugin: function () { - 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); + Plugin.register(MatterAttractors); + Plugin.use(MatterLib, MatterAttractors); - return layer; + return this; }, /** - * 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. + * Enables the Matter Wrap Plugin. * - * 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. + * The coordinate wrapping plugin that automatically wraps the position of bodies such that they always stay + * within the given bounds. Upon crossing a boundary the body will appear on the opposite side of the bounds, + * while maintaining its velocity. * - * Prior to v3.50.0 this method was called `createDynamicLayer`. + * https://github.com/liabru/matter-wrap * - * @method Phaser.Tilemaps.Tilemap#createLayer - * @since 3.0.0 + * This method is called automatically if `plugins.wrap` is set in the Matter World Config. + * However, you can also call it directly from within your game. * - * @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. + * @method Phaser.Physics.Matter.MatterPhysics#enableWrapPlugin + * @since 3.0.0 * - * @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer was created, or null if it failed. + * @return {this} This Matter Physics instance. */ - createLayer: function (layerID, tileset, x, y) + enableWrapPlugin: function () { - 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); + Plugin.register(MatterWrap); + Plugin.use(MatterLib, MatterWrap); - return layer; + return this; }, /** - * 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: + * Enables the Matter Collision Events Plugin. * - * ```javascript - * createFromObjects(layerName, { - * id: 9 - * }); - * ``` + * Note that this plugin is enabled by default. So you should only ever need to call this + * method if you have specifically disabled the plugin in your Matter World Config. + * You can disable it by setting `plugins.collisionevents: false` in your Matter World Config. * - * 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. + * This plugin triggers three new events on Matter.Body: * - * By default this method will convert objects into `Sprite` instances, but you can override - * this by providing your own class type: + * 1. `onCollide` + * 2. `onCollideEnd` + * 3. `onCollideActive` * - * ```javascript - * createFromObjects(layerName, { - * gid: 26, - * classType: Coin - * }); - * ``` + * These events correspond to the Matter.js events `collisionStart`, `collisionActive` and `collisionEnd`, respectively. + * You can listen to these events via Matter.Events or they will also be emitted from the Matter World. * - * 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. + * This plugin also extends Matter.Body with three convenience functions: * - * 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. + * `Matter.Body.setOnCollide(callback)` + * `Matter.Body.setOnCollideEnd(callback)` + * `Matter.Body.setOnCollideActive(callback)` * - * 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 register event callbacks by providing a function of type (pair: Matter.Pair) => void * - * 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. + * https://github.com/dxu/matter-collision-events * - * Finally, you can provide an array of config objects, to convert multiple types of object in - * a single call: + * @method Phaser.Physics.Matter.MatterPhysics#enableCollisionEventsPlugin + * @since 3.22.0 * - * ```javascript - * createFromObjects(layerName, [ - * { - * gid: 26, - * classType: Coin - * }, - * { - * id: 9, - * classType: BossMonster - * }, - * { - * name: 'lava', - * classType: LavaTile - * } - * ]); - * ``` + * @return {this} This Matter Physics instance. + */ + enableCollisionEventsPlugin: function () + { + Plugin.register(MatterCollisionEvents); + Plugin.use(MatterLib, MatterCollisionEvents); + + return this; + }, + + /** + * Pauses the Matter World instance and sets `enabled` to `false`. * - * The signature of this method changed significantly in v3.50.0. Prior to this, it did not take config objects. + * A paused world will not run any simulations for the duration it is paused. * - * @method Phaser.Tilemaps.Tilemap#createFromObjects + * @method Phaser.Physics.Matter.MatterPhysics#pause + * @fires Phaser.Physics.Matter.Events#PAUSE * @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. + * @return {Phaser.Physics.Matter.World} The Matter World object. */ - createFromObjects: function (objectLayerName, config) + pause: function () { - 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 - if (Array.isArray(obj.properties)) - { - // Tiled objects custom properties format - obj.properties.forEach(function (propData) - { - var key = propData['name']; - if (sprite[key] !== undefined) - { - sprite[key] = propData['value']; - } - else - { - sprite.setData(key, propData['value']); - } - }); - } - else - { - 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; + return this.world.pause(); }, /** - * 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. + * Resumes this Matter World instance from a paused state and sets `enabled` to `true`. * - * @method Phaser.Tilemaps.Tilemap#createFromTiles + * @method Phaser.Physics.Matter.MatterPhysics#resume * @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. + * @return {Phaser.Physics.Matter.World} The Matter World object. */ - createFromTiles: function (indexes, replacements, spriteConfig, scene, camera, layer) + resume: function () { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, layer); + return this.world.resume(); }, /** - * 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 + * Sets the Matter Engine to run at fixed timestep of 60Hz and enables `autoUpdate`. + * If you have set a custom `getDelta` function then this will override it. * - * @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. + * @method Phaser.Physics.Matter.MatterPhysics#set60Hz + * @since 3.4.0 * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + * @return {this} This Matter Physics instance. */ - fill: function (index, tileX, tileY, width, height, recalculateFaces, layer) + set60Hz: function () { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); + this.world.getDelta = this.world.update60Hz; + this.world.autoUpdate = true; - if (layer === null) { return null; } + return this; + }, - TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, layer); + /** + * Sets the Matter Engine to run at fixed timestep of 30Hz and enables `autoUpdate`. + * If you have set a custom `getDelta` function then this will override it. + * + * @method Phaser.Physics.Matter.MatterPhysics#set30Hz + * @since 3.4.0 + * + * @return {this} This Matter Physics instance. + */ + set30Hz: function () + { + this.world.getDelta = this.world.update30Hz; + this.world.autoUpdate = true; 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. + * Manually advances the physics simulation by one iteration. * - * @method Phaser.Tilemaps.Tilemap#filterObjects - * @since 3.0.0 + * You can optionally pass in the `delta` and `correction` values to be used by Engine.update. + * If undefined they use the Matter defaults of 60Hz and no correction. * - * @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. + * Calling `step` directly bypasses any checks of `enabled` or `autoUpdate`. * - * @return {?Phaser.Types.Tilemaps.TiledObject[]} An array of object that match the search, or null if the objectLayer given was invalid. + * It also ignores any custom `getDelta` functions, as you should be passing the delta + * value in to this call. + * + * You can adjust the number of iterations that Engine.update performs internally. + * Use the Scene Matter Physics config object to set the following properties: + * + * positionIterations (defaults to 6) + * velocityIterations (defaults to 4) + * constraintIterations (defaults to 2) + * + * Adjusting these values can help performance in certain situations, depending on the physics requirements + * of your game. + * + * @method Phaser.Physics.Matter.MatterPhysics#step + * @since 3.4.0 + * + * @param {number} [delta=16.666] - The delta value. + * @param {number} [correction=1] - Optional delta correction value. */ - filterObjects: function (objectLayer, callback, context) + step: function (delta, correction) { - 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); + this.world.step(delta, correction); }, /** - * 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. + * Checks if the vertices of the given body, or an array of bodies, contains the given point, or not. * - * @method Phaser.Tilemaps.Tilemap#filterTiles - * @since 3.0.0 + * You can pass in either a single body, or an array of bodies to be checked. This method will + * return `true` if _any_ of the bodies in the array contain the point. See the `intersectPoint` method if you need + * to get a list of intersecting bodies. * - * @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. + * The point should be transformed into the Matter World coordinate system in advance. This happens by + * default with Input Pointers, but if you wish to use points from another system you may need to + * transform them before passing them. * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + * @method Phaser.Physics.Matter.MatterPhysics#containsPoint + * @since 3.22.0 + * + * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} body - The body, or an array of bodies, to check against the point. + * @param {number} x - The horizontal coordinate of the point. + * @param {number} y - The vertical coordinate of the point. + * + * @return {boolean} `true` if the point is within one of the bodies given, otherwise `false`. */ - filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) + containsPoint: function (body, x, y) { - layer = this.getLayer(layer); + body = this.getMatterBodies(body); - if (layer === null) { return null; } + var position = Vector.create(x, y); - return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, layer); + var result = Query.point(body, position); + + return (result.length > 0) ? true : false; }, /** - * 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. + * Checks the given coordinates to see if any vertices of the given bodies contain it. * - * @method Phaser.Tilemaps.Tilemap#findByIndex - * @since 3.0.0 + * If no bodies are provided it will search all bodies in the Matter World, including within Composites. * - * @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. + * The coordinates should be transformed into the Matter World coordinate system in advance. This happens by + * default with Input Pointers, but if you wish to use coordinates from another system you may need to + * transform them before passing them. * - * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. + * @method Phaser.Physics.Matter.MatterPhysics#intersectPoint + * @since 3.22.0 + * + * @param {number} x - The horizontal coordinate of the point. + * @param {number} y - The vertical coordinate of the point. + * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world. + * + * @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies which contain the given point. */ - findByIndex: function (findIndex, skip, reverse, layer) + intersectPoint: function (x, y, bodies) { - layer = this.getLayer(layer); + bodies = this.getMatterBodies(bodies); - if (layer === null) { return null; } + var position = Vector.create(x, y); - return TilemapComponents.FindByIndex(findIndex, skip, reverse, layer); + var output = []; + + var result = Query.point(bodies, position); + + result.forEach(function (body) + { + if (output.indexOf(body) === -1) + { + output.push(body); + } + }); + + return output; }, /** - * 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. + * Checks the given rectangular area to see if any vertices of the given bodies intersect with it. + * Or, if the `outside` parameter is set to `true`, it checks to see which bodies do not + * intersect with it. * - * @method Phaser.Tilemaps.Tilemap#findObject - * @since 3.0.0 + * If no bodies are provided it will search all bodies in the Matter World, including within Composites. * - * @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. + * @method Phaser.Physics.Matter.MatterPhysics#intersectRect + * @since 3.22.0 * - * @return {?Phaser.Types.Tilemaps.TiledObject} An object that matches the search, or null if no object found. + * @param {number} x - The horizontal coordinate of the top-left of the area. + * @param {number} y - The vertical coordinate of the top-left of the area. + * @param {number} width - The width of the area. + * @param {number} height - The height of the area. + * @param {boolean} [outside=false] - If `false` it checks for vertices inside the area, if `true` it checks for vertices outside the area. + * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world. + * + * @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies that intersect with the given area. */ - findObject: function (objectLayer, callback, context) + intersectRect: function (x, y, width, height, outside, bodies) { - if (typeof objectLayer === 'string') - { - var name = objectLayer; + if (outside === undefined) { outside = false; } - objectLayer = this.getObjectLayer(objectLayer); + bodies = this.getMatterBodies(bodies); - if (!objectLayer) + var bounds = { + min: { x: x, y: y }, + max: { x: x + width, y: y + height } + }; + + var output = []; + + var result = Query.region(bodies, bounds, outside); + + result.forEach(function (body) + { + if (output.indexOf(body) === -1) { - console.warn('No object layer found with the name: ' + name); - return null; + output.push(body); } - } + }); - return objectLayer.objects.find(callback, context) || null; + return output; }, /** - * 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. + * Checks the given ray segment to see if any vertices of the given bodies intersect with it. * - * @method Phaser.Tilemaps.Tilemap#findTile - * @since 3.0.0 + * If no bodies are provided it will search all bodies in the Matter World. * - * @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. + * The width of the ray can be specified via the `rayWidth` parameter. + * + * @method Phaser.Physics.Matter.MatterPhysics#intersectRay + * @since 3.22.0 + * + * @param {number} x1 - The horizontal coordinate of the start of the ray segment. + * @param {number} y1 - The vertical coordinate of the start of the ray segment. + * @param {number} x2 - The horizontal coordinate of the end of the ray segment. + * @param {number} y2 - The vertical coordinate of the end of the ray segment. + * @param {number} [rayWidth=1] - The width of the ray segment. + * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world. * - * @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid. + * @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with the ray segment. */ - findTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) + intersectRay: function (x1, y1, x2, y2, rayWidth, bodies) { - layer = this.getLayer(layer); + if (rayWidth === undefined) { rayWidth = 1; } - if (layer === null) { return null; } + bodies = this.getMatterBodies(bodies); - return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); + var result = []; + var collisions = Query.ray(bodies, Vector.create(x1, y1), Vector.create(x2, y2), rayWidth); + + for (var i = 0; i < collisions.length; i++) + { + result.push(collisions[i].body); + } + + return result; }, /** - * 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. + * Checks the given Matter Body to see if it intersects with any of the given bodies. * - * If no layer specified, the map's current layer is used. + * If no bodies are provided it will check against all bodies in the Matter World. * - * @method Phaser.Tilemaps.Tilemap#forEachTile - * @since 3.0.0 + * @method Phaser.Physics.Matter.MatterPhysics#intersectBody + * @since 3.22.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. + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The target body. + * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check the target body against. If not provided it will search all bodies in the world. * - * @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid. + * @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with target body. */ - forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) + intersectBody: function (body, bodies) { - layer = this.getLayer(layer); + bodies = this.getMatterBodies(bodies); - if (layer === null) { return null; } + var result = []; + var collisions = Query.collides(body, bodies); - TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); + for (var i = 0; i < collisions.length; i++) + { + var pair = collisions[i]; - return this; + if (pair.bodyA === body) + { + result.push(pair.bodyB); + } + else + { + result.push(pair.bodyA); + } + } + + return result; }, /** - * Gets the image layer index based on its name. + * Checks to see if the target body, or an array of target bodies, intersects with any of the given bodies. * - * @method Phaser.Tilemaps.Tilemap#getImageIndex - * @since 3.0.0 + * If intersection occurs this method will return `true` and, if provided, invoke the callbacks. * - * @param {string} name - The name of the image to get. + * If no bodies are provided for the second parameter the target will check again all bodies in the Matter World. * - * @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. + * Note that bodies can only overlap if they are in non-colliding collision groups or categories. * - * @method Phaser.Tilemaps.Tilemap#getImageLayerNames - * @since 3.21.0 + * If you provide a `processCallback` then the two bodies that overlap are sent to it. This callback + * must return a boolean and is used to allow you to perform additional processing tests before a final + * outcome is decided. If it returns `true` then the bodies are finally passed to the `overlapCallback`, if set. * - * @return {string[]} Array of valid imagelayer names / IDs loaded into this Tilemap. + * If you provide an `overlapCallback` then the matching pairs of overlapping bodies will be sent to it. + * + * Both callbacks have the following signature: `function (bodyA, bodyB, collisionInfo)` where `bodyA` is always + * the target body. The `collisionInfo` object contains additional data, such as the angle and depth of penetration. + * + * @method Phaser.Physics.Matter.MatterPhysics#overlap + * @since 3.22.0 + * + * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} target - The target body, or array of target bodies, to check. + * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - The second body, or array of bodies, to check. If falsey it will check against all bodies in the world. + * @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the bodies overlap. + * @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two bodies if they overlap. If this is set then `overlapCallback` will only be invoked if this callback returns `true`. + * @param {*} [callbackContext] - The context, or scope, in which to run the callbacks. + * + * @return {boolean} `true` if the target body intersects with _any_ of the bodies given, otherwise `false`. */ - getImageLayerNames: function () + overlap: function (target, bodies, overlapCallback, processCallback, callbackContext) { - if (!this.images || !Array.isArray(this.images)) + if (overlapCallback === undefined) { overlapCallback = null; } + if (processCallback === undefined) { processCallback = null; } + if (callbackContext === undefined) { callbackContext = overlapCallback; } + + if (!Array.isArray(target)) { - return []; + target = [ target ]; } - return this.images.map(function (image) - { - return image.name; - }); - }, + target = this.getMatterBodies(target); + bodies = this.getMatterBodies(bodies); - /** - * 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++) + var match = false; + + for (var i = 0; i < target.length; i++) { - if (location[i].name === name) + var entry = target[i]; + + var collisions = Query.collides(entry, bodies); + + for (var c = 0; c < collisions.length; c++) { - return i; + var info = collisions[c]; + var bodyB = (info.bodyA.id === entry.id) ? info.bodyB : info.bodyA; + + if (!processCallback || processCallback.call(callbackContext, entry, bodyB, info)) + { + match = true; + + if (overlapCallback) + { + overlapCallback.call(callbackContext, entry, bodyB, info); + } + else if (!processCallback) + { + // If there are no callbacks we don't need to test every body, just exit when the first is found + return true; + } + } } } - return null; + return match; }, /** - * Gets the LayerData from `this.layers` that is associated with the given `layer`, or null if the layer is invalid. + * Sets the collision filter category of all given Matter Bodies to the given value. * - * @method Phaser.Tilemaps.Tilemap#getLayer - * @since 3.0.0 + * This number must be a power of two between 2^0 (= 1) and 2^31. * - * @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. + * Bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision + * categories are included in their collision masks (see {@link #setCollidesWith}). + * + * @method Phaser.Physics.Matter.MatterPhysics#setCollisionCategory + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world. + * @param {number} value - Unique category bitfield. * - * @return {Phaser.Tilemaps.LayerData} The corresponding LayerData within this.layers. + * @return {this} This Matter Physics instance. */ - getLayer: function (layer) + setCollisionCategory: function (bodies, value) { - var index = this.getLayerIndex(layer); + bodies = this.getMatterBodies(bodies); - return (index !== null) ? this.layers[index] : null; + bodies.forEach(function (body) + { + body.collisionFilter.category = value; + }); + + return this; }, /** - * Gets the ObjectLayer from `this.objects` that has the given `name`, or null if no ObjectLayer is found with that name. + * Sets the collision filter group of all given Matter Bodies to the given value. * - * @method Phaser.Tilemaps.Tilemap#getObjectLayer - * @since 3.0.0 + * If the group value is zero, or if two Matter Bodies have different group values, + * they will collide according to the usual collision filter rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}). * - * @param {string} [name] - The name of the object layer from Tiled. + * If two Matter Bodies have the same positive group value, they will always collide; + * if they have the same negative group value they will never collide. * - * @return {?Phaser.Tilemaps.ObjectLayer} The corresponding `ObjectLayer` within `this.objects`, or null. + * @method Phaser.Physics.Matter.MatterPhysics#setCollisionGroup + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world. + * @param {number} value - Unique group index. + * + * @return {this} This Matter Physics instance. */ - getObjectLayer: function (name) + setCollisionGroup: function (bodies, value) { - var index = this.getIndex(this.objects, name); + bodies = this.getMatterBodies(bodies); - return (index !== null) ? this.objects[index] : null; + bodies.forEach(function (body) + { + body.collisionFilter.group = value; + }); + + return this; }, /** - * Return a list of all valid objectgroup names loaded in this Tilemap. + * Sets the collision filter mask of all given Matter Bodies to the given value. * - * @method Phaser.Tilemaps.Tilemap#getObjectLayerNames - * @since 3.21.0 + * Two Matter Bodies with different collision groups will only collide if each one includes the others + * category in its mask based on a bitwise AND operation: `(categoryA & maskB) !== 0` and + * `(categoryB & maskA) !== 0` are both true. * - * @return {string[]} Array of valid objectgroup names / IDs loaded into this Tilemap. + * @method Phaser.Physics.Matter.MatterPhysics#setCollidesWith + * @since 3.22.0 + * + * @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world. + * @param {(number|number[])} categories - A unique category bitfield, or an array of them. + * + * @return {this} This Matter Physics instance. */ - getObjectLayerNames: function () + setCollidesWith: function (bodies, categories) { - if (!this.objects || !Array.isArray(this.objects)) + bodies = this.getMatterBodies(bodies); + + var flags = 0; + + if (!Array.isArray(categories)) { - return []; + flags = categories; + } + else + { + for (var i = 0; i < categories.length; i++) + { + flags |= categories[i]; + } } - return this.objects.map(function (object) + bodies.forEach(function (body) { - return object.name; + body.collisionFilter.mask = flags; }); + + return this; }, /** - * Gets the LayerData index of the given `layer` within this.layers, or null if an invalid - * `layer` is given. + * Takes an array and returns a new array made from all of the Matter Bodies found in the original array. * - * @method Phaser.Tilemaps.Tilemap#getLayerIndex - * @since 3.0.0 + * For example, passing in Matter Game Objects, such as a bunch of Matter Sprites, to this method, would + * return an array containing all of their native Matter Body objects. * - * @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. + * If the `bodies` argument is falsey, it will return all bodies in the world. * - * @return {number} The LayerData index within this.layers. + * @method Phaser.Physics.Matter.MatterPhysics#getMatterBodies + * @since 3.22.0 + * + * @param {array} [bodies] - An array of objects to extract the bodies from. If falsey, it will return all bodies in the world. + * + * @return {MatterJS.BodyType[]} An array of native Matter Body objects. */ - getLayerIndex: function (layer) + getMatterBodies: function (bodies) { - if (layer === undefined) - { - return this.currentLayerIndex; - } - else if (typeof layer === 'string') - { - return this.getLayerIndexByName(layer); - } - else if (typeof layer === 'number' && layer < this.layers.length) + if (!bodies) { - return layer; + return this.world.getAllBodies(); } - else if (layer instanceof TilemapLayer) + + if (!Array.isArray(bodies)) { - return layer.layerIndex; + bodies = [ bodies ]; } - else + + var output = []; + + for (var i = 0; i < bodies.length; i++) { - return null; + var body = (bodies[i].hasOwnProperty('body')) ? bodies[i].body : bodies[i]; + + output.push(body); } + + return output; }, /** - * Gets the index of the LayerData within this.layers that has the given `name`, or null if an - * invalid `name` is given. + * Sets both the horizontal and vertical linear velocity of the physics bodies. * - * @method Phaser.Tilemaps.Tilemap#getLayerIndexByName - * @since 3.0.0 + * @method Phaser.Physics.Matter.MatterPhysics#setVelocity + * @since 3.22.0 * - * @param {string} name - The name of the layer to get. + * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. + * @param {number} x - The horizontal linear velocity value. + * @param {number} y - The vertical linear velocity value. * - * @return {number} The LayerData index within this.layers. + * @return {this} This Matter Physics instance. */ - getLayerIndexByName: function (name) + setVelocity: function (bodies, x, y) { - return this.getIndex(this.layers, name); + bodies = this.getMatterBodies(bodies); + + var vec2 = this._tempVec2; + + vec2.x = x; + vec2.y = y; + + bodies.forEach(function (body) + { + Body.setVelocity(body, vec2); + }); + + return this; }, /** - * Gets a tile at the given tile coordinates from the given layer. - * - * If no layer is specified, the maps current layer is used. + * Sets just the horizontal linear velocity of the physics bodies. + * The vertical velocity of the body is unchanged. * - * @method Phaser.Tilemaps.Tilemap#getTileAt - * @since 3.0.0 + * @method Phaser.Physics.Matter.MatterPhysics#setVelocityX + * @since 3.22.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. + * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. + * @param {number} x - The horizontal linear velocity value. * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + * @return {this} This Matter Physics instance. */ - getTileAt: function (tileX, tileY, nonNull, layer) + setVelocityX: function (bodies, x) { - layer = this.getLayer(layer); + bodies = this.getMatterBodies(bodies); - if (layer === null) { return null; } + var vec2 = this._tempVec2; - return TilemapComponents.GetTileAt(tileX, tileY, nonNull, layer); + vec2.x = x; + + bodies.forEach(function (body) + { + vec2.y = body.velocity.y; + Body.setVelocity(body, vec2); + }); + + return this; }, /** - * Gets a tile at the given world coordinates from the given layer. - * - * If no layer is specified, the maps current layer is used. + * Sets just the vertical linear velocity of the physics bodies. + * The horizontal velocity of the body is unchanged. * - * @method Phaser.Tilemaps.Tilemap#getTileAtWorldXY - * @since 3.0.0 + * @method Phaser.Physics.Matter.MatterPhysics#setVelocityY + * @since 3.22.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. + * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. + * @param {number} y - The vertical linear velocity value. * - * @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid. + * @return {this} This Matter Physics instance. */ - getTileAtWorldXY: function (worldX, worldY, nonNull, camera, layer) + setVelocityY: function (bodies, y) { - layer = this.getLayer(layer); + bodies = this.getMatterBodies(bodies); - if (layer === null) { return null; } + var vec2 = this._tempVec2; - return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, layer); + vec2.y = y; + + bodies.forEach(function (body) + { + vec2.x = body.velocity.x; + Body.setVelocity(body, vec2); + }); + + return this; }, /** - * Return a list of all valid tilelayer names loaded in this Tilemap. + * Sets the angular velocity of the bodies instantly. + * Position, angle, force etc. are unchanged. * - * @method Phaser.Tilemaps.Tilemap#getTileLayerNames - * @since 3.21.0 + * @method Phaser.Physics.Matter.MatterPhysics#setAngularVelocity + * @since 3.22.0 * - * @return {string[]} Array of valid tilelayer names / IDs loaded into this Tilemap. + * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. + * @param {number} value - The angular velocity. + * + * @return {this} This Matter Physics instance. */ - getTileLayerNames: function () + setAngularVelocity: function (bodies, value) { - if (!this.layers || !Array.isArray(this.layers)) - { - return []; - } + bodies = this.getMatterBodies(bodies); - return this.layers.map(function (layer) + bodies.forEach(function (body) { - return layer.name; + Body.setAngularVelocity(body, value); }); + + return this; }, /** - * 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. + * Applies a force to a body, at the bodies current position, including resulting torque. * - * @method Phaser.Tilemaps.Tilemap#getTilesWithin - * @since 3.0.0 + * @method Phaser.Physics.Matter.MatterPhysics#applyForce + * @since 3.22.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. + * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. + * @param {Phaser.Types.Math.Vector2Like} force - A Vector that specifies the force to apply. * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + * @return {this} This Matter Physics instance. */ - getTilesWithin: function (tileX, tileY, width, height, filteringOptions, layer) + applyForce: function (bodies, force) { - layer = this.getLayer(layer); + bodies = this.getMatterBodies(bodies); - if (layer === null) { return null; } + var vec2 = this._tempVec2; - return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); + bodies.forEach(function (body) + { + vec2.x = body.position.x; + vec2.y = body.position.y; + + Body.applyForce(body, vec2, force); + }); + + return this; }, /** - * 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. + * Applies a force to a body, from the given world position, including resulting torque. + * If no angle is given, the current body angle is used. * - * If no layer is specified, the maps current layer is used. + * Use very small speed values, such as 0.1, depending on the mass and required velocity. * - * @method Phaser.Tilemaps.Tilemap#getTilesWithinShape - * @since 3.0.0 + * @method Phaser.Physics.Matter.MatterPhysics#applyForceFromPosition + * @since 3.22.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. + * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. + * @param {Phaser.Types.Math.Vector2Like} position - A Vector that specifies the world-space position to apply the force at. + * @param {number} speed - A speed value to be applied to a directional force. + * @param {number} [angle] - The angle, in radians, to apply the force from. Leave undefined to use the current body angle. * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + * @return {this} This Matter Physics instance. */ - getTilesWithinShape: function (shape, filteringOptions, camera, layer) + applyForceFromPosition: function (bodies, position, speed, angle) { - layer = this.getLayer(layer); + bodies = this.getMatterBodies(bodies); - if (layer === null) { return null; } + var vec2 = this._tempVec2; - return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, layer); + bodies.forEach(function (body) + { + if (angle === undefined) + { + angle = body.angle; + } + + vec2.x = speed * Math.cos(angle); + vec2.y = speed * Math.sin(angle); + + Body.applyForce(body, position, vec2); + }); + + return this; }, /** - * Gets the tiles in the given rectangular area (in world coordinates) of the layer. + * Apply a force to a body based on the given angle and speed. + * If no angle is given, the current body angle is used. * - * If no layer is specified, the maps current layer is used. + * Use very small speed values, such as 0.1, depending on the mass and required velocity. * - * @method Phaser.Tilemaps.Tilemap#getTilesWithinWorldXY - * @since 3.0.0 + * @method Phaser.Physics.Matter.MatterPhysics#applyForceFromAngle + * @since 3.22.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. + * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. + * @param {number} speed - A speed value to be applied to a directional force. + * @param {number} [angle] - The angle, in radians, to apply the force from. Leave undefined to use the current body angle. * - * @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid. + * @return {this} This Matter Physics instance. */ - getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera, layer) + applyForceFromAngle: function (bodies, speed, angle) { - layer = this.getLayer(layer); + bodies = this.getMatterBodies(bodies); - if (layer === null) { return null; } + var vec2 = this._tempVec2; - return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, layer); + bodies.forEach(function (body) + { + if (angle === undefined) + { + angle = body.angle; + } + + vec2.x = speed * Math.cos(angle); + vec2.y = speed * Math.sin(angle); + + Body.applyForce(body, { x: body.position.x, y: body.position.y }, vec2); + }); + + return this; }, /** - * Gets the Tileset that has the given `name`, or null if an invalid `name` is given. + * Returns the length of the given constraint, which is the distance between the two points. * - * @method Phaser.Tilemaps.Tilemap#getTileset - * @since 3.14.0 + * @method Phaser.Physics.Matter.MatterPhysics#getConstraintLength + * @since 3.22.0 * - * @param {string} name - The name of the Tileset to get. + * @param {MatterJS.ConstraintType} constraint - The constraint to get the length from. * - * @return {?Phaser.Tilemaps.Tileset} The Tileset, or `null` if no matching named tileset was found. + * @return {number} The length of the constraint. */ - getTileset: function (name) + getConstraintLength: function (constraint) { - var index = this.getIndex(this.tilesets, name); + var aX = constraint.pointA.x; + var aY = constraint.pointA.y; + var bX = constraint.pointB.x; + var bY = constraint.pointB.y; - return (index !== null) ? this.tilesets[index] : null; + if (constraint.bodyA) + { + aX += constraint.bodyA.position.x; + aY += constraint.bodyA.position.y; + } + + if (constraint.bodyB) + { + bX += constraint.bodyB.position.x; + bY += constraint.bodyB.position.y; + } + + return DistanceBetween(aX, aY, bX, bY); }, /** - * Gets the index of the Tileset within this.tilesets that has the given `name`, or null if an - * invalid `name` is given. + * Aligns a Body, or Matter Game Object, against the given coordinates. * - * @method Phaser.Tilemaps.Tilemap#getTilesetIndex - * @since 3.0.0 + * The alignment takes place using the body bounds, which take into consideration things + * like body scale and rotation. * - * @param {string} name - The name of the Tileset to get. + * Although a Body has a `position` property, it is based on the center of mass for the body, + * not a dimension based center. This makes aligning bodies difficult, especially if they have + * rotated or scaled. This method will derive the correct position based on the body bounds and + * its center of mass offset, in order to align the body with the given coordinate. * - * @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. + * For example, if you wanted to align a body so it sat in the bottom-center of the + * Scene, and the world was 800 x 600 in size: * - * If no layer is specified, the maps current layer is used. + * ```javascript + * this.matter.alignBody(body, 400, 600, Phaser.Display.Align.BOTTOM_CENTER); + * ``` * - * @method Phaser.Tilemaps.Tilemap#hasTileAt - * @since 3.0.0 + * You pass in 400 for the x coordinate, because that is the center of the world, and 600 for + * the y coordinate, as that is the base of the world. * - * @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. + * @method Phaser.Physics.Matter.MatterPhysics#alignBody + * @since 3.22.0 * - * @return {?boolean} Returns a boolean, or null if the layer given was invalid. + * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to align. + * @param {number} x - The horizontal position to align the body to. + * @param {number} y - The vertical position to align the body to. + * @param {number} align - One of the `Phaser.Display.Align` constants, such as `Phaser.Display.Align.TOP_LEFT`. + * + * @return {this} This Matter Physics instance. */ - hasTileAt: function (tileX, tileY, layer) + alignBody: function (body, x, y, align) { - layer = this.getLayer(layer); + body = (body.hasOwnProperty('body')) ? body.body : body; - if (layer === null) { return null; } + var pos; - return TilemapComponents.HasTileAt(tileX, tileY, layer); + switch (align) + { + case ALIGN_CONST.TOP_LEFT: + case ALIGN_CONST.LEFT_TOP: + pos = this.bodyBounds.getTopLeft(body, x, y); + break; + + case ALIGN_CONST.TOP_CENTER: + pos = this.bodyBounds.getTopCenter(body, x, y); + break; + + case ALIGN_CONST.TOP_RIGHT: + case ALIGN_CONST.RIGHT_TOP: + pos = this.bodyBounds.getTopRight(body, x, y); + break; + + case ALIGN_CONST.LEFT_CENTER: + pos = this.bodyBounds.getLeftCenter(body, x, y); + break; + + case ALIGN_CONST.CENTER: + pos = this.bodyBounds.getCenter(body, x, y); + break; + + case ALIGN_CONST.RIGHT_CENTER: + pos = this.bodyBounds.getRightCenter(body, x, y); + break; + + case ALIGN_CONST.LEFT_BOTTOM: + case ALIGN_CONST.BOTTOM_LEFT: + pos = this.bodyBounds.getBottomLeft(body, x, y); + break; + + case ALIGN_CONST.BOTTOM_CENTER: + pos = this.bodyBounds.getBottomCenter(body, x, y); + break; + + case ALIGN_CONST.BOTTOM_RIGHT: + case ALIGN_CONST.RIGHT_BOTTOM: + pos = this.bodyBounds.getBottomRight(body, x, y); + break; + } + + if (pos) + { + Body.setPosition(body, pos); + } + + return this; }, /** - * 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. + * The Scene that owns this plugin is shutting down. + * We need to kill and reset all internal properties as well as stop listening to Scene events. * - * @method Phaser.Tilemaps.Tilemap#hasTileAtWorldXY + * @method Phaser.Physics.Matter.MatterPhysics#shutdown + * @private * @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) + shutdown: function () { - layer = this.getLayer(layer); + var eventEmitter = this.systems.events; - if (layer === null) { return null; } + if (this.world) + { + eventEmitter.off(SceneEvents.UPDATE, this.world.update, this.world); + eventEmitter.off(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world); + } - return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, layer); - }, + eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); - /** - * 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 () + if (this.add) { - return this.layers[this.currentLayerIndex]; - }, + this.add.destroy(); + } - set: function (layer) + if (this.world) { - this.setLayer(layer); + this.world.destroy(); } + + this.add = null; + this.world = null; }, /** - * 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. + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. * - * @method Phaser.Tilemaps.Tilemap#putTileAt + * @method Phaser.Physics.Matter.MatterPhysics#destroy + * @private * @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) + destroy: function () { - if (recalculateFaces === undefined) { recalculateFaces = true; } + this.shutdown(); - layer = this.getLayer(layer); + this.scene.sys.events.off(SceneEvents.START, this.start, this); - if (layer === null) { return null; } + this.scene = null; + this.systems = 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; } +PluginCache.register('MatterPhysics', MatterPhysics, 'matterPhysics'); - layer = this.getLayer(layer); +module.exports = MatterPhysics; - 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; } +/***/ 73658: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - layer = this.getLayer(layer); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (layer === null) { return null; } +var AnimationState = __webpack_require__(16569); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(74527); +var GameObject = __webpack_require__(89980); +var GetFastValue = __webpack_require__(72632); +var Pipeline = __webpack_require__(58210); +var Sprite = __webpack_require__(13747); +var Vector2 = __webpack_require__(93736); - TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, layer); +/** + * @classdesc + * A Matter Physics Sprite Game Object. + * + * A Sprite Game Object is used for the display of both static and animated images in your game. + * Sprites can have input events and physics bodies. They can also be tweened, tinted, scrolled + * and animated. + * + * The main difference between a Sprite and an Image Game Object is that you cannot animate Images. + * As such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation + * Component. If you do not require animation then you can safely use Images to replace Sprites in all cases. + * + * @class Sprite + * @extends Phaser.GameObjects.Sprite + * @memberof Phaser.Physics.Matter + * @constructor + * @since 3.0.0 + * + * @extends Phaser.Physics.Matter.Components.Bounce + * @extends Phaser.Physics.Matter.Components.Collision + * @extends Phaser.Physics.Matter.Components.Force + * @extends Phaser.Physics.Matter.Components.Friction + * @extends Phaser.Physics.Matter.Components.Gravity + * @extends Phaser.Physics.Matter.Components.Mass + * @extends Phaser.Physics.Matter.Components.Sensor + * @extends Phaser.Physics.Matter.Components.SetBody + * @extends Phaser.Physics.Matter.Components.Sleep + * @extends Phaser.Physics.Matter.Components.Static + * @extends Phaser.Physics.Matter.Components.Transform + * @extends Phaser.Physics.Matter.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.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @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.Physics.Matter.World} world - A reference to the Matter.World instance that this body belongs to. + * @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. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + */ +var MatterSprite = new Class({ - return this; - }, + Extends: Sprite, - /** - * 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) + Mixins: [ + Components.Bounce, + Components.Collision, + Components.Force, + Components.Friction, + Components.Gravity, + Components.Mass, + Components.Sensor, + Components.SetBody, + Components.Sleep, + Components.Static, + Components.Transform, + Components.Velocity, + Pipeline + ], + + initialize: + + function MatterSprite (world, x, y, texture, frame, options) { - layer = this.getLayer(layer); + GameObject.call(this, world.scene, 'Sprite'); - if (layer === null) { return null; } + /** + * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. + * + * @name Phaser.Physics.Matter.Sprite#_crop + * @type {object} + * @private + * @since 3.24.0 + */ + this._crop = this.resetCropObject(); - TilemapComponents.Randomize(tileX, tileY, width, height, indexes, layer); + this.anims = new AnimationState(this); - return this; - }, + this.setTexture(texture, frame); + this.setSizeToFrame(); + this.setOrigin(); - /** - * 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); + /** + * A reference to the Matter.World instance that this body belongs to. + * + * @name Phaser.Physics.Matter.Sprite#world + * @type {Phaser.Physics.Matter.World} + * @since 3.0.0 + */ + this.world = world; + + /** + * An internal temp vector used for velocity and force calculations. + * + * @name Phaser.Physics.Matter.Sprite#_tempVec2 + * @type {Phaser.Math.Vector2} + * @private + * @since 3.0.0 + */ + this._tempVec2 = new Vector2(x, y); + + var shape = GetFastValue(options, 'shape', null); + + if (shape) + { + this.setBody(shape, options); + } + else + { + this.setRectangle(this.width, this.height, options); + } + + this.setPosition(x, y); + + this.initPipeline(); + this.initPostPipeline(true); + } + +}); + +module.exports = MatterSprite; + + +/***/ }), + +/***/ 84720: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Bodies = __webpack_require__(68516); +var Body = __webpack_require__(84125); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(74527); +var DeepCopy = __webpack_require__(28699); +var EventEmitter = __webpack_require__(6659); +var GetFastValue = __webpack_require__(72632); +var HasValue = __webpack_require__(19256); +var Vertices = __webpack_require__(39745); + +/** + * @classdesc + * A wrapper around a Tile that provides access to a corresponding Matter body. A tile can only + * have one Matter body associated with it. You can either pass in an existing Matter body for + * the tile or allow the constructor to create the corresponding body for you. If the Tile has a + * collision group (defined in Tiled), those shapes will be used to create the body. If not, the + * tile's rectangle bounding box will be used. + * + * The corresponding body will be accessible on the Tile itself via Tile.physics.matterBody. + * + * Note: not all Tiled collision shapes are supported. See + * Phaser.Physics.Matter.TileBody#setFromTileCollision for more information. + * + * @class TileBody + * @memberof Phaser.Physics.Matter + * @extends Phaser.Events.EventEmitter + * @constructor + * @since 3.0.0 + * + * @extends Phaser.Physics.Matter.Components.Bounce + * @extends Phaser.Physics.Matter.Components.Collision + * @extends Phaser.Physics.Matter.Components.Friction + * @extends Phaser.Physics.Matter.Components.Gravity + * @extends Phaser.Physics.Matter.Components.Mass + * @extends Phaser.Physics.Matter.Components.Sensor + * @extends Phaser.Physics.Matter.Components.Sleep + * @extends Phaser.Physics.Matter.Components.Static + * + * @param {Phaser.Physics.Matter.World} world - The Matter world instance this body belongs to. + * @param {Phaser.Tilemaps.Tile} tile - The target tile that should have a Matter body. + * @param {Phaser.Types.Physics.Matter.MatterTileOptions} [options] - Options to be used when creating the Matter body. + */ +var MatterTileBody = new Class({ - if (layer === null) { return null; } + Extends: EventEmitter, - TilemapComponents.CalculateFacesAt(tileX, tileY, layer); + Mixins: [ + Components.Bounce, + Components.Collision, + Components.Friction, + Components.Gravity, + Components.Mass, + Components.Sensor, + Components.Sleep, + Components.Static + ], - return this; - }, + initialize: - /** - * 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) + function MatterTileBody (world, tile, options) { - layer = this.getLayer(layer); + EventEmitter.call(this); - if (layer === null) { return null; } + /** + * The tile object the body is associated with. + * + * @name Phaser.Physics.Matter.TileBody#tile + * @type {Phaser.Tilemaps.Tile} + * @since 3.0.0 + */ + this.tile = tile; - TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, layer); + /** + * The Matter world the body exists within. + * + * @name Phaser.Physics.Matter.TileBody#world + * @type {Phaser.Physics.Matter.World} + * @since 3.0.0 + */ + this.world = world; - return this; - }, + // Install a reference to 'this' on the tile and ensure there can only be one matter body + // associated with the tile + if (tile.physics.matterBody) + { + tile.physics.matterBody.destroy(); + } - /** - * 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); + tile.physics.matterBody = this; - if (index !== null) + // Set the body either from an existing body (if provided), the shapes in the tileset + // collision layer (if it exists) or a rectangle matching the tile. + var body = GetFastValue(options, 'body', null); + + var addToWorld = GetFastValue(options, 'addToWorld', true); + + if (!body) { - SpliceOne(this.layers, index); + var collisionGroup = tile.getCollisionGroup(); + var collisionObjects = GetFastValue(collisionGroup, 'objects', []); - for (var i = index; i < this.layers.length; i++) + if (collisionObjects.length > 0) { - if (this.layers[i].tilemapLayer) - { - this.layers[i].tilemapLayer.layerIndex--; - } + this.setFromTileCollision(options); } - - if (this.currentLayerIndex === index) + else { - this.currentLayerIndex = 0; + this.setFromTileRectangle(options); } - - return this; } else { - return null; + this.setBody(body, addToWorld); } - }, - - /** - * 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) + if (tile.flipX || tile.flipY) { - layer = this.layers[index]; - - layer.destroy(); + var rotationPoint = { x: tile.getCenterX(), y: tile.getCenterY() }; + var scaleX = (tile.flipX) ? -1 : 1; + var scaleY = (tile.flipY) ? -1 : 1; - SpliceOne(this.layers, index); - - if (this.currentLayerIndex === index) - { - this.currentLayerIndex = 0; - } - - return this; - } - else - { - return null; + Body.scale(body, scaleX, scaleY, rotationPoint); } }, /** - * Removes all Tilemap Layers from this Tilemap and calls `destroy` on each of them. + * Sets the current body to a rectangle that matches the bounds of the tile. * - * @method Phaser.Tilemaps.Tilemap#removeAllLayers + * @method Phaser.Physics.Matter.TileBody#setFromTileRectangle * @since 3.0.0 * - * @return {this} This Tilemap object. + * @param {Phaser.Types.Physics.Matter.MatterBodyTileOptions} [options] - Options to be used when creating the Matter body. See MatterJS.Body for a list of what Matter accepts. + * + * @return {Phaser.Physics.Matter.TileBody} This TileBody object. */ - removeAllLayers: function () + setFromTileRectangle: function (options) { - var layers = this.layers; - - for (var i = 0; i < layers.length; i++) - { - if (layers[i].tilemapLayer) - { - layers[i].tilemapLayer.destroy(false); - } - } + if (options === undefined) { options = {}; } + if (!HasValue(options, 'isStatic')) { options.isStatic = true; } + if (!HasValue(options, 'addToWorld')) { options.addToWorld = true; } - layers.length = 0; + var bounds = this.tile.getBounds(); + var cx = bounds.x + (bounds.width / 2); + var cy = bounds.y + (bounds.height / 2); + var body = Bodies.rectangle(cx, cy, bounds.width, bounds.height, options); - this.currentLayerIndex = 0; + this.setBody(body, options.addToWorld); return this; }, /** - * Removes the given Tile, or an array of Tiles, from the layer to which they belong, - * and optionally recalculates the collision information. + * Sets the current body from the collision group associated with the Tile. This is typically + * set up in Tiled's collision editor. * - * @method Phaser.Tilemaps.Tilemap#removeTile - * @since 3.17.0 + * Note: Matter doesn't support all shapes from Tiled. Rectangles and polygons are directly + * supported. Ellipses are converted into circle bodies. Polylines are treated as if they are + * closed polygons. If a tile has multiple shapes, a multi-part body will be created. Concave + * shapes are supported if poly-decomp library is included. Decomposition is not guaranteed to + * work for complex shapes (e.g. holes), so it's often best to manually decompose a concave + * polygon into multiple convex polygons yourself. * - * @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. + * @method Phaser.Physics.Matter.TileBody#setFromTileCollision + * @since 3.0.0 * - * @return {Phaser.Tilemaps.Tile[]} Returns an array of Tiles that were removed. + * @param {Phaser.Types.Physics.Matter.MatterBodyTileOptions} [options] - Options to be used when creating the Matter body. See MatterJS.Body for a list of what Matter accepts. + * + * @return {Phaser.Physics.Matter.TileBody} This TileBody object. */ - removeTile: function (tiles, replaceIndex, recalculateFaces) + setFromTileCollision: function (options) { - if (replaceIndex === undefined) { replaceIndex = -1; } - if (recalculateFaces === undefined) { recalculateFaces = true; } + if (options === undefined) { options = {}; } + if (!HasValue(options, 'isStatic')) { options.isStatic = true; } + if (!HasValue(options, 'addToWorld')) { options.addToWorld = true; } - var removed = []; + var sx = this.tile.tilemapLayer.scaleX; + var sy = this.tile.tilemapLayer.scaleY; + var tileX = this.tile.getLeft(); + var tileY = this.tile.getTop(); + var collisionGroup = this.tile.getCollisionGroup(); + var collisionObjects = GetFastValue(collisionGroup, 'objects', []); - if (!Array.isArray(tiles)) - { - tiles = [ tiles ]; - } + var parts = []; - for (var i = 0; i < tiles.length; i++) + for (var i = 0; i < collisionObjects.length; i++) { - var tile = tiles[i]; - - removed.push(this.removeTileAt(tile.x, tile.y, true, recalculateFaces, tile.tilemapLayer)); + var object = collisionObjects[i]; + var ox = tileX + (object.x * sx); + var oy = tileY + (object.y * sy); + var ow = object.width * sx; + var oh = object.height * sy; + var body = null; - if (replaceIndex > -1) + if (object.rectangle) { - this.putTileAt(replaceIndex, tile.x, tile.y, recalculateFaces, tile.tilemapLayer); + body = Bodies.rectangle(ox + ow / 2, oy + oh / 2, ow, oh, options); } - } + else if (object.ellipse) + { + body = Bodies.circle(ox + ow / 2, oy + oh / 2, ow / 2, options); + } + else if (object.polygon || object.polyline) + { + // Polygons and polylines are both treated as closed polygons + var originalPoints = object.polygon ? object.polygon : object.polyline; - return removed; - }, + var points = originalPoints.map(function (p) + { + return { x: p.x * sx, y: p.y * sy }; + }); - /** - * 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; } + var vertices = Vertices.create(points); - layer = this.getLayer(layer); + // Points are relative to the object's origin (first point placed in Tiled), but + // matter expects points to be relative to the center of mass. This only applies to + // convex shapes. When a concave shape is decomposed, multiple parts are created and + // the individual parts are positioned relative to (ox, oy). + // + // Update: 8th January 2019 - the latest version of Matter needs the Vertices adjusted, + // regardless if convex or concave. - if (layer === null) { return null; } + var center = Vertices.centre(vertices); - return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, layer); - }, + ox += center.x; + oy += center.y; - /** - * 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; } + body = Bodies.fromVertices(ox, oy, vertices, options); + } - layer = this.getLayer(layer); + if (body) + { + parts.push(body); + } + } - if (layer === null) { return null; } + if (parts.length === 1) + { + this.setBody(parts[0], options.addToWorld); + } + else if (parts.length > 1) + { + var tempOptions = DeepCopy(options); - return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, layer); + tempOptions.parts = parts; + + this.setBody(Body.create(tempOptions), tempOptions.addToWorld); + } + + return this; }, /** - * 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. + * Sets the current body to the given body. This will remove the previous body, if one already + * exists. * - * @method Phaser.Tilemaps.Tilemap#renderDebug + * @method Phaser.Physics.Matter.TileBody#setBody * @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. + * @param {MatterJS.BodyType} body - The new Matter body to use. + * @param {boolean} [addToWorld=true] - Whether or not to add the body to the Matter world. * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + * @return {Phaser.Physics.Matter.TileBody} This TileBody object. */ - renderDebug: function (graphics, styleConfig, layer) + setBody: function (body, addToWorld) { - layer = this.getLayer(layer); + if (addToWorld === undefined) { addToWorld = true; } - if (layer === null) { return null; } + if (this.body) + { + this.removeBody(); + } - if (this.orientation === ORIENTATION.ORTHOGONAL) + this.body = body; + this.body.gameObject = this; + + if (addToWorld) { - TilemapComponents.RenderDebug(graphics, styleConfig, layer); + this.world.add(this.body); } 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 + * Removes the current body from the TileBody and from the Matter world * - * @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. + * @method Phaser.Physics.Matter.TileBody#removeBody + * @since 3.0.0 * - * @return {this} This Tilemap instance. + * @return {Phaser.Physics.Matter.TileBody} This TileBody object. */ - renderDebugFull: function (graphics, styleConfig) + removeBody: function () { - var layers = this.layers; - - for (var i = 0; i < layers.length; i++) + if (this.body) { - TilemapComponents.RenderDebug(graphics, styleConfig, layers[i]); + this.world.remove(this.body); + this.body.gameObject = undefined; + this.body = undefined; } 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. + * Removes the current body from the tile and the world. * - * @method Phaser.Tilemaps.Tilemap#replaceByIndex + * @method Phaser.Physics.Matter.TileBody#destroy * @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. + * @return {Phaser.Physics.Matter.TileBody} This TileBody object. */ - replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height, layer) + destroy: function () { - layer = this.getLayer(layer); + this.removeBody(); + this.tile.physics.matterBody = undefined; + this.removeAllListeners(); + } - if (layer === null) { return null; } +}); - TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, layer); +module.exports = MatterTileBody; - 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); +/***/ 10998: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (layer === null) { return null; } +/** + * @author Joachim Grill + * @author Richard Davey + * @copyright 2018 CodeAndWeb GmbH + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - TilemapComponents.SetCollision(indexes, collides, recalculateFaces, layer, updateLayer); +var Bodies = __webpack_require__(68516); +var Body = __webpack_require__(84125); +var Common = __webpack_require__(68758); +var GetFastValue = __webpack_require__(72632); +var Vertices = __webpack_require__(39745); - return this; - }, +/** + * Use PhysicsEditorParser.parseBody() to build a Matter body object, based on a physics data file + * created and exported with PhysicsEditor (https://www.codeandweb.com/physicseditor). + * + * @namespace Phaser.Physics.Matter.PhysicsEditorParser + * @since 3.10.0 + */ +var PhysicsEditorParser = { /** - * 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. + * Parses a body element exported by PhysicsEditor. * - * @method Phaser.Tilemaps.Tilemap#setCollisionBetween - * @since 3.0.0 + * @function Phaser.Physics.Matter.PhysicsEditorParser.parseBody + * @since 3.10.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. + * @param {number} x - The horizontal world location of the body. + * @param {number} y - The vertical world location of the body. + * @param {object} config - The body configuration and fixture (child body) definitions, as exported by PhysicsEditor. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + * @return {MatterJS.BodyType} A compound Matter JS Body. */ - setCollisionBetween: function (start, stop, collides, recalculateFaces, layer) + parseBody: function (x, y, config, options) { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } + if (options === undefined) { options = {}; } - layer = this.getLayer(layer); + var fixtureConfigs = GetFastValue(config, 'fixtures', []); + var fixtures = []; - if (layer === null) { return null; } + for (var fc = 0; fc < fixtureConfigs.length; fc++) + { + var fixtureParts = this.parseFixture(fixtureConfigs[fc]); - TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, layer); + for (var i = 0; i < fixtureParts.length; i++) + { + fixtures.push(fixtureParts[i]); + } + } - return this; - }, + var matterConfig = Common.clone(config, true); - /** - * 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; } + Common.extend(matterConfig, options, true); - layer = this.getLayer(layer); + delete matterConfig.fixtures; + delete matterConfig.type; - if (layer === null) { return null; } + var body = Body.create(matterConfig); - TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, layer); + Body.setParts(body, fixtures); - return this; + Body.setPosition(body, { x: x, y: y }); + + return body; }, /** - * 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. + * Parses an element of the "fixtures" list exported by PhysicsEditor * - * @method Phaser.Tilemaps.Tilemap#setCollisionByExclusion - * @since 3.0.0 + * @function Phaser.Physics.Matter.PhysicsEditorParser.parseFixture + * @since 3.10.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. + * @param {object} fixtureConfig - The fixture object to parse. * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + * @return {MatterJS.BodyType[]} - An array of Matter JS Bodies. */ - setCollisionByExclusion: function (indexes, collides, recalculateFaces, layer) + parseFixture: function (fixtureConfig) { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } + var matterConfig = Common.extend({}, false, fixtureConfig); - layer = this.getLayer(layer); + delete matterConfig.circle; + delete matterConfig.vertices; - if (layer === null) { return null; } + var fixtures; - TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, layer); + if (fixtureConfig.circle) + { + var x = GetFastValue(fixtureConfig.circle, 'x'); + var y = GetFastValue(fixtureConfig.circle, 'y'); + var r = GetFastValue(fixtureConfig.circle, 'radius'); + fixtures = [ Bodies.circle(x, y, r, matterConfig) ]; + } + else if (fixtureConfig.vertices) + { + fixtures = this.parseVertices(fixtureConfig.vertices, matterConfig); + } - return this; + return fixtures; }, /** - * 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. + * Parses the "vertices" lists exported by PhysicsEditor. * - * @method Phaser.Tilemaps.Tilemap#setCollisionFromCollisionGroup - * @since 3.0.0 + * @function Phaser.Physics.Matter.PhysicsEditorParser.parseVertices + * @since 3.10.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. + * @param {array} vertexSets - The vertex lists to parse. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + * @return {MatterJS.BodyType[]} - An array of Matter JS Bodies. */ - setCollisionFromCollisionGroup: function (collides, recalculateFaces, layer) + parseVertices: function (vertexSets, options) { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - layer = this.getLayer(layer); + if (options === undefined) { options = {}; } - if (layer === null) { return null; } + var parts = []; - TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, layer); + for (var v = 0; v < vertexSets.length; v++) + { + Vertices.clockwiseSort(vertexSets[v]); - return this; - }, + parts.push(Body.create(Common.extend({ + position: Vertices.centre(vertexSets[v]), + vertices: vertexSets[v] + }, options))); + } - /** - * 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); + // flag coincident part edges + return Bodies.flagCoincidentParts(parts); + } +}; - if (layer === null) { return null; } +module.exports = PhysicsEditorParser; - 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); +/***/ 72829: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (layer === null) { return null; } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, layer); +var Bodies = __webpack_require__(68516); +var Body = __webpack_require__(84125); - return this; - }, +/** + * Creates a body using the supplied physics data, as provided by a JSON file. + * + * The data file should be loaded as JSON: + * + * ```javascript + * preload () + * { + * this.load.json('ninjas', 'assets/ninjas.json); + * } + * + * create () + * { + * const ninjaShapes = this.cache.json.get('ninjas'); + * + * this.matter.add.fromJSON(400, 300, ninjaShapes.shinobi); + * } + * ``` + * + * Do not pass the entire JSON file to this method, but instead pass one of the shapes contained within it. + * + * If you pas in an `options` object, any settings in there will override those in the config object. + * + * The structure of the JSON file is as follows: + * + * ```text + * { + * 'generator_info': // The name of the application that created the JSON data + * 'shapeName': { + * 'type': // The type of body + * 'label': // Optional body label + * 'vertices': // An array, or an array of arrays, containing the vertex data in x/y object pairs + * } + * } + * ``` + * + * At the time of writing, only the Phaser Physics Tracer App exports in this format. + * + * @namespace Phaser.Physics.Matter.PhysicsJSONParser + * @since 3.22.0 + */ +var PhysicsJSONParser = { /** - * Sets the current layer to the LayerData associated with `layer`. + * Parses a body element from the given JSON data. * - * @method Phaser.Tilemaps.Tilemap#setLayer - * @since 3.0.0 + * @function Phaser.Physics.Matter.PhysicsJSONParser.parseBody + * @since 3.22.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. + * @param {number} x - The horizontal world location of the body. + * @param {number} y - The vertical world location of the body. + * @param {object} config - The body configuration data. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. * - * @return {this} This Tilemap object. + * @return {MatterJS.BodyType} A Matter JS Body. */ - setLayer: function (layer) + parseBody: function (x, y, config, options) { - var index = this.getLayerIndex(layer); + if (options === undefined) { options = {}; } - if (index !== null) - { - this.currentLayerIndex = index; - } + var body; + var vertexSets = config.vertices; - return this; - }, + if (vertexSets.length === 1) + { + // Just a single Body + options.vertices = vertexSets[0]; - /** - * 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; + body = Body.create(options); - // Update the base tile size on all layers & tiles - for (var i = 0; i < this.layers.length; i++) + Bodies.flagCoincidentParts(body.parts); + } + else { - 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; + var parts = []; - for (var row = 0; row < mapHeight; row++) + for (var i = 0; i < vertexSets.length; i++) { - for (var col = 0; col < mapWidth; col++) - { - var tile = mapData[row][col]; + var part = Body.create({ + vertices: vertexSets[i] + }); - if (tile !== null) - { - tile.setSize(undefined, undefined, tileWidth, tileHeight); - } - } + parts.push(part); } + + Bodies.flagCoincidentParts(parts); + + options.parts = parts; + + body = Body.create(options); } - return this; - }, + body.label = config.label; - /** - * 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); + Body.setPosition(body, { x: x, y: y }); - if (layer === null) { return this; } + return body; + } - layer.tileWidth = tileWidth; - layer.tileHeight = tileHeight; +}; - var mapData = layer.data; - var mapWidth = layer.width; - var mapHeight = layer.height; +module.exports = PhysicsJSONParser; - 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; - }, +/***/ 88596: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * 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); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (layer === null) { return null; } +var Bounds = __webpack_require__(84091); +var Class = __webpack_require__(56694); +var Composite = __webpack_require__(11299); +var Constraint = __webpack_require__(52838); +var Detector = __webpack_require__(13657); +var Events = __webpack_require__(35416); +var InputEvents = __webpack_require__(33963); +var Merge = __webpack_require__(30657); +var Sleeping = __webpack_require__(22806); +var Vector2 = __webpack_require__(93736); +var Vertices = __webpack_require__(39745); - TilemapComponents.Shuffle(tileX, tileY, width, height, layer); +/** + * @classdesc + * A Pointer Constraint is a special type of constraint that allows you to click + * and drag bodies in a Matter World. It monitors the active Pointers in a Scene, + * and when one is pressed down it checks to see if that hit any part of any active + * body in the world. If it did, and the body has input enabled, it will begin to + * drag it until either released, or you stop it via the `stopDrag` method. + * + * You can adjust the stiffness, length and other properties of the constraint via + * the `options` object on creation. + * + * @class PointerConstraint + * @memberof Phaser.Physics.Matter + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - A reference to the Scene to which this Pointer Constraint belongs. + * @param {Phaser.Physics.Matter.World} world - A reference to the Matter World instance to which this Constraint belongs. + * @param {object} [options] - A Constraint configuration object. + */ +var PointerConstraint = new Class({ - return this; - }, + initialize: - /** - * 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) + function PointerConstraint (scene, world, options) { - layer = this.getLayer(layer); + if (options === undefined) { options = {}; } - if (layer === null) { return null; } + // Defaults + var defaults = { + label: 'Pointer Constraint', + pointA: { x: 0, y: 0 }, + pointB: { x: 0, y: 0 }, + length: 0.01, + stiffness: 0.1, + angularStiffness: 1, + collisionFilter: { + category: 0x0001, + mask: 0xFFFFFFFF, + group: 0 + } + }; - TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, layer); + /** + * A reference to the Scene to which this Pointer Constraint belongs. + * This is the same Scene as the Matter World instance. + * + * @name Phaser.Physics.Matter.PointerConstraint#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - return this; - }, + /** + * A reference to the Matter World instance to which this Constraint belongs. + * + * @name Phaser.Physics.Matter.PointerConstraint#world + * @type {Phaser.Physics.Matter.World} + * @since 3.0.0 + */ + this.world = world; - /** - * 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); + /** + * The Camera the Pointer was interacting with when the input + * down event was processed. + * + * @name Phaser.Physics.Matter.PointerConstraint#camera + * @type {Phaser.Cameras.Scene2D.Camera} + * @since 3.0.0 + */ + this.camera = null; + + /** + * A reference to the Input Pointer that activated this Constraint. + * This is set in the `onDown` handler. + * + * @name Phaser.Physics.Matter.PointerConstraint#pointer + * @type {Phaser.Input.Pointer} + * @default null + * @since 3.0.0 + */ + this.pointer = null; + + /** + * Is this Constraint active or not? + * + * An active constraint will be processed each update. An inactive one will be skipped. + * Use this to toggle a Pointer Constraint on and off. + * + * @name Phaser.Physics.Matter.PointerConstraint#active + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.active = true; + + /** + * The internal transformed position. + * + * @name Phaser.Physics.Matter.PointerConstraint#position + * @type {Phaser.Math.Vector2} + * @since 3.0.0 + */ + this.position = new Vector2(); + + /** + * The body that is currently being dragged, if any. + * + * @name Phaser.Physics.Matter.PointerConstraint#body + * @type {?MatterJS.BodyType} + * @since 3.16.2 + */ + this.body = null; + + /** + * The part of the body that was clicked on to start the drag. + * + * @name Phaser.Physics.Matter.PointerConstraint#part + * @type {?MatterJS.BodyType} + * @since 3.16.2 + */ + this.part = null; - if (layer === null) { return null; } + /** + * The native Matter Constraint that is used to attach to bodies. + * + * @name Phaser.Physics.Matter.PointerConstraint#constraint + * @type {MatterJS.ConstraintType} + * @since 3.0.0 + */ + this.constraint = Constraint.create(Merge(options, defaults)); - return this._convert.TileToWorldX(tileX, camera, layer); + this.world.on(Events.BEFORE_UPDATE, this.update, this); + + scene.sys.input.on(InputEvents.POINTER_DOWN, this.onDown, this); + scene.sys.input.on(InputEvents.POINTER_UP, this.onUp, this); }, /** - * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layers position, scale and scroll. + * A Pointer has been pressed down onto the Scene. * - * If no layer is specified, the maps current layer is used. + * If this Constraint doesn't have an active Pointer then a hit test is set to + * run against all active bodies in the world during the _next_ call to `update`. + * If a body is found, it is bound to this constraint and the drag begins. * - * @method Phaser.Tilemaps.Tilemap#tileToWorldY + * @method Phaser.Physics.Matter.PointerConstraint#onDown * @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. + * @param {Phaser.Input.Pointer} pointer - A reference to the Pointer that was pressed. */ - tileToWorldY: function (tileX, camera, layer) + onDown: function (pointer) { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.TileToWorldY(tileX, camera, layer); + if (!this.pointer) + { + this.pointer = pointer; + this.camera = pointer.camera; + } }, /** - * 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 + * A Pointer has been released from the Scene. If it was the one this constraint was using, it's cleared. * - * @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. + * @method Phaser.Physics.Matter.PointerConstraint#onUp + * @since 3.22.0 * - * @return {?Phaser.Math.Vector2} Returns a Vector2, or null if the layer given was invalid. + * @param {Phaser.Input.Pointer} pointer - A reference to the Pointer that was pressed. */ - tileToWorldXY: function (tileX, tileY, vec2, camera, layer) + onUp: function (pointer) { - layer = this.getLayer(layer); - - if (layer === null) { return null; } - - return this._convert.TileToWorldXY(tileX, tileY, vec2, camera, layer); + if (pointer === this.pointer) + { + this.pointer = null; + } }, /** - * 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 + * Scans all active bodies in the current Matter World to see if any of them + * are hit by the Pointer. The _first one_ found to hit is set as the active contraint + * body. * - * @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. + * @method Phaser.Physics.Matter.PointerConstraint#getBody + * @fires Phaser.Physics.Matter.Events#DRAG_START + * @since 3.16.2 * - * @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid. + * @return {boolean} `true` if a body was found and set, otherwise `false`. */ - weightedRandomize: function (weightedIndexes, tileX, tileY, width, height, layer) + getBody: function (pointer) { - layer = this.getLayer(layer); + var pos = this.position; + var constraint = this.constraint; - if (layer === null) { return null; } + this.camera.getWorldPoint(pointer.x, pointer.y, pos); - TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, layer); + var bodies = Composite.allBodies(this.world.localWorld); - return this; + for (var i = 0; i < bodies.length; i++) + { + var body = bodies[i]; + + if (!body.ignorePointer && + Bounds.contains(body.bounds, pos) && + Detector.canCollide(body.collisionFilter, constraint.collisionFilter)) + { + if (this.hitTestBody(body, pos)) + { + this.world.emit(Events.DRAG_START, body, this.part, this); + + return true; + } + } + } + + return false; }, /** - * 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. + * Scans the current body to determine if a part of it was clicked on. + * If a part is found the body is set as the `constraint.bodyB` property, + * as well as the `body` property of this class. The part is also set. * - * @method Phaser.Tilemaps.Tilemap#worldToTileX - * @since 3.0.0 + * @method Phaser.Physics.Matter.PointerConstraint#hitTestBody + * @since 3.16.2 * - * @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. + * @param {MatterJS.BodyType} body - The Matter Body to check. + * @param {Phaser.Math.Vector2} position - A translated hit test position. * - * @return {?number} Returns a number, or null if the layer given was invalid. + * @return {boolean} `true` if a part of the body was hit, otherwise `false`. */ - worldToTileX: function (worldX, snapToFloor, camera, layer) + hitTestBody: function (body, position) { - layer = this.getLayer(layer); + var constraint = this.constraint; + var partsLength = body.parts.length; - if (layer === null) { return null; } + var start = (partsLength > 1) ? 1 : 0; - return this._convert.WorldToTileX(worldX, snapToFloor, camera, layer); + for (var i = start; i < partsLength; i++) + { + var part = body.parts[i]; + + if (Vertices.contains(part.vertices, position)) + { + constraint.pointA = position; + constraint.pointB = { x: position.x - body.position.x, y: position.y - body.position.y }; + + constraint.bodyB = body; + constraint.angleB = body.angle; + + Sleeping.set(body, false); + + this.part = part; + this.body = body; + + return true; + } + } + + return false; }, /** - * 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. + * Internal update handler. Called in the Matter BEFORE_UPDATE step. * - * @method Phaser.Tilemaps.Tilemap#worldToTileY + * @method Phaser.Physics.Matter.PointerConstraint#update + * @fires Phaser.Physics.Matter.Events#DRAG * @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) + update: function () { - layer = this.getLayer(layer); + var pointer = this.pointer; + var body = this.body; - if (layer === null) { return null; } + if (!this.active || !pointer) + { + if (body) + { + this.stopDrag(); + } - return this._convert.WorldToTileY(worldY, snapToFloor, camera, layer); + return; + } + + if (!pointer.isDown && body) + { + this.stopDrag(); + + return; + } + else if (pointer.isDown) + { + if (!body && !this.getBody(pointer)) + { + return; + } + + body = this.body; + + var pos = this.position; + var constraint = this.constraint; + + this.camera.getWorldPoint(pointer.x, pointer.y, pos); + + // Drag update + constraint.pointA.x = pos.x; + constraint.pointA.y = pos.y; + + Sleeping.set(body, false); + + this.world.emit(Events.DRAG, body, 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. - * - * If no layer is specified, the maps current layer is used. - * - * @method Phaser.Tilemaps.Tilemap#worldToTileXY - * @since 3.0.0 + * Stops the Pointer Constraint from dragging the body any further. * - * @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. + * This is called automatically if the Pointer is released while actively + * dragging a body. Or, you can call it manually to release a body from a + * constraint without having to first release the pointer. * - * @return {?Phaser.Math.Vector2} Returns a vec2, or null if the layer given was invalid. + * @method Phaser.Physics.Matter.PointerConstraint#stopDrag + * @fires Phaser.Physics.Matter.Events#DRAG_END + * @since 3.16.2 */ - worldToTileXY: function (worldX, worldY, snapToFloor, vec2, camera, layer) + stopDrag: function () { - layer = this.getLayer(layer); + var body = this.body; + var constraint = this.constraint; - if (layer === null) { return null; } + constraint.bodyB = null; + constraint.pointB = null; - return this._convert.WorldToTileXY(worldX, worldY, snapToFloor, vec2, camera, layer); + this.pointer = null; + this.body = null; + this.part = null; + + if (body) + { + this.world.emit(Events.DRAG_END, body, this); + } }, /** - * Removes all layer data from this Tilemap and nulls the scene reference. This will destroy any - * TilemapLayers that have been created. + * Destroys this Pointer Constraint instance and all of its references. * - * @method Phaser.Tilemaps.Tilemap#destroy + * @method Phaser.Physics.Matter.PointerConstraint#destroy * @since 3.0.0 */ destroy: function () { - this.removeAllLayers(); + this.world.removeConstraint(this.constraint); - this.tilesets.length = 0; - this.objects.length = 0; + this.pointer = null; + this.constraint = null; + this.body = null; + this.part = null; - this.scene = null; + this.world.off(Events.BEFORE_UPDATE, this.update); + + this.scene.sys.input.off(InputEvents.POINTER_DOWN, this.onDown, this); + this.scene.sys.input.off(InputEvents.POINTER_UP, this.onUp, this); } }); -module.exports = Tilemap; +module.exports = PointerConstraint; /***/ }), -/* 581 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 31468: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(251); -var TilemapLayerRender = __webpack_require__(1456); +var Bodies = __webpack_require__(68516); +var Body = __webpack_require__(84125); +var Class = __webpack_require__(56694); +var Common = __webpack_require__(68758); +var Composite = __webpack_require__(11299); +var Engine = __webpack_require__(45775); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(35416); +var GetFastValue = __webpack_require__(72632); +var GetValue = __webpack_require__(10850); +var MatterBody = __webpack_require__(84125); +var MatterEvents = __webpack_require__(39073); +var MatterTileBody = __webpack_require__(84720); +var MatterWorld = __webpack_require__(72005); +var Vector = __webpack_require__(10438); /** * @classdesc - * A Tilemap Layer is a Game Object that renders LayerData from a Tilemap when used in combination - * with one, or more, Tilesets. + * The Matter World class is responsible for managing one single instance of a Matter Physics World for Phaser. * - * @class TilemapLayer - * @extends Phaser.GameObjects.GameObject - * @memberof Phaser.Tilemaps - * @constructor - * @since 3.50.0 + * Access this via `this.matter.world` from within a Scene. * - * @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 + * This class creates a Matter JS World Composite along with the Matter JS Engine during instantiation. It also + * handles delta timing, bounds, body and constraint creation and debug drawing. * - * @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. + * If you wish to access the Matter JS World object directly, see the `localWorld` property. + * If you wish to access the Matter Engine directly, see the `engine` property. + * + * This class is an Event Emitter and will proxy _all_ Matter JS events, as they are received. + * + * @class World + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Physics.Matter + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to which this Matter World instance belongs. + * @param {Phaser.Types.Physics.Matter.MatterWorldConfig} config - The Matter World configuration object. */ -var TilemapLayer = new Class({ - - Extends: GameObject, +var World = new Class({ - Mixins: [ - Components.Alpha, - Components.BlendMode, - Components.ComputedSize, - Components.Depth, - Components.Flip, - Components.GetBounds, - Components.Origin, - Components.Pipeline, - Components.Transform, - Components.Visible, - Components.ScrollFactor, - TilemapLayerRender - ], + Extends: EventEmitter, initialize: - function TilemapLayer (scene, tilemap, layerIndex, tileset, x, y) + function World (scene, config) { - GameObject.call(this, scene, 'TilemapLayer'); + EventEmitter.call(this); /** - * Used internally by physics system to perform fast type checks. + * The Scene to which this Matter World instance belongs. * - * @name Phaser.Tilemaps.TilemapLayer#isTilemap - * @type {boolean} - * @readonly - * @since 3.50.0 + * @name Phaser.Physics.Matter.World#scene + * @type {Phaser.Scene} + * @since 3.0.0 */ - this.isTilemap = true; + this.scene = scene; /** - * The Tilemap that this layer is a part of. + * An instance of the MatterJS Engine. * - * @name Phaser.Tilemaps.TilemapLayer#tilemap - * @type {Phaser.Tilemaps.Tilemap} - * @since 3.50.0 + * @name Phaser.Physics.Matter.World#engine + * @type {MatterJS.Engine} + * @since 3.0.0 */ - this.tilemap = tilemap; + this.engine = Engine.create(config); /** - * The index of the LayerData associated with this layer. + * A `World` composite object that will contain all simulated bodies and constraints. * - * @name Phaser.Tilemaps.TilemapLayer#layerIndex - * @type {number} - * @since 3.50.0 + * @name Phaser.Physics.Matter.World#localWorld + * @type {MatterJS.World} + * @since 3.0.0 */ - this.layerIndex = layerIndex; + this.localWorld = this.engine.world; - /** - * 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]; + var gravity = GetValue(config, 'gravity', null); - // Link the LayerData with this static tilemap layer - this.layer.tilemapLayer = this; + if (gravity) + { + this.setGravity(gravity.x, gravity.y, gravity.scale); + } + else if (gravity === false) + { + this.setGravity(0, 0, 0); + } /** - * An array of `Tileset` objects associated with this layer. + * An object containing the 4 wall bodies that bound the physics world. * - * @name Phaser.Tilemaps.TilemapLayer#tileset - * @type {Phaser.Tilemaps.Tileset[]} - * @since 3.50.0 + * @name Phaser.Physics.Matter.World#walls + * @type {Phaser.Types.Physics.Matter.MatterWalls} + * @since 3.0.0 */ - this.tileset = []; + this.walls = { left: null, right: null, top: null, bottom: null }; /** - * The total number of tiles drawn by the renderer in the last frame. + * A flag that toggles if the world is enabled or not. * - * @name Phaser.Tilemaps.TilemapLayer#tilesDrawn - * @type {number} - * @readonly - * @since 3.50.0 + * @name Phaser.Physics.Matter.World#enabled + * @type {boolean} + * @default true + * @since 3.0.0 */ - this.tilesDrawn = 0; + this.enabled = GetValue(config, 'enabled', true); /** - * The total number of tiles in this layer. Updated every frame. + * This function is called every time the core game loop steps, which is bound to the + * Request Animation Frame frequency unless otherwise modified. * - * @name Phaser.Tilemaps.TilemapLayer#tilesTotal - * @type {number} - * @readonly - * @since 3.50.0 + * The function is passed two values: `time` and `delta`, both of which come from the game step values. + * + * It must return a number. This number is used as the delta value passed to Matter.Engine.update. + * + * You can override this function with your own to define your own timestep. + * + * If you need to update the Engine multiple times in a single game step then call + * `World.update` as many times as required. Each call will trigger the `getDelta` function. + * If you wish to have full control over when the Engine updates then see the property `autoUpdate`. + * + * You can also adjust the number of iterations that Engine.update performs. + * Use the Scene Matter Physics config object to set the following properties: + * + * positionIterations (defaults to 6) + * velocityIterations (defaults to 4) + * constraintIterations (defaults to 2) + * + * Adjusting these values can help performance in certain situations, depending on the physics requirements + * of your game. + * + * @name Phaser.Physics.Matter.World#getDelta + * @type {function} + * @since 3.4.0 */ - this.tilesTotal = this.layer.width * this.layer.height; + this.getDelta = GetValue(config, 'getDelta', this.update60Hz); + + var runnerConfig = GetFastValue(config, 'runner', {}); + + var hasFPS = GetFastValue(runnerConfig, 'fps', false); + + var fps = GetFastValue(runnerConfig, 'fps', 60); + + var delta = GetFastValue(runnerConfig, 'delta', 1000 / fps); + var deltaMin = GetFastValue(runnerConfig, 'deltaMin', 1000 / fps); + var deltaMax = GetFastValue(runnerConfig, 'deltaMax', 1000 / (fps * 0.5)); + + if (!hasFPS) + { + fps = 1000 / delta; + } /** - * Used internally during rendering. This holds the tiles that are visible within the Camera. + * The Matter JS Runner Configuration object. * - * @name Phaser.Tilemaps.TilemapLayer#culledTiles - * @type {Phaser.Tilemaps.Tile[]} - * @since 3.50.0 + * This object is populated via the Matter Configuration object's `runner` property and is + * updated constantly during the game step. + * + * @name Phaser.Physics.Matter.World#runner + * @type {Phaser.Types.Physics.Matter.MatterRunnerConfig} + * @since 3.22.0 */ - this.culledTiles = []; + this.runner = { + fps: fps, + deltaSampleSize: GetFastValue(runnerConfig, 'deltaSampleSize', 60), + counterTimestamp: 0, + frameCounter: 0, + deltaHistory: [], + timePrev: null, + timeScalePrev: 1, + frameRequestId: null, + isFixed: GetFastValue(runnerConfig, 'isFixed', false), + delta: delta, + deltaMin: deltaMin, + deltaMax: deltaMax + }; /** - * 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. + * Automatically call Engine.update every time the game steps. + * If you disable this then you are responsible for calling `World.step` directly from your game. + * If you call `set60Hz` or `set30Hz` then `autoUpdate` is reset to `true`. * - * @name Phaser.Tilemaps.TilemapLayer#skipCull + * @name Phaser.Physics.Matter.World#autoUpdate * @type {boolean} - * @since 3.50.0 + * @default true + * @since 3.4.0 */ - this.skipCull = false; + this.autoUpdate = GetValue(config, 'autoUpdate', true); + + var debugConfig = GetValue(config, 'debug', false); /** - * The amount of extra tiles to add into the cull rectangle when calculating its horizontal size. - * - * See the method `setCullPadding` for more details. + * A flag that controls if the debug graphics will be drawn to or not. * - * @name Phaser.Tilemaps.TilemapLayer#cullPaddingX - * @type {number} - * @default 1 - * @since 3.50.0 + * @name Phaser.Physics.Matter.World#drawDebug + * @type {boolean} + * @default false + * @since 3.0.0 */ - this.cullPaddingX = 1; + this.drawDebug = (typeof(debugConfig) === 'object') ? true : debugConfig; /** - * The amount of extra tiles to add into the cull rectangle when calculating its vertical size. - * - * See the method `setCullPadding` for more details. + * An instance of the Graphics object the debug bodies are drawn to, if enabled. * - * @name Phaser.Tilemaps.TilemapLayer#cullPaddingY - * @type {number} - * @default 1 - * @since 3.50.0 + * @name Phaser.Physics.Matter.World#debugGraphic + * @type {Phaser.GameObjects.Graphics} + * @since 3.0.0 */ - this.cullPaddingY = 1; + this.debugGraphic; /** - * 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. + * The debug configuration object. * - * It will be sent 4 arguments: + * The values stored in this object are read from the Matter World Config `debug` property. * - * 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. + * When a new Body or Constraint is _added to the World_, they are given the values stored in this object, + * unless they have their own `render` object set that will override them. * - * See the `TilemapComponents.CullTiles` source code for details on implementing your own culling system. + * Note that while you can modify the values of properties in this object at run-time, it will not change + * any of the Matter objects _already added_. It will only impact objects newly added to the world, or one + * that is removed and then re-added at a later time. * - * @name Phaser.Tilemaps.TilemapLayer#cullCallback - * @type {function} - * @since 3.50.0 + * @name Phaser.Physics.Matter.World#debugConfig + * @type {Phaser.Types.Physics.Matter.MatterDebugConfig} + * @since 3.22.0 */ - this.cullCallback = TilemapComponents.GetCullTilesFunction(this.layer.orientation); + this.debugConfig = { + showAxes: GetFastValue(debugConfig, 'showAxes', false), + showAngleIndicator: GetFastValue(debugConfig, 'showAngleIndicator', false), + angleColor: GetFastValue(debugConfig, 'angleColor', 0xe81153), + + showBroadphase: GetFastValue(debugConfig, 'showBroadphase', false), + broadphaseColor: GetFastValue(debugConfig, 'broadphaseColor', 0xffb400), + + showBounds: GetFastValue(debugConfig, 'showBounds', false), + boundsColor: GetFastValue(debugConfig, 'boundsColor', 0xffffff), + + showVelocity: GetFastValue(debugConfig, 'showVelocity', false), + velocityColor: GetFastValue(debugConfig, 'velocityColor', 0x00aeef), + + showCollisions: GetFastValue(debugConfig, 'showCollisions', false), + collisionColor: GetFastValue(debugConfig, 'collisionColor', 0xf5950c), + + showSeparations: GetFastValue(debugConfig, 'showSeparations', false), + separationColor: GetFastValue(debugConfig, 'separationColor', 0xffa500), + + showBody: GetFastValue(debugConfig, 'showBody', true), + showStaticBody: GetFastValue(debugConfig, 'showStaticBody', true), + showInternalEdges: GetFastValue(debugConfig, 'showInternalEdges', false), + + renderFill: GetFastValue(debugConfig, 'renderFill', false), + renderLine: GetFastValue(debugConfig, 'renderLine', true), + + fillColor: GetFastValue(debugConfig, 'fillColor', 0x106909), + fillOpacity: GetFastValue(debugConfig, 'fillOpacity', 1), + lineColor: GetFastValue(debugConfig, 'lineColor', 0x28de19), + lineOpacity: GetFastValue(debugConfig, 'lineOpacity', 1), + lineThickness: GetFastValue(debugConfig, 'lineThickness', 1), + + staticFillColor: GetFastValue(debugConfig, 'staticFillColor', 0x0d177b), + staticLineColor: GetFastValue(debugConfig, 'staticLineColor', 0x1327e4), + + showSleeping: GetFastValue(debugConfig, 'showSleeping', false), + staticBodySleepOpacity: GetFastValue(debugConfig, 'staticBodySleepOpacity', 0.7), + sleepFillColor: GetFastValue(debugConfig, 'sleepFillColor', 0x464646), + sleepLineColor: GetFastValue(debugConfig, 'sleepLineColor', 0x999a99), + + showSensors: GetFastValue(debugConfig, 'showSensors', true), + sensorFillColor: GetFastValue(debugConfig, 'sensorFillColor', 0x0d177b), + sensorLineColor: GetFastValue(debugConfig, 'sensorLineColor', 0x1327e4), + + showPositions: GetFastValue(debugConfig, 'showPositions', true), + positionSize: GetFastValue(debugConfig, 'positionSize', 4), + positionColor: GetFastValue(debugConfig, 'positionColor', 0xe042da), + + showJoint: GetFastValue(debugConfig, 'showJoint', true), + jointColor: GetFastValue(debugConfig, 'jointColor', 0xe0e042), + jointLineOpacity: GetFastValue(debugConfig, 'jointLineOpacity', 1), + jointLineThickness: GetFastValue(debugConfig, 'jointLineThickness', 2), + + pinSize: GetFastValue(debugConfig, 'pinSize', 4), + pinColor: GetFastValue(debugConfig, 'pinColor', 0x42e0e0), + + springColor: GetFastValue(debugConfig, 'springColor', 0xe042e0), + + anchorColor: GetFastValue(debugConfig, 'anchorColor', 0xefefef), + anchorSize: GetFastValue(debugConfig, 'anchorSize', 4), + + showConvexHulls: GetFastValue(debugConfig, 'showConvexHulls', false), + hullColor: GetFastValue(debugConfig, 'hullColor', 0xd703d0) + }; + + if (this.drawDebug) + { + this.createDebugGraphic(); + } + + this.setEventsProxy(); + + // Create the walls + + if (GetFastValue(config, 'setBounds', false)) + { + var boundsConfig = config['setBounds']; + + if (typeof boundsConfig === 'boolean') + { + this.setBounds(); + } + else + { + var x = GetFastValue(boundsConfig, 'x', 0); + var y = GetFastValue(boundsConfig, 'y', 0); + var width = GetFastValue(boundsConfig, 'width', scene.sys.scale.width); + var height = GetFastValue(boundsConfig, 'height', scene.sys.scale.height); + var thickness = GetFastValue(boundsConfig, 'thickness', 64); + var left = GetFastValue(boundsConfig, 'left', true); + var right = GetFastValue(boundsConfig, 'right', true); + var top = GetFastValue(boundsConfig, 'top', true); + var bottom = GetFastValue(boundsConfig, 'bottom', true); + + this.setBounds(x, y, width, height, thickness, left, right, top, bottom); + } + } + }, + + /** + * Sets the debug render style for the children of the given Matter Composite. + * + * Composites themselves do not render, but they can contain bodies, constraints and other composites that may do. + * So the children of this composite are passed to the `setBodyRenderStyle`, `setCompositeRenderStyle` and + * `setConstraintRenderStyle` methods accordingly. + * + * @method Phaser.Physics.Matter.World#setCompositeRenderStyle + * @since 3.22.0 + * + * @param {MatterJS.CompositeType} composite - The Matter Composite to set the render style on. + * + * @return {this} This Matter World instance for method chaining. + */ + setCompositeRenderStyle: function (composite) + { + var bodies = composite.bodies; + var constraints = composite.constraints; + var composites = composite.composites; + + var i; + var obj; + var render; + + for (i = 0; i < bodies.length; i++) + { + obj = bodies[i]; + render = obj.render; + + this.setBodyRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.fillColor, render.fillOpacity); + } + + for (i = 0; i < constraints.length; i++) + { + obj = constraints[i]; + render = obj.render; + + this.setConstraintRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.pinSize, render.anchorColor, render.anchorSize); + } + + for (i = 0; i < composites.length; i++) + { + obj = composites[i]; + + this.setCompositeRenderStyle(obj); + } + + return this; + }, + + /** + * Sets the debug render style for the given Matter Body. + * + * If you are using this on a Phaser Game Object, such as a Matter Sprite, then pass in the body property + * to this method, not the Game Object itself. + * + * If you wish to skip a parameter, so it retains its current value, pass `false` for it. + * + * If you wish to reset the Body render colors to the defaults found in the World Debug Config, then call + * this method with just the `body` parameter provided and no others. + * + * @method Phaser.Physics.Matter.World#setBodyRenderStyle + * @since 3.22.0 + * + * @param {MatterJS.BodyType} body - The Matter Body to set the render style on. + * @param {number} [lineColor] - The line color. If `null` it will use the World Debug Config value. + * @param {number} [lineOpacity] - The line opacity, between 0 and 1. If `null` it will use the World Debug Config value. + * @param {number} [lineThickness] - The line thickness. If `null` it will use the World Debug Config value. + * @param {number} [fillColor] - The fill color. If `null` it will use the World Debug Config value. + * @param {number} [fillOpacity] - The fill opacity, between 0 and 1. If `null` it will use the World Debug Config value. + * + * @return {this} This Matter World instance for method chaining. + */ + setBodyRenderStyle: function (body, lineColor, lineOpacity, lineThickness, fillColor, fillOpacity) + { + var render = body.render; + var config = this.debugConfig; + + if (!render) + { + return this; + } + + if (lineColor === undefined || lineColor === null) + { + lineColor = (body.isStatic) ? config.staticLineColor : config.lineColor; + } + + if (lineOpacity === undefined || lineOpacity === null) + { + lineOpacity = config.lineOpacity; + } + + if (lineThickness === undefined || lineThickness === null) + { + lineThickness = config.lineThickness; + } + + if (fillColor === undefined || fillColor === null) + { + fillColor = (body.isStatic) ? config.staticFillColor : config.fillColor; + } + + if (fillOpacity === undefined || fillOpacity === null) + { + fillOpacity = config.fillOpacity; + } + + if (lineColor !== false) + { + render.lineColor = lineColor; + } + + if (lineOpacity !== false) + { + render.lineOpacity = lineOpacity; + } + + if (lineThickness !== false) + { + render.lineThickness = lineThickness; + } + + if (fillColor !== false) + { + render.fillColor = fillColor; + } + + if (fillOpacity !== false) + { + render.fillOpacity = fillOpacity; + } + + return this; + }, + + /** + * Sets the debug render style for the given Matter Constraint. + * + * If you are using this on a Phaser Game Object, then pass in the body property + * to this method, not the Game Object itself. + * + * If you wish to skip a parameter, so it retains its current value, pass `false` for it. + * + * If you wish to reset the Constraint render colors to the defaults found in the World Debug Config, then call + * this method with just the `constraint` parameter provided and no others. + * + * @method Phaser.Physics.Matter.World#setConstraintRenderStyle + * @since 3.22.0 + * + * @param {MatterJS.ConstraintType} constraint - The Matter Constraint to set the render style on. + * @param {number} [lineColor] - The line color. If `null` it will use the World Debug Config value. + * @param {number} [lineOpacity] - The line opacity, between 0 and 1. If `null` it will use the World Debug Config value. + * @param {number} [lineThickness] - The line thickness. If `null` it will use the World Debug Config value. + * @param {number} [pinSize] - If this constraint is a pin, this sets the size of the pin circle. If `null` it will use the World Debug Config value. + * @param {number} [anchorColor] - The color used when rendering this constraints anchors. If `null` it will use the World Debug Config value. + * @param {number} [anchorSize] - The size of the anchor circle, if this constraint has anchors. If `null` it will use the World Debug Config value. + * + * @return {this} This Matter World instance for method chaining. + */ + setConstraintRenderStyle: function (constraint, lineColor, lineOpacity, lineThickness, pinSize, anchorColor, anchorSize) + { + var render = constraint.render; + var config = this.debugConfig; + + if (!render) + { + return this; + } + + // Reset them + if (lineColor === undefined || lineColor === null) + { + var type = render.type; + + if (type === 'line') + { + lineColor = config.jointColor; + } + else if (type === 'pin') + { + lineColor = config.pinColor; + } + else if (type === 'spring') + { + lineColor = config.springColor; + } + } + + if (lineOpacity === undefined || lineOpacity === null) + { + lineOpacity = config.jointLineOpacity; + } + + if (lineThickness === undefined || lineThickness === null) + { + lineThickness = config.jointLineThickness; + } + + if (pinSize === undefined || pinSize === null) + { + pinSize = config.pinSize; + } + + if (anchorColor === undefined || anchorColor === null) + { + anchorColor = config.anchorColor; + } + + if (anchorSize === undefined || anchorSize === null) + { + anchorSize = config.anchorSize; + } + + if (lineColor !== false) + { + render.lineColor = lineColor; + } + + if (lineOpacity !== false) + { + render.lineOpacity = lineOpacity; + } + + if (lineThickness !== false) + { + render.lineThickness = lineThickness; + } + + if (pinSize !== false) + { + render.pinSize = pinSize; + } + + if (anchorColor !== false) + { + render.anchorColor = anchorColor; + } + + if (anchorSize !== false) + { + render.anchorSize = anchorSize; + } + + return this; + }, + + /** + * This internal method acts as a proxy between all of the Matter JS events and then re-emits them + * via this class. + * + * @method Phaser.Physics.Matter.World#setEventsProxy + * @since 3.0.0 + */ + setEventsProxy: function () + { + var _this = this; + var engine = this.engine; + var world = this.localWorld; + + // Inject debug styles + + if (this.drawDebug) + { + MatterEvents.on(world, 'compositeModified', function (composite) + { + _this.setCompositeRenderStyle(composite); + }); + + MatterEvents.on(world, 'beforeAdd', function (event) + { + var objects = [].concat(event.object); + + for (var i = 0; i < objects.length; i++) + { + var obj = objects[i]; + var render = obj.render; + + if (obj.type === 'body') + { + _this.setBodyRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.fillColor, render.fillOpacity); + } + else if (obj.type === 'composite') + { + _this.setCompositeRenderStyle(obj); + } + else if (obj.type === 'constraint') + { + _this.setConstraintRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.pinSize, render.anchorColor, render.anchorSize); + } + } + }); + } + + MatterEvents.on(world, 'beforeAdd', function (event) + { + _this.emit(Events.BEFORE_ADD, event); + }); + + MatterEvents.on(world, 'afterAdd', function (event) + { + _this.emit(Events.AFTER_ADD, event); + }); + + MatterEvents.on(world, 'beforeRemove', function (event) + { + _this.emit(Events.BEFORE_REMOVE, event); + }); + + MatterEvents.on(world, 'afterRemove', function (event) + { + _this.emit(Events.AFTER_REMOVE, event); + }); + + MatterEvents.on(engine, 'beforeUpdate', function (event) + { + _this.emit(Events.BEFORE_UPDATE, event); + }); + + MatterEvents.on(engine, 'afterUpdate', function (event) + { + _this.emit(Events.AFTER_UPDATE, event); + }); + + MatterEvents.on(engine, 'collisionStart', function (event) + { + var pairs = event.pairs; + var bodyA; + var bodyB; + + if (pairs.length > 0) + { + bodyA = pairs[0].bodyA; + bodyB = pairs[0].bodyB; + } + + _this.emit(Events.COLLISION_START, event, bodyA, bodyB); + }); + + MatterEvents.on(engine, 'collisionActive', function (event) + { + var pairs = event.pairs; + var bodyA; + var bodyB; - /** - * 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; + if (pairs.length > 0) + { + bodyA = pairs[0].bodyA; + bodyB = pairs[0].bodyB; + } - /** - * 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.emit(Events.COLLISION_ACTIVE, event, bodyA, bodyB); + }); - 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); + MatterEvents.on(engine, 'collisionEnd', function (event) + { + var pairs = event.pairs; + var bodyA; + var bodyB; - this.initPipeline(); + if (pairs.length > 0) + { + bodyA = pairs[0].bodyA; + bodyB = pairs[0].bodyB; + } + + _this.emit(Events.COLLISION_END, event, bodyA, bodyB); + }); }, /** - * Populates the internal `tileset` array with the Tileset references this Layer requires for rendering. + * Sets the bounds of the Physics world to match the given world pixel dimensions. * - * @method Phaser.Tilemaps.TilemapLayer#setTilesets - * @private - * @since 3.50.0 + * You can optionally set which 'walls' to create: left, right, top or bottom. + * If none of the walls are given it will default to use the walls settings it had previously. + * I.e. if you previously told it to not have the left or right walls, and you then adjust the world size + * the newly created bounds will also not have the left and right walls. + * Explicitly state them in the parameters to override this. * - * @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. + * @method Phaser.Physics.Matter.World#setBounds + * @since 3.0.0 + * + * @param {number} [x=0] - The x coordinate of the top-left corner of the bounds. + * @param {number} [y=0] - The y coordinate of the top-left corner of the bounds. + * @param {number} [width] - The width of the bounds. + * @param {number} [height] - The height of the bounds. + * @param {number} [thickness=64] - The thickness of each wall, in pixels. + * @param {boolean} [left=true] - If true will create the left bounds wall. + * @param {boolean} [right=true] - If true will create the right bounds wall. + * @param {boolean} [top=true] - If true will create the top bounds wall. + * @param {boolean} [bottom=true] - If true will create the bottom bounds wall. + * + * @return {Phaser.Physics.Matter.World} This Matter World object. */ - setTilesets: function (tilesets) + setBounds: function (x, y, width, height, thickness, left, right, top, bottom) { - var gidMap = []; - var setList = []; - var map = this.tilemap; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.scene.sys.scale.width; } + if (height === undefined) { height = this.scene.sys.scale.height; } + if (thickness === undefined) { thickness = 64; } + if (left === undefined) { left = true; } + if (right === undefined) { right = true; } + if (top === undefined) { top = true; } + if (bottom === undefined) { bottom = true; } - if (!Array.isArray(tilesets)) - { - tilesets = [ tilesets ]; - } + this.updateWall(left, 'left', x - thickness, y - thickness, thickness, height + (thickness * 2)); + this.updateWall(right, 'right', x + width, y - thickness, thickness, height + (thickness * 2)); + this.updateWall(top, 'top', x, y - thickness, width, thickness); + this.updateWall(bottom, 'bottom', x, y + height, width, thickness); - for (var i = 0; i < tilesets.length; i++) - { - var tileset = tilesets[i]; + return this; + }, - if (typeof tileset === 'string') - { - tileset = map.getTileset(tileset); - } + /** + * Updates the 4 rectangle bodies that were created, if `setBounds` was set in the Matter config, to use + * the new positions and sizes. This method is usually only called internally via the `setBounds` method. + * + * @method Phaser.Physics.Matter.World#updateWall + * @since 3.0.0 + * + * @param {boolean} add - `true` if the walls are being added or updated, `false` to remove them from the world. + * @param {string} [position] - Either `left`, `right`, `top` or `bottom`. Only optional if `add` is `false`. + * @param {number} [x] - The horizontal position to place the walls at. Only optional if `add` is `false`. + * @param {number} [y] - The vertical position to place the walls at. Only optional if `add` is `false`. + * @param {number} [width] - The width of the walls, in pixels. Only optional if `add` is `false`. + * @param {number} [height] - The height of the walls, in pixels. Only optional if `add` is `false`. + */ + updateWall: function (add, position, x, y, width, height) + { + var wall = this.walls[position]; - if (tileset) + if (add) + { + if (wall) { - setList.push(tileset); + MatterWorld.remove(this.localWorld, wall); + } - var s = tileset.firstgid; + // adjust center + x += (width / 2); + y += (height / 2); - for (var t = 0; t < tileset.total; t++) - { - gidMap[s + t] = tileset; - } - } + this.walls[position] = this.create(x, y, width, height, { isStatic: true, friction: 0, frictionStatic: 0 }); } + else + { + if (wall) + { + MatterWorld.remove(this.localWorld, wall); + } - this.gidMap = gidMap; - this.tileset = setList; + this.walls[position] = null; + } }, /** - * 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 + * Creates a Phaser.GameObjects.Graphics object that is used to render all of the debug bodies and joints to. * - * 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. + * This method is called automatically by the constructor, if debugging has been enabled. * - * You can provide either an integer (0 to 3), or the string version of the order. + * The created Graphics object is automatically added to the Scene at 0x0 and given a depth of `Number.MAX_VALUE`, + * so it renders above all else in the Scene. * - * @method Phaser.Tilemaps.TilemapLayer#setRenderOrder - * @since 3.50.0 + * The Graphics object is assigned to the `debugGraphic` property of this class and `drawDebug` is enabled. * - * @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'. + * @method Phaser.Physics.Matter.World#createDebugGraphic + * @since 3.0.0 * - * @return {this} This Tilemap Layer object. + * @return {Phaser.GameObjects.Graphics} The newly created Graphics object. */ - setRenderOrder: function (renderOrder) + createDebugGraphic: function () { - var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; + var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 }); - if (typeof renderOrder === 'string') - { - renderOrder = orders.indexOf(renderOrder); - } + graphic.setDepth(Number.MAX_VALUE); - if (renderOrder >= 0 && renderOrder < 4) - { - this._renderOrder = renderOrder; - } + this.debugGraphic = graphic; - return this; + this.drawDebug = true; + + return graphic; }, /** - * 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 + * Sets the world gravity and gravity scale to 0. * - * @param {number} tileX - The x coordinate. - * @param {number} tileY - The y coordinate. + * @method Phaser.Physics.Matter.World#disableGravity + * @since 3.0.0 * - * @return {this} This Tilemap Layer object. + * @return {this} This Matter World object. */ - calculateFacesAt: function (tileX, tileY) + disableGravity: function () { - TilemapComponents.CalculateFacesAt(tileX, tileY, this.layer); + this.localWorld.gravity.x = 0; + this.localWorld.gravity.y = 0; + this.localWorld.gravity.scale = 0; 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. + * Sets the worlds gravity to the values given. * - * @method Phaser.Tilemaps.TilemapLayer#calculateFacesWithin - * @since 3.50.0 + * Gravity effects all bodies in the world, unless they have the `ignoreGravity` flag set. * - * @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. + * @method Phaser.Physics.Matter.World#setGravity + * @since 3.0.0 * - * @return {this} This Tilemap Layer object. + * @param {number} [x=0] - The world gravity x component. + * @param {number} [y=1] - The world gravity y component. + * @param {number} [scale=0.001] - The gravity scale factor. + * + * @return {this} This Matter World object. */ - calculateFacesWithin: function (tileX, tileY, width, height) + setGravity: function (x, y, scale) { - TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, this.layer); + if (x === undefined) { x = 0; } + if (y === undefined) { y = 1; } + if (scale === undefined) { scale = 0.001; } + + this.localWorld.gravity.x = x; + this.localWorld.gravity.y = y; + this.localWorld.gravity.scale = scale; 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. + * Creates a rectangle Matter body and adds it to the world. * - * @method Phaser.Tilemaps.TilemapLayer#createFromTiles - * @since 3.50.0 + * @method Phaser.Physics.Matter.World#create + * @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 determining the world XY + * @param {number} x - The horizontal position of the body in the world. + * @param {number} y - The vertical position of the body in the world. + * @param {number} width - The width of the body. + * @param {number} height - The height of the body. + * @param {object} options - Optional Matter configuration object. * - * @return {Phaser.GameObjects.Sprite[]} An array of the Sprites that were created. + * @return {MatterJS.BodyType} The Matter.js body that was created. */ - createFromTiles: function (indexes, replacements, spriteConfig, scene, camera) + create: function (x, y, width, height, options) { - return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, this.layer); + var body = Bodies.rectangle(x, y, width, height, options); + + MatterWorld.add(this.localWorld, body); + + return body; }, /** - * Returns the tiles in the given layer that are within the cameras viewport. - * This is used internally during rendering. + * Adds a Matter JS object, or array of objects, to the world. * - * @method Phaser.Tilemaps.TilemapLayer#cull - * @since 3.50.0 + * The objects should be valid Matter JS entities, such as a Body, Composite or Constraint. * - * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against. + * Triggers `beforeAdd` and `afterAdd` events. * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects to render. + * @method Phaser.Physics.Matter.World#add + * @since 3.0.0 + * + * @param {(object|object[])} object - Can be single object, or an array, and can be a body, composite or constraint. + * + * @return {this} This Matter World object. */ - cull: function (camera) + add: function (object) { - return this.cullCallback(this.layer, camera, this.culledTiles, this._renderOrder); + MatterWorld.add(this.localWorld, object); + + return this; }, /** - * 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. + * Removes a Matter JS object, or array of objects, from the world. * - * @method Phaser.Tilemaps.TilemapLayer#copy - * @since 3.50.0 + * The objects should be valid Matter JS entities, such as a Body, Composite or Constraint. * - * @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. + * Triggers `beforeRemove` and `afterRemove` events. * - * @return {this} This Tilemap Layer object. + * @method Phaser.Physics.Matter.World#remove + * @since 3.0.0 + * + * @param {(object|object[])} object - Can be single object, or an array, and can be a body, composite or constraint. + * @param {boolean} [deep=false] - Optionally search the objects children and recursively remove those as well. + * + * @return {this} This Matter World object. */ - copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces) + remove: function (object, deep) { - TilemapComponents.Copy(srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, this.layer); + if (!Array.isArray(object)) + { + object = [ object ]; + } + + for (var i = 0; i < object.length; i++) + { + var entity = object[i]; + + var body = (entity.body) ? entity.body : entity; + + Composite.remove(this.localWorld, body, deep); + } 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. + * Removes a Matter JS constraint, or array of constraints, from the world. * - * @method Phaser.Tilemaps.TilemapLayer#fill - * @since 3.50.0 + * Triggers `beforeRemove` and `afterRemove` events. * - * @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. + * @method Phaser.Physics.Matter.World#removeConstraint + * @since 3.0.0 * - * @return {this} This Tilemap Layer object. + * @param {(MatterJS.ConstraintType|MatterJS.ConstraintType[])} constraint - A Matter JS Constraint, or an array of constraints, to be removed. + * @param {boolean} [deep=false] - Optionally search the objects children and recursively remove those as well. + * + * @return {this} This Matter World object. */ - fill: function (index, tileX, tileY, width, height, recalculateFaces) + removeConstraint: function (constraint, deep) { - TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, this.layer); + Composite.remove(this.localWorld, constraint, deep); 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. + * Adds `MatterTileBody` instances for all the colliding tiles within the given tilemap layer. * - * @method Phaser.Tilemaps.TilemapLayer#filterTiles - * @since 3.50.0 + * Set the appropriate tiles in your layer to collide before calling this method! * - * @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. + * @method Phaser.Physics.Matter.World#convertTilemapLayer + * @since 3.0.0 * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - An array of tiles. + * @param {object} [options] - Options to be passed to the MatterTileBody constructor. {@see Phaser.Physics.Matter.TileBody} + * + * @return {this} This Matter World object. */ - filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions) + convertTilemapLayer: function (tilemapLayer, options) { - return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); + var layerData = tilemapLayer.layer; + var tiles = tilemapLayer.getTilesWithin(0, 0, layerData.width, layerData.height, { isColliding: true }); + + this.convertTiles(tiles, options); + + return this; }, /** - * 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. + * Adds `MatterTileBody` instances for the given tiles. This adds bodies regardless of whether the + * tiles are set to collide or not. * - * @method Phaser.Tilemaps.TilemapLayer#findByIndex - * @since 3.50.0 + * @method Phaser.Physics.Matter.World#convertTiles + * @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 {Phaser.Tilemaps.Tile[]} tiles - An array of tiles. + * @param {object} [options] - Options to be passed to the MatterTileBody constructor. {@see Phaser.Physics.Matter.TileBody} * - * @return {Phaser.Tilemaps.Tile} The first matching Tile object. + * @return {this} This Matter World object. */ - findByIndex: function (findIndex, skip, reverse) + convertTiles: function (tiles, options) { - return TilemapComponents.FindByIndex(findIndex, skip, reverse, this.layer); + if (tiles.length === 0) + { + return this; + } + + for (var i = 0; i < tiles.length; i++) + { + new MatterTileBody(this, tiles[i], options); + } + + return this; }, /** - * 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. + * Returns the next unique group index for which bodies will collide. + * If `isNonColliding` is `true`, returns the next unique group index for which bodies will not collide. * - * @method Phaser.Tilemaps.TilemapLayer#findTile - * @since 3.50.0 + * @method Phaser.Physics.Matter.World#nextGroup + * @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 {boolean} [isNonColliding=false] - If `true`, returns the next unique group index for which bodies will _not_ collide. * - * @return {?Phaser.Tilemaps.Tile} The first Tile found at the given location. + * @return {number} Unique category bitfield */ - findTile: function (callback, context, tileX, tileY, width, height, filteringOptions) + nextGroup: function (isNonColliding) { - return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); + return MatterBody.nextGroup(isNonColliding); }, /** - * 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 + * Returns the next unique category bitfield (starting after the initial default category 0x0001). + * There are 32 available. * - * @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. + * @method Phaser.Physics.Matter.World#nextCategory + * @since 3.0.0 * - * @return {this} This Tilemap Layer object. + * @return {number} Unique category bitfield */ - forEachTile: function (callback, context, tileX, tileY, width, height, filteringOptions) + nextCategory: function () { - TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); - - return this; + return MatterBody.nextCategory(); }, /** - * Gets a tile at the given tile coordinates from the given layer. + * Pauses this Matter World instance and sets `enabled` to `false`. * - * @method Phaser.Tilemaps.TilemapLayer#getTileAt - * @since 3.50.0 + * A paused world will not run any simulations for the duration it is paused. * - * @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. + * @method Phaser.Physics.Matter.World#pause + * @fires Phaser.Physics.Matter.Events#PAUSE + * @since 3.0.0 * - * @return {Phaser.Tilemaps.Tile} The Tile at the given coordinates or null if no tile was found or the coordinates were invalid. + * @return {this} This Matter World object. */ - getTileAt: function (tileX, tileY, nonNull) + pause: function () { - return TilemapComponents.GetTileAt(tileX, tileY, nonNull, this.layer); + this.enabled = false; + + this.emit(Events.PAUSE); + + return this; }, /** - * Gets a tile at the given world coordinates from the given layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTileAtWorldXY - * @since 3.50.0 + * Resumes this Matter World instance from a paused state and sets `enabled` to `true`. * - * @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. + * @method Phaser.Physics.Matter.World#resume + * @fires Phaser.Physics.Matter.Events#RESUME + * @since 3.0.0 * - * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid. + * @return {this} This Matter World object. */ - getTileAtWorldXY: function (worldX, worldY, nonNull, camera) + resume: function () { - return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, this.layer); + this.enabled = true; + + this.emit(Events.RESUME); + + return this; }, /** - * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. + * The internal update method. This is called automatically by the parent Scene. * - * @method Phaser.Tilemaps.TilemapLayer#getTilesWithin - * @since 3.50.0 + * Moves the simulation forward in time by delta ms. Uses `World.correction` value as an optional number that + * specifies the time correction factor to apply to the update. This can help improve the accuracy of the + * simulation in cases where delta is changing between updates. The value of correction is defined as `delta / lastDelta`, + * i.e. the percentage change of delta over the last step. Therefore the value is always 1 (no correction) when + * delta is constant (or when no correction is desired, which is the default). + * See the paper on Time Corrected Verlet for more information. * - * @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. + * Triggers `beforeUpdate` and `afterUpdate` events. Triggers `collisionStart`, `collisionActive` and `collisionEnd` events. * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. + * If the World is paused, `update` is still run, but exits early and does not update the Matter Engine. + * + * @method Phaser.Physics.Matter.World#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. */ - getTilesWithin: function (tileX, tileY, width, height, filteringOptions) + update: function (time, delta) { - return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, this.layer); + if (!this.enabled || !this.autoUpdate) + { + return; + } + + var engine = this.engine; + var runner = this.runner; + + var timing = engine.timing; + + if (runner.isFixed) + { + // fixed timestep + delta = this.getDelta(time, delta); + } + else + { + // dynamic timestep based on wall clock between calls + delta = (time - runner.timePrev) || runner.delta; + runner.timePrev = time; + + // optimistically filter delta over a few frames, to improve stability + runner.deltaHistory.push(delta); + runner.deltaHistory = runner.deltaHistory.slice(-runner.deltaSampleSize); + delta = Math.min.apply(null, runner.deltaHistory); + + // limit delta + delta = delta < runner.deltaMin ? runner.deltaMin : delta; + delta = delta > runner.deltaMax ? runner.deltaMax : delta; + + // update engine timing object + runner.delta = delta; + } + + runner.timeScalePrev = timing.timeScale; + + // fps counter + runner.frameCounter += 1; + + if (time - runner.counterTimestamp >= 1000) + { + runner.fps = runner.frameCounter * ((time - runner.counterTimestamp) / 1000); + runner.counterTimestamp = time; + runner.frameCounter = 0; + } + + Engine.update(engine, delta); }, /** - * 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. + * Manually advances the physics simulation by one iteration. * - * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinShape - * @since 3.50.0 + * You can optionally pass in the `delta` and `correction` values to be used by Engine.update. + * If undefined they use the Matter defaults of 60Hz and no correction. * - * @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. + * Calling `step` directly bypasses any checks of `enabled` or `autoUpdate`. * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the shape. + * It also ignores any custom `getDelta` functions, as you should be passing the delta + * value in to this call. + * + * You can adjust the number of iterations that Engine.update performs internally. + * Use the Scene Matter Physics config object to set the following properties: + * + * positionIterations (defaults to 6) + * velocityIterations (defaults to 4) + * constraintIterations (defaults to 2) + * + * Adjusting these values can help performance in certain situations, depending on the physics requirements + * of your game. + * + * @method Phaser.Physics.Matter.World#step + * @since 3.4.0 + * + * @param {number} [delta=16.666] - The delta value. */ - getTilesWithinShape: function (shape, filteringOptions, camera) + step: function (delta) { - return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, this.layer); + Engine.update(this.engine, delta); }, /** - * Gets the tiles in the given rectangular area (in world coordinates) of the layer. - * - * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinWorldXY - * @since 3.50.0 + * Runs the Matter Engine.update at a fixed timestep of 60Hz. * - * @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. + * @method Phaser.Physics.Matter.World#update60Hz + * @since 3.4.0 * - * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area. + * @return {number} The delta value to be passed to Engine.update. */ - getTilesWithinWorldXY: function (worldX, worldY, width, height, filteringOptions, camera) + update60Hz: function () { - return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, this.layer); + return 1000 / 60; }, /** - * 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 + * Runs the Matter Engine.update at a fixed timestep of 30Hz. * - * @param {number} tileX - The x coordinate, in tiles, not pixels. - * @param {number} tileY - The y coordinate, in tiles, not pixels. + * @method Phaser.Physics.Matter.World#update30Hz + * @since 3.4.0 * - * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. + * @return {number} The delta value to be passed to Engine.update. */ - hasTileAt: function (tileX, tileY) + update30Hz: function () { - return TilemapComponents.HasTileAt(tileX, tileY, this.layer); + return 1000 / 30; }, /** - * 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. + * Returns `true` if the given body can be found within the World. * - * @method Phaser.Tilemaps.TilemapLayer#hasTileAtWorldXY - * @since 3.50.0 + * @method Phaser.Physics.Matter.World#has + * @since 3.22.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 {(MatterJS.Body|Phaser.GameObjects.GameObject)} body - The Matter Body, or Game Object, to search for within the world. * - * @return {boolean} `true` if a tile was found at the given location, otherwise `false`. + * @return {MatterJS.BodyType[]} An array of all the Matter JS Bodies in this World. */ - hasTileAtWorldXY: function (worldX, worldY, camera) + has: function (body) { - return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, this.layer); + var src = (body.hasOwnProperty('body')) ? body.body : body; + + return (Composite.get(this.localWorld, src.id, src.type) !== null); }, /** - * 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 + * Returns all the bodies in the Matter World, including all bodies in children, recursively. * - * @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. + * @method Phaser.Physics.Matter.World#getAllBodies + * @since 3.22.0 * - * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. + * @return {MatterJS.BodyType[]} An array of all the Matter JS Bodies in this World. */ - putTileAt: function (tile, tileX, tileY, recalculateFaces) + getAllBodies: function () { - return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, this.layer); + return Composite.allBodies(this.localWorld); }, /** - * 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 + * Returns all the constraints in the Matter World, including all constraints in children, recursively. * - * @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. + * @method Phaser.Physics.Matter.World#getAllConstraints + * @since 3.22.0 * - * @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates. + * @return {MatterJS.ConstraintType[]} An array of all the Matter JS Constraints in this World. */ - putTileAtWorldXY: function (tile, worldX, worldY, recalculateFaces, camera) + getAllConstraints: function () { - return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, this.layer); + return Composite.allConstraints(this.localWorld); }, /** - * 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 + * Returns all the composites in the Matter World, including all composites in children, recursively. * - * @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. + * @method Phaser.Physics.Matter.World#getAllComposites + * @since 3.22.0 * - * @return {this} This Tilemap Layer object. + * @return {MatterJS.CompositeType[]} An array of all the Matter JS Composites in this World. */ - putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces) + getAllComposites: function () { - TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, this.layer); - - return this; + return Composite.allComposites(this.localWorld); }, /** - * 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 + * Handles the rendering of bodies and debug information to the debug Graphics object, if enabled. * - * @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. + * This method is called automatically by the Scene after all processing has taken place. * - * @return {this} This Tilemap Layer object. + * @method Phaser.Physics.Matter.World#postUpdate + * @private + * @since 3.0.0 */ - randomize: function (tileX, tileY, width, height, indexes) + postUpdate: function () { - TilemapComponents.Randomize(tileX, tileY, width, height, indexes, this.layer); + if (!this.drawDebug) + { + return; + } - return this; + var config = this.debugConfig; + var engine = this.engine; + var graphics = this.debugGraphic; + + var bodies = Composite.allBodies(this.localWorld); + + this.debugGraphic.clear(); + + if (config.showBroadphase && engine.broadphase.controller) + { + this.renderGrid(engine.broadphase, graphics, config.broadphaseColor, 0.5); + } + + if (config.showBounds) + { + this.renderBodyBounds(bodies, graphics, config.boundsColor, 0.5); + } + + if (config.showBody || config.showStaticBody) + { + this.renderBodies(bodies); + } + + if (config.showJoint) + { + this.renderJoints(); + } + + if (config.showAxes || config.showAngleIndicator) + { + this.renderBodyAxes(bodies, graphics, config.showAxes, config.angleColor, 0.5); + } + + if (config.showVelocity) + { + this.renderBodyVelocity(bodies, graphics, config.velocityColor, 1, 2); + } + + if (config.showSeparations) + { + this.renderSeparations(engine.pairs.list, graphics, config.separationColor); + } + + if (config.showCollisions) + { + this.renderCollisions(engine.pairs.list, graphics, config.collisionColor); + } }, /** - * Removes the tile at the given tile coordinates in the specified layer and updates the layers - * collision information. + * Renders the Engine Broadphase Controller Grid to the given Graphics instance. * - * @method Phaser.Tilemaps.TilemapLayer#removeTileAt - * @since 3.50.0 + * The debug renderer calls this method if the `showBroadphase` config value is set. * - * @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. + * This method is used internally by the Matter Debug Renderer, but is also exposed publically should + * you wish to render the Grid to your own Graphics instance. * - * @return {Phaser.Tilemaps.Tile} A Tile object. + * @method Phaser.Physics.Matter.World#renderGrid + * @since 3.22.0 + * + * @param {MatterJS.Grid} grid - The Matter Grid to be rendered. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. + * @param {number} lineColor - The line color. + * @param {number} lineOpacity - The line opacity, between 0 and 1. + * + * @return {this} This Matter World instance for method chaining. */ - removeTileAt: function (tileX, tileY, replaceWithNull, recalculateFaces) + renderGrid: function (grid, graphics, lineColor, lineOpacity) { - return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, this.layer); + graphics.lineStyle(1, lineColor, lineOpacity); + + var bucketKeys = Common.keys(grid.buckets); + + for (var i = 0; i < bucketKeys.length; i++) + { + var bucketId = bucketKeys[i]; + + if (grid.buckets[bucketId].length < 2) + { + continue; + } + + var region = bucketId.split(/C|R/); + + graphics.strokeRect( + parseInt(region[1], 10) * grid.bucketWidth, + parseInt(region[2], 10) * grid.bucketHeight, + grid.bucketWidth, + grid.bucketHeight + ); + } + + return this; }, /** - * Removes the tile at the given world coordinates in the specified layer and updates the layers - * collision information. + * Renders the list of Pair separations to the given Graphics instance. * - * @method Phaser.Tilemaps.TilemapLayer#removeTileAtWorldXY - * @since 3.50.0 + * The debug renderer calls this method if the `showSeparations` config value is set. * - * @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. + * This method is used internally by the Matter Debug Renderer, but is also exposed publically should + * you wish to render the Grid to your own Graphics instance. * - * @return {Phaser.Tilemaps.Tile} The Tile object that was removed from the given location. + * @method Phaser.Physics.Matter.World#renderSeparations + * @since 3.22.0 + * + * @param {MatterJS.Pair[]} pairs - An array of Matter Pairs to be rendered. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. + * @param {number} lineColor - The line color. + * + * @return {this} This Matter World instance for method chaining. */ - removeTileAtWorldXY: function (worldX, worldY, replaceWithNull, recalculateFaces, camera) + renderSeparations: function (pairs, graphics, lineColor) { - return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, this.layer); + graphics.lineStyle(1, lineColor, 1); + + for (var i = 0; i < pairs.length; i++) + { + var pair = pairs[i]; + + if (!pair.isActive) + { + continue; + } + + var collision = pair.collision; + var bodyA = collision.bodyA; + var bodyB = collision.bodyB; + var posA = bodyA.position; + var posB = bodyB.position; + var penetration = collision.penetration; + + var k = (!bodyA.isStatic && !bodyB.isStatic) ? 4 : 1; + + if (bodyB.isStatic) + { + k = 0; + } + + graphics.lineBetween( + posB.x, + posB.y, + posB.x - (penetration.x * k), + posB.y - (penetration.y * k) + ); + + k = (!bodyA.isStatic && !bodyB.isStatic) ? 4 : 1; + + if (bodyA.isStatic) + { + k = 0; + } + + graphics.lineBetween( + posA.x, + posA.y, + posA.x - (penetration.x * k), + posA.y - (penetration.y * k) + ); + } + + return this; }, /** - * 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. + * Renders the list of collision points and normals to the given Graphics instance. * - * @method Phaser.Tilemaps.TilemapLayer#renderDebug - * @since 3.50.0 + * The debug renderer calls this method if the `showCollisions` config value is set. * - * @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. + * This method is used internally by the Matter Debug Renderer, but is also exposed publically should + * you wish to render the Grid to your own Graphics instance. * - * @return {this} This Tilemap Layer object. + * @method Phaser.Physics.Matter.World#renderCollisions + * @since 3.22.0 + * + * @param {MatterJS.Pair[]} pairs - An array of Matter Pairs to be rendered. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. + * @param {number} lineColor - The line color. + * + * @return {this} This Matter World instance for method chaining. */ - renderDebug: function (graphics, styleConfig) + renderCollisions: function (pairs, graphics, lineColor) { - TilemapComponents.RenderDebug(graphics, styleConfig, this.layer); + graphics.lineStyle(1, lineColor, 0.5); + graphics.fillStyle(lineColor, 1); + + var i; + var pair; + + // Collision Positions + + for (i = 0; i < pairs.length; i++) + { + pair = pairs[i]; + + if (!pair.isActive) + { + continue; + } + + for (var j = 0; j < pair.activeContacts.length; j++) + { + var contact = pair.activeContacts[j]; + var vertex = contact.vertex; + + graphics.fillRect(vertex.x - 2, vertex.y - 2, 5, 5); + } + } + + // Collision Normals + + for (i = 0; i < pairs.length; i++) + { + pair = pairs[i]; + + if (!pair.isActive) + { + continue; + } + + var collision = pair.collision; + var contacts = pair.activeContacts; + + if (contacts.length > 0) + { + var normalPosX = contacts[0].vertex.x; + var normalPosY = contacts[0].vertex.y; + + if (contacts.length === 2) + { + normalPosX = (contacts[0].vertex.x + contacts[1].vertex.x) / 2; + normalPosY = (contacts[0].vertex.y + contacts[1].vertex.y) / 2; + } + + if (collision.bodyB === collision.supports[0].body || collision.bodyA.isStatic) + { + graphics.lineBetween( + normalPosX - collision.normal.x * 8, + normalPosY - collision.normal.y * 8, + normalPosX, + normalPosY + ); + } + else + { + graphics.lineBetween( + normalPosX + collision.normal.x * 8, + normalPosY + collision.normal.y * 8, + normalPosX, + normalPosY + ); + } + } + } 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. + * Renders the bounds of an array of Bodies to the given Graphics instance. * - * @method Phaser.Tilemaps.TilemapLayer#replaceByIndex - * @since 3.50.0 + * If the body is a compound body, it will render the bounds for the parent compound. * - * @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. + * The debug renderer calls this method if the `showBounds` config value is set. * - * @return {this} This Tilemap Layer object. + * This method is used internally by the Matter Debug Renderer, but is also exposed publically should + * you wish to render bounds to your own Graphics instance. + * + * @method Phaser.Physics.Matter.World#renderBodyBounds + * @since 3.22.0 + * + * @param {array} bodies - An array of bodies from the localWorld. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. + * @param {number} lineColor - The line color. + * @param {number} lineOpacity - The line opacity, between 0 and 1. */ - replaceByIndex: function (findIndex, newIndex, tileX, tileY, width, height) + renderBodyBounds: function (bodies, graphics, lineColor, lineOpacity) { - TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, this.layer); + graphics.lineStyle(1, lineColor, lineOpacity); + + for (var i = 0; i < bodies.length; i++) + { + var body = bodies[i]; + + // 1) Don't show invisible bodies + if (!body.render.visible) + { + continue; + } + + var bounds = body.bounds; + + if (bounds) + { + graphics.strokeRect( + bounds.min.x, + bounds.min.y, + bounds.max.x - bounds.min.x, + bounds.max.y - bounds.min.y + ); + } + else + { + var parts = body.parts; + + for (var j = parts.length > 1 ? 1 : 0; j < parts.length; j++) + { + var part = parts[j]; + + graphics.strokeRect( + part.bounds.min.x, + part.bounds.min.y, + part.bounds.max.x - part.bounds.min.x, + part.bounds.max.y - part.bounds.min.y + ); + } + } + } 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. + * Renders either all axes, or a single axis indicator, for an array of Bodies, to the given Graphics instance. * - * However, there are some instances when you may wish to disable this. + * The debug renderer calls this method if the `showAxes` or `showAngleIndicator` config values are set. * - * @method Phaser.Tilemaps.TilemapLayer#setSkipCull - * @since 3.50.0 + * This method is used internally by the Matter Debug Renderer, but is also exposed publically should + * you wish to render bounds to your own Graphics instance. * - * @param {boolean} [value=true] - Set to `true` to stop culling tiles. Set to `false` to enable culling again. + * @method Phaser.Physics.Matter.World#renderBodyAxes + * @since 3.22.0 * - * @return {this} This Tilemap Layer object. + * @param {array} bodies - An array of bodies from the localWorld. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. + * @param {boolean} showAxes - If `true` it will render all body axes. If `false` it will render a single axis indicator. + * @param {number} lineColor - The line color. + * @param {number} lineOpacity - The line opacity, between 0 and 1. */ - setSkipCull: function (value) + renderBodyAxes: function (bodies, graphics, showAxes, lineColor, lineOpacity) { - if (value === undefined) { value = true; } + graphics.lineStyle(1, lineColor, lineOpacity); - this.skipCull = value; + for (var i = 0; i < bodies.length; i++) + { + var body = bodies[i]; + var parts = body.parts; - return this; - }, + // 1) Don't show invisible bodies + if (!body.render.visible) + { + continue; + } - /** - * 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; } + var part; + var j; + var k; - this.cullPaddingX = paddingX; - this.cullPaddingY = paddingY; + if (showAxes) + { + for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) + { + part = parts[j]; - return this; - }, + for (k = 0; k < part.axes.length; k++) + { + var axis = part.axes[k]; - /** - * 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); + graphics.lineBetween( + part.position.x, + part.position.y, + part.position.x + axis.x * 20, + part.position.y + axis.y * 20 + ); + } + } + } + else + { + for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) + { + part = parts[j]; + + for (k = 0; k < part.axes.length; k++) + { + graphics.lineBetween( + part.position.x, + part.position.y, + (part.vertices[0].x + part.vertices[part.vertices.length - 1].x) / 2, + (part.vertices[0].y + part.vertices[part.vertices.length - 1].y) / 2 + ); + } + } + } + } 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). + * Renders a velocity indicator for an array of Bodies, to the given Graphics instance. * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionBetween - * @since 3.50.0 + * The debug renderer calls this method if the `showVelocity` config value is set. * - * @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. + * This method is used internally by the Matter Debug Renderer, but is also exposed publically should + * you wish to render bounds to your own Graphics instance. * - * @return {this} This Tilemap Layer object. + * @method Phaser.Physics.Matter.World#renderBodyVelocity + * @since 3.22.0 + * + * @param {array} bodies - An array of bodies from the localWorld. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. + * @param {number} lineColor - The line color. + * @param {number} lineOpacity - The line opacity, between 0 and 1. + * @param {number} lineThickness - The line thickness. */ - setCollisionBetween: function (start, stop, collides, recalculateFaces) + renderBodyVelocity: function (bodies, graphics, lineColor, lineOpacity, lineThickness) { - TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, this.layer); + graphics.lineStyle(lineThickness, lineColor, lineOpacity); - return this; - }, + for (var i = 0; i < bodies.length; i++) + { + var body = bodies[i]; - /** - * 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); + // 1) Don't show invisible bodies + if (!body.render.visible) + { + continue; + } + + graphics.lineBetween( + body.position.x, + body.position.y, + body.position.x + (body.position.x - body.positionPrev.x) * 2, + body.position.y + (body.position.y - body.positionPrev.y) * 2 + ); + } 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. + * Renders the given array of Bodies to the debug graphics instance. * - * @method Phaser.Tilemaps.TilemapLayer#setCollisionByExclusion - * @since 3.50.0 + * Called automatically by the `postUpdate` method. * - * @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. + * @method Phaser.Physics.Matter.World#renderBodies + * @private + * @since 3.14.0 * - * @return {this} This Tilemap Layer object. + * @param {array} bodies - An array of bodies from the localWorld. */ - setCollisionByExclusion: function (indexes, collides, recalculateFaces) + renderBodies: function (bodies) { - TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, this.layer); + var graphics = this.debugGraphic; - return this; - }, + var config = this.debugConfig; - /** - * 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); + var showBody = config.showBody; + var showStaticBody = config.showStaticBody; + var showSleeping = config.showSleeping; + var showInternalEdges = config.showInternalEdges; + var showConvexHulls = config.showConvexHulls; - return this; - }, + var renderFill = config.renderFill; + var renderLine = config.renderLine; - /** - * 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); + var staticBodySleepOpacity = config.staticBodySleepOpacity; + var sleepFillColor = config.sleepFillColor; + var sleepLineColor = config.sleepLineColor; - return this; - }, + var hullColor = config.hullColor; - /** - * 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); + for (var i = 0; i < bodies.length; i++) + { + var body = bodies[i]; - return this; - }, + // 1) Don't show invisible bodies + if (!body.render.visible) + { + continue; + } - /** - * 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); + // 2) Don't show static bodies, OR + // 3) Don't show dynamic bodies + if ((!showStaticBody && body.isStatic) || (!showBody && !body.isStatic)) + { + continue; + } - return this; - }, + var lineColor = body.render.lineColor; + var lineOpacity = body.render.lineOpacity; + var lineThickness = body.render.lineThickness; + var fillColor = body.render.fillColor; + var fillOpacity = body.render.fillOpacity; - /** - * 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); + if (showSleeping && body.isSleeping) + { + if (body.isStatic) + { + lineOpacity *= staticBodySleepOpacity; + fillOpacity *= staticBodySleepOpacity; + } + else + { + lineColor = sleepLineColor; + fillColor = sleepFillColor; + } + } - return this; - }, + if (!renderFill) + { + fillColor = null; + } - /** - * 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); - }, + if (!renderLine) + { + lineColor = null; + } - /** - * 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); - }, + this.renderBody(body, graphics, showInternalEdges, lineColor, lineOpacity, lineThickness, fillColor, fillOpacity); - /** - * 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); + var partsLength = body.parts.length; + + if (showConvexHulls && partsLength > 1) + { + this.renderConvexHull(body, graphics, hullColor, lineThickness); + } + } }, /** - * 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: + * Renders a single Matter Body to the given Phaser Graphics Game Object. * - * [ - * { 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 - * ] + * This method is used internally by the Matter Debug Renderer, but is also exposed publically should + * you wish to render a Body to your own Graphics instance. * - * 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. + * If you don't wish to render a line around the body, set the `lineColor` parameter to `null`. + * Equally, if you don't wish to render a fill, set the `fillColor` parameter to `null`. * - * @method Phaser.Tilemaps.TilemapLayer#weightedRandomize - * @since 3.50.0 + * @method Phaser.Physics.Matter.World#renderBody + * @since 3.22.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 {MatterJS.BodyType} body - The Matter Body to be rendered. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. + * @param {boolean} showInternalEdges - Render internal edges of the polygon? + * @param {number} [lineColor] - The line color. + * @param {number} [lineOpacity] - The line opacity, between 0 and 1. + * @param {number} [lineThickness=1] - The line thickness. + * @param {number} [fillColor] - The fill color. + * @param {number} [fillOpacity] - The fill opacity, between 0 and 1. * - * @return {this} This Tilemap Layer object. + * @return {this} This Matter World instance for method chaining. */ - weightedRandomize: function (weightedIndexes, tileX, tileY, width, height) + renderBody: function (body, graphics, showInternalEdges, lineColor, lineOpacity, lineThickness, fillColor, fillOpacity) { - TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, this.layer); + if (lineColor === undefined) { lineColor = null; } + if (lineOpacity === undefined) { lineOpacity = null; } + if (lineThickness === undefined) { lineThickness = 1; } + if (fillColor === undefined) { fillColor = null; } + if (fillOpacity === undefined) { fillOpacity = null; } + + var config = this.debugConfig; + + var sensorFillColor = config.sensorFillColor; + var sensorLineColor = config.sensorLineColor; + + // Handle compound parts + var parts = body.parts; + var partsLength = parts.length; + + for (var k = (partsLength > 1) ? 1 : 0; k < partsLength; k++) + { + var part = parts[k]; + var render = part.render; + var opacity = render.opacity; + + if (!render.visible || opacity === 0 || (part.isSensor && !config.showSensors)) + { + continue; + } + + // Part polygon + var circleRadius = part.circleRadius; + + graphics.beginPath(); + + if (part.isSensor) + { + if (fillColor !== null) + { + graphics.fillStyle(sensorFillColor, fillOpacity * opacity); + } + + if (lineColor !== null) + { + graphics.lineStyle(lineThickness, sensorLineColor, lineOpacity * opacity); + } + } + else + { + if (fillColor !== null) + { + graphics.fillStyle(fillColor, fillOpacity * opacity); + } + + if (lineColor !== null) + { + graphics.lineStyle(lineThickness, lineColor, lineOpacity * opacity); + } + } + + if (circleRadius) + { + graphics.arc(part.position.x, part.position.y, circleRadius, 0, 2 * Math.PI); + } + else + { + var vertices = part.vertices; + var vertLength = vertices.length; + + graphics.moveTo(vertices[0].x, vertices[0].y); + + for (var j = 1; j < vertLength; j++) + { + var vert = vertices[j]; + + if (!vertices[j - 1].isInternal || showInternalEdges) + { + graphics.lineTo(vert.x, vert.y); + } + else + { + graphics.moveTo(vert.x, vert.y); + } + + if (j < vertLength && vert.isInternal && !showInternalEdges) + { + var nextIndex = (j + 1) % vertLength; + + graphics.moveTo(vertices[nextIndex].x, vertices[nextIndex].y); + } + } + + graphics.closePath(); + } + + if (fillColor !== null) + { + graphics.fillPath(); + } + + if (lineColor !== null) + { + graphics.strokePath(); + } + } + + if (config.showPositions && !body.isStatic) + { + var px = body.position.x; + var py = body.position.y; + var hs = Math.ceil(config.positionSize / 2); + + graphics.fillStyle(config.positionColor, 1); + graphics.fillRect(px - hs, py - hs, config.positionSize, config.positionSize); + } return this; }, /** - * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the - * layers position, scale and scroll. + * Renders the Convex Hull for a single Matter Body to the given Phaser Graphics Game Object. * - * @method Phaser.Tilemaps.TilemapLayer#worldToTileX - * @since 3.50.0 + * This method is used internally by the Matter Debug Renderer, but is also exposed publically should + * you wish to render a Body hull to your own Graphics instance. * - * @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. + * @method Phaser.Physics.Matter.World#renderConvexHull + * @since 3.22.0 * - * @return {number} The tile X coordinate based on the world value. + * @param {MatterJS.BodyType} body - The Matter Body to be rendered. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. + * @param {number} hullColor - The color used to render the hull. + * @param {number} [lineThickness=1] - The hull line thickness. + * + * @return {this} This Matter World instance for method chaining. */ - worldToTileX: function (worldX, snapToFloor, camera) + renderConvexHull: function (body, graphics, hullColor, lineThickness) { - return this.tilemap.worldToTileX(worldX, snapToFloor, camera, this); + if (lineThickness === undefined) { lineThickness = 1; } + + var parts = body.parts; + var partsLength = parts.length; + + // Render Convex Hulls + if (partsLength > 1) + { + var verts = body.vertices; + + graphics.lineStyle(lineThickness, hullColor); + + graphics.beginPath(); + + graphics.moveTo(verts[0].x, verts[0].y); + + for (var v = 1; v < verts.length; v++) + { + graphics.lineTo(verts[v].x, verts[v].y); + } + + graphics.lineTo(verts[0].x, verts[0].y); + + graphics.strokePath(); + } + + return 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 + * Renders all of the constraints in the world (unless they are specifically set to invisible). * - * @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. + * Called automatically by the `postUpdate` method. * - * @return {number} The tile Y coordinate based on the world value. + * @method Phaser.Physics.Matter.World#renderJoints + * @private + * @since 3.14.0 */ - worldToTileY: function (worldY, snapToFloor, camera) + renderJoints: function () { - return this.tilemap.worldToTileY(worldY, snapToFloor, camera, this); + var graphics = this.debugGraphic; + + // Render constraints + var constraints = Composite.allConstraints(this.localWorld); + + for (var i = 0; i < constraints.length; i++) + { + var config = constraints[i].render; + + var lineColor = config.lineColor; + var lineOpacity = config.lineOpacity; + var lineThickness = config.lineThickness; + var pinSize = config.pinSize; + var anchorColor = config.anchorColor; + var anchorSize = config.anchorSize; + + this.renderConstraint(constraints[i], graphics, lineColor, lineOpacity, lineThickness, pinSize, anchorColor, anchorSize); + } }, /** - * 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 + * Renders a single Matter Constraint, such as a Pin or a Spring, to the given Phaser Graphics Game Object. * - * @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. + * This method is used internally by the Matter Debug Renderer, but is also exposed publically should + * you wish to render a Constraint to your own Graphics instance. * - * @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.Physics.Matter.World#renderConstraint + * @since 3.22.0 * - * @method Phaser.Tilemaps.TilemapLayer#destroy - * @since 3.50.0 + * @param {MatterJS.ConstraintType} constraint - The Matter Constraint to render. + * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. + * @param {number} lineColor - The line color. + * @param {number} lineOpacity - The line opacity, between 0 and 1. + * @param {number} lineThickness - The line thickness. + * @param {number} pinSize - If this constraint is a pin, this sets the size of the pin circle. + * @param {number} anchorColor - The color used when rendering this constraints anchors. Set to `null` to not render anchors. + * @param {number} anchorSize - The size of the anchor circle, if this constraint has anchors and is rendering them. * - * @param {boolean} [removeFromTilemap=true] - Remove this layer from the parent Tilemap? + * @return {this} This Matter World instance for method chaining. */ - destroy: function (removeFromTilemap) + renderConstraint: function (constraint, graphics, lineColor, lineOpacity, lineThickness, pinSize, anchorColor, anchorSize) { - if (removeFromTilemap === undefined) { removeFromTilemap = true; } + var render = constraint.render; - if (!this.tilemap) + if (!render.visible || !constraint.pointA || !constraint.pointB) { - // Abort, we've already been destroyed - return; + return this; } - // Uninstall this layer only if it is still installed on the LayerData object - if (this.layer.tilemapLayer === this) + graphics.lineStyle(lineThickness, lineColor, lineOpacity); + + var bodyA = constraint.bodyA; + var bodyB = constraint.bodyB; + var start; + var end; + + if (bodyA) { - this.layer.tilemapLayer = undefined; + start = Vector.add(bodyA.position, constraint.pointA); } - - if (removeFromTilemap) + else { - this.tilemap.removeLayer(this); + start = constraint.pointA; } - this.tilemap = undefined; - this.layer = undefined; - this.culledTiles.length = 0; - this.cullCallback = null; + if (render.type === 'pin') + { + graphics.strokeCircle(start.x, start.y, pinSize); + } + else + { + if (bodyB) + { + end = Vector.add(bodyB.position, constraint.pointB); + } + else + { + end = constraint.pointB; + } - this.gidMap = []; - this.tileset = []; + graphics.beginPath(); + graphics.moveTo(start.x, start.y); - GameObject.prototype.destroy.call(this); - } + if (render.type === 'spring') + { + var delta = Vector.sub(end, start); + var normal = Vector.perp(Vector.normalise(delta)); + var coils = Math.ceil(Common.clamp(constraint.length / 5, 12, 20)); + var offset; -}); + for (var j = 1; j < coils; j += 1) + { + offset = (j % 2 === 0) ? 1 : -1; -module.exports = TilemapLayer; + graphics.lineTo( + start.x + delta.x * (j / coils) + normal.x * offset * 4, + start.y + delta.y * (j / coils) + normal.y * offset * 4 + ); + } + } + graphics.lineTo(end.x, end.y); + } -/***/ }), -/* 582 */ -/***/ (function(module, exports, __webpack_require__) { + graphics.strokePath(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (render.anchors && anchorSize > 0) + { + graphics.fillStyle(anchorColor); + graphics.fillCircle(start.x, start.y, anchorSize); + graphics.fillCircle(end.x, end.y, anchorSize); + } -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); + return this; + }, -/** - * @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({ + /** + * Resets the internal collision IDs that Matter.JS uses for Body collision groups. + * + * You should call this before destroying your game if you need to restart the game + * again on the same page, without first reloading the page. Or, if you wish to + * consistently destroy a Scene that contains Matter.js and then run it again + * later in the same game. + * + * @method Phaser.Physics.Matter.World#resetCollisionIDs + * @since 3.17.0 + */ + resetCollisionIDs: function () + { + Body._nextCollidingGroupId = 1; + Body._nextNonCollidingGroupId = -1; + Body._nextCategory = 0x0001; - initialize: + return this; + }, - function TimerEvent (config) + /** + * Will remove all Matter physics event listeners and clear the matter physics world, + * engine and any debug graphics, if any. + * + * @method Phaser.Physics.Matter.World#shutdown + * @since 3.0.0 + */ + shutdown: function () { - /** - * 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; + MatterEvents.off(this.engine); - /** - * 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; + this.removeAllListeners(); - /** - * If repeating this contains the current repeat count. - * - * @name Phaser.Time.TimerEvent#repeatCount - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.repeatCount = 0; + MatterWorld.clear(this.localWorld, false); - /** - * True if this TimerEvent loops, otherwise false. - * - * @name Phaser.Time.TimerEvent#loop - * @type {boolean} - * @default false - * @readonly - * @since 3.0.0 - */ - this.loop = false; + Engine.clear(this.engine); - /** - * The callback that will be called when the TimerEvent occurs. - * - * @name Phaser.Time.TimerEvent#callback - * @type {function} - * @since 3.0.0 - */ - this.callback; + if (this.drawDebug) + { + this.debugGraphic.destroy(); + } + }, - /** - * The scope in which the callback will be called. - * - * @name Phaser.Time.TimerEvent#callbackScope - * @type {object} - * @since 3.0.0 - */ - this.callbackScope; + /** + * Will remove all Matter physics event listeners and clear the matter physics world, + * engine and any debug graphics, if any. + * + * After destroying the world it cannot be re-used again. + * + * @method Phaser.Physics.Matter.World#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.shutdown(); + } - /** - * 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; +module.exports = World; - /** - * 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; +/***/ 95349: +/***/ ((module) => { - /** - * 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; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.reset(config); - }, +/** + * A component to set restitution on objects. + * + * @namespace Phaser.Physics.Matter.Components.Bounce + * @since 3.0.0 + */ +var Bounce = { /** - * Completely reinitializes the Timer Event, regardless of its current state, according to a configuration object. + * Sets the restitution on the physics object. * - * @method Phaser.Time.TimerEvent#reset + * @method Phaser.Physics.Matter.Components.Bounce#setBounce * @since 3.0.0 * - * @param {Phaser.Types.Time.TimerEventConfig} config - The new state for the Timer Event. + * @param {number} value - A Number that defines the restitution (elasticity) of the body. The value is always positive and is in the range (0, 1). A value of 0 means collisions may be perfectly inelastic and no bouncing may occur. A value of 0.8 means the body may bounce back with approximately 80% of its kinetic energy. Note that collision response is based on pairs of bodies, and that restitution values are combined with the following formula: `Math.max(bodyA.restitution, bodyB.restitution)` * - * @return {Phaser.Time.TimerEvent} This TimerEvent object. + * @return {this} This Game Object instance. */ - reset: function (config) + setBounce: function (value) { - this.delay = GetFastValue(config, 'delay', 0); + this.body.restitution = value; - // Can also be set to -1 for an infinite loop (same as setting loop: true) - this.repeat = GetFastValue(config, 'repeat', 0); + return this; + } - this.loop = GetFastValue(config, 'loop', false); +}; - this.callback = GetFastValue(config, 'callback', undefined); +module.exports = Bounce; - this.callbackScope = GetFastValue(config, 'callbackScope', this.callback); - this.args = GetFastValue(config, 'args', []); +/***/ }), - this.timeScale = GetFastValue(config, 'timeScale', 1); +/***/ 70679: +/***/ ((module) => { - this.startAt = GetFastValue(config, 'startAt', 0); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.paused = GetFastValue(config, 'paused', false); +/** + * Contains methods for changing the collision filter of a Matter Body. Should be used as a mixin and not called directly. + * + * @namespace Phaser.Physics.Matter.Components.Collision + * @since 3.0.0 + */ +var Collision = { - this.elapsed = this.startAt; - this.hasDispatched = false; - this.repeatCount = (this.repeat === -1 || this.loop) ? 999999999999 : this.repeat; + /** + * Sets the collision category of this Game Object's Matter Body. This number must be a power of two between 2^0 (= 1) and 2^31. + * Two bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision + * categories are included in their collision masks (see {@link #setCollidesWith}). + * + * @method Phaser.Physics.Matter.Components.Collision#setCollisionCategory + * @since 3.0.0 + * + * @param {number} value - Unique category bitfield. + * + * @return {this} This Game Object instance. + */ + setCollisionCategory: function (value) + { + this.body.collisionFilter.category = value; return this; }, /** - * Gets the progress of the current iteration, not factoring in repeats. + * Sets the collision group of this Game Object's Matter Body. If this is zero or two Matter Bodies have different values, + * they will collide according to the usual rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}). + * If two Matter Bodies have the same positive value, they will always collide; if they have the same negative value, + * they will never collide. * - * @method Phaser.Time.TimerEvent#getProgress + * @method Phaser.Physics.Matter.Components.Collision#setCollisionGroup * @since 3.0.0 * - * @return {number} A number between 0 and 1 representing the current progress. + * @param {number} value - Unique group index. + * + * @return {this} This Game Object instance. */ - getProgress: function () + setCollisionGroup: function (value) { - return (this.elapsed / this.delay); + this.body.collisionFilter.group = value; + + return this; }, /** - * Gets the progress of the timer overall, factoring in repeats. + * Sets the collision mask for this Game Object's Matter Body. Two Matter Bodies with different collision groups will only + * collide if each one includes the other's category in its mask based on a bitwise AND, i.e. `(categoryA & maskB) !== 0` + * and `(categoryB & maskA) !== 0` are both true. * - * @method Phaser.Time.TimerEvent#getOverallProgress + * @method Phaser.Physics.Matter.Components.Collision#setCollidesWith * @since 3.0.0 * - * @return {number} The overall progress of the Timer Event, between 0 and 1. + * @param {(number|number[])} categories - A unique category bitfield, or an array of them. + * + * @return {this} This Game Object instance. */ - getOverallProgress: function () + setCollidesWith: function (categories) { - if (this.repeat > 0) - { - var totalDuration = this.delay + (this.delay * this.repeat); - var totalElapsed = this.elapsed + (this.delay * (this.repeat - this.repeatCount)); + var flags = 0; - return (totalElapsed / totalDuration); + if (!Array.isArray(categories)) + { + flags = categories; } else { - return this.getProgress(); + for (var i = 0; i < categories.length; i++) + { + flags |= categories[i]; + } } + + this.body.collisionFilter.mask = flags; + + return this; }, /** - * Returns the number of times this Timer Event will repeat before finishing. + * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. * - * 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. + * This does not change the bodies collision category, group or filter. Those must be set in addition + * to the callback. * - * @method Phaser.Time.TimerEvent#getRepeatCount - * @since 3.0.0 + * @method Phaser.Physics.Matter.Components.Collision#setOnCollide + * @since 3.22.0 * - * @return {number} How many times the Timer Event will repeat. + * @param {function} callback - The callback to invoke when this body starts colliding with another. + * + * @return {this} This Game Object instance. */ - getRepeatCount: function () + setOnCollide: function (callback) { - return this.repeatCount; + this.body.onCollideCallback = callback; + + return this; }, /** - * Returns the local elapsed time for the current iteration of the Timer Event. + * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. * - * @method Phaser.Time.TimerEvent#getElapsed - * @since 3.0.0 + * This does not change the bodies collision category, group or filter. Those must be set in addition + * to the callback. * - * @return {number} The local elapsed time in milliseconds. + * @method Phaser.Physics.Matter.Components.Collision#setOnCollideEnd + * @since 3.22.0 + * + * @param {function} callback - The callback to invoke when this body stops colliding with another. + * + * @return {this} This Game Object instance. */ - getElapsed: function () + setOnCollideEnd: function (callback) { - return this.elapsed; + this.body.onCollideEndCallback = callback; + + return this; }, /** - * Returns the local elapsed time for the current iteration of the Timer Event in seconds. + * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. * - * @method Phaser.Time.TimerEvent#getElapsedSeconds - * @since 3.0.0 + * This does not change the bodies collision category, group or filter. Those must be set in addition + * to the callback. * - * @return {number} The local elapsed time in seconds. + * @method Phaser.Physics.Matter.Components.Collision#setOnCollideActive + * @since 3.22.0 + * + * @param {function} callback - The callback to invoke for the duration of this body colliding with another. + * + * @return {this} This Game Object instance. */ - getElapsedSeconds: function () + setOnCollideActive: function (callback) { - return this.elapsed * 0.001; + this.body.onCollideActiveCallback = callback; + + return this; }, /** - * Returns the time interval until the next iteration of the Timer Event. + * The callback is sent a reference to the other body, along with a `Phaser.Types.Physics.Matter.MatterCollisionData` object. * - * @method Phaser.Time.TimerEvent#getRemaining - * @since 3.50.0 + * This does not change the bodies collision category, group or filter. Those must be set in addition + * to the callback. * - * @return {number} The time interval in milliseconds. + * @method Phaser.Physics.Matter.Components.Collision#setOnCollideWith + * @since 3.22.0 + * + * @param {(MatterJS.Body|MatterJS.Body[])} body - The body, or an array of bodies, to test for collisions with. + * @param {function} callback - The callback to invoke when this body collides with the given body or bodies. + * + * @return {this} This Game Object instance. */ - getRemaining: function () + setOnCollideWith: function (body, callback) { - return this.delay - this.elapsed; + if (!Array.isArray(body)) + { + body = [ body ]; + } + + for (var i = 0; i < body.length; i++) + { + var src = (body[i].hasOwnProperty('body')) ? body[i].body : body[i]; + + this.body.setOnCollideWith(src, callback); + } + + return this; + } + +}; + +module.exports = Collision; + + +/***/ }), + +/***/ 77178: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Body = __webpack_require__(84125); + +/** + * A component to apply force to Matter.js bodies. + * + * @namespace Phaser.Physics.Matter.Components.Force + * @since 3.0.0 + */ +var Force = { + + // force = vec2 / point + + /** + * Applies a force to a body. + * + * @method Phaser.Physics.Matter.Components.Force#applyForce + * @since 3.0.0 + * + * @param {Phaser.Math.Vector2} force - A Vector that specifies the force to apply. + * + * @return {this} This Game Object instance. + */ + applyForce: function (force) + { + this._tempVec2.set(this.body.position.x, this.body.position.y); + + Body.applyForce(this.body, this._tempVec2, force); + + return this; }, /** - * Returns the time interval until the next iteration of the Timer Event in seconds. + * Applies a force to a body from a given position. * - * @method Phaser.Time.TimerEvent#getRemainingSeconds - * @since 3.50.0 + * @method Phaser.Physics.Matter.Components.Force#applyForceFrom + * @since 3.0.0 * - * @return {number} The time interval in seconds. + * @param {Phaser.Math.Vector2} position - The position in which the force comes from. + * @param {Phaser.Math.Vector2} force - A Vector that specifies the force to apply. + * + * @return {this} This Game Object instance. */ - getRemainingSeconds: function () + applyForceFrom: function (position, force) { - return this.getRemaining() * 0.001; + Body.applyForce(this.body, position, force); + + return this; }, /** - * Returns the time interval until the last iteration of the Timer Event. + * Apply thrust to the forward position of the body. * - * @method Phaser.Time.TimerEvent#getOverallRemaining - * @since 3.50.0 + * Use very small values, such as 0.1, depending on the mass and required speed. * - * @return {number} The time interval in milliseconds. + * @method Phaser.Physics.Matter.Components.Force#thrust + * @since 3.0.0 + * + * @param {number} speed - A speed value to be applied to a directional force. + * + * @return {this} This Game Object instance. */ - getOverallRemaining: function () + thrust: function (speed) { - return this.delay * (1 + this.repeatCount) - this.elapsed; + var angle = this.body.angle; + + this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle)); + + Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2); + + return this; }, /** - * Returns the time interval until the last iteration of the Timer Event in seconds. + * Apply thrust to the left position of the body. * - * @method Phaser.Time.TimerEvent#getOverallRemainingSeconds - * @since 3.50.0 + * Use very small values, such as 0.1, depending on the mass and required speed. * - * @return {number} The time interval in seconds. + * @method Phaser.Physics.Matter.Components.Force#thrustLeft + * @since 3.0.0 + * + * @param {number} speed - A speed value to be applied to a directional force. + * + * @return {this} This Game Object instance. */ - getOverallRemainingSeconds: function () + thrustLeft: function (speed) { - return this.getOverallRemaining() * 0.001; + var angle = this.body.angle - Math.PI / 2; + + this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle)); + + Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2); + + return this; }, /** - * Forces the Timer Event to immediately expire, thus scheduling its removal in the next frame. + * Apply thrust to the right position of the body. * - * @method Phaser.Time.TimerEvent#remove + * Use very small values, such as 0.1, depending on the mass and required speed. + * + * @method Phaser.Physics.Matter.Components.Force#thrustRight * @since 3.0.0 * - * @param {boolean} [dispatchCallback=false] - If `true`, the function of the Timer Event will be called before its removal. + * @param {number} speed - A speed value to be applied to a directional force. + * + * @return {this} This Game Object instance. */ - remove: function (dispatchCallback) + thrustRight: function (speed) { - if (dispatchCallback === undefined) { dispatchCallback = false; } + var angle = this.body.angle + Math.PI / 2; - this.elapsed = this.delay; + this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle)); - this.hasDispatched = !dispatchCallback; + Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2); - this.repeatCount = 0; + return this; }, /** - * Destroys all object references in the Timer Event, i.e. its callback, scope, and arguments. + * Apply thrust to the back position of the body. * - * 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. + * Use very small values, such as 0.1, depending on the mass and required speed. * - * @method Phaser.Time.TimerEvent#destroy + * @method Phaser.Physics.Matter.Components.Force#thrustBack * @since 3.0.0 + * + * @param {number} speed - A speed value to be applied to a directional force. + * + * @return {this} This Game Object instance. */ - destroy: function () + thrustBack: function (speed) { - this.callback = undefined; - this.callbackScope = undefined; - this.args = []; + var angle = this.body.angle - Math.PI; + + this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle)); + + Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2); + + return this; } -}); +}; -module.exports = TimerEvent; +module.exports = Force; /***/ }), -/* 583 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 74015: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RESERVED = __webpack_require__(1465); - /** - * 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. + * Contains methods for changing the friction of a Game Object's Matter Body. Should be used a mixin, not called directly. * - * @function Phaser.Tweens.Builders.GetProps + * @namespace Phaser.Physics.Matter.Components.Friction * @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 +var Friction = { - if (config.hasOwnProperty('props')) + /** + * Sets new friction values for this Game Object's Matter Body. + * + * @method Phaser.Physics.Matter.Components.Friction#setFriction + * @since 3.0.0 + * + * @param {number} value - The new friction of the body, between 0 and 1, where 0 allows the Body to slide indefinitely, while 1 allows it to stop almost immediately after a force is applied. + * @param {number} [air] - If provided, the new air resistance of the Body. The higher the value, the faster the Body will slow as it moves through space. 0 means the body has no air resistance. + * @param {number} [fstatic] - If provided, the new static friction of the Body. The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. 0 means the body will never "stick" when it is nearly stationary. + * + * @return {this} This Game Object instance. + */ + setFriction: function (value, air, fstatic) { - for (key in config.props) + this.body.friction = value; + + if (air !== undefined) { - // Skip any property that starts with an underscore - if (key.substr(0, 1) !== '_') - { - keys.push({ key: key, value: config.props[key] }); - } + this.body.frictionAir = air; } - } - else - { - for (key in config) + + if (fstatic !== undefined) { - // 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] }); - } + this.body.frictionStatic = fstatic; } + + return this; + }, + + /** + * Sets a new air resistance for this Game Object's Matter Body. + * A value of 0 means the Body will never slow as it moves through space. + * The higher the value, the faster a Body slows when moving through space. + * + * @method Phaser.Physics.Matter.Components.Friction#setFrictionAir + * @since 3.0.0 + * + * @param {number} value - The new air resistance for the Body. + * + * @return {this} This Game Object instance. + */ + setFrictionAir: function (value) + { + this.body.frictionAir = value; + + return this; + }, + + /** + * Sets a new static friction for this Game Object's Matter Body. + * A value of 0 means the Body will never "stick" when it is nearly stationary. + * The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. + * + * @method Phaser.Physics.Matter.Components.Friction#setFrictionStatic + * @since 3.0.0 + * + * @param {number} value - The new static friction for the Body. + * + * @return {this} This Game Object instance. + */ + setFrictionStatic: function (value) + { + this.body.frictionStatic = value; + + return this; } - return keys; }; -module.exports = GetProps; +module.exports = Friction; /***/ }), -/* 584 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 11535: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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. + * A component to manipulate world gravity for Matter.js bodies. * - * @function Phaser.Tweens.Builders.GetTweens + * @namespace Phaser.Physics.Matter.Components.Gravity * @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); +var Gravity = { - if (tweens === null) - { - return []; - } - else if (typeof tweens === 'function') + /** + * A togglable function for ignoring world gravity in real-time on the current body. + * + * @method Phaser.Physics.Matter.Components.Gravity#setIgnoreGravity + * @since 3.0.0 + * + * @param {boolean} value - Set to true to ignore the effect of world gravity, or false to not ignore it. + * + * @return {this} This Game Object instance. + */ + setIgnoreGravity: function (value) { - tweens = tweens.call(); - } + this.body.ignoreGravity = value; - if (!Array.isArray(tweens)) - { - tweens = [ tweens ]; + return this; } - return tweens; }; -module.exports = GetTweens; +module.exports = Gravity; /***/ }), -/* 585 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 74497: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Defaults = __webpack_require__(265); -var GetAdvancedValue = __webpack_require__(13); -var GetBoolean = __webpack_require__(99); -var GetEaseFunction = __webpack_require__(80); -var GetNewValue = __webpack_require__(162); -var GetValue = __webpack_require__(6); -var GetValueOp = __webpack_require__(264); -var Tween = __webpack_require__(266); -var TweenData = __webpack_require__(268); +var Body = __webpack_require__(84125); +var Vector2 = __webpack_require__(93736); /** - * Creates a new Number Tween. + * Allows accessing the mass, density, and center of mass of a Matter-enabled Game Object. Should be used as a mixin and not directly. * - * @function Phaser.Tweens.Builders.NumberTweenBuilder + * @namespace Phaser.Physics.Matter.Components.Mass * @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 Mass = { - var from = GetValue(config, 'from', 0); - var to = GetValue(config, 'to', 1); + /** + * Sets the mass of the Game Object's Matter Body. + * + * @method Phaser.Physics.Matter.Components.Mass#setMass + * @since 3.0.0 + * + * @param {number} value - The new mass of the body. + * + * @return {this} This Game Object instance. + */ + setMass: function (value) + { + Body.setMass(this.body, value); - var targets = [ { value: from } ]; + return this; + }, - 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); + /** + * Sets density of the body. + * + * @method Phaser.Physics.Matter.Components.Mass#setDensity + * @since 3.0.0 + * + * @param {number} value - The new density of the body. + * + * @return {this} This Game Object instance. + */ + setDensity: function (value) + { + Body.setDensity(this.body, value); - var data = []; + return this; + }, - var ops = GetValueOp('value', to); + /** + * The body's center of mass. + * + * Calling this creates a new `Vector2 each time to avoid mutation. + * + * If you only need to read the value and won't change it, you can get it from `GameObject.body.centerOfMass`. + * + * @name Phaser.Physics.Matter.Components.Mass#centerOfMass + * @type {Phaser.Math.Vector2} + * @readonly + * @since 3.10.0 + * + * @return {Phaser.Math.Vector2} The center of mass. + */ + centerOfMass: { - var tweenData = TweenData( - targets[0], - 0, - 'value', - ops.getEnd, - ops.getStart, - ops.getActive, - ease, - delay, - duration, - yoyo, - hold, - repeat, - repeatDelay, - false, - false - ); + get: function () + { + return new Vector2(this.body.centerOfMass.x, this.body.centerOfMass.y); + } + } - tweenData.start = from; - tweenData.current = from; - tweenData.to = to; +}; - data.push(tweenData); +module.exports = Mass; - 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); +/***/ 75529: +/***/ ((module) => { - // Callback parameters: 0 = a reference to the Tween itself, 1 = the target/s of the Tween, ... your own params - var tweenArray = [ tween, null ]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var callbacks = Tween.TYPES; +/** + * Enables a Matter-enabled Game Object to be a sensor. Should be used as a mixin and not directly. + * + * @namespace Phaser.Physics.Matter.Components.Sensor + * @since 3.0.0 + */ +var Sensor = { - for (var i = 0; i < callbacks.length; i++) + /** + * Set the body belonging to this Game Object to be a sensor. + * Sensors trigger collision events, but don't react with colliding body physically. + * + * @method Phaser.Physics.Matter.Components.Sensor#setSensor + * @since 3.0.0 + * + * @param {boolean} value - `true` to set the body as a sensor, or `false` to disable it. + * + * @return {this} This Game Object instance. + */ + setSensor: function (value) { - var type = callbacks[i]; - - var callback = GetValue(config, type, false); + this.body.isSensor = value; - if (callback) - { - var callbackScope = GetValue(config, type + 'Scope', scope); - var callbackParams = GetValue(config, type + 'Params', []); + return this; + }, - // The null is reset to be the Tween target - tween.setCallback(type, callback, tweenArray.concat(callbackParams), callbackScope); - } + /** + * Is the body belonging to this Game Object a sensor or not? + * + * @method Phaser.Physics.Matter.Components.Sensor#isSensor + * @since 3.0.0 + * + * @return {boolean} `true` if the body is a sensor, otherwise `false`. + */ + isSensor: function () + { + return this.body.isSensor; } - return tween; }; -module.exports = NumberTweenBuilder; +module.exports = Sensor; /***/ }), -/* 586 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 64024: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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); +var Bodies = __webpack_require__(68516); +var Body = __webpack_require__(84125); +var FuzzyEquals = __webpack_require__(88456); +var GetFastValue = __webpack_require__(72632); +var PhysicsEditorParser = __webpack_require__(10998); +var PhysicsJSONParser = __webpack_require__(72829); +var Vertices = __webpack_require__(39745); /** - * 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. + * Enables a Matter-enabled Game Object to set its Body. Should be used as a mixin and not directly. * - * @return {function} The stagger function. + * @namespace Phaser.Physics.Matter.Components.SetBody + * @since 3.0.0 */ -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); +var SetBody = { - if (isRange) + /** + * Set the body on a Game Object to a rectangle. + * + * Calling this methods resets previous properties you may have set on the body, including + * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. + * + * @method Phaser.Physics.Matter.Components.SetBody#setRectangle + * @since 3.0.0 + * + * @param {number} width - Width of the rectangle. + * @param {number} height - Height of the rectangle. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {this} This Game Object instance. + */ + setRectangle: function (width, height, options) { - start += value1; - } + return this.setBody({ type: 'rectangle', width: width, height: height }, options); + }, - if (grid) + /** + * Set the body on a Game Object to a circle. + * + * Calling this methods resets previous properties you may have set on the body, including + * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. + * + * @method Phaser.Physics.Matter.Components.SetBody#setCircle + * @since 3.0.0 + * + * @param {number} radius - The radius of the circle. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {this} This Game Object instance. + */ + setCircle: function (radius, options) { - // Pre-calc the grid to save doing it for ever tweendata update - var gridWidth = grid[0]; - var gridHeight = grid[1]; + return this.setBody({ type: 'circle', radius: radius }, options); + }, - var fromX = 0; - var fromY = 0; + /** + * Set the body on the Game Object to a polygon shape. + * + * Calling this methods resets previous properties you may have set on the body, including + * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. + * + * @method Phaser.Physics.Matter.Components.SetBody#setPolygon + * @since 3.0.0 + * + * @param {number} radius - The "radius" of the polygon, i.e. the distance from its center to any vertex. This is also the radius of its circumcircle. + * @param {number} sides - The number of sides the polygon will have. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {this} This Game Object instance. + */ + setPolygon: function (radius, sides, options) + { + return this.setBody({ type: 'polygon', sides: sides, radius: radius }, options); + }, - var distanceX = 0; - var distanceY = 0; + /** + * Set the body on the Game Object to a trapezoid shape. + * + * Calling this methods resets previous properties you may have set on the body, including + * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. + * + * @method Phaser.Physics.Matter.Components.SetBody#setTrapezoid + * @since 3.0.0 + * + * @param {number} width - The width of the trapezoid Body. + * @param {number} height - The height of the trapezoid Body. + * @param {number} slope - The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {this} This Game Object instance. + */ + setTrapezoid: function (width, height, slope, options) + { + return this.setBody({ type: 'trapezoid', width: width, height: height, slope: slope }, options); + }, - var gridValues = []; + /** + * Set this Game Object to use the given existing Matter Body. + * + * The body is first removed from the world before being added to this Game Object. + * + * @method Phaser.Physics.Matter.Components.SetBody#setExistingBody + * @since 3.0.0 + * + * @param {MatterJS.BodyType} body - The Body this Game Object should use. + * @param {boolean} [addToWorld=true] - Should the body be immediately added to the World? + * + * @return {this} This Game Object instance. + */ + setExistingBody: function (body, addToWorld) + { + if (addToWorld === undefined) { addToWorld = true; } - if (fromLast) - { - fromX = gridWidth - 1; - fromY = gridHeight - 1; - } - else if (fromValue) + if (this.body) { - fromX = from % gridWidth; - fromY = Math.floor(from / gridWidth); + this.world.remove(this.body, true); } - else if (fromCenter) + + this.body = body; + + for (var i = 0; i < body.parts.length; i++) { - fromX = (gridWidth - 1) / 2; - fromY = (gridHeight - 1) / 2; + body.parts[i].gameObject = this; } - var gridMax = MATH_CONST.MIN_SAFE_INTEGER; + var _this = this; - for (var toY = 0; toY < gridHeight; toY++) + body.destroy = function destroy () { - gridValues[toY] = []; + _this.world.remove(_this.body, true); + _this.body.gameObject = null; + }; - for (var toX = 0; toX < gridWidth; toX++) + if (addToWorld) + { + if (this.world.has(body)) { - distanceX = fromX - toX; - distanceY = fromY - toY; - - var dist = Math.sqrt(distanceX * distanceX + distanceY * distanceY); - - if (dist > gridMax) - { - gridMax = dist; - } - - gridValues[toY][toX] = dist; + // Because it could be part of another Composite + this.world.remove(body, true); } - } - } - var easeFunction = (ease) ? GetEaseFunction(ease) : null; + this.world.add(body); + } - if (grid) - { - result = function (target, key, value, index) + if (this._originComponent) { - 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 rx = body.render.sprite.xOffset; + var ry = body.render.sprite.yOffset; - 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) + var comx = body.centerOfMass.x; + var comy = body.centerOfMass.y; + + if (FuzzyEquals(comx, 0.5) && FuzzyEquals(comy, 0.5)) { - output = (gridSpace * value1) * easeFunction(gridSpace / gridMax); + this.setOrigin(rx + 0.5, ry + 0.5); } else { - output = gridSpace * value1; + var cx = body.centerOffset.x; + var cy = body.centerOffset.y; + + this.setOrigin(rx + (cx / this.displayWidth), ry + (cy / this.displayHeight)); } + } - return output + start; - }; - } - else + return this; + }, + + /** + * Set this Game Object to create and use a new Body based on the configuration object given. + * + * Calling this method resets previous properties you may have set on the body, including + * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. + * + * @method Phaser.Physics.Matter.Components.SetBody#setBody + * @since 3.0.0 + * + * @param {(string|Phaser.Types.Physics.Matter.MatterSetBodyConfig)} config - Either a string, such as `circle`, or a Matter Set Body Configuration object. + * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * + * @return {this} This Game Object instance. + */ + setBody: function (config, options) { - result = function (target, key, value, index, total) + if (!config) { - // 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; + return this; + } - if (fromCenter) - { - spacing = ((value2 - value1) / total) * (fromIndex * 2); - } - else - { - spacing = ((value2 - value1) / total) * fromIndex; - } - - if (easeFunction) - { - output = spacing * easeFunction(fromIndex / total); - } - else + var body; + + // Allow them to do: shape: 'circle' instead of shape: { type: 'circle' } + if (typeof config === 'string') + { + // Using defaults + config = { type: config }; + } + + var shapeType = GetFastValue(config, 'type', 'rectangle'); + var bodyX = GetFastValue(config, 'x', this._tempVec2.x); + var bodyY = GetFastValue(config, 'y', this._tempVec2.y); + var bodyWidth = GetFastValue(config, 'width', this.width); + var bodyHeight = GetFastValue(config, 'height', this.height); + + switch (shapeType) + { + case 'rectangle': + body = Bodies.rectangle(bodyX, bodyY, bodyWidth, bodyHeight, options); + break; + + case 'circle': + var radius = GetFastValue(config, 'radius', Math.max(bodyWidth, bodyHeight) / 2); + var maxSides = GetFastValue(config, 'maxSides', 25); + body = Bodies.circle(bodyX, bodyY, radius, options, maxSides); + break; + + case 'trapezoid': + var slope = GetFastValue(config, 'slope', 0.5); + body = Bodies.trapezoid(bodyX, bodyY, bodyWidth, bodyHeight, slope, options); + break; + + case 'polygon': + var sides = GetFastValue(config, 'sides', 5); + var pRadius = GetFastValue(config, 'radius', Math.max(bodyWidth, bodyHeight) / 2); + body = Bodies.polygon(bodyX, bodyY, sides, pRadius, options); + break; + + case 'fromVertices': + case 'fromVerts': + + var verts = GetFastValue(config, 'verts', null); + + if (verts) { - output = spacing; + // Has the verts array come from Vertices.fromPath, or is it raw? + if (typeof verts === 'string') + { + verts = Vertices.fromPath(verts); + } + + if (this.body && !this.body.hasOwnProperty('temp')) + { + Body.setVertices(this.body, verts); + + body = this.body; + } + else + { + var flagInternal = GetFastValue(config, 'flagInternal', false); + var removeCollinear = GetFastValue(config, 'removeCollinear', 0.01); + var minimumArea = GetFastValue(config, 'minimumArea', 10); + + body = Bodies.fromVertices(bodyX, bodyY, verts, options, flagInternal, removeCollinear, minimumArea); + } } - } - else if (easeFunction) - { - output = (total * maxValue) * easeFunction(fromIndex / total); - } - else - { - output = fromIndex * value1; - } - - return output + start; - }; + + break; + + case 'fromPhysicsEditor': + body = PhysicsEditorParser.parseBody(bodyX, bodyY, config, options); + break; + + case 'fromPhysicsTracer': + body = PhysicsJSONParser.parseBody(bodyX, bodyY, config, options); + break; + } + + if (body) + { + this.setExistingBody(body, config.addToWorld); + } + + return this; } - return result; }; -module.exports = StaggerBuilder; +module.exports = SetBody; /***/ }), -/* 587 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 25106: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clone = __webpack_require__(77); -var Defaults = __webpack_require__(265); -var GetAdvancedValue = __webpack_require__(13); -var GetBoolean = __webpack_require__(99); -var GetEaseFunction = __webpack_require__(80); -var GetNewValue = __webpack_require__(162); -var GetTargets = __webpack_require__(263); -var GetTweens = __webpack_require__(584); -var GetValue = __webpack_require__(6); -var Timeline = __webpack_require__(588); -var TweenBuilder = __webpack_require__(163); +var Events = __webpack_require__(35416); +var Sleeping = __webpack_require__(22806); +var MatterEvents = __webpack_require__(39073); /** - * Builds a Timeline of Tweens based on a configuration object. + * Enables a Matter-enabled Game Object to be able to go to sleep. Should be used as a mixin and not directly. * - * @function Phaser.Tweens.Builders.TimelineBuilder + * @namespace Phaser.Physics.Matter.Components.Sleep * @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 Sleep = { - var timelineArray = [ timeline ]; + /** + * Sets this Body to sleep. + * + * @method Phaser.Physics.Matter.Components.Sleep#setToSleep + * @since 3.22.0 + * + * @return {this} This Game Object instance. + */ + setToSleep: function () + { + Sleeping.set(this.body, true); - var onStart = GetValue(config, 'onStart', false); + return this; + }, - // The Start of the Timeline - if (onStart) + /** + * Wakes this Body if asleep. + * + * @method Phaser.Physics.Matter.Components.Sleep#setAwake + * @since 3.22.0 + * + * @return {this} This Game Object instance. + */ + setAwake: function () { - var onStartScope = GetValue(config, 'onStartScope', scope); - var onStartParams = GetValue(config, 'onStartParams', []); - - timeline.setCallback('onStart', onStart, timelineArray.concat(onStartParams), onStartScope); - } + Sleeping.set(this.body, false); - var onUpdate = GetValue(config, 'onUpdate', false); + return this; + }, - // Every time the Timeline updates (regardless which Tweens are running) - if (onUpdate) + /** + * Sets the number of updates in which this body must have near-zero velocity before it is set as sleeping (if sleeping is enabled by the engine). + * + * @method Phaser.Physics.Matter.Components.Sleep#setSleepThreshold + * @since 3.0.0 + * + * @param {number} [value=60] - A `Number` that defines the number of updates in which this body must have near-zero velocity before it is set as sleeping. + * + * @return {this} This Game Object instance. + */ + setSleepThreshold: function (value) { - var onUpdateScope = GetValue(config, 'onUpdateScope', scope); - var onUpdateParams = GetValue(config, 'onUpdateParams', []); + if (value === undefined) { value = 60; } - timeline.setCallback('onUpdate', onUpdate, timelineArray.concat(onUpdateParams), onUpdateScope); - } + this.body.sleepThreshold = value; - var onLoop = GetValue(config, 'onLoop', false); + return this; + }, - // Called when the whole Timeline loops - if (onLoop) + /** + * Enable sleep and wake events for this body. + * + * By default when a body goes to sleep, or wakes up, it will not emit any events. + * + * The events are emitted by the Matter World instance and can be listened to via + * the `SLEEP_START` and `SLEEP_END` events. + * + * @method Phaser.Physics.Matter.Components.Sleep#setSleepEvents + * @since 3.0.0 + * + * @param {boolean} start - `true` if you want the sleep start event to be emitted for this body. + * @param {boolean} end - `true` if you want the sleep end event to be emitted for this body. + * + * @return {this} This Game Object instance. + */ + setSleepEvents: function (start, end) { - var onLoopScope = GetValue(config, 'onLoopScope', scope); - var onLoopParams = GetValue(config, 'onLoopParams', []); - - timeline.setCallback('onLoop', onLoop, timelineArray.concat(onLoopParams), onLoopScope); - } + this.setSleepStartEvent(start); + this.setSleepEndEvent(end); - var onYoyo = GetValue(config, 'onYoyo', false); + return this; + }, - // Called when a Timeline yoyos - if (onYoyo) + /** + * Enables or disables the Sleep Start event for this body. + * + * @method Phaser.Physics.Matter.Components.Sleep#setSleepStartEvent + * @since 3.0.0 + * + * @param {boolean} value - `true` to enable the sleep event, or `false` to disable it. + * + * @return {this} This Game Object instance. + */ + setSleepStartEvent: function (value) { - var onYoyoScope = GetValue(config, 'onYoyoScope', scope); - var onYoyoParams = GetValue(config, 'onYoyoParams', []); + if (value) + { + var world = this.world; - timeline.setCallback('onYoyo', onYoyo, timelineArray.concat(null, onYoyoParams), onYoyoScope); - } + MatterEvents.on(this.body, 'sleepStart', function (event) + { + world.emit(Events.SLEEP_START, event, this); + }); + } + else + { + MatterEvents.off(this.body, 'sleepStart'); + } - var onComplete = GetValue(config, 'onComplete', false); + return this; + }, - // Called when the Timeline completes, after the completeDelay, etc. - if (onComplete) + /** + * Enables or disables the Sleep End event for this body. + * + * @method Phaser.Physics.Matter.Components.Sleep#setSleepEndEvent + * @since 3.0.0 + * + * @param {boolean} value - `true` to enable the sleep event, or `false` to disable it. + * + * @return {this} This Game Object instance. + */ + setSleepEndEvent: function (value) { - var onCompleteScope = GetValue(config, 'onCompleteScope', scope); - var onCompleteParams = GetValue(config, 'onCompleteParams', []); + if (value) + { + var world = this.world; + + MatterEvents.on(this.body, 'sleepEnd', function (event) + { + world.emit(Events.SLEEP_END, event, this); + }); + } + else + { + MatterEvents.off(this.body, 'sleepEnd'); + } - timeline.setCallback('onComplete', onComplete, timelineArray.concat(onCompleteParams), onCompleteScope); + return this; } - // Tweens +}; - var tweens = GetTweens(config); +module.exports = Sleep; - if (tweens.length === 0) - { - timeline.paused = true; - return timeline; - } +/***/ }), - var defaults = Clone(Defaults); +/***/ 82884: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - defaults.targets = GetTargets(config); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // totalDuration: If specified each tween in the Timeline is given an equal portion of the totalDuration +var Body = __webpack_require__(84125); - var totalDuration = GetAdvancedValue(config, 'totalDuration', 0); +/** + * Provides methods used for getting and setting the static state of a physics body. + * + * @namespace Phaser.Physics.Matter.Components.Static + * @since 3.0.0 + */ +var Static = { - if (totalDuration > 0) - { - defaults.duration = Math.floor(totalDuration / tweens.length); - } - else + /** + * Changes the physics body to be either static `true` or dynamic `false`. + * + * @method Phaser.Physics.Matter.Components.Static#setStatic + * @since 3.0.0 + * + * @param {boolean} value - `true` to set the body as being static, or `false` to make it dynamic. + * + * @return {this} This Game Object instance. + */ + setStatic: function (value) { - defaults.duration = GetNewValue(config, 'duration', defaults.duration); - } + Body.setStatic(this.body, value); - 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); + return this; + }, - // Create the Tweens - for (var i = 0; i < tweens.length; i++) + /** + * Returns `true` if the body is static, otherwise `false` for a dynamic body. + * + * @method Phaser.Physics.Matter.Components.Static#isStatic + * @since 3.0.0 + * + * @return {boolean} `true` if the body is static, otherwise `false`. + */ + isStatic: function () { - timeline.queue(TweenBuilder(timeline, tweens[i], defaults)); + return this.body.isStatic; } - return timeline; }; -module.exports = TimelineBuilder; +module.exports = Static; /***/ }), -/* 588 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 4753: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(267); -var TweenBuilder = __webpack_require__(163); -var TWEEN_CONST = __webpack_require__(100); +var Body = __webpack_require__(84125); +var MATH_CONST = __webpack_require__(83392); +var WrapAngle = __webpack_require__(35786); +var WrapAngleDegrees = __webpack_require__(62138); + +// global bitmask flag for GameObject.renderMask (used by Scale) +var _FLAG = 4; // 0100 + +// Transform Component /** - * @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. + * Provides methods used for getting and setting the position, scale and rotation of a Game Object. * - * @class Timeline - * @memberof Phaser.Tweens - * @extends Phaser.Events.EventEmitter - * @constructor + * @namespace Phaser.Physics.Matter.Components.Transform * @since 3.0.0 - * - * @param {Phaser.Tweens.TweenManager} manager - The Tween Manager which owns this Timeline. */ -var Timeline = new Class({ +var Transform = { - Extends: EventEmitter, + /** + * The x position of this Game Object. + * + * @name Phaser.Physics.Matter.Components.Transform#x + * @type {number} + * @since 3.0.0 + */ + x: { - initialize: + get: function () + { + return this.body.position.x; + }, - function Timeline (manager) - { - EventEmitter.call(this); + set: function (value) + { + this._tempVec2.set(value, this.y); - /** - * The Tween Manager which owns this Timeline. - * - * @name Phaser.Tweens.Timeline#manager - * @type {Phaser.Tweens.TweenManager} - * @since 3.0.0 - */ - this.manager = manager; + Body.setPosition(this.body, this._tempVec2); + } - /** - * 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 y position of this Game Object. + * + * @name Phaser.Physics.Matter.Components.Transform#y + * @type {number} + * @since 3.0.0 + */ + y: { - /** - * The cached size of the data array. - * - * @name Phaser.Tweens.Timeline#totalData - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.totalData = 0; + get: function () + { + return this.body.position.y; + }, - /** - * 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; + set: function (value) + { + this._tempVec2.set(this.x, value); - /** - * 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; + Body.setPosition(this.body, this._tempVec2); + } - /** - * 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; + /** + * The horizontal scale of this Game Object. + * + * @name Phaser.Physics.Matter.Components.Transform#scaleX + * @type {number} + * @since 3.0.0 + */ + scaleX: { - /** - * How many loops are left to run? - * - * @name Phaser.Tweens.Timeline#loopCounter - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.loopCounter = 0; + get: function () + { + return this._scaleX; + }, - /** - * 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; + set: function (value) + { + var factorX = 1 / this._scaleX; + var factorY = 1 / this._scaleY; - /** - * 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; + this._scaleX = value; - /** - * The current state of the Timeline. - * - * @name Phaser.Tweens.Timeline#state - * @type {number} - * @since 3.0.0 - */ - this.state = TWEEN_CONST.PENDING_ADD; + if (this._scaleX === 0) + { + this.renderFlags &= ~_FLAG; + } + else + { + this.renderFlags |= _FLAG; + } - /** - * 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; + // Reset Matter scale back to 1 (sigh) + Body.scale(this.body, factorX, factorY); - /** - * 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; + Body.scale(this.body, value, this._scaleY); + } - /** - * 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; + /** + * The vertical scale of this Game Object. + * + * @name Phaser.Physics.Matter.Components.Transform#scaleY + * @type {number} + * @since 3.0.0 + */ + scaleY: { - /** - * 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; + get: function () + { + return this._scaleY; + }, - /** - * 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; + set: function (value) + { + var factorX = 1 / this._scaleX; + var factorY = 1 / this._scaleY; - /** - * 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; + this._scaleY = value; - /** - * 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; + if (this._scaleY === 0) + { + this.renderFlags &= ~_FLAG; + } + else + { + this.renderFlags |= _FLAG; + } - /** - * 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 - }; + Body.scale(this.body, factorX, factorY); + + Body.scale(this.body, this._scaleX, value); + } - /** - * 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. + * Use `angle` to set or get rotation of the physics body associated to this GameObject. + * Unlike rotation, when using set the value can be in degrees, which will be converted to radians internally. * - * @method Phaser.Tweens.Timeline#dispatchTimelineEvent - * @since 3.19.0 + * @name Phaser.Physics.Matter.Components.Transform#angle + * @type {number} + * @since 3.0.0 + */ + angle: { + + get: function () + { + return WrapAngleDegrees(this.body.angle * MATH_CONST.RAD_TO_DEG); + }, + + set: function (value) + { + // value is in degrees + this.rotation = WrapAngleDegrees(value) * MATH_CONST.DEG_TO_RAD; + } + }, + + /** + * Use `rotation` to set or get the rotation of the physics body associated with this GameObject. + * The value when set must be in radians. * - * @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. + * @name Phaser.Physics.Matter.Components.Transform#rotation + * @type {number} + * @since 3.0.0 */ - dispatchTimelineEvent: function (event, callback) - { - this.emit(event, this); + rotation: { - if (callback) + get: function () { - callback.func.apply(callback.scope, callback.params); + return this.body.angle; + }, + + set: function (value) + { + // value is in radians + this._rotation = WrapAngle(value); + + Body.setAngle(this.body, this._rotation); } }, /** - * 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. + * Sets the position of the physics body along x and y axes. + * Both the parameters to this function are optional and if not passed any they default to 0. + * Velocity, angle, force etc. are unchanged. * - * @method Phaser.Tweens.Timeline#setTimeScale + * @method Phaser.Physics.Matter.Components.Transform#setPosition * @since 3.0.0 * - * @param {number} value - The time scale value to set. + * @param {number} [x=0] - The horizontal position of the body. + * @param {number} [y=x] - The vertical position of the body. * - * @return {this} This Timeline object. + * @return {this} This Game Object instance. */ - setTimeScale: function (value) + setPosition: function (x, y) { - this.timeScale = value; + if (x === undefined) { x = 0; } + if (y === undefined) { y = x; } + + this._tempVec2.set(x, y); + + Body.setPosition(this.body, this._tempVec2); 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. + * Immediately sets the angle of the Body. + * Angular velocity, position, force etc. are unchanged. * - * @method Phaser.Tweens.Timeline#getTimeScale + * @method Phaser.Physics.Matter.Components.Transform#setRotation * @since 3.0.0 * - * @return {number} The value of the time scale applied to this Timeline. + * @param {number} [radians=0] - The angle of the body, in radians. + * + * @return {this} This Game Object instance. */ - getTimeScale: function () + setRotation: function (radians) { - return this.timeScale; + if (radians === undefined) { radians = 0; } + + this._rotation = WrapAngle(radians); + + Body.setAngle(this.body, radians); + + return this; }, /** - * Check whether or not the Timeline is playing. + * Setting fixed rotation sets the Body inertia to Infinity, which stops it + * from being able to rotate when forces are applied to it. * - * @method Phaser.Tweens.Timeline#isPlaying + * @method Phaser.Physics.Matter.Components.Transform#setFixedRotation * @since 3.0.0 * - * @return {boolean} `true` if this Timeline is active, otherwise `false`. + * @return {this} This Game Object instance. */ - isPlaying: function () + setFixedRotation: function () { - return (this.state === TWEEN_CONST.ACTIVE); + Body.setInertia(this.body, Infinity); + + return this; }, /** - * Creates a new Tween, based on the given Tween Config, and adds it to this Timeline. + * Immediately sets the angle of the Body. + * Angular velocity, position, force etc. are unchanged. * - * @method Phaser.Tweens.Timeline#add + * @method Phaser.Physics.Matter.Components.Transform#setAngle * @since 3.0.0 * - * @param {(Phaser.Types.Tweens.TweenBuilderConfig|object)} config - The configuration object for the Tween. + * @param {number} [degrees=0] - The angle to set, in degrees. * - * @return {this} This Timeline object. + * @return {this} This Game Object instance. */ - add: function (config) + setAngle: function (degrees) { - return this.queue(TweenBuilder(this, config)); + if (degrees === undefined) { degrees = 0; } + + this.angle = degrees; + + Body.setAngle(this.body, this.rotation); + + return this; }, /** - * Adds an existing Tween to this Timeline. + * Sets the scale of this Game Object. * - * @method Phaser.Tweens.Timeline#queue + * @method Phaser.Physics.Matter.Components.Transform#setScale * @since 3.0.0 * - * @param {Phaser.Tweens.Tween} tween - The Tween to be added to this Timeline. + * @param {number} [x=1] - The horizontal scale of this Game Object. + * @param {number} [y=x] - The vertical scale of this Game Object. If not set it will use the x value. + * @param {Phaser.Math.Vector2} [point] - The point (Vector2) from which scaling will occur. * - * @return {this} This Timeline object. + * @return {this} This Game Object instance. */ - queue: function (tween) + setScale: function (x, y, point) { - if (!this.isPlaying()) - { - tween.parent = this; - tween.parentIsTimeline = true; + if (x === undefined) { x = 1; } + if (y === undefined) { y = x; } - this.data.push(tween); + var factorX = 1 / this._scaleX; + var factorY = 1 / this._scaleY; - this.totalData = this.data.length; - } + this._scaleX = x; + this._scaleY = y; + + Body.scale(this.body, factorX, factorY, point); + + Body.scale(this.body, x, y, point); return this; - }, + } + +}; + +module.exports = Transform; + + +/***/ }), + +/***/ 37268: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Body = __webpack_require__(84125); + +/** + * Contains methods for changing the velocity of a Matter Body. Should be used as a mixin and not called directly. + * + * @namespace Phaser.Physics.Matter.Components.Velocity + * @since 3.0.0 + */ +var Velocity = { /** - * Checks whether a Tween has an offset value. + * Sets the horizontal velocity of the physics body. * - * @method Phaser.Tweens.Timeline#hasOffset + * @method Phaser.Physics.Matter.Components.Velocity#setVelocityX * @since 3.0.0 * - * @param {Phaser.Tweens.Tween} tween - The Tween to check. + * @param {number} x - The horizontal velocity value. * - * @return {boolean} `true` if the tween has a non-null offset. + * @return {this} This Game Object instance. */ - hasOffset: function (tween) + setVelocityX: function (x) { - return (tween.offset !== null); + this._tempVec2.set(x, this.body.velocity.y); + + Body.setVelocity(this.body, this._tempVec2); + + return this; }, /** - * Checks whether the offset value is a number or a directive that is relative to previous tweens. + * Sets vertical velocity of the physics body. * - * @method Phaser.Tweens.Timeline#isOffsetAbsolute + * @method Phaser.Physics.Matter.Components.Velocity#setVelocityY * @since 3.0.0 * - * @param {number} value - The offset value to be evaluated. + * @param {number} y - The vertical velocity value. * - * @return {boolean} `true` if the result is a number, `false` if it is a directive like " -= 1000". + * @return {this} This Game Object instance. */ - isOffsetAbsolute: function (value) + setVelocityY: function (y) { - return (typeof(value) === 'number'); + this._tempVec2.set(this.body.velocity.x, y); + + Body.setVelocity(this.body, this._tempVec2); + + return this; }, /** - * Checks if the offset is a relative value rather than an absolute one. - * If the value is just a number, this returns false. + * Sets both the horizontal and vertical velocity of the physics body. * - * @method Phaser.Tweens.Timeline#isOffsetRelative + * @method Phaser.Physics.Matter.Components.Velocity#setVelocity * @since 3.0.0 * - * @param {string} value - The offset value to be evaluated. + * @param {number} x - The horizontal velocity value. + * @param {number} [y=x] - The vertical velocity value, it can be either positive or negative. If not given, it will be the same as the `x` value. * - * @return {boolean} `true` if the value is relative, i.e " -= 1000". If `false`, the offset is absolute. + * @return {this} This Game Object instance. */ - isOffsetRelative: function (value) + setVelocity: function (x, y) { - var t = typeof(value); + this._tempVec2.set(x, y); - if (t === 'string') - { - var op = value[0]; + Body.setVelocity(this.body, this._tempVec2); - if (op === '-' || op === '+') - { - return true; - } - } + return this; + }, - return false; + /** + * Gets the current linear velocity of the physics body. + * + * @method Phaser.Physics.Matter.Components.Velocity#getVelocity + * @since 3.60.0 + * + * @return {Phaser.Types.Math.Vector2Like} The current linear velocity of the body. + */ + getVelocity: function () + { + return Body.getVelocity(this.body); }, /** - * Parses the relative offset value, returning a positive or negative number. + * Sets the angular velocity of the body instantly. + * Position, angle, force etc. are unchanged. * - * @method Phaser.Tweens.Timeline#getRelativeOffset + * @method Phaser.Physics.Matter.Components.Velocity#setAngularVelocity * @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. + * @param {number} velocity - The angular velocity. * - * @return {number} The parsed offset value. + * @return {this} This Game Object instance. */ - getRelativeOffset: function (value, base) + setAngularVelocity: function (velocity) { - var op = value[0]; - var num = parseFloat(value.substr(2)); - var result = base; + Body.setAngularVelocity(this.body, velocity); - switch (op) - { - case '+': - result += num; - break; + return this; + }, - case '-': - result -= num; - break; - } + /** + * Gets the current rotational velocity of the body. + * + * @method Phaser.Physics.Matter.Components.Velocity#getAngularVelocity + * @since 3.60.0 + * + * @return {number} The current angular velocity of the body. + */ + getAngularVelocity: function () + { + return Body.getAngularVelocity(this.body); + }, + + /** + * Sets the current rotational speed of the body. + * Direction is maintained. Affects body angular velocity. + * + * @method Phaser.Physics.Matter.Components.Velocity#setAngularSpeed + * @since 3.60.0 + * + * @param {number} speed - The angular speed. + * + * @return {this} This Game Object instance. + */ + setAngularSpeed: function (speed) + { + Body.setAngularSpeed(this.body, speed); - // Cannot ever be < 0 - return Math.max(0, result); + return this; }, /** - * 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. + * Gets the current rotational speed of the body. + * Equivalent to the magnitude of its angular velocity. * - * @method Phaser.Tweens.Timeline#calcDuration - * @since 3.0.0 + * @method Phaser.Physics.Matter.Components.Velocity#getAngularSpeed + * @since 3.60.0 + * + * @return {number} The current angular velocity of the body. */ - calcDuration: function () + getAngularSpeed: function () { - var prevEnd = 0; - var totalDuration = 0; - var offsetDuration = 0; + return Body.getAngularSpeed(this.body); + } + +}; + +module.exports = Velocity; + + +/***/ }), + +/***/ 74527: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Physics.Matter.Components + */ + +module.exports = { + + Bounce: __webpack_require__(95349), + Collision: __webpack_require__(70679), + Force: __webpack_require__(77178), + Friction: __webpack_require__(74015), + Gravity: __webpack_require__(11535), + Mass: __webpack_require__(74497), + Sensor: __webpack_require__(75529), + SetBody: __webpack_require__(64024), + Sleep: __webpack_require__(25106), + Static: __webpack_require__(82884), + Transform: __webpack_require__(4753), + Velocity: __webpack_require__(37268) + +}; + + +/***/ }), + +/***/ 63201: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @typedef {object} Phaser.Physics.Matter.Events.AfterAddEvent + * + * @property {any[]} object - An array of the object(s) that have been added. May be a single body, constraint, composite or a mixture of these. + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ + +/** + * The Matter Physics After Add Event. + * + * This event is dispatched by a Matter Physics World instance at the end of the process when a new Body + * or Constraint has just been added to the world. + * + * Listen to it from a Scene using: `this.matter.world.on('afteradd', listener)`. + * + * @event Phaser.Physics.Matter.Events#AFTER_ADD + * @type {string} + * @since 3.22.0 + * + * @param {Phaser.Physics.Matter.Events.AfterAddEvent} event - The Add Event object. + */ +module.exports = 'afteradd'; + + +/***/ }), + +/***/ 30474: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @typedef {object} Phaser.Physics.Matter.Events.AfterRemoveEvent + * + * @property {any[]} object - An array of the object(s) that were removed. May be a single body, constraint, composite or a mixture of these. + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ + +/** + * The Matter Physics After Remove Event. + * + * This event is dispatched by a Matter Physics World instance at the end of the process when a + * Body or Constraint was removed from the world. + * + * Listen to it from a Scene using: `this.matter.world.on('afterremove', listener)`. + * + * @event Phaser.Physics.Matter.Events#AFTER_REMOVE + * @type {string} + * @since 3.22.0 + * + * @param {Phaser.Physics.Matter.Events.AfterRemoveEvent} event - The Remove Event object. + */ +module.exports = 'afterremove'; + + +/***/ }), + +/***/ 44822: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @typedef {object} Phaser.Physics.Matter.Events.AfterUpdateEvent + * + * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ + +/** + * The Matter Physics After Update Event. + * + * This event is dispatched by a Matter Physics World instance after the engine has updated and all collision events have resolved. + * + * Listen to it from a Scene using: `this.matter.world.on('afterupdate', listener)`. + * + * @event Phaser.Physics.Matter.Events#AFTER_UPDATE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Physics.Matter.Events.AfterUpdateEvent} event - The Update Event object. + */ +module.exports = 'afterupdate'; + + +/***/ }), + +/***/ 88820: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @typedef {object} Phaser.Physics.Matter.Events.BeforeAddEvent + * + * @property {any[]} object - An array of the object(s) to be added. May be a single body, constraint, composite or a mixture of these. + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ + +/** + * The Matter Physics Before Add Event. + * + * This event is dispatched by a Matter Physics World instance at the start of the process when a new Body + * or Constraint is being added to the world. + * + * Listen to it from a Scene using: `this.matter.world.on('beforeadd', listener)`. + * + * @event Phaser.Physics.Matter.Events#BEFORE_ADD + * @type {string} + * @since 3.22.0 + * + * @param {Phaser.Physics.Matter.Events.BeforeAddEvent} event - The Add Event object. + */ +module.exports = 'beforeadd'; + + +/***/ }), + +/***/ 94849: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @typedef {object} Phaser.Physics.Matter.Events.BeforeRemoveEvent + * + * @property {any[]} object - An array of the object(s) to be removed. May be a single body, constraint, composite or a mixture of these. + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ + +/** + * The Matter Physics Before Remove Event. + * + * This event is dispatched by a Matter Physics World instance at the start of the process when a + * Body or Constraint is being removed from the world. + * + * Listen to it from a Scene using: `this.matter.world.on('beforeremove', listener)`. + * + * @event Phaser.Physics.Matter.Events#BEFORE_REMOVE + * @type {string} + * @since 3.22.0 + * + * @param {Phaser.Physics.Matter.Events.BeforeRemoveEvent} event - The Remove Event object. + */ +module.exports = 'beforeremove'; + + +/***/ }), + +/***/ 6391: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @typedef {object} Phaser.Physics.Matter.Events.BeforeUpdateEvent + * + * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ + +/** + * The Matter Physics Before Update Event. + * + * This event is dispatched by a Matter Physics World instance right before all the collision processing takes place. + * + * Listen to it from a Scene using: `this.matter.world.on('beforeupdate', listener)`. + * + * @event Phaser.Physics.Matter.Events#BEFORE_UPDATE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Physics.Matter.Events.BeforeUpdateEvent} event - The Update Event object. + */ +module.exports = 'beforeupdate'; + + +/***/ }), + +/***/ 96738: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @typedef {object} Phaser.Physics.Matter.Events.CollisionActiveEvent + * + * @property {Phaser.Types.Physics.Matter.MatterCollisionData[]} pairs - A list of all affected pairs in the collision. + * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ + +/** + * The Matter Physics Collision Active Event. + * + * This event is dispatched by a Matter Physics World instance after the engine has updated. + * It provides a list of all pairs that are colliding in the current tick (if any). + * + * Listen to it from a Scene using: `this.matter.world.on('collisionactive', listener)`. + * + * @event Phaser.Physics.Matter.Events#COLLISION_ACTIVE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Physics.Matter.Events.CollisionActiveEvent} event - The Collision Event object. + * @param {MatterJS.BodyType} bodyA - The first body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. + * @param {MatterJS.BodyType} bodyB - The second body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. + */ +module.exports = 'collisionactive'; + + +/***/ }), + +/***/ 7916: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @typedef {object} Phaser.Physics.Matter.Events.CollisionEndEvent + * + * @property {Phaser.Types.Physics.Matter.MatterCollisionData[]} pairs - A list of all affected pairs in the collision. + * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ + +/** + * The Matter Physics Collision End Event. + * + * This event is dispatched by a Matter Physics World instance after the engine has updated. + * It provides a list of all pairs that have finished colliding in the current tick (if any). + * + * Listen to it from a Scene using: `this.matter.world.on('collisionend', listener)`. + * + * @event Phaser.Physics.Matter.Events#COLLISION_END + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Physics.Matter.Events.CollisionEndEvent} event - The Collision Event object. + * @param {MatterJS.BodyType} bodyA - The first body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. + * @param {MatterJS.BodyType} bodyB - The second body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. + */ +module.exports = 'collisionend'; + + +/***/ }), + +/***/ 59529: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @typedef {object} Phaser.Physics.Matter.Events.CollisionStartEvent + * + * @property {Phaser.Types.Physics.Matter.MatterCollisionData[]} pairs - A list of all affected pairs in the collision. + * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ + +/** + * The Matter Physics Collision Start Event. + * + * This event is dispatched by a Matter Physics World instance after the engine has updated. + * It provides a list of all pairs that have started to collide in the current tick (if any). + * + * Listen to it from a Scene using: `this.matter.world.on('collisionstart', listener)`. + * + * @event Phaser.Physics.Matter.Events#COLLISION_START + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Physics.Matter.Events.CollisionStartEvent} event - The Collision Event object. + * @param {MatterJS.BodyType} bodyA - The first body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. + * @param {MatterJS.BodyType} bodyB - The second body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. + */ +module.exports = 'collisionstart'; + + +/***/ }), + +/***/ 10219: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Matter Physics Drag End Event. + * + * This event is dispatched by a Matter Physics World instance when a Pointer Constraint + * stops dragging a body. + * + * Listen to it from a Scene using: `this.matter.world.on('dragend', listener)`. + * + * @event Phaser.Physics.Matter.Events#DRAG_END + * @type {string} + * @since 3.16.2 + * + * @param {MatterJS.BodyType} body - The Body that has stopped being dragged. This is a Matter Body, not a Phaser Game Object. + * @param {Phaser.Physics.Matter.PointerConstraint} constraint - The Pointer Constraint that was dragging the body. + */ +module.exports = 'dragend'; + + +/***/ }), - for (var i = 0; i < this.totalData; i++) - { - var tween = this.data[i]; +/***/ 183: +/***/ ((module) => { - tween.init(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - 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; +/** + * The Matter Physics Drag Event. + * + * This event is dispatched by a Matter Physics World instance when a Pointer Constraint + * is actively dragging a body. It is emitted each time the pointer moves. + * + * Listen to it from a Scene using: `this.matter.world.on('drag', listener)`. + * + * @event Phaser.Physics.Matter.Events#DRAG + * @type {string} + * @since 3.16.2 + * + * @param {MatterJS.BodyType} body - The Body that is being dragged. This is a Matter Body, not a Phaser Game Object. + * @param {Phaser.Physics.Matter.PointerConstraint} constraint - The Pointer Constraint that is dragging the body. + */ +module.exports = 'drag'; - 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; - } +/***/ 39143: +/***/ ((module) => { - // Excludes loop values - this.duration = totalDuration; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.loopCounter = (this.loop === -1) ? 999999999999 : this.loop; +/** + * The Matter Physics Drag Start Event. + * + * This event is dispatched by a Matter Physics World instance when a Pointer Constraint + * starts dragging a body. + * + * Listen to it from a Scene using: `this.matter.world.on('dragstart', listener)`. + * + * @event Phaser.Physics.Matter.Events#DRAG_START + * @type {string} + * @since 3.16.2 + * + * @param {MatterJS.BodyType} body - The Body that has started being dragged. This is a Matter Body, not a Phaser Game Object. + * @param {MatterJS.BodyType} part - The part of the body that was clicked on. + * @param {Phaser.Physics.Matter.PointerConstraint} constraint - The Pointer Constraint that is dragging the body. + */ +module.exports = 'dragstart'; - 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; +/***/ 16483: +/***/ ((module) => { - if (this.paused) - { - this.state = TWEEN_CONST.PAUSED; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return false; - } - else - { - return true; - } - }, +/** + * The Matter Physics World Pause Event. + * + * This event is dispatched by an Matter Physics World instance when it is paused. + * + * Listen to it from a Scene using: `this.matter.world.on('pause', listener)`. + * + * @event Phaser.Physics.Matter.Events#PAUSE + * @type {string} + * @since 3.0.0 + */ +module.exports = 'pause'; - /** - * 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 }; - } +/***/ 35806: +/***/ ((module) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * 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); - }, +/** + * The Matter Physics World Resume Event. + * + * This event is dispatched by an Matter Physics World instance when it resumes from a paused state. + * + * Listen to it from a Scene using: `this.matter.world.on('resume', listener)`. + * + * @event Phaser.Physics.Matter.Events#RESUME + * @type {string} + * @since 3.0.0 + */ +module.exports = 'resume'; - /** - * 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); +/***/ 22106: +/***/ ((module) => { - return; - } - else - { - this.resetTweens(false); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.state = TWEEN_CONST.ACTIVE; - } +/** + * @typedef {object} Phaser.Physics.Matter.Events.SleepEndEvent + * + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ - this.dispatchTimelineEvent(Events.TIMELINE_START, this.callbacks.onStart); - }, +/** + * The Matter Physics Sleep End Event. + * + * This event is dispatched by a Matter Physics World instance when a Body stop sleeping. + * + * Listen to it from a Scene using: `this.matter.world.on('sleepend', listener)`. + * + * @event Phaser.Physics.Matter.Events#SLEEP_END + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Physics.Matter.Events.SleepEndEvent} event - The Sleep Event object. + * @param {MatterJS.BodyType} body - The body that has stopped sleeping. + */ +module.exports = 'sleepend'; - /** - * 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); +/***/ 5803: +/***/ ((module) => { - if (this.loopDelay > 0) - { - this.countdown = this.loopDelay; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.state = TWEEN_CONST.LOOP_DELAY; - } - else - { - this.state = TWEEN_CONST.ACTIVE; +/** + * @typedef {object} Phaser.Physics.Matter.Events.SleepStartEvent + * + * @property {any} source - The source object of the event. + * @property {string} name - The name of the event. + */ - this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); - } - } - else if (this.completeDelay > 0) - { - this.state = TWEEN_CONST.COMPLETE_DELAY; +/** + * The Matter Physics Sleep Start Event. + * + * This event is dispatched by a Matter Physics World instance when a Body goes to sleep. + * + * Listen to it from a Scene using: `this.matter.world.on('sleepstart', listener)`. + * + * @event Phaser.Physics.Matter.Events#SLEEP_START + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Physics.Matter.Events.SleepStartEvent} event - The Sleep Event object. + * @param {MatterJS.BodyType} body - The body that has gone to sleep. + */ +module.exports = 'sleepstart'; - 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; - } +/***/ 35416: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (this.useFrames) - { - delta = 1 * this.manager.timeScale; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - delta *= this.timeScale; +/** + * @namespace Phaser.Physics.Matter.Events + */ - this.elapsed += delta; - this.progress = Math.min(this.elapsed / this.duration, 1); +module.exports = { - this.totalElapsed += delta; - this.totalProgress = Math.min(this.totalElapsed / this.totalDuration, 1); + AFTER_ADD: __webpack_require__(63201), + AFTER_REMOVE: __webpack_require__(30474), + AFTER_UPDATE: __webpack_require__(44822), + BEFORE_ADD: __webpack_require__(88820), + BEFORE_REMOVE: __webpack_require__(94849), + BEFORE_UPDATE: __webpack_require__(6391), + COLLISION_ACTIVE: __webpack_require__(96738), + COLLISION_END: __webpack_require__(7916), + COLLISION_START: __webpack_require__(59529), + DRAG_END: __webpack_require__(10219), + DRAG: __webpack_require__(183), + DRAG_START: __webpack_require__(39143), + PAUSE: __webpack_require__(16483), + RESUME: __webpack_require__(35806), + SLEEP_END: __webpack_require__(22106), + SLEEP_START: __webpack_require__(5803) - 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--; - } - } +/***/ 45949: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.dispatchTimelineEvent(Events.TIMELINE_UPDATE, this.callbacks.onUpdate); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Anything still running? If not, we're done - if (stillRunning === 0) - { - this.nextState(); - } +/** + * @namespace Phaser.Physics.Matter + */ - break; +module.exports = { - case TWEEN_CONST.LOOP_DELAY: + BodyBounds: __webpack_require__(63568), + Components: __webpack_require__(74527), + Events: __webpack_require__(35416), + Factory: __webpack_require__(72653), + MatterGameObject: __webpack_require__(3860), + Image: __webpack_require__(7030), + Matter: __webpack_require__(18171), + MatterPhysics: __webpack_require__(50583), + PolyDecomp: __webpack_require__(81084), + Sprite: __webpack_require__(73658), + TileBody: __webpack_require__(84720), + PhysicsEditorParser: __webpack_require__(10998), + PhysicsJSONParser: __webpack_require__(72829), + PointerConstraint: __webpack_require__(88596), + World: __webpack_require__(31468) - this.countdown -= delta; +}; - if (this.countdown <= 0) - { - this.state = TWEEN_CONST.ACTIVE; - this.dispatchTimelineEvent(Events.TIMELINE_LOOP, this.callbacks.onLoop); - } +/***/ }), - break; +/***/ 84125: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case TWEEN_CONST.COMPLETE_DELAY: +/** + * The `Matter.Body` module contains methods for creating and manipulating body models. + * A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`. + * Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the module `Matter.Bodies`. + * + * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). + * @class Body + */ - this.countdown -= delta; +var Body = {}; - if (this.countdown <= 0) - { - this.state = TWEEN_CONST.PENDING_REMOVE; +module.exports = Body; - this.dispatchTimelineEvent(Events.TIMELINE_COMPLETE, this.callbacks.onComplete); - } +var Vertices = __webpack_require__(39745); +var Vector = __webpack_require__(10438); +var Sleeping = __webpack_require__(22806); +var Common = __webpack_require__(68758); +var Bounds = __webpack_require__(84091); +var Axes = __webpack_require__(50658); - break; - } +(function() { - return (this.state === TWEEN_CONST.PENDING_REMOVE); - }, + Body._timeCorrection = true; + Body._inertiaScale = 4; + Body._nextCollidingGroupId = 1; + Body._nextNonCollidingGroupId = -1; + Body._nextCategory = 0x0001; + Body._baseDelta = 1000 / 60; /** - * 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 + * Creates a new rigid body model. The options parameter is an object that specifies any properties you wish to override the defaults. + * All properties have default values, and many are pre-calculated automatically based on other properties. + * Vertices must be specified in clockwise order. + * See the properties section below for detailed information on what you can pass via the `options` object. + * @method create + * @param {} options + * @return {body} body */ - stop: function () - { - this.state = TWEEN_CONST.PENDING_REMOVE; - }, + Body.create = function(options) { + var defaults = { + id: Common.nextId(), + type: 'body', + label: 'Body', + parts: [], + plugin: {}, + angle: 0, + vertices: null, // Phaser change: no point calling fromPath if they pass in vertices anyway + position: { x: 0, y: 0 }, + force: { x: 0, y: 0 }, + torque: 0, + positionImpulse: { x: 0, y: 0 }, + constraintImpulse: { x: 0, y: 0, angle: 0 }, + totalContacts: 0, + speed: 0, + angularSpeed: 0, + velocity: { x: 0, y: 0 }, + angularVelocity: 0, + isSensor: false, + isStatic: false, + isSleeping: false, + motion: 0, + sleepThreshold: 60, + density: 0.001, + restitution: 0, + friction: 0.1, + frictionStatic: 0.5, + frictionAir: 0.01, + collisionFilter: { + category: 0x0001, + mask: 0xFFFFFFFF, + group: 0 + }, + slop: 0.05, + timeScale: 1, + events: null, + bounds: null, + chamfer: null, + circleRadius: 0, + positionPrev: null, + anglePrev: 0, + parent: null, + axes: null, + area: 0, + mass: 0, + inverseMass: 0, + inertia: 0, + deltaTime: 1000 / 60, + inverseInertia: 0, + _original: null, + render: { + visible: true, + opacity: 1, + sprite: { + xOffset: 0, + yOffset: 0 + }, + fillColor: null, // custom Phaser property + fillOpacity: null, // custom Phaser property + lineColor: null, // custom Phaser property + lineOpacity: null, // custom Phaser property + lineThickness: null // custom Phaser property + }, + gameObject: null, // custom Phaser property + scale: { x: 1, y: 1 }, // custom Phaser property + centerOfMass: { x: 0, y: 0 }, // custom Phaser property (float, 0 - 1) + centerOffset: { x: 0, y: 0 }, // custom Phaser property (pixel values) + gravityScale: { x: 1, y: 1 }, // custom Phaser property + ignoreGravity: false, // custom Phaser property + ignorePointer: false, // custom Phaser property + onCollideCallback: null, // custom Phaser property + onCollideEndCallback: null, // custom Phaser property + onCollideActiveCallback: null, // custom Phaser property + onCollideWith: {} // custom Phaser property + }; - /** - * 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) + if (!options.hasOwnProperty('position') && options.hasOwnProperty('vertices')) { - return; + options.position = Vertices.centre(options.vertices); + } + else if (!options.hasOwnProperty('vertices')) + { + defaults.vertices = Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'); } - this.paused = true; + var body = Common.extend(defaults, options); - this._pausedState = this.state; + _initProperties(body, options); - this.state = TWEEN_CONST.PAUSED; + // Helper function + body.setOnCollideWith = function (body, callback) + { + if (callback) + { + this.onCollideWith[body.id] = callback; + } + else + { + delete this.onCollideWith[body.id]; + } - this.emit(Events.TIMELINE_PAUSE, this); + return this; + } - return this; - }, + return body; + }; /** - * 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. + * Returns the next unique group index for which bodies will collide. + * If `isNonColliding` is `true`, returns the next unique group index for which bodies will _not_ collide. + * See `body.collisionFilter` for more information. + * @method nextGroup + * @param {bool} [isNonColliding=false] + * @return {Number} Unique group index */ - resume: function () - { - if (this.state === TWEEN_CONST.PAUSED) - { - this.paused = false; - - this.state = this._pausedState; - - this.emit(Events.TIMELINE_RESUME, this); - } + Body.nextGroup = function(isNonColliding) { + if (isNonColliding) + return Body._nextNonCollidingGroupId--; - return this; - }, + return Body._nextCollidingGroupId++; + }; /** - * 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`. + * Returns the next unique category bitfield (starting after the initial default category `0x0001`). + * There are 32 available. See `body.collisionFilter` for more information. + * @method nextCategory + * @return {Number} Unique category bitfield */ - hasTarget: function (target) - { - for (var i = 0; i < this.data.length; i++) - { - if (this.data[i].hasTarget(target)) - { - return true; - } - } - - return false; - }, + Body.nextCategory = function() { + Body._nextCategory = Body._nextCategory << 1; + return Body._nextCategory; + }; /** - * 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 + * Initialises body properties. + * @method _initProperties + * @private + * @param {body} body + * @param {} [options] */ - destroy: function () - { - for (var i = 0; i < this.data.length; i++) - { - this.data[i].stop(); - } - } + var _initProperties = function(body, options) { + options = options || {}; -}); + // init required properties (order is important) + Body.set(body, { + bounds: body.bounds || Bounds.create(body.vertices), + positionPrev: body.positionPrev || Vector.clone(body.position), + anglePrev: body.anglePrev || body.angle, + vertices: body.vertices, + parts: body.parts || [body], + isStatic: body.isStatic, + isSleeping: body.isSleeping, + parent: body.parent || body + }); + + Vertices.rotate(body.vertices, body.angle, body.position); + Axes.rotate(body.axes, body.angle); + Bounds.update(body.bounds, body.vertices, body.velocity); -Timeline.TYPES = [ 'onStart', 'onUpdate', 'onLoop', 'onComplete', 'onYoyo' ]; + // allow options to override the automatically calculated properties + Body.set(body, { + axes: options.axes || body.axes, + area: options.area || body.area, + mass: options.mass || body.mass, + inertia: options.inertia || body.inertia + }); -module.exports = Timeline; + if (body.parts.length === 1) + { + var bounds = body.bounds; + var centerOfMass = body.centerOfMass; + var centerOffset = body.centerOffset; -/***/ }), -/* 589 */ -/***/ (function(module, exports, __webpack_require__) { + var bodyWidth = bounds.max.x - bounds.min.x; + var bodyHeight = bounds.max.y - bounds.min.y; -/** - * @author Joachim Grill - * @author Richard Davey - * @copyright 2018 CodeAndWeb GmbH - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + centerOfMass.x = -(bounds.min.x - body.position.x) / bodyWidth; + centerOfMass.y = -(bounds.min.y - body.position.y) / bodyHeight; -var Bodies = __webpack_require__(86); -var Body = __webpack_require__(41); -var Common = __webpack_require__(32); -var GetFastValue = __webpack_require__(2); -var Vertices = __webpack_require__(64); + centerOffset.x = bodyWidth * centerOfMass.x; + centerOffset.y = bodyHeight * centerOfMass.y; + } -/** - * Use PhysicsEditorParser.parseBody() to build a Matter body object, based on a physics data file - * created and exported with PhysicsEditor (https://www.codeandweb.com/physicseditor). - * - * @namespace Phaser.Physics.Matter.PhysicsEditorParser - * @since 3.10.0 - */ -var PhysicsEditorParser = { + // From Matter render code: + // body.render.sprite.xOffset += -(body.bounds.min.x - body.position.x) / (body.bounds.max.x - body.bounds.min.x); + // body.render.sprite.yOffset += -(body.bounds.min.y - body.position.y) / (body.bounds.max.y - body.bounds.min.y); + }; /** - * Parses a body element exported by PhysicsEditor. - * - * @function Phaser.Physics.Matter.PhysicsEditorParser.parseBody - * @since 3.10.0 - * - * @param {number} x - The horizontal world location of the body. - * @param {number} y - The vertical world location of the body. - * @param {object} config - The body configuration and fixture (child body) definitions, as exported by PhysicsEditor. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {MatterJS.BodyType} A compound Matter JS Body. + * Given a property and a value (or map of), sets the property(s) on the body, using the appropriate setter functions if they exist. + * Prefer to use the actual setter functions in performance critical situations. + * @method set + * @param {body} body + * @param {} settings A property name (or map of properties and values) to set on the body. + * @param {} value The value to set if `settings` is a single property name. */ - parseBody: function (x, y, config, options) - { - if (options === undefined) { options = {}; } + Body.set = function(body, settings, value) { + var property; - var fixtureConfigs = GetFastValue(config, 'fixtures', []); - var fixtures = []; + if (typeof settings === 'string') { + property = settings; + settings = {}; + settings[property] = value; + } - for (var fc = 0; fc < fixtureConfigs.length; fc++) - { - var fixtureParts = this.parseFixture(fixtureConfigs[fc]); + for (property in settings) { + if (!Object.prototype.hasOwnProperty.call(settings, property)) + continue; - for (var i = 0; i < fixtureParts.length; i++) - { - fixtures.push(fixtureParts[i]); + value = settings[property]; + switch (property) { + + case 'isStatic': + Body.setStatic(body, value); + break; + case 'isSleeping': + Sleeping.set(body, value); + break; + case 'mass': + Body.setMass(body, value); + break; + case 'density': + Body.setDensity(body, value); + break; + case 'inertia': + Body.setInertia(body, value); + break; + case 'vertices': + Body.setVertices(body, value); + break; + case 'position': + Body.setPosition(body, value); + break; + case 'angle': + Body.setAngle(body, value); + break; + case 'velocity': + Body.setVelocity(body, value); + break; + case 'angularVelocity': + Body.setAngularVelocity(body, value); + break; + case 'speed': + Body.setSpeed(body, value); + break; + case 'angularSpeed': + Body.setAngularSpeed(body, value); + break; + case 'parts': + Body.setParts(body, value); + break; + case 'centre': + Body.setCentre(body, value); + break; + default: + body[property] = value; } } + }; - var matterConfig = Common.clone(config, true); - - Common.extend(matterConfig, options, true); + /** + * Sets the body as static, including isStatic flag and setting mass and inertia to Infinity. + * @method setStatic + * @param {body} body + * @param {bool} isStatic + */ + Body.setStatic = function(body, isStatic) { + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; - delete matterConfig.fixtures; - delete matterConfig.type; + if (isStatic) { + if (!part.isStatic) { + part._original = { + restitution: part.restitution, + friction: part.friction, + mass: part.mass, + inertia: part.inertia, + density: part.density, + inverseMass: part.inverseMass, + inverseInertia: part.inverseInertia + }; + } - var body = Body.create(matterConfig); + part.restitution = 0; + part.friction = 1; + part.mass = part.inertia = part.density = Infinity; + part.inverseMass = part.inverseInertia = 0; - Body.setParts(body, fixtures); - - Body.setPosition(body, { x: x, y: y }); + part.positionPrev.x = part.position.x; + part.positionPrev.y = part.position.y; + part.anglePrev = part.angle; + part.angularVelocity = 0; + part.speed = 0; + part.angularSpeed = 0; + part.motion = 0; + } else if (part._original) { + part.restitution = part._original.restitution; + part.friction = part._original.friction; + part.mass = part._original.mass; + part.inertia = part._original.inertia; + part.density = part._original.density; + part.inverseMass = part._original.inverseMass; + part.inverseInertia = part._original.inverseInertia; - return body; - }, + part._original = null; + } + part.isStatic = isStatic; + } + }; /** - * Parses an element of the "fixtures" list exported by PhysicsEditor - * - * @function Phaser.Physics.Matter.PhysicsEditorParser.parseFixture - * @since 3.10.0 - * - * @param {object} fixtureConfig - The fixture object to parse. - * - * @return {MatterJS.BodyType[]} - An array of Matter JS Bodies. + * Sets the mass of the body. Inverse mass, density and inertia are automatically updated to reflect the change. + * @method setMass + * @param {body} body + * @param {number} mass */ - parseFixture: function (fixtureConfig) - { - var matterConfig = Common.extend({}, false, fixtureConfig); - - delete matterConfig.circle; - delete matterConfig.vertices; + Body.setMass = function(body, mass) { + var moment = body.inertia / (body.mass / 6); + body.inertia = moment * (mass / 6); + body.inverseInertia = 1 / body.inertia; - var fixtures; + body.mass = mass; + body.inverseMass = 1 / body.mass; + body.density = body.mass / body.area; + }; - if (fixtureConfig.circle) - { - var x = GetFastValue(fixtureConfig.circle, 'x'); - var y = GetFastValue(fixtureConfig.circle, 'y'); - var r = GetFastValue(fixtureConfig.circle, 'radius'); - fixtures = [ Bodies.circle(x, y, r, matterConfig) ]; - } - else if (fixtureConfig.vertices) - { - fixtures = this.parseVertices(fixtureConfig.vertices, matterConfig); - } + /** + * Sets the density of the body. Mass and inertia are automatically updated to reflect the change. + * @method setDensity + * @param {body} body + * @param {number} density + */ + Body.setDensity = function(body, density) { + Body.setMass(body, density * body.area); + body.density = density; + }; - return fixtures; - }, + /** + * Sets the moment of inertia (i.e. second moment of area) of the body. + * Inverse inertia is automatically updated to reflect the change. Mass is not changed. + * @method setInertia + * @param {body} body + * @param {number} inertia + */ + Body.setInertia = function(body, inertia) { + body.inertia = inertia; + body.inverseInertia = 1 / body.inertia; + }; /** - * Parses the "vertices" lists exported by PhysicsEditor. + * Sets the body's vertices and updates body properties accordingly, including inertia, area and mass (with respect to `body.density`). + * Vertices will be automatically transformed to be orientated around their centre of mass as the origin. + * They are then automatically translated to world space based on `body.position`. * - * @function Phaser.Physics.Matter.PhysicsEditorParser.parseVertices - * @since 3.10.0 + * The `vertices` argument should be passed as an array of `Matter.Vector` points (or a `Matter.Vertices` array). + * Vertices must form a convex hull, concave hulls are not supported. * - * @param {array} vertexSets - The vertex lists to parse. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {MatterJS.BodyType[]} - An array of Matter JS Bodies. + * @method setVertices + * @param {body} body + * @param {vector[]} vertices */ - parseVertices: function (vertexSets, options) - { - if (options === undefined) { options = {}; } - - var parts = []; - - for (var v = 0; v < vertexSets.length; v++) - { - Vertices.clockwiseSort(vertexSets[v]); - - parts.push(Body.create(Common.extend({ - position: Vertices.centre(vertexSets[v]), - vertices: vertexSets[v] - }, options))); + Body.setVertices = function(body, vertices) { + // change vertices + if (vertices[0].body === body) { + body.vertices = vertices; + } else { + body.vertices = Vertices.create(vertices, body); } - // flag coincident part edges - return Bodies.flagCoincidentParts(parts); - } -}; - -module.exports = PhysicsEditorParser; - + // update properties + body.axes = Axes.fromVertices(body.vertices); + body.area = Vertices.area(body.vertices); + Body.setMass(body, body.density * body.area); -/***/ }), -/* 590 */ -/***/ (function(module, exports, __webpack_require__) { + // orient vertices around the centre of mass at origin (0, 0) + var centre = Vertices.centre(body.vertices); + Vertices.translate(body.vertices, centre, -1); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // update inertia while vertices are at origin (0, 0) + Body.setInertia(body, Body._inertiaScale * Vertices.inertia(body.vertices, body.mass)); -var Bodies = __webpack_require__(86); -var Body = __webpack_require__(41); + // update geometry + Vertices.translate(body.vertices, body.position); -/** - * Creates a body using the supplied physics data, as provided by a JSON file. - * - * The data file should be loaded as JSON: - * - * ```javascript - * preload () - * { - * this.load.json('ninjas', 'assets/ninjas.json); - * } - * - * create () - * { - * const ninjaShapes = this.cache.json.get('ninjas'); - * - * this.matter.add.fromJSON(400, 300, ninjaShapes.shinobi); - * } - * ``` - * - * Do not pass the entire JSON file to this method, but instead pass one of the shapes contained within it. - * - * If you pas in an `options` object, any settings in there will override those in the config object. - * - * The structure of the JSON file is as follows: - * - * ```text - * { - * 'generator_info': // The name of the application that created the JSON data - * 'shapeName': { - * 'type': // The type of body - * 'label': // Optional body label - * 'vertices': // An array, or an array of arrays, containing the vertex data in x/y object pairs - * } - * } - * ``` - * - * At the time of writing, only the Phaser Physics Tracer App exports in this format. - * - * @namespace Phaser.Physics.Matter.PhysicsJSONParser - * @since 3.22.0 - */ -var PhysicsJSONParser = { + Bounds.update(body.bounds, body.vertices, body.velocity); + }; /** - * Parses a body element from the given JSON data. - * - * @function Phaser.Physics.Matter.PhysicsJSONParser.parseBody - * @since 3.22.0 - * - * @param {number} x - The horizontal world location of the body. - * @param {number} y - The vertical world location of the body. - * @param {object} config - The body configuration data. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {MatterJS.BodyType} A Matter JS Body. + * Sets the parts of the `body` and updates mass, inertia and centroid. + * Each part will have its parent set to `body`. + * By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.` + * Note that this method will ensure that the first part in `body.parts` will always be the `body`. + * @method setParts + * @param {body} body + * @param [body] parts + * @param {bool} [autoHull=true] */ - parseBody: function (x, y, config, options) - { - if (options === undefined) { options = {}; } - - var body; - var vertexSets = config.vertices; - - if (vertexSets.length === 1) - { - // Just a single Body - options.vertices = vertexSets[0]; + Body.setParts = function(body, parts, autoHull) { + var i; - body = Body.create(options); + // add all the parts, ensuring that the first part is always the parent body + parts = parts.slice(0); + body.parts.length = 0; + body.parts.push(body); + body.parent = body; - Bodies.flagCoincidentParts(body.parts); + for (i = 0; i < parts.length; i++) { + var part = parts[i]; + if (part !== body) { + part.parent = body; + body.parts.push(part); + } } - else - { - var parts = []; - for (var i = 0; i < vertexSets.length; i++) - { - var part = Body.create({ - vertices: vertexSets[i] - }); + if (body.parts.length === 1) + return; - parts.push(part); + autoHull = typeof autoHull !== 'undefined' ? autoHull : true; + + // find the convex hull of all parts to set on the parent body + if (autoHull) { + var vertices = []; + for (i = 0; i < parts.length; i++) { + vertices = vertices.concat(parts[i].vertices); } - Bodies.flagCoincidentParts(parts); + Vertices.clockwiseSort(vertices); - options.parts = parts; + var hull = Vertices.hull(vertices), + hullCentre = Vertices.centre(hull); - body = Body.create(options); + Body.setVertices(body, hull); + Vertices.translate(body.vertices, hullCentre); } - body.label = config.label; - - Body.setPosition(body, { x: x, y: y }); - - return body; - } - -}; + // sum the properties of all compound parts of the parent body + var total = Body._totalProperties(body); -module.exports = PhysicsJSONParser; + // Phaser addition + var cx = total.centre.x; + var cy = total.centre.y; + var bounds = body.bounds; + var centerOfMass = body.centerOfMass; + var centerOffset = body.centerOffset; -/***/ }), -/* 591 */ -/***/ (function(module, exports, __webpack_require__) { + Bounds.update(bounds, body.vertices, body.velocity); -/** -* The `Matter.Composites` module contains factory methods for creating composite bodies -* with commonly used configurations (such as stacks and chains). -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Composites -*/ + centerOfMass.x = -(bounds.min.x - cx) / (bounds.max.x - bounds.min.x); + centerOfMass.y = -(bounds.min.y - cy) / (bounds.max.y - bounds.min.y); -var Composites = {}; + centerOffset.x = cx; + centerOffset.y = cy; -module.exports = Composites; + body.area = total.area; + body.parent = body; + body.position.x = cx; + body.position.y = cy; + body.positionPrev.x = cx; + body.positionPrev.y = cy; -var Composite = __webpack_require__(118); -var Constraint = __webpack_require__(128); -var Common = __webpack_require__(32); -var Body = __webpack_require__(41); -var Bodies = __webpack_require__(86); + // Matter.js original + // body.position.x = total.centre.x; + // body.position.y = total.centre.y; + // body.positionPrev.x = total.centre.x; + // body.positionPrev.y = total.centre.y; -(function() { + Body.setMass(body, total.mass); + Body.setInertia(body, total.inertia); + Body.setPosition(body, total.centre); + }; /** - * Create a new composite containing bodies created in the callback in a grid arrangement. - * This function uses the body's bounds to prevent overlaps. - * @method stack - * @param {number} xx - * @param {number} yy - * @param {number} columns - * @param {number} rows - * @param {number} columnGap - * @param {number} rowGap - * @param {function} callback - * @return {composite} A new composite containing objects created in the callback + * Set the centre of mass of the body. + * The `centre` is a vector in world-space unless `relative` is set, in which case it is a translation. + * The centre of mass is the point the body rotates about and can be used to simulate non-uniform density. + * This is equal to moving `body.position` but not the `body.vertices`. + * Invalid if the `centre` falls outside the body's convex hull. + * @method setCentre + * @param {body} body + * @param {vector} centre + * @param {bool} relative */ - Composites.stack = function(xx, yy, columns, rows, columnGap, rowGap, callback) { - var stack = Composite.create({ label: 'Stack' }), - x = xx, - y = yy, - lastBody, - i = 0; - - for (var row = 0; row < rows; row++) { - var maxHeight = 0; - - for (var column = 0; column < columns; column++) { - var body = callback(x, y, column, row, lastBody, i); - - if (body) { - var bodyHeight = body.bounds.max.y - body.bounds.min.y, - bodyWidth = body.bounds.max.x - body.bounds.min.x; - - if (bodyHeight > maxHeight) - maxHeight = bodyHeight; - - Body.translate(body, { x: bodyWidth * 0.5, y: bodyHeight * 0.5 }); - - x = body.bounds.max.x + columnGap; + Body.setCentre = function(body, centre, relative) { + if (!relative) { + body.positionPrev.x = centre.x - (body.position.x - body.positionPrev.x); + body.positionPrev.y = centre.y - (body.position.y - body.positionPrev.y); + body.position.x = centre.x; + body.position.y = centre.y; + } else { + body.positionPrev.x += centre.x; + body.positionPrev.y += centre.y; + body.position.x += centre.x; + body.position.y += centre.y; + } + }; - Composite.addBody(stack, body); - - lastBody = body; - i += 1; - } else { - x += columnGap; - } - } - - y += maxHeight + rowGap; - x = xx; + /** + * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged. + * @method setPosition + * @param {body} body + * @param {vector} position + * @param {boolean} updateVelocity + */ + Body.setPosition = function(body, position, updateVelocity) { + var delta = Vector.sub(position, body.position); + if (updateVelocity) { + body.positionPrev.x = body.position.x; + body.positionPrev.y = body.position.y; + body.velocity.x = delta.x; + body.velocity.y = delta.y; + body.speed = Vector.magnitude(delta); + } else { + body.positionPrev.x += delta.x; + body.positionPrev.y += delta.y; } - return stack; + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; + part.position.x += delta.x; + part.position.y += delta.y; + Vertices.translate(part.vertices, delta); + Bounds.update(part.bounds, part.vertices, body.velocity); + } }; - + /** - * Chains all bodies in the given composite together using constraints. - * @method chain - * @param {composite} composite - * @param {number} xOffsetA - * @param {number} yOffsetA - * @param {number} xOffsetB - * @param {number} yOffsetB - * @param {object} options - * @return {composite} A new composite containing objects chained together with constraints + * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged. + * @method setAngle + * @param {body} body + * @param {number} angle + * @param {boolean} updateVelocity */ - Composites.chain = function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) { - var bodies = composite.bodies; - - for (var i = 1; i < bodies.length; i++) { - var bodyA = bodies[i - 1], - bodyB = bodies[i], - bodyAHeight = bodyA.bounds.max.y - bodyA.bounds.min.y, - bodyAWidth = bodyA.bounds.max.x - bodyA.bounds.min.x, - bodyBHeight = bodyB.bounds.max.y - bodyB.bounds.min.y, - bodyBWidth = bodyB.bounds.max.x - bodyB.bounds.min.x; - - var defaults = { - bodyA: bodyA, - pointA: { x: bodyAWidth * xOffsetA, y: bodyAHeight * yOffsetA }, - bodyB: bodyB, - pointB: { x: bodyBWidth * xOffsetB, y: bodyBHeight * yOffsetB } - }; - - var constraint = Common.extend(defaults, options); - - Composite.addConstraint(composite, Constraint.create(constraint)); + Body.setAngle = function(body, angle, updateVelocity) { + var delta = angle - body.angle; + if (updateVelocity) { + body.anglePrev = body.angle; + body.angularVelocity = delta; + body.angularSpeed = Math.abs(delta); + } else { + body.anglePrev += delta; } - composite.label += ' Chain'; - - return composite; + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; + part.angle += delta; + Vertices.rotate(part.vertices, delta, body.position); + Axes.rotate(part.axes, delta); + Bounds.update(part.bounds, part.vertices, body.velocity); + if (i > 0) { + Vector.rotateAbout(part.position, delta, body.position, part.position); + } + } }; /** - * Connects bodies in the composite with constraints in a grid pattern, with optional cross braces. - * @method mesh - * @param {composite} composite - * @param {number} columns - * @param {number} rows - * @param {boolean} crossBrace - * @param {object} options - * @return {composite} The composite containing objects meshed together with constraints + * Sets the linear velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. + * @method setVelocity + * @param {body} body + * @param {vector} velocity */ - Composites.mesh = function(composite, columns, rows, crossBrace, options) { - var bodies = composite.bodies, - row, - col, - bodyA, - bodyB, - bodyC; - - for (row = 0; row < rows; row++) { - for (col = 1; col < columns; col++) { - bodyA = bodies[(col - 1) + (row * columns)]; - bodyB = bodies[col + (row * columns)]; - Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options))); - } - - if (row > 0) { - for (col = 0; col < columns; col++) { - bodyA = bodies[col + ((row - 1) * columns)]; - bodyB = bodies[col + (row * columns)]; - Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options))); - - if (crossBrace && col > 0) { - bodyC = bodies[(col - 1) + ((row - 1) * columns)]; - Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options))); - } + Body.setVelocity = function(body, velocity) { + var timeScale = body.deltaTime / Body._baseDelta; + body.positionPrev.x = body.position.x - velocity.x * timeScale; + body.positionPrev.y = body.position.y - velocity.y * timeScale; + body.velocity.x = (body.position.x - body.positionPrev.x) / timeScale; + body.velocity.y = (body.position.y - body.positionPrev.y) / timeScale; + body.speed = Vector.magnitude(body.velocity); + }; - if (crossBrace && col < columns - 1) { - bodyC = bodies[(col + 1) + ((row - 1) * columns)]; - Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options))); - } - } - } - } + /** + * Gets the current linear velocity of the body. + * @method getVelocity + * @param {body} body + * @return {vector} velocity + */ + Body.getVelocity = function(body) { + var timeScale = Body._baseDelta / body.deltaTime; - composite.label += ' Mesh'; - - return composite; + return { + x: (body.position.x - body.positionPrev.x) * timeScale, + y: (body.position.y - body.positionPrev.y) * timeScale + }; }; - + /** - * Create a new composite containing bodies created in the callback in a pyramid arrangement. - * This function uses the body's bounds to prevent overlaps. - * @method pyramid - * @param {number} xx - * @param {number} yy - * @param {number} columns - * @param {number} rows - * @param {number} columnGap - * @param {number} rowGap - * @param {function} callback - * @return {composite} A new composite containing objects created in the callback + * Gets the current linear speed of the body. + * Equivalent to the magnitude of its velocity. + * @method getSpeed + * @param {body} body + * @return {number} speed */ - Composites.pyramid = function(xx, yy, columns, rows, columnGap, rowGap, callback) { - return Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y, column, row, lastBody, i) { - var actualRows = Math.min(rows, Math.ceil(columns / 2)), - lastBodyWidth = lastBody ? lastBody.bounds.max.x - lastBody.bounds.min.x : 0; - - if (row > actualRows) - return; - - // reverse row order - row = actualRows - row; - - var start = row, - end = columns - 1 - row; + Body.getSpeed = function(body) { + return Vector.magnitude(Body.getVelocity(body)); + }; - if (column < start || column > end) - return; - - // retroactively fix the first body's position, since width was unknown - if (i === 1) { - Body.translate(lastBody, { x: (column + (columns % 2 === 1 ? 1 : -1)) * lastBodyWidth, y: 0 }); - } + /** + * Sets the current linear speed of the body. + * Direction is maintained. Affects body velocity. + * @method setSpeed + * @param {body} body + * @param {number} speed + */ + Body.setSpeed = function(body, speed) { + Body.setVelocity(body, Vector.mult(Vector.normalise(Body.getVelocity(body)), speed)); + }; - var xOffset = lastBody ? column * lastBodyWidth : 0; - - return callback(xx + xOffset + column * columnGap, y, column, row, lastBody, i); - }); + /** + * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. + * @method setAngularVelocity + * @param {body} body + * @param {number} velocity + */ + Body.setAngularVelocity = function(body, velocity) { + var timeScale = body.deltaTime / Body._baseDelta; + body.anglePrev = body.angle - velocity * timeScale; + body.angularVelocity = (body.angle - body.anglePrev) / timeScale; + body.angularSpeed = Math.abs(body.angularVelocity); }; /** - * Creates a composite with a Newton's Cradle setup of bodies and constraints. - * @method newtonsCradle - * @param {number} xx - * @param {number} yy - * @param {number} number - * @param {number} size - * @param {number} length - * @return {composite} A new composite newtonsCradle body + * Gets the current rotational velocity of the body. + * @method getAngularVelocity + * @param {body} body + * @return {number} angular velocity */ - Composites.newtonsCradle = function(xx, yy, number, size, length) { - var newtonsCradle = Composite.create({ label: 'Newtons Cradle' }); + Body.getAngularVelocity = function(body) { + return (body.angle - body.anglePrev) * Body._baseDelta / body.deltaTime; + }; - for (var i = 0; i < number; i++) { - var separation = 1.9, - circle = Bodies.circle(xx + i * (size * separation), yy + length, size, - { inertia: Infinity, restitution: 1, friction: 0, frictionAir: 0.0001, slop: 1 }), - constraint = Constraint.create({ pointA: { x: xx + i * (size * separation), y: yy }, bodyB: circle }); + /** + * Gets the current rotational speed of the body. + * Equivalent to the magnitude of its angular velocity. + * @method getAngularSpeed + * @param {body} body + * @return {number} angular speed + */ + Body.getAngularSpeed = function(body) { + return Math.abs(Body.getAngularVelocity(body)); + }; - Composite.addBody(newtonsCradle, circle); - Composite.addConstraint(newtonsCradle, constraint); - } + /** + * Sets the current rotational speed of the body. + * Direction is maintained. Affects body angular velocity. + * @method setAngularSpeed + * @param {body} body + * @param {number} speed + */ + Body.setAngularSpeed = function(body, speed) { + Body.setAngularVelocity(body, Common.sign(Body.getAngularVelocity(body)) * speed); + }; - return newtonsCradle; + /** + * Moves a body by a given vector relative to its current position, without imparting any velocity. + * @method translate + * @param {body} body + * @param {vector} translation + * @param {boolean} [updateVelocity] + */ + Body.translate = function(body, translation, updateVelocity) { + Body.setPosition(body, Vector.add(body.position, translation), updateVelocity); }; - + /** - * Creates a composite with simple car setup of bodies and constraints. - * @method car - * @param {number} xx - * @param {number} yy - * @param {number} width - * @param {number} height - * @param {number} wheelSize - * @return {composite} A new composite car body + * Rotates a body by a given angle relative to its current angle, without imparting any angular velocity. + * @method rotate + * @param {body} body + * @param {number} rotation + * @param {vector} [point] + * @param {boolean} [updateVelocity] */ - Composites.car = function(xx, yy, width, height, wheelSize) { - var group = Body.nextGroup(true), - wheelBase = 20, - wheelAOffset = -width * 0.5 + wheelBase, - wheelBOffset = width * 0.5 - wheelBase, - wheelYOffset = 0; - - var car = Composite.create({ label: 'Car' }), - body = Bodies.rectangle(xx, yy, width, height, { - collisionFilter: { - group: group - }, - chamfer: { - radius: height * 0.5 - }, - density: 0.0002 - }); - - var wheelA = Bodies.circle(xx + wheelAOffset, yy + wheelYOffset, wheelSize, { - collisionFilter: { - group: group - }, - friction: 0.8 - }); - - var wheelB = Bodies.circle(xx + wheelBOffset, yy + wheelYOffset, wheelSize, { - collisionFilter: { - group: group - }, - friction: 0.8 - }); - - var axelA = Constraint.create({ - bodyB: body, - pointB: { x: wheelAOffset, y: wheelYOffset }, - bodyA: wheelA, - stiffness: 1, - length: 0 - }); - - var axelB = Constraint.create({ - bodyB: body, - pointB: { x: wheelBOffset, y: wheelYOffset }, - bodyA: wheelB, - stiffness: 1, - length: 0 - }); - - Composite.addBody(car, body); - Composite.addBody(car, wheelA); - Composite.addBody(car, wheelB); - Composite.addConstraint(car, axelA); - Composite.addConstraint(car, axelB); + Body.rotate = function(body, rotation, point, updateVelocity) { + if (!point) { + Body.setAngle(body, body.angle + rotation, updateVelocity); + } else { + var cos = Math.cos(rotation), + sin = Math.sin(rotation), + dx = body.position.x - point.x, + dy = body.position.y - point.y; - return car; + Body.setPosition(body, { + x: point.x + (dx * cos - dy * sin), + y: point.y + (dx * sin + dy * cos) + }, updateVelocity); + + Body.setAngle(body, body.angle + rotation, updateVelocity); + } }; /** - * Creates a simple soft body like object. - * @method softBody - * @param {number} xx - * @param {number} yy - * @param {number} columns - * @param {number} rows - * @param {number} columnGap - * @param {number} rowGap - * @param {boolean} crossBrace - * @param {number} particleRadius - * @param {} particleOptions - * @param {} constraintOptions - * @return {composite} A new composite softBody + * Scales the body, including updating physical properties (mass, area, axes, inertia), from a world-space point (default is body centre). + * @method scale + * @param {body} body + * @param {number} scaleX + * @param {number} scaleY + * @param {vector} [point] */ - Composites.softBody = function(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) { - particleOptions = Common.extend({ inertia: Infinity }, particleOptions); - constraintOptions = Common.extend({ stiffness: 0.2, render: { type: 'line', anchors: false } }, constraintOptions); + Body.scale = function(body, scaleX, scaleY, point) { + var totalArea = 0, + totalInertia = 0; - var softBody = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) { - return Bodies.circle(x, y, particleRadius, particleOptions); - }); + point = point || body.position; - Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions); + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; - softBody.label = 'Soft Body'; + part.scale.x = scaleX; + part.scale.y = scaleY; - return softBody; - }; + // scale vertices + Vertices.scale(part.vertices, scaleX, scaleY, point); -})(); + // update properties + part.axes = Axes.fromVertices(part.vertices); + part.area = Vertices.area(part.vertices); + Body.setMass(part, body.density * part.area); + // update inertia (requires vertices to be at origin) + Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y }); + Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass)); + Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y }); -/***/ }), -/* 592 */ -/***/ (function(module, exports, __webpack_require__) { + if (i > 0) { + totalArea += part.area; + totalInertia += part.inertia; + } -/** -* The `Matter.Svg` module contains methods for converting SVG images into an array of vector points. -* -* To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Svg -*/ + // scale position + part.position.x = point.x + (part.position.x - point.x) * scaleX; + part.position.y = point.y + (part.position.y - point.y) * scaleY; -var Svg = {}; + // update bounds + Bounds.update(part.bounds, part.vertices, body.velocity); + } -module.exports = Svg; + // handle parent body + if (body.parts.length > 1) { + body.area = totalArea; -var Bounds = __webpack_require__(84); -var Common = __webpack_require__(32); + if (!body.isStatic) { + Body.setMass(body, body.density * totalArea); + Body.setInertia(body, totalInertia); + } + } -(function() { + // handle circles + if (body.circleRadius) { + if (scaleX === scaleY) { + body.circleRadius *= scaleX; + } else { + // body is no longer a circle + body.circleRadius = null; + } + } + }; /** - * Converts an SVG path into an array of vector points. - * If the input path forms a concave shape, you must decompose the result into convex parts before use. - * See `Bodies.fromVertices` which provides support for this. - * Note that this function is not guaranteed to support complex paths (such as those with holes). - * You must load the `pathseg.js` polyfill on newer browsers. - * @method pathToVertices - * @param {SVGPathElement} path - * @param {Number} [sampleLength=15] - * @return {Vector[]} points + * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration. + * @method update + * @param {body} body + * @param {number} deltaTime */ - Svg.pathToVertices = function(path, sampleLength) { - if (typeof window !== 'undefined' && !('SVGPathSeg' in window)) { - Common.warn('Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.'); - } + Body.update = function(body, deltaTime) { + deltaTime = (typeof deltaTime !== 'undefined' ? deltaTime : (1000 / 60)) * body.timeScale; + var deltaTimeSquared = deltaTime * deltaTime, + correction = Body._timeCorrection ? deltaTime / (body.deltaTime || deltaTime) : 1; - // https://github.com/wout/svg.topoly.js/blob/master/svg.topoly.js - var i, il, total, point, segment, segments, - segmentsQueue, lastSegment, - lastPoint, segmentIndex, points = [], - lx, ly, length = 0, x = 0, y = 0; + // from the previous step + var frictionAir = 1 - body.frictionAir * (deltaTime / Common._baseDelta), + velocityPrevX = (body.position.x - body.positionPrev.x) * correction, + velocityPrevY = (body.position.y - body.positionPrev.y) * correction; - sampleLength = sampleLength || 15; + // update velocity with Verlet integration + body.velocity.x = (velocityPrevX * frictionAir) + (body.force.x / body.mass) * deltaTimeSquared; + body.velocity.y = (velocityPrevY * frictionAir) + (body.force.y / body.mass) * deltaTimeSquared; - var addPoint = function(px, py, pathSegType) { - // all odd-numbered path types are relative except PATHSEG_CLOSEPATH (1) - var isRelative = pathSegType % 2 === 1 && pathSegType > 1; + body.positionPrev.x = body.position.x; + body.positionPrev.y = body.position.y; + body.position.x += body.velocity.x; + body.position.y += body.velocity.y; + body.deltaTime = deltaTime; - // when the last point doesn't equal the current point add the current point - if (!lastPoint || px != lastPoint.x || py != lastPoint.y) { - if (lastPoint && isRelative) { - lx = lastPoint.x; - ly = lastPoint.y; - } else { - lx = 0; - ly = 0; - } + // update angular velocity with Verlet integration + body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared; + body.anglePrev = body.angle; + body.angle += body.angularVelocity; - var point = { - x: lx + px, - y: ly + py - }; + // track speed and acceleration + body.speed = Vector.magnitude(body.velocity); + body.angularSpeed = Math.abs(body.angularVelocity); - // set last point - if (isRelative || !lastPoint) { - lastPoint = point; - } + // transform the body geometry + for (var i = 0; i < body.parts.length; i++) { + var part = body.parts[i]; - points.push(point); + Vertices.translate(part.vertices, body.velocity); - x = lx + px; - y = ly + py; + if (i > 0) { + part.position.x += body.velocity.x; + part.position.y += body.velocity.y; } - }; - var addSegmentPoint = function(segment) { - var segType = segment.pathSegTypeAsLetter.toUpperCase(); + if (body.angularVelocity !== 0) { + Vertices.rotate(part.vertices, body.angularVelocity, body.position); + Axes.rotate(part.axes, body.angularVelocity); + if (i > 0) { + Vector.rotateAbout(part.position, body.angularVelocity, body.position, part.position); + } + } - // skip path ends - if (segType === 'Z') - return; + Bounds.update(part.bounds, part.vertices, body.velocity); + } + }; - // map segment to x and y - switch (segType) { + /** + * Updates properties `body.velocity`, `body.speed`, `body.angularVelocity` and `body.angularSpeed` which are normalised in relation to `Body._baseDelta`. + * @method updateVelocities + * @param {body} body + */ + Body.updateVelocities = function(body) { + var timeScale = Body._baseDelta / body.deltaTime, + bodyVelocity = body.velocity; - case 'M': - case 'L': - case 'T': - case 'C': - case 'S': - case 'Q': - x = segment.x; - y = segment.y; - break; - case 'H': - x = segment.x; - break; - case 'V': - y = segment.y; - break; - } + bodyVelocity.x = (body.position.x - body.positionPrev.x) * timeScale; + bodyVelocity.y = (body.position.y - body.positionPrev.y) * timeScale; + body.speed = Math.sqrt((bodyVelocity.x * bodyVelocity.x) + (bodyVelocity.y * bodyVelocity.y)); - addPoint(x, y, segment.pathSegType); + body.angularVelocity = (body.angle - body.anglePrev) * timeScale; + body.angularSpeed = Math.abs(body.angularVelocity); + }; + + /** + * Applies a force to a body from a given world-space position, including resulting torque. + * @method applyForce + * @param {body} body + * @param {vector} position + * @param {vector} force + */ + Body.applyForce = function(body, position, force) { + var offset = { x: position.x - body.position.x, y: position.y - body.position.y }; + body.force.x += force.x; + body.force.y += force.y; + body.torque += offset.x * force.y - offset.y * force.x; + }; + + /** + * Returns the sums of the properties of all compound parts of the parent body. + * @method _totalProperties + * @private + * @param {body} body + * @return {} + */ + Body._totalProperties = function(body) { + // from equations at: + // https://ecourses.ou.edu/cgi-bin/ebook.cgi?doc=&topic=st&chap_sec=07.2&page=theory + // http://output.to/sideway/default.asp?qno=121100087 + + var properties = { + mass: 0, + area: 0, + inertia: 0, + centre: { x: 0, y: 0 } }; - // ensure path is absolute - Svg._svgPathToAbsolute(path); + // sum the properties of all compound parts of the parent body + for (var i = body.parts.length === 1 ? 0 : 1; i < body.parts.length; i++) { + var part = body.parts[i], + mass = part.mass !== Infinity ? part.mass : 1; - // get total length - total = path.getTotalLength(); + properties.mass += mass; + properties.area += part.area; + properties.inertia += part.inertia; + properties.centre = Vector.add(properties.centre, Vector.mult(part.position, mass)); + } - // queue segments - segments = []; - for (i = 0; i < path.pathSegList.numberOfItems; i += 1) - segments.push(path.pathSegList.getItem(i)); + properties.centre = Vector.div(properties.centre, properties.mass); - segmentsQueue = segments.concat(); + return properties; + }; - // sample through path - while (length < total) { - // get segment at position - segmentIndex = path.getPathSegAtLength(length); - segment = segments[segmentIndex]; + /* + * + * Events Documentation + * + */ - // new segment - if (segment != lastSegment) { - while (segmentsQueue.length && segmentsQueue[0] != segment) - addSegmentPoint(segmentsQueue.shift()); + /** + * Fired when a body starts sleeping (where `this` is the body). + * + * @event sleepStart + * @this {body} The body that has started sleeping + * @param {} event An event object + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ - lastSegment = segment; - } + /** + * Fired when a body ends sleeping (where `this` is the body). + * + * @event sleepEnd + * @this {body} The body that has ended sleeping + * @param {} event An event object + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ - // add points in between when curving - // TODO: adaptive sampling - switch (segment.pathSegTypeAsLetter.toUpperCase()) { + /* + * + * Properties Documentation + * + */ - case 'C': - case 'T': - case 'S': - case 'Q': - case 'A': - point = path.getPointAtLength(length); - addPoint(point.x, point.y, 0); - break; + /** + * An integer `Number` uniquely identifying number generated in `Body.create` by `Common.nextId`. + * + * @property id + * @type number + */ - } + /** + * A `String` denoting the type of object. + * + * @property type + * @type string + * @default "body" + * @readOnly + */ - // increment by sample value - length += sampleLength; - } + /** + * An arbitrary `String` name to help the user identify and manage bodies. + * + * @property label + * @type string + * @default "Body" + */ - // add remaining segments not passed by sampling - for (i = 0, il = segmentsQueue.length; i < il; ++i) - addSegmentPoint(segmentsQueue[i]); + /** + * An array of bodies that make up this body. + * The first body in the array must always be a self reference to the current body instance. + * All bodies in the `parts` array together form a single rigid compound body. + * Parts are allowed to overlap, have gaps or holes or even form concave bodies. + * Parts themselves should never be added to a `World`, only the parent body should be. + * Use `Body.setParts` when setting parts to ensure correct updates of all properties. + * + * @property parts + * @type body[] + */ - return points; - }; + /** + * An object reserved for storing plugin-specific properties. + * + * @property plugin + * @type {} + */ - Svg._svgPathToAbsolute = function(path) { - // http://phrogz.net/convert-svg-path-to-all-absolute-commands - // Copyright (c) Gavin Kistner - // http://phrogz.net/js/_ReuseLicense.txt - // Modifications: tidy formatting and naming - var x0, y0, x1, y1, x2, y2, segs = path.pathSegList, - x = 0, y = 0, len = segs.numberOfItems; + /** + * A self reference if the body is _not_ a part of another body. + * Otherwise this is a reference to the body that this is a part of. + * See `body.parts`. + * + * @property parent + * @type body + */ - for (var i = 0; i < len; ++i) { - var seg = segs.getItem(i), - segType = seg.pathSegTypeAsLetter; + /** + * A `Number` specifying the angle of the body, in radians. + * + * @property angle + * @type number + * @default 0 + */ - if (/[MLHVCSQTA]/.test(segType)) { - if ('x' in seg) x = seg.x; - if ('y' in seg) y = seg.y; - } else { - if ('x1' in seg) x1 = x + seg.x1; - if ('x2' in seg) x2 = x + seg.x2; - if ('y1' in seg) y1 = y + seg.y1; - if ('y2' in seg) y2 = y + seg.y2; - if ('x' in seg) x += seg.x; - if ('y' in seg) y += seg.y; + /** + * An array of `Vector` objects that specify the convex hull of the rigid body. + * These should be provided about the origin `(0, 0)`. E.g. + * + * [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }] + * + * When passed via `Body.create`, the vertices are translated relative to `body.position` (i.e. world-space, and constantly updated by `Body.update` during simulation). + * The `Vector` objects are also augmented with additional properties required for efficient collision detection. + * + * Other properties such as `inertia` and `bounds` are automatically calculated from the passed vertices (unless provided via `options`). + * Concave hulls are not currently supported. The module `Matter.Vertices` contains useful methods for working with vertices. + * + * @property vertices + * @type vector[] + */ - switch (segType) { + /** + * A `Vector` that specifies the current world-space position of the body. + * + * @property position + * @type vector + * @default { x: 0, y: 0 } + */ - case 'm': - segs.replaceItem(path.createSVGPathSegMovetoAbs(x, y), i); - break; - case 'l': - segs.replaceItem(path.createSVGPathSegLinetoAbs(x, y), i); - break; - case 'h': - segs.replaceItem(path.createSVGPathSegLinetoHorizontalAbs(x), i); - break; - case 'v': - segs.replaceItem(path.createSVGPathSegLinetoVerticalAbs(y), i); - break; - case 'c': - segs.replaceItem(path.createSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2), i); - break; - case 's': - segs.replaceItem(path.createSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2), i); - break; - case 'q': - segs.replaceItem(path.createSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1), i); - break; - case 't': - segs.replaceItem(path.createSVGPathSegCurvetoQuadraticSmoothAbs(x, y), i); - break; - case 'a': - segs.replaceItem(path.createSVGPathSegArcAbs(x, y, seg.r1, seg.r2, seg.angle, seg.largeArcFlag, seg.sweepFlag), i); - break; - case 'z': - case 'Z': - x = x0; - y = y0; - break; + /** + * A `Vector` that holds the current scale values as set by `Body.setScale`. + * + * @property scale + * @type vector + * @default { x: 1, y: 1 } + */ - } - } + /** + * A `Vector` that specifies the force to apply in the current step. It is zeroed after every `Body.update`. See also `Body.applyForce`. + * + * @property force + * @type vector + * @default { x: 0, y: 0 } + */ - if (segType == 'M' || segType == 'm') { - x0 = x; - y0 = y; - } - } - }; + /** + * A `Number` that specifies the torque (turning force) to apply in the current step. It is zeroed after every `Body.update`. + * + * @property torque + * @type number + * @default 0 + */ -})(); + /** + * A `Number` that _measures_ the current speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.velocity`). + * + * @readOnly + * @property speed + * @type number + * @default 0 + */ -/***/ }), -/* 593 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * A `Number` that _measures_ the current angular speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.angularVelocity`). + * + * @readOnly + * @property angularSpeed + * @type number + * @default 0 + */ -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * A `Vector` that _measures_ the current velocity of the body after the last `Body.update`. It is read-only. + * If you need to modify a body's velocity directly, you should either apply a force or simply change the body's `position` (as the engine uses position-Verlet integration). + * + * @readOnly + * @property velocity + * @type vector + * @default { x: 0, y: 0 } + */ -var Bodies = __webpack_require__(86); -var Body = __webpack_require__(41); -var Class = __webpack_require__(0); -var Components = __webpack_require__(249); -var EventEmitter = __webpack_require__(9); -var GetFastValue = __webpack_require__(2); -var HasValue = __webpack_require__(126); -var Vertices = __webpack_require__(64); + /** + * A `Number` that _measures_ the current angular velocity of the body after the last `Body.update`. It is read-only. + * If you need to modify a body's angular velocity directly, you should apply a torque or simply change the body's `angle` (as the engine uses position-Verlet integration). + * + * @readOnly + * @property angularVelocity + * @type number + * @default 0 + */ -/** - * @classdesc - * A wrapper around a Tile that provides access to a corresponding Matter body. A tile can only - * have one Matter body associated with it. You can either pass in an existing Matter body for - * the tile or allow the constructor to create the corresponding body for you. If the Tile has a - * collision group (defined in Tiled), those shapes will be used to create the body. If not, the - * tile's rectangle bounding box will be used. - * - * The corresponding body will be accessible on the Tile itself via Tile.physics.matterBody. - * - * Note: not all Tiled collision shapes are supported. See - * Phaser.Physics.Matter.TileBody#setFromTileCollision for more information. - * - * @class TileBody - * @memberof Phaser.Physics.Matter - * @extends Phaser.Events.EventEmitter - * @constructor - * @since 3.0.0 - * - * @extends Phaser.Physics.Matter.Components.Bounce - * @extends Phaser.Physics.Matter.Components.Collision - * @extends Phaser.Physics.Matter.Components.Friction - * @extends Phaser.Physics.Matter.Components.Gravity - * @extends Phaser.Physics.Matter.Components.Mass - * @extends Phaser.Physics.Matter.Components.Sensor - * @extends Phaser.Physics.Matter.Components.Sleep - * @extends Phaser.Physics.Matter.Components.Static - * - * @param {Phaser.Physics.Matter.World} world - The Matter world instance this body belongs to. - * @param {Phaser.Tilemaps.Tile} tile - The target tile that should have a Matter body. - * @param {Phaser.Types.Physics.Matter.MatterTileOptions} [options] - Options to be used when creating the Matter body. - */ -var MatterTileBody = new Class({ + /** + * A flag that indicates whether a body is considered static. A static body can never change position or angle and is completely fixed. + * If you need to set a body as static after its creation, you should use `Body.setStatic` as this requires more than just setting this flag. + * + * @property isStatic + * @type boolean + * @default false + */ - Extends: EventEmitter, + /** + * A flag that indicates whether a body is a sensor. Sensor triggers collision events, but doesn't react with colliding body physically. + * + * @property isSensor + * @type boolean + * @default false + */ - Mixins: [ - Components.Bounce, - Components.Collision, - Components.Friction, - Components.Gravity, - Components.Mass, - Components.Sensor, - Components.Sleep, - Components.Static - ], + /** + * A flag that indicates whether the body is considered sleeping. A sleeping body acts similar to a static body, except it is only temporary and can be awoken. + * If you need to set a body as sleeping, you should use `Sleeping.set` as this requires more than just setting this flag. + * + * @property isSleeping + * @type boolean + * @default false + */ - initialize: + /** + * A `Number` that _measures_ the amount of movement a body currently has (a combination of `speed` and `angularSpeed`). It is read-only and always positive. + * It is used and updated by the `Matter.Sleeping` module during simulation to decide if a body has come to rest. + * + * @readOnly + * @property motion + * @type number + * @default 0 + */ - function MatterTileBody (world, tile, options) - { - EventEmitter.call(this); + /** + * A `Number` that defines the number of updates in which this body must have near-zero velocity before it is set as sleeping by the `Matter.Sleeping` module (if sleeping is enabled by the engine). + * + * @property sleepThreshold + * @type number + * @default 60 + */ - /** - * The tile object the body is associated with. - * - * @name Phaser.Physics.Matter.TileBody#tile - * @type {Phaser.Tilemaps.Tile} - * @since 3.0.0 - */ - this.tile = tile; + /** + * A `Number` that defines the density of the body, that is its mass per unit area. + * If you pass the density via `Body.create` the `mass` property is automatically calculated for you based on the size (area) of the object. + * This is generally preferable to simply setting mass and allows for more intuitive definition of materials (e.g. rock has a higher density than wood). + * + * @property density + * @type number + * @default 0.001 + */ - /** - * The Matter world the body exists within. - * - * @name Phaser.Physics.Matter.TileBody#world - * @type {Phaser.Physics.Matter.World} - * @since 3.0.0 - */ - this.world = world; + /** + * A `Number` that defines the mass of the body, although it may be more appropriate to specify the `density` property instead. + * If you modify this value, you must also modify the `body.inverseMass` property (`1 / mass`). + * + * @property mass + * @type number + */ - // Install a reference to 'this' on the tile and ensure there can only be one matter body - // associated with the tile - if (tile.physics.matterBody) - { - tile.physics.matterBody.destroy(); - } + /** + * A `Number` that defines the inverse mass of the body (`1 / mass`). + * If you modify this value, you must also modify the `body.mass` property. + * + * @property inverseMass + * @type number + */ - tile.physics.matterBody = this; + /** + * A `Number` that defines the moment of inertia (i.e. second moment of area) of the body. + * It is automatically calculated from the given convex hull (`vertices` array) and density in `Body.create`. + * If you modify this value, you must also modify the `body.inverseInertia` property (`1 / inertia`). + * + * @property inertia + * @type number + */ - // Set the body either from an existing body (if provided), the shapes in the tileset - // collision layer (if it exists) or a rectangle matching the tile. - var body = GetFastValue(options, 'body', null); + /** + * A `Number` that defines the inverse moment of inertia of the body (`1 / inertia`). + * If you modify this value, you must also modify the `body.inertia` property. + * + * @property inverseInertia + * @type number + */ - var addToWorld = GetFastValue(options, 'addToWorld', true); + /** + * A `Number` that defines the restitution (elasticity) of the body. The value is always positive and is in the range `(0, 1)`. + * A value of `0` means collisions may be perfectly inelastic and no bouncing may occur. + * A value of `0.8` means the body may bounce back with approximately 80% of its kinetic energy. + * Note that collision response is based on _pairs_ of bodies, and that `restitution` values are _combined_ with the following formula: + * + * Math.max(bodyA.restitution, bodyB.restitution) + * + * @property restitution + * @type number + * @default 0 + */ - if (!body) - { - var collisionGroup = tile.getCollisionGroup(); - var collisionObjects = GetFastValue(collisionGroup, 'objects', []); + /** + * A `Number` that defines the friction of the body. The value is always positive and is in the range `(0, 1)`. + * A value of `0` means that the body may slide indefinitely. + * A value of `1` means the body may come to a stop almost instantly after a force is applied. + * + * The effects of the value may be non-linear. + * High values may be unstable depending on the body. + * The engine uses a Coulomb friction model including static and kinetic friction. + * Note that collision response is based on _pairs_ of bodies, and that `friction` values are _combined_ with the following formula: + * + * Math.min(bodyA.friction, bodyB.friction) + * + * @property friction + * @type number + * @default 0.1 + */ - if (collisionObjects.length > 0) - { - this.setFromTileCollision(options); - } - else - { - this.setFromTileRectangle(options); - } - } - else - { - this.setBody(body, addToWorld); - } - }, + /** + * A `Number` that defines the static friction of the body (in the Coulomb friction model). + * A value of `0` means the body will never 'stick' when it is nearly stationary and only dynamic `friction` is used. + * The higher the value (e.g. `10`), the more force it will take to initially get the body moving when nearly stationary. + * This value is multiplied with the `friction` property to make it easier to change `friction` and maintain an appropriate amount of static friction. + * + * @property frictionStatic + * @type number + * @default 0.5 + */ + + /** + * A `Number` that defines the air friction of the body (air resistance). + * A value of `0` means the body will never slow as it moves through space. + * The higher the value, the faster a body slows when moving through space. + * The effects of the value are non-linear. + * + * @property frictionAir + * @type number + * @default 0.01 + */ + + /** + * An `Object` that specifies the collision filtering properties of this body. + * + * Collisions between two bodies will obey the following rules: + * - If the two bodies have the same non-zero value of `collisionFilter.group`, + * they will always collide if the value is positive, and they will never collide + * if the value is negative. + * - If the two bodies have different values of `collisionFilter.group` or if one + * (or both) of the bodies has a value of 0, then the category/mask rules apply as follows: + * + * Each body belongs to a collision category, given by `collisionFilter.category`. This + * value is used as a bit field and the category should have only one bit set, meaning that + * the value of this property is a power of two in the range [1, 2^31]. Thus, there are 32 + * different collision categories available. + * + * Each body also defines a collision bitmask, given by `collisionFilter.mask` which specifies + * the categories it collides with (the value is the bitwise AND value of all these categories). + * + * Using the category/mask rules, two bodies `A` and `B` collide if each includes the other's + * category in its mask, i.e. `(categoryA & maskB) !== 0` and `(categoryB & maskA) !== 0` + * are both true. + * + * @property collisionFilter + * @type object + */ + + /** + * An Integer `Number`, that specifies the collision group this body belongs to. + * See `body.collisionFilter` for more information. + * + * @property collisionFilter.group + * @type object + * @default 0 + */ + + /** + * A bit field that specifies the collision category this body belongs to. + * The category value should have only one bit set, for example `0x0001`. + * This means there are up to 32 unique collision categories available. + * See `body.collisionFilter` for more information. + * + * @property collisionFilter.category + * @type object + * @default 1 + */ /** - * Sets the current body to a rectangle that matches the bounds of the tile. - * - * @method Phaser.Physics.Matter.TileBody#setFromTileRectangle - * @since 3.0.0 + * A bit mask that specifies the collision categories this body may collide with. + * See `body.collisionFilter` for more information. * - * @param {Phaser.Types.Physics.Matter.MatterBodyTileOptions} [options] - Options to be used when creating the Matter body. See MatterJS.Body for a list of what Matter accepts. - * - * @return {Phaser.Physics.Matter.TileBody} This TileBody object. + * @property collisionFilter.mask + * @type object + * @default -1 */ - setFromTileRectangle: function (options) - { - if (options === undefined) { options = {}; } - if (!HasValue(options, 'isStatic')) { options.isStatic = true; } - if (!HasValue(options, 'addToWorld')) { options.addToWorld = true; } - - var bounds = this.tile.getBounds(); - var cx = bounds.x + (bounds.width / 2); - var cy = bounds.y + (bounds.height / 2); - var body = Bodies.rectangle(cx, cy, bounds.width, bounds.height, options); - - this.setBody(body, options.addToWorld); - - return this; - }, /** - * Sets the current body from the collision group associated with the Tile. This is typically - * set up in Tiled's collision editor. + * A `Number` that specifies a tolerance on how far a body is allowed to 'sink' or rotate into other bodies. + * Avoid changing this value unless you understand the purpose of `slop` in physics engines. + * The default should generally suffice, although very large bodies may require larger values for stable stacking. * - * Note: Matter doesn't support all shapes from Tiled. Rectangles and polygons are directly - * supported. Ellipses are converted into circle bodies. Polylines are treated as if they are - * closed polygons. If a tile has multiple shapes, a multi-part body will be created. Concave - * shapes are supported if poly-decomp library is included. Decomposition is not guaranteed to - * work for complex shapes (e.g. holes), so it's often best to manually decompose a concave - * polygon into multiple convex polygons yourself. + * @property slop + * @type number + * @default 0.05 + */ + + /** + * A `Number` that allows per-body time scaling, e.g. a force-field where bodies inside are in slow-motion, while others are at full speed. * - * @method Phaser.Physics.Matter.TileBody#setFromTileCollision - * @since 3.0.0 + * @property timeScale + * @type number + * @default 1 + */ + + /** + * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`. * - * @param {Phaser.Types.Physics.Matter.MatterBodyTileOptions} [options] - Options to be used when creating the Matter body. See MatterJS.Body for a list of what Matter accepts. - * - * @return {Phaser.Physics.Matter.TileBody} This TileBody object. + * @property render + * @type object */ - setFromTileCollision: function (options) - { - if (options === undefined) { options = {}; } - if (!HasValue(options, 'isStatic')) { options.isStatic = true; } - if (!HasValue(options, 'addToWorld')) { options.addToWorld = true; } - var sx = this.tile.tilemapLayer.scaleX; - var sy = this.tile.tilemapLayer.scaleY; - var tileX = this.tile.getLeft(); - var tileY = this.tile.getTop(); - var collisionGroup = this.tile.getCollisionGroup(); - var collisionObjects = GetFastValue(collisionGroup, 'objects', []); + /** + * A flag that indicates if the body should be rendered. + * + * @property render.visible + * @type boolean + * @default true + */ - var parts = []; + /** + * Sets the opacity to use when rendering. + * + * @property render.opacity + * @type number + * @default 1 + */ - for (var i = 0; i < collisionObjects.length; i++) - { - var object = collisionObjects[i]; - var ox = tileX + (object.x * sx); - var oy = tileY + (object.y * sy); - var ow = object.width * sx; - var oh = object.height * sy; - var body = null; + /** + * An `Object` that defines the sprite properties to use when rendering, if any. + * + * @property render.sprite + * @type object + */ - if (object.rectangle) - { - body = Bodies.rectangle(ox + ow / 2, oy + oh / 2, ow, oh, options); - } - else if (object.ellipse) - { - body = Bodies.circle(ox + ow / 2, oy + oh / 2, ow / 2, options); - } - else if (object.polygon || object.polyline) - { - // Polygons and polylines are both treated as closed polygons - var originalPoints = object.polygon ? object.polygon : object.polyline; + /** + * A `Number` that defines the offset in the x-axis for the sprite (normalised by texture width). + * + * @property render.sprite.xOffset + * @type number + * @default 0 + */ - var points = originalPoints.map(function (p) - { - return { x: p.x * sx, y: p.y * sy }; - }); + /** + * A `Number` that defines the offset in the y-axis for the sprite (normalised by texture height). + * + * @property render.sprite.yOffset + * @type number + * @default 0 + */ - var vertices = Vertices.create(points); + /** + * A hex color value that defines the fill color to use when rendering the body. + * + * @property render.fillColor + * @type number + */ - // Points are relative to the object's origin (first point placed in Tiled), but - // matter expects points to be relative to the center of mass. This only applies to - // convex shapes. When a concave shape is decomposed, multiple parts are created and - // the individual parts are positioned relative to (ox, oy). - // - // Update: 8th January 2019 - the latest version of Matter needs the Vertices adjusted, - // regardless if convex or concave. + /** + * A value that defines the fill opacity to use when rendering the body. + * + * @property render.fillOpacity + * @type number + */ - var center = Vertices.centre(vertices); + /** + * A hex color value that defines the line color to use when rendering the body. + * + * @property render.lineColor + * @type number + */ - ox += center.x; - oy += center.y; + /** + * A value that defines the line opacity to use when rendering the body. + * + * @property render.lineOpacity + * @type number + */ - body = Bodies.fromVertices(ox, oy, vertices, options); - } + /** + * A `Number` that defines the line width to use when rendering the body outline. + * + * @property render.lineThickness + * @type number + */ - if (body) - { - parts.push(body); - } - } + /** + * An array of unique axis vectors (edge normals) used for collision detection. + * These are automatically calculated from the given convex hull (`vertices` array) in `Body.create`. + * They are constantly updated by `Body.update` during the simulation. + * + * @property axes + * @type vector[] + */ - if (parts.length === 1) - { - this.setBody(parts[0], options.addToWorld); - } - else if (parts.length > 1) - { - options.parts = parts; - this.setBody(Body.create(options), options.addToWorld); - } + /** + * A `Number` that _measures_ the area of the body's convex hull, calculated at creation by `Body.create`. + * + * @property area + * @type string + * @default + */ - return this; - }, + /** + * A `Bounds` object that defines the AABB region for the body. + * It is automatically calculated from the given convex hull (`vertices` array) in `Body.create` and constantly updated by `Body.update` during simulation. + * + * @property bounds + * @type bounds + */ /** - * Sets the current body to the given body. This will remove the previous body, if one already - * exists. + * A reference to the Phaser Game Object this body belongs to, if any. * - * @method Phaser.Physics.Matter.TileBody#setBody - * @since 3.0.0 + * @property gameObject + * @type Phaser.GameObjects.GameObject + */ + + /** + * The center of mass of the Body. * - * @param {MatterJS.BodyType} body - The new Matter body to use. - * @param {boolean} [addToWorld=true] - Whether or not to add the body to the Matter world. - * - * @return {Phaser.Physics.Matter.TileBody} This TileBody object. + * @property centerOfMass + * @type vector + * @default { x: 0, y: 0 } */ - setBody: function (body, addToWorld) - { - if (addToWorld === undefined) { addToWorld = true; } - if (this.body) - { - this.removeBody(); - } + /** + * The center of the body in pixel values. + * Used by Phaser for texture aligment. + * + * @property centerOffset + * @type vector + * @default { x: 0, y: 0 } + */ - this.body = body; - this.body.gameObject = this; + /** + * Will this Body ignore World gravity during the Engine update? + * + * @property ignoreGravity + * @type boolean + * @default false + */ - if (addToWorld) - { - this.world.add(this.body); - } + /** + * Scale the influence of World gravity when applied to this body. + * + * @property gravityScale + * @type vector + * @default { x: 1, y: 1 } + */ - return this; - }, + /** + * Will this Body ignore Phaser Pointer input events? + * + * @property ignorePointer + * @type boolean + * @default false + */ /** - * Removes the current body from the TileBody and from the Matter world + * A callback that is invoked when this Body starts colliding with any other Body. * - * @method Phaser.Physics.Matter.TileBody#removeBody - * @since 3.0.0 + * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. * - * @return {Phaser.Physics.Matter.TileBody} This TileBody object. + * @property onCollideCallback + * @type function + * @default null */ - removeBody: function () - { - if (this.body) - { - this.world.remove(this.body); - this.body.gameObject = undefined; - this.body = undefined; - } - return this; - }, + /** + * A callback that is invoked when this Body stops colliding with any other Body. + * + * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. + * + * @property onCollideEndCallback + * @type function + * @default null + */ /** - * Removes the current body from the tile and the world. + * A callback that is invoked for the duration that this Body is colliding with any other Body. * - * @method Phaser.Physics.Matter.TileBody#destroy - * @since 3.0.0 + * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. * - * @return {Phaser.Physics.Matter.TileBody} This TileBody object. + * @property onCollideActiveCallback + * @type function + * @default null */ - destroy: function () - { - this.removeBody(); - this.tile.physics.matterBody = undefined; - this.removeAllListeners(); - } -}); + /** + * A collision callback dictionary used by the `Body.setOnCollideWith` function. + * + * @property onCollideWith + * @type object + * @default null + */ -module.exports = MatterTileBody; +})(); /***/ }), -/* 594 */ -/***/ (function(module, exports, __webpack_require__) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 11299: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @namespace Phaser.Physics.Matter.Matter - */ +* The `Matter.Composite` module contains methods for creating and manipulating composite bodies. +* A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure. +* It is important to use the functions in this module to modify composites, rather than directly modifying their properties. +* Note that the `Matter.World` object is also a type of `Matter.Composite` and as such all composite methods here can also operate on a `Matter.World`. +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Composite +*/ -var Matter = __webpack_require__(1399); +var Composite = {}; -Matter.Body = __webpack_require__(41); -Matter.Composite = __webpack_require__(118); -Matter.World = __webpack_require__(596); +module.exports = Composite; -Matter.Detector = __webpack_require__(273); -Matter.Grid = __webpack_require__(597); -Matter.Pairs = __webpack_require__(598); -Matter.Pair = __webpack_require__(250); -Matter.Query = __webpack_require__(1400); -Matter.Resolver = __webpack_require__(599); -Matter.SAT = __webpack_require__(274); +var Events = __webpack_require__(39073); +var Common = __webpack_require__(68758); +var Bounds = __webpack_require__(84091); +var Body = __webpack_require__(84125); -Matter.Constraint = __webpack_require__(128); +(function() { -Matter.Common = __webpack_require__(32); -Matter.Engine = __webpack_require__(1401); -Matter.Events = __webpack_require__(166); -Matter.Sleeping = __webpack_require__(165); -Matter.Plugin = __webpack_require__(595); + /** + * Creates a new composite. The options parameter is an object that specifies any properties you wish to override the defaults. + * See the properites section below for detailed information on what you can pass via the `options` object. + * @method create + * @param {} [options] + * @return {composite} A new composite + */ + Composite.create = function(options) { + return Common.extend({ + id: Common.nextId(), + type: 'composite', + parent: null, + isModified: false, + bodies: [], + constraints: [], + composites: [], + label: 'Composite', + plugin: {}, + cache: { + allBodies: null, + allConstraints: null, + allComposites: null + } + }, options); + }; -Matter.Bodies = __webpack_require__(86); -Matter.Composites = __webpack_require__(591); + /** + * Sets the composite's `isModified` flag. + * If `updateParents` is true, all parents will be set (default: false). + * If `updateChildren` is true, all children will be set (default: false). + * @method setModified + * @param {composite} composite + * @param {boolean} isModified + * @param {boolean} [updateParents=false] + * @param {boolean} [updateChildren=false] + */ + Composite.setModified = function(composite, isModified, updateParents, updateChildren) { -Matter.Axes = __webpack_require__(271); -Matter.Bounds = __webpack_require__(84); -Matter.Svg = __webpack_require__(592); -Matter.Vector = __webpack_require__(83); -Matter.Vertices = __webpack_require__(64); + Events.trigger(composite, 'compositeModified', composite); -// aliases + composite.isModified = isModified; -Matter.World.add = Matter.Composite.add; -Matter.World.remove = Matter.Composite.remove; -Matter.World.addComposite = Matter.Composite.addComposite; -Matter.World.addBody = Matter.Composite.addBody; -Matter.World.addConstraint = Matter.Composite.addConstraint; -Matter.World.clear = Matter.Composite.clear; + if (isModified && composite.cache) { + composite.cache.allBodies = null; + composite.cache.allConstraints = null; + composite.cache.allComposites = null; + } -module.exports = Matter; + if (updateParents && composite.parent) { + Composite.setModified(composite.parent, isModified, updateParents, updateChildren); + } + if (updateChildren) { + for (var i = 0; i < composite.composites.length; i++) { + var childComposite = composite.composites[i]; + Composite.setModified(childComposite, isModified, updateParents, updateChildren); + } + } + }; -/***/ }), -/* 595 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Generic single or multi-add function. Adds a single or an array of body(s), constraint(s) or composite(s) to the given composite. + * Triggers `beforeAdd` and `afterAdd` events on the `composite`. + * @method add + * @param {composite} composite + * @param {object|array} object A single or an array of body(s), constraint(s) or composite(s) + * @return {composite} The original composite with the objects added + */ + Composite.add = function(composite, object) { + var objects = [].concat(object); -/** -* The `Matter.Plugin` module contains functions for registering and installing plugins on modules. -* -* @class Plugin -*/ + Events.trigger(composite, 'beforeAdd', { object: object }); -var Plugin = {}; + for (var i = 0; i < objects.length; i++) { + var obj = objects[i]; -module.exports = Plugin; + switch (obj.type) { + + case 'body': + // skip adding compound parts + if (obj.parent !== obj) { + Common.warn('Composite.add: skipped adding a compound body part (you must add its parent instead)'); + break; + } -var Common = __webpack_require__(32); + Composite.addBody(composite, obj); + break; + case 'constraint': + Composite.addConstraint(composite, obj); + break; + case 'composite': + Composite.addComposite(composite, obj); + break; + case 'mouseConstraint': + Composite.addConstraint(composite, obj.constraint); + break; -(function() { + } + } - Plugin._registry = {}; + Events.trigger(composite, 'afterAdd', { object: object }); + + return composite; + }; /** - * Registers a plugin object so it can be resolved later by name. - * @method register - * @param plugin {} The plugin to register. - * @return {object} The plugin. + * Generic remove function. Removes one or many body(s), constraint(s) or a composite(s) to the given composite. + * Optionally searching its children recursively. + * Triggers `beforeRemove` and `afterRemove` events on the `composite`. + * @method remove + * @param {composite} composite + * @param {object|array} object + * @param {boolean} [deep=false] + * @return {composite} The original composite with the objects removed */ - Plugin.register = function(plugin) { - if (!Plugin.isPlugin(plugin)) { - Common.warn('Plugin.register:', Plugin.toString(plugin), 'does not implement all required fields.'); - } + Composite.remove = function(composite, object, deep) { + var objects = [].concat(object); - if (plugin.name in Plugin._registry) { - var registered = Plugin._registry[plugin.name], - pluginVersion = Plugin.versionParse(plugin.version).number, - registeredVersion = Plugin.versionParse(registered.version).number; + Events.trigger(composite, 'beforeRemove', { object: object }); + + for (var i = 0; i < objects.length; i++) { + var obj = objects[i]; + + switch (obj.type) { + + case 'body': + Composite.removeBody(composite, obj, deep); + break; + case 'constraint': + Composite.removeConstraint(composite, obj, deep); + break; + case 'composite': + Composite.removeComposite(composite, obj, deep); + break; + case 'mouseConstraint': + Composite.removeConstraint(composite, obj.constraint); + break; - if (pluginVersion > registeredVersion) { - Common.warn('Plugin.register:', Plugin.toString(registered), 'was upgraded to', Plugin.toString(plugin)); - Plugin._registry[plugin.name] = plugin; - } else if (pluginVersion < registeredVersion) { - Common.warn('Plugin.register:', Plugin.toString(registered), 'can not be downgraded to', Plugin.toString(plugin)); - } else if (plugin !== registered) { - Common.warn('Plugin.register:', Plugin.toString(plugin), 'is already registered to different plugin object'); } - } else { - Plugin._registry[plugin.name] = plugin; } - return plugin; + Events.trigger(composite, 'afterRemove', { object: object }); + + return composite; }; /** - * Resolves a dependency to a plugin object from the registry if it exists. - * The `dependency` may contain a version, but only the name matters when resolving. - * @method resolve - * @param dependency {string} The dependency. - * @return {object} The plugin if resolved, otherwise `undefined`. + * Adds a composite to the given composite. + * @private + * @method addComposite + * @param {composite} compositeA + * @param {composite} compositeB + * @return {composite} The original compositeA with the objects from compositeB added */ - Plugin.resolve = function(dependency) { - return Plugin._registry[Plugin.dependencyParse(dependency).name]; + Composite.addComposite = function(compositeA, compositeB) { + compositeA.composites.push(compositeB); + compositeB.parent = compositeA; + Composite.setModified(compositeA, true, true, false); + return compositeA; }; /** - * Returns a pretty printed plugin name and version. - * @method toString - * @param plugin {} The plugin. - * @return {string} Pretty printed plugin name and version. + * Removes a composite from the given composite, and optionally searching its children recursively. + * @private + * @method removeComposite + * @param {composite} compositeA + * @param {composite} compositeB + * @param {boolean} [deep=false] + * @return {composite} The original compositeA with the composite removed */ - Plugin.toString = function(plugin) { - return typeof plugin === 'string' ? plugin : (plugin.name || 'anonymous') + '@' + (plugin.version || plugin.range || '0.0.0'); + Composite.removeComposite = function(compositeA, compositeB, deep) { + var position = Common.indexOf(compositeA.composites, compositeB); + if (position !== -1) { + Composite.removeCompositeAt(compositeA, position); + } + + if (deep) { + for (var i = 0; i < compositeA.composites.length; i++){ + Composite.removeComposite(compositeA.composites[i], compositeB, true); + } + } + + return compositeA; }; /** - * Returns `true` if the object meets the minimum standard to be considered a plugin. - * This means it must define the following properties: - * - `name` - * - `version` - * - `install` - * @method isPlugin - * @param obj {} The obj to test. - * @return {boolean} `true` if the object can be considered a plugin otherwise `false`. + * Removes a composite from the given composite. + * @private + * @method removeCompositeAt + * @param {composite} composite + * @param {number} position + * @return {composite} The original composite with the composite removed */ - Plugin.isPlugin = function(obj) { - return obj && obj.name && obj.version && obj.install; + Composite.removeCompositeAt = function(composite, position) { + composite.composites.splice(position, 1); + Composite.setModified(composite, true, true, false); + return composite; }; /** - * Returns `true` if a plugin with the given `name` been installed on `module`. - * @method isUsed - * @param module {} The module. - * @param name {string} The plugin name. - * @return {boolean} `true` if a plugin with the given `name` been installed on `module`, otherwise `false`. + * Adds a body to the given composite. + * @private + * @method addBody + * @param {composite} composite + * @param {body} body + * @return {composite} The original composite with the body added */ - Plugin.isUsed = function(module, name) { - return module.used.indexOf(name) > -1; + Composite.addBody = function(composite, body) { + composite.bodies.push(body); + Composite.setModified(composite, true, true, false); + return composite; }; /** - * Returns `true` if `plugin.for` is applicable to `module` by comparing against `module.name` and `module.version`. - * If `plugin.for` is not specified then it is assumed to be applicable. - * The value of `plugin.for` is a string of the format `'module-name'` or `'module-name@version'`. - * @method isFor - * @param plugin {} The plugin. - * @param module {} The module. - * @return {boolean} `true` if `plugin.for` is applicable to `module`, otherwise `false`. + * Removes a body from the given composite, and optionally searching its children recursively. + * @private + * @method removeBody + * @param {composite} composite + * @param {body} body + * @param {boolean} [deep=false] + * @return {composite} The original composite with the body removed */ - Plugin.isFor = function(plugin, module) { - var parsed = plugin.for && Plugin.dependencyParse(plugin.for); - return !plugin.for || (module.name === parsed.name && Plugin.versionSatisfies(module.version, parsed.range)); + Composite.removeBody = function(composite, body, deep) { + var position = Common.indexOf(composite.bodies, body); + if (position !== -1) { + Composite.removeBodyAt(composite, position); + } + + if (deep) { + for (var i = 0; i < composite.composites.length; i++){ + Composite.removeBody(composite.composites[i], body, true); + } + } + + return composite; }; /** - * Installs the plugins by calling `plugin.install` on each plugin specified in `plugins` if passed, otherwise `module.uses`. - * For installing plugins on `Matter` see the convenience function `Matter.use`. - * Plugins may be specified either by their name or a reference to the plugin object. - * Plugins themselves may specify further dependencies, but each plugin is installed only once. - * Order is important, a topological sort is performed to find the best resulting order of installation. - * This sorting attempts to satisfy every dependency's requested ordering, but may not be exact in all cases. - * This function logs the resulting status of each dependency in the console, along with any warnings. - * - A green tick ✅ indicates a dependency was resolved and installed. - * - An orange diamond 🔶 indicates a dependency was resolved but a warning was thrown for it or one if its dependencies. - * - A red cross ❌ indicates a dependency could not be resolved. - * Avoid calling this function multiple times on the same module unless you intend to manually control installation order. - * @method use - * @param module {} The module install plugins on. - * @param [plugins=module.uses] {} The plugins to install on module (optional, defaults to `module.uses`). + * Removes a body from the given composite. + * @private + * @method removeBodyAt + * @param {composite} composite + * @param {number} position + * @return {composite} The original composite with the body removed */ - Plugin.use = function(module, plugins) { - module.uses = (module.uses || []).concat(plugins || []); + Composite.removeBodyAt = function(composite, position) { + composite.bodies.splice(position, 1); + Composite.setModified(composite, true, true, false); + return composite; + }; - if (module.uses.length === 0) { - Common.warn('Plugin.use:', Plugin.toString(module), 'does not specify any dependencies to install.'); - return; - } + /** + * Adds a constraint to the given composite. + * @private + * @method addConstraint + * @param {composite} composite + * @param {constraint} constraint + * @return {composite} The original composite with the constraint added + */ + Composite.addConstraint = function(composite, constraint) { + composite.constraints.push(constraint); + Composite.setModified(composite, true, true, false); + return composite; + }; - var dependencies = Plugin.dependencies(module), - sortedDependencies = Common.topologicalSort(dependencies), - status = []; + /** + * Removes a constraint from the given composite, and optionally searching its children recursively. + * @private + * @method removeConstraint + * @param {composite} composite + * @param {constraint} constraint + * @param {boolean} [deep=false] + * @return {composite} The original composite with the constraint removed + */ + Composite.removeConstraint = function(composite, constraint, deep) { + var position = Common.indexOf(composite.constraints, constraint); + if (position !== -1) { + Composite.removeConstraintAt(composite, position); + } - for (var i = 0; i < sortedDependencies.length; i += 1) { - if (sortedDependencies[i] === module.name) { - continue; + if (deep) { + for (var i = 0; i < composite.composites.length; i++){ + Composite.removeConstraint(composite.composites[i], constraint, true); } + } - var plugin = Plugin.resolve(sortedDependencies[i]); + return composite; + }; - if (!plugin) { - status.push('❌ ' + sortedDependencies[i]); - continue; - } + /** + * Removes a body from the given composite. + * @private + * @method removeConstraintAt + * @param {composite} composite + * @param {number} position + * @return {composite} The original composite with the constraint removed + */ + Composite.removeConstraintAt = function(composite, position) { + composite.constraints.splice(position, 1); + Composite.setModified(composite, true, true, false); + return composite; + }; - if (Plugin.isUsed(module, plugin.name)) { - continue; + /** + * Removes all bodies, constraints and composites from the given composite. + * Optionally clearing its children recursively. + * @method clear + * @param {composite} composite + * @param {boolean} keepStatic + * @param {boolean} [deep=false] + */ + Composite.clear = function(composite, keepStatic, deep) { + if (deep) { + for (var i = 0; i < composite.composites.length; i++){ + Composite.clear(composite.composites[i], keepStatic, true); } + } + + if (keepStatic) { + composite.bodies = composite.bodies.filter(function(body) { return body.isStatic; }); + } else { + composite.bodies.length = 0; + } - if (!Plugin.isFor(plugin, module)) { - Common.warn('Plugin.use:', Plugin.toString(plugin), 'is for', plugin.for, 'but installed on', Plugin.toString(module) + '.'); - plugin._warned = true; - } + composite.constraints.length = 0; + composite.composites.length = 0; - if (plugin.install) { - plugin.install(module); - } else { - Common.warn('Plugin.use:', Plugin.toString(plugin), 'does not specify an install function.'); - plugin._warned = true; - } + Composite.setModified(composite, true, true, false); - if (plugin._warned) { - status.push('🔶 ' + Plugin.toString(plugin)); - delete plugin._warned; - } else { - status.push('✅ ' + Plugin.toString(plugin)); - } + return composite; + }; - module.used.push(plugin.name); + /** + * Returns all bodies in the given composite, including all bodies in its children, recursively. + * @method allBodies + * @param {composite} composite + * @return {body[]} All the bodies + */ + Composite.allBodies = function(composite) { + if (composite.cache && composite.cache.allBodies) { + return composite.cache.allBodies; } - if (status.length > 0 && !plugin.silent) { - Common.info(status.join(' ')); + var bodies = [].concat(composite.bodies); + + for (var i = 0; i < composite.composites.length; i++) + bodies = bodies.concat(Composite.allBodies(composite.composites[i])); + + if (composite.cache) { + composite.cache.allBodies = bodies; } + + return bodies; }; /** - * Recursively finds all of a module's dependencies and returns a flat dependency graph. - * @method dependencies - * @param module {} The module. - * @return {object} A dependency graph. + * Returns all constraints in the given composite, including all constraints in its children, recursively. + * @method allConstraints + * @param {composite} composite + * @return {constraint[]} All the constraints */ - Plugin.dependencies = function(module, tracked) { - var parsedBase = Plugin.dependencyParse(module), - name = parsedBase.name; + Composite.allConstraints = function(composite) { + if (composite.cache && composite.cache.allConstraints) { + return composite.cache.allConstraints; + } - tracked = tracked || {}; + var constraints = [].concat(composite.constraints); - if (name in tracked) { - return; + for (var i = 0; i < composite.composites.length; i++) + constraints = constraints.concat(Composite.allConstraints(composite.composites[i])); + + if (composite.cache) { + composite.cache.allConstraints = constraints; } - module = Plugin.resolve(module) || module; + return constraints; + }; - tracked[name] = Common.map(module.uses || [], function(dependency) { - if (Plugin.isPlugin(dependency)) { - Plugin.register(dependency); - } + /** + * Returns all composites in the given composite, including all composites in its children, recursively. + * @method allComposites + * @param {composite} composite + * @return {composite[]} All the composites + */ + Composite.allComposites = function(composite) { + if (composite.cache && composite.cache.allComposites) { + return composite.cache.allComposites; + } - var parsed = Plugin.dependencyParse(dependency), - resolved = Plugin.resolve(dependency); + var composites = [].concat(composite.composites); - if (resolved && !Plugin.versionSatisfies(resolved.version, parsed.range)) { - Common.warn( - 'Plugin.dependencies:', Plugin.toString(resolved), 'does not satisfy', - Plugin.toString(parsed), 'used by', Plugin.toString(parsedBase) + '.' - ); + for (var i = 0; i < composite.composites.length; i++) + composites = composites.concat(Composite.allComposites(composite.composites[i])); - resolved._warned = true; - module._warned = true; - } else if (!resolved) { - Common.warn( - 'Plugin.dependencies:', Plugin.toString(dependency), 'used by', - Plugin.toString(parsedBase), 'could not be resolved.' - ); + if (composite.cache) { + composite.cache.allComposites = composites; + } - module._warned = true; - } + return composites; + }; - return parsed.name; + /** + * Searches the composite recursively for an object matching the type and id supplied, null if not found. + * @method get + * @param {composite} composite + * @param {number} id + * @param {string} type + * @return {object} The requested object, if found + */ + Composite.get = function(composite, id, type) { + var objects, + object; + + switch (type) { + case 'body': + objects = Composite.allBodies(composite); + break; + case 'constraint': + objects = Composite.allConstraints(composite); + break; + case 'composite': + objects = Composite.allComposites(composite).concat(composite); + break; + } + + if (!objects) + return null; + + object = objects.filter(function(object) { + return object.id.toString() === id.toString(); }); - for (var i = 0; i < tracked[name].length; i += 1) { - Plugin.dependencies(tracked[name][i], tracked); + return object.length === 0 ? null : object[0]; + }; + + /** + * Moves the given object(s) from compositeA to compositeB (equal to a remove followed by an add). + * @method move + * @param {compositeA} compositeA + * @param {object[]} objects + * @param {compositeB} compositeB + * @return {composite} Returns compositeA + */ + Composite.move = function(compositeA, objects, compositeB) { + Composite.remove(compositeA, objects); + Composite.add(compositeB, objects); + return compositeA; + }; + + /** + * Assigns new ids for all objects in the composite, recursively. + * @method rebase + * @param {composite} composite + * @return {composite} Returns composite + */ + Composite.rebase = function(composite) { + var objects = Composite.allBodies(composite) + .concat(Composite.allConstraints(composite)) + .concat(Composite.allComposites(composite)); + + for (var i = 0; i < objects.length; i++) { + objects[i].id = Common.nextId(); } - return tracked; + return composite; }; /** - * Parses a dependency string into its components. - * The `dependency` is a string of the format `'module-name'` or `'module-name@version'`. - * See documentation for `Plugin.versionParse` for a description of the format. - * This function can also handle dependencies that are already resolved (e.g. a module object). - * @method dependencyParse - * @param dependency {string} The dependency of the format `'module-name'` or `'module-name@version'`. - * @return {object} The dependency parsed into its components. + * Translates all children in the composite by a given vector relative to their current positions, + * without imparting any velocity. + * @method translate + * @param {composite} composite + * @param {vector} translation + * @param {bool} [recursive=true] */ - Plugin.dependencyParse = function(dependency) { - if (Common.isString(dependency)) { - var pattern = /^[\w-]+(@(\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?))?$/; + Composite.translate = function(composite, translation, recursive) { + var bodies = recursive ? Composite.allBodies(composite) : composite.bodies; - if (!pattern.test(dependency)) { - Common.warn('Plugin.dependencyParse:', dependency, 'is not a valid dependency string.'); - } + for (var i = 0; i < bodies.length; i++) { + Body.translate(bodies[i], translation); + } - return { - name: dependency.split('@')[0], - range: dependency.split('@')[1] || '*' - }; + return composite; + }; + + /** + * Rotates all children in the composite by a given angle about the given point, without imparting any angular velocity. + * @method rotate + * @param {composite} composite + * @param {number} rotation + * @param {vector} point + * @param {bool} [recursive=true] + */ + Composite.rotate = function(composite, rotation, point, recursive) { + var cos = Math.cos(rotation), + sin = Math.sin(rotation), + bodies = recursive ? Composite.allBodies(composite) : composite.bodies; + + for (var i = 0; i < bodies.length; i++) { + var body = bodies[i], + dx = body.position.x - point.x, + dy = body.position.y - point.y; + + Body.setPosition(body, { + x: point.x + (dx * cos - dy * sin), + y: point.y + (dx * sin + dy * cos) + }); + + Body.rotate(body, rotation); } - return { - name: dependency.name, - range: dependency.range || dependency.version - }; + return composite; + }; + + /** + * Scales all children in the composite, including updating physical properties (mass, area, axes, inertia), from a world-space point. + * @method scale + * @param {composite} composite + * @param {number} scaleX + * @param {number} scaleY + * @param {vector} point + * @param {bool} [recursive=true] + */ + Composite.scale = function(composite, scaleX, scaleY, point, recursive) { + var bodies = recursive ? Composite.allBodies(composite) : composite.bodies; + + for (var i = 0; i < bodies.length; i++) { + var body = bodies[i], + dx = body.position.x - point.x, + dy = body.position.y - point.y; + + Body.setPosition(body, { + x: point.x + dx * scaleX, + y: point.y + dy * scaleY + }); + + Body.scale(body, scaleX, scaleY); + } + + return composite; + }; + + /** + * Returns the union of the bounds of all of the composite's bodies. + * @method bounds + * @param {composite} composite The composite. + * @returns {bounds} The composite bounds. + */ + Composite.bounds = function(composite) { + var bodies = Composite.allBodies(composite), + vertices = []; + + for (var i = 0; i < bodies.length; i += 1) { + var body = bodies[i]; + vertices.push(body.bounds.min, body.bounds.max); + } + + return Bounds.create(vertices); }; + /* + * + * Events Documentation + * + */ + + /** + * Fired when a call to `Composite.add` is made, before objects have been added. + * + * @event beforeAdd + * @param {} event An event object + * @param {} event.object The object(s) to be added (may be a single body, constraint, composite or a mixed array of these) + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /** + * Fired when a call to `Composite.add` is made, after objects have been added. + * + * @event afterAdd + * @param {} event An event object + * @param {} event.object The object(s) that have been added (may be a single body, constraint, composite or a mixed array of these) + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /** + * Fired when a call to `Composite.remove` is made, before objects have been removed. + * + * @event beforeRemove + * @param {} event An event object + * @param {} event.object The object(s) to be removed (may be a single body, constraint, composite or a mixed array of these) + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /** + * Fired when a call to `Composite.remove` is made, after objects have been removed. + * + * @event afterRemove + * @param {} event An event object + * @param {} event.object The object(s) that have been removed (may be a single body, constraint, composite or a mixed array of these) + * @param {} event.source The source object of the event + * @param {} event.name The name of the event + */ + + /* + * + * Properties Documentation + * + */ + /** - * Parses a version string into its components. - * Versions are strictly of the format `x.y.z` (as in [semver](http://semver.org/)). - * Versions may optionally have a prerelease tag in the format `x.y.z-alpha`. - * Ranges are a strict subset of [npm ranges](https://docs.npmjs.com/misc/semver#advanced-range-syntax). - * Only the following range types are supported: - * - Tilde ranges e.g. `~1.2.3` - * - Caret ranges e.g. `^1.2.3` - * - Exact version e.g. `1.2.3` - * - Any version `*` - * @method versionParse - * @param range {string} The version string. - * @return {object} The version range parsed into its components. + * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`. + * + * @property id + * @type number */ - Plugin.versionParse = function(range) { - var pattern = /^\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?$/; - if (!pattern.test(range)) { - Common.warn('Plugin.versionParse:', range, 'is not a valid version or range.'); - } - - var identifiers = range.split('-'); - range = identifiers[0]; - - var isRange = isNaN(Number(range[0])), - version = isRange ? range.substr(1) : range, - parts = Common.map(version.split('.'), function(part) { - return Number(part); - }); - - return { - isRange: isRange, - version: version, - range: range, - operator: isRange ? range[0] : '', - parts: parts, - prerelease: identifiers[1], - number: parts[0] * 1e8 + parts[1] * 1e4 + parts[2] - }; - }; + /** + * A `String` denoting the type of object. + * + * @property type + * @type string + * @default "composite" + * @readOnly + */ /** - * Returns `true` if `version` satisfies the given `range`. - * See documentation for `Plugin.versionParse` for a description of the format. - * If a version or range is not specified, then any version (`*`) is assumed to satisfy. - * @method versionSatisfies - * @param version {string} The version string. - * @param range {string} The range string. - * @return {boolean} `true` if `version` satisfies `range`, otherwise `false`. + * An arbitrary `String` name to help the user identify and manage composites. + * + * @property label + * @type string + * @default "Composite" */ - Plugin.versionSatisfies = function(version, range) { - range = range || '*'; - var rangeParsed = Plugin.versionParse(range), - rangeParts = rangeParsed.parts, - versionParsed = Plugin.versionParse(version), - versionParts = versionParsed.parts; + /** + * A flag that specifies whether the composite has been modified during the current step. + * Most `Matter.Composite` methods will automatically set this flag to `true` to inform the engine of changes to be handled. + * If you need to change it manually, you should use the `Composite.setModified` method. + * + * @property isModified + * @type boolean + * @default false + */ - if (rangeParsed.isRange) { - if (rangeParsed.operator === '*' || version === '*') { - return true; - } + /** + * The `Composite` that is the parent of this composite. It is automatically managed by the `Matter.Composite` methods. + * + * @property parent + * @type composite + * @default null + */ - if (rangeParsed.operator === '~') { - return versionParts[0] === rangeParts[0] && versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2]; - } + /** + * An array of `Body` that are _direct_ children of this composite. + * To add or remove bodies you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property. + * If you wish to recursively find all descendants, you should use the `Composite.allBodies` method. + * + * @property bodies + * @type body[] + * @default [] + */ - if (rangeParsed.operator === '^') { - if (rangeParts[0] > 0) { - return versionParts[0] === rangeParts[0] && versionParsed.number >= rangeParsed.number; - } + /** + * An array of `Constraint` that are _direct_ children of this composite. + * To add or remove constraints you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property. + * If you wish to recursively find all descendants, you should use the `Composite.allConstraints` method. + * + * @property constraints + * @type constraint[] + * @default [] + */ - if (rangeParts[1] > 0) { - return versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2]; - } + /** + * An array of `Composite` that are _direct_ children of this composite. + * To add or remove composites you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property. + * If you wish to recursively find all descendants, you should use the `Composite.allComposites` method. + * + * @property composites + * @type composite[] + * @default [] + */ - return versionParts[2] === rangeParts[2]; - } - } + /** + * An object reserved for storing plugin-specific properties. + * + * @property plugin + * @type {} + */ - return version === range || version === '*'; - }; + /** + * An object used for storing cached results for performance reasons. + * This is used internally only and is automatically managed. + * + * @private + * @property cache + * @type {} + */ })(); /***/ }), -/* 596 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72005: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** -* The `Matter.World` module contains methods for creating and manipulating the world composite. -* A `Matter.World` is a `Matter.Composite` body, which is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`. -* A `Matter.World` has a few additional properties including `gravity` and `bounds`. -* It is important to use the functions in the `Matter.Composite` module to modify the world composite, rather than directly modifying its properties. -* There are also a few methods here that alias those in `Matter.Composite` for easier readability. +* This module has now been replaced by `Matter.Composite`. * -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* All usage should be migrated to the equivalent functions found on `Matter.Composite`. +* For example `World.add(world, body)` now becomes `Composite.add(world, body)`. +* +* The property `world.gravity` has been moved to `engine.gravity`. +* +* For back-compatibility purposes this module will remain as a direct alias to `Matter.Composite` in the short term during migration. +* Eventually this alias module will be marked as deprecated and then later removed in a future release. * * @class World * @extends Composite @@ -142418,38 +161802,20 @@ var World = {}; module.exports = World; -var Composite = __webpack_require__(118); -var Constraint = __webpack_require__(128); -var Common = __webpack_require__(32); +var Composite = __webpack_require__(11299); (function() { /** - * Creates a new world composite. The options parameter is an object that specifies any properties you wish to override the defaults. - * See the properties section below for detailed information on what you can pass via the `options` object. - * @method create - * @constructor - * @param {} options - * @return {world} A new world + * See above, aliases for back compatibility only */ - World.create = function(options) { - var composite = Composite.create(); - - var defaults = { - label: 'World', - gravity: { - x: 0, - y: 1, - scale: 0.001 - }, - bounds: { - min: { x: -Infinity, y: -Infinity }, - max: { x: Infinity, y: Infinity } - } - }; - - return Common.extend(composite, defaults, options); - }; + World.create = Composite.create; + World.add = Composite.add; + World.remove = Composite.remove; + World.clear = Composite.clear; + World.addComposite = Composite.addComposite; + World.addBody = Composite.addBody; + World.addConstraint = Composite.addConstraint; /* * @@ -142498,7 +161864,7 @@ var Common = __webpack_require__(32); // World is a Composite body // see src/module/Outro.js for these aliases: - + /** * An alias for Composite.add * @method add @@ -142530,7 +161896,7 @@ var Common = __webpack_require__(32); * @param {composite} composite * @return {world} The original world with the objects from composite added */ - + /** * An alias for Composite.addBody * @method addBody @@ -142551,46496 +161917,50192 @@ var Common = __webpack_require__(32); /***/ }), -/* 597 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 63454: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** -* The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures. +* The `Matter.Collision` module contains methods for detecting collisions between a given pair of bodies. +* +* For efficient detection between a list of bodies, see `Matter.Detector` and `Matter.Query`. * -* @class Grid +* See `Matter.Engine` for collision events. +* +* @class Collision */ -var Grid = {}; +var Collision = {}; -module.exports = Grid; +module.exports = Collision; -var Pair = __webpack_require__(250); -var Detector = __webpack_require__(273); -var Common = __webpack_require__(32); +var Vertices = __webpack_require__(39745); +var Pair = __webpack_require__(70584); (function() { + var _supports = []; + + var _overlapAB = { + overlap: 0, + axis: null + }; + + var _overlapBA = { + overlap: 0, + axis: null + }; /** - * Creates a new grid. + * Creates a new collision record. * @method create - * @param {} options - * @return {grid} A new grid + * @param {body} bodyA The first body part represented by the collision record + * @param {body} bodyB The second body part represented by the collision record + * @return {collision} A new collision record */ - Grid.create = function(options) { - var defaults = { - controller: Grid, - detector: Detector.collisions, - buckets: {}, - pairs: {}, - pairsList: [], - bucketWidth: 48, - bucketHeight: 48 + Collision.create = function(bodyA, bodyB) { + return { + pair: null, + collided: false, + bodyA: bodyA, + bodyB: bodyB, + parentA: bodyA.parent, + parentB: bodyB.parent, + depth: 0, + normal: { x: 0, y: 0 }, + tangent: { x: 0, y: 0 }, + penetration: { x: 0, y: 0 }, + supports: [] }; - - return Common.extend(defaults, options); }; /** - * The width of a single grid bucket. - * - * @property bucketWidth - * @type number - * @default 48 + * Detect collision between two bodies. + * @method collides + * @param {body} bodyA + * @param {body} bodyB + * @param {pairs} [pairs] Optionally reuse collision records from existing pairs. + * @return {collision|null} A collision record if detected, otherwise null */ + Collision.collides = function(bodyA, bodyB, pairs) { + Collision._overlapAxes(_overlapAB, bodyA.vertices, bodyB.vertices, bodyA.axes); - /** - * The height of a single grid bucket. - * - * @property bucketHeight - * @type number - * @default 48 - */ + if (_overlapAB.overlap <= 0) { + return null; + } - /** - * Updates the grid. - * @method update - * @param {grid} grid - * @param {body[]} bodies - * @param {engine} engine - * @param {boolean} forceUpdate - */ - Grid.update = function(grid, bodies, engine, forceUpdate) { - var i, col, row, - world = engine.world, - buckets = grid.buckets, - bucket, - bucketId, - gridChanged = false; - - // @if DEBUG - var metrics = engine.metrics; - metrics.broadphaseTests = 0; - // @endif - - for (i = 0; i < bodies.length; i++) { - var body = bodies[i]; + Collision._overlapAxes(_overlapBA, bodyB.vertices, bodyA.vertices, bodyB.axes); - if (body.isSleeping && !forceUpdate) - continue; + if (_overlapBA.overlap <= 0) { + return null; + } - // don't update out of world bodies - if (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x - || body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y) - continue; + // reuse collision records for gc efficiency + var pair = pairs && pairs.table[Pair.id(bodyA, bodyB)], + collision; + + if (!pair) { + collision = Collision.create(bodyA, bodyB); + collision.collided = true; + collision.bodyA = bodyA.id < bodyB.id ? bodyA : bodyB; + collision.bodyB = bodyA.id < bodyB.id ? bodyB : bodyA; + collision.parentA = collision.bodyA.parent; + collision.parentB = collision.bodyB.parent; + } else { + collision = pair.collision; + } - var newRegion = Grid._getRegion(grid, body); + bodyA = collision.bodyA; + bodyB = collision.bodyB; - // if the body has changed grid region - if (!body.region || newRegion.id !== body.region.id || forceUpdate) { + var minOverlap; - // @if DEBUG - metrics.broadphaseTests += 1; - // @endif + if (_overlapAB.overlap < _overlapBA.overlap) { + minOverlap = _overlapAB; + } else { + minOverlap = _overlapBA; + } - if (!body.region || forceUpdate) - body.region = newRegion; + var normal = collision.normal, + supports = collision.supports, + minAxis = minOverlap.axis, + minAxisX = minAxis.x, + minAxisY = minAxis.y; - var union = Grid._regionUnion(newRegion, body.region); + // ensure normal is facing away from bodyA + if (minAxisX * (bodyB.position.x - bodyA.position.x) + minAxisY * (bodyB.position.y - bodyA.position.y) < 0) { + normal.x = minAxisX; + normal.y = minAxisY; + } else { + normal.x = -minAxisX; + normal.y = -minAxisY; + } + + collision.tangent.x = -normal.y; + collision.tangent.y = normal.x; - // update grid buckets affected by region change - // iterate over the union of both regions - for (col = union.startCol; col <= union.endCol; col++) { - for (row = union.startRow; row <= union.endRow; row++) { - bucketId = Grid._getBucketId(col, row); - bucket = buckets[bucketId]; + collision.depth = minOverlap.overlap; - var isInsideNewRegion = (col >= newRegion.startCol && col <= newRegion.endCol - && row >= newRegion.startRow && row <= newRegion.endRow); + collision.penetration.x = normal.x * collision.depth; + collision.penetration.y = normal.y * collision.depth; - var isInsideOldRegion = (col >= body.region.startCol && col <= body.region.endCol - && row >= body.region.startRow && row <= body.region.endRow); + // find support points, there is always either exactly one or two + var supportsB = Collision._findSupports(bodyA, bodyB, normal, 1), + supportCount = 0; - // remove from old region buckets - if (!isInsideNewRegion && isInsideOldRegion) { - if (isInsideOldRegion) { - if (bucket) - Grid._bucketRemoveBody(grid, bucket, body); - } - } + // find the supports from bodyB that are inside bodyA + if (Vertices.contains(bodyA.vertices, supportsB[0])) { + supports[supportCount++] = supportsB[0]; + } - // add to new region buckets - if (body.region === newRegion || (isInsideNewRegion && !isInsideOldRegion) || forceUpdate) { - if (!bucket) - bucket = Grid._createBucket(buckets, bucketId); - Grid._bucketAddBody(grid, bucket, body); - } - } - } + if (Vertices.contains(bodyA.vertices, supportsB[1])) { + supports[supportCount++] = supportsB[1]; + } - // set the new region - body.region = newRegion; + // find the supports from bodyA that are inside bodyB + if (supportCount < 2) { + var supportsA = Collision._findSupports(bodyB, bodyA, normal, -1); + + if (Vertices.contains(bodyB.vertices, supportsA[0])) { + supports[supportCount++] = supportsA[0]; + } - // flag changes so we can update pairs - gridChanged = true; + if (supportCount < 2 && Vertices.contains(bodyB.vertices, supportsA[1])) { + supports[supportCount++] = supportsA[1]; } } - // update pairs list only if pairs changed (i.e. a body changed region) - if (gridChanged) - grid.pairsList = Grid._createActivePairsList(grid); - }; + // account for the edge case of overlapping but no vertex containment + if (supportCount === 0) { + supports[supportCount++] = supportsB[0]; + } - /** - * Clears the grid. - * @method clear - * @param {grid} grid - */ - Grid.clear = function(grid) { - grid.buckets = {}; - grid.pairs = {}; - grid.pairsList = []; + // update supports array size + supports.length = supportCount; + + return collision; }; /** - * Finds the union of two regions. - * @method _regionUnion + * Find the overlap between two sets of vertices. + * @method _overlapAxes * @private - * @param {} regionA - * @param {} regionB - * @return {} region + * @param {object} result + * @param {vertices} verticesA + * @param {vertices} verticesB + * @param {axes} axes */ - Grid._regionUnion = function(regionA, regionB) { - var startCol = Math.min(regionA.startCol, regionB.startCol), - endCol = Math.max(regionA.endCol, regionB.endCol), - startRow = Math.min(regionA.startRow, regionB.startRow), - endRow = Math.max(regionA.endRow, regionB.endRow); + Collision._overlapAxes = function(result, verticesA, verticesB, axes) { + var verticesALength = verticesA.length, + verticesBLength = verticesB.length, + verticesAX = verticesA[0].x, + verticesAY = verticesA[0].y, + verticesBX = verticesB[0].x, + verticesBY = verticesB[0].y, + axesLength = axes.length, + overlapMin = Number.MAX_VALUE, + overlapAxisNumber = 0, + overlap, + overlapAB, + overlapBA, + dot, + i, + j; - return Grid._createRegion(startCol, endCol, startRow, endRow); - }; + for (i = 0; i < axesLength; i++) { + var axis = axes[i], + axisX = axis.x, + axisY = axis.y, + minA = verticesAX * axisX + verticesAY * axisY, + minB = verticesBX * axisX + verticesBY * axisY, + maxA = minA, + maxB = minB; + + for (j = 1; j < verticesALength; j += 1) { + dot = verticesA[j].x * axisX + verticesA[j].y * axisY; - /** - * Gets the region a given body falls in for a given grid. - * @method _getRegion - * @private - * @param {} grid - * @param {} body - * @return {} region - */ - Grid._getRegion = function(grid, body) { - var bounds = body.bounds, - startCol = Math.floor(bounds.min.x / grid.bucketWidth), - endCol = Math.floor(bounds.max.x / grid.bucketWidth), - startRow = Math.floor(bounds.min.y / grid.bucketHeight), - endRow = Math.floor(bounds.max.y / grid.bucketHeight); - - return Grid._createRegion(startCol, endCol, startRow, endRow); - }; + if (dot > maxA) { + maxA = dot; + } else if (dot < minA) { + minA = dot; + } + } - /** - * Creates a region. - * @method _createRegion - * @private - * @param {} startCol - * @param {} endCol - * @param {} startRow - * @param {} endRow - * @return {} region - */ - Grid._createRegion = function(startCol, endCol, startRow, endRow) { - return { - id: startCol + ',' + endCol + ',' + startRow + ',' + endRow, - startCol: startCol, - endCol: endCol, - startRow: startRow, - endRow: endRow - }; - }; + for (j = 1; j < verticesBLength; j += 1) { + dot = verticesB[j].x * axisX + verticesB[j].y * axisY; - /** - * Gets the bucket id at the given position. - * @method _getBucketId - * @private - * @param {} column - * @param {} row - * @return {string} bucket id - */ - Grid._getBucketId = function(column, row) { - return 'C' + column + 'R' + row; - }; + if (dot > maxB) { + maxB = dot; + } else if (dot < minB) { + minB = dot; + } + } - /** - * Creates a bucket. - * @method _createBucket - * @private - * @param {} buckets - * @param {} bucketId - * @return {} bucket - */ - Grid._createBucket = function(buckets, bucketId) { - var bucket = buckets[bucketId] = []; - return bucket; + overlapAB = maxA - minB; + overlapBA = maxB - minA; + overlap = overlapAB < overlapBA ? overlapAB : overlapBA; + + if (overlap < overlapMin) { + overlapMin = overlap; + overlapAxisNumber = i; + + if (overlap <= 0) { + // can not be intersecting + break; + } + } + } + + result.axis = axes[overlapAxisNumber]; + result.overlap = overlapMin; }; /** - * Adds a body to a bucket. - * @method _bucketAddBody + * Projects vertices on an axis and returns an interval. + * @method _projectToAxis * @private - * @param {} grid - * @param {} bucket - * @param {} body + * @param {} projection + * @param {} vertices + * @param {} axis */ - Grid._bucketAddBody = function(grid, bucket, body) { - // add new pairs - for (var i = 0; i < bucket.length; i++) { - var bodyB = bucket[i]; - - if (body.id === bodyB.id || (body.isStatic && bodyB.isStatic)) - continue; + Collision._projectToAxis = function(projection, vertices, axis) { + var min = vertices[0].x * axis.x + vertices[0].y * axis.y, + max = min; - // keep track of the number of buckets the pair exists in - // important for Grid.update to work - var pairId = Pair.id(body, bodyB), - pair = grid.pairs[pairId]; + for (var i = 1; i < vertices.length; i += 1) { + var dot = vertices[i].x * axis.x + vertices[i].y * axis.y; - if (pair) { - pair[2] += 1; - } else { - grid.pairs[pairId] = [body, bodyB, 1]; + if (dot > max) { + max = dot; + } else if (dot < min) { + min = dot; } } - // add to bodies (after pairs, otherwise pairs with self) - bucket.push(body); + projection.min = min; + projection.max = max; }; /** - * Removes a body from a bucket. - * @method _bucketRemoveBody + * Finds supporting vertices given two bodies along a given direction using hill-climbing. + * @method _findSupports * @private - * @param {} grid - * @param {} bucket - * @param {} body + * @param {body} bodyA + * @param {body} bodyB + * @param {vector} normal + * @param {number} direction + * @return [vector] */ - Grid._bucketRemoveBody = function(grid, bucket, body) { - // remove from bucket - bucket.splice(bucket.indexOf(body), 1); + Collision._findSupports = function(bodyA, bodyB, normal, direction) { + var vertices = bodyB.vertices, + verticesLength = vertices.length, + bodyAPositionX = bodyA.position.x, + bodyAPositionY = bodyA.position.y, + normalX = normal.x * direction, + normalY = normal.y * direction, + nearestDistance = Number.MAX_VALUE, + vertexA, + vertexB, + vertexC, + distance, + j; - // update pair counts - for (var i = 0; i < bucket.length; i++) { - // keep track of the number of buckets the pair exists in - // important for _createActivePairsList to work - var bodyB = bucket[i], - pairId = Pair.id(body, bodyB), - pair = grid.pairs[pairId]; + // find deepest vertex relative to the axis + for (j = 0; j < verticesLength; j += 1) { + vertexB = vertices[j]; + distance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y); - if (pair) - pair[2] -= 1; + // convex hill-climbing + if (distance < nearestDistance) { + nearestDistance = distance; + vertexA = vertexB; + } } - }; - - /** - * Generates a list of the active pairs in the grid. - * @method _createActivePairsList - * @private - * @param {} grid - * @return [] pairs - */ - Grid._createActivePairsList = function(grid) { - var pairKeys, - pair, - pairs = []; - // grid.pairs is used as a hashmap - pairKeys = Common.keys(grid.pairs); + // measure next vertex + vertexC = vertices[(verticesLength + vertexA.index - 1) % verticesLength]; + nearestDistance = normalX * (bodyAPositionX - vertexC.x) + normalY * (bodyAPositionY - vertexC.y); - // iterate over grid.pairs - for (var k = 0; k < pairKeys.length; k++) { - pair = grid.pairs[pairKeys[k]]; + // compare with previous vertex + vertexB = vertices[(vertexA.index + 1) % verticesLength]; + if (normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y) < nearestDistance) { + _supports[0] = vertexA; + _supports[1] = vertexB; - // if pair exists in at least one bucket - // it is a pair that needs further collision testing so push it - if (pair[2] > 0) { - pairs.push(pair); - } else { - delete grid.pairs[pairKeys[k]]; - } + return _supports; } - return pairs; + _supports[0] = vertexA; + _supports[1] = vertexC; + + return _supports; }; - -})(); + /* + * + * Properties Documentation + * + */ -/***/ }), -/* 598 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * A reference to the pair using this collision record, if there is one. + * + * @property pair + * @type {pair|null} + * @default null + */ -/** -* The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets. -* -* @class Pairs -*/ + /** + * A flag that indicates if the bodies were colliding when the collision was last updated. + * + * @property collided + * @type boolean + * @default false + */ -var Pairs = {}; + /** + * The first body part represented by the collision (see also `collision.parentA`). + * + * @property bodyA + * @type body + */ -module.exports = Pairs; + /** + * The second body part represented by the collision (see also `collision.parentB`). + * + * @property bodyB + * @type body + */ -var Pair = __webpack_require__(250); -var Common = __webpack_require__(32); + /** + * The first body represented by the collision (i.e. `collision.bodyA.parent`). + * + * @property parentA + * @type body + */ -(function() { - - Pairs._pairMaxIdleLife = 1000; + /** + * The second body represented by the collision (i.e. `collision.bodyB.parent`). + * + * @property parentB + * @type body + */ /** - * Creates a new pairs structure. - * @method create - * @param {object} options - * @return {pairs} A new pairs structure + * A `Number` that represents the minimum separating distance between the bodies along the collision normal. + * + * @readOnly + * @property depth + * @type number + * @default 0 */ - Pairs.create = function(options) { - return Common.extend({ - table: {}, - list: [], - collisionStart: [], - collisionActive: [], - collisionEnd: [] - }, options); - }; /** - * Updates pairs given a list of collisions. - * @method update - * @param {object} pairs - * @param {collision[]} collisions - * @param {number} timestamp + * A normalised `Vector` that represents the direction between the bodies that provides the minimum separating distance. + * + * @property normal + * @type vector + * @default { x: 0, y: 0 } */ - Pairs.update = function(pairs, collisions, timestamp) { - var pairsList = pairs.list, - pairsTable = pairs.table, - collisionStart = pairs.collisionStart, - collisionEnd = pairs.collisionEnd, - collisionActive = pairs.collisionActive, - collision, - pairId, - pair, - i; - // clear collision state arrays, but maintain old reference - collisionStart.length = 0; - collisionEnd.length = 0; - collisionActive.length = 0; + /** + * A normalised `Vector` that is the tangent direction to the collision normal. + * + * @property tangent + * @type vector + * @default { x: 0, y: 0 } + */ - for (i = 0; i < pairsList.length; i++) { - pairsList[i].confirmedActive = false; - } + /** + * A `Vector` that represents the direction and depth of the collision. + * + * @property penetration + * @type vector + * @default { x: 0, y: 0 } + */ - for (i = 0; i < collisions.length; i++) { - collision = collisions[i]; + /** + * An array of body vertices that represent the support points in the collision. + * These are the deepest vertices (along the collision normal) of each body that are contained by the other body's vertices. + * + * @property supports + * @type vector[] + * @default [] + */ - if (collision.collided) { - pairId = Pair.id(collision.bodyA, collision.bodyB); +})(); - pair = pairsTable[pairId]; - - if (pair) { - // pair already exists (but may or may not be active) - if (pair.isActive) { - // pair exists and is active - collisionActive.push(pair); - } else { - // pair exists but was inactive, so a collision has just started again - collisionStart.push(pair); - } - // update the pair - Pair.update(pair, collision, timestamp); - pair.confirmedActive = true; - } else { - // pair did not exist, create a new pair - pair = Pair.create(collision, timestamp); - pairsTable[pairId] = pair; +/***/ }), - // push the new pair - collisionStart.push(pair); - pairsList.push(pair); - } - } - } +/***/ 17319: +/***/ ((module) => { - // deactivate previously active pairs that are now inactive - for (i = 0; i < pairsList.length; i++) { - pair = pairsList[i]; - if (pair.isActive && !pair.confirmedActive) { - Pair.setActive(pair, false, timestamp); - collisionEnd.push(pair); - } - } - }; - - /** - * Finds and removes pairs that have been inactive for a set amount of time. - * @method removeOld - * @param {object} pairs - * @param {number} timestamp - */ - Pairs.removeOld = function(pairs, timestamp) { - var pairsList = pairs.list, - pairsTable = pairs.table, - indexesToRemove = [], - pair, - collision, - pairIndex, - i; +/** +* The `Matter.Contact` module contains methods for creating and manipulating collision contacts. +* +* @class Contact +*/ - for (i = 0; i < pairsList.length; i++) { - pair = pairsList[i]; - collision = pair.collision; - - // never remove sleeping pairs - if (collision.bodyA.isSleeping || collision.bodyB.isSleeping) { - pair.timeUpdated = timestamp; - continue; - } +var Contact = {}; - // if pair is inactive for too long, mark it to be removed - if (timestamp - pair.timeUpdated > Pairs._pairMaxIdleLife) { - indexesToRemove.push(i); - } - } +module.exports = Contact; - // remove marked pairs - for (i = 0; i < indexesToRemove.length; i++) { - pairIndex = indexesToRemove[i] - i; - pair = pairsList[pairIndex]; - delete pairsTable[pair.id]; - pairsList.splice(pairIndex, 1); - } - }; +(function() { /** - * Clears the given pairs structure. - * @method clear - * @param {pairs} pairs - * @return {pairs} pairs + * Creates a new contact. + * @method create + * @param {vertex} vertex + * @return {contact} A new contact */ - Pairs.clear = function(pairs) { - pairs.table = {}; - pairs.list.length = 0; - pairs.collisionStart.length = 0; - pairs.collisionActive.length = 0; - pairs.collisionEnd.length = 0; - return pairs; + Contact.create = function(vertex) { + return { + vertex: vertex, + normalImpulse: 0, + tangentImpulse: 0 + }; }; })(); /***/ }), -/* 599 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 13657: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** -* The `Matter.Resolver` module contains methods for resolving collision pairs. +* The `Matter.Detector` module contains methods for efficiently detecting collisions between a list of bodies using a broadphase algorithm. * -* @class Resolver +* @class Detector */ -var Resolver = {}; +var Detector = {}; -module.exports = Resolver; +module.exports = Detector; -var Vertices = __webpack_require__(64); -var Vector = __webpack_require__(83); -var Common = __webpack_require__(32); -var Bounds = __webpack_require__(84); +var Common = __webpack_require__(68758); +var Collision = __webpack_require__(63454); (function() { - Resolver._restingThresh = 4; - Resolver._restingThreshTangent = 6; - Resolver._positionDampen = 0.9; - Resolver._positionWarming = 0.8; - Resolver._frictionNormalMultiplier = 5; - /** - * Prepare pairs for position solving. - * @method preSolvePosition - * @param {pair[]} pairs + * Creates a new collision detector. + * @method create + * @param {} options + * @return {detector} A new collision detector */ - Resolver.preSolvePosition = function(pairs) { - var i, - pair, - activeCount; + Detector.create = function(options) { + var defaults = { + bodies: [], + pairs: null + }; - // find total contacts on each body - for (i = 0; i < pairs.length; i++) { - pair = pairs[i]; - - if (!pair.isActive) - continue; - - activeCount = pair.activeContacts.length; - pair.collision.parentA.totalContacts += activeCount; - pair.collision.parentB.totalContacts += activeCount; - } + return Common.extend(defaults, options); }; /** - * Find a solution for pair positions. - * @method solvePosition - * @param {pair[]} pairs + * Sets the list of bodies in the detector. + * @method setBodies + * @param {detector} detector * @param {body[]} bodies - * @param {number} timeScale */ - Resolver.solvePosition = function(pairs, bodies, timeScale) { - var i, - normalX, - normalY, - pair, - collision, - bodyA, - bodyB, - normal, - separation, - penetration, - positionImpulseA, - positionImpulseB, - contactShare, - bodyBtoAX, - bodyBtoAY, - positionImpulse, - impulseCoefficient = timeScale * Resolver._positionDampen; + Detector.setBodies = function(detector, bodies) { + detector.bodies = bodies.slice(0); + }; - for (i = 0; i < bodies.length; i++) { - var body = bodies[i]; - body.previousPositionImpulse.x = body.positionImpulse.x; - body.previousPositionImpulse.y = body.positionImpulse.y; - } + /** + * Clears the detector including its list of bodies. + * @method clear + * @param {detector} detector + */ + Detector.clear = function(detector) { + detector.bodies = []; + }; - // find impulses required to resolve penetration - for (i = 0; i < pairs.length; i++) { - pair = pairs[i]; - - if (!pair.isActive || pair.isSensor) - continue; + /** + * Efficiently finds all collisions among all the bodies in `detector.bodies` using a broadphase algorithm. + * + * _Note:_ The specific ordering of collisions returned is not guaranteed between releases and may change for performance reasons. + * If a specific ordering is required then apply a sort to the resulting array. + * @method collisions + * @param {detector} detector + * @return {collision[]} collisions + */ + Detector.collisions = function(detector) { + var collisions = [], + pairs = detector.pairs, + bodies = detector.bodies, + bodiesLength = bodies.length, + canCollide = Detector.canCollide, + collides = Collision.collides, + i, + j; - collision = pair.collision; - bodyA = collision.parentA; - bodyB = collision.parentB; - normal = collision.normal; + bodies.sort(Detector._compareBoundsX); - positionImpulseA = bodyA.previousPositionImpulse; - positionImpulseB = bodyB.previousPositionImpulse; + for (i = 0; i < bodiesLength; i++) { + var bodyA = bodies[i], + boundsA = bodyA.bounds, + boundXMax = bodyA.bounds.max.x, + boundYMax = bodyA.bounds.max.y, + boundYMin = bodyA.bounds.min.y, + bodyAStatic = bodyA.isStatic || bodyA.isSleeping, + partsALength = bodyA.parts.length, + partsASingle = partsALength === 1; - penetration = collision.penetration; + for (j = i + 1; j < bodiesLength; j++) { + var bodyB = bodies[j], + boundsB = bodyB.bounds; - bodyBtoAX = positionImpulseB.x - positionImpulseA.x + penetration.x; - bodyBtoAY = positionImpulseB.y - positionImpulseA.y + penetration.y; + if (boundsB.min.x > boundXMax) { + break; + } - normalX = normal.x; - normalY = normal.y; + if (boundYMax < boundsB.min.y || boundYMin > boundsB.max.y) { + continue; + } - separation = normalX * bodyBtoAX + normalY * bodyBtoAY; - pair.separation = separation; + if (bodyAStatic && (bodyB.isStatic || bodyB.isSleeping)) { + continue; + } - positionImpulse = (separation - pair.slop) * impulseCoefficient; + if (!canCollide(bodyA.collisionFilter, bodyB.collisionFilter)) { + continue; + } - if (bodyA.isStatic || bodyB.isStatic) - positionImpulse *= 2; - - if (!(bodyA.isStatic || bodyA.isSleeping)) { - contactShare = positionImpulse / bodyA.totalContacts; - bodyA.positionImpulse.x += normalX * contactShare; - bodyA.positionImpulse.y += normalY * contactShare; - } + var partsBLength = bodyB.parts.length; - if (!(bodyB.isStatic || bodyB.isSleeping)) { - contactShare = positionImpulse / bodyB.totalContacts; - bodyB.positionImpulse.x -= normalX * contactShare; - bodyB.positionImpulse.y -= normalY * contactShare; - } - } - }; + if (partsASingle && partsBLength === 1) { + var collision = collides(bodyA, bodyB, pairs); - /** - * Apply position resolution. - * @method postSolvePosition - * @param {body[]} bodies - */ - Resolver.postSolvePosition = function(bodies) { - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i]; + if (collision) { + collisions.push(collision); + } + } else { + var partsAStart = partsALength > 1 ? 1 : 0, + partsBStart = partsBLength > 1 ? 1 : 0; + + for (var k = partsAStart; k < partsALength; k++) { + var partA = bodyA.parts[k], + boundsA = partA.bounds; - // reset contact count - body.totalContacts = 0; + for (var z = partsBStart; z < partsBLength; z++) { + var partB = bodyB.parts[z], + boundsB = partB.bounds; - if (body.positionImpulse.x !== 0 || body.positionImpulse.y !== 0) { - // update body geometry - for (var j = 0; j < body.parts.length; j++) { - var part = body.parts[j]; - Vertices.translate(part.vertices, body.positionImpulse); - Bounds.update(part.bounds, part.vertices, body.velocity); - part.position.x += body.positionImpulse.x; - part.position.y += body.positionImpulse.y; - } + if (boundsA.min.x > boundsB.max.x || boundsA.max.x < boundsB.min.x + || boundsA.max.y < boundsB.min.y || boundsA.min.y > boundsB.max.y) { + continue; + } - // move the body without changing velocity - body.positionPrev.x += body.positionImpulse.x; - body.positionPrev.y += body.positionImpulse.y; + var collision = collides(partA, partB, pairs); - if (Vector.dot(body.positionImpulse, body.velocity) < 0) { - // reset cached impulse if the body has velocity along it - body.positionImpulse.x = 0; - body.positionImpulse.y = 0; - } else { - // warm the next iteration - body.positionImpulse.x *= Resolver._positionWarming; - body.positionImpulse.y *= Resolver._positionWarming; + if (collision) { + collisions.push(collision); + } + } + } } } } + + return collisions; }; /** - * Prepare pairs for velocity solving. - * @method preSolveVelocity - * @param {pair[]} pairs + * Returns `true` if both supplied collision filters will allow a collision to occur. + * See `body.collisionFilter` for more information. + * @method canCollide + * @param {} filterA + * @param {} filterB + * @return {bool} `true` if collision can occur */ - Resolver.preSolveVelocity = function(pairs) { - var i, - j, - pair, - contacts, - collision, - bodyA, - bodyB, - normal, - tangent, - contact, - contactVertex, - normalImpulse, - tangentImpulse, - offset, - impulse = Vector._temp[0], - tempA = Vector._temp[1]; - - for (i = 0; i < pairs.length; i++) { - pair = pairs[i]; - - if (!pair.isActive || pair.isSensor) - continue; - - contacts = pair.activeContacts; - collision = pair.collision; - bodyA = collision.parentA; - bodyB = collision.parentB; - normal = collision.normal; - tangent = collision.tangent; - - // resolve each contact - for (j = 0; j < contacts.length; j++) { - contact = contacts[j]; - contactVertex = contact.vertex; - normalImpulse = contact.normalImpulse; - tangentImpulse = contact.tangentImpulse; - - if (normalImpulse !== 0 || tangentImpulse !== 0) { - // total impulse from contact - impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse); - impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse); - - // apply impulse from contact - if (!(bodyA.isStatic || bodyA.isSleeping)) { - offset = Vector.sub(contactVertex, bodyA.position, tempA); - bodyA.positionPrev.x += impulse.x * bodyA.inverseMass; - bodyA.positionPrev.y += impulse.y * bodyA.inverseMass; - bodyA.anglePrev += Vector.cross(offset, impulse) * bodyA.inverseInertia; - } + Detector.canCollide = function(filterA, filterB) { + if (filterA.group === filterB.group && filterA.group !== 0) + return filterA.group > 0; - if (!(bodyB.isStatic || bodyB.isSleeping)) { - offset = Vector.sub(contactVertex, bodyB.position, tempA); - bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass; - bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass; - bodyB.anglePrev -= Vector.cross(offset, impulse) * bodyB.inverseInertia; - } - } - } - } + return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0; }; /** - * Find a solution for pair velocities. - * @method solveVelocity - * @param {pair[]} pairs - * @param {number} timeScale + * The comparison function used in the broadphase algorithm. + * Returns the signed delta of the bodies bounds on the x-axis. + * @private + * @method _sortCompare + * @param {body} bodyA + * @param {body} bodyB + * @return {number} The signed delta used for sorting */ - Resolver.solveVelocity = function(pairs, timeScale) { - var timeScaleSquared = timeScale * timeScale, - impulse = Vector._temp[0], - tempA = Vector._temp[1], - tempB = Vector._temp[2], - tempC = Vector._temp[3], - tempD = Vector._temp[4], - tempE = Vector._temp[5]; - - for (var i = 0; i < pairs.length; i++) { - var pair = pairs[i]; - - if (!pair.isActive || pair.isSensor) - continue; - - var collision = pair.collision, - bodyA = collision.parentA, - bodyB = collision.parentB, - normal = collision.normal, - tangent = collision.tangent, - contacts = pair.activeContacts, - contactShare = 1 / contacts.length; - - // update body velocities - bodyA.velocity.x = bodyA.position.x - bodyA.positionPrev.x; - bodyA.velocity.y = bodyA.position.y - bodyA.positionPrev.y; - bodyB.velocity.x = bodyB.position.x - bodyB.positionPrev.x; - bodyB.velocity.y = bodyB.position.y - bodyB.positionPrev.y; - bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev; - bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev; - - // resolve each contact - for (var j = 0; j < contacts.length; j++) { - var contact = contacts[j], - contactVertex = contact.vertex, - offsetA = Vector.sub(contactVertex, bodyA.position, tempA), - offsetB = Vector.sub(contactVertex, bodyB.position, tempB), - velocityPointA = Vector.add(bodyA.velocity, Vector.mult(Vector.perp(offsetA), bodyA.angularVelocity), tempC), - velocityPointB = Vector.add(bodyB.velocity, Vector.mult(Vector.perp(offsetB), bodyB.angularVelocity), tempD), - relativeVelocity = Vector.sub(velocityPointA, velocityPointB, tempE), - normalVelocity = Vector.dot(normal, relativeVelocity); - - var tangentVelocity = Vector.dot(tangent, relativeVelocity), - tangentSpeed = Math.abs(tangentVelocity), - tangentVelocityDirection = Common.sign(tangentVelocity); - - // raw impulses - var normalImpulse = (1 + pair.restitution) * normalVelocity, - normalForce = Common.clamp(pair.separation + normalVelocity, 0, 1) * Resolver._frictionNormalMultiplier; - - // coulomb friction - var tangentImpulse = tangentVelocity, - maxFriction = Infinity; - - if (tangentSpeed > pair.friction * pair.frictionStatic * normalForce * timeScaleSquared) { - maxFriction = tangentSpeed; - tangentImpulse = Common.clamp( - pair.friction * tangentVelocityDirection * timeScaleSquared, - -maxFriction, maxFriction - ); - } - - // modify impulses accounting for mass, inertia and offset - var oAcN = Vector.cross(offsetA, normal), - oBcN = Vector.cross(offsetB, normal), - share = contactShare / (bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN); - - normalImpulse *= share; - tangentImpulse *= share; - - // handle high velocity and resting collisions separately - if (normalVelocity < 0 && normalVelocity * normalVelocity > Resolver._restingThresh * timeScaleSquared) { - // high normal velocity so clear cached contact normal impulse - contact.normalImpulse = 0; - } else { - // solve resting collision constraints using Erin Catto's method (GDC08) - // impulse constraint tends to 0 - var contactNormalImpulse = contact.normalImpulse; - contact.normalImpulse = Math.min(contact.normalImpulse + normalImpulse, 0); - normalImpulse = contact.normalImpulse - contactNormalImpulse; - } + Detector._compareBoundsX = function(bodyA, bodyB) { + return bodyA.bounds.min.x - bodyB.bounds.min.x; + }; - // handle high velocity and resting collisions separately - if (tangentVelocity * tangentVelocity > Resolver._restingThreshTangent * timeScaleSquared) { - // high tangent velocity so clear cached contact tangent impulse - contact.tangentImpulse = 0; - } else { - // solve resting collision constraints using Erin Catto's method (GDC08) - // tangent impulse tends to -tangentSpeed or +tangentSpeed - var contactTangentImpulse = contact.tangentImpulse; - contact.tangentImpulse = Common.clamp(contact.tangentImpulse + tangentImpulse, -maxFriction, maxFriction); - tangentImpulse = contact.tangentImpulse - contactTangentImpulse; - } + /* + * + * Properties Documentation + * + */ - // total impulse from contact - impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse); - impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse); - - // apply impulse from contact - if (!(bodyA.isStatic || bodyA.isSleeping)) { - bodyA.positionPrev.x += impulse.x * bodyA.inverseMass; - bodyA.positionPrev.y += impulse.y * bodyA.inverseMass; - bodyA.anglePrev += Vector.cross(offsetA, impulse) * bodyA.inverseInertia; - } + /** + * The array of `Matter.Body` between which the detector finds collisions. + * + * _Note:_ The order of bodies in this array _is not fixed_ and will be continually managed by the detector. + * @property bodies + * @type body[] + * @default [] + */ - if (!(bodyB.isStatic || bodyB.isSleeping)) { - bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass; - bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass; - bodyB.anglePrev -= Vector.cross(offsetB, impulse) * bodyB.inverseInertia; - } - } - } - }; + /** + * Optional. A `Matter.Pairs` object from which previous collision objects may be reused. Intended for internal `Matter.Engine` usage. + * @property pairs + * @type {pairs|null} + * @default null + */ })(); /***/ }), -/* 600 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); -try { - // This works if eval is allowed (see CSP) - g = g || new Function("return this")(); -} catch (e) { - // This works if the window reference is available - if (typeof window === "object") g = window; -} +/***/ 70584: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} +/** +* The `Matter.Pair` module contains methods for creating and manipulating collision pairs. +* +* @class Pair +*/ -module.exports = g; +var Pair = {}; +module.exports = Pair; -/***/ }), -/* 601 */ -/***/ (function(module, exports, __webpack_require__) { +var Contact = __webpack_require__(17319); -/** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +(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 QuickSet = __webpack_require__(276); + var pair = { + id: Pair.id(bodyA, bodyB), + bodyA: bodyA, + bodyB: bodyB, + collision: collision, + contacts: [], + activeContacts: [], + separation: 0, + isActive: true, + confirmedActive: true, + isSensor: bodyA.isSensor || bodyB.isSensor, + timeCreated: timestamp, + timeUpdated: timestamp, + inverseMass: 0, + friction: 0, + frictionStatic: 0, + restitution: 0, + slop: 0 + }; -/** - * Takes an array of Game Objects, or any objects that have public `x` and `y` properties, and aligns them next to each other. - * - * The first item isn't moved. The second item is aligned next to the first, then the third next to the second, and so on. - * - * @function Phaser.Actions.AlignTo - * @since 3.22.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} position - The position to align the items with. This is an align constant, such as `Phaser.Display.Align.LEFT_CENTER`. - * @param {number} [offsetX=0] - Optional horizontal offset from the position. - * @param {number} [offsetY=0] - Optional vertical offset from the position. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var AlignTo = function (items, position, offsetX, offsetY) -{ - var target = items[0]; + Pair.update(pair, collision, timestamp); - for (var i = 1; i < items.length; i++) - { - var item = items[i]; + return pair; + }; - QuickSet(item, target, position, offsetX, offsetY); + /** + * Updates a pair given a collision. + * @method update + * @param {pair} pair + * @param {collision} collision + * @param {number} timestamp + */ + Pair.update = function(pair, collision, timestamp) { + var contacts = pair.contacts, + supports = collision.supports, + activeContacts = pair.activeContacts, + parentA = collision.parentA, + parentB = collision.parentB, + parentAVerticesLength = parentA.vertices.length; + + pair.isActive = true; + pair.timeUpdated = timestamp; + pair.collision = collision; + pair.separation = collision.depth; + pair.inverseMass = parentA.inverseMass + parentB.inverseMass; + pair.friction = parentA.friction < parentB.friction ? parentA.friction : parentB.friction; + pair.frictionStatic = parentA.frictionStatic > parentB.frictionStatic ? parentA.frictionStatic : parentB.frictionStatic; + pair.restitution = parentA.restitution > parentB.restitution ? parentA.restitution : parentB.restitution; + pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop; + + collision.pair = pair; + activeContacts.length = 0; + + for (var i = 0; i < supports.length; i++) { + var support = supports[i], + contactId = support.body === parentA ? support.index : parentAVerticesLength + support.index, + contact = contacts[contactId]; - target = item; - } + if (contact) { + activeContacts.push(contact); + } else { + activeContacts.push(contacts[contactId] = Contact.create(support)); + } + } + }; + + /** + * 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; + } + }; - return items; -}; + /** + * 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; + } + }; -module.exports = AlignTo; +})(); /***/ }), -/* 602 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ -var PropertyValueInc = __webpack_require__(46); +/***/ 91327: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Takes an array of Game Objects, or any objects that have a public `angle` property, - * and then adds the given value to each of their `angle` properties. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `Angle(group.getChildren(), value, step)` - * - * @function Phaser.Actions.Angle - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to be added to the `angle` property. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var Angle = function (items, value, step, index, direction) -{ - return PropertyValueInc(items, 'angle', value, step, index, direction); -}; +* The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets. +* +* @class Pairs +*/ -module.exports = Angle; +var Pairs = {}; +module.exports = Pairs; -/***/ }), -/* 603 */ -/***/ (function(module, exports) { +var Pair = __webpack_require__(70584); +var Common = __webpack_require__(68758); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +(function() { -/** - * Takes an array of objects and passes each of them to the given callback. - * - * @function Phaser.Actions.Call - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {Phaser.Types.Actions.CallCallback} callback - The callback to be invoked. It will be passed just one argument: the item from the array. - * @param {*} context - The scope in which the callback will be invoked. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that was passed to this Action. - */ -var Call = function (items, callback, context) -{ - for (var i = 0; i < items.length; i++) - { - var item = items[i]; + /** + * Creates a new pairs structure. + * @method create + * @param {object} options + * @return {pairs} A new pairs structure + */ + Pairs.create = function(options) { + return Common.extend({ + table: {}, + list: [], + collisionStart: [], + collisionActive: [], + collisionEnd: [] + }, options); + }; - callback.call(context, item); - } + /** + * Updates pairs given a list of collisions. + * @method update + * @param {object} pairs + * @param {collision[]} collisions + * @param {number} timestamp + */ + Pairs.update = function(pairs, collisions, timestamp) { + var pairsList = pairs.list, + pairsListLength = pairsList.length, + pairsTable = pairs.table, + collisionsLength = collisions.length, + collisionStart = pairs.collisionStart, + collisionEnd = pairs.collisionEnd, + collisionActive = pairs.collisionActive, + collision, + pairIndex, + pair, + i; - return items; -}; + // clear collision state arrays, but maintain old reference + collisionStart.length = 0; + collisionEnd.length = 0; + collisionActive.length = 0; -module.exports = Call; + for (i = 0; i < pairsListLength; i++) { + pairsList[i].confirmedActive = false; + } + for (i = 0; i < collisionsLength; i++) { + collision = collisions[i]; + pair = collision.pair; -/***/ }), -/* 604 */ -/***/ (function(module, exports) { + if (pair) { + // pair already exists (but may or may not be active) + if (pair.isActive) { + // pair exists and is active + collisionActive.push(pair); + } else { + // pair exists but was inactive, so a collision has just started again + collisionStart.push(pair); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // update the pair + Pair.update(pair, collision, timestamp); + pair.confirmedActive = true; + } else { + // pair did not exist, create a new pair + pair = Pair.create(collision, timestamp); + pairsTable[pair.id] = pair; -/** - * Takes an array of objects and returns the first element in the array that has properties which match - * all of those specified in the `compare` object. For example, if the compare object was: `{ scaleX: 0.5, alpha: 1 }` - * then it would return the first item which had the property `scaleX` set to 0.5 and `alpha` set to 1. - * - * To use this with a Group: `GetFirst(group.getChildren(), compare, index)` - * - * @function Phaser.Actions.GetFirst - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be searched by this action. - * @param {object} compare - The comparison object. Each property in this object will be checked against the items of the array. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * - * @return {?(object|Phaser.GameObjects.GameObject)} The first object in the array that matches the comparison object, or `null` if no match was found. - */ -var GetFirst = function (items, compare, index) -{ - if (index === undefined) { index = 0; } + // push the new pair + collisionStart.push(pair); + pairsList.push(pair); + } + } - for (var i = index; i < items.length; i++) - { - var item = items[i]; + // find pairs that are no longer active + var removePairIndex = []; + pairsListLength = pairsList.length; - var match = true; + for (i = 0; i < pairsListLength; i++) { + pair = pairsList[i]; + + if (!pair.confirmedActive) { + Pair.setActive(pair, false, timestamp); + collisionEnd.push(pair); - for (var property in compare) - { - if (item[property] !== compare[property]) - { - match = false; + if (!pair.collision.bodyA.isSleeping && !pair.collision.bodyB.isSleeping) { + removePairIndex.push(i); + } } } - if (match) - { - return item; + // remove inactive pairs + for (i = 0; i < removePairIndex.length; i++) { + pairIndex = removePairIndex[i] - i; + pair = pairsList[pairIndex]; + pairsList.splice(pairIndex, 1); + delete pairsTable[pair.id]; } - } + }; - return null; -}; + /** + * Clears the given pairs structure. + * @method clear + * @param {pairs} pairs + * @return {pairs} pairs + */ + Pairs.clear = function(pairs) { + pairs.table = {}; + pairs.list.length = 0; + pairs.collisionStart.length = 0; + pairs.collisionActive.length = 0; + pairs.collisionEnd.length = 0; + return pairs; + }; -module.exports = GetFirst; +})(); /***/ }), -/* 605 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 13390: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Takes an array of objects and returns the last element in the array that has properties which match - * all of those specified in the `compare` object. For example, if the compare object was: `{ scaleX: 0.5, alpha: 1 }` - * then it would return the last item which had the property `scaleX` set to 0.5 and `alpha` set to 1. - * - * To use this with a Group: `GetLast(group.getChildren(), compare, index)` - * - * @function Phaser.Actions.GetLast - * @since 3.3.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be searched by this action. - * @param {object} compare - The comparison object. Each property in this object will be checked against the items of the array. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * - * @return {?(object|Phaser.GameObjects.GameObject)} The last object in the array that matches the comparison object, or `null` if no match was found. - */ -var GetLast = function (items, compare, index) -{ - if (index === undefined) { index = 0; } - - for (var i = index; i < items.length; i++) - { - var item = items[i]; - - var match = true; - - for (var property in compare) - { - if (item[property] !== compare[property]) - { - match = false; - } - } - - if (match) - { - return item; - } - } +* The `Matter.Query` module contains methods for performing collision queries. +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Query +*/ - return null; -}; +var Query = {}; -module.exports = GetLast; +module.exports = Query; +var Vector = __webpack_require__(10438); +var Collision = __webpack_require__(63454); +var Bounds = __webpack_require__(84091); +var Bodies = __webpack_require__(68516); +var Vertices = __webpack_require__(39745); -/***/ }), -/* 606 */ -/***/ (function(module, exports, __webpack_require__) { +(function() { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Returns a list of collisions between `body` and `bodies`. + * @method collides + * @param {body} body + * @param {body[]} bodies + * @return {collision[]} Collisions + */ + Query.collides = function(body, bodies) { + var collisions = [], + bodiesLength = bodies.length, + bounds = body.bounds, + collides = Collision.collides, + overlaps = Bounds.overlaps; -var AlignIn = __webpack_require__(289); -var CONST = __webpack_require__(123); -var GetFastValue = __webpack_require__(2); -var NOOP = __webpack_require__(1); -var Zone = __webpack_require__(129); + for (var i = 0; i < bodiesLength; i++) { + var bodyA = bodies[i], + partsALength = bodyA.parts.length, + partsAStart = partsALength === 1 ? 0 : 1; -var tempZone = new Zone({ sys: { queueDepthSort: NOOP, events: { once: NOOP } } }, 0, 0, 1, 1); + // Phaser addition - skip same body checks + if (body === bodyA) + { + continue; + } -/** - * Takes an array of Game Objects, or any objects that have public `x` and `y` properties, - * and then aligns them based on the grid configuration given to this action. - * - * @function Phaser.Actions.GridAlign - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {Phaser.Types.Actions.GridAlignConfig} options - The GridAlign Configuration object. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var GridAlign = function (items, options) -{ - if (options === undefined) { options = {}; } + if (overlaps(bodyA.bounds, bounds)) { + for (var j = partsAStart; j < partsALength; j++) { + var part = bodyA.parts[j]; - var widthSet = options.hasOwnProperty('width'); - var heightSet = options.hasOwnProperty('height'); + if (overlaps(part.bounds, bounds)) { + var collision = collides(part, body); - var width = GetFastValue(options, 'width', -1); - var height = GetFastValue(options, 'height', -1); + if (collision) { + collisions.push(collision); + break; + } + } + } + } + } - var cellWidth = GetFastValue(options, 'cellWidth', 1); - var cellHeight = GetFastValue(options, 'cellHeight', cellWidth); + return collisions; + }; - var position = GetFastValue(options, 'position', CONST.TOP_LEFT); - var x = GetFastValue(options, 'x', 0); - var y = GetFastValue(options, 'y', 0); + /** + * Casts a ray segment against a set of bodies and returns all collisions, ray width is optional. Intersection points are not provided. + * @method ray + * @param {body[]} bodies + * @param {vector} startPoint + * @param {vector} endPoint + * @param {number} [rayWidth] + * @return {collision[]} Collisions + */ + Query.ray = function(bodies, startPoint, endPoint, rayWidth) { + rayWidth = rayWidth || 1e-100; - var cx = 0; - var cy = 0; - var w = (width * cellWidth); - var h = (height * cellHeight); + var rayAngle = Vector.angle(startPoint, endPoint), + rayLength = Vector.magnitude(Vector.sub(startPoint, endPoint)), + rayX = (endPoint.x + startPoint.x) * 0.5, + rayY = (endPoint.y + startPoint.y) * 0.5, + ray = Bodies.rectangle(rayX, rayY, rayLength, rayWidth, { angle: rayAngle }), + collisions = Query.collides(ray, bodies); - tempZone.setPosition(x, y); - tempZone.setSize(cellWidth, cellHeight); + for (var i = 0; i < collisions.length; i += 1) { + var collision = collisions[i]; + collision.body = collision.bodyB = collision.bodyA; + } - for (var i = 0; i < items.length; i++) - { - AlignIn(items[i], tempZone, position); + return collisions; + }; - if (widthSet && width === -1) - { - // We keep laying them out horizontally until we've done them all - tempZone.x += cellWidth; - } - else if (heightSet && height === -1) - { - // We keep laying them out vertically until we've done them all - tempZone.y += cellHeight; + /** + * Returns all bodies whose bounds are inside (or outside if set) the given set of bounds, from the given set of bodies. + * @method region + * @param {body[]} bodies + * @param {bounds} bounds + * @param {bool} [outside=false] + * @return {body[]} The bodies matching the query + */ + Query.region = function(bodies, bounds, outside) { + var result = []; + + for (var i = 0; i < bodies.length; i++) { + var body = bodies[i], + overlaps = Bounds.overlaps(body.bounds, bounds); + if ((overlaps && !outside) || (!overlaps && outside)) + result.push(body); } - else if (heightSet && !widthSet) - { - // We keep laying them out until we hit the column limit - cy += cellHeight; - tempZone.y += cellHeight; - if (cy === h) - { - cy = 0; - cx += cellWidth; - tempZone.y = y; - tempZone.x += cellWidth; + return result; + }; - if (cx === w) - { - // We've hit the column limit, so return, even if there are items left - break; - } - } - } - else - { - // We keep laying them out until we hit the column limit - cx += cellWidth; - tempZone.x += cellWidth; + /** + * Returns all bodies whose vertices contain the given point, from the given set of bodies. + * @method point + * @param {body[]} bodies + * @param {vector} point + * @return {body[]} The bodies matching the query + */ + Query.point = function(bodies, point) { + var result = []; - if (cx === w) - { - cx = 0; - cy += cellHeight; - tempZone.x = x; - tempZone.y += cellHeight; + for (var i = 0; i < bodies.length; i++) { + var body = bodies[i]; - if (cy === h) - { - // We've hit the column limit, so return, even if there are items left - break; + if (Bounds.contains(body.bounds, point)) { + for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) { + var part = body.parts[j]; + + if (Bounds.contains(part.bounds, point) + && Vertices.contains(part.vertices, point)) { + result.push(body); + break; + } } } } - } - return items; -}; + return result; + }; -module.exports = GridAlign; +})(); /***/ }), -/* 607 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 44272: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +* The `Matter.Resolver` module contains methods for resolving collision pairs. +* +* @class Resolver +*/ -var Clamp = __webpack_require__(18); +var Resolver = {}; -// bitmask flag for GameObject.renderMask -var _FLAG = 2; // 0010 +module.exports = Resolver; -/** - * Provides methods used for setting the alpha properties of a Game Object. - * Should be applied as a mixin and not used directly. - * - * @namespace Phaser.GameObjects.Components.Alpha - * @since 3.0.0 - */ +var Vertices = __webpack_require__(39745); +var Common = __webpack_require__(68758); +var Bounds = __webpack_require__(84091); -var Alpha = { +(function() { - /** - * Private internal value. Holds the global alpha value. - * - * @name Phaser.GameObjects.Components.Alpha#_alpha - * @type {number} - * @private - * @default 1 - * @since 3.0.0 - */ - _alpha: 1, + Resolver._restingThresh = 2; + Resolver._restingThreshTangent = Math.sqrt(6); + Resolver._positionDampen = 0.9; + Resolver._positionWarming = 0.8; + Resolver._frictionNormalMultiplier = 5; + Resolver._frictionMaxStatic = Number.MAX_VALUE; /** - * Private internal value. Holds the top-left alpha value. - * - * @name Phaser.GameObjects.Components.Alpha#_alphaTL - * @type {number} - * @private - * @default 1 - * @since 3.0.0 + * Prepare pairs for position solving. + * @method preSolvePosition + * @param {pair[]} pairs */ - _alphaTL: 1, + Resolver.preSolvePosition = function(pairs) { + var i, + pair, + activeCount, + pairsLength = pairs.length; - /** - * Private internal value. Holds the top-right alpha value. - * - * @name Phaser.GameObjects.Components.Alpha#_alphaTR - * @type {number} - * @private - * @default 1 - * @since 3.0.0 - */ - _alphaTR: 1, + // find total contacts on each body + for (i = 0; i < pairsLength; i++) { + pair = pairs[i]; - /** - * Private internal value. Holds the bottom-left alpha value. - * - * @name Phaser.GameObjects.Components.Alpha#_alphaBL - * @type {number} - * @private - * @default 1 - * @since 3.0.0 - */ - _alphaBL: 1, + if (!pair.isActive) + continue; - /** - * Private internal value. Holds the bottom-right alpha value. - * - * @name Phaser.GameObjects.Components.Alpha#_alphaBR - * @type {number} - * @private - * @default 1 - * @since 3.0.0 - */ - _alphaBR: 1, + activeCount = pair.activeContacts.length; + pair.collision.parentA.totalContacts += activeCount; + pair.collision.parentB.totalContacts += activeCount; + } + }; /** - * Clears all alpha values associated with this Game Object. - * - * Immediately sets the alpha levels back to 1 (fully opaque). - * - * @method Phaser.GameObjects.Components.Alpha#clearAlpha - * @since 3.0.0 - * - * @return {this} This Game Object instance. + * Find a solution for pair positions. + * @method solvePosition + * @param {pair[]} pairs + * @param {number} delta + * @param {number} [damping=1] */ - clearAlpha: function () - { - return this.setAlpha(1); - }, + Resolver.solvePosition = function(pairs, delta, damping) { + var i, + pair, + collision, + bodyA, + bodyB, + normal, + contactShare, + positionImpulse, + positionDampen = Resolver._positionDampen * (damping || 1), + slopDampen = Common.clamp(delta / Common._baseDelta, 0, 1), + pairsLength = pairs.length; - /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * - * If your game is running under WebGL you can optionally specify four different alpha values, each of which - * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. - * - * @method Phaser.GameObjects.Components.Alpha#setAlpha - * @since 3.0.0 - * - * @param {number} [topLeft=1] - The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. - * @param {number} [topRight] - The alpha value used for the top-right of the Game Object. WebGL only. - * @param {number} [bottomLeft] - The alpha value used for the bottom-left of the Game Object. WebGL only. - * @param {number} [bottomRight] - The alpha value used for the bottom-right of the Game Object. WebGL only. - * - * @return {this} This Game Object instance. - */ - setAlpha: function (topLeft, topRight, bottomLeft, bottomRight) - { - if (topLeft === undefined) { topLeft = 1; } + // find impulses required to resolve penetration + for (i = 0; i < pairsLength; i++) { + pair = pairs[i]; - // Treat as if there is only one alpha value for the whole Game Object - if (topRight === undefined) - { - this.alpha = topLeft; - } - else - { - this._alphaTL = Clamp(topLeft, 0, 1); - this._alphaTR = Clamp(topRight, 0, 1); - this._alphaBL = Clamp(bottomLeft, 0, 1); - this._alphaBR = Clamp(bottomRight, 0, 1); - } + if (!pair.isActive || pair.isSensor) + continue; - return this; - }, + collision = pair.collision; + bodyA = collision.parentA; + bodyB = collision.parentB; + normal = collision.normal; - /** - * The alpha value of the Game Object. - * - * This is a global value, impacting the entire Game Object, not just a region of it. - * - * @name Phaser.GameObjects.Components.Alpha#alpha - * @type {number} - * @since 3.0.0 - */ - alpha: { + // get current separation between body edges involved in collision + pair.separation = + normal.x * (bodyB.positionImpulse.x + collision.penetration.x - bodyA.positionImpulse.x) + + normal.y * (bodyB.positionImpulse.y + collision.penetration.y - bodyA.positionImpulse.y); + } - get: function () - { - return this._alpha; - }, + for (i = 0; i < pairsLength; i++) { + pair = pairs[i]; - set: function (value) - { - var v = Clamp(value, 0, 1); + if (!pair.isActive || pair.isSensor) + continue; - this._alpha = v; - this._alphaTL = v; - this._alphaTR = v; - this._alphaBL = v; - this._alphaBR = v; + collision = pair.collision; + bodyA = collision.parentA; + bodyB = collision.parentB; + normal = collision.normal; + positionImpulse = pair.separation - pair.slop * slopDampen; - if (v === 0) - { - this.renderFlags &= ~_FLAG; + if (bodyA.isStatic || bodyB.isStatic) + positionImpulse *= 2; + + if (!(bodyA.isStatic || bodyA.isSleeping)) { + contactShare = positionDampen / bodyA.totalContacts; + bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare; + bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare; } - else - { - this.renderFlags |= _FLAG; + + if (!(bodyB.isStatic || bodyB.isSleeping)) { + contactShare = positionDampen / bodyB.totalContacts; + bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare; + bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare; } } - - }, + }; /** - * The alpha value starting from the top-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * - * @name Phaser.GameObjects.Components.Alpha#alphaTopLeft - * @type {number} - * @webglOnly - * @since 3.0.0 + * Apply position resolution. + * @method postSolvePosition + * @param {body[]} bodies */ - alphaTopLeft: { + Resolver.postSolvePosition = function(bodies) { + var positionWarming = Resolver._positionWarming, + bodiesLength = bodies.length, + verticesTranslate = Vertices.translate, + boundsUpdate = Bounds.update; - get: function () - { - return this._alphaTL; - }, + for (var i = 0; i < bodiesLength; i++) { + var body = bodies[i], + positionImpulse = body.positionImpulse, + positionImpulseX = positionImpulse.x, + positionImpulseY = positionImpulse.y, + velocity = body.velocity; - set: function (value) - { - var v = Clamp(value, 0, 1); + // reset contact count + body.totalContacts = 0; - this._alphaTL = v; + if (positionImpulseX !== 0 || positionImpulseY !== 0) { + // update body geometry + for (var j = 0; j < body.parts.length; j++) { + var part = body.parts[j]; + verticesTranslate(part.vertices, positionImpulse); + boundsUpdate(part.bounds, part.vertices, velocity); + part.position.x += positionImpulseX; + part.position.y += positionImpulseY; + } - if (v !== 0) - { - this.renderFlags |= _FLAG; + // move the body without changing velocity + body.positionPrev.x += positionImpulseX; + body.positionPrev.y += positionImpulseY; + + if (positionImpulseX * velocity.x + positionImpulseY * velocity.y < 0) { + // reset cached impulse if the body has velocity along it + positionImpulse.x = 0; + positionImpulse.y = 0; + } else { + // warm the next iteration + positionImpulse.x *= positionWarming; + positionImpulse.y *= positionWarming; + } } } - - }, + }; /** - * The alpha value starting from the top-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * - * @name Phaser.GameObjects.Components.Alpha#alphaTopRight - * @type {number} - * @webglOnly - * @since 3.0.0 + * Prepare pairs for velocity solving. + * @method preSolveVelocity + * @param {pair[]} pairs */ - alphaTopRight: { + Resolver.preSolveVelocity = function(pairs) { + var pairsLength = pairs.length, + i, + j; - get: function () - { - return this._alphaTR; - }, + for (i = 0; i < pairsLength; i++) { + var pair = pairs[i]; - set: function (value) - { - var v = Clamp(value, 0, 1); + if (!pair.isActive || pair.isSensor) + continue; - this._alphaTR = v; + var contacts = pair.activeContacts, + contactsLength = contacts.length, + collision = pair.collision, + bodyA = collision.parentA, + bodyB = collision.parentB, + normal = collision.normal, + tangent = collision.tangent; - if (v !== 0) - { - this.renderFlags |= _FLAG; + // resolve each contact + for (j = 0; j < contactsLength; j++) { + var contact = contacts[j], + contactVertex = contact.vertex, + normalImpulse = contact.normalImpulse, + tangentImpulse = contact.tangentImpulse; + + if (normalImpulse !== 0 || tangentImpulse !== 0) { + // total impulse from contact + var impulseX = normal.x * normalImpulse + tangent.x * tangentImpulse, + impulseY = normal.y * normalImpulse + tangent.y * tangentImpulse; + + // apply impulse from contact + if (!(bodyA.isStatic || bodyA.isSleeping)) { + bodyA.positionPrev.x += impulseX * bodyA.inverseMass; + bodyA.positionPrev.y += impulseY * bodyA.inverseMass; + bodyA.anglePrev += bodyA.inverseInertia * ( + (contactVertex.x - bodyA.position.x) * impulseY + - (contactVertex.y - bodyA.position.y) * impulseX + ); + } + + if (!(bodyB.isStatic || bodyB.isSleeping)) { + bodyB.positionPrev.x -= impulseX * bodyB.inverseMass; + bodyB.positionPrev.y -= impulseY * bodyB.inverseMass; + bodyB.anglePrev -= bodyB.inverseInertia * ( + (contactVertex.x - bodyB.position.x) * impulseY + - (contactVertex.y - bodyB.position.y) * impulseX + ); + } + } } } - - }, + }; /** - * The alpha value starting from the bottom-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * - * @name Phaser.GameObjects.Components.Alpha#alphaBottomLeft - * @type {number} - * @webglOnly - * @since 3.0.0 - */ - alphaBottomLeft: { + * Find a solution for pair velocities. + * @method solveVelocity + * @param {pair[]} pairs + * @param {number} delta + */ + Resolver.solveVelocity = function(pairs, delta) { + var timeScale = delta / Common._baseDelta, + timeScaleSquared = timeScale * timeScale, + timeScaleCubed = timeScaleSquared * timeScale, + restingThresh = -Resolver._restingThresh * timeScale, + restingThreshTangent = Resolver._restingThreshTangent, + frictionNormalMultiplier = Resolver._frictionNormalMultiplier * timeScale, + frictionMaxStatic = Resolver._frictionMaxStatic, + pairsLength = pairs.length, + tangentImpulse, + maxFriction, + i, + j; - get: function () - { - return this._alphaBL; - }, + for (i = 0; i < pairsLength; i++) { + var pair = pairs[i]; - set: function (value) - { - var v = Clamp(value, 0, 1); + if (!pair.isActive || pair.isSensor) + continue; - this._alphaBL = v; + var collision = pair.collision, + bodyA = collision.parentA, + bodyB = collision.parentB, + bodyAVelocity = bodyA.velocity, + bodyBVelocity = bodyB.velocity, + normalX = collision.normal.x, + normalY = collision.normal.y, + tangentX = collision.tangent.x, + tangentY = collision.tangent.y, + contacts = pair.activeContacts, + contactsLength = contacts.length, + contactShare = 1 / contactsLength, + inverseMassTotal = bodyA.inverseMass + bodyB.inverseMass, + friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier; - if (v !== 0) - { - this.renderFlags |= _FLAG; - } - } + // update body velocities + bodyAVelocity.x = bodyA.position.x - bodyA.positionPrev.x; + bodyAVelocity.y = bodyA.position.y - bodyA.positionPrev.y; + bodyBVelocity.x = bodyB.position.x - bodyB.positionPrev.x; + bodyBVelocity.y = bodyB.position.y - bodyB.positionPrev.y; + bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev; + bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev; - }, + // resolve each contact + for (j = 0; j < contactsLength; j++) { + var contact = contacts[j], + contactVertex = contact.vertex; - /** - * The alpha value starting from the bottom-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * - * @name Phaser.GameObjects.Components.Alpha#alphaBottomRight - * @type {number} - * @webglOnly - * @since 3.0.0 - */ - alphaBottomRight: { + var offsetAX = contactVertex.x - bodyA.position.x, + offsetAY = contactVertex.y - bodyA.position.y, + offsetBX = contactVertex.x - bodyB.position.x, + offsetBY = contactVertex.y - bodyB.position.y; - get: function () - { - return this._alphaBR; - }, + var velocityPointAX = bodyAVelocity.x - offsetAY * bodyA.angularVelocity, + velocityPointAY = bodyAVelocity.y + offsetAX * bodyA.angularVelocity, + velocityPointBX = bodyBVelocity.x - offsetBY * bodyB.angularVelocity, + velocityPointBY = bodyBVelocity.y + offsetBX * bodyB.angularVelocity; - set: function (value) - { - var v = Clamp(value, 0, 1); + var relativeVelocityX = velocityPointAX - velocityPointBX, + relativeVelocityY = velocityPointAY - velocityPointBY; - this._alphaBR = v; + var normalVelocity = normalX * relativeVelocityX + normalY * relativeVelocityY, + tangentVelocity = tangentX * relativeVelocityX + tangentY * relativeVelocityY; - if (v !== 0) - { - this.renderFlags |= _FLAG; - } - } + // coulomb friction + var normalOverlap = pair.separation + normalVelocity; + var normalForce = Math.min(normalOverlap, 1); + normalForce = normalOverlap < 0 ? 0 : normalForce; - } + var frictionLimit = normalForce * friction; -}; + if (tangentVelocity < -frictionLimit || tangentVelocity > frictionLimit) { + maxFriction = (tangentVelocity > 0 ? tangentVelocity : -tangentVelocity); + tangentImpulse = pair.friction * (tangentVelocity > 0 ? 1 : -1) * timeScaleCubed; -module.exports = Alpha; + if (tangentImpulse < -maxFriction) { + tangentImpulse = -maxFriction; + } else if (tangentImpulse > maxFriction) { + tangentImpulse = maxFriction; + } + } else { + tangentImpulse = tangentVelocity; + maxFriction = frictionMaxStatic; + } + + // account for mass, inertia and contact offset + var oAcN = offsetAX * normalY - offsetAY * normalX, + oBcN = offsetBX * normalY - offsetBY * normalX, + share = contactShare / (inverseMassTotal + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN); + + // raw impulses + var normalImpulse = (1 + pair.restitution) * normalVelocity * share; + tangentImpulse *= share; + + // handle high velocity and resting collisions separately + if (normalVelocity < restingThresh) { + // high normal velocity so clear cached contact normal impulse + contact.normalImpulse = 0; + } else { + // solve resting collision constraints using Erin Catto's method (GDC08) + // impulse constraint tends to 0 + var contactNormalImpulse = contact.normalImpulse; + contact.normalImpulse += normalImpulse; + if (contact.normalImpulse > 0) contact.normalImpulse = 0; + normalImpulse = contact.normalImpulse - contactNormalImpulse; + } + + // handle high velocity and resting collisions separately + if (tangentVelocity < -restingThreshTangent || tangentVelocity > restingThreshTangent) { + // high tangent velocity so clear cached contact tangent impulse + contact.tangentImpulse = 0; + } else { + // solve resting collision constraints using Erin Catto's method (GDC08) + // tangent impulse tends to -tangentSpeed or +tangentSpeed + var contactTangentImpulse = contact.tangentImpulse; + contact.tangentImpulse += tangentImpulse; + if (contact.tangentImpulse < -maxFriction) contact.tangentImpulse = -maxFriction; + if (contact.tangentImpulse > maxFriction) contact.tangentImpulse = maxFriction; + tangentImpulse = contact.tangentImpulse - contactTangentImpulse; + } + + // total impulse from contact + var impulseX = normalX * normalImpulse + tangentX * tangentImpulse, + impulseY = normalY * normalImpulse + tangentY * tangentImpulse; + + // apply impulse from contact + if (!(bodyA.isStatic || bodyA.isSleeping)) { + bodyA.positionPrev.x += impulseX * bodyA.inverseMass; + bodyA.positionPrev.y += impulseY * bodyA.inverseMass; + bodyA.anglePrev += (offsetAX * impulseY - offsetAY * impulseX) * bodyA.inverseInertia; + } + + if (!(bodyB.isStatic || bodyB.isSleeping)) { + bodyB.positionPrev.x -= impulseX * bodyB.inverseMass; + bodyB.positionPrev.y -= impulseY * bodyB.inverseMass; + bodyB.anglePrev -= (offsetBX * impulseY - offsetBY * impulseX) * bodyB.inverseInertia; + } + } + } + }; + +})(); /***/ }), -/* 608 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 52838: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Provides methods used for calculating and setting the size of a non-Frame based Game Object. - * Should be applied as a mixin and not used directly. - * - * @namespace Phaser.GameObjects.Components.ComputedSize - * @since 3.0.0 - */ +* The `Matter.Constraint` module contains methods for creating and manipulating constraints. +* Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position). +* The stiffness of constraints can be modified to create springs or elastic. +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Constraint +*/ -var ComputedSize = { +var Constraint = {}; - /** - * The native (un-scaled) width of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. - * - * @name Phaser.GameObjects.Components.ComputedSize#width - * @type {number} - * @since 3.0.0 - */ - width: 0, +module.exports = Constraint; - /** - * The native (un-scaled) height of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. - * - * @name Phaser.GameObjects.Components.ComputedSize#height - * @type {number} - * @since 3.0.0 - */ - height: 0, +var Vertices = __webpack_require__(39745); +var Vector = __webpack_require__(10438); +var Sleeping = __webpack_require__(22806); +var Bounds = __webpack_require__(84091); +var Axes = __webpack_require__(50658); +var Common = __webpack_require__(68758); + +(function() { + + Constraint._warming = 0.4; + Constraint._torqueDampen = 1; + Constraint._minLength = 0.000001; /** - * The displayed width of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - * - * @name Phaser.GameObjects.Components.ComputedSize#displayWidth - * @type {number} - * @since 3.0.0 + * Creates a new constraint. + * All properties have default values, and many are pre-calculated automatically based on other properties. + * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` value (e.g. `0.7` or above). + * If the constraint is unstable, try lowering the `stiffness` value and / or increasing `engine.constraintIterations`. + * For compound bodies, constraints must be applied to the parent body (not one of its parts). + * See the properties section below for detailed information on what you can pass via the `options` object. + * @method create + * @param {} options + * @return {constraint} constraint */ - displayWidth: { + Constraint.create = function(options) { + var constraint = options; - get: function () - { - return this.scaleX * this.width; - }, + // if bodies defined but no points, use body centre + if (constraint.bodyA && !constraint.pointA) + constraint.pointA = { x: 0, y: 0 }; + if (constraint.bodyB && !constraint.pointB) + constraint.pointB = { x: 0, y: 0 }; - set: function (value) - { - this.scaleX = value / this.width; + // calculate static length using initial world space points + var initialPointA = constraint.bodyA ? Vector.add(constraint.bodyA.position, constraint.pointA) : constraint.pointA, + initialPointB = constraint.bodyB ? Vector.add(constraint.bodyB.position, constraint.pointB) : constraint.pointB, + length = Vector.magnitude(Vector.sub(initialPointA, initialPointB)); + + constraint.length = typeof constraint.length !== 'undefined' ? constraint.length : length; + + // option defaults + constraint.id = constraint.id || Common.nextId(); + constraint.label = constraint.label || 'Constraint'; + constraint.type = 'constraint'; + constraint.stiffness = constraint.stiffness || (constraint.length > 0 ? 1 : 0.7); + constraint.damping = constraint.damping || 0; + constraint.angularStiffness = constraint.angularStiffness || 0; + constraint.angleA = constraint.bodyA ? constraint.bodyA.angle : constraint.angleA; + constraint.angleB = constraint.bodyB ? constraint.bodyB.angle : constraint.angleB; + constraint.plugin = {}; + + // render + var render = { + visible: true, + type: 'line', + anchors: true, + lineColor: null, // custom Phaser property + lineOpacity: null, // custom Phaser property + lineThickness: null, // custom Phaser property + pinSize: null, // custom Phaser property + anchorColor: null, // custom Phaser property + anchorSize: null // custom Phaser property + }; + + if (constraint.length === 0 && constraint.stiffness > 0.1) { + render.type = 'pin'; + render.anchors = false; + } else if (constraint.stiffness < 0.9) { + render.type = 'spring'; } - }, + constraint.render = Common.extend(render, constraint.render); + + return constraint; + }; /** - * The displayed height of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - * - * @name Phaser.GameObjects.Components.ComputedSize#displayHeight - * @type {number} - * @since 3.0.0 + * Prepares for solving by constraint warming. + * @private + * @method preSolveAll + * @param {body[]} bodies */ - displayHeight: { + Constraint.preSolveAll = function(bodies) { + for (var i = 0; i < bodies.length; i += 1) { + var body = bodies[i], + impulse = body.constraintImpulse; - get: function () - { - return this.scaleY * this.height; - }, + if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) { + continue; + } - set: function (value) - { - this.scaleY = value / this.height; + body.position.x += impulse.x; + body.position.y += impulse.y; + body.angle += impulse.angle; } - - }, + }; /** - * Sets the internal size of this Game Object, as used for frame or physics body creation. - * - * This will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or call the - * `setDisplaySize` method, which is the same thing as changing the scale but allows you - * to do so by giving pixel values. - * - * If you have enabled this Game Object for input, changing the size will _not_ change the - * size of the hit area. To do this you should adjust the `input.hitArea` object directly. - * - * @method Phaser.GameObjects.Components.ComputedSize#setSize - * @since 3.4.0 - * - * @param {number} width - The width of this Game Object. - * @param {number} height - The height of this Game Object. - * - * @return {this} This Game Object instance. + * Solves all constraints in a list of collisions. + * @private + * @method solveAll + * @param {constraint[]} constraints + * @param {number} delta */ - setSize: function (width, height) - { - this.width = width; - this.height = height; + Constraint.solveAll = function(constraints, delta) { + var timeScale = Common.clamp(delta / Common._baseDelta, 0, 1); + // Solve fixed constraints first. + for (var i = 0; i < constraints.length; i += 1) { + var constraint = constraints[i], + fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic), + fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic); - return this; - }, + if (fixedA || fixedB) { + Constraint.solve(constraints[i], timeScale); + } + } + + // Solve free constraints last. + for (i = 0; i < constraints.length; i += 1) { + constraint = constraints[i]; + fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic); + fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic); + + if (!fixedA && !fixedB) { + Constraint.solve(constraints[i], timeScale); + } + } + }; /** - * Sets the display size of this Game Object. - * - * Calling this will adjust the scale. - * - * @method Phaser.GameObjects.Components.ComputedSize#setDisplaySize - * @since 3.4.0 - * - * @param {number} width - The width of this Game Object. - * @param {number} height - The height of this Game Object. - * - * @return {this} This Game Object instance. + * Solves a distance constraint with Gauss-Siedel method. + * @private + * @method solve + * @param {constraint} constraint + * @param {number} timeScale */ - setDisplaySize: function (width, height) - { - this.displayWidth = width; - this.displayHeight = height; + Constraint.solve = function(constraint, timeScale) { + var bodyA = constraint.bodyA, + bodyB = constraint.bodyB, + pointA = constraint.pointA, + pointB = constraint.pointB; - return this; - } + if (!bodyA && !bodyB) + return; -}; + // update reference angle + if (bodyA && !bodyA.isStatic) { + Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA); + constraint.angleA = bodyA.angle; + } + + // update reference angle + if (bodyB && !bodyB.isStatic) { + Vector.rotate(pointB, bodyB.angle - constraint.angleB, pointB); + constraint.angleB = bodyB.angle; + } -module.exports = ComputedSize; + var pointAWorld = pointA, + pointBWorld = pointB; + if (bodyA) pointAWorld = Vector.add(bodyA.position, pointA); + if (bodyB) pointBWorld = Vector.add(bodyB.position, pointB); -/***/ }), -/* 609 */ -/***/ (function(module, exports) { + if (!pointAWorld || !pointBWorld) + return; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var delta = Vector.sub(pointAWorld, pointBWorld), + currentLength = Vector.magnitude(delta); -/** - * Provides methods used for getting and setting the texture of a Game Object. - * - * @namespace Phaser.GameObjects.Components.Crop - * @since 3.12.0 - */ + // prevent singularity + if (currentLength < Constraint._minLength) { + currentLength = Constraint._minLength; + } -var Crop = { + // solve distance constraint with Gauss-Siedel method + var difference = (currentLength - constraint.length) / currentLength, + isRigid = constraint.stiffness >= 1 || constraint.length === 0, + stiffness = isRigid ? constraint.stiffness * timeScale + : constraint.stiffness * timeScale * timeScale, + damping = constraint.damping * timeScale, + force = Vector.mult(delta, difference * stiffness), + massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0), + inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0), + resistanceTotal = massTotal + inertiaTotal, + torque, + share, + normal, + normalVelocity, + relativeVelocity; - /** - * The Texture this Game Object is using to render with. - * - * @name Phaser.GameObjects.Components.Crop#texture - * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} - * @since 3.0.0 - */ - texture: null, + if (damping > 0) { + var zero = Vector.create(); + normal = Vector.div(delta, currentLength); - /** - * The Texture Frame this Game Object is using to render with. - * - * @name Phaser.GameObjects.Components.Crop#frame - * @type {Phaser.Textures.Frame} - * @since 3.0.0 - */ - frame: null, + relativeVelocity = Vector.sub( + bodyB && Vector.sub(bodyB.position, bodyB.positionPrev) || zero, + bodyA && Vector.sub(bodyA.position, bodyA.positionPrev) || zero + ); - /** - * A boolean flag indicating if this Game Object is being cropped or not. - * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. - * Equally, calling `setCrop` with no arguments will reset the crop and disable it. - * - * @name Phaser.GameObjects.Components.Crop#isCropped - * @type {boolean} - * @since 3.11.0 - */ - isCropped: false, + normalVelocity = Vector.dot(normal, relativeVelocity); + } + + if (bodyA && !bodyA.isStatic) { + share = bodyA.inverseMass / massTotal; + + // keep track of applied impulses for post solving + bodyA.constraintImpulse.x -= force.x * share; + bodyA.constraintImpulse.y -= force.y * share; + + // apply forces + bodyA.position.x -= force.x * share; + bodyA.position.y -= force.y * share; + + // apply damping + if (damping > 0) { + bodyA.positionPrev.x -= damping * normal.x * normalVelocity * share; + bodyA.positionPrev.y -= damping * normal.y * normalVelocity * share; + } + + // apply torque + torque = (Vector.cross(pointA, force) / resistanceTotal) * Constraint._torqueDampen * bodyA.inverseInertia * (1 - constraint.angularStiffness); + bodyA.constraintImpulse.angle -= torque; + bodyA.angle -= torque; + } + + if (bodyB && !bodyB.isStatic) { + share = bodyB.inverseMass / massTotal; + + // keep track of applied impulses for post solving + bodyB.constraintImpulse.x += force.x * share; + bodyB.constraintImpulse.y += force.y * share; + + // apply forces + bodyB.position.x += force.x * share; + bodyB.position.y += force.y * share; + + // apply damping + if (damping > 0) { + bodyB.positionPrev.x += damping * normal.x * normalVelocity * share; + bodyB.positionPrev.y += damping * normal.y * normalVelocity * share; + } + + // apply torque + torque = (Vector.cross(pointB, force) / resistanceTotal) * Constraint._torqueDampen * bodyB.inverseInertia * (1 - constraint.angularStiffness); + bodyB.constraintImpulse.angle += torque; + bodyB.angle += torque; + } + + }; /** - * Applies a crop to a texture based Game Object, such as a Sprite or Image. - * - * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. - * - * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just - * changes what is shown when rendered. - * - * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. - * - * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left - * half of it, you could call `setCrop(0, 0, 400, 600)`. - * - * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop - * an area of 200x100 when applied to a Game Object that had a scale factor of 2. - * - * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. - * - * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. - * - * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow - * the renderer to skip several internal calculations. - * - * @method Phaser.GameObjects.Components.Crop#setCrop - * @since 3.11.0 - * - * @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. - * @param {number} [y] - The y coordinate to start the crop from. - * @param {number} [width] - The width of the crop rectangle in pixels. - * @param {number} [height] - The height of the crop rectangle in pixels. - * - * @return {this} This Game Object instance. + * Performs body updates required after solving constraints. + * @private + * @method postSolveAll + * @param {body[]} bodies */ - setCrop: function (x, y, width, height) - { - if (x === undefined) - { - this.isCropped = false; - } - else if (this.frame) - { - if (typeof x === 'number') - { - this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY); + Constraint.postSolveAll = function(bodies) { + for (var i = 0; i < bodies.length; i++) { + var body = bodies[i], + impulse = body.constraintImpulse; + + if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) { + continue; } - else - { - var rect = x; - this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY); + Sleeping.set(body, false); + + // update geometry and reset + for (var j = 0; j < body.parts.length; j++) { + var part = body.parts[j]; + + Vertices.translate(part.vertices, impulse); + + if (j > 0) { + part.position.x += impulse.x; + part.position.y += impulse.y; + } + + if (impulse.angle !== 0) { + Vertices.rotate(part.vertices, impulse.angle, body.position); + Axes.rotate(part.axes, impulse.angle); + if (j > 0) { + Vector.rotateAbout(part.position, impulse.angle, body.position, part.position); + } + } + + Bounds.update(part.bounds, part.vertices, body.velocity); } - this.isCropped = true; + // dampen the cached impulse for warming next step + impulse.angle *= Constraint._warming; + impulse.x *= Constraint._warming; + impulse.y *= Constraint._warming; } + }; - return this; - }, + /** + * Returns the world-space position of `constraint.pointA`, accounting for `constraint.bodyA`. + * @method pointAWorld + * @param {constraint} constraint + * @returns {vector} the world-space position + */ + Constraint.pointAWorld = function(constraint) { + return { + x: (constraint.bodyA ? constraint.bodyA.position.x : 0) + + (constraint.pointA ? constraint.pointA.x : 0), + y: (constraint.bodyA ? constraint.bodyA.position.y : 0) + + (constraint.pointA ? constraint.pointA.y : 0) + }; + }; /** - * Internal method that returns a blank, well-formed crop object for use by a Game Object. - * - * @method Phaser.GameObjects.Components.Crop#resetCropObject - * @private - * @since 3.12.0 - * - * @return {object} The crop object. + * Returns the world-space position of `constraint.pointB`, accounting for `constraint.bodyB`. + * @method pointBWorld + * @param {constraint} constraint + * @returns {vector} the world-space position */ - resetCropObject: function () - { - return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 }; - } + Constraint.pointBWorld = function(constraint) { + return { + x: (constraint.bodyB ? constraint.bodyB.position.x : 0) + + (constraint.pointB ? constraint.pointB.x : 0), + y: (constraint.bodyB ? constraint.bodyB.position.y : 0) + + (constraint.pointB ? constraint.pointB.y : 0) + }; + }; -}; + /** + * Returns the current length of the constraint. + * This is the distance between both of the constraint's end points. + * See `constraint.length` for the target rest length. + * @method currentLength + * @param {constraint} constraint + * @returns {number} the current length + */ + Constraint.currentLength = function(constraint) { + var pointAX = (constraint.bodyA ? constraint.bodyA.position.x : 0) + + (constraint.pointA ? constraint.pointA.x : 0); -module.exports = Crop; + var pointAY = (constraint.bodyA ? constraint.bodyA.position.y : 0) + + (constraint.pointA ? constraint.pointA.y : 0); + var pointBX = (constraint.bodyB ? constraint.bodyB.position.x : 0) + + (constraint.pointB ? constraint.pointB.x : 0); + + var pointBY = (constraint.bodyB ? constraint.bodyB.position.y : 0) + + (constraint.pointB ? constraint.pointB.y : 0); -/***/ }), -/* 610 */ -/***/ (function(module, exports) { + var deltaX = pointAX - pointBX; + var deltaY = pointAY - pointBY; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return Math.sqrt(deltaX * deltaX + deltaY * deltaY); + }; + /* + * + * Properties Documentation + * + */ -/** - * Provides methods used for visually flipping a Game Object. - * Should be applied as a mixin and not used directly. - * - * @namespace Phaser.GameObjects.Components.Flip - * @since 3.0.0 - */ + /** + * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`. + * + * @property id + * @type number + */ -var Flip = { + /** + * A `String` denoting the type of object. + * + * @property type + * @type string + * @default "constraint" + * @readOnly + */ /** - * The horizontally flipped state of the Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * - * @name Phaser.GameObjects.Components.Flip#flipX - * @type {boolean} - * @default false - * @since 3.0.0 + * An arbitrary `String` name to help the user identify and manage bodies. + * + * @property label + * @type string + * @default "Constraint" */ - flipX: false, /** - * The vertically flipped state of the Game Object. - * - * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * - * @name Phaser.GameObjects.Components.Flip#flipY - * @type {boolean} - * @default false - * @since 3.0.0 + * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`. + * + * @property render + * @type object */ - flipY: false, /** - * Toggles the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * - * @method Phaser.GameObjects.Components.Flip#toggleFlipX - * @since 3.0.0 - * - * @return {this} This Game Object instance. + * A flag that indicates if the constraint should be rendered. + * + * @property render.visible + * @type boolean + * @default true */ - toggleFlipX: function () - { - this.flipX = !this.flipX; - return this; - }, + /** + * A `Number` that defines the line width to use when rendering the constraint outline. + * A value of `0` means no outline will be rendered. + * + * @property render.lineWidth + * @type number + * @default 2 + */ /** - * Toggles the vertical flipped state of this Game Object. - * - * @method Phaser.GameObjects.Components.Flip#toggleFlipY - * @since 3.0.0 - * - * @return {this} This Game Object instance. + * A `String` that defines the stroke style to use when rendering the constraint outline. + * It is the same as when using a canvas, so it accepts CSS style property values. + * + * @property render.strokeStyle + * @type string + * @default a random colour */ - toggleFlipY: function () - { - this.flipY = !this.flipY; - return this; - }, + /** + * A `String` that defines the constraint rendering type. + * The possible values are 'line', 'pin', 'spring'. + * An appropriate render type will be automatically chosen unless one is given in options. + * + * @property render.type + * @type string + * @default 'line' + */ /** - * Sets the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * - * @method Phaser.GameObjects.Components.Flip#setFlipX - * @since 3.0.0 + * A `Boolean` that defines if the constraint's anchor points should be rendered. * - * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. - * - * @return {this} This Game Object instance. + * @property render.anchors + * @type boolean + * @default true */ - setFlipX: function (value) - { - this.flipX = value; - return this; - }, + /** + * The first possible `Body` that this constraint is attached to. + * + * @property bodyA + * @type body + * @default null + */ /** - * Sets the vertical flipped state of this Game Object. - * - * @method Phaser.GameObjects.Components.Flip#setFlipY - * @since 3.0.0 + * The second possible `Body` that this constraint is attached to. * - * @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped. - * - * @return {this} This Game Object instance. + * @property bodyB + * @type body + * @default null */ - setFlipY: function (value) - { - this.flipY = value; - return this; - }, + /** + * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyA` if defined, otherwise a world-space position. + * + * @property pointA + * @type vector + * @default { x: 0, y: 0 } + */ /** - * Sets the horizontal and vertical flipped state of this Game Object. - * - * A Game Object that is flipped will render inversed on the flipped axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * - * @method Phaser.GameObjects.Components.Flip#setFlip - * @since 3.0.0 + * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyB` if defined, otherwise a world-space position. * - * @param {boolean} x - The horizontal flipped state. `false` for no flip, or `true` to be flipped. - * @param {boolean} y - The horizontal flipped state. `false` for no flip, or `true` to be flipped. - * - * @return {this} This Game Object instance. + * @property pointB + * @type vector + * @default { x: 0, y: 0 } */ - setFlip: function (x, y) - { - this.flipX = x; - this.flipY = y; - return this; - }, + /** + * A `Number` that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. + * A value of `1` means the constraint should be very stiff. + * A value of `0.2` means the constraint acts like a soft spring. + * + * @property stiffness + * @type number + * @default 1 + */ /** - * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. - * - * @method Phaser.GameObjects.Components.Flip#resetFlip - * @since 3.0.0 + * A `Number` that specifies the damping of the constraint, + * i.e. the amount of resistance applied to each body based on their velocities to limit the amount of oscillation. + * Damping will only be apparent when the constraint also has a very low `stiffness`. + * A value of `0.1` means the constraint will apply heavy damping, resulting in little to no oscillation. + * A value of `0` means the constraint will apply no damping. * - * @return {this} This Game Object instance. + * @property damping + * @type number + * @default 0 */ - resetFlip: function () - { - this.flipX = false; - this.flipY = false; - return this; - } + /** + * A `Number` that specifies the target resting length of the constraint. + * It is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. + * + * @property length + * @type number + */ -}; + /** + * An object reserved for storing plugin-specific properties. + * + * @property plugin + * @type {} + */ -module.exports = Flip; +})(); /***/ }), -/* 611 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 68758: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +* The `Matter.Common` module contains utility functions that are common to all modules. +* +* @class Common +*/ -var Rectangle = __webpack_require__(10); -var RotateAround = __webpack_require__(308); -var Vector2 = __webpack_require__(3); +var Common = {}; -/** - * Provides methods used for obtaining the bounds of a Game Object. - * Should be applied as a mixin and not used directly. - * - * @namespace Phaser.GameObjects.Components.GetBounds - * @since 3.0.0 - */ +module.exports = Common; -var GetBounds = { +(function() { + Common._baseDelta = 1000 / 60; + Common._nextId = 0; + Common._seed = 0; + Common._nowStartTime = +(new Date()); + Common._warnedOnce = {}; + Common._decomp = null; + /** - * Processes the bounds output vector before returning it. - * - * @method Phaser.GameObjects.Components.GetBounds#prepareBoundsOutput - * @private - * @since 3.18.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} output - An object to store the values in. If not provided a new Vector2 will be created. - * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Extends the object in the first argument using the object in the second argument. + * @method extend + * @param {} obj + * @param {boolean} deep + * @return {} obj extended */ - prepareBoundsOutput: function (output, includeParent) - { - if (includeParent === undefined) { includeParent = false; } + Common.extend = function(obj, deep) { + var argsStart, + args, + deepClone; - if (this.rotation !== 0) - { - RotateAround(output, this.x, this.y, this.rotation); + if (typeof deep === 'boolean') { + argsStart = 2; + deepClone = deep; + } else { + argsStart = 1; + deepClone = true; } - if (includeParent && this.parentContainer) - { - var parentMatrix = this.parentContainer.getBoundsTransformMatrix(); + for (var i = argsStart; i < arguments.length; i++) { + var source = arguments[i]; - parentMatrix.transformPoint(output.x, output.y, output); + if (source) { + for (var prop in source) { + if (deepClone && source[prop] && source[prop].constructor === Object) { + if (!obj[prop] || obj[prop].constructor === Object) { + obj[prop] = obj[prop] || {}; + Common.extend(obj[prop], deepClone, source[prop]); + } else { + obj[prop] = source[prop]; + } + } else { + obj[prop] = source[prop]; + } + } + } } - - return output; - }, + + return obj; + }; /** - * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * - * @method Phaser.GameObjects.Components.GetBounds#getCenter - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created. - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Creates a new clone of the object, if deep is true references will also be cloned. + * @method clone + * @param {} obj + * @param {bool} deep + * @return {} obj cloned */ - getCenter: function (output) - { - if (output === undefined) { output = new Vector2(); } - - output.x = this.x - (this.displayWidth * this.originX) + (this.displayWidth / 2); - output.y = this.y - (this.displayHeight * this.originY) + (this.displayHeight / 2); - - return output; - }, + Common.clone = function(obj, deep) { + return Common.extend({}, deep, obj); + }; /** - * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * - * @method Phaser.GameObjects.Components.GetBounds#getTopLeft - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created. - * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Returns the list of keys for the given object. + * @method keys + * @param {} obj + * @return {string[]} keys */ - getTopLeft: function (output, includeParent) - { - if (!output) { output = new Vector2(); } + Common.keys = function(obj) { + if (Object.keys) + return Object.keys(obj); - output.x = this.x - (this.displayWidth * this.originX); - output.y = this.y - (this.displayHeight * this.originY); + // avoid hasOwnProperty for performance + var keys = []; + for (var key in obj) + keys.push(key); + return keys; + }; - return this.prepareBoundsOutput(output, includeParent); - }, + /** + * Returns the list of values for the given object. + * @method values + * @param {} obj + * @return {array} Array of the objects property values + */ + Common.values = function(obj) { + var values = []; + + if (Object.keys) { + var keys = Object.keys(obj); + for (var i = 0; i < keys.length; i++) { + values.push(obj[keys[i]]); + } + return values; + } + + // avoid hasOwnProperty for performance + for (var key in obj) + values.push(obj[key]); + return values; + }; /** - * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * - * @method Phaser.GameObjects.Components.GetBounds#getTopCenter - * @since 3.18.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created. - * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Gets a value from `base` relative to the `path` string. + * @method get + * @param {} obj The base object + * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz' + * @param {number} [begin] Path slice begin + * @param {number} [end] Path slice end + * @return {} The object at the given path */ - getTopCenter: function (output, includeParent) - { - if (!output) { output = new Vector2(); } + Common.get = function(obj, path, begin, end) { + path = path.split('.').slice(begin, end); - output.x = (this.x - (this.displayWidth * this.originX)) + (this.displayWidth / 2); - output.y = this.y - (this.displayHeight * this.originY); + for (var i = 0; i < path.length; i += 1) { + obj = obj[path[i]]; + } - return this.prepareBoundsOutput(output, includeParent); - }, + return obj; + }; /** - * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * - * @method Phaser.GameObjects.Components.GetBounds#getTopRight - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created. - * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Sets a value on `base` relative to the given `path` string. + * @method set + * @param {} obj The base object + * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz' + * @param {} val The value to set + * @param {number} [begin] Path slice begin + * @param {number} [end] Path slice end + * @return {} Pass through `val` for chaining */ - getTopRight: function (output, includeParent) - { - if (!output) { output = new Vector2(); } - - output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth; - output.y = this.y - (this.displayHeight * this.originY); + Common.set = function(obj, path, val, begin, end) { + var parts = path.split('.').slice(begin, end); + Common.get(obj, path, 0, -1)[parts[parts.length - 1]] = val; + return val; + }; - return this.prepareBoundsOutput(output, includeParent); - }, + /** + * Shuffles the given array in-place. + * The function uses a seeded random generator. + * @method shuffle + * @param {array} array + * @return {array} array shuffled randomly + */ + Common.shuffle = function(array) { + for (var i = array.length - 1; i > 0; i--) { + var j = Math.floor(Common.random() * (i + 1)); + var temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + return array; + }; /** - * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * - * @method Phaser.GameObjects.Components.GetBounds#getLeftCenter - * @since 3.18.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created. - * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Randomly chooses a value from a list with equal probability. + * The function uses a seeded random generator. + * @method choose + * @param {array} choices + * @return {object} A random choice object from the array */ - getLeftCenter: function (output, includeParent) - { - if (!output) { output = new Vector2(); } + Common.choose = function(choices) { + return choices[Math.floor(Common.random() * choices.length)]; + }; - output.x = this.x - (this.displayWidth * this.originX); - output.y = (this.y - (this.displayHeight * this.originY)) + (this.displayHeight / 2); + /** + * Returns true if the object is a HTMLElement, otherwise false. + * @method isElement + * @param {object} obj + * @return {boolean} True if the object is a HTMLElement, otherwise false + */ + Common.isElement = function(obj) { + if (typeof HTMLElement !== 'undefined') { + return obj instanceof HTMLElement; + } - return this.prepareBoundsOutput(output, includeParent); - }, + return !!(obj && obj.nodeType && obj.nodeName); + }; /** - * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * - * @method Phaser.GameObjects.Components.GetBounds#getRightCenter - * @since 3.18.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created. - * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Returns true if the object is an array. + * @method isArray + * @param {object} obj + * @return {boolean} True if the object is an array, otherwise false */ - getRightCenter: function (output, includeParent) - { - if (!output) { output = new Vector2(); } - - output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth; - output.y = (this.y - (this.displayHeight * this.originY)) + (this.displayHeight / 2); + Common.isArray = function(obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; + }; - return this.prepareBoundsOutput(output, includeParent); - }, + /** + * Returns true if the object is a function. + * @method isFunction + * @param {object} obj + * @return {boolean} True if the object is a function, otherwise false + */ + Common.isFunction = function(obj) { + return typeof obj === "function"; + }; /** - * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * - * @method Phaser.GameObjects.Components.GetBounds#getBottomLeft - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created. - * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Returns true if the object is a plain object. + * @method isPlainObject + * @param {object} obj + * @return {boolean} True if the object is a plain object, otherwise false */ - getBottomLeft: function (output, includeParent) - { - if (!output) { output = new Vector2(); } + Common.isPlainObject = function(obj) { + return typeof obj === 'object' && obj.constructor === Object; + }; - output.x = this.x - (this.displayWidth * this.originX); - output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight; + /** + * Returns true if the object is a string. + * @method isString + * @param {object} obj + * @return {boolean} True if the object is a string, otherwise false + */ + Common.isString = function(obj) { + return toString.call(obj) === '[object String]'; + }; + + /** + * Returns the given value clamped between a minimum and maximum value. + * @method clamp + * @param {number} value + * @param {number} min + * @param {number} max + * @return {number} The value clamped between min and max inclusive + */ + Common.clamp = function(value, min, max) { + if (value < min) + return min; + if (value > max) + return max; + return value; + }; + + /** + * Returns the sign of the given value. + * @method sign + * @param {number} value + * @return {number} -1 if negative, +1 if 0 or positive + */ + Common.sign = function(value) { + return value < 0 ? -1 : 1; + }; + + /** + * Returns the current timestamp since the time origin (e.g. from page load). + * The result is in milliseconds and will use high-resolution timing if available. + * @method now + * @return {number} the current timestamp in milliseconds + */ + Common.now = function() { + if (typeof window !== 'undefined' && window.performance) { + if (window.performance.now) { + return window.performance.now(); + } else if (window.performance.webkitNow) { + return window.performance.webkitNow(); + } + } - return this.prepareBoundsOutput(output, includeParent); - }, + if (Date.now) { + return Date.now(); + } + return (new Date()) - Common._nowStartTime; + }; + /** - * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * - * @method Phaser.GameObjects.Components.GetBounds#getBottomCenter - * @since 3.18.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created. - * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Returns a random value between a minimum and a maximum value inclusive. + * The function uses a seeded random generator. + * @method random + * @param {number} min + * @param {number} max + * @return {number} A random number between min and max inclusive */ - getBottomCenter: function (output, includeParent) - { - if (!output) { output = new Vector2(); } - - output.x = (this.x - (this.displayWidth * this.originX)) + (this.displayWidth / 2); - output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight; + Common.random = function(min, max) { + min = (typeof min !== "undefined") ? min : 0; + max = (typeof max !== "undefined") ? max : 1; + return min + _seededRandom() * (max - min); + }; - return this.prepareBoundsOutput(output, includeParent); - }, + var _seededRandom = function() { + // https://en.wikipedia.org/wiki/Linear_congruential_generator + Common._seed = (Common._seed * 9301 + 49297) % 233280; + return Common._seed / 233280; + }; /** - * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * - * @method Phaser.GameObjects.Components.GetBounds#getBottomRight - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(Phaser.Math.Vector2|object)} [output] - An object to store the values in. If not provided a new Vector2 will be created. - * @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? - * - * @return {(Phaser.Math.Vector2|object)} The values stored in the output object. + * Converts a CSS hex colour string into an integer. + * @method colorToNumber + * @param {string} colorString + * @return {number} An integer representing the CSS hex string */ - getBottomRight: function (output, includeParent) - { - if (!output) { output = new Vector2(); } + Common.colorToNumber = function(colorString) { + colorString = colorString.replace('#',''); - output.x = (this.x - (this.displayWidth * this.originX)) + this.displayWidth; - output.y = (this.y - (this.displayHeight * this.originY)) + this.displayHeight; + if (colorString.length == 3) { + colorString = colorString.charAt(0) + colorString.charAt(0) + + colorString.charAt(1) + colorString.charAt(1) + + colorString.charAt(2) + colorString.charAt(2); + } - return this.prepareBoundsOutput(output, includeParent); - }, + return parseInt(colorString, 16); + }; /** - * Gets the bounds of this Game Object, regardless of origin. - * The values are stored and returned in a Rectangle, or Rectangle-like, object. - * - * @method Phaser.GameObjects.Components.GetBounds#getBounds - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [output,$return] - * - * @param {(Phaser.Geom.Rectangle|object)} [output] - An object to store the values in. If not provided a new Rectangle will be created. + * The console logging level to use, where each level includes all levels above and excludes the levels below. + * The default level is 'debug' which shows all console messages. * - * @return {(Phaser.Geom.Rectangle|object)} The values stored in the output object. + * Possible level values are: + * - 0 = None + * - 1 = Debug + * - 2 = Info + * - 3 = Warn + * - 4 = Error + * @property Common.logLevel + * @type {Number} + * @default 1 */ - getBounds: function (output) - { - if (output === undefined) { output = new Rectangle(); } + Common.logLevel = 1; - // We can use the output object to temporarily store the x/y coords in: + /** + * Shows a `console.log` message only if the current `Common.logLevel` allows it. + * The message will be prefixed with 'matter-js' to make it easily identifiable. + * @method log + * @param ...objs {} The objects to log. + */ + Common.log = function() { + if (console && Common.logLevel > 0 && Common.logLevel <= 3) { + console.log.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments))); + } + }; - var TLx, TLy, TRx, TRy, BLx, BLy, BRx, BRy; + /** + * Shows a `console.info` message only if the current `Common.logLevel` allows it. + * The message will be prefixed with 'matter-js' to make it easily identifiable. + * @method info + * @param ...objs {} The objects to log. + */ + Common.info = function() { + if (console && Common.logLevel > 0 && Common.logLevel <= 2) { + console.info.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments))); + } + }; - // Instead of doing a check if parent container is - // defined per corner we only do it once. - if (this.parentContainer) - { - var parentMatrix = this.parentContainer.getBoundsTransformMatrix(); + /** + * Shows a `console.warn` message only if the current `Common.logLevel` allows it. + * The message will be prefixed with 'matter-js' to make it easily identifiable. + * @method warn + * @param ...objs {} The objects to log. + */ + Common.warn = function() { + if (console && Common.logLevel > 0 && Common.logLevel <= 3) { + console.warn.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments))); + } + }; - this.getTopLeft(output); - parentMatrix.transformPoint(output.x, output.y, output); + /** + * Uses `Common.warn` to log the given message one time only. + * @method warnOnce + * @param ...objs {} The objects to log. + */ + Common.warnOnce = function() { + var message = Array.prototype.slice.call(arguments).join(' '); - TLx = output.x; - TLy = output.y; + if (!Common._warnedOnce[message]) { + Common.warn(message); + Common._warnedOnce[message] = true; + } + }; - this.getTopRight(output); - parentMatrix.transformPoint(output.x, output.y, output); + /** + * Shows a deprecated console warning when the function on the given object is called. + * The target function will be replaced with a new function that first shows the warning + * and then calls the original function. + * @method deprecated + * @param {object} obj The object or module + * @param {string} name The property name of the function on obj + * @param {string} warning The one-time message to show if the function is called + */ + Common.deprecated = function(obj, prop, warning) { + obj[prop] = Common.chain(function() { + Common.warnOnce('🔅 deprecated 🔅', warning); + }, obj[prop]); + }; - TRx = output.x; - TRy = output.y; + /** + * Returns the next unique sequential ID. + * @method nextId + * @return {Number} Unique sequential ID + */ + Common.nextId = function() { + return Common._nextId++; + }; - this.getBottomLeft(output); - parentMatrix.transformPoint(output.x, output.y, output); + /** + * A cross browser compatible indexOf implementation. + * @method indexOf + * @param {array} haystack + * @param {object} needle + * @return {number} The position of needle in haystack, otherwise -1. + */ + Common.indexOf = function(haystack, needle) { + if (haystack.indexOf) + return haystack.indexOf(needle); - BLx = output.x; - BLy = output.y; + for (var i = 0; i < haystack.length; i++) { + if (haystack[i] === needle) + return i; + } - this.getBottomRight(output); - parentMatrix.transformPoint(output.x, output.y, output); + return -1; + }; - BRx = output.x; - BRy = output.y; + /** + * A cross browser compatible array map implementation. + * @method map + * @param {array} list + * @param {function} func + * @return {array} Values from list transformed by func. + */ + Common.map = function(list, func) { + if (list.map) { + return list.map(func); } - else - { - this.getTopLeft(output); - TLx = output.x; - TLy = output.y; + var mapped = []; - this.getTopRight(output); + for (var i = 0; i < list.length; i += 1) { + mapped.push(func(list[i])); + } - TRx = output.x; - TRy = output.y; + return mapped; + }; - this.getBottomLeft(output); + /** + * Takes a directed graph and returns the partially ordered set of vertices in topological order. + * Circular dependencies are allowed. + * @method topologicalSort + * @param {object} graph + * @return {array} Partially ordered set of vertices in topological order. + */ + Common.topologicalSort = function(graph) { + // https://github.com/mgechev/javascript-algorithms + // Copyright (c) Minko Gechev (MIT license) + // Modifications: tidy formatting and naming + var result = [], + visited = [], + temp = []; - BLx = output.x; - BLy = output.y; + for (var node in graph) { + if (!visited[node] && !temp[node]) { + Common._topologicalSort(node, visited, temp, graph, result); + } + } - this.getBottomRight(output); + return result; + }; - BRx = output.x; - BRy = output.y; - } + Common._topologicalSort = function(node, visited, temp, graph, result) { + var neighbors = graph[node] || []; + temp[node] = true; - output.x = Math.min(TLx, TRx, BLx, BRx); - output.y = Math.min(TLy, TRy, BLy, BRy); - output.width = Math.max(TLx, TRx, BLx, BRx) - output.x; - output.height = Math.max(TLy, TRy, BLy, BRy) - output.y; + for (var i = 0; i < neighbors.length; i += 1) { + var neighbor = neighbors[i]; - return output; - } + if (temp[neighbor]) { + // skip circular dependencies + continue; + } -}; + if (!visited[neighbor]) { + Common._topologicalSort(neighbor, visited, temp, graph, result); + } + } -module.exports = GetBounds; + temp[node] = false; + visited[node] = true; + result.push(node); + }; -/***/ }), -/* 612 */ -/***/ (function(module, exports) { + /** + * Takes _n_ functions as arguments and returns a new function that calls them in order. + * The arguments applied when calling the new function will also be applied to every function passed. + * The value of `this` refers to the last value returned in the chain that was not `undefined`. + * Therefore if a passed function does not return a value, the previously returned value is maintained. + * After all passed functions have been called the new function returns the last returned value (if any). + * If any of the passed functions are a chain, then the chain will be flattened. + * @method chain + * @param ...funcs {function} The functions to chain. + * @return {function} A new function that calls the passed functions in order. + */ + Common.chain = function() { + var funcs = []; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + for (var i = 0; i < arguments.length; i += 1) { + var func = arguments[i]; -/** - * The Game Blur Event. - * - * This event is dispatched by the Game Visibility Handler when the window in which the Game instance is embedded - * enters a blurred state. The blur event is raised when the window loses focus. This can happen if a user swaps - * tab, or if they simply remove focus from the browser to another app. - * - * @event Phaser.Core.Events#BLUR - * @since 3.0.0 - */ -module.exports = 'blur'; + if (func._chained) { + // flatten already chained functions + funcs.push.apply(funcs, func._chained); + } else { + funcs.push(func); + } + } + var chain = function() { + // https://github.com/GoogleChrome/devtools-docs/issues/53#issuecomment-51941358 + var lastResult, + args = new Array(arguments.length); -/***/ }), -/* 613 */ -/***/ (function(module, exports) { + for (var i = 0, l = arguments.length; i < l; i++) { + args[i] = arguments[i]; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + for (i = 0; i < funcs.length; i += 1) { + var result = funcs[i].apply(lastResult, args); -/** - * The Game Boot Event. - * - * This event is dispatched when the Phaser Game instance has finished booting, but before it is ready to start running. - * The global systems use this event to know when to set themselves up, dispatching their own `ready` events as required. - * - * @event Phaser.Core.Events#BOOT - * @since 3.0.0 - */ -module.exports = 'boot'; + if (typeof result !== 'undefined') { + lastResult = result; + } + } + return lastResult; + }; -/***/ }), -/* 614 */ -/***/ (function(module, exports) { + chain._chained = funcs; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return chain; + }; -/** - * The Game Context Lost Event. - * - * This event is dispatched by the Game if the WebGL Renderer it is using encounters a WebGL Context Lost event from the browser. - * - * The partner event is `CONTEXT_RESTORED`. - * - * @event Phaser.Core.Events#CONTEXT_LOST - * @since 3.19.0 - */ -module.exports = 'contextlost'; + /** + * Chains a function to excute before the original function on the given `path` relative to `base`. + * See also docs for `Common.chain`. + * @method chainPathBefore + * @param {} base The base object + * @param {string} path The path relative to `base` + * @param {function} func The function to chain before the original + * @return {function} The chained function that replaced the original + */ + Common.chainPathBefore = function(base, path, func) { + return Common.set(base, path, Common.chain( + func, + Common.get(base, path) + )); + }; + /** + * Chains a function to excute after the original function on the given `path` relative to `base`. + * See also docs for `Common.chain`. + * @method chainPathAfter + * @param {} base The base object + * @param {string} path The path relative to `base` + * @param {function} func The function to chain after the original + * @return {function} The chained function that replaced the original + */ + Common.chainPathAfter = function(base, path, func) { + return Common.set(base, path, Common.chain( + Common.get(base, path), + func + )); + }; -/***/ }), -/* 615 */ -/***/ (function(module, exports) { + /** + * Provide the [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module to enable + * concave vertex decomposition support when using `Bodies.fromVertices` e.g. `Common.setDecomp(require('poly-decomp'))`. + * @method setDecomp + * @param {} decomp The [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module. + */ + Common.setDecomp = function(decomp) { + Common._decomp = decomp; + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Returns the [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module provided through `Common.setDecomp`, + * otherwise returns the global `decomp` if set. + * @method getDecomp + * @return {} The [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module if provided. + */ + Common.getDecomp = function() { + // get user provided decomp if set + var decomp = Common._decomp; -/** - * The Game Context Restored Event. - * - * This event is dispatched by the Game if the WebGL Renderer it is using encounters a WebGL Context Restored event from the browser. - * - * The partner event is `CONTEXT_LOST`. - * - * @event Phaser.Core.Events#CONTEXT_RESTORED - * @since 3.19.0 - */ -module.exports = 'contextrestored'; + try { + // otherwise from window global + if (!decomp && typeof window !== 'undefined') { + decomp = window.decomp; + } + + // otherwise from node global + if (!decomp && typeof __webpack_require__.g !== 'undefined') { + decomp = __webpack_require__.g.decomp; + } + } catch (e) { + // decomp not available + decomp = null; + } + + return decomp; + }; +})(); /***/ }), -/* 616 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 45775: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * The Game Destroy Event. - * - * This event is dispatched when the game instance has been told to destroy itself. - * Lots of internal systems listen to this event in order to clear themselves out. - * Custom plugins and game code should also do the same. - * - * @event Phaser.Core.Events#DESTROY - * @since 3.0.0 - */ -module.exports = 'destroy'; +* The `Matter.Engine` module contains methods for creating and manipulating engines. +* An engine is a controller that manages updating the simulation of the world. +* See `Matter.Runner` for an optional game loop utility. +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Engine +*/ +var Engine = {}; -/***/ }), -/* 617 */ -/***/ (function(module, exports) { +module.exports = Engine; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +var Sleeping = __webpack_require__(22806); +var Resolver = __webpack_require__(44272); +var Detector = __webpack_require__(13657); +var Pairs = __webpack_require__(91327); +var Events = __webpack_require__(39073); +var Composite = __webpack_require__(11299); +var Constraint = __webpack_require__(52838); +var Common = __webpack_require__(68758); +var Body = __webpack_require__(84125); -/** - * The Game Focus Event. - * - * This event is dispatched by the Game Visibility Handler when the window in which the Game instance is embedded - * enters a focused state. The focus event is raised when the window re-gains focus, having previously lost it. - * - * @event Phaser.Core.Events#FOCUS - * @since 3.0.0 - */ -module.exports = 'focus'; +(function() { + /** + * Creates a new engine. The options parameter is an object that specifies any properties you wish to override the defaults. + * All properties have default values, and many are pre-calculated automatically based on other properties. + * See the properties section below for detailed information on what you can pass via the `options` object. + * @method create + * @param {object} [options] + * @return {engine} engine + */ + Engine.create = function(options) { + options = options || {}; -/***/ }), -/* 618 */ -/***/ (function(module, exports) { + var defaults = { + positionIterations: 6, + velocityIterations: 4, + constraintIterations: 2, + enableSleeping: false, + events: [], + plugin: {}, + gravity: { + x: 0, + y: 1, + scale: 0.001 + }, + timing: { + timestamp: 0, + timeScale: 1, + lastDelta: 0, + lastElapsed: 0 + } + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var engine = Common.extend(defaults, options); -/** - * The Game Hidden Event. - * - * This event is dispatched by the Game Visibility Handler when the document in which the Game instance is embedded - * enters a hidden state. Only browsers that support the Visibility API will cause this event to be emitted. - * - * In most modern browsers, when the document enters a hidden state, the Request Animation Frame and setTimeout, which - * control the main game loop, will automatically pause. There is no way to stop this from happening. It is something - * your game should account for in its own code, should the pause be an issue (i.e. for multiplayer games) - * - * @event Phaser.Core.Events#HIDDEN - * @since 3.0.0 - */ -module.exports = 'hidden'; + engine.world = options.world || Composite.create({ label: 'World' }); + engine.pairs = options.pairs || Pairs.create(); + engine.detector = options.detector || Detector.create(); + // for temporary back compatibility only + engine.grid = { buckets: [] }; + engine.world.gravity = engine.gravity; + engine.broadphase = engine.grid; + engine.metrics = {}; -/***/ }), -/* 619 */ -/***/ (function(module, exports) { + return engine; + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Moves the simulation forward in time by `delta` ms. + * Triggers `beforeUpdate` and `afterUpdate` events. + * Triggers `collisionStart`, `collisionActive` and `collisionEnd` events. + * @method update + * @param {engine} engine + * @param {number} [delta=16.666] + */ + Engine.update = function(engine, delta) { + var startTime = Common.now(); -/** - * The Game Pause Event. - * - * This event is dispatched when the Game loop enters a paused state, usually as a result of the Visibility Handler. - * - * @event Phaser.Core.Events#PAUSE - * @since 3.0.0 - */ -module.exports = 'pause'; + var world = engine.world, + detector = engine.detector, + pairs = engine.pairs, + timing = engine.timing, + timestamp = timing.timestamp, + i; + delta = typeof delta !== 'undefined' ? delta : Common._baseDelta; + delta *= timing.timeScale; -/***/ }), -/* 620 */ -/***/ (function(module, exports) { + // increment timestamp + timing.timestamp += delta; + timing.lastDelta = delta; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // create an event object + var event = { + timestamp: timing.timestamp, + delta: delta + }; -/** - * The Game Post-Render Event. - * - * This event is dispatched right at the end of the render process. - * - * Every Scene will have rendered and been drawn to the canvas by the time this event is fired. - * Use it for any last minute post-processing before the next game step begins. - * - * @event Phaser.Core.Events#POST_RENDER - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - A reference to the current renderer being used by the Game instance. - */ -module.exports = 'postrender'; + Events.trigger(engine, 'beforeUpdate', event); + // get all bodies and all constraints in the world + var allBodies = Composite.allBodies(world), + allConstraints = Composite.allConstraints(world); -/***/ }), -/* 621 */ -/***/ (function(module, exports) { + // if the world has changed + if (world.isModified) { + // update the detector bodies + Detector.setBodies(detector, allBodies); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // reset all composite modified flags + Composite.setModified(world, false, false, true); + } -/** - * The Game Post-Step Event. - * - * This event is dispatched after the Scene Manager has updated. - * Hook into it from plugins or systems that need to do things before the render starts. - * - * @event Phaser.Core.Events#POST_STEP - * @since 3.0.0 - * - * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. - */ -module.exports = 'poststep'; + // update sleeping if enabled + if (engine.enableSleeping) + Sleeping.update(allBodies, delta); + // apply gravity to all bodies + Engine._bodiesApplyGravity(allBodies, engine.gravity); -/***/ }), -/* 622 */ -/***/ (function(module, exports) { + // update all body position and rotation by integration + if (delta > 0) { + Engine._bodiesUpdate(allBodies, delta); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + Events.trigger(engine, 'beforeSolve', event); -/** - * The Game Pre-Render Event. - * - * This event is dispatched immediately before any of the Scenes have started to render. - * - * The renderer will already have been initialized this frame, clearing itself and preparing to receive the Scenes for rendering, but it won't have actually drawn anything yet. - * - * @event Phaser.Core.Events#PRE_RENDER - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - A reference to the current renderer being used by the Game instance. - */ -module.exports = 'prerender'; + // update all constraints (first pass) + Constraint.preSolveAll(allBodies); + for (i = 0; i < engine.constraintIterations; i++) { + Constraint.solveAll(allConstraints, delta); + } + Constraint.postSolveAll(allBodies); + // find all collisions + detector.pairs = engine.pairs; + var collisions = Detector.collisions(detector); -/***/ }), -/* 623 */ -/***/ (function(module, exports) { + // update collision pairs + Pairs.update(pairs, collisions, timestamp); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // wake up bodies involved in collisions + if (engine.enableSleeping) + Sleeping.afterCollisions(pairs.list); -/** - * The Game Pre-Step Event. - * - * This event is dispatched before the main Game Step starts. By this point in the game cycle none of the Scene updates have yet happened. - * Hook into it from plugins or systems that need to update before the Scene Manager does. - * - * @event Phaser.Core.Events#PRE_STEP - * @since 3.0.0 - * - * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. - */ -module.exports = 'prestep'; + // trigger collision events + if (pairs.collisionStart.length > 0) { + Events.trigger(engine, 'collisionStart', { + pairs: pairs.collisionStart, + timestamp: timing.timestamp, + delta: delta + }); + } + // iteratively resolve position between collisions + var positionDamping = Common.clamp(20 / engine.positionIterations, 0, 1); -/***/ }), -/* 624 */ -/***/ (function(module, exports) { + Resolver.preSolvePosition(pairs.list); + for (i = 0; i < engine.positionIterations; i++) { + Resolver.solvePosition(pairs.list, delta, positionDamping); + } + Resolver.postSolvePosition(allBodies); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // update all constraints (second pass) + Constraint.preSolveAll(allBodies); + for (i = 0; i < engine.constraintIterations; i++) { + Constraint.solveAll(allConstraints, delta); + } + Constraint.postSolveAll(allBodies); -/** - * The Game Ready Event. - * - * This event is dispatched when the Phaser Game instance has finished booting, the Texture Manager is fully ready, - * and all local systems are now able to start. - * - * @event Phaser.Core.Events#READY - * @since 3.0.0 - */ -module.exports = 'ready'; + // iteratively resolve velocity between collisions + Resolver.preSolveVelocity(pairs.list); + for (i = 0; i < engine.velocityIterations; i++) { + Resolver.solveVelocity(pairs.list, delta); + } + // update body speed and velocity properties + Engine._bodiesUpdateVelocities(allBodies); -/***/ }), -/* 625 */ -/***/ (function(module, exports) { + // trigger collision events + if (pairs.collisionActive.length > 0) { + Events.trigger(engine, 'collisionActive', { + pairs: pairs.collisionActive, + timestamp: timing.timestamp, + delta: delta + }); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (pairs.collisionEnd.length > 0) { + Events.trigger(engine, 'collisionEnd', { + pairs: pairs.collisionEnd, + timestamp: timing.timestamp, + delta: delta + }); + } -/** - * The Game Resume Event. - * - * This event is dispatched when the game loop leaves a paused state and resumes running. - * - * @event Phaser.Core.Events#RESUME - * @since 3.0.0 - */ -module.exports = 'resume'; + // clear force buffers + Engine._bodiesClearForces(allBodies); + Events.trigger(engine, 'afterUpdate', event); -/***/ }), -/* 626 */ -/***/ (function(module, exports) { + // log the time elapsed computing this update + engine.timing.lastElapsed = Common.now() - startTime; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return engine; + }; -/** - * The Game Step Event. - * - * This event is dispatched after the Game Pre-Step and before the Scene Manager steps. - * Hook into it from plugins or systems that need to update before the Scene Manager does, but after the core Systems have. - * - * @event Phaser.Core.Events#STEP - * @since 3.0.0 - * - * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. - */ -module.exports = 'step'; + /** + * Merges two engines by keeping the configuration of `engineA` but replacing the world with the one from `engineB`. + * @method merge + * @param {engine} engineA + * @param {engine} engineB + */ + Engine.merge = function(engineA, engineB) { + Common.extend(engineA, engineB); + if (engineB.world) { + engineA.world = engineB.world; -/***/ }), -/* 627 */ -/***/ (function(module, exports) { + Engine.clear(engineA); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var bodies = Composite.allBodies(engineA.world); -/** - * The Game Visible Event. - * - * This event is dispatched by the Game Visibility Handler when the document in which the Game instance is embedded - * enters a visible state, previously having been hidden. - * - * Only browsers that support the Visibility API will cause this event to be emitted. - * - * @event Phaser.Core.Events#VISIBLE - * @since 3.0.0 - */ -module.exports = 'visible'; + for (var i = 0; i < bodies.length; i++) { + var body = bodies[i]; + Sleeping.set(body, false); + body.id = Common.nextId(); + } + } + }; + /** + * Clears the engine pairs and detector. + * @method clear + * @param {engine} engine + */ + Engine.clear = function(engine) { + Pairs.clear(engine.pairs); + Detector.clear(engine.detector); + }; -/***/ }), -/* 628 */ -/***/ (function(module, exports) { + /** + * Zeroes the `body.force` and `body.torque` force buffers. + * @method _bodiesClearForces + * @private + * @param {body[]} bodies + */ + Engine._bodiesClearForces = function(bodies) { + var bodiesLength = bodies.length; + for (var i = 0; i < bodiesLength; i++) { + var body = bodies[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // reset force buffers + body.force.x = 0; + body.force.y = 0; + body.torque = 0; + } + }; -/** - * The Post-Render Event. - * - * This event is dispatched by the Renderer when all rendering, for all cameras in all Scenes, - * has completed, but before any pending snap shots have been taken. - * - * @event Phaser.Renderer.Events#POST_RENDER - * @since 3.50.0 - */ -module.exports = 'postrender'; + /** + * Applys a mass dependant force to all given bodies. + * @method _bodiesApplyGravity + * @private + * @param {body[]} bodies + * @param {vector} gravity + */ + Engine._bodiesApplyGravity = function(bodies, gravity) { + var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001, + bodiesLength = bodies.length; + if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) { + return; + } -/***/ }), -/* 629 */ -/***/ (function(module, exports) { + for (var i = 0; i < bodiesLength; i++) { + var body = bodies[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (body.isStatic || body.isSleeping) + continue; -/** - * The Pre-Render Event. - * - * This event is dispatched by the Phaser Renderer. This happens right at the start of the render - * process, after the context has been cleared, the scissors enabled (WebGL only) and everything has been - * reset ready for the render. - * - * @event Phaser.Renderer.Events#PRE_RENDER - * @since 3.50.0 - */ -module.exports = 'prerender'; + // add the resultant force of gravity + body.force.y += body.mass * gravity.y * gravityScale; + body.force.x += body.mass * gravity.x * gravityScale; + } + }; + /** + * Applies `Body.update` to all given `bodies`. + * @method _bodiesUpdate + * @private + * @param {body[]} bodies + * @param {number} delta The amount of time elapsed between updates + */ + Engine._bodiesUpdate = function(bodies, delta) { + var bodiesLength = bodies.length; -/***/ }), -/* 630 */ -/***/ (function(module, exports) { + for (var i = 0; i < bodiesLength; i++) { + var body = bodies[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (body.isStatic || body.isSleeping) + continue; -/** - * The Render Event. - * - * This event is dispatched by the Phaser Renderer for every camera in every Scene. - * - * It is dispatched before any of the children in the Scene have been rendered. - * - * @event Phaser.Renderer.Events#RENDER - * @since 3.50.0 - * - * @param {Phaser.Scene} scene - The Scene being rendered. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered. - */ -module.exports = 'render'; + Body.update(body, delta); + } + }; + /** + * Applies `Body.updateVelocities` to all given `bodies`. + * @method _bodiesUpdateVelocities + * @private + * @param {body[]} bodies + */ + Engine._bodiesUpdateVelocities = function(bodies) { + var bodiesLength = bodies.length; -/***/ }), -/* 631 */ -/***/ (function(module, exports) { + for (var i = 0; i < bodiesLength; i++) { + Body.updateVelocities(bodies[i]); + } + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * A deprecated alias for `Runner.run`, use `Matter.Runner.run(engine)` instead and see `Matter.Runner` for more information. + * @deprecated use Matter.Runner.run(engine) instead + * @method run + * @param {engine} engine + */ -/** - * The Renderer Resize Event. - * - * This event is dispatched by the Phaser Renderer when it is resized, usually as a result - * of the Scale Manager resizing. - * - * @event Phaser.Renderer.Events#RESIZE - * @since 3.50.0 - * - * @param {number} width - The new width of the renderer. - * @param {number} height - The new height of the renderer. - */ -module.exports = 'resize'; + /** + * Fired just before an update + * + * @event beforeUpdate + * @param {object} event An event object + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {engine} event.source The source object of the event + * @param {string} event.name The name of the event + */ + /** + * Fired after engine update and all collision events + * + * @event afterUpdate + * @param {object} event An event object + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {engine} event.source The source object of the event + * @param {string} event.name The name of the event + */ -/***/ }), -/* 632 */ -/***/ (function(module, exports) { + /** + * Fired after engine update, provides a list of all pairs that have started to collide in the current tick (if any) + * + * @event collisionStart + * @param {object} event An event object + * @param {pair[]} event.pairs List of affected pairs + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {engine} event.source The source object of the event + * @param {string} event.name The name of the event + */ -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Fired after engine update, provides a list of all pairs that are colliding in the current tick (if any) + * + * @event collisionActive + * @param {object} event An event object + * @param {pair[]} event.pairs List of affected pairs + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {engine} event.source The source object of the event + * @param {string} event.name The name of the event + */ -/** - * Provides methods used for getting and setting the origin of a Game Object. - * Values are normalized, given in the range 0 to 1. - * Display values contain the calculated pixel values. - * Should be applied as a mixin and not used directly. - * - * @namespace Phaser.GameObjects.Components.Origin - * @since 3.0.0 - */ + /** + * Fired after engine update, provides a list of all pairs that have ended collision in the current tick (if any) + * + * @event collisionEnd + * @param {object} event An event object + * @param {pair[]} event.pairs List of affected pairs + * @param {number} event.timestamp The engine.timing.timestamp of the event + * @param {engine} event.source The source object of the event + * @param {string} event.name The name of the event + */ -var Origin = { + /* + * + * Properties Documentation + * + */ /** - * A property indicating that a Game Object has this component. + * An integer `Number` that specifies the number of position iterations to perform each update. + * The higher the value, the higher quality the simulation will be at the expense of performance. * - * @name Phaser.GameObjects.Components.Origin#_originComponent - * @type {boolean} - * @private - * @default true - * @since 3.2.0 + * @property positionIterations + * @type number + * @default 6 */ - _originComponent: true, /** - * The horizontal origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the left of the Game Object. + * An integer `Number` that specifies the number of velocity iterations to perform each update. + * The higher the value, the higher quality the simulation will be at the expense of performance. * - * @name Phaser.GameObjects.Components.Origin#originX - * @type {number} - * @default 0.5 - * @since 3.0.0 + * @property velocityIterations + * @type number + * @default 4 */ - originX: 0.5, /** - * The vertical origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the top of the Game Object. + * An integer `Number` that specifies the number of constraint iterations to perform each update. + * The higher the value, the higher quality the simulation will be at the expense of performance. + * The default value of `2` is usually very adequate. * - * @name Phaser.GameObjects.Components.Origin#originY - * @type {number} - * @default 0.5 - * @since 3.0.0 + * @property constraintIterations + * @type number + * @default 2 */ - originY: 0.5, - - // private + read only - _displayOriginX: 0, - _displayOriginY: 0, /** - * The horizontal display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * A flag that specifies whether the engine should allow sleeping via the `Matter.Sleeping` module. + * Sleeping can improve stability and performance, but often at the expense of accuracy. * - * @name Phaser.GameObjects.Components.Origin#displayOriginX - * @type {number} - * @since 3.0.0 + * @property enableSleeping + * @type boolean + * @default false */ - displayOriginX: { - - get: function () - { - return this._displayOriginX; - }, - set: function (value) - { - this._displayOriginX = value; - this.originX = value / this.width; - } + /** + * An `Object` containing properties regarding the timing systems of the engine. + * + * @property timing + * @type object + */ - }, + /** + * A `Number` that specifies the global scaling factor of time for all bodies. + * A value of `0` freezes the simulation. + * A value of `0.1` gives a slow-motion effect. + * A value of `1.2` gives a speed-up effect. + * + * @property timing.timeScale + * @type number + * @default 1 + */ /** - * The vertical display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * A `Number` that specifies the current simulation-time in milliseconds starting from `0`. + * It is incremented on every `Engine.update` by the given `delta` argument. * - * @name Phaser.GameObjects.Components.Origin#displayOriginY - * @type {number} - * @since 3.0.0 + * @property timing.timestamp + * @type number + * @default 0 */ - displayOriginY: { - get: function () - { - return this._displayOriginY; - }, + /** + * A `Number` that represents the total execution time elapsed during the last `Engine.update` in milliseconds. + * It is updated by timing from the start of the last `Engine.update` call until it ends. + * + * This value will also include the total execution time of all event handlers directly or indirectly triggered by the engine update. + * + * @property timing.lastElapsed + * @type number + * @default 0 + */ - set: function (value) - { - this._displayOriginY = value; - this.originY = value / this.height; - } + /** + * A `Number` that represents the `delta` value used in the last engine update. + * + * @property timing.lastDelta + * @type number + * @default 0 + */ - }, + /** + * A `Matter.Detector` instance. + * + * @property detector + * @type detector + * @default a Matter.Detector instance + */ /** - * Sets the origin of this Game Object. + * A `Matter.Grid` instance. * - * The values are given in the range 0 to 1. + * @deprecated replaced by `engine.detector` + * @property grid + * @type grid + * @default a Matter.Grid instance + */ + + /** + * Replaced by and now alias for `engine.grid`. * - * @method Phaser.GameObjects.Components.Origin#setOrigin - * @since 3.0.0 + * @deprecated replaced by `engine.detector` + * @property broadphase + * @type grid + * @default a Matter.Grid instance + */ + + /** + * The root `Matter.Composite` instance that will contain all bodies, constraints and other composites to be simulated by this engine. * - * @param {number} [x=0.5] - The horizontal origin value. - * @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`. + * @property world + * @type composite + * @default a Matter.Composite instance + */ + + /** + * An object reserved for storing plugin-specific properties. * - * @return {this} This Game Object instance. + * @property plugin + * @type {} */ - setOrigin: function (x, y) - { - if (x === undefined) { x = 0.5; } - if (y === undefined) { y = x; } - this.originX = x; - this.originY = y; + /** + * The gravity to apply on all bodies in `engine.world`. + * + * @property gravity + * @type object + */ - return this.updateDisplayOrigin(); - }, + /** + * The gravity x component. + * + * @property gravity.x + * @type object + * @default 0 + */ /** - * Sets the origin of this Game Object based on the Pivot values in its Frame. + * The gravity y component. * - * @method Phaser.GameObjects.Components.Origin#setOriginFromFrame - * @since 3.0.0 + * @property gravity.y + * @type object + * @default 1 + */ + + /** + * The gravity scale factor. * - * @return {this} This Game Object instance. + * @property gravity.scale + * @type object + * @default 0.001 */ - setOriginFromFrame: function () - { - if (!this.frame || !this.frame.customPivot) - { - return this.setOrigin(); - } - else - { - this.originX = this.frame.pivotX; - this.originY = this.frame.pivotY; + +})(); + + +/***/ }), + +/***/ 39073: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** +* The `Matter.Events` module contains methods to fire and listen to events on other objects. +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Events +*/ + +var Events = {}; + +module.exports = Events; + +var Common = __webpack_require__(68758); + +(function() { + + /** + * Subscribes a callback function to the given object's `eventName`. + * @method on + * @param {} object + * @param {string} eventNames + * @param {function} callback + */ + Events.on = function(object, eventNames, callback) { + var names = eventNames.split(' '), + name; + + for (var i = 0; i < names.length; i++) { + name = names[i]; + object.events = object.events || {}; + object.events[name] = object.events[name] || []; + object.events[name].push(callback); } - return this.updateDisplayOrigin(); - }, + return callback; + }; /** - * Sets the display origin of this Game Object. - * The difference between this and setting the origin is that you can use pixel values for setting the display origin. - * - * @method Phaser.GameObjects.Components.Origin#setDisplayOrigin - * @since 3.0.0 - * - * @param {number} [x=0] - The horizontal display origin value. - * @param {number} [y=x] - The vertical display origin value. If not defined it will be set to the value of `x`. - * - * @return {this} This Game Object instance. + * Removes the given event callback. If no callback, clears all callbacks in `eventNames`. If no `eventNames`, clears all events. + * @method off + * @param {} object + * @param {string} eventNames + * @param {function} callback */ - setDisplayOrigin: function (x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } + Events.off = function(object, eventNames, callback) { + if (!eventNames) { + object.events = {}; + return; + } - this.displayOriginX = x; - this.displayOriginY = y; + // handle Events.off(object, callback) + if (typeof eventNames === 'function') { + callback = eventNames; + eventNames = Common.keys(object.events).join(' '); + } - return this; - }, + var names = eventNames.split(' '); + + for (var i = 0; i < names.length; i++) { + var callbacks = object.events[names[i]], + newCallbacks = []; + + if (callback && callbacks) { + for (var j = 0; j < callbacks.length; j++) { + if (callbacks[j] !== callback) + newCallbacks.push(callbacks[j]); + } + } + + object.events[names[i]] = newCallbacks; + } + }; /** - * Updates the Display Origin cached values internally stored on this Game Object. - * You don't usually call this directly, but it is exposed for edge-cases where you may. - * - * @method Phaser.GameObjects.Components.Origin#updateDisplayOrigin - * @since 3.0.0 - * - * @return {this} This Game Object instance. + * Fires all the callbacks subscribed to the given object's `eventName`, in the order they subscribed, if any. + * @method trigger + * @param {} object + * @param {string} eventNames + * @param {} event */ - updateDisplayOrigin: function () - { - this._displayOriginX = this.originX * this.width; - this._displayOriginY = this.originY * this.height; + Events.trigger = function(object, eventNames, event) { + var names, + name, + callbacks, + eventClone; - return this; - } + var events = object.events; + + if (events && Common.keys(events).length > 0) { + if (!event) + event = {}; -}; + names = eventNames.split(' '); -module.exports = Origin; + for (var i = 0; i < names.length; i++) { + name = names[i]; + callbacks = events[name]; + + if (callbacks) { + eventClone = Common.clone(event, false); + eventClone.name = name; + eventClone.source = object; + + for (var j = 0; j < callbacks.length; j++) { + callbacks[j].apply(object, [eventClone]); + } + } + } + } + }; + +})(); /***/ }), -/* 633 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 16929: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +* The `Matter` module is the top level namespace. It also includes a function for installing plugins on top of the library. +* +* @class Matter +*/ -var DegToRad = __webpack_require__(36); -var GetBoolean = __webpack_require__(99); -var GetValue = __webpack_require__(6); -var TWEEN_CONST = __webpack_require__(100); -var Vector2 = __webpack_require__(3); +var Matter = {}; -/** - * Provides methods used for managing a Game Object following a Path. - * Should be applied as a mixin and not used directly. - * - * @namespace Phaser.GameObjects.Components.PathFollower - * @since 3.17.0 - */ +module.exports = Matter; -var PathFollower = { +var Plugin = __webpack_require__(84474); +var Common = __webpack_require__(68758); + +(function() { /** - * The Path this PathFollower is following. It can only follow one Path at a time. - * - * @name Phaser.GameObjects.Components.PathFollower#path - * @type {Phaser.Curves.Path} - * @since 3.0.0 + * The library name. + * @property name + * @readOnly + * @type {String} */ - path: null, + Matter.name = 'matter-js'; /** - * Should the PathFollower automatically rotate to point in the direction of the Path? - * - * @name Phaser.GameObjects.Components.PathFollower#rotateToPath - * @type {boolean} - * @default false - * @since 3.0.0 + * The library version. + * @property version + * @readOnly + * @type {String} */ - rotateToPath: false, + Matter.version = '0.19.0'; /** - * If the PathFollower is rotating to match the Path (@see Phaser.GameObjects.PathFollower#rotateToPath) - * this value is added to the rotation value. This allows you to rotate objects to a path but control - * the angle of the rotation as well. - * - * @name Phaser.GameObjects.PathFollower#pathRotationOffset - * @type {number} - * @default 0 - * @since 3.0.0 + * A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`. + * Alternatively you may set `Matter.uses` manually and install them by calling `Plugin.use(Matter)`. + * @property uses + * @type {Array} */ - pathRotationOffset: 0, + Matter.uses = []; /** - * An additional vector to add to the PathFollowers position, allowing you to offset it from the - * Path coordinates. - * - * @name Phaser.GameObjects.PathFollower#pathOffset - * @type {Phaser.Math.Vector2} - * @since 3.0.0 + * The plugins that have been installed through `Matter.Plugin.install`. Read only. + * @property used + * @readOnly + * @type {Array} */ - pathOffset: null, + Matter.used = []; /** - * A Vector2 that stores the current point of the path the follower is on. - * - * @name Phaser.GameObjects.PathFollower#pathVector - * @type {Phaser.Math.Vector2} - * @since 3.0.0 + * Installs the given plugins on the `Matter` namespace. + * This is a short-hand for `Plugin.use`, see it for more information. + * Call this function once at the start of your code, with all of the plugins you wish to install as arguments. + * Avoid calling this function multiple times unless you intend to manually control installation order. + * @method use + * @param ...plugin {Function} The plugin(s) to install on `base` (multi-argument). */ - pathVector: null, + Matter.use = function() { + Plugin.use(Matter, Array.prototype.slice.call(arguments)); + }; /** - * The distance the follower has traveled from the previous point to the current one, at the last update. - * - * @name Phaser.GameObjects.PathFollower#pathDelta - * @type {Phaser.Math.Vector2} - * @since 3.23.0 + * Chains a function to excute before the original function on the given `path` relative to `Matter`. + * See also docs for `Common.chain`. + * @method before + * @param {string} path The path relative to `Matter` + * @param {function} func The function to chain before the original + * @return {function} The chained function that replaced the original */ - pathDelta: null, + Matter.before = function(path, func) { + path = path.replace(/^Matter./, ''); + return Common.chainPathBefore(Matter, path, func); + }; /** - * The Tween used for following the Path. - * - * @name Phaser.GameObjects.PathFollower#pathTween - * @type {Phaser.Tweens.Tween} - * @since 3.0.0 + * Chains a function to excute after the original function on the given `path` relative to `Matter`. + * See also docs for `Common.chain`. + * @method after + * @param {string} path The path relative to `Matter` + * @param {function} func The function to chain after the original + * @return {function} The chained function that replaced the original */ - pathTween: null, + Matter.after = function(path, func) { + path = path.replace(/^Matter./, ''); + return Common.chainPathAfter(Matter, path, func); + }; + +})(); + + +/***/ }), + +/***/ 84474: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** +* The `Matter.Plugin` module contains functions for registering and installing plugins on modules. +* +* @class Plugin +*/ + +var Plugin = {}; + +module.exports = Plugin; + +var Common = __webpack_require__(68758); + +(function() { + + Plugin._registry = {}; + + /** + * Registers a plugin object so it can be resolved later by name. + * @method register + * @param plugin {} The plugin to register. + * @return {object} The plugin. + */ + Plugin.register = function(plugin) { + if (!Plugin.isPlugin(plugin)) { + Common.warn('Plugin.register:', Plugin.toString(plugin), 'does not implement all required fields.'); + } + + if (plugin.name in Plugin._registry) { + var registered = Plugin._registry[plugin.name], + pluginVersion = Plugin.versionParse(plugin.version).number, + registeredVersion = Plugin.versionParse(registered.version).number; + + if (pluginVersion > registeredVersion) { + Common.warn('Plugin.register:', Plugin.toString(registered), 'was upgraded to', Plugin.toString(plugin)); + Plugin._registry[plugin.name] = plugin; + } else if (pluginVersion < registeredVersion) { + Common.warn('Plugin.register:', Plugin.toString(registered), 'can not be downgraded to', Plugin.toString(plugin)); + } else if (plugin !== registered) { + Common.warn('Plugin.register:', Plugin.toString(plugin), 'is already registered to different plugin object'); + } + } else { + Plugin._registry[plugin.name] = plugin; + } + + return plugin; + }; + + /** + * Resolves a dependency to a plugin object from the registry if it exists. + * The `dependency` may contain a version, but only the name matters when resolving. + * @method resolve + * @param dependency {string} The dependency. + * @return {object} The plugin if resolved, otherwise `undefined`. + */ + Plugin.resolve = function(dependency) { + return Plugin._registry[Plugin.dependencyParse(dependency).name]; + }; + + /** + * Returns a pretty printed plugin name and version. + * @method toString + * @param plugin {} The plugin. + * @return {string} Pretty printed plugin name and version. + */ + Plugin.toString = function(plugin) { + return typeof plugin === 'string' ? plugin : (plugin.name || 'anonymous') + '@' + (plugin.version || plugin.range || '0.0.0'); + }; + + /** + * Returns `true` if the object meets the minimum standard to be considered a plugin. + * This means it must define the following properties: + * - `name` + * - `version` + * - `install` + * @method isPlugin + * @param obj {} The obj to test. + * @return {boolean} `true` if the object can be considered a plugin otherwise `false`. + */ + Plugin.isPlugin = function(obj) { + return obj && obj.name && obj.version && obj.install; + }; /** - * Settings for the PathFollower. - * - * @name Phaser.GameObjects.PathFollower#pathConfig - * @type {?Phaser.Types.GameObjects.PathFollower.PathConfig} - * @default null - * @since 3.0.0 + * Returns `true` if a plugin with the given `name` been installed on `module`. + * @method isUsed + * @param module {} The module. + * @param name {string} The plugin name. + * @return {boolean} `true` if a plugin with the given `name` been installed on `module`, otherwise `false`. */ - pathConfig: null, + Plugin.isUsed = function(module, name) { + return module.used.indexOf(name) > -1; + }; /** - * Records the direction of the follower so it can change direction. - * - * @name Phaser.GameObjects.PathFollower#_prevDirection - * @type {number} - * @private - * @since 3.0.0 + * Returns `true` if `plugin.for` is applicable to `module` by comparing against `module.name` and `module.version`. + * If `plugin.for` is not specified then it is assumed to be applicable. + * The value of `plugin.for` is a string of the format `'module-name'` or `'module-name@version'`. + * @method isFor + * @param plugin {} The plugin. + * @param module {} The module. + * @return {boolean} `true` if `plugin.for` is applicable to `module`, otherwise `false`. */ - _prevDirection: TWEEN_CONST.PLAYING_FORWARD, + Plugin.isFor = function(plugin, module) { + var parsed = plugin.for && Plugin.dependencyParse(plugin.for); + return !plugin.for || (module.name === parsed.name && Plugin.versionSatisfies(module.version, parsed.range)); + }; /** - * Set the Path that this PathFollower should follow. - * - * Optionally accepts {@link Phaser.Types.GameObjects.PathFollower.PathConfig} settings. - * - * @method Phaser.GameObjects.Components.PathFollower#setPath - * @since 3.0.0 - * - * @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time. - * @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config] - Settings for the PathFollower. - * - * @return {this} This Game Object. + * Installs the plugins by calling `plugin.install` on each plugin specified in `plugins` if passed, otherwise `module.uses`. + * For installing plugins on `Matter` see the convenience function `Matter.use`. + * Plugins may be specified either by their name or a reference to the plugin object. + * Plugins themselves may specify further dependencies, but each plugin is installed only once. + * Order is important, a topological sort is performed to find the best resulting order of installation. + * This sorting attempts to satisfy every dependency's requested ordering, but may not be exact in all cases. + * This function logs the resulting status of each dependency in the console, along with any warnings. + * - A green tick ✅ indicates a dependency was resolved and installed. + * - An orange diamond 🔶 indicates a dependency was resolved but a warning was thrown for it or one if its dependencies. + * - A red cross ❌ indicates a dependency could not be resolved. + * Avoid calling this function multiple times on the same module unless you intend to manually control installation order. + * @method use + * @param module {} The module install plugins on. + * @param [plugins=module.uses] {} The plugins to install on module (optional, defaults to `module.uses`). */ - setPath: function (path, config) - { - if (config === undefined) { config = this.pathConfig; } - - var tween = this.pathTween; + Plugin.use = function(module, plugins) { + module.uses = (module.uses || []).concat(plugins || []); - if (tween && tween.isPlaying()) - { - tween.stop(); + if (module.uses.length === 0) { + Common.warn('Plugin.use:', Plugin.toString(module), 'does not specify any dependencies to install.'); + return; } - this.path = path; + var dependencies = Plugin.dependencies(module), + sortedDependencies = Common.topologicalSort(dependencies), + status = []; - if (config) - { - this.startFollow(config); - } + for (var i = 0; i < sortedDependencies.length; i += 1) { + if (sortedDependencies[i] === module.name) { + continue; + } - return this; - }, + var plugin = Plugin.resolve(sortedDependencies[i]); - /** - * Set whether the PathFollower should automatically rotate to point in the direction of the Path. - * - * @method Phaser.GameObjects.Components.PathFollower#setRotateToPath - * @since 3.0.0 - * - * @param {boolean} value - Whether the PathFollower should automatically rotate to point in the direction of the Path. - * @param {number} [offset=0] - Rotation offset in degrees. - * - * @return {this} This Game Object. - */ - setRotateToPath: function (value, offset) - { - if (offset === undefined) { offset = 0; } + if (!plugin) { + status.push('❌ ' + sortedDependencies[i]); + continue; + } - this.rotateToPath = value; + if (Plugin.isUsed(module, plugin.name)) { + continue; + } - this.pathRotationOffset = offset; + if (!Plugin.isFor(plugin, module)) { + Common.warn('Plugin.use:', Plugin.toString(plugin), 'is for', plugin.for, 'but installed on', Plugin.toString(module) + '.'); + plugin._warned = true; + } - return this; - }, + if (plugin.install) { + plugin.install(module); + } else { + Common.warn('Plugin.use:', Plugin.toString(plugin), 'does not specify an install function.'); + plugin._warned = true; + } - /** - * Is this PathFollower actively following a Path or not? - * - * To be considered as `isFollowing` it must be currently moving on a Path, and not paused. - * - * @method Phaser.GameObjects.Components.PathFollower#isFollowing - * @since 3.0.0 - * - * @return {boolean} `true` is this PathFollower is actively following a Path, otherwise `false`. - */ - isFollowing: function () - { - var tween = this.pathTween; + if (plugin._warned) { + status.push('🔶 ' + Plugin.toString(plugin)); + delete plugin._warned; + } else { + status.push('✅ ' + Plugin.toString(plugin)); + } - return (tween && tween.isPlaying()); - }, + module.used.push(plugin.name); + } + + if (status.length > 0 && !plugin.silent) { + Common.info(status.join(' ')); + } + }; /** - * Starts this PathFollower following its given Path. - * - * @method Phaser.GameObjects.Components.PathFollower#startFollow - * @since 3.3.0 - * - * @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config={}] - The duration of the follow, or a PathFollower config object. - * @param {number} [startAt=0] - Optional start position of the follow, between 0 and 1. - * - * @return {this} This Game Object. + * Recursively finds all of a module's dependencies and returns a flat dependency graph. + * @method dependencies + * @param module {} The module. + * @return {object} A dependency graph. */ - startFollow: function (config, startAt) - { - if (config === undefined) { config = {}; } - if (startAt === undefined) { startAt = 0; } - - var tween = this.pathTween; + Plugin.dependencies = function(module, tracked) { + var parsedBase = Plugin.dependencyParse(module), + name = parsedBase.name; - if (tween && tween.isPlaying()) - { - tween.stop(); - } + tracked = tracked || {}; - if (typeof config === 'number') - { - config = { duration: config }; + if (name in tracked) { + return; } - // Override in case they've been specified in the config - config.from = GetValue(config, 'from', 0); - config.to = GetValue(config, 'to', 1); + module = Plugin.resolve(module) || module; - var positionOnPath = GetBoolean(config, 'positionOnPath', false); + tracked[name] = Common.map(module.uses || [], function(dependency) { + if (Plugin.isPlugin(dependency)) { + Plugin.register(dependency); + } - this.rotateToPath = GetBoolean(config, 'rotateToPath', false); - this.pathRotationOffset = GetValue(config, 'rotationOffset', 0); + var parsed = Plugin.dependencyParse(dependency), + resolved = Plugin.resolve(dependency); - // This works, but it's not an ideal way of doing it as the follower jumps position - var seek = GetValue(config, 'startAt', startAt); + if (resolved && !Plugin.versionSatisfies(resolved.version, parsed.range)) { + Common.warn( + 'Plugin.dependencies:', Plugin.toString(resolved), 'does not satisfy', + Plugin.toString(parsed), 'used by', Plugin.toString(parsedBase) + '.' + ); - if (seek) - { - config.onStart = function (tween) - { - var tweenData = tween.data[0]; - tweenData.progress = seek; - tweenData.elapsed = tweenData.duration * seek; - var v = tweenData.ease(tweenData.progress); - tweenData.current = tweenData.start + ((tweenData.end - tweenData.start) * v); - tweenData.target[tweenData.key] = tweenData.current; - }; - } + resolved._warned = true; + module._warned = true; + } else if (!resolved) { + Common.warn( + 'Plugin.dependencies:', Plugin.toString(dependency), 'used by', + Plugin.toString(parsedBase), 'could not be resolved.' + ); - if (!this.pathOffset) - { - this.pathOffset = new Vector2(this.x, this.y); - } + module._warned = true; + } - if (!this.pathVector) - { - this.pathVector = new Vector2(); - } + return parsed.name; + }); - if (!this.pathDelta) - { - this.pathDelta = new Vector2(); + for (var i = 0; i < tracked[name].length; i += 1) { + Plugin.dependencies(tracked[name][i], tracked); } - this.pathDelta.reset(); + return tracked; + }; - this.pathTween = this.scene.sys.tweens.addCounter(config); + /** + * Parses a dependency string into its components. + * The `dependency` is a string of the format `'module-name'` or `'module-name@version'`. + * See documentation for `Plugin.versionParse` for a description of the format. + * This function can also handle dependencies that are already resolved (e.g. a module object). + * @method dependencyParse + * @param dependency {string} The dependency of the format `'module-name'` or `'module-name@version'`. + * @return {object} The dependency parsed into its components. + */ + Plugin.dependencyParse = function(dependency) { + if (Common.isString(dependency)) { + var pattern = /^[\w-]+(@(\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-+]+)?))?$/; - // The starting point of the path, relative to this follower - this.path.getStartPoint(this.pathOffset); + if (!pattern.test(dependency)) { + Common.warn('Plugin.dependencyParse:', dependency, 'is not a valid dependency string.'); + } - if (positionOnPath) - { - this.x = this.pathOffset.x; - this.y = this.pathOffset.y; + return { + name: dependency.split('@')[0], + range: dependency.split('@')[1] || '*' + }; } - this.pathOffset.x = this.x - this.pathOffset.x; - this.pathOffset.y = this.y - this.pathOffset.y; - - this._prevDirection = TWEEN_CONST.PLAYING_FORWARD; + return { + name: dependency.name, + range: dependency.range || dependency.version + }; + }; - if (this.rotateToPath) - { - // Set the rotation now (in case the tween has a delay on it, etc) - var nextPoint = this.path.getPoint(0.1); + /** + * Parses a version string into its components. + * Versions are strictly of the format `x.y.z` (as in [semver](http://semver.org/)). + * Versions may optionally have a prerelease tag in the format `x.y.z-alpha`. + * Ranges are a strict subset of [npm ranges](https://docs.npmjs.com/misc/semver#advanced-range-syntax). + * Only the following range types are supported: + * - Tilde ranges e.g. `~1.2.3` + * - Caret ranges e.g. `^1.2.3` + * - Greater than ranges e.g. `>1.2.3` + * - Greater than or equal ranges e.g. `>=1.2.3` + * - Exact version e.g. `1.2.3` + * - Any version `*` + * @method versionParse + * @param range {string} The version string. + * @return {object} The version range parsed into its components. + */ + Plugin.versionParse = function(range) { + var pattern = /^(\*)|(\^|~|>=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-+]+)?$/; - this.rotation = Math.atan2(nextPoint.y - this.y, nextPoint.x - this.x) + DegToRad(this.pathRotationOffset); + if (!pattern.test(range)) { + Common.warn('Plugin.versionParse:', range, 'is not a valid version or range.'); } - this.pathConfig = config; + var parts = pattern.exec(range); + var major = Number(parts[4]); + var minor = Number(parts[5]); + var patch = Number(parts[6]); - return this; - }, + return { + isRange: Boolean(parts[1] || parts[2]), + version: parts[3], + range: range, + operator: parts[1] || parts[2] || '', + major: major, + minor: minor, + patch: patch, + parts: [major, minor, patch], + prerelease: parts[7], + number: major * 1e8 + minor * 1e4 + patch + }; + }; /** - * Pauses this PathFollower. It will still continue to render, but it will remain motionless at the - * point on the Path at which you paused it. - * - * @method Phaser.GameObjects.Components.PathFollower#pauseFollow - * @since 3.3.0 - * - * @return {this} This Game Object. + * Returns `true` if `version` satisfies the given `range`. + * See documentation for `Plugin.versionParse` for a description of the format. + * If a version or range is not specified, then any version (`*`) is assumed to satisfy. + * @method versionSatisfies + * @param version {string} The version string. + * @param range {string} The range string. + * @return {boolean} `true` if `version` satisfies `range`, otherwise `false`. */ - pauseFollow: function () - { - var tween = this.pathTween; + Plugin.versionSatisfies = function(version, range) { + range = range || '*'; - if (tween && tween.isPlaying()) - { - tween.pause(); - } + var r = Plugin.versionParse(range), + v = Plugin.versionParse(version); - return this; - }, + if (r.isRange) { + if (r.operator === '*' || version === '*') { + return true; + } - /** - * Resumes a previously paused PathFollower. - * - * If the PathFollower was not paused this has no effect. - * - * @method Phaser.GameObjects.Components.PathFollower#resumeFollow - * @since 3.3.0 - * - * @return {this} This Game Object. - */ - resumeFollow: function () - { - var tween = this.pathTween; + if (r.operator === '>') { + return v.number > r.number; + } - if (tween && tween.isPaused()) - { - tween.resume(); - } + if (r.operator === '>=') { + return v.number >= r.number; + } - return this; - }, + if (r.operator === '~') { + return v.major === r.major && v.minor === r.minor && v.patch >= r.patch; + } - /** - * Stops this PathFollower from following the path any longer. - * - * This will invoke any 'stop' conditions that may exist on the Path, or for the follower. - * - * @method Phaser.GameObjects.Components.PathFollower#stopFollow - * @since 3.3.0 - * - * @return {this} This Game Object. - */ - stopFollow: function () - { - var tween = this.pathTween; + if (r.operator === '^') { + if (r.major > 0) { + return v.major === r.major && v.number >= r.number; + } - if (tween && tween.isPlaying()) - { - tween.stop(); + if (r.minor > 0) { + return v.minor === r.minor && v.patch >= r.patch; + } + + return v.patch === r.patch; + } } - return this; - }, + return version === range || version === '*'; + }; - /** - * Internal update handler that advances this PathFollower along the path. - * - * Called automatically by the Scene step, should not typically be called directly. - * - * @method Phaser.GameObjects.Components.PathFollower#pathUpdate - * @since 3.17.0 - */ - pathUpdate: function () - { - var tween = this.pathTween; +})(); - if (tween) - { - var tweenData = tween.data[0]; - var pathDelta = this.pathDelta; - var pathVector = this.pathVector; - pathDelta.copy(pathVector).negate(); +/***/ }), - if (tweenData.state === TWEEN_CONST.COMPLETE) - { - this.path.getPoint(1, pathVector); +/***/ 22806: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - pathDelta.add(pathVector); - pathVector.add(this.pathOffset); +/** +* The `Matter.Sleeping` module contains methods to manage the sleeping state of bodies. +* +* @class Sleeping +*/ - this.setPosition(pathVector.x, pathVector.y); +var Sleeping = {}; - return; - } - else if (tweenData.state !== TWEEN_CONST.PLAYING_FORWARD && tweenData.state !== TWEEN_CONST.PLAYING_BACKWARD) - { - // If delayed, etc then bail out - return; +module.exports = Sleeping; + +var Body = __webpack_require__(84125); +var Events = __webpack_require__(39073); +var Common = __webpack_require__(68758); + +(function() { + + Sleeping._motionWakeThreshold = 0.18; + Sleeping._motionSleepThreshold = 0.08; + Sleeping._minBias = 0.9; + + /** + * Puts bodies to sleep or wakes them up depending on their motion. + * @method update + * @param {body[]} bodies + * @param {number} delta + */ + Sleeping.update = function(bodies, delta) { + var timeScale = delta / Common._baseDelta, + motionSleepThreshold = Sleeping._motionSleepThreshold; + + // update bodies sleeping status + for (var i = 0; i < bodies.length; i++) { + var body = bodies[i], + speed = Body.getSpeed(body), + angularSpeed = Body.getAngularSpeed(body), + motion = speed * speed + angularSpeed * angularSpeed; + + // wake up bodies if they have a force applied + if (body.force.x !== 0 || body.force.y !== 0) { + Sleeping.set(body, false); + continue; } - this.path.getPoint(tween.getValue(), pathVector); + var minMotion = Math.min(body.motion, motion), + maxMotion = Math.max(body.motion, motion); + + // biased average motion estimation between frames + body.motion = Sleeping._minBias * minMotion + (1 - Sleeping._minBias) * maxMotion; - pathDelta.add(pathVector); - pathVector.add(this.pathOffset); + if (body.sleepThreshold > 0 && body.motion < motionSleepThreshold) { + body.sleepCounter += 1; + + if (body.sleepCounter >= body.sleepThreshold / timeScale) { + Sleeping.set(body, true); + } + } else if (body.sleepCounter > 0) { + body.sleepCounter -= 1; + } + } + }; - var oldX = this.x; - var oldY = this.y; + /** + * Given a set of colliding pairs, wakes the sleeping bodies involved. + * @method afterCollisions + * @param {pair[]} pairs + */ + Sleeping.afterCollisions = function(pairs) { + var motionSleepThreshold = Sleeping._motionSleepThreshold; - this.setPosition(pathVector.x, pathVector.y); + // wake up bodies involved in collisions + for (var i = 0; i < pairs.length; i++) { + var pair = pairs[i]; + + // don't wake inactive pairs + if (!pair.isActive) + continue; - var speedX = this.x - oldX; - var speedY = this.y - oldY; + var collision = pair.collision, + bodyA = collision.bodyA.parent, + bodyB = collision.bodyB.parent; + + // don't wake if at least one body is static + if ((bodyA.isSleeping && bodyB.isSleeping) || bodyA.isStatic || bodyB.isStatic) + continue; + + if (bodyA.isSleeping || bodyB.isSleeping) { + var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB, + movingBody = sleepingBody === bodyA ? bodyB : bodyA; - if (speedX === 0 && speedY === 0) - { - // Bail out early - return; + if (!sleepingBody.isStatic && movingBody.motion > motionSleepThreshold) { + Sleeping.set(sleepingBody, false); + } } + } + }; + + /** + * Set a body as sleeping or awake. + * @method set + * @param {body} body + * @param {boolean} isSleeping + */ + Sleeping.set = function(body, isSleeping) { + var wasSleeping = body.isSleeping; - if (tweenData.state !== this._prevDirection) - { - // We've changed direction, so don't do a rotate this frame - this._prevDirection = tweenData.state; + if (isSleeping) { + body.isSleeping = true; + body.sleepCounter = body.sleepThreshold; - return; + body.positionImpulse.x = 0; + body.positionImpulse.y = 0; + + body.positionPrev.x = body.position.x; + body.positionPrev.y = body.position.y; + + body.anglePrev = body.angle; + body.speed = 0; + body.angularSpeed = 0; + body.motion = 0; + + if (!wasSleeping) { + Events.trigger(body, 'sleepStart'); } + } else { + body.isSleeping = false; + body.sleepCounter = 0; - if (this.rotateToPath) - { - this.rotation = Math.atan2(speedY, speedX) + DegToRad(this.pathRotationOffset); + if (wasSleeping) { + Events.trigger(body, 'sleepEnd'); } } - } - -}; + }; -module.exports = PathFollower; +})(); /***/ }), -/* 634 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 68516: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Provides methods used for getting and setting the size of a Game Object. - * - * @namespace Phaser.GameObjects.Components.Size - * @since 3.0.0 - */ +* The `Matter.Bodies` module contains factory methods for creating rigid body models +* with commonly used body configurations (such as rectangles, circles and other polygons). +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Bodies +*/ -var Size = { +// TODO: true circle bodies - /** - * A property indicating that a Game Object has this component. - * - * @name Phaser.GameObjects.Components.Size#_sizeComponent - * @type {boolean} - * @private - * @default true - * @since 3.2.0 - */ - _sizeComponent: true, +var Bodies = {}; - /** - * The native (un-scaled) width of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. - * - * @name Phaser.GameObjects.Components.Size#width - * @type {number} - * @since 3.0.0 - */ - width: 0, +module.exports = Bodies; - /** - * The native (un-scaled) height of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. - * - * @name Phaser.GameObjects.Components.Size#height - * @type {number} - * @since 3.0.0 - */ - height: 0, +var Vertices = __webpack_require__(39745); +var Common = __webpack_require__(68758); +var Body = __webpack_require__(84125); +var Bounds = __webpack_require__(84091); +var Vector = __webpack_require__(10438); + +(function() { /** - * The displayed width of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - * - * @name Phaser.GameObjects.Components.Size#displayWidth - * @type {number} - * @since 3.0.0 + * Creates a new rigid body model with a rectangle hull. + * The options parameter is an object that specifies any properties you wish to override the defaults. + * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. + * @method rectangle + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @param {object} [options] + * @return {body} A new rectangle body */ - displayWidth: { + Bodies.rectangle = function(x, y, width, height, options) { + options = options || {}; - get: function () - { - return Math.abs(this.scaleX * this.frame.realWidth); - }, + var rectangle = { + label: 'Rectangle Body', + position: { x: x, y: y }, + vertices: Vertices.fromPath('L 0 0 L ' + width + ' 0 L ' + width + ' ' + height + ' L 0 ' + height) + }; - set: function (value) - { - this.scaleX = value / this.frame.realWidth; + if (options.chamfer) { + var chamfer = options.chamfer; + rectangle.vertices = Vertices.chamfer(rectangle.vertices, chamfer.radius, + chamfer.quality, chamfer.qualityMin, chamfer.qualityMax); + delete options.chamfer; } - }, + return Body.create(Common.extend({}, rectangle, options)); + }; /** - * The displayed height of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - * - * @name Phaser.GameObjects.Components.Size#displayHeight - * @type {number} - * @since 3.0.0 + * Creates a new rigid body model with a trapezoid hull. + * The `slope` is parameterised as a fraction of `width` and must be < 1 to form a valid trapezoid. + * The options parameter is an object that specifies any properties you wish to override the defaults. + * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. + * @method trapezoid + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + * @param {number} slope Must be a number < 1. + * @param {object} [options] + * @return {body} A new trapezoid body */ - displayHeight: { + Bodies.trapezoid = function(x, y, width, height, slope, options) { + options = options || {}; - get: function () - { - return Math.abs(this.scaleY * this.frame.realHeight); - }, + slope *= 0.5; + var roof = (1 - (slope * 2)) * width; - set: function (value) - { - this.scaleY = value / this.frame.realHeight; + var x1 = width * slope, + x2 = x1 + roof, + x3 = x2 + x1, + verticesPath; + + if (slope < 0.5) { + verticesPath = 'L 0 0 L ' + x1 + ' ' + (-height) + ' L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0'; + } else { + verticesPath = 'L 0 0 L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0'; } - }, + var trapezoid = { + label: 'Trapezoid Body', + position: { x: x, y: y }, + vertices: Vertices.fromPath(verticesPath) + }; + + if (options.chamfer) { + var chamfer = options.chamfer; + trapezoid.vertices = Vertices.chamfer(trapezoid.vertices, chamfer.radius, + chamfer.quality, chamfer.qualityMin, chamfer.qualityMax); + delete options.chamfer; + } + + return Body.create(Common.extend({}, trapezoid, options)); + }; /** - * Sets the size of this Game Object to be that of the given Frame. - * - * This will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or call the - * `setDisplaySize` method, which is the same thing as changing the scale but allows you - * to do so by giving pixel values. - * - * If you have enabled this Game Object for input, changing the size will _not_ change the - * size of the hit area. To do this you should adjust the `input.hitArea` object directly. - * - * @method Phaser.GameObjects.Components.Size#setSizeToFrame - * @since 3.0.0 - * - * @param {Phaser.Textures.Frame} frame - The frame to base the size of this Game Object on. - * - * @return {this} This Game Object instance. + * Creates a new rigid body model with a circle hull. + * The options parameter is an object that specifies any properties you wish to override the defaults. + * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. + * @method circle + * @param {number} x + * @param {number} y + * @param {number} radius + * @param {object} [options] + * @param {number} [maxSides] + * @return {body} A new circle body */ - setSizeToFrame: function (frame) - { - if (frame === undefined) { frame = this.frame; } + Bodies.circle = function(x, y, radius, options, maxSides) { + options = options || {}; - this.width = frame.realWidth; - this.height = frame.realHeight; + var circle = { + label: 'Circle Body', + circleRadius: radius + }; - return this; - }, + // approximate circles with polygons until true circles implemented in SAT + maxSides = maxSides || 25; + var sides = Math.ceil(Math.max(10, Math.min(maxSides, radius))); - /** - * Sets the internal size of this Game Object, as used for frame or physics body creation. - * - * This will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or call the - * `setDisplaySize` method, which is the same thing as changing the scale but allows you - * to do so by giving pixel values. - * - * If you have enabled this Game Object for input, changing the size will _not_ change the - * size of the hit area. To do this you should adjust the `input.hitArea` object directly. - * - * @method Phaser.GameObjects.Components.Size#setSize - * @since 3.0.0 - * - * @param {number} width - The width of this Game Object. - * @param {number} height - The height of this Game Object. - * - * @return {this} This Game Object instance. - */ - setSize: function (width, height) - { - this.width = width; - this.height = height; + // optimisation: always use even number of sides (half the number of unique axes) + if (sides % 2 === 1) + sides += 1; - return this; - }, + return Bodies.polygon(x, y, sides, radius, Common.extend({}, circle, options)); + }; /** - * Sets the display size of this Game Object. - * - * Calling this will adjust the scale. - * - * @method Phaser.GameObjects.Components.Size#setDisplaySize - * @since 3.0.0 - * - * @param {number} width - The width of this Game Object. - * @param {number} height - The height of this Game Object. - * - * @return {this} This Game Object instance. + * Creates a new rigid body model with a regular polygon hull with the given number of sides. + * The options parameter is an object that specifies any properties you wish to override the defaults. + * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. + * @method polygon + * @param {number} x + * @param {number} y + * @param {number} sides + * @param {number} radius + * @param {object} [options] + * @return {body} A new regular polygon body */ - setDisplaySize: function (width, height) - { - this.displayWidth = width; - this.displayHeight = height; - - return this; - } - -}; + Bodies.polygon = function(x, y, sides, radius, options) { + options = options || {}; -module.exports = Size; + if (sides < 3) + return Bodies.circle(x, y, radius, options); + var theta = 2 * Math.PI / sides, + path = '', + offset = theta * 0.5; -/***/ }), -/* 635 */ -/***/ (function(module, exports) { + for (var i = 0; i < sides; i += 1) { + var angle = offset + (i * theta), + xx = Math.cos(angle) * radius, + yy = Math.sin(angle) * radius; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + path += 'L ' + xx.toFixed(3) + ' ' + yy.toFixed(3) + ' '; + } -// bitmask flag for GameObject.renderMask -var _FLAG = 8; // 1000 + var polygon = { + label: 'Polygon Body', + position: { x: x, y: y }, + vertices: Vertices.fromPath(path) + }; -/** - * Provides methods used for getting and setting the texture of a Game Object. - * - * @namespace Phaser.GameObjects.Components.Texture - * @since 3.0.0 - */ + if (options.chamfer) { + var chamfer = options.chamfer; + polygon.vertices = Vertices.chamfer(polygon.vertices, chamfer.radius, + chamfer.quality, chamfer.qualityMin, chamfer.qualityMax); + delete options.chamfer; + } -var Texture = { + return Body.create(Common.extend({}, polygon, options)); + }; /** - * The Texture this Game Object is using to render with. + * Utility to create a compound body based on set(s) of vertices. * - * @name Phaser.GameObjects.Components.Texture#texture - * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} - * @since 3.0.0 - */ - texture: null, - - /** - * The Texture Frame this Game Object is using to render with. + * _Note:_ To optionally enable automatic concave vertices decomposition the [poly-decomp](https://github.com/schteppe/poly-decomp.js) + * package must be first installed and provided see `Common.setDecomp`, otherwise the convex hull of each vertex set will be used. * - * @name Phaser.GameObjects.Components.Texture#frame - * @type {Phaser.Textures.Frame} - * @since 3.0.0 - */ - frame: null, - - /** - * Internal flag. Not to be set by this Game Object. + * The resulting vertices are reorientated about their centre of mass, + * and offset such that `body.position` corresponds to this point. * - * @name Phaser.GameObjects.Components.Texture#isCropped - * @type {boolean} - * @private - * @since 3.11.0 - */ - isCropped: false, - - /** - * Sets the texture and frame this Game Object will use to render with. + * The resulting offset may be found if needed by subtracting `body.bounds` from the original input bounds. + * To later move the centre of mass see `Body.setCentre`. * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * Note that automatic conconcave decomposition results are not always optimal. + * For best results, simplify the input vertices as much as possible first. + * By default this function applies some addtional simplification to help. * - * @method Phaser.GameObjects.Components.Texture#setTexture - * @since 3.0.0 + * Some outputs may also require further manual processing afterwards to be robust. + * In particular some parts may need to be overlapped to avoid collision gaps. + * Thin parts and sharp points should be avoided or removed where possible. * - * @param {(string|Phaser.Textures.Texture)} key - The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. - * @param {(string|number)} [frame] - The name or index of the frame within the Texture. + * The options parameter object specifies any `Matter.Body` properties you wish to override the defaults. * - * @return {this} This Game Object instance. + * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. + * @method fromVertices + * @param {number} x + * @param {number} y + * @param {array} vertexSets One or more arrays of vertex points e.g. `[[{ x: 0, y: 0 }...], ...]`. + * @param {object} [options] The body options. + * @param {bool} [flagInternal=false] Optionally marks internal edges with `isInternal`. + * @param {number} [removeCollinear=0.01] Threshold when simplifying vertices along the same edge. + * @param {number} [minimumArea=10] Threshold when removing small parts. + * @param {number} [removeDuplicatePoints=0.01] Threshold when simplifying nearby vertices. + * @return {body} */ - setTexture: function (key, frame) - { - this.texture = this.scene.sys.textures.get(key); + Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea, removeDuplicatePoints) { + var decomp = Common.getDecomp(), + canDecomp, + body, + parts, + isConvex, + isConcave, + vertices, + i, + j, + k, + v, + z; - return this.setFrame(frame); - }, + // check decomp is as expected + canDecomp = Boolean(decomp && decomp.quickDecomp); - /** - * Sets the frame this Game Object will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. - * - * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. - * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * - * @method Phaser.GameObjects.Components.Texture#setFrame - * @since 3.0.0 - * - * @param {(string|number)} frame - The name or index of the frame within the Texture. - * @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object? - * @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object? - * - * @return {this} This Game Object instance. - */ - setFrame: function (frame, updateSize, updateOrigin) - { - if (updateSize === undefined) { updateSize = true; } - if (updateOrigin === undefined) { updateOrigin = true; } + options = options || {}; + parts = []; - this.frame = this.texture.get(frame); + flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false; + removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01; + minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10; + removeDuplicatePoints = typeof removeDuplicatePoints !== 'undefined' ? removeDuplicatePoints : 0.01; - if (!this.frame.cutWidth || !this.frame.cutHeight) - { - this.renderFlags &= ~_FLAG; + // ensure vertexSets is an array of arrays + if (!Common.isArray(vertexSets[0])) { + vertexSets = [vertexSets]; } - else - { - this.renderFlags |= _FLAG; + + for (v = 0; v < vertexSets.length; v += 1) { + vertices = vertexSets[v]; + isConvex = Vertices.isConvex(vertices); + isConcave = !isConvex; + + if (isConcave && !canDecomp) { + Common.warnOnce( + 'Bodies.fromVertices: Install the \'poly-decomp\' library and use Common.setDecomp or provide \'decomp\' as a global to decompose concave vertices.' + ); + } + + if (isConvex || !canDecomp) { + if (isConvex) { + vertices = Vertices.clockwiseSort(vertices); + } else { + // fallback to convex hull when decomposition is not possible + vertices = Vertices.hull(vertices); + } + + parts.push({ + position: { x: x, y: y }, + vertices: vertices + }); + } else { + // initialise a decomposition + var concave = vertices.map(function(vertex) { + return [vertex.x, vertex.y]; + }); + + // vertices are concave and simple, we can decompose into parts + decomp.makeCCW(concave); + if (removeCollinear !== false) + decomp.removeCollinearPoints(concave, removeCollinear); + if (removeDuplicatePoints !== false && decomp.removeDuplicatePoints) + decomp.removeDuplicatePoints(concave, removeDuplicatePoints); + + // use the quick decomposition algorithm (Bayazit) + var decomposed = decomp.quickDecomp(concave); + + // for each decomposed chunk + for (i = 0; i < decomposed.length; i++) { + var chunk = decomposed[i]; + + // convert vertices into the correct structure + var chunkVertices = chunk.map(function(vertices) { + return { + x: vertices[0], + y: vertices[1] + }; + }); + + // skip small chunks + if (minimumArea > 0 && Vertices.area(chunkVertices) < minimumArea) + continue; + + // create a compound part + parts.push({ + position: Vertices.centre(chunkVertices), + vertices: chunkVertices + }); + } + } } - if (this._sizeComponent && updateSize) - { - this.setSizeToFrame(); + // create body parts + for (i = 0; i < parts.length; i++) { + parts[i] = Body.create(Common.extend(parts[i], options)); } - if (this._originComponent && updateOrigin) - { - if (this.frame.customPivot) - { - this.setOrigin(this.frame.pivotX, this.frame.pivotY); + // flag internal edges (coincident part edges) + if (flagInternal) { + var coincident_max_dist = 5; + + for (i = 0; i < parts.length; i++) { + var partA = parts[i]; + + for (j = i + 1; j < parts.length; j++) { + var partB = parts[j]; + + if (Bounds.overlaps(partA.bounds, partB.bounds)) { + var pav = partA.vertices, + pbv = partB.vertices; + + // iterate vertices of both parts + for (k = 0; k < partA.vertices.length; k++) { + for (z = 0; z < partB.vertices.length; z++) { + // find distances between the vertices + var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z])), + db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length])); + + // if both vertices are very close, consider the edge concident (internal) + if (da < coincident_max_dist && db < coincident_max_dist) { + pav[k].isInternal = true; + pbv[z].isInternal = true; + } + } + } + + } + } } - else + } + + if (parts.length > 1) { + // create the parent body to be returned, that contains generated compound parts + body = Body.create(Common.extend({ parts: parts.slice(0) }, options)); + + // offset such that body.position is at the centre off mass + Body.setPosition(body, { x: x, y: y }); + + return body; + } else { + return parts[0]; + } + }; + + /** + * Takes an array of Body objects and flags all internal edges (coincident parts) based on the maxDistance + * value. The array is changed in-place and returned, so you can pass this function a `Body.parts` property. + * + * @method flagCoincidentParts + * @param {body[]} parts - The Body parts, or array of bodies, to flag. + * @param {number} [maxDistance=5] + * @return {body[]} The modified `parts` parameter. + */ + Bodies.flagCoincidentParts = function (parts, maxDistance) + { + if (maxDistance === undefined) { maxDistance = 5; } + + for (var i = 0; i < parts.length; i++) + { + var partA = parts[i]; + + for (var j = i + 1; j < parts.length; j++) { - this.updateDisplayOrigin(); + var partB = parts[j]; + + if (Bounds.overlaps(partA.bounds, partB.bounds)) + { + var pav = partA.vertices; + var pbv = partB.vertices; + + // iterate vertices of both parts + for (var k = 0; k < partA.vertices.length; k++) + { + for (var z = 0; z < partB.vertices.length; z++) + { + // find distances between the vertices + var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z])); + var db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length])); + + // if both vertices are very close, consider the edge concident (internal) + if (da < maxDistance && db < maxDistance) + { + pav[k].isInternal = true; + pbv[z].isInternal = true; + } + } + } + } } } - return this; - } - -}; + return parts; + }; -module.exports = Texture; +})(); /***/ }), -/* 636 */ -/***/ (function(module, exports) { + +/***/ 56643: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +* The `Matter.Composites` module contains factory methods for creating composite bodies +* with commonly used configurations (such as stacks and chains). +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Composites +*/ -// bitmask flag for GameObject.renderMask -var _FLAG = 8; // 1000 +var Composites = {}; -/** - * Provides methods used for getting and setting the texture of a Game Object. - * - * @namespace Phaser.GameObjects.Components.TextureCrop - * @since 3.0.0 - */ +module.exports = Composites; -var TextureCrop = { +var Composite = __webpack_require__(11299); +var Constraint = __webpack_require__(52838); +var Common = __webpack_require__(68758); +var Body = __webpack_require__(84125); +var Bodies = __webpack_require__(68516); - /** - * The Texture this Game Object is using to render with. - * - * @name Phaser.GameObjects.Components.TextureCrop#texture - * @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture} - * @since 3.0.0 - */ - texture: null, +(function() { /** - * The Texture Frame this Game Object is using to render with. - * - * @name Phaser.GameObjects.Components.TextureCrop#frame - * @type {Phaser.Textures.Frame} - * @since 3.0.0 + * Create a new composite containing bodies created in the callback in a grid arrangement. + * This function uses the body's bounds to prevent overlaps. + * @method stack + * @param {number} x Starting position in X. + * @param {number} y Starting position in Y. + * @param {number} columns + * @param {number} rows + * @param {number} columnGap + * @param {number} rowGap + * @param {function} callback + * @return {composite} A new composite containing objects created in the callback */ - frame: null, + Composites.stack = function(x, y, columns, rows, columnGap, rowGap, callback) { + var stack = Composite.create({ label: 'Stack' }), + currentX = x, + currentY = y, + lastBody, + i = 0; - /** - * A boolean flag indicating if this Game Object is being cropped or not. - * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. - * Equally, calling `setCrop` with no arguments will reset the crop and disable it. - * - * @name Phaser.GameObjects.Components.TextureCrop#isCropped - * @type {boolean} - * @since 3.11.0 - */ - isCropped: false, + for (var row = 0; row < rows; row++) { + var maxHeight = 0; - /** - * Applies a crop to a texture based Game Object, such as a Sprite or Image. - * - * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. - * - * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just - * changes what is shown when rendered. - * - * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. - * - * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left - * half of it, you could call `setCrop(0, 0, 400, 600)`. - * - * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop - * an area of 200x100 when applied to a Game Object that had a scale factor of 2. - * - * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. - * - * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. - * - * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow - * the renderer to skip several internal calculations. - * - * @method Phaser.GameObjects.Components.TextureCrop#setCrop - * @since 3.11.0 - * - * @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. - * @param {number} [y] - The y coordinate to start the crop from. - * @param {number} [width] - The width of the crop rectangle in pixels. - * @param {number} [height] - The height of the crop rectangle in pixels. - * - * @return {this} This Game Object instance. - */ - setCrop: function (x, y, width, height) - { - if (x === undefined) - { - this.isCropped = false; - } - else if (this.frame) - { - if (typeof x === 'number') - { - this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY); - } - else - { - var rect = x; + for (var column = 0; column < columns; column++) { + var body = callback(currentX, currentY, column, row, lastBody, i); - this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY); + if (body) { + var bodyHeight = body.bounds.max.y - body.bounds.min.y, + bodyWidth = body.bounds.max.x - body.bounds.min.x; + + if (bodyHeight > maxHeight) + maxHeight = bodyHeight; + + Body.translate(body, { x: bodyWidth * 0.5, y: bodyHeight * 0.5 }); + + currentX = body.bounds.max.x + columnGap; + + Composite.addBody(stack, body); + + lastBody = body; + i += 1; + } else { + currentX += columnGap; + } } - this.isCropped = true; + currentY += maxHeight + rowGap; + currentX = x; } - return this; - }, + return stack; + }; /** - * Sets the texture and frame this Game Object will use to render with. - * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * - * @method Phaser.GameObjects.Components.TextureCrop#setTexture - * @since 3.0.0 - * - * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. - * @param {(string|number)} [frame] - The name or index of the frame within the Texture. - * - * @return {this} This Game Object instance. + * Chains all bodies in the given composite together using constraints. + * @method chain + * @param {composite} composite + * @param {number} xOffsetA + * @param {number} yOffsetA + * @param {number} xOffsetB + * @param {number} yOffsetB + * @param {object} options + * @return {composite} A new composite containing objects chained together with constraints */ - setTexture: function (key, frame) - { - this.texture = this.scene.sys.textures.get(key); + Composites.chain = function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) { + var bodies = composite.bodies; - return this.setFrame(frame); - }, + for (var i = 1; i < bodies.length; i++) { + var bodyA = bodies[i - 1], + bodyB = bodies[i], + bodyAHeight = bodyA.bounds.max.y - bodyA.bounds.min.y, + bodyAWidth = bodyA.bounds.max.x - bodyA.bounds.min.x, + bodyBHeight = bodyB.bounds.max.y - bodyB.bounds.min.y, + bodyBWidth = bodyB.bounds.max.x - bodyB.bounds.min.x; - /** - * Sets the frame this Game Object will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. - * - * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. - * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * - * @method Phaser.GameObjects.Components.TextureCrop#setFrame - * @since 3.0.0 - * - * @param {(string|number)} frame - The name or index of the frame within the Texture. - * @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object? - * @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object? - * - * @return {this} This Game Object instance. - */ - setFrame: function (frame, updateSize, updateOrigin) - { - if (updateSize === undefined) { updateSize = true; } - if (updateOrigin === undefined) { updateOrigin = true; } + var defaults = { + bodyA: bodyA, + pointA: { x: bodyAWidth * xOffsetA, y: bodyAHeight * yOffsetA }, + bodyB: bodyB, + pointB: { x: bodyBWidth * xOffsetB, y: bodyBHeight * yOffsetB } + }; - this.frame = this.texture.get(frame); + var constraint = Common.extend(defaults, options); - if (!this.frame.cutWidth || !this.frame.cutHeight) - { - this.renderFlags &= ~_FLAG; - } - else - { - this.renderFlags |= _FLAG; + Composite.addConstraint(composite, Constraint.create(constraint)); } - if (this._sizeComponent && updateSize) - { - this.setSizeToFrame(); - } + composite.label += ' Chain'; - if (this._originComponent && updateOrigin) - { - if (this.frame.customPivot) - { - this.setOrigin(this.frame.pivotX, this.frame.pivotY); + return composite; + }; + + /** + * Connects bodies in the composite with constraints in a grid pattern, with optional cross braces. + * @method mesh + * @param {composite} composite + * @param {number} columns + * @param {number} rows + * @param {boolean} crossBrace + * @param {object} options + * @return {composite} The composite containing objects meshed together with constraints + */ + Composites.mesh = function(composite, columns, rows, crossBrace, options) { + var bodies = composite.bodies, + row, + col, + bodyA, + bodyB, + bodyC; + + for (row = 0; row < rows; row++) { + for (col = 1; col < columns; col++) { + bodyA = bodies[(col - 1) + (row * columns)]; + bodyB = bodies[col + (row * columns)]; + Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options))); } - else - { - this.updateDisplayOrigin(); + + if (row > 0) { + for (col = 0; col < columns; col++) { + bodyA = bodies[col + ((row - 1) * columns)]; + bodyB = bodies[col + (row * columns)]; + Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options))); + + if (crossBrace && col > 0) { + bodyC = bodies[(col - 1) + ((row - 1) * columns)]; + Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options))); + } + + if (crossBrace && col < columns - 1) { + bodyC = bodies[(col + 1) + ((row - 1) * columns)]; + Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options))); + } + } } } - if (this.isCropped) - { - this.frame.updateCropUVs(this._crop, this.flipX, this.flipY); - } + composite.label += ' Mesh'; - return this; - }, + return composite; + }; /** - * Internal method that returns a blank, well-formed crop object for use by a Game Object. - * - * @method Phaser.GameObjects.Components.TextureCrop#resetCropObject - * @private - * @since 3.12.0 - * - * @return {object} The crop object. + * Create a new composite containing bodies created in the callback in a pyramid arrangement. + * This function uses the body's bounds to prevent overlaps. + * @method pyramid + * @param {number} x Starting position in X. + * @param {number} y Starting position in Y. + * @param {number} columns + * @param {number} rows + * @param {number} columnGap + * @param {number} rowGap + * @param {function} callback + * @return {composite} A new composite containing objects created in the callback */ - resetCropObject: function () - { - return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 }; - } + Composites.pyramid = function(x, y, columns, rows, columnGap, rowGap, callback) { + return Composites.stack(x, y, columns, rows, columnGap, rowGap, function(stackX, stackY, column, row, lastBody, i) { + var actualRows = Math.min(rows, Math.ceil(columns / 2)), + lastBodyWidth = lastBody ? lastBody.bounds.max.x - lastBody.bounds.min.x : 0; -}; + if (row > actualRows) + return; -module.exports = TextureCrop; + // reverse row order + row = actualRows - row; + var start = row, + end = columns - 1 - row; -/***/ }), -/* 637 */ -/***/ (function(module, exports) { + if (column < start || column > end) + return; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // retroactively fix the first body's position, since width was unknown + if (i === 1) { + Body.translate(lastBody, { x: (column + (columns % 2 === 1 ? 1 : -1)) * lastBodyWidth, y: 0 }); + } -/** - * Provides methods used for setting the tint of a Game Object. - * Should be applied as a mixin and not used directly. - * - * @namespace Phaser.GameObjects.Components.Tint - * @webglOnly - * @since 3.0.0 - */ + var xOffset = lastBody ? column * lastBodyWidth : 0; -var Tint = { + return callback(x + xOffset + column * columnGap, stackY, column, row, lastBody, i); + }); + }; /** - * The tint value being applied to the top-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - * - * @name Phaser.GameObjects.Components.Tint#tintTopLeft - * @type {number} - * @default 0xffffff - * @since 3.0.0 + * This has now moved to the [newtonsCradle example](https://github.com/liabru/matter-js/blob/master/examples/newtonsCradle.js), follow that instead as this function is deprecated here. + * @deprecated moved to newtonsCradle example + * @method newtonsCradle + * @param {number} x Starting position in X. + * @param {number} y Starting position in Y. + * @param {number} number + * @param {number} size + * @param {number} length + * @return {composite} A new composite newtonsCradle body */ - tintTopLeft: 0xffffff, + Composites.newtonsCradle = function(x, y, number, size, length) { + var newtonsCradle = Composite.create({ label: 'Newtons Cradle' }); - /** - * The tint value being applied to the top-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - * - * @name Phaser.GameObjects.Components.Tint#tintTopRight - * @type {number} - * @default 0xffffff - * @since 3.0.0 - */ - tintTopRight: 0xffffff, + for (var i = 0; i < number; i++) { + var separation = 1.9, + circle = Bodies.circle(x + i * (size * separation), y + length, size, + { inertia: Infinity, restitution: 1, friction: 0, frictionAir: 0.0001, slop: 1 }), + constraint = Constraint.create({ pointA: { x: x + i * (size * separation), y: y }, bodyB: circle }); - /** - * The tint value being applied to the bottom-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - * - * @name Phaser.GameObjects.Components.Tint#tintBottomLeft - * @type {number} - * @default 0xffffff - * @since 3.0.0 - */ - tintBottomLeft: 0xffffff, + Composite.addBody(newtonsCradle, circle); + Composite.addConstraint(newtonsCradle, constraint); + } - /** - * The tint value being applied to the bottom-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - * - * @name Phaser.GameObjects.Components.Tint#tintBottomRight - * @type {number} - * @default 0xffffff - * @since 3.0.0 - */ - tintBottomRight: 0xffffff, + return newtonsCradle; + }; /** - * The tint fill mode. - * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. - * - * @name Phaser.GameObjects.Components.Tint#tintFill - * @type {boolean} - * @default false - * @since 3.11.0 + * This has now moved to the [car example](https://github.com/liabru/matter-js/blob/master/examples/car.js), follow that instead as this function is deprecated here. + * @deprecated moved to car example + * @method car + * @param {number} x Starting position in X. + * @param {number} y Starting position in Y. + * @param {number} width + * @param {number} height + * @param {number} wheelSize + * @return {composite} A new composite car body */ - tintFill: false, + Composites.car = function(x, y, width, height, wheelSize) { + var group = Body.nextGroup(true), + wheelBase = 20, + wheelAOffset = -width * 0.5 + wheelBase, + wheelBOffset = width * 0.5 - wheelBase, + wheelYOffset = 0; - /** - * Clears all tint values associated with this Game Object. - * - * Immediately sets the color values back to 0xffffff and the tint type to 'additive', - * which results in no visible change to the texture. - * - * @method Phaser.GameObjects.Components.Tint#clearTint - * @webglOnly - * @since 3.0.0 - * - * @return {this} This Game Object instance. - */ - clearTint: function () - { - this.setTint(0xffffff); + var car = Composite.create({ label: 'Car' }), + body = Bodies.rectangle(x, y, width, height, { + collisionFilter: { + group: group + }, + chamfer: { + radius: height * 0.5 + }, + density: 0.0002 + }); - return this; - }, + var wheelA = Bodies.circle(x + wheelAOffset, y + wheelYOffset, wheelSize, { + collisionFilter: { + group: group + }, + friction: 0.8 + }); - /** - * Sets an additive tint on this Game Object. - * - * The tint works by taking the pixel color values from the Game Objects texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole Game Object will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. - * - * @method Phaser.GameObjects.Components.Tint#setTint - * @webglOnly - * @since 3.0.0 - * - * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. - * @param {number} [topRight] - The tint being applied to the top-right of the Game Object. - * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the Game Object. - * @param {number} [bottomRight] - The tint being applied to the bottom-right of the Game Object. - * - * @return {this} This Game Object instance. - */ - setTint: function (topLeft, topRight, bottomLeft, bottomRight) - { - if (topLeft === undefined) { topLeft = 0xffffff; } + var wheelB = Bodies.circle(x + wheelBOffset, y + wheelYOffset, wheelSize, { + collisionFilter: { + group: group + }, + friction: 0.8 + }); - if (topRight === undefined) - { - topRight = topLeft; - bottomLeft = topLeft; - bottomRight = topLeft; - } + var axelA = Constraint.create({ + bodyB: body, + pointB: { x: wheelAOffset, y: wheelYOffset }, + bodyA: wheelA, + stiffness: 1, + length: 0 + }); - this.tintTopLeft = topLeft; - this.tintTopRight = topRight; - this.tintBottomLeft = bottomLeft; - this.tintBottomRight = bottomRight; + var axelB = Constraint.create({ + bodyB: body, + pointB: { x: wheelBOffset, y: wheelYOffset }, + bodyA: wheelB, + stiffness: 1, + length: 0 + }); - this.tintFill = false; + Composite.addBody(car, body); + Composite.addBody(car, wheelA); + Composite.addBody(car, wheelB); + Composite.addConstraint(car, axelA); + Composite.addConstraint(car, axelB); - return this; - }, + return car; + }; /** - * Sets a fill-based tint on this Game Object. - * - * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture - * with those in the tint. You can use this for effects such as making a player flash 'white' - * if hit by something. You can provide either one color value, in which case the whole - * Game Object will be rendered in that color. Or you can provide a color per corner. The colors - * are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. - * - * @method Phaser.GameObjects.Components.Tint#setTintFill - * @webglOnly - * @since 3.11.0 - * - * @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. - * @param {number} [topRight] - The tint being applied to the top-right of the Game Object. - * @param {number} [bottomLeft] - The tint being applied to the bottom-left of the Game Object. - * @param {number} [bottomRight] - The tint being applied to the bottom-right of the Game Object. - * - * @return {this} This Game Object instance. + * This has now moved to the [softBody example](https://github.com/liabru/matter-js/blob/master/examples/softBody.js) + * and the [cloth example](https://github.com/liabru/matter-js/blob/master/examples/cloth.js), follow those instead as this function is deprecated here. + * @deprecated moved to softBody and cloth examples + * @method softBody + * @param {number} x Starting position in X. + * @param {number} y Starting position in Y. + * @param {number} columns + * @param {number} rows + * @param {number} columnGap + * @param {number} rowGap + * @param {boolean} crossBrace + * @param {number} particleRadius + * @param {} particleOptions + * @param {} constraintOptions + * @return {composite} A new composite softBody */ - setTintFill: function (topLeft, topRight, bottomLeft, bottomRight) - { - this.setTint(topLeft, topRight, bottomLeft, bottomRight); + Composites.softBody = function(x, y, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) { + particleOptions = Common.extend({ inertia: Infinity }, particleOptions); + constraintOptions = Common.extend({ stiffness: 0.2, render: { type: 'line', anchors: false } }, constraintOptions); - this.tintFill = true; + var softBody = Composites.stack(x, y, columns, rows, columnGap, rowGap, function(stackX, stackY) { + return Bodies.circle(stackX, stackY, particleRadius, particleOptions); + }); - return this; - }, + Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions); + + softBody.label = 'Soft Body'; + + return softBody; + }; + +})(); + + +/***/ }), + +/***/ 50658: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** +* The `Matter.Axes` module contains methods for creating and manipulating sets of axes. +* +* @class Axes +*/ + +var Axes = {}; + +module.exports = Axes; + +var Vector = __webpack_require__(10438); +var Common = __webpack_require__(68758); + +(function() { /** - * The tint value being applied to the whole of the Game Object. - * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. - * - * @name Phaser.GameObjects.Components.Tint#tint - * @type {number} - * @webglOnly - * @since 3.0.0 + * Creates a new set of axes from the given vertices. + * @method fromVertices + * @param {vertices} vertices + * @return {axes} A new axes from the given vertices */ - tint: { + Axes.fromVertices = function(vertices) { + var axes = {}; - set: function (value) - { - this.setTint(value, value, value, value); + // find the unique axes, using edge normal gradients + for (var i = 0; i < vertices.length; i++) { + var j = (i + 1) % vertices.length, + normal = Vector.normalise({ + x: vertices[j].y - vertices[i].y, + y: vertices[i].x - vertices[j].x + }), + gradient = (normal.y === 0) ? Infinity : (normal.x / normal.y); + + // limit precision + gradient = gradient.toFixed(3).toString(); + axes[gradient] = normal; } - }, + + return Common.values(axes); + }; /** - * Does this Game Object have a tint applied? - * - * It checks to see if the 4 tint properties are set to the value 0xffffff - * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. - * - * @name Phaser.GameObjects.Components.Tint#isTinted - * @type {boolean} - * @webglOnly - * @readonly - * @since 3.11.0 + * Rotates a set of axes by the given angle. + * @method rotate + * @param {axes} axes + * @param {number} angle */ - isTinted: { - - get: function () - { - var white = 0xffffff; + Axes.rotate = function(axes, angle) { + if (angle === 0) + return; + + var cos = Math.cos(angle), + sin = Math.sin(angle); - return ( - this.tintFill || - this.tintTopLeft !== white || - this.tintTopRight !== white || - this.tintBottomLeft !== white || - this.tintBottomRight !== white - ); + for (var i = 0; i < axes.length; i++) { + var axis = axes[i], + xx; + xx = axis.x * cos - axis.y * sin; + axis.y = axis.x * sin + axis.y * cos; + axis.x = xx; } + }; - } - -}; - -module.exports = Tint; +})(); /***/ }), -/* 638 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 84091: +/***/ ((module) => { /** - * The Change Data Event. - * - * This event is dispatched by a Data Manager when an item in the data store is changed. - * - * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for - * a change data event from a Game Object you would use: `sprite.data.on('changedata', listener)`. - * - * This event is dispatched for all items that change in the Data Manager. - * To listen for the change of a specific item, use the `CHANGE_DATA_KEY_EVENT` event. - * - * @event Phaser.Data.Events#CHANGE_DATA - * @since 3.0.0 - * - * @param {any} parent - A reference to the object that the Data Manager responsible for this event belongs to. - * @param {string} key - The unique key of the data item within the Data Manager. - * @param {any} value - The new value of the item in the Data Manager. - * @param {any} previousValue - The previous value of the item in the Data Manager. - */ -module.exports = 'changedata'; - +* The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB). +* +* @class Bounds +*/ -/***/ }), -/* 639 */ -/***/ (function(module, exports) { +var Bounds = {}; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +module.exports = Bounds; -/** - * The Change Data Key Event. - * - * This event is dispatched by a Data Manager when an item in the data store is changed. - * - * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for - * the change of a specific data item from a Game Object you would use: `sprite.data.on('changedata-key', listener)`, - * where `key` is the unique string key of the data item. For example, if you have a data item stored called `gold` - * then you can listen for `sprite.data.on('changedata-gold')`. - * - * @event Phaser.Data.Events#CHANGE_DATA_KEY - * @since 3.16.1 - * - * @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event. - * @param {any} value - The item that was updated in the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance. - * @param {any} previousValue - The previous item that was updated in the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance. - */ -module.exports = 'changedata-'; +(function() { + /** + * Creates a new axis-aligned bounding box (AABB) for the given vertices. + * @method create + * @param {vertices} vertices + * @return {bounds} A new bounds object + */ + Bounds.create = function(vertices) { + var bounds = { + min: { x: 0, y: 0 }, + max: { x: 0, y: 0 } + }; -/***/ }), -/* 640 */ -/***/ (function(module, exports) { + if (vertices) + Bounds.update(bounds, vertices); + + return bounds; + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Updates bounds using the given vertices and extends the bounds given a velocity. + * @method update + * @param {bounds} bounds + * @param {vertices} vertices + * @param {vector} velocity + */ + Bounds.update = function(bounds, vertices, velocity) { + bounds.min.x = Infinity; + bounds.max.x = -Infinity; + bounds.min.y = Infinity; + bounds.max.y = -Infinity; -/** - * The Data Manager Destroy Event. - * - * The Data Manager will listen for the destroy event from its parent, and then close itself down. - * - * @event Phaser.Data.Events#DESTROY - * @since 3.50.0 - */ -module.exports = 'destroy'; + for (var i = 0; i < vertices.length; i++) { + var vertex = vertices[i]; + if (vertex.x > bounds.max.x) bounds.max.x = vertex.x; + if (vertex.x < bounds.min.x) bounds.min.x = vertex.x; + if (vertex.y > bounds.max.y) bounds.max.y = vertex.y; + if (vertex.y < bounds.min.y) bounds.min.y = vertex.y; + } + + if (velocity) { + if (velocity.x > 0) { + bounds.max.x += velocity.x; + } else { + bounds.min.x += velocity.x; + } + + if (velocity.y > 0) { + bounds.max.y += velocity.y; + } else { + bounds.min.y += velocity.y; + } + } + }; + /** + * Returns true if the bounds contains the given point. + * @method contains + * @param {bounds} bounds + * @param {vector} point + * @return {boolean} True if the bounds contain the point, otherwise false + */ + Bounds.contains = function(bounds, point) { + return point.x >= bounds.min.x && point.x <= bounds.max.x + && point.y >= bounds.min.y && point.y <= bounds.max.y; + }; -/***/ }), -/* 641 */ -/***/ (function(module, exports) { + /** + * Returns true if the two bounds intersect. + * @method overlaps + * @param {bounds} boundsA + * @param {bounds} boundsB + * @return {boolean} True if the bounds overlap, otherwise false + */ + Bounds.overlaps = function(boundsA, boundsB) { + return (boundsA.min.x <= boundsB.max.x && boundsA.max.x >= boundsB.min.x + && boundsA.max.y >= boundsB.min.y && boundsA.min.y <= boundsB.max.y); + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Translates the bounds by the given vector. + * @method translate + * @param {bounds} bounds + * @param {vector} vector + */ + Bounds.translate = function(bounds, vector) { + bounds.min.x += vector.x; + bounds.max.x += vector.x; + bounds.min.y += vector.y; + bounds.max.y += vector.y; + }; -/** - * The Remove Data Event. - * - * This event is dispatched by a Data Manager when an item is removed from it. - * - * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for - * the removal of a data item on a Game Object you would use: `sprite.data.on('removedata', listener)`. - * - * @event Phaser.Data.Events#REMOVE_DATA - * @since 3.0.0 - * - * @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event. - * @param {string} key - The unique key of the data item within the Data Manager. - * @param {any} data - The item that was removed from the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance. - */ -module.exports = 'removedata'; + /** + * Shifts the bounds to the given position. + * @method shift + * @param {bounds} bounds + * @param {vector} position + */ + Bounds.shift = function(bounds, position) { + var deltaX = bounds.max.x - bounds.min.x, + deltaY = bounds.max.y - bounds.min.y; + + bounds.min.x = position.x; + bounds.max.x = position.x + deltaX; + bounds.min.y = position.y; + bounds.max.y = position.y + deltaY; + }; + +})(); /***/ }), -/* 642 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 92765: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * The Set Data Event. - * - * This event is dispatched by a Data Manager when a new item is added to the data store. - * - * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for - * the addition of a new data item on a Game Object you would use: `sprite.data.on('setdata', listener)`. - * - * @event Phaser.Data.Events#SET_DATA - * @since 3.0.0 - * - * @param {any} parent - A reference to the object that owns the instance of the Data Manager responsible for this event. - * @param {string} key - The unique key of the data item within the Data Manager. - * @param {any} data - The item that was added to the Data Manager. This can be of any data type, i.e. a string, boolean, number, object or instance. - */ -module.exports = 'setdata'; +* The `Matter.Svg` module contains methods for converting SVG images into an array of vector points. +* +* To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Svg +*/ +var Svg = {}; -/***/ }), -/* 643 */ -/***/ (function(module, exports) { +module.exports = Svg; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +var Bounds = __webpack_require__(84091); +var Common = __webpack_require__(68758); -/** - * The Game Object Added to Scene Event. - * - * This event is dispatched when a Game Object is added to a Scene. - * - * Listen for it on a Game Object instance using `GameObject.on('addedtoscene', listener)`. - * - * @event Phaser.GameObjects.Events#ADDED_TO_SCENE - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the Scene. - * @param {Phaser.Scene} scene - The Scene to which the Game Object was added. - */ -module.exports = 'addedtoscene'; +(function() { + /** + * Converts an SVG path into an array of vector points. + * If the input path forms a concave shape, you must decompose the result into convex parts before use. + * See `Bodies.fromVertices` which provides support for this. + * Note that this function is not guaranteed to support complex paths (such as those with holes). + * You must load the `pathseg.js` polyfill on newer browsers. + * @method pathToVertices + * @param {SVGPathElement} path + * @param {Number} [sampleLength=15] + * @return {Vector[]} points + */ + Svg.pathToVertices = function(path, sampleLength) { + if (typeof window !== 'undefined' && !('SVGPathSeg' in window)) { + Common.warn('Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.'); + } -/***/ }), -/* 644 */ -/***/ (function(module, exports) { + // https://github.com/wout/svg.topoly.js/blob/master/svg.topoly.js + var i, il, total, point, segment, segments, + segmentsQueue, lastSegment, + lastPoint, segmentIndex, points = [], + lx, ly, length = 0, x = 0, y = 0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + sampleLength = sampleLength || 15; -/** - * The Game Object Destroy Event. - * - * This event is dispatched when a Game Object instance is being destroyed. - * - * Listen for it on a Game Object instance using `GameObject.on('destroy', listener)`. - * - * @event Phaser.GameObjects.Events#DESTROY - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object which is being destroyed. - * @param {boolean} fromScene - `True` if this Game Object is being destroyed by the Scene, `false` if not. - */ -module.exports = 'destroy'; + var addPoint = function(px, py, pathSegType) { + // all odd-numbered path types are relative except PATHSEG_CLOSEPATH (1) + var isRelative = pathSegType % 2 === 1 && pathSegType > 1; + // when the last point doesn't equal the current point add the current point + if (!lastPoint || px != lastPoint.x || py != lastPoint.y) { + if (lastPoint && isRelative) { + lx = lastPoint.x; + ly = lastPoint.y; + } else { + lx = 0; + ly = 0; + } -/***/ }), -/* 645 */ -/***/ (function(module, exports) { + var point = { + x: lx + px, + y: ly + py + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // set last point + if (isRelative || !lastPoint) { + lastPoint = point; + } -/** - * The Game Object Removed from Scene Event. - * - * This event is dispatched when a Game Object is removed from a Scene. - * - * Listen for it on a Game Object instance using `GameObject.on('removedfromscene', listener)`. - * - * @event Phaser.GameObjects.Events#REMOVED_FROM_SCENE - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the Scene. - * @param {Phaser.Scene} scene - The Scene from which the Game Object was removed. - */ -module.exports = 'removedfromscene'; + points.push(point); + x = lx + px; + y = ly + py; + } + }; -/***/ }), -/* 646 */ -/***/ (function(module, exports) { + var addSegmentPoint = function(segment) { + var segType = segment.pathSegTypeAsLetter.toUpperCase(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // skip path ends + if (segType === 'Z') + return; -/** - * The Video Game Object Complete Event. - * - * This event is dispatched when a Video finishes playback by reaching the end of its duration. It - * is also dispatched if a video marker sequence is being played and reaches the end. - * - * Note that not all videos can fire this event. Live streams, for example, have no fixed duration, - * so never technically 'complete'. - * - * If a video is stopped from playback, via the `Video.stop` method, it will emit the - * `VIDEO_STOP` event instead of this one. - * - * Listen for it from a Video Game Object instance using `Video.on('complete', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_COMPLETE - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which completed playback. - */ -module.exports = 'complete'; + // map segment to x and y + switch (segType) { + + case 'M': + case 'L': + case 'T': + case 'C': + case 'S': + case 'Q': + x = segment.x; + y = segment.y; + break; + case 'H': + x = segment.x; + break; + case 'V': + y = segment.y; + break; + } + addPoint(x, y, segment.pathSegType); + }; -/***/ }), -/* 647 */ -/***/ (function(module, exports) { + // ensure path is absolute + Svg._svgPathToAbsolute(path); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // get total length + total = path.getTotalLength(); -/** - * The Video Game Object Created Event. - * - * This event is dispatched when the texture for a Video has been created. This happens - * when enough of the video source has been loaded that the browser is able to render a - * frame from it. - * - * Listen for it from a Video Game Object instance using `Video.on('created', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_CREATED - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event. - * @param {number} width - The width of the video. - * @param {number} height - The height of the video. - */ -module.exports = 'created'; + // queue segments + segments = []; + for (i = 0; i < path.pathSegList.numberOfItems; i += 1) + segments.push(path.pathSegList.getItem(i)); + segmentsQueue = segments.concat(); -/***/ }), -/* 648 */ -/***/ (function(module, exports) { + // sample through path + while (length < total) { + // get segment at position + segmentIndex = path.getPathSegAtLength(length); + segment = segments[segmentIndex]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // new segment + if (segment != lastSegment) { + while (segmentsQueue.length && segmentsQueue[0] != segment) + addSegmentPoint(segmentsQueue.shift()); -/** - * The Video Game Object Error Event. - * - * This event is dispatched when a Video tries to play a source that does not exist, or is the wrong file type. - * - * Listen for it from a Video Game Object instance using `Video.on('error', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_ERROR - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which threw the error. - * @param {Event} event - The native DOM event the browser raised during playback. - */ -module.exports = 'error'; + lastSegment = segment; + } + // add points in between when curving + // TODO: adaptive sampling + switch (segment.pathSegTypeAsLetter.toUpperCase()) { -/***/ }), -/* 649 */ -/***/ (function(module, exports) { + case 'C': + case 'T': + case 'S': + case 'Q': + case 'A': + point = path.getPointAtLength(length); + addPoint(point.x, point.y, 0); + break; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + } -/** - * The Video Game Object Loop Event. - * - * This event is dispatched when a Video that is currently playing has looped. This only - * happens if the `loop` parameter was specified, or the `setLoop` method was called, - * and if the video has a fixed duration. Video streams, for example, cannot loop, as - * they have no duration. - * - * Looping is based on the result of the Video `timeupdate` event. This event is not - * frame-accurate, due to the way browsers work, so please do not rely on this loop - * event to be time or frame precise. - * - * Listen for it from a Video Game Object instance using `Video.on('loop', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_LOOP - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which has looped. - */ -module.exports = 'loop'; + // increment by sample value + length += sampleLength; + } + // add remaining segments not passed by sampling + for (i = 0, il = segmentsQueue.length; i < il; ++i) + addSegmentPoint(segmentsQueue[i]); -/***/ }), -/* 650 */ -/***/ (function(module, exports) { + return points; + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + Svg._svgPathToAbsolute = function(path) { + // http://phrogz.net/convert-svg-path-to-all-absolute-commands + // Copyright (c) Gavin Kistner + // http://phrogz.net/js/_ReuseLicense.txt + // Modifications: tidy formatting and naming + var x0, y0, x1, y1, x2, y2, segs = path.pathSegList, + x = 0, y = 0, len = segs.numberOfItems; -/** - * The Video Game Object Play Event. - * - * This event is dispatched when a Video begins playback. For videos that do not require - * interaction unlocking, this is usually as soon as the `Video.play` method is called. - * However, for videos that require unlocking, it is fired once playback begins after - * they've been unlocked. - * - * Listen for it from a Video Game Object instance using `Video.on('play', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_PLAY - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which started playback. - */ -module.exports = 'play'; + for (var i = 0; i < len; ++i) { + var seg = segs.getItem(i), + segType = seg.pathSegTypeAsLetter; + if (/[MLHVCSQTA]/.test(segType)) { + if ('x' in seg) x = seg.x; + if ('y' in seg) y = seg.y; + } else { + if ('x1' in seg) x1 = x + seg.x1; + if ('x2' in seg) x2 = x + seg.x2; + if ('y1' in seg) y1 = y + seg.y1; + if ('y2' in seg) y2 = y + seg.y2; + if ('x' in seg) x += seg.x; + if ('y' in seg) y += seg.y; -/***/ }), -/* 651 */ -/***/ (function(module, exports) { + switch (segType) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + case 'm': + segs.replaceItem(path.createSVGPathSegMovetoAbs(x, y), i); + break; + case 'l': + segs.replaceItem(path.createSVGPathSegLinetoAbs(x, y), i); + break; + case 'h': + segs.replaceItem(path.createSVGPathSegLinetoHorizontalAbs(x), i); + break; + case 'v': + segs.replaceItem(path.createSVGPathSegLinetoVerticalAbs(y), i); + break; + case 'c': + segs.replaceItem(path.createSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2), i); + break; + case 's': + segs.replaceItem(path.createSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2), i); + break; + case 'q': + segs.replaceItem(path.createSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1), i); + break; + case 't': + segs.replaceItem(path.createSVGPathSegCurvetoQuadraticSmoothAbs(x, y), i); + break; + case 'a': + segs.replaceItem(path.createSVGPathSegArcAbs(x, y, seg.r1, seg.r2, seg.angle, seg.largeArcFlag, seg.sweepFlag), i); + break; + case 'z': + case 'Z': + x = x0; + y = y0; + break; -/** - * The Video Game Object Seeked Event. - * - * This event is dispatched when a Video completes seeking to a new point in its timeline. - * - * Listen for it from a Video Game Object instance using `Video.on('seeked', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_SEEKED - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which completed seeking. - */ -module.exports = 'seeked'; + } + } + + if (segType == 'M' || segType == 'm') { + x0 = x; + y0 = y; + } + } + }; +})(); /***/ }), -/* 652 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 10438: +/***/ ((module) => { /** - * The Video Game Object Seeking Event. - * - * This event is dispatched when a Video _begins_ seeking to a new point in its timeline. - * When the seek is complete, it will dispatch the `VIDEO_SEEKED` event to conclude. - * - * Listen for it from a Video Game Object instance using `Video.on('seeking', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_SEEKING - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which started seeking. - */ -module.exports = 'seeking'; +* The `Matter.Vector` module contains methods for creating and manipulating vectors. +* Vectors are the basis of all the geometry related operations in the engine. +* A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`. +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Vector +*/ +// TODO: consider params for reusing vector objects -/***/ }), -/* 653 */ -/***/ (function(module, exports) { +var Vector = {}; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +module.exports = Vector; -/** - * The Video Game Object Stopped Event. - * - * This event is dispatched when a Video is stopped from playback via a call to the `Video.stop` method, - * either directly via game code, or indirectly as the result of changing a video source or destroying it. - * - * Listen for it from a Video Game Object instance using `Video.on('stop', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_STOP - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which stopped playback. - */ -module.exports = 'stop'; +(function() { + /** + * Creates a new vector. + * @method create + * @param {number} x + * @param {number} y + * @return {vector} A new vector + */ + Vector.create = function(x, y) { + return { x: x || 0, y: y || 0 }; + }; -/***/ }), -/* 654 */ -/***/ (function(module, exports) { + /** + * Returns a new vector with `x` and `y` copied from the given `vector`. + * @method clone + * @param {vector} vector + * @return {vector} A new cloned vector + */ + Vector.clone = function(vector) { + return { x: vector.x, y: vector.y }; + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Returns the magnitude (length) of a vector. + * @method magnitude + * @param {vector} vector + * @return {number} The magnitude of the vector + */ + Vector.magnitude = function(vector) { + return Math.sqrt((vector.x * vector.x) + (vector.y * vector.y)); + }; -/** - * The Video Game Object Timeout Event. - * - * This event is dispatched when a Video has exhausted its allocated time while trying to connect to a video - * source to start playback. - * - * Listen for it from a Video Game Object instance using `Video.on('timeout', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_TIMEOUT - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which timed out. - */ -module.exports = 'timeout'; + /** + * Returns the magnitude (length) of a vector (therefore saving a `sqrt` operation). + * @method magnitudeSquared + * @param {vector} vector + * @return {number} The squared magnitude of the vector + */ + Vector.magnitudeSquared = function(vector) { + return (vector.x * vector.x) + (vector.y * vector.y); + }; + /** + * Rotates the vector about (0, 0) by specified angle. + * @method rotate + * @param {vector} vector + * @param {number} angle + * @param {vector} [output] + * @return {vector} The vector rotated about (0, 0) + */ + Vector.rotate = function(vector, angle, output) { + var cos = Math.cos(angle), sin = Math.sin(angle); + if (!output) output = {}; + var x = vector.x * cos - vector.y * sin; + output.y = vector.x * sin + vector.y * cos; + output.x = x; + return output; + }; -/***/ }), -/* 655 */ -/***/ (function(module, exports) { + /** + * Rotates the vector about a specified point by specified angle. + * @method rotateAbout + * @param {vector} vector + * @param {number} angle + * @param {vector} point + * @param {vector} [output] + * @return {vector} A new vector rotated about the point + */ + Vector.rotateAbout = function(vector, angle, point, output) { + var cos = Math.cos(angle), sin = Math.sin(angle); + if (!output) output = {}; + var x = point.x + ((vector.x - point.x) * cos - (vector.y - point.y) * sin); + output.y = point.y + ((vector.x - point.x) * sin + (vector.y - point.y) * cos); + output.x = x; + return output; + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Normalises a vector (such that its magnitude is `1`). + * @method normalise + * @param {vector} vector + * @return {vector} A new vector normalised + */ + Vector.normalise = function(vector) { + var magnitude = Vector.magnitude(vector); + if (magnitude === 0) + return { x: 0, y: 0 }; + return { x: vector.x / magnitude, y: vector.y / magnitude }; + }; -/** - * The Video Game Object Unlocked Event. - * - * This event is dispatched when a Video that was prevented from playback due to the browsers - * Media Engagement Interaction policy, is unlocked by a user gesture. - * - * Listen for it from a Video Game Object instance using `Video.on('unlocked', listener)`. - * - * @event Phaser.GameObjects.Events#VIDEO_UNLOCKED - * @since 3.20.0 - * - * @param {Phaser.GameObjects.Video} video - The Video Game Object which raised the event. - */ -module.exports = 'unlocked'; + /** + * Returns the dot-product of two vectors. + * @method dot + * @param {vector} vectorA + * @param {vector} vectorB + * @return {number} The dot product of the two vectors + */ + Vector.dot = function(vectorA, vectorB) { + return (vectorA.x * vectorB.x) + (vectorA.y * vectorB.y); + }; + /** + * Returns the cross-product of two vectors. + * @method cross + * @param {vector} vectorA + * @param {vector} vectorB + * @return {number} The cross product of the two vectors + */ + Vector.cross = function(vectorA, vectorB) { + return (vectorA.x * vectorB.y) - (vectorA.y * vectorB.x); + }; -/***/ }), -/* 656 */ -/***/ (function(module, exports) { + /** + * Returns the cross-product of three vectors. + * @method cross3 + * @param {vector} vectorA + * @param {vector} vectorB + * @param {vector} vectorC + * @return {number} The cross product of the three vectors + */ + Vector.cross3 = function(vectorA, vectorB, vectorC) { + return (vectorB.x - vectorA.x) * (vectorC.y - vectorA.y) - (vectorB.y - vectorA.y) * (vectorC.x - vectorA.x); + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Adds the two vectors. + * @method add + * @param {vector} vectorA + * @param {vector} vectorB + * @param {vector} [output] + * @return {vector} A new vector of vectorA and vectorB added + */ + Vector.add = function(vectorA, vectorB, output) { + if (!output) output = {}; + output.x = vectorA.x + vectorB.x; + output.y = vectorA.y + vectorB.y; + return output; + }; -/** - * The Game Object Added to Scene Event. - * - * This event is dispatched when a Game Object is added to a Scene. - * - * Listen for it from a Scene using `this.events.on('addedtoscene', listener)`. - * - * @event Phaser.Scenes.Events#ADDED_TO_SCENE - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the Scene. - * @param {Phaser.Scene} scene - The Scene to which the Game Object was added. - */ -module.exports = 'addedtoscene'; + /** + * Subtracts the two vectors. + * @method sub + * @param {vector} vectorA + * @param {vector} vectorB + * @param {vector} [output] + * @return {vector} A new vector of vectorA and vectorB subtracted + */ + Vector.sub = function(vectorA, vectorB, output) { + if (!output) output = {}; + output.x = vectorA.x - vectorB.x; + output.y = vectorA.y - vectorB.y; + return output; + }; + /** + * Multiplies a vector and a scalar. + * @method mult + * @param {vector} vector + * @param {number} scalar + * @return {vector} A new vector multiplied by scalar + */ + Vector.mult = function(vector, scalar) { + return { x: vector.x * scalar, y: vector.y * scalar }; + }; -/***/ }), -/* 657 */ -/***/ (function(module, exports) { + /** + * Divides a vector and a scalar. + * @method div + * @param {vector} vector + * @param {number} scalar + * @return {vector} A new vector divided by scalar + */ + Vector.div = function(vector, scalar) { + return { x: vector.x / scalar, y: vector.y / scalar }; + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Returns the perpendicular vector. Set `negate` to true for the perpendicular in the opposite direction. + * @method perp + * @param {vector} vector + * @param {bool} [negate=false] + * @return {vector} The perpendicular vector + */ + Vector.perp = function(vector, negate) { + negate = negate === true ? -1 : 1; + return { x: negate * -vector.y, y: negate * vector.x }; + }; -/** - * The Scene Systems Boot Event. - * - * This event is dispatched by a Scene during the Scene Systems boot process. Primarily used by Scene Plugins. - * - * Listen to it from a Scene using `this.events.on('boot', listener)`. - * - * @event Phaser.Scenes.Events#BOOT - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - */ -module.exports = 'boot'; + /** + * Negates both components of a vector such that it points in the opposite direction. + * @method neg + * @param {vector} vector + * @return {vector} The negated vector + */ + Vector.neg = function(vector) { + return { x: -vector.x, y: -vector.y }; + }; + + /** + * Returns the angle between the vector `vectorB - vectorA` and the x-axis in radians. + * @method angle + * @param {vector} vectorA + * @param {vector} vectorB + * @return {number} The angle in radians + */ + Vector.angle = function(vectorA, vectorB) { + return Math.atan2(vectorB.y - vectorA.y, vectorB.x - vectorA.x); + }; + + /** + * Temporary vector pool (not thread-safe). + * @property _temp + * @type {vector[]} + * @private + */ + Vector._temp = [ + Vector.create(), Vector.create(), + Vector.create(), Vector.create(), + Vector.create(), Vector.create() + ]; +})(); /***/ }), -/* 658 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 39745: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * The Scene Create Event. - * - * This event is dispatched by a Scene after it has been created by the Scene Manager. - * - * If a Scene has a `create` method then this event is emitted _after_ that has run. - * - * If there is a transition, this event will be fired after the `TRANSITION_START` event. - * - * Listen to it from a Scene using `this.events.on('create', listener)`. - * - * @event Phaser.Scenes.Events#CREATE - * @since 3.17.0 - * - * @param {Phaser.Scene} scene - A reference to the Scene that emitted this event. - */ -module.exports = 'create'; +* The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices. +* A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`. +* A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull). +* +* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). +* +* @class Vertices +*/ +var Vertices = {}; -/***/ }), -/* 659 */ -/***/ (function(module, exports) { +module.exports = Vertices; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +var Vector = __webpack_require__(10438); +var Common = __webpack_require__(68758); -/** - * The Scene Systems Destroy Event. - * - * This event is dispatched by a Scene during the Scene Systems destroy process. - * - * Listen to it from a Scene using `this.events.on('destroy', listener)`. - * - * You should destroy any resources that may be in use by your Scene in this event handler. - * - * @event Phaser.Scenes.Events#DESTROY - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - */ -module.exports = 'destroy'; +(function() { + /** + * Creates a new set of `Matter.Body` compatible vertices. + * The `points` argument accepts an array of `Matter.Vector` points orientated around the origin `(0, 0)`, for example: + * + * [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }] + * + * The `Vertices.create` method returns a new array of vertices, which are similar to Matter.Vector objects, + * but with some additional references required for efficient collision detection routines. + * + * Vertices must be specified in clockwise order. + * + * Note that the `body` argument is not optional, a `Matter.Body` reference must be provided. + * + * @method create + * @param {vector[]} points + * @param {body} body + */ + Vertices.create = function(points, body) { + var vertices = []; -/***/ }), -/* 660 */ -/***/ (function(module, exports) { + for (var i = 0; i < points.length; i++) { + var point = points[i], + vertex = { + x: point.x, + y: point.y, + index: i, + body: body, + isInternal: false + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + vertices.push(vertex); + } -/** - * The Scene Systems Pause Event. - * - * This event is dispatched by a Scene when it is paused, either directly via the `pause` method, or as an - * action from another Scene. - * - * Listen to it from a Scene using `this.events.on('pause', listener)`. - * - * @event Phaser.Scenes.Events#PAUSE - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - * @param {any} [data] - An optional data object that was passed to this Scene when it was paused. - */ -module.exports = 'pause'; + return vertices; + }; + /** + * Parses a string containing ordered x y pairs separated by spaces (and optionally commas), + * into a `Matter.Vertices` object for the given `Matter.Body`. + * For parsing SVG paths, see `Svg.pathToVertices`. + * @method fromPath + * @param {string} path + * @param {body} body + * @return {vertices} vertices + */ + Vertices.fromPath = function(path, body) { + var pathPattern = /L?\s*([-\d.e]+)[\s,]*([-\d.e]+)*/ig, + points = []; -/***/ }), -/* 661 */ -/***/ (function(module, exports) { + path.replace(pathPattern, function(match, x, y) { + points.push({ x: parseFloat(x), y: parseFloat(y) }); + }); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return Vertices.create(points, body); + }; -/** - * The Scene Systems Post Update Event. - * - * This event is dispatched by a Scene during the main game loop step. - * - * The event flow for a single step of a Scene is as follows: - * - * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} - * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} - * 3. The `Scene.update` method is called, if it exists - * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} - * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} - * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} - * - * Listen to it from a Scene using `this.events.on('postupdate', listener)`. - * - * A Scene will only run its step if it is active. - * - * @event Phaser.Scenes.Events#POST_UPDATE - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. - */ -module.exports = 'postupdate'; + /** + * Returns the centre (centroid) of the set of vertices. + * @method centre + * @param {vertices} vertices + * @return {vector} The centre point + */ + Vertices.centre = function(vertices) { + var area = Vertices.area(vertices, true), + centre = { x: 0, y: 0 }, + cross, + temp, + j; + for (var i = 0; i < vertices.length; i++) { + j = (i + 1) % vertices.length; + cross = Vector.cross(vertices[i], vertices[j]); + temp = Vector.mult(Vector.add(vertices[i], vertices[j]), cross); + centre = Vector.add(centre, temp); + } -/***/ }), -/* 662 */ -/***/ (function(module, exports) { + return Vector.div(centre, 6 * area); + }; -/** - * @author samme - * @copyright 2021 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Returns the average (mean) of the set of vertices. + * @method mean + * @param {vertices} vertices + * @return {vector} The average point + */ + Vertices.mean = function(vertices) { + var average = { x: 0, y: 0 }; -/** - * The Scene Systems Pre-Render Event. - * - * This event is dispatched by a Scene during the main game loop step. - * - * The event flow for a single step of a Scene is as follows: - * - * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} - * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} - * 3. The `Scene.update` method is called, if it exists - * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} - * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} - * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} - * - * Listen to this event from a Scene using `this.events.on('prerender', listener)`. - * - * A Scene will only render if it is visible. - * - * This event is dispatched after the Scene Display List is sorted and before the Scene is rendered. - * - * @event Phaser.Scenes.Events#PRE_RENDER - * @since 3.53.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that rendered the Scene. - */ -module.exports = 'prerender'; + for (var i = 0; i < vertices.length; i++) { + average.x += vertices[i].x; + average.y += vertices[i].y; + } + return Vector.div(average, vertices.length); + }; -/***/ }), -/* 663 */ -/***/ (function(module, exports) { + /** + * Returns the area of the set of vertices. + * @method area + * @param {vertices} vertices + * @param {bool} signed + * @return {number} The area + */ + Vertices.area = function(vertices, signed) { + var area = 0, + j = vertices.length - 1; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + for (var i = 0; i < vertices.length; i++) { + area += (vertices[j].x - vertices[i].x) * (vertices[j].y + vertices[i].y); + j = i; + } -/** - * The Scene Systems Pre Update Event. - * - * This event is dispatched by a Scene during the main game loop step. - * - * The event flow for a single step of a Scene is as follows: - * - * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} - * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} - * 3. The `Scene.update` method is called, if it exists - * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} - * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} - * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} - * - * Listen to it from a Scene using `this.events.on('preupdate', listener)`. - * - * A Scene will only run its step if it is active. - * - * @event Phaser.Scenes.Events#PRE_UPDATE - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. - */ -module.exports = 'preupdate'; + if (signed) + return area / 2; + return Math.abs(area) / 2; + }; -/***/ }), -/* 664 */ -/***/ (function(module, exports) { + /** + * Returns the moment of inertia (second moment of area) of the set of vertices given the total mass. + * @method inertia + * @param {vertices} vertices + * @param {number} mass + * @return {number} The polygon's moment of inertia + */ + Vertices.inertia = function(vertices, mass) { + var numerator = 0, + denominator = 0, + v = vertices, + cross, + j; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // find the polygon's moment of inertia, using second moment of area + // from equations at http://www.physicsforums.com/showthread.php?t=25293 + for (var n = 0; n < v.length; n++) { + j = (n + 1) % v.length; + cross = Math.abs(Vector.cross(v[j], v[n])); + numerator += cross * (Vector.dot(v[j], v[j]) + Vector.dot(v[j], v[n]) + Vector.dot(v[n], v[n])); + denominator += cross; + } -/** - * The Scene Systems Ready Event. - * - * This event is dispatched by a Scene during the Scene Systems start process. - * By this point in the process the Scene is now fully active and rendering. - * This event is meant for your game code to use, as all plugins have responded to the earlier 'start' event. - * - * Listen to it from a Scene using `this.events.on('ready', listener)`. - * - * @event Phaser.Scenes.Events#READY - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - * @param {any} [data] - An optional data object that was passed to this Scene when it was started. - */ -module.exports = 'ready'; + return (mass / 6) * (numerator / denominator); + }; + /** + * Translates the set of vertices in-place. + * @method translate + * @param {vertices} vertices + * @param {vector} vector + * @param {number} scalar + */ + Vertices.translate = function(vertices, vector, scalar) { + scalar = typeof scalar !== 'undefined' ? scalar : 1; -/***/ }), -/* 665 */ -/***/ (function(module, exports) { + var verticesLength = vertices.length, + translateX = vector.x * scalar, + translateY = vector.y * scalar, + i; + + for (i = 0; i < verticesLength; i++) { + vertices[i].x += translateX; + vertices[i].y += translateY; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return vertices; + }; -/** - * The Game Object Removed from Scene Event. - * - * This event is dispatched when a Game Object is removed from a Scene. - * - * Listen for it from a Scene using `this.events.on('removedfromscene', listener)`. - * - * @event Phaser.Scenes.Events#REMOVED_FROM_SCENE - * @since 3.50.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the Scene. - * @param {Phaser.Scene} scene - The Scene from which the Game Object was removed. - */ -module.exports = 'removedfromscene'; + /** + * Rotates the set of vertices in-place. + * @method rotate + * @param {vertices} vertices + * @param {number} angle + * @param {vector} point + */ + Vertices.rotate = function(vertices, angle, point) { + if (angle === 0) + return; + var cos = Math.cos(angle), + sin = Math.sin(angle), + pointX = point.x, + pointY = point.y, + verticesLength = vertices.length, + vertex, + dx, + dy, + i; -/***/ }), -/* 666 */ -/***/ (function(module, exports) { + for (i = 0; i < verticesLength; i++) { + vertex = vertices[i]; + dx = vertex.x - pointX; + dy = vertex.y - pointY; + vertex.x = pointX + (dx * cos - dy * sin); + vertex.y = pointY + (dx * sin + dy * cos); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return vertices; + }; -/** - * The Scene Systems Render Event. - * - * This event is dispatched by a Scene during the main game loop step. - * - * The event flow for a single step of a Scene is as follows: - * - * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} - * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} - * 3. The `Scene.update` method is called, if it exists - * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} - * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} - * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} - * - * Listen to it from a Scene using `this.events.on('render', listener)`. - * - * A Scene will only render if it is visible. - * - * By the time this event is dispatched, the Scene will have already been rendered. - * - * @event Phaser.Scenes.Events#RENDER - * @since 3.0.0 - * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that rendered the Scene. - */ -module.exports = 'render'; + /** + * Returns `true` if the `point` is inside the set of `vertices`. + * @method contains + * @param {vertices} vertices + * @param {vector} point + * @return {boolean} True if the vertices contains point, otherwise false + */ + Vertices.contains = function(vertices, point) { + var pointX = point.x, + pointY = point.y, + verticesLength = vertices.length, + vertex = vertices[verticesLength - 1], + nextVertex; + for (var i = 0; i < verticesLength; i++) { + nextVertex = vertices[i]; -/***/ }), -/* 667 */ -/***/ (function(module, exports) { + if ((pointX - vertex.x) * (nextVertex.y - vertex.y) + + (pointY - vertex.y) * (vertex.x - nextVertex.x) > 0) { + return false; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + vertex = nextVertex; + } -/** - * The Scene Systems Resume Event. - * - * This event is dispatched by a Scene when it is resumed from a paused state, either directly via the `resume` method, - * or as an action from another Scene. - * - * Listen to it from a Scene using `this.events.on('resume', listener)`. - * - * @event Phaser.Scenes.Events#RESUME - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - * @param {any} [data] - An optional data object that was passed to this Scene when it was resumed. - */ -module.exports = 'resume'; + return true; + }; + /** + * Scales the vertices from a point (default is centre) in-place. + * @method scale + * @param {vertices} vertices + * @param {number} scaleX + * @param {number} scaleY + * @param {vector} point + */ + Vertices.scale = function(vertices, scaleX, scaleY, point) { + if (scaleX === 1 && scaleY === 1) + return vertices; -/***/ }), -/* 668 */ -/***/ (function(module, exports) { + point = point || Vertices.centre(vertices); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var vertex, + delta; -/** - * The Scene Systems Shutdown Event. - * - * This event is dispatched by a Scene during the Scene Systems shutdown process. - * - * Listen to it from a Scene using `this.events.on('shutdown', listener)`. - * - * You should free-up any resources that may be in use by your Scene in this event handler, on the understanding - * that the Scene may, at any time, become active again. A shutdown Scene is not 'destroyed', it's simply not - * currently active. Use the [DESTROY]{@linkcode Phaser.Scenes.Events#event:DESTROY} event to completely clear resources. - * - * @event Phaser.Scenes.Events#SHUTDOWN - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - * @param {any} [data] - An optional data object that was passed to this Scene when it was shutdown. - */ -module.exports = 'shutdown'; + for (var i = 0; i < vertices.length; i++) { + vertex = vertices[i]; + delta = Vector.sub(vertex, point); + vertices[i].x = point.x + delta.x * scaleX; + vertices[i].y = point.y + delta.y * scaleY; + } + + return vertices; + }; + + /** + * Chamfers a set of vertices by giving them rounded corners, returns a new set of vertices. + * The radius parameter is a single number or an array to specify the radius for each vertex. + * @method chamfer + * @param {vertices} vertices + * @param {number[]} radius + * @param {number} quality + * @param {number} qualityMin + * @param {number} qualityMax + */ + Vertices.chamfer = function(vertices, radius, quality, qualityMin, qualityMax) { + if (typeof radius === 'number') { + radius = [radius]; + } else { + radius = radius || [8]; + } + // quality defaults to -1, which is auto + quality = (typeof quality !== 'undefined') ? quality : -1; + qualityMin = qualityMin || 2; + qualityMax = qualityMax || 14; -/***/ }), -/* 669 */ -/***/ (function(module, exports) { + var newVertices = []; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + for (var i = 0; i < vertices.length; i++) { + var prevVertex = vertices[i - 1 >= 0 ? i - 1 : vertices.length - 1], + vertex = vertices[i], + nextVertex = vertices[(i + 1) % vertices.length], + currentRadius = radius[i < radius.length ? i : radius.length - 1]; -/** - * The Scene Systems Sleep Event. - * - * This event is dispatched by a Scene when it is sent to sleep, either directly via the `sleep` method, - * or as an action from another Scene. - * - * Listen to it from a Scene using `this.events.on('sleep', listener)`. - * - * @event Phaser.Scenes.Events#SLEEP - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - * @param {any} [data] - An optional data object that was passed to this Scene when it was sent to sleep. - */ -module.exports = 'sleep'; + if (currentRadius === 0) { + newVertices.push(vertex); + continue; + } + var prevNormal = Vector.normalise({ + x: vertex.y - prevVertex.y, + y: prevVertex.x - vertex.x + }); -/***/ }), -/* 670 */ -/***/ (function(module, exports) { + var nextNormal = Vector.normalise({ + x: nextVertex.y - vertex.y, + y: vertex.x - nextVertex.x + }); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var diagonalRadius = Math.sqrt(2 * Math.pow(currentRadius, 2)), + radiusVector = Vector.mult(Common.clone(prevNormal), currentRadius), + midNormal = Vector.normalise(Vector.mult(Vector.add(prevNormal, nextNormal), 0.5)), + scaledVertex = Vector.sub(vertex, Vector.mult(midNormal, diagonalRadius)); -/** - * The Scene Systems Start Event. - * - * This event is dispatched by a Scene during the Scene Systems start process. Primarily used by Scene Plugins. - * - * Listen to it from a Scene using `this.events.on('start', listener)`. - * - * @event Phaser.Scenes.Events#START - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - */ -module.exports = 'start'; + var precision = quality; + if (quality === -1) { + // automatically decide precision + precision = Math.pow(currentRadius, 0.32) * 1.75; + } -/***/ }), -/* 671 */ -/***/ (function(module, exports) { + precision = Common.clamp(precision, qualityMin, qualityMax); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // use an even value for precision, more likely to reduce axes by using symmetry + if (precision % 2 === 1) + precision += 1; -/** - * The Scene Transition Complete Event. - * - * This event is dispatched by the Target Scene of a transition. - * - * It happens when the transition process has completed. This occurs when the duration timer equals or exceeds the duration - * of the transition. - * - * Listen to it from a Scene using `this.events.on('transitioncomplete', listener)`. - * - * The Scene Transition event flow is as follows: - * - * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. - * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. - * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... - * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. - * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. - * - * @event Phaser.Scenes.Events#TRANSITION_COMPLETE - * @since 3.5.0 - * - * @param {Phaser.Scene} scene -The Scene on which the transitioned completed. - */ -module.exports = 'transitioncomplete'; + var alpha = Math.acos(Vector.dot(prevNormal, nextNormal)), + theta = alpha / precision; + for (var j = 0; j < precision; j++) { + newVertices.push(Vector.add(Vector.rotate(radiusVector, theta * j), scaledVertex)); + } + } -/***/ }), -/* 672 */ -/***/ (function(module, exports) { + return newVertices; + }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Sorts the input vertices into clockwise order in place. + * @method clockwiseSort + * @param {vertices} vertices + * @return {vertices} vertices + */ + Vertices.clockwiseSort = function(vertices) { + var centre = Vertices.mean(vertices); -/** - * The Scene Transition Init Event. - * - * This event is dispatched by the Target Scene of a transition. - * - * It happens immediately after the `Scene.init` method is called. If the Scene does not have an `init` method, - * this event is not dispatched. - * - * Listen to it from a Scene using `this.events.on('transitioninit', listener)`. - * - * The Scene Transition event flow is as follows: - * - * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. - * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. - * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... - * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. - * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. - * - * @event Phaser.Scenes.Events#TRANSITION_INIT - * @since 3.5.0 - * - * @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from. - * @param {number} duration - The duration of the transition in ms. - */ -module.exports = 'transitioninit'; + vertices.sort(function(vertexA, vertexB) { + return Vector.angle(centre, vertexA) - Vector.angle(centre, vertexB); + }); + return vertices; + }; -/***/ }), -/* 673 */ -/***/ (function(module, exports) { + /** + * Returns true if the vertices form a convex shape (vertices must be in clockwise order). + * @method isConvex + * @param {vertices} vertices + * @return {bool} `true` if the `vertices` are convex, `false` if not (or `null` if not computable). + */ + Vertices.isConvex = function(vertices) { + // http://paulbourke.net/geometry/polygonmesh/ + // Copyright (c) Paul Bourke (use permitted) -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var flag = 0, + n = vertices.length, + i, + j, + k, + z; -/** - * The Scene Transition Out Event. - * - * This event is dispatched by a Scene when it initiates a transition to another Scene. - * - * Listen to it from a Scene using `this.events.on('transitionout', listener)`. - * - * The Scene Transition event flow is as follows: - * - * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. - * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. - * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... - * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. - * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. - * - * @event Phaser.Scenes.Events#TRANSITION_OUT - * @since 3.5.0 - * - * @param {Phaser.Scene} target - A reference to the Scene that is being transitioned to. - * @param {number} duration - The duration of the transition in ms. - */ -module.exports = 'transitionout'; + if (n < 3) + return null; + for (i = 0; i < n; i++) { + j = (i + 1) % n; + k = (i + 2) % n; + z = (vertices[j].x - vertices[i].x) * (vertices[k].y - vertices[j].y); + z -= (vertices[j].y - vertices[i].y) * (vertices[k].x - vertices[j].x); -/***/ }), -/* 674 */ -/***/ (function(module, exports) { + if (z < 0) { + flag |= 1; + } else if (z > 0) { + flag |= 2; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (flag === 3) { + return false; + } + } -/** - * The Scene Transition Start Event. - * - * This event is dispatched by the Target Scene of a transition, only if that Scene was not asleep. - * - * It happens immediately after the `Scene.create` method is called. If the Scene does not have a `create` method, - * this event is dispatched anyway. - * - * If the Target Scene was sleeping then the [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} event is - * dispatched instead of this event. - * - * Listen to it from a Scene using `this.events.on('transitionstart', listener)`. - * - * The Scene Transition event flow is as follows: - * - * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. - * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. - * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... - * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. - * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. - * - * @event Phaser.Scenes.Events#TRANSITION_START - * @since 3.5.0 - * - * @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from. - * @param {number} duration - The duration of the transition in ms. - */ -module.exports = 'transitionstart'; + if (flag !== 0){ + return true; + } else { + return null; + } + }; + /** + * Returns the convex hull of the input vertices as a new array of points. + * @method hull + * @param {vertices} vertices + * @return [vertex] vertices + */ + Vertices.hull = function(vertices) { + // http://geomalgorithms.com/a10-_hull-1.html -/***/ }), -/* 675 */ -/***/ (function(module, exports) { + var upper = [], + lower = [], + vertex, + i; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // sort vertices on x-axis (y-axis for ties) + vertices = vertices.slice(0); + vertices.sort(function(vertexA, vertexB) { + var dx = vertexA.x - vertexB.x; + return dx !== 0 ? dx : vertexA.y - vertexB.y; + }); -/** - * The Scene Transition Wake Event. - * - * This event is dispatched by the Target Scene of a transition, only if that Scene was asleep before - * the transition began. If the Scene was not asleep the [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} event is dispatched instead. - * - * Listen to it from a Scene using `this.events.on('transitionwake', listener)`. - * - * The Scene Transition event flow is as follows: - * - * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. - * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. - * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... - * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. - * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. - * - * @event Phaser.Scenes.Events#TRANSITION_WAKE - * @since 3.5.0 - * - * @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from. - * @param {number} duration - The duration of the transition in ms. - */ -module.exports = 'transitionwake'; + // build lower hull + for (i = 0; i < vertices.length; i += 1) { + vertex = vertices[i]; + while (lower.length >= 2 + && Vector.cross3(lower[lower.length - 2], lower[lower.length - 1], vertex) <= 0) { + lower.pop(); + } -/***/ }), -/* 676 */ -/***/ (function(module, exports) { + lower.push(vertex); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // build upper hull + for (i = vertices.length - 1; i >= 0; i -= 1) { + vertex = vertices[i]; -/** - * The Scene Systems Update Event. - * - * This event is dispatched by a Scene during the main game loop step. - * - * The event flow for a single step of a Scene is as follows: - * - * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} - * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} - * 3. The `Scene.update` method is called, if it exists - * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} - * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} - * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} - * - * Listen to it from a Scene using `this.events.on('update', listener)`. - * - * A Scene will only run its step if it is active. - * - * @event Phaser.Scenes.Events#UPDATE - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. - */ -module.exports = 'update'; + while (upper.length >= 2 + && Vector.cross3(upper[upper.length - 2], upper[upper.length - 1], vertex) <= 0) { + upper.pop(); + } + upper.push(vertex); + } -/***/ }), -/* 677 */ -/***/ (function(module, exports) { + // concatenation of the lower and upper hulls gives the convex hull + // omit last points because they are repeated at the beginning of the other list + upper.pop(); + lower.pop(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return upper.concat(lower); + }; -/** - * The Scene Systems Wake Event. - * - * This event is dispatched by a Scene when it is woken from sleep, either directly via the `wake` method, - * or as an action from another Scene. - * - * Listen to it from a Scene using `this.events.on('wake', listener)`. - * - * @event Phaser.Scenes.Events#WAKE - * @since 3.0.0 - * - * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. - * @param {any} [data] - An optional data object that was passed to this Scene when it was woken up. - */ -module.exports = 'wake'; +})(); /***/ }), -/* 678 */ -/***/ (function(module, exports, __webpack_require__) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 1675: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var PropertyValueInc = __webpack_require__(46); +var Matter = __webpack_require__(18171); /** - * Takes an array of Game Objects, or any objects that have a public `alpha` property, - * and then adds the given value to each of their `alpha` properties. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `IncAlpha(group.getChildren(), value, step)` - * - * @function Phaser.Actions.IncAlpha - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to be added to the `alpha` property. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * An attractors plugin for matter.js. + * See the readme for usage and examples. + * @module MatterAttractors */ -var IncAlpha = function (items, value, step, index, direction) +var MatterAttractors = { - return PropertyValueInc(items, 'alpha', value, step, index, direction); -}; - -module.exports = IncAlpha; - + name: 'matter-attractors', + version: '0.1.7', + for: 'matter-js@^0.19.0', + silent: true, -/***/ }), -/* 679 */ -/***/ (function(module, exports, __webpack_require__) { + // installs the plugin where `base` is `Matter` + // you should not need to call this directly. + install: function (base) + { + base.after('Body.create', function () + { + MatterAttractors.Body.init(this); + }); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + base.before('Engine.update', function (engine) + { + MatterAttractors.Engine.update(engine); + }); + }, -var PropertyValueInc = __webpack_require__(46); + Body: + { + /** + * Initialises the `body` to support attractors. + * This is called automatically by the plugin. + * @function MatterAttractors.Body.init + * @param {Matter.Body} body The body to init. + * @returns {void} No return value. + */ + init: function (body) + { + body.plugin.attractors = body.plugin.attractors || []; + } + }, -/** - * Takes an array of Game Objects, or any objects that have a public `x` property, - * and then adds the given value to each of their `x` properties. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `IncX(group.getChildren(), value, step)` - * - * @function Phaser.Actions.IncX - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to be added to the `x` property. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var IncX = function (items, value, step, index, direction) -{ - return PropertyValueInc(items, 'x', value, step, index, direction); -}; + Engine: + { + /** + * Applies all attractors for all bodies in the `engine`. + * This is called automatically by the plugin. + * @function MatterAttractors.Engine.update + * @param {Matter.Engine} engine The engine to update. + * @returns {void} No return value. + */ + update: function (engine) + { + var bodies = Matter.Composite.allBodies(engine.world); -module.exports = IncX; + for (var i = 0; i < bodies.length; i++) + { + var bodyA = bodies[i]; + var attractors = bodyA.plugin.attractors; + if (attractors && attractors.length > 0) + { + for (var j = 0; j < bodies.length; j++) + { + var bodyB = bodies[j]; -/***/ }), -/* 680 */ -/***/ (function(module, exports, __webpack_require__) { + if (i !== j) + { + for (var k = 0; k < attractors.length; k++) + { + var attractor = attractors[k]; + var forceVector = attractor; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (Matter.Common.isFunction(attractor)) + { + forceVector = attractor(bodyA, bodyB); + } -var PropertyValueInc = __webpack_require__(46); + if (forceVector) + { + Matter.Body.applyForce(bodyB, bodyB.position, forceVector); + } + } + } + } + } + } + } + }, -/** - * Takes an array of Game Objects, or any objects that have public `x` and `y` properties, - * and then adds the given value to each of them. - * - * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `IncXY(group.getChildren(), x, y, stepX, stepY)` - * - * @function Phaser.Actions.IncXY - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} x - The amount to be added to the `x` property. - * @param {number} [y=x] - The amount to be added to the `y` property. If `undefined` or `null` it uses the `x` value. - * @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var IncXY = function (items, x, y, stepX, stepY, index, direction) -{ - if (y === undefined || y === null) { y = x; } + /** + * Defines some useful common attractor functions that can be used + * by pushing them to your body's `body.plugin.attractors` array. + * @namespace MatterAttractors.Attractors + * @property {number} gravityConstant The gravitational constant used by the gravity attractor. + */ + Attractors: + { + gravityConstant: 0.001, - PropertyValueInc(items, 'x', x, stepX, index, direction); + /** + * An attractor function that applies Newton's law of gravitation. + * Use this by pushing `MatterAttractors.Attractors.gravity` to your body's `body.plugin.attractors` array. + * The gravitational constant defaults to `0.001` which you can change + * at `MatterAttractors.Attractors.gravityConstant`. + * @function MatterAttractors.Attractors.gravity + * @param {Matter.Body} bodyA The first body. + * @param {Matter.Body} bodyB The second body. + * @returns {void} No return value. + */ + gravity: function (bodyA, bodyB) + { + // use Newton's law of gravitation + var bToA = Matter.Vector.sub(bodyB.position, bodyA.position); + var distanceSq = Matter.Vector.magnitudeSquared(bToA) || 0.0001; + var normal = Matter.Vector.normalise(bToA); + var magnitude = -MatterAttractors.Attractors.gravityConstant * (bodyA.mass * bodyB.mass / distanceSq); + var force = Matter.Vector.mult(normal, magnitude); - return PropertyValueInc(items, 'y', y, stepY, index, direction); + // to apply forces to both bodies + Matter.Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force)); + Matter.Body.applyForce(bodyB, bodyB.position, force); + } + } }; -module.exports = IncXY; - - -/***/ }), -/* 681 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = MatterAttractors; /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @namespace Matter.Body + * @see http://brm.io/matter-js/docs/classes/Body.html */ -var PropertyValueInc = __webpack_require__(46); - /** - * Takes an array of Game Objects, or any objects that have a public `y` property, - * and then adds the given value to each of their `y` properties. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `IncY(group.getChildren(), value, step)` - * - * @function Phaser.Actions.IncY - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to be added to the `y` property. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * This plugin adds a new property `body.plugin.attractors` to instances of `Matter.Body`. + * This is an array of callback functions that will be called automatically + * for every pair of bodies, on every engine update. + * @property {Function[]} body.plugin.attractors + * @memberof Matter.Body */ -var IncY = function (items, value, step, index, direction) -{ - return PropertyValueInc(items, 'y', value, step, index, direction); -}; -module.exports = IncY; +/** + * An attractor function calculates the force to be applied + * to `bodyB`, it should either: + * - return the force vector to be applied to `bodyB` + * - or apply the force to the body(s) itself + * @callback AttractorFunction + * @param {Matter.Body} bodyA + * @param {Matter.Body} bodyB + * @returns {(Vector|undefined)} a force vector (optional) + */ /***/ }), -/* 682 */ -/***/ (function(module, exports) { + +/***/ 80391: +/***/ ((module) => { /** + * @author @dxu https://github.com/dxu/matter-collision-events * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * Takes an array of Game Objects and positions them on evenly spaced points around the perimeter of a Circle. - * - * If you wish to pass a `Phaser.GameObjects.Circle` Shape to this function, you should pass its `geom` property. - * - * @function Phaser.Actions.PlaceOnCircle - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Circle} circle - The Circle to position the Game Objects on. - * @param {number} [startAngle=0] - Optional angle to start position from, in radians. - * @param {number} [endAngle=6.28] - Optional angle to stop position at, in radians. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var PlaceOnCircle = function (items, circle, startAngle, endAngle) -{ - if (startAngle === undefined) { startAngle = 0; } - if (endAngle === undefined) { endAngle = 6.28; } +var MatterCollisionEvents = { - var angle = startAngle; - var angleStep = (endAngle - startAngle) / items.length; + name: 'matter-collision-events', + version: '0.1.6', + for: 'matter-js@^0.19.0', + silent: true, - for (var i = 0; i < items.length; i++) + install: function (matter) { - items[i].x = circle.x + (circle.radius * Math.cos(angle)); - items[i].y = circle.y + (circle.radius * Math.sin(angle)); - - angle += angleStep; - } + matter.after('Engine.create', function () + { + matter.Events.on(this, 'collisionStart', function (event) + { + event.pairs.map(function (pair) + { + var bodyA = pair.bodyA; + var bodyB = pair.bodyB; - return items; -}; + if (bodyA.gameObject) + { + bodyA.gameObject.emit('collide', bodyA, bodyB, pair); + } -module.exports = PlaceOnCircle; + if (bodyB.gameObject) + { + bodyB.gameObject.emit('collide', bodyB, bodyA, pair); + } + matter.Events.trigger(bodyA, 'onCollide', { pair: pair }); + matter.Events.trigger(bodyB, 'onCollide', { pair: pair }); -/***/ }), -/* 683 */ -/***/ (function(module, exports) { + if (bodyA.onCollideCallback) + { + bodyA.onCollideCallback(pair); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (bodyB.onCollideCallback) + { + bodyB.onCollideCallback(pair); + } -/** - * Takes an array of Game Objects and positions them on evenly spaced points around the perimeter of an Ellipse. - * - * If you wish to pass a `Phaser.GameObjects.Ellipse` Shape to this function, you should pass its `geom` property. - * - * @function Phaser.Actions.PlaceOnEllipse - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to position the Game Objects on. - * @param {number} [startAngle=0] - Optional angle to start position from, in radians. - * @param {number} [endAngle=6.28] - Optional angle to stop position at, in radians. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var PlaceOnEllipse = function (items, ellipse, startAngle, endAngle) -{ - if (startAngle === undefined) { startAngle = 0; } - if (endAngle === undefined) { endAngle = 6.28; } + if (bodyA.onCollideWith[bodyB.id]) + { + bodyA.onCollideWith[bodyB.id](bodyB, pair); + } - var angle = startAngle; - var angleStep = (endAngle - startAngle) / items.length; + if (bodyB.onCollideWith[bodyA.id]) + { + bodyB.onCollideWith[bodyA.id](bodyA, pair); + } + }); + }); - var a = ellipse.width / 2; - var b = ellipse.height / 2; + matter.Events.on(this, 'collisionActive', function (event) + { + event.pairs.map(function (pair) + { + var bodyA = pair.bodyA; + var bodyB = pair.bodyB; - for (var i = 0; i < items.length; i++) - { - items[i].x = ellipse.x + a * Math.cos(angle); - items[i].y = ellipse.y + b * Math.sin(angle); + if (bodyA.gameObject) + { + bodyA.gameObject.emit('collideActive', bodyA, bodyB, pair); + } - angle += angleStep; - } + if (bodyB.gameObject) + { + bodyB.gameObject.emit('collideActive', bodyB, bodyA, pair); + } - return items; -}; + matter.Events.trigger(bodyA, 'onCollideActive', { pair: pair }); + matter.Events.trigger(bodyB, 'onCollideActive', { pair: pair }); -module.exports = PlaceOnEllipse; + if (bodyA.onCollideActiveCallback) + { + bodyA.onCollideActiveCallback(pair); + } + if (bodyB.onCollideActiveCallback) + { + bodyB.onCollideActiveCallback(pair); + } + }); + }); -/***/ }), -/* 684 */ -/***/ (function(module, exports, __webpack_require__) { + matter.Events.on(this, 'collisionEnd', function (event) + { + event.pairs.map(function (pair) + { + var bodyA = pair.bodyA; + var bodyB = pair.bodyB; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (bodyA.gameObject) + { + bodyA.gameObject.emit('collideEnd', bodyA, bodyB, pair); + } -var GetPoints = __webpack_require__(172); + if (bodyB.gameObject) + { + bodyB.gameObject.emit('collideEnd', bodyB, bodyA, pair); + } -/** - * Positions an array of Game Objects on evenly spaced points of a Line. - * - * @function Phaser.Actions.PlaceOnLine - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Line} line - The Line to position the Game Objects on. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var PlaceOnLine = function (items, line) -{ - var points = GetPoints(line, items.length); + matter.Events.trigger(bodyA, 'onCollideEnd', { pair: pair }); + matter.Events.trigger(bodyB, 'onCollideEnd', { pair: pair }); - for (var i = 0; i < items.length; i++) - { - var item = items[i]; - var point = points[i]; + if (bodyA.onCollideEndCallback) + { + bodyA.onCollideEndCallback(pair); + } - item.x = point.x; - item.y = point.y; + if (bodyB.onCollideEndCallback) + { + bodyB.onCollideEndCallback(pair); + } + }); + }); + }); } - - return items; }; -module.exports = PlaceOnLine; +module.exports = MatterCollisionEvents; /***/ }), -/* 685 */ -/***/ (function(module, exports, __webpack_require__) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 44097: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var MarchingAnts = __webpack_require__(316); -var RotateLeft = __webpack_require__(178); -var RotateRight = __webpack_require__(179); +var Matter = __webpack_require__(18171); /** - * Takes an array of Game Objects and positions them on evenly spaced points around the perimeter of a Rectangle. - * - * Placement starts from the top-left of the rectangle, and proceeds in a clockwise direction. - * If the `shift` parameter is given you can offset where placement begins. - * - * @function Phaser.Actions.PlaceOnRectangle - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to position the Game Objects on. - * @param {number} [shift=0] - An optional positional offset. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + * A coordinate wrapping plugin for matter.js. + * See the readme for usage and examples. + * @module MatterWrap */ -var PlaceOnRectangle = function (items, rect, shift) -{ - if (shift === undefined) { shift = 0; } +var MatterWrap = { + // plugin meta + name: 'matter-wrap', // PLUGIN_NAME + version: '0.1.4', // PLUGIN_VERSION + for: 'matter-js@^0.19.0', + silent: true, // no console log please - var points = MarchingAnts(rect, false, items.length); + // installs the plugin where `base` is `Matter` + // you should not need to call this directly. + install: function(base) { + base.after('Engine.update', function() { + MatterWrap.Engine.update(this); + }); + }, - if (shift > 0) - { - RotateLeft(points, shift); - } - else if (shift < 0) - { - RotateRight(points, Math.abs(shift)); - } + Engine: { + /** + * Updates the engine by wrapping bodies and composites inside `engine.world`. + * This is called automatically by the plugin. + * @function MatterWrap.Engine.update + * @param {Matter.Engine} engine The engine to update. + * @returns {void} No return value. + */ + update: function(engine) { + var world = engine.world, + bodies = Matter.Composite.allBodies(world), + composites = Matter.Composite.allComposites(world); - for (var i = 0; i < items.length; i++) - { - items[i].x = points[i].x; - items[i].y = points[i].y; - } + for (var i = 0; i < bodies.length; i += 1) { + var body = bodies[i]; - return items; -}; + if (body.plugin.wrap) { + MatterWrap.Body.wrap(body, body.plugin.wrap); + } + } -module.exports = PlaceOnRectangle; + for (i = 0; i < composites.length; i += 1) { + var composite = composites[i]; + if (composite.plugin.wrap) { + MatterWrap.Composite.wrap(composite, composite.plugin.wrap); + } + } + } + }, -/***/ }), -/* 686 */ -/***/ (function(module, exports, __webpack_require__) { + Bounds: { + /** + * Returns a translation vector that wraps the `objectBounds` inside the `bounds`. + * @function MatterWrap.Bounds.wrap + * @param {Matter.Bounds} objectBounds The bounds of the object to wrap inside the bounds. + * @param {Matter.Bounds} bounds The bounds to wrap the body inside. + * @returns {?Matter.Vector} A translation vector (only if wrapping is required). + */ + wrap: function(objectBounds, bounds) { + var x = null, + y = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (typeof bounds.min.x !== 'undefined' && typeof bounds.max.x !== 'undefined') { + if (objectBounds.min.x > bounds.max.x) { + x = bounds.min.x - objectBounds.max.x; + } else if (objectBounds.max.x < bounds.min.x) { + x = bounds.max.x - objectBounds.min.x; + } + } -var BresenhamPoints = __webpack_require__(317); + if (typeof bounds.min.y !== 'undefined' && typeof bounds.max.y !== 'undefined') { + if (objectBounds.min.y > bounds.max.y) { + y = bounds.min.y - objectBounds.max.y; + } else if (objectBounds.max.y < bounds.min.y) { + y = bounds.max.y - objectBounds.min.y; + } + } -/** - * Takes an array of Game Objects and positions them on evenly spaced points around the edges of a Triangle. - * - * If you wish to pass a `Phaser.GameObjects.Triangle` Shape to this function, you should pass its `geom` property. - * - * @function Phaser.Actions.PlaceOnTriangle - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Triangle} triangle - The Triangle to position the Game Objects on. - * @param {number} [stepRate=1] - An optional step rate, to increase or decrease the packing of the Game Objects on the lines. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var PlaceOnTriangle = function (items, triangle, stepRate) -{ - var p1 = BresenhamPoints({ x1: triangle.x1, y1: triangle.y1, x2: triangle.x2, y2: triangle.y2 }, stepRate); - var p2 = BresenhamPoints({ x1: triangle.x2, y1: triangle.y2, x2: triangle.x3, y2: triangle.y3 }, stepRate); - var p3 = BresenhamPoints({ x1: triangle.x3, y1: triangle.y3, x2: triangle.x1, y2: triangle.y1 }, stepRate); + if (x !== null || y !== null) { + return { + x: x || 0, + y: y || 0 + }; + } + } + }, - // Remove overlaps - p1.pop(); - p2.pop(); - p3.pop(); + Body: { + /** + * Wraps the `body` position such that it always stays within the given bounds. + * Upon crossing a boundary the body will appear on the opposite side of the bounds, + * while maintaining its velocity. + * This is called automatically by the plugin. + * @function MatterWrap.Body.wrap + * @param {Matter.Body} body The body to wrap. + * @param {Matter.Bounds} bounds The bounds to wrap the body inside. + * @returns {?Matter.Vector} The translation vector that was applied (only if wrapping was required). + */ + wrap: function(body, bounds) { + var translation = MatterWrap.Bounds.wrap(body.bounds, bounds); - p1 = p1.concat(p2, p3); + if (translation) { + Matter.Body.translate(body, translation); + } - var step = p1.length / items.length; - var p = 0; + return translation; + } + }, - for (var i = 0; i < items.length; i++) - { - var item = items[i]; - var point = p1[Math.floor(p)]; + Composite: { + /** + * Returns the union of the bounds of all of the composite's bodies + * (not accounting for constraints). + * @function MatterWrap.Composite.bounds + * @param {Matter.Composite} composite The composite. + * @returns {Matter.Bounds} The composite bounds. + */ + bounds: function(composite) { + var bodies = Matter.Composite.allBodies(composite), + vertices = []; - item.x = point.x; - item.y = point.y; + for (var i = 0; i < bodies.length; i += 1) { + var body = bodies[i]; + vertices.push(body.bounds.min, body.bounds.max); + } - p += step; - } + return Matter.Bounds.create(vertices); + }, - return items; -}; + /** + * Wraps the `composite` position such that it always stays within the given bounds. + * Upon crossing a boundary the composite will appear on the opposite side of the bounds, + * while maintaining its velocity. + * This is called automatically by the plugin. + * @function MatterWrap.Composite.wrap + * @param {Matter.Composite} composite The composite to wrap. + * @param {Matter.Bounds} bounds The bounds to wrap the composite inside. + * @returns {?Matter.Vector} The translation vector that was applied (only if wrapping was required). + */ + wrap: function(composite, bounds) { + var translation = MatterWrap.Bounds.wrap( + MatterWrap.Composite.bounds(composite), + bounds + ); -module.exports = PlaceOnTriangle; + if (translation) { + Matter.Composite.translate(composite, translation); + } + return translation; + } + } +}; -/***/ }), -/* 687 */ -/***/ (function(module, exports) { +module.exports = MatterWrap; /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @namespace Matter.Body + * @see http://brm.io/matter-js/docs/classes/Body.html */ /** - * Play an animation on all Game Objects in the array that have an Animation component. - * - * You can pass either an animation key, or an animation configuration object for more control over the playback. - * - * @function Phaser.Actions.PlayAnimation - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. - * @param {boolean} [ignoreIfPlaying=false] - If this animation is already playing then ignore this call. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + * This plugin adds a new property `body.plugin.wrap` to instances of `Matter.Body`. + * This is a `Matter.Bounds` instance that specifies the wrapping region. + * @property {Matter.Bounds} body.plugin.wrap + * @memberof Matter.Body */ -var PlayAnimation = function (items, key, ignoreIfPlaying) -{ - for (var i = 0; i < items.length; i++) - { - var gameObject = items[i]; - - if (gameObject.anims) - { - gameObject.anims.play(key, ignoreIfPlaying); - } - } - - return items; -}; -module.exports = PlayAnimation; +/** + * This plugin adds a new property `composite.plugin.wrap` to instances of `Matter.Composite`. + * This is a `Matter.Bounds` instance that specifies the wrapping region. + * @property {Matter.Bounds} composite.plugin.wrap + * @memberof Matter.Composite + */ /***/ }), -/* 688 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 81084: +/***/ ((module) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Stefan Hedman (http://steffe.se) * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Random = __webpack_require__(170); +// v0.3.0 + +module.exports = { + decomp: polygonDecomp, + quickDecomp: polygonQuickDecomp, + isSimple: polygonIsSimple, + removeCollinearPoints: polygonRemoveCollinearPoints, + removeDuplicatePoints: polygonRemoveDuplicatePoints, + makeCCW: polygonMakeCCW +}; /** - * Takes an array of Game Objects and positions them at random locations within the Circle. - * - * If you wish to pass a `Phaser.GameObjects.Circle` Shape to this function, you should pass its `geom` property. - * - * @function Phaser.Actions.RandomCircle - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Circle} circle - The Circle to position the Game Objects within. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + * Compute the intersection between two lines. + * @static + * @method lineInt + * @param {Array} l1 Line vector 1 + * @param {Array} l2 Line vector 2 + * @param {Number} precision Precision to use when checking if the lines are parallel + * @return {Array} The intersection point. */ -var RandomCircle = function (items, circle) -{ - for (var i = 0; i < items.length; i++) - { - Random(circle, items[i]); +function lineInt(l1,l2,precision){ + precision = precision || 0; + var i = [0,0]; // point + var a1, b1, c1, a2, b2, c2, det; // scalars + a1 = l1[1][1] - l1[0][1]; + b1 = l1[0][0] - l1[1][0]; + c1 = a1 * l1[0][0] + b1 * l1[0][1]; + a2 = l2[1][1] - l2[0][1]; + b2 = l2[0][0] - l2[1][0]; + c2 = a2 * l2[0][0] + b2 * l2[0][1]; + det = a1 * b2 - a2*b1; + if (!scalar_eq(det, 0, precision)) { // lines are not parallel + i[0] = (b2 * c1 - b1 * c2) / det; + i[1] = (a1 * c2 - a2 * c1) / det; } + return i; +} - return items; -}; +/** + * Checks if two line segments intersects. + * @method segmentsIntersect + * @param {Array} p1 The start vertex of the first line segment. + * @param {Array} p2 The end vertex of the first line segment. + * @param {Array} q1 The start vertex of the second line segment. + * @param {Array} q2 The end vertex of the second line segment. + * @return {Boolean} True if the two line segments intersect + */ +function lineSegmentsIntersect(p1, p2, q1, q2){ + var dx = p2[0] - p1[0]; + var dy = p2[1] - p1[1]; + var da = q2[0] - q1[0]; + var db = q2[1] - q1[1]; -module.exports = RandomCircle; + // segments are parallel + if((da*dy - db*dx) === 0){ + return false; + } + var s = (dx * (q1[1] - p1[1]) + dy * (p1[0] - q1[0])) / (da * dy - db * dx); + var t = (da * (p1[1] - q1[1]) + db * (q1[0] - p1[0])) / (db * dx - da * dy); -/***/ }), -/* 689 */ -/***/ (function(module, exports, __webpack_require__) { + return (s>=0 && s<=1 && t>=0 && t<=1); +} /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Get the area of a triangle spanned by the three given points. Note that the area will be negative if the points are not given in counter-clockwise order. + * @static + * @method area + * @param {Array} a + * @param {Array} b + * @param {Array} c + * @return {Number} */ +function triangleArea(a,b,c){ + return (((b[0] - a[0])*(c[1] - a[1]))-((c[0] - a[0])*(b[1] - a[1]))); +} + +function isLeft(a,b,c){ + return triangleArea(a,b,c) > 0; +} -var Random = __webpack_require__(180); +function isLeftOn(a,b,c) { + return triangleArea(a, b, c) >= 0; +} + +function isRight(a,b,c) { + return triangleArea(a, b, c) < 0; +} + +function isRightOn(a,b,c) { + return triangleArea(a, b, c) <= 0; +} + +var tmpPoint1 = [], + tmpPoint2 = []; /** - * Takes an array of Game Objects and positions them at random locations within the Ellipse. - * - * If you wish to pass a `Phaser.GameObjects.Ellipse` Shape to this function, you should pass its `geom` property. - * - * @function Phaser.Actions.RandomEllipse - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to position the Game Objects within. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + * Check if three points are collinear + * @method collinear + * @param {Array} a + * @param {Array} b + * @param {Array} c + * @param {Number} [thresholdAngle=0] Threshold angle to use when comparing the vectors. The function will return true if the angle between the resulting vectors is less than this value. Use zero for max precision. + * @return {Boolean} */ -var RandomEllipse = function (items, ellipse) -{ - for (var i = 0; i < items.length; i++) - { - Random(ellipse, items[i]); - } - - return items; -}; +function collinear(a,b,c,thresholdAngle) { + if(!thresholdAngle){ + return triangleArea(a, b, c) === 0; + } else { + var ab = tmpPoint1, + bc = tmpPoint2; -module.exports = RandomEllipse; + ab[0] = b[0]-a[0]; + ab[1] = b[1]-a[1]; + bc[0] = c[0]-b[0]; + bc[1] = c[1]-b[1]; + var dot = ab[0]*bc[0] + ab[1]*bc[1], + magA = Math.sqrt(ab[0]*ab[0] + ab[1]*ab[1]), + magB = Math.sqrt(bc[0]*bc[0] + bc[1]*bc[1]), + angle = Math.acos(dot/(magA*magB)); + return angle < thresholdAngle; + } +} -/***/ }), -/* 690 */ -/***/ (function(module, exports, __webpack_require__) { +function sqdist(a,b){ + var dx = b[0] - a[0]; + var dy = b[1] - a[1]; + return dx * dx + dy * dy; +} /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Get a vertex at position i. It does not matter if i is out of bounds, this function will just cycle. + * @method at + * @param {Number} i + * @return {Array} */ +function polygonAt(polygon, i){ + var s = polygon.length; + return polygon[i < 0 ? i % s + s : i % s]; +} -var Random = __webpack_require__(173); +/** + * Clear the polygon data + * @method clear + * @return {Array} + */ +function polygonClear(polygon){ + polygon.length = 0; +} /** - * Takes an array of Game Objects and positions them at random locations on the Line. - * - * If you wish to pass a `Phaser.GameObjects.Line` Shape to this function, you should pass its `geom` property. - * - * @function Phaser.Actions.RandomLine - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Line} line - The Line to position the Game Objects randomly on. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + * Append points "from" to "to"-1 from an other polygon "poly" onto this one. + * @method append + * @param {Polygon} poly The polygon to get points from. + * @param {Number} from The vertex index in "poly". + * @param {Number} to The end vertex index in "poly". Note that this vertex is NOT included when appending. + * @return {Array} */ -var RandomLine = function (items, line) -{ - for (var i = 0; i < items.length; i++) - { - Random(line, items[i]); +function polygonAppend(polygon, poly, from, to){ + for(var i=from; i v[br][0])) { + br = i; + } + } + // reverse poly if clockwise + if (!isLeft(polygonAt(polygon, br - 1), polygonAt(polygon, br), polygonAt(polygon, br + 1))) { + polygonReverse(polygon); + return true; + } else { + return false; + } +} -/***/ }), -/* 691 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Reverse the vertices in the polygon + * @method reverse + */ +function polygonReverse(polygon){ + var tmp = []; + var N = polygon.length; + for(var i=0; i!==N; i++){ + tmp.push(polygon.pop()); + } + for(var i=0; i!==N; i++){ + polygon[i] = tmp[i]; + } +} /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Check if a point in the polygon is a reflex point + * @method isReflex + * @param {Number} i + * @return {Boolean} */ +function polygonIsReflex(polygon, i){ + return isRight(polygonAt(polygon, i - 1), polygonAt(polygon, i), polygonAt(polygon, i + 1)); +} -var Random = __webpack_require__(174); +var tmpLine1=[], + tmpLine2=[]; /** - * Takes an array of Game Objects and positions them at random locations within the Rectangle. - * - * @function Phaser.Actions.RandomRectangle - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to position the Game Objects within. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. + * Check if two vertices in the polygon can see each other + * @method canSee + * @param {Number} a Vertex index 1 + * @param {Number} b Vertex index 2 + * @return {Boolean} */ -var RandomRectangle = function (items, rect) -{ - for (var i = 0; i < items.length; i++) - { - Random(rect, items[i]); - } - - return items; -}; +function polygonCanSee(polygon, a,b) { + var p, dist, l1=tmpLine1, l2=tmpLine2; -module.exports = RandomRectangle; + if (isLeftOn(polygonAt(polygon, a + 1), polygonAt(polygon, a), polygonAt(polygon, b)) && isRightOn(polygonAt(polygon, a - 1), polygonAt(polygon, a), polygonAt(polygon, b))) { + return false; + } + dist = sqdist(polygonAt(polygon, a), polygonAt(polygon, b)); + for (var i = 0; i !== polygon.length; ++i) { // for each edge + if ((i + 1) % polygon.length === a || i === a){ // ignore incident edges + continue; + } + if (isLeftOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i + 1)) && isRightOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i))) { // if diag intersects an edge + l1[0] = polygonAt(polygon, a); + l1[1] = polygonAt(polygon, b); + l2[0] = polygonAt(polygon, i); + l2[1] = polygonAt(polygon, i + 1); + p = lineInt(l1,l2); + if (sqdist(polygonAt(polygon, a), p) < dist) { // if edge is blocking visibility to b + return false; + } + } + } + return true; +} -/***/ }), -/* 692 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Check if two vertices in the polygon can see each other + * @method canSee2 + * @param {Number} a Vertex index 1 + * @param {Number} b Vertex index 2 + * @return {Boolean} + */ +function polygonCanSee2(polygon, a,b) { + // for each edge + for (var i = 0; i !== polygon.length; ++i) { + // ignore incident edges + if (i === a || i === b || (i + 1) % polygon.length === a || (i + 1) % polygon.length === b){ + continue; + } + if( lineSegmentsIntersect(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i), polygonAt(polygon, i+1)) ){ + return false; + } + } + return true; +} /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Copy the polygon from vertex i to vertex j. + * @method copy + * @param {Number} i + * @param {Number} j + * @param {Polygon} [targetPoly] Optional target polygon to save in. + * @return {Polygon} The resulting copy. */ +function polygonCopy(polygon, i,j,targetPoly){ + var p = targetPoly || []; + polygonClear(p); + if (i < j) { + // Insert all vertices from i to j + for(var k=i; k<=j; k++){ + p.push(polygon[k]); + } + + } else { + + // Insert vertices 0 to j + for(var k=0; k<=j; k++){ + p.push(polygon[k]); + } -var Random = __webpack_require__(181); + // Insert vertices i to end + for(var k=i; k - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Decomposes the polygon into one or more convex sub-Polygons. + * @method decomp + * @return {Array} An array or Polygon objects. */ - -var PropertyValueInc = __webpack_require__(46); +function polygonDecomp(polygon){ + var edges = polygonGetCutEdges(polygon); + if(edges.length > 0){ + return polygonSlice(polygon, edges); + } else { + return [polygon]; + } +} /** - * Takes an array of Game Objects, or any objects that have a public `rotation` property, - * and then adds the given value to each of their `rotation` properties. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `Rotate(group.getChildren(), value, step)` - * - * @function Phaser.Actions.Rotate - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to be added to the `rotation` property (in radians). - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * Slices the polygon given one or more cut edges. If given one, this function will return two polygons (false on failure). If many, an array of polygons. + * @method slice + * @param {Array} cutEdges A list of edges, as returned by .getCutEdges() + * @return {Array} */ -var Rotate = function (items, value, step, index, direction) -{ - return PropertyValueInc(items, 'rotation', value, step, index, direction); -}; +function polygonSlice(polygon, cutEdges){ + if(cutEdges.length === 0){ + return [polygon]; + } + if(cutEdges instanceof Array && cutEdges.length && cutEdges[0] instanceof Array && cutEdges[0].length===2 && cutEdges[0][0] instanceof Array){ -module.exports = Rotate; + var polys = [polygon]; + + for(var i=0; i - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Checks that the line segments of this polygon do not intersect each other. + * @method isSimple + * @param {Array} path An array of vertices e.g. [[0,0],[0,1],...] + * @return {Boolean} + * @todo Should it check all segments with all others? */ +function polygonIsSimple(polygon){ + var path = polygon, i; + // Check + for(i=0; i maxlevel){ + console.warn("quickDecomp: max level ("+maxlevel+") reached."); + return result; + } -module.exports = RotateAround; + for (var i = 0; i < polygon.length; ++i) { + if (polygonIsReflex(poly, i)) { + reflexVertices.push(poly[i]); + upperDist = lowerDist = Number.MAX_VALUE; -/***/ }), -/* 695 */ -/***/ (function(module, exports, __webpack_require__) { + for (var j = 0; j < polygon.length; ++j) { + if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j - 1))) { // if line intersects with an edge + p = getIntersectionPoint(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j - 1)); // find the point of intersection + if (isRight(polygonAt(poly, i + 1), polygonAt(poly, i), p)) { // make sure it's inside the poly + d = sqdist(poly[i], p); + if (d < lowerDist) { // keep only the closest intersection + lowerDist = d; + lowerInt = p; + lowerIndex = j; + } + } + } + if (isLeft(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j + 1)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) { + p = getIntersectionPoint(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j + 1)); + if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), p)) { + d = sqdist(poly[i], p); + if (d < upperDist) { + upperDist = d; + upperInt = p; + upperIndex = j; + } + } + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // if there are no vertices to connect to, choose a point in the middle + if (lowerIndex === (upperIndex + 1) % polygon.length) { + //console.log("Case 1: Vertex("+i+"), lowerIndex("+lowerIndex+"), upperIndex("+upperIndex+"), poly.size("+polygon.length+")"); + p[0] = (lowerInt[0] + upperInt[0]) / 2; + p[1] = (lowerInt[1] + upperInt[1]) / 2; + steinerPoints.push(p); -var MathRotateAroundDistance = __webpack_require__(182); + if (i < upperIndex) { + //lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.begin() + upperIndex + 1); + polygonAppend(lowerPoly, poly, i, upperIndex+1); + lowerPoly.push(p); + upperPoly.push(p); + if (lowerIndex !== 0){ + //upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.end()); + polygonAppend(upperPoly, poly,lowerIndex,poly.length); + } + //upperPoly.insert(upperPoly.end(), poly.begin(), poly.begin() + i + 1); + polygonAppend(upperPoly, poly,0,i+1); + } else { + if (i !== 0){ + //lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.end()); + polygonAppend(lowerPoly, poly,i,poly.length); + } + //lowerPoly.insert(lowerPoly.end(), poly.begin(), poly.begin() + upperIndex + 1); + polygonAppend(lowerPoly, poly,0,upperIndex+1); + lowerPoly.push(p); + upperPoly.push(p); + //upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.begin() + i + 1); + polygonAppend(upperPoly, poly,lowerIndex,i+1); + } + } else { + // connect to the closest point within the triangle + //console.log("Case 2: Vertex("+i+"), closestIndex("+closestIndex+"), poly.size("+polygon.length+")\n"); -/** - * Rotates an array of Game Objects around a point by the given angle and distance. - * - * @function Phaser.Actions.RotateAroundDistance - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {object} point - Any object with public `x` and `y` properties. - * @param {number} angle - The angle to rotate by, in radians. - * @param {number} distance - The distance from the point of rotation in pixels. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var RotateAroundDistance = function (items, point, angle, distance) -{ - var x = point.x; - var y = point.y; + if (lowerIndex > upperIndex) { + upperIndex += polygon.length; + } + closestDist = Number.MAX_VALUE; - // There's nothing to do - if (distance === 0) - { - return items; - } + if(upperIndex < lowerIndex){ + return result; + } - for (var i = 0; i < items.length; i++) - { - MathRotateAroundDistance(items[i], x, y, angle, distance); - } + for (var j = lowerIndex; j <= upperIndex; ++j) { + if ( + isLeftOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && + isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j)) + ) { + d = sqdist(polygonAt(poly, i), polygonAt(poly, j)); + if (d < closestDist && polygonCanSee2(poly, i, j)) { + closestDist = d; + closestIndex = j % polygon.length; + } + } + } - return items; -}; + if (i < closestIndex) { + polygonAppend(lowerPoly, poly,i,closestIndex+1); + if (closestIndex !== 0){ + polygonAppend(upperPoly, poly,closestIndex,v.length); + } + polygonAppend(upperPoly, poly,0,i+1); + } else { + if (i !== 0){ + polygonAppend(lowerPoly, poly,i,v.length); + } + polygonAppend(lowerPoly, poly,0,closestIndex+1); + polygonAppend(upperPoly, poly,closestIndex,i+1); + } + } -module.exports = RotateAroundDistance; + // solve smallest poly first + if (lowerPoly.length < upperPoly.length) { + polygonQuickDecomp(lowerPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level); + polygonQuickDecomp(upperPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level); + } else { + polygonQuickDecomp(upperPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level); + polygonQuickDecomp(lowerPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level); + } + return result; + } + } + result.push(polygon); -/***/ }), -/* 696 */ -/***/ (function(module, exports, __webpack_require__) { + return result; +} /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Remove collinear points in the polygon. + * @method removeCollinearPoints + * @param {Number} [precision] The threshold angle to use when determining whether two edges are collinear. Use zero for finest precision. + * @return {Number} The number of points removed */ +function polygonRemoveCollinearPoints(polygon, precision){ + var num = 0; + for(var i=polygon.length-1; polygon.length>3 && i>=0; --i){ + if(collinear(polygonAt(polygon, i-1),polygonAt(polygon, i),polygonAt(polygon, i+1),precision)){ + // Remove the middle point + polygon.splice(i%polygon.length,1); + num++; + } + } + return num; +} -var PropertyValueInc = __webpack_require__(46); +/** + * Remove duplicate points in the polygon. + * @method removeDuplicatePoints + * @param {Number} [precision] The threshold to use when determining whether two points are the same. Use zero for best precision. + */ +function polygonRemoveDuplicatePoints(polygon, precision){ + for(var i=polygon.length-1; i>=1; --i){ + var pi = polygon[i]; + for(var j=i-1; j>=0; --j){ + if(points_eq(pi, polygon[j], precision)){ + polygon.splice(i,1); + continue; + } + } + } +} /** - * Takes an array of Game Objects, or any objects that have a public `scaleX` property, - * and then adds the given value to each of their `scaleX` properties. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `ScaleX(group.getChildren(), value, step)` - * - * @function Phaser.Actions.ScaleX - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to be added to the `scaleX` property. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * Check if two scalars are equal + * @static + * @method eq + * @param {Number} a + * @param {Number} b + * @param {Number} [precision] + * @return {Boolean} */ -var ScaleX = function (items, value, step, index, direction) -{ - return PropertyValueInc(items, 'scaleX', value, step, index, direction); -}; +function scalar_eq(a,b,precision){ + precision = precision || 0; + return Math.abs(a-b) <= precision; +} -module.exports = ScaleX; +/** + * Check if two points are equal + * @static + * @method points_eq + * @param {Array} a + * @param {Array} b + * @param {Number} [precision] + * @return {Boolean} + */ +function points_eq(a,b,precision){ + return scalar_eq(a[0],b[0],precision) && scalar_eq(a[1],b[1],precision); +} /***/ }), -/* 697 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 88257: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +* @author Richard Davey +* @copyright 2013-2023 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License} +*/ -var PropertyValueInc = __webpack_require__(46); +var Class = __webpack_require__(56694); /** - * Takes an array of Game Objects, or any objects that have public `scaleX` and `scaleY` properties, - * and then adds the given value to each of them. - * - * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `ScaleXY(group.getChildren(), scaleX, scaleY, stepX, stepY)` - * - * @function Phaser.Actions.ScaleXY - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * @classdesc + * A Global Plugin is installed just once into the Game owned Plugin Manager. + * It can listen for Game events and respond to them. * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} scaleX - The amount to be added to the `scaleX` property. - * @param {number} [scaleY] - The amount to be added to the `scaleY` property. If `undefined` or `null` it uses the `scaleX` value. - * @param {number} [stepX=0] - This is added to the `scaleX` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `scaleY` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * @class BasePlugin + * @memberof Phaser.Plugins + * @constructor + * @since 3.8.0 * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Plugin Manager. */ -var ScaleXY = function (items, scaleX, scaleY, stepX, stepY, index, direction) -{ - if (scaleY === undefined || scaleY === null) { scaleY = scaleX; } +var BasePlugin = new Class({ - PropertyValueInc(items, 'scaleX', scaleX, stepX, index, direction); + initialize: - return PropertyValueInc(items, 'scaleY', scaleY, stepY, index, direction); -}; + 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; -module.exports = ScaleXY; + /** + * 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. -/***/ }), -/* 698 */ -/***/ (function(module, exports, __webpack_require__) { + // var eventEmitter = this.game.events; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // 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); + }, -var PropertyValueInc = __webpack_require__(46); + /** + * 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 () + { + }, -/** - * Takes an array of Game Objects, or any objects that have a public `scaleY` property, - * and then adds the given value to each of their `scaleY` properties. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `ScaleY(group.getChildren(), value, step)` - * - * @function Phaser.Actions.ScaleY - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to be added to the `scaleY` property. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var ScaleY = function (items, value, step, index, direction) -{ - return PropertyValueInc(items, 'scaleY', value, step, index, direction); -}; + /** + * 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 = ScaleY; +}); + +module.exports = BasePlugin; /***/ }), -/* 699 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 18360: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var PropertyValueSet = __webpack_require__(27); - /** - * Takes an array of Game Objects, or any objects that have the public property `alpha` - * and then sets it to the given value. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetAlpha(group.getChildren(), value, step)` + * The Default Plugins. * - * @function Phaser.Actions.SetAlpha + * @namespace Phaser.Plugins.DefaultPlugins + * @memberof Phaser.Plugins * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. */ -var SetAlpha = function (items, value, step, index, direction) -{ - return PropertyValueSet(items, 'alpha', value, step, index, direction); -}; -module.exports = SetAlpha; +var DefaultPlugins = { + /** + * These are the Global Managers that are created by the Phaser.Game instance. + * They are referenced from Scene.Systems so that plugins can use them. + * + * @name Phaser.Plugins.DefaultPlugins.Global + * @type {array} + * @since 3.0.0 + */ + Global: [ -/***/ }), -/* 700 */ -/***/ (function(module, exports, __webpack_require__) { + 'game', + 'anims', + 'cache', + 'plugins', + 'registry', + 'scale', + 'sound', + 'textures', + 'renderer' -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + ], -var PropertyValueSet = __webpack_require__(27); + /** + * These are the core plugins that are installed into every Scene.Systems instance, no matter what. + * They are optionally exposed in the Scene as well (see the InjectionMap for details) + * + * They are created in the order in which they appear in this array and EventEmitter is always first. + * + * @name Phaser.Plugins.DefaultPlugins.CoreScene + * @type {array} + * @since 3.0.0 + */ + CoreScene: [ -/** - * Takes an array of Game Objects, or any objects that have the public property `blendMode` - * and then sets it to the given value. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetBlendMode(group.getChildren(), value)` - * - * @function Phaser.Actions.SetBlendMode - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var SetBlendMode = function (items, value, index, direction) -{ - return PropertyValueSet(items, 'blendMode', value, 0, index, direction); -}; + 'EventEmitter', -module.exports = SetBlendMode; + 'CameraManager', + 'GameObjectCreator', + 'GameObjectFactory', + 'ScenePlugin', + 'DisplayList', + 'UpdateList' + ], -/***/ }), -/* 701 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * These plugins are created in Scene.Systems in addition to the CoreScenePlugins. + * + * You can elect not to have these plugins by either creating a DefaultPlugins object as part + * of the Game Config, by creating a Plugins object as part of a Scene Config, or by modifying this array + * and building your own bundle. + * + * They are optionally exposed in the Scene as well (see the InjectionMap for details) + * + * They are always created in the order in which they appear in the array. + * + * @name Phaser.Plugins.DefaultPlugins.DefaultScene + * @type {array} + * @since 3.0.0 + */ + DefaultScene: [ -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + 'Clock', + 'DataManagerPlugin', + 'InputPlugin', + 'Loader', + 'TweenManager', + 'LightsPlugin' -var PropertyValueSet = __webpack_require__(27); + ] -/** - * Takes an array of Game Objects, or any objects that have the public property `depth` - * and then sets it to the given value. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetDepth(group.getChildren(), value, step)` - * - * @function Phaser.Actions.SetDepth - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var SetDepth = function (items, value, step, index, direction) -{ - return PropertyValueSet(items, 'depth', value, step, index, direction); }; -module.exports = SetDepth; +if (false) +{} + +if (false) +{} + +module.exports = DefaultPlugins; /***/ }), -/* 702 */ -/***/ (function(module, exports) { + +/***/ 91963: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * Passes all provided Game Objects to the Input Manager to enable them for input with identical areas and callbacks. - * - * @see {@link Phaser.GameObjects.GameObject#setInteractive} - * - * @function Phaser.Actions.SetHitArea - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {*} hitArea - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. - * @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - A callback to be invoked when the Game Object is interacted with. If you provide a shape you must also provide a callback. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var SetHitArea = function (items, hitArea, hitAreaCallback) -{ - for (var i = 0; i < items.length; i++) - { - items[i].setInteractive(hitArea, hitAreaCallback); - } - - return items; -}; - -module.exports = SetHitArea; +// Contains the plugins that Phaser uses globally and locally. +// These are the source objects, not instantiated. +var corePlugins = {}; +// Contains the plugins that the dev has loaded into their game +// These are the source objects, not instantiated. +var customPlugins = {}; -/***/ }), -/* 703 */ -/***/ (function(module, exports, __webpack_require__) { +var PluginCache = {}; /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @namespace Phaser.Plugins.PluginCache */ -var PropertyValueSet = __webpack_require__(27); - /** - * Takes an array of Game Objects, or any objects that have the public properties `originX` and `originY` - * and then sets them to the given values. - * - * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetOrigin(group.getChildren(), originX, originY, stepX, stepY)` - * - * @function Phaser.Actions.SetOrigin - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * Static method called directly by the Core internal Plugins. + * Key is a reference used to get the plugin from the plugins object (i.e. InputPlugin) + * Plugin is the object to instantiate to create the plugin + * Mapping is what the plugin is injected into the Scene.Systems as (i.e. input) * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} originX - The amount to set the `originX` property to. - * @param {number} [originY] - The amount to set the `originY` property to. If `undefined` or `null` it uses the `originX` value. - * @param {number} [stepX=0] - This is added to the `originX` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `originY` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * @method Phaser.Plugins.PluginCache.register + * @since 3.8.0 * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * @param {string} key - A reference used to get this plugin from the plugin cache. + * @param {function} plugin - The plugin to be stored. Should be the core object, not instantiated. + * @param {string} mapping - If this plugin is to be injected into the Scene Systems, this is the property key map used. + * @param {boolean} [custom=false] - Core Scene plugin or a Custom Scene plugin? */ -var SetOrigin = function (items, originX, originY, stepX, stepY, index, direction) +PluginCache.register = function (key, plugin, mapping, custom) { - if (originY === undefined || originY === null) { originY = originX; } - - PropertyValueSet(items, 'originX', originX, stepX, index, direction); - PropertyValueSet(items, 'originY', originY, stepY, index, direction); - - items.forEach(function (item) - { - item.updateDisplayOrigin(); - }); + if (custom === undefined) { custom = false; } - return items; + corePlugins[key] = { plugin: plugin, mapping: mapping, custom: custom }; }; -module.exports = SetOrigin; - - -/***/ }), -/* 704 */ -/***/ (function(module, exports, __webpack_require__) { - /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Stores a custom plugin in the global plugin cache. + * The key must be unique, within the scope of the cache. + * + * @method Phaser.Plugins.PluginCache.registerCustom + * @since 3.8.0 + * + * @param {string} key - A reference used to get this plugin from the plugin cache. + * @param {function} plugin - The plugin to be stored. Should be the core object, not instantiated. + * @param {string} mapping - If this plugin is to be injected into the Scene Systems, this is the property key map used. + * @param {?any} data - A value to be passed to the plugin's `init` method. */ - -var PropertyValueSet = __webpack_require__(27); +PluginCache.registerCustom = function (key, plugin, mapping, data) +{ + customPlugins[key] = { plugin: plugin, mapping: mapping, data: data }; +}; /** - * Takes an array of Game Objects, or any objects that have the public property `rotation` - * and then sets it to the given value. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetRotation(group.getChildren(), value, step)` - * - * @function Phaser.Actions.SetRotation - * @since 3.0.0 + * Checks if the given key is already being used in the core plugin cache. * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * @method Phaser.Plugins.PluginCache.hasCore + * @since 3.8.0 * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * @param {string} key - The key to check for. * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * @return {boolean} `true` if the key is already in use in the core cache, otherwise `false`. */ -var SetRotation = function (items, value, step, index, direction) +PluginCache.hasCore = function (key) { - return PropertyValueSet(items, 'rotation', value, step, index, direction); + return corePlugins.hasOwnProperty(key); }; -module.exports = SetRotation; - - -/***/ }), -/* 705 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var PropertyValueSet = __webpack_require__(27); - /** - * Takes an array of Game Objects, or any objects that have the public properties `scaleX` and `scaleY` - * and then sets them to the given values. - * - * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetScale(group.getChildren(), scaleX, scaleY, stepX, stepY)` - * - * @function Phaser.Actions.SetScale - * @since 3.0.0 + * Checks if the given key is already being used in the custom plugin cache. * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * @method Phaser.Plugins.PluginCache.hasCustom + * @since 3.8.0 * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} scaleX - The amount to set the `scaleX` property to. - * @param {number} [scaleY] - The amount to set the `scaleY` property to. If `undefined` or `null` it uses the `scaleX` value. - * @param {number} [stepX=0] - This is added to the `scaleX` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `scaleY` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * @param {string} key - The key to check for. * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * @return {boolean} `true` if the key is already in use in the custom cache, otherwise `false`. */ -var SetScale = function (items, scaleX, scaleY, stepX, stepY, index, direction) +PluginCache.hasCustom = function (key) { - if (scaleY === undefined || scaleY === null) { scaleY = scaleX; } - - PropertyValueSet(items, 'scaleX', scaleX, stepX, index, direction); - - return PropertyValueSet(items, 'scaleY', scaleY, stepY, index, direction); + return customPlugins.hasOwnProperty(key); }; -module.exports = SetScale; - - -/***/ }), -/* 706 */ -/***/ (function(module, exports, __webpack_require__) { - /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Returns the core plugin object from the cache based on the given key. + * + * @method Phaser.Plugins.PluginCache.getCore + * @since 3.8.0 + * + * @param {string} key - The key of the core plugin to get. + * + * @return {Phaser.Types.Plugins.CorePluginContainer} The core plugin object. */ - -var PropertyValueSet = __webpack_require__(27); +PluginCache.getCore = function (key) +{ + return corePlugins[key]; +}; /** - * Takes an array of Game Objects, or any objects that have the public property `scaleX` - * and then sets it to the given value. + * Returns the custom plugin object from the cache based on the given key. * - * The optional `step` property is applied incrementally, multiplied by each item in the array. + * @method Phaser.Plugins.PluginCache.getCustom + * @since 3.8.0 * - * To use this with a Group: `SetScaleX(group.getChildren(), value, step)` + * @param {string} key - The key of the custom plugin to get. * - * @function Phaser.Actions.SetScaleX - * @since 3.0.0 + * @return {Phaser.Types.Plugins.CustomPluginContainer} The custom plugin object. + */ +PluginCache.getCustom = function (key) +{ + return customPlugins[key]; +}; + +/** + * Returns an object from the custom cache based on the given key that can be instantiated. * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * @method Phaser.Plugins.PluginCache.getCustomClass + * @since 3.8.0 * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * @param {string} key - The key of the custom plugin to get. * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * @return {function} The custom plugin object. */ -var SetScaleX = function (items, value, step, index, direction) +PluginCache.getCustomClass = function (key) { - return PropertyValueSet(items, 'scaleX', value, step, index, direction); + return (customPlugins.hasOwnProperty(key)) ? customPlugins[key].plugin : null; }; -module.exports = SetScaleX; - - -/***/ }), -/* 707 */ -/***/ (function(module, exports, __webpack_require__) { - /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Removes a core plugin based on the given key. + * + * @method Phaser.Plugins.PluginCache.remove + * @since 3.8.0 + * + * @param {string} key - The key of the core plugin to remove. */ - -var PropertyValueSet = __webpack_require__(27); +PluginCache.remove = function (key) +{ + if (corePlugins.hasOwnProperty(key)) + { + delete corePlugins[key]; + } +}; /** - * Takes an array of Game Objects, or any objects that have the public property `scaleY` - * and then sets it to the given value. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetScaleY(group.getChildren(), value, step)` - * - * @function Phaser.Actions.SetScaleY - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * Removes a custom plugin based on the given key. * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * @method Phaser.Plugins.PluginCache.removeCustom + * @since 3.8.0 * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * @param {string} key - The key of the custom plugin to remove. */ -var SetScaleY = function (items, value, step, index, direction) +PluginCache.removeCustom = function (key) { - return PropertyValueSet(items, 'scaleY', value, step, index, direction); + if (customPlugins.hasOwnProperty(key)) + { + delete customPlugins[key]; + } }; -module.exports = SetScaleY; - - -/***/ }), -/* 708 */ -/***/ (function(module, exports, __webpack_require__) { - /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Removes all Core Plugins. + * + * This includes all of the internal system plugins that Phaser needs, like the Input Plugin and Loader Plugin. + * So be sure you only call this if you do not wish to run Phaser again. + * + * @method Phaser.Plugins.PluginCache.destroyCorePlugins + * @since 3.12.0 */ - -var PropertyValueSet = __webpack_require__(27); +PluginCache.destroyCorePlugins = function () +{ + for (var key in corePlugins) + { + if (corePlugins.hasOwnProperty(key)) + { + delete corePlugins[key]; + } + } +}; /** - * Takes an array of Game Objects, or any objects that have the public properties `scrollFactorX` and `scrollFactorY` - * and then sets them to the given values. - * - * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetScrollFactor(group.getChildren(), scrollFactorX, scrollFactorY, stepX, stepY)` - * - * @function Phaser.Actions.SetScrollFactor - * @since 3.21.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} scrollFactorX - The amount to set the `scrollFactorX` property to. - * @param {number} [scrollFactorY] - The amount to set the `scrollFactorY` property to. If `undefined` or `null` it uses the `scrollFactorX` value. - * @param {number} [stepX=0] - This is added to the `scrollFactorX` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `scrollFactorY` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * Removes all Custom Plugins. * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * @method Phaser.Plugins.PluginCache.destroyCustomPlugins + * @since 3.12.0 */ -var SetScrollFactor = function (items, scrollFactorX, scrollFactorY, stepX, stepY, index, direction) +PluginCache.destroyCustomPlugins = function () { - if (scrollFactorY === undefined || scrollFactorY === null) { scrollFactorY = scrollFactorX; } - - PropertyValueSet(items, 'scrollFactorX', scrollFactorX, stepX, index, direction); - - return PropertyValueSet(items, 'scrollFactorY', scrollFactorY, stepY, index, direction); + for (var key in customPlugins) + { + if (customPlugins.hasOwnProperty(key)) + { + delete customPlugins[key]; + } + } }; -module.exports = SetScrollFactor; +module.exports = PluginCache; /***/ }), -/* 709 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 49274: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var PropertyValueSet = __webpack_require__(27); +var Class = __webpack_require__(56694); +var GameEvents = __webpack_require__(97081); +var EventEmitter = __webpack_require__(6659); +var FileTypesManager = __webpack_require__(76846); +var GameObjectCreator = __webpack_require__(99325); +var GameObjectFactory = __webpack_require__(61286); +var GetFastValue = __webpack_require__(72632); +var PluginCache = __webpack_require__(91963); +var Remove = __webpack_require__(66458); /** - * Takes an array of Game Objects, or any objects that have the public property `scrollFactorX` - * and then sets it to the given value. + * @classdesc + * The PluginManager is responsible for installing and adding plugins to Phaser. * - * The optional `step` property is applied incrementally, multiplied by each item in the array. + * It is a global system and therefore belongs to the Game instance, not a specific Scene. * - * To use this with a Group: `SetScrollFactorX(group.getChildren(), value, step)` + * 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. * - * @function Phaser.Actions.SetScrollFactorX - * @since 3.21.0 + * There are two types of plugin: * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * 1. A Global Plugin + * 2. A Scene Plugin * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * 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. * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var SetScrollFactorX = function (items, value, step, index, direction) -{ - return PropertyValueSet(items, 'scrollFactorX', value, step, index, direction); -}; - -module.exports = SetScrollFactorX; - - -/***/ }), -/* 710 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var PropertyValueSet = __webpack_require__(27); - -/** - * Takes an array of Game Objects, or any objects that have the public property `scrollFactorY` - * and then sets it to the given value. + * 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. * - * The optional `step` property is applied incrementally, multiplied by each item in the array. + * You can add a plugin to Phaser in three different ways: * - * To use this with a Group: `SetScrollFactorY(group.getChildren(), value, step)` + * 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 * - * @function Phaser.Actions.SetScrollFactorY - * @since 3.21.0 + * For examples of all of these approaches please see the Phaser 3 Examples Repo `plugins` folder. * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] + * For information on creating your own plugin please see the Phaser 3 Plugin Template. * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. + * @class PluginManager + * @memberof Phaser.Plugins + * @constructor + * @since 3.0.0 * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. + * @param {Phaser.Game} game - The game instance that owns this Plugin Manager. */ -var SetScrollFactorY = function (items, value, step, index, direction) -{ - return PropertyValueSet(items, 'scrollFactorY', value, step, index, direction); -}; +var PluginManager = new Class({ -module.exports = SetScrollFactorY; + Extends: EventEmitter, + initialize: -/***/ }), -/* 711 */ -/***/ (function(module, exports) { + function PluginManager (game) + { + EventEmitter.call(this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The game instance that owns this Plugin Manager. + * + * @name Phaser.Plugins.PluginManager#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game = game; -/** - * Takes an array of Game Objects, or any objects that have the public method setTint() and then updates it to the given value(s). You can specify tint color per corner or provide only one color value for `topLeft` parameter, in which case whole item will be tinted with that color. - * - * @function Phaser.Actions.SetTint - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {number} topLeft - The tint being applied to top-left corner of item. If other parameters are given no value, this tint will be applied to whole item. - * @param {number} [topRight] - The tint to be applied to top-right corner of item. - * @param {number} [bottomLeft] - The tint to be applied to the bottom-left corner of item. - * @param {number} [bottomRight] - The tint to be applied to the bottom-right corner of item. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var SetTint = function (items, topLeft, topRight, bottomLeft, bottomRight) -{ - for (var i = 0; i < items.length; i++) + /** + * 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 () { - items[i].setTint(topLeft, topRight, bottomLeft, bottomRight); - } + var i; + var entry; + var key; + var plugin; + var start; + var mapping; + var data; + var config = this.game.config; - return items; -}; + // Any plugins to install? + var list = config.installGlobalPlugins; -module.exports = SetTint; + // 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]; -/***/ }), -/* 712 */ -/***/ (function(module, exports, __webpack_require__) { + // { key: 'TestPlugin', plugin: TestPlugin, start: true, mapping: 'test', data: { msg: 'The plugin is alive' } } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + 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); -var PropertyValueSet = __webpack_require__(27); + if (key) + { + if (plugin) + { + this.install(key, plugin, start, mapping, data); + } + else + { + console.warn('Missing `plugin` for key: ' + key); + } -/** - * Takes an array of Game Objects, or any objects that have the public property `visible` - * and then sets it to the given value. - * - * To use this with a Group: `SetVisible(group.getChildren(), value)` - * - * @function Phaser.Actions.SetVisible - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {boolean} value - The value to set the property to. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var SetVisible = function (items, value, index, direction) -{ - return PropertyValueSet(items, 'visible', value, 0, index, direction); -}; + } + } -module.exports = SetVisible; + // 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); -/***/ }), -/* 713 */ -/***/ (function(module, exports, __webpack_require__) { + for (i = 0; i < list.length; i++) + { + entry = list[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // { key: 'moveSpritePlugin', plugin: MoveSpritePlugin, , mapping: 'move' } -var PropertyValueSet = __webpack_require__(27); + key = GetFastValue(entry, 'key', null); + plugin = GetFastValue(entry, 'plugin', null); + mapping = GetFastValue(entry, 'mapping', null); -/** - * Takes an array of Game Objects, or any objects that have the public property `x` - * and then sets it to the given value. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetX(group.getChildren(), value, step)` - * - * @function Phaser.Actions.SetX - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var SetX = function (items, value, step, index, direction) -{ - return PropertyValueSet(items, 'x', value, step, index, direction); -}; + if (key) + { + if (plugin) + { + this.installScenePlugin(key, plugin, mapping); + } + else + { + console.warn('Missing `plugin` for key: ' + key); + } + } + } -module.exports = SetX; + this._pendingGlobal = []; + this._pendingScene = []; + this.game.events.once(GameEvents.DESTROY, this.destroy, this); + }, -/***/ }), -/* 714 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Reference the GlobalPlugins from Game into Scene.Systems + for (i = 0; i < globalPlugins.length; i++) + { + pluginKey = globalPlugins[i]; -var PropertyValueSet = __webpack_require__(27); + if (game[pluginKey]) + { + sys[pluginKey] = game[pluginKey]; -/** - * Takes an array of Game Objects, or any objects that have the public properties `x` and `y` - * and then sets them to the given values. - * - * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetXY(group.getChildren(), x, y, stepX, stepY)` - * - * @function Phaser.Actions.SetXY - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} x - The amount to set the `x` property to. - * @param {number} [y=x] - The amount to set the `y` property to. If `undefined` or `null` it uses the `x` value. - * @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter. - * @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var SetXY = function (items, x, y, stepX, stepY, index, direction) -{ - if (y === undefined || y === null) { y = x; } + // Scene level injection + if (map.hasOwnProperty(pluginKey)) + { + scene[map[pluginKey]] = sys[pluginKey]; + } + } + else if (pluginKey === 'game' && map.hasOwnProperty(pluginKey)) + { + scene[map[pluginKey]] = game; + } + } - PropertyValueSet(items, 'x', x, stepX, index, direction); + for (var s = 0; s < scenePlugins.length; s++) + { + pluginList = scenePlugins[s]; - return PropertyValueSet(items, 'y', y, stepY, index, direction); -}; + for (i = 0; i < pluginList.length; i++) + { + pluginKey = pluginList[i]; -module.exports = SetXY; + if (!PluginCache.hasCore(pluginKey)) + { + continue; + } + var source = PluginCache.getCore(pluginKey); -/***/ }), -/* 715 */ -/***/ (function(module, exports, __webpack_require__) { + var mapKey = source.mapping; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var plugin = new source.plugin(scene, this, mapKey); -var PropertyValueSet = __webpack_require__(27); + sys[mapKey] = plugin; -/** - * Takes an array of Game Objects, or any objects that have the public property `y` - * and then sets it to the given value. - * - * The optional `step` property is applied incrementally, multiplied by each item in the array. - * - * To use this with a Group: `SetY(group.getChildren(), value, step)` - * - * @function Phaser.Actions.SetY - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action. - * @param {number} value - The amount to set the property to. - * @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter. - * @param {number} [index=0] - An optional offset to start searching from within the items array. - * @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action. - */ -var SetY = function (items, value, step, index, direction) -{ - return PropertyValueSet(items, 'y', value, step, index, direction); -}; + // Scene level injection + if (source.custom) + { + scene[mapKey] = plugin; + } + else if (map.hasOwnProperty(mapKey)) + { + scene[map[mapKey]] = plugin; + } -module.exports = SetY; + // 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; -/***/ }), -/* 716 */ -/***/ (function(module, exports, __webpack_require__) { + for (i = 0; i < pluginList.length; i++) + { + var entry = pluginList[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (entry.mapping) + { + scene[entry.mapping] = entry.plugin; + } + } + }, -var Vector2 = __webpack_require__(3); + /** + * 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; -/** - * Iterate through the items array changing the position of each element to be that of the element that came before - * it in the array (or after it if direction = 1) - * - * The first items position is set to x/y. - * - * The final x/y coords are returned - * - * @function Phaser.Actions.ShiftPosition - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items] - * @generic {Phaser.Math.Vector2} O - [output,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {number} x - The x coordinate to place the first item in the array at. - * @param {number} y - The y coordinate to place the first item in the array at. - * @param {number} [direction=0] - The iteration direction. 0 = first to last and 1 = last to first. - * @param {(Phaser.Math.Vector2|object)} [output] - An optional objec to store the final objects position in. - * - * @return {Phaser.Math.Vector2} The output vector. - */ -var ShiftPosition = function (items, x, y, direction, output) -{ - if (direction === undefined) { direction = 0; } - if (output === undefined) { output = new Vector2(); } + // Merge in custom Scene plugins + list = list.concat(this.scenePlugins); - var px; - var py; + return list; + }, - if (items.length > 1) + /** + * 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) { - var i; - var cx; - var cy; - var cur; + 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); + } - if (direction === 0) + if (this.scenePlugins.indexOf(key) === -1) + { + this.scenePlugins.push(key); + } + else if (!fromLoader && PluginCache.hasCore(key)) { - // Bottom to Top + // Plugin wasn't from the loader but already exists + console.warn('Scene Plugin key in use: ' + key); + return; + } - var len = items.length - 1; + if (addToScene) + { + var instance = new plugin(addToScene, this, key); - px = items[len].x; - py = items[len].y; + addToScene.sys[key] = instance; - for (i = len - 1; i >= 0; i--) + if (mapping && mapping !== '') { - // Current item - cur = items[i]; + addToScene[mapping] = instance; + } + + instance.boot(); + } + }, - // Get current item x/y, to be passed to the next item in the list - cx = cur.x; - cy = cur.y; + /** + * 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; } - // Set current item to the previous items x/y - cur.x = px; - cur.y = py; + if (typeof plugin !== 'function') + { + console.warn('Invalid Plugin: ' + key); + return null; + } - // Set current as previous - px = cx; - py = cy; - } + if (PluginCache.hasCustom(key)) + { + console.warn('Plugin key in use: ' + key); + return null; + } + + if (mapping !== null) + { + start = true; + } - // Update the head item to the new x/y coordinates - items[len].x = x; - items[len].y = y; + if (!this.game.isBooted) + { + this._pendingGlobal.push({ key: key, plugin: plugin, start: start, mapping: mapping, data: data }); } else { - // Top to Bottom - - px = items[0].x; - py = items[0].y; + // Add it to the plugin store + PluginCache.registerCustom(key, plugin, mapping, data); - for (i = 1; i < items.length; i++) + if (start) { - // Current item - cur = items[i]; - - // Get current item x/y, to be passed to the next item in the list - cx = cur.x; - cy = cur.y; - - // Set current item to the previous items x/y - cur.x = px; - cur.y = py; - - // Set current as previous - px = cx; - py = cy; + return this.start(key); } - - // Update the head item to the new x/y coordinates - items[0].x = x; - items[0].y = y; } - } - else - { - px = items[0].x; - py = items[0].y; - - items[0].x = x; - items[0].y = y; - } - - // Return the final set of coordinates as they're effectively lost from the shift and may be needed - output.x = px; - output.y = py; - - return output; -}; - -module.exports = ShiftPosition; - - -/***/ }), -/* 717 */ -/***/ (function(module, exports, __webpack_require__) { + return null; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var ArrayShuffle = __webpack_require__(131); + for (var i = 0; i < list.length; i++) + { + var entry = list[i]; -/** - * Shuffles the array in place. The shuffled array is both modified and returned. - * - * @function Phaser.Actions.Shuffle - * @since 3.0.0 - * @see Phaser.Utils.Array.Shuffle - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var Shuffle = function (items) -{ - return ArrayShuffle(items); -}; + if (entry.key === key) + { + return i; + } + } -module.exports = Shuffle; + 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); -/***/ }), -/* 718 */ -/***/ (function(module, exports, __webpack_require__) { + if (idx !== -1) + { + return this.plugins[idx]; + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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); -var MathSmootherStep = __webpack_require__(183); + return (entry && entry.active); + }, -/** - * Smootherstep is a sigmoid-like interpolation and clamping function. - * - * The function depends on three parameters, the input x, the "left edge" and the "right edge", with the left edge being assumed smaller than the right edge. The function receives a real number x as an argument and returns 0 if x is less than or equal to the left edge, 1 if x is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial, between 0 and 1 otherwise. The slope of the smoothstep function is zero at both edges. This is convenient for creating a sequence of transitions using smoothstep to interpolate each segment as an alternative to using more sophisticated or expensive interpolation techniques. - * - * @function Phaser.Actions.SmootherStep - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {string} property - The property of the Game Object to interpolate. - * @param {number} min - The minimum interpolation value. - * @param {number} max - The maximum interpolation value. - * @param {boolean} [inc=false] - Should the values be incremented? `true` or set (`false`) - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var SmootherStep = function (items, property, min, max, inc) -{ - if (inc === undefined) { inc = false; } + /** + * 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 step = Math.abs(max - min) / items.length; - var i; + var entry = this.getEntry(runAs); - if (inc) - { - for (i = 0; i < items.length; i++) + // Plugin already running under this key? + if (entry && !entry.active) { - items[i][property] += MathSmootherStep(i * step, min, max); + // It exists, we just need to start it up again + entry.active = true; + entry.plugin.start(); } - } - else - { - for (i = 0; i < items.length; i++) + else if (!entry) { - items[i][property] = MathSmootherStep(i * step, min, max); + entry = this.createEntry(key, runAs); } - } - return items; -}; - -module.exports = SmootherStep; + 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); -/***/ }), -/* 719 */ -/***/ (function(module, exports, __webpack_require__) { + if (entry) + { + var instance = new entry.plugin(this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + entry = { + key: runAs, + plugin: instance, + active: true, + mapping: entry.mapping, + data: entry.data + }; -var MathSmoothStep = __webpack_require__(184); + this.plugins.push(entry); -/** - * Smoothstep is a sigmoid-like interpolation and clamping function. - * - * The function depends on three parameters, the input x, the "left edge" and the "right edge", with the left edge being assumed smaller than the right edge. The function receives a real number x as an argument and returns 0 if x is less than or equal to the left edge, 1 if x is greater than or equal to the right edge, and smoothly interpolates, using a Hermite polynomial, between 0 and 1 otherwise. The slope of the smoothstep function is zero at both edges. This is convenient for creating a sequence of transitions using smoothstep to interpolate each segment as an alternative to using more sophisticated or expensive interpolation techniques. - * - * @function Phaser.Actions.SmoothStep - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {string} property - The property of the Game Object to interpolate. - * @param {number} min - The minimum interpolation value. - * @param {number} max - The maximum interpolation value. - * @param {boolean} [inc=false] - Should the values be incremented? `true` or set (`false`) - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var SmoothStep = function (items, property, min, max, inc) -{ - if (inc === undefined) { inc = false; } + instance.init(entry.data); + instance.start(); + } - var step = Math.abs(max - min) / items.length; - var i; + return entry; + }, - if (inc) - { - for (i = 0; i < items.length; i++) - { - items[i][property] += MathSmoothStep(i * step, min, max); - } - } - else + /** + * 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) { - for (i = 0; i < items.length; i++) + var entry = this.getEntry(key); + + if (entry && entry.active) { - items[i][property] = MathSmoothStep(i * step, min, max); + entry.active = false; + entry.plugin.stop(); } - } - - return items; -}; - -module.exports = SmoothStep; - - -/***/ }), -/* 720 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * Takes an array of Game Objects and then modifies their `property` so the value equals, or is incremented, by the - * calculated spread value. - * - * The spread value is derived from the given `min` and `max` values and the total number of items in the array. - * - * For example, to cause an array of Sprites to change in alpha from 0 to 1 you could call: - * - * ```javascript - * Phaser.Actions.Spread(itemsArray, 'alpha', 0, 1); - * ``` - * - * @function Phaser.Actions.Spread - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {string} property - The property of the Game Object to spread. - * @param {number} min - The minimum value. - * @param {number} max - The maximum value. - * @param {boolean} [inc=false] - Should the values be incremented? `true` or set (`false`) - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that were passed to this Action. - */ -var Spread = function (items, property, min, max, inc) -{ - if (inc === undefined) { inc = false; } + /** + * 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 step = Math.abs(max - min) / items.length; - var i; + var entry = this.getEntry(key); - if (inc) - { - for (i = 0; i < items.length; i++) + if (entry) { - items[i][property] += i * step + min; + return entry.plugin; } - } - else - { - for (i = 0; i < items.length; i++) + else { - items[i][property] = i * step + min; - } - } - - return items; -}; - -module.exports = Spread; + var plugin = this.getClass(key); + if (plugin && autoStart) + { + entry = this.createEntry(key, key); -/***/ }), -/* 721 */ -/***/ (function(module, exports) { + return (entry) ? entry.plugin : null; + } + else if (plugin) + { + return plugin; + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return null; + }, -/** - * Takes an array of Game Objects and toggles the visibility of each one. - * Those previously `visible = false` will become `visible = true`, and vice versa. - * - * @function Phaser.Actions.ToggleVisible - * @since 3.0.0 - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var ToggleVisible = function (items) -{ - for (var i = 0; i < items.length; i++) + /** + * 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) { - items[i].visible = !items[i].visible; - } - - return items; -}; + return PluginCache.getCustomClass(key); + }, -module.exports = ToggleVisible; + /** + * 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); + } -/***/ }), -/* 722 */ -/***/ (function(module, exports, __webpack_require__) { + PluginCache.removeCustom(key); + }, -/** - * @author Richard Davey - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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); -var Wrap = __webpack_require__(68); + PluginCache.remove(key); + }, -/** - * Wrap each item's coordinates within a rectangle's area. - * - * @function Phaser.Actions.WrapInRectangle - * @since 3.0.0 - * @see Phaser.Math.Wrap - * - * @generic {Phaser.GameObjects.GameObject[]} G - [items,$return] - * - * @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action. - * @param {Phaser.Geom.Rectangle} rect - The rectangle. - * @param {number} [padding=0] - An amount added to each side of the rectangle during the operation. - * - * @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action. - */ -var WrapInRectangle = function (items, rect, padding) -{ - if (padding === undefined) + /** + * 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) { - padding = 0; - } + if (factoryCallback) + { + GameObjectFactory.register(key, factoryCallback); + } - for (var i = 0; i < items.length; i++) - { - var item = items[i]; + if (creatorCallback) + { + GameObjectCreator.register(key, creatorCallback); + } - item.x = Wrap(item.x, rect.left - padding, rect.right + padding); - item.y = Wrap(item.y, rect.top - padding, rect.bottom + padding); - } + return this; + }, - return items; -}; + /** + * 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; } -module.exports = WrapInRectangle; + if (removeFromFactory) + { + GameObjectFactory.remove(key); + } + if (removeFromCreator) + { + GameObjectCreator.remove(key); + } -/***/ }), -/* 723 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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); -/** - * @namespace Phaser.Animations - */ + if (addToScene && addToScene.sys.load) + { + addToScene.sys.load[key] = callback; + } + }, -module.exports = { + /** + * 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(); + } - Animation: __webpack_require__(185), - AnimationFrame: __webpack_require__(319), - AnimationManager: __webpack_require__(321), - AnimationState: __webpack_require__(164), - Events: __webpack_require__(132) + PluginCache.destroyCustomPlugins(); -}; + if (this.game.noReturn) + { + PluginCache.destroyCorePlugins(); + } + this.game = null; + this.plugins = []; + this.scenePlugins = []; + } -/***/ }), -/* 724 */ -/***/ (function(module, exports) { +}); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} +/* + * "Sometimes, the elegant implementation is just a function. + * Not a method. Not a class. Not a framework. Just a function." + * -- John Carmack */ -/** - * The Add Animation Event. - * - * This event is dispatched when a new animation is added to the global Animation Manager. - * - * This can happen either as a result of an animation instance being added to the Animation Manager, - * or the Animation Manager creating a new animation directly. - * - * @event Phaser.Animations.Events#ADD_ANIMATION - * @since 3.0.0 - * - * @param {string} key - The key of the Animation that was added to the global Animation Manager. - * @param {Phaser.Animations.Animation} animation - An instance of the newly created Animation. - */ -module.exports = 'add'; +module.exports = PluginManager; /***/ }), -/* 725 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 39283: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * The Animation Complete Event. - * - * This event is dispatched by a Sprite when an animation playing on it completes playback. - * This happens when the animation gets to the end of its sequence, factoring in any delays - * or repeats it may have to process. - * - * An animation that is set to loop, or repeat forever, will never fire this event, because - * it never actually completes. If you need to handle this, listen for the `ANIMATION_STOP` - * event instead, as this is emitted when the animation is stopped directly. - * - * Listen for it on the Sprite using `sprite.on('animationcomplete', listener)` - * - * The animation event flow is as follows: - * - * 1. `ANIMATION_START` - * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) - * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) - * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) - * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) - * - * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. - * - * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. - * - * @event Phaser.Animations.Events#ANIMATION_COMPLETE - * @since 3.50.0 - * - * @param {Phaser.Animations.Animation} animation - A reference to the Animation that completed. - * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. - * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation updated. - * @param {string} frameKey - The unique key of the Animation Frame within the Animation. - */ -module.exports = 'animationcomplete'; - - -/***/ }), -/* 726 */ -/***/ (function(module, exports) { +* @author Richard Davey +* @copyright 2013-2023 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License} +*/ -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +var BasePlugin = __webpack_require__(88257); +var Class = __webpack_require__(56694); +var SceneEvents = __webpack_require__(7599); /** - * The Animation Complete Dynamic Key Event. - * - * This event is dispatched by a Sprite when an animation playing on it completes playback. - * This happens when the animation gets to the end of its sequence, factoring in any delays - * or repeats it may have to process. - * - * An animation that is set to loop, or repeat forever, will never fire this event, because - * it never actually completes. If you need to handle this, listen for the `ANIMATION_STOP` - * event instead, as this is emitted when the animation is stopped directly. - * - * The difference between this and the `ANIMATION_COMPLETE` event is that this one has a - * dynamic event name that contains the name of the animation within it. For example, - * if you had an animation called `explode` you could listen for the completion of that - * specific animation by using: `sprite.on('animationcomplete-explode', listener)`. Or, if you - * wish to use types: `sprite.on(Phaser.Animations.Events.ANIMATION_COMPLETE_KEY + 'explode', listener)`. - * - * The animation event flow is as follows: - * - * 1. `ANIMATION_START` - * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) - * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) - * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) - * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) - * - * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. - * - * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. + * @classdesc + * A Scene Level Plugin is installed into every Scene and belongs to that Scene. + * It can listen for Scene events and respond to them. + * It can map itself to a Scene property, or into the Scene Systems, or both. * - * @event Phaser.Animations.Events#ANIMATION_COMPLETE_KEY - * @since 3.50.0 + * @class ScenePlugin + * @memberof Phaser.Plugins + * @extends Phaser.Plugins.BasePlugin + * @constructor + * @since 3.8.0 * - * @param {Phaser.Animations.Animation} animation - A reference to the Animation that completed. - * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. - * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation updated. - * @param {string} frameKey - The unique key of the Animation Frame within the Animation. - */ -module.exports = 'animationcomplete-'; - - -/***/ }), -/* 727 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin. + * @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Plugin Manager. + * @param {string} pluginKey - The key under which this plugin has been installed into the Scene Systems. */ +var ScenePlugin = new Class({ -/** - * The Animation Repeat Event. - * - * This event is dispatched by a Sprite when an animation repeats playing on it. - * This happens if the animation was created, or played, with a `repeat` value specified. - * - * An animation will repeat when it reaches the end of its sequence. - * - * Listen for it on the Sprite using `sprite.on('animationrepeat', listener)` - * - * The animation event flow is as follows: - * - * 1. `ANIMATION_START` - * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) - * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) - * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) - * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) - * - * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. - * - * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. - * - * @event Phaser.Animations.Events#ANIMATION_REPEAT - * @since 3.50.0 - * - * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has repeated. - * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. - * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation repeated. - * @param {string} frameKey - The unique key of the Animation Frame within the Animation. - */ -module.exports = 'animationrepeat'; + Extends: BasePlugin, + initialize: -/***/ }), -/* 728 */ -/***/ (function(module, exports) { + function ScenePlugin (scene, pluginManager, pluginKey) + { + BasePlugin.call(this, pluginManager); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * A reference to the Scene that has installed this plugin. + * Only set if it's a Scene Plugin, otherwise `null`. + * This property is only set when the plugin is instantiated and added to the Scene, not before. + * You can use it during the `boot` method. + * + * @name Phaser.Plugins.ScenePlugin#scene + * @type {?Phaser.Scene} + * @protected + * @since 3.8.0 + */ + this.scene = scene; -/** - * The Animation Restart Event. - * - * This event is dispatched by a Sprite when an animation restarts playing on it. - * This only happens when the `Sprite.anims.restart` method is called. - * - * Listen for it on the Sprite using `sprite.on('animationrestart', listener)` - * - * The animation event flow is as follows: - * - * 1. `ANIMATION_START` - * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) - * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) - * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) - * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) - * - * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. - * - * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. - * - * @event Phaser.Animations.Events#ANIMATION_RESTART - * @since 3.50.0 - * - * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has restarted. - * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. - * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation restarted. - * @param {string} frameKey - The unique key of the Animation Frame within the Animation. - */ -module.exports = 'animationrestart'; + /** + * A reference to the Scene Systems of the Scene that has installed this plugin. + * Only set if it's a Scene Plugin, otherwise `null`. + * This property is only set when the plugin is instantiated and added to the Scene, not before. + * You can use it during the `boot` method. + * + * @name Phaser.Plugins.ScenePlugin#systems + * @type {?Phaser.Scenes.Systems} + * @protected + * @since 3.8.0 + */ + this.systems = scene.sys; + /** + * The key under which this plugin was installed into the Scene Systems. + * + * This property is only set when the plugin is instantiated and added to the Scene, not before. + * You can use it during the `boot` method. + * + * @name Phaser.Plugins.ScenePlugin#pluginKey + * @type {string} + * @readonly + * @since 3.54.0 + */ + this.pluginKey = pluginKey; -/***/ }), -/* 729 */ -/***/ (function(module, exports) { + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * This method is called when the Scene boots. It is only ever called once. + * + * By this point the plugin properties `scene` and `systems` will have already been set. + * + * In here you can listen for {@link Phaser.Scenes.Events Scene events} and set-up whatever you need for this plugin to run. + * Here are the Scene events you can listen to: + * + * - start + * - ready + * - preupdate + * - update + * - postupdate + * - resize + * - pause + * - resume + * - sleep + * - wake + * - transitioninit + * - transitionstart + * - transitioncomplete + * - transitionout + * - shutdown + * - destroy + * + * At the very least you should offer a destroy handler for when the Scene closes down, i.e: + * + * ```javascript + * var eventEmitter = this.systems.events; + * eventEmitter.once('destroy', this.sceneDestroy, this); + * ``` + * + * @method Phaser.Plugins.ScenePlugin#boot + * @since 3.8.0 + */ + boot: function () + { + }, -/** - * The Animation Start Event. - * - * This event is dispatched by a Sprite when an animation starts playing on it. - * This happens when the animation is played, factoring in any delay that may have been specified. - * This event happens after the delay has expired and prior to the first update event. - * - * Listen for it on the Sprite using `sprite.on('animationstart', listener)` - * - * The animation event flow is as follows: - * - * 1. `ANIMATION_START` - * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) - * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) - * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) - * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) - * - * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. - * - * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. - * - * @event Phaser.Animations.Events#ANIMATION_START - * @since 3.50.0 - * - * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has started. - * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. - * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation started. - * @param {string} frameKey - The unique key of the Animation Frame within the Animation. - */ -module.exports = 'animationstart'; + /** + * Game instance has been destroyed. + * + * You must release everything in here, all references, all objects, free it all up. + * + * @method Phaser.Plugins.ScenePlugin#destroy + * @since 3.8.0 + */ + destroy: function () + { + this.pluginManager = null; + this.game = null; + this.scene = null; + this.systems = null; + } + +}); + +module.exports = ScenePlugin; /***/ }), -/* 730 */ -/***/ (function(module, exports) { + +/***/ 45615: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Animation Stop Event. - * - * This event is dispatched by a Sprite when an animation is stopped on it. An animation - * will only be stopeed if a method such as `Sprite.stop` or `Sprite.anims.stopAfterDelay` - * is called. It can also be emitted if a new animation is started before the current one completes. - * - * Listen for it on the Sprite using `sprite.on('animationstop', listener)` - * - * The animation event flow is as follows: - * - * 1. `ANIMATION_START` - * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) - * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) - * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) - * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) - * - * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. - * - * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. - * - * @event Phaser.Animations.Events#ANIMATION_STOP - * @since 3.50.0 - * - * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has stopped. - * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. - * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation stopped. - * @param {string} frameKey - The unique key of the Animation Frame within the Animation. + * @namespace Phaser.Plugins */ -module.exports = 'animationstop'; + +module.exports = { + + BasePlugin: __webpack_require__(88257), + DefaultPlugins: __webpack_require__(18360), + PluginCache: __webpack_require__(91963), + PluginManager: __webpack_require__(49274), + ScenePlugin: __webpack_require__(39283) + +}; /***/ }), -/* 731 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 75205: +/***/ (() => { -/** - * The Animation Update Event. - * - * This event is dispatched by a Sprite when an animation playing on it updates. This happens when the animation changes frame. - * An animation will change frame based on the frme rate and other factors like `timeScale` and `delay`. It can also change - * frame when stopped or restarted. - * - * Listen for it on the Sprite using `sprite.on('animationupdate', listener)` - * - * If an animation is playing faster than the game frame-rate can handle, it's entirely possible for it to emit several - * update events in a single game frame, so please be aware of this in your code. The **final** event received that frame - * is the one that is rendered to the game. - * - * The animation event flow is as follows: - * - * 1. `ANIMATION_START` - * 2. `ANIMATION_UPDATE` (repeated for however many frames the animation has) - * 3. `ANIMATION_REPEAT` (only if the animation is set to repeat, it then emits more update events after this) - * 4. `ANIMATION_COMPLETE` (only if there is a finite, or zero, repeat count) - * 5. `ANIMATION_COMPLETE_KEY` (only if there is a finite, or zero, repeat count) - * - * If the animation is stopped directly, the `ANIMATION_STOP` event is dispatched instead of `ANIMATION_COMPLETE`. - * - * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. - * - * @event Phaser.Animations.Events#ANIMATION_UPDATE - * @since 3.50.0 - * - * @param {Phaser.Animations.Animation} animation - A reference to the Animation that has updated. - * @param {Phaser.Animations.AnimationFrame} frame - The current Animation Frame of the Animation. - * @param {Phaser.GameObjects.Sprite} gameObject - A reference to the Game Object on which the animation updated. - * @param {string} frameKey - The unique key of the Animation Frame within the Animation. - */ -module.exports = 'animationupdate'; +// From https://github.com/ThaUnknown/rvfc-polyfill + +if (!('requestVideoFrameCallback' in HTMLVideoElement.prototype) && 'getVideoPlaybackQuality' in HTMLVideoElement.prototype) +{ + HTMLVideoElement.prototype._rvfcpolyfillmap = {} + HTMLVideoElement.prototype.requestVideoFrameCallback = function (callback) { + const handle = performance.now() + const quality = this.getVideoPlaybackQuality() + const baseline = this.mozPresentedFrames || this.mozPaintedFrames || quality.totalVideoFrames - quality.droppedVideoFrames + + const check = (old, now) => { + const newquality = this.getVideoPlaybackQuality() + const presentedFrames = this.mozPresentedFrames || this.mozPaintedFrames || newquality.totalVideoFrames - newquality.droppedVideoFrames + if (presentedFrames > baseline) { + const processingDuration = this.mozFrameDelay || (newquality.totalFrameDelay - quality.totalFrameDelay) || 0 + const timediff = now - old // HighRes diff + callback(now, { + presentationTime: now + processingDuration * 1000, + expectedDisplayTime: now + timediff, + width: this.videoWidth, + height: this.videoHeight, + mediaTime: Math.max(0, this.currentTime || 0) + timediff / 1000, + presentedFrames, + processingDuration + }) + delete this._rvfcpolyfillmap[handle] + } else { + this._rvfcpolyfillmap[handle] = requestAnimationFrame(newer => check(now, newer)) + } + } + this._rvfcpolyfillmap[handle] = requestAnimationFrame(newer => check(handle, newer)) + return handle + } + + HTMLVideoElement.prototype.cancelVideoFrameCallback = function (handle) { + cancelAnimationFrame(this._rvfcpolyfillmap[handle]) + delete this._rvfcpolyfillmap[handle] + } +} /***/ }), -/* 732 */ -/***/ (function(module, exports) { + +/***/ 95723: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Pause All Animations Event. - * - * This event is dispatched when the global Animation Manager is told to pause. - * - * When this happens all current animations will stop updating, although it doesn't necessarily mean - * that the game has paused as well. + * Phaser Blend Modes. * - * @event Phaser.Animations.Events#PAUSE_ALL + * @namespace Phaser.BlendModes * @since 3.0.0 */ -module.exports = 'pauseall'; +module.exports = { -/***/ }), -/* 733 */ -/***/ (function(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, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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, -/** - * The Remove Animation Event. - * - * This event is dispatched when an animation is removed from the global Animation Manager. - * - * @event Phaser.Animations.Events#REMOVE_ANIMATION - * @since 3.0.0 - * - * @param {string} key - The key of the Animation that was removed from the global Animation Manager. - * @param {Phaser.Animations.Animation} animation - An instance of the removed Animation. - */ -module.exports = 'remove'; + /** + * 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, -/***/ }), -/* 734 */ -/***/ (function(module, exports) { + /** + * 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, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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, -/** - * The Resume All Animations Event. - * - * This event is dispatched when the global Animation Manager resumes, having been previously paused. - * - * When this happens all current animations will continue updating again. - * - * @event Phaser.Animations.Events#RESUME_ALL - * @since 3.0.0 - */ -module.exports = 'resumeall'; + /** + * 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, -/***/ }), -/* 735 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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, -/** - * @namespace Phaser.Cache - */ + /** + * 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, -module.exports = { + /** + * 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, - BaseCache: __webpack_require__(323), - CacheManager: __webpack_require__(325), - Events: __webpack_require__(324) + /** + * 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, -/***/ }), -/* 736 */ -/***/ (function(module, exports) { + /** + * 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, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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, -/** - * The Cache Add Event. - * - * This event is dispatched by any Cache that extends the BaseCache each time a new object is added to it. - * - * @event Phaser.Cache.Events#ADD - * @since 3.0.0 - * - * @param {Phaser.Cache.BaseCache} cache - The cache to which the object was added. - * @param {string} key - The key of the object added to the cache. - * @param {*} object - A reference to the object that was added to the cache. - */ -module.exports = 'add'; + /** + * 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, -/***/ }), -/* 737 */ -/***/ (function(module, exports) { + /** + * 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, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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, -/** - * The Cache Remove Event. - * - * This event is dispatched by any Cache that extends the BaseCache each time an object is removed from it. - * - * @event Phaser.Cache.Events#REMOVE - * @since 3.0.0 - * - * @param {Phaser.Cache.BaseCache} cache - The cache from which the object was removed. - * @param {string} key - The key of the object removed from the cache. - * @param {*} object - A reference to the object that was removed from the cache. - */ -module.exports = 'remove'; + /** + * 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, -/***/ }), -/* 738 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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, -/** - * @namespace Phaser.Cameras - */ + /** + * 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, -/** - * @namespace Phaser.Types.Cameras - */ + /** + * 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, -module.exports = { + /** + * 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, - Controls: __webpack_require__(739), - Scene2D: __webpack_require__(742) + /** + * 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 }; /***/ }), -/* 739 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 27394: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Cameras.Controls + * Phaser Scale Modes. + * + * @namespace Phaser.ScaleModes + * @since 3.0.0 */ -module.exports = { +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, - FixedKeyControl: __webpack_require__(740), - SmoothedKeyControl: __webpack_require__(741) + /** + * Nearest Scale Mode. + * + * @name Phaser.ScaleModes.NEAREST + * @type {number} + * @readonly + * @since 3.0.0 + */ + NEAREST: 1 }; +module.exports = ScaleModes; + /***/ }), -/* 740 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 91135: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var GetValue = __webpack_require__(6); +var CameraEvents = __webpack_require__(89787); +var CanvasSnapshot = __webpack_require__(61840); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(86459); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(81044); +var GetBlendModes = __webpack_require__(32834); +var ScaleEvents = __webpack_require__(40444); +var TextureEvents = __webpack_require__(38203); +var TransformMatrix = __webpack_require__(69360); /** * @classdesc - * A Fixed Key Camera Control. - * - * This allows you to control the movement and zoom of a camera using the defined keys. - * - * ```javascript - * var camControl = new FixedKeyControl({ - * camera: this.cameras.main, - * left: cursors.left, - * right: cursors.right, - * speed: float OR { x: 0, y: 0 } - * }); - * ``` - * - * Movement is precise and has no 'smoothing' applied to it. - * - * You must call the `update` method of this controller every frame. + * The Canvas Renderer is responsible for managing 2D canvas rendering contexts, + * including the one used by the Games canvas. It tracks the internal state of a + * given context and can renderer textured Game Objects to it, taking into + * account alpha, blending, and scaling. * - * @class FixedKeyControl - * @memberof Phaser.Cameras.Controls + * @class CanvasRenderer + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Renderer.Canvas * @constructor * @since 3.0.0 * - * @param {Phaser.Types.Cameras.Controls.FixedKeyControlConfig} config - The Fixed Key Control configuration object. + * @param {Phaser.Game} game - The Phaser Game instance that owns this renderer. */ -var FixedKeyControl = new Class({ +var CanvasRenderer = new Class({ + + Extends: EventEmitter, initialize: - function FixedKeyControl (config) + function CanvasRenderer (game) { + EventEmitter.call(this); + + var gameConfig = game.config; + /** - * The Camera that this Control will update. + * The local configuration settings of the CanvasRenderer. * - * @name Phaser.Cameras.Controls.FixedKeyControl#camera - * @type {?Phaser.Cameras.Scene2D.Camera} - * @default null + * @name Phaser.Renderer.Canvas.CanvasRenderer#config + * @type {object} * @since 3.0.0 */ - this.camera = GetValue(config, 'camera', null); + this.config = { + clearBeforeRender: gameConfig.clearBeforeRender, + backgroundColor: gameConfig.backgroundColor, + antialias: gameConfig.antialias, + roundPixels: gameConfig.roundPixels + }; /** - * The Key to be pressed that will move the Camera left. + * The Phaser Game instance that owns this renderer. * - * @name Phaser.Cameras.Controls.FixedKeyControl#left - * @type {?Phaser.Input.Keyboard.Key} - * @default null + * @name Phaser.Renderer.Canvas.CanvasRenderer#game + * @type {Phaser.Game} * @since 3.0.0 */ - this.left = GetValue(config, 'left', null); + this.game = game; /** - * The Key to be pressed that will move the Camera right. + * A constant which allows the renderer to be easily identified as a Canvas Renderer. * - * @name Phaser.Cameras.Controls.FixedKeyControl#right - * @type {?Phaser.Input.Keyboard.Key} - * @default null + * @name Phaser.Renderer.Canvas.CanvasRenderer#type + * @type {number} * @since 3.0.0 */ - this.right = GetValue(config, 'right', null); + this.type = CONST.CANVAS; /** - * The Key to be pressed that will move the Camera up. + * The total number of Game Objects which were rendered in a frame. * - * @name Phaser.Cameras.Controls.FixedKeyControl#up - * @type {?Phaser.Input.Keyboard.Key} - * @default null + * @name Phaser.Renderer.Canvas.CanvasRenderer#drawCount + * @type {number} + * @default 0 * @since 3.0.0 */ - this.up = GetValue(config, 'up', null); + this.drawCount = 0; /** - * The Key to be pressed that will move the Camera down. + * The width of the canvas being rendered to. * - * @name Phaser.Cameras.Controls.FixedKeyControl#down - * @type {?Phaser.Input.Keyboard.Key} - * @default null + * @name Phaser.Renderer.Canvas.CanvasRenderer#width + * @type {number} * @since 3.0.0 */ - this.down = GetValue(config, 'down', null); + this.width = 0; /** - * The Key to be pressed that will zoom the Camera in. + * The height of the canvas being rendered to. * - * @name Phaser.Cameras.Controls.FixedKeyControl#zoomIn - * @type {?Phaser.Input.Keyboard.Key} - * @default null + * @name Phaser.Renderer.Canvas.CanvasRenderer#height + * @type {number} * @since 3.0.0 */ - this.zoomIn = GetValue(config, 'zoomIn', null); + this.height = 0; /** - * The Key to be pressed that will zoom the Camera out. + * The canvas element which the Game uses. * - * @name Phaser.Cameras.Controls.FixedKeyControl#zoomOut - * @type {?Phaser.Input.Keyboard.Key} - * @default null + * @name Phaser.Renderer.Canvas.CanvasRenderer#gameCanvas + * @type {HTMLCanvasElement} * @since 3.0.0 */ - this.zoomOut = GetValue(config, 'zoomOut', null); + this.gameCanvas = game.canvas; + + var contextOptions = { + alpha: game.config.transparent, + desynchronized: game.config.desynchronized, + willReadFrequently: false + }; /** - * The speed at which the camera will zoom if the `zoomIn` or `zoomOut` keys are pressed. + * The canvas context used to render all Cameras in all Scenes during the game loop. * - * @name Phaser.Cameras.Controls.FixedKeyControl#zoomSpeed - * @type {number} - * @default 0.01 + * @name Phaser.Renderer.Canvas.CanvasRenderer#gameContext + * @type {CanvasRenderingContext2D} * @since 3.0.0 */ - this.zoomSpeed = GetValue(config, 'zoomSpeed', 0.01); + this.gameContext = (gameConfig.context) ? gameConfig.context : this.gameCanvas.getContext('2d', contextOptions); /** - * The smallest zoom value the camera will reach when zoomed out. + * The canvas context currently used by the CanvasRenderer for all rendering operations. * - * @name Phaser.Cameras.Controls.FixedKeyControl#minZoom - * @type {number} - * @default 0.001 - * @since 3.53.0 + * @name Phaser.Renderer.Canvas.CanvasRenderer#currentContext + * @type {CanvasRenderingContext2D} + * @since 3.0.0 */ - this.minZoom = GetValue(config, 'minZoom', 0.001); + this.currentContext = this.gameContext; /** - * The largest zoom value the camera will reach when zoomed in. + * Should the Canvas use Image Smoothing or not when drawing Sprites? * - * @name Phaser.Cameras.Controls.FixedKeyControl#maxZoom - * @type {number} - * @default 1000 - * @since 3.53.0 + * @name Phaser.Renderer.Canvas.CanvasRenderer#antialias + * @type {boolean} + * @since 3.20.0 */ - this.maxZoom = GetValue(config, 'maxZoom', 1000); + this.antialias = game.config.antialias; /** - * The horizontal speed the camera will move. + * The blend modes supported by the Canvas Renderer. * - * @name Phaser.Cameras.Controls.FixedKeyControl#speedX - * @type {number} - * @default 0 + * This object maps the {@link Phaser.BlendModes} to canvas compositing operations. + * + * @name Phaser.Renderer.Canvas.CanvasRenderer#blendModes + * @type {array} * @since 3.0.0 */ - this.speedX = 0; + this.blendModes = GetBlendModes(); /** - * The vertical speed the camera will move. + * Details about the currently scheduled snapshot. * - * @name Phaser.Cameras.Controls.FixedKeyControl#speedY - * @type {number} - * @default 0 - * @since 3.0.0 + * If a non-null `callback` is set in this object, a snapshot of the canvas will be taken after the current frame is fully rendered. + * + * @name Phaser.Renderer.Canvas.CanvasRenderer#snapshotState + * @type {Phaser.Types.Renderer.Snapshot.SnapshotState} + * @since 3.16.0 */ - this.speedY = 0; + this.snapshotState = { + x: 0, + y: 0, + width: 1, + height: 1, + getPixel: false, + callback: null, + type: 'image/png', + encoder: 0.92 + }; - var speed = GetValue(config, 'speed', null); + /** + * A temporary Transform Matrix, re-used internally during batching. + * + * @name Phaser.Renderer.Canvas.CanvasRenderer#_tempMatrix1 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.11.0 + */ + this._tempMatrix1 = new TransformMatrix(); - if (typeof speed === 'number') - { - this.speedX = speed; - this.speedY = speed; - } - else - { - this.speedX = GetValue(config, 'speed.x', 0); - this.speedY = GetValue(config, 'speed.y', 0); - } + /** + * A temporary Transform Matrix, re-used internally during batching. + * + * @name Phaser.Renderer.Canvas.CanvasRenderer#_tempMatrix2 + * @private + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.11.0 + */ + this._tempMatrix2 = new TransformMatrix(); /** - * Internal property to track the current zoom level. + * A temporary Transform Matrix, re-used internally during batching. * - * @name Phaser.Cameras.Controls.FixedKeyControl#_zoom - * @type {number} + * @name Phaser.Renderer.Canvas.CanvasRenderer#_tempMatrix3 * @private - * @default 0 - * @since 3.0.0 + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.11.0 */ - this._zoom = 0; + this._tempMatrix3 = new TransformMatrix(); /** - * A flag controlling if the Controls will update the Camera or not. + * Has this renderer fully booted yet? * - * @name Phaser.Cameras.Controls.FixedKeyControl#active + * @name Phaser.Renderer.Canvas.CanvasRenderer#isBooted * @type {boolean} - * @since 3.0.0 + * @since 3.50.0 */ - this.active = (this.camera !== null); + this.isBooted = false; + + this.init(); }, /** - * Starts the Key Control running, providing it has been linked to a camera. + * Prepares the game canvas for rendering. * - * @method Phaser.Cameras.Controls.FixedKeyControl#start + * @method Phaser.Renderer.Canvas.CanvasRenderer#init * @since 3.0.0 + */ + init: function () + { + this.game.textures.once(TextureEvents.READY, this.boot, this); + }, + + /** + * Internal boot handler. * - * @return {this} This Key Control instance. + * @method Phaser.Renderer.Canvas.CanvasRenderer#boot + * @private + * @since 3.50.0 */ - start: function () + boot: function () { - this.active = (this.camera !== null); + var game = this.game; - return this; + var baseSize = game.scale.baseSize; + + this.width = baseSize.width; + this.height = baseSize.height; + + this.isBooted = true; + + game.scale.on(ScaleEvents.RESIZE, this.onResize, this); + + this.resize(baseSize.width, baseSize.height); }, /** - * Stops this Key Control from running. Call `start` to start it again. + * The event handler that manages the `resize` event dispatched by the Scale Manager. * - * @method Phaser.Cameras.Controls.FixedKeyControl#stop + * @method Phaser.Renderer.Canvas.CanvasRenderer#onResize + * @since 3.16.0 + * + * @param {Phaser.Structs.Size} gameSize - The default Game Size object. This is the un-modified game dimensions. + * @param {Phaser.Structs.Size} baseSize - The base Size object. The game dimensions multiplied by the resolution. The canvas width / height values match this. + */ + onResize: function (gameSize, baseSize) + { + // Has the underlying canvas size changed? + if (baseSize.width !== this.width || baseSize.height !== this.height) + { + this.resize(baseSize.width, baseSize.height); + } + }, + + /** + * Resize the main game canvas. + * + * @method Phaser.Renderer.Canvas.CanvasRenderer#resize + * @fires Phaser.Renderer.Events#RESIZE * @since 3.0.0 * - * @return {this} This Key Control instance. + * @param {number} [width] - The new width of the renderer. + * @param {number} [height] - The new height of the renderer. */ - stop: function () + resize: function (width, height) { - this.active = false; + this.width = width; + this.height = height; - return this; + this.emit(Events.RESIZE, width, height); }, /** - * Binds this Key Control to a camera. + * Resets the transformation matrix of the current context to the identity matrix, thus resetting any transformation. * - * @method Phaser.Cameras.Controls.FixedKeyControl#setCamera + * @method Phaser.Renderer.Canvas.CanvasRenderer#resetTransform + * @since 3.0.0 + */ + resetTransform: function () + { + this.currentContext.setTransform(1, 0, 0, 1, 0, 0); + }, + + /** + * Sets the blend mode (compositing operation) of the current context. + * + * @method Phaser.Renderer.Canvas.CanvasRenderer#setBlendMode * @since 3.0.0 * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to bind this Key Control to. + * @param {string} blendMode - The new blend mode which should be used. * - * @return {this} This Key Control instance. + * @return {this} This CanvasRenderer object. */ - setCamera: function (camera) + setBlendMode: function (blendMode) { - this.camera = camera; + this.currentContext.globalCompositeOperation = blendMode; return this; }, /** - * Applies the results of pressing the control keys to the Camera. + * Changes the Canvas Rendering Context that all draw operations are performed against. * - * You must call this every step, it is not called automatically. + * @method Phaser.Renderer.Canvas.CanvasRenderer#setContext + * @since 3.12.0 * - * @method Phaser.Cameras.Controls.FixedKeyControl#update - * @since 3.0.0 + * @param {?CanvasRenderingContext2D} [ctx] - The new Canvas Rendering Context to draw everything to. Leave empty to reset to the Game Canvas. * - * @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 {this} The Canvas Renderer instance. */ - update: function (delta) + setContext: function (ctx) { - if (!this.active) - { - return; - } - - if (delta === undefined) { delta = 1; } - - var cam = this.camera; - - if (this.up && this.up.isDown) - { - cam.scrollY -= ((this.speedY * delta) | 0); - } - else if (this.down && this.down.isDown) - { - cam.scrollY += ((this.speedY * delta) | 0); - } - - if (this.left && this.left.isDown) - { - cam.scrollX -= ((this.speedX * delta) | 0); - } - else if (this.right && this.right.isDown) - { - cam.scrollX += ((this.speedX * delta) | 0); - } - - // Camera zoom - - if (this.zoomIn && this.zoomIn.isDown) - { - cam.zoom -= this.zoomSpeed; - - if (cam.zoom < this.minZoom) - { - cam.zoom = this.minZoom; - } - } - else if (this.zoomOut && this.zoomOut.isDown) - { - cam.zoom += this.zoomSpeed; + this.currentContext = (ctx) ? ctx : this.gameContext; - if (cam.zoom > this.maxZoom) - { - cam.zoom = this.maxZoom; - } - } + return this; }, /** - * Destroys this Key Control. + * Sets the global alpha of the current context. * - * @method Phaser.Cameras.Controls.FixedKeyControl#destroy + * @method Phaser.Renderer.Canvas.CanvasRenderer#setAlpha * @since 3.0.0 + * + * @param {number} alpha - The new alpha to use, where 0 is fully transparent and 1 is fully opaque. + * + * @return {this} This CanvasRenderer object. */ - destroy: function () + setAlpha: function (alpha) { - this.camera = null; - - this.left = null; - this.right = null; - this.up = null; - this.down = null; - - this.zoomIn = null; - this.zoomOut = null; - } - -}); - -module.exports = FixedKeyControl; - + this.currentContext.globalAlpha = alpha; -/***/ }), -/* 741 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Called at the start of the render loop. + * + * @method Phaser.Renderer.Canvas.CanvasRenderer#preRender + * @fires Phaser.Renderer.Events#PRE_RENDER + * @since 3.0.0 + */ + preRender: function () + { + var ctx = this.gameContext; + var config = this.config; -var Class = __webpack_require__(0); -var GetValue = __webpack_require__(6); + var width = this.width; + var height = this.height; -/** - * @classdesc - * A Smoothed Key Camera Control. - * - * This allows you to control the movement and zoom of a camera using the defined keys. - * Unlike the Fixed Camera Control you can also provide physics values for acceleration, drag and maxSpeed for smoothing effects. - * - * ```javascript - * var controlConfig = { - * camera: this.cameras.main, - * left: cursors.left, - * right: cursors.right, - * up: cursors.up, - * down: cursors.down, - * zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q), - * zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E), - * zoomSpeed: 0.02, - * acceleration: 0.06, - * drag: 0.0005, - * maxSpeed: 1.0 - * }; - * ``` - * - * You must call the `update` method of this controller every frame. - * - * @class SmoothedKeyControl - * @memberof Phaser.Cameras.Controls - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Types.Cameras.Controls.SmoothedKeyControlConfig} config - The Smoothed Key Control configuration object. - */ -var SmoothedKeyControl = new Class({ + ctx.globalAlpha = 1; + ctx.globalCompositeOperation = 'source-over'; + ctx.setTransform(1, 0, 0, 1, 0, 0); - initialize: + if (config.clearBeforeRender) + { + ctx.clearRect(0, 0, width, height); - function SmoothedKeyControl (config) - { - /** - * The Camera that this Control will update. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#camera - * @type {?Phaser.Cameras.Scene2D.Camera} - * @default null - * @since 3.0.0 - */ - this.camera = GetValue(config, 'camera', null); + if (!config.transparent) + { + ctx.fillStyle = config.backgroundColor.rgba; + ctx.fillRect(0, 0, width, height); + } + } - /** - * The Key to be pressed that will move the Camera left. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#left - * @type {?Phaser.Input.Keyboard.Key} - * @default null - * @since 3.0.0 - */ - this.left = GetValue(config, 'left', null); + ctx.save(); - /** - * The Key to be pressed that will move the Camera right. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#right - * @type {?Phaser.Input.Keyboard.Key} - * @default null - * @since 3.0.0 - */ - this.right = GetValue(config, 'right', null); + this.drawCount = 0; - /** - * The Key to be pressed that will move the Camera up. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#up - * @type {?Phaser.Input.Keyboard.Key} - * @default null - * @since 3.0.0 - */ - this.up = GetValue(config, 'up', null); + this.emit(Events.PRE_RENDER); + }, - /** - * The Key to be pressed that will move the Camera down. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#down - * @type {?Phaser.Input.Keyboard.Key} - * @default null - * @since 3.0.0 - */ - this.down = GetValue(config, 'down', null); + /** + * The core render step for a Scene Camera. + * + * Iterates through the given array of Game Objects and renders them with the given Camera. + * + * This is called by the `CameraManager.render` method. The Camera Manager instance belongs to a Scene, and is invoked + * by the Scene Systems.render method. + * + * This method is not called if `Camera.visible` is `false`, or `Camera.alpha` is zero. + * + * @method Phaser.Renderer.Canvas.CanvasRenderer#render + * @fires Phaser.Renderer.Events#RENDER + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to render. + * @param {Phaser.GameObjects.GameObject[]} children - An array of filtered Game Objects that can be rendered by the given Camera. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera to render with. + */ + render: function (scene, children, camera) + { + var childCount = children.length; - /** - * The Key to be pressed that will zoom the Camera in. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#zoomIn - * @type {?Phaser.Input.Keyboard.Key} - * @default null - * @since 3.0.0 - */ - this.zoomIn = GetValue(config, 'zoomIn', null); + this.emit(Events.RENDER, scene, camera); - /** - * The Key to be pressed that will zoom the Camera out. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#zoomOut - * @type {?Phaser.Input.Keyboard.Key} - * @default null - * @since 3.0.0 - */ - this.zoomOut = GetValue(config, 'zoomOut', null); + var cx = camera.x; + var cy = camera.y; + var cw = camera.width; + var ch = camera.height; - /** - * The speed at which the camera will zoom if the `zoomIn` or `zoomOut` keys are pressed. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#zoomSpeed - * @type {number} - * @default 0.01 - * @since 3.0.0 - */ - this.zoomSpeed = GetValue(config, 'zoomSpeed', 0.01); + var ctx = (camera.renderToTexture) ? camera.context : scene.sys.context; - /** - * The smallest zoom value the camera will reach when zoomed out. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#minZoom - * @type {number} - * @default 0.001 - * @since 3.53.0 - */ - this.minZoom = GetValue(config, 'minZoom', 0.001); + // Save context pre-clip + ctx.save(); - /** - * The largest zoom value the camera will reach when zoomed in. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#maxZoom - * @type {number} - * @default 1000 - * @since 3.53.0 - */ - this.maxZoom = GetValue(config, 'maxZoom', 1000); + if (this.game.scene.customViewports) + { + ctx.beginPath(); + ctx.rect(cx, cy, cw, ch); + ctx.clip(); + } - /** - * The horizontal acceleration the camera will move. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#accelX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.accelX = 0; + camera.emit(CameraEvents.PRE_RENDER, camera); - /** - * The vertical acceleration the camera will move. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#accelY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.accelY = 0; + this.currentContext = ctx; - var accel = GetValue(config, 'acceleration', null); + var mask = camera.mask; - if (typeof accel === 'number') + if (mask) { - this.accelX = accel; - this.accelY = accel; + mask.preRenderCanvas(this, null, camera._maskCamera); } - else + + if (!camera.transparent) { - this.accelX = GetValue(config, 'acceleration.x', 0); - this.accelY = GetValue(config, 'acceleration.y', 0); + ctx.fillStyle = camera.backgroundColor.rgba; + ctx.fillRect(cx, cy, cw, ch); } - /** - * The horizontal drag applied to the camera when it is moving. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#dragX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.dragX = 0; + ctx.globalAlpha = camera.alpha; - /** - * The vertical drag applied to the camera when it is moving. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#dragY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.dragY = 0; + ctx.globalCompositeOperation = 'source-over'; - var drag = GetValue(config, 'drag', null); + this.drawCount += childCount; - if (typeof drag === 'number') + if (camera.renderToTexture) { - this.dragX = drag; - this.dragY = drag; + camera.emit(CameraEvents.PRE_RENDER, camera); } - else + + camera.matrix.copyToContext(ctx); + + for (var i = 0; i < childCount; i++) { - this.dragX = GetValue(config, 'drag.x', 0); - this.dragY = GetValue(config, 'drag.y', 0); + var child = children[i]; + + if (child.mask) + { + child.mask.preRenderCanvas(this, child, camera); + } + + child.renderCanvas(this, child, camera); + + if (child.mask) + { + child.mask.postRenderCanvas(this, child, camera); + } } - /** - * The maximum horizontal speed the camera will move. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#maxSpeedX - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.maxSpeedX = 0; + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.globalCompositeOperation = 'source-over'; + ctx.globalAlpha = 1; - /** - * The maximum vertical speed the camera will move. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#maxSpeedY - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.maxSpeedY = 0; + camera.flashEffect.postRenderCanvas(ctx); + camera.fadeEffect.postRenderCanvas(ctx); - var maxSpeed = GetValue(config, 'maxSpeed', null); + camera.dirty = false; - if (typeof maxSpeed === 'number') + if (mask) { - this.maxSpeedX = maxSpeed; - this.maxSpeedY = maxSpeed; + mask.postRenderCanvas(this); } - else + + // Restore pre-clip context + ctx.restore(); + + if (camera.renderToTexture) { - this.maxSpeedX = GetValue(config, 'maxSpeed.x', 0); - this.maxSpeedY = GetValue(config, 'maxSpeed.y', 0); + camera.emit(CameraEvents.POST_RENDER, camera); + + if (camera.renderToGame) + { + scene.sys.context.drawImage(camera.canvas, cx, cy); + } } - /** - * Internal property to track the speed of the control. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#_speedX - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._speedX = 0; + camera.emit(CameraEvents.POST_RENDER, camera); + }, - /** - * Internal property to track the speed of the control. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#_speedY - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._speedY = 0; + /** + * Restores the game context's global settings and takes a snapshot if one is scheduled. + * + * The post-render step happens after all Cameras in all Scenes have been rendered. + * + * @method Phaser.Renderer.Canvas.CanvasRenderer#postRender + * @fires Phaser.Renderer.Events#POST_RENDER + * @since 3.0.0 + */ + postRender: function () + { + var ctx = this.gameContext; - /** - * Internal property to track the zoom of the control. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#_zoom - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._zoom = 0; + ctx.restore(); - /** - * A flag controlling if the Controls will update the Camera or not. - * - * @name Phaser.Cameras.Controls.SmoothedKeyControl#active - * @type {boolean} - * @since 3.0.0 - */ - this.active = (this.camera !== null); + this.emit(Events.POST_RENDER); + + var state = this.snapshotState; + + if (state.callback) + { + CanvasSnapshot(this.gameCanvas, state); + + state.callback = null; + } }, /** - * Starts the Key Control running, providing it has been linked to a camera. + * Takes a snapshot of the given area of the given canvas. * - * @method Phaser.Cameras.Controls.SmoothedKeyControl#start - * @since 3.0.0 + * Unlike the other snapshot methods, this one is processed immediately and doesn't wait for the next render. * - * @return {this} This Key Control instance. + * Snapshots work by creating an Image object from the canvas data, this is a blocking process, which gets + * more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * + * @method Phaser.Renderer.Canvas.CanvasRenderer#snapshotCanvas + * @since 3.19.0 + * + * @param {HTMLCanvasElement} canvas - The canvas to grab from. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {boolean} [getPixel=false] - Grab a single pixel as a Color object, or an area as an Image object? + * @param {number} [x=0] - The x coordinate to grab from. + * @param {number} [y=0] - The y coordinate to grab from. + * @param {number} [width=canvas.width] - The width of the area to grab. + * @param {number} [height=canvas.height] - The height of the area to grab. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This Canvas Renderer. */ - start: function () + snapshotCanvas: function (canvas, callback, getPixel, x, y, width, height, type, encoderOptions) { - this.active = (this.camera !== null); + if (getPixel === undefined) { getPixel = false; } + + this.snapshotArea(x, y, width, height, callback, type, encoderOptions); + + var state = this.snapshotState; + + state.getPixel = getPixel; + + CanvasSnapshot(canvas, state); + + state.callback = null; return this; }, /** - * Stops this Key Control from running. Call `start` to start it again. + * Schedules a snapshot of the entire game viewport to be taken after the current frame is rendered. * - * @method Phaser.Cameras.Controls.SmoothedKeyControl#stop + * To capture a specific area see the `snapshotArea` method. To capture a specific pixel, see `snapshotPixel`. + * + * Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then + * calling this method will override it. + * + * Snapshots work by creating an Image object from the canvas data, this is a blocking process, which gets + * more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * + * @method Phaser.Renderer.Canvas.CanvasRenderer#snapshot * @since 3.0.0 * - * @return {this} This Key Control instance. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This WebGL Renderer. */ - stop: function () + snapshot: function (callback, type, encoderOptions) { - this.active = false; + return this.snapshotArea(0, 0, this.gameCanvas.width, this.gameCanvas.height, callback, type, encoderOptions); + }, + + /** + * Schedules a snapshot of the given area of the game viewport to be taken after the current frame is rendered. + * + * To capture the whole game viewport see the `snapshot` method. To capture a specific pixel, see `snapshotPixel`. + * + * Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then + * calling this method will override it. + * + * Snapshots work by creating an Image object from the canvas data, this is a blocking process, which gets + * more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * + * @method Phaser.Renderer.Canvas.CanvasRenderer#snapshotArea + * @since 3.16.0 + * + * @param {number} x - The x coordinate to grab from. + * @param {number} y - The y coordinate to grab from. + * @param {number} width - The width of the area to grab. + * @param {number} height - The height of the area to grab. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This WebGL Renderer. + */ + snapshotArea: function (x, y, width, height, callback, type, encoderOptions) + { + var state = this.snapshotState; + + state.callback = callback; + state.type = type; + state.encoder = encoderOptions; + state.getPixel = false; + state.x = x; + state.y = y; + state.width = Math.min(width, this.gameCanvas.width); + state.height = Math.min(height, this.gameCanvas.height); return this; }, /** - * Binds this Key Control to a camera. + * Schedules a snapshot of the given pixel from the game viewport to be taken after the current frame is rendered. * - * @method Phaser.Cameras.Controls.SmoothedKeyControl#setCamera - * @since 3.0.0 + * To capture the whole game viewport see the `snapshot` method. To capture a specific area, see `snapshotArea`. * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to bind this Key Control to. + * Only one snapshot can be active _per frame_. If you have already called `snapshotArea`, for example, then + * calling this method will override it. * - * @return {this} This Key Control instance. + * Unlike the other two snapshot methods, this one will return a `Color` object containing the color data for + * the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute, + * using less memory. + * + * @method Phaser.Renderer.Canvas.CanvasRenderer#snapshotPixel + * @since 3.16.0 + * + * @param {number} x - The x coordinate of the pixel to get. + * @param {number} y - The y coordinate of the pixel to get. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted. + * + * @return {this} This WebGL Renderer. */ - setCamera: function (camera) + snapshotPixel: function (x, y, callback) { - this.camera = camera; + this.snapshotArea(x, y, 1, 1, callback); + + this.snapshotState.getPixel = true; return this; }, /** - * Applies the results of pressing the control keys to the Camera. - * - * You must call this every step, it is not called automatically. + * Takes a Sprite Game Object, or any object that extends it, and draws it to the current context. * - * @method Phaser.Cameras.Controls.SmoothedKeyControl#update - * @since 3.0.0 + * @method Phaser.Renderer.Canvas.CanvasRenderer#batchSprite + * @since 3.12.0 * - * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + * @param {Phaser.GameObjects.GameObject} sprite - The texture based Game Object to draw. + * @param {Phaser.Textures.Frame} frame - The frame to draw, doesn't have to be that owned by the Game Object. + * @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. */ - update: function (delta) + batchSprite: function (sprite, frame, camera, parentTransformMatrix) { - if (!this.active) + var alpha = camera.alpha * sprite.alpha; + + if (alpha === 0) { + // Nothing to see, so abort early return; } - if (delta === undefined) { delta = 1; } + var ctx = this.currentContext; - var cam = this.camera; + var camMatrix = this._tempMatrix1; + var spriteMatrix = this._tempMatrix2; - // Apply Deceleration + var cd = frame.canvasData; - if (this._speedX > 0) - { - this._speedX -= this.dragX * delta; + var frameX = cd.x; + var frameY = cd.y; + var frameWidth = frame.cutWidth; + var frameHeight = frame.cutHeight; + var customPivot = frame.customPivot; - if (this._speedX < 0) - { - this._speedX = 0; - } - } - else if (this._speedX < 0) - { - this._speedX += this.dragX * delta; + var res = frame.source.resolution; - if (this._speedX > 0) - { - this._speedX = 0; - } - } + var displayOriginX = sprite.displayOriginX; + var displayOriginY = sprite.displayOriginY; - if (this._speedY > 0) - { - this._speedY -= this.dragY * delta; + var x = -displayOriginX + frame.x; + var y = -displayOriginY + frame.y; - if (this._speedY < 0) - { - this._speedY = 0; - } - } - else if (this._speedY < 0) + if (sprite.isCropped) { - this._speedY += this.dragY * delta; + var crop = sprite._crop; - if (this._speedY > 0) + if (crop.flipX !== sprite.flipX || crop.flipY !== sprite.flipY) { - this._speedY = 0; + frame.updateCropUVs(crop, sprite.flipX, sprite.flipY); } - } - // Check for keys + frameWidth = crop.cw; + frameHeight = crop.ch; - if (this.up && this.up.isDown) - { - this._speedY += this.accelY; + frameX = crop.cx; + frameY = crop.cy; - if (this._speedY > this.maxSpeedY) + x = -displayOriginX + crop.x; + y = -displayOriginY + crop.y; + + if (sprite.flipX) { - this._speedY = this.maxSpeedY; + if (x >= 0) + { + x = -(x + frameWidth); + } + else if (x < 0) + { + x = (Math.abs(x) - frameWidth); + } } - } - else if (this.down && this.down.isDown) - { - this._speedY -= this.accelY; - if (this._speedY < -this.maxSpeedY) + if (sprite.flipY) { - this._speedY = -this.maxSpeedY; + if (y >= 0) + { + y = -(y + frameHeight); + } + else if (y < 0) + { + y = (Math.abs(y) - frameHeight); + } } } - if (this.left && this.left.isDown) - { - this._speedX += this.accelX; + var flipX = 1; + var flipY = 1; - if (this._speedX > this.maxSpeedX) + if (sprite.flipX) + { + if (!customPivot) { - this._speedX = this.maxSpeedX; + x += (-frame.realWidth + (displayOriginX * 2)); } + + flipX = -1; } - else if (this.right && this.right.isDown) - { - this._speedX -= this.accelX; - if (this._speedX < -this.maxSpeedX) + // Auto-invert the flipY if this is coming from a GLTexture + if (sprite.flipY) + { + if (!customPivot) { - this._speedX = -this.maxSpeedX; + y += (-frame.realHeight + (displayOriginY * 2)); } + + flipY = -1; } - // Camera zoom + var gx = sprite.x; + var gy = sprite.y; - if (this.zoomIn && this.zoomIn.isDown) + if (camera.roundPixels) { - this._zoom = -this.zoomSpeed; + gx = Math.floor(gx); + gy = Math.floor(gy); } - else if (this.zoomOut && this.zoomOut.isDown) + + spriteMatrix.applyITRS(gx, gy, sprite.rotation, sprite.scaleX * flipX, sprite.scaleY * flipY); + + camMatrix.copyFrom(camera.matrix); + + if (parentTransformMatrix) { - this._zoom = this.zoomSpeed; + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * sprite.scrollFactorX, -camera.scrollY * sprite.scrollFactorY); + + // Undo the camera scroll + spriteMatrix.e = gx; + spriteMatrix.f = gy; } else { - this._zoom = 0; + spriteMatrix.e -= camera.scrollX * sprite.scrollFactorX; + spriteMatrix.f -= camera.scrollY * sprite.scrollFactorY; } - // Apply to Camera + // Multiply by the Sprite matrix + camMatrix.multiply(spriteMatrix); - if (this._speedX !== 0) + if (camera.roundPixels) { - cam.scrollX -= ((this._speedX * delta) | 0); + camMatrix.e = Math.round(camMatrix.e); + camMatrix.f = Math.round(camMatrix.f); } - if (this._speedY !== 0) + ctx.save(); + + camMatrix.setToContext(ctx); + + ctx.globalCompositeOperation = this.blendModes[sprite.blendMode]; + + ctx.globalAlpha = alpha; + + ctx.imageSmoothingEnabled = !frame.source.scaleMode; + + if (sprite.mask) { - cam.scrollY -= ((this._speedY * delta) | 0); + sprite.mask.preRenderCanvas(this, sprite, camera); } - if (this._zoom !== 0) + if (frameWidth > 0 && frameHeight > 0) { - cam.zoom += this._zoom; + ctx.drawImage(frame.source.image, frameX, frameY, frameWidth, frameHeight, x, y, frameWidth / res, frameHeight / res); + } - if (cam.zoom < this.minZoom) - { - cam.zoom = this.minZoom; - } - else if (cam.zoom > this.maxZoom) - { - cam.zoom = this.maxZoom; - } + if (sprite.mask) + { + sprite.mask.postRenderCanvas(this, sprite, camera); } + + ctx.restore(); }, /** - * Destroys this Key Control. + * Destroys all object references in the Canvas Renderer. * - * @method Phaser.Cameras.Controls.SmoothedKeyControl#destroy + * @method Phaser.Renderer.Canvas.CanvasRenderer#destroy * @since 3.0.0 */ destroy: function () { - this.camera = null; - - this.left = null; - this.right = null; - this.up = null; - this.down = null; + this.removeAllListeners(); - this.zoomIn = null; - this.zoomOut = null; + this.game = null; + this.gameCanvas = null; + this.gameContext = null; } }); -module.exports = SmoothedKeyControl; +module.exports = CanvasRenderer; /***/ }), -/* 742 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 6046: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Cameras.Scene2D + * @namespace Phaser.Renderer.Canvas */ module.exports = { - Camera: __webpack_require__(326), - BaseCamera: __webpack_require__(133), - CameraManager: __webpack_require__(799), - Effects: __webpack_require__(333), - Events: __webpack_require__(37) + CanvasRenderer: __webpack_require__(91135), + GetBlendModes: __webpack_require__(32834), + SetTransform: __webpack_require__(49584) }; /***/ }), -/* 743 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Destroy Camera Event. - * - * This event is dispatched by a Camera instance when it is destroyed by the Camera Manager. - * - * @event Phaser.Cameras.Scene2D.Events#DESTROY - * @since 3.0.0 - * - * @param {Phaser.Cameras.Scene2D.BaseCamera} camera - The camera that was destroyed. - */ -module.exports = 'cameradestroy'; - -/***/ }), -/* 744 */ -/***/ (function(module, exports) { +/***/ 32834: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * The Camera Fade In Complete Event. - * - * This event is dispatched by a Camera instance when the Fade In Effect completes. - * - * Listen to it from a Camera instance using `Camera.on('camerafadeincomplete', listener)`. - * - * @event Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Fade} effect - A reference to the effect instance. - */ -module.exports = 'camerafadeincomplete'; - - -/***/ }), -/* 745 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +var modes = __webpack_require__(95723); +var CanvasFeatures = __webpack_require__(98581); /** - * The Camera Fade In Start Event. - * - * This event is dispatched by a Camera instance when the Fade In Effect starts. - * - * Listen to it from a Camera instance using `Camera.on('camerafadeinstart', listener)`. + * Returns an array which maps the default blend modes to supported Canvas blend modes. * - * @event Phaser.Cameras.Scene2D.Events#FADE_IN_START - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Fade} effect - A reference to the effect instance. - * @param {number} duration - The duration of the effect. - * @param {number} red - The red color channel value. - * @param {number} green - The green color channel value. - * @param {number} blue - The blue color channel value. - */ -module.exports = 'camerafadeinstart'; - - -/***/ }), -/* 746 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Camera Fade Out Complete Event. - * - * This event is dispatched by a Camera instance when the Fade Out Effect completes. - * - * Listen to it from a Camera instance using `Camera.on('camerafadeoutcomplete', listener)`. + * If the browser doesn't support a blend mode, it will default to the normal `source-over` blend mode. * - * @event Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Fade} effect - A reference to the effect instance. - */ -module.exports = 'camerafadeoutcomplete'; - - -/***/ }), -/* 747 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Camera Fade Out Start Event. - * - * This event is dispatched by a Camera instance when the Fade Out Effect starts. - * - * Listen to it from a Camera instance using `Camera.on('camerafadeoutstart', listener)`. + * @function Phaser.Renderer.Canvas.GetBlendModes + * @since 3.0.0 * - * @event Phaser.Cameras.Scene2D.Events#FADE_OUT_START - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Fade} effect - A reference to the effect instance. - * @param {number} duration - The duration of the effect. - * @param {number} red - The red color channel value. - * @param {number} green - The green color channel value. - * @param {number} blue - The blue color channel value. + * @return {array} Which Canvas blend mode corresponds to which default Phaser blend mode. */ -module.exports = 'camerafadeoutstart'; - +var GetBlendModes = function () +{ + var output = []; + var useNew = CanvasFeatures.supportNewBlendModes; + var so = 'source-over'; -/***/ }), -/* 748 */ -/***/ (function(module, exports) { + output[modes.NORMAL] = so; + output[modes.ADD] = 'lighter'; + output[modes.MULTIPLY] = (useNew) ? 'multiply' : so; + output[modes.SCREEN] = (useNew) ? 'screen' : so; + output[modes.OVERLAY] = (useNew) ? 'overlay' : so; + output[modes.DARKEN] = (useNew) ? 'darken' : so; + output[modes.LIGHTEN] = (useNew) ? 'lighten' : so; + output[modes.COLOR_DODGE] = (useNew) ? 'color-dodge' : so; + output[modes.COLOR_BURN] = (useNew) ? 'color-burn' : so; + output[modes.HARD_LIGHT] = (useNew) ? 'hard-light' : so; + output[modes.SOFT_LIGHT] = (useNew) ? 'soft-light' : so; + output[modes.DIFFERENCE] = (useNew) ? 'difference' : so; + output[modes.EXCLUSION] = (useNew) ? 'exclusion' : so; + output[modes.HUE] = (useNew) ? 'hue' : so; + output[modes.SATURATION] = (useNew) ? 'saturation' : so; + output[modes.COLOR] = (useNew) ? 'color' : so; + output[modes.LUMINOSITY] = (useNew) ? 'luminosity' : so; + output[modes.ERASE] = 'destination-out'; + output[modes.SOURCE_IN] = 'source-in'; + output[modes.SOURCE_OUT] = 'source-out'; + output[modes.SOURCE_ATOP] = 'source-atop'; + output[modes.DESTINATION_OVER] = 'destination-over'; + output[modes.DESTINATION_IN] = 'destination-in'; + output[modes.DESTINATION_OUT] = 'destination-out'; + output[modes.DESTINATION_ATOP] = 'destination-atop'; + output[modes.LIGHTER] = 'lighter'; + output[modes.COPY] = 'copy'; + output[modes.XOR] = 'xor'; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return output; +}; -/** - * The Camera Flash Complete Event. - * - * This event is dispatched by a Camera instance when the Flash Effect completes. - * - * @event Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Flash} effect - A reference to the effect instance. - */ -module.exports = 'cameraflashcomplete'; +module.exports = GetBlendModes; /***/ }), -/* 749 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Camera Flash Start Event. - * - * This event is dispatched by a Camera instance when the Flash Effect starts. - * - * @event Phaser.Cameras.Scene2D.Events#FLASH_START - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Flash} effect - A reference to the effect instance. - * @param {number} duration - The duration of the effect. - * @param {number} red - The red color channel value. - * @param {number} green - The green color channel value. - * @param {number} blue - The blue color channel value. - */ -module.exports = 'cameraflashstart'; - -/***/ }), -/* 750 */ -/***/ (function(module, exports) { +/***/ 49584: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetCalcMatrix = __webpack_require__(73329); + /** - * The Camera Follower Update Event. + * Takes a reference to the Canvas Renderer, a Canvas Rendering Context, a Game Object, a Camera and a parent matrix + * and then performs the following steps: * - * This event is dispatched by a Camera instance when it is following a - * Game Object and the Camera position has been updated as a result of - * that following. + * 1. Checks the alpha of the source combined with the Camera alpha. If 0 or less it aborts. + * 2. Takes the Camera and Game Object matrix and multiplies them, combined with the parent matrix if given. + * 3. Sets the blend mode of the context to be that used by the Game Object. + * 4. Sets the alpha value of the context to be that used by the Game Object combined with the Camera. + * 5. Saves the context state. + * 6. Sets the final matrix values into the context via setTransform. + * 7. If the Game Object has a texture frame, imageSmoothingEnabled is set based on frame.source.scaleMode. + * 8. If the Game Object does not have a texture frame, imageSmoothingEnabled is set based on Renderer.antialias. * - * Listen to it from a Camera instance using: `camera.on('followupdate', listener)`. + * This function is only meant to be used internally. Most of the Canvas Renderer classes use it. * - * @event Phaser.Cameras.Scene2D.Events#FOLLOW_UPDATE - * @since 3.50.0 + * @function Phaser.Renderer.Canvas.SetTransform + * @since 3.12.0 * - * @param {Phaser.Cameras.Scene2D.BaseCamera} camera - The camera that emitted the event. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the camera is following. + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {CanvasRenderingContext2D} ctx - The canvas context to set the transform on. + * @param {Phaser.GameObjects.GameObject} src - The Game Object being rendered. Can be any type that extends the base class. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + * @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - A parent transform matrix to apply to the Game Object before rendering. + * + * @return {boolean} `true` if the Game Object context was set, otherwise `false`. */ -module.exports = 'followupdate'; +var SetTransform = function (renderer, ctx, src, camera, parentMatrix) +{ + var alpha = camera.alpha * src.alpha; + if (alpha <= 0) + { + // Nothing to see, so don't waste time calculating stuff + return false; + } -/***/ }), -/* 751 */ -/***/ (function(module, exports) { + var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Blend Mode + ctx.globalCompositeOperation = renderer.blendModes[src.blendMode]; -/** - * The Camera Pan Complete Event. - * - * This event is dispatched by a Camera instance when the Pan Effect completes. - * - * @event Phaser.Cameras.Scene2D.Events#PAN_COMPLETE - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Pan} effect - A reference to the effect instance. - */ -module.exports = 'camerapancomplete'; + // Alpha + ctx.globalAlpha = alpha; + ctx.save(); -/***/ }), -/* 752 */ -/***/ (function(module, exports) { + calcMatrix.setToContext(ctx); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + ctx.imageSmoothingEnabled = src.frame ? !src.frame.source.scaleMode : renderer.antialias; -/** - * The Camera Pan Start Event. - * - * This event is dispatched by a Camera instance when the Pan Effect starts. - * - * @event Phaser.Cameras.Scene2D.Events#PAN_START - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Pan} effect - A reference to the effect instance. - * @param {number} duration - The duration of the effect. - * @param {number} x - The destination scroll x coordinate. - * @param {number} y - The destination scroll y coordinate. - */ -module.exports = 'camerapanstart'; + return true; +}; + +module.exports = SetTransform; /***/ }), -/* 753 */ -/***/ (function(module, exports) { + +/***/ 70936: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Camera Post-Render Event. - * - * This event is dispatched by a Camera instance after is has finished rendering. - * It is only dispatched if the Camera is rendering to a texture. - * - * Listen to it from a Camera instance using: `camera.on('postrender', listener)`. + * The Post-Render Event. * - * @event Phaser.Cameras.Scene2D.Events#POST_RENDER - * @since 3.0.0 - * - * @param {Phaser.Cameras.Scene2D.BaseCamera} camera - The camera that has finished rendering to a texture. + * This event is dispatched by the Renderer when all rendering, for all cameras in all Scenes, + * has completed, but before any pending snap shots have been taken. + * + * @event Phaser.Renderer.Events#POST_RENDER + * @type {string} + * @since 3.50.0 */ module.exports = 'postrender'; /***/ }), -/* 754 */ -/***/ (function(module, exports) { + +/***/ 99298: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Camera Pre-Render Event. - * - * This event is dispatched by a Camera instance when it is about to render. - * It is only dispatched if the Camera is rendering to a texture. - * - * Listen to it from a Camera instance using: `camera.on('prerender', listener)`. + * The Pre-Render Event. * - * @event Phaser.Cameras.Scene2D.Events#PRE_RENDER - * @since 3.0.0 - * - * @param {Phaser.Cameras.Scene2D.BaseCamera} camera - The camera that is about to render to a texture. + * This event is dispatched by the Phaser Renderer. This happens right at the start of the render + * process, after the context has been cleared, the scissors enabled (WebGL only) and everything has been + * reset ready for the render. + * + * @event Phaser.Renderer.Events#PRE_RENDER + * @type {string} + * @since 3.50.0 */ module.exports = 'prerender'; /***/ }), -/* 755 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Camera Rotate Complete Event. - * - * This event is dispatched by a Camera instance when the Rotate Effect completes. - * - * @event Phaser.Cameras.Scene2D.Events#ROTATE_COMPLETE - * @since 3.23.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.RotateTo} effect - A reference to the effect instance. - */ -module.exports = 'camerarotatecomplete'; - -/***/ }), -/* 756 */ -/***/ (function(module, exports) { +/***/ 7743: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Camera Rotate Start Event. - * - * This event is dispatched by a Camera instance when the Rotate Effect starts. + * The Render Event. * - * @event Phaser.Cameras.Scene2D.Events#ROTATE_START - * @since 3.23.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.RotateTo} effect - A reference to the effect instance. - * @param {number} duration - The duration of the effect. - * @param {number} destination - The destination value. + * This event is dispatched by the Phaser Renderer for every camera in every Scene. + * + * It is dispatched before any of the children in the Scene have been rendered. + * + * @event Phaser.Renderer.Events#RENDER + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.Scene} scene - The Scene being rendered. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered. */ -module.exports = 'camerarotatestart'; +module.exports = 'render'; /***/ }), -/* 757 */ -/***/ (function(module, exports) { + +/***/ 99519: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Camera Shake Complete Event. - * - * This event is dispatched by a Camera instance when the Shake Effect completes. + * The Renderer Resize Event. * - * @event Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Shake} effect - A reference to the effect instance. + * This event is dispatched by the Phaser Renderer when it is resized, usually as a result + * of the Scale Manager resizing. + * + * @event Phaser.Renderer.Events#RESIZE + * @type {string} + * @since 3.50.0 + * + * @param {number} width - The new width of the renderer. + * @param {number} height - The new height of the renderer. */ -module.exports = 'camerashakecomplete'; +module.exports = 'resize'; /***/ }), -/* 758 */ -/***/ (function(module, exports) { + +/***/ 81044: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Camera Shake Start Event. - * - * This event is dispatched by a Camera instance when the Shake Effect starts. - * - * @event Phaser.Cameras.Scene2D.Events#SHAKE_START - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Shake} effect - A reference to the effect instance. - * @param {number} duration - The duration of the effect. - * @param {number} intensity - The intensity of the effect. + * @namespace Phaser.Renderer.Events */ -module.exports = 'camerashakestart'; - -/***/ }), -/* 759 */ -/***/ (function(module, exports) { +module.exports = { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + POST_RENDER: __webpack_require__(70936), + PRE_RENDER: __webpack_require__(99298), + RENDER: __webpack_require__(7743), + RESIZE: __webpack_require__(99519) -/** - * The Camera Zoom Complete Event. - * - * This event is dispatched by a Camera instance when the Zoom Effect completes. - * - * @event Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Zoom} effect - A reference to the effect instance. - */ -module.exports = 'camerazoomcomplete'; +}; /***/ }), -/* 760 */ -/***/ (function(module, exports) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 42069: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * The Camera Zoom Start Event. - * - * This event is dispatched by a Camera instance when the Zoom Effect starts. - * - * @event Phaser.Cameras.Scene2D.Events#ZOOM_START - * @since 3.3.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on. - * @param {Phaser.Cameras.Scene2D.Effects.Zoom} effect - A reference to the effect instance. - * @param {number} duration - The duration of the effect. - * @param {number} zoom - The destination zoom value. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -module.exports = 'camerazoomstart'; + +/** + * @namespace Phaser.Renderer + */ + +/** + * @namespace Phaser.Types.Renderer + */ + +module.exports = { + + Canvas: __webpack_require__(6046), + Events: __webpack_require__(81044), + Snapshot: __webpack_require__(95528), + WebGL: __webpack_require__(55478) + +}; /***/ }), -/* 761 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 61840: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var Events = __webpack_require__(37); +var CanvasPool = __webpack_require__(61068); +var Color = __webpack_require__(27119); +var GetFastValue = __webpack_require__(72632); /** - * @classdesc - * A Camera Fade effect. - * - * This effect will fade the camera viewport to the given color, over the duration specified. - * - * Only the camera viewport is faded. None of the objects it is displaying are impacted, i.e. their colors do - * not change. + * Takes a snapshot of an area from the current frame displayed by a canvas. * - * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, - * which is invoked each frame for the duration of the effect, if required. + * This is then copied to an Image object. When this loads, the results are sent + * to the callback provided in the Snapshot Configuration object. * - * @class Fade - * @memberof Phaser.Cameras.Scene2D.Effects - * @constructor - * @since 3.5.0 + * @function Phaser.Renderer.Snapshot.Canvas + * @since 3.0.0 * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. + * @param {HTMLCanvasElement} sourceCanvas - The canvas to take a snapshot of. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotState} config - The snapshot configuration object. */ -var Fade = new Class({ +var CanvasSnapshot = function (canvas, config) +{ + var callback = GetFastValue(config, 'callback'); + var type = GetFastValue(config, 'type', 'image/png'); + var encoderOptions = GetFastValue(config, 'encoder', 0.92); + var x = Math.abs(Math.round(GetFastValue(config, 'x', 0))); + var y = Math.abs(Math.round(GetFastValue(config, 'y', 0))); + var width = Math.floor(GetFastValue(config, 'width', canvas.width)); + var height = Math.floor(GetFastValue(config, 'height', canvas.height)); + var getPixel = GetFastValue(config, 'getPixel', false); - initialize: + if (getPixel) + { + var context = canvas.getContext('2d', { willReadFrequently: false }); + var imageData = context.getImageData(x, y, 1, 1); + var data = imageData.data; - function Fade (camera) + callback.call(null, new Color(data[0], data[1], data[2], data[3])); + } + else if (x !== 0 || y !== 0 || width !== canvas.width || height !== canvas.height) { - /** - * The Camera this effect belongs to. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#camera - * @type {Phaser.Cameras.Scene2D.Camera} - * @readonly - * @since 3.5.0 - */ - this.camera = camera; + // Area Grab + var copyCanvas = CanvasPool.createWebGL(this, width, height); + var ctx = copyCanvas.getContext('2d', { willReadFrequently: true }); - /** - * Is this effect actively running? - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#isRunning - * @type {boolean} - * @readonly - * @default false - * @since 3.5.0 - */ - this.isRunning = false; + if (width > 0 && height > 0) + { + ctx.drawImage(canvas, x, y, width, height, 0, 0, width, height); + } - /** - * Has this effect finished running? - * - * This is different from `isRunning` because it remains set to `true` when the effect is over, - * until the effect is either reset or started again. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#isComplete - * @type {boolean} - * @readonly - * @default false - * @since 3.5.0 - */ - this.isComplete = false; + var image1 = new Image(); - /** - * The direction of the fade. - * `true` = fade out (transparent to color), `false` = fade in (color to transparent) - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#direction - * @type {boolean} - * @readonly - * @since 3.5.0 - */ - this.direction = true; + image1.onerror = function () + { + callback.call(null); - /** - * The duration of the effect, in milliseconds. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#duration - * @type {number} - * @readonly - * @default 0 - * @since 3.5.0 - */ - this.duration = 0; + CanvasPool.remove(copyCanvas); + }; - /** - * The value of the red color channel the camera will use for the fade effect. - * A value between 0 and 255. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#red - * @type {number} - * @private - * @since 3.5.0 - */ - this.red = 0; + image1.onload = function () + { + callback.call(null, image1); - /** - * The value of the green color channel the camera will use for the fade effect. - * A value between 0 and 255. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#green - * @type {number} - * @private - * @since 3.5.0 - */ - this.green = 0; + CanvasPool.remove(copyCanvas); + }; - /** - * The value of the blue color channel the camera will use for the fade effect. - * A value between 0 and 255. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#blue - * @type {number} - * @private - * @since 3.5.0 - */ - this.blue = 0; + image1.src = copyCanvas.toDataURL(type, encoderOptions); + } + else + { + // Full Grab + var image2 = new Image(); - /** - * The value of the alpha channel used during the fade effect. - * A value between 0 and 1. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#alpha - * @type {number} - * @private - * @since 3.5.0 - */ - this.alpha = 0; + image2.onerror = function () + { + callback.call(null); + }; - /** - * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#progress - * @type {number} - * @since 3.5.0 - */ - this.progress = 0; + image2.onload = function () + { + callback.call(null, image2); + }; - /** - * Effect elapsed timer. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#_elapsed - * @type {number} - * @private - * @since 3.5.0 - */ - this._elapsed = 0; + image2.src = canvas.toDataURL(type, encoderOptions); + } +}; - /** - * This callback is invoked every frame for the duration of the effect. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#_onUpdate - * @type {?Phaser.Types.Cameras.Scene2D.CameraFadeCallback} - * @private - * @default null - * @since 3.5.0 - */ - this._onUpdate; +module.exports = CanvasSnapshot; - /** - * On Complete callback scope. - * - * @name Phaser.Cameras.Scene2D.Effects.Fade#_onUpdateScope - * @type {any} - * @private - * @since 3.5.0 - */ - this._onUpdateScope; - }, - /** - * Fades the Camera to or from the given color over the duration specified. - * - * @method Phaser.Cameras.Scene2D.Effects.Fade#start - * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_START - * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_START - * @since 3.5.0 - * - * @param {boolean} [direction=true] - The direction of the fade. `true` = fade out (transparent to color), `false` = fade in (color to transparent) - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255. - * @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255. - * @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255. - * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. - * @param {Phaser.Types.Cameras.Scene2D.CameraFadeCallback} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. - * - * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. - */ - start: function (direction, duration, red, green, blue, force, callback, context) - { - if (direction === undefined) { direction = true; } - if (duration === undefined) { duration = 1000; } - if (red === undefined) { red = 0; } - if (green === undefined) { green = 0; } - if (blue === undefined) { blue = 0; } - if (force === undefined) { force = false; } - if (callback === undefined) { callback = null; } - if (context === undefined) { context = this.camera.scene; } +/***/ }), - if (!force && this.isRunning) - { - return this.camera; - } +/***/ 1217: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.isRunning = true; - this.isComplete = false; - this.duration = duration; - this.direction = direction; - this.progress = 0; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.red = red; - this.green = green; - this.blue = blue; - this.alpha = (direction) ? Number.MIN_VALUE : 1; +var CanvasPool = __webpack_require__(61068); +var Color = __webpack_require__(27119); +var GetFastValue = __webpack_require__(72632); - this._elapsed = 0; +/** + * Takes a snapshot of an area from the current frame displayed by a WebGL canvas. + * + * This is then copied to an Image object. When this loads, the results are sent + * to the callback provided in the Snapshot Configuration object. + * + * @function Phaser.Renderer.Snapshot.WebGL + * @since 3.0.0 + * + * @param {WebGLRenderingContext} sourceContext - The WebGL context to take a snapshot of. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotState} config - The snapshot configuration object. + */ +var WebGLSnapshot = function (sourceContext, config) +{ + var gl = sourceContext; - this._onUpdate = callback; - this._onUpdateScope = context; + var callback = GetFastValue(config, 'callback'); + var type = GetFastValue(config, 'type', 'image/png'); + var encoderOptions = GetFastValue(config, 'encoder', 0.92); + var x = Math.abs(Math.round(GetFastValue(config, 'x', 0))); + var y = Math.abs(Math.round(GetFastValue(config, 'y', 0))); - var eventName = (direction) ? Events.FADE_OUT_START : Events.FADE_IN_START; + var getPixel = GetFastValue(config, 'getPixel', false); - this.camera.emit(eventName, this.camera, this, duration, red, green, blue); + var isFramebuffer = GetFastValue(config, 'isFramebuffer', false); - return this.camera; - }, + var bufferWidth = (isFramebuffer) ? GetFastValue(config, 'bufferWidth', 1) : gl.drawingBufferWidth; + var bufferHeight = (isFramebuffer) ? GetFastValue(config, 'bufferHeight', 1) : gl.drawingBufferHeight; - /** - * The main update loop for this effect. Called automatically by the Camera. - * - * @method Phaser.Cameras.Scene2D.Effects.Fade#update - * @since 3.5.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 (getPixel) { - if (!this.isRunning) - { - return; - } + var pixel = new Uint8Array(4); - this._elapsed += delta; + var destY = (isFramebuffer) ? y : bufferHeight - y; - this.progress = Clamp(this._elapsed / this.duration, 0, 1); + gl.readPixels(x, destY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel); - if (this._onUpdate) - { - this._onUpdate.call(this._onUpdateScope, this.camera, this.progress); - } + callback.call(null, new Color(pixel[0], pixel[1], pixel[2], pixel[3])); + } + else + { + var width = Math.floor(GetFastValue(config, 'width', bufferWidth)); + var height = Math.floor(GetFastValue(config, 'height', bufferHeight)); - if (this._elapsed < this.duration) - { - this.alpha = (this.direction) ? this.progress : 1 - this.progress; - } - else - { - this.alpha = (this.direction) ? 1 : 0; - this.effectComplete(); - } - }, + var total = width * height * 4; - /** - * Called internally by the Canvas Renderer. - * - * @method Phaser.Cameras.Scene2D.Effects.Fade#postRenderCanvas - * @since 3.5.0 - * - * @param {CanvasRenderingContext2D} ctx - The Canvas context to render to. - * - * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`. - */ - postRenderCanvas: function (ctx) - { - if (!this.isRunning && !this.isComplete) - { - return false; - } + var pixels = new Uint8Array(total); - var camera = this.camera; + gl.readPixels(x, bufferHeight - y - height, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - ctx.fillStyle = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',' + this.alpha + ')'; - ctx.fillRect(camera.x, camera.y, camera.width, camera.height); + var canvas = CanvasPool.createWebGL(this, width, height); + var ctx = canvas.getContext('2d', { willReadFrequently: true }); - return true; - }, + var imageData = ctx.getImageData(0, 0, width, height); - /** - * Called internally by the WebGL Renderer. - * - * @method Phaser.Cameras.Scene2D.Effects.Fade#postRenderWebGL - * @since 3.5.0 - * - * @param {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} pipeline - The WebGL Pipeline to render to. Must provide the `drawFillRect` method. - * @param {function} getTintFunction - A function that will return the gl safe tint colors. - * - * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`. - */ - postRenderWebGL: function (pipeline, getTintFunction) - { - if (!this.isRunning && !this.isComplete) + var data = imageData.data; + + for (var py = 0; py < height; py++) { - return false; + for (var px = 0; px < width; px++) + { + var sourceIndex = ((height - py - 1) * width + px) * 4; + + var destIndex = (isFramebuffer) ? total - ((py * width + (width - px)) * 4) : (py * width + px) * 4; + + data[destIndex + 0] = pixels[sourceIndex + 0]; + data[destIndex + 1] = pixels[sourceIndex + 1]; + data[destIndex + 2] = pixels[sourceIndex + 2]; + data[destIndex + 3] = pixels[sourceIndex + 3]; + } } - var camera = this.camera; - var red = this.red / 255; - var green = this.green / 255; - var blue = this.blue / 255; + ctx.putImageData(imageData, 0, 0); - pipeline.drawFillRect( - camera.x, camera.y, camera.width, camera.height, - getTintFunction(blue, green, red, 1), - this.alpha - ); + var image = new Image(); - return true; - }, + image.onerror = function () + { + callback.call(null); - /** - * Called internally when the effect completes. - * - * @method Phaser.Cameras.Scene2D.Effects.Fade#effectComplete - * @fires Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE - * @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE - * @since 3.5.0 - */ - effectComplete: function () - { - this._onUpdate = null; - this._onUpdateScope = null; + CanvasPool.remove(canvas); + }; - this.isRunning = false; - this.isComplete = true; + image.onload = function () + { + callback.call(null, image); - var eventName = (this.direction) ? Events.FADE_OUT_COMPLETE : Events.FADE_IN_COMPLETE; + CanvasPool.remove(canvas); + }; - this.camera.emit(eventName, this.camera, this); - }, + image.src = canvas.toDataURL(type, encoderOptions); + } +}; - /** - * Resets this camera effect. - * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. - * - * @method Phaser.Cameras.Scene2D.Effects.Fade#reset - * @since 3.5.0 - */ - reset: function () - { - this.isRunning = false; - this.isComplete = false; +module.exports = WebGLSnapshot; - this._onUpdate = null; - this._onUpdateScope = null; - }, - /** - * Destroys this effect, releasing it from the Camera. - * - * @method Phaser.Cameras.Scene2D.Effects.Fade#destroy - * @since 3.5.0 - */ - destroy: function () - { - this.reset(); +/***/ }), - this.camera = null; - } +/***/ 95528: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -}); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = Fade; +/** + * @namespace Phaser.Renderer.Snapshot + */ + +module.exports = { + + Canvas: __webpack_require__(61840), + WebGL: __webpack_require__(1217) + +}; /***/ }), -/* 762 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 35217: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var Events = __webpack_require__(37); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(65641); +var CustomMap = __webpack_require__(33885); +var Device = __webpack_require__(77290); +var GetFastValue = __webpack_require__(72632); +var RenderTarget = __webpack_require__(37410); +var SnapCeil = __webpack_require__(82127); + +// Default Phaser 3 Pipelines +var BitmapMaskPipeline = __webpack_require__(5583); +var FX = __webpack_require__(58136); +var FX_CONST = __webpack_require__(47406); +var FXPipeline = __webpack_require__(81828); +var LightPipeline = __webpack_require__(66901); +var MobilePipeline = __webpack_require__(71264); +var MultiPipeline = __webpack_require__(77310); +var PointLightPipeline = __webpack_require__(10919); +var RopePipeline = __webpack_require__(21213); +var SinglePipeline = __webpack_require__(51212); +var UtilityPipeline = __webpack_require__(60848); /** * @classdesc - * A Camera Flash effect. + * The Pipeline Manager is responsible for the creation, activation, running and destruction + * of WebGL Pipelines and Post FX Pipelines in Phaser 3. * - * This effect will flash the camera viewport to the given color, over the duration specified. + * The `WebGLRenderer` owns a single instance of the Pipeline Manager, which you can access + * via the `WebGLRenderer.pipelines` property. * - * Only the camera viewport is flashed. None of the objects it is displaying are impacted, i.e. their colors do - * not change. + * By default, there are 9 pipelines installed into the Pipeline Manager when Phaser boots: * - * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, - * which is invoked each frame for the duration of the effect, if required. + * 1. The Multi Pipeline. Responsible for all multi-texture rendering, i.e. Sprites and Tilemaps. + * 2. The Rope Pipeline. Responsible for rendering the Rope Game Object. + * 3. The Light Pipeline. Responsible for rendering the Light Game Object. + * 4. The Point Light Pipeline. Responsible for rendering the Point Light Game Object. + * 5. The Single Pipeline. Responsible for rendering Game Objects that explicitly require one bound texture. + * 6. The Bitmap Mask Pipeline. Responsible for Bitmap Mask rendering. + * 7. The Utility Pipeline. Responsible for providing lots of handy texture manipulation functions. + * 8. The Mobile Pipeline. Responsible for rendering on mobile with single-bound textures. + * 9. The FX Pipeline. Responsible for rendering Game Objects with special FX applied to them. * - * @class Flash - * @memberof Phaser.Cameras.Scene2D.Effects + * You can add your own custom pipeline via the `PipelineManager.add` method. Pipelines are + * identified by unique string-based keys. + * + * @class PipelineManager + * @memberof Phaser.Renderer.WebGL * @constructor - * @since 3.5.0 + * @since 3.50.0 * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the WebGL Renderer that owns this Pipeline Manager. */ -var Flash = new Class({ +var PipelineManager = new Class({ initialize: - function Flash (camera) + function PipelineManager (renderer) { /** - * The Camera this effect belongs to. + * A reference to the Game instance. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#camera - * @type {Phaser.Cameras.Scene2D.Camera} - * @readonly - * @since 3.5.0 + * @name Phaser.Renderer.WebGL.PipelineManager#game + * @type {Phaser.Game} + * @since 3.50.0 */ - this.camera = camera; + this.game = renderer.game; /** - * Is this effect actively running? + * A reference to the WebGL Renderer instance. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#isRunning - * @type {boolean} - * @readonly - * @default false - * @since 3.5.0 + * @name Phaser.Renderer.WebGL.PipelineManager#renderer + * @type {Phaser.Renderer.WebGL.WebGLRenderer} + * @since 3.50.0 */ - this.isRunning = false; + this.renderer = renderer; /** - * The duration of the effect, in milliseconds. + * This map stores all pipeline classes available in this manager. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#duration - * @type {number} - * @readonly - * @default 0 - * @since 3.5.0 - */ - this.duration = 0; - - /** - * The value of the red color channel the camera will use for the flash effect. - * A value between 0 and 255. + * The Utility Class must always come first. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#red - * @type {number} - * @private - * @since 3.5.0 + * @name Phaser.Renderer.WebGL.PipelineManager#classes + * @type {Phaser.Structs.Map.} + * @since 3.50.0 */ - this.red = 0; + this.classes = new CustomMap([ + [ CONST.UTILITY_PIPELINE, UtilityPipeline ], + [ CONST.MULTI_PIPELINE, MultiPipeline ], + [ CONST.BITMAPMASK_PIPELINE, BitmapMaskPipeline ], + [ CONST.SINGLE_PIPELINE, SinglePipeline ], + [ CONST.ROPE_PIPELINE, RopePipeline ], + [ CONST.LIGHT_PIPELINE, LightPipeline ], + [ CONST.POINTLIGHT_PIPELINE, PointLightPipeline ], + [ CONST.MOBILE_PIPELINE, MobilePipeline ], + [ CONST.FX_PIPELINE, FXPipeline ] + ]); /** - * The value of the green color channel the camera will use for the flash effect. - * A value between 0 and 255. + * This map stores all Post FX Pipeline classes available in this manager. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#green - * @type {number} - * @private - * @since 3.5.0 + * As of v3.60 this is now populated by default with the following + * Post FX Pipelines: + * + * * Barrel + * * Bloom + * * Blur + * * Bokeh / TiltShift + * * Circle + * * ColorMatrix + * * Displacement + * * Glow + * * Gradient + * * Pixelate + * * Shadow + * * Shine + * * Vignette + * * Wipe + * + * See the FX Controller class for more details. + * + * @name Phaser.Renderer.WebGL.PipelineManager#postPipelineClasses + * @type {Phaser.Structs.Map.} + * @since 3.50.0 */ - this.green = 0; + this.postPipelineClasses = new CustomMap([ + [ String(FX_CONST.BARREL), FX.Barrel ], + [ String(FX_CONST.BLOOM), FX.Bloom ], + [ String(FX_CONST.BLUR), FX.Blur ], + [ String(FX_CONST.BOKEH), FX.Bokeh ], + [ String(FX_CONST.CIRCLE), FX.Circle ], + [ String(FX_CONST.COLOR_MATRIX), FX.ColorMatrix ], + [ String(FX_CONST.DISPLACEMENT), FX.Displacement ], + [ String(FX_CONST.GLOW), FX.Glow ], + [ String(FX_CONST.GRADIENT), FX.Gradient ], + [ String(FX_CONST.PIXELATE), FX.Pixelate ], + [ String(FX_CONST.SHADOW), FX.Shadow ], + [ String(FX_CONST.SHINE), FX.Shine ], + [ String(FX_CONST.VIGNETTE), FX.Vignette ], + [ String(FX_CONST.WIPE), FX.Wipe ] + ]); /** - * The value of the blue color channel the camera will use for the flash effect. - * A value between 0 and 255. + * This map stores all pipeline instances in this manager. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#blue - * @type {number} - * @private - * @since 3.5.0 + * This is populated with the default pipelines in the `boot` method. + * + * @name Phaser.Renderer.WebGL.PipelineManager#pipelines + * @type {Phaser.Structs.Map.} + * @since 3.50.0 */ - this.blue = 0; + this.pipelines = new CustomMap(); /** - * The value of the alpha channel used during the flash effect. - * A value between 0 and 1. + * The default Game Object pipeline. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#alpha - * @type {number} - * @private - * @since 3.5.0 + * @name Phaser.Renderer.WebGL.PipelineManager#default + * @type {Phaser.Renderer.WebGL.WebGLPipeline} + * @default null + * @since 3.60.0 */ - this.alpha = 0; + this.default = null; /** - * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. + * Current pipeline in use by the WebGLRenderer. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#progress - * @type {number} - * @since 3.5.0 + * @name Phaser.Renderer.WebGL.PipelineManager#current + * @type {Phaser.Renderer.WebGL.WebGLPipeline} + * @default null + * @since 3.50.0 */ - this.progress = 0; + this.current = null; /** - * Effect elapsed timer. + * The previous WebGLPipeline that was in use. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#_elapsed - * @type {number} - * @private - * @since 3.5.0 + * This is set when `clearPipeline` is called and restored in `rebindPipeline` if none is given. + * + * @name Phaser.Renderer.WebGL.PipelineManager#previous + * @type {Phaser.Renderer.WebGL.WebGLPipeline} + * @default null + * @since 3.50.0 */ - this._elapsed = 0; + this.previous = null; /** - * This callback is invoked every frame for the duration of the effect. + * A constant-style reference to the Multi Pipeline Instance. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#_onUpdate - * @type {?Phaser.Types.Cameras.Scene2D.CameraFlashCallback} - * @private + * This is the default Phaser 3 pipeline and is used by the WebGL Renderer to manage + * camera effects and more. This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.PipelineManager#MULTI_PIPELINE + * @type {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} * @default null - * @since 3.5.0 + * @since 3.50.0 */ - this._onUpdate; + this.MULTI_PIPELINE = null; /** - * On Complete callback scope. + * A constant-style reference to the Bitmap Mask Pipeline Instance. * - * @name Phaser.Cameras.Scene2D.Effects.Flash#_onUpdateScope - * @type {any} - * @private - * @since 3.5.0 + * This is the default Phaser 3 mask pipeline and is used Game Objects using + * a Bitmap Mask. This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.PipelineManager#BITMAPMASK_PIPELINE + * @type {Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline} + * @default null + * @since 3.50.0 */ - this._onUpdateScope; - }, - - /** - * Flashes the Camera to or from the given color over the duration specified. - * - * @method Phaser.Cameras.Scene2D.Effects.Flash#start - * @fires Phaser.Cameras.Scene2D.Events#FLASH_START - * @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE - * @since 3.5.0 - * - * @param {number} [duration=250] - The duration of the effect in milliseconds. - * @param {number} [red=255] - The amount to flash the red channel towards. A value between 0 and 255. - * @param {number} [green=255] - The amount to flash the green channel towards. A value between 0 and 255. - * @param {number} [blue=255] - The amount to flash the blue channel towards. A value between 0 and 255. - * @param {boolean} [force=false] - Force the effect to start immediately, even if already running. - * @param {Phaser.Types.Cameras.Scene2D.CameraFlashCallback} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. - * - * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. - */ - start: function (duration, red, green, blue, force, callback, context) - { - if (duration === undefined) { duration = 250; } - if (red === undefined) { red = 255; } - if (green === undefined) { green = 255; } - if (blue === undefined) { blue = 255; } - if (force === undefined) { force = false; } - if (callback === undefined) { callback = null; } - if (context === undefined) { context = this.camera.scene; } - - if (!force && this.isRunning) - { - return this.camera; - } - - this.isRunning = true; - this.duration = duration; - this.progress = 0; - - this.red = red; - this.green = green; - this.blue = blue; - this.alpha = 1; - - this._elapsed = 0; - - this._onUpdate = callback; - this._onUpdateScope = context; - - this.camera.emit(Events.FLASH_START, this.camera, this, duration, red, green, blue); - - return this.camera; - }, - - /** - * The main update loop for this effect. Called automatically by the Camera. - * - * @method Phaser.Cameras.Scene2D.Effects.Flash#update - * @since 3.5.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.isRunning) - { - return; - } - - this._elapsed += delta; - - this.progress = Clamp(this._elapsed / this.duration, 0, 1); - - if (this._onUpdate) - { - this._onUpdate.call(this._onUpdateScope, this.camera, this.progress); - } - - if (this._elapsed < this.duration) - { - this.alpha = 1 - this.progress; - } - else - { - this.effectComplete(); - } - }, - - /** - * Called internally by the Canvas Renderer. - * - * @method Phaser.Cameras.Scene2D.Effects.Flash#postRenderCanvas - * @since 3.5.0 - * - * @param {CanvasRenderingContext2D} ctx - The Canvas context to render to. - * - * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`. - */ - postRenderCanvas: function (ctx) - { - if (!this.isRunning) - { - return false; - } - - var camera = this.camera; - - ctx.fillStyle = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',' + this.alpha + ')'; - ctx.fillRect(camera.x, camera.y, camera.width, camera.height); - - return true; - }, - - /** - * Called internally by the WebGL Renderer. - * - * @method Phaser.Cameras.Scene2D.Effects.Flash#postRenderWebGL - * @since 3.5.0 - * - * @param {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} pipeline - The WebGL Pipeline to render to. Must provide the `drawFillRect` method. - * @param {function} getTintFunction - A function that will return the gl safe tint colors. - * - * @return {boolean} `true` if the effect drew to the renderer, otherwise `false`. - */ - postRenderWebGL: function (pipeline, getTintFunction) - { - if (!this.isRunning) - { - return false; - } - - var camera = this.camera; - var red = this.red / 255; - var green = this.green / 255; - var blue = this.blue / 255; - - pipeline.drawFillRect( - camera.x, camera.y, camera.width, camera.height, - getTintFunction(blue, green, red, 1), - this.alpha - ); - - return true; - }, - - /** - * Called internally when the effect completes. - * - * @method Phaser.Cameras.Scene2D.Effects.Flash#effectComplete - * @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE - * @since 3.5.0 - */ - effectComplete: function () - { - this._onUpdate = null; - this._onUpdateScope = null; - - this.isRunning = false; - - this.camera.emit(Events.FLASH_COMPLETE, this.camera, this); - }, - - /** - * Resets this camera effect. - * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. - * - * @method Phaser.Cameras.Scene2D.Effects.Flash#reset - * @since 3.5.0 - */ - reset: function () - { - this.isRunning = false; - - this._onUpdate = null; - this._onUpdateScope = null; - }, - - /** - * Destroys this effect, releasing it from the Camera. - * - * @method Phaser.Cameras.Scene2D.Effects.Flash#destroy - * @since 3.5.0 - */ - destroy: function () - { - this.reset(); - - this.camera = null; - } - -}); - -module.exports = Flash; - - -/***/ }), -/* 763 */ -/***/ (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 EaseMap = __webpack_require__(134); -var Events = __webpack_require__(37); -var Vector2 = __webpack_require__(3); - -/** - * @classdesc - * A Camera Pan effect. - * - * This effect will scroll the Camera so that the center of its viewport finishes at the given destination, - * over the duration and with the ease specified. - * - * Only the camera scroll is moved. None of the objects it is displaying are impacted, i.e. their positions do - * not change. - * - * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, - * which is invoked each frame for the duration of the effect if required. - * - * @class Pan - * @memberof Phaser.Cameras.Scene2D.Effects - * @constructor - * @since 3.11.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. - */ -var Pan = new Class({ - - initialize: + this.BITMAPMASK_PIPELINE = null; - function Pan (camera) - { /** - * The Camera this effect belongs to. + * A constant-style reference to the Utility Pipeline Instance. * - * @name Phaser.Cameras.Scene2D.Effects.Pan#camera - * @type {Phaser.Cameras.Scene2D.Camera} - * @readonly - * @since 3.11.0 + * @name Phaser.Renderer.WebGL.PipelineManager#UTILITY_PIPELINE + * @type {Phaser.Renderer.WebGL.Pipelines.UtilityPipeline} + * @default null + * @since 3.50.0 */ - this.camera = camera; + this.UTILITY_PIPELINE = null; /** - * Is this effect actively running? + * A constant-style reference to the Mobile Pipeline Instance. * - * @name Phaser.Cameras.Scene2D.Effects.Pan#isRunning - * @type {boolean} - * @readonly - * @default false - * @since 3.11.0 + * This is the default Phaser 3 mobile pipeline and is used by the WebGL Renderer to manage + * camera effects and more on mobile devices. This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.PipelineManager#MOBILE_PIPELINE + * @type {Phaser.Renderer.WebGL.Pipelines.MobilePipeline} + * @default null + * @since 3.60.0 */ - this.isRunning = false; + this.MOBILE_PIPELINE = null; /** - * The duration of the effect, in milliseconds. + * A constant-style reference to the FX Pipeline Instance. * - * @name Phaser.Cameras.Scene2D.Effects.Pan#duration - * @type {number} - * @readonly - * @default 0 - * @since 3.11.0 + * This is the default Phaser 3 FX pipeline and is used by the WebGL Renderer to manage + * Game Objects with special effects enabled. This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.PipelineManager#FX_PIPELINE + * @type {Phaser.Renderer.WebGL.Pipelines.FXPipeline} + * @default null + * @since 3.60.0 */ - this.duration = 0; + this.FX_PIPELINE = null; /** - * The starting scroll coordinates to pan the camera from. - * - * @name Phaser.Cameras.Scene2D.Effects.Pan#source - * @type {Phaser.Math.Vector2} - * @since 3.11.0 + * 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.PipelineManager#fullFrame1 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 */ - this.source = new Vector2(); + this.fullFrame1; /** - * The constantly updated value based on zoom. - * - * @name Phaser.Cameras.Scene2D.Effects.Pan#current - * @type {Phaser.Math.Vector2} - * @since 3.11.0 + * 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.PipelineManager#fullFrame2 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 */ - this.current = new Vector2(); + this.fullFrame2; /** - * The destination scroll coordinates to pan the camera to. - * - * @name Phaser.Cameras.Scene2D.Effects.Pan#destination - * @type {Phaser.Math.Vector2} - * @since 3.11.0 + * 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.PipelineManager#halfFrame1 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 */ - this.destination = new Vector2(); + this.halfFrame1; /** - * The ease function to use during the pan. - * - * @name Phaser.Cameras.Scene2D.Effects.Pan#ease - * @type {function} - * @since 3.11.0 + * 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.PipelineManager#halfFrame2 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @default null + * @since 3.50.0 */ - this.ease; + this.halfFrame2; /** - * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. + * An array of RenderTarget instances that belong to this pipeline. * - * @name Phaser.Cameras.Scene2D.Effects.Pan#progress - * @type {number} - * @since 3.11.0 + * @name Phaser.Renderer.WebGL.PipelineManager#renderTargets + * @type {Phaser.Renderer.WebGL.RenderTarget[]} + * @since 3.60.0 */ - this.progress = 0; + this.renderTargets = []; /** - * Effect elapsed timer. + * The largest render target dimension before we just use a full-screen target. * - * @name Phaser.Cameras.Scene2D.Effects.Pan#_elapsed + * @name Phaser.Renderer.WebGL.PipelineManager#maxDimension * @type {number} - * @private - * @since 3.11.0 + * @since 3.60.0 */ - this._elapsed = 0; + this.maxDimension = 0; /** - * This callback is invoked every frame for the duration of the effect. + * The amount in which each target frame will increase. * - * @name Phaser.Cameras.Scene2D.Effects.Pan#_onUpdate - * @type {?Phaser.Types.Cameras.Scene2D.CameraPanCallback} - * @private - * @default null - * @since 3.11.0 + * Defaults to 32px but can be overridden in the config. + * + * @name Phaser.Renderer.WebGL.PipelineManager#frameInc + * @type {number} + * @since 3.60.0 */ - this._onUpdate; + this.frameInc = 32; /** - * On Complete callback scope. + * The Render Target index. Used internally by the methods + * in this class. Do not modify directly. * - * @name Phaser.Cameras.Scene2D.Effects.Pan#_onUpdateScope - * @type {any} - * @private - * @since 3.11.0 + * @name Phaser.Renderer.WebGL.PipelineManager#targetIndex + * @type {number} + * @since 3.60.0 */ - this._onUpdateScope; + this.targetIndex = 0; }, /** - * This effect will scroll the Camera so that the center of its viewport finishes at the given destination, - * over the duration and with the ease specified. + * Internal boot handler, called by the WebGLRenderer durings its boot process. * - * @method Phaser.Cameras.Scene2D.Effects.Pan#start - * @fires Phaser.Cameras.Scene2D.Events#PAN_START - * @fires Phaser.Cameras.Scene2D.Events#PAN_COMPLETE - * @since 3.11.0 + * Adds all of the default pipelines, based on the game config, and then calls + * the `boot` method on each one of them. * - * @param {number} x - The destination x coordinate to scroll the center of the Camera viewport to. - * @param {number} y - The destination y coordinate to scroll the center of the Camera viewport to. - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {(string|function)} [ease='Linear'] - The ease to use for the pan. Can be any of the Phaser Easing constants or a custom function. - * @param {boolean} [force=false] - Force the pan effect to start immediately, even if already running. - * @param {Phaser.Types.Cameras.Scene2D.CameraPanCallback} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, - * the current camera scroll x coordinate and the current camera scroll y coordinate. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * Finally, the default pipeline is set. * - * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. + * @method Phaser.Renderer.WebGL.PipelineManager#boot + * @since 3.50.0 + * + * @param {Phaser.Types.Core.PipelineConfig} pipelineConfig - The pipeline configuration object as set in the Game Config. + * @param {string} defaultPipeline - The name of the default Game Object pipeline, as set in the Game Config + * @param {boolean} autoMobilePipeline - Automatically set the default pipeline to mobile if non-desktop detected? */ - start: function (x, y, duration, ease, force, callback, context) + boot: function (pipelineConfig, defaultPipeline, autoMobilePipeline) { - if (duration === undefined) { duration = 1000; } - if (ease === undefined) { ease = EaseMap.Linear; } - if (force === undefined) { force = false; } - if (callback === undefined) { callback = null; } - if (context === undefined) { context = this.camera.scene; } + // Create the default RenderTextures + var renderer = this.renderer; + var targets = this.renderTargets; - var cam = this.camera; + this.frameInc = Math.floor(GetFastValue(pipelineConfig, 'frameInc', 32)); - if (!force && this.isRunning) + var renderWidth = renderer.width; + var renderHeight = renderer.height; + + var minDimension = Math.min(renderWidth, renderHeight); + + var qty = Math.ceil(minDimension / this.frameInc); + + for (var i = 1; i < qty; i++) { - return cam; + var targetWidth = i * this.frameInc; + + targets.push(new RenderTarget(renderer, targetWidth, targetWidth)); + + // Duplicate RT for swap frame + targets.push(new RenderTarget(renderer, targetWidth, targetWidth)); + + // Duplicate RT for alt swap frame + targets.push(new RenderTarget(renderer, targetWidth, targetWidth)); + + this.maxDimension = targetWidth; } - this.isRunning = true; - this.duration = duration; - this.progress = 0; + // Full-screen RTs + targets.push(new RenderTarget(renderer, renderWidth, renderHeight, 1, 0, true, true)); + targets.push(new RenderTarget(renderer, renderWidth, renderHeight, 1, 0, true, true)); + targets.push(new RenderTarget(renderer, renderWidth, renderHeight, 1, 0, true, true)); - // Starting from - this.source.set(cam.scrollX, cam.scrollY); + // Install each of the default pipelines - // Destination - this.destination.set(x, y); + var instance; + var pipelineName; - // Zoom factored version - cam.getScroll(x, y, this.current); + var _this = this; + var game = this.game; - // Using this ease - if (typeof ease === 'string' && EaseMap.hasOwnProperty(ease)) + this.classes.each(function (pipelineName, pipeline) { - this.ease = EaseMap[ease]; - } - else if (typeof ease === 'function') + instance = _this.add(pipelineName, new pipeline({ game: game })); + + if (pipelineName === CONST.UTILITY_PIPELINE) + { + _this.UTILITY_PIPELINE = instance; + + // FBO references + _this.fullFrame1 = instance.fullFrame1; + _this.fullFrame2 = instance.fullFrame2; + _this.halfFrame1 = instance.halfFrame1; + _this.halfFrame2 = instance.halfFrame2; + } + }); + + // Our const-like references + this.MULTI_PIPELINE = this.get(CONST.MULTI_PIPELINE); + this.BITMAPMASK_PIPELINE = this.get(CONST.BITMAPMASK_PIPELINE); + this.MOBILE_PIPELINE = this.get(CONST.MOBILE_PIPELINE); + this.FX_PIPELINE = this.get(CONST.FX_PIPELINE); + + // And now the ones in the config, if any + + if (pipelineConfig) { - this.ease = ease; - } + for (pipelineName in pipelineConfig) + { + var pipelineClass = pipelineConfig[pipelineName]; - this._elapsed = 0; + instance = new pipelineClass(game); - this._onUpdate = callback; - this._onUpdateScope = context; + instance.name = pipelineName; - this.camera.emit(Events.PAN_START, this.camera, this, duration, x, y); + if (instance.isPostFX) + { + this.postPipelineClasses.set(pipelineName, pipelineClass); + } + else if (!this.has(pipelineName)) + { + this.classes.set(pipelineName, pipelineClass); - return cam; + this.add(pipelineName, instance); + } + } + } + + // Finally, set the Default Game Object pipeline + this.default = this.get(defaultPipeline); + + if (autoMobilePipeline && !Device.os.desktop) + { + this.default = this.MOBILE_PIPELINE; + } }, /** - * The main update loop for this effect. Called automatically by the Camera. + * Sets the default pipeline being used by Game Objects. * - * @method Phaser.Cameras.Scene2D.Effects.Pan#update - * @since 3.11.0 + * If no instance, or matching name, exists in this manager, it returns `undefined`. * - * @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. + * You can use this to override the default pipeline, for example by forcing + * the Mobile or Multi Tint Pipelines, which is especially useful for development + * testing. + * + * Make sure you call this method _before_ creating any Game Objects, as it will + * only impact Game Objects created after you call it. + * + * @method Phaser.Renderer.WebGL.PipelineManager#setDefaultPipeline + * @since 3.60.0 + * + * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up. + * + * @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance that was set as default, or `undefined` if not found. */ - update: function (time, delta) + setDefaultPipeline: function (pipeline) { - if (!this.isRunning) + var instance = this.get(pipeline); + + if (instance) { - return; + this.default = instance; } - this._elapsed += delta; - - var progress = Clamp(this._elapsed / this.duration, 0, 1); - - this.progress = progress; - - var cam = this.camera; + return instance; + }, - if (this._elapsed < this.duration) + /** + * Adds a pipeline instance to this Pipeline Manager. + * + * The name of the instance must be unique within this manager. + * + * Make sure to pass an instance to this method, not a base class. + * + * For example, you should pass it like this: + * + * ```javascript + * this.add('yourName', new CustomPipeline(game));` + * ``` + * + * and **not** like this: + * + * ```javascript + * this.add('yourName', CustomPipeline);` + * ``` + * + * To add a **Post Pipeline**, see `addPostPipeline` instead. + * + * @method Phaser.Renderer.WebGL.PipelineManager#add + * @since 3.50.0 + * + * @param {string} name - A unique string-based key for the pipeline within the manager. + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - A pipeline _instance_ which must extend `WebGLPipeline`. + * + * @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance that was passed. + */ + add: function (name, pipeline) + { + if (pipeline.isPostFX) { - var v = this.ease(progress); + console.warn(name + ' is a Post Pipeline. Use `addPostPipeline` instead'); - cam.getScroll(this.destination.x, this.destination.y, this.current); + return; + } - var x = this.source.x + ((this.current.x - this.source.x) * v); - var y = this.source.y + ((this.current.y - this.source.y) * v); + var pipelines = this.pipelines; + var renderer = this.renderer; - cam.setScroll(x, y); + if (!pipelines.has(name)) + { + pipeline.name = name; + pipeline.manager = this; - if (this._onUpdate) - { - this._onUpdate.call(this._onUpdateScope, cam, progress, x, y); - } + pipelines.set(name, pipeline); } else { - cam.centerOn(this.destination.x, this.destination.y); + console.warn('Pipeline exists: ' + name); + } - if (this._onUpdate) - { - this._onUpdate.call(this._onUpdateScope, cam, progress, cam.scrollX, cam.scrollY); - } - - this.effectComplete(); + if (!pipeline.hasBooted) + { + pipeline.boot(); + } + + if (renderer.width !== 0 && renderer.height !== 0 && !pipeline.isPreFX) + { + pipeline.resize(renderer.width, renderer.height); } + + return pipeline; }, /** - * Called internally when the effect completes. + * Adds a Post Pipeline to this Pipeline Manager. * - * @method Phaser.Cameras.Scene2D.Effects.Pan#effectComplete - * @fires Phaser.Cameras.Scene2D.Events#PAN_COMPLETE - * @since 3.11.0 + * Make sure to pass a base class to this method, not an instance. + * + * For example, you should pass it like this: + * + * ```javascript + * this.addPostPipeline('yourName', CustomPipeline);` + * ``` + * + * and **not** like this: + * + * ```javascript + * this.addPostPipeline('yourName', new CustomPipeline());` + * ``` + * + * To add a regular pipeline, see the `add` method instead. + * + * @method Phaser.Renderer.WebGL.PipelineManager#addPostPipeline + * @since 3.50.0 + * + * @param {string} name - A unique string-based key for the pipeline within the manager. + * @param {function} pipeline - A pipeline class which must extend `PostFXPipeline`. + * + * @return {this} This Pipeline Manager. */ - effectComplete: function () + addPostPipeline: function (name, pipeline) { - this._onUpdate = null; - this._onUpdateScope = null; - - this.isRunning = false; - - this.camera.emit(Events.PAN_COMPLETE, this.camera, this); + if (!this.postPipelineClasses.has(name)) + { + this.postPipelineClasses.set(name, pipeline); + } }, /** - * Resets this camera effect. - * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. + * Flushes the current pipeline, if one is bound. * - * @method Phaser.Cameras.Scene2D.Effects.Pan#reset - * @since 3.11.0 + * @method Phaser.Renderer.WebGL.PipelineManager#flush + * @since 3.50.0 */ - reset: function () + flush: function () { - this.isRunning = false; - - this._onUpdate = null; - this._onUpdateScope = null; + if (this.current) + { + this.current.flush(); + } }, /** - * Destroys this effect, releasing it from the Camera. + * Checks if a pipeline is present in this Pipeline Manager. * - * @method Phaser.Cameras.Scene2D.Effects.Pan#destroy - * @since 3.11.0 + * @method Phaser.Renderer.WebGL.PipelineManager#has + * @since 3.50.0 + * + * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up. + * + * @return {boolean} `true` if the given pipeline is loaded, otherwise `false`. */ - destroy: function () + has: function (pipeline) { - this.reset(); - - this.camera = null; - this.source = null; - this.destination = null; - } - -}); - -module.exports = Pan; - - -/***/ }), -/* 764 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Back ease-in. - * - * @function Phaser.Math.Easing.Back.In - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * @param {number} [overshoot=1.70158] - The overshoot amount. - * - * @return {number} The tweened value. - */ -var In = function (v, overshoot) -{ - if (overshoot === undefined) { overshoot = 1.70158; } + var pipelines = this.pipelines; - return v * v * ((overshoot + 1) * v - overshoot); -}; + if (typeof pipeline === 'string') + { + return pipelines.has(pipeline); + } + else if (pipelines.contains(pipeline)) + { + return true; + } -module.exports = In; + return false; + }, + /** + * Returns the pipeline instance based on the given name, or instance. + * + * If no instance, or matching name, exists in this manager, it returns `undefined`. + * + * @method Phaser.Renderer.WebGL.PipelineManager#get + * @since 3.50.0 + * + * @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up. + * + * @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance, or `undefined` if not found. + */ + get: function (pipeline) + { + var pipelines = this.pipelines; -/***/ }), -/* 765 */ -/***/ (function(module, exports) { + if (typeof pipeline === 'string') + { + return pipelines.get(pipeline); + } + else if (pipelines.contains(pipeline)) + { + return pipeline; + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Returns a _new instance_ of the post pipeline based on the given name, or class. + * + * If no instance, or matching name, exists in this manager, it returns `undefined`. + * + * @method Phaser.Renderer.WebGL.PipelineManager#getPostPipeline + * @since 3.50.0 + * + * @param {(string|function|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance, or class to look-up. + * @param {Phaser.GameObjects.GameObject} [gameObject] - If this post pipeline is being installed into a Game Object or Camera, this is a reference to it. + * @param {object} [config] - Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * + * @return {Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} The pipeline instance, or `undefined` if not found. + */ + getPostPipeline: function (pipeline, gameObject, config) + { + var pipelineClasses = this.postPipelineClasses; -/** - * Back ease-out. - * - * @function Phaser.Math.Easing.Back.Out - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * @param {number} [overshoot=1.70158] - The overshoot amount. - * - * @return {number} The tweened value. - */ -var Out = function (v, overshoot) -{ - if (overshoot === undefined) { overshoot = 1.70158; } + var instance; + var pipelineName = ''; + var pipetype = typeof pipeline; - return --v * v * ((overshoot + 1) * v + overshoot) + 1; -}; + if (pipetype === 'string' || pipetype === 'number') + { + instance = pipelineClasses.get(pipeline); + pipelineName = pipeline; + } + else if (pipetype === 'function') + { + // A class + if (pipelineClasses.contains(pipeline)) + { + instance = pipeline; + } -module.exports = Out; + pipelineName = pipeline.name; + } + else if (pipetype === 'object') + { + // Instance + instance = pipelineClasses.get(pipeline.name); + pipelineName = pipeline.name; + } -/***/ }), -/* 766 */ -/***/ (function(module, exports) { + if (instance) + { + var newPipeline = new instance(this.game, config); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + newPipeline.name = pipelineName; -/** - * Back ease-in/out. - * - * @function Phaser.Math.Easing.Back.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * @param {number} [overshoot=1.70158] - The overshoot amount. - * - * @return {number} The tweened value. - */ -var InOut = function (v, overshoot) -{ - if (overshoot === undefined) { overshoot = 1.70158; } + if (gameObject) + { + newPipeline.gameObject = gameObject; + } - var s = overshoot * 1.525; + return newPipeline; + } + }, - if ((v *= 2) < 1) - { - return 0.5 * (v * v * ((s + 1) * v - s)); - } - else + /** + * Removes a pipeline instance based on the given name. + * + * If no pipeline matches the name, this method does nothing. + * + * Note that the pipeline will not be flushed or destroyed, it's simply removed from + * this manager. + * + * @method Phaser.Renderer.WebGL.PipelineManager#remove + * @since 3.50.0 + * + * @param {string} name - The name of the pipeline to be removed. + * @param {boolean} [removeClass=true] - Remove the pipeline class as well as the instance? + * @param {boolean} [removePostPipelineClass=true] - Remove the post pipeline class as well as the instance? + */ + remove: function (name, removeClass, removePostPipelineClass) { - return 0.5 * ((v -= 2) * v * ((s + 1) * v + s) + 2); - } -}; - -module.exports = InOut; - + if (removeClass === undefined) { removeClass = true; } + if (removePostPipelineClass === undefined) { removePostPipelineClass = true; } -/***/ }), -/* 767 */ -/***/ (function(module, exports) { + this.pipelines.delete(name); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (removeClass) + { + this.classes.delete(name); + } -/** - * Bounce ease-in. - * - * @function Phaser.Math.Easing.Bounce.In - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var In = function (v) -{ - v = 1 - v; + if (removePostPipelineClass) + { + this.postPipelineClasses.delete(name); + } + }, - if (v < 1 / 2.75) - { - return 1 - (7.5625 * v * v); - } - else if (v < 2 / 2.75) - { - return 1 - (7.5625 * (v -= 1.5 / 2.75) * v + 0.75); - } - else if (v < 2.5 / 2.75) - { - return 1 - (7.5625 * (v -= 2.25 / 2.75) * v + 0.9375); - } - else + /** + * Sets the current pipeline to be used by the `WebGLRenderer`. + * + * This method accepts a pipeline instance as its parameter, not the name. + * + * If the pipeline isn't already the current one it will call `WebGLPipeline.bind` and then `onBind`. + * + * You cannot set Post FX Pipelines using this method. To use a Post FX Pipeline, you should + * apply it to either a Camera, Container or other supporting Game Object. + * + * @method Phaser.Renderer.WebGL.PipelineManager#set + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline instance to be set as current. + * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. + * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. + * + * @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline that was set, or undefined if it couldn't be set. + */ + set: function (pipeline, gameObject, currentShader) { - return 1 - (7.5625 * (v -= 2.625 / 2.75) * v + 0.984375); - } -}; - -module.exports = In; - - -/***/ }), -/* 768 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (pipeline.isPostFX) + { + return; + } -/** - * Bounce ease-out. - * - * @function Phaser.Math.Easing.Bounce.Out - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var Out = function (v) -{ - if (v < 1 / 2.75) - { - return 7.5625 * v * v; - } - else if (v < 2 / 2.75) - { - return 7.5625 * (v -= 1.5 / 2.75) * v + 0.75; - } - else if (v < 2.5 / 2.75) - { - return 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375; - } - else - { - return 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375; - } -}; + if (!this.isCurrent(pipeline, currentShader)) + { + this.flush(); -module.exports = Out; + if (this.current) + { + this.current.unbind(); + } + this.current = pipeline; -/***/ }), -/* 769 */ -/***/ (function(module, exports) { + pipeline.bind(currentShader); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + pipeline.updateProjectionMatrix(); -/** - * Bounce ease-in/out. - * - * @function Phaser.Math.Easing.Bounce.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var InOut = function (v) -{ - var reverse = false; + pipeline.onBind(gameObject); - if (v < 0.5) - { - v = 1 - (v * 2); - reverse = true; - } - else - { - v = (v * 2) - 1; - } + return pipeline; + }, - if (v < 1 / 2.75) - { - v = 7.5625 * v * v; - } - else if (v < 2 / 2.75) - { - v = 7.5625 * (v -= 1.5 / 2.75) * v + 0.75; - } - else if (v < 2.5 / 2.75) - { - v = 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375; - } - else + /** + * This method is called by the `WebGLPipeline.batchQuad` method, right before a quad + * belonging to a Game Object is about to be added to the batch. + * + * It is also called directly bu custom Game Objects, such as Nine Slice or Mesh, + * from their render methods. + * + * It causes a batch flush, then calls the `preBatch` method on the Post FX Pipelines + * belonging to the Game Object. + * + * It should be followed by a call to `postBatch` to complete the process. + * + * @method Phaser.Renderer.WebGL.PipelineManager#preBatch + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object about to be batched. + */ + preBatch: function (gameObject) { - v = 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375; - } + if (gameObject.hasPostPipeline) + { + this.flush(); - if (reverse) - { - return (1 - v) * 0.5; - } - else - { - return v * 0.5 + 0.5; - } -}; + var pipelines = gameObject.postPipelines; -module.exports = InOut; + // Iterate in reverse because we need them stacked in the order they're in the array + for (var i = pipelines.length - 1; i >= 0; i--) + { + var pipeline = pipelines[i]; + if (pipeline.active) + { + pipeline.preBatch(gameObject); + } + } + } + }, -/***/ }), -/* 770 */ -/***/ (function(module, exports) { + /** + * This method is called by the `WebGLPipeline.batchQuad` method, right after a quad + * belonging to a Game Object has been added to the batch. + * + * It is also called directly bu custom Game Objects, such as Nine Slice or Mesh, + * from their render methods. + * + * It causes a batch flush, then calls the `postBatch` method on the Post FX Pipelines + * belonging to the Game Object. + * + * It should be preceeded by a call to `preBatch` to start the process. + * + * @method Phaser.Renderer.WebGL.PipelineManager#postBatch + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to the batch. + */ + postBatch: function (gameObject) + { + if (gameObject.hasPostPipeline) + { + this.flush(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var pipelines = gameObject.postPipelines; -/** - * Circular ease-in. - * - * @function Phaser.Math.Easing.Circular.In - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var In = function (v) -{ - return 1 - Math.sqrt(1 - v * v); -}; + for (var i = 0; i < pipelines.length; i++) + { + var pipeline = pipelines[i]; -module.exports = In; + if (pipeline.active) + { + pipeline.postBatch(gameObject); + } + } + } + }, + /** + * Called at the start of the `WebGLRenderer.preRenderCamera` method. + * + * If the Camera has post pipelines set, it will flush the batch and then call the + * `preBatch` method on the post-fx pipelines belonging to the Camera. + * + * @method Phaser.Renderer.WebGL.PipelineManager#preBatchCamera + * @since 3.50.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera about to be rendered. + */ + preBatchCamera: function (camera) + { + if (camera.hasPostPipeline) + { + this.flush(); -/***/ }), -/* 771 */ -/***/ (function(module, exports) { + var pipelines = camera.postPipelines; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Iterate in reverse because we need them stacked in the order they're in the array + for (var i = pipelines.length - 1; i >= 0; i--) + { + var pipeline = pipelines[i]; -/** - * Circular ease-out. - * - * @function Phaser.Math.Easing.Circular.Out - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var Out = function (v) -{ - return Math.sqrt(1 - (--v * v)); -}; + if (pipeline.active) + { + pipeline.preBatch(camera); + } + } + } + }, -module.exports = Out; + /** + * Called at the end of the `WebGLRenderer.postRenderCamera` method. + * + * If the Camera has post pipelines set, it will flush the batch and then call the + * `postBatch` method on the post-fx pipelines belonging to the Camera. + * + * @method Phaser.Renderer.WebGL.PipelineManager#postBatchCamera + * @since 3.50.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that was just rendered. + */ + postBatchCamera: function (camera) + { + if (camera.hasPostPipeline) + { + this.flush(); + var pipelines = camera.postPipelines; -/***/ }), -/* 772 */ -/***/ (function(module, exports) { + for (var i = 0; i < pipelines.length; i++) + { + var pipeline = pipelines[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (pipeline.active) + { + pipeline.postBatch(camera); + } + } + } + }, -/** - * Circular ease-in/out. - * - * @function Phaser.Math.Easing.Circular.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var InOut = function (v) -{ - if ((v *= 2) < 1) - { - return -0.5 * (Math.sqrt(1 - v * v) - 1); - } - else + /** + * Checks to see if the given pipeline is already the active pipeline, both within this + * Pipeline Manager and also has the same shader set in the Renderer. + * + * @method Phaser.Renderer.WebGL.PipelineManager#isCurrent + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline instance to be checked. + * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. + * + * @return {boolean} `true` if the given pipeline is already the current pipeline, otherwise `false`. + */ + isCurrent: function (pipeline, currentShader) { - return 0.5 * (Math.sqrt(1 - (v -= 2) * v) + 1); - } -}; + var renderer = this.renderer; + var current = this.current; -module.exports = InOut; + if (current && !currentShader) + { + currentShader = current.currentShader; + } + return !(current !== pipeline || currentShader.program !== renderer.currentProgram); + }, -/***/ }), -/* 773 */ -/***/ (function(module, exports) { + /** + * 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. + * + * The copy itself is handled by the Utility Pipeline. + * + * @method Phaser.Renderer.WebGL.PipelineManager#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? + * + * @return {this} This Pipeline Manager instance. + */ + copyFrame: function (source, target, brightness, clear, clearAlpha) + { + this.setUtility(this.UTILITY_PIPELINE.copyShader).copyFrame(source, target, brightness, clear, clearAlpha); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * Cubic ease-in. - * - * @function Phaser.Math.Easing.Cubic.In - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var In = function (v) -{ - return v * v * v; -}; + /** + * 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.PipelineManager#copyToGame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. + */ + copyToGame: function (source) + { + this.setUtility(this.UTILITY_PIPELINE.copyShader).copyToGame(source); -module.exports = In; + return this; + }, + /** + * 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. + * + * The copy itself is handled by the Utility Pipeline. + * + * @method Phaser.Renderer.WebGL.PipelineManager#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? + * @param {Phaser.Display.ColorMatrix} [colorMatrix] - The Color Matrix to use when performing the draw. + * + * @return {this} This Pipeline Manager instance. + */ + drawFrame: function (source, target, clearAlpha, colorMatrix) + { + this.setUtility(this.UTILITY_PIPELINE.colorMatrixShader).drawFrame(source, target, clearAlpha, colorMatrix); -/***/ }), -/* 774 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Draws the `source1` and `source2` Render Targets to the `target` Render Target + * using a linear blend effect, which is controlled by the `strength` parameter. + * + * The draw itself is handled by the Utility Pipeline. + * + * @method Phaser.Renderer.WebGL.PipelineManager#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? + * + * @return {this} This Pipeline Manager instance. + */ + blendFrames: function (source1, source2, target, strength, clearAlpha) + { + this.setUtility(this.UTILITY_PIPELINE.linearShader).blendFrames(source1, source2, target, strength, clearAlpha); -/** - * Cubic ease-out. - * - * @function Phaser.Math.Easing.Cubic.Out - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var Out = function (v) -{ - return --v * v * v + 1; -}; + return this; + }, -module.exports = Out; + /** + * Draws the `source1` and `source2` Render Targets to the `target` Render Target + * using an additive blend effect, which is controlled by the `strength` parameter. + * + * The draw itself is handled by the Utility Pipeline. + * + * @method Phaser.Renderer.WebGL.PipelineManager#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? + * + * @return {this} This Pipeline Manager instance. + */ + blendFramesAdditive: function (source1, source2, target, strength, clearAlpha) + { + this.setUtility(this.UTILITY_PIPELINE.addShader).blendFramesAdditive(source1, source2, target, strength, clearAlpha); + return this; + }, -/***/ }), -/* 775 */ -/***/ (function(module, exports) { + /** + * Clears the given Render Target. + * + * @method Phaser.Renderer.WebGL.PipelineManager#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? + * + * @return {this} This Pipeline Manager instance. + */ + clearFrame: function (target, clearAlpha) + { + this.UTILITY_PIPELINE.clearFrame(target, clearAlpha); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * Cubic ease-in/out. - * - * @function Phaser.Math.Easing.Cubic.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var InOut = function (v) -{ - if ((v *= 2) < 1) - { - return 0.5 * v * v * v; - } - else - { - return 0.5 * ((v -= 2) * v * v + 2); - } -}; + /** + * 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.PipelineManager#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? + * + * @return {this} This Pipeline Manager instance. + */ + blitFrame: function (source, target, brightness, clear, clearAlpha, eraseMode) + { + this.setUtility(this.UTILITY_PIPELINE.copyShader).blitFrame(source, target, brightness, clear, clearAlpha, eraseMode); -module.exports = InOut; + return this; + }, + /** + * 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.PipelineManager#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? + * + * @return {this} This Pipeline Manager instance. + */ + copyFrameRect: function (source, target, x, y, width, height, clear, clearAlpha) + { + this.UTILITY_PIPELINE.copyFrameRect(source, target, x, y, width, height, clear, clearAlpha); -/***/ }), -/* 776 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Returns `true` if the current pipeline is forced to use texture unit zero. + * + * @method Phaser.Renderer.WebGL.PipelineManager#forceZero + * @since 3.50.0 + * + * @return {boolean} `true` if the current pipeline is forced to use texture unit zero. + */ + forceZero: function () + { + return (this.current && this.current.forceZero); + }, -/** - * Elastic ease-in. - * - * @function Phaser.Math.Easing.Elastic.In - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * @param {number} [amplitude=0.1] - The amplitude of the elastic ease. - * @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles. - * - * @return {number} The tweened value. - */ -var In = function (v, amplitude, period) -{ - if (amplitude === undefined) { amplitude = 0.1; } - if (period === undefined) { period = 0.1; } + /** + * Sets the Multi Pipeline to be the currently bound pipeline. + * + * This is the default Phaser 3 rendering pipeline. + * + * @method Phaser.Renderer.WebGL.PipelineManager#setMulti + * @since 3.50.0 + * + * @return {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} The Multi Pipeline instance. + */ + setMulti: function () + { + return this.set(this.MULTI_PIPELINE); + }, - if (v === 0) + /** + * Sets the Utility Pipeline to be the currently bound pipeline. + * + * @method Phaser.Renderer.WebGL.PipelineManager#setUtility + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. + * + * @return {Phaser.Renderer.WebGL.Pipelines.UtilityPipeline} The Utility Pipeline instance. + */ + setUtility: function (currentShader) { - return 0; - } - else if (v === 1) + return this.UTILITY_PIPELINE.bind(currentShader); + }, + + /** + * Sets the FX Pipeline to be the currently bound pipeline. + * + * @method Phaser.Renderer.WebGL.PipelineManager#setFX + * @since 3.60.0 + * + * @return {Phaser.Renderer.WebGL.Pipelines.FXPipeline} The FX Pipeline instance. + */ + setFX: function () { - return 1; - } - else + return this.set(this.FX_PIPELINE); + }, + + /** + * Use this to reset the gl context to the state that Phaser requires to continue rendering. + * + * Calling this will: + * + * * Disable `DEPTH_TEST`, `CULL_FACE` and `STENCIL_TEST`. + * * Clear the depth buffer and stencil buffers. + * * Reset the viewport size. + * * Reset the blend mode. + * * Bind a blank texture as the active texture on texture unit zero. + * * Rebinds the given pipeline instance. + * + * You should call this if you have previously called `clear`, and then wish to return + * rendering control to Phaser again. + * + * @method Phaser.Renderer.WebGL.PipelineManager#rebind + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.WebGLPipeline} [pipeline] - The pipeline instance to be rebound. If not given, the previous pipeline will be bound. + */ + rebind: function (pipeline) { - var s = period / 4; + if (pipeline === undefined && this.previous) + { + pipeline = this.previous; + } - if (amplitude < 1) + var renderer = this.renderer; + var gl = renderer.gl; + + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.CULL_FACE); + + if (renderer.hasActiveStencilMask()) { - amplitude = 1; + gl.clear(gl.DEPTH_BUFFER_BIT); } else { - s = period * Math.asin(1 / amplitude) / (2 * Math.PI); + // If there wasn't a stencil mask set before this call, we can disable it safely + gl.disable(gl.STENCIL_TEST); + gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); } - return -(amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period)); - } -}; + gl.viewport(0, 0, renderer.width, renderer.height); -module.exports = In; + renderer.currentProgram = null; + renderer.setBlendMode(0, true); -/***/ }), -/* 777 */ -/***/ (function(module, exports) { + var vao = renderer.vaoExtension; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (vao) + { + vao.bindVertexArrayOES(null); + } -/** - * Elastic ease-out. - * - * @function Phaser.Math.Easing.Elastic.Out - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * @param {number} [amplitude=0.1] - The amplitude of the elastic ease. - * @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles. - * - * @return {number} The tweened value. - */ -var Out = function (v, amplitude, period) -{ - if (amplitude === undefined) { amplitude = 0.1; } - if (period === undefined) { period = 0.1; } + var entries = this.pipelines.entries; - if (v === 0) - { - return 0; - } - else if (v === 1) - { - return 1; - } - else + for (var key in entries) + { + entries[key].glReset = true; + } + + if (pipeline) + { + this.current = pipeline; + + pipeline.rebind(); + } + }, + + /** + * Flushes the current pipeline being used and then clears it, along with the + * the current shader program and vertex buffer from the `WebGLRenderer`. + * + * Then resets the blend mode to NORMAL. + * + * Call this before jumping to your own gl context handler, and then call `rebind` when + * you wish to return control to Phaser again. + * + * @method Phaser.Renderer.WebGL.PipelineManager#clear + * @since 3.50.0 + */ + clear: function () { - var s = period / 4; + var renderer = this.renderer; - if (amplitude < 1) + this.flush(); + + if (this.current) { - amplitude = 1; + this.current.unbind(); + this.previous = this.current; + this.current = null; } else { - s = period * Math.asin(1 / amplitude) / (2 * Math.PI); + this.previous = null; } - return (amplitude * Math.pow(2, -10 * v) * Math.sin((v - s) * (2 * Math.PI) / period) + 1); - } -}; - -module.exports = Out; - + renderer.currentProgram = null; -/***/ }), -/* 778 */ -/***/ (function(module, exports) { + renderer.setBlendMode(0, true); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var vao = renderer.vaoExtension; -/** - * Elastic ease-in/out. - * - * @function Phaser.Math.Easing.Elastic.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * @param {number} [amplitude=0.1] - The amplitude of the elastic ease. - * @param {number} [period=0.1] - Sets how tight the sine-wave is, where smaller values are tighter waves, which result in more cycles. - * - * @return {number} The tweened value. - */ -var InOut = function (v, amplitude, period) -{ - if (amplitude === undefined) { amplitude = 0.1; } - if (period === undefined) { period = 0.1; } + if (vao) + { + vao.bindVertexArrayOES(null); + } + }, - if (v === 0) - { - return 0; - } - else if (v === 1) - { - return 1; - } - else + /** + * Gets a Render Target the right size to render the Sprite on. + * + * If the Sprite exceeds the size of the renderer, the Render Target will only ever be the maximum + * size of the renderer. + * + * @method Phaser.Renderer.WebGL.PipelineManager#getRenderTarget + * @since 3.60.0 + * + * @param {number} size - The maximum dimension required. + * + * @return {Phaser.Renderer.WebGL.RenderTarget} A Render Target large enough to fit the sprite. + */ + getRenderTarget: function (size) { - var s = period / 4; + var targets = this.renderTargets; - if (amplitude < 1) - { - amplitude = 1; - } - else - { - s = period * Math.asin(1 / amplitude) / (2 * Math.PI); - } + // 2 for just swap + // 3 for swap + alt swap + var offset = 3; - if ((v *= 2) < 1) + if (size > this.maxDimension) { - return -0.5 * (amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period)); + this.targetIndex = targets.length - offset; + + return targets[this.targetIndex]; } else { - return amplitude * Math.pow(2, -10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period) * 0.5 + 1; + var index = (SnapCeil(size, this.frameInc, 0, true) - 1) * offset; + + this.targetIndex = index; + + return targets[index]; } - } -}; + }, -module.exports = InOut; + /** + * Gets a matching Render Target, the same size as the one the Sprite was drawn to, + * useful for double-buffer style effects such as blurs. + * + * @method Phaser.Renderer.WebGL.PipelineManager#getSwapRenderTarget + * @since 3.60.0 + * + * @return {Phaser.Renderer.WebGL.RenderTarget} The Render Target swap frame. + */ + getSwapRenderTarget: function () + { + return this.renderTargets[this.targetIndex + 1]; + }, + /** + * Gets a matching Render Target, the same size as the one the Sprite was drawn to, + * useful for double-buffer style effects such as blurs. + * + * @method Phaser.Renderer.WebGL.PipelineManager#getAltSwapRenderTarget + * @since 3.60.0 + * + * @return {Phaser.Renderer.WebGL.RenderTarget} The Render Target swap frame. + */ + getAltSwapRenderTarget: function () + { + return this.renderTargets[this.targetIndex + 2]; + }, -/***/ }), -/* 779 */ -/***/ (function(module, exports) { + /** + * Destroy the Pipeline Manager, cleaning up all related resources and references. + * + * @method Phaser.Renderer.WebGL.PipelineManager#destroy + * @since 3.50.0 + */ + destroy: function () + { + this.flush(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.classes.clear(); + this.postPipelineClasses.clear(); + this.pipelines.clear(); -/** - * Exponential ease-in. - * - * @function Phaser.Math.Easing.Expo.In - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var In = function (v) -{ - return Math.pow(2, 10 * (v - 1)) - 0.001; -}; + this.renderer = null; + this.game = null; + this.classes = null; + this.postPipelineClasses = null; + this.pipelines = null; + this.default = null; + this.current = null; + this.previous = null; + } -module.exports = In; +}); + +module.exports = PipelineManager; /***/ }), -/* 780 */ -/***/ (function(module, exports) { + +/***/ 37410: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var Events = __webpack_require__(81044); + /** - * Exponential ease-out. + * @classdesc + * A Render Target encapsulates a WebGL framebuffer and the WebGL Texture that displays it. * - * @function Phaser.Math.Easing.Expo.Out - * @since 3.0.0 + * 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. * - * @param {number} v - The value to be tweened. + * @class RenderTarget + * @memberof Phaser.Renderer.WebGL + * @constructor + * @since 3.50.0 * - * @return {number} The tweened value. + * @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? + * @param {boolean} [addDepthBuffer=true] - Add a DEPTH_STENCIL and attachment to this Render Target? + * @param {boolean} [forceClamp=true] - Force the texture to use the CLAMP_TO_EDGE wrap mode, even if a power of two? */ -var Out = function (v) -{ - return 1 - Math.pow(2, -10 * v); -}; +var RenderTarget = new Class({ -module.exports = Out; + initialize: + function RenderTarget (renderer, width, height, scale, minFilter, autoClear, autoResize, addDepthBuffer, forceClamp) + { + if (scale === undefined) { scale = 1; } + if (minFilter === undefined) { minFilter = 0; } + if (autoClear === undefined) { autoClear = true; } + if (autoResize === undefined) { autoResize = false; } + if (addDepthBuffer === undefined) { addDepthBuffer = true; } + if (forceClamp === undefined) { forceClamp = true; } -/***/ }), -/* 781 */ -/***/ (function(module, exports) { + /** + * A reference to the WebGLRenderer instance. + * + * @name Phaser.Renderer.WebGL.RenderTarget#renderer + * @type {Phaser.Renderer.WebGL.WebGLRenderer} + * @since 3.50.0 + */ + this.renderer = renderer; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -/** - * Exponential ease-in/out. - * - * @function Phaser.Math.Easing.Expo.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var InOut = function (v) -{ - if ((v *= 2) < 1) - { - return 0.5 * Math.pow(2, 10 * (v - 1)); - } - else - { - return 0.5 * (2 - Math.pow(2, -10 * (v - 1))); - } -}; + /** + * 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; -module.exports = InOut; + /** + * 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; -/***/ }), -/* 782 */ -/***/ (function(module, exports) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -/** - * Linear easing (no variation). - * - * @function Phaser.Math.Easing.Linear - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var Linear = function (v) -{ - return v; -}; + /** + * 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; -module.exports = Linear; + /** + * 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 = true; + /** + * Does this Render Target have a Depth Buffer? + * + * @name Phaser.Renderer.WebGL.RenderTarget#hasDepthBuffer + * @type {boolean} + * @readonly + * @since 3.60.0 + */ + this.hasDepthBuffer = addDepthBuffer; -/***/ }), -/* 783 */ -/***/ (function(module, exports) { + /** + * Force the WebGL Texture to use the CLAMP_TO_EDGE wrap mode, even if a power of two? + * + * If `false` it will use `gl.REPEAT` instead, which may be required for some effects, such + * as using this Render Target as a texture for a Shader. + * + * @name Phaser.Renderer.WebGL.RenderTarget#forceClamp + * @type {boolean} + * @since 3.60.0 + */ + this.forceClamp = forceClamp; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.resize(width, height); -/** - * Quadratic ease-in. - * - * @function Phaser.Math.Easing.Quadratic.In - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var In = function (v) -{ - return v * v; -}; + if (autoResize) + { + this.setAutoResize(true); + } + else + { + // Block resizing unless this RT allows it + this.autoResize = false; + } + }, -module.exports = In; + /** + * 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); -/***/ }), -/* 784 */ -/***/ (function(module, exports) { + this.autoResize = false; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * Quadratic ease-out. - * - * @function Phaser.Math.Easing.Quadratic.Out - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var Out = function (v) -{ - return v * (2 - v); -}; + /** + * 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; -module.exports = Out; + if (this.autoResize && (scaledWidth !== this.width || scaledHeight !== this.height)) + { + var renderer = this.renderer; + renderer.deleteFramebuffer(this.framebuffer); -/***/ }), -/* 785 */ -/***/ (function(module, exports) { + renderer.deleteTexture(this.texture); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + width *= this.scale; + height *= this.scale; -/** - * Quadratic ease-in/out. - * - * @function Phaser.Math.Easing.Quadratic.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var InOut = function (v) -{ - if ((v *= 2) < 1) - { - return 0.5 * v * v; - } - else - { - return -0.5 * (--v * (v - 2) - 1); - } -}; + width = Math.round(width); + height = Math.round(height); -module.exports = InOut; + if (width <= 0) + { + width = 1; + } + if (height <= 0) + { + height = 1; + } -/***/ }), -/* 786 */ -/***/ (function(module, exports) { + this.texture = renderer.createTextureFromSource(null, width, height, this.minFilter, this.forceClamp); + this.framebuffer = renderer.createFramebuffer(width, height, this.texture, this.hasDepthBuffer); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.width = width; + this.height = height; + } -/** - * Quartic ease-in. - * - * @function Phaser.Math.Easing.Quartic.In - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var In = function (v) -{ - return v * v * v * v; -}; + return this; + }, -module.exports = In; + /** + * 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; } + var renderer = this.renderer; -/***/ }), -/* 787 */ -/***/ (function(module, exports) { + if (adjustViewport) + { + renderer.flush(); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (width && height) + { + this.resize(width, height); + } -/** - * Quartic ease-out. - * - * @function Phaser.Math.Easing.Quartic.Out - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var Out = function (v) -{ - return 1 - (--v * v * v * v); -}; + renderer.pushFramebuffer(this.framebuffer, false, false); -module.exports = Out; + if (adjustViewport) + { + this.adjustViewport(); + } + if (this.autoClear) + { + var gl = this.renderer.gl; -/***/ }), -/* 788 */ -/***/ (function(module, exports) { + gl.clearColor(0, 0, 0, 0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.clear(gl.COLOR_BUFFER_BIT); + } -/** - * Quartic ease-in/out. - * - * @function Phaser.Math.Easing.Quartic.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var InOut = function (v) -{ - if ((v *= 2) < 1) - { - return 0.5 * v * v * v * v; - } - else - { - return -0.5 * ((v -= 2) * v * v * v - 2); - } -}; + renderer.clearStencilMask(); + }, -module.exports = InOut; + /** + * 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); -/***/ }), -/* 789 */ -/***/ (function(module, exports) { + gl.disable(gl.SCISSOR_TEST); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Clears this Render Target. + * + * @method Phaser.Renderer.WebGL.RenderTarget#clear + * @since 3.50.0 + */ + clear: function () + { + var renderer = this.renderer; + var gl = renderer.gl; -/** - * Quintic ease-in. - * - * @function Phaser.Math.Easing.Quintic.In - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var In = function (v) -{ - return v * v * v * v * v; -}; + renderer.pushFramebuffer(this.framebuffer); -module.exports = In; + gl.disable(gl.SCISSOR_TEST); + gl.clearColor(0, 0, 0, 0); -/***/ }), -/* 790 */ -/***/ (function(module, exports) { + gl.clear(gl.COLOR_BUFFER_BIT); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + renderer.popFramebuffer(); -/** - * Quintic ease-out. - * - * @function Phaser.Math.Easing.Quintic.Out - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var Out = function (v) -{ - return --v * v * v * v * v + 1; -}; + renderer.resetScissor(); + }, -module.exports = Out; + /** + * 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; -/***/ }), -/* 791 */ -/***/ (function(module, exports) { + if (flush) + { + renderer.flush(); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return renderer.popFramebuffer(); + }, -/** - * Quintic ease-in/out. - * - * @function Phaser.Math.Easing.Quintic.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var InOut = function (v) -{ - if ((v *= 2) < 1) - { - return 0.5 * v * v * v * v * v; - } - else + /** + * 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 () { - return 0.5 * ((v -= 2) * v * v * v * v + 2); + 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 = InOut; +}); + +module.exports = RenderTarget; /***/ }), -/* 792 */ -/***/ (function(module, exports) { + +/***/ 75512: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @author Matthew Groves <@doormat> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Sinusoidal ease-in. - * - * @function Phaser.Math.Easing.Sine.In + * @namespace Phaser.Renderer.WebGL.Utils * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. */ -var In = function (v) -{ - if (v === 0) - { - return 0; - } - else if (v === 1) - { - return 1; - } - else - { - return 1 - Math.cos(v * Math.PI / 2); - } -}; +module.exports = { -module.exports = In; + /** + * Packs four floats on a range from 0.0 to 1.0 into a single Uint32 + * + * @function Phaser.Renderer.WebGL.Utils.getTintFromFloats + * @since 3.0.0 + * + * @param {number} r - Red component in a range from 0.0 to 1.0 + * @param {number} g - Green component in a range from 0.0 to 1.0 + * @param {number} b - Blue component in a range from 0.0 to 1.0 + * @param {number} a - Alpha component in a range from 0.0 to 1.0 + * + * @return {number} The packed RGBA values as a Uint32. + */ + getTintFromFloats: function (r, g, b, a) + { + var ur = ((r * 255) | 0) & 0xff; + var ug = ((g * 255) | 0) & 0xff; + var ub = ((b * 255) | 0) & 0xff; + var ua = ((a * 255) | 0) & 0xff; + return ((ua << 24) | (ur << 16) | (ug << 8) | ub) >>> 0; + }, -/***/ }), -/* 793 */ -/***/ (function(module, exports) { + /** + * Packs a Uint24, representing RGB components, with a Float32, representing + * the alpha component, with a range between 0.0 and 1.0 and return a Uint32 + * + * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlpha + * @since 3.0.0 + * + * @param {number} rgb - Uint24 representing RGB components + * @param {number} a - Float32 representing Alpha component + * + * @return {number} Packed RGBA as Uint32 + */ + getTintAppendFloatAlpha: function (rgb, a) + { + var ua = ((a * 255) | 0) & 0xff; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return ((ua << 24) | rgb) >>> 0; + }, -/** - * Sinusoidal ease-out. - * - * @function Phaser.Math.Easing.Sine.Out - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var Out = function (v) -{ - if (v === 0) - { - return 0; - } - else if (v === 1) + /** + * Packs a Uint24, representing RGB components, with a Float32, representing + * the alpha component, with a range between 0.0 and 1.0 and return a + * swizzled Uint32 + * + * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlphaAndSwap + * @since 3.0.0 + * + * @param {number} rgb - Uint24 representing RGB components + * @param {number} a - Float32 representing Alpha component + * + * @return {number} Packed RGBA as Uint32 + */ + getTintAppendFloatAlphaAndSwap: function (rgb, a) { - return 1; - } - else + var ur = ((rgb >> 16) | 0) & 0xff; + var ug = ((rgb >> 8) | 0) & 0xff; + var ub = (rgb | 0) & 0xff; + var ua = ((a * 255) | 0) & 0xff; + + return ((ua << 24) | (ub << 16) | (ug << 8) | ur) >>> 0; + }, + + /** + * Unpacks a Uint24 RGB into an array of floats of ranges of 0.0 and 1.0 + * + * @function Phaser.Renderer.WebGL.Utils.getFloatsFromUintRGB + * @since 3.0.0 + * + * @param {number} rgb - RGB packed as a Uint24 + * + * @return {array} Array of floats representing each component as a float + */ + getFloatsFromUintRGB: function (rgb) { - return Math.sin(v * Math.PI / 2); - } -}; + var ur = ((rgb >> 16) | 0) & 0xff; + var ug = ((rgb >> 8) | 0) & 0xff; + var ub = (rgb | 0) & 0xff; -module.exports = Out; + return [ ur / 255, ug / 255, ub / 255 ]; + }, + /** + * Check to see how many texture units the GPU supports in a fragment shader + * and if the value specific in the game config is allowed. + * + * This value is hard-clamped to 16 for performance reasons on Android devices. + * + * @function Phaser.Renderer.WebGL.Utils.checkShaderMax + * @since 3.50.0 + * + * @param {WebGLRenderingContext} gl - The WebGLContext used to create the shaders. + * @param {number} maxTextures - The Game Config maxTextures value. + * + * @return {number} The number of texture units that is supported by this browser and GPU. + */ + checkShaderMax: function (gl, maxTextures) + { + // Note: This is the maximum number of TIUs that a _fragment_ shader supports + // https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_Unit -/***/ }), -/* 794 */ -/***/ (function(module, exports) { + // Hard-clamp this to 16 to avoid run-away texture counts such as on Android + var gpuMax = Math.min(16, gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!maxTextures || maxTextures === -1) + { + return gpuMax; + } + else + { + return Math.min(gpuMax, maxTextures); + } + }, -/** - * Sinusoidal ease-in/out. - * - * @function Phaser.Math.Easing.Sine.InOut - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * - * @return {number} The tweened value. - */ -var InOut = function (v) -{ - if (v === 0) - { - return 0; - } - else if (v === 1) - { - return 1; - } - else + /** + * Checks the given Fragment Shader Source for `%count%` and `%forloop%` declarations and + * replaces those with GLSL code for setting `texture = texture2D(uMainSampler[i], outTexCoord)`. + * + * @function Phaser.Renderer.WebGL.Utils.parseFragmentShaderMaxTextures + * @since 3.50.0 + * + * @param {string} fragmentShaderSource - The Fragment Shader source code to operate on. + * @param {number} maxTextures - The number of maxTextures value. + * + * @return {string} The modified Fragment Shader source. + */ + parseFragmentShaderMaxTextures: function (fragmentShaderSource, maxTextures) { - return 0.5 * (1 - Math.cos(Math.PI * v)); - } -}; + if (!fragmentShaderSource) + { + return ''; + } -module.exports = InOut; + var src = ''; + for (var i = 0; i < maxTextures; i++) + { + if (i > 0) + { + src += '\n\telse '; + } -/***/ }), -/* 795 */ -/***/ (function(module, exports) { + if (i < maxTextures - 1) + { + src += 'if (outTexId < ' + i + '.5)'; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + src += '\n\t{'; + src += '\n\t\ttexture = texture2D(uMainSampler[' + i + '], outTexCoord);'; + src += '\n\t}'; + } -/** - * Stepped easing. - * - * @function Phaser.Math.Easing.Stepped - * @since 3.0.0 - * - * @param {number} v - The value to be tweened. - * @param {number} [steps=1] - The number of steps in the ease. - * - * @return {number} The tweened value. - */ -var Stepped = function (v, steps) -{ - if (steps === undefined) { steps = 1; } + fragmentShaderSource = fragmentShaderSource.replace(/%count%/gi, maxTextures.toString()); - if (v <= 0) - { - return 0; - } - else if (v >= 1) - { - return 1; - } - else + return fragmentShaderSource.replace(/%forloop%/gi, src); + }, + + /** + * Takes the Glow FX Shader source and parses out the __SIZE__ and __DIST__ + * consts with the configuration values. + * + * @function Phaser.Renderer.WebGL.Utils.setGlowQuality + * @since 3.60.0 + * + * @param {string} shader - The Fragment Shader source code to operate on. + * @param {Phaser.Game} game - The Phaser Game instance. + * @param {number} [quality] - The quality of the glow (defaults to 0.1) + * @param {number} [distance] - The distance of the glow (defaults to 10) + * + * @return {string} The modified Fragment Shader source. + */ + setGlowQuality: function (shader, game, quality, distance) { - return (((steps * v) | 0) + 1) * (1 / steps); + if (quality === undefined) + { + quality = game.config.glowFXQuality; + } + + if (distance === undefined) + { + distance = game.config.glowFXDistance; + } + + shader = shader.replace(/__SIZE__/gi, (1 / quality / distance).toFixed(7)); + shader = shader.replace(/__DIST__/gi, distance.toFixed(0) + '.0'); + + return shader; } -}; -module.exports = Stepped; +}; /***/ }), -/* 796 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 44775: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var Events = __webpack_require__(37); -var Vector2 = __webpack_require__(3); +var Class = __webpack_require__(56694); +var DeepCopy = __webpack_require__(28699); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(18970); +var GetFastValue = __webpack_require__(72632); +var Matrix4 = __webpack_require__(16650); +var RendererEvents = __webpack_require__(81044); +var RenderTarget = __webpack_require__(37410); +var Utils = __webpack_require__(75512); +var WebGLShader = __webpack_require__(71305); /** * @classdesc - * A Camera Shake effect. + * The `WebGLPipeline` is a base class used by all of the core Phaser pipelines. * - * This effect will shake the camera viewport by a random amount, bounded by the specified intensity, each frame. + * It describes the way elements will be rendered in WebGL. Internally, it handles + * compiling the shaders, creating vertex buffers, assigning primitive topology and + * binding vertex attributes, all based on the given configuration data. * - * Only the camera viewport is moved. None of the objects it is displaying are impacted, i.e. their positions do - * not change. + * The pipeline is configured by passing in a `WebGLPipelineConfig` object. Please + * see the documentation for this type to fully understand the configuration options + * available to you. * - * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, - * which is invoked each frame for the duration of the effect if required. + * Usually, you would not extend from this class directly, but would instead extend + * from one of the core pipelines, such as the Multi Pipeline. * - * @class Shake - * @memberof Phaser.Cameras.Scene2D.Effects + * The pipeline flow per render-step is as follows: + * + * 1) onPreRender - called once at the start of the render step + * 2) onRender - call for each Scene Camera that needs to render (so can be multiple times per render step) + * 3) Internal flow: + * 3a) bind (only called if a Game Object is using this pipeline and it's not currently active) + * 3b) onBind (called for every Game Object that uses this pipeline) + * 3c) flush (can be called by a Game Object, internal method or from outside by changing pipeline) + * 4) onPostRender - called once at the end of the render step + * + * @class WebGLPipeline + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Renderer.WebGL * @constructor - * @since 3.5.0 + * @since 3.0.0 * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration object for this WebGL Pipeline. */ -var Shake = new Class({ +var WebGLPipeline = new Class({ + + Extends: EventEmitter, initialize: - function Shake (camera) + function WebGLPipeline (config) { + EventEmitter.call(this); + + var game = config.game; + var renderer = game.renderer; + var gl = renderer.gl; + /** - * The Camera this effect belongs to. + * Name of the pipeline. Used for identification and setting from Game Objects. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#camera - * @type {Phaser.Cameras.Scene2D.Camera} - * @readonly - * @since 3.5.0 + * @name Phaser.Renderer.WebGL.WebGLPipeline#name + * @type {string} + * @since 3.0.0 */ - this.camera = camera; + this.name = GetFastValue(config, 'name', 'WebGLPipeline'); /** - * Is this effect actively running? + * The Phaser Game instance to which this pipeline is bound. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#isRunning - * @type {boolean} - * @readonly - * @default false - * @since 3.5.0 + * @name Phaser.Renderer.WebGL.WebGLPipeline#game + * @type {Phaser.Game} + * @since 3.0.0 */ - this.isRunning = false; + this.game = game; /** - * The duration of the effect, in milliseconds. + * The WebGL Renderer instance to which this pipeline is bound. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#duration - * @type {number} - * @readonly - * @default 0 - * @since 3.5.0 + * @name Phaser.Renderer.WebGL.WebGLPipeline#renderer + * @type {Phaser.Renderer.WebGL.WebGLRenderer} + * @since 3.0.0 */ - this.duration = 0; + this.renderer = renderer; /** - * The intensity of the effect. Use small float values. The default when the effect starts is 0.05. - * This is a Vector2 object, allowing you to control the shake intensity independently across x and y. - * You can modify this value while the effect is active to create more varied shake effects. + * A reference to the WebGL Pipeline Manager. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#intensity - * @type {Phaser.Math.Vector2} - * @since 3.5.0 + * This is initially undefined and only set when this pipeline is added + * to the manager. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#manager + * @type {?Phaser.Renderer.WebGL.PipelineManager} + * @since 3.50.0 */ - this.intensity = new Vector2(); + this.manager; /** - * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. + * The WebGL context this WebGL Pipeline uses. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#progress - * @type {number} - * @since 3.5.0 + * @name Phaser.Renderer.WebGL.WebGLPipeline#gl + * @type {WebGLRenderingContext} + * @since 3.0.0 */ - this.progress = 0; + this.gl = gl; /** - * Effect elapsed timer. + * The canvas which this WebGL Pipeline renders to. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#_elapsed + * @name Phaser.Renderer.WebGL.WebGLPipeline#view + * @type {HTMLCanvasElement} + * @since 3.0.0 + */ + this.view = game.canvas; + + /** + * Width of the current viewport. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#width * @type {number} - * @private - * @since 3.5.0 + * @since 3.0.0 */ - this._elapsed = 0; + this.width = 0; /** - * How much to offset the camera by horizontally. + * Height of the current viewport. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#_offsetX + * @name Phaser.Renderer.WebGL.WebGLPipeline#height * @type {number} - * @private - * @default 0 * @since 3.0.0 */ - this._offsetX = 0; + this.height = 0; /** - * How much to offset the camera by vertically. + * The current number of vertices that have been added to the pipeline batch. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#_offsetY + * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexCount * @type {number} - * @private * @default 0 * @since 3.0.0 */ - this._offsetY = 0; + this.vertexCount = 0; /** - * This callback is invoked every frame for the duration of the effect. + * The total number of vertices that this pipeline batch can hold before it will flush. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#_onUpdate - * @type {?Phaser.Types.Cameras.Scene2D.CameraShakeCallback} - * @private - * @default null - * @since 3.5.0 + * This defaults to `renderer batchSize * 6`, where `batchSize` is defined in the Renderer Game Config. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexCapacity + * @type {number} + * @since 3.0.0 */ - this._onUpdate; + this.vertexCapacity = 0; /** - * On Complete callback scope. + * Raw byte buffer of vertices. * - * @name Phaser.Cameras.Scene2D.Effects.Shake#_onUpdateScope - * @type {any} - * @private - * @since 3.5.0 + * Either set via the config object `vertices` property, or generates a new Array Buffer of + * size `vertexCapacity * vertexSize`. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexData + * @type {ArrayBuffer} + * @readonly + * @since 3.0.0 */ - this._onUpdateScope; - }, - - /** - * Shakes the Camera by the given intensity over the duration specified. - * - * @method Phaser.Cameras.Scene2D.Effects.Shake#start - * @fires Phaser.Cameras.Scene2D.Events#SHAKE_START - * @fires Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE - * @since 3.5.0 - * - * @param {number} [duration=100] - The duration of the effect in milliseconds. - * @param {(number|Phaser.Math.Vector2)} [intensity=0.05] - The intensity of the shake. - * @param {boolean} [force=false] - Force the shake effect to start immediately, even if already running. - * @param {Phaser.Types.Cameras.Scene2D.CameraShakeCallback} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. - * - * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. - */ - start: function (duration, intensity, force, callback, context) - { - if (duration === undefined) { duration = 100; } - if (intensity === undefined) { intensity = 0.05; } - if (force === undefined) { force = false; } - if (callback === undefined) { callback = null; } - if (context === undefined) { context = this.camera.scene; } - - if (!force && this.isRunning) - { - return this.camera; - } - - this.isRunning = true; - this.duration = duration; - this.progress = 0; - - if (typeof intensity === 'number') - { - this.intensity.set(intensity); - } - else - { - this.intensity.set(intensity.x, intensity.y); - } - - this._elapsed = 0; - this._offsetX = 0; - this._offsetY = 0; - - this._onUpdate = callback; - this._onUpdateScope = context; - - this.camera.emit(Events.SHAKE_START, this.camera, this, duration, intensity); - - return this.camera; - }, - - /** - * The pre-render step for this effect. Called automatically by the Camera. - * - * @method Phaser.Cameras.Scene2D.Effects.Shake#preRender - * @since 3.5.0 - */ - preRender: function () - { - if (this.isRunning) - { - this.camera.matrix.translate(this._offsetX, this._offsetY); - } - }, - - /** - * The main update loop for this effect. Called automatically by the Camera. - * - * @method Phaser.Cameras.Scene2D.Effects.Shake#update - * @since 3.5.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.isRunning) - { - return; - } - - this._elapsed += delta; - - this.progress = Clamp(this._elapsed / this.duration, 0, 1); - - if (this._onUpdate) - { - this._onUpdate.call(this._onUpdateScope, this.camera, this.progress); - } - - if (this._elapsed < this.duration) - { - var intensity = this.intensity; - var width = this.camera.width; - var height = this.camera.height; - var zoom = this.camera.zoom; - - this._offsetX = (Math.random() * intensity.x * width * 2 - intensity.x * width) * zoom; - this._offsetY = (Math.random() * intensity.y * height * 2 - intensity.y * height) * zoom; - - if (this.camera.roundPixels) - { - this._offsetX = Math.round(this._offsetX); - this._offsetY = Math.round(this._offsetY); - } - } - else - { - this.effectComplete(); - } - }, - - /** - * Called internally when the effect completes. - * - * @method Phaser.Cameras.Scene2D.Effects.Shake#effectComplete - * @fires Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE - * @since 3.5.0 - */ - effectComplete: function () - { - this._offsetX = 0; - this._offsetY = 0; - - this._onUpdate = null; - this._onUpdateScope = null; - - this.isRunning = false; - - this.camera.emit(Events.SHAKE_COMPLETE, this.camera, this); - }, - - /** - * Resets this camera effect. - * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. - * - * @method Phaser.Cameras.Scene2D.Effects.Shake#reset - * @since 3.5.0 - */ - reset: function () - { - this.isRunning = false; - - this._offsetX = 0; - this._offsetY = 0; - - this._onUpdate = null; - this._onUpdateScope = null; - }, - - /** - * Destroys this effect, releasing it from the Camera. - * - * @method Phaser.Cameras.Scene2D.Effects.Shake#destroy - * @since 3.5.0 - */ - destroy: function () - { - this.reset(); - - this.camera = null; - this.intensity = null; - } + this.vertexData; -}); + /** + * The WebGLBuffer that holds the vertex data. + * + * Created from the `vertexData` ArrayBuffer. If `vertices` are set in the config, a `STATIC_DRAW` buffer + * is created. If not, a `DYNAMIC_DRAW` buffer is created. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexBuffer + * @type {WebGLBuffer} + * @readonly + * @since 3.0.0 + */ + this.vertexBuffer; -module.exports = Shake; + /** + * The currently active WebGLBuffer. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#activeBuffer + * @type {WebGLBuffer} + * @since 3.60.0 + */ + this.activeBuffer; + /** + * The primitive topology which the pipeline will use to submit draw calls. + * + * Defaults to GL_TRIANGLES if not otherwise set in the config. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#topology + * @type {GLenum} + * @since 3.0.0 + */ + this.topology = GetFastValue(config, 'topology', gl.TRIANGLES); -/***/ }), -/* 797 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Uint8 view to the `vertexData` ArrayBuffer. Used for uploading vertex buffer resources to the GPU. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#bytes + * @type {Uint8Array} + * @since 3.0.0 + */ + this.bytes; -/** - * @author Jason Nicholls - * @copyright 2018 Photon Storm Ltd. - * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} - */ + /** + * Float32 view of the array buffer containing the pipeline's vertices. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexViewF32 + * @type {Float32Array} + * @since 3.0.0 + */ + this.vertexViewF32; -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var Events = __webpack_require__(37); -var EaseMap = __webpack_require__(134); + /** + * Uint32 view of the array buffer containing the pipeline's vertices. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexViewU32 + * @type {Uint32Array} + * @since 3.0.0 + */ + this.vertexViewU32; -/** - * @classdesc - * A Camera Rotate effect. - * - * This effect will rotate the Camera so that the its viewport finishes at the given angle in radians, - * over the duration and with the ease specified. - * - * Camera rotation always takes place based on the Camera viewport. By default, rotation happens - * in the center of the viewport. You can adjust this with the `originX` and `originY` properties. - * - * Rotation influences the rendering of _all_ Game Objects visible by this Camera. However, it does not - * rotate the Camera viewport itself, which always remains an axis-aligned rectangle. - * - * Only the camera is rotates. None of the objects it is displaying are impacted, i.e. their positions do - * not change. - * - * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, - * which is invoked each frame for the duration of the effect if required. - * - * @class RotateTo - * @memberof Phaser.Cameras.Scene2D.Effects - * @constructor - * @since 3.23.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. - */ -var RotateTo = new Class({ + /** + * Indicates if the current pipeline is active, or not. + * + * Toggle this property to enable or disable a pipeline from rendering anything. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#active + * @type {boolean} + * @since 3.10.0 + */ + this.active = true; - initialize: + /** + * Some pipelines require the forced use of texture zero (like the light pipeline). + * + * This property should be set when that is the case. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#forceZero + * @type {boolean} + * @since 3.50.0 + */ + this.forceZero = GetFastValue(config, 'forceZero', false); - function RotateTo (camera) - { /** - * The Camera this effect belongs to. + * Indicates if this pipeline has booted or not. * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#camera - * @type {Phaser.Cameras.Scene2D.Camera} + * A pipeline boots only when the Game instance itself, and all associated systems, is + * fully ready. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#hasBooted + * @type {boolean} * @readonly - * @since 3.23.0 + * @since 3.50.0 */ - this.camera = camera; + this.hasBooted = false; /** - * Is this effect actively running? + * Indicates if this is a Post FX Pipeline, or not. * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#isRunning + * @name Phaser.Renderer.WebGL.WebGLPipeline#isPostFX * @type {boolean} * @readonly - * @default false - * @since 3.23.0 + * @since 3.50.0 */ - this.isRunning = false; + this.isPostFX = false; /** - * The duration of the effect, in milliseconds. + * Indicates if this is a Pre FX Pipeline, or not. * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#duration - * @type {number} + * @name Phaser.Renderer.WebGL.WebGLPipeline#isPreFX + * @type {boolean} * @readonly - * @default 0 - * @since 3.23.0 + * @since 3.60.0 */ - this.duration = 0; + this.isPreFX = false; /** - * The starting angle to rotate the camera from. - * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#source - * @type {number} - * @since 3.23.0 + * An array of RenderTarget instances that belong to this pipeline. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#renderTargets + * @type {Phaser.Renderer.WebGL.RenderTarget[]} + * @since 3.50.0 */ - this.source = 0; + this.renderTargets = []; /** - * The constantly updated value based on the force. - * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#current - * @type {number} - * @since 3.23.0 + * A reference to the currently bound Render Target instance from the `WebGLPipeline.renderTargets` array. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#currentRenderTarget + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.50.0 */ - this.current = 0; + this.currentRenderTarget; /** - * The destination angle in radians to rotate the camera to. - * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#destination - * @type {number} - * @since 3.23.0 + * An array of all the WebGLShader instances that belong to this pipeline. + * + * Shaders manage their own attributes and uniforms, but share the same vertex data buffer, + * which belongs to this pipeline. + * + * Shaders are set in a call to the `setShadersFromConfig` method, which happens automatically, + * but can also be called at any point in your game. See the method documentation for details. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#shaders + * @type {Phaser.Renderer.WebGL.WebGLShader[]} + * @since 3.50.0 */ - this.destination = 0; + this.shaders = []; /** - * The ease function to use during the Rotate. - * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#ease - * @type {function} - * @since 3.23.0 + * A reference to the currently bound WebGLShader instance from the `WebGLPipeline.shaders` array. + * + * For lots of pipelines, this is the only shader, so it is a quick way to reference it without + * an array look-up. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#currentShader + * @type {Phaser.Renderer.WebGL.WebGLShader} + * @since 3.50.0 */ - this.ease; + this.currentShader; /** - * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. + * The Projection matrix, used by shaders as 'uProjectionMatrix' uniform. * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#progress + * @name Phaser.Renderer.WebGL.WebGLPipeline#projectionMatrix + * @type {Phaser.Math.Matrix4} + * @since 3.50.0 + */ + this.projectionMatrix; + + /** + * The cached width of the Projection matrix. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#projectionWidth * @type {number} - * @since 3.23.0 + * @since 3.50.0 */ - this.progress = 0; + this.projectionWidth = 0; /** - * Effect elapsed timer. + * The cached height of the Projection matrix. * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#_elapsed + * @name Phaser.Renderer.WebGL.WebGLPipeline#projectionHeight * @type {number} - * @private - * @since 3.23.0 + * @since 3.50.0 */ - this._elapsed = 0; + this.projectionHeight = 0; /** - * @callback CameraRotateCallback + * The configuration object that was used to create this pipeline. * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera on which the effect is running. - * @param {number} progress - The progress of the effect. A value between 0 and 1. - * @param {number} angle - The Camera's new angle in radians. + * Treat this object as 'read only', because changing it post-creation will not + * impact this pipeline in any way. However, it is used internally for cloning + * and post-boot set-up. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#config + * @type {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} + * @since 3.50.0 */ + this.config = config; /** - * This callback is invoked every frame for the duration of the effect. + * Has the GL Context been reset to the Phaser defaults since the last time + * this pipeline was bound? This is set automatically when the Pipeline Manager + * resets itself, usually after handing off to a 3rd party renderer like Spine. * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#_onUpdate - * @type {?CameraRotateCallback} - * @private - * @default null - * @since 3.23.0 + * You should treat this property as read-only. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#glReset + * @type {boolean} + * @since 3.53.0 */ - this._onUpdate; + this.glReset = false; /** - * On Complete callback scope. + * The temporary Pipeline batch. This array contains the batch entries for + * the current frame, which is a package of textures and vertex offsets used + * for drawing. This package is built dynamically as the frame is built + * and cleared during the flush method. * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#_onUpdateScope - * @type {any} - * @private - * @since 3.23.0 + * Treat this array and all of its contents as read-only. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#batch + * @type {Phaser.Types.Renderer.WebGL.WebGLPipelineBatchEntry[]} + * @since 3.60.0 */ - this._onUpdateScope; + this.batch = []; /** - * The direction of the rotation. - * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#clockwise - * @type {boolean} - * @since 3.23.0 + * The most recently created Pipeline batch entry. + * + * Reset to null as part of the flush method. + * + * Treat this value as read-only. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#currentBatch + * @type {?Phaser.Types.Renderer.WebGL.WebGLPipelineBatchEntry} + * @since 3.60.0 */ - this.clockwise = true; + this.currentBatch = null; /** - * The shortest direction to the target rotation. - * - * @name Phaser.Cameras.Scene2D.Effects.RotateTo#shortestPath - * @type {boolean} - * @since 3.23.0 + * The most recently bound WebGLTexture, used as part of the batch process. + * + * Reset to null as part of the flush method. + * + * Treat this value as read-only. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#currentTexture + * @type {?WebGLTexture} + * @since 3.60.0 */ - this.shortestPath = false; + this.currentTexture = null; + + /** + * Holds the most recently assigned texture unit. + * + * Treat this value as read-only. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#currentUnit + * @type {number} + * @since 3.50.0 + */ + this.currentUnit = 0; + + /** + * The currently active WebGLTextures, used as part of the batch process. + * + * Reset to empty as part of the bind method. + * + * Treat this array as read-only. + * + * @name Phaser.Renderer.WebGL.WebGLPipeline#activeTextures + * @type {WebGLTexture[]} + * @since 3.60.0 + */ + this.activeTextures = []; }, /** - * This effect will scroll the Camera so that the center of its viewport finishes at the given angle, - * over the duration and with the ease specified. - * - * @method Phaser.Cameras.Scene2D.Effects.RotateTo#start - * @fires Phaser.Cameras.Scene2D.Events#ROTATE_START - * @fires Phaser.Cameras.Scene2D.Events#ROTATE_COMPLETE - * @since 3.23.0 + * Called when the Game has fully booted and the Renderer has finished setting up. * - * @param {number} radians - The destination angle in radians to rotate the Camera viewport to. If the angle is positive then the rotation is clockwise else anticlockwise - * @param {boolean} [shortestPath=false] - If shortest path is set to true the camera will rotate in the quickest direction clockwise or anti-clockwise. - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {(string|function)} [ease='Linear'] - The ease to use for the Rotate. Can be any of the Phaser Easing constants or a custom function. - * @param {boolean} [force=false] - Force the rotation effect to start immediately, even if already running. - * @param {CameraRotateCallback} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, - * the current camera scroll x coordinate and the current camera scroll y coordinate. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * By this stage all Game level systems are now in place. You can perform any final tasks that the + * pipeline may need, that relies on game systems such as the Texture Manager being ready. * - * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. + * @method Phaser.Renderer.WebGL.WebGLPipeline#boot + * @fires Phaser.Renderer.WebGL.Pipelines.Events#BOOT + * @since 3.11.0 */ - start: function (radians, shortestPath, duration, ease, force, callback, context) + boot: function () { - if (duration === undefined) { duration = 1000; } - if (ease === undefined) { ease = EaseMap.Linear; } - if (force === undefined) { force = false; } - if (callback === undefined) { callback = null; } - if (context === undefined) { context = this.camera.scene; } - if (shortestPath === undefined) { shortestPath = false; } + var i; + var gl = this.gl; + var config = this.config; + var renderer = this.renderer; - this.shortestPath = shortestPath; + if (!this.isPostFX) + { + this.projectionMatrix = new Matrix4().identity(); + } - var tmpDestination = radians; + // Create the Render Targets - if (radians < 0) + var renderTargets = this.renderTargets; + + var targets = GetFastValue(config, 'renderTarget', false); + + // If boolean, set to number = 1 + if (typeof(targets) === 'boolean' && targets) { - tmpDestination = -1 * radians; - this.clockwise = false; + targets = 1; } - else + + var width = renderer.width; + var height = renderer.height; + + if (typeof(targets) === 'number') { - this.clockwise = true; + // Create this many default RTs + for (i = 0; i < targets; i++) + { + renderTargets.push(new RenderTarget(renderer, width, height, 1, 0, true)); + } } + else if (Array.isArray(targets)) + { + for (i = 0; i < targets.length; i++) + { + var scale = GetFastValue(targets[i], 'scale', 1); + var minFilter = GetFastValue(targets[i], 'minFilter', 0); + var autoClear = GetFastValue(targets[i], 'autoClear', 1); + var targetWidth = GetFastValue(targets[i], 'width', null); + var targetHeight = GetFastValue(targets[i], 'height', targetWidth); - var maxRad = (360 * Math.PI) / 180; + if (targetWidth) + { + renderTargets.push(new RenderTarget(renderer, targetWidth, targetHeight, 1, minFilter, autoClear)); + } + else + { + renderTargets.push(new RenderTarget(renderer, width, height, scale, minFilter, autoClear)); + } + } + } - tmpDestination = tmpDestination - (Math.floor(tmpDestination / maxRad) * maxRad); + if (renderTargets.length) + { + // Default to the first one in the array + this.currentRenderTarget = renderTargets[0]; + } - var cam = this.camera; + // Create the Shaders - if (!force && this.isRunning) + this.setShadersFromConfig(config); + + // Which shader has the largest vertex size? + var shaders = this.shaders; + var vertexSize = 0; + + for (i = 0; i < shaders.length; i++) { - return cam; + if (shaders[i].vertexSize > vertexSize) + { + vertexSize = shaders[i].vertexSize; + } } - this.isRunning = true; - this.duration = duration; - this.progress = 0; + var batchSize = GetFastValue(config, 'batchSize', renderer.config.batchSize); - // Starting from - this.source = cam.rotation; + // * 6 because there are 6 vertices in a quad and 'batchSize' represents the quantity of quads in the batch - // Destination - this.destination = tmpDestination; + this.vertexCapacity = batchSize * 6; - // Using this ease - if (typeof ease === 'string' && EaseMap.hasOwnProperty(ease)) + var data = new ArrayBuffer(this.vertexCapacity * vertexSize); + + this.vertexData = data; + this.bytes = new Uint8Array(data); + this.vertexViewF32 = new Float32Array(data); + this.vertexViewU32 = new Uint32Array(data); + + var configVerts = GetFastValue(config, 'vertices', null); + + if (configVerts) { - this.ease = EaseMap[ease]; + this.vertexViewF32.set(configVerts); + + this.vertexBuffer = renderer.createVertexBuffer(data, gl.STATIC_DRAW); } - else if (typeof ease === 'function') + else { - this.ease = ease; + this.vertexBuffer = renderer.createVertexBuffer(data.byteLength, gl.DYNAMIC_DRAW); } - this._elapsed = 0; - - this._onUpdate = callback; - this._onUpdateScope = context; + // Set-up shaders + this.setVertexBuffer(); - if (this.shortestPath) + for (i = shaders.length - 1; i >= 0; i--) { - // The shortest path is true so calculate the quickest direction - var cwDist = 0; - var acwDist = 0; + shaders[i].rebind(); + } - if (this.destination > this.source) - { - cwDist = Math.abs(this.destination - this.source); - } - else - { - cwDist = (Math.abs(this.destination + maxRad) - this.source); - } + this.hasBooted = true; - if (this.source > this.destination) - { - acwDist = Math.abs(this.source - this.destination); - } - else - { - acwDist = (Math.abs(this.source + maxRad) - this.destination); - } + renderer.on(RendererEvents.RESIZE, this.resize, this); + renderer.on(RendererEvents.PRE_RENDER, this.onPreRender, this); + renderer.on(RendererEvents.RENDER, this.onRender, this); + renderer.on(RendererEvents.POST_RENDER, this.onPostRender, this); - if (cwDist < acwDist) - { - this.clockwise = true; - } - else if (cwDist > acwDist) - { - this.clockwise = false; - } - } + this.emit(Events.BOOT, this); - this.camera.emit(Events.ROTATE_START, this.camera, this, duration, tmpDestination); + this.onBoot(); + }, - return cam; + /** + * This method is called once when this pipeline has finished being set-up + * at the end of the boot process. By the time this method is called, all + * of the shaders are ready and configured. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#onBoot + * @since 3.50.0 + */ + onBoot: function () + { }, /** - * The main update loop for this effect. Called automatically by the Camera. + * This method is called once when this pipeline has finished being set-up + * at the end of the boot process. By the time this method is called, all + * of the shaders are ready and configured. It's also called if the renderer + * changes size. * - * @method Phaser.Cameras.Scene2D.Effects.RotateTo#update - * @since 3.23.0 + * @method Phaser.Renderer.WebGL.WebGLPipeline#onResize + * @since 3.50.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. + * @param {number} width - The new width of this WebGL Pipeline. + * @param {number} height - The new height of this WebGL Pipeline. */ - update: function (time, delta) + onResize: function () { - if (!this.isRunning) - { - return; - } - - this._elapsed += delta; - - var progress = Clamp(this._elapsed / this.duration, 0, 1); - - this.progress = progress; - - var cam = this.camera; - - if (this._elapsed < this.duration) - { - var v = this.ease(progress); - - this.current = cam.rotation; - var distance = 0; - var maxRad = (360 * Math.PI) / 180; - var target = this.destination; - var current = this.current; + }, - if (this.clockwise === false) - { - target = this.current; - current = this.destination; - } + /** + * Sets the currently active shader within this pipeline. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#setShader + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.WebGLShader} shader - The shader to set as being current. + * @param {boolean} [setAttributes=false] - Should the vertex attribute pointers be set? + * @param {WebGLBuffer} [vertexBuffer] - The vertex buffer to be set before the shader is bound. Defaults to the one owned by this pipeline. + * + * @return {this} This WebGLPipeline instance. + */ + setShader: function (shader, setAttributes, vertexBuffer) + { + var renderer = this.renderer; - if (target >= current) - { - distance = Math.abs(target - current); - } - else - { - distance = (Math.abs(target + maxRad) - current); - } + if (shader !== this.currentShader || renderer.currentProgram !== this.currentShader.program) + { + this.flush(); - var r = 0; + var wasBound = this.setVertexBuffer(vertexBuffer); - if (this.clockwise) - { - r = (cam.rotation + (distance * v)); - } - else + if (wasBound && !setAttributes) { - r = (cam.rotation - (distance * v)); + setAttributes = true; } - cam.rotation = r; + shader.bind(setAttributes, false); - if (this._onUpdate) - { - this._onUpdate.call(this._onUpdateScope, cam, progress, r); - } + this.currentShader = shader; } - else - { - cam.rotation = this.destination; - if (this._onUpdate) - { - this._onUpdate.call(this._onUpdateScope, cam, progress, this.destination); - } - - this.effectComplete(); - } + return this; }, /** - * Called internally when the effect completes. + * Searches all shaders in this pipeline for one matching the given name, then returns it. * - * @method Phaser.Cameras.Scene2D.Effects.RotateTo#effectComplete - * @since 3.23.0 - */ - effectComplete: function () - { - this._onUpdate = null; - this._onUpdateScope = null; - - this.isRunning = false; - - this.camera.emit(Events.ROTATE_COMPLETE, this.camera, this); - }, - - /** - * Resets this camera effect. - * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. + * @method Phaser.Renderer.WebGL.WebGLPipeline#getShaderByName + * @since 3.50.0 * - * @method Phaser.Cameras.Scene2D.Effects.RotateTo#reset - * @since 3.23.0 + * @param {string} name - The index of the shader to set. + * + * @return {Phaser.Renderer.WebGL.WebGLShader} The WebGLShader instance, if found. */ - reset: function () + getShaderByName: function (name) { - this.isRunning = false; + var shaders = this.shaders; - this._onUpdate = null; - this._onUpdateScope = null; + for (var i = 0; i < shaders.length; i++) + { + if (shaders[i].name === name) + { + return shaders[i]; + } + } }, /** - * Destroys this effect, releasing it from the Camera. + * Destroys all shaders currently set in the `WebGLPipeline.shaders` array and then parses the given + * `config` object, extracting the shaders from it, creating `WebGLShader` instances and finally + * setting them into the `shaders` array of this pipeline. * - * @method Phaser.Cameras.Scene2D.Effects.RotateTo#destroy - * @since 3.23.0 + * This is a destructive process. Be very careful when you call it, should you need to. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#setShadersFromConfig + * @since 3.50.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration object for this WebGL Pipeline. + * + * @return {this} This WebGLPipeline instance. */ - destroy: function () + setShadersFromConfig: function (config) { - this.reset(); - - this.camera = null; - this.source = null; - this.destination = null; - } - -}); - -module.exports = RotateTo; - + var i; + var shaders = this.shaders; + var renderer = this.renderer; -/***/ }), -/* 798 */ -/***/ (function(module, exports, __webpack_require__) { + for (i = 0; i < shaders.length; i++) + { + shaders[i].destroy(); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var vName = 'vertShader'; + var fName = 'fragShader'; + var aName = 'attributes'; -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var EaseMap = __webpack_require__(134); -var Events = __webpack_require__(37); + var defaultVertShader = GetFastValue(config, vName, null); + var defaultFragShader = Utils.parseFragmentShaderMaxTextures(GetFastValue(config, fName, null), renderer.maxTextures); + var defaultAttribs = GetFastValue(config, aName, null); -/** - * @classdesc - * A Camera Zoom effect. - * - * This effect will zoom the Camera to the given scale, over the duration and with the ease specified. - * - * The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback, - * which is invoked each frame for the duration of the effect if required. - * - * @class Zoom - * @memberof Phaser.Cameras.Scene2D.Effects - * @constructor - * @since 3.11.0 - * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon. - */ -var Zoom = new Class({ + var configShaders = GetFastValue(config, 'shaders', []); - initialize: + var len = configShaders.length; - function Zoom (camera) - { - /** - * The Camera this effect belongs to. - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#camera - * @type {Phaser.Cameras.Scene2D.Camera} - * @readonly - * @since 3.11.0 - */ - this.camera = camera; + if (len === 0) + { + if (defaultVertShader && defaultFragShader) + { + this.shaders = [ new WebGLShader(this, 'default', defaultVertShader, defaultFragShader, DeepCopy(defaultAttribs)) ]; + } + } + else + { + var newShaders = []; - /** - * Is this effect actively running? - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#isRunning - * @type {boolean} - * @readonly - * @default false - * @since 3.11.0 - */ - this.isRunning = false; + for (i = 0; i < len; i++) + { + var shaderEntry = configShaders[i]; - /** - * The duration of the effect, in milliseconds. - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#duration - * @type {number} - * @readonly - * @default 0 - * @since 3.11.0 - */ - this.duration = 0; + var name; + var vertShader; + var fragShader; + var attributes; - /** - * The starting zoom value; - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#source - * @type {number} - * @since 3.11.0 - */ - this.source = 1; + if (typeof shaderEntry === 'string') + { + name = 'default'; + vertShader = defaultVertShader; + fragShader = Utils.parseFragmentShaderMaxTextures(shaderEntry, renderer.maxTextures); + attributes = defaultAttribs; + } + else + { + name = GetFastValue(shaderEntry, 'name', 'default'); + vertShader = GetFastValue(shaderEntry, vName, defaultVertShader); + fragShader = Utils.parseFragmentShaderMaxTextures(GetFastValue(shaderEntry, fName, defaultFragShader), renderer.maxTextures); + attributes = GetFastValue(shaderEntry, aName, defaultAttribs); + } - /** - * The destination zoom value. - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#destination - * @type {number} - * @since 3.11.0 - */ - this.destination = 1; + if (name === 'default') + { + var lines = fragShader.split('\n'); + var test = lines[0].trim(); - /** - * The ease function to use during the zoom. - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#ease - * @type {function} - * @since 3.11.0 - */ - this.ease; + if (test.indexOf('#define SHADER_NAME') > -1) + { + name = test.substring(20); + } + } - /** - * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#progress - * @type {number} - * @since 3.11.0 - */ - this.progress = 0; + if (vertShader && fragShader) + { + newShaders.push(new WebGLShader(this, name, vertShader, fragShader, DeepCopy(attributes))); + } + } - /** - * Effect elapsed timer. - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#_elapsed - * @type {number} - * @private - * @since 3.11.0 - */ - this._elapsed = 0; + this.shaders = newShaders; + } - /** - * This callback is invoked every frame for the duration of the effect. - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#_onUpdate - * @type {?Phaser.Types.Cameras.Scene2D.CameraZoomCallback} - * @private - * @default null - * @since 3.11.0 - */ - this._onUpdate; + if (this.shaders.length === 0) + { + console.warn('Pipeline: ' + this.name + ' - Invalid shader config'); + } + else + { + this.currentShader = this.shaders[0]; + } - /** - * On Complete callback scope. - * - * @name Phaser.Cameras.Scene2D.Effects.Zoom#_onUpdateScope - * @type {any} - * @private - * @since 3.11.0 - */ - this._onUpdateScope; + return this; }, /** - * This effect will zoom the Camera to the given scale, over the duration and with the ease specified. + * Creates a new WebGL Pipeline Batch Entry, sets the texture unit as zero + * and pushes the entry into the batch. * - * @method Phaser.Cameras.Scene2D.Effects.Zoom#start - * @fires Phaser.Cameras.Scene2D.Events#ZOOM_START - * @fires Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE - * @since 3.11.0 + * @method Phaser.Renderer.WebGL.WebGLPipeline#createBatch + * @since 3.60.0 * - * @param {number} zoom - The target Camera zoom value. - * @param {number} [duration=1000] - The duration of the effect in milliseconds. - * @param {(string|function)} [ease='Linear'] - The ease to use for the Zoom. Can be any of the Phaser Easing constants or a custom function. - * @param {boolean} [force=false] - Force the zoom effect to start immediately, even if already running. - * @param {Phaser.Types.Cameras.Scene2D.CameraZoomCallback} [callback] - This callback will be invoked every frame for the duration of the effect. - * It is sent three arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is, - * and the current camera zoom value. - * @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs. + * @param {WebGLTexture} texture - The WebGLTexture assigned to this batch entry. * - * @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started. + * @return {number} The texture unit that was bound. */ - start: function (zoom, duration, ease, force, callback, context) + createBatch: function (texture) { - if (duration === undefined) { duration = 1000; } - if (ease === undefined) { ease = EaseMap.Linear; } - if (force === undefined) { force = false; } - if (callback === undefined) { callback = null; } - if (context === undefined) { context = this.camera.scene; } - - var cam = this.camera; + this.currentBatch = { + start: this.vertexCount, + count: 0, + texture: [ texture ], + unit: 0, + maxUnit: 0 + }; - if (!force && this.isRunning) - { - return cam; - } + this.currentUnit = 0; + this.currentTexture = texture; - this.isRunning = true; - this.duration = duration; - this.progress = 0; + this.batch.push(this.currentBatch); - // Starting from - this.source = cam.zoom; + return 0; + }, - // Zooming to - this.destination = zoom; + /** + * Adds the given texture to the current WebGL Pipeline Batch Entry and + * increases the batch entry unit and maxUnit values by 1. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#addTextureToBatch + * @since 3.60.0 + * + * @param {WebGLTexture} texture - The WebGLTexture assigned to this batch entry. + */ + addTextureToBatch: function (texture) + { + var batch = this.currentBatch; - // Using this ease - if (typeof ease === 'string' && EaseMap.hasOwnProperty(ease)) - { - this.ease = EaseMap[ease]; - } - else if (typeof ease === 'function') + if (batch) { - this.ease = ease; + batch.texture.push(texture); + batch.unit++; + batch.maxUnit++; } - - this._elapsed = 0; - - this._onUpdate = callback; - this._onUpdateScope = context; - - this.camera.emit(Events.ZOOM_START, this.camera, this, duration, zoom); - - return cam; }, /** - * The main update loop for this effect. Called automatically by the Camera. + * Takes the given WebGLTexture and determines what to do with it. * - * @method Phaser.Cameras.Scene2D.Effects.Zoom#update - * @since 3.11.0 + * If there is no current batch (i.e. after a flush) it will create a new + * batch from it. * - * @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. + * If the texture is already bound, it will return the current texture unit. + * + * If the texture already exists in the current batch, the unit gets reset + * to match it. + * + * If the texture cannot be found in the current batch, and it supports + * multiple textures, it's added into the batch and the unit indexes are + * advanced. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#pushBatch + * @since 3.60.0 + * + * @param {WebGLTexture} texture - The WebGLTexture assigned to this batch entry. + * + * @return {number} The texture unit that was bound. */ - update: function (time, delta) + pushBatch: function (texture) { - if (!this.isRunning) + // No current batch? Create one and return + if (!this.currentBatch || (this.forceZero && texture !== this.currentTexture)) { - return; + return this.createBatch(texture); } - this._elapsed += delta; - - this.progress = Clamp(this._elapsed / this.duration, 0, 1); - - if (this._elapsed < this.duration) + // Otherwise, check if the texture is in the current batch + if (texture === this.currentTexture) { - this.camera.zoom = this.source + ((this.destination - this.source) * this.ease(this.progress)); - - if (this._onUpdate) - { - this._onUpdate.call(this._onUpdateScope, this.camera, this.progress, this.camera.zoom); - } + return this.currentUnit; } else { - this.camera.zoom = this.destination; + var current = this.currentBatch; - if (this._onUpdate) + var idx = current.texture.indexOf(texture); + + if (idx === -1) { - this._onUpdate.call(this._onUpdateScope, this.camera, this.progress, this.destination); + // This is a brand new texture, not in the current batch + + // Have we exceed our limit? + if (current.texture.length === this.renderer.maxTextures) + { + return this.createBatch(texture); + } + else + { + // We're good, push it in + current.unit++; + current.maxUnit++; + current.texture.push(texture); + + this.currentUnit = current.unit; + this.currentTexture = texture; + + return current.unit; + } } + else + { + this.currentUnit = idx; + this.currentTexture = texture; - this.effectComplete(); + return idx; + } } }, /** - * Called internally when the effect completes. + * Custom pipelines can use this method in order to perform any required pre-batch tasks + * for the given Game Object. It must return the texture unit the Game Object was assigned. * - * @method Phaser.Cameras.Scene2D.Effects.Zoom#effectComplete - * @fires Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE - * @since 3.11.0 + * @method Phaser.Renderer.WebGL.WebGLPipeline#setGameObject + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object being rendered or added to the batch. + * @param {Phaser.Textures.Frame} [frame] - Optional frame to use. Can override that of the Game Object. + * + * @return {number} The texture unit the Game Object has been assigned. */ - effectComplete: function () + setGameObject: function (gameObject, frame) { - this._onUpdate = null; - this._onUpdateScope = null; - - this.isRunning = false; + if (frame === undefined) { frame = gameObject.frame; } - this.camera.emit(Events.ZOOM_COMPLETE, this.camera, this); + return this.pushBatch(frame.source.glTexture); }, /** - * Resets this camera effect. - * If it was previously running, it stops instantly without calling its onComplete callback or emitting an event. + * Check if the current batch of vertices is full. * - * @method Phaser.Cameras.Scene2D.Effects.Zoom#reset - * @since 3.11.0 + * You can optionally provide an `amount` parameter. If given, it will check if the batch + * needs to flush _if_ the `amount` is added to it. This allows you to test if you should + * flush before populating the batch. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#shouldFlush + * @since 3.0.0 + * + * @param {number} [amount=0] - Will the batch need to flush if this many vertices are added to it? + * + * @return {boolean} `true` if the current batch should be flushed, otherwise `false`. */ - reset: function () + shouldFlush: function (amount) { - this.isRunning = false; + if (amount === undefined) { amount = 0; } - this._onUpdate = null; - this._onUpdateScope = null; + return (this.vertexCount + amount > this.vertexCapacity); }, /** - * Destroys this effect, releasing it from the Camera. + * Returns the number of vertices that can be added to the current batch before + * it will trigger a flush to happen. * - * @method Phaser.Cameras.Scene2D.Effects.Zoom#destroy - * @since 3.11.0 + * @method Phaser.Renderer.WebGL.WebGLPipeline#vertexAvailable + * @since 3.60.0 + * + * @return {number} The number of vertices that can still be added to the current batch before it will flush. */ - destroy: function () + vertexAvailable: function () { - this.reset(); - - this.camera = null; - } + return this.vertexCapacity - this.vertexCount; + }, -}); + /** + * Resizes the properties used to describe the viewport. + * + * This method is called automatically by the renderer during its resize handler. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#resize + * @fires Phaser.Renderer.WebGL.Pipelines.Events#RESIZE + * @since 3.0.0 + * + * @param {number} width - The new width of this WebGL Pipeline. + * @param {number} height - The new height of this WebGL Pipeline. + * + * @return {this} This WebGLPipeline instance. + */ + resize: function (width, height) + { + if (width !== this.width || height !== this.height) + { + this.flush(); + } -module.exports = Zoom; + this.width = width; + this.height = height; + var targets = this.renderTargets; -/***/ }), -/* 799 */ -/***/ (function(module, exports, __webpack_require__) { + for (var i = 0; i < targets.length; i++) + { + targets[i].resize(width, height); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.setProjectionMatrix(width, height); -var Camera = __webpack_require__(326); -var Class = __webpack_require__(0); -var GetFastValue = __webpack_require__(2); -var PluginCache = __webpack_require__(24); -var RectangleContains = __webpack_require__(57); -var ScaleEvents = __webpack_require__(104); -var SceneEvents = __webpack_require__(20); + this.emit(Events.RESIZE, width, height, this); -/** - * @classdesc - * The Camera Manager is a plugin that belongs to a Scene and is responsible for managing all of the Scene Cameras. - * - * By default you can access the Camera Manager from within a Scene using `this.cameras`, although this can be changed - * in your game config. - * - * Create new Cameras using the `add` method. Or extend the Camera class with your own addition code and then add - * the new Camera in using the `addExisting` method. - * - * Cameras provide a view into your game world, and can be positioned, rotated, zoomed and scrolled accordingly. - * - * A Camera consists of two elements: The viewport and the scroll values. - * - * The viewport is the physical position and size of the Camera within your game. Cameras, by default, are - * created the same size as your game, but their position and size can be set to anything. This means if you - * wanted to create a camera that was 320x200 in size, positioned in the bottom-right corner of your game, - * you'd adjust the viewport to do that (using methods like `setViewport` and `setSize`). - * - * If you wish to change where the Camera is looking in your game, then you scroll it. You can do this - * via the properties `scrollX` and `scrollY` or the method `setScroll`. Scrolling has no impact on the - * viewport, and changing the viewport has no impact on the scrolling. - * - * By default a Camera will render all Game Objects it can see. You can change this using the `ignore` method, - * allowing you to filter Game Objects out on a per-Camera basis. The Camera Manager can manage up to 31 unique - * 'Game Object ignore capable' Cameras. Any Cameras beyond 31 that you create will all be given a Camera ID of - * zero, meaning that they cannot be used for Game Object exclusion. This means if you need your Camera to ignore - * Game Objects, make sure it's one of the first 31 created. - * - * A Camera also has built-in special effects including Fade, Flash, Camera Shake, Pan and Zoom. - * - * @class CameraManager - * @memberof Phaser.Cameras.Scene2D - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene that owns the Camera Manager plugin. - */ -var CameraManager = new Class({ + this.onResize(width, height); - initialize: + return this; + }, - function CameraManager (scene) + /** + * Adjusts this pipelines ortho Projection Matrix to use the given dimensions + * and resets the `uProjectionMatrix` uniform on all bound shaders. + * + * This method is called automatically by the renderer during its resize handler. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#setProjectionMatrix + * @since 3.50.0 + * + * @param {number} width - The new width of this WebGL Pipeline. + * @param {number} height - The new height of this WebGL Pipeline. + * + * @return {this} This WebGLPipeline instance. + */ + setProjectionMatrix: function (width, height) { - /** - * The Scene that owns the Camera Manager plugin. - * - * @name Phaser.Cameras.Scene2D.CameraManager#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; + var projectionMatrix = this.projectionMatrix; - /** - * A reference to the Scene.Systems handler for the Scene that owns the Camera Manager. - * - * @name Phaser.Cameras.Scene2D.CameraManager#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.systems = scene.sys; + // Because not all pipelines have them + if (!projectionMatrix) + { + return this; + } - /** - * All Cameras created by, or added to, this Camera Manager, will have their `roundPixels` - * property set to match this value. By default it is set to match the value set in the - * game configuration, but can be changed at any point. Equally, individual cameras can - * also be changed as needed. - * - * @name Phaser.Cameras.Scene2D.CameraManager#roundPixels - * @type {boolean} - * @since 3.11.0 - */ - this.roundPixels = scene.sys.game.config.roundPixels; + this.projectionWidth = width; + this.projectionHeight = height; - /** - * An Array of the Camera objects being managed by this Camera Manager. - * The Cameras are updated and rendered in the same order in which they appear in this array. - * Do not directly add or remove entries to this array. However, you can move the contents - * around the array should you wish to adjust the display order. - * - * @name Phaser.Cameras.Scene2D.CameraManager#cameras - * @type {Phaser.Cameras.Scene2D.Camera[]} - * @since 3.0.0 - */ - this.cameras = []; + projectionMatrix.ortho(0, width, height, 0, -1000, 1000); - /** - * A handy reference to the 'main' camera. By default this is the first Camera the - * Camera Manager creates. You can also set it directly, or use the `makeMain` argument - * in the `add` and `addExisting` methods. It allows you to access it from your game: - * - * ```javascript - * var cam = this.cameras.main; - * ``` - * - * Also see the properties `camera1`, `camera2` and so on. - * - * @name Phaser.Cameras.Scene2D.CameraManager#main - * @type {Phaser.Cameras.Scene2D.Camera} - * @since 3.0.0 - */ - this.main; + var shaders = this.shaders; - /** - * A default un-transformed Camera that doesn't exist on the camera list and doesn't - * count towards the total number of cameras being managed. It exists for other - * systems, as well as your own code, should they require a basic un-transformed - * camera instance from which to calculate a view matrix. - * - * @name Phaser.Cameras.Scene2D.CameraManager#default - * @type {Phaser.Cameras.Scene2D.Camera} - * @since 3.17.0 - */ - this.default; + var name = 'uProjectionMatrix'; - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); - scene.sys.events.on(SceneEvents.START, this.start, this); + for (var i = 0; i < shaders.length; i++) + { + var shader = shaders[i]; + + if (shader.hasUniform(name)) + { + shader.resetUniform(name); + + shader.setMatrix4fv(name, false, projectionMatrix.val, shader); + } + } + + return this; }, /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. + * Adjusts this pipelines ortho Projection Matrix to flip the y + * and bottom values. Call with 'false' as the parameter to flip + * them back again. * - * @method Phaser.Cameras.Scene2D.CameraManager#boot - * @private - * @listens Phaser.Scenes.Events#DESTROY - * @since 3.5.1 + * @method Phaser.Renderer.WebGL.WebGLPipeline#flipProjectionMatrix + * @since 3.60.0 + * + * @param {boolean} [flipY=true] - Flip the y and bottom values? */ - boot: function () + flipProjectionMatrix: function (flipY) { - var sys = this.systems; + if (flipY === undefined) { flipY = true; } - if (sys.settings.cameras) + var projectionMatrix = this.projectionMatrix; + + // Because not all pipelines have them + if (!projectionMatrix) { - // We have cameras to create - this.fromJSON(sys.settings.cameras); + return this; + } + + var width = this.projectionWidth; + var height = this.projectionHeight; + + if (flipY) + { + projectionMatrix.ortho(0, width, 0, height, -1000, 1000); } else { - // Make one - this.add(); + projectionMatrix.ortho(0, width, height, 0, -1000, 1000); } - this.main = this.cameras[0]; - - // Create a default camera - this.default = new Camera(0, 0, sys.scale.width, sys.scale.height).setScene(this.scene); - - sys.game.scale.on(ScaleEvents.RESIZE, this.onResize, this); - - this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); + this.setMatrix4fv('uProjectionMatrix', false, projectionMatrix.val); }, /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. + * Adjusts this pipelines ortho Projection Matrix to match that of the global + * WebGL Renderer Projection Matrix. * - * @method Phaser.Cameras.Scene2D.CameraManager#start - * @private - * @listens Phaser.Scenes.Events#UPDATE - * @listens Phaser.Scenes.Events#SHUTDOWN - * @since 3.5.0 + * This method is called automatically by the Pipeline Manager when this + * pipeline is set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#updateProjectionMatrix + * @since 3.50.0 */ - start: function () + updateProjectionMatrix: function () { - if (!this.main) + if (this.projectionMatrix) { - var sys = this.systems; + var globalWidth = this.renderer.projectionWidth; + var globalHeight = this.renderer.projectionHeight; - if (sys.settings.cameras) - { - // We have cameras to create - this.fromJSON(sys.settings.cameras); - } - else + if (this.projectionWidth !== globalWidth || this.projectionHeight !== globalHeight) { - // Make one - this.add(); + this.setProjectionMatrix(globalWidth, globalHeight); } - - this.main = this.cameras[0]; } - - var eventEmitter = this.systems.events; - - eventEmitter.on(SceneEvents.UPDATE, this.update, this); - eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * Adds a new Camera into the Camera Manager. The Camera Manager can support up to 31 different Cameras. - * - * Each Camera has its own viewport, which controls the size of the Camera and its position within the canvas. - * - * Use the `Camera.scrollX` and `Camera.scrollY` properties to change where the Camera is looking, or the - * Camera methods such as `centerOn`. Cameras also have built in special effects, such as fade, flash, shake, - * pan and zoom. - * - * By default Cameras are transparent and will render anything that they can see based on their `scrollX` - * and `scrollY` values. Game Objects can be set to be ignored by a Camera by using the `Camera.ignore` method. - * - * The Camera will have its `roundPixels` property set to whatever `CameraManager.roundPixels` is. You can change - * it after creation if required. + * This method is called every time the Pipeline Manager makes this pipeline the currently active one. * - * See the Camera class documentation for more details. + * It binds the resources and shader needed for this pipeline, including setting the vertex buffer + * and attribute pointers. * - * @method Phaser.Cameras.Scene2D.CameraManager#add + * @method Phaser.Renderer.WebGL.WebGLPipeline#bind + * @fires Phaser.Renderer.WebGL.Pipelines.Events#BIND * @since 3.0.0 * - * @param {number} [x=0] - The horizontal position of the Camera viewport. - * @param {number} [y=0] - The vertical position of the Camera viewport. - * @param {number} [width] - The width of the Camera viewport. If not given it'll be the game config size. - * @param {number} [height] - The height of the Camera viewport. If not given it'll be the game config size. - * @param {boolean} [makeMain=false] - Set this Camera as being the 'main' camera. This just makes the property `main` a reference to it. - * @param {string} [name=''] - The name of the Camera. + * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. * - * @return {Phaser.Cameras.Scene2D.Camera} The newly created Camera. + * @return {this} This WebGLPipeline instance. */ - add: function (x, y, width, height, makeMain, name) + bind: function (currentShader) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.scene.sys.scale.width; } - if (height === undefined) { height = this.scene.sys.scale.height; } - if (makeMain === undefined) { makeMain = false; } - if (name === undefined) { name = ''; } - - var camera = new Camera(x, y, width, height); + if (currentShader === undefined) { currentShader = this.currentShader; } - camera.setName(name); - camera.setScene(this.scene); - camera.setRoundPixels(this.roundPixels); + if (this.glReset) + { + return this.rebind(currentShader); + } - camera.id = this.getNextID(); + var wasBound = false; - this.cameras.push(camera); + var gl = this.gl; - if (makeMain) + if (gl.getParameter(gl.ARRAY_BUFFER_BINDING) !== this.vertexBuffer) { - this.main = camera; + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + + this.activeBuffer = this.vertexBuffer; + + wasBound = true; } - return camera; + currentShader.bind(wasBound); + + this.currentShader = currentShader; + + this.activeTextures.length = 0; + + this.emit(Events.BIND, this, currentShader); + + this.onActive(currentShader); + + return this; }, /** - * Adds an existing Camera into the Camera Manager. - * - * The Camera should either be a `Phaser.Cameras.Scene2D.Camera` instance, or a class that extends from it. - * - * The Camera will have its `roundPixels` property set to whatever `CameraManager.roundPixels` is. You can change - * it after addition if required. - * - * The Camera will be assigned an ID, which is used for Game Object exclusion and then added to the - * manager. As long as it doesn't already exist in the manager it will be added then returned. + * This method is called every time the Pipeline Manager rebinds this pipeline. * - * If this method returns `null` then the Camera already exists in this Camera Manager. + * It resets all shaders this pipeline uses, setting their attributes again. * - * @method Phaser.Cameras.Scene2D.CameraManager#addExisting + * @method Phaser.Renderer.WebGL.WebGLPipeline#rebind + * @fires Phaser.Renderer.WebGL.Pipelines.Events#REBIND * @since 3.0.0 * - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to be added to the Camera Manager. - * @param {boolean} [makeMain=false] - Set this Camera as being the 'main' camera. This just makes the property `main` a reference to it. + * @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current. * - * @return {?Phaser.Cameras.Scene2D.Camera} The Camera that was added to the Camera Manager, or `null` if it couldn't be added. + * @return {this} This WebGLPipeline instance. */ - addExisting: function (camera, makeMain) + rebind: function (currentShader) { - if (makeMain === undefined) { makeMain = false; } - - var index = this.cameras.indexOf(camera); + this.activeBuffer = null; - if (index === -1) - { - camera.id = this.getNextID(); + this.setVertexBuffer(); - camera.setRoundPixels(this.roundPixels); + var shaders = this.shaders; - this.cameras.push(camera); + // Loop in reverse, so the first shader in the array is left as being bound + for (var i = shaders.length - 1; i >= 0; i--) + { + var shader = shaders[i].rebind(); - if (makeMain) + if (!currentShader || shader === currentShader) { - this.main = camera; + this.currentShader = shader; } - - return camera; } - return null; + this.activeTextures.length = 0; + + this.emit(Events.REBIND, this.currentShader); + + this.onActive(this.currentShader); + + this.onRebind(); + + this.glReset = false; + + return this; }, /** - * Gets the next available Camera ID number. + * Binds the vertex buffer to be the active ARRAY_BUFFER on the WebGL context. * - * The Camera Manager supports up to 31 unique cameras, after which the ID returned will always be zero. - * You can create additional cameras beyond 31, but they cannot be used for Game Object exclusion. + * It first checks to see if it's already set as the active buffer and only + * binds itself if not. * - * @method Phaser.Cameras.Scene2D.CameraManager#getNextID - * @private - * @since 3.11.0 + * @method Phaser.Renderer.WebGL.WebGLPipeline#setVertexBuffer + * @since 3.50.0 * - * @return {number} The next available Camera ID, or 0 if they're all already in use. + * @param {WebGLBuffer} [buffer] - The Vertex Buffer to be bound. Defaults to the one owned by this pipeline. + * + * @return {boolean} `true` if the vertex buffer was bound, or `false` if it was already bound. */ - getNextID: function () + setVertexBuffer: function (buffer) { - var cameras = this.cameras; - - var testID = 1; - - // Find the first free camera ID we can use + if (buffer === undefined) { buffer = this.vertexBuffer; } - for (var t = 0; t < 32; t++) + if (buffer !== this.activeBuffer) { - var found = false; + var gl = this.gl; - for (var i = 0; i < cameras.length; i++) - { - var camera = cameras[i]; + this.gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - if (camera && camera.id === testID) - { - found = true; - continue; - } - } + this.activeBuffer = buffer; - if (found) - { - testID = testID << 1; - } - else - { - return testID; - } + return true; } - return 0; + return false; }, /** - * Gets the total number of Cameras in this Camera Manager. + * This method is called as a result of the `WebGLPipeline.batchQuad` method, right before a quad + * belonging to a Game Object is about to be added to the batch. When this is called, the + * renderer has just performed a flush. It will bind the current render target, if any are set + * and finally call the `onPreBatch` hook. * - * If the optional `isVisible` argument is set it will only count Cameras that are currently visible. + * It is also called as part of the `PipelineManager.preBatch` method when processing Post FX Pipelines. * - * @method Phaser.Cameras.Scene2D.CameraManager#getTotal - * @since 3.11.0 + * @method Phaser.Renderer.WebGL.WebGLPipeline#preBatch + * @since 3.50.0 * - * @param {boolean} [isVisible=false] - Set the `true` to only include visible Cameras in the total. + * @param {(Phaser.GameObjects.GameObject|Phaser.Cameras.Scene2D.Camera)} [gameObject] - The Game Object or Camera that invoked this pipeline, if any. * - * @return {number} The total number of Cameras in this Camera Manager. + * @return {this} This WebGLPipeline instance. */ - getTotal: function (isVisible) + preBatch: function (gameObject) { - if (isVisible === undefined) { isVisible = false; } + if (this.currentRenderTarget) + { + this.currentRenderTarget.bind(); + } - var total = 0; + this.onPreBatch(gameObject); - var cameras = this.cameras; + return this; + }, - for (var i = 0; i < cameras.length; i++) - { - var camera = cameras[i]; + /** + * This method is called as a result of the `WebGLPipeline.batchQuad` method, right after a quad + * belonging to a Game Object has been added to the batch. When this is called, the + * renderer has just performed a flush. + * + * It calls the `onDraw` hook followed by the `onPostBatch` hook, which can be used to perform + * additional Post FX Pipeline processing. + * + * It is also called as part of the `PipelineManager.postBatch` method when processing Post FX Pipelines. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#postBatch + * @since 3.50.0 + * + * @param {(Phaser.GameObjects.GameObject|Phaser.Cameras.Scene2D.Camera)} [gameObject] - The Game Object or Camera that invoked this pipeline, if any. + * + * @return {this} This WebGLPipeline instance. + */ + postBatch: function (gameObject) + { + this.onDraw(this.currentRenderTarget); - if (!isVisible || (isVisible && camera.visible)) - { - total++; - } - } + this.onPostBatch(gameObject); - return total; + return this; }, /** - * Populates this Camera Manager based on the given configuration object, or an array of config objects. + * This method is only used by Sprite FX and Post FX Pipelines and those that extend from them. * - * See the `Phaser.Types.Cameras.Scene2D.CameraConfig` documentation for details of the object structure. + * This method is called every time the `postBatch` method is called and is passed a + * reference to the current render target. * - * @method Phaser.Cameras.Scene2D.CameraManager#fromJSON - * @since 3.0.0 + * At the very least a Post FX Pipeline should call `this.bindAndDraw(renderTarget)`, + * however, you can do as much additional processing as you like in this method if + * you override it from within your own pipelines. * - * @param {(Phaser.Types.Cameras.Scene2D.CameraConfig|Phaser.Types.Cameras.Scene2D.CameraConfig[])} config - A Camera configuration object, or an array of them, to be added to this Camera Manager. + * @method Phaser.Renderer.WebGL.WebGLPipeline#onDraw + * @since 3.50.0 * - * @return {this} This Camera Manager instance. + * @param {Phaser.Renderer.WebGL.RenderTarget} renderTarget - The Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} [swapTarget] - A Swap Render Target, useful for double-buffer effects. Only set by SpriteFX Pipelines. */ - fromJSON: function (config) + onDraw: function () { - if (!Array.isArray(config)) + }, + + /** + * This method is called every time the Pipeline Manager deactivates this pipeline, swapping from + * it to another one. This happens after a call to `flush` and before the new pipeline is bound. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#unbind + * @since 3.50.0 + */ + unbind: function () + { + if (this.currentRenderTarget) { - config = [ config ]; + this.currentRenderTarget.unbind(); } + }, - var gameWidth = this.scene.sys.scale.width; - var gameHeight = this.scene.sys.scale.height; + /** + * Uploads the vertex data and emits a draw call for the current batch of vertices. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#flush + * @fires Phaser.Renderer.WebGL.Pipelines.Events#BEFORE_FLUSH + * @fires Phaser.Renderer.WebGL.Pipelines.Events#AFTER_FLUSH + * @since 3.0.0 + * + * @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not? + * + * @return {this} This WebGLPipeline instance. + */ + flush: function (isPostFlush) + { + if (isPostFlush === undefined) { isPostFlush = false; } - for (var i = 0; i < config.length; i++) + if (this.vertexCount > 0) { - var cameraConfig = config[i]; + this.emit(Events.BEFORE_FLUSH, this, isPostFlush); - var x = GetFastValue(cameraConfig, 'x', 0); - var y = GetFastValue(cameraConfig, 'y', 0); - var width = GetFastValue(cameraConfig, 'width', gameWidth); - var height = GetFastValue(cameraConfig, 'height', gameHeight); + this.onBeforeFlush(isPostFlush); - var camera = this.add(x, y, width, height); + var gl = this.gl; + var vertexCount = this.vertexCount; + var vertexSize = this.currentShader.vertexSize; + var topology = this.topology; - // Direct properties - camera.name = GetFastValue(cameraConfig, 'name', ''); - camera.zoom = GetFastValue(cameraConfig, 'zoom', 1); - camera.rotation = GetFastValue(cameraConfig, 'rotation', 0); - camera.scrollX = GetFastValue(cameraConfig, 'scrollX', 0); - camera.scrollY = GetFastValue(cameraConfig, 'scrollY', 0); - camera.roundPixels = GetFastValue(cameraConfig, 'roundPixels', false); - camera.visible = GetFastValue(cameraConfig, 'visible', true); + if (this.active) + { + this.setVertexBuffer(); - // Background Color + if (vertexCount === this.vertexCapacity) + { + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.DYNAMIC_DRAW); + } + else + { + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bytes.subarray(0, vertexCount * vertexSize)); + } - var backgroundColor = GetFastValue(cameraConfig, 'backgroundColor', false); + var i; + var entry; + var texture; + var batch = this.batch; + var activeTextures = this.activeTextures; - if (backgroundColor) - { - camera.setBackgroundColor(backgroundColor); - } + if (this.forceZero) + { + // Single Texture Pipeline + if (!activeTextures[0]) + { + gl.activeTexture(gl.TEXTURE0); + } - // Bounds + for (i = 0; i < batch.length; i++) + { + entry = batch[i]; + texture = entry.texture[0]; - var boundsConfig = GetFastValue(cameraConfig, 'bounds', null); + if (activeTextures[0] !== texture) + { + gl.bindTexture(gl.TEXTURE_2D, texture); - if (boundsConfig) - { - var bx = GetFastValue(boundsConfig, 'x', 0); - var by = GetFastValue(boundsConfig, 'y', 0); - var bwidth = GetFastValue(boundsConfig, 'width', gameWidth); - var bheight = GetFastValue(boundsConfig, 'height', gameHeight); + activeTextures[0] = texture; + } - camera.setBounds(bx, by, bwidth, bheight); + gl.drawArrays(topology, entry.start, entry.count); + } + } + else + { + for (i = 0; i < batch.length; i++) + { + entry = batch[i]; + + for (var t = 0; t <= entry.maxUnit; t++) + { + texture = entry.texture[t]; + + if (activeTextures[t] !== texture) + { + gl.activeTexture(gl.TEXTURE0 + t); + gl.bindTexture(gl.TEXTURE_2D, texture); + + activeTextures[t] = texture; + } + } + + gl.drawArrays(topology, entry.start, entry.count); + } + } } + + this.vertexCount = 0; + + this.batch.length = 0; + this.currentBatch = null; + this.currentTexture = null; + this.currentUnit = 0; + + this.emit(Events.AFTER_FLUSH, this, isPostFlush); + + this.onAfterFlush(isPostFlush); } return this; }, /** - * Gets a Camera based on its name. + * By default this is an empty method hook that you can override and use in your own custom pipelines. * - * Camera names are optional and don't have to be set, so this method is only of any use if you - * have given your Cameras unique names. + * This method is called every time the Pipeline Manager makes this the active pipeline. It is called + * at the end of the `WebGLPipeline.bind` method, after the current shader has been set. The current + * shader is passed to this hook. * - * @method Phaser.Cameras.Scene2D.CameraManager#getCamera - * @since 3.0.0 + * For example, if a display list has 3 Sprites in it that all use the same pipeline, this hook will + * only be called for the first one, as the 2nd and 3rd Sprites do not cause the pipeline to be changed. * - * @param {string} name - The name of the Camera. + * If you need to listen for that event instead, use the `onBind` hook. * - * @return {?Phaser.Cameras.Scene2D.Camera} The first Camera with a name matching the given string, otherwise `null`. + * @method Phaser.Renderer.WebGL.WebGLPipeline#onActive + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.WebGLShader} currentShader - The shader that was set as current. */ - getCamera: function (name) + onActive: function () { - var cameras = this.cameras; - - for (var i = 0; i < cameras.length; i++) - { - if (cameras[i].name === name) - { - return cameras[i]; - } - } - - return null; }, /** - * Returns an array of all cameras below the given Pointer. + * By default this is an empty method hook that you can override and use in your own custom pipelines. * - * The first camera in the array is the top-most camera in the camera list. + * This method is called every time a **Game Object** asks the Pipeline Manager to use this pipeline, + * even if the pipeline is already active. * - * @method Phaser.Cameras.Scene2D.CameraManager#getCamerasBelowPointer - * @since 3.10.0 + * Unlike the `onActive` method, which is only called when the Pipeline Manager makes this pipeline + * active, this hook is called for every Game Object that requests use of this pipeline, allowing you to + * perform per-object set-up, such as loading shader uniform data. * - * @param {Phaser.Input.Pointer} pointer - The Pointer to check against. + * @method Phaser.Renderer.WebGL.WebGLPipeline#onBind + * @since 3.50.0 * - * @return {Phaser.Cameras.Scene2D.Camera[]} An array of cameras below the Pointer. + * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. */ - getCamerasBelowPointer: function (pointer) + onBind: function () { - var cameras = this.cameras; - - var x = pointer.x; - var y = pointer.y; - - var output = []; - - for (var i = 0; i < cameras.length; i++) - { - var camera = cameras[i]; - - if (camera.visible && camera.inputEnabled && RectangleContains(camera, x, y)) - { - // So the top-most camera is at the top of the search array - output.unshift(camera); - } - } + }, - return output; + /** + * By default this is an empty method hook that you can override and use in your own custom pipelines. + * + * This method is called when the Pipeline Manager needs to rebind this pipeline. This happens after a + * pipeline has been cleared, usually when passing control over to a 3rd party WebGL library, like Spine, + * and then returing to Phaser again. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#onRebind + * @since 3.50.0 + */ + onRebind: function () + { }, /** - * Removes the given Camera, or an array of Cameras, from this Camera Manager. + * By default this is an empty method hook that you can override and use in your own custom pipelines. * - * If found in the Camera Manager it will be immediately removed from the local cameras array. - * If also currently the 'main' camera, 'main' will be reset to be camera 0. + * This method is called every time the `batchQuad` or `batchTri` methods are called. If this was + * as a result of a Game Object, then the Game Object reference is passed to this hook too. * - * The removed Cameras are automatically destroyed if the `runDestroy` argument is `true`, which is the default. - * If you wish to re-use the cameras then set this to `false`, but know that they will retain their references - * and internal data until destroyed or re-added to a Camera Manager. + * This hook is called _after_ the quad (or tri) has been added to the batch, so you can safely + * call 'flush' from within this. * - * @method Phaser.Cameras.Scene2D.CameraManager#remove - * @since 3.0.0 + * Note that Game Objects may call `batchQuad` or `batchTri` multiple times for a single draw, + * for example the Graphics Game Object. * - * @param {(Phaser.Cameras.Scene2D.Camera|Phaser.Cameras.Scene2D.Camera[])} camera - The Camera, or an array of Cameras, to be removed from this Camera Manager. - * @param {boolean} [runDestroy=true] - Automatically call `Camera.destroy` on each Camera removed from this Camera Manager. + * @method Phaser.Renderer.WebGL.WebGLPipeline#onBatch + * @since 3.50.0 * - * @return {number} The total number of Cameras removed. + * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. */ - remove: function (camera, runDestroy) + onBatch: function () { - if (runDestroy === undefined) { runDestroy = true; } - - if (!Array.isArray(camera)) - { - camera = [ camera ]; - } - - var total = 0; - var cameras = this.cameras; - - for (var i = 0; i < camera.length; i++) - { - var index = cameras.indexOf(camera[i]); - - if (index !== -1) - { - if (runDestroy) - { - cameras[index].destroy(); - } - else - { - cameras[index].renderList = []; - } - - cameras.splice(index, 1); - - total++; - } - } - - if (!this.main && cameras[0]) - { - this.main = cameras[0]; - } - - return total; }, /** - * The internal render method. This is called automatically by the Scene and should not be invoked directly. + * By default this is an empty method hook that you can override and use in your own custom pipelines. * - * It will iterate through all local cameras and render them in turn, as long as they're visible and have - * an alpha level > 0. + * This method is called immediately before a **Game Object** is about to add itself to the batch. * - * @method Phaser.Cameras.Scene2D.CameraManager#render - * @protected - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.WebGLPipeline#onPreBatch + * @since 3.50.0 * - * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Renderer that will render the children to this camera. - * @param {Phaser.GameObjects.DisplayList} displayList - The Display List for the Scene. + * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. */ - render: function (renderer, displayList) + onPreBatch: function () { - var scene = this.scene; - var cameras = this.cameras; - - for (var i = 0; i < this.cameras.length; i++) - { - var camera = cameras[i]; - - if (camera.visible && camera.alpha > 0) - { - camera.preRender(); - - var visibleChildren = this.getVisibleChildren(displayList.getChildren(), camera); - - renderer.render(scene, visibleChildren, camera); - } - } }, /** - * Takes an array of Game Objects and a Camera and returns a new array - * containing only those Game Objects that pass the `willRender` test - * against the given Camera. + * By default this is an empty method hook that you can override and use in your own custom pipelines. * - * @method Phaser.Cameras.Scene2D.CameraManager#getVisibleChildren - * @since 3.50.0 + * This method is called immediately after a **Game Object** has been added to the batch. * - * @param {Phaser.GameObjects.GameObject[]} children - An array of Game Objects to be checked against the camera. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to filte the Game Objects against. + * @method Phaser.Renderer.WebGL.WebGLPipeline#onPostBatch + * @since 3.50.0 * - * @return {Phaser.GameObjects.GameObject[]} A filtered list of only Game Objects within the Scene that will render against the given Camera. + * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any. */ - getVisibleChildren: function (children, camera) + onPostBatch: function () { - var visible = []; - - for (var i = 0; i < children.length; i++) - { - var child = children[i]; - - if (child.willRender(camera)) - { - visible.push(child); - } - } + }, - return visible; + /** + * By default this is an empty method hook that you can override and use in your own custom pipelines. + * + * This method is called once per frame, right before anything has been rendered, but after the canvas + * has been cleared. If this pipeline has a render target, it will also have been cleared by this point. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#onPreRender + * @since 3.50.0 + */ + onPreRender: function () + { }, /** - * Resets this Camera Manager. + * By default this is an empty method hook that you can override and use in your own custom pipelines. * - * This will iterate through all current Cameras, destroying them all, then it will reset the - * cameras array, reset the ID counter and create 1 new single camera using the default values. + * This method is called _once per frame_, by every Camera in a Scene that wants to render. * - * @method Phaser.Cameras.Scene2D.CameraManager#resetAll - * @since 3.0.0 + * It is called at the start of the rendering process, before anything has been drawn to the Camera. * - * @return {Phaser.Cameras.Scene2D.Camera} The freshly created main Camera. + * @method Phaser.Renderer.WebGL.WebGLPipeline#onRender + * @since 3.50.0 + * + * @param {Phaser.Scene} scene - The Scene being rendered. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered with. */ - resetAll: function () + onRender: function () { - for (var i = 0; i < this.cameras.length; i++) - { - this.cameras[i].destroy(); - } - - this.cameras = []; - - this.main = this.add(); - - return this.main; }, /** - * The main update loop. Called automatically when the Scene steps. + * By default this is an empty method hook that you can override and use in your own custom pipelines. * - * @method Phaser.Cameras.Scene2D.CameraManager#update - * @protected - * @since 3.0.0 + * This method is called _once per frame_, after all rendering has happened and snapshots have been taken. * - * @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. + * It is called at the very end of the rendering process, once all Cameras, for all Scenes, have + * been rendered. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#onPostRender + * @since 3.50.0 */ - update: function (time, delta) + onPostRender: function () { - for (var i = 0; i < this.cameras.length; i++) - { - this.cameras[i].update(time, delta); - } }, /** - * The event handler that manages the `resize` event dispatched by the Scale Manager. + * By default this is an empty method hook that you can override and use in your own custom pipelines. * - * @method Phaser.Cameras.Scene2D.CameraManager#onResize - * @since 3.18.0 + * This method is called every time this pipeline is asked to flush its batch. * - * @param {Phaser.Structs.Size} gameSize - The default Game Size object. This is the un-modified game dimensions. - * @param {Phaser.Structs.Size} baseSize - The base Size object. The game dimensions. The canvas width / height values match this. + * It is called immediately before the `gl.bufferData` and `gl.drawArrays` calls are made, so you can + * perform any final pre-render modifications. To apply changes post-render, see `onAfterFlush`. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#onBeforeFlush + * @since 3.50.0 + * + * @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not? */ - onResize: function (gameSize, baseSize, displaySize, previousWidth, previousHeight) + onBeforeFlush: function () { - for (var i = 0; i < this.cameras.length; i++) - { - var cam = this.cameras[i]; - - // if camera is at 0x0 and was the size of the previous game size, then we can safely assume it - // should be updated to match the new game size too - - if (cam._x === 0 && cam._y === 0 && cam._width === previousWidth && cam._height === previousHeight) - { - cam.setSize(baseSize.width, baseSize.height); - } - } }, /** - * Resizes all cameras to the given dimensions. + * By default this is an empty method hook that you can override and use in your own custom pipelines. * - * @method Phaser.Cameras.Scene2D.CameraManager#resize - * @since 3.2.0 + * This method is called immediately after this pipeline has finished flushing its batch. * - * @param {number} width - The new width of the camera. - * @param {number} height - The new height of the camera. + * It is called after the `gl.drawArrays` call. + * + * You can perform additional post-render effects, but be careful not to call `flush` + * on this pipeline from within this method, or you'll cause an infinite loop. + * + * To apply changes pre-render, see `onBeforeFlush`. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#onAfterFlush + * @since 3.50.0 + * + * @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not? */ - resize: function (width, height) + onAfterFlush: function () { - for (var i = 0; i < this.cameras.length; i++) - { - this.cameras[i].setSize(width, height); - } }, /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. + * Adds a single vertex to the current vertex buffer and increments the + * `vertexCount` property by 1. * - * @method Phaser.Cameras.Scene2D.CameraManager#shutdown - * @private - * @since 3.0.0 + * This method is called directly by `batchTri` and `batchQuad`. + * + * It does not perform any batch limit checking itself, so if you need to call + * this method directly, do so in the same way that `batchQuad` does, for example. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#batchVert + * @since 3.50.0 + * + * @param {number} x - The vertex x position. + * @param {number} y - The vertex y position. + * @param {number} u - UV u value. + * @param {number} v - UV v value. + * @param {number} unit - Texture unit to which the texture needs to be bound. + * @param {(number|boolean)} tintEffect - The tint effect for the shader to use. + * @param {number} tint - The tint color value. */ - shutdown: function () + batchVert: function (x, y, u, v, unit, tintEffect, tint) { - this.main = undefined; + var vertexViewF32 = this.vertexViewF32; + var vertexViewU32 = this.vertexViewU32; - for (var i = 0; i < this.cameras.length; i++) - { - this.cameras[i].destroy(); - } + var vertexOffset = (this.vertexCount * this.currentShader.vertexComponentCount) - 1; - this.cameras = []; + vertexViewF32[++vertexOffset] = x; + vertexViewF32[++vertexOffset] = y; + vertexViewF32[++vertexOffset] = u; + vertexViewF32[++vertexOffset] = v; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tint; - var eventEmitter = this.systems.events; + this.vertexCount++; - eventEmitter.off(SceneEvents.UPDATE, this.update, this); - eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); + this.currentBatch.count = (this.vertexCount - this.currentBatch.start); }, /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. + * Adds the vertices data into the batch and flushes if full. * - * @method Phaser.Cameras.Scene2D.CameraManager#destroy - * @private - * @since 3.0.0 + * Assumes 6 vertices in the following arrangement: + * + * ``` + * 0----3 + * |\ B| + * | \ | + * | \ | + * | A \| + * | \ + * 1----2 + * ``` + * + * Where tx0/ty0 = 0, tx1/ty1 = 1, tx2/ty2 = 2 and tx3/ty3 = 3 + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#batchQuad + * @since 3.50.0 + * + * @param {(Phaser.GameObjects.GameObject|null)} gameObject - The Game Object, if any, drawing this quad. + * @param {number} x0 - The top-left x position. + * @param {number} y0 - The top-left y position. + * @param {number} x1 - The bottom-left x position. + * @param {number} y1 - The bottom-left y position. + * @param {number} x2 - The bottom-right x position. + * @param {number} y2 - The bottom-right y position. + * @param {number} x3 - The top-right x position. + * @param {number} y3 - The top-right y position. + * @param {number} u0 - UV u0 value. + * @param {number} v0 - UV v0 value. + * @param {number} u1 - UV u1 value. + * @param {number} v1 - UV v1 value. + * @param {number} tintTL - The top-left tint color value. + * @param {number} tintTR - The top-right tint color value. + * @param {number} tintBL - The bottom-left tint color value. + * @param {number} tintBR - The bottom-right tint color value. + * @param {(number|boolean)} tintEffect - The tint effect for the shader to use. + * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs. + * @param {number} [unit=0] - Texture unit to which the texture needs to be bound. + * + * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`. */ - destroy: function () + batchQuad: function (gameObject, x0, y0, x1, y1, x2, y2, x3, y3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, unit) { - this.shutdown(); - - this.default.destroy(); - - this.scene.sys.events.off(SceneEvents.START, this.start, this); - - this.scene = null; - this.systems = null; - } - -}); - -PluginCache.register('CameraManager', CameraManager, 'cameras'); - -module.exports = CameraManager; - - -/***/ }), -/* 800 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Scale Manager has successfully entered fullscreen mode. - * - * @event Phaser.Scale.Events#ENTER_FULLSCREEN - * @since 3.16.1 - */ -module.exports = 'enterfullscreen'; - - -/***/ }), -/* 801 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Scale Manager tried to enter fullscreen mode but failed. - * - * @event Phaser.Scale.Events#FULLSCREEN_FAILED - * @since 3.17.0 - */ -module.exports = 'fullscreenfailed'; - - -/***/ }), -/* 802 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Scale Manager tried to enter fullscreen mode, but it is unsupported by the browser. - * - * @event Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED - * @since 3.16.1 - */ -module.exports = 'fullscreenunsupported'; - - -/***/ }), -/* 803 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Scale Manager was in fullscreen mode, but has since left, either directly via game code, - * or via a user gestured, such as pressing the ESC key. - * - * @event Phaser.Scale.Events#LEAVE_FULLSCREEN - * @since 3.16.1 - */ -module.exports = 'leavefullscreen'; - - -/***/ }), -/* 804 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Scale Manager Orientation Change Event. - * - * This event is dispatched whenever the Scale Manager detects an orientation change event from the browser. - * - * @event Phaser.Scale.Events#ORIENTATION_CHANGE - * @since 3.16.1 - * - * @param {string} orientation - The new orientation value. Either `Phaser.Scale.Orientation.LANDSCAPE` or `Phaser.Scale.Orientation.PORTRAIT`. - */ -module.exports = 'orientationchange'; - - -/***/ }), -/* 805 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Scale Manager Resize Event. - * - * This event is dispatched whenever the Scale Manager detects a resize event from the browser. - * It sends three parameters to the callback, each of them being Size components. You can read - * the `width`, `height`, `aspectRatio` and other properties of these components to help with - * scaling your own game content. - * - * @event Phaser.Scale.Events#RESIZE - * @since 3.16.1 - * - * @param {Phaser.Structs.Size} gameSize - A reference to the Game Size component. This is the un-scaled size of your game canvas. - * @param {Phaser.Structs.Size} baseSize - A reference to the Base Size component. This is the game size. - * @param {Phaser.Structs.Size} displaySize - A reference to the Display Size component. This is the scaled canvas size, after applying zoom and scale mode. - * @param {number} previousWidth - If the `gameSize` has changed, this value contains its previous width, otherwise it contains the current width. - * @param {number} previousHeight - If the `gameSize` has changed, this value contains its previous height, otherwise it contains the current height. - */ -module.exports = 'resize'; - - -/***/ }), -/* 806 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Core - */ - -module.exports = { - - Config: __webpack_require__(346), - CreateRenderer: __webpack_require__(366), - DebugHeader: __webpack_require__(384), - Events: __webpack_require__(22), - TimeStep: __webpack_require__(385), - VisibilityHandler: __webpack_require__(387) - -}; - - -/***/ }), -/* 807 */ -/***/ (function(module, exports) { - -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; + if (unit === undefined) { unit = this.currentUnit; } -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} + var hasFlushed = false; -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; + if (this.shouldFlush(6)) + { + this.flush(); - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } + hasFlushed = true; } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; + if (!this.currentBatch) + { + unit = this.setTexture2D(texture); } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; -process.listeners = function (name) { return [] } - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; + var vertexViewF32 = this.vertexViewF32; + var vertexViewU32 = this.vertexViewU32; + var vertexOffset = (this.vertexCount * this.currentShader.vertexComponentCount) - 1; -/***/ }), -/* 808 */ -/***/ (function(module, exports, __webpack_require__) { + vertexViewF32[++vertexOffset] = x0; + vertexViewF32[++vertexOffset] = y0; + vertexViewF32[++vertexOffset] = u0; + vertexViewF32[++vertexOffset] = v0; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tintTL; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + vertexViewF32[++vertexOffset] = x1; + vertexViewF32[++vertexOffset] = y1; + vertexViewF32[++vertexOffset] = u0; + vertexViewF32[++vertexOffset] = v1; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tintBL; -var Browser = __webpack_require__(136); + vertexViewF32[++vertexOffset] = x2; + vertexViewF32[++vertexOffset] = y2; + vertexViewF32[++vertexOffset] = u1; + vertexViewF32[++vertexOffset] = v1; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tintBR; -/** - * Determines the input support of the browser running this Phaser Game instance. - * These values are read-only and populated during the boot sequence of the game. - * They are then referenced by internal game systems and are available for you to access - * via `this.sys.game.device.input` from within any Scene. - * - * @typedef {object} Phaser.Device.Input - * @since 3.0.0 - * - * @property {?string} wheelType - The newest type of Wheel/Scroll event supported: 'wheel', 'mousewheel', 'DOMMouseScroll' - * @property {boolean} gamepads - Is navigator.getGamepads available? - * @property {boolean} mspointer - Is mspointer available? - * @property {boolean} touch - Is touch available? - */ -var Input = { + vertexViewF32[++vertexOffset] = x0; + vertexViewF32[++vertexOffset] = y0; + vertexViewF32[++vertexOffset] = u0; + vertexViewF32[++vertexOffset] = v0; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tintTL; - gamepads: false, - mspointer: false, - touch: false, - wheelEvent: null + vertexViewF32[++vertexOffset] = x2; + vertexViewF32[++vertexOffset] = y2; + vertexViewF32[++vertexOffset] = u1; + vertexViewF32[++vertexOffset] = v1; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tintBR; -}; + vertexViewF32[++vertexOffset] = x3; + vertexViewF32[++vertexOffset] = y3; + vertexViewF32[++vertexOffset] = u1; + vertexViewF32[++vertexOffset] = v0; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tintTR; -function init () -{ - if (typeof importScripts === 'function') - { - return Input; - } + this.vertexCount += 6; - if ('ontouchstart' in document.documentElement || (navigator.maxTouchPoints && navigator.maxTouchPoints >= 1)) - { - Input.touch = true; - } + this.currentBatch.count = (this.vertexCount - this.currentBatch.start); - if (navigator.msPointerEnabled || navigator.pointerEnabled) - { - Input.mspointer = true; - } + this.onBatch(gameObject); - if (navigator.getGamepads) - { - Input.gamepads = true; - } + return hasFlushed; + }, - // See https://developer.mozilla.org/en-US/docs/Web/Events/wheel - if ('onwheel' in window || (Browser.ie && 'WheelEvent' in window)) - { - // DOM3 Wheel Event: FF 17+, IE 9+, Chrome 31+, Safari 7+ - Input.wheelEvent = 'wheel'; - } - else if ('onmousewheel' in window) - { - // Non-FF legacy: IE 6-9, Chrome 1-31, Safari 5-7. - Input.wheelEvent = 'mousewheel'; - } - else if (Browser.firefox && 'MouseScrollEvent' in window) + /** + * Adds the vertices data into the batch and flushes if full. + * + * Assumes 3 vertices in the following arrangement: + * + * ``` + * 0 + * |\ + * | \ + * | \ + * | \ + * | \ + * 1-----2 + * ``` + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#batchTri + * @since 3.50.0 + * + * @param {(Phaser.GameObjects.GameObject|null)} gameObject - The Game Object, if any, drawing this quad. + * @param {number} x1 - The bottom-left x position. + * @param {number} y1 - The bottom-left y position. + * @param {number} x2 - The bottom-right x position. + * @param {number} y2 - The bottom-right y position. + * @param {number} x3 - The top-right x position. + * @param {number} y3 - The top-right y position. + * @param {number} u0 - UV u0 value. + * @param {number} v0 - UV v0 value. + * @param {number} u1 - UV u1 value. + * @param {number} v1 - UV v1 value. + * @param {number} tintTL - The top-left tint color value. + * @param {number} tintTR - The top-right tint color value. + * @param {number} tintBL - The bottom-left tint color value. + * @param {(number|boolean)} tintEffect - The tint effect for the shader to use. + * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs. + * @param {number} [unit=0] - Texture unit to which the texture needs to be bound. + * + * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`. + */ + batchTri: function (gameObject, x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintEffect, texture, unit) { - // FF prior to 17. This should probably be scrubbed. - Input.wheelEvent = 'DOMMouseScroll'; - } - - return Input; -} + if (unit === undefined) { unit = this.currentUnit; } -module.exports = init(); + var hasFlushed = false; + if (this.shouldFlush(3)) + { + this.flush(); -/***/ }), -/* 809 */ -/***/ (function(module, exports, __webpack_require__) { + hasFlushed = true; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!this.currentBatch) + { + unit = this.setTexture2D(texture); + } -var Browser = __webpack_require__(136); + var vertexViewF32 = this.vertexViewF32; + var vertexViewU32 = this.vertexViewU32; -/** - * Determines the audio playback capabilities of the device running this Phaser Game instance. - * These values are read-only and populated during the boot sequence of the game. - * They are then referenced by internal game systems and are available for you to access - * via `this.sys.game.device.audio` from within any Scene. - * - * @typedef {object} Phaser.Device.Audio - * @since 3.0.0 - * - * @property {boolean} audioData - Can this device play HTML Audio tags? - * @property {boolean} dolby - Can this device play EC-3 Dolby Digital Plus files? - * @property {boolean} m4a - Can this device can play m4a files. - * @property {boolean} mp3 - Can this device play mp3 files? - * @property {boolean} ogg - Can this device play ogg files? - * @property {boolean} opus - Can this device play opus files? - * @property {boolean} wav - Can this device play wav files? - * @property {boolean} webAudio - Does this device have the Web Audio API? - * @property {boolean} webm - Can this device play webm files? - */ -var Audio = { + var vertexOffset = (this.vertexCount * this.currentShader.vertexComponentCount) - 1; - audioData: false, - dolby: false, - m4a: false, - mp3: false, - ogg: false, - opus: false, - wav: false, - webAudio: false, - webm: false + vertexViewF32[++vertexOffset] = x0; + vertexViewF32[++vertexOffset] = y0; + vertexViewF32[++vertexOffset] = u0; + vertexViewF32[++vertexOffset] = v0; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tintTL; -}; + vertexViewF32[++vertexOffset] = x1; + vertexViewF32[++vertexOffset] = y1; + vertexViewF32[++vertexOffset] = u0; + vertexViewF32[++vertexOffset] = v1; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tintTR; -function init () -{ - if (typeof importScripts === 'function') - { - return Audio; - } + vertexViewF32[++vertexOffset] = x2; + vertexViewF32[++vertexOffset] = y2; + vertexViewF32[++vertexOffset] = u1; + vertexViewF32[++vertexOffset] = v1; + vertexViewF32[++vertexOffset] = unit; + vertexViewF32[++vertexOffset] = tintEffect; + vertexViewU32[++vertexOffset] = tintBL; - Audio.audioData = !!(window['Audio']); + this.vertexCount += 3; - Audio.webAudio = !!(window['AudioContext'] || window['webkitAudioContext']); + this.currentBatch.count = (this.vertexCount - this.currentBatch.start); - var audioElement = document.createElement('audio'); + this.onBatch(gameObject); - var result = !!audioElement.canPlayType; + return hasFlushed; + }, - try + /** + * Pushes a filled rectangle into the vertex batch. + * + * The dimensions are run through `Math.floor` before the quad is generated. + * + * Rectangle has no transform values and isn't transformed into the local space. + * + * Used for directly batching untransformed rectangles, such as Camera background colors. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#drawFillRect + * @since 3.50.0 + * + * @param {number} x - Horizontal top left coordinate of the rectangle. + * @param {number} y - Vertical top left coordinate of the rectangle. + * @param {number} width - Width of the rectangle. + * @param {number} height - Height of the rectangle. + * @param {number} color - Color of the rectangle to draw. + * @param {number} alpha - Alpha value of the rectangle to draw. + * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs. + * @param {boolean} [flipUV=true] - Flip the vertical UV coordinates of the texture before rendering? + */ + drawFillRect: function (x, y, width, height, color, alpha, texture, flipUV) { - if (result) - { - if (audioElement.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, '')) - { - Audio.ogg = true; - } - - if (audioElement.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/, '') || audioElement.canPlayType('audio/opus;').replace(/^no$/, '')) - { - Audio.opus = true; - } + if (texture === undefined) { texture = this.renderer.whiteTexture; } + if (flipUV === undefined) { flipUV = true; } - if (audioElement.canPlayType('audio/mpeg;').replace(/^no$/, '')) - { - Audio.mp3 = true; - } + x = Math.floor(x); + y = Math.floor(y); - // Mimetypes accepted: - // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements - if (audioElement.canPlayType('audio/wav').replace(/^no$/, '')) - { - Audio.wav = true; - } + var xw = Math.floor(x + width); + var yh = Math.floor(y + height); - if (audioElement.canPlayType('audio/x-m4a;') || audioElement.canPlayType('audio/aac;').replace(/^no$/, '')) - { - Audio.m4a = true; - } + var unit = this.setTexture2D(texture); - if (audioElement.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/, '')) - { - Audio.webm = true; - } + var tint = Utils.getTintAppendFloatAlphaAndSwap(color, alpha); - if (audioElement.canPlayType('audio/mp4;codecs="ec-3"') !== '') - { - if (Browser.edge) - { - Audio.dolby = true; - } - else if (Browser.safari && Browser.safariVersion >= 9) - { - if ((/Mac OS X (\d+)_(\d+)/).test(navigator.userAgent)) - { - var major = parseInt(RegExp.$1, 10); - var minor = parseInt(RegExp.$2, 10); + var u0 = 0; + var v0 = 0; + var u1 = 1; + var v1 = 1; - if ((major === 10 && minor >= 11) || major > 10) - { - Audio.dolby = true; - } - } - } - } + if (flipUV) + { + v0 = 1; + v1 = 0; } - } - catch (e) - { - // Nothing to do here - } - - return Audio; -} - -module.exports = init(); - - -/***/ }), -/* 810 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Determines the video support of the browser running this Phaser Game instance. - * These values are read-only and populated during the boot sequence of the game. - * They are then referenced by internal game systems and are available for you to access - * via `this.sys.game.device.video` from within any Scene. - * - * In Phaser 3.20 the properties were renamed to drop the 'Video' suffix. - * - * @typedef {object} Phaser.Device.Video - * @since 3.0.0 - * - * @property {boolean} h264 - Can this device play h264 mp4 video files? - * @property {boolean} hls - Can this device play hls video files? - * @property {boolean} mp4 - Can this device play h264 mp4 video files? - * @property {boolean} ogg - Can this device play ogg video files? - * @property {boolean} vp9 - Can this device play vp9 video files? - * @property {boolean} webm - Can this device play webm video files? - */ -var Video = { - h264: false, - hls: false, - mp4: false, - ogg: false, - vp9: false, - webm: false - -}; + this.batchQuad(null, x, y, x, yh, xw, yh, xw, y, u0, v0, u1, v1, tint, tint, tint, tint, 0, texture, unit); + }, -function init () -{ - if (typeof importScripts === 'function') + /** + * Sets the texture to be bound to the next available texture unit and returns + * the unit id. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#setTexture2D + * @since 3.50.0 + * + * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch. If not given uses `whiteTexture`. + * + * @return {number} The assigned texture unit. + */ + setTexture2D: function (texture) { - return Video; - } + if (texture === undefined) { texture = this.renderer.whiteTexture; } - var videoElement = document.createElement('video'); - var result = !!videoElement.canPlayType; + return this.pushBatch(texture); + }, - try + /** + * Activates the given WebGL Texture and binds it to the requested texture slot. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#bindTexture + * @since 3.50.0 + * + * @param {WebGLTexture} [target] - The WebGLTexture to activate and bind. + * @param {number} [unit=0] - The WebGL texture ID to activate. Defaults to `gl.TEXTURE0`. + * + * @return {this} This WebGL Pipeline instance. + */ + bindTexture: function (texture, unit) { - if (result) - { - if (videoElement.canPlayType('video/ogg; codecs="theora"').replace(/^no$/, '')) - { - Video.ogg = true; - } - - if (videoElement.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/, '')) - { - // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546 - Video.h264 = true; - Video.mp4 = true; - } - - if (videoElement.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/, '')) - { - Video.webm = true; - } + if (unit === undefined) { unit = 0; } - if (videoElement.canPlayType('video/webm; codecs="vp9"').replace(/^no$/, '')) - { - Video.vp9 = true; - } + var gl = this.gl; - if (videoElement.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(/^no$/, '')) - { - Video.hls = true; - } - } - } - catch (e) - { - // Nothing to do - } + gl.activeTexture(gl.TEXTURE0 + unit); - return Video; -} + gl.bindTexture(gl.TEXTURE_2D, texture); -module.exports = init(); + return this; + }, + /** + * Activates the given Render Target texture and binds it to the + * requested WebGL texture slot. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#bindRenderTarget + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The Render Target to activate and bind. + * @param {number} [unit=0] - The WebGL texture ID to activate. Defaults to `gl.TEXTURE0`. + * + * @return {this} This WebGL Pipeline instance. + */ + bindRenderTarget: function (target, unit) + { + return this.bindTexture(target.texture, unit); + }, -/***/ }), -/* 811 */ -/***/ (function(module, exports) { + /** + * Sets the current duration into a 1f uniform value based on the given name. + * + * This can be used for mapping time uniform values, such as `iTime`. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#setTime + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + setTime: function (name, shader) + { + this.set1f(name, this.game.loop.getDuration(), shader); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * Determines the full screen support of the browser running this Phaser Game instance. - * These values are read-only and populated during the boot sequence of the game. - * They are then referenced by internal game systems and are available for you to access - * via `this.sys.game.device.fullscreen` from within any Scene. - * - * @typedef {object} Phaser.Device.Fullscreen - * @since 3.0.0 - * - * @property {boolean} available - Does the browser support the Full Screen API? - * @property {boolean} keyboard - Does the browser support access to the Keyboard during Full Screen mode? - * @property {string} cancel - If the browser supports the Full Screen API this holds the call you need to use to cancel it. - * @property {string} request - If the browser supports the Full Screen API this holds the call you need to use to activate it. - */ -var Fullscreen = { + /** + * Sets a boolean uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#setBoolean + * @since 3.60.0 + * + * @param {string} name - The name of the uniform to set. + * @param {boolean} value - The new value of the `boolean` uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + setBoolean: function (name, value, shader) + { + if (shader === undefined) { shader = this.currentShader; } - available: false, - cancel: '', - keyboard: false, - request: '' + shader.setBoolean(name, value); -}; + return this; + }, -/** -* Checks for support of the Full Screen API. -* -* @ignore -*/ -function init () -{ - if (typeof importScripts === 'function') + /** + * Sets a 1f uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set1f + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new value of the `float` uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set1f: function (name, x, shader) { - return Fullscreen; - } - - var i; + if (shader === undefined) { shader = this.currentShader; } - var suffix1 = 'Fullscreen'; - var suffix2 = 'FullScreen'; + shader.set1f(name, x); - var fs = [ - 'request' + suffix1, - 'request' + suffix2, - 'webkitRequest' + suffix1, - 'webkitRequest' + suffix2, - 'msRequest' + suffix1, - 'msRequest' + suffix2, - 'mozRequest' + suffix2, - 'mozRequest' + suffix1 - ]; + return this; + }, - for (i = 0; i < fs.length; i++) + /** + * Sets a 2f uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set2f + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new X component of the `vec2` uniform. + * @param {number} y - The new Y component of the `vec2` uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set2f: function (name, x, y, shader) { - if (document.documentElement[fs[i]]) - { - Fullscreen.available = true; - Fullscreen.request = fs[i]; - break; - } - } + if (shader === undefined) { shader = this.currentShader; } - var cfs = [ - 'cancel' + suffix2, - 'exit' + suffix1, - 'webkitCancel' + suffix2, - 'webkitExit' + suffix1, - 'msCancel' + suffix2, - 'msExit' + suffix1, - 'mozCancel' + suffix2, - 'mozExit' + suffix1 - ]; + shader.set2f(name, x, y); - if (Fullscreen.available) - { - for (i = 0; i < cfs.length; i++) - { - if (document[cfs[i]]) - { - Fullscreen.cancel = cfs[i]; - break; - } - } - } + return this; + }, - // Keyboard Input? - // Safari 5.1 says it supports fullscreen keyboard, but is lying. - if (window['Element'] && Element['ALLOW_KEYBOARD_INPUT'] && !(/ Version\/5\.1(?:\.\d+)? Safari\//).test(navigator.userAgent)) + /** + * Sets a 3f uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set3f + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new X component of the `vec3` uniform. + * @param {number} y - The new Y component of the `vec3` uniform. + * @param {number} z - The new Z component of the `vec3` uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set3f: function (name, x, y, z, shader) { - Fullscreen.keyboard = true; - } - - Object.defineProperty(Fullscreen, 'active', { get: function () { return !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement); } }); + if (shader === undefined) { shader = this.currentShader; } - return Fullscreen; -} + shader.set3f(name, x, y, z); -module.exports = init(); + return this; + }, + /** + * Sets a 4f uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set4f + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - X component of the uniform + * @param {number} y - Y component of the uniform + * @param {number} z - Z component of the uniform + * @param {number} w - W component of the uniform + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set4f: function (name, x, y, z, w, shader) + { + if (shader === undefined) { shader = this.currentShader; } -/***/ }), -/* 812 */ -/***/ (function(module, exports, __webpack_require__) { + shader.set4f(name, x, y, z, w); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * @namespace Phaser.Math.Angle - */ + /** + * Sets a 1fv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set1fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set1fv: function (name, arr, shader) + { + if (shader === undefined) { shader = this.currentShader; } -module.exports = { + shader.set1fv(name, arr); - Between: __webpack_require__(349), - BetweenPoints: __webpack_require__(350), - BetweenPointsY: __webpack_require__(813), - BetweenY: __webpack_require__(814), - CounterClockwise: __webpack_require__(815), - Normalize: __webpack_require__(351), - Random: __webpack_require__(816), - RandomDegrees: __webpack_require__(817), - Reverse: __webpack_require__(818), - RotateTo: __webpack_require__(819), - ShortestBetween: __webpack_require__(820), - Wrap: __webpack_require__(269), - WrapDegrees: __webpack_require__(270) + return this; + }, -}; + /** + * Sets a 2fv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set2fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set2fv: function (name, arr, shader) + { + if (shader === undefined) { shader = this.currentShader; } + shader.set2fv(name, arr); -/***/ }), -/* 813 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Sets a 3fv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set3fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set3fv: function (name, arr, shader) + { + if (shader === undefined) { shader = this.currentShader; } -/** - * Find the angle of a segment from (point1.x, point1.y) -> (point2.x, point2.y). - * - * The difference between this method and {@link Phaser.Math.Angle.BetweenPoints} is that this assumes the y coordinate - * travels down the screen. - * - * @function Phaser.Math.Angle.BetweenPointsY - * @since 3.0.0 - * - * @param {Phaser.Types.Math.Vector2Like} point1 - The first point. - * @param {Phaser.Types.Math.Vector2Like} point2 - The second point. - * - * @return {number} The angle in radians. - */ -var BetweenPointsY = function (point1, point2) -{ - return Math.atan2(point2.x - point1.x, point2.y - point1.y); -}; + shader.set3fv(name, arr); -module.exports = BetweenPointsY; + return this; + }, + /** + * Sets a 4fv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set4fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set4fv: function (name, arr, shader) + { + if (shader === undefined) { shader = this.currentShader; } -/***/ }), -/* 814 */ -/***/ (function(module, exports) { + shader.set4fv(name, arr); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * Find the angle of a segment from (x1, y1) -> (x2, y2). - * - * The difference between this method and {@link Phaser.Math.Angle.Between} is that this assumes the y coordinate - * travels down the screen. - * - * @function Phaser.Math.Angle.BetweenY - * @since 3.0.0 - * - * @param {number} x1 - The x coordinate of the first point. - * @param {number} y1 - The y coordinate of the first point. - * @param {number} x2 - The x coordinate of the second point. - * @param {number} y2 - The y coordinate of the second point. - * - * @return {number} The angle in radians. - */ -var BetweenY = function (x1, y1, x2, y2) -{ - return Math.atan2(x2 - x1, y2 - y1); -}; + /** + * Sets a 1iv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set1iv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set1iv: function (name, arr, shader) + { + if (shader === undefined) { shader = this.currentShader; } -module.exports = BetweenY; + shader.set1iv(name, arr); + return this; + }, -/***/ }), -/* 815 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Sets a 2iv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set2iv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set2iv: function (name, arr, shader) + { + if (shader === undefined) { shader = this.currentShader; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + shader.set2iv(name, arr); -var CONST = __webpack_require__(14); + return this; + }, -/** - * Takes an angle in Phasers default clockwise format and converts it so that - * 0 is North, 90 is West, 180 is South and 270 is East, - * therefore running counter-clockwise instead of clockwise. - * - * You can pass in the angle from a Game Object using: - * - * ```javascript - * var converted = CounterClockwise(gameobject.rotation); - * ``` - * - * All values for this function are in radians. - * - * @function Phaser.Math.Angle.CounterClockwise - * @since 3.16.0 - * - * @param {number} angle - The angle to convert, in radians. - * - * @return {number} The converted angle, in radians. - */ -var CounterClockwise = function (angle) -{ - if (angle > Math.PI) + /** + * Sets a 3iv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set3iv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set3iv: function (name, arr, shader) { - angle -= CONST.PI2; - } + if (shader === undefined) { shader = this.currentShader; } - return Math.abs((((angle + CONST.TAU) % CONST.PI2) - CONST.PI2) % CONST.PI2); -}; + shader.set3iv(name, arr); -module.exports = CounterClockwise; + return this; + }, + + /** + * Sets a 4iv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set4iv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set4iv: function (name, arr, shader) + { + if (shader === undefined) { shader = this.currentShader; } + shader.set4iv(name, arr); -/***/ }), -/* 816 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @author @samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Sets a 1i uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set1i + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new value of the `int` uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set1i: function (name, x, shader) + { + if (shader === undefined) { shader = this.currentShader; } -var FloatBetween = __webpack_require__(137); + shader.set1i(name, x); -/** - * Returns a random angle in the range [-pi, pi]. - * - * @function Phaser.Math.Angle.Random - * @since 3.23.0 - * - * @return {number} The angle, in radians. - */ -var Random = function () -{ - return FloatBetween(-Math.PI, Math.PI); -}; + return this; + }, -module.exports = Random; + /** + * Sets a 2i uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set2i + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new X component of the `ivec2` uniform. + * @param {number} y - The new Y component of the `ivec2` uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set2i: function (name, x, y, shader) + { + if (shader === undefined) { shader = this.currentShader; } + shader.set2i(name, x, y); -/***/ }), -/* 817 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @author @samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Sets a 3i uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set3i + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new X component of the `ivec3` uniform. + * @param {number} y - The new Y component of the `ivec3` uniform. + * @param {number} z - The new Z component of the `ivec3` uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set3i: function (name, x, y, z, shader) + { + if (shader === undefined) { shader = this.currentShader; } -var FloatBetween = __webpack_require__(137); + shader.set3i(name, x, y, z); -/** - * Returns a random angle in the range [-180, 180]. - * - * @function Phaser.Math.Angle.RandomDegrees - * @since 3.23.0 - * - * @return {number} The angle, in degrees. - */ -var RandomDegrees = function () -{ - return FloatBetween(-180, 180); -}; + return this; + }, -module.exports = RandomDegrees; + /** + * Sets a 4i uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#set4i + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - X component of the uniform. + * @param {number} y - Y component of the uniform. + * @param {number} z - Z component of the uniform. + * @param {number} w - W component of the uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + set4i: function (name, x, y, z, w, shader) + { + if (shader === undefined) { shader = this.currentShader; } + shader.set4i(name, x, y, z, w); -/***/ }), -/* 818 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Sets a matrix 2fv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix2fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {boolean} transpose - Whether to transpose the matrix. Should be `false`. + * @param {number[]|Float32Array} matrix - The new values for the `mat2` uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + setMatrix2fv: function (name, transpose, matrix, shader) + { + if (shader === undefined) { shader = this.currentShader; } -var Normalize = __webpack_require__(351); + shader.setMatrix2fv(name, transpose, matrix); -/** - * Reverse the given angle. - * - * @function Phaser.Math.Angle.Reverse - * @since 3.0.0 - * - * @param {number} angle - The angle to reverse, in radians. - * - * @return {number} The reversed angle, in radians. - */ -var Reverse = function (angle) -{ - return Normalize(angle + Math.PI); -}; + return this; + }, -module.exports = Reverse; + /** + * Sets a matrix 3fv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix3fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {boolean} transpose - Whether to transpose the matrix. Should be `false`. + * @param {Float32Array} matrix - The new values for the `mat3` uniform. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + setMatrix3fv: function (name, transpose, matrix, shader) + { + if (shader === undefined) { shader = this.currentShader; } + shader.setMatrix3fv(name, transpose, matrix); -/***/ }), -/* 819 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Sets a matrix 4fv uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix4fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {boolean} transpose - Whether to transpose the matrix. Should be `false`. + * @param {Float32Array} matrix - The matrix data. If using a Matrix4 this should be the `Matrix4.val` property. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used. + * + * @return {this} This WebGLPipeline instance. + */ + setMatrix4fv: function (name, transpose, matrix, shader) + { + if (shader === undefined) { shader = this.currentShader; } -var MATH_CONST = __webpack_require__(14); + shader.setMatrix4fv(name, transpose, matrix); -/** - * Rotates `currentAngle` towards `targetAngle`, taking the shortest rotation distance. The `lerp` argument is the amount to rotate by in this call. - * - * @function Phaser.Math.Angle.RotateTo - * @since 3.0.0 - * - * @param {number} currentAngle - The current angle, in radians. - * @param {number} targetAngle - The target angle to rotate to, in radians. - * @param {number} [lerp=0.05] - The lerp value to add to the current angle. - * - * @return {number} The adjusted angle. - */ -var RotateTo = function (currentAngle, targetAngle, lerp) -{ - if (lerp === undefined) { lerp = 0.05; } + return this; + }, - if (currentAngle === targetAngle) + /** + * Destroys all shader instances, removes all object references and nulls all external references. + * + * @method Phaser.Renderer.WebGL.WebGLPipeline#destroy + * @fires Phaser.Renderer.WebGL.Pipelines.Events#DESTROY + * @since 3.0.0 + * + * @return {this} This WebGLPipeline instance. + */ + destroy: function () { - return currentAngle; - } + this.emit(Events.DESTROY, this); - if (Math.abs(targetAngle - currentAngle) <= lerp || Math.abs(targetAngle - currentAngle) >= (MATH_CONST.PI2 - lerp)) - { - currentAngle = targetAngle; - } - else - { - if (Math.abs(targetAngle - currentAngle) > Math.PI) - { - if (targetAngle < currentAngle) - { - targetAngle += MATH_CONST.PI2; - } - else - { - targetAngle -= MATH_CONST.PI2; - } - } + var i; - if (targetAngle > currentAngle) + var shaders = this.shaders; + + for (i = 0; i < shaders.length; i++) { - currentAngle += lerp; + shaders[i].destroy(); } - else if (targetAngle < currentAngle) + + var targets = this.renderTargets; + + for (i = 0; i < targets.length; i++) { - currentAngle -= lerp; + targets[i].destroy(); } - } - - return currentAngle; -}; -module.exports = RotateTo; + this.gl.deleteBuffer(this.vertexBuffer); + var renderer = this.renderer; -/***/ }), -/* 820 */ -/***/ (function(module, exports) { + renderer.off(RendererEvents.RESIZE, this.resize, this); + renderer.off(RendererEvents.PRE_RENDER, this.onPreRender, this); + renderer.off(RendererEvents.RENDER, this.onRender, this); + renderer.off(RendererEvents.POST_RENDER, this.onPostRender, this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.removeAllListeners(); -/** - * Gets the shortest angle between `angle1` and `angle2`. - * - * Both angles must be in the range -180 to 180, which is the same clamped - * range that `sprite.angle` uses, so you can pass in two sprite angles to - * this method and get the shortest angle back between the two of them. - * - * The angle returned will be in the same range. If the returned angle is - * greater than 0 then it's a counter-clockwise rotation, if < 0 then it's - * a clockwise rotation. - * - * @function Phaser.Math.Angle.ShortestBetween - * @since 3.0.0 - * - * @param {number} angle1 - The first angle in the range -180 to 180. - * @param {number} angle2 - The second angle in the range -180 to 180. - * - * @return {number} The shortest angle, in degrees. If greater than zero it's a counter-clockwise rotation. - */ -var ShortestBetween = function (angle1, angle2) -{ - var difference = angle2 - angle1; + this.game = null; + this.renderer = null; + this.manager = null; + this.gl = null; + this.view = null; + this.shaders = null; + this.renderTargets = null; + this.bytes = null; + this.vertexViewF32 = null; + this.vertexViewU32 = null; + this.vertexData = null; + this.vertexBuffer = null; + this.currentShader = null; + this.currentRenderTarget = null; + this.activeTextures = null; - if (difference === 0) - { - return 0; + return this; } - var times = Math.floor((difference - (-180)) / 360); - - return difference - (times * 360); - -}; +}); -module.exports = ShortestBetween; +module.exports = WebGLPipeline; /***/ }), -/* 821 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 11857: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @namespace Phaser.Math.Distance - */ - -module.exports = { - - Between: __webpack_require__(50), - BetweenPoints: __webpack_require__(352), - BetweenPointsSquared: __webpack_require__(822), - Chebyshev: __webpack_require__(823), - Power: __webpack_require__(824), - Snake: __webpack_require__(825), - Squared: __webpack_require__(353) - -}; +var ArrayRemove = __webpack_require__(66458); +var CameraEvents = __webpack_require__(89787); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(86459); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(81044); +var IsSizePowerOfTwo = __webpack_require__(28621); +var Matrix4 = __webpack_require__(16650); +var NOOP = __webpack_require__(72283); +var PipelineManager = __webpack_require__(35217); +var RenderTarget = __webpack_require__(37410); +var ScaleEvents = __webpack_require__(40444); +var TextureEvents = __webpack_require__(38203); +var Utils = __webpack_require__(75512); +var WebGLSnapshot = __webpack_require__(1217); +var DEBUG = false; -/***/ }), -/* 822 */ -/***/ (function(module, exports) { +if (false) +{ var SPECTOR; } /** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @callback WebGLContextCallback + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer which owns the context. */ /** - * Calculate the squared distance between two points. - * - * @function Phaser.Math.Distance.BetweenPointsSquared - * @since 3.22.0 + * @classdesc + * WebGLRenderer is a class that contains the needed functionality to keep the + * WebGLRenderingContext state clean. The main idea of the WebGLRenderer is to keep track of + * any context change that happens for WebGL rendering inside of Phaser. This means + * if raw webgl functions are called outside the WebGLRenderer of the Phaser WebGL + * rendering ecosystem they might pollute the current WebGLRenderingContext state producing + * unexpected behavior. It's recommended that WebGL interaction is done through + * WebGLRenderer and/or WebGLPipeline. * - * @param {Phaser.Types.Math.Vector2Like} a - The first point. - * @param {Phaser.Types.Math.Vector2Like} b - The second point. + * @class WebGLRenderer + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Renderer.WebGL + * @constructor + * @since 3.0.0 * - * @return {number} The squared distance between the points. + * @param {Phaser.Game} game - The Game instance which owns this WebGL Renderer. */ -var DistanceBetweenPointsSquared = function (a, b) -{ - var dx = a.x - b.x; - var dy = a.y - b.y; +var WebGLRenderer = new Class({ - return dx * dx + dy * dy; -}; + Extends: EventEmitter, -module.exports = DistanceBetweenPointsSquared; + initialize: + function WebGLRenderer (game) + { + EventEmitter.call(this); -/***/ }), -/* 823 */ -/***/ (function(module, exports) { + var gameConfig = game.config; -/** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var contextCreationConfig = { + alpha: gameConfig.transparent, + desynchronized: gameConfig.desynchronized, + depth: true, + antialias: gameConfig.antialiasGL, + premultipliedAlpha: gameConfig.premultipliedAlpha, + stencil: true, + failIfMajorPerformanceCaveat: gameConfig.failIfMajorPerformanceCaveat, + powerPreference: gameConfig.powerPreference, + preserveDrawingBuffer: gameConfig.preserveDrawingBuffer, + willReadFrequently: false + }; -/** - * Calculate the Chebyshev distance between two sets of coordinates (points). - * - * Chebyshev distance (or chessboard distance) is the maximum of the horizontal and vertical distances. - * It's the effective distance when movement can be horizontal, vertical, or diagonal. - * - * @function Phaser.Math.Distance.Chebyshev - * @since 3.22.0 - * - * @param {number} x1 - The x coordinate of the first point. - * @param {number} y1 - The y coordinate of the first point. - * @param {number} x2 - The x coordinate of the second point. - * @param {number} y2 - The y coordinate of the second point. - * - * @return {number} The distance between each point. - */ -var ChebyshevDistance = function (x1, y1, x2, y2) -{ - return Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)); -}; + /** + * The local configuration settings of this WebGL Renderer. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#config + * @type {object} + * @since 3.0.0 + */ + this.config = { + clearBeforeRender: gameConfig.clearBeforeRender, + antialias: gameConfig.antialias, + backgroundColor: gameConfig.backgroundColor, + contextCreation: contextCreationConfig, + roundPixels: gameConfig.roundPixels, + maxTextures: gameConfig.maxTextures, + maxTextureSize: gameConfig.maxTextureSize, + batchSize: gameConfig.batchSize, + maxLights: gameConfig.maxLights, + mipmapFilter: gameConfig.mipmapFilter + }; -module.exports = ChebyshevDistance; + /** + * The Game instance which owns this WebGL Renderer. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game = game; + /** + * A constant which allows the renderer to be easily identified as a WebGL Renderer. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#type + * @type {number} + * @since 3.0.0 + */ + this.type = CONST.WEBGL; -/***/ }), -/* 824 */ -/***/ (function(module, exports) { + /** + * An instance of the Pipeline Manager class, that handles all WebGL Pipelines. + * + * Use this to manage all of your interactions with pipelines, such as adding, getting, + * setting and rendering them. + * + * The Pipeline Manager class is created in the `init` method and then populated + * with pipelines during the `boot` method. + * + * Prior to Phaser v3.50.0 this was just a plain JavaScript object, not a class. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#pipelines + * @type {Phaser.Renderer.WebGL.PipelineManager} + * @since 3.50.0 + */ + this.pipelines = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The width of the canvas being rendered to. + * This is populated in the onResize event handler. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#width + * @type {number} + * @since 3.0.0 + */ + this.width = 0; -/** - * Calculate the distance between two sets of coordinates (points) to the power of `pow`. - * - * @function Phaser.Math.Distance.Power - * @since 3.0.0 - * - * @param {number} x1 - The x coordinate of the first point. - * @param {number} y1 - The y coordinate of the first point. - * @param {number} x2 - The x coordinate of the second point. - * @param {number} y2 - The y coordinate of the second point. - * @param {number} pow - The exponent. - * - * @return {number} The distance between each point. - */ -var DistancePower = function (x1, y1, x2, y2, pow) -{ - if (pow === undefined) { pow = 2; } + /** + * The height of the canvas being rendered to. + * This is populated in the onResize event handler. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#height + * @type {number} + * @since 3.0.0 + */ + this.height = 0; - return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow)); -}; + /** + * The canvas which this WebGL Renderer draws to. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#canvas + * @type {HTMLCanvasElement} + * @since 3.0.0 + */ + this.canvas = game.canvas; + + /** + * An array of blend modes supported by the WebGL Renderer. + * + * This array includes the default blend modes as well as any custom blend modes added through {@link #addBlendMode}. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#blendModes + * @type {array} + * @default [] + * @since 3.0.0 + */ + this.blendModes = []; -module.exports = DistancePower; + /** + * This property is set to `true` if the WebGL context of the renderer is lost. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#contextLost + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.contextLost = false; + /** + * Details about the currently scheduled snapshot. + * + * If a non-null `callback` is set in this object, a snapshot of the canvas will be taken after the current frame is fully rendered. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#snapshotState + * @type {Phaser.Types.Renderer.Snapshot.SnapshotState} + * @since 3.0.0 + */ + this.snapshotState = { + x: 0, + y: 0, + width: 1, + height: 1, + getPixel: false, + callback: null, + type: 'image/png', + encoder: 0.92, + isFramebuffer: false, + bufferWidth: 0, + bufferHeight: 0 + }; -/***/ }), -/* 825 */ -/***/ (function(module, exports) { + /** + * The maximum number of textures the GPU can handle. The minimum under the WebGL1 spec is 8. + * This is set via the Game Config `maxTextures` property and should never be changed after boot. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#maxTextures + * @type {number} + * @since 3.50.0 + */ + this.maxTextures = 0; -/** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * An array of the available WebGL texture units, used to populate the uSampler uniforms. + * + * This array is populated during the init phase and should never be changed after boot. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#textureIndexes + * @type {array} + * @since 3.50.0 + */ + this.textureIndexes; -/** - * Calculate the snake distance between two sets of coordinates (points). - * - * Snake distance (rectilinear distance, Manhattan distance) is the sum of the horizontal and vertical distances. - * It's the effective distance when movement is allowed only horizontally or vertically (but not both). - * - * @function Phaser.Math.Distance.Snake - * @since 3.22.0 - * - * @param {number} x1 - The x coordinate of the first point. - * @param {number} y1 - The y coordinate of the first point. - * @param {number} x2 - The x coordinate of the second point. - * @param {number} y2 - The y coordinate of the second point. - * - * @return {number} The distance between each point. - */ -var SnakeDistance = function (x1, y1, x2, y2) -{ - return Math.abs(x1 - x2) + Math.abs(y1 - y2); -}; + /** + * The currently bound framebuffer in use. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentFramebuffer + * @type {WebGLFramebuffer} + * @default null + * @since 3.0.0 + */ + this.currentFramebuffer = null; -module.exports = SnakeDistance; + /** + * A stack into which the frame buffer objects are pushed and popped. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#fboStack + * @type {WebGLFramebuffer[]} + * @since 3.50.0 + */ + this.fboStack = []; + /** + * Current WebGLProgram in use. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentProgram + * @type {WebGLProgram} + * @default null + * @since 3.0.0 + */ + this.currentProgram = null; -/***/ }), -/* 826 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Current blend mode in use + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentBlendMode + * @type {number} + * @since 3.0.0 + */ + this.currentBlendMode = Infinity; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Indicates if the the scissor state is enabled in WebGLRenderingContext + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentScissorEnabled + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.currentScissorEnabled = false; -/** - * @namespace Phaser.Math.Easing - */ + /** + * Stores the current scissor data + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentScissor + * @type {Uint32Array} + * @since 3.0.0 + */ + this.currentScissor = null; -module.exports = { + /** + * Stack of scissor data + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#scissorStack + * @type {Uint32Array} + * @since 3.0.0 + */ + this.scissorStack = []; - Back: __webpack_require__(334), - Bounce: __webpack_require__(335), - Circular: __webpack_require__(336), - Cubic: __webpack_require__(337), - Elastic: __webpack_require__(338), - Expo: __webpack_require__(339), - Linear: __webpack_require__(340), - Quadratic: __webpack_require__(341), - Quartic: __webpack_require__(342), - Quintic: __webpack_require__(343), - Sine: __webpack_require__(344), - Stepped: __webpack_require__(345) + /** + * The handler to invoke when the context is lost. + * This should not be changed and is set in the boot method. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#contextLostHandler + * @type {function} + * @since 3.19.0 + */ + this.contextLostHandler = NOOP; -}; + /** + * The handler to invoke when the context is restored. + * This should not be changed and is set in the boot method. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#contextRestoredHandler + * @type {function} + * @since 3.19.0 + */ + this.contextRestoredHandler = NOOP; + /** + * The underlying WebGL context of the renderer. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#gl + * @type {WebGLRenderingContext} + * @default null + * @since 3.0.0 + */ + this.gl = null; -/***/ }), -/* 827 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Array of strings that indicate which WebGL extensions are supported by the browser. + * This is populated in the `boot` method. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#supportedExtensions + * @type {string[]} + * @default null + * @since 3.0.0 + */ + this.supportedExtensions = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * If the browser supports the `ANGLE_instanced_arrays` extension, this property will hold + * a reference to the glExtension for it. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#instancedArraysExtension + * @type {ANGLE_instanced_arrays} + * @default null + * @since 3.50.0 + */ + this.instancedArraysExtension = null; -/** - * @namespace Phaser.Math.Fuzzy - */ + /** + * If the browser supports the `OES_vertex_array_object` extension, this property will hold + * a reference to the glExtension for it. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#vaoExtension + * @type {OES_vertex_array_object} + * @default null + * @since 3.50.0 + */ + this.vaoExtension = null; -module.exports = { + /** + * The WebGL Extensions loaded into the current context. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#extensions + * @type {object} + * @default {} + * @since 3.0.0 + */ + this.extensions = {}; - Ceil: __webpack_require__(828), - Equal: __webpack_require__(124), - Floor: __webpack_require__(829), - GreaterThan: __webpack_require__(354), - LessThan: __webpack_require__(355) + /** + * Stores the current WebGL component formats for further use. + * + * This array is populated in the `init` method. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#glFormats + * @type {array} + * @since 3.2.0 + */ + this.glFormats; -}; + /** + * Stores the WebGL texture compression formats that this device and browser supports. + * + * Support for using compressed texture formats was added in Phaser version 3.60. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#compression + * @type {Phaser.Types.Renderer.WebGL.WebGLTextureCompression} + * @since 3.8.0 + */ + this.compression; + /** + * Cached drawing buffer height to reduce gl calls. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#drawingBufferHeight + * @type {number} + * @readonly + * @since 3.11.0 + */ + this.drawingBufferHeight = 0; -/***/ }), -/* 828 */ -/***/ (function(module, exports) { + /** + * A blank 32x32 transparent texture, as used by the Graphics system where needed. + * This is set in the `boot` method. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#blankTexture + * @type {WebGLTexture} + * @readonly + * @since 3.12.0 + */ + this.blankTexture = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * A pure white 4x4 texture, as used by the Graphics system where needed. + * This is set in the `boot` method. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#whiteTexture + * @type {WebGLTexture} + * @readonly + * @since 3.50.0 + */ + this.whiteTexture = null; -/** - * Calculate the fuzzy ceiling of the given value. - * - * @function Phaser.Math.Fuzzy.Ceil - * @since 3.0.0 - * - * @param {number} value - The value. - * @param {number} [epsilon=0.0001] - The epsilon. - * - * @return {number} The fuzzy ceiling of the value. - */ -var Ceil = function (value, epsilon) -{ - if (epsilon === undefined) { epsilon = 0.0001; } + /** + * The total number of masks currently stacked. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#maskCount + * @type {number} + * @since 3.17.0 + */ + this.maskCount = 0; - return Math.ceil(value - epsilon); -}; + /** + * The mask stack. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#maskStack + * @type {Phaser.Display.Masks.GeometryMask[]} + * @since 3.17.0 + */ + this.maskStack = []; -module.exports = Ceil; + /** + * Internal property that tracks the currently set mask. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentMask + * @type {any} + * @since 3.17.0 + */ + this.currentMask = { mask: null, camera: null }; + /** + * Internal property that tracks the currently set camera mask. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentCameraMask + * @type {any} + * @since 3.17.0 + */ + this.currentCameraMask = { mask: null, camera: null }; -/***/ }), -/* 829 */ -/***/ (function(module, exports) { + /** + * Internal gl function mapping for uniform look-up. + * https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniform + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#glFuncMap + * @type {any} + * @since 3.17.0 + */ + this.glFuncMap = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The `type` of the Game Object being currently rendered. + * This can be used by advanced render functions for batching look-ahead. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentType + * @type {string} + * @since 3.19.0 + */ + this.currentType = ''; -/** - * Calculate the fuzzy floor of the given value. - * - * @function Phaser.Math.Fuzzy.Floor - * @since 3.0.0 - * - * @param {number} value - The value. - * @param {number} [epsilon=0.0001] - The epsilon. - * - * @return {number} The floor of the value. - */ -var Floor = function (value, epsilon) -{ - if (epsilon === undefined) { epsilon = 0.0001; } + /** + * Is the `type` of the Game Object being currently rendered different than the + * type of the object before it in the display list? I.e. it's a 'new' type. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#newType + * @type {boolean} + * @since 3.19.0 + */ + this.newType = false; - return Math.floor(value + epsilon); -}; + /** + * Does the `type` of the next Game Object in the display list match that + * of the object being currently rendered? + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#nextTypeMatch + * @type {boolean} + * @since 3.19.0 + */ + this.nextTypeMatch = false; -module.exports = Floor; + /** + * Is the Game Object being currently rendered the final one in the list? + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#finalType + * @type {boolean} + * @since 3.50.0 + */ + this.finalType = false; + /** + * The mipmap magFilter to be used when creating textures. + * + * You can specify this as a string in the game config, i.e.: + * + * `render: { mipmapFilter: 'NEAREST_MIPMAP_LINEAR' }` + * + * The 6 options for WebGL1 are, in order from least to most computationally expensive: + * + * NEAREST (for pixel art) + * LINEAR (the default) + * NEAREST_MIPMAP_NEAREST + * LINEAR_MIPMAP_NEAREST + * NEAREST_MIPMAP_LINEAR + * LINEAR_MIPMAP_LINEAR + * + * Mipmaps only work with textures that are fully power-of-two in size. + * + * For more details see https://webglfundamentals.org/webgl/lessons/webgl-3d-textures.html + * + * As of v3.60 no mipmaps will be generated unless a string is given in + * the game config. This saves on VRAM use when it may not be required. + * To obtain the previous result set the property to `LINEAR` in the config. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#mipmapFilter + * @type {GLenum} + * @since 3.21.0 + */ + this.mipmapFilter = null; -/***/ }), -/* 830 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The default scissor, set during `preRender` and modified during `resize`. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#defaultScissor + * @type {number[]} + * @private + * @since 3.50.0 + */ + this.defaultScissor = [ 0, 0, 0, 0 ]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Has this renderer fully booted yet? + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#isBooted + * @type {boolean} + * @since 3.50.0 + */ + this.isBooted = false; -/** - * @namespace Phaser.Math.Interpolation - */ + /** + * A Render Target you can use to capture the current state of the Renderer. + * + * A Render Target encapsulates a framebuffer and texture for the WebGL Renderer. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#renderTarget + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.50.0 + */ + this.renderTarget = null; -module.exports = { + /** + * The global game Projection matrix, used by shaders as 'uProjectionMatrix' uniform. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#projectionMatrix + * @type {Phaser.Math.Matrix4} + * @since 3.50.0 + */ + this.projectionMatrix; - Bezier: __webpack_require__(831), - CatmullRom: __webpack_require__(832), - CubicBezier: __webpack_require__(358), - Linear: __webpack_require__(833), - QuadraticBezier: __webpack_require__(359), - SmoothStep: __webpack_require__(360), - SmootherStep: __webpack_require__(834) + /** + * The cached width of the Projection matrix. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#projectionWidth + * @type {number} + * @since 3.50.0 + */ + this.projectionWidth = 0; -}; + /** + * The cached height of the Projection matrix. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#projectionHeight + * @type {number} + * @since 3.50.0 + */ + this.projectionHeight = 0; + /** + * A RenderTarget used by the BitmapMask Pipeline. + * + * This is the source, i.e. the masked Game Object itself. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#maskSource + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.60.0 + */ + this.maskSource = null; -/***/ }), -/* 831 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * A RenderTarget used by the BitmapMask Pipeline. + * + * This is the target, i.e. the framebuffer the masked objects are drawn to. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#maskTarget + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.60.0 + */ + this.maskTarget = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * An instance of SpectorJS used for WebGL Debugging. + * + * Only available in the Phaser Debug build. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#spector + * @type {function} + * @since 3.60.0 + */ + this.spector = null; -var Bernstein = __webpack_require__(356); + /** + * Is Spector currently capturing a WebGL frame? + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#_debugCapture + * @type {boolean} + * @private + * @since 3.60.0 + */ + this._debugCapture = false; -/** - * A bezier interpolation method. - * - * @function Phaser.Math.Interpolation.Bezier - * @since 3.0.0 - * - * @param {number[]} v - The input array of values to interpolate between. - * @param {number} k - The percentage of interpolation, between 0 and 1. - * - * @return {number} The interpolated value. - */ -var BezierInterpolation = function (v, k) -{ - var b = 0; - var n = v.length - 1; + this.init(this.config); + }, - for (var i = 0; i <= n; i++) + /** + * Creates a new WebGLRenderingContext and initializes all internal state. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#init + * @since 3.0.0 + * + * @param {object} config - The configuration object for the renderer. + * + * @return {this} This WebGLRenderer instance. + */ + init: function (config) { - b += Math.pow(1 - k, n - i) * Math.pow(k, i) * v[i] * Bernstein(n, i); - } + var gl; + var game = this.game; + var canvas = this.canvas; + var clearColor = config.backgroundColor; - return b; -}; + if (DEBUG) + { + this.spector = new SPECTOR.Spector(); -module.exports = BezierInterpolation; + this.spector.onCapture.add(this.onCapture.bind(this)); + } + // Did they provide their own context? + if (game.config.context) + { + gl = game.config.context; + } + else + { + gl = canvas.getContext('webgl', config.contextCreation) || canvas.getContext('experimental-webgl', config.contextCreation); + } -/***/ }), -/* 832 */ -/***/ (function(module, exports, __webpack_require__) { + if (!gl || gl.isContextLost()) + { + this.contextLost = true; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + throw new Error('WebGL unsupported'); + } -var CatmullRom = __webpack_require__(194); + this.gl = gl; -/** - * A Catmull-Rom interpolation method. - * - * @function Phaser.Math.Interpolation.CatmullRom - * @since 3.0.0 - * - * @param {number[]} v - The input array of values to interpolate between. - * @param {number} k - The percentage of interpolation, between 0 and 1. - * - * @return {number} The interpolated value. - */ -var CatmullRomInterpolation = function (v, k) -{ - var m = v.length - 1; - var f = m * k; - var i = Math.floor(f); + var _this = this; - if (v[0] === v[m]) - { - if (k < 0) + this.contextLostHandler = function (event) { - i = Math.floor(f = m * (1 + k)); - } + _this.contextLost = true; - return CatmullRom(f - i, v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m]); - } - else - { - if (k < 0) - { - return v[0] - (CatmullRom(-f, v[0], v[0], v[1], v[1]) - v[0]); - } + if (console) + { + console.warn('WebGL Context lost. Renderer disabled'); + } - if (k > 1) + event.preventDefault(); + }; + + canvas.addEventListener('webglcontextlost', this.contextLostHandler, false); + + // Set it back into the Game, so developers can access it from there too + game.context = gl; + + for (var i = 0; i <= 27; i++) { - return v[m] - (CatmullRom(f - m, v[m], v[m], v[m - 1], v[m - 1]) - v[m]); + this.blendModes.push({ func: [ gl.ONE, gl.ONE_MINUS_SRC_ALPHA ], equation: gl.FUNC_ADD }); } - return CatmullRom(f - i, v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2]); - } -}; - -module.exports = CatmullRomInterpolation; + // ADD + this.blendModes[1].func = [ gl.ONE, gl.DST_ALPHA ]; + // MULTIPLY + this.blendModes[2].func = [ gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA ]; -/***/ }), -/* 833 */ -/***/ (function(module, exports, __webpack_require__) { + // SCREEN + this.blendModes[3].func = [ gl.ONE, gl.ONE_MINUS_SRC_COLOR ]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // ERASE + this.blendModes[17] = { func: [ gl.ZERO, gl.ONE_MINUS_SRC_ALPHA ], equation: gl.FUNC_REVERSE_SUBTRACT }; -var Linear = __webpack_require__(135); + this.glFormats = [ gl.BYTE, gl.SHORT, gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT, gl.FLOAT ]; -/** - * A linear interpolation method. - * - * @function Phaser.Math.Interpolation.Linear - * @since 3.0.0 - * @see {@link https://en.wikipedia.org/wiki/Linear_interpolation} - * - * @param {number[]} v - The input array of values to interpolate between. - * @param {!number} k - The percentage of interpolation, between 0 and 1. - * - * @return {!number} The interpolated value. - */ -var LinearInterpolation = function (v, k) -{ - var m = v.length - 1; - var f = m * k; - var i = Math.floor(f); + // Set the gl function map + this.glFuncMap = { - if (k < 0) - { - return Linear(v[0], v[1], f); - } - else if (k > 1) - { - return Linear(v[m], v[m - 1], m - f); - } - else - { - return Linear(v[i], v[(i + 1 > m) ? m : i + 1], f - i); - } -}; + mat2: { func: gl.uniformMatrix2fv, length: 1, matrix: true }, + mat3: { func: gl.uniformMatrix3fv, length: 1, matrix: true }, + mat4: { func: gl.uniformMatrix4fv, length: 1, matrix: true }, -module.exports = LinearInterpolation; + '1f': { func: gl.uniform1f, length: 1 }, + '1fv': { func: gl.uniform1fv, length: 1 }, + '1i': { func: gl.uniform1i, length: 1 }, + '1iv': { func: gl.uniform1iv, length: 1 }, + '2f': { func: gl.uniform2f, length: 2 }, + '2fv': { func: gl.uniform2fv, length: 1 }, + '2i': { func: gl.uniform2i, length: 2 }, + '2iv': { func: gl.uniform2iv, length: 1 }, -/***/ }), -/* 834 */ -/***/ (function(module, exports, __webpack_require__) { + '3f': { func: gl.uniform3f, length: 3 }, + '3fv': { func: gl.uniform3fv, length: 1 }, + '3i': { func: gl.uniform3i, length: 3 }, + '3iv': { func: gl.uniform3iv, length: 1 }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + '4f': { func: gl.uniform4f, length: 4 }, + '4fv': { func: gl.uniform4fv, length: 1 }, + '4i': { func: gl.uniform4i, length: 4 }, + '4iv': { func: gl.uniform4iv, length: 1 } -var SmootherStep = __webpack_require__(183); + }; -/** - * A Smoother Step interpolation method. - * - * @function Phaser.Math.Interpolation.SmootherStep - * @since 3.9.0 - * @see {@link https://en.wikipedia.org/wiki/Smoothstep#Variations} - * - * @param {number} t - The percentage of interpolation, between 0 and 1. - * @param {number} min - The minimum value, also known as the 'left edge', assumed smaller than the 'right edge'. - * @param {number} max - The maximum value, also known as the 'right edge', assumed greater than the 'left edge'. - * - * @return {number} The interpolated value. - */ -var SmootherStepInterpolation = function (t, min, max) -{ - return min + (max - min) * SmootherStep(t, 0, 1); -}; + // Load supported extensions + var exts = gl.getSupportedExtensions(); -module.exports = SmootherStepInterpolation; + if (!config.maxTextures || config.maxTextures === -1) + { + config.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + } + if (!config.maxTextureSize) + { + config.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + } -/***/ }), -/* 835 */ -/***/ (function(module, exports, __webpack_require__) { + this.compression = this.getCompressedTextures(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.supportedExtensions = exts; -/** - * @namespace Phaser.Math.Pow2 - */ + var angleString = 'ANGLE_instanced_arrays'; -module.exports = { + this.instancedArraysExtension = (exts.indexOf(angleString) > -1) ? gl.getExtension(angleString) : null; - GetNext: __webpack_require__(361), - IsSize: __webpack_require__(138), - IsValue: __webpack_require__(836) + var vaoString = 'OES_vertex_array_object'; -}; + this.vaoExtension = (exts.indexOf(vaoString) > -1) ? gl.getExtension(vaoString) : null; + // Setup initial WebGL state + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.CULL_FACE); -/***/ }), -/* 836 */ -/***/ (function(module, exports) { + gl.enable(gl.BLEND); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.clearColor(clearColor.redGL, clearColor.greenGL, clearColor.blueGL, clearColor.alphaGL); -/** - * Tests the value and returns `true` if it is a power of two. - * - * @function Phaser.Math.Pow2.IsValue - * @since 3.0.0 - * - * @param {number} value - The value to check if it's a power of two. - * - * @return {boolean} Returns `true` if `value` is a power of two, otherwise `false`. - */ -var IsValuePowerOfTwo = function (value) -{ - return (value > 0 && (value & (value - 1)) === 0); -}; + // Mipmaps + if (config.mipmapFilter !== '') + { + this.mipmapFilter = gl[config.mipmapFilter]; + } -module.exports = IsValuePowerOfTwo; + // Check maximum supported textures + this.maxTextures = Utils.checkShaderMax(gl, config.maxTextures); + this.textureIndexes = []; -/***/ }), -/* 837 */ -/***/ (function(module, exports, __webpack_require__) { + // Create temporary WebGL textures to stop WebGL errors on mac os + for (var index = 0; index < this.maxTextures; index++) + { + var tempTexture = gl.createTexture(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.activeTexture(gl.TEXTURE0 + index); -/** - * @namespace Phaser.Math.Snap - */ + gl.bindTexture(gl.TEXTURE_2D, tempTexture); -module.exports = { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([ 0, 0, 255, 255 ])); - Ceil: __webpack_require__(139), - Floor: __webpack_require__(76), - To: __webpack_require__(838) + this.textureIndexes.push(index); + } -}; + this.pipelines = new PipelineManager(this); + this.setBlendMode(CONST.BlendModes.NORMAL); -/***/ }), -/* 838 */ -/***/ (function(module, exports) { + this.projectionMatrix = new Matrix4().identity(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + game.textures.once(TextureEvents.READY, this.boot, this); -/** - * Snap a value to nearest grid slice, using rounding. - * - * Example: if you have an interval gap of `5` and a position of `12`... you will snap to `10` whereas `14` will snap to `15`. - * - * @function Phaser.Math.Snap.To - * @since 3.0.0 - * - * @param {number} value - The value to snap. - * @param {number} gap - The interval gap of the grid. - * @param {number} [start=0] - Optional starting offset for gap. - * @param {boolean} [divide=false] - If `true` it will divide the snapped value by the gap before returning. - * - * @return {number} The snapped value. - */ -var SnapTo = function (value, gap, start, divide) -{ - if (start === undefined) { start = 0; } + return this; + }, - if (gap === 0) + /** + * Internal boot handler. Calls 'boot' on each pipeline. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#boot + * @private + * @since 3.11.0 + */ + boot: function () { - return value; - } + var game = this.game; + var pipelineManager = this.pipelines; - value -= start; - value = gap * Math.round(value / gap); + var baseSize = game.scale.baseSize; - return (divide) ? (start + value) / gap : start + value; -}; + var width = baseSize.width; + var height = baseSize.height; -module.exports = SnapTo; + this.width = width; + this.height = height; + this.isBooted = true; -/***/ }), -/* 839 */ -/***/ (function(module, exports, __webpack_require__) { + this.renderTarget = new RenderTarget(this, width, height, 1, 0, true, true); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.maskTarget = new RenderTarget(this, width, height, 1, 0, true, true); + this.maskSource = new RenderTarget(this, width, height, 1, 0, true, true); -var Class = __webpack_require__(0); + // Set-up pipelines + var config = game.config; -/** - * @classdesc - * A seeded Random Data Generator. - * - * Access via `Phaser.Math.RND` which is an instance of this class pre-defined - * by Phaser. Or, create your own instance to use as you require. - * - * The `Math.RND` generator is seeded by the Game Config property value `seed`. - * If no such config property exists, a random number is used. - * - * If you create your own instance of this class you should provide a seed for it. - * If no seed is given it will use a 'random' one based on Date.now. - * - * @class RandomDataGenerator - * @memberof Phaser.Math - * @constructor - * @since 3.0.0 - * - * @param {(string|string[])} [seeds] - The seeds to use for the random number generator. - */ -var RandomDataGenerator = new Class({ + pipelineManager.boot(config.pipeline, config.defaultPipeline, config.autoMobilePipeline); - initialize: + // Set-up default textures, fbo and scissor - function RandomDataGenerator (seeds) - { - if (seeds === undefined) { seeds = [ (Date.now() * Math.random()).toString() ]; } + this.blankTexture = game.textures.getFrame('__DEFAULT').glTexture; + this.whiteTexture = game.textures.getFrame('__WHITE').glTexture; - /** - * Internal var. - * - * @name Phaser.Math.RandomDataGenerator#c - * @type {number} - * @default 1 - * @private - * @since 3.0.0 - */ - this.c = 1; + var gl = this.gl; - /** - * Internal var. - * - * @name Phaser.Math.RandomDataGenerator#s0 - * @type {number} - * @default 0 - * @private - * @since 3.0.0 - */ - this.s0 = 0; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); - /** - * Internal var. - * - * @name Phaser.Math.RandomDataGenerator#s1 - * @type {number} - * @default 0 - * @private - * @since 3.0.0 - */ - this.s1 = 0; + gl.enable(gl.SCISSOR_TEST); - /** - * Internal var. - * - * @name Phaser.Math.RandomDataGenerator#s2 - * @type {number} - * @default 0 - * @private - * @since 3.0.0 - */ - this.s2 = 0; + game.scale.on(ScaleEvents.RESIZE, this.onResize, this); - /** - * Internal var. - * - * @name Phaser.Math.RandomDataGenerator#n - * @type {number} - * @default 0 - * @private - * @since 3.2.0 - */ - this.n = 0; + this.resize(width, height); + }, - /** - * Signs to choose from. - * - * @name Phaser.Math.RandomDataGenerator#signs - * @type {number[]} - * @since 3.0.0 - */ - this.signs = [ -1, 1 ]; + /** + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. + * + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. + * + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method will capture the current WebGL frame and send it to the Spector.js tool for inspection. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#captureFrame + * @since 3.60.0 + * + * @param {boolean} [quickCapture=false] - If `true` thumbnails are not captured in order to speed up the capture. + * @param {boolean} [fullCapture=false] - If `true` all details are captured. + */ + captureFrame: function (quickCapture, fullCapture) + { + if (quickCapture === undefined) { quickCapture = false; } + if (fullCapture === undefined) { fullCapture = false; } - if (seeds) + if (DEBUG && this.spector && !this._debugCapture) { - this.init(seeds); + this.spector.captureCanvas(this.canvas, 0, quickCapture, fullCapture); + + this._debugCapture = true; } }, /** - * Private random helper. + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. * - * @method Phaser.Math.RandomDataGenerator#rnd - * @since 3.0.0 - * @private + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. * - * @return {number} A random number. + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method will capture the next WebGL frame and send it to the Spector.js tool for inspection. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#captureNextFrame + * @since 3.60.0 */ - rnd: function () + captureNextFrame: function () { - var t = 2091639 * this.s0 + this.c * 2.3283064365386963e-10; // 2^-32 - - this.c = t | 0; - this.s0 = this.s1; - this.s1 = this.s2; - this.s2 = t - this.c; + if (DEBUG && this.spector && !this._debugCapture) + { + this._debugCapture = true; - return this.s2; + this.spector.captureNextFrame(this.canvas); + } }, /** - * Internal method that creates a seed hash. + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. * - * @method Phaser.Math.RandomDataGenerator#hash - * @since 3.0.0 - * @private + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. * - * @param {string} data - The value to hash. + * See https://github.com/BabylonJS/Spector.js for more details. * - * @return {number} The hashed value. + * This method will return the current FPS of the WebGL canvas. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#getFps + * @since 3.60.0 + * + * @return {number} The current FPS of the WebGL canvas. */ - hash: function (data) + getFps: function () { - var h; - var n = this.n; - - data = data.toString(); - - for (var i = 0; i < data.length; i++) + if (DEBUG && this.spector) { - n += data.charCodeAt(i); - h = 0.02519603282416938 * n; - n = h >>> 0; - h -= n; - h *= n; - n = h >>> 0; - h -= n; - n += h * 0x100000000;// 2^32 + return this.spector.getFps(); } - - this.n = n; - - return (n >>> 0) * 2.3283064365386963e-10;// 2^-32 }, /** - * Initialize the state of the random data generator. + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. * - * @method Phaser.Math.RandomDataGenerator#init - * @since 3.0.0 + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. * - * @param {(string|string[])} seeds - The seeds to initialize the random data generator with. + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method adds a command with the name value in the list. This can be filtered in the search. + * All logs can be filtered searching for "LOG". + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#log + * @since 3.60.0 + * + * @param {...*} arguments - The arguments to log to Spector. + * + * @return {string} The current log. */ - init: function (seeds) + log: function () { - if (typeof seeds === 'string') - { - this.state(seeds); - } - else + if (DEBUG && this.spector) { - this.sow(seeds); + var t = Array.prototype.slice.call(arguments).join(' '); + + return this.spector.log(t); } }, /** - * Reset the seed of the random data generator. + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. * - * _Note_: the seed array is only processed up to the first `undefined` (or `null`) value, should such be present. + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. * - * @method Phaser.Math.RandomDataGenerator#sow - * @since 3.0.0 + * See https://github.com/BabylonJS/Spector.js for more details. * - * @param {string[]} seeds - The array of seeds: the `toString()` of each value is used. + * This method will start a capture on the Phaser canvas. The capture will stop once it reaches + * the number of commands specified as a parameter, or after 10 seconds. If quick capture is true, + * the thumbnails are not captured in order to speed up the capture. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#startCapture + * @since 3.60.0 + * + * @param {number} [commandCount=0] - The number of commands to capture. If zero it will capture for 10 seconds. + * @param {boolean} [quickCapture=false] - If `true` thumbnails are not captured in order to speed up the capture. + * @param {boolean} [fullCapture=false] - If `true` all details are captured. */ - sow: function (seeds) + startCapture: function (commandCount, quickCapture, fullCapture) { - // Always reset to default seed - this.n = 0xefc8249d; - this.s0 = this.hash(' '); - this.s1 = this.hash(' '); - this.s2 = this.hash(' '); - this.c = 1; - - if (!seeds) - { - return; - } + if (commandCount === undefined) { commandCount = 0; } + if (quickCapture === undefined) { quickCapture = false; } + if (fullCapture === undefined) { fullCapture = false; } - // Apply any seeds - for (var i = 0; i < seeds.length && (seeds[i] != null); i++) + if (DEBUG && this.spector && !this._debugCapture) { - var seed = seeds[i]; - - this.s0 -= this.hash(seed); - this.s0 += ~~(this.s0 < 0); - this.s1 -= this.hash(seed); - this.s1 += ~~(this.s1 < 0); - this.s2 -= this.hash(seed); - this.s2 += ~~(this.s2 < 0); + this.spector.startCapture(this.canvas, commandCount, quickCapture, fullCapture); + + this._debugCapture = true; } }, /** - * Returns a random integer between 0 and 2^32. + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. * - * @method Phaser.Math.RandomDataGenerator#integer - * @since 3.0.0 + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. * - * @return {number} A random integer between 0 and 2^32. + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method will stop the current capture and returns the result in JSON. It displays the + * result if the UI has been displayed. This returns undefined if the capture has not been completed + * or did not find any commands. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#stopCapture + * @since 3.60.0 + * + * @return {object} The current capture. */ - integer: function () + stopCapture: function () { - // 2^32 - return this.rnd() * 0x100000000; + if (DEBUG && this.spector && this._debugCapture) + { + return this.spector.stopCapture(); + } }, /** - * Returns a random real number between 0 and 1. + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. * - * @method Phaser.Math.RandomDataGenerator#frac - * @since 3.0.0 + * Internal onCapture handler. * - * @return {number} A random real number between 0 and 1. + * @method Phaser.Renderer.WebGL.WebGLRenderer#onCapture + * @private + * @since 3.60.0 + * + * @param {object} capture - The capture data. */ - frac: function () + onCapture: function (capture) { - // 2^-53 - return this.rnd() + (this.rnd() * 0x200000 | 0) * 1.1102230246251565e-16; + if (DEBUG) + { + var view = this.spector.getResultUI(); + + view.display(capture); + + this._debugCapture = false; + } }, /** - * Returns a random real number between 0 and 2^32. + * The event handler that manages the `resize` event dispatched by the Scale Manager. * - * @method Phaser.Math.RandomDataGenerator#real - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.WebGLRenderer#onResize + * @since 3.16.0 * - * @return {number} A random real number between 0 and 2^32. + * @param {Phaser.Structs.Size} gameSize - The default Game Size object. This is the un-modified game dimensions. + * @param {Phaser.Structs.Size} baseSize - The base Size object. The game dimensions. The canvas width / height values match this. */ - real: function () + onResize: function (gameSize, baseSize) { - return this.integer() + this.frac(); + // Has the underlying canvas size changed? + if (baseSize.width !== this.width || baseSize.height !== this.height) + { + this.resize(baseSize.width, baseSize.height); + } }, /** - * Returns a random integer between and including min and max. + * Binds the WebGL Renderers Render Target, so all drawn content is now redirected to it. * - * @method Phaser.Math.RandomDataGenerator#integerInRange - * @since 3.0.0 + * Make sure to call `endCapture` when you are finished. * - * @param {number} min - The minimum value in the range. - * @param {number} max - The maximum value in the range. + * @method Phaser.Renderer.WebGL.WebGLRenderer#beginCapture + * @since 3.50.0 * - * @return {number} A random number between min and max. + * @param {number} [width] - Optional new width of the Render Target. + * @param {number} [height] - Optional new height of the Render Target. */ - integerInRange: function (min, max) + beginCapture: function (width, height) { - return Math.floor(this.realInRange(0, max - min + 1) + min); + if (width === undefined) { width = this.width; } + if (height === undefined) { height = this.height; } + + this.renderTarget.bind(true, width, height); + + this.setProjectionMatrix(width, height); }, /** - * Returns a random integer between and including min and max. - * This method is an alias for RandomDataGenerator.integerInRange. + * Unbinds the WebGL Renderers Render Target and returns it, stopping any further content being drawn to it. * - * @method Phaser.Math.RandomDataGenerator#between - * @since 3.0.0 + * If the viewport or scissors were modified during the capture, you should reset them by calling + * `resetViewport` and `resetScissor` accordingly. * - * @param {number} min - The minimum value in the range. - * @param {number} max - The maximum value in the range. + * @method Phaser.Renderer.WebGL.WebGLRenderer#endCapture + * @since 3.50.0 * - * @return {number} A random number between min and max. + * @return {Phaser.Renderer.WebGL.RenderTarget} A reference to the WebGL Renderer Render Target. */ - between: function (min, max) + endCapture: function () { - return Math.floor(this.realInRange(0, max - min + 1) + min); + this.renderTarget.unbind(true); + + this.resetProjectionMatrix(); + + return this.renderTarget; }, /** - * Returns a random real number between min and max. + * Resizes the drawing buffer to match that required by the Scale Manager. * - * @method Phaser.Math.RandomDataGenerator#realInRange + * @method Phaser.Renderer.WebGL.WebGLRenderer#resize + * @fires Phaser.Renderer.Events#RESIZE * @since 3.0.0 * - * @param {number} min - The minimum value in the range. - * @param {number} max - The maximum value in the range. + * @param {number} [width] - The new width of the renderer. + * @param {number} [height] - The new height of the renderer. * - * @return {number} A random number between min and max. + * @return {this} This WebGLRenderer instance. */ - realInRange: function (min, max) + resize: function (width, height) { - return this.frac() * (max - min) + min; + var gl = this.gl; + + this.width = width; + this.height = height; + + this.setProjectionMatrix(width, height); + + gl.viewport(0, 0, width, height); + + this.drawingBufferHeight = gl.drawingBufferHeight; + + gl.scissor(0, (gl.drawingBufferHeight - height), width, height); + + this.defaultScissor[2] = width; + this.defaultScissor[3] = height; + + this.emit(Events.RESIZE, width, height); + + return this; }, /** - * Returns a random real number between -1 and 1. + * Determines which compressed texture formats this browser and device supports. * - * @method Phaser.Math.RandomDataGenerator#normal - * @since 3.0.0 + * Called automatically as part of the WebGL Renderer init process. If you need to investigate + * which formats it supports, see the `Phaser.Renderer.WebGL.WebGLRenderer#compression` property instead. * - * @return {number} A random real number between -1 and 1. + * @method Phaser.Renderer.WebGL.WebGLRenderer#getCompressedTextures + * @since 3.60.0 + * + * @return {Phaser.Types.Renderer.WebGL.WebGLTextureCompression} The compression object. */ - normal: function () + getCompressedTextures: function () { - return 1 - (2 * this.frac()); + var extString = 'WEBGL_compressed_texture_'; + var wkExtString = 'WEBKIT_' + extString; + + var hasExt = function (gl, format) + { + var results = gl.getExtension(extString + format) || gl.getExtension(wkExtString + format); + + if (results) + { + var glEnums = {}; + + for (var key in results) + { + glEnums[results[key]] = key; + } + + return glEnums; + } + }; + + var gl = this.gl; + + return { + ETC: hasExt(gl, 'etc'), + ETC1: hasExt(gl, 'etc1'), + ATC: hasExt(gl, 'atc'), + ASTC: hasExt(gl, 'astc'), + BPTC: hasExt(gl, 'bptc'), + RGTC: hasExt(gl, 'rgtc'), + PVRTC: hasExt(gl, 'pvrtc'), + S3TC: hasExt(gl, 's3tc'), + S3TCSRGB: hasExt(gl, 's3tc_srgb'), + IMG: true + }; }, /** - * Returns a valid RFC4122 version4 ID hex string from https://gist.github.com/1308368 + * Returns a compressed texture format GLenum name based on the given format. * - * @method Phaser.Math.RandomDataGenerator#uuid - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.WebGLRenderer#getCompressedTextureName + * @since 3.60.0 * - * @return {string} A valid RFC4122 version4 ID hex string + * @param {string} baseFormat - The Base Format to check. + * @param {GLenum} [format] - An optional GLenum format to check within the base format. + * + * @return {string} The compressed texture format name, as a string. */ - uuid: function () + getCompressedTextureName: function (baseFormat, format) { - var a = ''; - var b = ''; + var supportedFormats = this.compression[baseFormat.toUpperCase()]; - for (b = a = ''; a++ < 36; b += ~a % 5 | a * 3 & 4 ? (a ^ 15 ? 8 ^ this.frac() * (a ^ 20 ? 16 : 4) : 4).toString(16) : '-') + if (format in supportedFormats) { - // eslint-disable-next-line no-empty + return supportedFormats[format]; } - - return b; }, /** - * Returns a random element from within the given array. + * Checks if the given compressed texture format is supported, or not. * - * @method Phaser.Math.RandomDataGenerator#pick - * @since 3.0.0 - * - * @generic T - * @genericUse {T[]} - [array] - * @genericUse {T} - [$return] + * @method Phaser.Renderer.WebGL.WebGLRenderer#supportsCompressedTexture + * @since 3.60.0 * - * @param {T[]} array - The array to pick a random element from. + * @param {string} baseFormat - The Base Format to check. + * @param {GLenum} [format] - An optional GLenum format to check within the base format. * - * @return {T} A random member of the array. + * @return {boolean} True if the format is supported, otherwise false. */ - pick: function (array) + supportsCompressedTexture: function (baseFormat, format) { - return array[this.integerInRange(0, array.length - 1)]; + var supportedFormats = this.compression[baseFormat.toUpperCase()]; + + if (supportedFormats) + { + if (format) + { + return format in supportedFormats; + } + else + { + return true; + } + } + + return false; }, /** - * Returns a sign to be used with multiplication operator. + * Gets the aspect ratio of the WebGLRenderer dimensions. * - * @method Phaser.Math.RandomDataGenerator#sign - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.WebGLRenderer#getAspectRatio + * @since 3.50.0 * - * @return {number} -1 or +1. + * @return {number} The aspect ratio of the WebGLRenderer dimensions. */ - sign: function () + getAspectRatio: function () { - return this.pick(this.signs); + return this.width / this.height; }, /** - * Returns a random element from within the given array, favoring the earlier entries. - * - * @method Phaser.Math.RandomDataGenerator#weightedPick - * @since 3.0.0 + * Sets the Projection Matrix of this renderer to the given dimensions. * - * @generic T - * @genericUse {T[]} - [array] - * @genericUse {T} - [$return] + * @method Phaser.Renderer.WebGL.WebGLRenderer#setProjectionMatrix + * @since 3.50.0 * - * @param {T[]} array - The array to pick a random element from. + * @param {number} width - The new width of the Projection Matrix. + * @param {number} height - The new height of the Projection Matrix. * - * @return {T} A random member of the array. + * @return {this} This WebGLRenderer instance. */ - weightedPick: function (array) + setProjectionMatrix: function (width, height) { - return array[~~(Math.pow(this.frac(), 2) * (array.length - 1) + 0.5)]; + if (width !== this.projectionWidth || height !== this.projectionHeight) + { + this.projectionWidth = width; + this.projectionHeight = height; + + this.projectionMatrix.ortho(0, width, height, 0, -1000, 1000); + } + + return this; }, /** - * Returns a random timestamp between min and max, or between the beginning of 2000 and the end of 2020 if min and max aren't specified. + * Resets the Projection Matrix back to this renderers width and height. * - * @method Phaser.Math.RandomDataGenerator#timestamp - * @since 3.0.0 + * This is called during `endCapture`, should the matrix have been changed + * as a result of the capture process. * - * @param {number} min - The minimum value in the range. - * @param {number} max - The maximum value in the range. + * @method Phaser.Renderer.WebGL.WebGLRenderer#resetProjectionMatrix + * @since 3.50.0 * - * @return {number} A random timestamp between min and max. + * @return {this} This WebGLRenderer instance. */ - timestamp: function (min, max) + resetProjectionMatrix: function () { - return this.realInRange(min || 946684800000, max || 1577862000000); + return this.setProjectionMatrix(this.width, this.height); }, /** - * Returns a random angle between -180 and 180. + * Checks if a WebGL extension is supported * - * @method Phaser.Math.RandomDataGenerator#angle + * @method Phaser.Renderer.WebGL.WebGLRenderer#hasExtension * @since 3.0.0 * - * @return {number} A random number between -180 and 180. + * @param {string} extensionName - Name of the WebGL extension + * + * @return {boolean} `true` if the extension is supported, otherwise `false`. */ - angle: function () + hasExtension: function (extensionName) { - return this.integerInRange(-180, 180); + return this.supportedExtensions ? this.supportedExtensions.indexOf(extensionName) : false; }, /** - * Returns a random rotation in radians, between -3.141 and 3.141 + * Loads a WebGL extension * - * @method Phaser.Math.RandomDataGenerator#rotation + * @method Phaser.Renderer.WebGL.WebGLRenderer#getExtension * @since 3.0.0 * - * @return {number} A random number between -3.141 and 3.141 + * @param {string} extensionName - The name of the extension to load. + * + * @return {object} WebGL extension if the extension is supported */ - rotation: function () + getExtension: function (extensionName) { - return this.realInRange(-3.1415926, 3.1415926); + if (!this.hasExtension(extensionName)) { return null; } + + if (!(extensionName in this.extensions)) + { + this.extensions[extensionName] = this.gl.getExtension(extensionName); + } + + return this.extensions[extensionName]; }, /** - * Gets or Sets the state of the generator. This allows you to retain the values - * that the generator is using between games, i.e. in a game save file. - * - * To seed this generator with a previously saved state you can pass it as the - * `seed` value in your game config, or call this method directly after Phaser has booted. - * - * Call this method with no parameters to return the current state. - * - * If providing a state it should match the same format that this method - * returns, which is a string with a header `!rnd` followed by the `c`, - * `s0`, `s1` and `s2` values respectively, each comma-delimited. + * Flushes the current pipeline if the pipeline is bound * - * @method Phaser.Math.RandomDataGenerator#state + * @method Phaser.Renderer.WebGL.WebGLRenderer#flush * @since 3.0.0 - * - * @param {string} [state] - Generator state to be set. - * - * @return {string} The current state of the generator. */ - state: function (state) + flush: function () { - if (typeof state === 'string' && state.match(/^!rnd/)) - { - state = state.split(','); - - this.c = parseFloat(state[1]); - this.s0 = parseFloat(state[2]); - this.s1 = parseFloat(state[3]); - this.s2 = parseFloat(state[4]); - } - - return [ '!rnd', this.c, this.s0, this.s1, this.s2 ].join(','); + this.pipelines.flush(); }, /** - * Shuffles the given array, using the current seed. - * - * @method Phaser.Math.RandomDataGenerator#shuffle - * @since 3.7.0 + * Pushes a new scissor state. This is used to set nested scissor states. * - * @generic T - * @genericUse {T[]} - [array,$return] + * @method Phaser.Renderer.WebGL.WebGLRenderer#pushScissor + * @since 3.0.0 * - * @param {T[]} [array] - The array to be shuffled. + * @param {number} x - The x position of the scissor. + * @param {number} y - The y position of the scissor. + * @param {number} width - The width of the scissor. + * @param {number} height - The height of the scissor. + * @param {number} [drawingBufferHeight] - Optional drawingBufferHeight override value. * - * @return {T[]} The shuffled array. + * @return {number[]} An array containing the scissor values. */ - shuffle: function (array) + pushScissor: function (x, y, width, height, drawingBufferHeight) { - var len = array.length - 1; - - for (var i = len; i > 0; i--) - { - var randomIndex = Math.floor(this.frac() * (i + 1)); - var itemAtIndex = array[randomIndex]; - - array[randomIndex] = array[i]; - array[i] = itemAtIndex; - } - - return array; - } + if (drawingBufferHeight === undefined) { drawingBufferHeight = this.drawingBufferHeight; } -}); + var scissorStack = this.scissorStack; -module.exports = RandomDataGenerator; + var scissor = [ x, y, width, height ]; + scissorStack.push(scissor); -/***/ }), -/* 840 */ -/***/ (function(module, exports) { + this.setScissor(x, y, width, height, drawingBufferHeight); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.currentScissor = scissor; -/** - * Calculate the mean average of the given values. - * - * @function Phaser.Math.Average - * @since 3.0.0 - * - * @param {number[]} values - The values to average. - * - * @return {number} The average value. - */ -var Average = function (values) -{ - var sum = 0; + return scissor; + }, - for (var i = 0; i < values.length; i++) + /** + * Sets the current scissor state. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#setScissor + * @since 3.0.0 + * + * @param {number} x - The x position of the scissor. + * @param {number} y - The y position of the scissor. + * @param {number} width - The width of the scissor. + * @param {number} height - The height of the scissor. + * @param {number} [drawingBufferHeight] - Optional drawingBufferHeight override value. + */ + setScissor: function (x, y, width, height, drawingBufferHeight) { - sum += (+values[i]); - } - - return sum / values.length; -}; - -module.exports = Average; - - -/***/ }), -/* 841 */ -/***/ (function(module, exports) { + if (drawingBufferHeight === undefined) { drawingBufferHeight = this.drawingBufferHeight; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var gl = this.gl; -/** - * Ceils to some place comparative to a `base`, default is 10 for decimal place. - * - * The `place` is represented by the power applied to `base` to get that place. - * - * @function Phaser.Math.CeilTo - * @since 3.0.0 - * - * @param {number} value - The value to round. - * @param {number} [place=0] - The place to round to. - * @param {number} [base=10] - The base to round in. Default is 10 for decimal. - * - * @return {number} The rounded value. - */ -var CeilTo = function (value, place, base) -{ - if (place === undefined) { place = 0; } - if (base === undefined) { base = 10; } + var current = this.currentScissor; - var p = Math.pow(base, -place); + var setScissor = (width > 0 && height > 0); - return Math.ceil(value * p) / p; -}; + if (current && setScissor) + { + var cx = current[0]; + var cy = current[1]; + var cw = current[2]; + var ch = current[3]; -module.exports = CeilTo; + setScissor = (cx !== x || cy !== y || cw !== width || ch !== height); + } + if (setScissor) + { + this.flush(); -/***/ }), -/* 842 */ -/***/ (function(module, exports) { + // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/scissor + gl.scissor(x, (drawingBufferHeight - y - height), width, height); + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Resets the gl scissor state to be whatever the current scissor is, if there is one, without + * modifying the scissor stack. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#resetScissor + * @since 3.50.0 + */ + resetScissor: function () + { + var gl = this.gl; -/** - * Calculates the positive difference of two given numbers. - * - * @function Phaser.Math.Difference - * @since 3.0.0 - * - * @param {number} a - The first number in the calculation. - * @param {number} b - The second number in the calculation. - * - * @return {number} The positive difference of the two given numbers. - */ -var Difference = function (a, b) -{ - return Math.abs(a - b); -}; + gl.enable(gl.SCISSOR_TEST); -module.exports = Difference; + var current = this.currentScissor; + if (current) + { + var x = current[0]; + var y = current[1]; + var width = current[2]; + var height = current[3]; -/***/ }), -/* 843 */ -/***/ (function(module, exports, __webpack_require__) { + if (width > 0 && height > 0) + { + gl.scissor(x, (this.drawingBufferHeight - y - height), width, height); + } + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Pops the last scissor state and sets it. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#popScissor + * @since 3.0.0 + */ + popScissor: function () + { + var scissorStack = this.scissorStack; -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var Matrix4 = __webpack_require__(69); -var NOOP = __webpack_require__(1); + // Remove the current scissor + scissorStack.pop(); -var tempMatrix = new Matrix4(); + // Reset the previous scissor + var scissor = scissorStack[scissorStack.length - 1]; -/** - * @classdesc - * - * @class Euler - * @memberof Phaser.Math - * @constructor - * @since 3.50.0 - * - * @param {number} [x] - The x component. - * @param {number} [y] - The y component. - * @param {number} [z] - The z component. - */ -var Euler = new Class({ + if (scissor) + { + this.setScissor(scissor[0], scissor[1], scissor[2], scissor[3]); + } - initialize: + this.currentScissor = scissor; + }, - function Euler (x, y, z, order) + /** + * Is there an active stencil mask? + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#hasActiveStencilMask + * @since 3.17.0 + * + * @return {boolean} `true` if there is an active stencil mask, otherwise `false`. + */ + hasActiveStencilMask: function () { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (z === undefined) { z = 0; } - if (order === undefined) { order = Euler.DefaultOrder; } - - this._x = x; - this._y = y; - this._z = z; - this._order = order; + var mask = this.currentMask.mask; + var camMask = this.currentCameraMask.mask; - this.onChangeCallback = NOOP; + return ((mask && mask.isStencil) || (camMask && camMask.isStencil)); }, - x: { - get: function () - { - return this._x; - }, + /** + * Resets the gl viewport to the current renderer dimensions. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#resetViewport + * @since 3.50.0 + */ + resetViewport: function () + { + var gl = this.gl; - set: function (value) - { - this._x = value; + gl.viewport(0, 0, this.width, this.height); - this.onChangeCallback(this); - } + this.drawingBufferHeight = gl.drawingBufferHeight; }, - y: { - get: function () - { - return this._y; - }, + /** + * Sets the blend mode to the value given. + * + * If the current blend mode is different from the one given, the pipeline is flushed and the new + * blend mode is enabled. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#setBlendMode + * @since 3.0.0 + * + * @param {number} blendModeId - The blend mode to be set. Can be a `BlendModes` const or an integer value. + * @param {boolean} [force=false] - Force the blend mode to be set, regardless of the currently set blend mode. + * + * @return {boolean} `true` if the blend mode was changed as a result of this call, forcing a flush, otherwise `false`. + */ + setBlendMode: function (blendModeId, force) + { + if (force === undefined) { force = false; } - set: function (value) + var gl = this.gl; + var blendMode = this.blendModes[blendModeId]; + + if (force || (blendModeId !== CONST.BlendModes.SKIP_CHECK && this.currentBlendMode !== blendModeId)) { - this._y = value; + this.flush(); - this.onChangeCallback(this); - } - }, + gl.enable(gl.BLEND); + gl.blendEquation(blendMode.equation); - z: { - get: function () - { - return this._z; - }, + if (blendMode.func.length > 2) + { + gl.blendFuncSeparate(blendMode.func[0], blendMode.func[1], blendMode.func[2], blendMode.func[3]); + } + else + { + gl.blendFunc(blendMode.func[0], blendMode.func[1]); + } - set: function (value) - { - this._z = value; + this.currentBlendMode = blendModeId; - this.onChangeCallback(this); + return true; } - }, - order: { - get: function () - { - return this._order; - }, + return false; + }, - set: function (value) - { - this._order = value; + /** + * Creates a new custom blend mode for the renderer. + * + * See https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Blending_modes + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#addBlendMode + * @since 3.0.0 + * + * @param {GLenum[]} func - An array containing the WebGL functions to use for the source and the destination blending factors, respectively. See the possible constants for {@link WebGLRenderingContext#blendFunc()}. + * @param {GLenum} equation - The equation to use for combining the RGB and alpha components of a new pixel with a rendered one. See the possible constants for {@link WebGLRenderingContext#blendEquation()}. + * + * @return {number} The index of the new blend mode, used for referencing it in the future. + */ + addBlendMode: function (func, equation) + { + var index = this.blendModes.push({ func: func, equation: equation }); - this.onChangeCallback(this); - } + return index - 1; }, - set: function (x, y, z, order) + /** + * Updates the function bound to a given custom blend mode. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#updateBlendMode + * @since 3.0.0 + * + * @param {number} index - The index of the custom blend mode. + * @param {function} func - The function to use for the blend mode. + * @param {function} equation - The equation to use for the blend mode. + * + * @return {this} This WebGLRenderer instance. + */ + updateBlendMode: function (index, func, equation) { - if (order === undefined) { order = this._order; } - - this._x = x; - this._y = y; - this._z = z; - this._order = order; + if (this.blendModes[index]) + { + this.blendModes[index].func = func; - this.onChangeCallback(this); + if (equation) + { + this.blendModes[index].equation = equation; + } + } return this; }, - copy: function (euler) + /** + * Removes a custom blend mode from the renderer. + * Any Game Objects still using this blend mode will error, so be sure to clear them first. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#removeBlendMode + * @since 3.0.0 + * + * @param {number} index - The index of the custom blend mode to be removed. + * + * @return {this} This WebGLRenderer instance. + */ + removeBlendMode: function (index) { - return this.set(euler.x, euler.y, euler.z, euler.order); + if (index > 17 && this.blendModes[index]) + { + this.blendModes.splice(index, 1); + } + + return this; }, - setFromQuaternion: function (quaternion, order, update) + /** + * Pushes a new framebuffer onto the FBO stack and makes it the currently bound framebuffer. + * + * If there was another framebuffer already bound it will force a pipeline flush. + * + * Call `popFramebuffer` to remove it again. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#pushFramebuffer + * @since 3.50.0 + * + * @param {WebGLFramebuffer} framebuffer - The framebuffer that needs to be bound. + * @param {boolean} [updateScissor=false] - Set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. + * @param {boolean} [setViewport=true] - Should the WebGL viewport be set? + * @param {WebGLTexture} [texture=null] - Bind the given frame buffer texture? + * @param {boolean} [clear=false] - Clear the frame buffer after binding? + * + * @return {this} This WebGLRenderer instance. + */ + pushFramebuffer: function (framebuffer, updateScissor, setViewport, texture, clear) { - if (order === undefined) { order = this._order; } - if (update === undefined) { update = false; } + if (framebuffer === this.currentFramebuffer) + { + return this; + } - tempMatrix.fromQuat(quaternion); + this.fboStack.push(framebuffer); - return this.setFromRotationMatrix(tempMatrix, order, update); + return this.setFramebuffer(framebuffer, updateScissor, setViewport, texture, clear); }, - setFromRotationMatrix: function (matrix, order, update) + /** + * Sets the given framebuffer as the active and currently bound framebuffer. + * + * If there was another framebuffer already bound it will force a pipeline flush. + * + * Typically, you should call `pushFramebuffer` instead of this method. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#setFramebuffer + * @since 3.0.0 + * + * @param {WebGLFramebuffer} framebuffer - The framebuffer that needs to be bound. + * @param {boolean} [updateScissor=false] - If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. + * @param {boolean} [setViewport=true] - Should the WebGL viewport be set? + * @param {WebGLTexture} [texture=null] - Bind the given frame buffer texture? + * @param {boolean} [clear=false] - Clear the frame buffer after binding? + * + * @return {this} This WebGLRenderer instance. + */ + setFramebuffer: function (framebuffer, updateScissor, setViewport, texture, clear) { - if (order === undefined) { order = this._order; } - if (update === undefined) { update = false; } - - var elements = matrix.val; - - // Upper 3x3 of matrix is un-scaled rotation matrix - var m11 = elements[0]; - var m12 = elements[4]; - var m13 = elements[8]; - var m21 = elements[1]; - var m22 = elements[5]; - var m23 = elements[9]; - var m31 = elements[2]; - var m32 = elements[6]; - var m33 = elements[10]; - - var x = 0; - var y = 0; - var z = 0; - var epsilon = 0.99999; + if (updateScissor === undefined) { updateScissor = false; } + if (setViewport === undefined) { setViewport = true; } + if (texture === undefined) { texture = null; } + if (clear === undefined) { clear = false; } - switch (order) + if (framebuffer === this.currentFramebuffer) { - case 'XYZ': - { - y = Math.asin(Clamp(m13, -1, 1)); - - if (Math.abs(m13) < epsilon) - { - x = Math.atan2(-m23, m33); - z = Math.atan2(-m12, m11); - } - else - { - x = Math.atan2(m32, m22); - } - - break; - } - - case 'YXZ': - { - x = Math.asin(-Clamp(m23, -1, 1)); - - if (Math.abs(m23) < epsilon) - { - y = Math.atan2(m13, m33); - z = Math.atan2(m21, m22); - } - else - { - y = Math.atan2(-m31, m11); - } + return this; + } - break; - } + var gl = this.gl; - case 'ZXY': - { - x = Math.asin(Clamp(m32, -1, 1)); + var width = this.width; + var height = this.height; - if (Math.abs(m32) < epsilon) - { - y = Math.atan2(-m31, m33); - z = Math.atan2(-m12, m22); - } - else - { - z = Math.atan2(m21, m11); - } + if (framebuffer && framebuffer.renderTexture && setViewport) + { + width = framebuffer.renderTexture.width; + height = framebuffer.renderTexture.height; + } + else + { + this.flush(); + } - break; - } + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - case 'ZYX': - { - y = Math.asin(-Clamp(m31, -1, 1)); + if (setViewport) + { + gl.viewport(0, 0, width, height); + } - if (Math.abs(m31) < epsilon) - { - x = Math.atan2(m32, m33); - z = Math.atan2(m21, m11); - } - else - { - z = Math.atan2(-m12, m22); - } + if (texture) + { + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + } - break; - } + if (clear) + { + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + } - case 'YZX': + if (updateScissor) + { + if (framebuffer) { - z = Math.asin(Clamp(m21, -1, 1)); - - if (Math.abs(m21) < epsilon) - { - x = Math.atan2(-m23, m22); - y = Math.atan2(-m31, m11); - } - else - { - y = Math.atan2(m13, m33); - } + this.drawingBufferHeight = height; - break; + this.pushScissor(0, 0, width, height); } - - case 'XZY': + else { - z = Math.asin(-Clamp(m12, -1, 1)); - - if (Math.abs(m12) < epsilon) - { - x = Math.atan2(m32, m22); - y = Math.atan2(m13, m11); - } - else - { - x = Math.atan2(-m23, m33); - } + this.drawingBufferHeight = this.height; - break; + this.popScissor(); } } - this._x = x; - this._y = y; - this._z = z; - this._order = order; - - if (update) - { - this.onChangeCallback(this); - } + this.currentFramebuffer = framebuffer; return this; - } - -}); - -Euler.RotationOrders = [ 'XYZ', 'YXZ', 'ZXY', 'ZYX', 'YZX', 'XZY' ]; - -Euler.DefaultOrder = 'XYZ'; - -module.exports = Euler; - - -/***/ }), -/* 844 */ -/***/ (function(module, exports) { + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Pops the previous framebuffer from the fbo stack and sets it. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#popFramebuffer + * @since 3.50.0 + * + * @param {boolean} [updateScissor=false] - If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. + * @param {boolean} [setViewport=true] - Should the WebGL viewport be set? + * + * @return {WebGLFramebuffer} The Framebuffer that was set, or `null` if there aren't any more in the stack. + */ + popFramebuffer: function (updateScissor, setViewport) + { + if (updateScissor === undefined) { updateScissor = false; } + if (setViewport === undefined) { setViewport = true; } -/** - * Floors to some place comparative to a `base`, default is 10 for decimal place. - * - * The `place` is represented by the power applied to `base` to get that place. - * - * @function Phaser.Math.FloorTo - * @since 3.0.0 - * - * @param {number} value - The value to round. - * @param {number} [place=0] - The place to round to. - * @param {number} [base=10] - The base to round in. Default is 10 for decimal. - * - * @return {number} The rounded value. - */ -var FloorTo = function (value, place, base) -{ - if (place === undefined) { place = 0; } - if (base === undefined) { base = 10; } + var fboStack = this.fboStack; - var p = Math.pow(base, -place); + // Remove the current fbo + fboStack.pop(); - return Math.floor(value * p) / p; -}; + // Reset the previous framebuffer + var framebuffer = fboStack[fboStack.length - 1]; -module.exports = FloorTo; + if (!framebuffer) + { + framebuffer = null; + } + this.setFramebuffer(framebuffer, updateScissor, setViewport); -/***/ }), -/* 845 */ -/***/ (function(module, exports) { + return framebuffer; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Restores the previous framebuffer from the fbo stack and sets it. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#restoreFramebuffer + * @since 3.60.0 + * + * @param {boolean} [updateScissor=false] - If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. + * @param {boolean} [setViewport=true] - Should the WebGL viewport be set? + */ + restoreFramebuffer: function (updateScissor, setViewport) + { + if (updateScissor === undefined) { updateScissor = false; } + if (setViewport === undefined) { setViewport = true; } -/** - * Calculate a per-ms speed from a distance and time (given in seconds). - * - * @function Phaser.Math.GetSpeed - * @since 3.0.0 - * - * @param {number} distance - The distance. - * @param {number} time - The time, in seconds. - * - * @return {number} The speed, in distance per ms. - * - * @example - * // 400px over 1 second is 0.4 px/ms - * Phaser.Math.GetSpeed(400, 1) // -> 0.4 - */ -var GetSpeed = function (distance, time) -{ - return (distance / time) / 1000; -}; + var fboStack = this.fboStack; -module.exports = GetSpeed; + var framebuffer = fboStack[fboStack.length - 1]; + if (!framebuffer) + { + framebuffer = null; + } -/***/ }), -/* 846 */ -/***/ (function(module, exports) { + this.currentFramebuffer = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.setFramebuffer(framebuffer, updateScissor, setViewport); + }, -/** - * Check if a given value is an even number. - * - * @function Phaser.Math.IsEven - * @since 3.0.0 - * - * @param {number} value - The number to perform the check with. - * - * @return {boolean} Whether the number is even or not. - */ -var IsEven = function (value) -{ - // Use abstract equality == for "is number" test + /** + * Binds a shader program. + * + * If there was a different program already bound it will force a pipeline flush first. + * + * If the same program given to this method is already set as the current program, no change + * will take place and this method will return `false`. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#setProgram + * @since 3.0.0 + * + * @param {WebGLProgram} program - The program that needs to be bound. + * + * @return {boolean} `true` if the given program was bound, otherwise `false`. + */ + setProgram: function (program) + { + if (program !== this.currentProgram) + { + this.flush(); - // eslint-disable-next-line eqeqeq - return (value == parseFloat(value)) ? !(value % 2) : void 0; -}; + this.gl.useProgram(program); -module.exports = IsEven; + this.currentProgram = program; + return true; + } -/***/ }), -/* 847 */ -/***/ (function(module, exports) { + return false; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Rebinds whatever program `WebGLRenderer.currentProgram` is set as, without + * changing anything, or flushing. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#resetProgram + * @since 3.50.0 + * + * @return {this} This WebGLRenderer instance. + */ + resetProgram: function () + { + this.gl.useProgram(this.currentProgram); -/** - * Check if a given value is an even number using a strict type check. - * - * @function Phaser.Math.IsEvenStrict - * @since 3.0.0 - * - * @param {number} value - The number to perform the check with. - * - * @return {boolean} Whether the number is even or not. - */ -var IsEvenStrict = function (value) -{ - // Use strict equality === for "is number" test - return (value === parseFloat(value)) ? !(value % 2) : void 0; -}; + return this; + }, -module.exports = IsEvenStrict; + /** + * Creates a texture from an image source. If the source is not valid it creates an empty texture. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#createTextureFromSource + * @since 3.0.0 + * + * @param {object} source - The source of the texture. + * @param {number} width - The width of the texture. + * @param {number} height - The height of the texture. + * @param {number} scaleMode - The scale mode to be used by the texture. + * @param {boolean} [forceClamp=false] - Force the texture to use the CLAMP_TO_EDGE wrap mode, even if a power of two? + * + * @return {?WebGLTexture} The WebGL Texture that was created, or `null` if it couldn't be created. + */ + createTextureFromSource: function (source, width, height, scaleMode, forceClamp) + { + if (forceClamp === undefined) { forceClamp = false; } + var gl = this.gl; + var minFilter = gl.NEAREST; + var magFilter = gl.NEAREST; + var wrap = gl.CLAMP_TO_EDGE; + var texture = null; -/***/ }), -/* 848 */ -/***/ (function(module, exports) { + width = source ? source.width : width; + height = source ? source.height : height; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var pow = IsSizePowerOfTwo(width, height); -/** - * Add an `amount` to a `value`, limiting the maximum result to `max`. - * - * @function Phaser.Math.MaxAdd - * @since 3.0.0 - * - * @param {number} value - The value to add to. - * @param {number} amount - The amount to add. - * @param {number} max - The maximum value to return. - * - * @return {number} The resulting value. - */ -var MaxAdd = function (value, amount, max) -{ - return Math.min(value + amount, max); -}; + if (pow && !forceClamp) + { + wrap = gl.REPEAT; + } -module.exports = MaxAdd; + if (scaleMode === CONST.ScaleModes.LINEAR && this.config.antialias) + { + minFilter = (pow && this.mipmapFilter) ? this.mipmapFilter : gl.LINEAR; + magFilter = gl.LINEAR; + } + if (source && source.compressed) + { + // If you don't set minFilter to LINEAR then the compressed textures don't work! + minFilter = gl.LINEAR; + magFilter = gl.LINEAR; + } -/***/ }), -/* 849 */ -/***/ (function(module, exports) { + if (!source && typeof width === 'number' && typeof height === 'number') + { + texture = this.createTexture2D(0, minFilter, magFilter, wrap, wrap, gl.RGBA, null, width, height); + } + else + { + texture = this.createTexture2D(0, minFilter, magFilter, wrap, wrap, gl.RGBA, source); + } -/** - * @author Vladislav Forsh - * @copyright 2021 RoboWhale - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return texture; + }, -/** - * Calculate the median of the given values. The values are sorted and the middle value is returned. - * In case of an even number of values, the average of the two middle values is returned. - * - * @function Phaser.Math.Median - * @since 3.54.0 - * - * @param {number[]} values - The values to average. - * - * @return {number} The median value. - */ -var Median = function (values) -{ - var valuesNum = values.length; - if (valuesNum === 0) + /** + * A wrapper for creating a WebGLTexture. If no pixel data is passed it will create an empty texture. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#createTexture2D + * @since 3.0.0 + * + * @param {number} mipLevel - Mip level of the texture. + * @param {number} minFilter - Filtering of the texture. + * @param {number} magFilter - Filtering of the texture. + * @param {number} wrapT - Wrapping mode of the texture. + * @param {number} wrapS - Wrapping mode of the texture. + * @param {number} format - Which format does the texture use. + * @param {?object} pixels - pixel data. + * @param {number} width - Width of the texture in pixels. + * @param {number} height - Height of the texture in pixels. + * @param {boolean} [pma=true] - Does the texture have premultiplied alpha? + * @param {boolean} [forceSize=false] - If `true` it will use the width and height passed to this method, regardless of the pixels dimension. + * @param {boolean} [flipY=false] - Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. + * + * @return {WebGLTexture} The WebGLTexture that was created. + */ + createTexture2D: function (mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height, pma, forceSize, flipY) { - return 0; - } - - values.sort(function (a, b) { return a - b; }); - - var halfIndex = Math.floor(valuesNum / 2); - - return valuesNum % 2 === 0 - ? (values[halfIndex] + values[halfIndex - 1]) / 2 - : values[halfIndex]; -}; - -module.exports = Median; - + pma = (pma === undefined || pma === null) ? true : pma; + if (forceSize === undefined) { forceSize = false; } + if (flipY === undefined) { flipY = false; } -/***/ }), -/* 850 */ -/***/ (function(module, exports) { + var gl = this.gl; + var texture = gl.createTexture(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.activeTexture(gl.TEXTURE0); -/** - * Subtract an `amount` from `value`, limiting the minimum result to `min`. - * - * @function Phaser.Math.MinSub - * @since 3.0.0 - * - * @param {number} value - The value to subtract from. - * @param {number} amount - The amount to subtract. - * @param {number} min - The minimum value to return. - * - * @return {number} The resulting value. - */ -var MinSub = function (value, amount, min) -{ - return Math.max(value - amount, min); -}; + var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D); -module.exports = MinSub; + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT); -/***/ }), -/* 851 */ -/***/ (function(module, exports) { + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, pma); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (flipY) + { + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + } -/** - * Work out what percentage `value` is of the range between `min` and `max`. - * If `max` isn't given then it will return the percentage of `value` to `min`. - * - * You can optionally specify an `upperMax` value, which is a mid-way point in the range that represents 100%, after which the % starts to go down to zero again. - * - * @function Phaser.Math.Percent - * @since 3.0.0 - * - * @param {number} value - The value to determine the percentage of. - * @param {number} min - The minimum value. - * @param {number} [max] - The maximum value. - * @param {number} [upperMax] - The mid-way point in the range that represents 100%. - * - * @return {number} A value between 0 and 1 representing the percentage. - */ -var Percent = function (value, min, max, upperMax) -{ - if (max === undefined) { max = min + 1; } + var generateMipmap = false; - var percentage = (value - min) / (max - min); + if (pixels === null || pixels === undefined) + { + gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, width, height, 0, format, gl.UNSIGNED_BYTE, null); - if (percentage > 1) - { - if (upperMax !== undefined) + generateMipmap = IsSizePowerOfTwo(width, height); + } + else if (pixels.compressed) { - percentage = ((upperMax - value)) / (upperMax - max); + width = pixels.width; + height = pixels.height; + generateMipmap = pixels.generateMipmap; - if (percentage < 0) + for (var i = 0; i < pixels.mipmaps.length; i++) { - percentage = 0; + gl.compressedTexImage2D(gl.TEXTURE_2D, i, pixels.internalFormat, pixels.mipmaps[i].width, pixels.mipmaps[i].height, 0, pixels.mipmaps[i].data); } } else { - percentage = 1; + if (!forceSize) + { + width = pixels.width; + height = pixels.height; + } + + gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, format, gl.UNSIGNED_BYTE, pixels); + + generateMipmap = IsSizePowerOfTwo(width, height); } - } - else if (percentage < 0) + + if (generateMipmap) + { + gl.generateMipmap(gl.TEXTURE_2D); + } + + if (currentTexture) + { + gl.bindTexture(gl.TEXTURE_2D, currentTexture); + } + + texture.isAlphaPremultiplied = pma; + texture.isRenderTexture = false; + texture.width = width; + texture.height = height; + + return texture; + }, + + /** + * Creates a WebGL Framebuffer object and optionally binds a depth stencil render buffer. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#createFramebuffer + * @since 3.0.0 + * + * @param {number} width - If `addDepthStencilBuffer` is true, this controls the width of the depth stencil. + * @param {number} height - If `addDepthStencilBuffer` is true, this controls the height of the depth stencil. + * @param {WebGLTexture} renderTexture - The color texture where the color pixels are written. + * @param {boolean} [addDepthStencilBuffer=false] - Create a Renderbuffer for the depth stencil? + * + * @return {WebGLFramebuffer} Raw WebGLFramebuffer + */ + createFramebuffer: function (width, height, renderTexture, addDepthStencilBuffer) { - percentage = 0; - } + if (addDepthStencilBuffer === undefined) { addDepthStencilBuffer = true; } - return percentage; -}; + var gl = this.gl; + var framebuffer = gl.createFramebuffer(); + var complete = 0; -module.exports = Percent; + this.setFramebuffer(framebuffer); + renderTexture.isRenderTexture = true; + renderTexture.isAlphaPremultiplied = false; -/***/ }), -/* 852 */ -/***/ (function(module, exports) { + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, renderTexture, 0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER); -/** - * Compute a random unit vector. - * - * Computes random values for the given vector between -1 and 1 that can be used to represent a direction. - * - * Optionally accepts a scale value to scale the resulting vector by. - * - * @function Phaser.Math.RandomXY - * @since 3.0.0 - * - * @param {Phaser.Math.Vector2} vector - The Vector to compute random values for. - * @param {number} [scale=1] - The scale of the random values. - * - * @return {Phaser.Math.Vector2} The given Vector. - */ -var RandomXY = function (vector, scale) -{ - if (scale === undefined) { scale = 1; } + if (complete !== gl.FRAMEBUFFER_COMPLETE) + { + var errors = { + 36054: 'Incomplete Attachment', + 36055: 'Missing Attachment', + 36057: 'Incomplete Dimensions', + 36061: 'Framebuffer Unsupported' + }; - var r = Math.random() * 2 * Math.PI; + throw new Error('Framebuffer status: ' + (errors[complete] || complete)); + } - vector.x = Math.cos(r) * scale; - vector.y = Math.sin(r) * scale; + framebuffer.renderTexture = renderTexture; - return vector; -}; + if (addDepthStencilBuffer) + { + var depthStencilBuffer = gl.createRenderbuffer(); -module.exports = RandomXY; + gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer); + } + this.setFramebuffer(null); -/***/ }), -/* 853 */ -/***/ (function(module, exports) { + return framebuffer; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Binds necessary resources and renders the mask to a separated framebuffer. + * The framebuffer for the masked object is also bound for further use. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#beginBitmapMask + * @since 3.60.0 + * + * @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called beginMask. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the current mask. + */ + beginBitmapMask: function (bitmapMask, camera) + { + var gl = this.gl; -/** - * Compute a random position vector in a spherical area, optionally defined by the given radius. - * - * @function Phaser.Math.RandomXYZ - * @since 3.0.0 - * - * @param {Phaser.Math.Vector3} vec3 - The Vector to compute random values for. - * @param {number} [radius=1] - The radius. - * - * @return {Phaser.Math.Vector3} The given Vector. - */ -var RandomXYZ = function (vec3, radius) -{ - if (radius === undefined) { radius = 1; } + if (gl) + { + this.flush(); - var r = Math.random() * 2 * Math.PI; - var z = (Math.random() * 2) - 1; - var zScale = Math.sqrt(1 - z * z) * radius; + this.maskTarget.bind(); - vec3.x = Math.cos(r) * zScale; - vec3.y = Math.sin(r) * zScale; - vec3.z = z * radius; + if (this.currentCameraMask.mask !== bitmapMask) + { + this.currentMask.mask = bitmapMask; + this.currentMask.camera = camera; + } + } + }, - return vec3; -}; + /** + * Binds necessary resources and renders the mask to a separated framebuffer. + * The framebuffer for the masked object is also bound for further use. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#drawBitmapMask + * @since 3.60.0 + * + * @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called beginMask. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the current mask. + * @param {Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline} bitmapMaskPipeline - The BitmapMask Pipeline instance that is requesting the draw. + */ + drawBitmapMask: function (bitmapMask, camera, bitmapMaskPipeline) + { + // mask.mainFramebuffer should now contain all the Game Objects we want masked + this.flush(); -module.exports = RandomXYZ; + this.maskSource.bind(); + this.setBlendMode(0, true); -/***/ }), -/* 854 */ -/***/ (function(module, exports) { + bitmapMask.renderWebGL(this, bitmapMask, camera); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.maskSource.unbind(true); + this.maskTarget.unbind(); -/** - * Compute a random four-dimensional vector. - * - * @function Phaser.Math.RandomXYZW - * @since 3.0.0 - * - * @param {Phaser.Math.Vector4} vec4 - The Vector to compute random values for. - * @param {number} [scale=1] - The scale of the random values. - * - * @return {Phaser.Math.Vector4} The given Vector. - */ -var RandomXYZW = function (vec4, scale) -{ - if (scale === undefined) { scale = 1; } + // Is there a stencil further up the stack? + var gl = this.gl; + var prev = this.getCurrentStencilMask(); - vec4.x = (Math.random() * 2 - 1) * scale; - vec4.y = (Math.random() * 2 - 1) * scale; - vec4.z = (Math.random() * 2 - 1) * scale; - vec4.w = (Math.random() * 2 - 1) * scale; + if (prev) + { + gl.enable(gl.STENCIL_TEST); - return vec4; -}; + prev.mask.applyStencil(this, prev.camera, true); + } + else + { + this.currentMask.mask = null; + } -module.exports = RandomXYZW; + // Bind this pipeline and draw + this.pipelines.set(bitmapMaskPipeline); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this.maskTarget.texture); -/***/ }), -/* 855 */ -/***/ (function(module, exports) { + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, this.maskSource.texture); + }, -/** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Creates a WebGLProgram instance based on the given vertex and fragment shader source. + * + * Then compiles, attaches and links the program before returning it. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#createProgram + * @since 3.0.0 + * + * @param {string} vertexShader - The vertex shader source code as a single string. + * @param {string} fragmentShader - The fragment shader source code as a single string. + * + * @return {WebGLProgram} The linked WebGLProgram created from the given shader source. + */ + createProgram: function (vertexShader, fragmentShader) + { + var gl = this.gl; -/** - * Position a `point` at the given `angle` and `distance` to (`x`, `y`). - * - * @function Phaser.Math.RotateTo - * @since 3.24.0 - * - * @generic {Phaser.Types.Math.Vector2Like} T - [point,$return] - * - * @param {Phaser.Types.Math.Vector2Like} point - The point to be positioned. - * @param {number} x - The horizontal coordinate to position from. - * @param {number} y - The vertical coordinate to position from. - * @param {number} angle - The angle of rotation in radians. - * @param {number} distance - The distance from (x, y) to place the point at. - * - * @return {Phaser.Types.Math.Vector2Like} The given point. - */ -var RotateTo = function (point, x, y, angle, distance) -{ - point.x = x + (distance * Math.cos(angle)); - point.y = y + (distance * Math.sin(angle)); + var program = gl.createProgram(); - return point; -}; + var vs = gl.createShader(gl.VERTEX_SHADER); + var fs = gl.createShader(gl.FRAGMENT_SHADER); -module.exports = RotateTo; + gl.shaderSource(vs, vertexShader); + gl.shaderSource(fs, fragmentShader); + gl.compileShader(vs); + gl.compileShader(fs); -/***/ }), -/* 856 */ -/***/ (function(module, exports) { + var failed = 'Shader failed:\n'; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) + { + throw new Error('Vertex ' + failed + gl.getShaderInfoLog(vs)); + } -/** - * Round a value to the given precision. - * - * For example: - * - * ```javascript - * RoundTo(123.456, 0) = 123 - * RoundTo(123.456, 1) = 120 - * RoundTo(123.456, 2) = 100 - * ``` - * - * To round the decimal, i.e. to round to precision, pass in a negative `place`: - * - * ```javascript - * RoundTo(123.456789, 0) = 123 - * RoundTo(123.456789, -1) = 123.5 - * RoundTo(123.456789, -2) = 123.46 - * RoundTo(123.456789, -3) = 123.457 - * ``` - * - * @function Phaser.Math.RoundTo - * @since 3.0.0 - * - * @param {number} value - The value to round. - * @param {number} [place=0] - The place to round to. Positive to round the units, negative to round the decimal. - * @param {number} [base=10] - The base to round in. Default is 10 for decimal. - * - * @return {number} The rounded value. - */ -var RoundTo = function (value, place, base) -{ - if (place === undefined) { place = 0; } - if (base === undefined) { base = 10; } + if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) + { + throw new Error('Fragment ' + failed + gl.getShaderInfoLog(fs)); + } - var p = Math.pow(base, -place); + gl.attachShader(program, vs); + gl.attachShader(program, fs); - return Math.round(value * p) / p; -}; + gl.linkProgram(program); -module.exports = RoundTo; + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) + { + throw new Error('Link ' + failed + gl.getProgramInfoLog(program)); + } + gl.useProgram(program); -/***/ }), -/* 857 */ -/***/ (function(module, exports) { + return program; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Wrapper for creating a vertex buffer. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#createVertexBuffer + * @since 3.0.0 + * + * @param {ArrayBuffer} initialDataOrSize - It's either ArrayBuffer or an integer indicating the size of the vbo + * @param {number} bufferUsage - How the buffer is used. gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW + * + * @return {WebGLBuffer} Raw vertex buffer + */ + createVertexBuffer: function (initialDataOrSize, bufferUsage) + { + var gl = this.gl; + var vertexBuffer = gl.createBuffer(); -/** - * Generate a series of sine and cosine values. - * - * @function Phaser.Math.SinCosTableGenerator - * @since 3.0.0 - * - * @param {number} length - The number of values to generate. - * @param {number} [sinAmp=1] - The sine value amplitude. - * @param {number} [cosAmp=1] - The cosine value amplitude. - * @param {number} [frequency=1] - The frequency of the values. - * - * @return {Phaser.Types.Math.SinCosTable} The generated values. - */ -var SinCosTableGenerator = function (length, sinAmp, cosAmp, frequency) -{ - if (sinAmp === undefined) { sinAmp = 1; } - if (cosAmp === undefined) { cosAmp = 1; } - if (frequency === undefined) { frequency = 1; } + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, initialDataOrSize, bufferUsage); + gl.bindBuffer(gl.ARRAY_BUFFER, null); - frequency *= Math.PI / length; + return vertexBuffer; + }, - var cos = []; - var sin = []; + /** + * Wrapper for creating a vertex buffer. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#createIndexBuffer + * @since 3.0.0 + * + * @param {ArrayBuffer} initialDataOrSize - Either ArrayBuffer or an integer indicating the size of the vbo. + * @param {number} bufferUsage - How the buffer is used. gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW. + * + * @return {WebGLBuffer} Raw index buffer + */ + createIndexBuffer: function (initialDataOrSize, bufferUsage) + { + var gl = this.gl; + var indexBuffer = gl.createBuffer(); - for (var c = 0; c < length; c++) + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, initialDataOrSize, bufferUsage); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + + return indexBuffer; + }, + + /** + * Calls `GL.deleteTexture` on the given WebGLTexture and also optionally + * resets the currently defined textures. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#deleteTexture + * @since 3.0.0 + * + * @param {WebGLTexture} texture - The WebGL Texture to be deleted. + * + * @return {this} This WebGLRenderer instance. + */ + deleteTexture: function (texture) { - cosAmp -= sinAmp * frequency; - sinAmp += cosAmp * frequency; + if (texture) + { + this.gl.deleteTexture(texture); + } - cos[c] = cosAmp; - sin[c] = sinAmp; - } + return this; + }, - return { - sin: sin, - cos: cos, - length: length - }; -}; + /** + * Deletes a WebGLFramebuffer from the GL instance. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#deleteFramebuffer + * @since 3.0.0 + * + * @param {WebGLFramebuffer} framebuffer - The Framebuffer to be deleted. + * + * @return {this} This WebGLRenderer instance. + */ + deleteFramebuffer: function (framebuffer) + { + if (framebuffer) + { + var gl = this.gl; -module.exports = SinCosTableGenerator; + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + var renderBuffer = gl.getParameter(gl.RENDERBUFFER_BINDING); -/***/ }), -/* 858 */ -/***/ (function(module, exports, __webpack_require__) { + if (renderBuffer) + { + gl.deleteRenderbuffer(renderBuffer); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.bindFramebuffer(gl.FRAMEBUFFER, null); -var Vector2 = __webpack_require__(3); + gl.deleteFramebuffer(framebuffer); -/** - * Returns a Vector2 containing the x and y position of the given index in a `width` x `height` sized grid. - * - * For example, in a 6 x 4 grid, index 16 would equal x: 4 y: 2. - * - * If the given index is out of range an empty Vector2 is returned. - * - * @function Phaser.Math.ToXY - * @since 3.19.0 - * - * @param {number} index - The position within the grid to get the x/y value for. - * @param {number} width - The width of the grid. - * @param {number} height - The height of the grid. - * @param {Phaser.Math.Vector2} [out] - An optional Vector2 to store the result in. If not given, a new Vector2 instance will be created. - * - * @return {Phaser.Math.Vector2} A Vector2 where the x and y properties contain the given grid index. - */ -var ToXY = function (index, width, height, out) -{ - if (out === undefined) { out = new Vector2(); } + ArrayRemove(this.fboStack, framebuffer); - var x = 0; - var y = 0; - var total = width * height; + if (this.currentFramebuffer === framebuffer) + { + this.currentFramebuffer = null; + } + } - if (index > 0 && index <= total) + return this; + }, + + /** + * Deletes a WebGLProgram from the GL instance. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#deleteProgram + * @since 3.0.0 + * + * @param {WebGLProgram} program - The shader program to be deleted. + * + * @return {this} This WebGLRenderer instance. + */ + deleteProgram: function (program) { - if (index > width - 1) - { - y = Math.floor(index / width); - x = index - (y * width); - } - else + if (program) { - x = index; + this.gl.deleteProgram(program); } - } - return out.set(x, y); -}; + return this; + }, -module.exports = ToXY; + /** + * Deletes a WebGLBuffer from the GL instance. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#deleteBuffer + * @since 3.0.0 + * + * @param {WebGLBuffer} vertexBuffer - The WebGLBuffer to be deleted. + * + * @return {this} This WebGLRenderer instance. + */ + deleteBuffer: function (buffer) + { + this.gl.deleteBuffer(buffer); + return this; + }, -/***/ }), -/* 859 */ -/***/ (function(module, exports) { + /** + * Controls the pre-render operations for the given camera. + * Handles any clipping needed by the camera and renders the background color if a color is visible. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#preRenderCamera + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to pre-render. + */ + preRenderCamera: function (camera) + { + var cx = camera.x; + var cy = camera.y; + var cw = camera.width; + var ch = camera.height; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var color = camera.backgroundColor; -/** - * Checks if the two values are within the given `tolerance` of each other. - * - * @function Phaser.Math.Within - * @since 3.0.0 - * - * @param {number} a - The first value to use in the calculation. - * @param {number} b - The second value to use in the calculation. - * @param {number} tolerance - The tolerance. Anything equal to or less than this value is considered as being within range. - * - * @return {boolean} Returns `true` if `a` is less than or equal to the tolerance of `b`. - */ -var Within = function (a, b, tolerance) -{ - return (Math.abs(a - b) <= tolerance); -}; + camera.emit(CameraEvents.PRE_RENDER, camera); -module.exports = Within; + this.pipelines.preBatchCamera(camera); + this.pushScissor(cx, cy, cw, ch); -/***/ }), -/* 860 */ -/***/ (function(module, exports, __webpack_require__) { + if (camera.mask) + { + this.currentCameraMask.mask = camera.mask; + this.currentCameraMask.camera = camera._maskCamera; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + camera.mask.preRenderWebGL(this, camera, camera._maskCamera); + } -var Vector3 = __webpack_require__(39); -var Matrix4 = __webpack_require__(69); -var Quaternion = __webpack_require__(365); + if (color.alphaGL > 0) + { + var pipeline = this.pipelines.setMulti(); -var tmpMat4 = new Matrix4(); -var tmpQuat = new Quaternion(); -var tmpVec3 = new Vector3(); + pipeline.drawFillRect( + cx, cy, cw, ch, + Utils.getTintFromFloats(color.blueGL, color.greenGL, color.redGL, 1), + color.alphaGL + ); + } + }, -/** - * Rotates a vector in place by axis angle. - * - * This is the same as transforming a point by an - * axis-angle quaternion, but it has higher precision. - * - * @function Phaser.Math.RotateVec3 - * @since 3.0.0 - * - * @param {Phaser.Math.Vector3} vec - The vector to be rotated. - * @param {Phaser.Math.Vector3} axis - The axis to rotate around. - * @param {number} radians - The angle of rotation in radians. - * - * @return {Phaser.Math.Vector3} The given vector. - */ -var RotateVec3 = function (vec, axis, radians) -{ - // Set the quaternion to our axis angle - tmpQuat.setAxisAngle(axis, radians); + /** + * Return the current stencil mask. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#getCurrentStencilMask + * @private + * @since 3.50.0 + */ + getCurrentStencilMask: function () + { + var prev = null; + var stack = this.maskStack; + var cameraMask = this.currentCameraMask; - // Create a rotation matrix from the axis angle - tmpMat4.fromRotationTranslation(tmpQuat, tmpVec3.set(0, 0, 0)); + if (stack.length > 0) + { + prev = stack[stack.length - 1]; + } + else if (cameraMask.mask && cameraMask.mask.isStencil) + { + prev = cameraMask; + } - // Multiply our vector by the rotation matrix - return vec.transformMat4(tmpMat4); -}; + return prev; + }, -module.exports = RotateVec3; + /** + * Controls the post-render operations for the given camera. + * + * Renders the foreground camera effects like flash and fading, then resets the current scissor state. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#postRenderCamera + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to post-render. + */ + postRenderCamera: function (camera) + { + var flashEffect = camera.flashEffect; + var fadeEffect = camera.fadeEffect; + if (flashEffect.isRunning || (fadeEffect.isRunning || fadeEffect.isComplete)) + { + var pipeline = this.pipelines.setMulti(); -/***/ }), -/* 861 */ -/***/ (function(module, exports) { + flashEffect.postRenderWebGL(pipeline, Utils.getTintFromFloats); + fadeEffect.postRenderWebGL(pipeline, Utils.getTintFromFloats); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + camera.dirty = false; -/** - * The Texture Add Event. - * - * This event is dispatched by the Texture Manager when a texture is added to it. - * - * Listen to this event from within a Scene using: `this.textures.on('addtexture', listener)`. - * - * @event Phaser.Textures.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The key of the Texture that was added to the Texture Manager. - * @param {Phaser.Textures.Texture} texture - A reference to the Texture that was added to the Texture Manager. - */ -module.exports = 'addtexture'; + this.popScissor(); + if (camera.mask) + { + this.currentCameraMask.mask = null; -/***/ }), -/* 862 */ -/***/ (function(module, exports) { + camera.mask.postRenderWebGL(this, camera._maskCamera); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.pipelines.postBatchCamera(camera); -/** - * The Texture Load Error Event. - * - * This event is dispatched by the Texture Manager when a texture it requested to load failed. - * This only happens when base64 encoded textures fail. All other texture types are loaded via the Loader Plugin. - * - * Listen to this event from within a Scene using: `this.textures.on('onerror', listener)`. - * - * @event Phaser.Textures.Events#ERROR - * @since 3.0.0 - * - * @param {string} key - The key of the Texture that failed to load into the Texture Manager. - */ -module.exports = 'onerror'; + camera.emit(CameraEvents.POST_RENDER, camera); + }, + /** + * Clears the current vertex buffer and updates pipelines. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#preRender + * @fires Phaser.Renderer.Events#PRE_RENDER + * @since 3.0.0 + */ + preRender: function () + { + if (this.contextLost) { return; } -/***/ }), -/* 863 */ -/***/ (function(module, exports) { + var gl = this.gl; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Make sure we are bound to the main frame buffer + gl.bindFramebuffer(gl.FRAMEBUFFER, null); -/** - * The Texture Load Event. - * - * This event is dispatched by the Texture Manager when a texture has finished loading on it. - * This only happens for base64 encoded textures. All other texture types are loaded via the Loader Plugin. - * - * Listen to this event from within a Scene using: `this.textures.on('onload', listener)`. - * - * This event is dispatched after the [ADD]{@linkcode Phaser.Textures.Events#event:ADD} event. - * - * @event Phaser.Textures.Events#LOAD - * @since 3.0.0 - * - * @param {string} key - The key of the Texture that was loaded by the Texture Manager. - * @param {Phaser.Textures.Texture} texture - A reference to the Texture that was loaded by the Texture Manager. - */ -module.exports = 'onload'; + if (this.config.clearBeforeRender) + { + var clearColor = this.config.backgroundColor; + gl.clearColor(clearColor.redGL, clearColor.greenGL, clearColor.blueGL, clearColor.alphaGL); -/***/ }), -/* 864 */ -/***/ (function(module, exports) { + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.enable(gl.SCISSOR_TEST); -/** - * This internal event signifies that the Texture Manager is now ready and the Game can continue booting. - * - * When a Phaser Game instance is booting for the first time, the Texture Manager has to wait on a couple of non-blocking - * async events before it's fully ready to carry on. When those complete the Texture Manager emits this event via the Game - * instance, which tells the Game to carry on booting. - * - * @event Phaser.Textures.Events#READY - * @since 3.16.1 - */ -module.exports = 'ready'; + this.currentScissor = this.defaultScissor; + this.scissorStack.length = 0; + this.scissorStack.push(this.currentScissor); -/***/ }), -/* 865 */ -/***/ (function(module, exports) { + if (this.game.scene.customViewports) + { + gl.scissor(0, (this.drawingBufferHeight - this.height), this.width, this.height); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.currentMask.mask = null; + this.currentCameraMask.mask = null; + this.maskStack.length = 0; -/** - * The Texture Remove Event. - * - * This event is dispatched by the Texture Manager when a texture is removed from it. - * - * Listen to this event from within a Scene using: `this.textures.on('removetexture', listener)`. - * - * If you have any Game Objects still using the removed texture, they will start throwing - * errors the next time they try to render. Be sure to clear all use of the texture in this event handler. - * - * @event Phaser.Textures.Events#REMOVE - * @since 3.0.0 - * - * @param {string} key - The key of the Texture that was removed from the Texture Manager. - */ -module.exports = 'removetexture'; + this.emit(Events.PRE_RENDER); + }, + + /** + * The core render step for a Scene Camera. + * + * Iterates through the given array of Game Objects and renders them with the given Camera. + * + * This is called by the `CameraManager.render` method. The Camera Manager instance belongs to a Scene, and is invoked + * by the Scene Systems.render method. + * + * This method is not called if `Camera.visible` is `false`, or `Camera.alpha` is zero. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#render + * @fires Phaser.Renderer.Events#RENDER + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene to render. + * @param {Phaser.GameObjects.GameObject[]} children - An array of filtered Game Objects that can be rendered by the given Camera. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera to render with. + */ + render: function (scene, children, camera) + { + if (this.contextLost) { return; } + var childCount = children.length; -/***/ }), -/* 866 */ -/***/ (function(module, exports) { + this.emit(Events.RENDER, scene, camera); -module.exports = [ - '#define SHADER_NAME PHASER_BITMAP_MASK_FS', - '', - 'precision mediump float;', - '', - 'uniform vec2 uResolution;', - 'uniform sampler2D uMainSampler;', - 'uniform sampler2D uMaskSampler;', - 'uniform bool uInvertMaskAlpha;', - '', - 'void main ()', - '{', - ' vec2 uv = gl_FragCoord.xy / uResolution;', - ' vec4 mainColor = texture2D(uMainSampler, uv);', - ' vec4 maskColor = texture2D(uMaskSampler, uv);', - ' float alpha = mainColor.a;', - '', - ' if (!uInvertMaskAlpha)', - ' {', - ' alpha *= (maskColor.a);', - ' }', - ' else', - ' {', - ' alpha *= (1.0 - maskColor.a);', - ' }', - '', - ' gl_FragColor = vec4(mainColor.rgb * alpha, alpha);', - '}', - '' -].join('\n'); + // Apply scissor for cam region + render background color, if not transparent + this.preRenderCamera(camera); + // Nothing to render, so bail out + if (childCount === 0) + { + this.setBlendMode(CONST.BlendModes.NORMAL); -/***/ }), -/* 867 */ -/***/ (function(module, exports) { + // Applies camera effects and pops the scissor, if set + this.postRenderCamera(camera); -module.exports = [ - '#define SHADER_NAME PHASER_BITMAP_MASK_VS', - '', - 'precision mediump float;', - '', - 'attribute vec2 inPosition;', - '', - 'void main ()', - '{', - ' gl_Position = vec4(inPosition, 0.0, 1.0);', - '}', - '' -].join('\n'); + return; + } + // Reset the current type + this.currentType = ''; -/***/ }), -/* 868 */ -/***/ (function(module, exports) { + var current = this.currentMask; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + for (var i = 0; i < childCount; i++) + { + this.finalType = (i === childCount - 1); -/** - * The WebGLPipeline After Flush Event. - * - * This event is dispatched by a WebGLPipeline right after it has issued a drawArrays command - * and cleared its vertex count. - * - * @event Phaser.Renderer.WebGL.Pipelines.Events#AFTER_FLUSH - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that has flushed. - * @param {boolean} isPostFlush - Was this flush invoked as part of a post-process, or not? - */ -module.exports = 'pipelineafterflush'; + var child = children[i]; + var mask = child.mask; -/***/ }), -/* 869 */ -/***/ (function(module, exports) { + current = this.currentMask; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (current.mask && current.mask !== mask) + { + // Render out the previously set mask + current.mask.postRenderWebGL(this, current.camera); + } -/** - * The WebGLPipeline Before Flush Event. - * - * This event is dispatched by a WebGLPipeline right before it is about to - * flush and issue a bufferData and drawArrays command. - * - * @event Phaser.Renderer.WebGL.Pipelines.Events#BEFORE_FLUSH - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that is about to flush. - * @param {boolean} isPostFlush - Was this flush invoked as part of a post-process, or not? - */ -module.exports = 'pipelinebeforeflush'; + if (mask && current.mask !== mask) + { + mask.preRenderWebGL(this, child, camera); + } + if (child.blendMode !== this.currentBlendMode) + { + this.setBlendMode(child.blendMode); + } -/***/ }), -/* 870 */ -/***/ (function(module, exports) { + var type = child.type; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (type !== this.currentType) + { + this.newType = true; + this.currentType = type; + } -/** - * The WebGLPipeline Bind Event. - * - * This event is dispatched by a WebGLPipeline when it is bound by the Pipeline Manager. - * - * @event Phaser.Renderer.WebGL.Pipelines.Events#BIND - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that was bound. - * @param {Phaser.Renderer.WebGL.WebGLShader} currentShader - The shader that was set as being current. - */ -module.exports = 'pipelinebind'; + if (!this.finalType) + { + this.nextTypeMatch = (children[i + 1].type === this.currentType); + } + else + { + this.nextTypeMatch = false; + } + child.renderWebGL(this, child, camera); -/***/ }), -/* 871 */ -/***/ (function(module, exports) { + this.newType = false; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + current = this.currentMask; -/** - * The WebGLPipeline Boot Event. - * - * This event is dispatched by a WebGLPipeline when it has completed its `boot` phase. - * - * @event Phaser.Renderer.WebGL.Pipelines.Events#BOOT - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that booted. - */ -module.exports = 'pipelineboot'; + if (current.mask) + { + // Render out the previously set mask, if it was the last item in the display list + current.mask.postRenderWebGL(this, current.camera); + } + this.setBlendMode(CONST.BlendModes.NORMAL); -/***/ }), -/* 872 */ -/***/ (function(module, exports) { + // Applies camera effects and pops the scissor, if set + this.postRenderCamera(camera); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The post-render step happens after all Cameras in all Scenes have been rendered. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#postRender + * @fires Phaser.Renderer.Events#POST_RENDER + * @since 3.0.0 + */ + postRender: function () + { + if (this.contextLost) { return; } -/** - * The WebGLPipeline Destroy Event. - * - * This event is dispatched by a WebGLPipeline when it is starting its destroy process. - * - * @event Phaser.Renderer.WebGL.Pipelines.Events#DESTROY - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that has flushed. - */ -module.exports = 'pipelinedestroy'; + this.flush(); + this.emit(Events.POST_RENDER); -/***/ }), -/* 873 */ -/***/ (function(module, exports) { + var state = this.snapshotState; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (state.callback) + { + WebGLSnapshot(this.gl, state); -/** - * The WebGLPipeline ReBind Event. - * - * This event is dispatched by a WebGLPipeline when it is re-bound by the Pipeline Manager. - * - * @event Phaser.Renderer.WebGL.Pipelines.Events#REBIND - * @since 3.50.0 - * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that was rebound. - * @param {Phaser.Renderer.WebGL.WebGLShader} currentShader - The shader that was set as being current. - */ -module.exports = 'pipelinerebind'; + state.callback = null; + } + }, + /** + * Disables the STENCIL_TEST but does not change the status + * of the current stencil mask. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#clearStencilMask + * @since 3.60.0 + */ + clearStencilMask: function () + { + this.gl.disable(this.gl.STENCIL_TEST); + }, -/***/ }), -/* 874 */ -/***/ (function(module, exports) { + /** + * Restores the current stencil function to the one that was in place + * before `clearStencilMask` was called. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#restoreStencilMask + * @since 3.60.0 + */ + restoreStencilMask: function () + { + var gl = this.gl; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var current = this.getCurrentStencilMask(); -/** - * The WebGLPipeline Resize Event. - * - * This event is dispatched by a WebGLPipeline when it is resized, usually as a result - * of the Renderer resizing. - * - * @event Phaser.Renderer.WebGL.Pipelines.Events#RESIZE - * @since 3.50.0 - * - * @param {number} width - The new width of the pipeline. - * @param {number} height - The new height of the pipeline. - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that was resized. - */ -module.exports = 'pipelineresize'; + if (current) + { + var mask = current.mask; + gl.enable(gl.STENCIL_TEST); -/***/ }), -/* 875 */ -/***/ (function(module, exports) { + // colorMask + stencilOp(KEEP) -module.exports = [ - '#define SHADER_NAME PHASER_GRAPHICS_FS', - '', - 'precision mediump float;', - '', - 'varying vec4 outColor;', - '', - 'void main ()', - '{', - ' gl_FragColor = vec4(outColor.bgr * outColor.a, outColor.a);', - '}', - '' -].join('\n'); + if (mask.invertAlpha) + { + gl.stencilFunc(gl.NOTEQUAL, mask.level, 0xff); + } + else + { + gl.stencilFunc(gl.EQUAL, mask.level, 0xff); + } + } + }, + /** + * Schedules a snapshot of the entire game viewport to be taken after the current frame is rendered. + * + * To capture a specific area see the `snapshotArea` method. To capture a specific pixel, see `snapshotPixel`. + * + * Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then + * calling this method will override it. + * + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. + * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, + * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, + * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#snapshot + * @since 3.0.0 + * + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This WebGL Renderer. + */ + snapshot: function (callback, type, encoderOptions) + { + return this.snapshotArea(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight, callback, type, encoderOptions); + }, -/***/ }), -/* 876 */ -/***/ (function(module, exports) { + /** + * Schedules a snapshot of the given area of the game viewport to be taken after the current frame is rendered. + * + * To capture the whole game viewport see the `snapshot` method. To capture a specific pixel, see `snapshotPixel`. + * + * Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then + * calling this method will override it. + * + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. + * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, + * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, + * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#snapshotArea + * @since 3.16.0 + * + * @param {number} x - The x coordinate to grab from. This is based on the game viewport, not the world. + * @param {number} y - The y coordinate to grab from. This is based on the game viewport, not the world. + * @param {number} width - The width of the area to grab. + * @param {number} height - The height of the area to grab. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This WebGL Renderer. + */ + snapshotArea: function (x, y, width, height, callback, type, encoderOptions) + { + var state = this.snapshotState; -module.exports = [ - '#define SHADER_NAME PHASER_GRAPHICS_VS', - '', - 'precision mediump float;', - '', - 'uniform mat4 uProjectionMatrix;', - '', - 'attribute vec2 inPosition;', - 'attribute vec4 inColor;', - '', - 'varying vec4 outColor;', - '', - 'void main ()', - '{', - ' gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);', - '', - ' outColor = inColor;', - '}', - '' -].join('\n'); + state.callback = callback; + state.type = type; + state.encoder = encoderOptions; + state.getPixel = false; + state.x = x; + state.y = y; + state.width = width; + state.height = height; + return this; + }, -/***/ }), -/* 877 */ -/***/ (function(module, exports) { + /** + * Schedules a snapshot of the given pixel from the game viewport to be taken after the current frame is rendered. + * + * To capture the whole game viewport see the `snapshot` method. To capture a specific area, see `snapshotArea`. + * + * Only one snapshot can be active _per frame_. If you have already called `snapshotArea`, for example, then + * calling this method will override it. + * + * Unlike the other two snapshot methods, this one will return a `Color` object containing the color data for + * the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute, + * using less memory. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#snapshotPixel + * @since 3.16.0 + * + * @param {number} x - The x coordinate of the pixel to get. This is based on the game viewport, not the world. + * @param {number} y - The y coordinate of the pixel to get. This is based on the game viewport, not the world. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted. + * + * @return {this} This WebGL Renderer. + */ + snapshotPixel: function (x, y, callback) + { + this.snapshotArea(x, y, 1, 1, callback); -module.exports = [ - '#define SHADER_NAME PHASER_LIGHT_FS', - '', - 'precision mediump float;', - '', - 'struct Light', - '{', - ' vec2 position;', - ' vec3 color;', - ' float intensity;', - ' float radius;', - '};', - '', - 'const int kMaxLights = %LIGHT_COUNT%;', - '', - 'uniform vec4 uCamera; /* x, y, rotation, zoom */', - 'uniform vec2 uResolution;', - 'uniform sampler2D uMainSampler;', - 'uniform sampler2D uNormSampler;', - 'uniform vec3 uAmbientLightColor;', - 'uniform Light uLights[kMaxLights];', - 'uniform mat3 uInverseRotationMatrix;', - '', - 'varying vec2 outTexCoord;', - 'varying vec4 outTint;', - '', - 'void main()', - '{', - ' vec3 finalColor = vec3(0.0, 0.0, 0.0);', - ' vec4 color = texture2D(uMainSampler, outTexCoord) * vec4(outTint.bgr * outTint.a, outTint.a);', - ' vec3 normalMap = texture2D(uNormSampler, outTexCoord).rgb;', - ' vec3 normal = normalize(uInverseRotationMatrix * vec3(normalMap * 2.0 - 1.0));', - ' vec2 res = vec2(min(uResolution.x, uResolution.y)) * uCamera.w;', - '', - ' for (int index = 0; index < kMaxLights; ++index)', - ' {', - ' Light light = uLights[index];', - ' vec3 lightDir = vec3((light.position.xy / res) - (gl_FragCoord.xy / res), 0.1);', - ' vec3 lightNormal = normalize(lightDir);', - ' float distToSurf = length(lightDir) * uCamera.w;', - ' float diffuseFactor = max(dot(normal, lightNormal), 0.0);', - ' float radius = (light.radius / res.x * uCamera.w) * uCamera.w;', - ' float attenuation = clamp(1.0 - distToSurf * distToSurf / (radius * radius), 0.0, 1.0);', - ' vec3 diffuse = light.color * diffuseFactor;', - ' finalColor += (attenuation * diffuse) * light.intensity;', - ' }', - '', - ' vec4 colorOutput = vec4(uAmbientLightColor + finalColor, 1.0);', - '', - ' gl_FragColor = color * vec4(colorOutput.rgb * colorOutput.a, colorOutput.a);', - '}', - '' -].join('\n'); + this.snapshotState.getPixel = true; + return this; + }, -/***/ }), -/* 878 */ -/***/ (function(module, exports) { + /** + * Takes a snapshot of the given area of the given frame buffer. + * + * Unlike the other snapshot methods, this one is processed immediately and doesn't wait for the next render. + * + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. + * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, + * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, + * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#snapshotFramebuffer + * @since 3.19.0 + * + * @param {WebGLFramebuffer} framebuffer - The framebuffer to grab from. + * @param {number} bufferWidth - The width of the framebuffer. + * @param {number} bufferHeight - The height of the framebuffer. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {boolean} [getPixel=false] - Grab a single pixel as a Color object, or an area as an Image object? + * @param {number} [x=0] - The x coordinate to grab from. This is based on the framebuffer, not the world. + * @param {number} [y=0] - The y coordinate to grab from. This is based on the framebuffer, not the world. + * @param {number} [width=bufferWidth] - The width of the area to grab. + * @param {number} [height=bufferHeight] - The height of the area to grab. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This WebGL Renderer. + */ + snapshotFramebuffer: function (framebuffer, bufferWidth, bufferHeight, callback, getPixel, x, y, width, height, type, encoderOptions) + { + if (getPixel === undefined) { getPixel = false; } + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = bufferWidth; } + if (height === undefined) { height = bufferHeight; } -module.exports = [ - '#define SHADER_NAME PHASER_MULTI_FS', - '', - 'precision mediump float;', - '', - 'uniform sampler2D uMainSampler[%count%];', - '', - 'varying vec2 outTexCoord;', - 'varying float outTexId;', - 'varying float outTintEffect;', - 'varying vec4 outTint;', - '', - 'void main ()', - '{', - ' vec4 texture;', - '', - ' %forloop%', - '', - ' vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);', - '', - ' // Multiply texture tint', - ' vec4 color = texture * texel;', - '', - ' if (outTintEffect == 1.0)', - ' {', - ' // Solid color + texture alpha', - ' color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);', - ' }', - ' else if (outTintEffect == 2.0)', - ' {', - ' // Solid color, no texture', - ' color = texel;', - ' }', - '', - ' gl_FragColor = color;', - '}', - '' -].join('\n'); + if (type === 'pixel') + { + getPixel = true; + type = 'image/png'; + } + var currentFramebuffer = this.currentFramebuffer; -/***/ }), -/* 879 */ -/***/ (function(module, exports) { + this.snapshotArea(x, y, width, height, callback, type, encoderOptions); -module.exports = [ - '#define SHADER_NAME PHASER_MULTI_VS', - '', - 'precision mediump float;', - '', - 'uniform mat4 uProjectionMatrix;', - '', - 'attribute vec2 inPosition;', - 'attribute vec2 inTexCoord;', - 'attribute float inTexId;', - 'attribute float inTintEffect;', - 'attribute vec4 inTint;', - '', - 'varying vec2 outTexCoord;', - 'varying float outTexId;', - 'varying float outTintEffect;', - 'varying vec4 outTint;', - '', - 'void main ()', - '{', - ' gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);', - '', - ' outTexCoord = inTexCoord;', - ' outTexId = inTexId;', - ' outTint = inTint;', - ' outTintEffect = inTintEffect;', - '}', - '' -].join('\n'); + var state = this.snapshotState; + state.getPixel = getPixel; -/***/ }), -/* 880 */ -/***/ (function(module, exports) { + state.isFramebuffer = true; + state.bufferWidth = bufferWidth; + state.bufferHeight = bufferHeight; -module.exports = [ - '#define SHADER_NAME PHASER_POINTLIGHT_FS', - '', - 'precision mediump float;', - '', - 'uniform vec2 uResolution;', - 'uniform float uCameraZoom;', - '', - 'varying vec4 lightPosition;', - 'varying vec4 lightColor;', - 'varying float lightRadius;', - 'varying float lightAttenuation;', - '', - 'void main ()', - '{', - ' vec2 center = (lightPosition.xy + 1.0) * (uResolution.xy * 0.5);', - '', - ' float distToSurf = length(center - gl_FragCoord.xy);', - '', - ' float radius = 1.0 - distToSurf / (lightRadius * uCameraZoom);', - '', - ' float intensity = smoothstep(0.0, 1.0, radius * lightAttenuation);', - '', - ' vec4 color = vec4(intensity, intensity, intensity, 0.0) * lightColor;', - '', - ' gl_FragColor = vec4(color.rgb * lightColor.a, color.a);', - '}', - '' -].join('\n'); + // Ensure they're not trying to grab an area larger than the framebuffer + state.width = Math.min(state.width, bufferWidth); + state.height = Math.min(state.height, bufferHeight); + this.setFramebuffer(framebuffer); -/***/ }), -/* 881 */ -/***/ (function(module, exports) { + WebGLSnapshot(this.gl, state); -module.exports = [ - '#define SHADER_NAME PHASER_POINTLIGHT_VS', - '', - 'precision mediump float;', - '', - 'uniform mat4 uProjectionMatrix;', - '', - 'attribute vec2 inPosition;', - 'attribute vec2 inLightPosition;', - 'attribute vec4 inLightColor;', - 'attribute float inLightRadius;', - 'attribute float inLightAttenuation;', - '', - 'varying vec4 lightPosition;', - 'varying vec4 lightColor;', - 'varying float lightRadius;', - 'varying float lightAttenuation;', - '', - 'void main ()', - '{', - ' lightColor = inLightColor;', - ' lightRadius = inLightRadius;', - ' lightAttenuation = inLightAttenuation;', - ' lightPosition = uProjectionMatrix * vec4(inLightPosition, 1.0, 1.0);', - '', - ' gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);', - '}', - '' -].join('\n'); + this.setFramebuffer(currentFramebuffer); + state.callback = null; + state.isFramebuffer = false; -/***/ }), -/* 882 */ -/***/ (function(module, exports) { + return this; + }, -module.exports = [ - '#define SHADER_NAME PHASER_SINGLE_FS', - '', - 'precision mediump float;', - '', - 'uniform sampler2D uMainSampler;', - '', - 'varying vec2 outTexCoord;', - 'varying float outTintEffect;', - 'varying vec4 outTint;', - '', - 'void main ()', - '{', - ' vec4 texture = texture2D(uMainSampler, outTexCoord);', - ' vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);', - '', - ' // Multiply texture tint', - ' vec4 color = texture * texel;', - '', - ' if (outTintEffect == 1.0)', - ' {', - ' // Solid color + texture alpha', - ' color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);', - ' }', - ' else if (outTintEffect == 2.0)', - ' {', - ' // Solid color, no texture', - ' color = texel;', - ' }', - '', - ' gl_FragColor = color;', - '}', - '' -].join('\n'); + /** + * Creates a new WebGL Texture based on the given Canvas Element. + * + * If the `dstTexture` parameter is given, the WebGL Texture is updated, rather than created fresh. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#canvasToTexture + * @since 3.0.0 + * + * @param {HTMLCanvasElement} srcCanvas - The Canvas to create the WebGL Texture from + * @param {WebGLTexture} [dstTexture] - The destination WebGL Texture to set. + * @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT` (such as for Text objects?) + * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? + * + * @return {WebGLTexture} The newly created, or updated, WebGL Texture. + */ + canvasToTexture: function (srcCanvas, dstTexture, noRepeat, flipY) + { + if (noRepeat === undefined) { noRepeat = false; } + if (flipY === undefined) { flipY = false; } + if (!dstTexture) + { + return this.createCanvasTexture(srcCanvas, noRepeat, flipY); + } + else + { + return this.updateCanvasTexture(srcCanvas, dstTexture, flipY); + } + }, -/***/ }), -/* 883 */ -/***/ (function(module, exports) { + /** + * Creates a new WebGL Texture based on the given Canvas Element. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#createCanvasTexture + * @since 3.20.0 + * + * @param {HTMLCanvasElement} srcCanvas - The Canvas to create the WebGL Texture from. + * @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT` (such as for Text objects?) + * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? + * + * @return {WebGLTexture} The newly created WebGL Texture. + */ + createCanvasTexture: function (srcCanvas, noRepeat, flipY) + { + if (noRepeat === undefined) { noRepeat = false; } + if (flipY === undefined) { flipY = false; } -module.exports = [ - '#define SHADER_NAME PHASER_SINGLE_VS', - '', - 'precision mediump float;', - '', - 'uniform mat4 uProjectionMatrix;', - '', - 'attribute vec2 inPosition;', - 'attribute vec2 inTexCoord;', - 'attribute float inTexId;', - 'attribute float inTintEffect;', - 'attribute vec4 inTint;', - '', - 'varying vec2 outTexCoord;', - 'varying float outTintEffect;', - 'varying vec4 outTint;', - '', - 'void main ()', - '{', - ' gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);', - '', - ' outTexCoord = inTexCoord;', - ' outTint = inTint;', - ' outTintEffect = inTintEffect;', - '}', - '' -].join('\n'); + var gl = this.gl; + var minFilter = gl.NEAREST; + var magFilter = gl.NEAREST; + var width = srcCanvas.width; + var height = srcCanvas.height; -/***/ }), -/* 884 */ -/***/ (function(module, exports) { + var wrapping = gl.CLAMP_TO_EDGE; -module.exports = [ - '#define SHADER_NAME PHASER_ADD_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 = frame1 + frame2 * uStrength;', - '}', - '' -].join('\n'); + var pow = IsSizePowerOfTwo(width, height); + if (!noRepeat && pow) + { + wrapping = gl.REPEAT; + } -/***/ }), -/* 885 */ -/***/ (function(module, exports) { + if (this.config.antialias) + { + minFilter = (pow && this.mipmapFilter) ? this.mipmapFilter : gl.LINEAR; + magFilter = gl.LINEAR; + } -module.exports = [ - '#define SHADER_NAME PHASER_COLORMATRIX_FS', - '', - 'precision mediump float;', - '', - 'uniform sampler2D uMainSampler;', - 'uniform float uColorMatrix[20];', - 'uniform float uAlpha;', - '', - 'varying vec2 outTexCoord;', - '', - 'void main ()', - '{', - ' vec4 c = texture2D(uMainSampler, outTexCoord);', - '', - ' if (uAlpha == 0.0)', - ' {', - ' gl_FragColor = c;', - '', - ' return;', - ' }', - '', - ' if (c.a > 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'); + return this.createTexture2D(0, minFilter, magFilter, wrapping, wrapping, gl.RGBA, srcCanvas, width, height, true, false, flipY); + }, + /** + * Updates a WebGL Texture based on the given Canvas Element. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#updateCanvasTexture + * @since 3.20.0 + * + * @param {HTMLCanvasElement} srcCanvas - The Canvas to update the WebGL Texture from. + * @param {WebGLTexture} dstTexture - The destination WebGL Texture to update. + * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? + * + * @return {WebGLTexture} The updated WebGL Texture. + */ + updateCanvasTexture: function (srcCanvas, dstTexture, flipY) + { + if (flipY === undefined) { flipY = false; } -/***/ }), -/* 886 */ -/***/ (function(module, exports) { + var gl = this.gl; -module.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'); + var width = srcCanvas.width; + var height = srcCanvas.height; + if (width > 0 && height > 0) + { + gl.activeTexture(gl.TEXTURE0); + var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D); + gl.bindTexture(gl.TEXTURE_2D, dstTexture); -/***/ }), -/* 887 */ -/***/ (function(module, exports) { + if (flipY) + { + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + } -module.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'); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas); -/***/ }), -/* 888 */ -/***/ (function(module, exports, __webpack_require__) { + dstTexture.width = width; + dstTexture.height = height; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (currentTexture) + { + gl.bindTexture(gl.TEXTURE_2D, currentTexture); + } + } -/** - * @namespace Phaser.Create - */ + return dstTexture; + }, -module.exports = { - - GenerateTexture: __webpack_require__(388), - Palettes: __webpack_require__(889) + /** + * Creates a new WebGL Texture based on the given HTML Video Element. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#createVideoTexture + * @since 3.20.0 + * + * @param {HTMLVideoElement} srcVideo - The Video to create the WebGL Texture from + * @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT`? + * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? + * + * @return {WebGLTexture} The newly created WebGL Texture. + */ + createVideoTexture: function (srcVideo, noRepeat, flipY) + { + if (noRepeat === undefined) { noRepeat = false; } + if (flipY === undefined) { flipY = false; } -}; + var gl = this.gl; + var minFilter = gl.NEAREST; + var magFilter = gl.NEAREST; + var width = srcVideo.videoWidth; + var height = srcVideo.videoHeight; -/***/ }), -/* 889 */ -/***/ (function(module, exports, __webpack_require__) { + var wrapping = gl.CLAMP_TO_EDGE; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var pow = IsSizePowerOfTwo(width, height); -/** - * @namespace Phaser.Create.Palettes - */ + if (!noRepeat && pow) + { + wrapping = gl.REPEAT; + } -module.exports = { + if (this.config.antialias) + { + minFilter = (pow && this.mipmapFilter) ? this.mipmapFilter : gl.LINEAR; + magFilter = gl.LINEAR; + } - ARNE16: __webpack_require__(389), - C64: __webpack_require__(890), - CGA: __webpack_require__(891), - JMP: __webpack_require__(892), - MSX: __webpack_require__(893) + return this.createTexture2D(0, minFilter, magFilter, wrapping, wrapping, gl.RGBA, srcVideo, width, height, true, true, flipY); + }, -}; + /** + * Updates a WebGL Texture based on the given HTML Video Element. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#updateVideoTexture + * @since 3.20.0 + * + * @param {HTMLVideoElement} srcVideo - The Video to update the WebGL Texture with. + * @param {WebGLTexture} dstTexture - The destination WebGL Texture to update. + * @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? + * + * @return {WebGLTexture} The updated WebGL Texture. + */ + updateVideoTexture: function (srcVideo, dstTexture, flipY) + { + if (flipY === undefined) { flipY = false; } + var gl = this.gl; -/***/ }), -/* 890 */ -/***/ (function(module, exports) { + var width = srcVideo.videoWidth; + var height = srcVideo.videoHeight; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (width > 0 && height > 0) + { + gl.activeTexture(gl.TEXTURE0); + var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D); + gl.bindTexture(gl.TEXTURE_2D, dstTexture); -/** - * A 16 color palette inspired by the Commodore 64. - * - * @name Phaser.Create.Palettes.C64 - * @since 3.0.0 - * - * @type {Phaser.Types.Create.Palette} - */ -module.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' -}; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, srcVideo); -/***/ }), -/* 891 */ -/***/ (function(module, exports) { + dstTexture.width = width; + dstTexture.height = height; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (currentTexture) + { + gl.bindTexture(gl.TEXTURE_2D, currentTexture); + } + } -/** - * A 16 color CGA inspired palette by [Arne](http://androidarts.com/palette/16pal.htm) - * - * @name Phaser.Create.Palettes.CGA - * @since 3.0.0 - * - * @type {Phaser.Types.Create.Palette} - */ -module.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' -}; + return dstTexture; + }, + /** + * Sets the minification and magnification filter for a texture. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#setTextureFilter + * @since 3.0.0 + * + * @param {number} texture - The texture to set the filter for. + * @param {number} filter - The filter to set. 0 for linear filtering, 1 for nearest neighbor (blocky) filtering. + * + * @return {this} This WebGL Renderer instance. + */ + setTextureFilter: function (texture, filter) + { + var gl = this.gl; + var glFilter = [ gl.LINEAR, gl.NEAREST ][filter]; -/***/ }), -/* 892 */ -/***/ (function(module, exports) { + gl.activeTexture(gl.TEXTURE0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D); -/** - * A 16 color JMP palette by [Arne](http://androidarts.com/palette/16pal.htm) - * - * @name Phaser.Create.Palettes.JMP - * @since 3.0.0 - * - * @type {Phaser.Types.Create.Palette} - */ -module.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' -}; + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter); -/***/ }), -/* 893 */ -/***/ (function(module, exports) { + if (currentTexture) + { + gl.bindTexture(gl.TEXTURE_2D, currentTexture); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * A 16 color palette inspired by Japanese computers like the MSX. - * - * @name Phaser.Create.Palettes.MSX - * @since 3.0.0 - * - * @type {Phaser.Types.Create.Palette} - */ -module.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' -}; + /** + * Returns the largest texture size (either width or height) that can be created. + * Note that VRAM may not allow a texture of any given size, it just expresses + * hardware / driver support for a given size. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#getMaxTextureSize + * @since 3.8.0 + * + * @return {number} The maximum supported texture size. + */ + getMaxTextureSize: function () + { + return this.config.maxTextureSize; + }, + /** + * Destroy this WebGLRenderer, cleaning up all related resources such as pipelines, native textures, etc. + * + * @method Phaser.Renderer.WebGL.WebGLRenderer#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.canvas.removeEventListener('webglcontextlost', this.contextLostHandler, false); -/***/ }), -/* 894 */ -/***/ (function(module, exports, __webpack_require__) { + this.maskTarget.destroy(); + this.maskSource.destroy(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.pipelines.destroy(); + + this.removeAllListeners(); + + this.fboStack = []; + this.maskStack = []; + this.extensions = {}; + this.textureIndexes = []; + + this.gl = null; + this.game = null; + this.canvas = null; + this.contextLost = true; + this.currentMask = null; + this.currentCameraMask = null; -/** - * @namespace Phaser.Curves - */ + if (DEBUG) + { + this.spector = null; + } + } -module.exports = { - Path: __webpack_require__(895), - MoveTo: __webpack_require__(393), +}); - CubicBezier: __webpack_require__(390), - Curve: __webpack_require__(94), - Ellipse: __webpack_require__(391), - Line: __webpack_require__(392), - QuadraticBezier: __webpack_require__(394), - Spline: __webpack_require__(395) -}; +module.exports = WebGLRenderer; /***/ }), -/* 895 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71305: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 CubicBezierCurve = __webpack_require__(390); -var EllipseCurve = __webpack_require__(391); -var GameObjectFactory = __webpack_require__(5); -var LineCurve = __webpack_require__(392); -var MovePathTo = __webpack_require__(393); -var QuadraticBezierCurve = __webpack_require__(394); -var Rectangle = __webpack_require__(10); -var SplineCurve = __webpack_require__(395); -var Vector2 = __webpack_require__(3); -var MATH_CONST = __webpack_require__(14); +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var WEBGL_CONST = __webpack_require__(71402); /** * @classdesc - * A Path combines multiple Curves into one continuous compound curve. - * It does not matter how many Curves are in the Path or what type they are. + * Instances of the WebGLShader class belong to the WebGL Pipeline classes. When the pipeline is + * created it will create an instance of this class for each one of its shaders, as defined in + * the pipeline configuration. * - * A Curve in a Path does not have to start where the previous Curve ends - that is to say, a Path does not - * have to be an uninterrupted curve. Only the order of the Curves influences the actual points on the Path. + * This class encapsulates everything needed to manage a shader in a pipeline, including the + * shader attributes and uniforms, as well as lots of handy methods such as `set2f`, for setting + * uniform values on this shader. * - * @class Path - * @memberof Phaser.Curves + * Typically, you do not create an instance of this class directly, as it works in unison with + * the pipeline to which it belongs. You can gain access to this class via a pipeline's `shaders` + * array, post-creation. + * + * @class WebGLShader + * @memberof Phaser.Renderer.WebGL * @constructor - * @since 3.0.0 + * @since 3.50.0 * - * @param {number} [x=0] - The X coordinate of the Path's starting point or a {@link Phaser.Types.Curves.JSONPath}. - * @param {number} [y=0] - The Y coordinate of the Path's starting point. + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The WebGLPipeline to which this Shader belongs. + * @param {string} name - The name of this Shader. + * @param {string} vertexShader - The vertex shader source code as a single string. + * @param {string} fragmentShader - The fragment shader source code as a single string. + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineAttributeConfig[]} attributes - An array of attributes. */ -var Path = new Class({ +var WebGLShader = new Class({ initialize: - function Path (x, y) + function WebGLShader (pipeline, name, vertexShader, fragmentShader, attributes) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } + /** + * A reference to the WebGLPipeline that owns this Shader. + * + * A Shader class can only belong to a single pipeline. + * + * @name Phaser.Renderer.WebGL.WebGLShader#pipeline + * @type {Phaser.Renderer.WebGL.WebGLPipeline} + * @since 3.50.0 + */ + this.pipeline = pipeline; /** - * The name of this Path. - * Empty by default and never populated by Phaser, this is left for developers to use. + * The name of this shader. * - * @name Phaser.Curves.Path#name + * @name Phaser.Renderer.WebGL.WebGLShader#name * @type {string} - * @default '' - * @since 3.0.0 + * @since 3.50.0 */ - this.name = ''; + this.name = name; /** - * The list of Curves which make up this Path. + * A reference to the WebGLRenderer instance. * - * @name Phaser.Curves.Path#curves - * @type {Phaser.Curves.Curve[]} - * @default [] - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.WebGLShader#renderer + * @type {Phaser.Renderer.WebGL.WebGLRenderer} + * @since 3.50.0 */ - this.curves = []; + this.renderer = pipeline.renderer; /** - * The cached length of each Curve in the Path. + * A reference to the WebGL Rendering Context the WebGL Renderer is using. * - * Used internally by {@link #getCurveLengths}. + * @name Phaser.Renderer.WebGL.WebGLShader#gl + * @type {WebGLRenderingContext} + * @since 3.50.0 + */ + this.gl = this.renderer.gl; + + /** + * The fragment shader source code. * - * @name Phaser.Curves.Path#cacheLengths - * @type {number[]} - * @default [] - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.WebGLShader#fragSrc + * @type {string} + * @since 3.60.0 */ - this.cacheLengths = []; + this.fragSrc = fragmentShader; /** - * Automatically closes the path. + * The vertex shader source code. * - * @name Phaser.Curves.Path#autoClose - * @type {boolean} - * @default false - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.WebGLShader#vertSrc + * @type {string} + * @since 3.60.0 */ - this.autoClose = false; + this.vertSrc = vertexShader; /** - * The starting point of the Path. + * The WebGLProgram created from the vertex and fragment shaders. * - * This is not necessarily equivalent to the starting point of the first Curve in the Path. In an empty Path, it's also treated as the ending point. + * @name Phaser.Renderer.WebGL.WebGLShader#program + * @type {WebGLProgram} + * @since 3.50.0 + */ + this.program = this.renderer.createProgram(vertexShader, fragmentShader); + + /** + * Array of objects that describe the vertex attributes. * - * @name Phaser.Curves.Path#startPoint - * @type {Phaser.Math.Vector2} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.WebGLShader#attributes + * @type {Phaser.Types.Renderer.WebGL.WebGLPipelineAttribute[]} + * @since 3.50.0 */ - this.startPoint = new Vector2(); + this.attributes; /** - * A temporary vector used to avoid object creation when adding a Curve to the Path. + * The amount of vertex attribute components of 32 bit length. * - * @name Phaser.Curves.Path#_tmpVec2A - * @type {Phaser.Math.Vector2} - * @private - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.WebGLShader#vertexComponentCount + * @type {number} + * @since 3.50.0 */ - this._tmpVec2A = new Vector2(); + this.vertexComponentCount = 0; /** - * A temporary vector used to avoid object creation when adding a Curve to the Path. + * The size, in bytes, of a single vertex. * - * @name Phaser.Curves.Path#_tmpVec2B - * @type {Phaser.Math.Vector2} - * @private - * @since 3.0.0 + * This is derived by adding together all of the vertex attributes. + * + * For example, the Multi Pipeline has the following attributes: + * + * inPosition - (size 2 x gl.FLOAT) = 8 + * inTexCoord - (size 2 x gl.FLOAT) = 8 + * inTexId - (size 1 x gl.FLOAT) = 4 + * inTintEffect - (size 1 x gl.FLOAT) = 4 + * inTint - (size 4 x gl.UNSIGNED_BYTE) = 4 + * + * The total, in this case, is 8 + 8 + 4 + 4 + 4 = 28. + * + * This is calculated automatically during the `createAttributes` method. + * + * @name Phaser.Renderer.WebGL.WebGLShader#vertexSize + * @type {number} + * @readonly + * @since 3.50.0 */ - this._tmpVec2B = new Vector2(); + this.vertexSize = 0; - if (typeof x === 'object') - { - this.fromJSON(x); - } - else - { - this.startPoint.set(x, y); - } + /** + * The active uniforms that this shader has. + * + * This is an object that maps the uniform names to their WebGL location and cached values. + * + * It is populated automatically via the `createUniforms` method. + * + * @name Phaser.Renderer.WebGL.WebGLShader#uniforms + * @type {Phaser.Types.Renderer.WebGL.WebGLPipelineUniformsConfig} + * @since 3.50.0 + */ + this.uniforms = {}; + + this.createAttributes(attributes); + this.createUniforms(); }, /** - * Appends a Curve to the end of the Path. + * Takes the vertex attributes config and parses it, creating the resulting array that is stored + * in this shaders `attributes` property, calculating the offset, normalization and location + * in the process. * - * The Curve does not have to start where the Path ends or, for an empty Path, at its defined starting point. + * Calling this method resets `WebGLShader.attributes`, `WebGLShader.vertexSize` and + * `WebGLShader.vertexComponentCount`. * - * @method Phaser.Curves.Path#add - * @since 3.0.0 + * It is called automatically when this class is created, but can be called manually if required. * - * @param {Phaser.Curves.Curve} curve - The Curve to append. + * @method Phaser.Renderer.WebGL.WebGLShader#createAttributes + * @since 3.50.0 * - * @return {this} This Path object. + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineAttributeConfig[]} attributes - An array of attributes configs. */ - add: function (curve) + createAttributes: function (attributes) { - this.curves.push(curve); + var count = 0; + var offset = 0; + var result = []; - return this; - }, + this.vertexComponentCount = 0; - /** - * Creates a circular Ellipse Curve positioned at the end of the Path. - * - * @method Phaser.Curves.Path#circleTo - * @since 3.0.0 - * - * @param {number} radius - The radius of the circle. - * @param {boolean} [clockwise=false] - `true` to create a clockwise circle as opposed to a counter-clockwise circle. - * @param {number} [rotation=0] - The rotation of the circle in degrees. - * - * @return {this} This Path object. - */ - circleTo: function (radius, clockwise, rotation) - { - if (clockwise === undefined) { clockwise = false; } + for (var i = 0; i < attributes.length; i++) + { + var element = attributes[i]; - return this.ellipseTo(radius, radius, 0, 360, clockwise, rotation); + var name = element.name; + var size = GetFastValue(element, 'size', 1); // i.e. 1 for a float, 2 for a vec2, 4 for a vec4, etc + var glType = GetFastValue(element, 'type', WEBGL_CONST.FLOAT); + var type = glType.enum; // The GLenum + var typeSize = glType.size; // The size in bytes of the type + + var normalized = (element.normalized) ? true : false; + + result.push({ + name: name, + size: size, + type: type, + normalized: normalized, + offset: offset, + enabled: false, + location: -1 + }); + + if (typeSize === 4) + { + count += size; + } + else + { + count++; + } + + offset += size * typeSize; + } + + this.vertexSize = offset; + this.vertexComponentCount = count; + this.attributes = result; }, /** - * Ensures that the Path is closed. + * Sets the program this shader uses as being the active shader in the WebGL Renderer. * - * A closed Path starts and ends at the same point. If the Path is not closed, a straight Line Curve will be created from the ending point directly to the starting point. During the check, the actual starting point of the Path, i.e. the starting point of the first Curve, will be used as opposed to the Path's defined {@link startPoint}, which could differ. + * This method is called every time the parent pipeline is made the current active pipeline. * - * Calling this method on an empty Path will result in an error. + * @method Phaser.Renderer.WebGL.WebGLShader#bind + * @since 3.50.0 * - * @method Phaser.Curves.Path#closePath - * @since 3.0.0 + * @param {boolean} [setAttributes=false] - Should the vertex attribute pointers be set? + * @param {boolean} [flush=false] - Flush the pipeline before binding this shader? * - * @return {this} This Path object. + * @return {this} This WebGLShader instance. */ - closePath: function () + bind: function (setAttributes, flush) { - // Add a line curve if start and end of lines are not connected - var startPoint = this.curves[0].getPoint(0); - var endPoint = this.curves[this.curves.length - 1].getPoint(1); + if (setAttributes === undefined) { setAttributes = false; } + if (flush === undefined) { flush = false; } - if (!startPoint.equals(endPoint)) + if (flush) { - // This will copy a reference to the vectors, which probably isn't sensible - this.curves.push(new LineCurve(endPoint, startPoint)); + this.pipeline.flush(); + } + + this.renderer.setProgram(this.program); + + if (setAttributes) + { + this.setAttribPointers(); } return this; }, /** - * Creates a cubic bezier curve starting at the previous end point and ending at p3, using p1 and p2 as control points. + * Sets the program this shader uses as being the active shader in the WebGL Renderer. * - * @method Phaser.Curves.Path#cubicBezierTo - * @since 3.0.0 + * Then resets all of the attribute pointers. * - * @param {(number|Phaser.Math.Vector2)} x - The x coordinate of the end point. Or, if a Vector2, the p1 value. - * @param {(number|Phaser.Math.Vector2)} y - The y coordinate of the end point. Or, if a Vector2, the p2 value. - * @param {(number|Phaser.Math.Vector2)} control1X - The x coordinate of the first control point. Or, if a Vector2, the p3 value. - * @param {number} [control1Y] - The y coordinate of the first control point. Not used if Vector2s are provided as the first 3 arguments. - * @param {number} [control2X] - The x coordinate of the second control point. Not used if Vector2s are provided as the first 3 arguments. - * @param {number} [control2Y] - The y coordinate of the second control point. Not used if Vector2s are provided as the first 3 arguments. + * @method Phaser.Renderer.WebGL.WebGLShader#rebind + * @since 3.50.0 * - * @return {this} This Path object. + * @return {this} This WebGLShader instance. */ - cubicBezierTo: function (x, y, control1X, control1Y, control2X, control2Y) + rebind: function () { - var p0 = this.getEndPoint(); - var p1; - var p2; - var p3; + this.renderer.setProgram(this.program); - // Assume they're all Vector2s - if (x instanceof Vector2) - { - p1 = x; - p2 = y; - p3 = control1X; - } - else - { - p1 = new Vector2(control1X, control1Y); - p2 = new Vector2(control2X, control2Y); - p3 = new Vector2(x, y); - } + this.setAttribPointers(true); - return this.add(new CubicBezierCurve(p0, p1, p2, p3)); + return this; }, - // Creates a quadratic bezier curve starting at the previous end point and ending at p2, using p1 as a control point - /** - * Creates a Quadratic Bezier Curve starting at the ending point of the Path. + * Sets the vertex attribute pointers. * - * @method Phaser.Curves.Path#quadraticBezierTo - * @since 3.2.0 + * This should only be called after the vertex buffer has been bound. * - * @param {(number|Phaser.Math.Vector2[])} x - The X coordinate of the second control point or, if it's a `Vector2`, the first control point. - * @param {number} [y] - The Y coordinate of the second control point or, if `x` is a `Vector2`, the second control point. - * @param {number} [controlX] - If `x` is not a `Vector2`, the X coordinate of the first control point. - * @param {number} [controlY] - If `x` is not a `Vector2`, the Y coordinate of the first control point. + * It is called automatically during the `bind` method. * - * @return {this} This Path object. + * @method Phaser.Renderer.WebGL.WebGLShader#setAttribPointers + * @since 3.50.0 + * + * @param {boolean} [reset=false] - Reset the vertex attribute locations? + * + * @return {this} This WebGLShader instance. */ - quadraticBezierTo: function (x, y, controlX, controlY) + setAttribPointers: function (reset) { - var p0 = this.getEndPoint(); - var p1; - var p2; + if (reset === undefined) { reset = false; } - // Assume they're all Vector2s - if (x instanceof Vector2) - { - p1 = x; - p2 = y; - } - else + var gl = this.gl; + var vertexSize = this.vertexSize; + var attributes = this.attributes; + var program = this.program; + + for (var i = 0; i < attributes.length; i++) { - p1 = new Vector2(controlX, controlY); - p2 = new Vector2(x, y); + var element = attributes[i]; + + var size = element.size; + var type = element.type; + var offset = element.offset; + var enabled = element.enabled; + var location = element.location; + var normalized = (element.normalized) ? true : false; + + if (reset) + { + var attribLocation = gl.getAttribLocation(program, element.name); + + if (attribLocation >= 0) + { + gl.enableVertexAttribArray(attribLocation); + + gl.vertexAttribPointer(attribLocation, size, type, normalized, vertexSize, offset); + + element.enabled = true; + element.location = attribLocation; + } + else if (attribLocation !== -1) + { + gl.disableVertexAttribArray(attribLocation); + } + } + else if (enabled) + { + gl.vertexAttribPointer(location, size, type, normalized, vertexSize, offset); + } + else if (!enabled && location > -1) + { + gl.disableVertexAttribArray(location); + + element.location = -1; + } } - return this.add(new QuadraticBezierCurve(p0, p1, p2)); + return this; }, /** - * Draws all Curves in the Path to a Graphics Game Object. + * Sets up the `WebGLShader.uniforms` object, populating it with the names + * and locations of the shader uniforms this shader requires. * - * @method Phaser.Curves.Path#draw - * @since 3.0.0 + * It works by first calling `gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS)` to + * find out how many active uniforms this shader has. It then iterates through them, + * calling `gl.getActiveUniform` to get the WebGL Active Info from each one. Finally, + * the name and location are stored in the local array. * - * @generic {Phaser.GameObjects.Graphics} G - [out,$return] + * This method is called automatically when this class is created. * - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics Game Object to draw to. - * @param {number} [pointsTotal=32] - The number of points to draw for each Curve. Higher numbers result in a smoother curve but require more processing. + * @method Phaser.Renderer.WebGL.WebGLShader#createUniforms + * @since 3.50.0 * - * @return {Phaser.GameObjects.Graphics} The Graphics object which was drawn to. + * @return {this} This WebGLShader instance. */ - draw: function (graphics, pointsTotal) + createUniforms: function () { - for (var i = 0; i < this.curves.length; i++) + var gl = this.gl; + var program = this.program; + var uniforms = this.uniforms; + + var i; + var name; + var location; + + // Look-up all active uniforms + + var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + + for (i = 0; i < totalUniforms; i++) { - var curve = this.curves[i]; + var info = gl.getActiveUniform(program, i); - if (!curve.active) + if (info) { - continue; - } + name = info.name; - curve.draw(graphics, pointsTotal); + location = gl.getUniformLocation(program, name); + + if (location !== null) + { + uniforms[name] = + { + name: name, + location: location, + value1: null, + value2: null, + value3: null, + value4: null + }; + } + + // If the uniform name contains [] for an array struct, + // we'll add an entry for the non-struct name as well. + // Such as uMainSampler[12] = uMainSampler + + var struct = name.indexOf('['); + + if (struct > 0) + { + name = name.substr(0, struct); + + if (!uniforms.hasOwnProperty(name)) + { + location = gl.getUniformLocation(program, name); + + if (location !== null) + { + uniforms[name] = + { + name: name, + location: location, + value1: null, + value2: null, + value3: null, + value4: null + }; + } + } + } + } } - return graphics; + return this; }, /** - * Creates an ellipse curve positioned at the previous end point, using the given parameters. + * Checks to see if the given uniform name exists and is active in this shader. * - * @method Phaser.Curves.Path#ellipseTo - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.WebGLShader#hasUniform + * @since 3.50.0 * - * @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. + * @param {string} name - The name of the uniform to check for. * - * @return {this} This Path object. + * @return {boolean} `true` if the uniform exists, otherwise `false`. */ - ellipseTo: function (xRadius, yRadius, startAngle, endAngle, clockwise, rotation) + hasUniform: function (name) { - var ellipse = new EllipseCurve(0, 0, xRadius, yRadius, startAngle, endAngle, clockwise, rotation); - - var end = this.getEndPoint(this._tmpVec2A); - - // Calculate where to center the ellipse - var start = ellipse.getStartPoint(this._tmpVec2B); + return this.uniforms.hasOwnProperty(name); + }, - end.subtract(start); + /** + * Resets the cached values of the given uniform. + * + * @method Phaser.Renderer.WebGL.WebGLShader#resetUniform + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to reset. + * + * @return {this} This WebGLShader instance. + */ + resetUniform: function (name) + { + var uniform = this.uniforms[name]; - ellipse.x = end.x; - ellipse.y = end.y; + if (uniform) + { + uniform.value1 = null; + uniform.value2 = null; + uniform.value3 = null; + uniform.value4 = null; + } - return this.add(ellipse); + return this; }, /** - * Creates a Path from a Path Configuration object. + * Sets the given uniform value/s based on the name and GL function. * - * The provided object should be a {@link Phaser.Types.Curves.JSONPath}, as returned by {@link #toJSON}. Providing a malformed object may cause errors. + * This method is called internally by other methods such as `set1f` and `set3iv`. * - * @method Phaser.Curves.Path#fromJSON - * @since 3.0.0 + * The uniform is only set if the value/s given are different to those previously set. * - * @param {Phaser.Types.Curves.JSONPath} data - The JSON object containing the Path data. + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @return {this} This Path object. + * @method Phaser.Renderer.WebGL.WebGLShader#setUniform1 + * @since 3.50.0 + * + * @param {function} setter - The GL function to call. + * @param {string} name - The name of the uniform to set. + * @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform. + * @param {boolean} [skipCheck=false] - Skip the value comparison? + * + * @return {this} This WebGLShader instance. */ - fromJSON: function (data) + setUniform1: function (setter, name, value1, skipCheck) { - // data should be an object matching the Path.toJSON object structure. - - this.curves = []; - this.cacheLengths = []; - - this.startPoint.set(data.x, data.y); - - this.autoClose = data.autoClose; + var uniform = this.uniforms[name]; - for (var i = 0; i < data.curves.length; i++) + if (!uniform) { - var curve = data.curves[i]; - - switch (curve.type) - { - case 'LineCurve': - this.add(LineCurve.fromJSON(curve)); - break; + return this; + } - case 'EllipseCurve': - this.add(EllipseCurve.fromJSON(curve)); - break; + if (skipCheck || uniform.value1 !== value1) + { + uniform.value1 = value1; - case 'SplineCurve': - this.add(SplineCurve.fromJSON(curve)); - break; + this.renderer.setProgram(this.program); - case 'CubicBezierCurve': - this.add(CubicBezierCurve.fromJSON(curve)); - break; + setter.call(this.gl, uniform.location, value1); - case 'QuadraticBezierCurve': - this.add(QuadraticBezierCurve.fromJSON(curve)); - break; - } + this.pipeline.currentShader = this; } return this; }, /** - * Returns a Rectangle with a position and size matching the bounds of this Path. + * Sets the given uniform value/s based on the name and GL function. * - * @method Phaser.Curves.Path#getBounds - * @since 3.0.0 + * This method is called internally by other methods such as `set1f` and `set3iv`. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * The uniform is only set if the value/s given are different to those previously set. * - * @param {Phaser.Geom.Rectangle} [out] - The Rectangle to store the bounds in. - * @param {number} [accuracy=16] - The accuracy of the bounds calculations. Higher values are more accurate at the cost of calculation speed. + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @return {Phaser.Geom.Rectangle} The modified `out` Rectangle, or a new Rectangle if none was provided. + * @method Phaser.Renderer.WebGL.WebGLShader#setUniform2 + * @since 3.50.0 + * + * @param {function} setter - The GL function to call. + * @param {string} name - The name of the uniform to set. + * @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform. + * @param {(boolean|number|number[]|Float32Array)} value2 - The new value of the uniform. + * @param {boolean} [skipCheck=false] - Skip the value comparison? + * + * @return {this} This WebGLShader instance. */ - getBounds: function (out, accuracy) + setUniform2: function (setter, name, value1, value2, skipCheck) { - if (out === undefined) { out = new Rectangle(); } - if (accuracy === undefined) { accuracy = 16; } - - out.x = Number.MAX_VALUE; - out.y = Number.MAX_VALUE; - - var bounds = new Rectangle(); - var maxRight = MATH_CONST.MIN_SAFE_INTEGER; - var maxBottom = MATH_CONST.MIN_SAFE_INTEGER; + var uniform = this.uniforms[name]; - for (var i = 0; i < this.curves.length; i++) + if (!uniform) { - var curve = this.curves[i]; + return this; + } - if (!curve.active) - { - continue; - } + if (skipCheck || uniform.value1 !== value1 || uniform.value2 !== value2) + { + uniform.value1 = value1; + uniform.value2 = value2; - curve.getBounds(bounds, accuracy); + this.renderer.setProgram(this.program); - out.x = Math.min(out.x, bounds.x); - out.y = Math.min(out.y, bounds.y); + setter.call(this.gl, uniform.location, value1, value2); - maxRight = Math.max(maxRight, bounds.right); - maxBottom = Math.max(maxBottom, bounds.bottom); + this.pipeline.currentShader = this; } - out.right = maxRight; - out.bottom = maxBottom; - - return out; + return this; }, /** - * Returns an array containing the length of the Path at the end of each Curve. + * Sets the given uniform value/s based on the name and GL function. * - * The result of this method will be cached to avoid recalculating it in subsequent calls. The cache is only invalidated when the {@link #curves} array changes in length, leading to potential inaccuracies if a Curve in the Path is changed, or if a Curve is removed and another is added in its place. + * This method is called internally by other methods such as `set1f` and `set3iv`. * - * @method Phaser.Curves.Path#getCurveLengths - * @since 3.0.0 + * The uniform is only set if the value/s given are different to those previously set. * - * @return {number[]} An array containing the length of the Path at the end of each one of its Curves. + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#setUniform3 + * @since 3.50.0 + * + * @param {function} setter - The GL function to call. + * @param {string} name - The name of the uniform to set. + * @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform. + * @param {(boolean|number|number[]|Float32Array)} value2 - The new value of the uniform. + * @param {(boolean|number|number[]|Float32Array)} value3 - The new value of the uniform. + * @param {boolean} [skipCheck=false] - Skip the value comparison? + * + * @return {this} This WebGLShader instance. */ - getCurveLengths: function () + setUniform3: function (setter, name, value1, value2, value3, skipCheck) { - // We use cache values if curves and cache array are same length + var uniform = this.uniforms[name]; - if (this.cacheLengths.length === this.curves.length) + if (!uniform) { - return this.cacheLengths; + return this; } - // Get length of sub-curve - // Push sums into cached array + if (skipCheck || uniform.value1 !== value1 || uniform.value2 !== value2 || uniform.value3 !== value3) + { + uniform.value1 = value1; + uniform.value2 = value2; + uniform.value3 = value3; - var lengths = []; - var sums = 0; + this.renderer.setProgram(this.program); - for (var i = 0; i < this.curves.length; i++) - { - sums += this.curves[i].getLength(); + setter.call(this.gl, uniform.location, value1, value2, value3); - lengths.push(sums); + this.pipeline.currentShader = this; } - this.cacheLengths = lengths; - - return lengths; + return this; }, /** - * Returns the ending point of the Path. + * Sets the given uniform value/s based on the name and GL function. * - * A Path's ending point is equivalent to the ending point of the last Curve in the Path. For an empty Path, the ending point is at the Path's defined {@link #startPoint}. + * This method is called internally by other methods such as `set1f` and `set3iv`. * - * @method Phaser.Curves.Path#getEndPoint - * @since 3.0.0 + * The uniform is only set if the value/s given are different to those previously set. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @param {Phaser.Math.Vector2} [out] - The object to store the point in. + * @method Phaser.Renderer.WebGL.WebGLShader#setUniform4 + * @since 3.50.0 * - * @return {Phaser.Math.Vector2} The modified `out` object, or a new Vector2 if none was provided. + * @param {function} setter - The GL function to call. + * @param {string} name - The name of the uniform to set. + * @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform. + * @param {(boolean|number|number[]|Float32Array)} value2 - The new value of the uniform. + * @param {(boolean|number|number[]|Float32Array)} value3 - The new value of the uniform. + * @param {(boolean|number|number[]|Float32Array)} value4 - The new value of the uniform. + * @param {boolean} [skipCheck=false] - Skip the value comparison? + * + * @return {this} This WebGLShader instance. */ - getEndPoint: function (out) + setUniform4: function (setter, name, value1, value2, value3, value4, skipCheck) { - if (out === undefined) { out = new Vector2(); } + var uniform = this.uniforms[name]; - if (this.curves.length > 0) + if (!uniform) { - this.curves[this.curves.length - 1].getPoint(1, out); + return this; } - else + + if (skipCheck || uniform.value1 !== value1 || uniform.value2 !== value2 || uniform.value3 !== value3 || uniform.value4 !== value4) { - out.copy(this.startPoint); + uniform.value1 = value1; + uniform.value2 = value2; + uniform.value3 = value3; + uniform.value4 = value4; + + this.renderer.setProgram(this.program); + + setter.call(this.gl, uniform.location, value1, value2, value3, value4); + + this.pipeline.currentShader = this; } - return out; + return this; }, /** - * Returns the total length of the Path. + * Sets a boolean uniform value based on the given name on this shader. * - * @see {@link #getCurveLengths} + * The uniform is only set if the value/s given are different to those previously set. * - * @method Phaser.Curves.Path#getLength - * @since 3.0.0 + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @return {number} The total length of the Path. + * @method Phaser.Renderer.WebGL.WebGLShader#setBoolean + * @since 3.60.0 + * + * @param {string} name - The name of the uniform to set. + * @param {boolean} value - The new value of the `boolean` uniform. + * + * @return {this} This WebGLShader instance. */ - getLength: function () + setBoolean: function (name, value) { - var lens = this.getCurveLengths(); - - return lens[lens.length - 1]; + return this.setUniform1(this.gl.uniform1i, name, Number(value)); }, - // To get accurate point with reference to - // entire path distance at time t, - // following has to be done: - - // 1. Length of each sub path have to be known - // 2. Locate and identify type of curve - // 3. Get t for the curve - // 4. Return curve.getPointAt(t') - /** - * Calculates the coordinates of the point at the given normalized location (between 0 and 1) on the Path. + * Sets a 1f uniform value based on the given name on this shader. * - * The location is relative to the entire Path, not to an individual Curve. A location of 0.5 is always in the middle of the Path and is thus an equal distance away from both its starting and ending points. In a Path with one Curve, it would be in the middle of the Curve; in a Path with two Curves, it could be anywhere on either one of them depending on their lengths. + * The uniform is only set if the value/s given are different to those previously set. * - * @method Phaser.Curves.Path#getPoint - * @since 3.0.0 + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * @method Phaser.Renderer.WebGL.WebGLShader#set1f + * @since 3.50.0 * - * @param {number} t - The location of the point to return, between 0 and 1. - * @param {Phaser.Math.Vector2} [out] - The object in which to store the calculated point. + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new value of the `float` uniform. * - * @return {?Phaser.Math.Vector2} The modified `out` object, or a new `Vector2` if none was provided. + * @return {this} This WebGLShader instance. */ - getPoint: function (t, out) + set1f: function (name, x) { - if (out === undefined) { out = new Vector2(); } - - var d = t * this.getLength(); - var curveLengths = this.getCurveLengths(); - var i = 0; - - while (i < curveLengths.length) - { - if (curveLengths[i] >= d) - { - var diff = curveLengths[i] - d; - var curve = this.curves[i]; - - var segmentLength = curve.getLength(); - var u = (segmentLength === 0) ? 0 : 1 - diff / segmentLength; - - return curve.getPointAt(u, out); - } - - i++; - } - - // loop where sum != 0, sum > d , sum+1 1 && !points[points.length - 1].equals(points[0])) - { - points.push(points[0]); - } - - return points; + return this.setUniform2(this.gl.uniform2f, name, x, y); }, /** - * Returns a randomly chosen point anywhere on the path. This follows the same rules as `getPoint` in that it may return a point on any Curve inside this path. + * Sets a 3f uniform value based on the given name on this shader. * - * When calling this method multiple times, the points are not guaranteed to be equally spaced spatially. + * The uniform is only set if the value/s given are different to those previously set. * - * @method Phaser.Curves.Path#getRandomPoint - * @since 3.0.0 + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * @method Phaser.Renderer.WebGL.WebGLShader#set3f + * @since 3.50.0 * - * @param {Phaser.Math.Vector2} [out] - `Vector2` instance that should be used for storing the result. If `undefined` a new `Vector2` will be created. + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new X component of the `vec3` uniform. + * @param {number} y - The new Y component of the `vec3` uniform. + * @param {number} z - The new Z component of the `vec3` uniform. * - * @return {Phaser.Math.Vector2} The modified `out` object, or a new `Vector2` if none was provided. + * @return {this} This WebGLShader instance. */ - getRandomPoint: function (out) + set3f: function (name, x, y, z) { - if (out === undefined) { out = new Vector2(); } - - return this.getPoint(Math.random(), out); + return this.setUniform3(this.gl.uniform3f, name, x, y, z); }, /** - * Divides this Path into a set of equally spaced points, + * Sets a 4f uniform value based on the given name on this shader. * - * The resulting points are equally spaced with respect to the points' position on the path, but not necessarily equally spaced spatially. + * The uniform is only set if the value/s given are different to those previously set. * - * @method Phaser.Curves.Path#getSpacedPoints - * @since 3.0.0 + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @param {number} [divisions=40] - The amount of points to divide this Path into. + * @method Phaser.Renderer.WebGL.WebGLShader#set4f + * @since 3.50.0 * - * @return {Phaser.Math.Vector2[]} A list of the points this path was subdivided into. + * @param {string} name - The name of the uniform to set. + * @param {number} x - X component of the uniform + * @param {number} y - Y component of the uniform + * @param {number} z - Z component of the uniform + * @param {number} w - W component of the uniform + * + * @return {this} This WebGLShader instance. */ - getSpacedPoints: function (divisions) + set4f: function (name, x, y, z, w) { - if (divisions === undefined) { divisions = 40; } - - var points = []; + return this.setUniform4(this.gl.uniform4f, name, x, y, z, w); + }, - for (var i = 0; i <= divisions; i++) - { - points.push(this.getPoint(i / divisions)); - } + /** + * Sets a 1fv uniform value based on the given name on this shader. + * + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#set1fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * + * @return {this} This WebGLShader instance. + */ + set1fv: function (name, arr) + { + return this.setUniform1(this.gl.uniform1fv, name, arr, true); + }, - if (this.autoClose) - { - points.push(points[0]); - } + /** + * Sets a 2fv uniform value based on the given name on this shader. + * + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#set2fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * + * @return {this} This WebGLShader instance. + */ + set2fv: function (name, arr) + { + return this.setUniform1(this.gl.uniform2fv, name, arr, true); + }, - return points; + /** + * Sets a 3fv uniform value based on the given name on this shader. + * + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#set3fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * + * @return {this} This WebGLShader instance. + */ + set3fv: function (name, arr) + { + return this.setUniform1(this.gl.uniform3fv, name, arr, true); }, /** - * Returns the starting point of the Path. + * Sets a 4fv uniform value based on the given name on this shader. + * + * The uniform is only set if the value/s given are different to those previously set. * - * @method Phaser.Curves.Path#getStartPoint - * @since 3.0.0 + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * @method Phaser.Renderer.WebGL.WebGLShader#set4fv + * @since 3.50.0 * - * @param {Phaser.Math.Vector2} [out] - `Vector2` instance that should be used for storing the result. If `undefined` a new `Vector2` will be created. + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. * - * @return {Phaser.Math.Vector2} The modified `out` object, or a new Vector2 if none was provided. + * @return {this} This WebGLShader instance. */ - getStartPoint: function (out) + set4fv: function (name, arr) { - if (out === undefined) { out = new Vector2(); } - - return out.copy(this.startPoint); + return this.setUniform1(this.gl.uniform4fv, name, arr, true); }, /** - * Gets a unit vector tangent at a relative position on the path. + * Sets a 1iv uniform value based on the given name on this shader. * - * @method Phaser.Curves.Path#getTangent - * @since 3.23.0 + * The uniform is only set if the value/s given are different to those previously set. * - * @generic {Phaser.Math.Vector2} O - [out,$return] + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @param {number} t - The relative position on the path, [0..1]. - * @param {Phaser.Math.Vector2} [out] - A vector to store the result in. + * @method Phaser.Renderer.WebGL.WebGLShader#set1iv + * @since 3.50.0 * - * @return {Phaser.Math.Vector2} Vector approximating the tangent line at the point t (delta +/- 0.0001) + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * + * @return {this} This WebGLShader instance. */ - getTangent: function (t, out) + set1iv: function (name, arr) { - if (out === undefined) { out = new Vector2(); } - - var d = t * this.getLength(); - var curveLengths = this.getCurveLengths(); - var i = 0; - - while (i < curveLengths.length) - { - if (curveLengths[i] >= d) - { - var diff = curveLengths[i] - d; - var curve = this.curves[i]; - - var segmentLength = curve.getLength(); - var u = (segmentLength === 0) ? 0 : 1 - diff / segmentLength; - - return curve.getTangentAt(u, out); - } - - i++; - } - - return null; + return this.setUniform1(this.gl.uniform1iv, name, arr, true); }, /** - * Creates a line curve from the previous end point to x/y. + * Sets a 2iv uniform value based on the given name on this shader. * - * @method Phaser.Curves.Path#lineTo - * @since 3.0.0 + * The uniform is only set if the value/s given are different to those previously set. * - * @param {(number|Phaser.Math.Vector2)} x - The X coordinate of the line's end point, or a `Vector2` containing the entire end point. - * @param {number} [y] - The Y coordinate of the line's end point, if a number was passed as the X parameter. + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @return {this} This Path object. + * @method Phaser.Renderer.WebGL.WebGLShader#set2iv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * + * @return {this} This WebGLShader instance. */ - lineTo: function (x, y) + set2iv: function (name, arr) { - if (x instanceof Vector2) - { - this._tmpVec2B.copy(x); - } - else - { - this._tmpVec2B.set(x, y); - } - - var end = this.getEndPoint(this._tmpVec2A); - - return this.add(new LineCurve([ end.x, end.y, this._tmpVec2B.x, this._tmpVec2B.y ])); + return this.setUniform1(this.gl.uniform2iv, name, arr, true); }, /** - * Creates a spline curve starting at the previous end point, using the given points on the curve. + * Sets a 3iv uniform value based on the given name on this shader. * - * @method Phaser.Curves.Path#splineTo - * @since 3.0.0 + * The uniform is only set if the value/s given are different to those previously set. * - * @param {Phaser.Math.Vector2[]} points - The points the newly created spline curve should consist of. + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @return {this} This Path object. + * @method Phaser.Renderer.WebGL.WebGLShader#set3iv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * + * @return {this} This WebGLShader instance. */ - splineTo: function (points) + set3iv: function (name, arr) { - points.unshift(this.getEndPoint()); - - return this.add(new SplineCurve(points)); + return this.setUniform1(this.gl.uniform3iv, name, arr, true); }, /** - * Creates a "gap" in this path from the path's current end point to the given coordinates. + * Sets a 4iv uniform value based on the given name on this shader. * - * After calling this function, this Path's end point will be equal to the given coordinates + * The uniform is only set if the value/s given are different to those previously set. * - * @method Phaser.Curves.Path#moveTo - * @since 3.0.0 + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. * - * @param {(number|Phaser.Math.Vector2)} x - The X coordinate of the position to move the path's end point to, or a `Vector2` containing the entire new end point. - * @param {number} [y] - The Y coordinate of the position to move the path's end point to, if a number was passed as the X coordinate. + * @method Phaser.Renderer.WebGL.WebGLShader#set4iv + * @since 3.50.0 * - * @return {this} This Path object. + * @param {string} name - The name of the uniform to set. + * @param {number[]|Float32Array} arr - The new value to be used for the uniform variable. + * + * @return {this} This WebGLShader instance. */ - moveTo: function (x, y) + set4iv: function (name, arr) { - if (x instanceof Vector2) - { - return this.add(new MovePathTo(x.x, x.y)); - } - else - { - return this.add(new MovePathTo(x, y)); - } + return this.setUniform1(this.gl.uniform4iv, name, arr, true); }, /** - * Converts this Path to a JSON object containing the path information and its constituent curves. + * Sets a 1i uniform value based on the given name on this shader. * - * @method Phaser.Curves.Path#toJSON - * @since 3.0.0 + * The uniform is only set if the value/s given are different to those previously set. * - * @return {Phaser.Types.Curves.JSONPath} The JSON object containing this path's data. + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#set1i + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new value of the `int` uniform. + * + * @return {this} This WebGLShader instance. */ - toJSON: function () + set1i: function (name, x) { - var out = []; - - for (var i = 0; i < this.curves.length; i++) - { - out.push(this.curves[i].toJSON()); - } - - return { - type: 'Path', - x: this.startPoint.x, - y: this.startPoint.y, - autoClose: this.autoClose, - curves: out - }; + return this.setUniform1(this.gl.uniform1i, name, x); }, /** - * cacheLengths must be recalculated. + * Sets a 2i uniform value based on the given name on this shader. * - * @method Phaser.Curves.Path#updateArcLengths - * @since 3.0.0 + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#set2i + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new X component of the `ivec2` uniform. + * @param {number} y - The new Y component of the `ivec2` uniform. + * + * @return {this} This WebGLShader instance. */ - updateArcLengths: function () + set2i: function (name, x, y) { - this.cacheLengths = []; - - this.getCurveLengths(); + return this.setUniform2(this.gl.uniform2i, name, x, y); }, /** - * Disposes of this Path, clearing its internal references to objects so they can be garbage-collected. + * Sets a 3i uniform value based on the given name on this shader. * - * @method Phaser.Curves.Path#destroy - * @since 3.0.0 + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#set3i + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - The new X component of the `ivec3` uniform. + * @param {number} y - The new Y component of the `ivec3` uniform. + * @param {number} z - The new Z component of the `ivec3` uniform. + * + * @return {this} This WebGLShader instance. */ - destroy: function () - { - this.curves.length = 0; - this.cacheLengths.length = 0; - this.startPoint = undefined; - } - -}); - -/** - * Creates a new Path Object. - * - * @method Phaser.GameObjects.GameObjectFactory#path - * @since 3.0.0 - * - * @param {number} x - The horizontal position of this Path. - * @param {number} y - The vertical position of this Path. - * - * @return {Phaser.Curves.Path} The Path Object that was created. - */ -GameObjectFactory.register('path', function (x, y) -{ - return new Path(x, y); -}); - -// When registering a factory function 'this' refers to the GameObjectFactory 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 - -module.exports = Path; - - -/***/ }), -/* 896 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Data - */ - -module.exports = { - - DataManager: __webpack_require__(101), - DataManagerPlugin: __webpack_require__(897), - Events: __webpack_require__(315) - -}; - - -/***/ }), -/* 897 */ -/***/ (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 DataManager = __webpack_require__(101); -var PluginCache = __webpack_require__(24); -var SceneEvents = __webpack_require__(20); - -/** - * @classdesc - * The Data Component features a means to store pieces of data specific to a Game Object, System or Plugin. - * You can then search, query it, and retrieve the data. The parent must either extend EventEmitter, - * or have a property called `events` that is an instance of it. - * - * @class DataManagerPlugin - * @extends Phaser.Data.DataManager - * @memberof Phaser.Data - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - A reference to the Scene that this DataManager belongs to. - */ -var DataManagerPlugin = new Class({ - - Extends: DataManager, - - initialize: - - function DataManagerPlugin (scene) + set3i: function (name, x, y, z) { - DataManager.call(this, scene, scene.sys.events); - - /** - * A reference to the Scene that this DataManager belongs to. - * - * @name Phaser.Data.DataManagerPlugin#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; - - /** - * A reference to the Scene's Systems. - * - * @name Phaser.Data.DataManagerPlugin#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.systems = scene.sys; - - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); - scene.sys.events.on(SceneEvents.START, this.start, this); + return this.setUniform3(this.gl.uniform3i, name, x, y, z); }, /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. + * Sets a 4i uniform value based on the given name on this shader. * - * @method Phaser.Data.DataManagerPlugin#boot - * @private - * @since 3.5.1 + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#set4i + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {number} x - X component of the uniform + * @param {number} y - Y component of the uniform + * @param {number} z - Z component of the uniform + * @param {number} w - W component of the uniform + * + * @return {this} This WebGLShader instance. */ - boot: function () + set4i: function (name, x, y, z, w) { - this.events = this.systems.events; - - this.events.once(SceneEvents.DESTROY, this.destroy, this); + return this.setUniform4(this.gl.uniform4i, name, x, y, z, w); }, /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. + * Sets a matrix 2fv uniform value based on the given name on this shader. * - * @method Phaser.Data.DataManagerPlugin#start - * @private - * @since 3.5.0 + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#setMatrix2fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {boolean} transpose - Whether to transpose the matrix. Should be `false`. + * @param {number[]|Float32Array} matrix - The new values for the `mat2` uniform. + * + * @return {this} This WebGLShader instance. */ - start: function () + setMatrix2fv: function (name, transpose, matrix) { - this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); + return this.setUniform2(this.gl.uniformMatrix2fv, name, transpose, matrix, true); }, /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. + * Sets a matrix 3fv uniform value based on the given name on this shader. * - * @method Phaser.Data.DataManagerPlugin#shutdown - * @private - * @since 3.5.0 + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#setMatrix3fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {boolean} transpose - Whether to transpose the matrix. Should be `false`. + * @param {Float32Array} matrix - The new values for the `mat3` uniform. + * + * @return {this} This WebGLShader instance. */ - shutdown: function () + setMatrix3fv: function (name, transpose, matrix) { - this.systems.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); + return this.setUniform2(this.gl.uniformMatrix3fv, name, transpose, matrix, true); }, /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. + * Sets a matrix 4fv uniform value based on the given name on this shader. * - * @method Phaser.Data.DataManagerPlugin#destroy - * @since 3.5.0 + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * + * @method Phaser.Renderer.WebGL.WebGLShader#setMatrix4fv + * @since 3.50.0 + * + * @param {string} name - The name of the uniform to set. + * @param {boolean} transpose - Should the matrix be transpose + * @param {Float32Array} matrix - Matrix data + * + * @return {this} This WebGLShader instance. */ - destroy: function () - { - DataManager.prototype.destroy.call(this); - - this.events.off(SceneEvents.START, this.start, this); - - this.scene = null; - this.systems = null; - } - -}); - -PluginCache.register('DataManagerPlugin', DataManagerPlugin, 'data'); - -module.exports = DataManagerPlugin; - - -/***/ }), -/* 898 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Display - */ - -module.exports = { - - Align: __webpack_require__(899), - BaseShader: __webpack_require__(396), - Bounds: __webpack_require__(902), - Canvas: __webpack_require__(906), - Color: __webpack_require__(397), - ColorMatrix: __webpack_require__(198), - Masks: __webpack_require__(916), - RGB: __webpack_require__(200) - -}; - - -/***/ }), -/* 899 */ -/***/ (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__(123); -var Extend = __webpack_require__(17); - -/** - * @namespace Phaser.Display.Align - */ - -var Align = { - - In: __webpack_require__(900), - To: __webpack_require__(901) - -}; - -// Merge in the consts -Align = Extend(false, Align, CONST); - -module.exports = Align; - - -/***/ }), -/* 900 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Display.Align.In - */ - -module.exports = { - - BottomCenter: __webpack_require__(290), - BottomLeft: __webpack_require__(291), - BottomRight: __webpack_require__(292), - Center: __webpack_require__(293), - LeftCenter: __webpack_require__(295), - QuickSet: __webpack_require__(289), - RightCenter: __webpack_require__(296), - TopCenter: __webpack_require__(297), - TopLeft: __webpack_require__(298), - TopRight: __webpack_require__(299) - -}; - - -/***/ }), -/* 901 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Display.Align.To - */ - -module.exports = { - - BottomCenter: __webpack_require__(277), - BottomLeft: __webpack_require__(278), - BottomRight: __webpack_require__(279), - LeftBottom: __webpack_require__(280), - LeftCenter: __webpack_require__(281), - LeftTop: __webpack_require__(282), - QuickSet: __webpack_require__(276), - RightBottom: __webpack_require__(283), - RightCenter: __webpack_require__(284), - RightTop: __webpack_require__(285), - TopCenter: __webpack_require__(286), - TopLeft: __webpack_require__(287), - TopRight: __webpack_require__(288) - -}; - - -/***/ }), -/* 902 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Display.Bounds - */ - -module.exports = { - - CenterOn: __webpack_require__(294), - GetBottom: __webpack_require__(42), - GetBounds: __webpack_require__(903), - GetCenterX: __webpack_require__(87), - GetCenterY: __webpack_require__(89), - GetLeft: __webpack_require__(43), - GetOffsetX: __webpack_require__(904), - GetOffsetY: __webpack_require__(905), - GetRight: __webpack_require__(44), - GetTop: __webpack_require__(45), - SetBottom: __webpack_require__(55), - SetCenterX: __webpack_require__(88), - SetCenterY: __webpack_require__(90), - SetLeft: __webpack_require__(53), - SetRight: __webpack_require__(54), - SetTop: __webpack_require__(52) - -}; - - -/***/ }), -/* 903 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetBottom = __webpack_require__(42); -var GetLeft = __webpack_require__(43); -var GetRight = __webpack_require__(44); -var GetTop = __webpack_require__(45); - -/** - * Returns the unrotated bounds of the Game Object as a rectangle. - * - * @function Phaser.Display.Bounds.GetBounds - * @since 3.24.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. - * @param {(Phaser.Geom.Rectangle|object)} [output] - An object to store the values in. - * - * @return {(Phaser.Geom.Rectangle|object)} - The bounds of the Game Object. - */ -var GetBounds = function (gameObject, output) -{ - if (output === undefined) { output = {}; } - - var left = GetLeft(gameObject); - var top = GetTop(gameObject); - - output.x = left; - output.y = top; - output.width = GetRight(gameObject) - left; - output.height = GetBottom(gameObject) - top; - - return output; -}; - -module.exports = GetBounds; - - -/***/ }), -/* 904 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Returns the amount the Game Object is visually offset from its x coordinate. - * This is the same as `width * origin.x`. - * This value will only be > 0 if `origin.x` is not equal to zero. - * - * @function Phaser.Display.Bounds.GetOffsetX - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. - * - * @return {number} The horizontal offset of the Game Object. - */ -var GetOffsetX = function (gameObject) -{ - return gameObject.width * gameObject.originX; -}; - -module.exports = GetOffsetX; - - -/***/ }), -/* 905 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Returns the amount the Game Object is visually offset from its y coordinate. - * This is the same as `width * origin.y`. - * This value will only be > 0 if `origin.y` is not equal to zero. - * - * @function Phaser.Display.Bounds.GetOffsetY - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from. - * - * @return {number} The vertical offset of the Game Object. - */ -var GetOffsetY = function (gameObject) -{ - return gameObject.height * gameObject.originY; -}; - -module.exports = GetOffsetY; - - -/***/ }), -/* 906 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Display.Canvas - */ - -module.exports = { - - CanvasInterpolation: __webpack_require__(367), - CanvasPool: __webpack_require__(31), - Smoothing: __webpack_require__(192), - TouchAction: __webpack_require__(907), - UserSelect: __webpack_require__(908) - -}; - - -/***/ }), -/* 907 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Sets the touch-action property on the canvas style. Can be used to disable default browser touch actions. - * - * @function Phaser.Display.Canvas.TouchAction - * @since 3.0.0 - * - * @param {HTMLCanvasElement} canvas - The canvas element to have the style applied to. - * @param {string} [value='none'] - The touch action value to set on the canvas. Set to `none` to disable touch actions. - * - * @return {HTMLCanvasElement} The canvas element. - */ -var TouchAction = function (canvas, value) -{ - if (value === undefined) { value = 'none'; } - - canvas.style['msTouchAction'] = value; - canvas.style['ms-touch-action'] = value; - canvas.style['touch-action'] = value; - - return canvas; -}; - -module.exports = TouchAction; - - -/***/ }), -/* 908 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Sets the user-select property on the canvas style. Can be used to disable default browser selection actions. - * - * @function Phaser.Display.Canvas.UserSelect - * @since 3.0.0 - * - * @param {HTMLCanvasElement} canvas - The canvas element to have the style applied to. - * @param {string} [value='none'] - The touch callout value to set on the canvas. Set to `none` to disable touch callouts. - * - * @return {HTMLCanvasElement} The canvas element. - */ -var UserSelect = function (canvas, value) -{ - if (value === undefined) { value = 'none'; } - - var vendors = [ - '-webkit-', - '-khtml-', - '-moz-', - '-ms-', - '' - ]; - - vendors.forEach(function (vendor) - { - canvas.style[vendor + 'user-select'] = value; - }); - - canvas.style['-webkit-touch-callout'] = value; - canvas.style['-webkit-tap-highlight-color'] = 'rgba(0, 0, 0, 0)'; - - return canvas; -}; - -module.exports = UserSelect; - - -/***/ }), -/* 909 */ -/***/ (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__(103); - -/** - * Return an array of Colors in a Color Spectrum. - * - * The spectrum colors flow in the order: red, yellow, green, blue. - * - * By default this function will return an array with 1024 elements in. - * - * However, you can reduce this to a smaller quantity if needed, by specitying the `limit` parameter. - * - * @function Phaser.Display.Color.ColorSpectrum - * @since 3.50.0 - * - * @param {number} [limit=1024] - How many colors should be returned? The maximum is 1024 but you can set a smaller quantity if required. - * - * @return {Phaser.Types.Display.ColorObject[]} An array containing `limit` parameter number of elements, where each contains a Color Object. - */ -var ColorSpectrum = function (limit) -{ - if (limit === undefined) { limit = 1024; } - - var colors = []; - - var range = 255; - - var i; - var r = 255; - var g = 0; - var b = 0; - - // Red to Yellow - for (i = 0; i <= range; i++) - { - colors.push({ r: r, g: i, b: b, color: GetColor(r, i, b) }); - } - - g = 255; - - // Yellow to Green - for (i = range; i >= 0; i--) - { - colors.push({ r: i, g: g, b: b, color: GetColor(i, g, b) }); - } - - r = 0; - - // Green to Blue - for (i = 0; i <= range; i++, g--) - { - colors.push({ r: r, g: g, b: i, color: GetColor(r, g, i) }); - } - - g = 0; - b = 255; - - // Blue to Red - for (i = 0; i <= range; i++, b--, r++) - { - colors.push({ r: r, g: g, b: b, color: GetColor(r, g, b) }); - } - - if (limit === 1024) - { - return colors; - } - else - { - var out = []; - - var t = 0; - var inc = 1024 / limit; - - for (i = 0; i < limit; i++) - { - out.push(colors[Math.floor(t)]); - - t += inc; - } - - return out; - } -}; - -module.exports = ColorSpectrum; - - -/***/ }), -/* 910 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Converts the given color value into an Object containing r,g,b and a properties. - * - * @function Phaser.Display.Color.ColorToRGBA - * @since 3.0.0 - * - * @param {number} color - A color value, optionally including the alpha value. - * - * @return {Phaser.Types.Display.ColorObject} An object containing the parsed color values. - */ -var ColorToRGBA = function (color) -{ - var output = { - r: color >> 16 & 0xFF, - g: color >> 8 & 0xFF, - b: color & 0xFF, - a: 255 - }; - - if (color > 16777215) - { - output.a = color >>> 24; - } - - return output; -}; - -module.exports = ColorToRGBA; - - -/***/ }), -/* 911 */ -/***/ (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__(38); -var HueToComponent = __webpack_require__(399); - -/** - * Converts HSL (hue, saturation and lightness) values to a Phaser Color object. - * - * @function Phaser.Display.Color.HSLToColor - * @since 3.0.0 - * - * @param {number} h - The hue value in the range 0 to 1. - * @param {number} s - The saturation value in the range 0 to 1. - * @param {number} l - The lightness value in the range 0 to 1. - * - * @return {Phaser.Display.Color} A Color object created from the results of the h, s and l values. - */ -var HSLToColor = function (h, s, l) -{ - // achromatic by default - var r = l; - var g = l; - var b = l; - - if (s !== 0) - { - var q = (l < 0.5) ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - - r = HueToComponent(p, q, h + 1 / 3); - g = HueToComponent(p, q, h); - b = HueToComponent(p, q, h - 1 / 3); - } - - var color = new Color(); - - return color.setGLTo(r, g, b, 1); -}; - -module.exports = HSLToColor; - - -/***/ }), -/* 912 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var HSVToRGB = __webpack_require__(188); - -/** - * Get HSV color wheel values in an array which will be 360 elements in size. - * - * @function Phaser.Display.Color.HSVColorWheel - * @since 3.0.0 - * - * @param {number} [s=1] - The saturation, in the range 0 - 1. - * @param {number} [v=1] - The value, in the range 0 - 1. - * - * @return {Phaser.Types.Display.ColorObject[]} An array containing 360 elements, where each contains a single numeric value corresponding to the color at that point in the HSV color wheel. - */ -var HSVColorWheel = function (s, v) -{ - if (s === undefined) { s = 1; } - if (v === undefined) { v = 1; } - - var colors = []; - - for (var c = 0; c <= 359; c++) + setMatrix4fv: function (name, transpose, matrix) { - colors.push(HSVToRGB(c / 359, s, v)); - } - - return colors; -}; - -module.exports = HSVColorWheel; - - -/***/ }), -/* 913 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Linear = __webpack_require__(135); - -/** - * @namespace Phaser.Display.Color.Interpolate - * @memberof Phaser.Display.Color - * @since 3.0.0 - */ - -/** - * Interpolates between the two given color ranges over the length supplied. - * - * @function Phaser.Display.Color.Interpolate.RGBWithRGB - * @memberof Phaser.Display.Color.Interpolate - * @static - * @since 3.0.0 - * - * @param {number} r1 - Red value. - * @param {number} g1 - Blue value. - * @param {number} b1 - Green value. - * @param {number} r2 - Red value. - * @param {number} g2 - Blue value. - * @param {number} b2 - Green value. - * @param {number} [length=100] - Distance to interpolate over. - * @param {number} [index=0] - Index to start from. - * - * @return {Phaser.Types.Display.ColorObject} An object containing the interpolated color values. - */ -var RGBWithRGB = function (r1, g1, b1, r2, g2, b2, length, index) -{ - if (length === undefined) { length = 100; } - if (index === undefined) { index = 0; } - - var t = index / length; - - return { - r: Linear(r1, r2, t), - g: Linear(g1, g2, t), - b: Linear(b1, b2, t) - }; -}; - -/** - * Interpolates between the two given color objects over the length supplied. - * - * @function Phaser.Display.Color.Interpolate.ColorWithColor - * @memberof Phaser.Display.Color.Interpolate - * @static - * @since 3.0.0 - * - * @param {Phaser.Display.Color} color1 - The first Color object. - * @param {Phaser.Display.Color} color2 - The second Color object. - * @param {number} [length=100] - Distance to interpolate over. - * @param {number} [index=0] - Index to start from. - * - * @return {Phaser.Types.Display.ColorObject} An object containing the interpolated color values. - */ -var ColorWithColor = function (color1, color2, length, index) -{ - if (length === undefined) { length = 100; } - if (index === undefined) { index = 0; } - - return RGBWithRGB(color1.r, color1.g, color1.b, color2.r, color2.g, color2.b, length, index); -}; - -/** - * Interpolates between the Color object and color values over the length supplied. - * - * @function Phaser.Display.Color.Interpolate.ColorWithRGB - * @memberof Phaser.Display.Color.Interpolate - * @static - * @since 3.0.0 - * - * @param {Phaser.Display.Color} color1 - The first Color object. - * @param {number} r - Red value. - * @param {number} g - Blue value. - * @param {number} b - Green value. - * @param {number} [length=100] - Distance to interpolate over. - * @param {number} [index=0] - Index to start from. - * - * @return {Phaser.Types.Display.ColorObject} An object containing the interpolated color values. - */ -var ColorWithRGB = function (color, r, g, b, length, index) -{ - if (length === undefined) { length = 100; } - if (index === undefined) { index = 0; } + return this.setUniform2(this.gl.uniformMatrix4fv, name, transpose, matrix, true); + }, - return RGBWithRGB(color.r, color.g, color.b, r, g, b, length, index); -}; + /** + * This method will create the Shader Program on the current GL context. + * + * If a program already exists, it will be destroyed and the new one will take its place. + * + * After the program is created the uniforms will be reset and + * this shader will be rebound. + * + * This is a very expensive process and if your shader is referenced elsewhere in + * your game those references may then be lost, so be sure to use this carefully. + * + * However, if you need to update say the fragment shader source, then you can pass + * the new source into this method and it'll rebuild the program using it. If you + * don't want to change the vertex shader src, pass `undefined` as the parameter. + * + * @method Phaser.Renderer.WebGL.WebGLShader#createProgram + * @since 3.60.0 + * + * @param {string} [vertSrc] - The source code of the vertex shader. If not given, uses the source already defined in this Shader. + * @param {string} [fragSrc] - The source code of the fragment shader. If not given, uses the source already defined in this Shader. + * + * @return {this} This WebGLShader instance. + */ + createProgram: function (vertSrc, fragSrc) + { + if (vertSrc === undefined) { vertSrc = this.vertSrc; } + if (fragSrc === undefined) { fragSrc = this.fragSrc; } -module.exports = { + var gl = this.gl; - RGBWithRGB: RGBWithRGB, - ColorWithRGB: ColorWithRGB, - ColorWithColor: ColorWithColor + if (this.program) + { + gl.deleteProgram(this.program); + } -}; + this.vertSrc = vertSrc; + this.fragSrc = fragSrc; + this.program = this.renderer.createProgram(vertSrc, fragSrc); -/***/ }), -/* 914 */ -/***/ (function(module, exports, __webpack_require__) { + this.createUniforms(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this.rebind(); + }, -var Between = __webpack_require__(195); -var Color = __webpack_require__(38); + /** + * Removes all external references from this class and deletes the WebGL program from the WebGL context. + * + * Does not remove this shader from the parent pipeline. + * + * @method Phaser.Renderer.WebGL.WebGLShader#destroy + * @since 3.50.0 + */ + destroy: function () + { + this.gl.deleteProgram(this.program); -/** - * Creates a new Color object where the r, g, and b values have been set to random values - * based on the given min max values. - * - * @function Phaser.Display.Color.RandomRGB - * @since 3.0.0 - * - * @param {number} [min=0] - The minimum value to set the random range from (between 0 and 255) - * @param {number} [max=255] - The maximum value to set the random range from (between 0 and 255) - * - * @return {Phaser.Display.Color} A Color object. - */ -var RandomRGB = function (min, max) -{ - if (min === undefined) { min = 0; } - if (max === undefined) { max = 255; } + this.pipeline = null; + this.renderer = null; + this.gl = null; + this.program = null; + this.attributes = null; + this.uniforms = null; + } - return new Color(Between(min, max), Between(min, max), Between(min, max)); -}; +}); -module.exports = RandomRGB; +module.exports = WebGLShader; /***/ }), -/* 915 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71402: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ComponentToHex = __webpack_require__(398); - -/** - * Converts the color values into an HTML compatible color string, prefixed with either `#` or `0x`. - * - * @function Phaser.Display.Color.RGBToString - * @since 3.0.0 - * - * @param {number} r - The red color value. A number between 0 and 255. - * @param {number} g - The green color value. A number between 0 and 255. - * @param {number} b - The blue color value. A number between 0 and 255. - * @param {number} [a=255] - The alpha value. A number between 0 and 255. - * @param {string} [prefix=#] - The prefix of the string. Either `#` or `0x`. - * - * @return {string} A string-based representation of the color values. - */ -var RGBToString = function (r, g, b, a, prefix) -{ - if (a === undefined) { a = 255; } - if (prefix === undefined) { prefix = '#'; } - - if (prefix === '#') - { - return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1, 7); - } - else - { - return '0x' + ComponentToHex(a) + ComponentToHex(r) + ComponentToHex(g) + ComponentToHex(b); - } -}; +var WEBGL_CONST = { -module.exports = RGBToString; + /** + * 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 }, -/***/ }), -/* 916 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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 }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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 }, -/** - * @namespace Phaser.Display.Masks - */ + /** + * 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 }, -module.exports = { + /** + * 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 }, - BitmapMask: __webpack_require__(310), - GeometryMask: __webpack_require__(311) + /** + * 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; + /***/ }), -/* 917 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 55478: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var WEBGL_CONST = __webpack_require__(71402); +var Extend = __webpack_require__(98611); + /** - * @namespace Phaser.DOM + * @namespace Phaser.Renderer.WebGL */ -var Dom = { +var WebGL = { - AddToDOM: __webpack_require__(142), - DOMContentLoaded: __webpack_require__(400), - GetInnerHeight: __webpack_require__(401), - GetScreenOrientation: __webpack_require__(402), - GetTarget: __webpack_require__(407), - ParseXML: __webpack_require__(408), - RemoveFromDOM: __webpack_require__(202), - RequestAnimationFrame: __webpack_require__(386) + PipelineManager: __webpack_require__(35217), + Pipelines: __webpack_require__(62253), + RenderTarget: __webpack_require__(37410), + Utils: __webpack_require__(75512), + WebGLPipeline: __webpack_require__(44775), + WebGLRenderer: __webpack_require__(11857), + WebGLShader: __webpack_require__(71305) }; -module.exports = Dom; - - -/***/ }), -/* 918 */ -/***/ (function(module, exports, __webpack_require__) { +// Merge in the consts -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +WebGL = Extend(false, WebGL, WEBGL_CONST); -/** - * @namespace Phaser.Events - */ +// Export it -module.exports = { EventEmitter: __webpack_require__(919) }; +module.exports = WebGL; /***/ }), -/* 919 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 5583: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var EE = __webpack_require__(9); -var PluginCache = __webpack_require__(24); +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var ShaderSourceFS = __webpack_require__(91679); +var ShaderSourceVS = __webpack_require__(89053); +var WEBGL_CONST = __webpack_require__(71402); +var WebGLPipeline = __webpack_require__(44775); /** * @classdesc - * EventEmitter is a Scene Systems plugin compatible version of eventemitter3. + * The Bitmap Mask Pipeline handles all of the bitmap mask rendering in WebGL for applying + * alpha masks to Game Objects. It works by sampling two texture on the fragment shader and + * using the fragments alpha to clip the region. * - * @class EventEmitter - * @memberof Phaser.Events + * The fragment shader it uses can be found in `shaders/src/BitmapMask.frag`. + * The vertex shader it uses can be found in `shaders/src/BitmapMask.vert`. + * + * The default shader attributes for this pipeline are: + * + * `inPosition` (vec2, offset 0) + * + * The default shader uniforms for this pipeline are: + * + * `uResolution` (vec2) + * `uMainSampler` (sampler2D) + * `uMaskSampler` (sampler2D) + * `uInvertMaskAlpha` (bool) + * + * @class BitmapMaskPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines * @constructor * @since 3.0.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. */ -var EventEmitter = new Class({ +var BitmapMaskPipeline = new Class({ - Extends: EE, + Extends: WebGLPipeline, initialize: - function EventEmitter () + function BitmapMaskPipeline (config) { - EE.call(this); + config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS), + config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS), + config.batchSize = GetFastValue(config, 'batchSize', 1), + config.vertices = GetFastValue(config, 'vertices', [ -1, 1, -1, -7, 7, 1 ]), + config.attributes = GetFastValue(config, 'attributes', [ + { + name: 'inPosition', + size: 2, + type: WEBGL_CONST.FLOAT + } + ]); + + WebGLPipeline.call(this, config); + }, + + boot: function () + { + WebGLPipeline.prototype.boot.call(this); + + this.set1i('uMainSampler', 0); + this.set1i('uMaskSampler', 1); + }, + + resize: function (width, height) + { + WebGLPipeline.prototype.resize.call(this, width, height); + + this.set2f('uResolution', width, height); }, /** - * Removes all listeners. + * Binds necessary resources and renders the mask to a separated framebuffer. + * The framebuffer for the masked object is also bound for further use. * - * @method Phaser.Events.EventEmitter#shutdown + * @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#beginMask * @since 3.0.0 + * + * @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called beginMask. + * @param {Phaser.GameObjects.GameObject} maskedObject - GameObject masked by the mask GameObject. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the current mask. */ - shutdown: function () + beginMask: function (mask, maskedObject, camera) { - this.removeAllListeners(); + this.renderer.beginBitmapMask(mask, camera); }, /** - * Removes all listeners. + * The masked game objects framebuffer is unbound and its texture + * is bound together with the mask texture and the mask shader and + * a draw call with a single quad is processed. Here is where the + * masking effect is applied. * - * @method Phaser.Events.EventEmitter#destroy + * @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#endMask * @since 3.0.0 + * + * @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called endMask. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to. + * @param {Phaser.Renderer.WebGL.RenderTarget} [renderTarget] - Optional WebGL RenderTarget. */ - destroy: function () + endMask: function (mask, camera, renderTarget) { - this.removeAllListeners(); - } - -}); - -/** - * Return an array listing the events for which the emitter has registered listeners. - * - * @method Phaser.Events.EventEmitter#eventNames - * @since 3.0.0 - * - * @return {Array.} - */ - -/** - * Return the listeners registered for a given event. - * - * @method Phaser.Events.EventEmitter#listeners - * @since 3.0.0 - * - * @param {(string|symbol)} event - The event name. - * - * @return {Function[]} The registered listeners. - */ - -/** - * Return the number of listeners listening to a given event. - * - * @method Phaser.Events.EventEmitter#listenerCount - * @since 3.0.0 - * - * @param {(string|symbol)} event - The event name. - * - * @return {number} The number of listeners. - */ + var gl = this.gl; + var renderer = this.renderer; -/** - * Calls each of the listeners registered for a given event. - * - * @method Phaser.Events.EventEmitter#emit - * @since 3.0.0 - * - * @param {(string|symbol)} event - The event name. - * @param {...*} [args] - Additional arguments that will be passed to the event handler. - * - * @return {boolean} `true` if the event had listeners, else `false`. - */ + // The renderable Game Object that is being used for the bitmap mask + var bitmapMask = mask.bitmapMask; -/** - * Add a listener for a given event. - * - * @method Phaser.Events.EventEmitter#on - * @since 3.0.0 - * - * @param {(string|symbol)} event - The event name. - * @param {function} fn - The listener function. - * @param {*} [context=this] - The context to invoke the listener with. - * - * @return {this} `this`. - */ + if (bitmapMask && gl) + { + renderer.drawBitmapMask(bitmapMask, camera, this); -/** - * Add a listener for a given event. - * - * @method Phaser.Events.EventEmitter#addListener - * @since 3.0.0 - * - * @param {(string|symbol)} event - The event name. - * @param {function} fn - The listener function. - * @param {*} [context=this] - The context to invoke the listener with. - * - * @return {this} `this`. - */ + if (renderTarget) + { + this.set2f('uResolution', renderTarget.width, renderTarget.height); + } -/** - * Add a one-time listener for a given event. - * - * @method Phaser.Events.EventEmitter#once - * @since 3.0.0 - * - * @param {(string|symbol)} event - The event name. - * @param {function} fn - The listener function. - * @param {*} [context=this] - The context to invoke the listener with. - * - * @return {this} `this`. - */ + this.set1i('uInvertMaskAlpha', mask.invertAlpha); -/** - * Remove the listeners of a given event. - * - * @method Phaser.Events.EventEmitter#removeListener - * @since 3.0.0 - * - * @param {(string|symbol)} event - The event name. - * @param {function} [fn] - Only remove the listeners that match this function. - * @param {*} [context] - Only remove the listeners that have this context. - * @param {boolean} [once] - Only remove one-time listeners. - * - * @return {this} `this`. - */ + // Finally, draw a triangle filling the whole screen + gl.drawArrays(this.topology, 0, 3); -/** - * Remove the listeners of a given event. - * - * @method Phaser.Events.EventEmitter#off - * @since 3.0.0 - * - * @param {(string|symbol)} event - The event name. - * @param {function} [fn] - Only remove the listeners that match this function. - * @param {*} [context] - Only remove the listeners that have this context. - * @param {boolean} [once] - Only remove one-time listeners. - * - * @return {this} `this`. - */ + if (renderTarget) + { + this.set2f('uResolution', this.width, this.height); + } -/** - * Remove all listeners, or those of the specified event. - * - * @method Phaser.Events.EventEmitter#removeAllListeners - * @since 3.0.0 - * - * @param {(string|symbol)} [event] - The event name. - * - * @return {this} `this`. - */ + // Clear gl.TEXTURE1 + gl.bindTexture(gl.TEXTURE_2D, null); + } + } -PluginCache.register('EventEmitter', EventEmitter, 'events'); +}); -module.exports = EventEmitter; +module.exports = BitmapMaskPipeline; /***/ }), -/* 920 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 81828: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddToDOM = __webpack_require__(142); -var AnimationManager = __webpack_require__(321); -var CacheManager = __webpack_require__(325); -var CanvasPool = __webpack_require__(31); -var Class = __webpack_require__(0); -var Config = __webpack_require__(346); -var CreateDOMContainer = __webpack_require__(921); -var CreateRenderer = __webpack_require__(366); -var DataManager = __webpack_require__(101); -var DebugHeader = __webpack_require__(384); -var Device = __webpack_require__(347); -var DOMContentLoaded = __webpack_require__(400); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(22); -var InputManager = __webpack_require__(409); -var PluginCache = __webpack_require__(24); -var PluginManager = __webpack_require__(414); -var ScaleManager = __webpack_require__(415); -var SceneManager = __webpack_require__(417); -var TextureEvents = __webpack_require__(106); -var TextureManager = __webpack_require__(422); -var TimeStep = __webpack_require__(385); -var VisibilityHandler = __webpack_require__(387); - -if (true) -{ - var SoundManagerCreator = __webpack_require__(426); -} - -if (false) -{ var FacebookInstantGamesPlugin; } +var Class = __webpack_require__(56694); +var FX = __webpack_require__(58136); +var FX_CONST = __webpack_require__(47406); +var GetFastValue = __webpack_require__(72632); +var PreFXPipeline = __webpack_require__(87228); +var Shaders = __webpack_require__(92462); +var Utils = __webpack_require__(75512); /** * @classdesc - * The Phaser.Game instance is the main controller for the entire Phaser game. It is responsible - * for handling the boot process, parsing the configuration values, creating the renderer, - * and setting-up all of the global Phaser systems, such as sound and input. - * Once that is complete it will start the Scene Manager and then begin the main game loop. + * The FXPipeline is a built-in pipeline that controls the application of FX Controllers during + * the rendering process. It maintains all of the FX shaders, instances of Post FX Pipelines and + * is responsible for rendering. * - * You should generally avoid accessing any of the systems created by Game, and instead use those - * made available to you via the Phaser.Scene Systems class instead. + * You should rarely interact with this pipeline directly. Instead, use the FX Controllers that + * is part of the Game Object class in order to manage the effects. * - * @class Game - * @memberof Phaser + * @class FXPipeline + * @extends Phaser.Renderer.WebGL.Pipelines.PreFXPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines * @constructor - * @fires Phaser.Core.Events#BLUR - * @fires Phaser.Core.Events#FOCUS - * @fires Phaser.Core.Events#HIDDEN - * @fires Phaser.Core.Events#VISIBLE - * @since 3.0.0 + * @since 3.60.0 * - * @param {Phaser.Types.Core.GameConfig} [GameConfig] - The configuration object for your Phaser Game instance. + * @param {Phaser.Game} game - A reference to the Phaser game instance. */ -var Game = new Class({ +var FXPipeline = new Class({ + + Extends: PreFXPipeline, initialize: - function Game (config) - { - /** - * The parsed Game Configuration object. - * - * The values stored within this object are read-only and should not be changed at run-time. - * - * @name Phaser.Game#config - * @type {Phaser.Core.Config} - * @readonly - * @since 3.0.0 - */ - this.config = new Config(config); + function FXPipeline (config) + { + // This order is fixed to match with the FX_CONST. Do not adjust. + config.shaders = [ + Utils.setGlowQuality(Shaders.FXGlowFrag, config.game), + Shaders.FXShadowFrag, + Shaders.FXPixelateFrag, + Shaders.FXVignetteFrag, + Shaders.FXShineFrag, + Shaders.FXBlurLowFrag, + Shaders.FXBlurMedFrag, + Shaders.FXBlurHighFrag, + Shaders.FXGradientFrag, + Shaders.FXBloomFrag, + Shaders.ColorMatrixFrag, + Shaders.FXCircleFrag, + Shaders.FXBarrelFrag, + Shaders.FXDisplacementFrag, + Shaders.FXWipeFrag, + Shaders.FXBokehFrag + ]; - /** - * A reference to either the Canvas or WebGL Renderer that this Game is using. - * - * @name Phaser.Game#renderer - * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} - * @since 3.0.0 - */ - this.renderer = null; + PreFXPipeline.call(this, config); - /** - * A reference to an HTML Div Element used as the DOM Element Container. - * - * Only set if `createDOMContainer` is `true` in the game config (by default it is `false`) and - * if you provide a parent element to insert the Phaser Game inside. - * - * See the DOM Element Game Object for more details. - * - * @name Phaser.Game#domContainer - * @type {HTMLDivElement} - * @since 3.17.0 - */ - this.domContainer = null; + var game = this.game; /** - * A reference to the HTML Canvas Element that Phaser uses to render the game. - * This is created automatically by Phaser unless you provide a `canvas` property - * in your Game Config. + * An instance of the Glow Post FX Pipeline. * - * @name Phaser.Game#canvas - * @type {HTMLCanvasElement} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#glow + * @type {Phaser.Renderer.WebGL.Pipelines.FX.GlowFXPipeline} + * @since 3.60.0 */ - this.canvas = null; + this.glow = new FX.Glow(game); /** - * A reference to the Rendering Context belonging to the Canvas Element this game is rendering to. - * If the game is running under Canvas it will be a 2d Canvas Rendering Context. - * If the game is running under WebGL it will be a WebGL Rendering Context. - * This context is created automatically by Phaser unless you provide a `context` property - * in your Game Config. + * An instance of the Shadow Post FX Pipeline. * - * @name Phaser.Game#context - * @type {(CanvasRenderingContext2D|WebGLRenderingContext)} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#shadow + * @type {Phaser.Renderer.WebGL.Pipelines.FX.ShadowFXPipeline} + * @since 3.60.0 */ - this.context = null; + this.shadow = new FX.Shadow(game); /** - * A flag indicating when this Game instance has finished its boot process. + * An instance of the Pixelate Post FX Pipeline. * - * @name Phaser.Game#isBooted - * @type {boolean} - * @readonly - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#pixelate + * @type {Phaser.Renderer.WebGL.Pipelines.FX.PixelateFXPipeline} + * @since 3.60.0 */ - this.isBooted = false; + this.pixelate = new FX.Pixelate(game); /** - * A flag indicating if this Game is currently running its game step or not. + * An instance of the Vignette Post FX Pipeline. * - * @name Phaser.Game#isRunning - * @type {boolean} - * @readonly - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#vignette + * @type {Phaser.Renderer.WebGL.Pipelines.FX.VignetteFXPipeline} + * @since 3.60.0 */ - this.isRunning = false; + this.vignette = new FX.Vignette(game); /** - * An Event Emitter which is used to broadcast game-level events from the global systems. + * An instance of the Shine Post FX Pipeline. * - * @name Phaser.Game#events - * @type {Phaser.Events.EventEmitter} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#shine + * @type {Phaser.Renderer.WebGL.Pipelines.FX.ShineFXPipeline} + * @since 3.60.0 */ - this.events = new EventEmitter(); + this.shine = new FX.Shine(game); /** - * An instance of the Animation Manager. + * An instance of the Gradient Post FX Pipeline. * - * The Animation Manager is a global system responsible for managing all animations used within your game. - * - * @name Phaser.Game#anims - * @type {Phaser.Animations.AnimationManager} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#gradient + * @type {Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline} + * @since 3.60.0 */ - this.anims = new AnimationManager(this); + this.gradient = new FX.Gradient(game); /** - * An instance of the Texture Manager. - * - * The Texture Manager is a global system responsible for managing all textures being used by your game. + * An instance of the Circle Post FX Pipeline. * - * @name Phaser.Game#textures - * @type {Phaser.Textures.TextureManager} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#circle + * @type {Phaser.Renderer.WebGL.Pipelines.FX.CircleFXPipeline} + * @since 3.60.0 */ - this.textures = new TextureManager(this); + this.circle = new FX.Circle(game); /** - * An instance of the Cache Manager. - * - * The Cache Manager is a global system responsible for caching, accessing and releasing external game assets. + * An instance of the Barrel Post FX Pipeline. * - * @name Phaser.Game#cache - * @type {Phaser.Cache.CacheManager} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#barrel + * @type {Phaser.Renderer.WebGL.Pipelines.FX.BarrelFXPipeline} + * @since 3.60.0 */ - this.cache = new CacheManager(this); + this.barrel = new FX.Barrel(game); /** - * An instance of the Data Manager + * An instance of the Wipe Post FX Pipeline. * - * @name Phaser.Game#registry - * @type {Phaser.Data.DataManager} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#wipe + * @type {Phaser.Renderer.WebGL.Pipelines.FX.WipeFXPipeline} + * @since 3.60.0 */ - this.registry = new DataManager(this); + this.wipe = new FX.Wipe(game); /** - * An instance of the Input Manager. + * An instance of the Bokeh Post FX Pipeline. * - * The Input Manager is a global system responsible for the capture of browser-level input events. - * - * @name Phaser.Game#input - * @type {Phaser.Input.InputManager} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#bokeh + * @type {Phaser.Renderer.WebGL.Pipelines.FX.BokehFXPipeline} + * @since 3.60.0 */ - this.input = new InputManager(this, this.config); + this.bokeh = new FX.Bokeh(game); + + // This array is intentionally sparse. Do not adjust. + var fxHandlers = []; + + fxHandlers[FX_CONST.GLOW] = this.onGlow; + fxHandlers[FX_CONST.SHADOW] = this.onShadow; + fxHandlers[FX_CONST.PIXELATE] = this.onPixelate; + fxHandlers[FX_CONST.VIGNETTE] = this.onVignette; + fxHandlers[FX_CONST.SHINE] = this.onShine; + fxHandlers[FX_CONST.BLUR] = this.onBlur; + fxHandlers[FX_CONST.GRADIENT] = this.onGradient; + fxHandlers[FX_CONST.BLOOM] = this.onBloom; + fxHandlers[FX_CONST.COLOR_MATRIX] = this.onColorMatrix; + fxHandlers[FX_CONST.CIRCLE] = this.onCircle; + fxHandlers[FX_CONST.BARREL] = this.onBarrel; + fxHandlers[FX_CONST.DISPLACEMENT] = this.onDisplacement; + fxHandlers[FX_CONST.WIPE] = this.onWipe; + fxHandlers[FX_CONST.BOKEH] = this.onBokeh; /** - * An instance of the Scene Manager. + * An array containing references to the methods that map to the FX CONSTs. * - * The Scene Manager is a global system responsible for creating, modifying and updating the Scenes in your game. + * This array is intentionally sparse. Do not adjust. * - * @name Phaser.Game#scene - * @type {Phaser.Scenes.SceneManager} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#fxHandlers + * @type {function[]} + * @since 3.60.0 */ - this.scene = new SceneManager(this, this.config.sceneConfig); + this.fxHandlers = fxHandlers; /** - * A reference to the Device inspector. - * - * Contains information about the device running this game, such as OS, browser vendor and feature support. - * Used by various systems to determine capabilities and code paths. + * The source Render Target. * - * @name Phaser.Game#device - * @type {Phaser.DeviceConf} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#source + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.60.0 */ - this.device = Device; + this.source; /** - * An instance of the Scale Manager. + * The target Render Target. * - * The Scale Manager is a global system responsible for handling scaling of the game canvas. - * - * @name Phaser.Game#scale - * @type {Phaser.Scale.ScaleManager} - * @since 3.16.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#target + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.60.0 */ - this.scale = new ScaleManager(this, this.config); + this.target; /** - * An instance of the base Sound Manager. - * - * The Sound Manager is a global system responsible for the playback and updating of all audio in your game. - * - * You can disable the inclusion of the Sound Manager in your build by toggling the webpack `FEATURE_SOUND` flag. + * The swap Render Target. * - * @name Phaser.Game#sound - * @type {(Phaser.Sound.NoAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager)} - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.FXPipeline#swap + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.60.0 */ - this.sound = null; + this.swap; + }, - if (true) + /** + * Takes the currently bound Game Object and runs all of its pre-render effects, + * using the given Render Target as the source. + * + * Finally calls `drawToGame` to copy the result to the Game Canvas. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onDraw + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} target1 - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target2 - The target Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target3 - The swap Render Target. + */ + onDraw: function (target1, target2, target3) + { + this.source = target1; + this.target = target2; + this.swap = target3; + + var width = target1.width; + var height = target1.height; + + var sprite = this.tempSprite; + var handlers = this.fxHandlers; + + if (sprite && sprite.preFX) { - this.sound = SoundManagerCreator.create(this); + var fx = sprite.preFX.list; + + for (var i = 0; i < fx.length; i++) + { + var controller = fx[i]; + + if (controller.active) + { + handlers[controller.type].call(this, controller, width, height); + } + } } - /** - * An instance of the Time Step. - * - * The Time Step is a global system responsible for setting-up and responding to the browser frame events, processing - * them and calculating delta values. It then automatically calls the game step. - * - * @name Phaser.Game#loop - * @type {Phaser.Core.TimeStep} - * @since 3.0.0 - */ - this.loop = new TimeStep(this, this.config.fps); + this.drawToGame(this.source); + }, - /** - * An instance of 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.Game#plugins - * @type {Phaser.Plugins.PluginManager} - * @since 3.0.0 - */ - this.plugins = new PluginManager(this, this.config); + /** + * Takes the source and target and runs a copy from source to target. + * + * This will use the current shader and pipeline. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#runDraw + * @since 3.60.0 + */ + runDraw: function () + { + var source = this.source; + var target = this.target; - if (false) - {} + this.copy(source, target); - /** - * Is this Game pending destruction at the start of the next frame? - * - * @name Phaser.Game#pendingDestroy - * @type {boolean} - * @private - * @since 3.5.0 - */ - this.pendingDestroy = false; + this.source = target; + this.target = source; + }, - /** - * Remove the Canvas once the destroy is over? - * - * @name Phaser.Game#removeCanvas - * @type {boolean} - * @private - * @since 3.5.0 - */ - this.removeCanvas = false; + /** + * Runs the Glow FX controller. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onGlow + * @since 3.60.0 + * + * @param {Phaser.FX.Glow} config - The Glow FX controller. + * @param {number} width - The width of the target. + * @param {number} height - The height of the target. + */ + onGlow: function (config, width, height) + { + var shader = this.shaders[FX_CONST.GLOW]; - /** - * Remove everything when the game is destroyed. - * You cannot create a new Phaser instance on the same web page after doing this. - * - * @name Phaser.Game#noReturn - * @type {boolean} - * @private - * @since 3.12.0 - */ - this.noReturn = false; + this.setShader(shader); - /** - * Does the window the game is running in currently have focus or not? - * This is modified by the VisibilityHandler. - * - * @name Phaser.Game#hasFocus - * @type {boolean} - * @readonly - * @since 3.9.0 - */ - this.hasFocus = false; + this.glow.onPreRender(config, shader, width, height); - // Wait for the DOM Ready event, then call boot. - DOMContentLoaded(this.boot.bind(this)); + this.runDraw(); }, /** - * This method is called automatically when the DOM is ready. It is responsible for creating the renderer, - * displaying the Debug Header, adding the game canvas to the DOM and emitting the 'boot' event. - * It listens for a 'ready' event from the base systems and once received it will call `Game.start`. + * Runs the Shadow FX controller. * - * @method Phaser.Game#boot - * @protected - * @fires Phaser.Core.Events#BOOT - * @listens Phaser.Textures.Events#READY - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onShadow + * @since 3.60.0 + * + * @param {Phaser.FX.Shadow} config - The Shadow FX controller. */ - boot: function () + onShadow: function (config) { - if (!PluginCache.hasCore('EventEmitter')) - { - console.warn('Aborting. Core Plugins missing.'); - return; - } + var shader = this.shaders[FX_CONST.SHADOW]; - this.isBooted = true; + this.setShader(shader); - this.config.preBoot(this); + this.shadow.onPreRender(config, shader); - this.scale.preBoot(); + this.runDraw(); + }, - CreateRenderer(this); + /** + * Runs the Pixelate FX controller. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onPixelate + * @since 3.60.0 + * + * @param {Phaser.FX.Pixelate} config - The Pixelate FX controller. + * @param {number} width - The width of the target. + * @param {number} height - The height of the target. + */ + onPixelate: function (config, width, height) + { + var shader = this.shaders[FX_CONST.PIXELATE]; - CreateDOMContainer(this); + this.setShader(shader); - DebugHeader(this); + this.pixelate.onPreRender(config, shader, width, height); - AddToDOM(this.canvas, this.config.parent); + this.runDraw(); + }, - // The Texture Manager has to wait on a couple of non-blocking events before it's fully ready. - // So it will emit this internal event when done: - this.textures.once(TextureEvents.READY, this.texturesReady, this); + /** + * Runs the Vignette FX controller. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onVignette + * @since 3.60.0 + * + * @param {Phaser.FX.Vignette} config - The Vignette FX controller. + */ + onVignette: function (config) + { + var shader = this.shaders[FX_CONST.VIGNETTE]; - this.events.emit(Events.BOOT); + this.setShader(shader); + + this.vignette.onPreRender(config, shader); + + this.runDraw(); }, /** - * Called automatically when the Texture Manager has finished setting up and preparing the - * default textures. + * Runs the Shine FX controller. * - * @method Phaser.Game#texturesReady - * @private - * @fires Phaser.Game#READY - * @since 3.12.0 + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onShine + * @since 3.60.0 + * + * @param {Phaser.FX.Shine} config - The Shine FX controller. + * @param {number} width - The width of the target. + * @param {number} height - The height of the target. */ - texturesReady: function () + onShine: function (config, width, height) { - // Start all the other systems - this.events.emit(Events.READY); + var shader = this.shaders[FX_CONST.SHINE]; - this.start(); + this.setShader(shader); + + this.shine.onPreRender(config, shader, width, height); + + this.runDraw(); }, /** - * Called automatically by Game.boot once all of the global systems have finished setting themselves up. - * By this point the Game is now ready to start the main loop running. - * It will also enable the Visibility Handler. + * Runs the Blur FX controller. * - * @method Phaser.Game#start - * @protected - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onBlur + * @since 3.60.0 + * + * @param {Phaser.FX.Blur} config - The Blur FX controller. + * @param {number} width - The width of the target. + * @param {number} height - The height of the target. */ - start: function () + onBlur: function (config, width, height) { - this.isRunning = true; + var quality = GetFastValue(config, 'quality'); - this.config.postBoot(this); + var shader = this.shaders[FX_CONST.BLUR + quality]; - if (this.renderer) + this.setShader(shader); + + this.set1i('uMainSampler', 0); + this.set2f('resolution', width, height); + this.set1f('strength', GetFastValue(config, 'strength')); + this.set3fv('color', GetFastValue(config, 'glcolor')); + + var x = GetFastValue(config, 'x'); + var y = GetFastValue(config, 'y'); + var steps = GetFastValue(config, 'steps'); + + for (var i = 0; i < steps; i++) { - this.loop.start(this.step.bind(this)); + this.set2f('offset', x, 0); + this.runDraw(); + + this.set2f('offset', 0, y); + this.runDraw(); } - else + }, + + /** + * Runs the Gradient FX controller. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onGradient + * @since 3.60.0 + * + * @param {Phaser.FX.Gradient} config - The Gradient FX controller. + */ + onGradient: function (config) + { + var shader = this.shaders[FX_CONST.GRADIENT]; + + this.setShader(shader); + + this.gradient.onPreRender(config, shader); + + this.runDraw(); + }, + + /** + * Runs the Bloom FX controller. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onBloom + * @since 3.60.0 + * + * @param {Phaser.FX.Bloom} config - The Bloom FX controller. + * @param {number} width - The width of the target. + * @param {number} height - The height of the target. + */ + onBloom: function (config, width, height) + { + var shader = this.shaders[FX_CONST.BLOOM]; + + this.copySprite(this.source, this.swap); + + this.setShader(shader); + + this.set1i('uMainSampler', 0); + this.set1f('strength', GetFastValue(config, 'blurStrength')); + this.set3fv('color', GetFastValue(config, 'glcolor')); + + var x = (2 / width) * GetFastValue(config, 'offsetX'); + var y = (2 / height) * GetFastValue(config, 'offsetY'); + var steps = GetFastValue(config, 'steps'); + + for (var i = 0; i < steps; i++) { - this.loop.start(this.headlessStep.bind(this)); + this.set2f('offset', x, 0); + this.runDraw(); + + this.set2f('offset', 0, y); + this.runDraw(); } - VisibilityHandler(this); + this.blendFrames(this.swap, this.source, this.target, GetFastValue(config, 'strength')); + this.copySprite(this.target, this.source); + }, - var eventEmitter = this.events; + /** + * Runs the ColorMatrix FX controller. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onColorMatrix + * @since 3.60.0 + * + * @param {Phaser.FX.ColorMatrix} config - The ColorMatrix FX controller. + */ + onColorMatrix: function (config) + { + this.setShader(this.colorMatrixShader); - eventEmitter.on(Events.HIDDEN, this.onHidden, this); - eventEmitter.on(Events.VISIBLE, this.onVisible, this); - eventEmitter.on(Events.BLUR, this.onBlur, this); - eventEmitter.on(Events.FOCUS, this.onFocus, this); + this.set1fv('uColorMatrix', config.getData()); + this.set1f('uAlpha', config.alpha); + + this.runDraw(); }, /** - * The main Game Step. Called automatically by the Time Step, once per browser frame (typically as a result of - * Request Animation Frame, or Set Timeout on very old browsers.) + * Runs the Circle FX controller. * - * The step will update the global managers first, then proceed to update each Scene in turn, via the Scene Manager. + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onCircle + * @since 3.60.0 * - * It will then render each Scene in turn, via the Renderer. This process emits `prerender` and `postrender` events. + * @param {Phaser.FX.Circle} config - The Circle FX controller. + * @param {number} width - The width of the target. + * @param {number} height - The height of the target. + */ + onCircle: function (config, width, height) + { + var shader = this.shaders[FX_CONST.CIRCLE]; + + this.setShader(shader); + + this.circle.onPreRender(config, shader, width, height); + + this.runDraw(); + }, + + /** + * Runs the Barrel FX controller. * - * @method Phaser.Game#step - * @fires Phaser.Core.Events#PRE_STEP - * @fires Phaser.Core.Events#STEP - * @fires Phaser.Core.Events#POST_STEP - * @fires Phaser.Core.Events#PRE_RENDER - * @fires Phaser.Core.Events#POST_RENDER - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onBarrel + * @since 3.60.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. + * @param {Phaser.FX.Barrel} config - The Barrel FX controller. */ - step: function (time, delta) + onBarrel: function (config) { - if (this.pendingDestroy) - { - return this.runDestroy(); - } + var shader = this.shaders[FX_CONST.BARREL]; - var eventEmitter = this.events; + this.setShader(shader); - // Global Managers like Input and Sound update in the prestep + this.barrel.onPreRender(config, shader); + + this.runDraw(); + }, + + /** + * Runs the Displacement FX controller. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onDisplacement + * @since 3.60.0 + * + * @param {Phaser.FX.Displacement} config - The Displacement FX controller. + */ + onDisplacement: function (config) + { + this.setShader(this.shaders[FX_CONST.DISPLACEMENT]); + + this.set1i('uDisplacementSampler', 1); + this.set2f('amount', config.x, config.y); + + this.bindTexture(config.glTexture, 1); + + this.runDraw(); + }, + + /** + * Runs the Wipe FX controller. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onWipe + * @since 3.60.0 + * + * @param {Phaser.FX.Wipe} config - The Wipe FX controller. + */ + onWipe: function (config) + { + var shader = this.shaders[FX_CONST.WIPE]; + + this.setShader(shader); + + this.wipe.onPreRender(config, shader); + + this.runDraw(); + }, + + /** + * Runs the Bokeh FX controller. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onBokeh + * @since 3.60.0 + * + * @param {Phaser.FX.Bokeh} config - The Bokeh FX controller. + */ + onBokeh: function (config, width, height) + { + var shader = this.shaders[FX_CONST.BOKEH]; + + this.setShader(shader); + + this.bokeh.onPreRender(config, shader, width, height); + + this.runDraw(); + }, + + /** + * Destroys all shader instances, removes all object references and nulls all external references. + * + * @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#destroy + * @since 3.60.0 + * + * @return {this} This WebGLPipeline instance. + */ + destroy: function () + { + this.glow.destroy(); + this.shadow.destroy(); + this.pixelate.destroy(); + this.vignette.destroy(); + this.shine.destroy(); + this.gradient.destroy(); + this.circle.destroy(); + this.barrel.destroy(); + this.wipe.destroy(); + this.bokeh.destroy(); + + this.fxHandlers = null; + this.source = null; + this.target = null; + this.swap = null; + + PreFXPipeline.prototype.destroy.call(this); + + return this; + } +}); + +module.exports = FXPipeline; + + +/***/ }), + +/***/ 66901: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var LightShaderSourceFS = __webpack_require__(65045); +var MultiPipeline = __webpack_require__(77310); +var TransformMatrix = __webpack_require__(69360); +var Vec2 = __webpack_require__(93736); +var WebGLPipeline = __webpack_require__(44775); + +/** + * @classdesc + * The Light Pipeline is an extension of the Multi Pipeline and uses a custom shader + * designed to handle forward diffused rendering of 2D lights in a Scene. + * + * The shader works in tandem with Light Game Objects, and optionally texture normal maps, + * to provide an ambient illumination effect. + * + * If you wish to provide your own shader, you can use the `%LIGHT_COUNT%` declaration in the source, + * and it will be automatically replaced at run-time with the total number of configured lights. + * + * The maximum number of lights can be set in the Render Config `maxLights` property and defaults to 10. + * + * Prior to Phaser v3.50 this pipeline was called the `ForwardDiffuseLightPipeline`. + * + * The fragment shader it uses can be found in `shaders/src/Light.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 those from the Multi Pipeline, plus: + * + * `uMainSampler` (sampler2D) + * `uNormSampler` (sampler2D) + * `uCamera` (vec4) + * `uResolution` (vec2) + * `uAmbientLightColor` (vec3) + * `uInverseRotationMatrix` (mat3) + * `uLights` (Light struct) + * + * @class LightPipeline + * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + */ +var LightPipeline = new Class({ + + Extends: MultiPipeline, + + initialize: + + function LightPipeline (config) + { + var fragShader = GetFastValue(config, 'fragShader', LightShaderSourceFS); + + config.fragShader = fragShader.replace('%LIGHT_COUNT%', config.game.renderer.config.maxLights); + + MultiPipeline.call(this, config); + + /** + * Inverse rotation matrix for normal map rotations. + * + * @name Phaser.Renderer.WebGL.Pipelines.LightPipeline#inverseRotationMatrix + * @type {Float32Array} + * @private + * @since 3.16.0 + */ + this.inverseRotationMatrix = new Float32Array([ + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 + ]); + + /** + * Stores a default normal map, which is an object with a `glTexture` property that + * maps to a 1x1 texture of the color #7f7fff created in the `boot` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.LightPipeline#defaultNormalMap + * @type {object} + * @since 3.50.0 + */ + this.defaultNormalMap; + + /** + * The currently bound normal map texture at texture unit one, if any. + * + * @name Phaser.Renderer.WebGL.WebGLRenderer#currentNormalMap; + * @type {?WebGLTexture} + * @since 3.60.0 + */ + this.currentNormalMap; + + /** + * A boolean that is set automatically during `onRender` that determines + * if the Scene LightManager is active, or not. + * + * @name Phaser.Renderer.WebGL.Pipelines.LightPipeline#lightsActive + * @type {boolean} + * @readonly + * @since 3.53.0 + */ + this.lightsActive = true; + + /** + * A persistent calculation vector used when processing the lights. + * + * @name Phaser.Renderer.WebGL.Pipelines.LightPipeline#tempVec2 + * @type {Phaser.Math.Vector2} + * @since 3.60.0 + */ + this.tempVec2 = new Vec2(); + + /** + * A temporary Transform Matrix used for parent Container calculations without them needing their own local copy. + * + * @name Phaser.Renderer.WebGL.Pipelines.LightPipeline#_tempMatrix + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.60.0 + */ + this._tempMatrix = new TransformMatrix(); + + /** + * A temporary Transform Matrix used for parent Container calculations without them needing their own local copy. + * + * @name Phaser.Renderer.WebGL.Pipelines.LightPipeline#_tempMatrix2 + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @private + * @since 3.60.0 + */ + this._tempMatrix2 = new TransformMatrix(); + }, + + /** + * Called when the Game has fully booted and the Renderer has finished setting up. + * + * By this stage all Game level systems are now in place and you can perform any final + * tasks that the pipeline may need that relied on game systems such as the Texture Manager. + * + * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#boot + * @since 3.11.0 + */ + boot: function () + { + WebGLPipeline.prototype.boot.call(this); + + var gl = this.gl; + + var tempTexture = gl.createTexture(); + + gl.activeTexture(gl.TEXTURE0); + + gl.bindTexture(gl.TEXTURE_2D, tempTexture); + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([ 127, 127, 255, 255 ])); + + this.defaultNormalMap = { glTexture: tempTexture }; + }, + + /** + * This function sets all the needed resources for each camera pass. + * + * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#onRender + * @ignore + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene being rendered. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered with. + */ + onRender: function (scene, camera) + { + var lightManager = scene.sys.lights; + + this.lightsActive = false; - eventEmitter.emit(Events.PRE_STEP, time, delta); + if (!lightManager || !lightManager.active) + { + return; + } - // This is mostly meant for user-land code and plugins + var lights = lightManager.getLights(camera); + var lightsCount = lights.length; - eventEmitter.emit(Events.STEP, time, delta); + // Ok, we're good to go ... - // Update the Scene Manager and all active Scenes + this.lightsActive = true; - this.scene.update(time, delta); + var i; + var renderer = this.renderer; + var height = renderer.height; + var cameraMatrix = camera.matrix; + var tempVec2 = this.tempVec2; - // Our final event before rendering starts + this.set1i('uMainSampler', 0); + this.set1i('uNormSampler', 1); + this.set2f('uResolution', this.width / 2, this.height / 2); + this.set4f('uCamera', camera.x, camera.y, camera.rotation, camera.zoom); + this.set3f('uAmbientLightColor', lightManager.ambientColor.r, lightManager.ambientColor.g, lightManager.ambientColor.b); + this.set1i('uLightCount', lightsCount); - eventEmitter.emit(Events.POST_STEP, time, delta); + for (i = 0; i < lightsCount; i++) + { + var light = lights[i].light; + var color = light.color; - var renderer = this.renderer; + var lightName = 'uLights[' + i + '].'; - // Run the Pre-render (clearing the canvas, setting background colors, etc) + cameraMatrix.transformPoint(light.x, light.y, tempVec2); - renderer.preRender(); + this.set2f(lightName + 'position', tempVec2.x - (camera.scrollX * light.scrollFactorX * camera.zoom), height - (tempVec2.y - (camera.scrollY * light.scrollFactorY) * camera.zoom)); + this.set3f(lightName + 'color', color.r, color.g, color.b); + this.set1f(lightName + 'intensity', light.intensity); + this.set1f(lightName + 'radius', light.radius); + } - eventEmitter.emit(Events.PRE_RENDER, renderer, time, delta); + this.currentNormalMapRotation = null; + }, - // The main render loop. Iterates all Scenes and all Cameras in those scenes, rendering to the renderer instance. + /** + * Rotates the normal map vectors inversely by the given angle. + * Only works in 2D space. + * + * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#setNormalMapRotation + * @since 3.16.0 + * + * @param {number} rotation - The angle of rotation in radians. + */ + setNormalMapRotation: function (rotation) + { + if (rotation !== this.currentNormalMapRotation || this.vertexCount === 0) + { + if (this.vertexCount > 0) + { + this.flush(); + } - this.scene.render(renderer); + var inverseRotationMatrix = this.inverseRotationMatrix; - // The Post-Render call. Tidies up loose end, takes snapshots, etc. + if (rotation) + { + var rot = -rotation; + var c = Math.cos(rot); + var s = Math.sin(rot); - renderer.postRender(); + inverseRotationMatrix[1] = s; + inverseRotationMatrix[3] = -s; + inverseRotationMatrix[0] = inverseRotationMatrix[4] = c; + } + else + { + inverseRotationMatrix[0] = inverseRotationMatrix[4] = 1; + inverseRotationMatrix[1] = inverseRotationMatrix[3] = 0; + } - // The final event before the step repeats. Your last chance to do anything to the canvas before it all starts again. + this.setMatrix3fv('uInverseRotationMatrix', false, inverseRotationMatrix); - eventEmitter.emit(Events.POST_RENDER, renderer, time, delta); + this.currentNormalMapRotation = rotation; + } }, /** - * A special version of the Game Step for the HEADLESS renderer only. - * - * The main Game Step. Called automatically by the Time Step, once per browser frame (typically as a result of - * Request Animation Frame, or Set Timeout on very old browsers.) - * - * The step will update the global managers first, then proceed to update each Scene in turn, via the Scene Manager. - * - * This process emits `prerender` and `postrender` events, even though nothing actually displays. + * Assigns a texture to the current batch. If a different texture is already set it creates a new batch object. * - * @method Phaser.Game#headlessStep - * @fires Phaser.Game#PRE_RENDER - * @fires Phaser.Game#POST_RENDER - * @since 3.2.0 + * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#setTexture2D + * @ignore + * @since 3.50.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. + * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch. If not given uses blankTexture. + * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object being rendered or added to the batch. */ - headlessStep: function (time, delta) + setTexture2D: function (texture, gameObject) { - if (this.pendingDestroy) - { - return this.runDestroy(); - } + var renderer = this.renderer; - var eventEmitter = this.events; + if (texture === undefined) { texture = renderer.whiteTexture; } - // Global Managers + var normalMap = this.getNormalMap(gameObject); - eventEmitter.emit(Events.PRE_STEP, time, delta); + if (this.isNewNormalMap(texture, normalMap)) + { + this.flush(); - eventEmitter.emit(Events.STEP, time, delta); + this.createBatch(texture); - // Scenes + this.addTextureToBatch(normalMap); - this.scene.update(time, delta); + this.currentNormalMap = normalMap; + } - eventEmitter.emit(Events.POST_STEP, time, delta); + var rotation = 0; - // Render + if (gameObject && gameObject.parentContainer) + { + var matrix = gameObject.getWorldTransformMatrix(this._tempMatrix, this._tempMatrix2); + + rotation = matrix.rotationNormalized; + } + else if (gameObject) + { + rotation = gameObject.rotation; + } - eventEmitter.emit(Events.PRE_RENDER); + this.setNormalMapRotation(rotation); - eventEmitter.emit(Events.POST_RENDER); + return 0; }, /** - * Called automatically by the Visibility Handler. - * This will pause the main loop and then emit a pause event. + * Custom pipelines can use this method in order to perform any required pre-batch tasks + * for the given Game Object. It must return the texture unit the Game Object was assigned. * - * @method Phaser.Game#onHidden - * @protected - * @fires Phaser.Core.Events#PAUSE - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#setGameObject + * @ignore + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object being rendered or added to the batch. + * @param {Phaser.Textures.Frame} [frame] - Optional frame to use. Can override that of the Game Object. + * + * @return {number} The texture unit the Game Object has been assigned. */ - onHidden: function () + setGameObject: function (gameObject, frame) { - this.loop.pause(); + if (frame === undefined) { frame = gameObject.frame; } - this.events.emit(Events.PAUSE); - }, + var texture = frame.glTexture; + var normalMap = this.getNormalMap(gameObject); - /** - * Called automatically by the Visibility Handler. - * This will resume the main loop and then emit a resume event. - * - * @method Phaser.Game#onVisible - * @protected - * @fires Phaser.Core.Events#RESUME - * @since 3.0.0 - */ - onVisible: function () - { - this.loop.resume(); + if (this.isNewNormalMap(texture, normalMap)) + { + this.flush(); - this.events.emit(Events.RESUME); - }, + this.createBatch(texture); - /** - * Called automatically by the Visibility Handler. - * This will set the main loop into a 'blurred' state, which pauses it. - * - * @method Phaser.Game#onBlur - * @protected - * @since 3.0.0 - */ - onBlur: function () - { - this.hasFocus = false; + this.addTextureToBatch(normalMap); - this.loop.blur(); + this.currentNormalMap = normalMap; + } + + if (gameObject.parentContainer) + { + var matrix = gameObject.getWorldTransformMatrix(this._tempMatrix, this._tempMatrix2); + + this.setNormalMapRotation(matrix.rotationNormalized); + } + else + { + this.setNormalMapRotation(gameObject.rotation); + } + + return 0; }, /** - * Called automatically by the Visibility Handler. - * This will set the main loop into a 'focused' state, which resumes it. + * Checks to see if the given diffuse and normal map textures are already bound, or not. * - * @method Phaser.Game#onFocus - * @protected - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.WebGLRenderer#isNewNormalMap + * @since 3.50.0 + * + * @param {WebGLTexture} texture - The WebGL diffuse texture. + * @param {WebGLTexture} normalMap - The WebGL normal map texture. + * + * @return {boolean} Returns `false` if this combination is already set, or `true` if it's a new combination. */ - onFocus: function () + isNewNormalMap: function (texture, normalMap) { - this.hasFocus = true; - - this.loop.focus(); + return (this.currentTexture !== texture || this.currentNormalMap !== normalMap); }, /** - * Returns the current game frame. + * Returns the normal map WebGLTexture from the given Game Object. + * If the Game Object doesn't have one, it returns the default normal map from this pipeline instead. * - * When the game starts running, the frame is incremented every time Request Animation Frame, or Set Timeout, fires. + * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#getNormalMap + * @since 3.50.0 * - * @method Phaser.Game#getFrame - * @since 3.16.0 + * @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object to get the normal map from. * - * @return {number} The current game frame. + * @return {WebGLTexture} The normal map texture. */ - getFrame: function () + getNormalMap: function (gameObject) { - return this.loop.frame; + var normalMap; + + if (!gameObject) + { + normalMap = this.defaultNormalMap; + } + else if (gameObject.displayTexture) + { + normalMap = gameObject.displayTexture.dataSource[gameObject.displayFrame.sourceIndex]; + } + else if (gameObject.texture) + { + normalMap = gameObject.texture.dataSource[gameObject.frame.sourceIndex]; + } + else if (gameObject.tileset) + { + if (Array.isArray(gameObject.tileset)) + { + normalMap = gameObject.tileset[0].image.dataSource[0]; + } + else + { + normalMap = gameObject.tileset.image.dataSource[0]; + } + } + + if (!normalMap) + { + normalMap = this.defaultNormalMap; + } + + return normalMap.glTexture; }, /** - * Returns the time that the current game step started at, as based on `performance.now`. + * Takes a Sprite Game Object, or any object that extends it, and adds it to the batch. * - * @method Phaser.Game#getTime - * @since 3.16.0 + * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#batchSprite + * @since 3.50.0 * - * @return {number} The current game timestamp. + * @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. */ - getTime: function () + batchSprite: function (gameObject, camera, parentTransformMatrix) { - return this.loop.now; + if (this.lightsActive) + { + MultiPipeline.prototype.batchSprite.call(this, gameObject, camera, parentTransformMatrix); + } }, /** - * Flags this Game instance as needing to be destroyed on the _next frame_, making this an asynchronous operation. - * - * It will wait until the current frame has completed and then call `runDestroy` internally. - * - * If you need to react to the games eventual destruction, listen for the `DESTROY` event. - * - * If you **do not** need to run Phaser again on the same web page you can set the `noReturn` argument to `true` and it will free-up - * memory being held by the core Phaser plugins. If you do need to create another game instance on the same page, leave this as `false`. + * Generic function for batching a textured quad using argument values instead of a Game Object. * - * @method Phaser.Game#destroy - * @fires Phaser.Core.Events#DESTROY - * @since 3.0.0 + * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#batchTexture + * @since 3.50.0 * - * @param {boolean} removeCanvas - Set to `true` if you would like the parent canvas element removed from the DOM, or `false` to leave it in place. - * @param {boolean} [noReturn=false] - If `true` all the core Phaser plugins are destroyed. You cannot create another instance of Phaser on the same web page if you do this. + * @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? */ - destroy: function (removeCanvas, noReturn) + 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) { - if (noReturn === undefined) { noReturn = false; } - - this.pendingDestroy = true; - - this.removeCanvas = removeCanvas; - this.noReturn = noReturn; + if (this.lightsActive) + { + MultiPipeline.prototype.batchTexture.call( + this, + 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 + ); + } }, /** - * Destroys this Phaser.Game instance, all global systems, all sub-systems and all Scenes. + * Adds a Texture Frame into the batch for rendering. * - * @method Phaser.Game#runDestroy - * @private - * @since 3.5.0 + * @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#batchTextureFrame + * @since 3.50.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. */ - runDestroy: function () + batchTextureFrame: function ( + frame, + x, y, + tint, alpha, + transformMatrix, + parentTransformMatrix + ) { - this.scene.destroy(); - - this.events.emit(Events.DESTROY); - - this.events.removeAllListeners(); - - if (this.renderer) - { - this.renderer.destroy(); - } - - if (this.removeCanvas && this.canvas) - { - CanvasPool.remove(this.canvas); - - if (this.canvas.parentNode) - { - this.canvas.parentNode.removeChild(this.canvas); - } - } - - if (this.domContainer) + if (this.lightsActive) { - this.domContainer.parentNode.removeChild(this.domContainer); + MultiPipeline.prototype.batchTextureFrame.call( + this, + frame, + x, y, + tint, alpha, + transformMatrix, + parentTransformMatrix + ); } - - this.loop.destroy(); - - this.pendingDestroy = false; } }); -module.exports = Game; - -/** - * "Computers are good at following instructions, but not at reading your mind." - Donald Knuth - */ +module.exports = LightPipeline; /***/ }), -/* 921 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71264: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AddToDOM = __webpack_require__(142); +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var MultiPipeline = __webpack_require__(77310); +var ShaderSourceFS = __webpack_require__(85060); +var ShaderSourceVS = __webpack_require__(18166); +var WEBGL_CONST = __webpack_require__(71402); +var WebGLPipeline = __webpack_require__(44775); -var CreateDOMContainer = function (game) -{ - var config = game.config; +/** + * @classdesc + * The Mobile Pipeline is the core 2D texture rendering pipeline used by Phaser in WebGL + * when the device running the game is detected to be a mobile. + * + * You can control the use of this pipeline by setting the Game Configuration + * property `autoMobilePipeline`. If set to `false` then all devices will use + * the Multi Tint Pipeline. You can also call the `PipelineManager.setDefaultPipeline` + * method at run-time, rather than boot-time, to modify the default Game Object + * pipeline. + * + * 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. + * + * The fragment shader it uses can be found in `shaders/src/Mobile.frag`. + * The vertex shader it uses can be found in `shaders/src/Mobile.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) + * + * Note that `inTexId` isn't used in the shader, it's just kept to allow us + * to piggy-back on the Multi Tint Pipeline functions. + * + * The default shader uniforms for this pipeline are: + * + * `uProjectionMatrix` (mat4) + * `uMainSampler` (sampler2D) + * + * @class MobilePipeline + * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + */ +var MobilePipeline = new Class({ - if (!config.parent || !config.domCreateContainer) + Extends: MultiPipeline, + + initialize: + + function MobilePipeline (config) { - return; - } + 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 + }, + { + name: 'inTexId' + }, + { + name: 'inTintEffect' + }, + { + name: 'inTint', + size: 4, + type: WEBGL_CONST.UNSIGNED_BYTE, + normalized: true + } + ]); + config.forceZero = true; - // DOM Element Container - var div = document.createElement('div'); + MultiPipeline.call(this, config); + }, - div.style.cssText = [ - 'display: block;', - 'width: ' + game.scale.width + 'px;', - 'height: ' + game.scale.height + 'px;', - 'padding: 0; margin: 0;', - 'position: absolute;', - 'overflow: hidden;', - 'pointer-events: ' + config.domPointerEvents + ';', - 'transform: scale(1);', - 'transform-origin: left top;' - ].join(' '); + /** + * Called when the Game has fully booted and the Renderer has finished setting up. + * + * By this stage all Game level systems are now in place and you can perform any final + * tasks that the pipeline may need that relied on game systems such as the Texture Manager. + * + * @method Phaser.Renderer.WebGL.Pipelines.MobilePipeline#boot + * @since 3.60.0 + */ + boot: function () + { + WebGLPipeline.prototype.boot.call(this); - game.domContainer = div; + this.set1i('uMainSampler', 0); + } - AddToDOM(div, config.parent); -}; +}); -module.exports = CreateDOMContainer; +module.exports = MobilePipeline; /***/ }), -/* 922 */ -/***/ (function(module, exports) { + +/***/ 77310: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Felipe Alfonso <@bitnenfer> + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var Earcut = __webpack_require__(11117); +var GetFastValue = __webpack_require__(72632); +var ShaderSourceFS = __webpack_require__(53787); +var ShaderSourceVS = __webpack_require__(15968); +var TransformMatrix = __webpack_require__(69360); +var Utils = __webpack_require__(75512); +var WEBGL_CONST = __webpack_require__(71402); +var WebGLPipeline = __webpack_require__(44775); + /** - * The Input Plugin Boot Event. - * - * This internal event is dispatched by the Input Plugin when it boots, signalling to all of its systems to create themselves. + * @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. * - * @event Phaser.Input.Events#BOOT - * @since 3.0.0 + * 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 should use the string + * declaration `%count%` in your fragment shader source, which is used to set the number of + * `sampler2Ds` available. Also add `%getSampler%` so Phaser can inject the getSampler glsl function. + * This function can be used to get the pixel vec4 from the texture: + * + * `vec4 texture = getSampler(int(outTexId), outTexCoord);` + * + * This pipeline will automatically inject the getSampler function for you, should the value 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. */ -module.exports = 'boot'; +var MultiPipeline = new Class({ + Extends: WebGLPipeline, -/***/ }), -/* 923 */ -/***/ (function(module, exports) { + initialize: -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + function MultiPipeline (config) + { + var renderer = config.game.renderer; -/** - * The Input Plugin Destroy Event. - * - * This internal event is dispatched by the Input Plugin when it is destroyed, signalling to all of its systems to destroy themselves. - * - * @event Phaser.Input.Events#DESTROY - * @since 3.0.0 - */ -module.exports = 'destroy'; + 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 + } + ]); -/***/ }), -/* 924 */ -/***/ (function(module, exports) { + WebGLPipeline.call(this, config); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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(); -/** - * The Pointer Drag End Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer stops dragging a Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('dragend', listener)`. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_END]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_END} event instead. - * - * @event Phaser.Input.Events#DRAG_END - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer stopped dragging. - */ -module.exports = 'dragend'; + /** + * 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(); -/***/ }), -/* 925 */ -/***/ (function(module, exports) { + /** + * A temporary Transform Matrix, re-used internally during batching by the + * Shape Game Objects. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#calcMatrix + * @type {Phaser.GameObjects.Components.TransformMatrix} + * @since 3.55.0 + */ + this.calcMatrix = new TransformMatrix(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Used internally to draw stroked triangles. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#tempTriangle + * @type {array} + * @private + * @since 3.55.0 + */ + this.tempTriangle = [ + { x: 0, y: 0, width: 0 }, + { x: 0, y: 0, width: 0 }, + { x: 0, y: 0, width: 0 }, + { x: 0, y: 0, width: 0 } + ]; -/** - * The Pointer Drag Enter Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer drags a Game Object into a Drag Target. - * - * Listen to this event from within a Scene using: `this.input.on('dragenter', listener)`. - * - * A Pointer can only drag a single Game Object at once. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_ENTER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_ENTER} event instead. - * - * @event Phaser.Input.Events#DRAG_ENTER - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. - * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has moved into. - */ -module.exports = 'dragenter'; + /** + * Cached stroke tint. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#strokeTint + * @type {object} + * @private + * @since 3.55.0 + */ + this.strokeTint = { TL: 0, TR: 0, BL: 0, BR: 0 }; + /** + * Cached fill tint. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#fillTint + * @type {object} + * @private + * @since 3.55.0 + */ + this.fillTint = { TL: 0, TR: 0, BL: 0, BR: 0 }; -/***/ }), -/* 926 */ -/***/ (function(module, exports) { + /** + * Internal texture frame reference. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#currentFrame + * @type {Phaser.Textures.Frame} + * @private + * @since 3.55.0 + */ + this.currentFrame = { u0: 0, v0: 0, u1: 1, v1: 1 }; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Internal path quad cache. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#firstQuad + * @type {number[]} + * @private + * @since 3.55.0 + */ + this.firstQuad = [ 0, 0, 0, 0, 0 ]; -/** - * The Pointer Drag Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves while dragging a Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('drag', listener)`. - * - * A Pointer can only drag a single Game Object at once. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG} event instead. - * - * @event Phaser.Input.Events#DRAG - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. - * @param {number} dragX - The x coordinate where the Pointer is currently dragging the Game Object, in world space. - * @param {number} dragY - The y coordinate where the Pointer is currently dragging the Game Object, in world space. - */ -module.exports = 'drag'; + /** + * Internal path quad cache. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#prevQuad + * @type {number[]} + * @private + * @since 3.55.0 + */ + this.prevQuad = [ 0, 0, 0, 0, 0 ]; + /** + * Used internally for triangulating a polygon. + * + * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#polygonCache + * @type {array} + * @private + * @since 3.55.0 + */ + this.polygonCache = []; + }, -/***/ }), -/* 927 */ -/***/ (function(module, exports) { + /** + * 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#boot + * @since 3.50.0 + */ + boot: function () + { + WebGLPipeline.prototype.boot.call(this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.currentShader.set1iv('uMainSampler', this.renderer.textureIndexes); + }, -/** - * The Pointer Drag Leave Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer drags a Game Object out of a Drag Target. - * - * Listen to this event from within a Scene using: `this.input.on('dragleave', listener)`. - * - * A Pointer can only drag a single Game Object at once. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_LEAVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_LEAVE} event instead. - * - * @event Phaser.Input.Events#DRAG_LEAVE - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. - * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has left. - */ -module.exports = 'dragleave'; + /** + * 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; -/***/ }), -/* 928 */ -/***/ (function(module, exports) { + var frame = gameObject.frame; + var texture = frame.glTexture; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + 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; -/** - * The Pointer Drag Over Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer drags a Game Object over a Drag Target. - * - * When the Game Object first enters the drag target it will emit a `dragenter` event. If it then moves while within - * the drag target, it will emit this event instead. - * - * Listen to this event from within a Scene using: `this.input.on('dragover', listener)`. - * - * A Pointer can only drag a single Game Object at once. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_OVER} event instead. - * - * @event Phaser.Input.Events#DRAG_OVER - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. - * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has moved over. - */ -module.exports = 'dragover'; + var displayOriginX = gameObject.displayOriginX; + var displayOriginY = gameObject.displayOriginY; + var x = -displayOriginX + frameX; + var y = -displayOriginY + frameY; -/***/ }), -/* 929 */ -/***/ (function(module, exports) { + if (gameObject.isCropped) + { + var crop = gameObject._crop; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (crop.flipX !== gameObject.flipX || crop.flipY !== gameObject.flipY) + { + frame.updateCropUVs(crop, gameObject.flipX, gameObject.flipY); + } -/** - * The Pointer Drag Start Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer starts to drag any Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('dragstart', listener)`. - * - * A Pointer can only drag a single Game Object at once. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_START]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_START} event instead. - * - * @event Phaser.Input.Events#DRAG_START - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer is dragging. - */ -module.exports = 'dragstart'; + u0 = crop.u0; + v0 = crop.v0; + u1 = crop.u1; + v1 = crop.v1; + frameWidth = crop.width; + frameHeight = crop.height; -/***/ }), -/* 930 */ -/***/ (function(module, exports) { + frameX = crop.x; + frameY = crop.y; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + x = -displayOriginX + frameX; + y = -displayOriginY + frameY; + } -/** - * The Pointer Drop Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer drops a Game Object on a Drag Target. - * - * Listen to this event from within a Scene using: `this.input.on('drop', listener)`. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DROP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DROP} event instead. - * - * @event Phaser.Input.Events#DROP - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object that this pointer was dragging. - * @param {Phaser.GameObjects.GameObject} target - The Drag Target the `gameObject` has been dropped on. - */ -module.exports = 'drop'; + var flipX = 1; + var flipY = 1; + if (gameObject.flipX) + { + if (!customPivot) + { + x += (-frame.realWidth + (displayOriginX * 2)); + } -/***/ }), -/* 931 */ -/***/ (function(module, exports) { + flipX = -1; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Auto-invert the flipY if this is coming from a GLTexture -/** - * The Input Plugin Game Out Event. - * - * This event is dispatched by the Input Plugin if the active pointer leaves the game canvas and is now - * outside of it, elsewhere on the web page. - * - * Listen to this event from within a Scene using: `this.input.on('gameout', listener)`. - * - * @event Phaser.Input.Events#GAME_OUT - * @since 3.16.1 - * - * @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 {(MouseEvent|TouchEvent)} event - The DOM Event that triggered the canvas out. - */ -module.exports = 'gameout'; + if (gameObject.flipY || (frame.source.isGLTexture && !texture.flipY)) + { + if (!customPivot) + { + y += (-frame.realHeight + (displayOriginY * 2)); + } + flipY = -1; + } -/***/ }), -/* 932 */ -/***/ (function(module, exports) { + var gx = gameObject.x; + var gy = gameObject.y; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // if (camera.roundPixels) + // { + // gx = Math.floor(gx); + // gy = Math.floor(gy); + // } -/** - * The Input Plugin Game Over Event. - * - * This event is dispatched by the Input Plugin if the active pointer enters the game canvas and is now - * over of it, having previously been elsewhere on the web page. - * - * Listen to this event from within a Scene using: `this.input.on('gameover', listener)`. - * - * @event Phaser.Input.Events#GAME_OVER - * @since 3.16.1 - * - * @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 {(MouseEvent|TouchEvent)} event - The DOM Event that triggered the canvas over. - */ -module.exports = 'gameover'; + spriteMatrix.applyITRS(gx, gy, gameObject.rotation, gameObject.scaleX * flipX, gameObject.scaleY * flipY); + camMatrix.copyFrom(camera.matrix); -/***/ }), -/* 933 */ -/***/ (function(module, exports) { + if (parentTransformMatrix) + { + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * gameObject.scrollFactorX, -camera.scrollY * gameObject.scrollFactorY); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Undo the camera scroll + spriteMatrix.e = gx; + spriteMatrix.f = gy; + } + else + { + spriteMatrix.e -= camera.scrollX * gameObject.scrollFactorX; + spriteMatrix.f -= camera.scrollY * gameObject.scrollFactorY; + } -/** - * The Game Object Down Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is pressed down on _any_ interactive Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('gameobjectdown', listener)`. - * - * To receive this event, the Game Objects must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} event instead. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} - * 2. [GAMEOBJECT_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DOWN} - * 3. [POINTER_DOWN]{@linkcode Phaser.Input.Events#event:POINTER_DOWN} or [POINTER_DOWN_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_DOWN_OUTSIDE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_DOWN - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer was pressed down on. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'gameobjectdown'; + // Multiply by the Sprite matrix, store result in calcMatrix + camMatrix.multiply(spriteMatrix, calcMatrix); + var quad = calcMatrix.setQuad(x, y, x + frameWidth, y + frameHeight, camera.roundPixels); -/***/ }), -/* 934 */ -/***/ (function(module, exports) { + var getTint = Utils.getTintAppendFloatAlpha; + var cameraAlpha = camera.alpha; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + 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); -/** - * The Game Object Drag End Event. - * - * This event is dispatched by an interactive Game Object if a pointer stops dragging it. - * - * Listen to this event from a Game Object using: `gameObject.on('dragend', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive and enabled for drag. - * See [GameObject.setInteractive](Phaser.GameObjects.GameObject#setInteractive) for more details. - * - * @event Phaser.Input.Events#GAMEOBJECT_DRAG_END - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {number} dragX - The x coordinate where the Pointer stopped dragging the Game Object, in world space. - * @param {number} dragY - The y coordinate where the Pointer stopped dragging the Game Object, in world space. - */ -module.exports = 'dragend'; + if (this.shouldFlush(6)) + { + this.flush(); + } + var unit = this.setGameObject(gameObject, frame); -/***/ }), -/* 935 */ -/***/ (function(module, exports) { + this.manager.preBatch(gameObject); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.batchQuad(gameObject, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, gameObject.tintFill, texture, unit); -/** - * The Game Object Drag Enter Event. - * - * This event is dispatched by an interactive Game Object if a pointer drags it into a drag target. - * - * Listen to this event from a Game Object using: `gameObject.on('dragenter', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive and enabled for drag. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * @event Phaser.Input.Events#GAMEOBJECT_DRAG_ENTER - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has moved into. - */ -module.exports = 'dragenter'; + 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); -/***/ }), -/* 936 */ -/***/ (function(module, exports) { + var camMatrix = this._tempMatrix1; + var spriteMatrix = this._tempMatrix2; + var calcMatrix = this._tempMatrix3; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var u0 = (frameX / textureWidth) + uOffset; + var v0 = (frameY / textureHeight) + vOffset; + var u1 = (frameX + frameWidth) / textureWidth + uOffset; + var v1 = (frameY + frameHeight) / textureHeight + vOffset; -/** - * The Game Object Drag Event. - * - * This event is dispatched by an interactive Game Object if a pointer moves while dragging it. - * - * Listen to this event from a Game Object using: `gameObject.on('drag', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive and enabled for drag. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * @event Phaser.Input.Events#GAMEOBJECT_DRAG - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {number} dragX - The x coordinate where the Pointer is currently dragging the Game Object, in world space. - * @param {number} dragY - The y coordinate where the Pointer is currently dragging the Game Object, in world space. - */ -module.exports = 'drag'; + var width = srcWidth; + var height = srcHeight; + var x = -displayOriginX; + var y = -displayOriginY; -/***/ }), -/* 937 */ -/***/ (function(module, exports) { + if (gameObject.isCropped) + { + var crop = gameObject._crop; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var cropWidth = crop.width; + var cropHeight = crop.height; -/** - * The Game Object Drag Leave Event. - * - * This event is dispatched by an interactive Game Object if a pointer drags it out of a drag target. - * - * Listen to this event from a Game Object using: `gameObject.on('dragleave', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive and enabled for drag. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * @event Phaser.Input.Events#GAMEOBJECT_DRAG_LEAVE - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has left. - */ -module.exports = 'dragleave'; + width = cropWidth; + height = cropHeight; + srcWidth = cropWidth; + srcHeight = cropHeight; -/***/ }), -/* 938 */ -/***/ (function(module, exports) { + frameX = crop.x; + frameY = crop.y; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var ox = frameX; + var oy = frameY; -/** - * The Game Object Drag Over Event. - * - * This event is dispatched by an interactive Game Object if a pointer drags it over a drag target. - * - * When the Game Object first enters the drag target it will emit a `dragenter` event. If it then moves while within - * the drag target, it will emit this event instead. - * - * Listen to this event from a Game Object using: `gameObject.on('dragover', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive and enabled for drag. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * @event Phaser.Input.Events#GAMEOBJECT_DRAG_OVER - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} target - The drag target that this pointer has moved over. - */ -module.exports = 'dragover'; + if (flipX) + { + ox = (frameWidth - crop.x - cropWidth); + } + if (flipY) + { + oy = (frameHeight - crop.y - cropHeight); + } -/***/ }), -/* 939 */ -/***/ (function(module, exports) { + u0 = (ox / textureWidth) + uOffset; + v0 = (oy / textureHeight) + vOffset; + u1 = (ox + cropWidth) / textureWidth + uOffset; + v1 = (oy + cropHeight) / textureHeight + vOffset; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + x = -displayOriginX + frameX; + y = -displayOriginY + frameY; + } -/** - * The Game Object Drag Start Event. - * - * This event is dispatched by an interactive Game Object if a pointer starts to drag it. - * - * Listen to this event from a Game Object using: `gameObject.on('dragstart', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive and enabled for drag. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * There are lots of useful drag related properties that are set within the Game Object when dragging occurs. - * For example, `gameObject.input.dragStartX`, `dragStartY` and so on. - * - * @event Phaser.Input.Events#GAMEOBJECT_DRAG_START - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {number} dragX - The x coordinate where the Pointer is currently dragging the Game Object, in world space. - * @param {number} dragY - The y coordinate where the Pointer is currently dragging the Game Object, in world space. - */ -module.exports = 'dragstart'; + // Invert the flipY if this is a RenderTexture + flipY = flipY ^ (!skipFlip && texture.isRenderTexture ? 1 : 0); + if (flipX) + { + width *= -1; + x += srcWidth; + } -/***/ }), -/* 940 */ -/***/ (function(module, exports) { + if (flipY) + { + height *= -1; + y += srcHeight; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // if (camera.roundPixels) + // { + // srcX = Math.floor(srcX); + // srcY = Math.floor(srcY); + // } -/** - * The Game Object Drop Event. - * - * This event is dispatched by an interactive Game Object if a pointer drops it on a Drag Target. - * - * Listen to this event from a Game Object using: `gameObject.on('drop', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive and enabled for drag. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * @event Phaser.Input.Events#GAMEOBJECT_DROP - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} target - The Drag Target the `gameObject` has been dropped on. - */ -module.exports = 'drop'; + spriteMatrix.applyITRS(srcX, srcY, rotation, scaleX, scaleY); + camMatrix.copyFrom(camera.matrix); -/***/ }), -/* 941 */ -/***/ (function(module, exports) { + if (parentTransformMatrix) + { + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Undo the camera scroll + spriteMatrix.e = srcX; + spriteMatrix.f = srcY; + } + else + { + spriteMatrix.e -= camera.scrollX * scrollFactorX; + spriteMatrix.f -= camera.scrollY * scrollFactorY; + } -/** - * The Game Object Move Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is moved across _any_ interactive Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('gameobjectmove', listener)`. - * - * To receive this event, the Game Objects must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_MOVE} event instead. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_MOVE} - * 2. [GAMEOBJECT_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_MOVE} - * 3. [POINTER_MOVE]{@linkcode Phaser.Input.Events#event:POINTER_MOVE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_MOVE - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer was moved on. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'gameobjectmove'; + // Multiply by the Sprite matrix, store result in calcMatrix + camMatrix.multiply(spriteMatrix, calcMatrix); + var quad = calcMatrix.setQuad(x, y, x + width, y + height, camera.roundPixels); -/***/ }), -/* 942 */ -/***/ (function(module, exports) { + if (textureUnit === undefined) + { + // textureUnit = this.renderer.setTexture2D(texture); + textureUnit = this.setTexture2D(texture); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (gameObject) + { + this.manager.preBatch(gameObject); + } -/** - * The Game Object Out Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves out of _any_ interactive Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('gameobjectout', listener)`. - * - * To receive this event, the Game Objects must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OUT} event instead. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OUT} - * 2. [GAMEOBJECT_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OUT} - * 3. [POINTER_OUT]{@linkcode Phaser.Input.Events#event:POINTER_OUT} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_OUT - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer moved out of. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'gameobjectout'; + this.batchQuad(gameObject, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); + if (gameObject) + { + this.manager.postBatch(gameObject); + } + }, -/***/ }), -/* 943 */ -/***/ (function(module, exports) { + /** + * 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); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var spriteMatrix = this._tempMatrix1.copyFrom(transformMatrix); + var calcMatrix = this._tempMatrix2; -/** - * The Game Object Over Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves over _any_ interactive Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('gameobjectover', listener)`. - * - * To receive this event, the Game Objects must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OVER} event instead. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OVER} - * 2. [GAMEOBJECT_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OVER} - * 3. [POINTER_OVER]{@linkcode Phaser.Input.Events#event:POINTER_OVER} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_OVER - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer moved over. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'gameobjectover'; + if (parentTransformMatrix) + { + spriteMatrix.multiply(parentTransformMatrix, calcMatrix); + } + else + { + calcMatrix = spriteMatrix; + } + var quad = calcMatrix.setQuad(x, y, x + frame.width, y + frame.height, false); -/***/ }), -/* 944 */ -/***/ (function(module, exports) { + var unit = this.setTexture2D(frame.source.glTexture); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + tint = Utils.getTintAppendFloatAlpha(tint, alpha); -/** - * The Game Object Pointer Down Event. - * - * This event is dispatched by an interactive Game Object if a pointer is pressed down on it. - * - * Listen to this event from a Game Object using: `gameObject.on('pointerdown', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} - * 2. [GAMEOBJECT_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DOWN} - * 3. [POINTER_DOWN]{@linkcode Phaser.Input.Events#event:POINTER_DOWN} or [POINTER_DOWN_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_DOWN_OUTSIDE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_POINTER_DOWN - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {number} localX - The x coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. - * @param {number} localY - The y coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'pointerdown'; + this.batchQuad(null, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, 0, frame.glTexture, unit); + }, + /** + * Pushes a filled rectangle into the vertex batch. + * + * Rectangle factors in the given transform matrices before adding to the batch. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchFillRect + * @since 3.55.0 + * + * @param {number} x - Horizontal top left coordinate of the rectangle. + * @param {number} y - Vertical top left coordinate of the rectangle. + * @param {number} width - Width of the rectangle. + * @param {number} height - Height of the rectangle. + * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. + */ + batchFillRect: function (x, y, width, height, currentMatrix, parentMatrix) + { + this.renderer.pipelines.set(this); -/***/ }), -/* 945 */ -/***/ (function(module, exports) { + var calcMatrix = this.calcMatrix; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix + if (parentMatrix) + { + parentMatrix.multiply(currentMatrix, calcMatrix); + } -/** - * The Game Object Pointer Move Event. - * - * This event is dispatched by an interactive Game Object if a pointer is moved while over it. - * - * Listen to this event from a Game Object using: `gameObject.on('pointermove', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_MOVE} - * 2. [GAMEOBJECT_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_MOVE} - * 3. [POINTER_MOVE]{@linkcode Phaser.Input.Events#event:POINTER_MOVE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_POINTER_MOVE - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {number} localX - The x coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. - * @param {number} localY - The y coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'pointermove'; + var quad = calcMatrix.setQuad(x, y, x + width, y + height, false); + var tint = this.fillTint; -/***/ }), -/* 946 */ -/***/ (function(module, exports) { + this.batchQuad(null, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], 0, 0, 1, 1, tint.TL, tint.TR, tint.BL, tint.BR, 2); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Pushes a filled triangle into the vertex batch. + * + * Triangle factors in the given transform matrices before adding to the batch. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchFillTriangle + * @since 3.55.0 + * + * @param {number} x0 - Point 0 x coordinate. + * @param {number} y0 - Point 0 y coordinate. + * @param {number} x1 - Point 1 x coordinate. + * @param {number} y1 - Point 1 y coordinate. + * @param {number} x2 - Point 2 x coordinate. + * @param {number} y2 - Point 2 y coordinate. + * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. + */ + batchFillTriangle: function (x0, y0, x1, y1, x2, y2, currentMatrix, parentMatrix) + { + this.renderer.pipelines.set(this); -/** - * The Game Object Pointer Out Event. - * - * This event is dispatched by an interactive Game Object if a pointer moves out of it. - * - * Listen to this event from a Game Object using: `gameObject.on('pointerout', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OUT} - * 2. [GAMEOBJECT_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OUT} - * 3. [POINTER_OUT]{@linkcode Phaser.Input.Events#event:POINTER_OUT} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_POINTER_OUT - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'pointerout'; + var calcMatrix = this.calcMatrix; + // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix + if (parentMatrix) + { + parentMatrix.multiply(currentMatrix, calcMatrix); + } -/***/ }), -/* 947 */ -/***/ (function(module, exports) { + var tx0 = calcMatrix.getX(x0, y0); + var ty0 = calcMatrix.getY(x0, y0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var tx1 = calcMatrix.getX(x1, y1); + var ty1 = calcMatrix.getY(x1, y1); -/** - * The Game Object Pointer Over Event. - * - * This event is dispatched by an interactive Game Object if a pointer moves over it. - * - * Listen to this event from a Game Object using: `gameObject.on('pointerover', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OVER} - * 2. [GAMEOBJECT_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OVER} - * 3. [POINTER_OVER]{@linkcode Phaser.Input.Events#event:POINTER_OVER} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_POINTER_OVER - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {number} localX - The x coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. - * @param {number} localY - The y coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'pointerover'; + var tx2 = calcMatrix.getX(x2, y2); + var ty2 = calcMatrix.getY(x2, y2); + var tint = this.fillTint; -/***/ }), -/* 948 */ -/***/ (function(module, exports) { + this.batchTri(null, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, tint.TL, tint.TR, tint.BL, 2); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Pushes a stroked triangle into the vertex batch. + * + * Triangle factors in the given transform matrices before adding to the batch. + * + * The triangle is created from 3 lines and drawn using the `batchStrokePath` method. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchStrokeTriangle + * @since 3.55.0 + * + * @param {number} x0 - Point 0 x coordinate. + * @param {number} y0 - Point 0 y coordinate. + * @param {number} x1 - Point 1 x coordinate. + * @param {number} y1 - Point 1 y coordinate. + * @param {number} x2 - Point 2 x coordinate. + * @param {number} y2 - Point 2 y coordinate. + * @param {number} lineWidth - The width of the line in pixels. + * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. + */ + batchStrokeTriangle: function (x0, y0, x1, y1, x2, y2, lineWidth, currentMatrix, parentMatrix) + { + var tempTriangle = this.tempTriangle; -/** - * The Game Object Pointer Up Event. - * - * This event is dispatched by an interactive Game Object if a pointer is released while over it. - * - * Listen to this event from a Game Object using: `gameObject.on('pointerup', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} - * 2. [GAMEOBJECT_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_UP} - * 3. [POINTER_UP]{@linkcode Phaser.Input.Events#event:POINTER_UP} or [POINTER_UP_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_UP_OUTSIDE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_POINTER_UP - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {number} localX - The x coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. - * @param {number} localY - The y coordinate that the Pointer interacted with this object on, relative to the Game Object's top-left position. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'pointerup'; + tempTriangle[0].x = x0; + tempTriangle[0].y = y0; + tempTriangle[0].width = lineWidth; + tempTriangle[1].x = x1; + tempTriangle[1].y = y1; + tempTriangle[1].width = lineWidth; -/***/ }), -/* 949 */ -/***/ (function(module, exports) { + tempTriangle[2].x = x2; + tempTriangle[2].y = y2; + tempTriangle[2].width = lineWidth; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + tempTriangle[3].x = x0; + tempTriangle[3].y = y0; + tempTriangle[3].width = lineWidth; -/** - * The Game Object Pointer Wheel Event. - * - * This event is dispatched by an interactive Game Object if a pointer has its wheel moved while over it. - * - * Listen to this event from a Game Object using: `gameObject.on('wheel', listener)`. - * Note that the scope of the listener is automatically set to be the Game Object instance itself. - * - * To receive this event, the Game Object must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_WHEEL} - * 2. [GAMEOBJECT_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_WHEEL} - * 3. [POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:POINTER_WHEEL} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_POINTER_WHEEL - * @since 3.18.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {number} deltaX - The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * @param {number} deltaY - 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. - * @param {number} deltaZ - The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'wheel'; + this.batchStrokePath(tempTriangle, lineWidth, false, currentMatrix, parentMatrix); + }, + /** + * Adds the given path to the vertex batch for rendering. + * + * It works by taking the array of path data and then passing it through Earcut, which + * creates a list of polygons. Each polygon is then added to the batch. + * + * The path is always automatically closed because it's filled. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchFillPath + * @since 3.55.0 + * + * @param {Phaser.Types.Math.Vector2Like[]} path - Collection of points that represent the path. + * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. + */ + batchFillPath: function (path, currentMatrix, parentMatrix) + { + this.renderer.pipelines.set(this); -/***/ }), -/* 950 */ -/***/ (function(module, exports) { + var calcMatrix = this.calcMatrix; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix + if (parentMatrix) + { + parentMatrix.multiply(currentMatrix, calcMatrix); + } -/** - * The Game Object Up Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is released while over _any_ interactive Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('gameobjectup', listener)`. - * - * To receive this event, the Game Objects must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} event instead. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} - * 2. [GAMEOBJECT_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_UP} - * 3. [POINTER_UP]{@linkcode Phaser.Input.Events#event:POINTER_UP} or [POINTER_UP_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_UP_OUTSIDE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_UP - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer was over when released. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'gameobjectup'; + var length = path.length; + var polygonCache = this.polygonCache; + var polygonIndexArray; + var point; + var tintTL = this.fillTint.TL; + var tintTR = this.fillTint.TR; + var tintBL = this.fillTint.BL; -/***/ }), -/* 951 */ -/***/ (function(module, exports) { + for (var pathIndex = 0; pathIndex < length; ++pathIndex) + { + point = path[pathIndex]; + polygonCache.push(point.x, point.y); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + polygonIndexArray = Earcut(polygonCache); + length = polygonIndexArray.length; -/** - * The Game Object Wheel Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer has its wheel moved while over _any_ interactive Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('gameobjectwheel', listener)`. - * - * To receive this event, the Game Objects must have been set as interactive. - * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. - * - * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_WHEEL} event instead. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_WHEEL} - * 2. [GAMEOBJECT_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_WHEEL} - * 3. [POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:POINTER_WHEEL} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#GAMEOBJECT_WHEEL - * @since 3.18.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the pointer was over when the wheel changed. - * @param {number} deltaX - The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * @param {number} deltaY - 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. - * @param {number} deltaZ - The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * @param {Phaser.Types.Input.EventData} event - The Phaser input event. You can call `stopPropagation()` to halt it from going any further in the event flow. - */ -module.exports = 'gameobjectwheel'; + for (var index = 0; index < length; index += 3) + { + var p0 = polygonIndexArray[index + 0] * 2; + var p1 = polygonIndexArray[index + 1] * 2; + var p2 = polygonIndexArray[index + 2] * 2; + var x0 = polygonCache[p0 + 0]; + var y0 = polygonCache[p0 + 1]; + var x1 = polygonCache[p1 + 0]; + var y1 = polygonCache[p1 + 1]; + var x2 = polygonCache[p2 + 0]; + var y2 = polygonCache[p2 + 1]; -/***/ }), -/* 952 */ -/***/ (function(module, exports) { + var tx0 = calcMatrix.getX(x0, y0); + var ty0 = calcMatrix.getY(x0, y0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var tx1 = calcMatrix.getX(x1, y1); + var ty1 = calcMatrix.getY(x1, y1); -/** - * The Input Manager Boot Event. - * - * This internal event is dispatched by the Input Manager when it boots. - * - * @event Phaser.Input.Events#MANAGER_BOOT - * @since 3.0.0 - */ -module.exports = 'boot'; + var tx2 = calcMatrix.getX(x2, y2); + var ty2 = calcMatrix.getY(x2, y2); + this.batchTri(null, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, tintTL, tintTR, tintBL, 2); + } -/***/ }), -/* 953 */ -/***/ (function(module, exports) { + polygonCache.length = 0; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Adds the given path to the vertex batch for rendering. + * + * It works by taking the array of path data and calling `batchLine` for each section + * of the path. + * + * The path is optionally closed at the end. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchStrokePath + * @since 3.55.0 + * + * @param {Phaser.Types.Math.Vector2Like[]} path - Collection of points that represent the path. + * @param {number} lineWidth - The width of the line segments in pixels. + * @param {boolean} pathOpen - Indicates if the path should be closed or left open. + * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. + */ + batchStrokePath: function (path, lineWidth, pathOpen, currentMatrix, parentMatrix) + { + this.renderer.pipelines.set(this); -/** - * The Input Manager Process Event. - * - * This internal event is dispatched by the Input Manager when not using the legacy queue system, - * and it wants the Input Plugins to update themselves. - * - * @event Phaser.Input.Events#MANAGER_PROCESS - * @since 3.0.0 - * - * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. - */ -module.exports = 'process'; + // Reset the closePath booleans + this.prevQuad[4] = 0; + this.firstQuad[4] = 0; + var pathLength = path.length - 1; -/***/ }), -/* 954 */ -/***/ (function(module, exports) { + for (var pathIndex = 0; pathIndex < pathLength; pathIndex++) + { + var point0 = path[pathIndex]; + var point1 = path[pathIndex + 1]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.batchLine( + point0.x, + point0.y, + point1.x, + point1.y, + point0.width / 2, + point1.width / 2, + lineWidth, + pathIndex, + !pathOpen && (pathIndex === pathLength - 1), + currentMatrix, + parentMatrix + ); + } + }, + + /** + * Creates a line out of 4 quads and adds it to the vertex batch based on the given line values. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchLine + * @since 3.55.0 + * + * @param {number} ax - x coordinate of the start of the line. + * @param {number} ay - y coordinate of the start of the line. + * @param {number} bx - x coordinate of the end of the line. + * @param {number} by - y coordinate of the end of the line. + * @param {number} aLineWidth - Width of the start of the line. + * @param {number} bLineWidth - Width of the end of the line. + * @param {number} index - If this line is part of a multi-line draw, the index of the line in the draw. + * @param {boolean} closePath - Does this line close a multi-line path? + * @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform. + * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform. + */ + batchLine: function (ax, ay, bx, by, aLineWidth, bLineWidth, lineWidth, index, closePath, currentMatrix, parentMatrix) + { + this.renderer.pipelines.set(this); -/** - * The Input Manager Update Event. - * - * This internal event is dispatched by the Input Manager as part of its update step. - * - * @event Phaser.Input.Events#MANAGER_UPDATE - * @since 3.0.0 - */ -module.exports = 'update'; + var calcMatrix = this.calcMatrix; + // Multiply and store result in calcMatrix, only if the parentMatrix is set, otherwise we'll use whatever values are already in the calcMatrix + if (parentMatrix) + { + parentMatrix.multiply(currentMatrix, calcMatrix); + } -/***/ }), -/* 955 */ -/***/ (function(module, exports) { + var dx = bx - ax; + var dy = by - ay; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var len = Math.sqrt(dx * dx + dy * dy); -/** - * The Pointer Down Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is pressed down anywhere. - * - * Listen to this event from within a Scene using: `this.input.on('pointerdown', listener)`. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} - * 2. [GAMEOBJECT_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DOWN} - * 3. [POINTER_DOWN]{@linkcode Phaser.Input.Events#event:POINTER_DOWN} or [POINTER_DOWN_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_DOWN_OUTSIDE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#POINTER_DOWN - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject[]} currentlyOver - An array containing all interactive Game Objects that the pointer was over when the event was created. - */ -module.exports = 'pointerdown'; + if (len === 0) + { + // Because we cannot (and should not) divide by zero! + return; + } + var al0 = aLineWidth * (by - ay) / len; + var al1 = aLineWidth * (ax - bx) / len; + var bl0 = bLineWidth * (by - ay) / len; + var bl1 = bLineWidth * (ax - bx) / len; -/***/ }), -/* 956 */ -/***/ (function(module, exports) { + var lx0 = bx - bl0; + var ly0 = by - bl1; + var lx1 = ax - al0; + var ly1 = ay - al1; + var lx2 = bx + bl0; + var ly2 = by + bl1; + var lx3 = ax + al0; + var ly3 = ay + al1; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // tx0 = bottom right + var brX = calcMatrix.getX(lx0, ly0); + var brY = calcMatrix.getY(lx0, ly0); -/** - * The Pointer Down Outside Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is pressed down anywhere outside of the game canvas. - * - * Listen to this event from within a Scene using: `this.input.on('pointerdownoutside', listener)`. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_DOWN} - * 2. [GAMEOBJECT_DOWN]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DOWN} - * 3. [POINTER_DOWN]{@linkcode Phaser.Input.Events#event:POINTER_DOWN} or [POINTER_DOWN_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_DOWN_OUTSIDE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#POINTER_DOWN_OUTSIDE - * @since 3.16.1 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - */ -module.exports = 'pointerdownoutside'; + // tx1 = bottom left + var blX = calcMatrix.getX(lx1, ly1); + var blY = calcMatrix.getY(lx1, ly1); + // tx2 = top right + var trX = calcMatrix.getX(lx2, ly2); + var trY = calcMatrix.getY(lx2, ly2); -/***/ }), -/* 957 */ -/***/ (function(module, exports) { + // tx3 = top left + var tlX = calcMatrix.getX(lx3, ly3); + var tlY = calcMatrix.getY(lx3, ly3); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var tint = this.strokeTint; -/** - * The Pointer Move Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is moved anywhere. - * - * Listen to this event from within a Scene using: `this.input.on('pointermove', listener)`. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_MOVE} - * 2. [GAMEOBJECT_MOVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_MOVE} - * 3. [POINTER_MOVE]{@linkcode Phaser.Input.Events#event:POINTER_MOVE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#POINTER_MOVE - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject[]} currentlyOver - An array containing all interactive Game Objects that the pointer was over when the event was created. - */ -module.exports = 'pointermove'; + var tintTL = tint.TL; + var tintTR = tint.TR; + var tintBL = tint.BL; + var tintBR = tint.BR; + // TL, BL, BR, TR + this.batchQuad(null, tlX, tlY, blX, blY, brX, brY, trX, trY, 0, 0, 1, 1, tintTL, tintTR, tintBL, tintBR, 2); -/***/ }), -/* 958 */ -/***/ (function(module, exports) { + if (lineWidth <= 2) + { + // No point doing a linejoin if the line isn't thick enough + return; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var prev = this.prevQuad; + var first = this.firstQuad; -/** - * The Pointer Out Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves out of any interactive Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('pointerout', listener)`. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OUT} - * 2. [GAMEOBJECT_OUT]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OUT} - * 3. [POINTER_OUT]{@linkcode Phaser.Input.Events#event:POINTER_OUT} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#POINTER_OUT - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject[]} justOut - An array containing all interactive Game Objects that the pointer moved out of when the event was created. - */ -module.exports = 'pointerout'; + if (index > 0 && prev[4]) + { + this.batchQuad(null, tlX, tlY, blX, blY, prev[0], prev[1], prev[2], prev[3], 0, 0, 1, 1, tintTL, tintTR, tintBL, tintBR, 2); + } + else + { + first[0] = tlX; + first[1] = tlY; + first[2] = blX; + first[3] = blY; + first[4] = 1; + } + if (closePath && first[4]) + { + // Add a join for the final path segment + this.batchQuad(null, brX, brY, trX, trY, first[0], first[1], first[2], first[3], 0, 0, 1, 1, tintTL, tintTR, tintBL, tintBR, 2); + } + else + { + // Store it -/***/ }), -/* 959 */ -/***/ (function(module, exports) { + prev[0] = brX; + prev[1] = brY; + prev[2] = trX; + prev[3] = trY; + prev[4] = 1; + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Destroys all shader instances, removes all object references and nulls all external references. + * + * @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#destroy + * @fires Phaser.Renderer.WebGL.Pipelines.Events#DESTROY + * @since 3.60.0 + * + * @return {this} This WebGLPipeline instance. + */ + destroy: function () + { + this._tempMatrix1.destroy(); + this._tempMatrix2.destroy(); + this._tempMatrix3.destroy(); -/** - * The Pointer Over Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer moves over any interactive Game Object. - * - * Listen to this event from within a Scene using: `this.input.on('pointerover', listener)`. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_OVER} - * 2. [GAMEOBJECT_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_OVER} - * 3. [POINTER_OVER]{@linkcode Phaser.Input.Events#event:POINTER_OVER} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#POINTER_OVER - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject[]} justOver - An array containing all interactive Game Objects that the pointer moved over when the event was created. - */ -module.exports = 'pointerover'; + this._tempMatrix1 = null; + this._tempMatrix1 = null; + this._tempMatrix1 = null; + WebGLPipeline.prototype.destroy.call(this); -/***/ }), -/* 960 */ -/***/ (function(module, exports) { + return this; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +}); -/** - * The Pointer Up Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is released anywhere. - * - * Listen to this event from within a Scene using: `this.input.on('pointerup', listener)`. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} - * 2. [GAMEOBJECT_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_UP} - * 3. [POINTER_UP]{@linkcode Phaser.Input.Events#event:POINTER_UP} or [POINTER_UP_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_UP_OUTSIDE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#POINTER_UP - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject[]} currentlyOver - An array containing all interactive Game Objects that the pointer was over when the event was created. - */ -module.exports = 'pointerup'; +module.exports = MultiPipeline; /***/ }), -/* 961 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Pointer Up Outside Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer is released anywhere outside of the game canvas. - * - * Listen to this event from within a Scene using: `this.input.on('pointerupoutside', listener)`. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_UP} - * 2. [GAMEOBJECT_UP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_UP} - * 3. [POINTER_UP]{@linkcode Phaser.Input.Events#event:POINTER_UP} or [POINTER_UP_OUTSIDE]{@linkcode Phaser.Input.Events#event:POINTER_UP_OUTSIDE} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. - * - * @event Phaser.Input.Events#POINTER_UP_OUTSIDE - * @since 3.16.1 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - */ -module.exports = 'pointerupoutside'; - -/***/ }), -/* 962 */ -/***/ (function(module, exports) { +/***/ 10919: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var PointLightShaderSourceFS = __webpack_require__(83327); +var PointLightShaderSourceVS = __webpack_require__(54677); +var WebGLPipeline = __webpack_require__(44775); + /** - * The Pointer Wheel Input Event. - * - * This event is dispatched by the Input Plugin belonging to a Scene if a pointer has its wheel updated. - * - * Listen to this event from within a Scene using: `this.input.on('wheel', listener)`. - * - * The event hierarchy is as follows: - * - * 1. [GAMEOBJECT_POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_POINTER_WHEEL} - * 2. [GAMEOBJECT_WHEEL]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_WHEEL} - * 3. [POINTER_WHEEL]{@linkcode Phaser.Input.Events#event:POINTER_WHEEL} - * - * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop - * the propagation of this event. + * @classdesc + * The Point Light Pipeline handles rendering the Point Light Game Objects in WebGL. * - * @event Phaser.Input.Events#POINTER_WHEEL - * @since 3.18.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer responsible for triggering this event. - * @param {Phaser.GameObjects.GameObject[]} currentlyOver - An array containing all interactive Game Objects that the pointer was over when the event was created. - * @param {number} deltaX - The horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device. - * @param {number} deltaY - 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. - * @param {number} deltaZ - The z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device. + * The fragment shader it uses can be found in `shaders/src/PointLight.frag`. + * The vertex shader it uses can be found in `shaders/src/PointLight.vert`. + * + * The default shader attributes for this pipeline are: + * + * `inPosition` (vec2) + * `inLightPosition` (vec2) + * `inLightRadius` (float) + * `inLightAttenuation` (float) + * `inLightColor` (vec4) + * + * The default shader uniforms for this pipeline are: + * + * `uProjectionMatrix` (mat4) + * `uResolution` (vec2) + * `uCameraZoom` (sampler2D) + * + * @class PointLightPipeline + * @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. */ -module.exports = 'wheel'; +var PointLightPipeline = new Class({ + Extends: WebGLPipeline, -/***/ }), -/* 963 */ -/***/ (function(module, exports) { + initialize: -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + function PointLightPipeline (config) + { + config.vertShader = GetFastValue(config, 'vertShader', PointLightShaderSourceVS); + config.fragShader = GetFastValue(config, 'fragShader', PointLightShaderSourceFS); + config.attributes = GetFastValue(config, 'attributes', [ + { + name: 'inPosition', + size: 2 + }, + { + name: 'inLightPosition', + size: 2 + }, + { + name: 'inLightRadius' + }, + { + name: 'inLightAttenuation' + }, + { + name: 'inLightColor', + size: 4 + } + ]); -/** - * The Input Manager Pointer Lock Change Event. - * - * This event is dispatched by the Input Manager when it is processing a native Pointer Lock Change DOM Event. - * - * @event Phaser.Input.Events#POINTERLOCK_CHANGE - * @since 3.0.0 - * - * @param {Event} event - The native DOM Event. - * @param {boolean} locked - The locked state of the Mouse Pointer. - */ -module.exports = 'pointerlockchange'; + WebGLPipeline.call(this, config); + }, + onRender: function (scene, camera) + { + this.set2f('uResolution', this.width, this.height); + this.set1f('uCameraZoom', camera.zoom); + }, -/***/ }), -/* 964 */ -/***/ (function(module, exports) { + /** + * Adds a Point Light Game Object to the batch, flushing if required. + * + * @method Phaser.Renderer.WebGL.Pipelines.PointLightPipeline#batchPointLight + * @since 3.50.0 + * + * @param {Phaser.GameObjects.PointLight} light - The Point Light Game Object. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the Point Light. + * @param {number} x0 - The top-left x position. + * @param {number} y0 - The top-left y position. + * @param {number} x1 - The bottom-left x position. + * @param {number} y1 - The bottom-left y position. + * @param {number} x2 - The bottom-right x position. + * @param {number} y2 - The bottom-right y position. + * @param {number} x3 - The top-right x position. + * @param {number} y3 - The top-right y position. + * @param {number} lightX - The horizontal center of the light. + * @param {number} lightY - The vertical center of the light. + */ + batchPointLight: function (light, camera, x0, y0, x1, y1, x2, y2, x3, y3, lightX, lightY) + { + var color = light.color; + var intensity = light.intensity; + var radius = light.radius; + var attenuation = light.attenuation; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var r = color.r * intensity; + var g = color.g * intensity; + var b = color.b * intensity; + var a = camera.alpha * light.alpha; -/** - * The Input Plugin Pre-Update Event. - * - * This internal event is dispatched by the Input Plugin at the start of its `preUpdate` method. - * This hook is designed specifically for input plugins, but can also be listened to from user-land code. - * - * @event Phaser.Input.Events#PRE_UPDATE - * @since 3.0.0 - */ -module.exports = 'preupdate'; + if (this.shouldFlush(6)) + { + this.flush(); + } + if (!this.currentBatch) + { + this.setTexture2D(); + } -/***/ }), -/* 965 */ -/***/ (function(module, exports) { + this.batchLightVert(x0, y0, lightX, lightY, radius, attenuation, r, g, b, a); + this.batchLightVert(x1, y1, lightX, lightY, radius, attenuation, r, g, b, a); + this.batchLightVert(x2, y2, lightX, lightY, radius, attenuation, r, g, b, a); + this.batchLightVert(x0, y0, lightX, lightY, radius, attenuation, r, g, b, a); + this.batchLightVert(x2, y2, lightX, lightY, radius, attenuation, r, g, b, a); + this.batchLightVert(x3, y3, lightX, lightY, radius, attenuation, r, g, b, a); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.currentBatch.count = (this.vertexCount - this.currentBatch.start); + }, -/** - * The Input Plugin Shutdown Event. - * - * This internal event is dispatched by the Input Plugin when it shuts down, signalling to all of its systems to shut themselves down. - * - * @event Phaser.Input.Events#SHUTDOWN - * @since 3.0.0 - */ -module.exports = 'shutdown'; + /** + * Adds a single Point Light vertex to the current vertex buffer and increments the + * `vertexCount` property by 1. + * + * This method is called directly by `batchPointLight`. + * + * @method Phaser.Renderer.WebGL.Pipelines.PointLightPipeline#batchLightVert + * @since 3.50.0 + * + * @param {number} x - The vertex x position. + * @param {number} y - The vertex y position. + * @param {number} lightX - The horizontal center of the light. + * @param {number} lightY - The vertical center of the light. + * @param {number} radius - The radius of the light. + * @param {number} attenuation - The attenuation of the light. + * @param {number} r - The red color channel of the light. + * @param {number} g - The green color channel of the light. + * @param {number} b - The blue color channel of the light. + * @param {number} a - The alpha color channel of the light. + */ + batchLightVert: function (x, y, lightX, lightY, radius, attenuation, r, g, b, a) + { + var vertexViewF32 = this.vertexViewF32; + var vertexOffset = (this.vertexCount * this.currentShader.vertexComponentCount) - 1; -/***/ }), -/* 966 */ -/***/ (function(module, exports) { + vertexViewF32[++vertexOffset] = x; + vertexViewF32[++vertexOffset] = y; + vertexViewF32[++vertexOffset] = lightX; + vertexViewF32[++vertexOffset] = lightY; + vertexViewF32[++vertexOffset] = radius; + vertexViewF32[++vertexOffset] = attenuation; + vertexViewF32[++vertexOffset] = r; + vertexViewF32[++vertexOffset] = g; + vertexViewF32[++vertexOffset] = b; + vertexViewF32[++vertexOffset] = a; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.vertexCount++; + } -/** - * The Input Plugin Start Event. - * - * This internal event is dispatched by the Input Plugin when it has finished setting-up, - * signalling to all of its internal systems to start. - * - * @event Phaser.Input.Events#START - * @since 3.0.0 - */ -module.exports = 'start'; +}); + +module.exports = PointLightPipeline; /***/ }), -/* 967 */ -/***/ (function(module, exports) { + +/***/ 80486: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var ColorMatrix = __webpack_require__(65246); +var GetFastValue = __webpack_require__(72632); +var ShaderSourceFS = __webpack_require__(12569); +var ShaderSourceVS = __webpack_require__(99365); +var WebGLPipeline = __webpack_require__(44775); + /** - * The Input Plugin Update Event. - * - * This internal event is dispatched by the Input Plugin at the start of its `update` method. - * This hook is designed specifically for input plugins, but can also be listened to from user-land code. + * @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. * - * @event Phaser.Input.Events#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. + * 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. */ -module.exports = 'update'; - +var PostFXPipeline = new Class({ -/***/ }), -/* 968 */ -/***/ (function(module, exports) { + Extends: WebGLPipeline, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + initialize: -/** - * The Loader Plugin Add File Event. - * - * This event is dispatched when a new file is successfully added to the Loader and placed into the load queue. - * - * Listen to it from a Scene using: `this.load.on('addfile', listener)`. - * - * If you add lots of files to a Loader from a `preload` method, it will dispatch this event for each one of them. - * - * @event Phaser.Loader.Events#ADD - * @since 3.0.0 - * - * @param {string} key - The unique key of the file that was added to the Loader. - * @param {string} type - The [file type]{@link Phaser.Loader.File#type} string of the file that was added to the Loader, i.e. `image`. - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event. - * @param {Phaser.Loader.File} file - A reference to the File which was added to the Loader. - */ -module.exports = 'addfile'; + 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); -/***/ }), -/* 969 */ -/***/ (function(module, exports) { + this.isPostFX = true; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * If this Post Pipeline belongs to a Game Object or Camera, + * this property contains a reference to it. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#gameObject + * @type {(Phaser.GameObjects.GameObject|Phaser.Cameras.Scene2D.Camera)} + * @since 3.50.0 + */ + this.gameObject; -/** - * The Loader Plugin Complete Event. - * - * This event is dispatched when the Loader has fully processed everything in the load queue. - * By this point every loaded file will now be in its associated cache and ready for use. - * - * Listen to it from a Scene using: `this.load.on('complete', listener)`. - * - * @event Phaser.Loader.Events#COMPLETE - * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event. - * @param {number} totalComplete - The total number of files that successfully loaded. - * @param {number} totalFailed - The total number of files that failed to load. - */ -module.exports = 'complete'; + /** + * If this Post Pipeline belongs to an FX Controller, this is a + * reference to it. + * + * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#controller + * @type {Phaser.FX.Controller} + * @since 3.60.0 + */ + this.controller; + /** + * 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(); -/***/ }), -/* 970 */ -/***/ (function(module, exports) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -/** - * The File Load Complete Event. - * - * This event is dispatched by the Loader Plugin when any file in the queue finishes loading. - * - * Listen to it from a Scene using: `this.load.on('filecomplete', listener)`. - * - * You can also listen for the completion of a specific file. See the [FILE_KEY_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_KEY_COMPLETE} event. - * - * @event Phaser.Loader.Events#FILE_COMPLETE - * @since 3.0.0 - * - * @param {string} key - The key of the file that just loaded and finished processing. - * @param {string} type - The [file type]{@link Phaser.Loader.File#type} of the file that just loaded, i.e. `image`. - * @param {any} data - The raw data the file contained. - */ -module.exports = 'filecomplete'; + /** + * 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; -/***/ }), -/* 971 */ -/***/ (function(module, exports) { + if (this.renderer.isBooted) + { + this.manager = this.renderer.pipelines; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.boot(); + } + }, -/** - * The File Load Complete Event. - * - * This event is dispatched by the Loader Plugin when any file in the queue finishes loading. - * - * It uses a special dynamic event name constructed from the key and type of the file. - * - * For example, if you have loaded an `image` with a key of `monster`, you can listen for it - * using the following: - * - * ```javascript - * this.load.on('filecomplete-image-monster', function (key, type, data) { - * // Your handler code - * }); - * ``` - * - * Or, if you have loaded a texture `atlas` with a key of `Level1`: - * - * ```javascript - * this.load.on('filecomplete-atlas-Level1', function (key, type, data) { - * // Your handler code - * }); - * ``` - * - * Or, if you have loaded a sprite sheet with a key of `Explosion` and a prefix of `GAMEOVER`: - * - * ```javascript - * this.load.on('filecomplete-spritesheet-GAMEOVERExplosion', function (key, type, data) { - * // Your handler code - * }); - * ``` - * - * You can also listen for the generic completion of files. See the [FILE_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_COMPLETE} event. - * - * @event Phaser.Loader.Events#FILE_KEY_COMPLETE - * @since 3.0.0 - * - * @param {string} key - The key of the file that just loaded and finished processing. - * @param {string} type - The [file type]{@link Phaser.Loader.File#type} of the file that just loaded, i.e. `image`. - * @param {any} data - The raw data the file contained. - */ -module.exports = 'filecomplete-'; + boot: function () + { + WebGLPipeline.prototype.boot.call(this); + var utility = this.manager.UTILITY_PIPELINE; -/***/ }), -/* 972 */ -/***/ (function(module, exports) { + this.fullFrame1 = utility.fullFrame1; + this.fullFrame2 = utility.fullFrame2; + this.halfFrame1 = utility.halfFrame1; + this.halfFrame2 = utility.halfFrame2; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.set1i('uMainSampler', 0); + }, -/** - * The File Load Error Event. - * - * This event is dispatched by the Loader Plugin when a file fails to load. - * - * Listen to it from a Scene using: `this.load.on('loaderror', listener)`. - * - * @event Phaser.Loader.Events#FILE_LOAD_ERROR - * @since 3.0.0 - * - * @param {Phaser.Loader.File} file - A reference to the File which errored during load. - */ -module.exports = 'loaderror'; + onDraw: function (renderTarget) + { + this.bindAndDraw(renderTarget); + }, + /** + * Returns the FX Controller for this Post FX Pipeline. + * + * This is called internally and not typically required outside. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#getController + * @since 3.60.0 + * + * @param {Phaser.FX.Controller} [controller] - An FX Controller, or undefined. + * + * @return {Phaser.FX.Controller|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} The FX Controller responsible, or this Pipeline. + */ + getController: function (controller) + { + if (controller !== undefined) + { + return controller; + } + else if (this.controller) + { + return this.controller; + } + else + { + return this; + } + }, -/***/ }), -/* 973 */ -/***/ (function(module, exports) { + /** + * Copy the `source` Render Target to the `target` Render Target. + * + * This method does _not_ bind a shader. It uses whatever shader + * is currently bound in this pipeline. It also does _not_ clear + * the frame buffers after use. You should take care of both of + * these things if you call this method directly. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copySprite + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. + */ + copySprite: function (source, target, reset) + { + if (reset === undefined) { reset = false; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var gl = this.gl; -/** - * The File Load Event. - * - * This event is dispatched by the Loader Plugin when a file finishes loading, - * but _before_ it is processed and added to the internal Phaser caches. - * - * Listen to it from a Scene using: `this.load.on('load', listener)`. - * - * @event Phaser.Loader.Events#FILE_LOAD - * @since 3.0.0 - * - * @param {Phaser.Loader.File} file - A reference to the File which just finished loading. - */ -module.exports = 'load'; + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source.texture); + var currentFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING); -/***/ }), -/* 974 */ -/***/ (function(module, exports) { + gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture, 0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); -/** - * The File Load Progress Event. - * - * This event is dispatched by the Loader Plugin during the load of a file, if the browser receives a DOM ProgressEvent and - * the `lengthComputable` event property is true. Depending on the size of the file and browser in use, this may, or may not happen. - * - * Listen to it from a Scene using: `this.load.on('fileprogress', listener)`. - * - * @event Phaser.Loader.Events#FILE_PROGRESS - * @since 3.0.0 - * - * @param {Phaser.Loader.File} file - A reference to the File which errored during load. - * @param {number} percentComplete - A value between 0 and 1 indicating how 'complete' this file is. - */ -module.exports = 'fileprogress'; + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); + if (reset) + { + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, currentFBO); + } + }, -/***/ }), -/* 975 */ -/***/ (function(module, exports) { + /** + * 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); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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); + }, -/** - * The Loader Plugin Post Process Event. - * - * This event is dispatched by the Loader Plugin when the Loader has finished loading everything in the load queue. - * It is dispatched before the internal lists are cleared and each File is destroyed. - * - * Use this hook to perform any last minute processing of files that can only happen once the - * Loader has completed, but prior to it emitting the `complete` event. - * - * Listen to it from a Scene using: `this.load.on('postprocess', listener)`. - * - * @event Phaser.Loader.Events#POST_PROCESS - * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event. - */ -module.exports = 'postprocess'; + /** + * Copy the `source` Render Target to the `target` Render Target, using this pipelines + * 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); + }, -/***/ }), -/* 976 */ -/***/ (function(module, exports) { + /** + * 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); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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); + }, -/** - * The Loader Plugin Progress Event. - * - * This event is dispatched when the Loader updates its load progress, typically as a result of a file having completed loading. - * - * Listen to it from a Scene using: `this.load.on('progress', listener)`. - * - * @event Phaser.Loader.Events#PROGRESS - * @since 3.0.0 - * - * @param {number} progress - The current progress of the load. A value between 0 and 1. - */ -module.exports = 'progress'; + /** + * 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); + }, -/***/ }), -/* 977 */ -/***/ (function(module, exports) { + /** + * 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; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var gl = this.gl; + var renderer = this.renderer; -/** - * The Loader Plugin Start Event. - * - * This event is dispatched when the Loader starts running. At this point load progress is zero. - * - * This event is dispatched even if there aren't any files in the load queue. - * - * Listen to it from a Scene using: `this.load.on('start', listener)`. - * - * @event Phaser.Loader.Events#START - * @since 3.0.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader Plugin that dispatched this event. - */ -module.exports = 'start'; + this.bind(currentShader); + this.set1i('uMainSampler', 0); -/***/ }), -/* 978 */ -/***/ (function(module, exports, __webpack_require__) { + 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); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (clear) + { + if (clearAlpha) + { + gl.clearColor(0, 0, 0, 0); + } + else + { + gl.clearColor(0, 0, 0, 1); + } -// These properties get injected into the Scene and map to local systems -// The map value is the property that is injected into the Scene, the key is the Scene.Systems reference. -// These defaults can be modified via the Scene config object -// var config = { -// map: { -// add: 'makeStuff', -// load: 'loader' -// } -// }; + gl.clear(gl.COLOR_BUFFER_BIT); + } + } + else + { + renderer.popFramebuffer(false, false); -var InjectionMap = { + if (!renderer.currentFramebuffer) + { + gl.viewport(0, 0, renderer.width, renderer.height); + } + } - game: 'game', - renderer: 'renderer', + renderer.restoreStencilMask(); - anims: 'anims', - cache: 'cache', - plugins: 'plugins', - registry: 'registry', - scale: 'scale', - sound: 'sound', - textures: 'textures', + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source.texture); - events: 'events', - cameras: 'cameras', - add: 'add', - make: 'make', - scenePlugin: 'scene', - displayList: 'children', - lights: 'lights', + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); - data: 'data', - input: 'input', - load: 'load', - time: 'time', - tweens: 'tweens', + if (target) + { + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, renderer.currentFramebuffer); + } + }, - arcadePhysics: 'physics', - impactPhysics: 'impact', - matterPhysics: 'matter' + /** + * Destroys all shader instances, removes all object references and nulls all external references. + * + * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#destroy + * @since 3.60.0 + * + * @return {this} This WebGLPipeline instance. + */ + destroy: function () + { + if (this.controller) + { + this.controller.destroy(); + } -}; + this.gameObject = null; + this.controller = null; + this.colorMatrix = null; + this.fullFrame1 = null; + this.fullFrame2 = null; + this.halfFrame1 = null; + this.halfFrame2 = null; -if (false) -{} + WebGLPipeline.prototype.destroy.call(this); -if (false) -{} + return this; + } -module.exports = InjectionMap; +}); + +module.exports = PostFXPipeline; /***/ }), -/* 979 */ -/***/ (function(module, exports) { + +/***/ 87228: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var BlendModes = __webpack_require__(95723); +var CenterOn = __webpack_require__(79993); +var Class = __webpack_require__(56694); +var ColorMatrixFS = __webpack_require__(37486); +var GetFastValue = __webpack_require__(72632); +var MultiPipeline = __webpack_require__(77310); +var PostFXFS = __webpack_require__(12569); +var Rectangle = __webpack_require__(74118); +var RenderTarget = __webpack_require__(37410); +var SingleQuadFS = __webpack_require__(85060); +var SingleQuadVS = __webpack_require__(18166); +var WebGLPipeline = __webpack_require__(44775); + /** - * Parses an XML Texture Atlas object and adds all the Frames into a Texture. - * - * @function Phaser.Textures.Parsers.AtlasXML - * @memberof Phaser.Textures.Parsers - * @private - * @since 3.7.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. - * @param {number} sourceIndex - The index of the TextureSource. - * @param {*} xml - The XML data. + * @classdesc + * The Pre FX Pipeline is a special kind of pipeline designed specifically for applying + * special effects to Game Objects before they are rendered. Where-as the Post FX Pipeline applies an effect _after_ the + * object has been rendered, the Pre FX Pipeline allows you to control the rendering of + * the object itself - passing it off to its own texture, where multi-buffer compositing + * can take place. + * + * You can only use the PreFX Pipeline on the following types of Game Objects, or those + * that extend from them: + * + * Sprite + * Image + * Text + * TileSprite + * RenderTexture + * Video + * + * @class PreFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines + * @constructor + * @since 3.60.0 * - * @return {Phaser.Textures.Texture} The Texture modified by this parser. + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. */ -var AtlasXML = function (texture, sourceIndex, xml) -{ - // Malformed? - if (!xml.getElementsByTagName('TextureAtlas')) - { - console.warn('Invalid Texture Atlas XML given'); - return; - } - - // Add in a __BASE entry (for the entire atlas) - var source = texture.source[sourceIndex]; - - texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); +var PreFXPipeline = new Class({ - // By this stage frames is a fully parsed array - var frames = xml.getElementsByTagName('SubTexture'); + Extends: MultiPipeline, - var newFrame; + initialize: - for (var i = 0; i < frames.length; i++) + function PreFXPipeline (config) { - var frame = frames[i].attributes; + var fragShader = GetFastValue(config, 'fragShader', PostFXFS); + var vertShader = GetFastValue(config, 'vertShader', SingleQuadVS); + var drawShader = GetFastValue(config, 'drawShader', PostFXFS); - var name = frame.name.value; - var x = parseInt(frame.x.value, 10); - var y = parseInt(frame.y.value, 10); - var width = parseInt(frame.width.value, 10); - var height = parseInt(frame.height.value, 10); + var defaultShaders = [ + { + name: 'DrawSprite', + fragShader: SingleQuadFS, + vertShader: SingleQuadVS + }, + { + name: 'CopySprite', + fragShader: fragShader, + vertShader: vertShader + }, + { + name: 'DrawGame', + fragShader: drawShader, + vertShader: SingleQuadVS + }, + { + name: 'ColorMatrix', + fragShader: ColorMatrixFS + } + ]; - // The frame values are the exact coordinates to cut the frame out of the atlas from - newFrame = texture.add(name, sourceIndex, x, y, width, height); + var configShaders = GetFastValue(config, 'shaders', []); - // These are the original (non-trimmed) sprite values - if (frame.frameX) - { - var frameX = Math.abs(parseInt(frame.frameX.value, 10)); - var frameY = Math.abs(parseInt(frame.frameY.value, 10)); - var frameWidth = parseInt(frame.frameWidth.value, 10); - var frameHeight = parseInt(frame.frameHeight.value, 10); + config.shaders = defaultShaders.concat(configShaders); - newFrame.setTrim( - width, - height, - frameX, - frameY, - frameWidth, - frameHeight - ); + if (!config.vertShader) + { + config.vertShader = vertShader; } - } - - return texture; -}; - -module.exports = AtlasXML; + config.batchSize = 1; -/***/ }), -/* 980 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + MultiPipeline.call(this, config); -/** - * Adds a Canvas Element to a Texture. - * - * @function Phaser.Textures.Parsers.Canvas - * @memberof Phaser.Textures.Parsers - * @private - * @since 3.0.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. - * @param {number} sourceIndex - The index of the TextureSource. - * - * @return {Phaser.Textures.Texture} The Texture modified by this parser. - */ -var Canvas = function (texture, sourceIndex) -{ - var source = texture.source[sourceIndex]; + this.isPreFX = true; - texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); + this.customMainSampler = null; - return texture; -}; + /** + * A reference to the Draw Sprite Shader belonging to this Pipeline. + * + * This shader is used when the sprite is drawn to this fbo (or to the game if drawToFrame is false) + * + * This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#drawSpriteShader + * @type {Phaser.Renderer.WebGL.WebGLShader} + * @default null + * @since 3.60.0 + */ + this.drawSpriteShader; -module.exports = Canvas; + /** + * A reference to the Copy Shader belonging to this Pipeline. + * + * This shader is used when you call the `copySprite` method. + * + * This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#copyShader + * @type {Phaser.Renderer.WebGL.WebGLShader} + * @default null + * @since 3.60.0 + */ + this.copyShader; + /** + * A reference to the Game Draw Shader belonging to this Pipeline. + * + * This shader draws the fbo to the game. + * + * This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#gameShader + * @type {Phaser.Renderer.WebGL.WebGLShader} + * @default null + * @since 3.60.0 + */ + this.gameShader; -/***/ }), -/* 981 */ -/***/ (function(module, exports) { + /** + * A reference to the Color Matrix Shader belonging to this Pipeline. + * + * This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#colorMatrixShader + * @type {Phaser.Renderer.WebGL.WebGLShader} + * @since 3.60.0 + */ + this.colorMatrixShader; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Raw byte buffer of vertices used specifically during the copySprite method. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#quadVertexData + * @type {ArrayBuffer} + * @readonly + * @since 3.60.0 + */ + this.quadVertexData; -/** - * Adds an Image Element to a Texture. - * - * @function Phaser.Textures.Parsers.Image - * @memberof Phaser.Textures.Parsers - * @private - * @since 3.0.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. - * @param {number} sourceIndex - The index of the TextureSource. - * - * @return {Phaser.Textures.Texture} The Texture modified by this parser. - */ -var Image = function (texture, sourceIndex) -{ - var source = texture.source[sourceIndex]; + /** + * The WebGLBuffer that holds the quadVertexData. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#quadVertexBuffer + * @type {WebGLBuffer} + * @readonly + * @since 3.60.0 + */ + this.quadVertexBuffer; - texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); + /** + * Float32 view of the quad array buffer. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#quadVertexViewF32 + * @type {Float32Array} + * @since 3.60.0 + */ + this.quadVertexViewF32; - return texture; -}; + /** + * A temporary Rectangle object re-used internally during sprite drawing. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#spriteBounds + * @type {Phaser.Geom.Rectangle} + * @private + * @since 3.60.0 + */ + this.spriteBounds = new Rectangle(); -module.exports = Image; + /** + * A temporary Rectangle object re-used internally during sprite drawing. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#targetBounds + * @type {Phaser.Geom.Rectangle} + * @private + * @since 3.60.0 + */ + this.targetBounds = new Rectangle(); + /** + * The full-screen Render Target that the sprite is first drawn to. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#fsTarget + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.60.0 + */ + this.fsTarget; -/***/ }), -/* 982 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The most recent Game Object drawn. + * + * @name Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#tempSprite + * @type {Phaser.GameObjects.Sprite} + * @private + * @since 3.60.0 + */ + this.tempSprite; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.renderer.isBooted) + { + this.manager = this.renderer.pipelines; -var Clone = __webpack_require__(77); + this.boot(); + } + }, -/** - * Parses a Texture Atlas JSON Array and adds the Frames to the Texture. - * JSON format expected to match that defined by Texture Packer, with the frames property containing an array of Frames. - * - * @function Phaser.Textures.Parsers.JSONArray - * @memberof Phaser.Textures.Parsers - * @private - * @since 3.0.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. - * @param {number} sourceIndex - The index of the TextureSource. - * @param {object} json - The JSON data. - * - * @return {Phaser.Textures.Texture} The Texture modified by this parser. - */ -var JSONArray = function (texture, sourceIndex, json) -{ - // Malformed? - if (!json['frames'] && !json['textures']) + boot: function () { - console.warn('Invalid Texture Atlas JSON Array'); - return; - } - - // Add in a __BASE entry (for the entire atlas) - var source = texture.source[sourceIndex]; + WebGLPipeline.prototype.boot.call(this); - texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); + var shaders = this.shaders; + var renderer = this.renderer; - // By this stage frames is a fully parsed array - var frames = (Array.isArray(json.textures)) ? json.textures[sourceIndex].frames : json.frames; + this.drawSpriteShader = shaders[0]; + this.copyShader = shaders[1]; + this.gameShader = shaders[2]; + this.colorMatrixShader = shaders[3]; - var newFrame; + // Our full-screen target (exclusive to this pipeline) + this.fsTarget = new RenderTarget(renderer, renderer.width, renderer.height, 1, 0, true, true); - for (var i = 0; i < frames.length; i++) - { - var src = frames[i]; + // Copy by reference the RTs in the PipelineManager, plus add our fsTarget + this.renderTargets = this.manager.renderTargets.concat(this.fsTarget); - // The frame values are the exact coordinates to cut the frame out of the atlas from - newFrame = texture.add(src.filename, sourceIndex, src.frame.x, src.frame.y, src.frame.w, src.frame.h); + // 6 verts * 28 bytes + var data = new ArrayBuffer(168); - // These are the original (non-trimmed) sprite values - if (src.trimmed) - { - newFrame.setTrim( - src.sourceSize.w, - src.sourceSize.h, - src.spriteSourceSize.x, - src.spriteSourceSize.y, - src.spriteSourceSize.w, - src.spriteSourceSize.h - ); - } + this.quadVertexData = data; - if (src.rotated) - { - newFrame.rotated = true; - newFrame.updateUVsInverted(); - } + this.quadVertexViewF32 = new Float32Array(data); - var pivot = src.anchor || src.pivot; + this.quadVertexBuffer = renderer.createVertexBuffer(data, this.gl.STATIC_DRAW); - if (pivot) - { - newFrame.customPivot = true; - newFrame.pivotX = pivot.x; - newFrame.pivotY = pivot.y; - } + this.onResize(renderer.width, renderer.height); - // Copy over any extra data - newFrame.customData = Clone(src); - } + // So calls to set uniforms in onPreRender target the right shader: + this.currentShader = this.copyShader; + }, - // Copy over any additional data that was in the JSON to Texture.customData - for (var dataKey in json) + /** + * Handles the resizing of the quad vertex data. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#onResize + * @since 3.60.0 + * + * @param {number} width - The new width of the quad. + * @param {number} height - The new height of the quad. + */ + onResize: function (width, height) { - if (dataKey === 'frames') - { - continue; - } - - if (Array.isArray(json[dataKey])) - { - texture.customData[dataKey] = json[dataKey].slice(0); - } - else - { - texture.customData[dataKey] = json[dataKey]; - } - } + var vertexViewF32 = this.quadVertexViewF32; - return texture; -}; + // vertexBuffer indexes: -module.exports = JSONArray; + // Each vert: [ x, y, u, v, unit, mode, tint ] + // 0 - 6 - vert 1 - x0/y0 + // 7 - 13 - vert 2 - x1/y1 + // 14 - 20 - vert 3 - x2/y2 + // 21 - 27 - vert 4 - x0/y0 + // 28 - 34 - vert 5 - x2/y2 + // 35 - 41 - vert 6 - x3/y3 -/***/ }), -/* 983 */ -/***/ (function(module, exports, __webpack_require__) { + // Verts + vertexViewF32[1] = height; // y0 + vertexViewF32[22] = height; // y0 + vertexViewF32[14] = width; // x2 + vertexViewF32[28] = width; // x2 + vertexViewF32[35] = width; // x3 + vertexViewF32[36] = height; // y3 + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Adds the vertices data into the batch and flushes if full. + * + * Assumes 6 vertices in the following arrangement: + * + * ``` + * 0----3 + * |\ B| + * | \ | + * | \ | + * | A \| + * | \ + * 1----2 + * ``` + * + * Where x0 / y0 = 0, x1 / y1 = 1, x2 / y2 = 2 and x3 / y3 = 3 + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#batchQuad + * @since 3.60.0 + * + * @param {(Phaser.GameObjects.GameObject|null)} gameObject - The Game Object, if any, drawing this quad. + * @param {number} x0 - The top-left x position. + * @param {number} y0 - The top-left y position. + * @param {number} x1 - The bottom-left x position. + * @param {number} y1 - The bottom-left y position. + * @param {number} x2 - The bottom-right x position. + * @param {number} y2 - The bottom-right y position. + * @param {number} x3 - The top-right x position. + * @param {number} y3 - The top-right y position. + * @param {number} u0 - UV u0 value. + * @param {number} v0 - UV v0 value. + * @param {number} u1 - UV u1 value. + * @param {number} v1 - UV v1 value. + * @param {number} tintTL - The top-left tint color value. + * @param {number} tintTR - The top-right tint color value. + * @param {number} tintBL - The bottom-left tint color value. + * @param {number} tintBR - The bottom-right tint color value. + * @param {(number|boolean)} tintEffect - The tint effect for the shader to use. + * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs. + * + * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`. + */ + batchQuad: function (gameObject, x0, y0, x1, y1, x2, y2, x3, y3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture) + { + var bx = Math.min(x0, x1, x2, x3); + var by = Math.min(y0, y1, y2, y3); + var br = Math.max(x0, x1, x2, x3); + var bb = Math.max(y0, y1, y2, y3); + var bw = br - bx; + var bh = bb - by; -var Clone = __webpack_require__(77); + var bounds = this.spriteBounds.setTo(bx, by, bw, bh); -/** - * Parses a Texture Atlas JSON Hash and adds the Frames to the Texture. - * JSON format expected to match that defined by Texture Packer, with the frames property containing an object of Frames. - * - * @function Phaser.Textures.Parsers.JSONHash - * @memberof Phaser.Textures.Parsers - * @private - * @since 3.0.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. - * @param {number} sourceIndex - The index of the TextureSource. - * @param {object} json - The JSON data. - * - * @return {Phaser.Textures.Texture} The Texture modified by this parser. - */ -var JSONHash = function (texture, sourceIndex, json) -{ - // Malformed? - if (!json['frames']) - { - console.warn('Invalid Texture Atlas JSON Hash given, missing \'frames\' Object'); - return; - } + var padding = (gameObject) ? gameObject.preFX.padding : 0; + var width = bw + (padding * 2); + var height = bh + (padding * 2); + var maxDimension = Math.abs(Math.max(width, height)); - // Add in a __BASE entry (for the entire atlas) - var source = texture.source[sourceIndex]; + var target = this.manager.getRenderTarget(maxDimension); - texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); + var targetBounds = this.targetBounds.setTo(0, 0, target.width, target.height); - // By this stage frames is a fully parsed Object - var frames = json.frames; - var newFrame; + // targetBounds is the same size as the fbo and centered on the spriteBounds + // so we can use it when we re-render this back to the game + CenterOn(targetBounds, bounds.centerX, bounds.centerY); - for (var key in frames) - { - if (!frames.hasOwnProperty(key)) - { - continue; - } + this.tempSprite = gameObject; - var src = frames[key]; + // Now draw the quad + var gl = this.gl; + var renderer = this.renderer; - // The frame values are the exact coordinates to cut the frame out of the atlas from - newFrame = texture.add(key, sourceIndex, src.frame.x, src.frame.y, src.frame.w, src.frame.h); + renderer.clearStencilMask(); - // These are the original (non-trimmed) sprite values - if (src.trimmed) - { - newFrame.setTrim( - src.sourceSize.w, - src.sourceSize.h, - src.spriteSourceSize.x, - src.spriteSourceSize.y, - src.spriteSourceSize.w, - src.spriteSourceSize.h - ); - } + this.setShader(this.drawSpriteShader); - if (src.rotated) - { - newFrame.rotated = true; - newFrame.updateUVsInverted(); - } + this.set1i('uMainSampler', 0); - var pivot = src.anchor || src.pivot; + this.flipProjectionMatrix(true); - if (pivot) + if (gameObject) { - newFrame.customPivot = true; - newFrame.pivotX = pivot.x; - newFrame.pivotY = pivot.y; + this.onDrawSprite(gameObject, target); + + gameObject.preFX.onFX(this); } - // Copy over any extra data - newFrame.customData = Clone(src); - } + var fsTarget = this.fsTarget; - // Copy over any additional data that was in the JSON to Texture.customData - for (var dataKey in json) - { - if (dataKey === 'frames') - { - continue; - } + this.flush(); - if (Array.isArray(json[dataKey])) - { - texture.customData[dataKey] = json[dataKey].slice(0); - } - else - { - texture.customData[dataKey] = json[dataKey]; - } - } + gl.viewport(0, 0, renderer.width, renderer.height); + gl.bindFramebuffer(gl.FRAMEBUFFER, fsTarget.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fsTarget.texture, 0); - return texture; -}; + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); -module.exports = JSONHash; + this.setTexture2D(texture); + this.batchVert(x0, y0, u0, v0, 0, tintEffect, tintTL); + this.batchVert(x1, y1, u0, v1, 0, tintEffect, tintBL); + this.batchVert(x2, y2, u1, v1, 0, tintEffect, tintBR); -/***/ }), -/* 984 */ -/***/ (function(module, exports, __webpack_require__) { + this.batchVert(x0, y0, u0, v0, 0, tintEffect, tintTL); + this.batchVert(x2, y2, u1, v1, 0, tintEffect, tintBR); + this.batchVert(x3, y3, u1, v0, 0, tintEffect, tintTR); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.flush(); -var GetFastValue = __webpack_require__(2); + this.flipProjectionMatrix(false); -/** - * Parses a Sprite Sheet and adds the Frames to the Texture. - * - * 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. - * - * @function Phaser.Textures.Parsers.SpriteSheet - * @memberof Phaser.Textures.Parsers - * @private - * @since 3.0.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. - * @param {number} sourceIndex - The index of the TextureSource. - * @param {number} x - The top-left coordinate of the Sprite Sheet. Defaults to zero. Used when extracting sheets from atlases. - * @param {number} y - The top-left coordinate of the Sprite Sheet. Defaults to zero. Used when extracting sheets from atlases. - * @param {number} width - The width of the source image. - * @param {number} height - The height of the source image. - * @param {object} config - An object describing how to parse the Sprite Sheet. - * @param {number} config.frameWidth - Width in pixels of a single frame in the sprite sheet. - * @param {number} [config.frameHeight] - Height in pixels of a single frame in the sprite sheet. Defaults to frameWidth if not provided. - * @param {number} [config.startFrame=0] - The frame to start extracting from. Defaults to zero. - * @param {number} [config.endFrame=-1] - The frame to finish extracting at. Defaults to -1, which means 'all frames'. - * @param {number} [config.margin=0] - If the frames have been drawn with a margin, specify the amount here. - * @param {number} [config.spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. - * - * @return {Phaser.Textures.Texture} The Texture modified by this parser. - */ -var SpriteSheet = function (texture, sourceIndex, x, y, width, height, config) -{ - var frameWidth = GetFastValue(config, 'frameWidth', null); - var frameHeight = GetFastValue(config, 'frameHeight', frameWidth); + // Now we've got the sprite drawn to our screen-sized fbo, copy the rect we need to our target - // If missing we can't proceed - if (frameWidth === null) - { - throw new Error('TextureManager.SpriteSheet: Invalid frameWidth given.'); - } + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, target.texture); + gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, targetBounds.x, targetBounds.y, targetBounds.width, targetBounds.height); - // Add in a __BASE entry (for the entire atlas) - var source = texture.source[sourceIndex]; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.bindTexture(gl.TEXTURE_2D, null); - texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); + // We've drawn the sprite to the target (using our pipeline shader) + // we can pass it to the pipeline in case they want to do further + // manipulations with it, post-fx style, then we need to draw the + // results back to the game in the correct position - var startFrame = GetFastValue(config, 'startFrame', 0); - var endFrame = GetFastValue(config, 'endFrame', -1); - var margin = GetFastValue(config, 'margin', 0); - var spacing = GetFastValue(config, 'spacing', 0); + this.onBatch(gameObject); - var row = Math.floor((width - margin + spacing) / (frameWidth + spacing)); - var column = Math.floor((height - margin + spacing) / (frameHeight + spacing)); - var total = row * column; + // Set this here, so we can immediately call the set uniform functions and it'll work on the correct shader + this.currentShader = this.copyShader; - if (total === 0) - { - console.warn('SpriteSheet frame dimensions will result in zero frames for texture:', texture.key); - } + this.onDraw(target, this.manager.getSwapRenderTarget(), this.manager.getAltSwapRenderTarget()); - if (startFrame > total || startFrame < -total) - { - startFrame = 0; - } + return true; + }, - if (startFrame < 0) + /** + * This callback is invoked when a sprite is drawn by this pipeline. + * + * It will fire after the shader has been set, but before the sprite has been drawn, + * so use it to set any additional uniforms you may need. + * + * Note: Manipulating the Sprite during this callback will _not_ change how it is drawn to the Render Target. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#onDrawSprite + * @since 3.60.0 + * + * @param {Phaser.GameObjects.Sprite} gameObject - The Sprite being drawn. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target the Sprite will be drawn to. + */ + onDrawSprite: function () { - // Allow negative skipframes. - startFrame = total + startFrame; - } + }, - if (endFrame !== -1) + /** + * This callback is invoked when you call the `copySprite` method. + * + * It will fire after the shader has been set, but before the source target has been copied, + * so use it to set any additional uniforms you may need. + * + * Note: Manipulating the Sprite during this callback will _not_ change the Render Targets. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#onCopySprite + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target being copied from. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target that will be copied to. + * @param {Phaser.GameObjects.Sprite} gameObject - The Sprite being copied. + */ + onCopySprite: function () { - total = startFrame + (endFrame + 1); - } - - var fx = margin; - var fy = margin; - var ax = 0; - var ay = 0; + }, - for (var i = 0; i < total; i++) + /** + * Copy the `source` Render Target to the `target` Render Target. + * + * No target 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. + * + * Calling this method will invoke the `onCopySprite` handler and will also call + * the `onFXCopy` callback on the Sprite. Both of these happen prior to the copy, allowing you + * to use them to set shader uniforms and other values. + * + * You can optionally pass in a ColorMatrix. If so, it will use the ColorMatrix shader + * during the copy, allowing you to manipulate the colors to a fine degree. + * See the `ColorMatrix` class for more details. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#copySprite + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target being copied from. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target that will be copied to. + * @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? + * @param {Phaser.Display.ColorMatrix} [colorMatrix] - Optional ColorMatrix to use when copying the Sprite. + * @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to use to copy the target. Defaults to the `copyShader`. + */ + copySprite: function (source, target, clear, clearAlpha, eraseMode, colorMatrix, shader) { - ax = 0; - ay = 0; - - var w = fx + frameWidth; - var h = fy + frameHeight; + if (clear === undefined) { clear = true; } + if (clearAlpha === undefined) { clearAlpha = true; } + if (eraseMode === undefined) { eraseMode = false; } + if (shader === undefined) { shader = this.copyShader; } - if (w > width) - { - ax = w - width; - } + var gl = this.gl; + var sprite = this.tempSprite; - if (h > height) + if (colorMatrix) { - ay = h - height; + shader = this.colorMatrixShader; } - texture.add(i, sourceIndex, x + fx, y + fy, frameWidth - ax, frameHeight - ay); - - fx += frameWidth + spacing; - - if (fx + frameWidth > width) - { - fx = margin; - fy += frameHeight + spacing; - } - } + this.currentShader = shader; - return texture; -}; + var wasBound = this.setVertexBuffer(this.quadVertexBuffer); -module.exports = SpriteSheet; + shader.bind(wasBound, false); + this.set1i('uMainSampler', 0); -/***/ }), -/* 985 */ -/***/ (function(module, exports, __webpack_require__) { + sprite.preFX.onFXCopy(this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.onCopySprite(source, target, sprite); -var GetFastValue = __webpack_require__(2); + if (colorMatrix) + { + this.set1fv('uColorMatrix', colorMatrix.getData()); + this.set1f('uAlpha', colorMatrix.alpha); + } -/** - * Parses a Sprite Sheet and adds the Frames to the Texture, where the Sprite Sheet is stored as a frame within an 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. - * - * @function Phaser.Textures.Parsers.SpriteSheetFromAtlas - * @memberof Phaser.Textures.Parsers - * @private - * @since 3.0.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. - * @param {Phaser.Textures.Frame} frame - The Frame that contains the Sprite Sheet. - * @param {object} config - An object describing how to parse the Sprite Sheet. - * @param {number} config.frameWidth - Width in pixels of a single frame in the sprite sheet. - * @param {number} [config.frameHeight] - Height in pixels of a single frame in the sprite sheet. Defaults to frameWidth if not provided. - * @param {number} [config.startFrame=0] - Index of the start frame in the sprite sheet - * @param {number} [config.endFrame=-1] - Index of the end frame in the sprite sheet. -1 mean all the rest of the frames - * @param {number} [config.margin=0] - If the frames have been drawn with a margin, specify the amount here. - * @param {number} [config.spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. - * - * @return {Phaser.Textures.Texture} The Texture modified by this parser. - */ -var SpriteSheetFromAtlas = function (texture, frame, config) -{ - var frameWidth = GetFastValue(config, 'frameWidth', null); - var frameHeight = GetFastValue(config, 'frameHeight', frameWidth); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source.texture); - // If missing we can't proceed - if (!frameWidth) - { - throw new Error('TextureManager.SpriteSheetFromAtlas: Invalid frameWidth given.'); - } + if (source.height > target.height) + { + gl.viewport(0, 0, source.width, source.height); - // Add in a __BASE entry (for the entire atlas frame) - var source = texture.source[0]; - texture.add('__BASE', 0, 0, 0, source.width, source.height); + this.setTargetUVs(source, target); + } + else + { + var diff = target.height - source.height; - var startFrame = GetFastValue(config, 'startFrame', 0); - var endFrame = GetFastValue(config, 'endFrame', -1); - var margin = GetFastValue(config, 'margin', 0); - var spacing = GetFastValue(config, 'spacing', 0); + gl.viewport(0, diff, source.width, source.height); - var x = frame.cutX; - var y = frame.cutY; + this.resetUVs(); + } - var cutWidth = frame.cutWidth; - var cutHeight = frame.cutHeight; - var sheetWidth = frame.realWidth; - var sheetHeight = frame.realHeight; + gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture, 0); - var row = Math.floor((sheetWidth - margin + spacing) / (frameWidth + spacing)); - var column = Math.floor((sheetHeight - margin + spacing) / (frameHeight + spacing)); - var total = row * column; + if (clear) + { + gl.clearColor(0, 0, 0, Number(!clearAlpha)); - // trim offsets + gl.clear(gl.COLOR_BUFFER_BIT); + } - var leftPad = frame.x; - var leftWidth = frameWidth - leftPad; + if (eraseMode) + { + var blendMode = this.renderer.currentBlendMode; - var rightWidth = frameWidth - ((sheetWidth - cutWidth) - leftPad); + this.renderer.setBlendMode(BlendModes.ERASE); + } - var topPad = frame.y; - var topHeight = frameHeight - topPad; + gl.bufferData(gl.ARRAY_BUFFER, this.quadVertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); - var bottomHeight = frameHeight - ((sheetHeight - cutHeight) - topPad); + if (eraseMode) + { + this.renderer.setBlendMode(blendMode); + } - if (startFrame > total || startFrame < -total) - { - startFrame = 0; - } + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + }, - if (startFrame < 0) + /** + * Draws the `source` Render Target to the `target` Render Target. + * + * This is done using whatever the currently bound shader is. This method does + * not set a shader. All it does is bind the source texture, set the viewport and UVs + * then bind the target framebuffer, clears it and draws the source to it. + * + * At the end a null framebuffer is bound. No other clearing-up takes place, so + * use this method carefully. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#copy + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. + */ + copy: function (source, target) { - // Allow negative skipframes. - startFrame = total + startFrame; - } + var gl = this.gl; - if (endFrame !== -1) - { - total = startFrame + (endFrame + 1); - } + this.set1i('uMainSampler', 0); - var sheetFrame; - var frameX = margin; - var frameY = margin; - var frameIndex = 0; - var sourceIndex = frame.sourceIndex; + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source.texture); - for (var sheetY = 0; sheetY < column; sheetY++) - { - var topRow = (sheetY === 0); - var bottomRow = (sheetY === column - 1); + // source and target must always be the same size + gl.viewport(0, 0, source.width, source.height); - for (var sheetX = 0; sheetX < row; sheetX++) - { - var leftRow = (sheetX === 0); - var rightRow = (sheetX === row - 1); + this.setUVs(0, 0, 0, 1, 1, 1, 1, 0); - sheetFrame = texture.add(frameIndex, sourceIndex, x + frameX, y + frameY, frameWidth, frameHeight); + gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture, 0); - if (leftRow || topRow || rightRow || bottomRow) - { - var destX = (leftRow) ? leftPad : 0; - var destY = (topRow) ? topPad : 0; + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); - var trimWidth = 0; - var trimHeight = 0; + gl.bufferData(gl.ARRAY_BUFFER, this.quadVertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); - if (leftRow) - { - trimWidth += (frameWidth - leftWidth); - } + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + }, - if (rightRow) - { - trimWidth += (frameWidth - rightWidth); - } + /** + * 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.PreFXPipeline#blendFrames + * @since 3.60.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); + }, - if (topRow) - { - trimHeight += (frameHeight - topHeight); - } + /** + * 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.PreFXPipeline#blendFramesAdditive + * @since 3.60.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); + }, - if (bottomRow) - { - trimHeight += (frameHeight - bottomHeight); - } + /** + * This method will copy the given Render Target to the game canvas using the `copyShader`. + * + * This applies the results of the copy shader during the draw. + * + * If you wish to copy the target without any effects see the `copyToGame` method instead. + * + * This method should be the final thing called in your pipeline. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#drawToGame + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw to the game. + */ + drawToGame: function (source) + { + this.currentShader = null; - var destWidth = frameWidth - trimWidth; - var destHeight = frameHeight - trimHeight; + this.setShader(this.copyShader); - sheetFrame.cutWidth = destWidth; - sheetFrame.cutHeight = destHeight; + this.bindAndDraw(source); + }, - sheetFrame.setTrim(frameWidth, frameHeight, destX, destY, destWidth, destHeight); - } + /** + * This method will copy the given Render Target to the game canvas using the `gameShader`. + * + * Unless you've changed it, the `gameShader` copies the target without modifying it, just + * ensuring it is placed in the correct location on the canvas. + * + * If you wish to draw the target with and apply the fragment shader at the same time, + * see the `drawToGame` method instead. + * + * This method should be the final thing called in your pipeline. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#copyToGame + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to copy to the game. + */ + copyToGame: function (source) + { + this.currentShader = null; - frameX += spacing; + this.setShader(this.gameShader); - if (leftRow) - { - frameX += leftWidth; - } - else if (rightRow) - { - frameX += rightWidth; - } - else - { - frameX += frameWidth; - } + this.bindAndDraw(source); + }, - frameIndex++; - } + /** + * This method is called by `drawToGame` and `copyToGame`. It takes the source Render Target + * and copies it back to the game canvas, or the next frame buffer in the stack, and should + * be considered the very last thing this pipeline does. + * + * You don't normally need to call this method, or override it, however it is left public + * should you wish to do so. + * + * Note that it does _not_ set a shader. You should do this yourself if invoking this. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#bindAndDraw + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw to the game. + */ + bindAndDraw: function (source) + { + var gl = this.gl; + var renderer = this.renderer; - frameX = margin; - frameY += spacing; + this.set1i('uMainSampler', 0); - if (topRow) - { - frameY += topHeight; - } - else if (bottomRow) + if (this.customMainSampler) { - frameY += bottomHeight; + this.setTexture2D(this.customMainSampler); } else { - frameY += frameHeight; + this.setTexture2D(source.texture); } - } - return texture; -}; + var matrix = this._tempMatrix1.loadIdentity(); -module.exports = SpriteSheetFromAtlas; + var x = this.targetBounds.x; + var y = this.targetBounds.y; + var xw = x + source.width; + var yh = y + source.height; -/***/ }), -/* 986 */ -/***/ (function(module, exports) { + var x0 = matrix.getX(x, y); + var x1 = matrix.getX(x, yh); + var x2 = matrix.getX(xw, yh); + var x3 = matrix.getX(xw, y); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Regular verts + var y0 = matrix.getY(x, y); + var y1 = matrix.getY(x, yh); + var y2 = matrix.getY(xw, yh); + var y3 = matrix.getY(xw, y); -var imageHeight = 0; + // Flip verts: + // var y0 = matrix.getY(x, yh); + // var y1 = matrix.getY(x, y); + // var y2 = matrix.getY(xw, y); + // var y3 = matrix.getY(xw, yh); -/** - * @function addFrame - * @private - * @since 3.0.0 - */ -var addFrame = function (texture, sourceIndex, name, frame) -{ - // The frame values are the exact coordinates to cut the frame out of the atlas from + var white = 0xffffff; - var y = imageHeight - frame.y - frame.height; + this.batchVert(x0, y0, 0, 0, 0, 0, white); + this.batchVert(x1, y1, 0, 1, 0, 0, white); + this.batchVert(x2, y2, 1, 1, 0, 0, white); + this.batchVert(x0, y0, 0, 0, 0, 0, white); + this.batchVert(x2, y2, 1, 1, 0, 0, white); + this.batchVert(x3, y3, 1, 0, 0, 0, white); - texture.add(name, sourceIndex, frame.x, y, frame.width, frame.height); + renderer.restoreFramebuffer(false, true); - // These are the original (non-trimmed) sprite values - /* - if (src.trimmed) - { - newFrame.setTrim( - src.sourceSize.w, - src.sourceSize.h, - src.spriteSourceSize.x, - src.spriteSourceSize.y, - src.spriteSourceSize.w, - src.spriteSourceSize.h - ); - } - */ -}; + if (!renderer.currentFramebuffer) + { + gl.viewport(0, 0, renderer.width, renderer.height); + } -/** - * Parses a Unity YAML File and creates Frames in the Texture. - * For more details about Sprite Meta Data see https://docs.unity3d.com/ScriptReference/SpriteMetaData.html - * - * @function Phaser.Textures.Parsers.UnityYAML - * @memberof Phaser.Textures.Parsers - * @private - * @since 3.0.0 - * - * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. - * @param {number} sourceIndex - The index of the TextureSource. - * @param {object} yaml - The YAML data. - * - * @return {Phaser.Textures.Texture} The Texture modified by this parser. - */ -var UnityYAML = function (texture, sourceIndex, yaml) -{ - // Add in a __BASE entry (for the entire atlas) - var source = texture.source[sourceIndex]; + renderer.restoreStencilMask(); - texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); + this.flush(); - imageHeight = source.height; + // Clear the source framebuffer out, ready for the next pass + // gl.clearColor(0, 0, 0, 0); + // gl.bindFramebuffer(gl.FRAMEBUFFER, source.framebuffer); + // gl.clear(gl.COLOR_BUFFER_BIT); + // gl.bindFramebuffer(gl.FRAMEBUFFER, null); - var data = yaml.split('\n'); + // No hanging references + this.tempSprite = null; + }, - var lineRegExp = /^[ ]*(- )*(\w+)+[: ]+(.*)/; + /** + * This method is called every time the `batchSprite` method is called and is passed a + * reference to the current render target. + * + * If you override this method, then it should make sure it calls either the + * `drawToGame` or `copyToGame` methods as the final thing it does. However, you can do as + * much additional processing as you like prior to this. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#onDraw + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target to draw to the game. + * @param {Phaser.Renderer.WebGL.RenderTarget} [swapTarget] - The Swap Render Target, useful for double-buffer effects. + * @param {Phaser.Renderer.WebGL.RenderTarget} [altSwapTarget] - The Swap Render Target, useful for double-buffer effects. + */ + onDraw: function (target) + { + this.drawToGame(target); + }, - var prevSprite = ''; - var currentSprite = ''; - var rect = { x: 0, y: 0, width: 0, height: 0 }; + /** + * Set the UV values for the 6 vertices that make up the quad used by the copy shader. + * + * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#setUVs + * @since 3.60.0 + * + * @param {number} uA - The u value of vertex A. + * @param {number} vA - The v value of vertex A. + * @param {number} uB - The u value of vertex B. + * @param {number} vB - The v value of vertex B. + * @param {number} uC - The u value of vertex C. + * @param {number} vC - The v value of vertex C. + * @param {number} uD - The u value of vertex D. + * @param {number} vD - The v value of vertex D. + */ + setUVs: function (uA, vA, uB, vB, uC, vC, uD, vD) + { + var vertexViewF32 = this.quadVertexViewF32; - // var pivot = { x: 0, y: 0 }; - // var border = { x: 0, y: 0, z: 0, w: 0 }; + vertexViewF32[2] = uA; + vertexViewF32[3] = vA; - for (var i = 0; i < data.length; i++) - { - var results = data[i].match(lineRegExp); + vertexViewF32[9] = uB; + vertexViewF32[10] = vB; - if (!results) - { - continue; - } + vertexViewF32[16] = uC; + vertexViewF32[17] = vC; - var isList = (results[1] === '- '); - var key = results[2]; - var value = results[3]; + vertexViewF32[23] = uA; + vertexViewF32[24] = vA; - if (isList) - { - if (currentSprite !== prevSprite) - { - addFrame(texture, sourceIndex, currentSprite, rect); + vertexViewF32[30] = uC; + vertexViewF32[31] = vC; - prevSprite = currentSprite; - } + vertexViewF32[37] = uD; + vertexViewF32[38] = vD; + }, - rect = { x: 0, y: 0, width: 0, height: 0 }; - } + /** + * Sets the vertex UV coordinates of the quad used by the copy shaders + * so that they correctly adjust the texture coordinates for a blit frame effect. + * + * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#setTargetUVs + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. + */ + setTargetUVs: function (source, target) + { + var diff = (target.height / source.height); - if (key === 'name') + if (diff > 0.5) { - // Start new list - currentSprite = value; - continue; + diff = 0.5 - (diff - 0.5); } - - switch (key) + else { - case 'x': - case 'y': - case 'width': - case 'height': - rect[key] = parseInt(value, 10); - break; - - // case 'pivot': - // pivot = eval('var obj = ' + value); - // break; - - // case 'border': - // border = eval('var obj = ' + value); - // break; + diff = 0.5 + (0.5 - diff); } - } - if (currentSprite !== prevSprite) + this.setUVs(0, diff, 0, 1 + diff, 1, 1 + diff, 1, diff); + }, + + /** + * Resets the quad vertice UV values to their default settings. + * + * The quad is used by the copy shader in this pipeline. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#resetUVs + * @since 3.60.0 + */ + resetUVs: function () { - addFrame(texture, sourceIndex, currentSprite, rect); - } + this.setUVs(0, 0, 0, 1, 1, 1, 1, 0); + }, - return texture; -}; + /** + * Destroys all shader instances, removes all object references and nulls all external references. + * + * @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#destroy + * @fires Phaser.Renderer.WebGL.Pipelines.Events#DESTROY + * @since 3.60.0 + * + * @return {this} This WebGLPipeline instance. + */ + destroy: function () + { + this.gl.deleteBuffer(this.quadVertexBuffer); -module.exports = UnityYAML; + this.drawSpriteShader = null; + this.copyShader = null; + this.gameShader = null; + this.colorMatrixShader = null; -/* -Example data: + this.quadVertexData = null; + this.quadVertexBuffer = null; + this.quadVertexViewF32 = null; -TextureImporter: - spritePivot: {x: .5, y: .5} - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spritePixelsToUnits: 100 - spriteSheet: - sprites: - - name: asteroids_0 - rect: - serializedVersion: 2 - x: 5 - y: 328 - width: 65 - height: 82 - alignment: 0 - pivot: {x: 0, y: 0} - border: {x: 0, y: 0, z: 0, w: 0} - - name: asteroids_1 - rect: - serializedVersion: 2 - x: 80 - y: 322 - width: 53 - height: 88 - alignment: 0 - pivot: {x: 0, y: 0} - border: {x: 0, y: 0, z: 0, w: 0} - spritePackingTag: Asteroids -*/ + this.fsTarget = null; + this.tempSprite = null; + MultiPipeline.prototype.destroy.call(this); -/***/ }), -/* 987 */ -/***/ (function(module, exports) { + return this; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +}); -/** - * The Sound Complete Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they complete playback. - * - * Listen to it from a Sound instance using `Sound.on('complete', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('complete', listener); - * music.play(); - * ``` - * - * @event Phaser.Sound.Events#COMPLETE - * @since 3.16.1 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - */ -module.exports = 'complete'; +module.exports = PreFXPipeline; /***/ }), -/* 988 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Audio Data Decoded Event. - * - * This event is dispatched by the Web Audio Sound Manager as a result of calling the `decodeAudio` method. - * - * Listen to it from the Sound Manager in a Scene using `this.sound.on('decoded', listener)`, i.e.: - * - * ```javascript - * this.sound.on('decoded', handler); - * this.sound.decodeAudio(key, audioData); - * ``` - * - * @event Phaser.Sound.Events#DECODED - * @since 3.18.0 - * - * @param {string} key - The key of the audio file that was decoded and added to the audio cache. - */ -module.exports = 'decoded'; - -/***/ }), -/* 989 */ -/***/ (function(module, exports) { +/***/ 21213: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * The Audio Data Decoded All Event. - * - * This event is dispatched by the Web Audio Sound Manager as a result of calling the `decodeAudio` method, - * once all files passed to the method have been decoded (or errored). - * - * Use `Phaser.Sound.Events#DECODED` to listen for single sounds being decoded, and `DECODED_ALL` to - * listen for them all completing. - * - * Listen to it from the Sound Manager in a Scene using `this.sound.on('decodedall', listener)`, i.e.: - * - * ```javascript - * this.sound.once('decodedall', handler); - * this.sound.decodeAudio([ audioFiles ]); - * ``` - * - * @event Phaser.Sound.Events#DECODED_ALL - * @since 3.18.0 - */ -module.exports = 'decodedall'; - - -/***/ }), -/* 990 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var MultiPipeline = __webpack_require__(77310); /** - * The Sound Destroy Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are destroyed, either - * directly or via a Sound Manager. - * - * Listen to it from a Sound instance using `Sound.on('destroy', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('destroy', listener); - * music.destroy(); - * ``` + * @classdesc + * The Rope Pipeline is a variation of the Multi Pipeline that uses a `TRIANGLE_STRIP` for + * its topology, instead of TRIANGLES. This is primarily used by the Rope Game Object, + * or anything that extends it. * - * @event Phaser.Sound.Events#DESTROY - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - */ -module.exports = 'destroy'; - - -/***/ }), -/* 991 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Sound Detune Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their detune value changes. - * - * Listen to it from a Sound instance using `Sound.on('detune', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('detune', listener); - * music.play(); - * music.setDetune(200); - * ``` + * Prior to Phaser v3.50 this pipeline was called the `TextureTintStripPipeline`. * - * @event Phaser.Sound.Events#DETUNE - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - * @param {number} detune - The new detune value of the Sound. - */ -module.exports = 'detune'; - - -/***/ }), -/* 992 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Sound Manager Global Detune Event. - * - * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, - * or the HTML5 Audio Manager. It is dispatched when the `detune` property of the Sound Manager is changed, which globally - * adjusts the detuning of all active sounds. - * - * Listen to it from a Scene using: `this.sound.on('rate', listener)`. + * 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`. * - * @event Phaser.Sound.Events#GLOBAL_DETUNE - * @since 3.0.0 - * - * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. - * @param {number} detune - The updated detune value. + * 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) + * + * The pipeline is structurally identical to the Multi Pipeline and should be treated as such. + * + * @class RopePipeline + * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. */ -module.exports = 'detune'; +var RopePipeline = new Class({ + + Extends: MultiPipeline, + initialize: -/***/ }), -/* 993 */ -/***/ (function(module, exports) { + function RopePipeline (config) + { + // GLenum 5 = TRIANGLE_STRIP + config.topology = 5; + config.batchSize = GetFastValue(config, 'batchSize', 256); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + MultiPipeline.call(this, config); + } +}); -/** - * The Sound Manager Global Mute Event. - * - * This event is dispatched by the Sound Manager when its `mute` property is changed, either directly - * or via the `setMute` method. This changes the mute state of all active sounds. - * - * Listen to it from a Scene using: `this.sound.on('mute', listener)`. - * - * @event Phaser.Sound.Events#GLOBAL_MUTE - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager)} soundManager - A reference to the Sound Manager that emitted the event. - * @param {boolean} mute - The mute value. `true` if the Sound Manager is now muted, otherwise `false`. - */ -module.exports = 'mute'; +module.exports = RopePipeline; /***/ }), -/* 994 */ -/***/ (function(module, exports) { + +/***/ 51212: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var MultiPipeline = __webpack_require__(77310); +var ShaderSourceFS = __webpack_require__(85060); +var ShaderSourceVS = __webpack_require__(18166); +var WebGLPipeline = __webpack_require__(44775); + /** - * The Sound Manager Global Rate Event. - * - * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, - * or the HTML5 Audio Manager. It is dispatched when the `rate` property of the Sound Manager is changed, which globally - * adjusts the playback rate of all active sounds. - * - * Listen to it from a Scene using: `this.sound.on('rate', listener)`. + * @classdesc + * The Single Pipeline is a special version of the Multi Pipeline that only ever + * uses one texture, bound to texture unit zero. Although not as efficient as the + * Multi Pipeline, it provides an easier way to create custom pipelines that only require + * a single bound texture. * - * @event Phaser.Sound.Events#GLOBAL_RATE - * @since 3.0.0 - * - * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. - * @param {number} rate - The updated rate value. + * Prior to Phaser v3.50 this pipeline didn't exist, but could be compared to the old `TextureTintPipeline`. + * + * The fragment shader it uses can be found in `shaders/src/Single.frag`. + * The vertex shader it uses can be found in `shaders/src/Single.vert`. + * + * The default shader attributes for this pipeline are: + * + * `inPosition` (vec2, offset 0) + * `inTexCoord` (vec2, offset 8) + * `inTexId` (float, offset 16) - this value is always zero in the Single Pipeline + * `inTintEffect` (float, offset 20) + * `inTint` (vec4, offset 24, normalized) + * + * The default shader uniforms for this pipeline are: + * + * `uProjectionMatrix` (mat4) + * `uMainSampler` (sampler2D) + * + * @class SinglePipeline + * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines + * @constructor + * @since 3.50.0 + * + * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. */ -module.exports = 'rate'; +var SinglePipeline = new Class({ + Extends: MultiPipeline, -/***/ }), -/* 995 */ -/***/ (function(module, exports) { + initialize: -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + function SinglePipeline (config) + { + config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS), + config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS), + config.forceZero = true; -/** - * The Sound Manager Global Volume Event. - * - * This event is dispatched by the Sound Manager when its `volume` property is changed, either directly - * or via the `setVolume` method. This changes the volume of all active sounds. - * - * Listen to it from a Scene using: `this.sound.on('volume', listener)`. - * - * @event Phaser.Sound.Events#GLOBAL_VOLUME - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager)} soundManager - A reference to the sound manager that emitted the event. - * @param {number} volume - The new global volume of the Sound Manager. - */ -module.exports = 'volume'; + MultiPipeline.call(this, config); + }, + boot: function () + { + WebGLPipeline.prototype.boot.call(this); -/***/ }), -/* 996 */ -/***/ (function(module, exports) { + this.set1i('uMainSampler', 0); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +}); -/** - * The Sound Loop Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their loop state is changed. - * - * Listen to it from a Sound instance using `Sound.on('loop', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('loop', listener); - * music.setLoop(true); - * ``` - * - * This is not to be confused with the [LOOPED]{@linkcode Phaser.Sound.Events#event:LOOPED} event, which emits each time a Sound loops during playback. - * - * @event Phaser.Sound.Events#LOOP - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - * @param {boolean} loop - The new loop value. `true` if the Sound will loop, otherwise `false`. - */ -module.exports = 'loop'; +module.exports = SinglePipeline; /***/ }), -/* 997 */ -/***/ (function(module, exports) { + +/***/ 60848: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var AddBlendFS = __webpack_require__(2529); +var BlendModes = __webpack_require__(95723); +var Class = __webpack_require__(56694); +var ColorMatrix = __webpack_require__(65246); +var ColorMatrixFS = __webpack_require__(37486); +var CopyFS = __webpack_require__(79060); +var GetFastValue = __webpack_require__(72632); +var LinearBlendFS = __webpack_require__(98921); +var QuadVS = __webpack_require__(99365); +var WebGLPipeline = __webpack_require__(44775); + /** - * The Sound Looped Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they loop during playback. - * - * Listen to it from a Sound instance using `Sound.on('looped', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('looped', listener); - * music.setLoop(true); - * music.play(); - * ``` - * - * This is not to be confused with the [LOOP]{@linkcode Phaser.Sound.Events#event:LOOP} event, which only emits when the loop state of a Sound is changed. + * @classdesc + * The Utility Pipeline is a special-use pipeline that belongs to the Pipeline Manager. * - * @event Phaser.Sound.Events#LOOPED - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. + * It provides 4 shaders and handy associated methods: + * + * 1) Copy Shader. A fast texture to texture copy shader with optional brightness setting. + * 2) Additive Blend Mode Shader. Blends two textures using an additive blend mode. + * 3) Linear Blend Mode Shader. Blends two textures using a linear blend mode. + * 4) Color Matrix Copy Shader. Draws a texture to a target using a Color Matrix. + * + * You do not extend this pipeline, but instead get a reference to it from the Pipeline + * Manager via the `setUtility` method. You can also access methods such as `copyFrame` + * directly from the Pipeline Manager. + * + * This pipeline provides methods for manipulating framebuffer backed textures, such as + * copying or blending one texture to another, copying a portion of a texture, additively + * blending two textures, flipping textures and more. + * + * The default shader attributes for this pipeline are: + * + * `inPosition` (vec2, offset 0) + * `inTexCoord` (vec2, offset 8) + * + * This pipeline has a hard-coded batch size of 1 and a hard coded set of vertices. + * + * @class UtilityPipeline + * @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. */ -module.exports = 'looped'; +var UtilityPipeline = new Class({ + Extends: WebGLPipeline, -/***/ }), -/* 998 */ -/***/ (function(module, exports) { + initialize: -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + function UtilityPipeline (config) + { + config.renderTarget = GetFastValue(config, 'renderTarget', [ + { + scale: 1 + }, + { + scale: 1 + }, + { + scale: 0.5 + }, + { + scale: 0.5 + } + ]); -/** - * The Sound Mute Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their mute state changes. - * - * Listen to it from a Sound instance using `Sound.on('mute', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('mute', listener); - * music.play(); - * music.setMute(true); - * ``` - * - * @event Phaser.Sound.Events#MUTE - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - * @param {boolean} mute - The mute value. `true` if the Sound is now muted, otherwise `false`. - */ -module.exports = 'mute'; + config.vertShader = GetFastValue(config, 'vertShader', QuadVS); + config.shaders = GetFastValue(config, 'shaders', [ + { + name: 'Copy', + fragShader: CopyFS + }, + { + name: 'AddBlend', + fragShader: AddBlendFS + }, + { + name: 'LinearBlend', + fragShader: LinearBlendFS + }, + { + name: 'ColorMatrix', + fragShader: ColorMatrixFS + } + ]); -/***/ }), -/* 999 */ -/***/ (function(module, exports) { + config.attributes = GetFastValue(config, 'attributes', [ + { + name: 'inPosition', + size: 2 + }, + { + name: 'inTexCoord', + size: 2 + } + ]); -/** - * @author pi-kei - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + 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 + ]; -/** - * The Sound Pan Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes. - * - * Listen to it from a Sound instance using `Sound.on('pan', listener)`, i.e.: - * - * ```javascript - * var sound = this.sound.add('key'); - * sound.on('pan', listener); - * sound.play(); - * sound.setPan(0.5); - * ``` - * - * @event Phaser.Sound.Events#PAN - * @since 3.50.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - * @param {number} pan - The new pan of the Sound. - */ -module.exports = 'pan'; + config.batchSize = 1; + WebGLPipeline.call(this, config); -/***/ }), -/* 1000 */ -/***/ (function(module, exports) { + /** + * A default Color Matrix, used by the Color Matrix Shader when one + * isn't provided. + * + * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#colorMatrix + * @type {Phaser.Display.ColorMatrix} + * @since 3.50.0 + */ + this.colorMatrix = new ColorMatrix(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * A reference to the Copy Shader belonging to this Utility Pipeline. + * + * This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#copyShader + * @type {Phaser.Renderer.WebGL.WebGLShader} + * @default null + * @since 3.50.0 + */ + this.copyShader; -/** - * The Pause All Sounds Event. - * - * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, - * or the HTML5 Audio Manager. It is dispatched when the `pauseAll` method is invoked and after all current Sounds - * have been paused. - * - * Listen to it from a Scene using: `this.sound.on('pauseall', listener)`. - * - * @event Phaser.Sound.Events#PAUSE_ALL - * @since 3.0.0 - * - * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. - */ -module.exports = 'pauseall'; + /** + * A reference to the Additive Blend Shader belonging to this Utility Pipeline. + * + * This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#addShader + * @type {Phaser.Renderer.WebGL.WebGLShader} + * @since 3.50.0 + */ + this.addShader; + /** + * A reference to the Linear Blend Shader belonging to this Utility Pipeline. + * + * This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#linearShader + * @type {Phaser.Renderer.WebGL.WebGLShader} + * @since 3.50.0 + */ + this.linearShader; -/***/ }), -/* 1001 */ -/***/ (function(module, exports) { + /** + * A reference to the Color Matrix Shader belonging to this Utility Pipeline. + * + * This property is set during the `boot` method. + * + * @name Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#colorMatrixShader + * @type {Phaser.Renderer.WebGL.WebGLShader} + * @since 3.50.0 + */ + this.colorMatrixShader; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * A reference to the Full Frame 1 Render Target. + * + * 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.UtilityPipeline#fullFrame1 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.50.0 + */ + this.fullFrame1; -/** - * The Sound Pause Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are paused. - * - * Listen to it from a Sound instance using `Sound.on('pause', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('pause', listener); - * music.play(); - * music.pause(); - * ``` - * - * @event Phaser.Sound.Events#PAUSE - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - */ -module.exports = 'pause'; + /** + * A reference to the Full Frame 2 Render Target. + * + * 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.UtilityPipeline#fullFrame2 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.50.0 + */ + this.fullFrame2; + /** + * A reference to the Half Frame 1 Render Target. + * + * 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.UtilityPipeline#halfFrame1 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.50.0 + */ + this.halfFrame1; -/***/ }), -/* 1002 */ -/***/ (function(module, exports) { + /** + * A reference to the Half Frame 2 Render Target. + * + * 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.UtilityPipeline#halfFrame2 + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.50.0 + */ + this.halfFrame2; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + boot: function () + { + WebGLPipeline.prototype.boot.call(this); -/** - * The Sound Play Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are played. - * - * Listen to it from a Sound instance using `Sound.on('play', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('play', listener); - * music.play(); - * ``` - * - * @event Phaser.Sound.Events#PLAY - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - */ -module.exports = 'play'; + var shaders = this.shaders; + var targets = this.renderTargets; + this.copyShader = shaders[0]; + this.addShader = shaders[1]; + this.linearShader = shaders[2]; + this.colorMatrixShader = shaders[3]; -/***/ }), -/* 1003 */ -/***/ (function(module, exports) { + this.fullFrame1 = targets[0]; + this.fullFrame2 = targets[1]; + this.halfFrame1 = targets[2]; + this.halfFrame2 = targets[3]; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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.UtilityPipeline#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) + { + if (brightness === undefined) { brightness = 1; } + if (clear === undefined) { clear = true; } + if (clearAlpha === undefined) { clearAlpha = true; } -/** - * The Sound Rate Change Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their rate changes. - * - * Listen to it from a Sound instance using `Sound.on('rate', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('rate', listener); - * music.play(); - * music.setRate(0.5); - * ``` - * - * @event Phaser.Sound.Events#RATE - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - * @param {number} rate - The new rate of the Sound. - */ -module.exports = 'rate'; + var gl = this.gl; + this.setShader(this.copyShader); -/***/ }), -/* 1004 */ -/***/ (function(module, exports) { + this.set1i('uMainSampler', 0); + this.set1f('uBrightness', brightness); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source.texture); -/** - * The Resume All Sounds Event. - * - * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, - * or the HTML5 Audio Manager. It is dispatched when the `resumeAll` method is invoked and after all current Sounds - * have been resumed. - * - * Listen to it from a Scene using: `this.sound.on('resumeall', listener)`. - * - * @event Phaser.Sound.Events#RESUME_ALL - * @since 3.0.0 - * - * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. - */ -module.exports = 'resumeall'; + 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); + } + else + { + gl.viewport(0, 0, source.width, source.height); + } + if (clear) + { + if (clearAlpha) + { + gl.clearColor(0, 0, 0, 0); + } + else + { + gl.clearColor(0, 0, 0, 1); + } -/***/ }), -/* 1005 */ -/***/ (function(module, exports) { + gl.clear(gl.COLOR_BUFFER_BIT); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); -/** - * The Sound Resume Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are resumed from a paused state. - * - * Listen to it from a Sound instance using `Sound.on('resume', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('resume', listener); - * music.play(); - * music.pause(); - * music.resume(); - * ``` - * - * @event Phaser.Sound.Events#RESUME - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - */ -module.exports = 'resume'; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.bindTexture(gl.TEXTURE_2D, null); + }, + /** + * 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.UtilityPipeline#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? + * @param {boolean} [flipY=false] - Flip the UV on the Y axis before drawing? + */ + blitFrame: function (source, target, brightness, clear, clearAlpha, eraseMode, flipY) + { + if (brightness === undefined) { brightness = 1; } + if (clear === undefined) { clear = true; } + if (clearAlpha === undefined) { clearAlpha = true; } + if (eraseMode === undefined) { eraseMode = false; } + if (flipY === undefined) { flipY = false; } -/***/ }), -/* 1006 */ -/***/ (function(module, exports) { + var gl = this.gl; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.setShader(this.copyShader); -/** - * The Sound Seek Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are seeked to a new position. - * - * Listen to it from a Sound instance using `Sound.on('seek', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('seek', listener); - * music.play(); - * music.setSeek(5000); - * ``` - * - * @event Phaser.Sound.Events#SEEK - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - * @param {number} detune - The new detune value of the Sound. - */ -module.exports = 'seek'; + this.set1i('uMainSampler', 0); + this.set1f('uBrightness', brightness); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source.texture); -/***/ }), -/* 1007 */ -/***/ (function(module, exports) { + if (source.height > target.height) + { + gl.viewport(0, 0, source.width, source.height); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.setTargetUVs(source, target); + } + else + { + var diff = target.height - source.height; -/** - * The Stop All Sounds Event. - * - * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, - * or the HTML5 Audio Manager. It is dispatched when the `stopAll` method is invoked and after all current Sounds - * have been stopped. - * - * Listen to it from a Scene using: `this.sound.on('stopall', listener)`. - * - * @event Phaser.Sound.Events#STOP_ALL - * @since 3.0.0 - * - * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. - */ -module.exports = 'stopall'; + gl.viewport(0, diff, source.width, source.height); + } + gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture, 0); -/***/ }), -/* 1008 */ -/***/ (function(module, exports) { + if (clear) + { + if (clearAlpha) + { + gl.clearColor(0, 0, 0, 0); + } + else + { + gl.clearColor(0, 0, 0, 1); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.clear(gl.COLOR_BUFFER_BIT); + } -/** - * The Sound Stop Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are stopped. - * - * Listen to it from a Sound instance using `Sound.on('stop', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('stop', listener); - * music.play(); - * music.stop(); - * ``` - * - * @event Phaser.Sound.Events#STOP - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - */ -module.exports = 'stop'; + if (eraseMode) + { + var blendMode = this.renderer.currentBlendMode; + this.renderer.setBlendMode(BlendModes.ERASE); + } -/***/ }), -/* 1009 */ -/***/ (function(module, exports) { + if (flipY) + { + this.flipY(); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); -/** - * The Sound Manager Unlocked Event. - * - * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, - * or the HTML5 Audio Manager. It is dispatched during the update loop when the Sound Manager becomes unlocked. For - * Web Audio this is on the first user gesture on the page. - * - * Listen to it from a Scene using: `this.sound.on('unlocked', listener)`. - * - * @event Phaser.Sound.Events#UNLOCKED - * @since 3.0.0 - * - * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. - */ -module.exports = 'unlocked'; + if (eraseMode) + { + this.renderer.setBlendMode(blendMode); + } + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.bindTexture(gl.TEXTURE_2D, null); -/***/ }), -/* 1010 */ -/***/ (function(module, exports) { + this.resetUVs(); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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.UtilityPipeline#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) + { + if (clear === undefined) { clear = true; } + if (clearAlpha === undefined) { clearAlpha = true; } -/** - * The Sound Volume Event. - * - * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their volume changes. - * - * Listen to it from a Sound instance using `Sound.on('volume', listener)`, i.e.: - * - * ```javascript - * var music = this.sound.add('key'); - * music.on('volume', listener); - * music.play(); - * music.setVolume(0.5); - * ``` - * - * @event Phaser.Sound.Events#VOLUME - * @since 3.0.0 - * - * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. - * @param {number} volume - The new volume of the Sound. - */ -module.exports = 'volume'; + var gl = this.gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, source.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, source.texture, 0); -/***/ }), -/* 1011 */ -/***/ (function(module, exports, __webpack_require__) { + if (clear) + { + if (clearAlpha) + { + gl.clearColor(0, 0, 0, 0); + } + else + { + gl.clearColor(0, 0, 0, 1); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.clear(gl.COLOR_BUFFER_BIT); + } -/** - * @namespace Phaser.GameObjects - */ + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, target.texture); -var GameObjects = { + gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, x, y, width, height); - Events: __webpack_require__(75), - - DisplayList: __webpack_require__(1012), - GameObjectCreator: __webpack_require__(16), - GameObjectFactory: __webpack_require__(5), - UpdateList: __webpack_require__(1040), - - Components: __webpack_require__(11), - GetCalcMatrix: __webpack_require__(19), - - BuildGameObject: __webpack_require__(28), - BuildGameObjectAnimation: __webpack_require__(439), - GameObject: __webpack_require__(15), - BitmapText: __webpack_require__(148), - Blitter: __webpack_require__(213), - Bob: __webpack_require__(440), - Container: __webpack_require__(214), - DOMElement: __webpack_require__(442), - DynamicBitmapText: __webpack_require__(215), - Extern: __webpack_require__(444), - Graphics: __webpack_require__(216), - Group: __webpack_require__(113), - Image: __webpack_require__(125), - Layer: __webpack_require__(219), - Particles: __webpack_require__(1074), - PathFollower: __webpack_require__(457), - RenderTexture: __webpack_require__(221), - RetroFont: __webpack_require__(1082), - Rope: __webpack_require__(223), - Sprite: __webpack_require__(73), - - Text: __webpack_require__(224), - GetTextSize: __webpack_require__(458), - MeasureText: __webpack_require__(460), - TextStyle: __webpack_require__(459), - - TileSprite: __webpack_require__(225), - Zone: __webpack_require__(129), - Video: __webpack_require__(226), + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.bindTexture(gl.TEXTURE_2D, null); + }, - // Shapes + /** + * 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.UtilityPipeline#copyToGame + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. + */ + copyToGame: function (source) + { + var gl = this.gl; - Shape: __webpack_require__(34), - Arc: __webpack_require__(461), - Curve: __webpack_require__(462), - Ellipse: __webpack_require__(463), - Grid: __webpack_require__(464), - IsoBox: __webpack_require__(465), - IsoTriangle: __webpack_require__(466), - Line: __webpack_require__(467), - Polygon: __webpack_require__(468), - Rectangle: __webpack_require__(473), - Star: __webpack_require__(474), - Triangle: __webpack_require__(475), + this.setShader(this.copyShader); - // Game Object Factories + this.set1i('uMainSampler', 0); + this.set1f('uBrightness', 1); - Factories: { - Blitter: __webpack_require__(1130), - Container: __webpack_require__(1131), - DOMElement: __webpack_require__(1132), - DynamicBitmapText: __webpack_require__(1133), - Extern: __webpack_require__(1134), - Graphics: __webpack_require__(1135), - Group: __webpack_require__(1136), - Image: __webpack_require__(1137), - Layer: __webpack_require__(1138), - Particles: __webpack_require__(1139), - PathFollower: __webpack_require__(1140), - RenderTexture: __webpack_require__(1141), - Rope: __webpack_require__(1142), - Sprite: __webpack_require__(1143), - StaticBitmapText: __webpack_require__(1144), - Text: __webpack_require__(1145), - TileSprite: __webpack_require__(1146), - Zone: __webpack_require__(1147), - Video: __webpack_require__(1148), + this.renderer.popFramebuffer(); - // Shapes - Arc: __webpack_require__(1149), - Curve: __webpack_require__(1150), - Ellipse: __webpack_require__(1151), - Grid: __webpack_require__(1152), - IsoBox: __webpack_require__(1153), - IsoTriangle: __webpack_require__(1154), - Line: __webpack_require__(1155), - Polygon: __webpack_require__(1156), - Rectangle: __webpack_require__(1157), - Star: __webpack_require__(1158), - Triangle: __webpack_require__(1159) + 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); }, - Creators: { - Blitter: __webpack_require__(1160), - Container: __webpack_require__(1161), - DynamicBitmapText: __webpack_require__(1162), - Graphics: __webpack_require__(1163), - Group: __webpack_require__(1164), - Image: __webpack_require__(1165), - Layer: __webpack_require__(1166), - Particles: __webpack_require__(1167), - RenderTexture: __webpack_require__(1168), - Rope: __webpack_require__(1169), - Sprite: __webpack_require__(1170), - StaticBitmapText: __webpack_require__(1171), - Text: __webpack_require__(1172), - TileSprite: __webpack_require__(1173), - Zone: __webpack_require__(1174), - Video: __webpack_require__(1175) - } + /** + * 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.UtilityPipeline#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? + * @param {Phaser.Display.ColorMatrix} [colorMatrix] - The Color Matrix to use when performing the draw. + */ + drawFrame: function (source, target, clearAlpha, colorMatrix) + { + if (clearAlpha === undefined) { clearAlpha = true; } + if (colorMatrix === undefined) { colorMatrix = this.colorMatrix; } -}; + var gl = this.gl; -// WebGL only Game Objects -if (true) -{ - GameObjects.Shader = __webpack_require__(229); - GameObjects.Mesh = __webpack_require__(230); - GameObjects.PointLight = __webpack_require__(150); + this.setShader(this.colorMatrixShader); - GameObjects.Factories.Shader = __webpack_require__(1184); - GameObjects.Factories.Mesh = __webpack_require__(1185); - GameObjects.Factories.PointLight = __webpack_require__(1186); + this.set1i('uMainSampler', 0); + this.set1fv('uColorMatrix', colorMatrix.getData()); + this.set1f('uAlpha', colorMatrix.alpha); - GameObjects.Creators.Shader = __webpack_require__(1187); - GameObjects.Creators.Mesh = __webpack_require__(1188); - GameObjects.Creators.PointLight = __webpack_require__(1189); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source.texture); - GameObjects.Light = __webpack_require__(481); - GameObjects.LightsManager = __webpack_require__(482); - GameObjects.LightsPlugin = __webpack_require__(1190); -} + 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); + } + else + { + gl.viewport(0, 0, source.width, source.height); + } -module.exports = GameObjects; + if (clearAlpha) + { + gl.clearColor(0, 0, 0, 0); + } + else + { + gl.clearColor(0, 0, 0, 1); + } + gl.clear(gl.COLOR_BUFFER_BIT); -/***/ }), -/* 1012 */ -/***/ (function(module, exports, __webpack_require__) { + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.bindTexture(gl.TEXTURE_2D, null); + }, -var Class = __webpack_require__(0); -var List = __webpack_require__(110); -var PluginCache = __webpack_require__(24); -var GameObjectEvents = __webpack_require__(75); -var SceneEvents = __webpack_require__(20); -var StableSort = __webpack_require__(79); + /** + * 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.UtilityPipeline#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? + * @param {Phaser.Renderer.WebGL.WebGLShader} [blendShader] - The shader to use during the blend copy. + */ + blendFrames: function (source1, source2, target, strength, clearAlpha, blendShader) + { + if (strength === undefined) { strength = 1; } + if (clearAlpha === undefined) { clearAlpha = true; } + if (blendShader === undefined) { blendShader = this.linearShader; } -/** - * @classdesc - * The Display List plugin. - * - * Display Lists belong to a Scene and maintain the list of Game Objects to render every frame. - * - * Some of these Game Objects may also be part of the Scene's [Update List]{@link Phaser.GameObjects.UpdateList}, for updating. - * - * @class DisplayList - * @extends Phaser.Structs.List. - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene that this Display List belongs to. - */ -var DisplayList = new Class({ + var gl = this.gl; - Extends: List, + this.setShader(blendShader); - initialize: + this.set1i('uMainSampler1', 0); + this.set1i('uMainSampler2', 1); + this.set1f('uStrength', strength); - function DisplayList (scene) - { - List.call(this, scene); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, source1.texture); - /** - * The flag the determines whether Game Objects should be sorted when `depthSort()` is called. - * - * @name Phaser.GameObjects.DisplayList#sortChildrenFlag - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.sortChildrenFlag = false; + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, source2.texture); - /** - * The Scene that this Display List belongs to. - * - * @name Phaser.GameObjects.DisplayList#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; + if (target) + { + gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture, 0); + gl.viewport(0, 0, target.width, target.height); + } + else + { + gl.viewport(0, 0, source1.width, source1.height); + } - /** - * The Scene's Systems. - * - * @name Phaser.GameObjects.DisplayList#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.systems = scene.sys; + if (clearAlpha) + { + gl.clearColor(0, 0, 0, 0); + } + else + { + gl.clearColor(0, 0, 0, 1); + } - /** - * The Scene's Event Emitter. - * - * @name Phaser.GameObjects.DisplayList#events - * @type {Phaser.Events.EventEmitter} - * @since 3.50.0 - */ - this.events = scene.sys.events; + gl.clear(gl.COLOR_BUFFER_BIT); - // Set the List callbacks - this.addCallback = this.addChildCallback; - this.removeCallback = this.removeChildCallback; + gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); + gl.drawArrays(gl.TRIANGLES, 0, 6); - this.events.once(SceneEvents.BOOT, this.boot, this); - this.events.on(SceneEvents.START, this.start, this); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.bindTexture(gl.TEXTURE_2D, null); }, /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. + * 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.GameObjects.DisplayList#boot - * @private - * @since 3.5.1 + * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#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? */ - boot: function () + blendFramesAdditive: function (source1, source2, target, strength, clearAlpha) { - this.events.once(SceneEvents.DESTROY, this.destroy, this); + this.blendFrames(source1, source2, target, strength, clearAlpha, this.addShader); }, /** - * Internal method called from `List.addCallback`. + * Clears the given Render Target. * - * @method Phaser.GameObjects.DisplayList#addChildCallback - * @private - * @fires Phaser.Scenes.Events#ADDED_TO_SCENE - * @fires Phaser.GameObjects.Events#ADDED_TO_SCENE + * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#clearFrame * @since 3.50.0 * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the list. + * @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? */ - addChildCallback: function (gameObject) + clearFrame: function (target, clearAlpha) { - if (gameObject.displayList && gameObject.displayList !== this) + if (clearAlpha === undefined) { clearAlpha = true; } + + var gl = this.gl; + + gl.viewport(0, 0, target.width, target.height); + + gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer); + + if (clearAlpha) { - gameObject.removeFromDisplayList(); + gl.clearColor(0, 0, 0, 0); } - - if (!gameObject.displayList) + else { - this.queueDepthSort(); + gl.clearColor(0, 0, 0, 1); + } - gameObject.displayList = this; + gl.clear(gl.COLOR_BUFFER_BIT); - gameObject.emit(GameObjectEvents.ADDED_TO_SCENE, gameObject, this.scene); + var fbo = this.renderer.currentFramebuffer; - this.events.emit(SceneEvents.ADDED_TO_SCENE, gameObject, this.scene); - } + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); }, /** - * Internal method called from `List.removeCallback`. + * Set the UV values for the 6 vertices that make up the quad used by the shaders + * in the Utility Pipeline. * - * @method Phaser.GameObjects.DisplayList#removeChildCallback - * @private - * @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE - * @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE + * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. + * + * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#setUVs * @since 3.50.0 * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the list. + * @param {number} uA - The u value of vertex A. + * @param {number} vA - The v value of vertex A. + * @param {number} uB - The u value of vertex B. + * @param {number} vB - The v value of vertex B. + * @param {number} uC - The u value of vertex C. + * @param {number} vC - The v value of vertex C. + * @param {number} uD - The u value of vertex D. + * @param {number} vD - The v value of vertex D. */ - removeChildCallback: function (gameObject) + setUVs: function (uA, vA, uB, vB, uC, vC, uD, vD) { - this.queueDepthSort(); - - gameObject.displayList = null; - - gameObject.emit(GameObjectEvents.REMOVED_FROM_SCENE, gameObject, this.scene); + var vertexViewF32 = this.vertexViewF32; - this.events.emit(SceneEvents.REMOVED_FROM_SCENE, gameObject, this.scene); + vertexViewF32[2] = uA; + vertexViewF32[3] = vA; + vertexViewF32[6] = uB; + vertexViewF32[7] = vB; + vertexViewF32[10] = uC; + vertexViewF32[11] = vC; + vertexViewF32[14] = uA; + vertexViewF32[15] = vA; + vertexViewF32[18] = uC; + vertexViewF32[19] = vC; + vertexViewF32[22] = uD; + vertexViewF32[23] = vD; }, /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. + * Sets the vertex UV coordinates of the quad used by the shaders in the Utility Pipeline + * so that they correctly adjust the texture coordinates for a blit frame effect. * - * @method Phaser.GameObjects.DisplayList#start - * @private - * @since 3.5.0 + * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. + * + * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#setTargetUVs + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target. + * @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target. */ - start: function () + setTargetUVs: function (source, target) { - this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); + var diff = (target.height / source.height); + + if (diff > 0.5) + { + diff = 0.5 - (diff - 0.5); + } + else + { + diff = 0.5 + (0.5 - diff); + } + + this.setUVs(0, diff, 0, 1 + diff, 1, 1 + diff, 1, diff); }, /** - * Force a sort of the display list on the next call to depthSort. + * Horizontally flips the UV coordinates of the quad used by the shaders in this + * Utility Pipeline. * - * @method Phaser.GameObjects.DisplayList#queueDepthSort - * @since 3.0.0 + * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. + * + * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#flipX + * @since 3.50.0 */ - queueDepthSort: function () + flipX: function () { - this.sortChildrenFlag = true; + this.setUVs(1, 0, 1, 1, 0, 1, 0, 0); }, /** - * Immediately sorts the display list if the flag is set. + * Vertically flips the UV coordinates of the quad used by the shaders in this + * Utility Pipeline. * - * @method Phaser.GameObjects.DisplayList#depthSort - * @since 3.0.0 + * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. + * + * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#flipY + * @since 3.50.0 */ - depthSort: function () + flipY: function () { - if (this.sortChildrenFlag) - { - StableSort(this.list, this.sortByDepth); - - this.sortChildrenFlag = false; - } + this.setUVs(0, 1, 0, 0, 1, 0, 1, 1); }, /** - * Compare the depth of two Game Objects. - * - * @method Phaser.GameObjects.DisplayList#sortByDepth - * @since 3.0.0 + * Resets the quad vertice UV values to their default settings. * - * @param {Phaser.GameObjects.GameObject} childA - The first Game Object. - * @param {Phaser.GameObjects.GameObject} childB - The second Game Object. + * The quad is used by all shaders of the Utility Pipeline. * - * @return {number} The difference between the depths of each Game Object. + * @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#resetUVs + * @since 3.50.0 */ - sortByDepth: function (childA, childB) + resetUVs: function () { - return childA._depth - childB._depth; - }, + this.setUVs(0, 0, 0, 1, 1, 1, 1, 0); + } + +}); + +module.exports = UtilityPipeline; + + +/***/ }), + +/***/ 65641: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var PIPELINE_CONST = { /** - * Returns an array which contains all objects currently on the Display List. - * This is a reference to the main list array, not a copy of it, so be careful not to modify it. - * - * @method Phaser.GameObjects.DisplayList#getChildren - * @since 3.12.0 + * The Bitmap Mask Pipeline. * - * @return {Phaser.GameObjects.GameObject[]} The group members. + * @name Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE + * @type {string} + * @const + * @since 3.50.0 */ - getChildren: function () - { - return this.list; - }, + BITMAPMASK_PIPELINE: 'BitmapMaskPipeline', /** - * The Scene that owns this plugin is shutting down. + * The Light 2D Pipeline. * - * We need to kill and reset all internal properties as well as stop listening to Scene events. + * @name Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + LIGHT_PIPELINE: 'Light2D', + + /** + * The Point Light Pipeline. * - * @method Phaser.GameObjects.DisplayList#shutdown - * @private - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINE + * @type {string} + * @const + * @since 3.50.0 */ - shutdown: function () - { - var list = this.list; + POINTLIGHT_PIPELINE: 'PointLightPipeline', - var i = list.length; + /** + * The Single Texture Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + SINGLE_PIPELINE: 'SinglePipeline', - while (i--) - { - list[i].destroy(true); - } + /** + * The Multi Texture Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + MULTI_PIPELINE: 'MultiPipeline', - list.length = 0; + /** + * The Rope Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + ROPE_PIPELINE: 'RopePipeline', - this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); - }, + /** + * The Graphics and Shapes Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.GRAPHICS_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + GRAPHICS_PIPELINE: 'GraphicsPipeline', /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. + * The Post FX Pipeline. * - * @method Phaser.GameObjects.DisplayList#destroy - * @private - * @since 3.0.0 + * @name Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE + * @type {string} + * @const + * @since 3.50.0 */ - destroy: function () - { - this.shutdown(); + POSTFX_PIPELINE: 'PostFXPipeline', - this.events.off(SceneEvents.START, this.start, this); + /** + * The Utility Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE + * @type {string} + * @const + * @since 3.50.0 + */ + UTILITY_PIPELINE: 'UtilityPipeline', - this.scene = null; - this.systems = null; - this.events = null; - } + /** + * The Mobile Texture Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.MOBILE_PIPELINE + * @type {string} + * @const + * @since 3.60.0 + */ + MOBILE_PIPELINE: 'MobilePipeline', -}); + /** + * The Special FX Pipeline. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX_PIPELINE + * @type {string} + * @const + * @since 3.60.0 + */ + FX_PIPELINE: 'FxPipeline' -PluginCache.register('DisplayList', DisplayList, 'displayList'); +}; -module.exports = DisplayList; +module.exports = PIPELINE_CONST; /***/ }), -/* 1013 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 68726: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Utils.Array.Matrix + * The WebGLPipeline After Flush Event. + * + * This event is dispatched by a WebGLPipeline right after it has issued a drawArrays command + * and cleared its vertex count. + * + * @event Phaser.Renderer.WebGL.Pipelines.Events#AFTER_FLUSH + * @since 3.50.0 + * + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that has flushed. + * @param {boolean} isPostFlush - Was this flush invoked as part of a post-process, or not? */ - -module.exports = { - - CheckMatrix: __webpack_require__(209), - MatrixToString: __webpack_require__(1014), - ReverseColumns: __webpack_require__(1015), - ReverseRows: __webpack_require__(1016), - Rotate180: __webpack_require__(1017), - RotateLeft: __webpack_require__(1018), - RotateMatrix: __webpack_require__(147), - RotateRight: __webpack_require__(1019), - Translate: __webpack_require__(1020), - TransposeMatrix: __webpack_require__(435) - -}; +module.exports = 'pipelineafterflush'; /***/ }), -/* 1014 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 67186: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Pad = __webpack_require__(186); -var CheckMatrix = __webpack_require__(209); - /** - * Generates a string (which you can pass to console.log) from the given Array Matrix. - * - * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) - * have the same length. There must be at least two rows. This is an example matrix: - * - * ``` - * [ - * [ 1, 1, 1, 1, 1, 1 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 2, 0, 1, 2, 0, 4 ], - * [ 2, 0, 3, 4, 0, 4 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 3, 3, 3, 3, 3, 3 ] - * ] - * ``` - * - * @function Phaser.Utils.Array.Matrix.MatrixToString - * @since 3.0.0 + * The WebGLPipeline Before Flush Event. * - * @generic T - * @genericUse {T[][]} - [matrix] + * This event is dispatched by a WebGLPipeline right before it is about to + * flush and issue a bufferData and drawArrays command. * - * @param {T[][]} [matrix] - A 2-dimensional array. + * @event Phaser.Renderer.WebGL.Pipelines.Events#BEFORE_FLUSH + * @since 3.50.0 * - * @return {string} A string representing the matrix. + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that is about to flush. + * @param {boolean} isPostFlush - Was this flush invoked as part of a post-process, or not? */ -var MatrixToString = function (matrix) -{ - var str = ''; - - if (!CheckMatrix(matrix)) - { - return str; - } - - for (var r = 0; r < matrix.length; r++) - { - for (var c = 0; c < matrix[r].length; c++) - { - var cell = matrix[r][c].toString(); - - if (cell !== 'undefined') - { - str += Pad(cell, 2); - } - else - { - str += '?'; - } - - if (c < matrix[r].length - 1) - { - str += ' |'; - } - } - - if (r < matrix.length - 1) - { - str += '\n'; - - for (var i = 0; i < matrix[r].length; i++) - { - str += '---'; - - if (i < matrix[r].length - 1) - { - str += '+'; - } - } - - str += '\n'; - } - - } - - return str; -}; - -module.exports = MatrixToString; +module.exports = 'pipelinebeforeflush'; /***/ }), -/* 1015 */ -/***/ (function(module, exports) { + +/***/ 22709: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Reverses the columns in the given Array Matrix. - * - * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) - * have the same length. There must be at least two rows. This is an example matrix: - * - * ``` - * [ - * [ 1, 1, 1, 1, 1, 1 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 2, 0, 1, 2, 0, 4 ], - * [ 2, 0, 3, 4, 0, 4 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 3, 3, 3, 3, 3, 3 ] - * ] - * ``` - * - * @function Phaser.Utils.Array.Matrix.ReverseColumns - * @since 3.0.0 + * The WebGLPipeline Bind Event. * - * @generic T - * @genericUse {T[][]} - [matrix,$return] + * This event is dispatched by a WebGLPipeline when it is bound by the Pipeline Manager. * - * @param {T[][]} [matrix] - The array matrix to reverse the columns for. + * @event Phaser.Renderer.WebGL.Pipelines.Events#BIND + * @since 3.50.0 * - * @return {T[][]} The column reversed matrix. + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that was bound. + * @param {Phaser.Renderer.WebGL.WebGLShader} currentShader - The shader that was set as being current. */ -var ReverseColumns = function (matrix) -{ - return matrix.reverse(); -}; - -module.exports = ReverseColumns; +module.exports = 'pipelinebind'; /***/ }), -/* 1016 */ -/***/ (function(module, exports) { + +/***/ 74469: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Reverses the rows in the given Array Matrix. - * - * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) - * have the same length. There must be at least two rows. This is an example matrix: - * - * ``` - * [ - * [ 1, 1, 1, 1, 1, 1 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 2, 0, 1, 2, 0, 4 ], - * [ 2, 0, 3, 4, 0, 4 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 3, 3, 3, 3, 3, 3 ] - * ] - * ``` - * - * @function Phaser.Utils.Array.Matrix.ReverseRows - * @since 3.0.0 + * The WebGLPipeline Boot Event. * - * @generic T - * @genericUse {T[][]} - [matrix,$return] + * This event is dispatched by a WebGLPipeline when it has completed its `boot` phase. * - * @param {T[][]} [matrix] - The array matrix to reverse the rows for. + * @event Phaser.Renderer.WebGL.Pipelines.Events#BOOT + * @since 3.50.0 * - * @return {T[][]} The column reversed matrix. + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that booted. */ -var ReverseRows = function (matrix) -{ - for (var i = 0; i < matrix.length; i++) - { - matrix[i].reverse(); - } - - return matrix; -}; - -module.exports = ReverseRows; +module.exports = 'pipelineboot'; /***/ }), -/* 1017 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 93953: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateMatrix = __webpack_require__(147); - /** - * Rotates the array matrix 180 degrees. + * The WebGLPipeline Destroy Event. * - * 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: + * This event is dispatched by a WebGLPipeline when it is starting its destroy process. * - * ``` - * [ - * [ 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 ] - * ] - * ``` + * @event Phaser.Renderer.WebGL.Pipelines.Events#DESTROY + * @since 3.50.0 * - * @function Phaser.Utils.Array.Matrix.Rotate180 - * @since 3.0.0 + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that has flushed. + */ +module.exports = 'pipelinedestroy'; + + +/***/ }), + +/***/ 51687: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The WebGLPipeline ReBind Event. * - * @generic T - * @genericUse {T[][]} - [matrix,$return] + * This event is dispatched by a WebGLPipeline when it is re-bound by the Pipeline Manager. * - * @param {T[][]} [matrix] - The array to rotate. + * @event Phaser.Renderer.WebGL.Pipelines.Events#REBIND + * @since 3.50.0 * - * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix. + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that was rebound. + * @param {Phaser.Renderer.WebGL.WebGLShader} currentShader - The shader that was set as being current. */ -var Rotate180 = function (matrix) -{ - return RotateMatrix(matrix, 180); -}; - -module.exports = Rotate180; +module.exports = 'pipelinerebind'; /***/ }), -/* 1018 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 25034: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateMatrix = __webpack_require__(147); - /** - * Rotates the array matrix to the left (or 90 degrees) - * - * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) - * have the same length. There must be at least two rows. This is an example matrix: - * - * ``` - * [ - * [ 1, 1, 1, 1, 1, 1 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 2, 0, 1, 2, 0, 4 ], - * [ 2, 0, 3, 4, 0, 4 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 3, 3, 3, 3, 3, 3 ] - * ] - * ``` - * - * @function Phaser.Utils.Array.Matrix.RotateLeft - * @since 3.0.0 + * The WebGLPipeline Resize Event. * - * @generic T - * @genericUse {T[][]} - [matrix,$return] + * This event is dispatched by a WebGLPipeline when it is resized, usually as a result + * of the Renderer resizing. * - * @param {T[][]} [matrix] - The array to rotate. + * @event Phaser.Renderer.WebGL.Pipelines.Events#RESIZE + * @since 3.50.0 * - * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix. + * @param {number} width - The new width of the pipeline. + * @param {number} height - The new height of the pipeline. + * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline that was resized. */ -var RotateLeft = function (matrix) -{ - return RotateMatrix(matrix, 90); -}; - -module.exports = RotateLeft; +module.exports = 'pipelineresize'; /***/ }), -/* 1019 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 18970: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateMatrix = __webpack_require__(147); - /** - * Rotates the array matrix to the left (or -90 degrees) - * - * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) - * have the same length. There must be at least two rows. This is an example matrix: - * - * ``` - * [ - * [ 1, 1, 1, 1, 1, 1 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 2, 0, 1, 2, 0, 4 ], - * [ 2, 0, 3, 4, 0, 4 ], - * [ 2, 0, 0, 0, 0, 4 ], - * [ 3, 3, 3, 3, 3, 3 ] - * ] - * ``` - * - * @function Phaser.Utils.Array.Matrix.RotateRight - * @since 3.0.0 - * - * @generic T - * @genericUse {T[][]} - [matrix,$return] - * - * @param {T[][]} [matrix] - The array to rotate. - * - * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix. + * @namespace Phaser.Renderer.WebGL.Pipelines.Events */ -var RotateRight = function (matrix) -{ - return RotateMatrix(matrix, -90); -}; -module.exports = RotateRight; +module.exports = { + + AFTER_FLUSH: __webpack_require__(68726), + BEFORE_FLUSH: __webpack_require__(67186), + BIND: __webpack_require__(22709), + BOOT: __webpack_require__(74469), + DESTROY: __webpack_require__(93953), + REBIND: __webpack_require__(51687), + RESIZE: __webpack_require__(25034) + +}; /***/ }), -/* 1020 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 32469: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateLeft = __webpack_require__(178); -var RotateRight = __webpack_require__(179); +var Class = __webpack_require__(56694); +var BarrelFrag = __webpack_require__(87751); +var PostFXPipeline = __webpack_require__(80486); /** - * Translates the given Array Matrix by shifting each column and row the - * amount specified. + * @classdesc + * The Barrel FX Pipeline. * - * 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: + * A barrel effect allows you to apply either a 'pinch' or 'expand' distortion to + * a Game Object. The amount of the effect can be modified in real-time. * - * ``` - * [ - * [ 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 ] - * ] - * ``` + * A Barrel effect is added to a Game Object via the FX component: * - * @function Phaser.Utils.Array.Matrix.Translate - * @since 3.50.0 + * ```js + * const sprite = this.add.sprite(); * - * @generic T - * @genericUse {T[][]} - [matrix,$return] + * sprite.postFX.addBarrel(); + * ``` * - * @param {T[][]} [matrix] - The array matrix to translate. - * @param {number} [x=0] - The amount to horizontally translate the matrix by. - * @param {number} [y=0] - The amount to vertically translate the matrix by. + * @class BarrelFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 * - * @return {T[][]} The translated matrix. + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var TranslateMatrix = function (matrix, x, y) -{ - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } +var BarrelFXPipeline = new Class({ - // Vertical translation + Extends: PostFXPipeline, - if (y !== 0) + initialize: + + function BarrelFXPipeline (game) { - if (y < 0) - { - // Shift Up - RotateLeft(matrix, Math.abs(y)); - } - else - { - // Shift Down - RotateRight(matrix, y); - } - } + PostFXPipeline.call(this, { + game: game, + fragShader: BarrelFrag + }); - // Horizontal translation + /** + * The amount of distortion applied to the barrel effect. + * + * Typically keep this within the range 1 (no distortion) to +- 1. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BarrelFXPipeline#amount + * @type {number} + * @since 3.60.0 + */ + this.amount = 1; + }, - if (x !== 0) + onPreRender: function (controller, shader) { - for (var i = 0; i < matrix.length; i++) - { - var row = matrix[i]; + controller = this.getController(controller); - if (x < 0) - { - RotateLeft(row, Math.abs(x)); - } - else - { - RotateRight(row, x); - } - } + this.set1f('amount', controller.amount, shader); } - return matrix; -}; +}); -module.exports = TranslateMatrix; +module.exports = BarrelFXPipeline; /***/ }), -/* 1021 */ -/***/ (function(module, exports) { + +/***/ 2134: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var BloomFrag = __webpack_require__(88222); +var PostFXPipeline = __webpack_require__(80486); + /** - * Adds the given item, or array of items, to the array. - * - * Each item must be unique within the array. + * @classdesc + * The Bloom FX Pipeline. * - * The array is modified in-place and returned. + * Bloom is an effect used to reproduce an imaging artifact of real-world cameras. + * The effect produces fringes of light extending from the borders of bright areas in an image, + * contributing to the illusion of an extremely bright light overwhelming the + * camera or eye capturing the scene. * - * You can optionally specify a limit to the maximum size of the array. If the quantity of items being - * added will take the array length over this limit, it will stop adding once the limit is reached. + * A Bloom effect is added to a Game Object via the FX component: * - * You can optionally specify a callback to be invoked for each item successfully added to the array. + * ```js + * const sprite = this.add.sprite(); * - * @function Phaser.Utils.Array.Add - * @since 3.4.0 + * sprite.postFX.addBloom(); + * ``` * - * @param {array} array - The array to be added to. - * @param {any|any[]} item - The item, or array of items, to add to the array. Each item must be unique within the array. - * @param {number} [limit] - Optional limit which caps the size of the array. - * @param {function} [callback] - A callback to be invoked for each item successfully added to the array. - * @param {object} [context] - The context in which the callback is invoked. + * @class BloomFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 * - * @return {array} The input array. + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var Add = function (array, item, limit, callback, context) -{ - if (context === undefined) { context = array; } +var BloomFXPipeline = new Class({ - if (limit > 0) - { - var remaining = limit - array.length; + Extends: PostFXPipeline, - // There's nothing more we can do here, the array is full - if (remaining <= 0) - { - return null; - } - } + initialize: - // Fast path to avoid array mutation and iteration - if (!Array.isArray(item)) + function BloomFXPipeline (game) { - if (array.indexOf(item) === -1) - { - array.push(item); - - if (callback) - { - callback.call(context, item); - } + PostFXPipeline.call(this, { + game: game, + fragShader: BloomFrag + }); - return item; - } - else - { - return null; - } - } + /** + * The number of steps to run the Bloom effect for. + * + * This value should always be an integer. + * + * It defaults to 4. The higher the value, the smoother the Bloom, + * but at the cost of exponentially more gl operations. + * + * Keep this to the lowest possible number you can have it, while + * still looking correct for your game. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BloomFXPipeline#steps + * @type {number} + * @since 3.60.0 + */ + this.steps = 4; - // If we got this far, we have an array of items to insert + /** + * The horizontal offset of the bloom effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BloomFXPipeline#offsetX + * @type {number} + * @since 3.60.0 + */ + this.offsetX = 1; - // Ensure all the items are unique - var itemLength = item.length - 1; + /** + * The vertical offset of the bloom effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BloomFXPipeline#offsetY + * @type {number} + * @since 3.60.0 + */ + this.offsetY = 1; - while (itemLength >= 0) - { - if (array.indexOf(item[itemLength]) !== -1) - { - // Already exists in array, so remove it - item.splice(itemLength, 1); - } + /** + * The strength of the blur process of the bloom effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BloomFXPipeline#blurStrength + * @type {number} + * @since 3.60.0 + */ + this.blurStrength = 1; - itemLength--; - } + /** + * The strength of the blend process of the bloom effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BloomFXPipeline#strength + * @type {number} + * @since 3.60.0 + */ + this.strength = 1; - // Anything left? - itemLength = item.length; + /** + * The internal gl color array. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BloomFXPipeline#glcolor + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor = [ 1, 1, 1 ]; + }, - if (itemLength === 0) + onPreRender: function (controller) { - return null; - } + controller = this.getController(controller); - if (limit > 0 && itemLength > remaining) + this.set1f('strength', controller.blurStrength); + this.set3fv('color', controller.glcolor); + }, + + onDraw: function (target1) { - item.splice(remaining); + var controller = this.getController(); - itemLength = remaining; - } + var target2 = this.fullFrame1; + var target3 = this.fullFrame2; - for (var i = 0; i < itemLength; i++) - { - var entry = item[i]; + this.copyFrame(target1, target3); - array.push(entry); + var x = (2 / target1.width) * controller.offsetX; + var y = (2 / target1.height) * controller.offsetY; - if (callback) + for (var i = 0; i < controller.steps; i++) { - callback.call(context, entry); + this.set2f('offset', x, 0); + this.copySprite(target1, target2); + + this.set2f('offset', 0, y); + this.copySprite(target2, target1); } + + this.blendFrames(target3, target1, target2, controller.strength); + + this.copyToGame(target2); } - return item; -}; +}); -module.exports = Add; +module.exports = BloomFXPipeline; /***/ }), -/* 1022 */ -/***/ (function(module, exports) { + +/***/ 63377: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var BlurLowFrag = __webpack_require__(35491); +var BlurMedFrag = __webpack_require__(75568); +var BlurHighFrag = __webpack_require__(44481); +var PostFXPipeline = __webpack_require__(80486); + /** - * Adds the given item, or array of items, to the array starting at the index specified. - * - * Each item must be unique within the array. - * - * Existing elements in the array are shifted up. - * - * The array is modified in-place and returned. - * - * You can optionally specify a limit to the maximum size of the array. If the quantity of items being - * added will take the array length over this limit, it will stop adding once the limit is reached. - * - * You can optionally specify a callback to be invoked for each item successfully added to the array. + * @classdesc + * The Blur FX Pipeline. * - * @function Phaser.Utils.Array.AddAt - * @since 3.4.0 + * A Gaussian blur is the result of blurring an image by a Gaussian function. It is a widely used effect, + * typically to reduce image noise and reduce detail. The visual effect of this blurring technique is a + * smooth blur resembling that of viewing the image through a translucent screen, distinctly different + * from the bokeh effect produced by an out-of-focus lens or the shadow of an object under usual illumination. * - * @param {array} array - The array to be added to. - * @param {any|any[]} item - The item, or array of items, to add to the array. - * @param {number} [index=0] - The index in the array where the item will be inserted. - * @param {number} [limit] - Optional limit which caps the size of the array. - * @param {function} [callback] - A callback to be invoked for each item successfully added to the array. - * @param {object} [context] - The context in which the callback is invoked. + * A Blur effect is added to a Game Object via the FX component: * - * @return {array} The input array. + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addBlur(); + * ``` + * + * @class BlurFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var AddAt = function (array, item, index, limit, callback, context) -{ - if (index === undefined) { index = 0; } - if (context === undefined) { context = array; } +var BlurFXPipeline = new Class({ - if (limit > 0) - { - var remaining = limit - array.length; + Extends: PostFXPipeline, - // There's nothing more we can do here, the array is full - if (remaining <= 0) - { - return null; - } - } + initialize: - // Fast path to avoid array mutation and iteration - if (!Array.isArray(item)) + function BlurFXPipeline (game) { - if (array.indexOf(item) === -1) - { - array.splice(index, 0, item); + PostFXPipeline.call(this, { + game: game, + shaders: [ + { + name: 'Gaussian5', + fragShader: BlurLowFrag + }, + { + name: 'Gaussian9', + fragShader: BlurMedFrag + }, + { + name: 'Gaussian13', + fragShader: BlurHighFrag + } + ] + }); - if (callback) - { - callback.call(context, item); - } + this.activeShader = this.shaders[0]; - return item; - } - else - { - return null; - } - } + /** + * The horizontal offset of the blur effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#x + * @type {number} + * @since 3.60.0 + */ + this.x = 2; - // If we got this far, we have an array of items to insert + /** + * The vertical offset of the blur effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#y + * @type {number} + * @since 3.60.0 + */ + this.y = 2; - // Ensure all the items are unique - var itemLength = item.length - 1; + /** + * The number of steps to run the Blur effect for. + * + * This value should always be an integer. + * + * It defaults to 4. The higher the value, the smoother the blur, + * but at the cost of exponentially more gl operations. + * + * Keep this to the lowest possible number you can have it, while + * still looking correct for your game. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#steps + * @type {number} + * @since 3.60.0 + */ + this.steps = 4; - while (itemLength >= 0) - { - if (array.indexOf(item[itemLength]) !== -1) - { - // Already exists in array, so remove it - item.pop(); - } + /** + * The strength of the blur effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#strength + * @type {number} + * @since 3.60.0 + */ + this.strength = 1; - itemLength--; - } + /** + * The internal gl color array. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#glcolor + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor = [ 1, 1, 1 ]; + }, - // Anything left? - itemLength = item.length; + /** + * Sets the quality of the blur effect to low. + * + * @method Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#setQualityLow + * @since 3.60.0 + * + * @return {this} This FX Pipeline. + */ + setQualityLow: function () + { + this.activeShader = this.shaders[0]; - if (itemLength === 0) + return this; + }, + + /** + * Sets the quality of the blur effect to medium. + * + * @method Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#setQualityMedium + * @since 3.60.0 + * + * @return {this} This FX Pipeline. + */ + setQualityMedium: function () { - return null; - } + this.activeShader = this.shaders[1]; - // Truncate to the limit - if (limit > 0 && itemLength > remaining) + return this; + }, + + /** + * Sets the quality of the blur effect to high. + * + * @method Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#setQualityHigh + * @since 3.60.0 + * + * @return {this} This FX Pipeline. + */ + setQualityHigh: function () { - item.splice(remaining); + this.activeShader = this.shaders[2]; - itemLength = remaining; - } + return this; + }, - for (var i = itemLength - 1; i >= 0; i--) + onDraw: function (target1) { - var entry = item[i]; + var controller = this.getController(); - array.splice(index, 0, entry); + var gl = this.gl; + var target2 = this.fullFrame1; - if (callback) - { - callback.call(context, entry); - } - } + var currentFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING); - return item; -}; + this.bind(this.activeShader); -module.exports = AddAt; + gl.activeTexture(gl.TEXTURE0); + gl.viewport(0, 0, target1.width, target1.height); + this.set1i('uMainSampler', 0); + this.set2f('resolution', target1.width, target1.height); + this.set1f('strength', controller.strength); + this.set3fv('color', controller.glcolor); -/***/ }), -/* 1023 */ -/***/ (function(module, exports) { + for (var i = 0; i < controller.steps; i++) + { + this.set2f('offset', controller.x, 0); + this.copySprite(target1, target2); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.set2f('offset', 0, controller.y); + this.copySprite(target2, target1); + } -/** - * Moves the given element to the top of the array. - * The array is modified in-place. - * - * @function Phaser.Utils.Array.BringToTop - * @since 3.4.0 - * - * @param {array} array - The array. - * @param {*} item - The element to move. - * - * @return {*} The element that was moved. - */ -var BringToTop = function (array, item) -{ - var currentIndex = array.indexOf(item); + gl.bindFramebuffer(gl.FRAMEBUFFER, currentFBO); + gl.bindTexture(gl.TEXTURE_2D, null); - if (currentIndex !== -1 && currentIndex < array.length) - { - array.splice(currentIndex, 1); - array.push(item); + this.copyToGame(target1); } - return item; -}; +}); -module.exports = BringToTop; +module.exports = BlurFXPipeline; /***/ }), -/* 1024 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 49745: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SafeRange = __webpack_require__(78); +var Class = __webpack_require__(56694); +var BokehFrag = __webpack_require__(69960); +var PostFXPipeline = __webpack_require__(80486); /** - * Returns the total number of elements in the array which have a property matching the given value. + * @classdesc + * The Bokeh FX Pipeline. * - * @function Phaser.Utils.Array.CountAllMatching - * @since 3.4.0 + * Bokeh refers to a visual effect that mimics the photographic technique of creating a shallow depth of field. + * This effect is used to emphasize the game's main subject or action, by blurring the background or foreground + * elements, resulting in a more immersive and visually appealing experience. It is achieved through rendering + * techniques that simulate the out-of-focus areas, giving a sense of depth and realism to the game's graphics. * - * @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] - An optional start index to search from. - * @param {number} [endIndex] - An optional end index to search to. + * This effect can also be used to generate a Tilt Shift effect, which is a technique used to create a miniature + * effect by blurring everything except a small area of the image. This effect is achieved by blurring the + * top and bottom elements, while keeping the center area in focus. * - * @return {number} The total number of elements with properties matching the given value. + * A Bokeh effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addBokeh(); + * ``` + * + * @class BokehFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var CountAllMatching = function (array, property, value, startIndex, endIndex) -{ - if (startIndex === undefined) { startIndex = 0; } - if (endIndex === undefined) { endIndex = array.length; } +var BokehFXPipeline = new Class({ - var total = 0; + Extends: PostFXPipeline, - if (SafeRange(array, startIndex, endIndex)) + initialize: + + function BokehFXPipeline (game) { - for (var i = startIndex; i < endIndex; i++) - { - var child = array[i]; + PostFXPipeline.call(this, { + game: game, + fragShader: BokehFrag + }); - if (child[property] === value) - { - total++; - } - } - } + /** + * Is this a Tilt Shift effect or a standard bokeh effect? + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BokehFXPipeline#isTiltShift + * @type {boolean} + * @since 3.60.0 + */ + this.isTiltShift = false; - return total; -}; + /** + * If a Tilt Shift effect this controls the strength of the blur. + * + * Setting this value on a non-Tilt Shift effect will have no effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BokehFXPipeline#strength + * @type {number} + * @since 3.60.0 + */ + this.strength = 1; -module.exports = CountAllMatching; + /** + * If a Tilt Shift effect this controls the amount of horizontal blur. + * + * Setting this value on a non-Tilt Shift effect will have no effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BokehFXPipeline#blurX + * @type {number} + * @since 3.60.0 + */ + this.blurX = 1; + /** + * If a Tilt Shift effect this controls the amount of vertical blur. + * + * Setting this value on a non-Tilt Shift effect will have no effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BokehFXPipeline#blurY + * @type {number} + * @since 3.60.0 + */ + this.blurY = 1; -/***/ }), -/* 1025 */ -/***/ (function(module, exports) { + /** + * The radius of the bokeh effect. + * + * This is a float value, where a radius of 0 will result in no effect being applied, + * and a radius of 1 will result in a strong bokeh. However, you can exceed this value + * for even stronger effects. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BokehFXPipeline#radius + * @type {number} + * @since 3.60.0 + */ + this.radius = 0.5; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The amount, or strength, of the bokeh effect. Defaults to 1. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BokehFXPipeline#amount + * @type {number} + * @since 3.60.0 + */ + this.amount = 1; -/** - * Passes each element in the array to the given callback. - * - * @function Phaser.Utils.Array.Each - * @since 3.4.0 - * - * @param {array} array - The array to search. - * @param {function} callback - A callback to be invoked for each item in the array. - * @param {object} context - The context in which the callback is invoked. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the current array item. - * - * @return {array} The input array. - */ -var Each = function (array, callback, context) -{ - var i; - var args = [ null ]; + /** + * The color contrast, or brightness, of the bokeh effect. Defaults to 0.2. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.BokehFXPipeline#contrast + * @type {number} + * @since 3.60.0 + */ + this.contrast = 0.2; + }, - for (i = 3; i < arguments.length; i++) + onPreRender: function (controller, shader, width, height) { - args.push(arguments[i]); - } + controller = this.getController(controller); - for (i = 0; i < array.length; i++) + this.set1f('radius', controller.radius, shader); + this.set1f('amount', controller.amount, shader); + this.set1f('contrast', controller.contrast, shader); + this.set1f('strength', controller.strength, shader); + this.set2f('blur', controller.blurX, controller.blurY, shader); + this.setBoolean('isTiltShift', controller.isTiltShift, shader); + + if (width && height) + { + this.set2f('resolution', width, height, shader); + } + }, + + onDraw: function (target) { - args[0] = array[i]; + this.set2f('resolution', target.width, target.height); - callback.apply(context, args); + this.bindAndDraw(target); } - return array; -}; +}); -module.exports = Each; +module.exports = BokehFXPipeline; /***/ }), -/* 1026 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 4323: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SafeRange = __webpack_require__(78); +var Class = __webpack_require__(56694); +var CircleFrag = __webpack_require__(33754); +var PostFXPipeline = __webpack_require__(80486); /** - * Passes each element in the array, between the start and end indexes, to the given callback. + * @classdesc + * The Circle FX Pipeline. * - * @function Phaser.Utils.Array.EachInRange - * @since 3.4.0 + * This effect will draw a circle around the texture of the Game Object, effectively masking off + * any area outside of the circle without the need for an actual mask. You can control the thickness + * of the circle, the color of the circle and the color of the background, should the texture be + * transparent. You can also control the feathering applied to the circle, allowing for a harsh or soft edge. * - * @param {array} array - The array to search. - * @param {function} callback - A callback to be invoked for each item in the array. - * @param {object} context - The context in which the callback is invoked. - * @param {number} startIndex - The start index to search from. - * @param {number} endIndex - The end index to search to. - * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + * Please note that adding this effect to a Game Object will not change the input area or physics body of + * the Game Object, should it have one. * - * @return {array} The input array. + * A Circle effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addCircle(); + * ``` + * + * @class CircleFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var EachInRange = function (array, callback, context, startIndex, endIndex) -{ - if (startIndex === undefined) { startIndex = 0; } - if (endIndex === undefined) { endIndex = array.length; } +var CircleFXPipeline = new Class({ - if (SafeRange(array, startIndex, endIndex)) - { - var i; - var args = [ null ]; + Extends: PostFXPipeline, - for (i = 5; i < arguments.length; i++) - { - args.push(arguments[i]); - } + initialize: - for (i = startIndex; i < endIndex; i++) - { - args[0] = array[i]; + function CircleFXPipeline (game) + { + PostFXPipeline.call(this, { + game: game, + fragShader: CircleFrag + }); - callback.apply(context, args); - } - } + /** + * The scale of the circle. The default scale is 1, which is a circle + * the full size of the underlying texture. Reduce this value to create + * a smaller circle, or increase it to create a circle that extends off + * the edges of the texture. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.CircleFXPipeline#scale + * @type {number} + * @since 3.60.0 + */ + this.scale = 1; - return array; -}; + /** + * The amount of feathering to apply to the circle from the ring, + * extending into the middle of the circle. The default is 0.005, + * which is a very low amount of feathering just making sure the ring + * has a smooth edge. Increase this amount to a value such as 0.5 + * or 0.025 for larger amounts of feathering. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.CircleFXPipeline#feather + * @type {number} + * @since 3.60.0 + */ + this.feather = 0.005; -module.exports = EachInRange; + /** + * The width of the circle around the texture, in pixels. This value + * doesn't factor in the feather, which can extend the thickness + * internally depending on its value. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.CircleFXPipeline#thickness + * @type {number} + * @since 3.60.0 + */ + this.thickness = 8; + /** + * The internal gl color array for the ring color. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.CircleFXPipeline#glcolor + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor = [ 1, 0.2, 0.7 ]; -/***/ }), -/* 1027 */ -/***/ (function(module, exports) { + /** + * The internal gl color array for the background color. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.CircleFXPipeline#glcolor2 + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor2 = [ 1, 0, 0, 0.4 ]; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + onPreRender: function (controller, shader, width, height) + { + controller = this.getController(controller); -/** - * Moves the given array element down one place in the array. - * The array is modified in-place. - * - * @function Phaser.Utils.Array.MoveDown - * @since 3.4.0 - * - * @param {array} array - The input array. - * @param {*} item - The element to move down the array. - * - * @return {array} The input array. - */ -var MoveDown = function (array, item) -{ - var currentIndex = array.indexOf(item); + this.set1f('scale', controller.scale, shader); + this.set1f('feather', controller.feather, shader); + this.set1f('thickness', controller.thickness, shader); + this.set3fv('color', controller.glcolor, shader); + this.set4fv('backgroundColor', controller.glcolor2, shader); - if (currentIndex > 0) - { - var item2 = array[currentIndex - 1]; + if (width && height) + { + this.set2f('resolution', width, height, shader); + } + }, - var index2 = array.indexOf(item2); + onDraw: function (target) + { + this.set2f('resolution', target.width, target.height); - array[currentIndex] = item2; - array[index2] = item; + this.bindAndDraw(target); } - return array; -}; +}); -module.exports = MoveDown; +module.exports = CircleFXPipeline; /***/ }), -/* 1028 */ -/***/ (function(module, exports) { + +/***/ 92066: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var PostFXPipeline = __webpack_require__(80486); + /** - * Moves an element in an array to a new position within the same array. - * The array is modified in-place. + * @classdesc + * The ColorMatrix FX Pipeline. * - * @function Phaser.Utils.Array.MoveTo - * @since 3.4.0 + * The color matrix effect is a visual technique that involves manipulating the colors of an image + * or scene using a mathematical matrix. This process can adjust hue, saturation, brightness, and contrast, + * allowing developers to create various stylistic appearances or mood settings within the game. + * Common applications include simulating different lighting conditions, applying color filters, + * or achieving a specific visual style. * - * @param {array} array - The array. - * @param {*} item - The element to move. - * @param {number} index - The new index that the element will be moved to. + * A ColorMatrix effect is added to a Game Object via the FX component: * - * @return {*} The element that was moved. + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addColorMatrix(); + * ``` + * + * @class ColorMatrixFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var MoveTo = function (array, item, index) -{ - var currentIndex = array.indexOf(item); +var ColorMatrixFXPipeline = new Class({ - if (currentIndex === -1 || index < 0 || index >= array.length) + Extends: PostFXPipeline, + + initialize: + + function ColorMatrixFXPipeline (game) { - throw new Error('Supplied index out of bounds'); - } + PostFXPipeline.call(this, { + game: game + }); + }, - if (currentIndex !== index) + onDraw: function (source) { - // Remove - array.splice(currentIndex, 1); + var target = this.fullFrame1; - // Add in new location - array.splice(index, 0, item); + if (this.controller) + { + this.manager.drawFrame(source, target, true, this.controller); + } + else + { + this.drawFrame(source, target); + } + + this.copyToGame(target); } - return item; -}; +}); -module.exports = MoveTo; +module.exports = ColorMatrixFXPipeline; /***/ }), -/* 1029 */ -/***/ (function(module, exports) { + +/***/ 89581: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var DisplacementFrag = __webpack_require__(35668); +var PostFXPipeline = __webpack_require__(80486); + /** - * Moves the given array element up one place in the array. - * The array is modified in-place. + * @classdesc + * The Displacement FX Pipeline. * - * @function Phaser.Utils.Array.MoveUp - * @since 3.4.0 + * The displacement effect is a visual technique that alters the position of pixels in an image + * or texture based on the values of a displacement map. This effect is used to create the illusion + * of depth, surface irregularities, or distortion in otherwise flat elements. It can be applied to + * characters, objects, or backgrounds to enhance realism, convey movement, or achieve various + * stylistic appearances. * - * @param {array} array - The input array. - * @param {*} item - The element to move up the array. + * A Displacement effect is added to a Game Object via the FX component: * - * @return {array} The input array. + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addDisplacement(); + * ``` + * + * @class DisplacementFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var MoveUp = function (array, item) -{ - var currentIndex = array.indexOf(item); +var DisplacementFXPipeline = new Class({ - if (currentIndex !== -1 && currentIndex < array.length - 1) - { - // The element one above `item` in the array - var item2 = array[currentIndex + 1]; - var index2 = array.indexOf(item2); + Extends: PostFXPipeline, - array[currentIndex] = item2; - array[index2] = item; - } + initialize: - return array; -}; + function DisplacementFXPipeline (game) + { + PostFXPipeline.call(this, { + game: game, + fragShader: DisplacementFrag + }); -module.exports = MoveUp; + /** + * The amount of horizontal displacement to apply. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.DisplacementFXPipeline#x + * @type {number} + * @since 3.60.0 + */ + this.x = 0.005; + /** + * The amount of vertical displacement to apply. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.DisplacementFXPipeline#y + * @type {number} + * @since 3.60.0 + */ + this.y = 0.005; -/***/ }), -/* 1030 */ -/***/ (function(module, exports) { + /** + * The underlying WebGLTexture used for displacement. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.DisplacementFXPipeline#glTexture + * @type {WebGLTexture} + * @since 3.60.0 + */ + this.glTexture; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + onBoot: function () + { + this.setTexture('__WHITE'); + }, -/** - * Moves the given array element above another one in the array. - * The array is modified in-place. - * - * @function Phaser.Utils.Array.MoveAbove - * @since 3.55.0 - * - * @param {array} array - The input array. - * @param {*} item1 - The element to move above base element. - * @param {*} item2 - The base element. - * - * - * @return {array} The input array. - */ -var MoveAbove = function (array, item1, item2) -{ - if (item1 === item2) + setTexture: function (texture) { - return array; - } + var phaserTexture = this.game.textures.getFrame(texture); - var currentIndex = array.indexOf(item1); - var baseIndex = array.indexOf(item2); + if (phaserTexture) + { + this.glTexture = phaserTexture.glTexture; + } + }, - if (currentIndex < 0 || baseIndex < 0) + onDraw: function (source) { - throw new Error('Supplied items must be elements of the same array'); - } + var controller = this.getController(); - if (currentIndex > baseIndex) - { - // item1 is already above item2 - return array; - } + var target = this.fullFrame1; - // Remove - array.splice(currentIndex, 1); + this.bind(); - // Add in new location - if (baseIndex === array.length - 1) - { - array.push(item1); - } - else - { - array.splice(baseIndex, 0, item1); + this.set1i('uMainSampler', 0); + this.set1i('uDisplacementSampler', 1); + this.set2f('amount', controller.x, controller.y); + + this.bindTexture(controller.glTexture, 1); + + this.copySprite(source, target); + + this.copyToGame(target); } - return array; -}; +}); -module.exports = MoveAbove; +module.exports = DisplacementFXPipeline; /***/ }), -/* 1031 */ -/***/ (function(module, exports) { + +/***/ 55084: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); +var GlowFrag = __webpack_require__(69675); +var PostFXPipeline = __webpack_require__(80486); +var Utils = __webpack_require__(75512); + /** - * Moves the given array element below another one in the array. - * The array is modified in-place. + * @classdesc + * The Glow FX Pipeline. * - * @function Phaser.Utils.Array.MoveBelow - * @since 3.55.0 + * The glow effect is a visual technique that creates a soft, luminous halo around game objects, + * characters, or UI elements. This effect is used to emphasize importance, enhance visual appeal, + * or convey a sense of energy, magic, or otherworldly presence. The effect can also be set on + * the inside of the Game Object. The color and strength of the glow can be modified. * - * @param {array} array - The input array. - * @param {*} item1 - The element to move below base element. - * @param {*} item2 - The base element. - * + * A Glow effect is added to a Game Object via the FX component: * - * @return {array} The input array. + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addGlow(); + * ``` + * + * @class GlowFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. + * @param {object} config - The configuration options for this pipeline. */ -var MoveBelow = function (array, item1, item2) -{ - if (item1 === item2) - { - return array; - } +var GlowFXPipeline = new Class({ - var currentIndex = array.indexOf(item1); - var baseIndex = array.indexOf(item2); + Extends: PostFXPipeline, - if (currentIndex < 0 || baseIndex < 0) - { - throw new Error('Supplied items must be elements of the same array'); - } + initialize: - if (currentIndex < baseIndex) + function GlowFXPipeline (game, config) { - // item1 is already below item2 - return array; - } + var quality = GetFastValue(config, 'quality', 0.1); + var distance = GetFastValue(config, 'distance', 10); - // Remove - array.splice(currentIndex, 1); + PostFXPipeline.call(this, { + game: game, + fragShader: Utils.setGlowQuality(GlowFrag, game, quality, distance) + }); - // Add in new location - if (baseIndex === 0) + /** + * The strength of the glow outward from the edge of the Sprite. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GlowFXPipeline#outerStrength + * @type {number} + * @since 3.60.0 + */ + this.outerStrength = 4; + + /** + * The strength of the glow inward from the edge of the Sprite. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GlowFXPipeline#innerStrength + * @type {number} + * @since 3.60.0 + */ + this.innerStrength = 0; + + /** + * If `true` only the glow is drawn, not the texture itself. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GlowFXPipeline#knockout + * @type {number} + * @since 3.60.0 + */ + this.knockout = false; + + /** + * A 4 element array of gl color values. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GlowFXPipeline#glcolor + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor = [ 1, 1, 1, 1 ]; + }, + + onPreRender: function (controller, shader, width, height) { - array.unshift(item1); - } - else + controller = this.getController(controller); + + this.set1f('outerStrength', controller.outerStrength, shader); + this.set1f('innerStrength', controller.innerStrength, shader); + this.set4fv('glowColor', controller.glcolor, shader); + this.setBoolean('knockout', controller.knockout, shader); + + if (width && height) + { + this.set2f('resolution', width, height, shader); + } + }, + + onDraw: function (target) { - array.splice(baseIndex, 0, item1); + this.set2f('resolution', target.width, target.height); + + this.bindAndDraw(target); } - return array; -}; +}); -module.exports = MoveBelow; +module.exports = GlowFXPipeline; /***/ }), -/* 1032 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 41653: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RoundAwayFromZero = __webpack_require__(363); +var Class = __webpack_require__(56694); +var GradientFrag = __webpack_require__(90993); +var PostFXPipeline = __webpack_require__(80486); /** - * Create an array of numbers (positive and/or negative) progressing from `start` - * up to but not including `end` by advancing by `step`. - * - * If `start` is less than `end` a zero-length range is created unless a negative `step` is specified. - * - * Certain values for `start` and `end` (eg. NaN/undefined/null) are currently coerced to 0; - * for forward compatibility make sure to pass in actual numbers. - * - * @example - * NumberArrayStep(4); - * // => [0, 1, 2, 3] - * - * NumberArrayStep(1, 5); - * // => [1, 2, 3, 4] - * - * NumberArrayStep(0, 20, 5); - * // => [0, 5, 10, 15] + * @classdesc + * The Gradient FX Pipeline. * - * NumberArrayStep(0, -4, -1); - * // => [0, -1, -2, -3] + * The gradient overlay effect is a visual technique where a smooth color transition is applied over Game Objects, + * such as sprites or UI components. This effect is used to enhance visual appeal, emphasize depth, or create + * stylistic and atmospheric variations. It can also be utilized to convey information, such as representing + * progress or health status through color changes. * - * NumberArrayStep(1, 4, 0); - * // => [1, 1, 1] + * A Gradient effect is added to a Game Object via the FX component: * - * NumberArrayStep(0); - * // => [] + * ```js + * const sprite = this.add.sprite(); * - * @function Phaser.Utils.Array.NumberArrayStep - * @since 3.0.0 + * sprite.postFX.addGradient(); + * ``` * - * @param {number} [start=0] - The start of the range. - * @param {number} [end=null] - The end of the range. - * @param {number} [step=1] - The value to increment or decrement by. + * @class GradientFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 * - * @return {number[]} The array of number values. + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var NumberArrayStep = function (start, end, step) -{ - if (start === undefined) { start = 0; } - if (end === undefined) { end = null; } - if (step === undefined) { step = 1; } - - if (end === null) - { - end = start; - start = 0; - } +var GradientFXPipeline = new Class({ - var result = []; + Extends: PostFXPipeline, - var total = Math.max(RoundAwayFromZero((end - start) / (step || 1)), 0); + initialize: - for (var i = 0; i < total; i++) + function GradientFXPipeline (game) { - result.push(start); - start += step; - } - - return result; -}; + PostFXPipeline.call(this, { + game: game, + fragShader: GradientFrag + }); -module.exports = NumberArrayStep; + /** + * The alpha value of the gradient effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline#alpha + * @type {number} + * @since 3.60.0 + */ + this.alpha = 0.2; + /** + * Sets how many 'chunks' the gradient is divided in to, as spread over the + * entire height of the texture. Leave this at zero for a smooth gradient, + * or set to a higher number to split the gradient into that many sections, giving + * a more banded 'retro' effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline#size + * @type {number} + * @since 3.60.0 + */ + this.size = 0; -/***/ }), -/* 1033 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The horizontal position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline#fromX + * @type {number} + * @since 3.60.0 + */ + this.fromX = 0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The vertical position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline#fromY + * @type {number} + * @since 3.60.0 + */ + this.fromY = 0; -var SpliceOne = __webpack_require__(74); + /** + * The horizontal position the gradient will end. This value is noralized, between 0 and 1 and is not in pixels. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline#toX + * @type {number} + * @since 3.60.0 + */ + this.toX = 0; -/** - * Removes the item from the given position in the array. - * - * The array is modified in-place. - * - * You can optionally specify a callback to be invoked for the item if it is successfully removed from the array. - * - * @function Phaser.Utils.Array.RemoveAt - * @since 3.4.0 - * - * @param {array} array - The array to be modified. - * @param {number} index - The array index to remove the item from. The index must be in bounds or it will throw an error. - * @param {function} [callback] - A callback to be invoked for the item removed from the array. - * @param {object} [context] - The context in which the callback is invoked. - * - * @return {*} The item that was removed. - */ -var RemoveAt = function (array, index, callback, context) -{ - if (context === undefined) { context = array; } + /** + * The vertical position the gradient will end. This value is noralized, between 0 and 1 and is not in pixels. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline#toY + * @type {number} + * @since 3.60.0 + */ + this.toY = 1; - if (index < 0 || index > array.length - 1) - { - throw new Error('Index out of bounds'); - } + /** + * The internal gl color array for the starting color. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline#glcolor1 + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor1 = [ 255, 0, 0 ]; - var item = SpliceOne(array, index); + /** + * The internal gl color array for the ending color. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline#glcolor2 + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor2 = [ 0, 255, 0 ]; + }, - if (callback) + onPreRender: function (controller, shader) { - callback.call(context, item); + controller = this.getController(controller); + + this.set1f('alpha', controller.alpha, shader); + this.set1i('size', controller.size, shader); + this.set3fv('color1', controller.glcolor1, shader); + this.set3fv('color2', controller.glcolor2, shader); + this.set2f('positionFrom', controller.fromX, controller.fromY, shader); + this.set2f('positionTo', controller.toX, controller.toY, shader); } - return item; -}; +}); -module.exports = RemoveAt; +module.exports = GradientFXPipeline; /***/ }), -/* 1034 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 73416: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SafeRange = __webpack_require__(78); +var Class = __webpack_require__(56694); +var PixelateFrag = __webpack_require__(37945); +var PostFXPipeline = __webpack_require__(80486); /** - * Removes the item within the given range in the array. - * - * The array is modified in-place. - * - * You can optionally specify a callback to be invoked for the item/s successfully removed from the array. + * @classdesc + * The Pixelate FX Pipeline. * - * @function Phaser.Utils.Array.RemoveBetween - * @since 3.4.0 + * The pixelate effect is a visual technique that deliberately reduces the resolution or detail of an image, + * creating a blocky or mosaic appearance composed of large, visible pixels. This effect can be used for stylistic + * purposes, as a homage to retro gaming, or as a means to obscure certain elements within the game, such as + * during a transition or to censor specific content. * - * @param {array} array - The array to be modified. - * @param {number} startIndex - The start index to remove from. - * @param {number} endIndex - The end index to remove to. - * @param {function} [callback] - A callback to be invoked for the item removed from the array. - * @param {object} [context] - The context in which the callback is invoked. + * A Pixelate effect is added to a Game Object via the FX component: * - * @return {Array.<*>} An array of items that were removed. + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addPixelate(); + * ``` + * + * @class PixelateFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var RemoveBetween = function (array, startIndex, endIndex, callback, context) -{ - if (startIndex === undefined) { startIndex = 0; } - if (endIndex === undefined) { endIndex = array.length; } - if (context === undefined) { context = array; } +var PixelateFXPipeline = new Class({ - if (SafeRange(array, startIndex, endIndex)) + Extends: PostFXPipeline, + + initialize: + + function PixelateFXPipeline (game) { - var size = endIndex - startIndex; + PostFXPipeline.call(this, { + game: game, + fragShader: PixelateFrag + }); - var removed = array.splice(startIndex, size); + /** + * The amount of pixelation to apply. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.PixelateFXPipeline#amount + * @type {number} + * @since 3.60.0 + */ + this.amount = 1; + }, - if (callback) - { - for (var i = 0; i < removed.length; i++) - { - var entry = removed[i]; + onPreRender: function (controller, shader, width, height) + { + controller = this.getController(controller); - callback.call(context, entry); - } + this.set1f('amount', controller.amount, shader); + + if (width && height) + { + this.set2f('resolution', width, height, shader); } + }, - return removed; - } - else + onDraw: function (target) { - return []; + this.set2f('resolution', target.width, target.height); + + this.bindAndDraw(target); } -}; -module.exports = RemoveBetween; +}); + +module.exports = PixelateFXPipeline; /***/ }), -/* 1035 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 58049: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SpliceOne = __webpack_require__(74); +var Class = __webpack_require__(56694); +var ShadowFrag = __webpack_require__(85718); +var PostFXPipeline = __webpack_require__(80486); /** - * Removes a random object from the given array and returns it. - * Will return null if there are no array items that fall within the specified range or if there is no item for the randomly chosen index. + * @classdesc + * The Shadow FX Pipeline. * - * @function Phaser.Utils.Array.RemoveRandomElement - * @since 3.0.0 + * The shadow effect is a visual technique used to create the illusion of depth and realism by adding darker, + * offset silhouettes or shapes beneath game objects, characters, or environments. These simulated shadows + * help to enhance the visual appeal and immersion, making the 2D game world appear more dynamic and three-dimensional. * - * @param {array} array - The array to removed a random element from. - * @param {number} [start=0] - The array index to start the search from. - * @param {number} [length=array.length] - Optional restriction on the number of elements to randomly select from. + * A Shadow effect is added to a Game Object via the FX component: * - * @return {object} The random element that was removed, or `null` if there were no array elements that fell within the given range. - */ -var RemoveRandomElement = function (array, start, length) -{ - if (start === undefined) { start = 0; } - if (length === undefined) { length = array.length; } - - var randomIndex = start + Math.floor(Math.random() * length); - - return SpliceOne(array, randomIndex); -}; - -module.exports = RemoveRandomElement; - - -/***/ }), -/* 1036 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Replaces an element of the array with the new element. - * The new element cannot already be a member of the array. - * The array is modified in-place. + * ```js + * const sprite = this.add.sprite(); * - * @function Phaser.Utils.Array.Replace - * @since 3.4.0 + * sprite.postFX.addShadow(); + * ``` * - * @param {array} array - The array to search within. - * @param {*} oldChild - The element in the array that will be replaced. - * @param {*} newChild - The element to be inserted into the array at the position of `oldChild`. + * @class ShadowFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 * - * @return {boolean} Returns true if the oldChild was successfully replaced, otherwise returns false. + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var Replace = function (array, oldChild, newChild) -{ - var index1 = array.indexOf(oldChild); - var index2 = array.indexOf(newChild); +var ShadowFXPipeline = new Class({ - if (index1 !== -1 && index2 === -1) - { - array[index1] = newChild; + Extends: PostFXPipeline, - return true; - } - else + initialize: + + function ShadowFXPipeline (game) { - return false; - } -}; + PostFXPipeline.call(this, { + game: game, + fragShader: ShadowFrag + }); -module.exports = Replace; + /** + * The horizontal offset of the shadow effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShadowFXPipeline#x + * @type {number} + * @since 3.60.0 + */ + this.x = 0; + /** + * The vertical offset of the shadow effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShadowFXPipeline#y + * @type {number} + * @since 3.60.0 + */ + this.y = 0; -/***/ }), -/* 1037 */ -/***/ (function(module, exports) { + /** + * The amount of decay for the shadow effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShadowFXPipeline#decay + * @type {number} + * @since 3.60.0 + */ + this.decay = 0.1; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The power of the shadow effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShadowFXPipeline#power + * @type {number} + * @since 3.60.0 + */ + this.power = 1; -/** - * Moves the given element to the bottom of the array. - * The array is modified in-place. - * - * @function Phaser.Utils.Array.SendToBack - * @since 3.4.0 - * - * @param {array} array - The array. - * @param {*} item - The element to move. - * - * @return {*} The element that was moved. - */ -var SendToBack = function (array, item) -{ - var currentIndex = array.indexOf(item); + /** + * The internal gl color array. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShadowFXPipeline#glcolor + * @type {number[]} + * @since 3.60.0 + */ + this.glcolor = [ 0, 0, 0, 1 ]; - if (currentIndex !== -1 && currentIndex > 0) + /** + * The number of samples that the shadow effect will run for. + * + * This should be an integer with a minimum value of 1 and a maximum of 12. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShadowFXPipeline#samples + * @type {number} + * @since 3.60.0 + */ + this.samples = 6; + + /** + * The intensity of the shadow effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShadowFXPipeline#intensity + * @type {number} + * @since 3.60.0 + */ + this.intensity = 1; + }, + + onPreRender: function (controller, shader) { - array.splice(currentIndex, 1); - array.unshift(item); + controller = this.getController(controller); + + var samples = controller.samples; + + this.set1i('samples', samples, shader); + this.set1f('intensity', controller.intensity, shader); + this.set1f('decay', controller.decay, shader); + this.set1f('power', (controller.power / samples), shader); + this.set2f('lightPosition', controller.x, controller.y, shader); + this.set4fv('color', controller.glcolor, shader); } - return item; -}; +}); -module.exports = SendToBack; +module.exports = ShadowFXPipeline; /***/ }), -/* 1038 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 18026: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SafeRange = __webpack_require__(78); +var Class = __webpack_require__(56694); +var ShineFrag = __webpack_require__(13740); +var PostFXPipeline = __webpack_require__(80486); /** - * Scans the array for elements with the given property. If found, the property is set to the `value`. + * @classdesc + * The Shine FX Pipeline. * - * For example: `SetAll('visible', true)` would set all elements that have a `visible` property to `false`. + * The shine effect is a visual technique that simulates the appearance of reflective + * or glossy surfaces by passing a light beam across a Game Object. This effect is used to + * enhance visual appeal, emphasize certain features, and create a sense of depth or + * material properties. * - * Optionally you can specify a start and end index. For example if the array had 100 elements, - * and you set `startIndex` to 0 and `endIndex` to 50, it would update only the first 50 elements. + * A Shine effect is added to a Game Object via the FX component: * - * @function Phaser.Utils.Array.SetAll - * @since 3.4.0 + * ```js + * const sprite = this.add.sprite(); * - * @param {array} array - The array to search. - * @param {string} property - The property to test for on each array element. - * @param {*} value - The value to set the property to. - * @param {number} [startIndex] - An optional start index to search from. - * @param {number} [endIndex] - An optional end index to search to. + * sprite.postFX.addShine(); + * ``` * - * @return {array} The input array. + * @class ShineFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var SetAll = function (array, property, value, startIndex, endIndex) -{ - if (startIndex === undefined) { startIndex = 0; } - if (endIndex === undefined) { endIndex = array.length; } +var ShineFXPipeline = new Class({ - if (SafeRange(array, startIndex, endIndex)) - { - for (var i = startIndex; i < endIndex; i++) - { - var entry = array[i]; + Extends: PostFXPipeline, - if (entry.hasOwnProperty(property)) - { - entry[property] = value; - } - } - } + initialize: - return array; -}; + function ShineFXPipeline (game) + { + PostFXPipeline.call(this, { + game: game, + fragShader: ShineFrag + }); -module.exports = SetAll; + /** + * The speed of the Shine effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShineFXPipeline#speed + * @type {number} + * @since 3.60.0 + */ + this.speed = 0.5; + /** + * The line width of the Shine effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShineFXPipeline#lineWidth + * @type {number} + * @since 3.60.0 + */ + this.lineWidth = 0.5; -/***/ }), -/* 1039 */ -/***/ (function(module, exports) { + /** + * The gradient of the Shine effect. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShineFXPipeline#gradient + * @type {number} + * @since 3.60.0 + */ + this.gradient = 3; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Does this Shine effect reveal or get added to its target? + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.ShineFXPipeline#reveal + * @type {boolean} + * @since 3.60.0 + */ + this.reveal = false; + }, -/** - * Swaps the position of two elements in the given array. - * The elements must exist in the same array. - * The array is modified in-place. - * - * @function Phaser.Utils.Array.Swap - * @since 3.4.0 - * - * @param {array} array - The input array. - * @param {*} item1 - The first element to swap. - * @param {*} item2 - The second element to swap. - * - * @return {array} The input array. - */ -var Swap = function (array, item1, item2) -{ - if (item1 === item2) + onPreRender: function (controller, shader, width, height) { - return array; - } + controller = this.getController(controller); - var index1 = array.indexOf(item1); - var index2 = array.indexOf(item2); + this.setTime('time', shader); - if (index1 < 0 || index2 < 0) + this.set1f('speed', controller.speed, shader); + this.set1f('lineWidth', controller.lineWidth, shader); + this.set1f('gradient', controller.gradient, shader); + this.setBoolean('reveal', controller.reveal, shader); + + if (width && height) + { + this.set2f('resolution', width, height, shader); + } + }, + + onDraw: function (target) { - throw new Error('Supplied items must be elements of the same array'); - } + this.set2f('resolution', target.width, target.height); - array[index1] = item2; - array[index2] = item1; + this.bindAndDraw(target); + } - return array; -}; +}); -module.exports = Swap; +module.exports = ShineFXPipeline; /***/ }), -/* 1040 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72381: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var ProcessQueue = __webpack_require__(211); -var PluginCache = __webpack_require__(24); -var SceneEvents = __webpack_require__(20); +var Class = __webpack_require__(56694); +var VignetteFrag = __webpack_require__(80617); +var PostFXPipeline = __webpack_require__(80486); /** * @classdesc - * The Update List plugin. + * The Vignette FX Pipeline. * - * Update Lists belong to a Scene and maintain the list Game Objects to be updated every frame. + * The vignette effect is a visual technique where the edges of the screen, or a Game Object, gradually darken or blur, + * creating a frame-like appearance. This effect is used to draw the player's focus towards the central action or subject, + * enhance immersion, and provide a cinematic or artistic quality to the game's visuals. * - * Some or all of these Game Objects may also be part of the Scene's [Display List]{@link Phaser.GameObjects.DisplayList}, for Rendering. + * A Vignette effect is added to a Game Object via the FX component: * - * @class UpdateList - * @extends Phaser.Structs.ProcessQueue. - * @memberof Phaser.GameObjects + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addVignette(); + * ``` + * + * @class VignetteFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX * @constructor - * @since 3.0.0 + * @since 3.60.0 * - * @param {Phaser.Scene} scene - The Scene that the Update List belongs to. + * @param {Phaser.Game} game - A reference to the Phaser Game instance. */ -var UpdateList = new Class({ +var VignetteFXPipeline = new Class({ - Extends: ProcessQueue, + Extends: PostFXPipeline, initialize: - function UpdateList (scene) + function VignetteFXPipeline (game) { - ProcessQueue.call(this); - - // No duplicates in this list - this.checkQueue = true; - - /** - * The Scene that the Update List belongs to. - * - * @name Phaser.GameObjects.UpdateList#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; - - /** - * The Scene's Systems. - * - * @name Phaser.GameObjects.UpdateList#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.systems = scene.sys; + PostFXPipeline.call(this, { + game: game, + fragShader: VignetteFrag + }); /** - * The `pending` list is a selection of items which are due to be made 'active' in the next update. + * The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1. * - * @name Phaser.GameObjects.UpdateList#_pending - * @type {Array.<*>} - * @private - * @default [] - * @since 3.20.0 + * @name Phaser.Renderer.WebGL.Pipelines.FX.VignetteFXPipeline#x + * @type {number} + * @since 3.60.0 */ + this.x = 0.5; /** - * The `active` list is a selection of items which are considered active and should be updated. + * The vertical offset of the vignette effect. This value is normalized to the range 0 to 1. * - * @name Phaser.GameObjects.UpdateList#_active - * @type {Array.<*>} - * @private - * @default [] - * @since 3.20.0 + * @name Phaser.Renderer.WebGL.Pipelines.FX.VignetteFXPipeline#y + * @type {number} + * @since 3.60.0 */ + this.y = 0.5; /** - * The `destroy` list is a selection of items that were active and are awaiting being destroyed in the next update. + * The radius of the vignette effect. This value is normalized to the range 0 to 1. * - * @name Phaser.GameObjects.UpdateList#_destroy - * @type {Array.<*>} - * @private - * @default [] - * @since 3.20.0 + * @name Phaser.Renderer.WebGL.Pipelines.FX.VignetteFXPipeline#radius + * @type {number} + * @since 3.60.0 */ + this.radius = 0.5; /** - * The total number of items awaiting processing. + * The strength of the vignette effect. * - * @name Phaser.GameObjects.UpdateList#_toProcess + * @name Phaser.Renderer.WebGL.Pipelines.FX.VignetteFXPipeline#strength * @type {number} - * @private - * @default 0 - * @since 3.0.0 + * @since 3.60.0 */ - - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); - scene.sys.events.on(SceneEvents.START, this.start, this); + this.strength = 0.5; }, - /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. - * - * @method Phaser.GameObjects.UpdateList#boot - * @private - * @since 3.5.1 - */ - boot: function () + onPreRender: function (controller, shader) { - this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); - }, + controller = this.getController(controller); - /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. - * - * @method Phaser.GameObjects.UpdateList#start - * @private - * @since 3.5.0 - */ - start: function () - { - var eventEmitter = this.systems.events; + this.set1f('radius', controller.radius, shader); + this.set1f('strength', controller.strength, shader); + this.set2f('position', controller.x, controller.y, shader); + } - eventEmitter.on(SceneEvents.PRE_UPDATE, this.update, this); - eventEmitter.on(SceneEvents.UPDATE, this.sceneUpdate, this); - eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); - }, +}); - /** - * The update step. - * - * Pre-updates every active Game Object in the list. - * - * @method Phaser.GameObjects.UpdateList#sceneUpdate - * @since 3.20.0 - * - * @param {number} time - The current timestamp. - * @param {number} delta - The delta time elapsed since the last frame. - */ - sceneUpdate: function (time, delta) - { - var list = this._active; - var length = list.length; +module.exports = VignetteFXPipeline; - for (var i = 0; i < length; i++) - { - var gameObject = list[i]; - if (gameObject.active) - { - gameObject.preUpdate.call(gameObject, time, delta); - } - } - }, +/***/ }), - /** - * The Scene that owns this plugin is shutting down. - * - * We need to kill and reset all internal properties as well as stop listening to Scene events. - * - * @method Phaser.GameObjects.UpdateList#shutdown - * @since 3.0.0 - */ - shutdown: function () - { - var i = this._active.length; +/***/ 80542: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - while (i--) - { - this._active[i].destroy(true); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - i = this._pending.length; +var Class = __webpack_require__(56694); +var WipeFrag = __webpack_require__(62879); +var PostFXPipeline = __webpack_require__(80486); - while (i--) - { - this._pending[i].destroy(true); - } +/** + * @classdesc + * The Wipe FX Pipeline. + * + * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements + * in the game, such as images, text, or scene transitions. This effect is often used to create + * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition + * between game states. + * + * You can set both the direction and the axis of the wipe effect. The following combinations are possible: + * + * * left to right: direction 0, axis 0 + * * right to left: direction 1, axis 0 + * * top to bottom: direction 1, axis 1 + * * bottom to top: direction 1, axis 0 + * + * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect. + * + * A Wipe effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addWipe(); + * sprite.postFX.addReveal(); + * ``` + * + * @class WipeFXPipeline + * @extends Phaser.Renderer.WebGL.WebGLPipeline + * @memberof Phaser.Renderer.WebGL.Pipelines.FX + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. + */ +var WipeFXPipeline = new Class({ - i = this._destroy.length; + Extends: PostFXPipeline, - while (i--) - { - this._destroy[i].destroy(true); - } + initialize: - this._toProcess = 0; + function WipeFXPipeline (game) + { + PostFXPipeline.call(this, { + game: game, + fragShader: WipeFrag + }); - this._pending = []; - this._active = []; - this._destroy = []; + /** + * The progress of the Wipe effect. This value is normalized to the range 0 to 1. + * + * Adjust this value to make the wipe transition (i.e. via a Tween) + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.WipeFXPipeline#progress + * @type {number} + * @since 3.60.0 + */ + this.progress = 0; - this.removeAllListeners(); + /** + * The width of the wipe effect. This value is normalized in the range 0 to 1. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.WipeFXPipeline#wipeWidth + * @type {number} + * @since 3.60.0 + */ + this.wipeWidth = 0.1; - var eventEmitter = this.systems.events; + /** + * The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.WipeFXPipeline#direction + * @type {number} + * @since 3.60.0 + */ + this.direction = 0; - eventEmitter.off(SceneEvents.PRE_UPDATE, this.update, this); - eventEmitter.off(SceneEvents.UPDATE, this.sceneUpdate, this); - eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); + /** + * The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.WipeFXPipeline#axis + * @type {number} + * @since 3.60.0 + */ + this.axis = 0; + + /** + * Is this a reveal (true) or a fade (false) effect? + * + * @name Phaser.Renderer.WebGL.Pipelines.FX.WipeFXPipeline#reveal + * @type {boolean} + * @since 3.60.0 + */ + this.reveal = false; }, - /** - * The Scene that owns this plugin is being destroyed. - * - * We need to shutdown and then kill off all external references. - * - * @method Phaser.GameObjects.UpdateList#destroy - * @since 3.0.0 - */ - destroy: function () + onPreRender: function (controller, shader) { - this.shutdown(); + controller = this.getController(controller); - this.systems.events.off(SceneEvents.START, this.start, this); + var progress = controller.progress; + var wipeWidth = controller.wipeWidth; + var direction = controller.direction; + var axis = controller.axis; - this.scene = null; - this.systems = null; + this.set4f('config', progress, wipeWidth, direction, axis, shader); + this.setBoolean('reveal', controller.reveal, shader); } - /** - * Adds a new item to the Update List. - * - * The item is added to the pending list and made active in the next update. - * - * @method Phaser.GameObjects.UpdateList#add - * @since 3.0.0 - * - * @param {*} item - The item to add to the queue. - * - * @return {*} The item that was added. - */ - - /** - * Removes an item from the Update List. - * - * The item is added to the pending destroy and fully removed in the next update. - * - * @method Phaser.GameObjects.UpdateList#remove - * @since 3.0.0 - * - * @param {*} item - The item to be removed from the queue. - * - * @return {*} The item that was removed. - */ - - /** - * Removes all active items from this Update List. - * - * All the items are marked as 'pending destroy' and fully removed in the next update. - * - * @method Phaser.GameObjects.UpdateList#removeAll - * @since 3.20.0 - * - * @return {this} This Update List object. - */ - - /** - * Update this queue. First it will process any items awaiting destruction, and remove them. - * - * Then it will check to see if there are any items pending insertion, and move them to an - * active state. Finally, it will return a list of active items for further processing. - * - * @method Phaser.GameObjects.UpdateList#update - * @since 3.0.0 - * - * @return {Array.<*>} A list of active items. - */ - - /** - * Returns the current list of active items. - * - * This method returns a reference to the active list array, not a copy of it. - * Therefore, be careful to not modify this array outside of the ProcessQueue. - * - * @method Phaser.GameObjects.UpdateList#getActive - * @since 3.0.0 - * - * @return {Array.<*>} A list of active items. - */ - - /** - * The number of entries in the active list. - * - * @name Phaser.GameObjects.UpdateList#length - * @type {number} - * @readonly - * @since 3.20.0 - */ }); -PluginCache.register('UpdateList', UpdateList, 'updateList'); - -module.exports = UpdateList; +module.exports = WipeFXPipeline; /***/ }), -/* 1041 */ -/***/ (function(module, exports) { + +/***/ 58136: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Process Queue Add Event. - * - * This event is dispatched by a Process Queue when a new item is successfully moved to its active list. - * - * You will most commonly see this used by a Scene's Update List when a new Game Object has been added. - * - * In that instance, listen to this event from within a Scene using: `this.sys.updateList.on('add', listener)`. - * - * @event Phaser.Structs.Events#PROCESS_QUEUE_ADD - * @since 3.20.0 - * - * @param {*} item - The item that was added to the Process Queue. + * @namespace Phaser.Renderer.WebGL.Pipelines.FX */ -module.exports = 'add'; +var FX = { -/***/ }), -/* 1042 */ -/***/ (function(module, exports) { + Barrel: __webpack_require__(32469), + Bloom: __webpack_require__(2134), + Blur: __webpack_require__(63377), + Bokeh: __webpack_require__(49745), + Circle: __webpack_require__(4323), + ColorMatrix: __webpack_require__(92066), + Displacement: __webpack_require__(89581), + Glow: __webpack_require__(55084), + Gradient: __webpack_require__(41653), + Pixelate: __webpack_require__(73416), + Shadow: __webpack_require__(58049), + Shine: __webpack_require__(18026), + Vignette: __webpack_require__(72381), + Wipe: __webpack_require__(80542) -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +}; -/** - * The Process Queue Remove Event. - * - * This event is dispatched by a Process Queue when a new item is successfully removed from its active list. - * - * You will most commonly see this used by a Scene's Update List when a Game Object has been removed. - * - * In that instance, listen to this event from within a Scene using: `this.sys.updateList.on('remove', listener)`. - * - * @event Phaser.Structs.Events#PROCESS_QUEUE_REMOVE - * @since 3.20.0 - * - * @param {*} item - The item that was removed from the Process Queue. - */ -module.exports = 'remove'; +// Export it + +module.exports = FX; /***/ }), -/* 1043 */ -/***/ (function(module, exports) { + +/***/ 62253: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CONST = __webpack_require__(65641); +var Extend = __webpack_require__(98611); + /** - * Calculate the full bounds, in local and world space, of a BitmapText Game Object. - * - * Returns a BitmapTextSize object that contains global and local variants of the Game Objects x and y coordinates and - * its width and height. Also includes an array of the line lengths and all word positions. - * - * The global position and size take into account the Game Object's position and scale. - * - * The local position and size just takes into account the font data. - * - * @function GetBitmapTextSize - * @since 3.0.0 - * @private - * - * @param {(Phaser.GameObjects.DynamicBitmapText|Phaser.GameObjects.BitmapText)} src - The BitmapText to calculate the bounds values for. - * @param {boolean} [round=false] - Whether to round the positions to the nearest integer. - * @param {boolean} [updateOrigin=false] - Whether to update the origin of the BitmapText after bounds calculations? - * @param {object} [out] - Object to store the results in, to save constant object creation. If not provided an empty object is returned. - * - * @return {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} The calculated bounds values of the BitmapText. + * @namespace Phaser.Renderer.WebGL.Pipelines */ -var GetBitmapTextSize = function (src, round, updateOrigin, out) -{ - if (updateOrigin === undefined) { updateOrigin = false; } - if (out === undefined) - { - out = { - local: { - x: 0, - y: 0, - width: 0, - height: 0 - }, - global: { - x: 0, - y: 0, - width: 0, - height: 0 - }, - lines: { - shortest: 0, - longest: 0, - lengths: null, - height: 0 - }, - wrappedText: '', - words: [], - characters: [], - scaleX: 0, - scaleY: 0 - }; +var Pipelines = { - return out; - } + FX: __webpack_require__(58136), - var text = src.text; - var textLength = text.length; - var maxWidth = src.maxWidth; - var wordWrapCharCode = src.wordWrapCharCode; + BitmapMaskPipeline: __webpack_require__(5583), + Events: __webpack_require__(18970), + FXPipeline: __webpack_require__(81828), + LightPipeline: __webpack_require__(66901), + MobilePipeline: __webpack_require__(71264), + MultiPipeline: __webpack_require__(77310), + PointLightPipeline: __webpack_require__(10919), + PostFXPipeline: __webpack_require__(80486), + PreFXPipeline: __webpack_require__(87228), + RopePipeline: __webpack_require__(21213), + SinglePipeline: __webpack_require__(51212), + UtilityPipeline: __webpack_require__(60848) - var bx = Number.MAX_VALUE; - var by = Number.MAX_VALUE; - var bw = 0; - var bh = 0; +}; - var chars = src.fontData.chars; - var lineHeight = src.fontData.lineHeight; - var letterSpacing = src.letterSpacing; +// Merge in the consts - var xAdvance = 0; - var yAdvance = 0; +Pipelines = Extend(false, Pipelines, CONST); - var charCode = 0; +// Export it - var glyph = null; +module.exports = Pipelines; - var align = src._align; - var x = 0; - var y = 0; +/***/ }), - var scale = (src.fontSize / src.fontData.size); - var sx = scale * src.scaleX; - var sy = scale * src.scaleY; +/***/ 2529: +/***/ ((module) => { - var lastGlyph = null; - var lastCharCode = 0; - var lineWidths = []; - var shortestLine = Number.MAX_VALUE; - var longestLine = 0; - var currentLine = 0; - var currentLineWidth = 0; +module.exports = [ + '#define SHADER_NAME PHASER_ADD_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 = frame1 + frame2 * uStrength;', + '}', +].join('\n'); - var i; - var words = []; - var characters = []; - var current = null; - // Scan for breach of maxWidth and insert carriage-returns - if (maxWidth > 0) - { - for (i = 0; i < textLength; i++) - { - charCode = text.charCodeAt(i); +/***/ }), - if (charCode === 10) - { - if (current !== null) - { - words.push({ - word: current.word, - i: current.i, - x: current.x * sx, - y: current.y * sy, - w: current.w * sx, - h: current.h * sy, - cr: true - }); +/***/ 91679: +/***/ ((module) => { - current = null; - } +module.exports = [ + '#define SHADER_NAME PHASER_BITMAP_MASK_FS', + 'precision mediump float;', + 'uniform vec2 uResolution;', + 'uniform sampler2D uMainSampler;', + 'uniform sampler2D uMaskSampler;', + 'uniform bool uInvertMaskAlpha;', + 'void main ()', + '{', + ' vec2 uv = gl_FragCoord.xy / uResolution;', + ' vec4 mainColor = texture2D(uMainSampler, uv);', + ' vec4 maskColor = texture2D(uMaskSampler, uv);', + ' if (!uInvertMaskAlpha)', + ' {', + ' mainColor *= maskColor.a;', + ' }', + ' else', + ' {', + ' mainColor *= (1.0 - maskColor.a);', + ' }', + ' gl_FragColor = mainColor;', + '}', +].join('\n'); - xAdvance = 0; - yAdvance += lineHeight; - lastGlyph = null; - continue; - } +/***/ }), - glyph = chars[charCode]; +/***/ 89053: +/***/ ((module) => { - if (!glyph) - { - continue; - } +module.exports = [ + '#define SHADER_NAME PHASER_BITMAP_MASK_VS', + 'precision mediump float;', + 'attribute vec2 inPosition;', + 'void main ()', + '{', + ' gl_Position = vec4(inPosition, 0.0, 1.0);', + '}', +].join('\n'); - if (lastGlyph !== null) - { - var glyphKerningOffset = glyph.kerning[lastCharCode]; - } - if (charCode === wordWrapCharCode) - { - if (current !== null) - { - words.push({ - word: current.word, - i: current.i, - x: current.x * sx, - y: current.y * sy, - w: current.w * sx, - h: current.h * sy, - cr: false - }); +/***/ }), - current = null; - } - } - else - { - if (current === null) - { - // We're starting a new word, recording the starting index, etc - current = { word: '', i: i, x: xAdvance, y: yAdvance, w: 0, h: lineHeight, cr: false }; - } +/***/ 37486: +/***/ ((module) => { - current.word = current.word.concat(text[i]); - current.w += glyph.xOffset + glyph.xAdvance + ((glyphKerningOffset !== undefined) ? glyphKerningOffset : 0); - } +module.exports = [ + '#define SHADER_NAME PHASER_COLORMATRIX_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform float uColorMatrix[20];', + 'uniform float uAlpha;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec4 c = texture2D(uMainSampler, outTexCoord);', + ' if (uAlpha == 0.0)', + ' {', + ' gl_FragColor = c;', + ' return;', + ' }', + ' if (c.a > 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'); - xAdvance += glyph.xAdvance + letterSpacing; - lastGlyph = glyph; - lastCharCode = charCode; - } - // Last word - if (current !== null) - { - words.push({ - word: current.word, - i: current.i, - x: current.x * sx, - y: current.y * sy, - w: current.w * sx, - h: current.h * sy, - cr: false - }); - } +/***/ }), - // Reset for the next loop - xAdvance = 0; - yAdvance = 0; - lastGlyph = null; - lastCharCode = 0; +/***/ 79060: +/***/ ((module) => { - // Loop through the words array and see if we've got any > maxWidth - var prev; - var offset = 0; - var crs = []; +module.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'); - for (i = 0; i < words.length; i++) - { - var entry = words[i]; - var left = entry.x; - var right = entry.x + entry.w; - if (prev) - { - var diff = left - (prev.x + prev.w); +/***/ }), - offset = left - (diff + prev.w); +/***/ 87751: +/***/ ((module) => { - prev = null; - } +module.exports = [ + '#define SHADER_NAME BARREL_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform float amount;', + 'varying vec2 outTexCoord;', + 'vec2 Distort(vec2 p)', + '{', + ' float theta = atan(p.y, p.x);', + ' float radius = length(p);', + ' radius = pow(radius, amount);', + ' p.x = radius * cos(theta);', + ' p.y = radius * sin(theta);', + ' return 0.5 * (p + 1.0);', + '}', + 'void main()', + '{', + ' vec2 xy = 2.0 * outTexCoord - 1.0;', + ' vec2 texCoord = outTexCoord;', + ' if (length(xy) < 1.0)', + ' {', + ' texCoord = Distort(xy);', + ' }', + ' gl_FragColor = texture2D(uMainSampler, texCoord);', + '}', +].join('\n'); - var checkLeft = left - offset; - var checkRight = right - offset; - if (checkLeft > maxWidth || checkRight > maxWidth) - { - crs.push(entry.i - 1); +/***/ }), - if (entry.cr) - { - crs.push(entry.i + entry.word.length); +/***/ 88222: +/***/ ((module) => { - offset = 0; - prev = null; - } - else - { - prev = entry; - } - } - else if (entry.cr) - { - crs.push(entry.i + entry.word.length); +module.exports = [ + '#define SHADER_NAME BLOOM_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform vec2 offset;', + 'uniform float strength;', + 'uniform vec3 color;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec4 sum = texture2D(uMainSampler, outTexCoord) * 0.204164 * strength;', + ' sum = sum + texture2D(uMainSampler, outTexCoord + offset * 1.407333) * 0.304005;', + ' sum = sum + texture2D(uMainSampler, outTexCoord - offset * 1.407333) * 0.304005;', + ' sum = sum + texture2D(uMainSampler, outTexCoord + offset * 3.294215) * 0.093913;', + ' gl_FragColor = (sum + texture2D(uMainSampler, outTexCoord - offset * 3.294215) * 0.093913) * vec4(color, 1);', + '}', +].join('\n'); - offset = 0; - prev = null; - } - } - var stringInsert = function (str, index, value) - { - return str.substr(0, index) + value + str.substr(index + 1); - }; +/***/ }), - for (i = crs.length - 1; i >= 0; i--) - { - // eslint-disable-next-line quotes - text = stringInsert(text, crs[i], "\n"); - } +/***/ 44481: +/***/ ((module) => { - out.wrappedText = text; +module.exports = [ + '#define SHADER_NAME BLUR_HIGH_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform vec2 resolution;', + 'uniform vec2 offset;', + 'uniform float strength;', + 'uniform vec3 color;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec2 uv = outTexCoord;', + ' vec4 col = vec4(0.0);', + ' vec2 off1 = vec2(1.411764705882353) * offset * strength;', + ' vec2 off2 = vec2(3.2941176470588234) * offset * strength;', + ' vec2 off3 = vec2(5.176470588235294) * offset * strength;', + ' col += texture2D(uMainSampler, uv) * 0.1964825501511404;', + ' col += texture2D(uMainSampler, uv + (off1 / resolution)) * 0.2969069646728344;', + ' col += texture2D(uMainSampler, uv - (off1 / resolution)) * 0.2969069646728344;', + ' col += texture2D(uMainSampler, uv + (off2 / resolution)) * 0.09447039785044732;', + ' col += texture2D(uMainSampler, uv - (off2 / resolution)) * 0.09447039785044732;', + ' col += texture2D(uMainSampler, uv + (off3 / resolution)) * 0.010381362401148057;', + ' col += texture2D(uMainSampler, uv - (off3 / resolution)) * 0.010381362401148057;', + ' gl_FragColor = col * vec4(color, 1.0);', + '}', +].join('\n'); - textLength = text.length; - // Recalculated in the next loop - words = []; - current = null; - } +/***/ }), - var charIndex = 0; +/***/ 35491: +/***/ ((module) => { - for (i = 0; i < textLength; i++) - { - charCode = text.charCodeAt(i); +module.exports = [ + '#define SHADER_NAME BLUR_LOW_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform vec2 resolution;', + 'uniform float strength;', + 'uniform vec3 color;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec2 uv = outTexCoord;', + ' vec4 col = vec4(0.0);', + ' vec2 offset = vec2(1.333) * strength;', + ' col += texture2D(uMainSampler, uv) * 0.29411764705882354;', + ' col += texture2D(uMainSampler, uv + (offset / resolution)) * 0.35294117647058826;', + ' col += texture2D(uMainSampler, uv - (offset / resolution)) * 0.35294117647058826;', + ' gl_FragColor = col * vec4(color, 1.0);', + '}', +].join('\n'); - if (charCode === 10) - { - if (current !== null) - { - words.push({ - word: current.word, - i: current.i, - x: current.x * sx, - y: current.y * sy, - w: current.w * sx, - h: current.h * sy - }); - current = null; - } +/***/ }), - xAdvance = 0; - yAdvance += lineHeight; - lastGlyph = null; +/***/ 75568: +/***/ ((module) => { - lineWidths[currentLine] = currentLineWidth; +module.exports = [ + '#define SHADER_NAME BLUR_MED_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform vec2 resolution;', + 'uniform vec2 offset;', + 'uniform float strength;', + 'uniform vec3 color;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec2 uv = outTexCoord;', + ' vec4 col = vec4(0.0);', + ' vec2 off1 = vec2(1.3846153846) * offset * strength;', + ' vec2 off2 = vec2(3.2307692308) * offset * strength;', + ' col += texture2D(uMainSampler, uv) * 0.2270270270;', + ' col += texture2D(uMainSampler, uv + (off1 / resolution)) * 0.3162162162;', + ' col += texture2D(uMainSampler, uv - (off1 / resolution)) * 0.3162162162;', + ' col += texture2D(uMainSampler, uv + (off2 / resolution)) * 0.0702702703;', + ' col += texture2D(uMainSampler, uv - (off2 / resolution)) * 0.0702702703;', + ' gl_FragColor = col * vec4(color, 1.0);', + '}', +].join('\n'); - if (currentLineWidth > longestLine) - { - longestLine = currentLineWidth; - } - if (currentLineWidth < shortestLine) - { - shortestLine = currentLineWidth; - } +/***/ }), + +/***/ 69960: +/***/ ((module) => { + +module.exports = [ + '#define SHADER_NAME BOKEH_FS', + 'precision mediump float;', + '#define ITERATIONS 100.0', + '#define ONEOVER_ITR 1.0 / ITERATIONS', + '#define PI 3.141596', + '#define GOLDEN_ANGLE 2.39996323', + 'uniform sampler2D uMainSampler;', + 'uniform vec2 resolution;', + 'uniform float radius;', + 'uniform float amount;', + 'uniform float contrast;', + 'uniform bool isTiltShift;', + 'uniform float strength;', + 'uniform vec2 blur;', + 'varying vec2 outTexCoord;', + 'vec2 Sample (in float theta, inout float r)', + '{', + ' r += 1.0 / r;', + ' return (r - 1.0) * vec2(cos(theta), sin(theta)) * 0.06;', + '}', + 'vec3 Bokeh (sampler2D tex, vec2 uv, float radius)', + '{', + ' vec3 acc = vec3(0.0);', + ' vec3 div = vec3(0.0);', + ' vec2 pixel = vec2(resolution.y / resolution.x, 1.0) * radius * .025;', + ' float r = 1.0;', + ' for (float j = 0.0; j < GOLDEN_ANGLE * ITERATIONS; j += GOLDEN_ANGLE)', + ' {', + ' vec3 col = texture2D(tex, uv + pixel * Sample(j, r)).xyz;', + ' col = contrast > 0.0 ? col * col * (1.0 + contrast) : col;', + ' vec3 bokeh = vec3(0.5) + pow(col, vec3(10.0)) * amount;', + ' acc += col * bokeh;', + ' div += bokeh;', + ' }', + ' return acc / div;', + '}', + 'void main ()', + '{', + ' float shift = 1.0;', + ' if (isTiltShift)', + ' {', + ' vec2 uv = vec2(gl_FragCoord.xy / resolution + vec2(-0.5, -0.5)) * 2.0;', + ' float centerStrength = 1.0;', + ' shift = length(uv * blur * strength) * centerStrength;', + ' }', + ' gl_FragColor = vec4(Bokeh(uMainSampler, outTexCoord * vec2(1.0, 1.0), radius * shift), 0.0);', + '}', +].join('\n'); - currentLine++; - currentLineWidth = 0; - continue; - } +/***/ }), - glyph = chars[charCode]; +/***/ 33754: +/***/ ((module) => { - if (!glyph) - { - continue; - } +module.exports = [ + '#define SHADER_NAME CIRCLE_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform vec2 resolution;', + 'uniform vec3 color;', + 'uniform vec4 backgroundColor;', + 'uniform float thickness;', + 'uniform float scale;', + 'uniform float feather;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec4 texture = texture2D(uMainSampler, outTexCoord);', + ' vec2 position = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0;', + ' float aspectRatio = resolution.x / resolution.y;', + ' position.x *= aspectRatio;', + ' float grad = length(position);', + ' float outer = aspectRatio;', + ' float inner = outer - (thickness * 2.0 / resolution.y);', + ' if (aspectRatio >= 1.0)', + ' {', + ' float f = 2.0 + (resolution.y / resolution.x);', + ' outer = 1.0;', + ' inner = 1.0 - (thickness * f / resolution.x);', + ' }', + ' outer *= scale;', + ' inner *= scale;', + ' float circle = smoothstep(outer, outer - 0.01, grad);', + ' float ring = circle - smoothstep(inner, inner - feather, grad);', + ' texture = mix(backgroundColor * backgroundColor.a, texture, texture.a);', + ' texture = (texture * (circle - ring));', + ' gl_FragColor = vec4(texture.rgb + (ring * color), texture.a);', + '}', +].join('\n'); - x = xAdvance; - y = yAdvance; - if (lastGlyph !== null) - { - var kerningOffset = glyph.kerning[lastCharCode]; +/***/ }), - x += (kerningOffset !== undefined) ? kerningOffset : 0; - } +/***/ 35668: +/***/ ((module) => { - if (bx > x) - { - bx = x; - } +module.exports = [ + '#define SHADER_NAME DISPLACEMENT_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform sampler2D uDisplacementSampler;', + 'uniform vec2 amount;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec2 disp = (-vec2(0.5, 0.5) + texture2D(uDisplacementSampler, outTexCoord).rr) * amount;', + ' gl_FragColor = texture2D(uMainSampler, outTexCoord + disp).rgba;', + '}', +].join('\n'); - if (by > y) - { - by = y; - } - var gw = x + glyph.xAdvance; - var gh = y + lineHeight; +/***/ }), - if (bw < gw) - { - bw = gw; - } +/***/ 69675: +/***/ ((module) => { - if (bh < gh) - { - bh = gh; - } +module.exports = [ + '#define SHADER_NAME GLOW_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'varying vec2 outTexCoord;', + 'uniform float outerStrength;', + 'uniform float innerStrength;', + 'uniform vec2 resolution;', + 'uniform vec4 glowColor;', + 'uniform bool knockout;', + 'const float PI = 3.14159265358979323846264;', + 'const float DIST = __DIST__;', + 'const float SIZE = min(__SIZE__, PI * 2.0);', + 'const float STEP = ceil(PI * 2.0 / SIZE);', + 'const float MAX_ALPHA = STEP * DIST * (DIST + 1.0) / 2.0;', + 'void main ()', + '{', + ' vec2 px = vec2(1.0 / resolution.x, 1.0 / resolution.y);', + ' float totalAlpha = 0.0;', + ' vec2 direction;', + ' vec2 displaced;', + ' vec4 color;', + ' for (float angle = 0.0; angle < PI * 2.0; angle += SIZE)', + ' {', + ' direction = vec2(cos(angle), sin(angle)) * px;', + ' for (float curDistance = 0.0; curDistance < DIST; curDistance++)', + ' {', + ' displaced = outTexCoord + direction * (curDistance + 1.0);', + ' color = texture2D(uMainSampler, displaced);', + ' totalAlpha += (DIST - curDistance) * color.a;', + ' }', + ' }', + ' color = texture2D(uMainSampler, outTexCoord);', + ' float alphaRatio = (totalAlpha / MAX_ALPHA);', + ' float innerGlowAlpha = (1.0 - alphaRatio) * innerStrength * color.a;', + ' float innerGlowStrength = min(1.0, innerGlowAlpha);', + ' vec4 innerColor = mix(color, glowColor, innerGlowStrength);', + ' float outerGlowAlpha = alphaRatio * outerStrength * (1.0 - color.a);', + ' float outerGlowStrength = min(1.0 - innerColor.a, outerGlowAlpha);', + ' vec4 outerGlowColor = outerGlowStrength * glowColor.rgba;', + ' if (knockout)', + ' {', + ' float resultAlpha = outerGlowAlpha + innerGlowAlpha;', + ' gl_FragColor = vec4(glowColor.rgb * resultAlpha, resultAlpha);', + ' }', + ' else', + ' {', + ' gl_FragColor = innerColor + outerGlowColor;', + ' }', + '}', +].join('\n'); - var charWidth = glyph.xOffset + glyph.xAdvance + ((kerningOffset !== undefined) ? kerningOffset : 0); - if (charCode === wordWrapCharCode) - { - if (current !== null) - { - words.push({ - word: current.word, - i: current.i, - x: current.x * sx, - y: current.y * sy, - w: current.w * sx, - h: current.h * sy - }); +/***/ }), - current = null; - } - } - else - { - if (current === null) - { - // We're starting a new word, recording the starting index, etc - current = { word: '', i: charIndex, x: xAdvance, y: yAdvance, w: 0, h: lineHeight }; - } +/***/ 90993: +/***/ ((module) => { - current.word = current.word.concat(text[i]); - current.w += charWidth; - } +module.exports = [ + '#define SHADER_NAME GRADIENT_FS', + '#define SRGB_TO_LINEAR(c) pow((c), vec3(2.2))', + '#define LINEAR_TO_SRGB(c) pow((c), vec3(1.0 / 2.2))', + '#define SRGB(r, g, b) SRGB_TO_LINEAR(vec3(float(r), float(g), float(b)) / 255.0)', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform vec2 positionFrom;', + 'uniform vec2 positionTo;', + 'uniform vec3 color1;', + 'uniform vec3 color2;', + 'uniform float alpha;', + 'uniform int size;', + 'varying vec2 outTexCoord;', + 'float gradientNoise(in vec2 uv)', + '{', + ' const vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189);', + ' return fract(magic.z * fract(dot(uv, magic.xy)));', + '}', + 'float stepped (in float s, in float scale, in int steps)', + '{', + ' return steps > 0 ? floor( s / ((1.0 * scale) / float(steps))) * 1.0 / float(steps - 1) : s;', + '}', + 'void main ()', + '{', + ' vec2 a = positionFrom;', + ' vec2 b = positionTo;', + ' vec2 ba = b - a;', + ' float d = dot(outTexCoord - a, ba) / dot(ba, ba);', + ' float t = size > 0 ? stepped(d, 1.0, size) : d;', + ' t = smoothstep(0.0, 1.0, clamp(t, 0.0, 1.0));', + ' vec3 color = mix(SRGB(color1.r, color1.g, color1.b), SRGB(color2.r, color2.g, color2.b), t);', + ' color = LINEAR_TO_SRGB(color);', + ' color += (1.0 / 255.0) * gradientNoise(outTexCoord) - (0.5 / 255.0);', + ' vec4 texture = texture2D(uMainSampler, outTexCoord);', + ' gl_FragColor = vec4(mix(color.rgb, texture.rgb, alpha), 1.0) * texture.a;', + '}', +].join('\n'); - characters.push({ - i: charIndex, - char: text[i], - code: charCode, - x: (glyph.xOffset + xAdvance) * scale, - y: (glyph.yOffset + yAdvance) * scale, - w: glyph.width * scale, - h: glyph.height * scale, - t: yAdvance * scale, - r: gw * scale, - b: lineHeight * scale, - line: currentLine, - glyph: glyph - }); - xAdvance += glyph.xAdvance + letterSpacing; - lastGlyph = glyph; - lastCharCode = charCode; - currentLineWidth = gw * scale; - charIndex++; - } +/***/ }), - // Last word - if (current !== null) - { - words.push({ - word: current.word, - i: current.i, - x: current.x * sx, - y: current.y * sy, - w: current.w * sx, - h: current.h * sy - }); - } +/***/ 37945: +/***/ ((module) => { - lineWidths[currentLine] = currentLineWidth; +module.exports = [ + '#define SHADER_NAME PIXELATE_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform vec2 resolution;', + 'uniform float amount;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' float pixelSize = floor(2.0 + amount);', + ' vec2 center = pixelSize * floor(outTexCoord * resolution / pixelSize) + pixelSize * vec2(0.5, 0.5);', + ' vec2 corner1 = center + pixelSize * vec2(-0.5, -0.5);', + ' vec2 corner2 = center + pixelSize * vec2(+0.5, -0.5);', + ' vec2 corner3 = center + pixelSize * vec2(+0.5, +0.5);', + ' vec2 corner4 = center + pixelSize * vec2(-0.5, +0.5);', + ' vec4 pixel = 0.4 * texture2D(uMainSampler, center / resolution);', + ' pixel += 0.15 * texture2D(uMainSampler, corner1 / resolution);', + ' pixel += 0.15 * texture2D(uMainSampler, corner2 / resolution);', + ' pixel += 0.15 * texture2D(uMainSampler, corner3 / resolution);', + ' pixel += 0.15 * texture2D(uMainSampler, corner4 / resolution);', + ' gl_FragColor = pixel;', + '}', +].join('\n'); - if (currentLineWidth > longestLine) - { - longestLine = currentLineWidth; - } - if (currentLineWidth < shortestLine) - { - shortestLine = currentLineWidth; - } +/***/ }), - // Adjust all of the character positions based on alignment - if (align > 0) - { - for (var c = 0; c < characters.length; c++) - { - var currentChar = characters[c]; +/***/ 85718: +/***/ ((module) => { - if (align === 1) - { - var ax1 = ((longestLine - lineWidths[currentChar.line]) / 2); +module.exports = [ + '#define SHADER_NAME SHADOW_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'varying vec2 outTexCoord;', + 'uniform vec2 lightPosition;', + 'uniform vec4 color;', + 'uniform float decay;', + 'uniform float power;', + 'uniform float intensity;', + 'uniform int samples;', + 'const int MAX = 12;', + 'void main ()', + '{', + ' vec4 texture = texture2D(uMainSampler, outTexCoord);', + ' vec2 pc = (lightPosition - outTexCoord) * intensity;', + ' float shadow = 0.0;', + ' float limit = max(float(MAX), float(samples));', + ' for (int i = 0; i < MAX; ++i)', + ' {', + ' if (i >= samples)', + ' {', + ' break;', + ' }', + ' shadow += texture2D(uMainSampler, outTexCoord + float(i) * decay / limit * pc).a * power;', + ' }', + ' float mask = 1.0 - texture.a;', + ' gl_FragColor = mix(texture, color, shadow * mask);', + '}', +].join('\n'); - currentChar.x += ax1; - currentChar.r += ax1; - } - else if (align === 2) - { - var ax2 = (longestLine - lineWidths[currentChar.line]); - currentChar.x += ax2; - currentChar.r += ax2; - } - } - } +/***/ }), - var local = out.local; - var global = out.global; - var lines = out.lines; +/***/ 13740: +/***/ ((module) => { - local.x = bx * scale; - local.y = by * scale; - local.width = bw * scale; - local.height = bh * scale; +module.exports = [ + '#define SHADER_NAME SHINE_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform vec2 resolution;', + 'uniform bool reveal;', + 'uniform float speed;', + 'uniform float time;', + 'uniform float lineWidth;', + 'uniform float gradient;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec2 uv = gl_FragCoord.xy / resolution.xy;', + ' vec4 tex = texture2D(uMainSampler, outTexCoord);', + ' vec4 col1 = vec4(0.3, 0.0, 0.0, 1.0);', + ' vec4 col2 = vec4(0.85, 0.85, 0.85, 1.0);', + ' uv.x = uv.x - mod(time * speed, 2.0) + 0.5;', + ' float y = uv.x * gradient;', + ' float s = smoothstep(y - lineWidth, y, uv.y) - smoothstep(y, y + lineWidth, uv.y);', + ' gl_FragColor = (((s * col1) + (s * col2)) * tex);', + ' if (!reveal)', + ' {', + ' gl_FragColor += tex;', + ' }', + '}', +].join('\n'); - global.x = (src.x - src._displayOriginX) + (bx * sx); - global.y = (src.y - src._displayOriginY) + (by * sy); - global.width = bw * sx; - global.height = bh * sy; +/***/ }), - lines.shortest = shortestLine; - lines.longest = longestLine; - lines.lengths = lineWidths; +/***/ 80617: +/***/ ((module) => { - if (round) - { - local.x = Math.ceil(local.x); - local.y = Math.ceil(local.y); - local.width = Math.ceil(local.width); - local.height = Math.ceil(local.height); +module.exports = [ + '#define SHADER_NAME VIGNETTE_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform float radius;', + 'uniform float strength;', + 'uniform vec2 position;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec4 col = vec4(1.0);', + ' float d = length(outTexCoord - position);', + ' if (d <= radius)', + ' {', + ' float g = d / radius;', + ' g = sin(g * 3.14 * strength);', + ' col = vec4(g * g * g);', + ' }', + ' vec4 texture = texture2D(uMainSampler, outTexCoord);', + ' gl_FragColor = texture * (1.0 - col);', + '}', +].join('\n'); - global.x = Math.ceil(global.x); - global.y = Math.ceil(global.y); - global.width = Math.ceil(global.width); - global.height = Math.ceil(global.height); - lines.shortest = Math.ceil(shortestLine); - lines.longest = Math.ceil(longestLine); - } +/***/ }), - if (updateOrigin) - { - src._displayOriginX = (src.originX * local.width); - src._displayOriginY = (src.originY * local.height); +/***/ 62879: +/***/ ((module) => { - global.x = src.x - (src._displayOriginX * src.scaleX); - global.y = src.y - (src._displayOriginY * src.scaleY); +module.exports = [ + '#define SHADER_NAME WIPE_FS', + 'precision mediump float;', + 'uniform sampler2D uMainSampler;', + 'uniform vec4 config;', + 'uniform bool reveal;', + 'varying vec2 outTexCoord;', + 'void main ()', + '{', + ' vec2 uv = outTexCoord;', + ' vec4 color0;', + ' vec4 color1;', + ' if (reveal)', + ' {', + ' color0 = vec4(0);', + ' color1 = texture2D(uMainSampler, uv);', + ' }', + ' else', + ' {', + ' color0 = texture2D(uMainSampler, uv);', + ' color1 = vec4(0);', + ' }', + ' float distance = config.x;', + ' float width = config.y;', + ' float direction = config.z;', + ' float axis = uv.x;', + ' if (config.w == 1.0)', + ' {', + ' axis = uv.y;', + ' }', + ' float adjust = mix(width, -width, distance);', + ' float value = smoothstep(distance - width, distance + width, abs(direction - axis) + adjust);', + ' gl_FragColor = mix(color1, color0, value);', + '}', +].join('\n'); - if (round) - { - global.x = Math.ceil(global.x); - global.y = Math.ceil(global.y); - } - } - out.words = words; - out.characters = characters; - out.lines.height = lineHeight; - out.scale = scale; - out.scaleX = src.scaleX; - out.scaleY = src.scaleY; +/***/ }), - return out; -}; +/***/ 65045: +/***/ ((module) => { -module.exports = GetBitmapTextSize; +module.exports = [ + '#define SHADER_NAME PHASER_LIGHT_FS', + 'precision mediump float;', + 'struct Light', + '{', + ' vec2 position;', + ' vec3 color;', + ' float intensity;', + ' float radius;', + '};', + 'const int kMaxLights = %LIGHT_COUNT%;', + 'uniform vec4 uCamera; /* x, y, rotation, zoom */', + 'uniform vec2 uResolution;', + 'uniform sampler2D uMainSampler;', + 'uniform sampler2D uNormSampler;', + 'uniform vec3 uAmbientLightColor;', + 'uniform Light uLights[kMaxLights];', + 'uniform mat3 uInverseRotationMatrix;', + 'uniform int uLightCount;', + 'varying vec2 outTexCoord;', + 'varying float outTexId;', + 'varying float outTintEffect;', + 'varying vec4 outTint;', + 'void main ()', + '{', + ' vec3 finalColor = vec3(0.0, 0.0, 0.0);', + ' vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);', + ' vec4 texture = texture2D(uMainSampler, outTexCoord);', + ' vec4 color = texture * texel;', + ' if (outTintEffect == 1.0)', + ' {', + ' color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);', + ' }', + ' else if (outTintEffect == 2.0)', + ' {', + ' color = texel;', + ' }', + ' vec3 normalMap = texture2D(uNormSampler, outTexCoord).rgb;', + ' vec3 normal = normalize(uInverseRotationMatrix * vec3(normalMap * 2.0 - 1.0));', + ' vec2 res = vec2(min(uResolution.x, uResolution.y)) * uCamera.w;', + ' for (int index = 0; index < kMaxLights; ++index)', + ' {', + ' if (index < uLightCount)', + ' {', + ' Light light = uLights[index];', + ' vec3 lightDir = vec3((light.position.xy / res) - (gl_FragCoord.xy / res), 0.1);', + ' vec3 lightNormal = normalize(lightDir);', + ' float distToSurf = length(lightDir) * uCamera.w;', + ' float diffuseFactor = max(dot(normal, lightNormal), 0.0);', + ' float radius = (light.radius / res.x * uCamera.w) * uCamera.w;', + ' float attenuation = clamp(1.0 - distToSurf * distToSurf / (radius * radius), 0.0, 1.0);', + ' vec3 diffuse = light.color * diffuseFactor;', + ' finalColor += (attenuation * diffuse) * light.intensity;', + ' }', + ' }', + ' vec4 colorOutput = vec4(uAmbientLightColor + finalColor, 1.0);', + ' gl_FragColor = color * vec4(colorOutput.rgb * colorOutput.a, colorOutput.a);', + '}', +].join('\n'); /***/ }), -/* 1044 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ -var ParseXMLBitmapFont = __webpack_require__(212); +/***/ 98921: +/***/ ((module) => { -/** - * Parse an XML Bitmap Font from an Atlas. - * - * Adds the parsed Bitmap Font data to the cache with the `fontName` key. - * - * @function ParseFromAtlas - * @since 3.0.0 - * @private - * - * @param {Phaser.Scene} scene - The Scene to parse the Bitmap Font for. - * @param {string} fontName - The key of the font to add to the Bitmap Font cache. - * @param {string} textureKey - The key of the BitmapFont's texture. - * @param {string} frameKey - The key of the BitmapFont texture's frame. - * @param {string} xmlKey - The key of the XML data of the font to parse. - * @param {number} [xSpacing] - The x-axis spacing to add between each letter. - * @param {number} [ySpacing] - The y-axis spacing to add to the line height. - * - * @return {boolean} Whether the parsing was successful or not. - */ -var ParseFromAtlas = function (scene, fontName, textureKey, frameKey, xmlKey, xSpacing, ySpacing) -{ - var texture = scene.sys.textures.get(textureKey); - var frame = texture.get(frameKey); - var xml = scene.sys.cache.xml.get(xmlKey); +module.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'); - if (frame && xml) - { - var data = ParseXMLBitmapFont(xml, frame, xSpacing, ySpacing, texture); - scene.sys.cache.bitmapFont.add(fontName, { data: data, texture: textureKey, frame: frameKey, fromAtlas: true }); +/***/ }), - return true; - } - else - { - return false; - } -}; +/***/ 25005: +/***/ ((module) => { -module.exports = ParseFromAtlas; +module.exports = [ + '#define SHADER_NAME PHASER_MESH_FS', + 'precision mediump float;', + 'uniform vec3 uLightPosition;', + 'uniform vec3 uLightAmbient;', + 'uniform vec3 uLightDiffuse;', + 'uniform vec3 uLightSpecular;', + 'uniform vec3 uFogColor;', + 'uniform float uFogNear;', + 'uniform float uFogFar;', + 'uniform vec3 uMaterialAmbient;', + 'uniform vec3 uMaterialDiffuse;', + 'uniform vec3 uMaterialSpecular;', + 'uniform float uMaterialShine;', + 'uniform vec3 uCameraPosition;', + 'uniform sampler2D uTexture;', + 'varying vec2 vTextureCoord;', + 'varying vec3 vNormal;', + 'varying vec3 vPosition;', + 'void main (void)', + '{', + ' vec4 color = texture2D(uTexture, vTextureCoord);', + ' vec3 ambient = uLightAmbient * uMaterialAmbient;', + ' vec3 norm = normalize(vNormal);', + ' vec3 lightDir = normalize(uLightPosition - vPosition);', + ' float diff = max(dot(norm, lightDir), 0.0);', + ' vec3 diffuse = uLightDiffuse * (diff * uMaterialDiffuse);', + ' vec3 viewDir = normalize(uCameraPosition - vPosition);', + ' vec3 reflectDir = reflect(-lightDir, norm);', + ' float spec = pow(max(dot(viewDir, reflectDir), 0.0), uMaterialShine);', + ' vec3 specular = uLightSpecular * (spec * uMaterialSpecular);', + ' vec3 result = (ambient + diffuse + specular) * color.rgb;', + ' float depth = gl_FragCoord.z / gl_FragCoord.w;', + ' float fogFactor = smoothstep(uFogNear, uFogFar, depth);', + ' gl_FragColor.rgb = mix(result.rgb, uFogColor, fogFactor);', + ' gl_FragColor.a = color.a;', + '}', +].join('\n'); /***/ }), -/* 1045 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); +/***/ 94914: +/***/ ((module) => { -if (true) -{ - renderWebGL = __webpack_require__(1046); -} +module.exports = [ + '#define SHADER_NAME PHASER_MESH_VS', + 'precision mediump float;', + 'attribute vec3 aVertexPosition;', + 'attribute vec3 aVertexNormal;', + 'attribute vec2 aTextureCoord;', + 'uniform mat4 uViewProjectionMatrix;', + 'uniform mat4 uModelMatrix;', + 'uniform mat4 uNormalMatrix;', + 'varying vec2 vTextureCoord;', + 'varying vec3 vNormal;', + 'varying vec3 vPosition;', + 'void main ()', + '{', + ' vTextureCoord = aTextureCoord;', + ' vPosition = vec3(uModelMatrix * vec4(aVertexPosition, 1.0));', + ' vNormal = vec3(uNormalMatrix * vec4(aVertexNormal, 1.0));', + ' gl_Position = uViewProjectionMatrix * uModelMatrix * vec4(aVertexPosition, 1.0);', + '}', +].join('\n'); -if (true) -{ - renderCanvas = __webpack_require__(1048); -} -module.exports = { +/***/ }), - renderWebGL: renderWebGL, - renderCanvas: renderCanvas +/***/ 11263: +/***/ ((module) => { -}; +module.exports = [ + '#define SHADER_NAME PHASER_MOBILE_FS', + '#ifdef GL_FRAGMENT_PRECISION_HIGH', + 'precision highp float;', + '#else', + 'precision mediump float;', + '#endif', + 'uniform sampler2D uMainSampler;', + 'varying vec2 outTexCoord;', + 'varying float outTintEffect;', + 'varying vec4 outTint;', + 'void main ()', + '{', + ' vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);', + ' vec4 texture = texture2D(uMainSampler, outTexCoord);', + ' vec4 color = texture * texel;', + ' if (outTintEffect == 1.0)', + ' {', + ' color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);', + ' }', + ' else if (outTintEffect == 2.0)', + ' {', + ' color = texel;', + ' }', + ' gl_FragColor = color;', + '}', +].join('\n'); /***/ }), -/* 1046 */ -/***/ (function(module, exports, __webpack_require__) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +/***/ 51852: +/***/ ((module) => { -var BatchChar = __webpack_require__(1047); -var GetCalcMatrix = __webpack_require__(19); -var Utils = __webpack_require__(12); +module.exports = [ + '#define SHADER_NAME PHASER_MOBILE_VS', + '#ifdef GL_FRAGMENT_PRECISION_HIGH', + 'precision highp float;', + '#else', + 'precision mediump float;', + '#endif', + 'uniform mat4 uProjectionMatrix;', + 'attribute vec2 inPosition;', + 'attribute vec2 inTexCoord;', + 'attribute float inTexId;', + 'attribute float inTintEffect;', + 'attribute vec4 inTint;', + 'varying vec2 outTexCoord;', + 'varying float outTintEffect;', + 'varying vec4 outTint;', + 'void main ()', + '{', + ' gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);', + ' outTexCoord = inTexCoord;', + ' outTint = inTint;', + ' outTintEffect = inTintEffect;', + '}', +].join('\n'); -/** - * 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.BitmapText#renderWebGL - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.BitmapText} 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 BitmapTextWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - var text = src._text; - var textLength = text.length; - if (textLength === 0) - { - return; - } +/***/ }), - camera.addToRenderList(src); +/***/ 53787: +/***/ ((module) => { - var pipeline = renderer.pipelines.set(src.pipeline, src); +module.exports = [ + '#define SHADER_NAME PHASER_MULTI_FS', + '#ifdef GL_FRAGMENT_PRECISION_HIGH', + 'precision highp float;', + '#else', + 'precision mediump float;', + '#endif', + 'uniform sampler2D uMainSampler[%count%];', + 'varying vec2 outTexCoord;', + 'varying float outTexId;', + 'varying float outTintEffect;', + 'varying vec4 outTint;', + 'void main ()', + '{', + ' vec4 texture;', + ' %forloop%', + ' vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);', + ' vec4 color = texture * texel;', + ' if (outTintEffect == 1.0)', + ' {', + ' color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);', + ' }', + ' else if (outTintEffect == 2.0)', + ' {', + ' color = texel;', + ' }', + ' gl_FragColor = color;', + '}', +].join('\n'); - var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; - var roundPixels = camera.roundPixels; +/***/ }), - var cameraAlpha = camera.alpha; +/***/ 15968: +/***/ ((module) => { - var charColors = src.charColors; +module.exports = [ + '#define SHADER_NAME PHASER_MULTI_VS', + '#ifdef GL_FRAGMENT_PRECISION_HIGH', + 'precision highp float;', + '#else', + 'precision mediump float;', + '#endif', + 'uniform mat4 uProjectionMatrix;', + 'attribute vec2 inPosition;', + 'attribute vec2 inTexCoord;', + 'attribute float inTexId;', + 'attribute float inTintEffect;', + 'attribute vec4 inTint;', + 'varying vec2 outTexCoord;', + 'varying float outTexId;', + 'varying float outTintEffect;', + 'varying vec4 outTint;', + 'void main ()', + '{', + ' gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);', + ' outTexCoord = inTexCoord;', + ' outTexId = inTexId;', + ' outTint = inTint;', + ' outTintEffect = inTintEffect;', + '}', +].join('\n'); - var tintEffect = src.tintFill; - var getTint = Utils.getTintAppendFloatAlpha; +/***/ }), - var tintTL = getTint(src.tintTopLeft, cameraAlpha * src._alphaTL); - var tintTR = getTint(src.tintTopRight, cameraAlpha * src._alphaTR); - var tintBL = getTint(src.tintBottomLeft, cameraAlpha * src._alphaBL); - var tintBR = getTint(src.tintBottomRight, cameraAlpha * src._alphaBR); +/***/ 83327: +/***/ ((module) => { - var texture = src.frame.glTexture; - var textureUnit = pipeline.setGameObject(src); +module.exports = [ + '#define SHADER_NAME PHASER_POINTLIGHT_FS', + 'precision mediump float;', + 'uniform vec2 uResolution;', + 'uniform float uCameraZoom;', + 'varying vec4 lightPosition;', + 'varying vec4 lightColor;', + 'varying float lightRadius;', + 'varying float lightAttenuation;', + 'void main ()', + '{', + ' vec2 center = (lightPosition.xy + 1.0) * (uResolution.xy * 0.5);', + ' float distToSurf = length(center - gl_FragCoord.xy);', + ' float radius = 1.0 - distToSurf / (lightRadius * uCameraZoom);', + ' float intensity = smoothstep(0.0, 1.0, radius * lightAttenuation);', + ' vec4 color = vec4(intensity, intensity, intensity, 0.0) * lightColor;', + ' gl_FragColor = vec4(color.rgb * lightColor.a, color.a);', + '}', +].join('\n'); - // Update the bounds - skipped internally if not dirty - var bounds = src.getTextBounds(false); - var i; - var char; - var glyph; +/***/ }), - var characters = bounds.characters; +/***/ 54677: +/***/ ((module) => { - var dropShadowX = src.dropShadowX; - var dropShadowY = src.dropShadowY; +module.exports = [ + '#define SHADER_NAME PHASER_POINTLIGHT_VS', + 'precision mediump float;', + 'uniform mat4 uProjectionMatrix;', + 'attribute vec2 inPosition;', + 'attribute vec2 inLightPosition;', + 'attribute vec4 inLightColor;', + 'attribute float inLightRadius;', + 'attribute float inLightAttenuation;', + 'varying vec4 lightPosition;', + 'varying vec4 lightColor;', + 'varying float lightRadius;', + 'varying float lightAttenuation;', + 'void main ()', + '{', + ' lightColor = inLightColor;', + ' lightRadius = inLightRadius;', + ' lightAttenuation = inLightAttenuation;', + ' lightPosition = uProjectionMatrix * vec4(inLightPosition, 1.0, 1.0);', + ' gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);', + '}', +].join('\n'); - var dropShadow = (dropShadowX !== 0 || dropShadowY !== 0); - renderer.pipelines.preBatch(src); +/***/ }), - if (dropShadow) - { - var srcShadowColor = src.dropShadowColor; - var srcShadowAlpha = src.dropShadowAlpha; +/***/ 12569: +/***/ ((module) => { - var shadowTL = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaTL); - var shadowTR = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaTR); - var shadowBL = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaBL); - var shadowBR = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaBR); +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'); - for (i = 0; i < characters.length; i++) - { - char = characters[i]; - glyph = char.glyph; - if (char.code === 32 || glyph.width === 0 || glyph.height === 0) - { - continue; - } +/***/ }), - BatchChar(pipeline, src, char, glyph, dropShadowX, dropShadowY, calcMatrix, roundPixels, shadowTL, shadowTR, shadowBL, shadowBR, 1, texture, textureUnit); - } - } +/***/ 99365: +/***/ ((module) => { - for (i = 0; i < characters.length; i++) - { - char = characters[i]; - glyph = char.glyph; +module.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'); - if (char.code === 32 || glyph.width === 0 || glyph.height === 0) - { - continue; - } - if (charColors[char.i]) - { - var color = charColors[char.i]; +/***/ }), - var charTintEffect = color.tintEffect; - var charTintTL = getTint(color.tintTL, cameraAlpha * src._alphaTL); - var charTintTR = getTint(color.tintTR, cameraAlpha * src._alphaTR); - var charTintBL = getTint(color.tintBL, cameraAlpha * src._alphaBL); - var charTintBR = getTint(color.tintBR, cameraAlpha * src._alphaBR); +/***/ 85060: +/***/ ((module) => { - BatchChar(pipeline, src, char, glyph, 0, 0, calcMatrix, roundPixels, charTintTL, charTintTR, charTintBL, charTintBR, charTintEffect, texture, textureUnit); - } - else - { - BatchChar(pipeline, src, char, glyph, 0, 0, calcMatrix, roundPixels, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); - } +module.exports = [ + '#define SHADER_NAME PHASER_SINGLE_FS', + '#ifdef GL_FRAGMENT_PRECISION_HIGH', + 'precision highp float;', + '#else', + 'precision mediump float;', + '#endif', + 'uniform sampler2D uMainSampler;', + 'varying vec2 outTexCoord;', + 'varying float outTintEffect;', + 'varying vec4 outTint;', + 'void main ()', + '{', + ' vec4 texture = texture2D(uMainSampler, outTexCoord);', + ' vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);', + ' vec4 color = texture * texel;', + ' if (outTintEffect == 1.0)', + ' {', + ' color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);', + ' }', + ' else if (outTintEffect == 2.0)', + ' {', + ' color = texel;', + ' }', + ' gl_FragColor = color;', + '}', +].join('\n'); - // Debug test if the characters are in the correct place when rendered: - // pipeline.drawFillRect(tx0, ty0, tx2 - tx0, ty2 - ty0, 0x00ff00, 0.5); - } - renderer.pipelines.postBatch(src); -}; +/***/ }), -module.exports = BitmapTextWebGLRenderer; +/***/ 18166: +/***/ ((module) => { + +module.exports = [ + '#define SHADER_NAME PHASER_SINGLE_VS', + 'precision mediump float;', + 'uniform mat4 uProjectionMatrix;', + 'attribute vec2 inPosition;', + 'attribute vec2 inTexCoord;', + 'attribute float inTexId;', + 'attribute float inTintEffect;', + 'attribute vec4 inTint;', + 'varying vec2 outTexCoord;', + 'varying float outTintEffect;', + 'varying vec4 outTint;', + 'void main ()', + '{', + ' gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);', + ' outTexCoord = inTexCoord;', + ' outTint = inTint;', + ' outTintEffect = inTintEffect;', + '}', +].join('\n'); /***/ }), -/* 1047 */ -/***/ (function(module, exports) { + +/***/ 92462: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Renders one character of the Bitmap Text to the WebGL Pipeline. + * @namespace Phaser.Renderer.WebGL.Shaders + */ + +module.exports = { + + AddBlendFrag: __webpack_require__(2529), + BitmapMaskFrag: __webpack_require__(91679), + BitmapMaskVert: __webpack_require__(89053), + ColorMatrixFrag: __webpack_require__(37486), + CopyFrag: __webpack_require__(79060), + FXBarrelFrag: __webpack_require__(87751), + FXBloomFrag: __webpack_require__(88222), + FXBlurHighFrag: __webpack_require__(44481), + FXBlurLowFrag: __webpack_require__(35491), + FXBlurMedFrag: __webpack_require__(75568), + FXBokehFrag: __webpack_require__(69960), + FXCircleFrag: __webpack_require__(33754), + FXDisplacementFrag: __webpack_require__(35668), + FXGlowFrag: __webpack_require__(69675), + FXGradientFrag: __webpack_require__(90993), + FXPixelateFrag: __webpack_require__(37945), + FXShadowFrag: __webpack_require__(85718), + FXShineFrag: __webpack_require__(13740), + FXVignetteFrag: __webpack_require__(80617), + FXWipeFrag: __webpack_require__(62879), + LightFrag: __webpack_require__(65045), + LinearBlendFrag: __webpack_require__(98921), + MeshFrag: __webpack_require__(25005), + MeshVert: __webpack_require__(94914), + MobileFrag: __webpack_require__(11263), + MobileVert: __webpack_require__(51852), + MultiFrag: __webpack_require__(53787), + MultiVert: __webpack_require__(15968), + PointLightFrag: __webpack_require__(83327), + PointLightVert: __webpack_require__(54677), + PostFXFrag: __webpack_require__(12569), + QuadVert: __webpack_require__(99365), + SingleFrag: __webpack_require__(85060), + SingleVert: __webpack_require__(18166) + +}; + + +/***/ }), + +/***/ 756: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CONST = __webpack_require__(55301); +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(40444); +var GameEvents = __webpack_require__(97081); +var GetInnerHeight = __webpack_require__(74181); +var GetTarget = __webpack_require__(2893); +var GetScreenOrientation = __webpack_require__(9229); +var NOOP = __webpack_require__(72283); +var Rectangle = __webpack_require__(74118); +var Size = __webpack_require__(90881); +var SnapFloor = __webpack_require__(84314); +var Vector2 = __webpack_require__(93736); +var Camera = __webpack_require__(47751); + +/** + * @classdesc + * The Scale Manager handles the scaling, resizing and alignment of the game canvas. * - * @function BatchChar - * @since 3.50.0 - * @private + * 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. * - * @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The WebGLPipeline. Must have a `batchQuad` method. - * @param {Phaser.GameObjects.BitmapText} src - The BitmapText Game Object. - * @param {Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter} char - The character to render. - * @param {Phaser.Types.GameObjects.BitmapText.BitmapFontCharacterData} glyph - The character glyph. - * @param {number} offsetX - The x offset. - * @param {number} offsetY - The y offset. - * @param {Phaser.GameObjects.Components.TransformMatrix} calcMatrix - The transform matrix. - * @param {boolean} roundPixels - Round the transform values or not? - * @param {number} tintTL - Top-left tint value. - * @param {number} tintTR - Top-right tint value. - * @param {number} tintBL - Bottom-left tint value. - * @param {number} tintBR - Bottom-right tint value. - * @param {number} tintEffect - The tint effect mode. - * @param {WebGLTexture} texture - The WebGL texture. - * @param {number} textureUnit - The texture unit. + * 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 BatchChar = function (pipeline, src, char, glyph, offsetX, offsetY, calcMatrix, roundPixels, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit) -{ - var x = (char.x - src.displayOriginX) + offsetX; - var y = (char.y - src.displayOriginY) + offsetY; +var ScaleManager = new Class({ - var xw = x + char.w; - var yh = y + char.h; + Extends: EventEmitter, - var tx0 = calcMatrix.getXRound(x, y, roundPixels); - var ty0 = calcMatrix.getYRound(x, y, roundPixels); + initialize: - var tx1 = calcMatrix.getXRound(x, yh, roundPixels); - var ty1 = calcMatrix.getYRound(x, yh, roundPixels); + function ScaleManager (game) + { + EventEmitter.call(this); - var tx2 = calcMatrix.getXRound(xw, yh, roundPixels); - var ty2 = calcMatrix.getYRound(xw, yh, roundPixels); + /** + * A reference to the Phaser.Game instance. + * + * @name Phaser.Scale.ScaleManager#game + * @type {Phaser.Game} + * @readonly + * @since 3.15.0 + */ + this.game = game; - var tx3 = calcMatrix.getXRound(xw, y, roundPixels); - var ty3 = calcMatrix.getYRound(xw, y, roundPixels); + /** + * 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; - pipeline.batchQuad(src, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, glyph.u0, glyph.v0, glyph.u1, glyph.v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); -}; + /** + * The DOM bounds of the canvas element. + * + * @name Phaser.Scale.ScaleManager#canvasBounds + * @type {Phaser.Geom.Rectangle} + * @since 3.16.0 + */ + this.canvasBounds = new Rectangle(); -module.exports = BatchChar; + /** + * 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; -/***/ }), -/* 1048 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The Parent Size component. + * + * @name Phaser.Scale.ScaleManager#parentSize + * @type {Phaser.Structs.Size} + * @since 3.16.0 + */ + this.parentSize = new Size(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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(); -var SetTransform = __webpack_require__(30); + /** + * 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(); -/** - * 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.BitmapText#renderCanvas - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.BitmapText} 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 BitmapTextCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - var text = src._text; - var textLength = text.length; + /** + * 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(); - var ctx = renderer.currentContext; + /** + * The game scale mode. + * + * @name Phaser.Scale.ScaleManager#scaleMode + * @type {Phaser.Scale.ScaleModeType} + * @since 3.16.0 + */ + this.scaleMode = CONST.SCALE_MODE.NONE; - if (textLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - return; - } + /** + * 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; - camera.addToRenderList(src); + /** + * 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; - var textureFrame = src.fromAtlas - ? src.frame - : src.texture.frames['__BASE']; + /** + * 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; - var chars = src.fontData.chars; - var lineHeight = src.fontData.lineHeight; - var letterSpacing = src._letterSpacing; + /** + * 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; - var xAdvance = 0; - var yAdvance = 0; + /** + * A reference to the Device.Fullscreen object. + * + * @name Phaser.Scale.ScaleManager#fullscreen + * @type {Phaser.Device.Fullscreen} + * @since 3.16.0 + */ + this.fullscreen; - var charCode = 0; + /** + * The DOM Element which is sent into fullscreen mode. + * + * @name Phaser.Scale.ScaleManager#fullscreenTarget + * @type {?any} + * @since 3.16.0 + */ + this.fullscreenTarget = null; - var glyph = null; - var glyphX = 0; - var glyphY = 0; - var glyphW = 0; - var glyphH = 0; + /** + * 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; - var x = 0; - var y = 0; + /** + * 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; - var lastGlyph = null; - var lastCharCode = 0; + /** + * 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; - var image = textureFrame.source.image; + /** + * Internal size interval tracker. + * + * @name Phaser.Scale.ScaleManager#_lastCheck + * @type {number} + * @private + * @since 3.16.0 + */ + this._lastCheck = 0; - var textureX = textureFrame.cutX; - var textureY = textureFrame.cutY; + /** + * Internal flag to check orientation state. + * + * @name Phaser.Scale.ScaleManager#_checkOrientation + * @type {boolean} + * @private + * @since 3.16.0 + */ + this._checkOrientation = false; - var scale = (src._fontSize / src.fontData.size); + /** + * Internal object containing our defined event listeners. + * + * @name Phaser.Scale.ScaleManager#domlisteners + * @type {object} + * @private + * @since 3.16.0 + */ + this.domlisteners = { - var align = src._align; - var currentLine = 0; - var lineOffsetX = 0; + orientationChange: NOOP, + windowResize: NOOP, + fullScreenChange: NOOP, + fullScreenError: NOOP - // Update the bounds - skipped internally if not dirty - var bounds = src.getTextBounds(false); + }; + }, - // In case the method above changed it (word wrapping) - if (src.maxWidth > 0) + /** + * 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 () { - text = bounds.wrappedText; - textLength = text.length; - } + // Parse the config to get the scaling values we need + this.parseConfig(this.game.config); - var lineData = src._bounds.lines; + this.game.events.once(GameEvents.BOOT, this.boot, this); + }, - if (align === 1) - { - lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2; - } - else if (align === 2) + /** + * 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 () { - lineOffsetX = (lineData.longest - lineData.lengths[0]); - } + var game = this.game; - ctx.translate(-src.displayOriginX, -src.displayOriginY); + this.canvas = game.canvas; - var roundPixels = camera.roundPixels; + this.fullscreen = game.device.fullscreen; - for (var i = 0; i < textLength; i++) - { - charCode = text.charCodeAt(i); + if (this.scaleMode !== CONST.SCALE_MODE.RESIZE) + { + this.displaySize.setAspectMode(this.scaleMode); + } - if (charCode === 10) + if (this.scaleMode === CONST.SCALE_MODE.NONE) { - currentLine++; + this.resize(this.width, this.height); + } + else + { + this.getParentBounds(); - if (align === 1) - { - lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2; - } - else if (align === 2) + // Only set the parent bounds if the parent has an actual size + if (this.parentSize.width > 0 && this.parentSize.height > 0) { - lineOffsetX = (lineData.longest - lineData.lengths[currentLine]); + this.displaySize.setParent(this.parentSize); } - xAdvance = 0; - yAdvance += lineHeight; - lastGlyph = null; - - continue; + this.refresh(); } - glyph = chars[charCode]; + 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); - if (!glyph) - { - continue; - } + this.startListeners(); + }, - glyphX = textureX + glyph.x; - glyphY = textureY + glyph.y; + /** + * 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); - glyphW = glyph.width; - glyphH = glyph.height; + // Get the size of the parent element + // This can often set a height of zero (especially for un-styled divs) + this.getParentBounds(); - x = glyph.xOffset + xAdvance; - y = glyph.yOffset + yAdvance; + var width = config.width; + var height = config.height; + var scaleMode = config.scaleMode; + var zoom = config.zoom; + var autoRound = config.autoRound; - if (lastGlyph !== null) + // If width = '100%', or similar value + if (typeof width === 'string') { - var kerningOffset = glyph.kerning[lastCharCode]; - x += (kerningOffset !== undefined) ? kerningOffset : 0; - } - - x *= scale; - y *= scale; + // If we have a parent with a height, we'll work it out from that + var parentWidth = this.parentSize.width; - x += lineOffsetX; + if (parentWidth === 0) + { + parentWidth = window.innerWidth; + } - xAdvance += glyph.xAdvance + letterSpacing; - lastGlyph = glyph; - lastCharCode = charCode; + var parentScaleX = parseInt(width, 10) / 100; - // Nothing to render or a space? Then skip to the next glyph - if (glyphW === 0 || glyphH === 0 || charCode === 32) - { - continue; + width = Math.floor(parentWidth * parentScaleX); } - if (roundPixels) + // If height = '100%', or similar value + if (typeof height === 'string') { - x = Math.round(x); - y = Math.round(y); - } - - ctx.save(); - - ctx.translate(x, y); - - ctx.scale(scale, scale); - - ctx.drawImage(image, glyphX, glyphY, glyphW, glyphH, 0, 0, glyphW, glyphH); - - ctx.restore(); - } - - ctx.restore(); -}; - -module.exports = BitmapTextCanvasRenderer; - - -/***/ }), -/* 1049 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1050); -} - -if (true) -{ - renderCanvas = __webpack_require__(1051); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; - - -/***/ }), -/* 1050 */ -/***/ (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 Utils = __webpack_require__(12); - -var tempMatrix = 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.Blitter#renderWebGL - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Blitter} 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 BlitterWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - var list = src.getRenderList(); - - if (list.length === 0) - { - return; - } - - var alpha = camera.alpha * src.alpha; - - if (alpha === 0) - { - // Nothing to see, so abort early - return; - } - - camera.addToRenderList(src); - - var pipeline = renderer.pipelines.set(this.pipeline, src); + // If we have a parent with a height, we'll work it out from that + var parentHeight = this.parentSize.height; - var cameraScrollX = camera.scrollX * src.scrollFactorX; - var cameraScrollY = camera.scrollY * src.scrollFactorY; + if (parentHeight === 0) + { + parentHeight = window.innerHeight; + } - var calcMatrix = tempMatrix.copyFrom(camera.matrix); + var parentScaleY = parseInt(height, 10) / 100; - if (parentMatrix) - { - calcMatrix.multiplyWithOffset(parentMatrix, -cameraScrollX, -cameraScrollY); + height = Math.floor(parentHeight * parentScaleY); + } - cameraScrollX = 0; - cameraScrollY = 0; - } + this.scaleMode = scaleMode; - var blitterX = src.x - cameraScrollX; - var blitterY = src.y - cameraScrollY; - var prevTextureSourceIndex = -1; - var tintEffect = false; - var roundPixels = camera.roundPixels; + this.autoRound = autoRound; - renderer.pipelines.preBatch(src); + this.autoCenter = config.autoCenter; - for (var index = 0; index < list.length; index++) - { - var bob = list[index]; - var frame = bob.frame; - var bobAlpha = bob.alpha * alpha; + this.resizeInterval = config.resizeInterval; - if (bobAlpha === 0) + if (autoRound) { - continue; + width = Math.floor(width); + height = Math.floor(height); } - var width = frame.width; - var height = frame.height; - - var x = blitterX + bob.x + frame.x; - var y = blitterY + bob.y + frame.y; + // 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 (bob.flipX) + if (zoom === CONST.ZOOM.MAX_ZOOM) { - width *= -1; - x += frame.width; + zoom = this.getMaxZoom(); } - if (bob.flipY) + this.zoom = zoom; + + if (zoom !== 1) { - height *= -1; - y += frame.height; + this._resetZoom = true; } - var xw = x + width; - var yh = y + height; - - var tx0 = calcMatrix.getX(x, y); - var ty0 = calcMatrix.getY(x, y); - - var tx1 = calcMatrix.getX(xw, yh); - var ty1 = calcMatrix.getY(xw, yh); - - var tint = Utils.getTintAppendFloatAlpha(bob.tint, bobAlpha); + // The modified game size + this.baseSize.setSize(width, height); - // Bind texture only if the Texture Source is different from before - if (frame.sourceIndex !== prevTextureSourceIndex) + if (autoRound) { - var textureUnit = pipeline.setGameObject(src, frame); - - prevTextureSourceIndex = frame.sourceIndex; + this.baseSize.width = Math.floor(this.baseSize.width); + this.baseSize.height = Math.floor(this.baseSize.height); } - if (roundPixels) + if (config.minWidth > 0) { - tx0 = Math.round(tx0); - ty0 = Math.round(ty0); - - tx1 = Math.round(tx1); - ty1 = Math.round(ty1); + this.displaySize.setMin(config.minWidth * zoom, config.minHeight * zoom); } - // TL x/y, BL x/y, BR x/y, TR x/y - if (pipeline.batchQuad(src, tx0, ty0, tx0, ty1, tx1, ty1, tx1, ty0, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, tintEffect, frame.glTexture, textureUnit)) + if (config.maxWidth > 0) { - prevTextureSourceIndex = -1; + this.displaySize.setMax(config.maxWidth * zoom, config.maxHeight * zoom); } - } - - renderer.pipelines.postBatch(src); -}; -module.exports = BlitterWebGLRenderer; - - -/***/ }), -/* 1051 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // 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); -/** - * 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.Blitter#renderCanvas - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Blitter} 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 BlitterCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - var list = src.getRenderList(); + this.orientation = GetScreenOrientation(width, height); + }, - if (list.length === 0) + /** + * 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) { - return; - } - - var ctx = renderer.currentContext; + var parent = config.parent; - var alpha = camera.alpha * src.alpha; + if (parent === null) + { + // User is responsible for managing the parent + return; + } - if (alpha === 0) - { - // Nothing to see, so abort early - return; - } + this.parent = GetTarget(parent); + this.parentIsWindow = (this.parent === document.body); - camera.addToRenderList(src); + if (config.expandParent && config.scaleMode !== CONST.SCALE_MODE.NONE) + { + var DOMRect = this.parent.getBoundingClientRect(); - // Blend Mode + Scale Mode - ctx.globalCompositeOperation = renderer.blendModes[src.blendMode]; + if (this.parentIsWindow || DOMRect.height === 0) + { + document.documentElement.style.height = '100%'; + document.body.style.height = '100%'; - ctx.imageSmoothingEnabled = !(!renderer.antialias || src.frame.source.scaleMode); + DOMRect = this.parent.getBoundingClientRect(); - var cameraScrollX = src.x - camera.scrollX * src.scrollFactorX; - var cameraScrollY = src.y - camera.scrollY * src.scrollFactorY; + // 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%'; + } + } + } - ctx.save(); + // And now get the fullscreenTarget + if (config.fullscreenTarget && !this.fullscreenTarget) + { + this.fullscreenTarget = GetTarget(config.fullscreenTarget); + } + }, - if (parentMatrix) + /** + * Calculates the size of the parent bounds and updates the `parentSize` + * properties, only 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 or position, otherwise `false`. + */ + getParentBounds: function () { - parentMatrix.copyToContext(ctx); - } + if (!this.parent) + { + return false; + } - var roundPixels = camera.roundPixels; + var parentSize = this.parentSize; - // Render bobs - for (var i = 0; i < list.length; i++) - { - var bob = list[i]; - var flip = (bob.flipX || bob.flipY); - var frame = bob.frame; - var cd = frame.canvasData; - var dx = frame.x; - var dy = frame.y; - var fx = 1; - var fy = 1; + // Ref. http://msdn.microsoft.com/en-us/library/hh781509(v=vs.85).aspx for getBoundingClientRect - var bobAlpha = bob.alpha * alpha; + // The returned value is a DOMRect object which is the smallest rectangle which contains the entire element, + // including its padding and border-width. The left, top, right, bottom, x, y, width, and height properties + // describe the position and size of the overall rectangle in pixels. Properties other than width and height + // are relative to the top-left of the viewport. - if (bobAlpha === 0) + var DOMRect = this.parent.getBoundingClientRect(); + + if (this.parentIsWindow && this.game.device.os.iOS) { - continue; + DOMRect.height = GetInnerHeight(true); } - ctx.globalAlpha = bobAlpha; + var newWidth = DOMRect.width; + var newHeight = DOMRect.height; - if (!flip) + if (parentSize.width !== newWidth || parentSize.height !== newHeight) { - if (roundPixels) - { - dx = Math.round(dx); - dy = Math.round(dy); - } + parentSize.setSize(newWidth, newHeight); - ctx.drawImage( - frame.source.image, - cd.x, - cd.y, - cd.width, - cd.height, - dx + bob.x + cameraScrollX, - dy + bob.y + cameraScrollY, - cd.width, - cd.height - ); + return true; } - else + else if (this.canvas) { - if (bob.flipX) - { - fx = -1; - dx -= cd.width; - } + var canvasBounds = this.canvasBounds; + var canvasRect = this.canvas.getBoundingClientRect(); - if (bob.flipY) + if (canvasRect.x !== canvasBounds.x || canvasRect.y !== canvasBounds.y) { - fy = -1; - dy -= cd.height; + return true; } - - ctx.save(); - ctx.translate(bob.x + cameraScrollX, bob.y + cameraScrollY); - ctx.scale(fx, fy); - ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, dx, dy, cd.width, cd.height); - ctx.restore(); } - } - - ctx.restore(); -}; - -module.exports = BlitterCanvasRenderer; - - -/***/ }), -/* 1052 */ -/***/ (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 renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1053); -} - -if (true) -{ - renderCanvas = __webpack_require__(1054); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; - - -/***/ }), -/* 1053 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Renders this Game Object with the WebGL Renderer to the given Camera. - * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. - * This method should not be called directly. It is a utility function of the Render module. - * - * @method Phaser.GameObjects.Container#renderWebGL - * @since 3.4.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested - */ -var ContainerWebGLRenderer = function (renderer, container, camera, parentMatrix) -{ - camera.addToRenderList(container); - var children = container.list; - var childCount = children.length; - - if (childCount === 0) - { - return; - } - - var transformMatrix = container.localTransform; + return false; + }, - if (parentMatrix) - { - transformMatrix.loadIdentity(); - transformMatrix.multiply(parentMatrix); - transformMatrix.translate(container.x, container.y); - transformMatrix.rotate(container.rotation); - transformMatrix.scale(container.scaleX, container.scaleY); - } - else + /** + * 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) { - transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY); - } + var lock = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation; - renderer.pipelines.preBatch(container); + if (lock) + { + return lock.call(screen, orientation); + } - var containerHasBlendMode = (container.blendMode !== -1); + return false; + }, - if (!containerHasBlendMode) + /** + * 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) { - // If Container is SKIP_TEST then set blend mode to be Normal - renderer.setBlendMode(0); - } - - var alpha = container.alpha; + this.parentSize.setSize(width, height); - var scrollFactorX = container.scrollFactorX; - var scrollFactorY = container.scrollFactorY; + return this.refresh(); + }, - for (var i = 0; i < childCount; i++) + /** + * 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 child = children[i]; + var autoRound = this.autoRound; - if (!child.willRender(camera)) + if (autoRound) { - continue; + width = Math.floor(width); + height = Math.floor(height); } - var childAlphaTopLeft; - var childAlphaTopRight; - var childAlphaBottomLeft; - var childAlphaBottomRight; - - if (child.alphaTopLeft !== undefined) - { - childAlphaTopLeft = child.alphaTopLeft; - childAlphaTopRight = child.alphaTopRight; - childAlphaBottomLeft = child.alphaBottomLeft; - childAlphaBottomRight = child.alphaBottomRight; - } - else - { - var childAlpha = child.alpha; + var previousWidth = this.width; + var previousHeight = this.height; - childAlphaTopLeft = childAlpha; - childAlphaTopRight = childAlpha; - childAlphaBottomLeft = childAlpha; - childAlphaBottomRight = childAlpha; - } + // 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); - var childScrollFactorX = child.scrollFactorX; - var childScrollFactorY = child.scrollFactorY; + // The modified game size + this.baseSize.resize(width, height); - if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode) + if (autoRound) { - // If Container doesn't have its own blend mode, then a child can have one - renderer.setBlendMode(child.blendMode); + this.baseSize.width = Math.floor(this.baseSize.width); + this.baseSize.height = Math.floor(this.baseSize.height); } - var mask = child.mask; + // 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); - if (mask) - { - mask.preRenderWebGL(renderer, child, camera); - } + this.canvas.width = this.baseSize.width; + this.canvas.height = this.baseSize.height; - var type = child.type; + return this.refresh(previousWidth, previousHeight); + }, - if (type !== renderer.currentType) + /** + * 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) { - renderer.newType = true; - renderer.currentType = type; + width = Math.floor(width); + height = Math.floor(height); } - renderer.nextTypeMatch = (i < childCount - 1) ? (children[i + 1].type === renderer.currentType) : false; - - // Set parent values - child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY); - - child.setAlpha(childAlphaTopLeft * alpha, childAlphaTopRight * alpha, childAlphaBottomLeft * alpha, childAlphaBottomRight * alpha); - - // Render - child.renderWebGL(renderer, child, camera, transformMatrix); - - // Restore original values + var previousWidth = this.width; + var previousHeight = this.height; - child.setAlpha(childAlphaTopLeft, childAlphaTopRight, childAlphaBottomLeft, childAlphaBottomRight); + // 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); - child.setScrollFactor(childScrollFactorX, childScrollFactorY); + // The modified game size + this.baseSize.resize(width, height); - if (mask) + if (autoRound) { - mask.postRenderWebGL(renderer, camera); + this.baseSize.width = Math.floor(this.baseSize.width); + this.baseSize.height = Math.floor(this.baseSize.height); } - renderer.newType = false; - } - - renderer.pipelines.postBatch(container); -}; - -module.exports = ContainerWebGLRenderer; - - -/***/ }), -/* 1054 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Renders this Game Object with the Canvas Renderer to the given Camera. - * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. - * This method should not be called directly. It is a utility function of the Render module. - * - * @method Phaser.GameObjects.Container#renderCanvas - * @since 3.4.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Container} container - The Game Object being rendered in this call. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. - * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested - */ -var ContainerCanvasRenderer = function (renderer, container, camera, parentMatrix) -{ - camera.addToRenderList(container); - - var children = container.list; - - if (children.length === 0) - { - return; - } - - var transformMatrix = container.localTransform; - - if (parentMatrix) - { - transformMatrix.loadIdentity(); - transformMatrix.multiply(parentMatrix); - transformMatrix.translate(container.x, container.y); - transformMatrix.rotate(container.rotation); - transformMatrix.scale(container.scaleX, container.scaleY); - } - else - { - transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY); - } - - var containerHasBlendMode = (container.blendMode !== -1); - - if (!containerHasBlendMode) - { - // If Container is SKIP_TEST then set blend mode to be Normal - renderer.setBlendMode(0); - } + // 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)); - var alpha = container._alpha; - var scrollFactorX = container.scrollFactorX; - var scrollFactorY = container.scrollFactorY; + this.canvas.width = this.baseSize.width; + this.canvas.height = this.baseSize.height; - if (container.mask) - { - container.mask.preRenderCanvas(renderer, null, camera); - } + var style = this.canvas.style; - for (var i = 0; i < children.length; i++) - { - var child = children[i]; + var styleWidth = width * zoom; + var styleHeight = height * zoom; - if (!child.willRender(camera)) + if (autoRound) { - continue; + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); } - var childAlpha = child.alpha; - var childScrollFactorX = child.scrollFactorX; - var childScrollFactorY = child.scrollFactorY; - - if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode) + if (styleWidth !== width || styleHeight !== height) { - // If Container doesn't have its own blend mode, then a child can have one - renderer.setBlendMode(child.blendMode); + style.width = styleWidth + 'px'; + style.height = styleHeight + 'px'; } - // Set parent values - child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY); - child.setAlpha(childAlpha * alpha); + return this.refresh(previousWidth, previousHeight); + }, - // Render - child.renderCanvas(renderer, child, camera, transformMatrix); + /** + * 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; - // Restore original values - child.setAlpha(childAlpha); - child.setScrollFactor(childScrollFactorX, childScrollFactorY); - } + return this.refresh(); + }, - if (container.mask) + /** + * 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) { - container.mask.postRenderCanvas(renderer); - } -}; - -module.exports = ContainerCanvasRenderer; - + if (previousWidth === undefined) { previousWidth = this.width; } + if (previousHeight === undefined) { previousHeight = this.height; } -/***/ }), -/* 1055 */ -/***/ (function(module, exports, __webpack_require__) { + this.updateScale(); + this.updateBounds(); + this.updateOrientation(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.displayScale.set(this.baseSize.width / this.canvasBounds.width, this.baseSize.height / this.canvasBounds.height); -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + var domContainer = this.game.domContainer; -if (true) -{ - renderWebGL = __webpack_require__(443); -} + if (domContainer) + { + this.baseSize.setCSS(domContainer); -if (true) -{ - renderCanvas = __webpack_require__(443); -} + var canvasStyle = this.canvas.style; + var domStyle = domContainer.style; -module.exports = { + domStyle.transform = 'scale(' + this.displaySize.width / this.baseSize.width + ',' + this.displaySize.height / this.baseSize.height + ')'; - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + domStyle.marginLeft = canvasStyle.marginLeft; + domStyle.marginTop = canvasStyle.marginTop; + } -}; + this.emit(Events.RESIZE, this.gameSize, this.baseSize, this.displaySize, previousWidth, previousHeight); + return this; + }, -/***/ }), -/* 1056 */ -/***/ (function(module, exports) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var newOrientation = GetScreenOrientation(this.width, this.height); -/** - * Phaser Blend Modes to CSS Blend Modes Map. - * - * @name Phaser.CSSBlendModes - * @ignore - * @enum {string} - * @memberof Phaser - * @readonly - * @since 3.12.0 - */ + if (newOrientation !== this.orientation) + { + this.orientation = newOrientation; -module.exports = [ - 'normal', - 'multiply', - 'multiply', - 'screen', - 'overlay', - 'darken', - 'lighten', - 'color-dodge', - 'color-burn', - 'hard-light', - 'soft-light', - 'difference', - 'exclusion', - 'hue', - 'saturation', - 'color', - 'luminosity' -]; + 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; -/***/ }), -/* 1057 */ -/***/ (function(module, exports, __webpack_require__) { + var width = this.gameSize.width; + var height = this.gameSize.height; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var styleWidth; + var styleHeight; -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + var zoom = this.zoom; + var autoRound = this.autoRound; -if (true) -{ - renderWebGL = __webpack_require__(1058); -} + if (this.scaleMode === CONST.SCALE_MODE.NONE) + { + // No scale + this.displaySize.setSize((width * zoom), (height * zoom)); -if (true) -{ - renderCanvas = __webpack_require__(1059); -} + styleWidth = this.displaySize.width; + styleHeight = this.displaySize.height; -module.exports = { + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + 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); -/***/ }), -/* 1058 */ -/***/ (function(module, exports, __webpack_require__) { + this.gameSize.setSize(this.displaySize.width, this.displaySize.height); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.baseSize.setSize(this.displaySize.width, this.displaySize.height); -var GetCalcMatrix = __webpack_require__(19); -var TransformMatrix = __webpack_require__(25); -var Utils = __webpack_require__(12); + styleWidth = this.displaySize.width; + styleHeight = this.displaySize.height; -var tempMatrix = new TransformMatrix(); + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } -/** - * 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.DynamicBitmapText#renderWebGL - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.DynamicBitmapText} 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 DynamicBitmapTextWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - var text = src.text; - var textLength = text.length; + this.canvas.width = styleWidth; + this.canvas.height = styleHeight; + } + else + { + // All other scale modes + this.displaySize.setSize(this.parentSize.width, this.parentSize.height); - if (textLength === 0) - { - return; - } + styleWidth = this.displaySize.width; + styleHeight = this.displaySize.height; - camera.addToRenderList(src); + if (autoRound) + { + styleWidth = Math.floor(styleWidth); + styleHeight = Math.floor(styleHeight); + } - var pipeline = renderer.pipelines.set(src.pipeline, src); + style.width = styleWidth + 'px'; + style.height = styleHeight + 'px'; + } - var result = GetCalcMatrix(src, camera, parentMatrix); + // Update the parentSize in case the canvas / style change modified it + this.getParentBounds(); - var spriteMatrix = result.sprite; - var calcMatrix = result.calc; + // Finally, update the centering + this.updateCenter(); + }, - var fontMatrix = tempMatrix; + /** + * 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); - var crop = (src.cropWidth > 0 || src.cropHeight > 0); + return Math.max(Math.min(zoomH, zoomV), 1); + }, - if (crop) + /** + * 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 () { - pipeline.flush(); + var autoCenter = this.autoCenter; - renderer.pushScissor( - calcMatrix.tx, - calcMatrix.ty, - src.cropWidth * calcMatrix.scaleX, - src.cropHeight * calcMatrix.scaleY - ); - } + if (autoCenter === CONST.CENTER.NO_CENTER) + { + return; + } - var frame = src.frame; - var texture = frame.glTexture; + var canvas = this.canvas; - var tintEffect = src.tintFill; - var tintTL = Utils.getTintAppendFloatAlpha(src.tintTopLeft, camera.alpha * src._alphaTL); - var tintTR = Utils.getTintAppendFloatAlpha(src.tintTopRight, camera.alpha * src._alphaTR); - var tintBL = Utils.getTintAppendFloatAlpha(src.tintBottomLeft, camera.alpha * src._alphaBL); - var tintBR = Utils.getTintAppendFloatAlpha(src.tintBottomRight, camera.alpha * src._alphaBR); + var style = canvas.style; - var textureUnit = pipeline.setGameObject(src); + var bounds = canvas.getBoundingClientRect(); - var xAdvance = 0; - var yAdvance = 0; - var charCode = 0; - var lastCharCode = 0; - var letterSpacing = src.letterSpacing; - var glyph; - var glyphW = 0; - var glyphH = 0; - var lastGlyph; - var scrollX = src.scrollX; - var scrollY = src.scrollY; + // var width = parseInt(canvas.style.width, 10) || canvas.width; + // var height = parseInt(canvas.style.height, 10) || canvas.height; - var fontData = src.fontData; - var chars = fontData.chars; - var lineHeight = fontData.lineHeight; - var scale = (src.fontSize / fontData.size); - var rotation = 0; + var width = bounds.width; + var height = bounds.height; - var align = src._align; - var currentLine = 0; - var lineOffsetX = 0; + var offsetX = Math.floor((this.parentSize.width - width) / 2); + var offsetY = Math.floor((this.parentSize.height - height) / 2); - // Update the bounds - skipped internally if not dirty - var bounds = src.getTextBounds(false); + if (autoCenter === CONST.CENTER.CENTER_HORIZONTALLY) + { + offsetY = 0; + } + else if (autoCenter === CONST.CENTER.CENTER_VERTICALLY) + { + offsetX = 0; + } - // In case the method above changed it (word wrapping) - if (src.maxWidth > 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 () { - text = bounds.wrappedText; - textLength = text.length; - } + var bounds = this.canvasBounds; + var clientRect = this.canvas.getBoundingClientRect(); - var lineData = src._bounds.lines; + 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; + }, - if (align === 1) + /** + * 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) { - lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2; - } - else if (align === 2) + 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) { - lineOffsetX = (lineData.longest - lineData.lengths[0]); - } + return (pageY - this.canvasBounds.top) * this.displayScale.y; + }, - var roundPixels = camera.roundPixels; - var displayCallback = src.displayCallback; - var callbackData = src.callbackData; + /** + * 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' }; } - renderer.pipelines.preBatch(src); + var fullscreen = this.fullscreen; - for (var i = 0; i < textLength; i++) - { - charCode = text.charCodeAt(i); + if (!fullscreen.available) + { + this.emit(Events.FULLSCREEN_UNSUPPORTED); - // Carriage-return - if (charCode === 10) + return; + } + + if (!fullscreen.active) { - currentLine++; + var fsTarget = this.getFullscreenTarget(); - if (align === 1) + if (fullscreen.keyboard) { - lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2; + fsTarget[fullscreen.request](Element.ALLOW_KEYBOARD_INPUT); } - else if (align === 2) + else { - lineOffsetX = (lineData.longest - lineData.lengths[currentLine]); + fsTarget[fullscreen.request](fullscreenOptions); } + } + }, - xAdvance = 0; - yAdvance += lineHeight; - lastGlyph = null; + /** + * 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(); - continue; - } + this.refresh(); - glyph = chars[charCode]; + this.emit(Events.ENTER_FULLSCREEN); + }, - if (!glyph) + /** + * 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) { - continue; - } + var fsTarget = document.createElement('div'); - glyphW = glyph.width; - glyphH = glyph.height; + fsTarget.style.margin = '0'; + fsTarget.style.padding = '0'; + fsTarget.style.width = '100%'; + fsTarget.style.height = '100%'; - var x = (glyph.xOffset + xAdvance) - scrollX; - var y = (glyph.yOffset + yAdvance) - scrollY; + this.fullscreenTarget = fsTarget; - if (lastGlyph !== null) - { - var kerningOffset = glyph.kerning[lastCharCode]; - x += (kerningOffset !== undefined) ? kerningOffset : 0; + this._createdFullscreenTarget = true; } - xAdvance += glyph.xAdvance + letterSpacing; - lastGlyph = glyph; - lastCharCode = charCode; - - // Nothing to render or a space? Then skip to the next glyph - if (glyphW === 0 || glyphH === 0 || charCode === 32) + if (this._createdFullscreenTarget) { - continue; + var canvasParent = this.canvas.parentNode; + + canvasParent.insertBefore(this.fullscreenTarget, this.canvas); + + this.fullscreenTarget.appendChild(this.canvas); } - scale = (src.fontSize / src.fontData.size); - rotation = 0; + return this.fullscreenTarget; + }, - if (displayCallback) + /** + * Removes the fullscreen target that was added to the DOM. + * + * @method Phaser.Scale.ScaleManager#removeFullscreenTarget + * @since 3.17.0 + */ + removeFullscreenTarget: function () + { + if (this._createdFullscreenTarget) { - callbackData.color = 0; - callbackData.tint.topLeft = tintTL; - callbackData.tint.topRight = tintTR; - callbackData.tint.bottomLeft = tintBL; - callbackData.tint.bottomRight = tintBR; - callbackData.index = i; - callbackData.charCode = charCode; - callbackData.x = x; - callbackData.y = y; - callbackData.scale = scale; - callbackData.rotation = rotation; - callbackData.data = glyph.data; + var fsTarget = this.fullscreenTarget; - var output = displayCallback(callbackData); + if (fsTarget && fsTarget.parentNode) + { + var parent = fsTarget.parentNode; - x = output.x; - y = output.y; - scale = output.scale; - rotation = output.rotation; + parent.insertBefore(this.canvas, fsTarget); - if (output.color) - { - tintTL = output.color; - tintTR = output.color; - tintBL = output.color; - tintBR = output.color; - } - else - { - tintTL = output.tint.topLeft; - tintTR = output.tint.topRight; - tintBL = output.tint.bottomLeft; - tintBR = output.tint.bottomRight; + parent.removeChild(fsTarget); } - - tintTL = Utils.getTintAppendFloatAlpha(tintTL, camera.alpha * src._alphaTL); - tintTR = Utils.getTintAppendFloatAlpha(tintTR, camera.alpha * src._alphaTR); - tintBL = Utils.getTintAppendFloatAlpha(tintBL, camera.alpha * src._alphaBL); - tintBR = Utils.getTintAppendFloatAlpha(tintBR, camera.alpha * src._alphaBR); } + }, - x *= scale; - y *= scale; - - x -= src.displayOriginX; - y -= src.displayOriginY; - - x += lineOffsetX; - - fontMatrix.applyITRS(x, y, rotation, scale, scale); + /** + * 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; - calcMatrix.multiply(fontMatrix, spriteMatrix); + if (!fullscreen.available) + { + this.emit(Events.FULLSCREEN_UNSUPPORTED); - var u0 = glyph.u0; - var v0 = glyph.v0; - var u1 = glyph.u1; - var v1 = glyph.v1; + return false; + } - var xw = glyphW; - var yh = glyphH; + if (fullscreen.active) + { + document[fullscreen.cancel](); + } - var tx0 = spriteMatrix.e; - var ty0 = spriteMatrix.f; + this.removeFullscreenTarget(); - var tx1 = yh * spriteMatrix.c + spriteMatrix.e; - var ty1 = yh * spriteMatrix.d + spriteMatrix.f; + // Get the parent size again as it will have changed + this.getParentBounds(); - var tx2 = xw * spriteMatrix.a + yh * spriteMatrix.c + spriteMatrix.e; - var ty2 = xw * spriteMatrix.b + yh * spriteMatrix.d + spriteMatrix.f; + this.emit(Events.LEAVE_FULLSCREEN); - var tx3 = xw * spriteMatrix.a + spriteMatrix.e; - var ty3 = xw * spriteMatrix.b + spriteMatrix.f; + this.refresh(); + }, - if (roundPixels) + /** + * 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) { - tx0 = Math.round(tx0); - ty0 = Math.round(ty0); - - tx1 = Math.round(tx1); - ty1 = Math.round(ty1); - - tx2 = Math.round(tx2); - ty2 = Math.round(ty2); - - tx3 = Math.round(tx3); - ty3 = Math.round(ty3); + this.stopFullscreen(); } + else + { + this.startFullscreen(fullscreenOptions); + } + }, - pipeline.batchQuad(src, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit); - } - - if (crop) + /** + * An internal method that starts the different DOM event listeners running. + * + * @method Phaser.Scale.ScaleManager#startListeners + * @since 3.16.0 + */ + startListeners: function () { - pipeline.flush(); + var _this = this; + var listeners = this.domlisteners; - renderer.popScissor(); - } + listeners.orientationChange = function () + { + _this.updateBounds(); - renderer.pipelines.postBatch(src); -}; + _this._checkOrientation = true; + _this.dirty = true; + }; -module.exports = DynamicBitmapTextWebGLRenderer; + listeners.windowResize = function () + { + _this.updateBounds(); + _this.dirty = true; + }; -/***/ }), -/* 1059 */ -/***/ (function(module, exports, __webpack_require__) { + // Only dispatched on mobile devices + window.addEventListener('orientationchange', listeners.orientationChange, false); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + window.addEventListener('resize', listeners.windowResize, false); -var SetTransform = __webpack_require__(30); + if (this.fullscreen.available) + { + listeners.fullScreenChange = function (event) + { + return _this.onFullScreenChange(event); + }; -/** - * 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.DynamicBitmapText#renderCanvas - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.DynamicBitmapText} 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 DynamicBitmapTextCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - var text = src._text; - var textLength = text.length; + listeners.fullScreenError = function (event) + { + return _this.onFullScreenError(event); + }; - var ctx = renderer.currentContext; + var vendors = [ 'webkit', 'moz', '' ]; - if (textLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) + 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 () { - return; - } + if (document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement || document.mozFullScreenElement) + { + this.fullscreenSuccessHandler(); + } + else + { + // They pressed ESC while in fullscreen mode + this.stopFullscreen(); + } + }, - camera.addToRenderList(src); + /** + * Triggered when a fullscreenerror event is dispatched by the DOM. + * + * @method Phaser.Scale.ScaleManager#onFullScreenError + * @since 3.16.0 + */ + onFullScreenError: function () + { + this.removeFullscreenTarget(); + }, - var textureFrame = src.fromAtlas - ? src.frame - : src.texture.frames['__BASE']; + /** + * Get Rectange of visible area. + * + * @method Phaser.Scale.ScaleManager#getViewPort + * @since 3.60.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The camera this viewport is respond upon. + * @param {Phaser.Geom.Rectangle} [out] - The Rectangle of visible area. + * + * @return {Phaser.Geom.Rectangle} The Rectangle of visible area. + */ + getViewPort: function (camera, out) + { + if (!(camera instanceof Camera)) + { + out = camera; + camera = undefined; + } - var displayCallback = src.displayCallback; - var callbackData = src.callbackData; + if (out === undefined) + { + out = new Rectangle(); + } - var chars = src.fontData.chars; - var lineHeight = src.fontData.lineHeight; - var letterSpacing = src._letterSpacing; + var baseSize = this.baseSize; + var parentSize = this.parentSize; + var canvasBounds = this.canvasBounds; + var displayScale = this.displayScale; - var xAdvance = 0; - var yAdvance = 0; + var x = (canvasBounds.x >= 0) ? 0 : -(canvasBounds.x * displayScale.x); - var charCode = 0; + var y = (canvasBounds.y >= 0) ? 0 : -(canvasBounds.y * displayScale.y); - var glyph = null; - var glyphX = 0; - var glyphY = 0; - var glyphW = 0; - var glyphH = 0; + var width; + if (parentSize.width >= canvasBounds.width) + { + width = baseSize.width; + } + else + { + width = baseSize.width - (canvasBounds.width - parentSize.width) * displayScale.x; + } - var x = 0; - var y = 0; + var height; + if (parentSize.height >= canvasBounds.height) + { + height = baseSize.height; + } + else + { + height = baseSize.height - (canvasBounds.height - parentSize.height) * displayScale.y; + } - var lastGlyph = null; - var lastCharCode = 0; + out.setTo(x, y, width, height); - var image = src.frame.source.image; + if (camera) + { + out.width /= camera.zoomX; + out.height /= camera.zoomY; + out.centerX = camera.centerX + camera.scrollX; + out.centerY = camera.centerY + camera.scrollY; + } - var textureX = textureFrame.cutX; - var textureY = textureFrame.cutY; + return out; + }, - var rotation = 0; - var scale = 0; - var baseScale = (src._fontSize / src.fontData.size); + /** + * 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; + } - var align = src._align; - var currentLine = 0; - var lineOffsetX = 0; + this._lastCheck += delta; - // Update the bounds - skipped internally if not dirty - src.getTextBounds(false); + if (this.dirty || this._lastCheck > this.resizeInterval) + { + // Returns true if the parent bounds have changed size + if (this.getParentBounds()) + { + this.refresh(); + } - var lineData = src._bounds.lines; + this.dirty = false; + this._lastCheck = 0; + } + }, - if (align === 1) - { - lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2; - } - else if (align === 2) + /** + * Stops all DOM event listeners. + * + * @method Phaser.Scale.ScaleManager#stopListeners + * @since 3.16.0 + */ + stopListeners: function () { - lineOffsetX = (lineData.longest - lineData.lengths[0]); - } + var listeners = this.domlisteners; - ctx.translate(-src.displayOriginX, -src.displayOriginY); + window.removeEventListener('orientationchange', listeners.orientationChange, false); + window.removeEventListener('resize', listeners.windowResize, false); - var roundPixels = camera.roundPixels; + var vendors = [ 'webkit', 'moz', '' ]; - if (src.cropWidth > 0 && src.cropHeight > 0) - { - ctx.beginPath(); - ctx.rect(0, 0, src.cropWidth, src.cropHeight); - ctx.clip(); - } + vendors.forEach(function (prefix) + { + document.removeEventListener(prefix + 'fullscreenchange', listeners.fullScreenChange, false); + document.removeEventListener(prefix + 'fullscreenerror', listeners.fullScreenError, false); + }); - for (var i = 0; i < textLength; i++) + // 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 () { - // Reset the scale (in case the callback changed it) - scale = baseScale; - rotation = 0; + this.removeAllListeners(); - charCode = text.charCodeAt(i); + this.stopListeners(); - if (charCode === 10) - { - currentLine++; + this.game = null; + this.canvas = null; + this.canvasBounds = null; + this.parent = null; + this.fullscreenTarget = null; - if (align === 1) - { - lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2; - } - else if (align === 2) - { - lineOffsetX = (lineData.longest - lineData.lengths[currentLine]); - } + this.parentSize.destroy(); + this.gameSize.destroy(); + this.baseSize.destroy(); + this.displaySize.destroy(); + }, - xAdvance = 0; - yAdvance += lineHeight; - lastGlyph = null; + /** + * Is the browser currently in fullscreen mode or not? + * + * @name Phaser.Scale.ScaleManager#isFullscreen + * @type {boolean} + * @readonly + * @since 3.16.0 + */ + isFullscreen: { - continue; + get: function () + { + return this.fullscreen.active; } - glyph = chars[charCode]; + }, - if (!glyph) + /** + * 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 () { - continue; + return this.gameSize.width; } - glyphX = textureX + glyph.x; - glyphY = textureY + glyph.y; - - glyphW = glyph.width; - glyphH = glyph.height; + }, - x = (glyph.xOffset + xAdvance) - src.scrollX; - y = (glyph.yOffset + yAdvance) - src.scrollY; + /** + * 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: { - if (lastGlyph !== null) + get: function () { - var kerningOffset = glyph.kerning[lastCharCode]; - x += (kerningOffset !== undefined) ? kerningOffset : 0; + return this.gameSize.height; } - if (displayCallback) - { - callbackData.index = i; - callbackData.charCode = charCode; - callbackData.x = x; - callbackData.y = y; - callbackData.scale = scale; - callbackData.rotation = rotation; - callbackData.data = glyph.data; + }, - var output = displayCallback(callbackData); + /** + * 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: { - x = output.x; - y = output.y; - scale = output.scale; - rotation = output.rotation; + get: function () + { + return (this.orientation === CONST.ORIENTATION.PORTRAIT); } - x *= scale; - y *= scale; - - x += lineOffsetX; + }, - xAdvance += glyph.xAdvance + letterSpacing; - lastGlyph = glyph; - lastCharCode = charCode; + /** + * 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: { - // Nothing to render or a space? Then skip to the next glyph - if (glyphW === 0 || glyphH === 0 || charCode === 32) + get: function () { - continue; + return (this.orientation === CONST.ORIENTATION.LANDSCAPE); } - if (roundPixels) - { - x = Math.round(x); - y = Math.round(y); - } + }, - ctx.save(); + /** + * 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: { - ctx.translate(x, y); + get: function () + { + return (this.height > this.width); + } - ctx.rotate(rotation); + }, - ctx.scale(scale, scale); + /** + * 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: { - ctx.drawImage(image, glyphX, glyphY, glyphW, glyphH, 0, 0, glyphW, glyphH); + get: function () + { + return (this.width > this.height); + } - ctx.restore(); } - ctx.restore(); -}; +}); -module.exports = DynamicBitmapTextCanvasRenderer; +module.exports = ScaleManager; /***/ }), -/* 1060 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 35098: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1061); -} - -if (true) -{ - renderCanvas = __webpack_require__(1062); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; - - -/***/ }), -/* 1061 */ -/***/ (function(module, exports, __webpack_require__) { - /** - * @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 */ -var GetCalcMatrix = __webpack_require__(19); - /** - * 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. + * Phaser Scale Manager constants for centering the game canvas. * - * @method Phaser.GameObjects.Extern#renderWebGL - * @since 3.16.0 - * @private + * To find out what each mode does please see [Phaser.Scale.Center]{@link Phaser.Scale.Center}. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Extern} 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 + * @typedef {Phaser.Scale.Center} Phaser.Scale.CenterType + * @memberof Phaser.Scale + * @since 3.16.0 */ -var ExternWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - renderer.pipelines.clear(); - - var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; - src.render.call(src, renderer, camera, calcMatrix); +module.exports = { - renderer.pipelines.rebind(); -}; + /** + * 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, -module.exports = ExternWebGLRenderer; + /** + * 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, -/***/ }), -/* 1062 */ -/***/ (function(module, exports) { + /** + * 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 +}; /***/ }), -/* 1063 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 53539: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1064); - - // Needed for Graphics.generateTexture - renderCanvas = __webpack_require__(448); -} +/** + * Phaser Scale Manager constants for orientation. + * + * @namespace Phaser.Scale.Orientation + * @memberof Phaser.Scale + * @since 3.16.0 + */ -if (true) -{ - renderCanvas = __webpack_require__(448); -} +/** + * 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 = { - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + /** + * 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' }; /***/ }), -/* 1064 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 12637: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Commands = __webpack_require__(217); -var GetCalcMatrix = __webpack_require__(19); -var TransformMatrix = __webpack_require__(25); -var Utils = __webpack_require__(12); - -var Point = function (x, y, width) -{ - this.x = x; - this.y = y; - this.width = width; -}; - -var Path = function (x, y, width) -{ - this.points = []; - this.pointsLength = 1; - this.points[0] = new Point(x, y, width); -}; - -var matrixStack = []; -var tempMatrix = new TransformMatrix(); +/** + * Phaser Scale Manager constants for the different scale modes available. + * + * @namespace Phaser.Scale.ScaleModes + * @memberof Phaser.Scale + * @since 3.16.0 + */ /** - * 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. + * Phaser Scale Manager constants for the different scale modes available. * - * @method Phaser.GameObjects.Graphics#renderWebGL - * @since 3.0.0 - * @private + * To find out what each mode does please see [Phaser.Scale.ScaleModes]{@link Phaser.Scale.ScaleModes}. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL 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 + * @typedef {Phaser.Scale.ScaleModes} Phaser.Scale.ScaleModeType + * @memberof Phaser.Scale + * @since 3.16.0 */ -var GraphicsWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - if (src.commandBuffer.length === 0) - { - return; - } - camera.addToRenderList(src); - - var pipeline = renderer.pipelines.set(src.pipeline, src); - - renderer.pipelines.preBatch(src); - - var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; - - var currentMatrix = tempMatrix.loadIdentity(); - - var commands = src.commandBuffer; - var alpha = camera.alpha * src.alpha; - - var lineWidth = 1; - var fillTint = pipeline.fillTint; - var strokeTint = pipeline.strokeTint; - - var tx = 0; - var ty = 0; - var ta = 0; - var iterStep = 0.01; - var PI2 = Math.PI * 2; - - var cmd; - - var path = []; - var pathIndex = 0; - var pathOpen = true; - var lastPath = null; - - var getTint = Utils.getTintAppendFloatAlpha; - - for (var cmdIndex = 0; cmdIndex < commands.length; cmdIndex++) - { - cmd = commands[cmdIndex]; - - switch (cmd) - { - case Commands.BEGIN_PATH: - { - path.length = 0; - lastPath = null; - pathOpen = true; - break; - } - - case Commands.CLOSE_PATH: - { - pathOpen = false; - - if (lastPath && lastPath.points.length) - { - lastPath.points.push(lastPath.points[0]); - } - break; - } - - case Commands.FILL_PATH: - { - for (pathIndex = 0; pathIndex < path.length; pathIndex++) - { - pipeline.batchFillPath( - path[pathIndex].points, - currentMatrix, - calcMatrix - ); - } - break; - } - - case Commands.STROKE_PATH: - { - for (pathIndex = 0; pathIndex < path.length; pathIndex++) - { - pipeline.batchStrokePath( - path[pathIndex].points, - lineWidth, - pathOpen, - currentMatrix, - calcMatrix - ); - } - break; - } - - case Commands.LINE_STYLE: - { - lineWidth = commands[++cmdIndex]; - var strokeColor = commands[++cmdIndex]; - var strokeAlpha = commands[++cmdIndex] * alpha; - var strokeTintColor = getTint(strokeColor, strokeAlpha); - strokeTint.TL = strokeTintColor; - strokeTint.TR = strokeTintColor; - strokeTint.BL = strokeTintColor; - strokeTint.BR = strokeTintColor; - break; - } - - case Commands.FILL_STYLE: - { - var fillColor = commands[++cmdIndex]; - var fillAlpha = commands[++cmdIndex] * alpha; - var fillTintColor = getTint(fillColor, fillAlpha); - fillTint.TL = fillTintColor; - fillTint.TR = fillTintColor; - fillTint.BL = fillTintColor; - fillTint.BR = fillTintColor; - break; - } - - case Commands.GRADIENT_FILL_STYLE: - { - var alphaTL = commands[++cmdIndex] * alpha; - var alphaTR = commands[++cmdIndex] * alpha; - var alphaBL = commands[++cmdIndex] * alpha; - var alphaBR = commands[++cmdIndex] * alpha; - - fillTint.TL = getTint(commands[++cmdIndex], alphaTL); - fillTint.TR = getTint(commands[++cmdIndex], alphaTR); - fillTint.BL = getTint(commands[++cmdIndex], alphaBL); - fillTint.BR = getTint(commands[++cmdIndex], alphaBR); - break; - } - - case Commands.GRADIENT_LINE_STYLE: - { - lineWidth = commands[++cmdIndex]; - var gradientLineAlpha = commands[++cmdIndex] * alpha; - strokeTint.TL = getTint(commands[++cmdIndex], gradientLineAlpha); - strokeTint.TR = getTint(commands[++cmdIndex], gradientLineAlpha); - strokeTint.BL = getTint(commands[++cmdIndex], gradientLineAlpha); - strokeTint.BR = getTint(commands[++cmdIndex], gradientLineAlpha); - break; - } - - case Commands.ARC: - { - var iteration = 0; - var x = commands[++cmdIndex]; - var y = commands[++cmdIndex]; - var radius = commands[++cmdIndex]; - var startAngle = commands[++cmdIndex]; - var endAngle = commands[++cmdIndex]; - var anticlockwise = commands[++cmdIndex]; - var overshoot = commands[++cmdIndex]; - - endAngle -= startAngle; +module.exports = { - if (anticlockwise) - { - if (endAngle < -PI2) - { - endAngle = -PI2; - } - else if (endAngle > 0) - { - endAngle = -PI2 + endAngle % PI2; - } - } - else if (endAngle > PI2) - { - endAngle = PI2; - } - else if (endAngle < 0) - { - endAngle = PI2 + endAngle % PI2; - } + /** + * 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, - if (lastPath === null) - { - lastPath = new Path(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius, lineWidth); - path.push(lastPath); - iteration += iterStep; - } + /** + * 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, - while (iteration < 1 + overshoot) - { - ta = endAngle * iteration + startAngle; - tx = x + Math.cos(ta) * radius; - ty = y + Math.sin(ta) * radius; + /** + * 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, - lastPath.points.push(new Point(tx, ty, lineWidth)); + /** + * 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, - iteration += iterStep; - } + /** + * 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, - ta = endAngle + startAngle; - tx = x + Math.cos(ta) * radius; - ty = y + Math.sin(ta) * radius; + /** + * 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 - lastPath.points.push(new Point(tx, ty, lineWidth)); +}; - break; - } - case Commands.FILL_RECT: - { - pipeline.batchFillRect( - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - currentMatrix, - calcMatrix - ); - break; - } +/***/ }), - case Commands.FILL_TRIANGLE: - { - pipeline.batchFillTriangle( - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - currentMatrix, - calcMatrix - ); - break; - } +/***/ 10217: +/***/ ((module) => { - case Commands.STROKE_TRIANGLE: - { - pipeline.batchStrokeTriangle( - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - commands[++cmdIndex], - lineWidth, - currentMatrix, - calcMatrix - ); - break; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - case Commands.LINE_TO: - { - if (lastPath !== null) - { - lastPath.points.push(new Point(commands[++cmdIndex], commands[++cmdIndex], lineWidth)); - } - else - { - lastPath = new Path(commands[++cmdIndex], commands[++cmdIndex], lineWidth); - path.push(lastPath); - } - break; - } +/** + * Phaser Scale Manager constants for zoom modes. + * + * @namespace Phaser.Scale.Zoom + * @memberof Phaser.Scale + * @since 3.16.0 + */ - case Commands.MOVE_TO: - { - lastPath = new Path(commands[++cmdIndex], commands[++cmdIndex], lineWidth); - path.push(lastPath); - break; - } +/** + * 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 + */ - case Commands.SAVE: - { - matrixStack.push(currentMatrix.copyToArray()); - break; - } +module.exports = { - case Commands.RESTORE: - { - currentMatrix.copyFromArray(matrixStack.pop()); - break; - } + /** + * 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, - case Commands.TRANSLATE: - { - x = commands[++cmdIndex]; - y = commands[++cmdIndex]; - currentMatrix.translate(x, y); - break; - } + /** + * 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, - case Commands.SCALE: - { - x = commands[++cmdIndex]; - y = commands[++cmdIndex]; - currentMatrix.scale(x, y); - break; - } + /** + * 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, - case Commands.ROTATE: - { - currentMatrix.rotate(commands[++cmdIndex]); - break; - } - } - } + /** + * 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 - renderer.pipelines.postBatch(src); }; -module.exports = GraphicsWebGLRenderer; - /***/ }), -/* 1065 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 55301: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1066); -} - -if (true) -{ - renderCanvas = __webpack_require__(1067); -} - -module.exports = { +var CONST = { - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + CENTER: __webpack_require__(35098), + ORIENTATION: __webpack_require__(53539), + SCALE_MODE: __webpack_require__(12637), + ZOOM: __webpack_require__(10217) }; +module.exports = CONST; + /***/ }), -/* 1066 */ -/***/ (function(module, exports) { + +/***/ 82085: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Renders this Game Object with the WebGL Renderer to the given Camera. - * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. - * This method should not be called directly. It is a utility function of the Render module. - * - * @method Phaser.GameObjects.Sprite#renderWebGL - * @since 3.0.0 - * @private + * The Scale Manager has successfully entered fullscreen mode. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Sprite} 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 + * @event Phaser.Scale.Events#ENTER_FULLSCREEN + * @type {string} + * @since 3.16.1 */ -var SpriteWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - src.pipeline.batchSprite(src, camera, parentMatrix); -}; - -module.exports = SpriteWebGLRenderer; +module.exports = 'enterfullscreen'; /***/ }), -/* 1067 */ -/***/ (function(module, exports) { + +/***/ 11826: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Renders this Game Object with the Canvas Renderer to the given Camera. - * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. - * This method should not be called directly. It is a utility function of the Render module. - * - * @method Phaser.GameObjects.Sprite#renderCanvas - * @since 3.0.0 - * @private + * The Scale Manager tried to enter fullscreen mode but failed. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Sprite} 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 + * @event Phaser.Scale.Events#FULLSCREEN_FAILED + * @type {string} + * @since 3.17.0 */ -var SpriteCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - renderer.batchSprite(src, src.frame, camera, parentMatrix); -}; - -module.exports = SpriteCanvasRenderer; +module.exports = 'fullscreenfailed'; /***/ }), -/* 1068 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 56691: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1069); -} - -if (true) -{ - renderCanvas = __webpack_require__(1070); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; +/** + * The Scale Manager tried to enter fullscreen mode, but it is unsupported by the browser. + * + * @event Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED + * @type {string} + * @since 3.16.1 + */ +module.exports = 'fullscreenunsupported'; /***/ }), -/* 1069 */ -/***/ (function(module, exports) { + +/***/ 34739: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Renders this Game Object with the WebGL Renderer to the given Camera. - * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. - * This method should not be called directly. It is a utility function of the Render module. - * - * @method Phaser.GameObjects.Image#renderWebGL - * @since 3.0.0 - * @private + * The Scale Manager was in fullscreen mode, but has since left, either directly via game code, + * or via a user gestured, such as pressing the ESC key. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Image} 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 + * @event Phaser.Scale.Events#LEAVE_FULLSCREEN + * @type {string} + * @since 3.16.1 */ -var ImageWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - this.pipeline.batchSprite(src, camera, parentMatrix); -}; - -module.exports = ImageWebGLRenderer; +module.exports = 'leavefullscreen'; /***/ }), -/* 1070 */ -/***/ (function(module, exports) { + +/***/ 26681: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Renders this Game Object with the Canvas Renderer to the given Camera. - * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. - * This method should not be called directly. It is a utility function of the Render module. + * The Scale Manager Orientation Change Event. * - * @method Phaser.GameObjects.Image#renderCanvas - * @since 3.0.0 - * @private + * This event is dispatched whenever the Scale Manager detects an orientation change event from the browser. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Image} 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 + * @event Phaser.Scale.Events#ORIENTATION_CHANGE + * @type {string} + * @since 3.16.1 + * + * @param {string} orientation - The new orientation value. Either `Phaser.Scale.Orientation.LANDSCAPE` or `Phaser.Scale.Orientation.PORTRAIT`. */ -var ImageCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - renderer.batchSprite(src, src.frame, camera, parentMatrix); -}; - -module.exports = ImageCanvasRenderer; +module.exports = 'orientationchange'; /***/ }), -/* 1071 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); -if (true) -{ - renderWebGL = __webpack_require__(1072); -} - -if (true) -{ - renderCanvas = __webpack_require__(1073); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; - - -/***/ }), -/* 1072 */ -/***/ (function(module, exports) { +/***/ 11428: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Renders this Game Object with the WebGL Renderer to the given Camera. - * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. - * This method should not be called directly. It is a utility function of the Render module. + * The Scale Manager Resize Event. * - * @method Phaser.GameObjects.Layer#renderWebGL - * @since 3.50.0 - * @private + * This event is dispatched whenever the Scale Manager detects a resize event from the browser. + * It sends three parameters to the callback, each of them being Size components. You can read + * the `width`, `height`, `aspectRatio` and other properties of these components to help with + * scaling your own game content. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Layer} layer - The Game Object being rendered in this call. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + * @event Phaser.Scale.Events#RESIZE + * @type {string} + * @since 3.16.1 + * + * @param {Phaser.Structs.Size} gameSize - A reference to the Game Size component. This is the un-scaled size of your game canvas. + * @param {Phaser.Structs.Size} baseSize - A reference to the Base Size component. This is the game size. + * @param {Phaser.Structs.Size} displaySize - A reference to the Display Size component. This is the scaled canvas size, after applying zoom and scale mode. + * @param {number} previousWidth - If the `gameSize` has changed, this value contains its previous width, otherwise it contains the current width. + * @param {number} previousHeight - If the `gameSize` has changed, this value contains its previous height, otherwise it contains the current height. */ -var LayerWebGLRenderer = function (renderer, layer, camera) -{ - var children = layer.list; - var childCount = children.length; - - if (childCount === 0) - { - return; - } - - layer.depthSort(); - - renderer.pipelines.preBatch(layer); - - var layerHasBlendMode = (layer.blendMode !== -1); - - if (!layerHasBlendMode) - { - // If Layer is SKIP_TEST then set blend mode to be Normal - renderer.setBlendMode(0); - } - - var alpha = layer.alpha; - - for (var i = 0; i < childCount; i++) - { - var child = children[i]; - - if (!child.willRender(camera)) - { - continue; - } - - var childAlphaTopLeft; - var childAlphaTopRight; - var childAlphaBottomLeft; - var childAlphaBottomRight; - - if (child.alphaTopLeft !== undefined) - { - childAlphaTopLeft = child.alphaTopLeft; - childAlphaTopRight = child.alphaTopRight; - childAlphaBottomLeft = child.alphaBottomLeft; - childAlphaBottomRight = child.alphaBottomRight; - } - else - { - var childAlpha = child.alpha; - - childAlphaTopLeft = childAlpha; - childAlphaTopRight = childAlpha; - childAlphaBottomLeft = childAlpha; - childAlphaBottomRight = childAlpha; - } - - if (!layerHasBlendMode && child.blendMode !== renderer.currentBlendMode) - { - // If Layer doesn't have its own blend mode, then a child can have one - renderer.setBlendMode(child.blendMode); - } - - var mask = child.mask; - - if (mask) - { - mask.preRenderWebGL(renderer, child, camera); - } - - var type = child.type; - - if (type !== renderer.currentType) - { - renderer.newType = true; - renderer.currentType = type; - } - - renderer.nextTypeMatch = (i < childCount - 1) ? (children[i + 1].type === renderer.currentType) : false; - - child.setAlpha(childAlphaTopLeft * alpha, childAlphaTopRight * alpha, childAlphaBottomLeft * alpha, childAlphaBottomRight * alpha); - - // Render - child.renderWebGL(renderer, child, camera); - - // Restore original values - child.setAlpha(childAlphaTopLeft, childAlphaTopRight, childAlphaBottomLeft, childAlphaBottomRight); - - if (mask) - { - mask.postRenderWebGL(renderer, camera); - } - - renderer.newType = false; - } - - renderer.pipelines.postBatch(layer); -}; - -module.exports = LayerWebGLRenderer; +module.exports = 'resize'; /***/ }), -/* 1073 */ -/***/ (function(module, exports) { + +/***/ 40444: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Renders this Game Object with the Canvas Renderer to the given Camera. - * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera. - * This method should not be called directly. It is a utility function of the Render module. - * - * @method Phaser.GameObjects.Layer#renderCanvas - * @since 3.50.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Layer} layer - 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 + * @namespace Phaser.Scale.Events */ -var LayerCanvasRenderer = function (renderer, layer, camera) -{ - var children = layer.list; - - if (children.length === 0) - { - return; - } - layer.depthSort(); - - var layerHasBlendMode = (layer.blendMode !== -1); - - if (!layerHasBlendMode) - { - // If Layer is SKIP_TEST then set blend mode to be Normal - renderer.setBlendMode(0); - } - - var alpha = layer._alpha; - - if (layer.mask) - { - layer.mask.preRenderCanvas(renderer, null, camera); - } - - for (var i = 0; i < children.length; i++) - { - var child = children[i]; - - if (!child.willRender(camera)) - { - continue; - } - - var childAlpha = child.alpha; - - if (!layerHasBlendMode && child.blendMode !== renderer.currentBlendMode) - { - // If Layer doesn't have its own blend mode, then a child can have one - renderer.setBlendMode(child.blendMode); - } - - // Set parent values - child.setAlpha(childAlpha * alpha); - - // Render - child.renderCanvas(renderer, child, camera); +module.exports = { - // Restore original values - child.setAlpha(childAlpha); - } + ENTER_FULLSCREEN: __webpack_require__(82085), + FULLSCREEN_FAILED: __webpack_require__(11826), + FULLSCREEN_UNSUPPORTED: __webpack_require__(56691), + LEAVE_FULLSCREEN: __webpack_require__(34739), + ORIENTATION_CHANGE: __webpack_require__(26681), + RESIZE: __webpack_require__(11428) - if (layer.mask) - { - layer.mask.postRenderCanvas(renderer); - } }; -module.exports = LayerCanvasRenderer; - /***/ }), -/* 1074 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 86754: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Extend = __webpack_require__(98611); +var CONST = __webpack_require__(55301); + /** - * @namespace Phaser.GameObjects.Particles + * @namespace Phaser.Scale + * + * @borrows Phaser.Scale.Center.NO_CENTER as NO_CENTER + * @borrows Phaser.Scale.Center.CENTER_BOTH as CENTER_BOTH + * @borrows Phaser.Scale.Center.CENTER_HORIZONTALLY as CENTER_HORIZONTALLY + * @borrows Phaser.Scale.Center.CENTER_VERTICALLY as CENTER_VERTICALLY + * + * @borrows Phaser.Scale.Orientation.LANDSCAPE as LANDSCAPE + * @borrows Phaser.Scale.Orientation.PORTRAIT as PORTRAIT + * + * @borrows Phaser.Scale.ScaleModes.NONE as NONE + * @borrows Phaser.Scale.ScaleModes.WIDTH_CONTROLS_HEIGHT as WIDTH_CONTROLS_HEIGHT + * @borrows Phaser.Scale.ScaleModes.HEIGHT_CONTROLS_WIDTH as HEIGHT_CONTROLS_WIDTH + * @borrows Phaser.Scale.ScaleModes.FIT as FIT + * @borrows Phaser.Scale.ScaleModes.ENVELOP as ENVELOP + * @borrows Phaser.Scale.ScaleModes.RESIZE as RESIZE + * + * @borrows Phaser.Scale.Zoom.NO_ZOOM as NO_ZOOM + * @borrows Phaser.Scale.Zoom.ZOOM_2X as ZOOM_2X + * @borrows Phaser.Scale.Zoom.ZOOM_4X as ZOOM_4X + * @borrows Phaser.Scale.Zoom.MAX_ZOOM as MAX_ZOOM */ -module.exports = { +var Scale = { - EmitterOp: __webpack_require__(449), - GravityWell: __webpack_require__(450), - Particle: __webpack_require__(451), - ParticleEmitter: __webpack_require__(452), - ParticleEmitterManager: __webpack_require__(220), - Zones: __webpack_require__(1078) + Center: __webpack_require__(35098), + Events: __webpack_require__(40444), + Orientation: __webpack_require__(53539), + ScaleManager: __webpack_require__(756), + ScaleModes: __webpack_require__(12637), + Zoom: __webpack_require__(10217) }; +Scale = Extend(false, Scale, CONST.CENTER); +Scale = Extend(false, Scale, CONST.ORIENTATION); +Scale = Extend(false, Scale, CONST.SCALE_MODE); +Scale = Extend(false, Scale, CONST.ZOOM); -/***/ }), -/* 1075 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1076); -} - -if (true) -{ - renderCanvas = __webpack_require__(1077); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; +module.exports = Scale; /***/ }), -/* 1076 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 47736: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var TransformMatrix = __webpack_require__(25); -var Utils = __webpack_require__(12); - -var tempMatrix1 = new TransformMatrix(); -var tempMatrix2 = new TransformMatrix(); -var tempMatrix3 = new TransformMatrix(); -var tempMatrix4 = new TransformMatrix(); +var GetFastValue = __webpack_require__(72632); +var UppercaseFirst = __webpack_require__(40587); /** - * 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. + * Builds an array of which physics plugins should be activated for the given Scene. * - * @method Phaser.GameObjects.Particles.EmitterManager#renderWebGL + * @function Phaser.Scenes.GetPhysicsPlugins * @since 3.0.0 - * @private * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Particles.ParticleEmitterManager} emitterManager - 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 {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 ParticleManagerWebGLRenderer = function (renderer, emitterManager, camera, parentMatrix) +var GetPhysicsPlugins = function (sys) { - var emitters = emitterManager.emitters.list; - var emittersLength = emitters.length; + var defaultSystem = sys.game.config.defaultPhysicsSystem; + var sceneSystems = GetFastValue(sys.settings, 'physics', false); - if (emittersLength === 0) + if (!defaultSystem && !sceneSystems) { + // No default physics system or systems in this scene return; } - var pipeline = renderer.pipelines.set(emitterManager.pipeline); - - var camMatrix = tempMatrix1; - var calcMatrix = tempMatrix2; - var particleMatrix = tempMatrix3; - var managerMatrix = tempMatrix4; + // Let's build the systems array + var output = []; - if (parentMatrix) - { - managerMatrix.loadIdentity(); - managerMatrix.multiply(parentMatrix); - managerMatrix.translate(emitterManager.x, emitterManager.y); - managerMatrix.rotate(emitterManager.rotation); - managerMatrix.scale(emitterManager.scaleX, emitterManager.scaleY); - } - else + if (defaultSystem) { - managerMatrix.applyITRS(emitterManager.x, emitterManager.y, emitterManager.rotation, emitterManager.scaleX, emitterManager.scaleY); + output.push(UppercaseFirst(defaultSystem + 'Physics')); } - var roundPixels = camera.roundPixels; - var texture = emitterManager.defaultFrame.glTexture; - var getTint = Utils.getTintAppendFloatAlpha; - - var textureUnit = pipeline.setGameObject(emitterManager, emitterManager.defaultFrame); - - renderer.pipelines.preBatch(emitterManager); - - for (var e = 0; e < emittersLength; e++) + if (sceneSystems) { - var emitter = emitters[e]; - var particles = emitter.alive; - var particleCount = particles.length; - - if (!emitter.visible || particleCount === 0) - { - continue; - } - - camera.addToRenderList(emitter); - - var scrollFactorX = emitter.scrollFactorX; - var scrollFactorY = emitter.scrollFactorY; - - renderer.setBlendMode(emitter.blendMode); - - if (emitter.mask) - { - emitter.mask.preRenderWebGL(renderer, emitter, camera); - - renderer.pipelines.set(emitterManager.pipeline); - } - - var tintEffect = 0; - - for (var i = 0; i < particleCount; i++) + for (var key in sceneSystems) { - var particle = particles[i]; - - var alpha = particle.alpha * camera.alpha; + key = UppercaseFirst(key.concat('Physics')); - if (alpha <= 0) + if (output.indexOf(key) === -1) { - continue; + output.push(key); } - - particleMatrix.applyITRS(particle.x, particle.y, particle.rotation, particle.scaleX, particle.scaleY); - - camMatrix.copyFrom(camera.matrix); - - camMatrix.multiplyWithOffset(managerMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY); - - // Undo the camera scroll - particleMatrix.e = particle.x; - particleMatrix.f = particle.y; - - // Multiply by the particle matrix, store result in calcMatrix - camMatrix.multiply(particleMatrix, calcMatrix); - - var frame = particle.frame; - - var x = -frame.halfWidth; - var y = -frame.halfHeight; - var xw = x + frame.width; - var yh = y + frame.height; - - 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 tint = getTint(particle.tint, alpha); - - pipeline.batchQuad(emitter, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, tintEffect, texture, textureUnit); - } - - if (emitter.mask) - { - emitter.mask.postRenderWebGL(renderer, camera); } } - renderer.pipelines.postBatch(emitterManager); + // An array of Physics systems to start for this Scene + return output; }; -module.exports = ParticleManagerWebGLRenderer; +module.exports = GetPhysicsPlugins; /***/ }), -/* 1077 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 91088: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 tempMatrix4 = new TransformMatrix(); +var GetFastValue = __webpack_require__(72632); /** - * 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. + * Builds an array of which plugins (not including physics plugins) should be activated for the given Scene. * - * @method Phaser.GameObjects.Particles.EmitterManager#renderCanvas + * @function Phaser.Scenes.GetScenePlugins * @since 3.0.0 - * @private * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Particles.ParticleEmitterManager} emitterManager - 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 {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 ParticleManagerCanvasRenderer = function (renderer, emitterManager, camera, parentMatrix) +var GetScenePlugins = function (sys) { - var emitters = emitterManager.emitters.list; - var emittersLength = emitters.length; + var defaultPlugins = sys.plugins.getDefaultScenePlugins(); + + var scenePlugins = GetFastValue(sys.settings, 'plugins', false); - if (emittersLength === 0) + // Scene Plugins always override Default Plugins + if (Array.isArray(scenePlugins)) { - return; + return scenePlugins; } - - var camMatrix = tempMatrix1.copyFrom(camera.matrix); - var calcMatrix = tempMatrix2; - var particleMatrix = tempMatrix3; - var managerMatrix = tempMatrix4; - - if (parentMatrix) + else if (defaultPlugins) { - managerMatrix.loadIdentity(); - managerMatrix.multiply(parentMatrix); - managerMatrix.translate(emitterManager.x, emitterManager.y); - managerMatrix.rotate(emitterManager.rotation); - managerMatrix.scale(emitterManager.scaleX, emitterManager.scaleY); + return defaultPlugins; } else { - managerMatrix.applyITRS(emitterManager.x, emitterManager.y, emitterManager.rotation, emitterManager.scaleX, emitterManager.scaleY); + // No default plugins or plugins in this scene + return []; } +}; - var ctx = renderer.currentContext; - var roundPixels = camera.roundPixels; - - for (var e = 0; e < emittersLength; e++) - { - var emitter = emitters[e]; - var particles = emitter.alive; - var particleCount = particles.length; - - if (!emitter.visible || particleCount === 0) - { - continue; - } - - camera.addToRenderList(emitter); - - var scrollFactorX = emitter.scrollFactorX; - var scrollFactorY = emitter.scrollFactorY; - - ctx.save(); - - ctx.globalCompositeOperation = renderer.blendModes[emitter.blendMode]; - - for (var i = 0; i < particleCount; i++) - { - var particle = particles[i]; - - var alpha = particle.alpha * camera.alpha; - - if (alpha <= 0) - { - continue; - } - - particleMatrix.applyITRS(particle.x, particle.y, particle.rotation, particle.scaleX, particle.scaleY); +module.exports = GetScenePlugins; - camMatrix.copyFrom(camera.matrix); - camMatrix.multiplyWithOffset(managerMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY); +/***/ }), - // Undo the camera scroll - particleMatrix.e = particle.x; - particleMatrix.f = particle.y; +/***/ 90415: +/***/ ((module) => { - // Multiply by the particle matrix, store result in calcMatrix - camMatrix.multiply(particleMatrix, calcMatrix); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var frame = particle.frame; - var cd = frame.canvasData; +// These properties get injected into the Scene and map to local systems +// The map value is the property that is injected into the Scene, the key is the Scene.Systems reference. +// These defaults can be modified via the Scene config object +// var config = { +// map: { +// add: 'makeStuff', +// load: 'loader' +// } +// }; - var x = -(frame.halfWidth); - var y = -(frame.halfHeight); +var InjectionMap = { - ctx.globalAlpha = alpha; + game: 'game', + renderer: 'renderer', - ctx.save(); + anims: 'anims', + cache: 'cache', + plugins: 'plugins', + registry: 'registry', + scale: 'scale', + sound: 'sound', + textures: 'textures', - calcMatrix.setToContext(ctx); + events: 'events', + cameras: 'cameras', + add: 'add', + make: 'make', + scenePlugin: 'scene', + displayList: 'children', + lights: 'lights', - if (roundPixels) - { - x = Math.round(x); - y = Math.round(y); - } + data: 'data', + input: 'input', + load: 'load', + time: 'time', + tweens: 'tweens', - ctx.imageSmoothingEnabled = !(!renderer.antialias || frame.source.scaleMode); + arcadePhysics: 'physics', + impactPhysics: 'impact', + matterPhysics: 'matter' - ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height); +}; - ctx.restore(); - } +if (false) +{} - ctx.restore(); - } -}; +if (false) +{} -module.exports = ParticleManagerCanvasRenderer; +module.exports = InjectionMap; /***/ }), -/* 1078 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 87157: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var Systems = __webpack_require__(63946); + /** - * @namespace Phaser.GameObjects.Particles.Zones + * @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] - The scene key or scene specific configuration settings. */ +var Scene = new Class({ -module.exports = { + initialize: - DeathZone: __webpack_require__(453), - EdgeZone: __webpack_require__(454), - RandomZone: __webpack_require__(456) + 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; -/***/ }), -/* 1079 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * A reference to the global 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; -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + /** + * 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.NoAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager)} + * @since 3.0.0 + */ + this.sound; -if (true) -{ - renderWebGL = __webpack_require__(1080); -} + /** + * 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; -if (true) -{ - renderCanvas = __webpack_require__(1081); -} + /** + * A Scene specific 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; -module.exports = { + /** + * The Scene Camera Manager. + * + * 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; - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + /** + * The Scene 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; -}; + /** + * The Scene 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; -/***/ }), -/* 1080 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The Game Object Display List belonging to this Scene. + * + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The Scene 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; -var Utils = __webpack_require__(12); + /** + * A Scene specific Data Manager Plugin. + * + * See the `registry` property for the global Data Manager. + * + * 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; -/** - * 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.RenderTexture#renderWebGL - * @since 3.2.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.RenderTexture} 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 RenderTextureWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + /** + * The Scene 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; - var cameraAlpha = camera.alpha; + /** + * The Scene 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; - var renderTarget = src.renderTarget; - var width = renderTarget.width; - var height = renderTarget.height; + /** + * The Scene 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; - var getTint = Utils.getTintAppendFloatAlpha; + /** + * The Scene 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; - var pipeline = renderer.pipelines.set(src.pipeline); + /** + * The Scene 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; - var textureUnit = pipeline.setTexture2D(renderTarget.texture); + /** + * The Scene 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; - renderer.pipelines.preBatch(src); + if (false) + {} - pipeline.batchTexture( - src, - renderTarget.texture, - width, height, - src.x, src.y, - width, height, - src.scaleX, src.scaleY, - src.rotation, - src.flipX, !src.flipY, - src.scrollFactorX, src.scrollFactorY, - src.displayOriginX, src.displayOriginY, - 0, 0, width, height, - getTint(src.tintTopLeft, cameraAlpha * src._alphaTL), - getTint(src.tintTopRight, cameraAlpha * src._alphaTR), - getTint(src.tintBottomLeft, cameraAlpha * src._alphaBL), - getTint(src.tintBottomRight, cameraAlpha * src._alphaBR), - src.tintFill, - 0, 0, - camera, - parentMatrix, - true, - textureUnit - ); + /** + * 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 global 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; - renderer.resetTextures(); + /** + * A reference to the renderer instance Phaser is using, either Canvas Renderer or WebGL Renderer. + * + * @name Phaser.Scene#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.50.0 + */ + this.renderer; + }, - renderer.pipelines.postBatch(src); -}; + /** + * This method 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 = RenderTextureWebGLRenderer; +module.exports = Scene; /***/ }), -/* 1081 */ -/***/ (function(module, exports) { + +/***/ 13553: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(92980); +var Events = __webpack_require__(7599); +var GameEvents = __webpack_require__(97081); +var GetValue = __webpack_require__(10850); +var LoaderEvents = __webpack_require__(683); +var NOOP = __webpack_require__(72283); +var Scene = __webpack_require__(87157); +var Systems = __webpack_require__(63946); + /** - * 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. + * @classdesc + * The Scene Manager. * - * @method Phaser.GameObjects.RenderTexture#renderCanvas - * @since 3.2.0 - * @private + * The Scene Manager is a Game level system, responsible for creating, processing and updating all of the + * Scenes in a Game instance. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.RenderTexture} 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 + * You should not usually interact directly with the Scene Manager at all. Instead, you should use + * the Scene Plugin, which is available from every Scene in your game via the `this.scene` property. + * + * Using methods in this Scene Manager directly will break queued operations and can cause runtime + * errors. Instead, go via the Scene Plugin. Every feature this Scene Manager provides is also + * available via the Scene Plugin. + * + * @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 RenderTextureCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); +var SceneManager = new Class({ - renderer.batchSprite(src, src.frame, camera, parentMatrix); -}; + initialize: -module.exports = RenderTextureCanvasRenderer; + 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 {Record} + * @since 3.0.0 + */ + this.keys = {}; -/***/ }), -/* 1082 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The array in which all of the scenes are kept. + * + * @name Phaser.Scenes.SceneManager#scenes + * @type {Phaser.Scene[]} + * @since 3.0.0 + */ + this.scenes = []; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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 = []; -var RETRO_FONT_CONST = __webpack_require__(1083); -var Extend = __webpack_require__(17); + /** + * 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 = []; -/** - * @namespace Phaser.GameObjects.RetroFont - * @since 3.6.0 - */ + /** + * 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 = []; -var RetroFont = { Parse: __webpack_require__(1084) }; + /** + * Boot time data to merge. + * + * @name Phaser.Scenes.SceneManager#_data + * @type {object} + * @private + * @since 3.4.0 + */ + this._data = {}; -// Merge in the consts -RetroFont = Extend(false, RetroFont, RETRO_FONT_CONST); + /** + * 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; -module.exports = RetroFont; + /** + * 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; -/***/ }), -/* 1083 */ -/***/ (function(module, exports) { + /** + * This system Scene is created during `bootQueue` and is a default + * empty Scene that lives outside of the Scene list, but can be used + * by plugins and managers that need access to a live Scene, without + * being tied to one. + * + * @name Phaser.Scenes.SceneManager#systemScene + * @type {Phaser.Scene} + * @since 3.60.0 + */ + this.systemScene; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (sceneConfig) + { + if (!Array.isArray(sceneConfig)) + { + sceneConfig = [ sceneConfig ]; + } -var RETRO_FONT_CONST = { + 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: {} + }); + } + } - /** - * Text Set 1 = !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET1 - * @type {string} - * @since 3.6.0 - */ - TEXT_SET1: ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~', + game.events.once(GameEvents.READY, this.bootQueue, this); + }, /** - * Text Set 2 = !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET2 - * @type {string} - * @since 3.6.0 + * Internal first-time Scene boot handler. + * + * @method Phaser.Scenes.SceneManager#bootQueue + * @private + * @since 3.2.0 */ - TEXT_SET2: ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ', + bootQueue: function () + { + if (this.isBooted) + { + return; + } - /** - * Text Set 3 = ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET3 - * @type {string} - * @since 3.6.0 - */ - TEXT_SET3: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ', + // Create the system Scene + this.systemScene = this.createSceneFromInstance('__SYSTEM', new Scene()); - /** - * Text Set 4 = ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET4 - * @type {string} - * @since 3.6.0 - */ - TEXT_SET4: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789', + var i; + var entry; + var key; + var sceneConfig; - /** - * Text Set 5 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789 - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET5 - * @type {string} - * @since 3.6.0 - */ - TEXT_SET5: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() \'!?-*:0123456789', + for (i = 0; i < this._pending.length; i++) + { + entry = this._pending[i]; - /** - * Text Set 6 = ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789"(),-.' - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET6 - * @type {string} - * @since 3.6.0 - */ - TEXT_SET6: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789"(),-.\' ', + key = entry.key; + sceneConfig = entry.scene; - /** - * Text Set 7 = AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW")28FLRX-'39 - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET7 - * @type {string} - * @since 3.6.0 - */ - TEXT_SET7: 'AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW")28FLRX-\'39', + var newScene; - /** - * Text Set 8 = 0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET8 - * @type {string} - * @since 3.6.0 - */ - TEXT_SET8: '0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ', + 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); + } - /** - * Text Set 9 = ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'"?! - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET9 - * @type {string} - * @since 3.6.0 - */ - TEXT_SET9: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,\'"?!', + // Replace key in case the scene changed it + key = newScene.sys.settings.key; - /** - * Text Set 10 = ABCDEFGHIJKLMNOPQRSTUVWXYZ - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET10 - * @type {string} - * @since 3.6.0 - */ - TEXT_SET10: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + 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; + }, /** - * Text Set 11 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,"-+!?()':;0123456789 - * - * @name Phaser.GameObjects.RetroFont.TEXT_SET11 - * @since 3.6.0 - * @type {string} + * Process the Scene operations queue. + * + * @method Phaser.Scenes.SceneManager#processQueue + * @since 3.0.0 */ - TEXT_SET11: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ.,"-+!?()\':;0123456789' + processQueue: function () + { + var pendingLength = this._pending.length; + var queueLength = this._queue.length; -}; + if (pendingLength === 0 && queueLength === 0) + { + return; + } -module.exports = RETRO_FONT_CONST; + var i; + var entry; + if (pendingLength) + { + for (i = 0; i < pendingLength; i++) + { + entry = this._pending[i]; -/***/ }), -/* 1084 */ -/***/ (function(module, exports, __webpack_require__) { + this.add(entry.key, entry.scene, entry.autoStart, entry.data); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // _start might have been populated by this.add + for (i = 0; i < this._start.length; i++) + { + entry = this._start[i]; -var GetValue = __webpack_require__(6); + this.start(entry); + } -/** - * Parses a Retro Font configuration object so you can pass it to the BitmapText constructor - * and create a BitmapText object using a fixed-width retro font. - * - * @function Phaser.GameObjects.RetroFont.Parse - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - A reference to the Phaser Scene. - * @param {Phaser.Types.GameObjects.BitmapText.RetroFontConfig} config - The font configuration object. - * - * @return {object} A parsed Bitmap Font data entry for the Bitmap Font cache. - */ -var ParseRetroFont = function (scene, config) -{ - var w = config.width; - var h = config.height; + // Clear the pending lists + this._start.length = 0; + this._pending.length = 0; + } - var cx = Math.floor(w / 2); - var cy = Math.floor(h / 2); + for (i = 0; i < this._queue.length; i++) + { + entry = this._queue[i]; - var letters = GetValue(config, 'chars', ''); + this[entry.op](entry.keyA, entry.keyB); + } - if (letters === '') + 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.Types.Scenes.SceneType)} 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) { - return; - } + if (autoStart === undefined) { autoStart = false; } + if (data === undefined) { data = {}; } - var key = GetValue(config, 'image', ''); + // 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 + }); - var frame = scene.sys.textures.getFrame(key); - var textureX = frame.cutX; - var textureY = frame.cutY; - var textureWidth = frame.source.width; - var textureHeight = frame.source.height; + if (!this.isBooted) + { + this._data[key] = { data: data }; + } - var offsetX = GetValue(config, 'offset.x', 0); - var offsetY = GetValue(config, 'offset.y', 0); - var spacingX = GetValue(config, 'spacing.x', 0); - var spacingY = GetValue(config, 'spacing.y', 0); - var lineSpacing = GetValue(config, 'lineSpacing', 0); + return null; + } - var charsPerRow = GetValue(config, 'charsPerRow', null); + key = this.getKey(key, sceneConfig); - if (charsPerRow === null) - { - charsPerRow = textureWidth / w; + var newScene; - if (charsPerRow > letters.length) + if (sceneConfig instanceof Scene) { - charsPerRow = letters.length; + newScene = this.createSceneFromInstance(key, sceneConfig); } - } + else if (typeof sceneConfig === 'object') + { + sceneConfig.key = key; - var x = offsetX; - var y = offsetY; + newScene = this.createSceneFromObject(key, sceneConfig); + } + else if (typeof sceneConfig === 'function') + { + newScene = this.createSceneFromFunction(key, sceneConfig); + } - var data = { - retroFont: true, - font: key, - size: w, - lineHeight: h + lineSpacing, - chars: {} - }; + // Any data to inject? + newScene.sys.settings.data = data; - var r = 0; + // Replace key in case the scene changed it + key = newScene.sys.settings.key; - for (var i = 0; i < letters.length; i++) - { - var charCode = letters.charCodeAt(i); + this.keys[key] = newScene; - var u0 = (textureX + x) / textureWidth; - var v0 = (textureY + y) / textureHeight; - var u1 = (textureX + x + w) / textureWidth; - var v1 = (textureY + y + h) / textureHeight; + this.scenes.push(newScene); - data.chars[charCode] = + if (autoStart || newScene.sys.settings.active) { - x: x, - y: y, - width: w, - height: h, - centerX: cx, - centerY: cy, - xOffset: 0, - yOffset: 0, - xAdvance: w, - data: {}, - kerning: {}, - u0: u0, - v0: v0, - u1: u1, - v1: v1 - }; + if (this._pending.length) + { + this._start.push(key); + } + else + { + this.start(key); + } + } - r++; + return newScene; + }, - if (r === charsPerRow) + /** + * 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 {this} This Scene Manager instance. + */ + remove: function (key) + { + if (this.isProcessing) { - r = 0; - x = offsetX; - y += h + spacingY; + this._queue.push({ op: 'remove', keyA: key, keyB: null }); } else { - x += w + spacingX; - } - } - - var entry = { - data: data, - frame: null, - texture: key - }; - - return entry; -}; + var sceneToRemove = this.getScene(key); -module.exports = ParseRetroFont; + if (!sceneToRemove || sceneToRemove.sys.isTransitioning()) + { + return this; + } + var index = this.scenes.indexOf(sceneToRemove); + var sceneKey = sceneToRemove.sys.settings.key; -/***/ }), -/* 1085 */ -/***/ (function(module, exports, __webpack_require__) { + if (index > -1) + { + delete this.keys[sceneKey]; + this.scenes.splice(index, 1); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this._start.indexOf(sceneKey) > -1) + { + index = this._start.indexOf(sceneKey); + this._start.splice(index, 1); + } -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + sceneToRemove.sys.destroy(); + } + } -if (true) -{ - renderWebGL = __webpack_require__(1086); -} + return this; + }, -if (true) -{ - renderCanvas = __webpack_require__(1087); -} + /** + * 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; -module.exports = { + sys.sceneUpdate = NOOP; - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + 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); + } + } -/***/ }), -/* 1086 */ -/***/ (function(module, exports, __webpack_require__) { + var loader; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (sys.load) + { + loader = sys.load; -var GetCalcMatrix = __webpack_require__(19); -var Utils = __webpack_require__(12); + loader.reset(); + } -/** - * 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.Rope#renderWebGL - * @since 3.23.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Rope} 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 RopeWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + if (loader && scene.preload) + { + scene.preload.call(scene); - var pipeline = renderer.pipelines.set(src.pipeline, src); + settings.status = CONST.LOADING; - var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; + // Start the loader going as we have something in the queue + loader.once(LoaderEvents.COMPLETE, this.loadComplete, this); - var vertices = src.vertices; - var uvs = src.uv; - var colors = src.colors; - var alphas = src.alphas; - var alpha = src.alpha; - var getTint = Utils.getTintAppendFloatAlpha; - var roundPixels = camera.roundPixels; + loader.start(); + } + else + { + // No preload? Then there was nothing to load either + this.create(scene); + } + }, - var meshVerticesLength = vertices.length; - var vertexCount = Math.floor(meshVerticesLength * 0.5); + /** + * 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) + { + // 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(); + } - // Because it's a triangle strip and we don't want lots of degenerate triangles joining things up - pipeline.flush(); + this.create(loader.scene); + }, - renderer.pipelines.preBatch(src); + /** + * 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); + }, - var textureUnit = pipeline.setGameObject(src); + /** + * 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(); - var vertexViewF32 = pipeline.vertexViewF32; - var vertexViewU32 = pipeline.vertexViewU32; + this.isProcessing = true; - var vertexOffset = (pipeline.vertexCount * pipeline.currentShader.vertexComponentCount) - 1; + // Loop through the active scenes in reverse order + for (var i = this.scenes.length - 1; i >= 0; i--) + { + var sys = this.scenes[i].sys; - var colorIndex = 0; + if (sys.settings.status > CONST.START && sys.settings.status <= CONST.RUNNING) + { + sys.step(time, delta); + } - var tintEffect = src.tintFill; + if (sys.scenePlugin._target) + { + sys.scenePlugin.step(time, delta); + } + } + }, - if (src.dirty) + /** + * 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) { - src.updateVertices(); - } + // Loop through the scenes in forward order + for (var i = 0; i < this.scenes.length; i++) + { + var sys = this.scenes[i].sys; - var debugCallback = src.debugCallback; - var debugVerts = []; + if (sys.settings.visible && sys.settings.status >= CONST.LOADING && sys.settings.status < CONST.SLEEPING) + { + sys.render(renderer); + } + } - for (var i = 0; i < meshVerticesLength; i += 2) - { - var x = vertices[i + 0]; - var y = vertices[i + 1]; + this.isProcessing = false; + }, - var tx = x * calcMatrix.a + y * calcMatrix.c + calcMatrix.e; - var ty = x * calcMatrix.b + y * calcMatrix.d + calcMatrix.f; + /** + * 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 (roundPixels) + if (scene.create) { - tx = Math.round(tx); - ty = Math.round(ty); - } + settings.status = CONST.CREATING; - vertexViewF32[++vertexOffset] = tx; - vertexViewF32[++vertexOffset] = ty; - vertexViewF32[++vertexOffset] = uvs[i + 0]; - vertexViewF32[++vertexOffset] = uvs[i + 1]; - vertexViewF32[++vertexOffset] = textureUnit; - vertexViewF32[++vertexOffset] = tintEffect; - vertexViewU32[++vertexOffset] = getTint(colors[colorIndex], camera.alpha * (alphas[colorIndex] * alpha)); + scene.create.call(scene, settings.data); - colorIndex++; + if (settings.status === CONST.DESTROYED) + { + return; + } + } - if (debugCallback) + if (settings.isTransition) { - debugVerts[i + 0] = tx; - debugVerts[i + 1] = ty; + sys.events.emit(Events.TRANSITION_START, settings.transitionFrom, settings.transitionDuration); } - } - if (debugCallback) - { - debugCallback.call(src, src, meshVerticesLength, debugVerts); - } + // 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; + } - pipeline.vertexCount += vertexCount; + settings.status = CONST.RUNNING; - renderer.pipelines.postBatch(src); -}; + sys.events.emit(Events.CREATE, scene); + }, -module.exports = RopeWebGLRenderer; + /** + * 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; -/***/ }), -/* 1087 */ -/***/ (function(module, exports) { + if (configKey !== '') + { + key = configKey; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.keys.hasOwnProperty(key)) + { + throw new Error('Cannot add a Scene with duplicate key: ' + key); + } -/** - * This is a stub function for Rope.Render. There is no Canvas renderer for Rope objects. - * - * @method Phaser.GameObjects.Rope#renderCanvas - * @since 3.23.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Rope} src - The Game Object being rendered in this call. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. - */ -var RopeCanvasRenderer = function () -{ -}; + return this.createSceneFromInstance(key, newScene); + } + else + { + newScene.sys = new Systems(newScene); -module.exports = RopeCanvasRenderer; + newScene.sys.settings.key = key; + newScene.sys.init(this.game); -/***/ }), -/* 1088 */ -/***/ (function(module, exports, __webpack_require__) { + return newScene; + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + if (configKey === '') + { + newScene.sys.settings.key = key; + } -if (true) -{ - renderWebGL = __webpack_require__(1089); -} + newScene.sys.init(this.game); -if (true) -{ - renderCanvas = __webpack_require__(1090); -} + return newScene; + }, -module.exports = { + /** + * 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); - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + var configKey = newScene.sys.settings.key; -}; + if (configKey !== '') + { + key = configKey; + } + else + { + newScene.sys.settings.key = key; + } + newScene.sys.init(this.game); -/***/ }), -/* 1089 */ -/***/ (function(module, exports, __webpack_require__) { + // Extract callbacks -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var defaults = [ 'init', 'preload', 'create', 'update', 'render' ]; -var Utils = __webpack_require__(12); + for (var i = 0; i < defaults.length; i++) + { + var sceneCallback = GetValue(sceneConfig, defaults[i], null); -/** - * 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.Text#renderWebGL - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Text} 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 TextWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - if (src.width === 0 || src.height === 0) - { - return; - } + if (sceneCallback) + { + newScene[defaults[i]] = sceneCallback; + } + } - camera.addToRenderList(src); + // Now let's move across any other functions or properties that may exist in the extend object: - var frame = src.frame; - var width = frame.width; - var height = frame.height; - var getTint = Utils.getTintAppendFloatAlpha; - var pipeline = renderer.pipelines.set(src.pipeline, src); + /* + scene: { + preload: preload, + create: create, + extend: { + hello: 1, + test: 'atari', + addImage: addImage + } + } + */ - var textureUnit = pipeline.setTexture2D(frame.glTexture, src); + if (sceneConfig.hasOwnProperty('extend')) + { + for (var propertyKey in sceneConfig.extend) + { + if (!sceneConfig.extend.hasOwnProperty(propertyKey)) + { + continue; + } - renderer.pipelines.preBatch(src); + var value = sceneConfig.extend[propertyKey]; - pipeline.batchTexture( - src, - frame.glTexture, - width, height, - src.x, src.y, - width / src.style.resolution, height / src.style.resolution, - src.scaleX, src.scaleY, - src.rotation, - src.flipX, src.flipY, - src.scrollFactorX, src.scrollFactorY, - src.displayOriginX, src.displayOriginY, - 0, 0, width, height, - getTint(src.tintTopLeft, camera.alpha * src._alphaTL), - getTint(src.tintTopRight, camera.alpha * src._alphaTR), - getTint(src.tintBottomLeft, camera.alpha * src._alphaBL), - getTint(src.tintBottomRight, camera.alpha * src._alphaBR), - src.tintFill, - 0, 0, - camera, - parentMatrix, - false, - textureUnit - ); + if (propertyKey === 'data' && newScene.hasOwnProperty('data') && typeof value === 'object') + { + // Populate the DataManager + newScene.data.merge(value); + } + else if (propertyKey !== 'sys') + { + newScene[propertyKey] = value; + } + } + } - renderer.pipelines.postBatch(src); -}; + return newScene; + }, -module.exports = TextWebGLRenderer; + /** + * 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; + } -/***/ }), -/* 1090 */ -/***/ (function(module, exports) { + // By this point it's either 'default' or extracted from the Scene -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.keys.hasOwnProperty(key)) + { + throw new Error('Cannot add a Scene with duplicate key: ' + key); + } + else + { + return key; + } + }, -/** - * 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.Text#renderCanvas - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Text} 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 TextCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - if (src.width === 0 || src.height === 0) + /** + * 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 + * + * @generic {Phaser.Scene[]} T - [$return] + * + * @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) { - return; - } + if (isActive === undefined) { isActive = true; } + if (inReverse === undefined) { inReverse = false; } - camera.addToRenderList(src); + var out = []; + var scenes = this.scenes; - renderer.batchSprite(src, src.frame, camera, parentMatrix); -}; + for (var i = 0; i < scenes.length; i++) + { + var scene = scenes[i]; -module.exports = TextCanvasRenderer; + if (scene && (!isActive || (isActive && scene.sys.isActive()))) + { + out.push(scene); + } + } + return (inReverse) ? out.reverse() : out; + }, -/***/ }), -/* 1091 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Retrieves a Scene based on the given key. + * + * If an actual Scene is passed to this method, it can be used to check if + * its currently within the Scene Manager, or not. + * + * @method Phaser.Scenes.SceneManager#getScene + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * @genericUse {T} - [$return] + * + * @param {(string|Phaser.Scene)} key - The key of the Scene to retrieve. + * + * @return {?Phaser.Scene} The Scene, or `null` if no matching Scene was found. + */ + 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; + } + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return null; + }, -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + /** + * Determines whether a Scene is running. + * + * @method Phaser.Scenes.SceneManager#isActive + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to check. + * + * @return {boolean} Whether the Scene is running, or `null` if no matching Scene was found. + */ + isActive: function (key) + { + var scene = this.getScene(key); -if (true) -{ - renderWebGL = __webpack_require__(1092); -} + if (scene) + { + return scene.sys.isActive(); + } -if (true) -{ - renderCanvas = __webpack_require__(1093); -} + return null; + }, -module.exports = { + /** + * Determines whether a Scene is paused. + * + * @method Phaser.Scenes.SceneManager#isPaused + * @since 3.17.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to check. + * + * @return {boolean} Whether the Scene is paused, or `null` if no matching Scene was found. + */ + isPaused: function (key) + { + var scene = this.getScene(key); - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + if (scene) + { + return scene.sys.isPaused(); + } -}; + return null; + }, + /** + * Determines whether a Scene is visible. + * + * @method Phaser.Scenes.SceneManager#isVisible + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to check. + * + * @return {boolean} Whether the Scene is visible, or `null` if no matching Scene was found. + */ + isVisible: function (key) + { + var scene = this.getScene(key); -/***/ }), -/* 1092 */ -/***/ (function(module, exports, __webpack_require__) { + if (scene) + { + return scene.sys.isVisible(); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return null; + }, -var Utils = __webpack_require__(12); + /** + * Determines whether a Scene is sleeping. + * + * @method Phaser.Scenes.SceneManager#isSleeping + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to check. + * + * @return {boolean} Whether the Scene is sleeping, or `null` if no matching Scene was found. + */ + isSleeping: function (key) + { + var scene = this.getScene(key); -/** - * 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.TileSprite#renderWebGL - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.TileSprite} 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 TileSpriteWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - src.updateCanvas(); + if (scene) + { + return scene.sys.isSleeping(); + } - var width = src.width; - var height = src.height; + return null; + }, - if (width === 0 || height === 0) + /** + * Pauses the given Scene. + * + * @method Phaser.Scenes.SceneManager#pause + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} 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 {this} This Scene Manager instance. + */ + pause: function (key, data) { - return; - } + var scene = this.getScene(key); - camera.addToRenderList(src); + if (scene) + { + scene.sys.pause(data); + } - renderer.pipelines.preBatch(src); + return this; + }, - var getTint = Utils.getTintAppendFloatAlpha; + /** + * Resumes the given Scene. + * + * @method Phaser.Scenes.SceneManager#resume + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} 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 {this} This Scene Manager instance. + */ + resume: function (key, data) + { + var scene = this.getScene(key); - var pipeline = renderer.pipelines.set(src.pipeline, src); + if (scene) + { + scene.sys.resume(data); + } - var textureUnit = pipeline.setTexture2D(src.fillPattern, src); + return this; + }, - pipeline.batchTexture( - src, - src.fillPattern, - src.displayFrame.width * src.tileScaleX, src.displayFrame.height * src.tileScaleY, - src.x, src.y, - width, height, - src.scaleX, src.scaleY, - src.rotation, - src.flipX, src.flipY, - src.scrollFactorX, src.scrollFactorY, - src.originX * width, src.originY * height, - 0, 0, width, height, - getTint(src.tintTopLeft, camera.alpha * src._alphaTL), - getTint(src.tintTopRight, camera.alpha * src._alphaTR), - getTint(src.tintBottomLeft, camera.alpha * src._alphaBL), - getTint(src.tintBottomRight, camera.alpha * src._alphaBR), - src.tintFill, - (src.tilePositionX % src.displayFrame.width) / src.displayFrame.width, - (src.tilePositionY % src.displayFrame.height) / src.displayFrame.height, - camera, - parentMatrix, - false, - textureUnit - ); + /** + * Puts the given Scene to sleep. + * + * @method Phaser.Scenes.SceneManager#sleep + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} 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 {this} This Scene Manager instance. + */ + sleep: function (key, data) + { + var scene = this.getScene(key); - renderer.pipelines.postBatch(src); -}; + if (scene && !scene.sys.isTransitioning()) + { + scene.sys.sleep(data); + } -module.exports = TileSpriteWebGLRenderer; + return this; + }, + /** + * Awakens the given Scene. + * + * @method Phaser.Scenes.SceneManager#wake + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} 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 {this} This Scene Manager instance. + */ + wake: function (key, data) + { + var scene = this.getScene(key); -/***/ }), -/* 1093 */ -/***/ (function(module, exports) { + if (scene) + { + scene.sys.wake(data); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * 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.TileSprite#renderCanvas - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.TileSprite} 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 TileSpriteCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - src.updateCanvas(); + /** + * 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 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to run. + * @param {object} [data] - A data object that will be passed to the Scene on start, wake, or resume. + * + * @return {this} This Scene Manager instance. + */ + run: function (key, data) + { + var scene = this.getScene(key); - camera.addToRenderList(src); + 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); + } + }, - renderer.batchSprite(src, src.frame, camera, parentMatrix); -}; + /** + * Starts the given Scene, if it is not starting, loading, or creating. + * + * If the Scene is running, paused, or sleeping, it will be shutdown and then started. + * + * @method Phaser.Scenes.SceneManager#start + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to start. + * @param {object} [data] - Optional data object to pass to `Scene.Settings` and `Scene.init`, and `Scene.create`. + * + * @return {this} This Scene Manager instance. + */ + 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 + }; -module.exports = TileSpriteCanvasRenderer; + return this; + } + var scene = this.getScene(key); -/***/ }), -/* 1094 */ -/***/ (function(module, exports, __webpack_require__) { + if (!scene) + { + console.warn('Scene not found for key: ' + key); + return this; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var sys = scene.sys; + var status = sys.settings.status; -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + // If the scene is already started but not yet running, + // let it continue. + if (status >= CONST.START && status <= CONST.CREATING) + { + return this; + } -if (true) -{ - renderWebGL = __webpack_require__(1095); -} + // If the Scene is already running, paused, or sleeping, + // close it down before starting it again. + else if (status >= CONST.RUNNING && status <= CONST.SLEEPING) + { + sys.shutdown(); -if (true) -{ - renderCanvas = __webpack_require__(1096); -} + sys.sceneUpdate = NOOP; -module.exports = { + sys.start(data); + } - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + // If the Scene is INIT or SHUTDOWN, + // start it directly. + else + { + sys.sceneUpdate = NOOP; -}; + sys.start(data); + var loader; -/***/ }), -/* 1095 */ -/***/ (function(module, exports) { + if (sys.load) + { + loader = sys.load; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Files payload? + if (loader && sys.settings.hasOwnProperty('pack')) + { + loader.reset(); -/** - * 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.Video#renderWebGL - * @since 3.20.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Video} 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 VideoWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - if (src.videoTexture) - { - camera.addToRenderList(src); + if (loader.addPack({ payload: sys.settings.pack })) + { + sys.settings.status = CONST.LOADING; - src.pipeline.batchSprite(src, camera, parentMatrix); - } -}; + loader.once(LoaderEvents.COMPLETE, this.payloadComplete, this); -module.exports = VideoWebGLRenderer; + loader.start(); + return this; + } + } + } -/***/ }), -/* 1096 */ -/***/ (function(module, exports) { + this.bootScene(scene); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * 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.Video#renderCanvas - * @since 3.20.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Video} 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 VideoCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - if (src.videoTexture) + /** + * Stops the given Scene. + * + * @method Phaser.Scenes.SceneManager#stop + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to stop. + * @param {object} [data] - Optional data object to pass to Scene.shutdown. + * + * @return {this} This Scene Manager instance. + */ + stop: function (key, data) { - camera.addToRenderList(src); + var scene = this.getScene(key); - renderer.batchSprite(src, src.frame, camera, parentMatrix); - } -}; + if (scene && !scene.sys.isTransitioning() && scene.sys.settings.status !== CONST.SHUTDOWN) + { + var loader = scene.sys.load; -module.exports = VideoCanvasRenderer; + if (loader) + { + loader.off(LoaderEvents.COMPLETE, this.loadComplete, this); + loader.off(LoaderEvents.COMPLETE, this.payloadComplete, this); + } + scene.sys.shutdown(data); + } -/***/ }), -/* 1097 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Sleeps one one Scene and starts the other. + * + * @method Phaser.Scenes.SceneManager#switch + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [from,to] + * + * @param {(string|Phaser.Scene)} from - The Scene to sleep. + * @param {(string|Phaser.Scene)} to - The Scene to start. + * + * @return {this} This Scene Manager instance. + */ + switch: function (from, to) + { + var sceneA = this.getScene(from); + var sceneB = this.getScene(to); -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + if (sceneA && sceneB && sceneA !== sceneB) + { + this.sleep(from); -if (true) -{ - renderWebGL = __webpack_require__(1098); -} + if (this.isSleeping(to)) + { + this.wake(to); + } + else + { + this.start(to); + } + } -if (true) -{ - renderCanvas = __webpack_require__(1099); -} + return this; + }, -module.exports = { + /** + * Retrieves a Scene by numeric index. + * + * @method Phaser.Scenes.SceneManager#getAt + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {T} - [$return] + * + * @param {number} index - The index of the Scene to retrieve. + * + * @return {(Phaser.Scene|undefined)} The Scene. + */ + getAt: function (index) + { + return this.scenes[index]; + }, - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + /** + * Retrieves the numeric index of a Scene. + * + * @method Phaser.Scenes.SceneManager#getIndex + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @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 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {this} This Scene Manager instance. + */ + 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); -/***/ }), -/* 1098 */ -/***/ (function(module, exports, __webpack_require__) { + this.scenes.splice(index, 1); + this.scenes.push(scene); + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var GetCalcMatrix = __webpack_require__(19); -var FillPathWebGL = __webpack_require__(114); -var StrokePathWebGL = __webpack_require__(81); + /** + * 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 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {this} This Scene Manager instance. + */ + sendToBack: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'sendToBack', keyA: key, keyB: null }); + } + else + { + var index = this.getIndex(key); -/** - * 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.Arc#renderWebGL - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Arc} 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 ArcWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + if (index !== -1 && index > 0) + { + var scene = this.getScene(key); - var pipeline = renderer.pipelines.set(src.pipeline); + this.scenes.splice(index, 1); + this.scenes.unshift(scene); + } + } - var result = GetCalcMatrix(src, camera, parentMatrix); + return this; + }, - var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); + /** + * Moves a Scene down one position in the Scenes list. + * + * @method Phaser.Scenes.SceneManager#moveDown + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {this} This Scene Manager instance. + */ + moveDown: function (key) + { + if (this.isProcessing) + { + this._queue.push({ op: 'moveDown', keyA: key, keyB: null }); + } + else + { + var indexA = this.getIndex(key); - var dx = src._displayOriginX; - var dy = src._displayOriginY; + if (indexA > 0) + { + var indexB = indexA - 1; + var sceneA = this.getScene(key); + var sceneB = this.getAt(indexB); - var alpha = camera.alpha * src.alpha; + this.scenes[indexA] = sceneB; + this.scenes[indexB] = sceneA; + } + } - renderer.pipelines.preBatch(src); + return this; + }, - if (src.isFilled) + /** + * Moves a Scene up one position in the Scenes list. + * + * @method Phaser.Scenes.SceneManager#moveUp + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to move. + * + * @return {this} This Scene Manager instance. + */ + moveUp: function (key) { - FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); - } + if (this.isProcessing) + { + this._queue.push({ op: 'moveUp', keyA: key, keyB: null }); + } + else + { + var indexA = this.getIndex(key); - if (src.isStroked) - { - StrokePathWebGL(pipeline, src, alpha, dx, dy); - } + if (indexA < this.scenes.length - 1) + { + var indexB = indexA + 1; + var sceneA = this.getScene(key); + var sceneB = this.getAt(indexB); - renderer.pipelines.postBatch(src); -}; + this.scenes[indexA] = sceneB; + this.scenes[indexB] = sceneA; + } + } -module.exports = ArcWebGLRenderer; + 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 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [keyA,keyB] + * + * @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 {this} This Scene Manager instance. + */ + moveAbove: function (keyA, keyB) + { + if (keyA === keyB) + { + return this; + } -/***/ }), -/* 1099 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.isProcessing) + { + this._queue.push({ op: 'moveAbove', keyA: keyA, keyB: keyB }); + } + else + { + var indexA = this.getIndex(keyA); + var indexB = this.getIndex(keyB); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (indexA !== -1 && indexB !== -1 && indexB < indexA) + { + var tempScene = this.getAt(indexB); -var DegToRad = __webpack_require__(36); -var FillStyleCanvas = __webpack_require__(48); -var LineStyleCanvas = __webpack_require__(60); -var SetTransform = __webpack_require__(30); + // Remove + this.scenes.splice(indexB, 1); -/** - * 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.Arc#renderCanvas - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Arc} 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 ArcCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + // Add in new location + this.scenes.splice(indexA + (indexB > indexA), 0, tempScene); + } + } - var ctx = renderer.currentContext; + return this; + }, - if (SetTransform(renderer, ctx, src, camera, parentMatrix)) + /** + * 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 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [keyA,keyB] + * + * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved below. + * @param {(string|Phaser.Scene)} keyB - The Scene to be moved. + * + * @return {this} This Scene Manager instance. + */ + moveBelow: function (keyA, keyB) { - var radius = src.radius; - - ctx.beginPath(); - - ctx.arc( - (radius) - src.originX * (radius * 2), - (radius) - src.originY * (radius * 2), - radius, - DegToRad(src._startAngle), - DegToRad(src._endAngle), - src.anticlockwise - ); - - if (src.closePath) + if (keyA === keyB) { - ctx.closePath(); + return this; } - if (src.isFilled) + if (this.isProcessing) { - FillStyleCanvas(ctx, src); - - ctx.fill(); + this._queue.push({ op: 'moveBelow', keyA: keyA, keyB: keyB }); } - - if (src.isStroked) + else { - LineStyleCanvas(ctx, src); - - ctx.stroke(); - } - - // Restore the context saved in SetTransform - ctx.restore(); - } -}; + var indexA = this.getIndex(keyA); + var indexB = this.getIndex(keyB); -module.exports = ArcCanvasRenderer; + if (indexA !== -1 && indexB !== -1 && indexB > indexA) + { + var tempScene = this.getAt(indexB); + // Remove + this.scenes.splice(indexB, 1); -/***/ }), -/* 1100 */ -/***/ (function(module, exports, __webpack_require__) { + if (indexA === 0) + { + this.scenes.unshift(tempScene); + } + else + { + // Add in new location + this.scenes.splice(indexA - (indexB < indexA), 0, tempScene); + } + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + /** + * 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 {this} This Scene Manager instance. + */ + queueOp: function (op, keyA, keyB) + { + this._queue.push({ op: op, keyA: keyA, keyB: keyB }); -if (true) -{ - renderWebGL = __webpack_require__(1101); -} + return this; + }, -if (true) -{ - renderCanvas = __webpack_require__(1102); -} + /** + * Swaps the positions of two Scenes in the Scenes list. + * + * @method Phaser.Scenes.SceneManager#swapPosition + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [keyA,keyB] + * + * @param {(string|Phaser.Scene)} keyA - The first Scene to swap. + * @param {(string|Phaser.Scene)} keyB - The second Scene to swap. + * + * @return {this} This Scene Manager instance. + */ + swapPosition: function (keyA, keyB) + { + if (keyA === keyB) + { + return this; + } -module.exports = { + if (this.isProcessing) + { + this._queue.push({ op: 'swapPosition', keyA: keyA, keyB: keyB }); + } + else + { + var indexA = this.getIndex(keyA); + var indexB = this.getIndex(keyB); - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + if (indexA !== indexB && indexA !== -1 && indexB !== -1) + { + var tempScene = this.getAt(indexA); -}; + this.scenes[indexA] = this.scenes[indexB]; + this.scenes[indexB] = tempScene; + } + } + return this; + }, -/***/ }), -/* 1101 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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' ]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + for (var i = 0; i < this.scenes.length; i++) + { + var sys = this.scenes[i].sys; -var FillPathWebGL = __webpack_require__(114); -var GetCalcMatrix = __webpack_require__(19); -var StrokePathWebGL = __webpack_require__(81); + var key = (sys.settings.visible && (sys.settings.status === CONST.RUNNING || sys.settings.status === CONST.PAUSED)) ? '[*] ' : '[-] '; + key += sys.settings.key + ' (' + map[sys.settings.status] + ')'; -/** - * 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.Curve#renderWebGL - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Curve} 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 CurveWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + out.push(key); + } - var pipeline = renderer.pipelines.set(src.pipeline); + console.log(out.join('\n')); + }, - var result = GetCalcMatrix(src, camera, parentMatrix); + /** + * Destroy this Scene Manager and all of its systems. + * + * This process cannot be reversed. + * + * This method is called automatically when a Phaser Game instance is destroyed. + * + * @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; - var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); + sys.destroy(); + } - var dx = src._displayOriginX + src._curveBounds.x; - var dy = src._displayOriginY + src._curveBounds.y; + this.systemScene.sys.destroy(); - var alpha = camera.alpha * src.alpha; + this.update = NOOP; - renderer.pipelines.preBatch(src); + this.scenes = []; - if (src.isFilled) - { - FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); - } + this._pending = []; + this._start = []; + this._queue = []; - if (src.isStroked) - { - StrokePathWebGL(pipeline, src, alpha, dx, dy); + this.game = null; + this.systemScene = null; } - renderer.pipelines.postBatch(src); -}; +}); -module.exports = CurveWebGLRenderer; +module.exports = SceneManager; /***/ }), -/* 1102 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 64051: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillStyleCanvas = __webpack_require__(48); -var LineStyleCanvas = __webpack_require__(60); -var SetTransform = __webpack_require__(30); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(7599); +var GetFastValue = __webpack_require__(72632); +var PluginCache = __webpack_require__(91963); /** - * 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. + * @classdesc + * The Scene Plugin is the main interface to the Scene Manager and allows you to control + * any Scene running in your game. You should always use this plugin. By default, it is + * mapped to the Scene property `this.scene`. Meaning, from within a Scene, you can call + * methods such as `this.scene.start()`. * - * @method Phaser.GameObjects.Curve#renderCanvas - * @since 3.13.0 - * @private + * Note that nearly all methods in this class are run on a queue-basis and not + * immediately. For example, calling `this.scene.launch('SceneB')` will try to + * launch SceneB when the Scene Manager next updates, which is at the start of the game + * step. All operations are queued and run in the order in which they are invoked here. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Curve} 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 + * @class ScenePlugin + * @memberof Phaser.Scenes + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene that this ScenePlugin belongs to. */ -var CurveCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); +var ScenePlugin = new Class({ - var ctx = renderer.currentContext; + initialize: - if (SetTransform(renderer, ctx, src, camera, parentMatrix)) + function ScenePlugin (scene) { - var dx = src._displayOriginX + src._curveBounds.x; - var dy = src._displayOriginY + src._curveBounds.y; - - var path = src.pathData; - var pathLength = path.length - 1; - - var px1 = path[0] - dx; - var py1 = path[1] - dy; - - ctx.beginPath(); - - ctx.moveTo(px1, py1); - - if (!src.closePath) - { - pathLength -= 2; - } - - for (var i = 2; i < pathLength; i += 2) - { - var px2 = path[i] - dx; - var py2 = path[i + 1] - dy; - - ctx.lineTo(px2, py2); - } - - if (src.closePath) - { - ctx.closePath(); - } - - if (src.isFilled) - { - FillStyleCanvas(ctx, src); - - ctx.fill(); - } - - if (src.isStroked) - { - LineStyleCanvas(ctx, src); - - ctx.stroke(); - } - - // Restore the context saved in SetTransform - ctx.restore(); - } -}; - -module.exports = CurveCanvasRenderer; - + /** + * The Scene that this ScenePlugin belongs to. + * + * @name Phaser.Scenes.ScenePlugin#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; -/***/ }), -/* 1103 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The Scene Systems instance of the Scene that this ScenePlugin belongs to. + * + * @name Phaser.Scenes.ScenePlugin#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.systems = scene.sys; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The settings of the Scene this ScenePlugin belongs to. + * + * @name Phaser.Scenes.ScenePlugin#settings + * @type {Phaser.Types.Scenes.SettingsObject} + * @since 3.0.0 + */ + this.settings = scene.sys.settings; -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + /** + * The key of the Scene this ScenePlugin belongs to. + * + * @name Phaser.Scenes.ScenePlugin#key + * @type {string} + * @since 3.0.0 + */ + this.key = scene.sys.settings.key; -if (true) -{ - renderWebGL = __webpack_require__(1104); -} + /** + * The Game's SceneManager. + * + * @name Phaser.Scenes.ScenePlugin#manager + * @type {Phaser.Scenes.SceneManager} + * @since 3.0.0 + */ + this.manager = scene.sys.game.scene; -if (true) -{ - renderCanvas = __webpack_require__(1105); -} + /** + * If this Scene is currently transitioning to another, this holds + * the current percentage of the transition progress, between 0 and 1. + * + * @name Phaser.Scenes.ScenePlugin#transitionProgress + * @type {number} + * @since 3.5.0 + */ + this.transitionProgress = 0; -module.exports = { + /** + * Transition elapsed timer. + * + * @name Phaser.Scenes.ScenePlugin#_elapsed + * @type {number} + * @private + * @since 3.5.0 + */ + this._elapsed = 0; - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + /** + * Transition elapsed timer. + * + * @name Phaser.Scenes.ScenePlugin#_target + * @type {?Phaser.Scene} + * @private + * @since 3.5.0 + */ + this._target = null; -}; + /** + * Transition duration. + * + * @name Phaser.Scenes.ScenePlugin#_duration + * @type {number} + * @private + * @since 3.5.0 + */ + this._duration = 0; + /** + * Transition callback. + * + * @name Phaser.Scenes.ScenePlugin#_onUpdate + * @type {function} + * @private + * @since 3.5.0 + */ + this._onUpdate; -/***/ }), -/* 1104 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Transition callback scope. + * + * @name Phaser.Scenes.ScenePlugin#_onUpdateScope + * @type {object} + * @private + * @since 3.5.0 + */ + this._onUpdateScope; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Will this Scene sleep (true) after the transition, or stop (false) + * + * @name Phaser.Scenes.ScenePlugin#_willSleep + * @type {boolean} + * @private + * @since 3.5.0 + */ + this._willSleep = false; -var FillPathWebGL = __webpack_require__(114); -var GetCalcMatrix = __webpack_require__(19); -var StrokePathWebGL = __webpack_require__(81); + /** + * Will this Scene be removed from the Scene Manager after the transition completes? + * + * @name Phaser.Scenes.ScenePlugin#_willRemove + * @type {boolean} + * @private + * @since 3.5.0 + */ + this._willRemove = false; -/** - * 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.Ellipse#renderWebGL - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Ellipse} 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 EllipseWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + scene.sys.events.once(Events.BOOT, this.boot, this); + scene.sys.events.on(Events.START, this.pluginStart, this); + }, - var pipeline = renderer.pipelines.set(src.pipeline); + /** + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. + * + * @method Phaser.Scenes.ScenePlugin#boot + * @private + * @since 3.0.0 + */ + boot: function () + { + this.systems.events.once(Events.DESTROY, this.destroy, this); + }, - var result = GetCalcMatrix(src, camera, parentMatrix); + /** + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. + * + * @method Phaser.Scenes.ScenePlugin#pluginStart + * @private + * @since 3.5.0 + */ + pluginStart: function () + { + this._target = null; - var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); + this.systems.events.once(Events.SHUTDOWN, this.shutdown, this); + }, - var dx = src._displayOriginX; - var dy = src._displayOriginY; + /** + * Shutdown this Scene and run the given one. + * + * This will happen at the next Scene Manager update, not immediately. + * + * @method Phaser.Scenes.ScenePlugin#start + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to start. + * @param {object} [data] - The Scene data. If no value is given it will not overwrite any previous data that may exist. + * + * @return {this} This Scene Plugin instance. + */ + start: function (key, data) + { + if (key === undefined) { key = this.key; } - var alpha = camera.alpha * src.alpha; + this.manager.queueOp('stop', this.key); + this.manager.queueOp('start', key, data); - renderer.pipelines.preBatch(src); + return this; + }, - if (src.isFilled) + /** + * Restarts this Scene. + * + * This will happen at the next Scene Manager update, not immediately. + * + * @method Phaser.Scenes.ScenePlugin#restart + * @since 3.4.0 + * + * @param {object} [data] - The Scene data. If no value is given it will not overwrite any previous data that may exist. + * + * @return {this} This Scene Plugin instance. + */ + restart: function (data) { - FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); - } + var key = this.key; - if (src.isStroked) - { - StrokePathWebGL(pipeline, src, alpha, dx, dy); - } + this.manager.queueOp('stop', key); + this.manager.queueOp('start', key, data); - renderer.pipelines.postBatch(src); -}; + return this; + }, -module.exports = EllipseWebGLRenderer; + /** + * This will start a transition from the current Scene to the target Scene given. + * + * The target Scene cannot be the same as the current Scene. + * + * The transition will last for the duration specified in milliseconds. + * + * You can have the target Scene moved above or below this one in the display list. + * + * You can specify an update callback. This callback will be invoked _every frame_ for the duration + * of the transition. + * + * This Scene can either be sent to sleep at the end of the transition, or stopped. The default is to stop. + * + * There are also 5 transition related events: This scene will emit the event `transitionout` when + * the transition begins, which is typically the frame after calling this method. + * + * The target Scene will emit the event `transitioninit` when that Scene's `init` method is called. + * It will then emit the event `transitionstart` when its `create` method is called. + * If the Scene was sleeping and has been woken up, it will emit the event `transitionwake` instead of these two, + * as the Scenes `init` and `create` methods are not invoked when a Scene wakes up. + * + * When the duration of the transition has elapsed it will emit the event `transitioncomplete`. + * These events are cleared of all listeners when the Scene shuts down, but not if it is sent to sleep. + * + * It's important to understand that the duration of the transition begins the moment you call this method. + * If the Scene you are transitioning to includes delayed processes, such as waiting for files to load, the + * time still counts down even while that is happening. If the game itself pauses, or something else causes + * this Scenes update loop to stop, then the transition will also pause for that duration. There are + * checks in place to prevent you accidentally stopping a transitioning Scene but if you've got code to + * override this understand that until the target Scene completes it might never be unlocked for input events. + * + * @method Phaser.Scenes.ScenePlugin#transition + * @fires Phaser.Scenes.Events#TRANSITION_OUT + * @since 3.5.0 + * + * @param {Phaser.Types.Scenes.SceneTransitionConfig} config - The transition configuration object. + * + * @return {boolean} `true` is the transition was started, otherwise `false`. + */ + transition: function (config) + { + if (config === undefined) { config = {}; } + var key = GetFastValue(config, 'target', false); -/***/ }), -/* 1105 */ -/***/ (function(module, exports, __webpack_require__) { + var target = this.manager.getScene(key); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!key || !this.checkValidTransition(target)) + { + return false; + } -var FillStyleCanvas = __webpack_require__(48); -var LineStyleCanvas = __webpack_require__(60); -var SetTransform = __webpack_require__(30); + var duration = GetFastValue(config, 'duration', 1000); -/** - * 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.Ellipse#renderCanvas - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Ellipse} 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 EllipseCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + this._elapsed = 0; + this._target = target; + this._duration = duration; + this._willSleep = GetFastValue(config, 'sleep', false); + this._willRemove = GetFastValue(config, 'remove', false); - var ctx = renderer.currentContext; + var callback = GetFastValue(config, 'onUpdate', null); - if (SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - var dx = src._displayOriginX; - var dy = src._displayOriginY; + if (callback) + { + this._onUpdate = callback; + this._onUpdateScope = GetFastValue(config, 'onUpdateScope', this.scene); + } - var path = src.pathData; - var pathLength = path.length - 1; + var allowInput = GetFastValue(config, 'allowInput', false); - var px1 = path[0] - dx; - var py1 = path[1] - dy; + this.settings.transitionAllowInput = allowInput; - ctx.beginPath(); + var targetSettings = target.sys.settings; - ctx.moveTo(px1, py1); + targetSettings.isTransition = true; + targetSettings.transitionFrom = this.scene; + targetSettings.transitionDuration = duration; + targetSettings.transitionAllowInput = allowInput; - if (!src.closePath) + if (GetFastValue(config, 'moveAbove', false)) { - pathLength -= 2; + this.manager.moveAbove(this.key, key); } - - for (var i = 2; i < pathLength; i += 2) + else if (GetFastValue(config, 'moveBelow', false)) { - var px2 = path[i] - dx; - var py2 = path[i + 1] - dy; - - ctx.lineTo(px2, py2); + this.manager.moveBelow(this.key, key); } - ctx.closePath(); - - if (src.isFilled) + if (target.sys.isSleeping()) { - FillStyleCanvas(ctx, src); - - ctx.fill(); + target.sys.wake(GetFastValue(config, 'data')); } - - if (src.isStroked) + else { - LineStyleCanvas(ctx, src); - - ctx.stroke(); + this.manager.start(key, GetFastValue(config, 'data')); } - // Restore the context saved in SetTransform - ctx.restore(); - } -}; - -module.exports = EllipseCanvasRenderer; - - -/***/ }), -/* 1106 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1107); -} - -if (true) -{ - renderCanvas = __webpack_require__(1108); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; - - -/***/ }), -/* 1107 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var GetCalcMatrix = __webpack_require__(19); -var Utils = __webpack_require__(12); + var onStartCallback = GetFastValue(config, 'onStart', null); -/** - * 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.Grid#renderWebGL - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Grid} 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 GridWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + var onStartScope = GetFastValue(config, 'onStartScope', this.scene); - var pipeline = renderer.pipelines.set(src.pipeline); + if (onStartCallback) + { + onStartCallback.call(onStartScope, this.scene, target, duration); + } - var result = GetCalcMatrix(src, camera, parentMatrix); + this.systems.events.emit(Events.TRANSITION_OUT, target, duration); - var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); + return true; + }, - calcMatrix.translate(-src._displayOriginX, -src._displayOriginY); + /** + * Checks to see if this Scene can transition to the target Scene or not. + * + * @method Phaser.Scenes.ScenePlugin#checkValidTransition + * @private + * @since 3.5.0 + * + * @param {Phaser.Scene} target - The Scene to test against. + * + * @return {boolean} `true` if this Scene can transition, otherwise `false`. + */ + checkValidTransition: function (target) + { + // Not a valid target if it doesn't exist, isn't active or is already transitioning in or out + if (!target || target.sys.isActive() || target.sys.isTransitioning() || target === this.scene || this.systems.isTransitioning()) + { + return false; + } - var alpha = camera.alpha * src.alpha; + return true; + }, - // Work out the grid size + /** + * A single game step. This is only called if the parent Scene is transitioning + * out to another Scene. + * + * @method Phaser.Scenes.ScenePlugin#step + * @private + * @since 3.5.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. + */ + step: function (time, delta) + { + this._elapsed += delta; - var width = src.width; - var height = src.height; + this.transitionProgress = Clamp(this._elapsed / this._duration, 0, 1); - var cellWidth = src.cellWidth; - var cellHeight = src.cellHeight; + if (this._onUpdate) + { + this._onUpdate.call(this._onUpdateScope, this.transitionProgress); + } - var gridWidth = Math.ceil(width / cellWidth); - var gridHeight = Math.ceil(height / cellHeight); + if (this._elapsed >= this._duration) + { + this.transitionComplete(); + } + }, - var cellWidthA = cellWidth; - var cellHeightA = cellHeight; + /** + * Called by `step` when the transition out of this scene to another is over. + * + * @method Phaser.Scenes.ScenePlugin#transitionComplete + * @private + * @fires Phaser.Scenes.Events#TRANSITION_COMPLETE + * @since 3.5.0 + */ + transitionComplete: function () + { + var targetSys = this._target.sys; + var targetSettings = this._target.sys.settings; - var cellWidthB = cellWidth - ((gridWidth * cellWidth) - width); - var cellHeightB = cellHeight - ((gridHeight * cellHeight) - height); + // Notify target scene + targetSys.events.emit(Events.TRANSITION_COMPLETE, this.scene); - var fillTint; - var fillTintColor; + // Clear target scene settings + targetSettings.isTransition = false; + targetSettings.transitionFrom = null; - var showCells = src.showCells; - var showAltCells = src.showAltCells; - var showOutline = src.showOutline; + // Clear local settings + this._duration = 0; + this._target = null; + this._onUpdate = null; + this._onUpdateScope = null; - var x = 0; - var y = 0; - var r = 0; - var cw = 0; - var ch = 0; + // Now everything is clear we can handle what happens to this Scene + if (this._willRemove) + { + this.manager.remove(this.key); + } + else if (this._willSleep) + { + this.systems.sleep(); + } + else + { + this.manager.stop(this.key); + } + }, - if (showOutline) + /** + * Add the Scene into the Scene Manager and start it if 'autoStart' is true or the Scene config 'active' property is set. + * + * @method Phaser.Scenes.ScenePlugin#add + * @since 3.0.0 + * + * @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`. + * @param {(Phaser.Types.Scenes.SceneType)} 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) { - // To make room for the grid lines (in case alpha < 1) - cellWidthA--; - cellHeightA--; + return this.manager.add(key, sceneConfig, autoStart, data); + }, - if (cellWidthB === cellWidth) + /** + * Launch the given Scene and run it in parallel with this one. + * + * This will happen at the next Scene Manager update, not immediately. + * + * @method Phaser.Scenes.ScenePlugin#launch + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to launch. + * @param {object} [data] - The Scene data. + * + * @return {this} This Scene Plugin instance. + */ + launch: function (key, data) + { + if (key && key !== this.key) { - cellWidthB--; + this.manager.queueOp('start', key, data); } - if (cellHeightB === cellHeight) + return this; + }, + + /** + * Runs the given Scene, but does not change the state of this Scene. + * + * This will happen at the next Scene Manager update, not immediately. + * + * 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.ScenePlugin#run + * @since 3.10.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to run. + * @param {object} [data] - A data object that will be passed to the Scene and emitted in its ready, wake, or resume events. + * + * @return {this} This Scene Plugin instance. + */ + run: function (key, data) + { + if (key && key !== this.key) { - cellHeightB--; + this.manager.queueOp('run', key, data); } - } - renderer.pipelines.preBatch(src); + return this; + }, - if (showCells && src.fillAlpha > 0) + /** + * Pause the Scene - this stops the update step from happening but it still renders. + * + * This will happen at the next Scene Manager update, not immediately. + * + * @method Phaser.Scenes.ScenePlugin#pause + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to pause. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its pause event. + * + * @return {this} This Scene Plugin instance. + */ + pause: function (key, data) { - fillTint = pipeline.fillTint; - fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha); - - fillTint.TL = fillTintColor; - fillTint.TR = fillTintColor; - fillTint.BL = fillTintColor; - fillTint.BR = fillTintColor; + if (key === undefined) { key = this.key; } - for (y = 0; y < gridHeight; y++) - { - if (showAltCells) - { - r = y % 2; - } + this.manager.queueOp('pause', key, data); - for (x = 0; x < gridWidth; x++) - { - if (showAltCells && r) - { - r = 0; - continue; - } + return this; + }, - r++; + /** + * Resume the Scene - starts the update loop again. + * + * This will happen at the next Scene Manager update, not immediately. + * + * @method Phaser.Scenes.ScenePlugin#resume + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to resume. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its resume event. + * + * @return {this} This Scene Plugin instance. + */ + resume: function (key, data) + { + if (key === undefined) { key = this.key; } - cw = (x < gridWidth - 1) ? cellWidthA : cellWidthB; - ch = (y < gridHeight - 1) ? cellHeightA : cellHeightB; + this.manager.queueOp('resume', key, data); - pipeline.batchFillRect( - x * cellWidth, - y * cellHeight, - cw, - ch - ); - } - } - } + return this; + }, - if (showAltCells && src.altFillAlpha > 0) + /** + * Makes the Scene sleep (no update, no render) but doesn't shutdown. + * + * This will happen at the next Scene Manager update, not immediately. + * + * @method Phaser.Scenes.ScenePlugin#sleep + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to put to sleep. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its sleep event. + * + * @return {this} This Scene Plugin instance. + */ + sleep: function (key, data) { - fillTint = pipeline.fillTint; - fillTintColor = Utils.getTintAppendFloatAlpha(src.altFillColor, src.altFillAlpha * alpha); + if (key === undefined) { key = this.key; } - fillTint.TL = fillTintColor; - fillTint.TR = fillTintColor; - fillTint.BL = fillTintColor; - fillTint.BR = fillTintColor; + this.manager.queueOp('sleep', key, data); - for (y = 0; y < gridHeight; y++) - { - if (showAltCells) - { - r = y % 2; - } + return this; + }, - for (x = 0; x < gridWidth; x++) - { - if (showAltCells && !r) - { - r = 1; - continue; - } + /** + * Makes the Scene wake-up (starts update and render) + * + * This will happen at the next Scene Manager update, not immediately. + * + * @method Phaser.Scenes.ScenePlugin#wake + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to wake up. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its wake event. + * + * @return {this} This Scene Plugin instance. + */ + wake: function (key, data) + { + if (key === undefined) { key = this.key; } - r = 0; + this.manager.queueOp('wake', key, data); - cw = (x < gridWidth - 1) ? cellWidthA : cellWidthB; - ch = (y < gridHeight - 1) ? cellHeightA : cellHeightB; + return this; + }, - pipeline.batchFillRect( - x * cellWidth, - y * cellHeight, - cw, - ch - ); - } + /** + * Makes this Scene sleep then starts the Scene given. + * + * This will happen at the next Scene Manager update, not immediately. + * + * @method Phaser.Scenes.ScenePlugin#switch + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to start. + * + * @return {this} This Scene Plugin instance. + */ + switch: function (key) + { + if (key !== this.key) + { + this.manager.queueOp('switch', this.key, key); } - } - if (showOutline && src.outlineFillAlpha > 0) + return this; + }, + + /** + * Shutdown the Scene, clearing display list, timers, etc. + * + * This happens at the next Scene Manager update, not immediately. + * + * @method Phaser.Scenes.ScenePlugin#stop + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to stop. + * @param {any} [data] - Optional data object to pass to Scene.Systems.shutdown. + * + * @return {this} This Scene Plugin instance. + */ + stop: function (key, data) { - var strokeTint = pipeline.strokeTint; - var color = Utils.getTintAppendFloatAlpha(src.outlineFillColor, src.outlineFillAlpha * alpha); + if (key === undefined) { key = this.key; } - strokeTint.TL = color; - strokeTint.TR = color; - strokeTint.BL = color; - strokeTint.BR = color; + this.manager.queueOp('stop', key, data); - for (x = 1; x < gridWidth; x++) - { - var x1 = x * cellWidth; + return this; + }, - pipeline.batchLine(x1, 0, x1, height, 1, 1, 1, 0, false); - } + /** + * Sets the active state of the given Scene. + * + * @method Phaser.Scenes.ScenePlugin#setActive + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {boolean} value - If `true` the Scene will be resumed. If `false` it will be paused. + * @param {(string|Phaser.Scene)} [key] - The Scene to set the active state of. + * @param {object} [data] - An optional data object that will be passed to the Scene and emitted with its events. + * + * @return {this} This Scene Plugin instance. + */ + setActive: function (value, key, data) + { + if (key === undefined) { key = this.key; } - for (y = 1; y < gridHeight; y++) - { - var y1 = y * cellHeight; + var scene = this.manager.getScene(key); - pipeline.batchLine(0, y1, width, y1, 1, 1, 1, 0, false); + if (scene) + { + scene.sys.setActive(value, data); } - } - - renderer.pipelines.postBatch(src); -}; -module.exports = GridWebGLRenderer; + return this; + }, + /** + * Sets the visible state of the given Scene. + * + * @method Phaser.Scenes.ScenePlugin#setVisible + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {boolean} value - The visible value. + * @param {(string|Phaser.Scene)} [key] - The Scene to set the visible state for. + * + * @return {this} This Scene Plugin instance. + */ + setVisible: function (value, key) + { + if (key === undefined) { key = this.key; } -/***/ }), -/* 1108 */ -/***/ (function(module, exports, __webpack_require__) { + var scene = this.manager.getScene(key); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (scene) + { + scene.sys.setVisible(value); + } -var FillStyleCanvas = __webpack_require__(48); -var LineStyleCanvas = __webpack_require__(60); -var SetTransform = __webpack_require__(30); + return this; + }, -/** - * 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.Grid#renderCanvas - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Grid} 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 GridCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + /** + * Checks if the given Scene is sleeping or not? + * + * @method Phaser.Scenes.ScenePlugin#isSleeping + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to check. + * + * @return {boolean} Whether the Scene is sleeping, or `null` if no matching Scene was found. + */ + isSleeping: function (key) + { + if (key === undefined) { key = this.key; } - var ctx = renderer.currentContext; + return this.manager.isSleeping(key); + }, - if (SetTransform(renderer, ctx, src, camera, parentMatrix)) + /** + * Checks if the given Scene is running or not? + * + * @method Phaser.Scenes.ScenePlugin#isActive + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to check. + * + * @return {boolean} Whether the Scene is running, or `null` if no matching Scene was found. + */ + isActive: function (key) { - var dx = -src._displayOriginX; - var dy = -src._displayOriginY; + if (key === undefined) { key = this.key; } - var alpha = camera.alpha * src.alpha; + return this.manager.isActive(key); + }, - // Work out the grid size + /** + * Checks if the given Scene is paused or not? + * + * @method Phaser.Scenes.ScenePlugin#isPaused + * @since 3.17.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to check. + * + * @return {boolean} Whether the Scene is paused, or `null` if no matching Scene was found. + */ + isPaused: function (key) + { + if (key === undefined) { key = this.key; } - var width = src.width; - var height = src.height; + return this.manager.isPaused(key); + }, - var cellWidth = src.cellWidth; - var cellHeight = src.cellHeight; + /** + * Checks if the given Scene is visible or not? + * + * @method Phaser.Scenes.ScenePlugin#isVisible + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to check. + * + * @return {boolean} Whether the Scene is visible, or `null` if no matching Scene was found. + */ + isVisible: function (key) + { + if (key === undefined) { key = this.key; } - var gridWidth = Math.ceil(width / cellWidth); - var gridHeight = Math.ceil(height / cellHeight); + return this.manager.isVisible(key); + }, - var cellWidthA = cellWidth; - var cellHeightA = cellHeight; + /** + * Swaps the position of two scenes in the Scenes list. + * + * This controls the order in which they are rendered and updated. + * + * @method Phaser.Scenes.ScenePlugin#swapPosition + * @since 3.2.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [keyA,keyB] + * + * @param {(string|Phaser.Scene)} keyA - The first Scene to swap. + * @param {(string|Phaser.Scene)} [keyB] - The second Scene to swap. If none is given it defaults to this Scene. + * + * @return {this} This Scene Plugin instance. + */ + swapPosition: function (keyA, keyB) + { + if (keyB === undefined) { keyB = this.key; } - var cellWidthB = cellWidth - ((gridWidth * cellWidth) - width); - var cellHeightB = cellHeight - ((gridHeight * cellHeight) - height); + if (keyA !== keyB) + { + this.manager.swapPosition(keyA, keyB); + } - var showCells = src.showCells; - var showAltCells = src.showAltCells; - var showOutline = src.showOutline; + return this; + }, - var x = 0; - var y = 0; - var r = 0; - var cw = 0; - var ch = 0; + /** + * Swaps the position of two scenes in the Scenes list, so that Scene B is directly above Scene A. + * + * This controls the order in which they are rendered and updated. + * + * @method Phaser.Scenes.ScenePlugin#moveAbove + * @since 3.2.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [keyA,keyB] + * + * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved to be above. + * @param {(string|Phaser.Scene)} [keyB] - The Scene to be moved. If none is given it defaults to this Scene. + * + * @return {this} This Scene Plugin instance. + */ + moveAbove: function (keyA, keyB) + { + if (keyB === undefined) { keyB = this.key; } - if (showOutline) + if (keyA !== keyB) { - // To make room for the grid lines (in case alpha < 1) - cellWidthA--; - cellHeightA--; + this.manager.moveAbove(keyA, keyB); + } - if (cellWidthB === cellWidth) - { - cellWidthB--; - } + return this; + }, - if (cellHeightB === cellHeight) - { - cellHeightB--; - } - } + /** + * Swaps the position of two scenes in the Scenes list, so that Scene B is directly below Scene A. + * + * This controls the order in which they are rendered and updated. + * + * @method Phaser.Scenes.ScenePlugin#moveBelow + * @since 3.2.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [keyA,keyB] + * + * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved to be below. + * @param {(string|Phaser.Scene)} [keyB] - The Scene to be moved. If none is given it defaults to this Scene. + * + * @return {this} This Scene Plugin instance. + */ + moveBelow: function (keyA, keyB) + { + if (keyB === undefined) { keyB = this.key; } - if (showCells && src.fillAlpha > 0) + if (keyA !== keyB) { - FillStyleCanvas(ctx, src); - - for (y = 0; y < gridHeight; y++) - { - if (showAltCells) - { - r = y % 2; - } + this.manager.moveBelow(keyA, keyB); + } - for (x = 0; x < gridWidth; x++) - { - if (showAltCells && r) - { - r = 0; - continue; - } + return this; + }, - r++; + /** + * 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.ScenePlugin#remove + * @since 3.2.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to be removed. + * + * @return {this} This Scene Plugin instance. + */ + remove: function (key) + { + if (key === undefined) { key = this.key; } - cw = (x < gridWidth - 1) ? cellWidthA : cellWidthB; - ch = (y < gridHeight - 1) ? cellHeightA : cellHeightB; + this.manager.remove(key); - ctx.fillRect( - dx + x * cellWidth, - dy + y * cellHeight, - cw, - ch - ); - } - } - } + return this; + }, - if (showAltCells && src.altFillAlpha > 0) - { - FillStyleCanvas(ctx, src, src.altFillColor, src.altFillAlpha * alpha); + /** + * Moves a Scene up one position in the Scenes list. + * + * @method Phaser.Scenes.ScenePlugin#moveUp + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to move. + * + * @return {this} This Scene Plugin instance. + */ + moveUp: function (key) + { + if (key === undefined) { key = this.key; } - for (y = 0; y < gridHeight; y++) - { - if (showAltCells) - { - r = y % 2; - } + this.manager.moveUp(key); - for (x = 0; x < gridWidth; x++) - { - if (showAltCells && !r) - { - r = 1; - continue; - } + return this; + }, - r = 0; + /** + * Moves a Scene down one position in the Scenes list. + * + * @method Phaser.Scenes.ScenePlugin#moveDown + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to move. + * + * @return {this} This Scene Plugin instance. + */ + moveDown: function (key) + { + if (key === undefined) { key = this.key; } - cw = (x < gridWidth - 1) ? cellWidthA : cellWidthB; - ch = (y < gridHeight - 1) ? cellHeightA : cellHeightB; + this.manager.moveDown(key); - ctx.fillRect( - dx + x * cellWidth, - dy + y * cellHeight, - cw, - ch - ); - } - } - } + return this; + }, - if (showOutline && src.outlineFillAlpha > 0) - { - LineStyleCanvas(ctx, src, src.outlineFillColor, src.outlineFillAlpha * alpha); + /** + * Brings a Scene to the top of the Scenes list. + * + * This means it will render above all other Scenes. + * + * @method Phaser.Scenes.ScenePlugin#bringToTop + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to move. + * + * @return {this} This Scene Plugin instance. + */ + bringToTop: function (key) + { + if (key === undefined) { key = this.key; } - for (x = 1; x < gridWidth; x++) - { - var x1 = x * cellWidth; + this.manager.bringToTop(key); - ctx.beginPath(); + return this; + }, - ctx.moveTo(x1 + dx, dy); - ctx.lineTo(x1 + dx, height + dy); + /** + * Sends a Scene to the back of the Scenes list. + * + * This means it will render below all other Scenes. + * + * @method Phaser.Scenes.ScenePlugin#sendToBack + * @since 3.0.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to move. + * + * @return {this} This Scene Plugin instance. + */ + sendToBack: function (key) + { + if (key === undefined) { key = this.key; } - ctx.stroke(); - } + this.manager.sendToBack(key); - for (y = 1; y < gridHeight; y++) - { - var y1 = y * cellHeight; + return this; + }, - ctx.beginPath(); + /** + * Retrieve a Scene. + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * @genericUse {T} - [$return] + * + * @method Phaser.Scenes.ScenePlugin#get + * @since 3.0.0 + * + * @param {(string|Phaser.Scene)} key - The Scene to retrieve. + * + * @return {Phaser.Scene} The Scene. + */ + get: function (key) + { + return this.manager.getScene(key); + }, - ctx.moveTo(dx, y1 + dy); - ctx.lineTo(dx + width, y1 + dy); + /** + * Return the status of the Scene. + * + * @method Phaser.Scenes.ScenePlugin#getStatus + * @since 3.60.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} key - The Scene to get the status from. + * + * @return {number} The Scene status. This maps to the `Phaser.Scene` constants, such as `Phaser.Scene.LOADING`. + */ + getStatus: function (key) + { + var scene = this.manager.getScene(key); - ctx.stroke(); - } + if (scene) + { + return scene.sys.getStatus(); } + }, - // Restore the context saved in SetTransform - ctx.restore(); - } -}; - -module.exports = GridCanvasRenderer; + /** + * Retrieves the numeric index of a Scene in the Scenes list. + * + * @method Phaser.Scenes.ScenePlugin#getIndex + * @since 3.7.0 + * + * @generic {Phaser.Scene} T + * @genericUse {(T|string)} - [key] + * + * @param {(string|Phaser.Scene)} [key] - The Scene to get the index of. + * + * @return {number} The index of the Scene. + */ + getIndex: function (key) + { + if (key === undefined) { key = this.key; } + return this.manager.getIndex(key); + }, -/***/ }), -/* 1109 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The Scene that owns this plugin is shutting down. + * + * We need to kill and reset all internal properties as well as stop listening to Scene events. + * + * @method Phaser.Scenes.ScenePlugin#shutdown + * @private + * @since 3.0.0 + */ + shutdown: function () + { + var eventEmitter = this.systems.events; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + eventEmitter.off(Events.SHUTDOWN, this.shutdown, this); + eventEmitter.off(Events.TRANSITION_OUT); + }, -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + /** + * The Scene that owns this plugin is being destroyed. + * + * We need to shutdown and then kill off all external references. + * + * @method Phaser.Scenes.ScenePlugin#destroy + * @private + * @since 3.0.0 + */ + destroy: function () + { + this.shutdown(); -if (true) -{ - renderWebGL = __webpack_require__(1110); -} + this.scene.sys.events.off(Events.START, this.start, this); -if (true) -{ - renderCanvas = __webpack_require__(1111); -} + this.scene = null; + this.systems = null; + this.settings = null; + this.manager = null; + } -module.exports = { +}); - renderWebGL: renderWebGL, - renderCanvas: renderCanvas +PluginCache.register('ScenePlugin', ScenePlugin, 'scenePlugin'); -}; +module.exports = ScenePlugin; /***/ }), -/* 1110 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 36765: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(19); -var Utils = __webpack_require__(12); +var CONST = __webpack_require__(92980); +var GetValue = __webpack_require__(10850); +var Merge = __webpack_require__(30657); +var InjectionMap = __webpack_require__(90415); /** - * 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.IsoBox#renderWebGL - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.IsoBox} 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 + * @namespace Phaser.Scenes.Settings */ -var IsoBoxWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var pipeline = renderer.pipelines.set(src.pipeline); - - var result = GetCalcMatrix(src, camera, parentMatrix); - - var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); - - var size = src.width; - var height = src.height; - - var sizeA = size / 2; - var sizeB = size / src.projection; - var alpha = camera.alpha * src.alpha; +var Settings = { - if (!src.isFilled) + /** + * 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) { - return; - } - - var tint; - - var x0; - var y0; - - var x1; - var y1; - - var x2; - var y2; - - var x3; - var y3; - - - renderer.pipelines.preBatch(src); + if (typeof config === 'string') + { + config = { key: config }; + } + else if (config === undefined) + { + // Pass the 'hasOwnProperty' checks + config = {}; + } - // Top Face + return { - if (src.showTop) - { - tint = Utils.getTintAppendFloatAlpha(src.fillTop, alpha); + status: CONST.PENDING, - x0 = calcMatrix.getX(-sizeA, -height); - y0 = calcMatrix.getY(-sizeA, -height); + key: GetValue(config, 'key', ''), + active: GetValue(config, 'active', false), + visible: GetValue(config, 'visible', true), - x1 = calcMatrix.getX(0, -sizeB - height); - y1 = calcMatrix.getY(0, -sizeB - height); + isBooted: false, - x2 = calcMatrix.getX(sizeA, -height); - y2 = calcMatrix.getY(sizeA, -height); + isTransition: false, + transitionFrom: null, + transitionDuration: 0, + transitionAllowInput: true, - x3 = calcMatrix.getX(0, sizeB - height); - y3 = calcMatrix.getY(0, sizeB - height); + // Loader payload array - pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); - } + data: {}, - // Left Face + pack: GetValue(config, 'pack', false), - if (src.showLeft) - { - tint = Utils.getTintAppendFloatAlpha(src.fillLeft, alpha); + // Cameras - x0 = calcMatrix.getX(-sizeA, 0); - y0 = calcMatrix.getY(-sizeA, 0); + cameras: GetValue(config, 'cameras', null), - x1 = calcMatrix.getX(0, sizeB); - y1 = calcMatrix.getY(0, sizeB); + // Scene Property Injection Map - x2 = calcMatrix.getX(0, sizeB - height); - y2 = calcMatrix.getY(0, sizeB - height); + map: GetValue(config, 'map', Merge(InjectionMap, GetValue(config, 'mapAdd', {}))), - x3 = calcMatrix.getX(-sizeA, -height); - y3 = calcMatrix.getY(-sizeA, -height); + // Physics - pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); - } + physics: GetValue(config, 'physics', {}), - // Right Face + // Loader - if (src.showRight) - { - tint = Utils.getTintAppendFloatAlpha(src.fillRight, alpha); + loader: GetValue(config, 'loader', {}), - x0 = calcMatrix.getX(sizeA, 0); - y0 = calcMatrix.getY(sizeA, 0); + // Plugins - x1 = calcMatrix.getX(0, sizeB); - y1 = calcMatrix.getY(0, sizeB); + plugins: GetValue(config, 'plugins', false), - x2 = calcMatrix.getX(0, sizeB - height); - y2 = calcMatrix.getY(0, sizeB - height); + // Input - x3 = calcMatrix.getX(sizeA, -height); - y3 = calcMatrix.getY(sizeA, -height); + input: GetValue(config, 'input', {}) - pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); + }; } - renderer.pipelines.postBatch(src); }; -module.exports = IsoBoxWebGLRenderer; +module.exports = Settings; /***/ }), -/* 1111 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 63946: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillStyleCanvas = __webpack_require__(48); -var SetTransform = __webpack_require__(30); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(92980); +var DefaultPlugins = __webpack_require__(18360); +var Events = __webpack_require__(7599); +var GetPhysicsPlugins = __webpack_require__(47736); +var GetScenePlugins = __webpack_require__(91088); +var NOOP = __webpack_require__(72283); +var Settings = __webpack_require__(36765); /** - * 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. + * @classdesc + * The Scene Systems class. * - * @method Phaser.GameObjects.IsoBox#renderCanvas - * @since 3.13.0 - * @private + * This class is available from within a Scene under the property `sys`. + * It is responsible for managing all of the plugins a Scene has running, including the display list, and + * handling the update step and renderer. It also contains references to global systems belonging to Game. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.IsoBox} 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 + * @class Systems + * @memberof Phaser.Scenes + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene that owns this Systems instance. + * @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - Scene specific configuration settings. */ -var IsoBoxCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); +var Systems = new Class({ - var ctx = renderer.currentContext; + initialize: - if (SetTransform(renderer, ctx, src, camera, parentMatrix) && src.isFilled) + function Systems (scene, config) { - var size = src.width; - var height = src.height; - - var sizeA = size / 2; - var sizeB = size / src.projection; + /** + * A reference to the Scene that these Systems belong to. + * + * @name Phaser.Scenes.Systems#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - // Top Face + /** + * A reference to the Phaser Game instance. + * + * @name Phaser.Scenes.Systems#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game; - if (src.showTop) - { - FillStyleCanvas(ctx, src, src.fillTop); + /** + * A reference to either the Canvas or WebGL Renderer that this Game is using. + * + * @name Phaser.Scenes.Systems#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.17.0 + */ + this.renderer; - ctx.beginPath(); + if (false) + {} - ctx.moveTo(-sizeA, -height); - ctx.lineTo(0, -sizeB - height); - ctx.lineTo(sizeA, -height); - ctx.lineTo(sizeA, -1); - ctx.lineTo(0, sizeB - 1); - ctx.lineTo(-sizeA, -1); - ctx.lineTo(-sizeA, -height); + /** + * The Scene Configuration object, as passed in when creating the Scene. + * + * @name Phaser.Scenes.Systems#config + * @type {(string|Phaser.Types.Scenes.SettingsConfig)} + * @since 3.0.0 + */ + this.config = config; - ctx.fill(); - } + /** + * The Scene Settings. This is the parsed output based on the Scene configuration. + * + * @name Phaser.Scenes.Systems#settings + * @type {Phaser.Types.Scenes.SettingsObject} + * @since 3.0.0 + */ + this.settings = Settings.create(config); - // Left Face + /** + * A handy reference to the Scene canvas / context. + * + * @name Phaser.Scenes.Systems#canvas + * @type {HTMLCanvasElement} + * @since 3.0.0 + */ + this.canvas; - if (src.showLeft) - { - FillStyleCanvas(ctx, src, src.fillLeft); + /** + * A reference to the Canvas Rendering Context being used by the renderer. + * + * @name Phaser.Scenes.Systems#context + * @type {CanvasRenderingContext2D} + * @since 3.0.0 + */ + this.context; - ctx.beginPath(); + // Global Systems - these are single-instance global managers that belong to Game - ctx.moveTo(-sizeA, 0); - ctx.lineTo(0, sizeB); - ctx.lineTo(0, sizeB - height); - ctx.lineTo(-sizeA, -height); - ctx.lineTo(-sizeA, 0); + /** + * A reference to the global Animations Manager. + * + * In the default set-up you can access this from within a Scene via the `this.anims` property. + * + * @name Phaser.Scenes.Systems#anims + * @type {Phaser.Animations.AnimationManager} + * @since 3.0.0 + */ + this.anims; - ctx.fill(); - } + /** + * A reference to the global Cache. The Cache stores all files bought in to Phaser via + * the Loader, with the exception of images. Images are stored in the Texture Manager. + * + * In the default set-up you can access this from within a Scene via the `this.cache` property. + * + * @name Phaser.Scenes.Systems#cache + * @type {Phaser.Cache.CacheManager} + * @since 3.0.0 + */ + this.cache; - // Right Face + /** + * A reference to the global Plugins Manager. + * + * In the default set-up you can access this from within a Scene via the `this.plugins` property. + * + * @name Phaser.Scenes.Systems#plugins + * @type {Phaser.Plugins.PluginManager} + * @since 3.0.0 + */ + this.plugins; - if (src.showRight) - { - FillStyleCanvas(ctx, src, src.fillRight); + /** + * A reference to the global registry. This is a game-wide instance of the Data Manager, allowing + * you to exchange data between Scenes via a universal and shared point. + * + * In the default set-up you can access this from within a Scene via the `this.registry` property. + * + * @name Phaser.Scenes.Systems#registry + * @type {Phaser.Data.DataManager} + * @since 3.0.0 + */ + this.registry; - ctx.beginPath(); + /** + * A reference to the global Scale Manager. + * + * In the default set-up you can access this from within a Scene via the `this.scale` property. + * + * @name Phaser.Scenes.Systems#scale + * @type {Phaser.Scale.ScaleManager} + * @since 3.15.0 + */ + this.scale; - ctx.moveTo(sizeA, 0); - ctx.lineTo(0, sizeB); - ctx.lineTo(0, sizeB - height); - ctx.lineTo(sizeA, -height); - ctx.lineTo(sizeA, 0); + /** + * A reference to the global Sound Manager. + * + * In the default set-up you can access this from within a Scene via the `this.sound` property. + * + * @name Phaser.Scenes.Systems#sound + * @type {(Phaser.Sound.NoAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager)} + * @since 3.0.0 + */ + this.sound; - ctx.fill(); - } + /** + * A reference to the global Texture Manager. + * + * In the default set-up you can access this from within a Scene via the `this.textures` property. + * + * @name Phaser.Scenes.Systems#textures + * @type {Phaser.Textures.TextureManager} + * @since 3.0.0 + */ + this.textures; - // Restore the context saved in SetTransform - ctx.restore(); - } -}; + // Core Plugins - these are non-optional Scene plugins, needed by lots of the other systems -module.exports = IsoBoxCanvasRenderer; + /** + * A reference to the Scene's Game Object Factory. + * + * Use this to quickly and easily create new Game Object's. + * + * In the default set-up you can access this from within a Scene via the `this.add` property. + * + * @name Phaser.Scenes.Systems#add + * @type {Phaser.GameObjects.GameObjectFactory} + * @since 3.0.0 + */ + this.add; + /** + * A reference to the Scene's Camera Manager. + * + * Use this to manipulate and create Cameras for this specific Scene. + * + * In the default set-up you can access this from within a Scene via the `this.cameras` property. + * + * @name Phaser.Scenes.Systems#cameras + * @type {Phaser.Cameras.Scene2D.CameraManager} + * @since 3.0.0 + */ + this.cameras; -/***/ }), -/* 1112 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * A reference to the Scene's Display List. + * + * Use this to organize the children contained in the display list. + * + * In the default set-up you can access this from within a Scene via the `this.children` property. + * + * @name Phaser.Scenes.Systems#displayList + * @type {Phaser.GameObjects.DisplayList} + * @since 3.0.0 + */ + this.displayList; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * A reference to the Scene's Event Manager. + * + * Use this to listen for Scene specific events, such as `pause` and `shutdown`. + * + * In the default set-up you can access this from within a Scene via the `this.events` property. + * + * @name Phaser.Scenes.Systems#events + * @type {Phaser.Events.EventEmitter} + * @since 3.0.0 + */ + this.events; -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + /** + * A reference to the Scene's Game Object Creator. + * + * Use this to quickly and easily create new Game Object's. The difference between this and the + * Game Object Factory, is that the Creator just creates and returns Game Object instances, it + * doesn't then add them to the Display List or Update List. + * + * In the default set-up you can access this from within a Scene via the `this.make` property. + * + * @name Phaser.Scenes.Systems#make + * @type {Phaser.GameObjects.GameObjectCreator} + * @since 3.0.0 + */ + this.make; -if (true) -{ - renderWebGL = __webpack_require__(1113); -} + /** + * A reference to the Scene Manager Plugin. + * + * Use this to manipulate both this and other Scene's in your game, for example to launch a parallel Scene, + * or pause or resume a Scene, or switch from this Scene to another. + * + * In the default set-up you can access this from within a Scene via the `this.scene` property. + * + * @name Phaser.Scenes.Systems#scenePlugin + * @type {Phaser.Scenes.ScenePlugin} + * @since 3.0.0 + */ + this.scenePlugin; -if (true) -{ - renderCanvas = __webpack_require__(1114); -} + /** + * A reference to the Scene's Update List. + * + * Use this to organize the children contained in the update list. + * + * The Update List is responsible for managing children that need their `preUpdate` methods called, + * in order to process so internal components, such as Sprites with Animations. + * + * In the default set-up there is no reference to this from within the Scene itself. + * + * @name Phaser.Scenes.Systems#updateList + * @type {Phaser.GameObjects.UpdateList} + * @since 3.0.0 + */ + this.updateList; -module.exports = { + /** + * The Scene Update function. + * + * This starts out as NOOP during init, preload and create, and at the end of create + * it swaps to be whatever the Scene.update function is. + * + * @name Phaser.Scenes.Systems#sceneUpdate + * @type {function} + * @private + * @since 3.10.0 + */ + this.sceneUpdate = NOOP; + }, - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + /** + * This method is called only once by the Scene Manager when the Scene is instantiated. + * It is responsible for setting up all of the Scene plugins and references. + * It should never be called directly. + * + * @method Phaser.Scenes.Systems#init + * @protected + * @fires Phaser.Scenes.Events#BOOT + * @since 3.0.0 + * + * @param {Phaser.Game} game - A reference to the Phaser Game instance. + */ + init: function (game) + { + this.settings.status = CONST.INIT; -}; + // This will get replaced by the SceneManager with the actual update function, if it exists, once create is over. + this.sceneUpdate = NOOP; + this.game = game; + this.renderer = game.renderer; -/***/ }), -/* 1113 */ -/***/ (function(module, exports, __webpack_require__) { + this.canvas = game.canvas; + this.context = game.context; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var pluginManager = game.plugins; -var GetCalcMatrix = __webpack_require__(19); -var Utils = __webpack_require__(12); + this.plugins = pluginManager; -/** - * 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.IsoTriangle#renderWebGL - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.IsoTriangle} 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 IsoTriangleWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + pluginManager.addToScene(this, DefaultPlugins.Global, [ DefaultPlugins.CoreScene, GetScenePlugins(this), GetPhysicsPlugins(this) ]); - var pipeline = renderer.pipelines.set(src.pipeline); + this.events.emit(Events.BOOT, this); - var result = GetCalcMatrix(src, camera, parentMatrix); + this.settings.isBooted = true; + }, - var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); + /** + * A single game step. Called automatically by the Scene Manager as a result of a Request Animation + * Frame or Set Timeout call to the main Game instance. + * + * @method Phaser.Scenes.Systems#step + * @fires Phaser.Scenes.Events#PRE_UPDATE + * @fires Phaser.Scenes.Events#UPDATE + * @fires Phaser.Scenes.Events#POST_UPDATE + * @since 3.0.0 + * + * @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now(). + * @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class. + */ + step: function (time, delta) + { + var events = this.events; - var size = src.width; - var height = src.height; + events.emit(Events.PRE_UPDATE, time, delta); - var sizeA = size / 2; - var sizeB = size / src.projection; + events.emit(Events.UPDATE, time, delta); - var reversed = src.isReversed; + this.sceneUpdate.call(this.scene, time, delta); - var alpha = camera.alpha * src.alpha; + events.emit(Events.POST_UPDATE, time, delta); + }, - if (!src.isFilled) + /** + * Called automatically by the Scene Manager. + * Instructs the Scene to render itself via its Camera Manager to the renderer given. + * + * @method Phaser.Scenes.Systems#render + * @fires Phaser.Scenes.Events#PRE_RENDER + * @fires Phaser.Scenes.Events#RENDER + * @since 3.0.0 + * + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that invoked the render call. + */ + render: function (renderer) { - return; - } - - renderer.pipelines.preBatch(src); - - var tint; + var displayList = this.displayList; - var x0; - var y0; + displayList.depthSort(); - var x1; - var y1; + this.events.emit(Events.PRE_RENDER, renderer); - var x2; - var y2; + this.cameras.render(renderer, displayList); - // Top Face + this.events.emit(Events.RENDER, renderer); + }, - if (src.showTop && reversed) + /** + * Force a sort of the display list on the next render. + * + * @method Phaser.Scenes.Systems#queueDepthSort + * @since 3.0.0 + */ + queueDepthSort: function () { - tint = Utils.getTintAppendFloatAlpha(src.fillTop, alpha); + this.displayList.queueDepthSort(); + }, - x0 = calcMatrix.getX(-sizeA, -height); - y0 = calcMatrix.getY(-sizeA, -height); + /** + * Immediately sorts the display list if the flag is set. + * + * @method Phaser.Scenes.Systems#depthSort + * @since 3.0.0 + */ + depthSort: function () + { + this.displayList.depthSort(); + }, - x1 = calcMatrix.getX(0, -sizeB - height); - y1 = calcMatrix.getY(0, -sizeB - height); + /** + * Pause this Scene. + * + * A paused Scene still renders, it just doesn't run any of its update handlers or systems. + * + * @method Phaser.Scenes.Systems#pause + * @fires Phaser.Scenes.Events#PAUSE + * @since 3.0.0 + * + * @param {object} [data] - A data object that will be passed in the 'pause' event. + * + * @return {Phaser.Scenes.Systems} This Systems object. + */ + pause: function (data) + { + var settings = this.settings; + var status = this.getStatus(); - x2 = calcMatrix.getX(sizeA, -height); - y2 = calcMatrix.getY(sizeA, -height); + if (status !== CONST.CREATING && status !== CONST.RUNNING) + { + console.warn('Cannot pause non-running Scene', settings.key); + } + else if (this.settings.active) + { + settings.status = CONST.PAUSED; - var x3 = calcMatrix.getX(0, sizeB - height); - var y3 = calcMatrix.getY(0, sizeB - height); + settings.active = false; - pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2); - } + this.events.emit(Events.PAUSE, this, data); + } - // Left Face + return this; + }, - if (src.showLeft) + /** + * Resume this Scene from a paused state. + * + * @method Phaser.Scenes.Systems#resume + * @fires Phaser.Scenes.Events#RESUME + * @since 3.0.0 + * + * @param {object} [data] - A data object that will be passed in the 'resume' event. + * + * @return {Phaser.Scenes.Systems} This Systems object. + */ + resume: function (data) { - tint = Utils.getTintAppendFloatAlpha(src.fillLeft, alpha); - - if (reversed) - { - x0 = calcMatrix.getX(-sizeA, -height); - y0 = calcMatrix.getY(-sizeA, -height); - - x1 = calcMatrix.getX(0, sizeB); - y1 = calcMatrix.getY(0, sizeB); + var events = this.events; + var settings = this.settings; - x2 = calcMatrix.getX(0, sizeB - height); - y2 = calcMatrix.getY(0, sizeB - height); - } - else + if (!this.settings.active) { - x0 = calcMatrix.getX(-sizeA, 0); - y0 = calcMatrix.getY(-sizeA, 0); + settings.status = CONST.RUNNING; - x1 = calcMatrix.getX(0, sizeB); - y1 = calcMatrix.getY(0, sizeB); + settings.active = true; - x2 = calcMatrix.getX(0, sizeB - height); - y2 = calcMatrix.getY(0, sizeB - height); + events.emit(Events.RESUME, this, data); } - pipeline.batchTri(src, x0, y0, x1, y1, x2, y2, 0, 0, 1, 1, tint, tint, tint, 2); - } - - // Right Face + return this; + }, - if (src.showRight) + /** + * Send this Scene to sleep. + * + * A sleeping Scene doesn't run its update step or render anything, but it also isn't shut down + * or has any of its systems or children removed, meaning it can be re-activated at any point and + * will carry on from where it left off. It also keeps everything in memory and events and callbacks + * from other Scenes may still invoke changes within it, so be careful what is left active. + * + * @method Phaser.Scenes.Systems#sleep + * @fires Phaser.Scenes.Events#SLEEP + * @since 3.0.0 + * + * @param {object} [data] - A data object that will be passed in the 'sleep' event. + * + * @return {Phaser.Scenes.Systems} This Systems object. + */ + sleep: function (data) { - tint = Utils.getTintAppendFloatAlpha(src.fillRight, alpha); + var settings = this.settings; + var status = this.getStatus(); - if (reversed) + if (status !== CONST.CREATING && status !== CONST.RUNNING) { - x0 = calcMatrix.getX(sizeA, -height); - y0 = calcMatrix.getY(sizeA, -height); - - x1 = calcMatrix.getX(0, sizeB); - y1 = calcMatrix.getY(0, sizeB); - - x2 = calcMatrix.getX(0, sizeB - height); - y2 = calcMatrix.getY(0, sizeB - height); + console.warn('Cannot sleep non-running Scene', settings.key); } else { - x0 = calcMatrix.getX(sizeA, 0); - y0 = calcMatrix.getY(sizeA, 0); + settings.status = CONST.SLEEPING; - x1 = calcMatrix.getX(0, sizeB); - y1 = calcMatrix.getY(0, sizeB); + settings.active = false; + settings.visible = false; - x2 = calcMatrix.getX(0, sizeB - height); - y2 = calcMatrix.getY(0, sizeB - height); + this.events.emit(Events.SLEEP, this, data); } - pipeline.batchTri(src, x0, y0, x1, y1, x2, y2, 0, 0, 1, 1, tint, tint, tint, 2); - } - - renderer.pipelines.postBatch(src); -}; + return this; + }, -module.exports = IsoTriangleWebGLRenderer; + /** + * Wake-up this Scene if it was previously asleep. + * + * @method Phaser.Scenes.Systems#wake + * @fires Phaser.Scenes.Events#WAKE + * @since 3.0.0 + * + * @param {object} [data] - A data object that will be passed in the 'wake' event. + * + * @return {Phaser.Scenes.Systems} This Systems object. + */ + wake: function (data) + { + var events = this.events; + var settings = this.settings; + settings.status = CONST.RUNNING; -/***/ }), -/* 1114 */ -/***/ (function(module, exports, __webpack_require__) { + settings.active = true; + settings.visible = true; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + events.emit(Events.WAKE, this, data); -var FillStyleCanvas = __webpack_require__(48); -var SetTransform = __webpack_require__(30); + if (settings.isTransition) + { + events.emit(Events.TRANSITION_WAKE, settings.transitionFrom, settings.transitionDuration); + } -/** - * 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.IsoTriangle#renderCanvas - * @since 3.13.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.IsoTriangle} 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 IsoTriangleCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + return this; + }, - var ctx = renderer.currentContext; + /** + * Returns any data that was sent to this Scene by another Scene. + * + * The data is also passed to `Scene.init` and in various Scene events, but + * you can access it at any point via this method. + * + * @method Phaser.Scenes.Systems#getData + * @since 3.22.0 + * + * @return {any} The Scene Data. + */ + getData: function () + { + return this.settings.data; + }, - if (SetTransform(renderer, ctx, src, camera, parentMatrix) && src.isFilled) + /** + * Returns the current status of this Scene. + * + * @method Phaser.Scenes.Systems#getStatus + * @since 3.60.0 + * + * @return {number} The status of this Scene. One of the `Phaser.Scene` constants. + */ + getStatus: function () { - var size = src.width; - var height = src.height; + return this.settings.status; + }, - var sizeA = size / 2; - var sizeB = size / src.projection; + /** + * Can this Scene receive Input events? + * + * @method Phaser.Scenes.Systems#canInput + * @since 3.60.0 + * + * @return {boolean} `true` if this Scene can receive Input events. + */ + canInput: function () + { + var status = this.settings.status; - var reversed = src.isReversed; + return (status > CONST.PENDING && status <= CONST.RUNNING); + }, - // Top Face + /** + * Is this Scene sleeping? + * + * @method Phaser.Scenes.Systems#isSleeping + * @since 3.0.0 + * + * @return {boolean} `true` if this Scene is asleep, otherwise `false`. + */ + isSleeping: function () + { + return (this.settings.status === CONST.SLEEPING); + }, - if (src.showTop && reversed) - { - FillStyleCanvas(ctx, src, src.fillTop); + /** + * Is this Scene running? + * + * @method Phaser.Scenes.Systems#isActive + * @since 3.0.0 + * + * @return {boolean} `true` if this Scene is running, otherwise `false`. + */ + isActive: function () + { + return (this.settings.status === CONST.RUNNING); + }, - ctx.beginPath(); + /** + * Is this Scene paused? + * + * @method Phaser.Scenes.Systems#isPaused + * @since 3.13.0 + * + * @return {boolean} `true` if this Scene is paused, otherwise `false`. + */ + isPaused: function () + { + return (this.settings.status === CONST.PAUSED); + }, - ctx.moveTo(-sizeA, -height); - ctx.lineTo(0, -sizeB - height); - ctx.lineTo(sizeA, -height); - ctx.lineTo(0, sizeB - height); + /** + * Is this Scene currently transitioning out to, or in from another Scene? + * + * @method Phaser.Scenes.Systems#isTransitioning + * @since 3.5.0 + * + * @return {boolean} `true` if this Scene is currently transitioning, otherwise `false`. + */ + isTransitioning: function () + { + return (this.settings.isTransition || this.scenePlugin._target !== null); + }, - ctx.fill(); - } + /** + * Is this Scene currently transitioning out from itself to another Scene? + * + * @method Phaser.Scenes.Systems#isTransitionOut + * @since 3.5.0 + * + * @return {boolean} `true` if this Scene is in transition to another Scene, otherwise `false`. + */ + isTransitionOut: function () + { + return (this.scenePlugin._target !== null && this.scenePlugin._duration > 0); + }, - // Left Face + /** + * Is this Scene currently transitioning in from another Scene? + * + * @method Phaser.Scenes.Systems#isTransitionIn + * @since 3.5.0 + * + * @return {boolean} `true` if this Scene is transitioning in from another Scene, otherwise `false`. + */ + isTransitionIn: function () + { + return (this.settings.isTransition); + }, - if (src.showLeft) - { - FillStyleCanvas(ctx, src, src.fillLeft); + /** + * Is this Scene visible and rendering? + * + * @method Phaser.Scenes.Systems#isVisible + * @since 3.0.0 + * + * @return {boolean} `true` if this Scene is visible, otherwise `false`. + */ + isVisible: function () + { + return this.settings.visible; + }, - ctx.beginPath(); + /** + * Sets the visible state of this Scene. + * An invisible Scene will not render, but will still process updates. + * + * @method Phaser.Scenes.Systems#setVisible + * @since 3.0.0 + * + * @param {boolean} value - `true` to render this Scene, otherwise `false`. + * + * @return {Phaser.Scenes.Systems} This Systems object. + */ + setVisible: function (value) + { + this.settings.visible = value; - if (reversed) - { - ctx.moveTo(-sizeA, -height); - ctx.lineTo(0, sizeB); - ctx.lineTo(0, sizeB - height); - } - else - { - ctx.moveTo(-sizeA, 0); - ctx.lineTo(0, sizeB); - ctx.lineTo(0, sizeB - height); - } + return this; + }, - ctx.fill(); + /** + * Set the active state of this Scene. + * + * An active Scene will run its core update loop. + * + * @method Phaser.Scenes.Systems#setActive + * @since 3.0.0 + * + * @param {boolean} value - If `true` the Scene will be resumed, if previously paused. If `false` it will be paused. + * @param {object} [data] - A data object that will be passed in the 'resume' or 'pause' events. + * + * @return {Phaser.Scenes.Systems} This Systems object. + */ + setActive: function (value, data) + { + if (value) + { + return this.resume(data); + } + else + { + return this.pause(data); } + }, - // Right Face + /** + * Start this Scene running and rendering. + * Called automatically by the SceneManager. + * + * @method Phaser.Scenes.Systems#start + * @fires Phaser.Scenes.Events#START + * @fires Phaser.Scenes.Events#READY + * @since 3.0.0 + * + * @param {object} data - Optional data object that may have been passed to this Scene from another. + */ + start: function (data) + { + var events = this.events; + var settings = this.settings; - if (src.showRight) + if (data) { - FillStyleCanvas(ctx, src, src.fillRight); + settings.data = data; + } - ctx.beginPath(); + settings.status = CONST.START; - if (reversed) - { - ctx.moveTo(sizeA, -height); - ctx.lineTo(0, sizeB); - ctx.lineTo(0, sizeB - height); - } - else - { - ctx.moveTo(sizeA, 0); - ctx.lineTo(0, sizeB); - ctx.lineTo(0, sizeB - height); - } + settings.active = true; + settings.visible = true; + + // For plugins to listen out for + events.emit(Events.START, this); + + // For user-land code to listen out for + events.emit(Events.READY, this, data); + }, + + /** + * Shutdown this Scene and send a shutdown event to all of its systems. + * A Scene that has been shutdown will not run its update loop or render, but it does + * not destroy any of its plugins or references. It is put into hibernation for later use. + * If you don't ever plan to use this Scene again, then it should be destroyed instead + * to free-up resources. + * + * @method Phaser.Scenes.Systems#shutdown + * @fires Phaser.Scenes.Events#SHUTDOWN + * @since 3.0.0 + * + * @param {object} [data] - A data object that will be passed in the 'shutdown' event. + */ + shutdown: function (data) + { + var events = this.events; + var settings = this.settings; + + events.off(Events.TRANSITION_INIT); + events.off(Events.TRANSITION_START); + events.off(Events.TRANSITION_COMPLETE); + events.off(Events.TRANSITION_OUT); - ctx.fill(); - } + settings.status = CONST.SHUTDOWN; - // Restore the context saved in SetTransform - ctx.restore(); - } -}; + settings.active = false; + settings.visible = false; -module.exports = IsoTriangleCanvasRenderer; + events.emit(Events.SHUTDOWN, this, data); + }, + /** + * Destroy this Scene and send a destroy event all of its systems. + * A destroyed Scene cannot be restarted. + * You should not call this directly, instead use `SceneManager.remove`. + * + * @method Phaser.Scenes.Systems#destroy + * @private + * @fires Phaser.Scenes.Events#DESTROY + * @since 3.0.0 + */ + destroy: function () + { + var events = this.events; + var settings = this.settings; -/***/ }), -/* 1115 */ -/***/ (function(module, exports, __webpack_require__) { + settings.status = CONST.DESTROYED; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + settings.active = false; + settings.visible = false; -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + events.emit(Events.DESTROY, this); -if (true) -{ - renderWebGL = __webpack_require__(1116); -} + events.removeAllListeners(); -if (true) -{ - renderCanvas = __webpack_require__(1117); -} + var props = [ 'scene', 'game', 'anims', 'cache', 'plugins', 'registry', 'sound', 'textures', 'add', 'camera', 'displayList', 'events', 'make', 'scenePlugin', 'updateList' ]; -module.exports = { + for (var i = 0; i < props.length; i++) + { + this[props[i]] = null; + } + } - renderWebGL: renderWebGL, - renderCanvas: renderCanvas +}); -}; +module.exports = Systems; /***/ }), -/* 1116 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 92980: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(19); -var Utils = __webpack_require__(12); - /** - * 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.Line#renderWebGL - * @since 3.13.0 - * @private + * Scene consts. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Line} 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 + * @ignore */ -var LineWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - var pipeline = renderer.pipelines.set(src.pipeline); +var CONST = { - var result = GetCalcMatrix(src, camera, parentMatrix); + /** + * Scene state. + * + * @name Phaser.Scenes.PENDING + * @readonly + * @type {number} + * @since 3.0.0 + */ + PENDING: 0, - pipeline.calcMatrix.copyFrom(result.calc); + /** + * Scene state. + * + * @name Phaser.Scenes.INIT + * @readonly + * @type {number} + * @since 3.0.0 + */ + INIT: 1, - var dx = src._displayOriginX; - var dy = src._displayOriginY; - var alpha = camera.alpha * src.alpha; + /** + * Scene state. + * + * @name Phaser.Scenes.START + * @readonly + * @type {number} + * @since 3.0.0 + */ + START: 2, - renderer.pipelines.preBatch(src); + /** + * Scene state. + * + * @name Phaser.Scenes.LOADING + * @readonly + * @type {number} + * @since 3.0.0 + */ + LOADING: 3, - if (src.isStroked) - { - var strokeTint = pipeline.strokeTint; - var color = Utils.getTintAppendFloatAlpha(src.strokeColor, src.strokeAlpha * alpha); + /** + * Scene state. + * + * @name Phaser.Scenes.CREATING + * @readonly + * @type {number} + * @since 3.0.0 + */ + CREATING: 4, - strokeTint.TL = color; - strokeTint.TR = color; - strokeTint.BL = color; - strokeTint.BR = color; + /** + * Scene state. + * + * @name Phaser.Scenes.RUNNING + * @readonly + * @type {number} + * @since 3.0.0 + */ + RUNNING: 5, - var startWidth = src._startWidth; - var endWidth = src._endWidth; + /** + * Scene state. + * + * @name Phaser.Scenes.PAUSED + * @readonly + * @type {number} + * @since 3.0.0 + */ + PAUSED: 6, - pipeline.batchLine( - src.geom.x1 - dx, - src.geom.y1 - dy, - src.geom.x2 - dx, - src.geom.y2 - dy, - startWidth, - endWidth, - 1, - 0, - false, - result.sprite, - result.camera - ); - } + /** + * Scene state. + * + * @name Phaser.Scenes.SLEEPING + * @readonly + * @type {number} + * @since 3.0.0 + */ + SLEEPING: 7, + + /** + * Scene state. + * + * @name Phaser.Scenes.SHUTDOWN + * @readonly + * @type {number} + * @since 3.0.0 + */ + SHUTDOWN: 8, + + /** + * Scene state. + * + * @name Phaser.Scenes.DESTROYED + * @readonly + * @type {number} + * @since 3.0.0 + */ + DESTROYED: 9 - renderer.pipelines.postBatch(src); }; -module.exports = LineWebGLRenderer; +module.exports = CONST; /***/ }), -/* 1117 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 31803: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var LineStyleCanvas = __webpack_require__(60); -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. + * The Game Object Added to Scene Event. * - * @method Phaser.GameObjects.Line#renderCanvas - * @since 3.13.0 - * @private + * This event is dispatched when a Game Object is added to a Scene. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Line} 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 + * Listen for it from a Scene using `this.events.on('addedtoscene', listener)`. + * + * @event Phaser.Scenes.Events#ADDED_TO_SCENE + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the Scene. + * @param {Phaser.Scene} scene - The Scene to which the Game Object was added. */ -var LineCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var ctx = renderer.currentContext; - - if (SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - var dx = src._displayOriginX; - var dy = src._displayOriginY; - - if (src.isStroked) - { - LineStyleCanvas(ctx, src); - - ctx.beginPath(); - - ctx.moveTo(src.geom.x1 - dx, src.geom.y1 - dy); - ctx.lineTo(src.geom.x2 - dx, src.geom.y2 - dy); - - ctx.stroke(); - } - - // Restore the context saved in SetTransform - ctx.restore(); - } -}; - -module.exports = LineCanvasRenderer; +module.exports = 'addedtoscene'; /***/ }), -/* 1118 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 94817: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1119); -} - -if (true) -{ - renderCanvas = __webpack_require__(1120); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; +/** + * The Scene Systems Boot Event. + * + * This event is dispatched by a Scene during the Scene Systems boot process. Primarily used by Scene Plugins. + * + * Listen to it from a Scene using `this.events.on('boot', listener)`. + * + * @event Phaser.Scenes.Events#BOOT + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + */ +module.exports = 'boot'; /***/ }), -/* 1119 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 28977: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(114); -var GetCalcMatrix = __webpack_require__(19); -var StrokePathWebGL = __webpack_require__(81); - /** - * 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. + * The Scene Create Event. * - * @method Phaser.GameObjects.Polygon#renderWebGL - * @since 3.13.0 - * @private + * This event is dispatched by a Scene after it has been created by the Scene Manager. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Polygon} 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 + * If a Scene has a `create` method then this event is emitted _after_ that has run. + * + * If there is a transition, this event will be fired after the `TRANSITION_START` event. + * + * Listen to it from a Scene using `this.events.on('create', listener)`. + * + * @event Phaser.Scenes.Events#CREATE + * @type {string} + * @since 3.17.0 + * + * @param {Phaser.Scene} scene - A reference to the Scene that emitted this event. */ -var PolygonWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var pipeline = renderer.pipelines.set(src.pipeline); - - var result = GetCalcMatrix(src, camera, parentMatrix); - - var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); - - var dx = src._displayOriginX; - var dy = src._displayOriginY; - - var alpha = camera.alpha * src.alpha; - - renderer.pipelines.preBatch(src); - - if (src.isFilled) - { - FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); - } - - if (src.isStroked) - { - StrokePathWebGL(pipeline, src, alpha, dx, dy); - } - - renderer.pipelines.postBatch(src); -}; - -module.exports = PolygonWebGLRenderer; +module.exports = 'create'; /***/ }), -/* 1120 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 91959: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillStyleCanvas = __webpack_require__(48); -var LineStyleCanvas = __webpack_require__(60); -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. + * The Scene Systems Destroy Event. * - * @method Phaser.GameObjects.Polygon#renderCanvas - * @since 3.13.0 - * @private + * This event is dispatched by a Scene during the Scene Systems destroy process. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Polygon} 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 + * Listen to it from a Scene using `this.events.on('destroy', listener)`. + * + * You should destroy any resources that may be in use by your Scene in this event handler. + * + * @event Phaser.Scenes.Events#DESTROY + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. */ -var PolygonCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var ctx = renderer.currentContext; - - if (SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - var dx = src._displayOriginX; - var dy = src._displayOriginY; - - var path = src.pathData; - var pathLength = path.length - 1; - - var px1 = path[0] - dx; - var py1 = path[1] - dy; - - ctx.beginPath(); - - ctx.moveTo(px1, py1); - - if (!src.closePath) - { - pathLength -= 2; - } - - for (var i = 2; i < pathLength; i += 2) - { - var px2 = path[i] - dx; - var py2 = path[i + 1] - dy; - - ctx.lineTo(px2, py2); - } - - ctx.closePath(); - - if (src.isFilled) - { - FillStyleCanvas(ctx, src); - - ctx.fill(); - } - - if (src.isStroked) - { - LineStyleCanvas(ctx, src); - - ctx.stroke(); - } - - // Restore the context saved in SetTransform - ctx.restore(); - } -}; - -module.exports = PolygonCanvasRenderer; +module.exports = 'destroy'; /***/ }), -/* 1121 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 363: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1122); -} - -if (true) -{ - renderCanvas = __webpack_require__(1123); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; +/** + * The Scene Systems Pause Event. + * + * This event is dispatched by a Scene when it is paused, either directly via the `pause` method, or as an + * action from another Scene. + * + * Listen to it from a Scene using `this.events.on('pause', listener)`. + * + * @event Phaser.Scenes.Events#PAUSE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + * @param {any} [data] - An optional data object that was passed to this Scene when it was paused. + */ +module.exports = 'pause'; /***/ }), -/* 1122 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 15643: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(19); -var StrokePathWebGL = __webpack_require__(81); -var Utils = __webpack_require__(12); - /** - * 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. + * The Scene Systems Post Update Event. * - * @method Phaser.GameObjects.Rectangle#renderWebGL - * @since 3.13.0 - * @private + * This event is dispatched by a Scene during the main game loop step. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Rectangle} 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 + * The event flow for a single step of a Scene is as follows: + * + * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} + * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} + * 3. The `Scene.update` method is called, if it exists + * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} + * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} + * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} + * + * Listen to it from a Scene using `this.events.on('postupdate', listener)`. + * + * A Scene will only run its step if it is active. + * + * @event Phaser.Scenes.Events#POST_UPDATE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. */ -var RectangleWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var pipeline = renderer.pipelines.set(src.pipeline); - - var result = GetCalcMatrix(src, camera, parentMatrix); - - pipeline.calcMatrix.copyFrom(result.calc); - - var dx = src._displayOriginX; - var dy = src._displayOriginY; - var alpha = camera.alpha * src.alpha; - - renderer.pipelines.preBatch(src); - - if (src.isFilled) - { - var fillTint = pipeline.fillTint; - var fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha); - - fillTint.TL = fillTintColor; - fillTint.TR = fillTintColor; - fillTint.BL = fillTintColor; - fillTint.BR = fillTintColor; - - pipeline.batchFillRect( - -dx, - -dy, - src.width, - src.height - ); - } - - if (src.isStroked) - { - StrokePathWebGL(pipeline, src, alpha, dx, dy); - } - - renderer.pipelines.postBatch(src); -}; - -module.exports = RectangleWebGLRenderer; +module.exports = 'postupdate'; /***/ }), -/* 1123 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 17058: +/***/ ((module) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author samme + * @copyright 2021 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillStyleCanvas = __webpack_require__(48); -var LineStyleCanvas = __webpack_require__(60); -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. + * The Scene Systems Pre-Render Event. * - * @method Phaser.GameObjects.Rectangle#renderCanvas - * @since 3.13.0 - * @private + * This event is dispatched by a Scene during the main game loop step. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Rectangle} 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 + * The event flow for a single step of a Scene is as follows: + * + * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} + * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} + * 3. The `Scene.update` method is called, if it exists + * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} + * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} + * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} + * + * Listen to this event from a Scene using `this.events.on('prerender', listener)`. + * + * A Scene will only render if it is visible. + * + * This event is dispatched after the Scene Display List is sorted and before the Scene is rendered. + * + * @event Phaser.Scenes.Events#PRE_RENDER + * @type {string} + * @since 3.53.0 + * + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that rendered the Scene. */ -var RectangleCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var ctx = renderer.currentContext; - - if (SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - var dx = src._displayOriginX; - var dy = src._displayOriginY; - - if (src.isFilled) - { - FillStyleCanvas(ctx, src); - - ctx.fillRect( - -dx, - -dy, - src.width, - src.height - ); - } - - if (src.isStroked) - { - LineStyleCanvas(ctx, src); - - ctx.beginPath(); - - ctx.rect( - -dx, - -dy, - src.width, - src.height - ); - - ctx.stroke(); - } - - // Restore the context saved in SetTransform - ctx.restore(); - } -}; - -module.exports = RectangleCanvasRenderer; +module.exports = 'prerender'; /***/ }), -/* 1124 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 77125: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1125); -} - -if (true) -{ - renderCanvas = __webpack_require__(1126); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; +/** + * The Scene Systems Pre Update Event. + * + * This event is dispatched by a Scene during the main game loop step. + * + * The event flow for a single step of a Scene is as follows: + * + * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} + * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} + * 3. The `Scene.update` method is called, if it exists + * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} + * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} + * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} + * + * Listen to it from a Scene using `this.events.on('preupdate', listener)`. + * + * A Scene will only run its step if it is active. + * + * @event Phaser.Scenes.Events#PRE_UPDATE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ +module.exports = 'preupdate'; /***/ }), -/* 1125 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 76018: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillPathWebGL = __webpack_require__(114); -var GetCalcMatrix = __webpack_require__(19); -var StrokePathWebGL = __webpack_require__(81); - /** - * 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. + * The Scene Systems Ready Event. * - * @method Phaser.GameObjects.Star#renderWebGL - * @since 3.13.0 - * @private + * This event is dispatched by a Scene during the Scene Systems start process. + * By this point in the process the Scene is now fully active and rendering. + * This event is meant for your game code to use, as all plugins have responded to the earlier 'start' event. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Star} 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 + * Listen to it from a Scene using `this.events.on('ready', listener)`. + * + * @event Phaser.Scenes.Events#READY + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + * @param {any} [data] - An optional data object that was passed to this Scene when it was started. */ -var StarWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var pipeline = renderer.pipelines.set(src.pipeline); - - var result = GetCalcMatrix(src, camera, parentMatrix); - - var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc); - - var dx = src._displayOriginX; - var dy = src._displayOriginY; - - var alpha = camera.alpha * src.alpha; - - renderer.pipelines.preBatch(src); - - if (src.isFilled) - { - FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy); - } - - if (src.isStroked) - { - StrokePathWebGL(pipeline, src, alpha, dx, dy); - } - - renderer.pipelines.postBatch(src); -}; - -module.exports = StarWebGLRenderer; +module.exports = 'ready'; /***/ }), -/* 1126 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 28620: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillStyleCanvas = __webpack_require__(48); -var LineStyleCanvas = __webpack_require__(60); -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. + * The Game Object Removed from Scene Event. * - * @method Phaser.GameObjects.Star#renderCanvas - * @since 3.13.0 - * @private + * This event is dispatched when a Game Object is removed from a Scene. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Star} 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 + * Listen for it from a Scene using `this.events.on('removedfromscene', listener)`. + * + * @event Phaser.Scenes.Events#REMOVED_FROM_SCENE + * @type {string} + * @since 3.50.0 + * + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the Scene. + * @param {Phaser.Scene} scene - The Scene from which the Game Object was removed. */ -var StarCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var ctx = renderer.currentContext; - - if (SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - var dx = src._displayOriginX; - var dy = src._displayOriginY; - - var path = src.pathData; - var pathLength = path.length - 1; - - var px1 = path[0] - dx; - var py1 = path[1] - dy; - - ctx.beginPath(); - - ctx.moveTo(px1, py1); - - if (!src.closePath) - { - pathLength -= 2; - } - - for (var i = 2; i < pathLength; i += 2) - { - var px2 = path[i] - dx; - var py2 = path[i + 1] - dy; - - ctx.lineTo(px2, py2); - } - - ctx.closePath(); - - if (src.isFilled) - { - FillStyleCanvas(ctx, src); - - ctx.fill(); - } - - if (src.isStroked) - { - LineStyleCanvas(ctx, src); - - ctx.stroke(); - } - - // Restore the context saved in SetTransform - ctx.restore(); - } -}; - -module.exports = StarCanvasRenderer; +module.exports = 'removedfromscene'; /***/ }), -/* 1127 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 41538: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1128); -} - -if (true) -{ - renderCanvas = __webpack_require__(1129); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; +/** + * The Scene Systems Render Event. + * + * This event is dispatched by a Scene during the main game loop step. + * + * The event flow for a single step of a Scene is as follows: + * + * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} + * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} + * 3. The `Scene.update` method is called, if it exists + * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} + * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} + * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} + * + * Listen to it from a Scene using `this.events.on('render', listener)`. + * + * A Scene will only render if it is visible. + * + * By the time this event is dispatched, the Scene will have already been rendered. + * + * @event Phaser.Scenes.Events#RENDER + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that rendered the Scene. + */ +module.exports = 'render'; /***/ }), -/* 1128 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 34268: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(19); -var StrokePathWebGL = __webpack_require__(81); -var Utils = __webpack_require__(12); - /** - * 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. + * The Scene Systems Resume Event. * - * @method Phaser.GameObjects.Triangle#renderWebGL - * @since 3.13.0 - * @private + * This event is dispatched by a Scene when it is resumed from a paused state, either directly via the `resume` method, + * or as an action from another Scene. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Triangle} 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 + * Listen to it from a Scene using `this.events.on('resume', listener)`. + * + * @event Phaser.Scenes.Events#RESUME + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + * @param {any} [data] - An optional data object that was passed to this Scene when it was resumed. */ -var TriangleWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var pipeline = renderer.pipelines.set(src.pipeline); - - var result = GetCalcMatrix(src, camera, parentMatrix); - - pipeline.calcMatrix.copyFrom(result.calc); - - var dx = src._displayOriginX; - var dy = src._displayOriginY; - var alpha = camera.alpha * src.alpha; - - renderer.pipelines.preBatch(src); - - if (src.isFilled) - { - var fillTint = pipeline.fillTint; - var fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha); - - fillTint.TL = fillTintColor; - fillTint.TR = fillTintColor; - fillTint.BL = fillTintColor; - fillTint.BR = fillTintColor; - - var x1 = src.geom.x1 - dx; - var y1 = src.geom.y1 - dy; - var x2 = src.geom.x2 - dx; - var y2 = src.geom.y2 - dy; - var x3 = src.geom.x3 - dx; - var y3 = src.geom.y3 - dy; - - pipeline.batchFillTriangle( - x1, - y1, - x2, - y2, - x3, - y3, - result.sprite, - result.camera - ); - } - - if (src.isStroked) - { - StrokePathWebGL(pipeline, src, alpha, dx, dy); - } - - renderer.pipelines.postBatch(src); -}; - -module.exports = TriangleWebGLRenderer; +module.exports = 'resume'; /***/ }), -/* 1129 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 2342: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var FillStyleCanvas = __webpack_require__(48); -var LineStyleCanvas = __webpack_require__(60); -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. + * The Scene Systems Shutdown Event. * - * @method Phaser.GameObjects.Triangle#renderCanvas - * @since 3.13.0 - * @private + * This event is dispatched by a Scene during the Scene Systems shutdown process. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Triangle} 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 + * Listen to it from a Scene using `this.events.on('shutdown', listener)`. + * + * You should free-up any resources that may be in use by your Scene in this event handler, on the understanding + * that the Scene may, at any time, become active again. A shutdown Scene is not 'destroyed', it's simply not + * currently active. Use the [DESTROY]{@linkcode Phaser.Scenes.Events#event:DESTROY} event to completely clear resources. + * + * @event Phaser.Scenes.Events#SHUTDOWN + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + * @param {any} [data] - An optional data object that was passed to this Scene when it was shutdown. */ -var TriangleCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); - - var ctx = renderer.currentContext; - - if (SetTransform(renderer, ctx, src, camera, parentMatrix)) - { - var dx = src._displayOriginX; - var dy = src._displayOriginY; - - var x1 = src.geom.x1 - dx; - var y1 = src.geom.y1 - dy; - var x2 = src.geom.x2 - dx; - var y2 = src.geom.y2 - dy; - var x3 = src.geom.x3 - dx; - var y3 = src.geom.y3 - dy; - - ctx.beginPath(); - - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.lineTo(x3, y3); - - ctx.closePath(); - - if (src.isFilled) - { - FillStyleCanvas(ctx, src); - - ctx.fill(); - } - - if (src.isStroked) - { - LineStyleCanvas(ctx, src); - - ctx.stroke(); - } - - // Restore the context saved in SetTransform - ctx.restore(); - } -}; - -module.exports = TriangleCanvasRenderer; +module.exports = 'shutdown'; /***/ }), -/* 1130 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 96541: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Blitter = __webpack_require__(213); -var GameObjectFactory = __webpack_require__(5); - /** - * Creates a new Blitter Game Object and adds it to the Scene. + * The Scene Systems Sleep Event. * - * Note: This method will only be available if the Blitter Game Object has been built into Phaser. + * This event is dispatched by a Scene when it is sent to sleep, either directly via the `sleep` method, + * or as an action from another Scene. * - * @method Phaser.GameObjects.GameObjectFactory#blitter - * @since 3.0.0 + * Listen to it from a Scene using `this.events.on('sleep', listener)`. * - * @param {number} x - The x position of the Game Object. - * @param {number} y - The y position of the Game Object. - * @param {string} key - The key of the Texture the Blitter object will use. - * @param {(string|number)} [frame] - The default Frame children of the Blitter will use. + * @event Phaser.Scenes.Events#SLEEP + * @type {string} + * @since 3.0.0 * - * @return {Phaser.GameObjects.Blitter} The Game Object that was created. + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + * @param {any} [data] - An optional data object that was passed to this Scene when it was sent to sleep. */ -GameObjectFactory.register('blitter', function (x, y, key, frame) -{ - return this.displayList.add(new Blitter(this.scene, x, y, key, frame)); -}); - -// When registering a factory function 'this' refers to the GameObjectFactory 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 +module.exports = 'sleep'; /***/ }), -/* 1131 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 74244: +/***/ ((module) => { /** * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Container = __webpack_require__(214); -var GameObjectFactory = __webpack_require__(5); - /** - * Creates a new Container Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Container Game Object has been built into Phaser. + * The Scene Systems Start Event. * - * @method Phaser.GameObjects.GameObjectFactory#container - * @since 3.4.0 + * This event is dispatched by a Scene during the Scene Systems start process. Primarily used by Scene Plugins. * - * @param {number} [x=0] - The horizontal position of this Game Object in the world. - * @param {number} [y=0] - The vertical position of this Game Object in the world. - * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Container. + * Listen to it from a Scene using `this.events.on('start', listener)`. * - * @return {Phaser.GameObjects.Container} The Game Object that was created. - */ -GameObjectFactory.register('container', function (x, y, children) -{ - return this.displayList.add(new Container(this.scene, x, y, children)); -}); + * @event Phaser.Scenes.Events#START + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + */ +module.exports = 'start'; /***/ }), -/* 1132 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 17046: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DOMElement = __webpack_require__(442); -var GameObjectFactory = __webpack_require__(5); - /** - * 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. - * - * 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. + * The Scene Transition Complete Event. * - * 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. + * This event is dispatched by the Target Scene of a transition. * - * Also, all DOM Elements are inserted into the same DOM Container, regardless of which Scene they are created in. + * It happens when the transition process has completed. This occurs when the duration timer equals or exceeds the duration + * of the transition. * - * 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. + * Listen to it from a Scene using `this.events.on('transitioncomplete', listener)`. * - * Note: This method will only be available if the DOM Element Game Object has been built into Phaser. + * The Scene Transition event flow is as follows: * - * @method Phaser.GameObjects.GameObjectFactory#dom - * @since 3.17.0 + * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. + * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. + * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... + * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. + * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. * - * @param {number} x - The horizontal position of this DOM Element in the world. - * @param {number} y - The vertical position of this DOM Element in the world. - * @param {(HTMLElement|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. + * @event Phaser.Scenes.Events#TRANSITION_COMPLETE + * @type {string} + * @since 3.5.0 * - * @return {Phaser.GameObjects.DOMElement} The Game Object that was created. + * @param {Phaser.Scene} scene -The Scene on which the transitioned completed. */ -GameObjectFactory.register('dom', function (x, y, element, style, innerText) -{ - var gameObject = new DOMElement(this.scene, x, y, element, style, innerText); - - this.displayList.add(gameObject); - - return gameObject; -}); +module.exports = 'transitioncomplete'; /***/ }), -/* 1133 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 13637: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var DynamicBitmapText = __webpack_require__(215); -var GameObjectFactory = __webpack_require__(5); - /** - * Creates a new Dynamic Bitmap Text Game Object and adds it to the Scene. - * - * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. - * - * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to - * match the font structure. - * - * Dynamic Bitmap Text objects are different from Static Bitmap Text in that they invoke a callback for each - * letter being rendered during the render pass. This callback allows you to manipulate the properties of - * each letter being rendered, such as its position, scale or tint, allowing you to create interesting effects - * like jiggling text, which can't be done with Static text. This means that Dynamic Text takes more processing - * time, so only use them if you require the callback ability they have. - * - * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability - * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by - * processing the font texture in an image editor, applying fills and any other effects required. - * - * To create multi-line text insert \r, \n or \r\n escape codes into the text string. + * The Scene Transition Init Event. * - * To create a BitmapText data files you need a 3rd party app such as: + * This event is dispatched by the Target Scene of a transition. * - * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/ - * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner - * Littera (Web-based, free): http://kvazars.com/littera/ + * It happens immediately after the `Scene.init` method is called. If the Scene does not have an `init` method, + * this event is not dispatched. * - * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of - * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: http://codebeautify.org/xmltojson + * Listen to it from a Scene using `this.events.on('transitioninit', listener)`. * - * Note: This method will only be available if the Dynamic Bitmap Text Game Object has been built into Phaser. + * The Scene Transition event flow is as follows: * - * @method Phaser.GameObjects.GameObjectFactory#dynamicBitmapText - * @since 3.0.0 + * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. + * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. + * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... + * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. + * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. * - * @param {number} x - The x position of the Game Object. - * @param {number} y - The y position of the Game Object. - * @param {string} font - The key of the font to use from the BitmapFont cache. - * @param {(string|string[])} [text] - The string, or array of strings, to be set as the content of this Bitmap Text. - * @param {number} [size] - The font size to set. + * @event Phaser.Scenes.Events#TRANSITION_INIT + * @type {string} + * @since 3.5.0 * - * @return {Phaser.GameObjects.DynamicBitmapText} The Game Object that was created. + * @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from. + * @param {number} duration - The duration of the transition in ms. */ -GameObjectFactory.register('dynamicBitmapText', function (x, y, font, text, size) -{ - return this.displayList.add(new DynamicBitmapText(this.scene, x, y, font, text, size)); -}); - -// When registering a factory function 'this' refers to the GameObjectFactory 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 +module.exports = 'transitioninit'; /***/ }), -/* 1134 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 14733: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extern = __webpack_require__(444); -var GameObjectFactory = __webpack_require__(5); - /** - * Creates a new Extern Game Object and adds it to the Scene. + * The Scene Transition Out Event. * - * Note: This method will only be available if the Extern Game Object has been built into Phaser. + * This event is dispatched by a Scene when it initiates a transition to another Scene. * - * @method Phaser.GameObjects.GameObjectFactory#extern - * @since 3.16.0 + * Listen to it from a Scene using `this.events.on('transitionout', listener)`. * - * @return {Phaser.GameObjects.Extern} The Game Object that was created. + * The Scene Transition event flow is as follows: + * + * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. + * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. + * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... + * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. + * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. + * + * @event Phaser.Scenes.Events#TRANSITION_OUT + * @type {string} + * @since 3.5.0 + * + * @param {Phaser.Scene} target - A reference to the Scene that is being transitioned to. + * @param {number} duration - The duration of the transition in ms. */ -GameObjectFactory.register('extern', function () -{ - var extern = new Extern(this.scene); - - this.displayList.add(extern); - - return extern; -}); - -// When registering a factory function 'this' refers to the GameObjectFactory 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 +module.exports = 'transitionout'; /***/ }), -/* 1135 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 33899: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Graphics = __webpack_require__(216); -var GameObjectFactory = __webpack_require__(5); - /** - * Creates a new Graphics Game Object and adds it to the Scene. + * The Scene Transition Start Event. * - * Note: This method will only be available if the Graphics Game Object has been built into Phaser. + * This event is dispatched by the Target Scene of a transition, only if that Scene was not asleep. * - * @method Phaser.GameObjects.GameObjectFactory#graphics - * @since 3.0.0 + * It happens immediately after the `Scene.create` method is called. If the Scene does not have a `create` method, + * this event is dispatched anyway. * - * @param {Phaser.Types.GameObjects.Graphics.Options} [config] - The Graphics configuration. + * If the Target Scene was sleeping then the [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} event is + * dispatched instead of this event. * - * @return {Phaser.GameObjects.Graphics} The Game Object that was created. + * Listen to it from a Scene using `this.events.on('transitionstart', listener)`. + * + * The Scene Transition event flow is as follows: + * + * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. + * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. + * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... + * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. + * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. + * + * @event Phaser.Scenes.Events#TRANSITION_START + * @type {string} + * @since 3.5.0 + * + * @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from. + * @param {number} duration - The duration of the transition in ms. */ -GameObjectFactory.register('graphics', function (config) -{ - return this.displayList.add(new Graphics(this.scene, config)); -}); - -// When registering a factory function 'this' refers to the GameObjectFactory 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 +module.exports = 'transitionstart'; /***/ }), -/* 1136 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 52418: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Group = __webpack_require__(113); -var GameObjectFactory = __webpack_require__(5); - /** - * Creates a new Group Game Object and adds it to the Scene. + * The Scene Transition Wake Event. * - * Note: This method will only be available if the Group Game Object has been built into Phaser. + * This event is dispatched by the Target Scene of a transition, only if that Scene was asleep before + * the transition began. If the Scene was not asleep the [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} event is dispatched instead. * - * @method Phaser.GameObjects.GameObjectFactory#group - * @since 3.0.0 + * Listen to it from a Scene using `this.events.on('transitionwake', listener)`. * - * @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupConfig[])} [children] - Game Objects to add to this Group; or the `config` argument. - * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - A Group Configuration object. + * The Scene Transition event flow is as follows: * - * @return {Phaser.GameObjects.Group} The Game Object that was created. + * 1. [TRANSITION_OUT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_OUT} - the Scene that started the transition will emit this event. + * 2. [TRANSITION_INIT]{@linkcode Phaser.Scenes.Events#event:TRANSITION_INIT} - the Target Scene will emit this event if it has an `init` method. + * 3. [TRANSITION_START]{@linkcode Phaser.Scenes.Events#event:TRANSITION_START} - the Target Scene will emit this event after its `create` method is called, OR ... + * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. + * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. + * + * @event Phaser.Scenes.Events#TRANSITION_WAKE + * @type {string} + * @since 3.5.0 + * + * @param {Phaser.Scene} from - A reference to the Scene that is being transitioned from. + * @param {number} duration - The duration of the transition in ms. */ -GameObjectFactory.register('group', function (children, config) -{ - return this.updateList.add(new Group(this.scene, children, config)); -}); +module.exports = 'transitionwake'; /***/ }), -/* 1137 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 31735: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Image = __webpack_require__(125); -var GameObjectFactory = __webpack_require__(5); - /** - * Creates a new Image Game Object and adds it to the Scene. + * The Scene Systems Update Event. * - * Note: This method will only be available if the Image Game Object has been built into Phaser. + * This event is dispatched by a Scene during the main game loop step. * - * @method Phaser.GameObjects.GameObjectFactory#image - * @since 3.0.0 + * The event flow for a single step of a Scene is as follows: * - * @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. + * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} + * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} + * 3. The `Scene.update` method is called, if it exists and the Scene is in a Running state, otherwise this is skipped. + * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} + * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} + * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} * - * @return {Phaser.GameObjects.Image} The Game Object that was created. + * Listen to it from a Scene using `this.events.on('update', listener)`. + * + * A Scene will only run its step if it is active. + * + * @event Phaser.Scenes.Events#UPDATE + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + * @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. */ -GameObjectFactory.register('image', function (x, y, key, frame) -{ - return this.displayList.add(new Image(this.scene, x, y, key, frame)); -}); - -// When registering a factory function 'this' refers to the GameObjectFactory 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 +module.exports = 'update'; /***/ }), -/* 1138 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 8470: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Layer = __webpack_require__(219); -var GameObjectFactory = __webpack_require__(5); - /** - * Creates a new Layer Game Object and adds it to the Scene. + * The Scene Systems Wake Event. * - * Note: This method will only be available if the Layer Game Object has been built into Phaser. + * This event is dispatched by a Scene when it is woken from sleep, either directly via the `wake` method, + * or as an action from another Scene. * - * @method Phaser.GameObjects.GameObjectFactory#layer - * @since 3.50.0 + * Listen to it from a Scene using `this.events.on('wake', listener)`. * - * @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Layer. + * @event Phaser.Scenes.Events#WAKE + * @type {string} + * @since 3.0.0 * - * @return {Phaser.GameObjects.Layer} The Game Object that was created. + * @param {Phaser.Scenes.Systems} sys - A reference to the Scene Systems class of the Scene that emitted this event. + * @param {any} [data] - An optional data object that was passed to this Scene when it was woken up. */ -GameObjectFactory.register('layer', function (children) -{ - return this.displayList.add(new Layer(this.scene, children)); -}); +module.exports = 'wake'; /***/ }), -/* 1139 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 7599: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectFactory = __webpack_require__(5); -var ParticleEmitterManager = __webpack_require__(220); - /** - * Creates a new Particle Emitter Manager Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Particles Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#particles - * @since 3.0.0 - * - * @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|object)} [frame] - An optional frame from the Texture this Game Object is rendering with. - * @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig|Phaser.Types.GameObjects.Particles.ParticleEmitterConfig[]} [emitters] - Configuration settings for one or more emitters to create. - * - * @return {Phaser.GameObjects.Particles.ParticleEmitterManager} The Game Object that was created. + * @namespace Phaser.Scenes.Events */ -GameObjectFactory.register('particles', function (key, frame, emitters) -{ - return this.displayList.add(new ParticleEmitterManager(this.scene, key, frame, emitters)); -}); + +module.exports = { + + ADDED_TO_SCENE: __webpack_require__(31803), + BOOT: __webpack_require__(94817), + CREATE: __webpack_require__(28977), + DESTROY: __webpack_require__(91959), + PAUSE: __webpack_require__(363), + POST_UPDATE: __webpack_require__(15643), + PRE_RENDER: __webpack_require__(17058), + PRE_UPDATE: __webpack_require__(77125), + READY: __webpack_require__(76018), + REMOVED_FROM_SCENE: __webpack_require__(28620), + RENDER: __webpack_require__(41538), + RESUME: __webpack_require__(34268), + SHUTDOWN: __webpack_require__(2342), + SLEEP: __webpack_require__(96541), + START: __webpack_require__(74244), + TRANSITION_COMPLETE: __webpack_require__(17046), + TRANSITION_INIT: __webpack_require__(13637), + TRANSITION_OUT: __webpack_require__(14733), + TRANSITION_START: __webpack_require__(33899), + TRANSITION_WAKE: __webpack_require__(52418), + UPDATE: __webpack_require__(31735), + WAKE: __webpack_require__(8470) + +}; /***/ }), -/* 1140 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 20436: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectFactory = __webpack_require__(5); -var PathFollower = __webpack_require__(457); +var CONST = __webpack_require__(92980); +var Extend = __webpack_require__(98611); /** - * Creates a new PathFollower Game Object and adds it to the Scene. - * - * Note: This method will only be available if the PathFollower Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#follower - * @since 3.0.0 - * - * @param {Phaser.Curves.Path} path - The Path this PathFollower is connected to. - * @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.GameObjects.PathFollower} The Game Object that was created. + * @namespace Phaser.Scenes */ -GameObjectFactory.register('follower', function (path, x, y, key, frame) -{ - var sprite = new PathFollower(this.scene, path, x, y, key, frame); - this.displayList.add(sprite); - this.updateList.add(sprite); +var Scene = { - return sprite; -}); + Events: __webpack_require__(7599), + GetPhysicsPlugins: __webpack_require__(47736), + GetScenePlugins: __webpack_require__(91088), + SceneManager: __webpack_require__(13553), + ScenePlugin: __webpack_require__(64051), + Settings: __webpack_require__(36765), + Systems: __webpack_require__(63946) -// When registering a factory function 'this' refers to the GameObjectFactory 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 +}; + +// Merge in the consts +Scene = Extend(false, Scene, CONST); + +module.exports = Scene; /***/ }), -/* 1141 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 25798: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectFactory = __webpack_require__(5); -var RenderTexture = __webpack_require__(221); +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(76038); +var Extend = __webpack_require__(98611); +var NOOP = __webpack_require__(72283); /** - * Creates a new Render Texture Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Render Texture Game Object has been built into Phaser. - * - * A Render Texture is a special texture that allows any number of Game Objects to be drawn to it. You can take many complex objects and - * draw them all to this one texture, which can they be used as the texture for other Game Object's. It's a way to generate dynamic - * textures at run-time that are WebGL friendly and don't invoke expensive GPU uploads. + * @classdesc + * Class containing all the shared state and behavior of a sound object, independent of the implementation. * - * @method Phaser.GameObjects.GameObjectFactory#renderTexture - * @since 3.2.0 + * @class BaseSound + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Sound + * @constructor + * @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 {number} [width=32] - The width of the Render Texture. - * @param {number} [height=32] - The height of the Render Texture. - * @property {string} [key] - The texture key to make the RenderTexture from. - * @property {string} [frame] - the frame to make the RenderTexture from. - * - * @return {Phaser.GameObjects.RenderTexture} The Game Object that was created. + * @param {Phaser.Sound.BaseSoundManager} 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. */ -GameObjectFactory.register('renderTexture', function (x, y, width, height, key, frame) -{ - return this.displayList.add(new RenderTexture(this.scene, x, y, width, height, key, frame)); +var BaseSound = new Class({ + + Extends: EventEmitter, + + initialize: + + function BaseSound (manager, key, config) + { + EventEmitter.call(this); + + /** + * Local reference to the sound manager. + * + * @name Phaser.Sound.BaseSound#manager + * @type {Phaser.Sound.BaseSoundManager} + * @since 3.0.0 + */ + this.manager = manager; + + /** + * Asset key for the sound. + * + * @name Phaser.Sound.BaseSound#key + * @type {string} + * @readonly + * @since 3.0.0 + */ + this.key = key; + + /** + * Flag indicating if sound is currently playing. + * + * @name Phaser.Sound.BaseSound#isPlaying + * @type {boolean} + * @default false + * @readonly + * @since 3.0.0 + */ + this.isPlaying = false; + + /** + * Flag indicating if sound is currently paused. + * + * @name Phaser.Sound.BaseSound#isPaused + * @type {boolean} + * @default false + * @readonly + * @since 3.0.0 + */ + this.isPaused = false; + + /** + * A property that holds the value of sound's actual playback rate, + * after its rate and detune values has been combined with global + * rate and detune values. + * + * @name Phaser.Sound.BaseSound#totalRate + * @type {number} + * @default 1 + * @readonly + * @since 3.0.0 + */ + this.totalRate = 1; + + /** + * A value representing the duration, in seconds. + * It could be total sound duration or a marker duration. + * + * @name Phaser.Sound.BaseSound#duration + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.duration = this.duration || 0; + + /** + * The total duration of the sound in seconds. + * + * @name Phaser.Sound.BaseSound#totalDuration + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.totalDuration = this.totalDuration || 0; + + /** + * A config object used to store default sound settings' values. + * Default values will be set by properties' setters. + * + * @name Phaser.Sound.BaseSound#config + * @type {Phaser.Types.Sound.SoundConfig} + * @private + * @since 3.0.0 + */ + this.config = { + + mute: false, + volume: 1, + rate: 1, + detune: 0, + seek: 0, + loop: false, + delay: 0, + pan: 0 + + }; + + /** + * Reference to the currently used config. + * It could be default config or marker config. + * + * @name Phaser.Sound.BaseSound#currentConfig + * @type {Phaser.Types.Sound.SoundConfig} + * @private + * @since 3.0.0 + */ + this.currentConfig = this.config; + + this.config = Extend(this.config, config); + + /** + * Object containing markers definitions. + * + * @name Phaser.Sound.BaseSound#markers + * @type {Object.} + * @default {} + * @readonly + * @since 3.0.0 + */ + this.markers = {}; + + /** + * Currently playing marker. + * 'null' if whole sound is playing. + * + * @name Phaser.Sound.BaseSound#currentMarker + * @type {Phaser.Types.Sound.SoundMarker} + * @default null + * @readonly + * @since 3.0.0 + */ + this.currentMarker = null; + + /** + * Flag indicating if destroy method was called on this sound. + * + * @name Phaser.Sound.BaseSound#pendingRemove + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.pendingRemove = false; + }, + + /** + * Adds a marker into the current sound. A marker is represented by name, start time, duration, and optionally config object. + * This allows you to bundle multiple sounds together into a single audio file and use markers to jump between them for playback. + * + * @method Phaser.Sound.BaseSound#addMarker + * @since 3.0.0 + * + * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object. + * + * @return {boolean} Whether the marker was added successfully. + */ + addMarker: function (marker) + { + if (!marker || !marker.name || typeof marker.name !== 'string') + { + return false; + } + + if (this.markers[marker.name]) + { + // eslint-disable-next-line no-console + console.error('addMarker ' + marker.name + ' already exists in Sound'); + + return false; + } + + marker = Extend(true, { + name: '', + start: 0, + duration: this.totalDuration - (marker.start || 0), + config: { + mute: false, + volume: 1, + rate: 1, + detune: 0, + seek: 0, + loop: false, + delay: 0, + pan: 0 + } + }, marker); + + this.markers[marker.name] = marker; + + return true; + }, + + /** + * Updates previously added marker. + * + * @method Phaser.Sound.BaseSound#updateMarker + * @since 3.0.0 + * + * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object with updated values. + * + * @return {boolean} Whether the marker was updated successfully. + */ + updateMarker: function (marker) + { + if (!marker || !marker.name || typeof marker.name !== 'string') + { + return false; + } + + if (!this.markers[marker.name]) + { + // eslint-disable-next-line no-console + console.warn('Audio Marker: ' + marker.name + ' missing in Sound: ' + this.key); + + return false; + } + + this.markers[marker.name] = Extend(true, this.markers[marker.name], marker); + + return true; + }, + + /** + * Removes a marker from the sound. + * + * @method Phaser.Sound.BaseSound#removeMarker + * @since 3.0.0 + * + * @param {string} markerName - The name of the marker to remove. + * + * @return {?Phaser.Types.Sound.SoundMarker} Removed marker object or 'null' if there was no marker with provided name. + */ + removeMarker: function (markerName) + { + var marker = this.markers[markerName]; + + if (!marker) + { + return null; + } + + this.markers[markerName] = null; + + return marker; + }, + + /** + * 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.BaseSound#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 (markerName === undefined) { markerName = ''; } + + if (typeof markerName === 'object') + { + config = markerName; + markerName = ''; + } + + if (typeof markerName !== 'string') + { + return false; + } + + if (!markerName) + { + this.currentMarker = null; + this.currentConfig = this.config; + this.duration = this.totalDuration; + } + else + { + if (!this.markers[markerName]) + { + // eslint-disable-next-line no-console + console.warn('Marker: ' + markerName + ' missing in Sound: ' + this.key); + + return false; + } + + this.currentMarker = this.markers[markerName]; + this.currentConfig = this.currentMarker.config; + this.duration = this.currentMarker.duration; + } + + this.resetConfig(); + + this.currentConfig = Extend(this.currentConfig, config); + + this.isPlaying = true; + this.isPaused = false; + + return true; + }, + + /** + * Pauses the sound. This only works if the sound is currently playing. + * + * You can inspect the `isPlaying` and `isPaused` properties to check the state. + * + * @method Phaser.Sound.BaseSound#pause + * @since 3.0.0 + * + * @return {boolean} Whether the sound was paused successfully. + */ + pause: function () + { + if (this.isPaused || !this.isPlaying) + { + return false; + } + + this.isPlaying = false; + this.isPaused = true; + + return true; + }, + + /** + * Resumes the sound. This only works if the sound is paused and not already playing. + * + * You can inspect the `isPlaying` and `isPaused` properties to check the state. + * + * @method Phaser.Sound.BaseSound#resume + * @since 3.0.0 + * + * @return {boolean} Whether the sound was resumed successfully. + */ + resume: function () + { + if (!this.isPaused || this.isPlaying) + { + return false; + } + + this.isPlaying = true; + this.isPaused = false; + + return true; + }, + + /** + * Stop playing this sound. + * + * @method Phaser.Sound.BaseSound#stop + * @since 3.0.0 + * + * @return {boolean} Whether the sound was stopped successfully. + */ + stop: function () + { + if (!this.isPaused && !this.isPlaying) + { + return false; + } + + this.isPlaying = false; + this.isPaused = false; + + this.resetConfig(); + + return true; + }, + + /** + * Method used internally for applying config values to some of the sound properties. + * + * @method Phaser.Sound.BaseSound#applyConfig + * @since 3.0.0 + */ + applyConfig: function () + { + this.mute = this.currentConfig.mute; + this.volume = this.currentConfig.volume; + this.rate = this.currentConfig.rate; + this.detune = this.currentConfig.detune; + this.loop = this.currentConfig.loop; + this.pan = this.currentConfig.pan; + }, + + /** + * Method used internally for resetting values of some of the config properties. + * + * @method Phaser.Sound.BaseSound#resetConfig + * @since 3.0.0 + */ + resetConfig: function () + { + this.currentConfig.seek = 0; + this.currentConfig.delay = 0; + }, + + /** + * Update method called automatically by sound manager on every game step. + * + * @method Phaser.Sound.BaseSound#update + * @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 elapsed since the last frame. + */ + update: NOOP, + + /** + * Method used internally to calculate total playback rate of the sound. + * + * @method Phaser.Sound.BaseSound#calculateRate + * @since 3.0.0 + */ + calculateRate: function () + { + var cent = 1.0005777895065548; // Math.pow(2, 1/1200); + var totalDetune = this.currentConfig.detune + this.manager.detune; + var detuneRate = Math.pow(cent, totalDetune); + + this.totalRate = this.currentConfig.rate * this.manager.rate * detuneRate; + }, + + /** + * Destroys this sound and all associated events and marks it for removal from the sound manager. + * + * @method Phaser.Sound.BaseSound#destroy + * @fires Phaser.Sound.Events#DESTROY + * @since 3.0.0 + */ + destroy: function () + { + if (this.pendingRemove) + { + return; + } + + this.emit(Events.DESTROY, this); + + this.removeAllListeners(); + + this.pendingRemove = true; + + this.manager = null; + this.config = null; + this.currentConfig = null; + this.markers = null; + this.currentMarker = null; + } + }); +module.exports = BaseSound; + /***/ }), -/* 1142 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 12486: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Rope = __webpack_require__(223); -var GameObjectFactory = __webpack_require__(5); +var Class = __webpack_require__(56694); +var Clone = __webpack_require__(32742); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(76038); +var GameEvents = __webpack_require__(97081); +var GetAll = __webpack_require__(71608); +var GetFirst = __webpack_require__(51463); +var NOOP = __webpack_require__(72283); +var Vector2 = __webpack_require__(93736); /** - * Creates a new Rope Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Rope Game Object and WebGL support have been built into Phaser. + * @classdesc + * Base class for other Sound Manager classes. * - * @method Phaser.GameObjects.GameObjectFactory#rope - * @webglOnly - * @since 3.23.0 + * @class BaseSoundManager + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Sound + * @constructor + * @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. - * @param {Phaser.Types.Math.Vector2Like[]} [points] - An array containing the vertices data for this Rope. If none is provided a simple quad is created. See `setPoints` to set this post-creation. - * @param {boolean} [horizontal=true] - Should the vertices of this Rope be aligned horizontally (`true`), or vertically (`false`)? - * @param {number[]} [colors] - An optional array containing the color data for this Rope. You should provide one color value per pair of vertices. - * @param {number[]} [alphas] - An optional array containing the alpha data for this Rope. You should provide one alpha value per pair of vertices. + * @param {Phaser.Game} game - Reference to the current game instance. * - * @return {Phaser.GameObjects.Rope} The Game Object that was created. + * @see Phaser.Sound.HTML5AudioSoundManager + * @see Phaser.Sound.NoAudioSoundManager + * @see Phaser.Sound.WebAudioSoundManager */ -if (true) -{ - GameObjectFactory.register('rope', function (x, y, texture, frame, points, horizontal, colors, alphas) +var BaseSoundManager = new Class({ + + Extends: EventEmitter, + + initialize: + + function BaseSoundManager (game) { - return this.displayList.add(new Rope(this.scene, x, y, texture, frame, points, horizontal, colors, alphas)); - }); -} + EventEmitter.call(this); + + /** + * Local reference to game. + * + * @name Phaser.Sound.BaseSoundManager#game + * @type {Phaser.Game} + * @readonly + * @since 3.0.0 + */ + this.game = game; + + /** + * Local reference to the JSON Cache, as used by Audio Sprites. + * + * @name Phaser.Sound.BaseSoundManager#jsonCache + * @type {Phaser.Cache.BaseCache} + * @readonly + * @since 3.7.0 + */ + this.jsonCache = game.cache.json; + + /** + * An array containing all added sounds. + * + * @name Phaser.Sound.BaseSoundManager#sounds + * @type {Phaser.Sound.BaseSound[]} + * @default [] + * @private + * @since 3.0.0 + */ + this.sounds = []; + + /** + * Global mute setting. + * + * @name Phaser.Sound.BaseSoundManager#mute + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.mute = false; + + /** + * Global volume setting. + * + * @name Phaser.Sound.BaseSoundManager#volume + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.volume = 1; + + /** + * Flag indicating if sounds should be paused when game looses focus, + * for instance when user switches to another tab/program/app. + * + * @name Phaser.Sound.BaseSoundManager#pauseOnBlur + * @type {boolean} + * @default true + * @since 3.0.0 + */ + this.pauseOnBlur = true; + + /** + * Property that actually holds the value of global playback rate. + * + * @name Phaser.Sound.BaseSoundManager#_rate + * @type {number} + * @private + * @default 1 + * @since 3.0.0 + */ + this._rate = 1; + + /** + * Property that actually holds the value of global detune. + * + * @name Phaser.Sound.BaseSoundManager#_detune + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._detune = 0; + + /** + * Mobile devices require sounds to be triggered from an explicit user action, + * such as a tap, before any sound can be loaded/played on a web page. + * Set to true if the audio system is currently locked awaiting user interaction. + * + * @name Phaser.Sound.BaseSoundManager#locked + * @type {boolean} + * @readonly + * @since 3.0.0 + */ + this.locked = this.locked || false; + + /** + * Flag used internally for handling when the audio system + * has been unlocked, if there ever was a need for it. + * + * @name Phaser.Sound.BaseSoundManager#unlocked + * @type {boolean} + * @default false + * @private + * @since 3.0.0 + */ + this.unlocked = false; + + /** + * Flag used to track if the game has lost focus. + * + * @name Phaser.Sound.BaseSoundManager#gameLostFocus + * @type {boolean} + * @default false + * @since 3.60.0 + */ + this.gameLostFocus = false; + + /** + * The Spatial Audio listener position. + * + * Only available with WebAudio. + * + * You can modify the x/y properties of this Vec2 directly to + * adjust the listener position within the game world. + * + * @name Phaser.Sound.BaseSoundManager#listenerPosition + * @type {Phaser.Math.Vector2} + * @since 3.60.0 + */ + this.listenerPosition = new Vector2(); + game.events.on(GameEvents.BLUR, this.onGameBlur, this); + game.events.on(GameEvents.FOCUS, this.onGameFocus, this); + game.events.on(GameEvents.PRE_STEP, this.update, this); + game.events.once(GameEvents.DESTROY, this.destroy, this); + }, -/***/ }), -/* 1143 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Adds a new sound into the sound manager. + * + * @method Phaser.Sound.BaseSoundManager#add + * @override + * @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.BaseSound} The new sound instance. + */ + add: NOOP, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Adds a new audio sprite sound into the sound manager. + * Audio Sprites are a combination of audio files and a JSON configuration. + * The JSON follows the format of that created by https://github.com/tonistiigi/audiosprite + * + * @method Phaser.Sound.BaseSoundManager#addAudioSprite + * @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.NoAudioSound|Phaser.Sound.HTML5AudioSound|Phaser.Sound.WebAudioSound)} The new audio sprite sound instance. + */ + addAudioSprite: function (key, config) + { + if (config === undefined) { config = {}; } -var GameObjectFactory = __webpack_require__(5); -var Sprite = __webpack_require__(73); + var sound = this.add(key, config); -/** - * Creates a new Sprite Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Sprite Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#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|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.GameObjects.Sprite} The Game Object that was created. - */ -GameObjectFactory.register('sprite', function (x, y, key, frame) -{ - var sprite = new Sprite(this.scene, x, y, key, frame); + sound.spritemap = this.jsonCache.get(key).spritemap; - this.displayList.add(sprite); + for (var markerName in sound.spritemap) + { + if (!sound.spritemap.hasOwnProperty(markerName)) + { + continue; + } - return sprite; -}); + var markerConfig = Clone(config); -// When registering a factory function 'this' refers to the GameObjectFactory 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 + var marker = sound.spritemap[markerName]; + markerConfig.loop = (marker.hasOwnProperty('loop')) ? marker.loop : false; -/***/ }), -/* 1144 */ -/***/ (function(module, exports, __webpack_require__) { + sound.addMarker({ + name: markerName, + start: marker.start, + duration: marker.end - marker.start, + config: markerConfig + }); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return sound; + }, -var BitmapText = __webpack_require__(148); -var GameObjectFactory = __webpack_require__(5); + /** + * Gets the first sound in this Sound Manager that matches the given key. + * If none can be found it returns `null`. + * + * @method Phaser.Sound.BaseSoundManager#get + * @since 3.23.0 + * + * @generic {Phaser.Sound.BaseSound} T + * @genericUse {T} - [$return] + * + * @param {string} key - Sound asset key. + * + * @return {?Phaser.Sound.BaseSound} - The sound, or null. + */ + get: function (key) + { + return GetFirst(this.sounds, 'key', key); + }, -/** - * Creates a new Bitmap Text Game Object and adds it to the Scene. - * - * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. - * - * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to - * match the font structure. - * - * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability - * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by - * processing the font texture in an image editor, applying fills and any other effects required. - * - * To create multi-line text insert \r, \n or \r\n escape codes into the text string. - * - * To create a BitmapText data files you need a 3rd party app such as: - * - * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/ - * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner - * Littera (Web-based, free): http://kvazars.com/littera/ - * - * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of - * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: http://codebeautify.org/xmltojson - * - * Note: This method will only be available if the Bitmap Text Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#bitmapText - * @since 3.0.0 - * - * @param {number} x - The x position of the Game Object. - * @param {number} y - The y position of the Game Object. - * @param {string} font - The key of the font to use from the BitmapFont cache. - * @param {(string|string[])} [text] - The string, or array of strings, to be set as the content of this Bitmap Text. - * @param {number} [size] - The font size to set. - * @param {number} [align=0] - The alignment of the text in a multi-line BitmapText object. - * - * @return {Phaser.GameObjects.BitmapText} The Game Object that was created. - */ -GameObjectFactory.register('bitmapText', function (x, y, font, text, size, align) -{ - return this.displayList.add(new BitmapText(this.scene, x, y, font, text, size, align)); -}); + /** + * Gets all sounds in this Sound Manager. + * + * You can optionally specify a key, in which case only Sound instances that match the given key + * will be returned. + * + * @method Phaser.Sound.BaseSoundManager#getAll + * @since 3.23.0 + * + * @generic {Phaser.Sound.BaseSound} T + * @genericUse {T[]} - [$return] + * + * @param {string} [key] - Optional asset key. If given, only Sound instances with this key will be returned. + * + * @return {Phaser.Sound.BaseSound[]} - The sounds, or an empty array. + */ + getAll: function (key) + { + if (key) + { + return GetAll(this.sounds, 'key', key); + } + else + { + return GetAll(this.sounds); + } + }, -// When registering a factory function 'this' refers to the GameObjectFactory 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 + /** + * Returns all sounds from this Sound Manager that are currently + * playing. That is, Sound instances that have their `isPlaying` + * property set to `true`. + * + * @method Phaser.Sound.BaseSoundManager#getAllPlaying + * @since 3.60.0 + * + * @generic {Phaser.Sound.BaseSound} T + * @genericUse {T[]} - [$return] + * + * @return {Phaser.Sound.BaseSound[]} - All currently playing sounds, or an empty array. + */ + getAllPlaying: function () + { + return GetAll(this.sounds, 'isPlaying', true); + }, + /** + * Adds a new sound to the sound manager and plays it. + * + * The sound will be automatically removed (destroyed) once playback ends. + * + * This lets you play a new sound on the fly without the need to keep a reference to it. + * + * @method Phaser.Sound.BaseSoundManager#play + * @listens Phaser.Sound.Events#COMPLETE + * @since 3.0.0 + * + * @param {string} key - Asset key for the sound. + * @param {(Phaser.Types.Sound.SoundConfig|Phaser.Types.Sound.SoundMarker)} [extra] - An optional additional object containing settings to be applied to the sound. It could be either config or marker object. + * + * @return {boolean} Whether the sound started playing successfully. + */ + play: function (key, extra) + { + var sound = this.add(key); -/***/ }), -/* 1145 */ -/***/ (function(module, exports, __webpack_require__) { + sound.once(Events.COMPLETE, sound.destroy, sound); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (extra) + { + if (extra.name) + { + sound.addMarker(extra); -var Text = __webpack_require__(224); -var GameObjectFactory = __webpack_require__(5); + return sound.play(extra.name); + } + else + { + return sound.play(extra); + } + } + else + { + return sound.play(); + } + }, -/** - * Creates a new Text Game Object and adds it to the Scene. - * - * A Text Game Object. - * - * Text objects work by creating their own internal hidden Canvas and then renders text to it using - * the standard Canvas `fillText` API. It then creates a texture from this canvas which is rendered - * to your game during the render pass. - * - * Because it uses the Canvas API you can take advantage of all the features this offers, such as - * applying gradient fills to the text, or strokes, shadows and more. You can also use custom fonts - * loaded externally, such as Google or TypeKit Web fonts. - * - * You can only display fonts that are currently loaded and available to the browser: therefore fonts must - * be pre-loaded. Phaser does not do ths for you, so you will require the use of a 3rd party font loader, - * or have the fonts ready available in the CSS on the page in which your Phaser game resides. - * - * See {@link http://www.jordanm.co.uk/tinytype this compatibility table} for the available default fonts - * across mobile browsers. - * - * A note on performance: Every time the contents of a Text object changes, i.e. changing the text being - * displayed, or the style of the text, it needs to remake the Text canvas, and if on WebGL, re-upload the - * new texture to the GPU. This can be an expensive operation if used often, or with large quantities of - * Text objects in your game. If you run into performance issues you would be better off using Bitmap Text - * instead, as it benefits from batching and avoids expensive Canvas API calls. - * - * Note: This method will only be available if the Text Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#text - * @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|string[])} text - The text this Text object will display. - * @param {Phaser.Types.GameObjects.Text.TextStyle} [style] - The Text style configuration object. - * - * @return {Phaser.GameObjects.Text} The Game Object that was created. - */ -GameObjectFactory.register('text', function (x, y, text, style) -{ - return this.displayList.add(new Text(this.scene, x, y, text, style)); -}); + /** + * Adds a new audio sprite sound to the sound manager and plays it. + * The sprite will be automatically removed (destroyed) once playback ends. + * This lets you play a new sound on the fly without the need to keep a reference to it. + * + * @method Phaser.Sound.BaseSoundManager#playAudioSprite + * @listens Phaser.Sound.Events#COMPLETE + * @since 3.0.0 + * + * @param {string} key - Asset key for the sound. + * @param {string} spriteName - The name of the sound sprite to play. + * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. + * + * @return {boolean} Whether the audio sprite sound started playing successfully. + */ + playAudioSprite: function (key, spriteName, config) + { + var sound = this.addAudioSprite(key); -// When registering a factory function 'this' refers to the GameObjectFactory 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 + sound.once(Events.COMPLETE, sound.destroy, sound); + return sound.play(spriteName, config); + }, -/***/ }), -/* 1146 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Removes a sound from the sound manager. + * The removed sound is destroyed before removal. + * + * @method Phaser.Sound.BaseSoundManager#remove + * @since 3.0.0 + * + * @param {Phaser.Sound.BaseSound} sound - The sound object to remove. + * + * @return {boolean} True if the sound was removed successfully, otherwise false. + */ + remove: function (sound) + { + var index = this.sounds.indexOf(sound); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (index !== -1) + { + sound.destroy(); -var TileSprite = __webpack_require__(225); -var GameObjectFactory = __webpack_require__(5); + this.sounds.splice(index, 1); -/** - * Creates a new TileSprite Game Object and adds it to the Scene. - * - * Note: This method will only be available if the TileSprite Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#tileSprite - * @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 {number} width - The width of the Game Object. If zero it will use the size of the texture frame. - * @param {number} height - The height of the Game Object. If zero it will use the size of the texture frame. - * @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.GameObjects.TileSprite} The Game Object that was created. - */ -GameObjectFactory.register('tileSprite', function (x, y, width, height, key, frame) -{ - return this.displayList.add(new TileSprite(this.scene, x, y, width, height, key, frame)); -}); + return true; + } -// When registering a factory function 'this' refers to the GameObjectFactory 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 + return false; + }, + /** + * Removes all sounds from the manager, destroying the sounds. + * + * @method Phaser.Sound.BaseSoundManager#removeAll + * @since 3.23.0 + */ + removeAll: function () + { + this.sounds.forEach(function (sound) + { + sound.destroy(); + }); -/***/ }), -/* 1147 */ -/***/ (function(module, exports, __webpack_require__) { + this.sounds.length = 0; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Removes all sounds from the sound manager that have an asset key matching the given value. + * The removed sounds are destroyed before removal. + * + * @method Phaser.Sound.BaseSoundManager#removeByKey + * @since 3.0.0 + * + * @param {string} key - The key to match when removing sound objects. + * + * @return {number} The number of matching sound objects that were removed. + */ + removeByKey: function (key) + { + var removed = 0; -var Zone = __webpack_require__(129); -var GameObjectFactory = __webpack_require__(5); + for (var i = this.sounds.length - 1; i >= 0; i--) + { + var sound = this.sounds[i]; -/** - * Creates a new Zone Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Zone Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#zone - * @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 {number} width - The width of the Game Object. - * @param {number} height - The height of the Game Object. - * - * @return {Phaser.GameObjects.Zone} The Game Object that was created. - */ -GameObjectFactory.register('zone', function (x, y, width, height) -{ - return this.displayList.add(new Zone(this.scene, x, y, width, height)); -}); + if (sound.key === key) + { + sound.destroy(); -// When registering a factory function 'this' refers to the GameObjectFactory 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 + this.sounds.splice(i, 1); + removed++; + } + } -/***/ }), -/* 1148 */ -/***/ (function(module, exports, __webpack_require__) { + return removed; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Pauses all the sounds in the game. + * + * @method Phaser.Sound.BaseSoundManager#pauseAll + * @fires Phaser.Sound.Events#PAUSE_ALL + * @since 3.0.0 + */ + pauseAll: function () + { + this.forEachActiveSound(function (sound) + { + sound.pause(); + }); -var Video = __webpack_require__(226); -var GameObjectFactory = __webpack_require__(5); + this.emit(Events.PAUSE_ALL, this); + }, -/** - * Creates a new Video Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Video Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#video - * @since 3.20.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] - Optional key of the Video this Game Object will play, as stored in the Video Cache. - * - * @return {Phaser.GameObjects.Video} The Game Object that was created. - */ -GameObjectFactory.register('video', function (x, y, key) -{ - return this.displayList.add(new Video(this.scene, x, y, key)); -}); + /** + * Resumes all the sounds in the game. + * + * @method Phaser.Sound.BaseSoundManager#resumeAll + * @fires Phaser.Sound.Events#RESUME_ALL + * @since 3.0.0 + */ + resumeAll: function () + { + this.forEachActiveSound(function (sound) + { + sound.resume(); + }); + this.emit(Events.RESUME_ALL, this); + }, -/***/ }), -/* 1149 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Sets the X and Y position of the Spatial Audio listener on this Web Audios context. + * + * If you call this method with no parameters it will default to the center-point of + * the game canvas. Depending on the type of game you're making, you may need to call + * this method constantly to reset the listener position as the camera scrolls. + * + * Calling this method does nothing on HTML5Audio. + * + * @method Phaser.Sound.BaseSoundManager#setListenerPosition + * @since 3.60.0 + * + * @param {number} [x] - The x position of the Spatial Audio listener. + * @param {number} [y] - The y position of the Spatial Audio listener. + */ + setListenerPosition: NOOP, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Stops all the sounds in the game. + * + * @method Phaser.Sound.BaseSoundManager#stopAll + * @fires Phaser.Sound.Events#STOP_ALL + * @since 3.0.0 + */ + stopAll: function () + { + this.forEachActiveSound(function (sound) + { + sound.stop(); + }); -var Arc = __webpack_require__(461); -var GameObjectFactory = __webpack_require__(5); + this.emit(Events.STOP_ALL, this); + }, -/** - * Creates a new Arc Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Arc Game Object has been built into Phaser. - * - * 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. - * - * @method Phaser.GameObjects.GameObjectFactory#arc - * @since 3.13.0 - * - * @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. - * - * @return {Phaser.GameObjects.Arc} The Game Object that was created. - */ -GameObjectFactory.register('arc', function (x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha) -{ - return this.displayList.add(new Arc(this.scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha)); -}); + /** + * Stops any sounds matching the given key. + * + * @method Phaser.Sound.BaseSoundManager#stopByKey + * @since 3.23.0 + * + * @param {string} key - Sound asset key. + * + * @return {number} - How many sounds were stopped. + */ + stopByKey: function (key) + { + var stopped = 0; -/** - * Creates a new Circle Shape Game Object and adds it to the Scene. - * - * A Circle is an Arc with no defined start and end angle, making it render as a complete circle. - * - * Note: This method will only be available if the Arc Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#circle - * @since 3.13.0 - * - * @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 circle. - * @param {number} [fillColor] - The color the circle will be filled with, i.e. 0xff0000 for red. - * @param {number} [fillAlpha] - The alpha the circle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. - * - * @return {Phaser.GameObjects.Arc} The Game Object that was created. - */ -GameObjectFactory.register('circle', function (x, y, radius, fillColor, fillAlpha) -{ - return this.displayList.add(new Arc(this.scene, x, y, radius, 0, 360, false, fillColor, fillAlpha)); -}); + this.getAll(key).forEach(function (sound) + { + if (sound.stop()) { stopped++; } + }); + return stopped; + }, -/***/ }), -/* 1150 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Method used internally for unlocking audio playback on devices that + * require user interaction before any sound can be played on a web page. + * + * 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.BaseSoundManager#unlock + * @override + * @protected + * @since 3.0.0 + */ + unlock: NOOP, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Method used internally for pausing sound manager if + * Phaser.Sound.BaseSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.BaseSoundManager#onBlur + * @override + * @protected + * @since 3.0.0 + */ + onBlur: NOOP, -var GameObjectFactory = __webpack_require__(5); -var Curve = __webpack_require__(462); + /** + * Method used internally for resuming sound manager if + * Phaser.Sound.BaseSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.BaseSoundManager#onFocus + * @override + * @protected + * @since 3.0.0 + */ + onFocus: NOOP, -/** - * Creates a new Curve Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Curve Game Object has been built into Phaser. - * - * 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. - * - * @method Phaser.GameObjects.GameObjectFactory#curve - * @since 3.13.0 - * - * @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. - * - * @return {Phaser.GameObjects.Curve} The Game Object that was created. - */ -GameObjectFactory.register('curve', function (x, y, curve, fillColor, fillAlpha) -{ - return this.displayList.add(new Curve(this.scene, x, y, curve, fillColor, fillAlpha)); -}); + /** + * Internal handler for Phaser.Core.Events#BLUR. + * + * @method Phaser.Sound.BaseSoundManager#onGameBlur + * @private + * @since 3.23.0 + */ + onGameBlur: function () + { + this.gameLostFocus = true; + if (this.pauseOnBlur) + { + this.onBlur(); + } + }, -/***/ }), -/* 1151 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Internal handler for Phaser.Core.Events#FOCUS. + * + * @method Phaser.Sound.BaseSoundManager#onGameFocus + * @private + * @since 3.23.0 + */ + onGameFocus: function () + { + this.gameLostFocus = false; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.pauseOnBlur) + { + this.onFocus(); + } + }, -var Ellipse = __webpack_require__(463); -var GameObjectFactory = __webpack_require__(5); + /** + * Update method called on every game step. + * Removes destroyed sounds and updates every active sound in the game. + * + * @method Phaser.Sound.BaseSoundManager#update + * @protected + * @fires Phaser.Sound.Events#UNLOCKED + * @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 elapsed since the last frame. + */ + update: function (time, delta) + { + if (this.unlocked) + { + this.unlocked = false; + this.locked = false; -/** - * Creates a new Ellipse Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Ellipse Game Object has been built into Phaser. - * - * 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. - * - * @method Phaser.GameObjects.GameObjectFactory#ellipse - * @since 3.13.0 - * - * @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. - * - * @return {Phaser.GameObjects.Ellipse} The Game Object that was created. - */ -GameObjectFactory.register('ellipse', function (x, y, width, height, fillColor, fillAlpha) -{ - return this.displayList.add(new Ellipse(this.scene, x, y, width, height, fillColor, fillAlpha)); -}); + this.emit(Events.UNLOCKED, this); + } + for (var i = this.sounds.length - 1; i >= 0; i--) + { + if (this.sounds[i].pendingRemove) + { + this.sounds.splice(i, 1); + } + } -/***/ }), -/* 1152 */ -/***/ (function(module, exports, __webpack_require__) { + this.sounds.forEach(function (sound) + { + sound.update(time, delta); + }); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Destroys all the sounds in the game and all associated events. + * + * @method Phaser.Sound.BaseSoundManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.game.events.off(GameEvents.BLUR, this.onGameBlur, this); + this.game.events.off(GameEvents.FOCUS, this.onGameFocus, this); + this.game.events.off(GameEvents.PRE_STEP, this.update, this); -var GameObjectFactory = __webpack_require__(5); -var Grid = __webpack_require__(464); + this.removeAllListeners(); -/** - * Creates a new Grid Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Grid Game Object has been built into Phaser. - * - * 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. - * - * @method Phaser.GameObjects.GameObjectFactory#grid - * @since 3.13.0 - * - * @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. - * @param {number} [outlineFillAlpha] - The alpha of the lines between the grid cells. - * - * @return {Phaser.GameObjects.Grid} The Game Object that was created. - */ -GameObjectFactory.register('grid', function (x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha) -{ - return this.displayList.add(new Grid(this.scene, x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha)); -}); + this.removeAll(); + this.sounds.length = 0; + this.sounds = null; + this.listenerPosition = null; + this.game = null; + }, -/***/ }), -/* 1153 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Method used internally for iterating only over active sounds and skipping sounds that are marked for removal. + * + * @method Phaser.Sound.BaseSoundManager#forEachActiveSound + * @private + * @since 3.0.0 + * + * @param {Phaser.Types.Sound.EachActiveSoundCallback} callback - Callback function. (manager: Phaser.Sound.BaseSoundManager, sound: Phaser.Sound.BaseSound, index: number, sounds: Phaser.Manager.BaseSound[]) => void + * @param {*} [scope] - Callback context. + */ + forEachActiveSound: function (callback, scope) + { + var _this = this; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.sounds.forEach(function (sound, index) + { + if (sound && !sound.pendingRemove) + { + callback.call(scope || _this, sound, index, _this.sounds); + } + }); + }, -var GameObjectFactory = __webpack_require__(5); -var IsoBox = __webpack_require__(465); + /** + * Sets the global playback rate at which all the sounds will be played. + * + * 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.BaseSoundManager#setRate + * @fires Phaser.Sound.Events#GLOBAL_RATE + * @since 3.3.0 + * + * @param {number} value - Global playback rate at which all the sounds will be played. + * + * @return {this} This Sound Manager. + */ + setRate: function (value) + { + this.rate = value; -/** - * Creates a new IsoBox Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the IsoBox Game Object has been built into Phaser. - * - * 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. - * - * @method Phaser.GameObjects.GameObjectFactory#isobox - * @since 3.13.0 - * - * @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. - * - * @return {Phaser.GameObjects.IsoBox} The Game Object that was created. - */ -GameObjectFactory.register('isobox', function (x, y, size, height, fillTop, fillLeft, fillRight) -{ - return this.displayList.add(new IsoBox(this.scene, x, y, size, height, fillTop, fillLeft, fillRight)); -}); + return this; + }, + /** + * Global playback rate at which all the sounds 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 audio's playback speed. + * + * @name Phaser.Sound.BaseSoundManager#rate + * @type {number} + * @default 1 + * @since 3.0.0 + */ + rate: { -/***/ }), -/* 1154 */ -/***/ (function(module, exports, __webpack_require__) { + get: function () + { + return this._rate; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + set: function (value) + { + this._rate = value; -var GameObjectFactory = __webpack_require__(5); -var IsoTriangle = __webpack_require__(466); + this.forEachActiveSound(function (sound) + { + sound.calculateRate(); + }); -/** - * Creates a new IsoTriangle Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the IsoTriangle Game Object has been built into Phaser. - * - * 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. - * - * @method Phaser.GameObjects.GameObjectFactory#isotriangle - * @since 3.13.0 - * - * @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. - * - * @return {Phaser.GameObjects.IsoTriangle} The Game Object that was created. - */ -GameObjectFactory.register('isotriangle', function (x, y, size, height, reversed, fillTop, fillLeft, fillRight) -{ - return this.displayList.add(new IsoTriangle(this.scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight)); -}); + this.emit(Events.GLOBAL_RATE, this, value); + } + }, -/***/ }), -/* 1155 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Sets the global detuning of all sounds 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.BaseSoundManager#setDetune + * @fires Phaser.Sound.Events#GLOBAL_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 Manager. + */ + setDetune: function (value) + { + this.detune = value; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var GameObjectFactory = __webpack_require__(5); -var Line = __webpack_require__(467); + /** + * Global detuning of all sounds 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.BaseSoundManager#detune + * @type {number} + * @default 0 + * @since 3.0.0 + */ + detune: { + + get: function () + { + return this._detune; + }, + + set: function (value) + { + this._detune = value; + + this.forEachActiveSound(function (sound) + { + sound.calculateRate(); + }); + + this.emit(Events.GLOBAL_DETUNE, this, value); + } + + } -/** - * Creates a new Line Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Line Game Object has been built into Phaser. - * - * 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. - * - * @method Phaser.GameObjects.GameObjectFactory#line - * @since 3.13.0 - * - * @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. - * - * @return {Phaser.GameObjects.Line} The Game Object that was created. - */ -GameObjectFactory.register('line', function (x, y, x1, y1, x2, y2, strokeColor, strokeAlpha) -{ - return this.displayList.add(new Line(this.scene, x, y, x1, y1, x2, y2, strokeColor, strokeAlpha)); }); +module.exports = BaseSoundManager; + /***/ }), -/* 1156 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 84191: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectFactory = __webpack_require__(5); -var Polygon = __webpack_require__(468); +var HTML5AudioSoundManager = __webpack_require__(27622); +var NoAudioSoundManager = __webpack_require__(17546); +var WebAudioSoundManager = __webpack_require__(55491); /** - * Creates a new Polygon Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Polygon Game Object has been built into Phaser. - * - * 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: + * Creates a Web Audio, HTML5 Audio or No Audio Sound Manager based on config and device settings. * - * - 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. + * Be aware of https://developers.google.com/web/updates/2017/09/autoplay-policy-changes * - * @method Phaser.GameObjects.GameObjectFactory#polygon - * @since 3.13.0 + * @function Phaser.Sound.SoundManagerCreator + * @since 3.0.0 * - * @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. + * @param {Phaser.Game} game - Reference to the current game instance. * - * @return {Phaser.GameObjects.Polygon} The Game Object that was created. + * @return {(Phaser.Sound.HTML5AudioSoundManager|Phaser.Sound.WebAudioSoundManager|Phaser.Sound.NoAudioSoundManager)} The Sound Manager instance that was created. */ -GameObjectFactory.register('polygon', function (x, y, points, fillColor, fillAlpha) -{ - return this.displayList.add(new Polygon(this.scene, x, y, points, fillColor, fillAlpha)); -}); +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; /***/ }), -/* 1157 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 77578: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectFactory = __webpack_require__(5); -var Rectangle = __webpack_require__(473); - /** - * Creates a new Rectangle Shape Game Object and adds it to the Scene. + * The Sound Complete Event. * - * Note: This method will only be available if the Rectangle Game Object has been built into Phaser. - * - * 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. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they complete playback. * - * @method Phaser.GameObjects.GameObjectFactory#rectangle - * @since 3.13.0 + * Listen to it from a Sound instance using `Sound.on('complete', listener)`, i.e.: * - * @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 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. + * ```javascript + * var music = this.sound.add('key'); + * music.on('complete', listener); + * music.play(); + * ``` * - * @return {Phaser.GameObjects.Rectangle} The Game Object that was created. + * @event Phaser.Sound.Events#COMPLETE + * @type {string} + * @since 3.16.1 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. */ -GameObjectFactory.register('rectangle', function (x, y, width, height, fillColor, fillAlpha) -{ - return this.displayList.add(new Rectangle(this.scene, x, y, width, height, fillColor, fillAlpha)); -}); +module.exports = 'complete'; /***/ }), -/* 1158 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 19679: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Star = __webpack_require__(474); -var GameObjectFactory = __webpack_require__(5); - /** - * Creates a new Star Shape Game Object and adds it to the Scene. + * The Audio Data Decoded All Event. * - * Note: This method will only be available if the Star Game Object has been built into Phaser. - * - * 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. + * This event is dispatched by the Web Audio Sound Manager as a result of calling the `decodeAudio` method, + * once all files passed to the method have been decoded (or errored). * - * @method Phaser.GameObjects.GameObjectFactory#star - * @since 3.13.0 + * Use `Phaser.Sound.Events#DECODED` to listen for single sounds being decoded, and `DECODED_ALL` to + * listen for them all completing. * - * @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. + * Listen to it from the Sound Manager in a Scene using `this.sound.on('decodedall', listener)`, i.e.: * - * @return {Phaser.GameObjects.Star} The Game Object that was created. + * ```javascript + * this.sound.once('decodedall', handler); + * this.sound.decodeAudio([ audioFiles ]); + * ``` + * + * @event Phaser.Sound.Events#DECODED_ALL + * @type {string} + * @since 3.18.0 */ -GameObjectFactory.register('star', function (x, y, points, innerRadius, outerRadius, fillColor, fillAlpha) -{ - return this.displayList.add(new Star(this.scene, x, y, points, innerRadius, outerRadius, fillColor, fillAlpha)); -}); +module.exports = 'decodedall'; /***/ }), -/* 1159 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 56951: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectFactory = __webpack_require__(5); -var Triangle = __webpack_require__(475); - /** - * Creates a new Triangle Shape Game Object and adds it to the Scene. + * The Audio Data Decoded Event. * - * Note: This method will only be available if the Triangle Game Object has been built into Phaser. - * - * 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. + * This event is dispatched by the Web Audio Sound Manager as a result of calling the `decodeAudio` method. * - * @method Phaser.GameObjects.GameObjectFactory#triangle - * @since 3.13.0 + * Listen to it from the Sound Manager in a Scene using `this.sound.on('decoded', listener)`, i.e.: * - * @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. + * ```javascript + * this.sound.on('decoded', handler); + * this.sound.decodeAudio(key, audioData); + * ``` * - * @return {Phaser.GameObjects.Triangle} The Game Object that was created. + * @event Phaser.Sound.Events#DECODED + * @type {string} + * @since 3.18.0 + * + * @param {string} key - The key of the audio file that was decoded and added to the audio cache. */ -GameObjectFactory.register('triangle', function (x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha) -{ - return this.displayList.add(new Triangle(this.scene, x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha)); -}); +module.exports = 'decoded'; /***/ }), -/* 1160 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 16436: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Blitter = __webpack_require__(213); -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); - /** - * Creates a new Blitter Game Object and returns it. + * The Sound Destroy Event. * - * Note: This method will only be available if the Blitter Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are destroyed, either + * directly or via a Sound Manager. * - * @method Phaser.GameObjects.GameObjectCreator#blitter - * @since 3.0.0 + * Listen to it from a Sound instance using `Sound.on('destroy', listener)`, i.e.: * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * ```javascript + * var music = this.sound.add('key'); + * music.on('destroy', listener); + * music.destroy(); + * ``` * - * @return {Phaser.GameObjects.Blitter} The Game Object that was created. + * @event Phaser.Sound.Events#DESTROY + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. */ -GameObjectCreator.register('blitter', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var key = GetAdvancedValue(config, 'key', null); - var frame = GetAdvancedValue(config, 'frame', null); - - var blitter = new Blitter(this.scene, 0, 0, key, frame); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, blitter, config); - - return blitter; -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'destroy'; /***/ }), -/* 1161 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 55154: +/***/ ((module) => { /** * @author Richard Davey - * @author Felipe Alfonso <@bitnenfer> - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BuildGameObject = __webpack_require__(28); -var Container = __webpack_require__(214); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); - /** - * Creates a new Container Game Object and returns it. + * The Sound Detune Event. * - * Note: This method will only be available if the Container Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their detune value changes. * - * @method Phaser.GameObjects.GameObjectCreator#container - * @since 3.4.0 + * Listen to it from a Sound instance using `Sound.on('detune', listener)`, i.e.: * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * ```javascript + * var music = this.sound.add('key'); + * music.on('detune', listener); + * music.play(); + * music.setDetune(200); + * ``` * - * @return {Phaser.GameObjects.Container} The Game Object that was created. + * @event Phaser.Sound.Events#DETUNE + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. + * @param {number} detune - The new detune value of the Sound. */ -GameObjectCreator.register('container', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var x = GetAdvancedValue(config, 'x', 0); - var y = GetAdvancedValue(config, 'y', 0); - var children = GetAdvancedValue(config, 'children', null); - - var container = new Container(this.scene, x, y, children); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, container, config); - - return container; -}); +module.exports = 'detune'; /***/ }), -/* 1162 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 57818: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(215); -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); - /** - * Creates a new Dynamic Bitmap Text Game Object and returns it. + * The Sound Manager Global Detune Event. * - * Note: This method will only be available if the Dynamic Bitmap Text Game Object has been built into Phaser. + * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, + * or the HTML5 Audio Manager. It is dispatched when the `detune` property of the Sound Manager is changed, which globally + * adjusts the detuning of all active sounds. * - * @method Phaser.GameObjects.GameObjectCreator#dynamicBitmapText + * Listen to it from a Scene using: `this.sound.on('rate', listener)`. + * + * @event Phaser.Sound.Events#GLOBAL_DETUNE + * @type {string} * @since 3.0.0 - *² - * @param {Phaser.Types.GameObjects.BitmapText.BitmapTextConfig} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. * - * @return {Phaser.GameObjects.DynamicBitmapText} The Game Object that was created. + * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. + * @param {number} detune - The updated detune value. */ -GameObjectCreator.register('dynamicBitmapText', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var font = GetAdvancedValue(config, 'font', ''); - var text = GetAdvancedValue(config, 'text', ''); - var size = GetAdvancedValue(config, 'size', false); - - var bitmapText = new BitmapText(this.scene, 0, 0, font, text, size); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, bitmapText, config); - - return bitmapText; -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'detune'; /***/ }), -/* 1163 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 57890: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectCreator = __webpack_require__(16); -var Graphics = __webpack_require__(216); - /** - * Creates a new Graphics Game Object and returns it. + * The Sound Manager Global Mute Event. * - * Note: This method will only be available if the Graphics Game Object has been built into Phaser. + * This event is dispatched by the Sound Manager when its `mute` property is changed, either directly + * or via the `setMute` method. This changes the mute state of all active sounds. * - * @method Phaser.GameObjects.GameObjectCreator#graphics - * @since 3.0.0 + * Listen to it from a Scene using: `this.sound.on('mute', listener)`. * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * @event Phaser.Sound.Events#GLOBAL_MUTE + * @type {string} + * @since 3.0.0 * - * @return {Phaser.GameObjects.Graphics} The Game Object that was created. + * @param {(Phaser.Sound.WebAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager)} soundManager - A reference to the Sound Manager that emitted the event. + * @param {boolean} mute - The mute value. `true` if the Sound Manager is now muted, otherwise `false`. */ -GameObjectCreator.register('graphics', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - var graphics = new Graphics(this.scene, config); - - if (config.add) - { - this.scene.sys.displayList.add(graphics); - } - - return graphics; -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'mute'; /***/ }), -/* 1164 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 83022: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectCreator = __webpack_require__(16); -var Group = __webpack_require__(113); - /** - * Creates a new Group Game Object and returns it. + * The Sound Manager Global Rate Event. * - * Note: This method will only be available if the Group Game Object has been built into Phaser. + * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, + * or the HTML5 Audio Manager. It is dispatched when the `rate` property of the Sound Manager is changed, which globally + * adjusts the playback rate of all active sounds. * - * @method Phaser.GameObjects.GameObjectCreator#group - * @since 3.0.0 + * Listen to it from a Scene using: `this.sound.on('rate', listener)`. * - * @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} config - The configuration object this Game Object will use to create itself. + * @event Phaser.Sound.Events#GLOBAL_RATE + * @type {string} + * @since 3.0.0 * - * @return {Phaser.GameObjects.Group} The Game Object that was created. + * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. + * @param {number} rate - The updated rate value. */ -GameObjectCreator.register('group', function (config) -{ - return new Group(this.scene, null, config); -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'rate'; /***/ }), -/* 1165 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 99170: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var Image = __webpack_require__(125); - /** - * Creates a new Image Game Object and returns it. + * The Sound Manager Global Volume Event. * - * Note: This method will only be available if the Image Game Object has been built into Phaser. + * This event is dispatched by the Sound Manager when its `volume` property is changed, either directly + * or via the `setVolume` method. This changes the volume of all active sounds. * - * @method Phaser.GameObjects.GameObjectCreator#image - * @since 3.0.0 + * Listen to it from a Scene using: `this.sound.on('volume', listener)`. * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * @event Phaser.Sound.Events#GLOBAL_VOLUME + * @type {string} + * @since 3.0.0 * - * @return {Phaser.GameObjects.Image} The Game Object that was created. + * @param {(Phaser.Sound.WebAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager)} soundManager - A reference to the sound manager that emitted the event. + * @param {number} volume - The new global volume of the Sound Manager. */ -GameObjectCreator.register('image', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var key = GetAdvancedValue(config, 'key', null); - var frame = GetAdvancedValue(config, 'frame', null); - - var image = new Image(this.scene, 0, 0, key, frame); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, image, config); - - return image; -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'volume'; /***/ }), -/* 1166 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 64289: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BuildGameObject = __webpack_require__(28); -var Layer = __webpack_require__(219); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); - /** - * Creates a new Layer Game Object and returns it. + * The Sound Looped Event. * - * Note: This method will only be available if the Layer Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they loop during playback. * - * @method Phaser.GameObjects.GameObjectCreator#layer - * @since 3.50.0 + * Listen to it from a Sound instance using `Sound.on('looped', listener)`, i.e.: * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * ```javascript + * var music = this.sound.add('key'); + * music.on('looped', listener); + * music.setLoop(true); + * music.play(); + * ``` * - * @return {Phaser.GameObjects.Layer} The Game Object that was created. + * This is not to be confused with the [LOOP]{@linkcode Phaser.Sound.Events#event:LOOP} event, which only emits when the loop state of a Sound is changed. + * + * @event Phaser.Sound.Events#LOOPED + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. */ -GameObjectCreator.register('layer', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var children = GetAdvancedValue(config, 'children', null); - - var layer = new Layer(this.scene, children); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, layer, config); - - return layer; -}); +module.exports = 'looped'; /***/ }), -/* 1167 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 67214: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var GetFastValue = __webpack_require__(2); -var ParticleEmitterManager = __webpack_require__(220); - /** - * Creates a new Particle Emitter Manager Game Object and returns it. + * The Sound Loop Event. * - * Note: This method will only be available if the Particles Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their loop state is changed. * - * @method Phaser.GameObjects.GameObjectCreator#particles - * @since 3.0.0 + * Listen to it from a Sound instance using `Sound.on('loop', listener)`, i.e.: * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * ```javascript + * var music = this.sound.add('key'); + * music.on('loop', listener); + * music.setLoop(true); + * ``` * - * @return {Phaser.GameObjects.Particles.ParticleEmitterManager} The Game Object that was created. + * This is not to be confused with the [LOOPED]{@linkcode Phaser.Sound.Events#event:LOOPED} event, which emits each time a Sound loops during playback. + * + * @event Phaser.Sound.Events#LOOP + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. + * @param {boolean} loop - The new loop value. `true` if the Sound will loop, otherwise `false`. */ -GameObjectCreator.register('particles', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var key = GetAdvancedValue(config, 'key', null); - var frame = GetAdvancedValue(config, 'frame', null); - var emitters = GetFastValue(config, 'emitters', null); - - // frame is optional and can contain the emitters array or object if skipped - var manager = new ParticleEmitterManager(this.scene, key, frame, emitters); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - var add = GetFastValue(config, 'add', false); - - if (add) - { - this.displayList.add(manager); - } - else - { - this.updateList.add(manager); - } - - return manager; -}); +module.exports = 'loop'; /***/ }), -/* 1168 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 53128: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var RenderTexture = __webpack_require__(221); - /** - * Creates a new Render Texture Game Object and returns it. + * The Sound Mute Event. * - * Note: This method will only be available if the Render Texture Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their mute state changes. * - * @method Phaser.GameObjects.GameObjectCreator#renderTexture - * @since 3.2.0 + * Listen to it from a Sound instance using `Sound.on('mute', listener)`, i.e.: * - * @param {Phaser.Types.GameObjects.RenderTexture.RenderTextureConfig} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * ```javascript + * var music = this.sound.add('key'); + * music.on('mute', listener); + * music.play(); + * music.setMute(true); + * ``` * - * @return {Phaser.GameObjects.RenderTexture} The Game Object that was created. + * @event Phaser.Sound.Events#MUTE + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. + * @param {boolean} mute - The mute value. `true` if the Sound is now muted, otherwise `false`. */ -GameObjectCreator.register('renderTexture', function (config, addToScene) -{ - if (config === undefined) { config = {}; } +module.exports = 'mute'; - var x = GetAdvancedValue(config, 'x', 0); - var y = GetAdvancedValue(config, 'y', 0); - var width = GetAdvancedValue(config, 'width', 32); - var height = GetAdvancedValue(config, 'height', 32); - var key = GetAdvancedValue(config, 'key', undefined); - var frame = GetAdvancedValue(config, 'frame', undefined); - var renderTexture = new RenderTexture(this.scene, x, y, width, height, key, frame); +/***/ }), - if (addToScene !== undefined) - { - config.add = addToScene; - } +/***/ 73078: +/***/ ((module) => { - BuildGameObject(this.scene, renderTexture, config); +/** + * @author pi-kei + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return renderTexture; -}); +/** + * The Sound Pan Event. + * + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes. + * + * Listen to it from a Sound instance using `Sound.on('pan', listener)`, i.e.: + * + * ```javascript + * var sound = this.sound.add('key'); + * sound.on('pan', listener); + * sound.play(); + * sound.setPan(0.5); + * ``` + * + * @event Phaser.Sound.Events#PAN + * @type {string} + * @since 3.50.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. + * @param {number} pan - The new pan of the Sound. + */ +module.exports = 'pan'; /***/ }), -/* 1169 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 76763: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var GetValue = __webpack_require__(6); -var Rope = __webpack_require__(223); - /** - * Creates a new Rope Game Object and returns it. + * The Pause All Sounds Event. * - * Note: This method will only be available if the Rope Game Object and WebGL support have been built into Phaser. + * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, + * or the HTML5 Audio Manager. It is dispatched when the `pauseAll` method is invoked and after all current Sounds + * have been paused. * - * @method Phaser.GameObjects.GameObjectCreator#rope - * @since 3.23.0 + * Listen to it from a Scene using: `this.sound.on('pauseall', listener)`. * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * @event Phaser.Sound.Events#PAUSE_ALL + * @type {string} + * @since 3.0.0 * - * @return {Phaser.GameObjects.Rope} The Game Object that was created. + * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. */ -GameObjectCreator.register('rope', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var key = GetAdvancedValue(config, 'key', null); - var frame = GetAdvancedValue(config, 'frame', null); - var horizontal = GetAdvancedValue(config, 'horizontal', true); - var points = GetValue(config, 'points', undefined); - var colors = GetValue(config, 'colors', undefined); - var alphas = GetValue(config, 'alphas', undefined); - - var rope = new Rope(this.scene, 0, 0, key, frame, points, horizontal, colors, alphas); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, rope, config); - - if (!config.add) - { - this.updateList.add(rope); - } - - return rope; -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'pauseall'; /***/ }), -/* 1170 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 88426: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BuildGameObject = __webpack_require__(28); -var BuildGameObjectAnimation = __webpack_require__(439); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var Sprite = __webpack_require__(73); - /** - * Creates a new Sprite Game Object and returns it. + * The Sound Pause Event. * - * Note: This method will only be available if the Sprite Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are paused. * - * @method Phaser.GameObjects.GameObjectCreator#sprite - * @since 3.0.0 + * Listen to it from a Sound instance using `Sound.on('pause', listener)`, i.e.: * - * @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * ```javascript + * var music = this.sound.add('key'); + * music.on('pause', listener); + * music.play(); + * music.pause(); + * ``` * - * @return {Phaser.GameObjects.Sprite} The Game Object that was created. + * @event Phaser.Sound.Events#PAUSE + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. */ -GameObjectCreator.register('sprite', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var key = GetAdvancedValue(config, 'key', null); - var frame = GetAdvancedValue(config, 'frame', null); - - var sprite = new Sprite(this.scene, 0, 0, key, frame); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, sprite, config); - - // Sprite specific config options: - - BuildGameObjectAnimation(sprite, config); - - return sprite; -}); +module.exports = 'pause'; /***/ }), -/* 1171 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 13765: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BitmapText = __webpack_require__(148); -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var GetValue = __webpack_require__(6); - /** - * Creates a new Bitmap Text Game Object and returns it. + * The Sound Play Event. * - * Note: This method will only be available if the Bitmap Text Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are played. * - * @method Phaser.GameObjects.GameObjectCreator#bitmapText + * Listen to it from a Sound instance using `Sound.on('play', listener)`, i.e.: + * + * ```javascript + * var music = this.sound.add('key'); + * music.on('play', listener); + * music.play(); + * ``` + * + * @event Phaser.Sound.Events#PLAY + * @type {string} * @since 3.0.0 * - * @param {Phaser.Types.GameObjects.BitmapText.BitmapTextConfig} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. - * - * @return {Phaser.GameObjects.BitmapText} The Game Object that was created. + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. */ -GameObjectCreator.register('bitmapText', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var font = GetValue(config, 'font', ''); - var text = GetAdvancedValue(config, 'text', ''); - var size = GetAdvancedValue(config, 'size', false); - var align = GetValue(config, 'align', 0); - - var bitmapText = new BitmapText(this.scene, 0, 0, font, text, size, align); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, bitmapText, config); - - return bitmapText; -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'play'; /***/ }), -/* 1172 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 80291: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var Text = __webpack_require__(224); - /** - * Creates a new Text Game Object and returns it. + * The Sound Rate Change Event. * - * Note: This method will only be available if the Text Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their rate changes. * - * @method Phaser.GameObjects.GameObjectCreator#text - * @since 3.0.0 + * Listen to it from a Sound instance using `Sound.on('rate', listener)`, i.e.: * - * @param {Phaser.Types.GameObjects.Text.TextConfig} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * ```javascript + * var music = this.sound.add('key'); + * music.on('rate', listener); + * music.play(); + * music.setRate(0.5); + * ``` * - * @return {Phaser.GameObjects.Text} The Game Object that was created. + * @event Phaser.Sound.Events#RATE + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. + * @param {number} rate - The new rate of the Sound. */ -GameObjectCreator.register('text', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - // style Object = { - // font: [ 'font', '16px Courier' ], - // backgroundColor: [ 'backgroundColor', null ], - // fill: [ 'fill', '#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', false ], - // fixedHeight: [ 'fixedHeight', false ], - // rtl: [ 'rtl', false ] - // } - - var content = GetAdvancedValue(config, 'text', ''); - var style = GetAdvancedValue(config, 'style', null); - - // Padding - // { padding: 2 } - // { padding: { x: , y: }} - // { padding: { left: , top: }} - // { padding: { left: , right: , top: , bottom: }} - - var padding = GetAdvancedValue(config, 'padding', null); - - if (padding !== null) - { - style.padding = padding; - } - - var text = new Text(this.scene, 0, 0, content, style); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, text, config); - - // Text specific config options: - - text.autoRound = GetAdvancedValue(config, 'autoRound', true); - text.resolution = GetAdvancedValue(config, 'resolution', 1); - - return text; -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'rate'; /***/ }), -/* 1173 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 11124: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var TileSprite = __webpack_require__(225); - /** - * Creates a new TileSprite Game Object and returns it. + * The Resume All Sounds Event. * - * Note: This method will only be available if the TileSprite Game Object has been built into Phaser. + * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, + * or the HTML5 Audio Manager. It is dispatched when the `resumeAll` method is invoked and after all current Sounds + * have been resumed. * - * @method Phaser.GameObjects.GameObjectCreator#tileSprite - * @since 3.0.0 + * Listen to it from a Scene using: `this.sound.on('resumeall', listener)`. * - * @param {Phaser.Types.GameObjects.TileSprite.TileSpriteConfig} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * @event Phaser.Sound.Events#RESUME_ALL + * @type {string} + * @since 3.0.0 * - * @return {Phaser.GameObjects.TileSprite} The Game Object that was created. + * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. */ -GameObjectCreator.register('tileSprite', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var x = GetAdvancedValue(config, 'x', 0); - var y = GetAdvancedValue(config, 'y', 0); - var width = GetAdvancedValue(config, 'width', 512); - var height = GetAdvancedValue(config, 'height', 512); - var key = GetAdvancedValue(config, 'key', ''); - var frame = GetAdvancedValue(config, 'frame', ''); - - var tile = new TileSprite(this.scene, x, y, width, height, key, frame); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, tile, config); - - return tile; -}); +module.exports = 'resumeall'; /***/ }), -/* 1174 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 55382: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var Zone = __webpack_require__(129); - /** - * Creates a new Zone Game Object and returns it. + * The Sound Resume Event. * - * Note: This method will only be available if the Zone Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are resumed from a paused state. * - * @method Phaser.GameObjects.GameObjectCreator#zone - * @since 3.0.0 + * Listen to it from a Sound instance using `Sound.on('resume', listener)`, i.e.: * - * @param {object} config - The configuration object this Game Object will use to create itself. + * ```javascript + * var music = this.sound.add('key'); + * music.on('resume', listener); + * music.play(); + * music.pause(); + * music.resume(); + * ``` * - * @return {Phaser.GameObjects.Zone} The Game Object that was created. + * @event Phaser.Sound.Events#RESUME + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. */ -GameObjectCreator.register('zone', function (config) -{ - var x = GetAdvancedValue(config, 'x', 0); - var y = GetAdvancedValue(config, 'y', 0); - var width = GetAdvancedValue(config, 'width', 1); - var height = GetAdvancedValue(config, 'height', width); - - return new Zone(this.scene, x, y, width, height); -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'resume'; /***/ }), -/* 1175 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71157: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var Video = __webpack_require__(226); - /** - * Creates a new Video Game Object and returns it. + * The Sound Seek Event. * - * Note: This method will only be available if the Video Game Object has been built into Phaser. + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are seeked to a new position. * - * @method Phaser.GameObjects.GameObjectCreator#video - * @since 3.20.0 + * Listen to it from a Sound instance using `Sound.on('seek', listener)`, i.e.: * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * ```javascript + * var music = this.sound.add('key'); + * music.on('seek', listener); + * music.play(); + * music.setSeek(5000); + * ``` * - * @return {Phaser.GameObjects.Video} The Game Object that was created. + * @event Phaser.Sound.Events#SEEK + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. + * @param {number} detune - The new detune value of the Sound. */ -GameObjectCreator.register('video', function (config, addToScene) -{ - if (config === undefined) { config = {}; } - - var key = GetAdvancedValue(config, 'key', null); - - var video = new Video(this.scene, 0, 0, key); - - if (addToScene !== undefined) - { - config.add = addToScene; - } - - BuildGameObject(this.scene, video, config); - - if (!config.add) - { - this.updateList.add(video); - } - - return video; -}); - -// When registering a factory function 'this' refers to the GameObjectCreator context. +module.exports = 'seek'; /***/ }), -/* 1176 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 31776: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1177); -} - -if (true) -{ - renderCanvas = __webpack_require__(1178); -} - -module.exports = { - - renderWebGL: renderWebGL, - renderCanvas: renderCanvas - -}; +/** + * The Stop All Sounds Event. + * + * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, + * or the HTML5 Audio Manager. It is dispatched when the `stopAll` method is invoked and after all current Sounds + * have been stopped. + * + * Listen to it from a Scene using: `this.sound.on('stopall', listener)`. + * + * @event Phaser.Sound.Events#STOP_ALL + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. + */ +module.exports = 'stopall'; /***/ }), -/* 1177 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 39450: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(19); - /** - * 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. + * The Sound Stop Event. * - * @method Phaser.GameObjects.Shader#renderWebGL - * @since 3.17.0 - * @private + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when they are stopped. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Shader} 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 + * Listen to it from a Sound instance using `Sound.on('stop', listener)`, i.e.: + * + * ```javascript + * var music = this.sound.add('key'); + * music.on('stop', listener); + * music.play(); + * music.stop(); + * ``` + * + * @event Phaser.Sound.Events#STOP + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. */ -var ShaderWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - if (!src.shader) - { - return; - } - - camera.addToRenderList(src); - - renderer.pipelines.clear(); +module.exports = 'stop'; - if (src.renderToTexture) - { - src.load(); - src.flush(); - } - else - { - var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; - // Renderer size changed? - if (renderer.width !== src._rendererWidth || renderer.height !== src._rendererHeight) - { - src.projOrtho(0, renderer.width, renderer.height, 0); - } +/***/ }), - src.load(calcMatrix.matrix); - src.flush(); - } +/***/ 21939: +/***/ ((module) => { - renderer.pipelines.rebind(); -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = ShaderWebGLRenderer; +/** + * The Sound Manager Unlocked Event. + * + * This event is dispatched by the Base Sound Manager, or more typically, an instance of the Web Audio Sound Manager, + * or the HTML5 Audio Manager. It is dispatched during the update loop when the Sound Manager becomes unlocked. For + * Web Audio this is on the first user gesture on the page. + * + * Listen to it from a Scene using: `this.sound.on('unlocked', listener)`. + * + * @event Phaser.Sound.Events#UNLOCKED + * @type {string} + * @since 3.0.0 + * + * @param {Phaser.Sound.BaseSoundManager} soundManager - A reference to the sound manager that emitted the event. + */ +module.exports = 'unlocked'; /***/ }), -/* 1178 */ -/***/ (function(module, exports) { + +/***/ 33019: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * This is a stub function for Shader.Render. There is no Canvas renderer for Shader objects. + * The Sound Volume Event. * - * @method Phaser.GameObjects.Shader#renderCanvas - * @since 3.17.0 - * @private + * This event is dispatched by both Web Audio and HTML5 Audio Sound objects when their volume changes. * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Shader} src - The Game Object being rendered in this call. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + * Listen to it from a Sound instance using `Sound.on('volume', listener)`, i.e.: + * + * ```javascript + * var music = this.sound.add('key'); + * music.on('volume', listener); + * music.play(); + * music.setVolume(0.5); + * ``` + * + * @event Phaser.Sound.Events#VOLUME + * @type {string} + * @since 3.0.0 + * + * @param {(Phaser.Sound.WebAudioSound|Phaser.Sound.HTML5AudioSound)} sound - A reference to the Sound that emitted the event. + * @param {number} volume - The new volume of the Sound. */ -var ShaderCanvasRenderer = function () -{ -}; - -module.exports = ShaderCanvasRenderer; +module.exports = 'volume'; /***/ }), -/* 1179 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 76038: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); - -if (true) -{ - renderWebGL = __webpack_require__(1180); -} - -if (true) -{ - renderCanvas = __webpack_require__(1181); -} +/** + * @namespace Phaser.Sound.Events + */ module.exports = { - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + COMPLETE: __webpack_require__(77578), + DECODED: __webpack_require__(56951), + DECODED_ALL: __webpack_require__(19679), + DESTROY: __webpack_require__(16436), + DETUNE: __webpack_require__(55154), + GLOBAL_DETUNE: __webpack_require__(57818), + GLOBAL_MUTE: __webpack_require__(57890), + GLOBAL_RATE: __webpack_require__(83022), + GLOBAL_VOLUME: __webpack_require__(99170), + LOOP: __webpack_require__(67214), + LOOPED: __webpack_require__(64289), + MUTE: __webpack_require__(53128), + PAN: __webpack_require__(73078), + PAUSE_ALL: __webpack_require__(76763), + PAUSE: __webpack_require__(88426), + PLAY: __webpack_require__(13765), + RATE: __webpack_require__(80291), + RESUME_ALL: __webpack_require__(11124), + RESUME: __webpack_require__(55382), + SEEK: __webpack_require__(71157), + STOP_ALL: __webpack_require__(31776), + STOP: __webpack_require__(39450), + UNLOCKED: __webpack_require__(21939), + VOLUME: __webpack_require__(33019) }; /***/ }), -/* 1180 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 34350: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetCalcMatrix = __webpack_require__(19); +var BaseSound = __webpack_require__(25798); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(76038); +var Clamp = __webpack_require__(82897); /** - * 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. + * @classdesc + * HTML5 Audio implementation of the sound. * - * @method Phaser.GameObjects.Mesh#renderWebGL + * @class HTML5AudioSound + * @extends Phaser.Sound.BaseSound + * @memberof Phaser.Sound + * @constructor * @since 3.0.0 - * @private * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.Mesh} 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 {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 MeshWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - var faces = src.faces; - var totalFaces = faces.length; - - if (totalFaces === 0) - { - return; - } - - camera.addToRenderList(src); - - var pipeline = renderer.pipelines.set(src.pipeline, src); +var HTML5AudioSound = new Class({ - var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; + Extends: BaseSound, - var textureUnit = pipeline.setGameObject(src); + initialize: - var F32 = pipeline.vertexViewF32; - var U32 = pipeline.vertexViewU32; + function HTML5AudioSound (manager, key, config) + { + if (config === undefined) { config = {}; } - var vertexOffset = (pipeline.vertexCount * pipeline.currentShader.vertexComponentCount) - 1; + /** + * An array containing all HTML5 Audio tags that could be used for individual + * sound 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[]} + * @since 3.0.0 + */ + this.tags = manager.game.cache.audio.get(key); - var tintEffect = src.tintFill; + if (!this.tags) + { + throw new Error('No cached audio asset with key "' + key); + } - var debugFaces = []; - var debugCallback = src.debugCallback; + /** + * Reference to an HTML5 Audio tag used for playing sound. + * + * @name Phaser.Sound.HTML5AudioSound#audio + * @type {HTMLAudioElement} + * @default null + * @since 3.0.0 + */ + this.audio = null; - var a = calcMatrix.a; - var b = calcMatrix.b; - var c = calcMatrix.c; - var d = calcMatrix.d; - var e = calcMatrix.e; - var f = calcMatrix.f; + /** + * 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} + * @default 0 + * @since 3.0.0 + */ + this.startTime = 0; - var z = src.viewPosition.z; + /** + * 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} + * @default 0 + * @since 3.0.0 + */ + this.previousTime = 0; - var hideCCW = src.hideCCW; - var roundPixels = camera.roundPixels; - var alpha = camera.alpha * src.alpha; + this.duration = this.tags[0].duration; - var totalFacesRendered = 0; + this.totalDuration = this.tags[0].duration; - renderer.pipelines.preBatch(src); + BaseSound.call(this, manager, key, config); + }, - for (var i = 0; i < totalFaces; i++) + /** + * 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. + * + * If you want to play the same sound simultaneously, then you need to create another instance + * of it and play that Sound. For HTML5 Audio this also requires creating multiple audio instances + * when loading the audio files. + * + * @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) { - var face = faces[i]; - - // If face has alpha <= 0, or hideCCW + clockwise, or isn't in camera view, then don't draw it - if (!face.isInView(camera, hideCCW, z, alpha, a, b, c, d, e, f, roundPixels)) + if (this.manager.isLocked(this, 'play', [ markerName, config ])) { - continue; + return false; } - if (pipeline.shouldFlush(3)) + if (!BaseSound.prototype.play.call(this, markerName, config)) { - pipeline.flush(); - - vertexOffset = 0; + return false; } - vertexOffset = face.load(F32, U32, vertexOffset, textureUnit, tintEffect); - - totalFacesRendered++; - pipeline.vertexCount += 3; - - if (debugCallback) + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + if (!this.pickAndPlayAudioTag()) { - debugFaces.push(face); + return false; } - } - src.totalFrame += totalFacesRendered; + this.emit(Events.PLAY, this); - if (debugCallback) - { - debugCallback.call(src, src, debugFaces); - } + return true; + }, - renderer.pipelines.postBatch(src); -}; + /** + * 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; + } -module.exports = MeshWebGLRenderer; + if (this.startTime > 0) + { + return false; + } + if (!BaseSound.prototype.pause.call(this)) + { + return false; + } -/***/ }), -/* 1181 */ -/***/ (function(module, exports) { + // \/\/\/ isPlaying = false, isPaused = true \/\/\/ + this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.stopAndReleaseAudioTag(); -/** - * This is a stub function for Mesh.Render. There is no Canvas renderer for Mesh objects. - * - * @method Phaser.GameObjects.Mesh#renderCanvas - * @since 3.0.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.GameObjects.Mesh} src - The Game Object being rendered in this call. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. - */ -var MeshCanvasRenderer = function () -{ -}; + this.emit(Events.PAUSE, this); -module.exports = MeshCanvasRenderer; + 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; + } -/***/ }), -/* 1182 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.startTime > 0) + { + return false; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!BaseSound.prototype.resume.call(this)) + { + return false; + } -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + if (!this.pickAndPlayAudioTag()) + { + return false; + } -if (true) -{ - renderWebGL = __webpack_require__(1183); -} + this.emit(Events.RESUME, this); -module.exports = { + return true; + }, - renderWebGL: renderWebGL, - renderCanvas: renderCanvas + /** + * 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(); -/***/ }), -/* 1183 */ -/***/ (function(module, exports, __webpack_require__) { + this.emit(Events.STOP, this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return true; + }, -var GetCalcMatrix = __webpack_require__(19); + /** + * This method is used internally to pick and play the next available audio tag. + * + * @method Phaser.Sound.HTML5AudioSound#pickAndPlayAudioTag + * @since 3.0.0 + * + * @return {boolean} Whether the sound was assigned an audio tag successfully. + */ + pickAndPlayAudioTag: function () + { + if (!this.pickAudioTag()) + { + this.reset(); -/** - * 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.PointLight#renderWebGL - * @since 3.50.0 - * @private - * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.GameObjects.PointLight} 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 PointLightWebGLRenderer = function (renderer, src, camera, parentMatrix) -{ - camera.addToRenderList(src); + return false; + } - var pipeline = renderer.pipelines.set(src.pipeline); + var seek = this.currentConfig.seek; + var delay = this.currentConfig.delay; + var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek; - var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc; + this.previousTime = offset; + this.audio.currentTime = offset; + this.applyConfig(); - var width = src.width; - var height = src.height; + if (delay === 0) + { + this.startTime = 0; - var x = -src._radius; - var y = -src._radius; + if (this.audio.paused) + { + this.playCatchPromise(); + } + } + else + { + this.startTime = window.performance.now() + delay * 1000; - var xw = x + width; - var yh = y + height; + if (!this.audio.paused) + { + this.audio.pause(); + } + } - var lightX = calcMatrix.getX(0, 0); - var lightY = calcMatrix.getY(0, 0); + this.resetConfig(); - var tx0 = calcMatrix.getX(x, y); - var ty0 = calcMatrix.getY(x, y); + return true; + }, - var tx1 = calcMatrix.getX(x, yh); - var ty1 = calcMatrix.getY(x, yh); + /** + * 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 + * @since 3.0.0 + * + * @return {boolean} Whether the sound was assigned an audio tag successfully. + */ + pickAudioTag: function () + { + if (this.audio) + { + return true; + } - var tx2 = calcMatrix.getX(xw, yh); - var ty2 = calcMatrix.getY(xw, yh); + for (var i = 0; i < this.tags.length; i++) + { + var audio = this.tags[i]; - var tx3 = calcMatrix.getX(xw, y); - var ty3 = calcMatrix.getY(xw, y); + if (audio.dataset.used === 'false') + { + audio.dataset.used = 'true'; + this.audio = audio; + return true; + } + } - renderer.pipelines.preBatch(src); + if (!this.manager.override) + { + return false; + } - pipeline.batchPointLight(src, camera, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, lightX, lightY); + var otherSounds = []; - renderer.pipelines.postBatch(src); -}; + this.manager.forEachActiveSound(function (sound) + { + if (sound.key === this.key && sound.audio) + { + otherSounds.push(sound); + } + }, this); -module.exports = PointLightWebGLRenderer; + 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]; -/***/ }), -/* 1184 */ -/***/ (function(module, exports, __webpack_require__) { + this.audio = selectedSound.audio; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + selectedSound.reset(); + selectedSound.audio = null; + selectedSound.startTime = 0; + selectedSound.previousTime = 0; -var Shader = __webpack_require__(229); -var GameObjectFactory = __webpack_require__(5); + return true; + }, -/** - * Creates a new Shader Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Shader Game Object and WebGL support have been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#shader - * @webglOnly - * @since 3.17.0 - * - * @param {(string|Phaser.Display.BaseShader)} key - The key of the shader to use from the shader cache, or a BaseShader instance. - * @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 Game Object. - * @param {number} [height=128] - The height of the Game Object. - * @param {string[]} [textures] - Optional array of texture keys to bind to the iChannel0...3 uniforms. The textures must already exist in the Texture Manager. - * @param {object} [textureData] - Optional additional texture data. - * - * @return {Phaser.GameObjects.Shader} The Game Object that was created. - */ -if (true) -{ - GameObjectFactory.register('shader', function (key, x, y, width, height, textures, textureData) + /** + * Method used for playing audio tag and catching possible exceptions + * thrown from rejected Promise returned from play method call. + * + * @method Phaser.Sound.HTML5AudioSound#playCatchPromise + * @since 3.0.0 + */ + playCatchPromise: function () { - return this.displayList.add(new Shader(this.scene, key, x, y, width, height, textures, textureData)); - }); -} - - -/***/ }), -/* 1185 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var playPromise = this.audio.play(); -var Mesh = __webpack_require__(230); -var GameObjectFactory = __webpack_require__(5); + if (playPromise) + { + // eslint-disable-next-line no-unused-vars + playPromise.catch(function (reason) + { + console.warn(reason); + }); + } + }, -/** - * Creates a new Mesh Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Mesh Game Object and WebGL support have been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectFactory#mesh - * @webglOnly - * @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. - * @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.GameObjects.Mesh} The Game Object that was created. - */ -if (true) -{ - GameObjectFactory.register('mesh', function (x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas) + /** + * This method is used internally to stop and release the current audio tag. + * + * @method Phaser.Sound.HTML5AudioSound#stopAndReleaseAudioTag + * @since 3.0.0 + */ + stopAndReleaseAudioTag: function () { - return this.displayList.add(new Mesh(this.scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas)); - }); -} - - -/***/ }), -/* 1186 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.startTime = 0; + this.previousTime = 0; -var GameObjectFactory = __webpack_require__(5); -var PointLight = __webpack_require__(150); + if (this.audio) + { + this.audio.pause(); + this.audio.dataset.used = 'false'; + this.audio = null; + } + }, -/** - * Creates a new Point Light Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Point Light Game Object has been built into Phaser. - * - * The Point Light Game Object provides a way to add a point light effect into your game, - * without the expensive shader processing requirements of the traditional Light Game Object. - * - * The difference is that the Point Light renders using a custom shader, designed to give the - * impression of a point light source, of variable radius, intensity and color, in your game. - * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their - * normal maps for calcuations. This makes them extremely fast to render compared to Lights - * and perfect for special effects, such as flickering torches or muzzle flashes. - * - * For maximum performance you should batch Point Light Game Objects together. This means - * ensuring they follow each other consecutively on the display list. Ideally, use a Layer - * Game Object and then add just Point Lights to it, so that it can batch together the rendering - * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in - * your game then it's perfectly safe to mix them into the dislay list as normal. However, if - * you're using a large number of them, please consider how they are mixed into the display list. - * - * The renderer will automatically cull Point Lights. Those with a radius that does not intersect - * with the Camera will be skipped in the rendering list. This happens automatically and the - * culled state is refreshed every frame, for every camera. - * - * The origin of a Point Light is always 0.5 and it cannot be changed. - * - * Point Lights are a WebGL only feature and do not have a Canvas counterpart. - * - * @method Phaser.GameObjects.GameObjectFactory#pointlight - * @since 3.50.0 - * - * @param {number} x - The horizontal position of this Point Light in the world. - * @param {number} y - The vertical position of this Point Light in the world. - * @param {number} [color=0xffffff] - The color of the Point Light, given as a hex value. - * @param {number} [radius=128] - The radius of the Point Light. - * @param {number} [intensity=1] - The intensity, or colr blend, of the Point Light. - * @param {number} [attenuation=0.1] - The attenuation of the Point Light. This is the reduction of light from the center point. - * - * @return {Phaser.GameObjects.PointLight} The Game Object that was created. - */ -GameObjectFactory.register('pointlight', function (x, y, color, radius, intensity, attenuation) -{ - return this.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity, attenuation)); -}); + /** + * Method used internally to reset sound state, usually when stopping sound + * or when hijacking audio tag from another sound. + * + * @method Phaser.Sound.HTML5AudioSound#reset + * @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.HTML5AudioSound#onBlur + * @since 3.0.0 + */ + onBlur: function () + { + this.isPlaying = false; + this.isPaused = true; -/***/ }), -/* 1187 */ -/***/ (function(module, exports, __webpack_require__) { + this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.currentConfig.delay = Math.max(0, (this.startTime - window.performance.now()) / 1000); -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var Shader = __webpack_require__(229); + this.stopAndReleaseAudioTag(); + }, -/** - * Creates a new Shader Game Object and returns it. - * - * Note: This method will only be available if the Shader Game Object and WebGL support have been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectCreator#shader - * @since 3.17.0 - * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. - * - * @return {Phaser.GameObjects.Shader} The Game Object that was created. - */ -GameObjectCreator.register('shader', function (config, addToScene) -{ - if (config === undefined) { config = {}; } + /** + * Method used internally by sound manager for resuming sound if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + * + * @method Phaser.Sound.HTML5AudioSound#onFocus + * @since 3.0.0 + */ + onFocus: function () + { + this.isPlaying = true; + this.isPaused = false; + this.pickAndPlayAudioTag(); + }, - var key = GetAdvancedValue(config, 'key', null); - var x = GetAdvancedValue(config, 'x', 0); - var y = GetAdvancedValue(config, 'y', 0); - var width = GetAdvancedValue(config, 'width', 128); - var height = GetAdvancedValue(config, 'height', 128); + /** + * 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 + * @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; + } - var shader = new Shader(this.scene, key, x, y, width, height); + // 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(); + } - if (addToScene !== undefined) - { - config.add = addToScene; - } + return; + } - BuildGameObject(this.scene, shader, config); + // handle looping and ending + var startTime = this.currentMarker ? this.currentMarker.start : 0; + var endTime = startTime + this.duration; + var currentTime = this.audio.currentTime; - return shader; -}); + 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; + } -// When registering a factory function 'this' refers to the GameObjectCreator context. + if (currentTime < this.previousTime) + { + this.emit(Events.LOOPED, this); + } + } + else if (currentTime >= endTime) + { + this.reset(); + this.stopAndReleaseAudioTag(); -/***/ }), -/* 1188 */ -/***/ (function(module, exports, __webpack_require__) { + this.emit(Events.COMPLETE, this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return; + } -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var GetValue = __webpack_require__(6); -var Mesh = __webpack_require__(230); + this.previousTime = currentTime; + }, -/** - * Creates a new Mesh Game Object and returns it. - * - * Note: This method will only be available if the Mesh Game Object and WebGL support have been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectCreator#mesh - * @since 3.0.0 - * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. - * - * @return {Phaser.GameObjects.Mesh} The Game Object that was created. - */ -GameObjectCreator.register('mesh', function (config, addToScene) -{ - if (config === undefined) { config = {}; } + /** + * 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); - var key = GetAdvancedValue(config, 'key', null); - var frame = GetAdvancedValue(config, 'frame', null); - var vertices = GetValue(config, 'vertices', []); - var uvs = GetValue(config, 'uvs', []); - var indicies = GetValue(config, 'indicies', []); - var containsZ = GetValue(config, 'containsZ', false); - var normals = GetValue(config, 'normals', []); - var colors = GetValue(config, 'colors', 0xffffff); - var alphas = GetValue(config, 'alphas', 1); + this.tags = null; - var mesh = new Mesh(this.scene, 0, 0, key, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas); + if (this.audio) + { + this.stopAndReleaseAudioTag(); + } + }, - if (addToScene !== undefined) + /** + * This method is used internally to update the mute setting of this sound. + * + * @method Phaser.Sound.HTML5AudioSound#updateMute + * @since 3.0.0 + */ + updateMute: function () { - config.add = addToScene; - } + if (this.audio) + { + this.audio.muted = this.currentConfig.mute || this.manager.mute; + } + }, - BuildGameObject(this.scene, mesh, config); + /** + * This method is used internally to update the volume of this sound. + * + * @method Phaser.Sound.HTML5AudioSound#updateVolume + * @since 3.0.0 + */ + updateVolume: function () + { + if (this.audio) + { + this.audio.volume = Clamp(this.currentConfig.volume * this.manager.volume, 0, 1); + } + }, - return mesh; -}); + /** + * This method is used internally to update the playback rate of this sound. + * + * @method Phaser.Sound.HTML5AudioSound#calculateRate + * @since 3.0.0 + */ + calculateRate: function () + { + BaseSound.prototype.calculateRate.call(this); + if (this.audio) + { + this.audio.playbackRate = this.totalRate; + } + }, -/***/ }), -/* 1189 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this.currentConfig.mute; + }, -var BuildGameObject = __webpack_require__(28); -var GameObjectCreator = __webpack_require__(16); -var GetAdvancedValue = __webpack_require__(13); -var PointLight = __webpack_require__(150); + set: function (value) + { + this.currentConfig.mute = value; -/** - * Creates a new Point Light Game Object and returns it. - * - * Note: This method will only be available if the Point Light Game Object has been built into Phaser. - * - * @method Phaser.GameObjects.GameObjectCreator#pointlight - * @since 3.50.0 - * - * @param {object} config - The configuration object this Game Object will use to create itself. - * @param {boolean} [addToScene] - Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. - * - * @return {Phaser.GameObjects.PointLight} The Game Object that was created. - */ -GameObjectCreator.register('pointlight', function (config, addToScene) -{ - if (config === undefined) { config = {}; } + if (this.manager.isLocked(this, 'mute', value)) + { + return; + } - var color = GetAdvancedValue(config, 'color', 0xffffff); - var radius = GetAdvancedValue(config, 'radius', 128); - var intensity = GetAdvancedValue(config, 'intensity', 1); - var attenuation = GetAdvancedValue(config, 'attenuation', 0.1); + this.updateMute(); - var layer = new PointLight(this.scene, 0, 0, color, radius, intensity, attenuation); + this.emit(Events.MUTE, this, value); + } + }, - if (addToScene !== undefined) + /** + * 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) { - config.add = addToScene; - } - - BuildGameObject(this.scene, layer, config); - - return layer; -}); + this.mute = value; + return this; + }, -/***/ }), -/* 1190 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this.currentConfig.volume; + }, -var Class = __webpack_require__(0); -var LightsManager = __webpack_require__(482); -var PluginCache = __webpack_require__(24); -var SceneEvents = __webpack_require__(20); + set: function (value) + { + this.currentConfig.volume = value; -/** - * @classdesc - * A Scene plugin that provides a {@link Phaser.GameObjects.LightsManager} for the Light2D pipeline. - * - * Available from within a Scene via `this.lights`. - * - * Add Lights using the {@link Phaser.GameObjects.LightsManager#addLight} method: - * - * ```javascript - * // Enable the Lights Manager because it is disabled by default - * this.lights.enable(); - * - * // Create a Light at [400, 300] with a radius of 200 - * this.lights.addLight(400, 300, 200); - * ``` - * - * For Game Objects to be affected by the Lights when rendered, you will need to set them to use the `Light2D` pipeline like so: - * - * ```javascript - * sprite.setPipeline('Light2D'); - * ``` - * - * Note that you cannot use this pipeline on Graphics Game Objects or Shape Game Objects. - * - * @class LightsPlugin - * @extends Phaser.GameObjects.LightsManager - * @memberof Phaser.GameObjects - * @constructor - * @since 3.0.0 - * - * @param {Phaser.Scene} scene - The Scene that this Lights Plugin belongs to. - */ -var LightsPlugin = new Class({ + if (this.manager.isLocked(this, 'volume', value)) + { + return; + } - Extends: LightsManager, + this.updateVolume(); - initialize: + this.emit(Events.VOLUME, this, value); + } + }, - function LightsPlugin (scene) + /** + * 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) { - /** - * A reference to the Scene that this Lights Plugin belongs to. - * - * @name Phaser.GameObjects.LightsPlugin#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; + this.volume = value; - /** - * A reference to the Scene's systems. - * - * @name Phaser.GameObjects.LightsPlugin#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.systems = scene.sys; + 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: { - if (!scene.sys.settings.isBooted) + get: function () { - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + 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); + } } - LightsManager.call(this); }, /** - * Boot the Lights Plugin. + * Sets the playback rate of this Sound. * - * @method Phaser.GameObjects.LightsPlugin#boot - * @since 3.0.0 + * 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. */ - boot: function () + setRate: function (value) { - var eventEmitter = this.systems.events; + this.rate = value; - eventEmitter.on(SceneEvents.SHUTDOWN, this.shutdown, this); - eventEmitter.on(SceneEvents.DESTROY, this.destroy, this); + return this; }, /** - * Destroy the Lights Plugin. - * - * Cleans up all references. + * 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.GameObjects.LightsPlugin#destroy + * @name Phaser.Sound.HTML5AudioSound#detune + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#DETUNE * @since 3.0.0 */ - destroy: function () - { - this.shutdown(); + detune: { - this.scene = undefined; - this.systems = undefined; - } + get: function () + { + return this.currentConfig.detune; + }, -}); + set: function (value) + { + this.currentConfig.detune = value; -PluginCache.register('LightsPlugin', LightsPlugin, 'lights'); + if (this.manager.isLocked(this, Events.DETUNE, value)) + { + return; + } + else + { + this.calculateRate(); -module.exports = LightsPlugin; + this.emit(Events.DETUNE, this, value); + } + } + }, -/***/ }), -/* 1191 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var Circle = __webpack_require__(65); + /** + * 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: { -Circle.Area = __webpack_require__(1192); -Circle.Circumference = __webpack_require__(302); -Circle.CircumferencePoint = __webpack_require__(169); -Circle.Clone = __webpack_require__(1193); -Circle.Contains = __webpack_require__(66); -Circle.ContainsPoint = __webpack_require__(1194); -Circle.ContainsRect = __webpack_require__(1195); -Circle.CopyFrom = __webpack_require__(1196); -Circle.Equals = __webpack_require__(1197); -Circle.GetBounds = __webpack_require__(1198); -Circle.GetPoint = __webpack_require__(300); -Circle.GetPoints = __webpack_require__(301); -Circle.Offset = __webpack_require__(1199); -Circle.OffsetPoint = __webpack_require__(1200); -Circle.Random = __webpack_require__(170); + 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; + } + }, -module.exports = Circle; + set: function (value) + { + if (this.manager.isLocked(this, 'seek', value)) + { + return; + } + if (this.startTime > 0) + { + return; + } -/***/ }), -/* 1192 */ -/***/ (function(module, exports) { + if (this.isPlaying || this.isPaused) + { + value = Math.min(Math.max(0, value), this.duration); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.isPlaying) + { + this.previousTime = value; + this.audio.currentTime = value; + } + else if (this.isPaused) + { + this.currentConfig.seek = value; + } -/** - * Calculates the area of the circle. - * - * @function Phaser.Geom.Circle.Area - * @since 3.0.0 - * - * @param {Phaser.Geom.Circle} circle - The Circle to get the area of. - * - * @return {number} The area of the Circle. - */ -var Area = function (circle) -{ - return (circle.radius > 0) ? Math.PI * circle.radius * circle.radius : 0; -}; + this.emit(Events.SEEK, this, value); + } + } + }, -module.exports = Area; + /** + * 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; + }, -/***/ }), -/* 1193 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this.currentConfig.loop; + }, -var Circle = __webpack_require__(65); + set: function (value) + { + this.currentConfig.loop = value; -/** - * Creates a new Circle instance based on the values contained in the given source. - * - * @function Phaser.Geom.Circle.Clone - * @since 3.0.0 - * - * @param {(Phaser.Geom.Circle|object)} source - The Circle to be cloned. Can be an instance of a Circle or a circle-like object, with x, y and radius properties. - * - * @return {Phaser.Geom.Circle} A clone of the source Circle. - */ -var Clone = function (source) -{ - return new Circle(source.x, source.y, source.radius); -}; + if (this.manager.isLocked(this, 'loop', value)) + { + return; + } -module.exports = Clone; + if (this.audio) + { + this.audio.loop = value; + } + this.emit(Events.LOOP, this, value); + } -/***/ }), -/* 1194 */ -/***/ (function(module, exports, __webpack_require__) { + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var Contains = __webpack_require__(66); + return this; + }, -/** - * Check to see if the Circle contains the given Point object. - * - * @function Phaser.Geom.Circle.ContainsPoint - * @since 3.0.0 - * - * @param {Phaser.Geom.Circle} circle - The Circle to check. - * @param {(Phaser.Geom.Point|object)} point - The Point object to check if it's within the Circle or not. - * - * @return {boolean} True if the Point coordinates are within the circle, otherwise false. - */ -var ContainsPoint = function (circle, point) -{ - return Contains(circle, point.x, point.y); -}; + /** + * 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: { -module.exports = ContainsPoint; + get: function () + { + return this.currentConfig.pan; + }, + set: function (value) + { + this.currentConfig.pan = value; -/***/ }), -/* 1195 */ -/***/ (function(module, exports, __webpack_require__) { + this.emit(Events.PAN, this, value); + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var Contains = __webpack_require__(66); + return this; + } -/** - * Check to see if the Circle contains all four points of the given Rectangle object. - * - * @function Phaser.Geom.Circle.ContainsRect - * @since 3.0.0 - * - * @param {Phaser.Geom.Circle} circle - The Circle to check. - * @param {(Phaser.Geom.Rectangle|object)} rect - The Rectangle object to check if it's within the Circle or not. - * - * @return {boolean} True if all of the Rectangle coordinates are within the circle, otherwise false. - */ -var ContainsRect = function (circle, rect) -{ - return ( - Contains(circle, rect.x, rect.y) && - Contains(circle, rect.right, rect.y) && - Contains(circle, rect.x, rect.bottom) && - Contains(circle, rect.right, rect.bottom) - ); -}; +}); -module.exports = ContainsRect; +module.exports = HTML5AudioSound; /***/ }), -/* 1196 */ -/***/ (function(module, exports) { + +/***/ 27622: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var BaseSoundManager = __webpack_require__(12486); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(76038); +var HTML5AudioSound = __webpack_require__(34350); + /** - * Copies the `x`, `y` and `radius` properties from the `source` Circle - * into the given `dest` Circle, then returns the `dest` Circle. + * HTML5 Audio implementation of the Sound Manager. * - * @function Phaser.Geom.Circle.CopyFrom - * @since 3.0.0 + * To play multiple instances of the same HTML5 Audio sound, you need to provide an `instances` value when + * loading the sound with the Loader: * - * @generic {Phaser.Geom.Circle} O - [dest,$return] + * ```javascript + * this.load.audio('explosion', 'explosion.mp3', { + * instances: 2 + * }); + * ``` * - * @param {Phaser.Geom.Circle} source - The source Circle to copy the values from. - * @param {Phaser.Geom.Circle} dest - The destination Circle to copy the values to. + * Not all browsers can play all audio formats. * - * @return {Phaser.Geom.Circle} The destination Circle. - */ -var CopyFrom = function (source, dest) -{ - return dest.setTo(source.x, source.y, source.radius); -}; - -module.exports = CopyFrom; - - -/***/ }), -/* 1197 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Compares the `x`, `y` and `radius` properties of the two given Circles. - * Returns `true` if they all match, otherwise returns `false`. + * 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). * - * @function Phaser.Geom.Circle.Equals + * @class HTML5AudioSoundManager + * @extends Phaser.Sound.BaseSoundManager + * @memberof Phaser.Sound + * @constructor * @since 3.0.0 * - * @param {Phaser.Geom.Circle} circle - The first Circle to compare. - * @param {Phaser.Geom.Circle} toCompare - The second Circle to compare. - * - * @return {boolean} `true` if the two Circles equal each other, otherwise `false`. + * @param {Phaser.Game} game - Reference to the current game instance. */ -var Equals = function (circle, toCompare) -{ - return ( - circle.x === toCompare.x && - circle.y === toCompare.y && - circle.radius === toCompare.radius - ); -}; - -module.exports = Equals; - - -/***/ }), -/* 1198 */ -/***/ (function(module, exports, __webpack_require__) { +var HTML5AudioSoundManager = new Class({ -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + Extends: BaseSoundManager, -var Rectangle = __webpack_require__(10); + initialize: -/** - * Returns the bounds of the Circle object. - * - * @function Phaser.Geom.Circle.GetBounds - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [out,$return] - * - * @param {Phaser.Geom.Circle} circle - The Circle to get the bounds from. - * @param {(Phaser.Geom.Rectangle|object)} [out] - A Rectangle, or rectangle-like object, to store the circle bounds in. If not given a new Rectangle will be created. - * - * @return {(Phaser.Geom.Rectangle|object)} The Rectangle object containing the Circles bounds. - */ -var GetBounds = function (circle, out) -{ - if (out === undefined) { out = new Rectangle(); } + 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; - out.x = circle.left; - out.y = circle.top; - out.width = circle.diameter; - out.height = circle.diameter; + /** + * 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; - return out; -}; + /** + * 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; -module.exports = GetBounds; + /** + * 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; -/***/ }), -/* 1199 */ -/***/ (function(module, exports) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -/** - * Offsets the Circle by the values given. - * - * @function Phaser.Geom.Circle.Offset - * @since 3.0.0 - * - * @generic {Phaser.Geom.Circle} O - [circle,$return] - * - * @param {Phaser.Geom.Circle} circle - The Circle to be offset (translated.) - * @param {number} x - The amount to horizontally offset the Circle by. - * @param {number} y - The amount to vertically offset the Circle by. - * - * @return {Phaser.Geom.Circle} The Circle that was offset. - */ -var Offset = function (circle, x, y) -{ - circle.x += x; - circle.y += y; + /** + * 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; - return circle; -}; + BaseSoundManager.call(this, game); + }, -module.exports = Offset; + /** + * 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); -/***/ }), -/* 1200 */ -/***/ (function(module, exports) { + return sound; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -/** - * Offsets the Circle by the values given in the `x` and `y` properties of the Point object. - * - * @function Phaser.Geom.Circle.OffsetPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Circle} O - [circle,$return] - * - * @param {Phaser.Geom.Circle} circle - The Circle to be offset (translated.) - * @param {(Phaser.Geom.Point|object)} point - The Point object containing the values to offset the Circle by. - * - * @return {Phaser.Geom.Circle} The Circle that was offset. - */ -var OffsetPoint = function (circle, point) -{ - circle.x += point.x; - circle.y += point.y; + var _this = this; - return circle; -}; + 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; -module.exports = OffsetPoint; + return false; + } + } + return true; + }); -/***/ }), -/* 1201 */ -/***/ (function(module, exports, __webpack_require__) { + if (!this.locked) + { + return; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var moved = false; -var Ellipse = __webpack_require__(111); + var detectMove = function () + { + moved = true; + }; -Ellipse.Area = __webpack_require__(1202); -Ellipse.Circumference = __webpack_require__(447); -Ellipse.CircumferencePoint = __webpack_require__(218); -Ellipse.Clone = __webpack_require__(1203); -Ellipse.Contains = __webpack_require__(112); -Ellipse.ContainsPoint = __webpack_require__(1204); -Ellipse.ContainsRect = __webpack_require__(1205); -Ellipse.CopyFrom = __webpack_require__(1206); -Ellipse.Equals = __webpack_require__(1207); -Ellipse.GetBounds = __webpack_require__(1208); -Ellipse.GetPoint = __webpack_require__(445); -Ellipse.GetPoints = __webpack_require__(446); -Ellipse.Offset = __webpack_require__(1209); -Ellipse.OffsetPoint = __webpack_require__(1210); -Ellipse.Random = __webpack_require__(180); + var unlock = function () + { + if (moved) + { + moved = false; + return; + } -module.exports = Ellipse; + document.body.removeEventListener('touchmove', detectMove); + document.body.removeEventListener('touchend', unlock); + var lockedTags = []; -/***/ }), -/* 1202 */ -/***/ (function(module, exports) { + _this.game.cache.audio.entries.each(function (key, tags) + { + for (var i = 0; i < tags.length; i++) + { + var tag = tags[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (tag.dataset.locked === 'true') + { + lockedTags.push(tag); + } + } -/** - * Calculates the area of the Ellipse. - * - * @function Phaser.Geom.Ellipse.Area - * @since 3.0.0 - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the area of. - * - * @return {number} The area of the Ellipse. - */ -var Area = function (ellipse) -{ - if (ellipse.isEmpty()) - { - return 0; - } + return true; + }); - // units squared - return (ellipse.getMajorRadius() * ellipse.getMinorRadius() * Math.PI); -}; + if (lockedTags.length === 0) + { + return; + } -module.exports = Area; + var lastTag = lockedTags[lockedTags.length - 1]; + lastTag.oncanplaythrough = function () + { + lastTag.oncanplaythrough = null; -/***/ }), -/* 1203 */ -/***/ (function(module, exports, __webpack_require__) { + lockedTags.forEach(function (tag) + { + tag.dataset.locked = 'false'; + }); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + _this.unlocked = true; + }; -var Ellipse = __webpack_require__(111); + lockedTags.forEach(function (tag) + { + tag.load(); + }); + }; -/** - * Creates a new Ellipse instance based on the values contained in the given source. - * - * @function Phaser.Geom.Ellipse.Clone - * @since 3.0.0 - * - * @param {Phaser.Geom.Ellipse} source - The Ellipse to be cloned. Can be an instance of an Ellipse or a ellipse-like object, with x, y, width and height properties. - * - * @return {Phaser.Geom.Ellipse} A clone of the source Ellipse. - */ -var Clone = function (source) -{ - return new Ellipse(source.x, source.y, source.width, source.height); -}; + this.once(Events.UNLOCKED, function () + { + this.forEachActiveSound(function (sound) + { + if (sound.currentMarker === null && sound.duration === 0) + { + sound.duration = sound.tags[0].duration; + } -module.exports = Clone; + sound.totalDuration = sound.tags[0].duration; + }); + while (this.lockedActionsQueue.length) + { + var lockedAction = this.lockedActionsQueue.shift(); -/***/ }), -/* 1204 */ -/***/ (function(module, exports, __webpack_require__) { + if (lockedAction.sound[lockedAction.prop].apply) + { + lockedAction.sound[lockedAction.prop].apply(lockedAction.sound, lockedAction.value || []); + } + else + { + lockedAction.sound[lockedAction.prop] = lockedAction.value; + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + }, this); -var Contains = __webpack_require__(112); + document.body.addEventListener('touchmove', detectMove, false); + document.body.addEventListener('touchend', unlock, false); + }, -/** - * Check to see if the Ellipse contains the given Point object. - * - * @function Phaser.Geom.Ellipse.ContainsPoint - * @since 3.0.0 - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to check. - * @param {(Phaser.Geom.Point|object)} point - The Point object to check if it's within the Circle or not. - * - * @return {boolean} True if the Point coordinates are within the circle, otherwise false. - */ -var ContainsPoint = function (ellipse, point) -{ - return Contains(ellipse, point.x, point.y); -}; + /** + * 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(); + } + }); + }, -module.exports = ContainsPoint; + /** + * 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; + }, -/***/ }), -/* 1205 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.onBlurPausedSounds.length = 0; + this.onBlurPausedSounds = null; + }, -var Contains = __webpack_require__(112); + /** + * 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 + }); -/** - * Check to see if the Ellipse contains all four points of the given Rectangle object. - * - * @function Phaser.Geom.Ellipse.ContainsRect - * @since 3.0.0 - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to check. - * @param {(Phaser.Geom.Rectangle|object)} rect - The Rectangle object to check if it's within the Ellipse or not. - * - * @return {boolean} True if all of the Rectangle coordinates are within the ellipse, otherwise false. - */ -var ContainsRect = function (ellipse, rect) -{ - return ( - Contains(ellipse, rect.x, rect.y) && - Contains(ellipse, rect.right, rect.y) && - Contains(ellipse, rect.x, rect.bottom) && - Contains(ellipse, rect.right, rect.bottom) - ); -}; + return true; + } -module.exports = ContainsRect; + 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; -/***/ }), -/* 1206 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * @name Phaser.Sound.HTML5AudioSoundManager#mute + * @type {boolean} + * @fires Phaser.Sound.Events#GLOBAL_MUTE + * @since 3.0.0 + */ + mute: { -/** - * Copies the `x`, `y`, `width` and `height` properties from the `source` Ellipse - * into the given `dest` Ellipse, then returns the `dest` Ellipse. - * - * @function Phaser.Geom.Ellipse.CopyFrom - * @since 3.0.0 - * - * @generic {Phaser.Geom.Ellipse} O - [dest,$return] - * - * @param {Phaser.Geom.Ellipse} source - The source Ellipse to copy the values from. - * @param {Phaser.Geom.Ellipse} dest - The destination Ellipse to copy the values to. - * - * @return {Phaser.Geom.Ellipse} The destination Ellipse. - */ -var CopyFrom = function (source, dest) -{ - return dest.setTo(source.x, source.y, source.width, source.height); -}; + get: function () + { + return this._mute; + }, -module.exports = CopyFrom; + set: function (value) + { + this._mute = value; + this.forEachActiveSound(function (sound) + { + sound.updateMute(); + }); -/***/ }), -/* 1207 */ -/***/ (function(module, exports) { + this.emit(Events.GLOBAL_MUTE, this, value); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + }, -/** - * Compares the `x`, `y`, `width` and `height` properties of the two given Ellipses. - * Returns `true` if they all match, otherwise returns `false`. - * - * @function Phaser.Geom.Ellipse.Equals - * @since 3.0.0 - * - * @param {Phaser.Geom.Ellipse} ellipse - The first Ellipse to compare. - * @param {Phaser.Geom.Ellipse} toCompare - The second Ellipse to compare. - * - * @return {boolean} `true` if the two Ellipse equal each other, otherwise `false`. - */ -var Equals = function (ellipse, toCompare) -{ - return ( - ellipse.x === toCompare.x && - ellipse.y === toCompare.y && - ellipse.width === toCompare.width && - ellipse.height === toCompare.height - ); -}; + /** + * 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; -module.exports = Equals; + return this; + }, + /** + * @name Phaser.Sound.HTML5AudioSoundManager#volume + * @type {number} + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.0.0 + */ + volume: { -/***/ }), -/* 1208 */ -/***/ (function(module, exports, __webpack_require__) { + get: function () + { + return this._volume; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + set: function (value) + { + this._volume = value; -var Rectangle = __webpack_require__(10); + this.forEachActiveSound(function (sound) + { + sound.updateVolume(); + }); -/** - * Returns the bounds of the Ellipse object. - * - * @function Phaser.Geom.Ellipse.GetBounds - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [out,$return] - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to get the bounds from. - * @param {(Phaser.Geom.Rectangle|object)} [out] - A Rectangle, or rectangle-like object, to store the ellipse bounds in. If not given a new Rectangle will be created. - * - * @return {(Phaser.Geom.Rectangle|object)} The Rectangle object containing the Ellipse bounds. - */ -var GetBounds = function (ellipse, out) -{ - if (out === undefined) { out = new Rectangle(); } + this.emit(Events.GLOBAL_VOLUME, this, value); + } - out.x = ellipse.left; - out.y = ellipse.top; - out.width = ellipse.width; - out.height = ellipse.height; + } - return out; -}; +}); -module.exports = GetBounds; +module.exports = HTML5AudioSoundManager; /***/ }), -/* 1209 */ -/***/ (function(module, exports) { + +/***/ 56751: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Offsets the Ellipse by the values given. - * - * @function Phaser.Geom.Ellipse.Offset - * @since 3.0.0 - * - * @generic {Phaser.Geom.Ellipse} O - [ellipse,$return] - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to be offset (translated.) - * @param {number} x - The amount to horizontally offset the Ellipse by. - * @param {number} y - The amount to vertically offset the Ellipse by. - * - * @return {Phaser.Geom.Ellipse} The Ellipse that was offset. + * @namespace Phaser.Sound */ -var Offset = function (ellipse, x, y) -{ - ellipse.x += x; - ellipse.y += y; - return ellipse; -}; +module.exports = { -module.exports = Offset; + SoundManagerCreator: __webpack_require__(84191), + Events: __webpack_require__(76038), -/***/ }), -/* 1210 */ -/***/ (function(module, exports) { + BaseSound: __webpack_require__(25798), + BaseSoundManager: __webpack_require__(12486), -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + WebAudioSound: __webpack_require__(96008), + WebAudioSoundManager: __webpack_require__(55491), -/** - * Offsets the Ellipse by the values given in the `x` and `y` properties of the Point object. - * - * @function Phaser.Geom.Ellipse.OffsetPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Ellipse} O - [ellipse,$return] - * - * @param {Phaser.Geom.Ellipse} ellipse - The Ellipse to be offset (translated.) - * @param {(Phaser.Geom.Point|object)} point - The Point object containing the values to offset the Ellipse by. - * - * @return {Phaser.Geom.Ellipse} The Ellipse that was offset. - */ -var OffsetPoint = function (ellipse, point) -{ - ellipse.x += point.x; - ellipse.y += point.y; + HTML5AudioSound: __webpack_require__(34350), + HTML5AudioSoundManager: __webpack_require__(27622), - return ellipse; -}; + NoAudioSound: __webpack_require__(38662), + NoAudioSoundManager: __webpack_require__(17546) -module.exports = OffsetPoint; +}; /***/ }), -/* 1211 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 38662: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Point = __webpack_require__(4); -var CircleToCircle = __webpack_require__(231); +var BaseSound = __webpack_require__(25798); +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var Extend = __webpack_require__(98611); +var NOOP = __webpack_require__(72283); + +var returnFalse = function () +{ + return false; +}; + +var returnNull = function () +{ + return null; +}; + +var returnThis = function () +{ + return this; +}; /** - * Checks if two Circles intersect and returns the intersection points as a Point object array. + * @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. * - * @function Phaser.Geom.Intersects.GetCircleToCircle - * @since 3.0.0 + * 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. * - * @param {Phaser.Geom.Circle} circleA - The first Circle to check for intersection. - * @param {Phaser.Geom.Circle} circleB - The second Circle to check for intersection. - * @param {array} [out] - An optional array in which to store the points of intersection. + * @class NoAudioSound + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 * - * @return {array} An array with the points of intersection if objects intersect, otherwise an empty array. + * @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 GetCircleToCircle = function (circleA, circleB, out) -{ - if (out === undefined) { out = []; } - - if (CircleToCircle(circleA, circleB)) - { - var x0 = circleA.x; - var y0 = circleA.y; - var r0 = circleA.radius; - - var x1 = circleB.x; - var y1 = circleB.y; - var r1 = circleB.radius; - - var coefficientA, coefficientB, coefficientC, lambda, x; - - if (y0 === y1) - { - x = ((r1 * r1) - (r0 * r0) - (x1 * x1) + (x0 * x0)) / (2 * (x0 - x1)); +var NoAudioSound = new Class({ - coefficientA = 1; - coefficientB = -2 * y1; - coefficientC = (x1 * x1) + (x * x) - (2 * x1 * x) + (y1 * y1) - (r1 * r1); + Extends: EventEmitter, - lambda = (coefficientB * coefficientB) - (4 * coefficientA * coefficientC); + initialize: - if (lambda === 0) - { - out.push(new Point(x, (-coefficientB / (2 * coefficientA)))); - } - else if (lambda > 0) - { - out.push(new Point(x, (-coefficientB + Math.sqrt(lambda)) / (2 * coefficientA))); - out.push(new Point(x, (-coefficientB - Math.sqrt(lambda)) / (2 * coefficientA))); - } - } - else - { - var v1 = (x0 - x1) / (y0 - y1); - var n = (r1 * r1 - r0 * r0 - x1 * x1 + x0 * x0 - y1 * y1 + y0 * y0) / (2 * (y0 - y1)); + function NoAudioSound (manager, key, config) + { + if (config === void 0) { config = {}; } - coefficientA = (v1 * v1) + 1; - coefficientB = (2 * y0 * v1) - (2 * n * v1) - (2 * x0); - coefficientC = (x0 * x0) + (y0 * y0) + (n * n) - (r0 * r0) - (2 * y0 * n); + EventEmitter.call(this); - lambda = (coefficientB * coefficientB) - (4 * coefficientA * coefficientC); + /** + * Local reference to the sound manager. + * + * @name Phaser.Sound.NoAudioSound#manager + * @type {Phaser.Sound.BaseSoundManager} + * @since 3.0.0 + */ + this.manager = manager; - if (lambda === 0) - { - x = (-coefficientB / (2 * coefficientA)); - out.push(new Point(x, (n - (x * v1)))); - } - else if (lambda > 0) - { - x = (-coefficientB + Math.sqrt(lambda)) / (2 * coefficientA); - out.push(new Point(x, (n - (x * v1)))); - x = (-coefficientB - Math.sqrt(lambda)) / (2 * coefficientA); - out.push(new Point(x, (n - (x * v1)))); - } - } - } + /** + * Asset key for the sound. + * + * @name Phaser.Sound.NoAudioSound#key + * @type {string} + * @readonly + * @since 3.0.0 + */ + this.key = key; - return out; -}; + /** + * Flag indicating if sound is currently playing. + * + * @name Phaser.Sound.NoAudioSound#isPlaying + * @type {boolean} + * @default false + * @readonly + * @since 3.0.0 + */ + this.isPlaying = false; -module.exports = GetCircleToCircle; + /** + * Flag indicating if sound is currently paused. + * + * @name Phaser.Sound.NoAudioSound#isPaused + * @type {boolean} + * @default false + * @readonly + * @since 3.0.0 + */ + this.isPaused = false; + /** + * A property that holds the value of sound's actual playback rate, + * after its rate and detune values has been combined with global + * rate and detune values. + * + * @name Phaser.Sound.NoAudioSound#totalRate + * @type {number} + * @default 1 + * @readonly + * @since 3.0.0 + */ + this.totalRate = 1; -/***/ }), -/* 1212 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * A value representing the duration, in seconds. + * It could be total sound duration or a marker duration. + * + * @name Phaser.Sound.NoAudioSound#duration + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.duration = 0; -/** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The total duration of the sound in seconds. + * + * @name Phaser.Sound.NoAudioSound#totalDuration + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.totalDuration = 0; -var GetLineToCircle = __webpack_require__(232); -var CircleToRectangle = __webpack_require__(151); + /** + * A config object used to store default sound settings' values. + * Default values will be set by properties' setters. + * + * @name Phaser.Sound.NoAudioSound#config + * @type {Phaser.Types.Sound.SoundConfig} + * @since 3.0.0 + */ + this.config = Extend({ + mute: false, + volume: 1, + rate: 1, + detune: 0, + seek: 0, + loop: false, + delay: 0, + pan: 0 + }, config); -/** - * Checks for intersection between a circle and a rectangle, - * and returns the intersection points as a Point object array. - * - * @function Phaser.Geom.Intersects.GetCircleToRectangle - * @since 3.0.0 - * - * @param {Phaser.Geom.Circle} circle - The circle to be checked. - * @param {Phaser.Geom.Rectangle} rect - The rectangle to be checked. - * @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 GetCircleToRectangle = function (circle, rect, out) -{ - if (out === undefined) { out = []; } + /** + * Reference to the currently used config. + * It could be default config or marker config. + * + * @name Phaser.Sound.NoAudioSound#currentConfig + * @type {Phaser.Types.Sound.SoundConfig} + * @since 3.0.0 + */ + this.currentConfig = this.config; - if (CircleToRectangle(circle, rect)) - { - var lineA = rect.getLineA(); - var lineB = rect.getLineB(); - var lineC = rect.getLineC(); - var lineD = rect.getLineD(); + /** + * Boolean indicating whether the sound is muted or not. + * Gets or sets the muted state of this sound. + * + * @name Phaser.Sound.NoAudioSound#mute + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#MUTE + * @since 3.0.0 + */ + this.mute = false; - GetLineToCircle(lineA, circle, out); - GetLineToCircle(lineB, circle, out); - GetLineToCircle(lineC, circle, out); - GetLineToCircle(lineD, circle, out); - } + /** + * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). + * + * @name Phaser.Sound.NoAudioSound#volume + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#VOLUME + * @since 3.0.0 + */ + this.volume = 1; - return out; -}; + /** + * 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.NoAudioSound#rate + * @type {number} + * @default 1 + * @fires Phaser.Sound.Events#RATE + * @since 3.0.0 + */ + this.rate = 1; -module.exports = GetCircleToRectangle; + /** + * 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.NoAudioSound#detune + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#DETUNE + * @since 3.0.0 + */ + this.detune = 0; + /** + * 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.NoAudioSound#seek + * @type {number} + * @fires Phaser.Sound.Events#SEEK + * @since 3.0.0 + */ + this.seek = 0; -/***/ }), -/* 1213 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Flag indicating whether or not the sound or current sound marker will loop. + * + * @name Phaser.Sound.NoAudioSound#loop + * @type {boolean} + * @default false + * @fires Phaser.Sound.Events#LOOP + * @since 3.0.0 + */ + this.loop = false; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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.NoAudioSound#pan + * @type {number} + * @default 0 + * @fires Phaser.Sound.Events#PAN + * @since 3.50.0 + */ + this.pan = 0; -var Vector4 = __webpack_require__(140); -var GetLineToPolygon = __webpack_require__(487); -var Line = __webpack_require__(47); + /** + * Object containing markers definitions. + * + * @name Phaser.Sound.NoAudioSound#markers + * @type {Object.} + * @default {} + * @readonly + * @since 3.0.0 + */ + this.markers = {}; -// Temp calculation segment -var segment = new Line(); + /** + * Currently playing marker. + * 'null' if whole sound is playing. + * + * @name Phaser.Sound.NoAudioSound#currentMarker + * @type {Phaser.Types.Sound.SoundMarker} + * @default null + * @readonly + * @since 3.0.0 + */ + this.currentMarker = null; -/** - * @ignore - */ -function CheckIntersects (angle, x, y, polygons, intersects) -{ - var dx = Math.cos(angle); - var dy = Math.sin(angle); + /** + * Flag indicating if destroy method was called on this sound. + * + * @name Phaser.Sound.NoAudioSound#pendingRemove + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.pendingRemove = false; + }, - segment.setTo(x, y, x + dx, y + dy); + /** + * @method Phaser.Sound.NoAudioSound#addMarker + * @since 3.0.0 + * + * @param {Phaser.Types.Sound.SoundMarker} marker - Marker object. + * + * @return {boolean} false + */ + addMarker: returnFalse, - var closestIntersect = GetLineToPolygon(segment, polygons); + /** + * @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, - if (closestIntersect) - { - intersects.push(new Vector4(closestIntersect.x, closestIntersect.y, angle, closestIntersect.w)); - } -} + /** + * @method Phaser.Sound.NoAudioSound#removeMarker + * @since 3.0.0 + * + * @param {string} markerName - The name of the marker to remove. + * + * @return {null} null + */ + removeMarker: returnNull, -/** - * @ignore - */ -function SortIntersects (a, b) -{ - return a.z - b.z; -} + /** + * @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, -/** - * Projects rays out from the given point to each line segment of the polygons. - * - * If the rays intersect with the polygons, the points of intersection are returned in an array. - * - * If no intersections are found, the returned array will be empty. - * - * Each Vector4 intersection result has the following properties: - * - * The `x` and `y` components contain the point of the intersection. - * The `z` component contains the angle of intersection. - * The `w` component contains the index of the polygon, in the given array, that triggered the intersection. - * - * @function Phaser.Geom.Intersects.GetRaysFromPointToPolygon - * @since 3.50.0 - * - * @param {number} x - The x coordinate to project the rays from. - * @param {number} y - The y coordinate to project the rays from. - * @param {Phaser.Geom.Polygon | Phaser.Geom.Polygon[]} polygons - A single polygon, or array of polygons, to check against the rays. - * - * @return {Phaser.Math.Vector4[]} An array containing all intersections in Vector4s. - */ -var GetRaysFromPointToPolygon = function (x, y, polygons) -{ - if (!Array.isArray(polygons)) - { - polygons = [ polygons ]; - } + /** + * @method Phaser.Sound.NoAudioSound#pause + * @since 3.0.0 + * + * @return {boolean} false + */ + pause: returnFalse, - var intersects = []; - var angles = []; + /** + * Resumes the sound. + * + * @method Phaser.Sound.NoAudioSound#resume + * @since 3.0.0 + * + * @return {boolean} false + */ + resume: returnFalse, - for (var i = 0; i < polygons.length; i++) - { - var points = polygons[i].points; + /** + * Stop playing this sound. + * + * @method Phaser.Sound.NoAudioSound#stop + * @since 3.0.0 + * + * @return {boolean} false + */ + stop: returnFalse, - for (var p = 0; p < points.length; p++) - { - var angle = Math.atan2(points[p].y - y, points[p].x - x); + /** + * Sets the muted state of this Sound. + * + * @method Phaser.Sound.NoAudioSound#setMute + * @since 3.4.0 + * + * @param {boolean} value - `true` to mute this sound, `false` to unmute it. + * + * @return {this} This Sound instance. + */ + setMute: returnThis, - if (angles.indexOf(angle) === -1) - { - // +- 0.00001 rads to catch lines behind segment corners + /** + * Sets the volume of this Sound. + * + * @method Phaser.Sound.NoAudioSound#setVolume + * @since 3.4.0 + * + * @param {number} value - The volume of the sound. + * + * @return {this} This Sound instance. + */ + setVolume: returnThis, - CheckIntersects(angle, x, y, polygons, intersects); - CheckIntersects(angle - 0.00001, x, y, polygons, intersects); - CheckIntersects(angle + 0.00001, x, y, polygons, intersects); + /** + * 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.NoAudioSound#setRate + * @since 3.3.0 + * + * @param {number} value - The playback rate at of this Sound. + * + * @return {this} This Sound instance. + */ + setRate: returnThis, - angles.push(angle); - } - } - } + /** + * 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.NoAudioSound#setDetune + * @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: returnThis, - return intersects.sort(SortIntersects); -}; + /** + * Seeks to a specific point in this sound. + * + * @method Phaser.Sound.NoAudioSound#setSeek + * @since 3.4.0 + * + * @param {number} value - The point in the sound to seek to. + * + * @return {this} This Sound instance. + */ + setSeek: returnThis, -module.exports = GetRaysFromPointToPolygon; + /** + * Sets the loop state of this Sound. + * + * @method Phaser.Sound.NoAudioSound#setLoop + * @since 3.4.0 + * + * @param {boolean} value - `true` to loop this sound, `false` to not loop it. + * + * @return {this} This Sound instance. + */ + setLoop: returnThis, + /** + * 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.NoAudioSound#setPan + * @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: returnThis, -/***/ }), -/* 1214 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Method used internally for applying config values to some of the sound properties. + * + * @method Phaser.Sound.NoAudioSound#applyConfig + * @since 3.0.0 + */ + applyConfig: returnNull, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Method used internally for resetting values of some of the config properties. + * + * @method Phaser.Sound.NoAudioSound#resetConfig + * @since 3.0.0 + */ + resetConfig: returnNull, -var Rectangle = __webpack_require__(10); -var RectangleToRectangle = __webpack_require__(152); + /** + * Update method called automatically by sound manager on every game step. + * + * @method Phaser.Sound.NoAudioSound#update + * @override + * @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 elapsed since the last frame. + */ + update: NOOP, -/** - * Checks if two Rectangle shapes intersect and returns the area of this intersection as Rectangle object. - * - * If optional `output` parameter is omitted, new Rectangle object is created and returned. If there is intersection, it will contain intersection area. If there is no intersection, it wil be empty Rectangle (all values set to zero). - * - * If Rectangle object is passed as `output` and there is intersection, then intersection area data will be loaded into it and it will be returned. If there is no intersection, it will be returned without any change. - * - * @function Phaser.Geom.Intersects.GetRectangleIntersection - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [output,$return] - * - * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle object. - * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle object. - * @param {Phaser.Geom.Rectangle} [output] - Optional Rectangle object. If given, the intersection data will be loaded into it (in case of no intersection, it will be left unchanged). Otherwise, new Rectangle object will be created and returned with either intersection data or empty (all values set to zero), if there is no intersection. - * - * @return {Phaser.Geom.Rectangle} A rectangle object with intersection data. - */ -var GetRectangleIntersection = function (rectA, rectB, output) -{ - if (output === undefined) { output = new Rectangle(); } + /** + * Method used internally to calculate total playback rate of the sound. + * + * @method Phaser.Sound.NoAudioSound#calculateRate + * @since 3.0.0 + */ + calculateRate: returnNull, - if (RectangleToRectangle(rectA, rectB)) + /** + * 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 () { - output.x = Math.max(rectA.x, rectB.x); - output.y = Math.max(rectA.y, rectB.y); - output.width = Math.min(rectA.right, rectB.right) - output.x; - output.height = Math.min(rectA.bottom, rectB.bottom) - output.y; + BaseSound.prototype.destroy.call(this); } - return output; -}; +}); -module.exports = GetRectangleIntersection; +module.exports = NoAudioSound; /***/ }), -/* 1215 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 17546: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. + * @author Richard Davey + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetLineToRectangle = __webpack_require__(234); -var RectangleToRectangle = __webpack_require__(152); +var BaseSoundManager = __webpack_require__(12486); +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var NoAudioSound = __webpack_require__(38662); +var NOOP = __webpack_require__(72283); /** - * Checks if two Rectangles intersect and returns the intersection points as a Point object array. + * @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. * - * A Rectangle intersects another Rectangle if any part of its bounds is within the other Rectangle's bounds. As such, the two Rectangles are considered "solid". A Rectangle with no width or no height will never intersect another Rectangle. + * 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. * - * @function Phaser.Geom.Intersects.GetRectangleToRectangle + * @class NoAudioSoundManager + * @extends Phaser.Sound.BaseSoundManager + * @memberof Phaser.Sound + * @constructor * @since 3.0.0 * - * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to check for intersection. - * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to check for intersection. - * @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. + * @param {Phaser.Game} game - Reference to the current game instance. */ -var GetRectangleToRectangle = function (rectA, rectB, out) -{ - if (out === undefined) { out = []; } - - if (RectangleToRectangle(rectA, rectB)) - { - var lineA = rectA.getLineA(); - var lineB = rectA.getLineB(); - var lineC = rectA.getLineC(); - var lineD = rectA.getLineD(); - - GetLineToRectangle(lineA, rectB, out); - GetLineToRectangle(lineB, rectB, out); - GetLineToRectangle(lineC, rectB, out); - GetLineToRectangle(lineD, rectB, out); - } +var NoAudioSoundManager = new Class({ - return out; -}; + Extends: EventEmitter, -module.exports = GetRectangleToRectangle; + initialize: + function NoAudioSoundManager (game) + { + EventEmitter.call(this); -/***/ }), -/* 1216 */ -/***/ (function(module, exports, __webpack_require__) { + this.game = game; + this.sounds = []; + this.mute = false; + this.volume = 1; + this.rate = 1; + this.detune = 0; + this.pauseOnBlur = true; + this.locked = false; + }, -/** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Adds a new sound into the sound manager. + * + * @method Phaser.Sound.NoAudioSoundManager#add + * @since 3.60.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.NoAudioSound} The new sound instance. + */ + add: function (key, config) + { + var sound = new NoAudioSound(this, key, config); -var RectangleToTriangle = __webpack_require__(489); -var GetLineToRectangle = __webpack_require__(234); + this.sounds.push(sound); -/** - * Checks for intersection between Rectangle shape and Triangle shape, - * and returns the intersection points as a Point object array. - * - * @function Phaser.Geom.Intersects.GetRectangleToTriangle - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rect - Rectangle object to test. - * @param {Phaser.Geom.Triangle} triangle - Triangle object to test. - * @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 GetRectangleToTriangle = function (rect, triangle, out) -{ - if (out === undefined) { out = []; } + return sound; + }, - if (RectangleToTriangle(rect, triangle)) + /** + * Adds a new audio sprite sound into the sound manager. + * Audio Sprites are a combination of audio files and a JSON configuration. + * The JSON follows the format of that created by https://github.com/tonistiigi/audiosprite + * + * @method Phaser.Sound.NoAudioSoundManager#addAudioSprite + * @since 3.60.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.NoAudioSound} The new audio sprite sound instance. + */ + addAudioSprite: function (key, config) { - var lineA = triangle.getLineA(); - var lineB = triangle.getLineB(); - var lineC = triangle.getLineC(); - - GetLineToRectangle(lineA, rect, out); - GetLineToRectangle(lineB, rect, out); - GetLineToRectangle(lineC, rect, out); - } - - return out; -}; + var sound = this.add(key, config); -module.exports = GetRectangleToTriangle; + sound.spritemap = {}; + return sound; + }, -/***/ }), -/* 1217 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Gets the first sound in the manager matching the given key, if any. + * + * @method Phaser.Sound.NoAudioSoundManager#get + * @since 3.23.0 + * + * @generic {Phaser.Sound.BaseSound} T + * @genericUse {T} - [$return] + * + * @param {string} key - Sound asset key. + * + * @return {?Phaser.Sound.BaseSound} - The sound, or null. + */ + get: function (key) + { + return BaseSoundManager.prototype.get.call(this, key); + }, -/** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Gets any sounds in the manager matching the given key. + * + * @method Phaser.Sound.NoAudioSoundManager#getAll + * @since 3.23.0 + * + * @generic {Phaser.Sound.BaseSound} T + * @genericUse {T[]} - [$return] + * + * @param {string} key - Sound asset key. + * + * @return {Phaser.Sound.BaseSound[]} - The sounds, or an empty array. + */ + getAll: function (key) + { + return BaseSoundManager.prototype.getAll.call(this, key); + }, -var GetLineToCircle = __webpack_require__(232); -var TriangleToCircle = __webpack_require__(491); + /** + * This method does nothing but return 'false' for the No Audio Sound Manager, to maintain + * compatibility with the other Sound Managers. + * + * @method Phaser.Sound.NoAudioSoundManager#play + * @since 3.0.0 + * + * @param {string} key - Asset key for the sound. + * @param {(Phaser.Types.Sound.SoundConfig|Phaser.Types.Sound.SoundMarker)} [extra] - An optional additional object containing settings to be applied to the sound. It could be either config or marker object. + * + * @return {boolean} Always 'false' for the No Audio Sound Manager. + */ + // eslint-disable-next-line no-unused-vars + play: function (key, extra) + { + return false; + }, -/** - * Checks if a Triangle and a Circle intersect, and returns the intersection points as a Point object array. - * - * 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.GetTriangleToCircle - * @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. - * @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 GetTriangleToCircle = function (triangle, circle, out) -{ - if (out === undefined) { out = []; } + /** + * This method does nothing but return 'false' for the No Audio Sound Manager, to maintain + * compatibility with the other Sound Managers. + * + * @method Phaser.Sound.NoAudioSoundManager#playAudioSprite + * @since 3.0.0 + * + * @param {string} key - Asset key for the sound. + * @param {string} spriteName - The name of the sound sprite to play. + * @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings. + * + * @return {boolean} Always 'false' for the No Audio Sound Manager. + */ + // eslint-disable-next-line no-unused-vars + playAudioSprite: function (key, spriteName, config) + { + return false; + }, - if (TriangleToCircle(triangle, circle)) + /** + * Removes a sound from the sound manager. + * The removed sound is destroyed before removal. + * + * @method Phaser.Sound.NoAudioSoundManager#remove + * @since 3.0.0 + * + * @param {Phaser.Sound.BaseSound} sound - The sound object to remove. + * + * @return {boolean} True if the sound was removed successfully, otherwise false. + */ + remove: function (sound) { - var lineA = triangle.getLineA(); - var lineB = triangle.getLineB(); - var lineC = triangle.getLineC(); + return BaseSoundManager.prototype.remove.call(this, sound); + }, - GetLineToCircle(lineA, circle, out); - GetLineToCircle(lineB, circle, out); - GetLineToCircle(lineC, circle, out); - } + /** + * Removes all sounds from the manager, destroying the sounds. + * + * @method Phaser.Sound.NoAudioSoundManager#removeAll + * @since 3.23.0 + */ + removeAll: function () + { + return BaseSoundManager.prototype.removeAll.call(this); + }, - return out; -}; + /** + * Removes all sounds from the sound manager that have an asset key matching the given value. + * The removed sounds are destroyed before removal. + * + * @method Phaser.Sound.NoAudioSoundManager#removeByKey + * @since 3.0.0 + * + * @param {string} key - The key to match when removing sound objects. + * + * @return {number} The number of matching sound objects that were removed. + */ + removeByKey: function (key) + { + return BaseSoundManager.prototype.removeByKey.call(this, key); + }, -module.exports = GetTriangleToCircle; + /** + * Stops any sounds matching the given key. + * + * @method Phaser.Sound.NoAudioSoundManager#stopByKey + * @since 3.23.0 + * + * @param {string} key - Sound asset key. + * + * @return {number} - How many sounds were stopped. + */ + stopByKey: function (key) + { + return BaseSoundManager.prototype.stopByKey.call(this, key); + }, + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#onBlur + * @since 3.0.0 + */ + onBlur: NOOP, -/***/ }), -/* 1218 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#onFocus + * @since 3.0.0 + */ + onFocus: NOOP, -/** - * @author Florian Vazelle - * @author Geoffrey Glaive - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#onGameBlur + * @since 3.0.0 + */ + onGameBlur: NOOP, -var TriangleToTriangle = __webpack_require__(494); -var GetTriangleToLine = __webpack_require__(492); + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#onGameFocus + * @since 3.0.0 + */ + onGameFocus: NOOP, -/** - * Checks if two Triangles intersect, and returns the intersection points as a Point object array. - * - * 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.GetTriangleToTriangle - * @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. - * @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 GetTriangleToTriangle = function (triangleA, triangleB, out) -{ - if (out === undefined) { out = []; } + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#pauseAll + * @since 3.0.0 + */ + pauseAll: NOOP, - if (TriangleToTriangle(triangleA, triangleB)) - { - var lineA = triangleB.getLineA(); - var lineB = triangleB.getLineB(); - var lineC = triangleB.getLineC(); + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#resumeAll + * @since 3.0.0 + */ + resumeAll: NOOP, - GetTriangleToLine(triangleA, lineA, out); - GetTriangleToLine(triangleA, lineB, out); - GetTriangleToLine(triangleA, lineC, out); - } + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#stopAll + * @since 3.0.0 + */ + stopAll: NOOP, - return out; -}; + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#update + * @since 3.0.0 + */ + update: NOOP, -module.exports = GetTriangleToTriangle; + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#setRate + * @since 3.0.0 + * + * @return {this} This Sound Manager. + */ + setRate: NOOP, + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#setDetune + * @since 3.0.0 + * + * @return {this} This Sound Manager. + */ + setDetune: NOOP, -/***/ }), -/* 1219 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#setMute + * @since 3.0.0 + */ + setMute: NOOP, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#setVolume + * @since 3.0.0 + */ + setVolume: NOOP, -var PointToLine = __webpack_require__(496); + /** + * Empty function for the No Audio Sound Manager. + * + * @method Phaser.Sound.NoAudioSoundManager#unlock + * @since 3.0.0 + */ + unlock: NOOP, -/** - * Checks if a Point is located on the given line segment. - * - * @function Phaser.Geom.Intersects.PointToLineSegment - * @since 3.0.0 - * - * @param {Phaser.Geom.Point} point - The Point to check for intersection. - * @param {Phaser.Geom.Line} line - The line segment to check for intersection. - * - * @return {boolean} `true` if the Point is on the given line segment, otherwise `false`. - */ -var PointToLineSegment = function (point, line) -{ - if (!PointToLine(point, line)) + /** + * Method used internally for iterating only over active sounds and skipping sounds that are marked for removal. + * + * @method Phaser.Sound.NoAudioSoundManager#forEachActiveSound + * @private + * @since 3.0.0 + * + * @param {Phaser.Types.Sound.EachActiveSoundCallback} callback - Callback function. (manager: Phaser.Sound.BaseSoundManager, sound: Phaser.Sound.BaseSound, index: number, sounds: Phaser.Manager.BaseSound[]) => void + * @param {*} [scope] - Callback context. + */ + forEachActiveSound: function (callbackfn, scope) { - return false; - } + BaseSoundManager.prototype.forEachActiveSound.call(this, callbackfn, scope); + }, - var xMin = Math.min(line.x1, line.x2); - var xMax = Math.max(line.x1, line.x2); - var yMin = Math.min(line.y1, line.y2); - var yMax = Math.max(line.y1, line.y2); + /** + * Destroys all the sounds in the game and all associated events. + * + * @method Phaser.Sound.NoAudioSoundManager#destroy + * @since 3.0.0 + */ + destroy: function () + { + BaseSoundManager.prototype.destroy.call(this); + } - return ((point.x >= xMin && point.x <= xMax) && (point.y >= yMin && point.y <= yMax)); -}; +}); -module.exports = PointToLineSegment; +module.exports = NoAudioSoundManager; /***/ }), -/* 1220 */ -/***/ (function(module, exports) { + +/***/ 96008: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var BaseSound = __webpack_require__(25798); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(76038); +var GetFastValue = __webpack_require__(72632); + /** - * Check if rectangle intersects with values. + * @classdesc + * Web Audio API implementation of the sound. * - * @function Phaser.Geom.Intersects.RectangleToValues + * @class WebAudioSound + * @extends Phaser.Sound.BaseSound + * @memberof Phaser.Sound + * @constructor * @since 3.0.0 * - * @param {Phaser.Geom.Rectangle} rect - The rectangle object - * @param {number} left - The x coordinate of the left of the Rectangle. - * @param {number} right - The x coordinate of the right of the Rectangle. - * @param {number} top - The y coordinate of the top of the Rectangle. - * @param {number} bottom - The y coordinate of the bottom of the Rectangle. - * @param {number} [tolerance=0] - Tolerance allowed in the calculation, expressed in pixels. - * - * @return {boolean} Returns true if there is an intersection. + * @param {Phaser.Sound.WebAudioSoundManager} manager - Reference to the WebAudio Sound Manager that owns this Sound instance. + * @param {string} key - Asset key for the sound. + * @param {Phaser.Types.Sound.SoundConfig} [config={}] - An optional config object containing default sound settings. */ -var RectangleToValues = function (rect, left, right, top, bottom, tolerance) -{ - if (tolerance === undefined) { tolerance = 0; } +var WebAudioSound = new Class({ - return !( - left > rect.right + tolerance || - right < rect.left - tolerance || - top > rect.bottom + tolerance || - bottom < rect.top - tolerance - ); -}; + Extends: BaseSound, -module.exports = RectangleToValues; + initialize: + function WebAudioSound (manager, key, config) + { + if (config === undefined) { config = {}; } -/***/ }), -/* 1221 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Audio buffer containing decoded data of the audio asset to be played. + * + * @name Phaser.Sound.WebAudioSound#audioBuffer + * @type {AudioBuffer} + * @since 3.0.0 + */ + this.audioBuffer = manager.game.cache.audio.get(key); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!this.audioBuffer) + { + throw new Error('Audio key "' + key + '" missing from cache'); + } -var Line = __webpack_require__(47); + /** + * 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} + * @default null + * @since 3.0.0 + */ + this.source = null; -Line.Angle = __webpack_require__(97); -Line.BresenhamPoints = __webpack_require__(317); -Line.CenterOn = __webpack_require__(1222); -Line.Clone = __webpack_require__(1223); -Line.CopyFrom = __webpack_require__(1224); -Line.Equals = __webpack_require__(1225); -Line.Extend = __webpack_require__(1226); -Line.GetEasedPoints = __webpack_require__(1227); -Line.GetMidPoint = __webpack_require__(1228); -Line.GetNearestPoint = __webpack_require__(1229); -Line.GetNormal = __webpack_require__(1230); -Line.GetPoint = __webpack_require__(307); -Line.GetPoints = __webpack_require__(172); -Line.GetShortestDistance = __webpack_require__(1231); -Line.Height = __webpack_require__(1232); -Line.Length = __webpack_require__(67); -Line.NormalAngle = __webpack_require__(497); -Line.NormalX = __webpack_require__(1233); -Line.NormalY = __webpack_require__(1234); -Line.Offset = __webpack_require__(1235); -Line.PerpSlope = __webpack_require__(1236); -Line.Random = __webpack_require__(173); -Line.ReflectAngle = __webpack_require__(1237); -Line.Rotate = __webpack_require__(1238); -Line.RotateAroundPoint = __webpack_require__(1239); -Line.RotateAroundXY = __webpack_require__(236); -Line.SetToAngle = __webpack_require__(1240); -Line.Slope = __webpack_require__(1241); -Line.Width = __webpack_require__(1242); + /** + * A reference to a second audio source used for gapless looped playback. + * + * @name Phaser.Sound.WebAudioSound#loopSource + * @type {AudioBufferSourceNode} + * @default null + * @since 3.0.0 + */ + this.loopSource = null; -module.exports = Line; + /** + * Gain node responsible for controlling this sound's muting. + * + * @name Phaser.Sound.WebAudioSound#muteNode + * @type {GainNode} + * @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} + * @since 3.0.0 + */ + this.volumeNode = manager.context.createGain(); -/***/ }), -/* 1222 */ -/***/ (function(module, exports) { + /** + * Panner node responsible for controlling this sound's pan. + * + * Doesn't work on iOS / Safari. + * + * @name Phaser.Sound.WebAudioSound#pannerNode + * @type {StereoPannerNode} + * @since 3.50.0 + */ + this.pannerNode = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The Stereo Spatial Panner node. + * + * @name Phaser.Sound.WebAudioSound#spatialNode + * @type {PannerNode} + * @since 3.60.0 + */ + this.spatialNode = null; + /** + * If the Spatial Panner node has been set to track a vector or + * Game Object, this retains a reference to it. + * + * @name Phaser.Sound.WebAudioSound#spatialSource + * @type {Phaser.Types.Math.Vector2Like} + * @since 3.60.0 + */ + this.spatialSource = null; -/** - * Center a line on the given coordinates. - * - * @function Phaser.Geom.Line.CenterOn - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The line to center. - * @param {number} x - The horizontal coordinate to center the line on. - * @param {number} y - The vertical coordinate to center the line on. - * - * @return {Phaser.Geom.Line} The centered line. - */ -var CenterOn = function (line, x, y) -{ - var tx = x - ((line.x1 + line.x2) / 2); - var ty = y - ((line.y1 + line.y2) / 2); + /** + * The time at which the sound should have started playback from the beginning. + * + * Treat this property as read-only. + * + * Based on `BaseAudioContext.currentTime` value. + * + * @name Phaser.Sound.WebAudioSound#playTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.playTime = 0; - line.x1 += tx; - line.y1 += ty; + /** + * The time at which the sound source should have actually started playback. + * + * Treat this property as read-only. + * + * Based on `BaseAudioContext.currentTime` value. + * + * @name Phaser.Sound.WebAudioSound#startTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.startTime = 0; - line.x2 += tx; - line.y2 += ty; + /** + * The time at which the sound loop source should actually start playback. + * + * Based on `BaseAudioContext.currentTime` value. + * + * @name Phaser.Sound.WebAudioSound#loopTime + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.loopTime = 0; - return line; -}; + /** + * An array where we keep track of all rate updates during playback. + * + * Treat this property as read-only. + * + * Array of object types: `{ time: number, rate: number }` + * + * @name Phaser.Sound.WebAudioSound#rateUpdates + * @type {array} + * @default [] + * @since 3.0.0 + */ + this.rateUpdates = []; -module.exports = CenterOn; + /** + * Used for keeping track when sound source playback has ended + * so its state can be updated accordingly. + * + * @name Phaser.Sound.WebAudioSound#hasEnded + * @type {boolean} + * @readonly + * @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} + * @readonly + * @default false + * @since 3.0.0 + */ + this.hasLooped = false; -/***/ }), -/* 1223 */ -/***/ (function(module, exports, __webpack_require__) { + this.muteNode.connect(this.volumeNode); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (manager.context.createPanner) + { + this.spatialNode = manager.context.createPanner(); -var Line = __webpack_require__(47); + this.volumeNode.connect(this.spatialNode); + } -/** - * Clone the given line. - * - * @function Phaser.Geom.Line.Clone - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} source - The source line to clone. - * - * @return {Phaser.Geom.Line} The cloned line. - */ -var Clone = function (source) -{ - return new Line(source.x1, source.y1, source.x2, source.y2); -}; + if (manager.context.createStereoPanner) + { + this.pannerNode = manager.context.createStereoPanner(); -module.exports = Clone; + if (manager.context.createPanner) + { + this.spatialNode.connect(this.pannerNode); + } + else + { + this.volumeNode.connect(this.pannerNode); + } + + this.pannerNode.connect(manager.destination); + } + else if (manager.context.createPanner) + { + this.spatialNode.connect(manager.destination); + } + else + { + this.volumeNode.connect(manager.destination); + } + this.duration = this.audioBuffer.duration; -/***/ }), -/* 1224 */ -/***/ (function(module, exports) { + this.totalDuration = this.audioBuffer.duration; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + BaseSound.call(this, manager, key, config); + }, -/** - * Copy the values of one line to a destination line. - * - * @function Phaser.Geom.Line.CopyFrom - * @since 3.0.0 - * - * @generic {Phaser.Geom.Line} O - [dest,$return] - * - * @param {Phaser.Geom.Line} source - The source line to copy the values from. - * @param {Phaser.Geom.Line} dest - The destination line to copy the values to. - * - * @return {Phaser.Geom.Line} The destination line. - */ -var CopyFrom = function (source, dest) -{ - return dest.setTo(source.x1, source.y1, source.x2, source.y2); -}; + /** + * 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. + * + * If you want to play the same sound simultaneously, then you need to create another instance + * of it and play that Sound. + * + * @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; + } -module.exports = CopyFrom; + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + this.stopAndRemoveBufferSource(); + this.createAndStartBufferSource(); + this.emit(Events.PLAY, this); -/***/ }), -/* 1225 */ -/***/ (function(module, exports) { + return true; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; + } -/** - * Compare two lines for strict equality. - * - * @function Phaser.Geom.Line.Equals - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The first line to compare. - * @param {Phaser.Geom.Line} toCompare - The second line to compare. - * - * @return {boolean} Whether the two lines are equal. - */ -var Equals = function (line, toCompare) -{ - return ( - line.x1 === toCompare.x1 && - line.y1 === toCompare.y1 && - line.x2 === toCompare.x2 && - line.y2 === toCompare.y2 - ); -}; + if (!BaseSound.prototype.pause.call(this)) + { + return false; + } -module.exports = Equals; + // \/\/\/ isPlaying = false, isPaused = true \/\/\/ + this.currentConfig.seek = this.getCurrentTime(); // Equivalent to setting paused time + this.stopAndRemoveBufferSource(); + this.emit(Events.PAUSE, this); -/***/ }), -/* 1226 */ -/***/ (function(module, exports, __webpack_require__) { + return true; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; + } -var Length = __webpack_require__(67); + if (!BaseSound.prototype.resume.call(this)) + { + return false; + } -/** - * Extends the start and end points of a Line by the given amounts. - * - * The amounts can be positive or negative. Positive points will increase the length of the line, - * while negative ones will decrease it. - * - * If no `right` value is provided it will extend the length of the line equally in both directions. - * - * Pass a value of zero to leave the start or end point unchanged. - * - * @function Phaser.Geom.Line.Extend - * @since 3.16.0 - * - * @param {Phaser.Geom.Line} line - The line instance to extend. - * @param {number} left - The amount to extend the start of the line by. - * @param {number} [right] - The amount to extend the end of the line by. If not given it will be set to the `left` value. - * - * @return {Phaser.Geom.Line} The modified Line instance. - */ -var Extend = function (line, left, right) -{ - if (right === undefined) { right = left; } + // \/\/\/ isPlaying = true, isPaused = false \/\/\/ + this.createAndStartBufferSource(); - var length = Length(line); + this.emit(Events.RESUME, this); - var slopX = line.x2 - line.x1; - var slopY = line.y2 - line.y1; + return true; + }, - if (left) + /** + * 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 () { - line.x1 = line.x1 - slopX / length * left; - line.y1 = line.y1 - slopY / length * left; - } + if (!BaseSound.prototype.stop.call(this)) + { + return false; + } - if (right) + // \/\/\/ 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 () { - line.x2 = line.x2 + slopX / length * right; - line.y2 = line.y2 + slopY / length * right; - } + 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; - return line; -}; + this.playTime = when - seek; + this.startTime = when; + this.source = this.createBufferSource(); -module.exports = Extend; + this.applyConfig(); + this.source.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration)); -/***/ }), -/* 1227 */ -/***/ (function(module, exports, __webpack_require__) { + this.resetConfig(); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * This method is only used internally and it creates a looping buffer source. + * + * @method Phaser.Sound.WebAudioSound#createAndStartLoopBufferSource + * @since 3.0.0 + */ + createAndStartLoopBufferSource: function () + { + var when = this.getLoopTime(); + var offset = this.currentMarker ? this.currentMarker.start : 0; + var duration = this.duration; -var DistanceBetweenPoints = __webpack_require__(352); -var GetEaseFunction = __webpack_require__(80); -var Point = __webpack_require__(4); + 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)); + }, -/** - * Returns an array of `quantity` Points where each point is taken from the given Line, - * spaced out according to the ease function specified. - * - * ```javascript - * const line = new Phaser.Geom.Line(100, 300, 700, 300); - * const points = Phaser.Geom.Line.GetEasedPoints(line, 'sine.out', 32) - * ``` - * - * In the above example, the `points` array will contain 32 points spread-out across - * the length of `line`, where the position of each point is determined by the `Sine.out` - * ease function. - * - * You can optionally provide a collinear threshold. In this case, the resulting points - * are checked against each other, and if they are `< collinearThreshold` distance apart, - * they are dropped from the results. This can help avoid lots of clustered points at - * far ends of the line with tightly-packed eases such as Quartic. Leave the value set - * to zero to skip this check. - * - * Note that if you provide a collinear threshold, the resulting array may not always - * contain `quantity` points. - * - * @function Phaser.Geom.Line.GetEasedPoints - * @since 3.23.0 - * - * @generic {Phaser.Geom.Point[]} O - [out,$return] - * - * @param {Phaser.Geom.Line} line - The Line object. - * @param {(string|function)} ease - The ease to use. This can be either a string from the EaseMap, or a custom function. - * @param {number} quantity - The number of points to return. Note that if you provide a `collinearThreshold`, the resulting array may not always contain this number of points. - * @param {number} [collinearThreshold=0] - An optional threshold. The final array is reduced so that each point is spaced out at least this distance apart. This helps reduce clustering in noisey eases. - * @param {number[]} [easeParams] - An optional array of ease parameters to go with the ease. - * - * @return {Phaser.Geom.Point[]} An array of Geom.Points containing the coordinates of the points on the line. - */ -var GetEasedPoints = function (line, ease, quantity, collinearThreshold, easeParams) -{ - if (collinearThreshold === undefined) { collinearThreshold = 0; } - if (easeParams === undefined) { easeParams = []; } + /** + * This method is only used internally and it creates a buffer source. + * + * @method Phaser.Sound.WebAudioSound#createBufferSource + * @since 3.0.0 + * + * @return {AudioBufferSourceNode} + */ + createBufferSource: function () + { + var _this = this; + var source = this.manager.context.createBufferSource(); - var results = []; + source.buffer = this.audioBuffer; - var x1 = line.x1; - var y1 = line.y1; + source.connect(this.muteNode); - var spaceX = line.x2 - x1; - var spaceY = line.y2 - y1; + source.onended = function (ev) + { + if (ev.target === _this.source) + { + // sound ended + if (_this.currentConfig.loop) + { + _this.hasLooped = true; + } + else + { + _this.hasEnded = true; + } + } - var easeFunc = GetEaseFunction(ease, easeParams); + // else was stopped + }; - var i; - var v; - var q = quantity - 1; + return source; + }, - for (i = 0; i < q; i++) + /** + * This method is only used internally and it stops and removes a buffer source. + * + * @method Phaser.Sound.WebAudioSound#stopAndRemoveBufferSource + * @since 3.0.0 + */ + stopAndRemoveBufferSource: function () { - v = easeFunc(i / q); + if (this.source) + { + this.source.stop(); + this.source.disconnect(); + this.source = null; + } - results.push(new Point(x1 + (spaceX * v), y1 + (spaceY * v))); - } + this.playTime = 0; + this.startTime = 0; - // Always include the end of the line - v = easeFunc(1); + this.stopAndRemoveLoopBufferSource(); + }, - results.push(new Point(x1 + (spaceX * v), y1 + (spaceY * v))); + /** + * This method is only used internally and it stops and removes a looping buffer source. + * + * @method Phaser.Sound.WebAudioSound#stopAndRemoveLoopBufferSource + * @since 3.0.0 + */ + stopAndRemoveLoopBufferSource: function () + { + if (this.loopSource) + { + this.loopSource.stop(); + this.loopSource.disconnect(); + this.loopSource = null; + } - // Remove collinear parts - if (collinearThreshold > 0) + this.loopTime = 0; + }, + + /** + * Method used internally for applying config values to some of the sound properties. + * + * @method Phaser.Sound.WebAudioSound#applyConfig + * @since 3.0.0 + */ + applyConfig: function () { - var prevPoint = results[0]; + this.rateUpdates.length = 0; - // Store the new results here - var sortedResults = [ prevPoint ]; + this.rateUpdates.push({ + time: 0, + rate: 1 + }); - for (i = 1; i < results.length - 1; i++) + var source = this.currentConfig.source; + + if (source && this.manager.context.createPanner) { - var point = results[i]; + var node = this.spatialNode; - if (DistanceBetweenPoints(prevPoint, point) >= collinearThreshold) + node.panningModel = GetFastValue(source, 'panningModel', 'equalpower'); + node.distanceModel = GetFastValue(source, 'distanceModel', 'inverse'); + node.orientationX.value = GetFastValue(source, 'orientationX', 0); + node.orientationY.value = GetFastValue(source, 'orientationY', 0); + node.orientationZ.value = GetFastValue(source, 'orientationZ', -1); + node.refDistance = GetFastValue(source, 'refDistance', 1); + node.maxDistance = GetFastValue(source, 'maxDistance', 10000); + node.rolloffFactor = GetFastValue(source, 'rolloffFactor', 1); + node.coneInnerAngle = GetFastValue(source, 'coneInnerAngle', 360); + node.coneOuterAngle = GetFastValue(source, 'coneOuterAngle', 0); + node.coneOuterGain = GetFastValue(source, 'coneOuterGain', 0); + + this.spatialSource = GetFastValue(source, 'follow', null); + + if (!this.spatialSource) { - sortedResults.push(point); - prevPoint = point; + node.positionX.value = GetFastValue(source, 'x', 0); + node.positionY.value = GetFastValue(source, 'y', 0); + node.positionZ.value = GetFastValue(source, 'z', 0); } } - // Top and tail - var endPoint = results[results.length - 1]; + BaseSound.prototype.applyConfig.call(this); + }, - if (DistanceBetweenPoints(prevPoint, endPoint) < collinearThreshold) + /** + * Sets the x position of this Sound in Spatial Audio space. + * + * This only has any effect if the sound was created with a SpatialSoundConfig object. + * + * Also see the `WebAudioSoundManager.setListenerPosition` method. + * + * If you find that the sound becomes too quiet, too quickly, as it moves away from + * the listener, then try different `refDistance` property values when configuring + * the spatial sound. + * + * @name Phaser.Sound.WebAudioSound#x + * @type {number} + * @since 3.60.0 + */ + x: { + + get: function () { - sortedResults.pop(); - } + if (this.spatialNode) + { + return this.spatialNode.positionX; + } + else + { + return 0; + } + }, - sortedResults.push(endPoint); + set: function (value) + { + if (this.spatialNode) + { + this.spatialNode.positionX.value = value; + } + } + }, - return sortedResults; - } - else - { - return results; - } -}; + /** + * Sets the y position of this Sound in Spatial Audio space. + * + * This only has any effect if the sound was created with a SpatialSoundConfig object. + * + * Also see the `WebAudioSoundManager.setListenerPosition` method. + * + * If you find that the sound becomes too quiet, too quickly, as it moves away from + * the listener, then try different `refDistance` property values when configuring + * the spatial sound. + * + * @name Phaser.Sound.WebAudioSound#y + * @type {number} + * @since 3.60.0 + */ + y: { -module.exports = GetEasedPoints; + get: function () + { + if (this.spatialNode) + { + return this.spatialNode.positionY; + } + else + { + return 0; + } + }, + set: function (value) + { + if (this.spatialNode) + { + this.spatialNode.positionY.value = value; + } + } + }, -/***/ }), -/* 1228 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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 + * @since 3.0.0 + */ + update: function () + { + if (this.isPlaying && this.spatialSource) + { + var x = GetFastValue(this.spatialSource, 'x', null); + var y = GetFastValue(this.spatialSource, 'y', null); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (x && x !== this._spatialx) + { + this._spatialx = this.spatialNode.positionX.value = x; + } + if (y && y !== this._spatialy) + { + this._spatialy = this.spatialNode.positionY.value = y; + } + } -var Point = __webpack_require__(4); + if (this.hasEnded) + { + this.hasEnded = false; -/** - * Get the midpoint of the given line. - * - * @function Phaser.Geom.Line.GetMidPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Line} line - The line to get the midpoint of. - * @param {(Phaser.Geom.Point|object)} [out] - An optional point object to store the midpoint in. - * - * @return {(Phaser.Geom.Point|object)} The midpoint of the Line. - */ -var GetMidPoint = function (line, out) -{ - if (out === undefined) { out = new Point(); } + BaseSound.prototype.stop.call(this); - out.x = (line.x1 + line.x2) / 2; - out.y = (line.y1 + line.y2) / 2; + this.stopAndRemoveBufferSource(); - return out; -}; + 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; -module.exports = GetMidPoint; + this.rateUpdates.push({ + time: 0, + rate: this.totalRate + }); + this.createAndStartLoopBufferSource(); -/***/ }), -/* 1229 */ -/***/ (function(module, exports, __webpack_require__) { + this.emit(Events.LOOPED, this); + } + }, -/** - * @author Richard Davey - * @author Florian Mertens - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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 () + { + if (this.pendingRemove) + { + return; + } -var Point = __webpack_require__(4); + BaseSound.prototype.destroy.call(this); -/** - * Get the nearest point on a line perpendicular to the given point. - * - * @function Phaser.Geom.Line.GetNearestPoint - * @since 3.16.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Line} line - The line to get the nearest point on. - * @param {(Phaser.Geom.Point|object)} point - The point to get the nearest point to. - * @param {(Phaser.Geom.Point|object)} [out] - An optional point, or point-like object, to store the coordinates of the nearest point on the line. - * - * @return {(Phaser.Geom.Point|object)} The nearest point on the line. - */ -var GetNearestPoint = function (line, point, out) -{ - if (out === undefined) { out = new Point(); } + this.audioBuffer = null; + this.stopAndRemoveBufferSource(); + this.muteNode.disconnect(); + this.muteNode = null; + this.volumeNode.disconnect(); + this.volumeNode = null; - var x1 = line.x1; - var y1 = line.y1; + if (this.pannerNode) + { + this.pannerNode.disconnect(); + this.pannerNode = null; + } - var x2 = line.x2; - var y2 = line.y2; + if (this.spatialNode) + { + this.spatialNode.disconnect(); + this.spatialNode = null; + this.spatialSource = null; + } - var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); + this.rateUpdates.length = 0; + this.rateUpdates = null; + }, - if (L2 === 0) + /** + * Method used internally to calculate total playback rate of the sound. + * + * @method Phaser.Sound.WebAudioSound#calculateRate + * @since 3.0.0 + */ + calculateRate: function () { - return out; - } + BaseSound.prototype.calculateRate.call(this); - var r = (((point.x - x1) * (x2 - x1)) + ((point.y - y1) * (y2 - y1))) / L2; + var now = this.manager.context.currentTime; - out.x = x1 + (r * (x2 - x1)); - out.y = y1 + (r * (y2 - y1)); + if (this.source && typeof this.totalRate === 'number') + { + this.source.playbackRate.setValueAtTime(this.totalRate, now); + } - return out; -}; + if (this.isPlaying) + { + this.rateUpdates.push({ + time: Math.max(this.startTime, now) - this.playTime, + rate: this.totalRate + }); -module.exports = GetNearestPoint; + if (this.loopSource) + { + this.stopAndRemoveLoopBufferSource(); + this.createAndStartLoopBufferSource(); + } + } + }, + /** + * Method used internally for calculating current playback time of a playing sound. + * + * @method Phaser.Sound.WebAudioSound#getCurrentTime + * @since 3.0.0 + */ + getCurrentTime: function () + { + var currentTime = 0; -/***/ }), -/* 1230 */ -/***/ (function(module, exports, __webpack_require__) { + for (var i = 0; i < this.rateUpdates.length; i++) + { + var nextTime = 0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (i < this.rateUpdates.length - 1) + { + nextTime = this.rateUpdates[i + 1].time; + } + else + { + nextTime = this.manager.context.currentTime - this.playTime; + } -var MATH_CONST = __webpack_require__(14); -var Angle = __webpack_require__(97); -var Point = __webpack_require__(4); + currentTime += (nextTime - this.rateUpdates[i].time) * this.rateUpdates[i].rate; + } -/** - * Calculate the normal of the given line. - * - * The normal of a line is a vector that points perpendicular from it. - * - * @function Phaser.Geom.Line.GetNormal - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Line} line - The line to calculate the normal of. - * @param {(Phaser.Geom.Point|object)} [out] - An optional point object to store the normal in. - * - * @return {(Phaser.Geom.Point|object)} The normal of the Line. - */ -var GetNormal = function (line, out) -{ - if (out === undefined) { out = new Point(); } + return currentTime; + }, - var a = Angle(line) - MATH_CONST.TAU; + /** + * Method used internally for calculating the time + * at witch the loop source should start playing. + * + * @method Phaser.Sound.WebAudioSound#getLoopTime + * @since 3.0.0 + */ + getLoopTime: function () + { + var lastRateUpdateCurrentTime = 0; - out.x = Math.cos(a); - out.y = Math.sin(a); + for (var i = 0; i < this.rateUpdates.length - 1; i++) + { + lastRateUpdateCurrentTime += (this.rateUpdates[i + 1].time - this.rateUpdates[i].time) * this.rateUpdates[i].rate; + } - return out; -}; + var lastRateUpdate = this.rateUpdates[this.rateUpdates.length - 1]; -module.exports = GetNormal; + 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: { -/***/ }), -/* 1231 */ -/***/ (function(module, exports) { + get: function () + { + return this.currentConfig.rate; + }, -/** - * @author Richard Davey - * @author Florian Mertens - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + set: function (value) + { + this.currentConfig.rate = value; -/** - * Get the shortest distance from a Line to the given Point. - * - * @function Phaser.Geom.Line.GetShortestDistance - * @since 3.16.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Line} line - The line to get the distance from. - * @param {(Phaser.Geom.Point|object)} point - The point to get the shortest distance to. - * - * @return {number} The shortest distance from the line to the point. - */ -var GetShortestDistance = function (line, point) -{ - var x1 = line.x1; - var y1 = line.y1; + this.calculateRate(); - var x2 = line.x2; - var y2 = line.y2; + this.emit(Events.RATE, this, value); + } - var L2 = (((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); + }, - if (L2 === 0) + /** + * 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) { - return false; - } - - var s = (((y1 - point.y) * (x2 - x1)) - ((x1 - point.x) * (y2 - y1))) / L2; - - return Math.abs(s) * Math.sqrt(L2); -}; + this.rate = value; -module.exports = GetShortestDistance; + 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: { -/***/ }), -/* 1232 */ -/***/ (function(module, exports) { + get: function () + { + return this.currentConfig.detune; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + set: function (value) + { + this.currentConfig.detune = value; -/** - * Calculate the height of the given line. - * - * @function Phaser.Geom.Line.Height - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The line to calculate the height of. - * - * @return {number} The height of the line. - */ -var Height = function (line) -{ - return Math.abs(line.y1 - line.y2); -}; + this.calculateRate(); -module.exports = Height; + this.emit(Events.DETUNE, this, value); + } + }, -/***/ }), -/* 1233 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var MATH_CONST = __webpack_require__(14); -var Angle = __webpack_require__(97); + /** + * 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: { -/** - * Returns the x component of the normal vector of the given line. - * - * @function Phaser.Geom.Line.NormalX - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The Line object to get the normal value from. - * - * @return {number} The x component of the normal vector of the line. - */ -var NormalX = function (line) -{ - return Math.cos(Angle(line) - MATH_CONST.TAU); -}; + get: function () + { + return (this.muteNode.gain.value === 0); + }, -module.exports = NormalX; + set: function (value) + { + this.currentConfig.mute = value; + this.muteNode.gain.setValueAtTime(value ? 0 : 1, 0); + this.emit(Events.MUTE, this, value); + } -/***/ }), -/* 1234 */ -/***/ (function(module, exports, __webpack_require__) { + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var MATH_CONST = __webpack_require__(14); -var Angle = __webpack_require__(97); + return this; + }, -/** - * The Y value of the normal of the given line. - * The normal of a line is a vector that points perpendicular from it. - * - * @function Phaser.Geom.Line.NormalY - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The line to calculate the normal of. - * - * @return {number} The Y value of the normal of the Line. - */ -var NormalY = function (line) -{ - return Math.sin(Angle(line) - MATH_CONST.TAU); -}; + /** + * 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: { -module.exports = NormalY; + get: function () + { + return this.volumeNode.gain.value; + }, + set: function (value) + { + this.currentConfig.volume = value; + this.volumeNode.gain.setValueAtTime(value, 0); -/***/ }), -/* 1235 */ -/***/ (function(module, exports) { + this.emit(Events.VOLUME, this, value); + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -/** - * Offset a line by the given amount. - * - * @function Phaser.Geom.Line.Offset - * @since 3.0.0 - * - * @generic {Phaser.Geom.Line} O - [line,$return] - * - * @param {Phaser.Geom.Line} line - The line to offset. - * @param {number} x - The horizontal offset to add to the line. - * @param {number} y - The vertical offset to add to the line. - * - * @return {Phaser.Geom.Line} The offset line. - */ -var Offset = function (line, x, y) -{ - line.x1 += x; - line.y1 += y; + return this; + }, - line.x2 += x; - line.y2 += y; + /** + * 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: { - return line; -}; + get: function () + { + if (this.isPlaying) + { + if (this.manager.context.currentTime < this.startTime) + { + return this.startTime - this.playTime; + } -module.exports = Offset; + 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; + } -/***/ }), -/* 1236 */ -/***/ (function(module, exports) { + if (this.isPlaying || this.isPaused) + { + value = Math.min(Math.max(0, value), this.duration); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.currentConfig.seek = value; -/** - * Calculate the perpendicular slope of the given line. - * - * @function Phaser.Geom.Line.PerpSlope - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The line to calculate the perpendicular slope of. - * - * @return {number} The perpendicular slope of the line. - */ -var PerpSlope = function (line) -{ - return -((line.x2 - line.x1) / (line.y2 - line.y1)); -}; + if (this.isPlaying) + { + this.stopAndRemoveBufferSource(); + this.createAndStartBufferSource(); + } -module.exports = PerpSlope; + 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; -/***/ }), -/* 1237 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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: { -var Angle = __webpack_require__(97); -var NormalAngle = __webpack_require__(497); + get: function () + { + return this.currentConfig.loop; + }, -/** - * Calculate the reflected angle between two lines. - * - * This is the outgoing angle based on the angle of Line 1 and the normalAngle of Line 2. - * - * @function Phaser.Geom.Line.ReflectAngle - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} lineA - The first line. - * @param {Phaser.Geom.Line} lineB - The second line. - * - * @return {number} The reflected angle between each line. - */ -var ReflectAngle = function (lineA, lineB) -{ - return (2 * NormalAngle(lineB) - Math.PI - Angle(lineA)); -}; + set: function (value) + { + this.currentConfig.loop = value; -module.exports = ReflectAngle; + if (this.isPlaying) + { + this.stopAndRemoveLoopBufferSource(); + if (value) + { + this.createAndStartLoopBufferSource(); + } + } -/***/ }), -/* 1238 */ -/***/ (function(module, exports, __webpack_require__) { + this.emit(Events.LOOP, this, value); + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var RotateAroundXY = __webpack_require__(236); + return this; + }, -/** - * Rotate a line around its midpoint by the given angle in radians. - * - * @function Phaser.Geom.Line.Rotate - * @since 3.0.0 - * - * @generic {Phaser.Geom.Line} O - [line,$return] - * - * @param {Phaser.Geom.Line} line - The line to rotate. - * @param {number} angle - The angle of rotation in radians. - * - * @return {Phaser.Geom.Line} The rotated line. - */ -var Rotate = function (line, angle) -{ - var x = (line.x1 + line.x2) / 2; - var y = (line.y1 + line.y2) / 2; + /** + * 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: { - return RotateAroundXY(line, x, y, angle); -}; + get: function () + { + if (this.pannerNode) + { + return this.pannerNode.pan.value; + } + else + { + return 0; + } + }, -module.exports = Rotate; + set: function (value) + { + this.currentConfig.pan = value; + if (this.pannerNode) + { + this.pannerNode.pan.setValueAtTime(value, this.manager.context.currentTime); + } -/***/ }), -/* 1239 */ -/***/ (function(module, exports, __webpack_require__) { + this.emit(Events.PAN, this, value); + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; -var RotateAroundXY = __webpack_require__(236); + return this; + } -/** - * Rotate a line around a point by the given angle in radians. - * - * @function Phaser.Geom.Line.RotateAroundPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Line} O - [line,$return] - * - * @param {Phaser.Geom.Line} line - The line to rotate. - * @param {(Phaser.Geom.Point|object)} point - The point to rotate the line around. - * @param {number} angle - The angle of rotation in radians. - * - * @return {Phaser.Geom.Line} The rotated line. - */ -var RotateAroundPoint = function (line, point, angle) -{ - return RotateAroundXY(line, point.x, point.y, angle); -}; +}); -module.exports = RotateAroundPoint; +module.exports = WebAudioSound; /***/ }), -/* 1240 */ -/***/ (function(module, exports) { + +/***/ 55491: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Pavle Goloskokovic (http://prunegames.com) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Base64ToArrayBuffer = __webpack_require__(82329); +var BaseSoundManager = __webpack_require__(12486); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(76038); +var GameEvents = __webpack_require__(97081); +var WebAudioSound = __webpack_require__(96008); +var GetFastValue = __webpack_require__(72632); + /** - * Set a line to a given position, angle and length. + * @classdesc + * Web Audio API implementation of the Sound Manager. * - * @function Phaser.Geom.Line.SetToAngle - * @since 3.0.0 + * Not all browsers can play all audio formats. * - * @generic {Phaser.Geom.Line} O - [line,$return] + * 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). * - * @param {Phaser.Geom.Line} line - The line to set. - * @param {number} x - The horizontal start position of the line. - * @param {number} y - The vertical start position of the line. - * @param {number} angle - The angle of the line in radians. - * @param {number} length - The length of the line. + * @class WebAudioSoundManager + * @extends Phaser.Sound.BaseSoundManager + * @memberof Phaser.Sound + * @constructor + * @since 3.0.0 * - * @return {Phaser.Geom.Line} The updated line. + * @param {Phaser.Game} game - Reference to the current game instance. */ -var SetToAngle = function (line, x, y, angle, length) -{ - line.x1 = x; - line.y1 = y; +var WebAudioSoundManager = new Class({ - line.x2 = x + (Math.cos(angle) * length); - line.y2 = y + (Math.sin(angle) * length); + Extends: BaseSoundManager, - return line; -}; + initialize: -module.exports = SetToAngle; + function WebAudioSoundManager (game) + { + /** + * The AudioContext being used for playback. + * + * @name Phaser.Sound.WebAudioSoundManager#context + * @type {AudioContext} + * @since 3.0.0 + */ + this.context = this.createAudioContext(game); + /** + * Gain node responsible for controlling global muting. + * + * @name Phaser.Sound.WebAudioSoundManager#masterMuteNode + * @type {GainNode} + * @since 3.0.0 + */ + this.masterMuteNode = this.context.createGain(); -/***/ }), -/* 1241 */ -/***/ (function(module, exports) { + /** + * Gain node responsible for controlling global volume. + * + * @name Phaser.Sound.WebAudioSoundManager#masterVolumeNode + * @type {GainNode} + * @since 3.0.0 + */ + this.masterVolumeNode = this.context.createGain(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.masterMuteNode.connect(this.masterVolumeNode); -/** - * Calculate the slope of the given line. - * - * @function Phaser.Geom.Line.Slope - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The line to calculate the slope of. - * - * @return {number} The slope of the line. - */ -var Slope = function (line) -{ - return (line.y2 - line.y1) / (line.x2 - line.x1); -}; + this.masterVolumeNode.connect(this.context.destination); -module.exports = Slope; + /** + * Destination node for connecting individual sounds to. + * + * @name Phaser.Sound.WebAudioSoundManager#destination + * @type {AudioNode} + * @since 3.0.0 + */ + this.destination = this.masterMuteNode; + this.locked = this.context.state === 'suspended' && ('ontouchstart' in window || 'onclick' in window); -/***/ }), -/* 1242 */ -/***/ (function(module, exports) { + BaseSoundManager.call(this, game); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.locked && game.isBooted) + { + this.unlock(); + } + else + { + game.events.once(GameEvents.BOOT, this.unlock, this); + } + }, -/** - * Calculate the width of the given line. - * - * @function Phaser.Geom.Line.Width - * @since 3.0.0 - * - * @param {Phaser.Geom.Line} line - The line to calculate the width of. - * - * @return {number} The width of the line. - */ -var Width = function (line) -{ - return Math.abs(line.x1 - line.x2); -}; + /** + * 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 + * @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; -module.exports = Width; + if (audioConfig.context) + { + audioConfig.context.resume(); + return audioConfig.context; + } -/***/ }), -/* 1243 */ -/***/ (function(module, exports, __webpack_require__) { + if (window.hasOwnProperty('AudioContext')) + { + return new AudioContext(); + } + else if (window.hasOwnProperty('webkitAudioContext')) + { + return new window.webkitAudioContext(); + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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(); + } -/** - * @namespace Phaser.Geom.Mesh - */ + if (this.masterMuteNode) + { + this.masterMuteNode.disconnect(); + } -var Mesh = { + if (this.masterVolumeNode) + { + this.masterVolumeNode.disconnect(); + } - Face: __webpack_require__(116), - GenerateGridVerts: __webpack_require__(1244), - GenerateObjVerts: __webpack_require__(480), - GenerateVerts: __webpack_require__(479), - ParseObj: __webpack_require__(498), - ParseObjMaterial: __webpack_require__(499), - RotateFace: __webpack_require__(1245), - Vertex: __webpack_require__(117) + this.context = context; -}; + this.masterMuteNode = context.createGain(); + this.masterVolumeNode = context.createGain(); -module.exports = Mesh; + this.masterMuteNode.connect(this.masterVolumeNode); + this.masterVolumeNode.connect(context.destination); + this.destination = this.masterMuteNode; -/***/ }), -/* 1244 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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); -var Face = __webpack_require__(116); -var GetFastValue = __webpack_require__(2); -var Matrix4 = __webpack_require__(69); -var Vector3 = __webpack_require__(39); -var Vertex = __webpack_require__(117); + this.sounds.push(sound); -var tempPosition = new Vector3(); -var tempRotation = new Vector3(); -var tempMatrix = new Matrix4(); + return sound; + }, -/** - * Creates a grid of vertices based on the given configuration object and optionally adds it to a Mesh. - * - * The size of the grid is given in pixels. An example configuration may be: - * - * `{ width: 256, height: 256, widthSegments: 2, heightSegments: 2, tile: true }` - * - * This will create a grid 256 x 256 pixels in size, split into 2 x 2 segments, with - * the texture tiling across the cells. - * - * You can split the grid into segments both vertically and horizontally. This will - * generate two faces per grid segment as a result. - * - * The `tile` parameter allows you to control if the tile will repeat across the grid - * segments, or be displayed in full. - * - * If adding this grid to a Mesh you can offset the grid via the `x` and `y` properties. - * - * UV coordinates are generated based on the given texture and frame in the config. For - * example, no frame is given, the UVs will be in the range 0 to 1. If a frame is given, - * such as from a texture atlas, the UVs will be generated within the range of that frame. - * - * @function Phaser.Geom.Mesh.GenerateGridVerts - * @since 3.50.0 - * - * @param {Phaser.Types.Geom.Mesh.GenerateGridConfig} config - A Grid configuration object. - * - * @return {Phaser.Types.Geom.Mesh.GenerateGridVertsResult} A Grid Result object, containing the generated vertices and indicies. - */ -var GenerateGridVerts = function (config) -{ - var mesh = GetFastValue(config, 'mesh'); - var texture = GetFastValue(config, 'texture', null); - var frame = GetFastValue(config, 'frame'); - var width = GetFastValue(config, 'width', 1); - var height = GetFastValue(config, 'height', width); - var widthSegments = GetFastValue(config, 'widthSegments', 1); - var heightSegments = GetFastValue(config, 'heightSegments', widthSegments); - var posX = GetFastValue(config, 'x', 0); - var posY = GetFastValue(config, 'y', 0); - var posZ = GetFastValue(config, 'z', 0); - var rotateX = GetFastValue(config, 'rotateX', 0); - var rotateY = GetFastValue(config, 'rotateY', 0); - var rotateZ = GetFastValue(config, 'rotateZ', 0); - var zIsUp = GetFastValue(config, 'zIsUp', true); - var isOrtho = GetFastValue(config, 'isOrtho', (mesh) ? mesh.dirtyCache[11] : false); - var colors = GetFastValue(config, 'colors', [ 0xffffff ]); - var alphas = GetFastValue(config, 'alphas', [ 1 ]); - var tile = GetFastValue(config, 'tile', false); - var flipY = GetFastValue(config, 'flipY', false); + /** + * 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; - var widthSet = GetFastValue(config, 'width', null); + if (!Array.isArray(audioKey)) + { + audioFiles = [ { key: audioKey, data: audioData } ]; + } + else + { + audioFiles = audioKey; + } - var result = { - faces: [], - verts: [] - }; + var cache = this.game.cache.audio; + var remaining = audioFiles.length; - tempPosition.set(posX, posY, posZ); - tempRotation.set(rotateX, rotateY, rotateZ); - tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp); + for (var i = 0; i < audioFiles.length; i++) + { + var entry = audioFiles[i]; - if (!texture && mesh) - { - texture = mesh.texture; - } - else if (mesh && typeof(texture) === 'string') - { - texture = mesh.scene.sys.textures.get(texture); - } - else - { - // There's nothing more we can do without a texture - return result; - } + var key = entry.key; + var data = entry.data; - var textureFrame = texture.get(frame); + if (typeof data === 'string') + { + data = Base64ToArrayBuffer(data); + } - // If the Mesh is ortho and no width / height is given, we'll default to texture sizes (if set!) - if (!widthSet && isOrtho && texture && mesh) - { - width = textureFrame.width / mesh.height; - height = textureFrame.height / mesh.height; - } + var success = function (key, audioBuffer) + { + cache.add(key, audioBuffer); - var halfWidth = width / 2; - var halfHeight = height / 2; + this.emit(Events.DECODED, key); - var gridX = Math.floor(widthSegments); - var gridY = Math.floor(heightSegments); + remaining--; - var gridX1 = gridX + 1; - var gridY1 = gridY + 1; + if (remaining === 0) + { + this.emit(Events.DECODED_ALL); + } + }.bind(this, key); - var segmentWidth = width / gridX; - var segmentHeight = height / gridY; + var failure = function (key, error) + { + // eslint-disable-next-line no-console + console.error('Error decoding audio: ' + key + ' - ', error ? error.message : ''); - var uvs = []; - var vertices = []; + remaining--; - var ix; - var iy; + if (remaining === 0) + { + this.emit(Events.DECODED_ALL); + } + }.bind(this, key); - var frameU0 = 0; - var frameU1 = 1; - var frameV0 = 0; - var frameV1 = 1; + this.context.decodeAudioData(data, success, failure); + } + }, - if (textureFrame) + /** + * Sets the X and Y position of the Spatial Audio listener on this Web Audios context. + * + * If you call this method with no parameters it will default to the center-point of + * the game canvas. Depending on the type of game you're making, you may need to call + * this method constantly to reset the listener position as the camera scrolls. + * + * Calling this method does nothing on HTML5Audio. + * + * @method Phaser.Sound.WebAudioSoundManager#setListenerPosition + * @since 3.60.0 + * + * @param {number} [x] - The x position of the Spatial Audio listener. + * @param {number} [y] - The y position of the Spatial Audio listener. + */ + setListenerPosition: function (x, y) { - frameU0 = textureFrame.u0; - frameU1 = textureFrame.u1; + if (x === undefined) { x = this.game.scale.width / 2; } + if (y === undefined) { y = this.game.scale.height / 2; } - if (!flipY) - { - frameV0 = textureFrame.v0; - frameV1 = textureFrame.v1; - } - else - { - frameV0 = textureFrame.v1; - frameV1 = textureFrame.v0; - } - } + this.listenerPosition.set(x, y); - var frameU = frameU1 - frameU0; - var frameV = frameV1 - frameV0; + return this; + }, - for (iy = 0; iy < gridY1; iy++) + /** + * 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 y = iy * segmentHeight - halfHeight; + var _this = this; - for (ix = 0; ix < gridX1; ix++) + var body = document.body; + + var unlockHandler = function unlockHandler () { - var x = ix * segmentWidth - halfWidth; + if (_this.context && body) + { + var bodyRemove = body.removeEventListener; - vertices.push(x, -y); + _this.context.resume().then(function () + { + bodyRemove('touchstart', unlockHandler); + bodyRemove('touchend', unlockHandler); + bodyRemove('click', unlockHandler); + bodyRemove('keydown', unlockHandler); - var tu = frameU0 + frameU * (ix / gridX); - var tv = frameV0 + frameV * (iy / gridY); + _this.unlocked = true; + }, function () + { + bodyRemove('touchstart', unlockHandler); + bodyRemove('touchend', unlockHandler); + bodyRemove('click', unlockHandler); + bodyRemove('keydown', unlockHandler); + }); + } + }; - uvs.push(tu, tv); + if (body) + { + body.addEventListener('touchstart', unlockHandler, false); + body.addEventListener('touchend', unlockHandler, false); + body.addEventListener('click', unlockHandler, false); + body.addEventListener('keydown', unlockHandler, false); } - } + }, - if (!Array.isArray(colors)) + /** + * 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 () { - colors = [ colors ]; - } + if (!this.locked) + { + this.context.suspend(); + } + }, - if (!Array.isArray(alphas)) + /** + * 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 () { - alphas = [ alphas ]; - } - - var alphaIndex = 0; - var colorIndex = 0; + var context = this.context; - for (iy = 0; iy < gridY; iy++) - { - for (ix = 0; ix < gridX; ix++) + if (context && !this.locked && (context.state === 'suspended' || context.state === 'interrupted')) { - var a = (ix + gridX1 * iy) * 2; - var b = (ix + gridX1 * (iy + 1)) * 2; - var c = ((ix + 1) + gridX1 * (iy + 1)) * 2; - var d = ((ix + 1) + gridX1 * iy) * 2; + context.resume(); + } + }, - var color = colors[colorIndex]; - var alpha = alphas[alphaIndex]; + /** + * Update method called on every game step. + * + * Removes destroyed sounds and updates every active sound in the game. + * + * @method Phaser.Sound.WebAudioSoundManager#update + * @protected + * @fires Phaser.Sound.Events#UNLOCKED + * @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 elapsed since the last frame. + */ + update: function (time, delta) + { + var listener = this.context.listener; - var vert1 = new Vertex(vertices[a], vertices[a + 1], 0, uvs[a], uvs[a + 1], color, alpha).transformMat4(tempMatrix); - var vert2 = new Vertex(vertices[b], vertices[b + 1], 0, uvs[b], uvs[b + 1], color, alpha).transformMat4(tempMatrix); - var vert3 = new Vertex(vertices[d], vertices[d + 1], 0, uvs[d], uvs[d + 1], color, alpha).transformMat4(tempMatrix); - var vert4 = new Vertex(vertices[b], vertices[b + 1], 0, uvs[b], uvs[b + 1], color, alpha).transformMat4(tempMatrix); - var vert5 = new Vertex(vertices[c], vertices[c + 1], 0, uvs[c], uvs[c + 1], color, alpha).transformMat4(tempMatrix); - var vert6 = new Vertex(vertices[d], vertices[d + 1], 0, uvs[d], uvs[d + 1], color, alpha).transformMat4(tempMatrix); + if (listener && listener.positionX !== undefined) + { + var x = GetFastValue(this.listenerPosition, 'x', null); + var y = GetFastValue(this.listenerPosition, 'y', null); - if (tile) + if (x && x !== this._spatialx) { - vert1.setUVs(frameU0, frameV1); - vert2.setUVs(frameU0, frameV0); - vert3.setUVs(frameU1, frameV1); - vert4.setUVs(frameU0, frameV0); - vert5.setUVs(frameU1, frameV0); - vert6.setUVs(frameU1, frameV1); + this._spatialx = listener.positionX.value = x; } - - colorIndex++; - - if (colorIndex === colors.length) + if (y && y !== this._spatialy) { - colorIndex = 0; + this._spatialy = listener.positionY.value = y; } + } - alphaIndex++; + BaseSoundManager.prototype.update.call(this, time, delta); - if (alphaIndex === alphas.length) - { - alphaIndex = 0; - } + // Resume interrupted audio on iOS only if the game has focus + if (!this.gameLostFocus) + { + this.onFocus(); + } + }, - result.verts.push(vert1, vert2, vert3, vert4, vert5, vert6); + /** + * 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; - result.faces.push( - new Face(vert1, vert2, vert3), - new Face(vert4, vert5, vert6) - ); + if (this.game.config.audio.context) + { + this.context.suspend(); } - } + else + { + var _this = this; - if (mesh) + 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) { - mesh.faces = mesh.faces.concat(result.faces); - mesh.vertices = mesh.vertices.concat(result.verts); - } + this.mute = value; - return result; -}; + return this; + }, -module.exports = GenerateGridVerts; + /** + * @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); + }, -/***/ }), -/* 1245 */ -/***/ (function(module, exports) { + set: function (value) + { + this.masterMuteNode.gain.setValueAtTime(value ? 0 : 1, 0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.emit(Events.GLOBAL_MUTE, this, value); + } -/** - * Rotates the vertices of a Face to the given angle. - * - * The actual vertex positions are adjusted, not their transformed positions. - * - * Therefore, this updates the vertex data directly. - * - * @function Phaser.Geom.Mesh.RotateFace - * @since 3.50.0 - * - * @param {Phaser.Geom.Mesh.Face} face - The Face to rotate. - * @param {number} angle - The angle to rotate to, in radians. - * @param {number} [cx] - An optional center of rotation. If not given, the Face in-center is used. - * @param {number} [cy] - An optional center of rotation. If not given, the Face in-center is used. - */ -var RotateFace = function (face, angle, cx, cy) -{ - var x; - var y; + }, - // No point of rotation? Use the inCenter instead, then. - if (cx === undefined && cy === undefined) + /** + * 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) { - var inCenter = face.getInCenter(); - - x = inCenter.x; - y = inCenter.y; - } - - var c = Math.cos(angle); - var s = Math.sin(angle); + this.volume = value; - var v1 = face.vertex1; - var v2 = face.vertex2; - var v3 = face.vertex3; + return this; + }, - var tx = v1.x - x; - var ty = v1.y - y; + /** + * @name Phaser.Sound.WebAudioSoundManager#volume + * @type {number} + * @fires Phaser.Sound.Events#GLOBAL_VOLUME + * @since 3.0.0 + */ + volume: { - v1.set(tx * c - ty * s + x, tx * s + ty * c + y); + get: function () + { + return this.masterVolumeNode.gain.value; + }, - tx = v2.x - x; - ty = v2.y - y; + set: function (value) + { + this.masterVolumeNode.gain.setValueAtTime(value, 0); - v2.set(tx * c - ty * s + x, tx * s + ty * c + y); + this.emit(Events.GLOBAL_VOLUME, this, value); + } - tx = v3.x - x; - ty = v3.y - y; + } - v3.set(tx * c - ty * s + x, tx * s + ty * c + y); -}; +}); -module.exports = RotateFace; +module.exports = WebAudioSoundManager; /***/ }), -/* 1246 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71207: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Point = __webpack_require__(4); - -Point.Ceil = __webpack_require__(1247); -Point.Clone = __webpack_require__(1248); -Point.CopyFrom = __webpack_require__(1249); -Point.Equals = __webpack_require__(1250); -Point.Floor = __webpack_require__(1251); -Point.GetCentroid = __webpack_require__(1252); -Point.GetMagnitude = __webpack_require__(500); -Point.GetMagnitudeSq = __webpack_require__(501); -Point.GetRectangleFromPoints = __webpack_require__(1253); -Point.Interpolate = __webpack_require__(1254); -Point.Invert = __webpack_require__(1255); -Point.Negative = __webpack_require__(1256); -Point.Project = __webpack_require__(1257); -Point.ProjectUnit = __webpack_require__(1258); -Point.SetMagnitude = __webpack_require__(1259); - -module.exports = Point; - - -/***/ }), -/* 1247 */ -/***/ (function(module, exports) { +var ArrayUtils = __webpack_require__(59959); +var Class = __webpack_require__(56694); +var NOOP = __webpack_require__(72283); +var StableSort = __webpack_require__(17922); /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @callback EachListCallback + * + * @param {I} item - The item which is currently being processed. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. */ /** - * Apply `Math.ceil()` to each coordinate of the given Point. + * @classdesc + * List is a generic implementation of an ordered list which contains utility methods for retrieving, manipulating, and iterating items. * - * @function Phaser.Geom.Point.Ceil + * @class List + * @memberof Phaser.Structs + * @constructor * @since 3.0.0 * - * @generic {Phaser.Geom.Point} O - [point,$return] - * - * @param {Phaser.Geom.Point} point - The Point to ceil. + * @generic T * - * @return {Phaser.Geom.Point} The Point with `Math.ceil()` applied to its coordinates. + * @param {*} parent - The parent of this list. */ -var Ceil = function (point) -{ - return point.setTo(Math.ceil(point.x), Math.ceil(point.y)); -}; +var List = new Class({ -module.exports = Ceil; + initialize: + function List (parent) + { + /** + * The parent of this list. + * + * @name Phaser.Structs.List#parent + * @type {*} + * @since 3.0.0 + */ + this.parent = parent; -/***/ }), -/* 1248 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The objects that belong to this collection. + * + * @genericUse {T[]} - [$type] + * + * @name Phaser.Structs.List#list + * @type {Array.<*>} + * @default [] + * @since 3.0.0 + */ + this.list = []; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The index of the current element. + * + * This is used internally when iterating through the list with the {@link #first}, {@link #last}, {@link #get}, and {@link #previous} properties. + * + * @name Phaser.Structs.List#position + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.position = 0; -var Point = __webpack_require__(4); + /** + * A callback that is invoked every time a child is added to this list. + * + * @name Phaser.Structs.List#addCallback + * @type {function} + * @since 3.4.0 + */ + this.addCallback = NOOP; -/** - * Clone the given Point. - * - * @function Phaser.Geom.Point.Clone - * @since 3.0.0 - * - * @param {Phaser.Geom.Point} source - The source Point to clone. - * - * @return {Phaser.Geom.Point} The cloned Point. - */ -var Clone = function (source) -{ - return new Point(source.x, source.y); -}; + /** + * A callback that is invoked every time a child is removed from this list. + * + * @name Phaser.Structs.List#removeCallback + * @type {function} + * @since 3.4.0 + */ + this.removeCallback = NOOP; -module.exports = Clone; + /** + * The property key to sort by. + * + * @name Phaser.Structs.List#_sortKey + * @type {string} + * @since 3.4.0 + */ + this._sortKey = ''; + }, + /** + * Adds the given item to the end of the list. Each item must be unique. + * + * @method Phaser.Structs.List#add + * @since 3.0.0 + * + * @genericUse {T} - [child,$return] + * + * @param {*|Array.<*>} child - The item, or array of items, to add to the list. + * @param {boolean} [skipCallback=false] - Skip calling the List.addCallback if this child is added successfully. + * + * @return {*} The list's underlying array. + */ + add: function (child, skipCallback) + { + if (skipCallback) + { + return ArrayUtils.Add(this.list, child); + } + else + { + return ArrayUtils.Add(this.list, child, 0, this.addCallback, this); + } + }, -/***/ }), -/* 1249 */ -/***/ (function(module, exports) { + /** + * Adds an item to list, starting at a specified index. Each item must be unique within the list. + * + * @method Phaser.Structs.List#addAt + * @since 3.0.0 + * + * @genericUse {T} - [child,$return] + * + * @param {*} child - The item, or array of items, to add to the list. + * @param {number} [index=0] - The index in the list at which the element(s) will be inserted. + * @param {boolean} [skipCallback=false] - Skip calling the List.addCallback if this child is added successfully. + * + * @return {*} The List's underlying array. + */ + addAt: function (child, index, skipCallback) + { + if (skipCallback) + { + return ArrayUtils.AddAt(this.list, child, index); + } + else + { + return ArrayUtils.AddAt(this.list, child, index, 0, this.addCallback, this); + } + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Retrieves the item at a given position inside the List. + * + * @method Phaser.Structs.List#getAt + * @since 3.0.0 + * + * @genericUse {T} - [$return] + * + * @param {number} index - The index of the item. + * + * @return {*} The retrieved item, or `undefined` if it's outside the List's bounds. + */ + getAt: function (index) + { + return this.list[index]; + }, -/** - * Copy the values of one Point to a destination Point. - * - * @function Phaser.Geom.Point.CopyFrom - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [dest,$return] - * - * @param {Phaser.Geom.Point} source - The source Point to copy the values from. - * @param {Phaser.Geom.Point} dest - The destination Point to copy the values to. - * - * @return {Phaser.Geom.Point} The destination Point. - */ -var CopyFrom = function (source, dest) -{ - return dest.setTo(source.x, source.y); -}; + /** + * Locates an item within the List and returns its index. + * + * @method Phaser.Structs.List#getIndex + * @since 3.0.0 + * + * @genericUse {T} - [child] + * + * @param {*} child - The item to locate. + * + * @return {number} The index of the item within the List, or -1 if it's not in the List. + */ + getIndex: function (child) + { + // Return -1 if given child isn't a child of this display list + return this.list.indexOf(child); + }, -module.exports = CopyFrom; + /** + * Sort the contents of this List so the items are in order based on the given property. + * For example, `sort('alpha')` would sort the List contents based on the value of their `alpha` property. + * + * @method Phaser.Structs.List#sort + * @since 3.0.0 + * + * @genericUse {T[]} - [children,$return] + * + * @param {string} property - The property to lexically sort by. + * @param {function} [handler] - Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean. + * + * @return {Phaser.Structs.List} This List object. + */ + sort: function (property, handler) + { + if (!property) + { + return this; + } + if (handler === undefined) + { + handler = function (childA, childB) + { + return childA[property] - childB[property]; + }; + } -/***/ }), -/* 1250 */ -/***/ (function(module, exports) { + StableSort(this.list, handler); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * A comparison of two `Point` objects to see if they are equal. - * - * @function Phaser.Geom.Point.Equals - * @since 3.0.0 - * - * @param {Phaser.Geom.Point} point - The original `Point` to compare against. - * @param {Phaser.Geom.Point} toCompare - The second `Point` to compare. - * - * @return {boolean} Returns true if the both `Point` objects are equal. - */ -var Equals = function (point, toCompare) -{ - return (point.x === toCompare.x && point.y === toCompare.y); -}; + /** + * Searches for the first instance of a child with its `name` + * property matching the given argument. Should more than one child have + * the same name only the first is returned. + * + * @method Phaser.Structs.List#getByName + * @since 3.0.0 + * + * @genericUse {T | null} - [$return] + * + * @param {string} name - The name to search for. + * + * @return {?*} The first child with a matching name, or null if none were found. + */ + getByName: function (name) + { + return ArrayUtils.GetFirst(this.list, 'name', name); + }, -module.exports = Equals; + /** + * Returns a random child from the group. + * + * @method Phaser.Structs.List#getRandom + * @since 3.0.0 + * + * @genericUse {T | null} - [$return] + * + * @param {number} [startIndex=0] - Offset from the front of the group (lowest child). + * @param {number} [length=(to top)] - Restriction on the number of values you want to randomly select from. + * + * @return {?*} A random child of this Group. + */ + getRandom: function (startIndex, length) + { + return ArrayUtils.GetRandom(this.list, startIndex, length); + }, + /** + * Returns the first element in a given part of the List which matches a specific criterion. + * + * @method Phaser.Structs.List#getFirst + * @since 3.0.0 + * + * @genericUse {T | null} - [$return] + * + * @param {string} property - The name of the property to test or a falsey value to have no criterion. + * @param {*} value - The value to test the `property` against, or `undefined` to allow any value and only check for existence. + * @param {number} [startIndex=0] - The position in the List to start the search at. + * @param {number} [endIndex] - The position in the List to optionally stop the search at. It won't be checked. + * + * @return {?*} The first item which matches the given criterion, or `null` if no such item exists. + */ + getFirst: function (property, value, startIndex, endIndex) + { + return ArrayUtils.GetFirst(this.list, property, value, startIndex, endIndex); + }, -/***/ }), -/* 1251 */ -/***/ (function(module, exports) { + /** + * Returns all children in this List. + * + * You can optionally specify a matching criteria using the `property` and `value` arguments. + * + * For example: `getAll('parent')` would return only children that have a property called `parent`. + * + * You can also specify a value to compare the property to: + * + * `getAll('visible', true)` would return only children that have their visible property set to `true`. + * + * Optionally you can specify a start and end index. For example if this List had 100 children, + * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only + * the first 50 children in the List. + * + * @method Phaser.Structs.List#getAll + * @since 3.0.0 + * + * @genericUse {T[]} - [$return] + * + * @param {string} [property] - An optional property to test against the value argument. + * @param {any} [value] - If property is set then Child.property must strictly equal this value to be included in the results. + * @param {number} [startIndex] - The first child index to start the search from. + * @param {number} [endIndex] - The last child index to search up until. + * + * @return {Array.<*>} All items of the List which match the given criterion, if any. + */ + getAll: function (property, value, startIndex, endIndex) + { + return ArrayUtils.GetAll(this.list, property, value, startIndex, endIndex); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Returns the total number of items in the List which have a property matching the given value. + * + * @method Phaser.Structs.List#count + * @since 3.0.0 + * + * @genericUse {T} - [value] + * + * @param {string} property - The property to test on each item. + * @param {*} value - The value to test the property against. + * + * @return {number} The total number of matching elements. + */ + count: function (property, value) + { + return ArrayUtils.CountAllMatching(this.list, property, value); + }, -/** - * Apply `Math.ceil()` to each coordinate of the given Point. - * - * @function Phaser.Geom.Point.Floor - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [point,$return] - * - * @param {Phaser.Geom.Point} point - The Point to floor. - * - * @return {Phaser.Geom.Point} The Point with `Math.floor()` applied to its coordinates. - */ -var Floor = function (point) -{ - return point.setTo(Math.floor(point.x), Math.floor(point.y)); -}; + /** + * Swaps the positions of two items in the list. + * + * @method Phaser.Structs.List#swap + * @since 3.0.0 + * + * @genericUse {T} - [child1,child2] + * + * @param {*} child1 - The first item to swap. + * @param {*} child2 - The second item to swap. + */ + swap: function (child1, child2) + { + ArrayUtils.Swap(this.list, child1, child2); + }, -module.exports = Floor; + /** + * Moves an item in the List to a new position. + * + * @method Phaser.Structs.List#moveTo + * @since 3.0.0 + * + * @genericUse {T} - [child,$return] + * + * @param {*} child - The item to move. + * @param {number} index - Moves an item in the List to a new position. + * + * @return {*} The item that was moved. + */ + moveTo: function (child, index) + { + return ArrayUtils.MoveTo(this.list, child, index); + }, + /** + * Moves the given array element above another one in the array. + * + * @method Phaser.Structs.List#moveAbove + * @since 3.55.0 + * + * @genericUse {T} - [child1,child2] + * + * @param {*} child1 - The element to move above base element. + * @param {*} child2 - The base element. + */ + moveAbove: function (child1, child2) + { + return ArrayUtils.MoveAbove(this.list, child1, child2); + }, -/***/ }), -/* 1252 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Moves the given array element below another one in the array. + * + * @method Phaser.Structs.List#moveBelow + * @since 3.55.0 + * + * @genericUse {T} - [child1,child2] + * + * @param {*} child1 - The element to move below base element. + * @param {*} child2 - The base element. + */ + moveBelow: function (child1, child2) + { + return ArrayUtils.MoveBelow(this.list, child1, child2); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Removes one or many items from the List. + * + * @method Phaser.Structs.List#remove + * @since 3.0.0 + * + * @genericUse {T} - [child,$return] + * + * @param {*} child - The item, or array of items, to remove. + * @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback. + * + * @return {*} The item, or array of items, which were successfully removed from the List. + */ + remove: function (child, skipCallback) + { + if (skipCallback) + { + return ArrayUtils.Remove(this.list, child); + } + else + { + return ArrayUtils.Remove(this.list, child, this.removeCallback, this); + } + }, -var Point = __webpack_require__(4); + /** + * Removes the item at the given position in the List. + * + * @method Phaser.Structs.List#removeAt + * @since 3.0.0 + * + * @genericUse {T} - [$return] + * + * @param {number} index - The position to remove the item from. + * @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback. + * + * @return {*} The item that was removed. + */ + removeAt: function (index, skipCallback) + { + if (skipCallback) + { + return ArrayUtils.RemoveAt(this.list, index); + } + else + { + return ArrayUtils.RemoveAt(this.list, index, this.removeCallback, this); + } + }, -/** - * Get the centroid or geometric center of a plane figure (the arithmetic mean position of all the points in the figure). - * Informally, it is the point at which a cutout of the shape could be perfectly balanced on the tip of a pin. - * - * @function Phaser.Geom.Point.GetCentroid - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Types.Math.Vector2Like[]} points - An array of Vector2Like objects to get the geometric center of. - * @param {Phaser.Geom.Point} [out] - A Point object to store the output coordinates in. If not given, a new Point instance is created. - * - * @return {Phaser.Geom.Point} A Point object representing the geometric center of the given points. - */ -var GetCentroid = function (points, out) -{ - if (out === undefined) { out = new Point(); } + /** + * Removes the items within the given range in the List. + * + * @method Phaser.Structs.List#removeBetween + * @since 3.0.0 + * + * @genericUse {T[]} - [$return] + * + * @param {number} [startIndex=0] - The index to start removing from. + * @param {number} [endIndex] - The position to stop removing at. The item at this position won't be removed. + * @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback. + * + * @return {Array.<*>} An array of the items which were removed. + */ + removeBetween: function (startIndex, endIndex, skipCallback) + { + if (skipCallback) + { + return ArrayUtils.RemoveBetween(this.list, startIndex, endIndex); + } + else + { + return ArrayUtils.RemoveBetween(this.list, startIndex, endIndex, this.removeCallback, this); + } + }, - if (!Array.isArray(points)) + /** + * Removes all the items. + * + * @method Phaser.Structs.List#removeAll + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.List.} - [$return] + * + * @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback. + * + * @return {Phaser.Structs.List} This List object. + */ + removeAll: function (skipCallback) { - throw new Error('GetCentroid points argument must be an array'); - } + var i = this.list.length; - var len = points.length; + while (i--) + { + this.remove(this.list[i], skipCallback); + } - if (len < 1) + return this; + }, + + /** + * Brings the given child to the top of this List. + * + * @method Phaser.Structs.List#bringToTop + * @since 3.0.0 + * + * @genericUse {T} - [child,$return] + * + * @param {*} child - The item to bring to the top of the List. + * + * @return {*} The item which was moved. + */ + bringToTop: function (child) { - throw new Error('GetCentroid points array must not be empty'); - } - else if (len === 1) + return ArrayUtils.BringToTop(this.list, child); + }, + + /** + * Sends the given child to the bottom of this List. + * + * @method Phaser.Structs.List#sendToBack + * @since 3.0.0 + * + * @genericUse {T} - [child,$return] + * + * @param {*} child - The item to send to the back of the list. + * + * @return {*} The item which was moved. + */ + sendToBack: function (child) { - out.x = points[0].x; - out.y = points[0].y; - } - else + return ArrayUtils.SendToBack(this.list, child); + }, + + /** + * Moves the given child up one place in this group unless it's already at the top. + * + * @method Phaser.Structs.List#moveUp + * @since 3.0.0 + * + * @genericUse {T} - [child,$return] + * + * @param {*} child - The item to move up. + * + * @return {*} The item which was moved. + */ + moveUp: function (child) { - for (var i = 0; i < len; i++) - { - out.x += points[i].x; - out.y += points[i].y; - } + ArrayUtils.MoveUp(this.list, child); - out.x /= len; - out.y /= len; - } + return child; + }, - return out; -}; + /** + * Moves the given child down one place in this group unless it's already at the bottom. + * + * @method Phaser.Structs.List#moveDown + * @since 3.0.0 + * + * @genericUse {T} - [child,$return] + * + * @param {*} child - The item to move down. + * + * @return {*} The item which was moved. + */ + moveDown: function (child) + { + ArrayUtils.MoveDown(this.list, child); -module.exports = GetCentroid; + return child; + }, + /** + * Reverses the order of all children in this List. + * + * @method Phaser.Structs.List#reverse + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.List.} - [$return] + * + * @return {Phaser.Structs.List} This List object. + */ + reverse: function () + { + this.list.reverse(); -/***/ }), -/* 1253 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Shuffles the items in the list. + * + * @method Phaser.Structs.List#shuffle + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.List.} - [$return] + * + * @return {Phaser.Structs.List} This List object. + */ + shuffle: function () + { + ArrayUtils.Shuffle(this.list); -var Rectangle = __webpack_require__(10); + return this; + }, -/** - * Calculates the Axis Aligned Bounding Box (or aabb) from an array of points. - * - * @function Phaser.Geom.Point.GetRectangleFromPoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [out,$return] - * - * @param {Phaser.Types.Math.Vector2Like[]} points - An array of Vector2Like objects to get the AABB from. - * @param {Phaser.Geom.Rectangle} [out] - A Rectangle object to store the results in. If not given, a new Rectangle instance is created. - * - * @return {Phaser.Geom.Rectangle} A Rectangle object holding the AABB values for the given points. - */ -var GetRectangleFromPoints = function (points, out) -{ - if (out === undefined) { out = new Rectangle(); } + /** + * Replaces a child of this List with the given newChild. The newChild cannot be a member of this List. + * + * @method Phaser.Structs.List#replace + * @since 3.0.0 + * + * @genericUse {T} - [oldChild,newChild,$return] + * + * @param {*} oldChild - The child in this List that will be replaced. + * @param {*} newChild - The child to be inserted into this List. + * + * @return {*} Returns the oldChild that was replaced within this group. + */ + replace: function (oldChild, newChild) + { + return ArrayUtils.Replace(this.list, oldChild, newChild); + }, - var xMax = Number.NEGATIVE_INFINITY; - var xMin = Number.POSITIVE_INFINITY; - var yMax = Number.NEGATIVE_INFINITY; - var yMin = Number.POSITIVE_INFINITY; + /** + * Checks if an item exists within the List. + * + * @method Phaser.Structs.List#exists + * @since 3.0.0 + * + * @genericUse {T} - [child] + * + * @param {*} child - The item to check for the existence of. + * + * @return {boolean} `true` if the item is found in the list, otherwise `false`. + */ + exists: function (child) + { + return (this.list.indexOf(child) > -1); + }, - for (var i = 0; i < points.length; i++) + /** + * Sets the property `key` to the given value on all members of this List. + * + * @method Phaser.Structs.List#setAll + * @since 3.0.0 + * + * @genericUse {T} - [value] + * + * @param {string} property - The name of the property to set. + * @param {*} value - The value to set the property to. + * @param {number} [startIndex] - The first child index to start the search from. + * @param {number} [endIndex] - The last child index to search up until. + */ + setAll: function (property, value, startIndex, endIndex) { - var point = points[i]; + ArrayUtils.SetAll(this.list, property, value, startIndex, endIndex); - if (point.x > xMax) - { - xMax = point.x; - } + return this; + }, - if (point.x < xMin) - { - xMin = point.x; - } + /** + * Passes all children to the given callback. + * + * @method Phaser.Structs.List#each + * @since 3.0.0 + * + * @genericUse {EachListCallback.} - [callback] + * + * @param {EachListCallback} callback - The function to call. + * @param {*} [context] - Value to use as `this` when executing callback. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + */ + each: function (callback, context) + { + var args = [ null ]; - if (point.y > yMax) + for (var i = 2; i < arguments.length; i++) { - yMax = point.y; + args.push(arguments[i]); } - if (point.y < yMin) + for (i = 0; i < this.list.length; i++) { - yMin = point.y; + args[0] = this.list[i]; + + callback.apply(context, args); } - } + }, - out.x = xMin; - out.y = yMin; - out.width = xMax - xMin; - out.height = yMax - yMin; + /** + * Clears the List and recreates its internal array. + * + * @method Phaser.Structs.List#shutdown + * @since 3.0.0 + */ + shutdown: function () + { + this.removeAll(); - return out; -}; + this.list = []; + }, -module.exports = GetRectangleFromPoints; + /** + * Destroys this List. + * + * @method Phaser.Structs.List#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.removeAll(); + this.parent = null; + this.addCallback = null; + this.removeCallback = null; + }, -/***/ }), -/* 1254 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The number of items inside the List. + * + * @name Phaser.Structs.List#length + * @type {number} + * @readonly + * @since 3.0.0 + */ + length: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this.list.length; + } -var Point = __webpack_require__(4); + }, -/** - * Returns the linear interpolation point between the two given points, based on `t`. - * - * @function Phaser.Geom.Point.Interpolate - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Point} pointA - The starting `Point` for the interpolation. - * @param {Phaser.Geom.Point} pointB - The target `Point` for the interpolation. - * @param {number} [t=0] - The amount to interpolate between the two points. Generally, a value between 0 (returns the starting `Point`) and 1 (returns the target `Point`). If omitted, 0 is used. - * @param {(Phaser.Geom.Point|object)} [out] - An optional `Point` object whose `x` and `y` values will be set to the result of the interpolation (can also be any object with `x` and `y` properties). If omitted, a new `Point` created and returned. - * - * @return {(Phaser.Geom.Point|object)} Either the object from the `out` argument with the properties `x` and `y` set to the result of the interpolation or a newly created `Point` object. - */ -var Interpolate = function (pointA, pointB, t, out) -{ - if (t === undefined) { t = 0; } - if (out === undefined) { out = new Point(); } + /** + * The first item in the List or `null` for an empty List. + * + * @name Phaser.Structs.List#first + * @genericUse {T} - [$type] + * @type {*} + * @readonly + * @since 3.0.0 + */ + first: { - out.x = pointA.x + ((pointB.x - pointA.x) * t); - out.y = pointA.y + ((pointB.y - pointA.y) * t); + get: function () + { + this.position = 0; - return out; -}; + if (this.list.length > 0) + { + return this.list[0]; + } + else + { + return null; + } + } -module.exports = Interpolate; + }, + + /** + * The last item in the List, or `null` for an empty List. + * + * @name Phaser.Structs.List#last + * @genericUse {T} - [$type] + * @type {*} + * @readonly + * @since 3.0.0 + */ + last: { + + get: function () + { + if (this.list.length > 0) + { + this.position = this.list.length - 1; + return this.list[this.position]; + } + else + { + return null; + } + } -/***/ }), -/* 1255 */ -/***/ (function(module, exports) { + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The next item in the List, or `null` if the entire List has been traversed. + * + * This property can be read successively after reading {@link #first} or manually setting the {@link #position} to iterate the List. + * + * @name Phaser.Structs.List#next + * @genericUse {T} - [$type] + * @type {*} + * @readonly + * @since 3.0.0 + */ + next: { -/** - * Swaps the X and the Y coordinate of a point. - * - * @function Phaser.Geom.Point.Invert - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [point,$return] - * - * @param {Phaser.Geom.Point} point - The Point to modify. - * - * @return {Phaser.Geom.Point} The modified `point`. - */ -var Invert = function (point) -{ - return point.setTo(point.y, point.x); -}; + get: function () + { + if (this.position < this.list.length) + { + this.position++; -module.exports = Invert; + return this.list[this.position]; + } + else + { + return null; + } + } + }, -/***/ }), -/* 1256 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The previous item in the List, or `null` if the entire List has been traversed. + * + * This property can be read successively after reading {@link #last} or manually setting the {@link #position} to iterate the List backwards. + * + * @name Phaser.Structs.List#previous + * @genericUse {T} - [$type] + * @type {*} + * @readonly + * @since 3.0.0 + */ + previous: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + if (this.position > 0) + { + this.position--; -var Point = __webpack_require__(4); + return this.list[this.position]; + } + else + { + return null; + } + } -/** - * Inverts a Point's coordinates. - * - * @function Phaser.Geom.Point.Negative - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Point} point - The Point to invert. - * @param {Phaser.Geom.Point} [out] - The Point to return the inverted coordinates in. - * - * @return {Phaser.Geom.Point} The modified `out` Point, or a new Point if none was provided. - */ -var Negative = function (point, out) -{ - if (out === undefined) { out = new Point(); } + } - return out.setTo(-point.x, -point.y); -}; +}); -module.exports = Negative; +module.exports = List; /***/ }), -/* 1257 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 33885: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Point = __webpack_require__(4); -var GetMagnitudeSq = __webpack_require__(501); +var Class = __webpack_require__(56694); /** - * Calculates the vector projection of `pointA` onto the nonzero `pointB`. This is the - * orthogonal projection of `pointA` onto a straight line parallel to `pointB`. - * - * @function Phaser.Geom.Point.Project - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] + * @callback EachMapCallback * - * @param {Phaser.Geom.Point} pointA - Point A, to be projected onto Point B. - * @param {Phaser.Geom.Point} pointB - Point B, to have Point A projected upon it. - * @param {Phaser.Geom.Point} [out] - The Point object to store the position in. If not given, a new Point instance is created. + * @param {string} key - The key of the Map entry. + * @param {E} entry - The value of the Map entry. * - * @return {Phaser.Geom.Point} A Point object holding the coordinates of the vector projection of `pointA` onto `pointB`. - */ -var Project = function (pointA, pointB, out) -{ - if (out === undefined) { out = new Point(); } - - var dot = ((pointA.x * pointB.x) + (pointA.y * pointB.y)); - var amt = dot / GetMagnitudeSq(pointB); - - if (amt !== 0) - { - out.x = amt * pointB.x; - out.y = amt * pointB.y; - } - - return out; -}; - -module.exports = Project; - - -/***/ }), -/* 1258 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @return {?boolean} The callback result. */ -var Point = __webpack_require__(4); - /** - * Calculates the vector projection of `pointA` onto the nonzero `pointB`. This is the - * orthogonal projection of `pointA` onto a straight line paralle to `pointB`. + * @classdesc + * The keys of a Map can be arbitrary values. * - * @function Phaser.Geom.Point.ProjectUnit - * @since 3.0.0 + * ```javascript + * var map = new Map([ + * [ 1, 'one' ], + * [ 2, 'two' ], + * [ 3, 'three' ] + * ]); + * ``` * - * @generic {Phaser.Geom.Point} O - [out,$return] + * @class Map + * @memberof Phaser.Structs + * @constructor + * @since 3.0.0 * - * @param {Phaser.Geom.Point} pointA - Point A, to be projected onto Point B. Must be a normalized point with a magnitude of 1. - * @param {Phaser.Geom.Point} pointB - Point B, to have Point A projected upon it. - * @param {Phaser.Geom.Point} [out] - The Point object to store the position in. If not given, a new Point instance is created. + * @generic K + * @generic V + * @genericUse {V[]} - [elements] * - * @return {Phaser.Geom.Point} A unit Point object holding the coordinates of the vector projection of `pointA` onto `pointB`. + * @param {Array.<*>} elements - An optional array of key-value pairs to populate this Map with. */ -var ProjectUnit = function (pointA, pointB, out) -{ - if (out === undefined) { out = new Point(); } +var Map = new Class({ - var amt = ((pointA.x * pointB.x) + (pointA.y * pointB.y)); + initialize: - if (amt !== 0) + function Map (elements) { - out.x = amt * pointB.x; - out.y = amt * pointB.y; - } - - return out; -}; + /** + * The entries in this Map. + * + * @genericUse {Object.} - [$type] + * + * @name Phaser.Structs.Map#entries + * @type {Object.} + * @default {} + * @since 3.0.0 + */ + this.entries = {}; -module.exports = ProjectUnit; + /** + * The number of key / value pairs in this Map. + * + * @name Phaser.Structs.Map#size + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.size = 0; + if (Array.isArray(elements)) + { + for (var i = 0; i < elements.length; i++) + { + this.set(elements[i][0], elements[i][1]); + } + } + }, -/***/ }), -/* 1259 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Adds an element with a specified `key` and `value` to this Map. + * If the `key` already exists, the value will be replaced. + * + * @method Phaser.Structs.Map#set + * @since 3.0.0 + * + * @genericUse {K} - [key] + * @genericUse {V} - [value] + * @genericUse {Phaser.Structs.Map.} - [$return] + * + * @param {string} key - The key of the element to be added to this Map. + * @param {*} value - The value of the element to be added to this Map. + * + * @return {Phaser.Structs.Map} This Map object. + */ + set: function (key, value) + { + if (!this.has(key)) + { + this.size++; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.entries[key] = value; -var GetMagnitude = __webpack_require__(500); + return this; + }, -/** - * Changes the magnitude (length) of a two-dimensional vector without changing its direction. - * - * @function Phaser.Geom.Point.SetMagnitude - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [point,$return] - * - * @param {Phaser.Geom.Point} point - The Point to treat as the end point of the vector. - * @param {number} magnitude - The new magnitude of the vector. - * - * @return {Phaser.Geom.Point} The modified Point. - */ -var SetMagnitude = function (point, magnitude) -{ - if (point.x !== 0 || point.y !== 0) + /** + * Returns the value associated to the `key`, or `undefined` if there is none. + * + * @method Phaser.Structs.Map#get + * @since 3.0.0 + * + * @genericUse {K} - [key] + * @genericUse {V} - [$return] + * + * @param {string} key - The key of the element to return from the `Map` object. + * + * @return {*} The element associated with the specified key or `undefined` if the key can't be found in this Map object. + */ + get: function (key) { - var m = GetMagnitude(point); + if (this.has(key)) + { + return this.entries[key]; + } + }, - point.x /= m; - point.y /= m; - } + /** + * Returns an `Array` of all the values stored in this Map. + * + * @method Phaser.Structs.Map#getArray + * @since 3.0.0 + * + * @genericUse {V[]} - [$return] + * + * @return {Array.<*>} An array of the values stored in this Map. + */ + getArray: function () + { + var output = []; + var entries = this.entries; - point.x *= magnitude; - point.y *= magnitude; + for (var key in entries) + { + output.push(entries[key]); + } - return point; -}; + return output; + }, -module.exports = SetMagnitude; + /** + * Returns a boolean indicating whether an element with the specified key exists or not. + * + * @method Phaser.Structs.Map#has + * @since 3.0.0 + * + * @genericUse {K} - [key] + * + * @param {string} key - The key of the element to test for presence of in this Map. + * + * @return {boolean} Returns `true` if an element with the specified key exists in this Map, otherwise `false`. + */ + has: function (key) + { + return (this.entries.hasOwnProperty(key)); + }, + /** + * Delete the specified element from this Map. + * + * @method Phaser.Structs.Map#delete + * @since 3.0.0 + * + * @genericUse {K} - [key] + * @genericUse {Phaser.Structs.Map.} - [$return] + * + * @param {string} key - The key of the element to delete from this Map. + * + * @return {Phaser.Structs.Map} This Map object. + */ + delete: function (key) + { + if (this.has(key)) + { + delete this.entries[key]; + this.size--; + } -/***/ }), -/* 1260 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Delete all entries from this Map. + * + * @method Phaser.Structs.Map#clear + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.Map.} - [$return] + * + * @return {Phaser.Structs.Map} This Map object. + */ + clear: function () + { + Object.keys(this.entries).forEach(function (prop) + { + delete this.entries[prop]; -var Polygon = __webpack_require__(227); + }, this); -Polygon.Clone = __webpack_require__(1261); -Polygon.Contains = __webpack_require__(228); -Polygon.ContainsPoint = __webpack_require__(1262); -Polygon.Earcut = __webpack_require__(59); -Polygon.GetAABB = __webpack_require__(469); -Polygon.GetNumberArray = __webpack_require__(1263); -Polygon.GetPoints = __webpack_require__(470); -Polygon.Perimeter = __webpack_require__(471); -Polygon.Reverse = __webpack_require__(1264); -Polygon.Simplify = __webpack_require__(1265); -Polygon.Smooth = __webpack_require__(472); -Polygon.Translate = __webpack_require__(1266); + this.size = 0; -module.exports = Polygon; + return this; + }, + /** + * Returns all entries keys in this Map. + * + * @method Phaser.Structs.Map#keys + * @since 3.0.0 + * + * @genericUse {K[]} - [$return] + * + * @return {string[]} Array containing entries' keys. + */ + keys: function () + { + return Object.keys(this.entries); + }, -/***/ }), -/* 1261 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Returns an `Array` of all entries. + * + * @method Phaser.Structs.Map#values + * @since 3.0.0 + * + * @genericUse {V[]} - [$return] + * + * @return {Array.<*>} An `Array` of entries. + */ + values: function () + { + var output = []; + var entries = this.entries; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + for (var key in entries) + { + output.push(entries[key]); + } -var Polygon = __webpack_require__(227); + return output; + }, -/** - * Create a new polygon which is a copy of the specified polygon - * - * @function Phaser.Geom.Polygon.Clone - * @since 3.0.0 - * - * @param {Phaser.Geom.Polygon} polygon - The polygon to create a clone of - * - * @return {Phaser.Geom.Polygon} A new separate Polygon cloned from the specified polygon, based on the same points. - */ -var Clone = function (polygon) -{ - return new Polygon(polygon.points); -}; + /** + * Dumps the contents of this Map to the console via `console.group`. + * + * @method Phaser.Structs.Map#dump + * @since 3.0.0 + */ + dump: function () + { + var entries = this.entries; -module.exports = Clone; + // eslint-disable-next-line no-console + console.group('Map'); + for (var key in entries) + { + console.log(key, entries[key]); + } -/***/ }), -/* 1262 */ -/***/ (function(module, exports, __webpack_require__) { + // eslint-disable-next-line no-console + console.groupEnd(); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Iterates through all entries in this Map, passing each one to the given callback. + * + * If the callback returns `false`, the iteration will break. + * + * @method Phaser.Structs.Map#each + * @since 3.0.0 + * + * @genericUse {EachMapCallback.} - [callback] + * @genericUse {Phaser.Structs.Map.} - [$return] + * + * @param {EachMapCallback} callback - The callback which will receive the keys and entries held in this Map. + * + * @return {Phaser.Structs.Map} This Map object. + */ + each: function (callback) + { + var entries = this.entries; -var Contains = __webpack_require__(228); + for (var key in entries) + { + if (callback(key, entries[key]) === false) + { + break; + } + } -/** - * Checks the given Point again the Polygon to see if the Point lays within its vertices. - * - * @function Phaser.Geom.Polygon.ContainsPoint - * @since 3.0.0 - * - * @param {Phaser.Geom.Polygon} polygon - The Polygon to check. - * @param {Phaser.Geom.Point} point - The Point to check if it's within the Polygon. - * - * @return {boolean} `true` if the Point is within the Polygon, otherwise `false`. - */ -var ContainsPoint = function (polygon, point) -{ - return Contains(polygon, point.x, point.y); -}; + return this; + }, -module.exports = ContainsPoint; + /** + * Returns `true` if the value exists within this Map. Otherwise, returns `false`. + * + * @method Phaser.Structs.Map#contains + * @since 3.0.0 + * + * @genericUse {V} - [value] + * + * @param {*} value - The value to search for. + * + * @return {boolean} `true` if the value is found, otherwise `false`. + */ + contains: function (value) + { + var entries = this.entries; + for (var key in entries) + { + if (entries[key] === value) + { + return true; + } + } -/***/ }), -/* 1263 */ -/***/ (function(module, exports) { + return false; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Merges all new keys from the given Map into this one. + * If it encounters a key that already exists it will be skipped unless override is set to `true`. + * + * @method Phaser.Structs.Map#merge + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.Map.} - [map,$return] + * + * @param {Phaser.Structs.Map} map - The Map to merge in to this Map. + * @param {boolean} [override=false] - Set to `true` to replace values in this Map with those from the source map, or `false` to skip them. + * + * @return {Phaser.Structs.Map} This Map object. + */ + merge: function (map, override) + { + if (override === undefined) { override = false; } -// Export the points as an array of flat numbers, following the sequence [ x,y, x,y, x,y ] + var local = this.entries; + var source = map.entries; -/** - * Stores all of the points of a Polygon into a flat array of numbers following the sequence [ x,y, x,y, x,y ], - * i.e. each point of the Polygon, in the order it's defined, corresponds to two elements of the resultant - * array for the point's X and Y coordinate. - * - * @function Phaser.Geom.Polygon.GetNumberArray - * @since 3.0.0 - * - * @generic {number[]} O - [output,$return] - * - * @param {Phaser.Geom.Polygon} polygon - The Polygon whose points to export. - * @param {(array|number[])} [output] - An array to which the points' coordinates should be appended. - * - * @return {(array|number[])} The modified `output` array, or a new array if none was given. - */ -var GetNumberArray = function (polygon, output) -{ - if (output === undefined) { output = []; } + for (var key in source) + { + if (local.hasOwnProperty(key) && override) + { + local[key] = source[key]; + } + else + { + this.set(key, source[key]); + } + } - for (var i = 0; i < polygon.points.length; i++) - { - output.push(polygon.points[i].x); - output.push(polygon.points[i].y); + return this; } - return output; -}; +}); -module.exports = GetNumberArray; +module.exports = Map; /***/ }), -/* 1264 */ -/***/ (function(module, exports) { + +/***/ 74623: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * Reverses the order of the points of a Polygon. - * - * @function Phaser.Geom.Polygon.Reverse - * @since 3.0.0 - * - * @generic {Phaser.Geom.Polygon} O - [polygon,$return] - * - * @param {Phaser.Geom.Polygon} polygon - The Polygon to modify. - * - * @return {Phaser.Geom.Polygon} The modified Polygon. - */ -var Reverse = function (polygon) -{ - polygon.points.reverse(); - - return polygon; -}; - -module.exports = Reverse; - - -/***/ }), -/* 1265 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @author Vladimir Agafonkin - * @see Based on Simplify.js mourner.github.io/simplify-js - */ +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(36716); /** - * Copyright (c) 2017, Vladimir Agafonkin - * All rights reserved. + * @classdesc + * A Process Queue maintains three internal lists. * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: + * The `pending` list is a selection of items which are due to be made 'active' in the next update. + * The `active` list is a selection of items which are considered active and should be updated. + * The `destroy` list is a selection of items that were active and are awaiting being destroyed in the next update. * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. + * When new items are added to a Process Queue they are put in the pending list, rather than being added + * immediately the active list. Equally, items that are removed are put into the destroy list, rather than + * being destroyed immediately. This allows the Process Queue to carefully process each item at a specific, fixed + * time, rather than at the time of the request from the API. * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. + * @class ProcessQueue + * @extends Phaser.Events.EventEmitter + * @memberof Phaser.Structs + * @constructor + * @since 3.0.0 * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @ignore + * @generic T */ -function getSqDist (p1, p2) -{ - var dx = p1.x - p2.x, - dy = p1.y - p2.y; +var ProcessQueue = new Class({ - return dx * dx + dy * dy; -} + Extends: EventEmitter, -/** - * Square distance from a point to a segment - * - * @ignore - */ -function getSqSegDist (p, p1, p2) -{ - var x = p1.x, - y = p1.y, - dx = p2.x - x, - dy = p2.y - y; + initialize: - if (dx !== 0 || dy !== 0) + function ProcessQueue () { - var t = ((p.x - x) * dx + (p.y - y) * dy) / (dx * dx + dy * dy); - - if (t > 1) - { - x = p2.x; - y = p2.y; - } - else if (t > 0) - { - x += dx * t; - y += dy * t; - } - } + EventEmitter.call(this); - dx = p.x - x; - dy = p.y - y; + /** + * The `pending` list is a selection of items which are due to be made 'active' in the next update. + * + * @genericUse {T[]} - [$type] + * + * @name Phaser.Structs.ProcessQueue#_pending + * @type {Array.<*>} + * @private + * @default [] + * @since 3.0.0 + */ + this._pending = []; - return dx * dx + dy * dy; -} + /** + * The `active` list is a selection of items which are considered active and should be updated. + * + * @genericUse {T[]} - [$type] + * + * @name Phaser.Structs.ProcessQueue#_active + * @type {Array.<*>} + * @private + * @default [] + * @since 3.0.0 + */ + this._active = []; -/** - * Basic distance-based simplification - * - * @ignore - */ -function simplifyRadialDist (points, sqTolerance) -{ - var prevPoint = points[0], - newPoints = [ prevPoint ], - point; + /** + * The `destroy` list is a selection of items that were active and are awaiting being destroyed in the next update. + * + * @genericUse {T[]} - [$type] + * + * @name Phaser.Structs.ProcessQueue#_destroy + * @type {Array.<*>} + * @private + * @default [] + * @since 3.0.0 + */ + this._destroy = []; - for (var i = 1, len = points.length; i < len; i++) - { - point = points[i]; + /** + * The total number of items awaiting processing. + * + * @name Phaser.Structs.ProcessQueue#_toProcess + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._toProcess = 0; - if (getSqDist(point, prevPoint) > sqTolerance) - { - newPoints.push(point); - prevPoint = point; - } - } + /** + * If `true` only unique objects will be allowed in the queue. + * + * @name Phaser.Structs.ProcessQueue#checkQueue + * @type {boolean} + * @since 3.50.0 + */ + this.checkQueue = false; + }, - if (prevPoint !== point) + /** + * Checks the given item to see if it is already active within this Process Queue. + * + * @method Phaser.Structs.ProcessQueue#isActive + * @since 3.60.0 + * + * @genericUse {T} - [item] + * @genericUse {Phaser.Structs.ProcessQueue.} - [$return] + * + * @param {*} item - The item to check. + * + * @return {boolean} `true` if the item is active, otherwise `false`. + */ + isActive: function (item) { - newPoints.push(point); - } - - return newPoints; -} - -/** - * @ignore - */ -function simplifyDPStep (points, first, last, sqTolerance, simplified) -{ - var maxSqDist = sqTolerance, - index; + return (this._active.indexOf(item) > -1); + }, - for (var i = first + 1; i < last; i++) + /** + * Checks the given item to see if it is already pending addition to this Process Queue. + * + * @method Phaser.Structs.ProcessQueue#isPending + * @since 3.60.0 + * + * @genericUse {T} - [item] + * @genericUse {Phaser.Structs.ProcessQueue.} - [$return] + * + * @param {*} item - The item to check. + * + * @return {boolean} `true` if the item is pending insertion, otherwise `false`. + */ + isPending: function (item) { - var sqDist = getSqSegDist(points[i], points[first], points[last]); + return (this._toProcess > 0 && this._pending.indexOf(item) > -1); + }, - if (sqDist > maxSqDist) - { - index = i; - maxSqDist = sqDist; - } - } + /** + * Checks the given item to see if it is already pending destruction from this Process Queue. + * + * @method Phaser.Structs.ProcessQueue#isDestroying + * @since 3.60.0 + * + * @genericUse {T} - [item] + * @genericUse {Phaser.Structs.ProcessQueue.} - [$return] + * + * @param {*} item - The item to check. + * + * @return {boolean} `true` if the item is pending destruction, otherwise `false`. + */ + isDestroying: function (item) + { + return (this._destroy.indexOf(item) > -1); + }, - if (maxSqDist > sqTolerance) + /** + * Adds a new item to the Process Queue. + * + * The item is added to the pending list and made active in the next update. + * + * @method Phaser.Structs.ProcessQueue#add + * @since 3.0.0 + * + * @genericUse {T} - [item] + * @genericUse {Phaser.Structs.ProcessQueue.} - [$return] + * + * @param {*} item - The item to add to the queue. + * + * @return {*} The item that was added. + */ + add: function (item) { - if (index - first > 1) + // Don't add if already active or pending, but DO add if active AND in the destroy list + if (this.checkQueue && (this.isActive() && !this.isDestroying()) || this.isPending()) { - simplifyDPStep(points, first, index, sqTolerance, simplified); + return item; } - simplified.push(points[index]); + this._pending.push(item); - if (last - index > 1) - { - simplifyDPStep(points, index, last, sqTolerance, simplified); - } - } -} + this._toProcess++; -/** - * Simplification using Ramer-Douglas-Peucker algorithm - * - * @ignore - */ -function simplifyDouglasPeucker (points, sqTolerance) -{ - var last = points.length - 1; + return item; + }, - var simplified = [ points[0] ]; + /** + * Removes an item from the Process Queue. + * + * The item is added to the 'destroy' list and is fully removed in the next update. + * + * @method Phaser.Structs.ProcessQueue#remove + * @since 3.0.0 + * + * @genericUse {T} - [item] + * @genericUse {Phaser.Structs.ProcessQueue.} - [$return] + * + * @param {*} item - The item to be removed from the queue. + * + * @return {*} The item that was removed. + */ + remove: function (item) + { + // Check if it's in the _pending list + if (this.isPending(item)) + { + var pending = this._pending; - simplifyDPStep(points, 0, last, sqTolerance, simplified); + var idx = pending.indexOf(item); - simplified.push(points[last]); + if (idx !== -1) + { + // Remove directly, no need to wait for an update loop + pending.splice(idx, 1); + } + } + else if (this.isActive(item)) + { + // Item is actively running? Queue it for deletion + this._destroy.push(item); - return simplified; -} + this._toProcess++; + } -/** - * Takes a Polygon object and simplifies the points by running them through a combination of - * Douglas-Peucker and Radial Distance algorithms. Simplification dramatically reduces the number of - * points in a polygon while retaining its shape, giving a huge performance boost when processing - * it and also reducing visual noise. - * - * @function Phaser.Geom.Polygon.Simplify - * @since 3.50.0 - * - * @generic {Phaser.Geom.Polygon} O - [polygon,$return] - * - * @param {Phaser.Geom.Polygon} polygon - The polygon to be simplified. The polygon will be modified in-place and returned. - * @param {number} [tolerance=1] - Affects the amount of simplification (in the same metric as the point coordinates). - * @param {boolean} [highestQuality=false] - Excludes distance-based preprocessing step which leads to highest quality simplification but runs ~10-20 times slower. - * - * @return {Phaser.Geom.Polygon} The input polygon. - */ -var Simplify = function (polygon, tolerance, highestQuality) -{ - if (tolerance === undefined) { tolerance = 1; } - if (highestQuality === undefined) { highestQuality = false; } + // If neither of the above conditions pass, then the item is either already in the destroy list, + // or isn't pending or active, so cannot be removed anyway - var points = polygon.points; + return item; + }, - if (points.length > 2) + /** + * Removes all active items from this Process Queue. + * + * All the items are marked as 'pending destroy' and fully removed in the next update. + * + * @method Phaser.Structs.ProcessQueue#removeAll + * @since 3.20.0 + * + * @return {this} This Process Queue object. + */ + removeAll: function () { - var sqTolerance = tolerance * tolerance; + var list = this._active; + var destroy = this._destroy; + var i = list.length; - if (!highestQuality) + while (i--) { - points = simplifyRadialDist(points, sqTolerance); - } - - polygon.setTo(simplifyDouglasPeucker(points, sqTolerance)); - } - - return polygon; -}; - -module.exports = Simplify; - - -/***/ }), -/* 1266 */ -/***/ (function(module, exports) { + destroy.push(list[i]); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this._toProcess++; + } -/** - * Tranlates the points of the given Polygon. - * - * @function Phaser.Geom.Polygon.Translate - * @since 3.50.0 - * - * @generic {Phaser.Geom.Polygon} O - [polygon,$return] - * - * @param {Phaser.Geom.Polygon} polygon - The Polygon to modify. - * @param {number} x - The amount to horizontally translate the points by. - * @param {number} y - The amount to vertically translate the points by. - * - * @return {Phaser.Geom.Polygon} The modified Polygon. - */ -var Translate = function (polygon, x, y) -{ - var points = polygon.points; + return this; + }, - for (var i = 0; i < points.length; i++) + /** + * Update this queue. First it will process any items awaiting destruction, and remove them. + * + * Then it will check to see if there are any items pending insertion, and move them to an + * active state. Finally, it will return a list of active items for further processing. + * + * @method Phaser.Structs.ProcessQueue#update + * @since 3.0.0 + * + * @genericUse {T[]} - [$return] + * + * @return {Array.<*>} A list of active items. + */ + update: function () { - points[i].x += x; - points[i].y += y; - } - - return polygon; -}; - -module.exports = Translate; - + if (this._toProcess === 0) + { + // Quick bail + return this._active; + } -/***/ }), -/* 1267 */ -/***/ (function(module, exports) { + var list = this._destroy; + var active = this._active; + var i; + var item; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Clear the 'destroy' list + for (i = 0; i < list.length; i++) + { + item = list[i]; -/** - * Calculates the area of the given Rectangle object. - * - * @function Phaser.Geom.Rectangle.Area - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rect - The rectangle to calculate the area of. - * - * @return {number} The area of the Rectangle object. - */ -var Area = function (rect) -{ - return rect.width * rect.height; -}; + // Remove from the 'active' array + var idx = active.indexOf(item); -module.exports = Area; + if (idx !== -1) + { + active.splice(idx, 1); + this.emit(Events.PROCESS_QUEUE_REMOVE, item); + } + } -/***/ }), -/* 1268 */ -/***/ (function(module, exports) { + list.length = 0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Process the pending addition list + // This stops callbacks and out of sync events from populating the active array mid-way during an update -/** - * Rounds a Rectangle's position up to the smallest integer greater than or equal to each current coordinate. - * - * @function Phaser.Geom.Rectangle.Ceil - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to adjust. - * - * @return {Phaser.Geom.Rectangle} The adjusted Rectangle. - */ -var Ceil = function (rect) -{ - rect.x = Math.ceil(rect.x); - rect.y = Math.ceil(rect.y); + list = this._pending; - return rect; -}; + for (i = 0; i < list.length; i++) + { + item = list[i]; -module.exports = Ceil; + if (!this.checkQueue || (this.checkQueue && active.indexOf(item) === -1)) + { + active.push(item); + this.emit(Events.PROCESS_QUEUE_ADD, item); + } + } -/***/ }), -/* 1269 */ -/***/ (function(module, exports) { + list.length = 0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this._toProcess = 0; -/** - * Rounds a Rectangle's position and size up to the smallest integer greater than or equal to each respective value. - * - * @function Phaser.Geom.Rectangle.CeilAll - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to modify. - * - * @return {Phaser.Geom.Rectangle} The modified Rectangle. - */ -var CeilAll = function (rect) -{ - rect.x = Math.ceil(rect.x); - rect.y = Math.ceil(rect.y); - rect.width = Math.ceil(rect.width); - rect.height = Math.ceil(rect.height); + // The owner of this queue can now safely do whatever it needs to with the active list + return active; + }, - return rect; -}; + /** + * Returns the current list of active items. + * + * This method returns a reference to the active list array, not a copy of it. + * Therefore, be careful to not modify this array outside of the ProcessQueue. + * + * @method Phaser.Structs.ProcessQueue#getActive + * @since 3.0.0 + * + * @genericUse {T[]} - [$return] + * + * @return {Array.<*>} A list of active items. + */ + getActive: function () + { + return this._active; + }, -module.exports = CeilAll; + /** + * The number of entries in the active list. + * + * @name Phaser.Structs.ProcessQueue#length + * @type {number} + * @readonly + * @since 3.20.0 + */ + length: { + get: function () + { + return this._active.length; + } -/***/ }), -/* 1270 */ -/***/ (function(module, exports, __webpack_require__) { + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Immediately destroys this process queue, clearing all of its internal arrays and resetting the process totals. + * + * @method Phaser.Structs.ProcessQueue#destroy + * @since 3.0.0 + */ + destroy: function () + { + this._toProcess = 0; -var Rectangle = __webpack_require__(10); + this._pending = []; + this._active = []; + this._destroy = []; + } -/** - * Creates a new Rectangle which is identical to the given one. - * - * @function Phaser.Geom.Rectangle.Clone - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} source - The Rectangle to clone. - * - * @return {Phaser.Geom.Rectangle} The newly created Rectangle, which is separate from the given one. - */ -var Clone = function (source) -{ - return new Rectangle(source.x, source.y, source.width, source.height); -}; +}); -module.exports = Clone; +module.exports = ProcessQueue; /***/ }), -/* 1271 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 68687: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** + * @author Vladimir Agafonkin * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Contains = __webpack_require__(57); +var quickselect = __webpack_require__(53466); /** - * Determines whether the specified point is contained within the rectangular region defined by this Rectangle object. + * @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. * - * @function Phaser.Geom.Rectangle.ContainsPoint - * @since 3.0.0 + * 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). * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle object. - * @param {Phaser.Geom.Point} point - The point object to be checked. Can be a Phaser Point object or any object with x and y values. + * 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. * - * @return {boolean} A value of true if the Rectangle object contains the specified point, otherwise false. + * rbush is forked from https://github.com/mourner/rbush by Vladimir Agafonkin + * + * @class RTree + * @memberof Phaser.Structs + * @constructor + * @since 3.0.0 */ -var ContainsPoint = function (rect, point) + +function rbush (maxEntries) { - return Contains(rect, point.x, point.y); -}; + var format = [ '.left', '.top', '.right', '.bottom' ]; -module.exports = ContainsPoint; + 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)); -/***/ }), -/* 1272 */ -/***/ (function(module, exports) { + this.clear(); +} -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +rbush.prototype = { -/** - * Copy the values of one Rectangle to a destination Rectangle. - * - * @function Phaser.Geom.Rectangle.CopyFrom - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [dest,$return] - * - * @param {Phaser.Geom.Rectangle} source - The source Rectangle to copy the values from. - * @param {Phaser.Geom.Rectangle} dest - The destination Rectangle to copy the values to. - * - * @return {Phaser.Geom.Rectangle} The destination Rectangle. - */ -var CopyFrom = function (source, dest) -{ - return dest.setTo(source.x, source.y, source.width, source.height); -}; + all: function () + { + return this._all(this.data, []); + }, -module.exports = CopyFrom; + search: function (bbox) + { + var node = this.data, + result = [], + toBBox = this.toBBox; + if (!intersects(bbox, node)) return result; -/***/ }), -/* 1273 */ -/***/ (function(module, exports) { + var nodesToSearch = [], + i, len, child, childBBox; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + while (node) { + for (i = 0, len = node.children.length; i < len; i++) { -/** - * Compares the `x`, `y`, `width` and `height` properties of two rectangles. - * - * @function Phaser.Geom.Rectangle.Equals - * @since 3.0.0 - * - * @param {Phaser.Geom.Rectangle} rect - Rectangle A - * @param {Phaser.Geom.Rectangle} toCompare - Rectangle B - * - * @return {boolean} `true` if the rectangles' properties are an exact match, otherwise `false`. - */ -var Equals = function (rect, toCompare) -{ - return ( - rect.x === toCompare.x && - rect.y === toCompare.y && - rect.width === toCompare.width && - rect.height === toCompare.height - ); -}; + child = node.children[i]; + childBBox = node.leaf ? toBBox(child) : child; -module.exports = Equals; + 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; + }, -/***/ }), -/* 1274 */ -/***/ (function(module, exports, __webpack_require__) { + collides: function (bbox) + { + var node = this.data, + toBBox = this.toBBox; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!intersects(bbox, node)) return false; -var GetAspectRatio = __webpack_require__(237); + var nodesToSearch = [], + i, len, child, childBBox; -/** - * Adjusts the target rectangle, changing its width, height and position, - * so that it fits inside the area of the source rectangle, while maintaining its original - * aspect ratio. - * - * Unlike the `FitOutside` function, there may be some space inside the source area not covered. - * - * @function Phaser.Geom.Rectangle.FitInside - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [target,$return] - * - * @param {Phaser.Geom.Rectangle} target - The target rectangle to adjust. - * @param {Phaser.Geom.Rectangle} source - The source rectangle to envelop the target in. - * - * @return {Phaser.Geom.Rectangle} The modified target rectangle instance. - */ -var FitInside = function (target, source) -{ - var ratio = GetAspectRatio(target); + while (node) { + for (i = 0, len = node.children.length; i < len; i++) { - if (ratio < GetAspectRatio(source)) - { - // Taller than Wide - target.setSize(source.height * ratio, source.height); - } - else + 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) { - // Wider than Tall - target.setSize(source.width, source.width / ratio); - } + if (!(data && data.length)) return this; - return target.setPosition( - source.centerX - (target.width / 2), - source.centerY - (target.height / 2) - ); -}; + if (data.length < this._minEntries) { + for (var i = 0, len = data.length; i < len; i++) { + this.insert(data[i]); + } + return this; + } -module.exports = FitInside; + // 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; -/***/ }), -/* 1275 */ -/***/ (function(module, exports, __webpack_require__) { + } else if (this.data.height === node.height) { + // split root if trees have the same height + this._splitRoot(this.data, node); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + } else { + if (this.data.height < node.height) { + // swap trees if inserted one is bigger + var tmpNode = this.data; + this.data = node; + node = tmpNode; + } -var GetAspectRatio = __webpack_require__(237); + // insert the small tree into the large tree at appropriate level + this._insert(node, this.data.height - node.height - 1, true); + } -/** - * Adjusts the target rectangle, changing its width, height and position, - * so that it fully covers the area of the source rectangle, while maintaining its original - * aspect ratio. - * - * Unlike the `FitInside` function, the target rectangle may extend further out than the source. - * - * @function Phaser.Geom.Rectangle.FitOutside - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [target,$return] - * - * @param {Phaser.Geom.Rectangle} target - The target rectangle to adjust. - * @param {Phaser.Geom.Rectangle} source - The source rectangle to envelope the target in. - * - * @return {Phaser.Geom.Rectangle} The modified target rectangle instance. - */ -var FitOutside = function (target, source) -{ - var ratio = GetAspectRatio(target); + return this; + }, - if (ratio > GetAspectRatio(source)) + insert: function (item) { - // Wider than Tall - target.setSize(source.height * ratio, source.height); - } - else + if (item) this._insert(item, this.data.height - 1); + return this; + }, + + clear: function () { - // Taller than Wide - target.setSize(source.width, source.width / ratio); - } + this.data = createNode([]); + return this; + }, - return target.setPosition( - source.centerX - target.width / 2, - source.centerY - target.height / 2 - ); -}; + remove: function (item, equalsFn) + { + if (!item) return this; -module.exports = FitOutside; + var node = this.data, + bbox = this.toBBox(item), + path = [], + indexes = [], + i, parent, index, goingUp; + // depth-first iterative tree traversal + while (node || path.length) { -/***/ }), -/* 1276 */ -/***/ (function(module, exports) { + if (!node) { // go up + node = path.pop(); + parent = path[path.length - 1]; + i = indexes.pop(); + goingUp = true; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (node.leaf) { // check current node + index = findItem(item, node.children, equalsFn); -/** - * Rounds down (floors) the top left X and Y coordinates of the given Rectangle to the largest integer less than or equal to them - * - * @function Phaser.Geom.Rectangle.Floor - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The rectangle to floor the top left X and Y coordinates of - * - * @return {Phaser.Geom.Rectangle} The rectangle that was passed to this function with its coordinates floored. - */ -var Floor = function (rect) -{ - rect.x = Math.floor(rect.x); - rect.y = Math.floor(rect.y); + 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; + } + } - return rect; -}; + if (!goingUp && !node.leaf && contains(node, bbox)) { // go down + path.push(node); + indexes.push(i); + i = 0; + parent = node; + node = node.children[0]; -module.exports = Floor; + } else if (parent) { // go right + i++; + node = parent.children[i]; + goingUp = false; + } else node = null; // nothing found + } -/***/ }), -/* 1277 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + toBBox: function (item) { return item; }, -/** - * Rounds a Rectangle's position and size down to the largest integer less than or equal to each current coordinate or dimension. - * - * @function Phaser.Geom.Rectangle.FloorAll - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to adjust. - * - * @return {Phaser.Geom.Rectangle} The adjusted Rectangle. - */ -var FloorAll = function (rect) -{ - rect.x = Math.floor(rect.x); - rect.y = Math.floor(rect.y); - rect.width = Math.floor(rect.width); - rect.height = Math.floor(rect.height); + compareMinX: compareNodeMinX, + compareMinY: compareNodeMinY, - return rect; -}; + toJSON: function () { return this.data; }, -module.exports = FloorAll; + 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); -/***/ }), -/* 1278 */ -/***/ (function(module, exports, __webpack_require__) { + node = nodesToSearch.pop(); + } + return result; + }, -/** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + _build: function (items, left, right, height) + { + var N = right - left + 1, + M = this._maxEntries, + node; -var Rectangle = __webpack_require__(10); + if (N <= M) { + // reached leaf level; return leaf + node = createNode(items.slice(left, right + 1)); + calcBBox(node, this.toBBox); + return node; + } -/** - * Create the smallest Rectangle containing two coordinate pairs. - * - * @function Phaser.Geom.Rectangle.FromXY - * @since 3.23.0 - * - * @generic {Phaser.Geom.Rectangle} O - [out,$return] - * - * @param {number} x1 - The X coordinate of the first point. - * @param {number} y1 - The Y coordinate of the first point. - * @param {number} x2 - The X coordinate of the second point. - * @param {number} y2 - The Y coordinate of the second point. - * @param {Phaser.Geom.Rectangle} [out] - Optional Rectangle to adjust. - * - * @return {Phaser.Geom.Rectangle} The adjusted `out` Rectangle, or a new Rectangle if none was provided. - */ -var FromXY = function (x1, y1, x2, y2, out) -{ - if (out === undefined) { out = new Rectangle(); } + if (!height) { + // target height of the bulk-loaded tree + height = Math.ceil(Math.log(N) / Math.log(M)); - return out.setTo( - Math.min(x1, x2), - Math.min(y1, y2), - Math.abs(x1 - x2), - Math.abs(y1 - y2) - ); -}; + // target number of root entries to maximize storage utilization + M = Math.ceil(N / Math.pow(M, height - 1)); + } -module.exports = FromXY; + node = createNode([]); + node.leaf = false; + node.height = height; + // split the items into M mostly square tiles -/***/ }), -/* 1279 */ -/***/ (function(module, exports, __webpack_require__) { + var N2 = Math.ceil(N / M), + N1 = N2 * Math.ceil(Math.sqrt(M)), + i, j, right2, right3; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + multiSelect(items, left, right, N1, this.compareMinX); -var Point = __webpack_require__(4); + for (i = left; i <= right; i += N1) { -/** - * Returns the center of a Rectangle as a Point. - * - * @function Phaser.Geom.Rectangle.GetCenter - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to get the center of. - * @param {(Phaser.Geom.Point|object)} [out] - Optional point-like object to update with the center coordinates. - * - * @return {(Phaser.Geom.Point|object)} The modified `out` object, or a new Point if none was provided. - */ -var GetCenter = function (rect, out) -{ - if (out === undefined) { out = new Point(); } + right2 = Math.min(i + N1 - 1, right); - out.x = rect.centerX; - out.y = rect.centerY; + multiSelect(items, i, right2, N2, this.compareMinY); - return out; -}; + for (j = i; j <= right2; j += N2) { -module.exports = GetCenter; + right3 = Math.min(j + N2 - 1, right2); + // pack each entry recursively + node.children.push(this._build(items, j, right3, height - 1)); + } + } -/***/ }), -/* 1280 */ -/***/ (function(module, exports, __webpack_require__) { + calcBBox(node, this.toBBox); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return node; + }, -var Point = __webpack_require__(4); + _chooseSubtree: function (bbox, node, level, path) + { + var i, len, child, targetNode, area, enlargement, minArea, minEnlargement; + while (true) { + path.push(node); -/** - * Returns the size of the Rectangle, expressed as a Point object. - * With the value of the `width` as the `x` property and the `height` as the `y` property. - * - * @function Phaser.Geom.Rectangle.GetSize - * @since 3.0.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to get the size from. - * @param {(Phaser.Geom.Point|object)} [out] - The Point object to store the size in. If not given, a new Point instance is created. - * - * @return {(Phaser.Geom.Point|object)} A Point object where `x` holds the width and `y` holds the height of the Rectangle. - */ -var GetSize = function (rect, out) -{ - if (out === undefined) { out = new Point(); } + if (node.leaf || path.length - 1 === level) break; - out.x = rect.width; - out.y = rect.height; + minArea = minEnlargement = Infinity; - return out; -}; + for (i = 0, len = node.children.length; i < len; i++) { + child = node.children[i]; + area = bboxArea(child); + enlargement = enlargedArea(bbox, child) - area; -module.exports = GetSize; + // 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; + } + } + } -/***/ }), -/* 1281 */ -/***/ (function(module, exports, __webpack_require__) { + node = targetNode || node.children[0]; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return node; + }, -var CenterOn = __webpack_require__(190); + _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); -/** - * Increases the size of a Rectangle by a specified amount. - * - * The center of the Rectangle stays the same. The amounts are added to each side, so the actual increase in width or height is two times bigger than the respective argument. - * - * @function Phaser.Geom.Rectangle.Inflate - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to inflate. - * @param {number} x - How many pixels the left and the right side should be moved by horizontally. - * @param {number} y - How many pixels the top and the bottom side should be moved by vertically. - * - * @return {Phaser.Geom.Rectangle} The inflated Rectangle. - */ -var Inflate = function (rect, x, y) -{ - var cx = rect.centerX; - var cy = rect.centerY; + // put the item into the node + node.children.push(item); + extend(node, bbox); - rect.setSize(rect.width + (x * 2), rect.height + (y * 2)); + // 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; + } - return CenterOn(rect, cx, cy); -}; + // adjust bboxes along the insertion path + this._adjustParentBBoxes(bbox, insertPath, level); + }, -module.exports = Inflate; + // 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); -/***/ }), -/* 1282 */ -/***/ (function(module, exports, __webpack_require__) { + var splitIndex = this._chooseSplitIndex(node, m, M); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex)); + newNode.height = node.height; + newNode.leaf = node.leaf; -var Rectangle = __webpack_require__(10); -var Intersects = __webpack_require__(152); + calcBBox(node, this.toBBox); + calcBBox(newNode, this.toBBox); -/** - * Takes two Rectangles and first checks to see if they intersect. - * If they intersect it will return the area of intersection in the `out` Rectangle. - * If they do not intersect, the `out` Rectangle will have a width and height of zero. - * - * @function Phaser.Geom.Rectangle.Intersection - * @since 3.11.0 - * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] - * - * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to get the intersection from. - * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to get the intersection from. - * @param {Phaser.Geom.Rectangle} [out] - A Rectangle to store the intersection results in. - * - * @return {Phaser.Geom.Rectangle} The intersection result. If the width and height are zero, no intersection occurred. - */ -var Intersection = function (rectA, rectB, out) -{ - if (out === undefined) { out = new Rectangle(); } + if (level) insertPath[level - 1].children.push(newNode); + else this._splitRoot(node, newNode); + }, - if (Intersects(rectA, rectB)) + _splitRoot: function (node, newNode) { - out.x = Math.max(rectA.x, rectB.x); - out.y = Math.max(rectA.y, rectB.y); - out.width = Math.min(rectA.right, rectB.right) - out.x; - out.height = Math.min(rectA.bottom, rectB.bottom) - out.y; - } - else + // 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) { - out.setEmpty(); - } + var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index; - return out; -}; + minOverlap = minArea = Infinity; -module.exports = Intersection; + 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); -/***/ }), -/* 1283 */ -/***/ (function(module, exports) { + // choose distribution with minimum overlap + if (overlap < minOverlap) { + minOverlap = overlap; + index = i; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + minArea = area < minArea ? area : minArea; -/** - * Merges a Rectangle with a list of points by repositioning and/or resizing it such that all points are located on or within its bounds. - * - * @function Phaser.Geom.Rectangle.MergePoints - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [target,$return] - * - * @param {Phaser.Geom.Rectangle} target - The Rectangle which should be merged. - * @param {Phaser.Geom.Point[]} points - An array of Points (or any object with public `x` and `y` properties) which should be merged with the Rectangle. - * - * @return {Phaser.Geom.Rectangle} The modified Rectangle. - */ -var MergePoints = function (target, points) -{ - var minX = target.x; - var maxX = target.right; - var minY = target.y; - var maxY = target.bottom; + } else if (overlap === minOverlap) { + // otherwise choose distribution with minimum area + if (area < minArea) { + minArea = area; + index = i; + } + } + } - for (var i = 0; i < points.length; i++) + return index; + }, + + // sorts node children by the best axis for split + _chooseSplitAxis: function (node, m, M) { - minX = Math.min(minX, points[i].x); - maxX = Math.max(maxX, points[i].x); - minY = Math.min(minY, points[i].y); - maxY = Math.max(maxY, points[i].y); - } + 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); - target.x = minX; - target.y = minY; - target.width = maxX - minX; - target.height = maxY - minY; + // 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); + }, - return target; -}; + // 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); -module.exports = MergePoints; + 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); + } -/***/ }), -/* 1284 */ -/***/ (function(module, exports) { + for (i = M - m - 1; i >= m; i--) { + child = node.children[i]; + extend(rightBBox, node.leaf ? toBBox(child) : child); + margin += bboxMargin(rightBBox); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return margin; + }, -// Merges source rectangle into target rectangle and returns target -// Neither rect should have negative widths or heights + _adjustParentBBoxes: function (bbox, path, level) + { + // adjust bboxes along the given tree path + for (var i = level; i >= 0; i--) { + extend(path[i], bbox); + } + }, -/** - * Merges the source rectangle into the target rectangle and returns the target. - * Neither rectangle should have a negative width or height. - * - * @function Phaser.Geom.Rectangle.MergeRect - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [target,$return] - * - * @param {Phaser.Geom.Rectangle} target - Target rectangle. Will be modified to include source rectangle. - * @param {Phaser.Geom.Rectangle} source - Rectangle that will be merged into target rectangle. - * - * @return {Phaser.Geom.Rectangle} Modified target rectangle that contains source rectangle. - */ -var MergeRect = function (target, source) -{ - var minX = Math.min(target.x, source.x); - var maxX = Math.max(target.right, source.right); + _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); - target.x = minX; - target.width = maxX - minX; + } else this.clear(); - var minY = Math.min(target.y, source.y); - var maxY = Math.max(target.bottom, source.bottom); + } else calcBBox(path[i], this.toBBox); + } + }, - target.y = minY; - target.height = maxY - minY; + compareMinX: function (a, b) + { + return a.left - b.left; + }, - return target; -}; + compareMinY: function (a, b) + { + return a.top - b.top; + }, -module.exports = MergeRect; + 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); -/***/ }), -/* 1285 */ -/***/ (function(module, exports) { + for (var i = 0; i < items.length; i++) { + if (equalsFn(item, items[i])) return i; + } + return -1; +} -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ +// calculate node's bbox from bboxes of its children +function calcBBox (node, toBBox) +{ + distBBox(node, 0, node.children.length, toBBox, node); +} -/** - * Merges a Rectangle with a point by repositioning and/or resizing it so that the point is on or within its bounds. - * - * @function Phaser.Geom.Rectangle.MergeXY - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [target,$return] - * - * @param {Phaser.Geom.Rectangle} target - The Rectangle which should be merged and modified. - * @param {number} x - The X coordinate of the point which should be merged. - * @param {number} y - The Y coordinate of the point which should be merged. - * - * @return {Phaser.Geom.Rectangle} The modified `target` Rectangle. - */ -var MergeXY = function (target, x, y) +// min bounding rectangle of node children from k to p-1 +function distBBox (node, k, p, toBBox, destNode) { - var minX = Math.min(target.x, x); - var maxX = Math.max(target.right, x); + if (!destNode) destNode = createNode(null); + destNode.minX = Infinity; + destNode.minY = Infinity; + destNode.maxX = -Infinity; + destNode.maxY = -Infinity; - target.x = minX; - target.width = maxX - minX; + for (var i = k, child; i < p; i++) { + child = node.children[i]; + extend(destNode, node.leaf ? toBBox(child) : child); + } - var minY = Math.min(target.y, y); - var maxY = Math.max(target.bottom, y); + return destNode; +} - target.y = minY; - target.height = maxY - minY; +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; +} - return target; -}; +function compareNodeMinX (a, b) { return a.minX - b.minX; } +function compareNodeMinY (a, b) { return a.minY - b.minY; } -module.exports = MergeXY; +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)); +} -/***/ }), -/* 1286 */ -/***/ (function(module, exports) { +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); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return Math.max(0, maxX - minX) * + Math.max(0, maxY - minY); +} -/** - * Nudges (translates) the top left corner of a Rectangle by a given offset. - * - * @function Phaser.Geom.Rectangle.Offset - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to adjust. - * @param {number} x - The distance to move the Rectangle horizontally. - * @param {number} y - The distance to move the Rectangle vertically. - * - * @return {Phaser.Geom.Rectangle} The adjusted Rectangle. - */ -var Offset = function (rect, x, y) +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) { - rect.x += x; - rect.y += y; + return b.minX <= a.maxX && + b.minY <= a.maxY && + b.maxX >= a.minX && + b.maxY >= a.minY; +} - return rect; -}; +function createNode (children) +{ + return { + children: children, + height: 1, + leaf: true, + minX: Infinity, + minY: Infinity, + maxX: -Infinity, + maxY: -Infinity + }; +} -module.exports = Offset; +// 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; -/***/ }), -/* 1287 */ -/***/ (function(module, exports) { + while (stack.length) + { + right = stack.pop(); + left = stack.pop(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (right - left <= n) continue; -/** - * Nudges (translates) the top-left corner of a Rectangle by the coordinates of a point (translation vector). - * - * @function Phaser.Geom.Rectangle.OffsetPoint - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The Rectangle to adjust. - * @param {(Phaser.Geom.Point|Phaser.Math.Vector2)} point - The point whose coordinates should be used as an offset. - * - * @return {Phaser.Geom.Rectangle} The adjusted Rectangle. - */ -var OffsetPoint = function (rect, point) -{ - rect.x += point.x; - rect.y += point.y; + mid = left + Math.ceil((right - left) / n / 2) * n; + quickselect(arr, mid, left, right, compare); - return rect; -}; + stack.push(left, mid, mid, right); + } +} -module.exports = OffsetPoint; +module.exports = rbush; /***/ }), -/* 1288 */ -/***/ (function(module, exports) { + +/***/ 58403: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); + /** - * Checks if two Rectangles overlap. If a Rectangle is within another Rectangle, the two will be considered overlapping. Thus, the Rectangles are treated as "solid". - * - * @function Phaser.Geom.Rectangle.Overlaps - * @since 3.0.0 + * @callback EachSetCallback * - * @param {Phaser.Geom.Rectangle} rectA - The first Rectangle to check. - * @param {Phaser.Geom.Rectangle} rectB - The second Rectangle to check. + * @param {E} entry - The Set entry. + * @param {number} index - The index of the entry within the Set. * - * @return {boolean} `true` if the two Rectangles overlap, `false` otherwise. - */ -var Overlaps = function (rectA, rectB) -{ - return ( - rectA.x < rectB.right && - rectA.right > rectB.x && - rectA.y < rectB.bottom && - rectA.bottom > rectB.y - ); -}; - -module.exports = Overlaps; - - -/***/ }), -/* 1289 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @return {?boolean} The callback result. */ -var Point = __webpack_require__(4); -var DegToRad = __webpack_require__(36); - /** - * Returns a Point from the perimeter of a Rectangle based on the given angle. + * @classdesc + * A Set is a collection of unique elements. * - * @function Phaser.Geom.Rectangle.PerimeterPoint + * @class Set + * @memberof Phaser.Structs + * @constructor * @since 3.0.0 * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Rectangle} rectangle - The Rectangle to get the perimeter point from. - * @param {number} angle - The angle of the point, in degrees. - * @param {Phaser.Geom.Point} [out] - The Point object to store the position in. If not given, a new Point instance is created. + * @generic T + * @genericUse {T[]} - [elements] * - * @return {Phaser.Geom.Point} A Point object holding the coordinates of the Rectangle perimeter. + * @param {Array.<*>} [elements] - An optional array of elements to insert into this Set. */ -var PerimeterPoint = function (rectangle, angle, out) -{ - if (out === undefined) { out = new Point(); } +var Set = new Class({ - angle = DegToRad(angle); + initialize: - var s = Math.sin(angle); - var c = Math.cos(angle); + function Set (elements) + { + /** + * The entries of this Set. Stored internally as an array. + * + * @genericUse {T[]} - [$type] + * + * @name Phaser.Structs.Set#entries + * @type {Array.<*>} + * @default [] + * @since 3.0.0 + */ + this.entries = []; - var dx = (c > 0) ? rectangle.width / 2 : rectangle.width / -2; - var dy = (s > 0) ? rectangle.height / 2 : rectangle.height / -2; + if (Array.isArray(elements)) + { + for (var i = 0; i < elements.length; i++) + { + this.set(elements[i]); + } + } + }, - if (Math.abs(dx * s) < Math.abs(dy * c)) - { - dy = (dx * s) / c; - } - else + /** + * Inserts the provided value into this Set. If the value is already contained in this Set this method will have no effect. + * + * @method Phaser.Structs.Set#set + * @since 3.0.0 + * + * @genericUse {T} - [value] + * @genericUse {Phaser.Structs.Set.} - [$return] + * + * @param {*} value - The value to insert into this Set. + * + * @return {Phaser.Structs.Set} This Set object. + */ + set: function (value) { - dx = (dy * c) / s; - } - - out.x = dx + rectangle.centerX; - out.y = dy + rectangle.centerY; + if (this.entries.indexOf(value) === -1) + { + this.entries.push(value); + } - return out; -}; + return this; + }, -module.exports = PerimeterPoint; + /** + * Get an element of this Set which has a property of the specified name, if that property is equal to the specified value. + * If no elements of this Set satisfy the condition then this method will return `null`. + * + * @method Phaser.Structs.Set#get + * @since 3.0.0 + * + * @genericUse {T} - [value,$return] + * + * @param {string} property - The property name to check on the elements of this Set. + * @param {*} value - The value to check for. + * + * @return {*} The first element of this Set that meets the required condition, or `null` if this Set contains no elements that meet the condition. + */ + get: function (property, value) + { + for (var i = 0; i < this.entries.length; i++) + { + var entry = this.entries[i]; + if (entry[property] === value) + { + return entry; + } + } + }, -/***/ }), -/* 1290 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Returns an array containing all the values in this Set. + * + * @method Phaser.Structs.Set#getArray + * @since 3.0.0 + * + * @genericUse {T[]} - [$return] + * + * @return {Array.<*>} An array containing all the values in this Set. + */ + getArray: function () + { + return this.entries.slice(0); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Removes the given value from this Set if this Set contains that value. + * + * @method Phaser.Structs.Set#delete + * @since 3.0.0 + * + * @genericUse {T} - [value] + * @genericUse {Phaser.Structs.Set.} - [$return] + * + * @param {*} value - The value to remove from the Set. + * + * @return {Phaser.Structs.Set} This Set object. + */ + delete: function (value) + { + var index = this.entries.indexOf(value); -var Between = __webpack_require__(195); -var ContainsRect = __webpack_require__(503); -var Point = __webpack_require__(4); + if (index > -1) + { + this.entries.splice(index, 1); + } -/** - * Calculates a random point that lies within the `outer` Rectangle, but outside of the `inner` Rectangle. - * The inner Rectangle must be fully contained within the outer rectangle. - * - * @function Phaser.Geom.Rectangle.RandomOutside - * @since 3.10.0 - * - * @generic {Phaser.Geom.Point} O - [out,$return] - * - * @param {Phaser.Geom.Rectangle} outer - The outer Rectangle to get the random point within. - * @param {Phaser.Geom.Rectangle} inner - The inner Rectangle to exclude from the returned point. - * @param {Phaser.Geom.Point} [out] - A Point, or Point-like object to store the result in. If not specified, a new Point will be created. - * - * @return {Phaser.Geom.Point} A Point object containing the random values in its `x` and `y` properties. - */ -var RandomOutside = function (outer, inner, out) -{ - if (out === undefined) { out = new Point(); } + return this; + }, - if (ContainsRect(outer, inner)) + /** + * Dumps the contents of this Set to the console via `console.group`. + * + * @method Phaser.Structs.Set#dump + * @since 3.0.0 + */ + dump: function () { - // Pick a random quadrant - // - // The quadrants don't extend the full widths / heights of the outer rect to give - // us a better uniformed distribution, otherwise you get clumping in the corners where - // the 4 quads would overlap + // eslint-disable-next-line no-console + console.group('Set'); - switch (Between(0, 3)) + for (var i = 0; i < this.entries.length; i++) { - case 0: // Top - out.x = outer.x + (Math.random() * (inner.right - outer.x)); - out.y = outer.y + (Math.random() * (inner.top - outer.y)); - break; + var entry = this.entries[i]; + console.log(entry); + } - case 1: // Bottom - out.x = inner.x + (Math.random() * (outer.right - inner.x)); - out.y = inner.bottom + (Math.random() * (outer.bottom - inner.bottom)); - break; + // eslint-disable-next-line no-console + console.groupEnd(); + }, - case 2: // Left - out.x = outer.x + (Math.random() * (inner.x - outer.x)); - out.y = inner.y + (Math.random() * (outer.bottom - inner.y)); - break; + /** + * Passes each value in this Set to the given callback. + * Use this function when you know this Set will be modified during the iteration, otherwise use `iterate`. + * + * @method Phaser.Structs.Set#each + * @since 3.0.0 + * + * @genericUse {EachSetCallback.} - [callback] + * @genericUse {Phaser.Structs.Set.} - [$return] + * + * @param {EachSetCallback} callback - The callback to be invoked and passed each value this Set contains. + * @param {*} [callbackScope] - The scope of the callback. + * + * @return {Phaser.Structs.Set} This Set object. + */ + each: function (callback, callbackScope) + { + var i; + var temp = this.entries.slice(); + var len = temp.length; - case 3: // Right - out.x = inner.right + (Math.random() * (outer.right - inner.right)); - out.y = outer.y + (Math.random() * (inner.bottom - outer.y)); - break; + if (callbackScope) + { + for (i = 0; i < len; i++) + { + if (callback.call(callbackScope, temp[i], i) === false) + { + break; + } + } + } + else + { + for (i = 0; i < len; i++) + { + if (callback(temp[i], i) === false) + { + break; + } + } } - } - - return out; -}; -module.exports = RandomOutside; + return this; + }, + /** + * Passes each value in this Set to the given callback. + * + * For when you absolutely know this Set won't be modified during the iteration. + * + * The callback must return a boolean. If it returns `false` then it will abort + * the Set iteration immediately. If it returns `true`, it will carry on + * iterating the next child in the Set. + * + * @method Phaser.Structs.Set#iterate + * @since 3.0.0 + * + * @genericUse {EachSetCallback.} - [callback] + * @genericUse {Phaser.Structs.Set.} - [$return] + * + * @param {EachSetCallback} callback - The callback to be invoked and passed each value this Set contains. + * @param {*} [callbackScope] - The scope of the callback. + * + * @return {Phaser.Structs.Set} This Set object. + */ + iterate: function (callback, callbackScope) + { + var i; + var len = this.entries.length; -/***/ }), -/* 1291 */ -/***/ (function(module, exports) { + if (callbackScope) + { + for (i = 0; i < len; i++) + { + if (callback.call(callbackScope, this.entries[i], i) === false) + { + break; + } + } + } + else + { + for (i = 0; i < len; i++) + { + if (callback(this.entries[i], i) === false) + { + break; + } + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * Determines if the two objects (either Rectangles or Rectangle-like) have the same width and height values under strict equality. - * - * @function Phaser.Geom.Rectangle.SameDimensions - * @since 3.15.0 - * - * @param {Phaser.Geom.Rectangle} rect - The first Rectangle object. - * @param {Phaser.Geom.Rectangle} toCompare - The second Rectangle object. - * - * @return {boolean} `true` if the objects have equivalent values for the `width` and `height` properties, otherwise `false`. - */ -var SameDimensions = function (rect, toCompare) -{ - return (rect.width === toCompare.width && rect.height === toCompare.height); -}; + /** + * Goes through each entry in this Set and invokes the given function on them, passing in the arguments. + * + * @method Phaser.Structs.Set#iterateLocal + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.Set.} - [$return] + * + * @param {string} callbackKey - The key of the function to be invoked on each Set entry. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. + * + * @return {Phaser.Structs.Set} This Set object. + */ + iterateLocal: function (callbackKey) + { + var i; + var args = []; -module.exports = SameDimensions; + for (i = 1; i < arguments.length; i++) + { + args.push(arguments[i]); + } + var len = this.entries.length; -/***/ }), -/* 1292 */ -/***/ (function(module, exports) { + for (i = 0; i < len; i++) + { + var entry = this.entries[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + entry[callbackKey].apply(entry, args); + } -// Scales the width and height of this Rectangle by the given amounts. + return this; + }, -/** - * Scales the width and height of this Rectangle by the given amounts. - * - * @function Phaser.Geom.Rectangle.Scale - * @since 3.0.0 - * - * @generic {Phaser.Geom.Rectangle} O - [rect,$return] - * - * @param {Phaser.Geom.Rectangle} rect - The `Rectangle` object that will be scaled by the specified amount(s). - * @param {number} x - The factor by which to scale the rectangle horizontally. - * @param {number} y - The amount by which to scale the rectangle vertically. If this is not specified, the rectangle will be scaled by the factor `x` in both directions. - * - * @return {Phaser.Geom.Rectangle} The rectangle object with updated `width` and `height` properties as calculated from the scaling factor(s). - */ -var Scale = function (rect, x, y) -{ - if (y === undefined) { y = x; } + /** + * Clears this Set so that it no longer contains any values. + * + * @method Phaser.Structs.Set#clear + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.Set.} - [$return] + * + * @return {Phaser.Structs.Set} This Set object. + */ + clear: function () + { + this.entries.length = 0; - rect.width *= x; - rect.height *= y; + return this; + }, - return rect; -}; + /** + * Returns `true` if this Set contains the given value, otherwise returns `false`. + * + * @method Phaser.Structs.Set#contains + * @since 3.0.0 + * + * @genericUse {T} - [value] + * + * @param {*} value - The value to check for in this Set. + * + * @return {boolean} `true` if the given value was found in this Set, otherwise `false`. + */ + contains: function (value) + { + return (this.entries.indexOf(value) > -1); + }, -module.exports = Scale; + /** + * Returns a new Set containing all values that are either in this Set or in the Set provided as an argument. + * + * @method Phaser.Structs.Set#union + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.Set.} - [set,$return] + * + * @param {Phaser.Structs.Set} set - The Set to perform the union with. + * + * @return {Phaser.Structs.Set} A new Set containing all the values in this Set and the Set provided as an argument. + */ + union: function (set) + { + var newSet = new Set(); + set.entries.forEach(function (value) + { + newSet.set(value); + }); -/***/ }), -/* 1293 */ -/***/ (function(module, exports, __webpack_require__) { + this.entries.forEach(function (value) + { + newSet.set(value); + }); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return newSet; + }, -var Triangle = __webpack_require__(82); + /** + * Returns a new Set that contains only the values which are in this Set and that are also in the given Set. + * + * @method Phaser.Structs.Set#intersect + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.Set.} - [set,$return] + * + * @param {Phaser.Structs.Set} set - The Set to intersect this set with. + * + * @return {Phaser.Structs.Set} The result of the intersection, as a new Set. + */ + intersect: function (set) + { + var newSet = new Set(); -Triangle.Area = __webpack_require__(1294); -Triangle.BuildEquilateral = __webpack_require__(1295); -Triangle.BuildFromPolygon = __webpack_require__(1296); -Triangle.BuildRight = __webpack_require__(1297); -Triangle.CenterOn = __webpack_require__(1298); -Triangle.Centroid = __webpack_require__(504); -Triangle.CircumCenter = __webpack_require__(1299); -Triangle.CircumCircle = __webpack_require__(1300); -Triangle.Clone = __webpack_require__(1301); -Triangle.Contains = __webpack_require__(115); -Triangle.ContainsArray = __webpack_require__(235); -Triangle.ContainsPoint = __webpack_require__(1302); -Triangle.CopyFrom = __webpack_require__(1303); -Triangle.Decompose = __webpack_require__(495); -Triangle.Equals = __webpack_require__(1304); -Triangle.GetPoint = __webpack_require__(476); -Triangle.GetPoints = __webpack_require__(477); -Triangle.InCenter = __webpack_require__(506); -Triangle.Perimeter = __webpack_require__(1305); -Triangle.Offset = __webpack_require__(505); -Triangle.Random = __webpack_require__(181); -Triangle.Rotate = __webpack_require__(1306); -Triangle.RotateAroundPoint = __webpack_require__(1307); -Triangle.RotateAroundXY = __webpack_require__(238); + this.entries.forEach(function (value) + { + if (set.contains(value)) + { + newSet.set(value); + } + }); -module.exports = Triangle; + return newSet; + }, + /** + * Returns a new Set containing all the values in this Set which are *not* also in the given Set. + * + * @method Phaser.Structs.Set#difference + * @since 3.0.0 + * + * @genericUse {Phaser.Structs.Set.} - [set,$return] + * + * @param {Phaser.Structs.Set} set - The Set to perform the difference with. + * + * @return {Phaser.Structs.Set} A new Set containing all the values in this Set that are not also in the Set provided as an argument to this method. + */ + difference: function (set) + { + var newSet = new Set(); -/***/ }), -/* 1294 */ -/***/ (function(module, exports) { + this.entries.forEach(function (value) + { + if (!set.contains(value)) + { + newSet.set(value); + } + }); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return newSet; + }, -// The 2D area of a triangle. The area value is always non-negative. + /** + * The size of this Set. This is the number of entries within it. + * Changing the size will truncate the Set if the given value is smaller than the current size. + * Increasing the size larger than the current size has no effect. + * + * @name Phaser.Structs.Set#size + * @type {number} + * @since 3.0.0 + */ + size: { -/** - * Returns the area of a Triangle. - * - * @function Phaser.Geom.Triangle.Area - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to use. - * - * @return {number} The area of the Triangle, always non-negative. - */ -var Area = function (triangle) -{ - var x1 = triangle.x1; - var y1 = triangle.y1; + get: function () + { + return this.entries.length; + }, - var x2 = triangle.x2; - var y2 = triangle.y2; + set: function (value) + { + if (value < this.entries.length) + { + return this.entries.length = value; + } + else + { + return this.entries.length; + } + } - var x3 = triangle.x3; - var y3 = triangle.y3; + } - return Math.abs(((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1)) / 2); -}; +}); -module.exports = Area; +module.exports = Set; /***/ }), -/* 1295 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 90881: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Triangle = __webpack_require__(82); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var SnapFloor = __webpack_require__(84314); +var Vector2 = __webpack_require__(93736); /** - * Builds an equilateral triangle. In the equilateral triangle, all the sides are the same length (congruent) and all the angles are the same size (congruent). - * The x/y specifies the top-middle of the triangle (x1/y1) and length is the length of each side. + * @classdesc + * The Size component allows you to set `width` and `height` properties and define the relationship between them. * - * @function Phaser.Geom.Triangle.BuildEquilateral - * @since 3.0.0 + * 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. * - * @param {number} x - x coordinate of the top point of the triangle. - * @param {number} y - y coordinate of the top point of the triangle. - * @param {number} length - Length of each side of the triangle. + * @class Size + * @memberof Phaser.Structs + * @constructor + * @since 3.16.0 * - * @return {Phaser.Geom.Triangle} The Triangle object of the given size. + * @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 BuildEquilateral = function (x, y, length) -{ - var height = length * (Math.sqrt(3) / 2); - - var x1 = x; - var y1 = y; - - var x2 = x + (length / 2); - var y2 = y + height; - - var x3 = x - (length / 2); - var y3 = y + height; +var Size = new Class({ - return new Triangle(x1, y1, x2, y2, x3, y3); -}; + initialize: -module.exports = BuildEquilateral; + 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; -/***/ }), -/* 1296 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Internal height value. + * + * @name Phaser.Structs.Size#_height + * @type {number} + * @private + * @since 3.16.0 + */ + this._height = height; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Internal parent reference. + * + * @name Phaser.Structs.Size#_parent + * @type {any} + * @private + * @since 3.16.0 + */ + this._parent = parent; -var EarCut = __webpack_require__(59); -var Triangle = __webpack_require__(82); + /** + * 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; -/** - * Takes an array of vertex coordinates, and optionally an array of hole indices, then returns an array - * of Triangle instances, where the given vertices have been decomposed into a series of triangles. - * - * @function Phaser.Geom.Triangle.BuildFromPolygon - * @since 3.0.0 - * - * @generic {Phaser.Geom.Triangle[]} O - [out,$return] - * - * @param {array} data - A flat array of vertex coordinates like [x0,y0, x1,y1, x2,y2, ...] - * @param {array} [holes=null] - An array of hole indices if any (e.g. [5, 8] for a 12-vertex input would mean one hole with vertices 5–7 and another with 8–11). - * @param {number} [scaleX=1] - Horizontal scale factor to multiply the resulting points by. - * @param {number} [scaleY=1] - Vertical scale factor to multiply the resulting points by. - * @param {(array|Phaser.Geom.Triangle[])} [out] - An array to store the resulting Triangle instances in. If not provided, a new array is created. - * - * @return {(array|Phaser.Geom.Triangle[])} An array of Triangle instances, where each triangle is based on the decomposed vertices data. - */ -var BuildFromPolygon = function (data, holes, scaleX, scaleY, out) -{ - if (holes === undefined) { holes = null; } - if (scaleX === undefined) { scaleX = 1; } - if (scaleY === undefined) { scaleY = 1; } - if (out === undefined) { out = []; } + /** + * 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; - var tris = EarCut(data, holes); + /** + * 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; - var a; - var b; - var c; + /** + * 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; - var x1; - var y1; + /** + * 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; - var x2; - var y2; + /** + * 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; - var x3; - var y3; + /** + * 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(); + }, - for (var i = 0; i < tris.length; i += 3) + /** + * 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) { - a = tris[i]; - b = tris[i + 1]; - c = tris[i + 2]; - - x1 = data[a * 2] * scaleX; - y1 = data[(a * 2) + 1] * scaleY; - - x2 = data[b * 2] * scaleX; - y2 = data[(b * 2) + 1] * scaleY; + if (value === undefined) { value = 0; } - x3 = data[c * 2] * scaleX; - y3 = data[(c * 2) + 1] * scaleY; + this.aspectMode = value; - out.push(new Triangle(x1, y1, x2, y2, x3, y3)); - } + return this.setSize(this._width, this._height); + }, - return out; -}; + /** + * 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; } -module.exports = BuildFromPolygon; + this.snapTo.set(snapWidth, snapHeight); + return this.setSize(this._width, this._height); + }, -/***/ }), -/* 1297 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this.setSize(this._width, this._height); + }, -var Triangle = __webpack_require__(82); + /** + * 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; } -// Builds a right triangle, with one 90 degree angle and two acute angles -// The x/y is the coordinate of the 90 degree angle (and will map to x1/y1 in the resulting Triangle) -// w/h can be positive or negative and represent the length of each side + this.minWidth = Clamp(width, 0, this.maxWidth); + this.minHeight = Clamp(height, 0, this.maxHeight); -/** - * Builds a right triangle, i.e. one which has a 90-degree angle and two acute angles. - * - * @function Phaser.Geom.Triangle.BuildRight - * @since 3.0.0 - * - * @param {number} x - The X coordinate of the right angle, which will also be the first X coordinate of the constructed Triangle. - * @param {number} y - The Y coordinate of the right angle, which will also be the first Y coordinate of the constructed Triangle. - * @param {number} width - The length of the side which is to the left or to the right of the right angle. - * @param {number} height - The length of the side which is above or below the right angle. - * - * @return {Phaser.Geom.Triangle} The constructed right Triangle. - */ -var BuildRight = function (x, y, width, height) -{ - if (height === undefined) { height = width; } + return this.setSize(this._width, this._height); + }, - // 90 degree angle - var x1 = x; - var y1 = y; + /** + * 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; } - var x2 = x; - var y2 = y - height; + this.maxWidth = Clamp(width, this.minWidth, Number.MAX_VALUE); + this.maxHeight = Clamp(height, this.minHeight, Number.MAX_VALUE); - var x3 = x + width; - var y3 = y; + return this.setSize(this._width, this._height); + }, - return new Triangle(x1, y1, x2, y2, x3, y3); -}; + /** + * 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; } -module.exports = BuildRight; + 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; -/***/ }), -/* 1298 */ -/***/ (function(module, exports, __webpack_require__) { + case Size.HEIGHT_CONTROLS_WIDTH: + this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y)); + this._width = this.getNewWidth(this._height * this.aspectRatio, false); + break; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + case Size.FIT: + this.constrain(width, height, true); + break; -var Centroid = __webpack_require__(504); -var Offset = __webpack_require__(505); + case Size.ENVELOP: + this.constrain(width, height, false); + break; + } -/** - * @callback CenterFunction - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to return the center coordinates of. - * - * @return {Phaser.Math.Vector2} The center point of the Triangle according to the function. - */ + return this; + }, -/** - * Positions the Triangle so that it is centered on the given coordinates. - * - * @function Phaser.Geom.Triangle.CenterOn - * @since 3.0.0 - * - * @generic {Phaser.Geom.Triangle} O - [triangle,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The triangle to be positioned. - * @param {number} x - The horizontal coordinate to center on. - * @param {number} y - The vertical coordinate to center on. - * @param {CenterFunction} [centerFunc] - The function used to center the triangle. Defaults to Centroid centering. - * - * @return {Phaser.Geom.Triangle} The Triangle that was centered. - */ -var CenterOn = function (triangle, x, y, centerFunc) -{ - if (centerFunc === undefined) { centerFunc = Centroid; } + /** + * 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; - // Get the center of the triangle - var center = centerFunc(triangle); + return this.setSize(this._width, this._height); + }, - // Difference - var diffX = x - center.x; - var diffY = y - center.y; + /** + * 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 Offset(triangle, diffX, diffY); -}; + return this; + }, -module.exports = CenterOn; + /** + * 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); -/***/ }), -/* 1299 */ -/***/ (function(module, exports, __webpack_require__) { + if (checkParent && this._parent && value > this._parent.width) + { + value = Math.max(this.minWidth, this._parent.width); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return value; + }, -var Vector2 = __webpack_require__(3); + /** + * 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; } -// Adapted from http://bjornharrtell.github.io/jsts/doc/api/jsts_geom_Triangle.js.html + value = Clamp(value, this.minHeight, this.maxHeight); -/** - * Computes the determinant of a 2x2 matrix. Uses standard double-precision arithmetic, so is susceptible to round-off error. - * - * @function det - * @private - * @since 3.0.0 - * - * @param {number} m00 - The [0,0] entry of the matrix. - * @param {number} m01 - The [0,1] entry of the matrix. - * @param {number} m10 - The [1,0] entry of the matrix. - * @param {number} m11 - The [1,1] entry of the matrix. - * - * @return {number} the determinant. - */ -function det (m00, m01, m10, m11) -{ - return (m00 * m11) - (m01 * m10); -} + if (checkParent && this._parent && value > this._parent.height) + { + value = Math.max(this.minHeight, this._parent.height); + } -/** - * Computes the circumcentre of a triangle. The circumcentre is the centre of - * the circumcircle, the smallest circle which encloses the triangle. It is also - * the common intersection point of the perpendicular bisectors of the sides of - * the triangle, and is the only point which has equal distance to all three - * vertices of the triangle. - * - * @function Phaser.Geom.Triangle.CircumCenter - * @since 3.0.0 - * - * @generic {Phaser.Math.Vector2} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the circumcenter of. - * @param {Phaser.Math.Vector2} [out] - The Vector2 object to store the position in. If not given, a new Vector2 instance is created. - * - * @return {Phaser.Math.Vector2} A Vector2 object holding the coordinates of the circumcenter of the Triangle. - */ -var CircumCenter = function (triangle, out) -{ - if (out === undefined) { out = new Vector2(); } + return value; + }, - var cx = triangle.x3; - var cy = triangle.y3; + /** + * 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; } - var ax = triangle.x1 - cx; - var ay = triangle.y1 - cy; + width = this.getNewWidth(width); + height = this.getNewHeight(height); - var bx = triangle.x2 - cx; - var by = triangle.y2 - cy; + var snap = this.snapTo; + var newRatio = (height === 0) ? 1 : width / height; - var denom = 2 * det(ax, ay, bx, by); - var numx = det(ay, ax * ax + ay * ay, by, bx * bx + by * by); - var numy = det(ax, ax * ax + ay * ay, bx, bx * bx + by * by); + if ((fit && this.aspectRatio > newRatio) || (!fit && this.aspectRatio < newRatio)) + { + // We need to change the height to fit the width - out.x = cx - numx / denom; - out.y = cy + numy / denom; + width = SnapFloor(width, snap.x); - return out; -}; + height = width / this.aspectRatio; -module.exports = CircumCenter; + 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 -/***/ }), -/* 1300 */ -/***/ (function(module, exports, __webpack_require__) { + height = SnapFloor(height, snap.y); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + width = height * this.aspectRatio; -var Circle = __webpack_require__(65); + if (snap.x > 0) + { + width = SnapFloor(width, snap.x); -// Adapted from https://gist.github.com/mutoo/5617691 + // Reduce the height accordingly + height = width * (1 / this.aspectRatio); + } + } -/** - * Finds the circumscribed circle (circumcircle) of a Triangle object. The circumcircle is the circle which touches all of the triangle's vertices. - * - * @function Phaser.Geom.Triangle.CircumCircle - * @since 3.0.0 - * - * @generic {Phaser.Geom.Circle} O - [out,$return] - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to use as input. - * @param {Phaser.Geom.Circle} [out] - An optional Circle to store the result in. - * - * @return {Phaser.Geom.Circle} The updated `out` Circle, or a new Circle if none was provided. - */ -var CircumCircle = function (triangle, out) -{ - if (out === undefined) { out = new Circle(); } + this._width = width; + this._height = height; - // A - var x1 = triangle.x1; - var y1 = triangle.y1; + return this; + }, - // B - var x2 = triangle.x2; - var y2 = triangle.y2; + /** + * 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); + }, - // C - var x3 = triangle.x3; - var y3 = triangle.y3; + /** + * 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); + }, - var A = x2 - x1; - var B = y2 - y1; - var C = x3 - x1; - var D = y3 - y1; - var E = A * (x1 + x2) + B * (y1 + y2); - var F = C * (x1 + x3) + D * (y1 + y3); - var G = 2 * (A * (y3 - y2) - B * (x3 - x2)); + /** + * 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); + }, - var dx; - var dy; + /** + * 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); + }, - // If the points of the triangle are collinear, then just find the - // extremes and use the midpoint as the center of the circumcircle. + /** + * 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 + ') }]'; + }, - if (Math.abs(G) < 0.000001) + /** + * 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) { - var minX = Math.min(x1, x2, x3); - var minY = Math.min(y1, y2, y3); - dx = (Math.max(x1, x2, x3) - minX) * 0.5; - dy = (Math.max(y1, y2, y3) - minY) * 0.5; + if (element && element.style) + { + element.style.width = this._width + 'px'; + element.style.height = this._height + 'px'; + } + }, - out.x = minX + dx; - out.y = minY + dy; - out.radius = Math.sqrt(dx * dx + dy * dy); - } - else + /** + * 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) { - out.x = (D * E - B * F) / G; - out.y = (A * F - C * E) / G; - dx = out.x - x1; - dy = out.y - y1; - out.radius = Math.sqrt(dx * dx + dy * dy); - } + destination.setAspectMode(this.aspectMode); - return out; -}; + destination.aspectRatio = this.aspectRatio; -module.exports = CircumCircle; + 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; + }, -/***/ }), -/* 1301 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return this._width; + }, -var Triangle = __webpack_require__(82); + set: function (value) + { + this.setSize(value, this._height); + } -/** - * Clones a Triangle object. - * - * @function Phaser.Geom.Triangle.Clone - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} source - The Triangle to clone. - * - * @return {Phaser.Geom.Triangle} A new Triangle identical to the given one but separate from it. - */ -var Clone = function (source) -{ - return new Triangle(source.x1, source.y1, source.x2, source.y2, source.x3, source.y3); -}; + }, -module.exports = Clone; + /** + * 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; + }, -/***/ }), -/* 1302 */ -/***/ (function(module, exports, __webpack_require__) { + set: function (value) + { + this.setSize(this._width, value); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + } -var Contains = __webpack_require__(115); +}); /** - * Tests if a triangle contains a point. - * - * @function Phaser.Geom.Triangle.ContainsPoint - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The triangle. - * @param {(Phaser.Geom.Point|Phaser.Math.Vector2|any)} point - The point to test, or any point-like object with public `x` and `y` properties. + * Do not make the size fit the aspect ratio. Change the ratio when the size changes. * - * @return {boolean} `true` if the point is within the triangle, otherwise `false`. - */ -var ContainsPoint = function (triangle, point) -{ - return Contains(triangle, point.x, point.y); -}; - -module.exports = ContainsPoint; - - -/***/ }), -/* 1303 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @name Phaser.Structs.Size.NONE + * @constant + * @type {number} + * @since 3.16.0 */ +Size.NONE = 0; /** - * Copy the values of one Triangle to a destination Triangle. - * - * @function Phaser.Geom.Triangle.CopyFrom - * @since 3.0.0 - * - * @generic {Phaser.Geom.Triangle} O - [dest,$return] - * - * @param {Phaser.Geom.Triangle} source - The source Triangle to copy the values from. - * @param {Phaser.Geom.Triangle} dest - The destination Triangle to copy the values to. + * The height is automatically adjusted based on the width. * - * @return {Phaser.Geom.Triangle} The destination Triangle. - */ -var CopyFrom = function (source, dest) -{ - return dest.setTo(source.x1, source.y1, source.x2, source.y2, source.x3, source.y3); -}; - -module.exports = CopyFrom; - - -/***/ }), -/* 1304 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * @name Phaser.Structs.Size.WIDTH_CONTROLS_HEIGHT + * @constant + * @type {number} + * @since 3.16.0 */ +Size.WIDTH_CONTROLS_HEIGHT = 1; /** - * Returns true if two triangles have the same coordinates. - * - * @function Phaser.Geom.Triangle.Equals - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The first triangle to check. - * @param {Phaser.Geom.Triangle} toCompare - The second triangle to check. + * The width is automatically adjusted based on the height. * - * @return {boolean} `true` if the two given triangles have the exact same coordinates, otherwise `false`. + * @name Phaser.Structs.Size.HEIGHT_CONTROLS_WIDTH + * @constant + * @type {number} + * @since 3.16.0 */ -var Equals = function (triangle, toCompare) -{ - return ( - triangle.x1 === toCompare.x1 && - triangle.y1 === toCompare.y1 && - triangle.x2 === toCompare.x2 && - triangle.y2 === toCompare.y2 && - triangle.x3 === toCompare.x3 && - triangle.y3 === toCompare.y3 - ); -}; - -module.exports = Equals; - - -/***/ }), -/* 1305 */ -/***/ (function(module, exports, __webpack_require__) { +Size.HEIGHT_CONTROLS_WIDTH = 2; /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * 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 */ - -var Length = __webpack_require__(67); +Size.FIT = 3; /** - * Gets the length of the perimeter of the given triangle. - * Calculated by adding together the length of each of the three sides. - * - * @function Phaser.Geom.Triangle.Perimeter - * @since 3.0.0 - * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to get the length from. + * 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. * - * @return {number} The length of the Triangle. + * @name Phaser.Structs.Size.ENVELOP + * @constant + * @type {number} + * @since 3.16.0 */ -var Perimeter = function (triangle) -{ - var line1 = triangle.getLineA(); - var line2 = triangle.getLineB(); - var line3 = triangle.getLineC(); - - return (Length(line1) + Length(line2) + Length(line3)); -}; +Size.ENVELOP = 4; -module.exports = Perimeter; +module.exports = Size; /***/ }), -/* 1306 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 94160: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(238); -var InCenter = __webpack_require__(506); - /** - * Rotates a Triangle about its incenter, which is the point at which its three angle bisectors meet. + * The Process Queue Add Event. * - * @function Phaser.Geom.Triangle.Rotate - * @since 3.0.0 + * This event is dispatched by a Process Queue when a new item is successfully moved to its active list. * - * @generic {Phaser.Geom.Triangle} O - [triangle,$return] + * You will most commonly see this used by a Scene's Update List when a new Game Object has been added. * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to rotate. - * @param {number} angle - The angle by which to rotate the Triangle, in radians. + * In that instance, listen to this event from within a Scene using: `this.sys.updateList.on('add', listener)`. * - * @return {Phaser.Geom.Triangle} The rotated Triangle. + * @event Phaser.Structs.Events#PROCESS_QUEUE_ADD + * @type {string} + * @since 3.20.0 + * + * @param {*} item - The item that was added to the Process Queue. */ -var Rotate = function (triangle, angle) -{ - var point = InCenter(triangle); - - return RotateAroundXY(triangle, point.x, point.y, angle); -}; - -module.exports = Rotate; +module.exports = 'add'; /***/ }), -/* 1307 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 95393: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RotateAroundXY = __webpack_require__(238); - /** - * Rotates a Triangle at a certain angle about a given Point or object with public `x` and `y` properties. + * The Process Queue Remove Event. * - * @function Phaser.Geom.Triangle.RotateAroundPoint - * @since 3.0.0 + * This event is dispatched by a Process Queue when a new item is successfully removed from its active list. * - * @generic {Phaser.Geom.Triangle} O - [triangle,$return] + * You will most commonly see this used by a Scene's Update List when a Game Object has been removed. * - * @param {Phaser.Geom.Triangle} triangle - The Triangle to rotate. - * @param {Phaser.Geom.Point} point - The Point to rotate the Triangle about. - * @param {number} angle - The angle by which to rotate the Triangle, in radians. + * In that instance, listen to this event from within a Scene using: `this.sys.updateList.on('remove', listener)`. * - * @return {Phaser.Geom.Triangle} The rotated Triangle. + * @event Phaser.Structs.Events#PROCESS_QUEUE_REMOVE + * @type {string} + * @since 3.20.0 + * + * @param {*} item - The item that was removed from the Process Queue. */ -var RotateAroundPoint = function (triangle, point, angle) -{ - return RotateAroundXY(triangle, point.x, point.y, angle); -}; - -module.exports = RotateAroundPoint; +module.exports = 'remove'; /***/ }), -/* 1308 */ -/***/ (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__(203); -var Extend = __webpack_require__(17); - -/** - * @namespace Phaser.Input - */ - -var Input = { - - CreatePixelPerfectHandler: __webpack_require__(507), - CreateInteractiveObject: __webpack_require__(508), - Events: __webpack_require__(51), - Gamepad: __webpack_require__(1309), - InputManager: __webpack_require__(409), - InputPlugin: __webpack_require__(1321), - InputPluginCache: __webpack_require__(153), - Keyboard: __webpack_require__(1322), - Mouse: __webpack_require__(1336), - Pointer: __webpack_require__(412), - Touch: __webpack_require__(1337) - -}; - -// Merge in the consts -Input = Extend(false, Input, CONST); -module.exports = Input; - - -/***/ }), -/* 1309 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 36716: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Input.Gamepad + * @namespace Phaser.Structs.Events */ module.exports = { - Axis: __webpack_require__(509), - Button: __webpack_require__(510), - Events: __webpack_require__(239), - Gamepad: __webpack_require__(511), - GamepadPlugin: __webpack_require__(1316), - - Configs: __webpack_require__(1317) -}; - - -/***/ }), -/* 1310 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Gamepad Button Down Event. - * - * This event is dispatched by the Gamepad Plugin when a button has been pressed on any active Gamepad. - * - * Listen to this event from within a Scene using: `this.input.gamepad.on('down', listener)`. - * - * You can also listen for a DOWN event from a Gamepad instance. See the [GAMEPAD_BUTTON_DOWN]{@linkcode Phaser.Input.Gamepad.Events#event:GAMEPAD_BUTTON_DOWN} event for details. - * - * @event Phaser.Input.Gamepad.Events#BUTTON_DOWN - * @since 3.10.0 - * - * @param {Phaser.Input.Gamepad} pad - A reference to the Gamepad on which the button was pressed. - * @param {Phaser.Input.Gamepad.Button} button - A reference to the Button which was pressed. - * @param {number} value - The value of the button at the time it was pressed. Between 0 and 1. Some Gamepads have pressure-sensitive buttons. - */ -module.exports = 'down'; - - -/***/ }), -/* 1311 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + PROCESS_QUEUE_ADD: __webpack_require__(94160), + PROCESS_QUEUE_REMOVE: __webpack_require__(95393) -/** - * The Gamepad Button Up Event. - * - * This event is dispatched by the Gamepad Plugin when a button has been released on any active Gamepad. - * - * Listen to this event from within a Scene using: `this.input.gamepad.on('up', listener)`. - * - * You can also listen for an UP event from a Gamepad instance. See the [GAMEPAD_BUTTON_UP]{@linkcode Phaser.Input.Gamepad.Events#event:GAMEPAD_BUTTON_UP} event for details. - * - * @event Phaser.Input.Gamepad.Events#BUTTON_UP - * @since 3.10.0 - * - * @param {Phaser.Input.Gamepad} pad - A reference to the Gamepad on which the button was released. - * @param {Phaser.Input.Gamepad.Button} button - A reference to the Button which was released. - * @param {number} value - The value of the button at the time it was released. Between 0 and 1. Some Gamepads have pressure-sensitive buttons. - */ -module.exports = 'up'; +}; /***/ }), -/* 1312 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Gamepad Connected Event. - * - * This event is dispatched by the Gamepad Plugin when a Gamepad has been connected. - * - * Listen to this event from within a Scene using: `this.input.gamepad.once('connected', listener)`. - * - * Note that the browser may require you to press a button on a gamepad before it will allow you to access it, - * this is for security reasons. However, it may also trust the page already, in which case you won't get the - * 'connected' event and instead should check `GamepadPlugin.total` to see if it thinks there are any gamepads - * already connected. - * - * @event Phaser.Input.Gamepad.Events#CONNECTED - * @since 3.0.0 - * - * @param {Phaser.Input.Gamepad} pad - A reference to the Gamepad which was connected. - * @param {Event} event - The native DOM Event that triggered the connection. - */ -module.exports = 'connected'; - -/***/ }), -/* 1313 */ -/***/ (function(module, exports) { +/***/ 20010: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Gamepad Disconnected Event. - * - * This event is dispatched by the Gamepad Plugin when a Gamepad has been disconnected. - * - * Listen to this event from within a Scene using: `this.input.gamepad.once('disconnected', listener)`. - * - * @event Phaser.Input.Gamepad.Events#DISCONNECTED - * @since 3.0.0 - * - * @param {Phaser.Input.Gamepad} pad - A reference to the Gamepad which was disconnected. - * @param {Event} event - The native DOM Event that triggered the disconnection. + * @namespace Phaser.Structs */ -module.exports = 'disconnected'; +module.exports = { -/***/ }), -/* 1314 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + Events: __webpack_require__(36716), + List: __webpack_require__(71207), + Map: __webpack_require__(33885), + ProcessQueue: __webpack_require__(74623), + RTree: __webpack_require__(68687), + Set: __webpack_require__(58403), + Size: __webpack_require__(90881) -/** - * The Gamepad Button Down Event. - * - * This event is dispatched by a Gamepad instance when a button has been pressed on it. - * - * Listen to this event from a Gamepad instance. Once way to get this is from the `pad1`, `pad2`, etc properties on the Gamepad Plugin: - * `this.input.gamepad.pad1.on('down', listener)`. - * - * Note that you will not receive any Gamepad button events until the browser considers the Gamepad as being 'connected'. - * - * You can also listen for a DOWN event from the Gamepad Plugin. See the [BUTTON_DOWN]{@linkcode Phaser.Input.Gamepad.Events#event:BUTTON_DOWN} event for details. - * - * @event Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_DOWN - * @since 3.10.0 - * - * @param {number} index - The index of the button that was pressed. - * @param {number} value - The value of the button at the time it was pressed. Between 0 and 1. Some Gamepads have pressure-sensitive buttons. - * @param {Phaser.Input.Gamepad.Button} button - A reference to the Button which was pressed. - */ -module.exports = 'down'; +}; /***/ }), -/* 1315 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * The Gamepad Button Up Event. - * - * This event is dispatched by a Gamepad instance when a button has been released on it. - * - * Listen to this event from a Gamepad instance. Once way to get this is from the `pad1`, `pad2`, etc properties on the Gamepad Plugin: - * `this.input.gamepad.pad1.on('up', listener)`. - * - * Note that you will not receive any Gamepad button events until the browser considers the Gamepad as being 'connected'. - * - * You can also listen for an UP event from the Gamepad Plugin. See the [BUTTON_UP]{@linkcode Phaser.Input.Gamepad.Events#event:BUTTON_UP} event for details. - * - * @event Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_UP - * @since 3.10.0 - * - * @param {number} index - The index of the button that was released. - * @param {number} value - The value of the button at the time it was released. Between 0 and 1. Some Gamepads have pressure-sensitive buttons. - * @param {Phaser.Input.Gamepad.Button} button - A reference to the Button which was released. - */ -module.exports = 'up'; - -/***/ }), -/* 1316 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 17487: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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__(239); -var Gamepad = __webpack_require__(511); -var GetValue = __webpack_require__(6); -var InputPluginCache = __webpack_require__(153); -var InputEvents = __webpack_require__(51); +var Class = __webpack_require__(56694); +var Clamp = __webpack_require__(82897); +var Color = __webpack_require__(27119); +var CONST = __webpack_require__(86459); +var IsSizePowerOfTwo = __webpack_require__(28621); +var Texture = __webpack_require__(31673); /** * @classdesc - * The Gamepad Plugin is an input plugin that belongs to the Scene-owned Input system. - * - * Its role is to listen for native DOM Gamepad Events and then process them. - * - * You do not need to create this class directly, the Input system will create an instance of it automatically. - * - * You can access it from within a Scene using `this.input.gamepad`. - * - * To listen for a gamepad being connected: - * - * ```javascript - * this.input.gamepad.once('connected', function (pad) { - * // 'pad' is a reference to the gamepad that was just connected - * }); - * ``` - * - * Note that the browser may require you to press a button on a gamepad before it will allow you to access it, - * this is for security reasons. However, it may also trust the page already, in which case you won't get the - * 'connected' event and instead should check `GamepadPlugin.total` to see if it thinks there are any gamepads - * already connected. + * A Canvas Texture is a special kind of Texture that is backed by an HTML Canvas Element as its source. * - * Once you have received the connected event, or polled the gamepads and found them enabled, you can access - * them via the built-in properties `GamepadPlugin.pad1` to `pad4`, for up to 4 game pads. With a reference - * to the gamepads you can poll its buttons and axis sticks. See the properties and methods available on - * the `Gamepad` class for more details. + * 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. * - * As of September 2020 Chrome, and likely other browsers, will soon start to require that games requesting - * access to the Gamepad API are running under SSL. They will actively block API access if they are not. + * 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. * - * For more information about Gamepad support in browsers see the following resources: + * 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. * - * https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API - * https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API - * https://www.smashingmagazine.com/2015/11/gamepad-api-in-web-games/ - * http://html5gamepad.com/ + * 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 GamepadPlugin - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Input.Gamepad + * @class CanvasTexture + * @extends Phaser.Textures.Texture + * @memberof Phaser.Textures * @constructor - * @since 3.10.0 + * @since 3.7.0 * - * @param {Phaser.Input.InputPlugin} sceneInputPlugin - A reference to the Scene Input Plugin that the KeyboardPlugin belongs to. + * @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 GamepadPlugin = new Class({ +var CanvasTexture = new Class({ - Extends: EventEmitter, + Extends: Texture, initialize: - function GamepadPlugin (sceneInputPlugin) + function CanvasTexture (manager, key, source, width, height) { - EventEmitter.call(this); - - /** - * A reference to the Scene that this Input Plugin is responsible for. - * - * @name Phaser.Input.Gamepad.GamepadPlugin#scene - * @type {Phaser.Scene} - * @since 3.10.0 - */ - this.scene = sceneInputPlugin.scene; - - /** - * A reference to the Scene Systems Settings. - * - * @name Phaser.Input.Gamepad.GamepadPlugin#settings - * @type {Phaser.Types.Scenes.SettingsObject} - * @since 3.10.0 - */ - this.settings = this.scene.sys.settings; + Texture.call(this, manager, key, source, width, height); - /** - * A reference to the Scene Input Plugin that created this Keyboard Plugin. - * - * @name Phaser.Input.Gamepad.GamepadPlugin#sceneInputPlugin - * @type {Phaser.Input.InputPlugin} - * @since 3.10.0 - */ - this.sceneInputPlugin = sceneInputPlugin; + this.add('__BASE', 0, 0, 0, width, height); /** - * A boolean that controls if the Gamepad Manager is enabled or not. - * Can be toggled on the fly. + * A reference to the Texture Source of this Canvas. * - * @name Phaser.Input.Gamepad.GamepadPlugin#enabled - * @type {boolean} - * @default true - * @since 3.10.0 + * @name Phaser.Textures.CanvasTexture#_source + * @type {Phaser.Textures.TextureSource} + * @private + * @since 3.7.0 */ - this.enabled = true; + this._source = this.frames['__BASE'].source; /** - * The Gamepad Event target, as defined in the Game Config. - * Typically the browser window, but can be any interactive DOM element. + * The source Canvas Element. * - * @name Phaser.Input.Gamepad.GamepadPlugin#target - * @type {any} - * @since 3.10.0 + * @name Phaser.Textures.CanvasTexture#canvas + * @readonly + * @type {HTMLCanvasElement} + * @since 3.7.0 */ - this.target; + this.canvas = this._source.image; /** - * An array of the connected Gamepads. + * The 2D Canvas Rendering Context. * - * @name Phaser.Input.Gamepad.GamepadPlugin#gamepads - * @type {Phaser.Input.Gamepad.Gamepad[]} - * @default [] - * @since 3.10.0 + * @name Phaser.Textures.CanvasTexture#context + * @readonly + * @type {CanvasRenderingContext2D} + * @since 3.7.0 */ - this.gamepads = []; + this.context = this.canvas.getContext('2d', { willReadFrequently: true }); /** - * An internal event queue. + * The width of the Canvas. + * This property is read-only, if you wish to change it use the `setSize` method. * - * @name Phaser.Input.Gamepad.GamepadPlugin#queue - * @type {GamepadEvent[]} - * @private - * @since 3.10.0 + * @name Phaser.Textures.CanvasTexture#width + * @readonly + * @type {number} + * @since 3.7.0 */ - this.queue = []; + this.width = width; /** - * Internal event handler. - * - * @name Phaser.Input.Gamepad.GamepadPlugin#onGamepadHandler - * @type {function} - * @private - * @since 3.10.0 + * 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.onGamepadHandler; + this.height = height; /** - * Internal Gamepad reference. + * The context image data. + * Use the `update` method to populate this when the canvas changes. * - * @name Phaser.Input.Gamepad.GamepadPlugin#_pad1 - * @type {Phaser.Input.Gamepad.Gamepad} - * @private - * @since 3.10.0 + * @name Phaser.Textures.CanvasTexture#imageData + * @type {ImageData} + * @since 3.13.0 */ - this._pad1; + this.imageData = this.context.getImageData(0, 0, width, height); /** - * Internal Gamepad reference. + * 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.Input.Gamepad.GamepadPlugin#_pad2 - * @type {Phaser.Input.Gamepad.Gamepad} - * @private - * @since 3.10.0 + * @name Phaser.Textures.CanvasTexture#data + * @type {Uint8ClampedArray} + * @since 3.13.0 */ - this._pad2; + this.data = null; + + if (this.imageData) + { + this.data = this.imageData.data; + } /** - * Internal Gamepad reference. + * An Uint32Array view into the `buffer`. * - * @name Phaser.Input.Gamepad.GamepadPlugin#_pad3 - * @type {Phaser.Input.Gamepad.Gamepad} - * @private - * @since 3.10.0 + * @name Phaser.Textures.CanvasTexture#pixels + * @type {Uint32Array} + * @since 3.13.0 */ - this._pad3; + this.pixels = null; /** - * Internal Gamepad reference. + * An ArrayBuffer the same size as the context ImageData. * - * @name Phaser.Input.Gamepad.GamepadPlugin#_pad4 - * @type {Phaser.Input.Gamepad.Gamepad} - * @private - * @since 3.10.0 + * @name Phaser.Textures.CanvasTexture#buffer + * @type {ArrayBuffer} + * @since 3.13.0 */ - this._pad4; + this.buffer; - sceneInputPlugin.pluginEvents.once(InputEvents.BOOT, this.boot, this); - sceneInputPlugin.pluginEvents.on(InputEvents.START, this.start, this); + 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 method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. + * This re-creates the `imageData` from the current context. + * It then re-builds the ArrayBuffer, the `data` Uint8ClampedArray reference and the `pixels` Int32Array. * - * @method Phaser.Input.Gamepad.GamepadPlugin#boot - * @private - * @since 3.10.0 + * 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. */ - boot: function () + update: function () { - var game = this.scene.sys.game; - var settings = this.settings.input; - var config = game.config; + this.imageData = this.context.getImageData(0, 0, this.width, this.height); - this.enabled = GetValue(settings, 'gamepad', config.inputGamepad) && game.device.input.gamepads; - this.target = GetValue(settings, 'gamepad.target', config.inputGamepadEventTarget); + this.data = this.imageData.data; - this.sceneInputPlugin.pluginEvents.once(InputEvents.DESTROY, this.destroy, this); + 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; }, /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. + * Draws the given Image or Canvas element to this CanvasTexture, then updates the internal + * ImageData buffer and arrays. * - * @method Phaser.Input.Gamepad.GamepadPlugin#start - * @private - * @since 3.10.0 + * @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. + * @param {boolean} [update=true] - Update the internal ImageData buffer and arrays. + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. */ - start: function () + draw: function (x, y, source, update) { - if (this.enabled) - { - this.startListeners(); + if (update === undefined) { update = true; } - this.refreshPads(); + this.context.drawImage(source, x, y); + + if (update) + { + this.update(); } - this.sceneInputPlugin.pluginEvents.once(InputEvents.SHUTDOWN, this.shutdown, this); + return this; }, /** - * Checks to see if both this plugin and the Scene to which it belongs is active. + * Draws the given texture frame to this CanvasTexture, then updates the internal + * ImageData buffer and arrays. * - * @method Phaser.Input.Gamepad.GamepadPlugin#isActive - * @since 3.10.0 + * @method Phaser.Textures.CanvasTexture#drawFrame + * @since 3.16.0 * - * @return {boolean} `true` if the plugin and the Scene it belongs to is active. + * @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. + * @param {boolean} [update=true] - Update the internal ImageData buffer and arrays. + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. */ - isActive: function () + drawFrame: function (key, frame, x, y, update) { - return (this.enabled && this.scene.sys.isActive()); + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (update === undefined) { update = true; } + + 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 + ); + + if (update) + { + this.update(); + } + } + + return this; }, /** - * Starts the Gamepad Event listeners running. - * This is called automatically and does not need to be manually invoked. + * Sets a pixel in the CanvasTexture to the given color and alpha values. * - * @method Phaser.Input.Gamepad.GamepadPlugin#startListeners - * @private - * @since 3.10.0 + * 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. */ - startListeners: function () + setPixel: function (x, y, red, green, blue, alpha) { - var _this = this; - var target = this.target; - - var handler = function (event) - { - if (event.defaultPrevented || !_this.isActive()) - { - // Do nothing if event already handled - return; - } + if (alpha === undefined) { alpha = 255; } - _this.refreshPads(); + x = Math.abs(Math.floor(x)); + y = Math.abs(Math.floor(y)); - _this.queue.push(event); - }; + var index = this.getIndex(x, y); - this.onGamepadHandler = handler; + if (index > -1) + { + var imageData = this.context.getImageData(x, y, 1, 1); - target.addEventListener('gamepadconnected', handler, false); - target.addEventListener('gamepaddisconnected', handler, false); + imageData.data[0] = red; + imageData.data[1] = green; + imageData.data[2] = blue; + imageData.data[3] = alpha; - // FF also supports gamepadbuttondown, gamepadbuttonup and gamepadaxismove but - // nothing else does, and we can get those values via the gamepads anyway, so we will - // until more browsers support this + this.context.putImageData(imageData, x, y); + } - // Finally, listen for an update event from the Input Plugin - this.sceneInputPlugin.pluginEvents.on(InputEvents.UPDATE, this.update, this); + return this; }, /** - * Stops the Gamepad Event listeners. - * This is called automatically and does not need to be manually invoked. + * Puts the ImageData into the context of this CanvasTexture at the given coordinates. * - * @method Phaser.Input.Gamepad.GamepadPlugin#stopListeners - * @private - * @since 3.10.0 + * @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. */ - stopListeners: function () + putData: function (imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) { - this.target.removeEventListener('gamepadconnected', this.onGamepadHandler); - this.target.removeEventListener('gamepaddisconnected', this.onGamepadHandler); + if (dirtyX === undefined) { dirtyX = 0; } + if (dirtyY === undefined) { dirtyY = 0; } + if (dirtyWidth === undefined) { dirtyWidth = imageData.width; } + if (dirtyHeight === undefined) { dirtyHeight = imageData.height; } - this.sceneInputPlugin.pluginEvents.off(InputEvents.UPDATE, this.update); + this.context.putImageData(imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight); - for (var i = 0; i < this.gamepads.length; i++) - { - this.gamepads[i].removeAllListeners(); - } + return this; }, /** - * Disconnects all current Gamepads. + * 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.Input.Gamepad.GamepadPlugin#disconnectAll - * @since 3.10.0 + * @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. */ - disconnectAll: function () + getData: function (x, y, width, height) { - for (var i = 0; i < this.gamepads.length; i++) - { - this.gamepads[i].pad.connected = false; - } + 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; }, /** - * Refreshes the list of connected Gamepads. + * Get the color of a specific pixel from this texture and store it in a Color object. * - * This is called automatically when a gamepad is connected or disconnected, - * and during the update loop. + * 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.Input.Gamepad.GamepadPlugin#refreshPads - * @private - * @since 3.10.0 + * @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. */ - refreshPads: function () + getPixel: function (x, y, out) { - var connectedPads = navigator.getGamepads(); - - if (!connectedPads) + if (!out) { - this.disconnectAll(); + out = new Color(); } - else - { - var currentPads = this.gamepads; - - for (var i = 0; i < connectedPads.length; i++) - { - var livePad = connectedPads[i]; - - // Because sometimes they're null (yes, really) - if (!livePad) - { - continue; - } - - var id = livePad.id; - var index = livePad.index; - var currentPad = currentPads[index]; - if (!currentPad) - { - // A new Gamepad, not currently stored locally - var newPad = new Gamepad(this, livePad); + var index = this.getIndex(x, y); - currentPads[index] = newPad; + if (index > -1) + { + var data = this.data; - if (!this._pad1) - { - this._pad1 = newPad; - } - else if (!this._pad2) - { - this._pad2 = newPad; - } - else if (!this._pad3) - { - this._pad3 = newPad; - } - else if (!this._pad4) - { - this._pad4 = newPad; - } - } - else if (currentPad.id !== id) - { - // A new Gamepad with a different vendor string, but it has got the same index as an old one - currentPad.destroy(); + var r = data[index + 0]; + var g = data[index + 1]; + var b = data[index + 2]; + var a = data[index + 3]; - currentPads[index] = new Gamepad(this, livePad); - } - else - { - // If neither of these, it's a pad we've already got, so update it - currentPad.update(livePad); - } - } + out.setTo(r, g, b, a); } + + return out; }, /** - * Returns an array of all currently connected Gamepads. + * Returns an array containing all of the pixels in the given region. * - * @method Phaser.Input.Gamepad.GamepadPlugin#getAll - * @since 3.10.0 + * If the requested region extends outside the bounds of this CanvasTexture, + * the region is truncated to fit. * - * @return {Phaser.Input.Gamepad.Gamepad[]} An array of all currently connected Gamepads. + * 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. */ - getAll: function () + 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 = []; - var pads = this.gamepads; - for (var i = 0; i < pads.length; i++) + for (var py = top; py < bottom; py++) { - if (pads[i]) + var row = []; + + for (var px = left; px < right; px++) { - out.push(pads[i]); + pixel = this.getPixel(px, py, pixel); + + row.push({ x: px, y: py, color: pixel.color, alpha: pixel.alphaGL }); } + + out.push(row); } return out; }, /** - * Looks-up a single Gamepad based on the given index value. + * Returns the Image Data index for the given pixel in this CanvasTexture. * - * @method Phaser.Input.Gamepad.GamepadPlugin#getPad - * @since 3.10.0 + * The index can be used to read directly from the `this.data` array. * - * @param {number} index - The index of the Gamepad to get. + * The index points to the red value in the array. The subsequent 3 indexes + * point to green, blue and alpha respectively. * - * @return {Phaser.Input.Gamepad.Gamepad} The Gamepad matching the given index, or undefined if none were found. - */ - getPad: function (index) - { - var pads = this.gamepads; - - for (var i = 0; i < pads.length; i++) - { - if (pads[i] && pads[i].index === index) - { - return pads[i]; - } - } - }, - - /** - * The internal update loop. Refreshes all connected gamepads and processes their events. + * @method Phaser.Textures.CanvasTexture#getIndex + * @since 3.16.0 * - * Called automatically by the Input Manager, invoked from the Game step. + * @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. * - * @method Phaser.Input.Gamepad.GamepadPlugin#update - * @private - * @fires Phaser.Input.Gamepad.Events#CONNECTED - * @fires Phaser.Input.Gamepad.Events#DISCONNECTED - * @since 3.10.0 + * @return {number} */ - update: function () + getIndex: function (x, y) { - if (!this.enabled) - { - return; - } - - this.refreshPads(); - - var len = this.queue.length; + x = Math.abs(Math.round(x)); + y = Math.abs(Math.round(y)); - if (len === 0) + if (x < this.width && y < this.height) { - return; + return (x + y * this.width) * 4; } - - var queue = this.queue.splice(0, len); - - // Process the event queue, dispatching all of the events that have stored up - for (var i = 0; i < len; i++) + else { - var event = queue[i]; - var pad = this.getPad(event.gamepad.index); - - if (event.type === 'gamepadconnected') - { - this.emit(Events.CONNECTED, pad, event); - } - else if (event.type === 'gamepaddisconnected') - { - this.emit(Events.DISCONNECTED, pad, event); - } + return -1; } }, /** - * Shuts the Gamepad Plugin down. - * All this does is remove any listeners bound to it. + * 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.Input.Gamepad.GamepadPlugin#shutdown - * @private - * @since 3.10.0 + * @method Phaser.Textures.CanvasTexture#refresh + * @since 3.7.0 + * + * @return {Phaser.Textures.CanvasTexture} This CanvasTexture. */ - shutdown: function () + refresh: function () { - this.stopListeners(); + this._source.update(); - this.removeAllListeners(); + return this; }, /** - * Destroys this Gamepad Plugin, disconnecting all Gamepads and releasing internal references. + * Gets the Canvas Element. * - * @method Phaser.Input.Gamepad.GamepadPlugin#destroy - * @private - * @since 3.10.0 + * @method Phaser.Textures.CanvasTexture#getCanvas + * @since 3.7.0 + * + * @return {HTMLCanvasElement} The Canvas DOM element this texture is using. */ - destroy: function () + getCanvas: function () { - this.shutdown(); - - for (var i = 0; i < this.gamepads.length; i++) - { - if (this.gamepads[i]) - { - this.gamepads[i].destroy(); - } - } - - this.gamepads = []; - - this.scene = null; - this.settings = null; - this.sceneInputPlugin = null; - this.target = null; + return this.canvas; }, /** - * The total number of connected game pads. + * Gets the 2D Canvas Rendering Context. * - * @name Phaser.Input.Gamepad.GamepadPlugin#total - * @type {number} - * @since 3.10.0 + * @method Phaser.Textures.CanvasTexture#getContext + * @since 3.7.0 + * + * @return {CanvasRenderingContext2D} The Canvas Rendering Context this texture is using. */ - total: { - - get: function () - { - return this.gamepads.length; - } - + getContext: function () + { + return this.context; }, /** - * A reference to the first connected Gamepad. + * Clears the given region of this Canvas Texture, resetting it back to transparent. + * If no region is given, the whole Canvas Texture is cleared. * - * This will be undefined if either no pads are connected, or the browser - * has not yet issued a gamepadconnect, which can happen even if a Gamepad - * is plugged in, but hasn't yet had any buttons pressed on it. + * @method Phaser.Textures.CanvasTexture#clear + * @since 3.7.0 * - * @name Phaser.Input.Gamepad.GamepadPlugin#pad1 - * @type {Phaser.Input.Gamepad.Gamepad} - * @since 3.10.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. + * @param {boolean} [update=true] - Update the internal ImageData buffer and arrays. + * + * @return {Phaser.Textures.CanvasTexture} The Canvas Texture. */ - pad1: { + clear: function (x, y, width, height, update) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.width; } + if (height === undefined) { height = this.height; } + if (update === undefined) { update = true; } - get: function () + this.context.clearRect(x, y, width, height); + + if (update) { - return this._pad1; + this.update(); } + return this; }, /** - * A reference to the second connected Gamepad. + * Changes the size of this Canvas Texture. * - * This will be undefined if either no pads are connected, or the browser - * has not yet issued a gamepadconnect, which can happen even if a Gamepad - * is plugged in, but hasn't yet had any buttons pressed on it. + * @method Phaser.Textures.CanvasTexture#setSize + * @since 3.7.0 * - * @name Phaser.Input.Gamepad.GamepadPlugin#pad2 - * @type {Phaser.Input.Gamepad.Gamepad} - * @since 3.10.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. */ - pad2: { + setSize: function (width, height) + { + if (height === undefined) { height = width; } - get: function () + if (width !== this.width || height !== this.height) { - return this._pad2; - } + // 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); - /** - * A reference to the third connected Gamepad. - * - * This will be undefined if either no pads are connected, or the browser - * has not yet issued a gamepadconnect, which can happen even if a Gamepad - * is plugged in, but hasn't yet had any buttons pressed on it. - * - * @name Phaser.Input.Gamepad.GamepadPlugin#pad3 - * @type {Phaser.Input.Gamepad.Gamepad} - * @since 3.10.0 - */ - pad3: { + // Update the Frame + this.frames['__BASE'].setSize(width, height, 0, 0); - get: function () - { - return this._pad3; + // Update this + this.width = width; + this.height = height; + + this.refresh(); } + return this; }, /** - * A reference to the fourth connected Gamepad. - * - * This will be undefined if either no pads are connected, or the browser - * has not yet issued a gamepadconnect, which can happen even if a Gamepad - * is plugged in, but hasn't yet had any buttons pressed on it. + * Destroys this Texture and releases references to its sources and frames. * - * @name Phaser.Input.Gamepad.GamepadPlugin#pad4 - * @type {Phaser.Input.Gamepad.Gamepad} - * @since 3.10.0 + * @method Phaser.Textures.CanvasTexture#destroy + * @since 3.16.0 */ - pad4: { - - get: function () - { - return this._pad4; - } + 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; } }); -/** - * An instance of the Gamepad Plugin class, if enabled via the `input.gamepad` Scene or Game Config property. - * Use this to create access Gamepads connected to the browser and respond to gamepad buttons. - * - * @name Phaser.Input.InputPlugin#gamepad - * @type {?Phaser.Input.Gamepad.GamepadPlugin} - * @since 3.10.0 - */ -InputPluginCache.register('GamepadPlugin', GamepadPlugin, 'gamepad', 'gamepad', 'inputGamepad'); - -module.exports = GamepadPlugin; - - -/***/ }), -/* 1317 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Input.Gamepad.Configs - */ - -module.exports = { - - DUALSHOCK_4: __webpack_require__(1318), - SNES_USB: __webpack_require__(1319), - XBOX_360: __webpack_require__(1320) - -}; - - -/***/ }), -/* 1318 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * PlayStation DualShock 4 Gamepad Configuration. - * Sony PlayStation DualShock 4 (v2) wireless controller - * - * @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4 - * @type {object} - * @since 3.0.0 - */ -module.exports = { - - UP: 12, - DOWN: 13, - LEFT: 14, - RIGHT: 15, - - SHARE: 8, - OPTIONS: 9, - PS: 16, - TOUCHBAR: 17, - - X: 0, - CIRCLE: 1, - SQUARE: 2, - TRIANGLE: 3, - - L1: 4, - R1: 5, - L2: 6, - R2: 7, - L3: 10, - R3: 11, - - LEFT_STICK_H: 0, - LEFT_STICK_V: 1, - RIGHT_STICK_H: 2, - RIGHT_STICK_V: 3 - -}; - - -/***/ }), -/* 1319 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * Tatar SNES USB Controller Gamepad Configuration. - * USB Gamepad (STANDARD GAMEPAD Vendor: 0079 Product: 0011) - * - * @name Phaser.Input.Gamepad.Configs.SNES_USB - * @type {object} - * @since 3.0.0 - */ -module.exports = { - - UP: 12, - DOWN: 13, - LEFT: 14, - RIGHT: 15, - - SELECT: 8, - START: 9, - - B: 0, - A: 1, - Y: 2, - X: 3, - - LEFT_SHOULDER: 4, - RIGHT_SHOULDER: 5 - -}; +module.exports = CanvasTexture; /***/ }), -/* 1320 */ -/***/ (function(module, exports) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * XBox 360 Gamepad Configuration. - * - * @name Phaser.Input.Gamepad.Configs.XBOX_360 - * @type {object} - * @since 3.0.0 - */ -module.exports = { - - UP: 12, - DOWN: 13, - LEFT: 14, - RIGHT: 15, - - MENU: 16, - - A: 0, - B: 1, - X: 2, - Y: 3, - LB: 4, - RB: 5, - - LT: 6, - RT: 7, - - BACK: 8, - START: 9, - - LS: 10, - RS: 11, - - LEFT_STICK_H: 0, - LEFT_STICK_V: 1, - RIGHT_STICK_H: 2, - RIGHT_STICK_V: 3 - -}; - - -/***/ }), -/* 1321 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 845: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Circle = __webpack_require__(65); -var CircleContains = __webpack_require__(66); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(203); -var CreateInteractiveObject = __webpack_require__(508); -var CreatePixelPerfectHandler = __webpack_require__(507); -var DistanceBetween = __webpack_require__(50); -var Ellipse = __webpack_require__(111); -var EllipseContains = __webpack_require__(112); -var Events = __webpack_require__(51); -var EventEmitter = __webpack_require__(9); -var GetFastValue = __webpack_require__(2); -var GEOM_CONST = __webpack_require__(56); -var InputPluginCache = __webpack_require__(153); -var IsPlainObject = __webpack_require__(7); -var PluginCache = __webpack_require__(24); -var Rectangle = __webpack_require__(10); -var RectangleContains = __webpack_require__(57); -var SceneEvents = __webpack_require__(20); -var Triangle = __webpack_require__(82); -var TriangleContains = __webpack_require__(115); +var BlendModes = __webpack_require__(95723); +var Camera = __webpack_require__(51052); +var CanvasPool = __webpack_require__(61068); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(86459); +var Frame = __webpack_require__(82047); +var GetFastValue = __webpack_require__(72632); +var PIPELINES = __webpack_require__(65641); +var RenderTarget = __webpack_require__(37410); +var Texture = __webpack_require__(31673); +var Utils = __webpack_require__(75512); /** * @classdesc - * The Input Plugin belongs to a Scene and handles all input related events and operations for it. - * - * You can access it from within a Scene using `this.input`. + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. * - * It emits events directly. For example, you can do: - * - * ```javascript - * this.input.on('pointerdown', callback, context); - * ``` - * - * To listen for a pointer down event anywhere on the game canvas. + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. * - * Game Objects can be enabled for input by calling their `setInteractive` method. After which they - * will directly emit input events: + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. * - * ```javascript - * var sprite = this.add.sprite(x, y, texture); - * sprite.setInteractive(); - * sprite.on('pointerdown', callback, context); + * ```js + * const t = this.textures.addDynamicTexture('player', 64, 128); + * // draw objects to t + * this.add.sprite(x, y, 'player'); * ``` * - * There are lots of game configuration options available relating to input. - * See the [Input Config object]{@linkcode Phaser.Types.Core.InputConfig} for more details, including how to deal with Phaser - * listening for input events outside of the canvas, how to set a default number of pointers, input - * capture settings and more. - * - * Please also see the Input examples and tutorials for further information. - * - * **Incorrect input coordinates with Angular** - * - * If you are using Phaser within Angular, and use nglf or the router, to make the component in which the Phaser game resides - * change state (i.e. appear or disappear) then you'll need to notify the Scale Manager about this, as Angular will mess with - * the DOM in a way in which Phaser can't detect directly. Call `this.scale.updateBounds()` as part of your game init in order - * to refresh the canvas DOM bounds values, which Phaser uses for input point position calculations. + * Because this is a standard Texture within Phaser, you can add frames to it, meaning you can use it + * to generate sprite sheets, texture atlases or tile sets. * - * @class InputPlugin - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Input - * @constructor - * @since 3.0.0 + * Under WebGL1, a FrameBuffer, which is what this Dynamic Texture uses internally, cannot be anti-aliased. + * This means that when drawing objects such as Shapes or Graphics instances to this texture, they may appear + * to be drawn with no aliasing around the edges. This is a technical limitation of WebGL1. To get around it, + * create your shape as a texture in an art package, then draw that to this texture. * - * @param {Phaser.Scene} scene - A reference to the Scene that this Input Plugin is responsible for. - */ -var InputPlugin = new Class({ - - Extends: EventEmitter, - - initialize: - - function InputPlugin (scene) - { - EventEmitter.call(this); - - /** - * A reference to the Scene that this Input Plugin is responsible for. - * - * @name Phaser.Input.InputPlugin#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; - - /** - * A reference to the Scene Systems class. - * - * @name Phaser.Input.InputPlugin#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.systems = scene.sys; - - /** - * A reference to the Scene Systems Settings. - * - * @name Phaser.Input.InputPlugin#settings - * @type {Phaser.Types.Scenes.SettingsObject} - * @since 3.5.0 - */ - this.settings = scene.sys.settings; - - /** - * A reference to the Game Input Manager. - * - * @name Phaser.Input.InputPlugin#manager - * @type {Phaser.Input.InputManager} - * @since 3.0.0 - */ - this.manager = scene.sys.game.input; - - /** - * Internal event queue used for plugins only. - * - * @name Phaser.Input.InputPlugin#pluginEvents - * @type {Phaser.Events.EventEmitter} - * @private - * @since 3.10.0 - */ - this.pluginEvents = new EventEmitter(); - - /** - * If `true` this Input Plugin will process DOM input events. - * - * @name Phaser.Input.InputPlugin#enabled - * @type {boolean} - * @default true - * @since 3.5.0 - */ - this.enabled = true; - - /** - * A reference to the Scene Display List. This property is set during the `boot` method. - * - * @name Phaser.Input.InputPlugin#displayList - * @type {Phaser.GameObjects.DisplayList} - * @since 3.0.0 - */ - this.displayList; - - /** - * A reference to the Scene Cameras Manager. This property is set during the `boot` method. - * - * @name Phaser.Input.InputPlugin#cameras - * @type {Phaser.Cameras.Scene2D.CameraManager} - * @since 3.0.0 - */ - this.cameras; - - // Inject the available input plugins into this class - InputPluginCache.install(this); - - /** - * A reference to the Mouse Manager. - * - * This property is only set if Mouse support has been enabled in your Game Configuration file. - * - * If you just wish to get access to the mouse pointer, use the `mousePointer` property instead. - * - * @name Phaser.Input.InputPlugin#mouse - * @type {?Phaser.Input.Mouse.MouseManager} - * @since 3.0.0 - */ - this.mouse = this.manager.mouse; - - /** - * When set to `true` (the default) the Input Plugin will emulate DOM behavior by only emitting events from - * the top-most Game Objects in the Display List. - * - * If set to `false` it will emit events from all Game Objects below a Pointer, not just the top one. - * - * @name Phaser.Input.InputPlugin#topOnly - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.topOnly = true; - - /** - * How often should the Pointers be checked? - * - * The value is a time, given in ms, and is the time that must have elapsed between game steps before - * the Pointers will be polled again. When a pointer is polled it runs a hit test to see which Game - * Objects are currently below it, or being interacted with it. - * - * Pointers will *always* be checked if they have been moved by the user, or press or released. - * - * This property only controls how often they will be polled if they have not been updated. - * You should set this if you want to have Game Objects constantly check against the pointers, even - * if the pointer didn't itself move. - * - * Set to 0 to poll constantly. Set to -1 to only poll on user movement. - * - * @name Phaser.Input.InputPlugin#pollRate - * @type {number} - * @default -1 - * @since 3.0.0 - */ - this.pollRate = -1; + * Based on the assumption that you will be using this Dynamic Texture as a source for Sprites, it will + * automatically invert any drawing done to it on the y axis. If you do not require this, please call the + * `setIsSpriteTexture()` method and pass it `false` as its parameter. Do this before you start drawing + * to this texture, otherwise you will get vertically inverted frames under WebGL. This isn't required + * for Canvas. + * + * @class DynamicTexture + * @extends Phaser.Textures.Texture + * @memberof Phaser.Textures + * @constructor + * @since 3.60.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 {number} [width=256] - The width of this Dymamic Texture in pixels. Defaults to 256 x 256. + * @param {number} [height=256] - The height of this Dymamic Texture in pixels. Defaults to 256 x 256. + */ +var DynamicTexture = new Class({ - /** - * Internal poll timer value. - * - * @name Phaser.Input.InputPlugin#_pollTimer - * @type {number} - * @private - * @default 0 - * @since 3.0.0 - */ - this._pollTimer = 0; + Extends: Texture, - var _eventData = { cancelled: false }; + initialize: - /** - * Internal event propagation callback container. - * - * @name Phaser.Input.InputPlugin#_eventContainer - * @type {Phaser.Types.Input.EventData} - * @private - * @since 3.13.0 - */ - this._eventContainer = { - stopPropagation: function () - { - _eventData.cancelled = true; - } - }; + function DynamicTexture (manager, key, width, height) + { + if (width === undefined) { width = 256; } + if (height === undefined) { height = 256; } /** - * Internal event propagation data object. + * The internal data type of this object. * - * @name Phaser.Input.InputPlugin#_eventData - * @type {object} - * @private - * @since 3.13.0 + * @name Phaser.Textures.DynamicTexture#type + * @type {string} + * @readonly + * @since 3.60.0 */ - this._eventData = _eventData; + this.type = 'DynamicTexture'; - /** - * The distance, in pixels, a pointer has to move while being held down, before it thinks it is being dragged. - * - * @name Phaser.Input.InputPlugin#dragDistanceThreshold - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.dragDistanceThreshold = 0; + var renderer = manager.game.renderer; - /** - * The amount of time, in ms, a pointer has to be held down before it thinks it is dragging. - * - * The default polling rate is to poll only on move so once the time threshold is reached the - * drag event will not start until you move the mouse. If you want it to start immediately - * when the time threshold is reached, you must increase the polling rate by calling - * [setPollAlways]{@linkcode Phaser.Input.InputPlugin#setPollAlways} or - * [setPollRate]{@linkcode Phaser.Input.InputPlugin#setPollRate}. - * - * @name Phaser.Input.InputPlugin#dragTimeThreshold - * @type {number} - * @default 0 - * @since 3.0.0 - */ - this.dragTimeThreshold = 0; + var isCanvas = (renderer && renderer.type === CONST.CANVAS); - /** - * Used to temporarily store the results of the Hit Test - * - * @name Phaser.Input.InputPlugin#_temp - * @type {array} - * @private - * @default [] - * @since 3.0.0 - */ - this._temp = []; + var source = (isCanvas) ? CanvasPool.create2D(this, width, height) : [ this ]; + + Texture.call(this, manager, key, source, width, height); + + this.add('__BASE', 0, 0, 0, width, height); /** - * Used to temporarily store the results of the Hit Test dropZones + * A reference to either the Canvas or WebGL Renderer that the Game instance is using. * - * @name Phaser.Input.InputPlugin#_tempZones - * @type {array} - * @private - * @default [] - * @since 3.0.0 + * @name Phaser.Textures.DynamicTexture#renderer + * @type {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} + * @since 3.2.0 */ - this._tempZones = []; + this.renderer = renderer; /** - * A list of all Game Objects that have been set to be interactive in the Scene this Input Plugin is managing. + * This flag is set to 'true' during `beginDraw` and reset to 'false` in `endDraw`, + * allowing you to determine if this Dynamic Texture is batch drawing, or not. * - * @name Phaser.Input.InputPlugin#_list - * @type {Phaser.GameObjects.GameObject[]} - * @private - * @default [] - * @since 3.0.0 + * @name Phaser.Textures.DynamicTexture#isDrawing + * @type {boolean} + * @readonly + * @since 3.60.0 */ - this._list = []; + this.isDrawing = false; /** - * Objects waiting to be inserted to the list on the next call to 'begin'. + * A reference to the Rendering Context belonging to the Canvas Element this Dynamic Texture is drawing to. * - * @name Phaser.Input.InputPlugin#_pendingInsertion - * @type {Phaser.GameObjects.GameObject[]} - * @private - * @default [] - * @since 3.0.0 + * @name Phaser.Textures.DynamicTexture#canvas + * @type {HTMLCanvasElement} + * @since 3.2.0 */ - this._pendingInsertion = []; + this.canvas = (isCanvas) ? source : null; /** - * Objects waiting to be removed from the list on the next call to 'begin'. + * The 2D Canvas Rendering Context. * - * @name Phaser.Input.InputPlugin#_pendingRemoval - * @type {Phaser.GameObjects.GameObject[]} - * @private - * @default [] - * @since 3.0.0 + * @name Phaser.Textures.DynamicTexture#context + * @readonly + * @type {CanvasRenderingContext2D} + * @since 3.7.0 */ - this._pendingRemoval = []; + this.context = (isCanvas) ? source.getContext('2d', { willReadFrequently: true }) : null; /** - * A list of all Game Objects that have been enabled for dragging. + * Is this Dynamic Texture dirty or not? If not it won't spend time clearing or filling itself. * - * @name Phaser.Input.InputPlugin#_draggable - * @type {Phaser.GameObjects.GameObject[]} - * @private - * @default [] - * @since 3.0.0 + * @name Phaser.Textures.DynamicTexture#dirty + * @type {boolean} + * @since 3.12.0 */ - this._draggable = []; + this.dirty = false; /** - * A list of all Interactive Objects currently considered as being 'draggable' by any pointer, indexed by pointer ID. + * Is this Dynamic Texture being used as the base texture for a Sprite Game Object? * - * @name Phaser.Input.InputPlugin#_drag - * @type {{0:Array,1:Array,2:Array,3:Array,4:Array,5:Array,6:Array,7:Array,8:Array,9:Array,10:Array}} - * @private - * @since 3.0.0 + * This is enabled by default, as we expect that will be the core use for Dynamic Textures. + * + * However, to disable it, call `RenderTexture.setIsSpriteTexture(false)`. + * + * You should do this _before_ drawing to this texture, so that it correctly + * inverses the frames for WebGL rendering. Not doing so will result in vertically flipped frames. + * + * This property is used in the `endDraw` method. + * + * @name Phaser.Textures.DynamicTexture#isSpriteTexture + * @type {boolean} + * @since 3.60.0 */ - this._drag = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: [] }; + this.isSpriteTexture = true; /** - * A array containing the dragStates, for this Scene, index by the Pointer ID. + * Internal erase mode flag. * - * @name Phaser.Input.InputPlugin#_dragState - * @type {number[]} + * @name Phaser.Textures.DynamicTexture#_eraseMode + * @type {boolean} * @private * @since 3.16.0 */ - this._dragState = []; + this._eraseMode = false; /** - * A list of all Interactive Objects currently considered as being 'over' by any pointer, indexed by pointer ID. + * An internal Camera that can be used to move around this Dynamic Texture. * - * @name Phaser.Input.InputPlugin#_over - * @type {{0:Array,1:Array,2:Array,3:Array,4:Array,5:Array,6:Array,7:Array,8:Array,9:Array,10:Array}} - * @private - * @since 3.0.0 + * Control it just like you would any Scene Camera. The difference is that it only impacts + * the placement of **Game Objects** (not textures) that you then draw to this texture. + * + * You can scroll, zoom and rotate this Camera. + * + * @name Phaser.Textures.DynamicTexture#camera + * @type {Phaser.Cameras.Scene2D.BaseCamera} + * @since 3.12.0 */ - this._over = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: [] }; + this.camera = new Camera(0, 0, width, height).setScene(manager.game.scene.systemScene, false); /** - * A list of valid DOM event types. + * The Render Target that belongs to this Dynamic Texture. * - * @name Phaser.Input.InputPlugin#_validTypes - * @type {string[]} - * @private - * @since 3.0.0 + * A Render Target encapsulates a framebuffer and texture for the WebGL Renderer. + * + * This property remains `null` under Canvas. + * + * @name Phaser.Textures.DynamicTexture#renderTarget + * @type {Phaser.Renderer.WebGL.RenderTarget} + * @since 3.60.0 */ - this._validTypes = [ 'onDown', 'onUp', 'onOver', 'onOut', 'onMove', 'onDragStart', 'onDrag', 'onDragEnd', 'onDragEnter', 'onDragLeave', 'onDragOver', 'onDrop' ]; + this.renderTarget = (!isCanvas) ? new RenderTarget(renderer, width, height, 1, 0, false, true, true, false) : null; /** - * Internal property that tracks frame event state. + * A reference to the WebGL Single Pipeline. * - * @name Phaser.Input.InputPlugin#_updatedThisFrame - * @type {boolean} - * @private - * @since 3.18.0 + * This property remains `null` under Canvas. + * + * @name Phaser.Textures.DynamicTexture#pipeline + * @type {Phaser.Renderer.WebGL.Pipelines.SinglePipeline} + * @since 3.60.0 */ - this._updatedThisFrame = false; + this.pipeline = (!isCanvas) ? renderer.pipelines.get(PIPELINES.SINGLE_PIPELINE) : null; - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); - scene.sys.events.on(SceneEvents.START, this.start, this); + this.setSize(width, height); }, /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. + * Resizes this Dynamic Texture to the new dimensions given. * - * @method Phaser.Input.InputPlugin#boot - * @fires Phaser.Input.Events#BOOT - * @private - * @since 3.5.1 - */ - boot: function () - { - this.cameras = this.systems.cameras; - - this.displayList = this.systems.displayList; - - this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); - - // Registered input plugins listen for this - this.pluginEvents.emit(Events.BOOT); - }, - - /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. + * In WebGL it will destroy and then re-create the frame buffer being used by this Dynamic Texture. + * In Canvas it will resize the underlying canvas DOM element. * - * @method Phaser.Input.InputPlugin#start - * @fires Phaser.Input.Events#START - * @private - * @since 3.5.0 + * Both approaches will erase everything currently drawn to this texture. + * + * If the dimensions given are the same as those already being used, calling this method will do nothing. + * + * @method Phaser.Textures.DynamicTexture#setSize + * @since 3.10.0 + * + * @param {number} width - The new width of this Dynamic Texture. + * @param {number} [height=width] - The new height of this Dynamic Texture. If not specified, will be set the same as the `width`. + * + * @return {this} This Dynamic Texture. */ - start: function () + setSize: function (width, height) { - var eventEmitter = this.systems.events; - - eventEmitter.on(SceneEvents.TRANSITION_START, this.transitionIn, this); - eventEmitter.on(SceneEvents.TRANSITION_OUT, this.transitionOut, this); - eventEmitter.on(SceneEvents.TRANSITION_COMPLETE, this.transitionComplete, this); - eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this); - eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); + if (height === undefined) { height = width; } - this.manager.events.on(Events.GAME_OUT, this.onGameOut, this); - this.manager.events.on(Events.GAME_OVER, this.onGameOver, this); + var frame = this.get(); + var source = frame.source; - this.enabled = true; + if (width !== this.width || height !== this.height) + { + if (this.canvas) + { + this.canvas.width = width; + this.canvas.height = height; + } - // Populate the pointer drag states - this._dragState = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + var renderTarget = this.renderTarget; - // Registered input plugins listen for this - this.pluginEvents.emit(Events.START); - }, + if (renderTarget) + { + renderTarget.resize(width, height); - /** - * Game Over handler. - * - * @method Phaser.Input.InputPlugin#onGameOver - * @fires Phaser.Input.Events#GAME_OVER - * @private - * @since 3.16.2 - */ - onGameOver: function (event) - { - if (this.isActive()) - { - this.emit(Events.GAME_OVER, event.timeStamp, event); - } - }, + frame.glTexture = renderTarget.texture; - /** - * Game Out handler. - * - * @method Phaser.Input.InputPlugin#onGameOut - * @fires Phaser.Input.Events#GAME_OUT - * @private - * @since 3.16.2 - */ - onGameOut: function (event) - { - if (this.isActive()) - { - this.emit(Events.GAME_OUT, event.timeStamp, event); - } - }, + source.isRenderTexture = true; + source.isGLTexture = true; + source.glTexture = renderTarget.texture; + source.glTexture.flipY = true; + } - /** - * The pre-update handler is responsible for checking the pending removal and insertion lists and - * deleting old Game Objects. - * - * @method Phaser.Input.InputPlugin#preUpdate - * @private - * @fires Phaser.Input.Events#PRE_UPDATE - * @since 3.0.0 - */ - preUpdate: function () - { - // Registered input plugins listen for this - this.pluginEvents.emit(Events.PRE_UPDATE); + this.camera.setSize(width, height); - var removeList = this._pendingRemoval; - var insertList = this._pendingInsertion; + source.width = width; + source.height = height; - var toRemove = removeList.length; - var toInsert = insertList.length; + frame.setSize(width, height); - if (toRemove === 0 && toInsert === 0) - { - // Quick bail - return; + this.width = width; + this.height = height; } - - var current = this._list; - - // Delete old gameObjects - for (var i = 0; i < toRemove; i++) + else { - var gameObject = removeList[i]; - - var index = current.indexOf(gameObject); + // Resize the frame + var baseFrame = this.getSourceImage(); - if (index > -1) + if (frame.cutX + width > baseFrame.width) { - current.splice(index, 1); + width = baseFrame.width - frame.cutX; + } - this.clear(gameObject, true); + if (frame.cutY + height > baseFrame.height) + { + height = baseFrame.height - frame.cutY; } - } - // Clear the removal list - removeList.length = 0; - this._pendingRemoval.length = 0; + frame.setSize(width, height, frame.cutX, frame.cutY); + } - // Move pendingInsertion to list (also clears pendingInsertion at the same time) - this._list = current.concat(insertList.splice(0)); + return this; }, /** - * Checks to see if both this plugin and the Scene to which it belongs is active. + * If you are planning on using this Render Texture as a base texture for Sprite + * Game Objects, then you should call this method with a value of `true` before + * drawing anything to it, otherwise you will get inverted frames in WebGL. * - * @method Phaser.Input.InputPlugin#isActive - * @since 3.10.0 + * @method Phaser.Textures.DynamicTexture#setIsSpriteTexture + * @since 3.60.0 * - * @return {boolean} `true` if the plugin and the Scene it belongs to is active. + * @param {boolean} value - Is this Render Target being used as a Sprite Texture, or not? + * + * @return {this} This Game Object instance. */ - isActive: function () + setIsSpriteTexture: function (value) { - return (this.enabled && this.scene.sys.isActive()); + this.isSpriteTexture = value; + + return this; }, /** - * This is called automatically by the Input Manager. - * It emits events for plugins to listen to and also handles polling updates, if enabled. + * Fills this Dynamic Texture with the given color. * - * @method Phaser.Input.InputPlugin#updatePoll - * @since 3.18.0 + * By default it will fill the entire texture, however you can set it to fill a specific + * rectangular area by using the x, y, width and height arguments. * - * @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. + * The color should be given in hex format, i.e. 0xff0000 for red, 0x00ff00 for green, etc. * - * @return {boolean} `true` if the plugin and the Scene it belongs to is active. + * @method Phaser.Textures.DynamicTexture#fill + * @since 3.2.0 + * + * @param {number} rgb - The color to fill this Dynamic Texture with, such as 0xff0000 for red. + * @param {number} [alpha=1] - The alpha value used by the fill. + * @param {number} [x=0] - The left coordinate of the fill rectangle. + * @param {number} [y=0] - The top coordinate of the fill rectangle. + * @param {number} [width=this.width] - The width of the fill rectangle. + * @param {number} [height=this.height] - The height of the fill rectangle. + * + * @return {this} This Dynamic Texture instance. */ - updatePoll: function (time, delta) + fill: function (rgb, alpha, x, y, width, height) { - if (!this.isActive()) - { - return false; - } - - // The plugins should update every frame, regardless if there has been - // any DOM input events or not (such as the Gamepad and Keyboard) - this.pluginEvents.emit(Events.UPDATE, time, delta); + var camera = this.camera; + var renderer = this.renderer; - // We can leave now if we've already updated once this frame via the immediate DOM event handlers - if (this._updatedThisFrame) - { - this._updatedThisFrame = false; + if (alpha === undefined) { alpha = 1; } + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.width; } + if (height === undefined) { height = this.height; } - return false; - } + var r = (rgb >> 16 & 0xFF); + var g = (rgb >> 8 & 0xFF); + var b = (rgb & 0xFF); - var i; - var manager = this.manager; + var renderTarget = this.renderTarget; - var pointers = manager.pointers; - var pointersTotal = manager.pointersTotal; + camera.preRender(); - for (i = 0; i < pointersTotal; i++) + if (renderTarget) { - pointers[i].updateMotion(); - } + renderTarget.bind(true); - // No point going any further if there aren't any interactive objects - if (this._list.length === 0) - { - return false; - } + var pipeline = this.pipeline.manager.set(this.pipeline); - var rate = this.pollRate; + var sx = renderer.width / renderTarget.width; + var sy = renderer.height / renderTarget.height; - if (rate === -1) - { - return false; - } - else if (rate > 0) - { - this._pollTimer -= delta; + pipeline.drawFillRect( + x * sx, y * sy, width * sx, height * sy, + Utils.getTintFromFloats(b / 255, g / 255, r / 255, 1), + alpha + ); - if (this._pollTimer < 0) - { - // Discard timer diff, we're ready to poll again - this._pollTimer = this.pollRate; - } - else - { - // Not enough time has elapsed since the last poll, so abort now - return false; - } + renderTarget.unbind(true); } - - // We got this far? Then we should poll for movement - var captured = false; - - for (i = 0; i < pointersTotal; i++) + else { - var total = 0; - - var pointer = pointers[i]; - - // Always reset this array - this._tempZones = []; - - // _temp contains a hit tested and camera culled list of IO objects - this._temp = this.hitTestPointer(pointer); - - this.sortGameObjects(this._temp, pointer); - this.sortDropZones(this._tempZones); - - if (this.topOnly) - { - // Only the top-most one counts now, so safely ignore the rest - if (this._temp.length) - { - this._temp.splice(1); - } - - if (this._tempZones.length) - { - this._tempZones.splice(1); - } - } + var ctx = this.context; - total += this.processOverOutEvents(pointer); + renderer.setContext(ctx); - if (this.getDragState(pointer) === 2) - { - this.processDragThresholdEvent(pointer, time); - } + ctx.globalCompositeOperation = 'source-over'; + ctx.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')'; + ctx.fillRect(x, y, width, height); - if (total > 0) - { - // We interacted with an event in this Scene, so block any Scenes below us from doing the same this frame - captured = true; - } + renderer.setContext(); } - return captured; + this.dirty = true; + + return this; }, /** - * This method is called when a DOM Event is received by the Input Manager. It handles dispatching the events - * to relevant input enabled Game Objects in this scene. - * - * @method Phaser.Input.InputPlugin#update - * @private - * @fires Phaser.Input.Events#UPDATE - * @since 3.0.0 + * Fully clears this Dynamic Texture, erasing everything from it and resetting it back to + * a blank, transparent, texture. * - * @param {number} type - The type of event to process. - * @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred. + * @method Phaser.Textures.DynamicTexture#clear + * @since 3.2.0 * - * @return {boolean} `true` if this Scene has captured the input events from all other Scenes, otherwise `false`. + * @return {this} This Dynamic Texture instance. */ - update: function (type, pointers) + clear: function () { - if (!this.isActive()) - { - return false; - } - - var pointersTotal = pointers.length; - var captured = false; - - for (var i = 0; i < pointersTotal; i++) + if (this.dirty) { - var total = 0; - var pointer = pointers[i]; - - // Always reset this array - this._tempZones = []; - - // _temp contains a hit tested and camera culled list of IO objects - this._temp = this.hitTestPointer(pointer); - - this.sortGameObjects(this._temp, pointer); - this.sortDropZones(this._tempZones); + var ctx = this.context; + var renderTarget = this.renderTarget; - if (this.topOnly) + if (renderTarget) { - // Only the top-most one counts now, so safely ignore the rest - if (this._temp.length) - { - this._temp.splice(1); - } - - if (this._tempZones.length) - { - this._tempZones.splice(1); - } + renderTarget.clear(); } - - switch (type) + else if (ctx) { - case CONST.MOUSE_DOWN: - total += this.processDragDownEvent(pointer); - total += this.processDownEvents(pointer); - total += this.processOverOutEvents(pointer); - break; - - case CONST.MOUSE_UP: - total += this.processDragUpEvent(pointer); - total += this.processUpEvents(pointer); - total += this.processOverOutEvents(pointer); - break; - - case CONST.TOUCH_START: - total += this.processDragDownEvent(pointer); - total += this.processDownEvents(pointer); - total += this.processOverEvents(pointer); - break; - - case CONST.TOUCH_END: - case CONST.TOUCH_CANCEL: - total += this.processDragUpEvent(pointer); - total += this.processUpEvents(pointer); - total += this.processOutEvents(pointer); - break; - - case CONST.MOUSE_MOVE: - case CONST.TOUCH_MOVE: - total += this.processDragMoveEvent(pointer); - total += this.processMoveEvents(pointer); - total += this.processOverOutEvents(pointer); - break; - - case CONST.MOUSE_WHEEL: - total += this.processWheelEvent(pointer); - break; + ctx.save(); + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.clearRect(0, 0, this.width, this.height); + ctx.restore(); } - if (total > 0) - { - // We interacted with an event in this Scene, so block any Scenes below us from doing the same this frame - captured = true; - } + this.dirty = false; } - this._updatedThisFrame = true; - - return captured; + return this; }, /** - * Clears a Game Object so it no longer has an Interactive Object associated with it. - * The Game Object is then queued for removal from the Input Plugin on the next update. + * Takes the given texture key and frame and then stamps it at the given + * x and y coordinates. You can use the optional 'config' argument to provide + * lots more options about how the stamp is applied, including the alpha, + * tint, angle, scale and origin. * - * @method Phaser.Input.InputPlugin#clear - * @since 3.0.0 + * By default, the frame will stamp on the x/y coordinates based on its center. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will have its Interactive Object removed. - * @param {boolean} [skipQueue=false] - Skip adding this Game Object into the removal queue? + * If you wish to stamp from the top-left, set the config `originX` and + * `originY` properties both to zero. * - * @return {Phaser.GameObjects.GameObject} The Game Object that had its Interactive Object removed. + * @method Phaser.Textures.DynamicTexture#stamp + * @since 3.60.0 + * + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param {number} [x=0] - The x position to draw the frame at. + * @param {number} [y=0] - The y position to draw the frame at. + * @param {Phaser.Types.Textures.StampConfig} [config] - The stamp configuration object, allowing you to set the alpha, tint, angle, scale and origin of the stamp. + * + * @return {this} This Dynamic Texture instance. */ - clear: function (gameObject, skipQueue) + stamp: function (key, frame, x, y, config) { - if (skipQueue === undefined) { skipQueue = false; } + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } - var input = gameObject.input; + var alpha = GetFastValue(config, 'alpha', 1); + var tint = GetFastValue(config, 'tint', 0xffffff); + var angle = GetFastValue(config, 'angle', 0); + var rotation = GetFastValue(config, 'rotation', 0); + var scale = GetFastValue(config, 'scale', 1); + var scaleX = GetFastValue(config, 'scaleX', scale); + var scaleY = GetFastValue(config, 'scaleY', scale); + var originX = GetFastValue(config, 'originX', 0.5); + var originY = GetFastValue(config, 'originY', 0.5); + var blendMode = GetFastValue(config, 'blendMode', 0); + var erase = GetFastValue(config, 'erase', false); + var skipBatch = GetFastValue(config, 'skipBatch', false); - // If GameObject.input already cleared from higher class - if (!input) + var stamp = this.manager.resetStamp(alpha, tint); + + stamp.setAngle(0); + + if (angle !== 0) { - return; + stamp.setAngle(angle); } - - if (!skipQueue) + else if (rotation !== 0) { - this.queueForRemoval(gameObject); + stamp.setRotation(rotation); } - input.gameObject = undefined; - input.target = undefined; - input.hitArea = undefined; - input.hitAreaCallback = undefined; - input.callbackContext = undefined; - - gameObject.input = null; + stamp.setScale(scaleX, scaleY); + stamp.setTexture(key, frame); + stamp.setOrigin(originX, originY); + stamp.setBlendMode(blendMode); - // Clear from _draggable, _drag and _over - var index = this._draggable.indexOf(gameObject); - - if (index > -1) + if (erase) { - this._draggable.splice(index, 1); + this._eraseMode = true; } - index = this._drag[0].indexOf(gameObject); - - if (index > -1) + if (!skipBatch) { - this._drag[0].splice(index, 1); + this.draw(stamp, x, y); } - - index = this._over[0].indexOf(gameObject); - - if (index > -1) + else { - this._over[0].splice(index, 1); + this.batchGameObject(stamp, x, y); + } - this.manager.resetCursor(input); + if (erase) + { + this._eraseMode = false; } - return gameObject; + return this; }, /** - * Disables Input on a single Game Object. + * Draws the given object, or an array of objects, to this Dynamic Texture using a blend mode of ERASE. + * This has the effect of erasing any filled pixels present in the objects from this texture. * - * An input disabled Game Object still retains its Interactive Object component and can be re-enabled - * at any time, by passing it to `InputPlugin.enable`. + * It can accept any of the following: * - * @method Phaser.Input.InputPlugin#disable - * @since 3.0.0 + * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. + * * Tilemap Layers. + * * A Group. The contents of which will be iterated and drawn in turn. + * * A Container. The contents of which will be iterated fully, and drawn in turn. + * * A Scene Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture, or a Render Texture. + * * A Texture Frame instance. + * * A string. This is used to look-up the texture from the Texture Manager. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to have its input system disabled. + * Note: You cannot erase a Dynamic Texture from itself. + * + * If passing in a Group or Container it will only draw children that return `true` + * when their `willRender()` method is called. I.e. a Container with 10 children, + * 5 of which have `visible=false` will only draw the 5 visible ones. + * + * If passing in an array of Game Objects it will draw them all, regardless if + * they pass a `willRender` check or not. + * + * You can pass in a string in which case it will look for a texture in the Texture + * Manager matching that string, and draw the base frame. + * + * You can pass in the `x` and `y` coordinates to draw the objects at. The use of + * the coordinates differ based on what objects are being drawn. If the object is + * a Group, Container or Display List, the coordinates are _added_ to the positions + * of the children. For all other types of object, the coordinates are exact. + * + * Calling this method causes the WebGL batch to flush, so it can write the texture + * data to the framebuffer being used internally. The batch is flushed at the end, + * after the entries have been iterated. So if you've a bunch of objects to draw, + * try and pass them in an array in one single call, rather than making lots of + * separate calls. + * + * If you are not planning on using this Dynamic Texture as a base texture for Sprite + * Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before + * calling this method, otherwise you will get vertically inverted frames in WebGL. + * + * @method Phaser.Textures.DynamicTexture#erase + * @since 3.16.0 + * + * @param {any} entries - Any renderable Game Object, or Group, Container, Display List, Render Texture, Texture Frame, or an array of any of these. + * @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object. + * @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object. + * + * @return {this} This Dynamic Texture instance. */ - disable: function (gameObject) + erase: function (entries, x, y) { - gameObject.input.enabled = false; + this._eraseMode = true; + + this.draw(entries, x, y); + + this._eraseMode = false; + + return this; }, /** - * Enable a Game Object for interaction. + * Draws the given object, or an array of objects, to this Dynamic Texture. * - * If the Game Object already has an Interactive Object component, it is enabled and returned. + * It can accept any of the following: * - * Otherwise, a new Interactive Object component is created and assigned to the Game Object's `input` property. + * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. + * * Tilemap Layers. + * * A Group. The contents of which will be iterated and drawn in turn. + * * A Container. The contents of which will be iterated fully, and drawn in turn. + * * A Scene Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture, or a Render Texture. + * * A Texture Frame instance. + * * A string. This is used to look-up the texture from the Texture Manager. * - * Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area - * for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced - * input detection. + * Note 1: You cannot draw a Dynamic Texture to itself. * - * If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If - * this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific - * shape for it to use. + * Note 2: For Game Objects that have Post FX Pipelines, the pipeline _cannot_ be + * used when drawn to this texture. * - * You can also provide an Input Configuration Object as the only argument to this method. + * If passing in a Group or Container it will only draw children that return `true` + * when their `willRender()` method is called. I.e. a Container with 10 children, + * 5 of which have `visible=false` will only draw the 5 visible ones. * - * @method Phaser.Input.InputPlugin#enable - * @since 3.0.0 + * If passing in an array of Game Objects it will draw them all, regardless if + * they pass a `willRender` check or not. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to be enabled for input. - * @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. - * @param {Phaser.Types.Input.HitAreaCallback} [hitAreaCallback] - The 'contains' function to invoke to check if the pointer is within the hit area. - * @param {boolean} [dropZone=false] - Is this Game Object a drop zone or not? + * You can pass in a string in which case it will look for a texture in the Texture + * Manager matching that string, and draw the base frame. If you need to specify + * exactly which frame to draw then use the method `drawFrame` instead. * - * @return {this} This Input Plugin. + * You can pass in the `x` and `y` coordinates to draw the objects at. The use of + * the coordinates differ based on what objects are being drawn. If the object is + * a Group, Container or Display List, the coordinates are _added_ to the positions + * of the children. For all other types of object, the coordinates are exact. + * + * The `alpha` and `tint` values are only used by Texture Frames. + * Game Objects use their own alpha and tint values when being drawn. + * + * Calling this method causes the WebGL batch to flush, so it can write the texture + * data to the framebuffer being used internally. The batch is flushed at the end, + * after the entries have been iterated. So if you've a bunch of objects to draw, + * try and pass them in an array in one single call, rather than making lots of + * separate calls. + * + * If you are not planning on using this Dynamic Texture as a base texture for Sprite + * Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before + * calling this method, otherwise you will get vertically inverted frames in WebGL. + * + * @method Phaser.Textures.DynamicTexture#draw + * @since 3.2.0 + * + * @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these. + * @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object. + * @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. + * + * @return {this} This Dynamic Texture instance. */ - enable: function (gameObject, hitArea, hitAreaCallback, dropZone) + draw: function (entries, x, y, alpha, tint) { - if (dropZone === undefined) { dropZone = false; } + this.beginDraw(); + this.batchDraw(entries, x, y, alpha, tint); + this.endDraw(); - if (gameObject.input) - { - // If it is already has an InteractiveObject then just enable it and return - gameObject.input.enabled = true; - } - else - { - // Create an InteractiveObject and enable it - this.setHitArea(gameObject, hitArea, hitAreaCallback); - } + return this; + }, - if (gameObject.input && dropZone && !gameObject.input.dropZone) - { - gameObject.input.dropZone = dropZone; - } + /** + * Draws the Texture Frame to the Render Texture at the given position. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * + * ```javascript + * var rt = this.add.renderTexture(0, 0, 800, 600); + * rt.drawFrame(key, frame); + * ``` + * + * You can optionally provide a position, alpha and tint value to apply to the frame + * before it is drawn. + * + * Calling this method will cause a batch flush, so if you've got a stack of things to draw + * in a tight loop, try using the `draw` method instead. + * + * If you need to draw a Sprite to this Render Texture, use the `draw` method instead. + * + * If you are not planning on using this Dynamic Texture as a base texture for Sprite + * Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before + * calling this method, otherwise you will get vertically inverted frames in WebGL. + * + * @method Phaser.Textures.DynamicTexture#drawFrame + * @since 3.12.0 + * + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param {number} [x=0] - The x position to draw the frame at. + * @param {number} [y=0] - The y position to draw the frame at. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. WebGL only. + * + * @return {this} This Dynamic Texture instance. + */ + drawFrame: function (key, frame, x, y, alpha, tint) + { + this.beginDraw(); + this.batchDrawFrame(key, frame, x, y, alpha, tint); + this.endDraw(); return this; }, /** - * Takes the given Pointer and performs a hit test against it, to see which interactive Game Objects - * it is currently above. + * Takes the given Texture Frame and draws it to this Dynamic Texture as a fill pattern, + * i.e. in a grid-layout based on the frame dimensions. * - * The hit test is performed against which-ever Camera the Pointer is over. If it is over multiple - * cameras, it starts checking the camera at the top of the camera list, and if nothing is found, iterates down the list. + * Textures are referenced by their string-based keys, as stored in the Texture Manager. * - * @method Phaser.Input.InputPlugin#hitTestPointer - * @since 3.0.0 + * You can optionally provide a position, width, height, alpha and tint value to apply to + * the frames before they are drawn. The position controls the top-left where the repeating + * fill will start from. The width and height control the size of the filled area. * - * @param {Phaser.Input.Pointer} pointer - The Pointer to check against the Game Objects. + * The position can be negative if required, but the dimensions cannot. * - * @return {Phaser.GameObjects.GameObject[]} An array of all the interactive Game Objects the Pointer was above. + * Calling this method will cause a batch flush by default. Use the `skipBatch` argument + * to disable this if this call is part of a larger batch draw. + * + * If you are not planning on using this Dynamic Texture as a base texture for Sprite + * Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before + * calling this method, otherwise you will get vertically inverted frames in WebGL. + * + * @method Phaser.Textures.DynamicTexture#repeat + * @since 3.60.0 + * + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param {number} [x=0] - The x position to start drawing the frames from (can be negative to offset). + * @param {number} [y=0] - The y position to start drawing the frames from (can be negative to offset). + * @param {number} [width=this.width] - The width of the area to repeat the frame within. Defaults to the width of this Dynamic Texture. + * @param {number} [height=this.height] - The height of the area to repeat the frame within. Defaults to the height of this Dynamic Texture. + * @param {number} [alpha=1] - The alpha to use. Defaults to 1, no alpha. + * @param {number} [tint=0xffffff] - WebGL only. The tint color to use. Leave as undefined, or 0xffffff to have no tint. + * @param {boolean} [skipBatch=false] - Skip beginning and ending a batch with this call. Use if this is part of a bigger batched draw. + * + * @return {this} This Dynamic Texture instance. */ - hitTestPointer: function (pointer) + repeat: function (key, frame, x, y, width, height, alpha, tint, skipBatch) { - var cameras = this.cameras.getCamerasBelowPointer(pointer); + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (width === undefined) { width = this.width; } + if (height === undefined) { height = this.height; } + if (alpha === undefined) { alpha = 1; } + if (tint === undefined) { tint = 0xffffff; } + if (skipBatch === undefined) { skipBatch = false; } - for (var c = 0; c < cameras.length; c++) + if (key instanceof Frame) { - var camera = cameras[c]; + frame = key; + } + else + { + frame = this.manager.getFrame(key, frame); + } - // Get a list of all objects that can be seen by the camera below the pointer in the scene and store in 'over' array. - // All objects in this array are input enabled, as checked by the hitTest method, so we don't need to check later on as well. - var over = this.manager.hitTest(pointer, this._list, camera); + if (!frame) + { + return this; + } - // Filter out the drop zones - for (var i = 0; i < over.length; i++) - { - var obj = over[i]; + var stamp = this.manager.resetStamp(alpha, tint); - if (obj.input.dropZone) - { - this._tempZones.push(obj); - } - } + stamp.setFrame(frame); + stamp.setOrigin(0); - if (over.length > 0) - { - pointer.camera = camera; + var frameWidth = frame.width; + var frameHeight = frame.height; - return over; - } - } + // Clamp to integer + width = Math.floor(width); + height = Math.floor(height); - // If we got this far then there were no Game Objects below the pointer, but it was still over - // a camera, so set that the top-most one into the pointer + // How many stamps can we fit in horizontally and vertically? + // We round this number up to allow for excess overflow + var hmax = Math.ceil(width / frameWidth); + var vmax = Math.ceil(height / frameHeight); - pointer.camera = cameras[0]; + // How much extra horizontal and vertical space do we have on the right/bottom? + var hdiff = (hmax * frameWidth) - width; + var vdiff = (vmax * frameHeight) - height; - return []; - }, + if (hdiff > 0) + { + hdiff = frameWidth - hdiff; + } - /** - * An internal method that handles the Pointer down event. - * - * @method Phaser.Input.InputPlugin#processDownEvents - * @private - * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_DOWN - * @fires Phaser.Input.Events#GAMEOBJECT_DOWN - * @fires Phaser.Input.Events#POINTER_DOWN - * @fires Phaser.Input.Events#POINTER_DOWN_OUTSIDE - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer being tested. - * - * @return {number} The total number of objects interacted with. - */ - processDownEvents: function (pointer) - { - var total = 0; - var currentlyOver = this._temp; + if (vdiff > 0) + { + vdiff = frameHeight - vdiff; + } - var _eventData = this._eventData; - var _eventContainer = this._eventContainer; + // x/y may be negative - _eventData.cancelled = false; + if (x < 0) + { + hmax += Math.ceil(Math.abs(x) / frameWidth); + } - var aborted = false; + if (y < 0) + { + vmax += Math.ceil(Math.abs(y) / frameHeight); + } - // Go through all objects the pointer was over and fire their events / callbacks - for (var i = 0; i < currentlyOver.length; i++) + var dx = x; + var dy = y; + + var useCrop = false; + var cropRect = this.manager.stampCrop.setTo(0, 0, frameWidth, frameHeight); + + if (!skipBatch) { - var gameObject = currentlyOver[i]; + this.beginDraw(); + } - if (!gameObject.input) + for (var ty = 0; ty < vmax; ty++) + { + // Negative offset? + if (dy + frameHeight < 0) { + // We can't see it, as it's off the top + dy += frameHeight; continue; } - total++; + for (var tx = 0; tx < hmax; tx++) + { + useCrop = false; - gameObject.emit(Events.GAMEOBJECT_POINTER_DOWN, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); + // Negative offset? + if (dx + frameWidth < 0) + { + // We can't see it, as it's fully off the left + dx += frameWidth; + continue; + } + else if (dx < 0) + { + // Partially off the left + useCrop = true; + cropRect.width = (frameWidth + dx); + cropRect.x = frameWidth - cropRect.width; + } - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } + // Negative vertical offset + if (dy < 0) + { + // Partially off the top + useCrop = true; + cropRect.height = (frameHeight + dy); + cropRect.y = frameHeight - cropRect.height; + } - this.emit(Events.GAMEOBJECT_DOWN, pointer, gameObject, _eventContainer); + if (hdiff > 0 && tx === hmax - 1) + { + useCrop = true; + cropRect.width = hdiff; + } - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; + if (vdiff > 0 && ty === vmax - 1) + { + useCrop = true; + cropRect.height = vdiff; + } + + if (useCrop) + { + stamp.setCrop(cropRect); + } + + this.batchGameObject(stamp, dx, dy); + + // Reset crop + stamp.isCropped = false; + + cropRect.setTo(0, 0, frameWidth, frameHeight); + + dx += frameWidth; } + + dx = x; + dy += frameHeight; } - // If they released outside the canvas, but pressed down inside it, we'll still dispatch the event. - if (!aborted && this.manager) + if (!skipBatch) { - if (pointer.downElement === this.manager.game.canvas) - { - this.emit(Events.POINTER_DOWN, pointer, currentlyOver); - } - else - { - this.emit(Events.POINTER_DOWN_OUTSIDE, pointer); - } + this.endDraw(); } - return total; + return this; }, /** - * Returns the drag state of the given Pointer for this Input Plugin. + * Use this method if you need to batch draw a large number of Game Objects to + * this Dynamic Texture in a single pass, or on a frequent basis. This is especially + * useful under WebGL, however, if your game is using Canvas only, it will not make + * any speed difference in that situation. * - * The state will be one of the following: + * This method starts the beginning of a batched draw, unless one is already open. * - * 0 = Not dragging anything - * 1 = Primary button down and objects below, so collect a draglist - * 2 = Pointer being checked if meets drag criteria - * 3 = Pointer meets criteria, notify the draglist - * 4 = Pointer actively dragging the draglist and has moved - * 5 = Pointer actively dragging but has been released, notify draglist + * Batched drawing is faster than calling `draw` in loop, but you must be careful + * to manage the flow of code and remember to call `endDraw()` when you're finished. * - * @method Phaser.Input.InputPlugin#getDragState - * @since 3.16.0 + * If you don't need to draw large numbers of objects it's much safer and easier + * to use the `draw` method instead. * - * @param {Phaser.Input.Pointer} pointer - The Pointer to get the drag state for. + * The flow should be: * - * @return {number} The drag state of the given Pointer. + * ```javascript + * // Call once: + * DynamicTexture.beginDraw(); + * + * // repeat n times: + * DynamicTexture.batchDraw(); + * // or + * DynamicTexture.batchDrawFrame(); + * + * // Call once: + * DynamicTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Dynamic Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * @method Phaser.Textures.DynamicTexture#beginDraw + * @since 3.50.0 + * + * @return {this} This Dynamic Texture instance. */ - getDragState: function (pointer) + beginDraw: function () { - return this._dragState[pointer.id]; + if (!this.isDrawing) + { + var camera = this.camera; + var renderer = this.renderer; + var renderTarget = this.renderTarget; + + camera.preRender(); + + if (renderTarget) + { + renderer.beginCapture(renderTarget.width, renderTarget.height); + } + else + { + renderer.setContext(this.context); + } + + this.isDrawing = true; + } + + return this; }, /** - * Sets the drag state of the given Pointer for this Input Plugin. + * Use this method if you have already called `beginDraw` and need to batch + * draw a large number of objects to this Dynamic Texture. * - * The state must be one of the following values: + * This method batches the drawing of the given objects to this texture, + * without causing a WebGL bind or batch flush for each one. * - * 0 = Not dragging anything - * 1 = Primary button down and objects below, so collect a draglist - * 2 = Pointer being checked if meets drag criteria - * 3 = Pointer meets criteria, notify the draglist - * 4 = Pointer actively dragging the draglist and has moved - * 5 = Pointer actively dragging but has been released, notify draglist + * It is faster than calling `draw`, but you must be careful to manage the + * flow of code and remember to call `endDraw()`. If you don't need to draw large + * numbers of objects it's much safer and easier to use the `draw` method instead. * - * @method Phaser.Input.InputPlugin#setDragState - * @since 3.16.0 + * The flow should be: * - * @param {Phaser.Input.Pointer} pointer - The Pointer to set the drag state for. - * @param {number} state - The drag state value. An integer between 0 and 5. + * ```javascript + * // Call once: + * DynamicTexture.beginDraw(); + * + * // repeat n times: + * DynamicTexture.batchDraw(); + * // or + * DynamicTexture.batchDrawFrame(); + * + * // Call once: + * DynamicTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Dynamic Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * This method can accept any of the following: + * + * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. + * * Tilemap Layers. + * * A Group. The contents of which will be iterated and drawn in turn. + * * A Container. The contents of which will be iterated fully, and drawn in turn. + * * A Scene's Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture or Render Texture. + * * A Texture Frame instance. + * * A string. This is used to look-up a texture from the Texture Manager. + * + * Note: You cannot draw a Dynamic Texture to itself. + * + * If passing in a Group or Container it will only draw children that return `true` + * when their `willRender()` method is called. I.e. a Container with 10 children, + * 5 of which have `visible=false` will only draw the 5 visible ones. + * + * If passing in an array of Game Objects it will draw them all, regardless if + * they pass a `willRender` check or not. + * + * You can pass in a string in which case it will look for a texture in the Texture + * Manager matching that string, and draw the base frame. If you need to specify + * exactly which frame to draw then use the method `drawFrame` instead. + * + * You can pass in the `x` and `y` coordinates to draw the objects at. The use of + * the coordinates differ based on what objects are being drawn. If the object is + * a Group, Container or Display List, the coordinates are _added_ to the positions + * of the children. For all other types of object, the coordinates are exact. + * + * The `alpha` and `tint` values are only used by Texture Frames. + * Game Objects use their own alpha and tint values when being drawn. + * + * @method Phaser.Textures.DynamicTexture#batchDraw + * @since 3.50.0 + * + * @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Dynamic or Texture, Texture Frame or an array of any of these. + * @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object. + * @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. + * + * @return {this} This Dynamic Texture instance. */ - setDragState: function (pointer, state) + batchDraw: function (entries, x, y, alpha, tint) { - this._dragState[pointer.id] = state; + if (!Array.isArray(entries)) + { + entries = [ entries ]; + } + + this.batchList(entries, x, y, alpha, tint); + + return this; }, /** - * Checks to see if a Pointer is ready to drag the objects below it, based on either a distance - * or time threshold. + * Use this method if you have already called `beginDraw` and need to batch + * draw a large number of texture frames to this Dynamic Texture. + * + * This method batches the drawing of the given frames to this Dynamic Texture, + * without causing a WebGL bind or batch flush for each one. + * + * It is faster than calling `drawFrame`, but you must be careful to manage the + * flow of code and remember to call `endDraw()`. If you don't need to draw large + * numbers of frames it's much safer and easier to use the `drawFrame` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * DynamicTexture.beginDraw(); + * + * // repeat n times: + * DynamicTexture.batchDraw(); + * // or + * DynamicTexture.batchDrawFrame(); + * + * // Call once: + * DynamicTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Dynamic Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. * - * @method Phaser.Input.InputPlugin#processDragThresholdEvent - * @private - * @since 3.18.0 + * You can optionally provide a position, alpha and tint value to apply to the frame + * before it is drawn. * - * @param {Phaser.Input.Pointer} pointer - The Pointer to check the drag thresholds on. - * @param {number} time - The current time. + * @method Phaser.Textures.DynamicTexture#batchDrawFrame + * @since 3.50.0 + * + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. + * @param {number} [x=0] - The x position to draw the frame at. + * @param {number} [y=0] - The y position to draw the frame at. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. + * + * @return {this} This Dynamic Texture instance. */ - processDragThresholdEvent: function (pointer, time) + batchDrawFrame: function (key, frame, x, y, alpha, tint) { - var passed = false; - var timeThreshold = this.dragTimeThreshold; - var distanceThreshold = this.dragDistanceThreshold; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (alpha === undefined) { alpha = 1; } + if (tint === undefined) { tint = 0xffffff; } - if (distanceThreshold > 0 && DistanceBetween(pointer.x, pointer.y, pointer.downX, pointer.downY) >= distanceThreshold) - { - // It has moved far enough to be considered a drag - passed = true; - } - else if (timeThreshold > 0 && (time >= pointer.downTime + timeThreshold)) - { - // It has been held down long enough to be considered a drag - passed = true; - } + var textureFrame = this.manager.getFrame(key, frame); - if (passed) + if (textureFrame) { - this.setDragState(pointer, 3); - - return this.processDragStartList(pointer); + if (this.renderTarget) + { + this.pipeline.batchTextureFrame(textureFrame, x, y, tint, alpha, this.camera.matrix, null); + } + else + { + this.batchTextureFrame(textureFrame, x, y, alpha, tint); + } } + + return this; }, /** - * Processes the drag list for the given pointer and dispatches the start events for each object on it. + * Use this method to finish batch drawing to this Dynamic Texture. * - * @method Phaser.Input.InputPlugin#processDragStartList - * @private - * @fires Phaser.Input.Events#DRAG_START - * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_START - * @since 3.18.0 + * Doing so will stop the WebGL Renderer from capturing draws and then blit the + * framebuffer to the Render Target owned by this texture. * - * @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on. + * Calling this method without first calling `beginDraw` will have no effect. * - * @return {number} The number of items that DRAG_START was called on. + * Batch drawing is faster than calling `draw`, but you must be careful to manage the + * flow of code and remember to call `endDraw()` when you're finished. + * + * If you don't need to draw large numbers of objects it's much safer and easier + * to use the `draw` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * DynamicTexture.beginDraw(); + * + * // repeat n times: + * DynamicTexture.batchDraw(); + * // or + * DynamicTexture.batchDrawFrame(); + * + * // Call once: + * DynamicTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Dynamic Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * @method Phaser.Textures.DynamicTexture#endDraw + * @since 3.50.0 + * + * @param {boolean} [erase=false] - Draws all objects in this batch using a blend mode of ERASE. This has the effect of erasing any filled pixels in the objects being drawn. + * + * @return {this} This Dynamic Texture instance. */ - processDragStartList: function (pointer) + endDraw: function (erase) { - // 3 = Pointer meets criteria and is freshly down, notify the draglist - if (this.getDragState(pointer) !== 3) - { - return 0; - } - - var list = this._drag[pointer.id]; + if (erase === undefined) { erase = this._eraseMode; } - for (var i = 0; i < list.length; i++) + if (this.isDrawing) { - var gameObject = list[i]; - - var input = gameObject.input; + var renderer = this.renderer; - input.dragState = 2; + var renderTarget = this.renderTarget; - input.dragStartX = gameObject.x; - input.dragStartY = gameObject.y; + if (renderTarget) + { + var canvasTarget = renderer.endCapture(); - input.dragStartXGlobal = pointer.worldX; - input.dragStartYGlobal = pointer.worldY; + var util = renderer.pipelines.setUtility(); - input.dragX = input.dragStartXGlobal - input.dragStartX; - input.dragY = input.dragStartYGlobal - input.dragStartY; + util.blitFrame(canvasTarget, renderTarget, 1, false, false, erase, this.isSpriteTexture); - gameObject.emit(Events.GAMEOBJECT_DRAG_START, pointer, input.dragX, input.dragY); + renderer.resetScissor(); + renderer.resetViewport(); + } + else + { + renderer.setContext(); + } - this.emit(Events.DRAG_START, pointer, gameObject); + this.dirty = true; + this.isDrawing = false; } - this.setDragState(pointer, 4); - - return list.length; + return this; }, /** - * Processes a 'drag down' event for the given pointer. Checks the pointer state, builds-up the drag list - * and prepares them all for interaction. + * Internal method that handles the drawing of an array of children. * - * @method Phaser.Input.InputPlugin#processDragDownEvent + * @method Phaser.Textures.DynamicTexture#batchList * @private - * @since 3.18.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on. + * @since 3.12.0 * - * @return {number} The number of items that were collected on the drag list. + * @param {array} children - The array of Game Objects, Textures or Frames to draw. + * @param {number} [x=0] - The x position to offset the Game Object by. + * @param {number} [y=0] - The y position to offset the Game Object by. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. */ - processDragDownEvent: function (pointer) + batchList: function (children, x, y, alpha, tint) { - var currentlyOver = this._temp; + var len = children.length; - if (this._draggable.length === 0 || currentlyOver.length === 0 || !pointer.primaryDown || this.getDragState(pointer) !== 0) + if (len === 0) { - // There are no draggable items, no over items or the pointer isn't down, so let's not even bother going further - return 0; + return; } - // 1 = Primary button down and objects below, so collect a draglist - this.setDragState(pointer, 1); - - // Get draggable objects, sort them, pick the top (or all) and store them somewhere - var draglist = []; - - for (var i = 0; i < currentlyOver.length; i++) + for (var i = 0; i < len; i++) { - var gameObject = currentlyOver[i]; + var entry = children[i]; - if (gameObject.input.draggable && (gameObject.input.dragState === 0)) + if (!entry || entry === this) { - draglist.push(gameObject); + continue; } - } - - if (draglist.length === 0) - { - this.setDragState(pointer, 0); - - return 0; - } - else if (draglist.length > 1) - { - this.sortGameObjects(draglist, pointer); - if (this.topOnly) + if (entry.renderWebGL || entry.renderCanvas) { - draglist.splice(1); + // Game Objects + this.batchGameObject(entry, x, y); + } + else if (entry.isParent || entry.list) + { + // Groups / Display Lists + this.batchGroup(entry.getChildren(), x, y); + } + else if (typeof entry === 'string') + { + // Texture key + this.batchTextureFrameKey(entry, null, x, y, alpha, tint); + } + else if (entry instanceof Frame) + { + // Texture Frame instance + this.batchTextureFrame(entry, x, y, alpha, tint); + } + else if (Array.isArray(entry)) + { + // Another Array + this.batchList(entry, x, y, alpha, tint); } } + }, - // draglist now contains all potential candidates for dragging - this._drag[pointer.id] = draglist; - - if (this.dragDistanceThreshold === 0 && this.dragTimeThreshold === 0) - { - // No drag criteria, so snap immediately to mode 3 - this.setDragState(pointer, 3); + /** + * Internal method that handles drawing the contents of a Phaser Group to this Dynamic Texture. + * + * @method Phaser.Textures.DynamicTexture#batchGroup + * @private + * @since 3.12.0 + * + * @param {array} children - The array of Game Objects to draw. + * @param {number} [x=0] - The x position to offset the Game Objects by. + * @param {number} [y=0] - The y position to offset the Game Objects by. + */ + batchGroup: function (children, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } - return this.processDragStartList(pointer); - } - else + for (var i = 0; i < children.length; i++) { - // Check the distance / time on the next event - this.setDragState(pointer, 2); + var entry = children[i]; - return 0; + if (entry.willRender(this.camera)) + { + this.batchGameObject(entry, entry.x + x, entry.y + y); + } } }, /** - * Processes a 'drag move' event for the given pointer. + * Internal method that handles drawing a single Phaser Game Object to this Dynamic Texture. * - * @method Phaser.Input.InputPlugin#processDragMoveEvent + * @method Phaser.Textures.DynamicTexture#batchGameObject * @private - * @fires Phaser.Input.Events#DRAG_ENTER - * @fires Phaser.Input.Events#DRAG - * @fires Phaser.Input.Events#DRAG_LEAVE - * @fires Phaser.Input.Events#DRAG_OVER - * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_ENTER - * @fires Phaser.Input.Events#GAMEOBJECT_DRAG - * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_LEAVE - * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_OVER - * @since 3.18.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on. + * @since 3.12.0 * - * @return {number} The number of items that were updated by this drag event. + * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to draw. + * @param {number} [x=0] - The x position to draw the Game Object at. + * @param {number} [y=0] - The y position to draw the Game Object at. */ - processDragMoveEvent: function (pointer) + batchGameObject: function (gameObject, x, y) { - // 2 = Pointer being checked if meets drag criteria - if (this.getDragState(pointer) === 2) - { - this.processDragThresholdEvent(pointer, this.manager.game.loop.now); - } - - if (this.getDragState(pointer) !== 4) - { - return 0; - } - - // 4 = Pointer actively dragging the draglist and has moved - var dropZones = this._tempZones; + if (x === undefined) { x = gameObject.x; } + if (y === undefined) { y = gameObject.y; } - var list = this._drag[pointer.id]; + var prevX = gameObject.x; + var prevY = gameObject.y; - for (var i = 0; i < list.length; i++) - { - var gameObject = list[i]; + var camera = this.camera; + var renderer = this.renderer; + var eraseMode = this._eraseMode; - var input = gameObject.input; + var mask = gameObject.mask; - var target = input.target; + gameObject.setPosition(x, y); - // If this GO has a target then let's check it - if (target) + if (this.canvas) + { + if (eraseMode) { - var index = dropZones.indexOf(target); - - // Got a target, are we still over it? - if (index === 0) - { - // We're still over it, and it's still the top of the display list, phew ... - gameObject.emit(Events.GAMEOBJECT_DRAG_OVER, pointer, target); - - this.emit(Events.DRAG_OVER, pointer, gameObject, target); - } - else if (index > 0) - { - // Still over it but it's no longer top of the display list (targets must always be at the top) - gameObject.emit(Events.GAMEOBJECT_DRAG_LEAVE, pointer, target); - - this.emit(Events.DRAG_LEAVE, pointer, gameObject, target); - - input.target = dropZones[0]; - - target = input.target; - - gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, target); - - this.emit(Events.DRAG_ENTER, pointer, gameObject, target); - } - else - { - // Nope, we've moved on (or the target has!), leave the old target - gameObject.emit(Events.GAMEOBJECT_DRAG_LEAVE, pointer, target); - - this.emit(Events.DRAG_LEAVE, pointer, gameObject, target); - - // Anything new to replace it? - // Yup! - if (dropZones[0]) - { - input.target = dropZones[0]; - - target = input.target; - - gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, target); + var blendMode = gameObject.blendMode; - this.emit(Events.DRAG_ENTER, pointer, gameObject, target); - } - else - { - // Nope - input.target = null; - } - } + gameObject.blendMode = BlendModes.ERASE; } - else if (!target && dropZones[0]) - { - input.target = dropZones[0]; - target = input.target; + if (mask) + { + mask.preRenderCanvas(renderer, gameObject, camera); + } - gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, target); + gameObject.renderCanvas(renderer, gameObject, camera, null); - this.emit(Events.DRAG_ENTER, pointer, gameObject, target); + if (mask) + { + mask.postRenderCanvas(renderer, gameObject, camera); } - var dragX; - var dragY; - - if (!gameObject.parentContainer) + if (eraseMode) { - dragX = pointer.worldX - input.dragX; - dragY = pointer.worldY - input.dragY; + gameObject.blendMode = blendMode; } - else + } + else if (renderer) + { + if (mask) { - var dx = pointer.worldX - input.dragStartXGlobal; - var dy = pointer.worldY - input.dragStartYGlobal; - - var rotation = gameObject.getParentRotation(); - - var dxRotated = dx * Math.cos(rotation) + dy * Math.sin(rotation); - var dyRotated = dy * Math.cos(rotation) - dx * Math.sin(rotation); - - dxRotated *= (1 / gameObject.parentContainer.scaleX); - dyRotated *= (1 / gameObject.parentContainer.scaleY); + mask.preRenderWebGL(renderer, gameObject, camera); + } - dragX = dxRotated + input.dragStartX; - dragY = dyRotated + input.dragStartY; + if (!eraseMode) + { + renderer.setBlendMode(gameObject.blendMode); } - gameObject.emit(Events.GAMEOBJECT_DRAG, pointer, dragX, dragY); + gameObject.renderWebGL(renderer, gameObject, camera); - this.emit(Events.DRAG, pointer, gameObject, dragX, dragY); + if (mask) + { + mask.postRenderWebGL(renderer, camera, this.renderTarget); + } } - return list.length; + gameObject.setPosition(prevX, prevY); }, /** - * Processes a 'drag down' event for the given pointer. Checks the pointer state, builds-up the drag list - * and prepares them all for interaction. + * Internal method that handles the drawing a Texture Frame based on its key. * - * @method Phaser.Input.InputPlugin#processDragUpEvent - * @fires Phaser.Input.Events#DRAG_END - * @fires Phaser.Input.Events#DROP - * @fires Phaser.Input.Events#GAMEOBJECT_DRAG_END - * @fires Phaser.Input.Events#GAMEOBJECT_DROP + * @method Phaser.Textures.DynamicTexture#batchTextureFrameKey * @private - * @since 3.18.0 - * - * @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on. + * @since 3.12.0 * - * @return {number} The number of items that were updated by this drag event. + * @param {string} key - The key of the texture to be used, as stored in the Texture Manager. + * @param {(string|number)} [frame] - The name or index of the frame within the Texture. + * @param {number} [x=0] - The x position to offset the Game Object by. + * @param {number} [y=0] - The y position to offset the Game Object by. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. */ - processDragUpEvent: function (pointer) + batchTextureFrameKey: function (key, frame, x, y, alpha, tint) { - // 5 = Pointer was actively dragging but has been released, notify draglist - var list = this._drag[pointer.id]; + var textureFrame = this.manager.getFrame(key, frame); - for (var i = 0; i < list.length; i++) + if (textureFrame) { - var gameObject = list[i]; - - var input = gameObject.input; - - if (input && input.dragState === 2) - { - input.dragState = 0; - - input.dragX = input.localX - gameObject.displayOriginX; - input.dragY = input.localY - gameObject.displayOriginY; - - var dropped = false; - - var target = input.target; - - if (target) - { - gameObject.emit(Events.GAMEOBJECT_DROP, pointer, target); - - this.emit(Events.DROP, pointer, gameObject, target); - - input.target = null; - - dropped = true; - } - - // And finally the dragend event - - if (gameObject.input) - { - gameObject.emit(Events.GAMEOBJECT_DRAG_END, pointer, input.dragX, input.dragY, dropped); - - this.emit(Events.DRAG_END, pointer, gameObject, dropped); - } - } + this.batchTextureFrame(textureFrame, x, y, alpha, tint); } - - this.setDragState(pointer, 0); - - list.splice(0); - - return 0; }, /** - * An internal method that handles the Pointer movement event. + * Internal method that handles the drawing of a Texture Frame to this Dynamic Texture. * - * @method Phaser.Input.InputPlugin#processMoveEvents + * @method Phaser.Textures.DynamicTexture#batchTextureFrame * @private - * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_MOVE - * @fires Phaser.Input.Events#GAMEOBJECT_MOVE - * @fires Phaser.Input.Events#POINTER_MOVE - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. + * @since 3.12.0 * - * @return {number} The total number of objects interacted with. + * @param {Phaser.Textures.Frame} textureFrame - The Texture Frame to draw. + * @param {number} [x=0] - The x position to draw the Frame at. + * @param {number} [y=0] - The y position to draw the Frame at. + * @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. + * @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. */ - processMoveEvents: function (pointer) + batchTextureFrame: function (textureFrame, x, y, alpha, tint) { - var total = 0; - var currentlyOver = this._temp; - - var _eventData = this._eventData; - var _eventContainer = this._eventContainer; - - _eventData.cancelled = false; + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } + if (alpha === undefined) { alpha = 1; } + if (tint === undefined) { tint = 0xffffff; } - var aborted = false; + var matrix = this.camera.matrix; + var renderTarget = this.renderTarget; - // Go through all objects the pointer was over and fire their events / callbacks - for (var i = 0; i < currentlyOver.length; i++) + if (renderTarget) { - var gameObject = currentlyOver[i]; - - if (!gameObject.input) - { - continue; - } + this.pipeline.batchTextureFrame(textureFrame, x, y, tint, alpha, matrix, null); + } + else + { + var ctx = this.context; + var cd = textureFrame.canvasData; + var source = textureFrame.source.image; - total++; + ctx.save(); - gameObject.emit(Events.GAMEOBJECT_POINTER_MOVE, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); + ctx.globalCompositeOperation = (this._eraseMode) ? 'destination-out' : 'source-over'; - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } + ctx.globalAlpha = alpha; - this.emit(Events.GAMEOBJECT_MOVE, pointer, gameObject, _eventContainer); + matrix.setToContext(ctx); - if (_eventData.cancelled || !gameObject.input) + if (cd.width > 0 && cd.height > 0) { - aborted = true; - break; + ctx.drawImage(source, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height); } - if (this.topOnly) - { - break; - } + ctx.restore(); } + }, - if (!aborted) + /** + * Takes a snapshot of the given area of this Dynamic Texture. + * + * The snapshot is taken immediately, but the results are returned via the given callback. + * + * To capture the whole Dynamic Texture see the `snapshot` method. + * To capture just a specific pixel, see the `snapshotPixel` method. + * + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer + * into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally + * creating an Image object from it, which is the image returned to the callback provided. + * + * All in all, this is a computationally expensive and blocking process, which gets more expensive + * the larger the resolution this Dynamic Texture has, so please be careful how you employ this in your game. + * + * @method Phaser.Textures.DynamicTexture#snapshotArea + * @since 3.19.0 + * + * @param {number} x - The x coordinate to grab from. + * @param {number} y - The y coordinate to grab from. + * @param {number} width - The width of the area to grab. + * @param {number} height - The height of the area to grab. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This Dynamic Texture instance. + */ + snapshotArea: function (x, y, width, height, callback, type, encoderOptions) + { + if (this.renderTarget) { - this.emit(Events.POINTER_MOVE, pointer, currentlyOver); + this.renderer.snapshotFramebuffer(this.renderTarget.framebuffer, this.width, this.height, callback, false, x, y, width, height, type, encoderOptions); + } + else + { + this.renderer.snapshotCanvas(this.canvas, callback, false, x, y, width, height, type, encoderOptions); } - return total; + return this; }, /** - * An internal method that handles a mouse wheel event. + * Takes a snapshot of the whole of this Dynamic Texture. * - * @method Phaser.Input.InputPlugin#processWheelEvent - * @private - * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_WHEEL - * @fires Phaser.Input.Events#GAMEOBJECT_WHEEL - * @fires Phaser.Input.Events#POINTER_WHEEL - * @since 3.18.0 + * The snapshot is taken immediately, but the results are returned via the given callback. * - * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. + * To capture a portion of this Dynamic Texture see the `snapshotArea` method. + * To capture just a specific pixel, see the `snapshotPixel` method. * - * @return {number} The total number of objects interacted with. + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer + * into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally + * creating an Image object from it, which is the image returned to the callback provided. + * + * All in all, this is a computationally expensive and blocking process, which gets more expensive + * the larger the resolution this Dynamic Texture has, so please be careful how you employ this in your game. + * + * @method Phaser.Textures.DynamicTexture#snapshot + * @since 3.19.0 + * + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created. + * @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`. + * @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. + * + * @return {this} This Dynamic Texture instance. */ - processWheelEvent: function (pointer) + snapshot: function (callback, type, encoderOptions) { - var total = 0; - var currentlyOver = this._temp; + return this.snapshotArea(0, 0, this.width, this.height, callback, type, encoderOptions); + }, - var _eventData = this._eventData; - var _eventContainer = this._eventContainer; + /** + * Takes a snapshot of the given pixel from this Dynamic Texture. + * + * The snapshot is taken immediately, but the results are returned via the given callback. + * + * To capture the whole Dynamic Texture see the `snapshot` method. + * To capture a portion of this Dynamic Texture see the `snapshotArea` method. + * + * Unlike the two other snapshot methods, this one will send your callback a `Color` object + * containing the color data for the requested pixel. It doesn't need to create an internal + * Canvas or Image object, so is a lot faster to execute, using less memory than the other snapshot methods. + * + * @method Phaser.Textures.DynamicTexture#snapshotPixel + * @since 3.19.0 + * + * @param {number} x - The x coordinate of the pixel to get. + * @param {number} y - The y coordinate of the pixel to get. + * @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted. + * + * @return {this} This Dynamic Texture instance. + */ + snapshotPixel: function (x, y, callback) + { + return this.snapshotArea(x, y, 1, 1, callback, 'pixel'); + }, - _eventData.cancelled = false; + /** + * Returns the underlying WebGLTexture, if not running in Canvas mode. + * + * @method Phaser.Textures.DynamicTexture#getWebGLTexture + * @since 3.60.0 + * + * @return {?WebGLTexture} The underlying WebGLTexture, if not running in Canvas mode. + */ + getWebGLTexture: function () + { + if (this.renderTarget) + { + return this.renderTarget.texture; + } + }, - var aborted = false; + /** + * Renders this Dynamic Texture onto the Stamp Game Object as a BitmapMask. + * + * @method Phaser.Textures.DynamicTexture#renderWebGL + * @since 3.60.0 + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.GameObjects.Image} 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 + */ + renderWebGL: function (renderer, src, camera, parentMatrix) + { + var stamp = this.manager.resetStamp(); - var dx = pointer.deltaX; - var dy = pointer.deltaY; - var dz = pointer.deltaZ; + stamp.setTexture(this); + stamp.setOrigin(0); - // Go through all objects the pointer was over and fire their events / callbacks - for (var i = 0; i < currentlyOver.length; i++) + stamp.renderWebGL(renderer, stamp, camera, parentMatrix); + }, + + /** + * This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer. + * + * @method Phaser.Textures.DynamicTexture#renderCanvas + * @since 3.60.0 + * + * @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to. + * @param {Phaser.GameObjects.GameObject} mask - The masked Game Object which would be rendered. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to. + */ + renderCanvas: function () + { + // NOOP + }, + + /** + * Internal destroy handler, called as part of the destroy process. + * + * @method Phaser.Textures.DynamicTexture#preDestroy + * @protected + * @since 3.9.0 + */ + preDestroy: function () + { + CanvasPool.remove(this.canvas); + + if (this.renderTarget) { - var gameObject = currentlyOver[i]; + this.renderTarget.destroy(); + } - if (!gameObject.input) - { - continue; - } + this.camera.destroy(); + this.stamp.destroy(); - total++; + this.canvas = null; + this.context = null; + this.renderer = null; + this.scene = null; + } - gameObject.emit(Events.GAMEOBJECT_POINTER_WHEEL, pointer, dx, dy, dz, _eventContainer); +}); - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } +module.exports = DynamicTexture; - this.emit(Events.GAMEOBJECT_WHEEL, pointer, gameObject, dx, dy, dz, _eventContainer); - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } - } +/***/ }), - if (!aborted) - { - this.emit(Events.POINTER_WHEEL, pointer, currentlyOver, dx, dy, dz); - } +/***/ 82047: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return total; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * An internal method that handles the Pointer over events. - * This is called when a touch input hits the canvas, having previously been off of it. - * - * @method Phaser.Input.InputPlugin#processOverEvents - * @private - * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OVER - * @fires Phaser.Input.Events#GAMEOBJECT_OVER - * @fires Phaser.Input.Events#POINTER_OVER - * @since 3.18.0 - * - * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. - * - * @return {number} The total number of objects interacted with. - */ - processOverEvents: function (pointer) +var Class = __webpack_require__(56694); +var Clamp = __webpack_require__(82897); +var Extend = __webpack_require__(98611); + +/** + * @classdesc + * A Frame is a section of a Texture. + * + * @class Frame + * @memberof Phaser.Textures + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Textures.Texture} texture - The Texture this Frame is a part of. + * @param {(number|string)} name - The name of this Frame. The name is unique within the Texture. + * @param {number} sourceIndex - The index of the TextureSource that this Frame is a part of. + * @param {number} x - The x coordinate of the top-left of this Frame. + * @param {number} y - The y coordinate of the top-left of this Frame. + * @param {number} width - The width of this Frame. + * @param {number} height - The height of this Frame. + */ +var Frame = new Class({ + + initialize: + + function Frame (texture, name, sourceIndex, x, y, width, height) { - var currentlyOver = this._temp; + /** + * The Texture this Frame is a part of. + * + * @name Phaser.Textures.Frame#texture + * @type {Phaser.Textures.Texture} + * @since 3.0.0 + */ + this.texture = texture; - var totalInteracted = 0; + /** + * The name of this Frame. + * The name is unique within the Texture. + * + * @name Phaser.Textures.Frame#name + * @type {string} + * @since 3.0.0 + */ + this.name = name; - var total = currentlyOver.length; + /** + * The TextureSource this Frame is part of. + * + * @name Phaser.Textures.Frame#source + * @type {Phaser.Textures.TextureSource} + * @since 3.0.0 + */ + this.source = texture.source[sourceIndex]; - var justOver = []; + /** + * The index of the TextureSource in the Texture sources array. + * + * @name Phaser.Textures.Frame#sourceIndex + * @type {number} + * @since 3.0.0 + */ + this.sourceIndex = sourceIndex; - if (total > 0) - { - var manager = this.manager; + /** + * A reference to the Texture Source WebGL Texture that this Frame is using. + * + * @name Phaser.Textures.Frame#glTexture + * @type {?WebGLTexture} + * @default null + * @since 3.11.0 + */ + this.glTexture = this.source.glTexture; - var _eventData = this._eventData; - var _eventContainer = this._eventContainer; + /** + * X position within the source image to cut from. + * + * @name Phaser.Textures.Frame#cutX + * @type {number} + * @since 3.0.0 + */ + this.cutX; - _eventData.cancelled = false; + /** + * Y position within the source image to cut from. + * + * @name Phaser.Textures.Frame#cutY + * @type {number} + * @since 3.0.0 + */ + this.cutY; - var aborted = false; + /** + * The width of the area in the source image to cut. + * + * @name Phaser.Textures.Frame#cutWidth + * @type {number} + * @since 3.0.0 + */ + this.cutWidth; - for (var i = 0; i < total; i++) - { - var gameObject = currentlyOver[i]; + /** + * The height of the area in the source image to cut. + * + * @name Phaser.Textures.Frame#cutHeight + * @type {number} + * @since 3.0.0 + */ + this.cutHeight; - if (!gameObject.input) - { - continue; - } + /** + * The X rendering offset of this Frame, taking trim into account. + * + * @name Phaser.Textures.Frame#x + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.x = 0; - justOver.push(gameObject); + /** + * The Y rendering offset of this Frame, taking trim into account. + * + * @name Phaser.Textures.Frame#y + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.y = 0; - manager.setCursor(gameObject.input); + /** + * The rendering width of this Frame, taking trim into account. + * + * @name Phaser.Textures.Frame#width + * @type {number} + * @since 3.0.0 + */ + this.width; - gameObject.emit(Events.GAMEOBJECT_POINTER_OVER, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); + /** + * The rendering height of this Frame, taking trim into account. + * + * @name Phaser.Textures.Frame#height + * @type {number} + * @since 3.0.0 + */ + this.height; - totalInteracted++; + /** + * Half the width, floored. + * Precalculated for the renderer. + * + * @name Phaser.Textures.Frame#halfWidth + * @type {number} + * @since 3.0.0 + */ + this.halfWidth; - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } + /** + * Half the height, floored. + * Precalculated for the renderer. + * + * @name Phaser.Textures.Frame#halfHeight + * @type {number} + * @since 3.0.0 + */ + this.halfHeight; - this.emit(Events.GAMEOBJECT_OVER, pointer, gameObject, _eventContainer); + /** + * The x center of this frame, floored. + * + * @name Phaser.Textures.Frame#centerX + * @type {number} + * @since 3.0.0 + */ + this.centerX; - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } - } + /** + * The y center of this frame, floored. + * + * @name Phaser.Textures.Frame#centerY + * @type {number} + * @since 3.0.0 + */ + this.centerY; - if (!aborted) - { - this.emit(Events.POINTER_OVER, pointer, justOver); - } - } + /** + * The horizontal pivot point of this Frame. + * + * @name Phaser.Textures.Frame#pivotX + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.pivotX = 0; - // Then sort it into display list order - this._over[pointer.id] = justOver; + /** + * The vertical pivot point of this Frame. + * + * @name Phaser.Textures.Frame#pivotY + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.pivotY = 0; - return totalInteracted; - }, + /** + * Does this Frame have a custom pivot point? + * + * @name Phaser.Textures.Frame#customPivot + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.customPivot = false; - /** - * An internal method that handles the Pointer out events. - * This is called when a touch input leaves the canvas, as it can never be 'over' in this case. - * - * @method Phaser.Input.InputPlugin#processOutEvents - * @private - * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OUT - * @fires Phaser.Input.Events#GAMEOBJECT_OUT - * @fires Phaser.Input.Events#POINTER_OUT - * @since 3.18.0 - * - * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. - * - * @return {number} The total number of objects interacted with. - */ - processOutEvents: function (pointer) - { - var previouslyOver = this._over[pointer.id]; + /** + * **CURRENTLY UNSUPPORTED** + * + * Is this frame is rotated or not in the Texture? + * Rotation allows you to use rotated frames in texture atlas packing. + * It has nothing to do with Sprite rotation. + * + * @name Phaser.Textures.Frame#rotated + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.rotated = false; - var totalInteracted = 0; + /** + * Over-rides the Renderer setting. + * -1 = use Renderer Setting + * 0 = No rounding + * 1 = Round + * + * @name Phaser.Textures.Frame#autoRound + * @type {number} + * @default -1 + * @since 3.0.0 + */ + this.autoRound = -1; - var total = previouslyOver.length; + /** + * Any Frame specific custom data can be stored here. + * + * @name Phaser.Textures.Frame#customData + * @type {object} + * @since 3.0.0 + */ + this.customData = {}; - if (total > 0) - { - var manager = this.manager; + /** + * WebGL UV u0 value. + * + * @name Phaser.Textures.Frame#u0 + * @type {number} + * @default 0 + * @since 3.11.0 + */ + this.u0 = 0; - var _eventData = this._eventData; - var _eventContainer = this._eventContainer; + /** + * WebGL UV v0 value. + * + * @name Phaser.Textures.Frame#v0 + * @type {number} + * @default 0 + * @since 3.11.0 + */ + this.v0 = 0; - _eventData.cancelled = false; + /** + * WebGL UV u1 value. + * + * @name Phaser.Textures.Frame#u1 + * @type {number} + * @default 0 + * @since 3.11.0 + */ + this.u1 = 0; - var aborted = false; + /** + * WebGL UV v1 value. + * + * @name Phaser.Textures.Frame#v1 + * @type {number} + * @default 0 + * @since 3.11.0 + */ + this.v1 = 0; - this.sortGameObjects(previouslyOver, pointer); + /** + * The un-modified source frame, trim and UV data. + * + * @name Phaser.Textures.Frame#data + * @type {object} + * @private + * @since 3.0.0 + */ + this.data = { + cut: { + x: 0, + y: 0, + w: 0, + h: 0, + r: 0, + b: 0 + }, + trim: false, + sourceSize: { + w: 0, + h: 0 + }, + spriteSourceSize: { + x: 0, + y: 0, + w: 0, + h: 0, + r: 0, + b: 0 + }, + radius: 0, + drawImage: { + x: 0, + y: 0, + width: 0, + height: 0 + } + }; + + this.setSize(width, height, x, y); + }, + + /** + * Sets the width, height, x and y of this Frame. + * + * This is called automatically by the constructor + * and should rarely be changed on-the-fly. + * + * @method Phaser.Textures.Frame#setSize + * @since 3.7.0 + * + * @param {number} width - The width of the frame before being trimmed. + * @param {number} height - The height of the frame before being trimmed. + * @param {number} [x=0] - The x coordinate of the top-left of this Frame. + * @param {number} [y=0] - The y coordinate of the top-left of this Frame. + * + * @return {this} This Frame object. + */ + setSize: function (width, height, x, y) + { + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } - for (var i = 0; i < total; i++) - { - var gameObject = previouslyOver[i]; + this.cutX = x; + this.cutY = y; + this.cutWidth = width; + this.cutHeight = height; - // Call onOut for everything in the previouslyOver array - gameObject = previouslyOver[i]; + this.width = width; + this.height = height; - if (!gameObject.input) - { - continue; - } + this.halfWidth = Math.floor(width * 0.5); + this.halfHeight = Math.floor(height * 0.5); - manager.resetCursor(gameObject.input); + this.centerX = Math.floor(width / 2); + this.centerY = Math.floor(height / 2); - gameObject.emit(Events.GAMEOBJECT_POINTER_OUT, pointer, _eventContainer); + var data = this.data; + var cut = data.cut; - totalInteracted++; + cut.x = x; + cut.y = y; + cut.w = width; + cut.h = height; + cut.r = x + width; + cut.b = y + height; - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } + data.sourceSize.w = width; + data.sourceSize.h = height; - this.emit(Events.GAMEOBJECT_OUT, pointer, gameObject, _eventContainer); + data.spriteSourceSize.w = width; + data.spriteSourceSize.h = height; - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } + data.radius = 0.5 * Math.sqrt(width * width + height * height); - if (!aborted) - { - this.emit(Events.POINTER_OUT, pointer, previouslyOver); - } - } + var drawImage = data.drawImage; - this._over[pointer.id] = []; - } + drawImage.x = x; + drawImage.y = y; + drawImage.width = width; + drawImage.height = height; - return totalInteracted; + return this.updateUVs(); }, /** - * An internal method that handles the Pointer over and out events. + * If the frame was trimmed when added to the Texture Atlas, this records the trim and source data. * - * @method Phaser.Input.InputPlugin#processOverOutEvents - * @private - * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OVER - * @fires Phaser.Input.Events#GAMEOBJECT_OVER - * @fires Phaser.Input.Events#POINTER_OVER - * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OUT - * @fires Phaser.Input.Events#GAMEOBJECT_OUT - * @fires Phaser.Input.Events#POINTER_OUT + * @method Phaser.Textures.Frame#setTrim * @since 3.0.0 * - * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. + * @param {number} actualWidth - The width of the frame before being trimmed. + * @param {number} actualHeight - The height of the frame before being trimmed. + * @param {number} destX - The destination X position of the trimmed frame for display. + * @param {number} destY - The destination Y position of the trimmed frame for display. + * @param {number} destWidth - The destination width of the trimmed frame for display. + * @param {number} destHeight - The destination height of the trimmed frame for display. * - * @return {number} The total number of objects interacted with. + * @return {this} This Frame object. */ - processOverOutEvents: function (pointer) + setTrim: function (actualWidth, actualHeight, destX, destY, destWidth, destHeight) { - var currentlyOver = this._temp; + var data = this.data; + var ss = data.spriteSourceSize; - var i; - var gameObject; - var justOut = []; - var justOver = []; - var stillOver = []; - var previouslyOver = this._over[pointer.id]; - var currentlyDragging = this._drag[pointer.id]; + // Store actual values - var manager = this.manager; + data.trim = true; - // Go through all objects the pointer was previously over, and see if it still is. - // Splits the previouslyOver array into two parts: justOut and stillOver + data.sourceSize.w = actualWidth; + data.sourceSize.h = actualHeight; - for (i = 0; i < previouslyOver.length; i++) - { - gameObject = previouslyOver[i]; + ss.x = destX; + ss.y = destY; + ss.w = destWidth; + ss.h = destHeight; + ss.r = destX + destWidth; + ss.b = destY + destHeight; - if (currentlyOver.indexOf(gameObject) === -1 && currentlyDragging.indexOf(gameObject) === -1) - { - // Not in the currentlyOver array, so must be outside of this object now - justOut.push(gameObject); - } - else - { - // In the currentlyOver array - stillOver.push(gameObject); - } - } + // Adjust properties + this.x = destX; + this.y = destY; - // Go through all objects the pointer is currently over (the hit test results) - // and if not in the previouslyOver array we know it's a new entry, so add to justOver - for (i = 0; i < currentlyOver.length; i++) - { - gameObject = currentlyOver[i]; + this.width = destWidth; + this.height = destHeight; - // Is this newly over? + this.halfWidth = destWidth * 0.5; + this.halfHeight = destHeight * 0.5; - if (previouslyOver.indexOf(gameObject) === -1) - { - justOver.push(gameObject); - } - } + this.centerX = Math.floor(destWidth / 2); + this.centerY = Math.floor(destHeight / 2); - // By this point the arrays are filled, so now we can process what happened... + return this.updateUVs(); + }, - // Process the Just Out objects - var total = justOut.length; + /** + * Takes a crop data object and, based on the rectangular region given, calculates the + * required UV coordinates in order to crop this Frame for WebGL and Canvas rendering. + * + * This is called directly by the Game Object Texture Components `setCrop` method. + * Please use that method to crop a Game Object. + * + * @method Phaser.Textures.Frame#setCropUVs + * @since 3.11.0 + * + * @param {object} crop - The crop data object. This is the `GameObject._crop` property. + * @param {number} x - The x coordinate to start the crop from. Cannot be negative or exceed the Frame width. + * @param {number} y - The y coordinate to start the crop from. Cannot be negative or exceed the Frame height. + * @param {number} width - The width of the crop rectangle. Cannot exceed the Frame width. + * @param {number} height - The height of the crop rectangle. Cannot exceed the Frame height. + * @param {boolean} flipX - Does the parent Game Object have flipX set? + * @param {boolean} flipY - Does the parent Game Object have flipY set? + * + * @return {object} The updated crop data object. + */ + setCropUVs: function (crop, x, y, width, height, flipX, flipY) + { + // Clamp the input values - var totalInteracted = 0; + var cx = this.cutX; + var cy = this.cutY; + var cw = this.cutWidth; + var ch = this.cutHeight; + var rw = this.realWidth; + var rh = this.realHeight; - var _eventData = this._eventData; - var _eventContainer = this._eventContainer; + x = Clamp(x, 0, rw); + y = Clamp(y, 0, rh); - _eventData.cancelled = false; + width = Clamp(width, 0, rw - x); + height = Clamp(height, 0, rh - y); - var aborted = false; + var ox = cx + x; + var oy = cy + y; + var ow = width; + var oh = height; - if (total > 0) + var data = this.data; + + if (data.trim) { - this.sortGameObjects(justOut, pointer); + var ss = data.spriteSourceSize; - // Call onOut for everything in the justOut array - for (i = 0; i < total; i++) - { - gameObject = justOut[i]; + // Need to check for intersection between the cut area and the crop area + // If there is none, we set UV to be empty, otherwise set it to be the intersection area - if (!gameObject.input) - { - continue; - } + width = Clamp(width, 0, cw - x); + height = Clamp(height, 0, ch - y); - // Reset cursor before we emit the event, in case they want to change it during the event - manager.resetCursor(gameObject.input); + var cropRight = x + width; + var cropBottom = y + height; - gameObject.emit(Events.GAMEOBJECT_POINTER_OUT, pointer, _eventContainer); + var intersects = !(ss.r < x || ss.b < y || ss.x > cropRight || ss.y > cropBottom); - totalInteracted++; + if (intersects) + { + var ix = Math.max(ss.x, x); + var iy = Math.max(ss.y, y); + var iw = Math.min(ss.r, cropRight) - ix; + var ih = Math.min(ss.b, cropBottom) - iy; + + ow = iw; + oh = ih; - if (_eventData.cancelled || !gameObject.input) + if (flipX) { - aborted = true; - break; + ox = cx + (cw - (ix - ss.x) - iw); } - - this.emit(Events.GAMEOBJECT_OUT, pointer, gameObject, _eventContainer); - - if (_eventData.cancelled || !gameObject.input) + else { - aborted = true; - break; + ox = cx + (ix - ss.x); } - } - - if (!aborted) - { - this.emit(Events.POINTER_OUT, pointer, justOut); - } - } - - // Process the Just Over objects - total = justOver.length; - - _eventData.cancelled = false; - - aborted = false; - - if (total > 0) - { - this.sortGameObjects(justOver, pointer); - - // Call onOver for everything in the justOver array - for (i = 0; i < total; i++) - { - gameObject = justOver[i]; - if (!gameObject.input) + if (flipY) { - continue; + oy = cy + (ch - (iy - ss.y) - ih); } - - // Set cursor before we emit the event, in case they want to change it during the event - manager.setCursor(gameObject.input); - - gameObject.emit(Events.GAMEOBJECT_POINTER_OVER, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); - - totalInteracted++; - - if (_eventData.cancelled || !gameObject.input) + else { - aborted = true; - break; + oy = cy + (iy - ss.y); } - this.emit(Events.GAMEOBJECT_OVER, pointer, gameObject, _eventContainer); + x = ix; + y = iy; - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } + width = iw; + height = ih; } - - if (!aborted) + else { - this.emit(Events.POINTER_OVER, pointer, justOver); + ox = 0; + oy = 0; + ow = 0; + oh = 0; } } - - // Add the contents of justOver to the previously over array - previouslyOver = stillOver.concat(justOver); - - // Then sort it into display list order - this._over[pointer.id] = this.sortGameObjects(previouslyOver, pointer); - - return totalInteracted; - }, - - /** - * An internal method that handles the Pointer up events. - * - * @method Phaser.Input.InputPlugin#processUpEvents - * @private - * @fires Phaser.Input.Events#GAMEOBJECT_POINTER_UP - * @fires Phaser.Input.Events#GAMEOBJECT_UP - * @fires Phaser.Input.Events#POINTER_UP - * @fires Phaser.Input.Events#POINTER_UP_OUTSIDE - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - The pointer to check for events against. - * - * @return {number} The total number of objects interacted with. - */ - processUpEvents: function (pointer) - { - var currentlyOver = this._temp; - - var _eventData = this._eventData; - var _eventContainer = this._eventContainer; - - _eventData.cancelled = false; - - var aborted = false; - - // Go through all objects the pointer was over and fire their events / callbacks - for (var i = 0; i < currentlyOver.length; i++) + else { - var gameObject = currentlyOver[i]; - - if (!gameObject.input) + if (flipX) { - continue; + ox = cx + (cw - x - width); } - gameObject.emit(Events.GAMEOBJECT_POINTER_UP, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer); - - if (_eventData.cancelled || !gameObject.input) + if (flipY) { - aborted = true; - break; + oy = cy + (ch - y - height); } + } - this.emit(Events.GAMEOBJECT_UP, pointer, gameObject, _eventContainer); + var tw = this.source.width; + var th = this.source.height; - if (_eventData.cancelled || !gameObject.input) - { - aborted = true; - break; - } - } + // Map the given coordinates into UV space, clamping to the 0-1 range. - // If they released outside the canvas, but pressed down inside it, we'll still dispatch the event. - if (!aborted && this.manager) - { - if (pointer.upElement === this.manager.game.canvas) - { - this.emit(Events.POINTER_UP, pointer, currentlyOver); - } - else - { - this.emit(Events.POINTER_UP_OUTSIDE, pointer); - } - } + crop.u0 = Math.max(0, ox / tw); + crop.v0 = Math.max(0, oy / th); + crop.u1 = Math.min(1, (ox + ow) / tw); + crop.v1 = Math.min(1, (oy + oh) / th); - return currentlyOver.length; + crop.x = x; + crop.y = y; + + crop.cx = ox; + crop.cy = oy; + crop.cw = ow; + crop.ch = oh; + + crop.width = width; + crop.height = height; + + crop.flipX = flipX; + crop.flipY = flipY; + + return crop; }, /** - * Queues a Game Object for insertion into this Input Plugin on the next update. + * Takes a crop data object and recalculates the UVs based on the dimensions inside the crop object. + * Called automatically by `setFrame`. * - * @method Phaser.Input.InputPlugin#queueForInsertion - * @private - * @since 3.0.0 + * @method Phaser.Textures.Frame#updateCropUVs + * @since 3.11.0 * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to add. + * @param {object} crop - The crop data object. This is the `GameObject._crop` property. + * @param {boolean} flipX - Does the parent Game Object have flipX set? + * @param {boolean} flipY - Does the parent Game Object have flipY set? * - * @return {this} This InputPlugin object. + * @return {object} The updated crop data object. */ - queueForInsertion: function (child) + updateCropUVs: function (crop, flipX, flipY) { - if (this._pendingInsertion.indexOf(child) === -1 && this._list.indexOf(child) === -1) - { - this._pendingInsertion.push(child); - } - - return this; + return this.setCropUVs(crop, crop.x, crop.y, crop.width, crop.height, flipX, flipY); }, /** - * Queues a Game Object for removal from this Input Plugin on the next update. + * Directly sets the canvas and WebGL UV data for this frame. * - * @method Phaser.Input.InputPlugin#queueForRemoval - * @private - * @since 3.0.0 + * Use this if you need to override the values that are generated automatically + * when the Frame is created. * - * @param {Phaser.GameObjects.GameObject} child - The Game Object to remove. + * @method Phaser.Textures.Frame#setUVs + * @since 3.50.0 * - * @return {this} This InputPlugin object. + * @param {number} width - Width of this frame for the Canvas data. + * @param {number} height - Height of this frame for the Canvas data. + * @param {number} u0 - UV u0 value. + * @param {number} v0 - UV v0 value. + * @param {number} u1 - UV u1 value. + * @param {number} v1 - UV v1 value. + * + * @return {this} This Frame object. */ - queueForRemoval: function (child) + setUVs: function (width, height, u0, v0, u1, v1) { - this._pendingRemoval.push(child); + // Canvas data + + var cd = this.data.drawImage; + + cd.width = width; + cd.height = height; + + // WebGL data + + this.u0 = u0; + this.v0 = v0; + + this.u1 = u1; + this.v1 = v1; return this; }, /** - * Sets the draggable state of the given array of Game Objects. - * - * They can either be set to be draggable, or can have their draggable state removed by passing `false`. - * - * A Game Object will not fire drag events unless it has been specifically enabled for drag. + * Updates the internal WebGL UV cache and the drawImage cache. * - * @method Phaser.Input.InputPlugin#setDraggable + * @method Phaser.Textures.Frame#updateUVs * @since 3.0.0 * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to change the draggable state on. - * @param {boolean} [value=true] - Set to `true` if the Game Objects should be made draggable, `false` if they should be unset. - * - * @return {this} This InputPlugin object. + * @return {this} This Frame object. */ - setDraggable: function (gameObjects, value) + updateUVs: function () { - if (value === undefined) { value = true; } + var cx = this.cutX; + var cy = this.cutY; + var cw = this.cutWidth; + var ch = this.cutHeight; - if (!Array.isArray(gameObjects)) - { - gameObjects = [ gameObjects ]; - } + // Canvas data - for (var i = 0; i < gameObjects.length; i++) - { - var gameObject = gameObjects[i]; + var cd = this.data.drawImage; - gameObject.input.draggable = value; + cd.width = cw; + cd.height = ch; - var index = this._draggable.indexOf(gameObject); + // WebGL data - if (value && index === -1) - { - this._draggable.push(gameObject); - } - else if (!value && index > -1) - { - this._draggable.splice(index, 1); - } - } + var tw = this.source.width; + var th = this.source.height; + + this.u0 = cx / tw; + this.v0 = cy / th; + + this.u1 = (cx + cw) / tw; + this.v1 = (cy + ch) / th; return this; }, /** - * Creates a function that can be passed to `setInteractive`, `enable` or `setHitArea` that will handle - * pixel-perfect input detection on an Image or Sprite based Game Object, or any custom class that extends them. - * - * The following will create a sprite that is clickable on any pixel that has an alpha value >= 1. - * - * ```javascript - * this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect()); - * ``` - * - * The following will create a sprite that is clickable on any pixel that has an alpha value >= 150. - * - * ```javascript - * this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect(150)); - * ``` - * - * Once you have made an Interactive Object pixel perfect it impacts all input related events for it: down, up, - * dragstart, drag, etc. - * - * As a pointer interacts with the Game Object it will constantly poll the texture, extracting a single pixel from - * the given coordinates and checking its color values. This is an expensive process, so should only be enabled on - * Game Objects that really need it. - * - * You cannot make non-texture based Game Objects pixel perfect. So this will not work on Graphics, BitmapText, - * Render Textures, Text, Tilemaps, Containers or Particles. - * - * @method Phaser.Input.InputPlugin#makePixelPerfect - * @since 3.10.0 + * Updates the internal WebGL UV cache. * - * @param {number} [alphaTolerance=1] - The alpha level that the pixel should be above to be included as a successful interaction. + * @method Phaser.Textures.Frame#updateUVsInverted + * @since 3.0.0 * - * @return {function} A Pixel Perfect Handler for use as a hitArea shape callback. + * @return {this} This Frame object. */ - makePixelPerfect: function (alphaTolerance) + updateUVsInverted: function () { - if (alphaTolerance === undefined) { alphaTolerance = 1; } + var tw = this.source.width; + var th = this.source.height; - var textureManager = this.systems.textures; + this.u0 = (this.cutX + this.cutHeight) / tw; + this.v0 = this.cutY / th; - return CreatePixelPerfectHandler(textureManager, alphaTolerance); + this.u1 = this.cutX / tw; + this.v1 = (this.cutY + this.cutWidth) / th; + + return this; }, /** - * Sets the hit area for the given array of Game Objects. - * - * A hit area is typically one of the geometric shapes Phaser provides, such as a `Phaser.Geom.Rectangle` - * or `Phaser.Geom.Circle`. However, it can be any object as long as it works with the provided callback. - * - * If no hit area is provided a Rectangle is created based on the size of the Game Object, if possible - * to calculate. - * - * The hit area callback is the function that takes an `x` and `y` coordinate and returns a boolean if - * those values fall within the area of the shape or not. All of the Phaser geometry objects provide this, - * such as `Phaser.Geom.Rectangle.Contains`. + * Clones this Frame into a new Frame object. * - * @method Phaser.Input.InputPlugin#setHitArea + * @method Phaser.Textures.Frame#clone * @since 3.0.0 * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set the hit area on. - * @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. - * @param {Phaser.Types.Input.HitAreaCallback} [hitAreaCallback] - The 'contains' function to invoke to check if the pointer is within the hit area. - * - * @return {this} This InputPlugin object. + * @return {Phaser.Textures.Frame} A clone of this Frame. */ - setHitArea: function (gameObjects, hitArea, hitAreaCallback) + clone: function () { - if (hitArea === undefined) - { - return this.setHitAreaFromTexture(gameObjects); - } - - if (!Array.isArray(gameObjects)) - { - gameObjects = [ gameObjects ]; - } - - var draggable = false; - var dropZone = false; - var cursor = false; - var useHandCursor = false; - var pixelPerfect = false; - var customHitArea = true; - - // Config object? - if (IsPlainObject(hitArea)) - { - var config = hitArea; - - hitArea = GetFastValue(config, 'hitArea', null); - hitAreaCallback = GetFastValue(config, 'hitAreaCallback', null); - draggable = GetFastValue(config, 'draggable', false); - dropZone = GetFastValue(config, 'dropZone', false); - cursor = GetFastValue(config, 'cursor', false); - useHandCursor = GetFastValue(config, 'useHandCursor', false); - - pixelPerfect = GetFastValue(config, 'pixelPerfect', false); - var alphaTolerance = GetFastValue(config, 'alphaTolerance', 1); - - if (pixelPerfect) - { - hitArea = {}; - hitAreaCallback = this.makePixelPerfect(alphaTolerance); - } + var clone = new Frame(this.texture, this.name, this.sourceIndex); - // Still no hitArea or callback? - if (!hitArea || !hitAreaCallback) - { - this.setHitAreaFromTexture(gameObjects); - customHitArea = false; - } - } - else if (typeof hitArea === 'function' && !hitAreaCallback) - { - hitAreaCallback = hitArea; - hitArea = {}; - } + clone.cutX = this.cutX; + clone.cutY = this.cutY; + clone.cutWidth = this.cutWidth; + clone.cutHeight = this.cutHeight; - for (var i = 0; i < gameObjects.length; i++) - { - var gameObject = gameObjects[i]; + clone.x = this.x; + clone.y = this.y; - if (pixelPerfect && gameObject.type === 'Container') - { - console.warn('Cannot pixelPerfect test a Container. Use a custom callback.'); - continue; - } + clone.width = this.width; + clone.height = this.height; - var io = (!gameObject.input) ? CreateInteractiveObject(gameObject, hitArea, hitAreaCallback) : gameObject.input; + clone.halfWidth = this.halfWidth; + clone.halfHeight = this.halfHeight; - io.customHitArea = customHitArea; - io.dropZone = dropZone; - io.cursor = (useHandCursor) ? 'pointer' : cursor; + clone.centerX = this.centerX; + clone.centerY = this.centerY; - gameObject.input = io; + clone.rotated = this.rotated; - if (draggable) - { - this.setDraggable(gameObject); - } + clone.data = Extend(true, clone.data, this.data); - this.queueForInsertion(gameObject); - } + clone.updateUVs(); - return this; + return clone; }, /** - * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Circle` shape, using - * the given coordinates and radius to control its position and size. + * Destroys this Frame by nulling its reference to the parent Texture and and data objects. * - * @method Phaser.Input.InputPlugin#setHitAreaCircle + * @method Phaser.Textures.Frame#destroy * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a circle hit area. - * @param {number} x - The center of the circle. - * @param {number} y - The center of the circle. - * @param {number} radius - The radius of the circle. - * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Circle.Contains. - * - * @return {this} This InputPlugin object. */ - setHitAreaCircle: function (gameObjects, x, y, radius, callback) + destroy: function () { - if (callback === undefined) { callback = CircleContains; } - - var shape = new Circle(x, y, radius); - - return this.setHitArea(gameObjects, shape, callback); + this.source = null; + this.texture = null; + this.glTexture = null; + this.customData = null; + this.data = null; }, /** - * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Ellipse` shape, using - * the given coordinates and dimensions to control its position and size. + * The width of the Frame in its un-trimmed, un-padded state, as prepared in the art package, + * before being packed. * - * @method Phaser.Input.InputPlugin#setHitAreaEllipse + * @name Phaser.Textures.Frame#realWidth + * @type {number} + * @readonly * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having an ellipse hit area. - * @param {number} x - The center of the ellipse. - * @param {number} y - The center of the ellipse. - * @param {number} width - The width of the ellipse. - * @param {number} height - The height of the ellipse. - * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Ellipse.Contains. - * - * @return {this} This InputPlugin object. */ - setHitAreaEllipse: function (gameObjects, x, y, width, height, callback) - { - if (callback === undefined) { callback = EllipseContains; } + realWidth: { - var shape = new Ellipse(x, y, width, height); + get: function () + { + return this.data.sourceSize.w; + } - return this.setHitArea(gameObjects, shape, callback); }, /** - * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Rectangle` shape, using - * the Game Objects texture frame to define the position and size of the hit area. + * The height of the Frame in its un-trimmed, un-padded state, as prepared in the art package, + * before being packed. * - * @method Phaser.Input.InputPlugin#setHitAreaFromTexture + * @name Phaser.Textures.Frame#realHeight + * @type {number} + * @readonly * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having an ellipse hit area. - * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Rectangle.Contains. - * - * @return {this} This InputPlugin object. */ - setHitAreaFromTexture: function (gameObjects, callback) - { - if (callback === undefined) { callback = RectangleContains; } - - if (!Array.isArray(gameObjects)) - { - gameObjects = [ gameObjects ]; - } + realHeight: { - for (var i = 0; i < gameObjects.length; i++) + get: function () { - var gameObject = gameObjects[i]; - - var frame = gameObject.frame; - - var width = 0; - var height = 0; - - if (gameObject.width) - { - width = gameObject.width; - height = gameObject.height; - } - else if (frame) - { - width = frame.realWidth; - height = frame.realHeight; - } - - if (gameObject.type === 'Container' && (width === 0 || height === 0)) - { - console.warn('Container.setInteractive must specify a Shape or call setSize() first'); - continue; - } - - if (width !== 0 && height !== 0) - { - gameObject.input = CreateInteractiveObject(gameObject, new Rectangle(0, 0, width, height), callback); - - this.queueForInsertion(gameObject); - } + return this.data.sourceSize.h; } - return this; }, /** - * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Rectangle` shape, using - * the given coordinates and dimensions to control its position and size. + * The radius of the Frame (derived from sqrt(w * w + h * h) / 2) * - * @method Phaser.Input.InputPlugin#setHitAreaRectangle + * @name Phaser.Textures.Frame#radius + * @type {number} + * @readonly * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a rectangular hit area. - * @param {number} x - The top-left of the rectangle. - * @param {number} y - The top-left of the rectangle. - * @param {number} width - The width of the rectangle. - * @param {number} height - The height of the rectangle. - * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Rectangle.Contains. - * - * @return {this} This InputPlugin object. */ - setHitAreaRectangle: function (gameObjects, x, y, width, height, callback) - { - if (callback === undefined) { callback = RectangleContains; } + radius: { - var shape = new Rectangle(x, y, width, height); + get: function () + { + return this.data.radius; + } - return this.setHitArea(gameObjects, shape, callback); }, /** - * Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Triangle` shape, using - * the given coordinates to control the position of its points. + * Is the Frame trimmed or not? * - * @method Phaser.Input.InputPlugin#setHitAreaTriangle + * @name Phaser.Textures.Frame#trimmed + * @type {boolean} + * @readonly * @since 3.0.0 - * - * @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a triangular hit area. - * @param {number} x1 - The x coordinate of the first point of the triangle. - * @param {number} y1 - The y coordinate of the first point of the triangle. - * @param {number} x2 - The x coordinate of the second point of the triangle. - * @param {number} y2 - The y coordinate of the second point of the triangle. - * @param {number} x3 - The x coordinate of the third point of the triangle. - * @param {number} y3 - The y coordinate of the third point of the triangle. - * @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Triangle.Contains. - * - * @return {this} This InputPlugin object. */ - setHitAreaTriangle: function (gameObjects, x1, y1, x2, y2, x3, y3, callback) - { - if (callback === undefined) { callback = TriangleContains; } + trimmed: { - var shape = new Triangle(x1, y1, x2, y2, x3, y3); + get: function () + { + return this.data.trim; + } - return this.setHitArea(gameObjects, shape, callback); }, /** - * Creates an Input Debug Shape for the given Game Object. - * - * The Game Object must have _already_ been enabled for input prior to calling this method. - * - * This is intended to assist you during development and debugging. - * - * Debug Shapes can only be created for Game Objects that are using standard Phaser Geometry for input, - * including: Circle, Ellipse, Line, Polygon, Rectangle and Triangle. - * - * Game Objects that are using their automatic hit areas are using Rectangles by default, so will also work. - * - * The Debug Shape is created and added to the display list and is then kept in sync with the Game Object - * it is connected with. Should you need to modify it yourself, such as to hide it, you can access it via - * the Game Object property: `GameObject.input.hitAreaDebug`. - * - * Calling this method on a Game Object that already has a Debug Shape will first destroy the old shape, - * before creating a new one. If you wish to remove the Debug Shape entirely, you should call the - * method `InputPlugin.removeDebug`. - * - * Note that the debug shape will only show the outline of the input area. If the input test is using a - * pixel perfect check, for example, then this is not displayed. If you are using a custom shape, that - * doesn't extend one of the base Phaser Geometry objects, as your hit area, then this method will not - * work. - * - * @method Phaser.Input.InputPlugin#enableDebug - * @since 3.19.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to create the input debug shape for. - * @param {number} [color=0x00ff00] - The outline color of the debug shape. + * The Canvas drawImage data object. * - * @return {this} This Input Plugin. + * @name Phaser.Textures.Frame#canvasData + * @type {object} + * @readonly + * @since 3.0.0 */ - enableDebug: function (gameObject, color) - { - if (color === undefined) { color = 0x00ff00; } - - var input = gameObject.input; + canvasData: { - if (!input || !input.hitArea) + get: function () { - return this; + return this.data.drawImage; } - var shape = input.hitArea; - var shapeType = shape.type; - var debug = input.hitAreaDebug; - var factory = this.systems.add; - var updateList = this.systems.updateList; + } - if (debug) - { - updateList.remove(debug); +}); - debug.destroy(); +module.exports = Frame; - debug = null; - } - var offsetx = 0; - var offsety = 0; - switch (shapeType) - { - case GEOM_CONST.CIRCLE: - debug = factory.arc(0, 0, shape.radius); - offsetx = shape.x - shape.radius; - offsety = shape.y - shape.radius; - break; +/***/ }), - case GEOM_CONST.ELLIPSE: - debug = factory.ellipse(0, 0, shape.width, shape.height); - offsetx = shape.x - shape.width / 2; - offsety = shape.y - shape.height / 2; - break; +/***/ 31673: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - case GEOM_CONST.LINE: - debug = factory.line(0, 0, shape.x1, shape.y1, shape.x2, shape.y2); - break; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - case GEOM_CONST.POLYGON: - debug = factory.polygon(0, 0, shape.points); - break; +var Class = __webpack_require__(56694); +var Frame = __webpack_require__(82047); +var TextureSource = __webpack_require__(32547); - case GEOM_CONST.RECTANGLE: - debug = factory.rectangle(0, 0, shape.width, shape.height); - offsetx = shape.x; - offsety = shape.y; - break; +var TEXTURE_MISSING_ERROR = 'Texture "%s" has no frame "%s"'; - case GEOM_CONST.TRIANGLE: - debug = factory.triangle(0, 0, shape.x1, shape.y1, shape.x2, shape.y2, shape.x3, shape.y3); - break; - } +/** + * @classdesc + * A Texture consists of a source, usually an Image from the Cache, and a collection of Frames. + * The Frames represent the different areas of the Texture. For example a texture atlas + * may have many Frames, one for each element within the atlas. Where-as a single image would have + * just one frame, that encompasses the whole image. + * + * Every Texture, no matter where it comes from, always has at least 1 frame called the `__BASE` frame. + * This frame represents the entirety of the source image. + * + * 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. + * + * @class Texture + * @memberof Phaser.Textures + * @constructor + * @since 3.0.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 {(HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[])} source - An array of sources that are used to create the texture. Usually Images, but can also be a Canvas. + * @param {number} [width] - The width of the Texture. This is optional and automatically derived from the source images. + * @param {number} [height] - The height of the Texture. This is optional and automatically derived from the source images. + */ +var Texture = new Class({ - if (debug) + initialize: + + function Texture (manager, key, source, width, height) + { + if (!Array.isArray(source)) { - debug.isFilled = false; + source = [ source ]; + } - debug.preUpdate = function () - { - debug.setStrokeStyle(1 / gameObject.scale, color); + /** + * A reference to the Texture Manager this Texture belongs to. + * + * @name Phaser.Textures.Texture#manager + * @type {Phaser.Textures.TextureManager} + * @since 3.0.0 + */ + this.manager = manager; - debug.setDisplayOrigin(gameObject.displayOriginX, gameObject.displayOriginY); + /** + * The unique string-based key of this Texture. + * + * @name Phaser.Textures.Texture#key + * @type {string} + * @since 3.0.0 + */ + this.key = key; - var x = gameObject.x; - var y = gameObject.y; - var rotation = gameObject.rotation; - var scaleX = gameObject.scaleX; - var scaleY = gameObject.scaleY; + /** + * An array of TextureSource instances. + * These are unique to this Texture and contain the actual Image (or Canvas) data. + * + * @name Phaser.Textures.Texture#source + * @type {Phaser.Textures.TextureSource[]} + * @since 3.0.0 + */ + this.source = []; - if (gameObject.parentContainer) - { - var matrix = gameObject.getWorldTransformMatrix(); + /** + * An array of TextureSource data instances. + * Used to store additional data images, such as normal maps or specular maps. + * + * @name Phaser.Textures.Texture#dataSource + * @type {array} + * @since 3.0.0 + */ + this.dataSource = []; - x = matrix.tx; - y = matrix.ty; - rotation = matrix.rotation; - scaleX = matrix.scaleX; - scaleY = matrix.scaleY; - } + /** + * A key-value object pair associating the unique Frame keys with the Frames objects. + * + * @name Phaser.Textures.Texture#frames + * @type {object} + * @since 3.0.0 + */ + this.frames = {}; - debug.setRotation(rotation); - debug.setScale(scaleX, scaleY); - debug.setPosition(x + offsetx, y + offsety); - debug.setScrollFactor(gameObject.scrollFactorX, gameObject.scrollFactorY); - debug.setDepth(gameObject.depth); - }; + /** + * Any additional data that was set in the source JSON (if any), + * or any extra data you'd like to store relating to this texture + * + * @name Phaser.Textures.Texture#customData + * @type {object} + * @since 3.0.0 + */ + this.customData = {}; - updateList.add(debug); + /** + * The name of the first frame of the Texture. + * + * @name Phaser.Textures.Texture#firstFrame + * @type {string} + * @since 3.0.0 + */ + this.firstFrame = '__BASE'; + + /** + * The total number of Frames in this Texture, including the `__BASE` frame. + * + * A Texture will always contain at least 1 frame because every Texture contains a `__BASE` frame by default, + * in addition to any extra frames that have been added to it, such as when parsing a Sprite Sheet or Texture Atlas. + * + * @name Phaser.Textures.Texture#frameTotal + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.frameTotal = 0; - input.hitAreaDebug = debug; + // Load the Sources + for (var i = 0; i < source.length; i++) + { + this.source.push(new TextureSource(this, source[i], width, height)); } - - return this; }, /** - * Removes an Input Debug Shape from the given Game Object. + * Adds a new Frame to this Texture. * - * The shape is destroyed immediately and the `hitAreaDebug` property is set to `null`. + * A Frame is a rectangular region of a TextureSource with a unique index or string-based key. * - * @method Phaser.Input.InputPlugin#removeDebug - * @since 3.19.0 + * The name given must be unique within this Texture. If it already exists, this method will return `null`. * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to remove the input debug shape from. + * @method Phaser.Textures.Texture#add + * @since 3.0.0 * - * @return {this} This Input Plugin. + * @param {(number|string)} name - The name of this Frame. The name is unique within the Texture. + * @param {number} sourceIndex - The index of the TextureSource that this Frame is a part of. + * @param {number} x - The x coordinate of the top-left of this Frame. + * @param {number} y - The y coordinate of the top-left of this Frame. + * @param {number} width - The width of this Frame. + * @param {number} height - The height of this Frame. + * + * @return {?Phaser.Textures.Frame} The Frame that was added to this Texture, or `null` if the given name already exists. */ - removeDebug: function (gameObject) + add: function (name, sourceIndex, x, y, width, height) { - var input = gameObject.input; - - if (input && input.hitAreaDebug) + if (this.has(name)) { - var debug = input.hitAreaDebug; + return null; + } - this.systems.updateList.remove(debug); + var frame = new Frame(this, name, sourceIndex, x, y, width, height); - debug.destroy(); + this.frames[name] = frame; - input.hitAreaDebug = null; + // Set the first frame of the Texture (other than __BASE) + // This is used to ensure we don't spam the display with entire + // atlases of sprite sheets, but instead just the first frame of them + // should the dev incorrectly specify the frame index + if (this.firstFrame === '__BASE') + { + this.firstFrame = name; } - return this; + this.frameTotal++; + + return frame; }, /** - * Sets the Pointers to always poll. + * Removes the given Frame from this Texture. The Frame is destroyed immediately. * - * When a pointer is polled it runs a hit test to see which Game Objects are currently below it, - * or being interacted with it, regardless if the Pointer has actually moved or not. + * Any Game Objects using this Frame should stop using it _before_ you remove it, + * as it does not happen automatically. * - * You should enable this if you want objects in your game to fire over / out events, and the objects - * are constantly moving, but the pointer may not have. Polling every frame has additional computation - * costs, especially if there are a large number of interactive objects in your game. + * @method Phaser.Textures.Texture#remove + * @since 3.19.0 * - * @method Phaser.Input.InputPlugin#setPollAlways - * @since 3.0.0 + * @param {string} name - The key of the Frame to remove. * - * @return {this} This InputPlugin object. + * @return {boolean} True if a Frame with the matching key was removed from this Texture. */ - setPollAlways: function () + remove: function (name) { - return this.setPollRate(0); + if (this.has(name)) + { + var frame = this.get(name); + + frame.destroy(); + + delete this.frames[name]; + + return true; + } + + return false; }, /** - * Sets the Pointers to only poll when they are moved or updated. - * - * When a pointer is polled it runs a hit test to see which Game Objects are currently below it, - * or being interacted with it. + * Checks to see if a Frame matching the given key exists within this Texture. * - * @method Phaser.Input.InputPlugin#setPollOnMove + * @method Phaser.Textures.Texture#has * @since 3.0.0 * - * @return {this} This InputPlugin object. + * @param {string} name - The key of the Frame to check for. + * + * @return {boolean} True if a Frame with the matching key exists in this Texture. */ - setPollOnMove: function () + has: function (name) { - return this.setPollRate(-1); + return this.frames.hasOwnProperty(name); }, /** - * Sets the poll rate value. This is the amount of time that should have elapsed before a pointer - * will be polled again. See the `setPollAlways` and `setPollOnMove` methods. + * Gets a Frame from this Texture based on either the key or the index of the Frame. * - * @method Phaser.Input.InputPlugin#setPollRate + * In a Texture Atlas Frames are typically referenced by a key. + * In a Sprite Sheet Frames are referenced by an index. + * Passing no value for the name returns the base texture. + * + * @method Phaser.Textures.Texture#get * @since 3.0.0 * - * @param {number} value - The amount of time, in ms, that should elapsed before re-polling the pointers. + * @param {(string|number)} [name] - The string-based name, or integer based index, of the Frame to get from this Texture. * - * @return {this} This InputPlugin object. + * @return {Phaser.Textures.Frame} The Texture Frame. */ - setPollRate: function (value) + get: function (name) { - this.pollRate = value; - this._pollTimer = 0; + // null, undefined, empty string, zero + if (!name) + { + name = this.firstFrame; + } - return this; + var frame = this.frames[name]; + + if (!frame) + { + console.warn(TEXTURE_MISSING_ERROR, this.key, name); + + frame = this.frames[this.firstFrame]; + } + + return frame; }, /** - * When set to `true` the global Input Manager will emulate DOM behavior by only emitting events from - * the top-most Scene in the Scene List. By default, if a Scene receives an input event it will then stop the event - * from flowing down to any Scenes below it in the Scene list. To disable this behavior call this method with `false`. + * Takes the given TextureSource and returns the index of it within this Texture. + * If it's not in this Texture, it returns -1. + * Unless this Texture has multiple TextureSources, such as with a multi-atlas, this + * method will always return zero or -1. * - * @method Phaser.Input.InputPlugin#setGlobalTopOnly + * @method Phaser.Textures.Texture#getTextureSourceIndex * @since 3.0.0 * - * @param {boolean} value - Set to `true` to stop processing input events on the Scene that receives it, or `false` to let the event continue down the Scene list. + * @param {Phaser.Textures.TextureSource} source - The TextureSource to check. * - * @return {this} This InputPlugin object. + * @return {number} The index of the TextureSource within this Texture, or -1 if not in this Texture. */ - setGlobalTopOnly: function (value) + getTextureSourceIndex: function (source) { - this.manager.globalTopOnly = value; + for (var i = 0; i < this.source.length; i++) + { + if (this.source[i] === source) + { + return i; + } + } - return this; + return -1; }, /** - * When set to `true` this Input Plugin will emulate DOM behavior by only emitting events from - * the top-most Game Objects in the Display List. - * - * If set to `false` it will emit events from all Game Objects below a Pointer, not just the top one. + * Returns an array of all the Frames in the given TextureSource. * - * @method Phaser.Input.InputPlugin#setTopOnly + * @method Phaser.Textures.Texture#getFramesFromTextureSource * @since 3.0.0 * - * @param {boolean} value - `true` to only include the top-most Game Object, or `false` to include all Game Objects in a hit test. + * @param {number} sourceIndex - The index of the TextureSource to get the Frames from. + * @param {boolean} [includeBase=false] - Include the `__BASE` Frame in the output array? * - * @return {this} This InputPlugin object. + * @return {Phaser.Textures.Frame[]} An array of Texture Frames. */ - setTopOnly: function (value) + getFramesFromTextureSource: function (sourceIndex, includeBase) { - this.topOnly = value; + if (includeBase === undefined) { includeBase = false; } - return this; + var out = []; + + for (var frameName in this.frames) + { + if (frameName === '__BASE' && !includeBase) + { + continue; + } + + var frame = this.frames[frameName]; + + if (frame.sourceIndex === sourceIndex) + { + out.push(frame); + } + } + + return out; }, /** - * Given an array of Game Objects and a Pointer, sort the array and return it, - * so that the objects are in render order with the lowest at the bottom. + * Returns an array with all of the names of the Frames in this Texture. * - * @method Phaser.Input.InputPlugin#sortGameObjects + * Useful if you want to randomly assign a Frame to a Game Object, as you can + * pick a random element from the returned array. + * + * @method Phaser.Textures.Texture#getFrameNames * @since 3.0.0 * - * @param {Phaser.GameObjects.GameObject[]} gameObjects - An array of Game Objects to be sorted. - * @param {Phaser.Input.Pointer} pointer - The Pointer to check against the Game Objects. + * @param {boolean} [includeBase=false] - Include the `__BASE` Frame in the output array? * - * @return {Phaser.GameObjects.GameObject[]} The sorted array of Game Objects. + * @return {string[]} An array of all Frame names in this Texture. */ - sortGameObjects: function (gameObjects, pointer) + getFrameNames: function (includeBase) { - if (gameObjects.length < 2) - { - return gameObjects; - } + if (includeBase === undefined) { includeBase = false; } - var list = pointer.camera.renderList; + var out = Object.keys(this.frames); - return gameObjects.sort(function (childA, childB) + if (!includeBase) { - return list.indexOf(childB) - list.indexOf(childA); - }); + var idx = out.indexOf('__BASE'); + + if (idx !== -1) + { + out.splice(idx, 1); + } + } + + return out; }, /** - * Given an array of Drop Zone Game Objects, sort the array and return it, - * so that the objects are in depth index order with the lowest at the bottom. + * Given a Frame name, return the source image it uses to render with. * - * @method Phaser.Input.InputPlugin#sortDropZones - * @since 3.52.0 + * This will return the actual DOM Image or Canvas element. * - * @param {Phaser.GameObjects.GameObject[]} gameObjects - An array of Game Objects to be sorted. + * @method Phaser.Textures.Texture#getSourceImage + * @since 3.0.0 * - * @return {Phaser.GameObjects.GameObject[]} The sorted array of Game Objects. + * @param {(string|number)} [name] - The string-based name, or integer based index, of the Frame to get from this Texture. + * + * @return {(HTMLImageElement|HTMLCanvasElement|Phaser.GameObjects.RenderTexture)} The DOM Image, Canvas Element or Render Texture. */ - sortDropZones: function (gameObjects) + getSourceImage: function (name) { - if (gameObjects.length < 2) + if (name === undefined || name === null || this.frameTotal === 1) { - return gameObjects; + name = '__BASE'; } - this.scene.sys.depthSort(); + var frame = this.frames[name]; - return gameObjects.sort(this.sortDropZoneHandler.bind(this)); + if (frame) + { + return frame.source.image; + } + else + { + console.warn(TEXTURE_MISSING_ERROR, this.key, name); + + return this.frames['__BASE'].source.image; + } }, /** - * Return the child lowest down the display list (with the smallest index) - * Will iterate through all parent containers, if present. + * Given a Frame name, return the data source image it uses to render with. + * You can use this to get the normal map for an image for example. * - * Prior to version 3.52.0 this method was called `sortHandlerGO`. + * This will return the actual DOM Image. * - * @method Phaser.Input.InputPlugin#sortDropZoneHandler - * @private - * @since 3.52.0 + * @method Phaser.Textures.Texture#getDataSourceImage + * @since 3.7.0 * - * @param {Phaser.GameObjects.GameObject} childA - The first Game Object to compare. - * @param {Phaser.GameObjects.GameObject} childB - The second Game Object to compare. + * @param {(string|number)} [name] - The string-based name, or integer based index, of the Frame to get from this Texture. * - * @return {number} Returns either a negative or positive integer, or zero if they match. + * @return {(HTMLImageElement|HTMLCanvasElement)} The DOM Image or Canvas Element. */ - sortDropZoneHandler: function (childA, childB) + getDataSourceImage: function (name) { - if (!childA.parentContainer && !childB.parentContainer) - { - // Quick bail out when neither child has a container - return this.displayList.getIndex(childB) - this.displayList.getIndex(childA); - } - else if (childA.parentContainer === childB.parentContainer) - { - // Quick bail out when both children have the same container - return childB.parentContainer.getIndex(childB) - childA.parentContainer.getIndex(childA); - } - else if (childA.parentContainer === childB) + if (name === undefined || name === null || this.frameTotal === 1) { - // Quick bail out when childA is a child of childB - return -1; + name = '__BASE'; } - else if (childB.parentContainer === childA) + + var frame = this.frames[name]; + var idx; + + if (!frame) { - // Quick bail out when childA is a child of childB - return 1; + console.warn(TEXTURE_MISSING_ERROR, this.key, name); + + idx = this.frames['__BASE'].sourceIndex; } else { - // Container index check - var listA = childA.getIndexList(); - var listB = childB.getIndexList(); - var len = Math.min(listA.length, listB.length); - - for (var i = 0; i < len; i++) - { - var indexA = listA[i]; - var indexB = listB[i]; - - if (indexA === indexB) - { - // Go to the next level down - continue; - } - else - { - // Non-matching parents, so return - return indexB - indexA; - } - } - - return listB.length - listA.length; + idx = frame.sourceIndex; } - // Technically this shouldn't happen, but ... - // eslint-disable-next-line no-unreachable - return 0; + return this.dataSource[idx].image; }, /** - * This method should be called from within an input event handler, such as `pointerdown`. + * Adds a data source image to this Texture. * - * When called, it stops the Input Manager from allowing _this specific event_ to be processed by any other Scene - * not yet handled in the scene list. + * An example of a data source image would be a normal map, where all of the Frames for this Texture + * equally apply to the normal map. * - * @method Phaser.Input.InputPlugin#stopPropagation + * @method Phaser.Textures.Texture#setDataSource * @since 3.0.0 * - * @return {this} This InputPlugin object. + * @param {(HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[])} data - The source image. */ - stopPropagation: function () + setDataSource: function (data) { - this.manager._tempSkip = true; + if (!Array.isArray(data)) + { + data = [ data ]; + } - return this; - }, + for (var i = 0; i < data.length; i++) + { + var source = this.source[i]; - /** - * 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.InputPlugin#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) - { - return this.manager.addPointer(quantity); + this.dataSource.push(new TextureSource(this, data[i], source.width, source.height)); + } }, /** - * 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 + * Sets the Filter Mode for this Texture. * - * It's up to you to pick a suitable cursor format that works across the range of browsers you need to support. + * The mode can be either Linear, the default, or Nearest. * - * @method Phaser.Input.InputPlugin#setDefaultCursor - * @since 3.10.0 + * For pixel-art you should use Nearest. * - * @param {string} cursor - The CSS to be used when setting the default cursor. + * The mode applies to the entire Texture, not just a specific Frame of it. * - * @return {this} This Input instance. - */ - setDefaultCursor: function (cursor) - { - this.manager.setDefaultCursor(cursor); - - return this; - }, - - /** - * The Scene that owns this plugin is transitioning in. + * @method Phaser.Textures.Texture#setFilter + * @since 3.0.0 * - * @method Phaser.Input.InputPlugin#transitionIn - * @private - * @since 3.5.0 + * @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode. */ - transitionIn: function () + setFilter: function (filterMode) { - this.enabled = this.settings.transitionAllowInput; - }, + var i; - /** - * The Scene that owns this plugin has finished transitioning in. - * - * @method Phaser.Input.InputPlugin#transitionComplete - * @private - * @since 3.5.0 - */ - transitionComplete: function () - { - if (!this.settings.transitionAllowInput) + for (i = 0; i < this.source.length; i++) { - this.enabled = true; + this.source[i].setFilter(filterMode); } - }, - /** - * The Scene that owns this plugin is transitioning out. - * - * @method Phaser.Input.InputPlugin#transitionOut - * @private - * @since 3.5.0 - */ - transitionOut: function () - { - this.enabled = this.settings.transitionAllowInput; + for (i = 0; i < this.dataSource.length; i++) + { + this.dataSource[i].setFilter(filterMode); + } }, /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. + * Destroys this Texture and releases references to its sources and frames. * - * @method Phaser.Input.InputPlugin#shutdown - * @fires Phaser.Input.Events#SHUTDOWN - * @private + * @method Phaser.Textures.Texture#destroy * @since 3.0.0 */ - shutdown: function () + destroy: function () { - // Registered input plugins listen for this - this.pluginEvents.emit(Events.SHUTDOWN); + var i; + var source = this.source; + var dataSource = this.dataSource; - this._temp.length = 0; - this._list.length = 0; - this._draggable.length = 0; - this._pendingRemoval.length = 0; - this._pendingInsertion.length = 0; - this._dragState.length = 0; + for (i = 0; i < source.length; i++) + { + if (source[i]) + { + source[i].destroy(); + } + } - for (var i = 0; i < 10; i++) + for (i = 0; i < dataSource.length; i++) { - this._drag[i] = []; - this._over[i] = []; + if (dataSource[i]) + { + dataSource[i].destroy(); + } } - this.removeAllListeners(); + for (var frameName in this.frames) + { + var frame = this.frames[frameName]; - var manager = this.manager; + if (frame) + { + frame.destroy(); + } + } - manager.canvas.style.cursor = manager.defaultCursor; + this.source = []; + this.dataSource = []; + this.frames = {}; - var eventEmitter = this.systems.events; + this.manager.removeKey(this.key); - eventEmitter.off(SceneEvents.TRANSITION_START, this.transitionIn, this); - eventEmitter.off(SceneEvents.TRANSITION_OUT, this.transitionOut, this); - eventEmitter.off(SceneEvents.TRANSITION_COMPLETE, this.transitionComplete, this); - eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this); + this.manager = null; + } - manager.events.off(Events.GAME_OUT, this.onGameOut, this); - manager.events.off(Events.GAME_OVER, this.onGameOver, this); +}); - eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); - }, +module.exports = Texture; - /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. - * - * @method Phaser.Input.InputPlugin#destroy - * @fires Phaser.Input.Events#DESTROY - * @private - * @since 3.0.0 - */ - destroy: function () - { - this.shutdown(); - // Registered input plugins listen for this - this.pluginEvents.emit(Events.DESTROY); +/***/ }), - this.pluginEvents.removeAllListeners(); +/***/ 6237: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.scene.sys.events.off(SceneEvents.START, this.start, this); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.scene = null; - this.cameras = null; - this.manager = null; - this.events = null; - this.mouse = null; - }, +var CanvasPool = __webpack_require__(61068); +var CanvasTexture = __webpack_require__(17487); +var Class = __webpack_require__(56694); +var Color = __webpack_require__(27119); +var CONST = __webpack_require__(86459); +var DynamicTexture = __webpack_require__(845); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(38203); +var Frame = __webpack_require__(82047); +var GameEvents = __webpack_require__(97081); +var GenerateTexture = __webpack_require__(52780); +var GetValue = __webpack_require__(10850); +var ImageGameObject = __webpack_require__(1539); +var IsPlainObject = __webpack_require__(42911); +var Parser = __webpack_require__(69150); +var Rectangle = __webpack_require__(74118); +var Texture = __webpack_require__(31673); - /** - * The x coordinates of the ActivePointer based on the first camera in the camera list. - * This is only safe to use if your game has just 1 non-transformed camera and doesn't use multi-touch. - * - * @name Phaser.Input.InputPlugin#x - * @type {number} - * @readonly - * @since 3.0.0 - */ - x: { +/** + * @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. + */ - get: function () - { - return this.manager.activePointer.x; - } +/** + * @classdesc + * When Phaser boots it will create an instance of this Texture Manager class. + * + * It is a global manager that handles all textures in your game. You can access it from within + * a Scene via the `this.textures` property. + * + * Its role is as a manager for all textures that your game uses. It can create, update and remove + * textures globally, as well as parse texture data from external files, such as sprite sheets + * and texture atlases. + * + * Sprites and other texture-based Game Objects get their texture data directly from this class. + * + * @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, - /** - * The y coordinates of the ActivePointer based on the first camera in the camera list. - * This is only safe to use if your game has just 1 non-transformed camera and doesn't use multi-touch. - * - * @name Phaser.Input.InputPlugin#y - * @type {number} - * @readonly - * @since 3.0.0 - */ - y: { + initialize: - get: function () - { - return this.manager.activePointer.y; - } + function TextureManager (game) + { + EventEmitter.call(this); - }, + /** + * The Game that the Texture Manager belongs to. + * + * A game will only ever have one instance of a Texture Manager. + * + * @name Phaser.Textures.TextureManager#game + * @type {Phaser.Game} + * @since 3.0.0 + */ + this.game = game; - /** - * Are any mouse or touch pointers currently over the game canvas? - * - * @name Phaser.Input.InputPlugin#isOver - * @type {boolean} - * @readonly - * @since 3.16.0 - */ - isOver: { + /** + * The internal name of this manager. + * + * @name Phaser.Textures.TextureManager#name + * @type {string} + * @readonly + * @since 3.0.0 + */ + this.name = 'TextureManager'; - get: function () - { - return this.manager.isOver; - } + /** + * This object contains all Textures that belong to this Texture Manager. + * + * Textures are identified by string-based keys, which are used as the property + * within this object. Therefore, you can access any texture directly from this + * object without any iteration. + * + * You should not typically modify this object directly, but instead use the + * methods provided by the Texture Manager to add and remove entries from it. + * + * @name Phaser.Textures.TextureManager#list + * @type {object} + * @default {} + * @since 3.0.0 + */ + this.list = {}; - }, + /** + * The temporary canvas element used to save the pixel data of an arbitrary texture + * during the `TextureManager.getPixel` and `getPixelAlpha` methods. + * + * @name Phaser.Textures.TextureManager#_tempCanvas + * @type {HTMLCanvasElement} + * @private + * @since 3.0.0 + */ + this._tempCanvas = CanvasPool.create2D(this); - /** - * 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.InputPlugin#mousePointer - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 - */ - mousePointer: { + /** + * The 2d context of the `_tempCanvas` element. + * + * @name Phaser.Textures.TextureManager#_tempContext + * @type {CanvasRenderingContext2D} + * @private + * @since 3.0.0 + */ + this._tempContext = this._tempCanvas.getContext('2d', { willReadFrequently: true }); - get: function () - { - return this.manager.mousePointer; - } + /** + * An internal tracking value used for emitting the 'READY' event after all of + * the managers in the game have booted. + * + * @name Phaser.Textures.TextureManager#_pending + * @type {number} + * @private + * @default 0 + * @since 3.0.0 + */ + this._pending = 0; - }, + /** + * An Image Game Object that belongs to this Texture Manager. + * + * Used as a drawing stamp within Dynamic Textures. + * + * This is not part of the display list and doesn't render. + * + * @name Phaser.Textures.TextureManager#stamp + * @type {Phaser.GameObjects.Image} + * @readonly + * @since 3.60.0 + */ + this.stamp; - /** - * The current active input Pointer. - * - * @name Phaser.Input.InputPlugin#activePointer - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.0.0 - */ - activePointer: { + /** + * The crop Rectangle as used by the Stamp when it needs to crop itself. + * + * @name Phaser.Textures.TextureManager#stampCrop + * @type {Phaser.Geom.Rectangle} + * @since 3.60.0 + */ + this.stampCrop = new Rectangle(); - get: function () - { - return this.manager.activePointer; - } + /** + * If this flag is `true` then the Texture Manager will never emit any + * warnings to the console log that report missing textures. + * + * @name Phaser.Textures.TextureManager#silentWarnings + * @type {boolean} + * @default false + * @since 3.60.0 + */ + this.silentWarnings = false; + game.events.once(GameEvents.BOOT, this.boot, this); }, /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. + * The Boot Handler called by Phaser.Game when it first starts up. * - * @name Phaser.Input.InputPlugin#pointer1 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 + * @method Phaser.Textures.TextureManager#boot + * @private + * @since 3.0.0 */ - pointer1: { - - get: function () - { - return this.manager.pointers[1]; - } + boot: function () + { + this._pending = 3; - }, + this.on(Events.LOAD, this.updatePending, this); + this.on(Events.ERROR, this.updatePending, this); - /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. - * - * @name Phaser.Input.InputPlugin#pointer2 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 - */ - pointer2: { + var config = this.game.config; - get: function () - { - return this.manager.pointers[2]; - } + this.addBase64('__DEFAULT', config.defaultImage); + this.addBase64('__MISSING', config.missingImage); + this.addBase64('__WHITE', config.whiteImage); + this.game.events.once(GameEvents.DESTROY, this.destroy, this); }, /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. + * After 'onload' or 'onerror' invoked twice, emit 'ready' event. * - * @name Phaser.Input.InputPlugin#pointer3 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 + * @method Phaser.Textures.TextureManager#updatePending + * @private + * @since 3.0.0 */ - pointer3: { + updatePending: function () + { + this._pending--; - get: function () + if (this._pending === 0) { - return this.manager.pointers[3]; - } - - }, + this.off(Events.LOAD); + this.off(Events.ERROR); - /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. - * - * @name Phaser.Input.InputPlugin#pointer4 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 - */ - pointer4: { + this.emit(Events.READY); - get: function () - { - return this.manager.pointers[4]; + this.stamp = new ImageGameObject(this.game.scene.systemScene).setOrigin(0); } - }, /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. + * Checks the given texture key and throws a console.warn if the key is already in use, then returns false. * - * @name Phaser.Input.InputPlugin#pointer5 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 - */ - pointer5: { - - get: function () - { - return this.manager.pointers[5]; - } - - }, - - /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. + * If you wish to avoid the console.warn then use `TextureManager.exists` instead. * - * @name Phaser.Input.InputPlugin#pointer6 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 + * @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`. */ - pointer6: { - - get: function () + checkKey: function (key) + { + if (this.exists(key)) { - return this.manager.pointers[6]; + if (!this.silentWarnings) + { + // eslint-disable-next-line no-console + console.error('Texture key already in use: ' + key); + } + + return false; } + return true; }, /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. + * 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. * - * @name Phaser.Input.InputPlugin#pointer7 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 + * 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. */ - pointer7: { - - get: function () + remove: function (key) + { + if (typeof key === 'string') { - return this.manager.pointers[7]; - } - - }, + if (this.exists(key)) + { + key = this.get(key); + } + else + { + if (!this.silentWarnings) + { + console.warn('No texture found matching key: ' + key); + } - /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. - * - * @name Phaser.Input.InputPlugin#pointer8 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 - */ - pointer8: { + return this; + } + } - get: function () + // By this point key should be a Texture, if not, the following fails anyway + if (this.list.hasOwnProperty(key.key)) { - return this.manager.pointers[8]; + key.destroy(); + + this.emit(Events.REMOVE, key.key); + this.emit(Events.REMOVE_KEY + key.key); } + return this; }, /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. + * Removes a key from the Texture Manager but does not destroy the Texture that was using the key. * - * @name Phaser.Input.InputPlugin#pointer9 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 + * @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. */ - pointer9: { - - get: function () + removeKey: function (key) + { + if (this.list.hasOwnProperty(key)) { - return this.manager.pointers[9]; + delete this.list[key]; } + return this; }, /** - * A touch-based Pointer object. - * This will be `undefined` by default unless you add a new Pointer using `addPointer`. + * Adds a new Texture to the Texture Manager created from the given Base64 encoded data. * - * @name Phaser.Input.InputPlugin#pointer10 - * @type {Phaser.Input.Pointer} - * @readonly - * @since 3.10.0 + * 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. */ - pointer10: { - - get: function () + addBase64: function (key, data) + { + if (this.checkKey(key)) { - return this.manager.pointers[10]; - } - - } - -}); - -PluginCache.register('InputPlugin', InputPlugin, 'input'); - -module.exports = InputPlugin; - - -/***/ }), -/* 1322 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -/** - * @namespace Phaser.Input.Keyboard - */ - -module.exports = { - - Events: __webpack_require__(154), - - KeyboardManager: __webpack_require__(410), - KeyboardPlugin: __webpack_require__(1330), - - Key: __webpack_require__(512), - KeyCodes: __webpack_require__(143), - - KeyCombo: __webpack_require__(513), - - AdvanceKeyCombo: __webpack_require__(515), - ProcessKeyCombo: __webpack_require__(514), - ResetKeyCombo: __webpack_require__(516), - - JustDown: __webpack_require__(1332), - JustUp: __webpack_require__(1333), - DownDuration: __webpack_require__(1334), - UpDuration: __webpack_require__(1335) - -}; - - -/***/ }), -/* 1323 */ -/***/ (function(module, exports) { + var _this = this; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var image = new Image(); -/** - * The Global Key Down Event. - * - * This event is dispatched by the Keyboard Plugin when any key on the keyboard is pressed down. - * - * Listen to this event from within a Scene using: `this.input.keyboard.on('keydown', listener)`. - * - * You can also listen for a specific key being pressed. See [Keyboard.Events.KEY_DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:KEY_DOWN} for details. - * - * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:DOWN} for details. - * - * _Note_: Many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting. - * Read [this article on ghosting]{@link http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/} for details. - * - * Also, please be aware that some browser extensions can disable or override Phaser keyboard handling. - * For example, the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. - * There are others. So, please check your extensions if you find you have specific keys that don't work. - * - * @event Phaser.Input.Keyboard.Events#ANY_KEY_DOWN - * @since 3.0.0 - * - * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about the key that was pressed, any modifiers, etc. - */ -module.exports = 'keydown'; + image.onerror = function () + { + _this.emit(Events.ERROR, key); + }; + image.onload = function () + { + var texture = _this.create(key, image); -/***/ }), -/* 1324 */ -/***/ (function(module, exports) { + Parser.Image(texture, 0); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + _this.emit(Events.ADD, key, texture); + _this.emit(Events.ADD_KEY + key, texture); + _this.emit(Events.LOAD, key, texture); + }; -/** - * The Global Key Up Event. - * - * This event is dispatched by the Keyboard Plugin when any key on the keyboard is released. - * - * Listen to this event from within a Scene using: `this.input.keyboard.on('keyup', listener)`. - * - * You can also listen for a specific key being released. See [Keyboard.Events.KEY_UP]{@linkcode Phaser.Input.Keyboard.Events#event:KEY_UP} for details. - * - * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.UP]{@linkcode Phaser.Input.Keyboard.Events#event:UP} for details. - * - * @event Phaser.Input.Keyboard.Events#ANY_KEY_UP - * @since 3.0.0 - * - * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about the key that was released, any modifiers, etc. - */ -module.exports = 'keyup'; + image.src = data; + } + return this; + }, -/***/ }), -/* 1325 */ -/***/ (function(module, exports) { + /** + * 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; } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var data = ''; -/** - * The Key Combo Match Event. - * - * This event is dispatched by the Keyboard Plugin when a [Key Combo]{@link Phaser.Input.Keyboard.KeyCombo} is matched. - * - * Listen for this event from the Key Plugin after a combo has been created: - * - * ```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!'); - * }); - * ``` - * - * @event Phaser.Input.Keyboard.Events#COMBO_MATCH - * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.KeyCombo} keycombo - The Key Combo object that was matched. - * @param {KeyboardEvent} event - The native DOM Keyboard Event of the final key in the combo. You can inspect this to learn more about any modifiers, etc. - */ -module.exports = 'keycombomatch'; + var textureFrame = this.getFrame(key, frame); + if (textureFrame && (textureFrame.source.isRenderTexture || textureFrame.source.isGLTexture)) + { + if (!this.silentWarnings) + { + console.warn('Cannot getBase64 from WebGL Texture'); + } + } + else if (textureFrame) + { + var cd = textureFrame.canvasData; -/***/ }), -/* 1326 */ -/***/ (function(module, exports) { + var canvas = CanvasPool.create2D(this, cd.width, cd.height); + var ctx = canvas.getContext('2d', { willReadFrequently: true }); + + if (cd.width > 0 && cd.height > 0) + { + ctx.drawImage( + textureFrame.source.image, + cd.x, + cd.y, + cd.width, + cd.height, + 0, + 0, + cd.width, + cd.height + ); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + data = canvas.toDataURL(type, encoderOptions); -/** - * The Key Down Event. - * - * This event is dispatched by a [Key]{@link Phaser.Input.Keyboard.Key} object when it is pressed. - * - * Listen for this event from the Key object instance directly: - * - * ```javascript - * var spaceBar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); - * - * spaceBar.on('down', listener) - * ``` - * - * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_DOWN} for details. - * - * @event Phaser.Input.Keyboard.Events#DOWN - * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.Key} key - The Key object that was pressed. - * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about any modifiers, etc. - */ -module.exports = 'down'; + CanvasPool.remove(canvas); + } + return data; + }, -/***/ }), -/* 1327 */ -/***/ (function(module, exports) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.checkKey(key)) + { + texture = this.create(key, source); -/** - * The Key Down Event. - * - * This event is dispatched by the Keyboard Plugin when any key on the keyboard is pressed down. - * - * Unlike the `ANY_KEY_DOWN` event, this one has a special dynamic event name. For example, to listen for the `A` key being pressed - * use the following from within a Scene: `this.input.keyboard.on('keydown-A', listener)`. You can replace the `-A` part of the event - * name with any valid [Key Code string]{@link Phaser.Input.Keyboard.KeyCodes}. For example, this will listen for the space bar: - * `this.input.keyboard.on('keydown-SPACE', listener)`. - * - * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_DOWN} for details. - * - * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:DOWN} for details. - * - * _Note_: Many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting. - * Read [this article on ghosting]{@link http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/} for details. - * - * Also, please be aware that some browser extensions can disable or override Phaser keyboard handling. - * For example, the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. - * There are others. So, please check your extensions if you find you have specific keys that don't work. - * - * @event Phaser.Input.Keyboard.Events#KEY_DOWN - * @since 3.0.0 - * - * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about the key that was pressed, any modifiers, etc. - */ -module.exports = 'keydown-'; + Parser.Image(texture, 0); + if (dataSource) + { + texture.setDataSource(dataSource); + } -/***/ }), -/* 1328 */ -/***/ (function(module, exports) { + this.emit(Events.ADD, key, texture); + this.emit(Events.ADD_KEY + key, texture); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return texture; + }, -/** - * The Key Up Event. - * - * This event is dispatched by the Keyboard Plugin when any key on the keyboard is released. - * - * Unlike the `ANY_KEY_UP` event, this one has a special dynamic event name. For example, to listen for the `A` key being released - * use the following from within a Scene: `this.input.keyboard.on('keyup-A', listener)`. You can replace the `-A` part of the event - * name with any valid [Key Code string]{@link Phaser.Input.Keyboard.KeyCodes}. For example, this will listen for the space bar: - * `this.input.keyboard.on('keyup-SPACE', listener)`. - * - * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_UP]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_UP} for details. - * - * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.UP]{@linkcode Phaser.Input.Keyboard.Events#event:UP} for details. - * - * @event Phaser.Input.Keyboard.Events#KEY_UP - * @since 3.0.0 - * - * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about the key that was released, any modifiers, etc. - */ -module.exports = 'keyup-'; + /** + * 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; } -/***/ }), -/* 1329 */ -/***/ (function(module, exports) { + texture = this.create(key, glTexture, width, height); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + texture.add('__BASE', 0, 0, 0, width, height); -/** - * The Key Up Event. - * - * This event is dispatched by a [Key]{@link Phaser.Input.Keyboard.Key} object when it is released. - * - * Listen for this event from the Key object instance directly: - * - * ```javascript - * var spaceBar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); - * - * spaceBar.on('up', listener) - * ``` - * - * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_UP]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_UP} for details. - * - * @event Phaser.Input.Keyboard.Events#UP - * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.Key} key - The Key object that was released. - * @param {KeyboardEvent} event - The native DOM Keyboard Event. You can inspect this to learn more about any modifiers, etc. - */ -module.exports = 'up'; + this.emit(Events.ADD, key, texture); + this.emit(Events.ADD_KEY + key, texture); + } + return texture; + }, -/***/ }), -/* 1330 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Adds a Compressed Texture to this Texture Manager. + * + * The texture should typically have been loaded via the `CompressedTextureFile` loader, + * in order to prepare the correct data object this method requires. + * + * You can optionally also pass atlas data to this method, in which case a texture atlas + * will be generated from the given compressed texture, combined with the atlas data. + * + * @method Phaser.Textures.TextureManager#addCompressedTexture + * @fires Phaser.Textures.Events#ADD + * @since 3.60.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {Phaser.Types.Textures.CompressedTextureData} textureData - The Compressed Texture data object. + * @param {object} [atlasData] - Optional Texture Atlas data. + * + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. + */ + addCompressedTexture: function (key, textureData, atlasData) + { + var texture = null; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.checkKey(key)) + { + texture = this.create(key, textureData); -var Class = __webpack_require__(0); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(154); -var GameEvents = __webpack_require__(22); -var GetValue = __webpack_require__(6); -var InputEvents = __webpack_require__(51); -var InputPluginCache = __webpack_require__(153); -var Key = __webpack_require__(512); -var KeyCodes = __webpack_require__(143); -var KeyCombo = __webpack_require__(513); -var KeyMap = __webpack_require__(1331); -var SceneEvents = __webpack_require__(20); -var SnapFloor = __webpack_require__(76); + texture.add('__BASE', 0, 0, 0, textureData.width, textureData.height); -/** - * @classdesc - * The Keyboard Plugin is an input plugin that belongs to the Scene-owned Input system. - * - * Its role is to listen for native DOM Keyboard Events and then process them. - * - * You do not need to create this class directly, the Input system will create an instance of it automatically. - * - * You can access it from within a Scene using `this.input.keyboard`. For example, you can do: - * - * ```javascript - * this.input.keyboard.on('keydown', callback, context); - * ``` - * - * Or, to listen for a specific key: - * - * ```javascript - * this.input.keyboard.on('keydown-A', callback, context); - * ``` - * - * You can also create Key objects, which you can then poll in your game loop: - * - * ```javascript - * var spaceBar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); - * ``` - * - * If you have multiple parallel Scenes, each trying to get keyboard input, be sure to disable capture on them to stop them from - * stealing input from another Scene in the list. You can do this with `this.input.keyboard.enabled = false` within the - * Scene to stop all input, or `this.input.keyboard.preventDefault = false` to stop a Scene halting input on another Scene. - * - * _Note_: Many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting. - * See http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/ for more details. - * - * Also please be aware that certain browser extensions can disable or override Phaser keyboard handling. - * For example the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. - * And there are others. So, please check your extensions before opening Phaser issues about keys that don't work. - * - * @class KeyboardPlugin - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Input.Keyboard - * @constructor - * @since 3.10.0 - * - * @param {Phaser.Input.InputPlugin} sceneInputPlugin - A reference to the Scene Input Plugin that the KeyboardPlugin belongs to. - */ -var KeyboardPlugin = new Class({ + if (atlasData) + { + if (Array.isArray(atlasData)) + { + for (var i = 0; i < atlasData.length; i++) + { + Parser.JSONHash(texture, i, atlasData[i]); + } + } + else + { + Parser.JSONHash(texture, 0, atlasData); + } + } - Extends: EventEmitter, + this.emit(Events.ADD, key, texture); + this.emit(Events.ADD_KEY + key, texture); + } - initialize: + return texture; + }, - function KeyboardPlugin (sceneInputPlugin) + /** + * 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) { - EventEmitter.call(this); + var texture = null; - /** - * A reference to the core game, so we can listen for visibility events. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#game - * @type {Phaser.Game} - * @since 3.16.0 - */ - this.game = sceneInputPlugin.systems.game; + if (this.checkKey(key)) + { + texture = this.create(key, renderTexture); - /** - * A reference to the Scene that this Input Plugin is responsible for. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#scene - * @type {Phaser.Scene} - * @since 3.10.0 - */ - this.scene = sceneInputPlugin.scene; + texture.add('__BASE', 0, 0, 0, renderTexture.width, renderTexture.height); - /** - * A reference to the Scene Systems Settings. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#settings - * @type {Phaser.Types.Scenes.SettingsObject} - * @since 3.10.0 - */ - this.settings = this.scene.sys.settings; + this.emit(Events.ADD, key, texture); + this.emit(Events.ADD_KEY + key, texture); + } - /** - * A reference to the Scene Input Plugin that created this Keyboard Plugin. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#sceneInputPlugin - * @type {Phaser.Input.InputPlugin} - * @since 3.10.0 - */ - this.sceneInputPlugin = sceneInputPlugin; + return texture; + }, - /** - * A reference to the global Keyboard Manager. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#manager - * @type {Phaser.Input.Keyboard.KeyboardManager} - * @since 3.16.0 - */ - this.manager = sceneInputPlugin.manager.keyboard; + /** + * 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); - /** - * A boolean that controls if this Keyboard Plugin is enabled or not. - * Can be toggled on the fly. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#enabled - * @type {boolean} - * @default true - * @since 3.10.0 - */ - this.enabled = true; + config.canvas = canvas; - /** - * An array of Key objects to process. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#keys - * @type {Phaser.Input.Keyboard.Key[]} - * @since 3.10.0 - */ - this.keys = []; + GenerateTexture(config); - /** - * An array of KeyCombo objects to process. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#combos - * @type {Phaser.Input.Keyboard.KeyCombo[]} - * @since 3.10.0 - */ - this.combos = []; + return this.addCanvas(key, canvas); + } + else + { + return null; + } + }, - /** - * Internal repeat key flag. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#prevCode - * @type {string} - * @private - * @since 3.50.0 - */ - this.prevCode = 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; } - /** - * Internal repeat key flag. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#prevTime - * @type {number} - * @private - * @since 3.50.0 - */ - this.prevTime = 0; + if (this.checkKey(key)) + { + var canvas = CanvasPool.create(this, width, height, CONST.CANVAS, true); - /** - * Internal repeat key flag. - * - * @name Phaser.Input.Keyboard.KeyboardPlugin#prevType - * @type {string} - * @private - * @since 3.50.1 - */ - this.prevType = null; + return this.addCanvas(key, canvas); + } - sceneInputPlugin.pluginEvents.once(InputEvents.BOOT, this.boot, this); - sceneInputPlugin.pluginEvents.on(InputEvents.START, this.start, this); + return null; }, /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. + * Creates a new Canvas Texture object from an existing Canvas element + * and adds it to this Texture Manager, unless `skipCache` is true. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#boot - * @private - * @since 3.10.0 + * @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. */ - boot: function () + addCanvas: function (key, source, skipCache) { - var settings = this.settings.input; - - this.enabled = GetValue(settings, 'keyboard', true); + if (skipCache === undefined) { skipCache = false; } - var captures = GetValue(settings, 'keyboard.capture', null); + var texture = null; - if (captures) + if (skipCache) { - this.addCaptures(captures); + 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.sceneInputPlugin.pluginEvents.once(InputEvents.DESTROY, this.destroy, this); + this.list[key] = texture; + + this.emit(Events.ADD, key, texture); + this.emit(Events.ADD_KEY + key, texture); + } + + return texture; }, /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. + * Creates a Dynamic Texture instance and adds itself to this Texture Manager. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#start - * @private - * @since 3.10.0 + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. + * + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. + * + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. + * + * See the methods available on the `DynamicTexture` class for more details. + * + * Optionally, you can also pass a Dynamic Texture instance to this method to have + * it added to the Texture Manager. + * + * @method Phaser.Textures.TextureManager#addDynamicTexture + * @fires Phaser.Textures.Events#ADD + * @since 3.60.0 + * + * @param {(string|Phaser.Textures.DynamicTexture)} key - The string-based key of this Texture. Must be unique within the Texture Manager. Or, a DynamicTexture instance. + * @param {number} [width=256] - The width of this Dynamic Texture in pixels. Defaults to 256 x 256. Ignored if an instance is passed as the key. + * @param {number} [height=256] - The height of this Dynamic Texture in pixels. Defaults to 256 x 256. Ignored if an instance is passed as the key. + * + * @return {?Phaser.Textures.DynamicTexture} The Dynamic Texture that was created, or `null` if the key is already in use. */ - start: function () + addDynamicTexture: function (key, width, height) { - this.sceneInputPlugin.manager.events.on(InputEvents.MANAGER_PROCESS, this.update, this); + var texture = null; - this.sceneInputPlugin.pluginEvents.once(InputEvents.SHUTDOWN, this.shutdown, this); + if (typeof(key) === 'string' && !this.exists(key)) + { + texture = new DynamicTexture(this, key, width, height); + } + else + { + texture = key; + key = texture.key; + } - this.game.events.on(GameEvents.BLUR, this.resetKeys, this); + if (this.checkKey(key)) + { + this.list[key] = texture; - this.scene.sys.events.on(SceneEvents.PAUSE, this.resetKeys, this); - this.scene.sys.events.on(SceneEvents.SLEEP, this.resetKeys, this); + this.emit(Events.ADD, key, texture); + this.emit(Events.ADD_KEY + key, texture); + } + else + { + texture = null; + } + + return texture; }, /** - * Checks to see if both this plugin and the Scene to which it belongs is active. + * Adds a Texture Atlas to this Texture Manager. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#isActive - * @since 3.10.0 + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file, + * such as those exported by applications like Texture Packer. * - * @return {boolean} `true` if the plugin and the Scene it belongs to is active. + * It can accept either JSON Array or JSON Hash formats, as exported by Texture Packer and similar software. + * + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. + * + * @method Phaser.Textures.TextureManager#addAtlas + * @since 3.0.0 + * + * @param {string} key - The unique string-based key of the Texture. + * @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element/s, or a Phaser Texture. + * @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. */ - isActive: function () + addAtlas: function (key, source, data, dataSource) { - return (this.enabled && this.scene.sys.isActive()); + // 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); + } }, /** - * 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. + * Adds a Texture Atlas to this Texture Manager. * - * This `addCapture` method enables consuming keyboard events for specific keys, so they don't bubble up the browser - * and cause the default behaviors. + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file, + * such as those exported by applications like Texture Packer. * - * 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. + * The frame data of the atlas must be stored in an Array within the JSON. * - * You can pass a single key code value: + * This is known as a JSON Array in software such as Texture Packer. * - * ```javascript - * this.input.keyboard.addCapture(62); - * ``` + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. * - * An array of key codes: + * @method Phaser.Textures.TextureManager#addAtlasJSONArray + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 * - * ```javascript - * this.input.keyboard.addCapture([ 62, 63, 64 ]); - * ``` + * @param {string} key - The unique string-based key of the Texture. + * @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element/s, or a Phaser Texture. + * @param {(object|object[])} data - The Texture Atlas data/s. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. * - * Or, a comma-delimited string: + * @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 (source instanceof Texture) + { + key = texture.key; + texture = source; + } + else if (this.checkKey(key)) + { + texture = this.create(key, source); + } + + if (texture) + { + // 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); + this.emit(Events.ADD_KEY + key, texture); + } + + return texture; + }, + + /** + * Adds a Texture Atlas to this Texture Manager. * - * ```javascript - * this.input.keyboard.addCapture('W,S,A,D'); - * ``` + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file, + * such as those exported by applications like Texture Packer. * - * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. + * The frame data of the atlas must be stored in an Object within the JSON. * - * You can also provide an array mixing both strings and key code integers. + * This is known as a JSON Hash in software such as Texture Packer. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#addCapture - * @since 3.16.0 + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. * - * @param {(string|number|number[]|any[])} keycode - The Key Codes to enable event capture for. + * @method Phaser.Textures.TextureManager#addAtlasJSONHash + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 * - * @return {this} This KeyboardPlugin object. + * @param {string} key - The unique string-based key of the Texture. + * @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element/s, or a Phaser Texture. + * @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. */ - addCapture: function (keycode) + addAtlasJSONHash: function (key, source, data, dataSource) { - this.manager.addCapture(keycode); + var texture = null; - return this; + if (source instanceof Texture) + { + key = texture.key; + texture = source; + } + else if (this.checkKey(key)) + { + texture = this.create(key, source); + } + + if (texture) + { + 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); + this.emit(Events.ADD_KEY + key, texture); + } + + return texture; }, /** - * Removes an existing key capture. + * Adds a Texture Atlas to this Texture Manager. * - * 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. + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a data file, + * such as those exported by applications like Texture Packer. * - * You can pass a single key code value: + * The frame data of the atlas must be stored in an XML file. * - * ```javascript - * this.input.keyboard.removeCapture(62); - * ``` + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. * - * An array of key codes: + * @method Phaser.Textures.TextureManager#addAtlasXML + * @fires Phaser.Textures.Events#ADD + * @since 3.7.0 * - * ```javascript - * this.input.keyboard.removeCapture([ 62, 63, 64 ]); - * ``` + * @param {string} key - The unique string-based key of the Texture. + * @param {(HTMLImageElement|Phaser.Textures.Texture)} source - The source Image element, or a Phaser Texture. + * @param {object} data - The Texture Atlas XML data. + * @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element. * - * Or, a comma-delimited string: + * @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 (source instanceof Texture) + { + key = texture.key; + texture = source; + } + else if (this.checkKey(key)) + { + texture = this.create(key, source); + } + + if (texture) + { + Parser.AtlasXML(texture, 0, data); + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + this.emit(Events.ADD_KEY + key, texture); + } + + return texture; + }, + + /** + * Adds a Unity Texture Atlas to this Texture Manager. * - * ```javascript - * this.input.keyboard.removeCapture('W,S,A,D'); - * ``` + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a data file, + * such as those exported by applications like Texture Packer or Unity. * - * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. + * The frame data of the atlas must be stored in a Unity YAML file. * - * You can also provide an array mixing both strings and key code integers. + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#removeCapture - * @since 3.16.0 + * @method Phaser.Textures.TextureManager#addUnityAtlas + * @fires Phaser.Textures.Events#ADD + * @since 3.0.0 * - * @param {(string|number|number[]|any[])} keycode - The Key Codes to disable event capture for. + * @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 {this} This KeyboardPlugin object. + * @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use. */ - removeCapture: function (keycode) + addUnityAtlas: function (key, source, data, dataSource) { - this.manager.removeCapture(keycode); + var texture = null; - return this; + if (source instanceof Texture) + { + key = texture.key; + texture = source; + } + else if (this.checkKey(key)) + { + texture = this.create(key, source); + } + + if (texture) + { + Parser.UnityYAML(texture, 0, data); + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + this.emit(Events.ADD_KEY + key, texture); + } + + return texture; }, /** - * Returns an array that contains all of the keyboard captures currently enabled. + * Adds a Sprite Sheet to this Texture Manager. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#getCaptures - * @since 3.16.0 + * 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. This is different to a Texture Atlas, created by tools such as + * Texture Packer, and more akin with the fixed-frame exports you get from apps like Aseprite or old arcade + * games. * - * @return {number[]} An array of all the currently capturing key codes. + * As of Phaser 3.60 you can use this method to add a sprite sheet to an existing Phaser Texture. + * + * @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. Give an empty string if you provide a Phaser Texture as the 2nd argument. + * @param {(HTMLImageElement|Phaser.Textures.Texture)} source - The source Image element, or a Phaser Texture. + * @param {Phaser.Types.Textures.SpriteSheetConfig} config - The configuration object for this Sprite Sheet. + * @param {HTMLImageElement|HTMLCanvasElement} [dataSource] - An optional data Image element. + * + * @return {?Phaser.Textures.Texture} The Texture that was created or updated, or `null` if the key is already in use. */ - getCaptures: function () + addSpriteSheet: function (key, source, config, dataSource) { - return this.manager.captures; + var texture = null; + + if (source instanceof Texture) + { + key = texture.key; + texture = source; + } + else if (this.checkKey(key)) + { + texture = this.create(key, source); + } + + if (texture) + { + var width = texture.source[0].width; + var height = texture.source[0].height; + + Parser.SpriteSheet(texture, 0, 0, 0, width, height, config); + + if (dataSource) + { + texture.setDataSource(dataSource); + } + + this.emit(Events.ADD, key, texture); + this.emit(Events.ADD_KEY + key, texture); + } + + return texture; }, /** - * Allows Phaser to prevent any key captures you may have defined from bubbling up the browser. - * You can use this to re-enable event capturing if you had paused it via `disableGlobalCapture`. + * Adds a Sprite Sheet to this Texture Manager, where the Sprite Sheet exists as a Frame within a Texture Atlas. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#enableGlobalCapture - * @since 3.16.0 + * 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. * - * @return {this} This KeyboardPlugin object. + * @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. */ - enableGlobalCapture: function () + addSpriteSheetFromAtlas: function (key, config) { - this.manager.preventDefault = true; + if (!this.checkKey(key)) + { + return null; + } - return this; + 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); + this.emit(Events.ADD_KEY + key, texture); + + return texture; + } }, /** - * Disables Phaser from preventing any key captures you may have defined, without actually removing them. - * You can use this to temporarily disable event capturing if, for example, you swap to a DOM element. + * Creates a new Texture using the given source and dimensions. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#disableGlobalCapture - * @since 3.16.0 + * @method Phaser.Textures.TextureManager#create + * @since 3.0.0 * - * @return {this} This KeyboardPlugin object. + * @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. */ - disableGlobalCapture: function () + create: function (key, source, width, height) { - this.manager.preventDefault = false; + var texture = null; - return this; + if (this.checkKey(key)) + { + texture = new Texture(this, key, source, width, height); + + this.list[key] = texture; + } + + return texture; }, /** - * Removes all keyboard captures. + * Checks the given key to see if a Texture using it exists within this Texture Manager. * - * Note that this is a global change. It will clear all event captures across your game, not just for this specific Scene. + * @method Phaser.Textures.TextureManager#exists + * @since 3.0.0 * - * @method Phaser.Input.Keyboard.KeyboardPlugin#clearCaptures - * @since 3.16.0 + * @param {string} key - The unique string-based key of the Texture. * - * @return {this} This KeyboardPlugin object. + * @return {boolean} Returns `true` if a Texture matching the given key exists in this Texture Manager. */ - clearCaptures: function () + exists: function (key) { - this.manager.clearCaptures(); - - return this; + return (this.list.hasOwnProperty(key)); }, /** - * Creates and returns an object containing 4 hotkeys for Up, Down, Left and Right, and also Space Bar and shift. + * Returns a Texture from the Texture Manager that matches the given key. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#createCursorKeys - * @since 3.10.0 + * If the key is `undefined` it will return the `__DEFAULT` Texture. * - * @return {Phaser.Types.Input.Keyboard.CursorKeys} An object containing the properties: `up`, `down`, `left`, `right`, `space` and `shift`. + * If the key is an instance of a Texture, it will return the instance. + * + * If the key is an instance of a Frame, it will return the frames parent Texture instance. + * + * Finally, if the key is given, but not found, and not a Texture or Frame instance, it will return the `__MISSING` Texture. + * + * @method Phaser.Textures.TextureManager#get + * @since 3.0.0 + * + * @param {(string|Phaser.Textures.Texture|Phaser.Textures.Frame)} key - The unique string-based key of the Texture, or a Texture, or Frame instance. + * + * @return {Phaser.Textures.Texture} The Texture matching the given key. */ - createCursorKeys: function () + get: function (key) { - return this.addKeys({ - up: KeyCodes.UP, - down: KeyCodes.DOWN, - left: KeyCodes.LEFT, - right: KeyCodes.RIGHT, - space: KeyCodes.SPACE, - shift: KeyCodes.SHIFT - }); + if (key === undefined) { key = '__DEFAULT'; } + + if (this.list[key]) + { + return this.list[key]; + } + else if (key instanceof Texture) + { + return key; + } + else if (key instanceof Frame) + { + return key.texture; + } + 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(); + } }, /** - * A practical way to create an object containing user selected hotkeys. - * - * For example: - * - * ```javascript - * this.input.keyboard.addKeys({ 'up': Phaser.Input.Keyboard.KeyCodes.W, 'down': Phaser.Input.Keyboard.KeyCodes.S }); - * ``` + * Takes a Texture key and Frame name and returns a reference to that Frame, if found. * - * would return an object containing the properties (`up` and `down`) mapped to W and S {@link Phaser.Input.Keyboard.Key} objects. + * @method Phaser.Textures.TextureManager#getFrame + * @since 3.0.0 * - * You can also pass in a comma-separated string: + * @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. * - * ```javascript - * this.input.keyboard.addKeys('W,S,A,D'); - * ``` + * @return {Phaser.Textures.Frame} A Texture Frame object. + */ + getFrame: function (key, frame) + { + if (this.list[key]) + { + return this.list[key].get(frame); + } + }, + + /** + * Parses the 'key' parameter and returns a Texture Frame instance. * - * Which will return an object with the properties W, S, A and D mapped to the relevant Key objects. + * It can accept the following formats: * - * To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'. + * 1) A string + * 2) An array where the elements are: [ key, [frame] ] + * 3) An object with the properties: { key, [frame] } + * 4) A Texture instance - which returns the default frame from the Texture + * 5) A Frame instance - returns itself * - * @method Phaser.Input.Keyboard.KeyboardPlugin#addKeys - * @since 3.10.0 + * @method Phaser.Textures.TextureManager#parseFrame + * @since 3.60.0 * - * @param {(object|string)} keys - An object containing Key Codes, or a comma-separated string. - * @param {boolean} [enableCapture=true] - Automatically call `preventDefault` on the native DOM browser event for the key codes being added. - * @param {boolean} [emitOnRepeat=false] - Controls if the Key will continuously emit a 'down' event while being held down (true), or emit the event just once (false, the default). + * @param {(string|array|object|Phaser.Textures.Texture|Phaser.Textures.Frame)} key - The key to be parsed. * - * @return {object} An object containing Key objects mapped to the input properties. + * @return {Phaser.Textures.Frame} A Texture Frame object, if found, or undefined if not. */ - addKeys: function (keys, enableCapture, emitOnRepeat) + parseFrame: function (key) { - if (enableCapture === undefined) { enableCapture = true; } - if (emitOnRepeat === undefined) { emitOnRepeat = false; } - - var output = {}; - - if (typeof keys === 'string') + if (!key) { - keys = keys.split(','); + return undefined; + } + else if (typeof key === 'string') + { + return this.getFrame(key); + } + else if (Array.isArray(key) && key.length === 2) + { + return this.getFrame(key[0], key[1]); + } + else if (IsPlainObject(key)) + { + return this.getFrame(key.key, key.frame); + } + else if (key instanceof Texture) + { + return key.get(); + } + else if (key instanceof Frame) + { + return key; + } + }, - for (var i = 0; i < keys.length; i++) - { - var currentKey = keys[i].trim(); + /** + * Returns an array with all of the keys of all Textures in this Texture Manager. + * The output array will exclude the `__DEFAULT`, `__MISSING`, and `__WHITE` 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 = []; - if (currentKey) - { - output[currentKey] = this.addKey(currentKey, enableCapture, emitOnRepeat); - } - } - } - else + for (var key in this.list) { - for (var key in keys) + if (key !== '__DEFAULT' && key !== '__MISSING' && key !== '__WHITE') { - output[key] = this.addKey(keys[key], enableCapture, emitOnRepeat); + output.push(key); } } @@ -189048,17778 +212110,17890 @@ var KeyboardPlugin = new Class({ }, /** - * Adds a Key object to this Keyboard Plugin. - * - * The given argument can be either an existing Key object, a string, such as `A` or `SPACE`, or a key code value. - * - * If a Key object is given, and one already exists matching the same key code, the existing one is replaced with the new one. + * 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.Input.Keyboard.KeyboardPlugin#addKey - * @since 3.10.0 + * @method Phaser.Textures.TextureManager#getPixel + * @since 3.0.0 * - * @param {(Phaser.Input.Keyboard.Key|string|number)} key - Either a Key object, a string, such as `A` or `SPACE`, or a key code value. - * @param {boolean} [enableCapture=true] - Automatically call `preventDefault` on the native DOM browser event for the key codes being added. - * @param {boolean} [emitOnRepeat=false] - Controls if the Key will continuously emit a 'down' event while being held down (true), or emit the event just once (false, the default). + * @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.Input.Keyboard.Key} The newly created Key object, or a reference to it if it already existed in the keys array. + * @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. */ - addKey: function (key, enableCapture, emitOnRepeat) + getPixel: function (x, y, key, frame) { - if (enableCapture === undefined) { enableCapture = true; } - if (emitOnRepeat === undefined) { emitOnRepeat = false; } - - var keys = this.keys; + var textureFrame = this.getFrame(key, frame); - if (key instanceof Key) + if (textureFrame) { - var idx = keys.indexOf(key); - - if (idx > -1) - { - keys[idx] = key; - } - else - { - keys[key.keyCode] = key; - } + // Adjust for trim (if not trimmed x and y are just zero) + x -= textureFrame.x; + y -= textureFrame.y; - if (enableCapture) - { - this.addCapture(key.keyCode); - } + var data = textureFrame.data.cut; - key.setEmitOnRepeat(emitOnRepeat); + x += data.x; + y += data.y; - return key; - } + if (x >= data.x && x < data.r && y >= data.y && y < data.b) + { + var ctx = this._tempContext; - if (typeof key === 'string') - { - key = KeyCodes[key.toUpperCase()]; - } + ctx.clearRect(0, 0, 1, 1); + ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); - if (!keys[key]) - { - keys[key] = new Key(this, key); + var rgb = ctx.getImageData(0, 0, 1, 1); - if (enableCapture) - { - this.addCapture(key); + return new Color(rgb.data[0], rgb.data[1], rgb.data[2], rgb.data[3]); } - - keys[key].setEmitOnRepeat(emitOnRepeat); } - return keys[key]; + return null; }, /** - * Removes a Key object from this Keyboard Plugin. - * - * The given argument can be either a Key object, a string, such as `A` or `SPACE`, or a key code value. + * 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.Input.Keyboard.KeyboardPlugin#removeKey + * @method Phaser.Textures.TextureManager#getPixelAlpha * @since 3.10.0 * - * @param {(Phaser.Input.Keyboard.Key|string|number)} key - Either a Key object, a string, such as `A` or `SPACE`, or a key code value. - * @param {boolean} [destroy=false] - Call `Key.destroy` on the removed Key object? + * @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 {this} This KeyboardPlugin object. + * @return {number} A value between 0 and 255, or `null` if the coordinates were out of bounds. */ - removeKey: function (key, destroy) + getPixelAlpha: function (x, y, key, frame) { - if (destroy === undefined) { destroy = false; } - - var keys = this.keys; - var ref; + var textureFrame = this.getFrame(key, frame); - if (key instanceof Key) + if (textureFrame) { - var idx = keys.indexOf(key); + // Adjust for trim (if not trimmed x and y are just zero) + x -= textureFrame.x; + y -= textureFrame.y; - if (idx > -1) - { - ref = this.keys[idx]; + var data = textureFrame.data.cut; - this.keys[idx] = undefined; - } - } - else if (typeof key === 'string') - { - key = KeyCodes[key.toUpperCase()]; - } + x += data.x; + y += data.y; - if (keys[key]) - { - ref = keys[key]; + if (x >= data.x && x < data.r && y >= data.y && y < data.b) + { + var ctx = this._tempContext; - keys[key] = undefined; - } + ctx.clearRect(0, 0, 1, 1); + ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1); - if (ref) - { - ref.plugin = null; + var rgb = ctx.getImageData(0, 0, 1, 1); - if (destroy) - { - ref.destroy(); + return rgb.data[3]; } } - return this; + return null; }, /** - * Removes all Key objects created by _this_ Keyboard Plugin. + * 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.Input.Keyboard.KeyboardPlugin#removeAllKeys - * @since 3.24.0 + * @method Phaser.Textures.TextureManager#setTexture + * @since 3.0.0 * - * @param {boolean} [destroy=false] - Call `Key.destroy` on each removed Key object? + * @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 {this} This KeyboardPlugin object. + * @return {Phaser.GameObjects.GameObject} The Game Object the texture was set on. */ - removeAllKeys: function (destroy) + setTexture: function (gameObject, key, frame) { - var keys = this.keys; - - for (var i = 0; i < keys.length; i++) + if (this.list[key]) { - var key = keys[i]; - - if (key) - { - keys[i] = undefined; - - if (destroy) - { - key.destroy(); - } - } + gameObject.texture = this.list[key]; + gameObject.frame = gameObject.texture.get(frame); } - return this; + return gameObject; }, /** - * Creates a new KeyCombo. - * - * 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 this Keyboard Plugin. - * - * 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!'); - * }); - * ``` + * Changes the key being used by a Texture to the new key provided. * - * Or, to listen for the user entering the word PHASER: + * The old key is removed, allowing it to be re-used. * - * ```javascript - * this.input.keyboard.createCombo('PHASER'); - * ``` + * Game Objects are linked to Textures by a reference to the Texture object, so + * all existing references will be retained. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#createCombo - * @since 3.10.0 + * @method Phaser.Textures.TextureManager#renameTexture + * @since 3.12.0 * - * @param {(string|number[]|object[])} keys - The keys that comprise this combo. - * @param {Phaser.Types.Input.Keyboard.KeyComboConfig} [config] - A Key Combo configuration object. + * @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 {Phaser.Input.Keyboard.KeyCombo} The new KeyCombo object. + * @return {boolean} `true` if the Texture key was successfully renamed, otherwise `false`. */ - createCombo: function (keys, config) + renameTexture: function (currentKey, newKey) { - return new KeyCombo(this, keys, config); + var texture = this.get(currentKey); + + if (texture && currentKey !== newKey) + { + texture.key = newKey; + + this.list[newKey] = texture; + + delete this.list[currentKey]; + + return true; + } + + return false; }, /** - * Checks if the given Key object is currently being held down. - * - * The difference between this method and checking the `Key.isDown` property directly is that you can provide - * a duration to this method. For example, if you wanted a key press to fire a bullet, but you only wanted - * it to be able to fire every 100ms, then you can call this method with a `duration` of 100 and it - * will only return `true` every 100ms. - * - * If the Keyboard Plugin has been disabled, this method will always return `false`. - * - * @method Phaser.Input.Keyboard.KeyboardPlugin#checkDown - * @since 3.11.0 + * Passes all Textures to the given callback. * - * @param {Phaser.Input.Keyboard.Key} key - A Key object. - * @param {number} [duration=0] - The duration which must have elapsed before this Key is considered as being down. + * @method Phaser.Textures.TextureManager#each + * @since 3.0.0 * - * @return {boolean} `true` if the Key is down within the duration specified, otherwise `false`. + * @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. */ - checkDown: function (key, duration) + each: function (callback, scope) { - if (duration === undefined) { duration = 0; } + var args = [ null ]; - if (this.enabled && key.isDown) + for (var i = 1; i < arguments.length; i++) { - var t = SnapFloor(this.time - key.timeDown, duration); + args.push(arguments[i]); + } - if (t > key._tick) - { - key._tick = t; + for (var texture in this.list) + { + args[0] = this.list[texture]; - return true; - } + callback.apply(scope, args); } - - return false; }, /** - * Internal update handler called by the Input Plugin, which is in turn invoked by the Game step. + * Resets the internal Stamp object, ready for drawing and returns it. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#update - * @private - * @since 3.10.0 + * @method Phaser.Textures.TextureManager#resetStamp + * @since 3.60.0 + * + * @param {number} [alpha=1] - The alpha to use. + * @param {number} [tint=0xffffff] - WebGL only. The tint color to use. + * + * @return {Phaser.GameObjects.Image} A reference to the Stamp Game Object. */ - update: function () + resetStamp: function (alpha, tint) { - var queue = this.manager.queue; - var len = queue.length; + if (alpha === undefined) { alpha = 1; } + if (tint === undefined) { tint = 0xffffff; } - if (!this.isActive() || len === 0) + var stamp = this.stamp; + + stamp.setCrop(); + stamp.setPosition(0); + stamp.setAngle(0); + stamp.setScale(1); + stamp.setAlpha(alpha); + stamp.setTint(tint); + + return stamp; + }, + + /** + * 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) { - return; + this.list[texture].destroy(); } - var keys = this.keys; + this.list = {}; - // Process the event queue, dispatching all of the events that have stored up - for (var i = 0; i < len; i++) - { - var event = queue[i]; - var code = event.keyCode; - var key = keys[code]; - var repeat = false; + this.stamp.destroy(); - // Override the default functions (it's too late for the browser to use them anyway, so we may as well) - if (event.cancelled === undefined) - { - // Event allowed to flow across all handlers in this Scene, and any other Scene in the Scene list - event.cancelled = 0; + this.game = null; + this.stamp = null; - // Won't reach any more local (Scene level) handlers - event.stopImmediatePropagation = function () - { - event.cancelled = 1; - }; + CanvasPool.remove(this._tempCanvas); + } - // Won't reach any more handlers in any Scene further down the Scene list - event.stopPropagation = function () - { - event.cancelled = -1; - }; - } +}); - if (event.cancelled === -1) - { - // This event has been stopped from broadcasting to any other Scene, so abort. - continue; - } +module.exports = TextureManager; - // Duplicate event bailout - if (code === this.prevCode && event.timeStamp === this.prevTime && event.type === this.prevType) - { - // On some systems, the exact same event will fire multiple times. This prevents it. - continue; - } - this.prevCode = code; - this.prevTime = event.timeStamp; - this.prevType = event.type; +/***/ }), - if (event.type === 'keydown') +/***/ 32547: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CanvasPool = __webpack_require__(61068); +var Class = __webpack_require__(56694); +var IsSizePowerOfTwo = __webpack_require__(28621); +var ScaleModes = __webpack_require__(27394); + +/** + * @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|Phaser.Types.Textures.CompressedTextureData|Phaser.Textures.DynamicTexture)} 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; + + /** + * A reference to the Canvas or WebGL Renderer. + * + * @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 instance 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. + * + * In Phaser 3.60 and above it can also be a Compressed Texture data object. + * + * @name Phaser.Textures.TextureSource#source + * @type {(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement|Phaser.GameObjects.RenderTexture|WebGLTexture|Phaser.Types.Textures.CompressedTextureData|Phaser.Textures.DynamicTexture)} + * @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.compressed) ? null : source; + + /** + * Holds the compressed textured algorithm, or `null` if it's not a compressed texture. + * + * Prior to Phaser 3.60 this value always held `null`. + * + * @name Phaser.Textures.TextureSource#compressionAlgorithm + * @type {number} + * @default null + * @since 3.0.0 + */ + this.compressionAlgorithm = (source.compressed) ? source.format : 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' || source.type === 'DynamicTexture'); + + /** + * 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; + + /** + * 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) + { + var source = this.source; + + if (renderer.gl) { - // Key specific callback first - if (key) - { - repeat = key.isDown; + var image = this.image; + var flipY = this.flipY; + var width = this.width; + var height = this.height; + var scaleMode = this.scaleMode; - key.onDown(event); + if (this.isCanvas) + { + this.glTexture = renderer.createCanvasTexture(image, false, flipY); } - - if (!event.cancelled && (!key || !repeat)) + else if (this.isVideo) { - if (KeyMap[code]) - { - this.emit(Events.KEY_DOWN + KeyMap[code], event); - } - - if (!event.cancelled) - { - this.emit(Events.ANY_KEY_DOWN, event); - } + this.glTexture = renderer.createVideoTexture(image, false, flipY); } - } - else - { - // Key specific callback first - if (key) + else if (this.isRenderTexture) { - key.onUp(event); + this.glTexture = renderer.createTextureFromSource(null, width, height, scaleMode); } - - if (!event.cancelled) + else if (this.isGLTexture) { - if (KeyMap[code]) - { - this.emit(Events.KEY_UP + KeyMap[code], event); - } - - if (!event.cancelled) - { - this.emit(Events.ANY_KEY_UP, event); - } + this.glTexture = source; + } + else if (this.compressionAlgorithm) + { + this.glTexture = renderer.createTextureFromSource(source); + } + else + { + this.glTexture = renderer.createTextureFromSource(image, width, height, scaleMode); } - } - // Reset the cancel state for other Scenes to use - if (event.cancelled === 1) + if (false) + {} + } + else if (this.isRenderTexture) { - event.cancelled = 0; + this.image = source.canvas; } } + + if (!game.config.antialias) + { + this.setFilter(1); + } }, /** - * Resets all Key objects created by _this_ Keyboard Plugin back to their default un-pressed states. - * This can only reset keys created via the `addKey`, `addKeys` or `createCursorKeys` methods. - * If you have created a Key object directly you'll need to reset it yourself. + * Sets the Filter Mode for this Texture. * - * This method is called automatically when the Keyboard Plugin shuts down, but can be - * invoked directly at any time you require. + * The mode can be either Linear, the default, or Nearest. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#resetKeys - * @since 3.15.0 + * For pixel-art you should use Nearest. * - * @return {this} This KeyboardPlugin object. + * @method Phaser.Textures.TextureSource#setFilter + * @since 3.0.0 + * + * @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode. */ - resetKeys: function () + setFilter: function (filterMode) { - var keys = this.keys; - - for (var i = 0; i < keys.length; i++) + if (this.renderer.gl) { - // Because it's a sparsely populated array - if (keys[i]) - { - keys[i].reset(); - } + this.renderer.setTextureFilter(this.glTexture, filterMode); } - return this; + this.scaleMode = filterMode; }, /** - * Shuts this Keyboard Plugin down. This performs the following tasks: + * Sets the `UNPACK_FLIP_Y_WEBGL` flag for the WebGL Texture during texture upload. * - * 1 - Removes all keys created by this Keyboard plugin. - * 2 - Stops and removes the keyboard event listeners. - * 3 - Clears out any pending requests in the queue, without processing them. + * @method Phaser.Textures.TextureSource#setFlipY + * @since 3.20.0 * - * @method Phaser.Input.Keyboard.KeyboardPlugin#shutdown - * @private - * @since 3.10.0 + * @param {boolean} [value=true] - Should the WebGL Texture be flipped on the Y axis on texture upload or not? */ - shutdown: function () + setFlipY: function (value) { - this.removeAllKeys(true); - this.removeAllListeners(); - - this.sceneInputPlugin.manager.events.off(InputEvents.MANAGER_PROCESS, this.update, this); - - this.game.events.off(GameEvents.BLUR, this.resetKeys); + if (value === undefined) { value = true; } - this.scene.sys.events.off(SceneEvents.PAUSE, this.resetKeys, this); - this.scene.sys.events.off(SceneEvents.SLEEP, this.resetKeys, this); + this.flipY = value; - this.queue = []; + return this; }, /** - * Destroys this Keyboard Plugin instance and all references it holds, plus clears out local arrays. + * If this TextureSource is backed by a Canvas and is running under WebGL, + * it updates the WebGLTexture using the canvas data. * - * @method Phaser.Input.Keyboard.KeyboardPlugin#destroy - * @private - * @since 3.10.0 + * @method Phaser.Textures.TextureSource#update + * @since 3.7.0 */ - destroy: function () + update: function () { - this.shutdown(); - - var keys = this.keys; + var renderer = this.renderer; + var image = this.image; + var flipY = this.flipY; + var gl = renderer.gl; - for (var i = 0; i < keys.length; i++) + if (gl && this.isCanvas) { - // Because it's a sparsely populated array - if (keys[i]) - { - keys[i].destroy(); - } + this.glTexture = renderer.updateCanvasTexture(image, this.glTexture, flipY); + } + else if (gl && this.isVideo) + { + this.glTexture = renderer.updateVideoTexture(image, this.glTexture, flipY); } - - this.keys = []; - this.combos = []; - this.queue = []; - - this.scene = null; - this.settings = null; - this.sceneInputPlugin = null; - this.manager = null; }, /** - * Internal time value. + * Destroys this Texture Source and nulls the references. * - * @name Phaser.Input.Keyboard.KeyboardPlugin#time - * @type {number} - * @private - * @since 3.11.0 + * @method Phaser.Textures.TextureSource#destroy + * @since 3.0.0 */ - time: { + destroy: function () + { + if (this.glTexture) + { + this.renderer.deleteTexture(this.glTexture, true); + } - get: function () + if (this.isCanvas) { - return this.sceneInputPlugin.manager.time; + CanvasPool.remove(this.image); } + this.renderer = null; + this.texture = null; + this.source = null; + this.image = null; + this.glTexture = null; } }); -/** - * An instance of the Keyboard Plugin class, if enabled via the `input.keyboard` Scene or Game Config property. - * Use this to create Key objects and listen for keyboard specific events. - * - * @name Phaser.Input.InputPlugin#keyboard - * @type {?Phaser.Input.Keyboard.KeyboardPlugin} - * @since 3.10.0 - */ -InputPluginCache.register('KeyboardPlugin', KeyboardPlugin, 'keyboard', 'keyboard', 'inputKeyboard'); - -module.exports = KeyboardPlugin; +module.exports = TextureSource; /***/ }), -/* 1331 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var KeyCodes = __webpack_require__(143); - -var KeyMap = {}; - -for (var key in KeyCodes) -{ - KeyMap[KeyCodes[key]] = key; -} - -module.exports = KeyMap; - -/***/ }), -/* 1332 */ -/***/ (function(module, exports) { +/***/ 65154: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The justDown value allows you to test if this Key has just been pressed down or not. - * - * When you check this value it will return `true` if the Key is down, otherwise `false`. - * - * You can only call justDown once per key press. It will only return `true` once, until the Key is released and pressed down again. - * This allows you to use it in situations where you want to check if this key is down without using an event, such as in a core game loop. + * Filter Types. * - * @function Phaser.Input.Keyboard.JustDown + * @namespace Phaser.Textures.FilterMode + * @memberof Phaser.Textures * @since 3.0.0 - * - * @param {Phaser.Input.Keyboard.Key} key - The Key to check to see if it's just down or not. - * - * @return {boolean} `true` if the Key was just pressed, otherwise `false`. */ -var JustDown = function (key) -{ - if (key._justDown) - { - key._justDown = false; +var CONST = { + + /** + * Linear filter type. + * + * @name Phaser.Textures.FilterMode.LINEAR + * @type {number} + * @const + * @since 3.0.0 + */ + LINEAR: 0, + + /** + * Nearest neighbor filter type. + * + * @name Phaser.Textures.FilterMode.NEAREST + * @type {number} + * @const + * @since 3.0.0 + */ + NEAREST: 1 - return true; - } - else - { - return false; - } }; -module.exports = JustDown; +module.exports = CONST; /***/ }), -/* 1333 */ -/***/ (function(module, exports) { + +/***/ 49644: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The justUp value allows you to test if this Key has just been released or not. - * - * When you check this value it will return `true` if the Key is up, otherwise `false`. - * - * You can only call JustUp once per key release. It will only return `true` once, until the Key is pressed down and released again. - * This allows you to use it in situations where you want to check if this key is up without using an event, such as in a core game loop. + * The Texture Add Event. * - * @function Phaser.Input.Keyboard.JustUp - * @since 3.0.0 + * This event is dispatched by the Texture Manager when a texture is added to it. * - * @param {Phaser.Input.Keyboard.Key} key - The Key to check to see if it's just up or not. + * Listen to this event from within a Scene using: `this.textures.on('addtexture', listener)`. * - * @return {boolean} `true` if the Key was just released, otherwise `false`. + * @event Phaser.Textures.Events#ADD + * @type {string} + * @since 3.0.0 + * + * @param {string} key - The key of the Texture that was added to the Texture Manager. + * @param {Phaser.Textures.Texture} texture - A reference to the Texture that was added to the Texture Manager. */ -var JustUp = function (key) -{ - if (key._justUp) - { - key._justUp = false; - - return true; - } - else - { - return false; - } -}; - -module.exports = JustUp; +module.exports = 'addtexture'; /***/ }), -/* 1334 */ -/***/ (function(module, exports) { + +/***/ 29569: +/***/ ((module) => { /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Returns `true` if the Key was pressed down within the `duration` value given, based on the current - * game clock time. Or `false` if it either isn't down, or was pressed down longer ago than the given duration. + * The Texture Add Key Event. * - * @function Phaser.Input.Keyboard.DownDuration - * @since 3.0.0 + * This event is dispatched by the Texture Manager when a texture with the given key is added to it. * - * @param {Phaser.Input.Keyboard.Key} key - The Key object to test. - * @param {number} [duration=50] - The duration, in ms, within which the key must have been pressed down. + * Listen to this event from within a Scene using: `this.textures.on('addtexture-key', listener)`. * - * @return {boolean} `true` if the Key was pressed down within `duration` ms ago, otherwise `false`. + * @event Phaser.Textures.Events#ADD_KEY + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.Textures.Texture} texture - A reference to the Texture that was added to the Texture Manager. */ -var DownDuration = function (key, duration) -{ - if (duration === undefined) { duration = 50; } - - var current = key.plugin.game.loop.time - key.timeDown; - - return (key.isDown && current < duration); -}; - -module.exports = DownDuration; +module.exports = 'addtexture-'; /***/ }), -/* 1335 */ -/***/ (function(module, exports) { + +/***/ 60079: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Returns `true` if the Key was released within the `duration` value given, based on the current - * game clock time. Or returns `false` if it either isn't up, or was released longer ago than the given duration. + * The Texture Load Error Event. * - * @function Phaser.Input.Keyboard.UpDuration - * @since 3.0.0 + * This event is dispatched by the Texture Manager when a texture it requested to load failed. + * This only happens when base64 encoded textures fail. All other texture types are loaded via the Loader Plugin. * - * @param {Phaser.Input.Keyboard.Key} key - The Key object to test. - * @param {number} [duration=50] - The duration, in ms, within which the key must have been released. + * Listen to this event from within a Scene using: `this.textures.on('onerror', listener)`. * - * @return {boolean} `true` if the Key was released within `duration` ms ago, otherwise `false`. + * @event Phaser.Textures.Events#ERROR + * @type {string} + * @since 3.0.0 + * + * @param {string} key - The key of the Texture that failed to load into the Texture Manager. */ -var UpDuration = function (key, duration) -{ - if (duration === undefined) { duration = 50; } - - var current = key.plugin.game.loop.time - key.timeUp; - - return (key.isUp && current < duration); -}; - -module.exports = UpDuration; +module.exports = 'onerror'; /***/ }), -/* 1336 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72665: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Input.Mouse + * The Texture Load Event. + * + * This event is dispatched by the Texture Manager when a texture has finished loading on it. + * This only happens for base64 encoded textures. All other texture types are loaded via the Loader Plugin. + * + * Listen to this event from within a Scene using: `this.textures.on('onload', listener)`. + * + * This event is dispatched after the [ADD]{@linkcode Phaser.Textures.Events#event:ADD} event. + * + * @event Phaser.Textures.Events#LOAD + * @type {string} + * @since 3.0.0 + * + * @param {string} key - The key of the Texture that was loaded by the Texture Manager. + * @param {Phaser.Textures.Texture} texture - A reference to the Texture that was loaded by the Texture Manager. */ - -/* eslint-disable */ -module.exports = { - - MouseManager: __webpack_require__(411) - -}; -/* eslint-enable */ +module.exports = 'onload'; /***/ }), -/* 1337 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 93006: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Input.Touch + * This internal event signifies that the Texture Manager is now ready and the Game can continue booting. + * + * When a Phaser Game instance is booting for the first time, the Texture Manager has to wait on a couple of non-blocking + * async events before it's fully ready to carry on. When those complete the Texture Manager emits this event via the Game + * instance, which tells the Game to carry on booting. + * + * @event Phaser.Textures.Events#READY + * @type {string} + * @since 3.16.1 */ - -/* eslint-disable */ -module.exports = { - - TouchManager: __webpack_require__(413) - -}; -/* eslint-enable */ +module.exports = 'ready'; /***/ }), -/* 1338 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 69018: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(21); -var Extend = __webpack_require__(17); - /** - * @namespace Phaser.Loader + * The Texture Remove Event. + * + * This event is dispatched by the Texture Manager when a texture is removed from it. + * + * Listen to this event from within a Scene using: `this.textures.on('removetexture', listener)`. + * + * If you have any Game Objects still using the removed texture, they will start throwing + * errors the next time they try to render. Be sure to clear all use of the texture in this event handler. + * + * @event Phaser.Textures.Events#REMOVE + * @type {string} + * @since 3.0.0 + * + * @param {string} key - The key of the Texture that was removed from the Texture Manager. */ +module.exports = 'removetexture'; -var Loader = { - - Events: __webpack_require__(95), - - FileTypes: __webpack_require__(1339), - File: __webpack_require__(23), - FileTypesManager: __webpack_require__(8), - GetURL: __webpack_require__(155), - LoaderPlugin: __webpack_require__(1365), - MergeXHRSettings: __webpack_require__(240), - MultiFile: __webpack_require__(49), - XHRLoader: __webpack_require__(517), - XHRSettings: __webpack_require__(156) +/***/ }), -}; +/***/ 85549: +/***/ ((module) => { -// Merge in the consts -Loader = Extend(false, Loader, CONST); +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = Loader; +/** + * The Texture Remove Key Event. + * + * This event is dispatched by the Texture Manager when a texture with the given key is removed from it. + * + * Listen to this event from within a Scene using: `this.textures.on('removetexture-key', listener)`. + * + * If you have any Game Objects still using the removed texture, they will start throwing + * errors the next time they try to render. Be sure to clear all use of the texture in this event handler. + * + * @event Phaser.Textures.Events#REMOVE_KEY + * @type {string} + * @since 3.60.0 + */ +module.exports = 'removetexture-'; /***/ }), -/* 1339 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 38203: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Loader.FileTypes + * @namespace Phaser.Textures.Events */ module.exports = { - AnimationJSONFile: __webpack_require__(1340), - AsepriteFile: __webpack_require__(1341), - AtlasJSONFile: __webpack_require__(1342), - AtlasXMLFile: __webpack_require__(1343), - AudioFile: __webpack_require__(518), - AudioSpriteFile: __webpack_require__(1344), - BinaryFile: __webpack_require__(1345), - BitmapFontFile: __webpack_require__(1346), - CSSFile: __webpack_require__(1347), - GLSLFile: __webpack_require__(1348), - HTML5AudioFile: __webpack_require__(519), - HTMLFile: __webpack_require__(1349), - HTMLTextureFile: __webpack_require__(1350), - ImageFile: __webpack_require__(71), - JSONFile: __webpack_require__(61), - MultiAtlasFile: __webpack_require__(1351), - MultiScriptFile: __webpack_require__(1352), - OBJFile: __webpack_require__(1353), - PackFile: __webpack_require__(1354), - PluginFile: __webpack_require__(1355), - SceneFile: __webpack_require__(1356), - ScenePluginFile: __webpack_require__(1357), - ScriptFile: __webpack_require__(520), - SpriteSheetFile: __webpack_require__(1358), - SVGFile: __webpack_require__(1359), - TextFile: __webpack_require__(242), - TilemapCSVFile: __webpack_require__(1360), - TilemapImpactFile: __webpack_require__(1361), - TilemapJSONFile: __webpack_require__(1362), - UnityAtlasFile: __webpack_require__(1363), - VideoFile: __webpack_require__(1364), - XMLFile: __webpack_require__(241) + ADD: __webpack_require__(49644), + ADD_KEY: __webpack_require__(29569), + ERROR: __webpack_require__(60079), + LOAD: __webpack_require__(72665), + READY: __webpack_require__(93006), + REMOVE: __webpack_require__(69018), + REMOVE_KEY: __webpack_require__(85549) }; /***/ }), -/* 1340 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 87499: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(61); -var LoaderEvents = __webpack_require__(95); +var Extend = __webpack_require__(98611); +var FilterMode = __webpack_require__(65154); /** - * @classdesc - * A single Animation JSON File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#animation method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#animation. + * @namespace Phaser.Textures + */ + +/** + * Linear filter type. * - * @class AnimationJSONFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor + * @name Phaser.Textures.LINEAR + * @type {number} + * @const * @since 3.0.0 + */ + +/** + * Nearest Neighbor filter type. * - * @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 {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". - * @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. + * @name Phaser.Textures.NEAREST + * @type {number} + * @const + * @since 3.0.0 */ -var AnimationJSONFile = new Class({ - Extends: JSONFile, +var Textures = { - initialize: + CanvasTexture: __webpack_require__(17487), + DynamicTexture: __webpack_require__(845), + Events: __webpack_require__(38203), + FilterMode: FilterMode, + Frame: __webpack_require__(82047), + Parsers: __webpack_require__(69150), + Texture: __webpack_require__(31673), + TextureManager: __webpack_require__(6237), + TextureSource: __webpack_require__(32547) - // 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 AnimationJSONFile (loader, key, url, xhrSettings, dataKey) - { - JSONFile.call(this, loader, key, url, xhrSettings, dataKey); +Textures = Extend(false, Textures, FilterMode); - this.type = 'animationJSON'; - }, +module.exports = Textures; - /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. - * - * @method Phaser.Loader.FileTypes.AnimationJSONFile#onProcess - * @since 3.7.0 - */ - onProcess: function () - { - // We need to hook into this event: - this.loader.once(LoaderEvents.POST_PROCESS, this.onLoadComplete, this); - // But the rest is the same as a normal JSON file - JSONFile.prototype.onProcess.call(this); - }, +/***/ }), - /** - * Called at the end of the load process, after the Loader has finished all files in its queue. - * - * @method Phaser.Loader.FileTypes.AnimationJSONFile#onLoadComplete - * @since 3.7.0 - */ - onLoadComplete: function () - { - this.loader.systems.anims.fromJSON(this.data); - } +/***/ 35082: +/***/ ((module) => { -}); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ /** - * Adds an Animation JSON Data file, or array of Animation 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.animation('baddieAnims', 'files/BaddieAnims.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. - * - * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring - * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. - * - * 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.animation({ - * key: 'baddieAnims', - * url: 'files/BaddieAnims.json' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.JSONFileConfig` for more details. - * - * Once the file has finished loading it will automatically be passed to the global Animation Managers `fromJSON` method. - * This will parse all of the JSON data and create animation data from it. This process happens at the very end - * of the Loader, once every other file in the load queue has finished. The reason for this is to allow you to load - * both animation data and the images it relies upon in the same load call. - * - * Once the animation data has been parsed you will be able to play animations using that data. - * Please see the Animation Manager `fromJSON` method for more details about the format and playback. - * - * You can also access the raw animation data from its Cache using its key: - * - * ```javascript - * this.load.animation('baddieAnims', 'files/BaddieAnims.json'); - * // and later in your game ... - * var data = this.cache.json.get('baddieAnims'); - * ``` - * - * 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 if you only wanted to create animations from the `boss` data, 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. + * Parses an XML Texture Atlas object and adds all the Frames into a Texture. * - * @method Phaser.Loader.LoaderPlugin#animation - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 + * @function Phaser.Textures.Parsers.AtlasXML + * @memberof Phaser.Textures.Parsers + * @private + * @since 3.7.0 * - * @param {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig|Phaser.Types.Loader.FileTypes.JSONFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string} [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". - * @param {string} [dataKey] - When the Animation JSON file loads only this property will be stored in the Cache and used to create animation data. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. + * @param {number} sourceIndex - The index of the TextureSource. + * @param {*} xml - The XML data. * - * @return {this} The Loader instance. + * @return {Phaser.Textures.Texture} The Texture modified by this parser. */ -FileTypesManager.register('animation', function (key, url, dataKey, xhrSettings) +var AtlasXML = function (texture, sourceIndex, xml) { - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined + // Malformed? + if (!xml.getElementsByTagName('TextureAtlas')) + { + console.warn('Invalid Texture Atlas XML given'); + return; + } - if (Array.isArray(key)) + // Add in a __BASE entry (for the entire atlas) + var source = texture.source[sourceIndex]; + + texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); + + // By this stage frames is a fully parsed array + var frames = xml.getElementsByTagName('SubTexture'); + + var newFrame; + + for (var i = 0; i < frames.length; i++) { - for (var i = 0; i < key.length; i++) + var frame = frames[i].attributes; + + var name = frame.name.value; + var x = parseInt(frame.x.value, 10); + var y = parseInt(frame.y.value, 10); + var width = parseInt(frame.width.value, 10); + var height = parseInt(frame.height.value, 10); + + // The frame values are the exact coordinates to cut the frame out of the atlas from + newFrame = texture.add(name, sourceIndex, x, y, width, height); + + // These are the original (non-trimmed) sprite values + if (frame.frameX) { - this.addFile(new AnimationJSONFile(this, key[i])); + var frameX = Math.abs(parseInt(frame.frameX.value, 10)); + var frameY = Math.abs(parseInt(frame.frameY.value, 10)); + var frameWidth = parseInt(frame.frameWidth.value, 10); + var frameHeight = parseInt(frame.frameHeight.value, 10); + + newFrame.setTrim( + width, + height, + frameX, + frameY, + frameWidth, + frameHeight + ); } } - else - { - this.addFile(new AnimationJSONFile(this, key, url, xhrSettings, dataKey)); - } - return this; -}); + return texture; +}; -module.exports = AnimationJSONFile; +module.exports = AtlasXML; /***/ }), -/* 1341 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 83332: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(71); -var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(61); -var MultiFile = __webpack_require__(49); - /** - * @classdesc - * A single JSON based Texture Atlas File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#atlas method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#atlas. + * Adds a Canvas Element to a Texture. * - * https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?source=photonstorm + * @function Phaser.Textures.Parsers.Canvas + * @memberof Phaser.Textures.Parsers + * @private + * @since 3.0.0 * - * @class AsepriteFile - * @extends Phaser.Loader.MultiFile - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.50.0 + * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. + * @param {number} sourceIndex - The index of the TextureSource. * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.AsepriteFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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, a well formed JSON object. - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. + * @return {Phaser.Textures.Texture} The Texture modified by this parser. */ -var AsepriteFile = new Class({ - - Extends: MultiFile, - - initialize: - - function AsepriteFile (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) - { - var image; - var data; - - if (IsPlainObject(key)) - { - var config = key; - - key = GetFastValue(config, 'key'); - - image = new ImageFile(loader, { - key: key, - url: GetFastValue(config, 'textureURL'), - extension: GetFastValue(config, 'textureExtension', 'png'), - normalMap: GetFastValue(config, 'normalMap'), - xhrSettings: GetFastValue(config, 'textureXhrSettings') - }); +var Canvas = function (texture, sourceIndex) +{ + var source = texture.source[sourceIndex]; - data = new JSONFile(loader, { - key: key, - url: GetFastValue(config, 'atlasURL'), - extension: GetFastValue(config, 'atlasExtension', 'json'), - xhrSettings: GetFastValue(config, 'atlasXhrSettings') - }); - } - else - { - image = new ImageFile(loader, key, textureURL, textureXhrSettings); - data = new JSONFile(loader, key, atlasURL, atlasXhrSettings); - } + texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); - if (image.linkFile) - { - // Image has a normal map - MultiFile.call(this, loader, 'atlasjson', key, [ image, data, image.linkFile ]); - } - else - { - MultiFile.call(this, loader, 'atlasjson', key, [ image, data ]); - } - }, + return texture; +}; - /** - * Adds this file to its target cache upon successful loading and processing. - * - * @method Phaser.Loader.FileTypes.AsepriteFile#addToCache - * @since 3.7.0 - */ - addToCache: function () - { - if (this.isReadyToProcess()) - { - var image = this.files[0]; - var json = this.files[1]; - var normalMap = (this.files[2]) ? this.files[2].data : null; +module.exports = Canvas; - this.loader.textureManager.addAtlas(image.key, image.data, json.data, normalMap); - json.addToCache(); +/***/ }), - this.complete = true; - } - } +/***/ 21560: +/***/ ((module) => { -}); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ /** - * Aseprite is a powerful animated sprite editor and pixel art tool. - * - * You can find more details at https://www.aseprite.org/ - * - * Adds a JSON based Aseprite Animation, or array of animations, 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.aseprite('gladiator', 'images/Gladiator.png', 'images/Gladiator.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. - * - * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring - * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. - * - * To export a compatible JSON file in Aseprite, please do the following: - * - * 1. Go to "File - Export Sprite Sheet" - * - * 2. On the **Layout** tab: - * 2a. Set the "Sheet type" to "Packed" - * 2b. Set the "Constraints" to "None" - * 2c. Check the "Merge Duplicates" checkbox - * - * 3. On the **Sprite** tab: - * 3a. Set "Layers" to "Visible layers" - * 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags - * - * 4. On the **Borders** tab: - * 4a. Check the "Trim Sprite" and "Trim Cells" options - * 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough) - * - * 5. On the **Output** tab: - * 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type - * 5b. Check "JSON Data" and give your json file a name - * 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind. - * 5d. Make sure "Tags" is checked in the Meta options - * 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more. - * - * 6. Click export - * - * This was tested with Aseprite 1.2.25. - * - * This will export a png and json file which you can load using the Aseprite Loader, i.e.: - * - * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. - * - * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.aseprite({ - * key: 'gladiator', - * textureURL: 'images/Gladiator.png', - * atlasURL: 'images/Gladiator.json' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.AsepriteFileConfig` for more details. - * - * Instead of passing a URL for the JSON data you can also pass in a well formed JSON object instead. - * - * Once loaded, you can call this method from within a Scene with the 'atlas' key: - * - * ```javascript - * this.anims.createFromAseprite('paladin'); - * ``` - * - * Any animations defined in the JSON will now be available to use in Phaser and you play them - * via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline, - * you can play it in Phaser using that Tag name: - * - * ```javascript - * this.add.sprite(400, 300).play('War Cry'); - * ``` - * - * When calling this method you can optionally provide an array of tag names, and only those animations - * will be created. For example: - * - * ```javascript - * this.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]); - * ``` - * - * This will only create the 3 animations defined. Note that the tag names are case-sensitive. - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Note: The ability to load this type of file will only be available if the Aseprite File type has been built into Phaser. - * It is available in the default build but can be excluded from custom builds. + * Adds an Image Element to a Texture. * - * @method Phaser.Loader.LoaderPlugin#aseprite - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.50.0 + * @function Phaser.Textures.Parsers.Image + * @memberof Phaser.Textures.Parsers + * @private + * @since 3.0.0 * - * @param {(string|Phaser.Types.Loader.FileTypes.AsepriteFileConfig|Phaser.Types.Loader.FileTypes.AsepriteFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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, a well formed JSON object. - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. + * @param {number} sourceIndex - The index of the TextureSource. * - * @return {this} The Loader instance. + * @return {Phaser.Textures.Texture} The Texture modified by this parser. */ -FileTypesManager.register('aseprite', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) +var Image = function (texture, sourceIndex) { - var multifile; - - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined - - if (Array.isArray(key)) - { - for (var i = 0; i < key.length; i++) - { - multifile = new AsepriteFile(this, key[i]); - - this.addFile(multifile.files); - } - } - else - { - multifile = new AsepriteFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); + var source = texture.source[sourceIndex]; - this.addFile(multifile.files); - } + texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); - return this; -}); + return texture; +}; -module.exports = AsepriteFile; +module.exports = Image; /***/ }), -/* 1342 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 64423: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(71); -var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(61); -var MultiFile = __webpack_require__(49); +var Clone = __webpack_require__(32742); /** - * @classdesc - * A single JSON based Texture Atlas File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#atlas method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#atlas. - * - * https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?source=photonstorm + * Parses a Texture Atlas JSON Array and adds the Frames to the Texture. + * JSON format expected to match that defined by Texture Packer, with the frames property containing an array of Frames. * - * @class AtlasJSONFile - * @extends Phaser.Loader.MultiFile - * @memberof Phaser.Loader.FileTypes - * @constructor + * @function Phaser.Textures.Parsers.JSONArray + * @memberof Phaser.Textures.Parsers + * @private * @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.AtlasJSONFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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, a well formed JSON object. - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. + * @param {number} sourceIndex - The index of the TextureSource. + * @param {object} json - The JSON data. + * + * @return {Phaser.Textures.Texture} The Texture modified by this parser. */ -var AtlasJSONFile = new Class({ +var JSONArray = function (texture, sourceIndex, json) +{ + // Malformed? + if (!json['frames'] && !json['textures']) + { + console.warn('Invalid Texture Atlas JSON Array'); + return; + } - Extends: MultiFile, + // Add in a __BASE entry (for the entire atlas) + var source = texture.source[sourceIndex]; - initialize: + texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); - function AtlasJSONFile (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) - { - var image; - var data; + // By this stage frames is a fully parsed array + var frames = (Array.isArray(json.textures)) ? json.textures[sourceIndex].frames : json.frames; - if (IsPlainObject(key)) - { - var config = key; + var newFrame; - key = GetFastValue(config, 'key'); + for (var i = 0; i < frames.length; i++) + { + var src = frames[i]; - image = new ImageFile(loader, { - key: key, - url: GetFastValue(config, 'textureURL'), - extension: GetFastValue(config, 'textureExtension', 'png'), - normalMap: GetFastValue(config, 'normalMap'), - xhrSettings: GetFastValue(config, 'textureXhrSettings') - }); + // The frame values are the exact coordinates to cut the frame out of the atlas from + newFrame = texture.add(src.filename, sourceIndex, src.frame.x, src.frame.y, src.frame.w, src.frame.h); - data = new JSONFile(loader, { - key: key, - url: GetFastValue(config, 'atlasURL'), - extension: GetFastValue(config, 'atlasExtension', 'json'), - xhrSettings: GetFastValue(config, 'atlasXhrSettings') - }); - } - else + if (!newFrame) { - image = new ImageFile(loader, key, textureURL, textureXhrSettings); - data = new JSONFile(loader, key, atlasURL, atlasXhrSettings); - } + console.warn('Invalid atlas json, frame already exists: ' + src.filename); - if (image.linkFile) - { - // Image has a normal map - MultiFile.call(this, loader, 'atlasjson', key, [ image, data, image.linkFile ]); + continue; } - else + + // These are the original (non-trimmed) sprite values + if (src.trimmed) { - MultiFile.call(this, loader, 'atlasjson', key, [ image, data ]); + newFrame.setTrim( + src.sourceSize.w, + src.sourceSize.h, + src.spriteSourceSize.x, + src.spriteSourceSize.y, + src.spriteSourceSize.w, + src.spriteSourceSize.h + ); } - }, - /** - * Adds this file to its target cache upon successful loading and processing. - * - * @method Phaser.Loader.FileTypes.AtlasJSONFile#addToCache - * @since 3.7.0 - */ - addToCache: function () - { - if (this.isReadyToProcess()) + if (src.rotated) { - var image = this.files[0]; - var json = this.files[1]; - var normalMap = (this.files[2]) ? this.files[2].data : null; - - this.loader.textureManager.addAtlas(image.key, image.data, json.data, normalMap); - - json.pendingDestroy(); - - this.complete = true; + newFrame.rotated = true; + newFrame.updateUVsInverted(); } - } -}); + var pivot = src.anchor || src.pivot; -/** - * Adds a JSON based Texture Atlas, or array of atlases, 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.atlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.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. - * - * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring - * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. - * - * Phaser expects the atlas data to be provided in a JSON file, using either the JSON Hash or JSON Array format. - * These files are created by software such as Texture Packer, Shoebox and Adobe Flash / Animate. - * If you are using Texture Packer and have enabled multi-atlas support, then please use the Phaser Multi Atlas loader - * instead of this one. - * - * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. - * - * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.atlas({ - * key: 'mainmenu', - * textureURL: 'images/MainMenu.png', - * atlasURL: 'images/MainMenu.json' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig` for more details. - * - * Instead of passing a URL for the atlas JSON data you can also pass in a well formed JSON object instead. - * - * Once the atlas has finished loading you can use frames from it as textures for a Game Object by referencing its key: - * - * ```javascript - * this.load.atlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.json'); - * // and later in your game ... - * this.add.image(x, y, 'mainmenu', 'background'); - * ``` - * - * To get a list of all available frames within an atlas please consult your Texture Atlas software. - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, - * then you can specify it by providing an array as the `url` where the second element is the normal map: - * - * ```javascript - * this.load.atlas('mainmenu', [ 'images/MainMenu.png', 'images/MainMenu-n.png' ], 'images/MainMenu.json'); - * ``` - * - * Or, if you are using a config object use the `normalMap` property: - * - * ```javascript - * this.load.atlas({ - * key: 'mainmenu', - * textureURL: 'images/MainMenu.png', - * normalMap: 'images/MainMenu-n.png', - * atlasURL: 'images/MainMenu.json' - * }); - * ``` - * - * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. - * Normal maps are a WebGL only feature. - * - * Note: The ability to load this type of file will only be available if the Atlas 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#atlas - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig|Phaser.Types.Loader.FileTypes.AtlasJSONFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {object|string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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, a well formed JSON object. - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. - * - * @return {this} The Loader instance. - */ -FileTypesManager.register('atlas', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) -{ - var multifile; + if (pivot) + { + newFrame.customPivot = true; + newFrame.pivotX = pivot.x; + newFrame.pivotY = pivot.y; + } - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined + // Copy over any extra data + newFrame.customData = Clone(src); + } - if (Array.isArray(key)) + // Copy over any additional data that was in the JSON to Texture.customData + for (var dataKey in json) { - for (var i = 0; i < key.length; i++) + if (dataKey === 'frames') { - multifile = new AtlasJSONFile(this, key[i]); - - this.addFile(multifile.files); + continue; } - } - else - { - multifile = new AtlasJSONFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); - this.addFile(multifile.files); + if (Array.isArray(json[dataKey])) + { + texture.customData[dataKey] = json[dataKey].slice(0); + } + else + { + texture.customData[dataKey] = json[dataKey]; + } } - return this; -}); + return texture; +}; -module.exports = AtlasJSONFile; +module.exports = JSONArray; /***/ }), -/* 1343 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 17264: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(71); -var IsPlainObject = __webpack_require__(7); -var MultiFile = __webpack_require__(49); -var XMLFile = __webpack_require__(241); +var Clone = __webpack_require__(32742); /** - * @classdesc - * A single XML based Texture Atlas File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#atlasXML method and are not typically created directly. + * Parses a Texture Atlas JSON Hash and adds the Frames to the Texture. + * JSON format expected to match that defined by Texture Packer, with the frames property containing an object of Frames. * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#atlasXML. + * @function Phaser.Textures.Parsers.JSONHash + * @memberof Phaser.Textures.Parsers + * @private + * @since 3.0.0 * - * @class AtlasXMLFile - * @extends Phaser.Loader.MultiFile - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.7.0 + * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. + * @param {number} sourceIndex - The index of the TextureSource. + * @param {object} json - The JSON data. * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas xml file. Used in replacement of the Loaders default XHR Settings. + * @return {Phaser.Textures.Texture} The Texture modified by this parser. */ -var AtlasXMLFile = new Class({ +var JSONHash = function (texture, sourceIndex, json) +{ + // Malformed? + if (!json['frames']) + { + console.warn('Invalid Texture Atlas JSON Hash given, missing \'frames\' Object'); + return; + } - Extends: MultiFile, + // Add in a __BASE entry (for the entire atlas) + var source = texture.source[sourceIndex]; - initialize: + texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); - function AtlasXMLFile (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) - { - var image; - var data; + // By this stage frames is a fully parsed Object + var frames = json.frames; + var newFrame; - if (IsPlainObject(key)) + for (var key in frames) + { + if (!frames.hasOwnProperty(key)) { - var config = key; + continue; + } - key = GetFastValue(config, 'key'); + var src = frames[key]; - image = new ImageFile(loader, { - key: key, - url: GetFastValue(config, 'textureURL'), - extension: GetFastValue(config, 'textureExtension', 'png'), - normalMap: GetFastValue(config, 'normalMap'), - xhrSettings: GetFastValue(config, 'textureXhrSettings') - }); + // The frame values are the exact coordinates to cut the frame out of the atlas from + newFrame = texture.add(key, sourceIndex, src.frame.x, src.frame.y, src.frame.w, src.frame.h); - data = new XMLFile(loader, { - key: key, - url: GetFastValue(config, 'atlasURL'), - extension: GetFastValue(config, 'atlasExtension', 'xml'), - xhrSettings: GetFastValue(config, 'atlasXhrSettings') - }); - } - else + if (!newFrame) { - image = new ImageFile(loader, key, textureURL, textureXhrSettings); - data = new XMLFile(loader, key, atlasURL, atlasXhrSettings); + console.warn('Invalid atlas json, frame already exists: ' + key); + + continue; } - if (image.linkFile) + // These are the original (non-trimmed) sprite values + if (src.trimmed) { - // Image has a normal map - MultiFile.call(this, loader, 'atlasxml', key, [ image, data, image.linkFile ]); + newFrame.setTrim( + src.sourceSize.w, + src.sourceSize.h, + src.spriteSourceSize.x, + src.spriteSourceSize.y, + src.spriteSourceSize.w, + src.spriteSourceSize.h + ); } - else + + if (src.rotated) { - MultiFile.call(this, loader, 'atlasxml', key, [ image, data ]); + newFrame.rotated = true; + newFrame.updateUVsInverted(); } - }, - /** - * Adds this file to its target cache upon successful loading and processing. - * - * @method Phaser.Loader.FileTypes.AtlasXMLFile#addToCache - * @since 3.7.0 - */ - addToCache: function () - { - if (this.isReadyToProcess()) + var pivot = src.anchor || src.pivot; + + if (pivot) { - var image = this.files[0]; - var xml = this.files[1]; - var normalMap = (this.files[2]) ? this.files[2].data : null; + newFrame.customPivot = true; + newFrame.pivotX = pivot.x; + newFrame.pivotY = pivot.y; + } - this.loader.textureManager.addAtlasXML(image.key, image.data, xml.data, normalMap); + // Copy over any extra data + newFrame.customData = Clone(src); + } - xml.pendingDestroy(); + // Copy over any additional data that was in the JSON to Texture.customData + for (var dataKey in json) + { + if (dataKey === 'frames') + { + continue; + } - this.complete = true; + if (Array.isArray(json[dataKey])) + { + texture.customData[dataKey] = json[dataKey].slice(0); + } + else + { + texture.customData[dataKey] = json[dataKey]; } } -}); + return texture; +}; + +module.exports = JSONHash; + + +/***/ }), + +/***/ 67409: +/***/ ((module) => { /** - * Adds an XML based Texture Atlas, or array of atlases, 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.atlasXML('mainmenu', 'images/MainMenu.png', 'images/MainMenu.xml'); - * } - * ``` - * - * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, - * or if it's already running, when the next free load slot becomes available. This happens automatically if you - * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued - * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. - * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the - * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been - * loaded. - * - * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring - * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. - * - * Phaser expects the atlas data to be provided in an XML file format. - * These files are created by software such as Shoebox and Adobe Flash / Animate. - * - * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. - * - * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.atlasXML({ - * key: 'mainmenu', - * textureURL: 'images/MainMenu.png', - * atlasURL: 'images/MainMenu.xml' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig` for more details. - * - * Once the atlas has finished loading you can use frames from it as textures for a Game Object by referencing its key: - * - * ```javascript - * this.load.atlasXML('mainmenu', 'images/MainMenu.png', 'images/MainMenu.xml'); - * // and later in your game ... - * this.add.image(x, y, 'mainmenu', 'background'); - * ``` - * - * To get a list of all available frames within an atlas please consult your Texture Atlas software. - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, - * then you can specify it by providing an array as the `url` where the second element is the normal map: - * - * ```javascript - * this.load.atlasXML('mainmenu', [ 'images/MainMenu.png', 'images/MainMenu-n.png' ], 'images/MainMenu.xml'); - * ``` - * - * Or, if you are using a config object use the `normalMap` property: - * - * ```javascript - * this.load.atlasXML({ - * key: 'mainmenu', - * textureURL: 'images/MainMenu.png', - * normalMap: 'images/MainMenu-n.png', - * atlasURL: 'images/MainMenu.xml' - * }); - * ``` - * - * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. - * Normal maps are a WebGL only feature. - * - * Note: The ability to load this type of file will only be available if the Atlas XML File type has been built into Phaser. - * It is available in the default build but can be excluded from custom builds. + * @author Richard Davey + * @copyright 2021 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Parses a KTX format Compressed Texture file and generates texture data suitable for WebGL from it. * - * @method Phaser.Loader.LoaderPlugin#atlasXML - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.7.0 + * @function Phaser.Textures.Parsers.KTXParser + * @memberof Phaser.Textures.Parsers + * @since 3.60.0 * - * @param {(string|Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig|Phaser.Types.Loader.FileTypes.AtlasXMLFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas xml file. Used in replacement of the Loaders default XHR Settings. + * @param {ArrayBuffer} data - The data object created by the Compressed Texture File Loader. * - * @return {this} The Loader instance. + * @return {Phaser.Types.Textures.CompressedTextureData} The Compressed Texture data. */ -FileTypesManager.register('atlasXML', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) +var KTXParser = function (data) { - var multifile; + var idCheck = [ 0xab, 0x4b, 0x54, 0x58, 0x20, 0x31, 0x31, 0xbb, 0x0d, 0x0a, 0x1a, 0x0a ]; - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined + var i; + var id = new Uint8Array(data, 0, 12); - if (Array.isArray(key)) + for (i = 0; i < id.length; i++) { - for (var i = 0; i < key.length; i++) + if (id[i] !== idCheck[i]) { - multifile = new AtlasXMLFile(this, key[i]); + console.warn('KTXParser - Invalid file format'); - this.addFile(multifile.files); + return; } } - else + + var size = Uint32Array.BYTES_PER_ELEMENT; + + var head = new DataView(data, 12, 13 * size); + + var littleEndian = (head.getUint32(0, true) === 0x04030201); + + var glType = head.getUint32(1 * size, littleEndian); + + if (glType !== 0) { - multifile = new AtlasXMLFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); + console.warn('KTXParser - Only compressed formats supported'); - this.addFile(multifile.files); + return; } - return this; -}); + var internalFormat = head.getUint32(4 * size, littleEndian); + var width = head.getUint32(6 * size, littleEndian); + var height = head.getUint32(7 * size, littleEndian); -module.exports = AtlasXMLFile; + var mipmapLevels = Math.max(1, head.getUint32(11 * size, littleEndian)); + + var bytesOfKeyValueData = head.getUint32(12 * size, littleEndian); + + var mipmaps = new Array(mipmapLevels); + + var offset = 12 + 13 * 4 + bytesOfKeyValueData; + var levelWidth = width; + var levelHeight = height; + + for (i = 0; i < mipmapLevels; i++) + { + var levelSize = new Int32Array(data, offset, 1)[0]; + + // levelSize field + offset += 4; + + mipmaps[i] = { + data: new Uint8Array(data, offset, levelSize), + width: levelWidth, + height: levelHeight + }; + + // add padding for odd sized image + // offset += 3 - ((levelSize + 3) % 4); + + levelWidth = Math.max(1, levelWidth >> 1); + levelHeight = Math.max(1, levelHeight >> 1); + + offset += levelSize; + } + + return { + mipmaps: mipmaps, + width: width, + height: height, + internalFormat: internalFormat, + compressed: true, + generateMipmap: false + }; +}; + +module.exports = KTXParser; /***/ }), -/* 1344 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 24904: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2021 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AudioFile = __webpack_require__(518); -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(61); -var MultiFile = __webpack_require__(49); - /** - * @classdesc - * An Audio Sprite File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#audioSprite method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#audioSprite. - * - * @class AudioSpriteFile - * @extends Phaser.Loader.MultiFile - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.7.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string} jsonURL - The absolute or relative URL to load the json file from. Or a well formed JSON object to use instead. - * @param {{(string|string[])}} [audioURL] - The absolute or relative URL to load the audio file from. If empty it will be obtained by parsing the JSON file. - * @param {any} [audioConfig] - The audio configuration options. - * @param {Phaser.Types.Loader.XHRSettingsObject} [audioXhrSettings] - An XHR Settings configuration object for the audio file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings. + * @ignore */ -var AudioSpriteFile = new Class({ - - Extends: MultiFile, +function GetSize (width, height, x, y, dx, dy, mult) +{ + if (mult === undefined) { mult = 16; } - initialize: + return Math.floor((width + x) / dx) * Math.floor((height + y) / dy) * mult; +} - function AudioSpriteFile (loader, key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings) - { - if (IsPlainObject(key)) - { - var config = key; +/** + * @ignore + */ +function PVRTC2bppSize (width, height) +{ + width = Math.max(width, 16); + height = Math.max(height, 8); - key = GetFastValue(config, 'key'); - jsonURL = GetFastValue(config, 'jsonURL'); - audioURL = GetFastValue(config, 'audioURL'); - audioConfig = GetFastValue(config, 'audioConfig'); - audioXhrSettings = GetFastValue(config, 'audioXhrSettings'); - jsonXhrSettings = GetFastValue(config, 'jsonXhrSettings'); - } + return width * height / 4; +} - var data; +/** + * @ignore + */ +function PVRTC4bppSize (width, height) +{ + width = Math.max(width, 8); + height = Math.max(height, 8); - // No url? then we're going to do a json load and parse it from that - if (!audioURL) - { - data = new JSONFile(loader, key, jsonURL, jsonXhrSettings); + return width * height / 2; +} - MultiFile.call(this, loader, 'audiosprite', key, [ data ]); +/** + * @ignore + */ +function DXTEtcSmallSize (width, height) +{ + return GetSize(width, height, 3, 3, 4, 4, 8); +} - this.config.resourceLoad = true; - this.config.audioConfig = audioConfig; - this.config.audioXhrSettings = audioXhrSettings; - } - else - { - var audio = AudioFile.create(loader, key, audioURL, audioConfig, audioXhrSettings); +/** + * @ignore + */ +function DXTEtcAstcBigSize (width, height) +{ + return GetSize(width, height, 3, 3, 4, 4); +} - if (audio) - { - data = new JSONFile(loader, key, jsonURL, jsonXhrSettings); +/** + * @ignore + */ +function ATC5x4Size (width, height) +{ + return GetSize(width, height, 4, 3, 5, 4); +} - MultiFile.call(this, loader, 'audiosprite', key, [ audio, data ]); +/** + * @ignore + */ +function ATC5x5Size (width, height) +{ + return GetSize(width, height, 4, 4, 5, 5); +} - this.config.resourceLoad = false; - } - } - }, +/** + * @ignore + */ +function ATC6x5Size (width, height) +{ + return GetSize(width, height, 5, 4, 6, 5); +} - /** - * Called by each File when it finishes loading. - * - * @method Phaser.Loader.FileTypes.AudioSpriteFile#onFileComplete - * @since 3.7.0 - * - * @param {Phaser.Loader.File} file - The File that has completed processing. - */ - onFileComplete: function (file) - { - var index = this.files.indexOf(file); +/** + * @ignore + */ +function ATC6x6Size (width, height) +{ + return GetSize(width, height, 5, 5, 6, 6); +} - if (index !== -1) - { - this.pending--; +/** + * @ignore + */ +function ATC8x5Size (width, height) +{ + return GetSize(width, height, 7, 4, 8, 5); +} - if (this.config.resourceLoad && file.type === 'json' && file.data.hasOwnProperty('resources')) - { - // Inspect the data for the files to now load - var urls = file.data.resources; +/** + * @ignore + */ +function ATC8x6Size (width, height) +{ + return GetSize(width, height, 7, 5, 8, 6); +} - var audioConfig = GetFastValue(this.config, 'audioConfig'); - var audioXhrSettings = GetFastValue(this.config, 'audioXhrSettings'); +/** + * @ignore + */ +function ATC8x8Size (width, height) +{ + return GetSize(width, height, 7, 7, 8, 8); +} - var audio = AudioFile.create(this.loader, file.key, urls, audioConfig, audioXhrSettings); +/** + * @ignore + */ +function ATC10x5Size (width, height) +{ + return GetSize(width, height, 9, 4, 10, 5); +} - if (audio) - { - this.addToMultiFile(audio); +/** + * @ignore + */ +function ATC10x6Size (width, height) +{ + return GetSize(width, height, 9, 5, 10, 6); +} - this.loader.addFile(audio); - } - } - } - }, +/** + * @ignore + */ +function ATC10x8Size (width, height) +{ + return GetSize(width, height, 9, 7, 10, 8); +} - /** - * Adds this file to its target cache upon successful loading and processing. - * - * @method Phaser.Loader.FileTypes.AudioSpriteFile#addToCache - * @since 3.7.0 - */ - addToCache: function () - { - if (this.isReadyToProcess()) - { - var fileA = this.files[0]; - var fileB = this.files[1]; +/** + * @ignore + */ +function ATC10x10Size (width, height) +{ + return GetSize(width, height, 9, 9, 10, 10); +} - fileA.addToCache(); - fileB.addToCache(); +/** + * @ignore + */ +function ATC12x10Size (width, height) +{ + return GetSize(width, height, 11, 9, 12, 10); +} - this.complete = true; - } - } +/** + * @ignore + */ +function ATC12x12Size (width, height) +{ + return GetSize(width, height, 11, 11, 12, 12); +} -}); +/** + * 0: COMPRESSED_RGB_PVRTC_2BPPV1_IMG + * 1: COMPRESSED_RGBA_PVRTC_2BPPV1_IMG + * 2: COMPRESSED_RGB_PVRTC_4BPPV1_IMG + * 3: COMPRESSED_RGBA_PVRTC_4BPPV1_IMG + * 6: COMPRESSED_RGB_ETC1 + * 7: COMPRESSED_RGB_S3TC_DXT1_EXT + * 8: COMPRESSED_RGBA_S3TC_DXT1_EXT + * 9: COMPRESSED_RGBA_S3TC_DXT3_EXT + * 11: COMPRESSED_RGBA_S3TC_DXT5_EXT + * 22: COMPRESSED_RGB8_ETC2 + * 23: COMPRESSED_RGBA8_ETC2_EAC + * 24: COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 + * 25: COMPRESSED_R11_EAC + * 26: COMPRESSED_RG11_EAC + * 27: COMPRESSED_RGBA_ASTC_4x4_KHR + * 28: COMPRESSED_RGBA_ASTC_5x4_KHR + * 29: COMPRESSED_RGBA_ASTC_5x5_KHR + * 30: COMPRESSED_RGBA_ASTC_6x5_KHR + * 31: COMPRESSED_RGBA_ASTC_6x6_KHR + * 32: COMPRESSED_RGBA_ASTC_8x5_KHR + * 33: COMPRESSED_RGBA_ASTC_8x6_KHR + * 34: COMPRESSED_RGBA_ASTC_8x8_KHR + * 35: COMPRESSED_RGBA_ASTC_10x5_KHR + * 36: COMPRESSED_RGBA_ASTC_10x6_KHR + * 37: COMPRESSED_RGBA_ASTC_10x8_KHR + * 38: COMPRESSED_RGBA_ASTC_10x10_KHR + * 39: COMPRESSED_RGBA_ASTC_12x10_KHR + * 40: COMPRESSED_RGBA_ASTC_12x12_KHR + */ /** - * Adds a JSON based Audio Sprite, or array of audio sprites, 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.audioSprite('kyobi', 'kyobi.json', [ - * 'kyobi.ogg', - * 'kyobi.mp3', - * 'kyobi.m4a' - * ]); - * } - * ``` - * - * Audio Sprites are a combination of audio files and a JSON configuration. - * The JSON follows the format of that created by https://github.com/tonistiigi/audiosprite - * - * If the JSON file includes a 'resource' object then you can let Phaser parse it and load the audio - * files automatically based on its content. To do this exclude the audio URLs from the load: - * - * ```javascript - * function preload () - * { - * this.load.audioSprite('kyobi', 'kyobi.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. - * - * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring - * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. - * - * 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.audioSprite({ - * key: 'kyobi', - * jsonURL: 'audio/Kyobi.json', - * audioURL: [ - * 'audio/Kyobi.ogg', - * 'audio/Kyobi.mp3', - * 'audio/Kyobi.m4a' - * ] - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig` for more details. - * - * Instead of passing a URL for the audio JSON data you can also pass in a well formed JSON object instead. - * - * Once the audio has finished loading you can use it create an Audio Sprite by referencing its key: - * - * ```javascript - * this.load.audioSprite('kyobi', 'kyobi.json'); - * // and later in your game ... - * var music = this.sound.addAudioSprite('kyobi'); - * music.play('title'); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * 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 Sprite 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#audioSprite - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 + * @ignore + */ +var FORMATS = { + 0: { sizeFunc: PVRTC2bppSize, glFormat: 0x8C01 }, + 1: { sizeFunc: PVRTC2bppSize, glFormat: 0x8C03 }, + 2: { sizeFunc: PVRTC4bppSize, glFormat: 0x8C00 }, + 3: { sizeFunc: PVRTC4bppSize, glFormat: 0x8C02 }, + 6: { sizeFunc: DXTEtcSmallSize , glFormat: 0x8D64 }, + 7: { sizeFunc: DXTEtcSmallSize, glFormat: 0x83F0 }, + 8: { sizeFunc: DXTEtcAstcBigSize, glFormat: 0x83F1 }, + 9: { sizeFunc: DXTEtcAstcBigSize, glFormat: 0x83F2 }, + 11: { sizeFunc: DXTEtcAstcBigSize, glFormat: 0x83F3 }, + 22: { sizeFunc: DXTEtcSmallSize , glFormat: 0x9274 }, + 23: { sizeFunc: DXTEtcAstcBigSize, glFormat: 0x9278 }, + 24: { sizeFunc: DXTEtcSmallSize, glFormat: 0x9276 }, + 25: { sizeFunc: DXTEtcSmallSize, glFormat: 0x9270 }, + 26: { sizeFunc: DXTEtcAstcBigSize, glFormat: 0x9272 }, + 27: { sizeFunc: DXTEtcAstcBigSize, glFormat: 0x93B0 }, + 28: { sizeFunc: ATC5x4Size, glFormat: 0x93B1 }, + 29: { sizeFunc: ATC5x5Size, glFormat: 0x93B2 }, + 30: { sizeFunc: ATC6x5Size, glFormat: 0x93B3 }, + 31: { sizeFunc: ATC6x6Size, glFormat: 0x93B4 }, + 32: { sizeFunc: ATC8x5Size, glFormat: 0x93B5 }, + 33: { sizeFunc: ATC8x6Size, glFormat: 0x93B6 }, + 34: { sizeFunc: ATC8x8Size, glFormat: 0x93B7 }, + 35: { sizeFunc: ATC10x5Size, glFormat: 0x93B8 }, + 36: { sizeFunc: ATC10x6Size, glFormat: 0x93B9 }, + 37: { sizeFunc: ATC10x8Size, glFormat: 0x93BA }, + 38: { sizeFunc: ATC10x10Size, glFormat: 0x93BB }, + 39: { sizeFunc: ATC12x10Size, glFormat: 0x93BC }, + 40: { sizeFunc: ATC12x12Size, glFormat: 0x93BD } +}; + +/** + * Parses a PVR format Compressed Texture file and generates texture data suitable for WebGL from it. + * + * @function Phaser.Textures.Parsers.PVRParser + * @memberof Phaser.Textures.Parsers + * @since 3.60.0 * - * @param {(string|Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig|Phaser.Types.Loader.FileTypes.AudioSpriteFileConfig[])} key - The key to use for this file, or a file configuration object, or an array of objects. - * @param {string} jsonURL - The absolute or relative URL to load the json file from. Or a well formed JSON object to use instead. - * @param {(string|string[])} [audioURL] - The absolute or relative URL to load the audio file from. If empty it will be obtained by parsing the JSON file. - * @param {any} [audioConfig] - The audio configuration options. - * @param {Phaser.Types.Loader.XHRSettingsObject} [audioXhrSettings] - An XHR Settings configuration object for the audio file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings. + * @param {ArrayBuffer} data - The data object created by the Compressed Texture File Loader. * - * @return {this} The Loader. + * @return {Phaser.Types.Textures.CompressedTextureData} The Compressed Texture data. */ -FileTypesManager.register('audioSprite', function (key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings) +var PVRParser = function (data) { - var game = this.systems.game; - var gameAudioConfig = game.config.audio; - var deviceAudio = game.device.audio; + var header = new Uint32Array(data, 0, 13); - if ((gameAudioConfig && gameAudioConfig.noAudio) || (!deviceAudio.webAudio && !deviceAudio.audioData)) - { - // Sounds are disabled, so skip loading audio - return this; - } + // PIXEL_FORMAT_INDEX + var pvrFormat = header[2]; - var multifile; + var internalFormat = FORMATS[pvrFormat].glFormat; + var sizeFunction = FORMATS[pvrFormat].sizeFunc; - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined + // MIPMAPCOUNT_INDEX + var mipmapLevels = header[11]; - if (Array.isArray(key)) - { - for (var i = 0; i < key.length; i++) - { - multifile = new AudioSpriteFile(this, key[i]); + // WIDTH_INDEX + var width = header[7]; - if (multifile.files) - { - this.addFile(multifile.files); - } - } - } - else + // HEIGHT_INDEX + var height = header[6]; + + // HEADER_SIZE + METADATA_SIZE_INDEX + var dataOffset = 52 + header[12]; + + var image = new Uint8Array(data, dataOffset); + + var mipmaps = new Array(mipmapLevels); + + var offset = 0; + var levelWidth = width; + var levelHeight = height; + + for (var i = 0; i < mipmapLevels; i++) { - multifile = new AudioSpriteFile(this, key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings); + var levelSize = sizeFunction(levelWidth, levelHeight); - if (multifile.files) - { - this.addFile(multifile.files); - } + mipmaps[i] = { + data: new Uint8Array(image.buffer, image.byteOffset + offset, levelSize), + width: levelWidth, + height: levelHeight + }; + + levelWidth = Math.max(1, levelWidth >> 1); + levelHeight = Math.max(1, levelHeight >> 1); + + offset += levelSize; } - return this; -}); + return { + mipmaps: mipmaps, + width: width, + height: height, + internalFormat: internalFormat, + compressed: true, + generateMipmap: false + }; +}; + +module.exports = PVRParser; /***/ }), -/* 1345 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 6143: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); +var GetFastValue = __webpack_require__(72632); /** - * @classdesc - * A single Binary File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#binary method and are not typically created directly. + * Parses a Sprite Sheet and adds the Frames to the Texture. * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#binary. + * 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. * - * @class BinaryFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor + * @function Phaser.Textures.Parsers.SpriteSheet + * @memberof Phaser.Textures.Parsers + * @private * @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.BinaryFileConfig)} 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 `.bin`, i.e. if `key` was "alien" then the URL will be "alien.bin". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - * @param {any} [dataType] - Optional type to cast the binary file to once loaded. For example, `Uint8Array`. + * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. + * @param {number} sourceIndex - The index of the TextureSource. + * @param {number} x - The top-left coordinate of the Sprite Sheet. Defaults to zero. Used when extracting sheets from atlases. + * @param {number} y - The top-left coordinate of the Sprite Sheet. Defaults to zero. Used when extracting sheets from atlases. + * @param {number} width - The width of the source image. + * @param {number} height - The height of the source image. + * @param {object} config - An object describing how to parse the Sprite Sheet. + * @param {number} config.frameWidth - Width in pixels of a single frame in the sprite sheet. + * @param {number} [config.frameHeight] - Height in pixels of a single frame in the sprite sheet. Defaults to frameWidth if not provided. + * @param {number} [config.startFrame=0] - The frame to start extracting from. Defaults to zero. + * @param {number} [config.endFrame=-1] - The frame to finish extracting at. Defaults to -1, which means 'all frames'. + * @param {number} [config.margin=0] - If the frames have been drawn with a margin, specify the amount here. + * @param {number} [config.spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. + * + * @return {Phaser.Textures.Texture} The Texture modified by this parser. */ -var BinaryFile = new Class({ - - Extends: File, - - initialize: +var SpriteSheet = function (texture, sourceIndex, x, y, width, height, config) +{ + var frameWidth = GetFastValue(config, 'frameWidth', null); + var frameHeight = GetFastValue(config, 'frameHeight', frameWidth); - function BinaryFile (loader, key, url, xhrSettings, dataType) + // If missing we can't proceed + if (frameWidth === null) { - var extension = 'bin'; + throw new Error('TextureManager.SpriteSheet: Invalid frameWidth given.'); + } - if (IsPlainObject(key)) - { - var config = key; + // Add in a __BASE entry (for the entire atlas) + var source = texture.source[sourceIndex]; - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - dataType = GetFastValue(config, 'dataType', dataType); - } + texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); - var fileConfig = { - type: 'binary', - cache: loader.cacheManager.binary, - extension: extension, - responseType: 'arraybuffer', - key: key, - url: url, - xhrSettings: xhrSettings, - config: { dataType: dataType } - }; + var startFrame = GetFastValue(config, 'startFrame', 0); + var endFrame = GetFastValue(config, 'endFrame', -1); + var margin = GetFastValue(config, 'margin', 0); + var spacing = GetFastValue(config, 'spacing', 0); - File.call(this, loader, fileConfig); - }, + var row = Math.floor((width - margin + spacing) / (frameWidth + spacing)); + var column = Math.floor((height - margin + spacing) / (frameHeight + spacing)); + var total = row * column; - /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. - * - * @method Phaser.Loader.FileTypes.BinaryFile#onProcess - * @since 3.7.0 - */ - onProcess: function () + if (total === 0) { - this.state = CONST.FILE_PROCESSING; + console.warn('SpriteSheet frame dimensions will result in zero frames for texture:', texture.key); + } - var ctor = this.config.dataType; + if (startFrame > total || startFrame < -total) + { + startFrame = 0; + } - this.data = (ctor) ? new ctor(this.xhrLoader.response) : this.xhrLoader.response; + if (startFrame < 0) + { + // Allow negative skipframes. + startFrame = total + startFrame; + } - this.onProcessComplete(); + if (endFrame === -1 || endFrame > total || endFrame < startFrame) + { + endFrame = total; } -}); + var fx = margin; + var fy = margin; + var ax = 0; + var ay = 0; + var c = 0; -/** - * Adds a Binary file, or array of Binary 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.binary('doom', 'files/Doom.wad'); - * } - * ``` - * - * 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 Binary Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Binary 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 Binary Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.binary({ - * key: 'doom', - * url: 'files/Doom.wad', - * dataType: Uint8Array - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.BinaryFileConfig` for more details. - * - * Once the file has finished loading you can access it from its Cache using its key: - * - * ```javascript - * this.load.binary('doom', 'files/Doom.wad'); - * // and later in your game ... - * var data = this.cache.binary.get('doom'); - * ``` - * - * 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 `Data` the final key will be `LEVEL1.Data` and - * this is what you would use to retrieve the text from the Binary 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 "doom" - * and no URL is given then the Loader will set the URL to be "doom.bin". It will always add `.bin` 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 Binary 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#binary - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.BinaryFileConfig|Phaser.Types.Loader.FileTypes.BinaryFileConfig[])} 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 `.bin`, i.e. if `key` was "alien" then the URL will be "alien.bin". - * @param {any} [dataType] - Optional type to cast the binary file to once loaded. For example, `Uint8Array`. - * @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('binary', function (key, url, dataType, xhrSettings) -{ - if (Array.isArray(key)) + for (var i = 0; i < total; i++) { - for (var i = 0; i < key.length; i++) + ax = 0; + ay = 0; + + var w = fx + frameWidth; + var h = fy + frameHeight; + + if (w > width) { - // 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 BinaryFile(this, key[i])); + ax = w - width; + } + + if (h > height) + { + ay = h - height; + } + + if (i >= startFrame && i <= endFrame) + { + texture.add(c, sourceIndex, x + fx, y + fy, frameWidth - ax, frameHeight - ay); + + c++; + } + + fx += frameWidth + spacing; + + if (fx + frameWidth > width) + { + fx = margin; + fy += frameHeight + spacing; } - } - else - { - this.addFile(new BinaryFile(this, key, url, xhrSettings, dataType)); } - return this; -}); + return texture; +}; -module.exports = BinaryFile; +module.exports = SpriteSheet; /***/ }), -/* 1346 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 20030: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(71); -var IsPlainObject = __webpack_require__(7); -var MultiFile = __webpack_require__(49); -var ParseXMLBitmapFont = __webpack_require__(212); -var XMLFile = __webpack_require__(241); +var GetFastValue = __webpack_require__(72632); /** - * @classdesc - * A single Bitmap Font based File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#bitmapFont method and are not typically created directly. + * Parses a Sprite Sheet and adds the Frames to the Texture, where the Sprite Sheet is stored as a frame within an Atlas. * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#bitmapFont. + * 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. * - * @class BitmapFontFile - * @extends Phaser.Loader.MultiFile - * @memberof Phaser.Loader.FileTypes - * @constructor + * @function Phaser.Textures.Parsers.SpriteSheetFromAtlas + * @memberof Phaser.Textures.Parsers + * @private * @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.BitmapFontFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the font image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {string} [fontDataURL] - The absolute or relative URL to load the font xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the font image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [fontDataXhrSettings] - An XHR Settings configuration object for the font data xml file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. + * @param {Phaser.Textures.Frame} frame - The Frame that contains the Sprite Sheet. + * @param {object} config - An object describing how to parse the Sprite Sheet. + * @param {number} config.frameWidth - Width in pixels of a single frame in the sprite sheet. + * @param {number} [config.frameHeight] - Height in pixels of a single frame in the sprite sheet. Defaults to frameWidth if not provided. + * @param {number} [config.startFrame=0] - Index of the start frame in the sprite sheet + * @param {number} [config.endFrame=-1] - Index of the end frame in the sprite sheet. -1 mean all the rest of the frames + * @param {number} [config.margin=0] - If the frames have been drawn with a margin, specify the amount here. + * @param {number} [config.spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. + * + * @return {Phaser.Textures.Texture} The Texture modified by this parser. */ -var BitmapFontFile = new Class({ +var SpriteSheetFromAtlas = function (texture, frame, config) +{ + var frameWidth = GetFastValue(config, 'frameWidth', null); + var frameHeight = GetFastValue(config, 'frameHeight', frameWidth); - Extends: MultiFile, + // If missing we can't proceed + if (!frameWidth) + { + throw new Error('TextureManager.SpriteSheetFromAtlas: Invalid frameWidth given.'); + } - initialize: + // Add in a __BASE entry (for the entire atlas frame) + var source = texture.source[0]; + texture.add('__BASE', 0, 0, 0, source.width, source.height); - function BitmapFontFile (loader, key, textureURL, fontDataURL, textureXhrSettings, fontDataXhrSettings) + var startFrame = GetFastValue(config, 'startFrame', 0); + var endFrame = GetFastValue(config, 'endFrame', -1); + var margin = GetFastValue(config, 'margin', 0); + var spacing = GetFastValue(config, 'spacing', 0); + + var x = frame.cutX; + var y = frame.cutY; + + var cutWidth = frame.cutWidth; + var cutHeight = frame.cutHeight; + var sheetWidth = frame.realWidth; + var sheetHeight = frame.realHeight; + + var row = Math.floor((sheetWidth - margin + spacing) / (frameWidth + spacing)); + var column = Math.floor((sheetHeight - margin + spacing) / (frameHeight + spacing)); + var total = row * column; + + // trim offsets + + var leftPad = frame.x; + var leftWidth = frameWidth - leftPad; + + var rightWidth = frameWidth - ((sheetWidth - cutWidth) - leftPad); + + var topPad = frame.y; + var topHeight = frameHeight - topPad; + + var bottomHeight = frameHeight - ((sheetHeight - cutHeight) - topPad); + + if (startFrame > total || startFrame < -total) { - var image; - var data; + startFrame = 0; + } - if (IsPlainObject(key)) + if (startFrame < 0) + { + // Allow negative skipframes. + startFrame = total + startFrame; + } + + if (endFrame !== -1) + { + total = startFrame + (endFrame + 1); + } + + var sheetFrame; + var frameX = margin; + var frameY = margin; + var frameIndex = 0; + var sourceIndex = 0; + + for (var sheetY = 0; sheetY < column; sheetY++) + { + var topRow = (sheetY === 0); + var bottomRow = (sheetY === column - 1); + + for (var sheetX = 0; sheetX < row; sheetX++) { - var config = key; + var leftRow = (sheetX === 0); + var rightRow = (sheetX === row - 1); - key = GetFastValue(config, 'key'); + sheetFrame = texture.add(frameIndex, sourceIndex, x + frameX, y + frameY, frameWidth, frameHeight); - image = new ImageFile(loader, { - key: key, - url: GetFastValue(config, 'textureURL'), - extension: GetFastValue(config, 'textureExtension', 'png'), - normalMap: GetFastValue(config, 'normalMap'), - xhrSettings: GetFastValue(config, 'textureXhrSettings') - }); + if (leftRow || topRow || rightRow || bottomRow) + { + var destX = (leftRow) ? leftPad : 0; + var destY = (topRow) ? topPad : 0; - data = new XMLFile(loader, { - key: key, - url: GetFastValue(config, 'fontDataURL'), - extension: GetFastValue(config, 'fontDataExtension', 'xml'), - xhrSettings: GetFastValue(config, 'fontDataXhrSettings') - }); + var trimWidth = 0; + var trimHeight = 0; + + if (leftRow) + { + trimWidth += (frameWidth - leftWidth); + } + + if (rightRow) + { + trimWidth += (frameWidth - rightWidth); + } + + if (topRow) + { + trimHeight += (frameHeight - topHeight); + } + + if (bottomRow) + { + trimHeight += (frameHeight - bottomHeight); + } + + var destWidth = frameWidth - trimWidth; + var destHeight = frameHeight - trimHeight; + + sheetFrame.cutWidth = destWidth; + sheetFrame.cutHeight = destHeight; + + sheetFrame.setTrim(frameWidth, frameHeight, destX, destY, destWidth, destHeight); + } + + frameX += spacing; + + if (leftRow) + { + frameX += leftWidth; + } + else if (rightRow) + { + frameX += rightWidth; + } + else + { + frameX += frameWidth; + } + + frameIndex++; } - else + + frameX = margin; + frameY += spacing; + + if (topRow) { - image = new ImageFile(loader, key, textureURL, textureXhrSettings); - data = new XMLFile(loader, key, fontDataURL, fontDataXhrSettings); + frameY += topHeight; } - - if (image.linkFile) + else if (bottomRow) { - // Image has a normal map - MultiFile.call(this, loader, 'bitmapfont', key, [ image, data, image.linkFile ]); + frameY += bottomHeight; } else { - MultiFile.call(this, loader, 'bitmapfont', key, [ image, data ]); + frameY += frameHeight; } - }, + } - /** - * Adds this file to its target cache upon successful loading and processing. - * - * @method Phaser.Loader.FileTypes.BitmapFontFile#addToCache - * @since 3.7.0 - */ - addToCache: function () - { - if (this.isReadyToProcess()) - { - var image = this.files[0]; - var xml = this.files[1]; + return texture; +}; - image.addToCache(); - xml.pendingDestroy(); +module.exports = SpriteSheetFromAtlas; - var texture = image.cache.get(image.key); - var data = ParseXMLBitmapFont(xml.data, image.cache.getFrame(image.key), 0, 0, texture); +/***/ }), - this.loader.cacheManager.bitmapFont.add(image.key, { data: data, texture: image.key, frame: null }); +/***/ 89187: +/***/ ((module) => { - this.complete = true; - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -}); +var imageHeight = 0; /** - * Adds an XML based Bitmap Font, or array of fonts, 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: + * @function addFrame + * @private + * @since 3.0.0 + */ +var addFrame = function (texture, sourceIndex, name, frame) +{ + // The frame values are the exact coordinates to cut the frame out of the atlas from - * ```javascript - * function preload () - * { - * this.load.bitmapFont('goldenFont', 'images/GoldFont.png', 'images/GoldFont.xml'); - * } - * ``` - * - * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, - * or if it's already running, when the next free load slot becomes available. This happens automatically if you - * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued - * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. - * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the - * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been - * loaded. - * - * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring - * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. - * - * Phaser expects the font data to be provided in an XML file format. - * These files are created by software such as the [Angelcode Bitmap Font Generator](http://www.angelcode.com/products/bmfont/), - * [Littera](http://kvazars.com/littera/) or [Glyph Designer](https://71squared.com/glyphdesigner) - * - * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. - * - * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.bitmapFont({ - * key: 'goldenFont', - * textureURL: 'images/GoldFont.png', - * fontDataURL: 'images/GoldFont.xml' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.BitmapFontFileConfig` for more details. - * - * Once the atlas has finished loading you can use key of it when creating a Bitmap Text Game Object: - * - * ```javascript - * this.load.bitmapFont('goldenFont', 'images/GoldFont.png', 'images/GoldFont.xml'); - * // and later in your game ... - * this.add.bitmapText(x, y, 'goldenFont', 'Hello World'); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use when creating a Bitmap Text object. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, - * then you can specify it by providing an array as the `url` where the second element is the normal map: - * - * ```javascript - * this.load.bitmapFont('goldenFont', [ 'images/GoldFont.png', 'images/GoldFont-n.png' ], 'images/GoldFont.xml'); - * ``` - * - * Or, if you are using a config object use the `normalMap` property: - * - * ```javascript - * this.load.bitmapFont({ - * key: 'goldenFont', - * textureURL: 'images/GoldFont.png', - * normalMap: 'images/GoldFont-n.png', - * fontDataURL: 'images/GoldFont.xml' - * }); - * ``` - * - * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. - * Normal maps are a WebGL only feature. - * - * Note: The ability to load this type of file will only be available if the Bitmap Font File type has been built into Phaser. - * It is available in the default build but can be excluded from custom builds. + var y = imageHeight - frame.y - frame.height; + + texture.add(name, sourceIndex, frame.x, y, frame.width, frame.height); + + // These are the original (non-trimmed) sprite values + /* + if (src.trimmed) + { + newFrame.setTrim( + src.sourceSize.w, + src.sourceSize.h, + src.spriteSourceSize.x, + src.spriteSourceSize.y, + src.spriteSourceSize.w, + src.spriteSourceSize.h + ); + } + */ +}; + +/** + * Parses a Unity YAML File and creates Frames in the Texture. + * For more details about Sprite Meta Data see https://docs.unity3d.com/ScriptReference/SpriteMetaData.html * - * @method Phaser.Loader.LoaderPlugin#bitmapFont - * @fires Phaser.Loader.LoaderPlugin#ADD + * @function Phaser.Textures.Parsers.UnityYAML + * @memberof Phaser.Textures.Parsers + * @private * @since 3.0.0 * - * @param {(string|Phaser.Types.Loader.FileTypes.BitmapFontFileConfig|Phaser.Types.Loader.FileTypes.BitmapFontFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the font image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {string} [fontDataURL] - The absolute or relative URL to load the font xml data file from. If undefined or `null` it will be set to `.xml`, i.e. if `key` was "alien" then the URL will be "alien.xml". - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the font image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [fontDataXhrSettings] - An XHR Settings configuration object for the font data xml file. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Textures.Texture} texture - The Texture to add the Frames to. + * @param {number} sourceIndex - The index of the TextureSource. + * @param {object} yaml - The YAML data. * - * @return {this} The Loader instance. + * @return {Phaser.Textures.Texture} The Texture modified by this parser. */ -FileTypesManager.register('bitmapFont', function (key, textureURL, fontDataURL, textureXhrSettings, fontDataXhrSettings) +var UnityYAML = function (texture, sourceIndex, yaml) { - var multifile; + // Add in a __BASE entry (for the entire atlas) + var source = texture.source[sourceIndex]; - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined + texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); - if (Array.isArray(key)) + imageHeight = source.height; + + var data = yaml.split('\n'); + + var lineRegExp = /^[ ]*(- )*(\w+)+[: ]+(.*)/; + + var prevSprite = ''; + var currentSprite = ''; + var rect = { x: 0, y: 0, width: 0, height: 0 }; + + // var pivot = { x: 0, y: 0 }; + // var border = { x: 0, y: 0, z: 0, w: 0 }; + + for (var i = 0; i < data.length; i++) { - for (var i = 0; i < key.length; i++) + var results = data[i].match(lineRegExp); + + if (!results) + { + continue; + } + + var isList = (results[1] === '- '); + var key = results[2]; + var value = results[3]; + + if (isList) + { + if (currentSprite !== prevSprite) + { + addFrame(texture, sourceIndex, currentSprite, rect); + + prevSprite = currentSprite; + } + + rect = { x: 0, y: 0, width: 0, height: 0 }; + } + + if (key === 'name') + { + // Start new list + currentSprite = value; + continue; + } + + switch (key) { - multifile = new BitmapFontFile(this, key[i]); + case 'x': + case 'y': + case 'width': + case 'height': + rect[key] = parseInt(value, 10); + break; - this.addFile(multifile.files); + // case 'pivot': + // pivot = eval('var obj = ' + value); + // break; + + // case 'border': + // border = eval('var obj = ' + value); + // break; } } - else - { - multifile = new BitmapFontFile(this, key, textureURL, fontDataURL, textureXhrSettings, fontDataXhrSettings); - this.addFile(multifile.files); + if (currentSprite !== prevSprite) + { + addFrame(texture, sourceIndex, currentSprite, rect); } - return this; -}); + return texture; +}; -module.exports = BitmapFontFile; +module.exports = UnityYAML; + +/* +Example data: + +TextureImporter: + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + spriteSheet: + sprites: + - name: asteroids_0 + rect: + serializedVersion: 2 + x: 5 + y: 328 + width: 65 + height: 82 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + - name: asteroids_1 + rect: + serializedVersion: 2 + x: 80 + y: 322 + width: 53 + height: 88 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + spritePackingTag: Asteroids +*/ /***/ }), -/* 1347 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 69150: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); - /** - * @classdesc - * A single CSS File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#css method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#css. - * - * @class CSSFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.17.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.CSSFileConfig)} 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. + * @namespace Phaser.Textures.Parsers */ -var CSSFile = new Class({ - Extends: File, +module.exports = { - initialize: + AtlasXML: __webpack_require__(35082), + Canvas: __webpack_require__(83332), + Image: __webpack_require__(21560), + JSONArray: __webpack_require__(64423), + JSONHash: __webpack_require__(17264), + KTXParser: __webpack_require__(67409), + PVRParser: __webpack_require__(24904), + SpriteSheet: __webpack_require__(6143), + SpriteSheetFromAtlas: __webpack_require__(20030), + UnityYAML: __webpack_require__(89187) - function CSSFile (loader, key, url, xhrSettings) - { - var extension = 'css'; +}; - 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 - }; +/***/ 93560: +/***/ ((module) => { - File.call(this, loader, fileConfig); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Tilemaps.Formats + */ + +module.exports = { /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * CSV Map Type * - * @method Phaser.Loader.FileTypes.CSSFile#onProcess - * @since 3.17.0 + * @name Phaser.Tilemaps.Formats.CSV + * @type {number} + * @since 3.0.0 */ - onProcess: function () - { - this.state = CONST.FILE_PROCESSING; - - this.data = document.createElement('style'); - this.data.defer = false; - this.data.innerHTML = this.xhrLoader.responseText; - - document.head.appendChild(this.data); - - this.onProcessComplete(); - } + CSV: 0, -}); + /** + * Tiled JSON Map Type + * + * @name Phaser.Tilemaps.Formats.TILED_JSON + * @type {number} + * @since 3.0.0 + */ + TILED_JSON: 1, -/** - * Adds a CSS file, or array of CSS 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.css('headers', 'styles/headers.css'); - * } - * ``` - * - * 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.css({ - * key: 'headers', - * url: 'styles/headers.css' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.CSSFileConfig` for more details. - * - * Once the file has finished loading it will automatically be converted into a style DOM element - * via `document.createElement('style')`. It will have its `defer` property set to false and then the - * resulting element will be appended to `document.head`. The CSS styles are then applied to the current document. - * - * 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.css". It will always add `.css` 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 CSS 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#css - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.17.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.CSSFileConfig|Phaser.Types.Loader.FileTypes.CSSFileConfig[])} 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 `.css`, i.e. if `key` was "alien" then the URL will be "alien.css". - * @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('css', 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 CSSFile(this, key[i])); - } - } - else - { - this.addFile(new CSSFile(this, key, url, xhrSettings)); - } + /** + * 2D Array Map Type + * + * @name Phaser.Tilemaps.Formats.ARRAY_2D + * @type {number} + * @since 3.0.0 + */ + ARRAY_2D: 2, - return this; -}); + /** + * Weltmeister (Impact.js) Map Type + * + * @name Phaser.Tilemaps.Formats.WELTMEISTER + * @type {number} + * @since 3.0.0 + */ + WELTMEISTER: 3 -module.exports = CSSFile; +}; /***/ }), -/* 1348 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 97042: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); -var Shader = __webpack_require__(396); +var Class = __webpack_require__(56694); /** * @classdesc - * A single GLSL File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#glsl method and are not typically created directly. + * An Image Collection is a special Tile Set containing multiple images, with no slicing into each image. * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#glsl. + * Image Collections are normally created automatically when Tiled data is loaded. * - * @class GLSLFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes + * @class ImageCollection + * @memberof Phaser.Tilemaps * @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.GLSLFileConfig)} 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 `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". - * @param {string} [shaderType='fragment'] - The type of shader. Either `fragment` for a fragment shader, or `vertex` for a vertex shader. This is ignored if you load a shader bundle. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + * @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 GLSLFile = new Class({ - - Extends: File, +var ImageCollection = new Class({ initialize: - function GLSLFile (loader, key, url, shaderType, xhrSettings) + function ImageCollection (name, firstgid, width, height, margin, spacing, properties) { - var extension = 'glsl'; + if (width === undefined || width <= 0) { width = 32; } + if (height === undefined || height <= 0) { height = 32; } + if (margin === undefined) { margin = 0; } + if (spacing === undefined) { spacing = 0; } - if (IsPlainObject(key)) - { - var config = key; + /** + * The name of the Image Collection. + * + * @name Phaser.Tilemaps.ImageCollection#name + * @type {string} + * @since 3.0.0 + */ + this.name = name; - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - shaderType = GetFastValue(config, 'shaderType', 'fragment'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - } - else if (shaderType === undefined) - { - shaderType = 'fragment'; - } + /** + * 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; - var fileConfig = { - type: 'glsl', - cache: loader.cacheManager.shader, - extension: extension, - responseType: 'text', - key: key, - url: url, - config: { - shaderType: shaderType - }, - xhrSettings: xhrSettings - }; + /** + * The width of the widest image (in pixels). + * + * @name Phaser.Tilemaps.ImageCollection#imageWidth + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.imageWidth = width | 0; - File.call(this, loader, fileConfig); + /** + * 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; }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * Returns true if and only if this image collection contains the given image index. * - * @method Phaser.Loader.FileTypes.GLSLFile#onProcess - * @since 3.7.0 + * @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. */ - onProcess: function () + containsImageIndex: function (imageIndex) { - this.state = CONST.FILE_PROCESSING; - - this.data = this.xhrLoader.responseText; - - this.onProcessComplete(); + return (imageIndex >= this.firstgid && imageIndex < (this.firstgid + this.total)); }, /** - * Adds this file to its target cache upon successful loading and processing. + * Add an image to this Image Collection. * - * @method Phaser.Loader.FileTypes.GLSLFile#addToCache - * @since 3.17.0 + * @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. */ - addToCache: function () + addImage: function (gid, image) { - var data = this.data.split('\n'); + this.images.push({ gid: gid, image: image }); + this.total++; - // Check to see if this is a shader bundle, or raw glsl file. - var block = this.extractBlock(data, 0); + return this; + } - if (block) - { - while (block) - { - var key = this.getShaderName(block.header); - var shaderType = this.getShaderType(block.header); - var uniforms = this.getShaderUniforms(block.header); - var shaderSrc = block.shader; +}); - if (this.cache.has(key)) - { - var shader = this.cache.get(key); +module.exports = ImageCollection; - if (shaderType === 'fragment') - { - shader.fragmentSrc = shaderSrc; - } - else - { - shader.vertexSrc = shaderSrc; - } - if (!shader.uniforms) - { - shader.uniforms = uniforms; - } - } - else if (shaderType === 'fragment') - { - this.cache.add(key, new Shader(key, shaderSrc, '', uniforms)); - } - else +/***/ }), + +/***/ 46422: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2021 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); + +/** + * @classdesc + * The ObjectHelper helps tie objects with `gids` into the tileset + * that sits behind them. + * + * @class ObjectHelper + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Tilemaps.Tileset[]} tilesets - The backing tileset data. + */ +var ObjectHelper = new Class({ + + initialize: + + function ObjectHelper (tilesets) + { + /** + * The Tile GIDs array. + * + * @name Phaser.Tilemaps.ObjectHelper#gids + * @type {array} + * @since 3.60.0 + */ + this.gids = []; + + if (tilesets !== undefined) + { + for (var t = 0; t < tilesets.length; ++t) + { + var tileset = tilesets[t]; + + for (var i = 0; i < tileset.total; ++i) { - this.cache.add(key, new Shader(key, '', shaderSrc, uniforms)); + this.gids[tileset.firstgid + i] = tileset; } - - block = this.extractBlock(data, block.offset); } } - else if (this.config.shaderType === 'fragment') + + /** + * The Tile GIDs array. + * + * @name Phaser.Tilemaps.ObjectHelper#_gids + * @type {array} + * @private + * @since 3.60.0 + */ + this._gids = this.gids; + }, + + /** + * Enabled if the object helper reaches in to tilesets for data. + * Disabled if it only uses data directly on a gid object. + * + * @name Phaser.Tilemaps.ObjectHelper#enabled + * @type {boolean} + * @since 3.60.0 + */ + enabled: { + + get: function () { - // Single shader - this.cache.add(this.key, new Shader(this.key, this.data)); - } - else + return !!this.gids; + }, + + set: function (v) { - this.cache.add(this.key, new Shader(this.key, '', this.data)); + this.gids = v ? this._gids : undefined; } - this.pendingDestroy(); }, /** - * Returns the name of the shader from the header block. + * Gets the Tiled `type` field value from the object or the `gid` behind it. * - * @method Phaser.Loader.FileTypes.GLSLFile#getShaderName - * @since 3.17.0 + * @method Phaser.Tilemaps.ObjectHelper#getTypeIncludingTile + * @since 3.60.0 * - * @param {string[]} headerSource - The header data. + * @param {Phaser.Types.Tilemaps.TiledObject} obj - The Tiled object to investigate. * - * @return {string} The shader name. + * @return {?string} The `type` of the object, the tile behind the `gid` of the object, or `undefined`. */ - getShaderName: function (headerSource) + getTypeIncludingTile: function (obj) { - for (var i = 0; i < headerSource.length; i++) + if (obj.type !== undefined && obj.type !== '') { - var line = headerSource[i].trim(); + return obj.type; + } - if (line.substring(0, 5) === 'name:') - { - return line.substring(5).trim(); - } + if (!this.gids || obj.gid === undefined) + { + return undefined; } - return this.key; + var tileset = this.gids[obj.gid]; + + if (!tileset) + { + return undefined; + } + + var tileData = tileset.getTileData(obj.gid); + + if (!tileData) + { + return undefined; + } + + return tileData.type; }, /** - * Returns the type of the shader from the header block. + * Sets the sprite texture data as specified (usually in a config) or, failing that, + * as specified in the `gid` of the object being loaded (if any). * - * @method Phaser.Loader.FileTypes.GLSLFile#getShaderType - * @since 3.17.0 + * This fallback will only work if the tileset was loaded as a spritesheet matching + * the geometry of sprites fed into tiled, so that, for example: "tile id #`3`"" within + * the tileset is the same as texture frame `3` from the image of the tileset. * - * @param {string[]} headerSource - The header data. + * @method Phaser.Tilemaps.ObjectHelper#setTextureAndFrame + * @since 3.60.0 * - * @return {string} The shader type. Either 'fragment' or 'vertex'. + * @param {Phaser.GameObjects.GameObject} sprite - The Game Object to modify. + * @param {string|Phaser.Textures.Texture} [key] - The texture key to set (or else the `obj.gid`'s tile is used if available). + * @param {string|number|Phaser.Textures.Frame} [frame] - The frames key to set (or else the `obj.gid`'s tile is used if available). + * @param {Phaser.Types.Tilemaps.TiledObject} [obj] - The Tiled object for fallback. */ - getShaderType: function (headerSource) + setTextureAndFrame: function (sprite, key, frame, obj) { - for (var i = 0; i < headerSource.length; i++) + if ((key === null) && this.gids && obj.gid !== undefined) { - var line = headerSource[i].trim(); + var tileset = this.gids[obj.gid]; - if (line.substring(0, 5) === 'type:') + if (tileset) { - return line.substring(5).trim(); + if (key === null && tileset.image !== undefined) + { + key = tileset.image.key; + } + + if (frame === null) + { + // This relies on the tileset texture *also* having been loaded as a spritesheet. This isn't guaranteed! + frame = obj.gid - tileset.firstgid; + } + + // If we can't satisfy the request, probably best to null it out rather than set a whole spritesheet or something. + if (!sprite.scene.textures.getFrame(key, frame)) + { + key = null; + frame = null; + } } } - return this.config.shaderType; + sprite.setTexture(key, frame); }, /** - * Returns the shader uniforms from the header block. - * - * @method Phaser.Loader.FileTypes.GLSLFile#getShaderUniforms - * @since 3.17.0 + * Sets the `sprite.data` field from the tiled properties on the object and its tile (if any). * - * @param {string[]} headerSource - The header data. + * @method Phaser.Tilemaps.ObjectHelper#setPropertiesFromTiledObject + * @since 3.60.0 * - * @return {any} The shader uniforms object. + * @param {Phaser.GameObjects.GameObject} sprite + * @param {Phaser.Types.Tilemaps.TiledObject} obj */ - getShaderUniforms: function (headerSource) + setPropertiesFromTiledObject: function (sprite, obj) { - var uniforms = {}; - - for (var i = 0; i < headerSource.length; i++) + if (this.gids !== undefined && obj.gid !== undefined) { - var line = headerSource[i].trim(); + var tileset = this.gids[obj.gid]; - if (line.substring(0, 8) === 'uniform.') + if (tileset !== undefined) { - var pos = line.indexOf(':'); - - if (pos) - { - var key = line.substring(8, pos); - - try - { - uniforms[key] = JSON.parse(line.substring(pos + 1)); - } - catch (e) - { - console.warn('Invalid uniform JSON: ' + key); - } - } + this.setFromJSON(sprite, tileset.getTileProperties(obj.gid)); } } - return uniforms; + this.setFromJSON(sprite, obj.properties); }, /** - * Processes the shader file and extracts the relevant data. + * Sets the sprite data from the JSON object. * - * @method Phaser.Loader.FileTypes.GLSLFile#extractBlock + * @method Phaser.Tilemaps.ObjectHelper#setFromJSON + * @since 3.60.0 * @private - * @since 3.17.0 * - * @param {string[]} data - The array of shader data to process. - * @param {number} offset - The offset to start processing from. - * - * @return {any} The processed shader block, or null. + * @param {Phaser.GameObjects.GameObject} sprite - The object for which to populate `data`. + * @param {(Object.|Object[])} properties - The properties to set in either JSON object format or else a list of objects with `name` and `value` fields. */ - extractBlock: function (data, offset) + setFromJSON: function (sprite, properties) { - var headerStart = -1; - var headerEnd = -1; - var blockEnd = -1; - var headerOpen = false; - var captureSource = false; - var headerSource = []; - var shaderSource = []; - - for (var i = offset; i < data.length; i++) + if (!properties) { - var line = data[i].trim(); + return; + } - if (line === '---') + if (Array.isArray(properties)) + { + // Tiled objects custom properties format + properties.forEach(function (propData) { - if (headerStart === -1) - { - headerStart = i; - headerOpen = true; - } - else if (headerOpen) - { - headerEnd = i; - headerOpen = false; - captureSource = true; - } - else - { - // We've hit another --- delimiter, break out - captureSource = false; - break; - } - } - else if (headerOpen) + sprite.setData(propData.name, propData.value); + }); + + return; + } + + for (var key in properties) + { + if (sprite[key] !== undefined) { - headerSource.push(line); + sprite[key] = properties[key]; } - else if (captureSource) + else { - shaderSource.push(line); - blockEnd = i; + sprite.setData(key, properties[key]); } } - - if (!headerOpen && headerEnd !== -1) - { - return { header: headerSource, shader: shaderSource.join('\n'), offset: blockEnd }; - } - else - { - return null; - } } - }); +module.exports = ObjectHelper; + + +/***/ }), + +/***/ 15043: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + /** - * Adds a GLSL file, or array of GLSL files, to the current load queue. - * In Phaser 3 GLSL files are just plain Text files at the current moment in time. - * - * 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.glsl('plasma', 'shaders/Plasma.glsl'); - * } - * ``` - * - * 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 Shader Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Shader 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 Shader Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.glsl({ - * key: 'plasma', - * shaderType: 'fragment', - * url: 'shaders/Plasma.glsl' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.GLSLFileConfig` for more details. - * - * Once the file has finished loading you can access it from its Cache using its key: - * - * ```javascript - * this.load.glsl('plasma', 'shaders/Plasma.glsl'); - * // and later in your game ... - * var data = this.cache.shader.get('plasma'); - * ``` - * - * 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 `FX.` and the key was `Plasma` the final key will be `FX.Plasma` and - * this is what you would use to retrieve the text from the Shader 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 "plasma" - * and no URL is given then the Loader will set the URL to be "plasma.glsl". It will always add `.glsl` 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 GLSL File type has been built into Phaser. - * It is available in the default build but can be excluded from custom builds. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Formats = __webpack_require__(93560); +var MapData = __webpack_require__(16586); +var Parse = __webpack_require__(90715); +var Tilemap = __webpack_require__(89797); + +/** + * Create a Tilemap from the given key or data. If neither is given, make a blank Tilemap. When + * loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing from + * a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map data. For + * an empty map, you should specify tileWidth, tileHeight, width & height. * - * @method Phaser.Loader.LoaderPlugin#glsl - * @fires Phaser.Loader.LoaderPlugin#ADD + * @function Phaser.Tilemaps.ParseToTilemap * @since 3.0.0 * - * @param {(string|Phaser.Types.Loader.FileTypes.GLSLFileConfig|Phaser.Types.Loader.FileTypes.GLSLFileConfig[])} 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 `.glsl`, i.e. if `key` was "alien" then the URL will be "alien.glsl". - * @param {string} [shaderType='fragment'] - The type of shader. Either `fragment` for a fragment shader, or `vertex` for a vertex shader. This is ignored if you load a shader bundle. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. + * @param {Phaser.Scene} scene - The Scene to which this Tilemap belongs. + * @param {string} [key] - The key in the Phaser cache that corresponds to the loaded tilemap data. + * @param {number} [tileWidth=32] - The width of a tile in pixels. + * @param {number} [tileHeight=32] - The height of a tile in pixels. + * @param {number} [width=10] - The width of the map in tiles. + * @param {number} [height=10] - The height of the map in tiles. + * @param {number[][]} [data] - Instead of loading from the cache, you can also load directly from + * a 2D array of tile indexes. + * @param {boolean} [insertNull=false] - 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 {this} The Loader instance. + * @return {Phaser.Tilemaps.Tilemap} */ -FileTypesManager.register('glsl', function (key, url, shaderType, xhrSettings) +var ParseToTilemap = function (scene, key, tileWidth, tileHeight, width, height, data, insertNull) { - if (Array.isArray(key)) + if (tileWidth === undefined) { tileWidth = 32; } + if (tileHeight === undefined) { tileHeight = 32; } + if (width === undefined) { width = 10; } + if (height === undefined) { height = 10; } + if (insertNull === undefined) { insertNull = false; } + + var mapData = null; + + if (Array.isArray(data)) { - for (var i = 0; i < key.length; i++) + var name = key !== undefined ? key : 'map'; + mapData = Parse(name, Formats.ARRAY_2D, data, tileWidth, tileHeight, insertNull); + } + else if (key !== undefined) + { + var tilemapData = scene.cache.tilemap.get(key); + + if (!tilemapData) { - // 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 GLSLFile(this, key[i])); + console.warn('No map data found for key ' + key); + } + else + { + mapData = Parse(key, tilemapData.format, tilemapData.data, tileWidth, tileHeight, insertNull); } } - else + + if (mapData === null) { - this.addFile(new GLSLFile(this, key, url, shaderType, xhrSettings)); + mapData = new MapData({ + tileWidth: tileWidth, + tileHeight: tileHeight, + width: width, + height: height + }); } - return this; -}); + return new Tilemap(scene, mapData); +}; -module.exports = GLSLFile; +module.exports = ParseToTilemap; /***/ }), -/* 1349 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 29633: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var CONST = __webpack_require__(12920); +var DeepCopy = __webpack_require__(28699); +var Rectangle = __webpack_require__(66658); /** * @classdesc - * A single HTML File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#html method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#html. + * A Tile is a representation of a single tile within the Tilemap. This is a lightweight data + * representation, so its position information is stored without factoring in scroll, layer + * scale or layer position. * - * @class HTMLFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes + * @class Tile + * @memberof Phaser.Tilemaps * @constructor - * @since 3.12.0 + * @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.HTMLFileConfig)} 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 `.html`, i.e. if `key` was "alien" then the URL will be "alien.html". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. + * @extends Phaser.GameObjects.Components.Alpha + * @extends Phaser.GameObjects.Components.Flip + * @extends Phaser.GameObjects.Components.Visible + * + * @param {Phaser.Tilemaps.LayerData} layer - The LayerData object in the Tilemap that this tile belongs to. + * @param {number} index - The unique index of this tile within the map. + * @param {number} x - The x coordinate of this tile in tile coordinates. + * @param {number} y - The y coordinate of this tile in tile coordinates. + * @param {number} width - Width of the tile in pixels. + * @param {number} height - Height of the tile in pixels. + * @param {number} baseWidth - The base width a tile in the map (in pixels). Tiled maps support + * multiple tileset sizes within one map, but they are still placed at intervals of the base + * tile width. + * @param {number} baseHeight - The base height of the tile in pixels (in pixels). Tiled maps + * support multiple tileset sizes within one map, but they are still placed at intervals of the + * base tile height. */ -var HTMLFile = new Class({ +var Tile = new Class({ + + Mixins: [ + Components.Alpha, + Components.Flip, + Components.Visible + ], + + initialize: + + function Tile (layer, index, x, y, width, height, baseWidth, baseHeight) + { + /** + * The LayerData in the Tilemap data that this tile belongs to. + * + * @name Phaser.Tilemaps.Tile#layer + * @type {Phaser.Tilemaps.LayerData} + * @since 3.0.0 + */ + this.layer = layer; + + /** + * The index of this tile within the map data corresponding to the tileset, or -1 if this + * represents a blank tile. + * + * @name Phaser.Tilemaps.Tile#index + * @type {number} + * @since 3.0.0 + */ + this.index = index; + + /** + * The x map coordinate of this tile in tile units. + * + * @name Phaser.Tilemaps.Tile#x + * @type {number} + * @since 3.0.0 + */ + this.x = x; + + /** + * The y map coordinate of this tile in tile units. + * + * @name Phaser.Tilemaps.Tile#y + * @type {number} + * @since 3.0.0 + */ + this.y = y; + + /** + * The width of the tile in pixels. + * + * @name Phaser.Tilemaps.Tile#width + * @type {number} + * @since 3.0.0 + */ + this.width = width; + + /** + * The height of the tile in pixels. + * + * @name Phaser.Tilemaps.Tile#height + * @type {number} + * @since 3.0.0 + */ + this.height = height; + + /** + * The right of the tile in pixels. + * + * Set in the `updatePixelXY` method. + * + * @name Phaser.Tilemaps.Tile#right + * @type {number} + * @since 3.50.0 + */ + this.right; + + /** + * The bottom of the tile in pixels. + * + * Set in the `updatePixelXY` method. + * + * @name Phaser.Tilemaps.Tile#bottom + * @type {number} + * @since 3.50.0 + */ + this.bottom; + + /** + * The maps base width of a tile in pixels. Tiled maps support multiple tileset sizes + * within one map, but they are still placed at intervals of the base tile size. + * + * @name Phaser.Tilemaps.Tile#baseWidth + * @type {number} + * @since 3.0.0 + */ + this.baseWidth = (baseWidth !== undefined) ? baseWidth : width; + + /** + * The maps base height of a tile in pixels. Tiled maps support multiple tileset sizes + * within one map, but they are still placed at intervals of the base tile size. + * + * @name Phaser.Tilemaps.Tile#baseHeight + * @type {number} + * @since 3.0.0 + */ + this.baseHeight = (baseHeight !== undefined) ? baseHeight : height; + + /** + * The x coordinate of the top left of this tile in pixels. This is relative to the top left + * of the layer this tile is being rendered within. This property does NOT factor in camera + * scroll, layer scale or layer position. + * + * @name Phaser.Tilemaps.Tile#pixelX + * @type {number} + * @since 3.0.0 + */ + this.pixelX = 0; + + /** + * The y coordinate of the top left of this tile in pixels. This is relative to the top left + * of the layer this tile is being rendered within. This property does NOT factor in camera + * scroll, layer scale or layer position. + * + * @name Phaser.Tilemaps.Tile#pixelY + * @type {number} + * @since 3.0.0 + */ + this.pixelY = 0; + + this.updatePixelXY(); + + /** + * Tile specific properties. These usually come from Tiled. + * + * @name Phaser.Tilemaps.Tile#properties + * @type {any} + * @since 3.0.0 + */ + this.properties = {}; + + /** + * The rotation angle of this tile. + * + * @name Phaser.Tilemaps.Tile#rotation + * @type {number} + * @since 3.0.0 + */ + this.rotation = 0; + + /** + * Whether the tile should collide with any object on the left side. + * + * This property is used by Arcade Physics only, however, you can also use it + * in your own checks. + * + * @name Phaser.Tilemaps.Tile#collideLeft + * @type {boolean} + * @since 3.0.0 + */ + this.collideLeft = false; + + /** + * Whether the tile should collide with any object on the right side. + * + * This property is used by Arcade Physics only, however, you can also use it + * in your own checks. + * + * @name Phaser.Tilemaps.Tile#collideRight + * @type {boolean} + * @since 3.0.0 + */ + this.collideRight = false; + + /** + * Whether the tile should collide with any object on the top side. + * + * This property is used by Arcade Physics only, however, you can also use it + * in your own checks. + * + * @name Phaser.Tilemaps.Tile#collideUp + * @type {boolean} + * @since 3.0.0 + */ + this.collideUp = false; + + /** + * Whether the tile should collide with any object on the bottom side. + * + * This property is used by Arcade Physics only, however, you can also use it + * in your own checks. + * + * @name Phaser.Tilemaps.Tile#collideDown + * @type {boolean} + * @since 3.0.0 + */ + this.collideDown = false; + + /** + * Whether the tiles left edge is interesting for collisions. + * + * @name Phaser.Tilemaps.Tile#faceLeft + * @type {boolean} + * @since 3.0.0 + */ + this.faceLeft = false; - Extends: File, + /** + * Whether the tiles right edge is interesting for collisions. + * + * @name Phaser.Tilemaps.Tile#faceRight + * @type {boolean} + * @since 3.0.0 + */ + this.faceRight = false; - initialize: + /** + * Whether the tiles top edge is interesting for collisions. + * + * @name Phaser.Tilemaps.Tile#faceTop + * @type {boolean} + * @since 3.0.0 + */ + this.faceTop = false; - function HTMLFile (loader, key, url, xhrSettings) - { - var extension = 'html'; + /** + * Whether the tiles bottom edge is interesting for collisions. + * + * @name Phaser.Tilemaps.Tile#faceBottom + * @type {boolean} + * @since 3.0.0 + */ + this.faceBottom = false; - if (IsPlainObject(key)) - { - var config = key; + /** + * Tile collision callback. + * + * @name Phaser.Tilemaps.Tile#collisionCallback + * @type {function} + * @since 3.0.0 + */ + this.collisionCallback = undefined; - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - } + /** + * The context in which the collision callback will be called. + * + * @name Phaser.Tilemaps.Tile#collisionCallbackContext + * @type {object} + * @since 3.0.0 + */ + this.collisionCallbackContext = this; - var fileConfig = { - type: 'text', - cache: loader.cacheManager.html, - extension: extension, - responseType: 'text', - key: key, - url: url, - xhrSettings: xhrSettings - }; + /** + * The tint to apply to this tile. Note: tint is currently a single color value instead of + * the 4 corner tint component on other GameObjects. + * + * @name Phaser.Tilemaps.Tile#tint + * @type {number} + * @default + * @since 3.0.0 + */ + this.tint = 0xffffff; - File.call(this, loader, fileConfig); + /** + * An empty object where physics-engine specific information (e.g. bodies) may be stored. + * + * @name Phaser.Tilemaps.Tile#physics + * @type {object} + * @since 3.0.0 + */ + this.physics = {}; }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * Check if the given x and y world coordinates are within this Tile. This does not factor in + * camera scroll, layer scale or layer position. * - * @method Phaser.Loader.FileTypes.HTMLFile#onProcess - * @since 3.7.0 + * @method Phaser.Tilemaps.Tile#containsPoint + * @since 3.0.0 + * + * @param {number} x - The x coordinate to test. + * @param {number} y - The y coordinate to test. + * + * @return {boolean} True if the coordinates are within this Tile, otherwise false. */ - onProcess: function () + containsPoint: function (x, y) { - this.state = CONST.FILE_PROCESSING; - - this.data = this.xhrLoader.responseText; - - this.onProcessComplete(); - } - -}); + return !(x < this.pixelX || y < this.pixelY || x > this.right || y > this.bottom); + }, -/** - * Adds an HTML file, or array of HTML 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.html('story', 'files/LoginForm.html'); - * } - * ``` - * - * 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 HTML Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the HTML 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 HTML Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.html({ - * key: 'login', - * url: 'files/LoginForm.html' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.HTMLFileConfig` for more details. - * - * Once the file has finished loading you can access it from its Cache using its key: - * - * ```javascript - * this.load.html('login', 'files/LoginForm.html'); - * // and later in your game ... - * var data = this.cache.html.get('login'); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and - * this is what you would use to retrieve the html from the HTML Cache. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story" - * and no URL is given then the Loader will set the URL to be "story.html". It will always add `.html` 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 HTML 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#html - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.12.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.HTMLFileConfig|Phaser.Types.Loader.FileTypes.HTMLFileConfig[])} 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 `.html`, i.e. if `key` was "alien" then the URL will be "alien.html". - * @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('html', 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 HTMLFile(this, key[i])); - } - } - else + /** + * Copies the tile data and properties from the given Tile to this Tile. This copies everything + * except for position and interesting face calculations. + * + * @method Phaser.Tilemaps.Tile#copy + * @since 3.0.0 + * + * @param {Phaser.Tilemaps.Tile} tile - The tile to copy from. + * + * @return {this} This Tile object instance. + */ + copy: function (tile) { - this.addFile(new HTMLFile(this, key, url, xhrSettings)); - } - - return this; -}); - -module.exports = HTMLFile; - - -/***/ }), -/* 1350 */ -/***/ (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__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); - -/** - * @classdesc - * A single HTML File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#htmlTexture method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#htmlTexture. - * - * @class HTMLTextureFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.12.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.HTMLTextureFileConfig)} 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 `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {number} [width] - The width of the texture the HTML will be rendered to. - * @param {number} [height] - The height of the texture the HTML will be rendered to. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var HTMLTextureFile = new Class({ + this.index = tile.index; + this.alpha = tile.alpha; + this.properties = DeepCopy(tile.properties); + this.visible = tile.visible; + this.setFlip(tile.flipX, tile.flipY); + this.tint = tile.tint; + this.rotation = tile.rotation; + this.collideUp = tile.collideUp; + this.collideDown = tile.collideDown; + this.collideLeft = tile.collideLeft; + this.collideRight = tile.collideRight; + this.collisionCallback = tile.collisionCallback; + this.collisionCallbackContext = tile.collisionCallbackContext; - Extends: File, + return this; + }, - initialize: + /** + * The collision group for this Tile, defined within the Tileset. This returns a reference to + * the collision group stored within the Tileset, so any modification of the returned object + * will impact all tiles that have the same index as this tile. + * + * @method Phaser.Tilemaps.Tile#getCollisionGroup + * @since 3.0.0 + * + * @return {?object} The collision group for this Tile, as defined in the Tileset, or `null` if no group was defined. + */ + getCollisionGroup: function () + { + return this.tileset ? this.tileset.getTileCollisionGroup(this.index) : null; + }, - function HTMLTextureFile (loader, key, url, width, height, xhrSettings) + /** + * The tile data for this Tile, defined within the Tileset. This typically contains Tiled + * collision data, tile animations and terrain information. This returns a reference to the tile + * data stored within the Tileset, so any modification of the returned object will impact all + * tiles that have the same index as this tile. + * + * @method Phaser.Tilemaps.Tile#getTileData + * @since 3.0.0 + * + * @return {?object} The tile data for this Tile, as defined in the Tileset, or `null` if no data was defined. + */ + getTileData: function () { - if (width === undefined) { width = 512; } - if (height === undefined) { height = 512; } + return this.tileset ? this.tileset.getTileData(this.index) : null; + }, - var extension = 'html'; + /** + * Gets the world X position of the left side of the tile, factoring in the layers position, + * scale and scroll. + * + * @method Phaser.Tilemaps.Tile#getLeft + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * + * @return {number} The left (x) value of this tile. + */ + getLeft: function (camera) + { + var tilemapLayer = this.tilemapLayer; - if (IsPlainObject(key)) + if (tilemapLayer) { - var config = key; + var point = tilemapLayer.tileToWorldXY(this.x, this.y, undefined, camera); - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - width = GetFastValue(config, 'width', width); - height = GetFastValue(config, 'height', height); + return point.x; } - var fileConfig = { - type: 'html', - cache: loader.textureManager, - extension: extension, - responseType: 'text', - key: key, - url: url, - xhrSettings: xhrSettings, - config: { - width: width, - height: height - } - }; - - File.call(this, loader, fileConfig); + return this.x * this.baseWidth; }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * Gets the world X position of the right side of the tile, factoring in the layer's position, + * scale and scroll. * - * @method Phaser.Loader.FileTypes.HTMLTextureFile#onProcess - * @since 3.7.0 + * @method Phaser.Tilemaps.Tile#getRight + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * + * @return {number} The right (x) value of this tile. */ - onProcess: function () + getRight: function (camera) { - this.state = CONST.FILE_PROCESSING; - - var w = this.config.width; - var h = this.config.height; - - var data = []; + var tilemapLayer = this.tilemapLayer; - data.push(''); - data.push(''); - data.push(''); - data.push(this.xhrLoader.responseText); - data.push(''); - data.push(''); - data.push(''); + return (tilemapLayer) ? this.getLeft(camera) + this.width * tilemapLayer.scaleX : this.getLeft(camera) + this.width; + }, - var svg = [ data.join('\n') ]; - var _this = this; + /** + * Gets the world Y position of the top side of the tile, factoring in the layer's position, + * scale and scroll. + * + * @method Phaser.Tilemaps.Tile#getTop + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * + * @return {number} The top (y) value of this tile. + */ + getTop: function (camera) + { + var tilemapLayer = this.tilemapLayer; - try - { - var blob = new window.Blob(svg, { type: 'image/svg+xml;charset=utf-8' }); - } - catch (e) + // Tiled places tiles on a grid of baseWidth x baseHeight. The origin for a tile in grid + // units is the bottom left, so the y coordinate needs to be adjusted by the difference + // between the base size and this tile's size. + if (tilemapLayer) { - _this.state = CONST.FILE_ERRORED; - - _this.onProcessComplete(); + var point = tilemapLayer.tileToWorldXY(this.x, this.y, undefined, camera); - return; + return point.y; } - this.data = new Image(); + return this.y * this.baseWidth - (this.height - this.baseHeight); + }, - this.data.crossOrigin = this.crossOrigin; + /** + * Gets the world Y position of the bottom side of the tile, factoring in the layer's position, + * scale and scroll. - this.data.onload = function () - { - File.revokeObjectURL(_this.data); + * @method Phaser.Tilemaps.Tile#getBottom + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * + * @return {number} The bottom (y) value of this tile. + */ + getBottom: function (camera) + { + var tilemapLayer = this.tilemapLayer; - _this.onProcessComplete(); - }; + return tilemapLayer + ? this.getTop(camera) + this.height * tilemapLayer.scaleY + : this.getTop(camera) + this.height; + }, - this.data.onerror = function () - { - File.revokeObjectURL(_this.data); + /** + * Gets the world rectangle bounding box for the tile, factoring in the layers position, + * scale and scroll. + * + * @method Phaser.Tilemaps.Tile#getBounds + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * @param {Phaser.Geom.Rectangle} [output] - Optional Rectangle object to store the results in. + * + * @return {(Phaser.Geom.Rectangle|object)} The bounds of this Tile. + */ + getBounds: function (camera, output) + { + if (output === undefined) { output = new Rectangle(); } - _this.onProcessError(); - }; + output.x = this.getLeft(camera); + output.y = this.getTop(camera); + output.width = this.getRight(camera) - output.x; + output.height = this.getBottom(camera) - output.y; - File.createObjectURL(this.data, blob, 'image/svg+xml'); + return output; }, /** - * Adds this file to its target cache upon successful loading and processing. + * Gets the world X position of the center of the tile, factoring in the layer's position, + * scale and scroll. * - * @method Phaser.Loader.FileTypes.HTMLTextureFile#addToCache - * @since 3.7.0 + * @method Phaser.Tilemaps.Tile#getCenterX + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * + * @return {number} The center x position of this Tile. */ - addToCache: function () + getCenterX: function (camera) { - var texture = this.cache.addImage(this.key, this.data); + return (this.getLeft(camera) + this.getRight(camera)) / 2; + }, - this.pendingDestroy(texture); - } + /** + * Gets the world Y position of the center of the tile, factoring in the layer's position, + * scale and scroll. + * + * @method Phaser.Tilemaps.Tile#getCenterY + * @since 3.0.0 + * + * @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check. + * + * @return {number} The center y position of this Tile. + */ + getCenterY: function (camera) + { + return (this.getTop(camera) + this.getBottom(camera)) / 2; + }, -}); + /** + * Check for intersection with this tile. This does not factor in camera scroll, layer scale or + * layer position. + * + * @method Phaser.Tilemaps.Tile#intersects + * @since 3.0.0 + * + * @param {number} x - The x axis in pixels. + * @param {number} y - The y axis in pixels. + * @param {number} right - The right point. + * @param {number} bottom - The bottom point. + * + * @return {boolean} `true` if the Tile intersects with the given dimensions, otherwise `false`. + */ + intersects: function (x, y, right, bottom) + { + return !( + right <= this.pixelX || bottom <= this.pixelY || + x >= this.right || y >= this.bottom + ); + }, -/** - * Adds an HTML File, or array of HTML Files, to the current load queue. When the files are loaded they - * will be rendered to textures and stored in the Texture Manager. - * - * 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.htmlTexture('instructions', 'content/intro.html', 256, 512); - * } - * ``` - * - * 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 Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.htmlTexture({ - * key: 'instructions', - * url: 'content/intro.html', - * width: 256, - * height: 512 - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.HTMLTextureFileConfig` for more details. - * - * Once the file has finished loading you can use it as a texture for a Game Object by referencing its key: - * - * ```javascript - * this.load.htmlTexture('instructions', 'content/intro.html', 256, 512); - * // and later in your game ... - * this.add.image(x, y, 'instructions'); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.html". It will always add `.html` 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. - * - * The width and height are the size of the texture to which the HTML will be rendered. It's not possible to determine these - * automatically, so you will need to provide them, either as arguments or in the file config object. - * When the HTML file has loaded a new SVG element is created with a size and viewbox set to the width and height given. - * The SVG file has a body tag added to it, with the HTML file contents included. It then calls `window.Blob` on the SVG, - * and if successful is added to the Texture Manager, otherwise it fails processing. The overall quality of the rendered - * HTML depends on your browser, and some of them may not even support the svg / blob process used. Be aware that there are - * limitations on what HTML can be inside an SVG. You can find out more details in this - * [Mozilla MDN entry](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas). - * - * Note: The ability to load this type of file will only be available if the HTMLTextureFile 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#htmlTexture - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.12.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.HTMLTextureFileConfig|Phaser.Types.Loader.FileTypes.HTMLTextureFileConfig[])} 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 `.html`, i.e. if `key` was "alien" then the URL will be "alien.html". - * @param {number} [width=512] - The width of the texture the HTML will be rendered to. - * @param {number} [height=512] - The height of the texture the HTML will be rendered to. - * @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('htmlTexture', function (key, url, width, height, xhrSettings) -{ - if (Array.isArray(key)) + /** + * Checks if the tile is interesting. + * + * @method Phaser.Tilemaps.Tile#isInteresting + * @since 3.0.0 + * + * @param {boolean} collides - If true, will consider the tile interesting if it collides on any side. + * @param {boolean} faces - If true, will consider the tile interesting if it has an interesting face. + * + * @return {boolean} True if the Tile is interesting, otherwise false. + */ + isInteresting: function (collides, faces) { - for (var i = 0; i < key.length; i++) + if (collides && faces) { - // 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 HTMLTextureFile(this, key[i])); + return (this.canCollide || this.hasInterestingFace); + } + else if (collides) + { + return this.collides; + } + else if (faces) + { + return this.hasInterestingFace; } - } - else - { - this.addFile(new HTMLTextureFile(this, key, url, width, height, xhrSettings)); - } - - return this; -}); - -module.exports = HTMLTextureFile; - - -/***/ }), -/* 1351 */ -/***/ (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 FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(71); -var IsPlainObject = __webpack_require__(7); -var JSONFile = __webpack_require__(61); -var MultiFile = __webpack_require__(49); + return false; + }, -/** - * @classdesc - * A single Multi Texture Atlas File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#multiatlas method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#multiatlas. - * - * @class MultiAtlasFile - * @extends Phaser.Loader.MultiFile - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.7.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.MultiAtlasFileConfig)} key - The key of the file. Must be unique within both the Loader and the Texture Manager. Or a config object. - * @param {string} [atlasURL] - The absolute or relative URL to load the multi atlas json file from. - * @param {string} [path] - Optional path to use when loading the textures defined in the atlas data. - * @param {string} [baseURL] - Optional Base URL to use when loading the textures defined in the atlas data. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - Extra XHR Settings specifically for the atlas json file. - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - Extra XHR Settings specifically for the texture files. - */ -var MultiAtlasFile = new Class({ + /** + * Reset collision status flags. + * + * @method Phaser.Tilemaps.Tile#resetCollision + * @since 3.0.0 + * + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate interesting faces for this tile and its neighbors. + * + * @return {this} This Tile object instance. + */ + resetCollision: function (recalculateFaces) + { + if (recalculateFaces === undefined) { recalculateFaces = true; } - Extends: MultiFile, + this.collideLeft = false; + this.collideRight = false; + this.collideUp = false; + this.collideDown = false; - initialize: + this.faceTop = false; + this.faceBottom = false; + this.faceLeft = false; + this.faceRight = false; - function MultiAtlasFile (loader, key, atlasURL, path, baseURL, atlasXhrSettings, textureXhrSettings) - { - if (IsPlainObject(key)) + if (recalculateFaces) { - var config = key; - - key = GetFastValue(config, 'key'); + var tilemapLayer = this.tilemapLayer; - if (GetFastValue(config, 'url', false)) - { - atlasURL = GetFastValue(config, 'url'); - } - else + if (tilemapLayer) { - atlasURL = GetFastValue(config, 'atlasURL'); + this.tilemapLayer.calculateFacesAt(this.x, this.y); } - - atlasXhrSettings = GetFastValue(config, 'xhrSettings'); - path = GetFastValue(config, 'path'); - baseURL = GetFastValue(config, 'baseURL'); - textureXhrSettings = GetFastValue(config, 'textureXhrSettings'); } - var data = new JSONFile(loader, key, atlasURL, atlasXhrSettings); - - MultiFile.call(this, loader, 'multiatlas', key, [ data ]); - - this.config.path = path; - this.config.baseURL = baseURL; - this.config.textureXhrSettings = textureXhrSettings; + return this; }, /** - * Called by each File when it finishes loading. + * Reset faces. * - * @method Phaser.Loader.FileTypes.MultiAtlasFile#onFileComplete - * @since 3.7.0 + * @method Phaser.Tilemaps.Tile#resetFaces + * @since 3.0.0 * - * @param {Phaser.Loader.File} file - The File that has completed processing. + * @return {this} This Tile object instance. */ - onFileComplete: function (file) + resetFaces: function () { - var index = this.files.indexOf(file); - - if (index !== -1) - { - this.pending--; - - if (file.type === 'json' && file.data.hasOwnProperty('textures')) - { - // Inspect the data for the files to now load - var textures = file.data.textures; - - var config = this.config; - var loader = this.loader; - - var currentBaseURL = loader.baseURL; - var currentPath = loader.path; - var currentPrefix = loader.prefix; - - var baseURL = GetFastValue(config, 'baseURL', this.baseURL); - var path = GetFastValue(config, 'path', this.path); - var prefix = GetFastValue(config, 'prefix', this.prefix); - var textureXhrSettings = GetFastValue(config, 'textureXhrSettings'); + this.faceTop = false; + this.faceBottom = false; + this.faceLeft = false; + this.faceRight = false; - loader.setBaseURL(baseURL); - loader.setPath(path); - loader.setPrefix(prefix); + return this; + }, - for (var i = 0; i < textures.length; i++) - { - // "image": "texture-packer-multi-atlas-0.png", - var textureURL = textures[i].image; + /** + * Sets the collision flags for each side of this tile and updates the interesting faces list. + * + * @method Phaser.Tilemaps.Tile#setCollision + * @since 3.0.0 + * + * @param {boolean} left - Indicating collide with any object on the left. + * @param {boolean} [right] - Indicating collide with any object on the right. + * @param {boolean} [up] - Indicating collide with any object on the top. + * @param {boolean} [down] - Indicating collide with any object on the bottom. + * @param {boolean} [recalculateFaces=true] - Whether or not to recalculate interesting faces for this tile and its neighbors. + * + * @return {this} This Tile object instance. + */ + setCollision: function (left, right, up, down, recalculateFaces) + { + if (right === undefined) { right = left; } + if (up === undefined) { up = left; } + if (down === undefined) { down = left; } + if (recalculateFaces === undefined) { recalculateFaces = true; } - var key = 'MA' + this.multiKeyIndex + '_' + textureURL; + this.collideLeft = left; + this.collideRight = right; + this.collideUp = up; + this.collideDown = down; - var image = new ImageFile(loader, key, textureURL, textureXhrSettings); + this.faceLeft = left; + this.faceRight = right; + this.faceTop = up; + this.faceBottom = down; - this.addToMultiFile(image); + if (recalculateFaces) + { + var tilemapLayer = this.tilemapLayer; - loader.addFile(image); + if (tilemapLayer) + { + this.tilemapLayer.calculateFacesAt(this.x, this.y); + } + } - // "normalMap": "texture-packer-multi-atlas-0_n.png", - if (textures[i].normalMap) - { - var normalMap = new ImageFile(loader, key, textures[i].normalMap, textureXhrSettings); + return this; + }, - normalMap.type = 'normalMap'; + /** + * Set a callback to be called when this tile is hit by an object. The callback must true for + * collision processing to take place. + * + * @method Phaser.Tilemaps.Tile#setCollisionCallback + * @since 3.0.0 + * + * @param {function} callback - Callback function. + * @param {object} context - Callback will be called within this context. + * + * @return {this} This Tile object instance. + */ + setCollisionCallback: function (callback, context) + { + if (callback === null) + { + this.collisionCallback = undefined; + this.collisionCallbackContext = undefined; + } + else + { + this.collisionCallback = callback; + this.collisionCallbackContext = context; + } - image.setLink(normalMap); + return this; + }, - this.addToMultiFile(normalMap); + /** + * Sets the size of the tile and updates its pixelX and pixelY. + * + * @method Phaser.Tilemaps.Tile#setSize + * @since 3.0.0 + * + * @param {number} tileWidth - The width of the tile in pixels. + * @param {number} tileHeight - The height of the tile in pixels. + * @param {number} baseWidth - The base width a tile in the map (in pixels). + * @param {number} baseHeight - The base height of the tile in pixels (in pixels). + * + * @return {this} This Tile object instance. + */ + setSize: function (tileWidth, tileHeight, baseWidth, baseHeight) + { + if (tileWidth !== undefined) { this.width = tileWidth; } + if (tileHeight !== undefined) { this.height = tileHeight; } + if (baseWidth !== undefined) { this.baseWidth = baseWidth; } + if (baseHeight !== undefined) { this.baseHeight = baseHeight; } - loader.addFile(normalMap); - } - } + this.updatePixelXY(); - // Reset the loader settings - loader.setBaseURL(currentBaseURL); - loader.setPath(currentPath); - loader.setPrefix(currentPrefix); - } - } + return this; }, /** - * Adds this file to its target cache upon successful loading and processing. + * Used internally. Updates the tiles world XY position based on the current tile size. * - * @method Phaser.Loader.FileTypes.MultiAtlasFile#addToCache - * @since 3.7.0 + * @method Phaser.Tilemaps.Tile#updatePixelXY + * @since 3.0.0 + * + * @return {this} This Tile object instance. */ - addToCache: function () + updatePixelXY: function () { - if (this.isReadyToProcess()) + var orientation = this.layer.orientation; + + if (orientation === CONST.ORTHOGONAL) { - var fileJSON = this.files[0]; + // In orthogonal mode, Tiled places tiles on a grid of baseWidth x baseHeight. The origin for a tile is the + // bottom left, while the Phaser renderer assumes the origin is the top left. The y + // coordinate needs to be adjusted by the difference. - var data = []; - var images = []; - var normalMaps = []; + this.pixelX = this.x * this.baseWidth; + this.pixelY = this.y * this.baseHeight; + } + else if (orientation === CONST.ISOMETRIC) + { + // Reminder: For the tilemap to be centered we have to move the image to the right with the camera! + // This is crucial for wordtotile, tiletoworld to work. - for (var i = 1; i < this.files.length; i++) + this.pixelX = (this.x - this.y) * this.baseWidth * 0.5; + this.pixelY = (this.x + this.y) * this.baseHeight * 0.5; + } + else if (orientation === CONST.STAGGERED) + { + this.pixelX = this.x * this.baseWidth + this.y % 2 * (this.baseWidth / 2); + this.pixelY = this.y * (this.baseHeight / 2); + } + else if (orientation === CONST.HEXAGONAL) + { + var staggerAxis = this.layer.staggerAxis; + var staggerIndex = this.layer.staggerIndex; + var len = this.layer.hexSideLength; + var rowWidth; + var rowHeight; + + if (staggerAxis === 'y') { - var file = this.files[i]; + rowHeight = ((this.baseHeight - len) / 2 + len); - if (file.type === 'normalMap') + if (staggerIndex === 'odd') { - continue; + this.pixelX = this.x * this.baseWidth + this.y % 2 * (this.baseWidth / 2); } - - var pos = file.key.indexOf('_'); - var key = file.key.substr(pos + 1); - - var image = file.data; - - // Now we need to find out which json entry this mapped to - for (var t = 0; t < fileJSON.data.textures.length; t++) + else { - var item = fileJSON.data.textures[t]; - - if (item.image === key) - { - images.push(image); - - data.push(item); - - if (file.linkFile) - { - normalMaps.push(file.linkFile.data); - } - - break; - } + this.pixelX = this.x * this.baseWidth - this.y % 2 * (this.baseWidth / 2); } - } - if (normalMaps.length === 0) - { - normalMaps = undefined; + this.pixelY = this.y * rowHeight; } - - this.loader.textureManager.addAtlasJSONArray(this.key, images, data, normalMaps); - - this.complete = true; - - for (i = 0; i < this.files.length; i++) + else if (staggerAxis === 'x') { - this.files[i].pendingDestroy(); - } - } - } - -}); - -/** - * Adds a Multi Texture Atlas, or array of multi atlases, 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.multiatlas('level1', 'images/Level1.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. - * - * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring - * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. - * - * Phaser expects the atlas data to be provided in a JSON file as exported from the application Texture Packer, - * version 4.6.3 or above, where you have made sure to use the Phaser 3 Export option. - * - * The way it works internally is that you provide a URL to the JSON file. Phaser then loads this JSON, parses it and - * extracts which texture files it also needs to load to complete the process. If the JSON also defines normal maps, - * Phaser will load those as well. - * - * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.multiatlas({ - * key: 'level1', - * atlasURL: 'images/Level1.json' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.MultiAtlasFileConfig` for more details. - * - * Instead of passing a URL for the atlas JSON data you can also pass in a well formed JSON object instead. - * - * Once the atlas has finished loading you can use frames from it as textures for a Game Object by referencing its key: - * - * ```javascript - * this.load.multiatlas('level1', 'images/Level1.json'); - * // and later in your game ... - * this.add.image(x, y, 'level1', 'background'); - * ``` - * - * To get a list of all available frames within an atlas please consult your Texture Atlas software. - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Note: The ability to load this type of file will only be available if the Multi Atlas 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#multiatlas - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.7.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.MultiAtlasFileConfig|Phaser.Types.Loader.FileTypes.MultiAtlasFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas json data 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". - * @param {string} [path] - Optional path to use when loading the textures defined in the atlas data. - * @param {string} [baseURL] - Optional Base URL to use when loading the textures defined in the atlas data. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas json file. Used in replacement of the Loaders default XHR Settings. - * - * @return {this} The Loader instance. - */ -FileTypesManager.register('multiatlas', function (key, atlasURL, path, baseURL, atlasXhrSettings) -{ - var multifile; - - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined + rowWidth = ((this.baseWidth - len) / 2 + len); - if (Array.isArray(key)) - { - for (var i = 0; i < key.length; i++) - { - multifile = new MultiAtlasFile(this, key[i]); + this.pixelX = this.x * rowWidth; - this.addFile(multifile.files); + if (staggerIndex === 'odd') + { + this.pixelY = this.y * this.baseHeight + this.x % 2 * (this.baseHeight / 2); + } + else + { + this.pixelY = this.y * this.baseHeight - this.x % 2 * (this.baseHeight / 2); + } + } } - } - else - { - multifile = new MultiAtlasFile(this, key, atlasURL, path, baseURL, atlasXhrSettings); - - this.addFile(multifile.files); - } - return this; -}); + this.right = this.pixelX + this.baseWidth; + this.bottom = this.pixelY + this.baseHeight; -module.exports = MultiAtlasFile; + return this; + }, + /** + * Clean up memory. + * + * @method Phaser.Tilemaps.Tile#destroy + * @since 3.0.0 + */ + destroy: function () + { + this.collisionCallback = undefined; + this.collisionCallbackContext = undefined; + this.properties = undefined; + }, -/***/ }), -/* 1352 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * True if this tile can collide on any of its faces or has a collision callback set. + * + * @name Phaser.Tilemaps.Tile#canCollide + * @type {boolean} + * @readonly + * @since 3.0.0 + */ + canCollide: { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + get: function () + { + return (this.collideLeft || this.collideRight || this.collideUp || this.collideDown || (this.collisionCallback !== undefined)); + } -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); -var MultiFile = __webpack_require__(49); -var ScriptFile = __webpack_require__(520); + }, -/** - * @classdesc - * A Multi Script File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#scripts method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#scripts. - * - * @class MultiScriptFile - * @extends Phaser.Loader.MultiFile - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.17.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.MultiScriptFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string[]} [url] - An array of absolute or relative URLs to load the script files from. They are processed in the order given in the array. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object for the script files. Used in replacement of the Loaders default XHR Settings. - */ -var MultiScriptFile = new Class({ + /** + * True if this tile can collide on any of its faces. + * + * @name Phaser.Tilemaps.Tile#collides + * @type {boolean} + * @readonly + * @since 3.0.0 + */ + collides: { - Extends: MultiFile, + get: function () + { + return (this.collideLeft || this.collideRight || this.collideUp || this.collideDown); + } - initialize: + }, - function MultiScriptFile (loader, key, url, xhrSettings) - { - var extension = 'js'; - var files = []; + /** + * True if this tile has any interesting faces. + * + * @name Phaser.Tilemaps.Tile#hasInterestingFace + * @type {boolean} + * @readonly + * @since 3.0.0 + */ + hasInterestingFace: { - if (IsPlainObject(key)) + get: function () { - var config = key; - - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); + return (this.faceTop || this.faceBottom || this.faceLeft || this.faceRight); } - if (!Array.isArray(url)) - { - url = [ url ]; - } + }, - for (var i = 0; i < url.length; i++) + /** + * The tileset that contains this Tile. This is null if accessed from a LayerData instance + * before the tile is placed in a TilemapLayer, or if the tile has an index that doesn't correspond + * to any of the maps tilesets. + * + * @name Phaser.Tilemaps.Tile#tileset + * @type {?Phaser.Tilemaps.Tileset} + * @readonly + * @since 3.0.0 + */ + tileset: { + + get: function () { - var scriptFile = new ScriptFile(loader, { - key: key + '_' + i.toString(), - url: url[i], - extension: extension, - xhrSettings: xhrSettings - }); + var tilemapLayer = this.layer.tilemapLayer; - // Override the default onProcess function - scriptFile.onProcess = function () + if (tilemapLayer) { - this.onProcessComplete(); - }; + var tileset = tilemapLayer.gidMap[this.index]; - files.push(scriptFile); + if (tileset) + { + return tileset; + } + } + + return null; } - MultiFile.call(this, loader, 'scripts', key, files); }, /** - * Adds this file to its target cache upon successful loading and processing. + * The tilemap layer that contains this Tile. This will only return null if accessed from a + * LayerData instance before the tile is placed within a TilemapLayer. * - * @method Phaser.Loader.FileTypes.MultiScriptFile#addToCache - * @since 3.17.0 + * @name Phaser.Tilemaps.Tile#tilemapLayer + * @type {?Phaser.Tilemaps.TilemapLayer} + * @readonly + * @since 3.0.0 */ - addToCache: function () - { - if (this.isReadyToProcess()) + tilemapLayer: { + + get: function () { - for (var i = 0; i < this.files.length; i++) - { - var file = this.files[i]; + return this.layer.tilemapLayer; + } - file.data = document.createElement('script'); - file.data.language = 'javascript'; - file.data.type = 'text/javascript'; - file.data.defer = false; - file.data.text = file.xhrLoader.responseText; + }, - document.head.appendChild(file.data); - } + /** + * The tilemap that contains this Tile. This will only return null if accessed from a LayerData + * instance before the tile is placed within a TilemapLayer. + * + * @name Phaser.Tilemaps.Tile#tilemap + * @type {?Phaser.Tilemaps.Tilemap} + * @readonly + * @since 3.0.0 + */ + tilemap: { - this.complete = true; + get: function () + { + var tilemapLayer = this.tilemapLayer; + + return tilemapLayer ? tilemapLayer.tilemap : null; } + } }); +module.exports = Tile; + + +/***/ }), + +/***/ 89797: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + /** - * Adds an array of Script files to the current load queue. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var BuildTilesetIndex = __webpack_require__(14556); +var Class = __webpack_require__(56694); +var DegToRad = __webpack_require__(75606); +var Formats = __webpack_require__(93560); +var GetFastValue = __webpack_require__(72632); +var LayerData = __webpack_require__(94990); +var ObjectHelper = __webpack_require__(46422); +var ORIENTATION = __webpack_require__(12920); +var Rotate = __webpack_require__(52257); +var SpliceOne = __webpack_require__(72677); +var Sprite = __webpack_require__(13747); +var Tile = __webpack_require__(29633); +var TilemapComponents = __webpack_require__(5047); +var TilemapLayer = __webpack_require__(87177); +var Tileset = __webpack_require__(47975); + +/** + * A predicate, to test each element of the array. * - * The difference between this and the `ScriptFile` file type is that you give an array of scripts to this method, - * and the scripts are then processed _exactly_ in that order. This allows you to load a bunch of scripts that - * may have dependencies on each other without worrying about the async nature of traditional script loading. + * @callback TilemapFilterCallback * - * You can call this method from within your Scene's `preload`, along with any other files you wish to load: + * @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. * - * ```javascript - * function preload () - * { - * this.load.scripts('PostProcess', [ - * 'libs/shaders/CopyShader.js', - * 'libs/postprocessing/EffectComposer.js', - * 'libs/postprocessing/RenderPass.js', - * 'libs/postprocessing/MaskPass.js', - * 'libs/postprocessing/ShaderPass.js', - * 'libs/postprocessing/AfterimagePass.js' - * ]); - * } - * ``` + * @return {boolean} A value that coerces to `true` to keep the element, or to `false` otherwise. + */ + +/** + * @callback TilemapFindCallback * - * In the code above the script files will all be loaded in parallel but only processed (i.e. invoked) in the exact - * order given in the array. + * @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. * - * The files are **not** loaded right away. They are 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 files are queued - * it means you cannot use the files immediately after calling this method, but must wait for the files 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. + * @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 key must be a unique String and not already in-use by another file in the Loader. + * 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 * - * Instead of passing arguments you can pass a configuration object, such as: + * As of Phaser 3.50.0 the Tilemap API now supports the following types of map: * - * ```javascript - * this.load.scripts({ - * key: 'PostProcess', - * url: [ - * 'libs/shaders/CopyShader.js', - * 'libs/postprocessing/EffectComposer.js', - * 'libs/postprocessing/RenderPass.js', - * 'libs/postprocessing/MaskPass.js', - * 'libs/postprocessing/ShaderPass.js', - * 'libs/postprocessing/AfterimagePass.js' - * ] - * }); - * ``` + * 1) Orthogonal + * 2) Isometric + * 3) Hexagonal + * 4) Staggered * - * See the documentation for `Phaser.Types.Loader.FileTypes.MultiScriptFileConfig` for more details. + * Prior to this release, only orthogonal maps were supported. * - * Once all the files have finished loading they will automatically be converted into a script element - * via `document.createElement('script')`. They will have their 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. This is done in the exact order the files are specified in the url array. + * 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. * - * The URLs can be relative or absolute. If the URLs are relative the `Loader.baseURL` and `Loader.path` values will be prepended to them. + * 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: The ability to load this type of file will only be available if the MultiScript File type has been built into Phaser. - * It is available in the default build but can be excluded from custom builds. + * 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. * - * @method Phaser.Loader.LoaderPlugin#scripts - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.17.0 + * 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: * - * @param {(string|Phaser.Types.Loader.FileTypes.MultiScriptFileConfig|Phaser.Types.Loader.FileTypes.MultiScriptFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string[]} [url] - An array of absolute or relative URLs to load the script files from. They are processed in the order given in the array. - * @param {string} [extension='js'] - The default file extension to use if no url is provided. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for these files. + * - Opacity (blended with parent) and visibility (parent overrides child) + * - Vertical and horizontal offset * - * @return {this} The Loader instance. + * 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'. + * + * The Phaser Tiled Parser does **not** support the 'Collection of Images' feature for a Tileset. + * You must ensure all of your tiles are contained in a single tileset image file (per layer) + * and have this 'embedded' in the exported Tiled JSON map data. + * + * @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. */ -FileTypesManager.register('scripts', function (key, url, xhrSettings) -{ - var multifile; +var Tilemap = new Class({ - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined + initialize: - if (Array.isArray(key)) + function Tilemap (scene, mapData) { - for (var i = 0; i < key.length; i++) - { - multifile = new MultiScriptFile(this, key[i]); + /** + * @name Phaser.Tilemaps.Tilemap#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - this.addFile(multifile.files); - } - } - else - { - multifile = new MultiScriptFile(this, key, url, xhrSettings); + /** + * 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; - this.addFile(multifile.files); - } + /** + * 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; - return this; -}); + /** + * The width of the map (in tiles). + * + * @name Phaser.Tilemaps.Tilemap#width + * @type {number} + * @since 3.0.0 + */ + this.width = mapData.width; -module.exports = MultiScriptFile; + /** + * 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; -/***/ }), -/* 1353 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * The format of the map data. + * + * @name Phaser.Tilemaps.Tilemap#format + * @type {number} + * @since 3.0.0 + */ + this.format = mapData.format; -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); -var MultiFile = __webpack_require__(49); -var ParseObj = __webpack_require__(498); -var ParseObjMaterial = __webpack_require__(499); -var TextFile = __webpack_require__(242); + /** + * 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; -/** - * @classdesc - * A single Wavefront OBJ File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#obj method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#obj. - * - * @class OBJFile - * @extends Phaser.Loader.MultiFile - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.50.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.OBJFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string} [objURL] - The absolute or relative URL to load the obj file from. If undefined or `null` it will be set to `.obj`, i.e. if `key` was "alien" then the URL will be "alien.obj". - * @param {string} [matURL] - The absolute or relative URL to load the material file from. If undefined or `null` it will be set to `.mat`, i.e. if `key` was "alien" then the URL will be "alien.mat". - * @param {boolean} [flipUV] - Flip the UV coordinates stored in the model data? - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for these files. - */ -var OBJFile = new Class({ + /** + * Map specific properties as specified in Tiled. + * + * @name Phaser.Tilemaps.Tilemap#properties + * @type {object} + * @since 3.0.0 + */ + this.properties = mapData.properties; - Extends: MultiFile, + /** + * 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; - initialize: + /** + * 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; - function OBJFile (loader, key, objURL, matURL, flipUV, xhrSettings) - { - var obj; - var mat; + /** + * 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; - var cache = loader.cacheManager.obj; + /** + * An array of Tiled Image Layers. + * + * @name Phaser.Tilemaps.Tilemap#images + * @type {array} + * @since 3.0.0 + */ + this.images = mapData.images; - if (IsPlainObject(key)) - { - var config = key; + /** + * An array of Tilemap layer data. + * + * @name Phaser.Tilemaps.Tilemap#layers + * @type {Phaser.Tilemaps.LayerData[]} + * @since 3.0.0 + */ + this.layers = mapData.layers; - key = GetFastValue(config, 'key'); + /** + * Master list of tiles -> x, y, index in tileset. + * + * @name Phaser.Tilemaps.Tilemap#tiles + * @type {array} + * @since 3.60.0 + * @see Phaser.Tilemaps.Parsers.Tiled.BuildTilesetIndex + */ + this.tiles = mapData.tiles; - obj = new TextFile(loader, { - key: key, - type: 'obj', - cache: cache, - url: GetFastValue(config, 'url'), - extension: GetFastValue(config, 'extension', 'obj'), - xhrSettings: GetFastValue(config, 'xhrSettings'), - config: { - flipUV: GetFastValue(config, 'flipUV', flipUV) - } - }); + /** + * 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; - matURL = GetFastValue(config, 'matURL'); + /** + * 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; - if (matURL) - { - mat = new TextFile(loader, { - key: key, - type: 'mat', - cache: cache, - url: matURL, - extension: GetFastValue(config, 'matExtension', 'mat'), - xhrSettings: GetFastValue(config, 'xhrSettings') - }); - } - } - else - { - obj = new TextFile(loader, { - key: key, - url: objURL, - type: 'obj', - cache: cache, - extension: 'obj', - xhrSettings: xhrSettings, - config: { - flipUV: flipUV - } - }); + /** + * The index of the currently selected LayerData object. + * + * @name Phaser.Tilemaps.Tilemap#currentLayerIndex + * @type {number} + * @since 3.0.0 + */ + this.currentLayerIndex = 0; - if (matURL) - { - mat = new TextFile(loader, { - key: key, - url: matURL, - type: 'mat', - cache: cache, - extension: 'mat', - xhrSettings: xhrSettings - }); - } - } + /** + * 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; - MultiFile.call(this, loader, 'obj', key, [ obj, mat ]); + 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), + GetTileCorners: TilemapComponents.GetTileCornersFunction(orientation) + }; }, /** - * Adds this file to its target cache upon successful loading and processing. + * Sets the rendering (draw) order of the tiles in this map. * - * @method Phaser.Loader.FileTypes.OBJFile#addToCache - * @since 3.50.0 + * 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. */ - addToCache: function () + setRenderOrder: function (renderOrder) { - if (this.isReadyToProcess()) - { - var obj = this.files[0]; - var mat = this.files[1]; - - var objData = ParseObj(obj.data, obj.config.flipUV); - - if (mat) - { - objData.materials = ParseObjMaterial(mat.data); - } - - obj.cache.add(obj.key, objData); + var orders = [ 'right-down', 'left-down', 'right-up', 'left-up' ]; - this.complete = true; + if (typeof renderOrder === 'number') + { + renderOrder = orders[renderOrder]; } - } -}); + if (orders.indexOf(renderOrder) > -1) + { + this.renderOrder = renderOrder; + } -/** - * Adds a Wavefront OBJ file, or array of OBJ files, to the current load queue. - * - * Note: You should ensure your 3D package has triangulated the OBJ file prior to export. - * - * 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.obj('ufo', 'files/spaceship.obj'); - * } - * ``` - * - * You can optionally also load a Wavefront Material file as well, by providing the 3rd parameter: - * - * ```javascript - * function preload () - * { - * this.load.obj('ufo', 'files/spaceship.obj', 'files/spaceship.mtl'); - * } - * ``` - * - * If given, the material will be parsed and stored along with the obj data in the cache. - * - * 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 OBJ Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the OBJ 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 OBJ Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.obj({ - * key: 'ufo', - * url: 'files/spaceship.obj', - * matURL: 'files/spaceship.mtl', - * flipUV: true - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.OBJFileConfig` for more details. - * - * Once the file has finished loading you can access it from its Cache using its key: - * - * ```javascript - * this.load.obj('ufo', 'files/spaceship.obj'); - * // and later in your game ... - * var data = this.cache.obj.get('ufo'); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and - * this is what you would use to retrieve the obj from the OBJ Cache. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story" - * and no URL is given then the Loader will set the URL to be "story.obj". It will always add `.obj` 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 OBJ 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#obj - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.50.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.OBJFileConfig|Phaser.Types.Loader.FileTypes.OBJFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string} [objURL] - The absolute or relative URL to load the obj file from. If undefined or `null` it will be set to `.obj`, i.e. if `key` was "alien" then the URL will be "alien.obj". - * @param {string} [matURL] - Optional absolute or relative URL to load the obj material file from. - * @param {boolean} [flipUV] - Flip the UV coordinates stored in the model data? - * @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('obj', function (key, objURL, matURL, flipUVs, xhrSettings) -{ - var multifile; + return this; + }, - if (Array.isArray(key)) + /** + * 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. + * @param {object} [tileOffset={x: 0, y: 0}] - Tile texture drawing offset. + * If not specified, it will default to {0, 0} + * + * @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, tileOffset) { - for (var i = 0; i < key.length; i++) - { - multifile = new OBJFile(this, key[i]); + if (tilesetName === undefined) { return null; } + if (key === undefined || key === null) { key = tilesetName; } - // If it's an array it has to be an array of Objects, so we get everything out of the 'key' object - this.addFile(multifile.files); + if (!this.scene.sys.textures.exists(key)) + { + console.warn('Invalid Tileset Image: ' + key); + return null; } - } - else - { - multifile = new OBJFile(this, key, objURL, matURL, flipUVs, xhrSettings); - this.addFile(multifile.files); - } - - return this; -}); + var texture = this.scene.sys.textures.get(key); -module.exports = OBJFile; + var index = this.getTilesetIndex(tilesetName); + if (index === null && this.format === Formats.TILED_JSON) + { + console.warn('No data found for Tileset: ' + tilesetName); + return null; + } -/***/ }), -/* 1354 */ -/***/ (function(module, exports, __webpack_require__) { + var tileset = this.tilesets[index]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (tileset) + { + tileset.setTileSize(tileWidth, tileHeight); + tileset.setSpacing(tileMargin, tileSpacing); + tileset.setImage(texture); -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(61); + return tileset; + } -/** - * @classdesc - * A single JSON Pack File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#pack method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#pack. - * - * @class PackFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.7.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.PackFileConfig)} 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 `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". - * @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 PackFile = new Class({ + 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; } + if (tileOffset === undefined) { tileOffset = { x: 0, y: 0 }; } - Extends: JSONFile, + tileset = new Tileset(tilesetName, gid, tileWidth, tileHeight, tileMargin, tileSpacing, undefined, undefined, tileOffset); - initialize: + tileset.setImage(texture); - // 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 + this.tilesets.push(tileset); - function PackFile (loader, key, url, xhrSettings, dataKey) - { - JSONFile.call(this, loader, key, url, xhrSettings, dataKey); + this.tiles = BuildTilesetIndex(this); - this.type = 'packfile'; + return tileset; }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * 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.Loader.FileTypes.PackFile#onProcess - * @since 3.7.0 + * 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. */ - onProcess: function () + copy: function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) { - if (this.state !== CONST.FILE_POPULATED) - { - this.state = CONST.FILE_PROCESSING; - - this.data = JSON.parse(this.xhrLoader.responseText); - } - - // Let's pass the pack file data over to the Loader ... - this.loader.addPack(this.data, this.config); - - this.onProcessComplete(); - } + layer = this.getLayer(layer); -}); + if (layer !== null) + { + TilemapComponents.Copy( + srcTileX, srcTileY, + width, height, + destTileX, destTileY, + recalculateFaces, layer + ); -/** - * Adds a JSON File Pack, or array of packs, 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.pack('level1', 'data/Level1Files.json'); - * } - * ``` - * - * A File Pack is a JSON file (or object) that contains details about other files that should be added into the Loader. - * Here is a small example: - * - * ```json - * { - * "test1": { - * "files": [ - * { - * "type": "image", - * "key": "taikodrummaster", - * "url": "assets/pics/taikodrummaster.jpg" - * }, - * { - * "type": "image", - * "key": "sukasuka-chtholly", - * "url": "assets/pics/sukasuka-chtholly.png" - * } - * ] - * }, - * "meta": { - * "generated": "1401380327373", - * "app": "Phaser 3 Asset Packer", - * "url": "https://phaser.io", - * "version": "1.0", - * "copyright": "Photon Storm Ltd. 2018" - * } - * } - * ``` - * - * The pack can be split into sections. In the example above you'll see a section called `test1. You can tell - * the `load.pack` method to parse only a particular section of a pack. The pack is stored in the JSON Cache, - * so you can pass it to the Loader to process additional sections as needed in your game, or you can just load - * them all at once without specifying anything. - * - * The pack file can contain an entry for any type of file that Phaser can load. The object structures exactly - * match that of the file type configs, and all properties available within the file type configs can be used - * in the pack file too. - * - * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, - * or if it's already running, when the next free load slot becomes available. This happens automatically if you - * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued - * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. - * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the - * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been - * loaded. - * - * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring - * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. - * - * 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.pack({ - * key: 'level1', - * url: 'data/Level1Files.json' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.PackFileConfig` for more details. - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `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 Pack 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#pack - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.7.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.PackFileConfig|Phaser.Types.Loader.FileTypes.PackFileConfig[])} 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 `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". - * @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('pack', function (key, url, packKey, xhrSettings) -{ - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined + return this; + } + else + { + return null; + } + }, - if (Array.isArray(key)) + /** + * 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) { - for (var i = 0; i < key.length; i++) + 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) { - this.addFile(new PackFile(this, key[i])); + console.warn('Invalid Tilemap Layer ID: ' + name); + return null; } - } - else - { - this.addFile(new PackFile(this, key, url, xhrSettings, packKey)); - } - return this; -}); + var layerData = new LayerData({ + name: name, + tileWidth: tileWidth, + tileHeight: tileHeight, + width: width, + height: height, + orientation: this.orientation + }); -module.exports = PackFile; + var row; + for (var tileY = 0; tileY < height; tileY++) + { + row = []; -/***/ }), -/* 1355 */ -/***/ (function(module, exports, __webpack_require__) { + for (var tileX = 0; tileX < width; tileX++) + { + row.push(new Tile(layerData, -1, tileX, tileY, tileWidth, tileHeight, this.tileWidth, this.tileHeight)); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + layerData.data.push(row); + } -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); + this.layers.push(layerData); -/** - * @classdesc - * A single Plugin Script File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#plugin method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#plugin. - * - * @class PluginFile - * @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.PluginFileConfig)} 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 {boolean} [start=false] - Automatically start the plugin after loading? - * @param {string} [mapping] - If this plugin is to be injected into the Scene, this is the property key used. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var PluginFile = new Class({ + this.currentLayerIndex = this.layers.length - 1; - Extends: File, + var layer = new TilemapLayer(this.scene, this, this.currentLayerIndex, tileset, x, y); - initialize: + layer.setRenderOrder(this.renderOrder); - function PluginFile (loader, key, url, start, mapping, xhrSettings) + 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 extension = 'js'; + var index = this.getLayerIndex(layerID); - if (IsPlainObject(key)) + if (index === null) { - var config = key; + console.warn('Invalid Tilemap Layer ID: ' + layerID); - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - start = GetFastValue(config, 'start'); - mapping = GetFastValue(config, 'mapping'); + if (typeof layerID === 'string') + { + console.warn('Valid tilelayer names: %o', this.getTileLayerNames()); + } + + return null; } - var fileConfig = { - type: 'plugin', - cache: false, - extension: extension, - responseType: 'text', - key: key, - url: url, - xhrSettings: xhrSettings, - config: { - start: start, - mapping: mapping - } - }; + var layerData = this.layers[index]; - File.call(this, loader, fileConfig); + // Check for an associated tilemap layer + if (layerData.tilemapLayer) + { + console.warn('Tilemap Layer ID already exists:' + layerID); + return null; + } - // If the url variable refers to a class, add the plugin directly - if (typeof url === 'function') + this.currentLayerIndex = index; + + // Default the x/y position to match Tiled layer offset, if it exists. + + if (x === undefined) { - this.data = url; + x = layerData.x; + } - this.state = CONST.FILE_POPULATED; + 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; }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * 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) * - * @method Phaser.Loader.FileTypes.PluginFile#onProcess - * @since 3.7.0 + * Objects are matched on one of 4 criteria: The Object ID, the Object GID, the Object Name, or the Object Type. + * + * Within Tiled, Object IDs are unique per Object. Object GIDs, however, are shared by all objects + * using the same image. Finally, Object Names and Types are strings and the same name can be used on multiple + * Objects in Tiled, they do not have to be unique; Names are specific to Objects while Types can be inherited + * from Object GIDs using the same image. + * + * 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`, `type`, 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 {@link Phaser.GameObjects.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 {@link 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. The + * class must have {@link Phaser.GameObjects.Components.Transform#setPosition setPosition} and + * {@link Phaser.GameObjects.Components.Texture#setTexture setTexture} methods. + * + * Custom properties on the Object are copied onto any existing properties on 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 properties that do not exist on the Game Object are set in the + * Game Object's {@link Phaser.GameObjects.GameObject#data data store}. + * + * When `useTileset` is `true` (the default), Tile Objects will inherit the texture and any tile properties + * from the tileset, and the local tile ID will be used as the texture frame. For the frame selection to work + * you need to load the tileset texture as a spritesheet so its frame names match the local tile IDs. + * + * For instance, a tileset tile + * + * ``` + * { id: 3, type: 'treadmill', speed: 4 } + * ``` + * + * with gid 19 and an object + * + * ``` + * { id: 7, gid: 19, speed: 5, rotation: 90 } + * ``` + * + * will be interpreted as + * + * ``` + * { id: 7, gid: 19, speed: 5, rotation: 90, type: 'treadmill', texture: '[the tileset texture]', frame: 3 } + * ``` + * + * You can suppress this behavior by setting the boolean `ignoreTileset` for each `config` that should ignore + * object gid tilesets. + * + * You can set a `container` property in the config. If given, the new Game Object will be added to + * the Container or Layer instance instead of the Scene. + * + * You can set named texture-`key` and texture-`frame` properties, which will be set on the new Game Object. + * + * 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 + * }, + * { + * type: 'endzone', + * classType: Phaser.GameObjects.Zone + * } + * ]); + * ``` + * + * The signature of this method changed significantly in v3.60.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. + * @param {boolean} [useTileset=true] - True if objects that set gids should also search the underlying tile for properties and data. + * + * @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. */ - onProcess: function () + createFromObjects: function (objectLayerName, config, useTileset) { - var pluginManager = this.loader.systems.plugins; - var config = this.config; + if (useTileset === undefined) { useTileset = true; } - var start = GetFastValue(config, 'start', false); - var mapping = GetFastValue(config, 'mapping', null); + var results = []; - if (this.state === CONST.FILE_POPULATED) + var objectLayer = this.getObjectLayer(objectLayerName); + + if (!objectLayer) { - pluginManager.install(this.key, this.data, start, mapping); + console.warn('createFromObjects: Invalid objectLayerName given: ' + objectLayerName); + + return results; } - else + + var objectHelper = new ObjectHelper(useTileset ? this.tilesets : undefined); + + if (!Array.isArray(config)) { - // Plugin added via a js file - this.state = CONST.FILE_PROCESSING; + config = [ config ]; + } - this.data = document.createElement('script'); - this.data.language = 'javascript'; - this.data.type = 'text/javascript'; - this.data.defer = false; - this.data.text = this.xhrLoader.responseText; + var objects = objectLayer.objects; - document.head.appendChild(this.data); + for (var c = 0; c < config.length; c++) + { + var singleConfig = config[c]; - var plugin = pluginManager.install(this.key, window[this.key], start, mapping); + var id = GetFastValue(singleConfig, 'id', null); + var gid = GetFastValue(singleConfig, 'gid', null); + var name = GetFastValue(singleConfig, 'name', null); + var type = GetFastValue(singleConfig, 'type', null); + objectHelper.enabled = !GetFastValue(singleConfig, 'ignoreTileset', null); - if (start || mapping) + 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++) { - // Install into the current Scene Systems and Scene - this.loader.systems[mapping] = plugin; - this.loader.scene[mapping] = plugin; + obj = objects[s]; + + if ( + (id === null && gid === null && name === null && type === null) || + (id !== null && obj.id === id) || + (gid !== null && obj.gid === gid) || + (name !== null && obj.name === name) || + (type !== null && objectHelper.getTypeIncludingTile(obj) === type) + ) + { + toConvert.push(obj); + } } - } - this.onProcessComplete(); - } + // 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); -/** - * Adds a Plugin Script file, or array of plugin 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.plugin('modplayer', 'plugins/ModPlayer.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.plugin({ - * key: 'modplayer', - * url: 'plugins/ModPlayer.js' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.PluginFileConfig` 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. It will then be passed to the Phaser PluginCache.register method. - * - * 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 Plugin 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#plugin - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.PluginFileConfig|Phaser.Types.Loader.FileTypes.PluginFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {(string|function)} [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". Or, a plugin function. - * @param {boolean} [start] - Automatically start the plugin after loading? - * @param {string} [mapping] - If this plugin is to be injected into the Scene, this is the property key used. - * @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('plugin', function (key, url, start, mapping, 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 PluginFile(this, key[i])); - } - } - else - { - this.addFile(new PluginFile(this, key, url, start, mapping, xhrSettings)); - } + for (var i = 0; i < toConvert.length; i++) + { + obj = toConvert[i]; - return this; -}); + var sprite = new classType(scene); -module.exports = PluginFile; + sprite.setName(obj.name); + sprite.setPosition(obj.x, obj.y); + objectHelper.setTextureAndFrame(sprite, texture, frame, obj); + if (obj.width) + { + sprite.displayWidth = obj.width; + } -/***/ }), -/* 1356 */ -/***/ (function(module, exports, __webpack_require__) { + if (obj.height) + { + sprite.displayHeight = obj.height; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.orientation === ORIENTATION.ISOMETRIC) + { + var isometricRatio = this.tileWidth / this.tileHeight; + var isometricPosition = { + x: sprite.x - sprite.y, + y: (sprite.x + sprite.y) / isometricRatio + }; -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); + sprite.x = isometricPosition.x; + sprite.y = isometricPosition.y; + } -/** - * @classdesc - * An external Scene JavaScript File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#sceneFile method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#sceneFile. - * - * @class SceneFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.16.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.SceneFileConfig)} 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 SceneFile = new Class({ + // Origin is (0, 1) for tile objects or (0, 0) for other objects 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 - (obj.gid ? 1 : 0)) * obj.height + }; - Extends: File, + // If the object is rotated, then the origin offset also needs to be rotated. + if (obj.rotation) + { + var angle = DegToRad(obj.rotation); - initialize: + Rotate(offset, angle); - function SceneFile (loader, key, url, xhrSettings) - { - var extension = 'js'; + sprite.rotation = angle; + } - if (IsPlainObject(key)) - { - var config = key; + sprite.x += offset.x; + sprite.y += offset.y; - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - } + if (obj.flippedHorizontal !== undefined || obj.flippedVertical !== undefined) + { + sprite.setFlip(obj.flippedHorizontal, obj.flippedVertical); + } - var fileConfig = { - type: 'text', - extension: extension, - responseType: 'text', - key: key, - url: url, - xhrSettings: xhrSettings - }; + if (!obj.visible) + { + sprite.visible = false; + } - File.call(this, loader, fileConfig); + objectHelper.setPropertiesFromTiledObject(sprite, obj); + + if (container) + { + container.add(sprite); + } + else + { + scene.add.existing(sprite); + } + + results.push(sprite); + } + } + + return results; }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * 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.Loader.FileTypes.SceneFile#onProcess - * @since 3.16.0 + * @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. */ - onProcess: function () + createFromTiles: function (indexes, replacements, spriteConfig, scene, camera, layer) { - this.state = CONST.FILE_PROCESSING; + layer = this.getLayer(layer); - this.data = this.xhrLoader.responseText; + if (layer === null) { return null; } - this.onProcessComplete(); + return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, layer); }, /** - * Adds this file to its target cache upon successful loading and processing. + * 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.Loader.FileTypes.SceneFile#addToCache - * @since 3.16.0 + * 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. */ - addToCache: function () + fill: function (index, tileX, tileY, width, height, recalculateFaces, layer) { - var code = this.data.concat('(function(){\n' + 'return new ' + this.key + '();\n' + '}).call(this);'); + if (recalculateFaces === undefined) { recalculateFaces = true; } - // Stops rollup from freaking out during build - var eval2 = eval; + layer = this.getLayer(layer); - this.loader.sceneManager.add(this.key, eval2(code)); + if (layer === null) { return null; } - this.complete = true; - } + TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, layer); -}); + return this; + }, -/** - * Adds an external Scene file, or array of Scene 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.sceneFile('Level1', 'src/Level1.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. It is used to add the file to the global Scene Manager upon a successful load. - * - * For a Scene File it's vitally important that the key matches the class name in the JavaScript file. - * - * For example here is the source file: - * - * ```javascript - * class ExternalScene extends Phaser.Scene { - * - * constructor () - * { - * super('myScene'); - * } - * - * } - * ``` - * - * Because the class is called `ExternalScene` that is the exact same key you must use when loading it: - * - * ```javascript - * function preload () - * { - * this.load.sceneFile('ExternalScene', 'src/yourScene.js'); - * } - * ``` - * - * The key that is used within the Scene Manager can either be set to the same, or you can override it in the Scene - * constructor, as we've done in the example above, where the Scene key was changed to `myScene`. - * - * The key should be unique both in terms of files being loaded and Scenes already present in the Scene Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Scene Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.sceneFile({ - * key: 'Level1', - * url: 'src/Level1.js' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.SceneFileConfig` for more details. - * - * Once the file has finished loading it will be added to the Scene Manager. - * - * ```javascript - * this.load.sceneFile('Level1', 'src/Level1.js'); - * // and later in your game ... - * this.scene.start('Level1'); - * ``` - * - * 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 `WORLD1.` and the key was `Story` the final key will be `WORLD1.Story` and - * this is what you would use to retrieve the text from the Scene Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "story" - * and no URL is given then the Loader will set the URL to be "story.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 Scene 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#sceneFile - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.16.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.SceneFileConfig|Phaser.Types.Loader.FileTypes.SceneFileConfig[])} 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('sceneFile', function (key, url, xhrSettings) -{ - if (Array.isArray(key)) + /** + * 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 be returned in 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) { - for (var i = 0; i < key.length; i++) + if (typeof objectLayer === 'string') { - // 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 SceneFile(this, key[i])); - } - } - else - { - this.addFile(new SceneFile(this, key, url, xhrSettings)); - } + var name = objectLayer; - return this; -}); + objectLayer = this.getObjectLayer(objectLayer); -module.exports = SceneFile; + if (!objectLayer) + { + console.warn('No object layer found with the name: ' + name); + return null; + } + } + return objectLayer.objects.filter(callback, context); + }, -/***/ }), -/* 1357 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (layer === null) { return null; } -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); + return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, layer); + }, -/** - * @classdesc - * A single Scene Plugin Script File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#scenePlugin method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#scenePlugin. - * - * @class ScenePluginFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.8.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.ScenePluginFileConfig)} 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 {string} [systemKey] - If this plugin is to be added to Scene.Systems, this is the property key for it. - * @param {string} [sceneKey] - If this plugin is to be added to the Scene, this is the property key for it. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var ScenePluginFile = new Class({ + /** + * 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); - Extends: File, + if (layer === null) { return null; } - initialize: + return TilemapComponents.FindByIndex(findIndex, skip, reverse, layer); + }, - function ScenePluginFile (loader, key, url, systemKey, sceneKey, xhrSettings) + /** + * 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) { - var extension = 'js'; - - if (IsPlainObject(key)) + if (typeof objectLayer === 'string') { - var config = key; + var name = objectLayer; - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - systemKey = GetFastValue(config, 'systemKey'); - sceneKey = GetFastValue(config, 'sceneKey'); - } + objectLayer = this.getObjectLayer(objectLayer); - var fileConfig = { - type: 'scenePlugin', - cache: false, - extension: extension, - responseType: 'text', - key: key, - url: url, - xhrSettings: xhrSettings, - config: { - systemKey: systemKey, - sceneKey: sceneKey + if (!objectLayer) + { + console.warn('No object layer found with the name: ' + name); + return null; } - }; - - File.call(this, loader, fileConfig); - - // If the url variable refers to a class, add the plugin directly - if (typeof url === 'function') - { - this.data = url; - - this.state = CONST.FILE_POPULATED; } + + return objectLayer.objects.find(callback, context) || null; }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * 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.Loader.FileTypes.ScenePluginFile#onProcess - * @since 3.8.0 + * @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. */ - onProcess: function () + findTile: function (callback, context, tileX, tileY, width, height, filteringOptions, layer) { - var pluginManager = this.loader.systems.plugins; - var config = this.config; + layer = this.getLayer(layer); - var key = this.key; - var systemKey = GetFastValue(config, 'systemKey', key); - var sceneKey = GetFastValue(config, 'sceneKey', key); + if (layer === null) { return null; } - if (this.state === CONST.FILE_POPULATED) - { - pluginManager.installScenePlugin(systemKey, this.data, sceneKey, this.loader.scene, true); - } - else - { - // Plugin added via a js file - this.state = CONST.FILE_PROCESSING; + return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); + }, - this.data = document.createElement('script'); - this.data.language = 'javascript'; - this.data.type = 'text/javascript'; - this.data.defer = false; - this.data.text = this.xhrLoader.responseText; + /** + * 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); - document.head.appendChild(this.data); + if (layer === null) { return null; } - pluginManager.installScenePlugin(systemKey, window[this.key], sceneKey, this.loader.scene, true); - } + TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, layer); - this.onProcessComplete(); - } + 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); + }, -/** - * Adds a Scene Plugin Script file, or array of plugin 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.scenePlugin('ModPlayer', 'plugins/ModPlayer.js', 'modPlayer', 'mods'); - * } - * ``` - * - * 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.scenePlugin({ - * key: 'modplayer', - * url: 'plugins/ModPlayer.js' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.ScenePluginFileConfig` 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. It will then be passed to the Phaser PluginCache.register method. - * - * 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#scenePlugin - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.8.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.ScenePluginFileConfig|Phaser.Types.Loader.FileTypes.ScenePluginFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {(string|function)} [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". Or, set to a plugin function. - * @param {string} [systemKey] - If this plugin is to be added to Scene.Systems, this is the property key for it. - * @param {string} [sceneKey] - If this plugin is to be added to the Scene, this is the property key for it. - * @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('scenePlugin', function (key, url, systemKey, sceneKey, xhrSettings) -{ - if (Array.isArray(key)) + /** + * 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 () { - for (var i = 0; i < key.length; i++) + if (!this.images || !Array.isArray(this.images)) { - // 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 ScenePluginFile(this, key[i])); + return []; } - } - else + + 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) { - this.addFile(new ScenePluginFile(this, key, url, systemKey, sceneKey, xhrSettings)); - } + for (var i = 0; i < location.length; i++) + { + if (location[i].name === name) + { + return i; + } + } - return this; -}); + return null; + }, -module.exports = ScenePluginFile; + /** + * 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`, or null. + */ + getLayer: function (layer) + { + var index = this.getLayerIndex(layer); + return (index !== null) ? this.layers[index] : null; + }, -/***/ }), -/* 1358 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return (index !== null) ? this.objects[index] : null; + }, -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var ImageFile = __webpack_require__(71); + /** + * 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 []; + } -/** - * @classdesc - * A single Sprite Sheet Image File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#spritesheet method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#spritesheet. - * - * @class SpriteSheetFile - * @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.SpriteSheetFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string|string[]} [url] - The absolute or relative URL to load this file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {Phaser.Types.Loader.FileTypes.ImageFrameConfig} [frameConfig] - The frame configuration object. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var SpriteSheetFile = new Class({ + return this.objects.map(function (object) + { + return object.name; + }); + }, - Extends: ImageFile, + /** + * 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 && layer.tilemap === this) + { + return layer.layerIndex; + } + else + { + return null; + } + }, - initialize: + /** + * 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); + }, - function SpriteSheetFile (loader, key, url, frameConfig, xhrSettings) + /** + * 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) { - ImageFile.call(this, loader, key, url, xhrSettings, frameConfig); + layer = this.getLayer(layer); - this.type = 'spritesheet'; + if (layer === null) { return null; } + + return TilemapComponents.GetTileAt(tileX, tileY, nonNull, layer); }, /** - * Adds this file to its target cache upon successful loading and processing. + * Gets a tile at the given world coordinates from the given layer. * - * @method Phaser.Loader.FileTypes.SpriteSheetFile#addToCache - * @since 3.7.0 + * 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. */ - addToCache: function () + getTileAtWorldXY: function (worldX, worldY, nonNull, camera, layer) { - var texture = this.cache.addSpriteSheet(this.key, this.data, this.config); + layer = this.getLayer(layer); - this.pendingDestroy(texture); - } + if (layer === null) { return null; } -}); + return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, layer); + }, -/** - * Adds a Sprite Sheet Image, or array of Sprite Sheet Images, to the current load queue. - * - * The term 'Sprite Sheet' in Phaser means a fixed-size sheet. Where every frame in the sheet is the exact same size, - * and you reference those frames using numbers, not frame names. This is not the same thing as a Texture Atlas, where - * the frames are packed in a way where they take up the least amount of space, and are referenced by their names, - * not numbers. Some articles and software use the term 'Sprite Sheet' to mean Texture Atlas, so please be aware of - * what sort of file you're actually trying to load. - * - * 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.spritesheet('bot', 'images/robot.png', { frameWidth: 32, frameHeight: 38 }); - * } - * ``` - * - * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, - * or if it's already running, when the next free load slot becomes available. This happens automatically if you - * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued - * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. - * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the - * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been - * loaded. - * - * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. - * If you try to load an animated gif only the first frame will be rendered. Browsers do not natively support playback - * of animated gifs to Canvas elements. - * - * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.spritesheet({ - * key: 'bot', - * url: 'images/robot.png', - * frameConfig: { - * frameWidth: 32, - * frameHeight: 38, - * startFrame: 0, - * endFrame: 8 - * } - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.SpriteSheetFileConfig` for more details. - * - * Once the file has finished loading you can use it as a texture for a Game Object by referencing its key: - * - * ```javascript - * this.load.spritesheet('bot', 'images/robot.png', { frameWidth: 32, frameHeight: 38 }); - * // and later in your game ... - * this.add.image(x, y, 'bot', 0); - * ``` - * - * 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 `PLAYER.` and the key was `Running` the final key will be `PLAYER.Running` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, - * then you can specify it by providing an array as the `url` where the second element is the normal map: - * - * ```javascript - * this.load.spritesheet('logo', [ 'images/AtariLogo.png', 'images/AtariLogo-n.png' ], { frameWidth: 256, frameHeight: 80 }); - * ``` - * - * Or, if you are using a config object use the `normalMap` property: - * - * ```javascript - * this.load.spritesheet({ - * key: 'logo', - * url: 'images/AtariLogo.png', - * normalMap: 'images/AtariLogo-n.png', - * frameConfig: { - * frameWidth: 256, - * frameHeight: 80 - * } - * }); - * ``` - * - * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. - * Normal maps are a WebGL only feature. - * - * Note: The ability to load this type of file will only be available if the Sprite Sheet 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#spritesheet - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.SpriteSheetFileConfig|Phaser.Types.Loader.FileTypes.SpriteSheetFileConfig[])} 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 `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {Phaser.Types.Loader.FileTypes.ImageFrameConfig} [frameConfig] - The frame configuration object. At a minimum it should have a `frameWidth` property. - * @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('spritesheet', function (key, url, frameConfig, xhrSettings) -{ - if (Array.isArray(key)) + /** + * 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 () { - for (var i = 0; i < key.length; i++) + if (!this.layers || !Array.isArray(this.layers)) { - // 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 SpriteSheetFile(this, key[i])); + return []; } - } - else - { - this.addFile(new SpriteSheetFile(this, key, url, frameConfig, xhrSettings)); - } - - return this; -}); - -module.exports = SpriteSheetFile; + return this.layers.map(function (layer) + { + return layer.name; + }); + }, -/***/ }), -/* 1359 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (layer === null) { return null; } -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); + return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); + }, -/** - * @classdesc - * A single SVG File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#svg method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#svg. - * - * @class SVGFile - * @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.SVGFileConfig)} 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 `.svg`, i.e. if `key` was "alien" then the URL will be "alien.svg". - * @param {Phaser.Types.Loader.FileTypes.SVGSizeConfig} [svgConfig] - The svg size configuration object. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var SVGFile = new Class({ + /** + * 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); - Extends: File, + if (layer === null) { return null; } - initialize: + return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, layer); + }, - function SVGFile (loader, key, url, svgConfig, xhrSettings) + /** + * 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) { - var extension = 'svg'; - - if (IsPlainObject(key)) - { - var config = key; - - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - svgConfig = GetFastValue(config, 'svgConfig', {}); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); - } + layer = this.getLayer(layer); - var fileConfig = { - type: 'svg', - cache: loader.textureManager, - extension: extension, - responseType: 'text', - key: key, - url: url, - xhrSettings: xhrSettings, - config: { - width: GetFastValue(svgConfig, 'width'), - height: GetFastValue(svgConfig, 'height'), - scale: GetFastValue(svgConfig, 'scale') - } - }; + if (layer === null) { return null; } - File.call(this, loader, fileConfig); + return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, layer); }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * Gets the Tileset that has the given `name`, or null if an invalid `name` is given. * - * @method Phaser.Loader.FileTypes.SVGFile#onProcess - * @since 3.7.0 + * @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. */ - onProcess: function () + getTileset: function (name) { - this.state = CONST.FILE_PROCESSING; + var index = this.getIndex(this.tilesets, name); - var text = this.xhrLoader.responseText; - var svg = [ text ]; - var width = this.config.width; - var height = this.config.height; - var scale = this.config.scale; + return (index !== null) ? this.tilesets[index] : null; + }, - resize: if (width && height || scale) - { - var xml = null; - var parser = new DOMParser(); - xml = parser.parseFromString(text, 'text/xml'); - var svgXML = xml.getElementsByTagName('svg')[0]; + /** + * 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); + }, - var hasViewBox = svgXML.hasAttribute('viewBox'); - var svgWidth = parseFloat(svgXML.getAttribute('width')); - var svgHeight = parseFloat(svgXML.getAttribute('height')); + /** + * 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 (!hasViewBox && svgWidth && svgHeight) - { - // If there's no viewBox attribute, set one - svgXML.setAttribute('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight); - } - else if (hasViewBox && !svgWidth && !svgHeight) - { - // Get the w/h from the viewbox - var viewBox = svgXML.getAttribute('viewBox').split(/\s+|,/); + if (layer === null) { return null; } - svgWidth = viewBox[2]; - svgHeight = viewBox[3]; - } + return TilemapComponents.HasTileAt(tileX, tileY, layer); + }, - if (scale) - { - if (svgWidth && svgHeight) - { - width = svgWidth * scale; - height = svgHeight * scale; - } - else - { - break resize; - } - } + /** + * 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); - svgXML.setAttribute('width', width.toString() + 'px'); - svgXML.setAttribute('height', height.toString() + 'px'); + if (layer === null) { return null; } - svg = [ (new XMLSerializer()).serializeToString(svgXML) ]; - } + return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, layer); + }, - try - { - var blob = new window.Blob(svg, { type: 'image/svg+xml;charset=utf-8' }); - } - catch (e) + /** + * 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 () { - this.onProcessError(); + return this.layers[this.currentLayerIndex]; + }, - return; + set: function (layer) + { + this.setLayer(layer); } + }, - this.data = new Image(); - - this.data.crossOrigin = this.crossOrigin; + /** + * 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; } - var _this = this; - var retry = false; + layer = this.getLayer(layer); - this.data.onload = function () - { - if (!retry) - { - File.revokeObjectURL(_this.data); - } + if (layer === null) { return null; } - _this.onProcessComplete(); - }; + return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, layer); + }, - this.data.onerror = function () - { - // Safari 8 re-try - if (!retry) - { - retry = true; + /** + * 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; } - File.revokeObjectURL(_this.data); + layer = this.getLayer(layer); - _this.data.src = 'data:image/svg+xml,' + encodeURIComponent(svg.join('')); - } - else - { - _this.onProcessError(); - } - }; + if (layer === null) { return null; } - File.createObjectURL(this.data, blob, 'image/svg+xml'); + return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, layer); }, /** - * Adds this file to its target cache upon successful loading and processing. + * 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.Loader.FileTypes.SVGFile#addToCache - * @since 3.7.0 + * 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. */ - addToCache: function () + putTilesAt: function (tilesArray, tileX, tileY, recalculateFaces, layer) { - var texture = this.cache.addImage(this.key, this.data); + if (recalculateFaces === undefined) { recalculateFaces = true; } - this.pendingDestroy(texture); - } + layer = this.getLayer(layer); -}); + if (layer === null) { return null; } -/** - * Adds an SVG File, or array of SVG Files, to the current load queue. When the files are loaded they - * will be rendered to bitmap textures and stored in the Texture Manager. - * - * 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.svg('morty', 'images/Morty.svg'); - * } - * ``` - * - * 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 Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.svg({ - * key: 'morty', - * url: 'images/Morty.svg' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.SVGFileConfig` for more details. - * - * Once the file has finished loading you can use it as a texture for a Game Object by referencing its key: - * - * ```javascript - * this.load.svg('morty', 'images/Morty.svg'); - * // and later in your game ... - * this.add.image(x, y, 'morty'); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.html". It will always add `.html` 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 optionally pass an SVG Resize Configuration object when you load an SVG file. By default the SVG will be rendered to a texture - * at the same size defined in the SVG file attributes. However, this isn't always desirable. You may wish to resize the SVG (either down - * or up) to improve texture clarity, or reduce texture memory consumption. You can either specify an exact width and height to resize - * the SVG to: - * - * ```javascript - * function preload () - * { - * this.load.svg('morty', 'images/Morty.svg', { width: 300, height: 600 }); - * } - * ``` - * - * Or when using a configuration object: - * - * ```javascript - * this.load.svg({ - * key: 'morty', - * url: 'images/Morty.svg', - * svgConfig: { - * width: 300, - * height: 600 - * } - * }); - * ``` - * - * Alternatively, you can just provide a scale factor instead: - * - * ```javascript - * function preload () - * { - * this.load.svg('morty', 'images/Morty.svg', { scale: 2.5 }); - * } - * ``` - * - * Or when using a configuration object: - * - * ```javascript - * this.load.svg({ - * key: 'morty', - * url: 'images/Morty.svg', - * svgConfig: { - * scale: 2.5 - * } - * }); - * ``` - * - * If scale, width and height values are all given, the scale has priority and the width and height values are ignored. - * - * Note: The ability to load this type of file will only be available if the SVG 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#svg - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.SVGFileConfig|Phaser.Types.Loader.FileTypes.SVGFileConfig[])} 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 `.svg`, i.e. if `key` was "alien" then the URL will be "alien.svg". - * @param {Phaser.Types.Loader.FileTypes.SVGSizeConfig} [svgConfig] - The svg size configuration object. - * @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('svg', function (key, url, svgConfig, 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 SVGFile(this, key[i])); - } - } - else + 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) { - this.addFile(new SVGFile(this, key, url, svgConfig, xhrSettings)); - } + layer = this.getLayer(layer); - return this; -}); + if (layer === null) { return null; } -module.exports = SVGFile; + 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; } -/***/ }), -/* 1360 */ -/***/ (function(module, exports, __webpack_require__) { + TilemapComponents.CalculateFacesAt(tileX, tileY, layer); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -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__(40); + /** + * 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); -/** - * @classdesc - * A single Tilemap CSV File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#tilemapCSV method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#tilemapCSV. - * - * @class TilemapCSVFile - * @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.TilemapCSVFileConfig)} 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 `.csv`, i.e. if `key` was "alien" then the URL will be "alien.csv". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var TilemapCSVFile = new Class({ + if (layer === null) { return null; } - Extends: File, + TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, layer); - initialize: + return this; + }, - function TilemapCSVFile (loader, key, url, xhrSettings) + /** + * 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 extension = 'csv'; + var index = this.getLayerIndex(layer); - if (IsPlainObject(key)) + if (index !== null) { - var config = key; + SpliceOne(this.layers, index); - key = GetFastValue(config, 'key'); - url = GetFastValue(config, 'url'); - xhrSettings = GetFastValue(config, 'xhrSettings'); - extension = GetFastValue(config, 'extension', extension); + 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]; - var fileConfig = { - type: 'tilemapCSV', - cache: loader.cacheManager.tilemap, - extension: extension, - responseType: 'text', - key: key, - url: url, - xhrSettings: xhrSettings - }; + layer.tilemapLayer.destroy(); - File.call(this, loader, fileConfig); + SpliceOne(this.layers, index); - this.tilemapFormat = TILEMAP_FORMATS.CSV; + if (this.currentLayerIndex === index) + { + this.currentLayerIndex = 0; + } + + return this; + } + else + { + return null; + } }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * Removes all Tilemap Layers from this Tilemap and calls `destroy` on each of them. * - * @method Phaser.Loader.FileTypes.TilemapCSVFile#onProcess - * @since 3.7.0 + * @method Phaser.Tilemaps.Tilemap#removeAllLayers + * @since 3.0.0 + * + * @return {this} This Tilemap object. */ - onProcess: function () + removeAllLayers: function () { - this.state = CONST.FILE_PROCESSING; + var layers = this.layers; - this.data = this.xhrLoader.responseText; + for (var i = 0; i < layers.length; i++) + { + if (layers[i].tilemapLayer) + { + layers[i].tilemapLayer.destroy(false); + } + } - this.onProcessComplete(); + layers.length = 0; + + this.currentLayerIndex = 0; + + return this; }, /** - * Adds this file to its target cache upon successful loading and processing. + * Removes the given Tile, or an array of Tiles, from the layer to which they belong, + * and optionally recalculates the collision information. * - * @method Phaser.Loader.FileTypes.TilemapCSVFile#addToCache - * @since 3.7.0 + * @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. */ - addToCache: function () + removeTile: function (tiles, replaceIndex, recalculateFaces) { - var tiledata = { format: this.tilemapFormat, data: this.data }; - - this.cache.add(this.key, tiledata); - - this.pendingDestroy(tiledata); - } + if (replaceIndex === undefined) { replaceIndex = -1; } + if (recalculateFaces === undefined) { recalculateFaces = true; } -}); + var removed = []; -/** - * Adds a CSV Tilemap file, or array of CSV 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.tilemapCSV('level1', 'maps/Level1.csv'); - * } - * ``` - * - * Tilemap CSV data can be created in a text editor, or a 3rd party app that exports as CSV. - * - * 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 Tilemap Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Tilemap Cache. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Text Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.tilemapCSV({ - * key: 'level1', - * url: 'maps/Level1.csv' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.TilemapCSVFileConfig` for more details. - * - * Once the file has finished loading you can access it from its Cache using its key: - * - * ```javascript - * this.load.tilemapCSV('level1', 'maps/Level1.csv'); - * // and later in your game ... - * var map = this.make.tilemap({ key: 'level1' }); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and - * this is what you would use to retrieve the text from the Tilemap 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 "level" - * and no URL is given then the Loader will set the URL to be "level.csv". It will always add `.csv` 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 Tilemap CSV 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#tilemapCSV - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.TilemapCSVFileConfig|Phaser.Types.Loader.FileTypes.TilemapCSVFileConfig[])} 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 `.csv`, i.e. if `key` was "alien" then the URL will be "alien.csv". - * @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('tilemapCSV', function (key, url, xhrSettings) -{ - if (Array.isArray(key)) - { - for (var i = 0; i < key.length; i++) + if (!Array.isArray(tiles)) { - // 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 TilemapCSVFile(this, key[i])); + tiles = [ tiles ]; } - } - else - { - this.addFile(new TilemapCSVFile(this, key, url, xhrSettings)); - } - - return this; -}); -module.exports = TilemapCSVFile; + for (var i = 0; i < tiles.length; i++) + { + var tile = tiles[i]; + removed.push(this.removeTileAt(tile.x, tile.y, true, recalculateFaces, tile.tilemapLayer)); -/***/ }), -/* 1361 */ -/***/ (function(module, exports, __webpack_require__) { + if (replaceIndex > -1) + { + this.putTileAt(replaceIndex, tile.x, tile.y, recalculateFaces, tile.tilemapLayer); + } + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return removed; + }, -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(61); -var TILEMAP_FORMATS = __webpack_require__(40); + /** + * 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; } -/** - * @classdesc - * A single Impact.js Tilemap JSON File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#tilemapImpact method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#tilemapImpact. - * - * @class TilemapImpactFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.7.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.TilemapImpactFileConfig)} 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 `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var TilemapImpactFile = new Class({ + layer = this.getLayer(layer); - Extends: JSONFile, + if (layer === null) { return null; } - initialize: + return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, layer); + }, - function TilemapImpactFile (loader, key, url, xhrSettings) + /** + * 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) { - JSONFile.call(this, loader, key, url, xhrSettings); + if (replaceWithNull === undefined) { replaceWithNull = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } - this.type = 'tilemapJSON'; + layer = this.getLayer(layer); - this.cache = loader.cacheManager.tilemap; + if (layer === null) { return null; } + + return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, layer); }, /** - * Adds this file to its target cache upon successful loading and processing. + * 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. * - * @method Phaser.Loader.FileTypes.TilemapImpactFile#addToCache - * @since 3.7.0 + * 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. */ - addToCache: function () + renderDebug: function (graphics, styleConfig, layer) { - var tiledata = { format: TILEMAP_FORMATS.WELTMEISTER, data: this.data }; + layer = this.getLayer(layer); - this.cache.add(this.key, tiledata); + if (layer === null) { return null; } - this.pendingDestroy(tiledata); - } + if (this.orientation === ORIENTATION.ORTHOGONAL) + { + TilemapComponents.RenderDebug(graphics, styleConfig, layer); + } -}); + return this; + }, -/** - * Adds an Impact.js Tilemap file, or array of map 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.tilemapImpact('level1', 'maps/Level1.json'); - * } - * ``` - * - * Impact Tilemap data is created the Impact.js Map Editor called Weltmeister. - * - * 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 Tilemap Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Tilemap Cache. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Text Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.tilemapImpact({ - * key: 'level1', - * url: 'maps/Level1.json' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.TilemapImpactFileConfig` for more details. - * - * Once the file has finished loading you can access it from its Cache using its key: - * - * ```javascript - * this.load.tilemapImpact('level1', 'maps/Level1.json'); - * // and later in your game ... - * var map = this.make.tilemap({ key: 'level1' }); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and - * this is what you would use to retrieve the text from the Tilemap 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 "level" - * and no URL is given then the Loader will set the URL to be "level.json". It will always add `.json` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Note: The ability to load this type of file will only be available if the Tilemap Impact 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#tilemapImpact - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.7.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.TilemapImpactFileConfig|Phaser.Types.Loader.FileTypes.TilemapImpactFileConfig[])} 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 `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". - * @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('tilemapImpact', function (key, url, xhrSettings) -{ - if (Array.isArray(key)) + /** + * 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) { - for (var i = 0; i < key.length; i++) + var layers = this.layers; + + for (var i = 0; i < layers.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 TilemapImpactFile(this, key[i])); + TilemapComponents.RenderDebug(graphics, styleConfig, layers[i]); } - } - else - { - this.addFile(new TilemapImpactFile(this, key, url, xhrSettings)); - } - - return this; -}); - -module.exports = TilemapImpactFile; + return this; + }, -/***/ }), -/* 1362 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * 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); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (layer === null) { return null; } -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var JSONFile = __webpack_require__(61); -var TILEMAP_FORMATS = __webpack_require__(40); + TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, layer); -/** - * @classdesc - * A single Tiled Tilemap JSON File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#tilemapTiledJSON method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#tilemapTiledJSON. - * - * @class TilemapJSONFile - * @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.TilemapJSONFileConfig)} 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, a well formed JSON object. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var TilemapJSONFile = new Class({ + return this; + }, - Extends: JSONFile, + /** + * 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; } - initialize: + layer = this.getLayer(layer); - function TilemapJSONFile (loader, key, url, xhrSettings) - { - JSONFile.call(this, loader, key, url, xhrSettings); + if (layer === null) { return null; } - this.type = 'tilemapJSON'; + TilemapComponents.SetCollision(indexes, collides, recalculateFaces, layer, updateLayer); - this.cache = loader.cacheManager.tilemap; + return this; }, /** - * Adds this file to its target cache upon successful loading and processing. + * 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.Loader.FileTypes.TilemapJSONFile#addToCache - * @since 3.7.0 + * 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. */ - addToCache: function () + setCollisionBetween: function (start, stop, collides, recalculateFaces, layer) { - var tiledata = { format: TILEMAP_FORMATS.TILED_JSON, data: this.data }; + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } - this.cache.add(this.key, tiledata); + layer = this.getLayer(layer); - this.pendingDestroy(tiledata); - } + if (layer === null) { return null; } -}); + TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, layer); -/** - * Adds a Tiled JSON Tilemap file, or array of map 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.tilemapTiledJSON('level1', 'maps/Level1.json'); - * } - * ``` - * - * The Tilemap data is created using the Tiled Map Editor and selecting JSON as the export format. - * - * 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 Tilemap Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Tilemap Cache. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Text Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.tilemapTiledJSON({ - * key: 'level1', - * url: 'maps/Level1.json' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.TilemapJSONFileConfig` for more details. - * - * Once the file has finished loading you can access it from its Cache using its key: - * - * ```javascript - * this.load.tilemapTiledJSON('level1', 'maps/Level1.json'); - * // and later in your game ... - * var map = this.make.tilemap({ key: 'level1' }); - * ``` - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `LEVEL1.` and the key was `Story` the final key will be `LEVEL1.Story` and - * this is what you would use to retrieve the text from the Tilemap 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 "level" - * and no URL is given then the Loader will set the URL to be "level.json". It will always add `.json` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Note: The ability to load this type of file will only be available if the Tilemap 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#tilemapTiledJSON - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.TilemapJSONFileConfig|Phaser.Types.Loader.FileTypes.TilemapJSONFileConfig[])} 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, a well formed JSON object. - * @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('tilemapTiledJSON', 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 TilemapJSONFile(this, key[i])); - } - } - else + 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) { - this.addFile(new TilemapJSONFile(this, key, url, xhrSettings)); - } + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } - return this; -}); + layer = this.getLayer(layer); -module.exports = TilemapJSONFile; + if (layer === null) { return null; } + TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, layer); -/***/ }), -/* 1363 */ -/***/ (function(module, exports, __webpack_require__) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * 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; } -var Class = __webpack_require__(0); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var ImageFile = __webpack_require__(71); -var IsPlainObject = __webpack_require__(7); -var MultiFile = __webpack_require__(49); -var TextFile = __webpack_require__(242); + layer = this.getLayer(layer); -/** - * @classdesc - * A single text file based Unity Texture Atlas File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#unityAtlas method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#unityAtlas. - * - * @class UnityAtlasFile - * @extends Phaser.Loader.MultiFile - * @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.UnityAtlasFileConfig)} key - The key to use for this file, or a file configuration object. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas data file from. If undefined or `null` it will be set to `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings. - */ -var UnityAtlasFile = new Class({ + if (layer === null) { return null; } - Extends: MultiFile, + TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, layer); - initialize: + return this; + }, - function UnityAtlasFile (loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) + /** + * 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) { - var image; - var data; - - if (IsPlainObject(key)) - { - var config = key; + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } - key = GetFastValue(config, 'key'); + layer = this.getLayer(layer); - image = new ImageFile(loader, { - key: key, - url: GetFastValue(config, 'textureURL'), - extension: GetFastValue(config, 'textureExtension', 'png'), - normalMap: GetFastValue(config, 'normalMap'), - xhrSettings: GetFastValue(config, 'textureXhrSettings') - }); + if (layer === null) { return null; } - data = new TextFile(loader, { - key: key, - url: GetFastValue(config, 'atlasURL'), - extension: GetFastValue(config, 'atlasExtension', 'txt'), - xhrSettings: GetFastValue(config, 'atlasXhrSettings') - }); - } - else - { - image = new ImageFile(loader, key, textureURL, textureXhrSettings); - data = new TextFile(loader, key, atlasURL, atlasXhrSettings); - } + TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, layer); - if (image.linkFile) - { - // Image has a normal map - MultiFile.call(this, loader, 'unityatlas', key, [ image, data, image.linkFile ]); - } - else - { - MultiFile.call(this, loader, 'unityatlas', key, [ image, data ]); - } + return this; }, /** - * Adds this file to its target cache upon successful loading and processing. + * 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.Loader.FileTypes.UnityAtlasFile#addToCache - * @since 3.7.0 + * 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. */ - addToCache: function () + setTileIndexCallback: function (indexes, callback, callbackContext, layer) { - if (this.isReadyToProcess()) - { - var image = this.files[0]; - var text = this.files[1]; - var normalMap = (this.files[2]) ? this.files[2].data : null; + layer = this.getLayer(layer); - this.loader.textureManager.addUnityAtlas(image.key, image.data, text.data, normalMap); + if (layer === null) { return null; } - text.pendingDestroy(); + TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, layer); - this.complete = true; - } - } + 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); -/** - * Adds a Unity YAML based Texture Atlas, or array of atlases, 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.unityAtlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.txt'); - * } - * ``` - * - * The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts, - * or if it's already running, when the next free load slot becomes available. This happens automatically if you - * are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued - * it means you cannot use the file immediately after calling this method, but must wait for the file to complete. - * The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the - * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been - * loaded. - * - * If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring - * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. - * - * Phaser expects the atlas data to be provided in a YAML formatted text file as exported from Unity. - * - * Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle. - * - * The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. - * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file - * then remove it from the Texture Manager first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.unityAtlas({ - * key: 'mainmenu', - * textureURL: 'images/MainMenu.png', - * atlasURL: 'images/MainMenu.txt' - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.UnityAtlasFileConfig` for more details. - * - * Once the atlas has finished loading you can use frames from it as textures for a Game Object by referencing its key: - * - * ```javascript - * this.load.unityAtlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.json'); - * // and later in your game ... - * this.add.image(x, y, 'mainmenu', 'background'); - * ``` - * - * To get a list of all available frames within an atlas please consult your Texture Atlas software. - * - * If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files - * key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and - * this is what you would use to retrieve the image from the Texture Manager. - * - * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. - * - * If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien" - * and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although - * this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL. - * - * Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image, - * then you can specify it by providing an array as the `url` where the second element is the normal map: - * - * ```javascript - * this.load.unityAtlas('mainmenu', [ 'images/MainMenu.png', 'images/MainMenu-n.png' ], 'images/MainMenu.txt'); - * ``` - * - * Or, if you are using a config object use the `normalMap` property: - * - * ```javascript - * this.load.unityAtlas({ - * key: 'mainmenu', - * textureURL: 'images/MainMenu.png', - * normalMap: 'images/MainMenu-n.png', - * atlasURL: 'images/MainMenu.txt' - * }); - * ``` - * - * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. - * Normal maps are a WebGL only feature. - * - * Note: The ability to load this type of file will only be available if the Unity Atlas 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#unityAtlas - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Loader.FileTypes.UnityAtlasFileConfig|Phaser.Types.Loader.FileTypes.UnityAtlasFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them. - * @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `.png`, i.e. if `key` was "alien" then the URL will be "alien.png". - * @param {string} [atlasURL] - The absolute or relative URL to load the texture atlas data file from. If undefined or `null` it will be set to `.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt". - * @param {Phaser.Types.Loader.XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings. - * @param {Phaser.Types.Loader.XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings. - * - * @return {this} The Loader instance. - */ -FileTypesManager.register('unityAtlas', function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) -{ - var multifile; + if (layer === null) { return null; } - // Supports an Object file definition in the key argument - // Or an array of objects in the key argument - // Or a single entry where all arguments have been defined + TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, layer); - if (Array.isArray(key)) + 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) { - for (var i = 0; i < key.length; i++) - { - multifile = new UnityAtlasFile(this, key[i]); + var index = this.getLayerIndex(layer); - this.addFile(multifile.files); + if (index !== null) + { + this.currentLayerIndex = index; } - } - else - { - multifile = new UnityAtlasFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings); - this.addFile(multifile.files); - } + return this; + }, - 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; -module.exports = UnityAtlasFile; + // 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; -/***/ }), -/* 1364 */ -/***/ (function(module, exports, __webpack_require__) { + for (var row = 0; row < mapHeight; row++) + { + for (var col = 0; col < mapWidth; col++) + { + var tile = mapData[row][col]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (tile !== null) + { + tile.setSize(undefined, undefined, tileWidth, tileHeight); + } + } + } + } -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var File = __webpack_require__(23); -var FileTypesManager = __webpack_require__(8); -var GetURL = __webpack_require__(155); -var GetFastValue = __webpack_require__(2); -var IsPlainObject = __webpack_require__(7); + return this; + }, -/** - * @classdesc - * A single Video File suitable for loading by the Loader. - * - * These are created when you use the Phaser.Loader.LoaderPlugin#video method and are not typically created directly. - * - * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#video. - * - * @class VideoFile - * @extends Phaser.Loader.File - * @memberof Phaser.Loader.FileTypes - * @constructor - * @since 3.20.0 - * - * @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file. - * @param {(string|Phaser.Types.Loader.FileTypes.VideoFileConfig)} 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 {string} [loadEvent] - The load event to listen for when _not_ loading as a blob. Either 'loadeddata', 'canplay' or 'canplaythrough'. - * @param {boolean} [asBlob] - Load the video as a data blob, or via the Video element? - * @param {boolean} [noAudio] - Does the video have an audio track? If not you can enable auto-playing on it. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - Extra XHR Settings specifically for this file. - */ -var VideoFile = new Class({ + /** + * 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); - Extends: File, + if (layer === null) { return this; } - initialize: + layer.tileWidth = tileWidth; + layer.tileHeight = tileHeight; - // URL is an object created by VideoFile.getVideoURL - function VideoFile (loader, key, urlConfig, loadEvent, asBlob, noAudio, xhrSettings) - { - if (loadEvent === undefined) { loadEvent = 'loadeddata'; } - if (asBlob === undefined) { asBlob = false; } - if (noAudio === undefined) { noAudio = false; } + var mapData = layer.data; + var mapWidth = layer.width; + var mapHeight = layer.height; - if (loadEvent !== 'loadeddata' && loadEvent !== 'canplay' && loadEvent !== 'canplaythrough') + for (var row = 0; row < mapHeight; row++) { - loadEvent = 'loadeddata'; - } + for (var col = 0; col < mapWidth; col++) + { + var tile = mapData[row][col]; - var fileConfig = { - type: 'video', - cache: loader.cacheManager.video, - extension: urlConfig.type, - responseType: 'blob', - key: key, - url: urlConfig.url, - xhrSettings: xhrSettings, - config: { - loadEvent: loadEvent, - asBlob: asBlob, - noAudio: noAudio + if (tile !== null) + { + tile.setSize(tileWidth, tileHeight); + } } - }; - - this.onLoadCallback = this.onVideoLoadHandler.bind(this); - this.onErrorCallback = this.onVideoErrorHandler.bind(this); + } - File.call(this, loader, fileConfig); + return this; }, /** - * Called automatically by Loader.nextFile. - * This method controls what extra work this File does with its loaded data. + * 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.Loader.FileTypes.VideoFile#onProcess - * @since 3.20.0 + * 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. */ - onProcess: function () + shuffle: function (tileX, tileY, width, height, layer) { - this.state = CONST.FILE_PROCESSING; - - if (!this.config.asBlob) - { - this.onProcessComplete(); + layer = this.getLayer(layer); - return; - } + if (layer === null) { return null; } - // Load Video as blob + TilemapComponents.Shuffle(tileX, tileY, width, height, layer); - var video = this.createVideoElement(); + return this; + }, - this.data = video; + /** + * 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); - var _this = this; + if (layer === null) { return null; } - this.data.onloadeddata = function () - { - _this.onProcessComplete(); - }; + TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, layer); - this.data.onerror = function () - { - File.revokeObjectURL(_this.data); + return this; + }, - _this.onProcessError(); - }; + /** + * 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); - File.createObjectURL(video, this.xhrLoader.response, ''); + if (layer === null) { return null; } - video.load(); + return this._convert.TileToWorldX(tileX, camera, layer); }, /** - * Creates a Video Element within the DOM. + * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layers position, scale and scroll. * - * @method Phaser.Loader.FileTypes.VideoFile#createVideoElement - * @private - * @since 3.20.0 + * 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 {HTMLVideoElement} The newly created Video element. + * @return {?number} Returns a number, or null if the layer given was invalid. */ - createVideoElement: function () + tileToWorldY: function (tileY, camera, layer) { - var video = document.createElement('video'); + layer = this.getLayer(layer); - video.controls = false; - video.crossOrigin = this.loader.crossOrigin; + if (layer === null) { return null; } - if (this.config.noAudio) - { - video.muted = true; - video.defaultMuted = true; + return this._convert.TileToWorldY(tileY, camera, layer); + }, - video.setAttribute('autoplay', 'autoplay'); - } + /** + * 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); - video.setAttribute('playsinline', 'playsinline'); - video.setAttribute('preload', 'auto'); + if (layer === null) { return null; } - return video; + return this._convert.TileToWorldXY(tileX, tileY, vec2, camera, layer); }, /** - * Internal load event callback. + * Returns an array of Vector2s where each entry corresponds to the corner of the requested tile. * - * @method Phaser.Loader.FileTypes.VideoFile#onVideoLoadHandler - * @private - * @since 3.20.0 + * The `tileX` and `tileY` parameters are in tile coordinates, not world coordinates. * - * @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this load. + * The corner coordinates are in world space, having factored in TilemapLayer scale, position + * and the camera, if given. + * + * The size of the array will vary based on the orientation of the map. For example an + * orthographic map will return an array of 4 vectors, where-as a hexagonal map will, + * of course, return an array of 6 corner vectors. + * + * If no layer is specified, the maps current layer is used. + * + * @method Phaser.Tilemaps.Tilemap#getTileCorners + * @since 3.60.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @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 {?Phaser.Math.Vector2[]} Returns an array of Vector2s, or null if the layer given was invalid. */ - onVideoLoadHandler: function (event) + getTileCorners: function (tileX, tileY, camera, layer) { - var video = event.target; - - video.removeEventListener(this.config.loadEvent, this.onLoadCallback, true); - video.removeEventListener('error', this.onErrorCallback, true); - - this.data = video; + layer = this.getLayer(layer); - this.resetXHR(); + if (layer === null) { return null; } - this.loader.nextFile(this, true); + return this._convert.GetTileCorners(tileX, tileY, camera, layer); }, /** - * Internal load error event callback. + * 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: * - * @method Phaser.Loader.FileTypes.VideoFile#onVideoErrorHandler - * @private - * @since 3.20.0 + * [ + * { 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 + * ] * - * @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this load. + * 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. */ - onVideoErrorHandler: function (event) + weightedRandomize: function (weightedIndexes, tileX, tileY, width, height, layer) { - var video = event.target; + layer = this.getLayer(layer); - if (video) - { - video.removeEventListener(this.config.loadEvent, this.onLoadCallback, true); - video.removeEventListener('error', this.onErrorCallback, true); - } + if (layer === null) { return null; } - this.resetXHR(); + TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, layer); - this.loader.nextFile(this, false); + return this; }, /** - * 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. + * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the + * layers position, scale and scroll. * - * @method Phaser.Loader.FileTypes.VideoFile#load - * @since 3.20.0 + * If no layer is specified, the maps current layer is used. + * + * You cannot call this method for Isometric or Hexagonal tilemaps as they require + * both `worldX` and `worldY` values to determine the correct tile, instead you + * should use the `worldToTileXY` method. + * + * @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. */ - load: function () + worldToTileX: function (worldX, snapToFloor, camera, layer) { - var loadEvent = this.config.loadEvent; + layer = this.getLayer(layer); - if (this.config.asBlob) - { - File.prototype.load.call(this); - } - else - { - this.percentComplete = 0; + if (layer === null) { return null; } + + return this._convert.WorldToTileX(worldX, snapToFloor, camera, layer); + }, - var video = this.createVideoElement(); + /** + * 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. + * + * You cannot call this method for Isometric or Hexagonal tilemaps as they require + * both `worldX` and `worldY` values to determine the correct tile, instead you + * should use the `worldToTileXY` method. + * + * @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); - video.addEventListener(loadEvent, this.onLoadCallback, true); - video.addEventListener('error', this.onErrorCallback, true); + if (layer === null) { return null; } - video.src = GetURL(this, this.loader.baseURL); + return this._convert.WorldToTileY(worldY, snapToFloor, camera, layer); + }, - video.load(); - } - } + /** + * 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; } -VideoFile.create = function (loader, key, urls, loadEvent, asBlob, noAudio, xhrSettings) -{ - var game = loader.systems.game; + return this._convert.WorldToTileXY(worldX, worldY, snapToFloor, vec2, camera, layer); + }, - // url may be inside key, which may be an object - if (IsPlainObject(key)) + /** + * 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 () { - urls = GetFastValue(key, 'url', []); - loadEvent = GetFastValue(key, 'loadEvent', 'loadeddata'); - asBlob = GetFastValue(key, 'asBlob', false); - noAudio = GetFastValue(key, 'noAudio', false); - xhrSettings = GetFastValue(key, 'xhrSettings'); - key = GetFastValue(key, 'key'); - } + this.removeAllLayers(); - var urlConfig = VideoFile.getVideoURL(game, urls); - - if (urlConfig) - { - return new VideoFile(loader, key, urlConfig, loadEvent, asBlob, noAudio, xhrSettings); - } -}; + this.tiles.length = 0; + this.tilesets.length = 0; + this.objects.length = 0; -VideoFile.getVideoURL = function (game, urls) -{ - if (!Array.isArray(urls)) - { - urls = [ urls ]; + this.scene = null; } - for (var i = 0; i < urls.length; i++) - { - var url = GetFastValue(urls[i], 'url', urls[i]); +}); - if (url.indexOf('blob:') === 0) - { - return { - url: url, - type: '' - }; - } +module.exports = Tilemap; - var videoType; - if (url.indexOf('data:') === 0) - { - videoType = url.split(',')[0].match(/\/(.*?);/); - } - else - { - videoType = url.match(/\.([a-zA-Z0-9]+)($|\?)/); - } +/***/ }), - videoType = GetFastValue(urls[i], 'type', (videoType) ? videoType[1] : '').toLowerCase(); +/***/ 4843: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { - if (game.device.video[videoType]) - { - return { - url: url, - type: videoType - }; - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return null; -}; +var GameObjectCreator = __webpack_require__(99325); +var ParseToTilemap = __webpack_require__(15043); /** - * Adds a Video file, or array of video 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.video('intro', [ 'video/level1.mp4', 'video/level1.webm', 'video/level1.mov' ]); - * } - * ``` - * - * 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 Video Cache upon a successful load. - * The key should be unique both in terms of files being loaded and files already present in the Video 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 Video Cache first, before loading a new one. - * - * Instead of passing arguments you can pass a configuration object, such as: - * - * ```javascript - * this.load.video({ - * key: 'intro', - * url: [ 'video/level1.mp4', 'video/level1.webm', 'video/level1.mov' ], - * asBlob: false, - * noAudio: true - * }); - * ``` - * - * See the documentation for `Phaser.Types.Loader.FileTypes.VideoFileConfig` 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. + * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. + * When loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing + * from a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map + * data. For an empty map, you should specify tileWidth, tileHeight, width & height. * - * Due to different browsers supporting different video file types you should usually provide your video files in a variety of formats. - * mp4, mov and webm 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, starting with the first in the array and progressing to the end. + * @method Phaser.GameObjects.GameObjectCreator#tilemap + * @since 3.0.0 * - * Unlike most asset-types, videos do not _need_ to be preloaded. You can create a Video Game Object and then call its `loadURL` method, - * to load a video at run-time, rather than in advance. + * @param {Phaser.Types.Tilemaps.TilemapConfig} [config] - The config options for the Tilemap. * - * Note: The ability to load this type of file will only be available if the Video File type has been built into Phaser. - * It is available in the default build but can be excluded from custom builds. + * @return {Phaser.Tilemaps.Tilemap} + */ +GameObjectCreator.register('tilemap', function (config) +{ + // Defaults are applied in ParseToTilemap + var c = (config !== undefined) ? config : {}; + + return ParseToTilemap( + this.scene, + c.key, + c.tileWidth, + c.tileHeight, + c.width, + c.height, + c.data, + c.insertNull + ); +}); + + +/***/ }), + +/***/ 37940: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GameObjectFactory = __webpack_require__(61286); +var ParseToTilemap = __webpack_require__(15043); + +/** + * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. + * When loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing + * from a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map + * data. For an empty map, you should specify tileWidth, tileHeight, width & height. * - * @method Phaser.Loader.LoaderPlugin#video - * @fires Phaser.Loader.LoaderPlugin#ADD - * @since 3.20.0 + * @method Phaser.GameObjects.GameObjectFactory#tilemap + * @since 3.0.0 * - * @param {(string|Phaser.Types.Loader.FileTypes.VideoFileConfig|Phaser.Types.Loader.FileTypes.VideoFileConfig[])} 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 video files from. - * @param {string} [loadEvent='loadeddata'] - The load event to listen for when _not_ loading as a blob. Either `loadeddata`, `canplay` or `canplaythrough`. - * @param {boolean} [asBlob=false] - Load the video as a data blob, or stream it via the Video element? - * @param {boolean} [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it. - * @param {Phaser.Types.Loader.XHRSettingsObject} [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. + * @param {string} [key] - The key in the Phaser cache that corresponds to the loaded tilemap data. + * @param {number} [tileWidth=32] - The width of a tile in pixels. Pass in `null` to leave as the + * default. + * @param {number} [tileHeight=32] - The height of a tile in pixels. Pass in `null` to leave as the + * default. + * @param {number} [width=10] - The width of the map in tiles. Pass in `null` to leave as the + * default. + * @param {number} [height=10] - The height of the map in tiles. Pass in `null` to leave as the + * default. + * @param {number[][]} [data] - Instead of loading from the cache, you can also load directly from + * a 2D array of tile indexes. Pass in `null` for no data. + * @param {boolean} [insertNull=false] - 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 {this} The Loader instance. + * @return {Phaser.Tilemaps.Tilemap} */ -FileTypesManager.register('video', function (key, urls, loadEvent, asBlob, noAudio, xhrSettings) +GameObjectFactory.register('tilemap', function (key, tileWidth, tileHeight, width, height, data, insertNull) { - var videoFile; - - 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 - videoFile = VideoFile.create(this, key[i]); - - if (videoFile) - { - this.addFile(videoFile); - } - } - } - else - { - videoFile = VideoFile.create(this, key, urls, loadEvent, asBlob, noAudio, xhrSettings); + // Allow users to specify null to indicate that they want the default value, since null is + // shorter & more legible than undefined. Convert null to undefined to allow ParseToTilemap + // defaults to take effect. - if (videoFile) - { - this.addFile(videoFile); - } - } + if (key === null) { key = undefined; } + if (tileWidth === null) { tileWidth = undefined; } + if (tileHeight === null) { tileHeight = undefined; } + if (width === null) { width = undefined; } + if (height === null) { height = undefined; } - return this; + return ParseToTilemap(this.scene, key, tileWidth, tileHeight, width, height, data, insertNull); }); -module.exports = VideoFile; +// When registering a factory function 'this' refers to the GameObjectFactory 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 /***/ }), -/* 1365 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 87177: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var CONST = __webpack_require__(21); -var CustomSet = __webpack_require__(149); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(95); -var FileTypesManager = __webpack_require__(8); -var GetFastValue = __webpack_require__(2); -var PluginCache = __webpack_require__(24); -var SceneEvents = __webpack_require__(20); -var XHRSettings = __webpack_require__(156); +var Class = __webpack_require__(56694); +var Components = __webpack_require__(64937); +var GameObject = __webpack_require__(89980); +var TilemapComponents = __webpack_require__(5047); +var TilemapLayerRender = __webpack_require__(96193); +var Vector2 = __webpack_require__(93736); /** * @classdesc - * The Loader handles loading all external content such as Images, Sounds, Texture Atlases and data files. - * You typically interact with it via `this.load` in your Scene. Scenes can have a `preload` method, which is always - * called before the Scenes `create` method, allowing you to preload assets that the Scene may need. - * - * If you call any `this.load` methods from outside of `Scene.preload` then you need to start the Loader going - * yourself by calling `Loader.start()`. It's only automatically started during the Scene preload. - * - * The Loader uses a combination of tag loading (eg. Audio elements) and XHR and provides progress and completion events. - * Files are loaded in parallel by default. The amount of concurrent connections can be controlled in your Game Configuration. - * - * Once the Loader has started loading you are still able to add files to it. These can be injected as a result of a loader - * event, the type of file being loaded (such as a pack file) or other external events. As long as the Loader hasn't finished - * simply adding a new file to it, while running, will ensure it's added into the current queue. - * - * Every Scene has its own instance of the Loader and they are bound to the Scene in which they are created. However, - * assets loaded by the Loader are placed into global game-level caches. For example, loading an XML file will place that - * file inside `Game.cache.xml`, which is accessible from every Scene in your game, no matter who was responsible - * for loading it. The same is true of Textures. A texture loaded in one Scene is instantly available to all other Scenes - * in your game. - * - * The Loader works by using custom File Types. These are stored in the FileTypesManager, which injects them into the Loader - * when it's instantiated. You can create your own custom file types by extending either the File or MultiFile classes. - * See those files for more details. + * A Tilemap Layer is a Game Object that renders LayerData from a Tilemap when used in combination + * with one, or more, Tilesets. * - * @class LoaderPlugin - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Loader + * @class TilemapLayer + * @extends Phaser.GameObjects.GameObject + * @memberof Phaser.Tilemaps * @constructor - * @since 3.0.0 + * @since 3.50.0 * - * @param {Phaser.Scene} scene - The Scene which owns this Loader instance. + * @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.Mask + * @extends Phaser.GameObjects.Components.Origin + * @extends Phaser.GameObjects.Components.Pipeline + * @extends Phaser.GameObjects.Components.PostPipeline + * @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 LoaderPlugin = new Class({ +var TilemapLayer = new Class({ - Extends: EventEmitter, + Extends: GameObject, + + Mixins: [ + Components.Alpha, + Components.BlendMode, + Components.ComputedSize, + Components.Depth, + Components.Flip, + Components.GetBounds, + Components.Mask, + Components.Origin, + Components.Pipeline, + Components.PostPipeline, + Components.Transform, + Components.Visible, + Components.ScrollFactor, + TilemapLayerRender + ], initialize: - function LoaderPlugin (scene) + function TilemapLayer (scene, tilemap, layerIndex, tileset, x, y) { - EventEmitter.call(this); - - var gameConfig = scene.sys.game.config; - var sceneConfig = scene.sys.settings.loader; + GameObject.call(this, scene, 'TilemapLayer'); /** - * The Scene which owns this Loader instance. + * Used internally by physics system to perform fast type checks. * - * @name Phaser.Loader.LoaderPlugin#scene - * @type {Phaser.Scene} - * @since 3.0.0 + * @name Phaser.Tilemaps.TilemapLayer#isTilemap + * @type {boolean} + * @readonly + * @since 3.50.0 */ - this.scene = scene; + this.isTilemap = true; /** - * A reference to the Scene Systems. + * The Tilemap that this layer is a part of. * - * @name Phaser.Loader.LoaderPlugin#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 + * @name Phaser.Tilemaps.TilemapLayer#tilemap + * @type {Phaser.Tilemaps.Tilemap} + * @since 3.50.0 */ - this.systems = scene.sys; + this.tilemap = tilemap; /** - * A reference to the global Cache Manager. + * The index of the LayerData associated with this layer. * - * @name Phaser.Loader.LoaderPlugin#cacheManager - * @type {Phaser.Cache.CacheManager} - * @since 3.7.0 + * @name Phaser.Tilemaps.TilemapLayer#layerIndex + * @type {number} + * @since 3.50.0 */ - this.cacheManager = scene.sys.cache; + this.layerIndex = layerIndex; /** - * A reference to the global Texture Manager. + * The LayerData associated with this layer. LayerData can only be associated with one + * tilemap layer. * - * @name Phaser.Loader.LoaderPlugin#textureManager - * @type {Phaser.Textures.TextureManager} - * @since 3.7.0 + * @name Phaser.Tilemaps.TilemapLayer#layer + * @type {Phaser.Tilemaps.LayerData} + * @since 3.50.0 */ - this.textureManager = scene.sys.textures; + this.layer = tilemap.layers[layerIndex]; + + // Link the LayerData with this static tilemap layer + this.layer.tilemapLayer = this; /** - * A reference to the global Scene Manager. + * An array of `Tileset` objects associated with this layer. * - * @name Phaser.Loader.LoaderPlugin#sceneManager - * @type {Phaser.Scenes.SceneManager} - * @protected - * @since 3.16.0 + * @name Phaser.Tilemaps.TilemapLayer#tileset + * @type {Phaser.Tilemaps.Tileset[]} + * @since 3.50.0 */ - this.sceneManager = scene.sys.game.scene; - - // Inject the available filetypes into the Loader - FileTypesManager.install(this); + this.tileset = []; /** - * An optional prefix that is automatically prepended to the start of every file key. - * If prefix was `MENU.` and you load an image with the key 'Background' the resulting key would be `MENU.Background`. - * You can set this directly, or call `Loader.setPrefix()`. It will then affect every file added to the Loader - * from that point on. It does _not_ change any file already in the load queue. + * The total number of tiles drawn by the renderer in the last frame. * - * @name Phaser.Loader.LoaderPlugin#prefix - * @type {string} - * @default '' - * @since 3.7.0 + * @name Phaser.Tilemaps.TilemapLayer#tilesDrawn + * @type {number} + * @readonly + * @since 3.50.0 */ - this.prefix = ''; + this.tilesDrawn = 0; /** - * The value of `path`, if set, is placed before any _relative_ file path given. For example: - * - * ```javascript - * this.load.path = "images/sprites/"; - * this.load.image("ball", "ball.png"); - * this.load.image("tree", "level1/oaktree.png"); - * this.load.image("boom", "http://server.com/explode.png"); - * ``` - * - * Would load the `ball` file from `images/sprites/ball.png` and the tree from - * `images/sprites/level1/oaktree.png` but the file `boom` would load from the URL - * given as it's an absolute URL. - * - * Please note that the path is added before the filename but *after* the baseURL (if set.) - * - * If you set this property directly then it _must_ end with a "/". Alternatively, call `setPath()` and it'll do it for you. + * The total number of tiles in this layer. Updated every frame. * - * @name Phaser.Loader.LoaderPlugin#path - * @type {string} - * @default '' - * @since 3.0.0 + * @name Phaser.Tilemaps.TilemapLayer#tilesTotal + * @type {number} + * @readonly + * @since 3.50.0 */ - this.path = ''; + this.tilesTotal = this.layer.width * this.layer.height; /** - * If you want to append a URL before the path of any asset you can set this here. - * - * Useful if allowing the asset base url to be configured outside of the game code. - * - * If you set this property directly then it _must_ end with a "/". Alternatively, call `setBaseURL()` and it'll do it for you. + * Used internally during rendering. This holds the tiles that are visible within the Camera. * - * @name Phaser.Loader.LoaderPlugin#baseURL - * @type {string} - * @default '' - * @since 3.0.0 + * @name Phaser.Tilemaps.TilemapLayer#culledTiles + * @type {Phaser.Tilemaps.Tile[]} + * @since 3.50.0 */ - this.baseURL = ''; - - this.setBaseURL(GetFastValue(sceneConfig, 'baseURL', gameConfig.loaderBaseURL)); - - this.setPath(GetFastValue(sceneConfig, 'path', gameConfig.loaderPath)); - - this.setPrefix(GetFastValue(sceneConfig, 'prefix', gameConfig.loaderPrefix)); + this.culledTiles = []; /** - * The number of concurrent / parallel resources to try and fetch at once. + * You can control if the camera should cull tiles on this layer before rendering them or not. * - * Old browsers limit 6 requests per domain; modern ones, especially those with HTTP/2 don't limit it at all. + * By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer. * - * The default is 32 but you can change this in your Game Config, or by changing this property before the Loader starts. + * 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.Loader.LoaderPlugin#maxParallelDownloads - * @type {number} - * @since 3.0.0 + * @name Phaser.Tilemaps.TilemapLayer#skipCull + * @type {boolean} + * @since 3.50.0 */ - this.maxParallelDownloads = GetFastValue(sceneConfig, 'maxParallelDownloads', gameConfig.loaderMaxParallelDownloads); + this.skipCull = false; /** - * xhr specific global settings (can be overridden on a per-file basis) + * The amount of extra tiles to add into the cull rectangle when calculating its horizontal size. * - * @name Phaser.Loader.LoaderPlugin#xhr - * @type {Phaser.Types.Loader.XHRSettingsObject} - * @since 3.0.0 + * See the method `setCullPadding` for more details. + * + * @name Phaser.Tilemaps.TilemapLayer#cullPaddingX + * @type {number} + * @default 1 + * @since 3.50.0 */ - this.xhr = XHRSettings( - GetFastValue(sceneConfig, 'responseType', gameConfig.loaderResponseType), - GetFastValue(sceneConfig, 'async', gameConfig.loaderAsync), - GetFastValue(sceneConfig, 'user', gameConfig.loaderUser), - GetFastValue(sceneConfig, 'password', gameConfig.loaderPassword), - GetFastValue(sceneConfig, 'timeout', gameConfig.loaderTimeout), - GetFastValue(sceneConfig, 'withCredentials', gameConfig.loaderWithCredentials) - ); + this.cullPaddingX = 1; /** - * The crossOrigin value applied to loaded images. Very often this needs to be set to 'anonymous'. + * The amount of extra tiles to add into the cull rectangle when calculating its vertical size. * - * @name Phaser.Loader.LoaderPlugin#crossOrigin - * @type {string} - * @since 3.0.0 + * See the method `setCullPadding` for more details. + * + * @name Phaser.Tilemaps.TilemapLayer#cullPaddingY + * @type {number} + * @default 1 + * @since 3.50.0 */ - this.crossOrigin = GetFastValue(sceneConfig, 'crossOrigin', gameConfig.loaderCrossOrigin); + this.cullPaddingY = 1; /** - * The total number of files to load. It may not always be accurate because you may add to the Loader during the process - * of loading, especially if you load a Pack File. Therefore this value can change, but in most cases remains static. + * The callback that is invoked when the tiles are culled. * - * @name Phaser.Loader.LoaderPlugin#totalToLoad - * @type {number} - * @default 0 - * @since 3.0.0 + * 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.totalToLoad = 0; + this.cullCallback = TilemapComponents.GetCullTilesFunction(this.layer.orientation); /** - * The progress of the current load queue, as a float value between 0 and 1. - * This is updated automatically as files complete loading. - * Note that it is possible for this value to go down again if you add content to the current load queue during a load. + * The rendering (draw) order of the tiles in this layer. * - * @name Phaser.Loader.LoaderPlugin#progress + * 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 - * @since 3.0.0 + * @private + * @since 3.50.0 */ - this.progress = 0; + this._renderOrder = 0; /** - * Files are placed in this Set when they're added to the Loader via `addFile`. - * - * They are moved to the `inflight` Set when they start loading, and assuming a successful - * load, to the `queue` Set for further processing. - * - * By the end of the load process this Set will be empty. + * An array holding the mapping between the tile indexes and the tileset they belong to. * - * @name Phaser.Loader.LoaderPlugin#list - * @type {Phaser.Structs.Set.} - * @since 3.0.0 + * @name Phaser.Tilemaps.TilemapLayer#gidMap + * @type {Phaser.Tilemaps.Tileset[]} + * @since 3.50.0 */ - this.list = new CustomSet(); + this.gidMap = []; /** - * Files are stored in this Set while they're in the process of being loaded. - * - * Upon a successful load they are moved to the `queue` Set. + * A temporary Vector2 used in the tile coordinate methods. * - * By the end of the load process this Set will be empty. - * - * @name Phaser.Loader.LoaderPlugin#inflight - * @type {Phaser.Structs.Set.} - * @since 3.0.0 + * @name Phaser.Tilemaps.TilemapLayer#tempVec + * @type {Phaser.Math.Vector2} + * @private + * @since 3.60.0 */ - this.inflight = new CustomSet(); + this.tempVec = new Vector2(); /** - * Files are stored in this Set while they're being processed. - * - * If the process is successful they are moved to their final destination, which could be - * a Cache or the Texture Manager. + * The horizontal origin of this Tilemap Layer. * - * At the end of the load process this Set will be empty. - * - * @name Phaser.Loader.LoaderPlugin#queue - * @type {Phaser.Structs.Set.} + * @name Phaser.Tilemaps.TilemapLayer#originX + * @type {number} + * @default 0 + * @readOnly * @since 3.0.0 */ - this.queue = new CustomSet(); /** - * A temporary Set in which files are stored after processing, - * awaiting destruction at the end of the load process. + * The vertical origin of this Tilemap Layer. * - * @name Phaser.Loader.LoaderPlugin#_deleteQueue - * @type {Phaser.Structs.Set.} - * @private - * @since 3.7.0 + * @name Phaser.Tilemaps.TilemapLayer#originY + * @type {number} + * @default 0 + * @readOnly + * @since 3.0.0 */ - this._deleteQueue = new CustomSet(); /** - * The total number of files that failed to load during the most recent load. - * This value is reset when you call `Loader.start`. + * The horizontal display origin of this Tilemap Layer. * - * @name Phaser.Loader.LoaderPlugin#totalFailed + * @name Phaser.Tilemaps.TilemapLayer#displayOriginX * @type {number} * @default 0 - * @since 3.7.0 + * @readOnly + * @since 3.0.0 */ - this.totalFailed = 0; /** - * The total number of files that successfully loaded during the most recent load. - * This value is reset when you call `Loader.start`. + * The vertical display origin of this Tilemap Layer. * - * @name Phaser.Loader.LoaderPlugin#totalComplete + * @name Phaser.Tilemaps.TilemapLayer#displayOriginY * @type {number} * @default 0 - * @since 3.7.0 + * @readOnly + * @since 3.0.0 */ - this.totalComplete = 0; - /** - * The current state of the Loader. - * - * @name Phaser.Loader.LoaderPlugin#state - * @type {number} - * @readonly - * @since 3.0.0 - */ - this.state = CONST.LOADER_IDLE; + this.setTilesets(tileset); + this.setAlpha(this.layer.alpha); + this.setPosition(x, y); + this.setOrigin(0, 0); + this.setSize(tilemap.tileWidth * this.layer.width, tilemap.tileHeight * this.layer.height); + + this.initPipeline(); + this.initPostPipeline(false); + }, + + /** + * 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); + }, - /** - * The current index being used by multi-file loaders to avoid key clashes. - * - * @name Phaser.Loader.LoaderPlugin#multiKeyIndex - * @type {number} - * @private - * @since 3.20.0 - */ - this.multiKeyIndex = 0; + /** + * 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); - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); - scene.sys.events.on(SceneEvents.START, this.pluginStart, this); + return this; }, /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. + * 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.Loader.LoaderPlugin#boot - * @private - * @since 3.5.1 + * @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. */ - boot: function () + fill: function (index, tileX, tileY, width, height, recalculateFaces) { - this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); + TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, this.layer); + + return this; }, /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. + * 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.Loader.LoaderPlugin#pluginStart - * @private - * @since 3.5.1 + * @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. */ - pluginStart: function () + filterTiles: function (callback, context, tileX, tileY, width, height, filteringOptions) { - this.systems.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); + return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); }, /** - * If you want to append a URL before the path of any asset you can set this here. + * 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. * - * Useful if allowing the asset base url to be configured outside of the game code. + * @method Phaser.Tilemaps.TilemapLayer#findByIndex + * @since 3.50.0 * - * Once a base URL is set it will affect every file loaded by the Loader from that point on. It does _not_ change any - * file _already_ being loaded. To reset it, call this method with no arguments. + * @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. * - * @method Phaser.Loader.LoaderPlugin#setBaseURL - * @since 3.0.0 + * @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. * - * @param {string} [url] - The URL to use. Leave empty to reset. + * @method Phaser.Tilemaps.TilemapLayer#findTile + * @since 3.50.0 * - * @return {this} This Loader object. + * @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. */ - setBaseURL: function (url) + findTile: function (callback, context, tileX, tileY, width, height, filteringOptions) { - if (url === undefined) { url = ''; } - - if (url !== '' && url.substr(-1) !== '/') - { - url = url.concat('/'); - } + return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer); + }, - this.baseURL = url; + /** + * 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; }, /** - * The value of `path`, if set, is placed before any _relative_ file path given. For example: + * Sets an additive tint on each Tile within the given area. * - * ```javascript - * this.load.setPath("images/sprites/"); - * this.load.image("ball", "ball.png"); - * this.load.image("tree", "level1/oaktree.png"); - * this.load.image("boom", "http://server.com/explode.png"); - * ``` + * The tint works by taking the pixel color values from the tileset texture, and then + * multiplying it by the color value of the tint. * - * Would load the `ball` file from `images/sprites/ball.png` and the tree from - * `images/sprites/level1/oaktree.png` but the file `boom` would load from the URL - * given as it's an absolute URL. + * If no area values are given then all tiles will be tinted to the given color. * - * Please note that the path is added before the filename but *after* the baseURL (if set.) + * To remove a tint call this method with either no parameters, or by passing white `0xffffff` as the tint color. * - * Once a path is set it will then affect every file added to the Loader from that point on. It does _not_ change any - * file _already_ in the load queue. To reset it, call this method with no arguments. + * If a tile already has a tint set then calling this method will override that. * - * @method Phaser.Loader.LoaderPlugin#setPath - * @since 3.0.0 + * @method Phaser.Tilemaps.TilemapLayer#setTint + * @webglOnly + * @since 3.60.0 * - * @param {string} [path] - The path to use. Leave empty to reset. + * @param {number} [tint=0xffffff] - The tint color being applied to each tile within the region. Given as a hex value, i.e. `0xff0000` for red. Set to white (`0xffffff`) to reset the tint. + * @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 Loader object. + * @return {this} This Tilemap Layer object. */ - setPath: function (path) + setTint: function (tint, tileX, tileY, width, height, filteringOptions) { - if (path === undefined) { path = ''; } + if (tint === undefined) { tint = 0xffffff; } - if (path !== '' && path.substr(-1) !== '/') + var tintTile = function (tile) { - path = path.concat('/'); - } + tile.tint = tint; + }; - this.path = path; + return this.forEachTile(tintTile, this, tileX, tileY, width, height, filteringOptions); + }, - 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); }, /** - * An optional prefix that is automatically prepended to the start of every file key. + * Gets a tile at the given world coordinates from the given layer. * - * If prefix was `MENU.` and you load an image with the key 'Background' the resulting key would be `MENU.Background`. + * @method Phaser.Tilemaps.TilemapLayer#getTileAtWorldXY + * @since 3.50.0 * - * Once a prefix is set it will then affect every file added to the Loader from that point on. It does _not_ change any - * file _already_ in the load queue. To reset it, call this method with no arguments. + * @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. * - * @method Phaser.Loader.LoaderPlugin#setPrefix - * @since 3.7.0 + * @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 a tile at the given world coordinates from the given isometric layer. * - * @param {string} [prefix] - The prefix to use. Leave empty to reset. + * @method Phaser.Tilemaps.TilemapLayer#getIsoTileAtWorldXY + * @since 3.60.0 * - * @return {this} This Loader object. + * @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} [originTop=true] - Which is the active face of the isometric tile? The top (default, true), or the base? (false) + * @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. */ - setPrefix: function (prefix) + getIsoTileAtWorldXY: function (worldX, worldY, originTop, nonNull, camera) { - if (prefix === undefined) { prefix = ''; } + if (originTop === undefined) { originTop = true; } - this.prefix = prefix; + var point = this.tempVec; - return this; + TilemapComponents.IsometricWorldToTileXY(worldX, worldY, true, point, camera, this.layer, originTop); + + return this.getTileAt(point.x, point.y, nonNull); }, /** - * Sets the Cross Origin Resource Sharing value used when loading files. + * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. * - * Files can override this value on a per-file basis by specifying an alternative `crossOrigin` value in their file config. + * @method Phaser.Tilemaps.TilemapLayer#getTilesWithin + * @since 3.50.0 * - * Once CORs is set it will then affect every file loaded by the Loader from that point on, as long as they don't have - * their own CORs setting. To reset it, call this method with no arguments. + * @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. * - * For more details about CORs see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS + * @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.Loader.LoaderPlugin#setCORS - * @since 3.0.0 + * @method Phaser.Tilemaps.TilemapLayer#getTilesWithinShape + * @since 3.50.0 * - * @param {string} [crossOrigin] - The value to use for the `crossOrigin` property in the load request. + * @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 {this} This Loader object. + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the shape. */ - setCORS: function (crossOrigin) + getTilesWithinShape: function (shape, filteringOptions, camera) { - this.crossOrigin = crossOrigin; + return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, this.layer); + }, - return this; + /** + * 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); }, /** - * Adds a file, or array of files, into the load queue. + * 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. * - * The file must be an instance of `Phaser.Loader.File`, or a class that extends it. The Loader will check that the key - * used by the file won't conflict with any other key either in the loader, the inflight queue or the target cache. - * If allowed it will then add the file into the pending list, read for the load to start. Or, if the load has already - * started, ready for the next batch of files to be pulled from the list to the inflight queue. + * @method Phaser.Tilemaps.TilemapLayer#hasTileAt + * @since 3.50.0 * - * You should not normally call this method directly, but rather use one of the Loader methods like `image` or `atlas`, - * however you can call this as long as the file given to it is well formed. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @param {number} tileY - The y coordinate, in tiles, not pixels. * - * @method Phaser.Loader.LoaderPlugin#addFile - * @fires Phaser.Loader.Events#ADD - * @since 3.0.0 + * @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. * - * @param {(Phaser.Loader.File|Phaser.Loader.File[])} file - The file, or array of files, to be added to the load queue. + * @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`. */ - addFile: function (file) + hasTileAtWorldXY: function (worldX, worldY, camera) { - if (!Array.isArray(file)) - { - file = [ file ]; - } + return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, this.layer); + }, - for (var i = 0; i < file.length; i++) - { - var item = file[i]; + /** + * 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); + }, - // Does the file already exist in the cache or texture manager? - // Or will it conflict with a file already in the queue or inflight? - if (!this.keyExists(item)) - { - this.list.set(item); + /** + * 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); + }, - this.emit(Events.ADD, item.key, item.type, this, item); + /** + * 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); - if (this.isLoading()) - { - this.totalToLoad++; - this.updateProgress(); - } - } - } + return this; }, /** - * Checks the key and type of the given file to see if it will conflict with anything already - * in a Cache, the Texture Manager, or the list or inflight queues. + * 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.Loader.LoaderPlugin#keyExists - * @since 3.7.0 + * @method Phaser.Tilemaps.TilemapLayer#randomize + * @since 3.50.0 * - * @param {Phaser.Loader.File} file - The file to check the key of. + * @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 {boolean} `true` if adding this file will cause a cache or queue conflict, otherwise `false`. + * @return {this} This Tilemap Layer object. */ - keyExists: function (file) + randomize: function (tileX, tileY, width, height, indexes) { - var keyConflict = file.hasCacheConflict(); + TilemapComponents.Randomize(tileX, tileY, width, height, indexes, this.layer); - if (!keyConflict) - { - this.list.iterate(function (item) - { - if (item.type === file.type && item.key === file.key) - { - keyConflict = true; + return this; + }, - return false; - } + /** + * 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); + }, - if (!keyConflict && this.isLoading()) - { - this.inflight.iterate(function (item) - { - if (item.type === file.type && item.key === file.key) - { - keyConflict = true; + /** + * 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 false; - } + 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); - this.queue.iterate(function (item) - { - if (item.type === file.type && item.key === file.key) - { - keyConflict = true; + return this; + }, - return false; - } + /** + * 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 keyConflict; + return this; }, /** - * Takes a well formed, fully parsed pack file object and adds its entries into the load queue. Usually you do not call - * this method directly, but instead use `Loader.pack` and supply a path to a JSON file that holds the - * pack data. However, if you've got the data prepared you can pass it to this method. - * - * You can also provide an optional key. If you do then it will only add the entries from that part of the pack into - * to the load queue. If not specified it will add all entries it finds. For more details about the pack file format - * see the `LoaderPlugin.pack` method. + * 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.Loader.LoaderPlugin#addPack - * @since 3.7.0 + * @method Phaser.Tilemaps.TilemapLayer#setCullPadding + * @since 3.50.0 * - * @param {any} pack - The Pack File data to be parsed and each entry of it to added to the load queue. - * @param {string} [packKey] - An optional key to use from the pack file data. + * @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 {boolean} `true` if any files were added to the queue, otherwise `false`. + * @return {this} This Tilemap Layer object. */ - addPack: function (pack, packKey) + setCullPadding: function (paddingX, paddingY) { - // if no packKey provided we'll add everything to the queue - if (packKey && pack.hasOwnProperty(packKey)) - { - pack = { packKey: pack[packKey] }; - } + if (paddingX === undefined) { paddingX = 1; } + if (paddingY === undefined) { paddingY = 1; } - var total = 0; + this.cullPaddingX = paddingX; + this.cullPaddingY = paddingY; - // Store the loader settings in case this pack replaces them - var currentBaseURL = this.baseURL; - var currentPath = this.path; - var currentPrefix = this.prefix; + return this; + }, - // Here we go ... - for (var key in pack) - { - if (!Object.prototype.hasOwnProperty.call(pack, key)) - { - continue; - } + /** + * 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); - var config = pack[key]; + return this; + }, - // Any meta data to process? - var baseURL = GetFastValue(config, 'baseURL', currentBaseURL); - var path = GetFastValue(config, 'path', currentPath); - var prefix = GetFastValue(config, 'prefix', currentPrefix); - var files = GetFastValue(config, 'files', null); - var defaultType = GetFastValue(config, 'defaultType', 'void'); + /** + * 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); - if (Array.isArray(files)) - { - this.setBaseURL(baseURL); - this.setPath(path); - this.setPrefix(prefix); + return this; + }, - for (var i = 0; i < files.length; i++) - { - var file = files[i]; - var type = (file.hasOwnProperty('type')) ? file.type : defaultType; + /** + * 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); - if (this[type]) - { - this[type](file); - total++; - } - } - } - } + return this; + }, - // Reset the loader settings - this.setBaseURL(currentBaseURL); - this.setPath(currentPath); - this.setPrefix(currentPrefix); + /** + * 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 (total > 0); + return this; }, /** - * Is the Loader actively loading, or processing loaded files? + * 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.Loader.LoaderPlugin#isLoading - * @since 3.0.0 + * @method Phaser.Tilemaps.TilemapLayer#setCollisionFromCollisionGroup + * @since 3.50.0 * - * @return {boolean} `true` if the Loader is busy loading or processing, otherwise `false`. + * @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. */ - isLoading: function () + setCollisionFromCollisionGroup: function (collides, recalculateFaces) { - return (this.state === CONST.LOADER_LOADING || this.state === CONST.LOADER_PROCESSING); + TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, this.layer); + + return this; }, /** - * Is the Loader ready to start a new load? + * 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.Loader.LoaderPlugin#isReady - * @since 3.0.0 + * @method Phaser.Tilemaps.TilemapLayer#setTileIndexCallback + * @since 3.50.0 * - * @return {boolean} `true` if the Loader is ready to start a new load, otherwise `false`. + * @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. */ - isReady: function () + setTileIndexCallback: function (indexes, callback, callbackContext) { - return (this.state === CONST.LOADER_IDLE || this.state === CONST.LOADER_COMPLETE); + TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, this.layer); + + return this; }, /** - * Starts the Loader running. This will reset the progress and totals and then emit a `start` event. - * If there is nothing in the queue the Loader will immediately complete, otherwise it will start - * loading the first batch of files. - * - * The Loader is started automatically if the queue is populated within your Scenes `preload` method. + * 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. * - * However, outside of this, you need to call this method to start it. + * @method Phaser.Tilemaps.TilemapLayer#setTileLocationCallback + * @since 3.50.0 * - * If the Loader is already running this method will simply return. + * @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. * - * @method Phaser.Loader.LoaderPlugin#start - * @fires Phaser.Loader.Events#START - * @since 3.0.0 + * @return {this} This Tilemap Layer object. */ - start: function () + setTileLocationCallback: function (tileX, tileY, width, height, callback, callbackContext) { - if (!this.isReady()) - { - return; - } + TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, this.layer); - this.progress = 0; + return this; + }, - this.totalFailed = 0; - this.totalComplete = 0; - this.totalToLoad = this.list.size; + /** + * 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); - this.emit(Events.START, this); + return this; + }, - if (this.list.size === 0) - { - this.loadComplete(); - } - else - { - this.state = CONST.LOADER_LOADING; + /** + * 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); - this.inflight.clear(); - this.queue.clear(); + return this; + }, - this.updateProgress(); + /** + * 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); + }, - this.checkLoadQueue(); + /** + * 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); + }, - this.systems.events.on(SceneEvents.UPDATE, this.update, 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); }, /** - * Called automatically during the load process. - * It updates the `progress` value and then emits a progress event, which you can use to - * display a loading bar in your game. + * Returns an array of Vector2s where each entry corresponds to the corner of the requested tile. * - * @method Phaser.Loader.LoaderPlugin#updateProgress - * @fires Phaser.Loader.Events#PROGRESS - * @since 3.0.0 + * The `tileX` and `tileY` parameters are in tile coordinates, not world coordinates. + * + * The corner coordinates are in world space, having factored in TilemapLayer scale, position + * and the camera, if given. + * + * The size of the array will vary based on the orientation of the map. For example an + * orthographic map will return an array of 4 vectors, where-as a hexagonal map will, + * of course, return an array of 6 corner vectors. + * + * @method Phaser.Tilemaps.TilemapLayer#getTileCorners + * @since 3.60.0 + * + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @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 {?Phaser.Math.Vector2[]} Returns an array of Vector2s, or null if the layer given was invalid. */ - updateProgress: function () + getTileCorners: function (tileX, tileY, camera) { - this.progress = 1 - ((this.list.size + this.inflight.size) / this.totalToLoad); + return this.tilemap.getTileCorners(tileX, tileY, camera, this); + }, - this.emit(Events.PROGRESS, this.progress); + /** + * 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 (weightedIndexes, tileX, tileY, width, height) + { + TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, this.layer); + + return this; }, /** - * Called automatically during the load process. + * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the + * layers position, scale and scroll. * - * @method Phaser.Loader.LoaderPlugin#update - * @since 3.10.0 + * You cannot call this method for Isometric or Hexagonal tilemaps as they require + * both `worldX` and `worldY` values to determine the correct tile, instead you + * should use the `worldToTileXY` method. + * + * @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. */ - update: function () + 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. + * + * You cannot call this method for Isometric or Hexagonal tilemaps as they require + * both `worldX` and `worldY` values to determine the correct tile, instead you + * should use the `worldToTileXY` method. + * + * @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) { - if (this.state === CONST.LOADER_LOADING && this.list.size > 0 && this.inflight.size < this.maxParallelDownloads) - { - this.checkLoadQueue(); - } + return this.tilemap.worldToTileY(worldY, snapToFloor, camera, this); }, /** - * An internal method called by the Loader. + * 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. * - * It will check to see if there are any more files in the pending list that need loading, and if so it will move - * them from the list Set into the inflight Set, set their CORs flag and start them loading. + * @method Phaser.Tilemaps.TilemapLayer#worldToTileXY + * @since 3.50.0 * - * It will carrying on doing this for each file in the pending list until it runs out, or hits the max allowed parallel downloads. + * @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. * - * @method Phaser.Loader.LoaderPlugin#checkLoadQueue - * @private - * @since 3.7.0 + * @return {Phaser.Math.Vector2} A Vector2 containing the tile coordinates of the world values. */ - checkLoadQueue: function () + worldToTileXY: function (worldX, worldY, snapToFloor, point, camera) { - this.list.each(function (file) - { - if (file.state === CONST.FILE_POPULATED || (file.state === CONST.FILE_PENDING && this.inflight.size < this.maxParallelDownloads)) - { - this.inflight.set(file); - - this.list.delete(file); - - // If the file doesn't have its own crossOrigin set, we'll use the Loaders (which is undefined by default) - if (!file.crossOrigin) - { - file.crossOrigin = this.crossOrigin; - } - - file.load(); - } - - if (this.inflight.size === this.maxParallelDownloads) - { - // Tells the Set iterator to abort - return false; - } - - }, this); + return this.tilemap.worldToTileXY(worldX, worldY, snapToFloor, point, camera, this); }, /** - * An internal method called automatically by the XHRLoader belong to a File. - * - * This method will remove the given file from the inflight Set and update the load progress. - * If the file was successful its `onProcess` method is called, otherwise it is added to the delete queue. + * Destroys this TilemapLayer and removes its link to the associated LayerData. * - * @method Phaser.Loader.LoaderPlugin#nextFile - * @fires Phaser.Loader.Events#FILE_LOAD - * @fires Phaser.Loader.Events#FILE_LOAD_ERROR - * @since 3.0.0 + * @method Phaser.Tilemaps.TilemapLayer#destroy + * @since 3.50.0 * - * @param {Phaser.Loader.File} file - The File that just finished loading, or errored during load. - * @param {boolean} success - `true` if the file loaded successfully, otherwise `false`. + * @param {boolean} [removeFromTilemap=true] - Remove this layer from the parent Tilemap? */ - nextFile: function (file, success) + destroy: function (removeFromTilemap) { - // Has the game been destroyed during load? If so, bail out now. - if (!this.inflight) + if (removeFromTilemap === undefined) { removeFromTilemap = true; } + + if (!this.tilemap) { + // Abort, we've already been destroyed return; } - this.inflight.delete(file); - - this.updateProgress(); + // Uninstall this layer only if it is still installed on the LayerData object + if (this.layer.tilemapLayer === this) + { + this.layer.tilemapLayer = undefined; + } - if (success) + if (removeFromTilemap) { - this.totalComplete++; + this.tilemap.removeLayer(this); + } - this.queue.set(file); + this.tilemap = undefined; + this.layer = undefined; + this.culledTiles.length = 0; + this.cullCallback = null; - this.emit(Events.FILE_LOAD, file); + this.gidMap = []; + this.tileset = []; - file.onProcess(); - } - else - { - this.totalFailed++; + GameObject.prototype.destroy.call(this); + } - this._deleteQueue.set(file); +}); - this.emit(Events.FILE_LOAD_ERROR, file); +module.exports = TilemapLayer; - this.fileProcessComplete(file); - } - }, - /** - * An internal method that is called automatically by the File when it has finished processing. - * - * If the process was successful, and the File isn't part of a MultiFile, its `addToCache` method is called. - * - * It this then removed from the queue. If there are no more files to load `loadComplete` is called. - * - * @method Phaser.Loader.LoaderPlugin#fileProcessComplete - * @since 3.7.0 - * - * @param {Phaser.Loader.File} file - The file that has finished processing. - */ - fileProcessComplete: function (file) - { - // Has the game been destroyed during load? If so, bail out now. - if (!this.scene || !this.systems || !this.systems.game || this.systems.game.pendingDestroy) - { - return; - } +/***/ }), - // This file has failed, so move it to the failed Set - if (file.state === CONST.FILE_ERRORED) - { - if (file.multiFile) - { - file.multiFile.onFileFailed(file); - } - } - else if (file.state === CONST.FILE_COMPLETE) - { - if (file.multiFile) - { - if (file.multiFile.isReadyToProcess()) - { - // If we got here then all files the link file needs are ready to add to the cache - file.multiFile.addToCache(); - } - } - else - { - // If we got here, then the file processed, so let it add itself to its cache - file.addToCache(); - } - } +/***/ 17394: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Remove it from the queue - this.queue.delete(file); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Nothing left to do? +var TransformMatrix = __webpack_require__(69360); - if (this.list.size === 0 && this.inflight.size === 0 && this.queue.size === 0) - { - this.loadComplete(); - } - }, +var tempMatrix1 = new TransformMatrix(); +var tempMatrix2 = new TransformMatrix(); +var tempMatrix3 = new TransformMatrix(); - /** - * Called at the end when the load queue is exhausted and all files have either loaded or errored. - * By this point every loaded file will now be in its associated cache and ready for use. - * - * Also clears down the Sets, puts progress to 1 and clears the deletion queue. - * - * @method Phaser.Loader.LoaderPlugin#loadComplete - * @fires Phaser.Loader.Events#COMPLETE - * @fires Phaser.Loader.Events#POST_PROCESS - * @since 3.7.0 - */ - loadComplete: function () +/** + * 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.Tilemaps.TilemapLayer#renderCanvas + * @since 3.50.0 + * @private + * + * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. + * @param {Phaser.Tilemaps.TilemapLayer} 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 TilemapLayerCanvasRenderer = function (renderer, src, camera, parentMatrix) +{ + var renderTiles = src.cull(camera); + + var tileCount = renderTiles.length; + var alpha = camera.alpha * src.alpha; + + if (tileCount === 0 || alpha <= 0) { - this.emit(Events.POST_PROCESS, this); + return; + } - this.list.clear(); - this.inflight.clear(); - this.queue.clear(); + var camMatrix = tempMatrix1; + var layerMatrix = tempMatrix2; + var calcMatrix = tempMatrix3; - this.progress = 1; + layerMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY); - this.state = CONST.LOADER_COMPLETE; + camMatrix.copyFrom(camera.matrix); - this.systems.events.off(SceneEvents.UPDATE, this.update, this); + var ctx = renderer.currentContext; + var gidMap = src.gidMap; - // Call 'destroy' on each file ready for deletion - this._deleteQueue.iterateLocal('destroy'); + ctx.save(); - this._deleteQueue.clear(); + if (parentMatrix) + { + // Multiply the camera by the parent matrix + camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY); - this.emit(Events.COMPLETE, this, this.totalComplete, this.totalFailed); - }, + // Undo the camera scroll + layerMatrix.e = src.x; + layerMatrix.f = src.y; - /** - * Adds a File into the pending-deletion queue. - * - * @method Phaser.Loader.LoaderPlugin#flagForRemoval - * @since 3.7.0 - * - * @param {Phaser.Loader.File} file - The File to be queued for deletion when the Loader completes. - */ - flagForRemoval: function (file) + // Multiply by the Sprite matrix, store result in calcMatrix + camMatrix.multiply(layerMatrix, calcMatrix); + + calcMatrix.copyToContext(ctx); + } + else { - this._deleteQueue.set(file); - }, + layerMatrix.e -= camera.scrollX * src.scrollFactorX; + layerMatrix.f -= camera.scrollY * src.scrollFactorY; - /** - * Converts the given JSON data into a file that the browser then prompts you to download so you can save it locally. - * - * The data must be well formed JSON and ready-parsed, not a JavaScript object. - * - * @method Phaser.Loader.LoaderPlugin#saveJSON - * @since 3.0.0 - * - * @param {*} data - The JSON data, ready parsed. - * @param {string} [filename=file.json] - The name to save the JSON file as. - * - * @return {this} This Loader plugin. - */ - saveJSON: function (data, filename) + layerMatrix.copyToContext(ctx); + } + + if (!renderer.antialias || src.scaleX > 1 || src.scaleY > 1) { - return this.save(JSON.stringify(data), filename); - }, + ctx.imageSmoothingEnabled = false; + } - /** - * Causes the browser to save the given data as a file to its default Downloads folder. - * - * Creates a DOM level anchor link, assigns it as being a `download` anchor, sets the href - * to be an ObjectURL based on the given data, and then invokes a click event. - * - * @method Phaser.Loader.LoaderPlugin#save - * @since 3.0.0 - * - * @param {*} data - The data to be saved. Will be passed through URL.createObjectURL. - * @param {string} [filename=file.json] - The filename to save the file as. - * @param {string} [filetype=application/json] - The file type to use when saving the file. Defaults to JSON. - * - * @return {this} This Loader plugin. - */ - save: function (data, filename, filetype) + for (var i = 0; i < tileCount; i++) { - if (filename === undefined) { filename = 'file.json'; } - if (filetype === undefined) { filetype = 'application/json'; } + var tile = renderTiles[i]; - var blob = new Blob([ data ], { type: filetype }); + var tileset = gidMap[tile.index]; - var url = URL.createObjectURL(blob); + if (!tileset) + { + continue; + } - var a = document.createElement('a'); + var image = tileset.image.getSourceImage(); - a.download = filename; - a.textContent = 'Download ' + filename; - a.href = url; - a.click(); + var tileTexCoords = tileset.getTileTextureCoordinates(tile.index); + var tileWidth = tileset.tileWidth; + var tileHeight = tileset.tileHeight; - return this; - }, + if (tileTexCoords === null || tileWidth === 0 || tileHeight === 0) + { + continue; + } - /** - * Resets the Loader. - * - * This will clear all lists and reset the base URL, path and prefix. - * - * Warning: If the Loader is currently downloading files, or has files in its queue, they will be aborted. - * - * @method Phaser.Loader.LoaderPlugin#reset - * @since 3.0.0 - */ - reset: function () - { - this.list.clear(); - this.inflight.clear(); - this.queue.clear(); + var halfWidth = tileWidth * 0.5; + var halfHeight = tileHeight * 0.5; - var gameConfig = this.systems.game.config; - var sceneConfig = this.systems.settings.loader; + tileTexCoords.x += tileset.tileOffset.x; + tileTexCoords.y += tileset.tileOffset.y; - this.setBaseURL(GetFastValue(sceneConfig, 'baseURL', gameConfig.loaderBaseURL)); - this.setPath(GetFastValue(sceneConfig, 'path', gameConfig.loaderPath)); - this.setPrefix(GetFastValue(sceneConfig, 'prefix', gameConfig.loaderPrefix)); + ctx.save(); - this.state = CONST.LOADER_IDLE; - }, + ctx.translate(tile.pixelX + halfWidth, tile.pixelY + halfHeight); - /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. - * - * @method Phaser.Loader.LoaderPlugin#shutdown - * @private - * @since 3.0.0 - */ - shutdown: function () - { - this.reset(); + if (tile.rotation !== 0) + { + ctx.rotate(tile.rotation); + } - this.state = CONST.LOADER_SHUTDOWN; + if (tile.flipX || tile.flipY) + { + ctx.scale((tile.flipX) ? -1 : 1, (tile.flipY) ? -1 : 1); + } - this.systems.events.off(SceneEvents.UPDATE, this.update, this); - this.systems.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); - }, + ctx.globalAlpha = alpha * tile.alpha; - /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. - * - * @method Phaser.Loader.LoaderPlugin#destroy - * @private - * @since 3.0.0 - */ - destroy: function () - { - this.shutdown(); + ctx.drawImage( + image, + tileTexCoords.x, tileTexCoords.y, + tileWidth , tileHeight, + -halfWidth, -halfHeight, + tileWidth, tileHeight + ); - this.state = CONST.LOADER_DESTROYED; + ctx.restore(); + } - this.systems.events.off(SceneEvents.UPDATE, this.update, this); - this.systems.events.off(SceneEvents.START, this.pluginStart, this); + ctx.restore(); +}; - this.list = null; - this.inflight = null; - this.queue = null; +module.exports = TilemapLayerCanvasRenderer; - this.scene = null; - this.systems = null; - this.textureManager = null; - this.cacheManager = null; - this.sceneManager = null; - } -}); +/***/ }), -PluginCache.register('Loader', LoaderPlugin, 'load'); +/***/ 96193: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -module.exports = LoaderPlugin; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var NOOP = __webpack_require__(72283); +var renderWebGL = NOOP; +var renderCanvas = NOOP; + +if (true) +{ + renderWebGL = __webpack_require__(51395); +} + +if (true) +{ + renderCanvas = __webpack_require__(17394); +} + +module.exports = { + + renderWebGL: renderWebGL, + renderCanvas: renderCanvas + +}; /***/ }), -/* 1366 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 51395: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(62); -var Extend = __webpack_require__(17); +var Utils = __webpack_require__(75512); /** - * @namespace Phaser.Physics.Arcade + * 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.Tilemaps.TilemapLayer#renderWebGL + * @since 3.0.0 + * @private + * + * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. + * @param {Phaser.Tilemaps.TilemapLayer} src - The Game Object being rendered in this call. + * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. */ +var TilemapLayerWebGLRenderer = function (renderer, src, camera) +{ + var renderTiles = src.cull(camera); -var Arcade = { + var tileCount = renderTiles.length; + var alpha = camera.alpha * src.alpha; - ArcadePhysics: __webpack_require__(1367), - Body: __webpack_require__(527), - Collider: __webpack_require__(528), - Components: __webpack_require__(243), - Events: __webpack_require__(245), - Factory: __webpack_require__(521), - GetOverlapX: __webpack_require__(246), - GetOverlapY: __webpack_require__(247), - SeparateX: __webpack_require__(537), - SeparateY: __webpack_require__(538), - Group: __webpack_require__(524), - Image: __webpack_require__(522), - Sprite: __webpack_require__(157), - StaticBody: __webpack_require__(539), - StaticGroup: __webpack_require__(525), - Tilemap: __webpack_require__(1391), - World: __webpack_require__(526) + if (tileCount === 0 || alpha <= 0) + { + return; + } -}; + var gidMap = src.gidMap; + var pipeline = renderer.pipelines.set(src.pipeline, src); -// Merge in the consts -Arcade = Extend(false, Arcade, CONST); + var getTint = Utils.getTintAppendFloatAlpha; -module.exports = Arcade; + var scrollFactorX = src.scrollFactorX; + var scrollFactorY = src.scrollFactorY; + + var x = src.x; + var y = src.y; + + var sx = src.scaleX; + var sy = src.scaleY; + + renderer.pipelines.preBatch(src); + + for (var i = 0; i < tileCount; i++) + { + var tile = renderTiles[i]; + + var tileset = gidMap[tile.index]; + + if (!tileset) + { + continue; + } + + var tileTexCoords = tileset.getTileTextureCoordinates(tile.index); + + if (tileTexCoords === null) + { + continue; + } + + var texture = tileset.glTexture; + + var textureUnit = pipeline.setTexture2D(texture, src); + + var frameWidth = tileset.tileWidth; + var frameHeight = tileset.tileHeight; + + var frameX = tileTexCoords.x; + var frameY = tileTexCoords.y; + + var tw = tileset.tileWidth * 0.5; + var th = tileset.tileHeight * 0.5; + + var tOffsetX = tileset.tileOffset.x; + var tOffsetY = tileset.tileOffset.y; + + var tint = getTint(tile.tint, alpha * tile.alpha); + + pipeline.batchTexture( + src, + texture, + texture.width, texture.height, + x + tile.pixelX * sx + (tw * sx - tOffsetX), y + tile.pixelY * sy + (th * sy - tOffsetY), + tile.width, tile.height, + sx, sy, + tile.rotation, + tile.flipX, tile.flipY, + scrollFactorX, scrollFactorY, + tw, th, + frameX, frameY, frameWidth, frameHeight, + tint, tint, tint, tint, false, + 0, 0, + camera, + null, + true, + textureUnit + ); + } + + renderer.pipelines.postBatch(src); +}; + +module.exports = TilemapLayerWebGLRenderer; /***/ }), -/* 1367 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 47975: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var DegToRad = __webpack_require__(36); -var DistanceBetween = __webpack_require__(50); -var DistanceSquared = __webpack_require__(353); -var Factory = __webpack_require__(521); -var GetFastValue = __webpack_require__(2); -var Merge = __webpack_require__(127); -var OverlapCirc = __webpack_require__(523); -var OverlapRect = __webpack_require__(244); -var PluginCache = __webpack_require__(24); -var SceneEvents = __webpack_require__(20); -var Vector2 = __webpack_require__(3); -var World = __webpack_require__(526); +var Class = __webpack_require__(56694); +var Vector2 = __webpack_require__(93736); /** * @classdesc - * The Arcade Physics Plugin belongs to a Scene and sets up and manages the Scene's physics simulation. - * It also holds some useful methods for moving and rotating Arcade Physics Bodies. - * - * You can access it from within a Scene using `this.physics`. - * - * 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. + * A Tileset is a combination of a single image containing the tiles and a container for data about + * each tile. * - * @class ArcadePhysics - * @memberof Phaser.Physics.Arcade + * @class Tileset + * @memberof Phaser.Tilemaps * @constructor * @since 3.0.0 * - * @param {Phaser.Scene} scene - The Scene that this Plugin belongs to. + * @param {string} name - The name of the tileset in the map data. + * @param {number} firstgid - The first tile index this tileset contains. + * @param {number} [tileWidth=32] - Width of each tile (in pixels). + * @param {number} [tileHeight=32] - Height of each tile (in pixels). + * @param {number} [tileMargin=0] - The margin around all tiles in the sheet (in pixels). + * @param {number} [tileSpacing=0] - The spacing between each tile in the sheet (in pixels). + * @param {object} [tileProperties={}] - Custom properties defined per tile in the Tileset. + * These typically are custom properties created in Tiled when editing a tileset. + * @param {object} [tileData={}] - Data stored per tile. These typically are created in Tiled when editing a tileset, e.g. from Tiled's tile collision editor or terrain editor. + * @param {object} [tileOffset={x: 0, y: 0}] - Tile texture drawing offset. */ -var ArcadePhysics = new Class({ +var Tileset = new Class({ initialize: - function ArcadePhysics (scene) + function Tileset (name, firstgid, tileWidth, tileHeight, tileMargin, tileSpacing, tileProperties, tileData, tileOffset) { + if (tileWidth === undefined || tileWidth <= 0) { tileWidth = 32; } + if (tileHeight === undefined || tileHeight <= 0) { tileHeight = 32; } + if (tileMargin === undefined) { tileMargin = 0; } + if (tileSpacing === undefined) { tileSpacing = 0; } + if (tileProperties === undefined) { tileProperties = {}; } + if (tileData === undefined) { tileData = {}; } + /** - * The Scene that this Plugin belongs to. + * The name of the Tileset. * - * @name Phaser.Physics.Arcade.ArcadePhysics#scene - * @type {Phaser.Scene} + * @name Phaser.Tilemaps.Tileset#name + * @type {string} * @since 3.0.0 */ - this.scene = scene; + this.name = name; /** - * The Scene's Systems. + * The starting index of the first tile index this Tileset contains. * - * @name Phaser.Physics.Arcade.ArcadePhysics#systems - * @type {Phaser.Scenes.Systems} + * @name Phaser.Tilemaps.Tileset#firstgid + * @type {number} * @since 3.0.0 */ - this.systems = scene.sys; + this.firstgid = firstgid; /** - * A configuration object. Union of the `physics.arcade.*` properties of the GameConfig and SceneConfig objects. + * The width of each tile (in pixels). Use setTileSize to change. * - * @name Phaser.Physics.Arcade.ArcadePhysics#config - * @type {Phaser.Types.Physics.Arcade.ArcadeWorldConfig} + * @name Phaser.Tilemaps.Tileset#tileWidth + * @type {number} + * @readonly * @since 3.0.0 */ - this.config = this.getConfig(); + this.tileWidth = tileWidth; /** - * The physics simulation. + * The height of each tile (in pixels). Use setTileSize to change. * - * @name Phaser.Physics.Arcade.ArcadePhysics#world - * @type {Phaser.Physics.Arcade.World} + * @name Phaser.Tilemaps.Tileset#tileHeight + * @type {number} + * @readonly * @since 3.0.0 */ - this.world; + this.tileHeight = tileHeight; /** - * An object holding the Arcade Physics factory methods. + * The margin around the tiles in the sheet (in pixels). Use `setSpacing` to change. * - * @name Phaser.Physics.Arcade.ArcadePhysics#add - * @type {Phaser.Physics.Arcade.Factory} + * @name Phaser.Tilemaps.Tileset#tileMargin + * @type {number} + * @readonly * @since 3.0.0 */ - this.add; - - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); - scene.sys.events.on(SceneEvents.START, this.start, this); - }, + this.tileMargin = tileMargin; - /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. - * - * @method Phaser.Physics.Arcade.ArcadePhysics#boot - * @private - * @since 3.5.1 - */ - boot: function () - { - this.world = new World(this.scene, this.config); - this.add = new Factory(this.world); + /** + * The spacing between each the tile in the sheet (in pixels). Use `setSpacing` to change. + * + * @name Phaser.Tilemaps.Tileset#tileSpacing + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.tileSpacing = tileSpacing; - this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); - }, + /** + * Tileset-specific properties per tile that are typically defined in the Tiled editor in the + * Tileset editor. + * + * @name Phaser.Tilemaps.Tileset#tileProperties + * @type {object} + * @since 3.0.0 + */ + this.tileProperties = tileProperties; - /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. - * - * @method Phaser.Physics.Arcade.ArcadePhysics#start - * @private - * @since 3.5.0 - */ - start: function () - { - if (!this.world) - { - this.world = new World(this.scene, this.config); - this.add = new Factory(this.world); - } + /** + * Tileset-specific data per tile that are typically defined in the Tiled editor, e.g. within + * the Tileset collision editor. This is where collision objects and terrain are stored. + * + * @name Phaser.Tilemaps.Tileset#tileData + * @type {object} + * @since 3.0.0 + */ + this.tileData = tileData; - var eventEmitter = this.systems.events; + /** + * Controls the drawing offset from the tile origin. + * Defaults to 0x0, no offset. + * + * @name Phaser.Tilemaps.Tileset#tileOffset + * @type {Phaser.Math.Vector2} + * @since 3.60.0 + */ + this.tileOffset = new Vector2(); - if (!GetFastValue(this.config, 'customUpdate', false)) + if (tileOffset !== undefined) { - eventEmitter.on(SceneEvents.UPDATE, this.world.update, this.world); + this.tileOffset.set(tileOffset.x, tileOffset.y); } - eventEmitter.on(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world); - eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); - }, - - /** - * Causes `World.update` to be automatically called each time the Scene - * emits and `UPDATE` event. This is the default setting, so only needs - * calling if you have specifically disabled it. - * - * @method Phaser.Physics.Arcade.ArcadePhysics#enableUpdate - * @since 3.50.0 - */ - enableUpdate: function () - { - this.systems.events.on(SceneEvents.UPDATE, this.world.update, this.world); - }, - - /** - * Causes `World.update` to **not** be automatically called each time the Scene - * emits and `UPDATE` event. - * - * If you wish to run the World update at your own rate, or from your own - * component, then you should call this method to disable the built-in link, - * and then call `World.update(delta, time)` accordingly. - * - * Note that `World.postUpdate` is always automatically called when the Scene - * emits a `POST_UPDATE` event, regardless of this setting. - * - * @method Phaser.Physics.Arcade.ArcadePhysics#disableUpdate - * @since 3.50.0 - */ - disableUpdate: function () - { - this.systems.events.off(SceneEvents.UPDATE, this.world.update, this.world); - }, - - /** - * Creates the physics configuration for the current Scene. - * - * @method Phaser.Physics.Arcade.ArcadePhysics#getConfig - * @since 3.0.0 - * - * @return {Phaser.Types.Physics.Arcade.ArcadeWorldConfig} The physics configuration. - */ - getConfig: function () - { - var gameConfig = this.systems.game.config.physics; - var sceneConfig = this.systems.settings.physics; - - var config = Merge( - GetFastValue(sceneConfig, 'arcade', {}), - GetFastValue(gameConfig, 'arcade', {}) - ); - - return config; - }, - - /** - * Tests if Game Objects overlap. See {@link Phaser.Physics.Arcade.World#overlap} - * - * @method Phaser.Physics.Arcade.ArcadePhysics#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} [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 overlap. If this is set then `collideCallback` 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#overlap - */ - overlap: function (object1, object2, overlapCallback, processCallback, callbackContext) - { - if (overlapCallback === undefined) { overlapCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = overlapCallback; } - - return this.world.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 #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. The `collideCallback` is invoked if a collision occurs and the two colliding - * objects are passed to it. - * - * 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.ArcadePhysics#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 {*} [callbackContext] - The context in which to run the callbacks. - * - * @return {boolean} True if any overlapping Game Objects were separated, otherwise false. - * - * @see Phaser.Physics.Arcade.World#collide - */ - collide: function (object1, object2, collideCallback, processCallback, callbackContext) - { - if (collideCallback === undefined) { collideCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = collideCallback; } - - return this.world.collideObjects(object1, object2, collideCallback, processCallback, callbackContext, false); - }, - - /** - * 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.ArcadePhysics#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) - { - return this.world.collideTiles(sprite, tiles, collideCallback, processCallback, callbackContext); - }, - - /** - * 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.ArcadePhysics#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) - { - return this.world.overlapTiles(sprite, tiles, collideCallback, processCallback, callbackContext); - }, - - /** - * Pauses the simulation. - * - * @method Phaser.Physics.Arcade.ArcadePhysics#pause - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.World} The simulation. - */ - pause: function () - { - return this.world.pause(); - }, - - /** - * Resumes the simulation (if paused). - * - * @method Phaser.Physics.Arcade.ArcadePhysics#resume - * @since 3.0.0 - * - * @return {Phaser.Physics.Arcade.World} The simulation. - */ - resume: function () - { - return this.world.resume(); - }, - - /** - * Sets the acceleration.x/y property on the game object so it will move towards the x/y coordinates at the given rate (in pixels per second squared) - * - * You must give a maximum speed value, beyond which the game object won't go any faster. - * - * Note: The game object does not continuously track the target. If the target changes location during transit the game object will not modify its course. - * Note: The game object doesn't stop moving once it reaches the destination coordinates. - * - * @method Phaser.Physics.Arcade.ArcadePhysics#accelerateTo - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body. - * @param {number} x - The x coordinate to accelerate towards. - * @param {number} y - The y coordinate to accelerate towards. - * @param {number} [speed=60] - The acceleration (change in speed) in pixels per second squared. - * @param {number} [xSpeedMax=500] - The maximum x velocity the game object can reach. - * @param {number} [ySpeedMax=500] - The maximum y velocity the game object can reach. - * - * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. - */ - accelerateTo: function (gameObject, x, y, speed, xSpeedMax, ySpeedMax) - { - if (speed === undefined) { speed = 60; } + /** + * The cached image that contains the individual tiles. Use setImage to set. + * + * @name Phaser.Tilemaps.Tileset#image + * @type {?Phaser.Textures.Texture} + * @readonly + * @since 3.0.0 + */ + this.image = null; - var angle = Math.atan2(y - gameObject.y, x - gameObject.x); + /** + * The gl texture used by the WebGL renderer. + * + * @name Phaser.Tilemaps.Tileset#glTexture + * @type {?WebGLTexture} + * @readonly + * @since 3.11.0 + */ + this.glTexture = null; - gameObject.body.acceleration.setToPolar(angle, speed); + /** + * The number of tile rows in the the tileset. + * + * @name Phaser.Tilemaps.Tileset#rows + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.rows = 0; - if (xSpeedMax !== undefined && ySpeedMax !== undefined) - { - gameObject.body.maxVelocity.set(xSpeedMax, ySpeedMax); - } + /** + * The number of tile columns in the tileset. + * + * @name Phaser.Tilemaps.Tileset#columns + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.columns = 0; - return angle; - }, + /** + * The total number of tiles in the tileset. + * + * @name Phaser.Tilemaps.Tileset#total + * @type {number} + * @readonly + * @since 3.0.0 + */ + this.total = 0; - /** - * Sets the acceleration.x/y property on the game object so it will move towards the x/y coordinates at the given rate (in pixels per second squared) - * - * You must give a maximum speed value, beyond which the game object won't go any faster. - * - * Note: The game object does not continuously track the target. If the target changes location during transit the game object will not modify its course. - * Note: The game object doesn't stop moving once it reaches the destination coordinates. - * - * @method Phaser.Physics.Arcade.ArcadePhysics#accelerateToObject - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body. - * @param {Phaser.GameObjects.GameObject} destination - The Game Object to move towards. Can be any object but must have visible x/y properties. - * @param {number} [speed=60] - The acceleration (change in speed) in pixels per second squared. - * @param {number} [xSpeedMax=500] - The maximum x velocity the game object can reach. - * @param {number} [ySpeedMax=500] - The maximum y velocity the game object can reach. - * - * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. - */ - accelerateToObject: function (gameObject, destination, speed, xSpeedMax, ySpeedMax) - { - return this.accelerateTo(gameObject, destination.x, destination.y, speed, xSpeedMax, ySpeedMax); + /** + * The look-up table to specific tile image texture coordinates (UV in pixels). Each element + * contains the coordinates for a tile in an object of the form {x, y}. + * + * @name Phaser.Tilemaps.Tileset#texCoordinates + * @type {object[]} + * @readonly + * @since 3.0.0 + */ + this.texCoordinates = []; }, /** - * Finds the Body or Game Object closest to a source point or object. - * - * If a `targets` argument is passed, this method finds the closest of those. - * The targets can be Arcade Physics Game Objects, Dynamic Bodies, or Static Bodies. - * - * If no `targets` argument is passed, this method finds the closest Dynamic Body. - * - * If two or more targets are the exact same distance from the source point, only the first target - * is returned. + * Get a tiles properties that are stored in the Tileset. Returns null if tile index is not + * contained in this Tileset. This is typically defined in Tiled under the Tileset editor. * - * @method Phaser.Physics.Arcade.ArcadePhysics#closest + * @method Phaser.Tilemaps.Tileset#getTileProperties * @since 3.0.0 - * - * @param {any} source - Any object with public `x` and `y` properties, such as a Game Object or Geometry object. - * @param {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[]|Phaser.GameObjects.GameObject[])} [targets] - The targets. - * - * @return {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|Phaser.GameObjects.GameObject)} The target closest to the given source point. - */ - closest: function (source, targets) - { - if (!targets) - { - targets = this.world.bodies.entries; - } - - var min = Number.MAX_VALUE; - var closest = null; - var x = source.x; - var y = source.y; - var len = targets.length; - - for (var i = 0; i < len; i++) - { - var target = targets[i]; - var body = target.body || target; - - if (source === target || source === body || source === body.gameObject || source === body.center) - { - continue; - } - - var distance = DistanceSquared(x, y, body.center.x, body.center.y); - - if (distance < min) - { - closest = target; - min = distance; - } - } + * + * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. + * + * @return {?(object|undefined)} + */ + getTileProperties: function (tileIndex) + { + if (!this.containsTileIndex(tileIndex)) { return null; } - return closest; + return this.tileProperties[tileIndex - this.firstgid]; }, /** - * Finds the Body or Game Object farthest from a source point or object. - * - * If a `targets` argument is passed, this method finds the farthest of those. - * The targets can be Arcade Physics Game Objects, Dynamic Bodies, or Static Bodies. - * - * If no `targets` argument is passed, this method finds the farthest Dynamic Body. - * - * If two or more targets are the exact same distance from the source point, only the first target - * is returned. + * Get a tile's data that is stored in the Tileset. Returns null if tile index is not contained + * in this Tileset. This is typically defined in Tiled and will contain both Tileset collision + * info and terrain mapping. * - * @method Phaser.Physics.Arcade.ArcadePhysics#furthest + * @method Phaser.Tilemaps.Tileset#getTileData * @since 3.0.0 * - * @param {any} source - Any object with public `x` and `y` properties, such as a Game Object or Geometry object. - * @param {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[]|Phaser.GameObjects.GameObject[])} [targets] - The targets. + * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. * - * @return {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|Phaser.GameObjects.GameObject)} The target farthest from the given source point. + * @return {?object|undefined} */ - furthest: function (source, targets) + getTileData: function (tileIndex) { - if (!targets) - { - targets = this.world.bodies.entries; - } - - var max = -1; - var farthest = null; - var x = source.x; - var y = source.y; - var len = targets.length; - - for (var i = 0; i < len; i++) - { - var target = targets[i]; - var body = target.body || target; - - if (source === target || source === body || source === body.gameObject || source === body.center) - { - continue; - } - - var distance = DistanceSquared(x, y, body.center.x, body.center.y); - - if (distance > max) - { - farthest = target; - max = distance; - } - - } + if (!this.containsTileIndex(tileIndex)) { return null; } - return farthest; + return this.tileData[tileIndex - this.firstgid]; }, /** - * Move the given display object towards the x/y coordinates at a steady velocity. - * If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds. - * Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms. - * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course. - * Note: The display object doesn't stop moving once it reaches the destination coordinates. - * Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all) + * Get a tile's collision group that is stored in the Tileset. Returns null if tile index is not + * contained in this Tileset. This is typically defined within Tiled's tileset collision editor. * - * @method Phaser.Physics.Arcade.ArcadePhysics#moveTo + * @method Phaser.Tilemaps.Tileset#getTileCollisionGroup * @since 3.0.0 * - * @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body. - * @param {number} x - The x coordinate to move towards. - * @param {number} y - The y coordinate to move towards. - * @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec) - * @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms. + * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. * - * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. + * @return {?object} */ - moveTo: function (gameObject, x, y, speed, maxTime) + getTileCollisionGroup: function (tileIndex) { - if (speed === undefined) { speed = 60; } - if (maxTime === undefined) { maxTime = 0; } - - var angle = Math.atan2(y - gameObject.y, x - gameObject.x); - - if (maxTime > 0) - { - // We know how many pixels we need to move, but how fast? - speed = DistanceBetween(gameObject.x, gameObject.y, x, y) / (maxTime / 1000); - } - - gameObject.body.velocity.setToPolar(angle, speed); + var data = this.getTileData(tileIndex); - return angle; + return (data && data.objectgroup) ? data.objectgroup : null; }, /** - * Move the given display object towards the destination object at a steady velocity. - * If you specify a maxTime then it will adjust the speed (overwriting what you set) so it arrives at the destination in that number of seconds. - * Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms. - * Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course. - * Note: The display object doesn't stop moving once it reaches the destination coordinates. - * Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all) + * Returns true if and only if this Tileset contains the given tile index. * - * @method Phaser.Physics.Arcade.ArcadePhysics#moveToObject + * @method Phaser.Tilemaps.Tileset#containsTileIndex * @since 3.0.0 * - * @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body. - * @param {object} destination - Any object with public `x` and `y` properties, such as a Game Object or Geometry object. - * @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec) - * @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms. + * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. * - * @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. + * @return {boolean} */ - moveToObject: function (gameObject, destination, speed, maxTime) + containsTileIndex: function (tileIndex) { - return this.moveTo(gameObject, destination.x, destination.y, speed, maxTime); + return ( + tileIndex >= this.firstgid && + tileIndex < (this.firstgid + this.total) + ); }, /** - * Given the angle (in degrees) and speed calculate the velocity and return it as a vector, or set it to the given vector object. - * One way to use this is: velocityFromAngle(angle, 200, sprite.body.velocity) which will set the values directly to the sprite's velocity and not create a new vector object. + * Returns the texture coordinates (UV in pixels) in the Tileset image for the given tile index. + * Returns null if tile index is not contained in this Tileset. * - * @method Phaser.Physics.Arcade.ArcadePhysics#velocityFromAngle + * @method Phaser.Tilemaps.Tileset#getTileTextureCoordinates * @since 3.0.0 * - * @param {number} angle - The angle in degrees calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative) - * @param {number} [speed=60] - The speed it will move, in pixels per second squared. - * @param {Phaser.Math.Vector2} [vec2] - The Vector2 in which the x and y properties will be set to the calculated velocity. + * @param {number} tileIndex - The unique id of the tile across all tilesets in the map. * - * @return {Phaser.Math.Vector2} The Vector2 that stores the velocity. + * @return {?object} Object in the form { x, y } representing the top-left UV coordinate + * within the Tileset image. */ - velocityFromAngle: function (angle, speed, vec2) + getTileTextureCoordinates: function (tileIndex) { - if (speed === undefined) { speed = 60; } - if (vec2 === undefined) { vec2 = new Vector2(); } + if (!this.containsTileIndex(tileIndex)) { return null; } - return vec2.setToPolar(DegToRad(angle), speed); + return this.texCoordinates[tileIndex - this.firstgid]; }, /** - * Given the rotation (in radians) and speed calculate the velocity and return it as a vector, or set it to the given vector object. - * One way to use this is: velocityFromRotation(rotation, 200, sprite.body.velocity) which will set the values directly to the sprite's velocity and not create a new vector object. + * Sets the image associated with this Tileset and updates the tile data (rows, columns, etc.). * - * @method Phaser.Physics.Arcade.ArcadePhysics#velocityFromRotation + * @method Phaser.Tilemaps.Tileset#setImage * @since 3.0.0 * - * @param {number} rotation - The angle in radians. - * @param {number} [speed=60] - The speed it will move, in pixels per second squared - * @param {Phaser.Math.Vector2} [vec2] - The Vector2 in which the x and y properties will be set to the calculated velocity. + * @param {Phaser.Textures.Texture} texture - The image that contains the tiles. * - * @return {Phaser.Math.Vector2} The Vector2 that stores the velocity. + * @return {Phaser.Tilemaps.Tileset} This Tileset object. */ - velocityFromRotation: function (rotation, speed, vec2) + setImage: function (texture) { - if (speed === undefined) { speed = 60; } - if (vec2 === undefined) { vec2 = new Vector2(); } + this.image = texture; - return vec2.setToPolar(rotation, speed); + this.glTexture = texture.get().source.glTexture; + + this.updateTileData(this.image.source[0].width, this.image.source[0].height); + + return this; }, /** - * This method will search the given rectangular 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 for is extremely fast, - * otherwise the search is O(N) for Dynamic Bodies. + * Sets the tile width & height and updates the tile data (rows, columns, etc.). * - * @method Phaser.Physics.Arcade.ArcadePhysics#overlapRect - * @since 3.17.0 + * @method Phaser.Tilemaps.Tileset#setTileSize + * @since 3.0.0 * - * @param {number} x - The top-left x coordinate of the area to search within. - * @param {number} y - The top-left y coordinate of the area to search within. - * @param {number} width - The width of the area to search within. - * @param {number} height - The height 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? + * @param {number} [tileWidth] - The width of a tile in pixels. + * @param {number} [tileHeight] - The height of a tile in pixels. * - * @return {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[])} An array of bodies that overlap with the given area. + * @return {Phaser.Tilemaps.Tileset} This Tileset object. */ - overlapRect: function (x, y, width, height, includeDynamic, includeStatic) + setTileSize: function (tileWidth, tileHeight) { - return OverlapRect(this.world, x, y, width, height, includeDynamic, includeStatic); + if (tileWidth !== undefined) { this.tileWidth = tileWidth; } + if (tileHeight !== undefined) { this.tileHeight = tileHeight; } + + if (this.image) + { + this.updateTileData(this.image.source[0].width, this.image.source[0].height); + } + + return this; }, /** - * 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. + * Sets the tile margin & spacing and updates the tile data (rows, columns, etc.). * - * @method Phaser.Physics.Arcade.ArcadePhysics#overlapCirc - * @since 3.21.0 + * @method Phaser.Tilemaps.Tileset#setSpacing + * @since 3.0.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? + * @param {number} [margin] - The margin around the tiles in the sheet (in pixels). + * @param {number} [spacing] - The spacing between the tiles in the sheet (in pixels). * - * @return {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[])} An array of bodies that overlap with the given area. + * @return {Phaser.Tilemaps.Tileset} This Tileset object. */ - overlapCirc: function (x, y, radius, includeDynamic, includeStatic) + setSpacing: function (margin, spacing) { - return OverlapCirc(this.world, x, y, radius, includeDynamic, includeStatic); + if (margin !== undefined) { this.tileMargin = margin; } + if (spacing !== undefined) { this.tileSpacing = spacing; } + + if (this.image) + { + this.updateTileData(this.image.source[0].width, this.image.source[0].height); + } + + return this; }, /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. + * Updates tile texture coordinates and tileset data. * - * @method Phaser.Physics.Arcade.ArcadePhysics#shutdown + * @method Phaser.Tilemaps.Tileset#updateTileData * @since 3.0.0 + * + * @param {number} imageWidth - The (expected) width of the image to slice. + * @param {number} imageHeight - The (expected) height of the image to slice. + * + * @return {Phaser.Tilemaps.Tileset} This Tileset object. */ - shutdown: function () + updateTileData: function (imageWidth, imageHeight) { - if (!this.world) + var rowCount = (imageHeight - this.tileMargin * 2 + this.tileSpacing) / (this.tileHeight + this.tileSpacing); + var colCount = (imageWidth - this.tileMargin * 2 + this.tileSpacing) / (this.tileWidth + this.tileSpacing); + + if (rowCount % 1 !== 0 || colCount % 1 !== 0) { - // Already destroyed - return; + console.warn('Image tile area not tile size multiple in: ' + this.name); } - var eventEmitter = this.systems.events; + // In Tiled a tileset image that is not an even multiple of the tile dimensions is truncated + // - hence the floor when calculating the rows/columns. + rowCount = Math.floor(rowCount); + colCount = Math.floor(colCount); - eventEmitter.off(SceneEvents.UPDATE, this.world.update, this.world); - eventEmitter.off(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world); - eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); + this.rows = rowCount; + this.columns = colCount; - this.add.destroy(); - this.world.destroy(); + // In Tiled, "empty" spaces in a tileset count as tiles and hence count towards the gid + this.total = rowCount * colCount; - this.add = null; - this.world = null; - }, + this.texCoordinates.length = 0; - /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. - * - * @method Phaser.Physics.Arcade.ArcadePhysics#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.shutdown(); + var tx = this.tileMargin; + var ty = this.tileMargin; - this.scene.sys.events.off(SceneEvents.START, this.start, this); + for (var y = 0; y < this.rows; y++) + { + for (var x = 0; x < this.columns; x++) + { + this.texCoordinates.push({ x: tx, y: ty }); + tx += this.tileWidth + this.tileSpacing; + } - this.scene = null; - this.systems = null; + tx = this.tileMargin; + ty += this.tileHeight + this.tileSpacing; + } + + return this; } }); -PluginCache.register('ArcadePhysics', ArcadePhysics, 'arcadePhysics'); - -module.exports = ArcadePhysics; +module.exports = Tileset; /***/ }), -/* 1368 */ -/***/ (function(module, exports) { + +/***/ 92839: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetTileAt = __webpack_require__(15494); + /** - * Provides methods used for setting the acceleration properties of an Arcade Physics Body. + * 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. * - * @namespace Phaser.Physics.Arcade.Components.Acceleration + * @function Phaser.Tilemaps.Components.CalculateFacesAt * @since 3.0.0 + * + * @param {number} tileX - The x coordinate. + * @param {number} tileY - The y coordinate. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -var Acceleration = { +var CalculateFacesAt = function (tileX, tileY, layer) +{ + var tile = GetTileAt(tileX, tileY, true, layer); + var above = GetTileAt(tileX, tileY - 1, true, layer); + var below = GetTileAt(tileX, tileY + 1, true, layer); + var left = GetTileAt(tileX - 1, tileY, true, layer); + var right = GetTileAt(tileX + 1, tileY, true, layer); + var tileCollides = tile && tile.collides; - /** - * Sets the body's horizontal and vertical acceleration. If the vertical acceleration value is not provided, the vertical acceleration is set to the same value as the horizontal acceleration. - * - * @method Phaser.Physics.Arcade.Components.Acceleration#setAcceleration - * @since 3.0.0 - * - * @param {number} x - The horizontal acceleration - * @param {number} [y=x] - The vertical acceleration - * - * @return {this} This Game Object. - */ - setAcceleration: function (x, y) + // Assume the changed tile has all interesting edges + if (tileCollides) { - this.body.acceleration.set(x, y); + tile.faceTop = true; + tile.faceBottom = true; + tile.faceLeft = true; + tile.faceRight = true; + } - return this; - }, + // Reset edges that are shared between tile and its neighbors + if (above && above.collides) + { + if (tileCollides) + { + tile.faceTop = false; + } - /** - * Sets the body's horizontal acceleration. - * - * @method Phaser.Physics.Arcade.Components.Acceleration#setAccelerationX - * @since 3.0.0 - * - * @param {number} value - The horizontal acceleration - * - * @return {this} This Game Object. - */ - setAccelerationX: function (value) + above.faceBottom = !tileCollides; + } + + if (below && below.collides) { - this.body.acceleration.x = value; + if (tileCollides) + { + tile.faceBottom = false; + } - return this; - }, + below.faceTop = !tileCollides; + } - /** - * Sets the body's vertical acceleration. - * - * @method Phaser.Physics.Arcade.Components.Acceleration#setAccelerationY - * @since 3.0.0 - * - * @param {number} value - The vertical acceleration - * - * @return {this} This Game Object. - */ - setAccelerationY: function (value) + if (left && left.collides) { - this.body.acceleration.y = value; + if (tileCollides) + { + tile.faceLeft = false; + } - return this; + left.faceRight = !tileCollides; + } + + if (right && right.collides) + { + if (tileCollides) + { + tile.faceRight = false; + } + + right.faceLeft = !tileCollides; + } + + if (tile && !tile.collides) + { + tile.resetFaces(); } + return tile; }; -module.exports = Acceleration; +module.exports = CalculateFacesAt; /***/ }), -/* 1369 */ -/***/ (function(module, exports) { + +/***/ 60386: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetTileAt = __webpack_require__(15494); +var GetTilesWithin = __webpack_require__(50811); + /** - * Provides methods used for setting the angular acceleration properties of an Arcade Physics Body. + * 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. * - * @namespace Phaser.Physics.Arcade.Components.Angular + * @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 Angular = { +var CalculateFacesWithin = function (tileX, tileY, width, height, layer) +{ + var above = null; + var below = null; + var left = null; + var right = null; - /** - * Sets the angular velocity of the body. - * - * In Arcade Physics, bodies cannot rotate. They are always axis-aligned. - * However, they can have angular motion, which is passed on to the Game Object bound to the body, - * causing them to visually rotate, even though the body remains axis-aligned. - * - * @method Phaser.Physics.Arcade.Components.Angular#setAngularVelocity - * @since 3.0.0 - * - * @param {number} value - The amount of angular velocity. - * - * @return {this} This Game Object. - */ - setAngularVelocity: function (value) + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + + for (var i = 0; i < tiles.length; i++) { - this.body.angularVelocity = value; + var tile = tiles[i]; - return this; - }, + 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); - /** - * Sets the angular acceleration of the body. - * - * In Arcade Physics, bodies cannot rotate. They are always axis-aligned. - * However, they can have angular motion, which is passed on to the Game Object bound to the body, - * causing them to visually rotate, even though the body remains axis-aligned. - * - * @method Phaser.Physics.Arcade.Components.Angular#setAngularAcceleration - * @since 3.0.0 - * - * @param {number} value - The amount of angular acceleration. - * - * @return {this} This Game Object. - */ - setAngularAcceleration: function (value) + 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; + + +/***/ }), + +/***/ 13125: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(93736); + +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; + + +/***/ }), + +/***/ 17347: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CalculateFacesWithin = __webpack_require__(60386); +var GetTilesWithin = __webpack_require__(50811); +var IsInLayerBounds = __webpack_require__(62839); +var Tile = __webpack_require__(29633); + +/** + * 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 and recalculates collision + * information in the destination region. + * + * @function Phaser.Tilemaps.Components.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` if the faces data should be recalculated. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + */ +var Copy = function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) +{ + if (recalculateFaces === undefined) { recalculateFaces = true; } + + // Returns an array of Tile references + var srcTiles = GetTilesWithin(srcTileX, srcTileY, width, height, null, layer); + + // Create a new array of fresh Tile objects + var copyTiles = []; + + srcTiles.forEach(function (tile) { - this.body.angularAcceleration = value; + var newTile = new Tile( + tile.layer, + tile.index, + tile.x, + tile.y, + tile.width, + tile.height, + tile.baseWidth, + tile.baseHeight + ); - return this; - }, + newTile.copy(tile); - /** - * Sets the angular drag of the body. Drag is applied to the current velocity, providing a form of deceleration. - * - * @method Phaser.Physics.Arcade.Components.Angular#setAngularDrag - * @since 3.0.0 - * - * @param {number} value - The amount of drag. - * - * @return {this} This Game Object. - */ - setAngularDrag: function (value) + copyTiles.push(newTile); + }); + + var offsetX = destTileX - srcTileX; + var offsetY = destTileY - srcTileY; + + for (var i = 0; i < copyTiles.length; i++) { - this.body.angularDrag = value; + var copy = copyTiles[i]; + var tileX = copy.x + offsetX; + var tileY = copy.y + offsetY; - return this; + if (IsInLayerBounds(tileX, tileY, layer)) + { + if (layer.data[tileY][tileX]) + { + copy.x = tileX; + copy.y = tileY; + copy.updatePixelXY(); + + layer.data[tileY][tileX] = copy; + } + } + } + + if (recalculateFaces) + { + // Recalculate the faces within the destination area and neighboring tiles + CalculateFacesWithin(destTileX - 1, destTileY - 1, width + 2, height + 2, layer); } + srcTiles.length = 0; + copyTiles.length = 0; }; -module.exports = Angular; +module.exports = Copy; /***/ }), -/* 1370 */ -/***/ (function(module, exports) { + +/***/ 93604: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetTilesWithin = __webpack_require__(50811); +var ReplaceByIndex = __webpack_require__(51202); + /** - * Provides methods used for setting the bounce properties of an Arcade Physics Body. + * 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. * - * @namespace Phaser.Physics.Arcade.Components.Bounce + * @function Phaser.Tilemaps.Components.CreateFromTiles * @since 3.0.0 + * + * @param {(number|number[])} indexes - The tile index, or array of indexes, to create Sprites from. + * @param {?(number|number[])} 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 + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.GameObjects.Sprite[]} An array of the Sprites that were created. */ -var Bounce = { +var CreateFromTiles = function (indexes, replacements, spriteConfig, scene, camera, layer) +{ + if (!spriteConfig) { spriteConfig = {}; } - /** - * Sets the bounce values of this body. - * - * Bounce is the amount of restitution, or elasticity, the body has when it collides with another object. - * A value of 1 means that it will retain its full velocity after the rebound. A value of 0 means it will not rebound at all. - * - * @method Phaser.Physics.Arcade.Components.Bounce#setBounce - * @since 3.0.0 - * - * @param {number} x - The amount of horizontal bounce to apply on collision. A float, typically between 0 and 1. - * @param {number} [y=x] - The amount of vertical bounce to apply on collision. A float, typically between 0 and 1. - * - * @return {this} This Game Object. - */ - setBounce: function (x, y) + if (!Array.isArray(indexes)) { - this.body.bounce.set(x, y); + indexes = [ indexes ]; + } - return this; - }, + var tilemapLayer = layer.tilemapLayer; - /** - * Sets the horizontal bounce value for this body. - * - * @method Phaser.Physics.Arcade.Components.Bounce#setBounceX - * @since 3.0.0 - * - * @param {number} value - The amount of horizontal bounce to apply on collision. A float, typically between 0 and 1. - * - * @return {this} This Game Object. - */ - setBounceX: function (value) - { - this.body.bounce.x = value; + if (!scene) { scene = tilemapLayer.scene; } + if (!camera) { camera = scene.cameras.main; } - return this; - }, + var tiles = GetTilesWithin(0, 0, layer.width, layer.height, null, layer); + var sprites = []; + var i; - /** - * Sets the vertical bounce value for this body. - * - * @method Phaser.Physics.Arcade.Components.Bounce#setBounceY - * @since 3.0.0 - * - * @param {number} value - The amount of vertical bounce to apply on collision. A float, typically between 0 and 1. - * - * @return {this} This Game Object. - */ - setBounceY: function (value) + for (i = 0; i < tiles.length; i++) { - this.body.bounce.y = value; + var tile = tiles[i]; - return this; - }, + if (indexes.indexOf(tile.index) !== -1) + { + var point = tilemapLayer.tileToWorldXY(tile.x, tile.y, undefined, camera,layer); - /** - * Sets whether this Body collides with the world boundary. - * - * Optionally also sets the World Bounce values. If the `Body.worldBounce` is null, it's set to a new Phaser.Math.Vector2 first. - * - * @method Phaser.Physics.Arcade.Components.Bounce#setCollideWorldBounds - * @since 3.0.0 - * - * @param {boolean} [value=true] - `true` if this body should collide with the world bounds, otherwise `false`. - * @param {number} [bounceX] - If given this will be replace the `worldBounce.x` value. - * @param {number} [bounceY] - If given this will be replace the `worldBounce.y` value. - * - * @return {this} This Game Object. - */ - setCollideWorldBounds: function (value, bounceX, bounceY) + spriteConfig.x = point.x; + spriteConfig.y = point.y; + + sprites.push(scene.make.sprite(spriteConfig)); + } + } + + if (typeof replacements === 'number') + { + // Assume 1 replacement for all types of tile given + for (i = 0; i < indexes.length; i++) + { + ReplaceByIndex(indexes[i], replacements, 0, 0, layer.width, layer.height, layer); + } + } + else if (Array.isArray(replacements)) { - this.body.setCollideWorldBounds(value, bounceX, bounceY); + // Assume 1 to 1 mapping with indexes array + for (i = 0; i < indexes.length; i++) + { + ReplaceByIndex(indexes[i], replacements[i], 0, 0, layer.width, layer.height, layer); + } + } - return this; + return sprites; +}; + +module.exports = CreateFromTiles; + + +/***/ }), + +/***/ 71586: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Rectangle = __webpack_require__(74118); +var SnapCeil = __webpack_require__(82127); +var SnapFloor = __webpack_require__(84314); + +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; + + +/***/ }), + +/***/ 381: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CullBounds = __webpack_require__(71586); +var RunCull = __webpack_require__(6987); + +/** + * 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 = Bounce; +module.exports = CullTiles; /***/ }), -/* 1371 */ -/***/ (function(module, exports) { + +/***/ 97734: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetTilesWithin = __webpack_require__(50811); +var CalculateFacesWithin = __webpack_require__(60386); +var SetTileCollision = __webpack_require__(68234); + /** - * Provides methods used for setting the debug properties of an Arcade Physics Body. + * 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. * - * @namespace Phaser.Physics.Arcade.Components.Debug + * @function Phaser.Tilemaps.Components.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` if the faces data should be recalculated. + * @param {Phaser.Tilemaps.LayerData} layer - The tile layer to use. If not given the current layer is used. */ -var Debug = { +var Fill = function (index, tileX, tileY, width, height, recalculateFaces, layer) +{ + var doesIndexCollide = (layer.collideIndexes.indexOf(index) !== -1); - /** - * Sets the debug values of this body. - * - * Bodies will only draw their debug if debug has been enabled for Arcade Physics as a whole. - * Note that there is a performance cost in drawing debug displays. It should never be used in production. - * - * @method Phaser.Physics.Arcade.Components.Debug#setDebug - * @since 3.0.0 - * - * @param {boolean} showBody - Set to `true` to have this body render its outline to the debug display. - * @param {boolean} showVelocity - Set to `true` to have this body render a velocity marker to the debug display. - * @param {number} bodyColor - The color of the body outline when rendered to the debug display. - * - * @return {this} This Game Object. - */ - setDebug: function (showBody, showVelocity, bodyColor) + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + + for (var i = 0; i < tiles.length; i++) { - this.debugShowBody = showBody; - this.debugShowVelocity = showVelocity; - this.debugBodyColor = bodyColor; + tiles[i].index = index; - return this; - }, + SetTileCollision(tiles[i], doesIndexCollide); + } - /** - * Sets the color of the body outline when it renders to the debug display. - * - * @method Phaser.Physics.Arcade.Components.Debug#setDebugBodyColor - * @since 3.0.0 - * - * @param {number} value - The color of the body outline when rendered to the debug display. - * - * @return {this} This Game Object. - */ - setDebugBodyColor: function (value) + if (recalculateFaces) { - this.body.debugBodyColor = value; + // Recalculate the faces within the area and neighboring tiles + CalculateFacesWithin(tileX - 1, tileY - 1, width + 2, height + 2, layer); + } +}; - return this; - }, +module.exports = Fill; - /** - * Set to `true` to have this body render its outline to the debug display. - * - * @name Phaser.Physics.Arcade.Components.Debug#debugShowBody - * @type {boolean} - * @since 3.0.0 - */ - debugShowBody: { - get: function () - { - return this.body.debugShowBody; - }, +/***/ }), - set: function (value) +/***/ 63555: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTilesWithin = __webpack_require__(50811); + +/** + * 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. + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile[]} The filtered array of Tiles. + */ +var FilterTiles = function (callback, context, tileX, tileY, width, height, filteringOptions, layer) +{ + var tiles = GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); + + return tiles.filter(callback, context); +}; + +module.exports = FilterTiles; + + +/***/ }), + +/***/ 37982: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * 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. + * + * @function Phaser.Tilemaps.Components.FindByIndex + * @since 3.0.0 + * + * @param {number} index - The tile index value to search for. + * @param {number} skip - The number of times to skip a matching tile before returning. + * @param {boolean} reverse - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {?Phaser.Tilemaps.Tile} The first (or n skipped) tile with the matching index. + */ +var FindByIndex = function (findIndex, skip, reverse, layer) +{ + if (skip === undefined) { skip = 0; } + if (reverse === undefined) { reverse = false; } + + var count = 0; + var tx; + var ty; + var tile; + + if (reverse) + { + for (ty = layer.height - 1; ty >= 0; ty--) { - this.body.debugShowBody = value; + for (tx = layer.width - 1; tx >= 0; tx--) + { + tile = layer.data[ty][tx]; + if (tile && tile.index === findIndex) + { + if (count === skip) + { + return tile; + } + else + { + count += 1; + } + } + } + } + } + else + { + for (ty = 0; ty < layer.height; ty++) + { + for (tx = 0; tx < layer.width; tx++) + { + tile = layer.data[ty][tx]; + if (tile && tile.index === findIndex) + { + if (count === skip) + { + return tile; + } + else + { + count += 1; + } + } + } } + } - }, + return null; +}; - /** - * Set to `true` to have this body render a velocity marker to the debug display. - * - * @name Phaser.Physics.Arcade.Components.Debug#debugShowVelocity - * @type {boolean} - * @since 3.0.0 - */ - debugShowVelocity: { +module.exports = FindByIndex; - get: function () - { - return this.body.debugShowVelocity; - }, - set: function (value) - { - this.body.debugShowVelocity = value; - } +/***/ }), - }, +/***/ 48297: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * The color of the body outline when it renders to the debug display. - * - * @name Phaser.Physics.Arcade.Components.Debug#debugBodyColor - * @type {number} - * @since 3.0.0 - */ - debugBodyColor: { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - get: function () - { - return this.body.debugBodyColor; - }, +var GetTilesWithin = __webpack_require__(50811); - set: function (value) - { - this.body.debugBodyColor = value; - } +/** + * @callback FindTileCallback + * + * @param {Phaser.Tilemaps.Tile} value - The Tile. + * @param {number} index - The index of the tile. + * @param {Phaser.Tilemaps.Tile[]} array - An array of Tile objects. + * + * @return {boolean} Return `true` if the callback should run, otherwise `false`. + */ - } +/** + * 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. + * + * @function Phaser.Tilemaps.Components.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 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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {?Phaser.Tilemaps.Tile} A Tile that matches the search, or null if no Tile found + */ +var FindTile = function (callback, context, tileX, tileY, width, height, filteringOptions, layer) +{ + var tiles = GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); + return tiles.find(callback, context) || null; }; -module.exports = Debug; +module.exports = FindTile; /***/ }), -/* 1372 */ -/***/ (function(module, exports) { + +/***/ 80916: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetTilesWithin = __webpack_require__(50811); + /** - * Provides methods used for setting the drag properties of an Arcade Physics Body. + * @callback EachTileCallback * - * @namespace Phaser.Physics.Arcade.Components.Drag + * @param {Phaser.Tilemaps.Tile} value - The Tile. + * @param {number} index - The index of the tile. + * @param {Phaser.Tilemaps.Tile[]} array - An array of Tile objects. + */ + +/** + * 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. + * + * @function Phaser.Tilemaps.Components.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 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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -var Drag = { +var ForEachTile = function (callback, context, tileX, tileY, width, height, filteringOptions, layer) +{ + var tiles = GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); - /** - * Sets the body's horizontal and vertical drag. If the vertical drag value is not provided, the vertical drag is set to the same value as the horizontal drag. - * - * Drag can be considered as a form of deceleration that will return the velocity of a body back to zero over time. - * It is the absolute loss of velocity due to movement, in pixels per second squared. - * The x and y components are applied separately. - * - * When `useDamping` is true, this is 1 minus the damping factor. - * A value of 1 means the Body loses no velocity. - * A value of 0.95 means the Body loses 5% of its velocity per step. - * A value of 0.5 means the Body loses 50% of its velocity per step. - * - * Drag is applied only when `acceleration` is zero. - * - * @method Phaser.Physics.Arcade.Components.Drag#setDrag - * @since 3.0.0 - * - * @param {number} x - The amount of horizontal drag to apply. - * @param {number} [y=x] - The amount of vertical drag to apply. - * - * @return {this} This Game Object. - */ - setDrag: function (x, y) - { - this.body.drag.set(x, y); + tiles.forEach(callback, context); +}; - return this; - }, +module.exports = ForEachTile; - /** - * Sets the body's horizontal drag. - * - * Drag can be considered as a form of deceleration that will return the velocity of a body back to zero over time. - * It is the absolute loss of velocity due to movement, in pixels per second squared. - * The x and y components are applied separately. - * - * When `useDamping` is true, this is 1 minus the damping factor. - * A value of 1 means the Body loses no velocity. - * A value of 0.95 means the Body loses 5% of its velocity per step. - * A value of 0.5 means the Body loses 50% of its velocity per step. - * - * Drag is applied only when `acceleration` is zero. - * - * @method Phaser.Physics.Arcade.Components.Drag#setDragX - * @since 3.0.0 - * - * @param {number} value - The amount of horizontal drag to apply. - * - * @return {this} This Game Object. - */ - setDragX: function (value) - { - this.body.drag.x = value; - return this; - }, +/***/ }), - /** - * Sets the body's vertical drag. - * - * Drag can be considered as a form of deceleration that will return the velocity of a body back to zero over time. - * It is the absolute loss of velocity due to movement, in pixels per second squared. - * The x and y components are applied separately. - * - * When `useDamping` is true, this is 1 minus the damping factor. - * A value of 1 means the Body loses no velocity. - * A value of 0.95 means the Body loses 5% of its velocity per step. - * A value of 0.5 means the Body loses 50% of its velocity per step. - * - * Drag is applied only when `acceleration` is zero. - * - * @method Phaser.Physics.Arcade.Components.Drag#setDragY - * @since 3.0.0 - * - * @param {number} value - The amount of vertical drag to apply. - * - * @return {this} This Game Object. - */ - setDragY: function (value) - { - this.body.drag.y = value; +/***/ 31493: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * If this Body is using `drag` for deceleration this function 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.Components.Drag#setDamping - * @since 3.10.0 - * - * @param {boolean} value - `true` to use damping for deceleration, or `false` to use linear deceleration. - * - * @return {this} This Game Object. - */ - setDamping: function (value) - { - this.body.useDamping = value; +var CONST = __webpack_require__(12920); +var CullTiles = __webpack_require__(381); +var HexagonalCullTiles = __webpack_require__(37524); +var IsometricCullTiles = __webpack_require__(20887); +var NOOP = __webpack_require__(72283); +var StaggeredCullTiles = __webpack_require__(19242); - return this; +/** + * Gets the correct function to use to cull tiles, based on the map orientation. + * + * @function Phaser.Tilemaps.Components.GetCullTilesFunction + * @since 3.50.0 + * + * @param {number} orientation - The Tilemap orientation constant. + * + * @return {function} The function to use to cull tiles for the given map type. + */ +var GetCullTilesFunction = function (orientation) +{ + if (orientation === CONST.ORTHOGONAL) + { + return CullTiles; + } + else if (orientation === CONST.HEXAGONAL) + { + return HexagonalCullTiles; + } + else if (orientation === CONST.STAGGERED) + { + return StaggeredCullTiles; + } + else if (orientation === CONST.ISOMETRIC) + { + return IsometricCullTiles; + } + else + { + return NOOP; } - }; -module.exports = Drag; +module.exports = GetCullTilesFunction; /***/ }), -/* 1373 */ -/***/ (function(module, exports) { + +/***/ 15494: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var IsInLayerBounds = __webpack_require__(62839); + /** - * Provides methods used for setting the enable properties of an Arcade Physics Body. + * Gets a tile at the given tile coordinates from the given layer. * - * @namespace Phaser.Physics.Arcade.Components.Enable + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid. */ -var Enable = { +var GetTileAt = function (tileX, tileY, nonNull, layer) +{ + if (nonNull === undefined) { nonNull = false; } - /** - * Enables this Game Object's Body. - * - * @method Phaser.Physics.Arcade.Components.Enable#enableBody - * @since 3.0.0 - * - * @param {boolean} reset - Also reset the Body and place it at (x, y). - * @param {number} x - The horizontal position to place the Game Object and Body. - * @param {number} y - The horizontal position to place the Game Object and Body. - * @param {boolean} enableGameObject - Also activate this Game Object. - * @param {boolean} showGameObject - Also show this Game Object. - * - * @return {this} This Game Object. - * - * @see Phaser.Physics.Arcade.Body#enable - * @see Phaser.Physics.Arcade.StaticBody#enable - * @see Phaser.Physics.Arcade.Body#reset - * @see Phaser.Physics.Arcade.StaticBody#reset - * @see Phaser.GameObjects.GameObject#active - * @see Phaser.GameObjects.GameObject#visible - */ - enableBody: function (reset, x, y, enableGameObject, showGameObject) + if (IsInLayerBounds(tileX, tileY, layer)) { - if (reset) + var tile = layer.data[tileY][tileX] || null; + + if (!tile) { - this.body.reset(x, y); + return null; } - - if (enableGameObject) + else if (tile.index === -1) { - this.body.gameObject.active = true; + return nonNull ? tile : null; } - - if (showGameObject) + else { - this.body.gameObject.visible = true; + return tile; } - - this.body.enable = true; - - return this; - }, - - /** - * Stops and disables this Game Object's Body. - * - * @method Phaser.Physics.Arcade.Components.Enable#disableBody - * @since 3.0.0 - * - * @param {boolean} [disableGameObject=false] - Also deactivate this Game Object. - * @param {boolean} [hideGameObject=false] - Also hide this Game Object. - * - * @return {this} This Game Object. - * - * @see Phaser.Physics.Arcade.Body#enable - * @see Phaser.Physics.Arcade.StaticBody#enable - * @see Phaser.GameObjects.GameObject#active - * @see Phaser.GameObjects.GameObject#visible - */ - disableBody: function (disableGameObject, hideGameObject) + } + else { - if (disableGameObject === undefined) { disableGameObject = false; } - if (hideGameObject === undefined) { hideGameObject = false; } + return null; + } +}; - this.body.stop(); +module.exports = GetTileAt; - this.body.enable = false; - if (disableGameObject) - { - this.body.gameObject.active = false; - } +/***/ }), - if (hideGameObject) - { - this.body.gameObject.visible = false; - } +/***/ 24640: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Syncs the Body's position and size with its parent Game Object. - * You don't need to call this for Dynamic Bodies, as it happens automatically. - * But for Static bodies it's a useful way of modifying the position of a Static Body - * in the Physics World, based on its Game Object. - * - * @method Phaser.Physics.Arcade.Components.Enable#refreshBody - * @since 3.1.0 - * - * @return {this} This Game Object. - * - * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject - */ - refreshBody: function () - { - this.body.updateFromGameObject(); +var GetTileAt = __webpack_require__(15494); +var Vector2 = __webpack_require__(93736); - return this; - } +var point = new Vector2(); + +/** + * Gets a tile at the given world coordinates from the given layer. + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid. + */ +var GetTileAtWorldXY = function (worldX, worldY, nonNull, camera, layer) +{ + layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera); + return GetTileAt(point.x, point.y, nonNull, layer); }; -module.exports = Enable; +module.exports = GetTileAtWorldXY; /***/ }), -/* 1374 */ -/***/ (function(module, exports) { + +/***/ 48495: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Vector2 = __webpack_require__(93736); + /** - * Methods for setting the friction of an Arcade Physics Body. + * Gets the corners of the Tile as an array of Vector2s. * - * In Arcade Physics, friction is a special case of motion transfer from an "immovable" body to a riding body. + * @function Phaser.Tilemaps.Components.GetTileCorners + * @since 3.60.0 * - * @namespace Phaser.Physics.Arcade.Components.Friction - * @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.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. * - * @see Phaser.Physics.Arcade.Body#friction + * @return {Phaser.Math.Vector2[]} An array of Vector2s corresponding to the world XY location of each tile corner. */ -var Friction = { - - /** - * Sets the friction of this game object's physics body. - * In Arcade Physics, friction is a special case of motion transfer from an "immovable" body to a riding body. - * - * @method Phaser.Physics.Arcade.Components.Friction#setFriction - * @since 3.0.0 - * - * @param {number} x - The amount of horizontal friction to apply, [0, 1]. - * @param {number} [y=x] - The amount of vertical friction to apply, [0, 1]. - * - * @return {this} This Game Object. - * - * @see Phaser.Physics.Arcade.Body#friction - */ - setFriction: function (x, y) - { - this.body.friction.set(x, y); +var GetTileCorners = function (tileX, tileY, camera, layer) +{ + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; - return this; - }, + var worldX = 0; + var worldY = 0; - /** - * Sets the horizontal friction of this game object's physics body. - * This can move a riding body horizontally when it collides with this one on the vertical axis. - * - * @method Phaser.Physics.Arcade.Components.Friction#setFrictionX - * @since 3.0.0 - * - * @param {number} x - The amount of friction to apply, [0, 1]. - * - * @return {this} This Game Object. - * - * @see Phaser.Physics.Arcade.Body#friction - */ - setFrictionX: function (x) + if (tilemapLayer) { - this.body.friction.x = x; - - return this; - }, + if (!camera) { camera = tilemapLayer.scene.cameras.main; } - /** - * Sets the vertical friction of this game object's physics body. - * This can move a riding body vertically when it collides with this one on the horizontal axis. - * - * @method Phaser.Physics.Arcade.Components.Friction#setFrictionY - * @since 3.0.0 - * - * @param {number} y - The amount of friction to apply, [0, 1]. - * - * @return {this} This Game Object. - * - * @see Phaser.Physics.Arcade.Body#friction - */ - setFrictionY: function (y) - { - this.body.friction.y = y; + worldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + worldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - return this; + tileWidth *= tilemapLayer.scaleX; + tileHeight *= tilemapLayer.scaleY; } + var x = worldX + tileX * tileWidth; + var y = worldY + tileY * tileHeight; + + // Top Left + // Top Right + // Bottom Right + // Bottom Left + + return [ + new Vector2(x, y), + new Vector2(x + tileWidth, y), + new Vector2(x + tileWidth, y + tileHeight), + new Vector2(x, y + tileHeight) + ]; }; -module.exports = Friction; +module.exports = GetTileCorners; /***/ }), -/* 1375 */ -/***/ (function(module, exports) { + +/***/ 7160: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CONST = __webpack_require__(12920); +var HexagonalGetTileCorners = __webpack_require__(63634); +var NOOP = __webpack_require__(72283); +var GetTileCorners = __webpack_require__(48495); + /** - * Provides methods for setting the gravity properties of an Arcade Physics Game Object. - * Should be applied as a mixin and not used directly. + * Gets the correct function to use to get the tile corners, based on the map orientation. * - * @namespace Phaser.Physics.Arcade.Components.Gravity - * @since 3.0.0 + * @function Phaser.Tilemaps.Components.GetTileCornersFunction + * @since 3.60.0 + * + * @param {number} orientation - The Tilemap orientation constant. + * + * @return {function} The function to use to translate tiles for the given map type. */ -var Gravity = { - - /** - * Set the X and Y values of the gravitational pull to act upon this Arcade Physics Game Object. Values can be positive or negative. Larger values result in a stronger effect. - * - * If only one value is provided, this value will be used for both the X and Y axis. - * - * @method Phaser.Physics.Arcade.Components.Gravity#setGravity - * @since 3.0.0 - * - * @param {number} x - The gravitational force to be applied to the X-axis. - * @param {number} [y=x] - The gravitational force to be applied to the Y-axis. If this is not specified, the X value will be used. - * - * @return {this} This Game Object. - */ - setGravity: function (x, y) +var GetTileCornersFunction = function (orientation) +{ + if (orientation === CONST.ORTHOGONAL) { - this.body.gravity.set(x, y); - - return this; - }, - - /** - * Set the gravitational force to be applied to the X axis. Value can be positive or negative. Larger values result in a stronger effect. - * - * @method Phaser.Physics.Arcade.Components.Gravity#setGravityX - * @since 3.0.0 - * - * @param {number} x - The gravitational force to be applied to the X-axis. - * - * @return {this} This Game Object. - */ - setGravityX: function (x) + return GetTileCorners; + } + else if (orientation === CONST.ISOMETRIC) { - this.body.gravity.x = x; - - return this; - }, - - /** - * Set the gravitational force to be applied to the Y axis. Value can be positive or negative. Larger values result in a stronger effect. - * - * @method Phaser.Physics.Arcade.Components.Gravity#setGravityY - * @since 3.0.0 - * - * @param {number} y - The gravitational force to be applied to the Y-axis. - * - * @return {this} This Game Object. - */ - setGravityY: function (y) + return NOOP; + } + else if (orientation === CONST.HEXAGONAL) { - this.body.gravity.y = y; - - return this; + return HexagonalGetTileCorners; + } + else if (orientation === CONST.STAGGERED) + { + return NOOP; + } + else + { + return NOOP; } - }; -module.exports = Gravity; +module.exports = GetTileCornersFunction; /***/ }), -/* 1376 */ -/***/ (function(module, exports) { + +/***/ 16884: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CONST = __webpack_require__(12920); +var NOOP = __webpack_require__(72283); +var TileToWorldX = __webpack_require__(44150); + /** - * Provides methods used for setting the immovable properties of an Arcade Physics Body. + * Gets the correct function to use to translate tiles, based on the map orientation. * - * @namespace Phaser.Physics.Arcade.Components.Immovable - * @since 3.0.0 + * @function Phaser.Tilemaps.Components.GetTileToWorldXFunction + * @since 3.50.0 + * + * @param {number} orientation - The Tilemap orientation constant. + * + * @return {function} The function to use to translate tiles for the given map type. */ -var Immovable = { - - /** - * Sets if this Body can be separated during collisions with other bodies. - * - * When a body is immovable it means it won't move at all, not even to separate it from collision - * overlap. If you just wish to prevent a body from being knocked around by other bodies, see - * the `setPushable` method instead. - * - * @method Phaser.Physics.Arcade.Components.Immovable#setImmovable - * @since 3.0.0 - * - * @param {boolean} [value=true] - Sets if this body will be separated during collisions with other bodies. - * - * @return {this} This Game Object. - */ - setImmovable: function (value) +var GetTileToWorldXFunction = function (orientation) +{ + if (orientation === CONST.ORTHOGONAL) { - if (value === undefined) { value = true; } - - this.body.immovable = value; - - return this; + return TileToWorldX; + } + else + { + return NOOP; } - }; -module.exports = Immovable; +module.exports = GetTileToWorldXFunction; /***/ }), -/* 1377 */ -/***/ (function(module, exports) { + +/***/ 68182: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CONST = __webpack_require__(12920); +var HexagonalTileToWorldXY = __webpack_require__(21715); +var IsometricTileToWorldXY = __webpack_require__(21808); +var NOOP = __webpack_require__(72283); +var StaggeredTileToWorldXY = __webpack_require__(33388); +var TileToWorldXY = __webpack_require__(46836); + /** - * Provides methods used for setting the mass properties of an Arcade Physics Body. + * Gets the correct function to use to translate tiles, based on the map orientation. * - * @namespace Phaser.Physics.Arcade.Components.Mass - * @since 3.0.0 + * @function Phaser.Tilemaps.Components.GetTileToWorldXYFunction + * @since 3.50.0 + * + * @param {number} orientation - The Tilemap orientation constant. + * + * @return {function} The function to use to translate tiles for the given map type. */ -var Mass = { - - /** - * Sets the mass of the physics body - * - * @method Phaser.Physics.Arcade.Components.Mass#setMass - * @since 3.0.0 - * - * @param {number} value - New value for the mass of the body. - * - * @return {this} This Game Object. - */ - setMass: function (value) +var GetTileToWorldXYFunction = function (orientation) +{ + if (orientation === CONST.ORTHOGONAL) { - this.body.mass = value; - - return this; + return TileToWorldXY; + } + else if (orientation === CONST.ISOMETRIC) + { + return IsometricTileToWorldXY; + } + else if (orientation === CONST.HEXAGONAL) + { + return HexagonalTileToWorldXY; + } + else if (orientation === CONST.STAGGERED) + { + return StaggeredTileToWorldXY; + } + else + { + return NOOP; } - }; -module.exports = Mass; +module.exports = GetTileToWorldXYFunction; /***/ }), -/* 1378 */ -/***/ (function(module, exports) { + +/***/ 3752: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CONST = __webpack_require__(12920); +var NOOP = __webpack_require__(72283); +var StaggeredTileToWorldY = __webpack_require__(84132); +var TileToWorldY = __webpack_require__(42477); + /** - * Provides methods used for setting the pushable property of an Arcade Physics Body. + * Gets the correct function to use to translate tiles, based on the map orientation. * - * @namespace Phaser.Physics.Arcade.Components.Pushable + * @function Phaser.Tilemaps.Components.GetTileToWorldYFunction * @since 3.50.0 + * + * @param {number} orientation - The Tilemap orientation constant. + * + * @return {function} The function to use to translate tiles for the given map type. */ -var Pushable = { - - /** - * 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. - * - * @method Phaser.Physics.Arcade.Components.Pushable#setPushable - * @since 3.50.0 - * - * @param {boolean} [value=true] - Sets if this body can be pushed by collisions with another Body. - * - * @return {this} This Game Object. - */ - setPushable: function (value) +var GetTileToWorldYFunction = function (orientation) +{ + if (orientation === CONST.ORTHOGONAL) { - if (value === undefined) { value = true; } - - this.body.pushable = value; - - return this; + return TileToWorldY; + } + else if (orientation === CONST.STAGGERED) + { + return StaggeredTileToWorldY; + } + else + { + return NOOP; } - }; -module.exports = Pushable; +module.exports = GetTileToWorldYFunction; /***/ }), -/* 1379 */ -/***/ (function(module, exports) { + +/***/ 50811: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var GetFastValue = __webpack_require__(72632); + /** - * Provides methods for setting the size of an Arcade Physics Game Object. - * Should be applied as a mixin and not used directly. + * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. * - * @namespace Phaser.Physics.Arcade.Components.Size + * This returns an array with references to the Tile instances in, so be aware of + * modifying them directly. + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile[]} Array of Tile objects. */ -var Size = { +var GetTilesWithin = function (tileX, tileY, width, height, filteringOptions, layer) +{ + if (tileX === undefined) { tileX = 0; } + if (tileY === undefined) { tileY = 0; } + if (width === undefined) { width = layer.width; } + if (height === undefined) { height = layer.height; } + if (!filteringOptions) { filteringOptions = {}; } - /** - * Sets the body offset. This allows you to adjust the difference between the center of the body - * and the x and y coordinates of the parent Game Object. - * - * @method Phaser.Physics.Arcade.Components.Size#setOffset - * @since 3.0.0 - * - * @param {number} x - The amount to offset the body from the parent Game Object along the x-axis. - * @param {number} [y=x] - The amount to offset the body from the parent Game Object along the y-axis. Defaults to the value given for the x-axis. - * - * @return {this} This Game Object. - */ - setOffset: function (x, y) - { - this.body.setOffset(x, y); + var isNotEmpty = GetFastValue(filteringOptions, 'isNotEmpty', false); + var isColliding = GetFastValue(filteringOptions, 'isColliding', false); + var hasInterestingFace = GetFastValue(filteringOptions, 'hasInterestingFace', false); - return this; - }, + // Clip x, y to top left of map, while shrinking width/height to match. + if (tileX < 0) + { + width += tileX; + tileX = 0; + } - /** - * **DEPRECATED**: Please use `setBodySize` instead. - * - * Sets the size of this physics body. Setting the size does not adjust the dimensions of the parent Game Object. - * - * @method Phaser.Physics.Arcade.Components.Size#setSize - * @since 3.0.0 - * @deprecated - * - * @param {number} width - The new width of the physics body, in pixels. - * @param {number} height - The new height of the physics body, in pixels. - * @param {boolean} [center=true] - Should the body be re-positioned so its center aligns with the parent Game Object? - * - * @return {this} This Game Object. - */ - setSize: function (width, height, center) + if (tileY < 0) { - this.body.setSize(width, height, center); + height += tileY; + tileY = 0; + } - return this; - }, + // Clip width and height to bottom right of map. + if (tileX + width > layer.width) + { + width = Math.max(layer.width - tileX, 0); + } - /** - * Sets the size of this physics body. Setting the size does not adjust the dimensions of the parent Game Object. - * - * @method Phaser.Physics.Arcade.Components.Size#setBodySize - * @since 3.24.0 - * - * @param {number} width - The new width of the physics body, in pixels. - * @param {number} height - The new height of the physics body, in pixels. - * @param {boolean} [center=true] - Should the body be re-positioned so its center aligns with the parent Game Object? - * - * @return {this} This Game Object. - */ - setBodySize: function (width, height, center) + if (tileY + height > layer.height) { - this.body.setSize(width, height, center); + height = Math.max(layer.height - tileY, 0); + } - return this; - }, + var results = []; - /** - * Sets this physics body to use a circle for collision instead of a rectangle. - * - * @method Phaser.Physics.Arcade.Components.Size#setCircle - * @since 3.0.0 - * - * @param {number} radius - The radius of the physics body, in pixels. - * @param {number} [offsetX] - The amount to offset the body from the parent Game Object along the x-axis. - * @param {number} [offsetY] - The amount to offset the body from the parent Game Object along the y-axis. - * - * @return {this} This Game Object. - */ - setCircle: function (radius, offsetX, offsetY) + for (var ty = tileY; ty < tileY + height; ty++) { - this.body.setCircle(radius, offsetX, offsetY); + for (var tx = tileX; tx < tileX + width; tx++) + { + var tile = layer.data[ty][tx]; - return this; + if (tile !== null) + { + if (isNotEmpty && tile.index === -1) + { + continue; + } + + if (isColliding && !tile.collides) + { + continue; + } + + if (hasInterestingFace && !tile.hasInterestingFace) + { + continue; + } + + results.push(tile); + } + } } + return results; }; -module.exports = Size; +module.exports = GetTilesWithin; /***/ }), -/* 1380 */ -/***/ (function(module, exports) { + +/***/ 31674: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Geom = __webpack_require__(84068); +var GetTilesWithin = __webpack_require__(50811); +var Intersects = __webpack_require__(7563); +var NOOP = __webpack_require__(72283); +var Vector2 = __webpack_require__(93736); + +var TriangleToRectangle = function (triangle, rect) +{ + return Intersects.RectangleToTriangle(rect, triangle); +}; + +var point = new Vector2(); +var pointStart = new Vector2(); +var pointEnd = new Vector2(); + /** - * Provides methods for modifying the velocity of an Arcade Physics body. - * - * Should be applied as a mixin and not used directly. + * 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. * - * @namespace Phaser.Physics.Arcade.Components.Velocity + * @function Phaser.Tilemaps.Components.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 calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile[]} Array of Tile objects. */ -var Velocity = { +var GetTilesWithinShape = function (shape, filteringOptions, camera, layer) +{ + if (shape === undefined) { return []; } - /** - * Sets the velocity of the Body. - * - * @method Phaser.Physics.Arcade.Components.Velocity#setVelocity - * @since 3.0.0 - * - * @param {number} x - The horizontal velocity of the body. Positive values move the body to the right, while negative values move it to the left. - * @param {number} [y=x] - The vertical velocity of the body. Positive values move the body down, while negative values move it up. - * - * @return {this} This Game Object. - */ - setVelocity: function (x, y) + // intersectTest is a function with parameters: shape, rect + var intersectTest = NOOP; + + if (shape instanceof Geom.Circle) { - this.body.setVelocity(x, y); + intersectTest = Intersects.CircleToRectangle; + } + else if (shape instanceof Geom.Rectangle) + { + intersectTest = Intersects.RectangleToRectangle; + } + else if (shape instanceof Geom.Triangle) + { + intersectTest = TriangleToRectangle; + } + else if (shape instanceof Geom.Line) + { + intersectTest = Intersects.LineToRectangle; + } - return this; - }, + // Top left corner of the shapes's bounding box, rounded down to include partial tiles + layer.tilemapLayer.worldToTileXY(shape.left, shape.top, true, pointStart, camera); - /** - * Sets the horizontal component of the body's velocity. - * - * Positive values move the body to the right, while negative values move it to the left. - * - * @method Phaser.Physics.Arcade.Components.Velocity#setVelocityX - * @since 3.0.0 - * - * @param {number} x - The new horizontal velocity. - * - * @return {this} This Game Object. - */ - setVelocityX: function (x) - { - this.body.setVelocityX(x); + var xStart = pointStart.x; + var yStart = pointStart.y; - return this; - }, + // Bottom right corner of the shapes's bounding box, rounded up to include partial tiles + layer.tilemapLayer.worldToTileXY(shape.right, shape.bottom, false, pointEnd, camera); - /** - * Sets the vertical component of the body's velocity. - * - * Positive values move the body down, while negative values move it up. - * - * @method Phaser.Physics.Arcade.Components.Velocity#setVelocityY - * @since 3.0.0 - * - * @param {number} y - The new vertical velocity of the body. - * - * @return {this} This Game Object. - */ - setVelocityY: function (y) + var xEnd = Math.ceil(pointEnd.x); + var yEnd = Math.ceil(pointEnd.y); + + // Tiles within bounding rectangle of shape. Bounds are forced to be at least 1 x 1 tile in size + // to grab tiles for shapes that don't have a height or width (e.g. a horizontal line). + var width = Math.max(xEnd - xStart, 1); + var height = Math.max(yEnd - yStart, 1); + + var tiles = GetTilesWithin(xStart, yStart, width, height, filteringOptions, layer); + + var tileWidth = layer.tileWidth; + var tileHeight = layer.tileHeight; + + if (layer.tilemapLayer) { - this.body.setVelocityY(y); + tileWidth *= layer.tilemapLayer.scaleX; + tileHeight *= layer.tilemapLayer.scaleY; + } - return this; - }, + var results = []; + var tileRect = new Geom.Rectangle(0, 0, tileWidth, tileHeight); - /** - * Sets the maximum velocity of the body. - * - * @method Phaser.Physics.Arcade.Components.Velocity#setMaxVelocity - * @since 3.0.0 - * - * @param {number} x - The new maximum horizontal velocity. - * @param {number} [y=x] - The new maximum vertical velocity. - * - * @return {this} This Game Object. - */ - setMaxVelocity: function (x, y) + for (var i = 0; i < tiles.length; i++) { - this.body.maxVelocity.set(x, y); + var tile = tiles[i]; - return this; + layer.tilemapLayer.tileToWorldXY(tile.x, tile.y, point, camera); + + tileRect.x = point.x; + tileRect.y = point.y; + + if (intersectTest(shape, tileRect)) + { + results.push(tile); + } } + return results; }; -module.exports = Velocity; +module.exports = GetTilesWithinShape; + + +/***/ }), + +/***/ 44662: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTilesWithin = __webpack_require__(50811); +var Vector2 = __webpack_require__(93736); + +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; /***/ }), -/* 1381 */ -/***/ (function(module, exports) { + +/***/ 29296: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CONST = __webpack_require__(12920); +var NULL = __webpack_require__(10618); +var WorldToTileX = __webpack_require__(806); + /** - * The Arcade Physics World Collide Event. - * - * This event is dispatched by an Arcade Physics World instance if two bodies collide _and_ at least - * one of them has their [onCollide]{@link Phaser.Physics.Arcade.Body#onCollide} property set to `true`. - * - * It provides an alternative means to handling collide events rather than using the callback approach. - * - * Listen to it from a Scene using: `this.physics.world.on('collide', listener)`. - * - * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. + * Gets the correct function to use to translate tiles, based on the map orientation. * - * @event Phaser.Physics.Arcade.Events#COLLIDE - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject1 - The first Game Object involved in the collision. This is the parent of `body1`. - * @param {Phaser.GameObjects.GameObject} gameObject2 - The second Game Object involved in the collision. This is the parent of `body2`. - * @param {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody} body1 - The first Physics Body involved in the collision. - * @param {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody} body2 - The second Physics Body involved in the collision. + * Only orthogonal maps support this feature. + * + * @function Phaser.Tilemaps.Components.GetWorldToTileXFunction + * @since 3.50.0 + * + * @param {number} orientation - The Tilemap orientation constant. + * + * @return {function} The function to use to translate tiles for the given map type. */ -module.exports = 'collide'; +var GetWorldToTileXFunction = function (orientation) +{ + if (orientation === CONST.ORTHOGONAL) + { + return WorldToTileX; + } + else + { + return NULL; + } +}; + +module.exports = GetWorldToTileXFunction; /***/ }), -/* 1382 */ -/***/ (function(module, exports) { + +/***/ 32688: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CONST = __webpack_require__(12920); +var HexagonalWorldToTileXY = __webpack_require__(11516); +var IsometricWorldToTileXY = __webpack_require__(18750); +var NOOP = __webpack_require__(72283); +var StaggeredWorldToTileXY = __webpack_require__(90562); +var WorldToTileXY = __webpack_require__(45676); + /** - * The Arcade Physics World Overlap Event. - * - * This event is dispatched by an Arcade Physics World instance if two bodies overlap _and_ at least - * one of them has their [onOverlap]{@link Phaser.Physics.Arcade.Body#onOverlap} property set to `true`. - * - * It provides an alternative means to handling overlap events rather than using the callback approach. - * - * Listen to it from a Scene using: `this.physics.world.on('overlap', listener)`. - * - * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. + * Gets the correct function to use to translate tiles, based on the map orientation. * - * @event Phaser.Physics.Arcade.Events#OVERLAP - * @since 3.0.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject1 - The first Game Object involved in the overlap. This is the parent of `body1`. - * @param {Phaser.GameObjects.GameObject} gameObject2 - The second Game Object involved in the overlap. This is the parent of `body2`. - * @param {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody} body1 - The first Physics Body involved in the overlap. - * @param {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody} body2 - The second Physics Body involved in the overlap. + * @function Phaser.Tilemaps.Components.GetWorldToTileXYFunction + * @since 3.50.0 + * + * @param {number} orientation - The Tilemap orientation constant. + * + * @return {function} The function to use to translate tiles for the given map type. */ -module.exports = 'overlap'; +var GetWorldToTileXYFunction = function (orientation) +{ + if (orientation === CONST.ORTHOGONAL) + { + return WorldToTileXY; + } + else if (orientation === CONST.ISOMETRIC) + { + return IsometricWorldToTileXY; + } + else if (orientation === CONST.HEXAGONAL) + { + return HexagonalWorldToTileXY; + } + else if (orientation === CONST.STAGGERED) + { + return StaggeredWorldToTileXY; + } + else + { + return NOOP; + } +}; + +module.exports = GetWorldToTileXYFunction; /***/ }), -/* 1383 */ -/***/ (function(module, exports) { + +/***/ 74326: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CONST = __webpack_require__(12920); +var NULL = __webpack_require__(10618); +var StaggeredWorldToTileY = __webpack_require__(3689); +var WorldToTileY = __webpack_require__(70520); + /** - * The Arcade Physics World Pause Event. - * - * This event is dispatched by an Arcade Physics World instance when it is paused. - * - * Listen to it from a Scene using: `this.physics.world.on('pause', listener)`. + * Gets the correct function to use to translate tiles, based on the map orientation. * - * @event Phaser.Physics.Arcade.Events#PAUSE - * @since 3.0.0 + * @function Phaser.Tilemaps.Components.GetWorldToTileYFunction + * @since 3.50.0 + * + * @param {number} orientation - The Tilemap orientation constant. + * + * @return {function} The function to use to translate tiles for the given map type. */ -module.exports = 'pause'; +var GetWorldToTileYFunction = function (orientation) +{ + if (orientation === CONST.ORTHOGONAL) + { + return WorldToTileY; + } + else if (orientation === CONST.STAGGERED) + { + return StaggeredWorldToTileY; + } + else + { + return NULL; + } +}; + +module.exports = GetWorldToTileYFunction; /***/ }), -/* 1384 */ -/***/ (function(module, exports) { + +/***/ 46598: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var IsInLayerBounds = __webpack_require__(62839); + /** - * The Arcade Physics World Resume Event. - * - * This event is dispatched by an Arcade Physics World instance when it resumes from a paused state. - * - * Listen to it from a Scene using: `this.physics.world.on('resume', listener)`. + * 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. * - * @event Phaser.Physics.Arcade.Events#RESUME + * @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. */ -module.exports = 'resume'; +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; /***/ }), -/* 1385 */ -/***/ (function(module, exports) { + +/***/ 28654: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var HasTileAt = __webpack_require__(46598); +var Vector2 = __webpack_require__(93736); + +var point = new Vector2(); + /** - * The Arcade Physics Tile Collide Event. - * - * This event is dispatched by an Arcade Physics World instance if a body collides with a Tile _and_ - * has its [onCollide]{@link Phaser.Physics.Arcade.Body#onCollide} property set to `true`. - * - * It provides an alternative means to handling collide events rather than using the callback approach. - * - * Listen to it from a Scene using: `this.physics.world.on('tilecollide', listener)`. - * - * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. + * 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. * - * @event Phaser.Physics.Arcade.Events#TILE_COLLIDE - * @since 3.16.1 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object involved in the collision. This is the parent of `body`. - * @param {Phaser.Tilemaps.Tile} tile - The tile the body collided with. - * @param {Phaser.Physics.Arcade.Body} body - The Arcade Physics Body of the Game Object involved in the collision. + * @function Phaser.Tilemaps.Components.HasTileAtWorldXY + * @since 3.0.0 + * + * @param {number} worldX - The X coordinate of the world position. + * @param {number} worldY - The Y coordinate of the world position. + * @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 {?boolean} Returns a boolean, or null if the layer given was invalid. */ -module.exports = 'tilecollide'; +var HasTileAtWorldXY = function (worldX, worldY, camera, layer) +{ + layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera); + + var tileX = point.x; + var tileY = point.y; + + return HasTileAt(tileX, tileY, layer); +}; + +module.exports = HasTileAtWorldXY; /***/ }), -/* 1386 */ -/***/ (function(module, exports) { + +/***/ 6358: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var SnapCeil = __webpack_require__(82127); +var SnapFloor = __webpack_require__(84314); + /** - * The Arcade Physics Tile Overlap Event. - * - * This event is dispatched by an Arcade Physics World instance if a body overlaps with a Tile _and_ - * has its [onOverlap]{@link Phaser.Physics.Arcade.Body#onOverlap} property set to `true`. - * - * It provides an alternative means to handling overlap events rather than using the callback approach. - * - * Listen to it from a Scene using: `this.physics.world.on('tileoverlap', listener)`. - * - * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. + * Returns the bounds in the given layer that are within the camera's viewport. + * This is used internally by the cull tiles function. * - * @event Phaser.Physics.Arcade.Events#TILE_OVERLAP - * @since 3.16.1 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object involved in the overlap. This is the parent of `body`. - * @param {Phaser.Tilemaps.Tile} tile - The tile the body overlapped. - * @param {Phaser.Physics.Arcade.Body} body - The Arcade Physics Body of the Game Object involved in the overlap. + * @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. */ -module.exports = 'tileoverlap'; +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); -/***/ }), -/* 1387 */ -/***/ (function(module, exports) { + var len = layer.hexSideLength; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var boundsLeft; + var boundsRight; + var boundsTop; + var boundsBottom; -/** - * The Arcade Physics World Bounds Event. - * - * This event is dispatched by an Arcade Physics World instance if a body makes contact with the world bounds _and_ - * it has its [onWorldBounds]{@link Phaser.Physics.Arcade.Body#onWorldBounds} property set to `true`. - * - * It provides an alternative means to handling collide events rather than using the callback approach. - * - * Listen to it from a Scene using: `this.physics.world.on('worldbounds', listener)`. - * - * @event Phaser.Physics.Arcade.Events#WORLD_BOUNDS - * @since 3.0.0 - * - * @param {Phaser.Physics.Arcade.Body} body - The Arcade Physics Body that hit the world bounds. - * @param {boolean} up - Is the Body blocked up? I.e. collided with the top of the world bounds. - * @param {boolean} down - Is the Body blocked down? I.e. collided with the bottom of the world bounds. - * @param {boolean} left - Is the Body blocked left? I.e. collided with the left of the world bounds. - * @param {boolean} right - Is the Body blocked right? I.e. collided with the right of the world bounds. - */ -module.exports = 'worldbounds'; + if (this.staggerAxis === 'y') + { + var rowH = ((tileH - len) / 2 + len); + + boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX; + boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX; + + boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, rowH, 0, true) - tilemapLayer.cullPaddingY; + boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, rowH, 0, true) + tilemapLayer.cullPaddingY; + } + else + { + var rowW = ((tileW - len) / 2 + len); + + boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, rowW, 0, true) - tilemapLayer.cullPaddingX; + boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, rowW, 0, true) + tilemapLayer.cullPaddingX; + + boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH, 0, true) - tilemapLayer.cullPaddingY; + boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH, 0, true) + tilemapLayer.cullPaddingY; + } + + return { + left: boundsLeft, + right: boundsRight, + top: boundsTop, + bottom: boundsBottom + }; +}; + +module.exports = HexagonalCullBounds; /***/ }), -/* 1388 */ -/***/ (function(module, exports) { + +/***/ 37524: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var CullBounds = __webpack_require__(6358); +var RunCull = __webpack_require__(6987); + /** - * The Arcade Physics World Step Event. - * - * This event is dispatched by an Arcade Physics World instance whenever a physics step is run. - * It is emitted _after_ the bodies and colliders have been updated. - * - * In high framerate settings this can be multiple times per game frame. + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. * - * Listen to it from a Scene using: `this.physics.world.on('worldstep', listener)`. + * @function Phaser.Tilemaps.Components.HexagonalCullTiles + * @since 3.50.0 * - * @event Phaser.Physics.Arcade.Events#WORLD_STEP - * @since 3.18.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. * - * @param {number} delta - The delta time amount of this step, in seconds. + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. */ -module.exports = 'worldstep'; +var HexagonalCullTiles = 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 = HexagonalCullTiles; /***/ }), -/* 1389 */ -/***/ (function(module, exports) { + +/***/ 63634: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var body1; -var body2; -var body1Pushable; -var body2Pushable; -var body1MassImpact; -var body2MassImpact; -var body1FullImpact; -var body2FullImpact; -var body1MovingLeft; -var body1MovingRight; -var body1Stationary; -var body2MovingLeft; -var body2MovingRight; -var body2Stationary; -var body1OnLeft; -var body2OnLeft; -var overlap; +var HexagonalTileToWorldXY = __webpack_require__(21715); +var Vector2 = __webpack_require__(93736); + +var tempVec = new Vector2(); /** - * Sets all of the local processing values and calculates the velocity exchanges. - * - * Then runs `BlockCheck` and returns the value from it. - * - * This method is called by `Phaser.Physics.Arcade.SeparateX` and should not be - * called directly. + * Gets the corners of the Hexagonal Tile as an array of Vector2s. * - * @function Phaser.Physics.Arcade.ProcessX.Set - * @ignore - * @since 3.50.0 + * @function Phaser.Tilemaps.Components.HexagonalGetTileCorners + * @since 3.60.0 * - * @param {Phaser.Physics.Arcade.Body} b1 - The first Body to separate. - * @param {Phaser.Physics.Arcade.Body} b2 - The second Body to separate. - * @param {number} ov - The overlap value. + * @param {number} tileX - The x coordinate, in tiles, not pixels. + * @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 BlockCheck result. 0 = not blocked. 1 = Body 1 blocked. 2 = Body 2 blocked. + * @return {Phaser.Math.Vector2[]} An array of Vector2s corresponding to the world XY location of each tile corner. */ -var Set = function (b1, b2, ov) +var HexagonalGetTileCorners = function (tileX, tileY, camera, layer) { - body1 = b1; - body2 = b2; + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; - var v1 = body1.velocity.x; - var v2 = body2.velocity.x; + if (tilemapLayer) + { + tileWidth *= tilemapLayer.scaleX; + tileHeight *= tilemapLayer.scaleY; + } - body1Pushable = body1.pushable; - body1MovingLeft = body1._dx < 0; - body1MovingRight = body1._dx > 0; - body1Stationary = body1._dx === 0; - body1OnLeft = Math.abs(body1.right - body2.x) <= Math.abs(body2.right - body1.x); - body1FullImpact = v2 - v1 * body1.bounce.x; + // Sets the center of the tile into tempVec + var center = HexagonalTileToWorldXY(tileX, tileY, tempVec, camera, layer); - body2Pushable = body2.pushable; - body2MovingLeft = body2._dx < 0; - body2MovingRight = body2._dx > 0; - body2Stationary = body2._dx === 0; - body2OnLeft = !body1OnLeft; - body2FullImpact = v1 - v2 * body2.bounce.x; + var corners = []; - // negative delta = up, positive delta = down (inc. gravity) - overlap = Math.abs(ov); + // Hard-coded orientation values for Pointy-Top Hexagons only + var b0 = 0.5773502691896257; // Math.sqrt(3) / 3 - return BlockCheck(); + var hexWidth; + var hexHeight; + + if (this.staggerAxis === 'y') + { + hexWidth = b0 * tileWidth; + hexHeight = tileHeight / 2; + } + else + { + hexWidth = tileWidth / 2; + hexHeight = b0 * tileHeight; + } + + for (var i = 0; i < 6; i++) + { + var angle = 2 * Math.PI * (0.5 - i) / 6; + + corners.push(new Vector2(center.x + (hexWidth * Math.cos(angle)), center.y + (hexHeight * Math.sin(angle)))); + } + + return corners; }; +module.exports = HexagonalGetTileCorners; + + +/***/ }), + +/***/ 21715: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + /** - * Blocked Direction checks, because it doesn't matter if an object can be pushed - * or not, blocked is blocked. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(93736); + +/** + * 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.Physics.Arcade.ProcessX.BlockCheck - * @ignore + * @function Phaser.Tilemaps.Components.HexagonalTileToWorldXY * @since 3.50.0 * - * @return {number} The BlockCheck result. 0 = not blocked. 1 = Body 1 blocked. 2 = Body 2 blocked. + * @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 BlockCheck = function () +var HexagonalTileToWorldXY = function (tileX, tileY, point, camera, layer) { - // Body1 is moving right and Body2 is blocked from going right any further - if (body1MovingRight && body1OnLeft && body2.blocked.right) - { - body1.processX(-overlap, body1FullImpact, false, true); + if (!point) { point = new Vector2(); } - return 1; - } + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; - // Body1 is moving up and Body2 is blocked from going up any further - if (body1MovingLeft && body2OnLeft && body2.blocked.left) + var worldX = 0; + var worldY = 0; + + if (tilemapLayer) { - body1.processX(overlap, body1FullImpact, true); + if (!camera) { camera = tilemapLayer.scene.cameras.main; } - return 1; + worldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + worldY = tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY); + + tileWidth *= tilemapLayer.scaleX; + tileHeight *= tilemapLayer.scaleY; } - // Body2 is moving right and Body1 is blocked from going right any further - if (body2MovingRight && body2OnLeft && body1.blocked.right) + // Hard-coded orientation values for Pointy-Top Hexagons only + + // origin + var tileWidthHalf = tileWidth / 2; + var tileHeightHalf = tileHeight / 2; + + var x; + var y; + + if (this.staggerAxis === 'y') { - body2.processX(-overlap, body2FullImpact, false, true); + x = worldX + (tileWidth * tileX) + tileWidth; + y = worldY + ((1.5 * tileY) * tileHeightHalf) + tileHeightHalf; - return 2; + if (tileY % 2 === 0) + { + if (this.staggerIndex === 'odd') + { + x -= tileWidthHalf; + } + else + { + x += tileWidthHalf; + } + } } - - // Body2 is moving up and Body1 is blocked from going up any further - if (body2MovingLeft && body1OnLeft && body1.blocked.left) + else if ((this.staggerAxis === 'x') && (this.staggerIndex === 'odd')) { - body2.processX(overlap, body2FullImpact, true); + x = worldX + ((1.5 * tileX) * tileWidthHalf) + tileWidthHalf; + y = worldY + (tileHeight * tileX) + tileHeight; - return 2; + if (tileX % 2 === 0) + { + if (this.staggerIndex === 'odd') + { + y -= tileHeightHalf; + } + else + { + y += tileHeightHalf; + } + } } - return 0; + return point.set(x, y); }; +module.exports = HexagonalTileToWorldXY; + + +/***/ }), + +/***/ 11516: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + /** - * The main check function. Runs through one of the four possible tests and returns the results. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(93736); + +/** + * 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.Physics.Arcade.ProcessX.Check - * @ignore + * @function Phaser.Tilemaps.Components.HexagonalWorldToTileXY * @since 3.50.0 * - * @return {boolean} `true` if a check passed, otherwise `false`. + * @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 Check = function () +var HexagonalWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) { - var v1 = body1.velocity.x; - var v2 = body2.velocity.x; + if (!point) { point = new Vector2(); } - var nv1 = Math.sqrt((v2 * v2 * body2.mass) / body1.mass) * ((v2 > 0) ? 1 : -1); - var nv2 = Math.sqrt((v1 * v1 * body1.mass) / body2.mass) * ((v1 > 0) ? 1 : -1); - var avg = (nv1 + nv2) * 0.5; + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; - nv1 -= avg; - nv2 -= avg; + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } - body1MassImpact = avg + nv1 * body1.bounce.x; - body2MassImpact = avg + nv2 * body2.bounce.x; + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll - // Body1 hits Body2 on the right hand side - if (body1MovingLeft && body2OnLeft) - { - return Run(0); + worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileWidth *= tilemapLayer.scaleX; + tileHeight *= tilemapLayer.scaleY; } - // Body2 hits Body1 on the right hand side - if (body2MovingLeft && body1OnLeft) + // Hard-coded orientation values for Pointy-Top Hexagons only + var b0 = 0.5773502691896257; // Math.sqrt(3) / 3 + var b1 = -0.3333333333333333; // -1 / 3 + var b2 = 0; + var b3 = 0.6666666666666666; // 2 / 3 + + // origin + var tileWidthHalf = tileWidth / 2; + var tileHeightHalf = tileHeight / 2; + + var px; + var py; + var q; + var r; + var s; + + // size + if (layer.staggerAxis === 'y') { - return Run(1); + // x = b0 * tileWidth + // y = tileHeightHalf + px = (worldX - tileWidthHalf) / (b0 * tileWidth); + py = (worldY - tileHeightHalf) / tileHeightHalf; + + q = b0 * px + b1 * py; + r = b2 * px + b3 * py; + } + else + { + // x = tileWidthHalf + // y = b0 * tileHeight + px = (worldX - tileWidthHalf) / tileWidthHalf; + py = (worldY - tileHeightHalf) / (b0 * tileHeight); + + q = b1 * px + b0 * py; + r = b3 * px + b2 * py; } - // Body1 hits Body2 on the left hand side - if (body1MovingRight && body1OnLeft) + s = -q - r; + + var qi = Math.round(q); + var ri = Math.round(r); + var si = Math.round(s); + + var qDiff = Math.abs(qi - q); + var rDiff = Math.abs(ri - r); + var sDiff = Math.abs(si - s); + + if (qDiff > rDiff && qDiff > sDiff) { - return Run(2); + qi = -ri - si; + } + else if (rDiff > sDiff) + { + ri = -qi - si; } - // Body2 hits Body1 on the left hand side - if (body2MovingRight && body2OnLeft) + var x; + var y = ri; + + if (layer.staggerIndex === 'odd') { - return Run(3); + x = (y % 2 === 0) ? (ri / 2) + qi : (ri / 2) + qi - 0.5; + } + else + { + x = (y % 2 === 0) ? (ri / 2) + qi : (ri / 2) + qi + 0.5; } - return false; + return point.set(x, y); +}; + +module.exports = HexagonalWorldToTileXY; + + +/***/ }), + +/***/ 62839: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks if the given tile coordinates are within the bounds of the layer. + * + * @function Phaser.Tilemaps.Components.IsInLayerBounds + * @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.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {boolean} `true` if the tile coordinates are within the bounds of the layer, otherwise `false`. + */ +var IsInLayerBounds = function (tileX, tileY, layer) +{ + return (tileX >= 0 && tileX < layer.width && tileY >= 0 && tileY < layer.height); }; +module.exports = IsInLayerBounds; + + +/***/ }), + +/***/ 20887: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + /** - * The main check function. Runs through one of the four possible tests and returns the results. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CheckIsoBounds = __webpack_require__(13125); + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. * - * @function Phaser.Physics.Arcade.ProcessX.Run - * @ignore + * @function Phaser.Tilemaps.Components.IsometricCullTiles * @since 3.50.0 * - * @param {number} side - The side to test. As passed in by the `Check` function. + * @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 {boolean} Always returns `true`. + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. */ -var Run = function (side) +var IsometricCullTiles = function (layer, camera, outputArray, renderOrder) { - if (body1Pushable && body2Pushable) - { - // Both pushable, or both moving at the same time, so equal rebound - overlap *= 0.5; + if (outputArray === undefined) { outputArray = []; } + if (renderOrder === undefined) { renderOrder = 0; } - if (side === 0 || side === 3) - { - // body1MovingLeft && body2OnLeft - // body2MovingRight && body2OnLeft - body1.processX(overlap, body1MassImpact); - body2.processX(-overlap, body2MassImpact); - } - else - { - // body2MovingLeft && body1OnLeft - // body1MovingRight && body1OnLeft - body1.processX(-overlap, body1MassImpact); - body2.processX(overlap, body2MassImpact); - } - } - else if (body1Pushable && !body2Pushable) + outputArray.length = 0; + + var tilemapLayer = layer.tilemapLayer; + + var mapData = layer.data; + var mapWidth = layer.width; + var mapHeight = layer.height; + var skipCull = tilemapLayer.skipCull; + + var drawLeft = 0; + var drawRight = mapWidth; + var drawTop = 0; + var drawBottom = mapHeight; + + var x; + var y; + var tile; + + if (renderOrder === 0) { - // Body1 pushable, Body2 not + // right-down - if (side === 0 || side === 3) - { - // body1MovingLeft && body2OnLeft - // body2MovingRight && body2OnLeft - body1.processX(overlap, body1FullImpact, true); - } - else + for (y = drawTop; y < drawBottom; y++) { - // body2MovingLeft && body1OnLeft - // body1MovingRight && body1OnLeft - body1.processX(-overlap, body1FullImpact, false, true); + for (x = drawLeft; x < drawRight; x++) + { + if (skipCull || 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 (!body1Pushable && body2Pushable) + else if (renderOrder === 1) { - // Body2 pushable, Body1 not + // left-down - if (side === 0 || side === 3) - { - // body1MovingLeft && body2OnLeft - // body2MovingRight && body2OnLeft - body2.processX(-overlap, body2FullImpact, false, true); - } - else + for (y = drawTop; y < drawBottom; y++) { - // body2MovingLeft && body1OnLeft - // body1MovingRight && body1OnLeft - body2.processX(overlap, body2FullImpact, true); + for (x = drawRight; x >= drawLeft; x--) + { + if (skipCull || CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } } } - else + else if (renderOrder === 2) { - // Neither body is pushable, so base it on movement - - var halfOverlap = overlap * 0.5; + // right-up - if (side === 0) + for (y = drawBottom; y >= drawTop; y--) { - // body1MovingLeft && body2OnLeft - - if (body2Stationary) - { - body1.processX(overlap, 0, true); - body2.processX(0, null, false, true); - } - else if (body2MovingRight) - { - body1.processX(halfOverlap, 0, true); - body2.processX(-halfOverlap, 0, false, true); - } - else + for (x = drawLeft; x < drawRight; x++) { - // Body2 moving same direction as Body1 - body1.processX(halfOverlap, body2.velocity.x, true); - body2.processX(-halfOverlap, null, false, true); - } - } - else if (side === 1) - { - // body2MovingLeft && body1OnLeft + if (skipCull || CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; - if (body1Stationary) - { - body1.processX(0, null, false, true); - body2.processX(overlap, 0, true); - } - else if (body1MovingRight) - { - body1.processX(-halfOverlap, 0, false, true); - body2.processX(halfOverlap, 0, true); - } - else - { - // Body1 moving same direction as Body2 - body1.processX(-halfOverlap, null, false, true); - body2.processX(halfOverlap, body1.velocity.x, true); - } - } - else if (side === 2) - { - // body1MovingRight && body1OnLeft + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } - if (body2Stationary) - { - body1.processX(-overlap, 0, false, true); - body2.processX(0, null, true); - } - else if (body2MovingLeft) - { - body1.processX(-halfOverlap, 0, false, true); - body2.processX(halfOverlap, 0, true); - } - else - { - // Body2 moving same direction as Body1 - body1.processX(-halfOverlap, body2.velocity.x, false, true); - body2.processX(halfOverlap, null, true); + outputArray.push(tile); + } } } - else if (side === 3) - { - // body2MovingRight && body2OnLeft + } + else if (renderOrder === 3) + { + // left-up - if (body1Stationary) - { - body1.processX(0, null, true); - body2.processX(-overlap, 0, false, true); - } - else if (body1MovingLeft) - { - body1.processX(halfOverlap, 0, true); - body2.processX(-halfOverlap, 0, false, true); - } - else + for (y = drawBottom; y >= drawTop; y--) + { + for (x = drawRight; x >= drawLeft; x--) { - // Body1 moving same direction as Body2 - body1.processX(halfOverlap, body2.velocity.y, true); - body2.processX(-halfOverlap, null, false, true); + if (skipCull || CheckIsoBounds(x, y, layer, camera)) + { + tile = mapData[y][x]; + + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } } } } - return true; + tilemapLayer.tilesDrawn = outputArray.length; + tilemapLayer.tilesTotal = mapWidth * mapHeight; + + return outputArray; }; +module.exports = IsometricCullTiles; + + +/***/ }), + +/***/ 21808: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + /** - * This function is run when Body1 is Immovable and Body2 is not. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(93736); + +/** + * 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.Physics.Arcade.ProcessX.RunImmovableBody1 - * @ignore + * @function Phaser.Tilemaps.Components.IsometricTileToWorldXY * @since 3.50.0 * - * @param {number} blockedState - The block state value. + * @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 RunImmovableBody1 = function (blockedState) +var IsometricTileToWorldXY = function (tileX, tileY, point, camera, layer) { - if (blockedState === 1) + 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) { - // But Body2 cannot go anywhere either, so we cancel out velocity - // Separation happened in the block check - body2.velocity.x = 0; + 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; } - else if (body1OnLeft) + + var x = layerWorldX + (tileX - tileY) * (tileWidth / 2); + var y = layerWorldY + (tileX + tileY) * (tileHeight / 2); + + return point.set(x, y); +}; + +module.exports = IsometricTileToWorldXY; + + +/***/ }), + +/***/ 18750: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = __webpack_require__(93736); + +/** + * Converts from world XY coordinates (pixels) to isometric 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. + * + * @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. + * @param {boolean} [originTop=true] - Which is the active face of the isometric tile? The top (default, true), or the base? (false) + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var IsometricWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer, originTop) +{ + if (!point) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) { - body2.processX(overlap, body2FullImpact, true); + 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; } - else + + var tileWidthHalf = tileWidth / 2; + var tileHeightHalf = tileHeight / 2; + + worldX = worldX - tileWidthHalf; + + if (!originTop) { - body2.processX(-overlap, body2FullImpact, false, true); + worldY = worldY - tileHeight; } - // This is special case code that handles things like vertically moving platforms you can ride - if (body1.moves) + var x = 0.5 * (worldX / tileWidthHalf + worldY / tileHeightHalf); + var y = 0.5 * (-worldX / tileWidthHalf + worldY / tileHeightHalf); + + if (snapToFloor) { - body2.y += (body1.y - body1.prev.y) * body1.friction.y; - body2._dy = body2.y - body2.prev.y; + x = Math.floor(x); + y = Math.floor(y); } + + return point.set(x, y); }; +module.exports = IsometricWorldToTileXY; + + +/***/ }), + +/***/ 29003: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + /** - * This function is run when Body2 is Immovable and Body1 is not. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Tile = __webpack_require__(29633); +var IsInLayerBounds = __webpack_require__(62839); +var CalculateFacesAt = __webpack_require__(92839); +var SetTileCollision = __webpack_require__(68234); + +/** + * 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. * - * @function Phaser.Physics.Arcade.ProcessX.RunImmovableBody2 - * @ignore - * @since 3.50.0 + * @function Phaser.Tilemaps.Components.PutTileAt + * @since 3.0.0 * - * @param {number} blockedState - The block state value. + * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Tilemaps.Tile} The Tile object that was created or added to this map. */ -var RunImmovableBody2 = function (blockedState) +var PutTileAt = function (tile, tileX, tileY, recalculateFaces, layer) { - if (blockedState === 2) + if (recalculateFaces === undefined) { recalculateFaces = true; } + + if (!IsInLayerBounds(tileX, tileY, layer)) { - // But Body1 cannot go anywhere either, so we cancel out velocity - // Separation happened in the block check - body1.velocity.x = 0; + return null; } - else if (body2OnLeft) + + var index; + var oldTile = layer.data[tileY][tileX]; + var oldTileCollides = oldTile && oldTile.collides; + + if (tile instanceof Tile) { - body1.processX(overlap, body1FullImpact, true); + if (layer.data[tileY][tileX] === null) + { + layer.data[tileY][tileX] = new Tile(layer, tile.index, tileX, tileY, layer.tileWidth, layer.tileHeight); + } + + layer.data[tileY][tileX].copy(tile); } else { - body1.processX(-overlap, body1FullImpact, false, true); + index = tile; + + if (layer.data[tileY][tileX] === null) + { + layer.data[tileY][tileX] = new Tile(layer, index, tileX, tileY, layer.tileWidth, layer.tileHeight); + } + else + { + layer.data[tileY][tileX].index = index; + } } - // This is special case code that handles things like vertically moving platforms you can ride - if (body2.moves) + // Updating colliding flag on the new tile + var newTile = layer.data[tileY][tileX]; + var collides = layer.collideIndexes.indexOf(newTile.index) !== -1; + + index = tile instanceof Tile ? tile.index : tile; + + if (index === -1) + { + newTile.width = layer.tileWidth; + newTile.height = layer.tileHeight; + } + else + { + var tiles = layer.tilemapLayer.tilemap.tiles; + var sid = tiles[index][2]; + var set = layer.tilemapLayer.tileset[sid]; + + newTile.width = set.tileWidth; + newTile.height = set.tileHeight; + } + + SetTileCollision(newTile, collides); + + // Recalculate faces only if the colliding flag at (tileX, tileY) has changed + if (recalculateFaces && (oldTileCollides !== newTile.collides)) { - body1.y += (body2.y - body2.prev.y) * body2.friction.y; - body1._dy = body1.y - body1.prev.y; + CalculateFacesAt(tileX, tileY, layer); } -}; - -/** - * @namespace Phaser.Physics.Arcade.ProcessX - * @ignore - */ -module.exports = { - BlockCheck: BlockCheck, - Check: Check, - Set: Set, - Run: Run, - RunImmovableBody1: RunImmovableBody1, - RunImmovableBody2: RunImmovableBody2 + return newTile; }; +module.exports = PutTileAt; + /***/ }), -/* 1390 */ -/***/ (function(module, exports) { + +/***/ 48565: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var body1; -var body2; -var body1Pushable; -var body2Pushable; -var body1MassImpact; -var body2MassImpact; -var body1FullImpact; -var body2FullImpact; -var body1MovingUp; -var body1MovingDown; -var body1Stationary; -var body2MovingUp; -var body2MovingDown; -var body2Stationary; -var body1OnTop; -var body2OnTop; -var overlap; +var PutTileAt = __webpack_require__(29003); +var Vector2 = __webpack_require__(93736); + +var point = new Vector2(); /** - * Sets all of the local processing values and calculates the velocity exchanges. - * - * Then runs `BlockCheck` and returns the value from it. - * - * This method is called by `Phaser.Physics.Arcade.SeparateY` and should not be - * called directly. + * 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. * - * @function Phaser.Physics.Arcade.ProcessY.Set - * @ignore - * @since 3.50.0 + * @function Phaser.Tilemaps.Components.PutTileAtWorldXY + * @since 3.0.0 * - * @param {Phaser.Physics.Arcade.Body} b1 - The first Body to separate. - * @param {Phaser.Physics.Arcade.Body} b2 - The second Body to separate. - * @param {number} ov - The overlap value. + * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. * - * @return {number} The BlockCheck result. 0 = not blocked. 1 = Body 1 blocked. 2 = Body 2 blocked. + * @return {Phaser.Tilemaps.Tile} The Tile object that was created or added to this map. */ -var Set = function (b1, b2, ov) +var PutTileAtWorldXY = function (tile, worldX, worldY, recalculateFaces, camera, layer) { - body1 = b1; - body2 = b2; + layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera, layer); - var v1 = body1.velocity.y; - var v2 = body2.velocity.y; + return PutTileAt(tile, point.x, point.y, recalculateFaces, layer); +}; - body1Pushable = body1.pushable; - body1MovingUp = body1._dy < 0; - body1MovingDown = body1._dy > 0; - body1Stationary = body1._dy === 0; - body1OnTop = Math.abs(body1.bottom - body2.y) <= Math.abs(body2.bottom - body1.y); - body1FullImpact = v2 - v1 * body1.bounce.y; +module.exports = PutTileAtWorldXY; - body2Pushable = body2.pushable; - body2MovingUp = body2._dy < 0; - body2MovingDown = body2._dy > 0; - body2Stationary = body2._dy === 0; - body2OnTop = !body1OnTop; - body2FullImpact = v1 - v2 * body2.bounce.y; - // negative delta = up, positive delta = down (inc. gravity) - overlap = Math.abs(ov); +/***/ }), - return BlockCheck(); -}; +/***/ 56547: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Blocked Direction checks, because it doesn't matter if an object can be pushed - * or not, blocked is blocked. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var CalculateFacesWithin = __webpack_require__(60386); +var PutTileAt = __webpack_require__(29003); + +/** + * 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. * - * @function Phaser.Physics.Arcade.ProcessY.BlockCheck - * @ignore - * @since 3.50.0 + * @function Phaser.Tilemaps.Components.PutTilesAt + * @since 3.0.0 * - * @return {number} The BlockCheck result. 0 = not blocked. 1 = Body 1 blocked. 2 = Body 2 blocked. + * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -var BlockCheck = function () +var PutTilesAt = function (tilesArray, tileX, tileY, recalculateFaces, layer) { - // Body1 is moving down and Body2 is blocked from going down any further - if (body1MovingDown && body1OnTop && body2.blocked.down) - { - body1.processY(-overlap, body1FullImpact, false, true); + if (recalculateFaces === undefined) { recalculateFaces = true; } - return 1; + if (!Array.isArray(tilesArray)) + { + return null; } - // Body1 is moving up and Body2 is blocked from going up any further - if (body1MovingUp && body2OnTop && body2.blocked.up) + // Force the input array to be a 2D array + if (!Array.isArray(tilesArray[0])) { - body1.processY(overlap, body1FullImpact, true); - - return 1; + tilesArray = [ tilesArray ]; } - // Body2 is moving down and Body1 is blocked from going down any further - if (body2MovingDown && body2OnTop && body1.blocked.down) + var height = tilesArray.length; + var width = tilesArray[0].length; + + for (var ty = 0; ty < height; ty++) { - body2.processY(-overlap, body2FullImpact, false, true); + for (var tx = 0; tx < width; tx++) + { + var tile = tilesArray[ty][tx]; - return 2; + PutTileAt(tile, tileX + tx, tileY + ty, false, layer); + } } - // Body2 is moving up and Body1 is blocked from going up any further - if (body2MovingUp && body1OnTop && body1.blocked.up) + if (recalculateFaces) { - body2.processY(overlap, body2FullImpact, true); - - return 2; + // Recalculate the faces within the destination area and neighboring tiles + CalculateFacesWithin(tileX - 1, tileY - 1, width + 2, height + 2, layer); } - - return 0; }; -/** - * The main check function. Runs through one of the four possible tests and returns the results. - * - * @function Phaser.Physics.Arcade.ProcessY.Check - * @ignore - * @since 3.50.0 - * - * @return {boolean} `true` if a check passed, otherwise `false`. - */ -var Check = function () -{ - var v1 = body1.velocity.y; - var v2 = body2.velocity.y; - - var nv1 = Math.sqrt((v2 * v2 * body2.mass) / body1.mass) * ((v2 > 0) ? 1 : -1); - var nv2 = Math.sqrt((v1 * v1 * body1.mass) / body2.mass) * ((v1 > 0) ? 1 : -1); - var avg = (nv1 + nv2) * 0.5; - - nv1 -= avg; - nv2 -= avg; - - body1MassImpact = avg + nv1 * body1.bounce.y; - body2MassImpact = avg + nv2 * body2.bounce.y; +module.exports = PutTilesAt; - // Body1 hits Body2 on the bottom side - if (body1MovingUp && body2OnTop) - { - return Run(0); - } - // Body2 hits Body1 on the bottom side - if (body2MovingUp && body1OnTop) - { - return Run(1); - } +/***/ }), - // Body1 hits Body2 on the top side - if (body1MovingDown && body1OnTop) - { - return Run(2); - } +/***/ 91180: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Body2 hits Body1 on the top side - if (body2MovingDown && body2OnTop) - { - return Run(3); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return false; -}; +var GetTilesWithin = __webpack_require__(50811); +var GetRandom = __webpack_require__(72861); /** - * The main check function. Runs through one of the four possible tests and returns the results. - * - * @function Phaser.Physics.Arcade.ProcessY.Run - * @ignore - * @since 3.50.0 + * 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. * - * @param {number} side - The side to test. As passed in by the `Check` function. + * @function Phaser.Tilemaps.Components.Randomize + * @since 3.0.0 * - * @return {boolean} Always returns `true`. + * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -var Run = function (side) +var Randomize = function (tileX, tileY, width, height, indexes, layer) { - if (body1Pushable && body2Pushable) - { - // Both pushable, or both moving at the same time, so equal rebound - overlap *= 0.5; + var i; + var tiles = GetTilesWithin(tileX, tileY, width, height, {}, layer); - if (side === 0 || side === 3) - { - // body1MovingUp && body2OnTop - // body2MovingDown && body2OnTop - body1.processY(overlap, body1MassImpact); - body2.processY(-overlap, body2MassImpact); - } - else - { - // body2MovingUp && body1OnTop - // body1MovingDown && body1OnTop - body1.processY(-overlap, body1MassImpact); - body2.processY(overlap, body2MassImpact); - } - } - else if (body1Pushable && !body2Pushable) + // If no indices are given, then find all the unique indexes within the specified region + if (!indexes) { - // Body1 pushable, Body2 not + indexes = []; - if (side === 0 || side === 3) - { - // body1MovingUp && body2OnTop - // body2MovingDown && body2OnTop - body1.processY(overlap, body1FullImpact, true); - } - else + for (i = 0; i < tiles.length; i++) { - // body2MovingUp && body1OnTop - // body1MovingDown && body1OnTop - body1.processY(-overlap, body1FullImpact, false, true); + if (indexes.indexOf(tiles[i].index) === -1) + { + indexes.push(tiles[i].index); + } } } - else if (!body1Pushable && body2Pushable) - { - // Body2 pushable, Body1 not - if (side === 0 || side === 3) - { - // body1MovingUp && body2OnTop - // body2MovingDown && body2OnTop - body2.processY(-overlap, body2FullImpact, false, true); - } - else - { - // body2MovingUp && body1OnTop - // body1MovingDown && body1OnTop - body2.processY(overlap, body2FullImpact, true); - } - } - else + for (i = 0; i < tiles.length; i++) { - // Neither body is pushable, so base it on movement - - var halfOverlap = overlap * 0.5; - - if (side === 0) - { - // body1MovingUp && body2OnTop - - if (body2Stationary) - { - body1.processY(overlap, 0, true); - body2.processY(0, null, false, true); - } - else if (body2MovingDown) - { - body1.processY(halfOverlap, 0, true); - body2.processY(-halfOverlap, 0, false, true); - } - else - { - // Body2 moving same direction as Body1 - body1.processY(halfOverlap, body2.velocity.y, true); - body2.processY(-halfOverlap, null, false, true); - } - } - else if (side === 1) - { - // body2MovingUp && body1OnTop + tiles[i].index = GetRandom(indexes); + } +}; - if (body1Stationary) - { - body1.processY(0, null, false, true); - body2.processY(overlap, 0, true); - } - else if (body1MovingDown) - { - body1.processY(-halfOverlap, 0, false, true); - body2.processY(halfOverlap, 0, true); - } - else - { - // Body1 moving same direction as Body2 - body1.processY(-halfOverlap, null, false, true); - body2.processY(halfOverlap, body1.velocity.y, true); - } - } - else if (side === 2) - { - // body1MovingDown && body1OnTop +module.exports = Randomize; - if (body2Stationary) - { - body1.processY(-overlap, 0, false, true); - body2.processY(0, null, true); - } - else if (body2MovingUp) - { - body1.processY(-halfOverlap, 0, false, true); - body2.processY(halfOverlap, 0, true); - } - else - { - // Body2 moving same direction as Body1 - body1.processY(-halfOverlap, body2.velocity.y, false, true); - body2.processY(halfOverlap, null, true); - } - } - else if (side === 3) - { - // body2MovingDown && body2OnTop - if (body1Stationary) - { - body1.processY(0, null, true); - body2.processY(-overlap, 0, false, true); - } - else if (body1MovingUp) - { - body1.processY(halfOverlap, 0, true); - body2.processY(-halfOverlap, 0, false, true); - } - else - { - // Body1 moving same direction as Body2 - body1.processY(halfOverlap, body2.velocity.y, true); - body2.processY(-halfOverlap, null, false, true); - } - } - } +/***/ }), - return true; -}; +/***/ 929: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * This function is run when Body1 is Immovable and Body2 is not. - * - * @function Phaser.Physics.Arcade.ProcessY.RunImmovableBody1 - * @ignore - * @since 3.50.0 - * - * @param {number} blockedState - The block state value. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RunImmovableBody1 = function (blockedState) -{ - if (blockedState === 1) - { - // But Body2 cannot go anywhere either, so we cancel out velocity - // Separation happened in the block check - body2.velocity.y = 0; - } - else if (body1OnTop) - { - body2.processY(overlap, body2FullImpact, true); - } - else - { - body2.processY(-overlap, body2FullImpact, false, true); - } - // This is special case code that handles things like horizontally moving platforms you can ride - if (body1.moves) - { - body2.x += (body1.x - body1.prev.x) * body1.friction.x; - body2._dx = body2.x - body2.prev.x; - } -}; +var Tile = __webpack_require__(29633); +var IsInLayerBounds = __webpack_require__(62839); +var CalculateFacesAt = __webpack_require__(92839); /** - * This function is run when Body2 is Immovable and Body1 is not. + * Removes the tile at the given tile coordinates in the specified layer and updates the layer's + * collision information. * - * @function Phaser.Physics.Arcade.ProcessY.RunImmovableBody2 - * @ignore - * @since 3.50.0 + * @function Phaser.Tilemaps.Components.RemoveTileAt + * @since 3.0.0 * - * @param {number} blockedState - The block state value. + * @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 RunImmovableBody2 = function (blockedState) +var RemoveTileAt = function (tileX, tileY, replaceWithNull, recalculateFaces, layer) { - if (blockedState === 2) + if (replaceWithNull === undefined) { replaceWithNull = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + + if (!IsInLayerBounds(tileX, tileY, layer)) { - // But Body1 cannot go anywhere either, so we cancel out velocity - // Separation happened in the block check - body1.velocity.y = 0; + return null; } - else if (body2OnTop) + + var tile = layer.data[tileY][tileX]; + + if (!tile) { - body1.processY(overlap, body1FullImpact, true); + return null; } else { - body1.processY(-overlap, body1FullImpact, false, true); + layer.data[tileY][tileX] = (replaceWithNull) ? null : new Tile(layer, -1, tileX, tileY, layer.tileWidth, layer.tileHeight); } - // This is special case code that handles things like horizontally moving platforms you can ride - if (body2.moves) + // Recalculate faces only if the removed tile was a colliding tile + if (recalculateFaces && tile && tile.collides) { - body1.x += (body2.x - body2.prev.x) * body2.friction.x; - body1._dx = body1.x - body1.prev.x; + CalculateFacesAt(tileX, tileY, layer); } -}; - -/** - * @namespace Phaser.Physics.Arcade.ProcessY - * @ignore - */ -module.exports = { - BlockCheck: BlockCheck, - Check: Check, - Set: Set, - Run: Run, - RunImmovableBody1: RunImmovableBody1, - RunImmovableBody2: RunImmovableBody2 + return tile; }; +module.exports = RemoveTileAt; + /***/ }), -/* 1391 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 17384: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @namespace Phaser.Physics.Arcade.Tilemap - */ +var RemoveTileAt = __webpack_require__(929); +var Vector2 = __webpack_require__(93736); -var Tilemap = { +var point = new Vector2(); - ProcessTileCallbacks: __webpack_require__(530), - ProcessTileSeparationX: __webpack_require__(534), - ProcessTileSeparationY: __webpack_require__(536), - SeparateTile: __webpack_require__(532), - TileCheckX: __webpack_require__(533), - TileCheckY: __webpack_require__(535), - TileIntersectsBody: __webpack_require__(248) +/** + * Removes the tile at the given world coordinates in the specified layer and updates the layer's + * collision information. + * + * @function Phaser.Tilemaps.Components.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, 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.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.Tilemaps.Tile} The Tile object that was removed. + */ +var RemoveTileAtWorldXY = function (worldX, worldY, replaceWithNull, recalculateFaces, camera, layer) +{ + layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera, layer); + return RemoveTileAt(point.x, point.y, replaceWithNull, recalculateFaces, layer); }; -module.exports = Tilemap; +module.exports = RemoveTileAtWorldXY; /***/ }), -/* 1392 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 93763: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Vector2 = __webpack_require__(3); +var GetTilesWithin = __webpack_require__(50811); +var Color = __webpack_require__(95509); + +var defaultTileColor = new Color(105, 210, 231, 150); +var defaultCollidingTileColor = new Color(243, 134, 48, 200); +var defaultFaceColor = new Color(40, 39, 37, 150); /** - * @classdesc - * - * The Body Bounds class contains methods to help you extract the world coordinates from various points around - * the bounds of a Matter Body. Because Matter bodies are positioned based on their center of mass, and not a - * dimension based center, you often need to get the bounds coordinates in order to properly align them in the world. - * - * You can access this class via the MatterPhysics class from a Scene, i.e.: - * - * ```javascript - * this.matter.bodyBounds.getTopLeft(body); - * ``` - * - * See also the `MatterPhysics.alignBody` method. + * 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. * - * @class BodyBounds - * @memberof Phaser.Physics.Matter - * @constructor - * @since 3.22.0 + * @function Phaser.Tilemaps.Components.RenderDebug + * @since 3.0.0 + * + * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. + * @param {Phaser.Types.Tilemaps.DebugStyleOptions} styleConfig - An object specifying the colors to use for the debug drawing. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -var BodyBounds = new Class({ +var RenderDebug = function (graphics, styleConfig, layer) +{ + if (styleConfig === undefined) { styleConfig = {}; } - initialize: + // Default colors without needlessly creating Color objects + var tileColor = (styleConfig.tileColor !== undefined) ? styleConfig.tileColor : defaultTileColor; + var collidingTileColor = (styleConfig.collidingTileColor !== undefined) ? styleConfig.collidingTileColor : defaultCollidingTileColor; + var faceColor = (styleConfig.faceColor !== undefined) ? styleConfig.faceColor : defaultFaceColor; - function BodyBounds () - { - /** - * A Vector2 that stores the temporary bounds center value during calculations by methods in this class. - * - * @name Phaser.Physics.Matter.BodyBounds#boundsCenter - * @type {Phaser.Math.Vector2} - * @since 3.22.0 - */ - this.boundsCenter = new Vector2(); + var tiles = GetTilesWithin(0, 0, layer.width, layer.height, null, layer); - /** - * A Vector2 that stores the temporary center diff values during calculations by methods in this class. - * - * @name Phaser.Physics.Matter.BodyBounds#centerDiff - * @type {Phaser.Math.Vector2} - * @since 3.22.0 - */ - this.centerDiff = new Vector2(); - }, + graphics.translateCanvas(layer.tilemapLayer.x, layer.tilemapLayer.y); + graphics.scaleCanvas(layer.tilemapLayer.scaleX, layer.tilemapLayer.scaleY); - /** - * Parses the given body to get the bounds diff values from it. - * - * They're stored in this class in the temporary properties `boundsCenter` and `centerDiff`. - * - * This method is called automatically by all other methods in this class. - * - * @method Phaser.Physics.Matter.BodyBounds#parseBody - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the bounds position from. - * - * @return {boolean} `true` if it was able to get the bounds, otherwise `false`. - */ - parseBody: function (body) + for (var i = 0; i < tiles.length; i++) { - body = (body.hasOwnProperty('body')) ? body.body : body; + var tile = tiles[i]; - if (!body.hasOwnProperty('bounds') || !body.hasOwnProperty('centerOfMass')) + var tw = tile.width; + var th = tile.height; + var x = tile.pixelX; + var y = tile.pixelY; + + var color = tile.collides ? collidingTileColor : tileColor; + + if (color !== null) { - return false; + graphics.fillStyle(color.color, color.alpha / 255); + graphics.fillRect(x, y, tw, th); } - var boundsCenter = this.boundsCenter; - var centerDiff = this.centerDiff; + // Inset the face line to prevent neighboring tile's lines from overlapping + x += 1; + y += 1; + tw -= 2; + th -= 2; - var boundsWidth = body.bounds.max.x - body.bounds.min.x; - var boundsHeight = body.bounds.max.y - body.bounds.min.y; + if (faceColor !== null) + { + graphics.lineStyle(1, faceColor.color, faceColor.alpha / 255); - var bodyCenterX = boundsWidth * body.centerOfMass.x; - var bodyCenterY = boundsHeight * body.centerOfMass.y; + if (tile.faceTop) { graphics.lineBetween(x, y, x + tw, y); } + if (tile.faceRight) { graphics.lineBetween(x + tw, y, x + tw, y + th); } + if (tile.faceBottom) { graphics.lineBetween(x, y + th, x + tw, y + th); } + if (tile.faceLeft) { graphics.lineBetween(x, y, x, y + th); } + } + } +}; - boundsCenter.set(boundsWidth / 2, boundsHeight / 2); - centerDiff.set(bodyCenterX - boundsCenter.x, bodyCenterY - boundsCenter.y); +module.exports = RenderDebug; - return true; - }, +/** - /** - * Takes a Body and returns the world coordinates of the top-left of its _bounds_. - * - * Body bounds are updated by Matter each step and factor in scale and rotation. - * This will return the world coordinate based on the bodies _current_ position and bounds. - * - * @method Phaser.Physics.Matter.BodyBounds#getTopLeft - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. - * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. - * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. - * - * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. - */ - getTopLeft: function (body, x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } +function Orientation(f0, f1, f2, f3, b0, b1, b2, b3, start_angle) { + return {f0: f0, f1: f1, f2: f2, f3: f3, b0: b0, b1: b1, b2: b2, b3: b3, start_angle: start_angle}; +} - if (this.parseBody(body)) - { - var center = this.boundsCenter; - var diff = this.centerDiff; +function Layout(orientation, size, origin) { + return {orientation: orientation, size: size, origin: origin}; +} - return new Vector2( - x + center.x + diff.x, - y + center.y + diff.y - ); +function Hex(q, r, s) { + return {q: q, r: r, s: s}; +} + +function hex_round(h) +{ + var qi = Math.round(h.q); + var ri = Math.round(h.r); + var si = Math.round(h.s); + var q_diff = Math.abs(qi - h.q); + var r_diff = Math.abs(ri - h.r); + var s_diff = Math.abs(si - h.s); + if (q_diff > r_diff && q_diff > s_diff) + { + qi = -ri - si; + } + else + if (r_diff > s_diff) + { + ri = -qi - si; + } + else + { + si = -qi - ri; } + return Hex(qi, ri, si); +} - return false; - }, +var layout_pointy = Orientation(Math.sqrt(3.0), Math.sqrt(3.0) / 2.0, 0.0, 3.0 / 2.0, Math.sqrt(3.0) / 3.0, -1.0 / 3.0, 0.0, 2.0 / 3.0, 0.5); - /** - * Takes a Body and returns the world coordinates of the top-center of its _bounds_. - * - * Body bounds are updated by Matter each step and factor in scale and rotation. - * This will return the world coordinate based on the bodies _current_ position and bounds. - * - * @method Phaser.Physics.Matter.BodyBounds#getTopCenter - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. - * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. - * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. - * - * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. - */ - getTopCenter: function (body, x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } +function OffsetCoord(col, row) { + return {col: col, row: row}; +} - if (this.parseBody(body)) - { - var center = this.boundsCenter; - var diff = this.centerDiff; +var EVEN = 1; +var ODD = -1; - return new Vector2( - x + diff.x, - y + center.y + diff.y - ); - } +function roffset_from_cube(offset, h) +{ + var col = h.q + (h.r + offset * (h.r & 1)) / 2; + var row = h.r; + return OffsetCoord(col, row); +} - return false; - }, +function roffset_to_cube(offset, h) +{ + var q = h.col - (h.row + offset * (h.row & 1)) / 2; + var r = h.row; + var s = -q - r; + return Hex(q, r, s); +} - /** - * Takes a Body and returns the world coordinates of the top-right of its _bounds_. - * - * Body bounds are updated by Matter each step and factor in scale and rotation. - * This will return the world coordinate based on the bodies _current_ position and bounds. - * - * @method Phaser.Physics.Matter.BodyBounds#getTopRight - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. - * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. - * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. - * - * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. - */ - getTopRight: function (body, x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } +function hex_to_pixel(layout, h) +{ + var M = layout.orientation; + var size = layout.size; + var origin = layout.origin; + var x = (M.f0 * h.q + M.f1 * h.r) * size.x; + var y = (M.f2 * h.q + M.f3 * h.r) * size.y; + return new Vector2(x + origin.x, y + origin.y); +} - if (this.parseBody(body)) - { - var center = this.boundsCenter; - var diff = this.centerDiff; +function hex_corner_offset(layout, corner) +{ + var M = layout.orientation; + var size = layout.size; + var angle = 2.0 * Math.PI * (M.start_angle - corner) / 6.0; + return new Vector2(size.x * Math.cos(angle), size.y * Math.sin(angle)); +} - return new Vector2( - x - (center.x - diff.x), - y + center.y + diff.y - ); - } +function polygon_corners(layout, h) +{ + var corners = []; + var center = hex_to_pixel(layout, h); + for (var i = 0; i < 6; i++) + { + var offset = hex_corner_offset(layout, i); + corners.push(new Vector2(center.x + offset.x, center.y + offset.y)); + } + return corners; +} - return false; - }, +var layout = Layout(layout_pointy, new Vector2(tileHeight/2, tileWidth/2), new Vector2(tileWidth/2, tileWidth/2)); - /** - * Takes a Body and returns the world coordinates of the left-center of its _bounds_. - * - * Body bounds are updated by Matter each step and factor in scale and rotation. - * This will return the world coordinate based on the bodies _current_ position and bounds. - * - * @method Phaser.Physics.Matter.BodyBounds#getLeftCenter - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. - * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. - * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. - * - * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. - */ - getLeftCenter: function (body, x, y) +for (var q = 0; q <= 9; q++) +{ + for (var r = 0; r <= 9; r++) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } + var h = Hex(q, r, -q - r); // cubed + // var hr = hex_round(h); + // var o = roffset_from_cube(ODD, hr); + // var b = roffset_to_cube(ODD, o); - if (this.parseBody(body)) + var c = polygon_corners(layout, h); + + if (q === 0 && r === 0) { - var center = this.boundsCenter; - var diff = this.centerDiff; + console.log(c); + } - return new Vector2( - x + center.x + diff.x, - y + diff.y - ); + g.beginPath(); + g.moveTo(Math.floor(c[0].x), Math.floor(c[0].y)); + + for (var i = 1; i < c.length; i++) + { + g.lineTo(Math.floor(c[i].x), Math.floor(c[i].y)); } - return false; - }, + g.closePath(); + g.strokePath(); + } +} - /** - * Takes a Body and returns the world coordinates of the center of its _bounds_. - * - * Body bounds are updated by Matter each step and factor in scale and rotation. - * This will return the world coordinate based on the bodies _current_ position and bounds. - * - * @method Phaser.Physics.Matter.BodyBounds#getCenter - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. - * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. - * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. - * - * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. - */ - getCenter: function (body, x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } + var c = polygon_corners(layout, hr); - if (this.parseBody(body)) - { - var diff = this.centerDiff; + g.beginPath(); + g.moveTo(Math.floor(c[0].x), Math.floor(c[0].y)); - return new Vector2( - x + diff.x, - y + diff.y - ); - } + for (var i = 1; i < c.length; i++) + { + g.lineTo(Math.floor(c[i].x), Math.floor(c[i].y)); + } - return false; - }, + g.closePath(); + g.fillPath(); - /** - * Takes a Body and returns the world coordinates of the right-center of its _bounds_. - * - * Body bounds are updated by Matter each step and factor in scale and rotation. - * This will return the world coordinate based on the bodies _current_ position and bounds. - * - * @method Phaser.Physics.Matter.BodyBounds#getRightCenter - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. - * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. - * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. - * - * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. - */ - getRightCenter: function (body, x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } + // g.scene.add.text(c[3].x + 2, c[3].y + 6, `${hr.q} x ${hr.r}`); + g.scene.add.text(c[3].x + 2, c[3].y + 6, `${x} x ${y}`); - if (this.parseBody(body)) - { - var center = this.boundsCenter; - var diff = this.centerDiff; - return new Vector2( - x - (center.x - diff.x), - y + diff.y - ); +*/ + + +/***/ }), + +/***/ 51202: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTilesWithin = __webpack_require__(50811); + +/** + * 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; } + } +}; - return false; - }, +module.exports = ReplaceByIndex; - /** - * Takes a Body and returns the world coordinates of the bottom-left of its _bounds_. - * - * Body bounds are updated by Matter each step and factor in scale and rotation. - * This will return the world coordinate based on the bodies _current_ position and bounds. - * - * @method Phaser.Physics.Matter.BodyBounds#getBottomLeft - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. - * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. - * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. - * - * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. - */ - getBottomLeft: function (body, x, y) + +/***/ }), + +/***/ 6987: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Returns the tiles in the given layer that are within the cameras viewport. This is used internally. + * + * @function Phaser.Tilemaps.Components.RunCull + * @since 3.50.0 + * + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {object} bounds - An object containing the `left`, `right`, `top` and `bottom` bounds. + * @param {number} renderOrder - The rendering order constant. + * @param {array} outputArray - The array to store the Tile objects within. + * + * @return {Phaser.Tilemaps.Tile[]} An array of Tile objects. + */ +var RunCull = function (layer, bounds, renderOrder, outputArray) +{ + var mapData = layer.data; + var mapWidth = layer.width; + var mapHeight = layer.height; + + var tilemapLayer = layer.tilemapLayer; + + var drawLeft = Math.max(0, bounds.left); + var drawRight = Math.min(mapWidth, bounds.right); + var drawTop = Math.max(0, bounds.top); + var drawBottom = Math.min(mapHeight, bounds.bottom); + + var x; + var y; + var tile; + + if (renderOrder === 0) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } + // right-down - if (this.parseBody(body)) + for (y = drawTop; y < drawBottom; y++) { - var center = this.boundsCenter; - var diff = this.centerDiff; - - return new Vector2( - x + center.x + diff.x, - y - (center.y - diff.y) - ); - } + for (x = drawLeft; mapData[y] && x < drawRight; x++) + { + tile = mapData[y][x]; - return false; - }, + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } - /** - * Takes a Body and returns the world coordinates of the bottom-center of its _bounds_. - * - * Body bounds are updated by Matter each step and factor in scale and rotation. - * This will return the world coordinate based on the bodies _current_ position and bounds. - * - * @method Phaser.Physics.Matter.BodyBounds#getBottomCenter - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. - * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. - * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. - * - * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. - */ - getBottomCenter: function (body, x, y) + outputArray.push(tile); + } + } + } + else if (renderOrder === 1) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } + // left-down - if (this.parseBody(body)) + for (y = drawTop; y < drawBottom; y++) { - var center = this.boundsCenter; - var diff = this.centerDiff; + for (x = drawRight; mapData[y] && x >= drawLeft; x--) + { + tile = mapData[y][x]; - return new Vector2( - x + diff.x, - y - (center.y - diff.y) - ); + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } } + } + else if (renderOrder === 2) + { + // right-up - return false; - }, + for (y = drawBottom; y >= drawTop; y--) + { + for (x = drawLeft; mapData[y] && x < drawRight; x++) + { + tile = mapData[y][x]; - /** - * Takes a Body and returns the world coordinates of the bottom-right of its _bounds_. - * - * Body bounds are updated by Matter each step and factor in scale and rotation. - * This will return the world coordinate based on the bodies _current_ position and bounds. - * - * @method Phaser.Physics.Matter.BodyBounds#getBottomRight - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from. - * @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates. - * @param {number} [y=0] - Optional vertical offset to add to the returned coordinates. - * - * @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body. - */ - getBottomRight: function (body, x, y) + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } + + outputArray.push(tile); + } + } + } + else if (renderOrder === 3) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } + // left-up - if (this.parseBody(body)) + for (y = drawBottom; y >= drawTop; y--) { - var center = this.boundsCenter; - var diff = this.centerDiff; + for (x = drawRight; mapData[y] && x >= drawLeft; x--) + { + tile = mapData[y][x]; - return new Vector2( - x - (center.x - diff.x), - y - (center.y - diff.y) - ); - } + if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) + { + continue; + } - return false; + outputArray.push(tile); + } + } } -}); + tilemapLayer.tilesDrawn = outputArray.length; + tilemapLayer.tilesTotal = mapWidth * mapHeight; -module.exports = BodyBounds; + return outputArray; +}; + +module.exports = RunCull; /***/ }), -/* 1393 */ -/***/ (function(module, exports) { + +/***/ 51710: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author Stefan Hedman (http://steffe.se) + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// v0.3.0 - -module.exports = { - decomp: polygonDecomp, - quickDecomp: polygonQuickDecomp, - isSimple: polygonIsSimple, - removeCollinearPoints: polygonRemoveCollinearPoints, - removeDuplicatePoints: polygonRemoveDuplicatePoints, - makeCCW: polygonMakeCCW -}; - -/** - * Compute the intersection between two lines. - * @static - * @method lineInt - * @param {Array} l1 Line vector 1 - * @param {Array} l2 Line vector 2 - * @param {Number} precision Precision to use when checking if the lines are parallel - * @return {Array} The intersection point. - */ -function lineInt(l1,l2,precision){ - precision = precision || 0; - var i = [0,0]; // point - var a1, b1, c1, a2, b2, c2, det; // scalars - a1 = l1[1][1] - l1[0][1]; - b1 = l1[0][0] - l1[1][0]; - c1 = a1 * l1[0][0] + b1 * l1[0][1]; - a2 = l2[1][1] - l2[0][1]; - b2 = l2[0][0] - l2[1][0]; - c2 = a2 * l2[0][0] + b2 * l2[0][1]; - det = a1 * b2 - a2*b1; - if (!scalar_eq(det, 0, precision)) { // lines are not parallel - i[0] = (b2 * c1 - b1 * c2) / det; - i[1] = (a1 * c2 - a2 * c1) / det; - } - return i; -} +var SetTileCollision = __webpack_require__(68234); +var CalculateFacesWithin = __webpack_require__(60386); +var SetLayerCollisionIndex = __webpack_require__(91181); /** - * Checks if two line segments intersects. - * @method segmentsIntersect - * @param {Array} p1 The start vertex of the first line segment. - * @param {Array} p2 The end vertex of the first line segment. - * @param {Array} q1 The start vertex of the second line segment. - * @param {Array} q2 The end vertex of the second line segment. - * @return {Boolean} True if the two line segments intersect + * 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). + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @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. */ -function lineSegmentsIntersect(p1, p2, q1, q2){ - var dx = p2[0] - p1[0]; - var dy = p2[1] - p1[1]; - var da = q2[0] - q1[0]; - var db = q2[1] - q1[1]; +var SetCollision = function (indexes, collides, recalculateFaces, layer, updateLayer) +{ + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + if (updateLayer === undefined) { updateLayer = true; } - // segments are parallel - if((da*dy - db*dx) === 0){ - return false; - } + if (!Array.isArray(indexes)) + { + indexes = [ indexes ]; + } - var s = (dx * (q1[1] - p1[1]) + dy * (p1[0] - q1[0])) / (da * dy - db * dx); - var t = (da * (p1[1] - q1[1]) + db * (q1[0] - p1[0])) / (db * dx - da * dy); + // Update the array of colliding indexes + for (var i = 0; i < indexes.length; i++) + { + SetLayerCollisionIndex(indexes[i], collides, layer); + } - return (s>=0 && s<=1 && t>=0 && t<=1); -} + // Update the tiles + if (updateLayer) + { + for (var ty = 0; ty < layer.height; ty++) + { + for (var tx = 0; tx < layer.width; tx++) + { + var tile = layer.data[ty][tx]; -/** - * Get the area of a triangle spanned by the three given points. Note that the area will be negative if the points are not given in counter-clockwise order. - * @static - * @method area - * @param {Array} a - * @param {Array} b - * @param {Array} c - * @return {Number} - */ -function triangleArea(a,b,c){ - return (((b[0] - a[0])*(c[1] - a[1]))-((c[0] - a[0])*(b[1] - a[1]))); -} + if (tile && indexes.indexOf(tile.index) !== -1) + { + SetTileCollision(tile, collides); + } + } + } + } -function isLeft(a,b,c){ - return triangleArea(a,b,c) > 0; -} + if (recalculateFaces) + { + CalculateFacesWithin(0, 0, layer.width, layer.height, layer); + } +}; -function isLeftOn(a,b,c) { - return triangleArea(a, b, c) >= 0; -} +module.exports = SetCollision; -function isRight(a,b,c) { - return triangleArea(a, b, c) < 0; -} -function isRightOn(a,b,c) { - return triangleArea(a, b, c) <= 0; -} +/***/ }), -var tmpPoint1 = [], - tmpPoint2 = []; +/***/ 15216: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Check if three points are collinear - * @method collinear - * @param {Array} a - * @param {Array} b - * @param {Array} c - * @param {Number} [thresholdAngle=0] Threshold angle to use when comparing the vectors. The function will return true if the angle between the resulting vectors is less than this value. Use zero for max precision. - * @return {Boolean} + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -function collinear(a,b,c,thresholdAngle) { - if(!thresholdAngle){ - return triangleArea(a, b, c) === 0; - } else { - var ab = tmpPoint1, - bc = tmpPoint2; - - ab[0] = b[0]-a[0]; - ab[1] = b[1]-a[1]; - bc[0] = c[0]-b[0]; - bc[1] = c[1]-b[1]; - - var dot = ab[0]*bc[0] + ab[1]*bc[1], - magA = Math.sqrt(ab[0]*ab[0] + ab[1]*ab[1]), - magB = Math.sqrt(bc[0]*bc[0] + bc[1]*bc[1]), - angle = Math.acos(dot/(magA*magB)); - return angle < thresholdAngle; - } -} -function sqdist(a,b){ - var dx = b[0] - a[0]; - var dy = b[1] - a[1]; - return dx * dx + dy * dy; -} +var SetTileCollision = __webpack_require__(68234); +var CalculateFacesWithin = __webpack_require__(60386); +var SetLayerCollisionIndex = __webpack_require__(91181); /** - * Get a vertex at position i. It does not matter if i is out of bounds, this function will just cycle. - * @method at - * @param {Number} i - * @return {Array} + * 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). + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @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. */ -function polygonAt(polygon, i){ - var s = polygon.length; - return polygon[i < 0 ? i % s + s : i % s]; -} +var SetCollisionBetween = function (start, stop, collides, recalculateFaces, layer, updateLayer) +{ + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } + if (updateLayer === undefined) { updateLayer = true; } -/** - * Clear the polygon data - * @method clear - * @return {Array} - */ -function polygonClear(polygon){ - polygon.length = 0; -} + if (start > stop) + { + return; + } -/** - * Append points "from" to "to"-1 from an other polygon "poly" onto this one. - * @method append - * @param {Polygon} poly The polygon to get points from. - * @param {Number} from The vertex index in "poly". - * @param {Number} to The end vertex index in "poly". Note that this vertex is NOT included when appending. - * @return {Array} - */ -function polygonAppend(polygon, poly, from, to){ - for(var i=from; i v[br][0])) { - br = i; + if (tile) + { + if (tile.index >= start && tile.index <= stop) + { + SetTileCollision(tile, collides); + } + } + } } } - // reverse poly if clockwise - if (!isLeft(polygonAt(polygon, br - 1), polygonAt(polygon, br), polygonAt(polygon, br + 1))) { - polygonReverse(polygon); - return true; - } else { - return false; + if (recalculateFaces) + { + CalculateFacesWithin(0, 0, layer.width, layer.height, layer); } -} +}; + +module.exports = SetCollisionBetween; -/** - * Reverse the vertices in the polygon - * @method reverse - */ -function polygonReverse(polygon){ - var tmp = []; - var N = polygon.length; - for(var i=0; i!==N; i++){ - tmp.push(polygon.pop()); - } - for(var i=0; i!==N; i++){ - polygon[i] = tmp[i]; - } -} + +/***/ }), + +/***/ 33158: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Check if a point in the polygon is a reflex point - * @method isReflex - * @param {Number} i - * @return {Boolean} + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -function polygonIsReflex(polygon, i){ - return isRight(polygonAt(polygon, i - 1), polygonAt(polygon, i), polygonAt(polygon, i + 1)); -} -var tmpLine1=[], - tmpLine2=[]; +var SetTileCollision = __webpack_require__(68234); +var CalculateFacesWithin = __webpack_require__(60386); +var SetLayerCollisionIndex = __webpack_require__(91181); /** - * Check if two vertices in the polygon can see each other - * @method canSee - * @param {Number} a Vertex index 1 - * @param {Number} b Vertex index 2 - * @return {Boolean} + * 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. + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -function polygonCanSee(polygon, a,b) { - var p, dist, l1=tmpLine1, l2=tmpLine2; +var SetCollisionByExclusion = function (indexes, collides, recalculateFaces, layer) +{ + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } - if (isLeftOn(polygonAt(polygon, a + 1), polygonAt(polygon, a), polygonAt(polygon, b)) && isRightOn(polygonAt(polygon, a - 1), polygonAt(polygon, a), polygonAt(polygon, b))) { - return false; + if (!Array.isArray(indexes)) + { + indexes = [ indexes ]; } - dist = sqdist(polygonAt(polygon, a), polygonAt(polygon, b)); - for (var i = 0; i !== polygon.length; ++i) { // for each edge - if ((i + 1) % polygon.length === a || i === a){ // ignore incident edges - continue; - } - if (isLeftOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i + 1)) && isRightOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i))) { // if diag intersects an edge - l1[0] = polygonAt(polygon, a); - l1[1] = polygonAt(polygon, b); - l2[0] = polygonAt(polygon, i); - l2[1] = polygonAt(polygon, i + 1); - p = lineInt(l1,l2); - if (sqdist(polygonAt(polygon, a), p) < dist) { // if edge is blocking visibility to b - return false; + + // Note: this only updates layer.collideIndexes for tile indexes found currently in the layer + for (var ty = 0; ty < layer.height; ty++) + { + for (var tx = 0; tx < layer.width; tx++) + { + var tile = layer.data[ty][tx]; + + if (tile && indexes.indexOf(tile.index) === -1) + { + SetTileCollision(tile, collides); + SetLayerCollisionIndex(tile.index, collides, layer); } } } - return true; -} - -/** - * Check if two vertices in the polygon can see each other - * @method canSee2 - * @param {Number} a Vertex index 1 - * @param {Number} b Vertex index 2 - * @return {Boolean} - */ -function polygonCanSee2(polygon, a,b) { - // for each edge - for (var i = 0; i !== polygon.length; ++i) { - // ignore incident edges - if (i === a || i === b || (i + 1) % polygon.length === a || (i + 1) % polygon.length === b){ - continue; - } - if( lineSegmentsIntersect(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i), polygonAt(polygon, i+1)) ){ - return false; - } + if (recalculateFaces) + { + CalculateFacesWithin(0, 0, layer.width, layer.height, layer); } - return true; -} +}; -/** - * Copy the polygon from vertex i to vertex j. - * @method copy - * @param {Number} i - * @param {Number} j - * @param {Polygon} [targetPoly] Optional target polygon to save in. - * @return {Polygon} The resulting copy. - */ -function polygonCopy(polygon, i,j,targetPoly){ - var p = targetPoly || []; - polygonClear(p); - if (i < j) { - // Insert all vertices from i to j - for(var k=i; k<=j; k++){ - p.push(polygon[k]); - } +module.exports = SetCollisionByExclusion; - } else { - // Insert vertices 0 to j - for(var k=0; k<=j; k++){ - p.push(polygon[k]); - } +/***/ }), - // Insert vertices i to end - for(var k=i; k { - return p; -} +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var SetTileCollision = __webpack_require__(68234); +var CalculateFacesWithin = __webpack_require__(60386); +var HasValue = __webpack_require__(19256); /** - * Decomposes the polygon into convex pieces. Returns a list of edges [[p1,p2],[p2,p3],...] that cuts the polygon. - * Note that this algorithm has complexity O(N^4) and will be very slow for polygons with many vertices. - * @method getCutEdges - * @return {Array} + * 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. + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -function polygonGetCutEdges(polygon) { - var min=[], tmp1=[], tmp2=[], tmpPoly = []; - var nDiags = Number.MAX_VALUE; +var SetCollisionByProperty = function (properties, collides, recalculateFaces, layer) +{ + if (collides === undefined) { collides = true; } + if (recalculateFaces === undefined) { recalculateFaces = true; } - for (var i = 0; i < polygon.length; ++i) { - if (polygonIsReflex(polygon, i)) { - for (var j = 0; j < polygon.length; ++j) { - if (polygonCanSee(polygon, i, j)) { - tmp1 = polygonGetCutEdges(polygonCopy(polygon, i, j, tmpPoly)); - tmp2 = polygonGetCutEdges(polygonCopy(polygon, j, i, tmpPoly)); + for (var ty = 0; ty < layer.height; ty++) + { + for (var tx = 0; tx < layer.width; tx++) + { + var tile = layer.data[ty][tx]; - for(var k=0; k 0){ - return polygonSlice(polygon, edges); - } else { - return [polygon]; + if (recalculateFaces) + { + CalculateFacesWithin(0, 0, layer.width, layer.height, layer); } -} +}; -/** - * Slices the polygon given one or more cut edges. If given one, this function will return two polygons (false on failure). If many, an array of polygons. - * @method slice - * @param {Array} cutEdges A list of edges, as returned by .getCutEdges() - * @return {Array} - */ -function polygonSlice(polygon, cutEdges){ - if(cutEdges.length === 0){ - return [polygon]; - } - if(cutEdges instanceof Array && cutEdges.length && cutEdges[0] instanceof Array && cutEdges[0].length===2 && cutEdges[0][0] instanceof Array){ +module.exports = SetCollisionByProperty; - var polys = [polygon]; - for(var i=0; i { - // Was given one edge - var cutEdge = cutEdges; - var i = polygon.indexOf(cutEdge[0]); - var j = polygon.indexOf(cutEdge[1]); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if(i !== -1 && j !== -1){ - return [polygonCopy(polygon, i,j), - polygonCopy(polygon, j,i)]; - } else { - return false; - } - } -} +var SetTileCollision = __webpack_require__(68234); +var CalculateFacesWithin = __webpack_require__(60386); /** - * Checks that the line segments of this polygon do not intersect each other. - * @method isSimple - * @param {Array} path An array of vertices e.g. [[0,0],[0,1],...] - * @return {Boolean} - * @todo Should it check all segments with all others? + * Sets collision on the tiles within a layer by checking each tile's collision group data + * (typically defined in Tiled within the tileset collision editor). If any objects are found within + * a tile's collision group, the tile's colliding information will be set. The `collides` parameter + * controls if collision will be enabled (true) or disabled (false). + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -function polygonIsSimple(polygon){ - var path = polygon, i; - // Check - for(i=0; i 0) + { + SetTileCollision(tile, collides); } } } - // Check the segment between the last and the first point to all others - for(i=1; i { /** - * Quickly decompose the Polygon into convex sub-polygons. - * @method quickDecomp - * @param {Array} result - * @param {Array} [reflexVertices] - * @param {Array} [steinerPoints] - * @param {Number} [delta] - * @param {Number} [maxlevel] - * @param {Number} [level] - * @return {Array} + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -function polygonQuickDecomp(polygon, result,reflexVertices,steinerPoints,delta,maxlevel,level){ - maxlevel = maxlevel || 100; - level = level || 0; - delta = delta || 25; - result = typeof(result)!=="undefined" ? result : []; - reflexVertices = reflexVertices || []; - steinerPoints = steinerPoints || []; - var upperInt=[0,0], lowerInt=[0,0], p=[0,0]; // Points - var upperDist=0, lowerDist=0, d=0, closestDist=0; // scalars - var upperIndex=0, lowerIndex=0, closestIndex=0; // Integers - var lowerPoly=[], upperPoly=[]; // polygons - var poly = polygon, - v = polygon; +/** + * Internally used method to keep track of the tile indexes that collide within a layer. This + * updates LayerData.collideIndexes to either contain or not contain the given `tileIndex`. + * + * @function Phaser.Tilemaps.Components.SetLayerCollisionIndex + * @since 3.0.0 + * + * @param {number} tileIndex - The tile index to set the collision boolean for. + * @param {boolean} collides - Should the tile index collide or not? + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + */ +var SetLayerCollisionIndex = function (tileIndex, collides, layer) +{ + var loc = layer.collideIndexes.indexOf(tileIndex); - if(v.length < 3){ - return result; + if (collides && loc === -1) + { + layer.collideIndexes.push(tileIndex); } - - level++; - if(level > maxlevel){ - console.warn("quickDecomp: max level ("+maxlevel+") reached."); - return result; + else if (!collides && loc !== -1) + { + layer.collideIndexes.splice(loc, 1); } +}; - for (var i = 0; i < polygon.length; ++i) { - if (polygonIsReflex(poly, i)) { - reflexVertices.push(poly[i]); - upperDist = lowerDist = Number.MAX_VALUE; - - - for (var j = 0; j < polygon.length; ++j) { - if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j - 1))) { // if line intersects with an edge - p = getIntersectionPoint(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j - 1)); // find the point of intersection - if (isRight(polygonAt(poly, i + 1), polygonAt(poly, i), p)) { // make sure it's inside the poly - d = sqdist(poly[i], p); - if (d < lowerDist) { // keep only the closest intersection - lowerDist = d; - lowerInt = p; - lowerIndex = j; - } - } - } - if (isLeft(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j + 1)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) { - p = getIntersectionPoint(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j + 1)); - if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), p)) { - d = sqdist(poly[i], p); - if (d < upperDist) { - upperDist = d; - upperInt = p; - upperIndex = j; - } - } - } - } +module.exports = SetLayerCollisionIndex; - // if there are no vertices to connect to, choose a point in the middle - if (lowerIndex === (upperIndex + 1) % polygon.length) { - //console.log("Case 1: Vertex("+i+"), lowerIndex("+lowerIndex+"), upperIndex("+upperIndex+"), poly.size("+polygon.length+")"); - p[0] = (lowerInt[0] + upperInt[0]) / 2; - p[1] = (lowerInt[1] + upperInt[1]) / 2; - steinerPoints.push(p); - if (i < upperIndex) { - //lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.begin() + upperIndex + 1); - polygonAppend(lowerPoly, poly, i, upperIndex+1); - lowerPoly.push(p); - upperPoly.push(p); - if (lowerIndex !== 0){ - //upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.end()); - polygonAppend(upperPoly, poly,lowerIndex,poly.length); - } - //upperPoly.insert(upperPoly.end(), poly.begin(), poly.begin() + i + 1); - polygonAppend(upperPoly, poly,0,i+1); - } else { - if (i !== 0){ - //lowerPoly.insert(lowerPoly.end(), poly.begin() + i, poly.end()); - polygonAppend(lowerPoly, poly,i,poly.length); - } - //lowerPoly.insert(lowerPoly.end(), poly.begin(), poly.begin() + upperIndex + 1); - polygonAppend(lowerPoly, poly,0,upperIndex+1); - lowerPoly.push(p); - upperPoly.push(p); - //upperPoly.insert(upperPoly.end(), poly.begin() + lowerIndex, poly.begin() + i + 1); - polygonAppend(upperPoly, poly,lowerIndex,i+1); - } - } else { - // connect to the closest point within the triangle - //console.log("Case 2: Vertex("+i+"), closestIndex("+closestIndex+"), poly.size("+polygon.length+")\n"); +/***/ }), - if (lowerIndex > upperIndex) { - upperIndex += polygon.length; - } - closestDist = Number.MAX_VALUE; +/***/ 68234: +/***/ ((module) => { - if(upperIndex < lowerIndex){ - return result; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (var j = lowerIndex; j <= upperIndex; ++j) { - if ( - isLeftOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && - isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j)) - ) { - d = sqdist(polygonAt(poly, i), polygonAt(poly, j)); - if (d < closestDist && polygonCanSee2(poly, i, j)) { - closestDist = d; - closestIndex = j % polygon.length; - } - } - } +/** + * Internally used method to set the colliding state of a tile. This does not recalculate + * interesting faces. + * + * @function Phaser.Tilemaps.Components.SetTileCollision + * @since 3.0.0 + * + * @param {Phaser.Tilemaps.Tile} tile - The Tile to set the collision on. + * @param {boolean} [collides=true] - Should the tile index collide or not? + */ +var SetTileCollision = function (tile, collides) +{ + if (collides) + { + tile.setCollision(true, true, true, true, false); + } + else + { + tile.resetCollision(false); + } +}; - if (i < closestIndex) { - polygonAppend(lowerPoly, poly,i,closestIndex+1); - if (closestIndex !== 0){ - polygonAppend(upperPoly, poly,closestIndex,v.length); - } - polygonAppend(upperPoly, poly,0,i+1); - } else { - if (i !== 0){ - polygonAppend(lowerPoly, poly,i,v.length); - } - polygonAppend(lowerPoly, poly,0,closestIndex+1); - polygonAppend(upperPoly, poly,closestIndex,i+1); - } - } +module.exports = SetTileCollision; - // solve smallest poly first - if (lowerPoly.length < upperPoly.length) { - polygonQuickDecomp(lowerPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level); - polygonQuickDecomp(upperPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level); - } else { - polygonQuickDecomp(upperPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level); - polygonQuickDecomp(lowerPoly,result,reflexVertices,steinerPoints,delta,maxlevel,level); - } - return result; - } - } - result.push(polygon); +/***/ }), - return result; -} +/***/ 11628: +/***/ ((module) => { /** - * Remove collinear points in the polygon. - * @method removeCollinearPoints - * @param {Number} [precision] The threshold angle to use when determining whether two edges are collinear. Use zero for finest precision. - * @return {Number} The number of points removed + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -function polygonRemoveCollinearPoints(polygon, precision){ - var num = 0; - for(var i=polygon.length-1; polygon.length>3 && i>=0; --i){ - if(collinear(polygonAt(polygon, i-1),polygonAt(polygon, i),polygonAt(polygon, i+1),precision)){ - // Remove the middle point - polygon.splice(i%polygon.length,1); - num++; - } - } - return num; -} /** - * Remove duplicate points in the polygon. - * @method removeDuplicatePoints - * @param {Number} [precision] The threshold to use when determining whether two points are the same. Use zero for best precision. + * 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. + * + * @function Phaser.Tilemaps.Components.SetTileIndexCallback + * @since 3.0.0 + * + * @param {(number|array)} 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. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -function polygonRemoveDuplicatePoints(polygon, precision){ - for(var i=polygon.length-1; i>=1; --i){ - var pi = polygon[i]; - for(var j=i-1; j>=0; --j){ - if(points_eq(pi, polygon[j], precision)){ - polygon.splice(i,1); - continue; - } +var SetTileIndexCallback = function (indexes, callback, callbackContext, layer) +{ + if (typeof indexes === 'number') + { + layer.callbacks[indexes] = (callback !== null) + ? { callback: callback, callbackContext: callbackContext } + : undefined; + } + else + { + for (var i = 0, len = indexes.length; i < len; i++) + { + layer.callbacks[indexes[i]] = (callback !== null) + ? { callback: callback, callbackContext: callbackContext } + : undefined; } } -} +}; + +module.exports = SetTileIndexCallback; + + +/***/ }), + +/***/ 72732: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * Check if two scalars are equal - * @static - * @method eq - * @param {Number} a - * @param {Number} b - * @param {Number} [precision] - * @return {Boolean} + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -function scalar_eq(a,b,precision){ - precision = precision || 0; - return Math.abs(a-b) <= precision; -} + +var GetTilesWithin = __webpack_require__(50811); /** - * Check if two points are equal - * @static - * @method points_eq - * @param {Array} a - * @param {Array} b - * @param {Number} [precision] - * @return {Boolean} + * 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. + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. */ -function points_eq(a,b,precision){ - return scalar_eq(a[0],b[0],precision) && scalar_eq(a[1],b[1],precision); -} +var SetTileLocationCallback = function (tileX, tileY, width, height, callback, callbackContext, layer) +{ + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + + for (var i = 0; i < tiles.length; i++) + { + tiles[i].setCollisionCallback(callback, callbackContext); + } +}; + +module.exports = SetTileLocationCallback; /***/ }), -/* 1394 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 34397: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Bodies = __webpack_require__(86); -var Class = __webpack_require__(0); -var Composites = __webpack_require__(591); -var Constraint = __webpack_require__(128); -var Svg = __webpack_require__(592); -var MatterGameObject = __webpack_require__(1395); -var MatterImage = __webpack_require__(1396); -var MatterSprite = __webpack_require__(1397); -var MatterTileBody = __webpack_require__(593); -var PhysicsEditorParser = __webpack_require__(589); -var PhysicsJSONParser = __webpack_require__(590); -var PointerConstraint = __webpack_require__(1398); -var Vertices = __webpack_require__(64); +var GetTilesWithin = __webpack_require__(50811); +var ShuffleArray = __webpack_require__(18592); /** - * @classdesc - * The Matter Factory is responsible for quickly creating a variety of different types of - * bodies, constraints and Game Objects and adding them into the physics world. - * - * You access the factory from within a Scene using `add`: - * - * ```javascript - * this.matter.add.rectangle(x, y, width, height); - * ``` - * - * Use of the Factory is optional. All of the objects it creates can also be created - * directly via your own code or constructors. It is provided as a means to keep your - * code concise. + * 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. * - * @class Factory - * @memberof Phaser.Physics.Matter - * @constructor + * @function Phaser.Tilemaps.Components.Shuffle * @since 3.0.0 * - * @param {Phaser.Physics.Matter.World} world - The Matter World which this Factory adds to. + * @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 Factory = new Class({ +var Shuffle = function (tileX, tileY, width, height, layer) +{ + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); - initialize: + var indexes = tiles.map(function (tile) { return tile.index; }); - function Factory (world) + ShuffleArray(indexes); + + for (var i = 0; i < tiles.length; i++) { - /** - * The Matter World which this Factory adds to. - * - * @name Phaser.Physics.Matter.Factory#world - * @type {Phaser.Physics.Matter.World} - * @since 3.0.0 - */ - this.world = world; + tiles[i].index = indexes[i]; + } +}; - /** - * The Scene which this Factory's Matter World belongs to. - * - * @name Phaser.Physics.Matter.Factory#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = world.scene; +module.exports = Shuffle; - /** - * A reference to the Scene.Systems this Matter Physics instance belongs to. - * - * @name Phaser.Physics.Matter.Factory#sys - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.sys = world.scene.sys; - }, - /** - * Creates a new rigid rectangular Body and adds it to the World. - * - * @method Phaser.Physics.Matter.Factory#rectangle - * @since 3.0.0 - * - * @param {number} x - The X coordinate of the center of the Body. - * @param {number} y - The Y coordinate of the center of the Body. - * @param {number} width - The width of the Body. - * @param {number} height - The height of the Body. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {MatterJS.BodyType} A Matter JS Body. - */ - rectangle: function (x, y, width, height, options) - { - var body = Bodies.rectangle(x, y, width, height, options); +/***/ }), - this.world.add(body); +/***/ 53945: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return body; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Creates a new rigid trapezoidal Body and adds it to the World. - * - * @method Phaser.Physics.Matter.Factory#trapezoid - * @since 3.0.0 - * - * @param {number} x - The X coordinate of the center of the Body. - * @param {number} y - The Y coordinate of the center of the Body. - * @param {number} width - The width of the trapezoid Body. - * @param {number} height - The height of the trapezoid Body. - * @param {number} slope - The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {MatterJS.BodyType} A Matter JS Body. - */ - trapezoid: function (x, y, width, height, slope, options) - { - var body = Bodies.trapezoid(x, y, width, height, slope, options); +var SnapCeil = __webpack_require__(82127); +var SnapFloor = __webpack_require__(84314); - this.world.add(body); +/** + * 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; - return body; - }, + // 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); - /** - * Creates a new rigid circular Body and adds it to the World. - * - * @method Phaser.Physics.Matter.Factory#circle - * @since 3.0.0 - * - * @param {number} x - The X coordinate of the center of the Body. - * @param {number} y - The Y coordinate of the center of the Body. - * @param {number} radius - The radius of the circle. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * @param {number} [maxSides] - The maximum amount of sides to use for the polygon which will approximate this circle. - * - * @return {MatterJS.BodyType} A Matter JS Body. - */ - circle: function (x, y, radius, options, maxSides) - { - var body = Bodies.circle(x, y, radius, options, maxSides); + 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; - this.world.add(body); + 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 body; - }, + return { + left: boundsLeft, + right: boundsRight, + top: boundsTop, + bottom: boundsBottom + }; +}; - /** - * Creates a new rigid polygonal Body and adds it to the World. - * - * @method Phaser.Physics.Matter.Factory#polygon - * @since 3.0.0 - * - * @param {number} x - The X coordinate of the center of the Body. - * @param {number} y - The Y coordinate of the center of the Body. - * @param {number} sides - The number of sides the polygon will have. - * @param {number} radius - The "radius" of the polygon, i.e. the distance from its center to any vertex. This is also the radius of its circumcircle. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {MatterJS.BodyType} A Matter JS Body. - */ - polygon: function (x, y, sides, radius, options) - { - var body = Bodies.polygon(x, y, sides, radius, options); +module.exports = StaggeredCullBounds; - this.world.add(body); - return body; - }, +/***/ }), - /** - * Creates a body using the supplied vertices (or an array containing multiple sets of vertices) and adds it to the World. - * If the vertices are convex, they will pass through as supplied. Otherwise, if the vertices are concave, they will be decomposed. Note that this process is not guaranteed to support complex sets of vertices, e.g. ones with holes. - * - * @method Phaser.Physics.Matter.Factory#fromVertices - * @since 3.0.0 - * - * @param {number} x - The X coordinate of the center of the Body. - * @param {number} y - The Y coordinate of the center of the Body. - * @param {(string|array)} vertexSets - The vertices data. Either a path string or an array of vertices. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * @param {boolean} [flagInternal=false] - Flag internal edges (coincident part edges) - * @param {number} [removeCollinear=0.01] - Whether Matter.js will discard collinear edges (to improve performance). - * @param {number} [minimumArea=10] - During decomposition discard parts that have an area less than this. - * - * @return {MatterJS.BodyType} A Matter JS Body. - */ - fromVertices: function (x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) - { - if (typeof vertexSets === 'string') - { - vertexSets = Vertices.fromPath(vertexSets); - } +/***/ 19242: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var body = Bodies.fromVertices(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.world.add(body); +var CullBounds = __webpack_require__(53945); +var RunCull = __webpack_require__(6987); - return body; - }, +/** + * 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; } - /** - * Creates a body using data exported from the application PhysicsEditor (https://www.codeandweb.com/physicseditor) - * - * The PhysicsEditor file should be loaded as JSON: - * - * ```javascript - * preload () - * { - * this.load.json('vehicles', 'assets/vehicles.json); - * } - * - * create () - * { - * const vehicleShapes = this.cache.json.get('vehicles'); - * this.matter.add.fromPhysicsEditor(400, 300, vehicleShapes.truck); - * } - * ``` - * - * Do not pass the entire JSON file to this method, but instead pass one of the shapes contained within it. - * - * If you pas in an `options` object, any settings in there will override those in the PhysicsEditor config object. - * - * @method Phaser.Physics.Matter.Factory#fromPhysicsEditor - * @since 3.22.0 - * - * @param {number} x - The horizontal world location of the body. - * @param {number} y - The vertical world location of the body. - * @param {any} config - The JSON data exported from PhysicsEditor. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World? - * - * @return {MatterJS.BodyType} A Matter JS Body. - */ - fromPhysicsEditor: function (x, y, config, options, addToWorld) - { - if (addToWorld === undefined) { addToWorld = true; } + outputArray.length = 0; - var body = PhysicsEditorParser.parseBody(x, y, config, options); + var tilemapLayer = layer.tilemapLayer; - if (addToWorld && !this.world.has(body)) - { - this.world.add(body); - } + // Camera world view bounds, snapped for scaled tile size + // Cull Padding values are given in tiles, not pixels - return body; - }, + var bounds = CullBounds(layer, camera); - /** - * Creates a body using the path data from an SVG file. - * - * SVG Parsing requires the pathseg polyfill from https://github.com/progers/pathseg - * - * The SVG file should be loaded as XML, as this method requires the ability to extract - * the path data from it. I.e.: - * - * ```javascript - * preload () - * { - * this.load.xml('face', 'assets/face.svg); - * } - * - * create () - * { - * this.matter.add.fromSVG(400, 300, this.cache.xml.get('face')); - * } - * ``` - * - * @method Phaser.Physics.Matter.Factory#fromSVG - * @since 3.22.0 - * - * @param {number} x - The X coordinate of the body. - * @param {number} y - The Y coordinate of the body. - * @param {object} xml - The SVG Path data. - * @param {number} [scale=1] - Scale the vertices by this amount after creation. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World? - * - * @return {MatterJS.BodyType} A Matter JS Body. - */ - fromSVG: function (x, y, xml, scale, options, addToWorld) + if (tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) { - if (scale === undefined) { scale = 1; } - if (options === undefined) { options = {}; } - if (addToWorld === undefined) { addToWorld = true; } + bounds.left = 0; + bounds.right = layer.width; + bounds.top = 0; + bounds.bottom = layer.height; + } - var path = xml.getElementsByTagName('path'); - var vertexSets = []; + RunCull(layer, bounds, renderOrder, outputArray); - for (var i = 0; i < path.length; i++) - { - var points = Svg.pathToVertices(path[i], 30); + return outputArray; +}; - if (scale !== 1) - { - Vertices.scale(points, scale, scale); - } +module.exports = StaggeredCullTiles; - vertexSets.push(points); - } - var body = Bodies.fromVertices(x, y, vertexSets, options); +/***/ }), - if (addToWorld) - { - this.world.add(body); - } +/***/ 33388: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return body; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Creates a body using the supplied physics data, as provided by a JSON file. - * - * The data file should be loaded as JSON: - * - * ```javascript - * preload () - * { - * this.load.json('ninjas', 'assets/ninjas.json); - * } - * - * create () - * { - * const ninjaShapes = this.cache.json.get('ninjas'); - * - * this.matter.add.fromJSON(400, 300, ninjaShapes.shinobi); - * } - * ``` - * - * Do not pass the entire JSON file to this method, but instead pass one of the shapes contained within it. - * - * If you pas in an `options` object, any settings in there will override those in the config object. - * - * The structure of the JSON file is as follows: - * - * ```text - * { - * 'generator_info': // The name of the application that created the JSON data - * 'shapeName': { - * 'type': // The type of body - * 'label': // Optional body label - * 'vertices': // An array, or an array of arrays, containing the vertex data in x/y object pairs - * } - * } - * ``` - * - * At the time of writing, only the Phaser Physics Tracer App exports in this format. - * - * @method Phaser.Physics.Matter.Factory#fromJSON - * @since 3.22.0 - * - * @param {number} x - The X coordinate of the body. - * @param {number} y - The Y coordinate of the body. - * @param {any} config - The JSON physics data. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World? - * - * @return {MatterJS.BodyType} A Matter JS Body. - */ - fromJSON: function (x, y, config, options, addToWorld) - { - if (options === undefined) { options = {}; } - if (addToWorld === undefined) { addToWorld = true; } +var Vector2 = __webpack_require__(93736); - var body = PhysicsJSONParser.parseBody(x, y, config, options); +/** + * 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(); } - if (body && addToWorld) - { - this.world.add(body); - } + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; - return body; - }, + var layerWorldX = 0; + var layerWorldY = 0; - /** - * Create a new composite containing Matter Image objects created in a grid arrangement. - * This function uses the body bounds to prevent overlaps. - * - * @method Phaser.Physics.Matter.Factory#imageStack - * @since 3.0.0 - * - * @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. Set to `null` to skip this value. - * @param {number} x - The horizontal position of this composite in the world. - * @param {number} y - The vertical position of this composite in the world. - * @param {number} columns - The number of columns in the grid. - * @param {number} rows - The number of rows in the grid. - * @param {number} [columnGap=0] - The distance between each column. - * @param {number} [rowGap=0] - The distance between each row. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {MatterJS.CompositeType} A Matter JS Composite Stack. - */ - imageStack: function (key, frame, x, y, columns, rows, columnGap, rowGap, options) + if (tilemapLayer) { - if (columnGap === undefined) { columnGap = 0; } - if (rowGap === undefined) { rowGap = 0; } - if (options === undefined) { options = {}; } - - var world = this.world; - var displayList = this.sys.displayList; + if (!camera) { camera = tilemapLayer.scene.cameras.main; } - options.addToWorld = false; + layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); - var stack = Composites.stack(x, y, columns, rows, columnGap, rowGap, function (x, y) - { - var image = new MatterImage(world, x, y, key, frame, options); + tileWidth *= tilemapLayer.scaleX; - displayList.add(image); + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - return image.body; - }); + tileHeight *= tilemapLayer.scaleY; + } - world.add(stack); + var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2); + var y = layerWorldY + tileY * (tileHeight / 2); - return stack; - }, + return point.set(x, y); +}; - /** - * Create a new composite containing bodies created in the callback in a grid arrangement. - * - * This function uses the body bounds to prevent overlaps. - * - * @method Phaser.Physics.Matter.Factory#stack - * @since 3.0.0 - * - * @param {number} x - The horizontal position of this composite in the world. - * @param {number} y - The vertical position of this composite in the world. - * @param {number} columns - The number of columns in the grid. - * @param {number} rows - The number of rows in the grid. - * @param {number} columnGap - The distance between each column. - * @param {number} rowGap - The distance between each row. - * @param {function} callback - The callback that creates the stack. - * - * @return {MatterJS.CompositeType} A new composite containing objects created in the callback. - */ - stack: function (x, y, columns, rows, columnGap, rowGap, callback) - { - var stack = Composites.stack(x, y, columns, rows, columnGap, rowGap, callback); +module.exports = StaggeredTileToWorldXY; - this.world.add(stack); - return stack; - }, +/***/ }), - /** - * Create a new composite containing bodies created in the callback in a pyramid arrangement. - * This function uses the body bounds to prevent overlaps. - * - * @method Phaser.Physics.Matter.Factory#pyramid - * @since 3.0.0 - * - * @param {number} x - The horizontal position of this composite in the world. - * @param {number} y - The vertical position of this composite in the world. - * @param {number} columns - The number of columns in the pyramid. - * @param {number} rows - The number of rows in the pyramid. - * @param {number} columnGap - The distance between each column. - * @param {number} rowGap - The distance between each row. - * @param {function} callback - The callback function to be invoked. - * - * @return {MatterJS.CompositeType} A Matter JS Composite pyramid. - */ - pyramid: function (x, y, columns, rows, columnGap, rowGap, callback) - { - var stack = Composites.pyramid(x, y, columns, rows, columnGap, rowGap, callback); +/***/ 84132: +/***/ ((module) => { - this.world.add(stack); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return stack; - }, +/** + * 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; - /** - * Chains all bodies in the given composite together using constraints. - * - * @method Phaser.Physics.Matter.Factory#chain - * @since 3.0.0 - * - * @param {MatterJS.CompositeType} composite - The composite in which all bodies will be chained together sequentially. - * @param {number} xOffsetA - The horizontal offset of the BodyA constraint. This is a percentage based on the body size, not a world position. - * @param {number} yOffsetA - The vertical offset of the BodyA constraint. This is a percentage based on the body size, not a world position. - * @param {number} xOffsetB - The horizontal offset of the BodyB constraint. This is a percentage based on the body size, not a world position. - * @param {number} yOffsetB - The vertical offset of the BodyB constraint. This is a percentage based on the body size, not a world position. - * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. - * - * @return {MatterJS.CompositeType} The original composite that was passed to this method. - */ - chain: function (composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) + if (tilemapLayer) { - return Composites.chain(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options); - }, + if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } - /** - * Connects bodies in the composite with constraints in a grid pattern, with optional cross braces. - * - * @method Phaser.Physics.Matter.Factory#mesh - * @since 3.0.0 - * - * @param {MatterJS.CompositeType} composite - The composite in which all bodies will be chained together. - * @param {number} columns - The number of columns in the mesh. - * @param {number} rows - The number of rows in the mesh. - * @param {boolean} crossBrace - Create cross braces for the mesh as well? - * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. - * - * @return {MatterJS.CompositeType} The original composite that was passed to this method. - */ - mesh: function (composite, columns, rows, crossBrace, options) - { - return Composites.mesh(composite, columns, rows, crossBrace, options); - }, + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - /** - * Creates a composite with a Newton's Cradle setup of bodies and constraints. - * - * @method Phaser.Physics.Matter.Factory#newtonsCradle - * @since 3.0.0 - * - * @param {number} x - The horizontal position of the start of the cradle. - * @param {number} y - The vertical position of the start of the cradle. - * @param {number} number - The number of balls in the cradle. - * @param {number} size - The radius of each ball in the cradle. - * @param {number} length - The length of the 'string' the balls hang from. - * - * @return {MatterJS.CompositeType} A Newton's cradle composite. - */ - newtonsCradle: function (x, y, number, size, length) - { - var composite = Composites.newtonsCradle(x, y, number, size, length); + tileHeight *= tilemapLayer.scaleY; + } - this.world.add(composite); + return layerWorldY + tileY * (tileHeight / 2) + tileHeight; +}; - return composite; - }, +module.exports = StaggeredTileToWorldY; - /** - * Creates a composite with simple car setup of bodies and constraints. - * - * @method Phaser.Physics.Matter.Factory#car - * @since 3.0.0 - * - * @param {number} x - The horizontal position of the car in the world. - * @param {number} y - The vertical position of the car in the world. - * @param {number} width - The width of the car chasis. - * @param {number} height - The height of the car chasis. - * @param {number} wheelSize - The radius of the car wheels. - * - * @return {MatterJS.CompositeType} A new composite car body. - */ - car: function (x, y, width, height, wheelSize) - { - var composite = Composites.car(x, y, width, height, wheelSize); - this.world.add(composite); +/***/ }), - return composite; - }, +/***/ 90562: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Creates a simple soft body like object. - * - * @method Phaser.Physics.Matter.Factory#softBody - * @since 3.0.0 - * - * @param {number} x - The horizontal position of this composite in the world. - * @param {number} y - The vertical position of this composite in the world. - * @param {number} columns - The number of columns in the Composite. - * @param {number} rows - The number of rows in the Composite. - * @param {number} columnGap - The distance between each column. - * @param {number} rowGap - The distance between each row. - * @param {boolean} crossBrace - `true` to create cross braces between the bodies, or `false` to create just straight braces. - * @param {number} particleRadius - The radius of this circlular composite. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [particleOptions] - An optional Body configuration object that is used to set initial Body properties on creation. - * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [constraintOptions] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. - * - * @return {MatterJS.CompositeType} A new composite simple soft body. - */ - softBody: function (x, y, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) - { - var composite = Composites.softBody(x, y, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.world.add(composite); +var Vector2 = __webpack_require__(93736); - return composite; - }, +/** + * 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(); } - /** - * This method is an alias for `Factory.constraint`. - * - * Constraints (or joints) are used for specifying that a fixed distance must be maintained - * between two bodies, or a body and a fixed world-space position. - * - * The stiffness of constraints can be modified to create springs or elastic. - * - * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` - * value (e.g. `0.7` or above). - * - * If the constraint is unstable, try lowering the `stiffness` value and / or increasing - * `constraintIterations` within the Matter Config. - * - * For compound bodies, constraints must be applied to the parent body and not one of its parts. - * - * @method Phaser.Physics.Matter.Factory#joint - * @since 3.0.0 - * - * @param {MatterJS.BodyType} bodyA - The first possible `Body` that this constraint is attached to. - * @param {MatterJS.BodyType} bodyB - The second possible `Body` that this constraint is attached to. - * @param {number} [length] - A Number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. - * @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring. - * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. - * - * @return {MatterJS.ConstraintType} A Matter JS Constraint. - */ - joint: function (bodyA, bodyB, length, stiffness, options) - { - return this.constraint(bodyA, bodyB, length, stiffness, options); - }, + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; - /** - * This method is an alias for `Factory.constraint`. - * - * Constraints (or joints) are used for specifying that a fixed distance must be maintained - * between two bodies, or a body and a fixed world-space position. - * - * The stiffness of constraints can be modified to create springs or elastic. - * - * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` - * value (e.g. `0.7` or above). - * - * If the constraint is unstable, try lowering the `stiffness` value and / or increasing - * `constraintIterations` within the Matter Config. - * - * For compound bodies, constraints must be applied to the parent body and not one of its parts. - * - * @method Phaser.Physics.Matter.Factory#spring - * @since 3.0.0 - * - * @param {MatterJS.BodyType} bodyA - The first possible `Body` that this constraint is attached to. - * @param {MatterJS.BodyType} bodyB - The second possible `Body` that this constraint is attached to. - * @param {number} [length] - A Number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. - * @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring. - * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. - * - * @return {MatterJS.ConstraintType} A Matter JS Constraint. - */ - spring: function (bodyA, bodyB, length, stiffness, options) + if (tilemapLayer) { - return this.constraint(bodyA, bodyB, length, stiffness, options); - }, + if (!camera) { camera = tilemapLayer.scene.cameras.main; } - /** - * Constraints (or joints) are used for specifying that a fixed distance must be maintained - * between two bodies, or a body and a fixed world-space position. - * - * The stiffness of constraints can be modified to create springs or elastic. - * - * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` - * value (e.g. `0.7` or above). - * - * If the constraint is unstable, try lowering the `stiffness` value and / or increasing - * `constraintIterations` within the Matter Config. - * - * For compound bodies, constraints must be applied to the parent body and not one of its parts. - * - * @method Phaser.Physics.Matter.Factory#constraint - * @since 3.0.0 - * - * @param {MatterJS.BodyType} bodyA - The first possible `Body` that this constraint is attached to. - * @param {MatterJS.BodyType} bodyB - The second possible `Body` that this constraint is attached to. - * @param {number} [length] - A Number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. - * @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring. - * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. - * - * @return {MatterJS.ConstraintType} A Matter JS Constraint. - */ - constraint: function (bodyA, bodyB, length, stiffness, options) - { - if (stiffness === undefined) { stiffness = 1; } - if (options === undefined) { options = {}; } + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll - options.bodyA = (bodyA.type === 'body') ? bodyA : bodyA.body; - options.bodyB = (bodyB.type === 'body') ? bodyB : bodyB.body; + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - if (!isNaN(length)) - { - options.length = length; - } + tileHeight *= tilemapLayer.scaleY; - options.stiffness = stiffness; + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's horizontal scroll - var constraint = Constraint.create(options); + worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); - this.world.add(constraint); + tileWidth *= tilemapLayer.scaleX; + } - return constraint; - }, + 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; - /** - * Constraints (or joints) are used for specifying that a fixed distance must be maintained - * between two bodies, or a body and a fixed world-space position. - * - * A world constraint has only one body, you should specify a `pointA` position in - * the constraint options parameter to attach the constraint to the world. - * - * The stiffness of constraints can be modified to create springs or elastic. - * - * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` - * value (e.g. `0.7` or above). - * - * If the constraint is unstable, try lowering the `stiffness` value and / or increasing - * `constraintIterations` within the Matter Config. - * - * For compound bodies, constraints must be applied to the parent body and not one of its parts. - * - * @method Phaser.Physics.Matter.Factory#worldConstraint - * @since 3.0.0 - * - * @param {MatterJS.BodyType} body - The Matter `Body` that this constraint is attached to. - * @param {number} [length] - A number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. - * @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring. - * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. - * - * @return {MatterJS.ConstraintType} A Matter JS Constraint. - */ - worldConstraint: function (body, length, stiffness, options) - { - if (stiffness === undefined) { stiffness = 1; } - if (options === undefined) { options = {}; } + return point.set(x, y); +}; - options.bodyB = (body.type === 'body') ? body : body.body; +module.exports = StaggeredWorldToTileXY; - if (!isNaN(length)) - { - options.length = length; - } - options.stiffness = stiffness; +/***/ }), - var constraint = Constraint.create(options); +/***/ 3689: +/***/ ((module) => { - this.world.add(constraint); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return constraint; - }, +/** + * 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; - /** - * This method is an alias for `Factory.pointerConstraint`. - * - * A Pointer Constraint is a special type of constraint that allows you to click - * and drag bodies in a Matter World. It monitors the active Pointers in a Scene, - * and when one is pressed down it checks to see if that hit any part of any active - * body in the world. If it did, and the body has input enabled, it will begin to - * drag it until either released, or you stop it via the `stopDrag` method. - * - * You can adjust the stiffness, length and other properties of the constraint via - * the `options` object on creation. - * - * @method Phaser.Physics.Matter.Factory#mouseSpring - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. - * - * @return {MatterJS.ConstraintType} A Matter JS Constraint. - */ - mouseSpring: function (options) + if (tilemapLayer) { - return this.pointerConstraint(options); - }, + if (!camera) { camera = tilemapLayer.scene.cameras.main; } - /** - * A Pointer Constraint is a special type of constraint that allows you to click - * and drag bodies in a Matter World. It monitors the active Pointers in a Scene, - * and when one is pressed down it checks to see if that hit any part of any active - * body in the world. If it did, and the body has input enabled, it will begin to - * drag it until either released, or you stop it via the `stopDrag` method. - * - * You can adjust the stiffness, length and other properties of the constraint via - * the `options` object on creation. - * - * @method Phaser.Physics.Matter.Factory#pointerConstraint - * @since 3.0.0 - * - * @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation. - * - * @return {MatterJS.ConstraintType} A Matter JS Constraint. - */ - pointerConstraint: function (options) - { - if (options === undefined) { options = {}; } + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll - if (!options.hasOwnProperty('render')) - { - options.render = { visible: false }; - } + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - var pointerConstraint = new PointerConstraint(this.scene, this.world, options); + tileHeight *= tilemapLayer.scaleY; + } - this.world.add(pointerConstraint.constraint); + return (snapToFloor) ? Math.floor(worldY / (tileHeight / 2)) : worldY / (tileHeight / 2); +}; - return pointerConstraint; - }, +module.exports = StaggeredWorldToTileY; - /** - * Creates a Matter Physics Image Game Object. - * - * An Image is a light-weight Game Object useful for the display of static images in your game, - * such as logos, backgrounds, scenery or other non-animated elements. Images can have input - * events and physics bodies, or be tweened, tinted or scrolled. The main difference between an - * Image and a Sprite is that you cannot animate an Image as they do not have the Animation component. - * - * @method Phaser.Physics.Matter.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} 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. Set to `null` to skip this value. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {Phaser.Physics.Matter.Image} The Matter Image Game Object. - */ - image: function (x, y, key, frame, options) - { - var image = new MatterImage(this.world, x, y, key, frame, options); - this.sys.displayList.add(image); +/***/ }), - return image; - }, +/***/ 55217: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Creates a wrapper around a Tile that provides access to a corresponding Matter body. A tile can only - * have one Matter body associated with it. You can either pass in an existing Matter body for - * the tile or allow the constructor to create the corresponding body for you. If the Tile has a - * collision group (defined in Tiled), those shapes will be used to create the body. If not, the - * tile's rectangle bounding box will be used. - * - * The corresponding body will be accessible on the Tile itself via Tile.physics.matterBody. - * - * Note: not all Tiled collision shapes are supported. See - * Phaser.Physics.Matter.TileBody#setFromTileCollision for more information. - * - * @method Phaser.Physics.Matter.Factory#tileBody - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.Tile} tile - The target tile that should have a Matter body. - * @param {Phaser.Types.Physics.Matter.MatterTileOptions} [options] - Options to be used when creating the Matter body. - * - * @return {Phaser.Physics.Matter.TileBody} The Matter Tile Body Game Object. - */ - tileBody: function (tile, options) - { - return new MatterTileBody(this.world, tile, options); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Creates a Matter Physics Sprite Game Object. - * - * A Sprite Game Object is used for the display of both static and animated images in your game. - * Sprites can have input events and physics bodies. They can also be tweened, tinted, scrolled - * and animated. - * - * The main difference between a Sprite and an Image Game Object is that you cannot animate Images. - * As such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation - * Component. If you do not require animation then you can safely use Images to replace Sprites in all cases. - * - * @method Phaser.Physics.Matter.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. Set to `null` to skip this value. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {Phaser.Physics.Matter.Sprite} The Matter Sprite Game Object. - */ - sprite: function (x, y, key, frame, options) +var GetTilesWithin = __webpack_require__(50811); + +/** + * 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. + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + */ +var SwapByIndex = function (indexA, indexB, tileX, tileY, width, height, layer) +{ + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + + for (var i = 0; i < tiles.length; i++) { - var sprite = new MatterSprite(this.world, x, y, key, frame, options); + if (tiles[i]) + { + if (tiles[i].index === indexA) + { + tiles[i].index = indexB; + } + else if (tiles[i].index === indexB) + { + tiles[i].index = indexA; + } + } + } +}; - this.sys.displayList.add(sprite); - this.sys.updateList.add(sprite); +module.exports = SwapByIndex; - return sprite; - }, - /** - * Takes an existing Game Object and injects all of the Matter Components into it. - * - * This enables you to use component methods such as `setVelocity` or `isSensor` directly from - * this Game Object. - * - * You can also pass in either a Matter Body Configuration object, or a Matter Body instance - * to link with this Game Object. - * - * @method Phaser.Physics.Matter.Factory#gameObject - * @since 3.3.0 - * - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to inject the Matter Components in to. - * @param {(Phaser.Types.Physics.Matter.MatterBodyConfig|MatterJS.Body)} [options] - A Matter Body configuration object, or an instance of a Matter Body. - * @param {boolean} [addToWorld=true] - Add this Matter Body to the World? - * - * @return {(Phaser.Physics.Matter.Image|Phaser.Physics.Matter.Sprite|Phaser.GameObjects.GameObject)} The Game Object that had the Matter Components injected into it. - */ - gameObject: function (gameObject, options, addToWorld) - { - return MatterGameObject(this.world, gameObject, options, addToWorld); - }, +/***/ }), - /** - * Destroys this Factory. - * - * @method Phaser.Physics.Matter.Factory#destroy - * @since 3.5.0 - */ - destroy: function () +/***/ 44150: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the + * layer's position, scale and scroll. + * + * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {number} + */ +var TileToWorldX = function (tileX, camera, layer) +{ + var tileWidth = layer.baseTileWidth; + var tilemapLayer = layer.tilemapLayer; + var layerWorldX = 0; + + if (tilemapLayer) { - this.world = null; - this.scene = null; - this.sys = null; + if (!camera) { camera = tilemapLayer.scene.cameras.main; } + + layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX); + + tileWidth *= tilemapLayer.scaleX; } -}); + return layerWorldX + tileX * tileWidth; +}; -module.exports = Factory; +module.exports = TileToWorldX; /***/ }), -/* 1395 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 46836: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Components = __webpack_require__(249); -var GetFastValue = __webpack_require__(2); -var Vector2 = __webpack_require__(3); +var TileToWorldX = __webpack_require__(44150); +var TileToWorldY = __webpack_require__(42477); +var Vector2 = __webpack_require__(93736); /** - * Internal function to check if the object has a getter or setter. + * 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 hasGetterOrSetter - * @private + * @function Phaser.Tilemaps.Components.TileToWorldXY + * @since 3.0.0 * - * @param {object} def - The object to check. + * @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 {boolean} True if it has a getter or setter, otherwise false. + * @return {Phaser.Math.Vector2} The XY location in world coordinates. */ -function hasGetterOrSetter (def) +var TileToWorldXY = function (tileX, tileY, point, camera, layer) { - return (!!def.get && typeof def.get === 'function') || (!!def.set && typeof def.set === 'function'); -} + if (!point) { point = new Vector2(0, 0); } + + point.x = TileToWorldX(tileX, camera, layer); + point.y = TileToWorldY(tileY, camera, layer); + + return point; +}; + +module.exports = TileToWorldXY; + + +/***/ }), + +/***/ 42477: +/***/ ((module) => { /** - * A Matter Game Object is a generic object that allows you to combine any Phaser Game Object, - * including those you have extended or created yourself, with all of the Matter Components. - * - * This enables you to use component methods such as `setVelocity` or `isSensor` directly from - * this Game Object. + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the + * layer's position, scale and scroll. * - * @function Phaser.Physics.Matter.MatterGameObject - * @since 3.3.0 + * @function Phaser.Tilemaps.Components.TileToWorldY + * @since 3.0.0 * - * @param {Phaser.Physics.Matter.World} world - The Matter world to add the body to. - * @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will have the Matter body applied to it. - * @param {(Phaser.Types.Physics.Matter.MatterBodyConfig|MatterJS.Body)} [options] - A Matter Body configuration object, or an instance of a Matter Body. - * @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World? + * @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 {Phaser.GameObjects.GameObject} The Game Object that was created with the Matter body. + * @return {number} The Y location in world coordinates. */ -var MatterGameObject = function (world, gameObject, options, addToWorld) +var TileToWorldY = function (tileY, camera, layer) { - if (options === undefined) { options = {}; } - if (addToWorld === undefined) { addToWorld = true; } + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + var layerWorldY = 0; - var x = gameObject.x; - var y = gameObject.y; + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } - // Temp body pos to avoid body null checks - gameObject.body = { - temp: true, - position: { - x: x, - y: y - } - }; + layerWorldY = (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - var mixins = [ - Components.Bounce, - Components.Collision, - Components.Force, - Components.Friction, - Components.Gravity, - Components.Mass, - Components.Sensor, - Components.SetBody, - Components.Sleep, - Components.Static, - Components.Transform, - Components.Velocity - ]; + tileHeight *= tilemapLayer.scaleY; + } - // First let's inject all of the components into the Game Object - mixins.forEach(function (mixin) - { - for (var key in mixin) - { - if (hasGetterOrSetter(mixin[key])) - { - Object.defineProperty(gameObject, key, { - get: mixin[key].get, - set: mixin[key].set - }); - } - else - { - Object.defineProperty(gameObject, key, {value: mixin[key]}); - } - } + return layerWorldY + tileY * tileHeight; +}; - }); +module.exports = TileToWorldY; - gameObject.world = world; - gameObject._tempVec2 = new Vector2(x, y); +/***/ }), - if (options.hasOwnProperty('type') && options.type === 'body') +/***/ 39677: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetTilesWithin = __webpack_require__(50811); + +/** + * 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. + * + * @function Phaser.Tilemaps.Components.WeightedRandomize + * @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 {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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + */ +var WeightedRandomize = function (tileX, tileY, width, height, weightedIndexes, layer) +{ + if (!weightedIndexes) { return; } + + var i; + var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); + + var weightTotal = 0; + + for (i = 0; i < weightedIndexes.length; i++) { - gameObject.setExistingBody(options, addToWorld); + weightTotal += weightedIndexes[i].weight; } - else + + if (weightTotal <= 0) { return; } + + for (i = 0; i < tiles.length; i++) { - var shape = GetFastValue(options, 'shape', null); + var rand = Math.random() * weightTotal; + var sum = 0; + var randomIndex = -1; - if (!shape) + for (var j = 0; j < weightedIndexes.length; j++) { - shape = 'rectangle'; + sum += weightedIndexes[j].weight; + + if (rand <= sum) + { + var chosen = weightedIndexes[j].index; + + randomIndex = Array.isArray(chosen) + ? chosen[Math.floor(Math.random() * chosen.length)] + : chosen; + break; + } } - options.addToWorld = addToWorld; - - gameObject.setBody(shape, options); + tiles[i].index = randomIndex; } - - return gameObject; }; -module.exports = MatterGameObject; +module.exports = WeightedRandomize; /***/ }), -/* 1396 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 806: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var Components = __webpack_require__(249); -var GameObject = __webpack_require__(15); -var GetFastValue = __webpack_require__(2); -var Image = __webpack_require__(125); -var Pipeline = __webpack_require__(167); -var Vector2 = __webpack_require__(3); +var WorldToTileXY = __webpack_require__(45676); +var Vector2 = __webpack_require__(93736); + +var tempVec = new Vector2(); /** - * @classdesc - * A Matter Physics Image Game Object. - * - * An Image is a light-weight Game Object useful for the display of static images in your game, - * such as logos, backgrounds, scenery or other non-animated elements. Images can have input - * events and physics bodies, or be tweened, tinted or scrolled. The main difference between an - * Image and a Sprite is that you cannot animate an Image as they do not have the Animation component. + * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the + * layer's position, scale and scroll. * - * @class Image - * @extends Phaser.GameObjects.Image - * @memberof Phaser.Physics.Matter - * @constructor + * @function Phaser.Tilemaps.Components.WorldToTileX * @since 3.0.0 * - * @extends Phaser.Physics.Matter.Components.Bounce - * @extends Phaser.Physics.Matter.Components.Collision - * @extends Phaser.Physics.Matter.Components.Force - * @extends Phaser.Physics.Matter.Components.Friction - * @extends Phaser.Physics.Matter.Components.Gravity - * @extends Phaser.Physics.Matter.Components.Mass - * @extends Phaser.Physics.Matter.Components.Sensor - * @extends Phaser.Physics.Matter.Components.SetBody - * @extends Phaser.Physics.Matter.Components.Sleep - * @extends Phaser.Physics.Matter.Components.Static - * @extends Phaser.Physics.Matter.Components.Transform - * @extends Phaser.Physics.Matter.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 {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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. * - * @param {Phaser.Physics.Matter.World} world - A reference to the Matter.World instance that this body belongs to. - * @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. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * @return {number} The X location in tile units. */ -var MatterImage = new Class({ +var WorldToTileX = function (worldX, snapToFloor, camera, layer) +{ + WorldToTileXY(worldX, 0, snapToFloor, tempVec, camera, layer); - Extends: Image, + return tempVec.x; +}; - Mixins: [ - Components.Bounce, - Components.Collision, - Components.Force, - Components.Friction, - Components.Gravity, - Components.Mass, - Components.Sensor, - Components.SetBody, - Components.Sleep, - Components.Static, - Components.Transform, - Components.Velocity, - Pipeline - ], +module.exports = WorldToTileX; - initialize: - function MatterImage (world, x, y, texture, frame, options) - { - GameObject.call(this, world.scene, 'Image'); +/***/ }), - /** - * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. - * - * @name Phaser.Physics.Matter.Image#_crop - * @type {object} - * @private - * @since 3.24.0 - */ - this._crop = this.resetCropObject(); +/***/ 45676: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - this.setTexture(texture, frame); - this.setSizeToFrame(); - this.setOrigin(); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A reference to the Matter.World instance that this body belongs to. - * - * @name Phaser.Physics.Matter.Image#world - * @type {Phaser.Physics.Matter.World} - * @since 3.0.0 - */ - this.world = world; +var Vector2 = __webpack_require__(93736); - /** - * An internal temp vector used for velocity and force calculations. - * - * @name Phaser.Physics.Matter.Image#_tempVec2 - * @type {Phaser.Math.Vector2} - * @private - * @since 3.0.0 - */ - this._tempVec2 = new Vector2(x, y); +/** + * 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(); } - var shape = GetFastValue(options, 'shape', null); + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; - if (shape) - { - this.setBody(shape, options); - } - else - { - this.setRectangle(this.width, this.height, options); - } + if (tilemapLayer) + { + if (!camera) { camera = tilemapLayer.scene.cameras.main; } - this.setPosition(x, y); + // 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)); + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); - this.initPipeline(); + tileWidth *= tilemapLayer.scaleX; + tileHeight *= tilemapLayer.scaleY; } -}); + var x = worldX / tileWidth; + var y = worldY / tileHeight; -module.exports = MatterImage; + if (snapToFloor) + { + x = Math.floor(x); + y = Math.floor(y); + } + + return point.set(x, y); +}; + +module.exports = WorldToTileXY; /***/ }), -/* 1397 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 70520: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var AnimationState = __webpack_require__(164); -var Class = __webpack_require__(0); -var Components = __webpack_require__(249); -var GameObject = __webpack_require__(15); -var GetFastValue = __webpack_require__(2); -var Pipeline = __webpack_require__(167); -var Sprite = __webpack_require__(73); -var Vector2 = __webpack_require__(3); +var WorldToTileXY = __webpack_require__(45676); +var Vector2 = __webpack_require__(93736); + +var tempVec = new Vector2(); /** - * @classdesc - * A Matter Physics Sprite Game Object. + * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the + * layer's position, scale and scroll. * - * A Sprite Game Object is used for the display of both static and animated images in your game. - * Sprites can have input events and physics bodies. They can also be tweened, tinted, scrolled - * and animated. + * @function Phaser.Tilemaps.Components.WorldToTileY + * @since 3.0.0 * - * The main difference between a Sprite and an Image Game Object is that you cannot animate Images. - * As such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation - * Component. If you do not require animation then you can safely use Images to replace Sprites in all cases. + * @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. * - * @class Sprite - * @extends Phaser.GameObjects.Sprite - * @memberof Phaser.Physics.Matter - * @constructor - * @since 3.0.0 + * @return {number} The Y location in tile units. + */ +var WorldToTileY = function (worldY, snapToFloor, camera, layer) +{ + WorldToTileXY(0, worldY, snapToFloor, tempVec, camera, layer); + + return tempVec.y; +}; + +module.exports = WorldToTileY; + + +/***/ }), + +/***/ 5047: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * @namespace Phaser.Tilemaps.Components + */ + +module.exports = { + + CalculateFacesAt: __webpack_require__(92839), + CalculateFacesWithin: __webpack_require__(60386), + CheckIsoBounds: __webpack_require__(13125), + Copy: __webpack_require__(17347), + CreateFromTiles: __webpack_require__(93604), + CullBounds: __webpack_require__(71586), + CullTiles: __webpack_require__(381), + Fill: __webpack_require__(97734), + FilterTiles: __webpack_require__(63555), + FindByIndex: __webpack_require__(37982), + FindTile: __webpack_require__(48297), + ForEachTile: __webpack_require__(80916), + GetCullTilesFunction: __webpack_require__(31493), + GetTileAt: __webpack_require__(15494), + GetTileAtWorldXY: __webpack_require__(24640), + GetTileCorners: __webpack_require__(48495), + GetTileCornersFunction: __webpack_require__(7160), + GetTilesWithin: __webpack_require__(50811), + GetTilesWithinShape: __webpack_require__(31674), + GetTilesWithinWorldXY: __webpack_require__(44662), + GetTileToWorldXFunction: __webpack_require__(16884), + GetTileToWorldXYFunction: __webpack_require__(68182), + GetTileToWorldYFunction: __webpack_require__(3752), + GetWorldToTileXFunction: __webpack_require__(29296), + GetWorldToTileXYFunction: __webpack_require__(32688), + GetWorldToTileYFunction: __webpack_require__(74326), + HasTileAt: __webpack_require__(46598), + HasTileAtWorldXY: __webpack_require__(28654), + HexagonalCullBounds: __webpack_require__(6358), + HexagonalCullTiles: __webpack_require__(37524), + HexagonalGetTileCorners: __webpack_require__(63634), + HexagonalTileToWorldXY: __webpack_require__(21715), + HexagonalWorldToTileXY: __webpack_require__(11516), + IsInLayerBounds: __webpack_require__(62839), + IsometricCullTiles: __webpack_require__(20887), + IsometricTileToWorldXY: __webpack_require__(21808), + IsometricWorldToTileXY: __webpack_require__(18750), + PutTileAt: __webpack_require__(29003), + PutTileAtWorldXY: __webpack_require__(48565), + PutTilesAt: __webpack_require__(56547), + Randomize: __webpack_require__(91180), + RemoveTileAt: __webpack_require__(929), + RemoveTileAtWorldXY: __webpack_require__(17384), + RenderDebug: __webpack_require__(93763), + ReplaceByIndex: __webpack_require__(51202), + RunCull: __webpack_require__(6987), + SetCollision: __webpack_require__(51710), + SetCollisionBetween: __webpack_require__(15216), + SetCollisionByExclusion: __webpack_require__(33158), + SetCollisionByProperty: __webpack_require__(4180), + SetCollisionFromCollisionGroup: __webpack_require__(18625), + SetLayerCollisionIndex: __webpack_require__(91181), + SetTileCollision: __webpack_require__(68234), + SetTileIndexCallback: __webpack_require__(11628), + SetTileLocationCallback: __webpack_require__(72732), + Shuffle: __webpack_require__(34397), + StaggeredCullBounds: __webpack_require__(53945), + StaggeredCullTiles: __webpack_require__(19242), + StaggeredTileToWorldXY: __webpack_require__(33388), + StaggeredTileToWorldY: __webpack_require__(84132), + StaggeredWorldToTileXY: __webpack_require__(90562), + StaggeredWorldToTileY: __webpack_require__(3689), + SwapByIndex: __webpack_require__(55217), + TileToWorldX: __webpack_require__(44150), + TileToWorldXY: __webpack_require__(46836), + TileToWorldY: __webpack_require__(42477), + WeightedRandomize: __webpack_require__(39677), + WorldToTileX: __webpack_require__(806), + WorldToTileXY: __webpack_require__(45676), + WorldToTileY: __webpack_require__(70520) + +}; + + +/***/ }), + +/***/ 12920: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Tilemap constants for orientation. * - * @extends Phaser.Physics.Matter.Components.Bounce - * @extends Phaser.Physics.Matter.Components.Collision - * @extends Phaser.Physics.Matter.Components.Force - * @extends Phaser.Physics.Matter.Components.Friction - * @extends Phaser.Physics.Matter.Components.Gravity - * @extends Phaser.Physics.Matter.Components.Mass - * @extends Phaser.Physics.Matter.Components.Sensor - * @extends Phaser.Physics.Matter.Components.SetBody - * @extends Phaser.Physics.Matter.Components.Sleep - * @extends Phaser.Physics.Matter.Components.Static - * @extends Phaser.Physics.Matter.Components.Transform - * @extends Phaser.Physics.Matter.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 + * @namespace Phaser.Tilemaps.Orientation + * @memberof Phaser.Tilemaps + * @since 3.50.0 + */ + +/** + * Phaser Tilemap constants for orientation. * - * @param {Phaser.Physics.Matter.World} world - A reference to the Matter.World instance that this body belongs to. - * @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. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. + * To find out what each mode does please see [Phaser.Tilemaps.Orientation]{@link Phaser.Tilemaps.Orientation}. + * + * @typedef {Phaser.Tilemaps.Orientation} Phaser.Tilemaps.OrientationType + * @memberof Phaser.Tilemaps + * @since 3.50.0 */ -var MatterSprite = new Class({ - Extends: Sprite, +module.exports = { - Mixins: [ - Components.Bounce, - Components.Collision, - Components.Force, - Components.Friction, - Components.Gravity, - Components.Mass, - Components.Sensor, - Components.SetBody, - Components.Sleep, - Components.Static, - Components.Transform, - Components.Velocity, - Pipeline - ], + /** + * Orthogonal Tilemap orientation constant. + * + * @name Phaser.Tilemaps.Orientation.ORTHOGONAL + * @type {number} + * @const + * @since 3.50.0 + */ + ORTHOGONAL: 0, - initialize: + /** + * Isometric Tilemap orientation constant. + * + * @name Phaser.Tilemaps.Orientation.ISOMETRIC + * @type {number} + * @const + * @since 3.50.0 + */ + ISOMETRIC: 1, - function MatterSprite (world, x, y, texture, frame, options) - { - GameObject.call(this, world.scene, 'Sprite'); + /** + * Staggered Tilemap orientation constant. + * + * @name Phaser.Tilemaps.Orientation.STAGGERED + * @type {number} + * @const + * @since 3.50.0 + */ + STAGGERED: 2, - /** - * The internal crop data object, as used by `setCrop` and passed to the `Frame.setCropUVs` method. - * - * @name Phaser.Physics.Matter.Sprite#_crop - * @type {object} - * @private - * @since 3.24.0 - */ - this._crop = this.resetCropObject(); + /** + * Hexagonal Tilemap orientation constant. + * + * @name Phaser.Tilemaps.Orientation.HEXAGONAL + * @type {number} + * @const + * @since 3.50.0 + */ + HEXAGONAL: 3 - this.anims = new AnimationState(this); +}; - this.setTexture(texture, frame); - this.setSizeToFrame(); - this.setOrigin(); - /** - * A reference to the Matter.World instance that this body belongs to. - * - * @name Phaser.Physics.Matter.Sprite#world - * @type {Phaser.Physics.Matter.World} - * @since 3.0.0 - */ - this.world = world; +/***/ }), - /** - * An internal temp vector used for velocity and force calculations. - * - * @name Phaser.Physics.Matter.Sprite#_tempVec2 - * @type {Phaser.Math.Vector2} - * @private - * @since 3.0.0 - */ - this._tempVec2 = new Vector2(x, y); +/***/ 84758: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var shape = GetFastValue(options, 'shape', null); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (shape) - { - this.setBody(shape, options); - } - else - { - this.setRectangle(this.width, this.height, options); - } +var CONST = { - this.setPosition(x, y); + ORIENTATION: __webpack_require__(12920) - this.initPipeline(); - } +}; -}); +module.exports = CONST; -module.exports = MatterSprite; + +/***/ }), + +/***/ 52678: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Extend = __webpack_require__(98611); +var CONST = __webpack_require__(84758); + +/** + * @namespace Phaser.Tilemaps + * + * @borrows Phaser.Tilemaps.Orientation.ORTHOGONAL as ORTHOGONAL + * @borrows Phaser.Tilemaps.Orientation.ISOMETRIC as ISOMETRIC + * @borrows Phaser.Tilemaps.Orientation.STAGGERED as STAGGERED + * @borrows Phaser.Tilemaps.Orientation.HEXAGONAL as HEXAGONAL + */ + +var Tilemaps = { + + Components: __webpack_require__(5047), + Parsers: __webpack_require__(34124), + + Formats: __webpack_require__(93560), + ImageCollection: __webpack_require__(97042), + ParseToTilemap: __webpack_require__(15043), + Tile: __webpack_require__(29633), + Tilemap: __webpack_require__(89797), + TilemapCreator: __webpack_require__(4843), + TilemapFactory: __webpack_require__(37940), + Tileset: __webpack_require__(47975), + TilemapLayer: __webpack_require__(87177), + Orientation: __webpack_require__(12920), + + LayerData: __webpack_require__(94990), + MapData: __webpack_require__(16586), + ObjectLayer: __webpack_require__(15256) + +}; + +Tilemaps = Extend(false, Tilemaps, CONST.ORIENTATION); + +module.exports = Tilemaps; /***/ }), -/* 1398 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 94990: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Bounds = __webpack_require__(84); -var Class = __webpack_require__(0); -var Composite = __webpack_require__(118); -var Constraint = __webpack_require__(128); -var Detector = __webpack_require__(273); -var Events = __webpack_require__(272); -var InputEvents = __webpack_require__(51); -var Merge = __webpack_require__(127); -var Sleeping = __webpack_require__(165); -var Vector2 = __webpack_require__(3); -var Vertices = __webpack_require__(64); +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12920); +var GetFastValue = __webpack_require__(72632); /** * @classdesc - * A Pointer Constraint is a special type of constraint that allows you to click - * and drag bodies in a Matter World. It monitors the active Pointers in a Scene, - * and when one is pressed down it checks to see if that hit any part of any active - * body in the world. If it did, and the body has input enabled, it will begin to - * drag it until either released, or you stop it via the `stopDrag` method. - * - * You can adjust the stiffness, length and other properties of the constraint via - * the `options` object on creation. + * A class for representing data about about a layer in a map. Maps are parsed from CSV, Tiled, + * etc. into this format. Tilemap and TilemapLayer objects have a reference + * to this data and use it to look up and perform operations on tiles. * - * @class PointerConstraint - * @memberof Phaser.Physics.Matter + * @class LayerData + * @memberof Phaser.Tilemaps * @constructor * @since 3.0.0 * - * @param {Phaser.Scene} scene - A reference to the Scene to which this Pointer Constraint belongs. - * @param {Phaser.Physics.Matter.World} world - A reference to the Matter World instance to which this Constraint belongs. - * @param {object} [options] - A Constraint configuration object. + * @param {Phaser.Types.Tilemaps.LayerDataConfig} [config] - The Layer Data configuration object. */ -var PointerConstraint = new Class({ +var LayerData = new Class({ initialize: - function PointerConstraint (scene, world, options) + function LayerData (config) { - if (options === undefined) { options = {}; } - - // Defaults - var defaults = { - label: 'Pointer Constraint', - pointA: { x: 0, y: 0 }, - pointB: { x: 0, y: 0 }, - length: 0.01, - stiffness: 0.1, - angularStiffness: 1, - collisionFilter: { - category: 0x0001, - mask: 0xFFFFFFFF, - group: 0 - } - }; + if (config === undefined) { config = {}; } /** - * A reference to the Scene to which this Pointer Constraint belongs. - * This is the same Scene as the Matter World instance. + * The name of the layer, if specified in Tiled. * - * @name Phaser.Physics.Matter.PointerConstraint#scene - * @type {Phaser.Scene} + * @name Phaser.Tilemaps.LayerData#name + * @type {string} * @since 3.0.0 */ - this.scene = scene; + this.name = GetFastValue(config, 'name', 'layer'); /** - * A reference to the Matter World instance to which this Constraint belongs. + * The x offset of where to draw from the top left. * - * @name Phaser.Physics.Matter.PointerConstraint#world - * @type {Phaser.Physics.Matter.World} + * @name Phaser.Tilemaps.LayerData#x + * @type {number} * @since 3.0.0 */ - this.world = world; + this.x = GetFastValue(config, 'x', 0); /** - * The Camera the Pointer was interacting with when the input - * down event was processed. + * The y offset of where to draw from the top left. * - * @name Phaser.Physics.Matter.PointerConstraint#camera - * @type {Phaser.Cameras.Scene2D.Camera} + * @name Phaser.Tilemaps.LayerData#y + * @type {number} * @since 3.0.0 */ - this.camera = null; + this.y = GetFastValue(config, 'y', 0); /** - * A reference to the Input Pointer that activated this Constraint. - * This is set in the `onDown` handler. + * The width of the layer in tiles. * - * @name Phaser.Physics.Matter.PointerConstraint#pointer - * @type {Phaser.Input.Pointer} - * @default null + * @name Phaser.Tilemaps.LayerData#width + * @type {number} * @since 3.0.0 */ - this.pointer = null; + this.width = GetFastValue(config, 'width', 0); /** - * Is this Constraint active or not? - * - * An active constraint will be processed each update. An inactive one will be skipped. - * Use this to toggle a Pointer Constraint on and off. + * The height of the layer in tiles. * - * @name Phaser.Physics.Matter.PointerConstraint#active - * @type {boolean} - * @default true + * @name Phaser.Tilemaps.LayerData#height + * @type {number} * @since 3.0.0 */ - this.active = true; + this.height = GetFastValue(config, 'height', 0); /** - * The internal transformed position. + * The pixel width of the tiles. * - * @name Phaser.Physics.Matter.PointerConstraint#position - * @type {Phaser.Math.Vector2} + * @name Phaser.Tilemaps.LayerData#tileWidth + * @type {number} * @since 3.0.0 */ - this.position = new Vector2(); + this.tileWidth = GetFastValue(config, 'tileWidth', 0); /** - * The body that is currently being dragged, if any. + * The pixel height of the tiles. * - * @name Phaser.Physics.Matter.PointerConstraint#body - * @type {?MatterJS.BodyType} - * @since 3.16.2 + * @name Phaser.Tilemaps.LayerData#tileHeight + * @type {number} + * @since 3.0.0 */ - this.body = null; + this.tileHeight = GetFastValue(config, 'tileHeight', 0); /** - * The part of the body that was clicked on to start the drag. + * The base tile width. * - * @name Phaser.Physics.Matter.PointerConstraint#part - * @type {?MatterJS.BodyType} - * @since 3.16.2 + * @name Phaser.Tilemaps.LayerData#baseTileWidth + * @type {number} + * @since 3.0.0 */ - this.part = null; + this.baseTileWidth = GetFastValue(config, 'baseTileWidth', this.tileWidth); /** - * The native Matter Constraint that is used to attach to bodies. + * The base tile height. * - * @name Phaser.Physics.Matter.PointerConstraint#constraint - * @type {MatterJS.ConstraintType} + * @name Phaser.Tilemaps.LayerData#baseTileHeight + * @type {number} * @since 3.0.0 */ - this.constraint = Constraint.create(Merge(options, defaults)); - - this.world.on(Events.BEFORE_UPDATE, this.update, this); - - scene.sys.input.on(InputEvents.POINTER_DOWN, this.onDown, this); - scene.sys.input.on(InputEvents.POINTER_UP, this.onUp, this); - }, - - /** - * A Pointer has been pressed down onto the Scene. - * - * If this Constraint doesn't have an active Pointer then a hit test is set to - * run against all active bodies in the world during the _next_ call to `update`. - * If a body is found, it is bound to this constraint and the drag begins. - * - * @method Phaser.Physics.Matter.PointerConstraint#onDown - * @since 3.0.0 - * - * @param {Phaser.Input.Pointer} pointer - A reference to the Pointer that was pressed. - */ - onDown: function (pointer) - { - if (!this.pointer) - { - this.pointer = pointer; - this.camera = pointer.camera; - } - }, - - /** - * A Pointer has been released from the Scene. If it was the one this constraint was using, it's cleared. - * - * @method Phaser.Physics.Matter.PointerConstraint#onUp - * @since 3.22.0 - * - * @param {Phaser.Input.Pointer} pointer - A reference to the Pointer that was pressed. - */ - onUp: function (pointer) - { - if (pointer === this.pointer) - { - this.pointer = null; - } - }, - - /** - * Scans all active bodies in the current Matter World to see if any of them - * are hit by the Pointer. The _first one_ found to hit is set as the active contraint - * body. - * - * @method Phaser.Physics.Matter.PointerConstraint#getBody - * @fires Phaser.Physics.Matter.Events#DRAG_START - * @since 3.16.2 - * - * @return {boolean} `true` if a body was found and set, otherwise `false`. - */ - getBody: function (pointer) - { - var pos = this.position; - var constraint = this.constraint; - - this.camera.getWorldPoint(pointer.x, pointer.y, pos); - - var bodies = Composite.allBodies(this.world.localWorld); - - for (var i = 0; i < bodies.length; i++) - { - var body = bodies[i]; - - if (!body.ignorePointer && - Bounds.contains(body.bounds, pos) && - Detector.canCollide(body.collisionFilter, constraint.collisionFilter)) - { - if (this.hitTestBody(body, pos)) - { - this.world.emit(Events.DRAG_START, body, this.part, this); - - return true; - } - } - } - - return false; - }, - - /** - * Scans the current body to determine if a part of it was clicked on. - * If a part is found the body is set as the `constraint.bodyB` property, - * as well as the `body` property of this class. The part is also set. - * - * @method Phaser.Physics.Matter.PointerConstraint#hitTestBody - * @since 3.16.2 - * - * @param {MatterJS.BodyType} body - The Matter Body to check. - * @param {Phaser.Math.Vector2} position - A translated hit test position. - * - * @return {boolean} `true` if a part of the body was hit, otherwise `false`. - */ - hitTestBody: function (body, position) - { - var constraint = this.constraint; - var partsLength = body.parts.length; - - var start = (partsLength > 1) ? 1 : 0; - - for (var i = start; i < partsLength; i++) - { - var part = body.parts[i]; - - if (Vertices.contains(part.vertices, position)) - { - constraint.pointA = position; - constraint.pointB = { x: position.x - body.position.x, y: position.y - body.position.y }; - - constraint.bodyB = body; - constraint.angleB = body.angle; - - Sleeping.set(body, false); - - this.part = part; - this.body = body; - - return true; - } - } - - return false; - }, - - /** - * Internal update handler. Called in the Matter BEFORE_UPDATE step. - * - * @method Phaser.Physics.Matter.PointerConstraint#update - * @fires Phaser.Physics.Matter.Events#DRAG - * @since 3.0.0 - */ - update: function () - { - var pointer = this.pointer; - var body = this.body; - - if (!this.active || !pointer) - { - if (body) - { - this.stopDrag(); - } - - return; - } + this.baseTileHeight = GetFastValue(config, 'baseTileHeight', this.tileHeight); - if (!pointer.isDown && body) - { - this.stopDrag(); + /** + * The layers orientation, necessary to be able to determine a tiles pixelX and pixelY as well as the layers width and height. + * + * @name Phaser.Tilemaps.LayerData#orientation + * @type {Phaser.Tilemaps.OrientationType} + * @since 3.50.0 + */ + this.orientation = GetFastValue(config, 'orientation', CONST.ORTHOGONAL); - return; - } - else if (pointer.isDown) - { - if (!body && !this.getBody(pointer)) - { - return; - } + /** + * The width in pixels of the entire layer. + * + * @name Phaser.Tilemaps.LayerData#widthInPixels + * @type {number} + * @since 3.0.0 + */ + this.widthInPixels = GetFastValue(config, 'widthInPixels', this.width * this.baseTileWidth); - body = this.body; + /** + * The height in pixels of the entire layer. + * + * @name Phaser.Tilemaps.LayerData#heightInPixels + * @type {number} + * @since 3.0.0 + */ + this.heightInPixels = GetFastValue(config, 'heightInPixels', this.height * this.baseTileHeight); - var pos = this.position; - var constraint = this.constraint; - - this.camera.getWorldPoint(pointer.x, pointer.y, pos); - - // Drag update - constraint.pointA.x = pos.x; - constraint.pointA.y = pos.y; + /** + * The alpha value of the layer. + * + * @name Phaser.Tilemaps.LayerData#alpha + * @type {number} + * @since 3.0.0 + */ + this.alpha = GetFastValue(config, 'alpha', 1); - Sleeping.set(body, false); + /** + * Is the layer visible or not? + * + * @name Phaser.Tilemaps.LayerData#visible + * @type {boolean} + * @since 3.0.0 + */ + this.visible = GetFastValue(config, 'visible', true); - this.world.emit(Events.DRAG, body, this); - } - }, + /** + * Layer specific properties (can be specified in Tiled) + * + * @name Phaser.Tilemaps.LayerData#properties + * @type {object[]} + * @since 3.0.0 + */ + this.properties = GetFastValue(config, 'properties', []); - /** - * Stops the Pointer Constraint from dragging the body any further. - * - * This is called automatically if the Pointer is released while actively - * dragging a body. Or, you can call it manually to release a body from a - * constraint without having to first release the pointer. - * - * @method Phaser.Physics.Matter.PointerConstraint#stopDrag - * @fires Phaser.Physics.Matter.Events#DRAG_END - * @since 3.16.2 - */ - stopDrag: function () - { - var body = this.body; - var constraint = this.constraint; + /** + * Tile ID index map. + * + * @name Phaser.Tilemaps.LayerData#indexes + * @type {array} + * @since 3.0.0 + */ + this.indexes = GetFastValue(config, 'indexes', []); - constraint.bodyB = null; - constraint.pointB = null; + /** + * Tile Collision ID index map. + * + * @name Phaser.Tilemaps.LayerData#collideIndexes + * @type {array} + * @since 3.0.0 + */ + this.collideIndexes = GetFastValue(config, 'collideIndexes', []); - this.pointer = null; - this.body = null; - this.part = null; + /** + * An array of callbacks. + * + * @name Phaser.Tilemaps.LayerData#callbacks + * @type {array} + * @since 3.0.0 + */ + this.callbacks = GetFastValue(config, 'callbacks', []); - if (body) - { - this.world.emit(Events.DRAG_END, body, this); - } - }, + /** + * An array of physics bodies. + * + * @name Phaser.Tilemaps.LayerData#bodies + * @type {array} + * @since 3.0.0 + */ + this.bodies = GetFastValue(config, 'bodies', []); - /** - * Destroys this Pointer Constraint instance and all of its references. - * - * @method Phaser.Physics.Matter.PointerConstraint#destroy - * @since 3.0.0 - */ - destroy: function () - { - this.world.removeConstraint(this.constraint); + /** + * An array of the tile data indexes. + * + * @name Phaser.Tilemaps.LayerData#data + * @type {Phaser.Tilemaps.Tile[][]} + * @since 3.0.0 + */ + this.data = GetFastValue(config, 'data', []); - this.pointer = null; - this.constraint = null; - this.body = null; - this.part = null; + /** + * A reference to the Tilemap layer that owns this data. + * + * @name Phaser.Tilemaps.LayerData#tilemapLayer + * @type {Phaser.Tilemaps.TilemapLayer} + * @since 3.0.0 + */ + this.tilemapLayer = GetFastValue(config, 'tilemapLayer', null); - this.world.off(Events.BEFORE_UPDATE, this.update); + /** + * The length of the horizontal sides of the hexagon. + * Only used for hexagonal orientation Tilemaps. + * + * @name Phaser.Tilemaps.LayerData#hexSideLength + * @type {number} + * @since 3.50.0 + */ + this.hexSideLength = GetFastValue(config, 'hexSideLength', 0); - this.scene.sys.input.off(InputEvents.POINTER_DOWN, this.onDown, this); - this.scene.sys.input.off(InputEvents.POINTER_UP, this.onUp, this); + /** + * The Stagger Axis as defined in Tiled. + * + * Only used for hexagonal orientation Tilemaps. + * + * @name Phaser.Tilemaps.LayerData#staggerAxis + * @type {string} + * @since 3.60.0 + */ + this.staggerAxis = GetFastValue(config, 'staggerAxis', 'y'); + + /** + * The Stagger Index as defined in Tiled. + * + * Either 'odd' or 'even'. + * + * Only used for hexagonal orientation Tilemaps. + * + * @name Phaser.Tilemaps.LayerData#staggerIndex + * @type {string} + * @since 3.60.0 + */ + this.staggerIndex = GetFastValue(config, 'staggerIndex', 'odd'); } }); -module.exports = PointerConstraint; +module.exports = LayerData; /***/ }), -/* 1399 */ -/***/ (function(module, exports, __webpack_require__) { - -/** -* The `Matter` module is the top level namespace. It also includes a function for installing plugins on top of the library. -* -* @class Matter -*/ -var Matter = {}; - -module.exports = Matter; +/***/ 16586: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var Plugin = __webpack_require__(595); -var Common = __webpack_require__(32); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -(function() { +var Class = __webpack_require__(56694); +var CONST = __webpack_require__(12920); +var GetFastValue = __webpack_require__(72632); - /** - * The library name. - * @property name - * @readOnly - * @type {String} - */ - Matter.name = 'matter-js'; +/** + * @classdesc + * A class for representing data about a map. Maps are parsed from CSV, Tiled, etc. into this + * format. A Tilemap object get a copy of this data and then unpacks the needed properties into + * itself. + * + * @class MapData + * @memberof Phaser.Tilemaps + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Types.Tilemaps.MapDataConfig} [config] - The Map configuration object. + */ +var MapData = new Class({ - /** - * The library version. - * @property version - * @readOnly - * @type {String} - */ - Matter.version = '0.14.2'; + initialize: - /** - * A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`. - * Alternatively you may set `Matter.uses` manually and install them by calling `Plugin.use(Matter)`. - * @property uses - * @type {Array} - */ - Matter.uses = []; + function MapData (config) + { + if (config === undefined) { config = {}; } - /** - * The plugins that have been installed through `Matter.Plugin.install`. Read only. - * @property used - * @readOnly - * @type {Array} - */ - Matter.used = []; + /** + * The key in the Phaser cache that corresponds to the loaded tilemap data. + * + * @name Phaser.Tilemaps.MapData#name + * @type {string} + * @since 3.0.0 + */ + this.name = GetFastValue(config, 'name', 'map'); - /** - * Installs the given plugins on the `Matter` namespace. - * This is a short-hand for `Plugin.use`, see it for more information. - * Call this function once at the start of your code, with all of the plugins you wish to install as arguments. - * Avoid calling this function multiple times unless you intend to manually control installation order. - * @method use - * @param ...plugin {Function} The plugin(s) to install on `base` (multi-argument). - */ - Matter.use = function() { - Plugin.use(Matter, Array.prototype.slice.call(arguments)); - }; + /** + * The width of the entire tilemap. + * + * @name Phaser.Tilemaps.MapData#width + * @type {number} + * @since 3.0.0 + */ + this.width = GetFastValue(config, 'width', 0); - /** - * Chains a function to excute before the original function on the given `path` relative to `Matter`. - * See also docs for `Common.chain`. - * @method before - * @param {string} path The path relative to `Matter` - * @param {function} func The function to chain before the original - * @return {function} The chained function that replaced the original - */ - Matter.before = function(path, func) { - path = path.replace(/^Matter./, ''); - return Common.chainPathBefore(Matter, path, func); - }; + /** + * The height of the entire tilemap. + * + * @name Phaser.Tilemaps.MapData#height + * @type {number} + * @since 3.0.0 + */ + this.height = GetFastValue(config, 'height', 0); - /** - * Chains a function to excute after the original function on the given `path` relative to `Matter`. - * See also docs for `Common.chain`. - * @method after - * @param {string} path The path relative to `Matter` - * @param {function} func The function to chain after the original - * @return {function} The chained function that replaced the original - */ - Matter.after = function(path, func) { - path = path.replace(/^Matter./, ''); - return Common.chainPathAfter(Matter, path, func); - }; + /** + * If the map is infinite or not. + * + * @name Phaser.Tilemaps.MapData#infinite + * @type {boolean} + * @since 3.17.0 + */ + this.infinite = GetFastValue(config, 'infinite', false); -})(); + /** + * The width of the tiles. + * + * @name Phaser.Tilemaps.MapData#tileWidth + * @type {number} + * @since 3.0.0 + */ + this.tileWidth = GetFastValue(config, 'tileWidth', 0); + /** + * The height of the tiles. + * + * @name Phaser.Tilemaps.MapData#tileHeight + * @type {number} + * @since 3.0.0 + */ + this.tileHeight = GetFastValue(config, 'tileHeight', 0); -/***/ }), -/* 1400 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * The width in pixels of the entire tilemap. + * + * @name Phaser.Tilemaps.MapData#widthInPixels + * @type {number} + * @since 3.0.0 + */ + this.widthInPixels = GetFastValue(config, 'widthInPixels', this.width * this.tileWidth); -/** -* The `Matter.Query` module contains methods for performing collision queries. -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Query -*/ + /** + * The height in pixels of the entire tilemap. + * + * @name Phaser.Tilemaps.MapData#heightInPixels + * @type {number} + * @since 3.0.0 + */ + this.heightInPixels = GetFastValue(config, 'heightInPixels', this.height * this.tileHeight); -var Query = {}; + /** + * The format of the map data. + * + * @name Phaser.Tilemaps.MapData#format + * @type {number} + * @since 3.0.0 + */ + this.format = GetFastValue(config, 'format', null); -module.exports = Query; + /** + * The orientation of the map data (i.e. orthogonal, isometric, hexagonal), default 'orthogonal'. + * + * @name Phaser.Tilemaps.MapData#orientation + * @type {Phaser.Tilemaps.OrientationType} + * @since 3.50.0 + */ + this.orientation = GetFastValue(config, 'orientation', CONST.ORTHOGONAL); -var Vector = __webpack_require__(83); -var SAT = __webpack_require__(274); -var Bounds = __webpack_require__(84); -var Bodies = __webpack_require__(86); -var Vertices = __webpack_require__(64); + /** + * Determines the draw order of tilemap. Default is right-down + * + * 0, or 'right-down' + * 1, or 'left-down' + * 2, or 'right-up' + * 3, or 'left-up' + * + * @name Phaser.Tilemaps.MapData#renderOrder + * @type {string} + * @since 3.12.0 + */ + this.renderOrder = GetFastValue(config, 'renderOrder', 'right-down'); -(function() { + /** + * The version of the map data (as specified in Tiled). + * + * @name Phaser.Tilemaps.MapData#version + * @type {string} + * @since 3.0.0 + */ + this.version = GetFastValue(config, 'version', '1'); - /** - * Returns a list of collisions between `body` and `bodies`. - * @method collides - * @param {body} body - * @param {body[]} bodies - * @return {object[]} Collisions - */ - Query.collides = function(body, bodies) { - var collisions = []; + /** + * Map specific properties (can be specified in Tiled) + * + * @name Phaser.Tilemaps.MapData#properties + * @type {object} + * @since 3.0.0 + */ + this.properties = GetFastValue(config, 'properties', {}); - for (var i = 0; i < bodies.length; i++) { - var bodyA = bodies[i]; + /** + * An array with all the layers configured to the MapData. + * + * @name Phaser.Tilemaps.MapData#layers + * @type {(Phaser.Tilemaps.LayerData[]|Phaser.Tilemaps.ObjectLayer)} + * @since 3.0.0 + */ + this.layers = GetFastValue(config, 'layers', []); - // Phaser addition - skip same body checks - if (body === bodyA) - { - continue; - } - - if (Bounds.overlaps(bodyA.bounds, body.bounds)) { - for (var j = bodyA.parts.length === 1 ? 0 : 1; j < bodyA.parts.length; j++) { - var part = bodyA.parts[j]; + /** + * An array of Tiled Image Layers. + * + * @name Phaser.Tilemaps.MapData#images + * @type {array} + * @since 3.0.0 + */ + this.images = GetFastValue(config, 'images', []); - if (Bounds.overlaps(part.bounds, body.bounds)) { - var collision = SAT.collides(part, body); + /** + * An object of Tiled Object Layers. + * + * @name Phaser.Tilemaps.MapData#objects + * @type {Phaser.Types.Tilemaps.ObjectLayerConfig[]} + * @since 3.0.0 + */ + this.objects = GetFastValue(config, 'objects', []); - if (collision.collided) { - collisions.push(collision); - break; - } - } - } - } + // Because Tiled can sometimes create an empty object if you don't populate it, not an empty array + if (!Array.isArray(this.objects)) + { + this.objects = []; } - return collisions; - }; - - /** - * Casts a ray segment against a set of bodies and returns all collisions, ray width is optional. Intersection points are not provided. - * @method ray - * @param {body[]} bodies - * @param {vector} startPoint - * @param {vector} endPoint - * @param {number} [rayWidth] - * @return {object[]} Collisions - */ - Query.ray = function(bodies, startPoint, endPoint, rayWidth) { - rayWidth = rayWidth || 1e-100; + /** + * An object of collision data. Must be created as physics object or will return undefined. + * + * @name Phaser.Tilemaps.MapData#collision + * @type {object} + * @since 3.0.0 + */ + this.collision = GetFastValue(config, 'collision', {}); - var rayAngle = Vector.angle(startPoint, endPoint), - rayLength = Vector.magnitude(Vector.sub(startPoint, endPoint)), - rayX = (endPoint.x + startPoint.x) * 0.5, - rayY = (endPoint.y + startPoint.y) * 0.5, - ray = Bodies.rectangle(rayX, rayY, rayLength, rayWidth, { angle: rayAngle }), - collisions = Query.collides(ray, bodies); + /** + * An array of Tilesets. + * + * @name Phaser.Tilemaps.MapData#tilesets + * @type {Phaser.Tilemaps.Tileset[]} + * @since 3.0.0 + */ + this.tilesets = GetFastValue(config, 'tilesets', []); - for (var i = 0; i < collisions.length; i += 1) { - var collision = collisions[i]; - collision.body = collision.bodyB = collision.bodyA; - } + /** + * The collection of images the map uses(specified in Tiled) + * + * @name Phaser.Tilemaps.MapData#imageCollections + * @type {array} + * @since 3.0.0 + */ + this.imageCollections = GetFastValue(config, 'imageCollections', []); - return collisions; - }; + /** + * An array of tile instances. + * + * @name Phaser.Tilemaps.MapData#tiles + * @type {array} + * @since 3.0.0 + */ + this.tiles = GetFastValue(config, 'tiles', []); - /** - * Returns all bodies whose bounds are inside (or outside if set) the given set of bounds, from the given set of bodies. - * @method region - * @param {body[]} bodies - * @param {bounds} bounds - * @param {bool} [outside=false] - * @return {body[]} The bodies matching the query - */ - Query.region = function(bodies, bounds, outside) { - var result = []; + /** + * The length of the horizontal sides of the hexagon. + * + * Only used for hexagonal orientation Tilemaps. + * + * @name Phaser.Tilemaps.MapData#hexSideLength + * @type {number} + * @since 3.50.0 + */ + this.hexSideLength = GetFastValue(config, 'hexSideLength', 0); - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i], - overlaps = Bounds.overlaps(body.bounds, bounds); - if ((overlaps && !outside) || (!overlaps && outside)) - result.push(body); - } + /** + * The Stagger Axis as defined in Tiled. + * + * Only used for hexagonal orientation Tilemaps. + * + * @name Phaser.Tilemaps.MapData#staggerAxis + * @type {string} + * @since 3.60.0 + */ + this.staggerAxis = GetFastValue(config, 'staggerAxis', 'y'); - return result; - }; + /** + * The Stagger Index as defined in Tiled. + * + * Either 'odd' or 'even'. + * + * Only used for hexagonal orientation Tilemaps. + * + * @name Phaser.Tilemaps.MapData#staggerIndex + * @type {string} + * @since 3.60.0 + */ + this.staggerIndex = GetFastValue(config, 'staggerIndex', 'odd'); + } - /** - * Returns all bodies whose vertices contain the given point, from the given set of bodies. - * @method point - * @param {body[]} bodies - * @param {vector} point - * @return {body[]} The bodies matching the query - */ - Query.point = function(bodies, point) { - var result = []; +}); - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i]; - - if (Bounds.contains(body.bounds, point)) { - for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) { - var part = body.parts[j]; +module.exports = MapData; - if (Bounds.contains(part.bounds, point) - && Vertices.contains(part.vertices, point)) { - result.push(body); - break; - } - } - } - } - return result; - }; +/***/ }), -})(); +/***/ 15256: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -/***/ }), -/* 1401 */ -/***/ (function(module, exports, __webpack_require__) { +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); /** -* The `Matter.Engine` module contains methods for creating and manipulating engines. -* An engine is a controller that manages updating the simulation of the world. -* See `Matter.Runner` for an optional game loop utility. -* -* See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). -* -* @class Engine -*/ - -var Engine = {}; + * @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({ -module.exports = Engine; + initialize: -var World = __webpack_require__(596); -var Sleeping = __webpack_require__(165); -var Resolver = __webpack_require__(599); -var Pairs = __webpack_require__(598); -var Metrics = __webpack_require__(1523); -var Grid = __webpack_require__(597); -var Events = __webpack_require__(166); -var Composite = __webpack_require__(118); -var Constraint = __webpack_require__(128); -var Common = __webpack_require__(32); -var Body = __webpack_require__(41); + function ObjectLayer (config) + { + if (config === undefined) { config = {}; } -(function() { + /** + * The name of the Object Layer. + * + * @name Phaser.Tilemaps.ObjectLayer#name + * @type {string} + * @since 3.0.0 + */ + this.name = GetFastValue(config, 'name', 'object layer'); - /** - * Creates a new engine. The options parameter is an object that specifies any properties you wish to override the defaults. - * All properties have default values, and many are pre-calculated automatically based on other properties. - * See the properties section below for detailed information on what you can pass via the `options` object. - * @method create - * @param {object} [options] - * @return {engine} engine - */ - Engine.create = function(element, options) { - // options may be passed as the first (and only) argument - options = Common.isElement(element) ? options : element; - element = Common.isElement(element) ? element : null; - options = options || {}; + /** + * 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); - if (element || options.render) { - Common.warn('Engine.create: engine.render is deprecated (see docs)'); - } + /** + * 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', {}); - var defaults = { - positionIterations: 6, - velocityIterations: 4, - constraintIterations: 2, - enableSleeping: false, - events: [], - plugin: {}, - timing: { - timestamp: 0, - timeScale: 1 - }, - broadphase: { - controller: Grid - } - }; + /** + * 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', {}); - var engine = Common.extend(defaults, options); + /** + * 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'); - engine.world = options.world || World.create(engine.world); - engine.pairs = Pairs.create(); - engine.broadphase = engine.broadphase.controller.create(engine.broadphase); - engine.metrics = engine.metrics || { extended: false }; + /** + * 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); - // @if DEBUG - engine.metrics = Metrics.create(engine.metrics); - // @endif + /** + * 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', []); - return engine; - }; + // Because Tiled can sometimes create an empty object if you don't populate it, not an empty array + if (!Array.isArray(this.objects)) + { + this.objects = []; + } + } - /** - * Moves the simulation forward in time by `delta` ms. - * The `correction` argument is an optional `Number` that specifies the time correction factor to apply to the update. - * This can help improve the accuracy of the simulation in cases where `delta` is changing between updates. - * The value of `correction` is defined as `delta / lastDelta`, i.e. the percentage change of `delta` over the last step. - * Therefore the value is always `1` (no correction) when `delta` constant (or when no correction is desired, which is the default). - * See the paper on Time Corrected Verlet for more information. - * - * Triggers `beforeUpdate` and `afterUpdate` events. - * Triggers `collisionStart`, `collisionActive` and `collisionEnd` events. - * @method update - * @param {engine} engine - * @param {number} [delta=16.666] - * @param {number} [correction=1] - */ - Engine.update = function(engine, delta, correction) { - delta = delta || 1000 / 60; - correction = correction || 1; +}); - var world = engine.world, - timing = engine.timing, - broadphase = engine.broadphase, - broadphasePairs = [], - i; +module.exports = ObjectLayer; - // increment timestamp - timing.timestamp += delta * timing.timeScale; - // create an event object - var event = { - timestamp: timing.timestamp - }; +/***/ }), - Events.trigger(engine, 'beforeUpdate', event); +/***/ 21394: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // get lists of all bodies and constraints, no matter what composites they are in - var allBodies = Composite.allBodies(world), - allConstraints = Composite.allConstraints(world); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // @if DEBUG - // reset metrics logging - Metrics.reset(engine.metrics); - // @endif +var CONST = __webpack_require__(12920); - // if sleeping enabled, call the sleeping controller - if (engine.enableSleeping) - Sleeping.update(allBodies, timing.timeScale); +/** + * Get the Tilemap orientation from the given string. + * + * @function Phaser.Tilemaps.Parsers.FromOrientationString + * @since 3.50.0 + * + * @param {string} [orientation] - The orientation type as a string. + * + * @return {Phaser.Tilemaps.OrientationType} The Tilemap Orientation type. + */ +var FromOrientationString = function (orientation) +{ + orientation = orientation.toLowerCase(); - // applies gravity to all bodies - Engine._bodiesApplyGravity(allBodies, world.gravity); + if (orientation === 'isometric') + { + return CONST.ISOMETRIC; + } + else if (orientation === 'staggered') + { + return CONST.STAGGERED; + } + else if (orientation === 'hexagonal') + { + return CONST.HEXAGONAL; + } + else + { + return CONST.ORTHOGONAL; + } +}; - // update all body position and rotation by integration - Engine._bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds); +module.exports = FromOrientationString; - // update all constraints (first pass) - Constraint.preSolveAll(allBodies); - for (i = 0; i < engine.constraintIterations; i++) { - Constraint.solveAll(allConstraints, timing.timeScale); - } - Constraint.postSolveAll(allBodies); - // broadphase pass: find potential collision pairs - if (broadphase.controller) { - // if world is dirty, we must flush the whole grid - if (world.isModified) - broadphase.controller.clear(broadphase); +/***/ }), - // update the grid buckets based on current bodies - broadphase.controller.update(broadphase, allBodies, engine, world.isModified); - broadphasePairs = broadphase.pairsList; - } else { - // if no broadphase set, we just pass all bodies - broadphasePairs = allBodies; - } +/***/ 90715: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // clear all composite modified flags - if (world.isModified) { - Composite.setModified(world, false, false, true); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // narrowphase pass: find actual collisions, then create or update collision pairs - var collisions = broadphase.detector(broadphasePairs, engine); +var Formats = __webpack_require__(93560); +var Parse2DArray = __webpack_require__(84346); +var ParseCSV = __webpack_require__(96097); +var ParseJSONTiled = __webpack_require__(2378); +var ParseWeltmeister = __webpack_require__(44909); - // update collision pairs - var pairs = engine.pairs, - timestamp = timing.timestamp; - Pairs.update(pairs, collisions, timestamp); - Pairs.removeOld(pairs, timestamp); +/** + * 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; - // wake up bodies involved in collisions - if (engine.enableSleeping) - Sleeping.afterCollisions(pairs.list, timing.timeScale); + 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; + } - // trigger collision events - if (pairs.collisionStart.length > 0) - Events.trigger(engine, 'collisionStart', { pairs: pairs.collisionStart }); + return newMap; +}; - // iteratively resolve position between collisions - Resolver.preSolvePosition(pairs.list); - for (i = 0; i < engine.positionIterations; i++) { - Resolver.solvePosition(pairs.list, allBodies, timing.timeScale); - } - Resolver.postSolvePosition(allBodies); +module.exports = Parse; - // update all constraints (second pass) - Constraint.preSolveAll(allBodies); - for (i = 0; i < engine.constraintIterations; i++) { - Constraint.solveAll(allConstraints, timing.timeScale); - } - Constraint.postSolveAll(allBodies); - // iteratively resolve velocity between collisions - Resolver.preSolveVelocity(pairs.list); - for (i = 0; i < engine.velocityIterations; i++) { - Resolver.solveVelocity(pairs.list, timing.timeScale); - } +/***/ }), - // trigger collision events - if (pairs.collisionActive.length > 0) - Events.trigger(engine, 'collisionActive', { pairs: pairs.collisionActive }); +/***/ 84346: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (pairs.collisionEnd.length > 0) - Events.trigger(engine, 'collisionEnd', { pairs: pairs.collisionEnd }); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // @if DEBUG - // update metrics log - Metrics.update(engine.metrics, engine); - // @endif +var Formats = __webpack_require__(93560); +var LayerData = __webpack_require__(94990); +var MapData = __webpack_require__(16586); +var Tile = __webpack_require__(29633); - // clear force buffers - Engine._bodiesClearForces(allBodies); +/** + * Parses a 2D array of tile indexes into a new MapData object with a single layer. + * + * @function Phaser.Tilemaps.Parsers.Parse2DArray + * @since 3.0.0 + * + * @param {string} name - The name of the tilemap, used to set the name on the MapData. + * @param {number[][]} data - 2D array, CSV string or Tiled JSON object. + * @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 MapData object. + */ +var Parse2DArray = function (name, data, tileWidth, tileHeight, insertNull) +{ + var layerData = new LayerData({ + tileWidth: tileWidth, + tileHeight: tileHeight + }); - Events.trigger(engine, 'afterUpdate', event); + var mapData = new MapData({ + name: name, + tileWidth: tileWidth, + tileHeight: tileHeight, + format: Formats.ARRAY_2D, + layers: [ layerData ] + }); - return engine; - }; - - /** - * Merges two engines by keeping the configuration of `engineA` but replacing the world with the one from `engineB`. - * @method merge - * @param {engine} engineA - * @param {engine} engineB - */ - Engine.merge = function(engineA, engineB) { - Common.extend(engineA, engineB); - - if (engineB.world) { - engineA.world = engineB.world; + var tiles = []; + var height = data.length; + var width = 0; - Engine.clear(engineA); + for (var y = 0; y < data.length; y++) + { + tiles[y] = []; + var row = data[y]; - var bodies = Composite.allBodies(engineA.world); + for (var x = 0; x < row.length; x++) + { + var tileIndex = parseInt(row[x], 10); - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i]; - Sleeping.set(body, false); - body.id = Common.nextId(); + if (isNaN(tileIndex) || tileIndex === -1) + { + tiles[y][x] = insertNull + ? null + : new Tile(layerData, -1, x, y, tileWidth, tileHeight); + } + else + { + tiles[y][x] = new Tile(layerData, tileIndex, x, y, tileWidth, tileHeight); } } - }; - - /** - * Clears the engine including the world, pairs and broadphase. - * @method clear - * @param {engine} engine - */ - Engine.clear = function(engine) { - var world = engine.world; - - Pairs.clear(engine.pairs); - - var broadphase = engine.broadphase; - if (broadphase.controller) { - var bodies = Composite.allBodies(world); - broadphase.controller.clear(broadphase); - broadphase.controller.update(broadphase, bodies, engine, true); - } - }; - - /** - * Zeroes the `body.force` and `body.torque` force buffers. - * @method _bodiesClearForces - * @private - * @param {body[]} bodies - */ - Engine._bodiesClearForces = function(bodies) { - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i]; - - // reset force buffers - body.force.x = 0; - body.force.y = 0; - body.torque = 0; - } - }; - - /** - * Applys a mass dependant force to all given bodies. - * @method _bodiesApplyGravity - * @private - * @param {body[]} bodies - * @param {vector} gravity - */ - Engine._bodiesApplyGravity = function(bodies, gravity) { - var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001; - - if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) { - return; - } - - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i]; - - if (body.ignoreGravity || body.isStatic || body.isSleeping) - continue; - - // apply gravity - body.force.x += (body.mass * gravity.x * gravityScale) * body.gravityScale.x; - body.force.y += (body.mass * gravity.y * gravityScale) * body.gravityScale.y; - } - }; - - /** - * Applys `Body.update` to all given `bodies`. - * @method _bodiesUpdate - * @private - * @param {body[]} bodies - * @param {number} deltaTime - * The amount of time elapsed between updates - * @param {number} timeScale - * @param {number} correction - * The Verlet correction factor (deltaTime / lastDeltaTime) - * @param {bounds} worldBounds - */ - Engine._bodiesUpdate = function(bodies, deltaTime, timeScale, correction, worldBounds) { - for (var i = 0; i < bodies.length; i++) { - var body = bodies[i]; - - if (body.isStatic || body.isSleeping) - continue; - Body.update(body, deltaTime, timeScale, correction); + if (width === 0) + { + width = row.length; } - }; - - /** - * An alias for `Runner.run`, see `Matter.Runner` for more information. - * @method run - * @param {engine} engine - */ - - /** - * Fired just before an update - * - * @event beforeUpdate - * @param {} event An event object - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired after engine update and all collision events - * - * @event afterUpdate - * @param {} event An event object - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired after engine update, provides a list of all pairs that have started to collide in the current tick (if any) - * - * @event collisionStart - * @param {} event An event object - * @param {} event.pairs List of affected pairs - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired after engine update, provides a list of all pairs that are colliding in the current tick (if any) - * - * @event collisionActive - * @param {} event An event object - * @param {} event.pairs List of affected pairs - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /** - * Fired after engine update, provides a list of all pairs that have ended collision in the current tick (if any) - * - * @event collisionEnd - * @param {} event An event object - * @param {} event.pairs List of affected pairs - * @param {number} event.timestamp The engine.timing.timestamp of the event - * @param {} event.source The source object of the event - * @param {} event.name The name of the event - */ - - /* - * - * Properties Documentation - * - */ + } - /** - * An integer `Number` that specifies the number of position iterations to perform each update. - * The higher the value, the higher quality the simulation will be at the expense of performance. - * - * @property positionIterations - * @type number - * @default 6 - */ + mapData.width = layerData.width = width; + mapData.height = layerData.height = height; + mapData.widthInPixels = layerData.widthInPixels = width * tileWidth; + mapData.heightInPixels = layerData.heightInPixels = height * tileHeight; + layerData.data = tiles; - /** - * An integer `Number` that specifies the number of velocity iterations to perform each update. - * The higher the value, the higher quality the simulation will be at the expense of performance. - * - * @property velocityIterations - * @type number - * @default 4 - */ + return mapData; +}; - /** - * An integer `Number` that specifies the number of constraint iterations to perform each update. - * The higher the value, the higher quality the simulation will be at the expense of performance. - * The default value of `2` is usually very adequate. - * - * @property constraintIterations - * @type number - * @default 2 - */ +module.exports = Parse2DArray; - /** - * A flag that specifies whether the engine should allow sleeping via the `Matter.Sleeping` module. - * Sleeping can improve stability and performance, but often at the expense of accuracy. - * - * @property enableSleeping - * @type boolean - * @default false - */ - /** - * An `Object` containing properties regarding the timing systems of the engine. - * - * @property timing - * @type object - */ +/***/ }), - /** - * A `Number` that specifies the global scaling factor of time for all bodies. - * A value of `0` freezes the simulation. - * A value of `0.1` gives a slow-motion effect. - * A value of `1.2` gives a speed-up effect. - * - * @property timing.timeScale - * @type number - * @default 1 - */ +/***/ 96097: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A `Number` that specifies the current simulation-time in milliseconds starting from `0`. - * It is incremented on every `Engine.update` by the given `delta` argument. - * - * @property timing.timestamp - * @type number - * @default 0 - */ +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * An instance of a `Render` controller. The default value is a `Matter.Render` instance created by `Engine.create`. - * One may also develop a custom renderer module based on `Matter.Render` and pass an instance of it to `Engine.create` via `options.render`. - * - * A minimal custom renderer object must define at least three functions: `create`, `clear` and `world` (see `Matter.Render`). - * It is also possible to instead pass the _module_ reference via `options.render.controller` and `Engine.create` will instantiate one for you. - * - * @property render - * @type render - * @deprecated see Demo.js for an example of creating a renderer - * @default a Matter.Render instance - */ +var Formats = __webpack_require__(93560); +var Parse2DArray = __webpack_require__(84346); - /** - * An instance of a broadphase controller. The default value is a `Matter.Grid` instance created by `Engine.create`. - * - * @property broadphase - * @type grid - * @default a Matter.Grid instance - */ +/** + * 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(','); }); - /** - * A `World` composite object that will contain all simulated bodies and constraints. - * - * @property world - * @type world - * @default a Matter.World instance - */ + var map = Parse2DArray(name, array2D, tileWidth, tileHeight, insertNull); + map.format = Formats.CSV; - /** - * An object reserved for storing plugin-specific properties. - * - * @property plugin - * @type {} - */ + return map; +}; -})(); +module.exports = ParseCSV; /***/ }), -/* 1402 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 30951: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Bodies = __webpack_require__(86); -var Body = __webpack_require__(41); -var Class = __webpack_require__(0); -var Common = __webpack_require__(32); -var Composite = __webpack_require__(118); -var Engine = __webpack_require__(1401); -var EventEmitter = __webpack_require__(9); -var Events = __webpack_require__(272); -var GetFastValue = __webpack_require__(2); -var GetValue = __webpack_require__(6); -var MatterBody = __webpack_require__(41); -var MatterEvents = __webpack_require__(166); -var MatterTileBody = __webpack_require__(593); -var MatterWorld = __webpack_require__(596); -var Vector = __webpack_require__(83); +var LayerData = __webpack_require__(94990); +var Tile = __webpack_require__(29633); /** - * @classdesc - * The Matter World class is responsible for managing one single instance of a Matter Physics World for Phaser. - * - * Access this via `this.matter.world` from within a Scene. - * - * This class creates a Matter JS World Composite along with the Matter JS Engine during instantiation. It also - * handles delta timing, bounds, body and constraint creation and debug drawing. - * - * If you wish to access the Matter JS World object directly, see the `localWorld` property. - * If you wish to access the Matter Engine directly, see the `engine` property. - * - * This class is an Event Emitter and will proxy _all_ Matter JS events, as they are received. + * Parses all tilemap layers in an Impact JSON object into new LayerData objects. * - * @class World - * @extends Phaser.Events.EventEmitter - * @memberof Phaser.Physics.Matter - * @constructor + * @function Phaser.Tilemaps.Parsers.Impact.ParseTileLayers * @since 3.0.0 * - * @param {Phaser.Scene} scene - The Scene to which this Matter World instance belongs. - * @param {Phaser.Types.Physics.Matter.MatterWorldConfig} config - The Matter World configuration object. + * @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 World = new Class({ +var ParseTileLayers = function (json, insertNull) +{ + var tileLayers = []; - Extends: EventEmitter, + for (var i = 0; i < json.layer.length; i++) + { + var layer = json.layer[i]; - initialize: + var layerData = new LayerData({ + name: layer.name, + width: layer.width, + height: layer.height, + tileWidth: layer.tilesize, + tileHeight: layer.tilesize, + visible: layer.visible === 1 + }); - function World (scene, config) - { - EventEmitter.call(this); + var row = []; + var tileGrid = []; - /** - * The Scene to which this Matter World instance belongs. - * - * @name Phaser.Physics.Matter.World#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; + // 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; - /** - * An instance of the MatterJS Engine. - * - * @name Phaser.Physics.Matter.World#engine - * @type {MatterJS.Engine} - * @since 3.0.0 - */ - this.engine = Engine.create(config); + var tile; - /** - * A `World` composite object that will contain all simulated bodies and constraints. - * - * @name Phaser.Physics.Matter.World#localWorld - * @type {MatterJS.World} - * @since 3.0.0 - */ - this.localWorld = this.engine.world; + 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); + } - var gravity = GetValue(config, 'gravity', null); + row.push(tile); + } - if (gravity) - { - this.setGravity(gravity.x, gravity.y, gravity.scale); - } - else if (gravity === false) - { - this.setGravity(0, 0, 0); + tileGrid.push(row); + row = []; } - /** - * An object containing the 4 wall bodies that bound the physics world. - * - * @name Phaser.Physics.Matter.World#walls - * @type {object} - * @since 3.0.0 - */ - this.walls = { left: null, right: null, top: null, bottom: null }; + layerData.data = tileGrid; - /** - * A flag that toggles if the world is enabled or not. - * - * @name Phaser.Physics.Matter.World#enabled - * @type {boolean} - * @default true - * @since 3.0.0 - */ - this.enabled = GetValue(config, 'enabled', true); + tileLayers.push(layerData); + } - /** - * The correction argument is an optional Number that specifies the time correction factor to apply to the update. - * This can help improve the accuracy of the simulation in cases where delta is changing between updates. - * The value of correction is defined as delta / lastDelta, i.e. the percentage change of delta over the last step. - * Therefore the value is always 1 (no correction) when delta is constant (or when no correction is desired, which is the default). - * See the paper on Time Corrected Verlet for more information. - * - * @name Phaser.Physics.Matter.World#correction - * @type {number} - * @default 1 - * @since 3.4.0 - */ - this.correction = GetValue(config, 'correction', 1); + return tileLayers; +}; - /** - * This function is called every time the core game loop steps, which is bound to the - * Request Animation Frame frequency unless otherwise modified. - * - * The function is passed two values: `time` and `delta`, both of which come from the game step values. - * - * It must return a number. This number is used as the delta value passed to Matter.Engine.update. - * - * You can override this function with your own to define your own timestep. - * - * If you need to update the Engine multiple times in a single game step then call - * `World.update` as many times as required. Each call will trigger the `getDelta` function. - * If you wish to have full control over when the Engine updates then see the property `autoUpdate`. - * - * You can also adjust the number of iterations that Engine.update performs. - * Use the Scene Matter Physics config object to set the following properties: - * - * positionIterations (defaults to 6) - * velocityIterations (defaults to 4) - * constraintIterations (defaults to 2) - * - * Adjusting these values can help performance in certain situations, depending on the physics requirements - * of your game. - * - * @name Phaser.Physics.Matter.World#getDelta - * @type {function} - * @since 3.4.0 - */ - this.getDelta = GetValue(config, 'getDelta', this.update60Hz); +module.exports = ParseTileLayers; - var runnerConfig = GetFastValue(config, 'runner', {}); - var hasFPS = GetFastValue(runnerConfig, 'fps', false); +/***/ }), - var fps = GetFastValue(runnerConfig, 'fps', 60); +/***/ 47488: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var delta = GetFastValue(runnerConfig, 'delta', 1000 / fps); - var deltaMin = GetFastValue(runnerConfig, 'deltaMin', 1000 / fps); - var deltaMax = GetFastValue(runnerConfig, 'deltaMax', 1000 / (fps * 0.5)); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (!hasFPS) +var Tileset = __webpack_require__(47975); + +/** + * 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) { - fps = 1000 / delta; - } + tilesetsNames.push(tilesetName); - /** - * The Matter JS Runner Configuration object. - * - * This object is populated via the Matter Configuration object's `runner` property and is - * updated constantly during the game step. - * - * @name Phaser.Physics.Matter.World#runner - * @type {Phaser.Types.Physics.Matter.MatterRunnerConfig} - * @since 3.22.0 - */ - this.runner = { - fps: fps, - correction: GetFastValue(runnerConfig, 'correction', 1), - deltaSampleSize: GetFastValue(runnerConfig, 'deltaSampleSize', 60), - counterTimestamp: 0, - frameCounter: 0, - deltaHistory: [], - timePrev: null, - timeScalePrev: 1, - frameRequestId: null, - isFixed: GetFastValue(runnerConfig, 'isFixed', false), - delta: delta, - deltaMin: deltaMin, - deltaMax: deltaMax - }; + // 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)); + } + } - /** - * Automatically call Engine.update every time the game steps. - * If you disable this then you are responsible for calling `World.step` directly from your game. - * If you call `set60Hz` or `set30Hz` then `autoUpdate` is reset to `true`. - * - * @name Phaser.Physics.Matter.World#autoUpdate - * @type {boolean} - * @default true - * @since 3.4.0 - */ - this.autoUpdate = GetValue(config, 'autoUpdate', true); + return tilesets; +}; - var debugConfig = GetValue(config, 'debug', false); +module.exports = ParseTilesets; - /** - * A flag that controls if the debug graphics will be drawn to or not. - * - * @name Phaser.Physics.Matter.World#drawDebug - * @type {boolean} - * @default false - * @since 3.0.0 - */ - this.drawDebug = (typeof(debugConfig) === 'object') ? true : debugConfig; - /** - * An instance of the Graphics object the debug bodies are drawn to, if enabled. - * - * @name Phaser.Physics.Matter.World#debugGraphic - * @type {Phaser.GameObjects.Graphics} - * @since 3.0.0 - */ - this.debugGraphic; +/***/ }), - /** - * The debug configuration object. - * - * The values stored in this object are read from the Matter World Config `debug` property. - * - * When a new Body or Constraint is _added to the World_, they are given the values stored in this object, - * unless they have their own `render` object set that will override them. - * - * Note that while you can modify the values of properties in this object at run-time, it will not change - * any of the Matter objects _already added_. It will only impact objects newly added to the world, or one - * that is removed and then re-added at a later time. - * - * @name Phaser.Physics.Matter.World#debugConfig - * @type {Phaser.Types.Physics.Matter.MatterDebugConfig} - * @since 3.22.0 - */ - this.debugConfig = { - showAxes: GetFastValue(debugConfig, 'showAxes', false), - showAngleIndicator: GetFastValue(debugConfig, 'showAngleIndicator', false), - angleColor: GetFastValue(debugConfig, 'angleColor', 0xe81153), +/***/ 44909: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - showBroadphase: GetFastValue(debugConfig, 'showBroadphase', false), - broadphaseColor: GetFastValue(debugConfig, 'broadphaseColor', 0xffb400), +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - showBounds: GetFastValue(debugConfig, 'showBounds', false), - boundsColor: GetFastValue(debugConfig, 'boundsColor', 0xffffff), +var Formats = __webpack_require__(93560); +var MapData = __webpack_require__(16586); +var ParseTileLayers = __webpack_require__(30951); +var ParseTilesets = __webpack_require__(47488); - showVelocity: GetFastValue(debugConfig, 'showVelocity', false), - velocityColor: GetFastValue(debugConfig, 'velocityColor', 0x00aeef), +/** + * 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; + } - showCollisions: GetFastValue(debugConfig, 'showCollisions', false), - collisionColor: GetFastValue(debugConfig, 'collisionColor', 0xf5950c), + var width = 0; + var height = 0; - showSeparations: GetFastValue(debugConfig, 'showSeparations', false), - separationColor: GetFastValue(debugConfig, 'separationColor', 0xffa500), + 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; } + } - showBody: GetFastValue(debugConfig, 'showBody', true), - showStaticBody: GetFastValue(debugConfig, 'showStaticBody', true), - showInternalEdges: GetFastValue(debugConfig, 'showInternalEdges', false), + var mapData = new MapData({ + width: width, + height: height, + name: name, + tileWidth: json.layer[0].tilesize, + tileHeight: json.layer[0].tilesize, + format: Formats.WELTMEISTER + }); - renderFill: GetFastValue(debugConfig, 'renderFill', false), - renderLine: GetFastValue(debugConfig, 'renderLine', true), + mapData.layers = ParseTileLayers(json, insertNull); + mapData.tilesets = ParseTilesets(json); - fillColor: GetFastValue(debugConfig, 'fillColor', 0x106909), - fillOpacity: GetFastValue(debugConfig, 'fillOpacity', 1), - lineColor: GetFastValue(debugConfig, 'lineColor', 0x28de19), - lineOpacity: GetFastValue(debugConfig, 'lineOpacity', 1), - lineThickness: GetFastValue(debugConfig, 'lineThickness', 1), + return mapData; +}; - staticFillColor: GetFastValue(debugConfig, 'staticFillColor', 0x0d177b), - staticLineColor: GetFastValue(debugConfig, 'staticLineColor', 0x1327e4), +module.exports = ParseWeltmeister; - showSleeping: GetFastValue(debugConfig, 'showSleeping', false), - staticBodySleepOpacity: GetFastValue(debugConfig, 'staticBodySleepOpacity', 0.7), - sleepFillColor: GetFastValue(debugConfig, 'sleepFillColor', 0x464646), - sleepLineColor: GetFastValue(debugConfig, 'sleepLineColor', 0x999a99), - showSensors: GetFastValue(debugConfig, 'showSensors', true), - sensorFillColor: GetFastValue(debugConfig, 'sensorFillColor', 0x0d177b), - sensorLineColor: GetFastValue(debugConfig, 'sensorLineColor', 0x1327e4), +/***/ }), - showPositions: GetFastValue(debugConfig, 'showPositions', true), - positionSize: GetFastValue(debugConfig, 'positionSize', 4), - positionColor: GetFastValue(debugConfig, 'positionColor', 0xe042da), +/***/ 24507: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - showJoint: GetFastValue(debugConfig, 'showJoint', true), - jointColor: GetFastValue(debugConfig, 'jointColor', 0xe0e042), - jointLineOpacity: GetFastValue(debugConfig, 'jointLineOpacity', 1), - jointLineThickness: GetFastValue(debugConfig, 'jointLineThickness', 2), +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - pinSize: GetFastValue(debugConfig, 'pinSize', 4), - pinColor: GetFastValue(debugConfig, 'pinColor', 0x42e0e0), +/** + * @namespace Phaser.Tilemaps.Parsers.Impact + */ - springColor: GetFastValue(debugConfig, 'springColor', 0xe042e0), +module.exports = { - anchorColor: GetFastValue(debugConfig, 'anchorColor', 0xefefef), - anchorSize: GetFastValue(debugConfig, 'anchorSize', 4), + ParseTileLayers: __webpack_require__(30951), + ParseTilesets: __webpack_require__(47488), + ParseWeltmeister: __webpack_require__(44909) - showConvexHulls: GetFastValue(debugConfig, 'showConvexHulls', false), - hullColor: GetFastValue(debugConfig, 'hullColor', 0xd703d0) - }; +}; - if (this.drawDebug) - { - this.createDebugGraphic(); - } - this.setEventsProxy(); +/***/ }), - // Create the walls +/***/ 34124: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (GetFastValue(config, 'setBounds', false)) - { - var boundsConfig = config['setBounds']; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (typeof boundsConfig === 'boolean') - { - this.setBounds(); - } - else - { - var x = GetFastValue(boundsConfig, 'x', 0); - var y = GetFastValue(boundsConfig, 'y', 0); - var width = GetFastValue(boundsConfig, 'width', scene.sys.scale.width); - var height = GetFastValue(boundsConfig, 'height', scene.sys.scale.height); - var thickness = GetFastValue(boundsConfig, 'thickness', 64); - var left = GetFastValue(boundsConfig, 'left', true); - var right = GetFastValue(boundsConfig, 'right', true); - var top = GetFastValue(boundsConfig, 'top', true); - var bottom = GetFastValue(boundsConfig, 'bottom', true); +/** + * @namespace Phaser.Tilemaps.Parsers + */ - this.setBounds(x, y, width, height, thickness, left, right, top, bottom); - } - } - }, +module.exports = { - /** - * Sets the debug render style for the children of the given Matter Composite. - * - * Composites themselves do not render, but they can contain bodies, constraints and other composites that may do. - * So the children of this composite are passed to the `setBodyRenderStyle`, `setCompositeRenderStyle` and - * `setConstraintRenderStyle` methods accordingly. - * - * @method Phaser.Physics.Matter.World#setCompositeRenderStyle - * @since 3.22.0 - * - * @param {MatterJS.CompositeType} composite - The Matter Composite to set the render style on. - * - * @return {this} This Matter World instance for method chaining. - */ - setCompositeRenderStyle: function (composite) - { - var bodies = composite.bodies; - var constraints = composite.constraints; - var composites = composite.composites; + FromOrientationString: __webpack_require__(21394), + Parse: __webpack_require__(90715), + Parse2DArray: __webpack_require__(84346), + ParseCSV: __webpack_require__(96097), - var i; - var obj; - var render; + Impact: __webpack_require__(24507), + Tiled: __webpack_require__(50044) - for (i = 0; i < bodies.length; i++) - { - obj = bodies[i]; - render = obj.render; +}; - this.setBodyRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.fillColor, render.fillOpacity); - } - for (i = 0; i < constraints.length; i++) - { - obj = constraints[i]; - render = obj.render; +/***/ }), - this.setConstraintRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.pinSize, render.anchorColor, render.anchorSize); - } +/***/ 48646: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (i = 0; i < composites.length; i++) - { - obj = composites[i]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.setCompositeRenderStyle(obj); - } +var Extend = __webpack_require__(98611); - return this; - }, +/** + * 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; - /** - * Sets the debug render style for the given Matter Body. - * - * If you are using this on a Phaser Game Object, such as a Matter Sprite, then pass in the body property - * to this method, not the Game Object itself. - * - * If you wish to skip a parameter, so it retains its current value, pass `false` for it. - * - * If you wish to reset the Body render colors to the defaults found in the World Debug Config, then call - * this method with just the `body` parameter provided and no others. - * - * @method Phaser.Physics.Matter.World#setBodyRenderStyle - * @since 3.22.0 - * - * @param {MatterJS.BodyType} body - The Matter Body to set the render style on. - * @param {number} [lineColor] - The line color. If `null` it will use the World Debug Config value. - * @param {number} [lineOpacity] - The line opacity, between 0 and 1. If `null` it will use the World Debug Config value. - * @param {number} [lineThickness] - The line thickness. If `null` it will use the World Debug Config value. - * @param {number} [fillColor] - The fill color. If `null` it will use the World Debug Config value. - * @param {number} [fillOpacity] - The fill opacity, between 0 and 1. If `null` it will use the World Debug Config value. - * - * @return {this} This Matter World instance for method chaining. - */ - setBodyRenderStyle: function (body, lineColor, lineOpacity, lineThickness, fillColor, fillOpacity) + // go through each of the map data layers + for (var i = 0; i < mapData.layers.length; i++) { - var render = body.render; - var config = this.debugConfig; + layerData = mapData.layers[i]; - if (!render) - { - return this; - } + set = null; - if (lineColor === undefined || lineColor === null) + // rows of tiles + for (var j = 0; j < layerData.data.length; j++) { - lineColor = (body.isStatic) ? config.staticLineColor : config.lineColor; - } + row = layerData.data[j]; - if (lineOpacity === undefined || lineOpacity === null) - { - lineOpacity = config.lineOpacity; - } + // individual tiles + for (var k = 0; k < row.length; k++) + { + tile = row[k]; - if (lineThickness === undefined || lineThickness === null) - { - lineThickness = config.lineThickness; - } + if (tile === null || tile.index < 0) + { + continue; + } - if (fillColor === undefined || fillColor === null) - { - fillColor = (body.isStatic) ? config.staticFillColor : config.fillColor; - } + // find the relevant tileset + sid = mapData.tiles[tile.index][2]; + set = mapData.tilesets[sid]; - if (fillOpacity === undefined || fillOpacity === null) - { - fillOpacity = config.fillOpacity; - } + // Ensure that a tile's size matches its tileset + tile.width = set.tileWidth; + tile.height = set.tileHeight; - if (lineColor !== false) - { - render.lineColor = lineColor; + // 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] + ); + } + } } + } +}; - if (lineOpacity !== false) - { - render.lineOpacity = lineOpacity; - } +module.exports = AssignTileProperties; - if (lineThickness !== false) - { - render.lineThickness = lineThickness; - } - if (fillColor !== false) - { - render.fillColor = fillColor; - } +/***/ }), - if (fillOpacity !== false) - { - render.fillOpacity = fillOpacity; - } +/***/ 43908: +/***/ ((module) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Sets the debug render style for the given Matter Constraint. - * - * If you are using this on a Phaser Game Object, then pass in the body property - * to this method, not the Game Object itself. - * - * If you wish to skip a parameter, so it retains its current value, pass `false` for it. - * - * If you wish to reset the Constraint render colors to the defaults found in the World Debug Config, then call - * this method with just the `constraint` parameter provided and no others. - * - * @method Phaser.Physics.Matter.World#setConstraintRenderStyle - * @since 3.22.0 - * - * @param {MatterJS.ConstraintType} constraint - The Matter Constraint to set the render style on. - * @param {number} [lineColor] - The line color. If `null` it will use the World Debug Config value. - * @param {number} [lineOpacity] - The line opacity, between 0 and 1. If `null` it will use the World Debug Config value. - * @param {number} [lineThickness] - The line thickness. If `null` it will use the World Debug Config value. - * @param {number} [pinSize] - If this constraint is a pin, this sets the size of the pin circle. If `null` it will use the World Debug Config value. - * @param {number} [anchorColor] - The color used when rendering this constraints anchors. If `null` it will use the World Debug Config value. - * @param {number} [anchorSize] - The size of the anchor circle, if this constraint has anchors. If `null` it will use the World Debug Config value. - * - * @return {this} This Matter World instance for method chaining. - */ - setConstraintRenderStyle: function (constraint, lineColor, lineOpacity, lineThickness, pinSize, anchorColor, anchorSize) - { - var render = constraint.render; - var config = this.debugConfig; +/** + * 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); - if (!render) - { - return this; - } + // 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; + } - // Reset them - if (lineColor === undefined || lineColor === null) - { - var type = render.type; + return bytes; +}; - if (type === 'line') - { - lineColor = config.jointColor; - } - else if (type === 'pin') - { - lineColor = config.pinColor; - } - else if (type === 'spring') - { - lineColor = config.springColor; - } - } +module.exports = Base64Decode; - if (lineOpacity === undefined || lineOpacity === null) - { - lineOpacity = config.jointLineOpacity; - } - if (lineThickness === undefined || lineThickness === null) - { - lineThickness = config.jointLineThickness; - } +/***/ }), - if (pinSize === undefined || pinSize === null) - { - pinSize = config.pinSize; - } +/***/ 14556: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (anchorColor === undefined || anchorColor === null) - { - anchorColor = config.anchorColor; - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (anchorSize === undefined || anchorSize === null) - { - anchorSize = config.anchorSize; - } +var Tileset = __webpack_require__(47975); - if (lineColor !== false) - { - render.lineColor = lineColor; - } +/** + * 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 = []; - if (lineOpacity !== false) - { - render.lineOpacity = lineOpacity; - } + for (i = 0; i < mapData.imageCollections.length; i++) + { + var collection = mapData.imageCollections[i]; + var images = collection.images; - if (lineThickness !== false) + for (var j = 0; j < images.length; j++) { - render.lineThickness = lineThickness; - } + var image = images[j]; - if (pinSize !== false) - { - render.pinSize = pinSize; - } + set = new Tileset(image.image, image.gid, collection.imageWidth, collection.imageHeight, 0, 0); - if (anchorColor !== false) - { - render.anchorColor = anchorColor; - } + set.updateTileData(collection.imageWidth, collection.imageHeight); - if (anchorSize !== false) - { - render.anchorSize = anchorSize; + mapData.tilesets.push(set); } + } - return this; - }, - - /** - * This internal method acts as a proxy between all of the Matter JS events and then re-emits them - * via this class. - * - * @method Phaser.Physics.Matter.World#setEventsProxy - * @since 3.0.0 - */ - setEventsProxy: function () + for (i = 0; i < mapData.tilesets.length; i++) { - var _this = this; - var engine = this.engine; - var world = this.localWorld; + set = mapData.tilesets[i]; - // Inject debug styles + var x = set.tileMargin; + var y = set.tileMargin; - if (this.drawDebug) + var count = 0; + var countX = 0; + var countY = 0; + + for (var t = set.firstgid; t < set.firstgid + set.total; t++) { - MatterEvents.on(world, 'compositeModified', function (composite) + // Can add extra properties here as needed + tiles[t] = [ x, y, i ]; + + x += set.tileWidth + set.tileSpacing; + + count++; + + if (count === set.total) { - _this.setCompositeRenderStyle(composite); - }); + break; + } - MatterEvents.on(world, 'beforeAdd', function (event) + countX++; + + if (countX === set.columns) { - var objects = [].concat(event.object); - - for (var i = 0; i < objects.length; i++) + x = set.tileMargin; + y += set.tileHeight + set.tileSpacing; + + countX = 0; + countY++; + + if (countY === set.rows) { - var obj = objects[i]; - var render = obj.render; - - if (obj.type === 'body') - { - _this.setBodyRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.fillColor, render.fillOpacity); - } - else if (obj.type === 'composite') - { - _this.setCompositeRenderStyle(obj); - } - else if (obj.type === 'constraint') - { - _this.setConstraintRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.pinSize, render.anchorColor, render.anchorSize); - } + break; } - }); + } } + } - MatterEvents.on(world, 'beforeAdd', function (event) - { - _this.emit(Events.BEFORE_ADD, event); - }); + return tiles; +}; - MatterEvents.on(world, 'afterAdd', function (event) - { - _this.emit(Events.AFTER_ADD, event); - }); +module.exports = BuildTilesetIndex; - MatterEvents.on(world, 'beforeRemove', function (event) - { - _this.emit(Events.BEFORE_REMOVE, event); - }); - MatterEvents.on(world, 'afterRemove', function (event) - { - _this.emit(Events.AFTER_REMOVE, event); - }); +/***/ }), - MatterEvents.on(engine, 'beforeUpdate', function (event) - { - _this.emit(Events.BEFORE_UPDATE, event); - }); +/***/ 92044: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - MatterEvents.on(engine, 'afterUpdate', function (event) - { - _this.emit(Events.AFTER_UPDATE, event); - }); +/** + * @author Seth Berrier + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - MatterEvents.on(engine, 'collisionStart', function (event) - { - var pairs = event.pairs; - var bodyA; - var bodyB; +var GetFastValue = __webpack_require__(72632); - if (pairs.length > 0) - { - bodyA = pairs[0].bodyA; - bodyB = pairs[0].bodyB; - } +/** + * Parse a Tiled group layer and create a state object for inheriting. + * + * @function Phaser.Tilemaps.Parsers.Tiled.CreateGroupLayer + * @since 3.21.0 + * + * @param {object} json - The Tiled JSON object. + * @param {object} [group] - The current group layer from the Tiled JSON file. + * @param {object} [parentState] - The state of the parent group (if any). + * + * @return {object} A group state object with proper values for updating children layers. + */ +var CreateGroupLayer = function (json, group, parentState) +{ + if (!group) + { + // Return a default group state object + return { + i: 0, // Current layer array iterator + layers: json.layers, // Current array of layers + // Values inherited from parent group + name: '', + opacity: 1, + visible: true, + x: 0, + y: 0 + }; + } - _this.emit(Events.COLLISION_START, event, bodyA, bodyB); - }); + // Compute group layer x, y + var layerX = group.x + GetFastValue(group, 'startx', 0) * json.tilewidth + GetFastValue(group, 'offsetx', 0); + var layerY = group.y + GetFastValue(group, 'starty', 0) * json.tileheight + GetFastValue(group, 'offsety', 0); - MatterEvents.on(engine, 'collisionActive', function (event) - { - var pairs = event.pairs; - var bodyA; - var bodyB; + // Compute next state inherited from group + return { + i: 0, + layers: group.layers, + name: parentState.name + group.name + '/', + opacity: parentState.opacity * group.opacity, + visible: parentState.visible && group.visible, + x: parentState.x + layerX, + y: parentState.y + layerY + }; +}; - if (pairs.length > 0) - { - bodyA = pairs[0].bodyA; - bodyB = pairs[0].bodyB; - } +module.exports = CreateGroupLayer; - _this.emit(Events.COLLISION_ACTIVE, event, bodyA, bodyB); - }); - MatterEvents.on(engine, 'collisionEnd', function (event) - { - var pairs = event.pairs; - var bodyA; - var bodyB; +/***/ }), - if (pairs.length > 0) - { - bodyA = pairs[0].bodyA; - bodyB = pairs[0].bodyB; - } +/***/ 8847: +/***/ ((module) => { - _this.emit(Events.COLLISION_END, event, bodyA, bodyB); - }); - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Sets the bounds of the Physics world to match the given world pixel dimensions. - * You can optionally set which 'walls' to create: left, right, top or bottom. - * If none of the walls are given it will default to use the walls settings it had previously. - * I.e. if you previously told it to not have the left or right walls, and you then adjust the world size - * the newly created bounds will also not have the left and right walls. - * Explicitly state them in the parameters to override this. - * - * @method Phaser.Physics.Matter.World#setBounds - * @since 3.0.0 - * - * @param {number} [x=0] - The x coordinate of the top-left corner of the bounds. - * @param {number} [y=0] - The y coordinate of the top-left corner of the bounds. - * @param {number} [width] - The width of the bounds. - * @param {number} [height] - The height of the bounds. - * @param {number} [thickness=64] - The thickness of each wall, in pixels. - * @param {boolean} [left=true] - If true will create the left bounds wall. - * @param {boolean} [right=true] - If true will create the right bounds wall. - * @param {boolean} [top=true] - If true will create the top bounds wall. - * @param {boolean} [bottom=true] - If true will create the bottom bounds wall. - * - * @return {Phaser.Physics.Matter.World} This Matter World object. - */ - setBounds: function (x, y, width, height, thickness, left, right, top, bottom) +var FLIPPED_HORIZONTAL = 0x80000000; +var FLIPPED_VERTICAL = 0x40000000; +var FLIPPED_ANTI_DIAGONAL = 0x20000000; // Top-right is swapped with bottom-left corners + +/** + * See Tiled documentation on tile flipping: + * http://docs.mapeditor.org/en/latest/reference/tmx-map-format/ + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseGID + * @since 3.0.0 + * + * @param {number} gid - A Tiled GID. + * + * @return {Phaser.Types.Tilemaps.GIDData} The GID Data. + */ +var ParseGID = function (gid) +{ + var flippedHorizontal = Boolean(gid & FLIPPED_HORIZONTAL); + var flippedVertical = Boolean(gid & FLIPPED_VERTICAL); + var flippedAntiDiagonal = Boolean(gid & FLIPPED_ANTI_DIAGONAL); + gid = gid & ~(FLIPPED_HORIZONTAL | FLIPPED_VERTICAL | FLIPPED_ANTI_DIAGONAL); + + // Parse the flip flags into something Phaser can use + var rotation = 0; + var flipped = false; + + if (flippedHorizontal && flippedVertical && flippedAntiDiagonal) { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 0; } - if (width === undefined) { width = this.scene.sys.scale.width; } - if (height === undefined) { height = this.scene.sys.scale.height; } - if (thickness === undefined) { thickness = 64; } - if (left === undefined) { left = true; } - if (right === undefined) { right = true; } - if (top === undefined) { top = true; } - if (bottom === undefined) { bottom = true; } + rotation = Math.PI / 2; + flipped = true; + } + else if (flippedHorizontal && flippedVertical && !flippedAntiDiagonal) + { + rotation = Math.PI; + flipped = false; + } + else if (flippedHorizontal && !flippedVertical && flippedAntiDiagonal) + { + rotation = Math.PI / 2; + flipped = false; + } + else if (flippedHorizontal && !flippedVertical && !flippedAntiDiagonal) + { + rotation = 0; + flipped = true; + } + else if (!flippedHorizontal && flippedVertical && flippedAntiDiagonal) + { + rotation = 3 * Math.PI / 2; + flipped = false; + } + else if (!flippedHorizontal && flippedVertical && !flippedAntiDiagonal) + { + rotation = Math.PI; + flipped = true; + } + else if (!flippedHorizontal && !flippedVertical && flippedAntiDiagonal) + { + rotation = 3 * Math.PI / 2; + flipped = true; + } + else if (!flippedHorizontal && !flippedVertical && !flippedAntiDiagonal) + { + rotation = 0; + flipped = false; + } - this.updateWall(left, 'left', x - thickness, y - thickness, thickness, height + (thickness * 2)); - this.updateWall(right, 'right', x + width, y - thickness, thickness, height + (thickness * 2)); - this.updateWall(top, 'top', x, y - thickness, width, thickness); - this.updateWall(bottom, 'bottom', x, y + height, width, thickness); + return { + gid: gid, + flippedHorizontal: flippedHorizontal, + flippedVertical: flippedVertical, + flippedAntiDiagonal: flippedAntiDiagonal, + rotation: rotation, + flipped: flipped + }; +}; - return this; - }, +module.exports = ParseGID; - /** - * Updates the 4 rectangle bodies that were created, if `setBounds` was set in the Matter config, to use - * the new positions and sizes. This method is usually only called internally via the `setBounds` method. - * - * @method Phaser.Physics.Matter.World#updateWall - * @since 3.0.0 - * - * @param {boolean} add - `true` if the walls are being added or updated, `false` to remove them from the world. - * @param {string} [position] - Either `left`, `right`, `top` or `bottom`. Only optional if `add` is `false`. - * @param {number} [x] - The horizontal position to place the walls at. Only optional if `add` is `false`. - * @param {number} [y] - The vertical position to place the walls at. Only optional if `add` is `false`. - * @param {number} [width] - The width of the walls, in pixels. Only optional if `add` is `false`. - * @param {number} [height] - The height of the walls, in pixels. Only optional if `add` is `false`. - */ - updateWall: function (add, position, x, y, width, height) - { - var wall = this.walls[position]; - if (add) +/***/ }), + +/***/ 78339: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetFastValue = __webpack_require__(72632); +var CreateGroupLayer = __webpack_require__(92044); + +/** + * 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) { - if (wall) + // Ensure recursion stack is not empty first + if (groupStack.length < 1) { - MatterWorld.remove(this.localWorld, wall); + console.warn( + 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' + ); + break; } - // adjust center - x += (width / 2); - y += (height / 2); - - this.walls[position] = this.create(x, y, width, height, { isStatic: true, friction: 0, frictionStatic: 0 }); + // Return to previous recursive state + curGroupState = groupStack.pop(); + continue; } - else + + // Get current layer and advance iterator + var curi = curGroupState.layers[curGroupState.i]; + curGroupState.i++; + + if (curi.type !== 'imagelayer') { - if (wall) + if (curi.type === 'group') { - MatterWorld.remove(this.localWorld, wall); + // Compute next state inherited from group + var nextGroupState = CreateGroupLayer(json, curi, curGroupState); + + // Preserve current state before recursing + groupStack.push(curGroupState); + curGroupState = nextGroupState; } - this.walls[position] = null; + // Skip this layer OR 'recurse' (iterative style) into the group + continue; } - }, - - /** - * Creates a Phaser.GameObjects.Graphics object that is used to render all of the debug bodies and joints to. - * - * This method is called automatically by the constructor, if debugging has been enabled. - * - * The created Graphics object is automatically added to the Scene at 0x0 and given a depth of `Number.MAX_VALUE`, - * so it renders above all else in the Scene. - * - * The Graphics object is assigned to the `debugGraphic` property of this class and `drawDebug` is enabled. - * - * @method Phaser.Physics.Matter.World#createDebugGraphic - * @since 3.0.0 - * - * @return {Phaser.GameObjects.Graphics} The newly created Graphics object. - */ - createDebugGraphic: function () - { - var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 }); - graphic.setDepth(Number.MAX_VALUE); + 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', {}) + }); + } - this.debugGraphic = graphic; + return images; +}; - this.drawDebug = true; +module.exports = ParseImageLayers; - return graphic; - }, - /** - * Sets the world gravity and gravity scale to 0. - * - * @method Phaser.Physics.Matter.World#disableGravity - * @since 3.0.0 - * - * @return {this} This Matter World object. - */ - disableGravity: function () - { - this.localWorld.gravity.x = 0; - this.localWorld.gravity.y = 0; - this.localWorld.gravity.scale = 0; +/***/ }), - return this; - }, +/***/ 2378: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Sets the worlds gravity to the values given. - * - * Gravity effects all bodies in the world, unless they have the `ignoreGravity` flag set. - * - * @method Phaser.Physics.Matter.World#setGravity - * @since 3.0.0 - * - * @param {number} [x=0] - The world gravity x component. - * @param {number} [y=1] - The world gravity y component. - * @param {number} [scale=0.001] - The gravity scale factor. - * - * @return {this} This Matter World object. - */ - setGravity: function (x, y, scale) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = 1; } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.localWorld.gravity.x = x; - this.localWorld.gravity.y = y; +var AssignTileProperties = __webpack_require__(48646); +var BuildTilesetIndex = __webpack_require__(14556); +var CONST = __webpack_require__(12920); +var DeepCopy = __webpack_require__(28699); +var Formats = __webpack_require__(93560); +var FromOrientationString = __webpack_require__(21394); +var MapData = __webpack_require__(16586); +var ParseImageLayers = __webpack_require__(78339); +var ParseObjectLayers = __webpack_require__(61136); +var ParseTileLayers = __webpack_require__(95925); +var ParseTilesets = __webpack_require__(93392); - if (scale !== undefined) - { - this.localWorld.gravity.scale = scale; - } +/** + * 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} source - The original Tiled JSON object. This is deep copied by this function. + * @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, source, insertNull) +{ + var json = DeepCopy(source); - return this; - }, + // 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 + }); - /** - * Creates a rectangle Matter body and adds it to the world. - * - * @method Phaser.Physics.Matter.World#create - * @since 3.0.0 - * - * @param {number} x - The horizontal position of the body in the world. - * @param {number} y - The vertical position of the body in the world. - * @param {number} width - The width of the body. - * @param {number} height - The height of the body. - * @param {object} options - Optional Matter configuration object. - * - * @return {MatterJS.BodyType} The Matter.js body that was created. - */ - create: function (x, y, width, height, options) + if (mapData.orientation === CONST.HEXAGONAL) { - var body = Bodies.rectangle(x, y, width, height, options); + mapData.hexSideLength = json.hexsidelength; + mapData.staggerAxis = json.staggeraxis; + mapData.staggerIndex = json.staggerindex; + } - MatterWorld.add(this.localWorld, body); + mapData.layers = ParseTileLayers(json, insertNull); + mapData.images = ParseImageLayers(json); - return body; - }, + var sets = ParseTilesets(json); - /** - * Adds a Matter JS object, or array of objects, to the world. - * - * The objects should be valid Matter JS entities, such as a Body, Composite or Constraint. - * - * Triggers `beforeAdd` and `afterAdd` events. - * - * @method Phaser.Physics.Matter.World#add - * @since 3.0.0 - * - * @param {(object|object[])} object - Can be single object, or an array, and can be a body, composite or constraint. - * - * @return {this} This Matter World object. - */ - add: function (object) - { - MatterWorld.add(this.localWorld, object); + mapData.tilesets = sets.tilesets; + mapData.imageCollections = sets.imageCollections; - return this; - }, + mapData.objects = ParseObjectLayers(json); - /** - * Removes a Matter JS object, or array of objects, from the world. - * - * The objects should be valid Matter JS entities, such as a Body, Composite or Constraint. - * - * Triggers `beforeRemove` and `afterRemove` events. - * - * @method Phaser.Physics.Matter.World#remove - * @since 3.0.0 - * - * @param {(object|object[])} object - Can be single object, or an array, and can be a body, composite or constraint. - * @param {boolean} [deep=false] - Optionally search the objects children and recursively remove those as well. - * - * @return {this} This Matter World object. - */ - remove: function (object, deep) - { - if (!Array.isArray(object)) - { - object = [ object ]; - } + mapData.tiles = BuildTilesetIndex(mapData); - for (var i = 0; i < object.length; i++) - { - var entity = object[i]; + AssignTileProperties(mapData); - var body = (entity.body) ? entity.body : entity; + return mapData; +}; - Composite.remove(this.localWorld, body, deep); - } +module.exports = ParseJSONTiled; - return this; - }, - /** - * Removes a Matter JS constraint, or array of constraints, from the world. - * - * Triggers `beforeRemove` and `afterRemove` events. - * - * @method Phaser.Physics.Matter.World#removeConstraint - * @since 3.0.0 - * - * @param {(MatterJS.ConstraintType|MatterJS.ConstraintType[])} constraint - A Matter JS Constraint, or an array of constraints, to be removed. - * @param {boolean} [deep=false] - Optionally search the objects children and recursively remove those as well. - * - * @return {this} This Matter World object. - */ - removeConstraint: function (constraint, deep) - { - Composite.remove(this.localWorld, constraint, deep); +/***/ }), - return this; - }, +/***/ 4281: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Adds `MatterTileBody` instances for all the colliding tiles within the given tilemap layer. - * - * Set the appropriate tiles in your layer to collide before calling this method! - * - * @method Phaser.Physics.Matter.World#convertTilemapLayer - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - An array of tiles. - * @param {object} [options] - Options to be passed to the MatterTileBody constructor. {@see Phaser.Physics.Matter.TileBody} - * - * @return {this} This Matter World object. - */ - convertTilemapLayer: function (tilemapLayer, options) - { - var layerData = tilemapLayer.layer; - var tiles = tilemapLayer.getTilesWithin(0, 0, layerData.width, layerData.height, { isColliding: true }); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this.convertTiles(tiles, options); +var Pick = __webpack_require__(28820); +var ParseGID = __webpack_require__(8847); - return this; - }, +var copyPoints = function (p) { return { x: p.x, y: p.y }; }; - /** - * Adds `MatterTileBody` instances for the given tiles. This adds bodies regardless of whether the - * tiles are set to collide or not. - * - * @method Phaser.Physics.Matter.World#convertTiles - * @since 3.0.0 - * - * @param {Phaser.Tilemaps.Tile[]} tiles - An array of tiles. - * @param {object} [options] - Options to be passed to the MatterTileBody constructor. {@see Phaser.Physics.Matter.TileBody} - * - * @return {this} This Matter World object. - */ - convertTiles: function (tiles, options) - { - if (tiles.length === 0) - { - return this; - } +var commonObjectProps = [ 'id', 'name', 'type', 'rotation', 'properties', 'visible', 'x', 'y', 'width', 'height' ]; - for (var i = 0; i < tiles.length; i++) - { - new MatterTileBody(this, tiles[i], options); - } +/** + * Convert a Tiled object to an internal parsed object normalising and copying properties over, while applying optional x and y offsets. The parsed object will always have the properties `id`, `name`, `type`, `rotation`, `properties`, `visible`, `x`, `y`, `width` and `height`. Other properties will be added according to the object type (such as text, polyline, gid etc.) + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseObject + * @since 3.0.0 + * + * @param {object} tiledObject - Tiled object to convert to an internal parsed object normalising and copying properties over. + * @param {number} [offsetX=0] - Optional additional offset to apply to the object's x property. Defaults to 0. + * @param {number} [offsetY=0] - Optional additional offset to apply to the object's y property. Defaults to 0. + * + * @return {object} The parsed object containing properties read from the Tiled object according to it's type with x and y values updated according to the given offsets. + */ +var ParseObject = function (tiledObject, offsetX, offsetY) +{ + if (offsetX === undefined) { offsetX = 0; } + if (offsetY === undefined) { offsetY = 0; } - return this; - }, + var parsedObject = Pick(tiledObject, commonObjectProps); - /** - * Returns the next unique group index for which bodies will collide. - * If `isNonColliding` is `true`, returns the next unique group index for which bodies will not collide. - * - * @method Phaser.Physics.Matter.World#nextGroup - * @since 3.0.0 - * - * @param {boolean} [isNonColliding=false] - If `true`, returns the next unique group index for which bodies will _not_ collide. - * - * @return {number} Unique category bitfield - */ - nextGroup: function (isNonColliding) - { - return MatterBody.nextGroup(isNonColliding); - }, + parsedObject.x += offsetX; + parsedObject.y += offsetY; - /** - * Returns the next unique category bitfield (starting after the initial default category 0x0001). - * There are 32 available. - * - * @method Phaser.Physics.Matter.World#nextCategory - * @since 3.0.0 - * - * @return {number} Unique category bitfield - */ - nextCategory: function () + if (tiledObject.gid) { - return MatterBody.nextCategory(); - }, - - /** - * Pauses this Matter World instance and sets `enabled` to `false`. - * - * A paused world will not run any simulations for the duration it is paused. - * - * @method Phaser.Physics.Matter.World#pause - * @fires Phaser.Physics.Matter.Events#PAUSE - * @since 3.0.0 - * - * @return {this} This Matter World object. - */ - pause: function () + // Object tiles + var gidInfo = ParseGID(tiledObject.gid); + parsedObject.gid = gidInfo.gid; + parsedObject.flippedHorizontal = gidInfo.flippedHorizontal; + parsedObject.flippedVertical = gidInfo.flippedVertical; + parsedObject.flippedAntiDiagonal = gidInfo.flippedAntiDiagonal; + } + else if (tiledObject.polyline) { - this.enabled = false; - - this.emit(Events.PAUSE); - - return this; - }, - - /** - * Resumes this Matter World instance from a paused state and sets `enabled` to `true`. - * - * @method Phaser.Physics.Matter.World#resume - * @fires Phaser.Physics.Matter.Events#RESUME - * @since 3.0.0 - * - * @return {this} This Matter World object. - */ - resume: function () + parsedObject.polyline = tiledObject.polyline.map(copyPoints); + } + else if (tiledObject.polygon) { - this.enabled = true; + parsedObject.polygon = tiledObject.polygon.map(copyPoints); + } + else if (tiledObject.ellipse) + { + parsedObject.ellipse = tiledObject.ellipse; + } + else if (tiledObject.text) + { + parsedObject.text = tiledObject.text; + } + else if (tiledObject.point) + { + parsedObject.point = true; + } + else + { + // Otherwise, assume it is a rectangle + parsedObject.rectangle = true; + } - this.emit(Events.RESUME); + return parsedObject; +}; - return this; - }, +module.exports = ParseObject; - /** - * The internal update method. This is called automatically by the parent Scene. - * - * Moves the simulation forward in time by delta ms. Uses `World.correction` value as an optional number that - * specifies the time correction factor to apply to the update. This can help improve the accuracy of the - * simulation in cases where delta is changing between updates. The value of correction is defined as `delta / lastDelta`, - * i.e. the percentage change of delta over the last step. Therefore the value is always 1 (no correction) when - * delta is constant (or when no correction is desired, which is the default). - * See the paper on Time Corrected Verlet for more information. - * - * Triggers `beforeUpdate` and `afterUpdate` events. Triggers `collisionStart`, `collisionActive` and `collisionEnd` events. - * - * If the World is paused, `update` is still run, but exits early and does not update the Matter Engine. - * - * @method Phaser.Physics.Matter.World#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 (time, delta) - { - if (!this.enabled || !this.autoUpdate) - { - return; - } - var engine = this.engine; - var runner = this.runner; +/***/ }), - var timing = engine.timing; - var correction = this.correction; +/***/ 61136: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (runner.isFixed) - { - // fixed timestep - delta = this.getDelta(time, delta); - } - else - { - // dynamic timestep based on wall clock between calls - delta = (time - runner.timePrev) || runner.delta; - runner.timePrev = time; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // optimistically filter delta over a few frames, to improve stability - runner.deltaHistory.push(delta); - runner.deltaHistory = runner.deltaHistory.slice(-runner.deltaSampleSize); - delta = Math.min.apply(null, runner.deltaHistory); - - // limit delta - delta = delta < runner.deltaMin ? runner.deltaMin : delta; - delta = delta > runner.deltaMax ? runner.deltaMax : delta; +var GetFastValue = __webpack_require__(72632); +var ParseObject = __webpack_require__(4281); +var ObjectLayer = __webpack_require__(15256); +var CreateGroupLayer = __webpack_require__(92044); - // correction for delta - correction = delta / runner.delta; +/** + * 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 = []; - // update engine timing object - runner.delta = delta; - } + // State inherited from a parent group + var groupStack = []; + var curGroupState = CreateGroupLayer(json); - // time correction for time scaling - if (runner.timeScalePrev !== 0) + while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + { + if (curGroupState.i >= curGroupState.layers.length) { - correction *= timing.timeScale / runner.timeScalePrev; - } + // Ensure recursion stack is not empty first + if (groupStack.length < 1) + { + console.warn( + 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' + ); + break; + } - if (timing.timeScale === 0) - { - correction = 0; + // Return to previous recursive state + curGroupState = groupStack.pop(); + continue; } - runner.timeScalePrev = timing.timeScale; - runner.correction = correction; + // Get current layer and advance iterator + var curo = curGroupState.layers[curGroupState.i]; + curGroupState.i++; - // fps counter - runner.frameCounter += 1; + // Modify inherited properties + curo.opacity *= curGroupState.opacity; + curo.visible = curGroupState.visible && curo.visible; - if (time - runner.counterTimestamp >= 1000) + if (curo.type !== 'objectgroup') { - runner.fps = runner.frameCounter * ((time - runner.counterTimestamp) / 1000); - runner.counterTimestamp = time; - runner.frameCounter = 0; + 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; } - Engine.update(engine, delta, correction); - }, + 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); - /** - * Manually advances the physics simulation by one iteration. - * - * You can optionally pass in the `delta` and `correction` values to be used by Engine.update. - * If undefined they use the Matter defaults of 60Hz and no correction. - * - * Calling `step` directly bypasses any checks of `enabled` or `autoUpdate`. - * - * It also ignores any custom `getDelta` functions, as you should be passing the delta - * value in to this call. - * - * You can adjust the number of iterations that Engine.update performs internally. - * Use the Scene Matter Physics config object to set the following properties: - * - * positionIterations (defaults to 6) - * velocityIterations (defaults to 4) - * constraintIterations (defaults to 2) - * - * Adjusting these values can help performance in certain situations, depending on the physics requirements - * of your game. - * - * @method Phaser.Physics.Matter.World#step - * @since 3.4.0 - * - * @param {number} [delta=16.666] - The delta value. - * @param {number} [correction=1] - Optional delta correction value. - */ - step: function (delta, correction) - { - Engine.update(this.engine, delta, correction); - }, + var objects = []; + for (var j = 0; j < curo.objects.length; j++) + { + var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY); - /** - * Runs the Matter Engine.update at a fixed timestep of 60Hz. - * - * @method Phaser.Physics.Matter.World#update60Hz - * @since 3.4.0 - * - * @return {number} The delta value to be passed to Engine.update. - */ - update60Hz: function () - { - return 1000 / 60; - }, + objects.push(parsedObject); + } - /** - * Runs the Matter Engine.update at a fixed timestep of 30Hz. - * - * @method Phaser.Physics.Matter.World#update30Hz - * @since 3.4.0 - * - * @return {number} The delta value to be passed to Engine.update. - */ - update30Hz: function () - { - return 1000 / 30; - }, + var objectLayer = new ObjectLayer(curo); + objectLayer.objects = objects; - /** - * Returns `true` if the given body can be found within the World. - * - * @method Phaser.Physics.Matter.World#has - * @since 3.22.0 - * - * @param {(MatterJS.Body|Phaser.GameObjects.GameObject)} body - The Matter Body, or Game Object, to search for within the world. - * - * @return {MatterJS.BodyType[]} An array of all the Matter JS Bodies in this World. - */ - has: function (body) - { - var src = (body.hasOwnProperty('body')) ? body.body : body; + objectLayers.push(objectLayer); + } - return (Composite.get(this.localWorld, src.id, src.type) !== null); - }, + return objectLayers; +}; - /** - * Returns all the bodies in the Matter World, including all bodies in children, recursively. - * - * @method Phaser.Physics.Matter.World#getAllBodies - * @since 3.22.0 - * - * @return {MatterJS.BodyType[]} An array of all the Matter JS Bodies in this World. - */ - getAllBodies: function () - { - return Composite.allBodies(this.localWorld); - }, +module.exports = ParseObjectLayers; - /** - * Returns all the constraints in the Matter World, including all constraints in children, recursively. - * - * @method Phaser.Physics.Matter.World#getAllConstraints - * @since 3.22.0 - * - * @return {MatterJS.ConstraintType[]} An array of all the Matter JS Constraints in this World. - */ - getAllConstraints: function () - { - return Composite.allConstraints(this.localWorld); - }, - /** - * Returns all the composites in the Matter World, including all composites in children, recursively. - * - * @method Phaser.Physics.Matter.World#getAllComposites - * @since 3.22.0 - * - * @return {MatterJS.CompositeType[]} An array of all the Matter JS Composites in this World. - */ - getAllComposites: function () - { - return Composite.allComposites(this.localWorld); - }, +/***/ }), - /** - * Handles the rendering of bodies and debug information to the debug Graphics object, if enabled. - * - * This method is called automatically by the Scene after all processing has taken place. - * - * @method Phaser.Physics.Matter.World#postUpdate - * @private - * @since 3.0.0 - */ - postUpdate: function () - { - if (!this.drawDebug) - { - return; - } +/***/ 95925: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - var config = this.debugConfig; - var engine = this.engine; - var graphics = this.debugGraphic; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var bodies = Composite.allBodies(this.localWorld); +var Base64Decode = __webpack_require__(43908); +var CONST = __webpack_require__(12920); +var CreateGroupLayer = __webpack_require__(92044); +var FromOrientationString = __webpack_require__(21394); +var GetFastValue = __webpack_require__(72632); +var LayerData = __webpack_require__(94990); +var ParseGID = __webpack_require__(8847); +var Tile = __webpack_require__(29633); - this.debugGraphic.clear(); +/** + * 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 = []; - if (config.showBroadphase && engine.broadphase.controller) - { - this.renderGrid(engine.broadphase, graphics, config.broadphaseColor, 0.5); - } + // State inherited from a parent group + var groupStack = []; + var curGroupState = CreateGroupLayer(json); - if (config.showBounds) + while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) + { + if (curGroupState.i >= curGroupState.layers.length) { - this.renderBodyBounds(bodies, graphics, config.boundsColor, 0.5); - } + // Ensure recursion stack is not empty first + if (groupStack.length < 1) + { + console.warn( + 'TilemapParser.parseTiledJSON - Invalid layer group hierarchy' + ); + break; + } - if (config.showBody || config.showStaticBody) - { - this.renderBodies(bodies); + // Return to previous recursive state + curGroupState = groupStack.pop(); + continue; } - if (config.showJoint) - { - this.renderJoints(); - } + var curl = curGroupState.layers[curGroupState.i]; + curGroupState.i++; - if (config.showAxes || config.showAngleIndicator) + if (curl.type !== 'tilelayer') { - this.renderBodyAxes(bodies, graphics, config.showAxes, config.angleColor, 0.5); - } + if (curl.type === 'group') + { + // Compute next state inherited from group + var nextGroupState = CreateGroupLayer(json, curl, curGroupState); - if (config.showVelocity) - { - this.renderBodyVelocity(bodies, graphics, config.velocityColor, 1, 2); - } + // Preserve current state before recursing + groupStack.push(curGroupState); + curGroupState = nextGroupState; + } - if (config.showSeparations) - { - this.renderSeparations(engine.pairs.list, graphics, config.separationColor); + // Skip this layer OR 'recurse' (iterative style) into the group + continue; } - if (config.showCollisions) + // Base64 decode data if necessary. NOTE: uncompressed base64 only. + if (curl.compression) { - this.renderCollisions(engine.pairs.list, graphics, config.collisionColor); + console.warn( + 'TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer \'' + + curl.name + '\'' + ); + continue; } - }, - - /** - * Renders the Engine Broadphase Controller Grid to the given Graphics instance. - * - * The debug renderer calls this method if the `showBroadphase` config value is set. - * - * This method is used internally by the Matter Debug Renderer, but is also exposed publically should - * you wish to render the Grid to your own Graphics instance. - * - * @method Phaser.Physics.Matter.World#renderGrid - * @since 3.22.0 - * - * @param {MatterJS.Grid} grid - The Matter Grid to be rendered. - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. - * @param {number} lineColor - The line color. - * @param {number} lineOpacity - The line opacity, between 0 and 1. - * - * @return {this} This Matter World instance for method chaining. - */ - renderGrid: function (grid, graphics, lineColor, lineOpacity) - { - graphics.lineStyle(1, lineColor, lineOpacity); - - var bucketKeys = Common.keys(grid.buckets); - - for (var i = 0; i < bucketKeys.length; i++) + else if (curl.encoding && curl.encoding === 'base64') { - var bucketId = bucketKeys[i]; - - if (grid.buckets[bucketId].length < 2) + // Chunks for an infinite map + if (curl.chunks) { - continue; + for (var i = 0; i < curl.chunks.length; i++) + { + curl.chunks[i].data = Base64Decode(curl.chunks[i].data); + } } - var region = bucketId.split(/C|R/); + // Non-infinite map data + if (curl.data) + { + curl.data = Base64Decode(curl.data); + } - graphics.strokeRect( - parseInt(region[1], 10) * grid.bucketWidth, - parseInt(region[2], 10) * grid.bucketHeight, - grid.bucketWidth, - grid.bucketHeight - ); + delete curl.encoding; // Allow the same map to be parsed multiple times } - return this; - }, + // 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. - /** - * Renders the list of Pair separations to the given Graphics instance. - * - * The debug renderer calls this method if the `showSeparations` config value is set. - * - * This method is used internally by the Matter Debug Renderer, but is also exposed publically should - * you wish to render the Grid to your own Graphics instance. - * - * @method Phaser.Physics.Matter.World#renderSeparations - * @since 3.22.0 - * - * @param {MatterJS.Pair[]} pairs - An array of Matter Pairs to be rendered. - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. - * @param {number} lineColor - The line color. - * - * @return {this} This Matter World instance for method chaining. - */ - renderSeparations: function (pairs, graphics, lineColor) - { - graphics.lineStyle(1, lineColor, 1); + var layerData; + var gidInfo; + var tile; + var blankTile; - for (var i = 0; i < pairs.length; i++) - { - var pair = pairs[i]; + var output = []; + var x = 0; - if (!pair.isActive) - { - continue; - } + if (infiniteMap) + { + var layerOffsetX = (GetFastValue(curl, 'startx', 0) + curl.x); + var layerOffsetY = (GetFastValue(curl, 'starty', 0) + curl.y); - var collision = pair.collision; - var bodyA = collision.bodyA; - var bodyB = collision.bodyB; - var posA = bodyA.position; - var posB = bodyB.position; - var penetration = collision.penetration; + 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) + }); - var k = (!bodyA.isStatic && !bodyB.isStatic) ? 4 : 1; - - if (bodyB.isStatic) + if (layerData.orientation === CONST.HEXAGONAL) { - k = 0; + layerData.hexSideLength = json.hexsidelength; + layerData.staggerAxis = json.staggeraxis; + layerData.staggerIndex = json.staggerindex; } - graphics.lineBetween( - posB.x, - posB.y, - posB.x - (penetration.x * k), - posB.y - (penetration.y * k) - ); + for (var c = 0; c < curl.height; c++) + { + output[c] = [ null ]; - k = (!bodyA.isStatic && !bodyB.isStatic) ? 4 : 1; + for (var j = 0; j < curl.width; j++) + { + output[c][j] = null; + } + } - if (bodyA.isStatic) + for (c = 0, len = curl.chunks.length; c < len; c++) { - k = 0; - } + var chunk = curl.chunks[c]; - graphics.lineBetween( - posA.x, - posA.y, - posA.x - (penetration.x * k), - posA.y - (penetration.y * k) - ); - } + var offsetX = (chunk.x - layerOffsetX); + var offsetY = (chunk.y - layerOffsetY); - return this; - }, + var y = 0; - /** - * Renders the list of collision points and normals to the given Graphics instance. - * - * The debug renderer calls this method if the `showCollisions` config value is set. - * - * This method is used internally by the Matter Debug Renderer, but is also exposed publically should - * you wish to render the Grid to your own Graphics instance. - * - * @method Phaser.Physics.Matter.World#renderCollisions - * @since 3.22.0 - * - * @param {MatterJS.Pair[]} pairs - An array of Matter Pairs to be rendered. - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. - * @param {number} lineColor - The line color. - * - * @return {this} This Matter World instance for method chaining. - */ - renderCollisions: function (pairs, graphics, lineColor) - { - graphics.lineStyle(1, lineColor, 0.5); - graphics.fillStyle(lineColor, 1); + for (var t = 0, len2 = chunk.data.length; t < len2; t++) + { + var newOffsetX = x + offsetX; + var newOffsetY = y + offsetY; - var i; - var pair; + gidInfo = ParseGID(chunk.data[t]); - // Collision Positions + // index, x, y, width, height + if (gidInfo.gid > 0) + { + tile = new Tile(layerData, gidInfo.gid, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); - for (i = 0; i < pairs.length; i++) - { - pair = pairs[i]; + // Turning Tiled's FlippedHorizontal, FlippedVertical and FlippedAntiDiagonal + // propeties into flipX, flipY and rotation + tile.rotation = gidInfo.rotation; + tile.flipX = gidInfo.flipped; - if (!pair.isActive) - { - continue; - } + output[newOffsetY][newOffsetX] = tile; + } + else + { + blankTile = insertNull + ? null + : new Tile(layerData, -1, newOffsetX, newOffsetY, json.tilewidth, json.tileheight); + + output[newOffsetY][newOffsetX] = blankTile; + } - for (var j = 0; j < pair.activeContacts.length; j++) - { - var contact = pair.activeContacts[j]; - var vertex = contact.vertex; + x++; - graphics.fillRect(vertex.x - 2, vertex.y - 2, 5, 5); + if (x === chunk.width) + { + y++; + x = 0; + } + } } } - - // Collision Normals - - for (i = 0; i < pairs.length; i++) + else { - pair = pairs[i]; + 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 (!pair.isActive) + if (layerData.orientation === CONST.HEXAGONAL) { - continue; + layerData.hexSideLength = json.hexsidelength; + layerData.staggerAxis = json.staggeraxis; + layerData.staggerIndex = json.staggerindex; } + var row = []; - var collision = pair.collision; - var contacts = pair.activeContacts; - - if (contacts.length > 0) + // Loop through the data field in the JSON. + for (var k = 0, len = curl.data.length; k < len; k++) { - var normalPosX = contacts[0].vertex.x; - var normalPosY = contacts[0].vertex.y; + gidInfo = ParseGID(curl.data[k]); - if (contacts.length === 2) + // index, x, y, width, height + if (gidInfo.gid > 0) { - normalPosX = (contacts[0].vertex.x + contacts[1].vertex.x) / 2; - normalPosY = (contacts[0].vertex.y + contacts[1].vertex.y) / 2; - } + tile = new Tile(layerData, gidInfo.gid, x, output.length, json.tilewidth, json.tileheight); - if (collision.bodyB === collision.supports[0].body || collision.bodyA.isStatic) - { - graphics.lineBetween( - normalPosX - collision.normal.x * 8, - normalPosY - collision.normal.y * 8, - normalPosX, - normalPosY - ); + // 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 { - graphics.lineBetween( - normalPosX + collision.normal.x * 8, - normalPosY + collision.normal.y * 8, - normalPosX, - normalPosY - ); + 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 = []; } } } - return this; - }, + layerData.data = output; + tileLayers.push(layerData); + } - /** - * Renders the bounds of an array of Bodies to the given Graphics instance. - * - * If the body is a compound body, it will render the bounds for the parent compound. - * - * The debug renderer calls this method if the `showBounds` config value is set. - * - * This method is used internally by the Matter Debug Renderer, but is also exposed publically should - * you wish to render bounds to your own Graphics instance. - * - * @method Phaser.Physics.Matter.World#renderBodyBounds - * @since 3.22.0 - * - * @param {array} bodies - An array of bodies from the localWorld. - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. - * @param {number} lineColor - The line color. - * @param {number} lineOpacity - The line opacity, between 0 and 1. - */ - renderBodyBounds: function (bodies, graphics, lineColor, lineOpacity) - { - graphics.lineStyle(1, lineColor, lineOpacity); + return tileLayers; +}; - for (var i = 0; i < bodies.length; i++) - { - var body = bodies[i]; +module.exports = ParseTileLayers; - // 1) Don't show invisible bodies - if (!body.render.visible) - { - continue; - } - var bounds = body.bounds; +/***/ }), - if (bounds) - { - graphics.strokeRect( - bounds.min.x, - bounds.min.y, - bounds.max.x - bounds.min.x, - bounds.max.y - bounds.min.y - ); - } - else - { - var parts = body.parts; +/***/ 93392: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (var j = parts.length > 1 ? 1 : 0; j < parts.length; j++) - { - var part = parts[j]; - - graphics.strokeRect( - part.bounds.min.x, - part.bounds.min.y, - part.bounds.max.x - part.bounds.min.x, - part.bounds.max.y - part.bounds.min.y - ); - } - } - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +var Tileset = __webpack_require__(47975); +var ImageCollection = __webpack_require__(97042); +var ParseObject = __webpack_require__(4281); +var ParseWangsets = __webpack_require__(39642); - /** - * Renders either all axes, or a single axis indicator, for an array of Bodies, to the given Graphics instance. - * - * The debug renderer calls this method if the `showAxes` or `showAngleIndicator` config values are set. - * - * This method is used internally by the Matter Debug Renderer, but is also exposed publically should - * you wish to render bounds to your own Graphics instance. - * - * @method Phaser.Physics.Matter.World#renderBodyAxes - * @since 3.22.0 - * - * @param {array} bodies - An array of bodies from the localWorld. - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. - * @param {boolean} showAxes - If `true` it will render all body axes. If `false` it will render a single axis indicator. - * @param {number} lineColor - The line color. - * @param {number} lineOpacity - The line opacity, between 0 and 1. - */ - renderBodyAxes: function (bodies, graphics, showAxes, lineColor, lineOpacity) +/** + * 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++) { - graphics.lineStyle(1, lineColor, lineOpacity); + // name, firstgid, width, height, margin, spacing, properties + var set = json.tilesets[i]; - for (var i = 0; i < bodies.length; i++) + if (set.source) { - var body = bodies[i]; - var parts = body.parts; + 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, undefined, undefined, set.tileoffset); - // 1) Don't show invisible bodies - if (!body.render.visible) + if (json.version > 1) { - continue; - } - - var part; - var j; - var k; + var datas = undefined; + var props = undefined; - if (showAxes) - { - for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) + if (Array.isArray(set.tiles)) { - part = parts[j]; - - for (k = 0; k < part.axes.length; k++) + datas = datas || {}; + props = props || {}; + + // Tiled 1.2+ + for (var t = 0; t < set.tiles.length; t++) { - var axis = part.axes[k]; + var tile = set.tiles[t]; - graphics.lineBetween( - part.position.x, - part.position.y, - part.position.x + axis.x * 20, - part.position.y + axis.y * 20 - ); + // 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) + { + (datas[tile.id] || (datas[tile.id] = {})).objectgroup = tile.objectgroup; + + if (tile.objectgroup.objects) + { + var parsedObjects2 = tile.objectgroup.objects.map(function (obj) + { + return ParseObject(obj); + }); + + datas[tile.id].objectgroup.objects = parsedObjects2; + } + } + + // Copy animation data + if (tile.animation) + { + (datas[tile.id] || (datas[tile.id] = {})).animation = tile.animation; + } + + // Copy tile `type` field + // (see https://doc.mapeditor.org/en/latest/manual/custom-properties/#typed-tiles). + if (tile.type) + { + (datas[tile.id] || (datas[tile.id] = {})).type = tile.type; + } } } + + if (Array.isArray(set.wangsets)) + { + datas = datas || {}; + props = props || {}; + + ParseWangsets(set.wangsets, datas); + } + + if (datas) // Implies also props is set. + { + newSet.tileData = datas; + newSet.tileProperties = props; + } } else { - for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) + // Tiled 1 + + // Properties stored per-tile in object with string indexes starting at "0" + if (set.tileproperties) { - part = parts[j]; - - for (k = 0; k < part.axes.length; k++) + 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) { - graphics.lineBetween( - part.position.x, - part.position.y, - (part.vertices[0].x + part.vertices[part.vertices.length - 1].x) / 2, - (part.vertices[0].y + part.vertices[part.vertices.length - 1].y) / 2 - ); + 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; + } } } } - } - return this; - }, - - /** - * Renders a velocity indicator for an array of Bodies, to the given Graphics instance. - * - * The debug renderer calls this method if the `showVelocity` config value is set. - * - * This method is used internally by the Matter Debug Renderer, but is also exposed publically should - * you wish to render bounds to your own Graphics instance. - * - * @method Phaser.Physics.Matter.World#renderBodyVelocity - * @since 3.22.0 - * - * @param {array} bodies - An array of bodies from the localWorld. - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. - * @param {number} lineColor - The line color. - * @param {number} lineOpacity - The line opacity, between 0 and 1. - * @param {number} lineThickness - The line thickness. - */ - renderBodyVelocity: function (bodies, graphics, lineColor, lineOpacity, lineThickness) - { - graphics.lineStyle(lineThickness, lineColor, lineOpacity); + // 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); - for (var i = 0; i < bodies.length; i++) + tilesets.push(newSet); + } + else { - var body = bodies[i]; + var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties); - // 1) Don't show invisible bodies - if (!body.render.visible) + var maxId = 0; + + for (t = 0; t < set.tiles.length; t++) { - continue; + 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); } - graphics.lineBetween( - body.position.x, - body.position.y, - body.position.x + (body.position.x - body.positionPrev.x) * 2, - body.position.y + (body.position.y - body.positionPrev.y) * 2 - ); + newCollection.maxId = maxId; + + imageCollections.push(newCollection); } - return this; - }, + // We've got a new Tileset, so set the lastgid into the previous one + if (lastSet) + { + lastSet.lastgid = set.firstgid - 1; + } - /** - * Renders the given array of Bodies to the debug graphics instance. - * - * Called automatically by the `postUpdate` method. - * - * @method Phaser.Physics.Matter.World#renderBodies - * @private - * @since 3.14.0 - * - * @param {array} bodies - An array of bodies from the localWorld. - */ - renderBodies: function (bodies) - { - var graphics = this.debugGraphic; + lastSet = set; + } - var config = this.debugConfig; + return { tilesets: tilesets, imageCollections: imageCollections }; +}; - var showBody = config.showBody; - var showStaticBody = config.showStaticBody; - var showSleeping = config.showSleeping; - var showInternalEdges = config.showInternalEdges; - var showConvexHulls = config.showConvexHulls; +module.exports = ParseTilesets; - var renderFill = config.renderFill; - var renderLine = config.renderLine; - var staticBodySleepOpacity = config.staticBodySleepOpacity; - var sleepFillColor = config.sleepFillColor; - var sleepLineColor = config.sleepLineColor; +/***/ }), - var hullColor = config.hullColor; +/***/ 39642: +/***/ ((module) => { - for (var i = 0; i < bodies.length; i++) - { - var body = bodies[i]; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // 1) Don't show invisible bodies - if (!body.render.visible) - { - continue; - } +/** + * Parses out the Wangset information from Tiled 1.1.5+ map data, if present. + * + * Since a given tile can be in more than one wangset, the resulting properties + * are nested. `tile.data.wangid[someWangsetName]` will return the array-based wang id in + * this implementation. + * + * Note that we're not guaranteed that there will be any 'normal' tiles if the only + * thing in the tilset are wangtile definitions, so this has to be parsed separately. + * + * See https://doc.mapeditor.org/en/latest/manual/using-wang-tiles/ for more information. + * + * @function Phaser.Tilemaps.Parsers.Tiled.ParseWangsets + * @since 3.53.0 + * + * @param {Array.} wangsets - The array of wangset objects (parsed from JSON) + * @param {object} datas - The field into which to put wangset data from Tiled. + * + * @return {object} An object containing the tileset and image collection data. + */ +var ParseWangsets = function (wangsets, datas) +{ + for (var w = 0; w < wangsets.length; w++) + { + var wangset = wangsets[w]; + var identifier = w; - // 2) Don't show static bodies, OR - // 3) Don't show dynamic bodies - if ((!showStaticBody && body.isStatic) || (!showBody && !body.isStatic)) - { - continue; - } + if (wangset.name && wangset.name !== '') + { + identifier = wangset.name; + } - var lineColor = body.render.lineColor; - var lineOpacity = body.render.lineOpacity; - var lineThickness = body.render.lineThickness; - var fillColor = body.render.fillColor; - var fillOpacity = body.render.fillOpacity; + if (Array.isArray(wangset.wangtiles) && wangset.wangtiles.length > 0) + { + var edgeColors = {}; + var cornerColors = {}; - if (showSleeping && body.isSleeping) + var c; + var color; + var colorIndex; + + // Tiled before v2020.09.09 + if (Array.isArray(wangset.edgecolors)) { - if (body.isStatic) + for (c = 0; c < wangset.edgecolors.length; c++) { - lineOpacity *= staticBodySleepOpacity; - fillOpacity *= staticBodySleepOpacity; + colorIndex = 1 + c; + color = wangset.edgecolors[c]; + + if (color.name !== '') + { + edgeColors[colorIndex] = color.name; + } } - else + } + + if (Array.isArray(wangset.cornercolors)) + { + for (c = 0; c < wangset.cornercolors.length; c++) { - lineColor = sleepLineColor; - fillColor = sleepFillColor; + colorIndex = 1 + c; + color = wangset.cornercolors[c]; + + if (color.name !== '') + { + cornerColors[colorIndex] = color.name; + } } } - if (!renderFill) + // Tiled after v2020.09.09 + if (Array.isArray(wangset.colors)) { - fillColor = null; + for (c = 0; c < wangset.colors.length; c++) + { + color = wangset.colors[c]; + colorIndex = 1 + c; + + if (color.name !== '') + { + edgeColors[colorIndex] = cornerColors[colorIndex] = color.name; + } + } } - if (!renderLine) + // The wangid layout is north, northeast, east, southeast, etc. + var idLayout = [ + edgeColors, cornerColors, edgeColors, cornerColors, + edgeColors, cornerColors, edgeColors, cornerColors + ]; + + for (var t = 0; t < wangset.wangtiles.length; t++) { - lineColor = null; - } + var wangtile = wangset.wangtiles[t]; - this.renderBody(body, graphics, showInternalEdges, lineColor, lineOpacity, lineThickness, fillColor, fillOpacity); + var obj = (datas[wangtile.tileid] || (datas[wangtile.tileid] = {})); - var partsLength = body.parts.length; + obj = (obj.wangid || (obj.wangid = {})); - if (showConvexHulls && partsLength > 1) - { - this.renderConvexHull(body, graphics, hullColor, lineThickness); + var wangid = []; + + for (var i = 0; i < Math.min(idLayout.length, wangtile.wangid.length); i++) + { + color = wangtile.wangid[i]; + + if (color === 0) + { + wangid.push(undefined); + continue; + } + + var renamed = idLayout[i][color]; + + if (renamed !== undefined) + { + wangid.push(renamed); + continue; + } + + wangid.push(color); + } + + obj[identifier] = wangid; } } - }, + } +}; - /** - * Renders a single Matter Body to the given Phaser Graphics Game Object. - * - * This method is used internally by the Matter Debug Renderer, but is also exposed publically should - * you wish to render a Body to your own Graphics instance. - * - * If you don't wish to render a line around the body, set the `lineColor` parameter to `null`. - * Equally, if you don't wish to render a fill, set the `fillColor` parameter to `null`. - * - * @method Phaser.Physics.Matter.World#renderBody - * @since 3.22.0 - * - * @param {MatterJS.BodyType} body - The Matter Body to be rendered. - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. - * @param {boolean} showInternalEdges - Render internal edges of the polygon? - * @param {number} [lineColor] - The line color. - * @param {number} [lineOpacity] - The line opacity, between 0 and 1. - * @param {number} [lineThickness=1] - The line thickness. - * @param {number} [fillColor] - The fill color. - * @param {number} [fillOpacity] - The fill opacity, between 0 and 1. - * - * @return {this} This Matter World instance for method chaining. - */ - renderBody: function (body, graphics, showInternalEdges, lineColor, lineOpacity, lineThickness, fillColor, fillOpacity) - { - if (lineColor === undefined) { lineColor = null; } - if (lineOpacity === undefined) { lineOpacity = null; } - if (lineThickness === undefined) { lineThickness = 1; } - if (fillColor === undefined) { fillColor = null; } - if (fillOpacity === undefined) { fillOpacity = null; } +module.exports = ParseWangsets; - var config = this.debugConfig; - var sensorFillColor = config.sensorFillColor; - var sensorLineColor = config.sensorLineColor; +/***/ }), - // Handle compound parts - var parts = body.parts; - var partsLength = parts.length; +/***/ 50044: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (var k = (partsLength > 1) ? 1 : 0; k < partsLength; k++) - { - var part = parts[k]; - var render = part.render; - var opacity = render.opacity; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (!render.visible || opacity === 0 || (part.isSensor && !config.showSensors)) - { - continue; - } +/** + * @namespace Phaser.Tilemaps.Parsers.Tiled + */ - // Part polygon - var circleRadius = part.circleRadius; +module.exports = { - graphics.beginPath(); + AssignTileProperties: __webpack_require__(48646), + Base64Decode: __webpack_require__(43908), + BuildTilesetIndex: __webpack_require__(14556), + CreateGroupLayer: __webpack_require__(92044), + ParseGID: __webpack_require__(8847), + ParseImageLayers: __webpack_require__(78339), + ParseJSONTiled: __webpack_require__(2378), + ParseObject: __webpack_require__(4281), + ParseObjectLayers: __webpack_require__(61136), + ParseTileLayers: __webpack_require__(95925), + ParseTilesets: __webpack_require__(93392) - if (part.isSensor) - { - if (fillColor !== null) - { - graphics.fillStyle(sensorFillColor, fillOpacity * opacity); - } - - if (lineColor !== null) - { - graphics.lineStyle(lineThickness, sensorLineColor, lineOpacity * opacity); - } - } - else - { - if (fillColor !== null) - { - graphics.fillStyle(fillColor, fillOpacity * opacity); - } - - if (lineColor !== null) - { - graphics.lineStyle(lineThickness, lineColor, lineOpacity * opacity); - } - } +}; - if (circleRadius) - { - graphics.arc(part.position.x, part.position.y, circleRadius, 0, 2 * Math.PI); - } - else - { - var vertices = part.vertices; - var vertLength = vertices.length; - graphics.moveTo(vertices[0].x, vertices[0].y); +/***/ }), - for (var j = 1; j < vertLength; j++) - { - var vert = vertices[j]; +/***/ 73779: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (!vertices[j - 1].isInternal || showInternalEdges) - { - graphics.lineTo(vert.x, vert.y); - } - else - { - graphics.moveTo(vert.x, vert.y); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (j < vertLength && vert.isInternal && !showInternalEdges) - { - var nextIndex = (j + 1) % vertLength; +var Class = __webpack_require__(56694); +var PluginCache = __webpack_require__(91963); +var SceneEvents = __webpack_require__(7599); +var TimerEvent = __webpack_require__(57911); +var Remove = __webpack_require__(66458); - graphics.moveTo(vertices[nextIndex].x, vertices[nextIndex].y); - } - } - - graphics.closePath(); - } +/** + * @classdesc + * The Clock is a Scene plugin which creates and updates Timer Events for its Scene. + * + * @class Clock + * @memberof Phaser.Time + * @constructor + * @since 3.0.0 + * + * @param {Phaser.Scene} scene - The Scene which owns this Clock. + */ +var Clock = new Class({ - if (fillColor !== null) - { - graphics.fillPath(); - } + initialize: - if (lineColor !== null) - { - graphics.strokePath(); - } - } + function Clock (scene) + { + /** + * The Scene which owns this Clock. + * + * @name Phaser.Time.Clock#scene + * @type {Phaser.Scene} + * @since 3.0.0 + */ + this.scene = scene; - if (config.showPositions && !body.isStatic) - { - var px = body.position.x; - var py = body.position.y; - var hs = Math.ceil(config.positionSize / 2); + /** + * The Scene Systems object of the Scene which owns this Clock. + * + * @name Phaser.Time.Clock#systems + * @type {Phaser.Scenes.Systems} + * @since 3.0.0 + */ + this.systems = scene.sys; - graphics.fillStyle(config.positionColor, 1); - graphics.fillRect(px - hs, py - hs, config.positionSize, config.positionSize); - } + /** + * The current time of the Clock, in milliseconds. + * + * If accessed externally, this is equivalent to the `time` parameter normally passed to a Scene's `update` method. + * + * @name Phaser.Time.Clock#now + * @type {number} + * @since 3.0.0 + */ + this.now = 0; - return this; + /** + * The time the Clock (and Scene) started, in milliseconds. + * + * This can be compared to the `time` parameter passed to a Scene's `update` method. + * + * @name Phaser.Time.Clock#startTime + * @type {number} + * @since 3.60.0 + */ + this.startTime = 0; + + /** + * The scale of the Clock's time delta. + * + * The time delta is the time elapsed between two consecutive frames and influences the speed of time for this Clock and anything which uses it, such as its Timer Events. Values higher than 1 increase the speed of time, while values smaller than 1 decrease it. A value of 0 freezes time and is effectively equivalent to pausing the Clock. + * + * @name Phaser.Time.Clock#timeScale + * @type {number} + * @default 1 + * @since 3.0.0 + */ + this.timeScale = 1; + + /** + * Whether the Clock is paused (`true`) or active (`false`). + * + * When paused, the Clock will not update any of its Timer Events, thus freezing time. + * + * @name Phaser.Time.Clock#paused + * @type {boolean} + * @default false + * @since 3.0.0 + */ + this.paused = false; + + /** + * An array of all Timer Events whose delays haven't expired - these are actively updating Timer Events. + * + * @name Phaser.Time.Clock#_active + * @type {Phaser.Time.TimerEvent[]} + * @private + * @default [] + * @since 3.0.0 + */ + this._active = []; + + /** + * An array of all Timer Events which will be added to the Clock at the start of the next frame. + * + * @name Phaser.Time.Clock#_pendingInsertion + * @type {Phaser.Time.TimerEvent[]} + * @private + * @default [] + * @since 3.0.0 + */ + this._pendingInsertion = []; + + /** + * An array of all Timer Events which will be removed from the Clock at the start of the next frame. + * + * @name Phaser.Time.Clock#_pendingRemoval + * @type {Phaser.Time.TimerEvent[]} + * @private + * @default [] + * @since 3.0.0 + */ + this._pendingRemoval = []; + + scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + scene.sys.events.on(SceneEvents.START, this.start, this); }, /** - * Renders the Convex Hull for a single Matter Body to the given Phaser Graphics Game Object. - * - * This method is used internally by the Matter Debug Renderer, but is also exposed publically should - * you wish to render a Body hull to your own Graphics instance. - * - * @method Phaser.Physics.Matter.World#renderConvexHull - * @since 3.22.0 - * - * @param {MatterJS.BodyType} body - The Matter Body to be rendered. - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. - * @param {number} hullColor - The color used to render the hull. - * @param {number} [lineThickness=1] - The hull line thickness. - * - * @return {this} This Matter World instance for method chaining. + * This method is called automatically, only once, when the Scene is first created. + * Do not invoke it directly. + * + * @method Phaser.Time.Clock#boot + * @private + * @since 3.5.1 */ - renderConvexHull: function (body, graphics, hullColor, lineThickness) + boot: function () { - if (lineThickness === undefined) { lineThickness = 1; } + // Sync with the TimeStep + this.now = this.systems.game.loop.time; - var parts = body.parts; - var partsLength = parts.length; + this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); + }, - // Render Convex Hulls - if (partsLength > 1) + /** + * This method is called automatically by the Scene when it is starting up. + * It is responsible for creating local systems, properties and listening for Scene events. + * Do not invoke it directly. + * + * @method Phaser.Time.Clock#start + * @private + * @since 3.5.0 + */ + start: function () + { + this.startTime = this.systems.game.loop.time; + + var eventEmitter = this.systems.events; + + eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this); + eventEmitter.on(SceneEvents.UPDATE, this.update, this); + eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); + }, + + /** + * Creates a Timer Event and adds it to this Clock at the start of the next frame. + * + * You can pass in either a `TimerEventConfig` object, from with a new `TimerEvent` will + * be created, or you can pass in a `TimerEvent` instance. + * + * If passing an instance please make sure that this instance hasn't been used before. + * If it has ever entered a 'completed' state then it will no longer be suitable to + * run again. + * + * Also, if the `TimerEvent` instance is being used by _another_ Clock (in another Scene) + * it will still be updated by that Clock as well, so be careful when using this feature. + * + * @method Phaser.Time.Clock#addEvent + * @since 3.0.0 + * + * @param {(Phaser.Time.TimerEvent | Phaser.Types.Time.TimerEventConfig)} config - The configuration for the Timer Event, or an existing Timer Event object. + * + * @return {Phaser.Time.TimerEvent} The Timer Event which was created, or passed in. + */ + addEvent: function (config) + { + var event; + + if (config instanceof TimerEvent) { - var verts = body.vertices; + event = config; - graphics.lineStyle(lineThickness, hullColor); + this.removeEvent(event); - graphics.beginPath(); + event.elapsed = event.startAt; + event.hasDispatched = false; + event.repeatCount = (event.repeat === -1 || event.loop) ? 999999999999 : event.repeat; + } + else + { + event = new TimerEvent(config); + } - graphics.moveTo(verts[0].x, verts[0].y); + this._pendingInsertion.push(event); - for (var v = 1; v < verts.length; v++) - { - graphics.lineTo(verts[v].x, verts[v].y); - } - - graphics.lineTo(verts[0].x, verts[0].y); + return event; + }, - graphics.strokePath(); + /** + * Creates a Timer Event and adds it to the Clock at the start of the frame. + * + * This is a shortcut for {@link #addEvent} which can be shorter and is compatible with the syntax of the GreenSock Animation Platform (GSAP). + * + * @method Phaser.Time.Clock#delayedCall + * @since 3.0.0 + * + * @param {number} delay - The delay of the function call, in milliseconds. + * @param {function} callback - The function to call after the delay expires. + * @param {Array.<*>} [args] - The arguments to call the function with. + * @param {*} [callbackScope] - The scope (`this` object) to call the function with. + * + * @return {Phaser.Time.TimerEvent} The Timer Event which was created. + */ + delayedCall: function (delay, callback, args, callbackScope) + { + return this.addEvent({ delay: delay, callback: callback, args: args, callbackScope: callbackScope }); + }, + + /** + * Clears and recreates the array of pending Timer Events. + * + * @method Phaser.Time.Clock#clearPendingEvents + * @since 3.0.0 + * + * @return {this} - This Clock instance. + */ + clearPendingEvents: function () + { + this._pendingInsertion = []; + + return this; + }, + + /** + * Removes the given Timer Event, or an array of Timer Events, from this Clock. + * + * The events are removed from all internal lists (active, pending and removal), + * freeing the event up to be re-used. + * + * @method Phaser.Time.Clock#removeEvent + * @since 3.50.0 + * + * @param {(Phaser.Time.TimerEvent | Phaser.Time.TimerEvent[])} events - The Timer Event, or an array of Timer Events, to remove from this Clock. + * + * @return {this} - This Clock instance. + */ + removeEvent: function (events) + { + if (!Array.isArray(events)) + { + events = [ events ]; + } + + for (var i = 0; i < events.length; i++) + { + var event = events[i]; + + Remove(this._pendingRemoval, event); + Remove(this._pendingInsertion, event); + Remove(this._active, event); } return this; }, /** - * Renders all of the constraints in the world (unless they are specifically set to invisible). - * - * Called automatically by the `postUpdate` method. + * Schedules all active Timer Events for removal at the start of the frame. * - * @method Phaser.Physics.Matter.World#renderJoints - * @private - * @since 3.14.0 + * @method Phaser.Time.Clock#removeAllEvents + * @since 3.0.0 + * + * @return {this} - This Clock instance. */ - renderJoints: function () + removeAllEvents: function () { - var graphics = this.debugGraphic; + this._pendingRemoval = this._pendingRemoval.concat(this._active); - // Render constraints - var constraints = Composite.allConstraints(this.localWorld); + return this; + }, + + /** + * Updates the arrays of active and pending Timer Events. Called at the start of the frame. + * + * @method Phaser.Time.Clock#preUpdate + * @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. + */ + preUpdate: function () + { + var toRemove = this._pendingRemoval.length; + var toInsert = this._pendingInsertion.length; + + if (toRemove === 0 && toInsert === 0) + { + // Quick bail + return; + } + + var i; + var event; + + // Delete old events + for (i = 0; i < toRemove; i++) + { + event = this._pendingRemoval[i]; + + var index = this._active.indexOf(event); + + if (index > -1) + { + this._active.splice(index, 1); + } + + // Pool them? + event.destroy(); + } - for (var i = 0; i < constraints.length; i++) + for (i = 0; i < toInsert; i++) { - var config = constraints[i].render; - - var lineColor = config.lineColor; - var lineOpacity = config.lineOpacity; - var lineThickness = config.lineThickness; - var pinSize = config.pinSize; - var anchorColor = config.anchorColor; - var anchorSize = config.anchorSize; + event = this._pendingInsertion[i]; - this.renderConstraint(constraints[i], graphics, lineColor, lineOpacity, lineThickness, pinSize, anchorColor, anchorSize); + this._active.push(event); } + + // Clear the lists + this._pendingRemoval.length = 0; + this._pendingInsertion.length = 0; }, /** - * Renders a single Matter Constraint, such as a Pin or a Spring, to the given Phaser Graphics Game Object. - * - * This method is used internally by the Matter Debug Renderer, but is also exposed publically should - * you wish to render a Constraint to your own Graphics instance. - * - * @method Phaser.Physics.Matter.World#renderConstraint - * @since 3.22.0 - * - * @param {MatterJS.ConstraintType} constraint - The Matter Constraint to render. - * @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to. - * @param {number} lineColor - The line color. - * @param {number} lineOpacity - The line opacity, between 0 and 1. - * @param {number} lineThickness - The line thickness. - * @param {number} pinSize - If this constraint is a pin, this sets the size of the pin circle. - * @param {number} anchorColor - The color used when rendering this constraints anchors. Set to `null` to not render anchors. - * @param {number} anchorSize - The size of the anchor circle, if this constraint has anchors and is rendering them. - * - * @return {this} This Matter World instance for method chaining. + * Updates the Clock's internal time and all of its Timer Events. + * + * @method Phaser.Time.Clock#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. */ - renderConstraint: function (constraint, graphics, lineColor, lineOpacity, lineThickness, pinSize, anchorColor, anchorSize) + update: function (time, delta) { - var render = constraint.render; + this.now = time; - if (!render.visible || !constraint.pointA || !constraint.pointB) + if (this.paused) { - return this; + return; } - graphics.lineStyle(lineThickness, lineColor, lineOpacity); - - var bodyA = constraint.bodyA; - var bodyB = constraint.bodyB; - var start; - var end; + delta *= this.timeScale; - if (bodyA) - { - start = Vector.add(bodyA.position, constraint.pointA); - } - else + for (var i = 0; i < this._active.length; i++) { - start = constraint.pointA; - } + var event = this._active[i]; - if (render.type === 'pin') - { - graphics.strokeCircle(start.x, start.y, pinSize); - } - else - { - if (bodyB) - { - end = Vector.add(bodyB.position, constraint.pointB); - } - else + if (event.paused) { - end = constraint.pointB; + continue; } - graphics.beginPath(); - graphics.moveTo(start.x, start.y); + // Use delta time to increase elapsed. + // Avoids needing to adjust for pause / resume. + // Automatically smoothed by TimeStep class. + // In testing accurate to +- 1ms! + event.elapsed += delta * event.timeScale; - if (render.type === 'spring') + if (event.elapsed >= event.delay) { - var delta = Vector.sub(end, start); - var normal = Vector.perp(Vector.normalise(delta)); - var coils = Math.ceil(Common.clamp(constraint.length / 5, 12, 20)); - var offset; + var remainder = event.elapsed - event.delay; - for (var j = 1; j < coils; j += 1) - { - offset = (j % 2 === 0) ? 1 : -1; + // Limit it, in case it's checked in the callback + event.elapsed = event.delay; - graphics.lineTo( - start.x + delta.x * (j / coils) + normal.x * offset * 4, - start.y + delta.y * (j / coils) + normal.y * offset * 4 - ); + // Process the event + if (!event.hasDispatched && event.callback) + { + event.hasDispatched = true; + event.callback.apply(event.callbackScope, event.args); } - } - graphics.lineTo(end.x, end.y); - } - - graphics.strokePath(); - - if (render.anchors && anchorSize > 0) - { - graphics.fillStyle(anchorColor); - graphics.fillCircle(start.x, start.y, anchorSize); - graphics.fillCircle(end.x, end.y, anchorSize); - } + if (event.repeatCount > 0) + { + event.repeatCount--; - return this; - }, + // Very short delay + if (remainder >= event.delay) + { + while ((remainder >= event.delay) && (event.repeatCount > 0)) + { + if (event.callback) + { + event.callback.apply(event.callbackScope, event.args); + } - /** - * Resets the internal collision IDs that Matter.JS uses for Body collision groups. - * - * You should call this before destroying your game if you need to restart the game - * again on the same page, without first reloading the page. Or, if you wish to - * consistently destroy a Scene that contains Matter.js and then run it again - * later in the same game. - * - * @method Phaser.Physics.Matter.World#resetCollisionIDs - * @since 3.17.0 - */ - resetCollisionIDs: function () - { - Body._nextCollidingGroupId = 1; - Body._nextNonCollidingGroupId = -1; - Body._nextCategory = 0x0001; + remainder -= event.delay; + event.repeatCount--; + } + } - return this; + event.elapsed = remainder; + event.hasDispatched = false; + } + else if (event.hasDispatched) + { + this._pendingRemoval.push(event); + } + } + } }, /** - * Will remove all Matter physics event listeners and clear the matter physics world, - * engine and any debug graphics, if any. + * The Scene that owns this plugin is shutting down. + * We need to kill and reset all internal properties as well as stop listening to Scene events. * - * @method Phaser.Physics.Matter.World#shutdown + * @method Phaser.Time.Clock#shutdown + * @private * @since 3.0.0 */ shutdown: function () { - MatterEvents.off(this.engine); - - this.removeAllListeners(); + var i; - MatterWorld.clear(this.localWorld, false); + for (i = 0; i < this._pendingInsertion.length; i++) + { + this._pendingInsertion[i].destroy(); + } - Engine.clear(this.engine); + for (i = 0; i < this._active.length; i++) + { + this._active[i].destroy(); + } - if (this.drawDebug) + for (i = 0; i < this._pendingRemoval.length; i++) { - this.debugGraphic.destroy(); + this._pendingRemoval[i].destroy(); } + + this._active.length = 0; + this._pendingRemoval.length = 0; + this._pendingInsertion.length = 0; + + var eventEmitter = this.systems.events; + + eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this); + eventEmitter.off(SceneEvents.UPDATE, this.update, this); + eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * Will remove all Matter physics event listeners and clear the matter physics world, - * engine and any debug graphics, if any. - * - * After destroying the world it cannot be re-used again. + * The Scene that owns this plugin is being destroyed. + * We need to shutdown and then kill off all external references. * - * @method Phaser.Physics.Matter.World#destroy + * @method Phaser.Time.Clock#destroy + * @private * @since 3.0.0 */ destroy: function () { this.shutdown(); + + this.scene.sys.events.off(SceneEvents.START, this.start, this); + + this.scene = null; + this.systems = null; } }); -module.exports = World; +PluginCache.register('Clock', Clock, 'time'); + +module.exports = Clock; /***/ }), -/* 1403 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 20517: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @namespace Phaser.Plugins - */ - -module.exports = { - - BasePlugin: __webpack_require__(540), - DefaultPlugins: __webpack_require__(197), - PluginCache: __webpack_require__(24), - PluginManager: __webpack_require__(414), - ScenePlugin: __webpack_require__(1404) - -}; - - -/***/ }), -/* 1404 */ -/***/ (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 BasePlugin = __webpack_require__(540); -var Class = __webpack_require__(0); -var SceneEvents = __webpack_require__(20); +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var GameObjectFactory = __webpack_require__(61286); +var GetFastValue = __webpack_require__(72632); +var SceneEvents = __webpack_require__(7599); /** * @classdesc - * A Scene Level Plugin is installed into every Scene and belongs to that Scene. - * It can listen for Scene events and respond to them. - * It can map itself to a Scene property, or into the Scene Systems, or both. + * A Timeline is a way to schedule events to happen at specific times in the future. * - * @class ScenePlugin - * @memberof Phaser.Plugins - * @extends Phaser.Plugins.BasePlugin + * You can think of it as an event sequencer for your game, allowing you to schedule the + * running of callbacks, events and other actions at specific times in the future. + * + * A Timeline is a Scene level system, meaning you can have as many Timelines as you like, each + * belonging to a different Scene. You can also have multiple Timelines running at the same time. + * + * If the Scene is paused, the Timeline will also pause. If the Scene is destroyed, the Timeline + * will be automatically destroyed. However, you can control the Timeline directly, pausing, + * resuming and stopping it at any time. + * + * Create an instance of a Timeline via the Game Object Factory: + * + * ```js + * const timeline = this.add.timeline(); + * ``` + * + * The Timeline always starts paused. You must call `play` on it to start it running. + * + * You can also pass in a configuration object on creation, or an array of them: + * + * ```js + * const timeline = this.add.timeline({ + * at: 1000, + * run: () => { + * this.add.sprite(400, 300, 'logo'); + * } + * }); + * + * timeline.play(); + * ``` + * + * In this example we sequence a few different events: + * + * ```js + * const timeline = this.add.timeline([ + * { + * at: 1000, + * run: () => { this.logo = this.add.sprite(400, 300, 'logo'); }, + * sound: 'TitleMusic' + * }, + * { + * at: 2500, + * tween: { + * targets: this.logo, + * y: 600, + * yoyo: true + * }, + * sound: 'Explode' + * }, + * { + * at: 8000, + * event: 'HURRY_PLAYER', + * target: this.background, + * set: { + * tint: 0xff0000 + * } + * } + * ]); + * + * timeline.play(); + * ``` + * + * There are lots of options available to you via the configuration object. See the + * {@link Phaser.Types.Time.TimelineEventConfig} typedef for more details. + * + * @class Timeline + * @memberof Phaser.Time * @constructor - * @since 3.8.0 + * @since 3.60.0 * - * @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin. - * @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Plugin Manager. - * @param {string} pluginKey - The key under which this plugin has been installed into the Scene Systems. + * @param {Phaser.Scene} scene - The Scene which owns this Timeline. + * @param {Phaser.Types.Time.TimelineEventConfig|Phaser.Types.Time.TimelineEventConfig[]} config - The configuration object for this Timeline Event, or an array of them. */ -var ScenePlugin = new Class({ +var Timeline = new Class({ - Extends: BasePlugin, + Extends: EventEmitter, initialize: - function ScenePlugin (scene, pluginManager, pluginKey) + function Timeline (scene, config) { - BasePlugin.call(this, pluginManager); + EventEmitter.call(this); /** - * A reference to the Scene that has installed this plugin. - * Only set if it's a Scene Plugin, otherwise `null`. - * This property is only set when the plugin is instantiated and added to the Scene, not before. - * You can use it during the `boot` method. + * The Scene to which this Timeline belongs. * - * @name Phaser.Plugins.ScenePlugin#scene - * @type {?Phaser.Scene} - * @protected - * @since 3.8.0 + * @name Phaser.Time.Timeline#scene + * @type {Phaser.Scene} + * @since 3.60.0 */ this.scene = scene; /** - * A reference to the Scene Systems of the Scene that has installed this plugin. - * Only set if it's a Scene Plugin, otherwise `null`. - * This property is only set when the plugin is instantiated and added to the Scene, not before. - * You can use it during the `boot` method. + * A reference to the Scene Systems. * - * @name Phaser.Plugins.ScenePlugin#systems - * @type {?Phaser.Scenes.Systems} - * @protected - * @since 3.8.0 + * @name Phaser.Time.Timeline#systems + * @type {Phaser.Scenes.Systems} + * @since 3.60.0 */ this.systems = scene.sys; /** - * The key under which this plugin was installed into the Scene Systems. + * The elapsed time counter. * - * This property is only set when the plugin is instantiated and added to the Scene, not before. - * You can use it during the `boot` method. + * Treat this as read-only. * - * @name Phaser.Plugins.ScenePlugin#pluginKey - * @type {string} - * @readonly - * @since 3.54.0 + * @name Phaser.Time.Timeline#elapsed + * @type {number} + * @since 3.60.0 */ - this.pluginKey = pluginKey; + this.elapsed = 0; - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); + /** + * Whether the Timeline is running (`true`) or active (`false`). + * + * When paused, the Timeline will not run any of its actions. + * + * By default a Timeline is always paused and should be started by + * calling the `Timeline.play` method. + * + * You can use the `Timeline.pause` and `Timeline.resume` methods to control + * this value in a chainable way. + * + * @name Phaser.Time.Timeline#paused + * @type {boolean} + * @default true + * @since 3.60.0 + */ + this.paused = true; + + /** + * Whether the Timeline is complete (`true`) or not (`false`). + * + * A Timeline is considered complete when all of its events have been run. + * + * If you wish to restart a Timeline after it has completed, you can do so + * by calling the `Timeline.restart` method. + * + * You can also use the `Timeline.stop` method to stop a running Timeline, + * at any point, without resetting it. + * + * @name Phaser.Time.Timeline#complete + * @type {boolean} + * @default false + * @since 3.60.0 + */ + this.complete = false; + + /** + * The total number of events that have been run. + * + * This value is reset to zero if the Timeline is restarted. + * + * Treat this as read-only. + * + * @name Phaser.Time.Timeline#totalComplete + * @type {number} + * @since 3.60.0 + */ + this.totalComplete = 0; + + /** + * An array of all the Timeline Events. + * + * @name Phaser.Time.Timeline#events + * @type {Phaser.Types.Time.TimelineEvent[]} + * @since 3.60.0 + */ + this.events = []; + + var eventEmitter = this.systems.events; + + eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this); + eventEmitter.on(SceneEvents.UPDATE, this.update, this); + eventEmitter.once(SceneEvents.SHUTDOWN, this.destroy, this); + + if (config) + { + this.add(config); + } }, /** - * This method is called when the Scene boots. It is only ever called once. + * Updates the elapsed time counter, if this Timeline is not paused. * - * By this point the plugin properties `scene` and `systems` will have already been set. - * - * In here you can listen for {@link Phaser.Scenes.Events Scene events} and set-up whatever you need for this plugin to run. - * Here are the Scene events you can listen to: - * - * - start - * - ready - * - preupdate - * - update - * - postupdate - * - resize - * - pause - * - resume - * - sleep - * - wake - * - transitioninit - * - transitionstart - * - transitioncomplete - * - transitionout - * - shutdown - * - destroy - * - * At the very least you should offer a destroy handler for when the Scene closes down, i.e: - * - * ```javascript - * var eventEmitter = this.systems.events; - * eventEmitter.once('destroy', this.sceneDestroy, this); - * ``` + * @method Phaser.Time.Timeline#preUpdate + * @since 3.60.0 * - * @method Phaser.Plugins.ScenePlugin#boot - * @since 3.8.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. */ - boot: function () + preUpdate: function (time, delta) { + if (this.paused) + { + return; + } + + this.elapsed += delta; }, /** - * Game instance has been destroyed. + * Called automatically by the Scene update step. * - * You must release everything in here, all references, all objects, free it all up. + * Iterates through all of the Timeline Events and checks to see if they should be run. * - * @method Phaser.Plugins.ScenePlugin#destroy - * @since 3.8.0 + * If they should be run, then the `TimelineEvent.action` callback is invoked. + * + * If the `TimelineEvent.once` property is `true` then the event is removed from the Timeline. + * + * If the `TimelineEvent.event` property is set then the Timeline emits that event. + * + * If the `TimelineEvent.run` property is set then the Timeline invokes that method. + * + * If the `TimelineEvent.target` property is set then the Timeline invokes the `run` method on that target. + * + * @method Phaser.Time.Timeline#update + * @since 3.60.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. */ - destroy: function () + update: function () { - this.pluginManager = null; - this.game = null; - this.scene = null; - this.systems = null; - } - -}); - -module.exports = ScenePlugin; + if (this.paused) + { + return; + } + var i; + var events = this.events; + var removeSweep = false; + var sys = this.systems; + var target; -/***/ }), -/* 1405 */ -/***/ (function(module, exports, __webpack_require__) { + for (i = 0; i < events.length; i++) + { + var event = events[i]; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (!event.complete && event.time <= this.elapsed) + { + event.complete = true; -/** - * @namespace Phaser.Renderer - */ + this.totalComplete++; -/** - * @namespace Phaser.Types.Renderer - */ + if (event.once) + { + removeSweep = true; + } -module.exports = { + if (event.set && event.target) + { + // set is an object of key value pairs, apply them to target + for (var key in event.set) + { + event.target[key] = event.set[key]; + } + } - Canvas: __webpack_require__(1406), - Events: __webpack_require__(91), - Snapshot: __webpack_require__(1407), - WebGL: __webpack_require__(1408) + if (event.tween) + { + sys.tweens.add(event.tween); + } -}; + if (event.sound) + { + if (typeof event.sound === 'string') + { + sys.sound.play(event.sound); + } + else + { + sys.sound.play(event.sound.key, event.sound.config); + } + } + target = (event.target) ? event.target : this; -/***/ }), -/* 1406 */ -/***/ (function(module, exports, __webpack_require__) { + if (event.event) + { + this.emit(event.event, target); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (event.run) + { + event.run.call(target); + } -/** - * @namespace Phaser.Renderer.Canvas - */ + if (event.stop) + { + this.stop(); + } + } + } -module.exports = { + if (removeSweep) + { + for (i = 0; i < events.length; i++) + { + if (events[i].complete && events[i].once) + { + events.splice(i, 1); - CanvasRenderer: __webpack_require__(368), - GetBlendModes: __webpack_require__(370), - SetTransform: __webpack_require__(30) + i--; + } + } + } -}; + // It may be greater than the length if events have been removed + if (this.totalComplete >= events.length) + { + this.complete = true; + } + }, + /** + * Starts this Timeline running. + * + * If the Timeline is already running and the `fromStart` parameter is `true`, + * then calling this method will reset the Timeline events as incomplete. + * + * If you wish to resume a paused Timeline, then use the `Timeline.resume` method instead. + * + * @method Phaser.Time.Timeline#play + * @since 3.60.0 + * + * @param {boolean} [fromStart=true] - Reset this Timeline back to the start before playing. + * + * @return {this} This Timeline instance. + */ + play: function (fromStart) + { + if (fromStart === undefined) { fromStart = true; } -/***/ }), -/* 1407 */ -/***/ (function(module, exports, __webpack_require__) { + this.paused = false; + this.complete = false; + this.totalComplete = 0; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (fromStart) + { + this.reset(); + } -/** - * @namespace Phaser.Renderer.Snapshot - */ + return this; + }, -module.exports = { + /** + * Pauses this Timeline. + * + * To resume it again, call the `Timeline.resume` method or set the `Timeline.paused` property to `false`. + * + * If the Timeline is paused while processing the current game step, then it + * will carry on with all events that are due to run during that step and pause + * from the next game step. + * + * @method Phaser.Time.Timeline#pause + * @since 3.60.0 + * + * @return {this} This Timeline instance. + */ + pause: function () + { + this.paused = true; - Canvas: __webpack_require__(369), - WebGL: __webpack_require__(383) + return this; + }, -}; + /** + * Resumes this Timeline from a paused state. + * + * The Timeline will carry on from where it left off. + * + * If you need to reset the Timeline to the start, then call the `Timeline.reset` method. + * + * @method Phaser.Time.Timeline#resume + * @since 3.60.0 + * + * @return {this} This Timeline instance. + */ + resume: function () + { + this.paused = false; + return this; + }, -/***/ }), -/* 1408 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Stops this Timeline. + * + * This will set the `paused` and `complete` properties to `true`. + * + * If you wish to reset the Timeline to the start, then call the `Timeline.reset` method. + * + * @method Phaser.Time.Timeline#stop + * @since 3.60.0 + * + * @return {this} This Timeline instance. + */ + stop: function () + { + this.paused = true; + this.complete = true; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -var WEBGL_CONST = __webpack_require__(107); -var Extend = __webpack_require__(17); + /** + * Resets this Timeline back to the start. + * + * This will set the elapsed time to zero and set all events to be incomplete. + * + * If the Timeline had any events that were set to `once` that have already + * been removed, they will **not** be present again after calling this method. + * + * If the Timeline isn't currently running (i.e. it's paused or complete) then + * calling this method resets those states, the same as calling `Timeline.play(true)`. + * + * @method Phaser.Time.Timeline#reset + * @since 3.60.0 + * + * @return {this} This Timeline instance. + */ + reset: function () + { + this.elapsed = 0; -/** - * @namespace Phaser.Renderer.WebGL - */ + for (var i = 0; i < this.events.length; i++) + { + this.events[i].complete = false; + } -var WebGL = { + return this.play(false); + }, - PipelineManager: __webpack_require__(372), - Pipelines: __webpack_require__(1409), - RenderTarget: __webpack_require__(141), - Utils: __webpack_require__(12), - WebGLPipeline: __webpack_require__(58), - WebGLRenderer: __webpack_require__(371), - WebGLShader: __webpack_require__(375) + /** + * Adds one or more events to this Timeline. + * + * You can pass in a single configuration object, or an array of them: + * + * ```js + * const timeline = this.add.timeline({ + * at: 1000, + * run: () => { + * this.add.sprite(400, 300, 'logo'); + * } + * }); + * ``` + * + * @method Phaser.Time.Timeline#add + * @since 3.60.0 + * + * @param {Phaser.Types.Time.TimelineEventConfig|Phaser.Types.Time.TimelineEventConfig[]} config - The configuration object for this Timeline Event, or an array of them. + * + * @return {this} This Timeline instance. + */ + add: function (config) + { + if (!Array.isArray(config)) + { + config = [ config ]; + } -}; + var events = this.events; + var prevTime = 0; -// Merge in the consts + if (events.length > 0) + { + prevTime = events[events.length - 1].time; + } -WebGL = Extend(false, WebGL, WEBGL_CONST); + for (var i = 0; i < config.length; i++) + { + var entry = config[i]; -// Export it + // Start at the exact time given, based on elapsed time (i.e. x ms from the start of the Timeline) + var startTime = GetFastValue(entry, 'at', 0); -module.exports = WebGL; + // Start in x ms from whatever the current elapsed time is (i.e. x ms from now) + var offsetTime = GetFastValue(entry, 'in', null); + if (offsetTime !== null) + { + startTime = this.elapsed + offsetTime; + } -/***/ }), -/* 1409 */ -/***/ (function(module, exports, __webpack_require__) { + // Start in x ms from whatever the previous event's start time was (i.e. x ms after the previous event) + var fromTime = GetFastValue(entry, 'from', null); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (fromTime !== null) + { + startTime = prevTime + fromTime; + } -var CONST = __webpack_require__(92); -var Extend = __webpack_require__(17); + events.push({ + complete: false, + time: startTime, + run: GetFastValue(entry, 'run', null), + event: GetFastValue(entry, 'event', null), + target: GetFastValue(entry, 'target', null), + set: GetFastValue(entry, 'set', null), + tween: GetFastValue(entry, 'tween', null), + sound: GetFastValue(entry, 'sound', null), + once: GetFastValue(entry, 'once', false), + stop: GetFastValue(entry, 'stop', false) + }); -/** - * @namespace Phaser.Renderer.WebGL.Pipelines - */ + prevTime = startTime; + } -var Pipelines = { + this.complete = false; - BitmapMaskPipeline: __webpack_require__(373), - Events: __webpack_require__(374), - GraphicsPipeline: __webpack_require__(376), - LightPipeline: __webpack_require__(377), - MultiPipeline: __webpack_require__(108), - PointLightPipeline: __webpack_require__(378), - PostFXPipeline: __webpack_require__(1410), - RopePipeline: __webpack_require__(379), - SinglePipeline: __webpack_require__(380), - UtilityPipeline: __webpack_require__(381) + return this; + }, -}; + /** + * Removes all events from this Timeline, resets the elapsed time to zero + * and pauses the Timeline. + * + * @method Phaser.Time.Timeline#clear + * @since 3.60.0 + * + * @return {this} This Timeline instance. + */ + clear: function () + { + this.events = []; + this.elapsed = 0; + this.paused = true; -// Merge in the consts + return this; + }, -Pipelines = Extend(false, Pipelines, CONST); + /** + * Returns `true` if this Timeline is currently playing. + * + * A Timeline is playing if it is not paused or not complete. + * + * @method Phaser.Time.Timeline#isPlaying + * @since 3.60.0 + * + * @return {boolean} `true` if this Timeline is playing, otherwise `false`. + */ + isPlaying: function () + { + return (!this.paused && !this.complete); + }, -// Export it + /** + * Returns a number between 0 and 1 representing the progress of this Timeline. + * + * A value of 0 means the Timeline has just started, 0.5 means it's half way through, + * and 1 means it's complete. + * + * If the Timeline has no events, or all events have been removed, this will return 1. + * + * If the Timeline is paused, this will return the progress value at the time it was paused. + * + * Note that the value returned is based on the number of events that have been completed, + * not the 'duration' of the events (as this is unknown to the Timeline). + * + * @method Phaser.Time.Timeline#getProgress + * @since 3.60.0 + * + * @return {number} A number between 0 and 1 representing the progress of this Timeline. + */ + getProgress: function () + { + var total = Math.min(this.totalComplete, this.events.length); -module.exports = Pipelines; + return total / this.events.length; + }, + /** + * Destroys this Timeline. + * + * This will remove all events from the Timeline and stop it from processing. + * + * This method is called automatically when the Scene shuts down, but you may + * also call it directly should you need to destroy the Timeline earlier. + * + * @method Phaser.Time.Timeline#destroy + * @since 3.60.0 + */ + destroy: function () + { + var eventEmitter = this.systems.events; -/***/ }), -/* 1410 */ -/***/ (function(module, exports, __webpack_require__) { + eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this); + eventEmitter.off(SceneEvents.UPDATE, this.update, this); + eventEmitter.off(SceneEvents.SHUTDOWN, this.destroy, this); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.scene = null; + this.systems = null; + this.events = []; + } -var Class = __webpack_require__(0); -var ColorMatrix = __webpack_require__(198); -var GetFastValue = __webpack_require__(2); -var ShaderSourceFS = __webpack_require__(1411); -var ShaderSourceVS = __webpack_require__(382); -var WebGLPipeline = __webpack_require__(58); +}); /** - * @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. + * A Timeline is a way to schedule events to happen at specific times in the future. * - * 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. + * You can think of it as an event sequencer for your game, allowing you to schedule the + * running of callbacks, events and other actions at specific times in the future. * - * Please see the Phaser 3 examples for further details on this extensive subject. + * A Timeline is a Scene level system, meaning you can have as many Timelines as you like, each + * belonging to a different Scene. You can also have multiple Timelines running at the same time. * - * 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`. + * If the Scene is paused, the Timeline will also pause. If the Scene is destroyed, the Timeline + * will be automatically destroyed. However, you can control the Timeline directly, pausing, + * resuming and stopping it at any time. * - * The default shader attributes for this pipeline are: + * Create an instance of a Timeline via the Game Object Factory: * - * `inPosition` (vec2, offset 0) - * `inTexCoord` (vec2, offset 8) + * ```js + * const timeline = this.add.timeline(); + * ``` * - * The vertices array layout is: + * The Timeline always starts paused. You must call `play` on it to start it running. * - * -1, 1 B----C 1, 1 - * 0, 1 | /| 1, 1 - * | / | - * | / | - * |/ | - * -1, -1 A----D 1, -1 - * 0, 0 1, 0 + * You can also pass in a configuration object on creation, or an array of them: * - * 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) + * ```js + * const timeline = this.add.timeline({ + * at: 1000, + * run: () => { + * this.add.sprite(400, 300, 'logo'); + * } + * }); * - * First tri: A, B, C - * Second tri: A, C, D + * timeline.play(); + * ``` * - * Array index: + * In this example we sequence a few different events: * - * 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 + * ```js + * const timeline = this.add.timeline([ + * { + * at: 1000, + * run: () => { this.logo = this.add.sprite(400, 300, 'logo'); }, + * sound: 'TitleMusic' + * }, + * { + * at: 2500, + * tween: { + * targets: this.logo, + * y: 600, + * yoyo: true + * }, + * sound: 'Explode' + * }, + * { + * at: 8000, + * event: 'HURRY_PLAYER', + * target: this.background, + * set: { + * tint: 0xff0000 + * } + * } + * ]); * - * 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 + * timeline.play(); + * ``` * - * 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 + * There are lots of options available to you via the configuration object. See the + * {@link Phaser.Types.Time.TimelineEventConfig} typedef for more details. * - * 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 + * @method Phaser.GameObjects.GameObjectFactory#timeline + * @since 3.60.0 * - * 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 + * @param {Phaser.Types.Time.TimelineEventConfig|Phaser.Types.Time.TimelineEventConfig[]} config - The configuration object for this Timeline Event, or an array of them. * - * 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 + * @return {Phaser.Time.Timeline} The Timeline that was created. + */ +GameObjectFactory.register('timeline', function (config) +{ + return new Timeline(this.scene, config); +}); + +module.exports = Timeline; + + +/***/ }), + +/***/ 57911: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Class = __webpack_require__(56694); +var GetFastValue = __webpack_require__(72632); + +/** + * @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. * - * @class PostFXPipeline - * @extends Phaser.Renderer.WebGL.WebGLPipeline - * @memberof Phaser.Renderer.WebGL.Pipelines + * 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.50.0 + * @since 3.0.0 * - * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline. + * @param {Phaser.Types.Time.TimerEventConfig} config - The configuration for the Timer Event, including its delay and callback. */ -var PostFXPipeline = new Class({ - - Extends: WebGLPipeline, +var TimerEvent = new Class({ initialize: - function PostFXPipeline (config) + function TimerEvent (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. + * The delay in ms at which this TimerEvent fires. * - * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#gameObject - * @type {Phaser.GameObjects.GameObject} - * @since 3.50.0 + * @name Phaser.Time.TimerEvent#delay + * @type {number} + * @default 0 + * @readonly + * @since 3.0.0 */ - this.gameObject; + this.delay = 0; /** - * A Color Matrix instance belonging to this pipeline. - * - * Used during calls to the `drawFrame` method. + * The total number of times this TimerEvent will repeat before finishing. * - * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#colorMatrix - * @type {Phaser.Display.ColorMatrix} - * @since 3.50.0 + * @name Phaser.Time.TimerEvent#repeat + * @type {number} + * @default 0 + * @readonly + * @since 3.0.0 */ - this.colorMatrix = new ColorMatrix(); + this.repeat = 0; /** - * A reference to the Full Frame 1 Render Target that belongs to the - * Utility Pipeline. This property is set during the `boot` method. + * If repeating this contains the current repeat count. * - * This Render Target is the full size of the renderer. + * @name Phaser.Time.TimerEvent#repeatCount + * @type {number} + * @default 0 + * @since 3.0.0 + */ + this.repeatCount = 0; + + /** + * True if this TimerEvent loops, otherwise false. * - * 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.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.Renderer.WebGL.Pipelines.PostFXPipeline#fullFrame1 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 + * @name Phaser.Time.TimerEvent#callback + * @type {function} + * @since 3.0.0 */ - this.fullFrame1; + this.callback; /** - * A reference to the Full Frame 2 Render Target that belongs to the - * Utility Pipeline. This property is set during the `boot` method. + * The scope in which the callback will be called. * - * This Render Target is the full size of the renderer. + * @name Phaser.Time.TimerEvent#callbackScope + * @type {object} + * @since 3.0.0 + */ + this.callbackScope; + + /** + * Additional arguments to be passed to the callback. * - * 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.Time.TimerEvent#args + * @type {array} + * @since 3.0.0 + */ + this.args; + + /** + * Scale the time causing this TimerEvent to update. * - * @name Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#fullFrame2 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 + * @name Phaser.Time.TimerEvent#timeScale + * @type {number} + * @default 1 + * @since 3.0.0 */ - this.fullFrame2; + this.timeScale = 1; /** - * A reference to the Half Frame 1 Render Target that belongs to the - * Utility Pipeline. This property is set during the `boot` method. + * Start this many MS into the elapsed (useful if you want a long duration with repeat, but for the first loop to fire quickly) * - * This Render Target is half the size of the renderer. + * @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. * - * 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. + * 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.Renderer.WebGL.Pipelines.PostFXPipeline#halfFrame1 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 + * @name Phaser.Time.TimerEvent#elapsed + * @type {number} + * @default 0 + * @since 3.0.0 */ - this.halfFrame1; + this.elapsed = 0; /** - * A reference to the Half Frame 2 Render Target that belongs to the - * Utility Pipeline. This property is set during the `boot` method. + * Whether or not this timer is paused. * - * This Render Target is half the size of the renderer. + * @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. * - * 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. + * 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.Renderer.WebGL.Pipelines.PostFXPipeline#halfFrame2 - * @type {Phaser.Renderer.WebGL.RenderTarget} - * @default null - * @since 3.50.0 + * @name Phaser.Time.TimerEvent#hasDispatched + * @type {boolean} + * @default false + * @since 3.0.0 */ - this.halfFrame2; - - if (this.renderer.isBooted) - { - this.manager = this.renderer.pipelines; + this.hasDispatched = false; - this.boot(); - } + this.reset(config); }, - boot: function () + /** + * 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) { - WebGLPipeline.prototype.boot.call(this); + this.delay = GetFastValue(config, 'delay', 0); - var utility = this.manager.UTILITY_PIPELINE; + // Can also be set to -1 for an infinite loop (same as setting loop: true) + this.repeat = GetFastValue(config, 'repeat', 0); - this.fullFrame1 = utility.fullFrame1; - this.fullFrame2 = utility.fullFrame2; - this.halfFrame1 = utility.halfFrame1; - this.halfFrame2 = utility.halfFrame2; + this.loop = GetFastValue(config, 'loop', false); - this.set1i('uMainSampler', 0); - }, + this.callback = GetFastValue(config, 'callback', undefined); - onDraw: function (renderTarget) - { - this.bindAndDraw(renderTarget); + this.callbackScope = GetFastValue(config, 'callbackScope', this); + + 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; + + if (this.delay === 0 && (this.repeat > 0 || this.loop)) + { + throw new Error('TimerEvent infinite loop created via zero delay'); + } + + return this; }, /** - * Copy the `source` Render Target to the `target` Render Target. + * Gets the progress of the current iteration, not factoring in repeats. * - * You can optionally set the brightness factor of the copy. + * @method Phaser.Time.TimerEvent#getProgress + * @since 3.0.0 * - * 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. + * @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.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrame - * @since 3.50.0 + * @method Phaser.Time.TimerEvent#getOverallProgress + * @since 3.0.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? + * @return {number} The overall progress of the Timer Event, between 0 and 1. */ - copyFrame: function (source, target, brightness, clear, clearAlpha) + getOverallProgress: function () { - this.manager.copyFrame(source, target, brightness, clear, clearAlpha); + 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(); + } }, /** - * 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. + * Returns the number of times this Timer Event will repeat before finishing. * - * 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. + * 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.Renderer.WebGL.Pipelines.PostFXPipeline#copyToGame - * @since 3.50.0 + * @method Phaser.Time.TimerEvent#getRepeatCount + * @since 3.0.0 * - * @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from. + * @return {number} How many times the Timer Event will repeat. */ - copyToGame: function (source) + getRepeatCount: function () { - this.manager.copyToGame(source); + return this.repeatCount; }, /** - * 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. + * Returns the local elapsed time for the current iteration of the Timer Event. * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#drawFrame - * @since 3.50.0 + * @method Phaser.Time.TimerEvent#getElapsed + * @since 3.0.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? + * @return {number} The local elapsed time in milliseconds. */ - drawFrame: function (source, target, clearAlpha) + getElapsed: function () { - this.manager.drawFrame(source, target, clearAlpha, this.colorMatrix); + return this.elapsed; }, /** - * Draws the `source1` and `source2` Render Targets to the `target` Render Target - * using a linear blend effect, which is controlled by the `strength` parameter. + * Returns the local elapsed time for the current iteration of the Timer Event in seconds. * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFrames - * @since 3.50.0 + * @method Phaser.Time.TimerEvent#getElapsedSeconds + * @since 3.0.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? + * @return {number} The local elapsed time in seconds. */ - blendFrames: function (source1, source2, target, strength, clearAlpha) + getElapsedSeconds: function () { - this.manager.blendFrames(source1, source2, target, strength, clearAlpha); + return this.elapsed * 0.001; }, /** - * Draws the `source1` and `source2` Render Targets to the `target` Render Target - * using an additive blend effect, which is controlled by the `strength` parameter. + * Returns the time interval until the next iteration of the Timer Event. * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFramesAdditive + * @method Phaser.Time.TimerEvent#getRemaining * @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? + * @return {number} The time interval in milliseconds. */ - blendFramesAdditive: function (source1, source2, target, strength, clearAlpha) + getRemaining: function () { - this.manager.blendFramesAdditive(source1, source2, target, strength, clearAlpha); + return this.delay - this.elapsed; }, /** - * Clears the given Render Target. + * Returns the time interval until the next iteration of the Timer Event in seconds. * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#clearFrame + * @method Phaser.Time.TimerEvent#getRemainingSeconds * @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? + * @return {number} The time interval in seconds. */ - clearFrame: function (target, clearAlpha) + getRemainingSeconds: function () { - this.manager.clearFrame(target, clearAlpha); + return this.getRemaining() * 0.001; }, /** - * 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. + * Returns the time interval until the last iteration of the Timer Event. * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blitFrame + * @method Phaser.Time.TimerEvent#getOverallRemaining * @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? + * @return {number} The time interval in milliseconds. */ - blitFrame: function (source, target, brightness, clear, clearAlpha, eraseMode) + getOverallRemaining: function () { - this.manager.blitFrame(source, target, brightness, clear, clearAlpha, eraseMode); + return this.delay * (1 + this.repeatCount) - this.elapsed; }, /** - * 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. + * Returns the time interval until the last iteration of the Timer Event in seconds. * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrameRect + * @method Phaser.Time.TimerEvent#getOverallRemainingSeconds * @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? + * @return {number} The time interval in seconds. */ - copyFrameRect: function (source, target, x, y, width, height, clear, clearAlpha) + getOverallRemainingSeconds: function () { - this.manager.copyFrameRect(source, target, x, y, width, height, clear, clearAlpha); + return this.getOverallRemaining() * 0.001; }, /** - * 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. + * Forces the Timer Event to immediately expire, thus scheduling its removal in the next frame. * - * @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#bindAndDraw - * @since 3.50.0 + * @method Phaser.Time.TimerEvent#remove + * @since 3.0.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. + * @param {boolean} [dispatchCallback=false] - If `true`, the function of the Timer Event will be called before its removal. */ - bindAndDraw: function (source, target, clear, clearAlpha, currentShader) + remove: function (dispatchCallback) { - 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 (dispatchCallback === undefined) { dispatchCallback = false; } - if (!renderer.currentFramebuffer) - { - gl.viewport(0, 0, renderer.width, renderer.height); - } - } + this.elapsed = this.delay; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, source.texture); + this.hasDispatched = !dispatchCallback; - gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW); - gl.drawArrays(gl.TRIANGLES, 0, 6); + this.repeatCount = 0; + }, - if (!target) - { - renderer.resetTextures(); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - } + /** + * 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 = PostFXPipeline; +module.exports = TimerEvent; /***/ }), -/* 1411 */ -/***/ (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'); - -/***/ }), -/* 1412 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 97121: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Extend = __webpack_require__(17); -var CONST = __webpack_require__(201); - /** - * @namespace Phaser.Scale - * - * @borrows Phaser.Scale.Center.NO_CENTER as NO_CENTER - * @borrows Phaser.Scale.Center.CENTER_BOTH as CENTER_BOTH - * @borrows Phaser.Scale.Center.CENTER_HORIZONTALLY as CENTER_HORIZONTALLY - * @borrows Phaser.Scale.Center.CENTER_VERTICALLY as CENTER_VERTICALLY - * - * @borrows Phaser.Scale.Orientation.LANDSCAPE as LANDSCAPE - * @borrows Phaser.Scale.Orientation.PORTRAIT as PORTRAIT - * - * @borrows Phaser.Scale.ScaleModes.NONE as NONE - * @borrows Phaser.Scale.ScaleModes.WIDTH_CONTROLS_HEIGHT as WIDTH_CONTROLS_HEIGHT - * @borrows Phaser.Scale.ScaleModes.HEIGHT_CONTROLS_WIDTH as HEIGHT_CONTROLS_WIDTH - * @borrows Phaser.Scale.ScaleModes.FIT as FIT - * @borrows Phaser.Scale.ScaleModes.ENVELOP as ENVELOP - * @borrows Phaser.Scale.ScaleModes.RESIZE as RESIZE - * - * @borrows Phaser.Scale.Zoom.NO_ZOOM as NO_ZOOM - * @borrows Phaser.Scale.Zoom.ZOOM_2X as ZOOM_2X - * @borrows Phaser.Scale.Zoom.ZOOM_4X as ZOOM_4X - * @borrows Phaser.Scale.Zoom.MAX_ZOOM as MAX_ZOOM + * @namespace Phaser.Time */ -var Scale = { +module.exports = { - Center: __webpack_require__(403), - Events: __webpack_require__(104), - Orientation: __webpack_require__(404), - ScaleManager: __webpack_require__(415), - ScaleModes: __webpack_require__(405), - Zoom: __webpack_require__(406) + Clock: __webpack_require__(73779), + Timeline: __webpack_require__(20517), + TimerEvent: __webpack_require__(57911) }; -Scale = Extend(false, Scale, CONST.CENTER); -Scale = Extend(false, Scale, CONST.ORIENTATION); -Scale = Extend(false, Scale, CONST.SCALE_MODE); -Scale = Extend(false, Scale, CONST.ZOOM); - -module.exports = Scale; - /***/ }), -/* 1413 */ -/***/ (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__(144); -var Extend = __webpack_require__(17); - -/** - * @namespace Phaser.Scenes - */ - -var Scene = { - - Events: __webpack_require__(20), - GetPhysicsPlugins: __webpack_require__(419), - GetScenePlugins: __webpack_require__(420), - SceneManager: __webpack_require__(417), - ScenePlugin: __webpack_require__(1414), - Settings: __webpack_require__(421), - Systems: __webpack_require__(204) - -}; -// Merge in the consts -Scene = Extend(false, Scene, CONST); - -module.exports = Scene; - - -/***/ }), -/* 1414 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ 64532: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clamp = __webpack_require__(18); -var Class = __webpack_require__(0); -var Events = __webpack_require__(20); -var GetFastValue = __webpack_require__(2); -var PluginCache = __webpack_require__(24); +var ArrayRemove = __webpack_require__(66458); +var Class = __webpack_require__(56694); +var Flatten = __webpack_require__(5454); +var NumberTweenBuilder = __webpack_require__(68710); +var PluginCache = __webpack_require__(91963); +var SceneEvents = __webpack_require__(7599); +var StaggerBuilder = __webpack_require__(91944); +var Tween = __webpack_require__(39366); +var TweenBuilder = __webpack_require__(68061); +var TweenChain = __webpack_require__(45641); +var TweenChainBuilder = __webpack_require__(56034); /** * @classdesc - * The Scene Plugin is the main interface to the Scene Manager and allows you to control - * any Scene running in your game. You should always use this plugin. By default, it is - * mapped to the Scene property `this.scene`. Meaning, from within a Scene, you can call - * methods such as `this.scene.start()`. + * The Tween Manager is a default Scene Plugin which controls and updates Tweens. * - * Note that nearly all methods in this class are run on a queue-basis and not - * immediately. For example, calling `this.scene.launch('SceneB')` will try to - * launch SceneB when the Scene Manager next updates, which is at the start of the game - * step. All operations are queued and run in the order in which they are invoked here. + * A tween is a way to alter one or more properties of a target object over a defined period of time. * - * @class ScenePlugin - * @memberof Phaser.Scenes + * Tweens are created by calling the `add` method and passing in the configuration object. + * + * ```js + * const logo = this.add.image(100, 100, 'logo'); + * + * this.tweens.add({ + * targets: logo, + * x: 600, + * ease: 'Power1', + * duration: 2000 + * }); + * ``` + * + * See the `TweenBuilderConfig` for all of the options you have available. + * + * Playback will start immediately unless the tween has been configured to be paused. + * + * Please note that a Tween will not manipulate any target property that begins with an underscore. + * + * Tweens are designed to be 'fire-and-forget'. They automatically destroy themselves once playback + * is complete, to free-up memory and resources. If you wish to keep a tween after playback, i.e. to + * play it again at a later time, then you should set the `persist` property to `true` in the config. + * However, doing so means it's entirely up to _you_ to destroy the tween when you're finished with it, + * otherwise it will linger in memory forever. + * + * If you wish to chain Tweens together for sequential playback, see the `TweenManager.chain` method. + * + * @class TweenManager + * @memberof Phaser.Tweens * @constructor * @since 3.0.0 * - * @param {Phaser.Scene} scene - The Scene that this ScenePlugin belongs to. + * @param {Phaser.Scene} scene - The Scene which owns this Tween Manager. */ -var ScenePlugin = new Class({ +var TweenManager = new Class({ initialize: - function ScenePlugin (scene) + function TweenManager (scene) { /** - * The Scene that this ScenePlugin belongs to. + * The Scene which owns this Tween Manager. * - * @name Phaser.Scenes.ScenePlugin#scene + * @name Phaser.Tweens.TweenManager#scene * @type {Phaser.Scene} * @since 3.0.0 */ this.scene = scene; /** - * The Scene Systems instance of the Scene that this ScenePlugin belongs to. + * The Scene Systems Event Emitter. * - * @name Phaser.Scenes.ScenePlugin#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 + * @name Phaser.Tweens.TweenManager#events + * @type {Phaser.Events.EventEmitter} + * @since 3.60.0 */ - this.systems = scene.sys; + this.events = scene.sys.events; /** - * The settings of the Scene this ScenePlugin belongs to. + * The time scale of the Tween Manager. * - * @name Phaser.Scenes.ScenePlugin#settings - * @type {Phaser.Types.Scenes.SettingsObject} + * This value scales the time delta between two frames, thus influencing the speed of time for all Tweens owned by this Tween Manager. + * + * @name Phaser.Tweens.TweenManager#timeScale + * @type {number} + * @default 1 * @since 3.0.0 */ - this.settings = scene.sys.settings; + this.timeScale = 1; /** - * The key of the Scene this ScenePlugin belongs to. + * This toggles the updating state of this Tween Manager. * - * @name Phaser.Scenes.ScenePlugin#key - * @type {string} - * @since 3.0.0 + * Setting `paused` to `true` (or calling the `pauseAll` method) will + * stop this Tween Manager from updating any of its tweens, including + * newly created ones. Set back to `false` to resume playback. + * + * @name Phaser.Tweens.TweenManager#paused + * @type {boolean} + * @default false + * @since 3.60.0 */ - this.key = scene.sys.settings.key; + this.paused = false; /** - * The Game's SceneManager. + * Is this Tween Manager currently processing the tweens as part of + * its 'update' loop? This is set to 'true' at the start of 'update' + * and reset to 'false' at the end of the function. Allows you to trap + * Tween Manager status during tween callbacks. * - * @name Phaser.Scenes.ScenePlugin#manager - * @type {Phaser.Scenes.SceneManager} - * @since 3.0.0 + * @name Phaser.Tweens.TweenManager#processing + * @type {boolean} + * @default false + * @since 3.60.0 */ - this.manager = scene.sys.game.scene; + this.processing = false; /** - * If this Scene is currently transitioning to another, this holds - * the current percentage of the transition progress, between 0 and 1. + * An array of Tweens which are actively being processed by the Tween Manager. * - * @name Phaser.Scenes.ScenePlugin#transitionProgress - * @type {number} - * @since 3.5.0 + * @name Phaser.Tweens.TweenManager#tweens + * @type {Phaser.Tweens.Tween[]} + * @since 3.60.0 */ - this.transitionProgress = 0; + this.tweens = []; /** - * Transition elapsed timer. + * The time the Tween Manager was updated. * - * @name Phaser.Scenes.ScenePlugin#_elapsed + * @name Phaser.Tweens.TweenManager#time * @type {number} - * @private - * @since 3.5.0 + * @since 3.60.0 */ - this._elapsed = 0; + this.time = 0; /** - * Transition elapsed timer. + * The time the Tween Manager was started. * - * @name Phaser.Scenes.ScenePlugin#_target - * @type {?Phaser.Scenes.Scene} - * @private - * @since 3.5.0 + * @name Phaser.Tweens.TweenManager#startTime + * @type {number} + * @since 3.60.0 */ - this._target = null; + this.startTime = 0; /** - * Transition duration. + * The time the Tween Manager should next update. * - * @name Phaser.Scenes.ScenePlugin#_duration + * @name Phaser.Tweens.TweenManager#nextTime * @type {number} - * @private - * @since 3.5.0 + * @since 3.60.0 */ - this._duration = 0; + this.nextTime = 0; /** - * Transition callback. + * The time the Tween Manager previously updated. * - * @name Phaser.Scenes.ScenePlugin#_onUpdate - * @type {function} - * @private - * @since 3.5.0 + * @name Phaser.Tweens.TweenManager#prevTime + * @type {number} + * @since 3.60.0 */ - this._onUpdate; + this.prevTime = 0; /** - * Transition callback scope. + * The maximum amount of time, in milliseconds, the browser can + * lag for, before lag smoothing is applied. * - * @name Phaser.Scenes.ScenePlugin#_onUpdateScope - * @type {object} - * @private - * @since 3.5.0 + * See the `TweenManager.setLagSmooth` method for further details. + * + * @name Phaser.Tweens.TweenManager#maxLag + * @type {number} + * @default 500 + * @since 3.60.0 */ - this._onUpdateScope; + this.maxLag = 500; /** - * Will this Scene sleep (true) after the transition, or stop (false) + * The amount of time, in milliseconds, that is used to set the + * delta when lag smoothing is applied. * - * @name Phaser.Scenes.ScenePlugin#_willSleep - * @type {boolean} - * @private - * @since 3.5.0 + * See the `TweenManager.setLagSmooth` method for further details. + * + * @name Phaser.Tweens.TweenManager#lagSkip + * @type {number} + * @default 33 + * @since 3.60.0 */ - this._willSleep = false; + this.lagSkip = 33; /** - * Will this Scene be removed from the Scene Manager after the transition completes? + * An internal value that holds the fps rate. * - * @name Phaser.Scenes.ScenePlugin#_willRemove - * @type {boolean} - * @private - * @since 3.5.0 + * @name Phaser.Tweens.TweenManager#gap + * @type {number} + * @since 3.60.0 */ - this._willRemove = false; + this.gap = 1000 / 240; - scene.sys.events.once(Events.BOOT, this.boot, this); - scene.sys.events.on(Events.START, this.pluginStart, this); + this.events.once(SceneEvents.BOOT, this.boot, this); + this.events.on(SceneEvents.START, this.start, this); }, /** * This method is called automatically, only once, when the Scene is first created. * Do not invoke it directly. * - * @method Phaser.Scenes.ScenePlugin#boot + * @method Phaser.Tweens.TweenManager#boot * @private - * @since 3.0.0 + * @since 3.5.1 */ boot: function () { - this.systems.events.once(Events.DESTROY, this.destroy, this); + this.events.once(SceneEvents.DESTROY, this.destroy, this); }, /** @@ -206827,790 +230001,896 @@ var ScenePlugin = new Class({ * It is responsible for creating local systems, properties and listening for Scene events. * Do not invoke it directly. * - * @method Phaser.Scenes.ScenePlugin#pluginStart + * @method Phaser.Tweens.TweenManager#start * @private * @since 3.5.0 */ - pluginStart: function () + start: function () { - this._target = null; + this.timeScale = 1; + this.paused = false; - this.systems.events.once(Events.SHUTDOWN, this.shutdown, this); + this.startTime = Date.now(); + this.prevTime = this.startTime; + this.nextTime = this.gap; + + this.events.on(SceneEvents.UPDATE, this.update, this); + this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** - * Shutdown this Scene and run the given one. + * Create a Tween and return it, but does not add it to this Tween Manager. * - * This will happen at the next Scene Manager update, not immediately. + * Please note that a Tween will not manipulate any target property that begins with an underscore. * - * @method Phaser.Scenes.ScenePlugin#start + * In order to play this tween, you'll need to add it to a Tween Manager via + * the `TweenManager.existing` method. + * + * You can optionally pass an **array** of Tween Configuration objects to this method and it will create + * one Tween per entry in the array. If an array is given, an array of tweens is returned. + * + * @method Phaser.Tweens.TweenManager#create * @since 3.0.0 * - * @param {(string|Phaser.Scene)} [key] - The Scene to start. - * @param {object} [data] - The Scene data. + * @param {Phaser.Types.Tweens.TweenBuilderConfig|Phaser.Types.Tweens.TweenBuilderConfig[]|object|object[]} config - A Tween Configuration object. Or an array of Tween Configuration objects. * - * @return {this} This Scene Plugin instance. + * @return {Phaser.Tweens.Tween|Phaser.Tweens.Tween[]} The created Tween, or an array of Tweens if an array of tween configs was provided. */ - start: function (key, data) + create: function (config) { - if (key === undefined) { key = this.key; } - - this.manager.queueOp('stop', this.key); - this.manager.queueOp('start', key, data); + if (!Array.isArray(config)) + { + config = [ config ]; + } - return this; - }, + var result = []; - /** - * Restarts this Scene. - * - * This will happen at the next Scene Manager update, not immediately. - * - * @method Phaser.Scenes.ScenePlugin#restart - * @since 3.4.0 - * - * @param {object} [data] - The Scene data. - * - * @return {this} This Scene Plugin instance. - */ - restart: function (data) - { - var key = this.key; + for (var i = 0; i < config.length; i++) + { + var tween = config[i]; - this.manager.queueOp('stop', key); - this.manager.queueOp('start', key, data); + if (tween instanceof Tween || tween instanceof TweenChain) + { + // Allow them to send an array of mixed instances and configs + result.push(tween); + } + else if (Array.isArray(tween.tweens)) + { + result.push(TweenChainBuilder(this, tween)); + } + else + { + result.push(TweenBuilder(this, tween)); + } + } - return this; + return (result.length === 1) ? result[0] : result; }, /** - * This will start a transition from the current Scene to the target Scene given. + * Create a Tween and add it to this Tween Manager by passing a Tween Configuration object. * - * The transition will last for the duration specified in milliseconds. + * Example, run from within a Scene: * - * You can have the target Scene moved above or below this one in the display list. + * ```js + * const logo = this.add.image(100, 100, 'logo'); * - * You can specify an update callback. This callback will be invoked _every frame_ for the duration - * of the transition. + * this.tweens.add({ + * targets: logo, + * x: 600, + * ease: 'Power1', + * duration: 2000 + * }); + * ``` * - * This Scene can either be sent to sleep at the end of the transition, or stopped. The default is to stop. + * See the `TweenBuilderConfig` for all of the options you have available. * - * There are also 5 transition related events: This scene will emit the event `transitionout` when - * the transition begins, which is typically the frame after calling this method. + * Playback will start immediately unless the tween has been configured to be paused. * - * The target Scene will emit the event `transitioninit` when that Scene's `init` method is called. - * It will then emit the event `transitionstart` when its `create` method is called. - * If the Scene was sleeping and has been woken up, it will emit the event `transitionwake` instead of these two, - * as the Scenes `init` and `create` methods are not invoked when a Scene wakes up. + * Please note that a Tween will not manipulate any target property that begins with an underscore. * - * When the duration of the transition has elapsed it will emit the event `transitioncomplete`. - * These events are cleared of all listeners when the Scene shuts down, but not if it is sent to sleep. + * Tweens are designed to be 'fire-and-forget'. They automatically destroy themselves once playback + * is complete, to free-up memory and resources. If you wish to keep a tween after playback, i.e. to + * play it again at a later time, then you should set the `persist` property to `true` in the config. + * However, doing so means it's entirely up to _you_ to destroy the tween when you're finished with it, + * otherwise it will linger in memory forever. * - * It's important to understand that the duration of the transition begins the moment you call this method. - * If the Scene you are transitioning to includes delayed processes, such as waiting for files to load, the - * time still counts down even while that is happening. If the game itself pauses, or something else causes - * this Scenes update loop to stop, then the transition will also pause for that duration. There are - * checks in place to prevent you accidentally stopping a transitioning Scene but if you've got code to - * override this understand that until the target Scene completes it might never be unlocked for input events. + * If you wish to chain Tweens together for sequential playback, see the `TweenManager.chain` method. * - * @method Phaser.Scenes.ScenePlugin#transition - * @fires Phaser.Scenes.Events#TRANSITION_OUT - * @since 3.5.0 + * @method Phaser.Tweens.TweenManager#add + * @since 3.0.0 * - * @param {Phaser.Types.Scenes.SceneTransitionConfig} config - The transition configuration object. + * @param {Phaser.Types.Tweens.TweenBuilderConfig|Phaser.Types.Tweens.TweenChainBuilderConfig|Phaser.Tweens.Tween|Phaser.Tweens.TweenChain} config - A Tween Configuration object, or a Tween or TweenChain instance. * - * @return {boolean} `true` is the transition was started, otherwise `false`. + * @return {Phaser.Tweens.Tween} The created Tween. */ - transition: function (config) + add: function (config) { - if (config === undefined) { config = {}; } - - var key = GetFastValue(config, 'target', false); - - var target = this.manager.getScene(key); - - if (!key || !this.checkValidTransition(target)) - { - return false; - } - - var duration = GetFastValue(config, 'duration', 1000); - - this._elapsed = 0; - this._target = target; - this._duration = duration; - this._willSleep = GetFastValue(config, 'sleep', false); - this._willRemove = GetFastValue(config, 'remove', false); - - var callback = GetFastValue(config, 'onUpdate', null); - - if (callback) - { - this._onUpdate = callback; - this._onUpdateScope = GetFastValue(config, 'onUpdateScope', this.scene); - } - - var allowInput = GetFastValue(config, 'allowInput', false); - - this.settings.transitionAllowInput = allowInput; - - var targetSettings = target.sys.settings; - - targetSettings.isTransition = true; - targetSettings.transitionFrom = this.scene; - targetSettings.transitionDuration = duration; - targetSettings.transitionAllowInput = allowInput; - - if (GetFastValue(config, 'moveAbove', false)) - { - this.manager.moveAbove(this.key, key); - } - else if (GetFastValue(config, 'moveBelow', false)) - { - this.manager.moveBelow(this.key, key); - } + var tween = config; + var tweens = this.tweens; - if (target.sys.isSleeping()) + if (tween instanceof Tween || tween instanceof TweenChain) { - target.sys.wake(GetFastValue(config, 'data')); + tweens.push(tween.reset()); } else { - this.manager.start(key, GetFastValue(config, 'data')); - } - - this.systems.events.emit(Events.TRANSITION_OUT, target, duration); + if (Array.isArray(tween.tweens)) + { + tween = TweenChainBuilder(this, tween); + } + else + { + tween = TweenBuilder(this, tween); + } - this.systems.events.on(Events.UPDATE, this.step, this); + tweens.push(tween.reset()); + } - return true; + return tween; }, /** - * Checks to see if this Scene can transition to the target Scene or not. + * Create multiple Tweens and add them all to this Tween Manager, by passing an array of Tween Configuration objects. * - * @method Phaser.Scenes.ScenePlugin#checkValidTransition - * @private - * @since 3.5.0 + * See the `TweenBuilderConfig` for all of the options you have available. * - * @param {Phaser.Scene} target - The Scene to test against. + * Playback will start immediately unless the tweens have been configured to be paused. * - * @return {boolean} `true` if this Scene can transition, otherwise `false`. - */ - checkValidTransition: function (target) - { - // Not a valid target if it doesn't exist, isn't active or is already transitioning in or out - if (!target || target.sys.isActive() || target.sys.isTransitioning() || target === this.scene || this.systems.isTransitioning()) - { - return false; - } - - return true; - }, - - /** - * A single game step. This is only called if the parent Scene is transitioning - * out to another Scene. + * Please note that a Tween will not manipulate any target property that begins with an underscore. * - * @method Phaser.Scenes.ScenePlugin#step - * @private - * @since 3.5.0 + * Tweens are designed to be 'fire-and-forget'. They automatically destroy themselves once playback + * is complete, to free-up memory and resources. If you wish to keep a tween after playback, i.e. to + * play it again at a later time, then you should set the `persist` property to `true` in the config. + * However, doing so means it's entirely up to _you_ to destroy the tween when you're finished with it, + * otherwise it will linger in memory forever. * - * @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. + * If you wish to chain Tweens together for sequential playback, see the `TweenManager.chain` method. + * + * @method Phaser.Tweens.TweenManager#addMultiple + * @since 3.60.0 + * + * @param {Phaser.Types.Tweens.TweenBuilderConfig[]|object[]} configs - An array of Tween Configuration objects. + * + * @return {Phaser.Tweens.Tween[]} An array of created Tweens. */ - step: function (time, delta) + addMultiple: function (configs) { - this._elapsed += delta; - - this.transitionProgress = Clamp(this._elapsed / this._duration, 0, 1); + var tween; + var result = []; + var tweens = this.tweens; - if (this._onUpdate) + for (var i = 0; i < configs.length; i++) { - this._onUpdate.call(this._onUpdateScope, this.transitionProgress); - } + tween = configs[i]; - if (this._elapsed >= this._duration) - { - this.transitionComplete(); + if (tween instanceof Tween || tween instanceof TweenChain) + { + tweens.push(tween.reset()); + } + else + { + if (Array.isArray(tween.tweens)) + { + tween = TweenChainBuilder(this, tween); + } + else + { + tween = TweenBuilder(this, tween); + } + + tweens.push(tween.reset()); + } + + result.push(tween); } + + return result; }, /** - * Called by `step` when the transition out of this scene to another is over. + * Create a sequence of Tweens, chained to one-another, and add them to this Tween Manager. * - * @method Phaser.Scenes.ScenePlugin#transitionComplete - * @private - * @fires Phaser.Scenes.Events#TRANSITION_COMPLETE - * @since 3.5.0 + * The tweens are played in order, from start to finish. You can optionally set the chain + * to repeat as many times as you like. Once the chain has finished playing, or repeating if set, + * all tweens in the chain will be destroyed automatically. To override this, set the 'persists' + * argument to 'true'. + * + * Playback will start immediately unless the _first_ Tween has been configured to be paused. + * + * Please note that Tweens will not manipulate any target property that begins with an underscore. + * + * @method Phaser.Tweens.TweenManager#chain + * @since 3.60.0 + * + * @param {Phaser.Types.Tweens.TweenChainBuilderConfig|object} tweens - A Tween Chain configuration object. + * + * @return {Phaser.Tweens.TweenChain} The Tween Chain instance. */ - transitionComplete: function () + chain: function (config) { - var targetSys = this._target.sys; - var targetSettings = this._target.sys.settings; - - // Stop the step - this.systems.events.off(Events.UPDATE, this.step, this); - - // Notify target scene - targetSys.events.emit(Events.TRANSITION_COMPLETE, this.scene); - - // Clear target scene settings - targetSettings.isTransition = false; - targetSettings.transitionFrom = null; + var chain = TweenChainBuilder(this, config); - // Clear local settings - this._duration = 0; - this._target = null; - this._onUpdate = null; - this._onUpdateScope = null; + this.tweens.push(chain.init()); - // Now everything is clear we can handle what happens to this Scene - if (this._willRemove) - { - this.manager.remove(this.key); - } - else if (this._willSleep) - { - this.systems.sleep(); - } - else - { - this.manager.stop(this.key); - } + return chain; }, /** - * Add the Scene into the Scene Manager and start it if 'autoStart' is true or the Scene config 'active' property is set. + * Returns an array containing this Tween and all Tweens chained to it, + * in the order in which they will be played. * - * @method Phaser.Scenes.ScenePlugin#add - * @since 3.0.0 + * If there are no chained Tweens an empty array is returned. * - * @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`. + * @method Phaser.Tweens.TweenManager#getChainedTweens + * @since 3.60.0 * - * @return {?Phaser.Scene} The added Scene, if it was added immediately, otherwise `null`. + * @param {Phaser.Tweens.Tween} tween - The Tween to return the chain from. + * + * @return {Phaser.Tweens.Tween[]} An array of the chained tweens, or an empty array if there aren't any. */ - add: function (key, sceneConfig, autoStart, data) + getChainedTweens: function (tween) { - return this.manager.add(key, sceneConfig, autoStart, data); + return tween.getChainedTweens(); }, /** - * Launch the given Scene and run it in parallel with this one. + * Check to see if the given Tween instance exists within this Tween Manager. * - * This will happen at the next Scene Manager update, not immediately. + * Will return `true` as long as the Tween is being processed by this Tween Manager. * - * @method Phaser.Scenes.ScenePlugin#launch - * @since 3.0.0 + * Will return `false` if not present, or has a state of `REMOVED` or `DESTROYED`. * - * @param {(string|Phaser.Scene)} key - The Scene to launch. - * @param {object} [data] - The Scene data. + * @method Phaser.Tweens.TweenManager#has + * @since 3.60.0 * - * @return {this} This Scene Plugin instance. + * @param {Phaser.Tweens.Tween} tween - The Tween instance to check. + * + * @return {boolean} `true` if the Tween exists within this Tween Manager, otherwise `false`. */ - launch: function (key, data) + has: function (tween) { - if (key && key !== this.key) - { - this.manager.queueOp('start', key, data); - } - - return this; + return (this.tweens.indexOf(tween) > -1); }, /** - * Runs the given Scene, but does not change the state of this Scene. - * - * This will happen at the next Scene Manager update, not immediately. + * Add an existing Tween to this Tween Manager. * - * 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. + * Playback will start immediately unless the tween has been configured to be paused. * - * @method Phaser.Scenes.ScenePlugin#run - * @since 3.10.0 + * @method Phaser.Tweens.TweenManager#existing + * @since 3.0.0 * - * @param {(string|Phaser.Scene)} key - The Scene to run. - * @param {object} [data] - A data object that will be passed to the Scene and emitted in its ready, wake, or resume events. + * @param {Phaser.Tweens.Tween} tween - The Tween to add. * - * @return {this} This Scene Plugin instance. + * @return {this} This Tween Manager instance. */ - run: function (key, data) + existing: function (tween) { - if (key && key !== this.key) + if (!this.has(tween)) { - this.manager.queueOp('run', key, data); + this.tweens.push(tween.reset()); } return this; }, /** - * Pause the Scene - this stops the update step from happening but it still renders. + * Create a Number Tween and add it to the active Tween list. * - * This will happen at the next Scene Manager update, not immediately. + * A Number Tween is a special kind of tween that doesn't have a target. Instead, + * it allows you to tween between 2 numeric values. The default values are + * `0` and `1`, but you can change them via the `from` and `to` properties. * - * @method Phaser.Scenes.ScenePlugin#pause + * You can get the current tweened value via the `Tween.getValue()` method. + * + * Playback will start immediately unless the tween has been configured to be paused. + * + * Please note that a Tween will not manipulate any target property that begins with an underscore. + * + * @method Phaser.Tweens.TweenManager#addCounter * @since 3.0.0 * - * @param {(string|Phaser.Scene)} [key] - The Scene to pause. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its pause event. + * @param {Phaser.Types.Tweens.NumberTweenBuilderConfig} config - The configuration object for the Number Tween. * - * @return {this} This Scene Plugin instance. + * @return {Phaser.Tweens.Tween} The created Number Tween. */ - pause: function (key, data) + addCounter: function (config) { - if (key === undefined) { key = this.key; } + var tween = NumberTweenBuilder(this, config); - this.manager.queueOp('pause', key, data); + this.tweens.push(tween.reset()); - return this; + return tween; }, /** - * Resume the Scene - starts the update loop again. + * Creates a Stagger function to be used by a Tween property. * - * This will happen at the next Scene Manager update, not immediately. + * The stagger function will allow you to stagger changes to the value of the property across all targets of the tween. * - * @method Phaser.Scenes.ScenePlugin#resume - * @since 3.0.0 + * This is only worth using if the tween has multiple targets. * - * @param {(string|Phaser.Scene)} [key] - The Scene to resume. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its resume event. + * 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: * - * @return {this} This Scene Plugin instance. + * ```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' }) + * }); + * ``` + * + * @method Phaser.Tweens.TweenManager#stagger + * @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 - The configuration object for the Stagger function. + * + * @return {function} The stagger function. */ - resume: function (key, data) + stagger: function (value, options) { - if (key === undefined) { key = this.key; } - - this.manager.queueOp('resume', key, data); - - return this; + return StaggerBuilder(value, options); }, /** - * Makes the Scene sleep (no update, no render) but doesn't shutdown. + * Set the limits that are used when a browser encounters lag, or delays that cause the elapsed + * time between two frames to exceed the expected amount. If this occurs, the Tween Manager will + * act as if the 'skip' amount of times has passed, in order to maintain strict tween sequencing. * - * This will happen at the next Scene Manager update, not immediately. + * This is enabled by default with the values 500ms for the lag limit and 33ms for the skip. * - * @method Phaser.Scenes.ScenePlugin#sleep - * @since 3.0.0 + * You should not set these to low values, as it won't give time for the browser to ever + * catch-up with itself and reclaim sync. * - * @param {(string|Phaser.Scene)} [key] - The Scene to put to sleep. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its sleep event. + * Call this method with no arguments to disable smoothing. * - * @return {this} This Scene Plugin instance. + * Call it with the arguments `500` and `33` to reset to the defaults. + * + * @method Phaser.Tweens.TweenManager#setLagSmooth + * @since 3.60.0 + * + * @param {number} [limit=0] - If the browser exceeds this amount, in milliseconds, it will act as if the 'skip' amount has elapsed instead. + * @param {number} [skip=0] - The amount, in milliseconds, to use as the step delta should the browser lag beyond the 'limit'. + * + * @return {this} This Tween Manager instance. */ - sleep: function (key, data) + setLagSmooth: function (limit, skip) { - if (key === undefined) { key = this.key; } + if (limit === undefined) { limit = 1 / 1e-8; } + if (skip === undefined) { skip = 0; } - this.manager.queueOp('sleep', key, data); + this.maxLag = limit; + this.lagSkip = Math.min(skip, this.maxLag); return this; }, /** - * Makes the Scene wake-up (starts update and render) + * Limits the Tween system to run at a particular frame rate. * - * This will happen at the next Scene Manager update, not immediately. + * You should not set this _above_ the frequency of the browser, + * but instead can use it to throttle the frame rate lower, should + * you need to in certain situations. * - * @method Phaser.Scenes.ScenePlugin#wake - * @since 3.0.0 + * @method Phaser.Tweens.TweenManager#setFps + * @since 3.60.0 * - * @param {(string|Phaser.Scene)} [key] - The Scene to wake up. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its wake event. + * @param {number} [fps=240] - The frame rate to tick at. * - * @return {this} This Scene Plugin instance. + * @return {this} This Tween Manager instance. */ - wake: function (key, data) + setFps: function (fps) { - if (key === undefined) { key = this.key; } + if (fps === undefined) { fps = 240; } - this.manager.queueOp('wake', key, data); + this.gap = 1000 / fps; + this.nextTime = this.time * 1000 + this.gap; return this; }, /** - * Makes this Scene sleep then starts the Scene given. + * Internal method that calculates the delta value, along with the other timing values, + * and returns the new delta. * - * This will happen at the next Scene Manager update, not immediately. + * You should not typically call this method directly. * - * @method Phaser.Scenes.ScenePlugin#switch - * @since 3.0.0 + * @method Phaser.Tweens.TweenManager#getDelta + * @since 3.60.0 * - * @param {(string|Phaser.Scene)} key - The Scene to start. + * @param {boolean} [tick=false] - Is this a manual tick, or an automated tick? * - * @return {this} This Scene Plugin instance. + * @return {number} The new delta value. */ - switch: function (key) + getDelta: function (tick) { - if (key !== this.key) + var elapsed = Date.now() - this.prevTime; + + if (elapsed > this.maxLag) { - this.manager.queueOp('switch', this.key, key); + this.startTime += elapsed - this.lagSkip; } - return this; + this.prevTime += elapsed; + + var time = this.prevTime - this.startTime; + var overlap = time - this.nextTime; + var delta = time - this.time * 1000; + + if (overlap > 0 || tick) + { + time /= 1000; + this.time = time; + this.nextTime += overlap + (overlap >= this.gap ? 4 : this.gap - overlap); + } + else + { + delta = 0; + } + + return delta; }, /** - * Shutdown the Scene, clearing display list, timers, etc. - * - * This happens at the next Scene Manager update, not immediately. + * Manually advance the Tween system by one step. * - * @method Phaser.Scenes.ScenePlugin#stop - * @since 3.0.0 + * This will update all Tweens even if the Tween Manager is currently + * paused. * - * @param {(string|Phaser.Scene)} [key] - The Scene to stop. - * @param {any} [data] - Optional data object to pass to Scene.Systems.shutdown. + * @method Phaser.Tweens.TweenManager#tick + * @since 3.60.0 * - * @return {this} This Scene Plugin instance. + * @return {this} This Tween Manager instance. */ - stop: function (key, data) + tick: function () { - if (key === undefined) { key = this.key; } - - this.manager.queueOp('stop', key, data); + this.step(true); return this; }, /** - * Sets the active state of the given Scene. - * - * @method Phaser.Scenes.ScenePlugin#setActive - * @since 3.0.0 + * Internal update handler. * - * @param {boolean} value - If `true` the Scene will be resumed. If `false` it will be paused. - * @param {(string|Phaser.Scene)} [key] - The Scene to set the active state of. - * @param {object} [data] - An optional data object that will be passed to the Scene and emitted with its events. + * Calls `TweenManager.step` as long as the Tween Manager has not + * been paused. * - * @return {this} This Scene Plugin instance. + * @method Phaser.Tweens.TweenManager#update + * @since 3.0.0 */ - setActive: function (value, key, data) + update: function () { - if (key === undefined) { key = this.key; } - - var scene = this.manager.getScene(key); - - if (scene) + if (!this.paused) { - scene.sys.setActive(value, data); + this.step(false); } - - return this; }, /** - * Sets the visible state of the given Scene. + * Updates all Tweens belonging to this Tween Manager. * - * @method Phaser.Scenes.ScenePlugin#setVisible - * @since 3.0.0 + * Called automatically by `update` and `tick`. * - * @param {boolean} value - The visible value. - * @param {(string|Phaser.Scene)} [key] - The Scene to set the visible state for. + * @method Phaser.Tweens.TweenManager#step + * @since 3.60.0 * - * @return {this} This Scene Plugin instance. + * @param {boolean} [tick=false] - Is this a manual tick, or an automated tick? */ - setVisible: function (value, key) + step: function (tick) { - if (key === undefined) { key = this.key; } + if (tick === undefined) { tick = false; } - var scene = this.manager.getScene(key); + var delta = this.getDelta(tick); - if (scene) + if (delta <= 0) { - scene.sys.setVisible(value); + // If we've got a negative delta, skip this step + return; } - return this; - }, + this.processing = true; - /** - * Checks if the given Scene is sleeping or not? - * - * @method Phaser.Scenes.ScenePlugin#isSleeping - * @since 3.0.0 - * - * @param {(string|Phaser.Scene)} [key] - The Scene to check. - * - * @return {boolean} Whether the Scene is sleeping, or `null` if no matching Scene was found. - */ - isSleeping: function (key) - { - if (key === undefined) { key = this.key; } + var i; + var tween; + var toDestroy = []; + var list = this.tweens; - return this.manager.isSleeping(key); + // By not caching the length we can immediately update tweens added + // this frame (such as chained tweens) + for (i = 0; i < list.length; i++) + { + tween = list[i]; + + // If Tween.update returns 'true' then it means it has completed, + // so move it to the destroy list + if (tween.update(delta)) + { + toDestroy.push(tween); + } + } + + // Clean-up the 'toDestroy' list + var count = toDestroy.length; + + if (count && list.length > 0) + { + for (i = 0; i < count; i++) + { + tween = toDestroy[i]; + + var idx = list.indexOf(tween); + + if (idx > -1 && (tween.isPendingRemove() || tween.isDestroyed())) + { + list.splice(idx, 1); + + tween.destroy(); + } + } + + toDestroy.length = 0; + } + + this.processing = false; }, /** - * Checks if the given Scene is running or not? + * Removes the given Tween from this Tween Manager, even if it hasn't started + * playback yet. If this method is called while the Tween Manager is processing + * an update loop, then the tween will be flagged for removal at the start of + * the next frame. Otherwise, it is removed immediately. * - * @method Phaser.Scenes.ScenePlugin#isActive - * @since 3.0.0 + * The removed tween is _not_ destroyed. It is just removed from this Tween Manager. * - * @param {(string|Phaser.Scene)} [key] - The Scene to check. + * @method Phaser.Tweens.TweenManager#remove + * @since 3.17.0 * - * @return {boolean} Whether the Scene is running, or `null` if no matching Scene was found. + * @param {Phaser.Tweens.Tween} tween - The Tween to be removed. + * + * @return {this} This Tween Manager instance. */ - isActive: function (key) + remove: function (tween) { - if (key === undefined) { key = this.key; } + if (this.processing) + { + // Remove it on the next frame + tween.setPendingRemoveState(); + } + else + { + // Remove it immediately + ArrayRemove(this.tweens, tween); - return this.manager.isActive(key); + tween.setRemovedState(); + } + + return this; }, /** - * Checks if the given Scene is paused or not? + * Resets the given Tween. * - * @method Phaser.Scenes.ScenePlugin#isPaused - * @since 3.17.0 + * If the Tween does not belong to this Tween Manager, it will first be added. * - * @param {(string|Phaser.Scene)} [key] - The Scene to check. + * Then it will seek to position 0 and playback will start on the next frame. * - * @return {boolean} Whether the Scene is paused, or `null` if no matching Scene was found. + * @method Phaser.Tweens.TweenManager#reset + * @since 3.60.0 + * + * @param {Phaser.Tweens.Tween} tween - The Tween to be reset. + * + * @return {this} This Tween Manager instance. */ - isPaused: function (key) + reset: function (tween) { - if (key === undefined) { key = this.key; } + this.existing(tween); - return this.manager.isPaused(key); + tween.seek(); + + tween.setActiveState(); + + return this; }, /** - * Checks if the given Scene is visible or not? + * Checks if a Tween is active and adds it to the Tween Manager at the start of the frame if it isn't. * - * @method Phaser.Scenes.ScenePlugin#isVisible + * @method Phaser.Tweens.TweenManager#makeActive * @since 3.0.0 * - * @param {(string|Phaser.Scene)} [key] - The Scene to check. + * @param {Phaser.Tweens.Tween} tween - The Tween to check. * - * @return {boolean} Whether the Scene is visible, or `null` if no matching Scene was found. + * @return {this} This Tween Manager instance. */ - isVisible: function (key) + makeActive: function (tween) { - if (key === undefined) { key = this.key; } + this.existing(tween); - return this.manager.isVisible(key); + tween.setActiveState(); + + return this; }, /** - * Swaps the position of two scenes in the Scenes list. - * - * This controls the order in which they are rendered and updated. + * Passes all Tweens to the given callback. * - * @method Phaser.Scenes.ScenePlugin#swapPosition - * @since 3.2.0 + * @method Phaser.Tweens.TweenManager#each + * @since 3.0.0 * - * @param {(string|Phaser.Scene)} keyA - The first Scene to swap. - * @param {(string|Phaser.Scene)} [keyB] - The second Scene to swap. If none is given it defaults to this Scene. + * @param {function} callback - The function to call. + * @param {object} [scope] - The scope (`this` object) to call the function with. + * @param {...*} [args] - The arguments to pass into the function. Its first argument will always be the Tween currently being iterated. * - * @return {this} This Scene Plugin instance. + * @return {this} This Tween Manager instance. */ - swapPosition: function (keyA, keyB) + each: function (callback, scope) { - if (keyB === undefined) { keyB = this.key; } + var i; + var args = [ null ]; - if (keyA !== keyB) + for (i = 1; i < arguments.length; i++) { - this.manager.swapPosition(keyA, keyB); + args.push(arguments[i]); } + this.tweens.forEach(function (tween) + { + args[0] = tween; + + callback.apply(scope, args); + }); + return this; }, /** - * Swaps the position of two scenes in the Scenes list, so that Scene B is directly above Scene A. + * Returns an array containing references to all Tweens in this Tween Manager. * - * This controls the order in which they are rendered and updated. + * It is safe to mutate the returned array. However, acting upon any of the Tweens + * within it, will adjust those stored in this Tween Manager, as they are passed + * by reference and not cloned. * - * @method Phaser.Scenes.ScenePlugin#moveAbove - * @since 3.2.0 + * If you wish to get tweens for a specific target, see `getTweensOf`. * - * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved to be above. - * @param {(string|Phaser.Scene)} [keyB] - The Scene to be moved. If none is given it defaults to this Scene. + * @method Phaser.Tweens.TweenManager#getTweens + * @since 3.0.0 * - * @return {this} This Scene Plugin instance. + * @return {Phaser.Tweens.Tween[]} A new array containing references to all Tweens. */ - moveAbove: function (keyA, keyB) + getTweens: function () { - if (keyB === undefined) { keyB = this.key; } - - if (keyA !== keyB) - { - this.manager.moveAbove(keyA, keyB); - } - - return this; + return this.tweens.slice(); }, /** - * Swaps the position of two scenes in the Scenes list, so that Scene B is directly below Scene A. + * Returns an array of all Tweens in the Tween Manager which affect the given target, or array of targets. * - * This controls the order in which they are rendered and updated. + * It's possible for this method to return tweens that are about to be removed from + * the Tween Manager. You should check the state of the returned tween before acting + * upon it. * - * @method Phaser.Scenes.ScenePlugin#moveBelow - * @since 3.2.0 + * @method Phaser.Tweens.TweenManager#getTweensOf + * @since 3.0.0 * - * @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved to be below. - * @param {(string|Phaser.Scene)} [keyB] - The Scene to be moved. If none is given it defaults to this Scene. + * @param {(object|object[])} target - The target to look for. Provide an array to look for multiple targets. * - * @return {this} This Scene Plugin instance. + * @return {Phaser.Tweens.Tween[]} A new array containing all Tweens which affect the given target(s). */ - moveBelow: function (keyA, keyB) + getTweensOf: function (target) { - if (keyB === undefined) { keyB = this.key; } + var output = []; + var list = this.tweens; + + if (!Array.isArray(target)) + { + target = [ target ]; + } + else + { + target = Flatten(target); + } - if (keyA !== keyB) + var targetLen = target.length; + + for (var i = 0; i < list.length; i++) { - this.manager.moveBelow(keyA, keyB); + var tween = list[i]; + + for (var t = 0; t < targetLen; t++) + { + if (!tween.isDestroyed() && tween.hasTarget(target[t])) + { + output.push(tween); + } + } } - return this; + return output; }, /** - * 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. + * Returns the scale of the time delta for all Tweens owned by this Tween Manager. * - * @method Phaser.Scenes.ScenePlugin#remove - * @since 3.2.0 - * - * @param {(string|Phaser.Scene)} [key] - The Scene to be removed. + * @method Phaser.Tweens.TweenManager#getGlobalTimeScale + * @since 3.0.0 * - * @return {this} This Scene Plugin instance. + * @return {number} The scale of the time delta, usually 1. */ - remove: function (key) + getGlobalTimeScale: function () { - if (key === undefined) { key = this.key; } - - this.manager.remove(key); - - return this; + return this.timeScale; }, /** - * Moves a Scene up one position in the Scenes list. + * Sets a new scale of the time delta for this Tween Manager. * - * @method Phaser.Scenes.ScenePlugin#moveUp + * The time delta is the time elapsed between two consecutive frames and influences the speed of time for this Tween Manager and all Tweens it owns. Values higher than 1 increase the speed of time, while values smaller than 1 decrease it. A value of 0 freezes time and is effectively equivalent to pausing all Tweens. + * + * @method Phaser.Tweens.TweenManager#setGlobalTimeScale * @since 3.0.0 * - * @param {(string|Phaser.Scene)} [key] - The Scene to move. + * @param {number} value - The new scale of the time delta, where 1 is the normal speed. * - * @return {this} This Scene Plugin instance. + * @return {this} This Tween Manager instance. */ - moveUp: function (key) + setGlobalTimeScale: function (value) { - if (key === undefined) { key = this.key; } - - this.manager.moveUp(key); + this.timeScale = value; return this; }, /** - * Moves a Scene down one position in the Scenes list. + * Checks if the given object is being affected by a _playing_ Tween. * - * @method Phaser.Scenes.ScenePlugin#moveDown + * If the Tween is paused, this method will return false. + * + * @method Phaser.Tweens.TweenManager#isTweening * @since 3.0.0 * - * @param {(string|Phaser.Scene)} [key] - The Scene to move. + * @param {object} target - The object to check if a tween is active for it, or not. * - * @return {this} This Scene Plugin instance. + * @return {boolean} Returns `true` if a tween is active on the given target, otherwise `false`. */ - moveDown: function (key) + isTweening: function (target) { - if (key === undefined) { key = this.key; } + var list = this.tweens; + var tween; - this.manager.moveDown(key); + for (var i = 0; i < list.length; i++) + { + tween = list[i]; - return this; + if (tween.isPlaying() && tween.hasTarget(target)) + { + return true; + } + } + + return false; }, /** - * Brings a Scene to the top of the Scenes list. + * Destroys all Tweens in this Tween Manager. * - * This means it will render above all other Scenes. + * The tweens will erase all references to any targets they hold + * and be stopped immediately. * - * @method Phaser.Scenes.ScenePlugin#bringToTop - * @since 3.0.0 + * If this method is called while the Tween Manager is running its + * update process, then the tweens will be removed at the start of + * the next frame. Outside of this, they are removed immediately. * - * @param {(string|Phaser.Scene)} [key] - The Scene to move. + * @method Phaser.Tweens.TweenManager#killAll + * @since 3.0.0 * - * @return {this} This Scene Plugin instance. + * @return {this} This Tween Manager instance. */ - bringToTop: function (key) + killAll: function () { - if (key === undefined) { key = this.key; } + var tweens = (this.processing) ? this.getTweens() : this.tweens; - this.manager.bringToTop(key); + for (var i = 0; i < tweens.length; i++) + { + tweens[i].destroy(); + } + + if (!this.processing) + { + tweens.length = 0; + } return this; }, /** - * Sends a Scene to the back of the Scenes list. + * Stops all Tweens which affect the given target or array of targets. * - * This means it will render below all other Scenes. + * The tweens will erase all references to any targets they hold + * and be stopped immediately. * - * @method Phaser.Scenes.ScenePlugin#sendToBack + * If this method is called while the Tween Manager is running its + * update process, then the tweens will be removed at the start of + * the next frame. Outside of this, they are removed immediately. + * + * @see {@link #getTweensOf} + * + * @method Phaser.Tweens.TweenManager#killTweensOf * @since 3.0.0 * - * @param {(string|Phaser.Scene)} [key] - The Scene to move. + * @param {(object|array)} target - The target to kill the tweens of. Provide an array to use multiple targets. * - * @return {this} This Scene Plugin instance. + * @return {this} This Tween Manager instance. */ - sendToBack: function (key) + killTweensOf: function (target) { - if (key === undefined) { key = this.key; } + var tweens = this.getTweensOf(target); - this.manager.sendToBack(key); + for (var i = 0; i < tweens.length; i++) + { + tweens[i].destroy(); + } return this; }, /** - * Retrieve a Scene. + * Pauses this Tween Manager. No Tweens will update while paused. * - * @method Phaser.Scenes.ScenePlugin#get - * @since 3.0.0 + * This includes tweens created after this method was called. * - * @param {(string|Phaser.Scene)} key - The Scene to retrieve. + * See `TweenManager#resumeAll` to resume the playback. * - * @return {Phaser.Scene} The Scene. + * As of Phaser 3.60 you can also toggle the boolean property `TweenManager.paused`. + * + * @method Phaser.Tweens.TweenManager#pauseAll + * @since 3.0.0 + * + * @return {this} This Tween Manager instance. */ - get: function (key) + pauseAll: function () { - return this.manager.getScene(key); + this.paused = true; + + return this; }, /** - * Retrieves the numeric index of a Scene in the Scenes list. + * Resumes playback of this Tween Manager. * - * @method Phaser.Scenes.ScenePlugin#getIndex - * @since 3.7.0 + * All active Tweens will continue updating. * - * @param {(string|Phaser.Scene)} [key] - The Scene to get the index of. + * See `TweenManager#pauseAll` to pause the playback. * - * @return {number} The index of the Scene. + * As of Phaser 3.60 you can also toggle the boolean property `TweenManager.paused`. + * + * @method Phaser.Tweens.TweenManager#resumeAll + * @since 3.0.0 + * + * @return {this} This Tween Manager instance. */ - getIndex: function (key) + resumeAll: function () { - if (key === undefined) { key = this.key; } + this.paused = false; - return this.manager.getIndex(key); + return this; }, /** @@ -207618,9382 +230898,10839 @@ var ScenePlugin = new Class({ * * We need to kill and reset all internal properties as well as stop listening to Scene events. * - * @method Phaser.Scenes.ScenePlugin#shutdown - * @private + * @method Phaser.Tweens.TweenManager#shutdown * @since 3.0.0 */ shutdown: function () { - var eventEmitter = this.systems.events; + this.killAll(); - eventEmitter.off(Events.SHUTDOWN, this.shutdown, this); - eventEmitter.off(Events.POST_UPDATE, this.step, this); - eventEmitter.off(Events.TRANSITION_OUT); + this.tweens = []; + + this.events.off(SceneEvents.UPDATE, this.update, this); + this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this); }, /** * The Scene that owns this plugin is being destroyed. - * * We need to shutdown and then kill off all external references. * - * @method Phaser.Scenes.ScenePlugin#destroy - * @private + * @method Phaser.Tweens.TweenManager#destroy * @since 3.0.0 */ destroy: function () { this.shutdown(); - this.scene.sys.events.off(Events.START, this.start, this); + this.events.off(SceneEvents.START, this.start, this); this.scene = null; - this.systems = null; - this.settings = null; - this.manager = null; + this.events = null; } }); -PluginCache.register('ScenePlugin', ScenePlugin, 'scenePlugin'); - -module.exports = ScenePlugin; - - -/***/ }), -/* 1415 */ -/***/ (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 - */ - -module.exports = { - - Events: __webpack_require__(438), - List: __webpack_require__(110), - Map: __webpack_require__(102), - ProcessQueue: __webpack_require__(211), - RTree: __webpack_require__(531), - Set: __webpack_require__(149), - Size: __webpack_require__(416) +PluginCache.register('TweenManager', TweenManager, 'tweens'); -}; +module.exports = TweenManager; /***/ }), -/* 1416 */ -/***/ (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 FilterMode = __webpack_require__(1417); - -/** - * @namespace Phaser.Textures - */ - -/** - * Linear filter type. - * - * @name Phaser.Textures.LINEAR - * @type {number} - * @const - * @since 3.0.0 - */ - -/** - * Nearest Neighbor filter type. - * - * @name Phaser.Textures.NEAREST - * @type {number} - * @const - * @since 3.0.0 - */ - -var Textures = { - - CanvasTexture: __webpack_require__(423), - Events: __webpack_require__(106), - FilterMode: FilterMode, - Frame: __webpack_require__(109), - Parsers: __webpack_require__(425), - Texture: __webpack_require__(206), - TextureManager: __webpack_require__(422), - TextureSource: __webpack_require__(424) - -}; - -Textures = Extend(false, Textures, FilterMode); - -module.exports = Textures; - -/***/ }), -/* 1417 */ -/***/ (function(module, exports) { +/***/ 63130: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Filter Types. + * Retrieves the value of the given key from an object. * - * @namespace Phaser.Textures.FilterMode - * @memberof Phaser.Textures + * @function Phaser.Tweens.Builders.GetBoolean * @since 3.0.0 - */ -var CONST = { - - /** - * Linear filter type. - * - * @name Phaser.Textures.FilterMode.LINEAR - * @type {number} - * @const - * @since 3.0.0 - */ - LINEAR: 0, - - /** - * Nearest neighbor filter type. - * - * @name Phaser.Textures.FilterMode.NEAREST - * @type {number} - * @const - * @since 3.0.0 - */ - NEAREST: 1 - -}; - -module.exports = CONST; - - -/***/ }), -/* 1418 */ -/***/ (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__(1419); - -/** - * @namespace Phaser.Tilemaps - * - * @borrows Phaser.Tilemaps.Orientation.ORTHOGONAL as ORTHOGONAL - * @borrows Phaser.Tilemaps.Orientation.ISOMETRIC as ISOMETRIC - * @borrows Phaser.Tilemaps.Orientation.STAGGERED as STAGGERED - * @borrows Phaser.Tilemaps.Orientation.HEXAGONAL as HEXAGONAL - */ - -var Tilemaps = { - - Components: __webpack_require__(251), - Parsers: __webpack_require__(1452), - - Formats: __webpack_require__(40), - ImageCollection: __webpack_require__(576), - ParseToTilemap: __webpack_require__(262), - Tile: __webpack_require__(85), - Tilemap: __webpack_require__(580), - TilemapCreator: __webpack_require__(1459), - TilemapFactory: __webpack_require__(1460), - Tileset: __webpack_require__(122), - TilemapLayer: __webpack_require__(581), - Orientation: __webpack_require__(29), - - LayerData: __webpack_require__(120), - MapData: __webpack_require__(121), - ObjectLayer: __webpack_require__(572) - -}; - -Tilemaps = Extend(false, Tilemaps, CONST.ORIENTATION); - -module.exports = Tilemaps; - - -/***/ }), -/* 1419 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var CONST = { - - ORIENTATION: __webpack_require__(29) - -}; - -module.exports = CONST; - - -/***/ }), -/* 1420 */ -/***/ (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 CalculateFacesWithin = __webpack_require__(63); - -/** - * 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. * - * @function Phaser.Tilemaps.Components.Copy - * @since 3.0.0 + * @param {object} source - The object to retrieve the value from. + * @param {string} key - The key to look for in the `source` object. + * @param {boolean} defaultValue - The default value to return if the `key` doesn't exist or if no `source` object is provided. * - * @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` if the faces data should be recalculated. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @return {boolean} The retrieved value. */ -var Copy = function (srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) +var GetBoolean = function (source, key, defaultValue) { - if (recalculateFaces === undefined) { recalculateFaces = true; } - - if (srcTileX < 0) { srcTileX = 0; } - if (srcTileY < 0) { srcTileY = 0; } - - var srcTiles = GetTilesWithin(srcTileX, srcTileY, width, height, null, layer); - - var offsetX = destTileX - srcTileX; - var offsetY = destTileY - srcTileY; - - for (var i = 0; i < srcTiles.length; i++) + if (!source) { - var tileX = srcTiles[i].x + offsetX; - var tileY = srcTiles[i].y + offsetY; - - if (tileX >= 0 && tileX < layer.width && tileY >= 0 && tileY < layer.height) - { - if (layer.data[tileY][tileX]) - { - layer.data[tileY][tileX].copy(srcTiles[i]); - } - } + return defaultValue; } - - if (recalculateFaces) + else if (source.hasOwnProperty(key)) { - // Recalculate the faces within the destination area and neighboring tiles - CalculateFacesWithin(destTileX - 1, destTileY - 1, width + 2, height + 2, layer); + return source[key]; + } + else + { + return defaultValue; } }; -module.exports = Copy; +module.exports = GetBoolean; /***/ }), -/* 1421 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 21902: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetTilesWithin = __webpack_require__(26); -var ReplaceByIndex = __webpack_require__(542); +var EaseMap = __webpack_require__(35060); +var UppercaseFirst = __webpack_require__(40587); /** - * 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. + * This internal function is used to return the correct ease function for a Tween. * - * @function Phaser.Tilemaps.Components.CreateFromTiles + * It can take a variety of input, including an EaseMap based string, or a custom function. + * + * @function Phaser.Tweens.Builders.GetEaseFunction * @since 3.0.0 * - * @param {(number|number[])} indexes - The tile index, or array of indexes, to create Sprites from. - * @param {(number|number[])} 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 - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {(string|function)} ease - The ease to find. This can be either a string from the EaseMap, or a custom function. + * @param {number[]} [easeParams] - An optional array of ease parameters to go with the ease. * - * @return {Phaser.GameObjects.Sprite[]} An array of the Sprites that were created. + * @return {function} The ease function. */ -var CreateFromTiles = function (indexes, replacements, spriteConfig, scene, camera, layer) +var GetEaseFunction = function (ease, easeParams) { - if (!spriteConfig) { spriteConfig = {}; } - - if (!Array.isArray(indexes)) - { - indexes = [ indexes ]; - } - - var tilemapLayer = layer.tilemapLayer; - - if (!scene) { scene = tilemapLayer.scene; } - if (!camera) { camera = scene.cameras.main; } - - var tiles = GetTilesWithin(0, 0, layer.width, layer.height, null, layer); - var sprites = []; - var i; + // Default ease function + var easeFunction = EaseMap.Power0; - for (i = 0; i < tiles.length; i++) + // Prepare ease function + if (typeof ease === 'string') { - var tile = tiles[i]; - - if (indexes.indexOf(tile.index) !== -1) - { - var point = tilemapLayer.tileToWorldXY(tile.x, tile.y, undefined, camera,layer); - - spriteConfig.x = point.x; - spriteConfig.y = point.y; - - sprites.push(scene.make.sprite(spriteConfig)); - } - } + // String based look-up - if (typeof replacements === 'number') - { - // Assume 1 replacement for all types of tile given - for (i = 0; i < indexes.length; i++) + // 1) They specified it correctly + if (EaseMap.hasOwnProperty(ease)) { - ReplaceByIndex(indexes[i], replacements, 0, 0, layer.width, layer.height, layer); + easeFunction = EaseMap[ease]; } - } - else if (Array.isArray(replacements)) - { - // Assume 1 to 1 mapping with indexes array - for (i = 0; i < indexes.length; i++) + else { - ReplaceByIndex(indexes[i], replacements[i], 0, 0, layer.width, layer.height, layer); - } - } - - return sprites; -}; - -module.exports = CreateFromTiles; - - -/***/ }), -/* 1422 */ -/***/ (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 CalculateFacesWithin = __webpack_require__(63); -var SetTileCollision = __webpack_require__(72); - -/** - * 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. - * - * @function Phaser.Tilemaps.Components.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` if the faces data should be recalculated. - * @param {Phaser.Tilemaps.LayerData} layer - The tile layer to use. If not given the current layer is used. - */ -var Fill = function (index, tileX, tileY, width, height, recalculateFaces, layer) -{ - var doesIndexCollide = (layer.collideIndexes.indexOf(index) !== -1); - - var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); - - for (var i = 0; i < tiles.length; i++) - { - tiles[i].index = index; - - SetTileCollision(tiles[i], doesIndexCollide); - } - - if (recalculateFaces) - { - // Recalculate the faces within the area and neighboring tiles - CalculateFacesWithin(tileX - 1, tileY - 1, width + 2, height + 2, layer); - } -}; - -module.exports = Fill; - - -/***/ }), -/* 1423 */ -/***/ (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); - -/** - * 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. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile[]} The filtered array of Tiles. - */ -var FilterTiles = function (callback, context, tileX, tileY, width, height, filteringOptions, layer) -{ - var tiles = GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); - - return tiles.filter(callback, context); -}; - -module.exports = FilterTiles; - - -/***/ }), -/* 1424 */ -/***/ (function(module, exports) { + // Do some string manipulation to try and find it + var direction = ''; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (ease.indexOf('.')) + { + // quad.in = Quad.easeIn + // quad.out = Quad.easeOut + // quad.inout = Quad.easeInOut -/** - * 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. - * - * @function Phaser.Tilemaps.Components.FindByIndex - * @since 3.0.0 - * - * @param {number} index - The tile index value to search for. - * @param {number} skip - The number of times to skip a matching tile before returning. - * @param {boolean} reverse - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {?Phaser.Tilemaps.Tile} The first (or n skipped) tile with the matching index. - */ -var FindByIndex = function (findIndex, skip, reverse, layer) -{ - if (skip === undefined) { skip = 0; } - if (reverse === undefined) { reverse = false; } + direction = ease.substring(ease.indexOf('.') + 1); - var count = 0; - var tx; - var ty; - var tile; + var directionLower = direction.toLowerCase(); - if (reverse) - { - for (ty = layer.height - 1; ty >= 0; ty--) - { - for (tx = layer.width - 1; tx >= 0; tx--) - { - tile = layer.data[ty][tx]; - if (tile && tile.index === findIndex) + if (directionLower === 'in') { - if (count === skip) - { - return tile; - } - else - { - count += 1; - } + direction = 'easeIn'; } - } - } - } - else - { - for (ty = 0; ty < layer.height; ty++) - { - for (tx = 0; tx < layer.width; tx++) - { - tile = layer.data[ty][tx]; - if (tile && tile.index === findIndex) + else if (directionLower === 'out') { - if (count === skip) - { - return tile; - } - else - { - count += 1; - } + direction = 'easeOut'; + } + else if (directionLower === 'inout') + { + direction = 'easeInOut'; } } - } - } - - return null; -}; - -module.exports = FindByIndex; - - -/***/ }), -/* 1425 */ -/***/ (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); - -/** - * @callback FindTileCallback - * - * @param {Phaser.Tilemaps.Tile} value - The Tile. - * @param {number} index - The index of the tile. - * @param {Phaser.Tilemaps.Tile[]} array - An array of Tile objects. - * - * @return {boolean} Return `true` if the callback should run, otherwise `false`. - */ - -/** - * 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. - * - * @function Phaser.Tilemaps.Components.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 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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {?Phaser.Tilemaps.Tile} A Tile that matches the search, or null if no Tile found - */ -var FindTile = function (callback, context, tileX, tileY, width, height, filteringOptions, layer) -{ - var tiles = GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); - - return tiles.find(callback, context) || null; -}; - -module.exports = FindTile; - - -/***/ }), -/* 1426 */ -/***/ (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); - -/** - * @callback EachTileCallback - * - * @param {Phaser.Tilemaps.Tile} value - The Tile. - * @param {number} index - The index of the tile. - * @param {Phaser.Tilemaps.Tile[]} array - An array of Tile objects. - */ - -/** - * 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. - * - * @function Phaser.Tilemaps.Components.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 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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - */ -var ForEachTile = function (callback, context, tileX, tileY, width, height, filteringOptions, layer) -{ - var tiles = GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer); - - tiles.forEach(callback, context); -}; - -module.exports = ForEachTile; - - -/***/ }), -/* 1427 */ -/***/ (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__(29); -var CullTiles = __webpack_require__(544); -var HexagonalCullTiles = __webpack_require__(545); -var IsometricCullTiles = __webpack_require__(547); -var NOOP = __webpack_require__(1); -var StaggeredCullTiles = __webpack_require__(548); - -/** - * Gets the correct function to use to cull tiles, based on the map orientation. - * - * @function Phaser.Tilemaps.Components.GetCullTilesFunction - * @since 3.50.0 - * - * @param {number} orientation - The Tilemap orientation constant. - * - * @return {function} The function to use to cull tiles for the given map type. - */ -var GetCullTilesFunction = function (orientation) -{ - if (orientation === CONST.ORTHOGONAL) - { - return CullTiles; - } - else if (orientation === CONST.HEXAGONAL) - { - return HexagonalCullTiles; - } - else if (orientation === CONST.STAGGERED) - { - return StaggeredCullTiles; - } - else if (orientation === CONST.ISOMETRIC) - { - return IsometricCullTiles; - } - else - { - return NOOP; - } -}; - -module.exports = GetCullTilesFunction; - - -/***/ }), -/* 1428 */ -/***/ (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__(158); -var Vector2 = __webpack_require__(3); - -var point = new Vector2(); - -/** - * Gets a tile at the given world coordinates from the given layer. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid. - */ -var GetTileAtWorldXY = function (worldX, worldY, nonNull, camera, layer) -{ - layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera); - - return GetTileAt(point.x, point.y, nonNull, layer); -}; - -module.exports = GetTileAtWorldXY; - -/***/ }), -/* 1429 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var Geom = __webpack_require__(483); -var GetTilesWithin = __webpack_require__(26); -var Intersects = __webpack_require__(484); -var NOOP = __webpack_require__(1); -var Vector2 = __webpack_require__(3); - -var TriangleToRectangle = function (triangle, rect) -{ - return Intersects.RectangleToTriangle(rect, triangle); -}; - -var point = new Vector2(); -var pointStart = new Vector2(); -var pointEnd = new Vector2(); - -/** - * 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. - * - * @function Phaser.Tilemaps.Components.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 calculating the tile index from the world values. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * - * @return {Phaser.Tilemaps.Tile[]} Array of Tile objects. - */ -var GetTilesWithinShape = function (shape, filteringOptions, camera, layer) -{ - if (shape === undefined) { return []; } - - // intersectTest is a function with parameters: shape, rect - var intersectTest = NOOP; - - if (shape instanceof Geom.Circle) - { - intersectTest = Intersects.CircleToRectangle; - } - else if (shape instanceof Geom.Rectangle) - { - intersectTest = Intersects.RectangleToRectangle; - } - else if (shape instanceof Geom.Triangle) - { - intersectTest = TriangleToRectangle; - } - else if (shape instanceof Geom.Line) - { - intersectTest = Intersects.LineToRectangle; - } - - // Top left corner of the shapes's bounding box, rounded down to include partial tiles - layer.tilemapLayer.worldToTileXY(shape.left, shape.top, true, pointStart, camera); - - var xStart = pointStart.x; - var yStart = pointStart.y; - - // Bottom right corner of the shapes's bounding box, rounded up to include partial tiles - layer.tilemapLayer.worldToTileXY(shape.right, shape.bottom, true, pointEnd, camera); - - var xEnd = Math.ceil(pointEnd.x); - var yEnd = Math.ceil(pointEnd.y); - - // Tiles within bounding rectangle of shape. Bounds are forced to be at least 1 x 1 tile in size - // to grab tiles for shapes that don't have a height or width (e.g. a horizontal line). - var width = Math.max(xEnd - xStart, 1); - var height = Math.max(yEnd - yStart, 1); - - var tiles = GetTilesWithin(xStart, yStart, width, height, filteringOptions, layer); - - var tileWidth = layer.tileWidth; - var tileHeight = layer.tileHeight; - - if (layer.tilemapLayer) - { - tileWidth *= layer.tilemapLayer.scaleX; - tileHeight *= layer.tilemapLayer.scaleY; - } - - var results = []; - var tileRect = new Geom.Rectangle(0, 0, tileWidth, tileHeight); - - for (var i = 0; i < tiles.length; i++) - { - var tile = tiles[i]; + ease = UppercaseFirst(ease.substring(0, ease.indexOf('.') + 1) + direction); - layer.tilemapLayer.tileToWorldXY(tile.x, tile.y, point, camera); - - tileRect.x = point.x; - tileRect.y = point.y; - - if (intersectTest(shape, tileRect)) - { - results.push(tile); + if (EaseMap.hasOwnProperty(ease)) + { + easeFunction = EaseMap[ease]; + } } } - - return results; -}; - -module.exports = GetTilesWithinShape; - - -/***/ }), -/* 1430 */ -/***/ (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__(29); -var NOOP = __webpack_require__(1); -var TileToWorldX = __webpack_require__(253); - -/** - * Gets the correct function to use to translate tiles, based on the map orientation. - * - * @function Phaser.Tilemaps.Components.GetTileToWorldXFunction - * @since 3.50.0 - * - * @param {number} orientation - The Tilemap orientation constant. - * - * @return {function} The function to use to translate tiles for the given map type. - */ -var GetTileToWorldXFunction = function (orientation) -{ - if (orientation === CONST.ORTHOGONAL) - { - return TileToWorldX; - } - else - { - return NOOP; - } -}; - -module.exports = GetTileToWorldXFunction; - - -/***/ }), -/* 1431 */ -/***/ (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__(29); -var HexagonalTileToWorldXY = __webpack_require__(550); -var IsometricTileToWorldXY = __webpack_require__(551); -var NOOP = __webpack_require__(1); -var StaggeredTileToWorldXY = __webpack_require__(552); -var TileToWorldXY = __webpack_require__(553); - -/** - * Gets the correct function to use to translate tiles, based on the map orientation. - * - * @function Phaser.Tilemaps.Components.GetTileToWorldXYFunction - * @since 3.50.0 - * - * @param {number} orientation - The Tilemap orientation constant. - * - * @return {function} The function to use to translate tiles for the given map type. - */ -var GetTileToWorldXYFunction = function (orientation) -{ - if (orientation === CONST.ORTHOGONAL) - { - return TileToWorldXY; - } - else if (orientation === CONST.ISOMETRIC) - { - return IsometricTileToWorldXY; - } - else if (orientation === CONST.HEXAGONAL) - { - return HexagonalTileToWorldXY; - } - else if (orientation === CONST.STAGGERED) - { - return StaggeredTileToWorldXY; - } - else + else if (typeof ease === 'function') { - return NOOP; + // Custom function + easeFunction = ease; } -}; - -module.exports = GetTileToWorldXYFunction; - - -/***/ }), -/* 1432 */ -/***/ (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__(29); -var HexagonalTileToWorldY = __webpack_require__(554); -var NOOP = __webpack_require__(1); -var StaggeredTileToWorldY = __webpack_require__(555); -var TileToWorldY = __webpack_require__(254); - -/** - * Gets the correct function to use to translate tiles, based on the map orientation. - * - * @function Phaser.Tilemaps.Components.GetTileToWorldYFunction - * @since 3.50.0 - * - * @param {number} orientation - The Tilemap orientation constant. - * - * @return {function} The function to use to translate tiles for the given map type. - */ -var GetTileToWorldYFunction = function (orientation) -{ - if (orientation === CONST.ORTHOGONAL) - { - return TileToWorldY; - } - else if (orientation === CONST.HEXAGONAL) - { - return HexagonalTileToWorldY; - } - else if (orientation === CONST.STAGGERED) - { - return StaggeredTileToWorldY; - } - else + // No custom ease parameters? + if (!easeParams) { - return NOOP; + // Return ease function + return easeFunction; } -}; - -module.exports = GetTileToWorldYFunction; - - -/***/ }), -/* 1433 */ -/***/ (function(module, exports, __webpack_require__) { -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var cloneParams = easeParams.slice(0); -var CONST = __webpack_require__(29); -var NOOP = __webpack_require__(1); -var WorldToTileX = __webpack_require__(255); + cloneParams.unshift(0); -/** - * Gets the correct function to use to translate tiles, based on the map orientation. - * - * @function Phaser.Tilemaps.Components.GetWorldToTileXFunction - * @since 3.50.0 - * - * @param {number} orientation - The Tilemap orientation constant. - * - * @return {function} The function to use to translate tiles for the given map type. - */ -var GetWorldToTileXFunction = function (orientation) -{ - if (orientation === CONST.ORTHOGONAL) - { - return WorldToTileX; - } - else - { - return NOOP; - } + // Return ease function with custom ease parameters + return function (v) + { + cloneParams[0] = v; + + return easeFunction.apply(this, cloneParams); + }; }; -module.exports = GetWorldToTileXFunction; +module.exports = GetEaseFunction; /***/ }), -/* 1434 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 4840: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(29); -var HexagonalWorldToTileXY = __webpack_require__(556); -var IsometricWorldToTileXY = __webpack_require__(557); -var NOOP = __webpack_require__(1); -var StaggeredWorldToTileXY = __webpack_require__(558); -var WorldToTileXY = __webpack_require__(559); +var Bezier = __webpack_require__(63210); +var CatmullRom = __webpack_require__(88332); +var Linear = __webpack_require__(47614); + +var FuncMap = { + bezier: Bezier, + catmull: CatmullRom, + catmullrom: CatmullRom, + linear: Linear +}; /** - * Gets the correct function to use to translate tiles, based on the map orientation. + * This internal function is used to return the correct interpolation function for a Tween. * - * @function Phaser.Tilemaps.Components.GetWorldToTileXYFunction - * @since 3.50.0 + * It can take a variety of input, including a string, or a custom function. * - * @param {number} orientation - The Tilemap orientation constant. + * @function Phaser.Tweens.Builders.GetInterpolationFunction + * @since 3.60.0 * - * @return {function} The function to use to translate tiles for the given map type. + * @param {(string|function|null)} interpolation - The interpolation function to find. This can be either a string, or a custom function, or null. + * + * @return {?function} The interpolation function to use, or `null`. */ -var GetWorldToTileXYFunction = function (orientation) +var GetInterpolationFunction = function (interpolation) { - if (orientation === CONST.ORTHOGONAL) - { - return WorldToTileXY; - } - else if (orientation === CONST.ISOMETRIC) - { - return IsometricWorldToTileXY; - } - else if (orientation === CONST.HEXAGONAL) + if (interpolation === null) { - return HexagonalWorldToTileXY; + return null; } - else if (orientation === CONST.STAGGERED) + + // Default interpolation function + var interpolationFunction = FuncMap.linear; + + // Prepare interpolation function + if (typeof interpolation === 'string') { - return StaggeredWorldToTileXY; + // String based look-up + + // 1) They specified it correctly + if (FuncMap.hasOwnProperty(interpolation)) + { + interpolationFunction = FuncMap[interpolation]; + } } - else + else if (typeof interpolation === 'function') { - return NOOP; + // Custom function + interpolationFunction = interpolation; } + + // Return interpolation function + return interpolationFunction; }; -module.exports = GetWorldToTileXYFunction; +module.exports = GetInterpolationFunction; /***/ }), -/* 1435 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 28348: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(29); -var HexagonalWorldToTileY = __webpack_require__(560); -var NOOP = __webpack_require__(1); -var StaggeredWorldToTileY = __webpack_require__(561); -var WorldToTileY = __webpack_require__(256); - /** - * Gets the correct function to use to translate tiles, based on the map orientation. + * Internal function used by the Tween Builder to create a function that will return + * the given value from the source. * - * @function Phaser.Tilemaps.Components.GetWorldToTileYFunction - * @since 3.50.0 + * @function Phaser.Tweens.Builders.GetNewValue + * @since 3.0.0 * - * @param {number} orientation - The Tilemap orientation constant. + * @param {any} source - The source object to get the value from. + * @param {string} key - The property to get from the source. + * @param {any} defaultValue - A default value to return should the source not have the property set. * - * @return {function} The function to use to translate tiles for the given map type. + * @return {function} A function which, when called, will return the property value from the source. */ -var GetWorldToTileYFunction = function (orientation) +var GetNewValue = function (source, key, defaultValue) { - if (orientation === CONST.ORTHOGONAL) - { - return WorldToTileY; - } - else if (orientation === CONST.HEXAGONAL) + var valueCallback; + + if (source.hasOwnProperty(key)) { - return HexagonalWorldToTileY; + var t = typeof(source[key]); + + if (t === 'function') + { + valueCallback = function (target, targetKey, value, targetIndex, totalTargets, tween) + { + return source[key](target, targetKey, value, targetIndex, totalTargets, tween); + }; + } + else + { + valueCallback = function () + { + return source[key]; + }; + } } - else if (orientation === CONST.STAGGERED) + else if (typeof defaultValue === 'function') { - return StaggeredWorldToTileY; + valueCallback = defaultValue; } else { - return NOOP; + valueCallback = function () + { + return defaultValue; + }; } + + return valueCallback; }; -module.exports = GetWorldToTileYFunction; +module.exports = GetNewValue; /***/ }), -/* 1436 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 92407: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var HasTileAt = __webpack_require__(562); -var Vector2 = __webpack_require__(3); - -var point = new Vector2(); +var RESERVED = __webpack_require__(53709); /** - * 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. + * 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.Tilemaps.Components.HasTileAtWorldXY + * @function Phaser.Tweens.Builders.GetProps * @since 3.0.0 * - * @param {number} worldX - The X coordinate of the world position. - * @param {number} worldY - The Y coordinate of the world position. - * @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. + * @param {Phaser.Types.Tweens.TweenBuilderConfig} config - The configuration object of the Tween to get the properties from. * - * @return {?boolean} Returns a boolean, or null if the layer given was invalid. + * @return {string[]} An array of all the properties the tween will operate on. */ -var HasTileAtWorldXY = function (worldX, worldY, camera, layer) +var GetProps = function (config) { - layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera); + var key; + var keys = []; - var tileX = point.x; - var tileY = point.y; + // First see if we have a props object - return HasTileAt(tileX, tileY, layer); + if (config.hasOwnProperty('props')) + { + for (key in config.props) + { + // Skip any property that starts with an underscore + if (key.substring(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.substring(0, 1) !== '_') + { + keys.push({ key: key, value: config[key] }); + } + } + } + + return keys; }; -module.exports = HasTileAtWorldXY; +module.exports = GetProps; /***/ }), -/* 1437 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 65868: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var PutTileAt = __webpack_require__(257); -var Vector2 = __webpack_require__(3); - -var point = new Vector2(); +var GetValue = __webpack_require__(10850); /** - * 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. + * Extracts an array of targets from a Tween configuration object. * - * @function Phaser.Tilemaps.Components.PutTileAtWorldXY + * The targets will be looked for in a `targets` property. If it's a function, its return value will be used as the result. + * + * @function Phaser.Tweens.Builders.GetTargets * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {object} config - The configuration object to use. * - * @return {Phaser.Tilemaps.Tile} The Tile object that was created or added to this map. + * @return {array} An array of targets (may contain only one element), or `null` if no targets were specified. */ -var PutTileAtWorldXY = function (tile, worldX, worldY, recalculateFaces, camera, layer) +var GetTargets = function (config) { - layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera, layer); + var targets = GetValue(config, 'targets', null); - return PutTileAt(tile, point.x, point.y, recalculateFaces, layer); + if (targets === null) + { + return targets; + } + + if (typeof targets === 'function') + { + targets = targets.call(); + } + + if (!Array.isArray(targets)) + { + targets = [ targets ]; + } + + return targets; }; -module.exports = PutTileAtWorldXY; +module.exports = GetTargets; /***/ }), -/* 1438 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 9744: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CalculateFacesWithin = __webpack_require__(63); -var PutTileAt = __webpack_require__(257); +var Between = __webpack_require__(17489); +var FloatBetween = __webpack_require__(61616); /** - * 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. + * @ignore + */ +function hasGetActive (def) +{ + return (!!def.getActive && typeof def.getActive === 'function'); +} + +/** + * @ignore + */ +function hasGetStart (def) +{ + return (!!def.getStart && typeof def.getStart === 'function'); +} + +/** + * @ignore + */ +function hasGetEnd (def) +{ + return (!!def.getEnd && typeof def.getEnd === 'function'); +} + +/** + * @ignore + */ +function hasGetters (def) +{ + return hasGetStart(def) || hasGetEnd(def) || hasGetActive(def); +} + +/** + * Returns `getActive`, `getStart` and `getEnd` functions for a TweenData based on a target property and end value. * - * @function Phaser.Tilemaps.Components.PutTilesAt + * `getActive` if not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. + * `getEnd` is invoked once any start delays have expired and returns what the value should tween to. + * `getStart` is invoked when the tween reaches the end and needs to either repeat or yoyo, it returns the value to go back to. + * + * If the end value is a number, it will be treated as an absolute value and the property will be tweened to it. + * A string can be provided to specify a relative end value which consists of an operation + * (`+=` to add to the current value, `-=` to subtract from the current value, `*=` to multiply the current + * value, or `/=` to divide the current value) followed by its operand. + * + * A function can be provided to allow greater control over the end value; it will receive the target + * object being tweened, the name of the property being tweened, and the current value of the property + * as its arguments and must return a value. + * + * If both the starting and the ending values need to be controlled, an object with `getStart` and `getEnd` + * callbacks, which will receive the same arguments, can be provided instead. If an object with a `value` + * property is provided, the property will be used as the effective value under the same rules described here. + * + * @function Phaser.Tweens.Builders.GetValueOp * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {string} key - The name of the property to modify. + * @param {*} propertyValue - The ending value of the property, as described above. + * + * @return {function} An array of functions, `getActive`, `getStart` and `getEnd`, which return the starting and the ending value of the property based on the provided value. */ -var PutTilesAt = function (tilesArray, tileX, tileY, recalculateFaces, layer) +var GetValueOp = function (key, propertyValue) { - if (recalculateFaces === undefined) { recalculateFaces = true; } + var callbacks; - if (!Array.isArray(tilesArray)) - { - return null; - } + // The returned value sets what the property will be at the END of the Tween (usually called at the start of the Tween) + var getEnd = function (target, key, value) { return value; }; - // Force the input array to be a 2D array - if (!Array.isArray(tilesArray[0])) + // The returned value sets what the property will be at the START of the Tween (usually called at the end of the Tween) + var getStart = function (target, key, value) { return value; }; + + // What to set the property to the moment the TweenData is invoked + var getActive = null; + + var t = typeof(propertyValue); + + if (t === 'number') { - tilesArray = [ tilesArray ]; + // props: { + // x: 400, + // y: 300 + // } + + getEnd = function () + { + return propertyValue; + }; } + else if (Array.isArray(propertyValue)) + { + // props: { + // x: [ 400, 300, 200 ], + // y: [ 10, 500, 10 ] + // } - var height = tilesArray.length; - var width = tilesArray[0].length; + getStart = function () + { + return propertyValue[0]; + }; - for (var ty = 0; ty < height; ty++) + getEnd = function () + { + return propertyValue[propertyValue.length - 1]; + }; + } + else if (t === 'string') { - for (var tx = 0; tx < width; tx++) + // props: { + // x: '+=400', + // y: '-=300', + // z: '*=2', + // w: '/=2', + // p: 'random(10, 100)' - random float + // p: 'int(10, 100)' - random int + // } + + var op = propertyValue.toLowerCase(); + var isRandom = (op.substring(0, 6) === 'random'); + var isInt = (op.substring(0, 3) === 'int'); + + if (isRandom || isInt) { - var tile = tilesArray[ty][tx]; + // random(0.5, 3.45) + // int(10, 100) + var brace1 = op.indexOf('('); + var brace2 = op.indexOf(')'); + var comma = op.indexOf(','); - PutTileAt(tile, tileX + tx, tileY + ty, false, layer); + if (brace1 && brace2 && comma) + { + var value1 = parseFloat(op.substring(brace1 + 1, comma)); + var value2 = parseFloat(op.substring(comma + 1, brace2)); + + if (isRandom) + { + getEnd = function () + { + return FloatBetween(value1, value2); + }; + } + else + { + getEnd = function () + { + return Between(value1, value2); + }; + } + } + else + { + throw new Error('invalid random() format'); + } } - } + else + { + op = op[0]; + var num = parseFloat(propertyValue.substr(2)); - if (recalculateFaces) - { - // Recalculate the faces within the destination area and neighboring tiles - CalculateFacesWithin(tileX - 1, tileY - 1, width + 2, height + 2, layer); + switch (op) + { + case '+': + getEnd = function (target, key, value) + { + return value + num; + }; + break; + + case '-': + getEnd = function (target, key, value) + { + return value - num; + }; + break; + + case '*': + getEnd = function (target, key, value) + { + return value * num; + }; + break; + + case '/': + getEnd = function (target, key, value) + { + return value / num; + }; + break; + + default: + getEnd = function () + { + return parseFloat(propertyValue); + }; + } + } } -}; + else if (t === 'function') + { + // The same as setting just the getEnd function and no getStart -module.exports = PutTilesAt; + // props: { + // x: function (target, key, value, targetIndex, totalTargets, tween, tweenData) { return value + 50); }, + // } + getEnd = propertyValue; + } + else if (t === 'object') + { + if (hasGetters(propertyValue)) + { + /* + x: { + // Called the moment Tween is active. The returned value sets the property on the target immediately. + getActive: function (target, key, value, targetIndex, totalTargets, tween, tweenData) + { + return value; + }, -/***/ }), -/* 1439 */ -/***/ (function(module, exports, __webpack_require__) { + // Called at the start of the Tween. The returned value sets what the property will be at the END of the Tween. + getEnd: function (target, key, value, targetIndex, totalTargets, tween, tweenData) + { + return value; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + // Called at the end of the Tween. The returned value sets what the property will be at the START of the Tween. + getStart: function (target, key, value, targetIndex, totalTargets, tween, tweenData) + { + return value; + } + } + */ -var GetTilesWithin = __webpack_require__(26); -var GetRandom = __webpack_require__(210); + if (hasGetActive(propertyValue)) + { + getActive = propertyValue.getActive; + } -/** - * 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. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - */ -var Randomize = function (tileX, tileY, width, height, indexes, layer) -{ - var i; - var tiles = GetTilesWithin(tileX, tileY, width, height, {}, layer); + if (hasGetEnd(propertyValue)) + { + getEnd = propertyValue.getEnd; + } - // If no indices are given, then find all the unique indexes within the specified region - if (!indexes) - { - indexes = []; + if (hasGetStart(propertyValue)) + { + getStart = propertyValue.getStart; + } + } + else if (propertyValue.hasOwnProperty('value')) + { + // 'value' may still be a string, function or a number + // props: { + // x: { value: 400, ... }, + // y: { value: 300, ... } + // } - for (i = 0; i < tiles.length; i++) + callbacks = GetValueOp(key, propertyValue.value); + } + else { - if (indexes.indexOf(tiles[i].index) === -1) + // 'from' and 'to' may still be a string, function or a number + // props: { + // x: { from: 400, to: 600 }, + // y: { from: 300, to: 500 } + // } + + // Same as above, but the 'start' value is set immediately on the target + // props: { + // x: { start: 400, to: 600 }, + // y: { start: 300, to: 500 } + // } + + // 'start' value is set immediately, then it goes 'from' to 'to' during the tween + // props: { + // x: { start: 200, from: 400, to: 600 }, + // y: { start: 300, from: 300, to: 500 } + // } + + var hasTo = propertyValue.hasOwnProperty('to'); + var hasFrom = propertyValue.hasOwnProperty('from'); + var hasStart = propertyValue.hasOwnProperty('start'); + + if (hasTo && (hasFrom || hasStart)) { - indexes.push(tiles[i].index); + callbacks = GetValueOp(key, propertyValue.to); + + if (hasStart) + { + var startCallbacks = GetValueOp(key, propertyValue.start); + + callbacks.getActive = startCallbacks.getEnd; + } + + if (hasFrom) + { + var fromCallbacks = GetValueOp(key, propertyValue.from); + + callbacks.getStart = fromCallbacks.getEnd; + } } } } - for (i = 0; i < tiles.length; i++) + // If callback not set by the else if block above then set it here and return it + if (!callbacks) { - tiles[i].index = GetRandom(indexes); + callbacks = { + getActive: getActive, + getEnd: getEnd, + getStart: getStart + }; } + + return callbacks; }; -module.exports = Randomize; +module.exports = GetValueOp; /***/ }), -/* 1440 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 68710: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var RemoveTileAt = __webpack_require__(563); -var Vector2 = __webpack_require__(3); - -var point = new Vector2(); +var BaseTween = __webpack_require__(502); +var Defaults = __webpack_require__(99730); +var GetAdvancedValue = __webpack_require__(20494); +var GetBoolean = __webpack_require__(63130); +var GetEaseFunction = __webpack_require__(21902); +var GetNewValue = __webpack_require__(28348); +var GetValue = __webpack_require__(10850); +var GetValueOp = __webpack_require__(9744); +var MergeRight = __webpack_require__(72066); +var Tween = __webpack_require__(39366); /** - * Removes the tile at the given world coordinates in the specified layer and updates the layer's - * collision information. + * Creates a new Number Tween. * - * @function Phaser.Tilemaps.Components.RemoveTileAtWorldXY + * @function Phaser.Tweens.Builders.NumberTweenBuilder * @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, 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.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. + * @param {Phaser.Tweens.TweenManager} 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.Tilemaps.Tile} The Tile object that was removed. + * @return {Phaser.Tweens.Tween} The new tween. */ -var RemoveTileAtWorldXY = function (worldX, worldY, replaceWithNull, recalculateFaces, camera, layer) +var NumberTweenBuilder = function (parent, config, defaults) { - layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera, layer); - - return RemoveTileAt(point.x, point.y, replaceWithNull, recalculateFaces, layer); -}; + if (config instanceof Tween) + { + config.parent = parent; -module.exports = RemoveTileAtWorldXY; + return config; + } + if (defaults === undefined) + { + defaults = Defaults; + } + else + { + defaults = MergeRight(Defaults, defaults); + } -/***/ }), -/* 1441 */ -/***/ (function(module, exports, __webpack_require__) { + // var tween = this.tweens.addCounter({ + // from: 100, + // to: 200, + // ... (normal tween properties) + // }) + // + // Then use it in your game via: + // + // tween.getValue() -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var from = GetValue(config, 'from', 0); + var to = GetValue(config, 'to', 1); -var GetTilesWithin = __webpack_require__(26); -var Color = __webpack_require__(397); + var targets = [ { value: from } ]; -var defaultTileColor = new Color(105, 210, 231, 150); -var defaultCollidingTileColor = new Color(243, 134, 48, 200); -var defaultFaceColor = new Color(40, 39, 37, 150); + var delay = GetValue(config, 'delay', defaults.delay); + var easeParams = GetValue(config, 'easeParams', defaults.easeParams); + var ease = GetValue(config, 'ease', defaults.ease); -/** - * 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. - * - * @function Phaser.Tilemaps.Components.RenderDebug - * @since 3.0.0 - * - * @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon. - * @param {Phaser.Types.Tilemaps.DebugStyleOptions} styleConfig - An object specifying the colors to use for the debug drawing. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - */ -var RenderDebug = function (graphics, styleConfig, layer) -{ - if (styleConfig === undefined) { styleConfig = {}; } + var ops = GetValueOp('value', to); - // Default colors without needlessly creating Color objects - var tileColor = (styleConfig.tileColor !== undefined) ? styleConfig.tileColor : defaultTileColor; - var collidingTileColor = (styleConfig.collidingTileColor !== undefined) ? styleConfig.collidingTileColor : defaultCollidingTileColor; - var faceColor = (styleConfig.faceColor !== undefined) ? styleConfig.faceColor : defaultFaceColor; + var tween = new Tween(parent, targets); - var tiles = GetTilesWithin(0, 0, layer.width, layer.height, null, layer); + var tweenData = tween.add( + 0, + 'value', + ops.getEnd, + ops.getStart, + ops.getActive, + GetEaseFunction(GetValue(config, 'ease', ease), GetValue(config, 'easeParams', easeParams)), + GetNewValue(config, 'delay', delay), + GetValue(config, 'duration', defaults.duration), + GetBoolean(config, 'yoyo', defaults.yoyo), + GetValue(config, 'hold', defaults.hold), + GetValue(config, 'repeat', defaults.repeat), + GetValue(config, 'repeatDelay', defaults.repeatDelay), + false, + false + ); - graphics.translateCanvas(layer.tilemapLayer.x, layer.tilemapLayer.y); - graphics.scaleCanvas(layer.tilemapLayer.scaleX, layer.tilemapLayer.scaleY); + tweenData.start = from; + tweenData.current = from; - for (var i = 0; i < tiles.length; i++) - { - var tile = tiles[i]; + 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.persist = GetBoolean(config, 'persist', false); - var tw = tile.width; - var th = tile.height; - var x = tile.pixelX; - var y = tile.pixelY; + // Set the Callbacks + tween.callbackScope = GetValue(config, 'callbackScope', tween); - var color = tile.collides ? collidingTileColor : tileColor; + var callbacks = BaseTween.TYPES; - if (color !== null) - { - graphics.fillStyle(color.color, color.alpha / 255); - graphics.fillRect(x, y, tw, th); - } + for (var i = 0; i < callbacks.length; i++) + { + var type = callbacks[i]; - // Inset the face line to prevent neighboring tile's lines from overlapping - x += 1; - y += 1; - tw -= 2; - th -= 2; + var callback = GetValue(config, type, false); - if (faceColor !== null) + if (callback) { - graphics.lineStyle(1, faceColor.color, faceColor.alpha / 255); + var callbackParams = GetValue(config, type + 'Params', []); - if (tile.faceTop) { graphics.lineBetween(x, y, x + tw, y); } - if (tile.faceRight) { graphics.lineBetween(x + tw, y, x + tw, y + th); } - if (tile.faceBottom) { graphics.lineBetween(x, y + th, x + tw, y + th); } - if (tile.faceLeft) { graphics.lineBetween(x, y, x, y + th); } + tween.setCallback(type, callback, callbackParams); } } + + return tween; }; -module.exports = RenderDebug; +module.exports = NumberTweenBuilder; /***/ }), -/* 1442 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 91944: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(72); -var CalculateFacesWithin = __webpack_require__(63); -var SetLayerCollisionIndex = __webpack_require__(160); +var GetEaseFunction = __webpack_require__(21902); +var GetValue = __webpack_require__(10850); +var MATH_CONST = __webpack_require__(83392); /** - * 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). + * Creates a Stagger function to be used by a Tween property. * - * @function Phaser.Tilemaps.Components.SetCollision - * @since 3.0.0 + * The stagger function will allow you to stagger changes to the value of the property across all targets of the tween. * - * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @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. + * 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 SetCollision = function (indexes, collides, recalculateFaces, layer, updateLayer) +var StaggerBuilder = function (value, options) { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - if (updateLayer === undefined) { updateLayer = true; } + if (options === undefined) { options = {}; } - if (!Array.isArray(indexes)) - { - indexes = [ indexes ]; - } + var result; - // Update the array of colliding indexes - for (var i = 0; i < indexes.length; i++) + 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) { - SetLayerCollisionIndex(indexes[i], collides, layer); + start += value1; } - // Update the tiles - if (updateLayer) + if (grid) { - for (var ty = 0; ty < layer.height; ty++) + // Pre-calc the grid to save doing it for every 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) { - for (var tx = 0; tx < layer.width; tx++) + 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++) { - var tile = layer.data[ty][tx]; + distanceX = fromX - toX; + distanceY = fromY - toY; - if (tile && indexes.indexOf(tile.index) !== -1) + var dist = Math.sqrt(distanceX * distanceX + distanceY * distanceY); + + if (dist > gridMax) { - SetTileCollision(tile, collides); + gridMax = dist; } + + gridValues[toY][toX] = dist; } } } - if (recalculateFaces) + var easeFunction = (ease) ? GetEaseFunction(ease) : null; + + if (grid) { - CalculateFacesWithin(0, 0, layer.width, layer.height, layer); + 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 = SetCollision; +module.exports = StaggerBuilder; /***/ }), -/* 1443 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 68061: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(72); -var CalculateFacesWithin = __webpack_require__(63); -var SetLayerCollisionIndex = __webpack_require__(160); +var BaseTween = __webpack_require__(502); +var Defaults = __webpack_require__(99730); +var GetAdvancedValue = __webpack_require__(20494); +var GetBoolean = __webpack_require__(63130); +var GetEaseFunction = __webpack_require__(21902); +var GetInterpolationFunction = __webpack_require__(4840); +var GetNewValue = __webpack_require__(28348); +var GetProps = __webpack_require__(92407); +var GetTargets = __webpack_require__(65868); +var GetValue = __webpack_require__(10850); +var GetValueOp = __webpack_require__(9744); +var MergeRight = __webpack_require__(72066); +var Tween = __webpack_require__(39366); /** - * 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). + * Creates a new Tween. * - * @function Phaser.Tilemaps.Components.SetCollisionBetween + * @function Phaser.Tweens.Builders.TweenBuilder * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. - * @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. + * @param {Phaser.Tweens.TweenManager} parent - The owner of the new Tween. + * @param {Phaser.Types.Tweens.TweenBuilderConfig|object} config - Configuration for the new Tween. + * @param {Phaser.Types.Tweens.TweenConfigDefaults} defaults - Tween configuration defaults. + * + * @return {Phaser.Tweens.Tween} The new tween. */ -var SetCollisionBetween = function (start, stop, collides, recalculateFaces, layer, updateLayer) +var TweenBuilder = function (parent, config, defaults) { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - if (updateLayer === undefined) { updateLayer = true; } + if (config instanceof Tween) + { + config.parent = parent; - if (start > stop) + return config; + } + + if (defaults === undefined) { - return; + defaults = Defaults; + } + else + { + defaults = MergeRight(Defaults, defaults); } - // Update the array of colliding indexes - for (var index = start; index <= stop; index++) + // Create arrays of the Targets and the Properties + var targets = GetTargets(config); + + if (!targets && defaults.targets) { - SetLayerCollisionIndex(index, collides, layer); + targets = defaults.targets; } - // Update the tiles - if (updateLayer) + var props = GetProps(config); + + // Default Tween values + + var delay = GetValue(config, 'delay', defaults.delay); + var duration = GetValue(config, 'duration', defaults.duration); + var easeParams = GetValue(config, 'easeParams', defaults.easeParams); + var ease = GetValue(config, 'ease', defaults.ease); + var hold = GetValue(config, 'hold', defaults.hold); + var repeat = GetValue(config, 'repeat', defaults.repeat); + var repeatDelay = GetValue(config, 'repeatDelay', defaults.repeatDelay); + var yoyo = GetBoolean(config, 'yoyo', defaults.yoyo); + var flipX = GetBoolean(config, 'flipX', defaults.flipX); + var flipY = GetBoolean(config, 'flipY', defaults.flipY); + var interpolation = GetValue(config, 'interpolation', defaults.interpolation); + + var addTarget = function (tween, targetIndex, key, value) { - for (var ty = 0; ty < layer.height; ty++) + if (key === 'texture') { - for (var tx = 0; tx < layer.width; tx++) + var texture = value; + var frame = undefined; + + if (Array.isArray(value)) { - var tile = layer.data[ty][tx]; + texture = value[0]; + frame = value[1]; + } + else if (value.hasOwnProperty('value')) + { + texture = value.value; - if (tile) + if (Array.isArray(value.value)) { - if (tile.index >= start && tile.index <= stop) - { - SetTileCollision(tile, collides); - } + texture = value.value[0]; + frame = value.value[1]; } + else if (typeof value.value === 'string') + { + texture = value.value; + } + } + else if (typeof value === 'string') + { + texture = value; + } + + tween.addFrame( + targetIndex, + texture, + frame, + GetNewValue(value, 'delay', delay), + GetValue(value, 'duration', duration), + GetValue(value, 'hold', hold), + GetValue(value, 'repeat', repeat), + GetValue(value, 'repeatDelay', repeatDelay), + GetBoolean(value, 'flipX', flipX), + GetBoolean(value, 'flipY', flipY) + ); + } + else + { + var ops = GetValueOp(key, value); + + var interpolationFunc = GetInterpolationFunction(GetValue(value, 'interpolation', interpolation)); + + tween.add( + targetIndex, + key, + ops.getEnd, + ops.getStart, + ops.getActive, + GetEaseFunction(GetValue(value, 'ease', ease), GetValue(value, 'easeParams', easeParams)), + GetNewValue(value, 'delay', delay), + GetValue(value, 'duration', duration), + GetBoolean(value, 'yoyo', yoyo), + GetValue(value, 'hold', hold), + GetValue(value, 'repeat', repeat), + GetValue(value, 'repeatDelay', repeatDelay), + GetBoolean(value, 'flipX', flipX), + GetBoolean(value, 'flipY', flipY), + interpolationFunc, + (interpolationFunc) ? value : null + ); + } + }; + + var tween = new Tween(parent, targets); + + // Loop through every property defined in the Tween, i.e.: props { x, y, alpha } + for (var p = 0; p < props.length; p++) + { + var key = props[p].key; + var value = props[p].value; + + // Create 1 TweenData per target, per property + for (var targetIndex = 0; targetIndex < targets.length; targetIndex++) + { + // Special-case for scale short-cut: + if (key === 'scale' && !targets[targetIndex].hasOwnProperty('scale')) + { + addTarget(tween, targetIndex, 'scaleX', value); + addTarget(tween, targetIndex, 'scaleY', value); + } + else + { + addTarget(tween, targetIndex, key, value); } } } - if (recalculateFaces) + 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.persist = GetBoolean(config, 'persist', false); + + // Set the Callbacks + tween.callbackScope = GetValue(config, 'callbackScope', tween); + + var callbacks = BaseTween.TYPES; + + for (var i = 0; i < callbacks.length; i++) { - CalculateFacesWithin(0, 0, layer.width, layer.height, layer); + var type = callbacks[i]; + + var callback = GetValue(config, type, false); + + if (callback) + { + var callbackParams = GetValue(config, type + 'Params', []); + + tween.setCallback(type, callback, callbackParams); + } } + + return tween; }; -module.exports = SetCollisionBetween; +module.exports = TweenBuilder; /***/ }), -/* 1444 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 56034: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(72); -var CalculateFacesWithin = __webpack_require__(63); -var SetLayerCollisionIndex = __webpack_require__(160); +var BaseTween = __webpack_require__(502); +var GetAdvancedValue = __webpack_require__(20494); +var GetBoolean = __webpack_require__(63130); +var GetTargets = __webpack_require__(65868); +var GetValue = __webpack_require__(10850); +var TweenBuilder = __webpack_require__(68061); +var TweenChain = __webpack_require__(45641); /** - * 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. + * Creates a new Tween Chain instance. * - * @function Phaser.Tilemaps.Components.SetCollisionByExclusion - * @since 3.0.0 + * @function Phaser.Tweens.Builders.TweenChainBuilder + * @since 3.60.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @param {Phaser.Tweens.TweenManager} parent - The owner of the new Tween. + * @param {Phaser.Types.Tweens.TweenChainBuilderConfig|object} config - Configuration for the new Tween. + * + * @return {Phaser.Tweens.TweenChain} The new Tween Chain. */ -var SetCollisionByExclusion = function (indexes, collides, recalculateFaces, layer) +var TweenChainBuilder = function (parent, config) { - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - if (!Array.isArray(indexes)) + if (config instanceof TweenChain) { - indexes = [ indexes ]; + config.parent = parent; + + return config; } - // Note: this only updates layer.collideIndexes for tile indexes found currently in the layer - for (var ty = 0; ty < layer.height; ty++) + // Default TweenChain values + + var chain = new TweenChain(parent); + + chain.startDelay = GetValue(config, 'delay', 0); + chain.completeDelay = GetAdvancedValue(config, 'completeDelay', 0); + chain.loop = Math.round(GetAdvancedValue(config, 'loop', GetValue(config, 'repeat', 0))); + chain.loopDelay = Math.round(GetAdvancedValue(config, 'loopDelay', GetValue(config, 'repeatDelay', 0))); + chain.paused = GetBoolean(config, 'paused', false); + chain.persist = GetBoolean(config, 'persist', true); + + // Set the Callbacks + chain.callbackScope = GetValue(config, 'callbackScope', chain); + + var i; + var callbacks = BaseTween.TYPES; + + for (i = 0; i < callbacks.length; i++) { - for (var tx = 0; tx < layer.width; tx++) + var type = callbacks[i]; + + var callback = GetValue(config, type, false); + + if (callback) { - var tile = layer.data[ty][tx]; + var callbackParams = GetValue(config, type + 'Params', []); - if (tile && indexes.indexOf(tile.index) === -1) - { - SetTileCollision(tile, collides); - SetLayerCollisionIndex(tile.index, collides, layer); - } + chain.setCallback(type, callback, callbackParams); } } - if (recalculateFaces) + // Add in the Tweens + var tweens = GetValue(config, 'tweens', null); + + if (Array.isArray(tweens)) { - CalculateFacesWithin(0, 0, layer.width, layer.height, layer); + var chainedTweens = []; + + var targets = GetTargets(config); + var defaults = undefined; + + if (targets) + { + defaults = { targets: targets }; + } + + for (i = 0; i < tweens.length; i++) + { + chainedTweens.push(TweenBuilder(chain, tweens[i], defaults)); + } + + chain.add(chainedTweens); } + + return chain; }; -module.exports = SetCollisionByExclusion; +module.exports = TweenChainBuilder; /***/ }), -/* 1445 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 79619: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(72); -var CalculateFacesWithin = __webpack_require__(63); -var HasValue = __webpack_require__(126); - /** - * 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. - * - * @function Phaser.Tilemaps.Components.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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * @namespace Phaser.Tweens.Builders */ -var SetCollisionByProperty = function (properties, collides, recalculateFaces, layer) -{ - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - for (var ty = 0; ty < layer.height; ty++) - { - for (var tx = 0; tx < layer.width; tx++) - { - var tile = layer.data[ty][tx]; +module.exports = { - if (!tile) { continue; } + GetBoolean: __webpack_require__(63130), + GetEaseFunction: __webpack_require__(21902), + GetInterpolationFunction: __webpack_require__(4840), + GetNewValue: __webpack_require__(28348), + GetProps: __webpack_require__(92407), + GetTargets: __webpack_require__(65868), + GetValueOp: __webpack_require__(9744), + NumberTweenBuilder: __webpack_require__(68710), + StaggerBuilder: __webpack_require__(91944), + TweenBuilder: __webpack_require__(68061) - for (var property in properties) - { - if (!HasValue(tile.properties, property)) { continue; } +}; - var values = properties[property]; - if (!Array.isArray(values)) - { - values = [ values ]; - } +/***/ }), - for (var i = 0; i < values.length; i++) - { - if (tile.properties[property] === values[i]) - { - SetTileCollision(tile, collides); - } - } - } - } - } +/***/ 5570: +/***/ ((module) => { - if (recalculateFaces) - { - CalculateFacesWithin(0, 0, layer.width, layer.height, layer); - } -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = SetCollisionByProperty; +/** + * The Tween Active Event. + * + * This event is dispatched by a Tween when it becomes active within the Tween Manager. + * + * An 'active' Tween is one that is now progressing, although it may not yet be updating + * any target properties, due to settings such as `delay`. If you need an event for when + * the Tween starts actually updating its first property, see `TWEEN_START`. + * + * Listen to it from a Tween instance using `Tween.on('active', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.create({ + * targets: image, + * x: 500, + * ease: 'Power1', + * duration: 3000 + * }); + * tween.on('active', listener); + * this.tweens.existing(tween); + * ``` + * + * Note that this event is usually dispatched already by the time you call `this.tweens.add()`, and is + * meant for use with `tweens.create()` and/or `tweens.existing()`. + * + * @event Phaser.Tweens.Events#TWEEN_ACTIVE + * @type {string} + * @since 3.19.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. + * @param {(any|any[])} targets - The targets of the Tween. If this Tween has multiple targets this will be an array of the targets. + */ +module.exports = 'active'; /***/ }), -/* 1446 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 6383: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var SetTileCollision = __webpack_require__(72); -var CalculateFacesWithin = __webpack_require__(63); - /** - * Sets collision on the tiles within a layer by checking each tile's collision group data - * (typically defined in Tiled within the tileset collision editor). If any objects are found within - * a tile's collision group, the tile's colliding information will be set. The `collides` parameter - * controls if collision will be enabled (true) or disabled (false). + * The Tween Complete Event. * - * @function Phaser.Tilemaps.Components.SetCollisionFromCollisionGroup - * @since 3.0.0 + * This event is dispatched by a Tween when it completes playback entirely, factoring in repeats and loops. * - * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * If the Tween has been set to loop or repeat infinitely, this event will not be dispatched + * unless the `Tween.stop` method is called. + * + * If a Tween has a `completeDelay` set, this event will fire after that delay expires. + * + * Listen to it from a Tween instance using `Tween.on('complete', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * x: 500, + * ease: 'Power1', + * duration: 3000 + * }); + * tween.on('complete', listener); + * ``` + * + * @event Phaser.Tweens.Events#TWEEN_COMPLETE + * @type {string} + * @since 3.19.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. + * @param {(any|any[])} targets - The targets of the Tween. If this Tween has multiple targets this will be an array of the targets. */ -var SetCollisionFromCollisionGroup = function (collides, recalculateFaces, layer) -{ - if (collides === undefined) { collides = true; } - if (recalculateFaces === undefined) { recalculateFaces = true; } - - for (var ty = 0; ty < layer.height; ty++) - { - for (var tx = 0; tx < layer.width; tx++) - { - var tile = layer.data[ty][tx]; +module.exports = 'complete'; - if (!tile) { continue; } - var collisionGroup = tile.getCollisionGroup(); +/***/ }), - // It's possible in Tiled to have a collision group without any shapes, e.g. create a - // shape and then delete the shape. - if (collisionGroup && collisionGroup.objects && collisionGroup.objects.length > 0) - { - SetTileCollision(tile, collides); - } - } - } +/***/ 72582: +/***/ ((module) => { - if (recalculateFaces) - { - CalculateFacesWithin(0, 0, layer.width, layer.height, layer); - } -}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = SetCollisionFromCollisionGroup; +/** + * The Tween Loop Event. + * + * This event is dispatched by a Tween when it loops. + * + * This event will only be dispatched if the Tween has a loop count set. + * + * If a Tween has a `loopDelay` set, this event will fire after that delay expires. + * + * The difference between `loop` and `repeat` is that `repeat` is a property setting, + * where-as `loop` applies to the entire Tween. + * + * Listen to it from a Tween instance using `Tween.on('loop', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * x: 500, + * ease: 'Power1', + * duration: 3000, + * loop: 6 + * }); + * tween.on('loop', listener); + * ``` + * + * @event Phaser.Tweens.Events#TWEEN_LOOP + * @type {string} + * @since 3.19.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. + * @param {(any|any[])} targets - The targets of the Tween. If this Tween has multiple targets this will be an array of the targets. + */ +module.exports = 'loop'; /***/ }), -/* 1447 */ -/***/ (function(module, exports) { + +/***/ 90281: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * 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. + * The Tween Pause Event. * - * @function Phaser.Tilemaps.Components.SetTileIndexCallback - * @since 3.0.0 + * This event is dispatched by a Tween when it is paused. * - * @param {(number|array)} 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. - * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * Listen to it from a Tween instance using `Tween.on('pause', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * ease: 'Power1', + * duration: 3000, + * x: 600 + * }); + * tween.on('pause', listener); + * // At some point later ... + * tween.pause(); + * ``` + * + * @event Phaser.Tweens.Events#TWEEN_PAUSE + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. */ -var SetTileIndexCallback = function (indexes, callback, callbackContext, layer) -{ - if (typeof indexes === 'number') - { - layer.callbacks[indexes] = (callback !== null) - ? { callback: callback, callbackContext: callbackContext } - : undefined; - } - else - { - for (var i = 0, len = indexes.length; i < len; i++) - { - layer.callbacks[indexes[i]] = (callback !== null) - ? { callback: callback, callbackContext: callbackContext } - : undefined; - } - } -}; - -module.exports = SetTileIndexCallback; +module.exports = 'pause'; /***/ }), -/* 1448 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 80803: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetTilesWithin = __webpack_require__(26); - /** - * 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. + * The Tween Repeat Event. * - * @function Phaser.Tilemaps.Components.SetTileLocationCallback - * @since 3.0.0 + * This event is dispatched by a Tween when one of the properties it is tweening repeats. * - * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * This event will only be dispatched if the Tween has a property with a repeat count set. + * + * If a Tween has a `repeatDelay` set, this event will fire after that delay expires. + * + * The difference between `loop` and `repeat` is that `repeat` is a property setting, + * where-as `loop` applies to the entire Tween. + * + * Listen to it from a Tween instance using `Tween.on('repeat', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * x: 500, + * ease: 'Power1', + * duration: 3000, + * repeat: 4 + * }); + * tween.on('repeat', listener); + * ``` + * + * @event Phaser.Tweens.Events#TWEEN_REPEAT + * @type {string} + * @since 3.19.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. + * @param {string} key - The property on the target that has just repeated, i.e. `x` or `scaleY`, or whatever property you are tweening. + * @param {any} target - The target object that was repeated. Usually a Game Object, but can be of any type. + * @param {number} current - The current value of the property being set on the target. + * @param {number} previous - The previous value of the property being set on the target. */ -var SetTileLocationCallback = function (tileX, tileY, width, height, callback, callbackContext, layer) -{ - var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); +module.exports = 'repeat'; - for (var i = 0; i < tiles.length; i++) - { - tiles[i].setCollisionCallback(callback, callbackContext); - } -}; -module.exports = SetTileLocationCallback; +/***/ }), + +/***/ 13640: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Tween Resume Event. + * + * This event is dispatched by a Tween when it is resumed from a paused state. + * + * Listen to it from a Tween instance using `Tween.on('resume', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * ease: 'Power1', + * duration: 3000, + * x: 600 + * }); + * tween.on('resume', listener); + * // At some point later ... + * tween.resume(); + * ``` + * + * @event Phaser.Tweens.Events#TWEEN_RESUME + * @type {string} + * @since 3.60.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. + */ +module.exports = 'resume'; /***/ }), -/* 1449 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 10472: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetTilesWithin = __webpack_require__(26); -var ShuffleArray = __webpack_require__(131); - /** - * 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. + * The Tween Start Event. * - * @function Phaser.Tilemaps.Components.Shuffle - * @since 3.0.0 + * This event is dispatched by a Tween when it starts tweening its first property. * - * @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. + * A Tween will only emit this event once, as it can only start once. + * + * If a Tween has a `delay` set, this event will fire after that delay expires. + * + * Listen to it from a Tween instance using `Tween.on('start', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * x: 500, + * ease: 'Power1', + * duration: 3000 + * }); + * tween.on('start', listener); + * ``` + * + * @event Phaser.Tweens.Events#TWEEN_START + * @type {string} + * @since 3.19.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. + * @param {(any|any[])} targets - The targets of the Tween. If this Tween has multiple targets this will be an array of the targets. */ -var Shuffle = function (tileX, tileY, width, height, layer) -{ - var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); +module.exports = 'start'; - var indexes = tiles.map(function (tile) { return tile.index; }); - ShuffleArray(indexes); +/***/ }), - for (var i = 0; i < tiles.length; i++) - { - tiles[i].index = indexes[i]; - } -}; +/***/ 5379: +/***/ ((module) => { -module.exports = Shuffle; +/** + * @author samme + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * The Tween Stop Event. + * + * This event is dispatched by a Tween when it is stopped. + * + * Listen to it from a Tween instance using `Tween.on('stop', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * x: 500, + * ease: 'Power1', + * duration: 3000 + * }); + * tween.on('stop', listener); + * ``` + * + * @event Phaser.Tweens.Events#TWEEN_STOP + * @type {string} + * @since 3.24.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. + * @param {(any|any[])} targets - The targets of the Tween. If this Tween has multiple targets this will be an array of the targets. + */ +module.exports = 'stop'; /***/ }), -/* 1450 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 43449: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 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 - * `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision - * information. + * The Tween Update Event. * - * @function Phaser.Tilemaps.Components.SwapByIndex - * @since 3.0.0 + * This event is dispatched by a Tween every time it updates _any_ of the properties it is tweening. * - * @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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * A Tween that is changing 3 properties of a target will emit this event 3 times per change, once per property. + * + * **Note:** This is a very high frequency event and may be dispatched multiple times, every single frame. + * + * Listen to it from a Tween instance using `Tween.on('update', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * x: 500, + * ease: 'Power1', + * duration: 3000, + * }); + * tween.on('update', listener); + * ``` + * + * @event Phaser.Tweens.Events#TWEEN_UPDATE + * @type {string} + * @since 3.19.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. + * @param {string} key - The property on the target that has just updated, i.e. `x` or `scaleY`, or whatever property you are tweening. + * @param {any} target - The target object that was updated. Usually a Game Object, but can be of any type. + * @param {number} current - The current value of the property that was tweened. + * @param {number} previous - The previous value of the property that was tweened, prior to this update. */ -var SwapByIndex = function (indexA, indexB, 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]) - { - if (tiles[i].index === indexA) - { - tiles[i].index = indexB; - } - else if (tiles[i].index === indexB) - { - tiles[i].index = indexA; - } - } - } -}; - -module.exports = SwapByIndex; +module.exports = 'update'; /***/ }), -/* 1451 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 61541: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetTilesWithin = __webpack_require__(26); - /** - * 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: + * The Tween Yoyo Event. * - * [ - * { 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 - * ] + * This event is dispatched by a Tween whenever a property it is tweening yoyos. * - * 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. + * This event will only be dispatched if the Tween has a property with `yoyo` set. * - * @function Phaser.Tilemaps.Components.WeightedRandomize - * @since 3.0.0 + * If the Tween has a `hold` value, this event is dispatched when the hold expires. * - * @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 {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 {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * This event is dispatched for every property, and for every target, that yoyos. + * For example, if a Tween was updating 2 properties and had 10 targets, this event + * would be dispatched 20 times (twice per target). So be careful how you use it! + * + * Listen to it from a Tween instance using `Tween.on('yoyo', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * x: 500, + * ease: 'Power1', + * duration: 3000, + * yoyo: true + * }); + * tween.on('yoyo', listener); + * ``` + * + * @event Phaser.Tweens.Events#TWEEN_YOYO + * @type {string} + * @since 3.19.0 + * + * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. + * @param {string} key - The property on the target that has just yoyo'd, i.e. `x` or `scaleY`, or whatever property you are tweening. + * @param {any} target - The target object that was yoyo'd. Usually a Game Object, but can be of any type. + * @param {number} current - The current value of the property being set on the target. + * @param {number} previous - The previous value of the property being set on the target. */ -var WeightedRandomize = function (tileX, tileY, width, height, weightedIndexes, layer) -{ - if (!weightedIndexes) { return; } - - var i; - var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer); +module.exports = 'yoyo'; - var weightTotal = 0; - for (i = 0; i < weightedIndexes.length; i++) - { - weightTotal += weightedIndexes[i].weight; - } +/***/ }), - if (weightTotal <= 0) { return; } +/***/ 54272: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - for (i = 0; i < tiles.length; i++) - { - var rand = Math.random() * weightTotal; - var sum = 0; - var randomIndex = -1; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - for (var j = 0; j < weightedIndexes.length; j++) - { - sum += weightedIndexes[j].weight; +/** + * @namespace Phaser.Tweens.Events + */ - if (rand <= sum) - { - var chosen = weightedIndexes[j].index; +module.exports = { - randomIndex = Array.isArray(chosen) - ? chosen[Math.floor(Math.random() * chosen.length)] - : chosen; - break; - } - } + TWEEN_ACTIVE: __webpack_require__(5570), + TWEEN_COMPLETE: __webpack_require__(6383), + TWEEN_LOOP: __webpack_require__(72582), + TWEEN_PAUSE: __webpack_require__(90281), + TWEEN_RESUME: __webpack_require__(13640), + TWEEN_REPEAT: __webpack_require__(80803), + TWEEN_START: __webpack_require__(10472), + TWEEN_STOP: __webpack_require__(5379), + TWEEN_UPDATE: __webpack_require__(43449), + TWEEN_YOYO: __webpack_require__(61541) - tiles[i].index = randomIndex; - } }; -module.exports = WeightedRandomize; - /***/ }), -/* 1452 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 75193: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Tilemaps.Parsers + * @namespace Phaser.Tweens */ -module.exports = { +var Tweens = { - FromOrientationString: __webpack_require__(258), - Parse: __webpack_require__(564), - Parse2DArray: __webpack_require__(259), - ParseCSV: __webpack_require__(565), + States: __webpack_require__(55303), - Impact: __webpack_require__(1454), - Tiled: __webpack_require__(1455) + Builders: __webpack_require__(79619), + Events: __webpack_require__(54272), + TweenManager: __webpack_require__(64532), + Tween: __webpack_require__(39366), + TweenData: __webpack_require__(15718), + TweenFrameData: __webpack_require__(96490), + + BaseTween: __webpack_require__(502), + TweenChain: __webpack_require__(45641) }; +module.exports = Tweens; + /***/ }), -/* 1453 */ -/***/ (function(module, exports) { + +/***/ 502: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Class = __webpack_require__(56694); +var EventEmitter = __webpack_require__(6659); +var Events = __webpack_require__(54272); +var TWEEN_CONST = __webpack_require__(55303); + /** - * Parses out the Wangset information from Tiled 1.1.5+ map data, if present. - * - * Since a given tile can be in more than one wangset, the resulting properties - * are nested. `tile.data.wangid[someWangsetName]` will return the array-based wang id in - * this implementation. - * - * Note that we're not guaranteed that there will be any 'normal' tiles if the only - * thing in the tilset are wangtile definitions, so this has to be parsed separately. - * - * See https://doc.mapeditor.org/en/latest/manual/using-wang-tiles/ for more information. + * @classdesc + * As the name implies, this is the base Tween class that both the Tween and TweenChain + * inherit from. It contains shared properties and methods common to both types of Tween. * - * @function Phaser.Tilemaps.Parsers.Tiled.ParseWangsets - * @since 3.53.0 + * Typically you would never instantiate this class directly, although you could certainly + * use it to create your own variation of Tweens from. * - * @param {Array.} wangsets - The array of wangset objects (parsed from JSON) - * @param {object} datas - The field into which to put wangset data from Tiled. + * @class BaseTween + * @memberof Phaser.Tweens + * @extends Phaser.Events.EventEmitter + * @constructor + * @since 3.60.0 * - * @return {object} An object containing the tileset and image collection data. + * @param {(Phaser.Tweens.TweenManager|Phaser.Tweens.TweenChain)} parent - A reference to the Tween Manager, or Tween Chain, that owns this Tween. */ -var ParseWangsets = function (wangsets, datas) -{ - for (var w = 0; w < wangsets.length; w++) +var BaseTween = new Class({ + + Extends: EventEmitter, + + initialize: + + function BaseTween (parent) { - var wangset = wangsets[w]; - var identifier = w; + EventEmitter.call(this); - if (wangset.name && wangset.name !== '') + /** + * A reference to the Tween Manager, or Tween Chain, that owns this Tween. + * + * @name Phaser.Tweens.BaseTween#parent + * @type {(Phaser.Tweens.TweenManager|Phaser.Tweens.TweenChain)} + * @since 3.60.0 + */ + this.parent = parent; + + /** + * The main data array. For a Tween, this contains all of the `TweenData` objects, each + * containing a unique property and target that is being tweened. + * + * For a TweenChain, this contains an array of `Tween` instances, which are being played + * through in sequence. + * + * @name Phaser.Tweens.BaseTween#data + * @type {(Phaser.Tweens.TweenData[]|Phaser.Tweens.Tween[])} + * @since 3.60.0 + */ + this.data = []; + + /** + * The cached size of the data array. + * + * @name Phaser.Tweens.BaseTween#totalData + * @type {number} + * @since 3.60.0 + */ + this.totalData = 0; + + /** + * The time in milliseconds before the 'onStart' event fires. + * + * For a Tween, this is the shortest `delay` value across all of the TweenDatas it owns. + * For a TweenChain, it is whatever delay value was given in the configuration. + * + * @name Phaser.Tweens.BaseTween#startDelay + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.startDelay = 0; + + /** + * Has this Tween started playback yet? + * + * This boolean is toggled when the Tween leaves the 'start delayed' state and begins running. + * + * @name Phaser.Tweens.BaseTween#hasStarted + * @type {boolean} + * @readonly + * @since 3.60.0 + */ + this.hasStarted = false; + + /** + * Scales the time applied to this Tween. 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. + * + * This value is multiplied by the `TweenManager.timeScale`. + * + * @name Phaser.Tweens.BaseTween#timeScale + * @type {number} + * @default 1 + * @since 3.60.0 + */ + this.timeScale = 1; + + /** + * The number of times this Tween will loop. + * + * Can be -1 for an infinite loop, zero for none, or a positive integer. + * + * Typically this is set in the configuration object, but can also be set directly + * as long as this Tween is paused and hasn't started playback. + * + * When enabled it will play through ALL Tweens again. + * + * Use TweenData.repeat to loop a single element. + * + * @name Phaser.Tweens.BaseTween#loop + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.loop = 0; + + /** + * The time in milliseconds before the Tween loops. + * + * Only used if `loop` is > 0. + * + * @name Phaser.Tweens.BaseTween#loopDelay + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.loopDelay = 0; + + /** + * Internal counter recording how many loops are left to run. + * + * @name Phaser.Tweens.BaseTween#loopCounter + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.loopCounter = 0; + + /** + * The time in milliseconds before the 'onComplete' event fires. + * + * This never fires if `loop = -1` as it never completes because it has been + * set to loop forever. + * + * @name Phaser.Tweens.BaseTween#completeDelay + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.completeDelay = 0; + + /** + * An internal countdown timer (used by loopDelay and completeDelay) + * + * @name Phaser.Tweens.BaseTween#countdown + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.countdown = 0; + + /** + * The current state of the Tween. + * + * @name Phaser.Tweens.BaseTween#state + * @type {Phaser.Tweens.StateType} + * @since 3.60.0 + */ + this.state = TWEEN_CONST.PENDING; + + /** + * Is the Tween currently paused? + * + * A paused Tween needs to be started with the `play` method, or resumed with the `resume` method. + * + * This property can be toggled at runtime if required. + * + * @name Phaser.Tweens.BaseTween#paused + * @type {boolean} + * @default false + * @since 3.60.0 + */ + this.paused = false; + + /** + * An object containing the different Tween callback functions. + * + * You can either set these in the Tween config, or by calling the `Tween.setCallback` method. + * + * The types available are: + * + * `onActive` - When the Tween is first created it moves to an 'active' state when added to the Tween Manager. 'Active' does not mean 'playing'. + * `onStart` - When the Tween starts playing after a delayed or paused state. This will happen at the same time as `onActive` if the tween has no delay and isn't paused. + * `onLoop` - When a Tween loops, if it has been set to do so. This happens _after_ the `loopDelay` expires, if set. + * `onComplete` - When the Tween finishes playback fully. Never invoked if the Tween is set to repeat infinitely. + * `onStop` - Invoked only if the `Tween.stop` method is called. + * `onPause` - Invoked only if the `Tween.pause` method is called. Not invoked if the Tween Manager is paused. + * `onResume` - Invoked only if the `Tween.resume` method is called. Not invoked if the Tween Manager is resumed. + * + * The following types are also available and are invoked on a `TweenData` level - that is per-object, per-property, being tweened. + * + * `onYoyo` - When a TweenData starts a yoyo. This happens _after_ the `hold` delay expires, if set. + * `onRepeat` - When a TweenData repeats playback. This happens _after_ the `repeatDelay` expires, if set. + * `onUpdate` - When a TweenData updates a property on a source target during playback. + * + * @name Phaser.Tweens.BaseTween#callbacks + * @type {Phaser.Types.Tweens.TweenCallbacks} + * @since 3.60.0 + */ + this.callbacks = { + onActive: null, + onComplete: null, + onLoop: null, + onPause: null, + onRepeat: null, + onResume: null, + onStart: null, + onStop: null, + onUpdate: null, + onYoyo: null + }; + + /** + * The scope (or context) in which all of the callbacks are invoked. + * + * This defaults to be this Tween, but you can override this property + * to set it to whatever object you require. + * + * @name Phaser.Tweens.BaseTween#callbackScope + * @type {any} + * @since 3.60.0 + */ + this.callbackScope; + + /** + * Will this Tween persist after playback? A Tween that persists will _not_ be destroyed by the + * Tween Manager, or when calling `Tween.stop`, and can be re-played as required. You can either + * set this property when creating the tween in the tween config, or set it _prior_ to playback. + * + * However, it's up to you to ensure you destroy persistent tweens when you are finished with them, + * or they will retain references you may no longer require and waste memory. + * + * By default, `Tweens` are set to _not_ persist, so they are automatically cleaned-up by + * the Tween Manager. But `TweenChains` _do_ persist by default, unless overridden in their + * config. This is because the type of situations you use a chain for is far more likely to + * need to be replayed again in the future, rather than disposed of. + * + * @name Phaser.Tweens.BaseTween#persist + * @type {boolean} + * @since 3.60.0 + */ + this.persist = false; + }, + + /** + * Sets the value of the time scale applied to this Tween. 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. + * + * This value is multiplied by the `TweenManager.timeScale`. + * + * @method Phaser.Tweens.BaseTween#setTimeScale + * @since 3.60.0 + * + * @param {number} value - The time scale value to set. + * + * @return {this} This Tween instance. + */ + setTimeScale: function (value) + { + this.timeScale = value; + + return this; + }, + + /** + * Gets the value of the time scale applied to this Tween. A value of 1 runs in real-time. + * A value of 0.5 runs 50% slower, and so on. + * + * @method Phaser.Tweens.BaseTween#getTimeScale + * @since 3.60.0 + * + * @return {number} The value of the time scale applied to this Tween. + */ + getTimeScale: function () + { + return this.timeScale; + }, + + /** + * Checks if this Tween is currently playing. + * + * If this Tween is paused, or not active, this method will return false. + * + * @method Phaser.Tweens.BaseTween#isPlaying + * @since 3.60.0 + * + * @return {boolean} `true` if the Tween is playing, otherwise `false`. + */ + isPlaying: function () + { + return (!this.paused && this.isActive()); + }, + + /** + * Checks if the Tween is currently paused. + * + * This is the same as inspecting the `BaseTween.paused` property directly. + * + * @method Phaser.Tweens.BaseTween#isPaused + * @since 3.60.0 + * + * @return {boolean} `true` if the Tween is paused, otherwise `false`. + */ + isPaused: function () + { + return this.paused; + }, + + /** + * Pauses the Tween immediately. Use `resume` to continue playback. + * + * You can also toggle the `Tween.paused` boolean property, but doing so will not trigger the PAUSE event. + * + * @method Phaser.Tweens.BaseTween#pause + * @fires Phaser.Tweens.Events#TWEEN_PAUSE + * @since 3.60.0 + * + * @return {this} This Tween instance. + */ + pause: function () + { + if (!this.paused) { - identifier = wangset.name; + this.paused = true; + + this.dispatchEvent(Events.TWEEN_PAUSE, 'onPause'); } - if (Array.isArray(wangset.wangtiles) && wangset.wangtiles.length > 0) + return this; + }, + + /** + * Resumes the playback of a previously paused Tween. + * + * You can also toggle the `Tween.paused` boolean property, but doing so will not trigger the RESUME event. + * + * @method Phaser.Tweens.BaseTween#resume + * @fires Phaser.Tweens.Events#TWEEN_RESUME + * @since 3.60.0 + * + * @return {this} This Tween instance. + */ + resume: function () + { + if (this.paused) { - var edgeColors = {}; - var cornerColors = {}; + this.paused = false; - var c; - var color; - var colorIndex; + this.dispatchEvent(Events.TWEEN_RESUME, 'onResume'); + } - // Tiled before v2020.09.09 - if (Array.isArray(wangset.edgecolors)) - { - for (c = 0; c < wangset.edgecolors.length; c++) - { - colorIndex = 1 + c; - color = wangset.edgecolors[c]; + return this; + }, - if (color.name !== '') - { - edgeColors[colorIndex] = color.name; - } - } - } + /** + * Internal method that makes this Tween active within the TweenManager + * and emits the onActive event and callback. + * + * @method Phaser.Tweens.BaseTween#makeActive + * @fires Phaser.Tweens.Events#TWEEN_ACTIVE + * @since 3.60.0 + */ + makeActive: function () + { + this.parent.makeActive(this); - if (Array.isArray(wangset.cornercolors)) - { - for (c = 0; c < wangset.cornercolors.length; c++) - { - colorIndex = 1 + c; - color = wangset.cornercolors[c]; + this.dispatchEvent(Events.TWEEN_ACTIVE, 'onActive'); + }, - if (color.name !== '') - { - cornerColors[colorIndex] = color.name; - } - } - } + /** + * Internal method that handles this tween completing and emitting the onComplete event + * and callback. + * + * @method Phaser.Tweens.BaseTween#onCompleteHandler + * @since 3.60.0 + */ + onCompleteHandler: function () + { + this.setPendingRemoveState(); - // Tiled after v2020.09.09 - if (Array.isArray(wangset.colors)) - { - for (c = 0; c < wangset.colors.length; c++) - { - color = wangset.colors[c]; - colorIndex = 1 + c; + this.dispatchEvent(Events.TWEEN_COMPLETE, 'onComplete'); + }, - if (color.name !== '') - { - edgeColors[colorIndex] = cornerColors[colorIndex] = color.name; - } - } - } + /** + * Flags the Tween as being complete, whatever stage of progress it is at. + * + * If an `onComplete` callback has been defined it will automatically invoke it, unless a `delay` + * argument is provided, in which case the Tween will delay for that period of time before calling the callback. + * + * If you don't need a delay or don't have an `onComplete` callback then call `Tween.stop` instead. + * + * @method Phaser.Tweens.BaseTween#complete + * @fires Phaser.Tweens.Events#TWEEN_COMPLETE + * @since 3.2.0 + * + * @param {number} [delay=0] - The time to wait before invoking the complete callback. If zero it will fire immediately. + * + * @return {this} This Tween instance. + */ + complete: function (delay) + { + if (delay === undefined) { delay = 0; } - // The wangid layout is north, northeast, east, southeast, etc. - var idLayout = [ - edgeColors, cornerColors, edgeColors, cornerColors, - edgeColors, cornerColors, edgeColors, cornerColors - ]; + if (delay) + { + this.setCompleteDelayState(); - for (var t = 0; t < wangset.wangtiles.length; t++) - { - var wangtile = wangset.wangtiles[t]; + this.countdown = delay; + } + else + { + this.onCompleteHandler(); + } - var obj = (datas[wangtile.tileid] || (datas[wangtile.tileid] = {})); + return this; + }, - obj = (obj.wangid || (obj.wangid = {})); + /** + * Flags the Tween as being complete only once the current loop has finished. + * + * This is a useful way to stop an infinitely looping tween once a complete cycle is over, + * rather than abruptly. + * + * If you don't have a loop then call `Tween.stop` instead. + * + * @method Phaser.Tweens.BaseTween#completeAfterLoop + * @fires Phaser.Tweens.Events#TWEEN_COMPLETE + * @since 3.60.0 + * + * @param {number} [loops=0] - The number of loops that should finish before this tween completes. Zero means complete just the current loop. + * + * @return {this} This Tween instance. + */ + completeAfterLoop: function (loops) + { + if (loops === undefined) { loops = 0; } - var wangid = []; + if (this.loopCounter > loops) + { + this.loopCounter = loops; + } - for (var i = 0; i < Math.min(idLayout.length, wangtile.wangid.length); i++) - { - color = wangtile.wangid[i]; + return this; + }, - if (color === 0) - { - wangid.push(undefined); - continue; - } + /** + * Immediately removes this Tween from the TweenManager and all of its internal arrays, + * no matter what stage it is at. Then sets the tween state to `REMOVED`. + * + * You should dispose of your reference to this tween after calling this method, to + * free it from memory. If you no longer require it, call `Tween.destroy()` on it. + * + * @method Phaser.Tweens.BaseTween#remove + * @since 3.60.0 + * + * @return {this} This Tween instance. + */ + remove: function () + { + this.parent.remove(this); - var renamed = idLayout[i][color]; + return this; + }, - if (renamed !== undefined) - { - wangid.push(renamed); - continue; - } + /** + * Stops the Tween immediately, whatever stage of progress it is at. + * + * If not a part of a Tween Chain it is also flagged for removal by the Tween Manager. + * + * If an `onStop` callback has been defined it will automatically invoke it. + * + * The Tween will be removed during the next game frame, but should be considered 'destroyed' from this point on. + * + * Typically, you cannot play a Tween that has been stopped. If you just wish to pause the tween, not destroy it, + * then call the `pause` method instead and use `resume` to continue playback. If you wish to restart the Tween, + * use the `restart` or `seek` methods. + * + * @method Phaser.Tweens.BaseTween#stop + * @fires Phaser.Tweens.Events#TWEEN_STOP + * @since 3.60.0 + * + * @return {this} This Tween instance. + */ + stop: function () + { + if (!this.isRemoved() && !this.isPendingRemove() && !this.isDestroyed()) + { + this.dispatchEvent(Events.TWEEN_STOP, 'onStop'); - wangid.push(color); - } + this.setPendingRemoveState(); + } + + return this; + }, + + /** + * Internal method that handles the processing of the loop delay countdown timer and + * the dispatch of related events. Called automatically by `Tween.update`. + * + * @method Phaser.Tweens.BaseTween#updateLoopCountdown + * @since 3.60.0 + * + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ + updateLoopCountdown: function (delta) + { + this.countdown -= delta; + + if (this.countdown <= 0) + { + this.setActiveState(); + + this.dispatchEvent(Events.TWEEN_LOOP, 'onLoop'); + } + }, + + /** + * Internal method that handles the processing of the start delay countdown timer and + * the dispatch of related events. Called automatically by `Tween.update`. + * + * @method Phaser.Tweens.BaseTween#updateStartCountdown + * @since 3.60.0 + * + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ + updateStartCountdown: function (delta) + { + this.countdown -= delta; + + if (this.countdown <= 0) + { + this.hasStarted = true; + + this.setActiveState(); + + this.dispatchEvent(Events.TWEEN_START, 'onStart'); + + // Reset the delta so we always start progress from zero + delta = 0; + } + + return delta; + }, + + /** + * Internal method that handles the processing of the complete delay countdown timer and + * the dispatch of related events. Called automatically by `Tween.update`. + * + * @method Phaser.Tweens.BaseTween#updateCompleteDelay + * @since 3.60.0 + * + * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ + updateCompleteDelay: function (delta) + { + this.countdown -= delta; + + if (this.countdown <= 0) + { + this.onCompleteHandler(); + } + }, + + /** + * Sets an event based callback to be invoked during playback. + * + * Calling this method will replace a previously set callback for the given type, if any exists. + * + * The types available are: + * + * `onActive` - When the Tween is first created it moves to an 'active' state when added to the Tween Manager. 'Active' does not mean 'playing'. + * `onStart` - When the Tween starts playing after a delayed or paused state. This will happen at the same time as `onActive` if the tween has no delay and isn't paused. + * `onLoop` - When a Tween loops, if it has been set to do so. This happens _after_ the `loopDelay` expires, if set. + * `onComplete` - When the Tween finishes playback fully. Never invoked if the Tween is set to repeat infinitely. + * `onStop` - Invoked only if the `Tween.stop` method is called. + * `onPause` - Invoked only if the `Tween.pause` method is called. Not invoked if the Tween Manager is paused. + * `onResume` - Invoked only if the `Tween.resume` method is called. Not invoked if the Tween Manager is resumed. + * + * The following types are also available and are invoked on a `TweenData` level - that is per-object, per-property, being tweened. + * + * `onYoyo` - When a TweenData starts a yoyo. This happens _after_ the `hold` delay expires, if set. + * `onRepeat` - When a TweenData repeats playback. This happens _after_ the `repeatDelay` expires, if set. + * `onUpdate` - When a TweenData updates a property on a source target during playback. + * + * @method Phaser.Tweens.BaseTween#setCallback + * @since 3.60.0 + * + * @param {Phaser.Types.Tweens.TweenCallbackTypes} type - The type of callback to set. One of: `onActive`, `onComplete`, `onLoop`, `onPause`, `onRepeat`, `onResume`, `onStart`, `onStop`, `onUpdate` or `onYoyo`. + * @param {function} callback - Your callback that will be invoked. + * @param {array} [params] - The parameters to pass to the callback. Pass an empty array if you don't want to define any, but do wish to set the scope. + * + * @return {this} This Tween instance. + */ + setCallback: function (type, callback, params) + { + if (params === undefined) { params = []; } + + if (this.callbacks.hasOwnProperty(type)) + { + this.callbacks[type] = { func: callback, params: params }; + } + + return this; + }, + + /** + * Sets this Tween state to PENDING. + * + * @method Phaser.Tweens.BaseTween#setPendingState + * @since 3.60.0 + */ + setPendingState: function () + { + this.state = TWEEN_CONST.PENDING; + }, + + /** + * Sets this Tween state to ACTIVE. + * + * @method Phaser.Tweens.BaseTween#setActiveState + * @since 3.60.0 + */ + setActiveState: function () + { + this.state = TWEEN_CONST.ACTIVE; + }, - obj[identifier] = wangid; - } - } - } -}; + /** + * Sets this Tween state to LOOP_DELAY. + * + * @method Phaser.Tweens.BaseTween#setLoopDelayState + * @since 3.60.0 + */ + setLoopDelayState: function () + { + this.state = TWEEN_CONST.LOOP_DELAY; + }, -module.exports = ParseWangsets; + /** + * Sets this Tween state to COMPLETE_DELAY. + * + * @method Phaser.Tweens.BaseTween#setCompleteDelayState + * @since 3.60.0 + */ + setCompleteDelayState: function () + { + this.state = TWEEN_CONST.COMPLETE_DELAY; + }, + /** + * Sets this Tween state to START_DELAY. + * + * @method Phaser.Tweens.BaseTween#setStartDelayState + * @since 3.60.0 + */ + setStartDelayState: function () + { + this.state = TWEEN_CONST.START_DELAY; -/***/ }), -/* 1454 */ -/***/ (function(module, exports, __webpack_require__) { + this.countdown = this.startDelay; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.hasStarted = false; + }, -/** - * @namespace Phaser.Tilemaps.Parsers.Impact - */ + /** + * Sets this Tween state to PENDING_REMOVE. + * + * @method Phaser.Tweens.BaseTween#setPendingRemoveState + * @since 3.60.0 + */ + setPendingRemoveState: function () + { + this.state = TWEEN_CONST.PENDING_REMOVE; + }, -module.exports = { + /** + * Sets this Tween state to REMOVED. + * + * @method Phaser.Tweens.BaseTween#setRemovedState + * @since 3.60.0 + */ + setRemovedState: function () + { + this.state = TWEEN_CONST.REMOVED; + }, - ParseTileLayers: __webpack_require__(578), - ParseTilesets: __webpack_require__(579), - ParseWeltmeister: __webpack_require__(577) + /** + * Sets this Tween state to FINISHED. + * + * @method Phaser.Tweens.BaseTween#setFinishedState + * @since 3.60.0 + */ + setFinishedState: function () + { + this.state = TWEEN_CONST.FINISHED; + }, -}; + /** + * Sets this Tween state to DESTROYED. + * + * @method Phaser.Tweens.BaseTween#setDestroyedState + * @since 3.60.0 + */ + setDestroyedState: function () + { + this.state = TWEEN_CONST.DESTROYED; + }, + /** + * Returns `true` if this Tween has a _current_ state of PENDING, otherwise `false`. + * + * @method Phaser.Tweens.BaseTween#isPending + * @since 3.60.0 + * + * @return {boolean} `true` if this Tween has a _current_ state of PENDING, otherwise `false`. + */ + isPending: function () + { + return (this.state === TWEEN_CONST.PENDING); + }, -/***/ }), -/* 1455 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Returns `true` if this Tween has a _current_ state of ACTIVE, otherwise `false`. + * + * @method Phaser.Tweens.BaseTween#isActive + * @since 3.60.0 + * + * @return {boolean} `true` if this Tween has a _current_ state of ACTIVE, otherwise `false`. + */ + isActive: function () + { + return (this.state === TWEEN_CONST.ACTIVE); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Returns `true` if this Tween has a _current_ state of LOOP_DELAY, otherwise `false`. + * + * @method Phaser.Tweens.BaseTween#isLoopDelayed + * @since 3.60.0 + * + * @return {boolean} `true` if this Tween has a _current_ state of LOOP_DELAY, otherwise `false`. + */ + isLoopDelayed: function () + { + return (this.state === TWEEN_CONST.LOOP_DELAY); + }, -/** - * @namespace Phaser.Tilemaps.Parsers.Tiled - */ + /** + * Returns `true` if this Tween has a _current_ state of COMPLETE_DELAY, otherwise `false`. + * + * @method Phaser.Tweens.BaseTween#isCompleteDelayed + * @since 3.60.0 + * + * @return {boolean} `true` if this Tween has a _current_ state of COMPLETE_DELAY, otherwise `false`. + */ + isCompleteDelayed: function () + { + return (this.state === TWEEN_CONST.COMPLETE_DELAY); + }, -module.exports = { + /** + * Returns `true` if this Tween has a _current_ state of START_DELAY, otherwise `false`. + * + * @method Phaser.Tweens.BaseTween#isStartDelayed + * @since 3.60.0 + * + * @return {boolean} `true` if this Tween has a _current_ state of START_DELAY, otherwise `false`. + */ + isStartDelayed: function () + { + return (this.state === TWEEN_CONST.START_DELAY); + }, - AssignTileProperties: __webpack_require__(567), - Base64Decode: __webpack_require__(574), - BuildTilesetIndex: __webpack_require__(568), - CreateGroupLayer: __webpack_require__(161), - ParseGID: __webpack_require__(261), - ParseImageLayers: __webpack_require__(569), - ParseJSONTiled: __webpack_require__(566), - ParseObject: __webpack_require__(260), - ParseObjectLayers: __webpack_require__(570), - ParseTileLayers: __webpack_require__(573), - ParseTilesets: __webpack_require__(575) + /** + * Returns `true` if this Tween has a _current_ state of PENDING_REMOVE, otherwise `false`. + * + * @method Phaser.Tweens.BaseTween#isPendingRemove + * @since 3.60.0 + * + * @return {boolean} `true` if this Tween has a _current_ state of PENDING_REMOVE, otherwise `false`. + */ + isPendingRemove: function () + { + return (this.state === TWEEN_CONST.PENDING_REMOVE); + }, -}; + /** + * Returns `true` if this Tween has a _current_ state of REMOVED, otherwise `false`. + * + * @method Phaser.Tweens.BaseTween#isRemoved + * @since 3.60.0 + * + * @return {boolean} `true` if this Tween has a _current_ state of REMOVED, otherwise `false`. + */ + isRemoved: function () + { + return (this.state === TWEEN_CONST.REMOVED); + }, + /** + * Returns `true` if this Tween has a _current_ state of FINISHED, otherwise `false`. + * + * @method Phaser.Tweens.BaseTween#isFinished + * @since 3.60.0 + * + * @return {boolean} `true` if this Tween has a _current_ state of FINISHED, otherwise `false`. + */ + isFinished: function () + { + return (this.state === TWEEN_CONST.FINISHED); + }, -/***/ }), -/* 1456 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Returns `true` if this Tween has a _current_ state of DESTROYED, otherwise `false`. + * + * @method Phaser.Tweens.BaseTween#isDestroyed + * @since 3.60.0 + * + * @return {boolean} `true` if this Tween has a _current_ state of DESTROYED, otherwise `false`. + */ + isDestroyed: function () + { + return (this.state === TWEEN_CONST.DESTROYED); + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Handles the destroy process of this Tween, clearing out the + * Tween Data and resetting the targets. A Tween that has been + * destroyed cannot ever be played or used again. + * + * @method Phaser.Tweens.BaseTween#destroy + * @since 3.60.0 + */ + destroy: function () + { + if (this.data) + { + this.data.forEach(function (tweenData) + { + tweenData.destroy(); + }); + } -var renderWebGL = __webpack_require__(1); -var renderCanvas = __webpack_require__(1); + this.removeAllListeners(); -if (true) -{ - renderWebGL = __webpack_require__(1457); -} + this.callbacks = null; + this.data = null; + this.parent = null; -if (true) -{ - renderCanvas = __webpack_require__(1458); -} + this.setDestroyedState(); + } -module.exports = { +}); - renderWebGL: renderWebGL, - renderCanvas: renderCanvas +BaseTween.TYPES = [ + 'onActive', + 'onComplete', + 'onLoop', + 'onPause', + 'onRepeat', + 'onResume', + 'onStart', + 'onStop', + 'onUpdate', + 'onYoyo' +]; -}; +module.exports = BaseTween; /***/ }), -/* 1457 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 65521: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Utils = __webpack_require__(12); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(54272); +var TWEEN_CONST = __webpack_require__(55303); /** - * 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. + * @classdesc + * BaseTweenData is the class that the TweenData and TweenFrameData classes + * extend from. You should not typically instantiate this class directly, but instead + * use it to form your own tween data classes from, should you require it. * - * @method Phaser.Tilemaps.TilemapLayer#renderWebGL - * @since 3.0.0 - * @private + * Prior to Phaser 3.60 the TweenData was just an object, but was refactored to a class, + * to make it responsible for its own state and updating. * - * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer. - * @param {Phaser.Tilemaps.TilemapLayer} src - The Game Object being rendered in this call. - * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object. + * @class BaseTweenData + * @memberof Phaser.Tweens + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Tweens.Tween} tween - The tween this TweenData instance belongs to. + * @param {number} targetIndex - The target index within the Tween targets array. + * @param {string} key - The property of the target to tween. + * @param {Phaser.Types.Tweens.GetEndCallback} getEnd - What the property will be at the END of the Tween. + * @param {Phaser.Types.Tweens.GetStartCallback} getStart - What the property will be at the START of the Tween. + * @param {?Phaser.Types.Tweens.GetActiveCallback} getActive - If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. + * @param {function} ease - The ease function this tween uses. + * @param {function} delay - Function that returns the time in milliseconds before tween will start. + * @param {number} duration - The duration of the tween in milliseconds. + * @param {boolean} yoyo - Determines whether the tween should return back to its start value after hold has expired. + * @param {number} hold - Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param {number} repeat - Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param {number} repeatDelay - Function that returns the time in milliseconds before the repeat will start. + * @param {boolean} flipX - Should toggleFlipX be called when yoyo or repeat happens? + * @param {boolean} flipY - Should toggleFlipY be called when yoyo or repeat happens? + * @param {?function} interpolation - The interpolation function to be used for arrays of data. Defaults to 'null'. + * @param {?number[]} interpolationData - The array of interpolation data to be set. Defaults to 'null'. */ -var TilemapLayerWebGLRenderer = function (renderer, src, camera) -{ - var renderTiles = src.cull(camera); +var BaseTweenData = new Class({ - var tileCount = renderTiles.length; - var alpha = camera.alpha * src.alpha; + initialize: - if (tileCount === 0 || alpha <= 0) + function BaseTweenData (tween, targetIndex, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY) { - return; - } - - var gidMap = src.gidMap; - var pipeline = renderer.pipelines.set(src.pipeline, src); - - var getTint = Utils.getTintAppendFloatAlpha; + /** + * A reference to the Tween that this TweenData instance belongs to. + * + * @name Phaser.Tweens.BaseTweenData#tween + * @type {Phaser.Tweens.Tween} + * @since 3.60.0 + */ + this.tween = tween; - var scrollFactorX = src.scrollFactorX; - var scrollFactorY = src.scrollFactorY; + /** + * The index of the target within the Tween `targets` array. + * + * @name Phaser.Tweens.BaseTweenData#targetIndex + * @type {number} + * @since 3.60.0 + */ + this.targetIndex = targetIndex; - var x = src.x; - var y = src.y; + /** + * The duration of the tween in milliseconds, excluding any time required + * for yoyo or repeats. + * + * @name Phaser.Tweens.BaseTweenData#duration + * @type {number} + * @since 3.60.0 + */ + this.duration = duration; - var sx = src.scaleX; - var sy = src.scaleY; + /** + * The total calculated duration, in milliseconds, of this TweenData. + * Factoring in the duration, repeats, delays and yoyos. + * + * @name Phaser.Tweens.BaseTweenData#totalDuration + * @type {number} + * @since 3.60.0 + */ + this.totalDuration = 0; - renderer.pipelines.preBatch(src); + /** + * The time, in milliseconds, before this tween will start playing. + * + * This value is generated by the `getDelay` function. + * + * @name Phaser.Tweens.BaseTweenData#delay + * @type {number} + * @since 3.60.0 + */ + this.delay = 0; - for (var i = 0; i < tileCount; i++) - { - var tile = renderTiles[i]; + /** + * This function returns the value to be used for `TweenData.delay`. + * + * @name Phaser.Tweens.BaseTweenData#getDelay + * @type {function} + * @since 3.60.0 + */ + this.getDelay = delay; - var tileset = gidMap[tile.index]; + /** + * Will the Tween ease back to its starting values, after reaching the end + * and any `hold` value that may be set? + * + * @name Phaser.Tweens.BaseTweenData#yoyo + * @type {boolean} + * @since 3.60.0 + */ + this.yoyo = yoyo; - if (!tileset) - { - continue; - } + /** + * The time, in milliseconds, before this tween will start a yoyo to repeat. + * + * @name Phaser.Tweens.BaseTweenData#hold + * @type {number} + * @since 3.60.0 + */ + this.hold = hold; - var tileTexCoords = tileset.getTileTextureCoordinates(tile.index); + /** + * The number of times this tween will repeat. + * + * The tween will always run once regardless of this value, + * so a repeat value of '1' will play the tween twice: I.e. the original + * play-through and then it repeats that once (1). + * + * If this value is set to -1 this tween will repeat forever. + * + * @name Phaser.Tweens.BaseTweenData#repeat + * @type {number} + * @since 3.60.0 + */ + this.repeat = repeat; - if (tileTexCoords === null) - { - continue; - } + /** + * The time, in milliseconds, before the repeat will start. + * + * @name Phaser.Tweens.BaseTweenData#repeatDelay + * @type {number} + * @since 3.60.0 + */ + this.repeatDelay = repeatDelay; - var texture = tileset.glTexture; + /** + * How many repeats are left to run? + * + * @name Phaser.Tweens.BaseTweenData#repeatCounter + * @type {number} + * @since 3.60.0 + */ + this.repeatCounter = 0; - var textureUnit = pipeline.setTexture2D(texture, src); + /** + * If `true` this Tween will call `toggleFlipX` on the Tween target + * whenever it yoyo's or repeats. It will only be called if the target + * has a function matching this name, like most Phaser GameObjects do. + * + * @name Phaser.Tweens.BaseTweenData#flipX + * @type {boolean} + * @since 3.60.0 + */ + this.flipX = flipX; - var frameWidth = tileset.tileWidth; - var frameHeight = tileset.tileHeight; + /** + * If `true` this Tween will call `toggleFlipY` on the Tween target + * whenever it yoyo's or repeats. It will only be called if the target + * has a function matching this name, like most Phaser GameObjects do. + * + * @name Phaser.Tweens.BaseTweenData#flipY + * @type {boolean} + * @since 3.60.0 + */ + this.flipY = flipY; - var frameX = tileTexCoords.x; - var frameY = tileTexCoords.y; + /** + * A value between 0 and 1 holding the progress of this TweenData. + * + * @name Phaser.Tweens.BaseTweenData#progress + * @type {number} + * @since 3.60.0 + */ + this.progress = 0; - var tw = tileset.tileWidth * 0.5; - var th = tileset.tileHeight * 0.5; + /** + * The amount of time, in milliseconds, that has elapsed since this + * TweenData was made active. + * + * @name Phaser.Tweens.BaseTweenData#elapsed + * @type {number} + * @since 3.60.0 + */ + this.elapsed = 0; - var tint = getTint(tile.tint, alpha * tile.alpha); + /** + * The state of this TweenData. + * + * @name Phaser.Tweens.BaseTweenData#state + * @type {Phaser.Tweens.StateType} + * @since 3.60.0 + */ + this.state = 0; - pipeline.batchTexture( - src, - texture, - texture.width, texture.height, - x + ((tw + tile.pixelX) * sx), y + ((th + tile.pixelY) * sy), - tile.width, tile.height, - sx, sy, - tile.rotation, - tile.flipX, tile.flipY, - scrollFactorX, scrollFactorY, - tw, th, - frameX, frameY, frameWidth, frameHeight, - tint, tint, tint, tint, false, - 0, 0, - camera, - null, - true, - textureUnit - ); - } + /** + * Is this Tween Data currently waiting for a countdown to elapse, or not? + * + * @name Phaser.Tweens.BaseTweenData#isCountdown + * @type {boolean} + * @since 3.60.0 + */ + this.isCountdown = false; + }, - renderer.pipelines.postBatch(src); -}; + /** + * Returns a reference to the target object belonging to this TweenData. + * + * @method Phaser.Tweens.BaseTweenData#getTarget + * @since 3.60.0 + * + * @return {object} The target object. Can be any JavaScript object, but is typically a Game Object. + */ + getTarget: function () + { + return this.tween.targets[this.targetIndex]; + }, -module.exports = TilemapLayerWebGLRenderer; + /** + * Sets this TweenData's target object property to be the given value. + * + * @method Phaser.Tweens.BaseTweenData#setTargetValue + * @since 3.60.0 + * + * @param {number} [value] - The value to set on the target. If not given, sets it to the last `current` value. + */ + setTargetValue: function (value) + { + if (value === undefined) { value = this.current; } + this.tween.targets[this.targetIndex][this.key] = value; + }, -/***/ }), -/* 1458 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Sets this TweenData state to CREATED. + * + * @method Phaser.Tweens.BaseTweenData#setCreatedState + * @since 3.60.0 + */ + setCreatedState: function () + { + this.state = TWEEN_CONST.CREATED; + this.isCountdown = false; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Sets this TweenData state to DELAY. + * + * @method Phaser.Tweens.BaseTweenData#setDelayState + * @since 3.60.0 + */ + setDelayState: function () + { + this.state = TWEEN_CONST.DELAY; + this.isCountdown = true; + }, -var TransformMatrix = __webpack_require__(25); + /** + * Sets this TweenData state to PENDING_RENDER. + * + * @method Phaser.Tweens.BaseTweenData#setPendingRenderState + * @since 3.60.0 + */ + setPendingRenderState: function () + { + this.state = TWEEN_CONST.PENDING_RENDER; + this.isCountdown = false; + }, -var tempMatrix1 = new TransformMatrix(); -var tempMatrix2 = new TransformMatrix(); -var tempMatrix3 = new TransformMatrix(); + /** + * Sets this TweenData state to PLAYING_FORWARD. + * + * @method Phaser.Tweens.BaseTweenData#setPlayingForwardState + * @since 3.60.0 + */ + setPlayingForwardState: function () + { + this.state = TWEEN_CONST.PLAYING_FORWARD; + this.isCountdown = false; + }, -/** - * 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.Tilemaps.TilemapLayer#renderCanvas - * @since 3.50.0 - * @private - * - * @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer. - * @param {Phaser.Tilemaps.TilemapLayer} 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 TilemapLayerCanvasRenderer = function (renderer, src, camera, parentMatrix) -{ - var renderTiles = src.cull(camera); + /** + * Sets this TweenData state to PLAYING_BACKWARD. + * + * @method Phaser.Tweens.BaseTweenData#setPlayingBackwardState + * @since 3.60.0 + */ + setPlayingBackwardState: function () + { + this.state = TWEEN_CONST.PLAYING_BACKWARD; + this.isCountdown = false; + }, - var tileCount = renderTiles.length; - var alpha = camera.alpha * src.alpha; + /** + * Sets this TweenData state to HOLD_DELAY. + * + * @method Phaser.Tweens.BaseTweenData#setHoldState + * @since 3.60.0 + */ + setHoldState: function () + { + this.state = TWEEN_CONST.HOLD_DELAY; + this.isCountdown = true; + }, - if (tileCount === 0 || alpha <= 0) + /** + * Sets this TweenData state to REPEAT_DELAY. + * + * @method Phaser.Tweens.BaseTweenData#setRepeatState + * @since 3.60.0 + */ + setRepeatState: function () { - return; - } + this.state = TWEEN_CONST.REPEAT_DELAY; + this.isCountdown = true; + }, - var camMatrix = tempMatrix1; - var layerMatrix = tempMatrix2; - var calcMatrix = tempMatrix3; + /** + * Sets this TweenData state to COMPLETE. + * + * @method Phaser.Tweens.BaseTweenData#setCompleteState + * @since 3.60.0 + */ + setCompleteState: function () + { + this.state = TWEEN_CONST.COMPLETE; + this.isCountdown = false; + }, - layerMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY); + /** + * Returns `true` if this TweenData has a _current_ state of CREATED, otherwise `false`. + * + * @method Phaser.Tweens.BaseTweenData#isCreated + * @since 3.60.0 + * + * @return {boolean} `true` if this TweenData has a _current_ state of CREATED, otherwise `false`. + */ + isCreated: function () + { + return (this.state === TWEEN_CONST.CREATED); + }, - camMatrix.copyFrom(camera.matrix); + /** + * Returns `true` if this TweenData has a _current_ state of DELAY, otherwise `false`. + * + * @method Phaser.Tweens.BaseTweenData#isDelayed + * @since 3.60.0 + * + * @return {boolean} `true` if this TweenData has a _current_ state of DELAY, otherwise `false`. + */ + isDelayed: function () + { + return (this.state === TWEEN_CONST.DELAY); + }, - var ctx = renderer.currentContext; - var gidMap = src.gidMap; + /** + * Returns `true` if this TweenData has a _current_ state of PENDING_RENDER, otherwise `false`. + * + * @method Phaser.Tweens.BaseTweenData#isPendingRender + * @since 3.60.0 + * + * @return {boolean} `true` if this TweenData has a _current_ state of PENDING_RENDER, otherwise `false`. + */ + isPendingRender: function () + { + return (this.state === TWEEN_CONST.PENDING_RENDER); + }, - ctx.save(); + /** + * Returns `true` if this TweenData has a _current_ state of PLAYING_FORWARD, otherwise `false`. + * + * @method Phaser.Tweens.BaseTweenData#isPlayingForward + * @since 3.60.0 + * + * @return {boolean} `true` if this TweenData has a _current_ state of PLAYING_FORWARD, otherwise `false`. + */ + isPlayingForward: function () + { + return (this.state === TWEEN_CONST.PLAYING_FORWARD); + }, - if (parentMatrix) + /** + * Returns `true` if this TweenData has a _current_ state of PLAYING_BACKWARD, otherwise `false`. + * + * @method Phaser.Tweens.BaseTweenData#isPlayingBackward + * @since 3.60.0 + * + * @return {boolean} `true` if this TweenData has a _current_ state of PLAYING_BACKWARD, otherwise `false`. + */ + isPlayingBackward: function () { - // Multiply the camera by the parent matrix - camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY); + return (this.state === TWEEN_CONST.PLAYING_BACKWARD); + }, - // Undo the camera scroll - layerMatrix.e = src.x; - layerMatrix.f = src.y; + /** + * Returns `true` if this TweenData has a _current_ state of HOLD_DELAY, otherwise `false`. + * + * @method Phaser.Tweens.BaseTweenData#isHolding + * @since 3.60.0 + * + * @return {boolean} `true` if this TweenData has a _current_ state of HOLD_DELAY, otherwise `false`. + */ + isHolding: function () + { + return (this.state === TWEEN_CONST.HOLD_DELAY); + }, - // Multiply by the Sprite matrix, store result in calcMatrix - camMatrix.multiply(layerMatrix, calcMatrix); + /** + * Returns `true` if this TweenData has a _current_ state of REPEAT_DELAY, otherwise `false`. + * + * @method Phaser.Tweens.BaseTweenData#isRepeating + * @since 3.60.0 + * + * @return {boolean} `true` if this TweenData has a _current_ state of REPEAT_DELAY, otherwise `false`. + */ + isRepeating: function () + { + return (this.state === TWEEN_CONST.REPEAT_DELAY); + }, - calcMatrix.copyToContext(ctx); - } - else + /** + * Returns `true` if this TweenData has a _current_ state of COMPLETE, otherwise `false`. + * + * @method Phaser.Tweens.BaseTweenData#isComplete + * @since 3.60.0 + * + * @return {boolean} `true` if this TweenData has a _current_ state of COMPLETE, otherwise `false`. + */ + isComplete: function () { - layerMatrix.e -= camera.scrollX * src.scrollFactorX; - layerMatrix.f -= camera.scrollY * src.scrollFactorY; + return (this.state === TWEEN_CONST.COMPLETE); + }, - layerMatrix.copyToContext(ctx); - } + /** + * Internal method used as part of the playback process that checks if this + * TweenData should yoyo, repeat, or has completed. + * + * @method Phaser.Tweens.BaseTweenData#setStateFromEnd + * @fires Phaser.Tweens.Events#TWEEN_REPEAT + * @fires Phaser.Tweens.Events#TWEEN_YOYO + * @since 3.60.0 + * + * @param {number} diff - Any extra time that needs to be accounted for in the elapsed and progress values. + */ + setStateFromEnd: function (diff) + { + if (this.yoyo) + { + this.onRepeat(diff, true, true); + } + else if (this.repeatCounter > 0) + { + this.onRepeat(diff, true, false); + } + else + { + this.setCompleteState(); + } + }, - if (!renderer.antialias || src.scaleX > 1 || src.scaleY > 1) + /** + * Internal method used as part of the playback process that checks if this + * TweenData should repeat or has completed. + * + * @method Phaser.Tweens.BaseTweenData#setStateFromStart + * @fires Phaser.Tweens.Events#TWEEN_REPEAT + * @since 3.60.0 + * + * @param {number} diff - Any extra time that needs to be accounted for in the elapsed and progress values. + */ + setStateFromStart: function (diff) { - ctx.imageSmoothingEnabled = false; - } + if (this.repeatCounter > 0) + { + this.onRepeat(diff, false); + } + else + { + this.setCompleteState(); + } + }, - for (var i = 0; i < tileCount; i++) + /** + * Internal method that resets this Tween Data entirely, including the progress and elapsed values. + * + * Called automatically by the parent Tween. Should not be called directly. + * + * @method Phaser.Tweens.BaseTweenData#reset + * @since 3.60.0 + */ + reset: function () { - var tile = renderTiles[i]; + var tween = this.tween; + var totalTargets = tween.totalTargets; - var tileset = gidMap[tile.index]; + var targetIndex = this.targetIndex; + var target = tween.targets[targetIndex]; + var key = this.key; - if (!tileset) + this.progress = 0; + this.elapsed = 0; + + // Function signature: target, key, value, index, total, tween + + this.delay = this.getDelay(target, key, 0, targetIndex, totalTargets, tween); + + this.repeatCounter = (this.repeat === -1) ? TWEEN_CONST.MAX : this.repeat; + + this.setPendingRenderState(); + + // calcDuration: + + // Set t1 (duration + hold + yoyo) + var t1 = this.duration + this.hold; + + if (this.yoyo) { - continue; + t1 += this.duration; } - var image = tileset.image.getSourceImage(); + // Set t2 (repeatDelay + duration + hold + yoyo) + var t2 = t1 + this.repeatDelay; - var tileTexCoords = tileset.getTileTextureCoordinates(tile.index); + // Total Duration + this.totalDuration = this.delay + t1; - if (tileTexCoords === null) + if (this.repeat === -1) { - continue; + this.totalDuration += (t2 * TWEEN_CONST.MAX); + tween.isInfinite = true; + } + else if (this.repeat > 0) + { + this.totalDuration += (t2 * this.repeat); } - var tileWidth = tileset.tileWidth; - var tileHeight = tileset.tileHeight; + if (this.totalDuration > tween.duration) + { + // Set the longest duration in the parent Tween + tween.duration = this.totalDuration; + } - var halfWidth = tileWidth * 0.5; - var halfHeight = tileHeight * 0.5; + if (this.delay < tween.startDelay) + { + tween.startDelay = this.delay; + } - ctx.save(); + if (this.delay > 0) + { + this.elapsed = this.delay; - ctx.translate(tile.pixelX + halfWidth, tile.pixelY + halfHeight); + this.setDelayState(); + } + }, - if (tile.rotation !== 0) + /** + * Internal method that handles repeating or yoyo'ing this TweenData. + * + * Called automatically by `setStateFromStart` and `setStateFromEnd`. + * + * @method Phaser.Tweens.BaseTweenData#onRepeat + * @fires Phaser.Tweens.Events#TWEEN_REPEAT + * @fires Phaser.Tweens.Events#TWEEN_YOYO + * @since 3.60.0 + * + * @param {number} diff - Any extra time that needs to be accounted for in the elapsed and progress values. + * @param {boolean} setStart - Set the TweenData start values? + * @param {boolean} isYoyo - Is this call a Yoyo check? + */ + onRepeat: function (diff, setStart, isYoyo) + { + var tween = this.tween; + var totalTargets = tween.totalTargets; + + var targetIndex = this.targetIndex; + var target = tween.targets[targetIndex]; + var key = this.key; + + var isTweenData = (key !== 'texture'); + + // Account for any extra time we got from the previous frame + this.elapsed = diff; + this.progress = diff / this.duration; + + if (this.flipX) { - ctx.rotate(tile.rotation); + target.toggleFlipX(); } - if (tile.flipX || tile.flipY) + if (this.flipY) { - ctx.scale((tile.flipX) ? -1 : 1, (tile.flipY) ? -1 : 1); + target.toggleFlipY(); } - ctx.globalAlpha = alpha * tile.alpha; + if (isTweenData && (setStart || isYoyo)) + { + this.start = this.getStartValue(target, key, this.start, targetIndex, totalTargets, tween); + } - ctx.drawImage( - image, - tileTexCoords.x, tileTexCoords.y, - tileWidth , tileHeight, - -halfWidth, -halfHeight, - tileWidth, tileHeight - ); + if (isYoyo) + { + this.setPlayingBackwardState(); - ctx.restore(); - } + this.dispatchEvent(Events.TWEEN_YOYO, 'onYoyo'); - ctx.restore(); -}; + return; + } -module.exports = TilemapLayerCanvasRenderer; + this.repeatCounter--; + // Custom + if (isTweenData) + { + this.end = this.getEndValue(target, key, this.start, targetIndex, totalTargets, tween); + } -/***/ }), -/* 1459 */ -/***/ (function(module, exports, __webpack_require__) { + // Delay? + if (this.repeatDelay > 0) + { + this.elapsed = this.repeatDelay - diff; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (isTweenData) + { + this.current = this.start; -var GameObjectCreator = __webpack_require__(16); -var ParseToTilemap = __webpack_require__(262); + target[key] = this.current; + } -/** - * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. - * When loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing - * from a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map - * data. For an empty map, you should specify tileWidth, tileHeight, width & height. - * - * @method Phaser.GameObjects.GameObjectCreator#tilemap - * @since 3.0.0 - * - * @param {Phaser.Types.Tilemaps.TilemapConfig} [config] - The config options for the Tilemap. - * - * @return {Phaser.Tilemaps.Tilemap} - */ -GameObjectCreator.register('tilemap', function (config) -{ - // Defaults are applied in ParseToTilemap - var c = (config !== undefined) ? config : {}; + this.setRepeatState(); + } + else + { + this.setPlayingForwardState(); + + this.dispatchEvent(Events.TWEEN_REPEAT, 'onRepeat'); + } + }, + + /** + * Immediately destroys this TweenData, nulling of all its references. + * + * @method Phaser.Tweens.BaseTweenData#destroy + * @since 3.60.0 + */ + destroy: function () + { + this.tween = null; + this.getDelay = null; + this.setCompleteState(); + } - return ParseToTilemap( - this.scene, - c.key, - c.tileWidth, - c.tileHeight, - c.width, - c.height, - c.data, - c.insertNull - ); }); +module.exports = BaseTweenData; + /***/ }), -/* 1460 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 99730: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GameObjectFactory = __webpack_require__(5); -var ParseToTilemap = __webpack_require__(262); - /** - * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. - * When loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing - * from a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map - * data. For an empty map, you should specify tileWidth, tileHeight, width & height. - * - * @method Phaser.GameObjects.GameObjectFactory#tilemap + * @typedef {object} Phaser.Types.Tweens.TweenConfigDefaults * @since 3.0.0 * - * @param {string} [key] - The key in the Phaser cache that corresponds to the loaded tilemap data. - * @param {number} [tileWidth=32] - The width of a tile in pixels. Pass in `null` to leave as the - * default. - * @param {number} [tileHeight=32] - The height of a tile in pixels. Pass in `null` to leave as the - * default. - * @param {number} [width=10] - The width of the map in tiles. Pass in `null` to leave as the - * default. - * @param {number} [height=10] - The height of the map in tiles. Pass in `null` to leave as the - * default. - * @param {number[][]} [data] - Instead of loading from the cache, you can also load directly from - * a 2D array of tile indexes. Pass in `null` for no data. - * @param {boolean} [insertNull=false] - 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.Tilemap} + * @property {(object|object[])} targets - The object, or an array of objects, to run the tween on. + * @property {number} [delay=0] - The number of milliseconds to delay before the tween will start. + * @property {number} [duration=1000] - The duration of the tween in milliseconds. + * @property {string} [ease='Power0'] - The easing equation to use for the tween. + * @property {array} [easeParams] - Optional easing parameters. + * @property {number} [hold=0] - The number of milliseconds to hold the tween for before yoyo'ing. + * @property {number} [repeat=0] - The number of times to repeat the tween. + * @property {number} [repeatDelay=0] - The number of milliseconds to pause before a tween will repeat. + * @property {boolean} [yoyo=false] - Should the tween complete, then reverse the values incrementally to get back to the starting tween values? The reverse tweening will also take `duration` milliseconds to complete. + * @property {boolean} [flipX=false] - Horizontally flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipX` property. + * @property {boolean} [flipY=false] - Vertically flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipY` property. + * @property {boolean} [persist=false] - Retain the tween within the Tween Manager, even after playback completes? + * @property {function} [interpolation=null] - The interpolation function to use for array-based tween values. */ -GameObjectFactory.register('tilemap', function (key, tileWidth, tileHeight, width, height, data, insertNull) -{ - // Allow users to specify null to indicate that they want the default value, since null is - // shorter & more legible than undefined. Convert null to undefined to allow ParseToTilemap - // defaults to take effect. - - if (key === null) { key = undefined; } - if (tileWidth === null) { tileWidth = undefined; } - if (tileHeight === null) { tileHeight = undefined; } - if (width === null) { width = undefined; } - if (height === null) { height = undefined; } - return ParseToTilemap(this.scene, key, tileWidth, tileHeight, width, height, data, insertNull); -}); +var TWEEN_DEFAULTS = { + targets: null, + delay: 0, + duration: 1000, + ease: 'Power0', + easeParams: null, + hold: 0, + repeat: 0, + repeatDelay: 0, + yoyo: false, + flipX: false, + flipY: false, + persist: false, + interpolation: null +}; -// When registering a factory function 'this' refers to the GameObjectFactory 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 +module.exports = TWEEN_DEFAULTS; /***/ }), -/* 1461 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 53709: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @namespace Phaser.Time - */ - -module.exports = { +// RESERVED properties that a Tween config object uses - Clock: __webpack_require__(1462), - TimerEvent: __webpack_require__(582) +// completeDelay: The time the tween will wait before the onComplete event is dispatched once it has completed +// delay: The time the tween will wait before it first starts +// duration: The duration of the tween +// ease: The ease function used by the tween +// easeParams: The parameters to go with the ease function (if any) +// flipX: flip X the GameObject on tween end +// flipY: flip Y the GameObject on tween end +// hold: The time the tween will pause before running a yoyo +// loop: The time the tween will pause before starting either a yoyo or returning to the start for a repeat +// loopDelay: +// paused: Does the tween start in a paused state, or playing? +// props: The properties being tweened by the tween +// repeat: The number of times the tween will repeat itself (a value of 1 means the tween will play twice, as it repeated once) +// repeatDelay: The time the tween will pause for before starting a repeat. The tween holds in the start state. +// targets: The targets the tween is updating. +// yoyo: boolean - Does the tween reverse itself (yoyo) when it reaches the end? -}; +module.exports = [ + 'callbackScope', + 'completeDelay', + 'delay', + 'duration', + 'ease', + 'easeParams', + 'flipX', + 'flipY', + 'hold', + 'interpolation', + 'loop', + 'loopDelay', + 'onActive', + 'onActiveParams', + 'onComplete', + 'onCompleteParams', + 'onLoop', + 'onLoopParams', + 'onPause', + 'onPauseParams', + 'onRepeat', + 'onRepeatParams', + 'onResume', + 'onResumeParams', + 'onStart', + 'onStartParams', + 'onStop', + 'onStopParams', + 'onUpdate', + 'onUpdateParams', + 'onYoyo', + 'onYoyoParams', + 'paused', + 'persist', + 'props', + 'repeat', + 'repeatDelay', + 'targets', + 'yoyo' +]; /***/ }), -/* 1462 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 39366: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Class = __webpack_require__(0); -var PluginCache = __webpack_require__(24); -var SceneEvents = __webpack_require__(20); -var TimerEvent = __webpack_require__(582); -var Remove = __webpack_require__(93); +var BaseTween = __webpack_require__(502); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(54272); +var GameObjectCreator = __webpack_require__(99325); +var GameObjectFactory = __webpack_require__(61286); +var MATH_CONST = __webpack_require__(83392); +var TWEEN_CONST = __webpack_require__(55303); +var TweenData = __webpack_require__(15718); +var TweenFrameData = __webpack_require__(96490); /** * @classdesc - * The Clock is a Scene plugin which creates and updates Timer Events for its Scene. + * A Tween is able to manipulate the properties of one or more objects to any given value, based + * on a duration and type of ease. They are rarely instantiated directly and instead should be + * created via the TweenManager. * - * @class Clock - * @memberof Phaser.Time + * Please note that a Tween will not manipulate any property that begins with an underscore. + * + * @class Tween + * @memberof Phaser.Tweens + * @extends Phaser.Tweens.BaseTween * @constructor * @since 3.0.0 * - * @param {Phaser.Scene} scene - The Scene which owns this Clock. + * @param {Phaser.Tweens.TweenManager} parent - A reference to the Tween Manager that owns this Tween. + * @param {object[]} targets - An array of targets to be tweened. */ -var Clock = new Class({ +var Tween = new Class({ + + Extends: BaseTween, initialize: - function Clock (scene) + function Tween (parent, targets) { + BaseTween.call(this, parent); + /** - * The Scene which owns this Clock. + * An array of references to the target/s this Tween is operating on. * - * @name Phaser.Time.Clock#scene - * @type {Phaser.Scene} + * This array should not be manipulated outside of this Tween. + * + * @name Phaser.Tweens.Tween#targets + * @type {object[]} * @since 3.0.0 */ - this.scene = scene; + this.targets = targets; /** - * The Scene Systems object of the Scene which owns this Clock. + * Cached target total. * - * @name Phaser.Time.Clock#systems - * @type {Phaser.Scenes.Systems} + * Used internally and should be treated as read-only. + * + * This is not necessarily the same as the data total. + * + * @name Phaser.Tweens.Tween#totalTargets + * @type {number} * @since 3.0.0 */ - this.systems = scene.sys; + this.totalTargets = targets.length; /** - * The current time of the Clock, in milliseconds. + * Is this Tween currently seeking? * - * If accessed externally, this is equivalent to the `time` parameter normally passed to a Scene's `update` method. + * This boolean is toggled in the `Tween.seek` method. * - * @name Phaser.Time.Clock#now - * @type {number} - * @since 3.0.0 + * When a tween is seeking, by default it will not dispatch any events or callbacks. + * + * @name Phaser.Tweens.Tween#isSeeking + * @type {boolean} + * @readonly + * @since 3.19.0 */ - this.now = 0; + this.isSeeking = false; /** - * The scale of the Clock's time delta. + * Does this Tween loop or repeat infinitely? * - * The time delta is the time elapsed between two consecutive frames and influences the speed of time for this Clock and anything which uses it, such as its Timer Events. Values higher than 1 increase the speed of time, while values smaller than 1 decrease it. A value of 0 freezes time and is effectively equivalent to pausing the Clock. + * @name Phaser.Tweens.Tween#isInfinite + * @type {boolean} + * @readonly + * @since 3.60.0 + */ + this.isInfinite = false; + + /** + * Elapsed time in milliseconds of this run through of the Tween. * - * @name Phaser.Time.Clock#timeScale + * @name Phaser.Tweens.Tween#elapsed * @type {number} - * @default 1 - * @since 3.0.0 + * @default 0 + * @since 3.60.0 */ - this.timeScale = 1; + this.elapsed = 0; /** - * Whether the Clock is paused (`true`) or active (`false`). + * Total elapsed time in milliseconds of the entire Tween, including looping. * - * When paused, the Clock will not update any of its Timer Events, thus freezing time. + * @name Phaser.Tweens.Tween#totalElapsed + * @type {number} + * @default 0 + * @since 3.60.0 + */ + this.totalElapsed = 0; + + /** + * Time in milliseconds for the whole Tween to play through once, excluding loop amounts and loop delays. * - * @name Phaser.Time.Clock#paused - * @type {boolean} - * @default false - * @since 3.0.0 + * This value is set in the `Tween.initTweenData` method and is zero before that point. + * + * @name Phaser.Tweens.Tween#duration + * @type {number} + * @default 0 + * @since 3.60.0 */ - this.paused = false; + this.duration = 0; /** - * An array of all Timer Events whose delays haven't expired - these are actively updating Timer Events. + * Value between 0 and 1. The amount of progress through the Tween, excluding loops. * - * @name Phaser.Time.Clock#_active - * @type {Phaser.Time.TimerEvent[]} - * @private - * @default [] - * @since 3.0.0 + * @name Phaser.Tweens.Tween#progress + * @type {number} + * @default 0 + * @since 3.60.0 */ - this._active = []; + this.progress = 0; /** - * An array of all Timer Events which will be added to the Clock at the start of the next frame. + * Time in milliseconds it takes for the Tween to complete a full playthrough (including looping) * - * @name Phaser.Time.Clock#_pendingInsertion - * @type {Phaser.Time.TimerEvent[]} - * @private - * @default [] - * @since 3.0.0 + * For an infinite Tween, this value is a very large integer. + * + * @name Phaser.Tweens.Tween#totalDuration + * @type {number} + * @default 0 + * @since 3.60.0 */ - this._pendingInsertion = []; + this.totalDuration = 0; /** - * An array of all Timer Events which will be removed from the Clock at the start of the next frame. + * The amount of progress that has been made through the entire Tween, including looping. * - * @name Phaser.Time.Clock#_pendingRemoval - * @type {Phaser.Time.TimerEvent[]} - * @private - * @default [] - * @since 3.0.0 + * A value between 0 and 1. + * + * @name Phaser.Tweens.Tween#totalProgress + * @type {number} + * @default 0 + * @since 3.60.0 */ - this._pendingRemoval = []; + this.totalProgress = 0; + }, - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); - scene.sys.events.on(SceneEvents.START, this.start, this); + /** + * Adds a new TweenData to this Tween. Typically, this method is called + * automatically by the TweenBuilder, however you can also invoke it + * yourself. + * + * @method Phaser.Tweens.Tween#add + * @since 3.60.0 + * + * @param {number} targetIndex - The target index within the Tween targets array. + * @param {string} key - The property of the target to tween. + * @param {Phaser.Types.Tweens.GetEndCallback} getEnd - What the property will be at the END of the Tween. + * @param {Phaser.Types.Tweens.GetStartCallback} getStart - What the property will be at the START of the Tween. + * @param {?Phaser.Types.Tweens.GetActiveCallback} getActive - If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. + * @param {function} ease - The ease function this tween uses. + * @param {function} delay - Function that returns the time in milliseconds before tween will start. + * @param {number} duration - The duration of the tween in milliseconds. + * @param {boolean} yoyo - Determines whether the tween should return back to its start value after hold has expired. + * @param {number} hold - Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param {number} repeat - Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param {number} repeatDelay - Function that returns the time in milliseconds before the repeat will start. + * @param {boolean} flipX - Should toggleFlipX be called when yoyo or repeat happens? + * @param {boolean} flipY - Should toggleFlipY be called when yoyo or repeat happens? + * @param {?function} interpolation - The interpolation function to be used for arrays of data. Defaults to 'null'. + * @param {?number[]} interpolationData - The array of interpolation data to be set. Defaults to 'null'. + * + * @return {Phaser.Tweens.TweenData} The TweenData instance that was added. + */ + add: function (targetIndex, key, getEnd, getStart, getActive, ease, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY, interpolation, interpolationData) + { + var tweenData = new TweenData(this, targetIndex, key, getEnd, getStart, getActive, ease, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY, interpolation, interpolationData); + + this.totalData = this.data.push(tweenData); + + return tweenData; }, /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. + * Adds a new TweenFrameData to this Tween. Typically, this method is called + * automatically by the TweenBuilder, however you can also invoke it + * yourself. * - * @method Phaser.Time.Clock#boot - * @private - * @since 3.5.1 + * @method Phaser.Tweens.Tween#addFrame + * @since 3.60.0 + * + * @param {number} targetIndex - The target index within the Tween targets array. + * @param {string} texture - The texture to set on the target at the end of the tween. + * @param {string|number} frame - The texture frame to set on the target at the end of the tween. + * @param {function} delay - Function that returns the time in milliseconds before tween will start. + * @param {number} duration - The duration of the tween in milliseconds. + * @param {number} hold - Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param {number} repeat - Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param {number} repeatDelay - Function that returns the time in milliseconds before the repeat will start. + * @param {boolean} flipX - Should toggleFlipX be called when yoyo or repeat happens? + * @param {boolean} flipY - Should toggleFlipY be called when yoyo or repeat happens? + * + * @return {Phaser.Tweens.TweenFrameData} The TweenFrameData instance that was added. */ - boot: function () + addFrame: function (targetIndex, texture, frame, delay, duration, hold, repeat, repeatDelay, flipX, flipY) { - // Sync with the TimeStep - this.now = this.systems.game.loop.time; + var tweenData = new TweenFrameData(this, targetIndex, texture, frame, delay, duration, hold, repeat, repeatDelay, flipX, flipY); - this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); + this.totalData = this.data.push(tweenData); + + return tweenData; }, /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. + * Returns the current value of the specified Tween Data. * - * @method Phaser.Time.Clock#start - * @private - * @since 3.5.0 + * If this Tween has been destroyed, it will return `null`. + * + * @method Phaser.Tweens.Tween#getValue + * @since 3.0.0 + * + * @param {number} [index=0] - The Tween Data to return the value from. + * + * @return {number} The value of the requested Tween Data, or `null` if this Tween has been destroyed. */ - start: function () + getValue: function (index) { - var eventEmitter = this.systems.events; + if (index === undefined) { index = 0; } - eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this); - eventEmitter.on(SceneEvents.UPDATE, this.update, this); - eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); + var value = null; + + if (this.data) + { + value = this.data[index].current; + } + + return value; }, /** - * Creates a Timer Event and adds it to this Clock at the start of the next frame. + * See if this Tween is currently acting upon the given target. * - * You can pass in either a `TimerEventConfig` object, from with a new `TimerEvent` will - * be created, or you can pass in a `TimerEvent` instance. + * @method Phaser.Tweens.Tween#hasTarget + * @since 3.0.0 * - * If passing an instance please make sure that this instance hasn't been used before. - * If it has ever entered a 'completed' state then it will no longer be suitable to - * run again. + * @param {object} target - The target to check against this Tween. * - * Also, if the `TimerEvent` instance is being used by _another_ Clock (in another Scene) - * it will still be updated by that Clock as well, so be careful when using this feature. + * @return {boolean} `true` if the given target is a target of this Tween, otherwise `false`. + */ + hasTarget: function (target) + { + return (this.targets && this.targets.indexOf(target) !== -1); + }, + + /** + * Updates the 'end' value of the given property across all matching targets, as long + * as this Tween is currently playing (either forwards or backwards). * - * @method Phaser.Time.Clock#addEvent + * Calling this does not adjust the duration of the Tween, or the current progress. + * + * You can optionally tell it to set the 'start' value to be the current value. + * + * If this Tween is in any other state other than playing then calling this method has no effect. + * + * Additionally, if the Tween repeats, is reset, or is seeked, it will revert to the original + * starting and ending values. + * + * @method Phaser.Tweens.Tween#updateTo * @since 3.0.0 * - * @param {(Phaser.Time.TimerEvent | Phaser.Types.Time.TimerEventConfig)} config - The configuration for the Timer Event, or an existing Timer Event object. + * @param {string} key - The property to set the new value for. You cannot update the 'texture' property via this method. + * @param {number} value - The new value of the property. + * @param {boolean} [startToCurrent=false] - Should this change set the start value to be the current value? * - * @return {Phaser.Time.TimerEvent} The Timer Event which was created, or passed in. + * @return {this} This Tween instance. */ - addEvent: function (config) + updateTo: function (key, value, startToCurrent) { - var event; + if (startToCurrent === undefined) { startToCurrent = false; } + + if (key !== 'texture') + { + for (var i = 0; i < this.totalData; i++) + { + var tweenData = this.data[i]; + + if (tweenData.key === key && (tweenData.isPlayingForward() || tweenData.isPlayingBackward())) + { + tweenData.end = value; + + if (startToCurrent) + { + tweenData.start = tweenData.current; + } + } + } + } + + return this; + }, + + /** + * Restarts the Tween from the beginning. + * + * If the Tween has already finished and been destroyed, restarting it will throw an error. + * + * If you wish to restart the Tween from a specific point, use the `Tween.seek` method instead. + * + * @method Phaser.Tweens.Tween#restart + * @since 3.0.0 + * + * @return {this} This Tween instance. + */ + restart: function () + { + switch (this.state) + { + case TWEEN_CONST.REMOVED: + case TWEEN_CONST.FINISHED: + this.seek(); + this.parent.makeActive(this); + break; + + case TWEEN_CONST.PENDING: + case TWEEN_CONST.PENDING_REMOVE: + this.parent.reset(this); + break; + + case TWEEN_CONST.DESTROYED: + console.warn('Cannot restart destroyed Tween', this); + break; + + default: + this.seek(); + break; + } + + this.paused = false; + this.hasStarted = false; + + return this; + }, + + /** + * Internal method that advances to the next state of the Tween during playback. + * + * @method Phaser.Tweens.Tween#nextState + * @fires Phaser.Tweens.Events#TWEEN_COMPLETE + * @fires Phaser.Tweens.Events#TWEEN_LOOP + * @since 3.0.0 + * + * @return {boolean} `true` if this Tween has completed, otherwise `false`. + */ + nextState: function () + { + if (this.loopCounter > 0) + { + this.elapsed = 0; + this.progress = 0; + this.loopCounter--; + + this.initTweenData(true); + + if (this.loopDelay > 0) + { + this.countdown = this.loopDelay; - if (config instanceof TimerEvent) - { - event = config; + this.setLoopDelayState(); + } + else + { + this.setActiveState(); - this.removeEvent(event); + this.dispatchEvent(Events.TWEEN_LOOP, 'onLoop'); + } + } + else if (this.completeDelay > 0) + { + this.countdown = this.completeDelay; - event.elapsed = event.startAt; - event.hasDispatched = false; - event.repeatCount = (event.repeat === -1 || event.loop) ? 999999999999 : event.repeat; + this.setCompleteDelayState(); } else { - event = new TimerEvent(config); - } + this.onCompleteHandler(); - this._pendingInsertion.push(event); + return true; + } - return event; + return false; }, /** - * Creates a Timer Event and adds it to the Clock at the start of the frame. - * - * This is a shortcut for {@link #addEvent} which can be shorter and is compatible with the syntax of the GreenSock Animation Platform (GSAP). - * - * @method Phaser.Time.Clock#delayedCall - * @since 3.0.0 - * - * @param {number} delay - The delay of the function call, in milliseconds. - * @param {function} callback - The function to call after the delay expires. - * @param {Array.<*>} [args] - The arguments to call the function with. - * @param {*} [callbackScope] - The scope (`this` object) to call the function with. + * Internal method that handles this tween completing and starting + * the next tween in the chain, if any. * - * @return {Phaser.Time.TimerEvent} The Timer Event which was created. + * @method Phaser.Tweens.Tween#onCompleteHandler + * @since 3.60.0 */ - delayedCall: function (delay, callback, args, callbackScope) + onCompleteHandler: function () { - return this.addEvent({ delay: delay, callback: callback, args: args, callbackScope: callbackScope }); + this.progress = 1; + this.totalProgress = 1; + + BaseTween.prototype.onCompleteHandler.call(this); }, /** - * Clears and recreates the array of pending Timer Events. + * Starts a Tween playing. * - * @method Phaser.Time.Clock#clearPendingEvents + * You only need to call this method if you have configured the tween to be paused on creation. + * + * If the Tween is already playing, calling this method again will have no effect. If you wish to + * restart the Tween, use `Tween.restart` instead. + * + * Calling this method after the Tween has completed will start the Tween playing again from the beginning. + * This is the same as calling `Tween.seek(0)` and then `Tween.play()`. + * + * @method Phaser.Tweens.Tween#play * @since 3.0.0 * - * @return {this} - This Clock instance. + * @return {this} This Tween instance. */ - clearPendingEvents: function () + play: function () { - this._pendingInsertion = []; + if (this.isDestroyed()) + { + console.warn('Cannot play destroyed Tween', this); + + return this; + } + + if (this.isPendingRemove() || this.isFinished()) + { + this.seek(); + } + + this.paused = false; + + this.setActiveState(); return this; }, /** - * Removes the given Timer Event, or an array of Timer Events, from this Clock. + * Seeks to a specific point in the Tween. * - * The events are removed from all internal lists (active, pending and removal), - * freeing the event up to be re-used. + * The given amount is a value in milliseconds that represents how far into the Tween + * you wish to seek, based on the start of the Tween. * - * @method Phaser.Time.Clock#removeEvent - * @since 3.50.0 + * Note that the seek amount takes the entire duration of the Tween into account, including delays, loops and repeats. + * For example, a Tween that lasts for 2 seconds, but that loops 3 times, would have a total duration of 6 seconds, + * so seeking to 3000 ms would seek to the Tweens half-way point based on its _entire_ duration. * - * @param {(Phaser.Time.TimerEvent | Phaser.Time.TimerEvent[])} events - The Timer Event, or an array of Timer Events, to remove from this Clock. + * Prior to Phaser 3.60 this value was given as a number between 0 and 1 and didn't + * work for Tweens had an infinite repeat. This new method works for all Tweens. * - * @return {this} - This Clock instance. + * Seeking works by resetting the Tween to its initial values and then iterating through the Tween at `delta` + * jumps per step. The longer the Tween, the longer this can take. If you need more precision you can + * reduce the delta value. If you need a faster seek, you can increase it. When the Tween is + * reset it will refresh the starting and ending values. If these are coming from a dynamic function, + * or a random array, it will be called for each seek. + * + * While seeking the Tween will _not_ emit any of its events or callbacks unless + * the 3rd parameter is set to `true`. + * + * If this Tween is paused, seeking will not change this fact. It will advance the Tween + * to the desired point and then pause it again. + * + * @method Phaser.Tweens.Tween#seek + * @since 3.0.0 + * + * @param {number} [amount=0] - The number of milliseconds to seek into the Tween from the beginning. + * @param {number} [delta=16.6] - The size of each step when seeking through the Tween. A higher value completes faster but at the cost of less precision. + * @param {boolean} [emit=false] - While seeking, should the Tween emit any of its events or callbacks? The default is 'false', i.e. to seek silently. + * + * @return {this} This Tween instance. */ - removeEvent: function (events) + seek: function (amount, delta, emit) { - if (!Array.isArray(events)) + if (amount === undefined) { amount = 0; } + if (delta === undefined) { delta = 16.6; } + if (emit === undefined) { emit = false; } + + if (this.isDestroyed()) { - events = [ events ]; + console.warn('Cannot seek destroyed Tween', this); + + return this; } - for (var i = 0; i < events.length; i++) + if (!emit) { - var event = events[i]; + this.isSeeking = true; + } - Remove(this._pendingRemoval, event); - Remove(this._pendingInsertion, event); - Remove(this._active, event); + this.reset(true); + + this.initTweenData(true); + + this.setActiveState(); + + this.dispatchEvent(Events.TWEEN_ACTIVE, 'onActive'); + + var isPaused = this.paused; + + this.paused = false; + + if (amount > 0) + { + var iterations = Math.floor(amount / delta); + var remainder = amount - (iterations * delta); + + for (var i = 0; i < iterations; i++) + { + this.update(delta); + } + + if (remainder > 0) + { + this.update(remainder); + } } - return this; - }, + this.paused = isPaused; - /** - * Schedules all active Timer Events for removal at the start of the frame. - * - * @method Phaser.Time.Clock#removeAllEvents - * @since 3.0.0 - * - * @return {this} - This Clock instance. - */ - removeAllEvents: function () - { - this._pendingRemoval = this._pendingRemoval.concat(this._active); + this.isSeeking = false; return this; }, /** - * Updates the arrays of active and pending Timer Events. Called at the start of the frame. + * Initialises all of the Tween Data and Tween values. * - * @method Phaser.Time.Clock#preUpdate - * @since 3.0.0 + * This is called automatically and should not typically be invoked directly. * - * @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. + * @method Phaser.Tweens.Tween#initTweenData + * @since 3.60.0 + * + * @param {boolean} [isSeeking=false] - Is the Tween Data being reset as part of a seek? */ - preUpdate: function () + initTweenData: function (isSeeking) { - var toRemove = this._pendingRemoval.length; - var toInsert = this._pendingInsertion.length; + if (isSeeking === undefined) { isSeeking = false; } - if (toRemove === 0 && toInsert === 0) + // These two values are updated directly during TweenData.reset: + this.duration = 0; + this.startDelay = MATH_CONST.MAX_SAFE_INTEGER; + + var data = this.data; + + for (var i = 0; i < this.totalData; i++) { - // Quick bail - return; + data[i].reset(isSeeking); } - var i; - var event; + // Clamp duration to ensure we never divide by zero + this.duration = Math.max(this.duration, 0.01); - // Delete old events - for (i = 0; i < toRemove; i++) + var duration = this.duration; + var completeDelay = this.completeDelay; + var loopCounter = this.loopCounter; + var loopDelay = this.loopDelay; + + if (loopCounter > 0) { - event = this._pendingRemoval[i]; + this.totalDuration = duration + completeDelay + ((duration + loopDelay) * loopCounter); + } + else + { + this.totalDuration = duration + completeDelay; + } + }, - var index = this._active.indexOf(event); + /** + * Resets this Tween ready for another play-through. + * + * This is called automatically from the Tween Manager, or from the parent TweenChain, + * and should not typically be invoked directly. + * + * If you wish to restart this Tween, use the `Tween.restart` or `Tween.seek` methods instead. + * + * @method Phaser.Tweens.Tween#reset + * @fires Phaser.Tweens.Events#TWEEN_ACTIVE + * @since 3.60.0 + * + * @param {boolean} [skipInit=false] - Skip resetting the TweenData and Active State? + * + * @return {this} This Tween instance. + */ + reset: function (skipInit) + { + if (skipInit === undefined) { skipInit = false; } - if (index > -1) - { - this._active.splice(index, 1); - } + this.elapsed = 0; + this.totalElapsed = 0; + this.progress = 0; + this.totalProgress = 0; + this.loopCounter = this.loop; - // Pool them? - event.destroy(); + if (this.loop === -1) + { + this.isInfinite = true; + this.loopCounter = TWEEN_CONST.MAX; } - for (i = 0; i < toInsert; i++) + if (!skipInit) { - event = this._pendingInsertion[i]; + this.initTweenData(); - this._active.push(event); + this.setActiveState(); + + this.dispatchEvent(Events.TWEEN_ACTIVE, 'onActive'); } - // Clear the lists - this._pendingRemoval.length = 0; - this._pendingInsertion.length = 0; + return this; }, /** - * Updates the Clock's internal time and all of its Timer Events. + * Internal method that advances the Tween based on the time values. * - * @method Phaser.Time.Clock#update + * @method Phaser.Tweens.Tween#update + * @fires Phaser.Tweens.Events#TWEEN_COMPLETE + * @fires Phaser.Tweens.Events#TWEEN_LOOP + * @fires Phaser.Tweens.Events#TWEEN_START * @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. + * + * @return {boolean} Returns `true` if this Tween has finished and should be removed from the Tween Manager, otherwise returns `false`. */ - update: function (time, delta) + update: function (delta) { - this.now = time; - - if (this.paused) + if (this.isPendingRemove() || this.isDestroyed()) { - return; + return true; + } + else if (this.paused || this.isFinished()) + { + return false; } - delta *= this.timeScale; + delta *= this.timeScale * this.parent.timeScale; - for (var i = 0; i < this._active.length; i++) + if (this.isLoopDelayed()) { - var event = this._active[i]; + this.updateLoopCountdown(delta); - if (event.paused) - { - continue; - } + return false; + } + else if (this.isCompleteDelayed()) + { + this.updateCompleteDelay(delta); - // Use delta time to increase elapsed. - // Avoids needing to adjust for pause / resume. - // Automatically smoothed by TimeStep class. - // In testing accurate to +- 1ms! - event.elapsed += delta * event.timeScale; + return false; + } + else if (!this.hasStarted) + { + this.startDelay -= delta; - if (event.elapsed >= event.delay) + if (this.startDelay <= 0) { - var remainder = event.elapsed - event.delay; + this.hasStarted = true; - // Limit it, in case it's checked in the callback - event.elapsed = event.delay; + this.dispatchEvent(Events.TWEEN_START, 'onStart'); - // Process the event - if (!event.hasDispatched && event.callback) - { - event.hasDispatched = true; - event.callback.apply(event.callbackScope, event.args); - } + // Reset the delta so we always start progress from zero + delta = 0; + } + } - if (event.repeatCount > 0) - { - event.repeatCount--; + var stillRunning = false; - event.elapsed = remainder; - event.hasDispatched = false; - } - else + if (this.isActive()) + { + var data = this.data; + + for (var i = 0; i < this.totalData; i++) + { + if (data[i].update(delta)) { - this._pendingRemoval.push(event); + stillRunning = true; } } } + + this.elapsed += delta; + this.progress = Math.min(this.elapsed / this.duration, 1); + + this.totalElapsed += delta; + this.totalProgress = Math.min(this.totalElapsed / this.totalDuration, 1); + + // Anything still running? If not, we're done + if (!stillRunning) + { + // This calls onCompleteHandler if this tween is over + this.nextState(); + } + + // if nextState called onCompleteHandler then we're ready to be removed, unless we persist + var remove = this.isPendingRemove(); + + if (remove && this.persist) + { + this.setFinishedState(); + + remove = false; + } + + return remove; }, /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. + * Moves this Tween forward by the given amount of milliseconds. * - * @method Phaser.Time.Clock#shutdown - * @private - * @since 3.0.0 + * It will only advance through the current loop of the Tween. For example, if the + * Tween is set to repeat or yoyo, it can only fast forward through a single + * section of the sequence. Use `Tween.seek` for more complex playhead control. + * + * If the Tween is paused or has already finished, calling this will have no effect. + * + * @method Phaser.Tweens.Tween#forward + * @since 3.60.0 + * + * @param {number} ms - The number of milliseconds to advance this Tween by. + * + * @return {this} This Tween instance. */ - shutdown: function () + forward: function (ms) { - var i; + this.update(ms); - for (i = 0; i < this._pendingInsertion.length; i++) - { - this._pendingInsertion[i].destroy(); - } + return this; + }, - for (i = 0; i < this._active.length; i++) - { - this._active[i].destroy(); - } + /** + * Moves this Tween backward by the given amount of milliseconds. + * + * It will only rewind through the current loop of the Tween. For example, if the + * Tween is set to repeat or yoyo, it can only fast forward through a single + * section of the sequence. Use `Tween.seek` for more complex playhead control. + * + * If the Tween is paused or has already finished, calling this will have no effect. + * + * @method Phaser.Tweens.Tween#rewind + * @since 3.60.0 + * + * @param {number} ms - The number of milliseconds to rewind this Tween by. + * + * @return {this} This Tween instance. + */ + rewind: function (ms) + { + this.update(-ms); - for (i = 0; i < this._pendingRemoval.length; i++) - { - this._pendingRemoval[i].destroy(); - } + return this; + }, - this._active.length = 0; - this._pendingRemoval.length = 0; - this._pendingInsertion.length = 0; + /** + * Internal method that will emit a Tween based Event and invoke the given callback. + * + * @method Phaser.Tweens.Tween#dispatchEvent + * @since 3.60.0 + * + * @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched. + * @param {Phaser.Types.Tweens.TweenCallbackTypes} [callback] - The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation. + */ + dispatchEvent: function (event, callback) + { + if (!this.isSeeking) + { + this.emit(event, this, this.targets); - var eventEmitter = this.systems.events; + var handler = this.callbacks[callback]; - eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this); - eventEmitter.off(SceneEvents.UPDATE, this.update, this); - eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); + if (handler) + { + handler.func.apply(this.callbackScope, [ this, this.targets ].concat(handler.params)); + } + } }, /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. + * Handles the destroy process of this Tween, clearing out the + * Tween Data and resetting the targets. A Tween that has been + * destroyed cannot ever be played or used again. * - * @method Phaser.Time.Clock#destroy - * @private - * @since 3.0.0 + * @method Phaser.Tweens.Tween#destroy + * @since 3.60.0 */ destroy: function () { - this.shutdown(); - - this.scene.sys.events.off(SceneEvents.START, this.start, this); + BaseTween.prototype.destroy.call(this); - this.scene = null; - this.systems = null; + this.targets = null; } }); -PluginCache.register('Clock', Clock, 'time'); +/** + * Creates a new Tween object. + * + * Note: This method will only be available if Tweens have been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#tween + * @since 3.0.0 + * + * @param {Phaser.Types.Tweens.TweenBuilderConfig|Phaser.Types.Tweens.TweenChainBuilderConfig|Phaser.Tweens.Tween|Phaser.Tweens.TweenChain} config - A Tween Configuration object, or a Tween or TweenChain instance. + * + * @return {Phaser.Tweens.Tween} The Tween that was created. + */ +GameObjectFactory.register('tween', function (config) +{ + return this.scene.sys.tweens.add(config); +}); -module.exports = Clock; +/** + * Creates a new Tween object and returns it. + * + * Note: This method will only be available if Tweens have been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#tween + * @since 3.0.0 + * + * @param {Phaser.Types.Tweens.TweenBuilderConfig|Phaser.Types.Tweens.TweenChainBuilderConfig|Phaser.Tweens.Tween|Phaser.Tweens.TweenChain} config - A Tween Configuration object, or a Tween or TweenChain instance. + * + * @return {Phaser.Tweens.Tween} The Tween that was created. + */ +GameObjectCreator.register('tween', function (config) +{ + return this.scene.sys.tweens.create(config); +}); + +module.exports = Tween; /***/ }), -/* 1463 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 45641: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(100); -var Extend = __webpack_require__(17); +var ArrayRemove = __webpack_require__(66458); +var BaseTween = __webpack_require__(502); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(54272); +var GameObjectCreator = __webpack_require__(99325); +var GameObjectFactory = __webpack_require__(61286); +var TWEEN_CONST = __webpack_require__(55303); /** - * @namespace Phaser.Tweens + * @classdesc + * A TweenChain is a special type of Tween that allows you to create a sequence of Tweens, chained to one-another, + * and add them to the Tween Manager. + * + * The tweens are played in order, from start to finish. You can optionally set the chain + * to repeat as many times as you like. Once the chain has finished playing, or repeating if set, + * all tweens in the chain will be destroyed automatically. To override this, set the 'persists' + * argument to 'true'. + * + * Playback will start immediately unless the _first_ Tween has been configured to be paused. + * + * Please note that Tweens will not manipulate any target property that begins with an underscore. + * + * @class TweenChain + * @memberof Phaser.Tweens + * @extends Phaser.Tweens.BaseTween + * @constructor + * @since 3.60.0 + * + * @param {(Phaser.Tweens.TweenManager|Phaser.Tweens.TweenChain)} parent - A reference to the Tween Manager, or TweenChain, that owns this TweenChain. */ +var TweenChain = new Class({ -var Tweens = { - - Builders: __webpack_require__(1464), - Events: __webpack_require__(267), - - TweenManager: __webpack_require__(1480), - Tween: __webpack_require__(266), - TweenData: __webpack_require__(268), - Timeline: __webpack_require__(588) + Extends: BaseTween, -}; - -// Merge in the consts -Tweens = Extend(false, Tweens, CONST); + initialize: -module.exports = Tweens; + function TweenChain (parent) + { + BaseTween.call(this, parent); + /** + * A reference to the Tween that this TweenChain is currently playing. + * + * @name Phaser.Tweens.TweenChain#currentTween + * @type {Phaser.Tweens.Tween} + * @since 3.60.0 + */ + this.currentTween = null; -/***/ }), -/* 1464 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * A reference to the data array index of the currently playing tween. + * + * @name Phaser.Tweens.TweenChain#currentIndex + * @type {number} + * @since 3.60.0 + */ + this.currentIndex = 0; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Prepares this TweenChain for playback. + * + * Called automatically by the TweenManager. Should not be called directly. + * + * @method Phaser.Tweens.TweenChain#init + * @fires Phaser.Tweens.Events#TWEEN_ACTIVE + * @since 3.60.0 + * + * @return {this} This TweenChain instance. + */ + init: function () + { + this.loopCounter = (this.loop === -1) ? TWEEN_CONST.MAX : this.loop; -/** - * @namespace Phaser.Tweens.Builders - */ + this.setCurrentTween(0); -module.exports = { + if (this.startDelay > 0 && !this.isStartDelayed()) + { + this.setStartDelayState(); + } + else + { + this.setActiveState(); + } - GetBoolean: __webpack_require__(99), - GetEaseFunction: __webpack_require__(80), - GetNewValue: __webpack_require__(162), - GetProps: __webpack_require__(583), - GetTargets: __webpack_require__(263), - GetTweens: __webpack_require__(584), - GetValueOp: __webpack_require__(264), - NumberTweenBuilder: __webpack_require__(585), - StaggerBuilder: __webpack_require__(586), - TimelineBuilder: __webpack_require__(587), - TweenBuilder: __webpack_require__(163) + this.dispatchEvent(Events.TWEEN_ACTIVE, 'onActive'); -}; + return this; + }, + /** + * Create a sequence of Tweens, chained to one-another, and add them to this Tween Manager. + * + * The tweens are played in order, from start to finish. You can optionally set the chain + * to repeat as many times as you like. Once the chain has finished playing, or repeating if set, + * all tweens in the chain will be destroyed automatically. To override this, set the 'persists' + * argument to 'true'. + * + * Playback will start immediately unless the _first_ Tween has been configured to be paused. + * + * Please note that Tweens will not manipulate any target property that begins with an underscore. + * + * @method Phaser.Tweens.TweenChain#add + * @since 3.60.0 + * + * @param {Phaser.Types.Tweens.TweenBuilderConfig[]|object[]} tweens - An array of Tween configuration objects for the Tweens in this chain. + * + * @return {this} This TweenChain instance. + */ + add: function (tweens) + { + var newTweens = this.parent.create(tweens); -/***/ }), -/* 1465 */ -/***/ (function(module, exports) { + if (!Array.isArray(newTweens)) + { + newTweens = [ newTweens ]; + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var data = this.data; -// RESERVED properties that a Tween config object uses + for (var i = 0; i < newTweens.length; i++) + { + var tween = newTweens[i]; -// completeDelay: The time the tween will wait before the onComplete event is dispatched once it has completed -// delay: The time the tween will wait before it first starts -// duration: The duration of the tween -// ease: The ease function used by the tween -// easeParams: The parameters to go with the ease function (if any) -// flipX: flip X the GameObject on tween end -// flipY: flip Y the GameObject on tween end// hold: The time the tween will pause before running a yoyo -// hold: The time the tween will pause before running a yoyo -// loop: The time the tween will pause before starting either a yoyo or returning to the start for a repeat -// loopDelay: -// offset: Used when the Tween is part of a Timeline -// paused: Does the tween start in a paused state, or playing? -// props: The properties being tweened by the tween -// repeat: The number of times the tween will repeat itself (a value of 1 means the tween will play twice, as it repeated once) -// repeatDelay: The time the tween will pause for before starting a repeat. The tween holds in the start state. -// targets: The targets the tween is updating. -// useFrames: Use frames or milliseconds? -// yoyo: boolean - Does the tween reverse itself (yoyo) when it reaches the end? + tween.parent = this; -module.exports = [ - 'callbackScope', - 'completeDelay', - 'delay', - 'duration', - 'ease', - 'easeParams', - 'flipX', - 'flipY', - 'hold', - 'loop', - 'loopDelay', - 'offset', - 'onActive', - 'onActiveParams', - 'onActiveScope', - 'onComplete', - 'onCompleteParams', - 'onCompleteScope', - 'onLoop', - 'onLoopParams', - 'onLoopScope', - 'onRepeat', - 'onRepeatParams', - 'onRepeatScope', - 'onStart', - 'onStartParams', - 'onStartScope', - 'onStop', - 'onStopParams', - 'onStopScope', - 'onUpdate', - 'onUpdateParams', - 'onUpdateScope', - 'onYoyo', - 'onYoyoParams', - 'onYoyoScope', - 'paused', - 'props', - 'repeat', - 'repeatDelay', - 'targets', - 'useFrames', - 'yoyo' -]; + data.push(tween.reset()); + } + this.totalData = data.length; -/***/ }), -/* 1466 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Removes the given Tween from this Tween Chain. + * + * The removed tween is _not_ destroyed. It is just removed from this Tween Chain. + * + * If the given Tween is currently playing then the chain will automatically move + * to the next tween in the chain. If there are no more tweens, this chain will complete. + * + * @method Phaser.Tweens.TweenChain#remove + * @since 3.60.0 + * @override + * + * @param {Phaser.Tweens.Tween} tween - The Tween to be removed. + * + * @return {this} This Tween Chain instance. + */ + remove: function (tween) + { + // Remove it immediately + ArrayRemove(this.data, tween); -/** - * The Timeline Complete Event. - * - * This event is dispatched by a Tween Timeline when it completes playback. - * - * Listen to it from a Timeline instance using `Timeline.on('complete', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('complete', listener); - * timeline.play(); - * ``` - * - * @event Phaser.Tweens.Events#TIMELINE_COMPLETE - * @since 3.0.0 - * - * @param {Phaser.Tweens.Timeline} timeline - A reference to the Timeline instance that emitted the event. - */ -module.exports = 'complete'; + tween.setRemovedState(); + if (tween === this.currentTween) + { + this.nextTween(); + } -/***/ }), -/* 1467 */ -/***/ (function(module, exports) { + this.totalData = this.data.length; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * The Timeline Loop Event. - * - * This event is dispatched by a Tween Timeline every time it loops. - * - * Listen to it from a Timeline instance using `Timeline.on('loop', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * loop: 4, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('loop', listener); - * timeline.play(); - * ``` - * - * @event Phaser.Tweens.Events#TIMELINE_LOOP - * @since 3.0.0 - * - * @param {Phaser.Tweens.Timeline} timeline - A reference to the Timeline instance that emitted the event. - */ -module.exports = 'loop'; + /** + * See if any of the tweens in this Tween Chain is currently acting upon the given target. + * + * @method Phaser.Tweens.TweenChain#hasTarget + * @since 3.60.0 + * + * @param {object} target - The target to check against this TweenChain. + * + * @return {boolean} `true` if the given target is a target of this TweenChain, otherwise `false`. + */ + hasTarget: function (target) + { + var data = this.data; + for (var i = 0; i < this.totalData; i++) + { + if (data[i].hasTarget(target)) + { + return true; + } + } -/***/ }), -/* 1468 */ -/***/ (function(module, exports) { + return false; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Restarts the TweenChain from the beginning. + * + * If this TweenChain was configured to have a loop, or start delay, those + * are reset to their initial values as well. It will also dispatch the + * `onActive` callback and event again. + * + * @method Phaser.Tweens.TweenChain#restart + * @since 3.60.0 + * + * @return {this} This TweenChain instance. + */ + restart: function () + { + if (this.isDestroyed()) + { + console.warn('Cannot restart destroyed TweenChain', this); -/** - * The Timeline Pause Event. - * - * This event is dispatched by a Tween Timeline when it is paused. - * - * Listen to it from a Timeline instance using `Timeline.on('pause', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('pause', listener); - * // At some point later ... - * timeline.pause(); - * ``` - * - * @event Phaser.Tweens.Events#TIMELINE_PAUSE - * @since 3.0.0 - * - * @param {Phaser.Tweens.Timeline} timeline - A reference to the Timeline instance that emitted the event. - */ -module.exports = 'pause'; + return this; + } + if (this.isRemoved()) + { + this.parent.makeActive(this); + } -/***/ }), -/* 1469 */ -/***/ (function(module, exports) { + this.resetTweens(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.paused = false; -/** - * The Timeline Resume Event. - * - * This event is dispatched by a Tween Timeline when it is resumed from a paused state. - * - * Listen to it from a Timeline instance using `Timeline.on('resume', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('resume', listener); - * // At some point later ... - * timeline.resume(); - * ``` - * - * @event Phaser.Tweens.Events#TIMELINE_RESUME - * @since 3.0.0 - * - * @param {Phaser.Tweens.Timeline} timeline - A reference to the Timeline instance that emitted the event. - */ -module.exports = 'resume'; + return this.init(); + }, + /** + * Resets the given Tween. + * + * It will seek to position 0 and playback will start on the next frame. + * + * @method Phaser.Tweens.TweenChain#reset + * @since 3.60.0 + * + * @param {Phaser.Tweens.Tween} tween - The Tween to be reset. + * + * @return {this} This TweenChain instance. + */ + reset: function (tween) + { + tween.seek(); -/***/ }), -/* 1470 */ -/***/ (function(module, exports) { + tween.setActiveState(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return this; + }, -/** - * The Timeline Start Event. - * - * This event is dispatched by a Tween Timeline when it starts. - * - * Listen to it from a Timeline instance using `Timeline.on('start', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('start', listener); - * timeline.play(); - * ``` - * - * @event Phaser.Tweens.Events#TIMELINE_START - * @since 3.0.0 - * - * @param {Phaser.Tweens.Timeline} timeline - A reference to the Timeline instance that emitted the event. - */ -module.exports = 'start'; + /** + * Re-initiases the given Tween and sets it to the Active state. + * + * @method Phaser.Tweens.TweenChain#makeActive + * @since 3.60.0 + * @override + * + * @param {Phaser.Tweens.Tween} tween - The Tween to check. + * + * @return {this} This TweenChain instance. + */ + makeActive: function (tween) + { + tween.reset(); + tween.setActiveState(); -/***/ }), -/* 1471 */ -/***/ (function(module, exports) { + return this; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Internal method that advances to the next state of the TweenChain playback. + * + * @method Phaser.Tweens.TweenChain#nextState + * @fires Phaser.Tweens.Events#TWEEN_COMPLETE + * @fires Phaser.Tweens.Events#TWEEN_LOOP + * @since 3.60.0 + * + * @return {boolean} `true` if this TweenChain has completed, otherwise `false`. + */ + nextState: function () + { + if (this.loopCounter > 0) + { + this.loopCounter--; -/** - * The Timeline Update Event. - * - * This event is dispatched by a Tween Timeline every time it updates, which can happen a lot of times per second, - * so be careful about listening to this event unless you absolutely require it. - * - * Listen to it from a Timeline instance using `Timeline.on('update', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('update', listener); - * timeline.play(); - * ``` - * - * @event Phaser.Tweens.Events#TIMELINE_UPDATE - * @since 3.0.0 - * - * @param {Phaser.Tweens.Timeline} timeline - A reference to the Timeline instance that emitted the event. - */ -module.exports = 'update'; + this.resetTweens(); + if (this.loopDelay > 0) + { + this.countdown = this.loopDelay; -/***/ }), -/* 1472 */ -/***/ (function(module, exports) { + this.setLoopDelayState(); + } + else + { + this.setActiveState(); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.dispatchEvent(Events.TWEEN_LOOP, 'onLoop'); + } + } + else if (this.completeDelay > 0) + { + this.countdown = this.completeDelay; -/** - * The Tween Active Event. - * - * This event is dispatched by a Tween when it becomes active within the Tween Manager. - * - * An 'active' Tween is one that is now progressing, although it may not yet be updating - * any target properties, due to settings such as `delay`. If you need an event for when - * the Tween starts actually updating its first property, see `TWEEN_START`. - * - * Listen to it from a Tween instance using `Tween.on('active', listener)`, i.e.: - * - * ```javascript - * var tween = this.tweens.add({ - * targets: image, - * x: 500, - * ease: 'Power1', - * duration: 3000 - * }); - * tween.on('active', listener); - * ``` - * - * @event Phaser.Tweens.Events#TWEEN_ACTIVE - * @since 3.19.0 - * - * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. - * @param {any[]} targets - An array of references to the target/s the Tween is operating on. - */ -module.exports = 'active'; + this.setCompleteDelayState(); + } + else + { + this.onCompleteHandler(); + return true; + } -/***/ }), -/* 1473 */ -/***/ (function(module, exports) { + return false; + }, -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + /** + * Starts this TweenChain playing. + * + * You only need to call this method if you have configured this TweenChain to be paused on creation. + * + * If the TweenChain is already playing, calling this method again will have no effect. If you wish to + * restart the chain, use `TweenChain.restart` instead. + * + * Calling this method after the TweenChain has completed will start the chain playing again from the beginning. + * + * @method Phaser.Tweens.TweenChain#play + * @since 3.60.0 + * + * @return {this} This TweenChain instance. + */ + play: function () + { + if (this.isDestroyed()) + { + console.warn('Cannot play destroyed TweenChain', this); -/** - * The Tween Complete Event. - * - * This event is dispatched by a Tween when it completes playback entirely, factoring in repeats and loops. - * - * If the Tween has been set to loop or repeat infinitely, this event will not be dispatched - * unless the `Tween.stop` method is called. - * - * If a Tween has a `completeDelay` set, this event will fire after that delay expires. - * - * Listen to it from a Tween instance using `Tween.on('complete', listener)`, i.e.: - * - * ```javascript - * var tween = this.tweens.add({ - * targets: image, - * x: 500, - * ease: 'Power1', - * duration: 3000 - * }); - * tween.on('complete', listener); - * ``` - * - * @event Phaser.Tweens.Events#TWEEN_COMPLETE - * @since 3.19.0 - * - * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. - * @param {any[]} targets - An array of references to the target/s the Tween is operating on. - */ -module.exports = 'complete'; + return this; + } + if (this.isPendingRemove() || this.isPending()) + { + this.resetTweens(); + } -/***/ }), -/* 1474 */ -/***/ (function(module, exports) { + this.paused = false; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (this.startDelay > 0 && !this.isStartDelayed()) + { + this.setStartDelayState(); + } + else + { + this.setActiveState(); + } -/** - * The Tween Loop Event. - * - * This event is dispatched by a Tween when it loops. - * - * This event will only be dispatched if the Tween has a loop count set. - * - * If a Tween has a `loopDelay` set, this event will fire after that delay expires. - * - * The difference between `loop` and `repeat` is that `repeat` is a property setting, - * where-as `loop` applies to the entire Tween. - * - * Listen to it from a Tween instance using `Tween.on('loop', listener)`, i.e.: - * - * ```javascript - * var tween = this.tweens.add({ - * targets: image, - * x: 500, - * ease: 'Power1', - * duration: 3000, - * loop: 6 - * }); - * tween.on('loop', listener); - * ``` - * - * @event Phaser.Tweens.Events#TWEEN_LOOP - * @since 3.19.0 - * - * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. - * @param {any[]} targets - An array of references to the target/s the Tween is operating on. - */ -module.exports = 'loop'; + return this; + }, + /** + * Internal method that resets all of the Tweens and the current index pointer. + * + * @method Phaser.Tweens.TweenChain#resetTweens + * @since 3.60.0 + */ + resetTweens: function () + { + var data = this.data; + var total = this.totalData; -/***/ }), -/* 1475 */ -/***/ (function(module, exports) { + for (var i = 0; i < total; i++) + { + data[i].reset(false); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + this.currentIndex = 0; + this.currentTween = data[0]; + }, -/** - * The Tween Repeat Event. - * - * This event is dispatched by a Tween when one of the properties it is tweening repeats. - * - * This event will only be dispatched if the Tween has a property with a repeat count set. - * - * If a Tween has a `repeatDelay` set, this event will fire after that delay expires. - * - * The difference between `loop` and `repeat` is that `repeat` is a property setting, - * where-as `loop` applies to the entire Tween. - * - * Listen to it from a Tween instance using `Tween.on('repeat', listener)`, i.e.: - * - * ```javascript - * var tween = this.tweens.add({ - * targets: image, - * x: 500, - * ease: 'Power1', - * duration: 3000, - * repeat: 4 - * }); - * tween.on('repeat', listener); - * ``` - * - * @event Phaser.Tweens.Events#TWEEN_REPEAT - * @since 3.19.0 - * - * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. - * @param {string} key - The key of the property that just repeated. - * @param {any} target - The target that the property just repeated on. - */ -module.exports = 'repeat'; + /** + * Internal method that advances the TweenChain based on the time values. + * + * @method Phaser.Tweens.TweenChain#update + * @fires Phaser.Tweens.Events#TWEEN_COMPLETE + * @fires Phaser.Tweens.Events#TWEEN_LOOP + * @fires Phaser.Tweens.Events#TWEEN_START + * @since 3.60.0 + * + * @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 TweenChain has finished and should be removed from the Tween Manager, otherwise returns `false`. + */ + update: function (delta) + { + if (this.isPendingRemove() || this.isDestroyed()) + { + return true; + } + else if (this.isFinished() || this.paused) + { + return false; + } + // The TweehChain.timeScale is applied within Tween.update, so doesn't need including here + delta *= this.parent.timeScale; -/***/ }), -/* 1476 */ -/***/ (function(module, exports) { + if (this.isLoopDelayed()) + { + this.updateLoopCountdown(delta); + } + else if (this.isCompleteDelayed()) + { + this.updateCompleteDelay(delta); + } + else if (this.isStartDelayed()) + { + // Reset the delta so we always start progress from zero + delta = this.updateStartCountdown(delta); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + var remove = false; -/** - * The Tween Start Event. - * - * This event is dispatched by a Tween when it starts tweening its first property. - * - * A Tween will only emit this event once, as it can only start once. - * - * If a Tween has a `delay` set, this event will fire after that delay expires. - * - * Listen to it from a Tween instance using `Tween.on('start', listener)`, i.e.: - * - * ```javascript - * var tween = this.tweens.add({ - * targets: image, - * x: 500, - * ease: 'Power1', - * duration: 3000 - * }); - * tween.on('start', listener); - * ``` - * - * @event Phaser.Tweens.Events#TWEEN_START - * @since 3.19.0 - * - * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. - * @param {any[]} targets - An array of references to the target/s the Tween is operating on. - */ -module.exports = 'start'; + if (this.isActive() && this.currentTween) + { + if (this.currentTween.update(delta)) + { + // This tween has finshed playback, so move to the next one + if (this.nextTween()) + { + this.nextState(); + } + } + // if nextState called onCompleteHandler then we're ready to be removed, unless we persist + remove = this.isPendingRemove(); -/***/ }), -/* 1477 */ -/***/ (function(module, exports) { + if (remove && this.persist) + { + this.setFinishedState(); -/** - * @author samme - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + remove = false; + } + } -/** - * The Tween Stop Event. - * - * This event is dispatched by a Tween when it is stopped. - * - * Listen to it from a Tween instance using `Tween.on('stop', listener)`, i.e.: - * - * ```javascript - * var tween = this.tweens.add({ - * targets: image, - * x: 500, - * ease: 'Power1', - * duration: 3000 - * }); - * tween.on('stop', listener); - * ``` - * - * @event Phaser.Tweens.Events#TWEEN_STOP - * @since 3.24.0 - * - * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. - * @param {any[]} targets - An array of references to the target/s the Tween is operating on. - */ -module.exports = 'stop'; + return remove; + }, + /** + * Immediately advances to the next Tween in the chain. + * + * This is typically called internally, but can be used if you need to + * advance playback for some reason. + * + * @method Phaser.Tweens.TweenChain#nextTween + * @since 3.60.0 + * + * @return {boolean} `true` if there are no more Tweens in the chain, otherwise `false`. + */ + nextTween: function () + { + this.currentIndex++; -/***/ }), -/* 1478 */ -/***/ (function(module, exports) { + if (this.currentIndex === this.totalData) + { + return true; + } + else + { + this.setCurrentTween(this.currentIndex); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return false; + }, -/** - * The Tween Update Event. - * - * This event is dispatched by a Tween every time it updates _any_ of the properties it is tweening. - * - * A Tween that is changing 3 properties of a target will emit this event 3 times per change, once per property. - * - * **Note:** This is a very high frequency event and may be dispatched multiple times, every single frame. - * - * Listen to it from a Tween instance using `Tween.on('update', listener)`, i.e.: - * - * ```javascript - * var tween = this.tweens.add({ - * targets: image, - * x: 500, - * ease: 'Power1', - * duration: 3000, - * }); - * tween.on('update', listener); - * ``` - * - * @event Phaser.Tweens.Events#TWEEN_UPDATE - * @since 3.19.0 - * - * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. - * @param {string} key - The property that was updated, i.e. `x` or `scale`. - * @param {any} target - The target object that was updated. Usually a Game Object, but can be of any type. - * @param {number} current - The current value of the property that was tweened. - * @param {number} previous - The previous value of the property that was tweened, prior to this update. - */ -module.exports = 'update'; + /** + * Sets the current active Tween to the given index, based on its + * entry in the TweenChain data array. + * + * @method Phaser.Tweens.TweenChain#setCurrentTween + * @since 3.60.0 + * + * @param {number} index - The index of the Tween to be made current. + */ + setCurrentTween: function (index) + { + this.currentIndex = index; + this.currentTween = this.data[index]; -/***/ }), -/* 1479 */ -/***/ (function(module, exports) { + this.currentTween.setActiveState(); + + this.currentTween.dispatchEvent(Events.TWEEN_ACTIVE, 'onActive'); + }, + + /** + * Internal method that will emit a TweenChain based Event and invoke the given callback. + * + * @method Phaser.Tweens.TweenChain#dispatchEvent + * @since 3.60.0 + * + * @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched. + * @param {Phaser.Types.Tweens.TweenCallbackTypes} [callback] - The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation. + */ + dispatchEvent: function (event, callback) + { + this.emit(event, this); + + var handler = this.callbacks[callback]; + + if (handler) + { + handler.func.apply(this.callbackScope, [ this ].concat(handler.params)); + } + }, + + /** + * Immediately destroys this TweenChain, nulling of all its references. + * + * @method Phaser.Tweens.TweenChain#destroy + * @since 3.60.0 + */ + destroy: function () + { + BaseTween.prototype.destroy.call(this); + + this.currentTween = null; + } + +}); /** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} + * Creates a new TweenChain object and adds it to the Tween Manager. + * + * Note: This method will only be available if Tweens have been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectFactory#tweenchain + * @since 3.60.0 + * + * @param {Phaser.Types.Tweens.TweenBuilderConfig|object} config - The TweenChain configuration. + * + * @return {Phaser.Tweens.TweenChain} The TweenChain that was created. */ +GameObjectFactory.register('tweenchain', function (config) +{ + return this.scene.sys.tweens.chain(config); +}); /** - * The Tween Yoyo Event. - * - * This event is dispatched by a Tween whenever a property it is tweening yoyos. - * - * This event will only be dispatched if the Tween has a property with `yoyo` set. - * - * If the Tween has a `hold` value, this event is dispatched when the hold expires. - * - * This event is dispatched for every property, and for every target, that yoyos. - * For example, if a Tween was updating 2 properties and had 10 targets, this event - * would be dispatched 20 times (twice per target). So be careful how you use it! - * - * Listen to it from a Tween instance using `Tween.on('yoyo', listener)`, i.e.: - * - * ```javascript - * var tween = this.tweens.add({ - * targets: image, - * x: 500, - * ease: 'Power1', - * duration: 3000, - * yoyo: true - * }); - * tween.on('yoyo', listener); - * ``` + * Creates a new TweenChain object and returns it, without adding it to the Tween Manager. * - * @event Phaser.Tweens.Events#TWEEN_YOYO - * @since 3.19.0 - * - * @param {Phaser.Tweens.Tween} tween - A reference to the Tween instance that emitted the event. - * @param {string} key - The property that yoyo'd, i.e. `x` or `scale`. - * @param {any} target - The target object that was yoyo'd. Usually a Game Object, but can be of any type. + * Note: This method will only be available if Tweens have been built into Phaser. + * + * @method Phaser.GameObjects.GameObjectCreator#tweenchain + * @since 3.60.0 + * + * @param {Phaser.Types.Tweens.TweenBuilderConfig|object} config - The TweenChain configuration. + * + * @return {Phaser.Tweens.TweenChain} The TweenChain that was created. */ -module.exports = 'yoyo'; +GameObjectCreator.register('tweenchain', function (config) +{ + return this.scene.sys.tweens.create(config); +}); + +module.exports = TweenChain; /***/ }), -/* 1480 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 15718: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var ArrayRemove = __webpack_require__(93); -var Class = __webpack_require__(0); -var NumberTweenBuilder = __webpack_require__(585); -var PluginCache = __webpack_require__(24); -var SceneEvents = __webpack_require__(20); -var StaggerBuilder = __webpack_require__(586); -var TimelineBuilder = __webpack_require__(587); -var TWEEN_CONST = __webpack_require__(100); -var TweenBuilder = __webpack_require__(163); +var BaseTweenData = __webpack_require__(65521); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(54272); /** * @classdesc - * The Tween Manager is a default Scene Plugin which controls and updates Tweens and Timelines. + * The TweenData is a class that contains a single target and property that is being tweened. * - * @class TweenManager + * Tweens create TweenData instances when they are created, with one TweenData instance per + * target, per property. A Tween can own multiple TweenData instances, but a TweenData only + * ever belongs to a single Tween. + * + * You should not typically create these yourself, but rather use the TweenBuilder, + * or the `Tween.add` method. + * + * Prior to Phaser 3.60 the TweenData was just an object, but was refactored to a class, + * to make it responsible for its own state and updating. + * + * @class TweenData * @memberof Phaser.Tweens + * @extends Phaser.Tweens.BaseTweenData * @constructor - * @since 3.0.0 + * @since 3.60.0 * - * @param {Phaser.Scene} scene - The Scene which owns this Tween Manager. + * @param {Phaser.Tweens.Tween} tween - The tween this TweenData instance belongs to. + * @param {number} targetIndex - The target index within the Tween targets array. + * @param {string} key - The property of the target to tween. + * @param {Phaser.Types.Tweens.GetEndCallback} getEnd - What the property will be at the END of the Tween. + * @param {Phaser.Types.Tweens.GetStartCallback} getStart - What the property will be at the START of the Tween. + * @param {?Phaser.Types.Tweens.GetActiveCallback} getActive - If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. + * @param {function} ease - The ease function this tween uses. + * @param {function} delay - Function that returns the time in milliseconds before tween will start. + * @param {number} duration - The duration of the tween in milliseconds. + * @param {boolean} yoyo - Determines whether the tween should return back to its start value after hold has expired. + * @param {number} hold - Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param {number} repeat - Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param {number} repeatDelay - Function that returns the time in milliseconds before the repeat will start. + * @param {boolean} flipX - Should toggleFlipX be called when yoyo or repeat happens? + * @param {boolean} flipY - Should toggleFlipY be called when yoyo or repeat happens? + * @param {?function} interpolation - The interpolation function to be used for arrays of data. Defaults to 'null'. + * @param {?number[]} interpolationData - The array of interpolation data to be set. Defaults to 'null'. */ -var TweenManager = new Class({ +var TweenData = new Class({ + + Extends: BaseTweenData, initialize: - function TweenManager (scene) + function TweenData (tween, targetIndex, key, getEnd, getStart, getActive, ease, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY, interpolation, interpolationData) { + BaseTweenData.call(this, tween, targetIndex, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY); + /** - * The Scene which owns this Tween Manager. + * The property of the target to be tweened. * - * @name Phaser.Tweens.TweenManager#scene - * @type {Phaser.Scene} - * @since 3.0.0 + * @name Phaser.Tweens.TweenData#key + * @type {string} + * @readonly + * @since 3.60.0 */ - this.scene = scene; + this.key = key; /** - * The Systems object of the Scene which owns this Tween Manager. + * A function that returns what to set the target property to, + * the moment the TweenData is invoked. * - * @name Phaser.Tweens.TweenManager#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 + * This is called when this TweenData is inititalised or reset. + * + * @name Phaser.Tweens.TweenData#getActiveValue + * @type {?Phaser.Types.Tweens.GetActiveCallback} + * @since 3.60.0 */ - this.systems = scene.sys; + this.getActiveValue = getActive; /** - * The time scale of the Tween Manager. + * A function that returns what to set the target property to + * at the end of the tween. * - * This value scales the time delta between two frames, thus influencing the speed of time for all Tweens owned by this Tween Manager. + * This is called when the tween starts playing, after any initial + * start delay, or if the tween is reset, or is set to repeat. * - * @name Phaser.Tweens.TweenManager#timeScale - * @type {number} - * @default 1 - * @since 3.0.0 + * @name Phaser.Tweens.TweenData#getEndValue + * @type {Phaser.Types.Tweens.GetEndCallback} + * @since 3.60.0 */ - this.timeScale = 1; + this.getEndValue = getEnd; /** - * An array of Tweens and Timelines which will be added to the Tween Manager at the start of the frame. + * A function that returns what to set the target property to + * at the start of the tween. * - * @name Phaser.Tweens.TweenManager#_add - * @type {array} - * @private - * @since 3.0.0 + * This is called when the tween starts playing, after any initial + * start delay, or if the tween is reset, or is set to repeat. + * + * @name Phaser.Tweens.TweenData#getStartValue + * @type {Phaser.Types.Tweens.GetStartCallback} + * @since 3.60.0 */ - this._add = []; + this.getStartValue = getStart; /** - * An array of Tweens and Timelines pending to be later added to the Tween Manager. + * The ease function this Tween uses to calculate the target value. * - * @name Phaser.Tweens.TweenManager#_pending - * @type {array} - * @private - * @since 3.0.0 + * @name Phaser.Tweens.TweenData#ease + * @type {function} + * @since 3.60.0 */ - this._pending = []; + this.ease = ease; /** - * An array of Tweens and Timelines which are still incomplete and are actively processed by the Tween Manager. + * The targets starting value, as returned by `getStartValue`. * - * @name Phaser.Tweens.TweenManager#_active - * @type {array} - * @private - * @since 3.0.0 + * @name Phaser.Tweens.TweenData#start + * @type {number} + * @since 3.60.0 */ - this._active = []; + this.start = 0; /** - * An array of Tweens and Timelines which will be removed from the Tween Manager at the start of the frame. + * The target value from the previous step. * - * @name Phaser.Tweens.TweenManager#_destroy - * @type {array} - * @private - * @since 3.0.0 + * @name Phaser.Tweens.TweenData#previous + * @type {number} + * @since 3.60.0 */ - this._destroy = []; + this.previous = 0; /** - * The number of Tweens and Timelines which need to be processed by the Tween Manager at the start of the frame. + * The targets current value, as recorded in the most recent step. * - * @name Phaser.Tweens.TweenManager#_toProcess + * @name Phaser.Tweens.TweenData#current * @type {number} - * @private - * @default 0 - * @since 3.0.0 + * @since 3.60.0 */ - this._toProcess = 0; - - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); - scene.sys.events.on(SceneEvents.START, this.start, this); - }, - - /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. - * - * @method Phaser.Tweens.TweenManager#boot - * @private - * @since 3.5.1 - */ - boot: function () - { - this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); - }, + this.current = 0; - /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. - * - * @method Phaser.Tweens.TweenManager#start - * @private - * @since 3.5.0 - */ - start: function () - { - var eventEmitter = this.systems.events; + /** + * The targets ending value, as returned by `getEndValue`. + * + * @name Phaser.Tweens.TweenData#end + * @type {number} + * @since 3.60.0 + */ + this.end = 0; - eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this); - eventEmitter.on(SceneEvents.UPDATE, this.update, this); - eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); + /** + * The interpolation function to be used for arrays of data. + * + * @name Phaser.Tweens.TweenData#interpolation + * @type {?function} + * @default null + * @since 3.60.0 + */ + this.interpolation = interpolation; - this.timeScale = 1; + /** + * The array of data to interpolate, if interpolation is being used. + * + * @name Phaser.Tweens.TweenData#interpolationData + * @type {?number[]} + * @since 3.60.0 + */ + this.interpolationData = interpolationData; }, /** - * Create a Tween Timeline and return it, but do NOT add it to the active or pending Tween lists. + * Internal method that resets this Tween Data entirely, including the progress and elapsed values. * - * @method Phaser.Tweens.TweenManager#createTimeline - * @since 3.0.0 + * Called automatically by the parent Tween. Should not be called directly. * - * @param {Phaser.Types.Tweens.TimelineBuilderConfig} [config] - The configuration object for the Timeline and its Tweens. + * @method Phaser.Tweens.TweenData#reset + * @since 3.60.0 * - * @return {Phaser.Tweens.Timeline} The created Timeline object. + * @param {boolean} [isSeeking=false] - Is the Tween Data being reset as part of a Tween seek? */ - createTimeline: function (config) + reset: function (isSeeking) { - return TimelineBuilder(this, config); - }, + BaseTweenData.prototype.reset.call(this); - /** - * Create a Tween Timeline and add it to the active Tween list. - * - * @method Phaser.Tweens.TweenManager#timeline - * @since 3.0.0 - * - * @param {Phaser.Types.Tweens.TimelineBuilderConfig} [config] - The configuration object for the Timeline and its Tweens. - * - * @return {Phaser.Tweens.Timeline} The created Timeline object. - */ - timeline: function (config) - { - var timeline = TimelineBuilder(this, config); + var target = this.tween.targets[this.targetIndex]; + var key = this.key; - if (!timeline.paused) + if (isSeeking) { - this._add.push(timeline); - - this._toProcess++; + target[key] = this.start; } - return timeline; - }, + this.start = 0; + this.previous = 0; + this.current = 0; + this.end = 0; - /** - * Create a Tween and return it, but do NOT add it to the active or pending Tween lists. - * - * @method Phaser.Tweens.TweenManager#create - * @since 3.0.0 - * - * @param {Phaser.Types.Tweens.TweenBuilderConfig|object} config - The configuration object for the Tween. - * - * @return {Phaser.Tweens.Tween} The created Tween object. - */ - create: function (config) - { - return TweenBuilder(this, config); + if (this.getActiveValue) + { + target[key] = this.getActiveValue(target, key, 0); + } }, /** - * Create a Tween and add it to the active Tween list. + * Internal method that advances this TweenData based on the delta value given. * - * @method Phaser.Tweens.TweenManager#add - * @since 3.0.0 + * @method Phaser.Tweens.TweenData#update + * @fires Phaser.Tweens.Events#TWEEN_UPDATE + * @fires Phaser.Tweens.Events#TWEEN_REPEAT + * @since 3.60.0 * - * @param {Phaser.Types.Tweens.TweenBuilderConfig|object} config - The configuration object for the Tween. + * @param {number} delta - The elapsed delta time in ms. * - * @return {Phaser.Tweens.Tween} The created Tween. + * @return {boolean} `true` if this TweenData is still playing, or `false` if it has finished entirely. */ - add: function (config) + update: function (delta) { - var tween = TweenBuilder(this, config); + var tween = this.tween; + var totalTargets = tween.totalTargets; - this._add.push(tween); + var targetIndex = this.targetIndex; + var target = tween.targets[targetIndex]; + var key = this.key; - this._toProcess++; + // Bail out if we don't have a target to act upon + if (!target) + { + this.setCompleteState(); - return tween; - }, + return false; + } - /** - * Add an existing tween into the active Tween list. - * - * @method Phaser.Tweens.TweenManager#existing - * @since 3.0.0 - * - * @param {Phaser.Tweens.Tween} tween - The Tween to add. - * - * @return {Phaser.Tweens.TweenManager} This Tween Manager object. - */ - existing: function (tween) - { - this._add.push(tween); + if (this.isCountdown) + { + this.elapsed -= delta; - this._toProcess++; + if (this.elapsed <= 0) + { + this.elapsed = 0; - return this; - }, + delta = 0; - /** - * Create a Number Tween and add it to the active Tween list. - * - * @method Phaser.Tweens.TweenManager#addCounter - * @since 3.0.0 - * - * @param {Phaser.Types.Tweens.NumberTweenBuilderConfig} config - The configuration object for the Number Tween. - * - * @return {Phaser.Tweens.Tween} The created Number Tween. - */ - addCounter: function (config) - { - var tween = NumberTweenBuilder(this, config); + if (this.isDelayed()) + { + this.setPendingRenderState(); + } + else if (this.isRepeating()) + { + this.setPlayingForwardState(); + + this.dispatchEvent(Events.TWEEN_REPEAT, 'onRepeat'); + } + else if (this.isHolding()) + { + this.setStateFromEnd(0); + } + } + } - this._add.push(tween); + // All of the above have the ability to change the state, so put this in its own check - this._toProcess++; + if (this.isPendingRender()) + { + this.start = this.getStartValue(target, key, target[key], targetIndex, totalTargets, tween); - return tween; - }, + this.end = this.getEndValue(target, key, this.start, targetIndex, totalTargets, tween); - /** - * 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' }) - * }); - * ``` - * - * @method Phaser.Tweens.TweenManager#stagger - * @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 - The configuration object for the Stagger function. - * - * @return {function} The stagger function. - */ - stagger: function (value, options) - { - return StaggerBuilder(value, options); - }, + this.current = this.start; - /** - * Updates the Tween Manager's internal lists at the start of the frame. - * - * This method will return immediately if no changes have been indicated. - * - * @method Phaser.Tweens.TweenManager#preUpdate - * @since 3.0.0 - */ - preUpdate: function () - { - if (this._toProcess === 0) - { - // Quick bail - return; + target[key] = this.start; + + this.setPlayingForwardState(); + + return true; } - var list = this._destroy; - var active = this._active; - var pending = this._pending; - var i; - var tween; + var forward = this.isPlayingForward(); + var backward = this.isPlayingBackward(); - // Clear the 'destroy' list - for (i = 0; i < list.length; i++) + if (forward || backward) { - tween = list[i]; + var elapsed = this.elapsed; + var duration = this.duration; + var diff = 0; + var complete = false; - // Remove from the 'active' array - var idx = active.indexOf(tween); + elapsed += delta; - if (idx === -1) + if (elapsed >= duration) { - // Not in the active array, is it in pending instead? - idx = pending.indexOf(tween); - - if (idx > -1) - { - tween.state = TWEEN_CONST.REMOVED; - pending.splice(idx, 1); - } + diff = elapsed - duration; + elapsed = duration; + complete = true; } - else + else if (elapsed < 0) { - tween.state = TWEEN_CONST.REMOVED; - active.splice(idx, 1); + elapsed = 0; } - } - list.length = 0; + var progress = Clamp(elapsed / duration, 0, 1); - // Process the addition list - // This stops callbacks and out of sync events from populating the active array mid-way during the update + this.elapsed = elapsed; + this.progress = progress; + this.previous = this.current; - list = this._add; + if (complete) + { + if (forward) + { + this.current = this.end; - for (i = 0; i < list.length; i++) - { - tween = list[i]; + target[key] = this.end; + + if (this.hold > 0) + { + this.elapsed = this.hold; + + this.setHoldState(); + } + else + { + this.setStateFromEnd(diff); + } + } + else + { + this.current = this.start; - if (tween.state === TWEEN_CONST.PENDING_ADD) + target[key] = this.start; + + this.setStateFromStart(diff); + } + } + else { - // Return true if the Tween should be started right away, otherwise false - if (tween.init()) + if (!forward) { - tween.play(); + progress = 1 - progress; + } + + var v = this.ease(progress); - this._active.push(tween); + if (this.interpolation) + { + this.current = this.interpolation(this.interpolationData, v); } else { - this._pending.push(tween); + this.current = this.start + ((this.end - this.start) * v); } + + target[key] = this.current; } - } - list.length = 0; + this.dispatchEvent(Events.TWEEN_UPDATE, 'onUpdate'); + } - this._toProcess = 0; + // Return TRUE if this TweenData still playing, otherwise FALSE + return !this.isComplete(); }, /** - * Updates all Tweens and Timelines of the Tween Manager. + * Internal method that will emit a TweenData based Event on the + * parent Tween and also invoke the given callback, if provided. * - * @method Phaser.Tweens.TweenManager#update - * @since 3.0.0 + * @method Phaser.Tweens.TweenData#dispatchEvent + * @since 3.60.0 * - * @param {number} timestamp - The current time in milliseconds. - * @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + * @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched. + * @param {Phaser.Types.Tweens.TweenCallbackTypes} [callback] - The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation. */ - update: function (timestamp, delta) + dispatchEvent: function (event, callback) { - // Process active tweens - var list = this._active; - var tween; - - // Scale the delta - delta *= this.timeScale; + var tween = this.tween; - for (var i = 0; i < list.length; i++) + if (!tween.isSeeking) { - tween = list[i]; + var target = tween.targets[this.targetIndex]; + var key = this.key; - // If Tween.update returns 'true' then it means it has completed, - // so move it to the destroy list - if (tween.update(timestamp, delta)) + var current = this.current; + var previous = this.previous; + + tween.emit(event, tween, key, target, current, previous); + + var handler = tween.callbacks[callback]; + + if (handler) { - this._destroy.push(tween); - this._toProcess++; + handler.func.apply(tween.callbackScope, [ tween, target, key, current, previous ].concat(handler.params)); } } }, /** - * Removes the given tween from the Tween Manager, regardless of its state (pending or active). - * - * @method Phaser.Tweens.TweenManager#remove - * @since 3.17.0 + * Immediately destroys this TweenData, nulling of all its references. * - * @param {Phaser.Tweens.Tween} tween - The Tween to be removed. - * - * @return {Phaser.Tweens.TweenManager} This Tween Manager object. + * @method Phaser.Tweens.TweenData#destroy + * @since 3.60.0 */ - remove: function (tween) + destroy: function () { - ArrayRemove(this._add, tween); - ArrayRemove(this._pending, tween); - ArrayRemove(this._active, tween); - ArrayRemove(this._destroy, tween); + BaseTweenData.prototype.destroy.call(this); - tween.state = TWEEN_CONST.REMOVED; + this.getActiveValue = null; + this.getEndValue = null; + this.getStartValue = null; + this.ease = null; + } - return this; - }, +}); - /** - * Checks if a Tween or Timeline is active and adds it to the Tween Manager at the start of the frame if it isn't. - * - * @method Phaser.Tweens.TweenManager#makeActive - * @since 3.0.0 - * - * @param {Phaser.Tweens.Tween} tween - The Tween to check. - * - * @return {Phaser.Tweens.TweenManager} This Tween Manager object. - */ - makeActive: function (tween) - { - if (this._add.indexOf(tween) !== -1 || this._active.indexOf(tween) !== -1) - { - return this; - } +module.exports = TweenData; - var idx = this._pending.indexOf(tween); - if (idx !== -1) - { - this._pending.splice(idx, 1); - } +/***/ }), + +/***/ 96490: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - this._add.push(tween); +var BaseTweenData = __webpack_require__(65521); +var Clamp = __webpack_require__(82897); +var Class = __webpack_require__(56694); +var Events = __webpack_require__(54272); - tween.state = TWEEN_CONST.PENDING_ADD; +/** + * @classdesc + * The TweenFrameData is a class that contains a single target that will change the texture frame + * at the conclusion of the Tween. + * + * TweenFrameData instances are typically created by the TweenBuilder automatically, when it + * detects the prescence of a 'texture' property as the key being tweened. + * + * A Tween can own multiple TweenFrameData instances, but a TweenFrameData only + * ever belongs to a single Tween. + * + * You should not typically create these yourself, but rather use the TweenBuilder, + * or the `Tween.addFrame` method. + * + * @class TweenFrameData + * @memberof Phaser.Tweens + * @extends Phaser.Tweens.BaseTweenData + * @constructor + * @since 3.60.0 + * + * @param {Phaser.Tweens.Tween} tween - The tween this TweenData instance belongs to. + * @param {number} targetIndex - The target index within the Tween targets array. + * @param {string} texture - The texture key to set at the end of this tween. + * @param {(string|number)} frame - The texture frame to set at the end of this tween. + * @param {function} delay - Function that returns the time in milliseconds before tween will start. + * @param {number} duration - The duration of the tween in milliseconds. + * @param {number} hold - Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param {number} repeat - Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param {number} repeatDelay - Function that returns the time in milliseconds before the repeat will start. + * @param {boolean} flipX - Should toggleFlipX be called when yoyo or repeat happens? + * @param {boolean} flipY - Should toggleFlipY be called when yoyo or repeat happens? + */ +var TweenFrameData = new Class({ - this._toProcess++; + Extends: BaseTweenData, - return this; - }, + initialize: - /** - * Passes all Tweens to the given callback. - * - * @method Phaser.Tweens.TweenManager#each - * @since 3.0.0 - * - * @param {function} callback - The function to call. - * @param {object} [scope] - The scope (`this` object) to call the function with. - * @param {...*} [args] - The arguments to pass into the function. Its first argument will always be the Tween currently being iterated. - */ - each: function (callback, scope) + function TweenFrameData (tween, targetIndex, texture, frame, delay, duration, hold, repeat, repeatDelay, flipX, flipY) { - var args = [ null ]; + BaseTweenData.call(this, tween, targetIndex, delay, duration, false, hold, repeat, repeatDelay, flipX, flipY); - for (var i = 1; i < arguments.length; i++) - { - args.push(arguments[i]); - } + /** + * The property of the target to be tweened. + * + * Always 'texture' for a TweenFrameData object. + * + * @name Phaser.Tweens.TweenFrameData#key + * @type {string} + * @readonly + * @since 3.60.0 + */ + this.key = 'texture'; - for (var texture in this.list) - { - args[0] = this.list[texture]; + /** + * The texture to be set at the start of the tween. + * + * @name Phaser.Tweens.TweenFrameData#startTexture + * @type {string} + * @since 3.60.0 + */ + this.startTexture = null; - callback.apply(scope, args); - } + /** + * The texture to be set at the end of the tween. + * + * @name Phaser.Tweens.TweenFrameData#endTexture + * @type {string} + * @since 3.60.0 + */ + this.endTexture = texture; + + /** + * The frame to be set at the start of the tween. + * + * @name Phaser.Tweens.TweenFrameData#startFrame + * @type {(string|number)} + * @since 3.60.0 + */ + this.startFrame = null; + + /** + * The frame to be set at the end of the tween. + * + * @name Phaser.Tweens.TweenFrameData#endFrame + * @type {(string|number)} + * @since 3.60.0 + */ + this.endFrame = frame; + + /** + * Will the Tween ease back to its starting values, after reaching the end + * and any `hold` value that may be set? + * + * @name Phaser.Tweens.TweenFrameData#yoyo + * @type {boolean} + * @since 3.60.0 + */ + this.yoyo = (repeat !== 0) ? true : false; }, /** - * Returns an array of all active Tweens and Timelines in the Tween Manager. + * Internal method that resets this Tween Data entirely, including the progress and elapsed values. * - * @method Phaser.Tweens.TweenManager#getAllTweens - * @since 3.0.0 + * Called automatically by the parent Tween. Should not be called directly. * - * @return {Phaser.Tweens.Tween[]} A new array containing references to all active Tweens and Timelines. + * @method Phaser.Tweens.TweenFrameData#reset + * @since 3.60.0 + * + * @param {boolean} [isSeeking=false] - Is the Tween Data being reset as part of a Tween seek? */ - getAllTweens: function () + reset: function (isSeeking) { - var list = this._active; - var output = []; + BaseTweenData.prototype.reset.call(this); - for (var i = 0; i < list.length; i++) + var target = this.tween.targets[this.targetIndex]; + + if (!this.startTexture) { - output.push(list[i]); + this.startTexture = target.texture.key; + this.startFrame = target.frame.name; } - return output; - }, - - /** - * Returns the scale of the time delta for all Tweens and Timelines owned by this Tween Manager. - * - * @method Phaser.Tweens.TweenManager#getGlobalTimeScale - * @since 3.0.0 - * - * @return {number} The scale of the time delta, usually 1. - */ - getGlobalTimeScale: function () - { - return this.timeScale; + if (isSeeking) + { + target.setTexture(this.startTexture, this.startFrame); + } }, /** - * Returns an array of all Tweens or Timelines in the Tween Manager which affect the given target or array of targets. - * - * Only the currently active tweens are tested. A tween that has completed and is - * awaiting removal will not be included in the results. - * - * If you wish to also search pending tweens, use the `includePending` flag. + * Internal method that advances this TweenData based on the delta value given. * - * @method Phaser.Tweens.TweenManager#getTweensOf - * @since 3.0.0 + * @method Phaser.Tweens.TweenFrameData#update + * @fires Phaser.Tweens.Events#TWEEN_UPDATE + * @fires Phaser.Tweens.Events#TWEEN_REPEAT + * @since 3.60.0 * - * @param {(object|array)} target - The target to look for. Provide an array to look for multiple targets. - * @param {boolean} [includePending=false] - Also check for pending tweens, not just active ones? + * @param {number} delta - The elapsed delta time in ms. * - * @return {Phaser.Tweens.Tween[]} A new array containing all Tweens and Timelines which affect the given target(s). + * @return {boolean} `true` if this TweenData is still playing, or `false` if it has finished entirely. */ - getTweensOf: function (target, includePending) + update: function (delta) { - if (includePending === undefined) { includePending = false; } - - var list = this._active; - var tween; - var output = []; - var i; - var t; + var tween = this.tween; + var targetIndex = this.targetIndex; + var target = tween.targets[targetIndex]; - if (!Array.isArray(target)) + // Bail out if we don't have a target to act upon + if (!target) { - target = [ target ]; + this.setCompleteState(); + + return false; } - for (i = 0; i < list.length; i++) + if (this.isCountdown) { - tween = list[i]; + this.elapsed -= delta; - for (t = 0; t < target.length; t++) + if (this.elapsed <= 0) { - if (tween.hasTarget(target[t])) + this.elapsed = 0; + + delta = 0; + + if (this.isDelayed()) { - output.push(tween); + this.setPendingRenderState(); + } + else if (this.isRepeating()) + { + this.setPlayingForwardState(); + + this.dispatchEvent(Events.TWEEN_REPEAT, 'onRepeat'); + } + else if (this.isHolding()) + { + this.setStateFromEnd(0); } } } - if (includePending) + // All of the above have the ability to change the state, so put this in its own check + + if (this.isPendingRender()) { - list = this._pending; + if (this.startTexture) + { + target.setTexture(this.startTexture, this.startFrame); + } - for (i = 0; i < list.length; i++) + this.setPlayingForwardState(); + + return true; + } + + var forward = this.isPlayingForward(); + var backward = this.isPlayingBackward(); + + if (forward || backward) + { + var elapsed = this.elapsed; + var duration = this.duration; + var diff = 0; + var complete = false; + + elapsed += delta; + + if (elapsed >= duration) + { + diff = elapsed - duration; + elapsed = duration; + complete = true; + } + else if (elapsed < 0) { - tween = list[i]; + elapsed = 0; + } + + var progress = Clamp(elapsed / duration, 0, 1); + + this.elapsed = elapsed; + this.progress = progress; - for (t = 0; t < target.length; t++) + if (complete) + { + if (forward) { - if (tween.hasTarget(target[t])) + target.setTexture(this.endTexture, this.endFrame); + + if (this.hold > 0) + { + this.elapsed = this.hold; + + this.setHoldState(); + } + else { - output.push(tween); + this.setStateFromEnd(diff); } } + else + { + target.setTexture(this.startTexture, this.startFrame); + + this.setStateFromStart(diff); + } } + + this.dispatchEvent(Events.TWEEN_UPDATE, 'onUpdate'); } - return output; + // Return TRUE if this TweenData still playing, otherwise FALSE + return !this.isComplete(); }, /** - * Checks if the given object is being affected by a playing Tween. + * Internal method that will emit a TweenData based Event on the + * parent Tween and also invoke the given callback, if provided. * - * @method Phaser.Tweens.TweenManager#isTweening - * @since 3.0.0 + * @method Phaser.Tweens.TweenFrameData#dispatchEvent + * @since 3.60.0 * - * @param {object} target - target Phaser.Tweens.Tween object - * - * @return {boolean} returns if target tween object is active or not + * @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched. + * @param {Phaser.Types.Tweens.TweenCallbackTypes} [callback] - The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation. */ - isTweening: function (target) + dispatchEvent: function (event, callback) { - var list = this._active; - var tween; + var tween = this.tween; - for (var i = 0; i < list.length; i++) + if (!tween.isSeeking) { - tween = list[i]; + var target = tween.targets[this.targetIndex]; + var key = this.key; + + tween.emit(event, tween, key, target); - if (tween.hasTarget(target) && tween.isPlaying()) + var handler = tween.callbacks[callback]; + + if (handler) { - return true; + handler.func.apply(tween.callbackScope, [ tween, target, key ].concat(handler.params)); } } - - return false; }, /** - * Stops all Tweens in this Tween Manager. They will be removed at the start of the frame. - * - * @method Phaser.Tweens.TweenManager#killAll - * @since 3.0.0 + * Immediately destroys this TweenData, nulling of all its references. * - * @return {Phaser.Tweens.TweenManager} This Tween Manager. + * @method Phaser.Tweens.TweenFrameData#destroy + * @since 3.60.0 */ - killAll: function () + destroy: function () { - var tweens = this.getAllTweens(); + BaseTweenData.prototype.destroy.call(this); - for (var i = 0; i < tweens.length; i++) - { - tweens[i].stop(); - } + this.startTexture = null; + this.endTexture = null; + this.startFrame = null; + this.endFrame = null; + } - return this; - }, +}); + +module.exports = TweenFrameData; + + +/***/ }), + +/***/ 55303: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Phaser Tween States. + * + * @namespace Phaser.Tweens.States + * @memberof Phaser.Tweens + * @since 3.60.0 + */ + +/** + * Phaser Tween state constants. + * + * @typedef {Phaser.Tweens.States} Phaser.Tweens.StateType + * @memberof Phaser.Tweens + * @since 3.60.0 + */ + +var TWEEN_CONST = { /** - * Stops all Tweens which affect the given target or array of targets. The Tweens will be removed from the Tween Manager at the start of the frame. - * - * @see {@link #getTweensOf} + * TweenData state. * - * @method Phaser.Tweens.TweenManager#killTweensOf + * @name Phaser.Tweens.States.CREATED + * @type {number} + * @const * @since 3.0.0 + */ + CREATED: 0, + + // 1 used to be INIT prior to 3.60 + + /** + * TweenData state. * - * @param {(object|array)} target - The target to look for. Provide an array to look for multiple targets. + * @name Phaser.Tweens.States.DELAY + * @type {number} + * @const + * @since 3.0.0 + */ + DELAY: 2, + + // 3 used to be OFFSET_DELAY prior to 3.60 + + /** + * TweenData state. * - * @return {Phaser.Tweens.TweenManager} This Tween Manager. + * @name Phaser.Tweens.States.PENDING_RENDER + * @type {number} + * @const + * @since 3.0.0 */ - killTweensOf: function (target) - { - var tweens = this.getTweensOf(target); + PENDING_RENDER: 4, - for (var i = 0; i < tweens.length; i++) - { - tweens[i].stop(); - } + /** + * TweenData state. + * + * @name Phaser.Tweens.States.PLAYING_FORWARD + * @type {number} + * @const + * @since 3.0.0 + */ + PLAYING_FORWARD: 5, - return this; - }, + /** + * TweenData state. + * + * @name Phaser.Tweens.States.PLAYING_BACKWARD + * @type {number} + * @const + * @since 3.0.0 + */ + PLAYING_BACKWARD: 6, /** - * Pauses all Tweens in this Tween Manager. + * TweenData state. * - * @method Phaser.Tweens.TweenManager#pauseAll + * @name Phaser.Tweens.States.HOLD_DELAY + * @type {number} + * @const * @since 3.0.0 + */ + HOLD_DELAY: 7, + + /** + * TweenData state. * - * @return {Phaser.Tweens.TweenManager} This Tween Manager. + * @name Phaser.Tweens.States.REPEAT_DELAY + * @type {number} + * @const + * @since 3.0.0 */ - pauseAll: function () - { - var list = this._active; + REPEAT_DELAY: 8, - for (var i = 0; i < list.length; i++) - { - list[i].pause(); - } + /** + * TweenData state. + * + * @name Phaser.Tweens.States.COMPLETE + * @type {number} + * @const + * @since 3.0.0 + */ + COMPLETE: 9, - return this; - }, + // Tween specific (starts from 20 to cleanly allow extra TweenData consts in the future) /** - * Resumes all Tweens in this Tween Manager. + * Tween state. The Tween has been created but has not yet been added to the Tween Manager. * - * @method Phaser.Tweens.TweenManager#resumeAll + * @name Phaser.Tweens.States.PENDING + * @type {number} + * @const * @since 3.0.0 + */ + PENDING: 20, + + /** + * Tween state. The Tween is active within the Tween Manager. This means it is either playing, + * or was playing and is currently paused, but in both cases it's still being processed by + * the Tween Manager, so is considered 'active'. * - * @return {Phaser.Tweens.TweenManager} This Tween Manager. + * @name Phaser.Tweens.States.ACTIVE + * @type {number} + * @const + * @since 3.0.0 */ - resumeAll: function () - { - var list = this._active; + ACTIVE: 21, - for (var i = 0; i < list.length; i++) - { - list[i].resume(); - } + /** + * Tween state. The Tween is waiting for a loop countdown to elapse. + * + * @name Phaser.Tweens.States.LOOP_DELAY + * @type {number} + * @const + * @since 3.0.0 + */ + LOOP_DELAY: 22, - return this; - }, + /** + * Tween state. The Tween is waiting for a complete delay to elapse. + * + * @name Phaser.Tweens.States.COMPLETE_DELAY + * @type {number} + * @const + * @since 3.0.0 + */ + COMPLETE_DELAY: 23, /** - * Sets a new scale of the time delta for this Tween Manager. + * Tween state. The Tween is waiting for a starting delay to elapse. * - * The time delta is the time elapsed between two consecutive frames and influences the speed of time for this Tween Manager and all Tweens it owns. Values higher than 1 increase the speed of time, while values smaller than 1 decrease it. A value of 0 freezes time and is effectively equivalent to pausing all Tweens. + * @name Phaser.Tweens.States.START_DELAY + * @type {number} + * @const + * @since 3.0.0 + */ + START_DELAY: 24, + + /** + * Tween state. The Tween has finished playback and is waiting to be removed from the Tween Manager. * - * @method Phaser.Tweens.TweenManager#setGlobalTimeScale + * @name Phaser.Tweens.States.PENDING_REMOVE + * @type {number} + * @const * @since 3.0.0 + */ + PENDING_REMOVE: 25, + + /** + * Tween state. The Tween has been removed from the Tween Manager. * - * @param {number} value - The new scale of the time delta, where 1 is the normal speed. + * @name Phaser.Tweens.States.REMOVED + * @type {number} + * @const + * @since 3.0.0 + */ + REMOVED: 26, + + /** + * Tween state. The Tween has finished playback but was flagged as 'persistent' during creation, + * so will not be automatically removed by the Tween Manager. * - * @return {Phaser.Tweens.TweenManager} This Tween Manager. + * @name Phaser.Tweens.States.FINISHED + * @type {number} + * @const + * @since 3.60.0 */ - setGlobalTimeScale: function (value) - { - this.timeScale = value; + FINISHED: 27, - return this; - }, + /** + * Tween state. The Tween has been destroyed and can no longer be played by a Tween Manager. + * + * @name Phaser.Tweens.States.DESTROYED + * @type {number} + * @const + * @since 3.60.0 + */ + DESTROYED: 28, /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. + * A large integer value used for 'infinite' style countdowns. * - * @method Phaser.Tweens.TweenManager#shutdown - * @since 3.0.0 + * Similar use-case to Number.MAX_SAFE_INTEGER but we cannot use that because it's not + * supported on IE. + * + * @name Phaser.Tweens.States.MAX + * @type {number} + * @const + * @since 3.60.0 */ - shutdown: function () + MAX: 999999999999 + +}; + +module.exports = TWEEN_CONST; + + +/***/ }), + +/***/ 56694: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +// Taken from klasse by mattdesl https://github.com/mattdesl/klasse + +function hasGetterOrSetter (def) +{ + return (!!def.get && typeof def.get === 'function') || (!!def.set && typeof def.set === 'function'); +} + +function getProperty (definition, k, isClassDescriptor) +{ + // This may be a lightweight object, OR it might be a property that was defined previously. + + // For simple class descriptors we can just assume its NOT previously defined. + var def = (isClassDescriptor) ? definition[k] : Object.getOwnPropertyDescriptor(definition, k); + + if (!isClassDescriptor && def.value && typeof def.value === 'object') { - this.killAll(); + def = def.value; + } - this._add = []; - this._pending = []; - this._active = []; - this._destroy = []; + // This might be a regular property, or it may be a getter/setter the user defined in a class. + if (def && hasGetterOrSetter(def)) + { + if (typeof def.enumerable === 'undefined') + { + def.enumerable = true; + } - this._toProcess = 0; + if (typeof def.configurable === 'undefined') + { + def.configurable = true; + } - var eventEmitter = this.systems.events; + return def; + } + else + { + return false; + } +} - eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this); - eventEmitter.off(SceneEvents.UPDATE, this.update, this); - eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); - }, +function hasNonConfigurable (obj, k) +{ + var prop = Object.getOwnPropertyDescriptor(obj, k); - /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. - * - * @method Phaser.Tweens.TweenManager#destroy - * @since 3.0.0 - */ - destroy: function () + if (!prop) { - this.shutdown(); + return false; + } - this.scene.sys.events.off(SceneEvents.START, this.start, this); + if (prop.value && typeof prop.value === 'object') + { + prop = prop.value; + } - this.scene = null; - this.systems = null; + if (prop.configurable === false) + { + return true; + } + + return false; +} + +/** + * Extends the given `myClass` object's prototype with the properties of `definition`. + * + * @function extend + * @ignore + * @param {Object} ctor The constructor object to mix into. + * @param {Object} definition A dictionary of functions for the class. + * @param {boolean} isClassDescriptor Is the definition a class descriptor? + * @param {Object} [extend] The parent constructor object. + */ +function extend (ctor, definition, isClassDescriptor, extend) +{ + for (var k in definition) + { + if (!definition.hasOwnProperty(k)) + { + continue; + } + + var def = getProperty(definition, k, isClassDescriptor); + + if (def !== false) + { + // If Extends is used, we will check its prototype to see if the final variable exists. + + var parent = extend || ctor; + + if (hasNonConfigurable(parent.prototype, k)) + { + // Just skip the final property + if (Class.ignoreFinals) + { + continue; + } + + // We cannot re-define a property that is configurable=false. + // So we will consider them final and throw an error. This is by + // default so it is clear to the developer what is happening. + // You can set ignoreFinals to true if you need to extend a class + // which has configurable=false; it will simply not re-define final properties. + throw new Error('cannot override final property \'' + k + '\', set Class.ignoreFinals = true to skip'); + } + + Object.defineProperty(ctor.prototype, k, def); + } + else + { + ctor.prototype[k] = definition[k]; + } + } +} + +/** + * Applies the given `mixins` to the prototype of `myClass`. + * + * @function mixin + * @ignore + * @param {Object} myClass The constructor object to mix into. + * @param {Object|Array} mixins The mixins to apply to the constructor. + */ +function mixin (myClass, mixins) +{ + if (!mixins) + { + return; + } + + if (!Array.isArray(mixins)) + { + mixins = [ mixins ]; + } + + for (var i = 0; i < mixins.length; i++) + { + extend(myClass, mixins[i].prototype || mixins[i]); + } +} + +/** + * Creates a new class with the given descriptor. + * The constructor, defined by the name `initialize`, + * is an optional function. If unspecified, an anonymous + * function will be used which calls the parent class (if + * one exists). + * + * You can also use `Extends` and `Mixins` to provide subclassing + * and inheritance. + * + * @class Phaser.Class + * @constructor + * @param {Object} definition a dictionary of functions for the class + * @example + * + * var MyClass = new Phaser.Class({ + * + * initialize: function() { + * this.foo = 2.0; + * }, + * + * bar: function() { + * return this.foo + 5; + * } + * }); + */ +function Class (definition) +{ + if (!definition) + { + definition = {}; + } + + // The variable name here dictates what we see in Chrome debugger + var initialize; + var Extends; + + if (definition.initialize) + { + if (typeof definition.initialize !== 'function') + { + throw new Error('initialize must be a function'); + } + + initialize = definition.initialize; + + // Usually we should avoid 'delete' in V8 at all costs. + // However, its unlikely to make any performance difference + // here since we only call this on class creation (i.e. not object creation). + delete definition.initialize; + } + else if (definition.Extends) + { + var base = definition.Extends; + + initialize = function () + { + base.apply(this, arguments); + }; + } + else + { + initialize = function () {}; + } + + if (definition.Extends) + { + initialize.prototype = Object.create(definition.Extends.prototype); + initialize.prototype.constructor = initialize; + + // For getOwnPropertyDescriptor to work, we need to act directly on the Extends (or Mixin) + + Extends = definition.Extends; + + delete definition.Extends; + } + else + { + initialize.prototype.constructor = initialize; + } + + // Grab the mixins, if they are specified... + var mixins = null; + + if (definition.Mixins) + { + mixins = definition.Mixins; + delete definition.Mixins; } -}); + // First, mixin if we can. + mixin(initialize, mixins); + + // Now we grab the actual definition which defines the overrides. + extend(initialize, definition, true, Extends); + + return initialize; +} -PluginCache.register('TweenManager', TweenManager, 'tweens'); +Class.extend = extend; +Class.mixin = mixin; +Class.ignoreFinals = false; -module.exports = TweenManager; +module.exports = Class; /***/ }), -/* 1481 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72283: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Utils + * A NOOP (No Operation) callback function. + * + * Used internally by Phaser when it's more expensive to determine if a callback exists + * than it is to just invoke an empty function. + * + * @function Phaser.Utils.NOOP + * @since 3.0.0 */ - -module.exports = { - - Array: __webpack_require__(208), - Base64: __webpack_require__(1482), - Objects: __webpack_require__(1484), - String: __webpack_require__(1488), - NOOP: __webpack_require__(1) - +var NOOP = function () +{ + // NOOP }; +module.exports = NOOP; + /***/ }), -/* 1482 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 10618: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Utils.Base64 + * A NULL OP callback function. + * + * This function always returns `null`. + * + * Used internally by Phaser when it's more expensive to determine if a callback exists + * than it is to just invoke an empty function. + * + * @function Phaser.Utils.NULL + * @since 3.60.0 */ - -module.exports = { - - ArrayBufferToBase64: __webpack_require__(1483), - Base64ToArrayBuffer: __webpack_require__(433) - +var NULL = function () +{ + return null; }; +module.exports = NULL; + /***/ }), -/* 1483 */ -/***/ (function(module, exports) { + +/***/ 78991: +/***/ ((module) => { /** - * @author Niklas von Hertzen (https://github.com/niklasvh/base64-arraybuffer) * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - /** - * Converts an ArrayBuffer into a base64 string. - * - * The resulting string can optionally be a data uri if the `mediaType` argument is provided. - * - * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs for more details. + * Adds the given item, or array of items, to the array. * - * @function Phaser.Utils.Base64.ArrayBufferToBase64 - * @since 3.18.0 - * - * @param {ArrayBuffer} arrayBuffer - The Array Buffer to encode. - * @param {string} [mediaType] - An optional media type, i.e. `audio/ogg` or `image/jpeg`. If included the resulting string will be a data URI. - * - * @return {string} The base64 encoded Array Buffer. + * Each item must be unique within the array. + * + * The array is modified in-place and returned. + * + * You can optionally specify a limit to the maximum size of the array. If the quantity of items being + * added will take the array length over this limit, it will stop adding once the limit is reached. + * + * You can optionally specify a callback to be invoked for each item successfully added to the array. + * + * @function Phaser.Utils.Array.Add + * @since 3.4.0 + * + * @param {array} array - The array to be added to. + * @param {any|any[]} item - The item, or array of items, to add to the array. Each item must be unique within the array. + * @param {number} [limit] - Optional limit which caps the size of the array. + * @param {function} [callback] - A callback to be invoked for each item successfully added to the array. + * @param {object} [context] - The context in which the callback is invoked. + * + * @return {array} The input array. */ -var ArrayBufferToBase64 = function (arrayBuffer, mediaType) +var Add = function (array, item, limit, callback, context) { - var bytes = new Uint8Array(arrayBuffer); - var len = bytes.length; - - var base64 = (mediaType) ? 'data:' + mediaType + ';base64,' : ''; + if (context === undefined) { context = array; } - for (var i = 0; i < len; i += 3) + if (limit > 0) { - base64 += chars[bytes[i] >> 2]; - base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; - base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; - base64 += chars[bytes[i + 2] & 63]; + var remaining = limit - array.length; + + // There's nothing more we can do here, the array is full + if (remaining <= 0) + { + return null; + } } - if ((len % 3) === 2) + // Fast path to avoid array mutation and iteration + if (!Array.isArray(item)) { - base64 = base64.substring(0, base64.length - 1) + '='; + if (array.indexOf(item) === -1) + { + array.push(item); + + if (callback) + { + callback.call(context, item); + } + + return item; + } + else + { + return null; + } } - else if (len % 3 === 1) + + // If we got this far, we have an array of items to insert + + // Ensure all the items are unique + var itemLength = item.length - 1; + + while (itemLength >= 0) { - base64 = base64.substring(0, base64.length - 2) + '=='; + if (array.indexOf(item[itemLength]) !== -1) + { + // Already exists in array, so remove it + item.splice(itemLength, 1); + } + + itemLength--; } - - return base64; -}; -module.exports = ArrayBufferToBase64; + // Anything left? + itemLength = item.length; + if (itemLength === 0) + { + return null; + } -/***/ }), -/* 1484 */ -/***/ (function(module, exports, __webpack_require__) { + if (limit > 0 && itemLength > remaining) + { + item.splice(remaining); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + itemLength = remaining; + } -/** - * @namespace Phaser.Utils.Objects - */ + for (var i = 0; i < itemLength; i++) + { + var entry = item[i]; -module.exports = { + array.push(entry); - Clone: __webpack_require__(77), - DeepCopy: __webpack_require__(175), - Extend: __webpack_require__(17), - GetAdvancedValue: __webpack_require__(13), - GetFastValue: __webpack_require__(2), - GetMinMaxValue: __webpack_require__(1485), - GetValue: __webpack_require__(6), - HasAll: __webpack_require__(1486), - HasAny: __webpack_require__(455), - HasValue: __webpack_require__(126), - IsPlainObject: __webpack_require__(7), - Merge: __webpack_require__(127), - MergeRight: __webpack_require__(1487), - Pick: __webpack_require__(571), - SetValue: __webpack_require__(478) + if (callback) + { + callback.call(context, entry); + } + } + return item; }; +module.exports = Add; + /***/ }), -/* 1485 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 48522: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var GetValue = __webpack_require__(6); -var Clamp = __webpack_require__(18); - /** - * Retrieves and clamps a numerical value from an object. + * Adds the given item, or array of items, to the array starting at the index specified. * - * @function Phaser.Utils.Objects.GetMinMaxValue - * @since 3.0.0 + * Each item must be unique within the array. * - * @param {object} source - The object to retrieve the value from. - * @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`). - * @param {number} min - The minimum value which can be returned. - * @param {number} max - The maximum value which can be returned. - * @param {number} defaultValue - The value to return if the property doesn't exist. It's also constrained to the given bounds. + * Existing elements in the array are shifted up. * - * @return {number} The clamped value from the `source` object. + * The array is modified in-place and returned. + * + * You can optionally specify a limit to the maximum size of the array. If the quantity of items being + * added will take the array length over this limit, it will stop adding once the limit is reached. + * + * You can optionally specify a callback to be invoked for each item successfully added to the array. + * + * @function Phaser.Utils.Array.AddAt + * @since 3.4.0 + * + * @param {array} array - The array to be added to. + * @param {any|any[]} item - The item, or array of items, to add to the array. + * @param {number} [index=0] - The index in the array where the item will be inserted. + * @param {number} [limit] - Optional limit which caps the size of the array. + * @param {function} [callback] - A callback to be invoked for each item successfully added to the array. + * @param {object} [context] - The context in which the callback is invoked. + * + * @return {array} The input array. */ -var GetMinMaxValue = function (source, key, min, max, defaultValue) +var AddAt = function (array, item, index, limit, callback, context) { - if (defaultValue === undefined) { defaultValue = min; } + if (index === undefined) { index = 0; } + if (context === undefined) { context = array; } - var value = GetValue(source, key, defaultValue); + if (limit > 0) + { + var remaining = limit - array.length; - return Clamp(value, min, max); + // There's nothing more we can do here, the array is full + if (remaining <= 0) + { + return null; + } + } + + // Fast path to avoid array mutation and iteration + if (!Array.isArray(item)) + { + if (array.indexOf(item) === -1) + { + array.splice(index, 0, item); + + if (callback) + { + callback.call(context, item); + } + + return item; + } + else + { + return null; + } + } + + // If we got this far, we have an array of items to insert + + // Ensure all the items are unique + var itemLength = item.length - 1; + + while (itemLength >= 0) + { + if (array.indexOf(item[itemLength]) !== -1) + { + // Already exists in array, so remove it + item.pop(); + } + + itemLength--; + } + + // Anything left? + itemLength = item.length; + + if (itemLength === 0) + { + return null; + } + + // Truncate to the limit + if (limit > 0 && itemLength > remaining) + { + item.splice(remaining); + + itemLength = remaining; + } + + for (var i = itemLength - 1; i >= 0; i--) + { + var entry = item[i]; + + array.splice(index, 0, entry); + + if (callback) + { + callback.call(context, entry); + } + } + + return item; }; -module.exports = GetMinMaxValue; +module.exports = AddAt; /***/ }), -/* 1486 */ -/***/ (function(module, exports) { + +/***/ 58742: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Verifies that an object contains all requested keys + * Moves the given element to the top of the array. + * The array is modified in-place. * - * @function Phaser.Utils.Objects.HasAll - * @since 3.0.0 + * @function Phaser.Utils.Array.BringToTop + * @since 3.4.0 * - * @param {object} source - an object on which to check for key existence - * @param {string[]} keys - an array of keys to ensure the source object contains + * @param {array} array - The array. + * @param {*} item - The element to move. * - * @return {boolean} true if the source object contains all keys, false otherwise. + * @return {*} The element that was moved. */ -var HasAll = function (source, keys) +var BringToTop = function (array, item) { - for (var i = 0; i < keys.length; i++) + var currentIndex = array.indexOf(item); + + if (currentIndex !== -1 && currentIndex < array.length) { - if (!source.hasOwnProperty(keys[i])) - { - return false; - } + array.splice(currentIndex, 1); + array.push(item); } - return true; + return item; }; -module.exports = HasAll; +module.exports = BringToTop; /***/ }), -/* 1487 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 30164: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Clone = __webpack_require__(77); +var SafeRange = __webpack_require__(45838); /** - * Creates a new Object using all values from obj1. - * - * Then scans obj2. If a property is found in obj2 that *also* exists in obj1, the value from obj2 is used, otherwise the property is skipped. + * Returns the total number of elements in the array which have a property matching the given value. * - * @function Phaser.Utils.Objects.MergeRight - * @since 3.0.0 + * @function Phaser.Utils.Array.CountAllMatching + * @since 3.4.0 * - * @param {object} obj1 - The first object to merge. - * @param {object} obj2 - The second object to merge. Keys from this object which also exist in `obj1` will be copied to `obj1`. + * @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] - An optional start index to search from. + * @param {number} [endIndex] - An optional end index to search to. * - * @return {object} The merged object. `obj1` and `obj2` are not modified. + * @return {number} The total number of elements with properties matching the given value. */ -var MergeRight = function (obj1, obj2) +var CountAllMatching = function (array, property, value, startIndex, endIndex) { - var clone = Clone(obj1); + if (startIndex === undefined) { startIndex = 0; } + if (endIndex === undefined) { endIndex = array.length; } - for (var key in obj2) + var total = 0; + + if (SafeRange(array, startIndex, endIndex)) { - if (clone.hasOwnProperty(key)) + for (var i = startIndex; i < endIndex; i++) { - clone[key] = obj2[key]; + var child = array[i]; + + if (child[property] === value) + { + total++; + } } } - return clone; + return total; }; -module.exports = MergeRight; +module.exports = CountAllMatching; /***/ }), -/* 1488 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 36337: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @namespace Phaser.Utils.String + * Passes each element in the array to the given callback. + * + * @function Phaser.Utils.Array.Each + * @since 3.4.0 + * + * @param {array} array - The array to search. + * @param {function} callback - A callback to be invoked for each item in the array. + * @param {object} context - The context in which the callback is invoked. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the current array item. + * + * @return {array} The input array. */ +var Each = function (array, callback, context) +{ + var i; + var args = [ null ]; -module.exports = { + for (i = 3; i < arguments.length; i++) + { + args.push(arguments[i]); + } - Format: __webpack_require__(1489), - Pad: __webpack_require__(186), - RemoveAt: __webpack_require__(1490), - Reverse: __webpack_require__(1491), - UppercaseFirst: __webpack_require__(205), - UUID: __webpack_require__(222) + for (i = 0; i < array.length; i++) + { + args[0] = array[i]; + + callback.apply(context, args); + } + return array; }; +module.exports = Each; + /***/ }), -/* 1489 */ -/***/ (function(module, exports) { + +/***/ 46208: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var SafeRange = __webpack_require__(45838); + /** - * Takes a string and replaces instances of markers with values in the given array. - * The markers take the form of `%1`, `%2`, etc. I.e.: - * - * `Format("The %1 is worth %2 gold", [ 'Sword', 500 ])` + * Passes each element in the array, between the start and end indexes, to the given callback. * - * @function Phaser.Utils.String.Format - * @since 3.0.0 + * @function Phaser.Utils.Array.EachInRange + * @since 3.4.0 * - * @param {string} string - The string containing the replacement markers. - * @param {array} values - An array containing values that will replace the markers. If no value exists an empty string is inserted instead. + * @param {array} array - The array to search. + * @param {function} callback - A callback to be invoked for each item in the array. + * @param {object} context - The context in which the callback is invoked. + * @param {number} startIndex - The start index to search from. + * @param {number} endIndex - The end index to search to. + * @param {...*} [args] - Additional arguments that will be passed to the callback, after the child. * - * @return {string} The string containing replaced values. + * @return {array} The input array. */ -var Format = function (string, values) +var EachInRange = function (array, callback, context, startIndex, endIndex) { - return string.replace(/%([0-9]+)/g, function (s, n) + if (startIndex === undefined) { startIndex = 0; } + if (endIndex === undefined) { endIndex = array.length; } + + if (SafeRange(array, startIndex, endIndex)) { - return values[Number(n) - 1]; - }); + var i; + var args = [ null ]; + + for (i = 5; i < arguments.length; i++) + { + args.push(arguments[i]); + } + + for (i = startIndex; i < endIndex; i++) + { + args[0] = array[i]; + + callback.apply(context, args); + } + } + + return array; }; -module.exports = Format; +module.exports = EachInRange; /***/ }), -/* 1490 */ -/***/ (function(module, exports) { + +/***/ 2406: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Takes a string and removes the character at the given index. + * Searches a pre-sorted array for the closet value to the given number. * - * @function Phaser.Utils.String.RemoveAt - * @since 3.50.0 + * If the `key` argument is given it will assume the array contains objects that all have the required `key` property name, + * and will check for the closest value of those to the given number. * - * @param {string} string - The string to be worked on. - * @param {number} index - The index of the character to be removed. + * @function Phaser.Utils.Array.FindClosestInSorted + * @since 3.0.0 * - * @return {string} The modified string. + * @param {number} value - The value to search for in the array. + * @param {array} array - The array to search, which must be sorted. + * @param {string} [key] - An optional property key. If specified the array elements property will be checked against value. + * + * @return {(number|any)} The nearest value found in the array, or if a `key` was given, the nearest object with the matching property value. */ -var RemoveAt = function (string, index) +var FindClosestInSorted = function (value, array, key) { - if (index === 0) + if (!array.length) { - return string.slice(1); + return NaN; + } + else if (array.length === 1) + { + return array[0]; + } + + var i = 1; + var low; + var high; + + if (key) + { + if (value < array[0][key]) + { + return array[0]; + } + + while (array[i][key] < value) + { + i++; + } } else { - return string.slice(0, index - 1) + string.slice(index); + while (array[i] < value) + { + i++; + } + } + + if (i > array.length) + { + i = array.length; + } + + if (key) + { + low = array[i - 1][key]; + high = array[i][key]; + + return ((high - value) <= (value - low)) ? array[i] : array[i - 1]; + } + else + { + low = array[i - 1]; + high = array[i]; + + return ((high - value) <= (value - low)) ? high : low; } }; -module.exports = RemoveAt; +module.exports = FindClosestInSorted; /***/ }), -/* 1491 */ -/***/ (function(module, exports) { + +/***/ 5454: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Takes the given string and reverses it, returning the reversed string. - * For example if given the string `Atari 520ST` it would return `TS025 iratA`. + * Takes an array and flattens it, returning a shallow-copy flattened array. * - * @function Phaser.Utils.String.Reverse - * @since 3.0.0 + * @function Phaser.Utils.Array.Flatten + * @since 3.60.0 * - * @param {string} string - The string to be reversed. + * @param {array} array - The array to flatten. + * @param {array} [output] - An array to hold the results in. * - * @return {string} The reversed string. + * @return {array} The flattened output array. */ -var Reverse = function (string) +var Flatten = function (array, output) { - return string.split('').reverse().join(''); + if (output === undefined) { output = []; } + + for (var i = 0; i < array.length; i++) + { + if (Array.isArray(array[i])) + { + Flatten(array[i], output); + } + else + { + output.push(array[i]); + } + } + + return output; }; -module.exports = Reverse; +module.exports = Flatten; /***/ }), -/* 1492 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 71608: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @author Pavle Goloskokovic (http://prunegames.com) - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var SafeRange = __webpack_require__(45838); + /** - * @namespace Phaser.Sound + * Returns all elements in the array. + * + * You can optionally specify a matching criteria using the `property` and `value` arguments. + * + * For example: `getAll('visible', true)` would return only elements that have their visible property set. + * + * Optionally you can specify a start and end index. For example if the array had 100 elements, + * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only + * the first 50 elements. + * + * @function Phaser.Utils.Array.GetAll + * @since 3.4.0 + * + * @param {array} array - The array to search. + * @param {string} [property] - The property to test on each array element. + * @param {*} [value] - The value to test the property against. Must pass a strict (`===`) comparison check. + * @param {number} [startIndex] - An optional start index to search from. + * @param {number} [endIndex] - An optional end index to search to. + * + * @return {array} All matching elements from the array. */ +var GetAll = function (array, property, value, startIndex, endIndex) +{ + if (startIndex === undefined) { startIndex = 0; } + if (endIndex === undefined) { endIndex = array.length; } -module.exports = { - - SoundManagerCreator: __webpack_require__(426), - - Events: __webpack_require__(70), - - BaseSound: __webpack_require__(146), - BaseSoundManager: __webpack_require__(145), - - WebAudioSound: __webpack_require__(434), - WebAudioSoundManager: __webpack_require__(432), + var output = []; - HTML5AudioSound: __webpack_require__(429), - HTML5AudioSoundManager: __webpack_require__(427), + if (SafeRange(array, startIndex, endIndex)) + { + for (var i = startIndex; i < endIndex; i++) + { + var child = array[i]; - NoAudioSound: __webpack_require__(431), - NoAudioSoundManager: __webpack_require__(430) + if (!property || + (property && value === undefined && child.hasOwnProperty(property)) || + (property && value !== undefined && child[property] === value)) + { + output.push(child); + } + } + } + return output; }; +module.exports = GetAll; + /***/ }), -/* 1493 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 51463: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @namespace Phaser.Physics - */ +var SafeRange = __webpack_require__(45838); /** - * @namespace Phaser.Types.Physics + * 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; } -module.exports = { + if (SafeRange(array, startIndex, endIndex)) + { + for (var i = startIndex; i < endIndex; i++) + { + var child = array[i]; - Arcade: __webpack_require__(1366), - Matter: __webpack_require__(1494) + if (!property || + (property && value === undefined && child.hasOwnProperty(property)) || + (property && value !== undefined && child[property] === value)) + { + return child; + } + } + } + return null; }; - -/***/ }), -/* 1494 */ -/***/ (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 - */ - -module.exports = { - - BodyBounds: __webpack_require__(1392), - Components: __webpack_require__(249), - Events: __webpack_require__(272), - Factory: __webpack_require__(1394), - MatterGameObject: __webpack_require__(1395), - Image: __webpack_require__(1396), - Matter: __webpack_require__(594), - MatterPhysics: __webpack_require__(1524), - PolyDecomp: __webpack_require__(1393), - Sprite: __webpack_require__(1397), - TileBody: __webpack_require__(593), - PhysicsEditorParser: __webpack_require__(589), - PhysicsJSONParser: __webpack_require__(590), - PointerConstraint: __webpack_require__(1398), - World: __webpack_require__(1402) - -}; +module.exports = GetFirst; /***/ }), -/* 1495 */ -/***/ (function(module, exports) { + +/***/ 72861: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * A component to set restitution on objects. + * Returns a Random element from the array. * - * @namespace Phaser.Physics.Matter.Components.Bounce + * @function Phaser.Utils.Array.GetRandom * @since 3.0.0 + * + * @param {array} array - The array to select the random entry from. + * @param {number} [startIndex=0] - An optional start index. + * @param {number} [length=array.length] - An optional length, the total number of elements (from the startIndex) to choose from. + * + * @return {*} A random element from the array, or `null` if no element could be found in the range given. */ -var Bounce = { - - /** - * Sets the restitution on the physics object. - * - * @method Phaser.Physics.Matter.Components.Bounce#setBounce - * @since 3.0.0 - * - * @param {number} value - A Number that defines the restitution (elasticity) of the body. The value is always positive and is in the range (0, 1). A value of 0 means collisions may be perfectly inelastic and no bouncing may occur. A value of 0.8 means the body may bounce back with approximately 80% of its kinetic energy. Note that collision response is based on pairs of bodies, and that restitution values are combined with the following formula: `Math.max(bodyA.restitution, bodyB.restitution)` - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setBounce: function (value) - { - this.body.restitution = value; +var GetRandom = function (array, startIndex, length) +{ + if (startIndex === undefined) { startIndex = 0; } + if (length === undefined) { length = array.length; } - return this; - } + var randomIndex = startIndex + Math.floor(Math.random() * length); + return (array[randomIndex] === undefined) ? null : array[randomIndex]; }; -module.exports = Bounce; +module.exports = GetRandom; /***/ }), -/* 1496 */ -/***/ (function(module, exports) { + +/***/ 24218: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Contains methods for changing the collision filter of a Matter Body. Should be used as a mixin and not called directly. + * Moves the given array element above another one in the array. + * The array is modified in-place. * - * @namespace Phaser.Physics.Matter.Components.Collision - * @since 3.0.0 + * @function Phaser.Utils.Array.MoveAbove + * @since 3.55.0 + * + * @param {array} array - The input array. + * @param {*} item1 - The element to move above base element. + * @param {*} item2 - The base element. + * + * + * @return {array} The input array. */ -var Collision = { - - /** - * Sets the collision category of this Game Object's Matter Body. This number must be a power of two between 2^0 (= 1) and 2^31. - * Two bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision - * categories are included in their collision masks (see {@link #setCollidesWith}). - * - * @method Phaser.Physics.Matter.Components.Collision#setCollisionCategory - * @since 3.0.0 - * - * @param {number} value - Unique category bitfield. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setCollisionCategory: function (value) - { - this.body.collisionFilter.category = value; - - return this; - }, - - /** - * Sets the collision group of this Game Object's Matter Body. If this is zero or two Matter Bodies have different values, - * they will collide according to the usual rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}). - * If two Matter Bodies have the same positive value, they will always collide; if they have the same negative value, - * they will never collide. - * - * @method Phaser.Physics.Matter.Components.Collision#setCollisionGroup - * @since 3.0.0 - * - * @param {number} value - Unique group index. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setCollisionGroup: function (value) - { - this.body.collisionFilter.group = value; - - return this; - }, - - /** - * Sets the collision mask for this Game Object's Matter Body. Two Matter Bodies with different collision groups will only - * collide if each one includes the other's category in its mask based on a bitwise AND, i.e. `(categoryA & maskB) !== 0` - * and `(categoryB & maskA) !== 0` are both true. - * - * @method Phaser.Physics.Matter.Components.Collision#setCollidesWith - * @since 3.0.0 - * - * @param {(number|number[])} categories - A unique category bitfield, or an array of them. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setCollidesWith: function (categories) +var MoveAbove = function (array, item1, item2) +{ + if (item1 === item2) { - var flags = 0; - - if (!Array.isArray(categories)) - { - flags = categories; - } - else - { - for (var i = 0; i < categories.length; i++) - { - flags |= categories[i]; - } - } - - this.body.collisionFilter.mask = flags; + return array; + } - return this; - }, + var currentIndex = array.indexOf(item1); + var baseIndex = array.indexOf(item2); - /** - * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. - * - * This does not change the bodies collision category, group or filter. Those must be set in addition - * to the callback. - * - * @method Phaser.Physics.Matter.Components.Collision#setOnCollide - * @since 3.22.0 - * - * @param {function} callback - The callback to invoke when this body starts colliding with another. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setOnCollide: function (callback) + if (currentIndex < 0 || baseIndex < 0) { - this.body.onCollideCallback = callback; - - return this; - }, + throw new Error('Supplied items must be elements of the same array'); + } - /** - * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. - * - * This does not change the bodies collision category, group or filter. Those must be set in addition - * to the callback. - * - * @method Phaser.Physics.Matter.Components.Collision#setOnCollideEnd - * @since 3.22.0 - * - * @param {function} callback - The callback to invoke when this body stops colliding with another. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setOnCollideEnd: function (callback) + if (currentIndex > baseIndex) { - this.body.onCollideEndCallback = callback; + // item1 is already above item2 + return array; + } - return this; - }, + // Remove + array.splice(currentIndex, 1); - /** - * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. - * - * This does not change the bodies collision category, group or filter. Those must be set in addition - * to the callback. - * - * @method Phaser.Physics.Matter.Components.Collision#setOnCollideActive - * @since 3.22.0 - * - * @param {function} callback - The callback to invoke for the duration of this body colliding with another. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setOnCollideActive: function (callback) + // Add in new location + if (baseIndex === array.length - 1) { - this.body.onCollideActiveCallback = callback; - - return this; - }, - - /** - * The callback is sent a reference to the other body, along with a `Phaser.Types.Physics.Matter.MatterCollisionData` object. - * - * This does not change the bodies collision category, group or filter. Those must be set in addition - * to the callback. - * - * @method Phaser.Physics.Matter.Components.Collision#setOnCollideWith - * @since 3.22.0 - * - * @param {(MatterJS.Body|MatterJS.Body[])} body - The body, or an array of bodies, to test for collisions with. - * @param {function} callback - The callback to invoke when this body collides with the given body or bodies. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setOnCollideWith: function (body, callback) + array.push(item1); + } + else { - if (!Array.isArray(body)) - { - body = [ body ]; - } - - for (var i = 0; i < body.length; i++) - { - var src = (body[i].hasOwnProperty('body')) ? body[i].body : body[i]; - - this.body.setOnCollideWith(src, callback); - } - - return this; + array.splice(baseIndex, 0, item1); } + return array; }; -module.exports = Collision; +module.exports = MoveAbove; /***/ }), -/* 1497 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 58258: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(41); - /** - * A component to apply force to Matter.js bodies. + * Moves the given array element below another one in the array. + * The array is modified in-place. * - * @namespace Phaser.Physics.Matter.Components.Force - * @since 3.0.0 + * @function Phaser.Utils.Array.MoveBelow + * @since 3.55.0 + * + * @param {array} array - The input array. + * @param {*} item1 - The element to move below base element. + * @param {*} item2 - The base element. + * + * + * @return {array} The input array. */ -var Force = { - - // force = vec2 / point - - /** - * Applies a force to a body. - * - * @method Phaser.Physics.Matter.Components.Force#applyForce - * @since 3.0.0 - * - * @param {Phaser.Math.Vector2} force - A Vector that specifies the force to apply. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - applyForce: function (force) +var MoveBelow = function (array, item1, item2) +{ + if (item1 === item2) { - this._tempVec2.set(this.body.position.x, this.body.position.y); - - Body.applyForce(this.body, this._tempVec2, force); + return array; + } - return this; - }, + var currentIndex = array.indexOf(item1); + var baseIndex = array.indexOf(item2); - /** - * Applies a force to a body from a given position. - * - * @method Phaser.Physics.Matter.Components.Force#applyForceFrom - * @since 3.0.0 - * - * @param {Phaser.Math.Vector2} position - The position in which the force comes from. - * @param {Phaser.Math.Vector2} force - A Vector that specifies the force to apply. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - applyForceFrom: function (position, force) + if (currentIndex < 0 || baseIndex < 0) { - Body.applyForce(this.body, position, force); - - return this; - }, + throw new Error('Supplied items must be elements of the same array'); + } - /** - * Apply thrust to the forward position of the body. - * - * Use very small values, such as 0.1, depending on the mass and required speed. - * - * @method Phaser.Physics.Matter.Components.Force#thrust - * @since 3.0.0 - * - * @param {number} speed - A speed value to be applied to a directional force. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - thrust: function (speed) + if (currentIndex < baseIndex) { - var angle = this.body.angle; - - this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle)); - - Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2); + // item1 is already below item2 + return array; + } - return this; - }, + // Remove + array.splice(currentIndex, 1); - /** - * Apply thrust to the left position of the body. - * - * Use very small values, such as 0.1, depending on the mass and required speed. - * - * @method Phaser.Physics.Matter.Components.Force#thrustLeft - * @since 3.0.0 - * - * @param {number} speed - A speed value to be applied to a directional force. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - thrustLeft: function (speed) + // Add in new location + if (baseIndex === 0) { - var angle = this.body.angle - Math.PI / 2; + array.unshift(item1); + } + else + { + array.splice(baseIndex, 0, item1); + } - this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle)); + return array; +}; - Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2); +module.exports = MoveBelow; - return this; - }, - /** - * Apply thrust to the right position of the body. - * - * Use very small values, such as 0.1, depending on the mass and required speed. - * - * @method Phaser.Physics.Matter.Components.Force#thrustRight - * @since 3.0.0 - * - * @param {number} speed - A speed value to be applied to a directional force. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - thrustRight: function (speed) - { - var angle = this.body.angle + Math.PI / 2; +/***/ }), - this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle)); +/***/ 51172: +/***/ ((module) => { - Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +/** + * Moves the given array element down one place in the array. + * The array is modified in-place. + * + * @function Phaser.Utils.Array.MoveDown + * @since 3.4.0 + * + * @param {array} array - The input array. + * @param {*} item - The element to move down the array. + * + * @return {array} The input array. + */ +var MoveDown = function (array, item) +{ + var currentIndex = array.indexOf(item); - /** - * Apply thrust to the back position of the body. - * - * Use very small values, such as 0.1, depending on the mass and required speed. - * - * @method Phaser.Physics.Matter.Components.Force#thrustBack - * @since 3.0.0 - * - * @param {number} speed - A speed value to be applied to a directional force. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - thrustBack: function (speed) + if (currentIndex > 0) { - var angle = this.body.angle - Math.PI; - - this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle)); + var item2 = array[currentIndex - 1]; - Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2); + var index2 = array.indexOf(item2); - return this; + array[currentIndex] = item2; + array[index2] = item; } + return array; }; -module.exports = Force; +module.exports = MoveDown; /***/ }), -/* 1498 */ -/***/ (function(module, exports) { + +/***/ 68396: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * Contains methods for changing the friction of a Game Object's Matter Body. Should be used a mixin, not called directly. + * Moves an element in an array to a new position within the same array. + * The array is modified in-place. * - * @namespace Phaser.Physics.Matter.Components.Friction - * @since 3.0.0 + * @function Phaser.Utils.Array.MoveTo + * @since 3.4.0 + * + * @param {array} array - The array. + * @param {*} item - The element to move. + * @param {number} index - The new index that the element will be moved to. + * + * @return {*} The element that was moved. */ -var Friction = { - - /** - * Sets new friction values for this Game Object's Matter Body. - * - * @method Phaser.Physics.Matter.Components.Friction#setFriction - * @since 3.0.0 - * - * @param {number} value - The new friction of the body, between 0 and 1, where 0 allows the Body to slide indefinitely, while 1 allows it to stop almost immediately after a force is applied. - * @param {number} [air] - If provided, the new air resistance of the Body. The higher the value, the faster the Body will slow as it moves through space. 0 means the body has no air resistance. - * @param {number} [fstatic] - If provided, the new static friction of the Body. The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. 0 means the body will never "stick" when it is nearly stationary. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setFriction: function (value, air, fstatic) - { - this.body.friction = value; - - if (air !== undefined) - { - this.body.frictionAir = air; - } - - if (fstatic !== undefined) - { - this.body.frictionStatic = fstatic; - } - - return this; - }, +var MoveTo = function (array, item, index) +{ + var currentIndex = array.indexOf(item); - /** - * Sets a new air resistance for this Game Object's Matter Body. - * A value of 0 means the Body will never slow as it moves through space. - * The higher the value, the faster a Body slows when moving through space. - * - * @method Phaser.Physics.Matter.Components.Friction#setFrictionAir - * @since 3.0.0 - * - * @param {number} value - The new air resistance for the Body. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setFrictionAir: function (value) + if (currentIndex === -1 || index < 0 || index >= array.length) { - this.body.frictionAir = value; - - return this; - }, + throw new Error('Supplied index out of bounds'); + } - /** - * Sets a new static friction for this Game Object's Matter Body. - * A value of 0 means the Body will never "stick" when it is nearly stationary. - * The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. - * - * @method Phaser.Physics.Matter.Components.Friction#setFrictionStatic - * @since 3.0.0 - * - * @param {number} value - The new static friction for the Body. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setFrictionStatic: function (value) + if (currentIndex !== index) { - this.body.frictionStatic = value; + // Remove + array.splice(currentIndex, 1); - return this; + // Add in new location + array.splice(index, 0, item); } + return item; }; -module.exports = Friction; +module.exports = MoveTo; /***/ }), -/* 1499 */ -/***/ (function(module, exports) { + +/***/ 27555: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * A component to manipulate world gravity for Matter.js bodies. + * Moves the given array element up one place in the array. + * The array is modified in-place. * - * @namespace Phaser.Physics.Matter.Components.Gravity - * @since 3.0.0 + * @function Phaser.Utils.Array.MoveUp + * @since 3.4.0 + * + * @param {array} array - The input array. + * @param {*} item - The element to move up the array. + * + * @return {array} The input array. */ -var Gravity = { +var MoveUp = function (array, item) +{ + var currentIndex = array.indexOf(item); - /** - * A togglable function for ignoring world gravity in real-time on the current body. - * - * @method Phaser.Physics.Matter.Components.Gravity#setIgnoreGravity - * @since 3.0.0 - * - * @param {boolean} value - Set to true to ignore the effect of world gravity, or false to not ignore it. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setIgnoreGravity: function (value) + if (currentIndex !== -1 && currentIndex < array.length - 1) { - this.body.ignoreGravity = value; + // The element one above `item` in the array + var item2 = array[currentIndex + 1]; + var index2 = array.indexOf(item2); - return this; + array[currentIndex] = item2; + array[index2] = item; } + return array; }; -module.exports = Gravity; +module.exports = MoveUp; /***/ }), -/* 1500 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 13401: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(41); -var Vector2 = __webpack_require__(3); - /** - * Allows accessing the mass, density, and center of mass of a Matter-enabled Game Object. Should be used as a mixin and not directly. + * Create an array representing the range of numbers (usually integers), between, and inclusive of, + * the given `start` and `end` arguments. For example: * - * @namespace Phaser.Physics.Matter.Components.Mass + * `var array = Phaser.Utils.Array.NumberArray(2, 4); // array = [2, 3, 4]` + * `var array = Phaser.Utils.Array.NumberArray(0, 9); // array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]` + * `var array = Phaser.Utils.Array.NumberArray(8, 2); // array = [8, 7, 6, 5, 4, 3, 2]` + * + * This is equivalent to `Phaser.Utils.Array.NumberArrayStep(start, end, 1)`. + * + * You can optionally provide a prefix and / or suffix string. If given the array will contain + * strings, not integers. For example: + * + * `var array = Phaser.Utils.Array.NumberArray(1, 4, 'Level '); // array = ["Level 1", "Level 2", "Level 3", "Level 4"]` + * `var array = Phaser.Utils.Array.NumberArray(5, 7, 'HD-', '.png'); // array = ["HD-5.png", "HD-6.png", "HD-7.png"]` + * + * @function Phaser.Utils.Array.NumberArray * @since 3.0.0 + * + * @param {number} start - The minimum value the array starts with. + * @param {number} end - The maximum value the array contains. + * @param {string} [prefix] - Optional prefix to place before the number. If provided the array will contain strings, not integers. + * @param {string} [suffix] - Optional suffix to place after the number. If provided the array will contain strings, not integers. + * + * @return {(number[]|string[])} The array of number values, or strings if a prefix or suffix was provided. */ -var Mass = { - - /** - * Sets the mass of the Game Object's Matter Body. - * - * @method Phaser.Physics.Matter.Components.Mass#setMass - * @since 3.0.0 - * - * @param {number} value - The new mass of the body. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setMass: function (value) - { - Body.setMass(this.body, value); +var NumberArray = function (start, end, prefix, suffix) +{ + var result = []; - return this; - }, + var i; + var asString = false; - /** - * Sets density of the body. - * - * @method Phaser.Physics.Matter.Components.Mass#setDensity - * @since 3.0.0 - * - * @param {number} value - The new density of the body. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setDensity: function (value) + if (prefix || suffix) { - Body.setDensity(this.body, value); + asString = true; - return this; - }, + if (!prefix) + { + prefix = ''; + } - /** - * The body's center of mass. - * - * Calling this creates a new `Vector2 each time to avoid mutation. - * - * If you only need to read the value and won't change it, you can get it from `GameObject.body.centerOfMass`. - * - * @name Phaser.Physics.Matter.Components.Mass#centerOfMass - * @type {Phaser.Math.Vector2} - * @readonly - * @since 3.10.0 - * - * @return {Phaser.Math.Vector2} The center of mass. - */ - centerOfMass: { + if (!suffix) + { + suffix = ''; + } + } - get: function () + if (end < start) + { + for (i = start; i >= end; i--) { - return new Vector2(this.body.centerOfMass.x, this.body.centerOfMass.y); + if (asString) + { + result.push(prefix + i.toString() + suffix); + } + else + { + result.push(i); + } + } + } + else + { + for (i = start; i <= end; i++) + { + if (asString) + { + result.push(prefix + i.toString() + suffix); + } + else + { + result.push(i); + } } } + return result; }; -module.exports = Mass; +module.exports = NumberArray; /***/ }), -/* 1501 */ -/***/ (function(module, exports) { + +/***/ 89955: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var RoundAwayFromZero = __webpack_require__(67233); + /** - * Enables a Matter-enabled Game Object to be a sensor. Should be used as a mixin and not directly. + * Create an array of numbers (positive and/or negative) progressing from `start` + * up to but not including `end` by advancing by `step`. * - * @namespace Phaser.Physics.Matter.Components.Sensor + * If `start` is less than `end` a zero-length range is created unless a negative `step` is specified. + * + * Certain values for `start` and `end` (eg. NaN/undefined/null) are currently coerced to 0; + * for forward compatibility make sure to pass in actual numbers. + * + * @example + * NumberArrayStep(4); + * // => [0, 1, 2, 3] + * + * NumberArrayStep(1, 5); + * // => [1, 2, 3, 4] + * + * NumberArrayStep(0, 20, 5); + * // => [0, 5, 10, 15] + * + * NumberArrayStep(0, -4, -1); + * // => [0, -1, -2, -3] + * + * NumberArrayStep(1, 4, 0); + * // => [1, 1, 1] + * + * NumberArrayStep(0); + * // => [] + * + * @function Phaser.Utils.Array.NumberArrayStep * @since 3.0.0 + * + * @param {number} [start=0] - The start of the range. + * @param {number} [end=null] - The end of the range. + * @param {number} [step=1] - The value to increment or decrement by. + * + * @return {number[]} The array of number values. */ -var Sensor = { +var NumberArrayStep = function (start, end, step) +{ + if (start === undefined) { start = 0; } + if (end === undefined) { end = null; } + if (step === undefined) { step = 1; } - /** - * Set the body belonging to this Game Object to be a sensor. - * Sensors trigger collision events, but don't react with colliding body physically. - * - * @method Phaser.Physics.Matter.Components.Sensor#setSensor - * @since 3.0.0 - * - * @param {boolean} value - `true` to set the body as a sensor, or `false` to disable it. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setSensor: function (value) + if (end === null) { - this.body.isSensor = value; + end = start; + start = 0; + } - return this; - }, + var result = []; - /** - * Is the body belonging to this Game Object a sensor or not? - * - * @method Phaser.Physics.Matter.Components.Sensor#isSensor - * @since 3.0.0 - * - * @return {boolean} `true` if the body is a sensor, otherwise `false`. - */ - isSensor: function () + var total = Math.max(RoundAwayFromZero((end - start) / (step || 1)), 0); + + for (var i = 0; i < total; i++) { - return this.body.isSensor; + result.push(start); + start += step; } + return result; }; -module.exports = Sensor; +module.exports = NumberArrayStep; /***/ }), -/* 1502 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 53466: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Bodies = __webpack_require__(86); -var Body = __webpack_require__(41); -var FuzzyEquals = __webpack_require__(124); -var GetFastValue = __webpack_require__(2); -var PhysicsEditorParser = __webpack_require__(589); -var PhysicsJSONParser = __webpack_require__(590); -var Vertices = __webpack_require__(64); +/** + * @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; +} /** - * Enables a Matter-enabled Game Object to set its Body. Should be used as a mixin and not directly. + * A [Floyd-Rivest](https://en.wikipedia.org/wiki/Floyd%E2%80%93Rivest_algorithm) quick selection algorithm. * - * @namespace Phaser.Physics.Matter.Components.SetBody + * 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 SetBody = { - - /** - * Set the body on a Game Object to a rectangle. - * - * Calling this methods resets previous properties you may have set on the body, including - * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. - * - * @method Phaser.Physics.Matter.Components.SetBody#setRectangle - * @since 3.0.0 - * - * @param {number} width - Width of the rectangle. - * @param {number} height - Height of the rectangle. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setRectangle: function (width, height, options) - { - return this.setBody({ type: 'rectangle', width: width, height: height }, options); - }, - - /** - * Set the body on a Game Object to a circle. - * - * Calling this methods resets previous properties you may have set on the body, including - * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. - * - * @method Phaser.Physics.Matter.Components.SetBody#setCircle - * @since 3.0.0 - * - * @param {number} radius - The radius of the circle. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setCircle: function (radius, options) - { - return this.setBody({ type: 'circle', radius: radius }, options); - }, - - /** - * Set the body on the Game Object to a polygon shape. - * - * Calling this methods resets previous properties you may have set on the body, including - * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. - * - * @method Phaser.Physics.Matter.Components.SetBody#setPolygon - * @since 3.0.0 - * - * @param {number} radius - The "radius" of the polygon, i.e. the distance from its center to any vertex. This is also the radius of its circumcircle. - * @param {number} sides - The number of sides the polygon will have. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setPolygon: function (radius, sides, options) - { - return this.setBody({ type: 'polygon', sides: sides, radius: radius }, options); - }, - - /** - * Set the body on the Game Object to a trapezoid shape. - * - * Calling this methods resets previous properties you may have set on the body, including - * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. - * - * @method Phaser.Physics.Matter.Components.SetBody#setTrapezoid - * @since 3.0.0 - * - * @param {number} width - The width of the trapezoid Body. - * @param {number} height - The height of the trapezoid Body. - * @param {number} slope - The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setTrapezoid: function (width, height, slope, options) - { - return this.setBody({ type: 'trapezoid', width: width, height: height, slope: slope }, options); - }, +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; } - /** - * Set this Game Object to use the given existing Matter Body. - * - * The body is first removed from the world before being added to this Game Object. - * - * @method Phaser.Physics.Matter.Components.SetBody#setExistingBody - * @since 3.0.0 - * - * @param {MatterJS.BodyType} body - The Body this Game Object should use. - * @param {boolean} [addToWorld=true] - Should the body be immediately added to the World? - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setExistingBody: function (body, addToWorld) + while (right > left) { - if (addToWorld === undefined) { addToWorld = true; } - - if (this.body) + if (right - left > 600) { - this.world.remove(this.body, true); - } - - this.body = body; + 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)); - for (var i = 0; i < body.parts.length; i++) - { - body.parts[i].gameObject = this; + QuickSelect(arr, k, newLeft, newRight, compare); } - var _this = this; + var t = arr[k]; + var i = left; + var j = right; - body.destroy = function destroy () - { - _this.world.remove(_this.body, true); - _this.body.gameObject = null; - }; + swap(arr, left, k); - if (addToWorld) + if (compare(arr[right], t) > 0) { - if (this.world.has(body)) - { - // Because it could be part of another Composite - this.world.remove(body, true); - } - - this.world.add(body); + swap(arr, left, right); } - if (this._originComponent) + while (i < j) { - var rx = body.render.sprite.xOffset; - var ry = body.render.sprite.yOffset; + swap(arr, i, j); - var comx = body.centerOfMass.x; - var comy = body.centerOfMass.y; + i++; + j--; - if (FuzzyEquals(comx, 0.5) && FuzzyEquals(comy, 0.5)) + while (compare(arr[i], t) < 0) { - this.setOrigin(rx + 0.5, ry + 0.5); + i++; } - else - { - var cx = body.centerOffset.x; - var cy = body.centerOffset.y; - this.setOrigin(rx + (cx / this.displayWidth), ry + (cy / this.displayHeight)); + while (compare(arr[j], t) > 0) + { + j--; } } - return this; - }, - - /** - * Set this Game Object to create and use a new Body based on the configuration object given. - * - * Calling this method resets previous properties you may have set on the body, including - * plugins, mass, friction, etc. So be sure to re-apply these in the options object if needed. - * - * @method Phaser.Physics.Matter.Components.SetBody#setBody - * @since 3.0.0 - * - * @param {(string|Phaser.Types.Physics.Matter.MatterSetBodyConfig)} config - Either a string, such as `circle`, or a Matter Set Body Configuration object. - * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setBody: function (config, options) - { - if (!config) + if (compare(arr[left], t) === 0) { - return this; + swap(arr, left, j); } - - var body; - - // Allow them to do: shape: 'circle' instead of shape: { type: 'circle' } - if (typeof config === 'string') + else { - // Using defaults - config = { type: config }; + j++; + swap(arr, j, right); } - var shapeType = GetFastValue(config, 'type', 'rectangle'); - var bodyX = GetFastValue(config, 'x', this._tempVec2.x); - var bodyY = GetFastValue(config, 'y', this._tempVec2.y); - var bodyWidth = GetFastValue(config, 'width', this.width); - var bodyHeight = GetFastValue(config, 'height', this.height); - - switch (shapeType) + if (j <= k) { - case 'rectangle': - body = Bodies.rectangle(bodyX, bodyY, bodyWidth, bodyHeight, options); - break; - - case 'circle': - var radius = GetFastValue(config, 'radius', Math.max(bodyWidth, bodyHeight) / 2); - var maxSides = GetFastValue(config, 'maxSides', 25); - body = Bodies.circle(bodyX, bodyY, radius, options, maxSides); - break; - - case 'trapezoid': - var slope = GetFastValue(config, 'slope', 0.5); - body = Bodies.trapezoid(bodyX, bodyY, bodyWidth, bodyHeight, slope, options); - break; - - case 'polygon': - var sides = GetFastValue(config, 'sides', 5); - var pRadius = GetFastValue(config, 'radius', Math.max(bodyWidth, bodyHeight) / 2); - body = Bodies.polygon(bodyX, bodyY, sides, pRadius, options); - break; - - case 'fromVertices': - case 'fromVerts': - - var verts = GetFastValue(config, 'verts', null); - - if (verts) - { - // Has the verts array come from Vertices.fromPath, or is it raw? - if (typeof verts === 'string') - { - verts = Vertices.fromPath(verts); - } - - if (this.body && !this.body.hasOwnProperty('temp')) - { - Body.setVertices(this.body, verts); - - body = this.body; - } - else - { - var flagInternal = GetFastValue(config, 'flagInternal', false); - var removeCollinear = GetFastValue(config, 'removeCollinear', 0.01); - var minimumArea = GetFastValue(config, 'minimumArea', 10); - - body = Bodies.fromVertices(bodyX, bodyY, verts, options, flagInternal, removeCollinear, minimumArea); - } - } - - break; - - case 'fromPhysicsEditor': - body = PhysicsEditorParser.parseBody(bodyX, bodyY, config, options); - break; - - case 'fromPhysicsTracer': - body = PhysicsJSONParser.parseBody(bodyX, bodyY, config, options); - break; + left = j + 1; } - if (body) + if (k <= j) { - this.setExistingBody(body, config.addToWorld); + right = j - 1; } - - return this; } - }; -module.exports = SetBody; +module.exports = QuickSelect; /***/ }), -/* 1503 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 75757: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Events = __webpack_require__(272); -var Sleeping = __webpack_require__(165); -var MatterEvents = __webpack_require__(166); +var GetValue = __webpack_require__(10850); +var Shuffle = __webpack_require__(18592); + +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; +}; /** - * Enables a Matter-enabled Game Object to be able to go to sleep. Should be used as a mixin and not directly. + * Creates an array populated with a range of values, based on the given arguments and configuration object. * - * @namespace Phaser.Physics.Matter.Components.Sleep + * 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 Sleep = { - - /** - * Sets this Body to sleep. - * - * @method Phaser.Physics.Matter.Components.Sleep#setToSleep - * @since 3.22.0 - * - * @return {this} This Game Object. - */ - setToSleep: function () - { - Sleeping.set(this.body, true); +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); - return this; - }, + var out = []; - /** - * Wakes this Body if asleep. - * - * @method Phaser.Physics.Matter.Components.Sleep#setAwake - * @since 3.22.0 - * - * @return {this} This Game Object. - */ - setAwake: function () + if (randomB) { - Sleeping.set(this.body, false); - - return this; - }, + Shuffle(b); + } - /** - * Sets the number of updates in which this body must have near-zero velocity before it is set as sleeping (if sleeping is enabled by the engine). - * - * @method Phaser.Physics.Matter.Components.Sleep#setSleepThreshold - * @since 3.0.0 - * - * @param {number} [value=60] - A `Number` that defines the number of updates in which this body must have near-zero velocity before it is set as sleeping. - * - * @return {this} This Game Object. - */ - setSleepThreshold: function (value) + // Endless repeat, so limit by max + if (repeat === -1) { - if (value === undefined) { value = 60; } - - this.body.sleepThreshold = value; - - return this; - }, + if (max === 0) + { + repeat = 0; + } + else + { + // Work out how many repeats we need + var total = (a.length * b.length) * qty; - /** - * Enable sleep and wake events for this body. - * - * By default when a body goes to sleep, or wakes up, it will not emit any events. - * - * The events are emitted by the Matter World instance and can be listened to via - * the `SLEEP_START` and `SLEEP_END` events. - * - * @method Phaser.Physics.Matter.Components.Sleep#setSleepEvents - * @since 3.0.0 - * - * @param {boolean} start - `true` if you want the sleep start event to be emitted for this body. - * @param {boolean} end - `true` if you want the sleep end event to be emitted for this body. - * - * @return {this} This Game Object. - */ - setSleepEvents: function (start, end) - { - this.setSleepStartEvent(start); - this.setSleepEndEvent(end); + if (yoyo) + { + total *= 2; + } - return this; - }, + repeat = Math.ceil(max / total); + } + } - /** - * Enables or disables the Sleep Start event for this body. - * - * @method Phaser.Physics.Matter.Components.Sleep#setSleepStartEvent - * @since 3.0.0 - * - * @param {boolean} value - `true` to enable the sleep event, or `false` to disable it. - * - * @return {this} This Game Object. - */ - setSleepStartEvent: function (value) + for (var i = 0; i <= repeat; i++) { - if (value) - { - var world = this.world; + var chunk = BuildChunk(a, b, qty); - MatterEvents.on(this.body, 'sleepStart', function (event) - { - world.emit(Events.SLEEP_START, event, this); - }); - } - else + if (random) { - MatterEvents.off(this.body, 'sleepStart'); + Shuffle(chunk); } - return this; - }, + out = out.concat(chunk); - /** - * Enables or disables the Sleep End event for this body. - * - * @method Phaser.Physics.Matter.Components.Sleep#setSleepEndEvent - * @since 3.0.0 - * - * @param {boolean} value - `true` to enable the sleep event, or `false` to disable it. - * - * @return {this} This Game Object. - */ - setSleepEndEvent: function (value) - { - if (value) + if (yoyo) { - var world = this.world; + chunk.reverse(); - MatterEvents.on(this.body, 'sleepEnd', function (event) - { - world.emit(Events.SLEEP_END, event, this); - }); - } - else - { - MatterEvents.off(this.body, 'sleepEnd'); + out = out.concat(chunk); } + } - return this; + if (max) + { + out.splice(max); } + return out; }; -module.exports = Sleep; +module.exports = Range; /***/ }), -/* 1504 */ -/***/ (function(module, exports) { + +/***/ 66458: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @typedef {object} Phaser.Physics.Matter.Events.AfterAddEvent - * - * @property {any[]} object - An array of the object(s) that have been added. May be a single body, constraint, composite or a mixture of these. - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ +var SpliceOne = __webpack_require__(72677); /** - * The Matter Physics After Add Event. - * - * This event is dispatched by a Matter Physics World instance at the end of the process when a new Body - * or Constraint has just been added to the world. - * - * Listen to it from a Scene using: `this.matter.world.on('afteradd', listener)`. + * Removes the given item, or array of items, from the array. * - * @event Phaser.Physics.Matter.Events#AFTER_ADD - * @since 3.22.0 - * - * @param {Phaser.Physics.Matter.Events.AfterAddEvent} event - The Add Event object. + * The array is modified in-place. + * + * You can optionally specify a callback to be invoked for each item successfully removed from the array. + * + * @function Phaser.Utils.Array.Remove + * @since 3.4.0 + * + * @param {array} array - The array to be modified. + * @param {*|Array.<*>} item - The item, or array of items, to be removed from the array. + * @param {function} [callback] - A callback to be invoked for each item successfully removed from the array. + * @param {object} [context] - The context in which the callback is invoked. + * + * @return {*|Array.<*>} The item, or array of items, that were successfully removed from the array. */ -module.exports = 'afteradd'; +var Remove = function (array, item, callback, context) +{ + if (context === undefined) { context = array; } + var index; -/***/ }), -/* 1505 */ -/***/ (function(module, exports) { + // Fast path to avoid array mutation and iteration + if (!Array.isArray(item)) + { + index = array.indexOf(item); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (index !== -1) + { + SpliceOne(array, index); -/** - * @typedef {object} Phaser.Physics.Matter.Events.AfterRemoveEvent - * - * @property {any[]} object - An array of the object(s) that were removed. May be a single body, constraint, composite or a mixture of these. - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ + if (callback) + { + callback.call(context, item); + } -/** - * The Matter Physics After Remove Event. - * - * This event is dispatched by a Matter Physics World instance at the end of the process when a - * Body or Constraint was removed from the world. - * - * Listen to it from a Scene using: `this.matter.world.on('afterremove', listener)`. - * - * @event Phaser.Physics.Matter.Events#AFTER_REMOVE - * @since 3.22.0 - * - * @param {Phaser.Physics.Matter.Events.AfterRemoveEvent} event - The Remove Event object. - */ -module.exports = 'afterremove'; + return item; + } + else + { + return null; + } + } + // If we got this far, we have an array of items to remove -/***/ }), -/* 1506 */ -/***/ (function(module, exports) { + var itemLength = item.length - 1; + var removed = []; -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + while (itemLength >= 0) + { + var entry = item[itemLength]; -/** - * @typedef {object} Phaser.Physics.Matter.Events.AfterUpdateEvent - * - * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ + index = array.indexOf(entry); -/** - * The Matter Physics After Update Event. - * - * This event is dispatched by a Matter Physics World instance after the engine has updated and all collision events have resolved. - * - * Listen to it from a Scene using: `this.matter.world.on('afterupdate', listener)`. - * - * @event Phaser.Physics.Matter.Events#AFTER_UPDATE - * @since 3.0.0 - * - * @param {Phaser.Physics.Matter.Events.AfterUpdateEvent} event - The Update Event object. - */ -module.exports = 'afterupdate'; + if (index !== -1) + { + SpliceOne(array, index); + + removed.push(entry); + + if (callback) + { + callback.call(context, entry); + } + } + + itemLength--; + } + + return removed; +}; + +module.exports = Remove; /***/ }), -/* 1507 */ -/***/ (function(module, exports) { + +/***/ 8324: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @typedef {object} Phaser.Physics.Matter.Events.BeforeAddEvent - * - * @property {any[]} object - An array of the object(s) to be added. May be a single body, constraint, composite or a mixture of these. - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ +var SpliceOne = __webpack_require__(72677); /** - * The Matter Physics Before Add Event. - * - * This event is dispatched by a Matter Physics World instance at the start of the process when a new Body - * or Constraint is being added to the world. - * - * Listen to it from a Scene using: `this.matter.world.on('beforeadd', listener)`. + * Removes the item from the given position in the array. * - * @event Phaser.Physics.Matter.Events#BEFORE_ADD - * @since 3.22.0 - * - * @param {Phaser.Physics.Matter.Events.BeforeAddEvent} event - The Add Event object. + * The array is modified in-place. + * + * You can optionally specify a callback to be invoked for the item if it is successfully removed from the array. + * + * @function Phaser.Utils.Array.RemoveAt + * @since 3.4.0 + * + * @param {array} array - The array to be modified. + * @param {number} index - The array index to remove the item from. The index must be in bounds or it will throw an error. + * @param {function} [callback] - A callback to be invoked for the item removed from the array. + * @param {object} [context] - The context in which the callback is invoked. + * + * @return {*} The item that was removed. */ -module.exports = 'beforeadd'; +var RemoveAt = function (array, index, callback, context) +{ + if (context === undefined) { context = array; } + + if (index < 0 || index > array.length - 1) + { + throw new Error('Index out of bounds'); + } + + var item = SpliceOne(array, index); + + if (callback) + { + callback.call(context, item); + } + + return item; +}; + +module.exports = RemoveAt; /***/ }), -/* 1508 */ -/***/ (function(module, exports) { + +/***/ 47427: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @typedef {object} Phaser.Physics.Matter.Events.BeforeRemoveEvent - * - * @property {any[]} object - An array of the object(s) to be removed. May be a single body, constraint, composite or a mixture of these. - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ +var SafeRange = __webpack_require__(45838); /** - * The Matter Physics Before Remove Event. - * - * This event is dispatched by a Matter Physics World instance at the start of the process when a - * Body or Constraint is being removed from the world. - * - * Listen to it from a Scene using: `this.matter.world.on('beforeremove', listener)`. + * Removes the item within the given range in the array. * - * @event Phaser.Physics.Matter.Events#BEFORE_REMOVE - * @since 3.22.0 - * - * @param {Phaser.Physics.Matter.Events.BeforeRemoveEvent} event - The Remove Event object. + * The array is modified in-place. + * + * You can optionally specify a callback to be invoked for the item/s successfully removed from the array. + * + * @function Phaser.Utils.Array.RemoveBetween + * @since 3.4.0 + * + * @param {array} array - The array to be modified. + * @param {number} startIndex - The start index to remove from. + * @param {number} endIndex - The end index to remove to. + * @param {function} [callback] - A callback to be invoked for the item removed from the array. + * @param {object} [context] - The context in which the callback is invoked. + * + * @return {Array.<*>} An array of items that were removed. */ -module.exports = 'beforeremove'; +var RemoveBetween = function (array, startIndex, endIndex, callback, context) +{ + if (startIndex === undefined) { startIndex = 0; } + if (endIndex === undefined) { endIndex = array.length; } + if (context === undefined) { context = array; } + if (SafeRange(array, startIndex, endIndex)) + { + var size = endIndex - startIndex; -/***/ }), -/* 1509 */ -/***/ (function(module, exports) { + var removed = array.splice(startIndex, size); -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + if (callback) + { + for (var i = 0; i < removed.length; i++) + { + var entry = removed[i]; -/** - * @typedef {object} Phaser.Physics.Matter.Events.BeforeUpdateEvent - * - * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ + callback.call(context, entry); + } + } -/** - * The Matter Physics Before Update Event. - * - * This event is dispatched by a Matter Physics World instance right before all the collision processing takes place. - * - * Listen to it from a Scene using: `this.matter.world.on('beforeupdate', listener)`. - * - * @event Phaser.Physics.Matter.Events#BEFORE_UPDATE - * @since 3.0.0 - * - * @param {Phaser.Physics.Matter.Events.BeforeUpdateEvent} event - The Update Event object. - */ -module.exports = 'beforeupdate'; + return removed; + } + else + { + return []; + } +}; + +module.exports = RemoveBetween; /***/ }), -/* 1510 */ -/***/ (function(module, exports) { + +/***/ 50147: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -/** - * @typedef {object} Phaser.Physics.Matter.Events.CollisionActiveEvent - * - * @property {Phaser.Types.Physics.Matter.MatterCollisionData[]} pairs - A list of all affected pairs in the collision. - * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ +var SpliceOne = __webpack_require__(72677); /** - * The Matter Physics Collision Active Event. - * - * This event is dispatched by a Matter Physics World instance after the engine has updated. - * It provides a list of all pairs that are colliding in the current tick (if any). - * - * Listen to it from a Scene using: `this.matter.world.on('collisionactive', listener)`. + * Removes a random object from the given array and returns it. + * Will return null if there are no array items that fall within the specified range or if there is no item for the randomly chosen index. * - * @event Phaser.Physics.Matter.Events#COLLISION_ACTIVE + * @function Phaser.Utils.Array.RemoveRandomElement * @since 3.0.0 - * - * @param {Phaser.Physics.Matter.Events.CollisionActiveEvent} event - The Collision Event object. - * @param {MatterJS.BodyType} bodyA - The first body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. - * @param {MatterJS.BodyType} bodyB - The second body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. + * + * @param {array} array - The array to removed a random element from. + * @param {number} [start=0] - The array index to start the search from. + * @param {number} [length=array.length] - Optional restriction on the number of elements to randomly select from. + * + * @return {object} The random element that was removed, or `null` if there were no array elements that fell within the given range. */ -module.exports = 'collisionactive'; +var RemoveRandomElement = function (array, start, length) +{ + if (start === undefined) { start = 0; } + if (length === undefined) { length = array.length; } + + var randomIndex = start + Math.floor(Math.random() * length); + + return SpliceOne(array, randomIndex); +}; + +module.exports = RemoveRandomElement; /***/ }), -/* 1511 */ -/***/ (function(module, exports) { + +/***/ 80402: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @typedef {object} Phaser.Physics.Matter.Events.CollisionEndEvent + * Replaces an element of the array with the new element. + * The new element cannot already be a member of the array. + * The array is modified in-place. * - * @property {Phaser.Types.Physics.Matter.MatterCollisionData[]} pairs - A list of all affected pairs in the collision. - * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ - -/** - * The Matter Physics Collision End Event. - * - * This event is dispatched by a Matter Physics World instance after the engine has updated. - * It provides a list of all pairs that have finished colliding in the current tick (if any). - * - * Listen to it from a Scene using: `this.matter.world.on('collisionend', listener)`. + * @function Phaser.Utils.Array.Replace + * @since 3.4.0 * - * @event Phaser.Physics.Matter.Events#COLLISION_END - * @since 3.0.0 - * - * @param {Phaser.Physics.Matter.Events.CollisionEndEvent} event - The Collision Event object. - * @param {MatterJS.BodyType} bodyA - The first body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. - * @param {MatterJS.BodyType} bodyB - The second body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. + * @param {array} array - The array to search within. + * @param {*} oldChild - The element in the array that will be replaced. + * @param {*} newChild - The element to be inserted into the array at the position of `oldChild`. + * + * @return {boolean} Returns true if the oldChild was successfully replaced, otherwise returns false. */ -module.exports = 'collisionend'; +var Replace = function (array, oldChild, newChild) +{ + var index1 = array.indexOf(oldChild); + var index2 = array.indexOf(newChild); + + if (index1 !== -1 && index2 === -1) + { + array[index1] = newChild; + + return true; + } + else + { + return false; + } +}; + +module.exports = Replace; /***/ }), -/* 1512 */ -/***/ (function(module, exports) { + +/***/ 77640: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @typedef {object} Phaser.Physics.Matter.Events.CollisionStartEvent - * - * @property {Phaser.Types.Physics.Matter.MatterCollisionData[]} pairs - A list of all affected pairs in the collision. - * @property {number} timestamp - The Matter Engine `timing.timestamp` value for the event. - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ - -/** - * The Matter Physics Collision Start Event. - * - * This event is dispatched by a Matter Physics World instance after the engine has updated. - * It provides a list of all pairs that have started to collide in the current tick (if any). - * - * Listen to it from a Scene using: `this.matter.world.on('collisionstart', listener)`. + * Moves the element at the start of the array to the end, shifting all items in the process. + * The "rotation" happens to the left. * - * @event Phaser.Physics.Matter.Events#COLLISION_START + * @function Phaser.Utils.Array.RotateLeft * @since 3.0.0 - * - * @param {Phaser.Physics.Matter.Events.CollisionStartEvent} event - The Collision Event object. - * @param {MatterJS.BodyType} bodyA - The first body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. - * @param {MatterJS.BodyType} bodyB - The second body of the first colliding pair. The `event.pairs` array may contain more colliding bodies. + * + * @param {array} array - The array to shift to the left. This array is modified in place. + * @param {number} [total=1] - The number of times to shift the array. + * + * @return {*} The most recently shifted element. */ -module.exports = 'collisionstart'; +var RotateLeft = function (array, total) +{ + if (total === undefined) { total = 1; } + var element = null; -/***/ }), -/* 1513 */ -/***/ (function(module, exports) { + for (var i = 0; i < total; i++) + { + element = array.shift(); + array.push(element); + } -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ + return element; +}; -/** - * The Matter Physics Drag End Event. - * - * This event is dispatched by a Matter Physics World instance when a Pointer Constraint - * stops dragging a body. - * - * Listen to it from a Scene using: `this.matter.world.on('dragend', listener)`. - * - * @event Phaser.Physics.Matter.Events#DRAG_END - * @since 3.16.2 - * - * @param {MatterJS.BodyType} body - The Body that has stopped being dragged. This is a Matter Body, not a Phaser Game Object. - * @param {Phaser.Physics.Matter.PointerConstraint} constraint - The Pointer Constraint that was dragging the body. - */ -module.exports = 'dragend'; +module.exports = RotateLeft; /***/ }), -/* 1514 */ -/***/ (function(module, exports) { + +/***/ 38487: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Matter Physics Drag Event. - * - * This event is dispatched by a Matter Physics World instance when a Pointer Constraint - * is actively dragging a body. It is emitted each time the pointer moves. - * - * Listen to it from a Scene using: `this.matter.world.on('drag', listener)`. + * Moves the element at the end of the array to the start, shifting all items in the process. + * The "rotation" happens to the right. * - * @event Phaser.Physics.Matter.Events#DRAG - * @since 3.16.2 - * - * @param {MatterJS.BodyType} body - The Body that is being dragged. This is a Matter Body, not a Phaser Game Object. - * @param {Phaser.Physics.Matter.PointerConstraint} constraint - The Pointer Constraint that is dragging the body. + * @function Phaser.Utils.Array.RotateRight + * @since 3.0.0 + * + * @param {array} array - The array to shift to the right. This array is modified in place. + * @param {number} [total=1] - The number of times to shift the array. + * + * @return {*} The most recently shifted element. */ -module.exports = 'drag'; +var RotateRight = function (array, total) +{ + if (total === undefined) { total = 1; } + + var element = null; + + for (var i = 0; i < total; i++) + { + element = array.pop(); + array.unshift(element); + } + + return element; +}; + +module.exports = RotateRight; /***/ }), -/* 1515 */ -/***/ (function(module, exports) { + +/***/ 45838: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Matter Physics Drag Start Event. - * - * This event is dispatched by a Matter Physics World instance when a Pointer Constraint - * starts dragging a body. - * - * Listen to it from a Scene using: `this.matter.world.on('dragstart', listener)`. + * Tests if the start and end indexes are a safe range for the given array. * - * @event Phaser.Physics.Matter.Events#DRAG_START - * @since 3.16.2 - * - * @param {MatterJS.BodyType} body - The Body that has started being dragged. This is a Matter Body, not a Phaser Game Object. - * @param {MatterJS.BodyType} part - The part of the body that was clicked on. - * @param {Phaser.Physics.Matter.PointerConstraint} constraint - The Pointer Constraint that is dragging the body. + * @function Phaser.Utils.Array.SafeRange + * @since 3.4.0 + * + * @param {array} array - The array to check. + * @param {number} startIndex - The start index. + * @param {number} endIndex - The end index. + * @param {boolean} [throwError=true] - Throw an error if the range is out of bounds. + * + * @return {boolean} True if the range is safe, otherwise false. */ -module.exports = 'dragstart'; +var SafeRange = function (array, startIndex, endIndex, throwError) +{ + var len = array.length; + + if (startIndex < 0 || + startIndex > len || + startIndex >= endIndex || + endIndex > len) + { + if (throwError) + { + throw new Error('Range Error: Values outside acceptable range'); + } + + return false; + } + else + { + return true; + } +}; + +module.exports = SafeRange; /***/ }), -/* 1516 */ -/***/ (function(module, exports) { + +/***/ 27847: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * The Matter Physics World Pause Event. - * - * This event is dispatched by an Matter Physics World instance when it is paused. - * - * Listen to it from a Scene using: `this.matter.world.on('pause', listener)`. + * Moves the given element to the bottom of the array. + * The array is modified in-place. * - * @event Phaser.Physics.Matter.Events#PAUSE - * @since 3.0.0 + * @function Phaser.Utils.Array.SendToBack + * @since 3.4.0 + * + * @param {array} array - The array. + * @param {*} item - The element to move. + * + * @return {*} The element that was moved. */ -module.exports = 'pause'; +var SendToBack = function (array, item) +{ + var currentIndex = array.indexOf(item); + + if (currentIndex !== -1 && currentIndex > 0) + { + array.splice(currentIndex, 1); + array.unshift(item); + } + + return item; +}; + +module.exports = SendToBack; /***/ }), -/* 1517 */ -/***/ (function(module, exports) { + +/***/ 6034: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var SafeRange = __webpack_require__(45838); + /** - * The Matter Physics World Resume Event. - * - * This event is dispatched by an Matter Physics World instance when it resumes from a paused state. - * - * Listen to it from a Scene using: `this.matter.world.on('resume', listener)`. + * Scans the array for elements with the given property. If found, the property is set to the `value`. * - * @event Phaser.Physics.Matter.Events#RESUME - * @since 3.0.0 + * For example: `SetAll('visible', true)` would set all elements that have a `visible` property to `false`. + * + * Optionally you can specify a start and end index. For example if the array had 100 elements, + * and you set `startIndex` to 0 and `endIndex` to 50, it would update only the first 50 elements. + * + * @function Phaser.Utils.Array.SetAll + * @since 3.4.0 + * + * @param {array} array - The array to search. + * @param {string} property - The property to test for on each array element. + * @param {*} value - The value to set the property to. + * @param {number} [startIndex] - An optional start index to search from. + * @param {number} [endIndex] - An optional end index to search to. + * + * @return {array} The input array. */ -module.exports = 'resume'; +var SetAll = function (array, property, value, startIndex, endIndex) +{ + if (startIndex === undefined) { startIndex = 0; } + if (endIndex === undefined) { endIndex = array.length; } + + if (SafeRange(array, startIndex, endIndex)) + { + for (var i = startIndex; i < endIndex; i++) + { + var entry = array[i]; + + if (entry.hasOwnProperty(property)) + { + entry[property] = value; + } + } + } + + return array; +}; + +module.exports = SetAll; /***/ }), -/* 1518 */ -/***/ (function(module, exports) { + +/***/ 18592: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @typedef {object} Phaser.Physics.Matter.Events.SleepEndEvent + * Shuffles the contents of the given array using the Fisher-Yates implementation. * - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ - -/** - * The Matter Physics Sleep End Event. - * - * This event is dispatched by a Matter Physics World instance when a Body stop sleeping. - * - * Listen to it from a Scene using: `this.matter.world.on('sleepend', listener)`. + * The original array is modified directly and returned. * - * @event Phaser.Physics.Matter.Events#SLEEP_END + * @function Phaser.Utils.Array.Shuffle * @since 3.0.0 - * - * @param {Phaser.Physics.Matter.Events.SleepEndEvent} event - The Sleep Event object. - * @param {MatterJS.BodyType} body - The body that has stopped sleeping. + * + * @generic T + * @genericUse {T[]} - [array,$return] + * + * @param {T[]} array - The array to shuffle. This array is modified in place. + * + * @return {T[]} The shuffled array. */ -module.exports = 'sleepend'; +var Shuffle = function (array) +{ + for (var i = array.length - 1; i > 0; i--) + { + var j = Math.floor(Math.random() * (i + 1)); + var temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + + return array; +}; + +module.exports = Shuffle; /***/ }), -/* 1519 */ -/***/ (function(module, exports) { + +/***/ 28834: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * @typedef {object} Phaser.Physics.Matter.Events.SleepStartEvent + * Takes the given array and runs a numeric sort on it, ignoring any non-digits that + * may be in the entries. * - * @property {any} source - The source object of the event. - * @property {string} name - The name of the event. - */ - -/** - * The Matter Physics Sleep Start Event. - * - * This event is dispatched by a Matter Physics World instance when a Body goes to sleep. - * - * Listen to it from a Scene using: `this.matter.world.on('sleepstart', listener)`. + * You should only run this on arrays containing strings. * - * @event Phaser.Physics.Matter.Events#SLEEP_START - * @since 3.0.0 - * - * @param {Phaser.Physics.Matter.Events.SleepStartEvent} event - The Sleep Event object. - * @param {MatterJS.BodyType} body - The body that has gone to sleep. + * @function Phaser.Utils.Array.SortByDigits + * @since 3.50.0 + * + * @param {string[]} array - The input array of strings. + * + * @return {string[]} The sorted input array. */ -module.exports = 'sleepstart'; +var SortByDigits = function (array) +{ + var re = /\D/g; + + array.sort(function (a, b) + { + return (parseInt(a.replace(re, ''), 10) - parseInt(b.replace(re, ''), 10)); + }); + + return array; +}; + +module.exports = SortByDigits; /***/ }), -/* 1520 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 72677: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(41); - /** - * Provides methods used for getting and setting the static state of a physics body. + * Removes a single item from an array and returns it without creating gc, like the native splice does. + * Based on code by Mike Reinstein. * - * @namespace Phaser.Physics.Matter.Components.Static + * @function Phaser.Utils.Array.SpliceOne * @since 3.0.0 + * + * @param {array} array - The array to splice from. + * @param {number} index - The index of the item which should be spliced. + * + * @return {*} The item which was spliced (removed). */ -var Static = { - - /** - * Changes the physics body to be either static `true` or dynamic `false`. - * - * @method Phaser.Physics.Matter.Components.Static#setStatic - * @since 3.0.0 - * - * @param {boolean} value - `true` to set the body as being static, or `false` to make it dynamic. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setStatic: function (value) +var SpliceOne = function (array, index) +{ + if (index >= array.length) { - Body.setStatic(this.body, value); + return; + } - return this; - }, + var len = array.length - 1; - /** - * Returns `true` if the body is static, otherwise `false` for a dynamic body. - * - * @method Phaser.Physics.Matter.Components.Static#isStatic - * @since 3.0.0 - * - * @return {boolean} `true` if the body is static, otherwise `false`. - */ - isStatic: function () + var item = array[index]; + + for (var i = index; i < len; i++) { - return this.body.isStatic; + array[i] = array[i + 1]; } + array.length = len; + + return item; }; -module.exports = Static; +module.exports = SpliceOne; /***/ }), -/* 1521 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 17922: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @author Angry Bytes (and contributors) + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(41); -var MATH_CONST = __webpack_require__(14); -var WrapAngle = __webpack_require__(269); -var WrapAngleDegrees = __webpack_require__(270); +var Device = __webpack_require__(77290); -// global bitmask flag for GameObject.renderMask (used by Scale) -var _FLAG = 4; // 0100 - -// Transform Component +/** + * The comparator function. + * + * @ignore + * + * @param {*} a - The first item to test. + * @param {*} b - The second itemt to test. + * + * @return {boolean} True if they localCompare, otherwise false. + */ +function Compare (a, b) +{ + return String(a).localeCompare(b); +} /** - * Provides methods used for getting and setting the position, scale and rotation of a Game Object. + * Process the array contents. * - * @namespace Phaser.Physics.Matter.Components.Transform - * @since 3.0.0 + * @ignore + * + * @param {array} array - The array to process. + * @param {function} compare - The comparison function. + * + * @return {array} - The processed array. */ -var Transform = { +function Process (array, compare) +{ + // Short-circuit when there's nothing to sort. + var len = array.length; - /** - * The x position of this Game Object. - * - * @name Phaser.Physics.Matter.Components.Transform#x - * @type {number} - * @since 3.0.0 - */ - x: { + if (len <= 1) + { + return array; + } - get: function () - { - return this.body.position.x; - }, + // Rather than dividing input, simply iterate chunks of 1, 2, 4, 8, etc. + // Chunks are the size of the left or right hand in merge sort. + // Stop when the left-hand covers all of the array. + var buffer = new Array(len); - set: function (value) - { - this._tempVec2.set(value, this.y); + for (var chk = 1; chk < len; chk *= 2) + { + RunPass(array, compare, chk, buffer); - Body.setPosition(this.body, this._tempVec2); - } + var tmp = array; - }, + array = buffer; - /** - * The y position of this Game Object. - * - * @name Phaser.Physics.Matter.Components.Transform#y - * @type {number} - * @since 3.0.0 - */ - y: { + buffer = tmp; + } - get: function () - { - return this.body.position.y; - }, + return array; +} - set: function (value) - { - this._tempVec2.set(this.x, value); +/** + * Run a single pass with the given chunk size. + * + * @ignore + * + * @param {array} arr - The array to run the pass on. + * @param {function} comp - The comparison function. + * @param {number} chk - The number of iterations. + * @param {array} result - The array to store the result in. + */ +function RunPass (arr, comp, chk, result) +{ + var len = arr.length; + var i = 0; - Body.setPosition(this.body, this._tempVec2); - } + // Step size / double chunk size. + var dbl = chk * 2; - }, + // Bounds of the left and right chunks. + var l, r, e; - /** - * The horizontal scale of this Game Object. - * - * @name Phaser.Physics.Matter.Components.Transform#scaleX - * @type {number} - * @since 3.0.0 - */ - scaleX: { + // Iterators over the left and right chunk. + var li, ri; - get: function () + // Iterate over pairs of chunks. + for (l = 0; l < len; l += dbl) + { + r = l + chk; + e = r + chk; + + if (r > len) { - return this._scaleX; - }, + r = len; + } - set: function (value) + if (e > len) { - var factorX = 1 / this._scaleX; - var factorY = 1 / this._scaleY; - - this._scaleX = value; + e = len; + } - if (this._scaleX === 0) + // Iterate both chunks in parallel. + li = l; + ri = r; + + while (true) + { + // Compare the chunks. + if (li < r && ri < e) { - this.renderFlags &= ~_FLAG; + // This works for a regular `sort()` compatible comparator, + // but also for a simple comparator like: `a > b` + if (comp(arr[li], arr[ri]) <= 0) + { + result[i++] = arr[li++]; + } + else + { + result[i++] = arr[ri++]; + } + } + else if (li < r) + { + // Nothing to compare, just flush what's left. + result[i++] = arr[li++]; + } + else if (ri < e) + { + result[i++] = arr[ri++]; } else { - this.renderFlags |= _FLAG; + // Both iterators are at the chunk ends. + break; } + } + } +} - // Reset Matter scale back to 1 (sigh) - Body.scale(this.body, factorX, factorY); +/** + * An in-place stable array sort, because `Array#sort()` is not guaranteed stable. + * + * This is an implementation of merge sort, without recursion. + * + * Function based on the Two-Screen/stable sort 0.1.8 from https://github.com/Two-Screen/stable + * + * @function Phaser.Utils.Array.StableSort + * @since 3.0.0 + * + * @param {array} array - The input array to be sorted. + * @param {function} [compare] - The comparison function. + * + * @return {array} The sorted result. + */ +var StableSort = function (array, compare) +{ + if (compare === undefined) { compare = Compare; } - Body.scale(this.body, value, this._scaleY); - } + // Short-circuit when there's nothing to sort. + if (!array || array.length < 2) + { + return array; + } - }, + if (Device.features.stableSort) + { + return array.sort(compare); + } - /** - * The vertical scale of this Game Object. - * - * @name Phaser.Physics.Matter.Components.Transform#scaleY - * @type {number} - * @since 3.0.0 - */ - scaleY: { + var result = Process(array, compare); - get: function () - { - return this._scaleY; - }, + // This simply copies back if the result isn't in the original array, which happens on an odd number of passes. + if (result !== array) + { + RunPass(result, null, array.length, array); + } - set: function (value) - { - var factorX = 1 / this._scaleX; - var factorY = 1 / this._scaleY; + return array; +}; - this._scaleY = value; +module.exports = StableSort; - if (this._scaleY === 0) - { - this.renderFlags &= ~_FLAG; - } - else - { - this.renderFlags |= _FLAG; - } - Body.scale(this.body, factorX, factorY); +/***/ }), - Body.scale(this.body, this._scaleX, value); - } +/***/ 96928: +/***/ ((module) => { - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Use `angle` to set or get rotation of the physics body associated to this GameObject. - * Unlike rotation, when using set the value can be in degrees, which will be converted to radians internally. - * - * @name Phaser.Physics.Matter.Components.Transform#angle - * @type {number} - * @since 3.0.0 - */ - angle: { +/** + * Swaps the position of two elements in the given array. + * The elements must exist in the same array. + * The array is modified in-place. + * + * @function Phaser.Utils.Array.Swap + * @since 3.4.0 + * + * @param {array} array - The input array. + * @param {*} item1 - The first element to swap. + * @param {*} item2 - The second element to swap. + * + * @return {array} The input array. + */ +var Swap = function (array, item1, item2) +{ + if (item1 === item2) + { + return array; + } - get: function () - { - return WrapAngleDegrees(this.body.angle * MATH_CONST.RAD_TO_DEG); - }, + var index1 = array.indexOf(item1); + var index2 = array.indexOf(item2); - set: function (value) - { - // value is in degrees - this.rotation = WrapAngleDegrees(value) * MATH_CONST.DEG_TO_RAD; - } - }, + if (index1 < 0 || index2 < 0) + { + throw new Error('Supplied items must be elements of the same array'); + } - /** - * Use `rotation` to set or get the rotation of the physics body associated with this GameObject. - * The value when set must be in radians. - * - * @name Phaser.Physics.Matter.Components.Transform#rotation - * @type {number} - * @since 3.0.0 - */ - rotation: { + array[index1] = item2; + array[index2] = item1; - get: function () - { - return this.body.angle; - }, + return array; +}; - set: function (value) - { - // value is in radians - this._rotation = WrapAngle(value); +module.exports = Swap; - Body.setAngle(this.body, this._rotation); - } - }, - /** - * Sets the position of the physics body along x and y axes. - * Both the parameters to this function are optional and if not passed any they default to 0. - * Velocity, angle, force etc. are unchanged. - * - * @method Phaser.Physics.Matter.Components.Transform#setPosition - * @since 3.0.0 - * - * @param {number} [x=0] - The horizontal position of the body. - * @param {number} [y=x] - The vertical position of the body. - * - * @return {this} This Game Object. - */ - setPosition: function (x, y) - { - if (x === undefined) { x = 0; } - if (y === undefined) { y = x; } +/***/ }), - this._tempVec2.set(x, y); +/***/ 59959: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - Body.setPosition(this.body, this._tempVec2); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +/** + * @namespace Phaser.Utils.Array + */ - /** - * Immediately sets the angle of the Body. - * Angular velocity, position, force etc. are unchanged. - * - * @method Phaser.Physics.Matter.Components.Transform#setRotation - * @since 3.0.0 - * - * @param {number} [radians=0] - The angle of the body, in radians. - * - * @return {this} This Game Object. - */ - setRotation: function (radians) - { - if (radians === undefined) { radians = 0; } +module.exports = { - this._rotation = WrapAngle(radians); + Matrix: __webpack_require__(13515), - Body.setAngle(this.body, radians); + Add: __webpack_require__(78991), + AddAt: __webpack_require__(48522), + BringToTop: __webpack_require__(58742), + CountAllMatching: __webpack_require__(30164), + Each: __webpack_require__(36337), + EachInRange: __webpack_require__(46208), + FindClosestInSorted: __webpack_require__(2406), + Flatten: __webpack_require__(5454), + GetAll: __webpack_require__(71608), + GetFirst: __webpack_require__(51463), + GetRandom: __webpack_require__(72861), + MoveDown: __webpack_require__(51172), + MoveTo: __webpack_require__(68396), + MoveUp: __webpack_require__(27555), + MoveAbove: __webpack_require__(24218), + MoveBelow: __webpack_require__(58258), + NumberArray: __webpack_require__(13401), + NumberArrayStep: __webpack_require__(89955), + QuickSelect: __webpack_require__(53466), + Range: __webpack_require__(75757), + Remove: __webpack_require__(66458), + RemoveAt: __webpack_require__(8324), + RemoveBetween: __webpack_require__(47427), + RemoveRandomElement: __webpack_require__(50147), + Replace: __webpack_require__(80402), + RotateLeft: __webpack_require__(77640), + RotateRight: __webpack_require__(38487), + SafeRange: __webpack_require__(45838), + SendToBack: __webpack_require__(27847), + SetAll: __webpack_require__(6034), + Shuffle: __webpack_require__(18592), + SortByDigits: __webpack_require__(28834), + SpliceOne: __webpack_require__(72677), + StableSort: __webpack_require__(17922), + Swap: __webpack_require__(96928) - return this; - }, +}; - /** - * Setting fixed rotation sets the Body inertia to Infinity, which stops it - * from being able to rotate when forces are applied to it. - * - * @method Phaser.Physics.Matter.Components.Transform#setFixedRotation - * @since 3.0.0 - * - * @return {this} This Game Object. - */ - setFixedRotation: function () + +/***/ }), + +/***/ 97494: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Checks if an array can be used as a matrix. + * + * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) + * have the same length. This is an example matrix: + * + * ``` + * [ + * [ 1, 1, 1, 1, 1, 1 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 2, 0, 1, 2, 0, 4 ], + * [ 2, 0, 3, 4, 0, 4 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 3, 3, 3, 3, 3, 3 ] + * ] + * ``` + * + * @function Phaser.Utils.Array.Matrix.CheckMatrix + * @since 3.0.0 + * + * @generic T + * @genericUse {T[][]} - [matrix] + * + * @param {T[][]} [matrix] - The array to check. + * + * @return {boolean} `true` if the given `matrix` array is a valid matrix. + */ +var CheckMatrix = function (matrix) +{ + if (!Array.isArray(matrix) || !Array.isArray(matrix[0])) { - Body.setInertia(this.body, Infinity); + return false; + } - return this; - }, + // How long is the first row? + var size = matrix[0].length; - /** - * Immediately sets the angle of the Body. - * Angular velocity, position, force etc. are unchanged. - * - * @method Phaser.Physics.Matter.Components.Transform#setAngle - * @since 3.0.0 - * - * @param {number} [degrees=0] - The angle to set, in degrees. - * - * @return {this} This Game Object. - */ - setAngle: function (degrees) + // Validate the rest of the rows are the same length + for (var i = 1; i < matrix.length; i++) { - if (degrees === undefined) { degrees = 0; } + if (matrix[i].length !== size) + { + return false; + } + } - this.angle = degrees; + return true; +}; + +module.exports = CheckMatrix; + + +/***/ }), + +/***/ 68428: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Pad = __webpack_require__(76400); +var CheckMatrix = __webpack_require__(97494); + +/** + * Generates a string (which you can pass to console.log) from the given Array Matrix. + * + * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) + * have the same length. There must be at least two rows. This is an example matrix: + * + * ``` + * [ + * [ 1, 1, 1, 1, 1, 1 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 2, 0, 1, 2, 0, 4 ], + * [ 2, 0, 3, 4, 0, 4 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 3, 3, 3, 3, 3, 3 ] + * ] + * ``` + * + * @function Phaser.Utils.Array.Matrix.MatrixToString + * @since 3.0.0 + * + * @generic T + * @genericUse {T[][]} - [matrix] + * + * @param {T[][]} [matrix] - A 2-dimensional array. + * + * @return {string} A string representing the matrix. + */ +var MatrixToString = function (matrix) +{ + var str = ''; + + if (!CheckMatrix(matrix)) + { + return str; + } - Body.setAngle(this.body, this.rotation); + for (var r = 0; r < matrix.length; r++) + { + for (var c = 0; c < matrix[r].length; c++) + { + var cell = matrix[r][c].toString(); - return this; - }, + if (cell !== 'undefined') + { + str += Pad(cell, 2); + } + else + { + str += '?'; + } - /** - * Sets the scale of this Game Object. - * - * @method Phaser.Physics.Matter.Components.Transform#setScale - * @since 3.0.0 - * - * @param {number} [x=1] - The horizontal scale of this Game Object. - * @param {number} [y=x] - The vertical scale of this Game Object. If not set it will use the x value. - * @param {Phaser.Math.Vector2} [point] - The point (Vector2) from which scaling will occur. - * - * @return {this} This Game Object. - */ - setScale: function (x, y, point) - { - if (x === undefined) { x = 1; } - if (y === undefined) { y = x; } + if (c < matrix[r].length - 1) + { + str += ' |'; + } + } - var factorX = 1 / this._scaleX; - var factorY = 1 / this._scaleY; + if (r < matrix.length - 1) + { + str += '\n'; - this._scaleX = x; - this._scaleY = y; + for (var i = 0; i < matrix[r].length; i++) + { + str += '---'; - Body.scale(this.body, factorX, factorY, point); + if (i < matrix[r].length - 1) + { + str += '+'; + } + } - Body.scale(this.body, x, y, point); + str += '\n'; + } - return this; } + return str; }; -module.exports = Transform; +module.exports = MatrixToString; /***/ }), -/* 1522 */ -/***/ (function(module, exports, __webpack_require__) { + +/***/ 59521: +/***/ ((module) => { /** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var Body = __webpack_require__(41); - /** - * Contains methods for changing the velocity of a Matter Body. Should be used as a mixin and not called directly. + * Reverses the columns in the given Array Matrix. * - * @namespace Phaser.Physics.Matter.Components.Velocity + * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) + * have the same length. There must be at least two rows. This is an example matrix: + * + * ``` + * [ + * [ 1, 1, 1, 1, 1, 1 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 2, 0, 1, 2, 0, 4 ], + * [ 2, 0, 3, 4, 0, 4 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 3, 3, 3, 3, 3, 3 ] + * ] + * ``` + * + * @function Phaser.Utils.Array.Matrix.ReverseColumns * @since 3.0.0 + * + * @generic T + * @genericUse {T[][]} - [matrix,$return] + * + * @param {T[][]} [matrix] - The array matrix to reverse the columns for. + * + * @return {T[][]} The column reversed matrix. */ -var Velocity = { - - /** - * Sets the angular velocity of the body instantly. - * Position, angle, force etc. are unchanged. - * - * @method Phaser.Physics.Matter.Components.Velocity#setAngularVelocity - * @since 3.0.0 - * - * @param {number} value - The angular velocity. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setAngularVelocity: function (value) - { - Body.setAngularVelocity(this.body, value); - - return this; - }, - - /** - * Sets the horizontal velocity of the physics body. - * - * @method Phaser.Physics.Matter.Components.Velocity#setVelocityX - * @since 3.0.0 - * - * @param {number} x - The horizontal velocity value. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setVelocityX: function (x) - { - this._tempVec2.set(x, this.body.velocity.y); +var ReverseColumns = function (matrix) +{ + return matrix.reverse(); +}; - Body.setVelocity(this.body, this._tempVec2); +module.exports = ReverseColumns; - return this; - }, - /** - * Sets vertical velocity of the physics body. - * - * @method Phaser.Physics.Matter.Components.Velocity#setVelocityY - * @since 3.0.0 - * - * @param {number} y - The vertical velocity value. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setVelocityY: function (y) - { - this._tempVec2.set(this.body.velocity.x, y); +/***/ }), - Body.setVelocity(this.body, this._tempVec2); +/***/ 51995: +/***/ ((module) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Sets both the horizontal and vertical velocity of the physics body. - * - * @method Phaser.Physics.Matter.Components.Velocity#setVelocity - * @since 3.0.0 - * - * @param {number} x - The horizontal velocity value. - * @param {number} [y=x] - The vertical velocity value, it can be either positive or negative. If not given, it will be the same as the `x` value. - * - * @return {Phaser.GameObjects.GameObject} This Game Object. - */ - setVelocity: function (x, y) +/** + * Reverses the rows in the given Array Matrix. + * + * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) + * have the same length. There must be at least two rows. This is an example matrix: + * + * ``` + * [ + * [ 1, 1, 1, 1, 1, 1 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 2, 0, 1, 2, 0, 4 ], + * [ 2, 0, 3, 4, 0, 4 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 3, 3, 3, 3, 3, 3 ] + * ] + * ``` + * + * @function Phaser.Utils.Array.Matrix.ReverseRows + * @since 3.0.0 + * + * @generic T + * @genericUse {T[][]} - [matrix,$return] + * + * @param {T[][]} [matrix] - The array matrix to reverse the rows for. + * + * @return {T[][]} The column reversed matrix. + */ +var ReverseRows = function (matrix) +{ + for (var i = 0; i < matrix.length; i++) { - this._tempVec2.set(x, y); - - Body.setVelocity(this.body, this._tempVec2); - - return this; + matrix[i].reverse(); } + return matrix; }; -module.exports = Velocity; +module.exports = ReverseRows; /***/ }), -/* 1523 */ -/***/ (function(module, exports, __webpack_require__) { -// @if DEBUG -/** -* _Internal Class_, not generally used outside of the engine's internals. -* -*/ +/***/ 89011: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var Metrics = {}; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = Metrics; +var RotateMatrix = __webpack_require__(63515); -var Composite = __webpack_require__(118); -var Common = __webpack_require__(32); +/** + * Rotates the array matrix 180 degrees. + * + * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) + * have the same length. There must be at least two rows. This is an example matrix: + * + * ``` + * [ + * [ 1, 1, 1, 1, 1, 1 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 2, 0, 1, 2, 0, 4 ], + * [ 2, 0, 3, 4, 0, 4 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 3, 3, 3, 3, 3, 3 ] + * ] + * ``` + * + * @function Phaser.Utils.Array.Matrix.Rotate180 + * @since 3.0.0 + * + * @generic T + * @genericUse {T[][]} - [matrix,$return] + * + * @param {T[][]} [matrix] - The array to rotate. + * + * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix. + */ +var Rotate180 = function (matrix) +{ + return RotateMatrix(matrix, 180); +}; -(function() { +module.exports = Rotate180; - /** - * Creates a new metrics. - * @method create - * @private - * @return {metrics} A new metrics - */ - Metrics.create = function(options) { - var defaults = { - extended: false, - narrowDetections: 0, - narrowphaseTests: 0, - narrowReuse: 0, - narrowReuseCount: 0, - midphaseTests: 0, - broadphaseTests: 0, - narrowEff: 0.0001, - midEff: 0.0001, - broadEff: 0.0001, - collisions: 0, - buckets: 0, - bodies: 0, - pairs: 0 - }; - return Common.extend(defaults, false, options); - }; +/***/ }), - /** - * Resets metrics. - * @method reset - * @private - * @param {metrics} metrics - */ - Metrics.reset = function(metrics) { - if (metrics.extended) { - metrics.narrowDetections = 0; - metrics.narrowphaseTests = 0; - metrics.narrowReuse = 0; - metrics.narrowReuseCount = 0; - metrics.midphaseTests = 0; - metrics.broadphaseTests = 0; - metrics.narrowEff = 0; - metrics.midEff = 0; - metrics.broadEff = 0; - metrics.collisions = 0; - metrics.buckets = 0; - metrics.pairs = 0; - metrics.bodies = 0; - } - }; +/***/ 42549: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Updates metrics. - * @method update - * @private - * @param {metrics} metrics - * @param {engine} engine - */ - Metrics.update = function(metrics, engine) { - if (metrics.extended) { - var world = engine.world, - bodies = Composite.allBodies(world); - - metrics.collisions = metrics.narrowDetections; - metrics.pairs = engine.pairs.list.length; - metrics.bodies = bodies.length; - metrics.midEff = (metrics.narrowDetections / (metrics.midphaseTests || 1)).toFixed(2); - metrics.narrowEff = (metrics.narrowDetections / (metrics.narrowphaseTests || 1)).toFixed(2); - metrics.broadEff = (1 - (metrics.broadphaseTests / (bodies.length || 1))).toFixed(2); - metrics.narrowReuse = (metrics.narrowReuseCount / (metrics.narrowphaseTests || 1)).toFixed(2); - //var broadphase = engine.broadphase[engine.broadphase.current]; - //if (broadphase.instance) - // metrics.buckets = Common.keys(broadphase.instance.buckets).length; - } - }; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -})(); -// @endif - - -/***/ }), -/* 1524 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. - * @license {@link https://opensource.org/licenses/MIT|MIT License} - */ - -var ALIGN_CONST = __webpack_require__(123); -var Axes = __webpack_require__(271); -var Bodies = __webpack_require__(86); -var Body = __webpack_require__(41); -var BodyBounds = __webpack_require__(1392); -var Bounds = __webpack_require__(84); -var Class = __webpack_require__(0); -var Composite = __webpack_require__(118); -var Composites = __webpack_require__(591); -var Constraint = __webpack_require__(128); -var Detector = __webpack_require__(273); -var DistanceBetween = __webpack_require__(50); -var Factory = __webpack_require__(1394); -var GetFastValue = __webpack_require__(2); -var GetValue = __webpack_require__(6); -var Grid = __webpack_require__(597); -var MatterAttractors = __webpack_require__(1525); -var MatterCollisionEvents = __webpack_require__(1526); -var MatterLib = __webpack_require__(1399); -var MatterWrap = __webpack_require__(1527); -var Merge = __webpack_require__(127); -var Pair = __webpack_require__(250); -var Pairs = __webpack_require__(598); -var Plugin = __webpack_require__(595); -var PluginCache = __webpack_require__(24); -var Query = __webpack_require__(1400); -var Resolver = __webpack_require__(599); -var SAT = __webpack_require__(274); -var SceneEvents = __webpack_require__(20); -var Svg = __webpack_require__(592); -var Vector = __webpack_require__(83); -var Vertices = __webpack_require__(64); -var World = __webpack_require__(1402); +var RotateMatrix = __webpack_require__(63515); /** - * @classdesc - * The Phaser Matter plugin provides the ability to use the Matter JS Physics Engine within your Phaser games. - * - * Unlike Arcade Physics, the other physics system provided with Phaser, Matter JS is a full-body physics system. - * It features: - * - * * Rigid bodies - * * Compound bodies - * * Composite bodies - * * Concave and convex hulls - * * Physical properties (mass, area, density etc.) - * * Restitution (elastic and inelastic collisions) - * * Collisions (broad-phase, mid-phase and narrow-phase) - * * Stable stacking and resting - * * Conservation of momentum - * * Friction and resistance - * * Constraints - * * Gravity - * * Sleeping and static bodies - * * Rounded corners (chamfering) - * * Views (translate, zoom) - * * Collision queries (raycasting, region tests) - * * Time scaling (slow-mo, speed-up) - * - * Configuration of Matter is handled via the Matter World Config object, which can be passed in either the - * Phaser Game Config, or Phaser Scene Config. Here is a basic example: - * - * ```js - * physics: { - * default: 'matter', - * matter: { - * enableSleeping: true, - * gravity: { - * y: 0 - * }, - * debug: { - * showBody: true, - * showStaticBody: true - * } - * } - * } + * Rotates the array matrix to the left (or 90 degrees) + * + * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) + * have the same length. There must be at least two rows. This is an example matrix: + * + * ``` + * [ + * [ 1, 1, 1, 1, 1, 1 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 2, 0, 1, 2, 0, 4 ], + * [ 2, 0, 3, 4, 0, 4 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 3, 3, 3, 3, 3, 3 ] + * ] * ``` - * - * This class acts as an interface between a Phaser Scene and a single instance of the Matter Engine. - * - * Use it to access the most common Matter features and helper functions. - * - * You can find details, documentation and examples on the Matter JS website: https://brm.io/matter-js/ * - * @class MatterPhysics - * @memberof Phaser.Physics.Matter - * @constructor + * @function Phaser.Utils.Array.Matrix.RotateLeft * @since 3.0.0 * - * @param {Phaser.Scene} scene - The Phaser Scene that owns this Matter Physics instance. + * @generic T + * @genericUse {T[][]} - [matrix,$return] + * + * @param {T[][]} [matrix] - The array to rotate. + * + * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix. */ -var MatterPhysics = new Class({ - - initialize: - - function MatterPhysics (scene) - { - /** - * The Phaser Scene that owns this Matter Physics instance - * - * @name Phaser.Physics.Matter.MatterPhysics#scene - * @type {Phaser.Scene} - * @since 3.0.0 - */ - this.scene = scene; - - /** - * A reference to the Scene Systems that belong to the Scene owning this Matter Physics instance. - * - * @name Phaser.Physics.Matter.MatterPhysics#systems - * @type {Phaser.Scenes.Systems} - * @since 3.0.0 - */ - this.systems = scene.sys; - - /** - * The parsed Matter Configuration object. - * - * @name Phaser.Physics.Matter.MatterPhysics#config - * @type {Phaser.Types.Physics.Matter.MatterWorldConfig} - * @since 3.0.0 - */ - this.config = this.getConfig(); - - /** - * An instance of the Matter World class. This class is responsible for the updating of the - * Matter Physics world, as well as handling debug drawing functions. - * - * @name Phaser.Physics.Matter.MatterPhysics#world - * @type {Phaser.Physics.Matter.World} - * @since 3.0.0 - */ - this.world; - - /** - * An instance of the Matter Factory. This class provides lots of functions for creating a - * wide variety of physics objects and adds them automatically to the Matter World. - * - * You can use this class to cut-down on the amount of code required in your game, however, - * use of the Factory is entirely optional and should be seen as a development aid. It's - * perfectly possible to create and add components to the Matter world without using it. - * - * @name Phaser.Physics.Matter.MatterPhysics#add - * @type {Phaser.Physics.Matter.Factory} - * @since 3.0.0 - */ - this.add; +var RotateLeft = function (matrix) +{ + return RotateMatrix(matrix, 90); +}; - /** - * An instance of the Body Bounds class. This class contains functions used for getting the - * world position from various points around the bounds of a physics body. - * - * @name Phaser.Physics.Matter.MatterPhysics#bodyBounds - * @type {Phaser.Physics.Matter.BodyBounds} - * @since 3.22.0 - */ - this.bodyBounds; +module.exports = RotateLeft; - // Body - /** - * A reference to the `Matter.Body` module. - * - * The `Matter.Body` module contains methods for creating and manipulating body models. - * A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`. - * Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the `Bodies` module. - * - * @name Phaser.Physics.Matter.MatterPhysics#body - * @type {MatterJS.BodyFactory} - * @since 3.18.0 - */ - this.body = Body; +/***/ }), - /** - * A reference to the `Matter.Composite` module. - * - * The `Matter.Composite` module contains methods for creating and manipulating composite bodies. - * A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure. - * It is important to use the functions in this module to modify composites, rather than directly modifying their properties. - * Note that the `Matter.World` object is also a type of `Matter.Composite` and as such all composite methods here can also operate on a `Matter.World`. - * - * @name Phaser.Physics.Matter.MatterPhysics#composite - * @type {MatterJS.CompositeFactory} - * @since 3.22.0 - */ - this.composite = Composite; +/***/ 63515: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - // Collision: +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * A reference to the `Matter.Detector` module. - * - * The `Matter.Detector` module contains methods for detecting collisions given a set of pairs. - * - * @name Phaser.Physics.Matter.MatterPhysics#detector - * @type {MatterJS.DetectorFactory} - * @since 3.22.0 - */ - this.detector = Detector; +var CheckMatrix = __webpack_require__(97494); +var TransposeMatrix = __webpack_require__(78581); - /** - * A reference to the `Matter.Grid` module. - * - * The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures. - * - * @name Phaser.Physics.Matter.MatterPhysics#grid - * @type {MatterJS.GridFactory} - * @since 3.22.0 - */ - this.grid = Grid; +/** + * Rotates the array matrix based on the given rotation value. + * + * The value can be given in degrees: 90, -90, 270, -270 or 180, + * or a string command: `rotateLeft`, `rotateRight` or `rotate180`. + * + * Based on the routine from {@link http://jsfiddle.net/MrPolywhirl/NH42z/}. + * + * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) + * have the same length. There must be at least two rows. This is an example matrix: + * + * ``` + * [ + * [ 1, 1, 1, 1, 1, 1 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 2, 0, 1, 2, 0, 4 ], + * [ 2, 0, 3, 4, 0, 4 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 3, 3, 3, 3, 3, 3 ] + * ] + * ``` + * + * @function Phaser.Utils.Array.Matrix.RotateMatrix + * @since 3.0.0 + * + * @generic T + * @genericUse {T[][]} - [matrix,$return] + * + * @param {T[][]} [matrix] - The array to rotate. + * @param {(number|string)} [direction=90] - The amount to rotate the matrix by. + * + * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix. + */ +var RotateMatrix = function (matrix, direction) +{ + if (direction === undefined) { direction = 90; } - /** - * A reference to the `Matter.Pair` module. - * - * The `Matter.Pair` module contains methods for creating and manipulating collision pairs. - * - * @name Phaser.Physics.Matter.MatterPhysics#pair - * @type {MatterJS.PairFactory} - * @since 3.22.0 - */ - this.pair = Pair; + if (!CheckMatrix(matrix)) + { + return null; + } - /** - * A reference to the `Matter.Pairs` module. - * - * The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets. - * - * @name Phaser.Physics.Matter.MatterPhysics#pairs - * @type {MatterJS.PairsFactory} - * @since 3.22.0 - */ - this.pairs = Pairs; + if (typeof direction !== 'string') + { + direction = ((direction % 360) + 360) % 360; + } - /** - * A reference to the `Matter.Query` module. - * - * The `Matter.Query` module contains methods for performing collision queries. - * - * @name Phaser.Physics.Matter.MatterPhysics#query - * @type {MatterJS.QueryFactory} - * @since 3.22.0 - */ - this.query = Query; + if (direction === 90 || direction === -270 || direction === 'rotateLeft') + { + matrix = TransposeMatrix(matrix); + matrix.reverse(); + } + else if (direction === -90 || direction === 270 || direction === 'rotateRight') + { + matrix.reverse(); + matrix = TransposeMatrix(matrix); + } + else if (Math.abs(direction) === 180 || direction === 'rotate180') + { + for (var i = 0; i < matrix.length; i++) + { + matrix[i].reverse(); + } - /** - * A reference to the `Matter.Resolver` module. - * - * The `Matter.Resolver` module contains methods for resolving collision pairs. - * - * @name Phaser.Physics.Matter.MatterPhysics#resolver - * @type {MatterJS.ResolverFactory} - * @since 3.22.0 - */ - this.resolver = Resolver; + matrix.reverse(); + } - /** - * A reference to the `Matter.SAT` module. - * - * The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem. - * - * @name Phaser.Physics.Matter.MatterPhysics#sat - * @type {MatterJS.SATFactory} - * @since 3.22.0 - */ - this.sat = SAT; + return matrix; +}; - // Constraint +module.exports = RotateMatrix; - /** - * A reference to the `Matter.Constraint` module. - * - * The `Matter.Constraint` module contains methods for creating and manipulating constraints. - * Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position). - * The stiffness of constraints can be modified to create springs or elastic. - * - * @name Phaser.Physics.Matter.MatterPhysics#constraint - * @type {MatterJS.ConstraintFactory} - * @since 3.22.0 - */ - this.constraint = Constraint; - // Factory +/***/ }), - /** - * A reference to the `Matter.Bodies` module. - * - * The `Matter.Bodies` module contains factory methods for creating rigid bodies - * with commonly used body configurations (such as rectangles, circles and other polygons). - * - * @name Phaser.Physics.Matter.MatterPhysics#bodies - * @type {MatterJS.BodiesFactory} - * @since 3.18.0 - */ - this.bodies = Bodies; +/***/ 14305: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A reference to the `Matter.Composites` module. - * - * The `Matter.Composites` module contains factory methods for creating composite bodies - * with commonly used configurations (such as stacks and chains). - * - * @name Phaser.Physics.Matter.MatterPhysics#composites - * @type {MatterJS.CompositesFactory} - * @since 3.22.0 - */ - this.composites = Composites; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - // Geometry +var RotateMatrix = __webpack_require__(63515); - /** - * A reference to the `Matter.Axes` module. - * - * The `Matter.Axes` module contains methods for creating and manipulating sets of axes. - * - * @name Phaser.Physics.Matter.MatterPhysics#axes - * @type {MatterJS.AxesFactory} - * @since 3.22.0 - */ - this.axes = Axes; +/** + * Rotates the array matrix to the left (or -90 degrees) + * + * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) + * have the same length. There must be at least two rows. This is an example matrix: + * + * ``` + * [ + * [ 1, 1, 1, 1, 1, 1 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 2, 0, 1, 2, 0, 4 ], + * [ 2, 0, 3, 4, 0, 4 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 3, 3, 3, 3, 3, 3 ] + * ] + * ``` + * + * @function Phaser.Utils.Array.Matrix.RotateRight + * @since 3.0.0 + * + * @generic T + * @genericUse {T[][]} - [matrix,$return] + * + * @param {T[][]} [matrix] - The array to rotate. + * + * @return {T[][]} The rotated matrix array. The source matrix should be discard for the returned matrix. + */ +var RotateRight = function (matrix) +{ + return RotateMatrix(matrix, -90); +}; - /** - * A reference to the `Matter.Bounds` module. - * - * The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB). - * - * @name Phaser.Physics.Matter.MatterPhysics#bounds - * @type {MatterJS.BoundsFactory} - * @since 3.22.0 - */ - this.bounds = Bounds; +module.exports = RotateRight; - /** - * A reference to the `Matter.Svg` module. - * - * The `Matter.Svg` module contains methods for converting SVG images into an array of vector points. - * - * To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg - * - * @name Phaser.Physics.Matter.MatterPhysics#svg - * @type {MatterJS.SvgFactory} - * @since 3.22.0 - */ - this.svg = Svg; - /** - * A reference to the `Matter.Vector` module. - * - * The `Matter.Vector` module contains methods for creating and manipulating vectors. - * Vectors are the basis of all the geometry related operations in the engine. - * A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`. - * - * @name Phaser.Physics.Matter.MatterPhysics#vector - * @type {MatterJS.VectorFactory} - * @since 3.22.0 - */ - this.vector = Vector; +/***/ }), - /** - * A reference to the `Matter.Vertices` module. - * - * The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices. - * A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`. - * A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull). - * - * @name Phaser.Physics.Matter.MatterPhysics#vertices - * @type {MatterJS.VerticesFactory} - * @since 3.22.0 - */ - this.vertices = Vertices; +/***/ 27365: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * A reference to the `Matter.Vertices` module. - * - * The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices. - * A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`. - * A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull). - * - * @name Phaser.Physics.Matter.MatterPhysics#verts - * @type {MatterJS.VerticesFactory} - * @since 3.14.0 - */ - this.verts = Vertices; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * An internal temp vector used for velocity and force calculations. - * - * @name Phaser.Physics.Matter.MatterPhysics#_tempVec2 - * @type {MatterJS.Vector} - * @private - * @since 3.22.0 - */ - this._tempVec2 = Vector.create(); +var RotateLeft = __webpack_require__(77640); +var RotateRight = __webpack_require__(38487); - // Matter plugins +/** + * Translates the given Array Matrix by shifting each column and row the + * amount specified. + * + * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) + * have the same length. There must be at least two rows. This is an example matrix: + * + * ``` + * [ + * [ 1, 1, 1, 1, 1, 1 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 2, 0, 1, 2, 0, 4 ], + * [ 2, 0, 3, 4, 0, 4 ], + * [ 2, 0, 0, 0, 0, 4 ], + * [ 3, 3, 3, 3, 3, 3 ] + * ] + * ``` + * + * @function Phaser.Utils.Array.Matrix.Translate + * @since 3.50.0 + * + * @generic T + * @genericUse {T[][]} - [matrix,$return] + * + * @param {T[][]} [matrix] - The array matrix to translate. + * @param {number} [x=0] - The amount to horizontally translate the matrix by. + * @param {number} [y=0] - The amount to vertically translate the matrix by. + * + * @return {T[][]} The translated matrix. + */ +var TranslateMatrix = function (matrix, x, y) +{ + if (x === undefined) { x = 0; } + if (y === undefined) { y = 0; } - if (GetValue(this.config, 'plugins.collisionevents', true)) - { - this.enableCollisionEventsPlugin(); - } + // Vertical translation - if (GetValue(this.config, 'plugins.attractors', false)) + if (y !== 0) + { + if (y < 0) { - this.enableAttractorPlugin(); + // Shift Up + RotateLeft(matrix, Math.abs(y)); } - - if (GetValue(this.config, 'plugins.wrap', false)) + else { - this.enableWrapPlugin(); + // Shift Down + RotateRight(matrix, y); } + } - Resolver._restingThresh = GetValue(this.config, 'restingThresh', 4); - Resolver._restingThreshTangent = GetValue(this.config, 'restingThreshTangent', 6); - Resolver._positionDampen = GetValue(this.config, 'positionDampen', 0.9); - Resolver._positionWarming = GetValue(this.config, 'positionWarming', 0.8); - Resolver._frictionNormalMultiplier = GetValue(this.config, 'frictionNormalMultiplier', 5); - - scene.sys.events.once(SceneEvents.BOOT, this.boot, this); - scene.sys.events.on(SceneEvents.START, this.start, this); - }, - - /** - * This method is called automatically, only once, when the Scene is first created. - * Do not invoke it directly. - * - * @method Phaser.Physics.Matter.MatterPhysics#boot - * @private - * @since 3.5.1 - */ - boot: function () - { - this.world = new World(this.scene, this.config); - this.add = new Factory(this.world); - this.bodyBounds = new BodyBounds(); - - this.systems.events.once(SceneEvents.DESTROY, this.destroy, this); - }, + // Horizontal translation - /** - * This method is called automatically by the Scene when it is starting up. - * It is responsible for creating local systems, properties and listening for Scene events. - * Do not invoke it directly. - * - * @method Phaser.Physics.Matter.MatterPhysics#start - * @private - * @since 3.5.0 - */ - start: function () + if (x !== 0) { - if (!this.world) + for (var i = 0; i < matrix.length; i++) { - this.world = new World(this.scene, this.config); - this.add = new Factory(this.world); + var row = matrix[i]; + + if (x < 0) + { + RotateLeft(row, Math.abs(x)); + } + else + { + RotateRight(row, x); + } } + } - var eventEmitter = this.systems.events; + return matrix; +}; - eventEmitter.on(SceneEvents.UPDATE, this.world.update, this.world); - eventEmitter.on(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world); - eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this); - }, +module.exports = TranslateMatrix; - /** - * This internal method is called when this class starts and retrieves the final Matter World Config. - * - * @method Phaser.Physics.Matter.MatterPhysics#getConfig - * @since 3.0.0 - * - * @return {Phaser.Types.Physics.Matter.MatterWorldConfig} The Matter World Config. - */ - getConfig: function () - { - var gameConfig = this.systems.game.config.physics; - var sceneConfig = this.systems.settings.physics; - var config = Merge( - GetFastValue(sceneConfig, 'matter', {}), - GetFastValue(gameConfig, 'matter', {}) - ); +/***/ }), - return config; - }, +/***/ 78581: +/***/ ((module) => { - /** - * Enables the Matter Attractors Plugin. - * - * The attractors plugin that makes it easy to apply continual forces on bodies. - * It's possible to simulate effects such as wind, gravity and magnetism. - * - * https://github.com/liabru/matter-attractors - * - * This method is called automatically if `plugins.attractors` is set in the Matter World Config. - * However, you can also call it directly from within your game. - * - * @method Phaser.Physics.Matter.MatterPhysics#enableAttractorPlugin - * @since 3.0.0 - * - * @return {this} This Matter Physics instance. - */ - enableAttractorPlugin: function () - { - Plugin.register(MatterAttractors); - Plugin.use(MatterLib, MatterAttractors); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +/** + * 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; - /** - * Enables the Matter Wrap Plugin. - * - * The coordinate wrapping plugin that automatically wraps the position of bodies such that they always stay - * within the given bounds. Upon crossing a boundary the body will appear on the opposite side of the bounds, - * while maintaining its velocity. - * - * https://github.com/liabru/matter-wrap - * - * This method is called automatically if `plugins.wrap` is set in the Matter World Config. - * However, you can also call it directly from within your game. - * - * @method Phaser.Physics.Matter.MatterPhysics#enableWrapPlugin - * @since 3.0.0 - * - * @return {this} This Matter Physics instance. - */ - enableWrapPlugin: function () + var result = new Array(sourceColCount); + + for (var i = 0; i < sourceColCount; i++) { - Plugin.register(MatterWrap); - Plugin.use(MatterLib, MatterWrap); + result[i] = new Array(sourceRowCount); - return this; - }, + for (var j = sourceRowCount - 1; j > -1; j--) + { + result[i][j] = array[j][i]; + } + } - /** - * Enables the Matter Collision Events Plugin. - * - * Note that this plugin is enabled by default. So you should only ever need to call this - * method if you have specifically disabled the plugin in your Matter World Config. - * You can disable it by setting `plugins.collisionevents: false` in your Matter World Config. - * - * This plugin triggers three new events on Matter.Body: - * - * 1. `onCollide` - * 2. `onCollideEnd` - * 3. `onCollideActive` - * - * These events correspond to the Matter.js events `collisionStart`, `collisionActive` and `collisionEnd`, respectively. - * You can listen to these events via Matter.Events or they will also be emitted from the Matter World. - * - * This plugin also extends Matter.Body with three convenience functions: - * - * `Matter.Body.setOnCollide(callback)` - * `Matter.Body.setOnCollideEnd(callback)` - * `Matter.Body.setOnCollideActive(callback)` - * - * You can register event callbacks by providing a function of type (pair: Matter.Pair) => void - * - * https://github.com/dxu/matter-collision-events - * - * @method Phaser.Physics.Matter.MatterPhysics#enableCollisionEventsPlugin - * @since 3.22.0 - * - * @return {this} This Matter Physics instance. - */ - enableCollisionEventsPlugin: function () - { - Plugin.register(MatterCollisionEvents); - Plugin.use(MatterLib, MatterCollisionEvents); + return result; +}; - return this; - }, +module.exports = TransposeMatrix; - /** - * Pauses the Matter World instance and sets `enabled` to `false`. - * - * A paused world will not run any simulations for the duration it is paused. - * - * @method Phaser.Physics.Matter.MatterPhysics#pause - * @fires Phaser.Physics.Matter.Events#PAUSE - * @since 3.0.0 - * - * @return {Phaser.Physics.Matter.World} The Matter World object. - */ - pause: function () - { - return this.world.pause(); - }, - /** - * Resumes this Matter World instance from a paused state and sets `enabled` to `true`. - * - * @method Phaser.Physics.Matter.MatterPhysics#resume - * @since 3.0.0 - * - * @return {Phaser.Physics.Matter.World} The Matter World object. - */ - resume: function () - { - return this.world.resume(); - }, +/***/ }), - /** - * Sets the Matter Engine to run at fixed timestep of 60Hz and enables `autoUpdate`. - * If you have set a custom `getDelta` function then this will override it. - * - * @method Phaser.Physics.Matter.MatterPhysics#set60Hz - * @since 3.4.0 - * - * @return {this} This Matter Physics instance. - */ - set60Hz: function () - { - this.world.getDelta = this.world.update60Hz; - this.world.autoUpdate = true; +/***/ 13515: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return this; - }, +/** + * @namespace Phaser.Utils.Array.Matrix + */ - /** - * Sets the Matter Engine to run at fixed timestep of 30Hz and enables `autoUpdate`. - * If you have set a custom `getDelta` function then this will override it. - * - * @method Phaser.Physics.Matter.MatterPhysics#set30Hz - * @since 3.4.0 - * - * @return {this} This Matter Physics instance. - */ - set30Hz: function () - { - this.world.getDelta = this.world.update30Hz; - this.world.autoUpdate = true; +module.exports = { - return this; - }, + CheckMatrix: __webpack_require__(97494), + MatrixToString: __webpack_require__(68428), + ReverseColumns: __webpack_require__(59521), + ReverseRows: __webpack_require__(51995), + Rotate180: __webpack_require__(89011), + RotateLeft: __webpack_require__(42549), + RotateMatrix: __webpack_require__(63515), + RotateRight: __webpack_require__(14305), + Translate: __webpack_require__(27365), + TransposeMatrix: __webpack_require__(78581) - /** - * Manually advances the physics simulation by one iteration. - * - * You can optionally pass in the `delta` and `correction` values to be used by Engine.update. - * If undefined they use the Matter defaults of 60Hz and no correction. - * - * Calling `step` directly bypasses any checks of `enabled` or `autoUpdate`. - * - * It also ignores any custom `getDelta` functions, as you should be passing the delta - * value in to this call. - * - * You can adjust the number of iterations that Engine.update performs internally. - * Use the Scene Matter Physics config object to set the following properties: - * - * positionIterations (defaults to 6) - * velocityIterations (defaults to 4) - * constraintIterations (defaults to 2) - * - * Adjusting these values can help performance in certain situations, depending on the physics requirements - * of your game. - * - * @method Phaser.Physics.Matter.MatterPhysics#step - * @since 3.4.0 - * - * @param {number} [delta=16.666] - The delta value. - * @param {number} [correction=1] - Optional delta correction value. - */ - step: function (delta, correction) - { - this.world.step(delta, correction); - }, +}; - /** - * Checks if the vertices of the given body, or an array of bodies, contains the given point, or not. - * - * You can pass in either a single body, or an array of bodies to be checked. This method will - * return `true` if _any_ of the bodies in the array contain the point. See the `intersectPoint` method if you need - * to get a list of intersecting bodies. - * - * The point should be transformed into the Matter World coordinate system in advance. This happens by - * default with Input Pointers, but if you wish to use points from another system you may need to - * transform them before passing them. - * - * @method Phaser.Physics.Matter.MatterPhysics#containsPoint - * @since 3.22.0 - * - * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} body - The body, or an array of bodies, to check against the point. - * @param {number} x - The horizontal coordinate of the point. - * @param {number} y - The vertical coordinate of the point. - * - * @return {boolean} `true` if the point is within one of the bodies given, otherwise `false`. - */ - containsPoint: function (body, x, y) - { - body = this.getMatterBodies(body); - var position = Vector.create(x, y); +/***/ }), - var result = Query.point(body, position); +/***/ 40581: +/***/ ((module) => { - return (result.length > 0) ? true : false; - }, +/** + * @author Niklas von Hertzen (https://github.com/niklasvh/base64-arraybuffer) + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Checks the given coordinates to see if any vertices of the given bodies contain it. - * - * If no bodies are provided it will search all bodies in the Matter World, including within Composites. - * - * The coordinates should be transformed into the Matter World coordinate system in advance. This happens by - * default with Input Pointers, but if you wish to use coordinates from another system you may need to - * transform them before passing them. - * - * @method Phaser.Physics.Matter.MatterPhysics#intersectPoint - * @since 3.22.0 - * - * @param {number} x - The horizontal coordinate of the point. - * @param {number} y - The vertical coordinate of the point. - * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world. - * - * @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies which contain the given point. - */ - intersectPoint: function (x, y, bodies) +var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +/** + * Converts an ArrayBuffer into a base64 string. + * + * The resulting string can optionally be a data uri if the `mediaType` argument is provided. + * + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs for more details. + * + * @function Phaser.Utils.Base64.ArrayBufferToBase64 + * @since 3.18.0 + * + * @param {ArrayBuffer} arrayBuffer - The Array Buffer to encode. + * @param {string} [mediaType] - An optional media type, i.e. `audio/ogg` or `image/jpeg`. If included the resulting string will be a data URI. + * + * @return {string} The base64 encoded Array Buffer. + */ +var ArrayBufferToBase64 = function (arrayBuffer, mediaType) +{ + var bytes = new Uint8Array(arrayBuffer); + var len = bytes.length; + + var base64 = (mediaType) ? 'data:' + mediaType + ';base64,' : ''; + + for (var i = 0; i < len; i += 3) { - bodies = this.getMatterBodies(bodies); + base64 += chars[bytes[i] >> 2]; + base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; + base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; + base64 += chars[bytes[i + 2] & 63]; + } - var position = Vector.create(x, y); + if ((len % 3) === 2) + { + base64 = base64.substring(0, base64.length - 1) + '='; + } + else if (len % 3 === 1) + { + base64 = base64.substring(0, base64.length - 2) + '=='; + } - var output = []; + return base64; +}; - var result = Query.point(bodies, position); +module.exports = ArrayBufferToBase64; - result.forEach(function (body) - { - if (output.indexOf(body) === -1) - { - output.push(body); - } - }); - return output; - }, +/***/ }), - /** - * Checks the given rectangular area to see if any vertices of the given bodies intersect with it. - * Or, if the `outside` parameter is set to `true`, it checks to see which bodies do not - * intersect with it. - * - * If no bodies are provided it will search all bodies in the Matter World, including within Composites. - * - * @method Phaser.Physics.Matter.MatterPhysics#intersectRect - * @since 3.22.0 - * - * @param {number} x - The horizontal coordinate of the top-left of the area. - * @param {number} y - The vertical coordinate of the top-left of the area. - * @param {number} width - The width of the area. - * @param {number} height - The height of the area. - * @param {boolean} [outside=false] - If `false` it checks for vertices inside the area, if `true` it checks for vertices outside the area. - * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world. - * - * @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies that intersect with the given area. - */ - intersectRect: function (x, y, width, height, outside, bodies) - { - if (outside === undefined) { outside = false; } +/***/ 82329: +/***/ ((module) => { - bodies = this.getMatterBodies(bodies); +/** + * @author Niklas von Hertzen (https://github.com/niklasvh/base64-arraybuffer) + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var bounds = { - min: { x: x, y: y }, - max: { x: x + width, y: y + height } - }; +var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - var output = []; +// Use a lookup table to find the index. +var lookup = new Uint8Array(256); - var result = Query.region(bodies, bounds, outside); +for (var i = 0; i < chars.length; i++) +{ + lookup[chars.charCodeAt(i)] = i; +} - result.forEach(function (body) - { - if (output.indexOf(body) === -1) - { - output.push(body); - } - }); +/** + * 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); - return output; - }, + var len = base64.length; + var bufferLength = len * 0.75; + var p = 0; + var encoded1; + var encoded2; + var encoded3; + var encoded4; - /** - * Checks the given ray segment to see if any vertices of the given bodies intersect with it. - * - * If no bodies are provided it will search all bodies in the Matter World. - * - * The width of the ray can be specified via the `rayWidth` parameter. - * - * @method Phaser.Physics.Matter.MatterPhysics#intersectRay - * @since 3.22.0 - * - * @param {number} x1 - The horizontal coordinate of the start of the ray segment. - * @param {number} y1 - The vertical coordinate of the start of the ray segment. - * @param {number} x2 - The horizontal coordinate of the end of the ray segment. - * @param {number} y2 - The vertical coordinate of the end of the ray segment. - * @param {number} [rayWidth=1] - The width of the ray segment. - * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world. - * - * @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with the ray segment. - */ - intersectRay: function (x1, y1, x2, y2, rayWidth, bodies) + if (base64[len - 1] === '=') { - if (rayWidth === undefined) { rayWidth = 1; } - - bodies = this.getMatterBodies(bodies); - - var result = []; - var collisions = Query.ray(bodies, Vector.create(x1, y1), Vector.create(x2, y2), rayWidth); + bufferLength--; - for (var i = 0; i < collisions.length; i++) + if (base64[len - 2] === '=') { - result.push(collisions[i].body); + bufferLength--; } + } - return result; - }, + var arrayBuffer = new ArrayBuffer(bufferLength); + var bytes = new Uint8Array(arrayBuffer); - /** - * Checks the given Matter Body to see if it intersects with any of the given bodies. - * - * If no bodies are provided it will check against all bodies in the Matter World. - * - * @method Phaser.Physics.Matter.MatterPhysics#intersectBody - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The target body. - * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check the target body against. If not provided it will search all bodies in the world. - * - * @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with target body. - */ - intersectBody: function (body, bodies) + for (var i = 0; i < len; i += 4) { - bodies = this.getMatterBodies(bodies); + encoded1 = lookup[base64.charCodeAt(i)]; + encoded2 = lookup[base64.charCodeAt(i + 1)]; + encoded3 = lookup[base64.charCodeAt(i + 2)]; + encoded4 = lookup[base64.charCodeAt(i + 3)]; - var result = []; - var collisions = Query.collides(body, bodies); + bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); + bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); + bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); + } - for (var i = 0; i < collisions.length; i++) - { - var pair = collisions[i]; + return arrayBuffer; +}; - if (pair.bodyA === body) - { - result.push(pair.bodyB); - } - else - { - result.push(pair.bodyA); - } - } +module.exports = Base64ToArrayBuffer; - return result; - }, - /** - * Checks to see if the target body, or an array of target bodies, intersects with any of the given bodies. - * - * If intersection occurs this method will return `true` and, if provided, invoke the callbacks. - * - * If no bodies are provided for the second parameter the target will check again all bodies in the Matter World. - * - * Note that bodies can only overlap if they are in non-colliding collision groups or categories. - * - * If you provide a `processCallback` then the two bodies that overlap are sent to it. This callback - * must return a boolean and is used to allow you to perform additional processing tests before a final - * outcome is decided. If it returns `true` then the bodies are finally passed to the `overlapCallback`, if set. - * - * If you provide an `overlapCallback` then the matching pairs of overlapping bodies will be sent to it. - * - * Both callbacks have the following signature: `function (bodyA, bodyB, collisionInfo)` where `bodyA` is always - * the target body. The `collisionInfo` object contains additional data, such as the angle and depth of penetration. - * - * @method Phaser.Physics.Matter.MatterPhysics#overlap - * @since 3.22.0 - * - * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} target - The target body, or array of target bodies, to check. - * @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - The second body, or array of bodies, to check. If falsey it will check against all bodies in the world. - * @param {ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the bodies overlap. - * @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two bodies if they overlap. If this is set then `overlapCallback` will only be invoked if this callback returns `true`. - * @param {*} [callbackContext] - The context, or scope, in which to run the callbacks. - * - * @return {boolean} `true` if the target body intersects with _any_ of the bodies given, otherwise `false`. - */ - overlap: function (target, bodies, overlapCallback, processCallback, callbackContext) - { - if (overlapCallback === undefined) { overlapCallback = null; } - if (processCallback === undefined) { processCallback = null; } - if (callbackContext === undefined) { callbackContext = overlapCallback; } +/***/ }), - if (!Array.isArray(target)) - { - target = [ target ]; - } +/***/ 78417: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - target = this.getMatterBodies(target); - bodies = this.getMatterBodies(bodies); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - var match = false; +/** + * @namespace Phaser.Utils.Base64 + */ - for (var i = 0; i < target.length; i++) - { - var entry = target[i]; +module.exports = { - var collisions = Query.collides(entry, bodies); + ArrayBufferToBase64: __webpack_require__(40581), + Base64ToArrayBuffer: __webpack_require__(82329) - for (var c = 0; c < collisions.length; c++) - { - var info = collisions[c]; - var bodyB = (info.bodyA.id === entry.id) ? info.bodyB : info.bodyA; +}; - if (!processCallback || processCallback.call(callbackContext, entry, bodyB, info)) - { - match = true; - if (overlapCallback) - { - overlapCallback.call(callbackContext, entry, bodyB, info); - } - else if (!processCallback) - { - // If there are no callbacks we don't need to test every body, just exit when the first is found - return true; - } - } - } - } +/***/ }), - return match; - }, +/***/ 22178: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Sets the collision filter category of all given Matter Bodies to the given value. - * - * This number must be a power of two between 2^0 (= 1) and 2^31. - * - * Bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision - * categories are included in their collision masks (see {@link #setCollidesWith}). - * - * @method Phaser.Physics.Matter.MatterPhysics#setCollisionCategory - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world. - * @param {number} value - Unique category bitfield. - * - * @return {this} This Matter Physics instance. - */ - setCollisionCategory: function (bodies, value) - { - bodies = this.getMatterBodies(bodies); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - bodies.forEach(function (body) - { - body.collisionFilter.category = value; - }); +/** + * @namespace Phaser.Utils + */ - return this; - }, +module.exports = { - /** - * Sets the collision filter group of all given Matter Bodies to the given value. - * - * If the group value is zero, or if two Matter Bodies have different group values, - * they will collide according to the usual collision filter rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}). - * - * If two Matter Bodies have the same positive group value, they will always collide; - * if they have the same negative group value they will never collide. - * - * @method Phaser.Physics.Matter.MatterPhysics#setCollisionGroup - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world. - * @param {number} value - Unique group index. - * - * @return {this} This Matter Physics instance. - */ - setCollisionGroup: function (bodies, value) - { - bodies = this.getMatterBodies(bodies); + Array: __webpack_require__(59959), + Base64: __webpack_require__(78417), + Objects: __webpack_require__(64615), + String: __webpack_require__(50379), + NOOP: __webpack_require__(72283), + NULL: __webpack_require__(10618) - bodies.forEach(function (body) - { - body.collisionFilter.group = value; - }); +}; - return this; - }, - /** - * Sets the collision filter mask of all given Matter Bodies to the given value. - * - * Two Matter Bodies with different collision groups will only collide if each one includes the others - * category in its mask based on a bitwise AND operation: `(categoryA & maskB) !== 0` and - * `(categoryB & maskA) !== 0` are both true. - * - * @method Phaser.Physics.Matter.MatterPhysics#setCollidesWith - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world. - * @param {(number|number[])} categories - A unique category bitfield, or an array of them. - * - * @return {this} This Matter Physics instance. - */ - setCollidesWith: function (bodies, categories) - { - bodies = this.getMatterBodies(bodies); +/***/ }), - var flags = 0; +/***/ 32742: +/***/ ((module) => { - if (!Array.isArray(categories)) +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Shallow Object Clone. Will not clone nested objects. + * + * @function Phaser.Utils.Objects.Clone + * @since 3.0.0 + * + * @param {object} obj - The object to clone. + * + * @return {object} A new object with the same properties as the input object. + */ +var Clone = function (obj) +{ + var clone = {}; + + for (var key in obj) + { + if (Array.isArray(obj[key])) { - flags = categories; + clone[key] = obj[key].slice(0); } else { - for (var i = 0; i < categories.length; i++) - { - flags |= categories[i]; - } + clone[key] = obj[key]; } + } - bodies.forEach(function (body) - { - body.collisionFilter.mask = flags; - }); - - return this; - }, + return clone; +}; - /** - * Takes an array and returns a new array made from all of the Matter Bodies found in the original array. - * - * For example, passing in Matter Game Objects, such as a bunch of Matter Sprites, to this method, would - * return an array containing all of their native Matter Body objects. - * - * If the `bodies` argument is falsey, it will return all bodies in the world. - * - * @method Phaser.Physics.Matter.MatterPhysics#getMatterBodies - * @since 3.22.0 - * - * @param {array} [bodies] - An array of objects to extract the bodies from. If falsey, it will return all bodies in the world. - * - * @return {MatterJS.BodyType[]} An array of native Matter Body objects. - */ - getMatterBodies: function (bodies) - { - if (!bodies) - { - return this.world.getAllBodies(); - } +module.exports = Clone; - if (!Array.isArray(bodies)) - { - bodies = [ bodies ]; - } - var output = []; +/***/ }), - for (var i = 0; i < bodies.length; i++) - { - var body = (bodies[i].hasOwnProperty('body')) ? bodies[i].body : bodies[i]; +/***/ 28699: +/***/ ((module) => { - output.push(body); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - return output; - }, +/** + * Deep Copy the given object or array. + * + * @function Phaser.Utils.Objects.DeepCopy + * @since 3.50.0 + * + * @param {object} obj - The object to deep copy. + * + * @return {object} A deep copy of the original object. + */ +var DeepCopy = function (inObject) +{ + var outObject; + var value; + var key; - /** - * Sets both the horizontal and vertical linear velocity of the physics bodies. - * - * @method Phaser.Physics.Matter.MatterPhysics#setVelocity - * @since 3.22.0 - * - * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. - * @param {number} x - The horizontal linear velocity value. - * @param {number} y - The vertical linear velocity value. - * - * @return {this} This Matter Physics instance. - */ - setVelocity: function (bodies, x, y) + if (typeof inObject !== 'object' || inObject === null) { - bodies = this.getMatterBodies(bodies); + // inObject is not an object + return inObject; + } - var vec2 = this._tempVec2; + // Create an array or object to hold the values + outObject = Array.isArray(inObject) ? [] : {}; - vec2.x = x; - vec2.y = y; + for (key in inObject) + { + value = inObject[key]; - bodies.forEach(function (body) - { - Body.setVelocity(body, vec2); - }); + // Recursively (deep) copy for nested objects, including arrays + outObject[key] = DeepCopy(value); + } - return this; - }, + return outObject; +}; - /** - * Sets just the horizontal linear velocity of the physics bodies. - * The vertical velocity of the body is unchanged. - * - * @method Phaser.Physics.Matter.MatterPhysics#setVelocityX - * @since 3.22.0 - * - * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. - * @param {number} x - The horizontal linear velocity value. - * - * @return {this} This Matter Physics instance. - */ - setVelocityX: function (bodies, x) - { - bodies = this.getMatterBodies(bodies); +module.exports = DeepCopy; - var vec2 = this._tempVec2; - vec2.x = x; +/***/ }), - bodies.forEach(function (body) - { - vec2.y = body.velocity.y; - Body.setVelocity(body, vec2); - }); +/***/ 98611: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - return this; - }, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * Sets just the vertical linear velocity of the physics bodies. - * The horizontal velocity of the body is unchanged. - * - * @method Phaser.Physics.Matter.MatterPhysics#setVelocityY - * @since 3.22.0 - * - * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. - * @param {number} y - The vertical linear velocity value. - * - * @return {this} This Matter Physics instance. - */ - setVelocityY: function (bodies, y) - { - bodies = this.getMatterBodies(bodies); +var IsPlainObject = __webpack_require__(42911); - var vec2 = this._tempVec2; +// @param {boolean} deep - Perform a deep copy? +// @param {object} target - The target object to copy to. +// @return {object} The extended object. - vec2.y = y; +/** + * This is a slightly modified version of http://api.jquery.com/jQuery.extend/ + * + * @function Phaser.Utils.Objects.Extend + * @since 3.0.0 + * + * @param {...*} [args] - The objects that will be mixed. + * + * @return {object} The extended object. + */ +var Extend = function () +{ + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; - bodies.forEach(function (body) - { - vec2.x = body.velocity.x; - Body.setVelocity(body, vec2); - }); + // Handle a deep copy situation + if (typeof target === 'boolean') + { + deep = target; + target = arguments[1] || {}; - return this; - }, + // skip the boolean and the target + i = 2; + } - /** - * Sets the angular velocity of the bodies instantly. - * Position, angle, force etc. are unchanged. - * - * @method Phaser.Physics.Matter.MatterPhysics#setAngularVelocity - * @since 3.22.0 - * - * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. - * @param {number} value - The angular velocity. - * - * @return {this} This Matter Physics instance. - */ - setAngularVelocity: function (bodies, value) + // extend Phaser if only one argument is passed + if (length === i) { - bodies = this.getMatterBodies(bodies); + target = this; + --i; + } - bodies.forEach(function (body) + for (; i < length; i++) + { + // Only deal with non-null/undefined values + if ((options = arguments[i]) != null) { - Body.setAngularVelocity(body, value); - }); + // Extend the base object + for (name in options) + { + src = target[name]; + copy = options[name]; - return this; - }, + // Prevent never-ending loop + if (target === copy) + { + continue; + } - /** - * Applies a force to a body, at the bodies current position, including resulting torque. - * - * @method Phaser.Physics.Matter.MatterPhysics#applyForce - * @since 3.22.0 - * - * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. - * @param {Phaser.Types.Math.Vector2Like} force - A Vector that specifies the force to apply. - * - * @return {this} This Matter Physics instance. - */ - applyForce: function (bodies, force) - { - bodies = this.getMatterBodies(bodies); + // Recurse if we're merging plain objects or arrays + if (deep && copy && (IsPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) + { + if (copyIsArray) + { + copyIsArray = false; + clone = src && Array.isArray(src) ? src : []; + } + else + { + clone = src && IsPlainObject(src) ? src : {}; + } - var vec2 = this._tempVec2; + // Never move original objects, clone them + target[name] = Extend(deep, clone, copy); - bodies.forEach(function (body) - { - vec2.x = body.position.x; - vec2.y = body.position.y; + // Don't bring in undefined values + } + else if (copy !== undefined) + { + target[name] = copy; + } + } + } + } - Body.applyForce(body, vec2, force); - }); + // Return the modified object + return target; +}; - return this; - }, +module.exports = Extend; - /** - * Applies a force to a body, from the given world position, including resulting torque. - * If no angle is given, the current body angle is used. - * - * Use very small speed values, such as 0.1, depending on the mass and required velocity. - * - * @method Phaser.Physics.Matter.MatterPhysics#applyForceFromPosition - * @since 3.22.0 - * - * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. - * @param {Phaser.Types.Math.Vector2Like} position - A Vector that specifies the world-space position to apply the force at. - * @param {number} speed - A speed value to be applied to a directional force. - * @param {number} [angle] - The angle, in radians, to apply the force from. Leave undefined to use the current body angle. - * - * @return {this} This Matter Physics instance. - */ - applyForceFromPosition: function (bodies, position, speed, angle) - { - bodies = this.getMatterBodies(bodies); - var vec2 = this._tempVec2; +/***/ }), - bodies.forEach(function (body) - { - if (angle === undefined) - { - angle = body.angle; - } +/***/ 20494: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - vec2.x = speed * Math.cos(angle); - vec2.y = speed * Math.sin(angle); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - Body.applyForce(body, position, vec2); - }); +var MATH = __webpack_require__(5923); +var GetValue = __webpack_require__(10850); - return this; - }, +/** + * Retrieves a value from an object. Allows for more advanced selection options, including: + * + * Allowed types: + * + * Implicit + * { + * x: 4 + * } + * + * From function + * { + * x: function () + * } + * + * Randomly pick one element from the array + * { + * x: [a, b, c, d, e, f] + * } + * + * Random integer between min and max: + * { + * x: { randInt: [min, max] } + * } + * + * Random float between min and max: + * { + * x: { randFloat: [min, max] } + * } + * + * + * @function Phaser.Utils.Objects.GetAdvancedValue + * @since 3.0.0 + * + * @param {object} source - The object to retrieve the value from. + * @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object. + * @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object. + * + * @return {*} The value of the requested key. + */ +var GetAdvancedValue = function (source, key, defaultValue) +{ + var value = GetValue(source, key, null); - /** - * Apply a force to a body based on the given angle and speed. - * If no angle is given, the current body angle is used. - * - * Use very small speed values, such as 0.1, depending on the mass and required velocity. - * - * @method Phaser.Physics.Matter.MatterPhysics#applyForceFromAngle - * @since 3.22.0 - * - * @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world. - * @param {number} speed - A speed value to be applied to a directional force. - * @param {number} [angle] - The angle, in radians, to apply the force from. Leave undefined to use the current body angle. - * - * @return {this} This Matter Physics instance. - */ - applyForceFromAngle: function (bodies, speed, angle) + if (value === null) { - bodies = this.getMatterBodies(bodies); + return defaultValue; + } + else if (Array.isArray(value)) + { + return MATH.RND.pick(value); + } + else if (typeof value === 'object') + { + if (value.hasOwnProperty('randInt')) + { + return MATH.RND.integerInRange(value.randInt[0], value.randInt[1]); + } + else if (value.hasOwnProperty('randFloat')) + { + return MATH.RND.realInRange(value.randFloat[0], value.randFloat[1]); + } + } + else if (typeof value === 'function') + { + return value(key); + } - var vec2 = this._tempVec2; + return value; +}; - bodies.forEach(function (body) - { - if (angle === undefined) - { - angle = body.angle; - } +module.exports = GetAdvancedValue; - vec2.x = speed * Math.cos(angle); - vec2.y = speed * Math.sin(angle); - Body.applyForce(body, { x: body.position.x, y: body.position.y }, vec2); - }); +/***/ }), - return this; - }, +/***/ 72632: +/***/ ((module) => { - /** - * Returns the length of the given constraint, which is the distance between the two points. - * - * @method Phaser.Physics.Matter.MatterPhysics#getConstraintLength - * @since 3.22.0 - * - * @param {MatterJS.ConstraintType} constraint - The constraint to get the length from. - * - * @return {number} The length of the constraint. - */ - getConstraintLength: function (constraint) +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Finds the key within the top level of the {@link source} object, or returns {@link defaultValue} + * + * @function Phaser.Utils.Objects.GetFastValue + * @since 3.0.0 + * + * @param {object} source - The object to search + * @param {string} key - The key for the property on source. Must exist at the top level of the source object (no periods) + * @param {*} [defaultValue] - The default value to use if the key does not exist. + * + * @return {*} The value if found; otherwise, defaultValue (null if none provided) + */ +var GetFastValue = function (source, key, defaultValue) +{ + var t = typeof(source); + + if (!source || t === 'number' || t === 'string') { - var aX = constraint.pointA.x; - var aY = constraint.pointA.y; - var bX = constraint.pointB.x; - var bY = constraint.pointB.y; + return defaultValue; + } + else if (source.hasOwnProperty(key) && source[key] !== undefined) + { + return source[key]; + } + else + { + return defaultValue; + } +}; - if (constraint.bodyA) - { - aX += constraint.bodyA.position.x; - aY += constraint.bodyA.position.y; - } +module.exports = GetFastValue; - if (constraint.bodyB) - { - bX += constraint.bodyB.position.x; - bY += constraint.bodyB.position.y; - } - return DistanceBetween(aX, aY, bX, bY); - }, +/***/ }), - /** - * Aligns a Body, or Matter Game Object, against the given coordinates. - * - * The alignment takes place using the body bounds, which take into consideration things - * like body scale and rotation. - * - * Although a Body has a `position` property, it is based on the center of mass for the body, - * not a dimension based center. This makes aligning bodies difficult, especially if they have - * rotated or scaled. This method will derive the correct position based on the body bounds and - * its center of mass offset, in order to align the body with the given coordinate. - * - * For example, if you wanted to align a body so it sat in the bottom-center of the - * Scene, and the world was 800 x 600 in size: - * - * ```javascript - * this.matter.alignBody(body, 400, 600, Phaser.Display.Align.BOTTOM_CENTER); - * ``` - * - * You pass in 400 for the x coordinate, because that is the center of the world, and 600 for - * the y coordinate, as that is the base of the world. - * - * @method Phaser.Physics.Matter.MatterPhysics#alignBody - * @since 3.22.0 - * - * @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to align. - * @param {number} x - The horizontal position to align the body to. - * @param {number} y - The vertical position to align the body to. - * @param {number} align - One of the `Phaser.Display.Align` constants, such as `Phaser.Display.Align.TOP_LEFT`. - * - * @return {this} This Matter Physics instance. - */ - alignBody: function (body, x, y, align) - { - body = (body.hasOwnProperty('body')) ? body.body : body; +/***/ 94324: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var GetValue = __webpack_require__(10850); +var Clamp = __webpack_require__(82897); + +/** + * Retrieves and clamps a numerical value from an object. + * + * @function Phaser.Utils.Objects.GetMinMaxValue + * @since 3.0.0 + * + * @param {object} source - The object to retrieve the value from. + * @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`). + * @param {number} min - The minimum value which can be returned. + * @param {number} max - The maximum value which can be returned. + * @param {number} defaultValue - The value to return if the property doesn't exist. It's also constrained to the given bounds. + * + * @return {number} The clamped value from the `source` object. + */ +var GetMinMaxValue = function (source, key, min, max, defaultValue) +{ + if (defaultValue === undefined) { defaultValue = min; } + + var value = GetValue(source, key, defaultValue); - var pos; + return Clamp(value, min, max); +}; - switch (align) - { - case ALIGN_CONST.TOP_LEFT: - case ALIGN_CONST.LEFT_TOP: - pos = this.bodyBounds.getTopLeft(body, x, y); - break; +module.exports = GetMinMaxValue; - case ALIGN_CONST.TOP_CENTER: - pos = this.bodyBounds.getTopCenter(body, x, y); - break; - - case ALIGN_CONST.TOP_RIGHT: - case ALIGN_CONST.RIGHT_TOP: - pos = this.bodyBounds.getTopRight(body, x, y); - break; - case ALIGN_CONST.LEFT_CENTER: - pos = this.bodyBounds.getLeftCenter(body, x, y); - break; +/***/ }), - case ALIGN_CONST.CENTER: - pos = this.bodyBounds.getCenter(body, x, y); - break; +/***/ 10850: +/***/ ((module) => { - case ALIGN_CONST.RIGHT_CENTER: - pos = this.bodyBounds.getRightCenter(body, x, y); - break; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - case ALIGN_CONST.LEFT_BOTTOM: - case ALIGN_CONST.BOTTOM_LEFT: - pos = this.bodyBounds.getBottomLeft(body, x, y); - break; +/** + * Retrieves a value from an object, or an alternative object, falling to a back-up default value if not found. + * + * The key is a string, which can be split based on the use of the period character. + * + * For example: + * + * ```javascript + * const source = { + * lives: 3, + * render: { + * screen: { + * width: 1024 + * } + * } + * } + * + * const lives = GetValue(source, 'lives', 1); + * const width = GetValue(source, 'render.screen.width', 800); + * const height = GetValue(source, 'render.screen.height', 600); + * ``` + * + * In the code above, `lives` will be 3 because it's defined at the top level of `source`. + * The `width` value will be 1024 because it can be found inside the `render.screen` object. + * The `height` value will be 600, the default value, because it is missing from the `render.screen` object. + * + * @function Phaser.Utils.Objects.GetValue + * @since 3.0.0 + * + * @param {object} source - The primary object to try to retrieve the value from. If not found in here, `altSource` is checked. + * @param {string} key - The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object. + * @param {*} defaultValue - The value to return if the `key` isn't found in the `source` object. + * @param {object} [altSource] - An alternative object to retrieve the value from. If the property exists in `source` then `altSource` will not be used. + * + * @return {*} The value of the requested key. + */ +var GetValue = function (source, key, defaultValue, altSource) +{ + if ((!source && !altSource) || typeof source === 'number') + { + return defaultValue; + } + else if (source && source.hasOwnProperty(key)) + { + return source[key]; + } + else if (altSource && altSource.hasOwnProperty(key)) + { + return altSource[key]; + } + else if (key.indexOf('.') !== -1) + { + var keys = key.split('.'); + var parentA = source; + var parentB = altSource; + var valueA = defaultValue; + var valueB = defaultValue; + var valueAFound = true; + var valueBFound = true; - case ALIGN_CONST.BOTTOM_CENTER: - pos = this.bodyBounds.getBottomCenter(body, x, y); - break; + // Use for loop here so we can break early + for (var i = 0; i < keys.length; i++) + { + if (parentA && parentA.hasOwnProperty(keys[i])) + { + // Yes parentA has a key property, let's carry on down + valueA = parentA[keys[i]]; + parentA = parentA[keys[i]]; + } + else + { + valueAFound = false; + } - case ALIGN_CONST.BOTTOM_RIGHT: - case ALIGN_CONST.RIGHT_BOTTOM: - pos = this.bodyBounds.getBottomRight(body, x, y); - break; + if (parentB && parentB.hasOwnProperty(keys[i])) + { + // Yes parentB has a key property, let's carry on down + valueB = parentB[keys[i]]; + parentB = parentB[keys[i]]; + } + else + { + valueBFound = false; + } } - if (pos) + if (valueAFound) { - Body.setPosition(body, pos); + return valueA; + } + else if (valueBFound) + { + return valueB; + } + else + { + return defaultValue; } + } + else + { + return defaultValue; + } +}; - return this; - }, +module.exports = GetValue; - /** - * The Scene that owns this plugin is shutting down. - * We need to kill and reset all internal properties as well as stop listening to Scene events. - * - * @method Phaser.Physics.Matter.MatterPhysics#shutdown - * @private - * @since 3.0.0 - */ - shutdown: function () - { - var eventEmitter = this.systems.events; - if (this.world) - { - eventEmitter.off(SceneEvents.UPDATE, this.world.update, this.world); - eventEmitter.off(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world); - } +/***/ }), - eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this); +/***/ 87701: +/***/ ((module) => { - if (this.add) +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Verifies that an object contains all requested keys + * + * @function Phaser.Utils.Objects.HasAll + * @since 3.0.0 + * + * @param {object} source - an object on which to check for key existence + * @param {string[]} keys - an array of keys to ensure the source object contains + * + * @return {boolean} true if the source object contains all keys, false otherwise. + */ +var HasAll = function (source, keys) +{ + for (var i = 0; i < keys.length; i++) + { + if (!source.hasOwnProperty(keys[i])) { - this.add.destroy(); + return false; } + } - if (this.world) + return true; +}; + +module.exports = HasAll; + + +/***/ }), + +/***/ 53523: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 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])) { - this.world.destroy(); + return true; } + } - this.add = null; - this.world = null; - }, + return false; +}; - /** - * The Scene that owns this plugin is being destroyed. - * We need to shutdown and then kill off all external references. - * - * @method Phaser.Physics.Matter.MatterPhysics#destroy - * @private - * @since 3.0.0 - */ - destroy: function () - { - this.shutdown(); +module.exports = HasAny; - this.scene.sys.events.off(SceneEvents.START, this.start, this); - this.scene = null; - this.systems = null; - } +/***/ }), -}); +/***/ 19256: +/***/ ((module) => { -PluginCache.register('MatterPhysics', MatterPhysics, 'matterPhysics'); +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ -module.exports = MatterPhysics; +/** + * Determine whether the source object has a property with the specified key. + * + * @function Phaser.Utils.Objects.HasValue + * @since 3.0.0 + * + * @param {object} source - The source object to be checked. + * @param {string} key - The property to check for within the object + * + * @return {boolean} `true` if the provided `key` exists on the `source` object, otherwise `false`. + */ +var HasValue = function (source, key) +{ + return (source.hasOwnProperty(key)); +}; + +module.exports = HasValue; /***/ }), -/* 1525 */ -/***/ (function(module, exports, __webpack_require__) { -var Matter = __webpack_require__(594); +/***/ 42911: +/***/ ((module) => { /** - * An attractors plugin for matter.js. - * See the readme for usage and examples. - * @module MatterAttractors + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MatterAttractors = -{ - name: 'matter-attractors', - version: '0.1.7', - for: 'matter-js@^0.14.2', - silent: true, - // installs the plugin where `base` is `Matter` - // you should not need to call this directly. - install: function (base) +/** + * This is a slightly modified version of jQuery.isPlainObject. + * A plain object is an object whose internal class property is [object Object]. + * + * @function Phaser.Utils.Objects.IsPlainObject + * @since 3.0.0 + * + * @param {object} obj - The object to inspect. + * + * @return {boolean} `true` if the object is plain, otherwise `false`. + */ +var IsPlainObject = function (obj) +{ + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if (!obj || typeof(obj) !== 'object' || obj.nodeType || obj === obj.window) { - base.after('Body.create', function () - { - MatterAttractors.Body.init(this); - }); - - base.before('Engine.update', function (engine) - { - MatterAttractors.Engine.update(engine); - }); - }, + return false; + } - Body: + // Support: Firefox <20 + // The try/catch suppresses exceptions thrown when attempting to access + // the "constructor" property of certain host objects, ie. |window.location| + // https://bugzilla.mozilla.org/show_bug.cgi?id=814622 + try { - /** - * Initialises the `body` to support attractors. - * This is called automatically by the plugin. - * @function MatterAttractors.Body.init - * @param {Matter.Body} body The body to init. - * @returns {void} No return value. - */ - init: function (body) + if (obj.constructor && !({}).hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) { - body.plugin.attractors = body.plugin.attractors || []; + return false; } - }, - - Engine: + } + catch (e) { - /** - * Applies all attractors for all bodies in the `engine`. - * This is called automatically by the plugin. - * @function MatterAttractors.Engine.update - * @param {Matter.Engine} engine The engine to update. - * @returns {void} No return value. - */ - update: function (engine) - { - var bodies = Matter.Composite.allBodies(engine.world); + return false; + } - for (var i = 0; i < bodies.length; i++) - { - var bodyA = bodies[i]; - var attractors = bodyA.plugin.attractors; + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; +}; - if (attractors && attractors.length > 0) - { - for (var j = 0; j < bodies.length; j++) - { - var bodyB = bodies[j]; +module.exports = IsPlainObject; - if (i !== j) - { - for (var k = 0; k < attractors.length; k++) - { - var attractor = attractors[k]; - var forceVector = attractor; - if (Matter.Common.isFunction(attractor)) - { - forceVector = attractor(bodyA, bodyB); - } +/***/ }), - if (forceVector) - { - Matter.Body.applyForce(bodyB, bodyB.position, forceVector); - } - } - } - } - } - } - } - }, +/***/ 30657: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - /** - * Defines some useful common attractor functions that can be used - * by pushing them to your body's `body.plugin.attractors` array. - * @namespace MatterAttractors.Attractors - * @property {number} gravityConstant The gravitational constant used by the gravity attractor. - */ - Attractors: - { - gravityConstant: 0.001, +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - /** - * An attractor function that applies Newton's law of gravitation. - * Use this by pushing `MatterAttractors.Attractors.gravity` to your body's `body.plugin.attractors` array. - * The gravitational constant defaults to `0.001` which you can change - * at `MatterAttractors.Attractors.gravityConstant`. - * @function MatterAttractors.Attractors.gravity - * @param {Matter.Body} bodyA The first body. - * @param {Matter.Body} bodyB The second body. - * @returns {void} No return value. - */ - gravity: function (bodyA, bodyB) - { - // use Newton's law of gravitation - var bToA = Matter.Vector.sub(bodyB.position, bodyA.position); - var distanceSq = Matter.Vector.magnitudeSquared(bToA) || 0.0001; - var normal = Matter.Vector.normalise(bToA); - var magnitude = -MatterAttractors.Attractors.gravityConstant * (bodyA.mass * bodyB.mass / distanceSq); - var force = Matter.Vector.mult(normal, magnitude); +var Clone = __webpack_require__(32742); - // to apply forces to both bodies - Matter.Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force)); - Matter.Body.applyForce(bodyB, bodyB.position, force); +/** + * Creates a new Object using all values from obj1 and obj2. + * If a value exists in both obj1 and obj2, the value in obj1 is used. + * + * This is only a shallow copy. Deeply nested objects are not cloned, so be sure to only use this + * function on shallow objects. + * + * @function Phaser.Utils.Objects.Merge + * @since 3.0.0 + * + * @param {object} obj1 - The first object. + * @param {object} obj2 - The second object. + * + * @return {object} A new object containing the union of obj1's and obj2's properties. + */ +var Merge = function (obj1, obj2) +{ + var clone = Clone(obj1); + + for (var key in obj2) + { + if (!clone.hasOwnProperty(key)) + { + clone[key] = obj2[key]; } } + + return clone; }; -module.exports = MatterAttractors; +module.exports = Merge; -/** - * @namespace Matter.Body - * @see http://brm.io/matter-js/docs/classes/Body.html - */ + +/***/ }), + +/***/ 72066: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * This plugin adds a new property `body.plugin.attractors` to instances of `Matter.Body`. - * This is an array of callback functions that will be called automatically - * for every pair of bodies, on every engine update. - * @property {Function[]} body.plugin.attractors - * @memberof Matter.Body + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Clone = __webpack_require__(32742); + /** - * An attractor function calculates the force to be applied - * to `bodyB`, it should either: - * - return the force vector to be applied to `bodyB` - * - or apply the force to the body(s) itself - * @callback AttractorFunction - * @param {Matter.Body} bodyA - * @param {Matter.Body} bodyB - * @returns {(Vector|undefined)} a force vector (optional) + * Creates a new Object using all values from obj1. + * + * Then scans obj2. If a property is found in obj2 that *also* exists in obj1, the value from obj2 is used, otherwise the property is skipped. + * + * @function Phaser.Utils.Objects.MergeRight + * @since 3.0.0 + * + * @param {object} obj1 - The first object to merge. + * @param {object} obj2 - The second object to merge. Keys from this object which also exist in `obj1` will be copied to `obj1`. + * + * @return {object} The merged object. `obj1` and `obj2` are not modified. */ +var MergeRight = function (obj1, obj2) +{ + var clone = Clone(obj1); + + for (var key in obj2) + { + if (clone.hasOwnProperty(key)) + { + clone[key] = obj2[key]; + } + } + + return clone; +}; + +module.exports = MergeRight; /***/ }), -/* 1526 */ -/***/ (function(module, exports) { + +/***/ 28820: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * @author @dxu https://github.com/dxu/matter-collision-events * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MatterCollisionEvents = { +var HasValue = __webpack_require__(19256); - name: 'matter-collision-events', - version: '0.1.6', - for: 'matter-js@^0.14.2', - silent: true, +/** + * 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 = {}; - install: function (matter) + for (var i = 0; i < keys.length; i++) { - matter.after('Engine.create', function () + var key = keys[i]; + + if (HasValue(object, key)) { - matter.Events.on(this, 'collisionStart', function (event) - { - event.pairs.map(function (pair) - { - var bodyA = pair.bodyA; - var bodyB = pair.bodyB; + obj[key] = object[key]; + } + } - if (bodyA.gameObject) - { - bodyA.gameObject.emit('collide', bodyA, bodyB, pair); - } + return obj; +}; - if (bodyB.gameObject) - { - bodyB.gameObject.emit('collide', bodyB, bodyA, pair); - } +module.exports = Pick; - matter.Events.trigger(bodyA, 'onCollide', { pair: pair }); - matter.Events.trigger(bodyB, 'onCollide', { pair: pair }); - if (bodyA.onCollideCallback) - { - bodyA.onCollideCallback(pair); - } +/***/ }), - if (bodyB.onCollideCallback) - { - bodyB.onCollideCallback(pair); - } +/***/ 22440: +/***/ ((module) => { - if (bodyA.onCollideWith[bodyB.id]) - { - bodyA.onCollideWith[bodyB.id](bodyB, pair); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (bodyB.onCollideWith[bodyA.id]) - { - bodyB.onCollideWith[bodyA.id](bodyA, pair); - } - }); - }); +/** + * 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; - matter.Events.on(this, 'collisionActive', function (event) + 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])) { - event.pairs.map(function (pair) - { - var bodyA = pair.bodyA; - var bodyB = pair.bodyB; + // Yes it has a key property, let's carry on down + prev = parent; + parent = parent[keys[i]]; + } + else + { + return false; + } + } - if (bodyA.gameObject) - { - bodyA.gameObject.emit('collideActive', bodyA, bodyB, pair); - } + prev[keys[keys.length - 1]] = value; - if (bodyB.gameObject) - { - bodyB.gameObject.emit('collideActive', bodyB, bodyA, pair); - } + return true; + } - matter.Events.trigger(bodyA, 'onCollideActive', { pair: pair }); - matter.Events.trigger(bodyB, 'onCollideActive', { pair: pair }); + return false; +}; - if (bodyA.onCollideActiveCallback) - { - bodyA.onCollideActiveCallback(pair); - } +module.exports = SetValue; - if (bodyB.onCollideActiveCallback) - { - bodyB.onCollideActiveCallback(pair); - } - }); - }); - matter.Events.on(this, 'collisionEnd', function (event) - { - event.pairs.map(function (pair) - { - var bodyA = pair.bodyA; - var bodyB = pair.bodyB; +/***/ }), - if (bodyA.gameObject) - { - bodyA.gameObject.emit('collideEnd', bodyA, bodyB, pair); - } +/***/ 64615: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - if (bodyB.gameObject) - { - bodyB.gameObject.emit('collideEnd', bodyB, bodyA, pair); - } +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - matter.Events.trigger(bodyA, 'onCollideEnd', { pair: pair }); - matter.Events.trigger(bodyB, 'onCollideEnd', { pair: pair }); +/** + * @namespace Phaser.Utils.Objects + */ - if (bodyA.onCollideEndCallback) - { - bodyA.onCollideEndCallback(pair); - } +module.exports = { - if (bodyB.onCollideEndCallback) - { - bodyB.onCollideEndCallback(pair); - } - }); - }); - }); - } -}; + Clone: __webpack_require__(32742), + DeepCopy: __webpack_require__(28699), + Extend: __webpack_require__(98611), + GetAdvancedValue: __webpack_require__(20494), + GetFastValue: __webpack_require__(72632), + GetMinMaxValue: __webpack_require__(94324), + GetValue: __webpack_require__(10850), + HasAll: __webpack_require__(87701), + HasAny: __webpack_require__(53523), + HasValue: __webpack_require__(19256), + IsPlainObject: __webpack_require__(42911), + Merge: __webpack_require__(30657), + MergeRight: __webpack_require__(72066), + Pick: __webpack_require__(28820), + SetValue: __webpack_require__(22440) -module.exports = MatterCollisionEvents; +}; /***/ }), -/* 1527 */ -/***/ (function(module, exports, __webpack_require__) { -var Matter = __webpack_require__(594); +/***/ 69429: +/***/ ((module) => { /** - * A coordinate wrapping plugin for matter.js. - * See the readme for usage and examples. - * @module MatterWrap + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var MatterWrap = { - // plugin meta - name: 'matter-wrap', // PLUGIN_NAME - version: '0.1.4', // PLUGIN_VERSION - for: 'matter-js@^0.14.2', - silent: true, // no console log please - // installs the plugin where `base` is `Matter` - // you should not need to call this directly. - install: function(base) { - base.after('Engine.update', function() { - MatterWrap.Engine.update(this); +/** + * Takes a string and replaces instances of markers with values in the given array. + * The markers take the form of `%1`, `%2`, etc. I.e.: + * + * `Format("The %1 is worth %2 gold", [ 'Sword', 500 ])` + * + * @function Phaser.Utils.String.Format + * @since 3.0.0 + * + * @param {string} string - The string containing the replacement markers. + * @param {array} values - An array containing values that will replace the markers. If no value exists an empty string is inserted instead. + * + * @return {string} The string containing replaced values. + */ +var Format = function (string, values) +{ + return string.replace(/%([0-9]+)/g, function (s, n) + { + return values[Number(n) - 1]; }); - }, - - Engine: { - /** - * Updates the engine by wrapping bodies and composites inside `engine.world`. - * This is called automatically by the plugin. - * @function MatterWrap.Engine.update - * @param {Matter.Engine} engine The engine to update. - * @returns {void} No return value. - */ - update: function(engine) { - var world = engine.world, - bodies = Matter.Composite.allBodies(world), - composites = Matter.Composite.allComposites(world); +}; - for (var i = 0; i < bodies.length; i += 1) { - var body = bodies[i]; +module.exports = Format; - if (body.plugin.wrap) { - MatterWrap.Body.wrap(body, body.plugin.wrap); - } - } - for (i = 0; i < composites.length; i += 1) { - var composite = composites[i]; +/***/ }), - if (composite.plugin.wrap) { - MatterWrap.Composite.wrap(composite, composite.plugin.wrap); - } - } - } - }, +/***/ 76400: +/***/ ((module) => { - Bounds: { - /** - * Returns a translation vector that wraps the `objectBounds` inside the `bounds`. - * @function MatterWrap.Bounds.wrap - * @param {Matter.Bounds} objectBounds The bounds of the object to wrap inside the bounds. - * @param {Matter.Bounds} bounds The bounds to wrap the body inside. - * @returns {?Matter.Vector} A translation vector (only if wrapping is required). - */ - wrap: function(objectBounds, bounds) { - var x = null, - y = null; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ - if (typeof bounds.min.x !== 'undefined' && typeof bounds.max.x !== 'undefined') { - if (objectBounds.min.x > bounds.max.x) { - x = bounds.min.x - objectBounds.max.x; - } else if (objectBounds.max.x < bounds.min.x) { - x = bounds.max.x - objectBounds.min.x; - } - } +/** + * Takes the given string and pads it out, to the length required, using the character + * specified. For example if you need a string to be 6 characters long, you can call: + * + * `pad('bob', 6, '-', 2)` + * + * This would return: `bob---` as it has padded it out to 6 characters, using the `-` on the right. + * + * You can also use it to pad numbers (they are always returned as strings): + * + * `pad(512, 6, '0', 1)` + * + * Would return: `000512` with the string padded to the left. + * + * If you don't specify a direction it'll pad to both sides: + * + * `pad('c64', 7, '*')` + * + * Would return: `**c64**` + * + * @function Phaser.Utils.String.Pad + * @since 3.0.0 + * + * @param {string|number|object} str - The target string. `toString()` will be called on the string, which means you can also pass in common data types like numbers. + * @param {number} [len=0] - The number of characters to be added. + * @param {string} [pad=" "] - The string to pad it out with (defaults to a space). + * @param {number} [dir=3] - The direction dir = 1 (left), 2 (right), 3 (both). + * + * @return {string} The padded string. + */ +var Pad = function (str, len, pad, dir) +{ + if (len === undefined) { len = 0; } + if (pad === undefined) { pad = ' '; } + if (dir === undefined) { dir = 3; } - if (typeof bounds.min.y !== 'undefined' && typeof bounds.max.y !== 'undefined') { - if (objectBounds.min.y > bounds.max.y) { - y = bounds.min.y - objectBounds.max.y; - } else if (objectBounds.max.y < bounds.min.y) { - y = bounds.max.y - objectBounds.min.y; - } - } + str = str.toString(); - if (x !== null || y !== null) { - return { - x: x || 0, - y: y || 0 - }; - } - } - }, + var padlen = 0; - Body: { - /** - * Wraps the `body` position such that it always stays within the given bounds. - * Upon crossing a boundary the body will appear on the opposite side of the bounds, - * while maintaining its velocity. - * This is called automatically by the plugin. - * @function MatterWrap.Body.wrap - * @param {Matter.Body} body The body to wrap. - * @param {Matter.Bounds} bounds The bounds to wrap the body inside. - * @returns {?Matter.Vector} The translation vector that was applied (only if wrapping was required). - */ - wrap: function(body, bounds) { - var translation = MatterWrap.Bounds.wrap(body.bounds, bounds); + if (len + 1 >= str.length) + { + switch (dir) + { + case 1: + str = new Array(len + 1 - str.length).join(pad) + str; + break; - if (translation) { - Matter.Body.translate(body, translation); - } + case 3: + var right = Math.ceil((padlen = len - str.length) / 2); + var left = padlen - right; + str = new Array(left + 1).join(pad) + str + new Array(right + 1).join(pad); + break; - return translation; + default: + str = str + new Array(len + 1 - str.length).join(pad); + break; + } } - }, - Composite: { - /** - * Returns the union of the bounds of all of the composite's bodies - * (not accounting for constraints). - * @function MatterWrap.Composite.bounds - * @param {Matter.Composite} composite The composite. - * @returns {Matter.Bounds} The composite bounds. - */ - bounds: function(composite) { - var bodies = Matter.Composite.allBodies(composite), - vertices = []; - - for (var i = 0; i < bodies.length; i += 1) { - var body = bodies[i]; - vertices.push(body.bounds.min, body.bounds.max); - } + return str; +}; - return Matter.Bounds.create(vertices); - }, +module.exports = Pad; - /** - * Wraps the `composite` position such that it always stays within the given bounds. - * Upon crossing a boundary the composite will appear on the opposite side of the bounds, - * while maintaining its velocity. - * This is called automatically by the plugin. - * @function MatterWrap.Composite.wrap - * @param {Matter.Composite} composite The composite to wrap. - * @param {Matter.Bounds} bounds The bounds to wrap the composite inside. - * @returns {?Matter.Vector} The translation vector that was applied (only if wrapping was required). - */ - wrap: function(composite, bounds) { - var translation = MatterWrap.Bounds.wrap( - MatterWrap.Composite.bounds(composite), - bounds - ); - if (translation) { - Matter.Composite.translate(composite, translation); - } +/***/ }), - return translation; - } - } -}; +/***/ 76872: +/***/ ((module) => { -module.exports = MatterWrap; +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ /** - * @namespace Matter.Body - * @see http://brm.io/matter-js/docs/classes/Body.html + * Takes a string and removes the character at the given index. + * + * @function Phaser.Utils.String.RemoveAt + * @since 3.50.0 + * + * @param {string} string - The string to be worked on. + * @param {number} index - The index of the character to be removed. + * + * @return {string} The modified string. */ +var RemoveAt = function (string, index) +{ + if (index === 0) + { + return string.slice(1); + } + else + { + return string.slice(0, index - 1) + string.slice(index); + } +}; + +module.exports = RemoveAt; + + +/***/ }), + +/***/ 8051: +/***/ ((module) => { /** - * This plugin adds a new property `body.plugin.wrap` to instances of `Matter.Body`. - * This is a `Matter.Bounds` instance that specifies the wrapping region. - * @property {Matter.Bounds} body.plugin.wrap - * @memberof Matter.Body + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ /** - * This plugin adds a new property `composite.plugin.wrap` to instances of `Matter.Composite`. - * This is a `Matter.Bounds` instance that specifies the wrapping region. - * @property {Matter.Bounds} composite.plugin.wrap - * @memberof Matter.Composite + * Takes the given string and reverses it, returning the reversed string. + * For example if given the string `Atari 520ST` it would return `TS025 iratA`. + * + * @function Phaser.Utils.String.Reverse + * @since 3.0.0 + * + * @param {string} string - The string to be reversed. + * + * @return {string} The reversed string. */ +var Reverse = function (string) +{ + return string.split('').reverse().join(''); +}; + +module.exports = Reverse; + /***/ }), -/* 1528 */ -/***/ (function(module, exports, __webpack_require__) { -/* WEBPACK VAR INJECTION */(function(global) {/** +/***/ 76583: +/***/ ((module) => { + +/** * @author Richard Davey - * @copyright 2020 Photon Storm Ltd. + * @copyright 2013-2023 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -var CONST = __webpack_require__(33); -var Extend = __webpack_require__(17); - /** - * @namespace Phaser + * Creates and returns an RFC4122 version 4 compliant UUID. + * + * The string is in the form: `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` where each `x` is replaced with a random + * hexadecimal digit from 0 to f, and `y` is replaced with a random hexadecimal digit from 8 to b. + * + * @function Phaser.Utils.String.UUID + * @since 3.12.0 + * + * @return {string} The UUID string. */ +var UUID = function () +{ + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) + { + var r = Math.random() * 16 | 0; + var v = (c === 'x') ? r : (r & 0x3 | 0x8); -var Phaser = { + return v.toString(16); + }); +}; - Actions: __webpack_require__(275), - Animations: __webpack_require__(723), - BlendModes: __webpack_require__(35), - Cache: __webpack_require__(735), - Cameras: __webpack_require__(738), - Core: __webpack_require__(806), - Class: __webpack_require__(0), - Create: __webpack_require__(888), - Curves: __webpack_require__(894), - Data: __webpack_require__(896), - Display: __webpack_require__(898), - DOM: __webpack_require__(917), - Events: __webpack_require__(918), - Game: __webpack_require__(920), - GameObjects: __webpack_require__(1011), - Geom: __webpack_require__(483), - Input: __webpack_require__(1308), - Loader: __webpack_require__(1338), - Math: __webpack_require__(193), - Physics: __webpack_require__(1493), - Plugins: __webpack_require__(1403), - Renderer: __webpack_require__(1405), - Scale: __webpack_require__(1412), - ScaleModes: __webpack_require__(168), - Scene: __webpack_require__(418), - Scenes: __webpack_require__(1413), - Structs: __webpack_require__(1415), - Textures: __webpack_require__(1416), - Tilemaps: __webpack_require__(1418), - Time: __webpack_require__(1461), - Tweens: __webpack_require__(1463), - Utils: __webpack_require__(1481) +module.exports = UUID; -}; -// Merge in the optional plugins and WebGL only features +/***/ }), -if (true) +/***/ 40587: +/***/ ((module) => { + +/** + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +/** + * Capitalizes the first letter of a string if there is one. + * @example + * UppercaseFirst('abc'); + * // returns 'Abc' + * @example + * UppercaseFirst('the happy family'); + * // returns 'The happy family' + * @example + * UppercaseFirst(''); + * // returns '' + * + * @function Phaser.Utils.String.UppercaseFirst + * @since 3.0.0 + * + * @param {string} str - The string to capitalize. + * + * @return {string} A new string, same as the first, but with the first letter capitalized. + */ +var UppercaseFirst = function (str) { - Phaser.Sound = __webpack_require__(1492); -} + return str && str[0].toUpperCase() + str.slice(1); +}; -if (false) -{} +module.exports = UppercaseFirst; -if (false) -{} -// Merge in the consts +/***/ }), -Phaser = Extend(false, Phaser, CONST); +/***/ 50379: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** - * The root types namespace. - * - * @namespace Phaser.Types - * @since 3.17.0 + * @author Richard Davey + * @copyright 2013-2023 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// Export it +/** + * @namespace Phaser.Utils.String + */ -module.exports = Phaser; +module.exports = { -global.Phaser = Phaser; + Format: __webpack_require__(69429), + Pad: __webpack_require__(76400), + RemoveAt: __webpack_require__(76872), + Reverse: __webpack_require__(8051), + UppercaseFirst: __webpack_require__(40587), + UUID: __webpack_require__(76583) -/* - * "Documentation is like pizza: when it is good, it is very, very good; - * and when it is bad, it is better than nothing." - * -- Dick Brandon - */ +}; -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(600))) /***/ }) -/******/ ]); + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/global */ +/******/ (() => { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ })(); +/******/ +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module is referenced by other modules so it can't be inlined +/******/ var __webpack_exports__ = __webpack_require__(92491); +/******/ +/******/ return __webpack_exports__; +/******/ })() +; }); \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.phaser/scripts/phaser.min.js b/source/editor/plugins/phasereditor2d.phaser/scripts/phaser.min.js old mode 100755 new mode 100644 index 27f8768f0..5ac2dd9f4 --- a/source/editor/plugins/phasereditor2d.phaser/scripts/phaser.min.js +++ b/source/editor/plugins/phasereditor2d.phaser/scripts/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()}(this,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(607),AlphaSingle:i(303),BlendMode:i(304),ComputedSize:i(608),Crop:i(609),Depth:i(305),Flip:i(610),GetBounds:i(611),Mask:i(309),Origin:i(632),PathFollower:i(633),Pipeline:i(167),ScrollFactor:i(312),Size:i(634),Texture:i(635),TextureCrop:i(636),Tint:i(637),ToJSON:i(176),Transform:i(313),TransformMatrix:i(25),Visible:i(314)}},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(175),s=i(9),v=i(374),x=i(2),m=i(69),T=i(91),w=i(141),b=i(12),E=i(375),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,this.glReset=!1},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>>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(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(){if(this.state!==h.FILE_POPULATED){this.state=h.FILE_PROCESSING;try{var t=JSON.parse(this.xhrLoader.responseText)}catch(t){throw console.warn("Invalid JSON: "+this.key),this.onProcessError(),t}var 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(39),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,R=m*M-y*C+x*_+T*A-w*S+b*E;return R?(R=1/R,this.setValues((o*M-a*C+h*_)*R,(n*C-i*M-s*_)*R,(p*b-g*w+v*T)*R,(c*w-u*b-d*T)*R,(a*A-r*M-h*S)*R,(e*M-n*A+s*S)*R,(g*x-f*b-v*y)*R,(l*b-c*x+d*y)*R,(r*C-o*A+h*E)*R,(i*A-e*C-s*E)*R,(f*w-p*x+v*m)*R,(u*x-l*w-d*m)*R,(o*S-r*_-a*E)*R,(e*_-i*S+n*E)*R,(p*y-f*T-g*m)*R,(l*T-u*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],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],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+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*R+a*D,h*w+l*A+u*R+c*D,d*w+f*A+p*R+g*D,v*w+m*A+y*R+x*D,s*b+r*_+o*P+a*F,h*b+l*_+u*P+c*F,d*b+f*_+p*P+g*F,v*b+m*_+y*P+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,R=n*s*l-r*a,P=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*R+p*P+y*O,c*R+g*P+x*O,d*R+v*P+T*O,f*R+m*P+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],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+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+R*h+P*d+O*v,M*r+R*l+P*f+O*m,M*o+R*u+P*p+O*y,M*a+R*c+P*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){t.exports={COMPLETE:i(987),DECODED:i(988),DECODED_ALL:i(989),DESTROY:i(990),DETUNE:i(991),GLOBAL_DETUNE:i(992),GLOBAL_MUTE:i(993),GLOBAL_RATE:i(994),GLOBAL_VOLUME:i(995),LOOP:i(996),LOOPED:i(997),MUTE:i(998),PAN:i(999),PAUSE_ALL:i(1e3),PAUSE:i(1001),PLAY:i(1002),RATE:i(1003),RESUME_ALL:i(1004),RESUME:i(1005),SEEK:i(1006),STOP_ALL:i(1007),STOP:i(1008),UNLOCKED:i(1009),VOLUME:i(1010)}},function(t,e,i){var n=i(0),s=i(21),c=i(23),r=i(8),d=i(2),f=i(7),o=new n({Extends:c,initialize:function t(e,i,n,s,r){var o,a,h="png";f(i)&&(i=d(a=i,"key"),n=d(a,"url"),o=d(a,"normalMap"),s=d(a,"xhrSettings"),h=d(a,"extension",h),r=d(a,"frameConfig")),Array.isArray(n)&&(o=n[1],n=n[0]);var l,u={type:"image",cache:e.textureManager,extension:h,responseType:"blob",key:i,url:n,xhrSettings:s,config:r};c.call(this,e,u),o&&((l=new t(e,this.key,o,s,r)).type="normalMap",this.setLink(l),e.addFile(l))},onProcess:function(){this.state=s.FILE_PROCESSING,this.data=new Image,this.data.crossOrigin=this.crossOrigin;var t=this;this.data.onload=function(){c.revokeObjectURL(t.data),t.onProcessComplete()},this.data.onerror=function(){c.revokeObjectURL(t.data),t.onProcessError()},c.createObjectURL(this.data,this.xhrLoader.response,"image/png")},addToCache:function(){var t,e=this.linkFile;e&&e.state===s.FILE_COMPLETE?(t="image"===this.type?this.cache.addImage(this.key,this.data,e.data):this.cache.addImage(e.key,e.data,this.data),this.pendingDestroy(t),e.pendingDestroy(t)):e||(t=this.cache.addImage(this.key,this.data),this.pendingDestroy(t))}});r.register("image",function(t,e,i){if(Array.isArray(t))for(var n=0;n=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){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,i){var n=i(29),s=i(0),r=i(11),o=i(502),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,i){var v={};t.exports=v;var m=i(64),y=i(32),x=i(41),d=i(84),f=i(83),T=i(1393);v.rectangle=function(t,e,i,n,s){s=s||{};var r,o={label:"Rectangle Body",position:{x:t,y:e},vertices:m.fromPath("L 0 0 L "+i+" 0 L "+i+" "+n+" L 0 "+n)};return s.chamfer&&(r=s.chamfer,o.vertices=m.chamfer(o.vertices,r.radius,r.quality,r.qualityMin,r.qualityMax),delete s.chamfer),x.create(y.extend({},o,s))},v.trapezoid=function(t,e,i,n,s,r){r=r||{};var o,a=i*(s*=.5),h=a+(1-2*s)*i,l=h+a,u=s<.5?"L 0 0 L "+a+" "+-n+" L "+h+" "+-n+" L "+l+" 0":"L 0 0 L "+h+" "+-n+" L "+l+" 0",c={label:"Trapezoid Body",position:{x:t,y:e},vertices:m.fromPath(u)};return r.chamfer&&(o=r.chamfer,c.vertices=m.chamfer(c.vertices,o.radius,o.quality,o.qualityMin,o.qualityMax),delete r.chamfer),x.create(y.extend({},c,r))},v.circle=function(t,e,i,n,s){n=n||{};var r={label:"Circle Body",circleRadius:i};s=s||25;var o=Math.ceil(Math.max(10,Math.min(s,i)));return o%2==1&&(o+=1),v.polygon(t,e,o,i,y.extend({},r,n))},v.polygon=function(t,e,i,n,s){if(s=s||{},i<3)return v.circle(t,e,n,s);for(var r=2*Math.PI/i,o="",a=.5*r,h=0;hh||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(208),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)},moveAbove:function(t,e){return s.MoveAbove(this.list,t,e)},moveBelow:function(t,e){return s.MoveBelow(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;ig||p.y>v)},translate:function(t,e){void 0===e&&(e=0);var i=this.vertex1,n=this.vertex2,s=this.vertex3;return i.x+=t,i.y+=e,n.x+=t,n.y+=e,s.x+=t,s.y+=e,this},x:{get:function(){return this.getInCenter().x},set:function(t){var e=this.getInCenter();this.translate(t-e.x,0)}},y:{get:function(){return this.getInCenter().y},set:function(t){var e=this.getInCenter();this.translate(0,t-e.y)}},alpha:{get:function(){var t=this.vertex1,e=this.vertex2,i=this.vertex3;return(t.alpha+e.alpha+i.alpha)/3},set:function(t){this.vertex1.alpha=t,this.vertex2.alpha=t,this.vertex3.alpha=t}},depth:{get:function(){var t=this.vertex1,e=this.vertex2,i=this.vertex3;return(t.vz+e.vz+i.vz)/3}},destroy:function(){this.vertex1=null,this.vertex2=null,this.vertex3=null}});t.exports=o},function(t,e,i){var n=i(0),r=i(12),u=i(39),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){var c={};t.exports=c;var o=i(166),r=i(32),a=i(84),d=i(41);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=this.firstgid&&te.right||t.y>e.bottom)}},function(t,e,i){var l=i(6),u={},n={register:function(t,e,i,n,s){u[t]={plugin:e,mapping:i,settingsKey:n,configKey:s}},getPlugin:function(t){return u[t]},install:function(t){var e=t.scene.sys,i=e.settings.input,n=e.game.config;for(var s in u){var r=u[s].plugin,o=u[s].mapping,a=u[s].settingsKey,h=u[s].configKey;l(i,a,n[h])&&(t[o]=new r(t))}},remove:function(t){u.hasOwnProperty(t)&&delete u[t]}};t.exports=n},function(t,e,i){t.exports={ANY_KEY_DOWN:i(1323),ANY_KEY_UP:i(1324),COMBO_MATCH:i(1325),DOWN:i(1326),KEY_DOWN:i(1327),KEY_UP:i(1328),UP:i(1329)}},function(t,e){t.exports=function(t,e){return!!t.url&&(t.url.match(/^(?:blob:|data:|http:\/\/|https:\/\/|\/\/)/)?t.url:e+t.url)}},function(t,e){t.exports=function(t,e,i,n,s,r){return void 0===t&&(t=""),void 0===e&&(e=!0),void 0===i&&(i=""),void 0===n&&(n=""),void 0===s&&(s=0),void 0===r&&(r=!1),{responseType:t,async:e,user:i,password:n,timeout:s,headers:void 0,header:void 0,headerValue:void 0,requestedWith:!1,overrideMimeType:void 0,withCredentials:r}}},function(t,e,i){var n=i(0),s=i(243),r=i(73),o=new n({Extends:r,Mixins:[s.Acceleration,s.Angular,s.Bounce,s.Debug,s.Drag,s.Enable,s.Friction,s.Gravity,s.Immovable,s.Mass,s.Pushable,s.Size,s.Velocity],initialize:function(t,e,i,n,s){r.call(this,t,e,i,n,s),this.body=null}});t.exports=o},function(t,e,i){var r=i(119);t.exports=function(t,e,i,n){if(void 0===i&&(i=!1),r(t,e,n)){var s=n.data[e][t]||null;return s&&(-1!==s.index||i)?s:null}return null}},function(t,e){t.exports=function(t,e,i,n){var s,r,o,a=t.data,h=t.width,l=t.height,u=t.tilemapLayer,c=Math.max(0,e.left),d=Math.min(h,e.right),f=Math.max(0,e.top),p=Math.min(l,e.bottom);if(0===i)for(r=f;rh.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.isPlaying&&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 u={};t.exports=u;var n=i(166);u._motionWakeThreshold=.18,u._motionSleepThreshold=.08,u._minBias=.9,u.update=function(t,e){for(var i=e*e*e,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(32);n.on=function(t,e,i){for(var n,s=e.split(" "),r=0;r=(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(327),s=i(189),r=i(331),o=i(332);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(103);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(38),s=i(330);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(105),r=i(136),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(){if("function"==typeof importScripts)return a;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(t){void 0===t&&(t=this._eraseMode);var e,i=this.renderer,n=this.renderTarget;return n?(e=i.endCapture(),i.pipelines.setUtility().blitFrame(e,n,1,!1,!1,t),i.resetScissor(),i.resetViewport()):i.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={Bounce:i(1495),Collision:i(1496),Force:i(1497),Friction:i(1498),Gravity:i(1499),Mass:i(1500),Sensor:i(1501),SetBody:i(1502),Sleep:i(1503),Static:i(1520),Transform:i(1521),Velocity:i(1522)}},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;at&&(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(185),s=i(0),r=i(102),o=i(9),a=i(132),h=i(22),T=i(2),d=i(6),f=i(186),p=i(322),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(38);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(38);t.exports=function(t){return new n(t.r,t.g,t.b,t.a)}},function(t,e,i){var a=i(38);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(33),l=i(347),u=i(2),c=i(6),d=i(7),f=i(193),p=i(1),g=i(197),v=i(187),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.domPointerEvents=c(t,"dom.pointerEvents","none"),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.preserveDrawingBuffer=c(i,"preserveDrawingBuffer",!1),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(105),browser:i(136),features:i(191),input:i(808),audio:i(809),video:i(810),fullscreen:i(811),canvasFeatures:i(348)}},function(t,e,i){var n,s,r,o=i(31),a={supportInverseAlpha:!1,supportNewBlendModes:!1};t.exports=("function"!=typeof importScripts&&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(367),l=a(31),u=a(33),c=a(191);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(368),n=a(371),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(37),u=i(369),n=i(0),s=i(33),r=i(9),f=i(91),o=i(370),a=i(104),h=i(106),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(38),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(389),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(146),s=i(0),r=i(70),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(137),r=i(80),o=i(2),a=i(68),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(1100),r=i(59),o=i(10),a=i(34),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&&r(this.lights,e),this},shutdown:function(){this.lights.length=0},destroy:function(){this.shutdown()}});t.exports=d},function(t,e,i){var n=i(56),s=i(17)(!1,s={Circle:i(1191),Ellipse:i(1201),Intersects:i(484),Line:i(1221),Mesh:i(1243),Point:i(1246),Polygon:i(1260),Rectangle:i(502),Triangle:i(1293)},n);t.exports=s},function(t,e,i){t.exports={CircleToCircle:i(231),CircleToRectangle:i(151),GetCircleToCircle:i(1211),GetCircleToRectangle:i(1212),GetLineToCircle:i(232),GetLineToLine:i(485),GetLineToPoints:i(486),GetLineToPolygon:i(487),GetLineToRectangle:i(234),GetRaysFromPointToPolygon:i(1213),GetRectangleIntersection:i(1214),GetRectangleToRectangle:i(1215),GetRectangleToTriangle:i(1216),GetTriangleToCircle:i(1217),GetTriangleToLine:i(492),GetTriangleToTriangle:i(1218),LineToCircle:i(233),LineToLine:i(96),LineToRectangle:i(488),PointToLine:i(496),PointToLineSegment:i(1219),RectangleToRectangle:i(152),RectangleToTriangle:i(489),RectangleToValues:i(1220),TriangleToCircle:i(491),TriangleToLine:i(493),TriangleToTriangle:i(494)}},function(t,e,i){var g=i(39);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(509),h=i(510),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=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,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(260),p=i(572),g=i(161);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(122),b=i(576),E=i(260),S=i(1453);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(120),f=i(85);t.exports=function(t,e){for(var i=[],n=0;n=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(118),r=(i(128),i(32));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(250),n=i(273),r=i(32);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=U.clamp(u.friction*R*i,-D,D));var F,k,I=X.cross(w,p),B=X.cross(b,p),N=m/(d.inverseMass+f.inverseMass+d.inverseInertia*I*I+f.inverseInertia*B*B);P*=N,L*=N,_<0&&_*_>Y._restingThresh*i?x.normalImpulse=0:(F=x.normalImpulse,x.normalImpulse=Math.min(x.normalImpulse+P,0),P=x.normalImpulse-F),C*C>Y._restingThreshTangent*i?x.tangentImpulse=0:(k=x.tangentImpulse,x.tangentImpulse=U.clamp(x.tangentImpulse+L,-D,D),L=x.tangentImpulse-k),n.x=p.x*P+g.x*L,n.y=p.y*P+g.y*L,d.isStatic||d.isSleeping||(d.positionPrev.x+=n.x*d.inverseMass,d.positionPrev.y+=n.y*d.inverseMass,d.anglePrev+=X.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-=X.cross(b,n)*f.inverseInertia)}}}}},function(t,e){var i=function(){return this}();try{i=i||new Function("return this")()}catch(t){"object"==typeof window&&(i=window)}t.exports=i},function(t,e,i){var a=i(276);t.exports=function(t,e,i,n){for(var s=t[0],r=1;rthis.maxZoom&&(e.zoom=this.maxZoom)))},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){var n=i(0),s=i(6),r=new n({initialize:function(t){this.camera=s(t,"camera",null),this.left=s(t,"left",null),this.right=s(t,"right",null),this.up=s(t,"up",null),this.down=s(t,"down",null),this.zoomIn=s(t,"zoomIn",null),this.zoomOut=s(t,"zoomOut",null),this.zoomSpeed=s(t,"zoomSpeed",.01),this.minZoom=s(t,"minZoom",.001),this.maxZoom=s(t,"maxZoom",1e3),this.accelX=0,this.accelY=0;var e=s(t,"acceleration",null);"number"==typeof e?(this.accelX=e,this.accelY=e):(this.accelX=s(t,"acceleration.x",0),this.accelY=s(t,"acceleration.y",0)),this.dragX=0,this.dragY=0;var i=s(t,"drag",null);"number"==typeof i?(this.dragX=i,this.dragY=i):(this.dragX=s(t,"drag.x",0),this.dragY=s(t,"drag.y",0)),this.maxSpeedX=0,this.maxSpeedY=0;var n=s(t,"maxSpeed",null);"number"==typeof n?(this.maxSpeedX=n,this.maxSpeedY=n):(this.maxSpeedX=s(t,"maxSpeed.x",0),this.maxSpeedY=s(t,"maxSpeed.y",0)),this._speedX=0,this._speedY=0,this._zoom=0,this.active=null!==this.camera},start:function(){return this.active=null!==this.camera,this},stop:function(){return this.active=!1,this},setCamera:function(t){return this.camera=t,this},update:function(t){var e;this.active&&(void 0===t&&(t=1),e=this.camera,0this.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.zoomthis.maxZoom&&(e.zoom=this.maxZoom)))},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(326),BaseCamera:i(133),CameraManager:i(799),Effects:i(333),Events:i(37)}},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(37),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(137);t.exports=function(){return n(-Math.PI,Math.PI)}},function(t,e,i){var n=i(137);t.exports=function(){return n(-180,180)}},function(t,e,i){var n=i(351);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(388),Palettes:i(889)}},function(t,e,i){t.exports={ARNE16:i(389),C64:i(890),CGA:i(891),JMP:i(892),MSX:i(893)}},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(895),MoveTo:i(393),CubicBezier:i(390),Curve:i(94),Ellipse:i(391),Line:i(392),QuadraticBezier:i(394),Spline:i(395)}},function(t,e,i){var n=i(0),u=i(390),l=i(391),s=i(5),r=i(392),o=i(393),a=i(394),h=i(10),c=i(395),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(38),l=i(399);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(188);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(135);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(195),s=i(38);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(398);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,7):"0x"+r(n)+r(t)+r(e)+r(i)}},function(t,e,i){t.exports={BitmapMask:i(310),GeometryMask:i(311)}},function(t,e,i){var n={AddToDOM:i(142),DOMContentLoaded:i(400),GetInnerHeight:i(401),GetScreenOrientation:i(402),GetTarget:i(407),ParseXML:i(408),RemoveFromDOM:i(202),RequestAnimationFrame:i(386)};t.exports=n},function(t,e,i){t.exports={EventEmitter:i(919)}},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(142),s=i(321),r=i(325),o=i(31),a=i(0),h=i(346),l=i(921),u=i(366),c=i(101),d=i(384),f=i(347),p=i(400),g=i(9),v=i(22),m=i(409),y=i(24),x=i(414),T=i(415),w=i(417),b=i(106),E=i(422),S=i(385),A=i(387),_=i(426),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(142);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: "+i.domPointerEvents+";","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 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),l=h.cutX,u=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:{}},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(190);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(152);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(36);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;ri[e][0])&&(e=n);return!S(R(t,e-1),R(t,e),R(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 R(t,e){var i=t.length;return t[e<0?e%i+i:e%i]}function P(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;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(438),List:i(110),Map:i(102),ProcessQueue:i(211),RTree:i(531),Set:i(149),Size:i(416)}},function(t,e,i){var n=i(17),s=i(1417),r=n(!1,r={CanvasTexture:i(423),Events:i(106),FilterMode:s,Frame:i(109),Parsers:i(425),Texture:i(206),TextureManager:i(422),TextureSource:i(424)},s);t.exports=r},function(t,e){t.exports={LINEAR:0,NEAREST:1}},function(t,e,i){var n=i(17),s=i(1419),r=n(!1,r={Components:i(251),Parsers:i(1452),Formats:i(40),ImageCollection:i(576),ParseToTilemap:i(262),Tile:i(85),Tilemap:i(580),TilemapCreator:i(1459),TilemapFactory:i(1460),Tileset:i(122),TilemapLayer:i(581),Orientation:i(29),LayerData:i(120),MapData:i(121),ObjectLayer:i(572)},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(63);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(63),l=i(160);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(175),Extend:i(17),GetAdvancedValue:i(13),GetFastValue:i(2),GetMinMaxValue:i(1485),GetValue:i(6),HasAll:i(1486),HasAny:i(455),HasValue:i(126),IsPlainObject:i(7),Merge:i(127),MergeRight:i(1487),Pick:i(571),SetValue:i(478)}},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;ie.max.x?i=e.min.x-t.max.x:t.max.xe.max.y?n=e.min.y-t.max.y:t.max.y(()=>{var t={6659:t=>{"use strict";var e=Object.prototype.hasOwnProperty,i="~";function s(){}function n(t,e,i){this.fn=t,this.context=e,this.once=i||!1}function r(t,e,s,r,o){if("function"!=typeof s)throw new TypeError("The listener must be a function");var a=new n(s,r||t,o),h=i?i+e:e;return t._events[h]?t._events[h].fn?t._events[h]=[t._events[h],a]:t._events[h].push(a):(t._events[h]=a,t._eventsCount++),t}function o(t,e){0==--t._eventsCount?t._events=new s:delete t._events[e]}function a(){this._events=new s,this._eventsCount=0}Object.create&&(s.prototype=Object.create(null),(new s).__proto__||(i=!1)),a.prototype.eventNames=function(){var t,s,n=[];if(0===this._eventsCount)return n;for(s in t=this._events)e.call(t,s)&&n.push(i?s.slice(1):s);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(t)):n},a.prototype.listeners=function(t){var e=i?i+t:t,s=this._events[e];if(!s)return[];if(s.fn)return[s.fn];for(var n=0,r=s.length,o=new Array(r);n{var s=i(82590);t.exports=function(t,e,i,n){for(var r=t[0],o=1;o{var s=i(6124);t.exports=function(t,e,i,n,r){return s(t,"angle",e,i,n,r)}},22015:t=>{t.exports=function(t,e,i){for(var s=0;s{t.exports=function(t,e,i){void 0===i&&(i=0);for(var s=i;s{t.exports=function(t,e,i){void 0===i&&(i=0);for(var s=i;s{var s=i(40327),n=i(84093),r=i(72632),o=i(72283),a=new(i(71030))({sys:{queueDepthSort:o,events:{once:o}}},0,0,1,1).setOrigin(0,0);t.exports=function(t,e){void 0===e&&(e={});var i=e.hasOwnProperty("width"),o=e.hasOwnProperty("height"),h=r(e,"width",-1),l=r(e,"height",-1),u=r(e,"cellWidth",1),c=r(e,"cellHeight",u),d=r(e,"position",n.TOP_LEFT),f=r(e,"x",0),p=r(e,"y",0),v=0,g=0,m=h*u,y=l*c;a.setPosition(f,p),a.setSize(u,c);for(var x=0;x{var s=i(6124);t.exports=function(t,e,i,n,r){return s(t,"alpha",e,i,n,r)}},3877:(t,e,i)=>{var s=i(6124);t.exports=function(t,e,i,n,r){return s(t,"x",e,i,n,r)}},71020:(t,e,i)=>{var s=i(6124);t.exports=function(t,e,i,n,r,o,a){return null==i&&(i=e),s(t,"x",e,n,o,a),s(t,"y",i,r,o,a)}},28970:(t,e,i)=>{var s=i(6124);t.exports=function(t,e,i,n,r){return s(t,"y",e,i,n,r)}},82249:t=>{t.exports=function(t,e,i,s){void 0===i&&(i=0),void 0===s&&(s=6.28);for(var n=i,r=(s-i)/t.length,o=e.x,a=e.y,h=e.radius,l=0;l{t.exports=function(t,e,i,s){void 0===i&&(i=0),void 0===s&&(s=6.28);for(var n=i,r=(s-i)/t.length,o=e.width/2,a=e.height/2,h=0;h{var s=i(8570);t.exports=function(t,e){for(var i=s(e,t.length),n=0;n{var s=i(40053),n=i(77640),r=i(38487);t.exports=function(t,e,i){void 0===i&&(i=0);var o=s(e,!1,t.length);i>0?n(o,i):i<0&&r(o,Math.abs(i));for(var a=0;a{var s=i(58813);t.exports=function(t,e,i){var n=s({x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2},i),r=s({x1:e.x2,y1:e.y2,x2:e.x3,y2:e.y3},i),o=s({x1:e.x3,y1:e.y3,x2:e.x1,y2:e.y1},i);n.pop(),r.pop(),o.pop();for(var a=(n=n.concat(r,o)).length/t.length,h=0,l=0;l{t.exports=function(t,e,i){for(var s=0;s{t.exports=function(t,e,i,s,n,r){var o;void 0===s&&(s=0),void 0===n&&(n=0),void 0===r&&(r=1);var a=0,h=t.length;if(1===r)for(o=n;o=0;o--)t[o][e]+=i+a*s,a++;return t}},23646:t=>{t.exports=function(t,e,i,s,n,r){var o;void 0===s&&(s=0),void 0===n&&(n=0),void 0===r&&(r=1);var a=0,h=t.length;if(1===r)for(o=n;o=0;o--)t[o][e]=i+a*s,a++;return t}},4392:(t,e,i)=>{var s=i(30977);t.exports=function(t,e){for(var i=0;i{var s=i(72006);t.exports=function(t,e){for(var i=0;i{var s=i(74077);t.exports=function(t,e){for(var i=0;i{var s=i(30001);t.exports=function(t,e){for(var i=0;i{var s=i(99761);t.exports=function(t,e){for(var i=0;i{var s=i(6124);t.exports=function(t,e,i,n,r){return s(t,"rotation",e,i,n,r)}},87299:(t,e,i)=>{var s=i(72395),n=i(53996);t.exports=function(t,e,i){for(var r=e.x,o=e.y,a=0;a{var s=i(72395);t.exports=function(t,e,i,n){var r=e.x,o=e.y;if(0===n)return t;for(var a=0;a{var s=i(6124);t.exports=function(t,e,i,n,r){return s(t,"scaleX",e,i,n,r)}},51449:(t,e,i)=>{var s=i(6124);t.exports=function(t,e,i,n,r,o,a){return null==i&&(i=e),s(t,"scaleX",e,n,o,a),s(t,"scaleY",i,r,o,a)}},64895:(t,e,i)=>{var s=i(6124);t.exports=function(t,e,i,n,r){return s(t,"scaleY",e,i,n,r)}},30329:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r){return s(t,"alpha",e,i,n,r)}},43954:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n){return s(t,"blendMode",e,0,i,n)}},70688:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r){return s(t,"depth",e,i,n,r)}},8314:t=>{t.exports=function(t,e,i){for(var s=0;s{var s=i(23646);t.exports=function(t,e,i,n,r,o,a){return null==i&&(i=e),s(t,"originX",e,n,o,a),s(t,"originY",i,r,o,a),t.forEach((function(t){t.updateDisplayOrigin()})),t}},38767:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r){return s(t,"rotation",e,i,n,r)}},18584:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r,o,a){return null==i&&(i=e),s(t,"scaleX",e,n,o,a),s(t,"scaleY",i,r,o,a)}},17381:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r){return s(t,"scaleX",e,i,n,r)}},74370:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r){return s(t,"scaleY",e,i,n,r)}},27773:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r,o,a){return null==i&&(i=e),s(t,"scrollFactorX",e,n,o,a),s(t,"scrollFactorY",i,r,o,a)}},75257:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r){return s(t,"scrollFactorX",e,i,n,r)}},54512:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r){return s(t,"scrollFactorY",e,i,n,r)}},69423:t=>{t.exports=function(t,e,i,s,n){for(var r=0;r{var s=i(23646);t.exports=function(t,e,i,n){return s(t,"visible",e,0,i,n)}},94833:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r){return s(t,"x",e,i,n,r)}},14284:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r,o,a){return null==i&&(i=e),s(t,"x",e,n,o,a),s(t,"y",i,r,o,a)}},96574:(t,e,i)=>{var s=i(23646);t.exports=function(t,e,i,n,r){return s(t,"y",e,i,n,r)}},74086:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n,r){var o,a;void 0===n&&(n=0),void 0===r&&(r=new s);var h=t.length;if(1===h)o=t[0].x,a=t[0].y,t[0].x=e,t[0].y=i;else{var l=1,u=0;0===n&&(u=h-1,l=h-2),o=t[u].x,a=t[u].y,t[u].x=e,t[u].y=i;for(var c=0;c=h||-1===l)){var d=t[l],f=d.x,p=d.y;d.x=o,d.y=a,o=f,a=p,0===n?l--:l++}}return r.x=o,r.y=a,r}},86347:(t,e,i)=>{var s=i(18592);t.exports=function(t){return s(t)}},1558:(t,e,i)=>{var s=i(5514);t.exports=function(t,e,i,n,r){void 0===r&&(r=!1);var o,a=Math.abs(n-i)/t.length;if(r)for(o=0;o{var s=i(87736);t.exports=function(t,e,i,n,r){void 0===r&&(r=!1);var o,a=Math.abs(n-i)/t.length;if(r)for(o=0;o{t.exports=function(t,e,i,s,n){if(void 0===n&&(n=!1),0===t.length)return t;if(1===t.length)return n?t[0][e]+=(s+i)/2:t[0][e]=(s+i)/2,t;var r,o=Math.abs(s-i)/(t.length-1);if(n)for(r=0;r{t.exports=function(t){for(var e=0;e{var s=i(1071);t.exports=function(t,e,i){void 0===i&&(i=0);for(var n=0;n{t.exports={AlignTo:i(62270),Angle:i(61148),Call:i(22015),GetFirst:i(31060),GetLast:i(52367),GridAlign:i(12673),IncAlpha:i(691),IncX:i(3877),IncXY:i(71020),IncY:i(28970),PlaceOnCircle:i(82249),PlaceOnEllipse:i(30285),PlaceOnLine:i(61557),PlaceOnRectangle:i(63549),PlaceOnTriangle:i(51629),PlayAnimation:i(1045),PropertyValueInc:i(6124),PropertyValueSet:i(23646),RandomCircle:i(4392),RandomEllipse:i(94985),RandomLine:i(63305),RandomRectangle:i(90739),RandomTriangle:i(91417),Rotate:i(26182),RotateAround:i(87299),RotateAroundDistance:i(92194),ScaleX:i(30363),ScaleXY:i(51449),ScaleY:i(64895),SetAlpha:i(30329),SetBlendMode:i(43954),SetDepth:i(70688),SetHitArea:i(8314),SetOrigin:i(12894),SetRotation:i(38767),SetScale:i(18584),SetScaleX:i(17381),SetScaleY:i(74370),SetScrollFactor:i(27773),SetScrollFactorX:i(75257),SetScrollFactorY:i(54512),SetTint:i(69423),SetVisible:i(58291),SetX:i(94833),SetXY:i(14284),SetY:i(96574),ShiftPosition:i(74086),Shuffle:i(86347),SmootherStep:i(9938),SmoothStep:i(1558),Spread:i(71060),ToggleVisible:i(11207),WrapInRectangle:i(24404)}},85463:(t,e,i)=>{var s=i(82897),n=i(56694),r=i(16938),o=i(2406),a=i(71519),h=i(10850),l=i(28834),u=new n({initialize:function(t,e,i){this.manager=t,this.key=e,this.type="frame",this.frames=this.getFrames(t.textureManager,h(i,"frames",[]),h(i,"defaultTextureKey",null),h(i,"sortFrames",!0)),this.frameRate=h(i,"frameRate",null),this.duration=h(i,"duration",null),this.msPerFrame,this.skipMissedFrames=h(i,"skipMissedFrames",!0),this.delay=h(i,"delay",0),this.repeat=h(i,"repeat",0),this.repeatDelay=h(i,"repeatDelay",0),this.yoyo=h(i,"yoyo",!1),this.showBeforeDelay=h(i,"showBeforeDelay",!1),this.showOnStart=h(i,"showOnStart",!1),this.hideOnComplete=h(i,"hideOnComplete",!1),this.paused=!1,this.calculateDuration(this,this.getTotalFrames(),this.duration,this.frameRate),this.manager.on&&(this.manager.on(r.PAUSE_ALL,this.pause,this),this.manager.on(r.RESUME_ALL,this.resume,this))},getTotalFrames:function(){return this.frames.length},calculateDuration:function(t,e,i,s){null===i&&null===s?(t.frameRate=24,t.duration=24/e*1e3):i&&null===s?(t.duration=i,t.frameRate=e/(i/1e3)):(t.frameRate=s,t.duration=e/s*1e3),t.msPerFrame=1e3/t.frameRate},addFrame:function(t){return this.addFrameAt(this.frames.length,t)},addFrameAt:function(t,e){var i=this.getFrames(this.manager.textureManager,e);if(i.length>0){if(0===t)this.frames=i.concat(this.frames);else if(t===this.frames.length)this.frames=this.frames.concat(i);else{var s=this.frames.slice(0,t),n=this.frames.slice(t);this.frames=s.concat(i,n)}this.updateFrameSequence()}return this},checkFrame:function(t){return t>=0&&t0){r.isLast=!0,r.nextFrame=c[0],c[0].prevFrame=r;var y=1/(c.length-1);for(o=0;o0?t.inReverse&&t.forward?t.forward=!1:this.repeatAnimation(t):t.complete():this.updateAndGetNextTick(t,e.nextFrame)},handleYoyoFrame:function(t,e){if(e||(e=!1),t.inReverse===!e&&t.repeatCounter>0)return(0===t.repeatDelay||t.pendingRepeat)&&(t.forward=e),void this.repeatAnimation(t);if(t.inReverse===e||0!==t.repeatCounter){t.forward=e;var i=e?t.currentFrame.nextFrame:t.currentFrame.prevFrame;this.updateAndGetNextTick(t,i)}else t.complete()},getLastFrame:function(){return this.frames[this.frames.length-1]},previousFrame:function(t){var e=t.currentFrame;e.isFirst?t.yoyo?this.handleYoyoFrame(t,!0):t.repeatCounter>0?(t.inReverse&&!t.forward||(t.forward=!0),this.repeatAnimation(t)):t.complete():this.updateAndGetNextTick(t,e.prevFrame)},updateAndGetNextTick:function(t,e){t.setCurrentFrame(e),this.getNextTick(t)},removeFrame:function(t){var e=this.frames.indexOf(t);return-1!==e&&this.removeFrameAt(e),this},removeFrameAt:function(t){return this.frames.splice(t,1),this.updateFrameSequence(),this},repeatAnimation:function(t){if(2===t._pendingStop){if(0===t._pendingStopValue)return t.stop();t._pendingStopValue--}t.repeatDelay>0&&!t.pendingRepeat?(t.pendingRepeat=!0,t.accumulator-=t.nextTick,t.nextTick+=t.repeatDelay):(t.repeatCounter--,t.forward?t.setCurrentFrame(t.currentFrame.nextFrame):t.setCurrentFrame(t.currentFrame.prevFrame),t.isPlaying&&(this.getNextTick(t),t.handleRepeat()))},toJSON:function(){var t={key:this.key,type:this.type,frames:[],frameRate:this.frameRate,duration:this.duration,skipMissedFrames:this.skipMissedFrames,delay:this.delay,repeat:this.repeat,repeatDelay:this.repeatDelay,yoyo:this.yoyo,showBeforeDelay:this.showBeforeDelay,showOnStart:this.showOnStart,hideOnComplete:this.hideOnComplete};return this.frames.forEach((function(e){t.frames.push(e.toJSON())})),t},updateFrameSequence:function(){for(var t,e=this.frames.length,i=1/(e-1),s=0;s1?(t.isLast=!0,t.prevFrame=this.frames[e-2],t.nextFrame=this.frames[0]):e>1&&(t.prevFrame=this.frames[s-1],t.nextFrame=this.frames[s+1]);return this},pause:function(){return this.paused=!0,this},resume:function(){return this.paused=!1,this},destroy:function(){this.manager.off&&(this.manager.off(r.PAUSE_ALL,this.pause,this),this.manager.off(r.RESUME_ALL,this.resume,this)),this.manager.remove(this.key);for(var t=0;t{var s=new(i(56694))({initialize:function(t,e,i,s,n){void 0===n&&(n=!1),this.textureKey=t,this.textureFrame=e,this.index=i,this.frame=s,this.isFirst=!1,this.isLast=!1,this.prevFrame=null,this.nextFrame=null,this.duration=0,this.progress=0,this.isKeyFrame=n},toJSON:function(){return{key:this.textureKey,frame:this.textureFrame,duration:this.duration,keyframe:this.isKeyFrame}},destroy:function(){this.frame=void 0}});t.exports=s},90249:(t,e,i)=>{var s=i(85463),n=i(56694),r=i(33885),o=i(6659),a=i(16938),h=i(97081),l=i(72632),u=i(10850),c=i(83392),d=i(13401),f=i(76400),p=new n({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 s=this.anims,n=this.mixes,r="string"==typeof t?t:t.key,o="string"==typeof e?e:e.key;if(s.has(r)&&s.has(o)){var a=n.get(r);a||(a={}),a[o]=i,n.set(r,a)}return this},removeMix:function(t,e){var i=this.mixes,s="string"==typeof t?t:t.key,n=i.get(s);if(n)if(e){var r="string"==typeof e?e:e.key;n.hasOwnProperty(r)&&delete n[r]}else e||i.delete(s);return this},getMix:function(t,e){var i=this.mixes,s="string"==typeof t?t:t.key,n="string"==typeof e?e:e.key,r=i.get(s);return r&&r.hasOwnProperty(n)?r[n]:0},add:function(t,e){return this.anims.has(t)?(console.warn("Animation key exists: "+t),this):(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(t,e,i){var s=[],n=this.game.cache.json.get(t);if(!n)return console.warn("No Aseprite data found for: "+t),s;var r=this,o=u(n,"meta",null),a=u(n,"frames",null);o&&a&&u(o,"frameTags",[]).forEach((function(n){var o=[],h=l(n,"name",null),u=l(n,"from",0),d=l(n,"to",0),f=l(n,"direction","forward");if(h&&(!e||e&&e.indexOf(h)>-1)){for(var p=0,v=u;v<=d;v++){var g=v.toString(),m=a[g];if(m){var y=l(m,"duration",c.MAX_SAFE_INTEGER);o.push({key:t,frame:g,duration:y}),p+=y}}var x=p/o.length;o.forEach((function(t){t.duration-=x})),"reverse"===f&&(o=o.reverse());var T,w={key:h,frames:o,duration:p,yoyo:"pingpong"===f};i?i.anims&&(T=i.anims.create(w)):T=r.create(w),T&&s.push(T)}}));return s},create:function(t){var e=t.key,i=!1;return e&&((i=this.get(e))?console.warn("AnimationManager key already exists: "+e):(i=new s(this,e,t),this.anims.set(e,i),this.emit(a.ADD_ANIMATION,e,i))),i},fromJSON:function(t,e){void 0===e&&(e=!1),e&&this.anims.clear(),"string"==typeof t&&(t=JSON.parse(t));var i=[];if(t.hasOwnProperty("anims")&&Array.isArray(t.anims)){for(var s=0;s{var s=i(56694),n=i(33885),r=i(72632),o=i(16938),a=i(85463),h=new s({initialize:function(t){this.parent=t,this.animationManager=t.scene.sys.anims,this.animationManager.on(o.REMOVE_ANIMATION,this.globalRemove,this),this.textureManager=this.animationManager.textureManager,this.anims=null,this.isPlaying=!1,this.hasStarted=!1,this.currentAnim=null,this.currentFrame=null,this.nextAnim=null,this.nextAnimsQueue=[],this.timeScale=1,this.frameRate=0,this.duration=0,this.msPerFrame=0,this.skipMissedFrames=!0,this.delay=0,this.repeat=0,this.repeatDelay=0,this.yoyo=!1,this.showBeforeDelay=!1,this.showOnStart=!1,this.hideOnComplete=!1,this.forward=!0,this.inReverse=!1,this.accumulator=0,this.nextTick=0,this.delayCounter=0,this.repeatCounter=0,this.pendingRepeat=!1,this._paused=!1,this._wasPlaying=!1,this._pendingStop=0,this._pendingStopValue},chain:function(t){var e=this.parent;if(void 0===t)return this.nextAnimsQueue.length=0,this.nextAnim=null,e;Array.isArray(t)||(t=[t]);for(var i=0;is.getTotalFrames()&&(h=0);var l=s.frames[h];0!==h||this.forward||(l=s.getLastFrame()),this.currentFrame=l}else console.warn("Missing animation: "+i);return 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){if(this.isPlaying){var i=this.nextAnim,s=this.nextAnimsQueue;i&&s.unshift(i),this.nextAnim=t,this._pendingStop=1,this._pendingStopValue=e}else this.delayCounter=e,this.play(t,!0);return this.parent},playAfterRepeat:function(t,e){if(void 0===e&&(e=1),this.isPlaying){var i=this.nextAnim,s=this.nextAnimsQueue;i&&s.unshift(i),-1!==this.repeatCounter&&e>this.repeatCounter&&(e=this.repeatCounter),this.nextAnim=t,this._pendingStop=2,this._pendingStopValue=e}else this.play(t);return this.parent},play:function(t,e){void 0===e&&(e=!1);var i=this.currentAnim,s=this.parent,n="string"==typeof t?t:t.key;if(e&&this.isPlaying&&i.key===n)return s;if(i&&this.isPlaying){var r=this.animationManager.getMix(i.key,t);if(r>0)return this.playAfterDelay(t,r)}return this.forward=!0,this.inReverse=!1,this._paused=!1,this._wasPlaying=!0,this.startAnimation(t)},playReverse:function(t,e){void 0===e&&(e=!1);var i="string"==typeof t?t:t.key;return e&&this.isPlaying&&this.currentAnim.key===i?this.parent:(this.forward=!1,this.inReverse=!0,this._paused=!1,this._wasPlaying=!0,this.startAnimation(t))},startAnimation:function(t){this.load(t);var e=this.currentAnim,i=this.parent;return e?(this.repeatCounter=-1===this.repeat?Number.MAX_VALUE:this.repeat,e.getFirstTick(this),this.isPlaying=!0,this.pendingRepeat=!1,this.hasStarted=!1,this._pendingStop=0,this._pendingStopValue=0,this._paused=!1,this.delayCounter+=this.delay,0===this.delayCounter?this.handleStart():this.showBeforeDelay&&this.setCurrentFrame(this.currentFrame),i):i},handleStart:function(){this.showOnStart&&this.parent.setVisible(!0),this.setCurrentFrame(this.currentFrame),this.hasStarted=!0,this.emitEvents(o.ANIMATION_START)},handleRepeat:function(){this.pendingRepeat=!1,this.emitEvents(o.ANIMATION_REPEAT)},handleStop:function(){this._pendingStop=0,this.isPlaying=!1,this.emitEvents(o.ANIMATION_STOP)},handleComplete:function(){this._pendingStop=0,this.isPlaying=!1,this.hideOnComplete&&this.parent.setVisible(!1),this.emitEvents(o.ANIMATION_COMPLETE,o.ANIMATION_COMPLETE_KEY)},emitEvents:function(t,e){var i=this.currentAnim;if(i){var s=this.currentFrame,n=this.parent,r=s.textureFrame;n.emit(t,i,s,n,r),e&&n.emit(e+i.key,i,s,n,r)}},reverse:function(){return this.isPlaying&&(this.inReverse=!this.inReverse,this.forward=!this.forward),this.parent},getProgress:function(){var t=this.currentFrame;if(!t)return 0;var e=t.progress;return this.inReverse&&(e*=-1),e},setProgress:function(t){return this.forward||(t=1-t),this.setCurrentFrame(this.currentAnim.getFrameByProgress(t)),this.parent},setRepeat:function(t){return this.repeatCounter=-1===t?Number.MAX_VALUE:t,this.parent},globalRemove:function(t,e){void 0===e&&(e=this.currentAnim),this.isPlaying&&e.key===this.currentAnim.key&&(this.stop(),this.setCurrentFrame(this.currentAnim.frames[0]))},restart:function(t,e){void 0===t&&(t=!1),void 0===e&&(e=!1);var i=this.currentAnim,s=this.parent;return i?(e&&(this.repeatCounter=-1===this.repeat?Number.MAX_VALUE:this.repeat),i.getFirstTick(this),this.emitEvents(o.ANIMATION_RESTART),this.isPlaying=!0,this.pendingRepeat=!1,this.hasStarted=!t,this._pendingStop=0,this._pendingStopValue=0,this._paused=!1,this.setCurrentFrame(i.frames[0]),this.parent):s},complete:function(){if(this._pendingStop=0,this.isPlaying=!1,this.currentAnim&&this.handleComplete(),this.nextAnim){var t=this.nextAnim;this.nextAnim=this.nextAnimsQueue.length>0?this.nextAnimsQueue.shift():null,this.play(t)}return this.parent},stop:function(){if(this._pendingStop=0,this.isPlaying=!1,this.delayCounter=0,this.currentAnim&&this.handleStop(),this.nextAnim){var t=this.nextAnim;this.nextAnim=this.nextAnimsQueue.shift(),this.play(t)}return this.parent},stopAfterDelay:function(t){return this._pendingStop=1,this._pendingStopValue=t,this.parent},stopAfterRepeat:function(t){return void 0===t&&(t=1),-1!==this.repeatCounter&&t>this.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)){var s=0;do{this.forward?i.nextFrame(this):i.previousFrame(this),s++}while(this.isPlaying&&this.accumulator>this.nextTick&&s<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(o.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))?console.warn("Animation key already exists: "+e):(i=new a(this,e,t),this.anims||(this.anims=new n),this.anims.set(e,i))),i},createFromAseprite:function(t,e){return this.animationManager.createFromAseprite(t,e,this.parent)},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(o.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=h},44509:t=>{t.exports="add"},84563:t=>{t.exports="animationcomplete"},61586:t=>{t.exports="animationcomplete-"},72175:t=>{t.exports="animationrepeat"},568:t=>{t.exports="animationrestart"},37690:t=>{t.exports="animationstart"},58525:t=>{t.exports="animationstop"},5243:t=>{t.exports="animationupdate"},10598:t=>{t.exports="pauseall"},4860:t=>{t.exports="remove"},31865:t=>{t.exports="resumeall"},16938:(t,e,i)=>{t.exports={ADD_ANIMATION:i(44509),ANIMATION_COMPLETE:i(84563),ANIMATION_COMPLETE_KEY:i(61586),ANIMATION_REPEAT:i(72175),ANIMATION_RESTART:i(568),ANIMATION_START:i(37690),ANIMATION_STOP:i(58525),ANIMATION_UPDATE:i(5243),PAUSE_ALL:i(10598),REMOVE_ANIMATION:i(4860),RESUME_ALL:i(31865)}},13517:(t,e,i)=>{t.exports={Animation:i(85463),AnimationFrame:i(71519),AnimationManager:i(90249),AnimationState:i(16569),Events:i(16938)}},23740:(t,e,i)=>{var s=i(56694),n=i(33885),r=i(6659),o=i(69773),a=new s({initialize:function(){this.entries=new n,this.events=new r},add:function(t,e){return this.entries.set(t,e),this.events.emit(o.ADD,this,t,e),this},has:function(t){return this.entries.has(t)},exists:function(t){return this.entries.has(t)},get:function(t){return this.entries.get(t)},remove:function(t){var e=this.get(t);return e&&(this.entries.delete(t),this.events.emit(o.REMOVE,this,t,e.data)),this},getKeys:function(){return this.entries.keys()},destroy:function(){this.entries.clear(),this.events.removeAllListeners(),this.entries=null,this.events=null}});t.exports=a},43474:(t,e,i)=>{var s=i(23740),n=i(56694),r=i(97081),o=new n({initialize:function(t){this.game=t,this.binary=new s,this.bitmapFont=new s,this.json=new s,this.physics=new s,this.shader=new s,this.audio=new s,this.video=new s,this.text=new s,this.html=new s,this.obj=new s,this.tilemap=new s,this.xml=new s,this.custom={},this.game.events.once(r.DESTROY,this.destroy,this)},addCustom:function(t){return this.custom.hasOwnProperty(t)||(this.custom[t]=new s),this.custom[t]},destroy:function(){for(var t=["binary","bitmapFont","json","physics","shader","audio","video","text","html","obj","tilemap","xml"],e=0;e{t.exports="add"},75968:t=>{t.exports="remove"},69773:(t,e,i)=>{t.exports={ADD:i(94762),REMOVE:i(75968)}},45820:(t,e,i)=>{t.exports={BaseCache:i(23740),CacheManager:i(43474),Events:i(69773)}},51052:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(75606),o=i(6659),a=i(89787),h=i(74118),l=i(69360),u=i(93222),c=i(93736),d=new s({Extends:o,Mixins:[n.AlphaSingle,n.Visible],initialize:function(t,e,i,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=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=s,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 c(i/2,s/2),this.originX=.5,this.originY=.5,this._customViewport=!1,this.mask=null,this._maskCamera=null,this.renderList=[],this.isSceneCamera=!0},addToRenderList:function(t){this.renderList.push(t)},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 c);var s=.5*this.width,n=.5*this.height;return i.x=t-s,i.y=e-n,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(){if(this.useBounds){var 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}return 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],s=e[1],n=e[2],r=e[3],o=i*r-s*n;if(!o)return t;var a=e[4],h=e[5],l=this.scrollX,u=this.scrollY,c=this.width,d=this.height,f=this.y,p=f+d,v=this.x,g=v+c,m=this.culledObjects,y=t.length;o=1/o,m.length=0;for(var x=0;xv&&S*i+E*n+af&&S*s+E*r+hn&&(t=n),t},clampY:function(t){var e=this._bounds,i=this.displayHeight,s=e.y+(i-this.height)/2,n=Math.max(s,s+e.height-i);return tn&&(t=n),t},removeBounds:function(){return this.useBounds=!1,this.dirty=!0,this._bounds.setEmpty(),this},setAngle:function(t){return void 0===t&&(t=0),this.rotation=r(t),this},setBackgroundColor:function(t){return void 0===t&&(t="rgba(0,0,0,0)"),this.backgroundColor=u(t),this.transparent=0===this.backgroundColor.alpha,this},setBounds:function(t,e,i,s,n){return void 0===n&&(n=!1),this._bounds.setTo(t,e,i,s),this.dirty=!0,this.useBounds=!0,n?this.centerToBounds():(this.scrollX=this.clampX(this.scrollX),this.scrollY=this.clampY(this.scrollY)),this},getBounds:function(t){void 0===t&&(t=new h);var e=this._bounds;return t.setTo(e.x,e.y,e.width,e.height),t},setName:function(t){return void 0===t&&(t=""),this.name=t,this},setPosition:function(t,e){return void 0===e&&(e=t),this.x=t,this.y=e,this},setRotation:function(t){return void 0===t&&(t=0),this.rotation=t,this},setRoundPixels:function(t){return this.roundPixels=t,this},setScene:function(t,e){void 0===e&&(e=!0),this.scene&&this._customViewport&&this.sceneManager.customViewports--,this.scene=t,this.isSceneCamera=e;var i=t.sys;return this.sceneManager=i.game.scene,this.scaleManager=i.scale,this.cameraManager=i.cameras,this.updateSystem(),this},setScroll:function(t,e){return void 0===e&&(e=t),this.scrollX=t,this.scrollY=e,this},setSize:function(t,e){return void 0===e&&(e=t),this.width=t,this.height=e,this},setViewport:function(t,e,i,s){return this.x=t,this.y=e,this.width=i,this.height=s,this},setZoom:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=t),0===t&&(t=.001),0===e&&(e=.001),this.zoomX=t,this.zoomY=e,this},setMask:function(t,e){return void 0===e&&(e=!0),this.mask=t,this._maskCamera=e?this.cameraManager.default:this,this},clearMask:function(t){return void 0===t&&(t=!1),t&&this.mask&&this.mask.destroy(),this.mask=null,this},toJSON:function(){var t={name:this.name,x:this.x,y:this.y,width:this.width,height:this.height,zoom:this.zoom,rotation:this.rotation,roundPixels:this.roundPixels,scrollX:this.scrollX,scrollY:this.scrollY,backgroundColor:this.backgroundColor.rgba};return this.useBounds&&(t.bounds={x:this._bounds.x,y:this._bounds.y,width:this._bounds.width,height:this._bounds.height}),t},update:function(){},setIsSceneCamera:function(t){return this.isSceneCamera=t,this},updateSystem:function(){if(this.scaleManager&&this.isSceneCamera){var t=0!==this._x||0!==this._y||this.scaleManager.width!==this._width||this.scaleManager.height!==this._height,e=this.sceneManager;t&&!this._customViewport?e.customViewports++:!t&&this._customViewport&&e.customViewports--,this.dirty=!0,this._customViewport=t}},destroy:function(){this.emit(a.DESTROY,this),this.removeAllListeners(),this.matrix.destroy(),this.culledObjects=[],this._customViewport&&this.sceneManager.customViewports--,this.renderList=[],this._bounds=null,this.scene=null,this.scaleManager=null,this.sceneManager=null,this.cameraManager=null},x:{get:function(){return this._x},set:function(t){this._x=t,this.updateSystem()}},y:{get:function(){return this._y},set:function(t){this._y=t,this.updateSystem()}},width:{get:function(){return this._width},set:function(t){this._width=t,this.updateSystem()}},height:{get:function(){return this._height},set:function(t){this._height=t,this.updateSystem()}},scrollX:{get:function(){return this._scrollX},set:function(t){t!==this._scrollX&&(this._scrollX=t,this.dirty=!0)}},scrollY:{get:function(){return this._scrollY},set:function(t){t!==this._scrollY&&(this._scrollY=t,this.dirty=!0)}},zoom:{get:function(){return(this._zoomX+this._zoomY)/2},set:function(t){this._zoomX=t,this._zoomY=t,this.dirty=!0}},zoomX:{get:function(){return this._zoomX},set:function(t){this._zoomX=t,this.dirty=!0}},zoomY:{get:function(){return this._zoomY},set:function(t){this._zoomY=t,this.dirty=!0}},rotation:{get:function(){return this._rotation},set:function(t){this._rotation=t,this.dirty=!0}},centerX:{get:function(){return this.x+.5*this.width}},centerY:{get:function(){return this.y+.5*this.height}},displayWidth:{get:function(){return this.width/this.zoomX}},displayHeight:{get:function(){return this.height/this.zoomY}}});t.exports=d},47751:(t,e,i)=>{var s=i(51052),n=i(79993),r=i(82897),o=i(56694),a=i(64937),h=i(53030),l=i(89787),u=i(42798),c=i(74118),d=i(93736),f=new o({Extends:s,Mixins:[a.PostPipeline],initialize:function(t,e,i,n){s.call(this,t,e,i,n),this.initPostPipeline(),this.inputEnabled=!0,this.fadeEffect=new h.Fade(this),this.flashEffect=new h.Flash(this),this.shakeEffect=new h.Shake(this),this.panEffect=new h.Pan(this),this.rotateToEffect=new h.RotateTo(this),this.zoomEffect=new h.Zoom(this),this.lerp=new d(1,1),this.followOffset=new d,this.deadzone=null,this._follow=null},setDeadzone:function(t,e){if(void 0===t)this.deadzone=null;else{if(this.deadzone?(this.deadzone.width=t,this.deadzone.height=e):this.deadzone=new c(0,0,t,e),this._follow){var i=this.width/2,s=this.height/2,r=this._follow.x-this.followOffset.x,o=this._follow.y-this.followOffset.y;this.midPoint.set(r,o),this.scrollX=r-i,this.scrollY=o-s}n(this.deadzone,this.midPoint.x,this.midPoint.y)}return this},fadeIn:function(t,e,i,s,n,r){return this.fadeEffect.start(!1,t,e,i,s,!0,n,r)},fadeOut:function(t,e,i,s,n,r){return this.fadeEffect.start(!0,t,e,i,s,!0,n,r)},fadeFrom:function(t,e,i,s,n,r,o){return this.fadeEffect.start(!1,t,e,i,s,n,r,o)},fade:function(t,e,i,s,n,r,o){return this.fadeEffect.start(!0,t,e,i,s,n,r,o)},flash:function(t,e,i,s,n,r,o){return this.flashEffect.start(t,e,i,s,n,r,o)},shake:function(t,e,i,s,n){return this.shakeEffect.start(t,e,i,s,n)},pan:function(t,e,i,s,n,r,o){return this.panEffect.start(t,e,i,s,n,r,o)},rotateTo:function(t,e,i,s,n,r,o){return this.rotateToEffect.start(t,e,i,s,n,r,o)},zoomTo:function(t,e,i,s,n,r){return this.zoomEffect.start(t,e,i,s,n,r)},preRender:function(){this.renderList.length=0;var t=this.width,e=this.height,i=.5*t,s=.5*e,r=this.zoom,o=this.matrix,a=t*this.originX,h=e*this.originY,c=this._follow,d=this.deadzone,f=this.scrollX,p=this.scrollY;d&&n(d,this.midPoint.x,this.midPoint.y);var v=!1;if(this.roundPixels&&(a=Math.floor(a),h=Math.floor(h)),c&&!this.panEffect.isRunning){var g=this.lerp,m=c.x-this.followOffset.x,y=c.y-this.followOffset.y;this.roundPixels&&(m=Math.floor(m),y=Math.floor(y)),d?(md.right&&(f=u(f,f+(m-d.right),g.x)),yd.bottom&&(p=u(p,p+(y-d.bottom),g.y))):(f=u(f,m-a,g.x),p=u(p,y-h,g.y)),v=!0}this.useBounds&&(f=this.clampX(f),p=this.clampY(p)),this.roundPixels&&(f=Math.floor(f),p=Math.floor(p)),this.scrollX=f,this.scrollY=p;var x=f+i,T=p+s;this.midPoint.set(x,T);var w=t/r,b=e/r,S=x-w/2,E=T-b/2;this.roundPixels&&(S=Math.floor(S),E=Math.floor(E)),this.worldView.setTo(S,E,w,b),o.applyITRS(Math.floor(this.x+a),Math.floor(this.y+h),this.rotation,r,r),o.translate(-a,-h),this.shakeEffect.preRender(),v&&this.emit(l.FOLLOW_UPDATE,this,c)},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,s,n,o){void 0===e&&(e=!1),void 0===i&&(i=1),void 0===s&&(s=i),void 0===n&&(n=0),void 0===o&&(o=n),this._follow=t,this.roundPixels=e,i=r(i,0,1),s=r(s,0,1),this.lerp.set(i,s),this.followOffset.set(n,o);var a=this.width/2,h=this.height/2,l=t.x-n,u=t.y-o;return this.midPoint.set(l,u),this.scrollX=l-a,this.scrollY=u-h,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=f},62382:(t,e,i)=>{var s=i(47751),n=i(56694),r=i(72632),o=i(91963),a=i(94287),h=i(40444),l=i(7599),u=new n({initialize:function(t){this.scene=t,this.systems=t.sys,this.roundPixels=t.sys.game.config.roundPixels,this.cameras=[],this.main,this.default,t.sys.events.once(l.BOOT,this.boot,this),t.sys.events.on(l.START,this.start,this)},boot:function(){var t=this.systems;t.settings.cameras?this.fromJSON(t.settings.cameras):this.add(),this.main=this.cameras[0],this.default=new s(0,0,t.scale.width,t.scale.height).setScene(this.scene),t.game.scale.on(h.RESIZE,this.onResize,this),this.systems.events.once(l.DESTROY,this.destroy,this)},start:function(){if(!this.main){var t=this.systems;t.settings.cameras?this.fromJSON(t.settings.cameras):this.add(),this.main=this.cameras[0]}var e=this.systems.events;e.on(l.UPDATE,this.update,this),e.once(l.SHUTDOWN,this.shutdown,this)},add:function(t,e,i,n,r,o){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=this.scene.sys.scale.width),void 0===n&&(n=this.scene.sys.scale.height),void 0===r&&(r=!1),void 0===o&&(o="");var a=new s(t,e,i,n);return a.setName(o),a.setScene(this.scene),a.setRoundPixels(this.roundPixels),a.id=this.getNextID(),this.cameras.push(a),r&&(this.main=a),a},addExisting:function(t,e){return void 0===e&&(e=!1),-1===this.cameras.indexOf(t)?(t.id=this.getNextID(),t.setRoundPixels(this.roundPixels),this.cameras.push(t),e&&(this.main=t),t):null},getNextID:function(){for(var t=this.cameras,e=1,i=0;i<32;i++){for(var s=!1,n=0;n0){r.preRender();var o=this.getVisibleChildren(e.getChildren(),r);t.render(i,o,r)}}},getVisibleChildren:function(t,e){return t.filter((function(t){return t.willRender(e)}))},resetAll:function(){for(var t=0;t{var s=i(82897),n=i(56694),r=i(89787),o=new n({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,s,n,o,a,h){if(void 0===t&&(t=!0),void 0===e&&(e=1e3),void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=0),void 0===o&&(o=!1),void 0===a&&(a=null),void 0===h&&(h=this.camera.scene),!o&&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=s,this.blue=n,this.alpha=t?Number.MIN_VALUE:1,this._elapsed=0,this._onUpdate=a,this._onUpdateScope=h;var l=t?r.FADE_OUT_START:r.FADE_IN_START;return this.camera.emit(l,this.camera,this,e,i,s,n),this.camera},update:function(t,e){this.isRunning&&(this._elapsed+=e,this.progress=s(this._elapsed/this.duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.camera,this.progress),this._elapsed{var s=i(82897),n=i(56694),r=i(89787),o=new n({initialize:function(t){this.camera=t,this.isRunning=!1,this.duration=0,this.red=0,this.green=0,this.blue=0,this.alpha=1,this.progress=0,this._elapsed=0,this._alpha,this._onUpdate,this._onUpdateScope},start:function(t,e,i,s,n,o,a){return void 0===t&&(t=250),void 0===e&&(e=255),void 0===i&&(i=255),void 0===s&&(s=255),void 0===n&&(n=!1),void 0===o&&(o=null),void 0===a&&(a=this.camera.scene),!n&&this.isRunning||(this.isRunning=!0,this.duration=t,this.progress=0,this.red=e,this.green=i,this.blue=s,this._alpha=this.alpha,this._elapsed=0,this._onUpdate=o,this._onUpdateScope=a,this.camera.emit(r.FLASH_START,this.camera,this,t,e,i,s)),this.camera},update:function(t,e){this.isRunning&&(this._elapsed+=e,this.progress=s(this._elapsed/this.duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.camera,this.progress),this._elapsed{var s=i(82897),n=i(56694),r=i(35060),o=i(89787),a=i(93736),h=new n({initialize:function(t){this.camera=t,this.isRunning=!1,this.duration=0,this.source=new a,this.current=new a,this.destination=new a,this.ease,this.progress=0,this._elapsed=0,this._onUpdate,this._onUpdateScope},start:function(t,e,i,s,n,a,h){void 0===i&&(i=1e3),void 0===s&&(s=r.Linear),void 0===n&&(n=!1),void 0===a&&(a=null),void 0===h&&(h=this.camera.scene);var l=this.camera;return!n&&this.isRunning||(this.isRunning=!0,this.duration=i,this.progress=0,this.source.set(l.scrollX,l.scrollY),this.destination.set(t,e),l.getScroll(t,e,this.current),"string"==typeof s&&r.hasOwnProperty(s)?this.ease=r[s]:"function"==typeof s&&(this.ease=s),this._elapsed=0,this._onUpdate=a,this._onUpdateScope=h,this.camera.emit(o.PAN_START,this.camera,this,i,t,e)),l},update:function(t,e){if(this.isRunning){this._elapsed+=e;var i=s(this._elapsed/this.duration,0,1);this.progress=i;var n=this.camera;if(this._elapsed{var s=i(82897),n=i(56694),r=i(89787),o=i(35060),a=new n({initialize:function(t){this.camera=t,this.isRunning=!1,this.duration=0,this.source=0,this.current=0,this.destination=0,this.ease,this.progress=0,this._elapsed=0,this._onUpdate,this._onUpdateScope,this.clockwise=!0,this.shortestPath=!1},start:function(t,e,i,s,n,a,h){void 0===i&&(i=1e3),void 0===s&&(s=o.Linear),void 0===n&&(n=!1),void 0===a&&(a=null),void 0===h&&(h=this.camera.scene),void 0===e&&(e=!1),this.shortestPath=e;var l=t;t<0?(l=-1*t,this.clockwise=!1):this.clockwise=!0;var u=360*Math.PI/180;l-=Math.floor(l/u)*u;var c=this.camera;if(!n&&this.isRunning)return c;if(this.isRunning=!0,this.duration=i,this.progress=0,this.source=c.rotation,this.destination=l,"string"==typeof s&&o.hasOwnProperty(s)?this.ease=o[s]:"function"==typeof s&&(this.ease=s),this._elapsed=0,this._onUpdate=a,this._onUpdateScope=h,this.shortestPath){var d=0,f=0;(d=this.destination>this.source?Math.abs(this.destination-this.source):Math.abs(this.destination+u)-this.source)<(f=this.source>this.destination?Math.abs(this.source-this.destination):Math.abs(this.source+u)-this.destination)?this.clockwise=!0:d>f&&(this.clockwise=!1)}return this.camera.emit(r.ROTATE_START,this.camera,this,i,l),c},update:function(t,e){if(this.isRunning){this._elapsed+=e;var i=s(this._elapsed/this.duration,0,1);this.progress=i;var n=this.camera;if(this._elapsed=l?Math.abs(h-l):Math.abs(h+a)-l;var u=0;u=this.clockwise?n.rotation+o*r:n.rotation-o*r,n.rotation=u,this._onUpdate&&this._onUpdate.call(this._onUpdateScope,n,i,u)}else n.rotation=this.destination,this._onUpdate&&this._onUpdate.call(this._onUpdateScope,n,i,this.destination),this.effectComplete()}},effectComplete:function(){this._onUpdate=null,this._onUpdateScope=null,this.isRunning=!1,this.camera.emit(r.ROTATE_COMPLETE,this.camera,this)},reset:function(){this.isRunning=!1,this._onUpdate=null,this._onUpdateScope=null},destroy:function(){this.reset(),this.camera=null,this.source=null,this.destination=null}});t.exports=a},3241:(t,e,i)=>{var s=i(82897),n=i(56694),r=i(89787),o=i(93736),a=new n({initialize:function(t){this.camera=t,this.isRunning=!1,this.duration=0,this.intensity=new o,this.progress=0,this._elapsed=0,this._offsetX=0,this._offsetY=0,this._onUpdate,this._onUpdateScope},start:function(t,e,i,s,n){return void 0===t&&(t=100),void 0===e&&(e=.05),void 0===i&&(i=!1),void 0===s&&(s=null),void 0===n&&(n=this.camera.scene),!i&&this.isRunning||(this.isRunning=!0,this.duration=t,this.progress=0,"number"==typeof e?this.intensity.set(e):this.intensity.set(e.x,e.y),this._elapsed=0,this._offsetX=0,this._offsetY=0,this._onUpdate=s,this._onUpdateScope=n,this.camera.emit(r.SHAKE_START,this.camera,this,t,e)),this.camera},preRender:function(){this.isRunning&&this.camera.matrix.translate(this._offsetX,this._offsetY)},update:function(t,e){if(this.isRunning)if(this._elapsed+=e,this.progress=s(this._elapsed/this.duration,0,1),this._onUpdate&&this._onUpdate.call(this._onUpdateScope,this.camera,this.progress),this._elapsed{var s=i(82897),n=i(56694),r=i(35060),o=i(89787),a=new n({initialize:function(t){this.camera=t,this.isRunning=!1,this.duration=0,this.source=1,this.destination=1,this.ease,this.progress=0,this._elapsed=0,this._onUpdate,this._onUpdateScope},start:function(t,e,i,s,n,a){void 0===e&&(e=1e3),void 0===i&&(i=r.Linear),void 0===s&&(s=!1),void 0===n&&(n=null),void 0===a&&(a=this.camera.scene);var h=this.camera;return!s&&this.isRunning||(this.isRunning=!0,this.duration=e,this.progress=0,this.source=h.zoom,this.destination=t,"string"==typeof i&&r.hasOwnProperty(i)?this.ease=r[i]:"function"==typeof i&&(this.ease=i),this._elapsed=0,this._onUpdate=n,this._onUpdateScope=a,this.camera.emit(o.ZOOM_START,this.camera,this,e,t)),h},update:function(t,e){this.isRunning&&(this._elapsed+=e,this.progress=s(this._elapsed/this.duration,0,1),this._elapsed{t.exports={Fade:i(92522),Flash:i(22151),Pan:i(37551),Shake:i(3241),RotateTo:i(1771),Zoom:i(13383)}},39577:t=>{t.exports="cameradestroy"},85373:t=>{t.exports="camerafadeincomplete"},92057:t=>{t.exports="camerafadeinstart"},1903:t=>{t.exports="camerafadeoutcomplete"},96131:t=>{t.exports="camerafadeoutstart"},85409:t=>{t.exports="cameraflashcomplete"},25500:t=>{t.exports="cameraflashstart"},44071:t=>{t.exports="followupdate"},19818:t=>{t.exports="camerapancomplete"},80002:t=>{t.exports="camerapanstart"},87966:t=>{t.exports="postrender"},74217:t=>{t.exports="prerender"},34805:t=>{t.exports="camerarotatecomplete"},30408:t=>{t.exports="camerarotatestart"},49856:t=>{t.exports="camerashakecomplete"},69189:t=>{t.exports="camerashakestart"},67657:t=>{t.exports="camerazoomcomplete"},14229:t=>{t.exports="camerazoomstart"},89787:(t,e,i)=>{t.exports={DESTROY:i(39577),FADE_IN_COMPLETE:i(85373),FADE_IN_START:i(92057),FADE_OUT_COMPLETE:i(1903),FADE_OUT_START:i(96131),FLASH_COMPLETE:i(85409),FLASH_START:i(25500),FOLLOW_UPDATE:i(44071),PAN_COMPLETE:i(19818),PAN_START:i(80002),POST_RENDER:i(87966),PRE_RENDER:i(74217),ROTATE_COMPLETE:i(34805),ROTATE_START:i(30408),SHAKE_COMPLETE:i(49856),SHAKE_START:i(69189),ZOOM_COMPLETE:i(67657),ZOOM_START:i(14229)}},32356:(t,e,i)=>{t.exports={Camera:i(47751),BaseCamera:i(51052),CameraManager:i(62382),Effects:i(53030),Events:i(89787)}},84219:(t,e,i)=>{var s=i(56694),n=i(10850),r=new s({initialize:function(t){this.camera=n(t,"camera",null),this.left=n(t,"left",null),this.right=n(t,"right",null),this.up=n(t,"up",null),this.down=n(t,"down",null),this.zoomIn=n(t,"zoomIn",null),this.zoomOut=n(t,"zoomOut",null),this.zoomSpeed=n(t,"zoomSpeed",.01),this.minZoom=n(t,"minZoom",.001),this.maxZoom=n(t,"maxZoom",1e3),this.speedX=0,this.speedY=0;var e=n(t,"speed",null);"number"==typeof e?(this.speedX=e,this.speedY=e):(this.speedX=n(t,"speed.x",0),this.speedY=n(t,"speed.y",0)),this._zoom=0,this.active=null!==this.camera},start:function(){return this.active=null!==this.camera,this},stop:function(){return this.active=!1,this},setCamera:function(t){return this.camera=t,this},update:function(t){if(this.active){void 0===t&&(t=1);var e=this.camera;this.up&&this.up.isDown?e.scrollY-=this.speedY*t|0:this.down&&this.down.isDown&&(e.scrollY+=this.speedY*t|0),this.left&&this.left.isDown?e.scrollX-=this.speedX*t|0:this.right&&this.right.isDown&&(e.scrollX+=this.speedX*t|0),this.zoomIn&&this.zoomIn.isDown?(e.zoom-=this.zoomSpeed,e.zoomthis.maxZoom&&(e.zoom=this.maxZoom))}},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},69370:(t,e,i)=>{var s=i(56694),n=i(10850),r=new s({initialize:function(t){this.camera=n(t,"camera",null),this.left=n(t,"left",null),this.right=n(t,"right",null),this.up=n(t,"up",null),this.down=n(t,"down",null),this.zoomIn=n(t,"zoomIn",null),this.zoomOut=n(t,"zoomOut",null),this.zoomSpeed=n(t,"zoomSpeed",.01),this.minZoom=n(t,"minZoom",.001),this.maxZoom=n(t,"maxZoom",1e3),this.accelX=0,this.accelY=0;var e=n(t,"acceleration",null);"number"==typeof e?(this.accelX=e,this.accelY=e):(this.accelX=n(t,"acceleration.x",0),this.accelY=n(t,"acceleration.y",0)),this.dragX=0,this.dragY=0;var i=n(t,"drag",null);"number"==typeof i?(this.dragX=i,this.dragY=i):(this.dragX=n(t,"drag.x",0),this.dragY=n(t,"drag.y",0)),this.maxSpeedX=0,this.maxSpeedY=0;var s=n(t,"maxSpeed",null);"number"==typeof s?(this.maxSpeedX=s,this.maxSpeedY=s):(this.maxSpeedX=n(t,"maxSpeed.x",0),this.maxSpeedY=n(t,"maxSpeed.y",0)),this._speedX=0,this._speedY=0,this._zoom=0,this.active=null!==this.camera},start:function(){return this.active=null!==this.camera,this},stop:function(){return this.active=!1,this},setCamera:function(t){return this.camera=t,this},update:function(t){if(this.active){void 0===t&&(t=1);var e=this.camera;this._speedX>0?(this._speedX-=this.dragX*t,this._speedX<0&&(this._speedX=0)):this._speedX<0&&(this._speedX+=this.dragX*t,this._speedX>0&&(this._speedX=0)),this._speedY>0?(this._speedY-=this.dragY*t,this._speedY<0&&(this._speedY=0)):this._speedY<0&&(this._speedY+=this.dragY*t,this._speedY>0&&(this._speedY=0)),this.up&&this.up.isDown?(this._speedY+=this.accelY,this._speedY>this.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.zoomthis.maxZoom&&(e.zoom=this.maxZoom))}},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},6524:(t,e,i)=>{t.exports={FixedKeyControl:i(84219),SmoothedKeyControl:i(69370)}},44143:(t,e,i)=>{t.exports={Controls:i(6524),Scene2D:i(32356)}},86459:(t,e,i)=>{var s={VERSION:"3.60.0",BlendModes:i(95723),ScaleModes:i(27394),AUTO:0,CANVAS:1,WEBGL:2,HEADLESS:3,FOREVER:-1,NONE:4,UP:5,DOWN:6,LEFT:7,RIGHT:8};t.exports=s},14033:(t,e,i)=>{var s=i(56694),n=i(86459),r=i(18360),o=i(77290),a=i(72632),h=i(10850),l=i(42911),u=i(72283),c=i(5923),d=i(65641),f=i(93222),p=new s({initialize:function(t){void 0===t&&(t={});var e=h(t,"scale",null);this.width=h(e,"width",1024,t),this.height=h(e,"height",768,t),this.zoom=h(e,"zoom",1,t),this.parent=h(e,"parent",void 0,t),this.scaleMode=h(e,e?"mode":"scaleMode",0,t),this.expandParent=h(e,"expandParent",!0,t),this.autoRound=h(e,"autoRound",!1,t),this.autoCenter=h(e,"autoCenter",0,t),this.resizeInterval=h(e,"resizeInterval",500,t),this.fullscreenTarget=h(e,"fullscreenTarget",null,t),this.minWidth=h(e,"minWidth",0,t),this.maxWidth=h(e,"maxWidth",0,t),this.minHeight=h(e,"minHeight",0,t),this.maxHeight=h(e,"maxHeight",0,t),this.renderType=h(t,"type",n.AUTO),this.canvas=h(t,"canvas",null),this.context=h(t,"context",null),this.canvasStyle=h(t,"canvasStyle",null),this.customEnvironment=h(t,"customEnvironment",!1),this.sceneConfig=h(t,"scene",null),this.seed=h(t,"seed",[(Date.now()*Math.random()).toString()]),c.RND=new c.RandomDataGenerator(this.seed),this.gameTitle=h(t,"title",""),this.gameURL=h(t,"url","https://phaser.io"),this.gameVersion=h(t,"version",""),this.autoFocus=h(t,"autoFocus",!0),this.stableSort=h(t,"stableSort",-1),-1===this.stableSort&&(this.stableSort=o.browser.es2019?1:0),o.features.stableSort=this.stableSort,this.domCreateContainer=h(t,"dom.createContainer",!1),this.domPointerEvents=h(t,"dom.pointerEvents","none"),this.inputKeyboard=h(t,"input.keyboard",!0),this.inputKeyboardEventTarget=h(t,"input.keyboard.target",window),this.inputKeyboardCapture=h(t,"input.keyboard.capture",[]),this.inputMouse=h(t,"input.mouse",!0),this.inputMouseEventTarget=h(t,"input.mouse.target",null),this.inputMousePreventDefaultDown=h(t,"input.mouse.preventDefaultDown",!0),this.inputMousePreventDefaultUp=h(t,"input.mouse.preventDefaultUp",!0),this.inputMousePreventDefaultMove=h(t,"input.mouse.preventDefaultMove",!0),this.inputMousePreventDefaultWheel=h(t,"input.mouse.preventDefaultWheel",!0),this.inputTouch=h(t,"input.touch",o.input.touch),this.inputTouchEventTarget=h(t,"input.touch.target",null),this.inputTouchCapture=h(t,"input.touch.capture",!0),this.inputActivePointers=h(t,"input.activePointers",1),this.inputSmoothFactor=h(t,"input.smoothFactor",0),this.inputWindowEvents=h(t,"input.windowEvents",!0),this.inputGamepad=h(t,"input.gamepad",!1),this.inputGamepadEventTarget=h(t,"input.gamepad.target",window),this.disableContextMenu=h(t,"disableContextMenu",!1),this.audio=h(t,"audio",{}),this.hideBanner=!1===h(t,"banner",null),this.hidePhaser=h(t,"banner.hidePhaser",!1),this.bannerTextColor=h(t,"banner.text","#ffffff"),this.bannerBackgroundColor=h(t,"banner.background",["#ff0000","#ffff00","#00ff00","#00ffff","#000000"]),""===this.gameTitle&&this.hidePhaser&&(this.hideBanner=!0),this.fps=h(t,"fps",null);var i=h(t,"render",null);this.pipeline=h(i,"pipeline",null,t),this.autoMobilePipeline=h(i,"autoMobilePipeline",!0,t),this.defaultPipeline=h(i,"defaultPipeline",d.MULTI_PIPELINE,t),this.antialias=h(i,"antialias",!0,t),this.antialiasGL=h(i,"antialiasGL",!0,t),this.mipmapFilter=h(i,"mipmapFilter","",t),this.desynchronized=h(i,"desynchronized",!1,t),this.roundPixels=h(i,"roundPixels",!1,t),this.pixelArt=h(i,"pixelArt",1!==this.zoom,t),this.pixelArt&&(this.antialias=!1,this.antialiasGL=!1,this.roundPixels=!0),this.transparent=h(i,"transparent",!1,t),this.clearBeforeRender=h(i,"clearBeforeRender",!0,t),this.preserveDrawingBuffer=h(i,"preserveDrawingBuffer",!1,t),this.premultipliedAlpha=h(i,"premultipliedAlpha",!0,t),this.failIfMajorPerformanceCaveat=h(i,"failIfMajorPerformanceCaveat",!1,t),this.powerPreference=h(i,"powerPreference","default",t),this.batchSize=h(i,"batchSize",4096,t),this.maxTextures=h(i,"maxTextures",-1,t),this.maxLights=h(i,"maxLights",10,t);var s=h(t,"backgroundColor",0);this.backgroundColor=f(s),this.transparent&&(this.backgroundColor=f(0),this.backgroundColor.alpha=0),this.preBoot=h(t,"callbacks.preBoot",u),this.postBoot=h(t,"callbacks.postBoot",u),this.physics=h(t,"physics",{}),this.defaultPhysicsSystem=h(this.physics,"default",!1),this.loaderBaseURL=h(t,"loader.baseURL",""),this.loaderPath=h(t,"loader.path",""),this.loaderMaxParallelDownloads=h(t,"loader.maxParallelDownloads",o.os.android?6:32),this.loaderCrossOrigin=h(t,"loader.crossOrigin",void 0),this.loaderResponseType=h(t,"loader.responseType",""),this.loaderAsync=h(t,"loader.async",!0),this.loaderUser=h(t,"loader.user",""),this.loaderPassword=h(t,"loader.password",""),this.loaderTimeout=h(t,"loader.timeout",0),this.loaderWithCredentials=h(t,"loader.withCredentials",!1),this.loaderImageLoadType=h(t,"loader.imageLoadType","XHR"),this.loaderLocalScheme=h(t,"loader.localScheme",["file://","capacitor://"]),this.glowFXQuality=h(t,"fx.glow.quality",.1),this.glowFXDistance=h(t,"fx.glow.distance",10),this.installGlobalPlugins=[],this.installScenePlugins=[];var p=h(t,"plugins",null),v=r.DefaultScene;p&&(Array.isArray(p)?this.defaultPlugins=p:l(p)&&(this.installGlobalPlugins=a(p,"global",[]),this.installScenePlugins=a(p,"scene",[]),Array.isArray(p.default)?v=p.default:Array.isArray(p.defaultMerge)&&(v=v.concat(p.defaultMerge)))),this.defaultPlugins=v;var g="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg";this.defaultImage=h(t,"images.default",g+"AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg=="),this.missingImage=h(t,"images.missing",g+"CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg=="),this.whiteImage=h(t,"images.white","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC"),window&&(window.FORCE_WEBGL?this.renderType=n.WEBGL:window.FORCE_CANVAS&&(this.renderType=n.CANVAS))}});t.exports=p},50150:(t,e,i)=>{var s=i(70616),n=i(61068),r=i(86459),o=i(90185);t.exports=function(t){var e=t.config;if((e.customEnvironment||e.canvas)&&e.renderType===r.AUTO)throw new Error("Must set explicit renderType in custom environment");if(!e.customEnvironment&&!e.canvas&&e.renderType!==r.HEADLESS)if(e.renderType===r.AUTO&&(e.renderType=o.webGL?r.WEBGL:r.CANVAS),e.renderType===r.WEBGL){if(!o.webGL)throw new Error("Cannot create WebGL context, aborting.")}else{if(e.renderType!==r.CANVAS)throw new Error("Unknown value for renderer type: "+e.renderType);if(!o.canvas)throw new Error("Cannot create Canvas context, aborting.")}e.antialias||n.disableSmoothing();var a,h,l=t.scale.baseSize,u=l.width,c=l.height;(e.canvas?(t.canvas=e.canvas,t.canvas.width=u,t.canvas.height=c):t.canvas=n.create(t,u,c,e.renderType),e.canvasStyle&&(t.canvas.style=e.canvasStyle),e.antialias||s.setCrisp(t.canvas),e.renderType!==r.HEADLESS)&&(a=i(91135),h=i(11857),e.renderType===r.WEBGL?t.renderer=new h(t):(t.renderer=new a(t),t.context=t.renderer.gameContext))}},77291:(t,e,i)=>{var s=i(86459);t.exports=function(t){var e=t.config;if(!e.hideBanner){var i="WebGL";e.renderType===s.CANVAS?i="Canvas":e.renderType===s.HEADLESS&&(i="Headless");var n,r=e.audio,o=t.device.audio;if(n=o.webAudio&&!r.disableWebAudio?"Web Audio":r.noAudio||!o.webAudio&&!o.audioData?"No Audio":"HTML5 Audio",t.device.browser.ie)window.console&&console.log("Phaser v"+s.VERSION+" / https://phaser.io");else{var a,h="",l=[h];if(Array.isArray(e.bannerBackgroundColor))e.bannerBackgroundColor.forEach((function(t){h=h.concat("%c "),l.push("background: "+t),a=t})),l[l.length-1]="color: "+e.bannerTextColor+"; background: "+a;else h=h.concat("%c "),l.push("color: "+e.bannerTextColor+"; background: "+e.bannerBackgroundColor);l.push("background: transparent"),e.gameTitle&&(h=h.concat(e.gameTitle),e.gameVersion&&(h=h.concat(" v"+e.gameVersion)),e.hidePhaser||(h=h.concat(" / ")));e.hidePhaser||(h=h.concat("Phaser v"+s.VERSION+" ("+i+" | "+n+")")),h=h.concat(" %c "+e.gameURL),l[0]=h,console.log.apply(console,l)}}}},15213:(t,e,i)=>{var s=i(99584),n=i(90249),r=i(43474),o=i(61068),a=i(56694),h=i(14033),l=i(85178),u=i(50150),c=i(81078),d=i(77291),f=i(77290),p=i(21546),v=i(6659),g=i(97081),m=i(69898),y=i(91963),x=i(49274),T=i(756),w=i(13553),b=i(38203),S=i(6237),E=i(26617),A=i(26493),C=i(84191),_=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 v,this.anims=new n(this),this.textures=new S(this),this.cache=new r(this),this.registry=new c(this,new v),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=C.create(this),this.loop=new E(this,this.config.fps),this.plugins=new x(this,this.config),this.pendingDestroy=!1,this.removeCanvas=!1,this.noReturn=!1,this.hasFocus=!1,this.isPaused=!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),s(this.canvas,this.config.parent),this.textures.once(b.READY,this.texturesReady,this),this.events.emit(g.BOOT)):console.warn("Aborting. Core Plugins missing.")},texturesReady:function(){this.events.emit(g.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(g.HIDDEN,this.onHidden,this),t.on(g.VISIBLE,this.onVisible,this),t.on(g.BLUR,this.onBlur,this),t.on(g.FOCUS,this.onFocus,this)},step:function(t,e){if(this.pendingDestroy)return this.runDestroy();if(!this.isPaused){var i=this.events;i.emit(g.PRE_STEP,t,e),i.emit(g.STEP,t,e),this.scene.update(t,e),i.emit(g.POST_STEP,t,e);var s=this.renderer;s.preRender(),i.emit(g.PRE_RENDER,s,t,e),this.scene.render(s),s.postRender(),i.emit(g.POST_RENDER,s,t,e)}},headlessStep:function(t,e){if(this.pendingDestroy)return this.runDestroy();if(!this.isPaused){var i=this.events;i.emit(g.PRE_STEP,t,e),i.emit(g.STEP,t,e),this.scene.update(t,e),i.emit(g.POST_STEP,t,e),this.scene.isProcessing=!1,i.emit(g.PRE_RENDER,null,t,e),i.emit(g.POST_RENDER,null,t,e)}},onHidden:function(){this.loop.pause(),this.events.emit(g.PAUSE)},pause:function(){var t=this.isPaused;this.isPaused=!0,t||this.events.emit(g.PAUSE)},onVisible:function(){this.loop.resume(),this.events.emit(g.RESUME)},resume:function(){var t=this.isPaused;this.isPaused=!1,t&&this.events.emit(g.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(g.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=_},26617:(t,e,i)=>{var s=i(56694),n=i(10850),r=i(72283),o=i(27385),a=new s({initialize:function(t,e){this.game=t,this.raf=new o,this.started=!1,this.running=!1,this.minFps=n(e,"min",5),this.targetFps=n(e,"target",60),this.fpsLimit=n(e,"limit",0),this.hasFpsLimit=this.fpsLimit>0,this._limitRate=this.hasFpsLimit?1e3/this.fpsLimit:0,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=n(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=n(e,"deltaHistory",10),this.panicMax=n(e,"panicMax",120),this.rawDelta=0,this.now=0,this.smoothStep=n(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,this.framesThisSecond=0;for(var e=0;e0||!this.inFocus)&&(this._coolDown--,t=Math.min(t,this._target)),t>this._min&&(t=i[e],t=Math.min(t,this._min)),i[e]=t,this.deltaIndex++,this.deltaIndex>=s&&(this.deltaIndex=0);for(var n=0,r=0;r=this.nextFpsUpdate&&this.updateFPS(t),this.framesThisSecond++,this.delta>=this._limitRate&&(this.callback(t,this.delta),this.delta=0),this.lastTime=t,this.frame++},step:function(t){this.now=t;var e=Math.max(0,t-this.lastTime);this.rawDelta=e,this.time+=this.rawDelta,this.smoothStep&&(e=this.smoothDelta(e)),this.delta=e,t>=this.nextFpsUpdate&&this.updateFPS(t),this.framesThisSecond++,this.callback(t,e),this.lastTime=t,this.frame++},tick:function(){var t=window.performance.now();this.hasFpsLimit?this.stepLimitFPS(t):this.step(t)},sleep:function(){this.running&&(this.raf.stop(),this.running=!1)},wake:function(t){void 0===t&&(t=!1);var e=window.performance.now();if(!this.running){t&&(this.startTime+=-this.lastTime+(this.lastTime+e));var i=this.hasFpsLimit?this.stepLimitFPS.bind(this):this.step.bind(this);this.raf.start(i,this.forceSetTimeOut,this._target),this.running=!0,this.nextFpsUpdate=e+1e3,this.framesThisSecond=0,this.fpsLimitTriggered=!1,this.tick()}},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.raf.destroy(),this.raf=null,this.game=null,this.callback=null}});t.exports=a},26493:(t,e,i)=>{var s=i(97081);t.exports=function(t){var e,i=t.events;if(void 0!==document.hidden)e="visibilitychange";else{["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(s.HIDDEN):i.emit(s.VISIBLE)}),!1),window.onblur=function(){i.emit(s.BLUR)},window.onfocus=function(){i.emit(s.FOCUS)},window.focus&&t.config.autoFocus&&window.focus()}},41651:t=>{t.exports="blur"},5520:t=>{t.exports="boot"},51673:t=>{t.exports="contextlost"},25055:t=>{t.exports="destroy"},23767:t=>{t.exports="focus"},57564:t=>{t.exports="hidden"},38327:t=>{t.exports="pause"},43807:t=>{t.exports="postrender"},73652:t=>{t.exports="poststep"},780:t=>{t.exports="prerender"},13781:t=>{t.exports="prestep"},38247:t=>{t.exports="ready"},29129:t=>{t.exports="resume"},34994:t=>{t.exports="step"},98704:t=>{t.exports="visible"},97081:(t,e,i)=>{t.exports={BLUR:i(41651),BOOT:i(5520),CONTEXT_LOST:i(51673),DESTROY:i(25055),FOCUS:i(23767),HIDDEN:i(57564),PAUSE:i(38327),POST_RENDER:i(43807),POST_STEP:i(73652),PRE_RENDER:i(780),PRE_STEP:i(13781),READY:i(38247),RESUME:i(29129),STEP:i(34994),VISIBLE:i(98704)}},80293:(t,e,i)=>{t.exports={Config:i(14033),CreateRenderer:i(50150),DebugHeader:i(77291),Events:i(97081),TimeStep:i(26617),VisibilityHandler:i(26493)}},52780:(t,e,i)=>{var s=i(81543),n=i(61068),r=i(10850);t.exports=function(t){var e=r(t,"data",[]),i=r(t,"canvas",null),o=r(t,"palette",s),a=r(t,"pixelWidth",1),h=r(t,"pixelHeight",a),l=r(t,"resizeCanvas",!0),u=r(t,"clearCanvas",!0),c=r(t,"preRender",null),d=r(t,"postRender",null),f=Math.floor(Math.abs(e[0].length*a)),p=Math.floor(Math.abs(e.length*h));i||(i=n.create2D(this,f,p),l=!1,u=!1),l&&(i.width=f,i.height=p);var v=i.getContext("2d",{willReadFrequently:!0});u&&v.clearRect(0,0,f,p),c&&c(i,v);for(var g=0;g{t.exports={GenerateTexture:i(52780),Palettes:i(25235)}},81543:t=>{t.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"}},75846:t=>{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"}},83206:t=>{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"}},13194:t=>{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"}},50686:t=>{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"}},25235:(t,e,i)=>{t.exports={ARNE16:i(81543),C64:i(75846),CGA:i(83206),JMP:i(13194),MSX:i(50686)}},63120:(t,e,i)=>{var s=i(56694),n=i(34631),r=i(38517),o=i(93736),a=new s({Extends:r,initialize:function(t,e,i,s){r.call(this,"CubicBezierCurve"),Array.isArray(t)&&(s=new o(t[6],t[7]),i=new o(t[4],t[5]),e=new o(t[2],t[3]),t=new o(t[0],t[1])),this.p0=t,this.p1=e,this.p2=i,this.p3=s},getStartPoint:function(t){return void 0===t&&(t=new o),t.copy(this.p0)},getResolution:function(t){return t},getPoint:function(t,e){void 0===e&&(e=new o);var i=this.p0,s=this.p1,r=this.p2,a=this.p3;return e.set(n(t,i.x,s.x,r.x,a.x),n(t,i.y,s.y,r.y,a.y))},draw:function(t,e){void 0===e&&(e=32);var i=this.getPoints(e);t.beginPath(),t.moveTo(this.p0.x,this.p0.y);for(var s=1;s{var s=i(56694),n=i(80222),r=i(74118),o=i(93736),a=new s({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();e>i&&(e=i/2);var s=Math.max(1,Math.round(i/e));return n(this.getSpacedPoints(s),t)},getDistancePoints:function(t){var e=this.getLength(),i=Math.max(1,e/t);return this.getSpacedPoints(i)},getEndPoint:function(t){return void 0===t&&(t=new o),this.getPointAt(1,t)},getLength:function(){var t=this.getLengths();return t[t.length-1]},getLengths:function(t){if(void 0===t&&(t=this.arcLengthDivisions),this.cacheArcLengths.length===t+1&&!this.needsUpdate)return this.cacheArcLengths;this.needsUpdate=!1;var e,i=[],s=this.getPoint(0,this._tmpVec2A),n=0;i.push(0);for(var r=1;r<=t;r++)n+=(e=this.getPoint(r/t,this._tmpVec2B)).distance(s),i.push(n),s.copy(e);return this.cacheArcLengths=i,i},getPointAt:function(t,e){var i=this.getUtoTmapping(t);return this.getPoint(i,e)},getPoints:function(t,e,i){void 0===i&&(i=[]),t||(t=e?this.getLength()/e:this.defaultDivisions);for(var s=0;s<=t;s++)i.push(this.getPoint(s/t));return i},getRandomPoint:function(t){return void 0===t&&(t=new o),this.getPoint(Math.random(),t)},getSpacedPoints:function(t,e,i){void 0===i&&(i=[]),t||(t=e?this.getLength()/e:this.defaultDivisions);for(var s=0;s<=t;s++){var n=this.getUtoTmapping(s/t,null,t);i.push(this.getPoint(n))}return i},getStartPoint:function(t){return void 0===t&&(t=new o),this.getPointAt(0,t)},getTangent:function(t,e){void 0===e&&(e=new o);var i=1e-4,s=t-i,n=t+i;return s<0&&(s=0),n>1&&(n=1),this.getPoint(s,this._tmpVec2A),this.getPoint(n,e),e.subtract(this._tmpVec2A).normalize()},getTangentAt:function(t,e){var i=this.getUtoTmapping(t);return this.getTangent(i,e)},getTFromDistance:function(t,e){return t<=0?0:this.getUtoTmapping(0,t,e)},getUtoTmapping:function(t,e,i){var s,n=this.getLengths(i),r=0,o=n.length;s=e?Math.min(e,n[o-1]):t*n[o-1];for(var a,h=0,l=o-1;h<=l;)if((a=n[r=Math.floor(h+(l-h)/2)]-s)<0)h=r+1;else{if(!(a>0)){l=r;break}l=r-1}if(n[r=l]===s)return r/(o-1);var u=n[r];return(r+(s-u)/(n[r+1]-u))/(o-1)},updateArcLengths:function(){this.needsUpdate=!0,this.getLengths()}});t.exports=a},48835:(t,e,i)=>{var s=i(56694),n=i(38517),r=i(75606),o=i(10850),a=i(23701),h=i(93736),l=new s({Extends:n,initialize:function(t,e,i,s,a,l,u,c){if("object"==typeof t){var d=t;t=o(d,"x",0),e=o(d,"y",0),i=o(d,"xRadius",0),s=o(d,"yRadius",i),a=o(d,"startAngle",0),l=o(d,"endAngle",360),u=o(d,"clockwise",!1),c=o(d,"rotation",0)}else void 0===s&&(s=i),void 0===a&&(a=0),void 0===l&&(l=360),void 0===u&&(u=!1),void 0===c&&(c=0);n.call(this,"EllipseCurve"),this.p0=new h(t,e),this._xRadius=i,this._yRadius=s,this._startAngle=r(a),this._endAngle=r(l),this._clockwise=u,this._rotation=r(c)},getStartPoint:function(t){return void 0===t&&(t=new h),this.getPoint(0,t)},getResolution:function(t){return 2*t},getPoint:function(t,e){void 0===e&&(e=new h);for(var i=2*Math.PI,s=this._endAngle-this._startAngle,n=Math.abs(s)i;)s-=i;s{var s=i(56694),n=i(38517),r=i(80222),o=i(74118),a=i(93736),h=new s({Extends:n,initialize:function(t,e){n.call(this,"LineCurve"),Array.isArray(t)&&(e=new a(t[2],t[3]),t=new a(t[0],t[1])),this.p0=t,this.p1=e,this.arcLengthDivisions=1},getBounds:function(t){return void 0===t&&(t=new o),r([this.p0,this.p1],t)},getStartPoint:function(t){return void 0===t&&(t=new a),t.copy(this.p0)},getResolution:function(t){return void 0===t&&(t=1),t},getPoint:function(t,e){return void 0===e&&(e=new a),1===t?e.copy(this.p1):(e.copy(this.p1).subtract(this.p0).scale(t).add(this.p0),e)},getPointAt:function(t,e){return this.getPoint(t,e)},getTangent:function(t,e){return void 0===e&&(e=new a),e.copy(this.p1).subtract(this.p0).normalize(),e},getUtoTmapping:function(t,e,i){var s;if(e){var n=this.getLengths(i),r=n[n.length-1];s=Math.min(e,r)/r}else s=t;return s},draw:function(t){return t.lineBetween(this.p0.x,this.p0.y,this.p1.x,this.p1.y),t},toJSON:function(){return{type:this.type,points:[this.p0.x,this.p0.y,this.p1.x,this.p1.y]}}});h.fromJSON=function(t){var e=t.points,i=new a(e[0],e[1]),s=new a(e[2],e[3]);return new h(i,s)},t.exports=h},64761:(t,e,i)=>{var s=i(56694),n=i(38517),r=i(16252),o=i(93736),a=new s({Extends:n,initialize:function(t,e,i){n.call(this,"QuadraticBezierCurve"),Array.isArray(t)&&(i=new o(t[4],t[5]),e=new o(t[2],t[3]),t=new o(t[0],t[1])),this.p0=t,this.p1=e,this.p2=i},getStartPoint:function(t){return void 0===t&&(t=new o),t.copy(this.p0)},getResolution:function(t){return t},getPoint:function(t,e){void 0===e&&(e=new o);var i=this.p0,s=this.p1,n=this.p2;return e.set(r(t,i.x,s.x,n.x),r(t,i.y,s.y,n.y))},draw:function(t,e){void 0===e&&(e=32);var i=this.getPoints(e);t.beginPath(),t.moveTo(this.p0.x,this.p0.y);for(var s=1;s{var s=i(14976),n=i(56694),r=i(38517),o=i(93736),a=new n({Extends:r,initialize:function(t){void 0===t&&(t=[]),r.call(this,"SplineCurve"),this.points=[],this.addPoints(t)},addPoints:function(t){for(var e=0;ei.length-2?i.length-1:r+1],c=i[r>i.length-3?i.length-1:r+2];return e.set(s(a,h.x,l.x,u.x,c.x),s(a,h.y,l.y,u.y,c.y))},toJSON:function(){for(var t=[],e=0;e{t.exports={Path:i(12822),MoveTo:i(53639),CubicBezier:i(63120),Curve:i(38517),Ellipse:i(48835),Line:i(58084),QuadraticBezier:i(64761),Spline:i(11956)}},53639:(t,e,i)=>{var s=i(56694),n=i(93736),r=new s({initialize:function(t,e){this.active=!1,this.p0=new n(t,e)},getPoint:function(t,e){return void 0===e&&(e=new n),e.copy(this.p0)},getPointAt:function(t,e){return this.getPoint(t,e)},getResolution:function(){return 1},getLength:function(){return 0},toJSON:function(){return{type:"MoveTo",points:[this.p0.x,this.p0.y]}}});t.exports=r},12822:(t,e,i)=>{var s=i(56694),n=i(63120),r=i(48835),o=i(61286),a=i(58084),h=i(53639),l=i(64761),u=i(74118),c=i(11956),d=i(93736),f=i(83392),p=new s({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 a(e,t)),this},cubicBezierTo:function(t,e,i,s,r,o){var a,h,l,u=this.getEndPoint();return t instanceof d?(a=t,h=e,l=i):(a=new d(i,s),h=new d(r,o),l=new d(t,e)),this.add(new n(u,a,h,l))},quadraticBezierTo:function(t,e,i,s){var n,r,o=this.getEndPoint();return t instanceof d?(n=t,r=e):(n=new d(i,s),r=new d(t,e)),this.add(new l(o,n,r))},draw:function(t,e){for(var i=0;i=e)return this.curves[s];s++}return null},getEndPoint:function(t){return void 0===t&&(t=new d),this.curves.length>0?this.curves[this.curves.length-1].getPoint(1,t):t.copy(this.startPoint),t},getLength:function(){var t=this.getCurveLengths();return t[t.length-1]},getPoint:function(t,e){void 0===e&&(e=new d);for(var i=t*this.getLength(),s=this.getCurveLengths(),n=0;n=i){var r=s[n]-i,o=this.curves[n],a=o.getLength(),h=0===a?0:1-r/a;return o.getPointAt(h,e)}n++}return null},getPoints:function(t){void 0===t&&(t=12);for(var e,i=[],s=0;s1&&!i[i.length-1].equals(i[0])&&i.push(i[0]),i},getRandomPoint:function(t){return void 0===t&&(t=new d),this.getPoint(Math.random(),t)},getSpacedPoints:function(t){void 0===t&&(t=40);for(var e=[],i=0;i<=t;i++)e.push(this.getPoint(i/t));return this.autoClose&&e.push(e[0]),e},getStartPoint:function(t){return void 0===t&&(t=new d),t.copy(this.startPoint)},getTangent:function(t,e){void 0===e&&(e=new d);for(var i=t*this.getLength(),s=this.getCurveLengths(),n=0;n=i){var r=s[n]-i,o=this.curves[n],a=o.getLength(),h=0===a?0:1-r/a;return o.getTangentAt(h,e)}n++}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 a([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 h(t.x,t.y)):this.add(new h(t,e))},toJSON:function(){for(var t=[],e=0;e{var s=i(56694),n=i(35026),r=new s({initialize:function(t,e){this.parent=t,this.events=e,e||(this.events=t.events?t.events:t),this.list={},this.values={},this._frozen=!1,!t.hasOwnProperty("sys")&&this.events&&this.events.once(n.DESTROY,this.destroy,this)},get:function(t){var e=this.list;if(Array.isArray(t)){for(var i=[],s=0;s{var s=i(56694),n=i(81078),r=i(91963),o=i(7599),a=new s({Extends:n,initialize:function(t){n.call(this,t,t.sys.events),this.scene=t,this.systems=t.sys,t.sys.events.once(o.BOOT,this.boot,this),t.sys.events.on(o.START,this.start,this)},boot:function(){this.events=this.systems.events,this.events.once(o.DESTROY,this.destroy,this)},start:function(){this.events.once(o.SHUTDOWN,this.shutdown,this)},shutdown:function(){this.systems.events.off(o.SHUTDOWN,this.shutdown,this)},destroy:function(){n.prototype.destroy.call(this),this.events.off(o.START,this.start,this),this.scene=null,this.systems=null}});r.register("DataManagerPlugin",a,"data"),t.exports=a},73569:t=>{t.exports="changedata"},15590:t=>{t.exports="changedata-"},37669:t=>{t.exports="destroy"},87090:t=>{t.exports="removedata"},90142:t=>{t.exports="setdata"},35026:(t,e,i)=>{t.exports={CHANGE_DATA:i(73569),CHANGE_DATA_KEY:i(15590),DESTROY:i(37669),REMOVE_DATA:i(87090),SET_DATA:i(90142)}},1999:(t,e,i)=>{t.exports={DataManager:i(81078),DataManagerPlugin:i(76508),Events:i(35026)}},10720:(t,e,i)=>{var s=i(1350),n={flac:!1,aac:!1,audioData:!1,dolby:!1,m4a:!1,mp3:!1,ogg:!1,opus:!1,wav:!1,webAudio:!1,webm:!1};t.exports=function(){if("function"==typeof importScripts)return n;n.audioData=!!window.Audio,n.webAudio=!(!window.AudioContext&&!window.webkitAudioContext);var t=document.createElement("audio"),e=!!t.canPlayType;try{if(e){var i=function(e,i){var s=t.canPlayType("audio/"+e).replace(/^no$/,"");return i?Boolean(s||t.canPlayType("audio/"+i).replace(/^no$/,"")):Boolean(s)};if(n.ogg=i('ogg; codecs="vorbis"'),n.opus=i('ogg; codecs="opus"',"opus"),n.mp3=i("mpeg"),n.wav=i("wav"),n.m4a=i("x-m4a"),n.aac=i("aac"),n.flac=i("flac","x-flac"),n.webm=i('webm; codecs="vorbis"'),""!==t.canPlayType('audio/mp4; codecs="ec-3"'))if(s.edge)n.dolby=!0;else if(s.safari&&s.safariVersion>=9&&/Mac OS X (\d+)_(\d+)/.test(navigator.userAgent)){var r=parseInt(RegExp.$1,10),o=parseInt(RegExp.$2,10);(10===r&&o>=11||r>10)&&(n.dolby=!0)}}}catch(t){}return n}()},1350:(t,e,i)=>{var s,n=i(36580),r={chrome:!1,chromeVersion:0,edge:!1,firefox:!1,firefoxVersion:0,ie:!1,ieVersion:0,mobileSafari:!1,opera:!1,safari:!1,safariVersion:0,silk:!1,trident:!1,tridentVersion:0,es2019:!1};t.exports=(s=navigator.userAgent,/Edg\/\d+/.test(s)?(r.edge=!0,r.es2019=!0):/OPR/.test(s)?(r.opera=!0,r.es2019=!0):/Chrome\/(\d+)/.test(s)&&!n.windowsPhone?(r.chrome=!0,r.chromeVersion=parseInt(RegExp.$1,10),r.es2019=r.chromeVersion>69):/Firefox\D+(\d+)/.test(s)?(r.firefox=!0,r.firefoxVersion=parseInt(RegExp.$1,10),r.es2019=r.firefoxVersion>10):/AppleWebKit/.test(s)&&n.iOS?r.mobileSafari=!0:/MSIE (\d+\.\d+);/.test(s)?(r.ie=!0,r.ieVersion=parseInt(RegExp.$1,10)):/Version\/(\d+\.\d+) Safari/.test(s)&&!n.windowsPhone?(r.safari=!0,r.safariVersion=parseInt(RegExp.$1,10),r.es2019=r.safariVersion>10):/Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/.test(s)&&(r.ie=!0,r.trident=!0,r.tridentVersion=parseInt(RegExp.$1,10),r.ieVersion=parseInt(RegExp.$3,10)),/Silk/.test(s)&&(r.silk=!0),r)},98581:(t,e,i)=>{var s,n,r,o=i(61068),a={supportInverseAlpha:!1,supportNewBlendModes:!1};t.exports=("function"!=typeof importScripts&&void 0!==document&&(a.supportNewBlendModes=(s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/",n="AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==",(r=new Image).onload=function(){var t=new Image;t.onload=function(){var e=o.create2D(t,6).getContext("2d",{willReadFrequently:!0});if(e.globalCompositeOperation="multiply",e.drawImage(r,0,0),e.drawImage(t,2,0),!e.getImageData(2,0,1,1))return!1;var i=e.getImageData(2,0,1,1).data;o.remove(t),a.supportNewBlendModes=255===i[0]&&0===i[1]&&0===i[2]},t.src=s+"/wCKxvRF"+n},r.src=s+"AP804Oa6"+n,!1),a.supportInverseAlpha=function(){var t=o.create2D(this,2).getContext("2d",{willReadFrequently:!0});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),s=i.data[0]===e.data[0]&&i.data[1]===e.data[1]&&i.data[2]===e.data[2]&&i.data[3]===e.data[3];return o.remove(this),s}()),a)},90185:(t,e,i)=>{var s=i(36580),n=i(1350),r=i(61068),o={canvas:!1,canvasBitBltShift:null,file:!1,fileSystem:!1,getUserMedia:!0,littleEndian:!1,localStorage:!1,pointerLock:!1,stableSort:!1,support32bit:!1,vibration:!1,webGL:!1,worker:!1};t.exports=function(){if("function"==typeof importScripts)return o;o.canvas=!!window.CanvasRenderingContext2D;try{o.localStorage=!!localStorage.getItem}catch(t){o.localStorage=!1}o.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),o.fileSystem=!!window.requestFileSystem;var t,e,i,a=!1;return o.webGL=function(){if(window.WebGLRenderingContext)try{var t=r.createWebGL(this),e=t.getContext("webgl")||t.getContext("experimental-webgl"),i=r.create2D(this),s=i.getContext("2d",{willReadFrequently:!0}).createImageData(1,1);return a=s.data instanceof Uint8ClampedArray,r.remove(t),r.remove(i),!!e}catch(t){return!1}return!1}(),o.worker=!!window.Worker,o.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,o.getUserMedia=o.getUserMedia&&!!navigator.getUserMedia&&!!window.URL,n.firefox&&n.firefoxVersion<21&&(o.getUserMedia=!1),!s.iOS&&(n.ie||n.firefox||n.chrome)&&(o.canvasBitBltShift=!0),(n.safari||n.mobileSafari)&&(o.canvasBitBltShift=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(o.vibration=!0),"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint32Array&&(o.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)),o.support32bit="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof Int32Array&&null!==o.littleEndian&&a,o}()},33553:t=>{var e={available:!1,cancel:"",keyboard:!1,request:""};t.exports=function(){if("function"==typeof importScripts)return e;var t,i="Fullscreen",s="FullScreen",n=["request"+i,"request"+s,"webkitRequest"+i,"webkitRequest"+s,"msRequest"+i,"msRequest"+s,"mozRequest"+s,"mozRequest"+i];for(t=0;t{var s=i(1350),n={gamepads:!1,mspointer:!1,touch:!1,wheelEvent:null};t.exports=("function"==typeof importScripts||(("ontouchstart"in document.documentElement||navigator.maxTouchPoints&&navigator.maxTouchPoints>=1)&&(n.touch=!0),(navigator.msPointerEnabled||navigator.pointerEnabled)&&(n.mspointer=!0),navigator.getGamepads&&(n.gamepads=!0),"onwheel"in window||s.ie&&"WheelEvent"in window?n.wheelEvent="wheel":"onmousewheel"in window?n.wheelEvent="mousewheel":s.firefox&&"MouseScrollEvent"in window&&(n.wheelEvent="DOMMouseScroll")),n)},36580:t=>{var e={android:!1,chromeOS:!1,cordova:!1,crosswalk:!1,desktop:!1,ejecta:!1,electron:!1,iOS:!1,iOSVersion:0,iPad:!1,iPhone:!1,kindle:!1,linux:!1,macOS:!1,node:!1,nodeWebkit:!1,pixelRatio:1,webApp:!1,windows:!1,windowsPhone:!1};t.exports=function(){if("function"==typeof importScripts)return e;var t=navigator.userAgent;/Windows/.test(t)?e.windows=!0:/Mac OS/.test(t)&&!/like Mac OS/.test(t)?navigator.maxTouchPoints&&navigator.maxTouchPoints>2?(e.iOS=!0,e.iPad=!0,navigator.appVersion.match(/Version\/(\d+)/),e.iOSVersion=parseInt(RegExp.$1,10)):e.macOS=!0:/Android/.test(t)?e.android=!0:/Linux/.test(t)?e.linux=!0:/iP[ao]d|iPhone/i.test(t)?(e.iOS=!0,navigator.appVersion.match(/OS (\d+)/),e.iOSVersion=parseInt(RegExp.$1,10),e.iPhone=-1!==t.toLowerCase().indexOf("iphone"),e.iPad=-1!==t.toLowerCase().indexOf("ipad")):/Kindle/.test(t)||/\bKF[A-Z][A-Z]+/.test(t)||/Silk.*Mobile Safari/.test(t)?e.kindle=!0:/CrOS/.test(t)&&(e.chromeOS=!0),(/Windows Phone/i.test(t)||/IEMobile/i.test(t))&&(e.android=!1,e.iOS=!1,e.macOS=!1,e.windows=!0,e.windowsPhone=!0);var i=/Silk/.test(t);return(e.windows||e.macOS||e.linux&&!i||e.chromeOS)&&(e.desktop=!0),(e.windowsPhone||/Windows NT/i.test(t)&&/Touch/i.test(t))&&(e.desktop=!1),navigator.standalone&&(e.webApp=!0),"function"!=typeof importScripts&&(void 0!==window.cordova&&(e.cordova=!0),void 0!==window.ejecta&&(e.ejecta=!0)),"undefined"!=typeof process&&process.versions&&process.versions.node&&(e.node=!0),e.node&&"object"==typeof process.versions&&(e.nodeWebkit=!!process.versions["node-webkit"],e.electron=!!process.versions.electron),/Crosswalk/.test(t)&&(e.crosswalk=!0),e.pixelRatio=window.devicePixelRatio||1,e}()},53861:(t,e,i)=>{var s=i(72632),n={h264:!1,hls:!1,mp4:!1,m4v:!1,ogg:!1,vp9:!1,webm:!1,hasRequestVideoFrame:!1};t.exports=function(){if("function"==typeof importScripts)return n;var t=document.createElement("video"),e=!!t.canPlayType,i=/^no$/;try{e&&(t.canPlayType('video/ogg; codecs="theora"').replace(i,"")&&(n.ogg=!0),t.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(i,"")&&(n.h264=!0,n.mp4=!0),t.canPlayType("video/x-m4v").replace(i,"")&&(n.m4v=!0),t.canPlayType('video/webm; codecs="vp8, vorbis"').replace(i,"")&&(n.webm=!0),t.canPlayType('video/webm; codecs="vp9"').replace(i,"")&&(n.vp9=!0),t.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(i,"")&&(n.hls=!0))}catch(t){}return t.parentNode&&t.parentNode.removeChild(t),n.getVideoURL=function(t){Array.isArray(t)||(t=[t]);for(var e=0;e{t.exports={os:i(36580),browser:i(1350),features:i(90185),input:i(95872),audio:i(10720),video:i(53861),fullscreen:i(33553),canvasFeatures:i(98581)}},65246:(t,e,i)=>{var s=i(56694),n=new Float32Array(20),r=new s({initialize:function(){this._matrix=new Float32Array(20),this.alpha=1,this._dirty=!0,this._data=new Float32Array(20),this.reset()},set:function(t){return this._matrix.set(t),this._dirty=!0,this},reset:function(){var t=this._matrix;return t.fill(0),t[0]=1,t[6]=1,t[12]=1,t[18]=1,this.alpha=1,this._dirty=!0,this},getData:function(){var t=this._data;return this._dirty&&(t.set(this._matrix),t[4]/=255,t[9]/=255,t[14]/=255,t[19]/=255,this._dirty=!1),t},brightness:function(t,e){void 0===t&&(t=0),void 0===e&&(e=!1);var i=t;return this.multiply([i,0,0,0,0,0,i,0,0,0,0,0,i,0,0,0,0,0,1,0],e)},saturate:function(t,e){void 0===t&&(t=0),void 0===e&&(e=!1);var i=2*t/3+1,s=-.5*(i-1);return this.multiply([i,s,s,0,0,s,i,s,0,0,s,s,i,0,0,0,0,0,1,0],e)},desaturate:function(t){return void 0===t&&(t=!1),this.saturate(-1,t)},hue:function(t,e){void 0===t&&(t=0),void 0===e&&(e=!1),t=t/180*Math.PI;var i=Math.cos(t),s=Math.sin(t),n=.213,r=.715,o=.072;return this.multiply([n+.787*i+s*-n,r+i*-r+s*-r,o+i*-o+.928*s,0,0,n+i*-n+.143*s,r+i*(1-r)+.14*s,o+i*-o+-.283*s,0,0,n+i*-n+-.787*s,r+i*-r+s*r,o+.928*i+s*o,0,0,0,0,0,1,0],e)},grayscale:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=!1),this.saturate(-t,e)},blackWhite:function(t){return void 0===t&&(t=!1),this.multiply(r.BLACK_WHITE,t)},contrast:function(t,e){void 0===t&&(t=0),void 0===e&&(e=!1);var i=t+1,s=-.5*(i-1);return this.multiply([i,0,0,0,s,0,i,0,0,s,0,0,i,0,s,0,0,0,1,0],e)},negative:function(t){return void 0===t&&(t=!1),this.multiply(r.NEGATIVE,t)},desaturateLuminance:function(t){return void 0===t&&(t=!1),this.multiply(r.DESATURATE_LUMINANCE,t)},sepia:function(t){return void 0===t&&(t=!1),this.multiply(r.SEPIA,t)},night:function(t,e){return void 0===t&&(t=.1),void 0===e&&(e=!1),this.multiply([-2*t,-t,0,0,0,-t,0,t,0,0,0,t,2*t,0,0,0,0,0,1,0],e)},lsd:function(t){return void 0===t&&(t=!1),this.multiply(r.LSD,t)},brown:function(t){return void 0===t&&(t=!1),this.multiply(r.BROWN,t)},vintagePinhole:function(t){return void 0===t&&(t=!1),this.multiply(r.VINTAGE,t)},kodachrome:function(t){return void 0===t&&(t=!1),this.multiply(r.KODACHROME,t)},technicolor:function(t){return void 0===t&&(t=!1),this.multiply(r.TECHNICOLOR,t)},polaroid:function(t){return void 0===t&&(t=!1),this.multiply(r.POLAROID,t)},shiftToBGR:function(t){return void 0===t&&(t=!1),this.multiply(r.SHIFT_BGR,t)},multiply:function(t,e){void 0===e&&(e=!1),e||this.reset();var i=this._matrix,s=n;return s.set(i),i.set([s[0]*t[0]+s[1]*t[5]+s[2]*t[10]+s[3]*t[15],s[0]*t[1]+s[1]*t[6]+s[2]*t[11]+s[3]*t[16],s[0]*t[2]+s[1]*t[7]+s[2]*t[12]+s[3]*t[17],s[0]*t[3]+s[1]*t[8]+s[2]*t[13]+s[3]*t[18],s[0]*t[4]+s[1]*t[9]+s[2]*t[14]+s[3]*t[19]+s[4],s[5]*t[0]+s[6]*t[5]+s[7]*t[10]+s[8]*t[15],s[5]*t[1]+s[6]*t[6]+s[7]*t[11]+s[8]*t[16],s[5]*t[2]+s[6]*t[7]+s[7]*t[12]+s[8]*t[17],s[5]*t[3]+s[6]*t[8]+s[7]*t[13]+s[8]*t[18],s[5]*t[4]+s[6]*t[9]+s[7]*t[14]+s[8]*t[19]+s[9],s[10]*t[0]+s[11]*t[5]+s[12]*t[10]+s[13]*t[15],s[10]*t[1]+s[11]*t[6]+s[12]*t[11]+s[13]*t[16],s[10]*t[2]+s[11]*t[7]+s[12]*t[12]+s[13]*t[17],s[10]*t[3]+s[11]*t[8]+s[12]*t[13]+s[13]*t[18],s[10]*t[4]+s[11]*t[9]+s[12]*t[14]+s[13]*t[19]+s[14],s[15]*t[0]+s[16]*t[5]+s[17]*t[10]+s[18]*t[15],s[15]*t[1]+s[16]*t[6]+s[17]*t[11]+s[18]*t[16],s[15]*t[2]+s[16]*t[7]+s[17]*t[12]+s[18]*t[17],s[15]*t[3]+s[16]*t[8]+s[17]*t[13]+s[18]*t[18],s[15]*t[4]+s[16]*t[9]+s[17]*t[14]+s[18]*t[19]+s[19]]),this._dirty=!0,this}});r.BLACK_WHITE=[.3,.6,.1,0,0,.3,.6,.1,0,0,.3,.6,.1,0,0,0,0,0,1,0],r.NEGATIVE=[-1,0,0,1,0,0,-1,0,1,0,0,0,-1,1,0,0,0,0,1,0],r.DESATURATE_LUMINANCE=[.2764723,.929708,.0938197,0,-37.1,.2764723,.929708,.0938197,0,-37.1,.2764723,.929708,.0938197,0,-37.1,0,0,0,1,0],r.SEPIA=[.393,.7689999,.18899999,0,0,.349,.6859999,.16799999,0,0,.272,.5339999,.13099999,0,0,0,0,0,1,0],r.LSD=[2,-.4,.5,0,0,-.5,2,-.4,0,0,-.4,-.5,3,0,0,0,0,0,1,0],r.BROWN=[.5997023498159715,.34553243048391263,-.2708298674538042,0,47.43192855600873,-.037703249837783157,.8609577587992641,.15059552388459913,0,-36.96841498319127,.24113635128153335,-.07441037908422492,.44972182064877153,0,-7.562075277591283,0,0,0,1,0],r.VINTAGE=[.6279345635605994,.3202183420819367,-.03965408211312453,0,9.651285835294123,.02578397704808868,.6441188644374771,.03259127616149294,0,7.462829176470591,.0466055556782719,-.0851232987247891,.5241648018700465,0,5.159190588235296,0,0,0,1,0],r.KODACHROME=[1.1285582396593525,-.3967382283601348,-.03992559172921793,0,63.72958762196502,-.16404339962244616,1.0835251566291304,-.05498805115633132,0,24.732407896706203,-.16786010706155763,-.5603416277695248,1.6014850761964943,0,35.62982807460946,0,0,0,1,0],r.TECHNICOLOR=[1.9125277891456083,-.8545344976951645,-.09155508482755585,0,11.793603434377337,-.3087833385928097,1.7658908555458428,-.10601743074722245,0,-70.35205161461398,-.231103377548616,-.7501899197440212,1.847597816108189,0,30.950940869491138,0,0,0,1,0],r.POLAROID=[1.438,-.062,-.062,0,0,-.122,1.378,-.122,0,0,-.016,-.016,1.483,0,0,0,0,0,1,0],r.SHIFT_BGR=[0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0],t.exports=r},39298:(t,e,i)=>{var s=i(56694),n=i(72283),r=new s({initialize:function(t,e,i){this._rgb=[0,0,0],this.onChangeCallback=n,this.dirty=!1,this.set(t,e,i)},set:function(t,e,i){return void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),this._rgb=[t,e,i],this.onChange(),this},equals:function(t,e,i){var s=this._rgb;return s[0]===t&&s[1]===e&&s[2]===i},onChange:function(){this.dirty=!0;var t=this._rgb;this.onChangeCallback.call(this,t[0],t[1],t[2])},r:{get:function(){return this._rgb[0]},set:function(t){this._rgb[0]=t,this.onChange()}},g:{get:function(){return this._rgb[1]},set:function(t){this._rgb[1]=t,this.onChange()}},b:{get:function(){return this._rgb[2]},set:function(t){this._rgb[2]=t,this.onChange()}},destroy:function(){this.onChangeCallback=null}});t.exports=r},84093:t=>{t.exports={TOP_LEFT:0,TOP_CENTER:1,TOP_RIGHT:2,LEFT_TOP:3,LEFT_CENTER:4,LEFT_BOTTOM:5,CENTER:6,RIGHT_TOP:7,RIGHT_CENTER:8,RIGHT_BOTTOM:9,BOTTOM_LEFT:10,BOTTOM_CENTER:11,BOTTOM_RIGHT:12}},32058:(t,e,i)=>{var s=i(97328),n=i(59994),r=i(73174),o=i(28417);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,n(e)+i),r(t,s(e)+a),t}},85535:(t,e,i)=>{var s=i(97328),n=i(40163),r=i(73174),o=i(74465);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,n(e)-i),r(t,s(e)+a),t}},9605:(t,e,i)=>{var s=i(97328),n=i(70271),r=i(73174),o=i(19298);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,n(e)+i),r(t,s(e)+a),t}},22529:(t,e,i)=>{var s=i(21843),n=i(59994),r=i(29568);t.exports=function(t,e,i,o){return void 0===i&&(i=0),void 0===o&&(o=0),s(t,n(e)+i,r(e)+o),t}},5739:(t,e,i)=>{var s=i(29568),n=i(40163),r=i(81711),o=i(74465);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,n(e)-i),r(t,s(e)+a),t}},40327:(t,e,i)=>{var s=i(84093),n=[];n[s.BOTTOM_CENTER]=i(32058),n[s.BOTTOM_LEFT]=i(85535),n[s.BOTTOM_RIGHT]=i(9605),n[s.CENTER]=i(22529),n[s.LEFT_CENTER]=i(5739),n[s.RIGHT_CENTER]=i(27683),n[s.TOP_CENTER]=i(96439),n[s.TOP_LEFT]=i(81447),n[s.TOP_RIGHT]=i(47888),n[s.LEFT_BOTTOM]=n[s.BOTTOM_LEFT],n[s.LEFT_TOP]=n[s.TOP_LEFT],n[s.RIGHT_BOTTOM]=n[s.BOTTOM_RIGHT],n[s.RIGHT_TOP]=n[s.TOP_RIGHT];t.exports=function(t,e,i,s,r){return n[i](t,e,s,r)}},27683:(t,e,i)=>{var s=i(29568),n=i(70271),r=i(81711),o=i(19298);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,n(e)+i),r(t,s(e)+a),t}},96439:(t,e,i)=>{var s=i(59994),n=i(47196),r=i(28417),o=i(84349);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),r(t,s(e)+i),o(t,n(e)-a),t}},81447:(t,e,i)=>{var s=i(40163),n=i(47196),r=i(74465),o=i(84349);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),r(t,s(e)-i),o(t,n(e)-a),t}},47888:(t,e,i)=>{var s=i(70271),n=i(47196),r=i(19298),o=i(84349);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),r(t,s(e)+i),o(t,n(e)-a),t}},46997:(t,e,i)=>{t.exports={BottomCenter:i(32058),BottomLeft:i(85535),BottomRight:i(9605),Center:i(22529),LeftCenter:i(5739),QuickSet:i(40327),RightCenter:i(27683),TopCenter:i(96439),TopLeft:i(81447),TopRight:i(47888)}},93545:(t,e,i)=>{var s=i(84093),n=i(98611),r={In:i(46997),To:i(86639)};r=n(!1,r,s),t.exports=r},27118:(t,e,i)=>{var s=i(97328),n=i(59994),r=i(28417),o=i(84349);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),r(t,n(e)+i),o(t,s(e)+a),t}},84469:(t,e,i)=>{var s=i(97328),n=i(40163),r=i(74465),o=i(84349);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),r(t,n(e)-i),o(t,s(e)+a),t}},51577:(t,e,i)=>{var s=i(97328),n=i(70271),r=i(19298),o=i(84349);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),r(t,n(e)+i),o(t,s(e)+a),t}},90271:(t,e,i)=>{var s=i(97328),n=i(40163),r=i(73174),o=i(19298);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,n(e)-i),r(t,s(e)+a),t}},30466:(t,e,i)=>{var s=i(29568),n=i(40163),r=i(81711),o=i(19298);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,n(e)-i),r(t,s(e)+a),t}},50087:(t,e,i)=>{var s=i(40163),n=i(47196),r=i(19298),o=i(84349);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),r(t,s(e)-i),o(t,n(e)-a),t}},82590:(t,e,i)=>{var s=i(84093),n=[];n[s.BOTTOM_CENTER]=i(27118),n[s.BOTTOM_LEFT]=i(84469),n[s.BOTTOM_RIGHT]=i(51577),n[s.LEFT_BOTTOM]=i(90271),n[s.LEFT_CENTER]=i(30466),n[s.LEFT_TOP]=i(50087),n[s.RIGHT_BOTTOM]=i(13555),n[s.RIGHT_CENTER]=i(99049),n[s.RIGHT_TOP]=i(67788),n[s.TOP_CENTER]=i(78170),n[s.TOP_LEFT]=i(54145),n[s.TOP_RIGHT]=i(75548);t.exports=function(t,e,i,s,r){return n[i](t,e,s,r)}},13555:(t,e,i)=>{var s=i(97328),n=i(70271),r=i(73174),o=i(74465);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,n(e)+i),r(t,s(e)+a),t}},99049:(t,e,i)=>{var s=i(29568),n=i(70271),r=i(81711),o=i(74465);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,n(e)+i),r(t,s(e)+a),t}},67788:(t,e,i)=>{var s=i(70271),n=i(47196),r=i(74465),o=i(84349);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),r(t,s(e)+i),o(t,n(e)-a),t}},78170:(t,e,i)=>{var s=i(59994),n=i(47196),r=i(73174),o=i(28417);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,s(e)+i),r(t,n(e)-a),t}},54145:(t,e,i)=>{var s=i(40163),n=i(47196),r=i(73174),o=i(74465);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,s(e)-i),r(t,n(e)-a),t}},75548:(t,e,i)=>{var s=i(70271),n=i(47196),r=i(73174),o=i(19298);t.exports=function(t,e,i,a){return void 0===i&&(i=0),void 0===a&&(a=0),o(t,s(e)+i),r(t,n(e)-a),t}},86639:(t,e,i)=>{t.exports={BottomCenter:i(27118),BottomLeft:i(84469),BottomRight:i(51577),LeftBottom:i(90271),LeftCenter:i(30466),LeftTop:i(50087),QuickSet:i(82590),RightBottom:i(13555),RightCenter:i(99049),RightTop:i(67788),TopCenter:i(78170),TopLeft:i(54145),TopRight:i(75548)}},21843:(t,e,i)=>{var s=i(28417),n=i(81711);t.exports=function(t,e,i){return s(t,e),n(t,i)}},97328:t=>{t.exports=function(t){return t.y+t.height-t.height*t.originY}},7126:(t,e,i)=>{var s=i(97328),n=i(40163),r=i(70271),o=i(47196),a=i(74118);t.exports=function(t,e){void 0===e&&(e=new a);var i=n(t),h=o(t);return e.x=i,e.y=h,e.width=r(t)-i,e.height=s(t)-h,e}},59994:t=>{t.exports=function(t){return t.x-t.width*t.originX+.5*t.width}},29568:t=>{t.exports=function(t){return t.y-t.height*t.originY+.5*t.height}},40163:t=>{t.exports=function(t){return t.x-t.width*t.originX}},52088:t=>{t.exports=function(t){return t.width*t.originX}},23379:t=>{t.exports=function(t){return t.height*t.originY}},70271:t=>{t.exports=function(t){return t.x+t.width-t.width*t.originX}},47196:t=>{t.exports=function(t){return t.y-t.height*t.originY}},73174:t=>{t.exports=function(t,e){return t.y=e-t.height+t.height*t.originY,t}},28417:t=>{t.exports=function(t,e){var i=t.width*t.originX;return t.x=e+i-.5*t.width,t}},81711:t=>{t.exports=function(t,e){var i=t.height*t.originY;return t.y=e+i-.5*t.height,t}},74465:t=>{t.exports=function(t,e){return t.x=e+t.width*t.originX,t}},19298:t=>{t.exports=function(t,e){return t.x=e-t.width+t.width*t.originX,t}},84349:t=>{t.exports=function(t,e){return t.y=e+t.height*t.originY,t}},15252:(t,e,i)=>{t.exports={CenterOn:i(21843),GetBottom:i(97328),GetBounds:i(7126),GetCenterX:i(59994),GetCenterY:i(29568),GetLeft:i(40163),GetOffsetX:i(52088),GetOffsetY:i(23379),GetRight:i(70271),GetTop:i(47196),SetBottom:i(73174),SetCenterX:i(28417),SetCenterY:i(81711),SetLeft:i(74465),SetRight:i(19298),SetTop:i(84349)}},70616:t=>{t.exports={setCrisp:function(t){return["optimizeSpeed","-moz-crisp-edges","-o-crisp-edges","-webkit-optimize-contrast","optimize-contrast","crisp-edges","pixelated"].forEach((function(e){t.style["image-rendering"]=e})),t.style.msInterpolationMode="nearest-neighbor",t},setBicubic:function(t){return t.style["image-rendering"]="auto",t.style.msInterpolationMode="bicubic",t}}},61068:(t,e,i)=>{var s,n,r,o=i(86459),a=i(8213),h=[],l=!1;t.exports=(r=function(){var t=0;return h.forEach((function(e){e.parent&&t++})),t},{create2D:function(t,e,i){return s(t,e,i,o.CANVAS)},create:s=function(t,e,i,s,r){var u;void 0===e&&(e=1),void 0===i&&(i=1),void 0===s&&(s=o.CANVAS),void 0===r&&(r=!1);var c=n(s);return null===c?(c={parent:t,canvas:document.createElement("canvas"),type:s},s===o.CANVAS&&h.push(c),u=c.canvas):(c.parent=t,u=c.canvas),r&&(c.parent=u),u.width=e,u.height=i,l&&s===o.CANVAS&&a.disable(u.getContext("2d",{willReadFrequently:!1})),u},createWebGL:function(t,e,i){return s(t,e,i,o.WEBGL)},disableSmoothing:function(){l=!0},enableSmoothing:function(){l=!1},first:n=function(t){if(void 0===t&&(t=o.CANVAS),t===o.WEBGL)return null;for(var e=0;e{var e,i="";t.exports={disable:function(t){return""===i&&(i=e(t)),i&&(t[i]=!1),t},enable:function(t){return""===i&&(i=e(t)),i&&(t[i]=!0),t},getPrefix:e=function(t){for(var e=["i","webkitI","msI","mozI","oI"],i=0;i{t.exports=function(t,e){return void 0===e&&(e="none"),t.style.msTouchAction=e,t.style["ms-touch-action"]=e,t.style["touch-action"]=e,t}},36505:t=>{t.exports=function(t,e){void 0===e&&(e="none");return["-webkit-","-khtml-","-moz-","-ms-",""].forEach((function(i){t.style[i+"user-select"]=e})),t.style["-webkit-touch-callout"]=e,t.style["-webkit-tap-highlight-color"]="rgba(0, 0, 0, 0)",t}},23514:(t,e,i)=>{t.exports={CanvasInterpolation:i(70616),CanvasPool:i(61068),Smoothing:i(8213),TouchAction:i(59271),UserSelect:i(36505)}},27119:(t,e,i)=>{var s=i(56694),n=i(22946),r=i(5657),o=i(24650),a=i(68033),h=new s({initialize:function(t,e,i,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=255),this.r=0,this.g=0,this.b=0,this.a=255,this._h=0,this._s=0,this._v=0,this._locked=!1,this.gl=[0,0,0,1],this._color=0,this._color32=0,this._rgba="",this.setTo(t,e,i,s)},transparent:function(){return this._locked=!0,this.red=0,this.green=0,this.blue=0,this.alpha=0,this._locked=!1,this.update(!0)},setTo:function(t,e,i,s,n){return void 0===s&&(s=255),void 0===n&&(n=!0),this._locked=!0,this.red=t,this.green=e,this.blue=i,this.alpha=s,this._locked=!1,this.update(n)},setGLTo:function(t,e,i,s){return void 0===s&&(s=1),this._locked=!0,this.redGL=t,this.greenGL=e,this.blueGL=i,this.alphaGL=s,this._locked=!1,this.update(!0)},setFromRGB:function(t){return this._locked=!0,this.red=t.r,this.green=t.g,this.blue=t.b,t.hasOwnProperty("a")&&(this.alpha=t.a),this._locked=!1,this.update(!0)},setFromHSV:function(t,e,i){return o(t,e,i,this)},update:function(t){if(void 0===t&&(t=!1),this._locked)return this;var e=this.r,i=this.g,s=this.b,o=this.a;return this._color=n(e,i,s),this._color32=r(e,i,s,o),this._rgba="rgba("+e+","+i+","+s+","+o/255+")",t&&a(e,i,s,this),this},updateHSV:function(){var t=this.r,e=this.g,i=this.b;return a(t,e,i,this),this},clone:function(){return new h(this.r,this.g,this.b,this.a)},gray:function(t){return this.setTo(t,t,t)},random:function(t,e){void 0===t&&(t=0),void 0===e&&(e=255);var i=Math.floor(t+Math.random()*(e-t)),s=Math.floor(t+Math.random()*(e-t)),n=Math.floor(t+Math.random()*(e-t));return this.setTo(i,s,n)},randomGray:function(t,e){void 0===t&&(t=0),void 0===e&&(e=255);var i=Math.floor(t+Math.random()*(e-t));return this.setTo(i,i,i)},saturate:function(t){return this.s+=t/100,this},desaturate:function(t){return this.s-=t/100,this},lighten:function(t){return this.v+=t/100,this},darken:function(t){return this.v-=t/100,this},brighten:function(t){var e=this.r,i=this.g,s=this.b;return e=Math.max(0,Math.min(255,e-Math.round(-t/100*255))),i=Math.max(0,Math.min(255,i-Math.round(-t/100*255))),s=Math.max(0,Math.min(255,s-Math.round(-t/100*255))),this.setTo(e,i,s)},color:{get:function(){return this._color}},color32:{get:function(){return this._color32}},rgba:{get:function(){return this._rgba}},redGL:{get:function(){return this.gl[0]},set:function(t){this.gl[0]=Math.min(Math.abs(t),1),this.r=Math.floor(255*this.gl[0]),this.update(!0)}},greenGL:{get:function(){return this.gl[1]},set:function(t){this.gl[1]=Math.min(Math.abs(t),1),this.g=Math.floor(255*this.gl[1]),this.update(!0)}},blueGL:{get:function(){return this.gl[2]},set:function(t){this.gl[2]=Math.min(Math.abs(t),1),this.b=Math.floor(255*this.gl[2]),this.update(!0)}},alphaGL:{get:function(){return this.gl[3]},set:function(t){this.gl[3]=Math.min(Math.abs(t),1),this.a=Math.floor(255*this.gl[3]),this.update()}},red:{get:function(){return this.r},set:function(t){t=Math.floor(Math.abs(t)),this.r=Math.min(t,255),this.gl[0]=t/255,this.update(!0)}},green:{get:function(){return this.g},set:function(t){t=Math.floor(Math.abs(t)),this.g=Math.min(t,255),this.gl[1]=t/255,this.update(!0)}},blue:{get:function(){return this.b},set:function(t){t=Math.floor(Math.abs(t)),this.b=Math.min(t,255),this.gl[2]=t/255,this.update(!0)}},alpha:{get:function(){return this.a},set:function(t){t=Math.floor(Math.abs(t)),this.a=Math.min(t,255),this.gl[3]=t/255,this.update()}},h:{get:function(){return this._h},set:function(t){this._h=t,o(t,this._s,this._v,this)}},s:{get:function(){return this._s},set:function(t){this._s=t,o(this._h,t,this._v,this)}},v:{get:function(){return this._v},set:function(t){this._v=t,o(this._h,this._s,t,this)}}});t.exports=h},30245:(t,e,i)=>{var s=i(22946);t.exports=function(t){void 0===t&&(t=1024);var e,i=[],n=255,r=255,o=0,a=0;for(e=0;e<=n;e++)i.push({r:r,g:e,b:a,color:s(r,e,a)});for(o=255,e=n;e>=0;e--)i.push({r:e,g:o,b:a,color:s(e,o,a)});for(r=0,e=0;e<=n;e++,o--)i.push({r:r,g:o,b:e,color:s(r,o,e)});for(o=0,a=255,e=0;e<=n;e++,a--,r++)i.push({r:r,g:o,b:a,color:s(r,o,a)});if(1024===t)return i;var h=[],l=0,u=1024/t;for(e=0;e{t.exports=function(t){var e={r:t>>16&255,g:t>>8&255,b:255&t,a:255};return t>16777215&&(e.a=t>>>24),e}},25409:t=>{t.exports=function(t){var e=t.toString(16);return 1===e.length?"0"+e:e}},22946:t=>{t.exports=function(t,e,i){return t<<16|e<<8|i}},5657:t=>{t.exports=function(t,e,i,s){return s<<24|t<<16|e<<8|i}},74777:(t,e,i)=>{var s=i(27119),n=i(59998);t.exports=function(t,e,i){var r=i,o=i,a=i;if(0!==e){var h=i<.5?i*(1+e):i+e-i*e,l=2*i-h;r=n(l,h,t+1/3),o=n(l,h,t),a=n(l,h,t-1/3)}return(new s).setGLTo(r,o,a,1)}},89263:(t,e,i)=>{var s=i(24650);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}},24650:(t,e,i)=>{var s=i(22946);function n(t,e,i,s){var n=(t+6*e)%6,r=Math.min(n,4-n,1);return Math.round(255*(s-s*i*Math.max(0,r)))}t.exports=function(t,e,i,r){void 0===e&&(e=1),void 0===i&&(i=1);var o=n(5,t,e,i),a=n(3,t,e,i),h=n(1,t,e,i);return r?r.setTo?r.setTo(o,a,h,r.alpha,!0):(r.r=o,r.g=a,r.b=h,r.color=s(o,a,h),r):{r:o,g:a,b:h,color:s(o,a,h)}}},91487:(t,e,i)=>{var s=i(27119);t.exports=function(t){var e=new s;t=t.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,i,s){return e+e+i+i+s+s}));var i=/^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);if(i){var n=parseInt(i[1],16),r=parseInt(i[2],16),o=parseInt(i[3],16);e.setTo(n,r,o)}return e}},59998:t=>{t.exports=function(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}},74853:(t,e,i)=>{var s=i(27119),n=i(15978);t.exports=function(t){var e=n(t);return new s(e.r,e.g,e.b,e.a)}},15978:t=>{t.exports=function(t){return t>16777215?{a:t>>>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}}},53756:(t,e,i)=>{var s=i(42798),n=function(t,e,i,n,r,o,a,h){void 0===a&&(a=100),void 0===h&&(h=0);var l=h/a;return{r:s(t,n,l),g:s(e,r,l),b:s(i,o,l)}};t.exports={RGBWithRGB:n,ColorWithRGB:function(t,e,i,s,r,o){return void 0===r&&(r=100),void 0===o&&(o=0),n(t.r,t.g,t.b,e,i,s,r,o)},ColorWithColor:function(t,e,i,s){return void 0===i&&(i=100),void 0===s&&(s=0),n(t.r,t.g,t.b,e.r,e.g,e.b,i,s)}}},73904:(t,e,i)=>{var s=i(27119);t.exports=function(t){return new s(t.r,t.g,t.b,t.a)}},26841:(t,e,i)=>{var s=i(27119);t.exports=function(t){var e=new s,i=/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/.exec(t.toLowerCase());if(i){var n=parseInt(i[1],10),r=parseInt(i[2],10),o=parseInt(i[3],10),a=void 0!==i[4]?parseFloat(i[4]):1;e.setTo(n,r,o,255*a)}return e}},68033:t=>{t.exports=function(t,e,i,s){void 0===s&&(s={h:0,s:0,v:0}),t/=255,e/=255,i/=255;var n=Math.min(t,e,i),r=Math.max(t,e,i),o=r-n,a=0,h=0===r?0:o/r,l=r;return r!==n&&(r===t?a=(e-i)/o+(e{var s=i(25409);t.exports=function(t,e,i,n,r){return void 0===n&&(n=255),void 0===r&&(r="#"),"#"===r?"#"+((1<<24)+(t<<16)+(e<<8)+i).toString(16).slice(1,7):"0x"+s(n)+s(t)+s(e)+s(i)}},37243:(t,e,i)=>{var s=i(17489),n=i(27119);t.exports=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=255),new n(s(t,e),s(t,e),s(t,e))}},93222:(t,e,i)=>{var s=i(91487),n=i(74853),r=i(73904),o=i(26841);t.exports=function(t){switch(typeof t){case"string":return"rgb"===t.substr(0,3).toLowerCase()?o(t):s(t);case"number":return n(t);case"object":return r(t)}}},95509:(t,e,i)=>{var s=i(27119);s.ColorSpectrum=i(30245),s.ColorToRGBA=i(86672),s.ComponentToHex=i(25409),s.GetColor=i(22946),s.GetColor32=i(5657),s.HexStringToColor=i(91487),s.HSLToColor=i(74777),s.HSVColorWheel=i(89263),s.HSVToRGB=i(24650),s.HueToComponent=i(59998),s.IntegerToColor=i(74853),s.IntegerToRGB=i(15978),s.Interpolate=i(53756),s.ObjectToColor=i(73904),s.RandomRGB=i(37243),s.RGBStringToColor=i(26841),s.RGBToHSV=i(68033),s.RGBToString=i(4880),s.ValueToColor=i(93222),t.exports=s},24816:(t,e,i)=>{t.exports={Align:i(93545),BaseShader:i(31053),Bounds:i(15252),Canvas:i(23514),Color:i(95509),ColorMatrix:i(65246),Masks:i(93310),RGB:i(39298)}},76756:(t,e,i)=>{var s=i(56694),n=i(61286),r=new s({initialize:function(t,e,i,s,n,r){e||(e=t.sys.make.image({x:i,y:s,key:n,frame:r,add:!1})),this.bitmapMask=e,this.invertAlpha=!1,this.isStencil=!1},setBitmap:function(t){this.bitmapMask=t},preRenderWebGL:function(t,e,i){t.pipelines.BITMAPMASK_PIPELINE.beginMask(this,e,i)},postRenderWebGL:function(t,e,i){t.pipelines.BITMAPMASK_PIPELINE.endMask(this,e,i)},preRenderCanvas:function(){},postRenderCanvas:function(){},destroy:function(){this.bitmapMask=null}});n.register("bitmapMask",(function(t,e,i,s,n){return new r(this.scene,t,e,i,s,n)})),t.exports=r},63037:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e){this.geometryMask=e,this.invertAlpha=!1,this.isStencil=!0,this.level=0},setShape:function(t){return this.geometryMask=t,this},setInvertAlpha:function(t){return void 0===t&&(t=!0),this.invertAlpha=t,this},preRenderWebGL:function(t,e,i){var s=t.gl;t.flush(),0===t.maskStack.length&&(s.enable(s.STENCIL_TEST),s.clear(s.STENCIL_BUFFER_BIT),t.maskCount=0),t.currentCameraMask.mask!==this&&(t.currentMask.mask=this),t.maskStack.push({mask:this,camera:i}),this.applyStencil(t,i,!0),t.maskCount++},applyStencil:function(t,e,i){var s=t.gl,n=this.geometryMask,r=t.maskCount,o=255;s.colorMask(!1,!1,!1,!1),i?(s.stencilFunc(s.EQUAL,r,o),s.stencilOp(s.KEEP,s.KEEP,s.INCR),r++):(s.stencilFunc(s.EQUAL,r+1,o),s.stencilOp(s.KEEP,s.KEEP,s.DECR)),this.level=r,n.renderWebGL(t,n,e),t.flush(),s.colorMask(!0,!0,!0,!0),s.stencilOp(s.KEEP,s.KEEP,s.KEEP),this.invertAlpha?s.stencilFunc(s.NOTEQUAL,r,o):s.stencilFunc(s.EQUAL,r,o)},postRenderWebGL:function(t){var e=t.gl;t.maskStack.pop(),t.maskCount--,t.flush();var i=t.currentMask;if(0===t.maskStack.length)i.mask=null,e.disable(e.STENCIL_TEST);else{var s=t.maskStack[t.maskStack.length-1];s.mask.applyStencil(t,s.camera,!1),t.currentCameraMask.mask!==s.mask?(i.mask=s.mask,i.camera=s.camera):i.mask=null}},preRenderCanvas:function(t,e,i){var s=this.geometryMask;t.currentContext.save(),s.renderCanvas(t,s,i,null,null,!0),t.currentContext.clip()},postRenderCanvas:function(t){t.currentContext.restore()},destroy:function(){this.geometryMask=null}});t.exports=s},93310:(t,e,i)=>{t.exports={BitmapMask:i(76756),GeometryMask:i(63037)}},31053:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e,i,s){e&&""!==e||(e=["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")),i&&""!==i||(i=["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")),void 0===s&&(s=null),this.key=t,this.fragmentSrc=e,this.vertexSrc=i,this.uniforms=s}});t.exports=s},99584:t=>{t.exports=function(t,e){var i;if(e)"string"==typeof e?i=document.getElementById(e):"object"==typeof e&&1===e.nodeType&&(i=e);else if(t.parentElement||null===e)return t;return i||(i=document.body),i.appendChild(t),t}},85178:(t,e,i)=>{var s=i(99584);t.exports=function(t){var e=t.config;if(e.parent&&e.domCreateContainer){var i=document.createElement("div");i.style.cssText=["display: block;","width: "+t.scale.width+"px;","height: "+t.scale.height+"px;","padding: 0; margin: 0;","position: absolute;","overflow: hidden;","pointer-events: "+e.domPointerEvents+";","transform: scale(1);","transform-origin: left top;"].join(" "),t.domContainer=i,s(i,e.parent)}}},21546:(t,e,i)=>{var s=i(36580);t.exports=function(t){if("complete"!==document.readyState&&"interactive"!==document.readyState){var e=function(){document.removeEventListener("deviceready",e,!0),document.removeEventListener("DOMContentLoaded",e,!0),window.removeEventListener("load",e,!0),t()};document.body?s.cordova?document.addEventListener("deviceready",e,!1):(document.addEventListener("DOMContentLoaded",e,!0),window.addEventListener("load",e,!0)):window.setTimeout(e,20)}else t()}},74181:t=>{t.exports=function(t){if(!t)return window.innerHeight;var e=Math.abs(window.orientation),i={w:0,h:0},s=document.createElement("div");return s.setAttribute("style","position: fixed; height: 100vh; width: 0; top: 0"),document.documentElement.appendChild(s),i.w=90===e?s.offsetHeight:window.innerWidth,i.h=90===e?window.innerWidth:s.offsetHeight,document.documentElement.removeChild(s),s=null,90!==Math.abs(window.orientation)?i.h:i.w}},9229:(t,e,i)=>{var s=i(55301);t.exports=function(t,e){var i=window.screen,n=!!i&&(i.orientation||i.mozOrientation||i.msOrientation);return n&&"string"==typeof n.type?n.type:"string"==typeof n?n:"number"==typeof window.orientation?0===window.orientation||180===window.orientation?s.ORIENTATION.PORTRAIT:s.ORIENTATION.LANDSCAPE:window.matchMedia?window.matchMedia("(orientation: portrait)").matches?s.ORIENTATION.PORTRAIT:window.matchMedia("(orientation: landscape)").matches?s.ORIENTATION.LANDSCAPE:void 0:e>t?s.ORIENTATION.PORTRAIT:s.ORIENTATION.LANDSCAPE}},2893:t=>{t.exports=function(t){var e;return""!==t&&("string"==typeof t?e=document.getElementById(t):t&&1===t.nodeType&&(e=t)),e||(e=document.body),e}},89200:t=>{t.exports=function(t){var e="";try{if(window.DOMParser)e=(new DOMParser).parseFromString(t,"text/xml");else(e=new ActiveXObject("Microsoft.XMLDOM")).loadXML(t)}catch(t){e=null}return e&&e.documentElement&&!e.getElementsByTagName("parsererror").length?e:null}},55638:t=>{t.exports=function(t){t.parentNode&&t.parentNode.removeChild(t)}},27385:(t,e,i)=>{var s=i(56694),n=i(72283),r=new s({initialize:function(){this.isRunning=!1,this.callback=n,this.isSetTimeOut=!1,this.timeOutID=null,this.delay=0;var t=this;this.step=function e(i){t.callback(i),t.isRunning&&(t.timeOutID=window.requestAnimationFrame(e))},this.stepTimeout=function e(){t.isRunning&&(t.timeOutID=window.setTimeout(e,t.delay)),t.callback(window.performance.now())}},start:function(t,e,i){this.isRunning||(this.callback=t,this.isSetTimeOut=e,this.delay=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=n}});t.exports=r},3590:(t,e,i)=>{var s={AddToDOM:i(99584),DOMContentLoaded:i(21546),GetInnerHeight:i(74181),GetScreenOrientation:i(9229),GetTarget:i(2893),ParseXML:i(89200),RemoveFromDOM:i(55638),RequestAnimationFrame:i(27385)};t.exports=s},78491:(t,e,i)=>{var s=i(56694),n=i(6659),r=i(91963),o=new s({Extends:n,initialize:function(){n.call(this)},shutdown:function(){this.removeAllListeners()},destroy:function(){this.removeAllListeners()}});r.register("EventEmitter",o,"events"),t.exports=o},95146:(t,e,i)=>{t.exports={EventEmitter:i(78491)}},20170:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e){void 0===e&&(e=1),n.call(this,r.BARREL,t),this.amount=e}});t.exports=o},51182:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o,a,h){void 0===i&&(i=1),void 0===s&&(s=1),void 0===o&&(o=1),void 0===a&&(a=1),void 0===h&&(h=4),n.call(this,r.BLOOM,t),this.steps=h,this.offsetX=i,this.offsetY=s,this.blurStrength=o,this.strength=a,this.glcolor=[1,1,1],null!=e&&(this.color=e)},color:{get:function(){var t=this.glcolor;return(255*t[0]<<16)+(255*t[1]<<8)+(255*t[2]|0)},set:function(t){var e=this.glcolor;e[0]=(t>>16&255)/255,e[1]=(t>>8&255)/255,e[2]=(255&t)/255}}});t.exports=o},51498:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o,a,h){void 0===e&&(e=0),void 0===i&&(i=2),void 0===s&&(s=2),void 0===o&&(o=1),void 0===h&&(h=4),n.call(this,r.BLUR,t),this.quality=0,this.x=i,this.y=s,this.steps=h,this.strength=o,this.glcolor=[1,1,1],null!=a&&(this.color=a)},color:{get:function(){var t=this.glcolor;return(255*t[0]<<16)+(255*t[1]<<8)+(255*t[2]|0)},set:function(t){var e=this.glcolor;e[0]=(t>>16&255)/255,e[1]=(t>>8&255)/255,e[2]=(255&t)/255}}});t.exports=o},12042:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o,a,h,l){void 0===e&&(e=.5),void 0===i&&(i=1),void 0===s&&(s=.2),void 0===o&&(o=!1),void 0===a&&(a=1),void 0===h&&(h=1),void 0===l&&(l=1),n.call(this,r.BOKEH,t),this.radius=e,this.amount=i,this.contrast=s,this.isTiltShift=o,this.strength=l,this.blurX=a,this.blurY=h}});t.exports=o},69900:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o,a){void 0===e&&(e=8),void 0===o&&(o=1),void 0===a&&(a=.005),n.call(this,r.CIRCLE,t),this.scale=o,this.feather=a,this.thickness=e,this.glcolor=[1,.2,.7],this.glcolor2=[1,0,0,.4],null!=i&&(this.color=i),null!=s&&(this.backgroundColor=s)},color:{get:function(){var t=this.glcolor;return(255*t[0]<<16)+(255*t[1]<<8)+(255*t[2]|0)},set:function(t){var e=this.glcolor;e[0]=(t>>16&255)/255,e[1]=(t>>8&255)/255,e[2]=(255&t)/255}},backgroundColor:{get:function(){var t=this.glcolor2;return(255*t[0]<<16)+(255*t[1]<<8)+(255*t[2]|0)},set:function(t){var e=this.glcolor2;e[0]=(t>>16&255)/255,e[1]=(t>>8&255)/255,e[2]=(255&t)/255}}});t.exports=o},48991:(t,e,i)=>{var s=i(56694),n=i(65246),r=i(47406),o=new s({Extends:n,initialize:function(t){n.call(this),this.type=r.COLOR_MATRIX,this.gameObject=t,this.active=!0},destroy:function(){this.gameObject=null,this._matrix=null,this._data=null}});t.exports=o},47551:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e){this.type=t,this.gameObject=e,this.active=!0},setActive:function(t){return this.active=t,this},destroy:function(){this.gameObject=null,this.active=!1}});t.exports=s},47909:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s){void 0===e&&(e="__WHITE"),void 0===i&&(i=.005),void 0===s&&(s=.005),n.call(this,r.DISPLACEMENT,t),this.x=i,this.y=s,this.glTexture,this.setTexture(e)},setTexture:function(t){var e=this.gameObject.scene.sys.textures.getFrame(t);return e&&(this.glTexture=e.glTexture),this}});t.exports=o},18919:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o){void 0===i&&(i=4),void 0===s&&(s=0),void 0===o&&(o=!1),n.call(this,r.GLOW,t),this.outerStrength=i,this.innerStrength=s,this.knockout=o,this.glcolor=[1,1,1,1],void 0!==e&&(this.color=e)},color:{get:function(){var t=this.glcolor;return(255*t[0]<<16)+(255*t[1]<<8)+(255*t[2]|0)},set:function(t){var e=this.glcolor;e[0]=(t>>16&255)/255,e[1]=(t>>8&255)/255,e[2]=(255&t)/255}}});t.exports=o},62494:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o,a,h,l,u){void 0===s&&(s=.2),void 0===o&&(o=0),void 0===a&&(a=0),void 0===h&&(h=0),void 0===l&&(l=1),void 0===u&&(u=0),n.call(this,r.GRADIENT,t),this.alpha=s,this.size=u,this.fromX=o,this.fromY=a,this.toX=h,this.toY=l,this.glcolor1=[255,0,0],this.glcolor2=[0,255,0],null!=e&&(this.color1=e),null!=i&&(this.color2=i)},color1:{get:function(){var t=this.glcolor1;return(t[0]<<16)+(t[1]<<8)+(0|t[2])},set:function(t){var e=this.glcolor1;e[0]=t>>16&255,e[1]=t>>8&255,e[2]=255&t}},color2:{get:function(){var t=this.glcolor2;return(t[0]<<16)+(t[1]<<8)+(0|t[2])},set:function(t){var e=this.glcolor2;e[0]=t>>16&255,e[1]=t>>8&255,e[2]=255&t}}});t.exports=o},68897:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e){void 0===e&&(e=1),n.call(this,r.PIXELATE,t),this.amount=e}});t.exports=o},58575:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o,a,h,l){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=.1),void 0===o&&(o=1),void 0===h&&(h=6),void 0===l&&(l=1),n.call(this,r.SHADOW,t),this.x=e,this.y=i,this.decay=s,this.power=o,this.glcolor=[0,0,0,1],this.samples=h,this.intensity=l,void 0!==a&&(this.color=a)},color:{get:function(){var t=this.glcolor;return(255*t[0]<<16)+(255*t[1]<<8)+(255*t[2]|0)},set:function(t){var e=this.glcolor;e[0]=(t>>16&255)/255,e[1]=(t>>8&255)/255,e[2]=(255&t)/255}}});t.exports=o},33755:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o){void 0===e&&(e=.5),void 0===i&&(i=.5),void 0===s&&(s=3),void 0===o&&(o=!1),n.call(this,r.SHINE,t),this.speed=e,this.lineWidth=i,this.gradient=s,this.reveal=o}});t.exports=o},24949:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o){void 0===e&&(e=.5),void 0===i&&(i=.5),void 0===s&&(s=.5),void 0===o&&(o=.5),n.call(this,r.VIGNETTE,t),this.x=e,this.y=i,this.radius=s,this.strength=o}});t.exports=o},66241:(t,e,i)=>{var s=i(56694),n=i(47551),r=i(47406),o=new s({Extends:n,initialize:function(t,e,i,s,o){void 0===e&&(e=.1),void 0===i&&(i=0),void 0===s&&(s=0),void 0===o&&(o=!1),n.call(this,r.WIPE,t),this.progress=0,this.wipeWidth=e,this.direction=i,this.axis=s,this.reveal=o}});t.exports=o},47406:t=>{t.exports={GLOW:4,SHADOW:5,PIXELATE:6,VIGNETTE:7,SHINE:8,BLUR:9,GRADIENT:12,BLOOM:13,COLOR_MATRIX:14,CIRCLE:15,BARREL:16,DISPLACEMENT:17,WIPE:18,BOKEH:19}},96910:(t,e,i)=>{var s=i(98611),n=i(47406),r={Barrel:i(20170),Controller:i(47551),Bloom:i(51182),Blur:i(51498),Bokeh:i(12042),Circle:i(69900),ColorMatrix:i(48991),Displacement:i(47909),Glow:i(18919),Gradient:i(62494),Pixelate:i(68897),Shadow:i(58575),Shine:i(33755),Vignette:i(24949),Wipe:i(66241)};r=s(!1,r,n),t.exports=r},88933:(t,e,i)=>{var s=i(95723),n=i(20494);t.exports=function(t,e,i){e.x=n(i,"x",0),e.y=n(i,"y",0),e.depth=n(i,"depth",0),e.flipX=n(i,"flipX",!1),e.flipY=n(i,"flipY",!1);var r=n(i,"scale",null);"number"==typeof r?e.setScale(r):null!==r&&(e.scaleX=n(r,"x",1),e.scaleY=n(r,"y",1));var o=n(i,"scrollFactor",null);"number"==typeof o?e.setScrollFactor(o):null!==o&&(e.scrollFactorX=n(o,"x",1),e.scrollFactorY=n(o,"y",1)),e.rotation=n(i,"rotation",0);var a=n(i,"angle",null);null!==a&&(e.angle=a),e.alpha=n(i,"alpha",1);var h=n(i,"origin",null);if("number"==typeof h)e.setOrigin(h);else if(null!==h){var l=n(h,"x",.5),u=n(h,"y",.5);e.setOrigin(l,u)}return e.blendMode=n(i,"blendMode",s.NORMAL),e.visible=n(i,"visible",!0),n(i,"add",!0)&&t.sys.displayList.add(e),e.preUpdate&&t.sys.updateList.add(e),e}},32291:(t,e,i)=>{var s=i(20494);t.exports=function(t,e){var i=s(e,"anims",null);if(null===i)return t;if("string"==typeof i)t.anims.play(i);else if("object"==typeof i){var n=t.anims,r=s(i,"key",void 0);if(r){var o=s(i,"startFrame",void 0),a=s(i,"delay",0),h=s(i,"repeat",0),l=s(i,"repeatDelay",0),u=s(i,"yoyo",!1),c=s(i,"play",!1),d=s(i,"delayedPlay",0),f={key:r,delay:a,repeat:h,repeatDelay:l,yoyo:u,startFrame:o};c?n.play(f):d>0?n.playAfterDelay(f,d):n.load(f)}}return t}},91713:(t,e,i)=>{var s=i(56694),n=i(71207),r=i(91963),o=i(56631),a=i(7599),h=i(17922),l=new s({Extends:n,initialize:function(t){n.call(this,t),this.sortChildrenFlag=!1,this.scene=t,this.systems=t.sys,this.events=t.sys.events,this.addCallback=this.addChildCallback,this.removeCallback=this.removeChildCallback,this.events.once(a.BOOT,this.boot,this),this.events.on(a.START,this.start,this)},boot:function(){this.events.once(a.DESTROY,this.destroy,this)},addChildCallback:function(t){t.displayList&&t.displayList!==this&&t.removeFromDisplayList(),t.parentContainer&&t.parentContainer.remove(t),t.displayList||(this.queueDepthSort(),t.displayList=this,t.emit(o.ADDED_TO_SCENE,t,this.scene),this.events.emit(a.ADDED_TO_SCENE,t,this.scene))},removeChildCallback:function(t){this.queueDepthSort(),t.displayList=null,t.emit(o.REMOVED_FROM_SCENE,t,this.scene),this.events.emit(a.REMOVED_FROM_SCENE,t,this.scene)},start:function(){this.events.once(a.SHUTDOWN,this.shutdown,this)},queueDepthSort:function(){this.sortChildrenFlag=!0},depthSort:function(){this.sortChildrenFlag&&(h(this.list,this.sortByDepth),this.sortChildrenFlag=!1)},sortByDepth:function(t,e){return t._depth-e._depth},getChildren:function(){return this.list},shutdown:function(){for(var t=this.list;t.length;)t[0].destroy(!0);this.events.off(a.SHUTDOWN,this.shutdown,this)},destroy:function(){this.shutdown(),this.events.off(a.START,this.start,this),this.scene=null,this.systems=null,this.events=null}});r.register("DisplayList",l,"displayList"),t.exports=l},89980:(t,e,i)=>{var s=i(56694),n=i(48129),r=i(81078),o=i(6659),a=i(56631),h=i(7599),l=new s({Extends:o,initialize:function(t,e){o.call(this),this.scene=t,this.displayList=null,this.type=e,this.state=0,this.parentContainer=null,this.name="",this.active=!0,this.tabIndex=-1,this.data=null,this.renderFlags=15,this.cameraFilter=0,this.input=null,this.body=null,this.ignoreDestroy=!1,this.on(a.ADDED_TO_SCENE,this.addedToScene,this),this.on(a.REMOVED_FROM_SCENE,this.removedFromScene,this),t.sys.queueDepthSort()},setActive:function(t){return this.active=t,this},setName:function(t){return this.name=t,this},setState:function(t){return this.state=t,this},setDataEnabled:function(){return this.data||(this.data=new r(this)),this},setData:function(t,e){return this.data||(this.data=new r(this)),this.data.set(t,e),this},incData:function(t,e){return this.data||(this.data=new r(this)),this.data.inc(t,e),this},toggleData:function(t){return this.data||(this.data=new r(this)),this.data.toggle(t),this},getData:function(t){return this.data||(this.data=new r(this)),this.data.get(t)},setInteractive:function(t,e,i){return this.scene.sys.input.enable(this,t,e,i),this},disableInteractive:function(){return this.scene.sys.input.disable(this),this},removeInteractive:function(){return this.scene.sys.input.clear(this),this.input=void 0,this},addedToScene:function(){},removedFromScene:function(){},update:function(){},toJSON:function(){return n(this)},willRender:function(t){return!(!(!this.displayList||!this.displayList.active||this.displayList.willRender(t))||l.RENDER_MASK!==this.renderFlags||0!==this.cameraFilter&&this.cameraFilter&t.id)},getIndexList:function(){for(var t=this,e=this.parentContainer,i=[];e&&(i.unshift(e.getIndex(t)),t=e,e.parentContainer);)e=e.parentContainer;return this.displayList?i.unshift(this.displayList.getIndex(t)):i.unshift(this.scene.sys.displayList.getIndex(t)),i},addToDisplayList:function(t){return void 0===t&&(t=this.scene.sys.displayList),this.displayList&&this.displayList!==t&&this.removeFromDisplayList(),t.exists(this)||(this.displayList=t,t.add(this,!0),t.queueDepthSort(),this.emit(a.ADDED_TO_SCENE,this,this.scene),t.events.emit(h.ADDED_TO_SCENE,this,this.scene)),this},addToUpdateList:function(){return this.scene&&this.preUpdate&&this.scene.sys.updateList.add(this),this},removeFromDisplayList:function(){var t=this.displayList||this.scene.sys.displayList;return t&&t.exists(this)&&(t.remove(this,!0),t.queueDepthSort(),this.displayList=null,this.emit(a.REMOVED_FROM_SCENE,this,this.scene),t.events.emit(h.REMOVED_FROM_SCENE,this,this.scene)),this},removeFromUpdateList:function(){return this.scene&&this.preUpdate&&this.scene.sys.updateList.remove(this),this},destroy:function(t){this.scene&&!this.ignoreDestroy&&(void 0===t&&(t=!1),this.preDestroy&&this.preDestroy.call(this),this.emit(a.DESTROY,this,t),this.removeAllListeners(),this.postPipelines&&this.resetPostPipeline(!0),this.removeFromDisplayList(),this.removeFromUpdateList(),this.input&&(this.scene.sys.input.clear(this),this.input=void 0),this.data&&(this.data.destroy(),this.data=void 0),this.body&&(this.body.destroy(),this.body=void 0),this.preFX&&(this.preFX.destroy(),this.preFX=void 0),this.postFX&&(this.postFX.destroy(),this.postFX=void 0),this.active=!1,this.visible=!1,this.scene=void 0,this.parentContainer=void 0)}});l.RENDER_MASK=15,t.exports=l},99325:(t,e,i)=>{var s=i(56694),n=i(91963),r=i(7599),o=new s({initialize:function(t){this.scene=t,this.systems=t.sys,this.events=t.sys.events,this.displayList,this.updateList,this.events.once(r.BOOT,this.boot,this),this.events.on(r.START,this.start,this)},boot:function(){this.displayList=this.systems.displayList,this.updateList=this.systems.updateList,this.events.once(r.DESTROY,this.destroy,this)},start:function(){this.events.once(r.SHUTDOWN,this.shutdown,this)},shutdown:function(){this.events.off(r.SHUTDOWN,this.shutdown,this)},destroy:function(){this.shutdown(),this.events.off(r.START,this.start,this),this.scene=null,this.systems=null,this.events=null,this.displayList=null,this.updateList=null}});o.register=function(t,e){o.prototype.hasOwnProperty(t)||(o.prototype[t]=e)},o.remove=function(t){o.prototype.hasOwnProperty(t)&&delete o.prototype[t]},n.register("GameObjectCreator",o,"make"),t.exports=o},61286:(t,e,i)=>{var s=i(56694),n=i(91963),r=i(7599),o=new s({initialize:function(t){this.scene=t,this.systems=t.sys,this.events=t.sys.events,this.displayList,this.updateList,this.events.once(r.BOOT,this.boot,this),this.events.on(r.START,this.start,this)},boot:function(){this.displayList=this.systems.displayList,this.updateList=this.systems.updateList,this.events.once(r.DESTROY,this.destroy,this)},start:function(){this.events.once(r.SHUTDOWN,this.shutdown,this)},existing:function(t){return(t.renderCanvas||t.renderWebGL)&&this.displayList.add(t),t.preUpdate&&this.updateList.add(t),t},shutdown:function(){this.events.off(r.SHUTDOWN,this.shutdown,this)},destroy:function(){this.shutdown(),this.events.off(r.START,this.start,this),this.scene=null,this.systems=null,this.events=null,this.displayList=null,this.updateList=null}});o.register=function(t,e){o.prototype.hasOwnProperty(t)||(o.prototype[t]=e)},o.remove=function(t){o.prototype.hasOwnProperty(t)&&delete o.prototype[t]},n.register("GameObjectFactory",o,"add"),t.exports=o},73329:(t,e,i)=>{var s=i(69360),n=new s,r=new s,o=new s,a={camera:n,sprite:r,calc:o};t.exports=function(t,e,i){var s=n,h=r,l=o;return h.applyITRS(t.x,t.y,t.rotation,t.scaleX,t.scaleY),s.copyFrom(e.matrix),i?(s.multiplyWithOffset(i,-e.scrollX*t.scrollFactorX,-e.scrollY*t.scrollFactorY),h.e=t.x,h.f=t.y):(h.e-=e.scrollX*t.scrollFactorX,h.f-=e.scrollY*t.scrollFactorY),s.multiply(h,l),a}},92034:(t,e,i)=>{var s=i(56694),n=i(74623),r=i(91963),o=i(7599),a=new s({Extends:n,initialize:function(t){n.call(this),this.checkQueue=!0,this.scene=t,this.systems=t.sys,t.sys.events.once(o.BOOT,this.boot,this),t.sys.events.on(o.START,this.start,this)},boot:function(){this.systems.events.once(o.DESTROY,this.destroy,this)},start:function(){var t=this.systems.events;t.on(o.PRE_UPDATE,this.update,this),t.on(o.UPDATE,this.sceneUpdate,this),t.once(o.SHUTDOWN,this.shutdown,this)},sceneUpdate:function(t,e){for(var i=this._active,s=i.length,n=0;n{t.exports=function(t,e,i,s,n,r,o,a,h,l,u,c,d,f,p){var v=i.x-e.displayOriginX+n,g=i.y-e.displayOriginY+r,m=v+i.w,y=g+i.h,x=o.getXRound(v,g,a),T=o.getYRound(v,g,a),w=o.getXRound(v,y,a),b=o.getYRound(v,y,a),S=o.getXRound(m,y,a),E=o.getYRound(m,y,a),A=o.getXRound(m,g,a),C=o.getYRound(m,g,a);t.batchQuad(e,x,T,w,b,S,E,A,C,s.u0,s.v0,s.u1,s.v1,h,l,u,c,d,f,p)}},82173:t=>{t.exports=function(t,e,i,s){if(void 0===i&&(i=!1),void 0===s)return s={local:{x:0,y:0,width:0,height:0},global:{x:0,y:0,width:0,height:0},lines:{shortest:0,longest:0,lengths:null,height:0},wrappedText:"",words:[],characters:[],scaleX:0,scaleY:0};var n,r,o,a,h=t.text,l=h.length,u=t.maxWidth,c=t.wordWrapCharCode,d=Number.MAX_VALUE,f=Number.MAX_VALUE,p=0,v=0,g=t.fontData.chars,m=t.fontData.lineHeight,y=t.letterSpacing,x=t.lineSpacing,T=0,w=0,b=0,S=null,E=t._align,A=0,C=0,_=t.fontSize/t.fontData.size,M=_*t.scaleX,P=_*t.scaleY,R=null,O=0,L=[],F=Number.MAX_VALUE,D=0,I=0,k=0,B=[],N=[],X=null;if(u>0){for(n=0;nu||H-z>u?(G.push(V.i-1),V.cr?(G.push(V.i+V.word.length),z=0,Y=null):Y=V):V.cr&&(G.push(V.i+V.word.length),z=0,Y=null)}for(n=G.length-1;n>=0;n--)r=h,o=G[n],a="\n",h=r.substr(0,o)+a+r.substr(o+1);s.wrappedText=h,l=h.length,B=[],X=null}var j=0;for(n=0;nA&&(d=A),f>C&&(f=C);var K=A+S.xAdvance,Z=C+m;pD&&(D=k),kD&&(D=k),k0)for(var Q=0;Q{var s=i(31476);t.exports=function(t,e,i,n,r,o,a){var h=t.sys.textures.get(i),l=h.get(n),u=t.sys.cache.xml.get(r);if(l&&u){var c=s(u,l,o,a,h);return t.sys.cache.bitmapFont.add(e,{data:c,texture:i,frame:n,fromAtlas:!0}),!0}return!1}},39860:(t,e,i)=>{var s=i(10850);t.exports=function(t,e){var i=e.width,n=e.height,r=Math.floor(i/2),o=Math.floor(n/2),a=s(e,"chars","");if(""!==a){var h=s(e,"image",""),l=t.sys.textures.getFrame(h),u=l.cutX,c=l.cutY,d=l.source.width,f=l.source.height,p=s(e,"offset.x",0),v=s(e,"offset.y",0),g=s(e,"spacing.x",0),m=s(e,"spacing.y",0),y=s(e,"lineSpacing",0),x=s(e,"charsPerRow",null);null===x&&(x=d/i)>a.length&&(x=a.length);for(var T=p,w=v,b={retroFont:!0,font:h,size:i,lineHeight:n+y,chars:{}},S=0,E=0;E{function e(t,e){return parseInt(t.getAttribute(e),10)}t.exports=function(t,i,s,n,r){void 0===s&&(s=0),void 0===n&&(n=0);var o=i.cutX,a=i.cutY,h=i.source.width,l=i.source.height,u=i.sourceIndex,c={},d=t.getElementsByTagName("info")[0],f=t.getElementsByTagName("common")[0];c.font=d.getAttribute("face"),c.size=e(d,"size"),c.lineHeight=e(f,"lineHeight")+n,c.chars={};var p=t.getElementsByTagName("char"),v=void 0!==i&&i.trimmed;if(v)var g=i.height,m=i.width;for(var y=0;y{var s=i(66863),n=i(98611),r={Parse:i(39860)};r=n(!1,r,s),t.exports=r},66863:t=>{t.exports={TEXT_SET1:" !\"#$%&'()*+,-./0123456789:;<=>?@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"}},13468:(t,e,i)=>{var s=i(44616),n=i(56694),r=i(88899),o=new n({Extends:s,Mixins:[r],initialize:function(t,e,i,n,r,o,a){s.call(this,t,e,i,n,r,o,a),this.type="DynamicBitmapText",this.scrollX=0,this.scrollY=0,this.cropWidth=0,this.cropHeight=0,this.displayCallback,this.callbackData={parent:this,color:0,tint:{topLeft:0,topRight:0,bottomLeft:0,bottomRight:0},index:0,charCode:0,x:0,y:0,scale:0,rotation:0,data:0}},setSize:function(t,e){return this.cropWidth=t,this.cropHeight=e,this},setDisplayCallback:function(t){return this.displayCallback=t,this},setScrollX:function(t){return this.scrollX=t,this},setScrollY:function(t){return this.scrollY=t,this}});t.exports=o},93438:(t,e,i)=>{var s=i(49584);t.exports=function(t,e,i,n){var r=e._text,o=r.length,a=t.currentContext;if(0!==o&&s(t,a,e,i,n)){i.addToRenderList(e);var h=e.fromAtlas?e.frame:e.texture.frames.__BASE,l=e.displayCallback,u=e.callbackData,c=e.fontData.chars,d=e.fontData.lineHeight,f=e._letterSpacing,p=0,v=0,g=0,m=null,y=0,x=0,T=0,w=0,b=0,S=0,E=null,A=0,C=e.frame.source.image,_=h.cutX,M=h.cutY,P=0,R=0,O=e._fontSize/e.fontData.size,L=e._align,F=0,D=0;e.getTextBounds(!1);var I=e._bounds.lines;1===L?D=(I.longest-I.lengths[0])/2:2===L&&(D=I.longest-I.lengths[0]),a.translate(-e.displayOriginX,-e.displayOriginY);var k=i.roundPixels;e.cropWidth>0&&e.cropHeight>0&&(a.beginPath(),a.rect(0,0,e.cropWidth,e.cropHeight),a.clip());for(var B=0;B{var s=i(13468),n=i(88933),r=i(99325),o=i(20494);r.register("dynamicBitmapText",(function(t,e){void 0===t&&(t={});var i=o(t,"font",""),r=o(t,"text",""),a=o(t,"size",!1),h=new s(this.scene,0,0,i,r,a);return void 0!==e&&(t.add=e),n(this.scene,h,t),h}))},94145:(t,e,i)=>{var s=i(13468);i(61286).register("dynamicBitmapText",(function(t,e,i,n,r){return this.displayList.add(new s(this.scene,t,e,i,n,r))}))},88899:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(16873),r=i(93438),t.exports={renderWebGL:n,renderCanvas:r}},16873:(t,e,i)=>{var s=i(73329),n=i(69360),r=i(75512),o=new n;t.exports=function(t,e,i,n){var a=e.text,h=a.length;if(0!==h){i.addToRenderList(e);var l=t.pipelines.set(e.pipeline,e),u=s(e,i,n);t.pipelines.preBatch(e);var c=u.sprite,d=u.calc,f=o,p=e.cropWidth>0||e.cropHeight>0;p&&(l.flush(),t.pushScissor(d.tx,d.ty,e.cropWidth*d.scaleX,e.cropHeight*d.scaleY));var v,g,m=e.frame.glTexture,y=e.tintFill,x=r.getTintAppendFloatAlpha(e.tintTopLeft,i.alpha*e._alphaTL),T=r.getTintAppendFloatAlpha(e.tintTopRight,i.alpha*e._alphaTR),w=r.getTintAppendFloatAlpha(e.tintBottomLeft,i.alpha*e._alphaBL),b=r.getTintAppendFloatAlpha(e.tintBottomRight,i.alpha*e._alphaBR),S=l.setGameObject(e),E=0,A=0,C=0,_=0,M=e.letterSpacing,P=0,R=0,O=e.scrollX,L=e.scrollY,F=e.fontData,D=F.chars,I=F.lineHeight,k=e.fontSize/F.size,B=0,N=e._align,X=0,U=0,Y=e.getTextBounds(!1);e.maxWidth>0&&(h=(a=Y.wrappedText).length);var z=e._bounds.lines;1===N?U=(z.longest-z.lengths[0])/2:2===N&&(U=z.longest-z.lengths[0]);for(var G=i.roundPixels,V=e.displayCallback,W=e.callbackData,H=0;H{var s=i(56694),n=i(82897),r=i(64937),o=i(89980),a=i(82173),h=i(68298),l=i(31476),u=i(74118),c=i(84557),d=new s({Extends:o,Mixins:[r.Alpha,r.BlendMode,r.Depth,r.GetBounds,r.Mask,r.Origin,r.Pipeline,r.PostPipeline,r.ScrollFactor,r.Texture,r.Tint,r.Transform,r.Visible,c],initialize:function(t,e,i,s,n,r,h){void 0===n&&(n=""),void 0===h&&(h=0),o.call(this,t,"BitmapText"),this.font=s;var l=this.scene.sys.cache.bitmapFont.get(s);l||console.warn("Invalid BitmapText key: "+s),this.fontData=l.data,this._text="",this._fontSize=r||this.fontData.size,this._letterSpacing=0,this._lineSpacing=0,this._align=h,this._bounds=a(),this._dirty=!0,this._maxWidth=0,this.wordWrapCharCode=32,this.charColors=[],this.dropShadowX=0,this.dropShadowY=0,this.dropShadowColor=0,this.dropShadowAlpha=.5,this.fromAtlas=l.fromAtlas,this.setTexture(l.texture,l.frame),this.setPosition(e,i),this.setOrigin(0,0),this.initPipeline(),this.initPostPipeline(),this.setText(n)},setLeftAlign:function(){return this._align=d.ALIGN_LEFT,this._dirty=!0,this},setCenterAlign:function(){return this._align=d.ALIGN_CENTER,this._dirty=!0,this},setRightAlign:function(){return this._align=d.ALIGN_RIGHT,this._dirty=!0,this},setFontSize:function(t){return this._fontSize=t,this._dirty=!0,this},setLetterSpacing:function(t){return void 0===t&&(t=0),this._letterSpacing=t,this._dirty=!0,this},setLineSpacing:function(t){return void 0===t&&(t=0),this.lineSpacing=t,this},setText:function(t){return t||0===t||(t=""),Array.isArray(t)&&(t=t.join("\n")),t!==this.text&&(this._text=t.toString(),this._dirty=!0,this.updateDisplayOrigin()),this},setDropShadow:function(t,e,i,s){return void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=.5),this.dropShadowX=t,this.dropShadowY=e,this.dropShadowColor=i,this.dropShadowAlpha=s,this},setCharacterTint:function(t,e,i,s,r,o,a){void 0===t&&(t=0),void 0===e&&(e=1),void 0===i&&(i=!1),void 0===s&&(s=-1),void 0===r&&(r=s,o=s,a=s);var h=this.text.length;-1===e&&(e=h),t<0&&(t=h+t),t=n(t,0,h-1);for(var l=n(t+e,t,h),u=this.charColors,c=t;c{var s=i(49584);t.exports=function(t,e,i,n){var r=e._text,o=r.length,a=t.currentContext;if(0!==o&&s(t,a,e,i,n)){i.addToRenderList(e);var h=e.fromAtlas?e.frame:e.texture.frames.__BASE,l=e.fontData.chars,u=e.fontData.lineHeight,c=e._letterSpacing,d=e._lineSpacing,f=0,p=0,v=0,g=null,m=0,y=0,x=0,T=0,w=0,b=0,S=null,E=0,A=h.source.image,C=h.cutX,_=h.cutY,M=e._fontSize/e.fontData.size,P=e._align,R=0,O=0,L=e.getTextBounds(!1);e.maxWidth>0&&(o=(r=L.wrappedText).length);var F=e._bounds.lines;1===P?O=(F.longest-F.lengths[0])/2:2===P&&(O=F.longest-F.lengths[0]),a.translate(-e.displayOriginX,-e.displayOriginY);for(var D=i.roundPixels,I=0;I{var s=i(44616),n=i(88933),r=i(99325),o=i(20494),a=i(10850);r.register("bitmapText",(function(t,e){void 0===t&&(t={});var i=a(t,"font",""),r=o(t,"text",""),h=o(t,"size",!1),l=a(t,"align",0),u=new s(this.scene,0,0,i,r,h,l);return void 0!==e&&(t.add=e),n(this.scene,u,t),u}))},21797:(t,e,i)=>{var s=i(44616);i(61286).register("bitmapText",(function(t,e,i,n,r,o){return this.displayList.add(new s(this.scene,t,e,i,n,r,o))}))},84557:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(26372),r=i(97545),t.exports={renderWebGL:n,renderCanvas:r}},26372:(t,e,i)=>{var s=i(8810),n=i(73329),r=i(75512);t.exports=function(t,e,i,o){if(0!==e._text.length){i.addToRenderList(e);var a=t.pipelines.set(e.pipeline,e),h=n(e,i,o).calc;t.pipelines.preBatch(e);var l,u,c,d=i.roundPixels,f=i.alpha,p=e.charColors,v=e.tintFill,g=r.getTintAppendFloatAlpha,m=g(e.tintTopLeft,f*e._alphaTL),y=g(e.tintTopRight,f*e._alphaTR),x=g(e.tintBottomLeft,f*e._alphaBL),T=g(e.tintBottomRight,f*e._alphaBR),w=e.frame.glTexture,b=a.setGameObject(e),S=e.getTextBounds(!1).characters,E=e.dropShadowX,A=e.dropShadowY;if(0!==E||0!==A){var C=e.dropShadowColor,_=e.dropShadowAlpha,M=g(C,f*_*e._alphaTL),P=g(C,f*_*e._alphaTR),R=g(C,f*_*e._alphaBL),O=g(C,f*_*e._alphaBR);for(l=0;l{var s=i(92246),n=i(41664),r=i(56694),o=i(64937),a=i(82047),h=i(89980),l=i(71207),u=new r({Extends:h,Mixins:[o.Alpha,o.BlendMode,o.Depth,o.Mask,o.Pipeline,o.PostPipeline,o.ScrollFactor,o.Size,o.Texture,o.Transform,o.Visible,s],initialize:function(t,e,i,s,n){h.call(this,t,"Blitter"),this.setTexture(s,n),this.setPosition(e,i),this.initPipeline(),this.initPostPipeline(),this.children=new l,this.renderList=[],this.dirty=!1},create:function(t,e,i,s,r){void 0===s&&(s=!0),void 0===r&&(r=this.children.length),void 0===i?i=this.frame:i instanceof a||(i=this.texture.get(i));var o=new n(this,t,e,i,s);return this.children.addAt(o,r,!1),this.dirty=!0,o},createFromCallback:function(t,e,i,s){for(var n=this.createMultiple(e,i,s),r=0;r0},getRenderList:function(){return this.dirty&&(this.renderList=this.children.list.filter(this.childCanRender,this),this.dirty=!1),this.renderList},clear:function(){this.children.removeAll(),this.dirty=!0},preDestroy:function(){this.children.destroy(),this.renderList=[]}});t.exports=u},33177:t=>{t.exports=function(t,e,i,s){var n=e.getRenderList();if(0!==n.length){var r=t.currentContext,o=i.alpha*e.alpha;if(0!==o){i.addToRenderList(e),r.globalCompositeOperation=t.blendModes[e.blendMode],r.imageSmoothingEnabled=!e.frame.source.scaleMode;var a=e.x-i.scrollX*e.scrollFactorX,h=e.y-i.scrollY*e.scrollFactorY;r.save(),s&&s.copyToContext(r);for(var l=i.roundPixels,u=0;u0&&p.height>0&&(r.save(),r.translate(c.x+a,c.y+h),r.scale(m,y),r.drawImage(f.source.image,p.x,p.y,p.width,p.height,v,g,p.width,p.height),r.restore())):(l&&(v=Math.round(v),g=Math.round(g)),p.width>0&&p.height>0&&r.drawImage(f.source.image,p.x,p.y,p.width,p.height,v+c.x+a,g+c.y+h,p.width,p.height)))}r.restore()}}}},68452:(t,e,i)=>{var s=i(52816),n=i(88933),r=i(99325),o=i(20494);r.register("blitter",(function(t,e){void 0===t&&(t={});var i=o(t,"key",null),r=o(t,"frame",null),a=new s(this.scene,0,0,i,r);return void 0!==e&&(t.add=e),n(this.scene,a,t),a}))},38906:(t,e,i)=>{var s=i(52816);i(61286).register("blitter",(function(t,e,i,n){return this.displayList.add(new s(this.scene,t,e,i,n))}))},92246:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(89165),r=i(33177),t.exports={renderWebGL:n,renderCanvas:r}},89165:(t,e,i)=>{var s=i(69360),n=i(75512),r=new s;t.exports=function(t,e,i,s){var o=e.getRenderList(),a=i.alpha*e.alpha;if(0!==o.length&&0!==a){i.addToRenderList(e);var h=t.pipelines.set(this.pipeline,e),l=i.scrollX*e.scrollFactorX,u=i.scrollY*e.scrollFactorY,c=r.copyFrom(i.matrix);s&&(c.multiplyWithOffset(s,-l,-u),l=0,u=0);var d=e.x-l,f=e.y-u,p=-1,v=i.roundPixels;t.pipelines.preBatch(e);for(var g=0;g{var s=i(56694),n=i(82047),r=new s({initialize:function(t,e,i,s,n){this.parent=t,this.x=e,this.y=i,this.frame=s,this.data={},this.tint=16777215,this._visible=n,this._alpha=1,this.flipX=!1,this.flipY=!1,this.hasTransformComponent=!0},setFrame:function(t){return void 0===t?this.frame=this.parent.frame:t instanceof n&&t.texture===this.parent.texture?this.frame=t:this.frame=this.parent.texture.get(t),this},resetFlip:function(){return this.flipX=!1,this.flipY=!1,this},reset:function(t,e,i){return this.x=t,this.y=e,this.flipX=!1,this.flipY=!1,this._alpha=1,this._visible=!0,this.parent.dirty=!0,i&&this.setFrame(i),this},setPosition:function(t,e){return this.x=t,this.y=e,this},setFlipX:function(t){return this.flipX=t,this},setFlipY:function(t){return this.flipY=t,this},setFlip:function(t,e){return this.flipX=t,this.flipY=e,this},setVisible:function(t){return this.visible=t,this},setAlpha:function(t){return this.alpha=t,this},setTint:function(t){return this.tint=t,this},destroy:function(){this.parent.dirty=!0,this.parent.children.remove(this),this.parent=void 0,this.frame=void 0,this.data=void 0},visible:{get:function(){return this._visible},set:function(t){this.parent.dirty|=this._visible!==t,this._visible=t}},alpha:{get:function(){return this._alpha},set:function(t){this.parent.dirty|=this._alpha>0!=t>0,this._alpha=t}}});t.exports=r},97123:(t,e,i)=>{var s=i(82897),n={_alpha:1,_alphaTL:1,_alphaTR:1,_alphaBL:1,_alphaBR:1,clearAlpha:function(){return this.setAlpha(1)},setAlpha:function(t,e,i,n){return void 0===t&&(t=1),void 0===e?this.alpha=t:(this._alphaTL=s(t,0,1),this._alphaTR=s(e,0,1),this._alphaBL=s(i,0,1),this._alphaBR=s(n,0,1)),this},alpha:{get:function(){return this._alpha},set:function(t){var e=s(t,0,1);this._alpha=e,this._alphaTL=e,this._alphaTR=e,this._alphaBL=e,this._alphaBR=e,0===e?this.renderFlags&=-3:this.renderFlags|=2}},alphaTopLeft:{get:function(){return this._alphaTL},set:function(t){var e=s(t,0,1);this._alphaTL=e,0!==e&&(this.renderFlags|=2)}},alphaTopRight:{get:function(){return this._alphaTR},set:function(t){var e=s(t,0,1);this._alphaTR=e,0!==e&&(this.renderFlags|=2)}},alphaBottomLeft:{get:function(){return this._alphaBL},set:function(t){var e=s(t,0,1);this._alphaBL=e,0!==e&&(this.renderFlags|=2)}},alphaBottomRight:{get:function(){return this._alphaBR},set:function(t){var e=s(t,0,1);this._alphaBR=e,0!==e&&(this.renderFlags|=2)}}};t.exports=n},15720:(t,e,i)=>{var s=i(82897),n={_alpha:1,clearAlpha:function(){return this.setAlpha(1)},setAlpha:function(t){return void 0===t&&(t=1),this.alpha=t,this},alpha:{get:function(){return this._alpha},set:function(t){var e=s(t,0,1);this._alpha=e,0===e?this.renderFlags&=-3:this.renderFlags|=2}}};t.exports=n},69732:(t,e,i)=>{var s=i(95723),n={_blendMode:s.NORMAL,blendMode:{get:function(){return this._blendMode},set:function(t){"string"==typeof t&&(t=s[t]),(t|=0)>=-1&&(this._blendMode=t)}},setBlendMode:function(t){return this.blendMode=t,this}};t.exports=n},28284:t=>{t.exports={width:0,height:0,displayWidth:{get:function(){return this.scaleX*this.width},set:function(t){this.scaleX=t/this.width}},displayHeight:{get:function(){return this.scaleY*this.height},set:function(t){this.scaleY=t/this.height}},setSize:function(t,e){return this.width=t,this.height=e,this},setDisplaySize:function(t,e){return this.displayWidth=t,this.displayHeight=e,this}}},85293:t=>{var e={texture:null,frame:null,isCropped:!1,setCrop:function(t,e,i,s){if(void 0===t)this.isCropped=!1;else if(this.frame){if("number"==typeof t)this.frame.setCropUVs(this._crop,t,e,i,s,this.flipX,this.flipY);else{var n=t;this.frame.setCropUVs(this._crop,n.x,n.y,n.width,n.height,this.flipX,this.flipY)}this.isCropped=!0}return this},resetCropObject:function(){return{u0:0,v0:0,u1:0,v1:0,width:0,height:0,x:0,y:0,flipX:!1,flipY:!1,cx:0,cy:0,cw:0,ch:0}}};t.exports=e},14975:t=>{var e={_depth:0,depth:{get:function(){return this._depth},set:function(t){this.displayList&&this.displayList.queueDepthSort(),this._depth=t}},setDepth:function(t){return void 0===t&&(t=0),this.depth=t,this}};t.exports=e},88677:(t,e,i)=>{var s=i(56694),n=i(96910),r=i(72677),o=new s({initialize:function(t,e){this.gameObject=t,this.isPost=e,this.enabled=!1,this.list=[],this.padding=0},setPadding:function(t){return void 0===t&&(t=0),this.padding=t,this.gameObject},onFXCopy:function(){},onFX:function(){},enable:function(t){if(!this.isPost){var e=this.gameObject.scene.sys.renderer;e&&e.pipelines?(this.gameObject.pipeline=e.pipelines.FX_PIPELINE,void 0!==t&&(this.padding=t),this.enabled=!0):this.enabled=!1}},clear:function(){if(this.isPost)this.gameObject.resetPostPipeline(!0);else{for(var t=this.list,e=0;e{t.exports={flipX:!1,flipY:!1,toggleFlipX:function(){return this.flipX=!this.flipX,this},toggleFlipY:function(){return this.flipY=!this.flipY,this},setFlipX:function(t){return this.flipX=t,this},setFlipY:function(t){return this.flipY=t,this},setFlip:function(t,e){return this.flipX=t,this.flipY=e,this},resetFlip:function(){return this.flipX=!1,this.flipY=!1,this}}},80693:(t,e,i)=>{var s=i(74118),n=i(2386),r=i(93736),o={prepareBoundsOutput:function(t,e){(void 0===e&&(e=!1),0!==this.rotation&&n(t,this.x,this.y,this.rotation),e&&this.parentContainer)&&this.parentContainer.getBoundsTransformMatrix().transformPoint(t.x,t.y,t);return t},getCenter:function(t,e){return void 0===t&&(t=new r),t.x=this.x-this.displayWidth*this.originX+this.displayWidth/2,t.y=this.y-this.displayHeight*this.originY+this.displayHeight/2,this.prepareBoundsOutput(t,e)},getTopLeft:function(t,e){return t||(t=new r),t.x=this.x-this.displayWidth*this.originX,t.y=this.y-this.displayHeight*this.originY,this.prepareBoundsOutput(t,e)},getTopCenter:function(t,e){return t||(t=new r),t.x=this.x-this.displayWidth*this.originX+this.displayWidth/2,t.y=this.y-this.displayHeight*this.originY,this.prepareBoundsOutput(t,e)},getTopRight:function(t,e){return t||(t=new r),t.x=this.x-this.displayWidth*this.originX+this.displayWidth,t.y=this.y-this.displayHeight*this.originY,this.prepareBoundsOutput(t,e)},getLeftCenter:function(t,e){return t||(t=new r),t.x=this.x-this.displayWidth*this.originX,t.y=this.y-this.displayHeight*this.originY+this.displayHeight/2,this.prepareBoundsOutput(t,e)},getRightCenter:function(t,e){return t||(t=new r),t.x=this.x-this.displayWidth*this.originX+this.displayWidth,t.y=this.y-this.displayHeight*this.originY+this.displayHeight/2,this.prepareBoundsOutput(t,e)},getBottomLeft:function(t,e){return t||(t=new r),t.x=this.x-this.displayWidth*this.originX,t.y=this.y-this.displayHeight*this.originY+this.displayHeight,this.prepareBoundsOutput(t,e)},getBottomCenter:function(t,e){return t||(t=new r),t.x=this.x-this.displayWidth*this.originX+this.displayWidth/2,t.y=this.y-this.displayHeight*this.originY+this.displayHeight,this.prepareBoundsOutput(t,e)},getBottomRight:function(t,e){return t||(t=new r),t.x=this.x-this.displayWidth*this.originX+this.displayWidth,t.y=this.y-this.displayHeight*this.originY+this.displayHeight,this.prepareBoundsOutput(t,e)},getBounds:function(t){var e,i,n,r,o,a,h,l;if(void 0===t&&(t=new s),this.parentContainer){var u=this.parentContainer.getBoundsTransformMatrix();this.getTopLeft(t),u.transformPoint(t.x,t.y,t),e=t.x,i=t.y,this.getTopRight(t),u.transformPoint(t.x,t.y,t),n=t.x,r=t.y,this.getBottomLeft(t),u.transformPoint(t.x,t.y,t),o=t.x,a=t.y,this.getBottomRight(t),u.transformPoint(t.x,t.y,t),h=t.x,l=t.y}else this.getTopLeft(t),e=t.x,i=t.y,this.getTopRight(t),n=t.x,r=t.y,this.getBottomLeft(t),o=t.x,a=t.y,this.getBottomRight(t),h=t.x,l=t.y;return t.x=Math.min(e,n,o,h),t.y=Math.min(i,r,a,l),t.width=Math.max(e,n,o,h)-t.x,t.height=Math.max(i,r,a,l)-t.y,t}};t.exports=o},39171:(t,e,i)=>{var s=i(76756),n=i(63037),r={mask:null,setMask:function(t){return this.mask=t,this},clearMask:function(t){return void 0===t&&(t=!1),t&&this.mask&&this.mask.destroy(),this.mask=null,this},createBitmapMask:function(t,e,i,n,r){return void 0===t&&(this.texture||this.shader||this.geom)&&(t=this),new s(this.scene,t,e,i,n,r)},createGeometryMask:function(t){return void 0!==t||"Graphics"!==this.type&&!this.geom||(t=this),new n(this.scene,t)}};t.exports=r},28072:t=>{var e={_originComponent:!0,originX:.5,originY:.5,_displayOriginX:0,_displayOriginY:0,displayOriginX:{get:function(){return this._displayOriginX},set:function(t){this._displayOriginX=t,this.originX=t/this.width}},displayOriginY:{get:function(){return this._displayOriginY},set:function(t){this._displayOriginY=t,this.originY=t/this.height}},setOrigin:function(t,e){return void 0===t&&(t=.5),void 0===e&&(e=t),this.originX=t,this.originY=e,this.updateDisplayOrigin()},setOriginFromFrame:function(){return this.frame&&this.frame.customPivot?(this.originX=this.frame.pivotX,this.originY=this.frame.pivotY,this.updateDisplayOrigin()):this.setOrigin()},setDisplayOrigin:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.displayOriginX=t,this.displayOriginY=e,this},updateDisplayOrigin:function(){return this._displayOriginX=this.originX*this.width,this._displayOriginY=this.originY*this.height,this}};t.exports=e},54211:(t,e,i)=>{var s=i(75606),n=i(63130),r=i(10850),o=i(55303),a=i(93736),h={path:null,rotateToPath:!1,pathRotationOffset:0,pathOffset:null,pathVector:null,pathDelta:null,pathTween:null,pathConfig:null,_prevDirection:o.PLAYING_FORWARD,setPath:function(t,e){void 0===e&&(e=this.pathConfig);var i=this.pathTween;return i&&i.isPlaying()&&i.stop(),this.path=t,e&&this.startFollow(e),this},setRotateToPath:function(t,e){return void 0===e&&(e=0),this.rotateToPath=t,this.pathRotationOffset=e,this},isFollowing:function(){var t=this.pathTween;return t&&t.isPlaying()},startFollow:function(t,e){void 0===t&&(t={}),void 0===e&&(e=0);var i=this.pathTween;i&&i.isPlaying()&&i.stop(),"number"==typeof t&&(t={duration:t}),t.from=r(t,"from",0),t.to=r(t,"to",1);var h=n(t,"positionOnPath",!1);this.rotateToPath=n(t,"rotateToPath",!1),this.pathRotationOffset=r(t,"rotationOffset",0);var l=r(t,"startAt",e);if(l&&(t.onStart=function(t){var e=t.data[0];e.progress=l,e.elapsed=e.duration*l;var i=e.ease(e.progress);e.current=e.start+(e.end-e.start)*i,e.setTargetValue()}),this.pathOffset||(this.pathOffset=new a(this.x,this.y)),this.pathVector||(this.pathVector=new a),this.pathDelta||(this.pathDelta=new a),this.pathDelta.reset(),t.persist=!0,this.pathTween=this.scene.sys.tweens.addCounter(t),this.path.getStartPoint(this.pathOffset),h&&(this.x=this.pathOffset.x,this.y=this.pathOffset.y),this.pathOffset.x=this.x-this.pathOffset.x,this.pathOffset.y=this.y-this.pathOffset.y,this._prevDirection=o.PLAYING_FORWARD,this.rotateToPath){var u=this.path.getPoint(.1);this.rotation=Math.atan2(u.y-this.y,u.x-this.x)+s(this.pathRotationOffset)}return this.pathConfig=t,this},pauseFollow:function(){var t=this.pathTween;return t&&t.isPlaying()&&t.pause(),this},resumeFollow:function(){var t=this.pathTween;return t&&t.isPaused()&&t.resume(),this},stopFollow:function(){var t=this.pathTween;return t&&t.isPlaying()&&t.stop(),this},pathUpdate:function(){var t=this.pathTween;if(t){var e=t.data[0],i=this.pathDelta,n=this.pathVector;if(i.copy(n).negate(),e.state===o.COMPLETE)return this.path.getPoint(e.end,n),i.add(n),n.add(this.pathOffset),void this.setPosition(n.x,n.y);if(e.state!==o.PLAYING_FORWARD&&e.state!==o.PLAYING_BACKWARD)return;this.path.getPoint(t.getValue(),n),i.add(n),n.add(this.pathOffset);var r=this.x,a=this.y;this.setPosition(n.x,n.y);var h=this.x-r,l=this.y-a;if(0===h&&0===l)return;if(e.state!==this._prevDirection)return void(this._prevDirection=e.state);this.rotateToPath&&(this.rotation=Math.atan2(l,h)+s(this.pathRotationOffset))}}};t.exports=h},58210:(t,e,i)=>{var s=i(28699),n={defaultPipeline:null,pipeline:null,pipelineData:null,initPipeline:function(t){this.pipelineData={};var e=this.scene.sys.renderer;if(!e)return!1;var i=e.pipelines;if(i){void 0===t&&(t=i.default);var s=i.get(t);if(s)return this.defaultPipeline=s,this.pipeline=s,!0}return!1},setPipeline:function(t,e,i){var n=this.scene.sys.renderer;if(!n)return this;var r=n.pipelines;if(r){var o=r.get(t);o&&(this.pipeline=o),e&&(this.pipelineData=i?s(e):e)}return this},setPipelineData:function(t,e){var i=this.pipelineData;return void 0===e?delete i[t]:i[t]=e,this},resetPipeline:function(t){return void 0===t&&(t=!1),this.pipeline=this.defaultPipeline,t&&(this.pipelineData={}),null!==this.pipeline},getPipelineName:function(){return this.pipeline.name}};t.exports=n},44086:(t,e,i)=>{var s=i(28699),n=i(88677),r=i(72677),o={hasPostPipeline:!1,postPipelines:null,postPipelineData:null,preFX:null,postFX:null,initPostPipeline:function(t){this.postPipelines=[],this.postPipelineData={},this.postFX=new n(this,!0),t&&(this.preFX=new n(this,!1))},setPostPipeline:function(t,e,i){var n=this.scene.sys.renderer;if(!n)return this;var r=n.pipelines;if(r){Array.isArray(t)||(t=[t]);for(var o=0;o0,this},setPostPipelineData:function(t,e){var i=this.postPipelineData;return void 0===e?delete i[t]:i[t]=e,this},getPostPipeline:function(t){for(var e="string"==typeof t,i=this.postPipelines,s=[],n=0;n=0;s--){var n=i[s];(e&&n.name===t||!e&&n===t)&&(n.destroy(),r(i,s))}return this.hasPostPipeline=this.postPipelines.length>0,this},clearFX:function(){return this.preFX&&this.preFX.clear(),this.postFX&&this.postFX.clear(),this}};t.exports=o},45900:t=>{var e={scrollFactorX:1,scrollFactorY:1,setScrollFactor:function(t,e){return void 0===e&&(e=t),this.scrollFactorX=t,this.scrollFactorY=e,this}};t.exports=e},31654:t=>{var e={_sizeComponent:!0,width:0,height:0,displayWidth:{get:function(){return Math.abs(this.scaleX*this.frame.realWidth)},set:function(t){this.scaleX=t/this.frame.realWidth}},displayHeight:{get:function(){return Math.abs(this.scaleY*this.frame.realHeight)},set:function(t){this.scaleY=t/this.frame.realHeight}},setSizeToFrame:function(t){t||(t=this.frame),this.width=t.realWidth,this.height=t.realHeight;var e=this.input;return e&&!e.customHitArea&&(e.hitArea.width=this.width,e.hitArea.height=this.height),this},setSize:function(t,e){return this.width=t,this.height=e,this},setDisplaySize:function(t,e){return this.displayWidth=t,this.displayHeight=e,this}};t.exports=e},82081:(t,e,i)=>{var s=i(82047),n={texture:null,frame:null,isCropped:!1,setTexture:function(t,e){return this.texture=this.scene.sys.textures.get(t),this.setFrame(e)},setFrame:function(t,e,i){return void 0===e&&(e=!0),void 0===i&&(i=!0),t instanceof s?(this.texture=this.scene.sys.textures.get(t.texture.key),this.frame=t):this.frame=this.texture.get(t),this.frame.cutWidth&&this.frame.cutHeight?this.renderFlags|=8:this.renderFlags&=-9,this._sizeComponent&&e&&this.setSizeToFrame(),this._originComponent&&i&&(this.frame.customPivot?this.setOrigin(this.frame.pivotX,this.frame.pivotY):this.updateDisplayOrigin()),this}};t.exports=n},21850:(t,e,i)=>{var s=i(82047),n={texture:null,frame:null,isCropped:!1,setCrop:function(t,e,i,s){if(void 0===t)this.isCropped=!1;else if(this.frame){if("number"==typeof t)this.frame.setCropUVs(this._crop,t,e,i,s,this.flipX,this.flipY);else{var n=t;this.frame.setCropUVs(this._crop,n.x,n.y,n.width,n.height,this.flipX,this.flipY)}this.isCropped=!0}return this},setTexture:function(t,e){return this.texture=this.scene.sys.textures.get(t),this.setFrame(e)},setFrame:function(t,e,i){return void 0===e&&(e=!0),void 0===i&&(i=!0),t instanceof s?(this.texture=this.scene.sys.textures.get(t.texture.key),this.frame=t):this.frame=this.texture.get(t),this.frame.cutWidth&&this.frame.cutHeight?this.renderFlags|=8:this.renderFlags&=-9,this._sizeComponent&&e&&this.setSizeToFrame(),this._originComponent&&i&&(this.frame.customPivot?this.setOrigin(this.frame.pivotX,this.frame.pivotY):this.updateDisplayOrigin()),this.isCropped&&this.frame.updateCropUVs(this._crop,this.flipX,this.flipY),this},resetCropObject:function(){return{u0:0,v0:0,u1:0,v1:0,width:0,height:0,x:0,y:0,flipX:!1,flipY:!1,cx:0,cy:0,cw:0,ch:0}}};t.exports=n},58072:t=>{var e={tintTopLeft:16777215,tintTopRight:16777215,tintBottomLeft:16777215,tintBottomRight:16777215,tintFill:!1,clearTint:function(){return this.setTint(16777215),this},setTint:function(t,e,i,s){return void 0===t&&(t=16777215),void 0===e&&(e=t,i=t,s=t),this.tintTopLeft=t,this.tintTopRight=e,this.tintBottomLeft=i,this.tintBottomRight=s,this.tintFill=!1,this},setTintFill:function(t,e,i,s){return this.setTint(t,e,i,s),this.tintFill=!0,this},tint:{set:function(t){this.setTint(t,t,t,t)}},isTinted:{get:function(){var t=16777215;return this.tintFill||this.tintTopLeft!==t||this.tintTopRight!==t||this.tintBottomLeft!==t||this.tintBottomRight!==t}}};t.exports=e},48129:t=>{t.exports=function(t){var e={name:t.name,type:t.type,x:t.x,y:t.y,depth:t.depth,scale:{x:t.scaleX,y:t.scaleY},origin:{x:t.originX,y:t.originY},flipX:t.flipX,flipY:t.flipY,rotation:t.rotation,alpha:t.alpha,visible:t.visible,blendMode:t.blendMode,textureKey:"",frameKey:"",data:{}};return t.texture&&(e.textureKey=t.texture.key,e.frameKey=t.frame.name),e}},56584:(t,e,i)=>{var s=i(83392),n=i(69360),r=i(64462),o=i(35786),a=i(62138),h=i(93736),l={hasTransformComponent:!0,_scaleX:1,_scaleY:1,_rotation:0,x:0,y:0,z:0,w:0,scale:{get:function(){return(this._scaleX+this._scaleY)/2},set:function(t){this._scaleX=t,this._scaleY=t,0===t?this.renderFlags&=-5:this.renderFlags|=4}},scaleX:{get:function(){return this._scaleX},set:function(t){this._scaleX=t,0===t?this.renderFlags&=-5:0!==this._scaleY&&(this.renderFlags|=4)}},scaleY:{get:function(){return this._scaleY},set:function(t){this._scaleY=t,0===t?this.renderFlags&=-5:0!==this._scaleX&&(this.renderFlags|=4)}},angle:{get:function(){return a(this._rotation*s.RAD_TO_DEG)},set:function(t){this.rotation=a(t)*s.DEG_TO_RAD}},rotation:{get:function(){return this._rotation},set:function(t){this._rotation=o(t)}},setPosition:function(t,e,i,s){return void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=0),void 0===s&&(s=0),this.x=t,this.y=e,this.z=i,this.w=s,this},copyPosition:function(t){return void 0!==t.x&&(this.x=t.x),void 0!==t.y&&(this.y=t.y),void 0!==t.z&&(this.z=t.z),void 0!==t.w&&(this.w=t.w),this},setRandomPosition:function(t,e,i,s){return void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=this.scene.sys.scale.width),void 0===s&&(s=this.scene.sys.scale.height),this.x=t+Math.random()*i,this.y=e+Math.random()*s,this},setRotation:function(t){return void 0===t&&(t=0),this.rotation=t,this},setAngle:function(t){return void 0===t&&(t=0),this.angle=t,this},setScale:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=t),this.scaleX=t,this.scaleY=e,this},setX:function(t){return void 0===t&&(t=0),this.x=t,this},setY:function(t){return void 0===t&&(t=0),this.y=t,this},setZ:function(t){return void 0===t&&(t=0),this.z=t,this},setW:function(t){return void 0===t&&(t=0),this.w=t,this},getLocalTransformMatrix:function(t){return void 0===t&&(t=new n),t.applyITRS(this.x,this.y,this._rotation,this._scaleX,this._scaleY)},getWorldTransformMatrix:function(t,e){void 0===t&&(t=new n);var i=this.parentContainer;if(!i)return this.getLocalTransformMatrix(t);for(e||(e=new n),t.applyITRS(this.x,this.y,this._rotation,this._scaleX,this._scaleY);i;)e.applyITRS(i.x,i.y,i._rotation,i._scaleX,i._scaleY),e.multiply(t,t),i=i.parentContainer;return t},getLocalPoint:function(t,e,i,s){i||(i=new h),s||(s=this.scene.sys.cameras.main);var n=s.scrollX,o=s.scrollY,a=t+n*this.scrollFactorX-n,l=e+o*this.scrollFactorY-o;return this.parentContainer?this.getWorldTransformMatrix().applyInverse(a,l,i):r(a,l,this.x,this.y,this.rotation,this.scaleX,this.scaleY,i),this._originComponent&&(i.x+=this._displayOriginX,i.y+=this._displayOriginY),i},getParentRotation:function(){for(var t=0,e=this.parentContainer;e;)t+=e.rotation,e=e.parentContainer;return t}};t.exports=l},69360:(t,e,i)=>{var s=i(56694),n=i(83392),r=i(93736),o=new s({initialize:function(t,e,i,s,n,r){void 0===t&&(t=1),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=1),void 0===n&&(n=0),void 0===r&&(r=0),this.matrix=new Float32Array([t,e,i,s,n,r,0,0,1]),this.decomposedMatrix={translateX:0,translateY:0,scaleX:1,scaleY:1,rotation:0},this.quad=new Float32Array(8)},a:{get:function(){return this.matrix[0]},set:function(t){this.matrix[0]=t}},b:{get:function(){return this.matrix[1]},set:function(t){this.matrix[1]=t}},c:{get:function(){return this.matrix[2]},set:function(t){this.matrix[2]=t}},d:{get:function(){return this.matrix[3]},set:function(t){this.matrix[3]=t}},e:{get:function(){return this.matrix[4]},set:function(t){this.matrix[4]=t}},f:{get:function(){return this.matrix[5]},set:function(t){this.matrix[5]=t}},tx:{get:function(){return this.matrix[4]},set:function(t){this.matrix[4]=t}},ty:{get:function(){return this.matrix[5]},set:function(t){this.matrix[5]=t}},rotation:{get:function(){return Math.acos(this.a/this.scaleX)*(Math.atan(-this.c/this.a)<0?-1:1)}},rotationNormalized:{get:function(){var t=this.matrix,e=t[0],i=t[1],s=t[2],r=t[3];return e||i?i>0?Math.acos(e/this.scaleX):-Math.acos(e/this.scaleX):s||r?n.TAU-(r>0?Math.acos(-s/this.scaleY):-Math.acos(s/this.scaleY)):0}},scaleX:{get:function(){return Math.sqrt(this.a*this.a+this.b*this.b)}},scaleY:{get:function(){return Math.sqrt(this.c*this.c+this.d*this.d)}},loadIdentity:function(){var t=this.matrix;return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,this},translate:function(t,e){var i=this.matrix;return i[4]=i[0]*t+i[2]*e+i[4],i[5]=i[1]*t+i[3]*e+i[5],this},scale:function(t,e){var i=this.matrix;return i[0]*=t,i[1]*=t,i[2]*=e,i[3]*=e,this},rotate:function(t){var e=Math.sin(t),i=Math.cos(t),s=this.matrix,n=s[0],r=s[1],o=s[2],a=s[3];return s[0]=n*i+o*e,s[1]=r*i+a*e,s[2]=n*-e+o*i,s[3]=r*-e+a*i,this},multiply:function(t,e){var i=this.matrix,s=t.matrix,n=i[0],r=i[1],o=i[2],a=i[3],h=i[4],l=i[5],u=s[0],c=s[1],d=s[2],f=s[3],p=s[4],v=s[5],g=void 0===e?i:e.matrix;return g[0]=u*n+c*o,g[1]=u*r+c*a,g[2]=d*n+f*o,g[3]=d*r+f*a,g[4]=p*n+v*o+h,g[5]=p*r+v*a+l,g},multiplyWithOffset:function(t,e,i){var s=this.matrix,n=t.matrix,r=s[0],o=s[1],a=s[2],h=s[3],l=e*r+i*a+s[4],u=e*o+i*h+s[5],c=n[0],d=n[1],f=n[2],p=n[3],v=n[4],g=n[5];return s[0]=c*r+d*a,s[1]=c*o+d*h,s[2]=f*r+p*a,s[3]=f*o+p*h,s[4]=v*r+g*a+l,s[5]=v*o+g*h+u,this},transform:function(t,e,i,s,n,r){var o=this.matrix,a=o[0],h=o[1],l=o[2],u=o[3],c=o[4],d=o[5];return o[0]=t*a+e*l,o[1]=t*h+e*u,o[2]=i*a+s*l,o[3]=i*h+s*u,o[4]=n*a+r*l+c,o[5]=n*h+r*u+d,this},transformPoint:function(t,e,i){void 0===i&&(i={x:0,y:0});var s=this.matrix,n=s[0],r=s[1],o=s[2],a=s[3],h=s[4],l=s[5];return i.x=t*n+e*o+h,i.y=t*r+e*a+l,i},invert:function(){var t=this.matrix,e=t[0],i=t[1],s=t[2],n=t[3],r=t[4],o=t[5],a=e*n-i*s;return t[0]=n/a,t[1]=-i/a,t[2]=-s/a,t[3]=e/a,t[4]=(s*o-n*r)/a,t[5]=-(e*o-i*r)/a,this},copyFrom:function(t){var e=this.matrix;return e[0]=t.a,e[1]=t.b,e[2]=t.c,e[3]=t.d,e[4]=t.e,e[5]=t.f,this},copyFromArray:function(t){var e=this.matrix;return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],this},copyToContext:function(t){var e=this.matrix;return t.transform(e[0],e[1],e[2],e[3],e[4],e[5]),t},setToContext:function(t){var e=this.matrix;return t.setTransform(e[0],e[1],e[2],e[3],e[4],e[5]),t},copyToArray:function(t){var e=this.matrix;return void 0===t?t=[e[0],e[1],e[2],e[3],e[4],e[5]]:(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5]),t},setTransform:function(t,e,i,s,n,r){var o=this.matrix;return o[0]=t,o[1]=e,o[2]=i,o[3]=s,o[4]=n,o[5]=r,this},decomposeMatrix:function(){var t=this.decomposedMatrix,e=this.matrix,i=e[0],s=e[1],n=e[2],r=e[3],o=i*r-s*n;if(t.translateX=e[4],t.translateY=e[5],i||s){var a=Math.sqrt(i*i+s*s);t.rotation=s>0?Math.acos(i/a):-Math.acos(i/a),t.scaleX=a,t.scaleY=o/a}else if(n||r){var h=Math.sqrt(n*n+r*r);t.rotation=.5*Math.PI-(r>0?Math.acos(-n/h):-Math.acos(n/h)),t.scaleX=o/h,t.scaleY=h}else t.rotation=0,t.scaleX=0,t.scaleY=0;return t},applyITRS:function(t,e,i,s,n){var r=this.matrix,o=Math.sin(i),a=Math.cos(i);return r[4]=t,r[5]=e,r[0]=a*s,r[1]=o*s,r[2]=-o*n,r[3]=a*n,this},applyInverse:function(t,e,i){void 0===i&&(i=new r);var s=this.matrix,n=s[0],o=s[1],a=s[2],h=s[3],l=s[4],u=s[5],c=1/(n*h+a*-o);return i.x=h*c*t+-a*c*e+(u*a-l*h)*c,i.y=n*c*e+-o*c*t+(-u*n+l*o)*c,i},setQuad:function(t,e,i,s,n,r){void 0===r&&(r=this.quad);var o=this.matrix,a=o[0],h=o[1],l=o[2],u=o[3],c=o[4],d=o[5];return r[0]=t*a+e*l+c,r[1]=t*h+e*u+d,r[2]=t*a+s*l+c,r[3]=t*h+s*u+d,r[4]=i*a+s*l+c,r[5]=i*h+s*u+d,r[6]=i*a+e*l+c,r[7]=i*h+e*u+d,n&&r.forEach((function(t,e){r[e]=Math.round(t)})),r},getX:function(t,e){return t*this.a+e*this.c+this.e},getY:function(t,e){return t*this.b+e*this.d+this.f},getXRound:function(t,e,i){var s=this.getX(t,e);return i&&(s=Math.round(s)),s},getYRound:function(t,e,i){var s=this.getY(t,e);return i&&(s=Math.round(s)),s},getCSSMatrix:function(){var t=this.matrix;return"matrix("+t[0]+","+t[1]+","+t[2]+","+t[3]+","+t[4]+","+t[5]+")"},destroy:function(){this.matrix=null,this.quad=null,this.decomposedMatrix=null}});t.exports=o},59694:t=>{var e={_visible:!0,visible:{get:function(){return this._visible},set:function(t){t?(this._visible=!0,this.renderFlags|=1):(this._visible=!1,this.renderFlags&=-2)}},setVisible:function(t){return this.visible=t,this}};t.exports=e},64937:(t,e,i)=>{t.exports={Alpha:i(97123),AlphaSingle:i(15720),BlendMode:i(69732),ComputedSize:i(28284),Crop:i(85293),Depth:i(14975),Flip:i(92972),FX:i(88677),GetBounds:i(80693),Mask:i(39171),Origin:i(28072),PathFollower:i(54211),Pipeline:i(58210),PostPipeline:i(44086),ScrollFactor:i(45900),Size:i(31654),Texture:i(82081),TextureCrop:i(21850),Tint:i(58072),ToJSON:i(48129),Transform:i(56584),TransformMatrix:i(69360),Visible:i(59694)}},70339:(t,e,i)=>{var s=i(59959),n=i(95723),r=i(56694),o=i(64937),a=i(56631),h=i(89980),l=i(74118),u=i(98524),c=i(58795),d=i(93736),f=new r({Extends:h,Mixins:[o.AlphaSingle,o.BlendMode,o.ComputedSize,o.Depth,o.Mask,o.PostPipeline,o.Transform,o.Visible,u],initialize:function(t,e,i,s){h.call(this,t,"Container"),this.list=[],this.exclusive=!0,this.maxSize=-1,this.position=0,this.localTransform=new o.TransformMatrix,this.tempTransformMatrix=new o.TransformMatrix,this._sortKey="",this._sysEvents=t.sys.events,this.scrollFactorX=1,this.scrollFactorY=1,this.initPostPipeline(),this.setPosition(e,i),this.setBlendMode(n.SKIP_CHECK),s&&this.add(s)},originX:{get:function(){return.5}},originY:{get:function(){return.5}},displayOriginX:{get:function(){return.5*this.width}},displayOriginY:{get:function(){return.5*this.height}},setExclusive:function(t){return void 0===t&&(t=!0),this.exclusive=t,this},getBounds:function(t){if(void 0===t&&(t=new l),t.setTo(this.x,this.y,0,0),this.parentContainer){var e=this.parentContainer.getBoundsTransformMatrix().transformPoint(this.x,this.y);t.setTo(e.x,e.y,0,0)}if(this.list.length>0){var i=this.list,s=new l,n=!1;t.setEmpty();for(var r=0;r-1},setAll:function(t,e,i,n){return s.SetAll(this.list,t,e,i,n),this},each:function(t,e){var i,s=[null],n=this.list.slice(),r=n.length;for(i=2;i0?this.list[0]:null}},last:{get:function(){return this.list.length>0?(this.position=this.list.length-1,this.list[this.position]):null}},next:{get:function(){return this.position0?(this.position--,this.list[this.position]):null}},preDestroy:function(){this.removeAll(!!this.exclusive),this.localTransform.destroy(),this.tempTransformMatrix.destroy(),this.list=[]}});t.exports=f},13916:t=>{t.exports=function(t,e,i,s){i.addToRenderList(e);var n=e.list;if(0!==n.length){var r=e.localTransform;s?(r.loadIdentity(),r.multiply(s),r.translate(e.x,e.y),r.rotate(e.rotation),r.scale(e.scaleX,e.scaleY)):r.applyITRS(e.x,e.y,e.rotation,e.scaleX,e.scaleY);var o=-1!==e.blendMode;o||t.setBlendMode(0);var a=e._alpha,h=e.scrollFactorX,l=e.scrollFactorY;e.mask&&e.mask.preRenderCanvas(t,null,i);for(var u=0;u{var s=i(88933),n=i(70339),r=i(99325),o=i(20494);r.register("container",(function(t,e){void 0===t&&(t={});var i=o(t,"x",0),r=o(t,"y",0),a=o(t,"children",null),h=new n(this.scene,i,r,a);return void 0!==e&&(t.add=e),s(this.scene,h,t),h}))},23400:(t,e,i)=>{var s=i(70339);i(61286).register("container",(function(t,e,i){return this.displayList.add(new s(this.scene,t,e,i))}))},98524:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(36934),r=i(13916),t.exports={renderWebGL:n,renderCanvas:r}},36934:t=>{t.exports=function(t,e,i,s){i.addToRenderList(e);var n=e.list,r=n.length;if(0!==r){var o=e.localTransform;s?(o.loadIdentity(),o.multiply(s),o.translate(e.x,e.y),o.rotate(e.rotation),o.scale(e.scaleX,e.scaleY)):o.applyITRS(e.x,e.y,e.rotation,e.scaleX,e.scaleY),t.pipelines.preBatch(e);var a=-1!==e.blendMode;a||t.setBlendMode(0);for(var h=e.alpha,l=e.scrollFactorX,u=e.scrollFactorY,c=0;c{t.exports=["normal","multiply","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"]},38943:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(11603),o=i(89980),a=i(42911),h=i(55638),l=i(7599),u=i(51729),c=new s({Extends:o,Mixins:[n.AlphaSingle,n.BlendMode,n.Depth,n.Origin,n.ScrollFactor,n.Transform,n.Visible,r],initialize:function(t,e,i,s,n,r){o.call(this,t,"DOMElement"),this.parent=t.sys.game.domContainer,this.cache=t.sys.cache.html,this.node,this.transformOnly=!1,this.skewX=0,this.skewY=0,this.rotate3d=new u,this.rotate3dAngle="deg",this.pointerEvents="auto",this.width=0,this.height=0,this.displayWidth=0,this.displayHeight=0,this.handler=this.dispatchNativeEvent.bind(this),this.setPosition(e,i),"string"==typeof s?"#"===s[0]?this.setElement(s.substr(1),n,r):this.createElement(s,n,r):s&&this.setElement(s,n,r),t.sys.events.on(l.SLEEP,this.handleSceneEvent,this),t.sys.events.on(l.WAKE,this.handleSceneEvent,this),t.sys.events.on(l.PRE_RENDER,this.preRender,this)},handleSceneEvent:function(t){var e=this.node,i=e.style;e&&(i.display=t.settings.visible?"block":"none")},setSkew:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.skewX=t,this.skewY=e,this},setPerspective:function(t){return this.parent.style.perspective=t+"px",this},perspective:{get:function(){return parseFloat(this.parent.style.perspective)},set:function(t){this.parent.style.perspective=t+"px"}},addListener:function(t){if(this.node){t=t.split(" ");for(var e=0;e{var s=i(2452),n=i(89980),r=i(69360),o=new r,a=new r,h=new r;t.exports=function(t,e,i,r){if(e.node){var l=e.node.style,u=e.scene.sys.settings;if(!l||!u.visible||n.RENDER_MASK!==e.renderFlags||0!==e.cameraFilter&&e.cameraFilter&i.id||e.parentContainer&&!e.parentContainer.willRender())l.display="none";else{var c=e.parentContainer,d=i.alpha*e.alpha;c&&(d*=c.alpha);var f=o,p=a,v=h,g=0,m=0,y="0%",x="0%";r?(g=e.width*e.scaleX*e.originX,m=e.height*e.scaleY*e.originY,p.applyITRS(e.x-g,e.y-m,e.rotation,e.scaleX,e.scaleY),f.copyFrom(i.matrix),f.multiplyWithOffset(r,-i.scrollX*e.scrollFactorX,-i.scrollY*e.scrollFactorY),p.e=e.x-g,p.f=e.y-m,f.multiply(p,v)):(g=e.width*e.originX,m=e.height*e.originY,p.applyITRS(e.x-g,e.y-m,e.rotation,e.scaleX,e.scaleY),f.copyFrom(i.matrix),y=100*e.originX+"%",x=100*e.originY+"%",p.e-=i.scrollX*e.scrollFactorX,p.f-=i.scrollY*e.scrollFactorY,f.multiply(p,v)),e.transformOnly||(l.display="block",l.opacity=d,l.zIndex=e._depth,l.pointerEvents=e.pointerEvents,l.mixBlendMode=s[e._blendMode]),l.transform=v.getCSSMatrix()+" skew("+e.skewX+"rad, "+e.skewY+"rad) rotate3d("+e.rotate3d.x+","+e.rotate3d.y+","+e.rotate3d.z+","+e.rotate3d.w+e.rotate3dAngle+")",l.transformOrigin=y+" "+x}}}},66788:(t,e,i)=>{var s=i(38943);i(61286).register("dom",(function(t,e,i,n,r){var o=new s(this.scene,t,e,i,n,r);return this.displayList.add(o),o}))},11603:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(66070),r=i(66070),t.exports={renderWebGL:n,renderCanvas:r}},65492:t=>{t.exports="addedtoscene"},98398:t=>{t.exports="destroy"},40239:t=>{t.exports="removedfromscene"},17286:t=>{t.exports="complete"},31496:t=>{t.exports="created"},89587:t=>{t.exports="error"},59792:t=>{t.exports="locked"},96342:t=>{t.exports="loop"},6017:t=>{t.exports="playing"},49614:t=>{t.exports="play"},24418:t=>{t.exports="seeked"},87318:t=>{t.exports="seeking"},50009:t=>{t.exports="stalled"},61922:t=>{t.exports="stop"},79501:t=>{t.exports="textureready"},4052:t=>{t.exports="unlocked"},54857:t=>{t.exports="unsupported"},56631:(t,e,i)=>{t.exports={ADDED_TO_SCENE:i(65492),DESTROY:i(98398),REMOVED_FROM_SCENE:i(40239),VIDEO_COMPLETE:i(17286),VIDEO_CREATED:i(31496),VIDEO_ERROR:i(89587),VIDEO_LOCKED:i(59792),VIDEO_LOOP:i(96342),VIDEO_PLAY:i(49614),VIDEO_PLAYING:i(6017),VIDEO_SEEKED:i(24418),VIDEO_SEEKING:i(87318),VIDEO_STALLED:i(50009),VIDEO_STOP:i(61922),VIDEO_TEXTURE:i(79501),VIDEO_UNLOCKED:i(4052),VIDEO_UNSUPPORTED:i(54857)}},39419:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(89980),o=i(79394),a=new s({Extends:r,Mixins:[n.Alpha,n.BlendMode,n.Depth,n.Flip,n.Origin,n.ScrollFactor,n.Size,n.Texture,n.Tint,n.Transform,n.Visible,o],initialize:function(t){r.call(this,t,"Extern")},addedToScene:function(){this.scene.sys.updateList.add(this)},removedFromScene:function(){this.scene.sys.updateList.remove(this)},preUpdate:function(){},render:function(){}});t.exports=a},96699:()=>{},41155:(t,e,i)=>{var s=i(39419);i(61286).register("extern",(function(){var t=new s(this.scene);return this.displayList.add(t),t}))},79394:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(81410),r=i(96699),t.exports={renderWebGL:n,renderCanvas:r}},81410:(t,e,i)=>{var s=i(73329);t.exports=function(t,e,i,n){t.pipelines.clear();var r=s(e,i,n).calc;e.render.call(e,t,i,r),t.pipelines.rebind()}},36266:t=>{t.exports={ARC:0,BEGIN_PATH:1,CLOSE_PATH:2,FILL_RECT:3,LINE_TO:4,MOVE_TO:5,LINE_STYLE:6,FILL_STYLE:7,FILL_PATH:8,STROKE_PATH:9,FILL_TRIANGLE:10,STROKE_TRIANGLE:11,SAVE:14,RESTORE:15,TRANSLATE:16,SCALE:17,ROTATE:18,GRADIENT_FILL_STYLE:21,GRADIENT_LINE_STYLE:22}},33182:(t,e,i)=>{var s=i(51052),n=i(56694),r=i(36266),o=i(64937),a=i(95669),h=i(89980),l=i(72632),u=i(10850),c=i(83392),d=i(60898),f=new n({Extends:h,Mixins:[o.AlphaSingle,o.BlendMode,o.Depth,o.Mask,o.Pipeline,o.PostPipeline,o.Transform,o.Visible,o.ScrollFactor,d],initialize:function(t,e){var i=u(e,"x",0),s=u(e,"y",0);h.call(this,t,"Graphics"),this.setPosition(i,s),this.initPipeline(),this.initPostPipeline(),this.displayOriginX=0,this.displayOriginY=0,this.commandBuffer=[],this.defaultFillColor=-1,this.defaultFillAlpha=1,this.defaultStrokeWidth=1,this.defaultStrokeColor=-1,this.defaultStrokeAlpha=1,this._lineWidth=1,this.setDefaultStyles(e)},setDefaultStyles:function(t){return u(t,"lineStyle",null)&&(this.defaultStrokeWidth=u(t,"lineStyle.width",1),this.defaultStrokeColor=u(t,"lineStyle.color",16777215),this.defaultStrokeAlpha=u(t,"lineStyle.alpha",1),this.lineStyle(this.defaultStrokeWidth,this.defaultStrokeColor,this.defaultStrokeAlpha)),u(t,"fillStyle",null)&&(this.defaultFillColor=u(t,"fillStyle.color",16777215),this.defaultFillAlpha=u(t,"fillStyle.alpha",1),this.fillStyle(this.defaultFillColor,this.defaultFillAlpha)),this},lineStyle:function(t,e,i){return void 0===i&&(i=1),this.commandBuffer.push(r.LINE_STYLE,t,e,i),this._lineWidth=t,this},fillStyle:function(t,e){return void 0===e&&(e=1),this.commandBuffer.push(r.FILL_STYLE,t,e),this},fillGradientStyle:function(t,e,i,s,n,o,a,h){return void 0===n&&(n=1),void 0===o&&(o=n),void 0===a&&(a=n),void 0===h&&(h=n),this.commandBuffer.push(r.GRADIENT_FILL_STYLE,n,o,a,h,t,e,i,s),this},lineGradientStyle:function(t,e,i,s,n,o){return void 0===o&&(o=1),this.commandBuffer.push(r.GRADIENT_LINE_STYLE,t,o,e,i,s,n),this},beginPath:function(){return this.commandBuffer.push(r.BEGIN_PATH),this},closePath:function(){return this.commandBuffer.push(r.CLOSE_PATH),this},fillPath:function(){return this.commandBuffer.push(r.FILL_PATH),this},fill:function(){return this.commandBuffer.push(r.FILL_PATH),this},strokePath:function(){return this.commandBuffer.push(r.STROKE_PATH),this},stroke:function(){return this.commandBuffer.push(r.STROKE_PATH),this},fillCircleShape:function(t){return this.fillCircle(t.x,t.y,t.radius)},strokeCircleShape:function(t){return this.strokeCircle(t.x,t.y,t.radius)},fillCircle:function(t,e,i){return this.beginPath(),this.arc(t,e,i,0,c.PI2),this.fillPath(),this},strokeCircle:function(t,e,i){return this.beginPath(),this.arc(t,e,i,0,c.PI2),this.strokePath(),this},fillRectShape:function(t){return this.fillRect(t.x,t.y,t.width,t.height)},strokeRectShape:function(t){return this.strokeRect(t.x,t.y,t.width,t.height)},fillRect:function(t,e,i,s){return this.commandBuffer.push(r.FILL_RECT,t,e,i,s),this},strokeRect:function(t,e,i,s){var n=this._lineWidth/2,r=t-n,o=t+n;return this.beginPath(),this.moveTo(t,e),this.lineTo(t,e+s),this.strokePath(),this.beginPath(),this.moveTo(t+i,e),this.lineTo(t+i,e+s),this.strokePath(),this.beginPath(),this.moveTo(r,e),this.lineTo(o+i,e),this.strokePath(),this.beginPath(),this.moveTo(r,e+s),this.lineTo(o+i,e+s),this.strokePath(),this},fillRoundedRect:function(t,e,i,s,n){void 0===n&&(n=20);var r=n,o=n,a=n,h=n;"number"!=typeof n&&(r=l(n,"tl",20),o=l(n,"tr",20),a=l(n,"bl",20),h=l(n,"br",20));var u=r>=0,d=o>=0,f=a>=0,p=h>=0;return r=Math.abs(r),o=Math.abs(o),a=Math.abs(a),h=Math.abs(h),this.beginPath(),this.moveTo(t+r,e),this.lineTo(t+i-o,e),d?this.arc(t+i-o,e+o,o,-c.TAU,0):this.arc(t+i,e,o,Math.PI,c.TAU,!0),this.lineTo(t+i,e+s-h),p?this.arc(t+i-h,e+s-h,h,0,c.TAU):this.arc(t+i,e+s,h,-c.TAU,Math.PI,!0),this.lineTo(t+a,e+s),f?this.arc(t+a,e+s-a,a,c.TAU,Math.PI):this.arc(t,e+s,a,0,-c.TAU,!0),this.lineTo(t,e+r),u?this.arc(t+r,e+r,r,-Math.PI,-c.TAU):this.arc(t,e,r,c.TAU,0,!0),this.fillPath(),this},strokeRoundedRect:function(t,e,i,s,n){void 0===n&&(n=20);var r=n,o=n,a=n,h=n,u=Math.min(i,s)/2;"number"!=typeof n&&(r=l(n,"tl",20),o=l(n,"tr",20),a=l(n,"bl",20),h=l(n,"br",20));var d=r>=0,f=o>=0,p=a>=0,v=h>=0;return r=Math.min(Math.abs(r),u),o=Math.min(Math.abs(o),u),a=Math.min(Math.abs(a),u),h=Math.min(Math.abs(h),u),this.beginPath(),this.moveTo(t+r,e),this.lineTo(t+i-o,e),this.moveTo(t+i-o,e),f?this.arc(t+i-o,e+o,o,-c.TAU,0):this.arc(t+i,e,o,Math.PI,c.TAU,!0),this.lineTo(t+i,e+s-h),this.moveTo(t+i,e+s-h),v?this.arc(t+i-h,e+s-h,h,0,c.TAU):this.arc(t+i,e+s,h,-c.TAU,Math.PI,!0),this.lineTo(t+a,e+s),this.moveTo(t+a,e+s),p?this.arc(t+a,e+s-a,a,c.TAU,Math.PI):this.arc(t,e+s,a,0,-c.TAU,!0),this.lineTo(t,e+r),this.moveTo(t,e+r),d?this.arc(t+r,e+r,r,-Math.PI,-c.TAU):this.arc(t,e,r,c.TAU,0,!0),this.strokePath(),this},fillPointShape:function(t,e){return this.fillPoint(t.x,t.y,e)},fillPoint:function(t,e,i){return!i||i<1?i=1:(t-=i/2,e-=i/2),this.commandBuffer.push(r.FILL_RECT,t,e,i,i),this},fillTriangleShape:function(t){return this.fillTriangle(t.x1,t.y1,t.x2,t.y2,t.x3,t.y3)},strokeTriangleShape:function(t){return this.strokeTriangle(t.x1,t.y1,t.x2,t.y2,t.x3,t.y3)},fillTriangle:function(t,e,i,s,n,o){return this.commandBuffer.push(r.FILL_TRIANGLE,t,e,i,s,n,o),this},strokeTriangle:function(t,e,i,s,n,o){return this.commandBuffer.push(r.STROKE_TRIANGLE,t,e,i,s,n,o),this},strokeLineShape:function(t){return this.lineBetween(t.x1,t.y1,t.x2,t.y2)},lineBetween:function(t,e,i,s){return this.beginPath(),this.moveTo(t,e),this.lineTo(i,s),this.strokePath(),this},lineTo:function(t,e){return this.commandBuffer.push(r.LINE_TO,t,e),this},moveTo:function(t,e){return this.commandBuffer.push(r.MOVE_TO,t,e),this},strokePoints:function(t,e,i,s){void 0===e&&(e=!1),void 0===i&&(i=!1),void 0===s&&(s=t.length),this.beginPath(),this.moveTo(t[0].x,t[0].y);for(var n=1;n-1&&this.fillStyle(this.defaultFillColor,this.defaultFillAlpha),this.defaultStrokeColor>-1&&this.lineStyle(this.defaultStrokeWidth,this.defaultStrokeColor,this.defaultStrokeAlpha),this},generateTexture:function(t,e,i){var s,n,r=this.scene.sys,o=r.game.renderer;void 0===e&&(e=r.scale.width),void 0===i&&(i=r.scale.height),f.TargetCamera.setScene(this.scene),f.TargetCamera.setViewport(0,0,e,i),f.TargetCamera.scrollX=this.x,f.TargetCamera.scrollY=this.y;var a={willReadFrequently:!0};if("string"==typeof t)if(r.textures.exists(t)){var h=(s=r.textures.get(t)).getSourceImage();h instanceof HTMLCanvasElement&&(n=h.getContext("2d",a))}else n=(s=r.textures.createCanvas(t,e,i)).getSourceImage().getContext("2d",a);else t instanceof HTMLCanvasElement&&(n=t.getContext("2d",a));return n&&(this.renderCanvas(o,this,f.TargetCamera,null,n,!1),s&&s.refresh()),this},preDestroy:function(){this.commandBuffer=[]}});f.TargetCamera=new s,t.exports=f},91543:(t,e,i)=>{var s=i(36266),n=i(49584);t.exports=function(t,e,i,r,o,a){var h=e.commandBuffer,l=h.length,u=o||t.currentContext;if(0!==l&&n(t,u,e,i,r)){i.addToRenderList(e);var c=1,d=1,f=0,p=0,v=1,g=0,m=0,y=0;u.beginPath();for(var x=0;x>>16,m=(65280&f)>>>8,y=255&f,u.strokeStyle="rgba("+g+","+m+","+y+","+c+")",u.lineWidth=v,x+=3;break;case s.FILL_STYLE:p=h[x+1],d=h[x+2],g=(16711680&p)>>>16,m=(65280&p)>>>8,y=255&p,u.fillStyle="rgba("+g+","+m+","+y+","+d+")",x+=2;break;case s.BEGIN_PATH:u.beginPath();break;case s.CLOSE_PATH:u.closePath();break;case s.FILL_PATH:a||u.fill();break;case s.STROKE_PATH:a||u.stroke();break;case s.FILL_RECT:a?u.rect(h[x+1],h[x+2],h[x+3],h[x+4]):u.fillRect(h[x+1],h[x+2],h[x+3],h[x+4]),x+=4;break;case s.FILL_TRIANGLE:u.beginPath(),u.moveTo(h[x+1],h[x+2]),u.lineTo(h[x+3],h[x+4]),u.lineTo(h[x+5],h[x+6]),u.closePath(),a||u.fill(),x+=6;break;case s.STROKE_TRIANGLE:u.beginPath(),u.moveTo(h[x+1],h[x+2]),u.lineTo(h[x+3],h[x+4]),u.lineTo(h[x+5],h[x+6]),u.closePath(),a||u.stroke(),x+=6;break;case s.LINE_TO:u.lineTo(h[x+1],h[x+2]),x+=2;break;case s.MOVE_TO:u.moveTo(h[x+1],h[x+2]),x+=2;break;case s.LINE_FX_TO:u.lineTo(h[x+1],h[x+2]),x+=5;break;case s.MOVE_FX_TO:u.moveTo(h[x+1],h[x+2]),x+=5;break;case s.SAVE:u.save();break;case s.RESTORE:u.restore();break;case s.TRANSLATE:u.translate(h[x+1],h[x+2]),x+=2;break;case s.SCALE:u.scale(h[x+1],h[x+2]),x+=2;break;case s.ROTATE:u.rotate(h[x+1]),x+=1;break;case s.GRADIENT_FILL_STYLE:x+=5;break;case s.GRADIENT_LINE_STYLE:x+=6}}u.restore()}}},41286:(t,e,i)=>{var s=i(99325),n=i(33182);s.register("graphics",(function(t,e){void 0===t&&(t={}),void 0!==e&&(t.add=e);var i=new n(this.scene,t);return t.add&&this.scene.sys.displayList.add(i),i}))},13122:(t,e,i)=>{var s=i(33182);i(61286).register("graphics",(function(t){return this.displayList.add(new s(this.scene,t))}))},60898:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(34429),r=i(91543),r=i(91543),t.exports={renderWebGL:n,renderCanvas:r}},34429:(t,e,i)=>{var s=i(36266),n=i(73329),r=i(69360),o=i(75512),a=function(t,e,i){this.x=t,this.y=e,this.width=i},h=function(t,e,i){this.points=[],this.pointsLength=1,this.points[0]=new a(t,e,i)},l=[],u=new r;t.exports=function(t,e,i,r){if(0!==e.commandBuffer.length){i.addToRenderList(e);var c=t.pipelines.set(e.pipeline,e);t.pipelines.preBatch(e);for(var d=n(e,i,r).calc,f=u.loadIdentity(),p=e.commandBuffer,v=i.alpha*e.alpha,g=1,m=c.fillTint,y=c.strokeTint,x=0,T=0,w=0,b=2*Math.PI,S=[],E=0,A=!0,C=null,_=o.getTintAppendFloatAlpha,M=0;M0&&(Y=Y%b-b):Y>b?Y=b:Y<0&&(Y=b+Y%b),null===C&&(C=new h(B+Math.cos(U)*X,N+Math.sin(U)*X,g),S.push(C),k+=.01);k<1+G;)w=Y*k+U,x=B+Math.cos(w)*X,T=N+Math.sin(w)*X,C.points.push(new a(x,T,g)),k+=.01;w=Y+U,x=B+Math.cos(w)*X,T=N+Math.sin(w)*X,C.points.push(new a(x,T,g));break;case s.FILL_RECT:c.batchFillRect(p[++M],p[++M],p[++M],p[++M],f,d);break;case s.FILL_TRIANGLE:c.batchFillTriangle(p[++M],p[++M],p[++M],p[++M],p[++M],p[++M],f,d);break;case s.STROKE_TRIANGLE:c.batchStrokeTriangle(p[++M],p[++M],p[++M],p[++M],p[++M],p[++M],g,f,d);break;case s.LINE_TO:null!==C?C.points.push(new a(p[++M],p[++M],g)):(C=new h(p[++M],p[++M],g),S.push(C));break;case s.MOVE_TO:C=new h(p[++M],p[++M],g),S.push(C);break;case s.SAVE:l.push(f.copyToArray());break;case s.RESTORE:f.copyFromArray(l.pop());break;case s.TRANSLATE:B=p[++M],N=p[++M],f.translate(B,N);break;case s.SCALE:B=p[++M],N=p[++M],f.scale(B,N);break;case s.ROTATE:f.rotate(p[++M])}t.pipelines.postBatch(e)}}},59192:(t,e,i)=>{var s=i(83979),n=i(56694),r=i(56631),o=i(6659),a=i(71608),h=i(72632),l=i(10850),u=i(19256),c=i(42911),d=i(75757),f=i(58403),p=i(13747),v=new n({Extends:o,initialize:function(t,e,i){o.call(this),i?e&&!Array.isArray(e)&&(e=[e]):Array.isArray(e)?c(e[0])&&(i=e,e=null):c(e)&&(i=e,e=null),this.scene=t,this.children=new f,this.isParent=!0,this.type="Group",this.classType=h(i,"classType",p),this.name=h(i,"name",""),this.active=h(i,"active",!0),this.maxSize=h(i,"maxSize",-1),this.defaultKey=h(i,"defaultKey",null),this.defaultFrame=h(i,"defaultFrame",null),this.runChildUpdate=h(i,"runChildUpdate",!1),this.createCallback=h(i,"createCallback",null),this.removeCallback=h(i,"removeCallback",null),this.createMultipleCallback=h(i,"createMultipleCallback",null),this.internalCreateCallback=h(i,"internalCreateCallback",null),this.internalRemoveCallback=h(i,"internalRemoveCallback",null),e&&this.addMultiple(e),i&&this.createMultiple(i),this.on(r.ADDED_TO_SCENE,this.addedToScene,this),this.on(r.REMOVED_FROM_SCENE,this.removedFromScene,this)},addedToScene:function(){this.scene.sys.updateList.add(this)},removedFromScene:function(){this.scene.sys.updateList.remove(this)},create:function(t,e,i,s,n,r){if(void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=this.defaultKey),void 0===s&&(s=this.defaultFrame),void 0===n&&(n=!0),void 0===r&&(r=!0),this.isFull())return null;var o=new this.classType(this.scene,t,e,i,s);return o.addToDisplayList(this.scene.sys.displayList),o.addToUpdateList(),o.visible=n,o.setActive(r),this.add(o),o},createMultiple:function(t){if(this.isFull())return[];Array.isArray(t)||(t=[t]);var e=[];if(t[0].key)for(var i=0;i=0;u--)if((l=d[u]).active===i){if(++c===e)break}else l=null;return l?("number"==typeof n&&(l.x=n),"number"==typeof r&&(l.y=r),l):s?this.create(n,r,o,a,h):null},get:function(t,e,i,s,n){return this.getFirst(!1,!0,t,e,i,s,n)},getFirstAlive:function(t,e,i,s,n,r){return this.getFirst(!0,t,e,i,s,n,r)},getFirstDead:function(t,e,i,s,n,r){return this.getFirst(!1,t,e,i,s,n,r)},playAnimation:function(t,e){return s.PlayAnimation(this.children.entries,t,e),this},isFull:function(){return-1!==this.maxSize&&this.children.size>=this.maxSize},countActive:function(t){void 0===t&&(t=!0);for(var e=0,i=0;i{var s=i(99325),n=i(59192);s.register("group",(function(t){return new n(this.scene,null,t)}))},62598:(t,e,i)=>{var s=i(59192);i(61286).register("group",(function(t,e){return this.updateList.add(new s(this.scene,t,e))}))},1539:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(89980),o=i(57322),a=new s({Extends:r,Mixins:[n.Alpha,n.BlendMode,n.Depth,n.Flip,n.GetBounds,n.Mask,n.Origin,n.Pipeline,n.PostPipeline,n.ScrollFactor,n.Size,n.TextureCrop,n.Tint,n.Transform,n.Visible,o],initialize:function(t,e,i,s,n){r.call(this,t,"Image"),this._crop=this.resetCropObject(),this.setTexture(s,n),this.setPosition(e,i),this.setSizeToFrame(),this.setOriginFromFrame(),this.initPipeline(),this.initPostPipeline(!0)}});t.exports=a},57786:t=>{t.exports=function(t,e,i,s){i.addToRenderList(e),t.batchSprite(e,e.frame,i,s)}},83556:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(1539);n.register("image",(function(t,e){void 0===t&&(t={});var i=r(t,"key",null),n=r(t,"frame",null),a=new o(this.scene,0,0,i,n);return void 0!==e&&(t.add=e),s(this.scene,a,t),a}))},20927:(t,e,i)=>{var s=i(1539);i(61286).register("image",(function(t,e,i,n){return this.displayList.add(new s(this.scene,t,e,i,n))}))},57322:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(59390),r=i(57786),t.exports={renderWebGL:n,renderCanvas:r}},59390:t=>{t.exports=function(t,e,i,s){i.addToRenderList(e),this.pipeline.batchSprite(e,i,s)}},48013:(t,e,i)=>{var s={Events:i(56631),DisplayList:i(91713),GameObjectCreator:i(99325),GameObjectFactory:i(61286),UpdateList:i(92034),Components:i(64937),GetCalcMatrix:i(73329),BuildGameObject:i(88933),BuildGameObjectAnimation:i(32291),GameObject:i(89980),BitmapText:i(44616),Blitter:i(52816),Bob:i(41664),Container:i(70339),DOMElement:i(38943),DynamicBitmapText:i(13468),Extern:i(39419),Graphics:i(33182),Group:i(59192),Image:i(1539),Layer:i(85305),Particles:i(27684),PathFollower:i(29598),RenderTexture:i(15996),RetroFont:i(55873),Rope:i(79968),Sprite:i(13747),Text:i(76555),GetTextSize:i(32979),MeasureText:i(27030),TextStyle:i(74744),TileSprite:i(35856),Zone:i(71030),Video:i(8630),Shape:i(91461),Arc:i(28593),Curve:i(15220),Ellipse:i(28591),Grid:i(39169),IsoBox:i(4415),IsoTriangle:i(65159),Line:i(579),Polygon:i(91249),Rectangle:i(517),Star:i(77843),Triangle:i(21873),Factories:{Blitter:i(38906),Container:i(23400),DOMElement:i(66788),DynamicBitmapText:i(94145),Extern:i(41155),Graphics:i(13122),Group:i(62598),Image:i(20927),Layer:i(17676),Particles:i(81212),PathFollower:i(19626),RenderTexture:i(29599),Rope:i(31982),Sprite:i(66135),StaticBitmapText:i(21797),Text:i(94627),TileSprite:i(20509),Zone:i(34546),Video:i(215),Arc:i(10369),Curve:i(10147),Ellipse:i(99869),Grid:i(9326),IsoBox:i(88154),IsoTriangle:i(67765),Line:i(85665),Polygon:i(88203),Rectangle:i(94355),Star:i(23962),Triangle:i(79296)},Creators:{Blitter:i(68452),Container:i(44516),DynamicBitmapText:i(67513),Graphics:i(41286),Group:i(61295),Image:i(83556),Layer:i(56378),Particles:i(765),RenderTexture:i(85692),Rope:i(96027),Sprite:i(89219),StaticBitmapText:i(95499),Text:i(75397),TileSprite:i(63950),Zone:i(24067),Video:i(65601)}};s.Shader=i(27902),s.Mesh=i(83321),s.NineSlice=i(44139),s.PointLight=i(13171),s.Plane=i(33412),s.Factories.Shader=i(51979),s.Factories.Mesh=i(8767),s.Factories.NineSlice=i(53778),s.Factories.PointLight=i(91201),s.Factories.Plane=i(58322),s.Creators.Shader=i(13908),s.Creators.Mesh=i(41839),s.Creators.NineSlice=i(40964),s.Creators.PointLight=i(162),s.Creators.Plane=i(10912),s.Light=i(14455),s.LightsManager=i(26193),s.LightsPlugin=i(50296),t.exports=s},85305:(t,e,i)=>{var s=i(95723),n=i(56694),r=i(64937),o=i(48129),a=i(81078),h=i(6659),l=i(56631),u=i(71207),c=i(58010),d=i(7599),f=i(17922),p=new n({Extends:u,Mixins:[r.AlphaSingle,r.BlendMode,r.Depth,r.Mask,r.PostPipeline,r.Visible,h,c],initialize:function(t,e){u.call(this,t),h.call(this),this.scene=t,this.displayList=null,this.type="Layer",this.state=0,this.parentContainer=null,this.name="",this.active=!0,this.tabIndex=-1,this.data=null,this.renderFlags=15,this.cameraFilter=0,this.input=null,this.body=null,this.ignoreDestroy=!1,this.systems=t.sys,this.events=t.sys.events,this.sortChildrenFlag=!1,this.addCallback=this.addChildCallback,this.removeCallback=this.removeChildCallback,this.initPostPipeline(),this.clearAlpha(),this.setBlendMode(s.SKIP_CHECK),e&&this.add(e),t.sys.queueDepthSort()},setActive:function(t){return this.active=t,this},setName:function(t){return this.name=t,this},setState:function(t){return this.state=t,this},setDataEnabled:function(){return this.data||(this.data=new a(this)),this},setData:function(t,e){return this.data||(this.data=new a(this)),this.data.set(t,e),this},incData:function(t,e){return this.data||(this.data=new a(this)),this.data.inc(t,e),this},toggleData:function(t){return this.data||(this.data=new a(this)),this.data.toggle(t),this},getData:function(t){return this.data||(this.data=new a(this)),this.data.get(t)},setInteractive:function(){return this},disableInteractive:function(){return this},removeInteractive:function(){return this},addedToScene:function(){},removedFromScene:function(){},update:function(){},toJSON:function(){return o(this)},willRender:function(t){return!(15!==this.renderFlags||0===this.list.length||0!==this.cameraFilter&&this.cameraFilter&t.id)},getIndexList:function(){for(var t=this,e=this.parentContainer,i=[];e&&(i.unshift(e.getIndex(t)),t=e,e.parentContainer);)e=e.parentContainer;return i.unshift(this.displayList.getIndex(t)),i},addChildCallback:function(t){t.displayList&&t.displayList!==this&&t.removeFromDisplayList(),t.displayList||(this.queueDepthSort(),t.displayList=this,t.emit(l.ADDED_TO_SCENE,t,this.scene),this.events.emit(d.ADDED_TO_SCENE,t,this.scene))},removeChildCallback:function(t){this.queueDepthSort(),t.displayList=null,t.emit(l.REMOVED_FROM_SCENE,t,this.scene),this.events.emit(d.REMOVED_FROM_SCENE,t,this.scene)},queueDepthSort:function(){this.sortChildrenFlag=!0},depthSort:function(){this.sortChildrenFlag&&(f(this.list,this.sortByDepth),this.sortChildrenFlag=!1)},sortByDepth:function(t,e){return t._depth-e._depth},getChildren:function(){return this.list},addToDisplayList:function(t){return void 0===t&&(t=this.scene.sys.displayList),this.displayList&&this.displayList!==t&&this.removeFromDisplayList(),t.exists(this)||(this.displayList=t,t.add(this,!0),t.queueDepthSort(),this.emit(l.ADDED_TO_SCENE,this,this.scene),t.events.emit(d.ADDED_TO_SCENE,this,this.scene)),this},removeFromDisplayList:function(){var t=this.displayList||this.scene.sys.displayList;return t.exists(this)&&(t.remove(this,!0),t.queueDepthSort(),this.displayList=null,this.emit(l.REMOVED_FROM_SCENE,this,this.scene),t.events.emit(d.REMOVED_FROM_SCENE,this,this.scene)),this},destroy:function(t){if(this.scene&&!this.ignoreDestroy){this.emit(l.DESTROY,this);for(var e=this.list;e.length;)e[0].destroy(t);this.removeAllListeners(),this.resetPostPipeline(!0),this.displayList&&(this.displayList.remove(this,!0),this.displayList.queueDepthSort()),this.data&&(this.data.destroy(),this.data=void 0),this.active=!1,this.visible=!1,this.list=void 0,this.scene=void 0,this.displayList=void 0,this.systems=void 0,this.events=void 0}}});t.exports=p},834:t=>{t.exports=function(t,e,i){var s=e.list;if(0!==s.length){e.depthSort();var n=-1!==e.blendMode;n||t.setBlendMode(0);var r=e._alpha;e.mask&&e.mask.preRenderCanvas(t,null,i);for(var o=0;o{var s=i(88933),n=i(85305),r=i(99325),o=i(20494);r.register("layer",(function(t,e){void 0===t&&(t={});var i=o(t,"children",null),r=new n(this.scene,i);return void 0!==e&&(t.add=e),s(this.scene,r,t),r}))},17676:(t,e,i)=>{var s=i(85305);i(61286).register("layer",(function(t){return this.displayList.add(new s(this.scene,t))}))},58010:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(17576),r=i(834),t.exports={renderWebGL:n,renderCanvas:r}},17576:t=>{t.exports=function(t,e,i){var s=e.list,n=s.length;if(0!==n){e.depthSort(),t.pipelines.preBatch(e);var r=-1!==e.blendMode;r||t.setBlendMode(0);for(var o=e.alpha,a=0;a{var s=i(26673),n=i(56694),r=i(64937),o=i(39298),a=i(75512),h=new n({Extends:s,Mixins:[r.Origin,r.ScrollFactor,r.Transform,r.Visible],initialize:function(t,e,i,n,r,a,h){s.call(this,t,e,i),this.color=new o(n,r,a),this.intensity=h,this.renderFlags=15,this.cameraFilter=0,this.setScrollFactor(1,1),this.setOrigin(),this.setDisplayOrigin(i)},displayWidth:{get:function(){return this.diameter},set:function(t){this.diameter=t}},displayHeight:{get:function(){return this.diameter},set:function(t){this.diameter=t}},width:{get:function(){return this.diameter},set:function(t){this.diameter=t}},height:{get:function(){return this.diameter},set:function(t){this.diameter=t}},willRender:function(t){return!(h.RENDER_MASK!==this.renderFlags||0!==this.cameraFilter&&this.cameraFilter&t.id)},setColor:function(t){var e=a.getFloatsFromUintRGB(t);return this.color.set(e[0],e[1],e[2]),this},setIntensity:function(t){return this.intensity=t,this},setRadius:function(t){return this.radius=t,this}});h.RENDER_MASK=15,t.exports=h},26193:(t,e,i)=>{var s=i(26535),n=i(56694),r=i(53996),o=i(14455),a=i(13171),h=i(39298),l=i(72677),u=i(17922),c=i(75512),d=new n({initialize:function(){this.lights=[],this.ambientColor=new h(.1,.1,.1),this.active=!1,this.maxLights=-1,this.visibleLights=0},addPointLight:function(t,e,i,s,n,r){return this.systems.displayList.add(new a(this.scene,t,e,i,s,n,r))},enable:function(){return-1===this.maxLights&&(this.maxLights=this.systems.renderer.config.maxLights),this.active=!0,this},disable:function(){return this.active=!1,this},getLights:function(t){for(var e=this.lights,i=t.worldView,n=[],o=0;othis.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,s,n){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=128),void 0===s&&(s=16777215),void 0===n&&(n=1);var r=c.getFloatsFromUintRGB(s),a=new o(t,e,i,r[0],r[1],r[2],n);return this.lights.push(a),a},removeLight:function(t){var e=this.lights.indexOf(t);return e>=0&&l(this.lights,e),this},shutdown:function(){this.lights.length=0},destroy:function(){this.shutdown()}});t.exports=d},50296:(t,e,i)=>{var s=i(56694),n=i(26193),r=i(91963),o=i(7599),a=new s({Extends:n,initialize:function(t){this.scene=t,this.systems=t.sys,t.sys.settings.isBooted||t.sys.events.once(o.BOOT,this.boot,this),n.call(this)},boot:function(){var t=this.systems.events;t.on(o.SHUTDOWN,this.shutdown,this),t.on(o.DESTROY,this.destroy,this)},destroy:function(){this.shutdown(),this.scene=void 0,this.systems=void 0}});r.register("LightsPlugin",a,"lights"),t.exports=a},83321:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(75606),o=i(18693),a=i(89980),h=i(53267),l=i(67623),u=i(73329),c=i(16650),d=i(23464),f=i(23701),p=i(17922),v=i(70015),g=i(85769),m=new s({Extends:a,Mixins:[n.AlphaSingle,n.BlendMode,n.Depth,n.Mask,n.Pipeline,n.PostPipeline,n.ScrollFactor,n.Size,n.Texture,n.Transform,n.Visible,d],initialize:function(t,e,i,s,n,r,o,h,l,u,d,f){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s="__WHITE"),a.call(this,t,"Mesh"),this.faces=[],this.vertices=[],this.tintFill=!1,this.debugCallback=null,this.debugGraphic=null,this.hideCCW=!0,this.modelPosition=new v,this.modelScale=new v(1,1,1),this.modelRotation=new v,this.dirtyCache=[0,0,0,0,0,0,0,0,0,0,0,0],this.transformMatrix=new c,this.viewPosition=new v,this.viewMatrix=new c,this.projectionMatrix=new c,this.totalRendered=0,this.totalFrame=0,this.ignoreDirtyCache=!1,this.fov,this.displayOriginX=0,this.displayOriginY=0;var p=t.sys.renderer;this.setPosition(e,i),this.setTexture(s,n),this.setSize(p.width,p.height),this.initPipeline(),this.initPostPipeline(),this.setPerspective(p.width,p.height),r&&this.addVertices(r,o,h,l,u,d,f)},addedToScene:function(){this.scene.sys.updateList.add(this)},removedFromScene:function(){this.scene.sys.updateList.remove(this)},panX:function(t){return this.viewPosition.addScale(v.LEFT,t),this.dirtyCache[10]=1,this},panY:function(t){return this.viewPosition.y+=v.DOWN.y*t,this.dirtyCache[10]=1,this},panZ:function(t){return this.viewPosition.z+=t,this.dirtyCache[10]=1,this},setPerspective:function(t,e,i,s,n){return void 0===i&&(i=45),void 0===s&&(s=.01),void 0===n&&(n=1e3),this.fov=i,this.projectionMatrix.perspective(r(i),t/e,s,n),this.dirtyCache[10]=1,this.dirtyCache[11]=0,this},setOrtho:function(t,e,i,s){return void 0===t&&(t=this.scene.sys.renderer.getAspectRatio()),void 0===e&&(e=1),void 0===i&&(i=-1e3),void 0===s&&(s=1e3),this.fov=0,this.projectionMatrix.ortho(-t,t,-e,e,i,s),this.dirtyCache[10]=1,this.dirtyCache[11]=1,this},clear:function(){return this.faces.forEach((function(t){t.destroy()})),this.faces=[],this.vertices=[],this},addVerticesFromObj:function(t,e,i,s,n,r,o,a,l){var u,c=this.scene.sys.cache.obj.get(t);return c&&(u=h(c,this,e,i,s,n,r,o,a,l)),u&&0!==u.verts.length||console.warn("Mesh.addVerticesFromObj data empty:",t),this},sortByDepth:function(t,e){return t.depth-e.depth},depthSort:function(){return p(this.faces,this.sortByDepth),this},addVertex:function(t,e,i,s,n,r,o){var a=new g(t,e,i,s,n,r,o);return this.vertices.push(a),a},addFace:function(t,e,i){var s=new o(t,e,i);return this.faces.push(s),this.dirtyCache[9]=-1,s},addVertices:function(t,e,i,s,n,r,o){var a=l(t,e,i,s,n,r,o);return a?(this.faces=this.faces.concat(a.faces),this.vertices=this.vertices.concat(a.vertices)):console.warn("Mesh.addVertices data empty or invalid"),this.dirtyCache[9]=-1,this},getFaceCount:function(){return this.faces.length},getVertexCount:function(){return this.vertices.length},getFace:function(t){return this.faces[t]},hasFaceAt:function(t,e,i){void 0===i&&(i=this.scene.sys.cameras.main);for(var s=u(this,i).calc,n=this.faces,r=0;r{t.exports=function(){}},41839:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(10850),a=i(83321);n.register("mesh",(function(t,e){void 0===t&&(t={});var i=r(t,"key",null),n=r(t,"frame",null),h=o(t,"vertices",[]),l=o(t,"uvs",[]),u=o(t,"indicies",[]),c=o(t,"containsZ",!1),d=o(t,"normals",[]),f=o(t,"colors",16777215),p=o(t,"alphas",1),v=new a(this.scene,0,0,i,n,h,l,u,c,d,f,p);return void 0!==e&&(t.add=e),s(this.scene,v,t),v}))},8767:(t,e,i)=>{var s=i(83321);i(61286).register("mesh",(function(t,e,i,n,r,o,a,h,l,u,c){return this.displayList.add(new s(this.scene,t,e,i,n,r,o,a,h,l,u,c))}))},23464:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(57410),r=i(6317),t.exports={renderWebGL:n,renderCanvas:r}},57410:(t,e,i)=>{var s=i(73329);t.exports=function(t,e,i,n){var r=e.faces,o=r.length;if(0!==o){i.addToRenderList(e);var a=t.pipelines.set(e.pipeline,e),h=s(e,i,n).calc;t.pipelines.preBatch(e);for(var l=a.setGameObject(e),u=a.vertexViewF32,c=a.vertexViewU32,d=a.vertexCount*a.currentShader.vertexComponentCount-1,f=e.tintFill,p=[],v=e.debugCallback,g=h.a,m=h.b,y=h.c,x=h.d,T=h.e,w=h.f,b=e.viewPosition.z,S=e.hideCCW,E=i.roundPixels,A=i.alpha*e.alpha,C=0,_=0;_{var s=i(56694),n=i(64937),r=i(89980),o=i(94456),a=i(85769),h=new s({Extends:r,Mixins:[n.AlphaSingle,n.BlendMode,n.Depth,n.GetBounds,n.Mask,n.Origin,n.Pipeline,n.PostPipeline,n.ScrollFactor,n.Texture,n.Transform,n.Visible,o],initialize:function(t,e,i,s,n,o,h,l,u,c,d){void 0===o&&(o=256),void 0===h&&(h=256),void 0===l&&(l=10),void 0===u&&(u=10),void 0===c&&(c=0),void 0===d&&(d=0),r.call(this,t,"NineSlice"),this._width,this._height,this._originX=.5,this._originY=.5,this._sizeComponent=!0,this.vertices=[],this.leftWidth,this.rightWidth,this.topHeight,this.bottomHeight,this.tint=16777215,this.tintFill=!1,this.is3Slice=0===c&&0===d;for(var f=this.is3Slice?18:54,p=0;p{var s=i(88933),n=i(99325),r=i(20494),o=i(10850),a=i(44139);n.register("nineslice",(function(t,e){void 0===t&&(t={});var i=r(t,"key",null),n=r(t,"frame",null),h=o(t,"width",256),l=o(t,"height",256),u=o(t,"leftWidth",10),c=o(t,"rightWidth",10),d=o(t,"topHeight",0),f=o(t,"bottomHeight",0),p=new a(this.scene,0,0,i,n,h,l,u,c,d,f);return void 0!==e&&(t.add=e),s(this.scene,p,t),p}))},53778:(t,e,i)=>{var s=i(44139);i(61286).register("nineslice",(function(t,e,i,n,r,o,a,h,l,u){return this.displayList.add(new s(this.scene,t,e,i,n,r,o,a,h,l,u))}))},94456:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(27420),t.exports={renderWebGL:n,renderCanvas:r}},27420:(t,e,i)=>{var s=i(73329),n=i(75512);t.exports=function(t,e,i,r){var o=e.vertices,a=o.length;if(0!==a){i.addToRenderList(e);var h=t.pipelines.set(e.pipeline,e),l=s(e,i,r,!1).calc;t.pipelines.preBatch(e);var u=h.setGameObject(e),c=h.vertexViewF32,d=h.vertexViewU32,f=h.vertexCount*h.currentShader.vertexComponentCount-1,p=i.roundPixels,v=e.tintFill,g=i.alpha*e.alpha,m=n.getTintAppendFloatAlpha(e.tint,g),y=h.vertexAvailable(),x=-1;y{var s=i(56694),n=i(93025),r=i(22946),o=i(21902),a=i(4840),h=i(15978),l=new s({Extends:n,initialize:function(t){n.call(this,t,null,!1),this.active=!1,this.easeName="Linear",this.r=[],this.g=[],this.b=[]},getMethod:function(){return null===this.propertyValue?0:9},setMethods:function(){var t=this.propertyValue,e=t,i=this.defaultEmit,s=this.defaultUpdate;if(9===this.method){this.start=t[0],this.ease=o("Linear"),this.interpolation=a("linear"),i=this.easedValueEmit,s=this.easeValueUpdate,e=t[0],this.active=!0;for(var n=0;n{var s=i(17489),n=i(82897),r=i(56694),o=i(61616),a=i(21902),h=i(72632),l=i(4840),u=i(88462),c=i(1071),d=new r({initialize:function(t,e,i){void 0===i&&(i=!1),this.propertyKey=t,this.propertyValue=e,this.defaultValue=e,this.steps=0,this.counter=0,this.yoyo=!1,this.direction=0,this.start=0,this.current=0,this.end=0,this.ease=null,this.interpolation=null,this.emitOnly=i,this.onEmit=this.defaultEmit,this.onUpdate=this.defaultUpdate,this.active=!0,this.method=0,this._onEmit,this._onUpdate},loadConfig:function(t,e){void 0===t&&(t={}),e&&(this.propertyKey=e),this.propertyValue=h(t,this.propertyKey,this.defaultValue),this.method=this.getMethod(),this.setMethods(),this.emitOnly&&(this.onUpdate=this.defaultUpdate)},toJSON:function(){return JSON.stringify(this.propertyValue)},onChange:function(t){var e;switch(this.method){case 1:case 3:case 8:e=t;break;case 2:this.propertyValue.indexOf(t)>=0&&(e=t);break;case 4:var i=(this.end-this.start)/this.steps;e=u(t,i),this.counter=e;break;case 5:case 6:case 7:e=n(t,this.start,this.end);break;case 9:e=this.start[0]}return this.current=e,this},getMethod:function(){var t=this.propertyValue;if(null===t)return 0;var e=typeof t;if("number"===e)return 1;if(Array.isArray(t))return 2;if("function"===e)return 3;if("object"===e){if(this.hasBoth(t,"start","end"))return this.has(t,"steps")?4:5;if(this.hasBoth(t,"min","max"))return 6;if(this.has(t,"random"))return 7;if(this.hasEither(t,"onEmit","onUpdate"))return 8;if(this.has(t,"interpolation"))return 9}return 0},setMethods:function(){var t=this.propertyValue,e=t,i=this.defaultEmit,s=this.defaultUpdate;switch(this.method){case 1:i=this.staticValueEmit;break;case 2:i=this.randomStaticValueEmit,e=t[0];break;case 3:this._onEmit=t,i=this.proxyEmit;break;case 4:this.start=t.start,this.end=t.end,this.steps=t.steps,this.counter=this.start,this.yoyo=!!this.has(t,"yoyo")&&t.yoyo,this.direction=0,i=this.steppedEmit,e=this.start;break;case 5:this.start=t.start,this.end=t.end;var n=this.has(t,"ease")?t.ease:"Linear";this.ease=a(n,t.easeParams),i=this.has(t,"random")&&t.random?this.randomRangedValueEmit:this.easedValueEmit,s=this.easeValueUpdate,e=this.start;break;case 6:this.start=t.min,this.end=t.max,i=this.has(t,"int")&&t.int?this.randomRangedIntEmit:this.randomRangedValueEmit,e=this.start;break;case 7:var r=t.random;Array.isArray(r)&&(this.start=r[0],this.end=r[1]),i=this.randomRangedIntEmit,e=this.start;break;case 8:this._onEmit=this.has(t,"onEmit")?t.onEmit:this.defaultEmit,this._onUpdate=this.has(t,"onUpdate")?t.onUpdate:this.defaultUpdate,i=this.proxyEmit,s=this.proxyUpdate;break;case 9:this.start=t.values;var o=this.has(t,"ease")?t.ease:"Linear";this.ease=a(o,t.easeParams),this.interpolation=l(t.interpolation),i=this.easedValueEmit,s=this.easeValueUpdate,e=this.start[0]}return this.onEmit=i,this.onUpdate=s,this.current=e,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,s){return s},proxyEmit:function(t,e,i){var s=this._onEmit(t,e,i);return this.current=s,s},proxyUpdate:function(t,e,i,s){var n=this._onUpdate(t,e,i,s);return this.current=n,n},staticValueEmit:function(){return this.current},staticValueUpdate:function(){return this.current},randomStaticValueEmit:function(){var t=Math.floor(Math.random()*this.propertyValue.length);return this.current=this.propertyValue[t],this.current},randomRangedValueEmit:function(t,e){var i=o(this.start,this.end);return t&&t.data[e]&&(t.data[e].min=i,t.data[e].max=this.end),this.current=i,i},randomRangedIntEmit:function(t,e){var i=s(this.start,this.end);return t&&t.data[e]&&(t.data[e].min=i,t.data[e].max=this.end),this.current=i,i},steppedEmit:function(){var t,e=this.counter,i=e,s=(this.end-this.start)/this.steps;this.yoyo?(0===this.direction?(i+=s)>=this.end&&(t=i-this.end,i=this.end-t,this.direction=1):(i-=s)<=this.start&&(t=this.start-i,i=this.start+t,this.direction=0),this.counter=i):this.counter=c(i+s,this.start,this.end);return this.current=e,e},easedValueEmit:function(t,e){if(t&&t.data[e]){var i=t.data[e];i.min=this.start,i.max=this.end}return this.current=this.start,this.start},easeValueUpdate:function(t,e,i){var s,n=t.data[e],r=this.ease(i);return s=this.interpolation?this.interpolation(this.start,r):(n.max-n.min)*r+n.min,this.current=s,s},destroy:function(){this.propertyValue=null,this.defaultValue=null,this.ease=null,this.interpolation=null,this._onEmit=null,this._onUpdate=null}});t.exports=d},87811:(t,e,i)=>{var s=i(56694),n=i(72632),r=i(30891),o=new s({Extends:r,initialize:function(t,e,i,s,o){if("object"==typeof t){var a=t;t=n(a,"x",0),e=n(a,"y",0),i=n(a,"power",0),s=n(a,"epsilon",100),o=n(a,"gravity",50)}else void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=100),void 0===o&&(o=50);r.call(this,t,e,!0),this._gravity=o,this._power=i*o,this._epsilon=s*s},update:function(t,e){var i=this.x-t.x,s=this.y-t.y,n=i*i+s*s;if(0!==n){var r=Math.sqrt(n);n{var s=i(16569),n=i(82897),r=i(56694),o=i(75606),a=i(74118),h=i(2386),l=i(93736),u=new r({initialize:function(t){this.emitter=t,this.texture=null,this.frame=null,this.x=0,this.y=0,this.worldPosition=new l,this.velocityX=0,this.velocityY=0,this.accelerationX=0,this.accelerationY=0,this.maxVelocityX=1e4,this.maxVelocityY=1e4,this.bounce=0,this.scaleX=1,this.scaleY=1,this.alpha=1,this.angle=0,this.rotation=0,this.tint=16777215,this.life=1e3,this.lifeCurrent=1e3,this.delayCurrent=0,this.holdCurrent=0,this.lifeT=0,this.data={tint:{min:16777215,max:16777215},alpha:{min:1,max:1},rotate:{min:0,max:0},scaleX:{min:1,max:1},scaleY:{min:1,max:1},x:{min:0,max:0},y:{min:0,max:0},accelerationX:{min:0,max:0},accelerationY:{min:0,max:0},maxVelocityX:{min:0,max:0},maxVelocityY:{min:0,max:0},moveToX:{min:0,max:0},moveToY:{min:0,max:0},bounce:{min:0,max:0}},this.isCropped=!1,this.scene=t.scene,this.anims=new s(this),this.bounds=new a},emit:function(t,e,i,s,n,r){return this.emitter.emit(t,e,i,s,n,r)},isAlive:function(){return this.lifeCurrent>0},kill:function(){this.lifeCurrent=0},setPosition:function(t,e){void 0===t&&(t=0),void 0===e&&(e=0),this.x=t,this.y=e},fire:function(t,e){var i=this.emitter,s=i.ops,n=i.getAnim();if(n?this.anims.play(n):(this.frame=i.getFrame(),this.texture=this.frame.texture),!this.frame)throw new Error("Particle has no texture frame");if(i.getEmitZone(this),void 0===t?this.x+=s.x.onEmit(this,"x"):s.x.steps>0?this.x+=t+s.x.onEmit(this,"x"):this.x+=t,void 0===e?this.y+=s.y.onEmit(this,"y"):s.y.steps>0?this.y+=e+s.y.onEmit(this,"y"):this.y+=e,this.life=s.lifespan.onEmit(this,"lifespan"),this.lifeCurrent=this.life,this.lifeT=0,this.delayCurrent=s.delay.onEmit(this,"delay"),this.holdCurrent=s.hold.onEmit(this,"hold"),this.scaleX=s.scaleX.onEmit(this,"scaleX"),this.scaleY=s.scaleY.active?s.scaleY.onEmit(this,"scaleY"):this.scaleX,this.angle=s.rotate.onEmit(this,"rotate"),this.rotation=o(this.angle),i.worldMatrix.transformPoint(this.x,this.y,this.worldPosition),0===this.delayCurrent&&i.getDeathZone(this))return this.lifeCurrent=0,!1;var r=s.speedX.onEmit(this,"speedX"),a=s.speedY.active?s.speedY.onEmit(this,"speedY"):r;if(i.radial){var h=o(s.angle.onEmit(this,"angle"));this.velocityX=Math.cos(h)*Math.abs(r),this.velocityY=Math.sin(h)*Math.abs(a)}else if(i.moveTo){var l=s.moveToX.onEmit(this,"moveToX"),u=s.moveToY.onEmit(this,"moveToY"),c=this.life/1e3;this.velocityX=(l-this.x)/c,this.velocityY=(u-this.y)/c}else this.velocityX=r,this.velocityY=a;return i.acceleration&&(this.accelerationX=s.accelerationX.onEmit(this,"accelerationX"),this.accelerationY=s.accelerationY.onEmit(this,"accelerationY")),this.maxVelocityX=s.maxVelocityX.onEmit(this,"maxVelocityX"),this.maxVelocityY=s.maxVelocityY.onEmit(this,"maxVelocityY"),this.bounce=s.bounce.onEmit(this,"bounce"),this.alpha=s.alpha.onEmit(this,"alpha"),s.color.active?this.tint=s.color.onEmit(this,"tint"):this.tint=s.tint.onEmit(this,"tint"),!0},update:function(t,e,i){if(this.lifeCurrent<=0)return!(this.holdCurrent>0)||(this.holdCurrent-=t,this.holdCurrent<=0);if(this.delayCurrent>0)return this.delayCurrent-=t,!1;this.anims.update(0,t);var s=this.emitter,n=s.ops,r=1-this.lifeCurrent/this.life;if(this.lifeT=r,this.x=n.x.onUpdate(this,"x",r,this.x),this.y=n.y.onUpdate(this,"y",r,this.y),s.moveTo){var a=n.moveToX.onUpdate(this,"moveToX",r,s.moveToX),h=n.moveToY.onUpdate(this,"moveToY",r,s.moveToY),l=this.lifeCurrent/1e3;this.velocityX=(a-this.x)/l,this.velocityY=(h-this.y)/l}return this.computeVelocity(s,t,e,i,r),this.scaleX=n.scaleX.onUpdate(this,"scaleX",r,this.scaleX),this.scaleY=this.scaleX,n.scaleY.active&&(this.scaleY=n.scaleY.onUpdate(this,"scaleY",r,this.scaleY)),this.angle=n.rotate.onUpdate(this,"rotate",r,this.angle),this.rotation=o(this.angle),s.getDeathZone(this)?(this.lifeCurrent=0,!0):(this.alpha=n.alpha.onUpdate(this,"alpha",r,this.alpha),n.color.active?this.tint=n.color.onUpdate(this,"color",r,this.tint):this.tint=n.tint.onUpdate(this,"tint",r,this.tint),this.lifeCurrent-=t,this.lifeCurrent<=0&&this.holdCurrent<=0)},computeVelocity:function(t,e,i,s,r){var o=t.ops,a=this.velocityX,h=this.velocityY,l=o.accelerationX.onUpdate(this,"accelerationX",r,this.accelerationX),u=o.accelerationY.onUpdate(this,"accelerationY",r,this.accelerationY),c=o.maxVelocityX.onUpdate(this,"maxVelocityX",r,this.maxVelocityX),d=o.maxVelocityY.onUpdate(this,"maxVelocityY",r,this.maxVelocityY);this.bounce=o.bounce.onUpdate(this,"bounce",r,this.bounce),a+=t.gravityX*i+l*i,h+=t.gravityY*i+u*i,a=n(a,-c,c),h=n(h,-d,d),this.velocityX=a,this.velocityY=h,this.x+=a*i,this.y+=h*i,t.worldMatrix.transformPoint(this.x,this.y,this.worldPosition);for(var f=0;f{var s=i(56694),n=i(30891),r=i(74118),o=new s({Extends:n,initialize:function(t,e,i,s,o,a,h,l){void 0===o&&(o=!0),void 0===a&&(a=!0),void 0===h&&(h=!0),void 0===l&&(l=!0),n.call(this,t,e,!0),this.bounds=new r(t,e,i,s),this.collideLeft=o,this.collideRight=a,this.collideTop=h,this.collideBottom=l},update:function(t){var e=this.bounds,i=-t.bounce,s=t.worldPosition;s.xe.right&&this.collideRight&&(t.x-=s.x-e.right,t.velocityX*=i),s.ye.bottom&&this.collideBottom&&(t.y-=s.y-e.bottom,t.velocityY*=i)}});t.exports=o},9216:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(48129),o=i(29538),a=i(69361),h=i(54213),l=i(19737),u=i(93025),c=i(40629),d=i(89980),f=i(72632),p=i(72861),v=i(87811),g=i(53523),m=i(19256),y=i(7782),x=i(71207),T=i(14655),w=i(14909),b=i(68433),S=i(74118),E=i(90205),A=i(66458),C=i(69116),_=i(17922),M=i(69360),P=i(93736),R=i(1071),O=i(73106),L=["active","advance","blendMode","colorEase","deathCallback","deathCallbackScope","duration","emitCallback","emitCallbackScope","follow","frequency","gravityX","gravityY","maxAliveParticles","maxParticles","name","emitting","particleBringToTop","particleClass","radial","sortCallback","sortOrderAsc","sortProperty","stopAfter","tintFill","timeScale","trackVisible","visible"],F=["accelerationX","accelerationY","alpha","angle","bounce","color","delay","hold","lifespan","maxVelocityX","maxVelocityY","moveToX","moveToY","quantity","rotate","scaleX","scaleY","speedX","speedY","tint","x","y"],D=new s({Extends:d,Mixins:[n.AlphaSingle,n.BlendMode,n.Depth,n.Mask,n.Pipeline,n.PostPipeline,n.ScrollFactor,n.Texture,n.Transform,n.Visible,C],initialize:function(t,e,i,s,n){d.call(this,t,"ParticleEmitter"),this.particleClass=w,this.ops={accelerationX:new u("accelerationX",0),accelerationY:new u("accelerationY",0),alpha:new u("alpha",1),angle:new u("angle",{min:0,max:360},!0),bounce:new u("bounce",0),color:new l("color"),delay:new u("delay",0,!0),hold:new u("hold",0,!0),lifespan:new u("lifespan",1e3,!0),maxVelocityX:new u("maxVelocityX",1e4),maxVelocityY:new u("maxVelocityY",1e4),moveToX:new u("moveToX",0),moveToY:new u("moveToY",0),quantity:new u("quantity",1,!0),rotate:new u("rotate",0),scaleX:new u("scaleX",1),scaleY:new u("scaleY",1),speedX:new u("speedX",0,!0),speedY:new u("speedY",0,!0),tint:new u("tint",16777215),x:new u("x",0),y:new u("y",0)},this.radial=!0,this.gravityX=0,this.gravityY=0,this.acceleration=!1,this.moveTo=!1,this.emitCallback=null,this.emitCallbackScope=null,this.deathCallback=null,this.deathCallbackScope=null,this.maxParticles=0,this.maxAliveParticles=0,this.stopAfter=0,this.duration=0,this.frequency=0,this.emitting=!0,this.particleBringToTop=!0,this.timeScale=1,this.emitZones=[],this.deathZones=[],this.viewBounds=null,this.follow=null,this.followOffset=new P,this.trackVisible=!1,this.frames=[],this.randomFrame=!0,this.frameQuantity=1,this.anims=[],this.randomAnim=!0,this.animQuantity=1,this.dead=[],this.alive=[],this.counters=new Float32Array(10),this.skipping=!1,this.worldMatrix=new M,this.sortProperty="",this.sortOrderAsc=!0,this.sortCallback=this.depthSortCallback,this.processors=new x(this),this.tintFill=!1,this.initPipeline(),this.initPostPipeline(),this.setPosition(e,i),this.setTexture(s),n&&this.setConfig(n)},addedToScene:function(){this.scene.sys.updateList.add(this)},removedFromScene:function(){this.scene.sys.updateList.remove(this)},setConfig:function(t){if(!t)return this;var e=0,i="",s=this.ops;for(e=0;e=this.animQuantity&&(this.animCounter=0,this.currentAnim=R(this.currentAnim+1,0,e-1)),i},setAnim:function(t,e,i){void 0===e&&(e=!0),void 0===i&&(i=1),this.randomAnim=e,this.animQuantity=i,this.currentAnim=0;var s=typeof t;if(this.anims.length=0,Array.isArray(t))this.anims=this.anims.concat(t);else if("string"===s)this.anims.push(t);else if("object"===s){var n=t;(t=f(n,"anims",null))&&(this.anims=this.anims.concat(t));var r=f(n,"cycle",!1);this.randomAnim=!r,this.animQuantity=f(n,"quantity",i)}return 1===this.anims.length&&(this.animQuantity=1,this.randomAnim=!1),this},setRadial:function(t){return void 0===t&&(t=!0),this.radial=t,this},addParticleBounds:function(t,e,i,s,n,r,o,a){if("object"==typeof t){var h=t;t=h.x,e=h.y,i=m(h,"w")?h.w:h.width,s=m(h,"h")?h.h:h.height}return this.addParticleProcessor(new O(t,e,i,s,n,r,o,a))},setParticleSpeed:function(t,e){return void 0===e&&(e=t),this.ops.speedX.onChange(t),t===e?this.ops.speedY.active=!1:this.ops.speedY.onChange(e),this.radial=!0,this},setParticleScale:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=t),this.ops.scaleX.onChange(t),this.ops.scaleY.onChange(e),this},setParticleGravity:function(t,e){return this.gravityX=t,this.gravityY=e,this},setParticleAlpha:function(t){return this.ops.alpha.onChange(t),this},setParticleTint:function(t){return this.ops.tint.onChange(t),this},setEmitterAngle:function(t){return this.ops.angle.onChange(t),this},setParticleLifespan:function(t){return this.ops.lifespan.onChange(t),this},setQuantity:function(t){return this.quantity=t,this},setFrequency:function(t,e){return this.frequency=t,this.flowCounter=t>0?t:0,e&&(this.quantity=e),this},addDeathZone:function(t){var e;Array.isArray(t)||(t=[t]);for(var i=this.deathZones,s=0;s-1&&(this.zoneTotal++,this.zoneTotal===s.total&&(this.zoneTotal=0,this.zoneIndex++,this.zoneIndex===i&&(this.zoneIndex=0)))}},getDeathZone:function(t){for(var e=this.deathZones,i=0;i=0&&(this.zoneIndex=e),this},addParticleProcessor:function(t){return this.processors.exists(t)||(t.emitter&&t.emitter.removeParticleProcessor(t),this.processors.add(t),t.emitter=this),t},removeParticleProcessor:function(t){return this.processors.exists(t)&&(this.processors.remove(t,!0),t.emitter=null),t},getProcessors:function(){return this.processors.getAll("active",!0)},createGravityWell:function(t){return this.addParticleProcessor(new v(t))},reserve:function(t){var e=this.dead;if(this.maxParticles>0){var i=this.getParticleCount();i+t>this.maxParticles&&(t=this.maxParticles-(i+t))}for(var s=0;s0&&this.getParticleCount()>=this.maxParticles||this.maxAliveParticles>0&&this.getAliveParticleCount()>=this.maxAliveParticles},onParticleEmit:function(t,e){return void 0===t?(this.emitCallback=null,this.emitCallbackScope=null):"function"==typeof t&&(this.emitCallback=t,e&&(this.emitCallbackScope=e)),this},onParticleDeath:function(t,e){return void 0===t?(this.deathCallback=null,this.deathCallbackScope=null):"function"==typeof t&&(this.deathCallback=t,e&&(this.deathCallbackScope=e)),this},killAll:function(){for(var t=this.dead,e=this.alive;e.length>0;)t.push(e.pop());return this},forEachAlive:function(t,e){for(var i=this.alive,s=i.length,n=0;n0&&this.fastForward(t),this.emitting=!0,this.resetCounters(this.frequency,!0),void 0!==e&&(this.duration=Math.abs(e)),this.emit(c.START,this)),this},stop:function(t){return void 0===t&&(t=!1),this.emitting&&(this.emitting=!1,t&&this.killAll(),this.emit(c.STOP,this)),this},pause:function(){return this.active=!1,this},resume:function(){return this.active=!0,this},setSortProperty:function(t,e){return void 0===t&&(t=""),void 0===e&&(e=this.true),this.sortProperty=t,this.sortOrderAsc=e,this.sortCallback=this.depthSortCallback,this},setSortCallback:function(t){return t=""!==this.sortProperty?this.depthSortCallback:null,this.sortCallback=t,this},depthSort:function(){return _(this.alive,this.sortCallback.bind(this)),this},depthSortCallback:function(t,e){var i=this.sortProperty;return this.sortOrderAsc?t[i]-e[i]:e[i]-t[i]},flow:function(t,e,i){return void 0===e&&(e=1),this.emitting=!1,this.frequency=t,this.quantity=e,void 0!==i&&(this.stopAfter=i),this.start()},explode:function(t,e,i){this.frequency=-1,this.resetCounters(-1,!0);var s=this.emitParticle(t,e,i);return this.emit(c.EXPLODE,this,s),s},emitParticleAt:function(t,e,i){return this.emitParticle(i,t,e)},emitParticle:function(t,e,i){if(!this.atLimit()){void 0===t&&(t=this.ops.quantity.onEmit());for(var s=this.dead,n=this.stopAfter,r=this.follow?this.follow.x+this.followOffset.x:e,o=this.follow?this.follow.y+this.followOffset.y:i,a=0;a0&&(this.stopCounter++,this.stopCounter>=n))break;if(this.atLimit())break}return h}},fastForward:function(t,e){void 0===e&&(e=1e3/60);var i=0;for(this.skipping=!0;i0){var u=this.deathCallback,d=this.deathCallbackScope;for(o=h-1;o>=0;o--){var f=a[o];n.splice(f.index,1),r.push(f.particle),u&&u.call(d,f.particle),f.particle.setPosition()}}if(this.emitting||this.skipping){if(0===this.frequency)this.emitParticle();else if(this.frequency>0)for(this.flowCounter-=e;this.flowCounter<=0;)this.emitParticle(),this.flowCounter+=this.frequency;this.skipping||(this.duration>0&&(this.elapsed+=e,this.elapsed>=this.duration&&this.stop()),this.stopAfter>0&&this.stopCounter>=this.stopAfter&&this.stop())}else 1===this.completeFlag&&0===n.length&&(this.completeFlag=0,this.emit(c.COMPLETE,this))},overlap:function(t){for(var e=this.getWorldTransformMatrix(),i=this.alive,s=i.length,n=[],r=0;r0){var u=0;for(this.skipping=!0;u0&&y(s,t,t),s},createEmitter:function(){throw new Error("createEmitter removed. See ParticleEmitter docs for info")},particleX:{get:function(){return this.ops.x.current},set:function(t){this.ops.x.onChange(t)}},particleY:{get:function(){return this.ops.y.current},set:function(t){this.ops.y.onChange(t)}},accelerationX:{get:function(){return this.ops.accelerationX.current},set:function(t){this.ops.accelerationX.onChange(t)}},accelerationY:{get:function(){return this.ops.accelerationY.current},set:function(t){this.ops.accelerationY.onChange(t)}},maxVelocityX:{get:function(){return this.ops.maxVelocityX.current},set:function(t){this.ops.maxVelocityX.onChange(t)}},maxVelocityY:{get:function(){return this.ops.maxVelocityY.current},set:function(t){this.ops.maxVelocityY.onChange(t)}},speed:{get:function(){return this.ops.speedX.current},set:function(t){this.ops.speedX.onChange(t),this.ops.speedY.onChange(t)}},speedX:{get:function(){return this.ops.speedX.current},set:function(t){this.ops.speedX.onChange(t)}},speedY:{get:function(){return this.ops.speedY.current},set:function(t){this.ops.speedY.onChange(t)}},moveToX:{get:function(){return this.ops.moveToX.current},set:function(t){this.ops.moveToX.onChange(t)}},moveToY:{get:function(){return this.ops.moveToY.current},set:function(t){this.ops.moveToY.onChange(t)}},bounce:{get:function(){return this.ops.bounce.current},set:function(t){this.ops.bounce.onChange(t)}},particleScaleX:{get:function(){return this.ops.scaleX.current},set:function(t){this.ops.scaleX.onChange(t)}},particleScaleY:{get:function(){return this.ops.scaleY.current},set:function(t){this.ops.scaleY.onChange(t)}},particleColor:{get:function(){return this.ops.color.current},set:function(t){this.ops.color.onChange(t)}},colorEase:{get:function(){return this.ops.color.easeName},set:function(t){this.ops.color.setEase(t)}},particleTint:{get:function(){return this.ops.tint.current},set:function(t){this.ops.tint.onChange(t)}},particleAlpha:{get:function(){return this.ops.alpha.current},set:function(t){this.ops.alpha.onChange(t)}},lifespan:{get:function(){return this.ops.lifespan.current},set:function(t){this.ops.lifespan.onChange(t)}},particleAngle:{get:function(){return this.ops.angle.current},set:function(t){this.ops.angle.onChange(t)}},particleRotate:{get:function(){return this.ops.rotate.current},set:function(t){this.ops.rotate.onChange(t)}},quantity:{get:function(){return this.ops.quantity.current},set:function(t){this.ops.quantity.onChange(t)}},delay:{get:function(){return this.ops.delay.current},set:function(t){this.ops.delay.onChange(t)}},hold:{get:function(){return this.ops.hold.current},set:function(t){this.ops.hold.onChange(t)}},flowCounter:{get:function(){return this.counters[0]},set:function(t){this.counters[0]=t}},frameCounter:{get:function(){return this.counters[1]},set:function(t){this.counters[1]=t}},animCounter:{get:function(){return this.counters[2]},set:function(t){this.counters[2]=t}},elapsed:{get:function(){return this.counters[3]},set:function(t){this.counters[3]=t}},stopCounter:{get:function(){return this.counters[4]},set:function(t){this.counters[4]=t}},completeFlag:{get:function(){return this.counters[5]},set:function(t){this.counters[5]=t}},zoneIndex:{get:function(){return this.counters[6]},set:function(t){this.counters[6]=t}},zoneTotal:{get:function(){return this.counters[7]},set:function(t){this.counters[7]=t}},currentFrame:{get:function(){return this.counters[8]},set:function(t){this.counters[8]=t}},currentAnim:{get:function(){return this.counters[9]},set:function(t){this.counters[9]=t}},preDestroy:function(){var t;this.texture=null,this.frames=null,this.anims=null,this.emitCallback=null,this.emitCallbackScope=null,this.deathCallback=null,this.deathCallbackScope=null,this.emitZones=null,this.deathZones=null,this.bounds=null,this.follow=null,this.counters=null;var e=this.ops;for(t=0;t{var s=i(90205),n=i(69360),r=new n,o=new n,a=new n,h=new n;t.exports=function(t,e,i,n){var l=r,u=o,c=a,d=h;n?(d.loadIdentity(),d.multiply(n),d.translate(e.x,e.y),d.rotate(e.rotation),d.scale(e.scaleX,e.scaleY)):d.applyITRS(e.x,e.y,e.rotation,e.scaleX,e.scaleY);var f=t.currentContext,p=i.roundPixels,v=i.alpha,g=e.alpha,m=e.alive,y=m.length,x=e.viewBounds;if(e.visible&&0!==y&&(!x||s(x,i.worldView))){e.sortCallback&&e.depthSort(),i.addToRenderList(e);var T=e.scrollFactorX,w=e.scrollFactorY;f.save(),f.globalCompositeOperation=t.blendModes[e.blendMode];for(var b=0;b0&&C.height>0){var _=-A.halfWidth,M=-A.halfHeight;f.globalAlpha=E,f.save(),u.setToContext(f),p&&(_=Math.round(_),M=Math.round(M)),f.imageSmoothingEnabled=!A.source.scaleMode,f.drawImage(A.source.image,C.x,C.y,C.width,C.height,_,M,C.width,C.height),f.restore()}}}f.restore()}}},765:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(72632),a=i(9216);n.register("particles",(function(t,e){void 0===t&&(t={});var i=r(t,"key",null),n=o(t,"config",null),h=new a(this.scene,0,0,i);return void 0!==e&&(t.add=e),s(this.scene,h,t),n&&h.setConfig(n),h}))},81212:(t,e,i)=>{var s=i(61286),n=i(9216);s.register("particles",(function(t,e,i,s){return void 0!==t&&"string"==typeof t&&console.warn("ParticleEmitterManager was removed in Phaser 3.60. See documentation for details"),this.displayList.add(new n(this.scene,t,e,i,s))}))},69116:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(10275),r=i(10456),t.exports={renderWebGL:n,renderCanvas:r}},10275:(t,e,i)=>{var s=i(90205),n=i(69360),r=i(75512),o=new n,a=new n,h=new n,l=new n;t.exports=function(t,e,i,n){var u=t.pipelines.set(e.pipeline),c=o,d=a,f=h,p=l;n?(p.loadIdentity(),p.multiply(n),p.translate(e.x,e.y),p.rotate(e.rotation),p.scale(e.scaleX,e.scaleY)):p.applyITRS(e.x,e.y,e.rotation,e.scaleX,e.scaleY);var v=i.roundPixels,g=r.getTintAppendFloatAlpha,m=i.alpha,y=e.alpha,x=e.frame.glTexture;t.pipelines.preBatch(e);var T=e.alive,w=T.length,b=e.viewBounds;if(0!==w&&(!b||s(b,i.worldView))){e.sortCallback&&e.depthSort();var S=u.setGameObject(e,e.frame);i.addToRenderList(e),c.copyFrom(i.matrix),c.multiplyWithOffset(p,-i.scrollX*e.scrollFactorX,-i.scrollY*e.scrollFactorY),t.setBlendMode(e.blendMode),e.mask&&(e.mask.preRenderWebGL(t,e,i),t.pipelines.set(e.pipeline));for(var E=e.tintFill,A=0;A{var s=new(i(56694))({initialize:function(t,e,i){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=!0),this.emitter,this.x=t,this.y=e,this.active=i},update:function(){},destroy:function(){this.emitter=null}});t.exports=s},76100:t=>{t.exports="complete"},26677:t=>{t.exports="deathzone"},62736:t=>{t.exports="explode"},56490:t=>{t.exports="start"},85715:t=>{t.exports="stop"},40629:(t,e,i)=>{t.exports={COMPLETE:i(76100),DEATH_ZONE:i(26677),EXPLODE:i(62736),START:i(56490),STOP:i(85715)}},27684:(t,e,i)=>{t.exports={EmitterColorOp:i(19737),EmitterOp:i(93025),Events:i(40629),GravityWell:i(87811),Particle:i(14909),ParticleBounds:i(73106),ParticleEmitter:i(9216),ParticleProcessor:i(30891),Zones:i(25962)}},69361:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e){this.source=t,this.killOnEnter=e},willKill:function(t){var e=t.worldPosition,i=this.source.contains(e.x,e.y);return i&&this.killOnEnter||!i&&!this.killOnEnter}});t.exports=s},54213:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e,i,s,n,r){void 0===s&&(s=!1),void 0===n&&(n=!0),void 0===r&&(r=-1),this.source=t,this.points=[],this.quantity=e,this.stepRate=i,this.yoyo=s,this.counter=-1,this.seamless=n,this._length=0,this._direction=0,this.total=r,this.updateSource()},updateSource:function(){if(this.points=this.source.getPoints(this.quantity,this.stepRate),this.seamless){var t=this.points[0],e=this.points[this.points.length-1];t.x===e.x&&t.y===e.y&&this.points.pop()}var i=this._length;return this._length=this.points.length,this._lengththis._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=s},68433:(t,e,i)=>{var s=i(56694),n=i(93736),r=new s({initialize:function(t){this.source=t,this._tempVec=new n,this.total=-1},getPoint:function(t){var e=this._tempVec;this.source.getRandomPoint(e),t.x=e.x,t.y=e.y}});t.exports=r},25962:(t,e,i)=>{t.exports={DeathZone:i(69361),EdgeZone:i(54213),RandomZone:i(68433)}},29598:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(13747),o=new s({Extends:r,Mixins:[n.PathFollower],initialize:function(t,e,i,s,n,o){r.call(this,t,i,s,n,o),this.path=e},preUpdate:function(t,e){this.anims.update(t,e),this.pathUpdate(t)}});t.exports=o},19626:(t,e,i)=>{var s=i(61286),n=i(29598);s.register("follower",(function(t,e,i,s,r){var o=new n(this.scene,t,e,i,s,r);return this.displayList.add(o),this.updateList.add(o),o}))},33412:(t,e,i)=>{var s=i(16569),n=i(56694),r=i(99425),o=i(15978),a=i(83321),h=i(76583),l=new n({Extends:a,initialize:function(t,e,i,n,r,o,h,l){n||(n="__DEFAULT"),a.call(this,t,e,i,n,r),this.type="Plane",this.anims=new s(this),this.gridWidth,this.gridHeight,this.isTiled,this._checkerboard=null,this.hideCCW=!1,this.setGridSize(o,h,l),this.setSizeToFrame(!1),this.setViewHeight()},setGridSize:function(t,e,i){void 0===t&&(t=8),void 0===e&&(e=8),void 0===i&&(i=!1);var s=!1;return i&&(s=!0),this.gridWidth=t,this.gridHeight=e,this.isTiled=i,this.clear(),r({mesh:this,widthSegments:t,heightSegments:e,isOrtho:!1,tile:i,flipY:s}),this},setSizeToFrame:function(t){void 0===t&&(t=!0);var e=this.frame;if(this.setPerspective(this.width/e.width,this.height/e.height),this._checkerboard&&this._checkerboard!==this.texture&&this.removeCheckerboard(),!t)return this;var i,s,n=this.gridWidth,r=this.gridHeight,o=this.vertices,a=e.u0,h=e.u1,l=e.v0,u=e.v1,c=0;if(this.isTiled)for(l=e.v1,u=e.v0,s=0;s7&&f>7?c.push(l.r,l.g,l.b,i):c.push(u.r,u.g,u.b,s);r.texImage2D(r.TEXTURE_2D,0,r.RGBA,16,16,0,r.RGBA,r.UNSIGNED_BYTE,new Uint8Array(c)),a.isAlphaPremultiplied=!0,a.isRenderTexture=!1,a.width=16,a.height=16;var p=this.scene.sys.textures.addGLTexture(h(),a,16,16);return this.removeCheckerboard(),this._checkerboard=p,r.bindTexture(r.TEXTURE_2D,null),this.setTexture(p),this.setSizeToFrame(),this.setViewHeight(n),this},removeCheckerboard:function(){this._checkerboard&&(this._checkerboard.destroy(),this._checkerboard=null)},play:function(t,e){return this.anims.play(t,e)},playReverse:function(t,e){return this.anims.playReverse(t,e)},playAfterDelay:function(t,e){return this.anims.playAfterDelay(t,e)},playAfterRepeat:function(t,e){return this.anims.playAfterRepeat(t,e)},stop:function(){return this.anims.stop()},stopAfterDelay:function(t){return this.anims.stopAfterDelay(t)},stopAfterRepeat:function(t){return this.anims.stopAfterRepeat(t)},stopOnFrame:function(t){return this.anims.stopOnFrame(t)},preUpdate:function(t,e){a.prototype.preUpdate.call(this,t,e),this.anims.update(t,e)},preDestroy:function(){this.clear(),this.removeCheckerboard(),this.anims.destroy(),this.anims=void 0,this.debugCallback=null,this.debugGraphic=null}});t.exports=l},10912:(t,e,i)=>{var s=i(88933),n=i(32291),r=i(99325),o=i(20494),a=i(10850),h=i(33412);r.register("plane",(function(t,e){void 0===t&&(t={});var i=o(t,"key",null),r=o(t,"frame",null),l=a(t,"width",8),u=a(t,"height",8),c=a(t,"tile",!1),d=new h(this.scene,0,0,i,r,l,u,c);void 0!==e&&(t.add=e);var f=a(t,"checkerboard",null);if(f){var p=a(f,"color1",16777215),v=a(f,"color2",255),g=a(f,"alpha1",255),m=a(f,"alpha2",255),y=a(f,"height",128);d.createCheckerboard(p,v,g,m,y)}return s(this.scene,d,t),n(d,t),d}))},58322:(t,e,i)=>{var s=i(33412);i(61286).register("plane",(function(t,e,i,n,r,o,a){return this.displayList.add(new s(this.scene,t,e,i,n,r,o,a))}))},13171:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(89980),o=i(74853),a=i(65641),h=i(71606),l=new s({Extends:r,Mixins:[n.AlphaSingle,n.BlendMode,n.Depth,n.Mask,n.Pipeline,n.PostPipeline,n.ScrollFactor,n.Transform,n.Visible,h],initialize:function(t,e,i,s,n,h,l){void 0===s&&(s=16777215),void 0===n&&(n=128),void 0===h&&(h=1),void 0===l&&(l=.1),r.call(this,t,"PointLight"),this.initPipeline(a.POINTLIGHT_PIPELINE),this.initPostPipeline(),this.setPosition(e,i),this.color=o(s),this.intensity=h,this.attenuation=l,this.width=2*n,this.height=2*n,this._radius=n},radius:{get:function(){return this._radius},set:function(t){this._radius=t,this.width=2*t,this.height=2*t}},originX:{get:function(){return.5}},originY:{get:function(){return.5}},displayOriginX:{get:function(){return this._radius}},displayOriginY:{get:function(){return this._radius}}});t.exports=l},162:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(13171);n.register("pointlight",(function(t,e){void 0===t&&(t={});var i=r(t,"color",16777215),n=r(t,"radius",128),a=r(t,"intensity",1),h=r(t,"attenuation",.1),l=new o(this.scene,0,0,i,n,a,h);return void 0!==e&&(t.add=e),s(this.scene,l,t),l}))},91201:(t,e,i)=>{var s=i(61286),n=i(13171);s.register("pointlight",(function(t,e,i,s,r,o){return this.displayList.add(new n(this.scene,t,e,i,s,r,o))}))},71606:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(80590),t.exports={renderWebGL:n,renderCanvas:r}},80590:(t,e,i)=>{var s=i(73329);t.exports=function(t,e,i,n){i.addToRenderList(e);var r=t.pipelines.set(e.pipeline),o=s(e,i,n).calc,a=e.width,h=e.height,l=-e._radius,u=-e._radius,c=l+a,d=u+h,f=o.getX(0,0),p=o.getY(0,0),v=o.getX(l,u),g=o.getY(l,u),m=o.getX(l,d),y=o.getY(l,d),x=o.getX(c,d),T=o.getY(c,d),w=o.getX(c,u),b=o.getY(c,u);t.pipelines.preBatch(e),r.batchPointLight(e,i,v,g,m,y,x,T,w,b,f,p),t.pipelines.postBatch(e)}},15996:(t,e,i)=>{var s=i(56694),n=i(845),r=i(1539),o=new s({Extends:r,initialize:function(t,e,i,s,o){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=32),void 0===o&&(o=32);var a=new n(t.sys.textures,"",s,o);r.call(this,t,e,i,a),this.type="RenderTexture",this.camera=this.texture.camera,this._saved=!1},setSize:function(t,e){this.width=t,this.height=e,this.texture.setSize(t,e),this.updateDisplayOrigin();var i=this.input;return i&&!i.customHitArea&&(i.hitArea.width=t,i.hitArea.height=e),this},resize:function(t,e){return this.setSize(t,e),this},saveTexture:function(t){var e=this.texture;return e.key=t,e.manager.addDynamicTexture(e)&&(this._saved=!0),e},fill:function(t,e,i,s,n,r){return this.texture.fill(t,e,i,s,n,r),this},clear:function(){return this.texture.clear(),this},stamp:function(t,e,i,s,n){return this.texture.stamp(t,e,i,s,n),this},erase:function(t,e,i){return this.texture.erase(t,e,i),this},draw:function(t,e,i,s,n){return this.texture.draw(t,e,i,s,n),this},drawFrame:function(t,e,i,s,n,r){return this.texture.drawFrame(t,e,i,s,n,r),this},repeat:function(t,e,i,s,n,r,o,a,h){return this.texture.repeat(t,e,i,s,n,r,o,a,h),this},beginDraw:function(){return this.texture.beginDraw(),this},batchDraw:function(t,e,i,s,n){return this.texture.batchDraw(t,e,i,s,n),this},batchDrawFrame:function(t,e,i,s,n,r){return this.texture.batchDrawFrame(t,e,i,s,n,r),this},endDraw:function(t){return this.texture.endDraw(t),this},snapshotArea:function(t,e,i,s,n,r,o){return this.texture.snapshotArea(t,e,i,s,n,r,o),this},snapshot:function(t,e,i){return this.snapshotArea(0,0,this.width,this.height,t,e,i)},snapshotPixel:function(t,e,i){return this.snapshotArea(t,e,1,1,i,"pixel")},preDestroy:function(){this._saved||this.texture.destroy()}});t.exports=o},85692:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(15996);n.register("renderTexture",(function(t,e){void 0===t&&(t={});var i=r(t,"x",0),n=r(t,"y",0),a=r(t,"width",32),h=r(t,"height",32),l=new o(this.scene,i,n,a,h);return void 0!==e&&(t.add=e),s(this.scene,l,t),l}))},29599:(t,e,i)=>{var s=i(61286),n=i(15996);s.register("renderTexture",(function(t,e,i,s){return this.displayList.add(new n(this.scene,t,e,i,s))}))},79968:(t,e,i)=>{var s=i(16569),n=i(56694),r=i(64937),o=i(89980),a=i(65641),h=i(58912),l=i(93736),u=new n({Extends:o,Mixins:[r.AlphaSingle,r.BlendMode,r.Depth,r.Flip,r.Mask,r.Pipeline,r.PostPipeline,r.Size,r.Texture,r.Transform,r.Visible,r.ScrollFactor,h],initialize:function(t,e,i,n,r,h,u,c,d){void 0===n&&(n="__DEFAULT"),void 0===h&&(h=2),void 0===u&&(u=!0),o.call(this,t,"Rope"),this.anims=new s(this),this.points=h,this.vertices,this.uv,this.colors,this.alphas,this.tintFill="__DEFAULT"===n,this.dirty=!1,this.horizontal=u,this._flipX=!1,this._flipY=!1,this._perp=new l,this.debugCallback=null,this.debugGraphic=null,this.setTexture(n,r),this.setPosition(e,i),this.setSizeToFrame(),this.initPipeline(a.ROPE_PIPELINE),Array.isArray(h)&&this.resizeArrays(h.length),this.setPoints(h,c,d),this.updateVertices()},addedToScene:function(){this.scene.sys.updateList.add(this)},removedFromScene:function(){this.scene.sys.updateList.remove(this)},preUpdate:function(t,e){var i=this.anims.currentFrame;this.anims.update(t,e),this.anims.currentFrame!==i&&(this.updateUVs(),this.updateVertices())},play:function(t,e,i){return this.anims.play(t,e,i),this},setDirty:function(){return this.dirty=!0,this},setHorizontal:function(t,e,i){return void 0===t&&(t=this.points.length),this.horizontal?this:(this.horizontal=!0,this.setPoints(t,e,i))},setVertical:function(t,e,i){return void 0===t&&(t=this.points.length),this.horizontal?(this.horizontal=!1,this.setPoints(t,e,i)):this},setTintFill:function(t){return void 0===t&&(t=!1),this.tintFill=t,this},setAlphas:function(t,e){var i=this.points.length;if(i<1)return this;var s,n=this.alphas;void 0===t?t=[1]:Array.isArray(t)||void 0!==e||(t=[t]);var r=0;if(void 0!==e)for(s=0;sr&&(o=t[r]),n[r]=o,t.length>r+1&&(o=t[r+1]),n[r+1]=o}return this},setColors:function(t){var e=this.points.length;if(e<1)return this;var i,s=this.colors;void 0===t?t=[16777215]:Array.isArray(t)||(t=[t]);var n=0;if(t.length===e)for(i=0;in&&(r=t[n]),s[n]=r,t.length>n+1&&(r=t[n+1]),s[n+1]=r}return this},setPoints:function(t,e,i){if(void 0===t&&(t=2),"number"==typeof t){var s,n,r,o=t;if(o<2&&(o=2),t=[],this.horizontal)for(r=-this.frame.halfWidth,n=this.frame.width/(o-1),s=0;s{t.exports=function(){}},96027:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(10850),a=i(79968);n.register("rope",(function(t,e){void 0===t&&(t={});var i=r(t,"key",null),n=r(t,"frame",null),h=r(t,"horizontal",!0),l=o(t,"points",void 0),u=o(t,"colors",void 0),c=o(t,"alphas",void 0),d=new a(this.scene,0,0,i,n,l,h,u,c);return void 0!==e&&(t.add=e),s(this.scene,d,t),d}))},31982:(t,e,i)=>{var s=i(79968);i(61286).register("rope",(function(t,e,i,n,r,o,a,h){return this.displayList.add(new s(this.scene,t,e,i,n,r,o,a,h))}))},58912:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(49489),r=i(44598),t.exports={renderWebGL:n,renderCanvas:r}},49489:(t,e,i)=>{var s=i(73329),n=i(75512);t.exports=function(t,e,i,r){i.addToRenderList(e);var o=t.pipelines.set(e.pipeline,e),a=s(e,i,r).calc,h=e.vertices,l=e.uv,u=e.colors,c=e.alphas,d=e.alpha,f=n.getTintAppendFloatAlpha,p=i.roundPixels,v=h.length,g=Math.floor(.5*v);o.flush(),t.pipelines.preBatch(e);var m=o.setGameObject(e),y=o.vertexViewF32,x=o.vertexViewU32,T=o.vertexCount*o.currentShader.vertexComponentCount-1,w=0,b=e.tintFill;e.dirty&&e.updateVertices();for(var S=e.debugCallback,E=[],A=0;A{var s=i(56694),n=i(64937),r=i(89980),o=i(72632),a=i(98611),h=i(22440),l=i(24252),u=i(69360),c=new s({Extends:r,Mixins:[n.ComputedSize,n.Depth,n.GetBounds,n.Mask,n.Origin,n.ScrollFactor,n.Transform,n.Visible,l],initialize:function(t,e,i,s,n,o,a,h){void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=128),void 0===o&&(o=128),r.call(this,t,"Shader"),this.blendMode=-1,this.shader;var l=t.sys.renderer;this.renderer=l,this.gl=l.gl,this.vertexData=new ArrayBuffer(2*Float32Array.BYTES_PER_ELEMENT*6),this.vertexBuffer=l.createVertexBuffer(this.vertexData.byteLength,this.gl.STREAM_DRAW),this.program=null,this.bytes=new Uint8Array(this.vertexData),this.vertexViewF32=new Float32Array(this.vertexData),this._tempMatrix1=new u,this._tempMatrix2=new u,this._tempMatrix3=new u,this.viewMatrix=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),this.projectionMatrix=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),this.uniforms={},this.pointer=null,this._rendererWidth=l.width,this._rendererHeight=l.height,this._textureCount=0,this.framebuffer=null,this.glTexture=null,this.renderToTexture=!1,this.texture=null,this.setPosition(i,s),this.setSize(n,o),this.setOrigin(.5,.5),this.setShader(e,a,h)},willRender:function(t){return!!this.renderToTexture||!(r.RENDER_MASK!==this.renderFlags||0!==this.cameraFilter&&this.cameraFilter&t.id)},setRenderToTexture:function(t,e){if(void 0===e&&(e=!1),!this.renderToTexture){var i=this.width,s=this.height,n=this.renderer;this.glTexture=n.createTextureFromSource(null,i,s,0),this.glTexture.flipY=e,this.framebuffer=n.createFramebuffer(i,s,this.glTexture,!1),this._rendererWidth=i,this._rendererHeight=s,this.renderToTexture=!0,this.projOrtho(0,this.width,this.height,0),t&&(this.texture=this.scene.sys.textures.addGLTexture(t,this.glTexture,i,s))}return this.shader&&(n.pipelines.clear(),this.load(),this.flush(),n.pipelines.rebind()),this},setShader:function(t,e,i){if(void 0===e&&(e=[]),"string"==typeof t){var s=this.scene.sys.cache.shader;if(!s.has(t))return console.warn("Shader missing: "+t),this;this.shader=s.get(t)}else this.shader=t;var n=this.gl,r=this.renderer;this.program&&n.deleteProgram(this.program);var o=r.createProgram(this.shader.vertexSrc,this.shader.fragmentSrc);n.uniformMatrix4fv(n.getUniformLocation(o,"uViewMatrix"),!1,this.viewMatrix),n.uniformMatrix4fv(n.getUniformLocation(o,"uProjectionMatrix"),!1,this.projectionMatrix),n.uniform2f(n.getUniformLocation(o,"uResolution"),this.width,this.height),this.program=o;var h=new Date,l={resolution:{type:"2f",value:{x:this.width,y:this.height}},time:{type:"1f",value:0},mouse:{type:"2f",value:{x:this.width/2,y:this.height/2}},date:{type:"4fv",value:[h.getFullYear(),h.getMonth(),h.getDate(),60*h.getHours()*60+60*h.getMinutes()+h.getSeconds()]},sampleRate:{type:"1f",value:44100},iChannel0:{type:"sampler2D",value:null,textureData:{repeat:!0}},iChannel1:{type:"sampler2D",value:null,textureData:{repeat:!0}},iChannel2:{type:"sampler2D",value:null,textureData:{repeat:!0}},iChannel3:{type:"sampler2D",value:null,textureData:{repeat:!0}}};this.shader.uniforms?this.uniforms=a(!0,{},this.shader.uniforms,l):this.uniforms=l;for(var u=0;u<4;u++)e[u]&&this.setSampler2D("iChannel"+u,e[u],u,i);return this.initUniforms(),this.projOrtho(0,this._rendererWidth,this._rendererHeight,0),this},setPointer:function(t){return this.pointer=t,this},projOrtho:function(t,e,i,s){var n=1/(t-e),r=1/(i-s),o=this.projectionMatrix;o[0]=-2*n,o[5]=-2*r,o[10]=-.001,o[12]=(t+e)*n,o[13]=(s+i)*r,o[14]=-0;var a=this.program,h=this.gl;this.renderer.setProgram(a),h.uniformMatrix4fv(h.getUniformLocation(a,"uProjectionMatrix"),!1,this.projectionMatrix),this._rendererWidth=e,this._rendererHeight=i},initUniforms:function(){var t=this.gl,e=this.renderer.glFuncMap,i=this.program;for(var s in this._textureCount=0,this.uniforms){var n=this.uniforms[s],r=n.type,o=e[r];n.uniformLocation=t.getUniformLocation(i,s),"sampler2D"!==r&&(n.glMatrix=o.matrix,n.glValueLength=o.length,n.glFunc=o.func)}},setSampler2DBuffer:function(t,e,i,s,n,r){void 0===n&&(n=0),void 0===r&&(r={});var o=this.uniforms[t];return o.value=e,r.width=i,r.height=s,o.textureData=r,this._textureCount=n,this.initSampler2D(o),this},setSampler2D:function(t,e,i,s){void 0===i&&(i=0);var n=this.scene.sys.textures;if(n.exists(e)){var r=n.getFrame(e);if(r.glTexture&&r.glTexture.isRenderTexture)return this.setSampler2DBuffer(t,r.glTexture,r.width,r.height,i,s);var o=this.uniforms[t],a=r.source;o.textureKey=e,o.source=a.image,o.value=r.glTexture,a.isGLTexture&&(s||(s={}),s.width=a.width,s.height=a.height),s&&(o.textureData=s),this._textureCount=i,this.initSampler2D(o)}return this},setUniform:function(t,e){return h(this.uniforms,t,e),this},getUniform:function(t){return o(this.uniforms,t,null)},setChannel0:function(t,e){return this.setSampler2D("iChannel0",t,0,e)},setChannel1:function(t,e){return this.setSampler2D("iChannel1",t,1,e)},setChannel2:function(t,e){return this.setSampler2D("iChannel2",t,2,e)},setChannel3:function(t,e){return this.setSampler2D("iChannel3",t,3,e)},initSampler2D:function(t){if(t.value){var e=this.gl;e.activeTexture(e.TEXTURE0+this._textureCount),e.bindTexture(e.TEXTURE_2D,t.value);var i=t.textureData;if(i&&!t.value.isRenderTexture){var s=e[o(i,"magFilter","linear").toUpperCase()],n=e[o(i,"minFilter","linear").toUpperCase()],r=e[o(i,"wrapS","repeat").toUpperCase()],a=e[o(i,"wrapT","repeat").toUpperCase()],h=e[o(i,"format","rgba").toUpperCase()];if(i.repeat&&(r=e.REPEAT,a=e.REPEAT),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,!!i.flipY),i.width){var l=o(i,"width",512),u=o(i,"height",2),c=o(i,"border",0);e.texImage2D(e.TEXTURE_2D,0,h,l,u,c,h,e.UNSIGNED_BYTE,null)}else e.texImage2D(e.TEXTURE_2D,0,h,e.RGBA,e.UNSIGNED_BYTE,t.source);e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,s),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,r),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,a)}this.renderer.setProgram(this.program),e.uniform1i(t.uniformLocation,this._textureCount),this._textureCount++}},syncUniforms:function(){var t,e,i,s,n,r=this.gl,o=this.uniforms,a=0;for(var h in o)i=(t=o[h]).glFunc,e=t.glValueLength,s=t.uniformLocation,null!==(n=t.value)&&(1===e?t.glMatrix?i.call(r,s,t.transpose,n):i.call(r,s,n):2===e?i.call(r,s,n.x,n.y):3===e?i.call(r,s,n.x,n.y,n.z):4===e?i.call(r,s,n.x,n.y,n.z,n.w):"sampler2D"===t.type&&(r.activeTexture(r.TEXTURE0+a),r.bindTexture(r.TEXTURE_2D,n),r.uniform1i(s,a),a++))},load:function(t){var e=this.gl,i=this.width,s=this.height,n=this.renderer,r=this.program,o=this.viewMatrix;if(!this.renderToTexture){var a=-this._displayOriginX,h=-this._displayOriginY;o[0]=t[0],o[1]=t[1],o[4]=t[2],o[5]=t[3],o[8]=t[4],o[9]=t[5],o[12]=o[0]*a+o[4]*h,o[13]=o[1]*a+o[5]*h}e.useProgram(r),e.uniformMatrix4fv(e.getUniformLocation(r,"uViewMatrix"),!1,o),e.uniform2f(e.getUniformLocation(r,"uResolution"),this.width,this.height);var l=this.uniforms,u=l.resolution;u.value.x=i,u.value.y=s,l.time.value=n.game.loop.getDuration();var c=this.pointer;if(c){var d=l.mouse,f=c.x/i,p=1-c.y/s;d.value.x=f.toFixed(2),d.value.y=p.toFixed(2)}this.syncUniforms()},flush:function(){var t=this.width,e=this.height,i=this.program,s=this.gl,n=this.vertexBuffer,r=this.renderer,o=2*Float32Array.BYTES_PER_ELEMENT;this.renderToTexture&&(r.setFramebuffer(this.framebuffer),s.clearColor(0,0,0,0),s.clear(s.COLOR_BUFFER_BIT)),s.bindBuffer(s.ARRAY_BUFFER,n);var a=s.getAttribLocation(i,"inPosition");-1!==a&&(s.enableVertexAttribArray(a),s.vertexAttribPointer(a,2,s.FLOAT,!1,o,0));var h=this.vertexViewF32;h[3]=e,h[4]=t,h[5]=e,h[8]=t,h[9]=e,h[10]=t;s.bufferSubData(s.ARRAY_BUFFER,0,this.bytes.subarray(0,6*o)),s.drawArrays(s.TRIANGLES,0,6),this.renderToTexture&&r.setFramebuffer(null,!1)},setAlpha:function(){},setBlendMode:function(){},preDestroy:function(){var t=this.gl;t.deleteProgram(this.program),t.deleteBuffer(this.vertexBuffer),this.renderToTexture&&(this.renderer.deleteFramebuffer(this.framebuffer),this.texture.destroy(),this.framebuffer=null,this.glTexture=null,this.texture=null)}});t.exports=c},10612:t=>{t.exports=function(){}},13908:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(27902);n.register("shader",(function(t,e){void 0===t&&(t={});var i=r(t,"key",null),n=r(t,"x",0),a=r(t,"y",0),h=r(t,"width",128),l=r(t,"height",128),u=new o(this.scene,i,n,a,h,l);return void 0!==e&&(t.add=e),s(this.scene,u,t),u}))},51979:(t,e,i)=>{var s=i(27902);i(61286).register("shader",(function(t,e,i,n,r,o,a){return this.displayList.add(new s(this.scene,t,e,i,n,r,o,a))}))},24252:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(19782),r=i(10612),t.exports={renderWebGL:n,renderCanvas:r}},19782:(t,e,i)=>{var s=i(73329);t.exports=function(t,e,i,n){if(e.shader){if(i.addToRenderList(e),t.pipelines.clear(),e.renderToTexture)e.load(),e.flush();else{var r=s(e,i,n).calc;t.width===e._rendererWidth&&t.height===e._rendererHeight||e.projOrtho(0,t.width,t.height,0),e.load(r.matrix),e.flush()}t.pipelines.rebind()}}},19543:(t,e,i)=>{var s=i(75512);t.exports=function(t,e,i,n,r,o){for(var a=s.getTintAppendFloatAlpha(i.fillColor,i.fillAlpha*n),h=i.pathData,l=i.pathIndexes,u=0;u{t.exports=function(t,e,i,s){var n=i||e.fillColor,r=s||e.fillAlpha,o=(16711680&n)>>>16,a=(65280&n)>>>8,h=255&n;t.fillStyle="rgba("+o+","+a+","+h+","+r+")"}},17876:t=>{t.exports=function(t,e,i,s){var n=i||e.strokeColor,r=s||e.strokeAlpha,o=(16711680&n)>>>16,a=(65280&n)>>>8,h=255&n;t.strokeStyle="rgba("+o+","+a+","+h+","+r+")",t.lineWidth=e.lineWidth}},91461:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(89980),o=i(88829),a=new s({Extends:r,Mixins:[n.AlphaSingle,n.BlendMode,n.Depth,n.GetBounds,n.Mask,n.Origin,n.Pipeline,n.PostPipeline,n.ScrollFactor,n.Transform,n.Visible],initialize:function(t,e,i){void 0===e&&(e="Shape"),r.call(this,t,e),this.geom=i,this.pathData=[],this.pathIndexes=[],this.fillColor=16777215,this.fillAlpha=1,this.strokeColor=16777215,this.strokeAlpha=1,this.lineWidth=1,this.isFilled=!1,this.isStroked=!1,this.closePath=!0,this._tempLine=new o,this.width=0,this.height=0,this.initPipeline(),this.initPostPipeline()},setFillStyle:function(t,e){return void 0===e&&(e=1),void 0===t?this.isFilled=!1:(this.fillColor=t,this.fillAlpha=e,this.isFilled=!0),this},setStrokeStyle:function(t,e,i){return void 0===i&&(i=1),void 0===t?this.isStroked=!1:(this.lineWidth=t,this.strokeColor=e,this.strokeAlpha=i,this.isStroked=!0),this},setClosePath:function(t){return this.closePath=t,this},setSize:function(t,e){return this.width=t,this.height=e,this},setDisplaySize:function(t,e){return this.displayWidth=t,this.displayHeight=e,this},preDestroy:function(){this.geom=null,this._tempLine=null,this.pathData=[],this.pathIndexes=[]},displayWidth:{get:function(){return this.scaleX*this.width},set:function(t){this.scaleX=t/this.width}},displayHeight:{get:function(){return this.scaleY*this.height},set:function(t){this.scaleY=t/this.height}}});t.exports=a},50262:(t,e,i)=>{var s=i(75512);t.exports=function(t,e,i,n,r){var o=t.strokeTint,a=s.getTintAppendFloatAlpha(e.strokeColor,e.strokeAlpha*i);o.TL=a,o.TR=a,o.BL=a,o.BR=a;var h=e.pathData,l=h.length-1,u=e.lineWidth,c=u/2,d=h[0]-n,f=h[1]-r;e.closePath||(l-=2);for(var p=2;p{var s=i(2213),n=i(56694),r=i(75606),o=i(11117),a=i(26673),h=i(83392),l=i(91461),u=new n({Extends:l,Mixins:[s],initialize:function(t,e,i,s,n,r,o,h,u){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=128),void 0===n&&(n=0),void 0===r&&(r=360),void 0===o&&(o=!1),l.call(this,t,"Arc",new a(0,0,s)),this._startAngle=n,this._endAngle=r,this._anticlockwise=o,this._iterations=.01,this.setPosition(e,i);var c=2*this.geom.radius;this.setSize(c,c),void 0!==h&&this.setFillStyle(h,u),this.updateDisplayOrigin(),this.updateData()},iterations:{get:function(){return this._iterations},set:function(t){this._iterations=t,this.updateData()}},radius:{get:function(){return this.geom.radius},set:function(t){this.geom.radius=t;var e=2*t;this.setSize(e,e),this.updateDisplayOrigin(),this.updateData()}},startAngle:{get:function(){return this._startAngle},set:function(t){this._startAngle=t,this.updateData()}},endAngle:{get:function(){return this._endAngle},set:function(t){this._endAngle=t,this.updateData()}},anticlockwise:{get:function(){return this._anticlockwise},set:function(t){this._anticlockwise=t,this.updateData()}},setRadius:function(t){return this.radius=t,this},setIterations:function(t){return void 0===t&&(t=.01),this.iterations=t,this},setStartAngle:function(t,e){return this._startAngle=t,void 0!==e&&(this._anticlockwise=e),this.updateData()},setEndAngle:function(t,e){return this._endAngle=t,void 0!==e&&(this._anticlockwise=e),this.updateData()},updateData:function(){var t=this._iterations,e=t,i=this.geom.radius,s=r(this._startAngle),n=r(this._endAngle),a=i,l=i;n-=s,this._anticlockwise?n<-h.PI2?n=-h.PI2:n>0&&(n=-h.PI2+n%h.PI2):n>h.PI2?n=h.PI2:n<0&&(n=h.PI2+n%h.PI2);for(var u,c=[a+Math.cos(s)*i,l+Math.sin(s)*i];e<1;)u=n*e+s,c.push(a+Math.cos(u)*i,l+Math.sin(u)*i),e+=t;return u=n+s,c.push(a+Math.cos(u)*i,l+Math.sin(u)*i),c.push(a+Math.cos(s)*i,l+Math.sin(s)*i),this.pathIndexes=o(c),this.pathData=c,this}});t.exports=u},23560:(t,e,i)=>{var s=i(75606),n=i(15608),r=i(17876),o=i(49584);t.exports=function(t,e,i,a){i.addToRenderList(e);var h=t.currentContext;if(o(t,h,e,i,a)){var l=e.radius;h.beginPath(),h.arc(l-e.originX*(2*l),l-e.originY*(2*l),l,s(e._startAngle),s(e._endAngle),e.anticlockwise),e.closePath&&h.closePath(),e.isFilled&&(n(h,e),h.fill()),e.isStroked&&(r(h,e),h.stroke()),h.restore()}}},10369:(t,e,i)=>{var s=i(28593),n=i(61286);n.register("arc",(function(t,e,i,n,r,o,a,h){return this.displayList.add(new s(this.scene,t,e,i,n,r,o,a,h))})),n.register("circle",(function(t,e,i,n,r){return this.displayList.add(new s(this.scene,t,e,i,0,360,!1,n,r))}))},2213:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(58356),r=i(23560),t.exports={renderWebGL:n,renderCanvas:r}},58356:(t,e,i)=>{var s=i(73329),n=i(19543),r=i(50262);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.pipelines.set(e.pipeline),h=s(e,i,o),l=a.calcMatrix.copyFrom(h.calc),u=e._displayOriginX,c=e._displayOriginY,d=i.alpha*e.alpha;t.pipelines.preBatch(e),e.isFilled&&n(a,l,e,d,u,c),e.isStroked&&r(a,e,d,u,c),t.pipelines.postBatch(e)}},15220:(t,e,i)=>{var s=i(56694),n=i(87203),r=i(11117),o=i(74118),a=i(91461),h=new s({Extends:a,Mixins:[n],initialize:function(t,e,i,s,n,r){void 0===e&&(e=0),void 0===i&&(i=0),a.call(this,t,"Curve",s),this._smoothness=32,this._curveBounds=new o,this.closePath=!1,this.setPosition(e,i),void 0!==n&&this.setFillStyle(n,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=[],s=this.geom.getPoints(e),n=0;n{var s=i(15608),n=i(17876),r=i(49584);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.currentContext;if(r(t,a,e,i,o)){var h=e._displayOriginX+e._curveBounds.x,l=e._displayOriginY+e._curveBounds.y,u=e.pathData,c=u.length-1,d=u[0]-h,f=u[1]-l;a.beginPath(),a.moveTo(d,f),e.closePath||(c-=2);for(var p=2;p{var s=i(61286),n=i(15220);s.register("curve",(function(t,e,i,s,r){return this.displayList.add(new n(this.scene,t,e,i,s,r))}))},87203:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(82958),r=i(4024),t.exports={renderWebGL:n,renderCanvas:r}},82958:(t,e,i)=>{var s=i(19543),n=i(73329),r=i(50262);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.pipelines.set(e.pipeline),h=n(e,i,o),l=a.calcMatrix.copyFrom(h.calc),u=e._displayOriginX+e._curveBounds.x,c=e._displayOriginY+e._curveBounds.y,d=i.alpha*e.alpha;t.pipelines.preBatch(e),e.isFilled&&s(a,l,e,d,u,c),e.isStroked&&r(a,e,d,u,c),t.pipelines.postBatch(e)}},28591:(t,e,i)=>{var s=i(56694),n=i(11117),r=i(84171),o=i(95669),a=i(91461),h=new s({Extends:a,Mixins:[r],initialize:function(t,e,i,s,n,r,h){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=128),void 0===n&&(n=128),a.call(this,t,"Ellipse",new o(s/2,n/2,s,n)),this._smoothness=64,this.setPosition(e,i),this.width=s,this.height=n,void 0!==r&&this.setFillStyle(r,h),this.updateDisplayOrigin(),this.updateData()},smoothness:{get:function(){return this._smoothness},set:function(t){this._smoothness=t,this.updateData()}},setSize:function(t,e){return this.width=t,this.height=e,this.geom.setPosition(t/2,e/2),this.geom.setSize(t,e),this.updateData()},setSmoothness:function(t){return this._smoothness=t,this.updateData()},updateData:function(){for(var t=[],e=this.geom.getPoints(this._smoothness),i=0;i{var s=i(15608),n=i(17876),r=i(49584);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.currentContext;if(r(t,a,e,i,o)){var h=e._displayOriginX,l=e._displayOriginY,u=e.pathData,c=u.length-1,d=u[0]-h,f=u[1]-l;a.beginPath(),a.moveTo(d,f),e.closePath||(c-=2);for(var p=2;p{var s=i(28591);i(61286).register("ellipse",(function(t,e,i,n,r,o){return this.displayList.add(new s(this.scene,t,e,i,n,r,o))}))},84171:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(17554),r=i(55881),t.exports={renderWebGL:n,renderCanvas:r}},17554:(t,e,i)=>{var s=i(19543),n=i(73329),r=i(50262);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.pipelines.set(e.pipeline),h=n(e,i,o),l=a.calcMatrix.copyFrom(h.calc),u=e._displayOriginX,c=e._displayOriginY,d=i.alpha*e.alpha;t.pipelines.preBatch(e),e.isFilled&&s(a,l,e,d,u,c),e.isStroked&&r(a,e,d,u,c),t.pipelines.postBatch(e)}},39169:(t,e,i)=>{var s=i(56694),n=i(91461),r=i(88059),o=new s({Extends:n,Mixins:[r],initialize:function(t,e,i,s,r,o,a,h,l,u,c){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=128),void 0===r&&(r=128),void 0===o&&(o=32),void 0===a&&(a=32),n.call(this,t,"Grid",null),this.cellWidth=o,this.cellHeight=a,this.showCells=!0,this.outlineFillColor=0,this.outlineFillAlpha=0,this.showOutline=!0,this.showAltCells=!1,this.altFillColor,this.altFillAlpha,this.setPosition(e,i),this.setSize(s,r),this.setFillStyle(h,l),void 0!==u&&this.setOutlineStyle(u,c),this.updateDisplayOrigin()},setFillStyle:function(t,e){return void 0===e&&(e=1),void 0===t?this.showCells=!1:(this.fillColor=t,this.fillAlpha=e,this.showCells=!0),this},setAltFillStyle:function(t,e){return void 0===e&&(e=1),void 0===t?this.showAltCells=!1:(this.altFillColor=t,this.altFillAlpha=e,this.showAltCells=!0),this},setOutlineStyle:function(t,e){return void 0===e&&(e=1),void 0===t?this.showOutline=!1:(this.outlineFillColor=t,this.outlineFillAlpha=e,this.showOutline=!0),this}});t.exports=o},95525:(t,e,i)=>{var s=i(15608),n=i(17876),r=i(49584);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.currentContext;if(r(t,a,e,i,o)){var h=-e._displayOriginX,l=-e._displayOriginY,u=i.alpha*e.alpha,c=e.width,d=e.height,f=e.cellWidth,p=e.cellHeight,v=Math.ceil(c/f),g=Math.ceil(d/p),m=f,y=p,x=f-(v*f-c),T=p-(g*p-d),w=e.showCells,b=e.showAltCells,S=e.showOutline,E=0,A=0,C=0,_=0,M=0;if(S&&(m--,y--,x===f&&x--,T===p&&T--),w&&e.fillAlpha>0)for(s(a,e),A=0;A0)for(s(a,e,e.altFillColor,e.altFillAlpha*u),A=0;A0){for(n(a,e,e.outlineFillColor,e.outlineFillAlpha*u),E=1;E{var s=i(61286),n=i(39169);s.register("grid",(function(t,e,i,s,r,o,a,h,l,u){return this.displayList.add(new n(this.scene,t,e,i,s,r,o,a,h,l,u))}))},88059:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(50639),r=i(95525),t.exports={renderWebGL:n,renderCanvas:r}},50639:(t,e,i)=>{var s=i(73329),n=i(75512);t.exports=function(t,e,i,r){i.addToRenderList(e);var o=t.pipelines.set(e.pipeline),a=s(e,i,r);o.calcMatrix.copyFrom(a.calc).translate(-e._displayOriginX,-e._displayOriginY);var h,l,u=i.alpha*e.alpha,c=e.width,d=e.height,f=e.cellWidth,p=e.cellHeight,v=Math.ceil(c/f),g=Math.ceil(d/p),m=f,y=p,x=f-(v*f-c),T=p-(g*p-d),w=e.showCells,b=e.showAltCells,S=e.showOutline,E=0,A=0,C=0,_=0,M=0;if(S&&(m--,y--,x===f&&x--,T===p&&T--),t.pipelines.preBatch(e),w&&e.fillAlpha>0)for(h=o.fillTint,l=n.getTintAppendFloatAlpha(e.fillColor,e.fillAlpha*u),h.TL=l,h.TR=l,h.BL=l,h.BR=l,A=0;A0)for(h=o.fillTint,l=n.getTintAppendFloatAlpha(e.altFillColor,e.altFillAlpha*u),h.TL=l,h.TR=l,h.BL=l,h.BR=l,A=0;A0){var P=o.strokeTint,R=n.getTintAppendFloatAlpha(e.outlineFillColor,e.outlineFillAlpha*u);for(P.TL=R,P.TR=R,P.BL=R,P.BR=R,E=1;E{var s=i(72296),n=i(56694),r=i(91461),o=new n({Extends:r,Mixins:[s],initialize:function(t,e,i,s,n,o,a,h){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=48),void 0===n&&(n=32),void 0===o&&(o=15658734),void 0===a&&(a=10066329),void 0===h&&(h=13421772),r.call(this,t,"IsoBox",null),this.projection=4,this.fillTop=o,this.fillLeft=a,this.fillRight=h,this.showTop=!0,this.showLeft=!0,this.showRight=!0,this.isFilled=!0,this.setPosition(e,i),this.setSize(s,n),this.updateDisplayOrigin()},setProjection:function(t){return this.projection=t,this},setFaces:function(t,e,i){return void 0===t&&(t=!0),void 0===e&&(e=!0),void 0===i&&(i=!0),this.showTop=t,this.showLeft=e,this.showRight=i,this},setFillStyle:function(t,e,i){return this.fillTop=t,this.fillLeft=e,this.fillRight=i,this.isFilled=!0,this}});t.exports=o},32884:(t,e,i)=>{var s=i(15608),n=i(49584);t.exports=function(t,e,i,r){i.addToRenderList(e);var o=t.currentContext;if(n(t,o,e,i,r)&&e.isFilled){var a=e.width,h=e.height,l=a/2,u=a/e.projection;e.showTop&&(s(o,e,e.fillTop),o.beginPath(),o.moveTo(-l,-h),o.lineTo(0,-u-h),o.lineTo(l,-h),o.lineTo(l,-1),o.lineTo(0,u-1),o.lineTo(-l,-1),o.lineTo(-l,-h),o.fill()),e.showLeft&&(s(o,e,e.fillLeft),o.beginPath(),o.moveTo(-l,0),o.lineTo(0,u),o.lineTo(0,u-h),o.lineTo(-l,-h),o.lineTo(-l,0),o.fill()),e.showRight&&(s(o,e,e.fillRight),o.beginPath(),o.moveTo(l,0),o.lineTo(0,u),o.lineTo(0,u-h),o.lineTo(l,-h),o.lineTo(l,0),o.fill()),o.restore()}}},88154:(t,e,i)=>{var s=i(61286),n=i(4415);s.register("isobox",(function(t,e,i,s,r,o,a){return this.displayList.add(new n(this.scene,t,e,i,s,r,o,a))}))},72296:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(33101),r=i(32884),t.exports={renderWebGL:n,renderCanvas:r}},33101:(t,e,i)=>{var s=i(73329),n=i(75512);t.exports=function(t,e,i,r){i.addToRenderList(e);var o,a,h,l,u,c,d,f,p,v=t.pipelines.set(e.pipeline),g=s(e,i,r),m=v.calcMatrix.copyFrom(g.calc),y=e.width,x=e.height,T=y/2,w=y/e.projection,b=i.alpha*e.alpha;e.isFilled&&(t.pipelines.preBatch(e),e.showTop&&(o=n.getTintAppendFloatAlpha(e.fillTop,b),a=m.getX(-T,-x),h=m.getY(-T,-x),l=m.getX(0,-w-x),u=m.getY(0,-w-x),c=m.getX(T,-x),d=m.getY(T,-x),f=m.getX(0,w-x),p=m.getY(0,w-x),v.batchQuad(e,a,h,l,u,c,d,f,p,0,0,1,1,o,o,o,o,2)),e.showLeft&&(o=n.getTintAppendFloatAlpha(e.fillLeft,b),a=m.getX(-T,0),h=m.getY(-T,0),l=m.getX(0,w),u=m.getY(0,w),c=m.getX(0,w-x),d=m.getY(0,w-x),f=m.getX(-T,-x),p=m.getY(-T,-x),v.batchQuad(e,a,h,l,u,c,d,f,p,0,0,1,1,o,o,o,o,2)),e.showRight&&(o=n.getTintAppendFloatAlpha(e.fillRight,b),a=m.getX(T,0),h=m.getY(T,0),l=m.getX(0,w),u=m.getY(0,w),c=m.getX(0,w-x),d=m.getY(0,w-x),f=m.getX(T,-x),p=m.getY(T,-x),v.batchQuad(e,a,h,l,u,c,d,f,p,0,0,1,1,o,o,o,o,2)),t.pipelines.postBatch(e))}},65159:(t,e,i)=>{var s=i(56694),n=i(93387),r=i(91461),o=new s({Extends:r,Mixins:[n],initialize:function(t,e,i,s,n,o,a,h,l){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=48),void 0===n&&(n=32),void 0===o&&(o=!1),void 0===a&&(a=15658734),void 0===h&&(h=10066329),void 0===l&&(l=13421772),r.call(this,t,"IsoTriangle",null),this.projection=4,this.fillTop=a,this.fillLeft=h,this.fillRight=l,this.showTop=!0,this.showLeft=!0,this.showRight=!0,this.isReversed=o,this.isFilled=!0,this.setPosition(e,i),this.setSize(s,n),this.updateDisplayOrigin()},setProjection:function(t){return this.projection=t,this},setReversed:function(t){return this.isReversed=t,this},setFaces:function(t,e,i){return void 0===t&&(t=!0),void 0===e&&(e=!0),void 0===i&&(i=!0),this.showTop=t,this.showLeft=e,this.showRight=i,this},setFillStyle:function(t,e,i){return this.fillTop=t,this.fillLeft=e,this.fillRight=i,this.isFilled=!0,this}});t.exports=o},9923:(t,e,i)=>{var s=i(15608),n=i(49584);t.exports=function(t,e,i,r){i.addToRenderList(e);var o=t.currentContext;if(n(t,o,e,i,r)&&e.isFilled){var a=e.width,h=e.height,l=a/2,u=a/e.projection,c=e.isReversed;e.showTop&&c&&(s(o,e,e.fillTop),o.beginPath(),o.moveTo(-l,-h),o.lineTo(0,-u-h),o.lineTo(l,-h),o.lineTo(0,u-h),o.fill()),e.showLeft&&(s(o,e,e.fillLeft),o.beginPath(),c?(o.moveTo(-l,-h),o.lineTo(0,u),o.lineTo(0,u-h)):(o.moveTo(-l,0),o.lineTo(0,u),o.lineTo(0,u-h)),o.fill()),e.showRight&&(s(o,e,e.fillRight),o.beginPath(),c?(o.moveTo(l,-h),o.lineTo(0,u),o.lineTo(0,u-h)):(o.moveTo(l,0),o.lineTo(0,u),o.lineTo(0,u-h)),o.fill()),o.restore()}}},67765:(t,e,i)=>{var s=i(61286),n=i(65159);s.register("isotriangle",(function(t,e,i,s,r,o,a,h){return this.displayList.add(new n(this.scene,t,e,i,s,r,o,a,h))}))},93387:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(54946),r=i(9923),t.exports={renderWebGL:n,renderCanvas:r}},54946:(t,e,i)=>{var s=i(73329),n=i(75512);t.exports=function(t,e,i,r){i.addToRenderList(e);var o=t.pipelines.set(e.pipeline),a=s(e,i,r),h=o.calcMatrix.copyFrom(a.calc),l=e.width,u=e.height,c=l/2,d=l/e.projection,f=e.isReversed,p=i.alpha*e.alpha;if(e.isFilled){var v,g,m,y,x,T,w;if(t.pipelines.preBatch(e),e.showTop&&f){v=n.getTintAppendFloatAlpha(e.fillTop,p),g=h.getX(-c,-u),m=h.getY(-c,-u),y=h.getX(0,-d-u),x=h.getY(0,-d-u),T=h.getX(c,-u),w=h.getY(c,-u);var b=h.getX(0,d-u),S=h.getY(0,d-u);o.batchQuad(e,g,m,y,x,T,w,b,S,0,0,1,1,v,v,v,v,2)}e.showLeft&&(v=n.getTintAppendFloatAlpha(e.fillLeft,p),f?(g=h.getX(-c,-u),m=h.getY(-c,-u),y=h.getX(0,d),x=h.getY(0,d),T=h.getX(0,d-u),w=h.getY(0,d-u)):(g=h.getX(-c,0),m=h.getY(-c,0),y=h.getX(0,d),x=h.getY(0,d),T=h.getX(0,d-u),w=h.getY(0,d-u)),o.batchTri(e,g,m,y,x,T,w,0,0,1,1,v,v,v,2)),e.showRight&&(v=n.getTintAppendFloatAlpha(e.fillRight,p),f?(g=h.getX(c,-u),m=h.getY(c,-u),y=h.getX(0,d),x=h.getY(0,d),T=h.getX(0,d-u),w=h.getY(0,d-u)):(g=h.getX(c,0),m=h.getY(c,0),y=h.getX(0,d),x=h.getY(0,d),T=h.getX(0,d-u),w=h.getY(0,d-u)),o.batchTri(e,g,m,y,x,T,w,0,0,1,1,v,v,v,2)),t.pipelines.postBatch(e)}}},579:(t,e,i)=>{var s=i(56694),n=i(91461),r=i(88829),o=i(52660),a=new s({Extends:n,Mixins:[o],initialize:function(t,e,i,s,o,a,h,l,u){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=0),void 0===o&&(o=0),void 0===a&&(a=128),void 0===h&&(h=0),n.call(this,t,"Line",new r(s,o,a,h));var c=Math.max(1,this.geom.right-this.geom.left),d=Math.max(1,this.geom.bottom-this.geom.top);this.lineWidth=1,this._startWidth=1,this._endWidth=1,this.setPosition(e,i),this.setSize(c,d),void 0!==l&&this.setStrokeStyle(1,l,u),this.updateDisplayOrigin()},setLineWidth:function(t,e){return void 0===e&&(e=t),this._startWidth=t,this._endWidth=e,this.lineWidth=t,this},setTo:function(t,e,i,s){return this.geom.setTo(t,e,i,s),this}});t.exports=a},52044:(t,e,i)=>{var s=i(17876),n=i(49584);t.exports=function(t,e,i,r){i.addToRenderList(e);var o=t.currentContext;if(n(t,o,e,i,r)){var a=e._displayOriginX,h=e._displayOriginY;e.isStroked&&(s(o,e),o.beginPath(),o.moveTo(e.geom.x1-a,e.geom.y1-h),o.lineTo(e.geom.x2-a,e.geom.y2-h),o.stroke()),o.restore()}}},85665:(t,e,i)=>{var s=i(61286),n=i(579);s.register("line",(function(t,e,i,s,r,o,a,h){return this.displayList.add(new n(this.scene,t,e,i,s,r,o,a,h))}))},52660:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(46952),r=i(52044),t.exports={renderWebGL:n,renderCanvas:r}},46952:(t,e,i)=>{var s=i(73329),n=i(75512);t.exports=function(t,e,i,r){i.addToRenderList(e);var o=t.pipelines.set(e.pipeline),a=s(e,i,r);o.calcMatrix.copyFrom(a.calc);var h=e._displayOriginX,l=e._displayOriginY,u=i.alpha*e.alpha;if(t.pipelines.preBatch(e),e.isStroked){var c=o.strokeTint,d=n.getTintAppendFloatAlpha(e.strokeColor,e.strokeAlpha*u);c.TL=d,c.TR=d,c.BL=d,c.BR=d;var f=e._startWidth,p=e._endWidth;o.batchLine(e.geom.x1-h,e.geom.y1-l,e.geom.x2-h,e.geom.y2-l,f,p,1,0,!1,a.sprite,a.camera)}t.pipelines.postBatch(e)}},91249:(t,e,i)=>{var s=i(70573),n=i(56694),r=i(11117),o=i(14045),a=i(8580),h=i(91461),l=i(18974),u=new n({Extends:h,Mixins:[s],initialize:function(t,e,i,s,n,r){void 0===e&&(e=0),void 0===i&&(i=0),h.call(this,t,"Polygon",new a(s));var l=o(this.geom);this.setPosition(e,i),this.setSize(l.width,l.height),void 0!==n&&this.setFillStyle(n,r),this.updateDisplayOrigin(),this.updateData()},smooth:function(t){void 0===t&&(t=1);for(var e=0;e{var s=i(15608),n=i(17876),r=i(49584);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.currentContext;if(r(t,a,e,i,o)){var h=e._displayOriginX,l=e._displayOriginY,u=e.pathData,c=u.length-1,d=u[0]-h,f=u[1]-l;a.beginPath(),a.moveTo(d,f),e.closePath||(c-=2);for(var p=2;p{var s=i(61286),n=i(91249);s.register("polygon",(function(t,e,i,s,r){return this.displayList.add(new n(this.scene,t,e,i,s,r))}))},70573:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(72841),r=i(40834),t.exports={renderWebGL:n,renderCanvas:r}},72841:(t,e,i)=>{var s=i(19543),n=i(73329),r=i(50262);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.pipelines.set(e.pipeline),h=n(e,i,o),l=a.calcMatrix.copyFrom(h.calc),u=e._displayOriginX,c=e._displayOriginY,d=i.alpha*e.alpha;t.pipelines.preBatch(e),e.isFilled&&s(a,l,e,d,u,c),e.isStroked&&r(a,e,d,u,c),t.pipelines.postBatch(e)}},517:(t,e,i)=>{var s=i(56694),n=i(74118),r=i(91461),o=i(37673),a=new s({Extends:r,Mixins:[o],initialize:function(t,e,i,s,o,a,h){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=128),void 0===o&&(o=128),r.call(this,t,"Rectangle",new n(0,0,s,o)),this.setPosition(e,i),this.setSize(s,o),void 0!==a&&this.setFillStyle(a,h),this.updateDisplayOrigin(),this.updateData()},setSize:function(t,e){this.width=t,this.height=e,this.geom.setSize(t,e),this.updateData(),this.updateDisplayOrigin();var i=this.input;return i&&!i.customHitArea&&(i.hitArea.width=t,i.hitArea.height=e),this},updateData:function(){var t=[],e=this.geom,i=this._tempLine;return e.getLineA(i),t.push(i.x1,i.y1,i.x2,i.y2),e.getLineB(i),t.push(i.x2,i.y2),e.getLineC(i),t.push(i.x2,i.y2),e.getLineD(i),t.push(i.x2,i.y2),this.pathData=t,this}});t.exports=a},4091:(t,e,i)=>{var s=i(15608),n=i(17876),r=i(49584);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.currentContext;if(r(t,a,e,i,o)){var h=e._displayOriginX,l=e._displayOriginY;e.isFilled&&(s(a,e),a.fillRect(-h,-l,e.width,e.height)),e.isStroked&&(n(a,e),a.beginPath(),a.rect(-h,-l,e.width,e.height),a.stroke()),a.restore()}}},94355:(t,e,i)=>{var s=i(61286),n=i(517);s.register("rectangle",(function(t,e,i,s,r,o){return this.displayList.add(new n(this.scene,t,e,i,s,r,o))}))},37673:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(43532),r=i(4091),t.exports={renderWebGL:n,renderCanvas:r}},43532:(t,e,i)=>{var s=i(73329),n=i(50262),r=i(75512);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.pipelines.set(e.pipeline),h=s(e,i,o);a.calcMatrix.copyFrom(h.calc);var l=e._displayOriginX,u=e._displayOriginY,c=i.alpha*e.alpha;if(t.pipelines.preBatch(e),e.isFilled){var d=a.fillTint,f=r.getTintAppendFloatAlpha(e.fillColor,e.fillAlpha*c);d.TL=f,d.TR=f,d.BL=f,d.BR=f,a.batchFillRect(-l,-u,e.width,e.height)}e.isStroked&&n(a,e,c,l,u),t.pipelines.postBatch(e)}},77843:(t,e,i)=>{var s=i(87956),n=i(56694),r=i(11117),o=i(91461),a=new n({Extends:o,Mixins:[s],initialize:function(t,e,i,s,n,r,a,h){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=5),void 0===n&&(n=32),void 0===r&&(r=64),o.call(this,t,"Star",null),this._points=s,this._innerRadius=n,this._outerRadius=r,this.setPosition(e,i),this.setSize(2*r,2*r),void 0!==a&&this.setFillStyle(a,h),this.updateDisplayOrigin(),this.updateData()},setPoints:function(t){return this._points=t,this.updateData()},setInnerRadius:function(t){return this._innerRadius=t,this.updateData()},setOuterRadius:function(t){return this._outerRadius=t,this.updateData()},points:{get:function(){return this._points},set:function(t){this._points=t,this.updateData()}},innerRadius:{get:function(){return this._innerRadius},set:function(t){this._innerRadius=t,this.updateData()}},outerRadius:{get:function(){return this._outerRadius},set:function(t){this._outerRadius=t,this.updateData()}},updateData:function(){var t=[],e=this._points,i=this._innerRadius,s=this._outerRadius,n=Math.PI/2*3,o=Math.PI/e,a=s,h=s;t.push(a,h+-s);for(var l=0;l{var s=i(15608),n=i(17876),r=i(49584);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.currentContext;if(r(t,a,e,i,o)){var h=e._displayOriginX,l=e._displayOriginY,u=e.pathData,c=u.length-1,d=u[0]-h,f=u[1]-l;a.beginPath(),a.moveTo(d,f),e.closePath||(c-=2);for(var p=2;p{var s=i(77843);i(61286).register("star",(function(t,e,i,n,r,o,a){return this.displayList.add(new s(this.scene,t,e,i,n,r,o,a))}))},87956:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(12037),r=i(11401),t.exports={renderWebGL:n,renderCanvas:r}},12037:(t,e,i)=>{var s=i(19543),n=i(73329),r=i(50262);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.pipelines.set(e.pipeline),h=n(e,i,o),l=a.calcMatrix.copyFrom(h.calc),u=e._displayOriginX,c=e._displayOriginY,d=i.alpha*e.alpha;t.pipelines.preBatch(e),e.isFilled&&s(a,l,e,d,u,c),e.isStroked&&r(a,e,d,u,c),t.pipelines.postBatch(e)}},21873:(t,e,i)=>{var s=i(56694),n=i(91461),r=i(66349),o=i(70498),a=new s({Extends:n,Mixins:[o],initialize:function(t,e,i,s,o,a,h,l,u,c,d){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=0),void 0===o&&(o=128),void 0===a&&(a=64),void 0===h&&(h=0),void 0===l&&(l=128),void 0===u&&(u=128),n.call(this,t,"Triangle",new r(s,o,a,h,l,u));var f=this.geom.right-this.geom.left,p=this.geom.bottom-this.geom.top;this.setPosition(e,i),this.setSize(f,p),void 0!==c&&this.setFillStyle(c,d),this.updateDisplayOrigin(),this.updateData()},setTo:function(t,e,i,s,n,r){return this.geom.setTo(t,e,i,s,n,r),this.updateData()},updateData:function(){var t=[],e=this.geom,i=this._tempLine;return e.getLineA(i),t.push(i.x1,i.y1,i.x2,i.y2),e.getLineB(i),t.push(i.x2,i.y2),e.getLineC(i),t.push(i.x2,i.y2),this.pathData=t,this}});t.exports=a},60213:(t,e,i)=>{var s=i(15608),n=i(17876),r=i(49584);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.currentContext;if(r(t,a,e,i,o)){var h=e._displayOriginX,l=e._displayOriginY,u=e.geom.x1-h,c=e.geom.y1-l,d=e.geom.x2-h,f=e.geom.y2-l,p=e.geom.x3-h,v=e.geom.y3-l;a.beginPath(),a.moveTo(u,c),a.lineTo(d,f),a.lineTo(p,v),a.closePath(),e.isFilled&&(s(a,e),a.fill()),e.isStroked&&(n(a,e),a.stroke()),a.restore()}}},79296:(t,e,i)=>{var s=i(61286),n=i(21873);s.register("triangle",(function(t,e,i,s,r,o,a,h,l,u){return this.displayList.add(new n(this.scene,t,e,i,s,r,o,a,h,l,u))}))},70498:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(72291),r=i(60213),t.exports={renderWebGL:n,renderCanvas:r}},72291:(t,e,i)=>{var s=i(73329),n=i(50262),r=i(75512);t.exports=function(t,e,i,o){i.addToRenderList(e);var a=t.pipelines.set(e.pipeline),h=s(e,i,o);a.calcMatrix.copyFrom(h.calc);var l=e._displayOriginX,u=e._displayOriginY,c=i.alpha*e.alpha;if(t.pipelines.preBatch(e),e.isFilled){var d=a.fillTint,f=r.getTintAppendFloatAlpha(e.fillColor,e.fillAlpha*c);d.TL=f,d.TR=f,d.BL=f,d.BR=f;var p=e.geom.x1-l,v=e.geom.y1-u,g=e.geom.x2-l,m=e.geom.y2-u,y=e.geom.x3-l,x=e.geom.y3-u;a.batchFillTriangle(p,v,g,m,y,x,h.sprite,h.camera)}e.isStroked&&n(a,e,c,l,u),t.pipelines.postBatch(e)}},13747:(t,e,i)=>{var s=i(16569),n=i(56694),r=i(64937),o=i(89980),a=i(20791),h=new n({Extends:o,Mixins:[r.Alpha,r.BlendMode,r.Depth,r.Flip,r.GetBounds,r.Mask,r.Origin,r.Pipeline,r.PostPipeline,r.ScrollFactor,r.Size,r.TextureCrop,r.Tint,r.Transform,r.Visible,a],initialize:function(t,e,i,n,r){o.call(this,t,"Sprite"),this._crop=this.resetCropObject(),this.anims=new s(this),this.setTexture(n,r),this.setPosition(e,i),this.setSizeToFrame(),this.setOriginFromFrame(),this.initPipeline(),this.initPostPipeline(!0)},addedToScene:function(){this.scene.sys.updateList.add(this)},removedFromScene:function(){this.scene.sys.updateList.remove(this)},preUpdate:function(t,e){this.anims.update(t,e)},play:function(t,e){return this.anims.play(t,e)},playReverse:function(t,e){return this.anims.playReverse(t,e)},playAfterDelay:function(t,e){return this.anims.playAfterDelay(t,e)},playAfterRepeat:function(t,e){return this.anims.playAfterRepeat(t,e)},chain:function(t){return this.anims.chain(t)},stop:function(){return this.anims.stop()},stopAfterDelay:function(t){return this.anims.stopAfterDelay(t)},stopAfterRepeat:function(t){return this.anims.stopAfterRepeat(t)},stopOnFrame:function(t){return this.anims.stopOnFrame(t)},toJSON:function(){return r.ToJSON(this)},preDestroy:function(){this.anims.destroy(),this.anims=void 0}});t.exports=h},27573:t=>{t.exports=function(t,e,i,s){i.addToRenderList(e),t.batchSprite(e,e.frame,i,s)}},89219:(t,e,i)=>{var s=i(88933),n=i(32291),r=i(99325),o=i(20494),a=i(13747);r.register("sprite",(function(t,e){void 0===t&&(t={});var i=o(t,"key",null),r=o(t,"frame",null),h=new a(this.scene,0,0,i,r);return void 0!==e&&(t.add=e),s(this.scene,h,t),n(h,t),h}))},66135:(t,e,i)=>{var s=i(61286),n=i(13747);s.register("sprite",(function(t,e,i,s){return this.displayList.add(new n(this.scene,t,e,i,s))}))},20791:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(21034),r=i(27573),t.exports={renderWebGL:n,renderCanvas:r}},21034:t=>{t.exports=function(t,e,i,s){i.addToRenderList(e),e.pipeline.batchSprite(e,i,s)}},32979:t=>{t.exports=function(t,e,i){var s=t.canvas,n=t.context,r=t.style,o=[],a=0,h=i.length;r.maxLines>0&&r.maxLines1&&(d+=f*(h-1)),{width:a,height:d,lines:h,lineWidths:o,lineSpacing:f,lineHeight:c}}},27030:(t,e,i)=>{var s=i(61068);t.exports=function(t){var e=s.create(this),i=e.getContext("2d",{willReadFrequently:!0});t.syncFont(e,i);var n=i.measureText(t.testString);if("actualBoundingBoxAscent"in n){var r=n.actualBoundingBoxAscent,o=n.actualBoundingBoxDescent;return s.remove(e),{ascent:r,descent:o,fontSize:r+o}}var a=Math.ceil(n.width*t.baselineX),h=a,l=2*h;h=h*t.baselineY|0,e.width=a,e.height=l,i.fillStyle="#f00",i.fillRect(0,0,a,l),i.font=t._font,i.textBaseline="alphabetic",i.fillStyle="#000",i.fillText(t.testString,0,h);var u={ascent:0,descent:0,fontSize:0},c=i.getImageData(0,0,a,l);if(!c)return u.ascent=h,u.descent=h+6,u.fontSize=u.ascent+u.descent,s.remove(e),u;var d,f,p=c.data,v=p.length,g=4*a,m=0,y=!1;for(d=0;dh;d--){for(f=0;f{var s=i(99584),n=i(61068),r=i(56694),o=i(64937),a=i(89980),h=i(32979),l=i(10850),u=i(55638),c=i(80032),d=i(74744),f=new r({Extends:a,Mixins:[o.Alpha,o.BlendMode,o.ComputedSize,o.Crop,o.Depth,o.Flip,o.GetBounds,o.Mask,o.Origin,o.Pipeline,o.PostPipeline,o.ScrollFactor,o.Tint,o.Transform,o.Visible,c],initialize:function(t,e,i,s,r){void 0===e&&(e=0),void 0===i&&(i=0),a.call(this,t,"Text"),this.renderer=t.sys.renderer,this.setPosition(e,i),this.setOrigin(0,0),this.initPipeline(),this.initPostPipeline(!0),this.canvas=n.create(this),this.context=this.canvas.getContext("2d",{willReadFrequently:!0}),this.style=new d(this,r),this.autoRound=!0,this.splitRegExp=/(?:\r\n|\r|\n)/,this._text=void 0,this.padding={left:0,right:0,top:0,bottom:0},this.width=1,this.height=1,this.lineSpacing=0,this.dirty=!1,0===this.style.resolution&&(this.style.resolution=1),this._crop=this.resetCropObject(),this.texture=t.sys.textures.addCanvas(null,this.canvas,!0),this.frame=this.texture.get(),this.frame.source.resolution=this.style.resolution,this.renderer&&this.renderer.gl&&(this.renderer.deleteTexture(this.frame.source.glTexture),this.frame.source.glTexture=null),this.initRTL(),this.setText(s),r&&r.padding&&this.setPadding(r.padding),r&&r.lineSpacing&&this.setLineSpacing(r.lineSpacing)},initRTL:function(){this.style.rtl&&(this.canvas.dir="rtl",this.context.direction="rtl",this.canvas.style.display="none",s(this.canvas,this.scene.sys.canvas),this.originX=1)},runWordWrap:function(t){var e=this.style;if(e.wordWrapCallback){var i=e.wordWrapCallback.call(e.wordWrapCallbackScope,t,this);return Array.isArray(i)&&(i=i.join("\n")),i}return e.wordWrapWidth?e.wordWrapUseAdvanced?this.advancedWordWrap(t,this.context,this.style.wordWrapWidth):this.basicWordWrap(t,this.context,this.style.wordWrapWidth):t},advancedWordWrap:function(t,e,i){for(var s="",n=t.replace(/ +/gi," ").split(this.splitRegExp),r=n.length,o=0;ol){if(0===c){for(var v=f;v.length&&(v=v.slice(0,-1),!((p=e.measureText(v).width)<=l)););if(!v.length)throw new Error("wordWrapWidth < a single character");var g=d.substr(v.length);u[c]=g,h+=v}var m=u[c].length?c:c+1,y=u.slice(m).join(" ").replace(/[ \n]*$/gi,"");n.splice(o+1,0,y),r=n.length;break}h+=f,l-=p}s+=h.replace(/[ \n]*$/gi,"")+"\n"}}return s=s.replace(/[\s|\n]*$/gi,"")},basicWordWrap:function(t,e,i){for(var s="",n=t.split(this.splitRegExp),r=n.length-1,o=e.measureText(" ").width,a=0;a<=r;a++){for(var h=i,l=n[a].split(" "),u=l.length-1,c=0;c<=u;c++){var d=l[c],f=e.measureText(d).width,p=f;ch&&c>0&&(s+="\n",h=i),s+=d,c0&&(d+=l.lineSpacing*v),i.rtl)c=f-c-u.left-u.right;else if("right"===i.align)c+=o-l.lineWidths[v];else if("center"===i.align)c+=(o-l.lineWidths[v])/2;else if("justify"===i.align){if(l.lineWidths[v]/l.width>=.85){var g=l.width-l.lineWidths[v],m=e.measureText(" ").width,y=a[v].trim(),x=y.split(" ");g+=(a[v].length-y.length)*m;for(var T=Math.floor(g/m),w=0;T>0;)x[w]+=" ",w=(w+1)%(x.length-1||1),--T;a[v]=x.join(" ")}}this.autoRound&&(c=Math.round(c),d=Math.round(d)),i.strokeThickness&&(i.syncShadow(e,i.shadowStroke),e.strokeText(a[v],c,d)),i.color&&(i.syncShadow(e,i.shadowFill),e.fillText(a[v],c,d))}e.restore(),this.renderer&&this.renderer.gl&&(this.frame.source.glTexture=this.renderer.canvasToTexture(t,this.frame.source.glTexture,!0),this.frame.glTexture=this.frame.source.glTexture),this.dirty=!0;var b=this.input;return b&&!b.customHitArea&&(b.hitArea.width=this.width,b.hitArea.height=this.height),this},getTextMetrics:function(){return this.style.getTextMetrics()},text:{get:function(){return this._text},set:function(t){this.setText(t)}},toJSON:function(){var t=o.ToJSON(this),e={autoRound:this.autoRound,text:this._text,style:this.style.toJSON(),padding:{left:this.padding.left,right:this.padding.right,top:this.padding.top,bottom:this.padding.bottom}};return t.data=e,t},preDestroy:function(){this.style.rtl&&u(this.canvas),n.remove(this.canvas),this.texture.destroy()}});t.exports=f},71649:t=>{t.exports=function(t,e,i,s){0!==e.width&&0!==e.height&&(i.addToRenderList(e),t.batchSprite(e,e.frame,i,s))}},75397:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(76555);n.register("text",(function(t,e){void 0===t&&(t={});var i=r(t,"text",""),n=r(t,"style",null),a=r(t,"padding",null);null!==a&&(n.padding=a);var h=new o(this.scene,0,0,i,n);return void 0!==e&&(t.add=e),s(this.scene,h,t),h.autoRound=r(t,"autoRound",!0),h.resolution=r(t,"resolution",1),h}))},94627:(t,e,i)=>{var s=i(76555);i(61286).register("text",(function(t,e,i,n){return this.displayList.add(new s(this.scene,t,e,i,n))}))},80032:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(76128),r=i(71649),t.exports={renderWebGL:n,renderCanvas:r}},74744:(t,e,i)=>{var s=i(56694),n=i(20494),r=i(10850),o=i(27030),a={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",!1],shadowFill:["shadow.fill",!1],align:["align","left"],maxLines:["maxLines",0],fixedWidth:["fixedWidth",0],fixedHeight:["fixedHeight",0],resolution:["resolution",0],rtl:["rtl",!1],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",!1]},h=new s({initialize:function(t,e){this.parent=t,this.fontFamily,this.fontSize,this.fontStyle,this.backgroundColor,this.color,this.stroke,this.strokeThickness,this.shadowOffsetX,this.shadowOffsetY,this.shadowColor,this.shadowBlur,this.shadowStroke,this.shadowFill,this.align,this.maxLines,this.fixedWidth,this.fixedHeight,this.resolution,this.rtl,this.testString,this.baselineX,this.baselineY,this.wordWrapWidth,this.wordWrapCallback,this.wordWrapCallbackScope,this.wordWrapUseAdvanced,this._font,this.setStyle(e,!1,!0)},setStyle:function(t,e,i){for(var s in void 0===e&&(e=!0),void 0===i&&(i=!1),t&&t.hasOwnProperty("fontSize")&&"number"==typeof t.fontSize&&(t.fontSize=t.fontSize.toString()+"px"),a){var h=i?a[s][1]:this[s];this[s]="wordWrapCallback"===s||"wordWrapCallbackScope"===s?r(t,a[s][0],h):n(t,a[s][0],h)}var l=r(t,"font",null);null!==l&&this.setFont(l,!1),this._font=[this.fontStyle,this.fontSize,this.fontFamily].join(" ").trim();var u=r(t,"fill",null);null!==u&&(this.color=u);var c=r(t,"metrics",!1);return c?this.metrics={ascent:r(c,"ascent",0),descent:r(c,"descent",0),fontSize:r(c,"fontSize",0)}:!e&&this.metrics||(this.metrics=o(this)),e?this.parent.updateText():this.parent},syncFont:function(t,e){e.font=this._font},syncStyle:function(t,e){e.textBaseline="alphabetic",e.fillStyle=this.color,e.strokeStyle=this.stroke,e.lineWidth=this.strokeThickness,e.lineCap="round",e.lineJoin="round"},syncShadow:function(t,e){e?(t.shadowOffsetX=this.shadowOffsetX,t.shadowOffsetY=this.shadowOffsetY,t.shadowColor=this.shadowColor,t.shadowBlur=this.shadowBlur):(t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowColor=0,t.shadowBlur=0)},update:function(t){return t&&(this._font=[this.fontStyle,this.fontSize,this.fontFamily].join(" ").trim(),this.metrics=o(this)),this.parent.updateText()},setFont:function(t,e){void 0===e&&(e=!0);var i=t,s="",n="";if("string"!=typeof t)i=r(t,"fontFamily","Courier"),s=r(t,"fontSize","16px"),n=r(t,"fontStyle","");else{var o=t.split(" "),a=0;n=o.length>2?o[a++]:"",s=o[a++]||"16px",i=o[a++]||"Courier"}return i===this.fontFamily&&s===this.fontSize&&n===this.fontStyle||(this.fontFamily=i,this.fontSize=s,this.fontStyle=n,e&&this.update(!0)),this.parent},setFontFamily:function(t){return this.fontFamily!==t&&(this.fontFamily=t,this.update(!0)),this.parent},setFontStyle:function(t){return this.fontStyle!==t&&(this.fontStyle=t,this.update(!0)),this.parent},setFontSize:function(t){return"number"==typeof t&&(t=t.toString()+"px"),this.fontSize!==t&&(this.fontSize=t,this.update(!0)),this.parent},setTestString:function(t){return this.testString=t,this.update(!0)},setFixedSize:function(t,e){return this.fixedWidth=t,this.fixedHeight=e,t&&(this.parent.width=t),e&&(this.parent.height=e),this.update(!1)},setBackgroundColor:function(t){return this.backgroundColor=t,this.update(!1)},setFill:function(t){return this.color=t,this.update(!1)},setColor:function(t){return this.color=t,this.update(!1)},setResolution:function(t){return this.resolution=t,this.update(!1)},setStroke:function(t,e){return void 0===e&&(e=this.strokeThickness),void 0===t&&0!==this.strokeThickness?(this.strokeThickness=0,this.update(!0)):this.stroke===t&&this.strokeThickness===e||(this.stroke=t,this.strokeThickness=e,this.update(!0)),this.parent},setShadow:function(t,e,i,s,n,r){return void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i="#000"),void 0===s&&(s=0),void 0===n&&(n=!1),void 0===r&&(r=!0),this.shadowOffsetX=t,this.shadowOffsetY=e,this.shadowColor=i,this.shadowBlur=s,this.shadowStroke=n,this.shadowFill=r,this.update(!1)},setShadowOffset:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.shadowOffsetX=t,this.shadowOffsetY=e,this.update(!1)},setShadowColor:function(t){return void 0===t&&(t="#000"),this.shadowColor=t,this.update(!1)},setShadowBlur:function(t){return void 0===t&&(t=0),this.shadowBlur=t,this.update(!1)},setShadowStroke:function(t){return this.shadowStroke=t,this.update(!1)},setShadowFill:function(t){return this.shadowFill=t,this.update(!1)},setWordWrapWidth:function(t,e){return void 0===e&&(e=!1),this.wordWrapWidth=t,this.wordWrapUseAdvanced=e,this.update(!1)},setWordWrapCallback:function(t,e){return void 0===e&&(e=null),this.wordWrapCallback=t,this.wordWrapCallbackScope=e,this.update(!1)},setAlign:function(t){return void 0===t&&(t="left"),this.align=t,this.update(!1)},setMaxLines:function(t){return void 0===t&&(t=0),this.maxLines=t,this.update(!1)},getTextMetrics:function(){var t=this.metrics;return{ascent:t.ascent,descent:t.descent,fontSize:t.fontSize}},toJSON:function(){var t={};for(var e in a)t[e]=this[e];return t.metrics=this.getTextMetrics(),t},destroy:function(){this.parent=void 0}});t.exports=h},76128:(t,e,i)=>{var s=i(75512);t.exports=function(t,e,i,n){if(0!==e.width&&0!==e.height){i.addToRenderList(e);var r=e.frame,o=r.width,a=r.height,h=s.getTintAppendFloatAlpha,l=t.pipelines.set(e.pipeline,e),u=l.setTexture2D(r.glTexture,e);l.batchTexture(e,r.glTexture,o,a,e.x,e.y,o/e.style.resolution,a/e.style.resolution,e.scaleX,e.scaleY,e.rotation,e.flipX,e.flipY,e.scrollFactorX,e.scrollFactorY,e.displayOriginX,e.displayOriginY,0,0,o,a,h(e.tintTopLeft,i.alpha*e._alphaTL),h(e.tintTopRight,i.alpha*e._alphaTR),h(e.tintBottomLeft,i.alpha*e._alphaBL),h(e.tintBottomRight,i.alpha*e._alphaBR),e.tintFill,0,0,i,n,!1,u)}}},35856:(t,e,i)=>{var s=i(61068),n=i(56694),r=i(64937),o=i(89980),a=i(3504),h=i(8213),l=i(9271),u=i(93736),c=new n({Extends:o,Mixins:[r.Alpha,r.BlendMode,r.ComputedSize,r.Crop,r.Depth,r.Flip,r.GetBounds,r.Mask,r.Origin,r.Pipeline,r.PostPipeline,r.ScrollFactor,r.Tint,r.Transform,r.Visible,l],initialize:function(t,e,i,n,r,h,l){var c=t.sys.renderer;o.call(this,t,"TileSprite");var d=t.sys.textures.get(h),f=d.get(l);f.source.compressionAlgorithm&&(console.warn("TileSprite cannot use compressed texture"),f=(d=t.sys.textures.get("__MISSING")).get()),"DynamicTexture"===d.type&&(console.warn("TileSprite cannot use Dynamic Texture"),f=(d=t.sys.textures.get("__MISSING")).get()),n&&r?(n=Math.floor(n),r=Math.floor(r)):(n=f.width,r=f.height),this._tilePosition=new u,this._tileScale=new u(1,1),this.dirty=!1,this.renderer=c,this.canvas=s.create(this,n,r),this.context=this.canvas.getContext("2d",{willReadFrequently:!1}),this.displayTexture=d,this.displayFrame=f,this._crop=this.resetCropObject(),this.texture=t.sys.textures.addCanvas(null,this.canvas,!0),this.frame=this.texture.get(),this.potWidth=a(f.width),this.potHeight=a(f.height),this.fillCanvas=s.create2D(this,this.potWidth,this.potHeight),this.fillContext=this.fillCanvas.getContext("2d",{willReadFrequently:!1}),this.fillPattern=null,this.setPosition(e,i),this.setSize(n,r),this.setFrame(l),this.setOriginFromFrame(),this.initPipeline(),this.initPostPipeline(!0)},setTexture:function(t,e){return this.displayTexture=this.scene.sys.textures.get(t),this.setFrame(e)},setFrame:function(t){var e=this.displayTexture.get(t);return this.potWidth=a(e.width),this.potHeight=a(e.height),this.canvas.width=0,e.cutWidth&&e.cutHeight?this.renderFlags|=8:this.renderFlags&=-9,this.displayFrame=e,this.dirty=!0,this.updateTileTexture(),this},setTilePosition:function(t,e){return void 0!==t&&(this.tilePositionX=t),void 0!==e&&(this.tilePositionY=e),this},setTileScale:function(t,e){return void 0===t&&(t=this.tileScaleX),void 0===e&&(e=t),this.tileScaleX=t,this.tileScaleY=e,this},updateTileTexture:function(){if(this.dirty&&this.renderer){var t=this.displayFrame;if(t.source.isRenderTexture||t.source.isGLTexture)return console.warn("TileSprites can only use Image or Canvas based textures"),void(this.dirty=!1);var e=this.fillContext,i=this.fillCanvas,s=this.potWidth,n=this.potHeight;this.renderer&&this.renderer.gl||(s=t.cutWidth,n=t.cutHeight),e.clearRect(0,0,s,n),i.width=s,i.height=n,e.drawImage(t.source.image,t.cutX,t.cutY,t.cutWidth,t.cutHeight,0,0,s,n),this.renderer&&this.renderer.gl?this.fillPattern=this.renderer.canvasToTexture(i,this.fillPattern):this.fillPattern=e.createPattern(i,"repeat"),this.updateCanvas(),this.dirty=!1}},updateCanvas:function(){var t=this.canvas;if(t.width===this.width&&t.height===this.height||(t.width=this.width,t.height=this.height,this.frame.setSize(this.width,this.height),this.updateDisplayOrigin(),this.dirty=!0),!this.dirty||this.renderer&&this.renderer.gl)this.dirty=!1;else{var e=this.context;this.scene.sys.game.config.antialias||h.disable(e);var i=this._tileScale.x,s=this._tileScale.y,n=this._tilePosition.x,r=this._tilePosition.y;e.clearRect(0,0,this.width,this.height),e.save(),e.scale(i,s),e.translate(-n,-r),e.fillStyle=this.fillPattern,e.fillRect(n,r,this.width/i,this.height/s),e.restore(),this.dirty=!1}},preDestroy:function(){this.renderer&&this.renderer.gl&&this.renderer.deleteTexture(this.fillPattern),s.remove(this.canvas),s.remove(this.fillCanvas),this.fillPattern=null,this.fillContext=null,this.fillCanvas=null,this.displayTexture=null,this.displayFrame=null,this.texture.destroy(),this.renderer=null},tilePositionX:{get:function(){return this._tilePosition.x},set:function(t){this._tilePosition.x=t,this.dirty=!0}},tilePositionY:{get:function(){return this._tilePosition.y},set:function(t){this._tilePosition.y=t,this.dirty=!0}},tileScaleX:{get:function(){return this._tileScale.x},set:function(t){this._tileScale.x=t,this.dirty=!0}},tileScaleY:{get:function(){return this._tileScale.y},set:function(t){this._tileScale.y=t,this.dirty=!0}}});t.exports=c},93305:t=>{t.exports=function(t,e,i,s){e.updateCanvas(),i.addToRenderList(e),t.batchSprite(e,e.frame,i,s)}},63950:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(35856);n.register("tileSprite",(function(t,e){void 0===t&&(t={});var i=r(t,"x",0),n=r(t,"y",0),a=r(t,"width",512),h=r(t,"height",512),l=r(t,"key",""),u=r(t,"frame",""),c=new o(this.scene,i,n,a,h,l,u);return void 0!==e&&(t.add=e),s(this.scene,c,t),c}))},20509:(t,e,i)=>{var s=i(35856);i(61286).register("tileSprite",(function(t,e,i,n,r,o){return this.displayList.add(new s(this.scene,t,e,i,n,r,o))}))},9271:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(74287),r=i(93305),t.exports={renderWebGL:n,renderCanvas:r}},74287:(t,e,i)=>{var s=i(75512);t.exports=function(t,e,i,n){e.updateCanvas();var r=e.width,o=e.height;if(0!==r&&0!==o){i.addToRenderList(e);var a=s.getTintAppendFloatAlpha,h=t.pipelines.set(e.pipeline,e),l=h.setTexture2D(e.fillPattern,e);h.batchTexture(e,e.fillPattern,e.displayFrame.width*e.tileScaleX,e.displayFrame.height*e.tileScaleY,e.x,e.y,r,o,e.scaleX,e.scaleY,e.rotation,e.flipX,e.flipY,e.scrollFactorX,e.scrollFactorY,e.originX*r,e.originY*o,0,0,r,o,a(e.tintTopLeft,i.alpha*e._alphaTL),a(e.tintTopRight,i.alpha*e._alphaTR),a(e.tintBottomLeft,i.alpha*e._alphaBL),a(e.tintBottomRight,i.alpha*e._alphaBR),e.tintFill,e.tilePositionX%e.displayFrame.width/e.displayFrame.width,e.tilePositionY%e.displayFrame.height/e.displayFrame.height,i,n,!1,l)}}},8630:(t,e,i)=>{var s=i(82897),n=i(56694),r=i(64937),o=i(56631),a=i(97081),h=i(89980),l=i(83392),u=i(76038),c=i(76583),d=i(77974),f=new n({Extends:h,Mixins:[r.Alpha,r.BlendMode,r.Depth,r.Flip,r.GetBounds,r.Mask,r.Origin,r.Pipeline,r.PostPipeline,r.ScrollFactor,r.Size,r.TextureCrop,r.Tint,r.Transform,r.Visible,d],initialize:function(t,e,i,s){h.call(this,t,"Video"),this.video,this.videoTexture,this.videoTextureSource,this.snapshotTexture,this.flipY=!1,this._key=c(),this.touchLocked=!1,this.playWhenUnlocked=!1,this.frameReady=!1,this.isStalled=!1,this.failedPlayAttempts=0,this.metadata,this.retry=0,this.retryInterval=500,this._systemMuted=!1,this._codeMuted=!1,this._systemPaused=!1,this._codePaused=!1,this._callbacks={ended:this.completeHandler.bind(this),legacy:this.legacyPlayHandler.bind(this),playing:this.playingHandler.bind(this),seeked:this.seekedHandler.bind(this),seeking:this.seekingHandler.bind(this),stalled:this.stalledHandler.bind(this),suspend:this.stalledHandler.bind(this),waiting:this.stalledHandler.bind(this)},this._loadCallbackHandler=this.loadErrorHandler.bind(this),this._crop=this.resetCropObject(),this.markers={},this._markerIn=0,this._markerOut=0,this._playingMarker=!1,this._lastUpdate=0,this.cacheKey="",this.isSeeking=!1,this._playCalled=!1,this._rfvCallbackId=0;var n=t.sys.game;this._device=n.device.video,this.setPosition(e,i),this.setSize(256,256),this.initPipeline(),this.initPostPipeline(!0),n.events.on(a.PAUSE,this.globalPause,this),n.events.on(a.RESUME,this.globalResume,this);var r=t.sys.sound;r&&r.on(u.GLOBAL_MUTE,this.globalMute,this),s&&this.load(s)},addedToScene:function(){this.scene.sys.updateList.add(this)},removedFromScene:function(){this.scene.sys.updateList.remove(this)},load:function(t){var e=this.scene.sys.cache.video.get(t);return e?(this.cacheKey=t,this.loadHandler(e.url,e.noAudio,e.crossOrigin)):console.warn("No video in cache for key: "+t),this},changeSource:function(t,e,i,s,n){void 0===e&&(e=!0),void 0===i&&(i=!1),this.cacheKey!==t&&(this.load(t),e&&this.play(i,s,n))},getVideoKey:function(){return this.cacheKey},loadURL:function(t,e,i){void 0===e&&(e=!1);var s=this._device.getVideoURL(t);return s?(this.cacheKey="",this.loadHandler(s.url,e,i)):console.warn("No supported video format found for "+t),this},loadMediaStream:function(t,e,i){return this.loadHandler(null,e,i,t)},loadHandler:function(t,e,i,s){e||(e=!1);var n=this.video;if(n?(this.removeLoadEventHandlers(),this.stop()):((n=document.createElement("video")).controls=!1,n.setAttribute("playsinline","playsinline"),n.setAttribute("preload","auto"),n.setAttribute("disablePictureInPicture","true")),e?(n.muted=!0,n.defaultMuted=!0,n.setAttribute("autoplay","autoplay")):(n.muted=!1,n.defaultMuted=!1,n.removeAttribute("autoplay")),i?n.setAttribute("crossorigin",i):n.removeAttribute("crossorigin"),s)if("srcObject"in n)try{n.srcObject=s}catch(t){if("TypeError"!==t.name)throw t;n.src=URL.createObjectURL(s)}else n.src=URL.createObjectURL(s);else n.src=t;return this.addLoadEventHandlers(),this.retry=0,this.video=n,this._playCalled=!1,n.load(),this},requestVideoFrame:function(t,e){var i=this.video;if(i){var s=e.width,n=e.height,r=this.videoTexture,a=this.videoTextureSource,h=!r||a.source!==i;h?(this._codePaused=i.paused,this._codeMuted=i.muted,r?(a.source=i,a.width=s,a.height=n,r.get().setSize(s,n)):((r=this.scene.sys.textures.create(this._key,i,s,n)).add("__BASE",0,0,0,s,n),this.setTexture(r),this.videoTexture=r,this.videoTextureSource=r.source[0],this.videoTextureSource.setFlipY(this.flipY),this.emit(o.VIDEO_TEXTURE,this,r)),this.setSizeToFrame(),this.updateDisplayOrigin()):a.update(),this.isStalled=!1,this.metadata=e;var l=e.mediaTime;h&&(this._lastUpdate=l,this.emit(o.VIDEO_CREATED,this,s,n),this.frameReady||(this.frameReady=!0,this.emit(o.VIDEO_PLAY,this))),this._playingMarker?l>=this._markerOut&&(i.loop?(i.currentTime=this._markerIn,this.emit(o.VIDEO_LOOP,this)):(this.stop(!1),this.emit(o.VIDEO_COMPLETE,this))):l-1&&i>e&&i=0&&!isNaN(i)&&i>e&&(this.markers[t]=[e,i]),this},playMarker:function(t,e){var i=this.markers[t];return i&&this.play(e,i[0],i[1]),this},removeMarker:function(t){return delete this.markers[t],this},snapshot:function(t,e){return void 0===t&&(t=this.width),void 0===e&&(e=this.height),this.snapshotArea(0,0,this.width,this.height,t,e)},snapshotArea:function(t,e,i,s,n,r){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=this.width),void 0===s&&(s=this.height),void 0===n&&(n=i),void 0===r&&(r=s);var o=this.video,a=this.snapshotTexture;return a?(a.setSize(n,r),o&&a.context.drawImage(o,t,e,i,s,0,0,n,r)):(a=this.scene.sys.textures.createCanvas(c(),n,r),this.snapshotTexture=a,o&&a.context.drawImage(o,t,e,i,s,0,0,n,r)),a.update()},saveSnapshotTexture:function(t){return this.snapshotTexture?this.scene.sys.textures.renameTexture(this.snapshotTexture.key,t):this.snapshotTexture=this.scene.sys.textures.createCanvas(t,this.width,this.height),this.snapshotTexture},playSuccess:function(){if(this._playCalled){this.addEventHandlers(),this._codePaused=!1,this.touchLocked&&(this.touchLocked=!1,this.emit(o.VIDEO_UNLOCKED,this));var t=this.scene.sys.sound;t&&t.mute&&this.setMute(!0),this._markerIn>-1&&(this.video.currentTime=this._markerIn)}},playError:function(t){var e=t.name;"NotAllowedError"===e?(this.touchLocked=!0,this.playWhenUnlocked=!0,this.failedPlayAttempts=1,this.emit(o.VIDEO_LOCKED,this)):"NotSupportedError"===e?(this.stop(!1),this.emit(o.VIDEO_UNSUPPORTED,this,t)):(this.stop(!1),this.emit(o.VIDEO_ERROR,this,t))},legacyPlayHandler:function(){var t=this.video;t&&(this.playSuccess(),t.removeEventListener("playing",this._callbacks.legacy))},playingHandler:function(){this.isStalled=!1,this.emit(o.VIDEO_PLAYING,this)},loadErrorHandler:function(t){this.stop(!1),this.emit(o.VIDEO_ERROR,this,t)},stalledHandler:function(t){this.isStalled=!0,this.emit(o.VIDEO_STALLED,this,t)},completeHandler:function(){this._playCalled=!1,this.emit(o.VIDEO_COMPLETE,this)},preUpdate:function(t,e){this.video&&this._playCalled&&this.touchLocked&&this.playWhenUnlocked&&(this.retry+=e,this.retry>=this.retryInterval&&(this.createPlayPromise(!1),this.retry=0))},seekTo:function(t){var e=this.video;if(e){var i=e.duration;if(i!==1/0&&!isNaN(i)){var s=i*t;this.setCurrentTime(s)}}return this},getCurrentTime:function(){return this.video?this.video.currentTime:0},setCurrentTime:function(t){var e=this.video;if(e){if("string"==typeof t){var i=t[0],s=parseFloat(t.substr(1));"+"===i?t=e.currentTime+s:"-"===i&&(t=e.currentTime-s)}e.currentTime=t}return this},seekingHandler:function(){this.isSeeking=!0,this.emit(o.VIDEO_SEEKING,this)},seekedHandler:function(){this.isSeeking=!1,this.emit(o.VIDEO_SEEKED,this)},getProgress:function(){var t=this.video;if(t){var e=t.duration;if(e!==1/0&&!isNaN(e))return t.currentTime/e}return-1},getDuration:function(){return this.video?this.video.duration:0},setMute:function(t){void 0===t&&(t=!0),this._codeMuted=t;var e=this.video;return e&&(e.muted=!!this._systemMuted||t),this},isMuted:function(){return this._codeMuted},globalMute:function(t,e){this._systemMuted=e;var i=this.video;i&&(i.muted=!!this._codeMuted||e)},globalPause:function(){this._systemPaused=!0,this.video&&!this.video.ended&&(this.removeEventHandlers(),this.video.pause())},globalResume:function(){this._systemPaused=!1,!this.video||this._codePaused||this.video.ended||this.createPlayPromise()},setPaused:function(t){void 0===t&&(t=!0);var e=this.video;return this._codePaused=t,e&&!e.ended&&(t?e.paused||(this.removeEventHandlers(),e.pause()):t||(this._playCalled?e.paused&&!this._systemPaused&&this.createPlayPromise():this.play())),this},pause:function(){return this.setPaused(!0)},resume:function(){return this.setPaused(!1)},getVolume:function(){return this.video?this.video.volume:1},setVolume:function(t){return void 0===t&&(t=1),this.video&&(this.video.volume=s(t,0,1)),this},getPlaybackRate:function(){return this.video?this.video.playbackRate:1},setPlaybackRate:function(t){return this.video&&(this.video.playbackRate=t),this},getLoop:function(){return!!this.video&&this.video.loop},setLoop:function(t){return void 0===t&&(t=!0),this.video&&(this.video.loop=t),this},isPlaying:function(){return!!this.video&&!(this.video.paused||this.video.ended)},isPaused:function(){return this.video&&this._playCalled&&this.video.paused||this._codePaused||this._systemPaused},saveTexture:function(t,e){return void 0===e&&(e=!1),this.videoTexture&&(this.scene.sys.textures.renameTexture(this._key,t),this.videoTextureSource.setFlipY(e)),this._key=t,this.flipY=e,!!this.videoTexture},stop:function(t){void 0===t&&(t=!0);var e=this.video;return e&&(this.removeEventHandlers(),e.cancelVideoFrameCallback(this._rfvCallbackId),e.pause()),this.retry=0,this._playCalled=!1,t&&this.emit(o.VIDEO_STOP,this),this},removeVideoElement:function(){var t=this.video;if(t){for(t.parentNode&&t.parentNode.removeChild(t);t.hasChildNodes();)t.removeChild(t.firstChild);t.removeAttribute("autoplay"),t.removeAttribute("src"),this.video=null}},preDestroy:function(){this.stop(!1),this.removeLoadEventHandlers(),this.removeVideoElement();var t=this.scene.sys.game.events;t.off(a.PAUSE,this.globalPause,this),t.off(a.RESUME,this.globalResume,this);var e=this.scene.sys.sound;e&&e.off(u.GLOBAL_MUTE,this.globalMute,this)}});t.exports=f},56933:t=>{t.exports=function(t,e,i,s){e.videoTexture&&(i.addToRenderList(e),t.batchSprite(e,e.frame,i,s))}},65601:(t,e,i)=>{var s=i(88933),n=i(99325),r=i(20494),o=i(8630);n.register("video",(function(t,e){void 0===t&&(t={});var i=r(t,"key",null),n=new o(this.scene,0,0,i);return void 0!==e&&(t.add=e),s(this.scene,n,t),n}))},215:(t,e,i)=>{var s=i(8630);i(61286).register("video",(function(t,e,i){return this.displayList.add(new s(this.scene,t,e,i))}))},77974:(t,e,i)=>{var s=i(72283),n=s,r=s;n=i(83572),r=i(56933),t.exports={renderWebGL:n,renderCanvas:r}},83572:t=>{t.exports=function(t,e,i,s){e.videoTexture&&(i.addToRenderList(e),e.pipeline.batchSprite(e,i,s))}},71030:(t,e,i)=>{var s=i(95723),n=i(26673),r=i(65650),o=i(56694),a=i(64937),h=i(89980),l=i(74118),u=i(94287),c=new o({Extends:h,Mixins:[a.Depth,a.GetBounds,a.Origin,a.Transform,a.ScrollFactor,a.Visible],initialize:function(t,e,i,n,r){void 0===n&&(n=1),void 0===r&&(r=n),h.call(this,t,"Zone"),this.setPosition(e,i),this.width=n,this.height=r,this.blendMode=s.NORMAL,this.updateDisplayOrigin()},displayWidth:{get:function(){return this.scaleX*this.width},set:function(t){this.scaleX=t/this.width}},displayHeight:{get:function(){return this.scaleY*this.height},set:function(t){this.scaleY=t/this.height}},setSize:function(t,e,i){void 0===i&&(i=!0),this.width=t,this.height=e,this.updateDisplayOrigin();var s=this.input;return i&&s&&!s.customHitArea&&(s.hitArea.width=t,s.hitArea.height=e),this},setDisplaySize:function(t,e){return this.displayWidth=t,this.displayHeight=e,this},setCircleDropZone:function(t){return this.setDropZone(new n(0,0,t),r)},setRectangleDropZone:function(t,e){return this.setDropZone(new l(0,0,t,e),u)},setDropZone:function(t,e){return this.input||this.setInteractive(t,e,!0),this},setAlpha:function(){},setBlendMode:function(){},renderCanvas:function(t,e,i){i.addToRenderList(e)},renderWebGL:function(t,e,i){i.addToRenderList(e)}});t.exports=c},24067:(t,e,i)=>{var s=i(99325),n=i(20494),r=i(71030);s.register("zone",(function(t){var e=n(t,"x",0),i=n(t,"y",0),s=n(t,"width",1),o=n(t,"height",s);return new r(this.scene,e,i,s,o)}))},34546:(t,e,i)=>{var s=i(71030);i(61286).register("zone",(function(t,e,i,n){return this.displayList.add(new s(this.scene,t,e,i,n))}))},95847:t=>{t.exports=function(t){return t.radius>0?Math.PI*t.radius*t.radius:0}},26673:(t,e,i)=>{var s=i(56694),n=i(65650),r=i(94026),o=i(62941),a=i(52394),h=i(30977),l=new s({initialize:function(t,e,i){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),this.type=a.CIRCLE,this.x=t,this.y=e,this._radius=i,this._diameter=2*i},contains:function(t,e){return n(this,t,e)},getPoint:function(t,e){return r(this,t,e)},getPoints:function(t,e,i){return o(this,t,e,i)},getRandomPoint:function(t){return h(this,t)},setTo:function(t,e,i){return this.x=t,this.y=e,this._radius=i,this._diameter=2*i,this},setEmpty:function(){return this._radius=0,this._diameter=0,this},setPosition:function(t,e){return void 0===e&&(e=t),this.x=t,this.y=e,this},isEmpty:function(){return this._radius<=0},radius:{get:function(){return this._radius},set:function(t){this._radius=t,this._diameter=2*t}},diameter:{get:function(){return this._diameter},set:function(t){this._diameter=t,this._radius=.5*t}},left:{get:function(){return this.x-this._radius},set:function(t){this.x=t+this._radius}},right:{get:function(){return this.x+this._radius},set:function(t){this.x=t-this._radius}},top:{get:function(){return this.y-this._radius},set:function(t){this.y=t+this._radius}},bottom:{get:function(){return this.y+this._radius},set:function(t){this.y=t-this._radius}}});t.exports=l},37964:t=>{t.exports=function(t){return Math.PI*t.radius*2}},72233:(t,e,i)=>{var s=i(79967);t.exports=function(t,e,i){return void 0===i&&(i=new s),i.x=t.x+t.radius*Math.cos(e),i.y=t.y+t.radius*Math.sin(e),i}},61761:(t,e,i)=>{var s=i(26673);t.exports=function(t){return new s(t.x,t.y,t.radius)}},65650:t=>{t.exports=function(t,e,i){return t.radius>0&&e>=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}},39187:(t,e,i)=>{var s=i(65650);t.exports=function(t,e){return s(t,e.x,e.y)}},58672:(t,e,i)=>{var s=i(65650);t.exports=function(t,e){return s(t,e.x,e.y)&&s(t,e.right,e.y)&&s(t,e.x,e.bottom)&&s(t,e.right,e.bottom)}},42997:t=>{t.exports=function(t,e){return e.setTo(t.x,t.y,t.radius)}},94894:t=>{t.exports=function(t,e){return t.x===e.x&&t.y===e.y&&t.radius===e.radius}},48027:(t,e,i)=>{var s=i(74118);t.exports=function(t,e){return void 0===e&&(e=new s),e.x=t.left,e.y=t.top,e.width=t.diameter,e.height=t.diameter,e}},94026:(t,e,i)=>{var s=i(72233),n=i(91806),r=i(83392),o=i(79967);t.exports=function(t,e,i){void 0===i&&(i=new o);var a=n(e,0,r.PI2);return s(t,a,i)}},62941:(t,e,i)=>{var s=i(37964),n=i(72233),r=i(91806),o=i(83392);t.exports=function(t,e,i,a){void 0===a&&(a=[]),!e&&i>0&&(e=s(t)/i);for(var h=0;h{t.exports=function(t,e,i){return t.x+=e,t.y+=i,t}},88665:t=>{t.exports=function(t,e){return t.x+=e.x,t.y+=e.y,t}},30977:(t,e,i)=>{var s=i(79967);t.exports=function(t,e){void 0===e&&(e=new s);var i=2*Math.PI*Math.random(),n=Math.random()+Math.random(),r=n>1?2-n:n,o=r*Math.cos(i),a=r*Math.sin(i);return e.x=t.x+o*t.radius,e.y=t.y+a*t.radius,e}},6112:(t,e,i)=>{var s=i(26673);s.Area=i(95847),s.Circumference=i(37964),s.CircumferencePoint=i(72233),s.Clone=i(61761),s.Contains=i(65650),s.ContainsPoint=i(39187),s.ContainsRect=i(58672),s.CopyFrom=i(42997),s.Equals=i(94894),s.GetBounds=i(48027),s.GetPoint=i(94026),s.GetPoints=i(62941),s.Offset=i(34585),s.OffsetPoint=i(88665),s.Random=i(30977),t.exports=s},52394:t=>{t.exports={CIRCLE:0,ELLIPSE:1,LINE:2,POINT:3,POLYGON:4,RECTANGLE:5,TRIANGLE:6}},58605:t=>{t.exports=function(t){return t.isEmpty()?0:t.getMajorRadius()*t.getMinorRadius()*Math.PI}},39507:t=>{t.exports=function(t){var e=t.width/2,i=t.height/2,s=Math.pow(e-i,2)/Math.pow(e+i,2);return Math.PI*(e+i)*(1+3*s/(10+Math.sqrt(4-3*s)))}},86998:(t,e,i)=>{var s=i(79967);t.exports=function(t,e,i){void 0===i&&(i=new s);var n=t.width/2,r=t.height/2;return i.x=t.x+n*Math.cos(e),i.y=t.y+r*Math.sin(e),i}},81773:(t,e,i)=>{var s=i(95669);t.exports=function(t){return new s(t.x,t.y,t.width,t.height)}},72313:t=>{t.exports=function(t,e,i){if(t.width<=0||t.height<=0)return!1;var s=(e-t.x)/t.width,n=(i-t.y)/t.height;return(s*=s)+(n*=n)<.25}},34368:(t,e,i)=>{var s=i(72313);t.exports=function(t,e){return s(t,e.x,e.y)}},71431:(t,e,i)=>{var s=i(72313);t.exports=function(t,e){return s(t,e.x,e.y)&&s(t,e.right,e.y)&&s(t,e.x,e.bottom)&&s(t,e.right,e.bottom)}},75459:t=>{t.exports=function(t,e){return e.setTo(t.x,t.y,t.width,t.height)}},95669:(t,e,i)=>{var s=i(56694),n=i(72313),r=i(95340),o=i(54978),a=i(52394),h=i(72006),l=new s({initialize:function(t,e,i,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=0),this.type=a.ELLIPSE,this.x=t,this.y=e,this.width=i,this.height=s},contains:function(t,e){return n(this,t,e)},getPoint:function(t,e){return r(this,t,e)},getPoints:function(t,e,i){return o(this,t,e,i)},getRandomPoint:function(t){return h(this,t)},setTo:function(t,e,i,s){return this.x=t,this.y=e,this.width=i,this.height=s,this},setEmpty:function(){return this.width=0,this.height=0,this},setPosition:function(t,e){return void 0===e&&(e=t),this.x=t,this.y=e,this},setSize:function(t,e){return void 0===e&&(e=t),this.width=t,this.height=e,this},isEmpty:function(){return this.width<=0||this.height<=0},getMinorRadius:function(){return Math.min(this.width,this.height)/2},getMajorRadius:function(){return Math.max(this.width,this.height)/2},left:{get:function(){return this.x-this.width/2},set:function(t){this.x=t+this.width/2}},right:{get:function(){return this.x+this.width/2},set:function(t){this.x=t-this.width/2}},top:{get:function(){return this.y-this.height/2},set:function(t){this.y=t+this.height/2}},bottom:{get:function(){return this.y+this.height/2},set:function(t){this.y=t-this.height/2}}});t.exports=l},98068:t=>{t.exports=function(t,e){return t.x===e.x&&t.y===e.y&&t.width===e.width&&t.height===e.height}},72897:(t,e,i)=>{var s=i(74118);t.exports=function(t,e){return void 0===e&&(e=new s),e.x=t.left,e.y=t.top,e.width=t.width,e.height=t.height,e}},95340:(t,e,i)=>{var s=i(86998),n=i(91806),r=i(83392),o=i(79967);t.exports=function(t,e,i){void 0===i&&(i=new o);var a=n(e,0,r.PI2);return s(t,a,i)}},54978:(t,e,i)=>{var s=i(39507),n=i(86998),r=i(91806),o=i(83392);t.exports=function(t,e,i,a){void 0===a&&(a=[]),!e&&i>0&&(e=s(t)/i);for(var h=0;h{t.exports=function(t,e,i){return t.x+=e,t.y+=i,t}},36233:t=>{t.exports=function(t,e){return t.x+=e.x,t.y+=e.y,t}},72006:(t,e,i)=>{var s=i(79967);t.exports=function(t,e){void 0===e&&(e=new s);var i=Math.random()*Math.PI*2,n=Math.sqrt(Math.random());return e.x=t.x+n*Math.cos(i)*t.width/2,e.y=t.y+n*Math.sin(i)*t.height/2,e}},40652:(t,e,i)=>{var s=i(95669);s.Area=i(58605),s.Circumference=i(39507),s.CircumferencePoint=i(86998),s.Clone=i(81773),s.Contains=i(72313),s.ContainsPoint=i(34368),s.ContainsRect=i(71431),s.CopyFrom=i(75459),s.Equals=i(98068),s.GetBounds=i(72897),s.GetPoint=i(95340),s.GetPoints=i(54978),s.Offset=i(77951),s.OffsetPoint=i(36233),s.Random=i(72006),t.exports=s},84068:(t,e,i)=>{var s=i(52394),n=i(98611),r={Circle:i(6112),Ellipse:i(40652),Intersects:i(7563),Line:i(28482),Mesh:i(14293),Point:i(63472),Polygon:i(44359),Rectangle:i(66658),Triangle:i(87619)};r=n(!1,r,s),t.exports=r},22184:(t,e,i)=>{var s=i(53996);t.exports=function(t,e){return s(t.x,t.y,e.x,e.y)<=t.radius+e.radius}},26535:t=>{t.exports=function(t,e){var i=e.width/2,s=e.height/2,n=Math.abs(t.x-e.x-i),r=Math.abs(t.y-e.y-s),o=i+t.radius,a=s+t.radius;if(n>o||r>a)return!1;if(n<=i||r<=s)return!0;var h=n-i,l=r-s;return h*h+l*l<=t.radius*t.radius}},71145:(t,e,i)=>{var s=i(79967),n=i(22184);t.exports=function(t,e,i){if(void 0===i&&(i=[]),n(t,e)){var r,o,a,h,l=t.x,u=t.y,c=t.radius,d=e.x,f=e.y,p=e.radius;if(u===f)0===(a=(o=-2*f)*o-4*(r=1)*(d*d+(h=(p*p-c*c-d*d+l*l)/(2*(l-d)))*h-2*d*h+f*f-p*p))?i.push(new s(h,-o/(2*r))):a>0&&(i.push(new s(h,(-o+Math.sqrt(a))/(2*r))),i.push(new s(h,(-o-Math.sqrt(a))/(2*r))));else{var v=(l-d)/(u-f),g=(p*p-c*c-d*d+l*l-f*f+u*u)/(2*(u-f));0===(a=(o=2*u*v-2*g*v-2*l)*o-4*(r=v*v+1)*(l*l+u*u+g*g-c*c-2*u*g))?(h=-o/(2*r),i.push(new s(h,g-h*v))):a>0&&(h=(-o+Math.sqrt(a))/(2*r),i.push(new s(h,g-h*v)),h=(-o-Math.sqrt(a))/(2*r),i.push(new s(h,g-h*v)))}}return i}},62508:(t,e,i)=>{var s=i(26111),n=i(26535);t.exports=function(t,e,i){if(void 0===i&&(i=[]),n(t,e)){var r=e.getLineA(),o=e.getLineB(),a=e.getLineC(),h=e.getLineD();s(r,t,i),s(o,t,i),s(a,t,i),s(h,t,i)}return i}},26111:(t,e,i)=>{var s=i(79967),n=i(61472);t.exports=function(t,e,i){if(void 0===i&&(i=[]),n(t,e)){var r,o,a=t.x1,h=t.y1,l=t.x2,u=t.y2,c=e.x,d=e.y,f=e.radius,p=l-a,v=u-h,g=a-c,m=h-d,y=p*p+v*v,x=2*(p*g+v*m),T=x*x-4*y*(g*g+m*m-f*f);if(0===T){var w=-x/(2*y);r=a+w*p,o=h+w*v,w>=0&&w<=1&&i.push(new s(r,o))}else if(T>0){var b=(-x-Math.sqrt(T))/(2*y);r=a+b*p,o=h+b*v,b>=0&&b<=1&&i.push(new s(r,o));var S=(-x+Math.sqrt(T))/(2*y);r=a+S*p,o=h+S*v,S>=0&&S<=1&&i.push(new s(r,o))}}return i}},96537:(t,e,i)=>{var s=i(70015);t.exports=function(t,e,i,n){void 0===i&&(i=!1);var r,o,a,h=t.x1,l=t.y1,u=t.x2,c=t.y2,d=e.x1,f=e.y1,p=u-h,v=c-l,g=e.x2-d,m=e.y2-f,y=p*m-v*g;if(0===y)return null;if(i){if((o=(d+g*(r=(p*(f-l)+v*(h-d))/(g*v-m*p))-h)/p)<0||r<0||r>1)return null;a=o}else{if(o=((l-f)*p-(h-d)*v)/y,(r=((d-h)*m-(f-l)*g)/y)<0||r>1||o<0||o>1)return null;a=r}return void 0===n&&(n=new s),n.set(h+p*a,l+v*a,a)}},17647:(t,e,i)=>{var s=i(96537),n=i(88829),r=i(70015),o=new n,a=new r;t.exports=function(t,e,i,n){void 0===i&&(i=!1),void 0===n&&(n=new r);var h=!1;n.set(),a.set();for(var l=e[0],u=1;u{var s=i(70015),n=i(51729),r=i(17647),o=new s;t.exports=function(t,e,i,s){void 0===s&&(s=new n),Array.isArray(e)||(e=[e]);var a=!1;s.set(),o.set();for(var h=0;h{var s=i(79967),n=i(25227),r=i(47910);t.exports=function(t,e,i){if(void 0===i&&(i=[]),r(t,e))for(var o=e.getLineA(),a=e.getLineB(),h=e.getLineC(),l=e.getLineD(),u=[new s,new s,new s,new s],c=[n(o,t,u[0]),n(a,t,u[1]),n(h,t,u[2]),n(l,t,u[3])],d=0;d<4;d++)c[d]&&i.push(u[d]);return i}},7449:(t,e,i)=>{var s=i(51729),n=i(68439),r=new(i(88829));function o(t,e,i,o,a){var h=Math.cos(t),l=Math.sin(t);r.setTo(e,i,e+h,i+l);var u=n(r,o,!0);u&&a.push(new s(u.x,u.y,t,u.w))}function a(t,e){return t.z-e.z}t.exports=function(t,e,i){Array.isArray(i)||(i=[i]);for(var s=[],n=[],r=0;r{var s=i(74118),n=i(90205);t.exports=function(t,e,i){return void 0===i&&(i=new s),n(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}},1946:(t,e,i)=>{var s=i(9569),n=i(90205);t.exports=function(t,e,i){if(void 0===i&&(i=[]),n(t,e)){var r=t.getLineA(),o=t.getLineB(),a=t.getLineC(),h=t.getLineD();s(r,e,i),s(o,e,i),s(a,e,i),s(h,e,i)}return i}},34211:(t,e,i)=>{var s=i(20370),n=i(9569);t.exports=function(t,e,i){if(void 0===i&&(i=[]),s(t,e)){var r=e.getLineA(),o=e.getLineB(),a=e.getLineC();n(r,t,i),n(o,t,i),n(a,t,i)}return i}},80511:(t,e,i)=>{var s=i(26111),n=i(48411);t.exports=function(t,e,i){if(void 0===i&&(i=[]),n(t,e)){var r=t.getLineA(),o=t.getLineB(),a=t.getLineC();s(r,e,i),s(o,e,i),s(a,e,i)}return i}},31343:(t,e,i)=>{var s=i(79967),n=i(86117),r=i(25227);t.exports=function(t,e,i){if(void 0===i&&(i=[]),n(t,e))for(var o=t.getLineA(),a=t.getLineB(),h=t.getLineC(),l=[new s,new s,new s],u=[r(o,e,l[0]),r(a,e,l[1]),r(h,e,l[2])],c=0;c<3;c++)u[c]&&i.push(l[c]);return i}},70534:(t,e,i)=>{var s=i(23589),n=i(31343);t.exports=function(t,e,i){if(void 0===i&&(i=[]),s(t,e)){var r=e.getLineA(),o=e.getLineB(),a=e.getLineC();n(t,r,i),n(t,o,i),n(t,a,i)}return i}},61472:(t,e,i)=>{var s=i(65650),n=new(i(79967));t.exports=function(t,e,i){if(void 0===i&&(i=n),s(e,t.x1,t.y1))return i.x=t.x1,i.y=t.y1,!0;if(s(e,t.x2,t.y2))return i.x=t.x2,i.y=t.y2,!0;var r=t.x2-t.x1,o=t.y2-t.y1,a=e.x-t.x1,h=e.y-t.y1,l=r*r+o*o,u=r,c=o;if(l>0){var d=(a*r+h*o)/l;u*=d,c*=d}return i.x=t.x1+u,i.y=t.y1+c,u*u+c*c<=l&&u*r+c*o>=0&&s(e,i.x,i.y)}},25227:t=>{t.exports=function(t,e,i){var s=t.x1,n=t.y1,r=t.x2,o=t.y2,a=e.x1,h=e.y1,l=e.x2,u=e.y2;if(s===r&&n===o||a===l&&h===u)return!1;var c=(u-h)*(r-s)-(l-a)*(o-n);if(0===c)return!1;var d=((l-a)*(n-h)-(u-h)*(s-a))/c,f=((r-s)*(n-h)-(o-n)*(s-a))/c;return!(d<0||d>1||f<0||f>1)&&(i&&(i.x=s+d*(r-s),i.y=n+d*(o-n)),!0)}},47910:t=>{t.exports=function(t,e){var i=t.x1,s=t.y1,n=t.x2,r=t.y2,o=e.x,a=e.y,h=e.right,l=e.bottom,u=0;if(i>=o&&i<=h&&s>=a&&s<=l||n>=o&&n<=h&&r>=a&&r<=l)return!0;if(i=o){if((u=s+(r-s)*(o-i)/(n-i))>a&&u<=l)return!0}else if(i>h&&n<=h&&(u=s+(r-s)*(h-i)/(n-i))>=a&&u<=l)return!0;if(s=a){if((u=i+(n-i)*(a-s)/(r-s))>=o&&u<=h)return!0}else if(s>l&&r<=l&&(u=i+(n-i)*(l-s)/(r-s))>=o&&u<=h)return!0;return!1}},34426:t=>{t.exports=function(t,e,i){void 0===i&&(i=1);var s=e.x1,n=e.y1,r=e.x2,o=e.y2,a=t.x,h=t.y,l=(r-s)*(r-s)+(o-n)*(o-n);if(0===l)return!1;var u=((a-s)*(r-s)+(h-n)*(o-n))/l;if(u<0)return Math.sqrt((s-a)*(s-a)+(n-h)*(n-h))<=i;if(u>=0&&u<=1){var c=((n-h)*(r-s)-(s-a)*(o-n))/l;return Math.abs(c)*Math.sqrt(l)<=i}return Math.sqrt((r-a)*(r-a)+(o-h)*(o-h))<=i}},81414:(t,e,i)=>{var s=i(34426);t.exports=function(t,e){if(!s(t,e))return!1;var i=Math.min(e.x1,e.x2),n=Math.max(e.x1,e.x2),r=Math.min(e.y1,e.y2),o=Math.max(e.y1,e.y2);return t.x>=i&&t.x<=n&&t.y>=r&&t.y<=o}},90205:t=>{t.exports=function(t,e){return!(t.width<=0||t.height<=0||e.width<=0||e.height<=0)&&!(t.righte.right||t.y>e.bottom)}},20370:(t,e,i)=>{var s=i(25227),n=i(94287),r=i(86875),o=i(87279);t.exports=function(t,e){if(e.left>t.right||e.rightt.bottom||e.bottom0}},8786:t=>{t.exports=function(t,e,i,s,n,r){return void 0===r&&(r=0),!(e>t.right+r||it.bottom+r||n{var s=i(61472),n=i(60689);t.exports=function(t,e){return!(t.left>e.right||t.righte.bottom||t.bottom{var s=i(25227);t.exports=function(t,e){return!(!t.contains(e.x1,e.y1)&&!t.contains(e.x2,e.y2))||(!!s(t.getLineA(),e)||(!!s(t.getLineB(),e)||!!s(t.getLineC(),e)))}},23589:(t,e,i)=>{var s=i(86875),n=i(18680),r=i(25227);t.exports=function(t,e){if(t.left>e.right||t.righte.bottom||t.bottom0||(c=n(e),(d=s(t,c,!0)).length>0)}},7563:(t,e,i)=>{t.exports={CircleToCircle:i(22184),CircleToRectangle:i(26535),GetCircleToCircle:i(71145),GetCircleToRectangle:i(62508),GetLineToCircle:i(26111),GetLineToLine:i(96537),GetLineToPoints:i(17647),GetLineToPolygon:i(68439),GetLineToRectangle:i(9569),GetRaysFromPointToPolygon:i(7449),GetRectangleIntersection:i(82931),GetRectangleToRectangle:i(1946),GetRectangleToTriangle:i(34211),GetTriangleToCircle:i(80511),GetTriangleToLine:i(31343),GetTriangleToTriangle:i(70534),LineToCircle:i(61472),LineToLine:i(25227),LineToRectangle:i(47910),PointToLine:i(34426),PointToLineSegment:i(81414),RectangleToRectangle:i(90205),RectangleToTriangle:i(20370),RectangleToValues:i(8786),TriangleToCircle:i(48411),TriangleToLine:i(86117),TriangleToTriangle:i(23589)}},50599:t=>{t.exports=function(t){return Math.atan2(t.y2-t.y1,t.x2-t.x1)}},58813:t=>{t.exports=function(t,e,i){void 0===e&&(e=1),void 0===i&&(i=[]);var s=Math.round(t.x1),n=Math.round(t.y1),r=Math.round(t.x2),o=Math.round(t.y2),a=Math.abs(r-s),h=Math.abs(o-n),l=s-h&&(c-=h,s+=l),f{t.exports=function(t,e,i){var s=e-(t.x1+t.x2)/2,n=i-(t.y1+t.y2)/2;return t.x1+=s,t.y1+=n,t.x2+=s,t.y2+=n,t}},26718:(t,e,i)=>{var s=i(88829);t.exports=function(t){return new s(t.x1,t.y1,t.x2,t.y2)}},88930:t=>{t.exports=function(t,e){return e.setTo(t.x1,t.y1,t.x2,t.y2)}},90656:t=>{t.exports=function(t,e){return t.x1===e.x1&&t.y1===e.y1&&t.x2===e.x2&&t.y2===e.y2}},30897:(t,e,i)=>{var s=i(16028);t.exports=function(t,e,i){void 0===i&&(i=e);var n=s(t),r=t.x2-t.x1,o=t.y2-t.y1;return e&&(t.x1=t.x1-r/n*e,t.y1=t.y1-o/n*e),i&&(t.x2=t.x2+r/n*i,t.y2=t.y2+o/n*i),t}},30684:(t,e,i)=>{var s=i(92951),n=i(21902),r=i(79967);t.exports=function(t,e,i,o,a){void 0===o&&(o=0),void 0===a&&(a=[]);var h,l,u=[],c=t.x1,d=t.y1,f=t.x2-c,p=t.y2-d,v=n(e,a),g=i-1;for(h=0;h0){var m=u[0],y=[m];for(h=1;h=o&&(y.push(x),m=x)}var T=u[u.length-1];return s(m,T){var s=i(79967);t.exports=function(t,e){return void 0===e&&(e=new s),e.x=(t.x1+t.x2)/2,e.y=(t.y1+t.y2)/2,e}},11222:(t,e,i)=>{var s=i(79967);t.exports=function(t,e,i){void 0===i&&(i=new s);var n=t.x1,r=t.y1,o=t.x2,a=t.y2,h=(o-n)*(o-n)+(a-r)*(a-r);if(0===h)return i;var l=((e.x-n)*(o-n)+(e.y-r)*(a-r))/h;return i.x=n+l*(o-n),i.y=r+l*(a-r),i}},7377:(t,e,i)=>{var s=i(83392),n=i(50599),r=i(79967);t.exports=function(t,e){void 0===e&&(e=new r);var i=n(t)-s.TAU;return e.x=Math.cos(i),e.y=Math.sin(i),e}},66464:(t,e,i)=>{var s=i(79967);t.exports=function(t,e,i){return void 0===i&&(i=new s),i.x=t.x1+(t.x2-t.x1)*e,i.y=t.y1+(t.y2-t.y1)*e,i}},8570:(t,e,i)=>{var s=i(16028),n=i(79967);t.exports=function(t,e,i,r){void 0===r&&(r=[]),!e&&i>0&&(e=s(t)/i);for(var o=t.x1,a=t.y1,h=t.x2,l=t.y2,u=0;u{t.exports=function(t,e){var i=t.x1,s=t.y1,n=t.x2,r=t.y2,o=(n-i)*(n-i)+(r-s)*(r-s);if(0===o)return!1;var a=((s-e.y)*(n-i)-(i-e.x)*(r-s))/o;return Math.abs(a)*Math.sqrt(o)}},82996:t=>{t.exports=function(t){return Math.abs(t.y1-t.y2)}},16028:t=>{t.exports=function(t){return Math.sqrt((t.x2-t.x1)*(t.x2-t.x1)+(t.y2-t.y1)*(t.y2-t.y1))}},88829:(t,e,i)=>{var s=i(56694),n=i(66464),r=i(8570),o=i(52394),a=i(74077),h=i(93736),l=new s({initialize:function(t,e,i,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=0),this.type=o.LINE,this.x1=t,this.y1=e,this.x2=i,this.y2=s},getPoint:function(t,e){return n(this,t,e)},getPoints:function(t,e,i){return r(this,t,e,i)},getRandomPoint:function(t){return a(this,t)},setTo:function(t,e,i,s){return void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=0),this.x1=t,this.y1=e,this.x2=i,this.y2=s,this},getPointA:function(t){return void 0===t&&(t=new h),t.set(this.x1,this.y1),t},getPointB:function(t){return void 0===t&&(t=new h),t.set(this.x2,this.y2),t},left:{get:function(){return Math.min(this.x1,this.x2)},set:function(t){this.x1<=this.x2?this.x1=t:this.x2=t}},right:{get:function(){return Math.max(this.x1,this.x2)},set:function(t){this.x1>this.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},73273:(t,e,i)=>{var s=i(83392),n=i(1071),r=i(50599);t.exports=function(t){var e=r(t)-s.TAU;return n(e,-Math.PI,Math.PI)}},96936:(t,e,i)=>{var s=i(83392),n=i(50599);t.exports=function(t){return Math.cos(n(t)-s.TAU)}},43581:(t,e,i)=>{var s=i(83392),n=i(50599);t.exports=function(t){return Math.sin(n(t)-s.TAU)}},13990:t=>{t.exports=function(t,e,i){return t.x1+=e,t.y1+=i,t.x2+=e,t.y2+=i,t}},1298:t=>{t.exports=function(t){return-(t.x2-t.x1)/(t.y2-t.y1)}},74077:(t,e,i)=>{var s=i(79967);t.exports=function(t,e){void 0===e&&(e=new s);var i=Math.random();return e.x=t.x1+i*(t.x2-t.x1),e.y=t.y1+i*(t.y2-t.y1),e}},30473:(t,e,i)=>{var s=i(50599),n=i(73273);t.exports=function(t,e){return 2*n(e)-Math.PI-s(t)}},25968:(t,e,i)=>{var s=i(1809);t.exports=function(t,e){var i=(t.x1+t.x2)/2,n=(t.y1+t.y2)/2;return s(t,i,n,e)}},24296:(t,e,i)=>{var s=i(1809);t.exports=function(t,e,i){return s(t,e.x,e.y,i)}},1809:t=>{t.exports=function(t,e,i,s){var n=Math.cos(s),r=Math.sin(s),o=t.x1-e,a=t.y1-i;return t.x1=o*n-a*r+e,t.y1=o*r+a*n+i,o=t.x2-e,a=t.y2-i,t.x2=o*n-a*r+e,t.y2=o*r+a*n+i,t}},88171:t=>{t.exports=function(t,e,i,s,n){return t.x1=e,t.y1=i,t.x2=e+Math.cos(s)*n,t.y2=i+Math.sin(s)*n,t}},82797:t=>{t.exports=function(t){return(t.y2-t.y1)/(t.x2-t.x1)}},41067:t=>{t.exports=function(t){return Math.abs(t.x1-t.x2)}},28482:(t,e,i)=>{var s=i(88829);s.Angle=i(50599),s.BresenhamPoints=i(58813),s.CenterOn=i(88513),s.Clone=i(26718),s.CopyFrom=i(88930),s.Equals=i(90656),s.Extend=i(30897),s.GetEasedPoints=i(30684),s.GetMidPoint=i(20487),s.GetNearestPoint=i(11222),s.GetNormal=i(7377),s.GetPoint=i(66464),s.GetPoints=i(8570),s.GetShortestDistance=i(65269),s.Height=i(82996),s.Length=i(16028),s.NormalAngle=i(73273),s.NormalX=i(96936),s.NormalY=i(43581),s.Offset=i(13990),s.PerpSlope=i(1298),s.Random=i(74077),s.ReflectAngle=i(30473),s.Rotate=i(25968),s.RotateAroundPoint=i(24296),s.RotateAroundXY=i(1809),s.SetToAngle=i(88171),s.Slope=i(82797),s.Width=i(41067),t.exports=s},18693:(t,e,i)=>{var s=i(56694),n=i(74118),r=i(93736);function o(t,e,i,s){var n=t-i,r=e-s,o=n*n+r*r;return Math.sqrt(o)}var a=new s({initialize:function(t,e,i){this.vertex1=t,this.vertex2=e,this.vertex3=i,this.bounds=new n,this._inCenter=new r},getInCenter:function(t){void 0===t&&(t=!0);var e,i,s,n,r,a,h=this.vertex1,l=this.vertex2,u=this.vertex3;t?(e=h.x,i=h.y,s=l.x,n=l.y,r=u.x,a=u.y):(e=h.vx,i=h.vy,s=l.vx,n=l.vy,r=u.vx,a=u.vy);var c=o(r,a,s,n),d=o(e,i,r,a),f=o(s,n,e,i),p=c+d+f;return this._inCenter.set((e*c+s*d+r*f)/p,(i*c+n*d+a*f)/p)},contains:function(t,e,i){var s=this.vertex1,n=this.vertex2,r=this.vertex3,o=s.vx,a=s.vy,h=n.vx,l=n.vy,u=r.vx,c=r.vy;if(i){var d=i.a,f=i.b,p=i.c,v=i.d,g=i.e,m=i.f;o=s.vx*d+s.vy*p+g,a=s.vx*f+s.vy*v+m,h=n.vx*d+n.vy*p+g,l=n.vx*f+n.vy*v+m,u=r.vx*d+r.vy*p+g,c=r.vx*f+r.vy*v+m}var y=u-o,x=c-a,T=h-o,w=l-a,b=t-o,S=e-a,E=y*y+x*x,A=y*T+x*w,C=y*b+x*S,_=T*T+w*w,M=T*b+w*S,P=E*_-A*A,R=0===P?0:1/P,O=(_*C-A*M)*R,L=(E*M-A*C)*R;return O>=0&&L>=0&&O+L<1},isCounterClockwise:function(t){var e=this.vertex1,i=this.vertex2,s=this.vertex3,n=(i.vx-e.vx)*(s.vy-e.vy)-(i.vy-e.vy)*(s.vx-e.vx);return t<=0?n>=0:n<0},load:function(t,e,i,s,n){return i=this.vertex1.load(t,e,i,s,n),i=this.vertex2.load(t,e,i,s,n),i=this.vertex3.load(t,e,i,s,n)},transformCoordinatesLocal:function(t,e,i,s){return this.vertex1.transformCoordinatesLocal(t,e,i,s),this.vertex2.transformCoordinatesLocal(t,e,i,s),this.vertex3.transformCoordinatesLocal(t,e,i,s),this},updateBounds:function(){var t=this.vertex1,e=this.vertex2,i=this.vertex3,s=this.bounds;return s.x=Math.min(t.vx,e.vx,i.vx),s.y=Math.min(t.vy,e.vy,i.vy),s.width=Math.max(t.vx,e.vx,i.vx)-s.x,s.height=Math.max(t.vy,e.vy,i.vy)-s.y,this},isInView:function(t,e,i,s,n,r,o,a,h,l,u){this.update(s,n,r,o,a,h,l,u);var c=this.vertex1,d=this.vertex2,f=this.vertex3;if(c.ta<=0&&d.ta<=0&&f.ta<=0)return!1;if(e&&!this.isCounterClockwise(i))return!1;var p=this.bounds;p.x=Math.min(c.tx,d.tx,f.tx),p.y=Math.min(c.ty,d.ty,f.ty),p.width=Math.max(c.tx,d.tx,f.tx)-p.x,p.height=Math.max(c.ty,d.ty,f.ty)-p.y;var v=t.x+t.width,g=t.y+t.height;return!(p.width<=0||p.height<=0||t.width<=0||t.height<=0)&&!(p.rightv||p.y>g)},scrollUV:function(t,e){return this.vertex1.scrollUV(t,e),this.vertex2.scrollUV(t,e),this.vertex3.scrollUV(t,e),this},scaleUV:function(t,e){return this.vertex1.scaleUV(t,e),this.vertex2.scaleUV(t,e),this.vertex3.scaleUV(t,e),this},setColor:function(t){return this.vertex1.color=t,this.vertex2.color=t,this.vertex3.color=t,this},update:function(t,e,i,s,n,r,o,a){return this.vertex1.update(e,i,s,n,r,o,a,t),this.vertex2.update(e,i,s,n,r,o,a,t),this.vertex3.update(e,i,s,n,r,o,a,t),this},translate:function(t,e){void 0===e&&(e=0);var i=this.vertex1,s=this.vertex2,n=this.vertex3;return i.x+=t,i.y+=e,s.x+=t,s.y+=e,n.x+=t,n.y+=e,this},x:{get:function(){return this.getInCenter().x},set:function(t){var e=this.getInCenter();this.translate(t-e.x,0)}},y:{get:function(){return this.getInCenter().y},set:function(t){var e=this.getInCenter();this.translate(0,t-e.y)}},alpha:{get:function(){var t=this.vertex1,e=this.vertex2,i=this.vertex3;return(t.alpha+e.alpha+i.alpha)/3},set:function(t){this.vertex1.alpha=t,this.vertex2.alpha=t,this.vertex3.alpha=t}},depth:{get:function(){var t=this.vertex1,e=this.vertex2,i=this.vertex3;return(t.vz+e.vz+i.vz)/3}},destroy:function(){this.vertex1=null,this.vertex2=null,this.vertex3=null}});t.exports=a},99425:(t,e,i)=>{var s=i(18693),n=i(72632),r=i(16650),o=i(70015),a=i(85769),h=new o,l=new o,u=new r;t.exports=function(t){var e,i=n(t,"mesh"),r=n(t,"texture",null),o=n(t,"frame"),c=n(t,"width",1),d=n(t,"height",c),f=n(t,"widthSegments",1),p=n(t,"heightSegments",f),v=n(t,"x",0),g=n(t,"y",0),m=n(t,"z",0),y=n(t,"rotateX",0),x=n(t,"rotateY",0),T=n(t,"rotateZ",0),w=n(t,"zIsUp",!0),b=n(t,"isOrtho",!!i&&i.dirtyCache[11]),S=n(t,"colors",[16777215]),E=n(t,"alphas",[1]),A=n(t,"tile",!1),C=n(t,"flipY",!1),_=n(t,"width",null),M={faces:[],verts:[]};if(h.set(v,g,m),l.set(y,x,T),u.fromRotationXYTranslation(l,h,w),!r&&i)r=i.texture,o||(e=i.frame);else if(i&&"string"==typeof r)r=i.scene.sys.textures.get(r);else if(!r)return M;e||(e=r.get(o)),!_&&b&&r&&i&&(c=e.width/i.height,d=e.height/i.height);var P,R,O=c/2,L=d/2,F=Math.floor(f),D=Math.floor(p),I=F+1,k=D+1,B=c/F,N=d/D,X=[],U=[],Y=0,z=1,G=0,V=1;e&&(Y=e.u0,z=e.u1,C?(G=e.v1,V=e.v0):(G=e.v0,V=e.v1));var W=z-Y,H=V-G;for(R=0;R{var s=i(18693),n=i(16650),r=i(70015),o=i(85769),a=new r,h=new r,l=new n;t.exports=function(t,e,i,n,r,u,c,d,f,p){void 0===i&&(i=1),void 0===n&&(n=0),void 0===r&&(r=0),void 0===u&&(u=0),void 0===c&&(c=0),void 0===d&&(d=0),void 0===f&&(f=0),void 0===p&&(p=!0);var v={faces:[],verts:[]},g=t.materials;a.set(n,r,u),h.set(c,d,f),l.fromRotationXYTranslation(h,a,p);for(var m=0;m{var s=i(18693),n=i(85769);t.exports=function(t,e,i,r,o,a,h,l){if(void 0===r&&(r=!1),void 0===a&&(a=16777215),void 0===h&&(h=1),void 0===l&&(l=!1),t.length===e.length||r){var u,c,d,f,p,v,g,m,y,x,T,w={faces:[],vertices:[]},b=r?3:2,S=Array.isArray(a),E=Array.isArray(h);if(Array.isArray(i)&&i.length>0)for(u=0;u{var e=!0,i="untitled",s="",n="";function r(t){var e=t.indexOf("#");return e>-1?t.substring(0,e):t}function o(t){return 0===t.models.length&&t.models.push({faces:[],name:i,textureCoords:[],vertexNormals:[],vertices:[]}),s="",t.models[t.models.length-1]}function a(t,e){var n=t.length>=2?t[1]:i;e.models.push({faces:[],name:n,textureCoords:[],vertexNormals:[],vertices:[]}),s=""}function h(t){2===t.length&&(s=t[1])}function l(t,e){var i=t.length,s=i>=2?parseFloat(t[1]):0,n=i>=3?parseFloat(t[2]):0,r=i>=4?parseFloat(t[3]):0;o(e).vertices.push({x:s,y:n,z:r})}function u(t,i){var s=t.length,n=s>=2?parseFloat(t[1]):0,r=s>=3?parseFloat(t[2]):0,a=s>=4?parseFloat(t[3]):0;isNaN(n)&&(n=0),isNaN(r)&&(r=0),isNaN(a)&&(a=0),e&&(r=1-r),o(i).textureCoords.push({u:n,v:r,w:a})}function c(t,e){var i=t.length,s=i>=2?parseFloat(t[1]):0,n=i>=3?parseFloat(t[2]):0,r=i>=4?parseFloat(t[3]):0;o(e).vertexNormals.push({x:s,y:n,z:r})}function d(t,e){var i=t.length-1;if(!(i<3)){for(var r={group:s,material:n,vertices:[]},a=0;a3)){var u=0,c=0,d=0;u=parseInt(h[0],10),l>1&&""!==h[1]&&(c=parseInt(h[1],10)),l>2&&(d=parseInt(h[2],10)),0!==u&&(u<0&&(u=o(e).vertices.length+1+u),c-=1,u-=1,d-=1,r.vertices.push({textureCoordsIndex:c,vertexIndex:u,vertexNormalIndex:d}))}}o(e).faces.push(r)}}function f(t,e){t.length>=2&&e.materialLibraries.push(t[1])}function p(t){t.length>=2&&(n=t[1])}t.exports=function(t,i){void 0===i&&(i=!0),e=i;var o={materials:{},materialLibraries:[],models:[]};s="",n="";for(var v=t.split("\n"),g=0;g{var s=i(22946);t.exports=function(t){for(var e={},i=t.split("\n"),n="",r=0;r=2?Math.floor(255*a[2]):h,u=a.length>=3?Math.floor(255*a[3]):h;e[n]=s(h,l,u)}}}return e}},15313:t=>{t.exports=function(t,e,i,s){var n,r;if(void 0===i&&void 0===s){var o=t.getInCenter();n=o.x,r=o.y}var a=Math.cos(e),h=Math.sin(e),l=t.vertex1,u=t.vertex2,c=t.vertex3,d=l.x-n,f=l.y-r;l.set(d*a-f*h+n,d*h+f*a+r),d=u.x-n,f=u.y-r,u.set(d*a-f*h+n,d*h+f*a+r),d=c.x-n,f=c.y-r,c.set(d*a-f*h+n,d*h+f*a+r)}},85769:(t,e,i)=>{var s=i(56694),n=i(75512),r=i(70015),o=new s({Extends:r,initialize:function(t,e,i,s,n,o,a,h,l,u){void 0===o&&(o=16777215),void 0===a&&(a=1),void 0===h&&(h=0),void 0===l&&(l=0),void 0===u&&(u=0),r.call(this,t,e,i),this.vx=0,this.vy=0,this.vz=0,this.nx=h,this.ny=l,this.nz=u,this.u=s,this.v=n,this.color=o,this.alpha=a,this.tx=0,this.ty=0,this.ta=0,this.tu=s,this.tv=n},setUVs:function(t,e){return this.u=t,this.v=e,this.tu=t,this.tv=e,this},scrollUV:function(t,e){return this.tu+=t,this.tv+=e,this},scaleUV:function(t,e){return this.tu=this.u*t,this.tv=this.v*e,this},transformCoordinatesLocal:function(t,e,i,s){var n=this.x,r=this.y,o=this.z,a=t.val,h=n*a[0]+r*a[4]+o*a[8]+a[12],l=n*a[1]+r*a[5]+o*a[9]+a[13],u=n*a[2]+r*a[6]+o*a[10]+a[14],c=n*a[3]+r*a[7]+o*a[11]+a[15];this.vx=h/c*e,this.vy=-l/c*i,this.vz=s<=0?u/c:-u/c},resize:function(t,e,i,s,n,r){return this.x=t,this.y=e,this.vx=this.x*i,this.vy=-this.y*s,this.vz=0,n<.5?this.vx+=i*(.5-n):n>.5&&(this.vx-=i*(n-.5)),r<.5?this.vy+=s*(.5-r):r>.5&&(this.vy-=s*(r-.5)),this},update:function(t,e,i,s,n,r,o,a){var h=this.vx*t+this.vy*i+n,l=this.vx*e+this.vy*s+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,s,r){return t[++i]=this.tx,t[++i]=this.ty,t[++i]=this.tu,t[++i]=this.tv,t[++i]=s,t[++i]=r,e[++i]=n.getTintAppendFloatAlpha(this.color,this.ta),i}});t.exports=o},14293:(t,e,i)=>{var s={Face:i(18693),GenerateGridVerts:i(99425),GenerateObjVerts:i(53267),GenerateVerts:i(67623),ParseObj:i(27291),ParseObjMaterial:i(76799),RotateFace:i(15313),Vertex:i(85769)};t.exports=s},77601:t=>{t.exports=function(t){return t.setTo(Math.ceil(t.x),Math.ceil(t.y))}},38933:(t,e,i)=>{var s=i(79967);t.exports=function(t){return new s(t.x,t.y)}},47103:t=>{t.exports=function(t,e){return e.setTo(t.x,t.y)}},13625:t=>{t.exports=function(t,e){return t.x===e.x&&t.y===e.y}},12536:t=>{t.exports=function(t){return t.setTo(Math.floor(t.x),Math.floor(t.y))}},54205:(t,e,i)=>{var s=i(79967);t.exports=function(t,e){if(void 0===e&&(e=new s),!Array.isArray(t))throw new Error("GetCentroid points argument must be an array");var i=t.length;if(i<1)throw new Error("GetCentroid points array must not be empty");if(1===i)e.x=t[0].x,e.y=t[0].y;else{for(var n=0;n{t.exports=function(t){return Math.sqrt(t.x*t.x+t.y*t.y)}},82712:t=>{t.exports=function(t){return t.x*t.x+t.y*t.y}},20052:(t,e,i)=>{var s=i(74118);t.exports=function(t,e){void 0===e&&(e=new s);for(var i=Number.NEGATIVE_INFINITY,n=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,a=0;ai&&(i=h.x),h.xr&&(r=h.y),h.y{var s=i(79967);t.exports=function(t,e,i,n){return void 0===i&&(i=0),void 0===n&&(n=new s),n.x=t.x+(e.x-t.x)*i,n.y=t.y+(e.y-t.y)*i,n}},42397:t=>{t.exports=function(t){return t.setTo(t.y,t.x)}},59464:(t,e,i)=>{var s=i(79967);t.exports=function(t,e){return void 0===e&&(e=new s),e.setTo(-t.x,-t.y)}},79967:(t,e,i)=>{var s=i(56694),n=i(52394),r=new s({initialize:function(t,e){void 0===t&&(t=0),void 0===e&&(e=t),this.type=n.POINT,this.x=t,this.y=e},setTo:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this.x=t,this.y=e,this}});t.exports=r},53581:(t,e,i)=>{var s=i(79967),n=i(82712);t.exports=function(t,e,i){void 0===i&&(i=new s);var r=(t.x*e.x+t.y*e.y)/n(e);return 0!==r&&(i.x=r*e.x,i.y=r*e.y),i}},50817:(t,e,i)=>{var s=i(79967);t.exports=function(t,e,i){void 0===i&&(i=new s);var n=t.x*e.x+t.y*e.y;return 0!==n&&(i.x=n*e.x,i.y=n*e.y),i}},40525:(t,e,i)=>{var s=i(50083);t.exports=function(t,e){if(0!==t.x||0!==t.y){var i=s(t);t.x/=i,t.y/=i}return t.x*=e,t.y*=e,t}},63472:(t,e,i)=>{var s=i(79967);s.Ceil=i(77601),s.Clone=i(38933),s.CopyFrom=i(47103),s.Equals=i(13625),s.Floor=i(12536),s.GetCentroid=i(54205),s.GetMagnitude=i(50083),s.GetMagnitudeSq=i(82712),s.GetRectangleFromPoints=i(20052),s.Interpolate=i(77154),s.Invert=i(42397),s.Negative=i(59464),s.Project=i(53581),s.ProjectUnit=i(50817),s.SetMagnitude=i(40525),t.exports=s},19631:(t,e,i)=>{var s=i(8580);t.exports=function(t){return new s(t.points)}},45604:t=>{t.exports=function(t,e,i){for(var s=!1,n=-1,r=t.points.length-1;++n{var s=i(45604);t.exports=function(t,e){return s(t,e.x,e.y)}},11117:t=>{"use strict";function e(t,e,s){s=s||2;var r,o,a,h,c,d,p,v=e&&e.length,g=v?e[0]*s:t.length,m=i(t,0,g,s,!0),y=[];if(!m||m.next===m.prev)return y;if(v&&(m=function(t,e,s,n){var r,o,a,h=[];for(r=0,o=e.length;r80*s){r=a=t[0],o=h=t[1];for(var x=s;xa&&(a=c),d>h&&(h=d);p=0!==(p=Math.max(a-r,h-o))?32767/p:0}return n(m,y,s,r,o,p,0),y}function i(t,e,i,s,n){var r,o;if(n===C(t,e,i,s)>0)for(r=e;r=e;r-=s)o=S(r,t[r],t[r+1],o);return o&&m(o,o.next)&&(E(o),o=o.next),o}function s(t,e){if(!t)return t;e||(e=t);var i,s=t;do{if(i=!1,s.steiner||!m(s,s.next)&&0!==g(s.prev,s,s.next))s=s.next;else{if(E(s),(s=e=s.prev)===s.next)break;i=!0}}while(i||s!==e);return e}function n(t,e,i,l,u,c,f){if(t){!f&&c&&function(t,e,i,s){var n=t;do{0===n.z&&(n.z=d(n.x,n.y,e,i,s)),n.prevZ=n.prev,n.nextZ=n.next,n=n.next}while(n!==t);n.prevZ.nextZ=null,n.prevZ=null,function(t){var e,i,s,n,r,o,a,h,l=1;do{for(i=t,t=null,r=null,o=0;i;){for(o++,s=i,a=0,e=0;e0||h>0&&s;)0!==a&&(0===h||!s||i.z<=s.z)?(n=i,i=i.nextZ,a--):(n=s,s=s.nextZ,h--),r?r.nextZ=n:t=n,n.prevZ=r,r=n;i=s}r.nextZ=null,l*=2}while(o>1)}(n)}(t,l,u,c);for(var p,v,g=t;t.prev!==t.next;)if(p=t.prev,v=t.next,c?o(t,l,u,c):r(t))e.push(p.i/i|0),e.push(t.i/i|0),e.push(v.i/i|0),E(t),t=v.next,g=v.next;else if((t=v)===g){f?1===f?n(t=a(s(t),e,i),e,i,l,u,c,2):2===f&&h(t,e,i,l,u,c):n(s(t),e,i,l,u,c,1);break}}}function r(t){var e=t.prev,i=t,s=t.next;if(g(e,i,s)>=0)return!1;for(var n=e.x,r=i.x,o=s.x,a=e.y,h=i.y,l=s.y,u=nr?n>o?n:o:r>o?r:o,f=a>h?a>l?a:l:h>l?h:l,v=s.next;v!==e;){if(v.x>=u&&v.x<=d&&v.y>=c&&v.y<=f&&p(n,a,r,h,o,l,v.x,v.y)&&g(v.prev,v,v.next)>=0)return!1;v=v.next}return!0}function o(t,e,i,s){var n=t.prev,r=t,o=t.next;if(g(n,r,o)>=0)return!1;for(var a=n.x,h=r.x,l=o.x,u=n.y,c=r.y,f=o.y,v=ah?a>l?a:l:h>l?h:l,x=u>c?u>f?u:f:c>f?c:f,T=d(v,m,e,i,s),w=d(y,x,e,i,s),b=t.prevZ,S=t.nextZ;b&&b.z>=T&&S&&S.z<=w;){if(b.x>=v&&b.x<=y&&b.y>=m&&b.y<=x&&b!==n&&b!==o&&p(a,u,h,c,l,f,b.x,b.y)&&g(b.prev,b,b.next)>=0)return!1;if(b=b.prevZ,S.x>=v&&S.x<=y&&S.y>=m&&S.y<=x&&S!==n&&S!==o&&p(a,u,h,c,l,f,S.x,S.y)&&g(S.prev,S,S.next)>=0)return!1;S=S.nextZ}for(;b&&b.z>=T;){if(b.x>=v&&b.x<=y&&b.y>=m&&b.y<=x&&b!==n&&b!==o&&p(a,u,h,c,l,f,b.x,b.y)&&g(b.prev,b,b.next)>=0)return!1;b=b.prevZ}for(;S&&S.z<=w;){if(S.x>=v&&S.x<=y&&S.y>=m&&S.y<=x&&S!==n&&S!==o&&p(a,u,h,c,l,f,S.x,S.y)&&g(S.prev,S,S.next)>=0)return!1;S=S.nextZ}return!0}function a(t,e,i){var n=t;do{var r=n.prev,o=n.next.next;!m(r,o)&&y(r,n,n.next,o)&&w(r,o)&&w(o,r)&&(e.push(r.i/i|0),e.push(n.i/i|0),e.push(o.i/i|0),E(n),E(n.next),n=t=o),n=n.next}while(n!==t);return s(n)}function h(t,e,i,r,o,a){var h=t;do{for(var l=h.next.next;l!==h.prev;){if(h.i!==l.i&&v(h,l)){var u=b(h,l);return h=s(h,h.next),u=s(u,u.next),n(h,e,i,r,o,a,0),void n(u,e,i,r,o,a,0)}l=l.next}h=h.next}while(h!==t)}function l(t,e){return t.x-e.x}function u(t,e){var i=function(t,e){var i,s=e,n=t.x,r=t.y,o=-1/0;do{if(r<=s.y&&r>=s.next.y&&s.next.y!==s.y){var a=s.x+(r-s.y)*(s.next.x-s.x)/(s.next.y-s.y);if(a<=n&&a>o&&(o=a,i=s.x=s.x&&s.x>=u&&n!==s.x&&p(ri.x||s.x===i.x&&c(i,s)))&&(i=s,f=h)),s=s.next}while(s!==l);return i}(t,e);if(!i)return e;var n=b(i,t);return s(n,n.next),s(i,i.next)}function c(t,e){return g(t.prev,t,e.prev)<0&&g(e.next,t,t.next)<0}function d(t,e,i,s,n){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=(t-i)*n|0)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=(e-s)*n|0)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function f(t){var e=t,i=t;do{(e.x=(t-o)*(r-a)&&(t-o)*(s-a)>=(i-o)*(e-a)&&(i-o)*(r-a)>=(n-o)*(s-a)}function v(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&&y(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(w(t,e)&&w(e,t)&&function(t,e){var i=t,s=!1,n=(t.x+e.x)/2,r=(t.y+e.y)/2;do{i.y>r!=i.next.y>r&&i.next.y!==i.y&&n<(i.next.x-i.x)*(r-i.y)/(i.next.y-i.y)+i.x&&(s=!s),i=i.next}while(i!==t);return s}(t,e)&&(g(t.prev,t,e.prev)||g(t,e.prev,e))||m(t,e)&&g(t.prev,t,t.next)>0&&g(e.prev,e,e.next)>0)}function g(t,e,i){return(e.y-t.y)*(i.x-e.x)-(e.x-t.x)*(i.y-e.y)}function m(t,e){return t.x===e.x&&t.y===e.y}function y(t,e,i,s){var n=T(g(t,e,i)),r=T(g(t,e,s)),o=T(g(i,s,t)),a=T(g(i,s,e));return n!==r&&o!==a||(!(0!==n||!x(t,i,e))||(!(0!==r||!x(t,s,e))||(!(0!==o||!x(i,t,s))||!(0!==a||!x(i,e,s)))))}function x(t,e,i){return e.x<=Math.max(t.x,i.x)&&e.x>=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function T(t){return t>0?1:t<0?-1:0}function w(t,e){return g(t.prev,t,t.next)<0?g(t,e,t.next)>=0&&g(t,t.prev,e)>=0:g(t,e,t.prev)<0||g(t,t.next,e)<0}function b(t,e){var i=new A(t.i,t.x,t.y),s=new A(e.i,e.x,e.y),n=t.next,r=e.prev;return t.next=e,e.prev=t,i.next=n,n.prev=i,s.next=i,i.prev=s,r.next=s,s.prev=r,s}function S(t,e,i,s){var n=new A(t,e,i);return s?(n.next=s.next,n.prev=s,s.next.prev=n,s.next=n):(n.prev=n,n.next=n),n}function E(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function A(t,e,i){this.i=t,this.x=e,this.y=i,this.prev=null,this.next=null,this.z=0,this.prevZ=null,this.nextZ=null,this.steiner=!1}function C(t,e,i,s){for(var n=0,r=e,o=i-s;r0&&(s+=t[n-1].length,i.holes.push(s))}return i},t.exports=e},14045:(t,e,i)=>{var s=i(74118);t.exports=function(t,e){void 0===e&&(e=new s);for(var i,n=1/0,r=1/0,o=-n,a=-r,h=0;h{t.exports=function(t,e){void 0===e&&(e=[]);for(var i=0;i{var s=i(16028),n=i(88829),r=i(5159);t.exports=function(t,e,i,o){void 0===o&&(o=[]);var a=t.points,h=r(t);!e&&i>0&&(e=h/i);for(var l=0;lc+g)){var m=v.getPoint((u-c)/g);o.push(m);break}c+=g}return o}},5159:(t,e,i)=>{var s=i(16028),n=i(88829);t.exports=function(t){for(var e=t.points,i=0,r=0;r{var s=i(56694),n=i(45604),r=i(89294),o=i(52394),a=new s({initialize:function(t){this.type=o.POLYGON,this.area=0,this.points=[],t&&this.setTo(t)},contains:function(t,e){return n(this,t,e)},setTo:function(t){if(this.area=0,this.points=[],"string"==typeof t&&(t=t.split(" ")),!Array.isArray(t))return this;for(var e,i=Number.MAX_VALUE,s=0;s{t.exports=function(t){return t.points.reverse(),t}},95874:t=>{function e(t,e,i){var s=e.x,n=e.y,r=i.x-s,o=i.y-n;if(0!==r||0!==o){var a=((t.x-s)*r+(t.y-n)*o)/(r*r+o*o);a>1?(s=i.x,n=i.y):a>0&&(s+=r*a,n+=o*a)}return(r=t.x-s)*r+(o=t.y-n)*o}function i(t,s,n,r,o){for(var a,h=r,l=s+1;lh&&(a=l,h=u)}h>r&&(a-s>1&&i(t,s,a,r,o),o.push(t[a]),n-a>1&&i(t,a,n,r,o))}function s(t,e){var s=t.length-1,n=[t[0]];return i(t,0,s,e,n),n.push(t[s]),n}t.exports=function(t,e,i){void 0===e&&(e=1),void 0===i&&(i=!1);var n=t.points;if(n.length>2){var r=e*e;i||(n=function(t,e){for(var i,s,n,r,o,a=t[0],h=[a],l=1,u=t.length;le&&(h.push(i),a=i);return a!==i&&h.push(i),h}(n,r)),t.setTo(s(n,r))}return t}},18974:t=>{var e=function(t,e){return t[0]=e[0],t[1]=e[1],t};t.exports=function(t){var i,s=[],n=t.points;for(i=0;i0&&r.push(e([0,0],s[0])),i=0;i1&&r.push(e([0,0],s[s.length-1])),t.setTo(r)}},23490:t=>{t.exports=function(t,e,i){for(var s=t.points,n=0;n{var s=i(8580);s.Clone=i(19631),s.Contains=i(45604),s.ContainsPoint=i(87289),s.Earcut=i(11117),s.GetAABB=i(14045),s.GetNumberArray=i(98286),s.GetPoints=i(89294),s.Perimeter=i(5159),s.Reverse=i(32244),s.Simplify=i(95874),s.Smooth=i(18974),s.Translate=i(23490),t.exports=s},1653:t=>{t.exports=function(t){return t.width*t.height}},33943:t=>{t.exports=function(t){return t.x=Math.ceil(t.x),t.y=Math.ceil(t.y),t}},58662:t=>{t.exports=function(t){return t.x=Math.ceil(t.x),t.y=Math.ceil(t.y),t.width=Math.ceil(t.width),t.height=Math.ceil(t.height),t}},79993:t=>{t.exports=function(t,e,i){return t.x=e-t.width/2,t.y=i-t.height/2,t}},81572:(t,e,i)=>{var s=i(74118);t.exports=function(t){return new s(t.x,t.y,t.width,t.height)}},94287:t=>{t.exports=function(t,e,i){return!(t.width<=0||t.height<=0)&&(t.x<=e&&t.x+t.width>=e&&t.y<=i&&t.y+t.height>=i)}},28687:(t,e,i)=>{var s=i(94287);t.exports=function(t,e){return s(t,e.x,e.y)}},73222:t=>{t.exports=function(t,e){return!(e.width*e.height>t.width*t.height)&&(e.x>t.x&&e.xt.x&&e.rightt.y&&e.yt.y&&e.bottom{t.exports=function(t,e){return e.setTo(t.x,t.y,t.width,t.height)}},87279:t=>{t.exports=function(t,e){return void 0===e&&(e=[]),e.push({x:t.x,y:t.y}),e.push({x:t.right,y:t.y}),e.push({x:t.right,y:t.bottom}),e.push({x:t.x,y:t.bottom}),e}},19989:t=>{t.exports=function(t,e){return t.x===e.x&&t.y===e.y&&t.width===e.width&&t.height===e.height}},92628:(t,e,i)=>{var s=i(6700);t.exports=function(t,e){var i=s(t);return i{var s=i(6700);t.exports=function(t,e){var i=s(t);return i>s(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)}},71356:t=>{t.exports=function(t){return t.x=Math.floor(t.x),t.y=Math.floor(t.y),t}},21687:t=>{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}},80222:(t,e,i)=>{var s=i(74118),n=i(83392);t.exports=function(t,e){if(void 0===e&&(e=new s),0===t.length)return e;for(var i,r,o,a=Number.MAX_VALUE,h=Number.MAX_VALUE,l=n.MIN_SAFE_INTEGER,u=n.MIN_SAFE_INTEGER,c=0;c{var s=i(74118);t.exports=function(t,e,i,n,r){return void 0===r&&(r=new s),r.setTo(Math.min(t,i),Math.min(e,n),Math.abs(t-i),Math.abs(e-n))}},6700:t=>{t.exports=function(t){return 0===t.height?NaN:t.width/t.height}},35242:(t,e,i)=>{var s=i(79967);t.exports=function(t,e){return void 0===e&&(e=new s),e.x=t.centerX,e.y=t.centerY,e}},47698:(t,e,i)=>{var s=i(85876),n=i(79967);t.exports=function(t,e,i){if(void 0===i&&(i=new n),e<=0||e>=1)return i.x=t.x,i.y=t.y,i;var r=s(t)*e;return e>.5?(r-=t.width+t.height)<=t.width?(i.x=t.right-r,i.y=t.bottom):(i.x=t.x,i.y=t.bottom-(r-t.width)):r<=t.width?(i.x=t.x+r,i.y=t.y):(i.x=t.right,i.y=t.y+(r-t.width)),i}},54932:(t,e,i)=>{var s=i(47698),n=i(85876);t.exports=function(t,e,i,r){void 0===r&&(r=[]),!e&&i>0&&(e=n(t)/i);for(var o=0;o{var s=i(79967);t.exports=function(t,e){return void 0===e&&(e=new s),e.x=t.width,e.y=t.height,e}},7782:(t,e,i)=>{var s=i(79993);t.exports=function(t,e,i){var n=t.centerX,r=t.centerY;return t.setSize(t.width+2*e,t.height+2*i),s(t,n,r)}},66217:(t,e,i)=>{var s=i(74118),n=i(90205);t.exports=function(t,e,i){return void 0===i&&(i=new s),n(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}},40053:(t,e,i)=>{var s=i(85876),n=i(79967);t.exports=function(t,e,i,r){if(void 0===r&&(r=[]),!e&&!i)return r;e?i=Math.round(s(t)/e):e=s(t)/i;for(var o=t.x,a=t.y,h=0,l=0;l=t.right&&(h=1,a+=o-t.right,o=t.right);break;case 1:(a+=e)>=t.bottom&&(h=2,o-=a-t.bottom,a=t.bottom);break;case 2:(o-=e)<=t.left&&(h=3,a-=t.left-o,o=t.left);break;case 3:(a-=e)<=t.top&&(h=0,a=t.top)}return r}},86673:t=>{t.exports=function(t,e){for(var i=t.x,s=t.right,n=t.y,r=t.bottom,o=0;o{t.exports=function(t,e){var i=Math.min(t.x,e.x),s=Math.max(t.right,e.right);t.x=i,t.width=s-i;var n=Math.min(t.y,e.y),r=Math.max(t.bottom,e.bottom);return t.y=n,t.height=r-n,t}},44755:t=>{t.exports=function(t,e,i){var s=Math.min(t.x,e),n=Math.max(t.right,e);t.x=s,t.width=n-s;var r=Math.min(t.y,i),o=Math.max(t.bottom,i);return t.y=r,t.height=o-r,t}},74466:t=>{t.exports=function(t,e,i){return t.x+=e,t.y+=i,t}},55946:t=>{t.exports=function(t,e){return t.x+=e.x,t.y+=e.y,t}},97474:t=>{t.exports=function(t,e){return t.xe.x&&t.ye.y}},85876:t=>{t.exports=function(t){return 2*(t.width+t.height)}},20243:(t,e,i)=>{var s=i(79967),n=i(75606);t.exports=function(t,e,i){void 0===i&&(i=new s),e=n(e);var r=Math.sin(e),o=Math.cos(e),a=o>0?t.width/2:t.width/-2,h=r>0?t.height/2:t.height/-2;return Math.abs(a*r){var s=i(79967);t.exports=function(t,e){return void 0===e&&(e=new s),e.x=t.x+Math.random()*t.width,e.y=t.y+Math.random()*t.height,e}},97691:(t,e,i)=>{var s=i(17489),n=i(73222),r=i(79967);t.exports=function(t,e,i){if(void 0===i&&(i=new r),n(t,e))switch(s(0,3)){case 0:i.x=t.x+Math.random()*(e.right-t.x),i.y=t.y+Math.random()*(e.top-t.y);break;case 1:i.x=e.x+Math.random()*(t.right-e.x),i.y=e.bottom+Math.random()*(t.bottom-e.bottom);break;case 2:i.x=t.x+Math.random()*(e.x-t.x),i.y=e.y+Math.random()*(t.bottom-e.y);break;case 3:i.x=e.right+Math.random()*(t.right-e.right),i.y=t.y+Math.random()*(e.bottom-t.y)}return i}},74118:(t,e,i)=>{var s=i(56694),n=i(94287),r=i(47698),o=i(54932),a=i(52394),h=i(88829),l=i(30001),u=new s({initialize:function(t,e,i,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=0),this.type=a.RECTANGLE,this.x=t,this.y=e,this.width=i,this.height=s},contains:function(t,e){return n(this,t,e)},getPoint:function(t,e){return r(this,t,e)},getPoints:function(t,e,i){return o(this,t,e,i)},getRandomPoint:function(t){return l(this,t)},setTo:function(t,e,i,s){return this.x=t,this.y=e,this.width=i,this.height=s,this},setEmpty:function(){return this.setTo(0,0,0,0)},setPosition:function(t,e){return void 0===e&&(e=t),this.x=t,this.y=e,this},setSize:function(t,e){return void 0===e&&(e=t),this.width=t,this.height=e,this},isEmpty:function(){return this.width<=0||this.height<=0},getLineA:function(t){return void 0===t&&(t=new h),t.setTo(this.x,this.y,this.right,this.y),t},getLineB:function(t){return void 0===t&&(t=new h),t.setTo(this.right,this.y,this.right,this.bottom),t},getLineC:function(t){return void 0===t&&(t=new h),t.setTo(this.right,this.bottom,this.x,this.bottom),t},getLineD:function(t){return void 0===t&&(t=new h),t.setTo(this.x,this.bottom,this.x,this.y),t},left:{get:function(){return this.x},set:function(t){t>=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},51828:t=>{t.exports=function(t,e){return t.width===e.width&&t.height===e.height}},5691:t=>{t.exports=function(t,e,i){return void 0===i&&(i=e),t.width*=e,t.height*=i,t}},58795:(t,e,i)=>{var s=i(74118);t.exports=function(t,e,i){void 0===i&&(i=new s);var n=Math.min(t.x,e.x),r=Math.min(t.y,e.y),o=Math.max(t.right,e.right)-n,a=Math.max(t.bottom,e.bottom)-r;return i.setTo(n,r,o,a)}},66658:(t,e,i)=>{var s=i(74118);s.Area=i(1653),s.Ceil=i(33943),s.CeilAll=i(58662),s.CenterOn=i(79993),s.Clone=i(81572),s.Contains=i(94287),s.ContainsPoint=i(28687),s.ContainsRect=i(73222),s.CopyFrom=i(29538),s.Decompose=i(87279),s.Equals=i(19989),s.FitInside=i(92628),s.FitOutside=i(85028),s.Floor=i(71356),s.FloorAll=i(21687),s.FromPoints=i(80222),s.FromXY=i(75785),s.GetAspectRatio=i(6700),s.GetCenter=i(35242),s.GetPoint=i(47698),s.GetPoints=i(54932),s.GetSize=i(31591),s.Inflate=i(7782),s.Intersection=i(66217),s.MarchingAnts=i(40053),s.MergePoints=i(86673),s.MergeRect=i(14655),s.MergeXY=i(44755),s.Offset=i(74466),s.OffsetPoint=i(55946),s.Overlaps=i(97474),s.Perimeter=i(85876),s.PerimeterPoint=i(20243),s.Random=i(30001),s.RandomOutside=i(97691),s.SameDimensions=i(51828),s.Scale=i(5691),s.Union=i(58795),t.exports=s},19108:t=>{t.exports=function(t){var e=t.x1,i=t.y1,s=t.x2,n=t.y2,r=t.x3,o=t.y3;return Math.abs(((r-e)*(n-i)-(s-e)*(o-i))/2)}},41199:(t,e,i)=>{var s=i(66349);t.exports=function(t,e,i){var n=i*(Math.sqrt(3)/2);return new s(t,e,t+i/2,e+n,t-i/2,e+n)}},88730:(t,e,i)=>{var s=i(11117),n=i(66349);t.exports=function(t,e,i,r,o){void 0===e&&(e=null),void 0===i&&(i=1),void 0===r&&(r=1),void 0===o&&(o=[]);for(var a,h,l,u,c,d,f,p,v,g=s(t,e),m=0;m{var s=i(66349);t.exports=function(t,e,i,n){return void 0===n&&(n=i),new s(t,e,t,e-n,t+i,e)}},1882:(t,e,i)=>{var s=i(56595),n=i(9640);t.exports=function(t,e,i,r){void 0===r&&(r=s);var o=r(t),a=e-o.x,h=i-o.y;return n(t,a,h)}},56595:(t,e,i)=>{var s=i(79967);t.exports=function(t,e){return void 0===e&&(e=new s),e.x=(t.x1+t.x2+t.x3)/3,e.y=(t.y1+t.y2+t.y3)/3,e}},91835:(t,e,i)=>{var s=i(93736);function n(t,e,i,s){return t*s-e*i}t.exports=function(t,e){void 0===e&&(e=new s);var i=t.x3,r=t.y3,o=t.x1-i,a=t.y1-r,h=t.x2-i,l=t.y2-r,u=2*n(o,a,h,l),c=n(a,o*o+a*a,l,h*h+l*l),d=n(o,o*o+a*a,h,h*h+l*l);return e.x=i-c/u,e.y=r+d/u,e}},97073:(t,e,i)=>{var s=i(26673);t.exports=function(t,e){void 0===e&&(e=new s);var i,n,r=t.x1,o=t.y1,a=t.x2,h=t.y2,l=t.x3,u=t.y3,c=a-r,d=h-o,f=l-r,p=u-o,v=c*(r+a)+d*(o+h),g=f*(r+l)+p*(o+u),m=2*(c*(u-h)-d*(l-a));if(Math.abs(m)<1e-6){var y=Math.min(r,a,l),x=Math.min(o,h,u);i=.5*(Math.max(r,a,l)-y),n=.5*(Math.max(o,h,u)-x),e.x=y+i,e.y=x+n,e.radius=Math.sqrt(i*i+n*n)}else e.x=(p*v-d*g)/m,e.y=(c*g-f*v)/m,i=e.x-r,n=e.y-o,e.radius=Math.sqrt(i*i+n*n);return e}},75974:(t,e,i)=>{var s=i(66349);t.exports=function(t){return new s(t.x1,t.y1,t.x2,t.y2,t.x3,t.y3)}},60689:t=>{t.exports=function(t,e,i){var s=t.x3-t.x1,n=t.y3-t.y1,r=t.x2-t.x1,o=t.y2-t.y1,a=e-t.x1,h=i-t.y1,l=s*s+n*n,u=s*r+n*o,c=s*a+n*h,d=r*r+o*o,f=r*a+o*h,p=l*d-u*u,v=0===p?0:1/p,g=(d*c-u*f)*v,m=(l*f-u*c)*v;return g>=0&&m>=0&&g+m<1}},86875:t=>{t.exports=function(t,e,i,s){void 0===i&&(i=!1),void 0===s&&(s=[]);for(var n,r,o,a,h,l,u=t.x3-t.x1,c=t.y3-t.y1,d=t.x2-t.x1,f=t.y2-t.y1,p=u*u+c*c,v=u*d+c*f,g=d*d+f*f,m=p*g-v*v,y=0===m?0:1/m,x=t.x1,T=t.y1,w=0;w=0&&r>=0&&n+r<1&&(s.push({x:e[w].x,y:e[w].y}),i)));w++);return s}},51532:(t,e,i)=>{var s=i(60689);t.exports=function(t,e){return s(t,e.x,e.y)}},42538:t=>{t.exports=function(t,e){return e.setTo(t.x1,t.y1,t.x2,t.y2,t.x3,t.y3)}},18680:t=>{t.exports=function(t,e){return void 0===e&&(e=[]),e.push({x:t.x1,y:t.y1}),e.push({x:t.x2,y:t.y2}),e.push({x:t.x3,y:t.y3}),e}},29977:t=>{t.exports=function(t,e){return t.x1===e.x1&&t.y1===e.y1&&t.x2===e.x2&&t.y2===e.y2&&t.x3===e.x3&&t.y3===e.y3}},56088:(t,e,i)=>{var s=i(79967),n=i(16028);t.exports=function(t,e,i){void 0===i&&(i=new s);var r=t.getLineA(),o=t.getLineB(),a=t.getLineC();if(e<=0||e>=1)return i.x=r.x1,i.y=r.y1,i;var h=n(r),l=n(o),u=n(a),c=(h+l+u)*e,d=0;return ch+l?(d=(c-=h+l)/u,i.x=a.x1+(a.x2-a.x1)*d,i.y=a.y1+(a.y2-a.y1)*d):(d=(c-=h)/l,i.x=o.x1+(o.x2-o.x1)*d,i.y=o.y1+(o.y2-o.y1)*d),i}},24402:(t,e,i)=>{var s=i(16028),n=i(79967);t.exports=function(t,e,i,r){void 0===r&&(r=[]);var o=t.getLineA(),a=t.getLineB(),h=t.getLineC(),l=s(o),u=s(a),c=s(h),d=l+u+c;!e&&i>0&&(e=d/i);for(var f=0;fl+u?(v=(p-=l+u)/c,g.x=h.x1+(h.x2-h.x1)*v,g.y=h.y1+(h.y2-h.y1)*v):(v=(p-=l)/u,g.x=a.x1+(a.x2-a.x1)*v,g.y=a.y1+(a.y2-a.y1)*v),r.push(g)}return r}},83648:(t,e,i)=>{var s=i(79967);function n(t,e,i,s){var n=t-i,r=e-s,o=n*n+r*r;return Math.sqrt(o)}t.exports=function(t,e){void 0===e&&(e=new s);var i=t.x1,r=t.y1,o=t.x2,a=t.y2,h=t.x3,l=t.y3,u=n(h,l,o,a),c=n(i,r,h,l),d=n(o,a,i,r),f=u+c+d;return e.x=(i*u+o*c+h*d)/f,e.y=(r*u+a*c+l*d)/f,e}},9640:t=>{t.exports=function(t,e,i){return t.x1+=e,t.y1+=i,t.x2+=e,t.y2+=i,t.x3+=e,t.y3+=i,t}},95290:(t,e,i)=>{var s=i(16028);t.exports=function(t){var e=t.getLineA(),i=t.getLineB(),n=t.getLineC();return s(e)+s(i)+s(n)}},99761:(t,e,i)=>{var s=i(79967);t.exports=function(t,e){void 0===e&&(e=new s);var i=t.x2-t.x1,n=t.y2-t.y1,r=t.x3-t.x1,o=t.y3-t.y1,a=Math.random(),h=Math.random();return a+h>=1&&(a=1-a,h=1-h),e.x=t.x1+(i*a+r*h),e.y=t.y1+(n*a+o*h),e}},21934:(t,e,i)=>{var s=i(19211),n=i(83648);t.exports=function(t,e){var i=n(t);return s(t,i.x,i.y,e)}},68454:(t,e,i)=>{var s=i(19211);t.exports=function(t,e,i){return s(t,e.x,e.y,i)}},19211:t=>{t.exports=function(t,e,i,s){var n=Math.cos(s),r=Math.sin(s),o=t.x1-e,a=t.y1-i;return t.x1=o*n-a*r+e,t.y1=o*r+a*n+i,o=t.x2-e,a=t.y2-i,t.x2=o*n-a*r+e,t.y2=o*r+a*n+i,o=t.x3-e,a=t.y3-i,t.x3=o*n-a*r+e,t.y3=o*r+a*n+i,t}},66349:(t,e,i)=>{var s=i(56694),n=i(60689),r=i(56088),o=i(24402),a=i(52394),h=i(88829),l=i(99761),u=new s({initialize:function(t,e,i,s,n,r){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=0),void 0===r&&(r=0),this.type=a.TRIANGLE,this.x1=t,this.y1=e,this.x2=i,this.y2=s,this.x3=n,this.y3=r},contains:function(t,e){return n(this,t,e)},getPoint:function(t,e){return r(this,t,e)},getPoints:function(t,e,i){return o(this,t,e,i)},getRandomPoint:function(t){return l(this,t)},setTo:function(t,e,i,s,n,r){return void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=0),void 0===r&&(r=0),this.x1=t,this.y1=e,this.x2=i,this.y2=s,this.x3=n,this.y3=r,this},getLineA:function(t){return void 0===t&&(t=new h),t.setTo(this.x1,this.y1,this.x2,this.y2),t},getLineB:function(t){return void 0===t&&(t=new h),t.setTo(this.x2,this.y2,this.x3,this.y3),t},getLineC:function(t){return void 0===t&&(t=new h),t.setTo(this.x3,this.y3,this.x1,this.y1),t},left:{get:function(){return Math.min(this.x1,this.x2,this.x3)},set:function(t){var e=0;e=this.x1<=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}},right:{get:function(){return Math.max(this.x1,this.x2,this.x3)},set:function(t){var e=0;e=this.x1>=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},87619:(t,e,i)=>{var s=i(66349);s.Area=i(19108),s.BuildEquilateral=i(41199),s.BuildFromPolygon=i(88730),s.BuildRight=i(3635),s.CenterOn=i(1882),s.Centroid=i(56595),s.CircumCenter=i(91835),s.CircumCircle=i(97073),s.Clone=i(75974),s.Contains=i(60689),s.ContainsArray=i(86875),s.ContainsPoint=i(51532),s.CopyFrom=i(42538),s.Decompose=i(18680),s.Equals=i(29977),s.GetPoint=i(56088),s.GetPoints=i(24402),s.InCenter=i(83648),s.Perimeter=i(95290),s.Offset=i(9640),s.Random=i(99761),s.Rotate=i(21934),s.RotateAroundPoint=i(68454),s.RotateAroundXY=i(19211),t.exports=s},27395:t=>{t.exports=function(t,e,i){return{gameObject:t,enabled:!0,draggable:!1,dropZone:!1,cursor:!1,target:null,camera:null,hitArea:e,hitAreaCallback:i,hitAreaDebug:null,customHitArea:!1,localX:0,localY:0,dragState:0,dragStartX:0,dragStartY:0,dragStartXGlobal:0,dragStartYGlobal:0,dragX:0,dragY:0}}},18104:t=>{t.exports=function(t,e){return function(i,s,n,r){var o=t.getPixelAlpha(s,n,r.texture.key,r.frame.name);return o&&o>=e}}},69898:(t,e,i)=>{var s=i(56694),n=i(72687),r=i(6659),o=i(33963),a=i(97081),h=i(71064),l=i(7905),u=i(40398),c=i(37579),d=i(69360),f=i(64462),p=new s({initialize:function(t,e){this.game=t,this.scaleManager,this.canvas,this.config=e,this.enabled=!0,this.events=new r,this.isOver=!0,this.defaultCursor="",this.keyboard=e.inputKeyboard?new h(this):null,this.mouse=e.inputMouse?new l(this):null,this.touch=e.inputTouch?new c(this):null,this.pointers=[],this.pointersTotal=e.inputActivePointers,e.inputTouch&&1===this.pointersTotal&&(this.pointersTotal=2);for(var i=0;i<=this.pointersTotal;i++){var s=new u(this,i);s.smoothFactor=e.inputSmoothFactor,this.pointers.push(s)}this.mousePointer=e.inputMouse?this.pointers[0]:null,this.activePointer=this.pointers[0],this.globalTopOnly=!0,this.time=0,this._tempPoint={x:0,y:0},this._tempHitTest=[],this._tempMatrix=new d,this._tempMatrix2=new d,this._tempSkip=!1,this.mousePointerContainer=[this.mousePointer],t.events.once(a.BOOT,this.boot,this)},boot:function(){var t=this.game,e=t.events;this.canvas=t.canvas,this.scaleManager=t.scale,this.events.emit(o.MANAGER_BOOT),e.on(a.PRE_RENDER,this.preRender,this),e.once(a.DESTROY,this.destroy,this)},setCanvasOver:function(t){this.isOver=!0,this.events.emit(o.GAME_OVER,t)},setCanvasOut:function(t){this.isOver=!1,this.events.emit(o.GAME_OUT,t)},preRender:function(){var t=this.game.loop.now,e=this.game.loop.delta,i=this.game.scene.getScenes(!0,!0);this.time=t,this.events.emit(o.MANAGER_UPDATE);for(var s=0;s10&&(t=10-this.pointersTotal);for(var i=0;i{var s=i(26673),n=i(65650),r=i(56694),o=i(72687),a=i(27395),h=i(18104),l=i(53996),u=i(95669),c=i(72313),d=i(33963),f=i(6659),p=i(72632),v=i(52394),g=i(63399),m=i(42911),y=i(91963),x=i(74118),T=i(94287),w=i(7599),b=i(66349),S=i(60689),E=new r({Extends:f,initialize:function(t){f.call(this),this.scene=t,this.systems=t.sys,this.settings=t.sys.settings,this.manager=t.sys.game.input,this.pluginEvents=new f,this.enabled=!0,this.displayList,this.cameras,g.install(this),this.mouse=this.manager.mouse,this.topOnly=!0,this.pollRate=-1,this._pollTimer=0;var e={cancelled:!1};this._eventContainer={stopPropagation:function(){e.cancelled=!0}},this._eventData=e,this.dragDistanceThreshold=0,this.dragTimeThreshold=0,this._temp=[],this._tempZones=[],this._list=[],this._pendingInsertion=[],this._pendingRemoval=[],this._draggable=[],this._drag={0:[],1:[],2:[],3:[],4:[],5:[],6:[],7:[],8:[],9:[],10:[]},this._dragState=[],this._over={0:[],1:[],2:[],3:[],4:[],5:[],6:[],7:[],8:[],9:[],10:[]},this._validTypes=["onDown","onUp","onOver","onOut","onMove","onDragStart","onDrag","onDragEnd","onDragEnter","onDragLeave","onDragOver","onDrop"],this._updatedThisFrame=!1,t.sys.events.once(w.BOOT,this.boot,this),t.sys.events.on(w.START,this.start,this)},boot:function(){this.cameras=this.systems.cameras,this.displayList=this.systems.displayList,this.systems.events.once(w.DESTROY,this.destroy,this),this.pluginEvents.emit(d.BOOT)},start:function(){var t=this.systems.events;t.on(w.TRANSITION_START,this.transitionIn,this),t.on(w.TRANSITION_OUT,this.transitionOut,this),t.on(w.TRANSITION_COMPLETE,this.transitionComplete,this),t.on(w.PRE_UPDATE,this.preUpdate,this),t.once(w.SHUTDOWN,this.shutdown,this),this.manager.events.on(d.GAME_OUT,this.onGameOut,this),this.manager.events.on(d.GAME_OVER,this.onGameOver,this),this.enabled=!0,this._dragState=[0,0,0,0,0,0,0,0,0,0],this.pluginEvents.emit(d.START)},onGameOver:function(t){this.isActive()&&this.emit(d.GAME_OVER,t.timeStamp,t)},onGameOut:function(t){this.isActive()&&this.emit(d.GAME_OUT,t.timeStamp,t)},preUpdate:function(){this.pluginEvents.emit(d.PRE_UPDATE);var t=this._pendingRemoval,e=this._pendingInsertion,i=t.length,s=e.length;if(0!==i||0!==s){for(var n=this._list,r=0;r-1&&(n.splice(a,1),this.clear(o,!0))}this._pendingRemoval.length=0,this._list=n.concat(e.splice(0))}},isActive:function(){return this.enabled&&this.scene.sys.canInput()},updatePoll:function(t,e){if(!this.isActive())return!1;if(this.pluginEvents.emit(d.UPDATE,t,e),this._updatedThisFrame)return this._updatedThisFrame=!1,!1;var i,s=this.manager,n=s.pointers,r=s.pointersTotal;for(i=0;i0){if(this._pollTimer-=e,!(this._pollTimer<0))return!1;this._pollTimer=this.pollRate}var a=!1;for(i=0;i0&&(a=!0)}return a},update:function(t,e){if(!this.isActive())return!1;for(var i=e.length,s=!1,n=0;n0&&(s=!0)}return this._updatedThisFrame=!0,s},clear:function(t,e){void 0===e&&(e=!1),this.disable(t);var i=t.input;i&&(this.removeDebug(t),i.gameObject=void 0,i.target=void 0,i.hitArea=void 0,i.hitAreaCallback=void 0,i.callbackContext=void 0,t.input=null),e||this.queueForRemoval(t);var s=this._draggable.indexOf(t);return s>-1&&this._draggable.splice(s,1),t},disable:function(t){var e=t.input;e&&(e.enabled=!1,e.dragState=0);var i=this._temp,s=this._drag,n=this._over,r=this.manager,o=i.indexOf(t);o>-1&&i.splice(o,1);for(var a=0;a-1&&s[a].splice(o,1),(o=n[a].indexOf(t))>-1&&(n[a].splice(o,1),r.resetCursor(e));return this},enable:function(t,e,i,s){return void 0===s&&(s=!1),t.input?t.input.enabled=!0:this.setHitArea(t,e,i),t.input&&s&&!t.input.dropZone&&(t.input.dropZone=s),this},hitTestPointer:function(t){for(var e=this.cameras.getCamerasBelowPointer(t),i=0;i0)return t.camera=s,n}return t.camera=e[0],[]},processDownEvents:function(t){var e=0,i=this._temp,s=this._eventData,n=this._eventContainer;s.cancelled=!1;for(var r=!1,o=0;o0&&l(t.x,t.y,t.downX,t.downY)>=n||s>0&&e>=t.downTime+s)&&(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;i1&&(this.sortGameObjects(i,t),this.topOnly&&i.splice(1)),this._drag[t.id]=i,0===this.dragDistanceThreshold&&0===this.dragTimeThreshold?(this.setDragState(t,3),this.processDragStartList(t)):(this.setDragState(t,2),0))},processDragMoveEvent:function(t){if(2===this.getDragState(t)&&this.processDragThresholdEvent(t,this.manager.game.loop.now),4!==this.getDragState(t))return 0;for(var e=this._tempZones,i=this._drag[t.id],s=0;s0?(o.emit(d.GAMEOBJECT_DRAG_LEAVE,t,h),this.emit(d.DRAG_LEAVE,t,o,h),a.target=e[0],h=a.target,o.emit(d.GAMEOBJECT_DRAG_ENTER,t,h),this.emit(d.DRAG_ENTER,t,o,h)):(o.emit(d.GAMEOBJECT_DRAG_LEAVE,t,h),this.emit(d.DRAG_LEAVE,t,o,h),e[0]?(a.target=e[0],h=a.target,o.emit(d.GAMEOBJECT_DRAG_ENTER,t,h),this.emit(d.DRAG_ENTER,t,o,h)):a.target=null)}else!h&&e[0]&&(a.target=e[0],h=a.target,o.emit(d.GAMEOBJECT_DRAG_ENTER,t,h),this.emit(d.DRAG_ENTER,t,o,h));if(o.parentContainer){var u=t.worldX-a.dragStartXGlobal,c=t.worldY-a.dragStartYGlobal,f=o.getParentRotation(),p=u*Math.cos(f)+c*Math.sin(f),v=c*Math.cos(f)-u*Math.sin(f);p*=1/o.parentContainer.scaleX,v*=1/o.parentContainer.scaleY,n=p+a.dragStartX,r=v+a.dragStartY}else n=t.worldX-a.dragX,r=t.worldY-a.dragY;o.emit(d.GAMEOBJECT_DRAG,t,n,r),this.emit(d.DRAG,t,o,n,r)}return i.length},processDragUpEvent:function(t){for(var e=this._drag[t.id],i=0;i0){var r=this.manager,o=this._eventData,a=this._eventContainer;o.cancelled=!1;for(var h=!1,l=0;l0){var n=this.manager,r=this._eventData,o=this._eventContainer;r.cancelled=!1;var a=!1;this.sortGameObjects(e,t);for(var h=0;h0){for(this.sortGameObjects(n,t),e=0;e0){for(this.sortGameObjects(r,t),e=0;e-1&&this._draggable.splice(n,1)}return this},makePixelPerfect:function(t){void 0===t&&(t=1);var e=this.systems.textures;return h(e,t)},setHitArea:function(t,e,i){if(void 0===e)return this.setHitAreaFromTexture(t);Array.isArray(t)||(t=[t]);var s=!1,n=!1,r=!1,o=!1,h=!1,l=!0;if(m(e)){var u=e;e=p(u,"hitArea",null),i=p(u,"hitAreaCallback",null),s=p(u,"draggable",!1),n=p(u,"dropZone",!1),r=p(u,"cursor",!1),o=p(u,"useHandCursor",!1),h=p(u,"pixelPerfect",!1);var c=p(u,"alphaTolerance",1);h&&(e={},i=this.makePixelPerfect(c)),e&&i||(this.setHitAreaFromTexture(t),l=!1)}else"function"!=typeof e||i||(i=e,e={});for(var d=0;d{var s=i(10850),n={},r={register:function(t,e,i,s,r){n[t]={plugin:e,mapping:i,settingsKey:s,configKey:r}},getPlugin:function(t){return n[t]},install:function(t){var e=t.scene.sys,i=e.settings.input,r=e.game.config;for(var o in n){var a=n[o].plugin,h=n[o].mapping,l=n[o].settingsKey,u=n[o].configKey;s(i,l,r[u])&&(t[h]=new a(t))}},remove:function(t){n.hasOwnProperty(t)&&delete n[t]}};t.exports=r},40398:(t,e,i)=>{var s=i(90447),n=i(56694),r=i(53996),o=i(88456),a=i(44521),h=i(93736),l=i(36580),u=new n({initialize:function(t,e){this.manager=t,this.id=e,this.event,this.downElement,this.upElement,this.camera=null,this.button=0,this.buttons=0,this.position=new h,this.prevPosition=new h,this.midPoint=new h(-1,-1),this.velocity=new h,this.angle=0,this.distance=0,this.smoothFactor=0,this.motionFactor=.2,this.worldX=0,this.worldY=0,this.moveTime=0,this.downX=0,this.downY=0,this.downTime=0,this.upX=0,this.upY=0,this.upTime=0,this.primaryDown=!1,this.isDown=!1,this.wasTouch=!1,this.wasCanceled=!1,this.movementX=0,this.movementY=0,this.identifier=0,this.pointerId=null,this.active=0===e,this.locked=!1,this.deltaX=0,this.deltaY=0,this.deltaZ=0},updateWorldPoint:function(t){var e=t.getWorldPoint(this.x,this.y);return this.worldX=e.x,this.worldY=e.y,this},positionToCamera:function(t,e){return t.getWorldPoint(this.x,this.y,e)},updateMotion:function(){var t=this.position.x,e=this.position.y,i=this.midPoint.x,n=this.midPoint.y;if(t!==i||e!==n){var r=a(this.motionFactor,i,t),h=a(this.motionFactor,n,e);o(r,t,.1)&&(r=t),o(h,e,.1)&&(h=e),this.midPoint.set(r,h);var l=t-r,u=e-h;this.velocity.set(l,u),this.angle=s(r,h,t,e),this.distance=Math.sqrt(l*l+u*u)}},up:function(t){"buttons"in t&&(this.buttons=t.buttons),this.event=t,this.button=t.button,this.upElement=t.target,this.manager.transformPointer(this,t.pageX,t.pageY,!1),0===t.button&&(this.primaryDown=!1,this.upX=this.x,this.upY=this.y),0===this.buttons&&(this.isDown=!1,this.upTime=t.timeStamp,this.wasTouch=!1)},down:function(t){"buttons"in t&&(this.buttons=t.buttons),this.event=t,this.button=t.button,this.downElement=t.target,this.manager.transformPointer(this,t.pageX,t.pageY,!1),0===t.button&&(this.primaryDown=!0,this.downX=this.x,this.downY=this.y),l.macOS&&t.ctrlKey&&(this.buttons=2,this.primaryDown=!1),this.isDown||(this.isDown=!0,this.downTime=t.timeStamp),this.wasTouch=!1},move:function(t){"buttons"in t&&(this.buttons=t.buttons),this.event=t,this.manager.transformPointer(this,t.pageX,t.pageY,!0),this.locked&&(this.movementX=t.movementX||t.mozMovementX||t.webkitMovementX||0,this.movementY=t.movementY||t.mozMovementY||t.webkitMovementY||0),this.moveTime=t.timeStamp,this.wasTouch=!1},wheel:function(t){"buttons"in t&&(this.buttons=t.buttons),this.event=t,this.manager.transformPointer(this,t.pageX,t.pageY,!1),this.deltaX=t.deltaX,this.deltaY=t.deltaY,this.deltaZ=t.deltaZ,this.wasTouch=!1},touchstart:function(t,e){t.pointerId&&(this.pointerId=t.pointerId),this.identifier=t.identifier,this.target=t.target,this.active=!0,this.buttons=1,this.event=e,this.downElement=t.target,this.manager.transformPointer(this,t.pageX,t.pageY,!1),this.primaryDown=!0,this.downX=this.x,this.downY=this.y,this.downTime=e.timeStamp,this.isDown=!0,this.wasTouch=!0,this.wasCanceled=!1,this.updateMotion()},touchmove:function(t,e){this.event=e,this.manager.transformPointer(this,t.pageX,t.pageY,!0),this.moveTime=e.timeStamp,this.wasTouch=!0,this.updateMotion()},touchend:function(t,e){this.buttons=0,this.event=e,this.upElement=t.target,this.manager.transformPointer(this,t.pageX,t.pageY,!1),this.primaryDown=!1,this.upX=this.x,this.upY=this.y,this.upTime=e.timeStamp,this.isDown=!1,this.wasTouch=!0,this.wasCanceled=!1,this.active=!1,this.updateMotion()},touchcancel:function(t,e){this.buttons=0,this.event=e,this.upElement=t.target,this.manager.transformPointer(this,t.pageX,t.pageY,!1),this.primaryDown=!1,this.upX=this.x,this.upY=this.y,this.upTime=e.timeStamp,this.isDown=!1,this.wasTouch=!0,this.wasCanceled=!0,this.active=!1},noButtonDown:function(){return 0===this.buttons},leftButtonDown:function(){return!!(1&this.buttons)},rightButtonDown:function(){return!!(2&this.buttons)},middleButtonDown:function(){return!!(4&this.buttons)},backButtonDown:function(){return!!(8&this.buttons)},forwardButtonDown:function(){return!!(16&this.buttons)},leftButtonReleased:function(){return 0===this.button&&!this.isDown},rightButtonReleased:function(){return 2===this.button&&!this.isDown},middleButtonReleased:function(){return 1===this.button&&!this.isDown},backButtonReleased:function(){return 3===this.button&&!this.isDown},forwardButtonReleased:function(){return 4===this.button&&!this.isDown},getDistance:function(){return this.isDown?r(this.downX,this.downY,this.x,this.y):r(this.downX,this.downY,this.upX,this.upY)},getDistanceX:function(){return this.isDown?Math.abs(this.downX-this.x):Math.abs(this.downX-this.upX)},getDistanceY:function(){return this.isDown?Math.abs(this.downY-this.y):Math.abs(this.downY-this.upY)},getDuration:function(){return this.isDown?this.manager.time-this.downTime:this.upTime-this.downTime},getAngle:function(){return this.isDown?s(this.downX,this.downY,this.x,this.y):s(this.downX,this.downY,this.upX,this.upY)},getInterpolatedPosition:function(t,e){void 0===t&&(t=10),void 0===e&&(e=[]);for(var i=this.prevPosition.x,s=this.prevPosition.y,n=this.position.x,r=this.position.y,o=0;o{t.exports={MOUSE_DOWN:0,MOUSE_MOVE:1,MOUSE_UP:2,TOUCH_START:3,TOUCH_MOVE:4,TOUCH_END:5,POINTER_LOCK_CHANGE:6,TOUCH_CANCEL:7,MOUSE_WHEEL:8}},14874:t=>{t.exports="boot"},54168:t=>{t.exports="destroy"},526:t=>{t.exports="dragend"},81623:t=>{t.exports="dragenter"},94472:t=>{t.exports="drag"},9304:t=>{t.exports="dragleave"},34265:t=>{t.exports="dragover"},50151:t=>{t.exports="dragstart"},98134:t=>{t.exports="drop"},56773:t=>{t.exports="gameobjectdown"},45824:t=>{t.exports="dragend"},39578:t=>{t.exports="dragenter"},72072:t=>{t.exports="drag"},82569:t=>{t.exports="dragleave"},70833:t=>{t.exports="dragover"},81442:t=>{t.exports="dragstart"},32936:t=>{t.exports="drop"},99658:t=>{t.exports="gameobjectmove"},60515:t=>{t.exports="gameobjectout"},55254:t=>{t.exports="gameobjectover"},34782:t=>{t.exports="pointerdown"},41769:t=>{t.exports="pointermove"},65588:t=>{t.exports="pointerout"},61640:t=>{t.exports="pointerover"},49342:t=>{t.exports="pointerup"},82662:t=>{t.exports="wheel"},13058:t=>{t.exports="gameobjectup"},52426:t=>{t.exports="gameobjectwheel"},78072:t=>{t.exports="gameout"},1545:t=>{t.exports="gameover"},67137:t=>{t.exports="boot"},27678:t=>{t.exports="process"},22257:t=>{t.exports="update"},90379:t=>{t.exports="pointerlockchange"},88909:t=>{t.exports="pointerdown"},36548:t=>{t.exports="pointerdownoutside"},18483:t=>{t.exports="pointermove"},22355:t=>{t.exports="pointerout"},7997:t=>{t.exports="pointerover"},66318:t=>{t.exports="pointerup"},94812:t=>{t.exports="pointerupoutside"},37310:t=>{t.exports="wheel"},24196:t=>{t.exports="preupdate"},27053:t=>{t.exports="shutdown"},29413:t=>{t.exports="start"},25165:t=>{t.exports="update"},33963:(t,e,i)=>{t.exports={BOOT:i(14874),DESTROY:i(54168),DRAG_END:i(526),DRAG_ENTER:i(81623),DRAG:i(94472),DRAG_LEAVE:i(9304),DRAG_OVER:i(34265),DRAG_START:i(50151),DROP:i(98134),GAME_OUT:i(78072),GAME_OVER:i(1545),GAMEOBJECT_DOWN:i(56773),GAMEOBJECT_DRAG_END:i(45824),GAMEOBJECT_DRAG_ENTER:i(39578),GAMEOBJECT_DRAG:i(72072),GAMEOBJECT_DRAG_LEAVE:i(82569),GAMEOBJECT_DRAG_OVER:i(70833),GAMEOBJECT_DRAG_START:i(81442),GAMEOBJECT_DROP:i(32936),GAMEOBJECT_MOVE:i(99658),GAMEOBJECT_OUT:i(60515),GAMEOBJECT_OVER:i(55254),GAMEOBJECT_POINTER_DOWN:i(34782),GAMEOBJECT_POINTER_MOVE:i(41769),GAMEOBJECT_POINTER_OUT:i(65588),GAMEOBJECT_POINTER_OVER:i(61640),GAMEOBJECT_POINTER_UP:i(49342),GAMEOBJECT_POINTER_WHEEL:i(82662),GAMEOBJECT_UP:i(13058),GAMEOBJECT_WHEEL:i(52426),MANAGER_BOOT:i(67137),MANAGER_PROCESS:i(27678),MANAGER_UPDATE:i(22257),POINTER_DOWN:i(88909),POINTER_DOWN_OUTSIDE:i(36548),POINTER_MOVE:i(18483),POINTER_OUT:i(22355),POINTER_OVER:i(7997),POINTER_UP:i(66318),POINTER_UP_OUTSIDE:i(94812),POINTER_WHEEL:i(37310),POINTERLOCK_CHANGE:i(90379),PRE_UPDATE:i(24196),SHUTDOWN:i(27053),START:i(29413),UPDATE:i(25165)}},70848:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e){this.pad=t,this.events=t.events,this.index=e,this.value=0,this.threshold=.1},update:function(t){this.value=t},getValue:function(){return Math.abs(this.value){var s=i(56694),n=i(43200),r=new s({initialize:function(t,e){this.pad=t,this.events=t.manager,this.index=e,this.value=0,this.threshold=1,this.pressed=!1},update:function(t){this.value=t;var e=this.pad,i=this.index;t>=this.threshold?this.pressed||(this.pressed=!0,this.events.emit(n.BUTTON_DOWN,e,this,t),this.pad.emit(n.GAMEPAD_BUTTON_DOWN,i,t,this)):this.pressed&&(this.pressed=!1,this.events.emit(n.BUTTON_UP,e,this,t),this.pad.emit(n.GAMEPAD_BUTTON_UP,i,t,this))},destroy:function(){this.pad=null,this.events=null}});t.exports=r},75956:(t,e,i)=>{var s=i(70848),n=i(21274),r=i(56694),o=i(6659),a=i(93736),h=new r({Extends:o,initialize:function(t,e){o.call(this),this.manager=t,this.pad=e,this.id=e.id,this.index=e.index;for(var i=[],r=0;r=2&&(this.leftStick.set(r[0].getValue(),r[1].getValue()),n>=4&&this.rightStick.set(r[2].getValue(),r[3].getValue()))}},destroy:function(){var t;for(this.removeAllListeners(),this.manager=null,this.pad=null,t=0;t{var s=i(56694),n=i(6659),r=i(43200),o=i(75956),a=i(10850),h=i(63399),l=i(33963),u=new s({Extends:n,initialize:function(t){n.call(this),this.scene=t.scene,this.settings=this.scene.sys.settings,this.sceneInputPlugin=t,this.enabled=!0,this.target,this.gamepads=[],this.queue=[],this.onGamepadHandler,this._pad1,this._pad2,this._pad3,this._pad4,t.pluginEvents.once(l.BOOT,this.boot,this),t.pluginEvents.on(l.START,this.start,this)},boot:function(){var t=this.scene.sys.game,e=this.settings.input,i=t.config;this.enabled=a(e,"gamepad",i.inputGamepad)&&t.device.input.gamepads,this.target=a(e,"gamepad.target",i.inputGamepadEventTarget),this.sceneInputPlugin.pluginEvents.once(l.DESTROY,this.destroy,this)},start:function(){this.enabled&&(this.startListeners(),this.refreshPads()),this.sceneInputPlugin.pluginEvents.once(l.SHUTDOWN,this.shutdown,this)},isActive:function(){return this.enabled&&this.scene.sys.isActive()},startListeners:function(){var t=this,e=this.target,i=function(e){!e.defaultPrevented&&t.isActive()&&(t.refreshPads(),t.queue.push(e))};this.onGamepadHandler=i,e.addEventListener("gamepadconnected",i,!1),e.addEventListener("gamepaddisconnected",i,!1),this.sceneInputPlugin.pluginEvents.on(l.UPDATE,this.update,this)},stopListeners:function(){this.target.removeEventListener("gamepadconnected",this.onGamepadHandler),this.target.removeEventListener("gamepaddisconnected",this.onGamepadHandler),this.sceneInputPlugin.pluginEvents.off(l.UPDATE,this.update);for(var t=0;t{t.exports={UP:12,DOWN:13,LEFT:14,RIGHT:15,SELECT:8,START:9,B:0,A:1,Y:2,X:3,LEFT_SHOULDER:4,RIGHT_SHOULDER:5}},74982:t=>{t.exports={UP:12,DOWN:13,LEFT:14,RIGHT:15,SHARE:8,OPTIONS:9,PS:16,TOUCHBAR:17,X:0,CIRCLE:1,SQUARE:2,TRIANGLE:3,L1:4,R1:5,L2:6,R2:7,L3:10,R3:11,LEFT_STICK_H:0,LEFT_STICK_V:1,RIGHT_STICK_H:2,RIGHT_STICK_V:3}},43247:t=>{t.exports={UP:12,DOWN:13,LEFT:14,RIGHT:15,MENU:16,A:0,B:1,X:2,Y:3,LB:4,RB:5,LT:6,RT:7,BACK:8,START:9,LS:10,RS:11,LEFT_STICK_H:0,LEFT_STICK_V:1,RIGHT_STICK_H:2,RIGHT_STICK_V:3}},4898:(t,e,i)=>{t.exports={DUALSHOCK_4:i(74982),SNES_USB:i(33171),XBOX_360:i(43247)}},17344:t=>{t.exports="down"},36635:t=>{t.exports="up"},85724:t=>{t.exports="connected"},55832:t=>{t.exports="disconnected"},772:t=>{t.exports="down"},33608:t=>{t.exports="up"},43200:(t,e,i)=>{t.exports={BUTTON_DOWN:i(17344),BUTTON_UP:i(36635),CONNECTED:i(85724),DISCONNECTED:i(55832),GAMEPAD_BUTTON_DOWN:i(772),GAMEPAD_BUTTON_UP:i(33608)}},92636:(t,e,i)=>{t.exports={Axis:i(70848),Button:i(21274),Events:i(43200),Gamepad:i(75956),GamepadPlugin:i(1379),Configs:i(4898)}},20873:(t,e,i)=>{var s=i(72687),n=i(98611),r={CreatePixelPerfectHandler:i(18104),CreateInteractiveObject:i(27395),Events:i(33963),Gamepad:i(92636),InputManager:i(69898),InputPlugin:i(12499),InputPluginCache:i(63399),Keyboard:i(28388),Mouse:i(11343),Pointer:i(40398),Touch:i(77423)};r=n(!1,r,s),t.exports=r},71064:(t,e,i)=>{var s=i(66458),n=i(56694),r=i(97081),o=i(33963),a=i(11873),h=i(72283),l=new n({initialize:function(t){this.manager=t,this.queue=[],this.preventDefault=!0,this.captures=[],this.enabled=!1,this.target,this.onKeyDown=h,this.onKeyUp=h,t.events.once(o.MANAGER_BOOT,this.boot,this)},boot:function(){var t=this.manager.config;this.enabled=t.inputKeyboard,this.target=t.inputKeyboardEventTarget,this.addCapture(t.inputKeyboardCapture),!this.target&&window&&(this.target=window),this.enabled&&this.target&&this.startListeners(),this.manager.game.events.on(r.POST_STEP,this.postUpdate,this)},startListeners:function(){var t=this;this.onKeyDown=function(e){if(!e.defaultPrevented&&t.enabled&&t.manager){t.queue.push(e),t.manager.events.emit(o.MANAGER_PROCESS);var i=e.altKey||e.ctrlKey||e.shiftKey||e.metaKey;t.preventDefault&&!i&&t.captures.indexOf(e.keyCode)>-1&&e.preventDefault()}},this.onKeyUp=function(e){if(!e.defaultPrevented&&t.enabled&&t.manager){t.queue.push(e),t.manager.events.emit(o.MANAGER_PROCESS);var i=e.altKey||e.ctrlKey||e.shiftKey||e.metaKey;t.preventDefault&&!i&&t.captures.indexOf(e.keyCode)>-1&&e.preventDefault()}};var e=this.target;e&&(e.addEventListener("keydown",this.onKeyDown,!1),e.addEventListener("keyup",this.onKeyUp,!1),this.enabled=!0)},stopListeners:function(){var t=this.target;t.removeEventListener("keydown",this.onKeyDown,!1),t.removeEventListener("keyup",this.onKeyUp,!1),this.enabled=!1},postUpdate:function(){this.queue=[]},addCapture:function(t){"string"==typeof t&&(t=t.split(",")),Array.isArray(t)||(t=[t]);for(var e=this.captures,i=0;i0},removeCapture:function(t){"string"==typeof t&&(t=t.split(",")),Array.isArray(t)||(t=[t]);for(var e=this.captures,i=0;i0},clearCaptures:function(){this.captures=[],this.preventDefault=!1},destroy:function(){this.stopListeners(),this.clearCaptures(),this.queue=[],this.manager.game.events.off(r.POST_RENDER,this.postUpdate,this),this.target=null,this.enabled=!1,this.manager=null}});t.exports=l},89666:(t,e,i)=>{var s=i(56694),n=i(6659),r=i(94030),o=i(97081),a=i(10850),h=i(33963),l=i(63399),u=i(50165),c=i(11873),d=i(95625),f=i(48044),p=i(7599),v=i(84314),g=new s({Extends:n,initialize:function(t){n.call(this),this.game=t.systems.game,this.scene=t.scene,this.settings=this.scene.sys.settings,this.sceneInputPlugin=t,this.manager=t.manager.keyboard,this.enabled=!0,this.keys=[],this.combos=[],this.prevCode=null,this.prevTime=0,this.prevType=null,t.pluginEvents.once(h.BOOT,this.boot,this),t.pluginEvents.on(h.START,this.start,this)},boot:function(){var t=this.settings.input;this.enabled=a(t,"keyboard",!0);var e=a(t,"keyboard.capture",null);e&&this.addCaptures(e),this.sceneInputPlugin.pluginEvents.once(h.DESTROY,this.destroy,this)},start:function(){this.sceneInputPlugin.manager.events.on(h.MANAGER_PROCESS,this.update,this),this.sceneInputPlugin.pluginEvents.once(h.SHUTDOWN,this.shutdown,this),this.game.events.on(o.BLUR,this.resetKeys,this),this.scene.sys.events.on(p.PAUSE,this.resetKeys,this),this.scene.sys.events.on(p.SLEEP,this.resetKeys,this)},isActive:function(){return this.enabled&&this.scene.sys.canInput()},addCapture:function(t){return this.manager.addCapture(t),this},removeCapture:function(t){return this.manager.removeCapture(t),this},getCaptures:function(){return this.manager.captures},enableGlobalCapture:function(){return this.manager.preventDefault=!0,this},disableGlobalCapture:function(){return this.manager.preventDefault=!1,this},clearCaptures:function(){return this.manager.clearCaptures(),this},createCursorKeys:function(){return this.addKeys({up:c.UP,down:c.DOWN,left:c.LEFT,right:c.RIGHT,space:c.SPACE,shift:c.SHIFT})},addKeys:function(t,e,i){void 0===e&&(e=!0),void 0===i&&(i=!1);var s={};if("string"==typeof t){t=t.split(",");for(var n=0;n-1?s[n]=t:s[t.keyCode]=t,e&&this.addCapture(t.keyCode),t.setEmitOnRepeat(i),t}return"string"==typeof t&&(t=c[t.toUpperCase()]),s[t]||(s[t]=new u(this,t),e&&this.addCapture(t),s[t].setEmitOnRepeat(i)),s[t]},removeKey:function(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var s,n=this.keys;if(t instanceof u){var r=n.indexOf(t);r>-1&&(s=this.keys[r],this.keys[r]=void 0)}else"string"==typeof t&&(t=c[t.toUpperCase()]);return n[t]&&(s=n[t],n[t]=void 0),s&&(s.plugin=null,i&&this.removeCapture(s.keyCode),e&&s.destroy()),this},removeAllKeys:function(t,e){void 0===t&&(t=!1),void 0===e&&(e=!1);for(var i=this.keys,s=0;st._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,s=0;s{t.exports=function(t,e){return e.timeLastMatched=t.timeStamp,e.index++,e.index===e.size||(e.current=e.keyCodes[e.index],!1)}},95625:(t,e,i)=>{var s=i(56694),n=i(94030),r=i(72632),o=i(2544),a=i(88754),h=new s({initialize:function(t,e,i){if(void 0===i&&(i={}),e.length<2)return!1;this.manager=t,this.enabled=!0,this.keyCodes=[];for(var s=0;s{var s=i(60258);t.exports=function(t,e){if(e.matched)return!0;var i=!1,n=!1;if(t.keyCode===e.current)if(e.index>0&&e.maxKeyDelay>0){var r=e.timeLastMatched+e.maxKeyDelay;t.timeStamp<=r&&(n=!0,i=s(t,e))}else n=!0,i=s(t,e);return!n&&e.resetOnWrongKey&&(e.index=0,e.current=e.keyCodes[0]),i&&(e.timeLastMatched=t.timeStamp,e.matched=!0,e.timeMatched=t.timeStamp),i}},88754:t=>{t.exports=function(t){return t.current=t.keyCodes[0],t.index=0,t.timeLastMatched=0,t.matched=!1,t.timeMatched=0,t}},5044:t=>{t.exports="keydown"},40813:t=>{t.exports="keyup"},89319:t=>{t.exports="keycombomatch"},43267:t=>{t.exports="down"},78595:t=>{t.exports="keydown-"},30056:t=>{t.exports="keyup-"},81939:t=>{t.exports="up"},94030:(t,e,i)=>{t.exports={ANY_KEY_DOWN:i(5044),ANY_KEY_UP:i(40813),COMBO_MATCH:i(89319),DOWN:i(43267),KEY_DOWN:i(78595),KEY_UP:i(30056),UP:i(81939)}},28388:(t,e,i)=>{t.exports={Events:i(94030),KeyboardManager:i(71064),KeyboardPlugin:i(89666),Key:i(50165),KeyCodes:i(11873),KeyCombo:i(95625),AdvanceKeyCombo:i(60258),ProcessKeyCombo:i(2544),ResetKeyCombo:i(88754),JustDown:i(42460),JustUp:i(53162),DownDuration:i(64964),UpDuration:i(70331)}},64964:t=>{t.exports=function(t,e){void 0===e&&(e=50);var i=t.plugin.game.loop.time-t.timeDown;return t.isDown&&i{t.exports=function(t){return!!t._justDown&&(t._justDown=!1,!0)}},53162:t=>{t.exports=function(t){return!!t._justUp&&(t._justUp=!1,!0)}},50165:(t,e,i)=>{var s=i(56694),n=i(6659),r=i(94030),o=new s({Extends:n,initialize:function(t,e){n.call(this),this.plugin=t,this.keyCode=e,this.originalEvent=void 0,this.enabled=!0,this.isDown=!1,this.isUp=!0,this.altKey=!1,this.ctrlKey=!1,this.shiftKey=!1,this.metaKey=!1,this.location=0,this.timeDown=0,this.duration=0,this.timeUp=0,this.emitOnRepeat=!1,this.repeats=0,this._justDown=!1,this._justUp=!1,this._tick=-1},setEmitOnRepeat:function(t){return this.emitOnRepeat=t,this},onDown:function(t){this.originalEvent=t,this.enabled&&(this.altKey=t.altKey,this.ctrlKey=t.ctrlKey,this.shiftKey=t.shiftKey,this.metaKey=t.metaKey,this.location=t.location,this.repeats++,this.isDown?this.emitOnRepeat&&this.emit(r.DOWN,this,t):(this.isDown=!0,this.isUp=!1,this.timeDown=t.timeStamp,this.duration=0,this._justDown=!0,this._justUp=!1,this.emit(r.DOWN,this,t)))},onUp:function(t){this.originalEvent=t,this.enabled&&(this.isDown=!1,this.isUp=!0,this.timeUp=t.timeStamp,this.duration=this.timeUp-this.timeDown,this.repeats=0,this._justDown=!1,this._justUp=!0,this._tick=-1,this.emit(r.UP,this,t))},reset:function(){return this.isDown=!1,this.isUp=!0,this.altKey=!1,this.ctrlKey=!1,this.shiftKey=!1,this.metaKey=!1,this.timeDown=0,this.duration=0,this.timeUp=0,this.repeats=0,this._justDown=!1,this._justUp=!1,this._tick=-1,this},getDuration:function(){return this.isDown?this.plugin.game.loop.time-this.timeDown:0},destroy:function(){this.removeAllListeners(),this.originalEvent=null,this.plugin=null}});t.exports=o},11873:t=>{t.exports={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:42,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,NUMPAD_ZERO:96,NUMPAD_ONE:97,NUMPAD_TWO:98,NUMPAD_THREE:99,NUMPAD_FOUR:100,NUMPAD_FIVE:101,NUMPAD_SIX:102,NUMPAD_SEVEN:103,NUMPAD_EIGHT:104,NUMPAD_NINE:105,NUMPAD_ADD:107,NUMPAD_SUBTRACT:109,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,SEMICOLON:186,PLUS:187,COMMA:188,MINUS:189,PERIOD:190,FORWARD_SLASH:191,BACK_SLASH:220,QUOTES:222,BACKTICK:192,OPEN_BRACKET:219,CLOSED_BRACKET:221,SEMICOLON_FIREFOX:59,COLON:58,COMMA_FIREFOX_WINDOWS:60,COMMA_FIREFOX:62,BRACKET_RIGHT_FIREFOX:174,BRACKET_LEFT_FIREFOX:175}},48044:(t,e,i)=>{var s=i(11873),n={};for(var r in s)n[s[r]]=r;t.exports=n},70331:t=>{t.exports=function(t,e){void 0===e&&(e=50);var i=t.plugin.game.loop.time-t.timeUp;return t.isUp&&i{var s=i(56694),n=i(90185),r=i(33963),o=i(72283),a=new s({initialize:function(t){this.manager=t,this.preventDefaultDown=!0,this.preventDefaultUp=!0,this.preventDefaultMove=!0,this.preventDefaultWheel=!1,this.enabled=!1,this.target,this.locked=!1,this.onMouseMove=o,this.onMouseDown=o,this.onMouseUp=o,this.onMouseDownWindow=o,this.onMouseUpWindow=o,this.onMouseOver=o,this.onMouseOut=o,this.onMouseWheel=o,this.pointerLockChange=o,this.isTop=!0,t.events.once(r.MANAGER_BOOT,this.boot,this)},boot:function(){var t=this.manager.config;this.enabled=t.inputMouse,this.target=t.inputMouseEventTarget,this.passive=t.inputMousePassive,this.preventDefaultDown=t.inputMousePreventDefaultDown,this.preventDefaultUp=t.inputMousePreventDefaultUp,this.preventDefaultMove=t.inputMousePreventDefaultMove,this.preventDefaultWheel=t.inputMousePreventDefaultWheel,this.target?"string"==typeof this.target&&(this.target=document.getElementById(this.target)):this.target=this.manager.game.canvas,t.disableContextMenu&&this.disableContextMenu(),this.enabled&&this.target&&this.startListeners()},disableContextMenu:function(){return this.target.addEventListener("contextmenu",(function(t){return t.preventDefault(),!1})),this},requestPointerLock:function(){if(n.pointerLock){var t=this.target;t.requestPointerLock=t.requestPointerLock||t.mozRequestPointerLock||t.webkitRequestPointerLock,t.requestPointerLock()}},releasePointerLock:function(){n.pointerLock&&(document.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock,document.exitPointerLock())},startListeners:function(){var t=this.target;if(t){var e=this,i=this.manager,s=i.canvas,r=window&&window.focus&&i.game.config.autoFocus;this.onMouseMove=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&(i.onMouseMove(t),e.preventDefaultMove&&t.preventDefault())},this.onMouseDown=function(t){r&&window.focus(),!t.defaultPrevented&&e.enabled&&i&&i.enabled&&(i.onMouseDown(t),e.preventDefaultDown&&t.target===s&&t.preventDefault())},this.onMouseDownWindow=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&t.target!==s&&i.onMouseDown(t)},this.onMouseUp=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&(i.onMouseUp(t),e.preventDefaultUp&&t.target===s&&t.preventDefault())},this.onMouseUpWindow=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&t.target!==s&&i.onMouseUp(t)},this.onMouseOver=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&i.setCanvasOver(t)},this.onMouseOut=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&i.setCanvasOut(t)},this.onMouseWheel=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&i.onMouseWheel(t),e.preventDefaultWheel&&t.target===s&&t.preventDefault()};var o={passive:!0};if(t.addEventListener("mousemove",this.onMouseMove),t.addEventListener("mousedown",this.onMouseDown),t.addEventListener("mouseup",this.onMouseUp),t.addEventListener("mouseover",this.onMouseOver,o),t.addEventListener("mouseout",this.onMouseOut,o),this.preventDefaultWheel?t.addEventListener("wheel",this.onMouseWheel,{passive:!1}):t.addEventListener("wheel",this.onMouseWheel,o),window&&i.game.config.inputWindowEvents)try{window.top.addEventListener("mousedown",this.onMouseDownWindow,o),window.top.addEventListener("mouseup",this.onMouseUpWindow,o)}catch(t){window.addEventListener("mousedown",this.onMouseDownWindow,o),window.addEventListener("mouseup",this.onMouseUpWindow,o),this.isTop=!1}n.pointerLock&&(this.pointerLockChange=function(t){var s=e.target;e.locked=document.pointerLockElement===s||document.mozPointerLockElement===s||document.webkitPointerLockElement===s,i.onPointerLockChange(t)},document.addEventListener("pointerlockchange",this.pointerLockChange,!0),document.addEventListener("mozpointerlockchange",this.pointerLockChange,!0),document.addEventListener("webkitpointerlockchange",this.pointerLockChange,!0)),this.enabled=!0}},stopListeners:function(){var t=this.target;t.removeEventListener("mousemove",this.onMouseMove),t.removeEventListener("mousedown",this.onMouseDown),t.removeEventListener("mouseup",this.onMouseUp),t.removeEventListener("mouseover",this.onMouseOver),t.removeEventListener("mouseout",this.onMouseOut),window&&((t=this.isTop?window.top:window).removeEventListener("mousedown",this.onMouseDownWindow),t.removeEventListener("mouseup",this.onMouseUpWindow)),n.pointerLock&&(document.removeEventListener("pointerlockchange",this.pointerLockChange,!0),document.removeEventListener("mozpointerlockchange",this.pointerLockChange,!0),document.removeEventListener("webkitpointerlockchange",this.pointerLockChange,!0))},destroy:function(){this.stopListeners(),this.target=null,this.enabled=!1,this.manager=null}});t.exports=a},11343:(t,e,i)=>{t.exports={MouseManager:i(7905)}},37579:(t,e,i)=>{var s=i(56694),n=i(33963),r=i(72283),o=new s({initialize:function(t){this.manager=t,this.capture=!0,this.enabled=!1,this.target,this.onTouchStart=r,this.onTouchStartWindow=r,this.onTouchMove=r,this.onTouchEnd=r,this.onTouchEndWindow=r,this.onTouchCancel=r,this.onTouchCancelWindow=r,this.isTop=!0,t.events.once(n.MANAGER_BOOT,this.boot,this)},boot:function(){var t=this.manager.config;this.enabled=t.inputTouch,this.target=t.inputTouchEventTarget,this.capture=t.inputTouchCapture,this.target?"string"==typeof this.target&&(this.target=document.getElementById(this.target)):this.target=this.manager.game.canvas,t.disableContextMenu&&this.disableContextMenu(),this.enabled&&this.target&&this.startListeners()},disableContextMenu:function(){return this.target.addEventListener("contextmenu",(function(t){return t.preventDefault(),!1})),this},startListeners:function(){var t=this.target;if(t){var e=this,i=this.manager,s=i.canvas,n=window&&window.focus&&i.game.config.autoFocus;this.onTouchMove=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&(i.onTouchMove(t),e.capture&&t.cancelable&&t.preventDefault())},this.onTouchStart=function(t){n&&window.focus(),!t.defaultPrevented&&e.enabled&&i&&i.enabled&&(i.onTouchStart(t),e.capture&&t.cancelable&&t.target===s&&t.preventDefault())},this.onTouchStartWindow=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&t.target!==s&&i.onTouchStart(t)},this.onTouchEnd=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&(i.onTouchEnd(t),e.capture&&t.cancelable&&t.target===s&&t.preventDefault())},this.onTouchEndWindow=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&t.target!==s&&i.onTouchEnd(t)},this.onTouchCancel=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&(i.onTouchCancel(t),e.capture&&t.preventDefault())},this.onTouchCancelWindow=function(t){!t.defaultPrevented&&e.enabled&&i&&i.enabled&&i.onTouchCancel(t)};var r=this.capture,o={passive:!0},a={passive:!1};if(t.addEventListener("touchstart",this.onTouchStart,r?a:o),t.addEventListener("touchmove",this.onTouchMove,r?a:o),t.addEventListener("touchend",this.onTouchEnd,r?a:o),t.addEventListener("touchcancel",this.onTouchCancel,r?a:o),window&&i.game.config.inputWindowEvents)try{window.top.addEventListener("touchstart",this.onTouchStartWindow,a),window.top.addEventListener("touchend",this.onTouchEndWindow,a),window.top.addEventListener("touchcancel",this.onTouchCancelWindow,a)}catch(t){window.addEventListener("touchstart",this.onTouchStartWindow,a),window.addEventListener("touchend",this.onTouchEndWindow,a),window.addEventListener("touchcancel",this.onTouchCancelWindow,a),this.isTop=!1}this.enabled=!0}},stopListeners:function(){var t=this.target;t.removeEventListener("touchstart",this.onTouchStart),t.removeEventListener("touchmove",this.onTouchMove),t.removeEventListener("touchend",this.onTouchEnd),t.removeEventListener("touchcancel",this.onTouchCancel),window&&((t=this.isTop?window.top:window).removeEventListener("touchstart",this.onTouchStartWindow),t.removeEventListener("touchend",this.onTouchEndWindow),t.removeEventListener("touchcancel",this.onTouchCancelWindow))},destroy:function(){this.stopListeners(),this.target=null,this.enabled=!1,this.manager=null}});t.exports=o},77423:(t,e,i)=>{t.exports={TouchManager:i(37579)}},98035:(t,e,i)=>{var s=i(56694),n=i(12117),r=i(683),o=i(72632),a=i(30750),h=i(43531),l=i(88490),u=i(33868),c=new s({initialize:function(t,e){if(this.loader=t,this.cache=o(e,"cache",!1),this.type=o(e,"type",!1),!this.type)throw new Error("Invalid File type: "+this.type);this.key=o(e,"key",!1);var i=this.key;if(t.prefix&&""!==t.prefix&&(this.key=t.prefix+i),!this.key)throw new Error("Invalid File key: "+this.key);var s=o(e,"url");void 0===s?s=t.path+i+"."+o(e,"extension",""):"string"!=typeof s||s.match(/^(?:blob:|data:|capacitor:\/\/|http:\/\/|https:\/\/|\/\/)/)||(s=t.path+s),this.url=s,this.src="",this.xhrSettings=u(o(e,"responseType",void 0)),o(e,"xhrSettings",!1)&&(this.xhrSettings=h(this.xhrSettings,o(e,"xhrSettings",{}))),this.xhrLoader=null,this.state="function"==typeof this.url?n.FILE_POPULATED:n.FILE_PENDING,this.bytesTotal=0,this.bytesLoaded=-1,this.percentComplete=-1,this.crossOrigin=void 0,this.data=void 0,this.config=o(e,"config",{}),this.multiFile,this.linkFile},setLink:function(t){this.linkFile=t,t.linkFile=this},resetXHR:function(){this.xhrLoader&&(this.xhrLoader.onload=void 0,this.xhrLoader.onerror=void 0,this.xhrLoader.onprogress=void 0)},load:function(){this.state===n.FILE_POPULATED?this.loader.nextFile(this,!0):(this.state=n.FILE_LOADING,this.src=a(this,this.loader.baseURL),0===this.src.indexOf("data:")?console.warn("Local data URIs are not supported: "+this.key):this.xhrLoader=l(this,this.loader.xhr))},onLoad:function(t,e){var i=t.responseURL&&this.loader.localSchemes.some((function(e){return 0===t.responseURL.indexOf(e)}))&&0===e.target.status,s=!(e.target&&200!==e.target.status)||i;4===t.readyState&&t.status>=400&&t.status<=599&&(s=!1),this.state=n.FILE_LOADED,this.resetXHR(),this.loader.nextFile(this,s)},onError:function(){this.resetXHR(),this.loader.nextFile(this,!1)},onProgress:function(t){t.lengthComputable&&(this.bytesLoaded=t.loaded,this.bytesTotal=t.total,this.percentComplete=Math.min(this.bytesLoaded/this.bytesTotal,1),this.loader.emit(r.FILE_PROGRESS,this,this.percentComplete))},onProcess:function(){this.state=n.FILE_PROCESSING,this.onProcessComplete()},onProcessComplete:function(){this.state=n.FILE_COMPLETE,this.multiFile&&this.multiFile.onFileComplete(this),this.loader.fileProcessComplete(this)},onProcessError:function(){console.error('Failed to process file: %s "%s"',this.type,this.key),this.state=n.FILE_ERRORED,this.multiFile&&this.multiFile.onFileFailed(this),this.loader.fileProcessComplete(this)},hasCacheConflict:function(){return this.cache&&this.cache.exists(this.key)},addToCache:function(){this.cache&&this.data&&this.cache.add(this.key,this.data)},pendingDestroy:function(t){if(this.state!==n.FILE_PENDING_DESTROY){void 0===t&&(t=this.data);var e=this.key,i=this.type;this.loader.emit(r.FILE_COMPLETE,e,i,t),this.loader.emit(r.FILE_KEY_COMPLETE+i+"-"+e,e,i,t),this.loader.flagForRemoval(this),this.state=n.FILE_PENDING_DESTROY}},destroy:function(){this.loader=null,this.cache=null,this.xhrSettings=null,this.multiFile=null,this.linkFile=null,this.data=null}});c.createObjectURL=function(t,e,i){if("function"==typeof URL)t.src=URL.createObjectURL(e);else{var s=new FileReader;s.onload=function(){t.removeAttribute("crossOrigin"),t.src="data:"+(e.type||i)+";base64,"+s.result.split(",")[1]},s.onerror=t.onerror,s.readAsDataURL(e)}},c.revokeObjectURL=function(t){"function"==typeof URL&&URL.revokeObjectURL(t.src)},t.exports=c},76846:t=>{var e={},i={install:function(t){for(var i in e)t[i]=e[i]},register:function(t,i){e[t]=i},destroy:function(){e={}}};t.exports=i},30750:t=>{t.exports=function(t,e){return!!t.url&&(t.url.match(/^(?:blob:|data:|capacitor:\/\/|http:\/\/|https:\/\/|\/\/)/)?t.url:e+t.url)}},67285:(t,e,i)=>{var s=i(56694),n=i(12117),r=i(58403),o=i(6659),a=i(683),h=i(76846),l=i(72632),u=i(10850),c=i(91963),d=i(7599),f=i(33868),p=new s({Extends:o,initialize:function(t){o.call(this);var e=t.sys.game.config,i=t.sys.settings.loader;this.scene=t,this.systems=t.sys,this.cacheManager=t.sys.cache,this.textureManager=t.sys.textures,this.sceneManager=t.sys.game.scene,h.install(this),this.prefix="",this.path="",this.baseURL="",this.setBaseURL(l(i,"baseURL",e.loaderBaseURL)),this.setPath(l(i,"path",e.loaderPath)),this.setPrefix(l(i,"prefix",e.loaderPrefix)),this.maxParallelDownloads=l(i,"maxParallelDownloads",e.loaderMaxParallelDownloads),this.xhr=f(l(i,"responseType",e.loaderResponseType),l(i,"async",e.loaderAsync),l(i,"user",e.loaderUser),l(i,"password",e.loaderPassword),l(i,"timeout",e.loaderTimeout),l(i,"withCredentials",e.loaderWithCredentials)),this.crossOrigin=l(i,"crossOrigin",e.loaderCrossOrigin),this.imageLoadType=l(i,"imageLoadType",e.loaderImageLoadType),this.localSchemes=l(i,"localScheme",e.loaderLocalScheme),this.totalToLoad=0,this.progress=0,this.list=new r,this.inflight=new r,this.queue=new r,this._deleteQueue=new r,this.totalFailed=0,this.totalComplete=0,this.state=n.LOADER_IDLE,this.multiKeyIndex=0,t.sys.events.once(d.BOOT,this.boot,this),t.sys.events.on(d.START,this.pluginStart,this)},boot:function(){this.systems.events.once(d.DESTROY,this.destroy,this)},pluginStart:function(){this.systems.events.once(d.SHUTDOWN,this.shutdown,this)},setBaseURL:function(t){return void 0===t&&(t=""),""!==t&&"/"!==t.substr(-1)&&(t=t.concat("/")),this.baseURL=t,this},setPath:function(t){return void 0===t&&(t=""),""!==t&&"/"!==t.substr(-1)&&(t=t.concat("/")),this.path=t,this},setPrefix:function(t){return void 0===t&&(t=""),this.prefix=t,this},setCORS:function(t){return this.crossOrigin=t,this},addFile:function(t){Array.isArray(t)||(t=[t]);for(var e=0;e0},isLoading:function(){return this.state===n.LOADER_LOADING||this.state===n.LOADER_PROCESSING},isReady:function(){return this.state===n.LOADER_IDLE||this.state===n.LOADER_COMPLETE},start:function(){this.isReady()&&(this.progress=0,this.totalFailed=0,this.totalComplete=0,this.totalToLoad=this.list.size,this.emit(a.START,this),0===this.list.size?this.loadComplete():(this.state=n.LOADER_LOADING,this.inflight.clear(),this.queue.clear(),this.updateProgress(),this.checkLoadQueue(),this.systems.events.on(d.UPDATE,this.update,this)))},updateProgress:function(){this.progress=1-(this.list.size+this.inflight.size)/this.totalToLoad,this.emit(a.PROGRESS,this.progress)},update:function(){this.state===n.LOADER_LOADING&&this.list.size>0&&this.inflight.size{var s=i(98611),n=i(33868);t.exports=function(t,e){var i=void 0===t?n():s({},t);if(e)for(var r in e)void 0!==e[r]&&(i[r]=e[r]);return i}},45176:(t,e,i)=>{var s=i(56694),n=i(12117),r=i(683),o=new s({initialize:function(t,e,i,s){var r=[];s.forEach((function(t){t&&r.push(t)})),this.loader=t,this.type=e,this.key=i,this.multiKeyIndex=t.multiKeyIndex++,this.files=r,this.state=n.FILE_PENDING,this.complete=!1,this.pending=r.length,this.failed=0,this.config={},this.baseURL=t.baseURL,this.path=t.path,this.prefix=t.prefix;for(var o=0;o{var s=i(43531);t.exports=function(t,e){var i=s(e,t.xhrSettings),n=new XMLHttpRequest;if(n.open("GET",t.src,i.async,i.user,i.password),n.responseType=t.xhrSettings.responseType,n.timeout=i.timeout,i.headers)for(var r in i.headers)n.setRequestHeader(r,i.headers[r]);return i.header&&i.headerValue&&n.setRequestHeader(i.header,i.headerValue),i.requestedWith&&n.setRequestHeader("X-Requested-With",i.requestedWith),i.overrideMimeType&&n.overrideMimeType(i.overrideMimeType),i.withCredentials&&(n.withCredentials=!0),n.onload=t.onLoad.bind(t,n),n.onerror=t.onError.bind(t,n),n.onprogress=t.onProgress.bind(t),n.send(),n}},33868:t=>{t.exports=function(t,e,i,s,n,r){return void 0===t&&(t=""),void 0===e&&(e=!0),void 0===i&&(i=""),void 0===s&&(s=""),void 0===n&&(n=0),void 0===r&&(r=!1),{responseType:t,async:e,user:i,password:s,timeout:n,headers:void 0,header:void 0,headerValue:void 0,requestedWith:!1,overrideMimeType:void 0,withCredentials:r}}},12117:t=>{t.exports={LOADER_IDLE:0,LOADER_LOADING:1,LOADER_PROCESSING:2,LOADER_COMPLETE:3,LOADER_SHUTDOWN:4,LOADER_DESTROYED:5,FILE_PENDING:10,FILE_LOADING:11,FILE_LOADED:12,FILE_FAILED:13,FILE_PROCESSING:14,FILE_ERRORED:16,FILE_COMPLETE:17,FILE_DESTROYED:18,FILE_POPULATED:19,FILE_PENDING_DESTROY:20}},7398:t=>{t.exports="addfile"},52187:t=>{t.exports="complete"},36627:t=>{t.exports="filecomplete"},81925:t=>{t.exports="filecomplete-"},29774:t=>{t.exports="loaderror"},20943:t=>{t.exports="load"},74693:t=>{t.exports="fileprogress"},71176:t=>{t.exports="postprocess"},88984:t=>{t.exports="progress"},72753:t=>{t.exports="start"},683:(t,e,i)=>{t.exports={ADD:i(7398),COMPLETE:i(52187),FILE_COMPLETE:i(36627),FILE_KEY_COMPLETE:i(81925),FILE_LOAD_ERROR:i(29774),FILE_LOAD:i(20943),FILE_PROGRESS:i(74693),POST_PROCESS:i(71176),PROGRESS:i(88984),START:i(72753)}},46468:(t,e,i)=>{var s=i(56694),n=i(76846),r=i(70806),o=i(683),a=new s({Extends:r,initialize:function(t,e,i,s,n){r.call(this,t,e,i,s,n),this.type="animationJSON"},onProcess:function(){this.loader.once(o.POST_PROCESS,this.onLoadComplete,this),r.prototype.onProcess.call(this)},onLoadComplete:function(){this.loader.systems.anims.fromJSON(this.data)}});n.register("animation",(function(t,e,i,s){if(Array.isArray(t))for(var n=0;n{var s=i(56694),n=i(76846),r=i(72632),o=i(42927),a=i(42911),h=i(70806),l=i(45176),u=new s({Extends:l,initialize:function(t,e,i,s,n,u){var c,d;if(a(e)){var f=e;e=r(f,"key"),c=new o(t,{key:e,url:r(f,"textureURL"),extension:r(f,"textureExtension","png"),normalMap:r(f,"normalMap"),xhrSettings:r(f,"textureXhrSettings")}),d=new h(t,{key:e,url:r(f,"atlasURL"),extension:r(f,"atlasExtension","json"),xhrSettings:r(f,"atlasXhrSettings")})}else c=new o(t,e,i,n),d=new h(t,e,s,u);c.linkFile?l.call(this,t,"atlasjson",e,[c,d,c.linkFile]):l.call(this,t,"atlasjson",e,[c,d])},addToCache:function(){if(this.isReadyToProcess()){var t=this.files[0],e=this.files[1],i=this.files[2]?this.files[2].data:null;this.loader.textureManager.addAtlas(t.key,t.data,e.data,i),e.addToCache(),this.complete=!0}}});n.register("aseprite",(function(t,e,i,s,n){var r;if(Array.isArray(t))for(var o=0;o{var s=i(56694),n=i(76846),r=i(72632),o=i(42927),a=i(42911),h=i(70806),l=i(45176),u=new s({Extends:l,initialize:function(t,e,i,s,n,u){var c,d;if(a(e)){var f=e;e=r(f,"key"),c=new o(t,{key:e,url:r(f,"textureURL"),extension:r(f,"textureExtension","png"),normalMap:r(f,"normalMap"),xhrSettings:r(f,"textureXhrSettings")}),d=new h(t,{key:e,url:r(f,"atlasURL"),extension:r(f,"atlasExtension","json"),xhrSettings:r(f,"atlasXhrSettings")})}else c=new o(t,e,i,n),d=new h(t,e,s,u);c.linkFile?l.call(this,t,"atlasjson",e,[c,d,c.linkFile]):l.call(this,t,"atlasjson",e,[c,d])},addToCache:function(){if(this.isReadyToProcess()){var t=this.files[0],e=this.files[1],i=this.files[2]?this.files[2].data:null;this.loader.textureManager.addAtlas(t.key,t.data,e.data,i),this.complete=!0}}});n.register("atlas",(function(t,e,i,s,n){var r;if(Array.isArray(t))for(var o=0;o{var s=i(56694),n=i(76846),r=i(72632),o=i(42927),a=i(42911),h=i(45176),l=i(15297),u=new s({Extends:h,initialize:function(t,e,i,s,n,u){var c,d;if(a(e)){var f=e;e=r(f,"key"),c=new o(t,{key:e,url:r(f,"textureURL"),extension:r(f,"textureExtension","png"),normalMap:r(f,"normalMap"),xhrSettings:r(f,"textureXhrSettings")}),d=new l(t,{key:e,url:r(f,"atlasURL"),extension:r(f,"atlasExtension","xml"),xhrSettings:r(f,"atlasXhrSettings")})}else c=new o(t,e,i,n),d=new l(t,e,s,u);c.linkFile?h.call(this,t,"atlasxml",e,[c,d,c.linkFile]):h.call(this,t,"atlasxml",e,[c,d])},addToCache:function(){if(this.isReadyToProcess()){var t=this.files[0],e=this.files[1],i=this.files[2]?this.files[2].data:null;this.loader.textureManager.addAtlasXML(t.key,t.data,e.data,i),this.complete=!0}}});n.register("atlasXML",(function(t,e,i,s,n){var r;if(Array.isArray(t))for(var o=0;o{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(30929),l=i(42911),u=new s({Extends:r,initialize:function(t,e,i,s,n){if(l(e)){var o=e;e=a(o,"key"),s=a(o,"xhrSettings"),n=a(o,"context",n)}var h={type:"audio",cache:t.cacheManager.audio,extension:i.type,responseType:"arraybuffer",key:e,url:i.url,xhrSettings:s,config:{context:n}};r.call(this,t,h)},onProcess:function(){this.state=n.FILE_PROCESSING;var t=this;this.config.context.decodeAudioData(this.xhrLoader.response,(function(e){t.data=e,t.onProcessComplete()}),(function(e){console.error("Error decoding audio: "+t.key+" - ",e?e.message:null),t.onProcessError()})),this.config.context=null}});u.create=function(t,e,i,s,n){var r=t.systems.game,o=r.config.audio,c=r.device.audio;l(e)&&(i=a(e,"url",[]),s=a(e,"config",{}));var d=u.getAudioURL(r,i);return d?c.webAudio&&!o.disableWebAudio?new u(t,e,d,n,r.sound.context):new h(t,e,d,s):(console.warn('No audio URLs for "%s" matched this device',e),null)},u.getAudioURL=function(t,e){Array.isArray(e)||(e=[e]);for(var i=0;i{var s=i(67448),n=i(56694),r=i(76846),o=i(72632),a=i(42911),h=i(70806),l=i(45176),u=new n({Extends:l,initialize:function(t,e,i,n,r,u,c){if(a(e)){var d=e;e=o(d,"key"),i=o(d,"jsonURL"),n=o(d,"audioURL"),r=o(d,"audioConfig"),u=o(d,"audioXhrSettings"),c=o(d,"jsonXhrSettings")}var f;if(n){var p=s.create(t,e,n,r,u);p&&(f=new h(t,e,i,c),l.call(this,t,"audiosprite",e,[p,f]),this.config.resourceLoad=!1)}else f=new h(t,e,i,c),l.call(this,t,"audiosprite",e,[f]),this.config.resourceLoad=!0,this.config.audioConfig=r,this.config.audioXhrSettings=u},onFileComplete:function(t){if(-1!==this.files.indexOf(t)&&(this.pending--,this.config.resourceLoad&&"json"===t.type&&t.data.hasOwnProperty("resources"))){var e=t.data.resources,i=o(this.config,"audioConfig"),n=o(this.config,"audioXhrSettings"),r=s.create(this.loader,t.key,e,i,n);r&&(this.addToMultiFile(r),this.loader.addFile(r))}},addToCache:function(){if(this.isReadyToProcess()){var t=this.files[0],e=this.files[1];t.addToCache(),e.addToCache(),this.complete=!0}}});r.register("audioSprite",(function(t,e,i,s,n,r){var o,a=this.systems.game,h=a.config.audio,l=a.device.audio;if(h&&h.noAudio||!l.webAudio&&!l.audioData)return this;if(Array.isArray(t))for(var c=0;c{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s,n){var o="bin";if(h(e)){var l=e;e=a(l,"key"),i=a(l,"url"),s=a(l,"xhrSettings"),o=a(l,"extension",o),n=a(l,"dataType",n)}var u={type:"binary",cache:t.cacheManager.binary,extension:o,responseType:"arraybuffer",key:e,url:i,xhrSettings:s,config:{dataType:n}};r.call(this,t,u)},onProcess:function(){this.state=n.FILE_PROCESSING;var t=this.config.dataType;this.data=t?new t(this.xhrLoader.response):this.xhrLoader.response,this.onProcessComplete()}});o.register("binary",(function(t,e,i,s){if(Array.isArray(t))for(var n=0;n{var s=i(56694),n=i(76846),r=i(72632),o=i(42927),a=i(42911),h=i(45176),l=i(31476),u=i(15297),c=new s({Extends:h,initialize:function(t,e,i,s,n,l){var c,d;if(a(e)){var f=e;e=r(f,"key"),c=new o(t,{key:e,url:r(f,"textureURL"),extension:r(f,"textureExtension","png"),normalMap:r(f,"normalMap"),xhrSettings:r(f,"textureXhrSettings")}),d=new u(t,{key:e,url:r(f,"fontDataURL"),extension:r(f,"fontDataExtension","xml"),xhrSettings:r(f,"fontDataXhrSettings")})}else c=new o(t,e,i,n),d=new u(t,e,s,l);c.linkFile?h.call(this,t,"bitmapfont",e,[c,d,c.linkFile]):h.call(this,t,"bitmapfont",e,[c,d])},addToCache:function(){if(this.isReadyToProcess()){var t=this.files[0],e=this.files[1];t.addToCache();var i=t.cache.get(t.key),s=l(e.data,t.cache.getFrame(t.key),0,0,i);this.loader.cacheManager.bitmapFont.add(t.key,{data:s,texture:t.key,frame:null}),this.complete=!0}}});n.register("bitmapFont",(function(t,e,i,s,n){var r;if(Array.isArray(t))for(var o=0;o{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s){var n="css";if(h(e)){var o=e;e=a(o,"key"),i=a(o,"url"),s=a(o,"xhrSettings"),n=a(o,"extension",n)}var l={type:"script",cache:!1,extension:n,responseType:"text",key:e,url:i,xhrSettings:s};r.call(this,t,l)},onProcess:function(){this.state=n.FILE_PROCESSING,this.data=document.createElement("style"),this.data.defer=!1,this.data.innerHTML=this.xhrLoader.responseText,document.head.appendChild(this.data),this.onProcessComplete()}});o.register("css",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{var s=i(73152),n=i(40612),r=i(56694),o=i(76846),a=i(72632),h=i(42927),l=i(42911),u=i(70806),c=i(67409),d=i(30657),f=i(80802),p=i(45176),v=i(24904),g=new r({Extends:p,initialize:function(t,e,i,s){if(i.multiAtlasURL){var r=new u(t,{key:e,url:i.multiAtlasURL,xhrSettings:s,config:i});p.call(this,t,"texture",e,[r])}else{var o=i.textureURL.substr(i.textureURL.length-3);i.type||(i.type="ktx"===o.toLowerCase()?"KTX":"PVR");var a=new n(t,{key:e,url:i.textureURL,extension:o,xhrSettings:s,config:i});if(i.atlasURL){var h=new u(t,{key:e,url:i.atlasURL,xhrSettings:s,config:i});p.call(this,t,"texture",e,[a,h])}else p.call(this,t,"texture",e,[a])}this.config=i},onFileComplete:function(t){if(-1!==this.files.indexOf(t)){if(this.pending--,!this.config.multiAtlasURL)return;if("json"===t.type&&t.data.hasOwnProperty("textures")){var e=t.data.textures,i=this.config,s=this.loader,r=s.baseURL,o=s.path,h=s.prefix,l=a(i,"multiBaseURL",this.baseURL),u=a(i,"multiPath",this.path),c=a(i,"prefix",this.prefix),d=a(i,"textureXhrSettings");l&&s.setBaseURL(l),u&&s.setPath(u),c&&s.setPrefix(c);for(var f=0;f{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=i(31053),u=new s({Extends:r,initialize:function(t,e,i,s,n){var o="glsl";if(h(e)){var l=e;e=a(l,"key"),i=a(l,"url"),s=a(l,"shaderType","fragment"),n=a(l,"xhrSettings"),o=a(l,"extension",o)}else void 0===s&&(s="fragment");var u={type:"glsl",cache:t.cacheManager.shader,extension:o,responseType:"text",key:e,url:i,config:{shaderType:s},xhrSettings:n};r.call(this,t,u)},onProcess:function(){this.state=n.FILE_PROCESSING,this.data=this.xhrLoader.responseText,this.onProcessComplete()},addToCache:function(){var t=this.data.split("\n"),e=this.extractBlock(t,0);if(e)for(;e;){var i=this.getShaderName(e.header),s=this.getShaderType(e.header),n=this.getShaderUniforms(e.header),r=e.shader;if(this.cache.has(i)){var o=this.cache.get(i);"fragment"===s?o.fragmentSrc=r:o.vertexSrc=r,o.uniforms||(o.uniforms=n)}else"fragment"===s?this.cache.add(i,new l(i,r,"",n)):this.cache.add(i,new l(i,"",r,n));e=this.extractBlock(t,e.offset)}else"fragment"===this.config.shaderType?this.cache.add(this.key,new l(this.key,this.data)):this.cache.add(this.key,new l(this.key,"",this.data))},getShaderName:function(t){for(var e=0;e{var s=i(56694),n=i(683),r=i(98035),o=i(72632),a=i(30750),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s){if(h(e)){var n=e;e=o(n,"key"),s=o(n,"config",s)}var a={type:"audio",cache:t.cacheManager.audio,extension:i.type,key:e,url:i.url,config:s};r.call(this,t,a),this.locked="ontouchstart"in window,this.loaded=!1,this.filesLoaded=0,this.filesTotal=0},onLoad:function(){this.loaded||(this.loaded=!0,this.loader.nextFile(this,!0))},onError:function(){for(var t=0;t{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s){var n="html";if(h(e)){var o=e;e=a(o,"key"),i=a(o,"url"),s=a(o,"xhrSettings"),n=a(o,"extension",n)}var l={type:"text",cache:t.cacheManager.html,extension:n,responseType:"text",key:e,url:i,xhrSettings:s};r.call(this,t,l)},onProcess:function(){this.state=n.FILE_PROCESSING,this.data=this.xhrLoader.responseText,this.onProcessComplete()}});o.register("html",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s,n,o){void 0===s&&(s=512),void 0===n&&(n=512);var l="html";if(h(e)){var u=e;e=a(u,"key"),i=a(u,"url"),o=a(u,"xhrSettings"),l=a(u,"extension",l),s=a(u,"width",s),n=a(u,"height",n)}var c={type:"html",cache:t.textureManager,extension:l,responseType:"text",key:e,url:i,xhrSettings:o,config:{width:s,height:n}};r.call(this,t,c)},onProcess:function(){this.state=n.FILE_PROCESSING;var t=this.config.width,e=this.config.height,i=[];i.push(''),i.push(''),i.push(''),i.push(this.xhrLoader.responseText),i.push(""),i.push(""),i.push("");var s=[i.join("\n")],o=this;try{var a=new window.Blob(s,{type:"image/svg+xml;charset=utf-8"})}catch(t){return o.state=n.FILE_ERRORED,void o.onProcessComplete()}this.data=new Image,this.data.crossOrigin=this.crossOrigin,this.data.onload=function(){r.revokeObjectURL(o.data),o.onProcessComplete()},this.data.onerror=function(){r.revokeObjectURL(o.data),o.onProcessError()},r.createObjectURL(this.data,a,"image/svg+xml")},addToCache:function(){this.cache.addImage(this.key,this.data)}});o.register("htmlTexture",(function(t,e,i,s,n){if(Array.isArray(t))for(var r=0;r{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=i(30750),u=new s({Extends:r,initialize:function t(e,i,s,n,o){var l,u="png";if(h(i)){var c=i;i=a(c,"key"),s=a(c,"url"),l=a(c,"normalMap"),n=a(c,"xhrSettings"),u=a(c,"extension",u),o=a(c,"frameConfig")}Array.isArray(s)&&(l=s[1],s=s[0]);var d={type:"image",cache:e.textureManager,extension:u,responseType:"blob",key:i,url:s,xhrSettings:n,config:o};if(r.call(this,e,d),l){var f=new t(e,this.key,l,n,o);f.type="normalMap",this.setLink(f),e.addFile(f)}this.useImageElementLoad="HTMLImageElement"===e.imageLoadType,this.useImageElementLoad&&(this.load=this.loadImage,this.onProcess=this.onProcessImage)},onProcess:function(){this.state=n.FILE_PROCESSING,this.data=new Image,this.data.crossOrigin=this.crossOrigin;var t=this;this.data.onload=function(){r.revokeObjectURL(t.data),t.onProcessComplete()},this.data.onerror=function(){r.revokeObjectURL(t.data),t.onProcessError()},r.createObjectURL(this.data,this.xhrLoader.response,"image/png")},onProcessImage:function(){var t=this.state;this.state=n.FILE_PROCESSING,t===n.FILE_LOADED?this.onProcessComplete():this.onProcessError()},loadImage:function(){if(this.state=n.FILE_LOADING,this.src=l(this,this.loader.baseURL),0===this.src.indexOf("data:"))console.warn("Local data URIs are not supported: "+this.key);else{this.data=new Image,this.data.crossOrigin=this.crossOrigin;var t=this;this.data.onload=function(){t.state=n.FILE_LOADED,t.loader.nextFile(t,!0)},this.data.onerror=function(){t.loader.nextFile(t,!1)},this.data.src=this.src}},addToCache:function(){var t=this.linkFile;t?t.state>=n.FILE_COMPLETE&&("normalMap"===this.type?this.cache.addImage(this.key,t.data,this.data):this.cache.addImage(this.key,this.data,t.data)):this.cache.addImage(this.key,this.data)}});o.register("image",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(10850),l=i(42911),u=new s({Extends:r,initialize:function(t,e,i,s,o){var u="json";if(l(e)){var c=e;e=a(c,"key"),i=a(c,"url"),s=a(c,"xhrSettings"),u=a(c,"extension",u),o=a(c,"dataKey",o)}var d={type:"json",cache:t.cacheManager.json,extension:u,responseType:"text",key:e,url:i,xhrSettings:s,config:o};r.call(this,t,d),l(i)&&(this.data=o?h(i,o):i,this.state=n.FILE_POPULATED)},onProcess:function(){if(this.state!==n.FILE_POPULATED){this.state=n.FILE_PROCESSING;try{var t=JSON.parse(this.xhrLoader.responseText)}catch(t){throw this.onProcessError(),t}var e=this.config;this.data="string"==typeof e?h(t,e,t):t}this.onProcessComplete()}});o.register("json",(function(t,e,i,s){if(Array.isArray(t))for(var n=0;n{var s=i(56694),n=i(76846),r=i(72632),o=i(42927),a=i(42911),h=i(70806),l=i(45176),u=new s({Extends:l,initialize:function(t,e,i,s,n,o,u){if(a(e)){var c=e;e=r(c,"key"),i=r(c,"url",!1)?r(c,"url"):r(c,"atlasURL"),o=r(c,"xhrSettings"),s=r(c,"path"),n=r(c,"baseURL"),u=r(c,"textureXhrSettings")}var d=new h(t,e,i,o);l.call(this,t,"multiatlas",e,[d]),this.config.path=s,this.config.baseURL=n,this.config.textureXhrSettings=u},onFileComplete:function(t){if(-1!==this.files.indexOf(t)&&(this.pending--,"json"===t.type&&t.data.hasOwnProperty("textures"))){var e=t.data.textures,i=this.config,s=this.loader,n=s.baseURL,a=s.path,h=s.prefix,l=r(i,"baseURL",this.baseURL),u=r(i,"path",this.path),c=r(i,"prefix",this.prefix),d=r(i,"textureXhrSettings");s.setBaseURL(l),s.setPath(u),s.setPrefix(c);for(var f=0;f{var s=i(56694),n=i(76846),r=i(72632),o=i(42911),a=i(45176),h=i(55188),l=new s({Extends:a,initialize:function(t,e,i,s){var n="js",l=[];if(o(e)){var u=e;e=r(u,"key"),i=r(u,"url"),s=r(u,"xhrSettings"),n=r(u,"extension",n)}Array.isArray(i)||(i=[i]);for(var c=0;c{var s=i(56694),n=i(76846),r=i(72632),o=i(42911),a=i(45176),h=i(27291),l=i(76799),u=i(86897),c=new s({Extends:a,initialize:function(t,e,i,s,n,h){var l,c,d=t.cacheManager.obj;if(o(e)){var f=e;e=r(f,"key"),l=new u(t,{key:e,type:"obj",cache:d,url:r(f,"url"),extension:r(f,"extension","obj"),xhrSettings:r(f,"xhrSettings"),config:{flipUV:r(f,"flipUV",n)}}),(s=r(f,"matURL"))&&(c=new u(t,{key:e,type:"mat",cache:d,url:s,extension:r(f,"matExtension","mat"),xhrSettings:r(f,"xhrSettings")}))}else l=new u(t,{key:e,url:i,type:"obj",cache:d,extension:"obj",xhrSettings:h,config:{flipUV:n}}),s&&(c=new u(t,{key:e,url:s,type:"mat",cache:d,extension:"mat",xhrSettings:h}));a.call(this,t,"obj",e,[l,c])},addToCache:function(){if(this.isReadyToProcess()){var t=this.files[0],e=this.files[1],i=h(t.data,t.config.flipUV);e&&(i.materials=l(e.data)),t.cache.add(t.key,i),this.complete=!0}}});n.register("obj",(function(t,e,i,s,n){var r;if(Array.isArray(t))for(var o=0;o{var s=i(56694),n=i(12117),r=i(76846),o=i(70806),a=new s({Extends:o,initialize:function(t,e,i,s,n){o.call(this,t,e,i,s,n),this.type="packfile"},onProcess:function(){if(this.state!==n.FILE_POPULATED&&(this.state=n.FILE_PROCESSING,this.data=JSON.parse(this.xhrLoader.responseText)),this.data.hasOwnProperty("files")&&this.config){var t={};t[this.config]=this.data,this.data=t}this.loader.addPack(this.data,this.config),this.onProcessComplete()}});r.register("pack",(function(t,e,i,s){if(Array.isArray(t))for(var n=0;n{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s,o,l){var u="js";if(h(e)){var c=e;e=a(c,"key"),i=a(c,"url"),l=a(c,"xhrSettings"),u=a(c,"extension",u),s=a(c,"start"),o=a(c,"mapping")}var d={type:"plugin",cache:!1,extension:u,responseType:"text",key:e,url:i,xhrSettings:l,config:{start:s,mapping:o}};r.call(this,t,d),"function"==typeof i&&(this.data=i,this.state=n.FILE_POPULATED)},onProcess:function(){var t=this.loader.systems.plugins,e=this.config,i=a(e,"start",!1),s=a(e,"mapping",null);if(this.state===n.FILE_POPULATED)t.install(this.key,this.data,i,s);else{this.state=n.FILE_PROCESSING,this.data=document.createElement("script"),this.data.language="javascript",this.data.type="text/javascript",this.data.defer=!1,this.data.text=this.xhrLoader.responseText,document.head.appendChild(this.data);var r=t.install(this.key,window[this.key],i,s);(i||s)&&(this.loader.systems[s]=r,this.loader.scene[s]=r)}this.onProcessComplete()}});o.register("plugin",(function(t,e,i,s,n){if(Array.isArray(t))for(var r=0;r{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s,n){var o="svg";if(h(e)){var l=e;e=a(l,"key"),i=a(l,"url"),s=a(l,"svgConfig",{}),n=a(l,"xhrSettings"),o=a(l,"extension",o)}var u={type:"svg",cache:t.textureManager,extension:o,responseType:"text",key:e,url:i,xhrSettings:n,config:{width:a(s,"width"),height:a(s,"height"),scale:a(s,"scale")}};r.call(this,t,u)},onProcess:function(){this.state=n.FILE_PROCESSING;var t=this.xhrLoader.responseText,e=[t],i=this.config.width,s=this.config.height,o=this.config.scale;t:if(i&&s||o){var a=(new DOMParser).parseFromString(t,"text/xml").getElementsByTagName("svg")[0],h=a.hasAttribute("viewBox"),l=parseFloat(a.getAttribute("width")),u=parseFloat(a.getAttribute("height"));if(!h&&l&&u)a.setAttribute("viewBox","0 0 "+l+" "+u);else if(h&&!l&&!u){var c=a.getAttribute("viewBox").split(/\s+|,/);l=c[2],u=c[3]}if(o){if(!l||!u)break t;i=l*o,s=u*o}a.setAttribute("width",i.toString()+"px"),a.setAttribute("height",s.toString()+"px"),e=[(new XMLSerializer).serializeToString(a)]}try{var d=new window.Blob(e,{type:"image/svg+xml;charset=utf-8"})}catch(t){return void this.onProcessError()}this.data=new Image,this.data.crossOrigin=this.crossOrigin;var f=this,p=!1;this.data.onload=function(){p||r.revokeObjectURL(f.data),f.onProcessComplete()},this.data.onerror=function(){p?f.onProcessError():(p=!0,r.revokeObjectURL(f.data),f.data.src="data:image/svg+xml,"+encodeURIComponent(e.join("")))},r.createObjectURL(this.data,d,"image/svg+xml")},addToCache:function(){this.cache.addImage(this.key,this.data)}});o.register("svg",(function(t,e,i,s){if(Array.isArray(t))for(var n=0;n{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s){var n="js";if(h(e)){var o=e;e=a(o,"key"),i=a(o,"url"),s=a(o,"xhrSettings"),n=a(o,"extension",n)}var l={type:"text",extension:n,responseType:"text",key:e,url:i,xhrSettings:s};r.call(this,t,l)},onProcess:function(){this.state=n.FILE_PROCESSING,this.data=this.xhrLoader.responseText,this.onProcessComplete()},addToCache:function(){var t=this.data.concat("(function(){\nreturn new "+this.key+"();\n}).call(this);"),e=eval;this.loader.sceneManager.add(this.key,e(t)),this.complete=!0}});o.register("sceneFile",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s,o,l){var u="js";if(h(e)){var c=e;e=a(c,"key"),i=a(c,"url"),l=a(c,"xhrSettings"),u=a(c,"extension",u),s=a(c,"systemKey"),o=a(c,"sceneKey")}var d={type:"scenePlugin",cache:!1,extension:u,responseType:"text",key:e,url:i,xhrSettings:l,config:{systemKey:s,sceneKey:o}};r.call(this,t,d),"function"==typeof i&&(this.data=i,this.state=n.FILE_POPULATED)},onProcess:function(){var t=this.loader.systems.plugins,e=this.config,i=this.key,s=a(e,"systemKey",i),r=a(e,"sceneKey",i);this.state===n.FILE_POPULATED?t.installScenePlugin(s,this.data,r,this.loader.scene,!0):(this.state=n.FILE_PROCESSING,this.data=document.createElement("script"),this.data.language="javascript",this.data.type="text/javascript",this.data.defer=!1,this.data.text=this.xhrLoader.responseText,document.head.appendChild(this.data),t.installScenePlugin(s,window[this.key],r,this.loader.scene,!0)),this.onProcessComplete()}});o.register("scenePlugin",(function(t,e,i,s,n){if(Array.isArray(t))for(var r=0;r{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s,n){var o="js";if(h(e)){var l=e;e=a(l,"key"),i=a(l,"url"),s=a(l,"type","script"),n=a(l,"xhrSettings"),o=a(l,"extension",o)}else void 0===s&&(s="script");var u={type:s,cache:!1,extension:o,responseType:"text",key:e,url:i,xhrSettings:n};r.call(this,t,u)},onProcess:function(){this.state=n.FILE_PROCESSING,this.data=document.createElement("script"),this.data.language="javascript",this.data.type="text/javascript",this.data.defer=!1,this.data.text=this.xhrLoader.responseText,document.head.appendChild(this.data),this.onProcessComplete()}});o.register("script",(function(t,e,i,s){if(Array.isArray(t))for(var n=0;n{var s=i(56694),n=i(12117),r=i(76846),o=i(42927),a=new s({Extends:o,initialize:function(t,e,i,s,n){o.call(this,t,e,i,n,s),this.type="spritesheet"},addToCache:function(){var t=this.linkFile;t?t.state>=n.FILE_COMPLETE&&("normalMap"===this.type?this.cache.addSpriteSheet(this.key,t.data,this.config,this.data):this.cache.addSpriteSheet(this.key,this.data,this.config,t.data)):this.cache.addSpriteSheet(this.key,this.data,this.config)}});r.register("spritesheet",(function(t,e,i,s){if(Array.isArray(t))for(var n=0;n{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=new s({Extends:r,initialize:function(t,e,i,s){var n="text",o="txt",l=t.cacheManager.text;if(h(e)){var u=e;e=a(u,"key"),i=a(u,"url"),s=a(u,"xhrSettings"),o=a(u,"extension",o),n=a(u,"type",n),l=a(u,"cache",l)}var c={type:n,cache:l,extension:o,responseType:"text",key:e,url:i,xhrSettings:s};r.call(this,t,c)},onProcess:function(){this.state=n.FILE_PROCESSING,this.data=this.xhrLoader.responseText,this.onProcessComplete()}});o.register("text",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=i(93560),u=new s({Extends:r,initialize:function(t,e,i,s){var n="csv";if(h(e)){var o=e;e=a(o,"key"),i=a(o,"url"),s=a(o,"xhrSettings"),n=a(o,"extension",n)}var u={type:"tilemapCSV",cache:t.cacheManager.tilemap,extension:n,responseType:"text",key:e,url:i,xhrSettings:s};r.call(this,t,u),this.tilemapFormat=l.CSV},onProcess:function(){this.state=n.FILE_PROCESSING,this.data=this.xhrLoader.responseText,this.onProcessComplete()},addToCache:function(){var t={format:this.tilemapFormat,data:this.data};this.cache.add(this.key,t)}});o.register("tilemapCSV",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{var s=i(56694),n=i(76846),r=i(70806),o=i(93560),a=new s({Extends:r,initialize:function(t,e,i,s){r.call(this,t,e,i,s),this.type="tilemapJSON",this.cache=t.cacheManager.tilemap},addToCache:function(){var t={format:o.WELTMEISTER,data:this.data};this.cache.add(this.key,t)}});n.register("tilemapImpact",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{var s=i(56694),n=i(76846),r=i(70806),o=i(93560),a=new s({Extends:r,initialize:function(t,e,i,s){r.call(this,t,e,i,s),this.type="tilemapJSON",this.cache=t.cacheManager.tilemap},addToCache:function(){var t={format:o.TILED_JSON,data:this.data};this.cache.add(this.key,t)}});n.register("tilemapTiledJSON",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{var s=i(56694),n=i(76846),r=i(72632),o=i(42927),a=i(42911),h=i(45176),l=i(86897),u=new s({Extends:h,initialize:function(t,e,i,s,n,u){var c,d;if(a(e)){var f=e;e=r(f,"key"),c=new o(t,{key:e,url:r(f,"textureURL"),extension:r(f,"textureExtension","png"),normalMap:r(f,"normalMap"),xhrSettings:r(f,"textureXhrSettings")}),d=new l(t,{key:e,url:r(f,"atlasURL"),extension:r(f,"atlasExtension","txt"),xhrSettings:r(f,"atlasXhrSettings")})}else c=new o(t,e,i,n),d=new l(t,e,s,u);c.linkFile?h.call(this,t,"unityatlas",e,[c,d,c.linkFile]):h.call(this,t,"unityatlas",e,[c,d])},addToCache:function(){if(this.isReadyToProcess()){var t=this.files[0],e=this.files[1],i=this.files[2]?this.files[2].data:null;this.loader.textureManager.addUnityAtlas(t.key,t.data,e.data,i),this.complete=!0}}});n.register("unityAtlas",(function(t,e,i,s,n){var r;if(Array.isArray(t))for(var o=0;o{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(30750),h=i(72632),l=i(42911),u=new s({Extends:r,initialize:function(t,e,i,s){if(void 0===s&&(s=!1),l(e)){var n=e;e=h(n,"key"),i=h(n,"url",[]),s=h(n,"noAudio",!1)}var o=t.systems.game.device.video.getVideoURL(i);o||console.warn("VideoFile: No supported format for "+e);var a={type:"video",cache:t.cacheManager.video,extension:o.type,key:e,url:o.url,config:{noAudio:s}};r.call(this,t,a)},onProcess:function(){this.data={url:this.src,noAudio:this.config.noAudio,crossOrigin:this.crossOrigin},this.onProcessComplete()},load:function(){this.src=a(this,this.loader.baseURL),this.state=n.FILE_LOADED,this.loader.nextFile(this,!0)}});o.register("video",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{var s=i(56694),n=i(12117),r=i(98035),o=i(76846),a=i(72632),h=i(42911),l=i(89200),u=new s({Extends:r,initialize:function(t,e,i,s){var n="xml";if(h(e)){var o=e;e=a(o,"key"),i=a(o,"url"),s=a(o,"xhrSettings"),n=a(o,"extension",n)}var l={type:"xml",cache:t.cacheManager.xml,extension:n,responseType:"text",key:e,url:i,xhrSettings:s};r.call(this,t,l)},onProcess:function(){this.state=n.FILE_PROCESSING,this.data=l(this.xhrLoader.responseText),this.data?this.onProcessComplete():this.onProcessError()}});o.register("xml",(function(t,e,i){if(Array.isArray(t))for(var s=0;s{t.exports={AnimationJSONFile:i(46468),AsepriteFile:i(31648),AtlasJSONFile:i(73152),AtlasXMLFile:i(24616),AudioFile:i(67448),AudioSpriteFile:i(66109),BinaryFile:i(40612),BitmapFontFile:i(54565),CompressedTextureFile:i(47375),CSSFile:i(99898),GLSLFile:i(46568),HTML5AudioFile:i(30929),HTMLFile:i(77459),HTMLTextureFile:i(9755),ImageFile:i(42927),JSONFile:i(70806),MultiAtlasFile:i(80802),MultiScriptFile:i(39034),OBJFile:i(85527),PackFile:i(3616),PluginFile:i(12217),SceneFile:i(95171),ScenePluginFile:i(82458),ScriptFile:i(55188),SpriteSheetFile:i(33536),SVGFile:i(4474),TextFile:i(86897),TilemapCSVFile:i(58673),TilemapImpactFile:i(98896),TilemapJSONFile:i(50563),UnityAtlasFile:i(82857),VideoFile:i(22833),XMLFile:i(15297)}},95695:(t,e,i)=>{var s=i(12117),n=i(98611),r={Events:i(683),FileTypes:i(34034),File:i(98035),FileTypesManager:i(76846),GetURL:i(30750),LoaderPlugin:i(67285),MergeXHRSettings:i(43531),MultiFile:i(45176),XHRLoader:i(88490),XHRSettings:i(33868)};r=n(!1,r,s),t.exports=r},26042:t=>{t.exports=function(t){for(var e=0,i=0;i{var s=i(8034);t.exports=function(t,e){return s(t)/s(e)/s(t-e)}},17489:t=>{t.exports=function(t,e){return Math.floor(Math.random()*(e-t+1)+t)}},14976:t=>{t.exports=function(t,e,i,s,n){var r=.5*(s-e),o=.5*(n-i),a=t*t;return(2*i-2*s+r+o)*(t*a)+(-3*i+3*s-2*r-o)*a+r*t+i}},89129:t=>{t.exports=function(t,e,i){void 0===e&&(e=0),void 0===i&&(i=10);var s=Math.pow(i,-e);return Math.ceil(t*s)/s}},82897:t=>{t.exports=function(t,e,i){return Math.max(e,Math.min(i,t))}},75606:(t,e,i)=>{var s=i(83392);t.exports=function(t){return t*s.DEG_TO_RAD}},767:t=>{t.exports=function(t,e){return Math.abs(t-e)}},9849:(t,e,i)=>{var s=i(82897),n=i(56694),r=i(16650),o=i(72283),a=new r,h=new n({initialize:function t(e,i,s,n){void 0===e&&(e=0),void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=t.DefaultOrder),this._x=e,this._y=i,this._z=s,this._order=n,this.onChangeCallback=o},x:{get:function(){return this._x},set:function(t){this._x=t,this.onChangeCallback(this)}},y:{get:function(){return this._y},set:function(t){this._y=t,this.onChangeCallback(this)}},z:{get:function(){return this._z},set:function(t){this._z=t,this.onChangeCallback(this)}},order:{get:function(){return this._order},set:function(t){this._order=t,this.onChangeCallback(this)}},set:function(t,e,i,s){return void 0===s&&(s=this._order),this._x=t,this._y=e,this._z=i,this._order=s,this.onChangeCallback(this),this},copy:function(t){return this.set(t.x,t.y,t.z,t.order)},setFromQuaternion:function(t,e,i){return void 0===e&&(e=this._order),void 0===i&&(i=!1),a.fromQuat(t),this.setFromRotationMatrix(a,e,i)},setFromRotationMatrix:function(t,e,i){void 0===e&&(e=this._order),void 0===i&&(i=!1);var n=t.val,r=n[0],o=n[4],a=n[8],h=n[1],l=n[5],u=n[9],c=n[2],d=n[6],f=n[10],p=0,v=0,g=0,m=.99999;switch(e){case"XYZ":v=Math.asin(s(a,-1,1)),Math.abs(a){t.exports=function(t){if(0===t)return 1;for(var e=t;--t;)e*=t;return e}},61616:t=>{t.exports=function(t,e){return Math.random()*(e-t)+t}},60679:t=>{t.exports=function(t,e,i){void 0===e&&(e=0),void 0===i&&(i=10);var s=Math.pow(i,-e);return Math.floor(t*s)/s}},91806:(t,e,i)=>{var s=i(82897);t.exports=function(t,e,i){return(i-e)*(t=s(t,0,1))+e}},79366:t=>{t.exports=function(t,e){return t/e/1e3}},43776:t=>{t.exports=function(t){return t==parseFloat(t)?!(t%2):void 0}},58442:t=>{t.exports=function(t){return t===parseFloat(t)?!(t%2):void 0}},42798:t=>{t.exports=function(t,e,i){return(e-t)*i+t}},61072:t=>{t.exports=function(t,e,i){return void 0===i&&(i=0),t.clone().lerp(e,i)}},5341:(t,e,i)=>{var s=new(i(56694))({initialize:function(t){this.val=new Float32Array(9),t?this.copy(t):this.identity()},clone:function(){return new s(this)},set:function(t){return this.copy(t)},copy:function(t){var e=this.val,i=t.val;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],this},fromMat4:function(t){var e=t.val,i=this.val;return i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=e[4],i[4]=e[5],i[5]=e[6],i[6]=e[8],i[7]=e[9],i[8]=e[10],this},fromArray:function(t){var e=this.val;return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],this},identity:function(){var t=this.val;return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,this},transpose:function(){var t=this.val,e=t[1],i=t[2],s=t[5];return t[1]=t[3],t[2]=t[6],t[3]=e,t[5]=t[7],t[6]=i,t[7]=s,this},invert:function(){var t=this.val,e=t[0],i=t[1],s=t[2],n=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8],u=l*r-o*h,c=-l*n+o*a,d=h*n-r*a,f=e*u+i*c+s*d;return f?(f=1/f,t[0]=u*f,t[1]=(-l*i+s*h)*f,t[2]=(o*i-s*r)*f,t[3]=c*f,t[4]=(l*e-s*a)*f,t[5]=(-o*e+s*n)*f,t[6]=d*f,t[7]=(-h*e+i*a)*f,t[8]=(r*e-i*n)*f,this):null},adjoint:function(){var t=this.val,e=t[0],i=t[1],s=t[2],n=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8];return t[0]=r*l-o*h,t[1]=s*h-i*l,t[2]=i*o-s*r,t[3]=o*a-n*l,t[4]=e*l-s*a,t[5]=s*n-e*o,t[6]=n*h-r*a,t[7]=i*a-e*h,t[8]=e*r-i*n,this},determinant:function(){var t=this.val,e=t[0],i=t[1],s=t[2],n=t[3],r=t[4],o=t[5],a=t[6],h=t[7],l=t[8];return e*(l*r-o*h)+i*(-l*n+o*a)+s*(h*n-r*a)},multiply:function(t){var e=this.val,i=e[0],s=e[1],n=e[2],r=e[3],o=e[4],a=e[5],h=e[6],l=e[7],u=e[8],c=t.val,d=c[0],f=c[1],p=c[2],v=c[3],g=c[4],m=c[5],y=c[6],x=c[7],T=c[8];return e[0]=d*i+f*r+p*h,e[1]=d*s+f*o+p*l,e[2]=d*n+f*a+p*u,e[3]=v*i+g*r+m*h,e[4]=v*s+g*o+m*l,e[5]=v*n+g*a+m*u,e[6]=y*i+x*r+T*h,e[7]=y*s+x*o+T*l,e[8]=y*n+x*a+T*u,this},translate:function(t){var e=this.val,i=t.x,s=t.y;return e[6]=i*e[0]+s*e[3]+e[6],e[7]=i*e[1]+s*e[4]+e[7],e[8]=i*e[2]+s*e[5]+e[8],this},rotate:function(t){var e=this.val,i=e[0],s=e[1],n=e[2],r=e[3],o=e[4],a=e[5],h=Math.sin(t),l=Math.cos(t);return e[0]=l*i+h*r,e[1]=l*s+h*o,e[2]=l*n+h*a,e[3]=l*r-h*i,e[4]=l*o-h*s,e[5]=l*a-h*n,this},scale:function(t){var e=this.val,i=t.x,s=t.y;return e[0]=i*e[0],e[1]=i*e[1],e[2]=i*e[2],e[3]=s*e[3],e[4]=s*e[4],e[5]=s*e[5],this},fromQuat:function(t){var e=t.x,i=t.y,s=t.z,n=t.w,r=e+e,o=i+i,a=s+s,h=e*r,l=e*o,u=e*a,c=i*o,d=i*a,f=s*a,p=n*r,v=n*o,g=n*a,m=this.val;return m[0]=1-(c+f),m[3]=l+g,m[6]=u-v,m[1]=l-g,m[4]=1-(h+f),m[7]=d+p,m[2]=u+v,m[5]=d-p,m[8]=1-(h+c),this},normalFromMat4:function(t){var e=t.val,i=this.val,s=e[0],n=e[1],r=e[2],o=e[3],a=e[4],h=e[5],l=e[6],u=e[7],c=e[8],d=e[9],f=e[10],p=e[11],v=e[12],g=e[13],m=e[14],y=e[15],x=s*h-n*a,T=s*l-r*a,w=s*u-o*a,b=n*l-r*h,S=n*u-o*h,E=r*u-o*l,A=c*g-d*v,C=c*m-f*v,_=c*y-p*v,M=d*m-f*g,P=d*y-p*g,R=f*y-p*m,O=x*R-T*P+w*M+b*_-S*C+E*A;return O?(O=1/O,i[0]=(h*R-l*P+u*M)*O,i[1]=(l*_-a*R-u*C)*O,i[2]=(a*P-h*_+u*A)*O,i[3]=(r*P-n*R-o*M)*O,i[4]=(s*R-r*_+o*C)*O,i[5]=(n*_-s*P-o*A)*O,i[6]=(g*E-m*S+y*b)*O,i[7]=(m*w-v*E-y*T)*O,i[8]=(v*S-g*w+y*x)*O,this):null}});t.exports=s},16650:(t,e,i)=>{var s=i(56694),n=i(70015),r=1e-6,o=new s({initialize:function(t){this.val=new Float32Array(16),t?this.copy(t):this.identity()},clone:function(){return new o(this)},set:function(t){return this.copy(t)},setValues:function(t,e,i,s,n,r,o,a,h,l,u,c,d,f,p,v){var g=this.val;return g[0]=t,g[1]=e,g[2]=i,g[3]=s,g[4]=n,g[5]=r,g[6]=o,g[7]=a,g[8]=h,g[9]=l,g[10]=u,g[11]=c,g[12]=d,g[13]=f,g[14]=p,g[15]=v,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 s=a.fromQuat(i).val,n=e.x,r=e.y,o=e.z;return this.setValues(s[0]*n,s[1]*n,s[2]*n,0,s[4]*r,s[5]*r,s[6]*r,0,s[8]*o,s[9]*o,s[10]*o,0,t.x,t.y,t.z,1)},xyz:function(t,e,i){this.identity();var s=this.val;return s[12]=t,s[13]=e,s[14]=i,this},scaling:function(t,e,i){this.zero();var s=this.val;return s[0]=t,s[5]=e,s[10]=i,s[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],s=t[3],n=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]=n,t[11]=t[14],t[12]=s,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],s=t[2],n=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],v=t[14],g=t[15],m=e*o-i*r,y=e*a-s*r,x=e*h-n*r,T=i*a-s*o,w=i*h-n*o,b=s*h-n*a,S=l*p-u*f,E=l*v-c*f,A=l*g-d*f,C=u*v-c*p,_=u*g-d*p,M=c*g-d*v,P=m*M-y*_+x*C+T*A-w*E+b*S;return P?(P=1/P,this.setValues((o*M-a*_+h*C)*P,(s*_-i*M-n*C)*P,(p*b-v*w+g*T)*P,(c*w-u*b-d*T)*P,(a*A-r*M-h*E)*P,(e*M-s*A+n*E)*P,(v*x-f*b-g*y)*P,(l*b-c*x+d*y)*P,(r*_-o*A+h*S)*P,(i*A-e*_-n*S)*P,(f*w-p*x+g*m)*P,(u*x-l*w-d*m)*P,(o*E-r*C-a*S)*P,(e*C-i*E+s*S)*P,(p*y-f*T-v*m)*P,(l*T-u*y+c*m)*P)):this},adjoint:function(){var t=this.val,e=t[0],i=t[1],s=t[2],n=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],v=t[14],g=t[15];return this.setValues(o*(c*g-d*v)-u*(a*g-h*v)+p*(a*d-h*c),-(i*(c*g-d*v)-u*(s*g-n*v)+p*(s*d-n*c)),i*(a*g-h*v)-o*(s*g-n*v)+p*(s*h-n*a),-(i*(a*d-h*c)-o*(s*d-n*c)+u*(s*h-n*a)),-(r*(c*g-d*v)-l*(a*g-h*v)+f*(a*d-h*c)),e*(c*g-d*v)-l*(s*g-n*v)+f*(s*d-n*c),-(e*(a*g-h*v)-r*(s*g-n*v)+f*(s*h-n*a)),e*(a*d-h*c)-r*(s*d-n*c)+l*(s*h-n*a),r*(u*g-d*p)-l*(o*g-h*p)+f*(o*d-h*u),-(e*(u*g-d*p)-l*(i*g-n*p)+f*(i*d-n*u)),e*(o*g-h*p)-r*(i*g-n*p)+f*(i*h-n*o),-(e*(o*d-h*u)-r*(i*d-n*u)+l*(i*h-n*o)),-(r*(u*v-c*p)-l*(o*v-a*p)+f*(o*c-a*u)),e*(u*v-c*p)-l*(i*v-s*p)+f*(i*c-s*u),-(e*(o*v-a*p)-r*(i*v-s*p)+f*(i*a-s*o)),e*(o*c-a*u)-r*(i*c-s*u)+l*(i*a-s*o))},determinant:function(){var t=this.val,e=t[0],i=t[1],s=t[2],n=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],v=t[14],g=t[15];return(e*o-i*r)*(c*g-d*v)-(e*a-s*r)*(u*g-d*p)+(e*h-n*r)*(u*v-c*p)+(i*a-s*o)*(l*g-d*f)-(i*h-n*o)*(l*v-c*f)+(s*h-n*a)*(l*p-u*f)},multiply:function(t){var e=this.val,i=e[0],s=e[1],n=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],v=e[13],g=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*s+T*a+w*c+b*v,e[2]=x*n+T*h+w*d+b*g,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*s+T*a+w*c+b*v,e[6]=x*n+T*h+w*d+b*g,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*s+T*a+w*c+b*v,e[10]=x*n+T*h+w*d+b*g,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*s+T*a+w*c+b*v,e[14]=x*n+T*h+w*d+b*g,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,s=e.val,n=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],v=i[14],g=i[3],m=i[7],y=i[11],x=i[15],T=s[0],w=s[4],b=s[8],S=s[12],E=s[1],A=s[5],C=s[9],_=s[13],M=s[2],P=s[6],R=s[10],O=s[14],L=s[3],F=s[7],D=s[11],I=s[15];return this.setValues(n*T+r*E+o*M+a*L,h*T+l*E+u*M+c*L,d*T+f*E+p*M+v*L,g*T+m*E+y*M+x*L,n*w+r*A+o*P+a*F,h*w+l*A+u*P+c*F,d*w+f*A+p*P+v*F,g*w+m*A+y*P+x*F,n*b+r*C+o*R+a*D,h*b+l*C+u*R+c*D,d*b+f*C+p*R+v*D,g*b+m*C+y*R+x*D,n*S+r*_+o*O+a*I,h*S+l*_+u*O+c*I,d*S+f*_+p*O+v*I,g*S+m*_+y*O+x*I)},translate:function(t){return this.translateXYZ(t.x,t.y,t.z)},translateXYZ:function(t,e,i){var s=this.val;return s[12]=s[0]*t+s[4]*e+s[8]*i+s[12],s[13]=s[1]*t+s[5]*e+s[9]*i+s[13],s[14]=s[2]*t+s[6]*e+s[10]*i+s[14],s[15]=s[3]*t+s[7]*e+s[11]*i+s[15],this},scale:function(t){return this.scaleXYZ(t.x,t.y,t.z)},scaleXYZ:function(t,e,i){var s=this.val;return s[0]=s[0]*t,s[1]=s[1]*t,s[2]=s[2]*t,s[3]=s[3]*t,s[4]=s[4]*e,s[5]=s[5]*e,s[6]=s[6]*e,s[7]=s[7]*e,s[8]=s[8]*i,s[9]=s[9]*i,s[10]=s[10]*i,s[11]=s[11]*i,this},makeRotationAxis:function(t,e){var i=Math.cos(e),s=Math.sin(e),n=1-i,r=t.x,o=t.y,a=t.z,h=n*r,l=n*o;return this.setValues(h*r+i,h*o-s*a,h*a+s*o,0,h*o+s*a,l*o+i,l*a-s*r,0,h*a-s*o,l*a+s*r,n*a*a+i,0,0,0,0,1)},rotate:function(t,e){var i=this.val,s=e.x,n=e.y,o=e.z,a=Math.sqrt(s*s+n*n+o*o);if(Math.abs(a){t.exports=function(t,e,i){return Math.min(t+e,i)}},37394:t=>{t.exports=function(t){var e=t.length;if(0===e)return 0;t.sort((function(t,e){return t-e}));var i=Math.floor(e/2);return e%2==0?(t[i]+t[i-1])/2:t[i]}},17259:t=>{t.exports=function(t,e,i){return Math.max(t-e,i)}},61820:t=>{t.exports=function(t,e,i,s){void 0===i&&(i=e+1);var n=(t-e)/(i-e);return n>1?void 0!==s?(n=(s-t)/(s-i))<0&&(n=0):n=1:n<0&&(n=0),n}},75003:(t,e,i)=>{var s=i(56694),n=i(5341),r=i(72283),o=i(70015),a=1e-6,h=new Int8Array([1,2,0]),l=new Float32Array([0,0,0]),u=new o(1,0,0),c=new o(0,1,0),d=new o,f=new n,p=new s({initialize:function(t,e,i,s){this.onChangeCallback=r,this.set(t,e,i,s)},x:{get:function(){return this._x},set:function(t){this._x=t,this.onChangeCallback(this)}},y:{get:function(){return this._y},set:function(t){this._y=t,this.onChangeCallback(this)}},z:{get:function(){return this._z},set:function(t){this._z=t,this.onChangeCallback(this)}},w:{get:function(){return this._w},set:function(t){this._w=t,this.onChangeCallback(this)}},copy:function(t){return this.set(t)},set:function(t,e,i,s,n){return void 0===n&&(n=!0),"object"==typeof t?(this._x=t.x||0,this._y=t.y||0,this._z=t.z||0,this._w=t.w||0):(this._x=t||0,this._y=e||0,this._z=i||0,this._w=s||0),n&&this.onChangeCallback(this),this},add:function(t){return this._x+=t.x,this._y+=t.y,this._z+=t.z,this._w+=t.w,this.onChangeCallback(this),this},subtract:function(t){return this._x-=t.x,this._y-=t.y,this._z-=t.z,this._w-=t.w,this.onChangeCallback(this),this},scale:function(t){return this._x*=t,this._y*=t,this._z*=t,this._w*=t,this.onChangeCallback(this),this},length:function(){var t=this.x,e=this.y,i=this.z,s=this.w;return Math.sqrt(t*t+e*e+i*i+s*s)},lengthSq:function(){var t=this.x,e=this.y,i=this.z,s=this.w;return t*t+e*e+i*i+s*s},normalize:function(){var t=this.x,e=this.y,i=this.z,s=this.w,n=t*t+e*e+i*i+s*s;return n>0&&(n=1/Math.sqrt(n),this._x=t*n,this._y=e*n,this._z=i*n,this._w=s*n),this.onChangeCallback(this),this},dot:function(t){return this.x*t.x+this.y*t.y+this.z*t.z+this.w*t.w},lerp:function(t,e){void 0===e&&(e=0);var i=this.x,s=this.y,n=this.z,r=this.w;return this.set(i+e*(t.x-i),s+e*(t.y-s),n+e*(t.z-n),r+e*(t.w-r))},rotationTo:function(t,e){var i=t.x*e.x+t.y*e.y+t.z*e.z;return i<-.999999?(d.copy(u).cross(t).length().999999?this.set(0,0,0,1):(d.copy(t).cross(e),this._x=d.x,this._y=d.y,this._z=d.z,this._w=1+i,this.normalize())},setAxes:function(t,e,i){var s=f.val;return s[0]=e.x,s[3]=e.y,s[6]=e.z,s[1]=i.x,s[4]=i.y,s[7]=i.z,s[2]=-t.x,s[5]=-t.y,s[8]=-t.z,this.fromMat3(f).normalize()},identity:function(){return this.set(0,0,0,1)},setAxisAngle:function(t,e){e*=.5;var i=Math.sin(e);return this.set(i*t.x,i*t.y,i*t.z,Math.cos(e))},multiply:function(t){var e=this.x,i=this.y,s=this.z,n=this.w,r=t.x,o=t.y,a=t.z,h=t.w;return this.set(e*h+n*r+i*a-s*o,i*h+n*o+s*r-e*a,s*h+n*a+e*o-i*r,n*h-e*r-i*o-s*a)},slerp:function(t,e){var i=this.x,s=this.y,n=this.z,r=this.w,o=t.x,h=t.y,l=t.z,u=t.w,c=i*o+s*h+n*l+r*u;c<0&&(c=-c,o=-o,h=-h,l=-l,u=-u);var d=1-e,f=e;if(1-c>a){var p=Math.acos(c),v=Math.sin(p);d=Math.sin((1-e)*p)/v,f=Math.sin(e*p)/v}return this.set(d*i+f*o,d*s+f*h,d*n+f*l,d*r+f*u)},invert:function(){var t=this.x,e=this.y,i=this.z,s=this.w,n=t*t+e*e+i*i+s*s,r=n?1/n:0;return this.set(-t*r,-e*r,-i*r,s*r)},conjugate:function(){return this._x=-this.x,this._y=-this.y,this._z=-this.z,this.onChangeCallback(this),this},rotateX:function(t){t*=.5;var e=this.x,i=this.y,s=this.z,n=this.w,r=Math.sin(t),o=Math.cos(t);return this.set(e*o+n*r,i*o+s*r,s*o-i*r,n*o-e*r)},rotateY:function(t){t*=.5;var e=this.x,i=this.y,s=this.z,n=this.w,r=Math.sin(t),o=Math.cos(t);return this.set(e*o-s*r,i*o+n*r,s*o+e*r,n*o-i*r)},rotateZ:function(t){t*=.5;var e=this.x,i=this.y,s=this.z,n=this.w,r=Math.sin(t),o=Math.cos(t);return this.set(e*o+i*r,i*o-e*r,s*o+n*r,n*o-s*r)},calculateW:function(){var t=this.x,e=this.y,i=this.z;return this.w=-Math.sqrt(1-t*t-e*e-i*i),this},setFromEuler:function(t,e){var i=t.x/2,s=t.y/2,n=t.z/2,r=Math.cos(i),o=Math.cos(s),a=Math.cos(n),h=Math.sin(i),l=Math.sin(s),u=Math.sin(n);switch(t.order){case"XYZ":this.set(h*o*a+r*l*u,r*l*a-h*o*u,r*o*u+h*l*a,r*o*a-h*l*u,e);break;case"YXZ":this.set(h*o*a+r*l*u,r*l*a-h*o*u,r*o*u-h*l*a,r*o*a+h*l*u,e);break;case"ZXY":this.set(h*o*a-r*l*u,r*l*a+h*o*u,r*o*u+h*l*a,r*o*a-h*l*u,e);break;case"ZYX":this.set(h*o*a-r*l*u,r*l*a+h*o*u,r*o*u-h*l*a,r*o*a+h*l*u,e);break;case"YZX":this.set(h*o*a+r*l*u,r*l*a+h*o*u,r*o*u-h*l*a,r*o*a-h*l*u,e);break;case"XZY":this.set(h*o*a-r*l*u,r*l*a-h*o*u,r*o*u+h*l*a,r*o*a+h*l*u,e)}return this},setFromRotationMatrix:function(t){var e,i=t.val,s=i[0],n=i[4],r=i[8],o=i[1],a=i[5],h=i[9],l=i[2],u=i[6],c=i[10],d=s+a+c;return d>0?(e=.5/Math.sqrt(d+1),this.set((u-h)*e,(r-l)*e,(o-n)*e,.25/e)):s>a&&s>c?(e=2*Math.sqrt(1+s-a-c),this.set(.25*e,(n+o)/e,(r+l)/e,(u-h)/e)):a>c?(e=2*Math.sqrt(1+a-s-c),this.set((n+o)/e,.25*e,(h+u)/e,(r-l)/e)):(e=2*Math.sqrt(1+c-s-a),this.set((r+l)/e,(h+u)/e,.25*e,(o-n)/e)),this},fromMat3:function(t){var e,i=t.val,s=i[0]+i[4]+i[8];if(s>0)e=Math.sqrt(s+1),this.w=.5*e,e=.5/e,this._x=(i[7]-i[5])*e,this._y=(i[2]-i[6])*e,this._z=(i[3]-i[1])*e;else{var n=0;i[4]>i[0]&&(n=1),i[8]>i[3*n+n]&&(n=2);var r=h[n],o=h[r];e=Math.sqrt(i[3*n+n]-i[3*r+r]-i[3*o+o]+1),l[n]=.5*e,e=.5/e,l[r]=(i[3*r+n]+i[3*n+r])*e,l[o]=(i[3*o+n]+i[3*n+o])*e,this._x=l[0],this._y=l[1],this._z=l[2],this._w=(i[3*o+r]-i[3*r+o])*e}return this.onChangeCallback(this),this}});t.exports=p},23701:(t,e,i)=>{var s=i(83392);t.exports=function(t){return t*s.RAD_TO_DEG}},16906:t=>{t.exports=function(t,e){void 0===e&&(e=1);var i=2*Math.random()*Math.PI;return t.x=Math.cos(i)*e,t.y=Math.sin(i)*e,t}},52417:t=>{t.exports=function(t,e){void 0===e&&(e=1);var i=2*Math.random()*Math.PI,s=2*Math.random()-1,n=Math.sqrt(1-s*s)*e;return t.x=Math.cos(i)*n,t.y=Math.sin(i)*n,t.z=s*e,t}},17915:t=>{t.exports=function(t,e){return void 0===e&&(e=1),t.x=(2*Math.random()-1)*e,t.y=(2*Math.random()-1)*e,t.z=(2*Math.random()-1)*e,t.w=(2*Math.random()-1)*e,t}},52257:t=>{t.exports=function(t,e){var i=t.x,s=t.y;return t.x=i*Math.cos(e)-s*Math.sin(e),t.y=i*Math.sin(e)+s*Math.cos(e),t}},2386:t=>{t.exports=function(t,e,i,s){var n=Math.cos(s),r=Math.sin(s),o=t.x-e,a=t.y-i;return t.x=o*n-a*r+e,t.y=o*r+a*n+i,t}},72395:t=>{t.exports=function(t,e,i,s,n){var r=s+Math.atan2(t.y-i,t.x-e);return t.x=e+n*Math.cos(r),t.y=i+n*Math.sin(r),t}},41061:t=>{t.exports=function(t,e,i,s,n){return t.x=e+n*Math.cos(s),t.y=i+n*Math.sin(s),t}},93709:(t,e,i)=>{var s=i(70015),n=i(16650),r=i(75003),o=new n,a=new r,h=new s;t.exports=function(t,e,i){return a.setAxisAngle(e,i),o.fromRotationTranslation(a,h.set(0,0,0)),t.transformMat4(o)}},67233:t=>{t.exports=function(t){return t>0?Math.ceil(t):Math.floor(t)}},64333:t=>{t.exports=function(t,e,i){void 0===e&&(e=0),void 0===i&&(i=10);var s=Math.pow(i,-e);return Math.round(t*s)/s}},59533:t=>{t.exports=function(t,e,i,s){void 0===e&&(e=1),void 0===i&&(i=1),void 0===s&&(s=1),s*=Math.PI/t;for(var n=[],r=[],o=0;o{t.exports=function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*(3-2*t)}},87736:t=>{t.exports=function(t,e,i){return(t=Math.max(0,Math.min(1,(t-e)/(i-e))))*t*t*(t*(6*t-15)+10)}},55805:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n){void 0===n&&(n=new s);var r=0,o=0;return t>0&&t<=e*i&&(r=t>e-1?t-(o=Math.floor(t/e))*e:t),n.set(r,o)}},64462:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n,r,o,a,h){void 0===h&&(h=new s);var l=Math.sin(r),u=Math.cos(r),c=u*o,d=l*o,f=-l*a,p=u*a,v=1/(c*p+f*-d);return h.x=p*v*t+-f*v*e+(n*f-i*p)*v,h.y=c*v*e+-d*v*t+(-n*c+i*d)*v,h}},93736:(t,e,i)=>{var s=i(56694),n=i(88456),r=new s({initialize:function(t,e){this.x=0,this.y=0,"object"==typeof t?(this.x=t.x||0,this.y=t.y||0):(void 0===e&&(e=t),this.x=t||0,this.y=e||0)},clone:function(){return new r(this.x,this.y)},copy:function(t){return this.x=t.x||0,this.y=t.y||0,this},setFromObject:function(t){return this.x=t.x||0,this.y=t.y||0,this},set:function(t,e){return void 0===e&&(e=t),this.x=t,this.y=e,this},setTo:function(t,e){return this.set(t,e)},setToPolar:function(t,e){return null==e&&(e=1),this.x=Math.cos(t)*e,this.y=Math.sin(t)*e,this},equals:function(t){return this.x===t.x&&this.y===t.y},fuzzyEquals:function(t,e){return n(this.x,t.x,e)&&n(this.y,t.y,e)},angle:function(){var t=Math.atan2(this.y,this.x);return t<0&&(t+=2*Math.PI),t},setAngle:function(t){return this.setToPolar(t,this.length())},add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.x-=t.x,this.y-=t.y,this},multiply:function(t){return this.x*=t.x,this.y*=t.y,this},scale:function(t){return isFinite(t)?(this.x*=t,this.y*=t):(this.x=0,this.y=0),this},divide:function(t){return this.x/=t.x,this.y/=t.y,this},negate:function(){return this.x=-this.x,this.y=-this.y,this},distance:function(t){var e=t.x-this.x,i=t.y-this.y;return Math.sqrt(e*e+i*i)},distanceSq:function(t){var e=t.x-this.x,i=t.y-this.y;return e*e+i*i},length:function(){var t=this.x,e=this.y;return Math.sqrt(t*t+e*e)},setLength:function(t){return this.normalize().scale(t)},lengthSq:function(){var t=this.x,e=this.y;return t*t+e*e},normalize:function(){var t=this.x,e=this.y,i=t*t+e*e;return i>0&&(i=1/Math.sqrt(i),this.x=t*i,this.y=e*i),this},normalizeRightHand:function(){var t=this.x;return this.x=-1*this.y,this.y=t,this},normalizeLeftHand:function(){var t=this.x;return this.x=this.y,this.y=-1*t,this},dot:function(t){return this.x*t.x+this.y*t.y},cross:function(t){return this.x*t.y-this.y*t.x},lerp:function(t,e){void 0===e&&(e=0);var i=this.x,s=this.y;return this.x=i+e*(t.x-i),this.y=s+e*(t.y-s),this},transformMat3:function(t){var e=this.x,i=this.y,s=t.val;return this.x=s[0]*e+s[3]*i+s[6],this.y=s[1]*e+s[4]*i+s[7],this},transformMat4:function(t){var e=this.x,i=this.y,s=t.val;return this.x=s[0]*e+s[4]*i+s[12],this.y=s[1]*e+s[5]*i+s[13],this},reset:function(){return this.x=0,this.y=0,this},limit:function(t){var e=this.length();return e&&e>t&&this.scale(t/e),this},reflect:function(t){return t=t.clone().normalize(),this.subtract(t.scale(2*this.dot(t)))},mirror:function(t){return this.reflect(t).negate()},rotate:function(t){var e=Math.cos(t),i=Math.sin(t);return this.set(e*this.x-i*this.y,i*this.x+e*this.y)},project:function(t){var e=this.dot(t)/t.dot(t);return this.copy(t).scale(e)}});r.ZERO=new r,r.RIGHT=new r(1,0),r.LEFT=new r(-1,0),r.UP=new r(0,-1),r.DOWN=new r(0,1),r.ONE=new r(1,1),t.exports=r},70015:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e,i){this.x=0,this.y=0,this.z=0,"object"==typeof t?(this.x=t.x||0,this.y=t.y||0,this.z=t.z||0):(this.x=t||0,this.y=e||0,this.z=i||0)},up:function(){return this.x=0,this.y=1,this.z=0,this},min:function(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this.z=Math.min(this.z,t.z),this},max:function(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this.z=Math.max(this.z,t.z),this},clone:function(){return new s(this.x,this.y,this.z)},addVectors:function(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this},crossVectors:function(t,e){var i=t.x,s=t.y,n=t.z,r=e.x,o=e.y,a=e.z;return this.x=s*a-n*o,this.y=n*r-i*a,this.z=i*o-s*r,this},equals:function(t){return this.x===t.x&&this.y===t.y&&this.z===t.z},copy:function(t){return this.x=t.x,this.y=t.y,this.z=t.z||0,this},set:function(t,e,i){return"object"==typeof t?(this.x=t.x||0,this.y=t.y||0,this.z=t.z||0):(this.x=t||0,this.y=e||0,this.z=i||0),this},setFromMatrixPosition:function(t){return this.fromArray(t.val,12)},setFromMatrixColumn:function(t,e){return this.fromArray(t.val,4*e)},fromArray:function(t,e){return void 0===e&&(e=0),this.x=t[e],this.y=t[e+1],this.z=t[e+2],this},add:function(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z||0,this},addScalar:function(t){return this.x+=t,this.y+=t,this.z+=t,this},addScale:function(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e||0,this},subtract:function(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z||0,this},multiply:function(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z||1,this},scale:function(t){return isFinite(t)?(this.x*=t,this.y*=t,this.z*=t):(this.x=0,this.y=0,this.z=0),this},divide:function(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z||1,this},negate:function(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this},distance:function(t){var e=t.x-this.x,i=t.y-this.y,s=t.z-this.z||0;return Math.sqrt(e*e+i*i+s*s)},distanceSq:function(t){var e=t.x-this.x,i=t.y-this.y,s=t.z-this.z||0;return e*e+i*i+s*s},length:function(){var t=this.x,e=this.y,i=this.z;return Math.sqrt(t*t+e*e+i*i)},lengthSq:function(){var t=this.x,e=this.y,i=this.z;return t*t+e*e+i*i},normalize:function(){var t=this.x,e=this.y,i=this.z,s=t*t+e*e+i*i;return s>0&&(s=1/Math.sqrt(s),this.x=t*s,this.y=e*s,this.z=i*s),this},dot:function(t){return this.x*t.x+this.y*t.y+this.z*t.z},cross:function(t){var e=this.x,i=this.y,s=this.z,n=t.x,r=t.y,o=t.z;return this.x=i*o-s*r,this.y=s*n-e*o,this.z=e*r-i*n,this},lerp:function(t,e){void 0===e&&(e=0);var i=this.x,s=this.y,n=this.z;return this.x=i+e*(t.x-i),this.y=s+e*(t.y-s),this.z=n+e*(t.z-n),this},applyMatrix3:function(t){var e=this.x,i=this.y,s=this.z,n=t.val;return this.x=n[0]*e+n[3]*i+n[6]*s,this.y=n[1]*e+n[4]*i+n[7]*s,this.z=n[2]*e+n[5]*i+n[8]*s,this},applyMatrix4:function(t){var e=this.x,i=this.y,s=this.z,n=t.val,r=1/(n[3]*e+n[7]*i+n[11]*s+n[15]);return this.x=(n[0]*e+n[4]*i+n[8]*s+n[12])*r,this.y=(n[1]*e+n[5]*i+n[9]*s+n[13])*r,this.z=(n[2]*e+n[6]*i+n[10]*s+n[14])*r,this},transformMat3:function(t){var e=this.x,i=this.y,s=this.z,n=t.val;return this.x=e*n[0]+i*n[3]+s*n[6],this.y=e*n[1]+i*n[4]+s*n[7],this.z=e*n[2]+i*n[5]+s*n[8],this},transformMat4:function(t){var e=this.x,i=this.y,s=this.z,n=t.val;return this.x=n[0]*e+n[4]*i+n[8]*s+n[12],this.y=n[1]*e+n[5]*i+n[9]*s+n[13],this.z=n[2]*e+n[6]*i+n[10]*s+n[14],this},transformCoordinates:function(t){var e=this.x,i=this.y,s=this.z,n=t.val,r=e*n[0]+i*n[4]+s*n[8]+n[12],o=e*n[1]+i*n[5]+s*n[9]+n[13],a=e*n[2]+i*n[6]+s*n[10]+n[14],h=e*n[3]+i*n[7]+s*n[11]+n[15];return this.x=r/h,this.y=o/h,this.z=a/h,this},transformQuat:function(t){var e=this.x,i=this.y,s=this.z,n=t.x,r=t.y,o=t.z,a=t.w,h=a*e+r*s-o*i,l=a*i+o*e-n*s,u=a*s+n*i-r*e,c=-n*e-r*i-o*s;return this.x=h*a+c*-n+l*-o-u*-r,this.y=l*a+c*-r+u*-n-h*-o,this.z=u*a+c*-o+h*-r-l*-n,this},project:function(t){var e=this.x,i=this.y,s=this.z,n=t.val,r=n[0],o=n[1],a=n[2],h=n[3],l=n[4],u=n[5],c=n[6],d=n[7],f=n[8],p=n[9],v=n[10],g=n[11],m=n[12],y=n[13],x=n[14],T=1/(e*h+i*d+s*g+n[15]);return this.x=(e*r+i*l+s*f+m)*T,this.y=(e*o+i*u+s*p+y)*T,this.z=(e*a+i*c+s*v+x)*T,this},projectViewMatrix:function(t,e){return this.applyMatrix4(t).applyMatrix4(e)},unprojectViewMatrix:function(t,e){return this.applyMatrix4(t).applyMatrix4(e)},unproject:function(t,e){var i=t.x,s=t.y,n=t.z,r=t.w,o=this.x-i,a=r-this.y-1-s,h=this.z;return this.x=2*o/n-1,this.y=2*a/r-1,this.z=2*h-1,this.project(e)},reset:function(){return this.x=0,this.y=0,this.z=0,this}});s.ZERO=new s,s.RIGHT=new s(1,0,0),s.LEFT=new s(-1,0,0),s.UP=new s(0,-1,0),s.DOWN=new s(0,1,0),s.FORWARD=new s(0,0,1),s.BACK=new s(0,0,-1),s.ONE=new s(1,1,1),t.exports=s},51729:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e,i,s){this.x=0,this.y=0,this.z=0,this.w=0,"object"==typeof t?(this.x=t.x||0,this.y=t.y||0,this.z=t.z||0,this.w=t.w||0):(this.x=t||0,this.y=e||0,this.z=i||0,this.w=s||0)},clone:function(){return new s(this.x,this.y,this.z,this.w)},copy:function(t){return this.x=t.x,this.y=t.y,this.z=t.z||0,this.w=t.w||0,this},equals:function(t){return this.x===t.x&&this.y===t.y&&this.z===t.z&&this.w===t.w},set:function(t,e,i,s){return"object"==typeof t?(this.x=t.x||0,this.y=t.y||0,this.z=t.z||0,this.w=t.w||0):(this.x=t||0,this.y=e||0,this.z=i||0,this.w=s||0),this},add:function(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z||0,this.w+=t.w||0,this},subtract:function(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z||0,this.w-=t.w||0,this},scale:function(t){return this.x*=t,this.y*=t,this.z*=t,this.w*=t,this},length:function(){var t=this.x,e=this.y,i=this.z,s=this.w;return Math.sqrt(t*t+e*e+i*i+s*s)},lengthSq:function(){var t=this.x,e=this.y,i=this.z,s=this.w;return t*t+e*e+i*i+s*s},normalize:function(){var t=this.x,e=this.y,i=this.z,s=this.w,n=t*t+e*e+i*i+s*s;return n>0&&(n=1/Math.sqrt(n),this.x=t*n,this.y=e*n,this.z=i*n,this.w=s*n),this},dot:function(t){return this.x*t.x+this.y*t.y+this.z*t.z+this.w*t.w},lerp:function(t,e){void 0===e&&(e=0);var i=this.x,s=this.y,n=this.z,r=this.w;return this.x=i+e*(t.x-i),this.y=s+e*(t.y-s),this.z=n+e*(t.z-n),this.w=r+e*(t.w-r),this},multiply:function(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z||1,this.w*=t.w||1,this},divide:function(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z||1,this.w/=t.w||1,this},distance:function(t){var e=t.x-this.x,i=t.y-this.y,s=t.z-this.z||0,n=t.w-this.w||0;return Math.sqrt(e*e+i*i+s*s+n*n)},distanceSq:function(t){var e=t.x-this.x,i=t.y-this.y,s=t.z-this.z||0,n=t.w-this.w||0;return e*e+i*i+s*s+n*n},negate:function(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this.w=-this.w,this},transformMat4:function(t){var e=this.x,i=this.y,s=this.z,n=this.w,r=t.val;return this.x=r[0]*e+r[4]*i+r[8]*s+r[12]*n,this.y=r[1]*e+r[5]*i+r[9]*s+r[13]*n,this.z=r[2]*e+r[6]*i+r[10]*s+r[14]*n,this.w=r[3]*e+r[7]*i+r[11]*s+r[15]*n,this},transformQuat:function(t){var e=this.x,i=this.y,s=this.z,n=t.x,r=t.y,o=t.z,a=t.w,h=a*e+r*s-o*i,l=a*i+o*e-n*s,u=a*s+n*i-r*e,c=-n*e-r*i-o*s;return this.x=h*a+c*-n+l*-o-u*-r,this.y=l*a+c*-r+u*-n-h*-o,this.z=u*a+c*-o+h*-r-l*-n,this},reset:function(){return this.x=0,this.y=0,this.z=0,this.w=0,this}});s.prototype.sub=s.prototype.subtract,s.prototype.mul=s.prototype.multiply,s.prototype.div=s.prototype.divide,s.prototype.dist=s.prototype.distance,s.prototype.distSq=s.prototype.distanceSq,s.prototype.len=s.prototype.length,s.prototype.lenSq=s.prototype.lengthSq,t.exports=s},9557:t=>{t.exports=function(t,e,i){return Math.abs(t-e)<=i}},1071:t=>{t.exports=function(t,e,i){if(t>=e&&t<=i)return t;var s=i-e;return e+((t-e)%s+s)%s}},90447:t=>{t.exports=function(t,e,i,s){return Math.atan2(s-e,i-t)}},94240:t=>{t.exports=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)}},84066:t=>{t.exports=function(t,e){return Math.atan2(e.x-t.x,e.y-t.y)}},9678:t=>{t.exports=function(t,e,i,s){return Math.atan2(i-t,s-e)}},76861:(t,e,i)=>{var s=i(83392);t.exports=function(t){return t>Math.PI&&(t-=s.PI2),Math.abs(((t+s.TAU)%s.PI2-s.PI2)%s.PI2)}},37570:t=>{t.exports=function(t){return(t%=2*Math.PI)>=0?t:t+2*Math.PI}},87597:(t,e,i)=>{var s=i(61616);t.exports=function(){return s(-Math.PI,Math.PI)}},74493:(t,e,i)=>{var s=i(61616);t.exports=function(){return s(-180,180)}},19049:(t,e,i)=>{var s=i(37570);t.exports=function(t){return s(t+Math.PI)}},90612:(t,e,i)=>{var s=i(83392);t.exports=function(t,e,i){return void 0===i&&(i=.05),t===e||(Math.abs(e-t)<=i||Math.abs(e-t)>=s.PI2-i?t=e:(Math.abs(e-t)>Math.PI&&(et?t+=i:e{t.exports=function(t,e){var i=e-t;return 0===i?0:i-360*Math.floor((i- -180)/360)}},35786:(t,e,i)=>{var s=i(1071);t.exports=function(t){return s(t,-Math.PI,Math.PI)}},62138:(t,e,i)=>{var s=i(1071);t.exports=function(t){return s(t,-180,180)}},22153:(t,e,i)=>{t.exports={Between:i(90447),BetweenPoints:i(94240),BetweenPointsY:i(84066),BetweenY:i(9678),CounterClockwise:i(76861),Normalize:i(37570),Random:i(87597),RandomDegrees:i(74493),Reverse:i(19049),RotateTo:i(90612),ShortestBetween:i(93954),Wrap:i(35786),WrapDegrees:i(62138)}},83392:t=>{var e={PI2:2*Math.PI,TAU:.5*Math.PI,EPSILON:1e-6,DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,RND:null,MIN_SAFE_INTEGER:Number.MIN_SAFE_INTEGER||-9007199254740991,MAX_SAFE_INTEGER:Number.MAX_SAFE_INTEGER||9007199254740991};t.exports=e},53996:t=>{t.exports=function(t,e,i,s){var n=t-i,r=e-s;return Math.sqrt(n*n+r*r)}},92951:t=>{t.exports=function(t,e){var i=t.x-e.x,s=t.y-e.y;return Math.sqrt(i*i+s*s)}},12161:t=>{t.exports=function(t,e){var i=t.x-e.x,s=t.y-e.y;return i*i+s*s}},38057:t=>{t.exports=function(t,e,i,s){return Math.max(Math.abs(t-i),Math.abs(e-s))}},33297:t=>{t.exports=function(t,e,i,s,n){return void 0===n&&(n=2),Math.sqrt(Math.pow(i-t,n)+Math.pow(s-e,n))}},90366:t=>{t.exports=function(t,e,i,s){return Math.abs(t-i)+Math.abs(e-s)}},35032:t=>{t.exports=function(t,e,i,s){var n=t-i,r=e-s;return n*n+r*r}},10130:(t,e,i)=>{t.exports={Between:i(53996),BetweenPoints:i(92951),BetweenPointsSquared:i(12161),Chebyshev:i(38057),Power:i(33297),Snake:i(90366),Squared:i(35032)}},35060:(t,e,i)=>{var s=i(25265),n=i(57428),r=i(73214),o=i(71778),a=i(36468),h=i(88258),l=i(52910),u=i(67799),c=i(74083),d=i(92284),f=i(28035),p=i(8754);t.exports={Power0:l,Power1:u.Out,Power2:o.Out,Power3:c.Out,Power4:d.Out,Linear:l,Quad:u.Out,Cubic:o.Out,Quart:c.Out,Quint:d.Out,Sine:f.Out,Expo:h.Out,Circ:r.Out,Elastic:a.Out,Back:s.Out,Bounce:n.Out,Stepped:p,"Quad.easeIn":u.In,"Cubic.easeIn":o.In,"Quart.easeIn":c.In,"Quint.easeIn":d.In,"Sine.easeIn":f.In,"Expo.easeIn":h.In,"Circ.easeIn":r.In,"Elastic.easeIn":a.In,"Back.easeIn":s.In,"Bounce.easeIn":n.In,"Quad.easeOut":u.Out,"Cubic.easeOut":o.Out,"Quart.easeOut":c.Out,"Quint.easeOut":d.Out,"Sine.easeOut":f.Out,"Expo.easeOut":h.Out,"Circ.easeOut":r.Out,"Elastic.easeOut":a.Out,"Back.easeOut":s.Out,"Bounce.easeOut":n.Out,"Quad.easeInOut":u.InOut,"Cubic.easeInOut":o.InOut,"Quart.easeInOut":c.InOut,"Quint.easeInOut":d.InOut,"Sine.easeInOut":f.InOut,"Expo.easeInOut":h.InOut,"Circ.easeInOut":r.InOut,"Elastic.easeInOut":a.InOut,"Back.easeInOut":s.InOut,"Bounce.easeInOut":n.InOut}},25860:t=>{t.exports=function(t,e){return void 0===e&&(e=1.70158),t*t*((e+1)*t-e)}},45264:t=>{t.exports=function(t,e){void 0===e&&(e=1.70158);var i=1.525*e;return(t*=2)<1?t*t*((i+1)*t-i)*.5:.5*((t-=2)*t*((i+1)*t+i)+2)}},36699:t=>{t.exports=function(t,e){return void 0===e&&(e=1.70158),--t*t*((e+1)*t+e)+1}},25265:(t,e,i)=>{t.exports={In:i(25860),Out:i(36699),InOut:i(45264)}},62191:t=>{t.exports=function(t){return(t=1-t)<1/2.75?1-7.5625*t*t:t<2/2.75?1-(7.5625*(t-=1.5/2.75)*t+.75):t<2.5/2.75?1-(7.5625*(t-=2.25/2.75)*t+.9375):1-(7.5625*(t-=2.625/2.75)*t+.984375)}},24799:t=>{t.exports=function(t){var e=!1;return t<.5?(t=1-2*t,e=!0):t=2*t-1,t<1/2.75?t*=7.5625*t:t=t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375,e?.5*(1-t):.5*t+.5}},60819:t=>{t.exports=function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}},57428:(t,e,i)=>{t.exports={In:i(62191),Out:i(60819),InOut:i(24799)}},86855:t=>{t.exports=function(t){return 1-Math.sqrt(1-t*t)}},7280:t=>{t.exports=function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)}},18058:t=>{t.exports=function(t){return Math.sqrt(1- --t*t)}},73214:(t,e,i)=>{t.exports={In:i(86855),Out:i(18058),InOut:i(7280)}},91532:t=>{t.exports=function(t){return t*t*t}},63180:t=>{t.exports=function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)}},16518:t=>{t.exports=function(t){return--t*t*t+1}},71778:(t,e,i)=>{t.exports={In:i(91532),Out:i(16518),InOut:i(63180)}},24729:t=>{t.exports=function(t,e,i){if(void 0===e&&(e=.1),void 0===i&&(i=.1),0===t)return 0;if(1===t)return 1;var s=i/4;return e<1?e=1:s=i*Math.asin(1/e)/(2*Math.PI),-e*Math.pow(2,10*(t-=1))*Math.sin((t-s)*(2*Math.PI)/i)}},50325:t=>{t.exports=function(t,e,i){if(void 0===e&&(e=.1),void 0===i&&(i=.1),0===t)return 0;if(1===t)return 1;var s=i/4;return e<1?e=1:s=i*Math.asin(1/e)/(2*Math.PI),(t*=2)<1?e*Math.pow(2,10*(t-=1))*Math.sin((t-s)*(2*Math.PI)/i)*-.5:e*Math.pow(2,-10*(t-=1))*Math.sin((t-s)*(2*Math.PI)/i)*.5+1}},84074:t=>{t.exports=function(t,e,i){if(void 0===e&&(e=.1),void 0===i&&(i=.1),0===t)return 0;if(1===t)return 1;var s=i/4;return e<1?e=1:s=i*Math.asin(1/e)/(2*Math.PI),e*Math.pow(2,-10*t)*Math.sin((t-s)*(2*Math.PI)/i)+1}},36468:(t,e,i)=>{t.exports={In:i(24729),Out:i(84074),InOut:i(50325)}},95638:t=>{t.exports=function(t){return Math.pow(2,10*(t-1))-.001}},10357:t=>{t.exports=function(t){return(t*=2)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*(t-1)))}},14894:t=>{t.exports=function(t){return 1-Math.pow(2,-10*t)}},88258:(t,e,i)=>{t.exports={In:i(95638),Out:i(14894),InOut:i(10357)}},33063:(t,e,i)=>{t.exports={Back:i(25265),Bounce:i(57428),Circular:i(73214),Cubic:i(71778),Elastic:i(36468),Expo:i(88258),Linear:i(52910),Quadratic:i(67799),Quartic:i(74083),Quintic:i(92284),Sine:i(28035),Stepped:i(8754)}},43927:t=>{t.exports=function(t){return t}},52910:(t,e,i)=>{t.exports=i(43927)},77471:t=>{t.exports=function(t){return t*t}},83863:t=>{t.exports=function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)}},44383:t=>{t.exports=function(t){return t*(2-t)}},67799:(t,e,i)=>{t.exports={In:i(77471),Out:i(44383),InOut:i(83863)}},48311:t=>{t.exports=function(t){return t*t*t*t}},55248:t=>{t.exports=function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)}},23135:t=>{t.exports=function(t){return 1- --t*t*t*t}},74083:(t,e,i)=>{t.exports={In:i(48311),Out:i(23135),InOut:i(55248)}},7313:t=>{t.exports=function(t){return t*t*t*t*t}},98759:t=>{t.exports=function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)}},26670:t=>{t.exports=function(t){return--t*t*t*t*t+1}},92284:(t,e,i)=>{t.exports={In:i(7313),Out:i(26670),InOut:i(98759)}},52929:t=>{t.exports=function(t){return 0===t?0:1===t?1:1-Math.cos(t*Math.PI/2)}},66333:t=>{t.exports=function(t){return 0===t?0:1===t?1:.5*(1-Math.cos(Math.PI*t))}},37255:t=>{t.exports=function(t){return 0===t?0:1===t?1:Math.sin(t*Math.PI/2)}},28035:(t,e,i)=>{t.exports={In:i(52929),Out:i(37255),InOut:i(66333)}},52770:t=>{t.exports=function(t,e){return void 0===e&&(e=1),t<=0?0:t>=1?1:1/e*(1+(e*t|0))}},8754:(t,e,i)=>{t.exports=i(52770)},17247:t=>{t.exports=function(t,e){return void 0===e&&(e=1e-4),Math.ceil(t-e)}},88456:t=>{t.exports=function(t,e,i){return void 0===i&&(i=1e-4),Math.abs(t-e){t.exports=function(t,e){return void 0===e&&(e=1e-4),Math.floor(t+e)}},41935:t=>{t.exports=function(t,e,i){return void 0===i&&(i=1e-4),t>e-i}},54726:t=>{t.exports=function(t,e,i){return void 0===i&&(i=1e-4),t{t.exports={Ceil:i(17247),Equal:i(88456),Floor:i(61824),GreaterThan:i(41935),LessThan:i(54726)}},5923:(t,e,i)=>{var s=i(83392),n=i(98611),r={Angle:i(22153),Distance:i(10130),Easing:i(33063),Fuzzy:i(52778),Interpolation:i(48528),Pow2:i(73773),Snap:i(23679),RandomDataGenerator:i(81429),Average:i(26042),Bernstein:i(22824),Between:i(17489),CatmullRom:i(14976),CeilTo:i(89129),Clamp:i(82897),DegToRad:i(75606),Difference:i(767),Euler:i(9849),Factorial:i(8034),FloatBetween:i(61616),FloorTo:i(60679),FromPercent:i(91806),GetSpeed:i(79366),IsEven:i(43776),IsEvenStrict:i(58442),Linear:i(42798),LinearXY:i(61072),MaxAdd:i(69635),Median:i(37394),MinSub:i(17259),Percent:i(61820),RadToDeg:i(23701),RandomXY:i(16906),RandomXYZ:i(52417),RandomXYZW:i(17915),Rotate:i(52257),RotateAround:i(2386),RotateAroundDistance:i(72395),RotateTo:i(41061),RoundAwayFromZero:i(67233),RoundTo:i(64333),SinCosTableGenerator:i(59533),SmootherStep:i(87736),SmoothStep:i(5514),ToXY:i(55805),TransformXY:i(64462),Within:i(9557),Wrap:i(1071),Vector2:i(93736),Vector3:i(70015),Vector4:i(51729),Matrix3:i(5341),Matrix4:i(16650),Quaternion:i(75003),RotateVec3:i(93709)};r=n(!1,r,s),t.exports=r},63210:(t,e,i)=>{var s=i(22824);t.exports=function(t,e){for(var i=0,n=t.length-1,r=0;r<=n;r++)i+=Math.pow(1-e,n-r)*Math.pow(e,r)*t[r]*s(n,r);return i}},88332:(t,e,i)=>{var s=i(14976);t.exports=function(t,e){var i=t.length-1,n=i*e,r=Math.floor(n);return t[0]===t[i]?(e<0&&(r=Math.floor(n=i*(1+e))),s(n-r,t[(r-1+i)%i],t[r],t[(r+1)%i],t[(r+2)%i])):e<0?t[0]-(s(-n,t[0],t[0],t[1],t[1])-t[0]):e>1?t[i]-(s(n-i,t[i],t[i],t[i-1],t[i-1])-t[i]):s(n-r,t[r?r-1:0],t[r],t[i{t.exports=function(t,e,i,s,n){return function(t,e){var i=1-t;return i*i*i*e}(t,e)+function(t,e){var i=1-t;return 3*i*i*t*e}(t,i)+function(t,e){return 3*(1-t)*t*t*e}(t,s)+function(t,e){return t*t*t*e}(t,n)}},47614:(t,e,i)=>{var s=i(42798);t.exports=function(t,e){var i=t.length-1,n=i*e,r=Math.floor(n);return e<0?s(t[0],t[1],n):e>1?s(t[i],t[i-1],i-n):s(t[r],t[r+1>i?i:r+1],n-r)}},16252:t=>{t.exports=function(t,e,i,s){return function(t,e){var i=1-t;return i*i*e}(t,e)+function(t,e){return 2*(1-t)*t*e}(t,i)+function(t,e){return t*t*e}(t,s)}},44521:(t,e,i)=>{var s=i(5514);t.exports=function(t,e,i){return e+(i-e)*s(t,0,1)}},45507:(t,e,i)=>{var s=i(87736);t.exports=function(t,e,i){return e+(i-e)*s(t,0,1)}},48528:(t,e,i)=>{t.exports={Bezier:i(63210),CatmullRom:i(88332),CubicBezier:i(34631),Linear:i(47614),QuadraticBezier:i(16252),SmoothStep:i(44521),SmootherStep:i(45507)}},3504:t=>{t.exports=function(t){var e=Math.log(t)/.6931471805599453;return 1<{t.exports=function(t,e){return t>0&&0==(t&t-1)&&e>0&&0==(e&e-1)}},2018:t=>{t.exports=function(t){return t>0&&0==(t&t-1)}},73773:(t,e,i)=>{t.exports={GetNext:i(3504),IsSize:i(28621),IsValue:i(2018)}},81429:(t,e,i)=>{var s=new(i(56694))({initialize:function(t){void 0===t&&(t=[(Date.now()*Math.random()).toString()]),this.c=1,this.s0=0,this.s1=0,this.s2=0,this.n=0,this.signs=[-1,1],t&&this.init(t)},rnd:function(){var t=2091639*this.s0+2.3283064365386963e-10*this.c;return this.c=0|t,this.s0=this.s1,this.s1=this.s2,this.s2=t-this.c,this.s2},hash:function(t){var e,i=this.n;t=t.toString();for(var s=0;s>>0,i=(e*=i)>>>0,i+=4294967296*(e-=i);return this.n=i,2.3283064365386963e-10*(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;e0;e--){var i=Math.floor(this.frac()*(e+1)),s=t[i];t[i]=t[e],t[e]=s}return t}});t.exports=s},82127:t=>{t.exports=function(t,e,i,s){return void 0===i&&(i=0),0===e?t:(t-=i,t=e*Math.ceil(t/e),s?(i+t)/e:i+t)}},84314:t=>{t.exports=function(t,e,i,s){return void 0===i&&(i=0),0===e?t:(t-=i,t=e*Math.floor(t/e),s?(i+t)/e:i+t)}},88462:t=>{t.exports=function(t,e,i,s){return void 0===i&&(i=0),0===e?t:(t-=i,t=e*Math.round(t/e),s?(i+t)/e:i+t)}},23679:(t,e,i)=>{t.exports={Ceil:i(82127),Floor:i(84314),To:i(88462)}},92491:(t,e,i)=>{i(75205);var s=i(86459),n=i(98611),r={Actions:i(83979),Animations:i(13517),BlendModes:i(95723),Cache:i(45820),Cameras:i(44143),Core:i(80293),Class:i(56694),Create:i(84106),Curves:i(73962),Data:i(1999),Display:i(24816),DOM:i(3590),Events:i(95146),FX:i(96910),Game:i(15213),GameObjects:i(48013),Geom:i(84068),Input:i(20873),Loader:i(95695),Math:i(5923),Physics:i(53954),Plugins:i(45615),Renderer:i(42069),Scale:i(86754),ScaleModes:i(27394),Scene:i(87157),Scenes:i(20436),Structs:i(20010),Textures:i(87499),Tilemaps:i(52678),Time:i(97121),Tweens:i(75193),Utils:i(22178)};r.Sound=i(56751),r=n(!1,r,s),t.exports=r,i.g.Phaser=r},62832:(t,e,i)=>{var s=i(56694),n=i(7864),r=i(1539),o=new s({Extends:r,Mixins:[n.Acceleration,n.Angular,n.Bounce,n.Debug,n.Drag,n.Enable,n.Friction,n.Gravity,n.Immovable,n.Mass,n.Pushable,n.Size,n.Velocity],initialize:function(t,e,i,s,n){r.call(this,t,e,i,s,n),this.body=null}});t.exports=o},66150:(t,e,i)=>{var s=i(56694),n=i(75606),r=i(53996),o=i(35032),a=i(99523),h=i(72632),l=i(30657),u=i(2732),c=i(15147),d=i(91963),f=i(7599),p=i(93736),v=i(85233),g=new s({initialize:function(t){this.scene=t,this.systems=t.sys,this.config=this.getConfig(),this.world,this.add,t.sys.events.once(f.BOOT,this.boot,this),t.sys.events.on(f.START,this.start,this)},boot:function(){this.world=new v(this.scene,this.config),this.add=new a(this.world),this.systems.events.once(f.DESTROY,this.destroy,this)},start:function(){this.world||(this.world=new v(this.scene,this.config),this.add=new a(this.world));var t=this.systems.events;h(this.config,"customUpdate",!1)||t.on(f.UPDATE,this.world.update,this.world),t.on(f.POST_UPDATE,this.world.postUpdate,this.world),t.once(f.SHUTDOWN,this.shutdown,this)},enableUpdate:function(){this.systems.events.on(f.UPDATE,this.world.update,this.world)},disableUpdate:function(){this.systems.events.off(f.UPDATE,this.world.update,this.world)},getConfig:function(){var t=this.systems.game.config.physics,e=this.systems.settings.physics;return l(h(e,"arcade",{}),h(t,"arcade",{}))},overlap:function(t,e,i,s,n){return void 0===i&&(i=null),void 0===s&&(s=null),void 0===n&&(n=i),this.world.collideObjects(t,e,i,s,n,!0)},collide:function(t,e,i,s,n){return void 0===i&&(i=null),void 0===s&&(s=null),void 0===n&&(n=i),this.world.collideObjects(t,e,i,s,n,!1)},collideTiles:function(t,e,i,s,n){return this.world.collideTiles(t,e,i,s,n)},overlapTiles:function(t,e,i,s,n){return this.world.overlapTiles(t,e,i,s,n)},pause:function(){return this.world.pause()},resume:function(){return this.world.resume()},accelerateTo:function(t,e,i,s,n,r){void 0===s&&(s=60);var o=Math.atan2(i-t.y,e-t.x);return t.body.acceleration.setToPolar(o,s),void 0!==n&&void 0!==r&&t.body.maxVelocity.set(n,r),o},accelerateToObject:function(t,e,i,s,n){return this.accelerateTo(t,e.x,e.y,i,s,n)},closest:function(t,e){e||(e=this.world.bodies.entries);for(var i=Number.MAX_VALUE,s=null,n=t.x,r=t.y,a=e.length,h=0;hi&&(s=l,i=c)}}return s},moveTo:function(t,e,i,s,n){void 0===s&&(s=60),void 0===n&&(n=0);var o=Math.atan2(i-t.y,e-t.x);return n>0&&(s=r(t.x,t.y,e,i)/(n/1e3)),t.body.velocity.setToPolar(o,s),o},moveToObject:function(t,e,i,s){return this.moveTo(t,e.x,e.y,i,s)},velocityFromAngle:function(t,e,i){return void 0===e&&(e=60),void 0===i&&(i=new p),i.setToPolar(n(t),e)},velocityFromRotation:function(t,e,i){return void 0===e&&(e=60),void 0===i&&(i=new p),i.setToPolar(t,e)},overlapRect:function(t,e,i,s,n,r){return c(this.world,t,e,i,s,n,r)},overlapCirc:function(t,e,i,s,n){return u(this.world,t,e,i,s,n)},shutdown:function(){if(this.world){var t=this.systems.events;t.off(f.UPDATE,this.world.update,this.world),t.off(f.POST_UPDATE,this.world.postUpdate,this.world),t.off(f.SHUTDOWN,this.shutdown,this),this.add.destroy(),this.world.destroy(),this.add=null,this.world=null}},destroy:function(){this.shutdown(),this.scene.sys.events.off(f.START,this.start,this),this.scene=null,this.systems=null}});d.register("ArcadePhysics",g,"arcadePhysics"),t.exports=g},25084:(t,e,i)=>{var s=i(56694),n=i(7864),r=i(13747),o=new s({Extends:r,Mixins:[n.Acceleration,n.Angular,n.Bounce,n.Debug,n.Drag,n.Enable,n.Friction,n.Gravity,n.Immovable,n.Mass,n.Pushable,n.Size,n.Velocity],initialize:function(t,e,i,s,n){r.call(this,t,e,i,s,n),this.body=null}});t.exports=o},97602:(t,e,i)=>{var s=i(56694),n=i(47401),r=i(27037),o=i(23701),a=i(74118),h=i(94287),l=i(93736),u=new s({initialize:function(t,e){var i=64,s=64,r=void 0!==e;r&&e.displayWidth&&(i=e.displayWidth,s=e.displayHeight),r||(e={x:0,y:0,angle:0,rotation:0,scaleX:1,scaleY:1,displayOriginX:0,displayOriginY:0}),this.world=t,this.gameObject=r?e:void 0,this.isBody=!0,this.transform={x:e.x,y:e.y,rotation:e.angle,scaleX:e.scaleX,scaleY:e.scaleY,displayOriginX:e.displayOriginX,displayOriginY:e.displayOriginY},this.debugShowBody=t.defaults.debugShowBody,this.debugShowVelocity=t.defaults.debugShowVelocity,this.debugBodyColor=t.defaults.bodyDebugColor,this.enable=!0,this.isCircle=!1,this.radius=0,this.offset=new l,this.position=new l(e.x-e.scaleX*e.displayOriginX,e.y-e.scaleY*e.displayOriginY),this.prev=this.position.clone(),this.prevFrame=this.position.clone(),this.allowRotation=!0,this.rotation=e.angle,this.preRotation=e.angle,this.width=i,this.height=s,this.sourceWidth=i,this.sourceHeight=s,e.frame&&(this.sourceWidth=e.frame.realWidth,this.sourceHeight=e.frame.realHeight),this.halfWidth=Math.abs(i/2),this.halfHeight=Math.abs(s/2),this.center=new l(this.position.x+this.halfWidth,this.position.y+this.halfHeight),this.velocity=new l,this.newVelocity=new l,this.deltaMax=new l,this.acceleration=new l,this.allowDrag=!0,this.drag=new l,this.allowGravity=!0,this.gravity=new l,this.bounce=new l,this.worldBounce=null,this.customBoundsRectangle=t.bounds,this.onWorldBounds=!1,this.onCollide=!1,this.onOverlap=!1,this.maxVelocity=new l(1e4,1e4),this.maxSpeed=-1,this.friction=new l(1,0),this.useDamping=!1,this.angularVelocity=0,this.angularAcceleration=0,this.angularDrag=0,this.maxAngular=1e3,this.mass=1,this.angle=0,this.speed=0,this.facing=n.FACING_NONE,this.immovable=!1,this.pushable=!0,this.moves=!0,this.customSeparateX=!1,this.customSeparateY=!1,this.overlapX=0,this.overlapY=0,this.overlapR=0,this.embedded=!1,this.collideWorldBounds=!1,this.checkCollision={none:!1,up:!0,down:!0,left:!0,right:!0},this.touching={none:!0,up:!1,down:!1,left:!1,right:!1},this.wasTouching={none:!0,up:!1,down:!1,left:!1,right:!1},this.blocked={none:!0,up:!1,down:!1,left:!1,right:!1},this.syncBounds=!1,this.physicsType=n.DYNAMIC_BODY,this._sx=e.scaleX,this._sy=e.scaleY,this._dx=0,this._dy=0,this._tx=0,this._ty=0,this._bounds=new a},updateBounds:function(){var t=this.gameObject,e=this.transform;if(t.parentContainer){var i=t.getWorldTransformMatrix(this.world._tempMatrix,this.world._tempMatrix2);e.x=i.tx,e.y=i.ty,e.rotation=o(i.rotation),e.scaleX=i.scaleX,e.scaleY=i.scaleY,e.displayOriginX=t.displayOriginX,e.displayOriginY=t.displayOriginY}else e.x=t.x,e.y=t.y,e.rotation=t.angle,e.scaleX=t.scaleX,e.scaleY=t.scaleY,e.displayOriginX=t.displayOriginX,e.displayOriginY=t.displayOriginY;var s=!1;if(this.syncBounds){var n=t.getBounds(this._bounds);this.width=n.width,this.height=n.height,s=!0}else{var r=Math.abs(e.scaleX),a=Math.abs(e.scaleY);this._sx===r&&this._sy===a||(this.width=this.sourceWidth*r,this.height=this.sourceHeight*a,this._sx=r,this._sy=a,s=!0)}s&&(this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this.updateCenter())},updateCenter:function(){this.center.set(this.position.x+this.halfWidth,this.position.y+this.halfHeight)},updateFromGameObject:function(){this.updateBounds();var t=this.transform;this.position.x=t.x+t.scaleX*(this.offset.x-t.displayOriginX),this.position.y=t.y+t.scaleY*(this.offset.y-t.displayOriginY),this.updateCenter()},resetFlags:function(t){void 0===t&&(t=!1);var e=this.wasTouching,i=this.touching,s=this.blocked;t?(e.none=!0,e.up=!1,e.down=!1,e.left=!1,e.right=!1):(e.none=i.none,e.up=i.up,e.down=i.down,e.left=i.left,e.right=i.right),i.none=!0,i.up=!1,i.down=!1,i.left=!1,i.right=!1,s.none=!0,s.up=!1,s.down=!1,s.left=!1,s.right=!1,this.overlapR=0,this.overlapX=0,this.overlapY=0,this.embedded=!1},preUpdate:function(t,e){t&&this.resetFlags(),this.gameObject&&this.updateFromGameObject(),this.rotation=this.transform.rotation,this.preRotation=this.rotation,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),t&&this.update(e)},update:function(t){if(this.prev.x=this.position.x,this.prev.y=this.position.y,this.moves){this.world.updateMotion(this,t);var e=this.velocity.x,i=this.velocity.y;this.newVelocity.set(e*t,i*t),this.position.add(this.newVelocity),this.updateCenter(),this.angle=Math.atan2(i,e),this.speed=Math.sqrt(e*e+i*i),this.collideWorldBounds&&this.checkWorldBounds()&&this.onWorldBounds&&this.world.emit(r.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},postUpdate:function(){var t=this.position.x-this.prevFrame.x,e=this.position.y-this.prevFrame.y,i=this.gameObject;if(this.moves){var s=this.deltaMax.x,r=this.deltaMax.y;0!==s&&0!==t&&(t<0&&t<-s?t=-s:t>0&&t>s&&(t=s)),0!==r&&0!==e&&(e<0&&e<-r?e=-r:e>0&&e>r&&(e=r)),i&&(i.x+=t,i.y+=e)}t<0?this.facing=n.FACING_LEFT:t>0&&(this.facing=n.FACING_RIGHT),e<0?this.facing=n.FACING_UP:e>0&&(this.facing=n.FACING_DOWN),this.allowRotation&&i&&(i.angle+=this.deltaZ()),this._tx=t,this._ty=e},setBoundsRectangle:function(t){return this.customBoundsRectangle=t||this.world.bounds,this},checkWorldBounds:function(){var t=this.position,e=this.customBoundsRectangle,i=this.world.checkCollision,s=this.worldBounce?-this.worldBounce.x:-this.bounce.x,n=this.worldBounce?-this.worldBounce.y:-this.bounce.y,r=!1;return t.xe.right&&i.right&&(t.x=e.right-this.width,this.velocity.x*=s,this.blocked.right=!0,r=!0),t.ye.bottom&&i.down&&(t.y=e.bottom-this.height,this.velocity.y*=n,this.blocked.down=!0,r=!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},setGameObject:function(t,e){return void 0===e&&(e=!0),this.world.remove(this),this.gameObject&&this.gameObject.body&&(this.gameObject.body=null),this.gameObject=t,t.body&&(t.body=this),this.setSize(),this.world.add(this),this.enable=e,this},setSize:function(t,e,i){void 0===i&&(i=!0);var s=this.gameObject;if(s&&(!t&&s.frame&&(t=s.frame.realWidth),!e&&s.frame&&(e=s.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&&s&&s.getCenter){var n=(s.width-t)/2,r=(s.height-e)/2;this.offset.set(n,r)}return 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),t>0?(this.isCircle=!0,this.radius=t,this.sourceWidth=2*t,this.sourceHeight=2*t,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(e,i),this.updateCenter()):this.isCircle=!1,this},reset:function(t,e){this.stop();var i=this.gameObject;i&&(i.setPosition(t,e),this.rotation=i.angle,this.preRotation=i.angle);var s=this.position;i&&i.getTopLeft?i.getTopLeft(s):s.set(t,e),this.prev.copy(s),this.prevFrame.copy(s),i&&this.updateBounds(),this.updateCenter(),this.collideWorldBounds&&this.checkWorldBounds(),this.resetFlags(!0)},stop:function(){return this.velocity.set(0),this.acceleration.set(0),this.speed=0,this.angularVelocity=0,this.angularAcceleration=0,this},getBounds:function(t){return t.x=this.x,t.y=this.y,t.right=this.right,t.bottom=this.bottom,t},hitTest:function(t,e){return this.isCircle?this.radius>0&&t>=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 this._dx>0?this._dx:-this._dx},deltaAbsY:function(){return this._dy>0?this._dy:-this._dy},deltaX:function(){return this._dx},deltaY:function(){return this._dy},deltaXFinal:function(){return this._tx},deltaYFinal:function(){return this._ty},deltaZ:function(){return this.rotation-this.preRotation},destroy:function(){this.enable=!1,this.world&&this.world.pendingDestroy.set(this)},drawDebug:function(t){var e=this.position,i=e.x+this.halfWidth,s=e.y+this.halfHeight;this.debugShowBody&&(t.lineStyle(t.defaultStrokeWidth,this.debugBodyColor),this.isCircle?t.strokeCircle(i,s,this.width/2):(this.checkCollision.up&&t.lineBetween(e.x,e.y,e.x+this.width,e.y),this.checkCollision.right&&t.lineBetween(e.x+this.width,e.y,e.x+this.width,e.y+this.height),this.checkCollision.down&&t.lineBetween(e.x,e.y+this.height,e.x+this.width,e.y+this.height),this.checkCollision.left&&t.lineBetween(e.x,e.y,e.x,e.y+this.height))),this.debugShowVelocity&&(t.lineStyle(t.defaultStrokeWidth,this.world.defaults.velocityDebugColor,1),t.lineBetween(i,s,i+this.velocity.x/2,s+this.velocity.y/2))},willDrawDebug:function(){return this.debugShowBody||this.debugShowVelocity},setCollideWorldBounds:function(t,e,i,s){void 0===t&&(t=!0),this.collideWorldBounds=t;var n=void 0!==e,r=void 0!==i;return(n||r)&&(this.worldBounce||(this.worldBounce=new l),n&&(this.worldBounce.x=e),r&&(this.worldBounce.y=i)),void 0!==s&&(this.onWorldBounds=s),this},setVelocity:function(t,e){return this.velocity.set(t,e),t=this.velocity.x,e=this.velocity.y,this.speed=Math.sqrt(t*t+e*e),this},setVelocityX:function(t){return this.setVelocity(t,this.velocity.y)},setVelocityY:function(t){return this.setVelocity(this.velocity.x,t)},setMaxVelocity:function(t,e){return this.maxVelocity.set(t,e),this},setMaxVelocityX:function(t){return this.maxVelocity.x=t,this},setMaxVelocityY:function(t){return this.maxVelocity.y=t,this},setMaxSpeed:function(t){return this.maxSpeed=t,this},setBounce:function(t,e){return this.bounce.set(t,e),this},setBounceX:function(t){return this.bounce.x=t,this},setBounceY:function(t){return this.bounce.y=t,this},setAcceleration:function(t,e){return this.acceleration.set(t,e),this},setAccelerationX:function(t){return this.acceleration.x=t,this},setAccelerationY:function(t){return this.acceleration.y=t,this},setAllowDrag:function(t){return void 0===t&&(t=!0),this.allowDrag=t,this},setAllowGravity:function(t){return void 0===t&&(t=!0),this.allowGravity=t,this},setAllowRotation:function(t){return void 0===t&&(t=!0),this.allowRotation=t,this},setDrag:function(t,e){return this.drag.set(t,e),this},setDamping:function(t){return this.useDamping=t,this},setDragX:function(t){return this.drag.x=t,this},setDragY:function(t){return this.drag.y=t,this},setGravity:function(t,e){return this.gravity.set(t,e),this},setGravityX:function(t){return this.gravity.x=t,this},setGravityY:function(t){return this.gravity.y=t,this},setFriction:function(t,e){return this.friction.set(t,e),this},setFrictionX:function(t){return this.friction.x=t,this},setFrictionY:function(t){return this.friction.y=t,this},setAngularVelocity:function(t){return this.angularVelocity=t,this},setAngularAcceleration:function(t){return this.angularAcceleration=t,this},setAngularDrag:function(t){return this.angularDrag=t,this},setMass:function(t){return this.mass=t,this},setImmovable:function(t){return void 0===t&&(t=!0),this.immovable=t,this},setEnable:function(t){return void 0===t&&(t=!0),this.enable=t,this},processX:function(t,e,i,s){this.x+=t,this.updateCenter(),null!==e&&(this.velocity.x=e);var n=this.blocked;i&&(n.left=!0,n.none=!1),s&&(n.right=!0,n.none=!1)},processY:function(t,e,i,s){this.y+=t,this.updateCenter(),null!==e&&(this.velocity.y=e);var n=this.blocked;i&&(n.up=!0,n.none=!1),s&&(n.down=!0,n.none=!1)},x:{get:function(){return this.position.x},set:function(t){this.position.x=t}},y:{get:function(){return this.position.y},set:function(t){this.position.y=t}},left:{get:function(){return this.position.x}},right:{get:function(){return this.position.x+this.width}},top:{get:function(){return this.position.y}},bottom:{get:function(){return this.position.y+this.height}}});t.exports=u},3909:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e,i,s,n,r,o){this.world=t,this.name="",this.active=!0,this.overlapOnly=e,this.object1=i,this.object2=s,this.collideCallback=n,this.processCallback=r,this.callbackContext=o},setName:function(t){return this.name=t,this},update:function(){this.world.collideObjects(this.object1,this.object2,this.collideCallback,this.processCallback,this.callbackContext,this.overlapOnly)},destroy:function(){this.world.removeCollider(this),this.active=!1,this.world=null,this.object1=null,this.object2=null,this.collideCallback=null,this.processCallback=null,this.callbackContext=null}});t.exports=s},99523:(t,e,i)=>{var s=i(62832),n=i(25084),r=i(97602),o=i(56694),a=i(47401),h=i(10481),l=i(66634),u=i(46346),c=new o({initialize:function(t){this.world=t,this.scene=t.scene,this.sys=t.scene.sys},collider:function(t,e,i,s,n){return this.world.addCollider(t,e,i,s,n)},overlap:function(t,e,i,s,n){return this.world.addOverlap(t,e,i,s,n)},existing:function(t,e){var i=e?a.STATIC_BODY:a.DYNAMIC_BODY;return this.world.enableBody(t,i),t},staticImage:function(t,e,i,n){var r=new s(this.scene,t,e,i,n);return this.sys.displayList.add(r),this.world.enableBody(r,a.STATIC_BODY),r},image:function(t,e,i,n){var r=new s(this.scene,t,e,i,n);return this.sys.displayList.add(r),this.world.enableBody(r,a.DYNAMIC_BODY),r},staticSprite:function(t,e,i,s){var r=new n(this.scene,t,e,i,s);return this.sys.displayList.add(r),this.sys.updateList.add(r),this.world.enableBody(r,a.STATIC_BODY),r},sprite:function(t,e,i,s){var r=new n(this.scene,t,e,i,s);return this.sys.displayList.add(r),this.sys.updateList.add(r),this.world.enableBody(r,a.DYNAMIC_BODY),r},staticGroup:function(t,e){return this.sys.updateList.add(new u(this.world,this.world.scene,t,e))},group:function(t,e){return this.sys.updateList.add(new h(this.world,this.world.scene,t,e))},body:function(t,e,i,s){var n=new r(this.world);return n.position.set(t,e),i&&s&&n.setSize(i,s),this.world.add(n,a.DYNAMIC_BODY),n},staticBody:function(t,e,i,s){var n=new l(this.world);return n.position.set(t,e),i&&s&&n.setSize(i,s),this.world.add(n,a.STATIC_BODY),n},destroy:function(){this.world=null,this.scene=null,this.sys=null}});t.exports=c},75671:(t,e,i)=>{var s=i(47401);t.exports=function(t,e,i,n){var r=0,o=t.deltaAbsX()+e.deltaAbsX()+n;return 0===t._dx&&0===e._dx?(t.embedded=!0,e.embedded=!0):t._dx>e._dx?(r=t.right-e.x)>o&&!i||!1===t.checkCollision.right||!1===e.checkCollision.left?r=0:(t.touching.none=!1,t.touching.right=!0,e.touching.none=!1,e.touching.left=!0,e.physicsType!==s.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.right=!0),t.physicsType!==s.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.left=!0)):t._dxo&&!i||!1===t.checkCollision.left||!1===e.checkCollision.right?r=0:(t.touching.none=!1,t.touching.left=!0,e.touching.none=!1,e.touching.right=!0,e.physicsType!==s.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.left=!0),t.physicsType!==s.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.right=!0))),t.overlapX=r,e.overlapX=r,r}},66185:(t,e,i)=>{var s=i(47401);t.exports=function(t,e,i,n){var r=0,o=t.deltaAbsY()+e.deltaAbsY()+n;return 0===t._dy&&0===e._dy?(t.embedded=!0,e.embedded=!0):t._dy>e._dy?(r=t.bottom-e.y)>o&&!i||!1===t.checkCollision.down||!1===e.checkCollision.up?r=0:(t.touching.none=!1,t.touching.down=!0,e.touching.none=!1,e.touching.up=!0,e.physicsType!==s.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.down=!0),t.physicsType!==s.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.up=!0)):t._dyo&&!i||!1===t.checkCollision.up||!1===e.checkCollision.down?r=0:(t.touching.none=!1,t.touching.up=!0,e.touching.none=!1,e.touching.down=!0,e.physicsType!==s.STATIC_BODY||i||(t.blocked.none=!1,t.blocked.up=!0),t.physicsType!==s.STATIC_BODY||i||(e.blocked.none=!1,e.blocked.down=!0))),t.overlapY=r,e.overlapY=r,r}},10481:(t,e,i)=>{var s=i(25084),n=i(56694),r=i(47401),o=i(72632),a=i(59192),h=i(42911),l=new n({Extends:a,initialize:function(t,e,i,n){if(i||n)if(h(i))n=i,i=null,n.internalCreateCallback=this.createCallbackHandler,n.internalRemoveCallback=this.removeCallbackHandler;else if(Array.isArray(i)&&h(i[0])){n=i[0];var l=this;i.forEach((function(t){t.internalCreateCallback=l.createCallbackHandler,t.internalRemoveCallback=l.removeCallbackHandler})),i=null}else n={internalCreateCallback:this.createCallbackHandler,internalRemoveCallback:this.removeCallbackHandler};else n={internalCreateCallback:this.createCallbackHandler,internalRemoveCallback:this.removeCallbackHandler};this.world=t,n.classType=o(n,"classType",s),this.physicsType=r.DYNAMIC_BODY,this.defaults={setCollideWorldBounds:o(n,"collideWorldBounds",!1),setBoundsRectangle:o(n,"customBoundsRectangle",null),setAccelerationX:o(n,"accelerationX",0),setAccelerationY:o(n,"accelerationY",0),setAllowDrag:o(n,"allowDrag",!0),setAllowGravity:o(n,"allowGravity",!0),setAllowRotation:o(n,"allowRotation",!0),setDamping:o(n,"useDamping",!1),setBounceX:o(n,"bounceX",0),setBounceY:o(n,"bounceY",0),setDragX:o(n,"dragX",0),setDragY:o(n,"dragY",0),setEnable:o(n,"enable",!0),setGravityX:o(n,"gravityX",0),setGravityY:o(n,"gravityY",0),setFrictionX:o(n,"frictionX",0),setFrictionY:o(n,"frictionY",0),setMaxSpeed:o(n,"maxSpeed",-1),setMaxVelocityX:o(n,"maxVelocityX",1e4),setMaxVelocityY:o(n,"maxVelocityY",1e4),setVelocityX:o(n,"velocityX",0),setVelocityY:o(n,"velocityY",0),setAngularVelocity:o(n,"angularVelocity",0),setAngularAcceleration:o(n,"angularAcceleration",0),setAngularDrag:o(n,"angularDrag",0),setMass:o(n,"mass",1),setImmovable:o(n,"immovable",!1)},a.call(this,e,i,n),this.type="PhysicsGroup"},createCallbackHandler:function(t){t.body||this.world.enableBody(t,r.DYNAMIC_BODY);var e=t.body;for(var i in this.defaults)e[i](this.defaults[i])},removeCallbackHandler:function(t){t.body&&this.world.disableBody(t)},setVelocity:function(t,e,i){void 0===i&&(i=0);for(var s=this.getChildren(),n=0;n{var e,i,s,n,r,o,a,h,l,u,c,d,f,p,v,g,m,y=function(){return u&&v&&i.blocked.right?(e.processX(-m,a,!1,!0),1):l&&g&&i.blocked.left?(e.processX(m,a,!0),1):f&&g&&e.blocked.right?(i.processX(-m,h,!1,!0),2):d&&v&&e.blocked.left?(i.processX(m,h,!0),2):0},x=function(t){if(s&&n)m*=.5,0===t||3===t?(e.processX(m,r),i.processX(-m,o)):(e.processX(-m,r),i.processX(m,o));else if(s&&!n)0===t||3===t?e.processX(m,a,!0):e.processX(-m,a,!1,!0);else if(!s&&n)0===t||3===t?i.processX(-m,h,!1,!0):i.processX(m,h,!0);else{var v=.5*m;0===t?p?(e.processX(m,0,!0),i.processX(0,null,!1,!0)):f?(e.processX(v,0,!0),i.processX(-v,0,!1,!0)):(e.processX(v,i.velocity.x,!0),i.processX(-v,null,!1,!0)):1===t?c?(e.processX(0,null,!1,!0),i.processX(m,0,!0)):u?(e.processX(-v,0,!1,!0),i.processX(v,0,!0)):(e.processX(-v,null,!1,!0),i.processX(v,e.velocity.x,!0)):2===t?p?(e.processX(-m,0,!1,!0),i.processX(0,null,!0)):d?(e.processX(-v,0,!1,!0),i.processX(v,0,!0)):(e.processX(-v,i.velocity.x,!1,!0),i.processX(v,null,!0)):3===t&&(c?(e.processX(0,null,!0),i.processX(-m,0,!1,!0)):l?(e.processX(v,0,!0),i.processX(-v,0,!1,!0)):(e.processX(v,i.velocity.y,!0),i.processX(-v,null,!1,!0)))}return!0};t.exports={BlockCheck:y,Check:function(){var t=e.velocity.x,s=i.velocity.x,n=Math.sqrt(s*s*i.mass/e.mass)*(s>0?1:-1),a=Math.sqrt(t*t*e.mass/i.mass)*(t>0?1:-1),h=.5*(n+a);return a-=h,r=h+(n-=h)*e.bounce.x,o=h+a*i.bounce.x,l&&g?x(0):d&&v?x(1):u&&v?x(2):!(!f||!g)&&x(3)},Set:function(t,r,o){i=r;var x=(e=t).velocity.x,T=i.velocity.x;return s=e.pushable,l=e._dx<0,u=e._dx>0,c=0===e._dx,v=Math.abs(e.right-i.x)<=Math.abs(i.right-e.x),a=T-x*e.bounce.x,n=i.pushable,d=i._dx<0,f=i._dx>0,p=0===i._dx,g=!v,h=x-T*i.bounce.x,m=Math.abs(o),y()},Run:x,RunImmovableBody1:function(t){1===t?i.velocity.x=0:v?i.processX(m,h,!0):i.processX(-m,h,!1,!0),e.moves&&(i.y+=(e.y-e.prev.y)*e.friction.y,i._dy=i.y-i.prev.y)},RunImmovableBody2:function(t){2===t?e.velocity.x=0:g?e.processX(m,a,!0):e.processX(-m,a,!1,!0),i.moves&&(e.y+=(i.y-i.prev.y)*i.friction.y,e._dy=e.y-e.prev.y)}}},67050:t=>{var e,i,s,n,r,o,a,h,l,u,c,d,f,p,v,g,m,y=function(){return u&&v&&i.blocked.down?(e.processY(-m,a,!1,!0),1):l&&g&&i.blocked.up?(e.processY(m,a,!0),1):f&&g&&e.blocked.down?(i.processY(-m,h,!1,!0),2):d&&v&&e.blocked.up?(i.processY(m,h,!0),2):0},x=function(t){if(s&&n)m*=.5,0===t||3===t?(e.processY(m,r),i.processY(-m,o)):(e.processY(-m,r),i.processY(m,o));else if(s&&!n)0===t||3===t?e.processY(m,a,!0):e.processY(-m,a,!1,!0);else if(!s&&n)0===t||3===t?i.processY(-m,h,!1,!0):i.processY(m,h,!0);else{var v=.5*m;0===t?p?(e.processY(m,0,!0),i.processY(0,null,!1,!0)):f?(e.processY(v,0,!0),i.processY(-v,0,!1,!0)):(e.processY(v,i.velocity.y,!0),i.processY(-v,null,!1,!0)):1===t?c?(e.processY(0,null,!1,!0),i.processY(m,0,!0)):u?(e.processY(-v,0,!1,!0),i.processY(v,0,!0)):(e.processY(-v,null,!1,!0),i.processY(v,e.velocity.y,!0)):2===t?p?(e.processY(-m,0,!1,!0),i.processY(0,null,!0)):d?(e.processY(-v,0,!1,!0),i.processY(v,0,!0)):(e.processY(-v,i.velocity.y,!1,!0),i.processY(v,null,!0)):3===t&&(c?(e.processY(0,null,!0),i.processY(-m,0,!1,!0)):l?(e.processY(v,0,!0),i.processY(-v,0,!1,!0)):(e.processY(v,i.velocity.y,!0),i.processY(-v,null,!1,!0)))}return!0};t.exports={BlockCheck:y,Check:function(){var t=e.velocity.y,s=i.velocity.y,n=Math.sqrt(s*s*i.mass/e.mass)*(s>0?1:-1),a=Math.sqrt(t*t*e.mass/i.mass)*(t>0?1:-1),h=.5*(n+a);return a-=h,r=h+(n-=h)*e.bounce.y,o=h+a*i.bounce.y,l&&g?x(0):d&&v?x(1):u&&v?x(2):!(!f||!g)&&x(3)},Set:function(t,r,o){i=r;var x=(e=t).velocity.y,T=i.velocity.y;return s=e.pushable,l=e._dy<0,u=e._dy>0,c=0===e._dy,v=Math.abs(e.bottom-i.y)<=Math.abs(i.bottom-e.y),a=T-x*e.bounce.y,n=i.pushable,d=i._dy<0,f=i._dy>0,p=0===i._dy,g=!v,h=x-T*i.bounce.y,m=Math.abs(o),y()},Run:x,RunImmovableBody1:function(t){1===t?i.velocity.y=0:v?i.processY(m,h,!0):i.processY(-m,h,!1,!0),e.moves&&(i.x+=(e.x-e.prev.x)*e.friction.x,i._dx=i.x-i.prev.x)},RunImmovableBody2:function(t){2===t?e.velocity.y=0:g?e.processY(m,a,!0):e.processY(-m,a,!1,!0),i.moves&&(e.x+=(i.x-i.prev.x)*i.friction.x,e._dx=e.x-e.prev.x)}}},61777:(t,e,i)=>{var s=i(75671),n=i(22916);t.exports=function(t,e,i,r,o){void 0===o&&(o=s(t,e,i,r));var a=t.immovable,h=e.immovable;if(i||0===o||a&&h||t.customSeparateX||e.customSeparateX)return 0!==o||t.embedded&&e.embedded;var l=n.Set(t,e,o);return a||h?(a?n.RunImmovableBody1(l):h&&n.RunImmovableBody2(l),!0):l>0||n.Check()}},25299:(t,e,i)=>{var s=i(66185),n=i(67050);t.exports=function(t,e,i,r,o){void 0===o&&(o=s(t,e,i,r));var a=t.immovable,h=e.immovable;if(i||0===o||a&&h||t.customSeparateY||e.customSeparateY)return 0!==o||t.embedded&&e.embedded;var l=n.Set(t,e,o);return a||h?(a?n.RunImmovableBody1(l):h&&n.RunImmovableBody2(l),!0):l>0||n.Check()}},66634:(t,e,i)=>{var s=i(65650),n=i(56694),r=i(47401),o=i(94287),a=i(93736),h=new n({initialize:function(t,e){var i=64,s=64,n=void 0!==e;n&&e.displayWidth&&(i=e.displayWidth,s=e.displayHeight),n||(e={x:0,y:0,angle:0,rotation:0,scaleX:1,scaleY:1,displayOriginX:0,displayOriginY:0}),this.world=t,this.gameObject=n?e:void 0,this.isBody=!0,this.debugShowBody=t.defaults.debugShowStaticBody,this.debugBodyColor=t.defaults.staticBodyDebugColor,this.enable=!0,this.isCircle=!1,this.radius=0,this.offset=new a,this.position=new a(e.x-i*e.originX,e.y-s*e.originY),this.width=i,this.height=s,this.halfWidth=Math.abs(this.width/2),this.halfHeight=Math.abs(this.height/2),this.center=new a(this.position.x+this.halfWidth,this.position.y+this.halfHeight),this.velocity=a.ZERO,this.allowGravity=!1,this.gravity=a.ZERO,this.bounce=a.ZERO,this.onWorldBounds=!1,this.onCollide=!1,this.onOverlap=!1,this.mass=1,this.immovable=!0,this.pushable=!1,this.customSeparateX=!1,this.customSeparateY=!1,this.overlapX=0,this.overlapY=0,this.overlapR=0,this.embedded=!1,this.collideWorldBounds=!1,this.checkCollision={none:!1,up:!0,down:!0,left:!0,right:!0},this.touching={none:!0,up:!1,down:!1,left:!1,right:!1},this.wasTouching={none:!0,up:!1,down:!1,left:!1,right:!1},this.blocked={none:!0,up:!1,down:!1,left:!1,right:!1},this.physicsType=r.STATIC_BODY,this._dx=0,this._dy=0},setGameObject:function(t,e){return t&&t!==this.gameObject&&(this.gameObject.body=null,t.body=this,this.gameObject=t),e&&this.updateFromGameObject(),this},updateFromGameObject:function(){this.world.staticTree.remove(this);var t=this.gameObject;return t.getTopLeft(this.position),this.width=t.displayWidth,this.height=t.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),this},setOffset:function(t,e){return void 0===e&&(e=t),this.world.staticTree.remove(this),this.position.x-=this.offset.x,this.position.y-=this.offset.y,this.offset.set(t,e),this.position.x+=this.offset.x,this.position.y+=this.offset.y,this.updateCenter(),this.world.staticTree.insert(this),this},setSize:function(t,e,i){void 0===i&&(i=!0);var s=this.gameObject;if(!t&&s.frame&&(t=s.frame.realWidth),!e&&s.frame&&(e=s.frame.realHeight),this.world.staticTree.remove(this),this.width=t,this.height=e,this.halfWidth=Math.floor(t/2),this.halfHeight=Math.floor(e/2),i&&s.getCenter){var n=s.displayWidth/2,r=s.displayHeight/2;this.position.x-=this.offset.x,this.position.y-=this.offset.y,this.offset.set(n-this.halfWidth,r-this.halfHeight),this.position.x+=this.offset.x,this.position.y+=this.offset.y}return this.updateCenter(),this.isCircle=!1,this.radius=0,this.world.staticTree.insert(this),this},setCircle:function(t,e,i){return void 0===e&&(e=this.offset.x),void 0===i&&(i=this.offset.y),t>0?(this.world.staticTree.remove(this),this.isCircle=!0,this.radius=t,this.width=2*t,this.height=2*t,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this.offset.set(e,i),this.updateCenter(),this.world.staticTree.insert(this)):this.isCircle=!1,this},updateCenter:function(){this.center.set(this.position.x+this.halfWidth,this.position.y+this.halfHeight)},reset:function(t,e){var i=this.gameObject;void 0===t&&(t=i.x),void 0===e&&(e=i.y),this.world.staticTree.remove(this),i.setPosition(t,e),i.getTopLeft(this.position),this.updateCenter(),this.world.staticTree.insert(this)},stop:function(){return this},getBounds:function(t){return t.x=this.x,t.y=this.y,t.right=this.right,t.bottom=this.bottom,t},hitTest:function(t,e){return this.isCircle?s(this,t,e):o(this,t,e)},postUpdate:function(){},deltaAbsX:function(){return 0},deltaAbsY:function(){return 0},deltaX:function(){return 0},deltaY:function(){return 0},deltaZ:function(){return 0},destroy:function(){this.enable=!1,this.world.pendingDestroy.set(this)},drawDebug:function(t){var e=this.position,i=e.x+this.halfWidth,s=e.y+this.halfHeight;this.debugShowBody&&(t.lineStyle(t.defaultStrokeWidth,this.debugBodyColor,1),this.isCircle?t.strokeCircle(i,s,this.width/2):t.strokeRect(e.x,e.y,this.width,this.height))},willDrawDebug:function(){return this.debugShowBody},setMass:function(t){return t<=0&&(t=.1),this.mass=t,this},x:{get:function(){return this.position.x},set:function(t){this.world.staticTree.remove(this),this.position.x=t,this.world.staticTree.insert(this)}},y:{get:function(){return this.position.y},set:function(t){this.world.staticTree.remove(this),this.position.y=t,this.world.staticTree.insert(this)}},left:{get:function(){return this.position.x}},right:{get:function(){return this.position.x+this.width}},top:{get:function(){return this.position.y}},bottom:{get:function(){return this.position.y+this.height}}});t.exports=h},46346:(t,e,i)=>{var s=i(25084),n=i(56694),r=i(47401),o=i(72632),a=i(59192),h=i(42911),l=new n({Extends:a,initialize:function(t,e,i,n){i||n?h(i)?(n=i,i=null,n.internalCreateCallback=this.createCallbackHandler,n.internalRemoveCallback=this.removeCallbackHandler,n.createMultipleCallback=this.createMultipleCallbackHandler,n.classType=o(n,"classType",s)):Array.isArray(i)&&h(i[0])?(n=i,i=null,n.forEach((function(t){t.internalCreateCallback=this.createCallbackHandler,t.internalRemoveCallback=this.removeCallbackHandler,t.createMultipleCallback=this.createMultipleCallbackHandler,t.classType=o(t,"classType",s)}))):n={internalCreateCallback:this.createCallbackHandler,internalRemoveCallback:this.removeCallbackHandler}:n={internalCreateCallback:this.createCallbackHandler,internalRemoveCallback:this.removeCallbackHandler,createMultipleCallback:this.createMultipleCallbackHandler,classType:s},this.world=t,this.physicsType=r.STATIC_BODY,a.call(this,e,i,n),this.type="StaticPhysicsGroup"},createCallbackHandler:function(t){t.body||this.world.enableBody(t,r.STATIC_BODY)},removeCallbackHandler:function(t){t.body&&this.world.disableBody(t)},createMultipleCallbackHandler:function(){this.refresh()},refresh:function(){for(var t=this.children.entries,e=0;e{var s=i(94240),n=i(97602),r=i(82897),o=i(56694),a=i(3909),h=i(47401),l=i(53996),u=i(92951),c=i(6659),d=i(27037),f=i(88456),p=i(41935),v=i(54726),g=i(75671),m=i(66185),y=i(44662),x=i(10850),T=i(83392),w=i(74623),b=i(25163),S=i(74118),E=i(68687),A=i(27354),C=i(61777),_=i(25299),M=i(58403),P=i(66634),R=i(28808),O=i(69360),L=i(93736),F=i(1071),D=new o({Extends:c,initialize:function(t,e){c.call(this),this.scene=t,this.bodies=new M,this.staticBodies=new M,this.pendingDestroy=new M,this.colliders=new w,this.gravity=new L(x(e,"gravity.x",0),x(e,"gravity.y",0)),this.bounds=new S(x(e,"x",0),x(e,"y",0),x(e,"width",t.sys.scale.width),x(e,"height",t.sys.scale.height)),this.checkCollision={up:x(e,"checkCollision.up",!0),down:x(e,"checkCollision.down",!0),left:x(e,"checkCollision.left",!0),right:x(e,"checkCollision.right",!0)},this.fps=x(e,"fps",60),this.fixedStep=x(e,"fixedStep",!0),this._elapsed=0,this._frameTime=1/this.fps,this._frameTimeMS=1e3*this._frameTime,this.stepsLastFrame=0,this.timeScale=x(e,"timeScale",1),this.OVERLAP_BIAS=x(e,"overlapBias",4),this.TILE_BIAS=x(e,"tileBias",16),this.forceX=x(e,"forceX",!1),this.isPaused=x(e,"isPaused",!1),this._total=0,this.drawDebug=x(e,"debug",!1),this.debugGraphic,this.defaults={debugShowBody:x(e,"debugShowBody",!0),debugShowStaticBody:x(e,"debugShowStaticBody",!0),debugShowVelocity:x(e,"debugShowVelocity",!0),bodyDebugColor:x(e,"debugBodyColor",16711935),staticBodyDebugColor:x(e,"debugStaticBodyColor",255),velocityDebugColor:x(e,"debugVelocityColor",65280)},this.maxEntries=x(e,"maxEntries",16),this.useTree=x(e,"useTree",!0),this.tree=new E(this.maxEntries),this.staticTree=new E(this.maxEntries),this.treeMinMax={minX:0,minY:0,maxX:0,maxY:0},this._tempMatrix=new O,this._tempMatrix2=new O,this.tileFilterOptions={isColliding:!0,isNotEmpty:!0,hasInterestingFace:!0},this.drawDebug&&this.createDebugGraphic()},enable:function(t,e){void 0===e&&(e=h.DYNAMIC_BODY),Array.isArray(t)||(t=[t]);for(var i=0;i=r;for(this.fixedStep||(n=.001*e,a=!0,this._elapsed=0),i=0;i=r;)this._elapsed-=r,this.step(n)}},step:function(t){var e,i,s=this.bodies.entries,n=s.length;for(e=0;e0){var l=this.tree,u=this.staticTree;for(s=(i=a.entries).length,t=0;t-1&&t.velocity.length()>d&&(t.velocity.normalize().scale(d),c=d),t.speed=c},separate:function(t,e,i,s,n){var r,o,a=!1,h=!0;if(!t.enable||!e.enable||t.checkCollision.none||e.checkCollision.none||!this.intersects(t,e))return a;if(i&&!1===i.call(s,t.gameObject,e.gameObject))return a;if(t.isCircle||e.isCircle){var l=this.separateCircle(t,e,n);l.result?(a=!0,h=!1):(r=l.x,o=l.y,h=!0)}if(h){var u=!1,c=!1,f=this.OVERLAP_BIAS;n?(u=C(t,e,n,f,r),c=_(t,e,n,f,o)):this.forceX||Math.abs(this.gravity.y+t.gravity.y)E&&(p=l(y,x,E,S)-w):x>A&&(yE&&(p=l(y,x,E,A)-w)),p*=-1}else p=t.halfWidth+e.halfWidth-u(o,a);t.overlapR=p,e.overlapR=p;var C=s(o,a),_=(p+T.EPSILON)*Math.cos(C),M=(p+T.EPSILON)*Math.sin(C),P={overlap:p,result:!1,x:_,y:M};if(i&&(!v||v&&0!==p))return P.result=!0,P;if(!v&&0===p||h&&c||t.customSeparateX||e.customSeparateX)return P.x=void 0,P.y=void 0,P;var R=!t.pushable&&!e.pushable;if(v){var O=o.x-a.x,L=o.y-a.y,F=Math.sqrt(Math.pow(O,2)+Math.pow(L,2)),D=(a.x-o.x)/F||0,I=(a.y-o.y)/F||0,k=2*(d.x*D+d.y*I-f.x*D-f.y*I)/(t.mass+e.mass);(h||c)&&(k*=2),h||(d.x=d.x-k/t.mass*D,d.y=d.y-k/t.mass*I,d.multiply(t.bounce)),c||(f.x=f.x+k/e.mass*D,f.y=f.y+k/e.mass*I,f.multiply(e.bounce)),h||c||(_*=.5,M*=.5),h||(t.x-=_,t.y-=M,t.updateCenter()),c||(e.x+=_,e.y+=M,e.updateCenter()),P.result=!0}else!h||t.pushable||R?(t.x-=_,t.y-=M,t.updateCenter()):(!c||e.pushable||R)&&(e.x+=_,e.y+=M,e.updateCenter()),P.x=void 0,P.y=void 0;return P},intersects:function(t,e){return t!==e&&(t.isCircle||e.isCircle?t.isCircle?e.isCircle?u(t.center,e.center)<=t.halfWidth+e.halfWidth:this.circleBodyIntersects(t,e):this.circleBodyIntersects(e,t):!(t.right<=e.left||t.bottom<=e.top||t.left>=e.right||t.top>=e.bottom))},circleBodyIntersects:function(t,e){var i=r(t.center.x,e.left,e.right),s=r(t.center.y,e.top,e.bottom);return(t.center.x-i)*(t.center.x-i)+(t.center.y-s)*(t.center.y-s)<=t.halfWidth*t.halfWidth},overlap:function(t,e,i,s,n){return void 0===i&&(i=null),void 0===s&&(s=null),void 0===n&&(n=i),this.collideObjects(t,e,i,s,n,!0)},collide:function(t,e,i,s,n){return void 0===i&&(i=null),void 0===s&&(s=null),void 0===n&&(n=i),this.collideObjects(t,e,i,s,n,!1)},collideObjects:function(t,e,i,s,n,r){var o,a;!t.isParent||void 0!==t.physicsType&&void 0!==e&&t!==e||(t=t.children.entries),e&&e.isParent&&void 0===e.physicsType&&(e=e.children.entries);var h=Array.isArray(t),l=Array.isArray(e);if(this._total=0,h||l)if(!h&&l)for(o=0;o0},collideHandler:function(t,e,i,s,n,r){if(void 0===e&&t.isParent)return this.collideGroupVsGroup(t,t,i,s,n,r);if(!t||!e)return!1;if(t.body||t.isBody){if(e.body||e.isBody)return this.collideSpriteVsSprite(t,e,i,s,n,r);if(e.isParent)return this.collideSpriteVsGroup(t,e,i,s,n,r);if(e.isTilemap)return this.collideSpriteVsTilemapLayer(t,e,i,s,n,r)}else if(t.isParent){if(e.body||e.isBody)return this.collideSpriteVsGroup(e,t,i,s,n,r);if(e.isParent)return this.collideGroupVsGroup(t,e,i,s,n,r);if(e.isTilemap)return this.collideGroupVsTilemapLayer(t,e,i,s,n,r)}else if(t.isTilemap){if(e.body||e.isBody)return this.collideSpriteVsTilemapLayer(e,t,i,s,n,r);if(e.isParent)return this.collideGroupVsTilemapLayer(e,t,i,s,n,r)}},collideSpriteVsSprite:function(t,e,i,s,n,r){var o=t.isBody?t:t.body,a=e.isBody?e:e.body;return!(!o||!a)&&(this.separate(o,a,s,n,r)&&(i&&i.call(n,t,e),this._total++),!0)},collideSpriteVsGroup:function(t,e,i,s,n,r){var o,a,l,u=t.isBody?t:t.body;if(0!==e.length&&u&&u.enable&&!u.checkCollision.none)if(this.useTree||e.physicsType===h.STATIC_BODY){var c=this.treeMinMax;c.minX=u.left,c.minY=u.top,c.maxX=u.right,c.maxY=u.bottom;var d=e.physicsType===h.DYNAMIC_BODY?this.tree.search(c):this.staticTree.search(c);for(a=d.length,o=0;oc.baseTileWidth){var d=(c.tileWidth-c.baseTileWidth)*e.scaleX;a-=d,l+=d}c.tileHeight>c.baseTileHeight&&(u+=(c.tileHeight-c.baseTileHeight)*e.scaleY);var f=r?null:this.tileFilterOptions,p=y(a,h,l,u,f,e.scene.cameras.main,e.layer);return 0!==p.length&&this.collideSpriteVsTilesHandler(t,p,i,s,n,r,!0)},collideSpriteVsTilesHandler:function(t,e,i,s,n,r,o){for(var a,h,l=t.isBody?t:t.body,u={left:0,right:0,top:0,bottom:0},c=!1,f=0;f{t.exports={setAcceleration:function(t,e){return this.body.acceleration.set(t,e),this},setAccelerationX:function(t){return this.body.acceleration.x=t,this},setAccelerationY:function(t){return this.body.acceleration.y=t,this}}},29257:t=>{t.exports={setAngularVelocity:function(t){return this.body.angularVelocity=t,this},setAngularAcceleration:function(t){return this.body.angularAcceleration=t,this},setAngularDrag:function(t){return this.body.angularDrag=t,this}}},62122:t=>{t.exports={setBounce:function(t,e){return this.body.bounce.set(t,e),this},setBounceX:function(t){return this.body.bounce.x=t,this},setBounceY:function(t){return this.body.bounce.y=t,this},setCollideWorldBounds:function(t,e,i,s){return this.body.setCollideWorldBounds(t,e,i,s),this}}},99803:t=>{t.exports={setDebug:function(t,e,i){return this.debugShowBody=t,this.debugShowVelocity=e,this.debugBodyColor=i,this},setDebugBodyColor:function(t){return this.body.debugBodyColor=t,this},debugShowBody:{get:function(){return this.body.debugShowBody},set:function(t){this.body.debugShowBody=t}},debugShowVelocity:{get:function(){return this.body.debugShowVelocity},set:function(t){this.body.debugShowVelocity=t}},debugBodyColor:{get:function(){return this.body.debugBodyColor},set:function(t){this.body.debugBodyColor=t}}}},87145:t=>{t.exports={setDrag:function(t,e){return this.body.drag.set(t,e),this},setDragX:function(t){return this.body.drag.x=t,this},setDragY:function(t){return this.body.drag.y=t,this},setDamping:function(t){return this.body.useDamping=t,this}}},96174:t=>{var e={enableBody:function(t,e,i,s,n){return t&&this.body.reset(e,i),s&&(this.body.gameObject.active=!0),n&&(this.body.gameObject.visible=!0),this.body.enable=!0,this},disableBody:function(t,e){return void 0===t&&(t=!1),void 0===e&&(e=!1),this.body.stop(),this.body.enable=!1,t&&(this.body.gameObject.active=!1),e&&(this.body.gameObject.visible=!1),this},refreshBody:function(){return this.body.updateFromGameObject(),this}};t.exports=e},51702:t=>{t.exports={setFriction:function(t,e){return this.body.friction.set(t,e),this},setFrictionX:function(t){return this.body.friction.x=t,this},setFrictionY:function(t){return this.body.friction.y=t,this}}},25578:t=>{t.exports={setGravity:function(t,e){return this.body.gravity.set(t,e),this},setGravityX:function(t){return this.body.gravity.x=t,this},setGravityY:function(t){return this.body.gravity.y=t,this}}},72029:t=>{var e={setImmovable:function(t){return void 0===t&&(t=!0),this.body.immovable=t,this}};t.exports=e},34566:t=>{t.exports={setMass:function(t){return this.body.mass=t,this}}},2732:(t,e,i)=>{var s=i(15147),n=i(26673),r=i(22184),o=i(26535);t.exports=function(t,e,i,a,h,l){var u=s(t,e-a,i-a,2*a,2*a,h,l);if(0===u.length)return u;for(var c=new n(e,i,a),d=new n,f=[],p=0;p{t.exports=function(t,e,i,s,n,r,o){void 0===r&&(r=!0),void 0===o&&(o=!1);var a=[],h=[],l=t.treeMinMax;if(l.minX=e,l.minY=i,l.maxX=e+s,l.maxY=i+n,o&&(h=t.staticTree.search(l)),r&&t.useTree)a=t.tree.search(l);else if(r){var u=t.bodies,c={position:{x:e,y:i},left:e,top:i,right:e+s,bottom:i+n,isCircle:!1},d=t.intersects;u.iterate((function(t){d(t,c)&&a.push(t)}))}return h.concat(a)}},57527:t=>{var e={setPushable:function(t){return void 0===t&&(t=!0),this.body.pushable=t,this}};t.exports=e},77687:t=>{t.exports={setOffset:function(t,e){return this.body.setOffset(t,e),this},setSize:function(t,e,i){return this.body.setSize(t,e,i),this},setBodySize:function(t,e,i){return this.body.setSize(t,e,i),this},setCircle:function(t,e,i){return this.body.setCircle(t,e,i),this}}},66536:t=>{t.exports={setVelocity:function(t,e){return this.body.setVelocity(t,e),this},setVelocityX:function(t){return this.body.setVelocityX(t),this},setVelocityY:function(t){return this.body.setVelocityY(t),this},setMaxVelocity:function(t,e){return this.body.maxVelocity.set(t,e),this}}},7864:(t,e,i)=>{t.exports={Acceleration:i(5321),Angular:i(29257),Bounce:i(62122),Debug:i(99803),Drag:i(87145),Enable:i(96174),Friction:i(51702),Gravity:i(25578),Immovable:i(72029),Mass:i(34566),OverlapCirc:i(2732),OverlapRect:i(15147),Pushable:i(57527),Size:i(77687),Velocity:i(66536)}},47401:t=>{t.exports={DYNAMIC_BODY:0,STATIC_BODY:1,GROUP:2,TILEMAPLAYER:3,FACING_NONE:10,FACING_UP:11,FACING_DOWN:12,FACING_LEFT:13,FACING_RIGHT:14}},22346:t=>{t.exports="collide"},95092:t=>{t.exports="overlap"},15775:t=>{t.exports="pause"},74142:t=>{t.exports="resume"},22825:t=>{t.exports="tilecollide"},10851:t=>{t.exports="tileoverlap"},7543:t=>{t.exports="worldbounds"},1487:t=>{t.exports="worldstep"},27037:(t,e,i)=>{t.exports={COLLIDE:i(22346),OVERLAP:i(95092),PAUSE:i(15775),RESUME:i(74142),TILE_COLLIDE:i(22825),TILE_OVERLAP:i(10851),WORLD_BOUNDS:i(7543),WORLD_STEP:i(1487)}},39977:(t,e,i)=>{var s=i(47401),n=i(98611),r={ArcadePhysics:i(66150),Body:i(97602),Collider:i(3909),Components:i(7864),Events:i(27037),Factory:i(99523),GetOverlapX:i(75671),GetOverlapY:i(66185),SeparateX:i(61777),SeparateY:i(25299),Group:i(10481),Image:i(62832),Sprite:i(25084),StaticBody:i(66634),StaticGroup:i(46346),Tilemap:i(8413),World:i(85233)};r=n(!1,r,s),t.exports=r},25163:t=>{t.exports=function(t,e){return t.collisionCallback?!t.collisionCallback.call(t.collisionCallbackContext,e,t):!t.layer.callbacks[t.index]||!t.layer.callbacks[t.index].callback.call(t.layer.callbacks[t.index].callbackContext,e,t)}},98209:t=>{t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.left=!0):e>0&&(t.blocked.none=!1,t.blocked.right=!0),t.position.x-=e,t.updateCenter(),0===t.bounce.x?t.velocity.x=0:t.velocity.x=-t.velocity.x*t.bounce.x}},72792:t=>{t.exports=function(t,e){e<0?(t.blocked.none=!1,t.blocked.up=!0):e>0&&(t.blocked.none=!1,t.blocked.down=!0),t.position.y-=e,t.updateCenter(),0===t.bounce.y?t.velocity.y=0:t.velocity.y=-t.velocity.y*t.bounce.y}},27354:(t,e,i)=>{var s=i(14405),n=i(52926),r=i(28808);t.exports=function(t,e,i,o,a,h,l){var u=o.left,c=o.top,d=o.right,f=o.bottom,p=i.faceLeft||i.faceRight,v=i.faceTop||i.faceBottom;if(l||(p=!0,v=!0),!p&&!v)return!1;var g=0,m=0,y=0,x=1;if(e.deltaAbsX()>e.deltaAbsY()?y=-1:e.deltaAbsX(){var s=i(98209);t.exports=function(t,e,i,n,r,o){var a=0,h=e.faceLeft,l=e.faceRight,u=e.collideLeft,c=e.collideRight;return o||(h=!0,l=!0,u=!0,c=!0),t.deltaX()<0&&c&&t.checkCollision.left?l&&t.x0&&u&&t.checkCollision.right&&h&&t.right>i&&(a=t.right-i)>r&&(a=0),0!==a&&(t.customSeparateX?t.overlapX=a:s(t,a)),a}},52926:(t,e,i)=>{var s=i(72792);t.exports=function(t,e,i,n,r,o){var a=0,h=e.faceTop,l=e.faceBottom,u=e.collideUp,c=e.collideDown;return o||(h=!0,l=!0,u=!0,c=!0),t.deltaY()<0&&c&&t.checkCollision.up?l&&t.y0&&u&&t.checkCollision.down&&h&&t.bottom>i&&(a=t.bottom-i)>r&&(a=0),0!==a&&(t.customSeparateY?t.overlapY=a:s(t,a)),a}},28808:t=>{t.exports=function(t,e){return!(e.right<=t.left||e.bottom<=t.top||e.position.x>=t.right||e.position.y>=t.bottom)}},8413:(t,e,i)=>{var s={ProcessTileCallbacks:i(25163),ProcessTileSeparationX:i(98209),ProcessTileSeparationY:i(72792),SeparateTile:i(27354),TileCheckX:i(14405),TileCheckY:i(52926),TileIntersectsBody:i(28808)};t.exports=s},53954:(t,e,i)=>{t.exports={Arcade:i(39977),Matter:i(45949)}},63568:(t,e,i)=>{var s=i(56694),n=i(93736),r=new s({initialize:function(){this.boundsCenter=new n,this.centerDiff=new n},parseBody:function(t){if(!(t=t.hasOwnProperty("body")?t.body:t).hasOwnProperty("bounds")||!t.hasOwnProperty("centerOfMass"))return!1;var e=this.boundsCenter,i=this.centerDiff,s=t.bounds.max.x-t.bounds.min.x,n=t.bounds.max.y-t.bounds.min.y,r=s*t.centerOfMass.x,o=n*t.centerOfMass.y;return e.set(s/2,n/2),i.set(r-e.x,o-e.y),!0},getTopLeft:function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),this.parseBody(t)){var s=this.boundsCenter,r=this.centerDiff;return new n(e+s.x+r.x,i+s.y+r.y)}return!1},getTopCenter:function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),this.parseBody(t)){var s=this.boundsCenter,r=this.centerDiff;return new n(e+r.x,i+s.y+r.y)}return!1},getTopRight:function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),this.parseBody(t)){var s=this.boundsCenter,r=this.centerDiff;return new n(e-(s.x-r.x),i+s.y+r.y)}return!1},getLeftCenter:function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),this.parseBody(t)){var s=this.boundsCenter,r=this.centerDiff;return new n(e+s.x+r.x,i+r.y)}return!1},getCenter:function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),this.parseBody(t)){var s=this.centerDiff;return new n(e+s.x,i+s.y)}return!1},getRightCenter:function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),this.parseBody(t)){var s=this.boundsCenter,r=this.centerDiff;return new n(e-(s.x-r.x),i+r.y)}return!1},getBottomLeft:function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),this.parseBody(t)){var s=this.boundsCenter,r=this.centerDiff;return new n(e+s.x+r.x,i-(s.y-r.y))}return!1},getBottomCenter:function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),this.parseBody(t)){var s=this.boundsCenter,r=this.centerDiff;return new n(e+r.x,i-(s.y-r.y))}return!1},getBottomRight:function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),this.parseBody(t)){var s=this.boundsCenter,r=this.centerDiff;return new n(e-(s.x-r.x),i-(s.y-r.y))}return!1}});t.exports=r},18171:(t,e,i)=>{var s=i(16929);s.Body=i(84125),s.Composite=i(11299),s.World=i(72005),s.Collision=i(63454),s.Detector=i(13657),s.Pairs=i(91327),s.Pair=i(70584),s.Query=i(13390),s.Resolver=i(44272),s.Constraint=i(52838),s.Common=i(68758),s.Engine=i(45775),s.Events=i(39073),s.Sleeping=i(22806),s.Plugin=i(84474),s.Bodies=i(68516),s.Composites=i(56643),s.Axes=i(50658),s.Bounds=i(84091),s.Svg=i(92765),s.Vector=i(10438),s.Vertices=i(39745),s.World.add=s.Composite.add,s.World.remove=s.Composite.remove,s.World.addComposite=s.Composite.addComposite,s.World.addBody=s.Composite.addBody,s.World.addConstraint=s.Composite.addConstraint,s.World.clear=s.Composite.clear,t.exports=s},72653:(t,e,i)=>{var s=i(68516),n=i(56694),r=i(56643),o=i(52838),a=i(92765),h=i(3860),l=i(7030),u=i(73658),c=i(84720),d=i(10998),f=i(72829),p=i(88596),v=i(39745),g=new n({initialize:function(t){this.world=t,this.scene=t.scene,this.sys=t.scene.sys},rectangle:function(t,e,i,n,r){var o=s.rectangle(t,e,i,n,r);return this.world.add(o),o},trapezoid:function(t,e,i,n,r,o){var a=s.trapezoid(t,e,i,n,r,o);return this.world.add(a),a},circle:function(t,e,i,n,r){var o=s.circle(t,e,i,n,r);return this.world.add(o),o},polygon:function(t,e,i,n,r){var o=s.polygon(t,e,i,n,r);return this.world.add(o),o},fromVertices:function(t,e,i,n,r,o,a){"string"==typeof i&&(i=v.fromPath(i));var h=s.fromVertices(t,e,i,n,r,o,a);return this.world.add(h),h},fromPhysicsEditor:function(t,e,i,s,n){void 0===n&&(n=!0);var r=d.parseBody(t,e,i,s);return n&&!this.world.has(r)&&this.world.add(r),r},fromSVG:function(t,e,i,n,r,o){void 0===n&&(n=1),void 0===r&&(r={}),void 0===o&&(o=!0);for(var h=i.getElementsByTagName("path"),l=[],u=0;u{var s=i(74527),n=i(72632),r=i(93736);t.exports=function(t,e,i,o){void 0===i&&(i={}),void 0===o&&(o=!0);var a=e.x,h=e.y;if(e.body={temp:!0,position:{x:a,y:h}},[s.Bounce,s.Collision,s.Force,s.Friction,s.Gravity,s.Mass,s.Sensor,s.SetBody,s.Sleep,s.Static,s.Transform,s.Velocity].forEach((function(t){for(var i in t)(s=t[i]).get&&"function"==typeof s.get||s.set&&"function"==typeof s.set?Object.defineProperty(e,i,{get:t[i].get,set:t[i].set}):Object.defineProperty(e,i,{value:t[i]});var s})),e.world=t,e._tempVec2=new r(a,h),i.hasOwnProperty("type")&&"body"===i.type)e.setExistingBody(i,o);else{var l=n(i,"shape",null);l||(l="rectangle"),i.addToWorld=o,e.setBody(l,i)}return e}},7030:(t,e,i)=>{var s=i(56694),n=i(74527),r=i(89980),o=i(72632),a=i(1539),h=i(58210),l=i(93736),u=new s({Extends:a,Mixins:[n.Bounce,n.Collision,n.Force,n.Friction,n.Gravity,n.Mass,n.Sensor,n.SetBody,n.Sleep,n.Static,n.Transform,n.Velocity,h],initialize:function(t,e,i,s,n,a){r.call(this,t.scene,"Image"),this._crop=this.resetCropObject(),this.setTexture(s,n),this.setSizeToFrame(),this.setOrigin(),this.world=t,this._tempVec2=new l(e,i);var h=o(a,"shape",null);h?this.setBody(h,a):this.setRectangle(this.width,this.height,a),this.setPosition(e,i),this.initPipeline(),this.initPostPipeline(!0)}});t.exports=u},50583:(t,e,i)=>{var s=i(84093),n=i(50658),r=i(68516),o=i(84125),a=i(63568),h=i(84091),l=i(56694),u=i(63454),c=i(68758),d=i(11299),f=i(56643),p=i(52838),v=i(13657),g=i(53996),m=i(72653),y=i(72632),x=i(10850),T=i(1675),w=i(80391),b=i(16929),S=i(44097),E=i(30657),A=i(70584),C=i(91327),_=i(84474),M=i(91963),P=i(13390),R=i(44272),O=i(7599),L=i(92765),F=i(10438),D=i(39745),I=i(31468);c.setDecomp(i(81084));var k=new l({initialize:function(t){this.scene=t,this.systems=t.sys,this.config=this.getConfig(),this.world,this.add,this.bodyBounds,this.body=o,this.composite=d,this.collision=u,this.detector=v,this.pair=A,this.pairs=C,this.query=P,this.resolver=R,this.constraint=p,this.bodies=r,this.composites=f,this.axes=n,this.bounds=h,this.svg=L,this.vector=F,this.vertices=D,this.verts=D,this._tempVec2=F.create(),x(this.config,"plugins.collisionevents",!0)&&this.enableCollisionEventsPlugin(),x(this.config,"plugins.attractors",!1)&&this.enableAttractorPlugin(),x(this.config,"plugins.wrap",!1)&&this.enableWrapPlugin(),R._restingThresh=x(this.config,"restingThresh",4),R._restingThreshTangent=x(this.config,"restingThreshTangent",6),R._positionDampen=x(this.config,"positionDampen",.9),R._positionWarming=x(this.config,"positionWarming",.8),R._frictionNormalMultiplier=x(this.config,"frictionNormalMultiplier",5),t.sys.events.once(O.BOOT,this.boot,this),t.sys.events.on(O.START,this.start,this)},boot:function(){this.world=new I(this.scene,this.config),this.add=new m(this.world),this.bodyBounds=new a,this.systems.events.once(O.DESTROY,this.destroy,this)},start:function(){this.world||(this.world=new I(this.scene,this.config),this.add=new m(this.world));var t=this.systems.events;t.on(O.UPDATE,this.world.update,this.world),t.on(O.POST_UPDATE,this.world.postUpdate,this.world),t.once(O.SHUTDOWN,this.shutdown,this)},getConfig:function(){var t=this.systems.game.config.physics,e=this.systems.settings.physics;return E(y(e,"matter",{}),y(t,"matter",{}))},enableAttractorPlugin:function(){return _.register(T),_.use(b,T),this},enableWrapPlugin:function(){return _.register(S),_.use(b,S),this},enableCollisionEventsPlugin:function(){return _.register(w),_.use(b,w),this},pause:function(){return this.world.pause()},resume:function(){return this.world.resume()},set60Hz:function(){return this.world.getDelta=this.world.update60Hz,this.world.autoUpdate=!0,this},set30Hz:function(){return this.world.getDelta=this.world.update30Hz,this.world.autoUpdate=!0,this},step:function(t,e){this.world.step(t,e)},containsPoint:function(t,e,i){t=this.getMatterBodies(t);var s=F.create(e,i);return P.point(t,s).length>0},intersectPoint:function(t,e,i){i=this.getMatterBodies(i);var s=F.create(t,e),n=[];return P.point(i,s).forEach((function(t){-1===n.indexOf(t)&&n.push(t)})),n},intersectRect:function(t,e,i,s,n,r){void 0===n&&(n=!1),r=this.getMatterBodies(r);var o={min:{x:t,y:e},max:{x:t+i,y:e+s}},a=[];return P.region(r,o,n).forEach((function(t){-1===a.indexOf(t)&&a.push(t)})),a},intersectRay:function(t,e,i,s,n,r){void 0===n&&(n=1),r=this.getMatterBodies(r);for(var o=[],a=P.ray(r,F.create(t,e),F.create(i,s),n),h=0;h{var s=i(16569),n=i(56694),r=i(74527),o=i(89980),a=i(72632),h=i(58210),l=i(13747),u=i(93736),c=new n({Extends:l,Mixins:[r.Bounce,r.Collision,r.Force,r.Friction,r.Gravity,r.Mass,r.Sensor,r.SetBody,r.Sleep,r.Static,r.Transform,r.Velocity,h],initialize:function(t,e,i,n,r,h){o.call(this,t.scene,"Sprite"),this._crop=this.resetCropObject(),this.anims=new s(this),this.setTexture(n,r),this.setSizeToFrame(),this.setOrigin(),this.world=t,this._tempVec2=new u(e,i);var l=a(h,"shape",null);l?this.setBody(l,h):this.setRectangle(this.width,this.height,h),this.setPosition(e,i),this.initPipeline(),this.initPostPipeline(!0)}});t.exports=c},84720:(t,e,i)=>{var s=i(68516),n=i(84125),r=i(56694),o=i(74527),a=i(28699),h=i(6659),l=i(72632),u=i(19256),c=i(39745),d=new r({Extends:h,Mixins:[o.Bounce,o.Collision,o.Friction,o.Gravity,o.Mass,o.Sensor,o.Sleep,o.Static],initialize:function(t,e,i){h.call(this),this.tile=e,this.world=t,e.physics.matterBody&&e.physics.matterBody.destroy(),e.physics.matterBody=this;var s=l(i,"body",null),r=l(i,"addToWorld",!0);if(s)this.setBody(s,r);else{var o=e.getCollisionGroup();l(o,"objects",[]).length>0?this.setFromTileCollision(i):this.setFromTileRectangle(i)}if(e.flipX||e.flipY){var a={x:e.getCenterX(),y:e.getCenterY()},u=e.flipX?-1:1,c=e.flipY?-1:1;n.scale(s,u,c,a)}},setFromTileRectangle:function(t){void 0===t&&(t={}),u(t,"isStatic")||(t.isStatic=!0),u(t,"addToWorld")||(t.addToWorld=!0);var e=this.tile.getBounds(),i=e.x+e.width/2,n=e.y+e.height/2,r=s.rectangle(i,n,e.width,e.height,t);return this.setBody(r,t.addToWorld),this},setFromTileCollision:function(t){void 0===t&&(t={}),u(t,"isStatic")||(t.isStatic=!0),u(t,"addToWorld")||(t.addToWorld=!0);for(var e=this.tile.tilemapLayer.scaleX,i=this.tile.tilemapLayer.scaleY,r=this.tile.getLeft(),o=this.tile.getTop(),h=this.tile.getCollisionGroup(),d=l(h,"objects",[]),f=[],p=0;p1){var E=a(t);E.parts=f,this.setBody(n.create(E),E.addToWorld)}return this},setBody:function(t,e){return void 0===e&&(e=!0),this.body&&this.removeBody(),this.body=t,this.body.gameObject=this,e&&this.world.add(this.body),this},removeBody:function(){return this.body&&(this.world.remove(this.body),this.body.gameObject=void 0,this.body=void 0),this},destroy:function(){this.removeBody(),this.tile.physics.matterBody=void 0,this.removeAllListeners()}});t.exports=d},10998:(t,e,i)=>{var s=i(68516),n=i(84125),r=i(68758),o=i(72632),a=i(39745),h={parseBody:function(t,e,i,s){void 0===s&&(s={});for(var a=o(i,"fixtures",[]),h=[],l=0;l{var s=i(68516),n=i(84125),r={parseBody:function(t,e,i,r){var o;void 0===r&&(r={});var a=i.vertices;if(1===a.length)r.vertices=a[0],o=n.create(r),s.flagCoincidentParts(o.parts);else{for(var h=[],l=0;l{var s=i(84091),n=i(56694),r=i(11299),o=i(52838),a=i(13657),h=i(35416),l=i(33963),u=i(30657),c=i(22806),d=i(93736),f=i(39745),p=new n({initialize:function(t,e,i){void 0===i&&(i={});this.scene=t,this.world=e,this.camera=null,this.pointer=null,this.active=!0,this.position=new d,this.body=null,this.part=null,this.constraint=o.create(u(i,{label:"Pointer Constraint",pointA:{x:0,y:0},pointB:{x:0,y:0},length:.01,stiffness:.1,angularStiffness:1,collisionFilter:{category:1,mask:4294967295,group:0}})),this.world.on(h.BEFORE_UPDATE,this.update,this),t.sys.input.on(l.POINTER_DOWN,this.onDown,this),t.sys.input.on(l.POINTER_UP,this.onUp,this)},onDown:function(t){this.pointer||(this.pointer=t,this.camera=t.camera)},onUp:function(t){t===this.pointer&&(this.pointer=null)},getBody:function(t){var e=this.position,i=this.constraint;this.camera.getWorldPoint(t.x,t.y,e);for(var n=r.allBodies(this.world.localWorld),o=0;o1?1:0;n{var s=i(68516),n=i(84125),r=i(56694),o=i(68758),a=i(11299),h=i(45775),l=i(6659),u=i(35416),c=i(72632),d=i(10850),f=i(84125),p=i(39073),v=i(84720),g=i(72005),m=i(10438),y=new r({Extends:l,initialize:function(t,e){l.call(this),this.scene=t,this.engine=h.create(e),this.localWorld=this.engine.world;var i=d(e,"gravity",null);i?this.setGravity(i.x,i.y,i.scale):!1===i&&this.setGravity(0,0,0),this.walls={left:null,right:null,top:null,bottom:null},this.enabled=d(e,"enabled",!0),this.getDelta=d(e,"getDelta",this.update60Hz);var s=c(e,"runner",{}),n=c(s,"fps",!1),r=c(s,"fps",60),o=c(s,"delta",1e3/r),a=c(s,"deltaMin",1e3/r),u=c(s,"deltaMax",1e3/(.5*r));n||(r=1e3/o),this.runner={fps:r,deltaSampleSize:c(s,"deltaSampleSize",60),counterTimestamp:0,frameCounter:0,deltaHistory:[],timePrev:null,timeScalePrev:1,frameRequestId:null,isFixed:c(s,"isFixed",!1),delta:o,deltaMin:a,deltaMax:u},this.autoUpdate=d(e,"autoUpdate",!0);var f=d(e,"debug",!1);if(this.drawDebug="object"==typeof f||f,this.debugGraphic,this.debugConfig={showAxes:c(f,"showAxes",!1),showAngleIndicator:c(f,"showAngleIndicator",!1),angleColor:c(f,"angleColor",15208787),showBroadphase:c(f,"showBroadphase",!1),broadphaseColor:c(f,"broadphaseColor",16757760),showBounds:c(f,"showBounds",!1),boundsColor:c(f,"boundsColor",16777215),showVelocity:c(f,"showVelocity",!1),velocityColor:c(f,"velocityColor",44783),showCollisions:c(f,"showCollisions",!1),collisionColor:c(f,"collisionColor",16094476),showSeparations:c(f,"showSeparations",!1),separationColor:c(f,"separationColor",16753920),showBody:c(f,"showBody",!0),showStaticBody:c(f,"showStaticBody",!0),showInternalEdges:c(f,"showInternalEdges",!1),renderFill:c(f,"renderFill",!1),renderLine:c(f,"renderLine",!0),fillColor:c(f,"fillColor",1075465),fillOpacity:c(f,"fillOpacity",1),lineColor:c(f,"lineColor",2678297),lineOpacity:c(f,"lineOpacity",1),lineThickness:c(f,"lineThickness",1),staticFillColor:c(f,"staticFillColor",857979),staticLineColor:c(f,"staticLineColor",1255396),showSleeping:c(f,"showSleeping",!1),staticBodySleepOpacity:c(f,"staticBodySleepOpacity",.7),sleepFillColor:c(f,"sleepFillColor",4605510),sleepLineColor:c(f,"sleepLineColor",10066585),showSensors:c(f,"showSensors",!0),sensorFillColor:c(f,"sensorFillColor",857979),sensorLineColor:c(f,"sensorLineColor",1255396),showPositions:c(f,"showPositions",!0),positionSize:c(f,"positionSize",4),positionColor:c(f,"positionColor",14697178),showJoint:c(f,"showJoint",!0),jointColor:c(f,"jointColor",14737474),jointLineOpacity:c(f,"jointLineOpacity",1),jointLineThickness:c(f,"jointLineThickness",2),pinSize:c(f,"pinSize",4),pinColor:c(f,"pinColor",4382944),springColor:c(f,"springColor",14697184),anchorColor:c(f,"anchorColor",15724527),anchorSize:c(f,"anchorSize",4),showConvexHulls:c(f,"showConvexHulls",!1),hullColor:c(f,"hullColor",14091216)},this.drawDebug&&this.createDebugGraphic(),this.setEventsProxy(),c(e,"setBounds",!1)){var p=e.setBounds;if("boolean"==typeof p)this.setBounds();else{var v=c(p,"x",0),g=c(p,"y",0),m=c(p,"width",t.sys.scale.width),y=c(p,"height",t.sys.scale.height),x=c(p,"thickness",64),T=c(p,"left",!0),w=c(p,"right",!0),b=c(p,"top",!0),S=c(p,"bottom",!0);this.setBounds(v,g,m,y,x,T,w,b,S)}}},setCompositeRenderStyle:function(t){var e,i,s,n=t.bodies,r=t.constraints,o=t.composites;for(e=0;e0&&(i=n[0].bodyA,s=n[0].bodyB),t.emit(u.COLLISION_START,e,i,s)})),p.on(e,"collisionActive",(function(e){var i,s,n=e.pairs;n.length>0&&(i=n[0].bodyA,s=n[0].bodyB),t.emit(u.COLLISION_ACTIVE,e,i,s)})),p.on(e,"collisionEnd",(function(e){var i,s,n=e.pairs;n.length>0&&(i=n[0].bodyA,s=n[0].bodyB),t.emit(u.COLLISION_END,e,i,s)}))},setBounds:function(t,e,i,s,n,r,o,a,h){return void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=this.scene.sys.scale.width),void 0===s&&(s=this.scene.sys.scale.height),void 0===n&&(n=64),void 0===r&&(r=!0),void 0===o&&(o=!0),void 0===a&&(a=!0),void 0===h&&(h=!0),this.updateWall(r,"left",t-n,e-n,n,s+2*n),this.updateWall(o,"right",t+i,e-n,n,s+2*n),this.updateWall(a,"top",t,e-n,i,n),this.updateWall(h,"bottom",t,e+s,i,n),this},updateWall:function(t,e,i,s,n,r){var o=this.walls[e];t?(o&&g.remove(this.localWorld,o),i+=n/2,s+=r/2,this.walls[e]=this.create(i,s,n,r,{isStatic:!0,friction:0,frictionStatic:0})):(o&&g.remove(this.localWorld,o),this.walls[e]=null)},createDebugGraphic:function(){var t=this.scene.sys.add.graphics({x:0,y:0});return t.setDepth(Number.MAX_VALUE),this.debugGraphic=t,this.drawDebug=!0,t},disableGravity:function(){return this.localWorld.gravity.x=0,this.localWorld.gravity.y=0,this.localWorld.gravity.scale=0,this},setGravity:function(t,e,i){return void 0===t&&(t=0),void 0===e&&(e=1),void 0===i&&(i=.001),this.localWorld.gravity.x=t,this.localWorld.gravity.y=e,this.localWorld.gravity.scale=i,this},create:function(t,e,i,n,r){var o=s.rectangle(t,e,i,n,r);return g.add(this.localWorld,o),o},add:function(t){return g.add(this.localWorld,t),this},remove:function(t,e){Array.isArray(t)||(t=[t]);for(var i=0;is.deltaMax?s.deltaMax:e,s.delta=e),s.timeScalePrev=n.timeScale,s.frameCounter+=1,t-s.counterTimestamp>=1e3&&(s.fps=s.frameCounter*((t-s.counterTimestamp)/1e3),s.counterTimestamp=t,s.frameCounter=0),h.update(i,e)}},step:function(t){h.update(this.engine,t)},update60Hz:function(){return 1e3/60},update30Hz:function(){return 1e3/30},has:function(t){var e=t.hasOwnProperty("body")?t.body:t;return null!==a.get(this.localWorld,e.id,e.type)},getAllBodies:function(){return a.allBodies(this.localWorld)},getAllConstraints:function(){return a.allConstraints(this.localWorld)},getAllComposites:function(){return a.allComposites(this.localWorld)},postUpdate:function(){if(this.drawDebug){var t=this.debugConfig,e=this.engine,i=this.debugGraphic,s=a.allBodies(this.localWorld);this.debugGraphic.clear(),t.showBroadphase&&e.broadphase.controller&&this.renderGrid(e.broadphase,i,t.broadphaseColor,.5),t.showBounds&&this.renderBodyBounds(s,i,t.boundsColor,.5),(t.showBody||t.showStaticBody)&&this.renderBodies(s),t.showJoint&&this.renderJoints(),(t.showAxes||t.showAngleIndicator)&&this.renderBodyAxes(s,i,t.showAxes,t.angleColor,.5),t.showVelocity&&this.renderBodyVelocity(s,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,s){e.lineStyle(1,i,s);for(var n=o.keys(t.buckets),r=0;r0){var l=h[0].vertex.x,u=h[0].vertex.y;2===h.length&&(l=(h[0].vertex.x+h[1].vertex.x)/2,u=(h[0].vertex.y+h[1].vertex.y)/2),a.bodyB===a.supports[0].body||a.bodyA.isStatic?e.lineBetween(l-8*a.normal.x,u-8*a.normal.y,l,u):e.lineBetween(l+8*a.normal.x,u+8*a.normal.y,l,u)}}return this},renderBodyBounds:function(t,e,i,s){e.lineStyle(1,i,s);for(var n=0;n1?1:0;h1?1:0;a1?1:0;a1&&this.renderConvexHull(v,e,f,y)}}},renderBody:function(t,e,i,s,n,r,o,a){void 0===s&&(s=null),void 0===n&&(n=null),void 0===r&&(r=1),void 0===o&&(o=null),void 0===a&&(a=null);for(var h=this.debugConfig,l=h.sensorFillColor,u=h.sensorLineColor,c=t.parts,d=c.length,f=d>1?1:0;f1){var n=t.vertices;e.lineStyle(s,i),e.beginPath(),e.moveTo(n[0].x,n[0].y);for(var r=1;r0&&(e.fillStyle(a),e.fillCircle(u.x,u.y,h),e.fillCircle(c.x,c.y,h)),this},resetCollisionIDs:function(){return n._nextCollidingGroupId=1,n._nextNonCollidingGroupId=-1,n._nextCategory=1,this},shutdown:function(){p.off(this.engine),this.removeAllListeners(),g.clear(this.localWorld,!1),h.clear(this.engine),this.drawDebug&&this.debugGraphic.destroy()},destroy:function(){this.shutdown()}});t.exports=y},95349:t=>{t.exports={setBounce:function(t){return this.body.restitution=t,this}}},70679:t=>{var e={setCollisionCategory:function(t){return this.body.collisionFilter.category=t,this},setCollisionGroup:function(t){return this.body.collisionFilter.group=t,this},setCollidesWith:function(t){var e=0;if(Array.isArray(t))for(var i=0;i{var s=i(84125),n={applyForce:function(t){return this._tempVec2.set(this.body.position.x,this.body.position.y),s.applyForce(this.body,this._tempVec2,t),this},applyForceFrom:function(t,e){return s.applyForce(this.body,t,e),this},thrust:function(t){var e=this.body.angle;return this._tempVec2.set(t*Math.cos(e),t*Math.sin(e)),s.applyForce(this.body,{x:this.body.position.x,y:this.body.position.y},this._tempVec2),this},thrustLeft:function(t){var e=this.body.angle-Math.PI/2;return this._tempVec2.set(t*Math.cos(e),t*Math.sin(e)),s.applyForce(this.body,{x:this.body.position.x,y:this.body.position.y},this._tempVec2),this},thrustRight:function(t){var e=this.body.angle+Math.PI/2;return this._tempVec2.set(t*Math.cos(e),t*Math.sin(e)),s.applyForce(this.body,{x:this.body.position.x,y:this.body.position.y},this._tempVec2),this},thrustBack:function(t){var e=this.body.angle-Math.PI;return this._tempVec2.set(t*Math.cos(e),t*Math.sin(e)),s.applyForce(this.body,{x:this.body.position.x,y:this.body.position.y},this._tempVec2),this}};t.exports=n},74015:t=>{var e={setFriction:function(t,e,i){return this.body.friction=t,void 0!==e&&(this.body.frictionAir=e),void 0!==i&&(this.body.frictionStatic=i),this},setFrictionAir:function(t){return this.body.frictionAir=t,this},setFrictionStatic:function(t){return this.body.frictionStatic=t,this}};t.exports=e},11535:t=>{t.exports={setIgnoreGravity:function(t){return this.body.ignoreGravity=t,this}}},74497:(t,e,i)=>{var s=i(84125),n=i(93736),r={setMass:function(t){return s.setMass(this.body,t),this},setDensity:function(t){return s.setDensity(this.body,t),this},centerOfMass:{get:function(){return new n(this.body.centerOfMass.x,this.body.centerOfMass.y)}}};t.exports=r},75529:t=>{t.exports={setSensor:function(t){return this.body.isSensor=t,this},isSensor:function(){return this.body.isSensor}}},64024:(t,e,i)=>{var s=i(68516),n=i(84125),r=i(88456),o=i(72632),a=i(10998),h=i(72829),l=i(39745),u={setRectangle:function(t,e,i){return this.setBody({type:"rectangle",width:t,height:e},i)},setCircle:function(t,e){return this.setBody({type:"circle",radius:t},e)},setPolygon:function(t,e,i){return this.setBody({type:"polygon",sides:e,radius:t},i)},setTrapezoid:function(t,e,i,s){return this.setBody({type:"trapezoid",width:t,height:e,slope:i},s)},setExistingBody:function(t,e){void 0===e&&(e=!0),this.body&&this.world.remove(this.body,!0),this.body=t;for(var i=0;i{var s=i(35416),n=i(22806),r=i(39073),o={setToSleep:function(){return n.set(this.body,!0),this},setAwake:function(){return n.set(this.body,!1),this},setSleepThreshold:function(t){return void 0===t&&(t=60),this.body.sleepThreshold=t,this},setSleepEvents:function(t,e){return this.setSleepStartEvent(t),this.setSleepEndEvent(e),this},setSleepStartEvent:function(t){if(t){var e=this.world;r.on(this.body,"sleepStart",(function(t){e.emit(s.SLEEP_START,t,this)}))}else r.off(this.body,"sleepStart");return this},setSleepEndEvent:function(t){if(t){var e=this.world;r.on(this.body,"sleepEnd",(function(t){e.emit(s.SLEEP_END,t,this)}))}else r.off(this.body,"sleepEnd");return this}};t.exports=o},82884:(t,e,i)=>{var s=i(84125),n={setStatic:function(t){return s.setStatic(this.body,t),this},isStatic:function(){return this.body.isStatic}};t.exports=n},4753:(t,e,i)=>{var s=i(84125),n=i(83392),r=i(35786),o=i(62138),a={x:{get:function(){return this.body.position.x},set:function(t){this._tempVec2.set(t,this.y),s.setPosition(this.body,this._tempVec2)}},y:{get:function(){return this.body.position.y},set:function(t){this._tempVec2.set(this.x,t),s.setPosition(this.body,this._tempVec2)}},scaleX:{get:function(){return this._scaleX},set:function(t){var e=1/this._scaleX,i=1/this._scaleY;this._scaleX=t,0===this._scaleX?this.renderFlags&=-5:this.renderFlags|=4,s.scale(this.body,e,i),s.scale(this.body,t,this._scaleY)}},scaleY:{get:function(){return this._scaleY},set:function(t){var e=1/this._scaleX,i=1/this._scaleY;this._scaleY=t,0===this._scaleY?this.renderFlags&=-5:this.renderFlags|=4,s.scale(this.body,e,i),s.scale(this.body,this._scaleX,t)}},angle:{get:function(){return o(this.body.angle*n.RAD_TO_DEG)},set:function(t){this.rotation=o(t)*n.DEG_TO_RAD}},rotation:{get:function(){return this.body.angle},set:function(t){this._rotation=r(t),s.setAngle(this.body,this._rotation)}},setPosition:function(t,e){return void 0===t&&(t=0),void 0===e&&(e=t),this._tempVec2.set(t,e),s.setPosition(this.body,this._tempVec2),this},setRotation:function(t){return void 0===t&&(t=0),this._rotation=r(t),s.setAngle(this.body,t),this},setFixedRotation:function(){return s.setInertia(this.body,1/0),this},setAngle:function(t){return void 0===t&&(t=0),this.angle=t,s.setAngle(this.body,this.rotation),this},setScale:function(t,e,i){void 0===t&&(t=1),void 0===e&&(e=t);var n=1/this._scaleX,r=1/this._scaleY;return this._scaleX=t,this._scaleY=e,s.scale(this.body,n,r,i),s.scale(this.body,t,e,i),this}};t.exports=a},37268:(t,e,i)=>{var s=i(84125),n={setVelocityX:function(t){return this._tempVec2.set(t,this.body.velocity.y),s.setVelocity(this.body,this._tempVec2),this},setVelocityY:function(t){return this._tempVec2.set(this.body.velocity.x,t),s.setVelocity(this.body,this._tempVec2),this},setVelocity:function(t,e){return this._tempVec2.set(t,e),s.setVelocity(this.body,this._tempVec2),this},getVelocity:function(){return s.getVelocity(this.body)},setAngularVelocity:function(t){return s.setAngularVelocity(this.body,t),this},getAngularVelocity:function(){return s.getAngularVelocity(this.body)},setAngularSpeed:function(t){return s.setAngularSpeed(this.body,t),this},getAngularSpeed:function(){return s.getAngularSpeed(this.body)}};t.exports=n},74527:(t,e,i)=>{t.exports={Bounce:i(95349),Collision:i(70679),Force:i(77178),Friction:i(74015),Gravity:i(11535),Mass:i(74497),Sensor:i(75529),SetBody:i(64024),Sleep:i(25106),Static:i(82884),Transform:i(4753),Velocity:i(37268)}},63201:t=>{t.exports="afteradd"},30474:t=>{t.exports="afterremove"},44822:t=>{t.exports="afterupdate"},88820:t=>{t.exports="beforeadd"},94849:t=>{t.exports="beforeremove"},6391:t=>{t.exports="beforeupdate"},96738:t=>{t.exports="collisionactive"},7916:t=>{t.exports="collisionend"},59529:t=>{t.exports="collisionstart"},10219:t=>{t.exports="dragend"},183:t=>{t.exports="drag"},39143:t=>{t.exports="dragstart"},16483:t=>{t.exports="pause"},35806:t=>{t.exports="resume"},22106:t=>{t.exports="sleepend"},5803:t=>{t.exports="sleepstart"},35416:(t,e,i)=>{t.exports={AFTER_ADD:i(63201),AFTER_REMOVE:i(30474),AFTER_UPDATE:i(44822),BEFORE_ADD:i(88820),BEFORE_REMOVE:i(94849),BEFORE_UPDATE:i(6391),COLLISION_ACTIVE:i(96738),COLLISION_END:i(7916),COLLISION_START:i(59529),DRAG_END:i(10219),DRAG:i(183),DRAG_START:i(39143),PAUSE:i(16483),RESUME:i(35806),SLEEP_END:i(22106),SLEEP_START:i(5803)}},45949:(t,e,i)=>{t.exports={BodyBounds:i(63568),Components:i(74527),Events:i(35416),Factory:i(72653),MatterGameObject:i(3860),Image:i(7030),Matter:i(18171),MatterPhysics:i(50583),PolyDecomp:i(81084),Sprite:i(73658),TileBody:i(84720),PhysicsEditorParser:i(10998),PhysicsJSONParser:i(72829),PointerConstraint:i(88596),World:i(31468)}},84125:(t,e,i)=>{var s={};t.exports=s;var n=i(39745),r=i(10438),o=i(22806),a=i(68758),h=i(84091),l=i(50658);!function(){s._timeCorrection=!0,s._inertiaScale=4,s._nextCollidingGroupId=1,s._nextNonCollidingGroupId=-1,s._nextCategory=1,s._baseDelta=1e3/60,s.create=function(e){var i={id:a.nextId(),type:"body",label:"Body",parts:[],plugin:{},angle:0,vertices:null,position:{x:0,y:0},force:{x:0,y:0},torque:0,positionImpulse:{x:0,y:0},constraintImpulse:{x:0,y:0,angle:0},totalContacts:0,speed:0,angularSpeed:0,velocity:{x:0,y:0},angularVelocity:0,isSensor:!1,isStatic:!1,isSleeping:!1,motion:0,sleepThreshold:60,density:.001,restitution:0,friction:.1,frictionStatic:.5,frictionAir:.01,collisionFilter:{category:1,mask:4294967295,group:0},slop:.05,timeScale:1,events:null,bounds:null,chamfer:null,circleRadius:0,positionPrev:null,anglePrev:0,parent:null,axes:null,area:0,mass:0,inverseMass:0,inertia:0,deltaTime:1e3/60,inverseInertia:0,_original:null,render:{visible:!0,opacity:1,sprite:{xOffset:0,yOffset:0},fillColor:null,fillOpacity:null,lineColor:null,lineOpacity:null,lineThickness:null},gameObject:null,scale:{x:1,y:1},centerOfMass:{x:0,y:0},centerOffset:{x:0,y:0},gravityScale:{x:1,y:1},ignoreGravity:!1,ignorePointer:!1,onCollideCallback:null,onCollideEndCallback:null,onCollideActiveCallback:null,onCollideWith:{}};!e.hasOwnProperty("position")&&e.hasOwnProperty("vertices")?e.position=n.centre(e.vertices):e.hasOwnProperty("vertices")||(i.vertices=n.fromPath("L 0 0 L 40 0 L 40 40 L 0 40"));var s=a.extend(i,e);return t(s,e),s.setOnCollideWith=function(t,e){return e?this.onCollideWith[t.id]=e:delete this.onCollideWith[t.id],this},s},s.nextGroup=function(t){return t?s._nextNonCollidingGroupId--:s._nextCollidingGroupId++},s.nextCategory=function(){return s._nextCategory=s._nextCategory<<1,s._nextCategory};var t=function(t,e){if(e=e||{},s.set(t,{bounds:t.bounds||h.create(t.vertices),positionPrev:t.positionPrev||r.clone(t.position),anglePrev:t.anglePrev||t.angle,vertices:t.vertices,parts:t.parts||[t],isStatic:t.isStatic,isSleeping:t.isSleeping,parent:t.parent||t}),n.rotate(t.vertices,t.angle,t.position),l.rotate(t.axes,t.angle),h.update(t.bounds,t.vertices,t.velocity),s.set(t,{axes:e.axes||t.axes,area:e.area||t.area,mass:e.mass||t.mass,inertia:e.inertia||t.inertia}),1===t.parts.length){var i=t.bounds,o=t.centerOfMass,a=t.centerOffset,u=i.max.x-i.min.x,c=i.max.y-i.min.y;o.x=-(i.min.x-t.position.x)/u,o.y=-(i.min.y-t.position.y)/c,a.x=u*o.x,a.y=c*o.y}};s.set=function(t,e,i){var n;for(n in"string"==typeof e&&(n=e,(e={})[n]=i),e)if(Object.prototype.hasOwnProperty.call(e,n))switch(i=e[n],n){case"isStatic":s.setStatic(t,i);break;case"isSleeping":o.set(t,i);break;case"mass":s.setMass(t,i);break;case"density":s.setDensity(t,i);break;case"inertia":s.setInertia(t,i);break;case"vertices":s.setVertices(t,i);break;case"position":s.setPosition(t,i);break;case"angle":s.setAngle(t,i);break;case"velocity":s.setVelocity(t,i);break;case"angularVelocity":s.setAngularVelocity(t,i);break;case"speed":s.setSpeed(t,i);break;case"angularSpeed":s.setAngularSpeed(t,i);break;case"parts":s.setParts(t,i);break;case"centre":s.setCentre(t,i);break;default:t[n]=i}},s.setStatic=function(t,e){for(var i=0;i0&&r.rotateAbout(a.position,s,t.position,a.position)}},s.setVelocity=function(t,e){var i=t.deltaTime/s._baseDelta;t.positionPrev.x=t.position.x-e.x*i,t.positionPrev.y=t.position.y-e.y*i,t.velocity.x=(t.position.x-t.positionPrev.x)/i,t.velocity.y=(t.position.y-t.positionPrev.y)/i,t.speed=r.magnitude(t.velocity)},s.getVelocity=function(t){var e=s._baseDelta/t.deltaTime;return{x:(t.position.x-t.positionPrev.x)*e,y:(t.position.y-t.positionPrev.y)*e}},s.getSpeed=function(t){return r.magnitude(s.getVelocity(t))},s.setSpeed=function(t,e){s.setVelocity(t,r.mult(r.normalise(s.getVelocity(t)),e))},s.setAngularVelocity=function(t,e){var i=t.deltaTime/s._baseDelta;t.anglePrev=t.angle-e*i,t.angularVelocity=(t.angle-t.anglePrev)/i,t.angularSpeed=Math.abs(t.angularVelocity)},s.getAngularVelocity=function(t){return(t.angle-t.anglePrev)*s._baseDelta/t.deltaTime},s.getAngularSpeed=function(t){return Math.abs(s.getAngularVelocity(t))},s.setAngularSpeed=function(t,e){s.setAngularVelocity(t,a.sign(s.getAngularVelocity(t))*e)},s.translate=function(t,e,i){s.setPosition(t,r.add(t.position,e),i)},s.rotate=function(t,e,i,n){if(i){var r=Math.cos(e),o=Math.sin(e),a=t.position.x-i.x,h=t.position.y-i.y;s.setPosition(t,{x:i.x+(a*r-h*o),y:i.y+(a*o+h*r)},n),s.setAngle(t,t.angle+e,n)}else s.setAngle(t,t.angle+e,n)},s.scale=function(t,e,i,r){var o=0,a=0;r=r||t.position;for(var u=0;u0&&(o+=c.area,a+=c.inertia),c.position.x=r.x+(c.position.x-r.x)*e,c.position.y=r.y+(c.position.y-r.y)*i,h.update(c.bounds,c.vertices,t.velocity)}t.parts.length>1&&(t.area=o,t.isStatic||(s.setMass(t,t.density*o),s.setInertia(t,a))),t.circleRadius&&(e===i?t.circleRadius*=e:t.circleRadius=null)},s.update=function(t,e){var i=(e=(void 0!==e?e:1e3/60)*t.timeScale)*e,o=s._timeCorrection?e/(t.deltaTime||e):1,u=1-t.frictionAir*(e/a._baseDelta),c=(t.position.x-t.positionPrev.x)*o,d=(t.position.y-t.positionPrev.y)*o;t.velocity.x=c*u+t.force.x/t.mass*i,t.velocity.y=d*u+t.force.y/t.mass*i,t.positionPrev.x=t.position.x,t.positionPrev.y=t.position.y,t.position.x+=t.velocity.x,t.position.y+=t.velocity.y,t.deltaTime=e,t.angularVelocity=(t.angle-t.anglePrev)*u*o+t.torque/t.inertia*i,t.anglePrev=t.angle,t.angle+=t.angularVelocity,t.speed=r.magnitude(t.velocity),t.angularSpeed=Math.abs(t.angularVelocity);for(var f=0;f0&&(p.position.x+=t.velocity.x,p.position.y+=t.velocity.y),0!==t.angularVelocity&&(n.rotate(p.vertices,t.angularVelocity,t.position),l.rotate(p.axes,t.angularVelocity),f>0&&r.rotateAbout(p.position,t.angularVelocity,t.position,p.position)),h.update(p.bounds,p.vertices,t.velocity)}},s.updateVelocities=function(t){var e=s._baseDelta/t.deltaTime,i=t.velocity;i.x=(t.position.x-t.positionPrev.x)*e,i.y=(t.position.y-t.positionPrev.y)*e,t.speed=Math.sqrt(i.x*i.x+i.y*i.y),t.angularVelocity=(t.angle-t.anglePrev)*e,t.angularSpeed=Math.abs(t.angularVelocity)},s.applyForce=function(t,e,i){var s=e.x-t.position.x,n=e.y-t.position.y;t.force.x+=i.x,t.force.y+=i.y,t.torque+=s*i.y-n*i.x},s._totalProperties=function(t){for(var e={mass:0,area:0,inertia:0,centre:{x:0,y:0}},i=1===t.parts.length?0:1;i{var s={};t.exports=s;var n=i(39073),r=i(68758),o=i(84091),a=i(84125);s.create=function(t){return r.extend({id:r.nextId(),type:"composite",parent:null,isModified:!1,bodies:[],constraints:[],composites:[],label:"Composite",plugin:{},cache:{allBodies:null,allConstraints:null,allComposites:null}},t)},s.setModified=function(t,e,i,r){if(n.trigger(t,"compositeModified",t),t.isModified=e,e&&t.cache&&(t.cache.allBodies=null,t.cache.allConstraints=null,t.cache.allComposites=null),i&&t.parent&&s.setModified(t.parent,e,i,r),r)for(var o=0;o{var s={};t.exports=s;var n=i(11299);s.create=n.create,s.add=n.add,s.remove=n.remove,s.clear=n.clear,s.addComposite=n.addComposite,s.addBody=n.addBody,s.addConstraint=n.addConstraint},63454:(t,e,i)=>{var s={};t.exports=s;var n,r,o,a=i(39745),h=i(70584);n=[],r={overlap:0,axis:null},o={overlap:0,axis:null},s.create=function(t,e){return{pair:null,collided:!1,bodyA:t,bodyB:e,parentA:t.parent,parentB:e.parent,depth:0,normal:{x:0,y:0},tangent:{x:0,y:0},penetration:{x:0,y:0},supports:[]}},s.collides=function(t,e,i){if(s._overlapAxes(r,t.vertices,e.vertices,t.axes),r.overlap<=0)return null;if(s._overlapAxes(o,e.vertices,t.vertices,e.axes),o.overlap<=0)return null;var n,l,u=i&&i.table[h.id(t,e)];u?n=u.collision:((n=s.create(t,e)).collided=!0,n.bodyA=t.idE?E=a:aA?A=a:an?n=o:o{var e={};t.exports=e,e.create=function(t){return{vertex:t,normalImpulse:0,tangentImpulse:0}}},13657:(t,e,i)=>{var s={};t.exports=s;var n=i(68758),r=i(63454);s.create=function(t){return n.extend({bodies:[],pairs:null},t)},s.setBodies=function(t,e){t.bodies=e.slice(0)},s.clear=function(t){t.bodies=[]},s.collisions=function(t){var e,i,n=[],o=t.pairs,a=t.bodies,h=a.length,l=s.canCollide,u=r.collides;for(a.sort(s._compareBoundsX),e=0;ef)break;if(!(p<_.min.y||v>_.max.y)&&(!g||!x.isStatic&&!x.isSleeping)&&l(c.collisionFilter,x.collisionFilter)){var T=x.parts.length;if(y&&1===T)(A=u(c,x,o))&&n.push(A);else for(var w=T>1?1:0,b=m>1?1:0;b_.max.x||d.max.x<_.min.x||d.max.y<_.min.y||d.min.y>_.max.y||(A=u(S,C,o))&&n.push(A)}}}}return n},s.canCollide=function(t,e){return t.group===e.group&&0!==t.group?t.group>0:0!=(t.mask&e.category)&&0!=(e.mask&t.category)},s._compareBoundsX=function(t,e){return t.bounds.min.x-e.bounds.min.x}},70584:(t,e,i)=>{var s={};t.exports=s;var n=i(17319);s.create=function(t,e){var i=t.bodyA,n=t.bodyB,r={id:s.id(i,n),bodyA:i,bodyB:n,collision:t,contacts:[],activeContacts:[],separation:0,isActive:!0,confirmedActive:!0,isSensor:i.isSensor||n.isSensor,timeCreated:e,timeUpdated:e,inverseMass:0,friction:0,frictionStatic:0,restitution:0,slop:0};return s.update(r,t,e),r},s.update=function(t,e,i){var s=t.contacts,r=e.supports,o=t.activeContacts,a=e.parentA,h=e.parentB,l=a.vertices.length;t.isActive=!0,t.timeUpdated=i,t.collision=e,t.separation=e.depth,t.inverseMass=a.inverseMass+h.inverseMass,t.friction=a.frictionh.frictionStatic?a.frictionStatic:h.frictionStatic,t.restitution=a.restitution>h.restitution?a.restitution:h.restitution,t.slop=a.slop>h.slop?a.slop:h.slop,e.pair=t,o.length=0;for(var u=0;u{var s={};t.exports=s;var n=i(70584),r=i(68758);s.create=function(t){return r.extend({table:{},list:[],collisionStart:[],collisionActive:[],collisionEnd:[]},t)},s.update=function(t,e,i){var s,r,o,a,h=t.list,l=h.length,u=t.table,c=e.length,d=t.collisionStart,f=t.collisionEnd,p=t.collisionActive;for(d.length=0,f.length=0,p.length=0,a=0;a{var s={};t.exports=s;var n=i(10438),r=i(63454),o=i(84091),a=i(68516),h=i(39745);s.collides=function(t,e){for(var i=[],s=e.length,n=t.bounds,a=r.collides,h=o.overlaps,l=0;l{var s={};t.exports=s;var n=i(39745),r=i(68758),o=i(84091);s._restingThresh=2,s._restingThreshTangent=Math.sqrt(6),s._positionDampen=.9,s._positionWarming=.8,s._frictionNormalMultiplier=5,s._frictionMaxStatic=Number.MAX_VALUE,s.preSolvePosition=function(t){var e,i,s,n=t.length;for(e=0;eV?(n=Y>0?Y:-Y,(i=v.friction*(Y>0?1:-1)*l)<-n?i=-n:i>n&&(i=n)):(i=Y,n=f);var W=L*b-F*w,H=D*b-I*w,j=_/(M+m.inverseInertia*W*W+y.inverseInertia*H*H),q=(1+v.restitution)*U*j;if(i*=j,U0&&(R.normalImpulse=0),q=R.normalImpulse-K}if(Y<-c||Y>c)R.tangentImpulse=0;else{var Z=R.tangentImpulse;R.tangentImpulse+=i,R.tangentImpulse<-n&&(R.tangentImpulse=-n),R.tangentImpulse>n&&(R.tangentImpulse=n),i=R.tangentImpulse-Z}var J=w*q+S*i,Q=b*q+E*i;m.isStatic||m.isSleeping||(m.positionPrev.x+=J*m.inverseMass,m.positionPrev.y+=Q*m.inverseMass,m.anglePrev+=(L*Q-F*J)*m.inverseInertia),y.isStatic||y.isSleeping||(y.positionPrev.x-=J*y.inverseMass,y.positionPrev.y-=Q*y.inverseMass,y.anglePrev-=(D*Q-I*J)*y.inverseInertia)}}}}},52838:(t,e,i)=>{var s={};t.exports=s;var n=i(39745),r=i(10438),o=i(22806),a=i(84091),h=i(50658),l=i(68758);s._warming=.4,s._torqueDampen=1,s._minLength=1e-6,s.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?r.add(e.bodyA.position,e.pointA):e.pointA,s=e.bodyB?r.add(e.bodyB.position,e.pointB):e.pointB,n=r.magnitude(r.sub(i,s));e.length=void 0!==e.length?e.length:n,e.id=e.id||l.nextId(),e.label=e.label||"Constraint",e.type="constraint",e.stiffness=e.stiffness||(e.length>0?1:.7),e.damping=e.damping||0,e.angularStiffness=e.angularStiffness||0,e.angleA=e.bodyA?e.bodyA.angle:e.angleA,e.angleB=e.bodyB?e.bodyB.angle:e.angleB,e.plugin={};var o={visible:!0,type:"line",anchors:!0,lineColor:null,lineOpacity:null,lineThickness:null,pinSize:null,anchorColor:null,anchorSize:null};return 0===e.length&&e.stiffness>.1?(o.type="pin",o.anchors=!1):e.stiffness<.9&&(o.type="spring"),e.render=l.extend(o,e.render),e},s.preSolveAll=function(t){for(var e=0;e=1||0===t.length?t.stiffness*e:t.stiffness*e*e,x=t.damping*e,T=r.mult(u,m*y),w=(i?i.inverseMass:0)+(n?n.inverseMass:0),b=w+((i?i.inverseInertia:0)+(n?n.inverseInertia:0));if(x>0){var S=r.create();p=r.div(u,c),g=r.sub(n&&r.sub(n.position,n.positionPrev)||S,i&&r.sub(i.position,i.positionPrev)||S),v=r.dot(p,g)}i&&!i.isStatic&&(f=i.inverseMass/w,i.constraintImpulse.x-=T.x*f,i.constraintImpulse.y-=T.y*f,i.position.x-=T.x*f,i.position.y-=T.y*f,x>0&&(i.positionPrev.x-=x*p.x*v*f,i.positionPrev.y-=x*p.y*v*f),d=r.cross(o,T)/b*s._torqueDampen*i.inverseInertia*(1-t.angularStiffness),i.constraintImpulse.angle-=d,i.angle-=d),n&&!n.isStatic&&(f=n.inverseMass/w,n.constraintImpulse.x+=T.x*f,n.constraintImpulse.y+=T.y*f,n.position.x+=T.x*f,n.position.y+=T.y*f,x>0&&(n.positionPrev.x+=x*p.x*v*f,n.positionPrev.y+=x*p.y*v*f),d=r.cross(a,T)/b*s._torqueDampen*n.inverseInertia*(1-t.angularStiffness),n.constraintImpulse.angle+=d,n.angle+=d)}}},s.postSolveAll=function(t){for(var e=0;e0&&(c.position.x+=l.x,c.position.y+=l.y),0!==l.angle&&(n.rotate(c.vertices,l.angle,i.position),h.rotate(c.axes,l.angle),u>0&&r.rotateAbout(c.position,l.angle,i.position,c.position)),a.update(c.bounds,c.vertices,i.velocity)}l.angle*=s._warming,l.x*=s._warming,l.y*=s._warming}}},s.pointAWorld=function(t){return{x:(t.bodyA?t.bodyA.position.x:0)+(t.pointA?t.pointA.x:0),y:(t.bodyA?t.bodyA.position.y:0)+(t.pointA?t.pointA.y:0)}},s.pointBWorld=function(t){return{x:(t.bodyB?t.bodyB.position.x:0)+(t.pointB?t.pointB.x:0),y:(t.bodyB?t.bodyB.position.y:0)+(t.pointB?t.pointB.y:0)}},s.currentLength=function(t){var e=(t.bodyA?t.bodyA.position.x:0)+(t.pointA?t.pointA.x:0),i=(t.bodyA?t.bodyA.position.y:0)+(t.pointA?t.pointA.y:0),s=e-((t.bodyB?t.bodyB.position.x:0)+(t.pointB?t.pointB.x:0)),n=i-((t.bodyB?t.bodyB.position.y:0)+(t.pointB?t.pointB.y:0));return Math.sqrt(s*s+n*n)}},68758:(t,e,i)=>{var s={};t.exports=s,function(){s._baseDelta=1e3/60,s._nextId=0,s._seed=0,s._nowStartTime=+new Date,s._warnedOnce={},s._decomp=null,s.extend=function(t,e){var i,n;"boolean"==typeof e?(i=2,n=e):(i=1,n=!0);for(var r=i;r0;e--){var i=Math.floor(s.random()*(e+1)),n=t[e];t[e]=t[i],t[i]=n}return t},s.choose=function(t){return t[Math.floor(s.random()*t.length)]},s.isElement=function(t){return"undefined"!=typeof HTMLElement?t instanceof HTMLElement:!!(t&&t.nodeType&&t.nodeName)},s.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)},s.isFunction=function(t){return"function"==typeof t},s.isPlainObject=function(t){return"object"==typeof t&&t.constructor===Object},s.isString=function(t){return"[object String]"===toString.call(t)},s.clamp=function(t,e,i){return ti?i:t},s.sign=function(t){return t<0?-1:1},s.now=function(){if("undefined"!=typeof window&&window.performance){if(window.performance.now)return window.performance.now();if(window.performance.webkitNow)return window.performance.webkitNow()}return Date.now?Date.now():new Date-s._nowStartTime},s.random=function(e,i){return i=void 0!==i?i:1,(e=void 0!==e?e:0)+t()*(i-e)};var t=function(){return s._seed=(9301*s._seed+49297)%233280,s._seed/233280};s.colorToNumber=function(t){return 3==(t=t.replace("#","")).length&&(t=t.charAt(0)+t.charAt(0)+t.charAt(1)+t.charAt(1)+t.charAt(2)+t.charAt(2)),parseInt(t,16)},s.logLevel=1,s.log=function(){console&&s.logLevel>0&&s.logLevel<=3&&console.log.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},s.info=function(){console&&s.logLevel>0&&s.logLevel<=2&&console.info.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},s.warn=function(){console&&s.logLevel>0&&s.logLevel<=3&&console.warn.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},s.warnOnce=function(){var t=Array.prototype.slice.call(arguments).join(" ");s._warnedOnce[t]||(s.warn(t),s._warnedOnce[t]=!0)},s.deprecated=function(t,e,i){t[e]=s.chain((function(){s.warnOnce("🔅 deprecated 🔅",i)}),t[e])},s.nextId=function(){return s._nextId++},s.indexOf=function(t,e){if(t.indexOf)return t.indexOf(e);for(var i=0;i{var s={};t.exports=s;var n=i(22806),r=i(44272),o=i(13657),a=i(91327),h=i(39073),l=i(11299),u=i(52838),c=i(68758),d=i(84125);s.create=function(t){t=t||{};var e=c.extend({positionIterations:6,velocityIterations:4,constraintIterations:2,enableSleeping:!1,events:[],plugin:{},gravity:{x:0,y:1,scale:.001},timing:{timestamp:0,timeScale:1,lastDelta:0,lastElapsed:0}},t);return e.world=t.world||l.create({label:"World"}),e.pairs=t.pairs||a.create(),e.detector=t.detector||o.create(),e.grid={buckets:[]},e.world.gravity=e.gravity,e.broadphase=e.grid,e.metrics={},e},s.update=function(t,e){var i,d=c.now(),f=t.world,p=t.detector,v=t.pairs,g=t.timing,m=g.timestamp;e=void 0!==e?e:c._baseDelta,e*=g.timeScale,g.timestamp+=e,g.lastDelta=e;var y={timestamp:g.timestamp,delta:e};h.trigger(t,"beforeUpdate",y);var x=l.allBodies(f),T=l.allConstraints(f);for(f.isModified&&(o.setBodies(p,x),l.setModified(f,!1,!1,!0)),t.enableSleeping&&n.update(x,e),s._bodiesApplyGravity(x,t.gravity),e>0&&s._bodiesUpdate(x,e),h.trigger(t,"beforeSolve",y),u.preSolveAll(x),i=0;i0&&h.trigger(t,"collisionStart",{pairs:v.collisionStart,timestamp:g.timestamp,delta:e});var b=c.clamp(20/t.positionIterations,0,1);for(r.preSolvePosition(v.list),i=0;i0&&h.trigger(t,"collisionActive",{pairs:v.collisionActive,timestamp:g.timestamp,delta:e}),v.collisionEnd.length>0&&h.trigger(t,"collisionEnd",{pairs:v.collisionEnd,timestamp:g.timestamp,delta:e}),s._bodiesClearForces(x),h.trigger(t,"afterUpdate",y),t.timing.lastElapsed=c.now()-d,t},s.merge=function(t,e){if(c.extend(t,e),e.world){t.world=e.world,s.clear(t);for(var i=l.allBodies(t.world),r=0;r{var s={};t.exports=s;var n=i(68758);s.on=function(t,e,i){for(var s,n=e.split(" "),r=0;r0){i||(i={}),s=e.split(" ");for(var l=0;l{var s={};t.exports=s;var n=i(84474),r=i(68758);s.name="matter-js",s.version="0.19.0",s.uses=[],s.used=[],s.use=function(){n.use(s,Array.prototype.slice.call(arguments))},s.before=function(t,e){return t=t.replace(/^Matter./,""),r.chainPathBefore(s,t,e)},s.after=function(t,e){return t=t.replace(/^Matter./,""),r.chainPathAfter(s,t,e)}},84474:(t,e,i)=>{var s={};t.exports=s;var n=i(68758);s._registry={},s.register=function(t){if(s.isPlugin(t)||n.warn("Plugin.register:",s.toString(t),"does not implement all required fields."),t.name in s._registry){var e=s._registry[t.name],i=s.versionParse(t.version).number,r=s.versionParse(e.version).number;i>r?(n.warn("Plugin.register:",s.toString(e),"was upgraded to",s.toString(t)),s._registry[t.name]=t):i-1},s.isFor=function(t,e){var i=t.for&&s.dependencyParse(t.for);return!t.for||e.name===i.name&&s.versionSatisfies(e.version,i.range)},s.use=function(t,e){if(t.uses=(t.uses||[]).concat(e||[]),0!==t.uses.length){for(var i=s.dependencies(t),r=n.topologicalSort(i),o=[],a=0;a0&&!h.silent&&n.info(o.join(" "))}else n.warn("Plugin.use:",s.toString(t),"does not specify any dependencies to install.")},s.dependencies=function(t,e){var i=s.dependencyParse(t),r=i.name;if(!(r in(e=e||{}))){t=s.resolve(t)||t,e[r]=n.map(t.uses||[],(function(e){s.isPlugin(e)&&s.register(e);var r=s.dependencyParse(e),o=s.resolve(e);return o&&!s.versionSatisfies(o.version,r.range)?(n.warn("Plugin.dependencies:",s.toString(o),"does not satisfy",s.toString(r),"used by",s.toString(i)+"."),o._warned=!0,t._warned=!0):o||(n.warn("Plugin.dependencies:",s.toString(e),"used by",s.toString(i),"could not be resolved."),t._warned=!0),r.name}));for(var o=0;o=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-+]+)?$/;e.test(t)||n.warn("Plugin.versionParse:",t,"is not a valid version or range.");var i=e.exec(t),s=Number(i[4]),r=Number(i[5]),o=Number(i[6]);return{isRange:Boolean(i[1]||i[2]),version:i[3],range:t,operator:i[1]||i[2]||"",major:s,minor:r,patch:o,parts:[s,r,o],prerelease:i[7],number:1e8*s+1e4*r+o}},s.versionSatisfies=function(t,e){e=e||"*";var i=s.versionParse(e),n=s.versionParse(t);if(i.isRange){if("*"===i.operator||"*"===t)return!0;if(">"===i.operator)return n.number>i.number;if(">="===i.operator)return n.number>=i.number;if("~"===i.operator)return n.major===i.major&&n.minor===i.minor&&n.patch>=i.patch;if("^"===i.operator)return i.major>0?n.major===i.major&&n.number>=i.number:i.minor>0?n.minor===i.minor&&n.patch>=i.patch:n.patch===i.patch}return t===e||"*"===t}},22806:(t,e,i)=>{var s={};t.exports=s;var n=i(84125),r=i(39073),o=i(68758);s._motionWakeThreshold=.18,s._motionSleepThreshold=.08,s._minBias=.9,s.update=function(t,e){for(var i=e/o._baseDelta,r=s._motionSleepThreshold,a=0;a0&&h.motion=h.sleepThreshold/i&&s.set(h,!0)):h.sleepCounter>0&&(h.sleepCounter-=1)}else s.set(h,!1)}},s.afterCollisions=function(t){for(var e=s._motionSleepThreshold,i=0;ie&&s.set(h,!1)}}}},s.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||r.trigger(t,"sleepStart")):(t.isSleeping=!1,t.sleepCounter=0,i&&r.trigger(t,"sleepEnd"))}},68516:(t,e,i)=>{var s={};t.exports=s;var n=i(39745),r=i(68758),o=i(84125),a=i(84091),h=i(10438);s.rectangle=function(t,e,i,s,a){a=a||{};var h={label:"Rectangle Body",position:{x:t,y:e},vertices:n.fromPath("L 0 0 L "+i+" 0 L "+i+" "+s+" L 0 "+s)};if(a.chamfer){var l=a.chamfer;h.vertices=n.chamfer(h.vertices,l.radius,l.quality,l.qualityMin,l.qualityMax),delete a.chamfer}return o.create(r.extend({},h,a))},s.trapezoid=function(t,e,i,s,a,h){h=h||{};var l,u=i*(a*=.5),c=u+(1-2*a)*i,d=c+u;l=a<.5?"L 0 0 L "+u+" "+-s+" L "+c+" "+-s+" L "+d+" 0":"L 0 0 L "+c+" "+-s+" L "+d+" 0";var f={label:"Trapezoid Body",position:{x:t,y:e},vertices:n.fromPath(l)};if(h.chamfer){var p=h.chamfer;f.vertices=n.chamfer(f.vertices,p.radius,p.quality,p.qualityMin,p.qualityMax),delete h.chamfer}return o.create(r.extend({},f,h))},s.circle=function(t,e,i,n,o){n=n||{};var a={label:"Circle Body",circleRadius:i};o=o||25;var h=Math.ceil(Math.max(10,Math.min(o,i)));return h%2==1&&(h+=1),s.polygon(t,e,h,i,r.extend({},a,n))},s.polygon=function(t,e,i,a,h){if(h=h||{},i<3)return s.circle(t,e,a,h);for(var l=2*Math.PI/i,u="",c=.5*l,d=0;d0&&n.area(C)1?(p=o.create(r.extend({parts:v.slice(0)},s)),o.setPosition(p,{x:t,y:e}),p):v[0]},s.flagCoincidentParts=function(t,e){void 0===e&&(e=5);for(var i=0;i{var s={};t.exports=s;var n=i(11299),r=i(52838),o=i(68758),a=i(84125),h=i(68516);s.stack=function(t,e,i,s,r,o,h){for(var l,u=n.create({label:"Stack"}),c=t,d=e,f=0,p=0;pv&&(v=y),a.translate(m,{x:.5*x,y:.5*y}),c=m.bounds.max.x+r,n.addBody(u,m),l=m,f+=1}else c+=r}d+=v+o,c=t}return u},s.chain=function(t,e,i,s,a,h){for(var l=t.bodies,u=1;u0)for(l=0;l0&&(d=f[l-1+(h-1)*e],n.addConstraint(t,r.create(o.extend({bodyA:d,bodyB:c},a)))),s&&ld||o<(l=d-l)||o>i-1-l))return 1===c&&a.translate(u,{x:(o+(i%2==1?1:-1))*f,y:0}),h(t+(u?o*f:0)+o*r,s,o,l,u,c)}))},s.newtonsCradle=function(t,e,i,s,o){for(var a=n.create({label:"Newtons Cradle"}),l=0;l{var s={};t.exports=s;var n=i(10438),r=i(68758);s.fromVertices=function(t){for(var e={},i=0;i{var e={};t.exports=e,e.create=function(t){var i={min:{x:0,y:0},max:{x:0,y:0}};return t&&e.update(i,t),i},e.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 s=0;st.max.x&&(t.max.x=n.x),n.xt.max.y&&(t.max.y=n.y),n.y0?t.max.x+=i.x:t.min.x+=i.x,i.y>0?t.max.y+=i.y:t.min.y+=i.y)},e.contains=function(t,e){return e.x>=t.min.x&&e.x<=t.max.x&&e.y>=t.min.y&&e.y<=t.max.y},e.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},e.translate=function(t,e){t.min.x+=e.x,t.max.x+=e.x,t.min.y+=e.y,t.max.y+=e.y},e.shift=function(t,e){var i=t.max.x-t.min.x,s=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+s}},92765:(t,e,i)=>{var s={};t.exports=s;i(84091);var n=i(68758);s.pathToVertices=function(t,e){"undefined"==typeof window||"SVGPathSeg"in window||n.warn("Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.");var i,r,o,a,h,l,u,c,d,f,p,v=[],g=0,m=0,y=0;e=e||15;var x=function(t,e,i){var s=i%2==1&&i>1;if(!d||t!=d.x||e!=d.y){d&&s?(f=d.x,p=d.y):(f=0,p=0);var n={x:f+t,y:p+e};!s&&d||(d=n),v.push(n),m=f+t,y=p+e}},T=function(t){var e=t.pathSegTypeAsLetter.toUpperCase();if("Z"!==e){switch(e){case"M":case"L":case"T":case"C":case"S":case"Q":m=t.x,y=t.y;break;case"H":m=t.x;break;case"V":y=t.y}x(m,y,t.pathSegType)}};for(s._svgPathToAbsolute(t),o=t.getTotalLength(),l=[],i=0;i{var e={};t.exports=e,e.create=function(t,e){return{x:t||0,y:e||0}},e.clone=function(t){return{x:t.x,y:t.y}},e.magnitude=function(t){return Math.sqrt(t.x*t.x+t.y*t.y)},e.magnitudeSquared=function(t){return t.x*t.x+t.y*t.y},e.rotate=function(t,e,i){var s=Math.cos(e),n=Math.sin(e);i||(i={});var r=t.x*s-t.y*n;return i.y=t.x*n+t.y*s,i.x=r,i},e.rotateAbout=function(t,e,i,s){var n=Math.cos(e),r=Math.sin(e);s||(s={});var o=i.x+((t.x-i.x)*n-(t.y-i.y)*r);return s.y=i.y+((t.x-i.x)*r+(t.y-i.y)*n),s.x=o,s},e.normalise=function(t){var i=e.magnitude(t);return 0===i?{x:0,y:0}:{x:t.x/i,y:t.y/i}},e.dot=function(t,e){return t.x*e.x+t.y*e.y},e.cross=function(t,e){return t.x*e.y-t.y*e.x},e.cross3=function(t,e,i){return(e.x-t.x)*(i.y-t.y)-(e.y-t.y)*(i.x-t.x)},e.add=function(t,e,i){return i||(i={}),i.x=t.x+e.x,i.y=t.y+e.y,i},e.sub=function(t,e,i){return i||(i={}),i.x=t.x-e.x,i.y=t.y-e.y,i},e.mult=function(t,e){return{x:t.x*e,y:t.y*e}},e.div=function(t,e){return{x:t.x/e,y:t.y/e}},e.perp=function(t,e){return{x:(e=!0===e?-1:1)*-t.y,y:e*t.x}},e.neg=function(t){return{x:-t.x,y:-t.y}},e.angle=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)},e._temp=[e.create(),e.create(),e.create(),e.create(),e.create(),e.create()]},39745:(t,e,i)=>{var s={};t.exports=s;var n=i(10438),r=i(68758);s.create=function(t,e){for(var i=[],s=0;s0)return!1;o=i}return!0},s.scale=function(t,e,i,r){if(1===e&&1===i)return t;var o,a;r=r||s.centre(t);for(var h=0;h=0?h-1:t.length-1],u=t[h],c=t[(h+1)%t.length],d=e[h0&&(r|=2),3===r)return!1;return 0!==r||null},s.hull=function(t){var e,i,s=[],r=[];for((t=t.slice(0)).sort((function(t,e){var i=t.x-e.x;return 0!==i?i:t.y-e.y})),i=0;i=2&&n.cross3(r[r.length-2],r[r.length-1],e)<=0;)r.pop();r.push(e)}for(i=t.length-1;i>=0;i-=1){for(e=t[i];s.length>=2&&n.cross3(s[s.length-2],s[s.length-1],e)<=0;)s.pop();s.push(e)}return s.pop(),r.pop(),s.concat(r)}},1675:(t,e,i)=>{var s=i(18171),n={name:"matter-attractors",version:"0.1.7",for:"matter-js@^0.19.0",silent:!0,install:function(t){t.after("Body.create",(function(){n.Body.init(this)})),t.before("Engine.update",(function(t){n.Engine.update(t)}))},Body:{init:function(t){t.plugin.attractors=t.plugin.attractors||[]}},Engine:{update:function(t){for(var e=s.Composite.allBodies(t.world),i=0;i0)for(var o=0;o{t.exports={name:"matter-collision-events",version:"0.1.6",for:"matter-js@^0.19.0",silent:!0,install:function(t){t.after("Engine.create",(function(){t.Events.on(this,"collisionStart",(function(e){e.pairs.map((function(e){var i=e.bodyA,s=e.bodyB;i.gameObject&&i.gameObject.emit("collide",i,s,e),s.gameObject&&s.gameObject.emit("collide",s,i,e),t.Events.trigger(i,"onCollide",{pair:e}),t.Events.trigger(s,"onCollide",{pair:e}),i.onCollideCallback&&i.onCollideCallback(e),s.onCollideCallback&&s.onCollideCallback(e),i.onCollideWith[s.id]&&i.onCollideWith[s.id](s,e),s.onCollideWith[i.id]&&s.onCollideWith[i.id](i,e)}))})),t.Events.on(this,"collisionActive",(function(e){e.pairs.map((function(e){var i=e.bodyA,s=e.bodyB;i.gameObject&&i.gameObject.emit("collideActive",i,s,e),s.gameObject&&s.gameObject.emit("collideActive",s,i,e),t.Events.trigger(i,"onCollideActive",{pair:e}),t.Events.trigger(s,"onCollideActive",{pair:e}),i.onCollideActiveCallback&&i.onCollideActiveCallback(e),s.onCollideActiveCallback&&s.onCollideActiveCallback(e)}))})),t.Events.on(this,"collisionEnd",(function(e){e.pairs.map((function(e){var i=e.bodyA,s=e.bodyB;i.gameObject&&i.gameObject.emit("collideEnd",i,s,e),s.gameObject&&s.gameObject.emit("collideEnd",s,i,e),t.Events.trigger(i,"onCollideEnd",{pair:e}),t.Events.trigger(s,"onCollideEnd",{pair:e}),i.onCollideEndCallback&&i.onCollideEndCallback(e),s.onCollideEndCallback&&s.onCollideEndCallback(e)}))}))}))}}},44097:(t,e,i)=>{var s=i(18171),n={name:"matter-wrap",version:"0.1.4",for:"matter-js@^0.19.0",silent:!0,install:function(t){t.after("Engine.update",(function(){n.Engine.update(this)}))},Engine:{update:function(t){for(var e=t.world,i=s.Composite.allBodies(e),r=s.Composite.allComposites(e),o=0;oe.max.x?i=e.min.x-t.max.x:t.max.xe.max.y?s=e.min.y-t.max.y:t.max.y{function e(t,e,i){i=i||0;var s,n,r,o,a,h,l,u=[0,0];return s=t[1][1]-t[0][1],n=t[0][0]-t[1][0],r=s*t[0][0]+n*t[0][1],o=e[1][1]-e[0][1],a=e[0][0]-e[1][0],h=o*e[0][0]+a*e[0][1],S(l=s*a-o*n,0,i)||(u[0]=(a*r-n*h)/l,u[1]=(s*h-o*r)/l),u}function i(t,e,i,s){var n=e[0]-t[0],r=e[1]-t[1],o=s[0]-i[0],a=s[1]-i[1];if(o*r-a*n==0)return!1;var h=(n*(i[1]-t[1])+r*(t[0]-i[0]))/(o*r-a*n),l=(o*(t[1]-i[1])+a*(i[0]-t[0]))/(a*n-o*r);return h>=0&&h<=1&&l>=0&&l<=1}function s(t,e,i){return(e[0]-t[0])*(i[1]-t[1])-(i[0]-t[0])*(e[1]-t[1])}function n(t,e,i){return s(t,e,i)>0}function r(t,e,i){return s(t,e,i)>=0}function o(t,e,i){return s(t,e,i)<0}function a(t,e,i){return s(t,e,i)<=0}t.exports={decomp:function(t){var e=T(t);return e.length>0?w(t,e):[t]},quickDecomp:function t(e,i,s,h,l,u,v){u=u||100,v=v||0,l=l||25,i=void 0!==i?i:[],s=s||[],h=h||[];var g=[0,0],m=[0,0],x=[0,0],T=0,w=0,S=0,E=0,A=0,C=0,_=0,M=[],P=[],R=e,O=e;if(O.length<3)return i;if(++v>u)return console.warn("quickDecomp: max level ("+u+") reached."),i;for(var L=0;LA&&(A+=e.length),E=Number.MAX_VALUE,A3&&s>=0;--s)u(d(t,s-1),d(t,s),d(t,s+1),e)&&(t.splice(s%t.length,1),i++);return i},removeDuplicatePoints:function(t,e){for(var i=t.length-1;i>=1;--i)for(var s=t[i],n=i-1;n>=0;--n)E(s,t[n],e)&&t.splice(i,1)},makeCCW:function(t){for(var e=0,i=t,s=1;si[e][0])&&(e=s);return!n(d(t,e-1),d(t,e),d(t,e+1))&&(function(t){for(var e=[],i=t.length,s=0;s!==i;s++)e.push(t.pop());for(s=0;s!==i;s++)t[s]=e[s]}(t),!0)}};var h=[],l=[];function u(t,e,i,n){if(n){var r=h,o=l;r[0]=e[0]-t[0],r[1]=e[1]-t[1],o[0]=i[0]-e[0],o[1]=i[1]-e[1];var a=r[0]*o[0]+r[1]*o[1],u=Math.sqrt(r[0]*r[0]+r[1]*r[1]),c=Math.sqrt(o[0]*o[0]+o[1]*o[1]);return Math.acos(a/(u*c)){var s=new(i(56694))({initialize:function(t){this.pluginManager=t,this.game=t.game},init:function(){},start:function(){},stop:function(){},destroy:function(){this.pluginManager=null,this.game=null,this.scene=null,this.systems=null}});t.exports=s},18360:t=>{t.exports={Global:["game","anims","cache","plugins","registry","scale","sound","textures","renderer"],CoreScene:["EventEmitter","CameraManager","GameObjectCreator","GameObjectFactory","ScenePlugin","DisplayList","UpdateList"],DefaultScene:["Clock","DataManagerPlugin","InputPlugin","Loader","TweenManager","LightsPlugin"]}},91963:t=>{var e={},i={},s={register:function(t,i,s,n){void 0===n&&(n=!1),e[t]={plugin:i,mapping:s,custom:n}},registerCustom:function(t,e,s,n){i[t]={plugin:e,mapping:s,data:n}},hasCore:function(t){return e.hasOwnProperty(t)},hasCustom:function(t){return i.hasOwnProperty(t)},getCore:function(t){return e[t]},getCustom:function(t){return i[t]},getCustomClass:function(t){return i.hasOwnProperty(t)?i[t].plugin:null},remove:function(t){e.hasOwnProperty(t)&&delete e[t]},removeCustom:function(t){i.hasOwnProperty(t)&&delete i[t]},destroyCorePlugins:function(){for(var t in e)e.hasOwnProperty(t)&&delete e[t]},destroyCustomPlugins:function(){for(var t in i)i.hasOwnProperty(t)&&delete i[t]}};t.exports=s},49274:(t,e,i)=>{var s=i(56694),n=i(97081),r=i(6659),o=i(76846),a=i(99325),h=i(61286),l=i(72632),u=i(91963),c=i(66458),d=new s({Extends:r,initialize:function(t){r.call(this),this.game=t,this.plugins=[],this.scenePlugins=[],this._pendingGlobal=[],this._pendingScene=[],t.isBooted?this.boot():t.events.once(n.BOOT,this.boot,this)},boot:function(){var t,e,i,s,r,o,a,h=this.game.config,u=h.installGlobalPlugins;for(u=u.concat(this._pendingGlobal),t=0;t{var s=i(88257),n=i(56694),r=i(7599),o=new n({Extends:s,initialize:function(t,e,i){s.call(this,e),this.scene=t,this.systems=t.sys,this.pluginKey=i,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},45615:(t,e,i)=>{t.exports={BasePlugin:i(88257),DefaultPlugins:i(18360),PluginCache:i(91963),PluginManager:i(49274),ScenePlugin:i(39283)}},75205:()=>{!("requestVideoFrameCallback"in HTMLVideoElement.prototype)&&"getVideoPlaybackQuality"in HTMLVideoElement.prototype&&(HTMLVideoElement.prototype._rvfcpolyfillmap={},HTMLVideoElement.prototype.requestVideoFrameCallback=function(t){const e=performance.now(),i=this.getVideoPlaybackQuality(),s=this.mozPresentedFrames||this.mozPaintedFrames||i.totalVideoFrames-i.droppedVideoFrames,n=(r,o)=>{const a=this.getVideoPlaybackQuality(),h=this.mozPresentedFrames||this.mozPaintedFrames||a.totalVideoFrames-a.droppedVideoFrames;if(h>s){const s=this.mozFrameDelay||a.totalFrameDelay-i.totalFrameDelay||0,n=o-r;t(o,{presentationTime:o+1e3*s,expectedDisplayTime:o+n,width:this.videoWidth,height:this.videoHeight,mediaTime:Math.max(0,this.currentTime||0)+n/1e3,presentedFrames:h,processingDuration:s}),delete this._rvfcpolyfillmap[e]}else this._rvfcpolyfillmap[e]=requestAnimationFrame((t=>n(o,t)))};return this._rvfcpolyfillmap[e]=requestAnimationFrame((t=>n(e,t))),e},HTMLVideoElement.prototype.cancelVideoFrameCallback=function(t){cancelAnimationFrame(this._rvfcpolyfillmap[t]),delete this._rvfcpolyfillmap[t]})},95723:t=>{t.exports={SKIP_CHECK:-1,NORMAL:0,ADD:1,MULTIPLY:2,SCREEN:3,OVERLAY:4,DARKEN:5,LIGHTEN:6,COLOR_DODGE:7,COLOR_BURN:8,HARD_LIGHT:9,SOFT_LIGHT:10,DIFFERENCE:11,EXCLUSION:12,HUE:13,SATURATION:14,COLOR:15,LUMINOSITY:16,ERASE:17,SOURCE_IN:18,SOURCE_OUT:19,SOURCE_ATOP:20,DESTINATION_OVER:21,DESTINATION_IN:22,DESTINATION_OUT:23,DESTINATION_ATOP:24,LIGHTER:25,COPY:26,XOR:27}},27394:t=>{t.exports={DEFAULT:0,LINEAR:0,NEAREST:1}},91135:(t,e,i)=>{var s=i(89787),n=i(61840),r=i(56694),o=i(86459),a=i(6659),h=i(81044),l=i(32834),u=i(40444),c=i(38203),d=i(69360),f=new r({Extends:a,initialize:function(t){a.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=o.CANVAS,this.drawCount=0,this.width=0,this.height=0,this.gameCanvas=t.canvas;var i={alpha:t.config.transparent,desynchronized:t.config.desynchronized,willReadFrequently:!1};this.gameContext=e.context?e.context:this.gameCanvas.getContext("2d",i),this.currentContext=this.gameContext,this.antialias=t.config.antialias,this.blendModes=l(),this.snapshotState={x:0,y:0,width:1,height:1,getPixel:!1,callback:null,type:"image/png",encoder:.92},this._tempMatrix1=new d,this._tempMatrix2=new d,this._tempMatrix3=new d,this.isBooted=!1,this.init()},init:function(){this.game.textures.once(c.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(u.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(h.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,s=this.height;t.globalAlpha=1,t.globalCompositeOperation="source-over",t.setTransform(1,0,0,1,0,0),e.clearBeforeRender&&(t.clearRect(0,0,i,s),e.transparent||(t.fillStyle=e.backgroundColor.rgba,t.fillRect(0,0,i,s))),t.save(),this.drawCount=0,this.emit(h.PRE_RENDER)},render:function(t,e,i){var n=e.length;this.emit(h.RENDER,t,i);var r=i.x,o=i.y,a=i.width,l=i.height,u=i.renderToTexture?i.context:t.sys.context;u.save(),this.game.scene.customViewports&&(u.beginPath(),u.rect(r,o,a,l),u.clip()),i.emit(s.PRE_RENDER,i),this.currentContext=u;var c=i.mask;c&&c.preRenderCanvas(this,null,i._maskCamera),i.transparent||(u.fillStyle=i.backgroundColor.rgba,u.fillRect(r,o,a,l)),u.globalAlpha=i.alpha,u.globalCompositeOperation="source-over",this.drawCount+=n,i.renderToTexture&&i.emit(s.PRE_RENDER,i),i.matrix.copyToContext(u);for(var d=0;d=0?m=-(m+c):m<0&&(m=Math.abs(m)-c)),t.flipY&&(y>=0?y=-(y+d):y<0&&(y=Math.abs(y)-d))}var T=1,w=1;t.flipX&&(f||(m+=-e.realWidth+2*v),T=-1),t.flipY&&(f||(y+=-e.realHeight+2*g),w=-1);var b=t.x,S=t.y;i.roundPixels&&(b=Math.floor(b),S=Math.floor(S)),a.applyITRS(b,S,t.rotation,t.scaleX*T,t.scaleY*w),o.copyFrom(i.matrix),s?(o.multiplyWithOffset(s,-i.scrollX*t.scrollFactorX,-i.scrollY*t.scrollFactorY),a.e=b,a.f=S):(a.e-=i.scrollX*t.scrollFactorX,a.f-=i.scrollY*t.scrollFactorY),o.multiply(a),i.roundPixels&&(o.e=Math.round(o.e),o.f=Math.round(o.f)),r.save(),o.setToContext(r),r.globalCompositeOperation=this.blendModes[t.blendMode],r.globalAlpha=n,r.imageSmoothingEnabled=!e.source.scaleMode,t.mask&&t.mask.preRenderCanvas(this,t,i),c>0&&d>0&&r.drawImage(e.source.image,l,u,c,d,m,y,c/p,d/p),t.mask&&t.mask.postRenderCanvas(this,t,i),r.restore()}},destroy:function(){this.removeAllListeners(),this.game=null,this.gameCanvas=null,this.gameContext=null}});t.exports=f},6046:(t,e,i)=>{t.exports={CanvasRenderer:i(91135),GetBlendModes:i(32834),SetTransform:i(49584)}},32834:(t,e,i)=>{var s=i(95723),n=i(98581);t.exports=function(){var t=[],e=n.supportNewBlendModes,i="source-over";return t[s.NORMAL]=i,t[s.ADD]="lighter",t[s.MULTIPLY]=e?"multiply":i,t[s.SCREEN]=e?"screen":i,t[s.OVERLAY]=e?"overlay":i,t[s.DARKEN]=e?"darken":i,t[s.LIGHTEN]=e?"lighten":i,t[s.COLOR_DODGE]=e?"color-dodge":i,t[s.COLOR_BURN]=e?"color-burn":i,t[s.HARD_LIGHT]=e?"hard-light":i,t[s.SOFT_LIGHT]=e?"soft-light":i,t[s.DIFFERENCE]=e?"difference":i,t[s.EXCLUSION]=e?"exclusion":i,t[s.HUE]=e?"hue":i,t[s.SATURATION]=e?"saturation":i,t[s.COLOR]=e?"color":i,t[s.LUMINOSITY]=e?"luminosity":i,t[s.ERASE]="destination-out",t[s.SOURCE_IN]="source-in",t[s.SOURCE_OUT]="source-out",t[s.SOURCE_ATOP]="source-atop",t[s.DESTINATION_OVER]="destination-over",t[s.DESTINATION_IN]="destination-in",t[s.DESTINATION_OUT]="destination-out",t[s.DESTINATION_ATOP]="destination-atop",t[s.LIGHTER]="lighter",t[s.COPY]="copy",t[s.XOR]="xor",t}},49584:(t,e,i)=>{var s=i(73329);t.exports=function(t,e,i,n,r){var o=n.alpha*i.alpha;if(o<=0)return!1;var a=s(i,n,r).calc;return e.globalCompositeOperation=t.blendModes[i.blendMode],e.globalAlpha=o,e.save(),a.setToContext(e),e.imageSmoothingEnabled=i.frame?!i.frame.source.scaleMode:t.antialias,!0}},70936:t=>{t.exports="postrender"},99298:t=>{t.exports="prerender"},7743:t=>{t.exports="render"},99519:t=>{t.exports="resize"},81044:(t,e,i)=>{t.exports={POST_RENDER:i(70936),PRE_RENDER:i(99298),RENDER:i(7743),RESIZE:i(99519)}},42069:(t,e,i)=>{t.exports={Canvas:i(6046),Events:i(81044),Snapshot:i(95528),WebGL:i(55478)}},61840:(t,e,i)=>{var s=i(61068),n=i(27119),r=i(72632);t.exports=function(t,e){var i=r(e,"callback"),o=r(e,"type","image/png"),a=r(e,"encoder",.92),h=Math.abs(Math.round(r(e,"x",0))),l=Math.abs(Math.round(r(e,"y",0))),u=Math.floor(r(e,"width",t.width)),c=Math.floor(r(e,"height",t.height));if(r(e,"getPixel",!1)){var d=t.getContext("2d",{willReadFrequently:!1}).getImageData(h,l,1,1).data;i.call(null,new n(d[0],d[1],d[2],d[3]))}else if(0!==h||0!==l||u!==t.width||c!==t.height){var f=s.createWebGL(this,u,c),p=f.getContext("2d",{willReadFrequently:!0});u>0&&c>0&&p.drawImage(t,h,l,u,c,0,0,u,c);var v=new Image;v.onerror=function(){i.call(null),s.remove(f)},v.onload=function(){i.call(null,v),s.remove(f)},v.src=f.toDataURL(o,a)}else{var g=new Image;g.onerror=function(){i.call(null)},g.onload=function(){i.call(null,g)},g.src=t.toDataURL(o,a)}}},1217:(t,e,i)=>{var s=i(61068),n=i(27119),r=i(72632);t.exports=function(t,e){var i=t,o=r(e,"callback"),a=r(e,"type","image/png"),h=r(e,"encoder",.92),l=Math.abs(Math.round(r(e,"x",0))),u=Math.abs(Math.round(r(e,"y",0))),c=r(e,"getPixel",!1),d=r(e,"isFramebuffer",!1),f=d?r(e,"bufferWidth",1):i.drawingBufferWidth,p=d?r(e,"bufferHeight",1):i.drawingBufferHeight;if(c){var v=new Uint8Array(4),g=d?u:p-u;i.readPixels(l,g,1,1,i.RGBA,i.UNSIGNED_BYTE,v),o.call(null,new n(v[0],v[1],v[2],v[3]))}else{var m=Math.floor(r(e,"width",f)),y=Math.floor(r(e,"height",p)),x=m*y*4,T=new Uint8Array(x);i.readPixels(l,p-u-y,m,y,i.RGBA,i.UNSIGNED_BYTE,T);for(var w=s.createWebGL(this,m,y),b=w.getContext("2d",{willReadFrequently:!0}),S=b.getImageData(0,0,m,y),E=S.data,A=0;A{t.exports={Canvas:i(61840),WebGL:i(1217)}},35217:(t,e,i)=>{var s=i(56694),n=i(65641),r=i(33885),o=i(77290),a=i(72632),h=i(37410),l=i(82127),u=i(5583),c=i(58136),d=i(47406),f=i(81828),p=i(66901),v=i(71264),g=i(77310),m=i(10919),y=i(21213),x=i(51212),T=i(60848),w=new s({initialize:function(t){this.game=t.game,this.renderer=t,this.classes=new r([[n.UTILITY_PIPELINE,T],[n.MULTI_PIPELINE,g],[n.BITMAPMASK_PIPELINE,u],[n.SINGLE_PIPELINE,x],[n.ROPE_PIPELINE,y],[n.LIGHT_PIPELINE,p],[n.POINTLIGHT_PIPELINE,m],[n.MOBILE_PIPELINE,v],[n.FX_PIPELINE,f]]),this.postPipelineClasses=new r([[String(d.BARREL),c.Barrel],[String(d.BLOOM),c.Bloom],[String(d.BLUR),c.Blur],[String(d.BOKEH),c.Bokeh],[String(d.CIRCLE),c.Circle],[String(d.COLOR_MATRIX),c.ColorMatrix],[String(d.DISPLACEMENT),c.Displacement],[String(d.GLOW),c.Glow],[String(d.GRADIENT),c.Gradient],[String(d.PIXELATE),c.Pixelate],[String(d.SHADOW),c.Shadow],[String(d.SHINE),c.Shine],[String(d.VIGNETTE),c.Vignette],[String(d.WIPE),c.Wipe]]),this.pipelines=new r,this.default=null,this.current=null,this.previous=null,this.MULTI_PIPELINE=null,this.BITMAPMASK_PIPELINE=null,this.UTILITY_PIPELINE=null,this.MOBILE_PIPELINE=null,this.FX_PIPELINE=null,this.fullFrame1,this.fullFrame2,this.halfFrame1,this.halfFrame2,this.renderTargets=[],this.maxDimension=0,this.frameInc=32,this.targetIndex=0},boot:function(t,e,i){var s=this.renderer,r=this.renderTargets;this.frameInc=Math.floor(a(t,"frameInc",32));for(var l,u,c=s.width,d=s.height,f=Math.min(c,d),p=Math.ceil(f/this.frameInc),v=1;v=0;i--){var s=e[i];s.active&&s.preBatch(t)}}},postBatch:function(t){if(t.hasPostPipeline){this.flush();for(var e=t.postPipelines,i=0;i=0;i--){var s=e[i];s.active&&s.preBatch(t)}}},postBatchCamera:function(t){if(t.hasPostPipeline){this.flush();for(var e=t.postPipelines,i=0;ithis.maxDimension)return this.targetIndex=e.length-3,e[this.targetIndex];var i=3*(l(t,this.frameInc,0,!0)-1);return this.targetIndex=i,e[i]},getSwapRenderTarget:function(){return this.renderTargets[this.targetIndex+1]},getAltSwapRenderTarget:function(){return this.renderTargets[this.targetIndex+2]},destroy:function(){this.flush(),this.classes.clear(),this.postPipelineClasses.clear(),this.pipelines.clear(),this.renderer=null,this.game=null,this.classes=null,this.postPipelineClasses=null,this.pipelines=null,this.default=null,this.current=null,this.previous=null}});t.exports=w},37410:(t,e,i)=>{var s=i(56694),n=i(81044),r=new s({initialize:function(t,e,i,s,n,r,o,a,h){void 0===s&&(s=1),void 0===n&&(n=0),void 0===r&&(r=!0),void 0===o&&(o=!1),void 0===a&&(a=!0),void 0===h&&(h=!0),this.renderer=t,this.framebuffer=null,this.texture=null,this.width=0,this.height=0,this.scale=s,this.minFilter=n,this.autoClear=r,this.autoResize=!0,this.hasDepthBuffer=a,this.forceClamp=h,this.resize(e,i),o?this.setAutoResize(!0):this.autoResize=!1},setAutoResize:function(t){return t&&!this.autoResize?(this.renderer.on(n.RESIZE,this.resize,this),this.autoResize=!0):!t&&this.autoResize&&(this.renderer.off(n.RESIZE,this.resize,this),this.autoResize=!1),this},resize:function(t,e){var i=t*this.scale,s=e*this.scale;if(this.autoResize&&(i!==this.width||s!==this.height)){var n=this.renderer;n.deleteFramebuffer(this.framebuffer),n.deleteTexture(this.texture),t*=this.scale,e*=this.scale,(t=Math.round(t))<=0&&(t=1),(e=Math.round(e))<=0&&(e=1),this.texture=n.createTextureFromSource(null,t,e,this.minFilter,this.forceClamp),this.framebuffer=n.createFramebuffer(t,e,this.texture,this.hasDepthBuffer),this.width=t,this.height=e}return this},bind:function(t,e,i){void 0===t&&(t=!1);var s=this.renderer;if(t&&s.flush(),e&&i&&this.resize(e,i),s.pushFramebuffer(this.framebuffer,!1,!1),t&&this.adjustViewport(),this.autoClear){var n=this.renderer.gl;n.clearColor(0,0,0,0),n.clear(n.COLOR_BUFFER_BIT)}s.clearStencilMask()},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(n.RESIZE,this.resize,this),this.renderer=null,this.framebuffer=null,this.texture=null}});t.exports=r},75512:t=>{t.exports={getTintFromFloats:function(t,e,i,s){return((255&(255*s|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){var i=Math.min(16,t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS));return e&&-1!==e?Math.min(i,e):i},parseFragmentShaderMaxTextures:function(t,e){if(!t)return"";for(var i="",s=0;s0&&(i+="\n\telse "),s{var s=i(56694),n=i(28699),r=i(6659),o=i(18970),a=i(72632),h=i(16650),l=i(81044),u=i(37410),c=i(75512),d=i(71305),f=new s({Extends:r,initialize:function(t){r.call(this);var e=t.game,i=e.renderer,s=i.gl;this.name=a(t,"name","WebGLPipeline"),this.game=e,this.renderer=i,this.manager,this.gl=s,this.view=e.canvas,this.width=0,this.height=0,this.vertexCount=0,this.vertexCapacity=0,this.vertexData,this.vertexBuffer,this.activeBuffer,this.topology=a(t,"topology",s.TRIANGLES),this.bytes,this.vertexViewF32,this.vertexViewU32,this.active=!0,this.forceZero=a(t,"forceZero",!1),this.hasBooted=!1,this.isPostFX=!1,this.isPreFX=!1,this.renderTargets=[],this.currentRenderTarget,this.shaders=[],this.currentShader,this.projectionMatrix,this.projectionWidth=0,this.projectionHeight=0,this.config=t,this.glReset=!1,this.batch=[],this.currentBatch=null,this.currentTexture=null,this.currentUnit=0,this.activeTextures=[]},boot:function(){var t,e=this.gl,i=this.config,s=this.renderer;this.isPostFX||(this.projectionMatrix=(new h).identity());var n=this.renderTargets,r=a(i,"renderTarget",!1);"boolean"==typeof r&&r&&(r=1);var c=s.width,d=s.height;if("number"==typeof r)for(t=0;tx&&(x=y[t].vertexSize);var T=a(i,"batchSize",s.config.batchSize);this.vertexCapacity=6*T;var w=new ArrayBuffer(this.vertexCapacity*x);this.vertexData=w,this.bytes=new Uint8Array(w),this.vertexViewF32=new Float32Array(w),this.vertexViewU32=new Uint32Array(w);var b=a(i,"vertices",null);for(b?(this.vertexViewF32.set(b),this.vertexBuffer=s.createVertexBuffer(w,e.STATIC_DRAW)):this.vertexBuffer=s.createVertexBuffer(w.byteLength,e.DYNAMIC_DRAW),this.setVertexBuffer(),t=y.length-1;t>=0;t--)y[t].rebind();this.hasBooted=!0,s.on(l.RESIZE,this.resize,this),s.on(l.PRE_RENDER,this.onPreRender,this),s.on(l.RENDER,this.onRender,this),s.on(l.POST_RENDER,this.onPostRender,this),this.emit(o.BOOT,this),this.onBoot()},onBoot:function(){},onResize:function(){},setShader:function(t,e,i){var s=this.renderer;t===this.currentShader&&s.currentProgram===this.currentShader.program||(this.flush(),this.setVertexBuffer(i)&&!e&&(e=!0),t.bind(e,!1),this.currentShader=t);return this},getShaderByName:function(t){for(var e=this.shaders,i=0;i-1&&(m=b.substring(20))}y&&x&&g.push(new d(this,m,y,x,n(T)))}this.shaders=g}return 0===this.shaders.length?console.warn("Pipeline: "+this.name+" - Invalid shader config"):this.currentShader=this.shaders[0],this},createBatch:function(t){return this.currentBatch={start:this.vertexCount,count:0,texture:[t],unit:0,maxUnit:0},this.currentUnit=0,this.currentTexture=t,this.batch.push(this.currentBatch),0},addTextureToBatch:function(t){var e=this.currentBatch;e&&(e.texture.push(t),e.unit++,e.maxUnit++)},pushBatch:function(t){if(!this.currentBatch||this.forceZero&&t!==this.currentTexture)return this.createBatch(t);if(t===this.currentTexture)return this.currentUnit;var e=this.currentBatch,i=e.texture.indexOf(t);return-1===i?e.texture.length===this.renderer.maxTextures?this.createBatch(t):(e.unit++,e.maxUnit++,e.texture.push(t),this.currentUnit=e.unit,this.currentTexture=t,e.unit):(this.currentUnit=i,this.currentTexture=t,i)},setGameObject:function(t,e){return void 0===e&&(e=t.frame),this.pushBatch(e.source.glTexture)},shouldFlush:function(t){return void 0===t&&(t=0),this.vertexCount+t>this.vertexCapacity},vertexAvailable:function(){return this.vertexCapacity-this.vertexCount},resize:function(t,e){t===this.width&&e===this.height||this.flush(),this.width=t,this.height=e;for(var i=this.renderTargets,s=0;s=0;i--){var s=e[i].rebind();t&&s!==t||(this.currentShader=s)}return this.activeTextures.length=0,this.emit(o.REBIND,this.currentShader),this.onActive(this.currentShader),this.onRebind(),this.glReset=!1,this},setVertexBuffer:function(t){if(void 0===t&&(t=this.vertexBuffer),t!==this.activeBuffer){var e=this.gl;return this.gl.bindBuffer(e.ARRAY_BUFFER,t),this.activeBuffer=t,!0}return!1},preBatch:function(t){return this.currentRenderTarget&&this.currentRenderTarget.bind(),this.onPreBatch(t),this},postBatch:function(t){return this.onDraw(this.currentRenderTarget),this.onPostBatch(t),this},onDraw:function(){},unbind:function(){this.currentRenderTarget&&this.currentRenderTarget.unbind()},flush:function(t){if(void 0===t&&(t=!1),this.vertexCount>0){this.emit(o.BEFORE_FLUSH,this,t),this.onBeforeFlush(t);var e=this.gl,i=this.vertexCount,s=this.currentShader.vertexSize,n=this.topology;if(this.active){var r,a,h;this.setVertexBuffer(),i===this.vertexCapacity?e.bufferData(e.ARRAY_BUFFER,this.vertexData,e.DYNAMIC_DRAW):e.bufferSubData(e.ARRAY_BUFFER,0,this.bytes.subarray(0,i*s));var l=this.batch,u=this.activeTextures;if(this.forceZero)for(u[0]||e.activeTexture(e.TEXTURE0),r=0;r{var s=i(66458),n=i(89787),r=i(56694),o=i(86459),a=i(6659),h=i(81044),l=i(28621),u=i(16650),c=i(72283),d=i(35217),f=i(37410),p=i(40444),v=i(38203),g=i(75512),m=i(1217),y=!1,x=new r({Extends:a,initialize:function(t){a.call(this);var e=t.config,i={alpha:e.transparent,desynchronized:e.desynchronized,depth:!0,antialias:e.antialiasGL,premultipliedAlpha:e.premultipliedAlpha,stencil:!0,failIfMajorPerformanceCaveat:e.failIfMajorPerformanceCaveat,powerPreference:e.powerPreference,preserveDrawingBuffer:e.preserveDrawingBuffer,willReadFrequently:!1};this.config={clearBeforeRender:e.clearBeforeRender,antialias:e.antialias,backgroundColor:e.backgroundColor,contextCreation:i,roundPixels:e.roundPixels,maxTextures:e.maxTextures,maxTextureSize:e.maxTextureSize,batchSize:e.batchSize,maxLights:e.maxLights,mipmapFilter:e.mipmapFilter},this.game=t,this.type=o.WEBGL,this.pipelines=null,this.width=0,this.height=0,this.canvas=t.canvas,this.blendModes=[],this.contextLost=!1,this.snapshotState={x:0,y:0,width:1,height:1,getPixel:!1,callback:null,type:"image/png",encoder:.92,isFramebuffer:!1,bufferWidth:0,bufferHeight:0},this.maxTextures=0,this.textureIndexes,this.currentFramebuffer=null,this.fboStack=[],this.currentProgram=null,this.currentBlendMode=1/0,this.currentScissorEnabled=!1,this.currentScissor=null,this.scissorStack=[],this.contextLostHandler=c,this.contextRestoredHandler=c,this.gl=null,this.supportedExtensions=null,this.instancedArraysExtension=null,this.vaoExtension=null,this.extensions={},this.glFormats,this.compression,this.drawingBufferHeight=0,this.blankTexture=null,this.whiteTexture=null,this.maskCount=0,this.maskStack=[],this.currentMask={mask:null,camera:null},this.currentCameraMask={mask:null,camera:null},this.glFuncMap=null,this.currentType="",this.newType=!1,this.nextTypeMatch=!1,this.finalType=!1,this.mipmapFilter=null,this.defaultScissor=[0,0,0,0],this.isBooted=!1,this.renderTarget=null,this.projectionMatrix,this.projectionWidth=0,this.projectionHeight=0,this.maskSource=null,this.maskTarget=null,this.spector=null,this._debugCapture=!1,this.init(this.config)},init:function(t){var e,i=this.game,s=this.canvas,n=t.backgroundColor;if(!(e=i.config.context?i.config.context:s.getContext("webgl",t.contextCreation)||s.getContext("experimental-webgl",t.contextCreation))||e.isContextLost())throw this.contextLost=!0,new Error("WebGL unsupported");this.gl=e;var r=this;this.contextLostHandler=function(t){r.contextLost=!0,console&&console.warn("WebGL Context lost. Renderer disabled"),t.preventDefault()},s.addEventListener("webglcontextlost",this.contextLostHandler,!1),i.context=e;for(var a=0;a<=27;a++)this.blendModes.push({func:[e.ONE,e.ONE_MINUS_SRC_ALPHA],equation:e.FUNC_ADD});this.blendModes[1].func=[e.ONE,e.DST_ALPHA],this.blendModes[2].func=[e.DST_COLOR,e.ONE_MINUS_SRC_ALPHA],this.blendModes[3].func=[e.ONE,e.ONE_MINUS_SRC_COLOR],this.blendModes[17]={func:[e.ZERO,e.ONE_MINUS_SRC_ALPHA],equation:e.FUNC_REVERSE_SUBTRACT},this.glFormats=[e.BYTE,e.SHORT,e.UNSIGNED_BYTE,e.UNSIGNED_SHORT,e.FLOAT],this.glFuncMap={mat2:{func:e.uniformMatrix2fv,length:1,matrix:!0},mat3:{func:e.uniformMatrix3fv,length:1,matrix:!0},mat4:{func:e.uniformMatrix4fv,length:1,matrix:!0},"1f":{func:e.uniform1f,length:1},"1fv":{func:e.uniform1fv,length:1},"1i":{func:e.uniform1i,length:1},"1iv":{func:e.uniform1iv,length:1},"2f":{func:e.uniform2f,length:2},"2fv":{func:e.uniform2fv,length:1},"2i":{func:e.uniform2i,length:2},"2iv":{func:e.uniform2iv,length:1},"3f":{func:e.uniform3f,length:3},"3fv":{func:e.uniform3fv,length:1},"3i":{func:e.uniform3i,length:3},"3iv":{func:e.uniform3iv,length:1},"4f":{func:e.uniform4f,length:4},"4fv":{func:e.uniform4fv,length:1},"4i":{func:e.uniform4i,length:4},"4iv":{func:e.uniform4iv,length:1}};var h=e.getSupportedExtensions();t.maxTextures&&-1!==t.maxTextures||(t.maxTextures=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS)),t.maxTextureSize||(t.maxTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE)),this.compression=this.getCompressedTextures(),this.supportedExtensions=h;var l="ANGLE_instanced_arrays";this.instancedArraysExtension=h.indexOf(l)>-1?e.getExtension(l):null;var c="OES_vertex_array_object";this.vaoExtension=h.indexOf(c)>-1?e.getExtension(c):null,e.disable(e.DEPTH_TEST),e.disable(e.CULL_FACE),e.enable(e.BLEND),e.clearColor(n.redGL,n.greenGL,n.blueGL,n.alphaGL),""!==t.mipmapFilter&&(this.mipmapFilter=e[t.mipmapFilter]),this.maxTextures=g.checkShaderMax(e,t.maxTextures),this.textureIndexes=[];for(var f=0;f0&&s>0;if(o&&a){var h=o[0],l=o[1],u=o[2],c=o[3];a=h!==t||l!==e||u!==i||c!==s}a&&(this.flush(),r.scissor(t,n-e-s,i,s))},resetScissor:function(){var t=this.gl;t.enable(t.SCISSOR_TEST);var e=this.currentScissor;if(e){var i=e[0],s=e[1],n=e[2],r=e[3];n>0&&r>0&&t.scissor(i,this.drawingBufferHeight-s-r,n,r)}},popScissor:function(){var t=this.scissorStack;t.pop();var e=t[t.length-1];e&&this.setScissor(e[0],e[1],e[2],e[3]),this.currentScissor=e},hasActiveStencilMask:function(){var t=this.currentMask.mask,e=this.currentCameraMask.mask;return t&&t.isStencil||e&&e.isStencil},resetViewport:function(){var t=this.gl;t.viewport(0,0,this.width,this.height),this.drawingBufferHeight=t.drawingBufferHeight},setBlendMode:function(t,e){void 0===e&&(e=!1);var i=this.gl,s=this.blendModes[t];return!!(e||t!==o.BlendModes.SKIP_CHECK&&this.currentBlendMode!==t)&&(this.flush(),i.enable(i.BLEND),i.blendEquation(s.equation),s.func.length>2?i.blendFuncSeparate(s.func[0],s.func[1],s.func[2],s.func[3]):i.blendFunc(s.func[0],s.func[1]),this.currentBlendMode=t,!0)},addBlendMode:function(t,e){return this.blendModes.push({func:t,equation:e})-1},updateBlendMode:function(t,e,i){return this.blendModes[t]&&(this.blendModes[t].func=e,i&&(this.blendModes[t].equation=i)),this},removeBlendMode:function(t){return t>17&&this.blendModes[t]&&this.blendModes.splice(t,1),this},pushFramebuffer:function(t,e,i,s,n){return t===this.currentFramebuffer?this:(this.fboStack.push(t),this.setFramebuffer(t,e,i,s,n))},setFramebuffer:function(t,e,i,s,n){if(void 0===e&&(e=!1),void 0===i&&(i=!0),void 0===s&&(s=null),void 0===n&&(n=!1),t===this.currentFramebuffer)return this;var r=this.gl,o=this.width,a=this.height;return t&&t.renderTexture&&i?(o=t.renderTexture.width,a=t.renderTexture.height):this.flush(),r.bindFramebuffer(r.FRAMEBUFFER,t),i&&r.viewport(0,0,o,a),s&&r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,s,0),n&&(r.clearColor(0,0,0,0),r.clear(r.COLOR_BUFFER_BIT)),e&&(t?(this.drawingBufferHeight=a,this.pushScissor(0,0,o,a)):(this.drawingBufferHeight=this.height,this.popScissor())),this.currentFramebuffer=t,this},popFramebuffer:function(t,e){void 0===t&&(t=!1),void 0===e&&(e=!0);var i=this.fboStack;i.pop();var s=i[i.length-1];return s||(s=null),this.setFramebuffer(s,t,e),s},restoreFramebuffer:function(t,e){void 0===t&&(t=!1),void 0===e&&(e=!0);var i=this.fboStack,s=i[i.length-1];s||(s=null),this.currentFramebuffer=null,this.setFramebuffer(s,t,e)},setProgram:function(t){return t!==this.currentProgram&&(this.flush(),this.gl.useProgram(t),this.currentProgram=t,!0)},resetProgram:function(){return this.gl.useProgram(this.currentProgram),this},createTextureFromSource:function(t,e,i,s,n){void 0===n&&(n=!1);var r=this.gl,a=r.NEAREST,h=r.NEAREST,u=r.CLAMP_TO_EDGE;e=t?t.width:e,i=t?t.height:i;var c=l(e,i);return c&&!n&&(u=r.REPEAT),s===o.ScaleModes.LINEAR&&this.config.antialias&&(a=c&&this.mipmapFilter?this.mipmapFilter:r.LINEAR,h=r.LINEAR),t&&t.compressed&&(a=r.LINEAR,h=r.LINEAR),t||"number"!=typeof e||"number"!=typeof i?this.createTexture2D(0,a,h,u,u,r.RGBA,t):this.createTexture2D(0,a,h,u,u,r.RGBA,null,e,i)},createTexture2D:function(t,e,i,s,n,r,o,a,h,u,c,d){u=null==u||u,void 0===c&&(c=!1),void 0===d&&(d=!1);var f=this.gl,p=f.createTexture();f.activeTexture(f.TEXTURE0);var v=f.getParameter(f.TEXTURE_BINDING_2D);f.bindTexture(f.TEXTURE_2D,p),f.texParameteri(f.TEXTURE_2D,f.TEXTURE_MIN_FILTER,e),f.texParameteri(f.TEXTURE_2D,f.TEXTURE_MAG_FILTER,i),f.texParameteri(f.TEXTURE_2D,f.TEXTURE_WRAP_S,n),f.texParameteri(f.TEXTURE_2D,f.TEXTURE_WRAP_T,s),f.pixelStorei(f.UNPACK_PREMULTIPLY_ALPHA_WEBGL,u),d&&f.pixelStorei(f.UNPACK_FLIP_Y_WEBGL,!0);var g=!1;if(null==o)f.texImage2D(f.TEXTURE_2D,t,r,a,h,0,r,f.UNSIGNED_BYTE,null),g=l(a,h);else if(o.compressed){a=o.width,h=o.height,g=o.generateMipmap;for(var m=0;m0)&&this.pipelines.setMulti().drawFillRect(e,i,s,r,g.getTintFromFloats(o.blueGL,o.greenGL,o.redGL,1),o.alphaGL)},getCurrentStencilMask:function(){var t=null,e=this.maskStack,i=this.currentCameraMask;return e.length>0?t=e[e.length-1]:i.mask&&i.mask.isStencil&&(t=i),t},postRenderCamera:function(t){var e=t.flashEffect,i=t.fadeEffect;if(e.isRunning||i.isRunning||i.isComplete){var s=this.pipelines.setMulti();e.postRenderWebGL(s,g.getTintFromFloats),i.postRenderWebGL(s,g.getTintFromFloats)}t.dirty=!1,this.popScissor(),t.mask&&(this.currentCameraMask.mask=null,t.mask.postRenderWebGL(this,t._maskCamera)),this.pipelines.postBatchCamera(t),t.emit(n.POST_RENDER,t)},preRender:function(){if(!this.contextLost){var t=this.gl;if(t.bindFramebuffer(t.FRAMEBUFFER,null),this.config.clearBeforeRender){var e=this.config.backgroundColor;t.clearColor(e.redGL,e.greenGL,e.blueGL,e.alphaGL),t.clear(t.COLOR_BUFFER_BIT|t.DEPTH_BUFFER_BIT|t.STENCIL_BUFFER_BIT)}t.enable(t.SCISSOR_TEST),this.currentScissor=this.defaultScissor,this.scissorStack.length=0,this.scissorStack.push(this.currentScissor),this.game.scene.customViewports&&t.scissor(0,this.drawingBufferHeight-this.height,this.width,this.height),this.currentMask.mask=null,this.currentCameraMask.mask=null,this.maskStack.length=0,this.emit(h.PRE_RENDER)}},render:function(t,e,i){if(!this.contextLost){var s=e.length;if(this.emit(h.RENDER,t,i),this.preRenderCamera(i),0===s)return this.setBlendMode(o.BlendModes.NORMAL),void this.postRenderCamera(i);this.currentType="";for(var n=this.currentMask,r=0;r0&&r>0){s.activeTexture(s.TEXTURE0);var o=s.getParameter(s.TEXTURE_BINDING_2D);s.bindTexture(s.TEXTURE_2D,e),i&&s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL,!0),s.pixelStorei(s.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),s.texImage2D(s.TEXTURE_2D,0,s.RGBA,s.RGBA,s.UNSIGNED_BYTE,t),e.width=n,e.height=r,o&&s.bindTexture(s.TEXTURE_2D,o)}return e},createVideoTexture:function(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var s=this.gl,n=s.NEAREST,r=s.NEAREST,o=t.videoWidth,a=t.videoHeight,h=s.CLAMP_TO_EDGE,u=l(o,a);return!e&&u&&(h=s.REPEAT),this.config.antialias&&(n=u&&this.mipmapFilter?this.mipmapFilter:s.LINEAR,r=s.LINEAR),this.createTexture2D(0,n,r,h,h,s.RGBA,t,o,a,!0,!0,i)},updateVideoTexture:function(t,e,i){void 0===i&&(i=!1);var s=this.gl,n=t.videoWidth,r=t.videoHeight;if(n>0&&r>0){s.activeTexture(s.TEXTURE0);var o=s.getParameter(s.TEXTURE_BINDING_2D);s.bindTexture(s.TEXTURE_2D,e),s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL,i),s.texImage2D(s.TEXTURE_2D,0,s.RGBA,s.RGBA,s.UNSIGNED_BYTE,t),e.width=n,e.height=r,o&&s.bindTexture(s.TEXTURE_2D,o)}return e},setTextureFilter:function(t,e){var i=this.gl,s=[i.LINEAR,i.NEAREST][e];i.activeTexture(i.TEXTURE0);var n=i.getParameter(i.TEXTURE_BINDING_2D);return i.bindTexture(i.TEXTURE_2D,t),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MIN_FILTER,s),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MAG_FILTER,s),n&&i.bindTexture(i.TEXTURE_2D,n),this},getMaxTextureSize:function(){return this.config.maxTextureSize},destroy:function(){this.canvas.removeEventListener("webglcontextlost",this.contextLostHandler,!1),this.maskTarget.destroy(),this.maskSource.destroy(),this.pipelines.destroy(),this.removeAllListeners(),this.fboStack=[],this.maskStack=[],this.extensions={},this.textureIndexes=[],this.gl=null,this.game=null,this.canvas=null,this.contextLost=!0,this.currentMask=null,this.currentCameraMask=null}});t.exports=x},71305:(t,e,i)=>{var s=i(56694),n=i(72632),r=i(71402),o=new s({initialize:function(t,e,i,s,n){this.pipeline=t,this.name=e,this.renderer=t.renderer,this.gl=this.renderer.gl,this.fragSrc=s,this.vertSrc=i,this.program=this.renderer.createProgram(i,s),this.attributes,this.vertexComponentCount=0,this.vertexSize=0,this.uniforms={},this.createAttributes(n),this.createUniforms()},createAttributes:function(t){var e=0,i=0,s=[];this.vertexComponentCount=0;for(var o=0;o=0?(e.enableVertexAttribArray(f),e.vertexAttribPointer(f,a,h,d,i,l),o.enabled=!0,o.location=f):-1!==f&&e.disableVertexAttribArray(f)}else u?e.vertexAttribPointer(c,a,h,d,i,l):!u&&c>-1&&(e.disableVertexAttribArray(c),o.location=-1)}return this},createUniforms:function(){var t,e,i,s=this.gl,n=this.program,r=this.uniforms,o=s.getProgramParameter(n,s.ACTIVE_UNIFORMS);for(t=0;t0&&(e=e.substr(0,h),r.hasOwnProperty(e)||null!==(i=s.getUniformLocation(n,e))&&(r[e]={name:e,location:i,value1:null,value2:null,value3:null,value4:null}))}}return this},hasUniform:function(t){return this.uniforms.hasOwnProperty(t)},resetUniform:function(t){var e=this.uniforms[t];return e&&(e.value1=null,e.value2=null,e.value3=null,e.value4=null),this},setUniform1:function(t,e,i,s){var n=this.uniforms[e];return n?((s||n.value1!==i)&&(n.value1=i,this.renderer.setProgram(this.program),t.call(this.gl,n.location,i),this.pipeline.currentShader=this),this):this},setUniform2:function(t,e,i,s,n){var r=this.uniforms[e];return r?((n||r.value1!==i||r.value2!==s)&&(r.value1=i,r.value2=s,this.renderer.setProgram(this.program),t.call(this.gl,r.location,i,s),this.pipeline.currentShader=this),this):this},setUniform3:function(t,e,i,s,n,r){var o=this.uniforms[e];return o?((r||o.value1!==i||o.value2!==s||o.value3!==n)&&(o.value1=i,o.value2=s,o.value3=n,this.renderer.setProgram(this.program),t.call(this.gl,o.location,i,s,n),this.pipeline.currentShader=this),this):this},setUniform4:function(t,e,i,s,n,r,o){var a=this.uniforms[e];return a?((o||a.value1!==i||a.value2!==s||a.value3!==n||a.value4!==r)&&(a.value1=i,a.value2=s,a.value3=n,a.value4=r,this.renderer.setProgram(this.program),t.call(this.gl,a.location,i,s,n,r),this.pipeline.currentShader=this),this):this},setBoolean:function(t,e){return this.setUniform1(this.gl.uniform1i,t,Number(e))},set1f:function(t,e){return this.setUniform1(this.gl.uniform1f,t,e)},set2f:function(t,e,i){return this.setUniform2(this.gl.uniform2f,t,e,i)},set3f:function(t,e,i,s){return this.setUniform3(this.gl.uniform3f,t,e,i,s)},set4f:function(t,e,i,s,n){return this.setUniform4(this.gl.uniform4f,t,e,i,s,n)},set1fv:function(t,e){return this.setUniform1(this.gl.uniform1fv,t,e,!0)},set2fv:function(t,e){return this.setUniform1(this.gl.uniform2fv,t,e,!0)},set3fv:function(t,e){return this.setUniform1(this.gl.uniform3fv,t,e,!0)},set4fv:function(t,e){return this.setUniform1(this.gl.uniform4fv,t,e,!0)},set1iv:function(t,e){return this.setUniform1(this.gl.uniform1iv,t,e,!0)},set2iv:function(t,e){return this.setUniform1(this.gl.uniform2iv,t,e,!0)},set3iv:function(t,e){return this.setUniform1(this.gl.uniform3iv,t,e,!0)},set4iv:function(t,e){return this.setUniform1(this.gl.uniform4iv,t,e,!0)},set1i:function(t,e){return this.setUniform1(this.gl.uniform1i,t,e)},set2i:function(t,e,i){return this.setUniform2(this.gl.uniform2i,t,e,i)},set3i:function(t,e,i,s){return this.setUniform3(this.gl.uniform3i,t,e,i,s)},set4i:function(t,e,i,s,n){return this.setUniform4(this.gl.uniform4i,t,e,i,s,n)},setMatrix2fv:function(t,e,i){return this.setUniform2(this.gl.uniformMatrix2fv,t,e,i,!0)},setMatrix3fv:function(t,e,i){return this.setUniform2(this.gl.uniformMatrix3fv,t,e,i,!0)},setMatrix4fv:function(t,e,i){return this.setUniform2(this.gl.uniformMatrix4fv,t,e,i,!0)},createProgram:function(t,e){void 0===t&&(t=this.vertSrc),void 0===e&&(e=this.fragSrc);var i=this.gl;return this.program&&i.deleteProgram(this.program),this.vertSrc=t,this.fragSrc=e,this.program=this.renderer.createProgram(t,e),this.createUniforms(),this.rebind()},destroy:function(){this.gl.deleteProgram(this.program),this.pipeline=null,this.renderer=null,this.gl=null,this.program=null,this.attributes=null,this.uniforms=null}});t.exports=o},71402:t=>{t.exports={BYTE:{enum:5120,size:1},UNSIGNED_BYTE:{enum:5121,size:1},SHORT:{enum:5122,size:2},UNSIGNED_SHORT:{enum:5123,size:2},INT:{enum:5124,size:4},UNSIGNED_INT:{enum:5125,size:4},FLOAT:{enum:5126,size:4}}},55478:(t,e,i)=>{var s=i(71402),n=i(98611),r={PipelineManager:i(35217),Pipelines:i(62253),RenderTarget:i(37410),Utils:i(75512),WebGLPipeline:i(44775),WebGLRenderer:i(11857),WebGLShader:i(71305)};r=n(!1,r,s),t.exports=r},5583:(t,e,i)=>{var s=i(56694),n=i(72632),r=i(91679),o=i(89053),a=i(71402),h=i(44775),l=new s({Extends:h,initialize:function(t){t.fragShader=n(t,"fragShader",r),t.vertShader=n(t,"vertShader",o),t.batchSize=n(t,"batchSize",1),t.vertices=n(t,"vertices",[-1,1,-1,-7,7,1]),t.attributes=n(t,"attributes",[{name:"inPosition",size:2,type:a.FLOAT}]),h.call(this,t)},boot:function(){h.prototype.boot.call(this),this.set1i("uMainSampler",0),this.set1i("uMaskSampler",1)},resize:function(t,e){h.prototype.resize.call(this,t,e),this.set2f("uResolution",t,e)},beginMask:function(t,e,i){this.renderer.beginBitmapMask(t,i)},endMask:function(t,e,i){var s=this.gl,n=this.renderer,r=t.bitmapMask;r&&s&&(n.drawBitmapMask(r,e,this),i&&this.set2f("uResolution",i.width,i.height),this.set1i("uInvertMaskAlpha",t.invertAlpha),s.drawArrays(this.topology,0,3),i&&this.set2f("uResolution",this.width,this.height),s.bindTexture(s.TEXTURE_2D,null))}});t.exports=l},81828:(t,e,i)=>{var s=i(56694),n=i(58136),r=i(47406),o=i(72632),a=i(87228),h=i(92462),l=i(75512),u=new s({Extends:a,initialize:function(t){t.shaders=[l.setGlowQuality(h.FXGlowFrag,t.game),h.FXShadowFrag,h.FXPixelateFrag,h.FXVignetteFrag,h.FXShineFrag,h.FXBlurLowFrag,h.FXBlurMedFrag,h.FXBlurHighFrag,h.FXGradientFrag,h.FXBloomFrag,h.ColorMatrixFrag,h.FXCircleFrag,h.FXBarrelFrag,h.FXDisplacementFrag,h.FXWipeFrag,h.FXBokehFrag],a.call(this,t);var e=this.game;this.glow=new n.Glow(e),this.shadow=new n.Shadow(e),this.pixelate=new n.Pixelate(e),this.vignette=new n.Vignette(e),this.shine=new n.Shine(e),this.gradient=new n.Gradient(e),this.circle=new n.Circle(e),this.barrel=new n.Barrel(e),this.wipe=new n.Wipe(e),this.bokeh=new n.Bokeh(e);var i=[];i[r.GLOW]=this.onGlow,i[r.SHADOW]=this.onShadow,i[r.PIXELATE]=this.onPixelate,i[r.VIGNETTE]=this.onVignette,i[r.SHINE]=this.onShine,i[r.BLUR]=this.onBlur,i[r.GRADIENT]=this.onGradient,i[r.BLOOM]=this.onBloom,i[r.COLOR_MATRIX]=this.onColorMatrix,i[r.CIRCLE]=this.onCircle,i[r.BARREL]=this.onBarrel,i[r.DISPLACEMENT]=this.onDisplacement,i[r.WIPE]=this.onWipe,i[r.BOKEH]=this.onBokeh,this.fxHandlers=i,this.source,this.target,this.swap},onDraw:function(t,e,i){this.source=t,this.target=e,this.swap=i;var s=t.width,n=t.height,r=this.tempSprite,o=this.fxHandlers;if(r&&r.preFX)for(var a=r.preFX.list,h=0;h{var s=i(56694),n=i(72632),r=i(65045),o=i(77310),a=i(69360),h=i(93736),l=i(44775),u=new s({Extends:o,initialize:function(t){var e=n(t,"fragShader",r);t.fragShader=e.replace("%LIGHT_COUNT%",t.game.renderer.config.maxLights),o.call(this,t),this.inverseRotationMatrix=new Float32Array([1,0,0,0,1,0,0,0,1]),this.defaultNormalMap,this.currentNormalMap,this.lightsActive=!0,this.tempVec2=new h,this._tempMatrix=new a,this._tempMatrix2=new a},boot:function(){l.prototype.boot.call(this);var t=this.gl,e=t.createTexture();t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,e),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,1,1,0,t.RGBA,t.UNSIGNED_BYTE,new Uint8Array([127,127,255,255])),this.defaultNormalMap={glTexture:e}},onRender:function(t,e){var i=t.sys.lights;if(this.lightsActive=!1,i&&i.active){var s,n=i.getLights(e),r=n.length;this.lightsActive=!0;var o=this.renderer.height,a=e.matrix,h=this.tempVec2;for(this.set1i("uMainSampler",0),this.set1i("uNormSampler",1),this.set2f("uResolution",this.width/2,this.height/2),this.set4f("uCamera",e.x,e.y,e.rotation,e.zoom),this.set3f("uAmbientLightColor",i.ambientColor.r,i.ambientColor.g,i.ambientColor.b),this.set1i("uLightCount",r),s=0;s0&&this.flush();var e=this.inverseRotationMatrix;if(t){var i=-t,s=Math.cos(i),n=Math.sin(i);e[1]=n,e[3]=-n,e[0]=e[4]=s}else e[0]=e[4]=1,e[1]=e[3]=0;this.setMatrix3fv("uInverseRotationMatrix",!1,e),this.currentNormalMapRotation=t}},setTexture2D:function(t,e){var i=this.renderer;void 0===t&&(t=i.whiteTexture);var s=this.getNormalMap(e);this.isNewNormalMap(t,s)&&(this.flush(),this.createBatch(t),this.addTextureToBatch(s),this.currentNormalMap=s);var n=0;e&&e.parentContainer?n=e.getWorldTransformMatrix(this._tempMatrix,this._tempMatrix2).rotationNormalized:e&&(n=e.rotation);return this.setNormalMapRotation(n),0},setGameObject:function(t,e){void 0===e&&(e=t.frame);var i=e.glTexture,s=this.getNormalMap(t);if(this.isNewNormalMap(i,s)&&(this.flush(),this.createBatch(i),this.addTextureToBatch(s),this.currentNormalMap=s),t.parentContainer){var n=t.getWorldTransformMatrix(this._tempMatrix,this._tempMatrix2);this.setNormalMapRotation(n.rotationNormalized)}else this.setNormalMapRotation(t.rotation);return 0},isNewNormalMap:function(t,e){return this.currentTexture!==t||this.currentNormalMap!==e},getNormalMap:function(t){var e;return t?t.displayTexture?e=t.displayTexture.dataSource[t.displayFrame.sourceIndex]:t.texture?e=t.texture.dataSource[t.frame.sourceIndex]:t.tileset&&(e=Array.isArray(t.tileset)?t.tileset[0].image.dataSource[0]:t.tileset.image.dataSource[0]):e=this.defaultNormalMap,e||(e=this.defaultNormalMap),e.glTexture},batchSprite:function(t,e,i){this.lightsActive&&o.prototype.batchSprite.call(this,t,e,i)},batchTexture:function(t,e,i,s,n,r,a,h,l,u,c,d,f,p,v,g,m,y,x,T,w,b,S,E,A,C,_,M,P,R,O,L){this.lightsActive&&o.prototype.batchTexture.call(this,t,e,i,s,n,r,a,h,l,u,c,d,f,p,v,g,m,y,x,T,w,b,S,E,A,C,_,M,P,R,O,L)},batchTextureFrame:function(t,e,i,s,n,r,a){this.lightsActive&&o.prototype.batchTextureFrame.call(this,t,e,i,s,n,r,a)}});t.exports=u},71264:(t,e,i)=>{var s=i(56694),n=i(72632),r=i(77310),o=i(85060),a=i(18166),h=i(71402),l=i(44775),u=new s({Extends:r,initialize:function(t){t.fragShader=n(t,"fragShader",o),t.vertShader=n(t,"vertShader",a),t.attributes=n(t,"attributes",[{name:"inPosition",size:2},{name:"inTexCoord",size:2},{name:"inTexId"},{name:"inTintEffect"},{name:"inTint",size:4,type:h.UNSIGNED_BYTE,normalized:!0}]),t.forceZero=!0,r.call(this,t)},boot:function(){l.prototype.boot.call(this),this.set1i("uMainSampler",0)}});t.exports=u},77310:(t,e,i)=>{var s=i(56694),n=i(11117),r=i(72632),o=i(53787),a=i(15968),h=i(69360),l=i(75512),u=i(71402),c=i(44775),d=new s({Extends:c,initialize:function(t){var e=t.game.renderer,i=r(t,"fragShader",o);t.fragShader=l.parseFragmentShaderMaxTextures(i,e.maxTextures),t.vertShader=r(t,"vertShader",a),t.attributes=r(t,"attributes",[{name:"inPosition",size:2},{name:"inTexCoord",size:2},{name:"inTexId"},{name:"inTintEffect"},{name:"inTint",size:4,type:u.UNSIGNED_BYTE,normalized:!0}]),c.call(this,t),this._tempMatrix1=new h,this._tempMatrix2=new h,this._tempMatrix3=new h,this.calcMatrix=new h,this.tempTriangle=[{x:0,y:0,width:0},{x:0,y:0,width:0},{x:0,y:0,width:0},{x:0,y:0,width:0}],this.strokeTint={TL:0,TR:0,BL:0,BR:0},this.fillTint={TL:0,TR:0,BL:0,BR:0},this.currentFrame={u0:0,v0:0,u1:1,v1:1},this.firstQuad=[0,0,0,0,0],this.prevQuad=[0,0,0,0,0],this.polygonCache=[]},boot:function(){c.prototype.boot.call(this),this.currentShader.set1iv("uMainSampler",this.renderer.textureIndexes)},batchSprite:function(t,e,i){this.manager.set(this,t);var s=this._tempMatrix1,n=this._tempMatrix2,r=this._tempMatrix3,o=t.frame,a=o.glTexture,h=o.u0,u=o.v0,c=o.u1,d=o.v1,f=o.x,p=o.y,v=o.cutWidth,g=o.cutHeight,m=o.customPivot,y=t.displayOriginX,x=t.displayOriginY,T=-y+f,w=-x+p;if(t.isCropped){var b=t._crop;b.flipX===t.flipX&&b.flipY===t.flipY||o.updateCropUVs(b,t.flipX,t.flipY),h=b.u0,u=b.v0,c=b.u1,d=b.v1,v=b.width,g=b.height,T=-y+(f=b.x),w=-x+(p=b.y)}var S=1,E=1;t.flipX&&(m||(T+=-o.realWidth+2*y),S=-1),(t.flipY||o.source.isGLTexture&&!a.flipY)&&(m||(w+=-o.realHeight+2*x),E=-1);var A=t.x,C=t.y;n.applyITRS(A,C,t.rotation,t.scaleX*S,t.scaleY*E),s.copyFrom(e.matrix),i?(s.multiplyWithOffset(i,-e.scrollX*t.scrollFactorX,-e.scrollY*t.scrollFactorY),n.e=A,n.f=C):(n.e-=e.scrollX*t.scrollFactorX,n.f-=e.scrollY*t.scrollFactorY),s.multiply(n,r);var _=r.setQuad(T,w,T+v,w+g,e.roundPixels),M=l.getTintAppendFloatAlpha,P=e.alpha,R=M(t.tintTopLeft,P*t._alphaTL),O=M(t.tintTopRight,P*t._alphaTR),L=M(t.tintBottomLeft,P*t._alphaBL),F=M(t.tintBottomRight,P*t._alphaBR);this.shouldFlush(6)&&this.flush();var D=this.setGameObject(t,o);this.manager.preBatch(t),this.batchQuad(t,_[0],_[1],_[2],_[3],_[4],_[5],_[6],_[7],h,u,c,d,R,O,L,F,t.tintFill,a,D),this.manager.postBatch(t)},batchTexture:function(t,e,i,s,n,r,o,a,h,l,u,c,d,f,p,v,g,m,y,x,T,w,b,S,E,A,C,_,M,P,R,O){this.manager.set(this,t);var L=this._tempMatrix1,F=this._tempMatrix2,D=this._tempMatrix3,I=m/i+C,k=y/s+_,B=(m+x)/i+C,N=(y+T)/s+_,X=o,U=a,Y=-v,z=-g;if(t.isCropped){var G=t._crop,V=G.width,W=G.height;X=V,U=W,o=V,a=W;var H=m=G.x,j=y=G.y;c&&(H=x-G.x-V),d&&(j=T-G.y-W),I=H/i+C,k=j/s+_,B=(H+V)/i+C,N=(j+W)/s+_,Y=-v+m,z=-g+y}c&&(X*=-1,Y+=o),(d^=!R&&e.isRenderTexture?1:0)&&(U*=-1,z+=a),F.applyITRS(n,r,u,h,l),L.copyFrom(M.matrix),P?(L.multiplyWithOffset(P,-M.scrollX*f,-M.scrollY*p),F.e=n,F.f=r):(F.e-=M.scrollX*f,F.f-=M.scrollY*p),L.multiply(F,D);var q=D.setQuad(Y,z,Y+X,z+U,M.roundPixels);void 0===O&&(O=this.setTexture2D(e)),t&&this.manager.preBatch(t),this.batchQuad(t,q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7],I,k,B,N,w,b,S,E,A,e,O),t&&this.manager.postBatch(t)},batchTextureFrame:function(t,e,i,s,n,r,o){this.manager.set(this);var a=this._tempMatrix1.copyFrom(r),h=this._tempMatrix2;o?a.multiply(o,h):h=a;var u=h.setQuad(e,i,e+t.width,i+t.height,!1),c=this.setTexture2D(t.source.glTexture);s=l.getTintAppendFloatAlpha(s,n),this.batchQuad(null,u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],t.u0,t.v0,t.u1,t.v1,s,s,s,s,0,t.glTexture,c)},batchFillRect:function(t,e,i,s,n,r){this.renderer.pipelines.set(this);var o=this.calcMatrix;r&&r.multiply(n,o);var a=o.setQuad(t,e,t+i,e+s,!1),h=this.fillTint;this.batchQuad(null,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],0,0,1,1,h.TL,h.TR,h.BL,h.BR,2)},batchFillTriangle:function(t,e,i,s,n,r,o,a){this.renderer.pipelines.set(this);var h=this.calcMatrix;a&&a.multiply(o,h);var l=h.getX(t,e),u=h.getY(t,e),c=h.getX(i,s),d=h.getY(i,s),f=h.getX(n,r),p=h.getY(n,r),v=this.fillTint;this.batchTri(null,l,u,c,d,f,p,0,0,1,1,v.TL,v.TR,v.BL,2)},batchStrokeTriangle:function(t,e,i,s,n,r,o,a,h){var l=this.tempTriangle;l[0].x=t,l[0].y=e,l[0].width=o,l[1].x=i,l[1].y=s,l[1].width=o,l[2].x=n,l[2].y=r,l[2].width=o,l[3].x=t,l[3].y=e,l[3].width=o,this.batchStrokePath(l,o,!1,a,h)},batchFillPath:function(t,e,i){this.renderer.pipelines.set(this);var s=this.calcMatrix;i&&i.multiply(e,s);for(var r,o,a=t.length,h=this.polygonCache,l=this.fillTint.TL,u=this.fillTint.TR,c=this.fillTint.BL,d=0;d0&&U[4]?this.batchQuad(null,F,D,P,R,U[0],U[1],U[2],U[3],0,0,1,1,k,B,N,X,2):(Y[0]=F,Y[1]=D,Y[2]=P,Y[3]=R,Y[4]=1),h&&Y[4]?this.batchQuad(null,_,M,O,L,Y[0],Y[1],Y[2],Y[3],0,0,1,1,k,B,N,X,2):(U[0]=_,U[1]=M,U[2]=O,U[3]=L,U[4]=1)}}},destroy:function(){return this._tempMatrix1.destroy(),this._tempMatrix2.destroy(),this._tempMatrix3.destroy(),this._tempMatrix1=null,this._tempMatrix1=null,this._tempMatrix1=null,c.prototype.destroy.call(this),this}});t.exports=d},10919:(t,e,i)=>{var s=i(56694),n=i(72632),r=i(83327),o=i(54677),a=i(44775),h=new s({Extends:a,initialize:function(t){t.vertShader=n(t,"vertShader",o),t.fragShader=n(t,"fragShader",r),t.attributes=n(t,"attributes",[{name:"inPosition",size:2},{name:"inLightPosition",size:2},{name:"inLightRadius"},{name:"inLightAttenuation"},{name:"inLightColor",size:4}]),a.call(this,t)},onRender:function(t,e){this.set2f("uResolution",this.width,this.height),this.set1f("uCameraZoom",e.zoom)},batchPointLight:function(t,e,i,s,n,r,o,a,h,l,u,c){var d=t.color,f=t.intensity,p=t.radius,v=t.attenuation,g=d.r*f,m=d.g*f,y=d.b*f,x=e.alpha*t.alpha;this.shouldFlush(6)&&this.flush(),this.currentBatch||this.setTexture2D(),this.batchLightVert(i,s,u,c,p,v,g,m,y,x),this.batchLightVert(n,r,u,c,p,v,g,m,y,x),this.batchLightVert(o,a,u,c,p,v,g,m,y,x),this.batchLightVert(i,s,u,c,p,v,g,m,y,x),this.batchLightVert(o,a,u,c,p,v,g,m,y,x),this.batchLightVert(h,l,u,c,p,v,g,m,y,x),this.currentBatch.count=this.vertexCount-this.currentBatch.start},batchLightVert:function(t,e,i,s,n,r,o,a,h,l){var u=this.vertexViewF32,c=this.vertexCount*this.currentShader.vertexComponentCount-1;u[++c]=t,u[++c]=e,u[++c]=i,u[++c]=s,u[++c]=n,u[++c]=r,u[++c]=o,u[++c]=a,u[++c]=h,u[++c]=l,this.vertexCount++}});t.exports=h},80486:(t,e,i)=>{var s=i(56694),n=i(65246),r=i(72632),o=i(12569),a=i(99365),h=i(44775),l=new s({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.controller,this.colorMatrix=new n,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)},getController:function(t){return void 0!==t?t:this.controller?this.controller:this},copySprite:function(t,e,i){void 0===i&&(i=!1);var s=this.gl;s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,t.texture);var n=s.getParameter(s.FRAMEBUFFER_BINDING);s.bindFramebuffer(s.FRAMEBUFFER,e.framebuffer),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,e.texture,0),s.clearColor(0,0,0,0),s.clear(s.COLOR_BUFFER_BIT),s.bufferData(s.ARRAY_BUFFER,this.vertexData,s.STATIC_DRAW),s.drawArrays(s.TRIANGLES,0,6),i&&(s.bindTexture(s.TEXTURE_2D,null),s.bindFramebuffer(s.FRAMEBUFFER,n))},copyFrame:function(t,e,i,s,n){this.manager.copyFrame(t,e,i,s,n)},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,s,n){this.manager.blendFrames(t,e,i,s,n)},blendFramesAdditive:function(t,e,i,s,n){this.manager.blendFramesAdditive(t,e,i,s,n)},clearFrame:function(t,e){this.manager.clearFrame(t,e)},blitFrame:function(t,e,i,s,n,r){this.manager.blitFrame(t,e,i,s,n,r)},copyFrameRect:function(t,e,i,s,n,r,o,a){this.manager.copyFrameRect(t,e,i,s,n,r,o,a)},bindAndDraw:function(t,e,i,s,n){void 0===i&&(i=!0),void 0===s&&(s=!0);var r=this.gl,o=this.renderer;this.bind(n),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&&(s?r.clearColor(0,0,0,0):r.clearColor(0,0,0,1),r.clear(r.COLOR_BUFFER_BIT))):(o.popFramebuffer(!1,!1),o.currentFramebuffer||r.viewport(0,0,o.width,o.height)),o.restoreStencilMask(),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,o.currentFramebuffer))},destroy:function(){return this.controller&&this.controller.destroy(),this.gameObject=null,this.controller=null,this.colorMatrix=null,this.fullFrame1=null,this.fullFrame2=null,this.halfFrame1=null,this.halfFrame2=null,h.prototype.destroy.call(this),this}});t.exports=l},87228:(t,e,i)=>{var s=i(95723),n=i(79993),r=i(56694),o=i(37486),a=i(72632),h=i(77310),l=i(12569),u=i(74118),c=i(37410),d=i(85060),f=i(18166),p=i(44775),v=new r({Extends:h,initialize:function(t){var e=a(t,"fragShader",l),i=a(t,"vertShader",f),s=a(t,"drawShader",l),n=[{name:"DrawSprite",fragShader:d,vertShader:f},{name:"CopySprite",fragShader:e,vertShader:i},{name:"DrawGame",fragShader:s,vertShader:f},{name:"ColorMatrix",fragShader:o}],r=a(t,"shaders",[]);t.shaders=n.concat(r),t.vertShader||(t.vertShader=i),t.batchSize=1,h.call(this,t),this.isPreFX=!0,this.customMainSampler=null,this.drawSpriteShader,this.copyShader,this.gameShader,this.colorMatrixShader,this.quadVertexData,this.quadVertexBuffer,this.quadVertexViewF32,this.spriteBounds=new u,this.targetBounds=new u,this.fsTarget,this.tempSprite,this.renderer.isBooted&&(this.manager=this.renderer.pipelines,this.boot())},boot:function(){p.prototype.boot.call(this);var t=this.shaders,e=this.renderer;this.drawSpriteShader=t[0],this.copyShader=t[1],this.gameShader=t[2],this.colorMatrixShader=t[3],this.fsTarget=new c(e,e.width,e.height,1,0,!0,!0),this.renderTargets=this.manager.renderTargets.concat(this.fsTarget);var i=new ArrayBuffer(168);this.quadVertexData=i,this.quadVertexViewF32=new Float32Array(i),this.quadVertexBuffer=e.createVertexBuffer(i,this.gl.STATIC_DRAW),this.onResize(e.width,e.height),this.currentShader=this.copyShader},onResize:function(t,e){var i=this.quadVertexViewF32;i[1]=e,i[22]=e,i[14]=t,i[28]=t,i[35]=t,i[36]=e},batchQuad:function(t,e,i,s,r,o,a,h,l,u,c,d,f,p,v,g,m,y,x){var T=Math.min(e,s,o,h),w=Math.min(i,r,a,l),b=Math.max(e,s,o,h)-T,S=Math.max(i,r,a,l)-w,E=this.spriteBounds.setTo(T,w,b,S),A=t?t.preFX.padding:0,C=b+2*A,_=S+2*A,M=Math.abs(Math.max(C,_)),P=this.manager.getRenderTarget(M),R=this.targetBounds.setTo(0,0,P.width,P.height);n(R,E.centerX,E.centerY),this.tempSprite=t;var O=this.gl,L=this.renderer;L.clearStencilMask(),this.setShader(this.drawSpriteShader),this.set1i("uMainSampler",0),this.flipProjectionMatrix(!0),t&&(this.onDrawSprite(t,P),t.preFX.onFX(this));var F=this.fsTarget;return this.flush(),O.viewport(0,0,L.width,L.height),O.bindFramebuffer(O.FRAMEBUFFER,F.framebuffer),O.framebufferTexture2D(O.FRAMEBUFFER,O.COLOR_ATTACHMENT0,O.TEXTURE_2D,F.texture,0),O.clearColor(0,0,0,0),O.clear(O.COLOR_BUFFER_BIT),this.setTexture2D(x),this.batchVert(e,i,u,c,0,y,p),this.batchVert(s,r,u,f,0,y,g),this.batchVert(o,a,d,f,0,y,m),this.batchVert(e,i,u,c,0,y,p),this.batchVert(o,a,d,f,0,y,m),this.batchVert(h,l,d,c,0,y,v),this.flush(),this.flipProjectionMatrix(!1),O.activeTexture(O.TEXTURE0),O.bindTexture(O.TEXTURE_2D,P.texture),O.copyTexSubImage2D(O.TEXTURE_2D,0,0,0,R.x,R.y,R.width,R.height),O.bindFramebuffer(O.FRAMEBUFFER,null),O.bindTexture(O.TEXTURE_2D,null),this.onBatch(t),this.currentShader=this.copyShader,this.onDraw(P,this.manager.getSwapRenderTarget(),this.manager.getAltSwapRenderTarget()),!0},onDrawSprite:function(){},onCopySprite:function(){},copySprite:function(t,e,i,n,r,o,a){void 0===i&&(i=!0),void 0===n&&(n=!0),void 0===r&&(r=!1),void 0===a&&(a=this.copyShader);var h=this.gl,l=this.tempSprite;o&&(a=this.colorMatrixShader),this.currentShader=a;var u=this.setVertexBuffer(this.quadVertexBuffer);if(a.bind(u,!1),this.set1i("uMainSampler",0),l.preFX.onFXCopy(this),this.onCopySprite(t,e,l),o&&(this.set1fv("uColorMatrix",o.getData()),this.set1f("uAlpha",o.alpha)),h.activeTexture(h.TEXTURE0),h.bindTexture(h.TEXTURE_2D,t.texture),t.height>e.height)h.viewport(0,0,t.width,t.height),this.setTargetUVs(t,e);else{var c=e.height-t.height;h.viewport(0,c,t.width,t.height),this.resetUVs()}if(h.bindFramebuffer(h.FRAMEBUFFER,e.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,e.texture,0),i&&(h.clearColor(0,0,0,Number(!n)),h.clear(h.COLOR_BUFFER_BIT)),r){var d=this.renderer.currentBlendMode;this.renderer.setBlendMode(s.ERASE)}h.bufferData(h.ARRAY_BUFFER,this.quadVertexData,h.STATIC_DRAW),h.drawArrays(h.TRIANGLES,0,6),r&&this.renderer.setBlendMode(d),h.bindFramebuffer(h.FRAMEBUFFER,null)},copy:function(t,e){var i=this.gl;this.set1i("uMainSampler",0),i.activeTexture(i.TEXTURE0),i.bindTexture(i.TEXTURE_2D,t.texture),i.viewport(0,0,t.width,t.height),this.setUVs(0,0,0,1,1,1,1,0),i.bindFramebuffer(i.FRAMEBUFFER,e.framebuffer),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,e.texture,0),i.clearColor(0,0,0,0),i.clear(i.COLOR_BUFFER_BIT),i.bufferData(i.ARRAY_BUFFER,this.quadVertexData,i.STATIC_DRAW),i.drawArrays(i.TRIANGLES,0,6),i.bindFramebuffer(i.FRAMEBUFFER,null)},blendFrames:function(t,e,i,s,n){this.manager.blendFrames(t,e,i,s,n)},blendFramesAdditive:function(t,e,i,s,n){this.manager.blendFramesAdditive(t,e,i,s,n)},drawToGame:function(t){this.currentShader=null,this.setShader(this.copyShader),this.bindAndDraw(t)},copyToGame:function(t){this.currentShader=null,this.setShader(this.gameShader),this.bindAndDraw(t)},bindAndDraw:function(t){var e=this.gl,i=this.renderer;this.set1i("uMainSampler",0),this.customMainSampler?this.setTexture2D(this.customMainSampler):this.setTexture2D(t.texture);var s=this._tempMatrix1.loadIdentity(),n=this.targetBounds.x,r=this.targetBounds.y,o=n+t.width,a=r+t.height,h=s.getX(n,r),l=s.getX(n,a),u=s.getX(o,a),c=s.getX(o,r),d=s.getY(n,r),f=s.getY(n,a),p=s.getY(o,a),v=s.getY(o,r),g=16777215;this.batchVert(h,d,0,0,0,0,g),this.batchVert(l,f,0,1,0,0,g),this.batchVert(u,p,1,1,0,0,g),this.batchVert(h,d,0,0,0,0,g),this.batchVert(u,p,1,1,0,0,g),this.batchVert(c,v,1,0,0,0,g),i.restoreFramebuffer(!1,!0),i.currentFramebuffer||e.viewport(0,0,i.width,i.height),i.restoreStencilMask(),this.flush(),this.tempSprite=null},onDraw:function(t){this.drawToGame(t)},setUVs:function(t,e,i,s,n,r,o,a){var h=this.quadVertexViewF32;h[2]=t,h[3]=e,h[9]=i,h[10]=s,h[16]=n,h[17]=r,h[23]=t,h[24]=e,h[30]=n,h[31]=r,h[37]=o,h[38]=a},setTargetUVs:function(t,e){var i=e.height/t.height;i=i>.5?.5-(i-.5):.5-i+.5,this.setUVs(0,i,0,1+i,1,1+i,1,i)},resetUVs:function(){this.setUVs(0,0,0,1,1,1,1,0)},destroy:function(){return this.gl.deleteBuffer(this.quadVertexBuffer),this.drawSpriteShader=null,this.copyShader=null,this.gameShader=null,this.colorMatrixShader=null,this.quadVertexData=null,this.quadVertexBuffer=null,this.quadVertexViewF32=null,this.fsTarget=null,this.tempSprite=null,h.prototype.destroy.call(this),this}});t.exports=v},21213:(t,e,i)=>{var s=i(56694),n=i(72632),r=i(77310),o=new s({Extends:r,initialize:function(t){t.topology=5,t.batchSize=n(t,"batchSize",256),r.call(this,t)}});t.exports=o},51212:(t,e,i)=>{var s=i(56694),n=i(72632),r=i(77310),o=i(85060),a=i(18166),h=i(44775),l=new s({Extends:r,initialize:function(t){t.fragShader=n(t,"fragShader",o),t.vertShader=n(t,"vertShader",a),t.forceZero=!0,r.call(this,t)},boot:function(){h.prototype.boot.call(this),this.set1i("uMainSampler",0)}});t.exports=l},60848:(t,e,i)=>{var s=i(2529),n=i(95723),r=i(56694),o=i(65246),a=i(37486),h=i(79060),l=i(72632),u=i(98921),c=i(99365),d=i(44775),f=new r({Extends:d,initialize:function(t){t.renderTarget=l(t,"renderTarget",[{scale:1},{scale:1},{scale:.5},{scale:.5}]),t.vertShader=l(t,"vertShader",c),t.shaders=l(t,"shaders",[{name:"Copy",fragShader:h},{name:"AddBlend",fragShader:s},{name:"LinearBlend",fragShader:u},{name:"ColorMatrix",fragShader:a}]),t.attributes=l(t,"attributes",[{name:"inPosition",size:2},{name:"inTexCoord",size:2}]),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],t.batchSize=1,d.call(this,t),this.colorMatrix=new o,this.copyShader,this.addShader,this.linearShader,this.colorMatrixShader,this.fullFrame1,this.fullFrame2,this.halfFrame1,this.halfFrame2},boot:function(){d.prototype.boot.call(this);var t=this.shaders,e=this.renderTargets;this.copyShader=t[0],this.addShader=t[1],this.linearShader=t[2],this.colorMatrixShader=t[3],this.fullFrame1=e[0],this.fullFrame2=e[1],this.halfFrame1=e[2],this.halfFrame2=e[3]},copyFrame:function(t,e,i,s,n){void 0===i&&(i=1),void 0===s&&(s=!0),void 0===n&&(n=!0);var r=this.gl;this.setShader(this.copyShader),this.set1i("uMainSampler",0),this.set1f("uBrightness",i),r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,t.texture),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)):r.viewport(0,0,t.width,t.height),s&&(n?r.clearColor(0,0,0,0):r.clearColor(0,0,0,1),r.clear(r.COLOR_BUFFER_BIT)),r.bufferData(r.ARRAY_BUFFER,this.vertexData,r.STATIC_DRAW),r.drawArrays(r.TRIANGLES,0,6),r.bindFramebuffer(r.FRAMEBUFFER,null),r.bindTexture(r.TEXTURE_2D,null)},blitFrame:function(t,e,i,s,r,o,a){void 0===i&&(i=1),void 0===s&&(s=!0),void 0===r&&(r=!0),void 0===o&&(o=!1),void 0===a&&(a=!1);var h=this.gl;if(this.setShader(this.copyShader),this.set1i("uMainSampler",0),this.set1f("uBrightness",i),h.activeTexture(h.TEXTURE0),h.bindTexture(h.TEXTURE_2D,t.texture),t.height>e.height)h.viewport(0,0,t.width,t.height),this.setTargetUVs(t,e);else{var l=e.height-t.height;h.viewport(0,l,t.width,t.height)}if(h.bindFramebuffer(h.FRAMEBUFFER,e.framebuffer),h.framebufferTexture2D(h.FRAMEBUFFER,h.COLOR_ATTACHMENT0,h.TEXTURE_2D,e.texture,0),s&&(r?h.clearColor(0,0,0,0):h.clearColor(0,0,0,1),h.clear(h.COLOR_BUFFER_BIT)),o){var u=this.renderer.currentBlendMode;this.renderer.setBlendMode(n.ERASE)}a&&this.flipY(),h.bufferData(h.ARRAY_BUFFER,this.vertexData,h.STATIC_DRAW),h.drawArrays(h.TRIANGLES,0,6),o&&this.renderer.setBlendMode(u),h.bindFramebuffer(h.FRAMEBUFFER,null),h.bindTexture(h.TEXTURE_2D,null),this.resetUVs()},copyFrameRect:function(t,e,i,s,n,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,s,n,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)},drawFrame:function(t,e,i,s){void 0===i&&(i=!0),void 0===s&&(s=this.colorMatrix);var n=this.gl;this.setShader(this.colorMatrixShader),this.set1i("uMainSampler",0),this.set1fv("uColorMatrix",s.getData()),this.set1f("uAlpha",s.alpha),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,t.texture),e?(n.viewport(0,0,e.width,e.height),n.bindFramebuffer(n.FRAMEBUFFER,e.framebuffer),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,e.texture,0)):n.viewport(0,0,t.width,t.height),i?n.clearColor(0,0,0,0):n.clearColor(0,0,0,1),n.clear(n.COLOR_BUFFER_BIT),n.bufferData(n.ARRAY_BUFFER,this.vertexData,n.STATIC_DRAW),n.drawArrays(n.TRIANGLES,0,6),n.bindFramebuffer(n.FRAMEBUFFER,null),n.bindTexture(n.TEXTURE_2D,null)},blendFrames:function(t,e,i,s,n,r){void 0===s&&(s=1),void 0===n&&(n=!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",s),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),n?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,s,n){this.blendFrames(t,e,i,s,n,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 s=this.renderer.currentFramebuffer;i.bindFramebuffer(i.FRAMEBUFFER,s)},setUVs:function(t,e,i,s,n,r,o,a){var h=this.vertexViewF32;h[2]=t,h[3]=e,h[6]=i,h[7]=s,h[10]=n,h[11]=r,h[14]=t,h[15]=e,h[18]=n,h[19]=r,h[22]=o,h[23]=a},setTargetUVs:function(t,e){var i=e.height/t.height;i=i>.5?.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},65641:t=>{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",MOBILE_PIPELINE:"MobilePipeline",FX_PIPELINE:"FxPipeline"}},68726:t=>{t.exports="pipelineafterflush"},67186:t=>{t.exports="pipelinebeforeflush"},22709:t=>{t.exports="pipelinebind"},74469:t=>{t.exports="pipelineboot"},93953:t=>{t.exports="pipelinedestroy"},51687:t=>{t.exports="pipelinerebind"},25034:t=>{t.exports="pipelineresize"},18970:(t,e,i)=>{t.exports={AFTER_FLUSH:i(68726),BEFORE_FLUSH:i(67186),BIND:i(22709),BOOT:i(74469),DESTROY:i(93953),REBIND:i(51687),RESIZE:i(25034)}},32469:(t,e,i)=>{var s=i(56694),n=i(87751),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.amount=1},onPreRender:function(t,e){t=this.getController(t),this.set1f("amount",t.amount,e)}});t.exports=o},2134:(t,e,i)=>{var s=i(56694),n=i(88222),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.steps=4,this.offsetX=1,this.offsetY=1,this.blurStrength=1,this.strength=1,this.glcolor=[1,1,1]},onPreRender:function(t){t=this.getController(t),this.set1f("strength",t.blurStrength),this.set3fv("color",t.glcolor)},onDraw:function(t){var e=this.getController(),i=this.fullFrame1,s=this.fullFrame2;this.copyFrame(t,s);for(var n=2/t.width*e.offsetX,r=2/t.height*e.offsetY,o=0;o{var s=i(56694),n=i(35491),r=i(75568),o=i(44481),a=i(80486),h=new s({Extends:a,initialize:function(t){a.call(this,{game:t,shaders:[{name:"Gaussian5",fragShader:n},{name:"Gaussian9",fragShader:r},{name:"Gaussian13",fragShader:o}]}),this.activeShader=this.shaders[0],this.x=2,this.y=2,this.steps=4,this.strength=1,this.glcolor=[1,1,1]},setQualityLow:function(){return this.activeShader=this.shaders[0],this},setQualityMedium:function(){return this.activeShader=this.shaders[1],this},setQualityHigh:function(){return this.activeShader=this.shaders[2],this},onDraw:function(t){var e=this.getController(),i=this.gl,s=this.fullFrame1,n=i.getParameter(i.FRAMEBUFFER_BINDING);this.bind(this.activeShader),i.activeTexture(i.TEXTURE0),i.viewport(0,0,t.width,t.height),this.set1i("uMainSampler",0),this.set2f("resolution",t.width,t.height),this.set1f("strength",e.strength),this.set3fv("color",e.glcolor);for(var r=0;r{var s=i(56694),n=i(69960),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.isTiltShift=!1,this.strength=1,this.blurX=1,this.blurY=1,this.radius=.5,this.amount=1,this.contrast=.2},onPreRender:function(t,e,i,s){t=this.getController(t),this.set1f("radius",t.radius,e),this.set1f("amount",t.amount,e),this.set1f("contrast",t.contrast,e),this.set1f("strength",t.strength,e),this.set2f("blur",t.blurX,t.blurY,e),this.setBoolean("isTiltShift",t.isTiltShift,e),i&&s&&this.set2f("resolution",i,s,e)},onDraw:function(t){this.set2f("resolution",t.width,t.height),this.bindAndDraw(t)}});t.exports=o},4323:(t,e,i)=>{var s=i(56694),n=i(33754),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.scale=1,this.feather=.005,this.thickness=8,this.glcolor=[1,.2,.7],this.glcolor2=[1,0,0,.4]},onPreRender:function(t,e,i,s){t=this.getController(t),this.set1f("scale",t.scale,e),this.set1f("feather",t.feather,e),this.set1f("thickness",t.thickness,e),this.set3fv("color",t.glcolor,e),this.set4fv("backgroundColor",t.glcolor2,e),i&&s&&this.set2f("resolution",i,s,e)},onDraw:function(t){this.set2f("resolution",t.width,t.height),this.bindAndDraw(t)}});t.exports=o},92066:(t,e,i)=>{var s=i(56694),n=i(80486),r=new s({Extends:n,initialize:function(t){n.call(this,{game:t})},onDraw:function(t){var e=this.fullFrame1;this.controller?this.manager.drawFrame(t,e,!0,this.controller):this.drawFrame(t,e),this.copyToGame(e)}});t.exports=r},89581:(t,e,i)=>{var s=i(56694),n=i(35668),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.x=.005,this.y=.005,this.glTexture},onBoot:function(){this.setTexture("__WHITE")},setTexture:function(t){var e=this.game.textures.getFrame(t);e&&(this.glTexture=e.glTexture)},onDraw:function(t){var e=this.getController(),i=this.fullFrame1;this.bind(),this.set1i("uMainSampler",0),this.set1i("uDisplacementSampler",1),this.set2f("amount",e.x,e.y),this.bindTexture(e.glTexture,1),this.copySprite(t,i),this.copyToGame(i)}});t.exports=o},55084:(t,e,i)=>{var s=i(56694),n=i(72632),r=i(69675),o=i(80486),a=i(75512),h=new s({Extends:o,initialize:function(t,e){var i=n(e,"quality",.1),s=n(e,"distance",10);o.call(this,{game:t,fragShader:a.setGlowQuality(r,t,i,s)}),this.outerStrength=4,this.innerStrength=0,this.knockout=!1,this.glcolor=[1,1,1,1]},onPreRender:function(t,e,i,s){t=this.getController(t),this.set1f("outerStrength",t.outerStrength,e),this.set1f("innerStrength",t.innerStrength,e),this.set4fv("glowColor",t.glcolor,e),this.setBoolean("knockout",t.knockout,e),i&&s&&this.set2f("resolution",i,s,e)},onDraw:function(t){this.set2f("resolution",t.width,t.height),this.bindAndDraw(t)}});t.exports=h},41653:(t,e,i)=>{var s=i(56694),n=i(90993),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.alpha=.2,this.size=0,this.fromX=0,this.fromY=0,this.toX=0,this.toY=1,this.glcolor1=[255,0,0],this.glcolor2=[0,255,0]},onPreRender:function(t,e){t=this.getController(t),this.set1f("alpha",t.alpha,e),this.set1i("size",t.size,e),this.set3fv("color1",t.glcolor1,e),this.set3fv("color2",t.glcolor2,e),this.set2f("positionFrom",t.fromX,t.fromY,e),this.set2f("positionTo",t.toX,t.toY,e)}});t.exports=o},73416:(t,e,i)=>{var s=i(56694),n=i(37945),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.amount=1},onPreRender:function(t,e,i,s){t=this.getController(t),this.set1f("amount",t.amount,e),i&&s&&this.set2f("resolution",i,s,e)},onDraw:function(t){this.set2f("resolution",t.width,t.height),this.bindAndDraw(t)}});t.exports=o},58049:(t,e,i)=>{var s=i(56694),n=i(85718),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.x=0,this.y=0,this.decay=.1,this.power=1,this.glcolor=[0,0,0,1],this.samples=6,this.intensity=1},onPreRender:function(t,e){var i=(t=this.getController(t)).samples;this.set1i("samples",i,e),this.set1f("intensity",t.intensity,e),this.set1f("decay",t.decay,e),this.set1f("power",t.power/i,e),this.set2f("lightPosition",t.x,t.y,e),this.set4fv("color",t.glcolor,e)}});t.exports=o},18026:(t,e,i)=>{var s=i(56694),n=i(13740),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.speed=.5,this.lineWidth=.5,this.gradient=3,this.reveal=!1},onPreRender:function(t,e,i,s){t=this.getController(t),this.setTime("time",e),this.set1f("speed",t.speed,e),this.set1f("lineWidth",t.lineWidth,e),this.set1f("gradient",t.gradient,e),this.setBoolean("reveal",t.reveal,e),i&&s&&this.set2f("resolution",i,s,e)},onDraw:function(t){this.set2f("resolution",t.width,t.height),this.bindAndDraw(t)}});t.exports=o},72381:(t,e,i)=>{var s=i(56694),n=i(80617),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.x=.5,this.y=.5,this.radius=.5,this.strength=.5},onPreRender:function(t,e){t=this.getController(t),this.set1f("radius",t.radius,e),this.set1f("strength",t.strength,e),this.set2f("position",t.x,t.y,e)}});t.exports=o},80542:(t,e,i)=>{var s=i(56694),n=i(62879),r=i(80486),o=new s({Extends:r,initialize:function(t){r.call(this,{game:t,fragShader:n}),this.progress=0,this.wipeWidth=.1,this.direction=0,this.axis=0,this.reveal=!1},onPreRender:function(t,e){var i=(t=this.getController(t)).progress,s=t.wipeWidth,n=t.direction,r=t.axis;this.set4f("config",i,s,n,r,e),this.setBoolean("reveal",t.reveal,e)}});t.exports=o},58136:(t,e,i)=>{var s={Barrel:i(32469),Bloom:i(2134),Blur:i(63377),Bokeh:i(49745),Circle:i(4323),ColorMatrix:i(92066),Displacement:i(89581),Glow:i(55084),Gradient:i(41653),Pixelate:i(73416),Shadow:i(58049),Shine:i(18026),Vignette:i(72381),Wipe:i(80542)};t.exports=s},62253:(t,e,i)=>{var s=i(65641),n=i(98611),r={FX:i(58136),BitmapMaskPipeline:i(5583),Events:i(18970),FXPipeline:i(81828),LightPipeline:i(66901),MobilePipeline:i(71264),MultiPipeline:i(77310),PointLightPipeline:i(10919),PostFXPipeline:i(80486),PreFXPipeline:i(87228),RopePipeline:i(21213),SinglePipeline:i(51212),UtilityPipeline:i(60848)};r=n(!1,r,s),t.exports=r},2529:t=>{t.exports=["#define SHADER_NAME PHASER_ADD_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 = frame1 + frame2 * uStrength;","}"].join("\n")},91679:t=>{t.exports=["#define SHADER_NAME PHASER_BITMAP_MASK_FS","precision mediump float;","uniform vec2 uResolution;","uniform sampler2D uMainSampler;","uniform sampler2D uMaskSampler;","uniform bool uInvertMaskAlpha;","void main ()","{"," vec2 uv = gl_FragCoord.xy / uResolution;"," vec4 mainColor = texture2D(uMainSampler, uv);"," vec4 maskColor = texture2D(uMaskSampler, uv);"," if (!uInvertMaskAlpha)"," {"," mainColor *= maskColor.a;"," }"," else"," {"," mainColor *= (1.0 - maskColor.a);"," }"," gl_FragColor = mainColor;","}"].join("\n")},89053:t=>{t.exports=["#define SHADER_NAME PHASER_BITMAP_MASK_VS","precision mediump float;","attribute vec2 inPosition;","void main ()","{"," gl_Position = vec4(inPosition, 0.0, 1.0);","}"].join("\n")},37486:t=>{t.exports=["#define SHADER_NAME PHASER_COLORMATRIX_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform float uColorMatrix[20];","uniform float uAlpha;","varying vec2 outTexCoord;","void main ()","{"," vec4 c = texture2D(uMainSampler, outTexCoord);"," if (uAlpha == 0.0)"," {"," gl_FragColor = c;"," return;"," }"," if (c.a > 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")},79060:t=>{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")},87751:t=>{t.exports=["#define SHADER_NAME BARREL_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform float amount;","varying vec2 outTexCoord;","vec2 Distort(vec2 p)","{"," float theta = atan(p.y, p.x);"," float radius = length(p);"," radius = pow(radius, amount);"," p.x = radius * cos(theta);"," p.y = radius * sin(theta);"," return 0.5 * (p + 1.0);","}","void main()","{"," vec2 xy = 2.0 * outTexCoord - 1.0;"," vec2 texCoord = outTexCoord;"," if (length(xy) < 1.0)"," {"," texCoord = Distort(xy);"," }"," gl_FragColor = texture2D(uMainSampler, texCoord);","}"].join("\n")},88222:t=>{t.exports=["#define SHADER_NAME BLOOM_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform vec2 offset;","uniform float strength;","uniform vec3 color;","varying vec2 outTexCoord;","void main ()","{"," vec4 sum = texture2D(uMainSampler, outTexCoord) * 0.204164 * strength;"," sum = sum + texture2D(uMainSampler, outTexCoord + offset * 1.407333) * 0.304005;"," sum = sum + texture2D(uMainSampler, outTexCoord - offset * 1.407333) * 0.304005;"," sum = sum + texture2D(uMainSampler, outTexCoord + offset * 3.294215) * 0.093913;"," gl_FragColor = (sum + texture2D(uMainSampler, outTexCoord - offset * 3.294215) * 0.093913) * vec4(color, 1);","}"].join("\n")},44481:t=>{t.exports=["#define SHADER_NAME BLUR_HIGH_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform vec2 resolution;","uniform vec2 offset;","uniform float strength;","uniform vec3 color;","varying vec2 outTexCoord;","void main ()","{"," vec2 uv = outTexCoord;"," vec4 col = vec4(0.0);"," vec2 off1 = vec2(1.411764705882353) * offset * strength;"," vec2 off2 = vec2(3.2941176470588234) * offset * strength;"," vec2 off3 = vec2(5.176470588235294) * offset * strength;"," col += texture2D(uMainSampler, uv) * 0.1964825501511404;"," col += texture2D(uMainSampler, uv + (off1 / resolution)) * 0.2969069646728344;"," col += texture2D(uMainSampler, uv - (off1 / resolution)) * 0.2969069646728344;"," col += texture2D(uMainSampler, uv + (off2 / resolution)) * 0.09447039785044732;"," col += texture2D(uMainSampler, uv - (off2 / resolution)) * 0.09447039785044732;"," col += texture2D(uMainSampler, uv + (off3 / resolution)) * 0.010381362401148057;"," col += texture2D(uMainSampler, uv - (off3 / resolution)) * 0.010381362401148057;"," gl_FragColor = col * vec4(color, 1.0);","}"].join("\n")},35491:t=>{t.exports=["#define SHADER_NAME BLUR_LOW_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform vec2 resolution;","uniform float strength;","uniform vec3 color;","varying vec2 outTexCoord;","void main ()","{"," vec2 uv = outTexCoord;"," vec4 col = vec4(0.0);"," vec2 offset = vec2(1.333) * strength;"," col += texture2D(uMainSampler, uv) * 0.29411764705882354;"," col += texture2D(uMainSampler, uv + (offset / resolution)) * 0.35294117647058826;"," col += texture2D(uMainSampler, uv - (offset / resolution)) * 0.35294117647058826;"," gl_FragColor = col * vec4(color, 1.0);","}"].join("\n")},75568:t=>{t.exports=["#define SHADER_NAME BLUR_MED_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform vec2 resolution;","uniform vec2 offset;","uniform float strength;","uniform vec3 color;","varying vec2 outTexCoord;","void main ()","{"," vec2 uv = outTexCoord;"," vec4 col = vec4(0.0);"," vec2 off1 = vec2(1.3846153846) * offset * strength;"," vec2 off2 = vec2(3.2307692308) * offset * strength;"," col += texture2D(uMainSampler, uv) * 0.2270270270;"," col += texture2D(uMainSampler, uv + (off1 / resolution)) * 0.3162162162;"," col += texture2D(uMainSampler, uv - (off1 / resolution)) * 0.3162162162;"," col += texture2D(uMainSampler, uv + (off2 / resolution)) * 0.0702702703;"," col += texture2D(uMainSampler, uv - (off2 / resolution)) * 0.0702702703;"," gl_FragColor = col * vec4(color, 1.0);","}"].join("\n")},69960:t=>{t.exports=["#define SHADER_NAME BOKEH_FS","precision mediump float;","#define ITERATIONS 100.0","#define ONEOVER_ITR 1.0 / ITERATIONS","#define PI 3.141596","#define GOLDEN_ANGLE 2.39996323","uniform sampler2D uMainSampler;","uniform vec2 resolution;","uniform float radius;","uniform float amount;","uniform float contrast;","uniform bool isTiltShift;","uniform float strength;","uniform vec2 blur;","varying vec2 outTexCoord;","vec2 Sample (in float theta, inout float r)","{"," r += 1.0 / r;"," return (r - 1.0) * vec2(cos(theta), sin(theta)) * 0.06;","}","vec3 Bokeh (sampler2D tex, vec2 uv, float radius)","{"," vec3 acc = vec3(0.0);"," vec3 div = vec3(0.0);"," vec2 pixel = vec2(resolution.y / resolution.x, 1.0) * radius * .025;"," float r = 1.0;"," for (float j = 0.0; j < GOLDEN_ANGLE * ITERATIONS; j += GOLDEN_ANGLE)"," {"," vec3 col = texture2D(tex, uv + pixel * Sample(j, r)).xyz;"," col = contrast > 0.0 ? col * col * (1.0 + contrast) : col;"," vec3 bokeh = vec3(0.5) + pow(col, vec3(10.0)) * amount;"," acc += col * bokeh;"," div += bokeh;"," }"," return acc / div;","}","void main ()","{"," float shift = 1.0;"," if (isTiltShift)"," {"," vec2 uv = vec2(gl_FragCoord.xy / resolution + vec2(-0.5, -0.5)) * 2.0;"," float centerStrength = 1.0;"," shift = length(uv * blur * strength) * centerStrength;"," }"," gl_FragColor = vec4(Bokeh(uMainSampler, outTexCoord * vec2(1.0, 1.0), radius * shift), 0.0);","}"].join("\n")},33754:t=>{t.exports=["#define SHADER_NAME CIRCLE_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform vec2 resolution;","uniform vec3 color;","uniform vec4 backgroundColor;","uniform float thickness;","uniform float scale;","uniform float feather;","varying vec2 outTexCoord;","void main ()","{"," vec4 texture = texture2D(uMainSampler, outTexCoord);"," vec2 position = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0;"," float aspectRatio = resolution.x / resolution.y;"," position.x *= aspectRatio;"," float grad = length(position);"," float outer = aspectRatio;"," float inner = outer - (thickness * 2.0 / resolution.y);"," if (aspectRatio >= 1.0)"," {"," float f = 2.0 + (resolution.y / resolution.x);"," outer = 1.0;"," inner = 1.0 - (thickness * f / resolution.x);"," }"," outer *= scale;"," inner *= scale;"," float circle = smoothstep(outer, outer - 0.01, grad);"," float ring = circle - smoothstep(inner, inner - feather, grad);"," texture = mix(backgroundColor * backgroundColor.a, texture, texture.a);"," texture = (texture * (circle - ring));"," gl_FragColor = vec4(texture.rgb + (ring * color), texture.a);","}"].join("\n")},35668:t=>{t.exports=["#define SHADER_NAME DISPLACEMENT_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform sampler2D uDisplacementSampler;","uniform vec2 amount;","varying vec2 outTexCoord;","void main ()","{"," vec2 disp = (-vec2(0.5, 0.5) + texture2D(uDisplacementSampler, outTexCoord).rr) * amount;"," gl_FragColor = texture2D(uMainSampler, outTexCoord + disp).rgba;","}"].join("\n")},69675:t=>{t.exports=["#define SHADER_NAME GLOW_FS","precision mediump float;","uniform sampler2D uMainSampler;","varying vec2 outTexCoord;","uniform float outerStrength;","uniform float innerStrength;","uniform vec2 resolution;","uniform vec4 glowColor;","uniform bool knockout;","const float PI = 3.14159265358979323846264;","const float DIST = __DIST__;","const float SIZE = min(__SIZE__, PI * 2.0);","const float STEP = ceil(PI * 2.0 / SIZE);","const float MAX_ALPHA = STEP * DIST * (DIST + 1.0) / 2.0;","void main ()","{"," vec2 px = vec2(1.0 / resolution.x, 1.0 / resolution.y);"," float totalAlpha = 0.0;"," vec2 direction;"," vec2 displaced;"," vec4 color;"," for (float angle = 0.0; angle < PI * 2.0; angle += SIZE)"," {"," direction = vec2(cos(angle), sin(angle)) * px;"," for (float curDistance = 0.0; curDistance < DIST; curDistance++)"," {"," displaced = outTexCoord + direction * (curDistance + 1.0);"," color = texture2D(uMainSampler, displaced);"," totalAlpha += (DIST - curDistance) * color.a;"," }"," }"," color = texture2D(uMainSampler, outTexCoord);"," float alphaRatio = (totalAlpha / MAX_ALPHA);"," float innerGlowAlpha = (1.0 - alphaRatio) * innerStrength * color.a;"," float innerGlowStrength = min(1.0, innerGlowAlpha);"," vec4 innerColor = mix(color, glowColor, innerGlowStrength);"," float outerGlowAlpha = alphaRatio * outerStrength * (1.0 - color.a);"," float outerGlowStrength = min(1.0 - innerColor.a, outerGlowAlpha);"," vec4 outerGlowColor = outerGlowStrength * glowColor.rgba;"," if (knockout)"," {"," float resultAlpha = outerGlowAlpha + innerGlowAlpha;"," gl_FragColor = vec4(glowColor.rgb * resultAlpha, resultAlpha);"," }"," else"," {"," gl_FragColor = innerColor + outerGlowColor;"," }","}"].join("\n")},90993:t=>{t.exports=["#define SHADER_NAME GRADIENT_FS","#define SRGB_TO_LINEAR(c) pow((c), vec3(2.2))","#define LINEAR_TO_SRGB(c) pow((c), vec3(1.0 / 2.2))","#define SRGB(r, g, b) SRGB_TO_LINEAR(vec3(float(r), float(g), float(b)) / 255.0)","precision mediump float;","uniform sampler2D uMainSampler;","uniform vec2 positionFrom;","uniform vec2 positionTo;","uniform vec3 color1;","uniform vec3 color2;","uniform float alpha;","uniform int size;","varying vec2 outTexCoord;","float gradientNoise(in vec2 uv)","{"," const vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189);"," return fract(magic.z * fract(dot(uv, magic.xy)));","}","float stepped (in float s, in float scale, in int steps)","{"," return steps > 0 ? floor( s / ((1.0 * scale) / float(steps))) * 1.0 / float(steps - 1) : s;","}","void main ()","{"," vec2 a = positionFrom;"," vec2 b = positionTo;"," vec2 ba = b - a;"," float d = dot(outTexCoord - a, ba) / dot(ba, ba);"," float t = size > 0 ? stepped(d, 1.0, size) : d;"," t = smoothstep(0.0, 1.0, clamp(t, 0.0, 1.0));"," vec3 color = mix(SRGB(color1.r, color1.g, color1.b), SRGB(color2.r, color2.g, color2.b), t);"," color = LINEAR_TO_SRGB(color);"," color += (1.0 / 255.0) * gradientNoise(outTexCoord) - (0.5 / 255.0);"," vec4 texture = texture2D(uMainSampler, outTexCoord);"," gl_FragColor = vec4(mix(color.rgb, texture.rgb, alpha), 1.0) * texture.a;","}"].join("\n")},37945:t=>{t.exports=["#define SHADER_NAME PIXELATE_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform vec2 resolution;","uniform float amount;","varying vec2 outTexCoord;","void main ()","{"," float pixelSize = floor(2.0 + amount);"," vec2 center = pixelSize * floor(outTexCoord * resolution / pixelSize) + pixelSize * vec2(0.5, 0.5);"," vec2 corner1 = center + pixelSize * vec2(-0.5, -0.5);"," vec2 corner2 = center + pixelSize * vec2(+0.5, -0.5);"," vec2 corner3 = center + pixelSize * vec2(+0.5, +0.5);"," vec2 corner4 = center + pixelSize * vec2(-0.5, +0.5);"," vec4 pixel = 0.4 * texture2D(uMainSampler, center / resolution);"," pixel += 0.15 * texture2D(uMainSampler, corner1 / resolution);"," pixel += 0.15 * texture2D(uMainSampler, corner2 / resolution);"," pixel += 0.15 * texture2D(uMainSampler, corner3 / resolution);"," pixel += 0.15 * texture2D(uMainSampler, corner4 / resolution);"," gl_FragColor = pixel;","}"].join("\n")},85718:t=>{t.exports=["#define SHADER_NAME SHADOW_FS","precision mediump float;","uniform sampler2D uMainSampler;","varying vec2 outTexCoord;","uniform vec2 lightPosition;","uniform vec4 color;","uniform float decay;","uniform float power;","uniform float intensity;","uniform int samples;","const int MAX = 12;","void main ()","{"," vec4 texture = texture2D(uMainSampler, outTexCoord);"," vec2 pc = (lightPosition - outTexCoord) * intensity;"," float shadow = 0.0;"," float limit = max(float(MAX), float(samples));"," for (int i = 0; i < MAX; ++i)"," {"," if (i >= samples)"," {"," break;"," }"," shadow += texture2D(uMainSampler, outTexCoord + float(i) * decay / limit * pc).a * power;"," }"," float mask = 1.0 - texture.a;"," gl_FragColor = mix(texture, color, shadow * mask);","}"].join("\n")},13740:t=>{t.exports=["#define SHADER_NAME SHINE_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform vec2 resolution;","uniform bool reveal;","uniform float speed;","uniform float time;","uniform float lineWidth;","uniform float gradient;","varying vec2 outTexCoord;","void main ()","{","\tvec2 uv = gl_FragCoord.xy / resolution.xy;"," vec4 tex = texture2D(uMainSampler, outTexCoord);"," vec4 col1 = vec4(0.3, 0.0, 0.0, 1.0);"," vec4 col2 = vec4(0.85, 0.85, 0.85, 1.0);"," uv.x = uv.x - mod(time * speed, 2.0) + 0.5;"," float y = uv.x * gradient;"," float s = smoothstep(y - lineWidth, y, uv.y) - smoothstep(y, y + lineWidth, uv.y);"," gl_FragColor = (((s * col1) + (s * col2)) * tex);"," if (!reveal)"," {"," gl_FragColor += tex;"," }","}"].join("\n")},80617:t=>{t.exports=["#define SHADER_NAME VIGNETTE_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform float radius;","uniform float strength;","uniform vec2 position;","varying vec2 outTexCoord;","void main ()","{"," vec4 col = vec4(1.0);"," float d = length(outTexCoord - position);"," if (d <= radius)"," {"," float g = d / radius;"," g = sin(g * 3.14 * strength);"," \tcol = vec4(g * g * g);"," }"," vec4 texture = texture2D(uMainSampler, outTexCoord);"," gl_FragColor = texture * (1.0 - col);","}"].join("\n")},62879:t=>{t.exports=["#define SHADER_NAME WIPE_FS","precision mediump float;","uniform sampler2D uMainSampler;","uniform vec4 config;","uniform bool reveal;","varying vec2 outTexCoord;","void main ()","{"," vec2 uv = outTexCoord;"," vec4 color0;"," vec4 color1;"," if (reveal)"," {"," color0 = vec4(0);"," color1 = texture2D(uMainSampler, uv);"," }"," else"," {"," color0 = texture2D(uMainSampler, uv);"," color1 = vec4(0);"," }"," float distance = config.x;"," float width = config.y;"," float direction = config.z;"," float axis = uv.x;"," if (config.w == 1.0)"," {"," axis = uv.y;"," }"," float adjust = mix(width, -width, distance);"," float value = smoothstep(distance - width, distance + width, abs(direction - axis) + adjust);"," gl_FragColor = mix(color1, color0, value);","}"].join("\n")},65045:t=>{t.exports=["#define SHADER_NAME PHASER_LIGHT_FS","precision mediump float;","struct Light","{"," vec2 position;"," vec3 color;"," float intensity;"," float radius;","};","const int kMaxLights = %LIGHT_COUNT%;","uniform vec4 uCamera; /* x, y, rotation, zoom */","uniform vec2 uResolution;","uniform sampler2D uMainSampler;","uniform sampler2D uNormSampler;","uniform vec3 uAmbientLightColor;","uniform Light uLights[kMaxLights];","uniform mat3 uInverseRotationMatrix;","uniform int uLightCount;","varying vec2 outTexCoord;","varying float outTexId;","varying float outTintEffect;","varying vec4 outTint;","void main ()","{"," vec3 finalColor = vec3(0.0, 0.0, 0.0);"," vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);"," vec4 texture = texture2D(uMainSampler, outTexCoord);"," vec4 color = texture * texel;"," if (outTintEffect == 1.0)"," {"," color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);"," }"," else if (outTintEffect == 2.0)"," {"," color = texel;"," }"," vec3 normalMap = texture2D(uNormSampler, outTexCoord).rgb;"," vec3 normal = normalize(uInverseRotationMatrix * vec3(normalMap * 2.0 - 1.0));"," vec2 res = vec2(min(uResolution.x, uResolution.y)) * uCamera.w;"," for (int index = 0; index < kMaxLights; ++index)"," {"," if (index < uLightCount)"," {"," Light light = uLights[index];"," vec3 lightDir = vec3((light.position.xy / res) - (gl_FragCoord.xy / res), 0.1);"," vec3 lightNormal = normalize(lightDir);"," float distToSurf = length(lightDir) * uCamera.w;"," float diffuseFactor = max(dot(normal, lightNormal), 0.0);"," float radius = (light.radius / res.x * uCamera.w) * uCamera.w;"," float attenuation = clamp(1.0 - distToSurf * distToSurf / (radius * radius), 0.0, 1.0);"," vec3 diffuse = light.color * diffuseFactor;"," finalColor += (attenuation * diffuse) * light.intensity;"," }"," }"," vec4 colorOutput = vec4(uAmbientLightColor + finalColor, 1.0);"," gl_FragColor = color * vec4(colorOutput.rgb * colorOutput.a, colorOutput.a);","}"].join("\n")},98921:t=>{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")},25005:t=>{t.exports=["#define SHADER_NAME PHASER_MESH_FS","precision mediump float;","uniform vec3 uLightPosition;","uniform vec3 uLightAmbient;","uniform vec3 uLightDiffuse;","uniform vec3 uLightSpecular;","uniform vec3 uFogColor;","uniform float uFogNear;","uniform float uFogFar;","uniform vec3 uMaterialAmbient;","uniform vec3 uMaterialDiffuse;","uniform vec3 uMaterialSpecular;","uniform float uMaterialShine;","uniform vec3 uCameraPosition;","uniform sampler2D uTexture;","varying vec2 vTextureCoord;","varying vec3 vNormal;","varying vec3 vPosition;","void main (void)","{"," vec4 color = texture2D(uTexture, vTextureCoord);"," vec3 ambient = uLightAmbient * uMaterialAmbient;"," vec3 norm = normalize(vNormal);"," vec3 lightDir = normalize(uLightPosition - vPosition);"," float diff = max(dot(norm, lightDir), 0.0);"," vec3 diffuse = uLightDiffuse * (diff * uMaterialDiffuse);"," vec3 viewDir = normalize(uCameraPosition - vPosition);"," vec3 reflectDir = reflect(-lightDir, norm);"," float spec = pow(max(dot(viewDir, reflectDir), 0.0), uMaterialShine);"," vec3 specular = uLightSpecular * (spec * uMaterialSpecular);"," vec3 result = (ambient + diffuse + specular) * color.rgb;"," float depth = gl_FragCoord.z / gl_FragCoord.w;"," float fogFactor = smoothstep(uFogNear, uFogFar, depth);"," gl_FragColor.rgb = mix(result.rgb, uFogColor, fogFactor);"," gl_FragColor.a = color.a;","}"].join("\n")},94914:t=>{t.exports=["#define SHADER_NAME PHASER_MESH_VS","precision mediump float;","attribute vec3 aVertexPosition;","attribute vec3 aVertexNormal;","attribute vec2 aTextureCoord;","uniform mat4 uViewProjectionMatrix;","uniform mat4 uModelMatrix;","uniform mat4 uNormalMatrix;","varying vec2 vTextureCoord;","varying vec3 vNormal;","varying vec3 vPosition;","void main ()","{"," vTextureCoord = aTextureCoord;"," vPosition = vec3(uModelMatrix * vec4(aVertexPosition, 1.0));"," vNormal = vec3(uNormalMatrix * vec4(aVertexNormal, 1.0));"," gl_Position = uViewProjectionMatrix * uModelMatrix * vec4(aVertexPosition, 1.0);","}"].join("\n")},11263:t=>{t.exports=["#define SHADER_NAME PHASER_MOBILE_FS","#ifdef GL_FRAGMENT_PRECISION_HIGH","precision highp float;","#else","precision mediump float;","#endif","uniform sampler2D uMainSampler;","varying vec2 outTexCoord;","varying float outTintEffect;","varying vec4 outTint;","void main ()","{"," vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);"," vec4 texture = texture2D(uMainSampler, outTexCoord);"," vec4 color = texture * texel;"," if (outTintEffect == 1.0)"," {"," color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);"," }"," else if (outTintEffect == 2.0)"," {"," color = texel;"," }"," gl_FragColor = color;","}"].join("\n")},51852:t=>{t.exports=["#define SHADER_NAME PHASER_MOBILE_VS","#ifdef GL_FRAGMENT_PRECISION_HIGH","precision highp float;","#else","precision mediump float;","#endif","uniform mat4 uProjectionMatrix;","attribute vec2 inPosition;","attribute vec2 inTexCoord;","attribute float inTexId;","attribute float inTintEffect;","attribute vec4 inTint;","varying vec2 outTexCoord;","varying float outTintEffect;","varying vec4 outTint;","void main ()","{"," gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);"," outTexCoord = inTexCoord;"," outTint = inTint;"," outTintEffect = inTintEffect;","}"].join("\n")},53787:t=>{t.exports=["#define SHADER_NAME PHASER_MULTI_FS","#ifdef GL_FRAGMENT_PRECISION_HIGH","precision highp float;","#else","precision mediump float;","#endif","uniform sampler2D uMainSampler[%count%];","varying vec2 outTexCoord;","varying float outTexId;","varying float outTintEffect;","varying vec4 outTint;","void main ()","{"," vec4 texture;"," %forloop%"," vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);"," vec4 color = texture * texel;"," if (outTintEffect == 1.0)"," {"," color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);"," }"," else if (outTintEffect == 2.0)"," {"," color = texel;"," }"," gl_FragColor = color;","}"].join("\n")},15968:t=>{t.exports=["#define SHADER_NAME PHASER_MULTI_VS","#ifdef GL_FRAGMENT_PRECISION_HIGH","precision highp float;","#else","precision mediump float;","#endif","uniform mat4 uProjectionMatrix;","attribute vec2 inPosition;","attribute vec2 inTexCoord;","attribute float inTexId;","attribute float inTintEffect;","attribute vec4 inTint;","varying vec2 outTexCoord;","varying float outTexId;","varying float outTintEffect;","varying vec4 outTint;","void main ()","{"," gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);"," outTexCoord = inTexCoord;"," outTexId = inTexId;"," outTint = inTint;"," outTintEffect = inTintEffect;","}"].join("\n")},83327:t=>{t.exports=["#define SHADER_NAME PHASER_POINTLIGHT_FS","precision mediump float;","uniform vec2 uResolution;","uniform float uCameraZoom;","varying vec4 lightPosition;","varying vec4 lightColor;","varying float lightRadius;","varying float lightAttenuation;","void main ()","{"," vec2 center = (lightPosition.xy + 1.0) * (uResolution.xy * 0.5);"," float distToSurf = length(center - gl_FragCoord.xy);"," float radius = 1.0 - distToSurf / (lightRadius * uCameraZoom);"," float intensity = smoothstep(0.0, 1.0, radius * lightAttenuation);"," vec4 color = vec4(intensity, intensity, intensity, 0.0) * lightColor;"," gl_FragColor = vec4(color.rgb * lightColor.a, color.a);","}"].join("\n")},54677:t=>{t.exports=["#define SHADER_NAME PHASER_POINTLIGHT_VS","precision mediump float;","uniform mat4 uProjectionMatrix;","attribute vec2 inPosition;","attribute vec2 inLightPosition;","attribute vec4 inLightColor;","attribute float inLightRadius;","attribute float inLightAttenuation;","varying vec4 lightPosition;","varying vec4 lightColor;","varying float lightRadius;","varying float lightAttenuation;","void main ()","{"," lightColor = inLightColor;"," lightRadius = inLightRadius;"," lightAttenuation = inLightAttenuation;"," lightPosition = uProjectionMatrix * vec4(inLightPosition, 1.0, 1.0);"," gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);","}"].join("\n")},12569:t=>{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")},99365:t=>{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")},85060:t=>{t.exports=["#define SHADER_NAME PHASER_SINGLE_FS","#ifdef GL_FRAGMENT_PRECISION_HIGH","precision highp float;","#else","precision mediump float;","#endif","uniform sampler2D uMainSampler;","varying vec2 outTexCoord;","varying float outTintEffect;","varying vec4 outTint;","void main ()","{"," vec4 texture = texture2D(uMainSampler, outTexCoord);"," vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);"," vec4 color = texture * texel;"," if (outTintEffect == 1.0)"," {"," color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);"," }"," else if (outTintEffect == 2.0)"," {"," color = texel;"," }"," gl_FragColor = color;","}"].join("\n")},18166:t=>{t.exports=["#define SHADER_NAME PHASER_SINGLE_VS","precision mediump float;","uniform mat4 uProjectionMatrix;","attribute vec2 inPosition;","attribute vec2 inTexCoord;","attribute float inTexId;","attribute float inTintEffect;","attribute vec4 inTint;","varying vec2 outTexCoord;","varying float outTintEffect;","varying vec4 outTint;","void main ()","{"," gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);"," outTexCoord = inTexCoord;"," outTint = inTint;"," outTintEffect = inTintEffect;","}"].join("\n")},92462:(t,e,i)=>{t.exports={AddBlendFrag:i(2529),BitmapMaskFrag:i(91679),BitmapMaskVert:i(89053),ColorMatrixFrag:i(37486),CopyFrag:i(79060),FXBarrelFrag:i(87751),FXBloomFrag:i(88222),FXBlurHighFrag:i(44481),FXBlurLowFrag:i(35491),FXBlurMedFrag:i(75568),FXBokehFrag:i(69960),FXCircleFrag:i(33754),FXDisplacementFrag:i(35668),FXGlowFrag:i(69675),FXGradientFrag:i(90993),FXPixelateFrag:i(37945),FXShadowFrag:i(85718),FXShineFrag:i(13740),FXVignetteFrag:i(80617),FXWipeFrag:i(62879),LightFrag:i(65045),LinearBlendFrag:i(98921),MeshFrag:i(25005),MeshVert:i(94914),MobileFrag:i(11263),MobileVert:i(51852),MultiFrag:i(53787),MultiVert:i(15968),PointLightFrag:i(83327),PointLightVert:i(54677),PostFXFrag:i(12569),QuadVert:i(99365),SingleFrag:i(85060),SingleVert:i(18166)}},756:(t,e,i)=>{var s=i(55301),n=i(56694),r=i(6659),o=i(40444),a=i(97081),h=i(74181),l=i(2893),u=i(9229),c=i(72283),d=i(74118),f=i(90881),p=i(84314),v=i(93736),g=i(47751),m=new n({Extends:r,initialize:function(t){r.call(this),this.game=t,this.canvas,this.canvasBounds=new d,this.parent=null,this.parentIsWindow=!1,this.parentSize=new f,this.gameSize=new f,this.baseSize=new f,this.displaySize=new f,this.scaleMode=s.SCALE_MODE.NONE,this.zoom=1,this._resetZoom=!1,this.displayScale=new v(1,1),this.autoRound=!1,this.autoCenter=s.CENTER.NO_CENTER,this.orientation=s.ORIENTATION.LANDSCAPE,this.fullscreen,this.fullscreenTarget=null,this._createdFullscreenTarget=!1,this.dirty=!1,this.resizeInterval=500,this._lastCheck=0,this._checkOrientation=!1,this.domlisteners={orientationChange:c,windowResize:c,fullScreenChange:c,fullScreenError:c}},preBoot:function(){this.parseConfig(this.game.config),this.game.events.once(a.BOOT,this.boot,this)},boot:function(){var t=this.game;this.canvas=t.canvas,this.fullscreen=t.device.fullscreen,this.scaleMode!==s.SCALE_MODE.RESIZE&&this.displaySize.setAspectMode(this.scaleMode),this.scaleMode===s.SCALE_MODE.NONE?this.resize(this.width,this.height):(this.getParentBounds(),this.parentSize.width>0&&this.parentSize.height>0&&this.displaySize.setParent(this.parentSize),this.refresh()),t.events.on(a.PRE_STEP,this.step,this),t.events.once(a.READY,this.refresh,this),t.events.once(a.DESTROY,this.destroy,this),this.startListeners()},parseConfig:function(t){this.getParent(t),this.getParentBounds();var e=t.width,i=t.height,n=t.scaleMode,r=t.zoom,o=t.autoRound;if("string"==typeof e){var a=this.parentSize.width;0===a&&(a=window.innerWidth);var h=parseInt(e,10)/100;e=Math.floor(a*h)}if("string"==typeof i){var l=this.parentSize.height;0===l&&(l=window.innerHeight);var c=parseInt(i,10)/100;i=Math.floor(l*c)}this.scaleMode=n,this.autoRound=o,this.autoCenter=t.autoCenter,this.resizeInterval=t.resizeInterval,o&&(e=Math.floor(e),i=Math.floor(i)),this.gameSize.setSize(e,i),r===s.ZOOM.MAX_ZOOM&&(r=this.getMaxZoom()),this.zoom=r,1!==r&&(this._resetZoom=!0),this.baseSize.setSize(e,i),o&&(this.baseSize.width=Math.floor(this.baseSize.width),this.baseSize.height=Math.floor(this.baseSize.height)),t.minWidth>0&&this.displaySize.setMin(t.minWidth*r,t.minHeight*r),t.maxWidth>0&&this.displaySize.setMax(t.maxWidth*r,t.maxHeight*r),this.displaySize.setSize(e,i),this.orientation=u(e,i)},getParent:function(t){var e=t.parent;if(null!==e){if(this.parent=l(e),this.parentIsWindow=this.parent===document.body,t.expandParent&&t.scaleMode!==s.SCALE_MODE.NONE){var i=this.parent.getBoundingClientRect();(this.parentIsWindow||0===i.height)&&(document.documentElement.style.height="100%",document.body.style.height="100%",i=this.parent.getBoundingClientRect(),this.parentIsWindow||0!==i.height||(this.parent.style.overflow="hidden",this.parent.style.width="100%",this.parent.style.height="100%"))}t.fullscreenTarget&&!this.fullscreenTarget&&(this.fullscreenTarget=l(t.fullscreenTarget))}},getParentBounds:function(){if(!this.parent)return!1;var t=this.parentSize,e=this.parent.getBoundingClientRect();this.parentIsWindow&&this.game.device.os.iOS&&(e.height=h(!0));var i=e.width,s=e.height;if(t.width!==i||t.height!==s)return t.setSize(i,s),!0;if(this.canvas){var n=this.canvasBounds,r=this.canvas.getBoundingClientRect();if(r.x!==n.x||r.y!==n.y)return!0}return!1},lockOrientation:function(t){var e=screen.lockOrientation||screen.mozLockOrientation||screen.msLockOrientation;return!!e&&e.call(screen,t)},setParentSize:function(t,e){return this.parentSize.setSize(t,e),this.refresh()},setGameSize:function(t,e){var i=this.autoRound;i&&(t=Math.floor(t),e=Math.floor(e));var s=this.width,n=this.height;return this.gameSize.resize(t,e),this.baseSize.resize(t,e),i&&(this.baseSize.width=Math.floor(this.baseSize.width),this.baseSize.height=Math.floor(this.baseSize.height)),this.displaySize.setAspectRatio(t/e),this.canvas.width=this.baseSize.width,this.canvas.height=this.baseSize.height,this.refresh(s,n)},resize:function(t,e){var i=this.zoom,s=this.autoRound;s&&(t=Math.floor(t),e=Math.floor(e));var n=this.width,r=this.height;this.gameSize.resize(t,e),this.baseSize.resize(t,e),s&&(this.baseSize.width=Math.floor(this.baseSize.width),this.baseSize.height=Math.floor(this.baseSize.height)),this.displaySize.setSize(t*i,e*i),this.canvas.width=this.baseSize.width,this.canvas.height=this.baseSize.height;var o=this.canvas.style,a=t*i,h=e*i;return s&&(a=Math.floor(a),h=Math.floor(h)),a===t&&h===e||(o.width=a+"px",o.height=h+"px"),this.refresh(n,r)},setZoom:function(t){return this.zoom=t,this._resetZoom=!0,this.refresh()},setMaxZoom:function(){return this.zoom=this.getMaxZoom(),this._resetZoom=!0,this.refresh()},refresh:function(t,e){void 0===t&&(t=this.width),void 0===e&&(e=this.height),this.updateScale(),this.updateBounds(),this.updateOrientation(),this.displayScale.set(this.baseSize.width/this.canvasBounds.width,this.baseSize.height/this.canvasBounds.height);var i=this.game.domContainer;if(i){this.baseSize.setCSS(i);var s=this.canvas.style,n=i.style;n.transform="scale("+this.displaySize.width/this.baseSize.width+","+this.displaySize.height/this.baseSize.height+")",n.marginLeft=s.marginLeft,n.marginTop=s.marginTop}return this.emit(o.RESIZE,this.gameSize,this.baseSize,this.displaySize,t,e),this},updateOrientation:function(){if(this._checkOrientation){this._checkOrientation=!1;var t=u(this.width,this.height);t!==this.orientation&&(this.orientation=t,this.emit(o.ORIENTATION_CHANGE,t))}},updateScale:function(){var t,e,i=this.canvas.style,n=this.gameSize.width,r=this.gameSize.height,o=this.zoom,a=this.autoRound;this.scaleMode===s.SCALE_MODE.NONE?(this.displaySize.setSize(n*o,r*o),t=this.displaySize.width,e=this.displaySize.height,a&&(t=Math.floor(t),e=Math.floor(e)),this._resetZoom&&(i.width=t+"px",i.height=e+"px",this._resetZoom=!1)):this.scaleMode===s.SCALE_MODE.RESIZE?(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),t=this.displaySize.width,e=this.displaySize.height,a&&(t=Math.floor(t),e=Math.floor(e)),this.canvas.width=t,this.canvas.height=e):(this.displaySize.setSize(this.parentSize.width,this.parentSize.height),t=this.displaySize.width,e=this.displaySize.height,a&&(t=Math.floor(t),e=Math.floor(e)),i.width=t+"px",i.height=e+"px"),this.getParentBounds(),this.updateCenter()},getMaxZoom:function(){var t=p(this.parentSize.width,this.gameSize.width,0,!0),e=p(this.parentSize.height,this.gameSize.height,0,!0);return Math.max(Math.min(t,e),1)},updateCenter:function(){var t=this.autoCenter;if(t!==s.CENTER.NO_CENTER){var e=this.canvas,i=e.style,n=e.getBoundingClientRect(),r=n.width,o=n.height,a=Math.floor((this.parentSize.width-r)/2),h=Math.floor((this.parentSize.height-o)/2);t===s.CENTER.CENTER_HORIZONTALLY?h=0:t===s.CENTER.CENTER_VERTICALLY&&(a=0),i.marginLeft=a+"px",i.marginTop=h+"px"}},updateBounds:function(){var t=this.canvasBounds,e=this.canvas.getBoundingClientRect();t.x=e.left+(window.pageXOffset||0)-(document.documentElement.clientLeft||0),t.y=e.top+(window.pageYOffset||0)-(document.documentElement.clientTop||0),t.width=e.width,t.height=e.height},transformX:function(t){return(t-this.canvasBounds.left)*this.displayScale.x},transformY:function(t){return(t-this.canvasBounds.top)*this.displayScale.y},startFullscreen:function(t){void 0===t&&(t={navigationUI:"hide"});var e=this.fullscreen;if(e.available){if(!e.active){var i=this.getFullscreenTarget();e.keyboard?i[e.request](Element.ALLOW_KEYBOARD_INPUT):i[e.request](t)}}else this.emit(o.FULLSCREEN_UNSUPPORTED)},fullscreenSuccessHandler:function(){this.getParentBounds(),this.refresh(),this.emit(o.ENTER_FULLSCREEN)},fullscreenErrorHandler:function(t){this.removeFullscreenTarget(),this.emit(o.FULLSCREEN_FAILED,t)},getFullscreenTarget:function(){if(!this.fullscreenTarget){var t=document.createElement("div");t.style.margin="0",t.style.padding="0",t.style.width="100%",t.style.height="100%",this.fullscreenTarget=t,this._createdFullscreenTarget=!0}this._createdFullscreenTarget&&(this.canvas.parentNode.insertBefore(this.fullscreenTarget,this.canvas),this.fullscreenTarget.appendChild(this.canvas));return this.fullscreenTarget},removeFullscreenTarget:function(){if(this._createdFullscreenTarget){var t=this.fullscreenTarget;if(t&&t.parentNode){var e=t.parentNode;e.insertBefore(this.canvas,t),e.removeChild(t)}}},stopFullscreen:function(){var t=this.fullscreen;if(!t.available)return this.emit(o.FULLSCREEN_UNSUPPORTED),!1;t.active&&document[t.cancel](),this.removeFullscreenTarget(),this.getParentBounds(),this.emit(o.LEAVE_FULLSCREEN),this.refresh()},toggleFullscreen:function(t){this.fullscreen.active?this.stopFullscreen():this.startFullscreen(t)},startListeners:function(){var t=this,e=this.domlisteners;if(e.orientationChange=function(){t.updateBounds(),t._checkOrientation=!0,t.dirty=!0},e.windowResize=function(){t.updateBounds(),t.dirty=!0},window.addEventListener("orientationchange",e.orientationChange,!1),window.addEventListener("resize",e.windowResize,!1),this.fullscreen.available){e.fullScreenChange=function(e){return t.onFullScreenChange(e)},e.fullScreenError=function(e){return t.onFullScreenError(e)};["webkit","moz",""].forEach((function(t){document.addEventListener(t+"fullscreenchange",e.fullScreenChange,!1),document.addEventListener(t+"fullscreenerror",e.fullScreenError,!1)})),document.addEventListener("MSFullscreenChange",e.fullScreenChange,!1),document.addEventListener("MSFullscreenError",e.fullScreenError,!1)}},onFullScreenChange:function(){document.fullscreenElement||document.webkitFullscreenElement||document.msFullscreenElement||document.mozFullScreenElement?this.fullscreenSuccessHandler():this.stopFullscreen()},onFullScreenError:function(){this.removeFullscreenTarget()},getViewPort:function(t,e){t instanceof g||(e=t,t=void 0),void 0===e&&(e=new d);var i,s,n=this.baseSize,r=this.parentSize,o=this.canvasBounds,a=this.displayScale,h=o.x>=0?0:-o.x*a.x,l=o.y>=0?0:-o.y*a.y;return i=r.width>=o.width?n.width:n.width-(o.width-r.width)*a.x,s=r.height>=o.height?n.height:n.height-(o.height-r.height)*a.y,e.setTo(h,l,i,s),t&&(e.width/=t.zoomX,e.height/=t.zoomY,e.centerX=t.centerX+t.scrollX,e.centerY=t.centerY+t.scrollY),e},step:function(t,e){this.parent&&(this._lastCheck+=e,(this.dirty||this._lastCheck>this.resizeInterval)&&(this.getParentBounds()&&this.refresh(),this.dirty=!1,this._lastCheck=0))},stopListeners:function(){var t=this.domlisteners;window.removeEventListener("orientationchange",t.orientationChange,!1),window.removeEventListener("resize",t.windowResize,!1);["webkit","moz",""].forEach((function(e){document.removeEventListener(e+"fullscreenchange",t.fullScreenChange,!1),document.removeEventListener(e+"fullscreenerror",t.fullScreenError,!1)})),document.removeEventListener("MSFullscreenChange",t.fullScreenChange,!1),document.removeEventListener("MSFullscreenError",t.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===s.ORIENTATION.PORTRAIT}},isLandscape:{get:function(){return this.orientation===s.ORIENTATION.LANDSCAPE}},isGamePortrait:{get:function(){return this.height>this.width}},isGameLandscape:{get:function(){return this.width>this.height}}});t.exports=m},35098:t=>{t.exports={NO_CENTER:0,CENTER_BOTH:1,CENTER_HORIZONTALLY:2,CENTER_VERTICALLY:3}},53539:t=>{t.exports={LANDSCAPE:"landscape-primary",PORTRAIT:"portrait-primary"}},12637:t=>{t.exports={NONE:0,WIDTH_CONTROLS_HEIGHT:1,HEIGHT_CONTROLS_WIDTH:2,FIT:3,ENVELOP:4,RESIZE:5}},10217:t=>{t.exports={NO_ZOOM:1,ZOOM_2X:2,ZOOM_4X:4,MAX_ZOOM:-1}},55301:(t,e,i)=>{var s={CENTER:i(35098),ORIENTATION:i(53539),SCALE_MODE:i(12637),ZOOM:i(10217)};t.exports=s},82085:t=>{t.exports="enterfullscreen"},11826:t=>{t.exports="fullscreenfailed"},56691:t=>{t.exports="fullscreenunsupported"},34739:t=>{t.exports="leavefullscreen"},26681:t=>{t.exports="orientationchange"},11428:t=>{t.exports="resize"},40444:(t,e,i)=>{t.exports={ENTER_FULLSCREEN:i(82085),FULLSCREEN_FAILED:i(11826),FULLSCREEN_UNSUPPORTED:i(56691),LEAVE_FULLSCREEN:i(34739),ORIENTATION_CHANGE:i(26681),RESIZE:i(11428)}},86754:(t,e,i)=>{var s=i(98611),n=i(55301),r={Center:i(35098),Events:i(40444),Orientation:i(53539),ScaleManager:i(756),ScaleModes:i(12637),Zoom:i(10217)};r=s(!1,r,n.CENTER),r=s(!1,r,n.ORIENTATION),r=s(!1,r,n.SCALE_MODE),r=s(!1,r,n.ZOOM),t.exports=r},47736:(t,e,i)=>{var s=i(72632),n=i(40587);t.exports=function(t){var e=t.game.config.defaultPhysicsSystem,i=s(t.settings,"physics",!1);if(e||i){var r=[];if(e&&r.push(n(e+"Physics")),i)for(var o in i)o=n(o.concat("Physics")),-1===r.indexOf(o)&&r.push(o);return r}}},91088:(t,e,i)=>{var s=i(72632);t.exports=function(t){var e=t.plugins.getDefaultScenePlugins(),i=s(t.settings,"plugins",!1);return Array.isArray(i)?i:e||[]}},90415:t=>{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"}},87157:(t,e,i)=>{var s=i(56694),n=i(63946),r=new s({initialize:function(t){this.sys=new n(this,t),this.game,this.anims,this.cache,this.registry,this.sound,this.textures,this.events,this.cameras,this.add,this.make,this.scene,this.children,this.lights,this.data,this.input,this.load,this.time,this.tweens,this.physics,this.matter,this.scale,this.plugins,this.renderer},update:function(){}});t.exports=r},13553:(t,e,i)=>{var s=i(56694),n=i(92980),r=i(7599),o=i(97081),a=i(10850),h=i(683),l=i(72283),u=i(87157),c=i(63946),d=new s({initialize:function(t,e){if(this.game=t,this.keys={},this.scenes=[],this._pending=[],this._start=[],this._queue=[],this._data={},this.isProcessing=!1,this.isBooted=!1,this.customViewports=0,this.systemScene,e){Array.isArray(e)||(e=[e]);for(var i=0;i-1&&(delete this.keys[s],this.scenes.splice(i,1),this._start.indexOf(s)>-1&&(i=this._start.indexOf(s),this._start.splice(i,1)),e.sys.destroy())}return this},bootScene:function(t){var e,i=t.sys,s=i.settings;i.sceneUpdate=l,t.init&&(t.init.call(t,s.data),s.status=n.INIT,s.isTransition&&i.events.emit(r.TRANSITION_INIT,s.transitionFrom,s.transitionDuration)),i.load&&(e=i.load).reset(),e&&t.preload?(t.preload.call(t),s.status=n.LOADING,e.once(h.COMPLETE,this.loadComplete,this),e.start()):this.create(t)},loadComplete:function(t){this.game.sound&&this.game.sound.onBlurPausedSounds&&this.game.sound.unlock(),this.create(t.scene)},payloadComplete:function(t){this.bootScene(t.scene)},update:function(t,e){this.processQueue(),this.isProcessing=!0;for(var i=this.scenes.length-1;i>=0;i--){var s=this.scenes[i].sys;s.settings.status>n.START&&s.settings.status<=n.RUNNING&&s.step(t,e),s.scenePlugin._target&&s.scenePlugin.step(t,e)}},render:function(t){for(var e=0;e=n.LOADING&&i.settings.status=n.START&&o<=n.CREATING)return this;if(o>=n.RUNNING&&o<=n.SLEEPING)r.shutdown(),r.sceneUpdate=l,r.start(e);else if(r.sceneUpdate=l,r.start(e),r.load&&(s=r.load),s&&r.settings.hasOwnProperty("pack")&&(s.reset(),s.addPack({payload:r.settings.pack})))return r.settings.status=n.LOADING,s.once(h.COMPLETE,this.payloadComplete,this),s.start(),this;return this.bootScene(i),this},stop:function(t,e){var i=this.getScene(t);if(i&&!i.sys.isTransitioning()&&i.sys.settings.status!==n.SHUTDOWN){var s=i.sys.load;s&&(s.off(h.COMPLETE,this.loadComplete,this),s.off(h.COMPLETE,this.payloadComplete,this)),i.sys.shutdown(e)}return this},switch:function(t,e){var i=this.getScene(t),s=this.getScene(e);return i&&s&&i!==s&&(this.sleep(t),this.isSleeping(e)?this.wake(e):this.start(e)),this},getAt:function(t){return this.scenes[t]},getIndex:function(t){var e=this.getScene(t);return this.scenes.indexOf(e)},bringToTop:function(t){if(this.isProcessing)this._queue.push({op:"bringToTop",keyA:t,keyB:null});else{var e=this.getIndex(t);if(-1!==e&&e0){var i=this.getScene(t);this.scenes.splice(e,1),this.scenes.unshift(i)}}return this},moveDown:function(t){if(this.isProcessing)this._queue.push({op:"moveDown",keyA:t,keyB:null});else{var e=this.getIndex(t);if(e>0){var i=e-1,s=this.getScene(t),n=this.getAt(i);this.scenes[e]=n,this.scenes[i]=s}}return this},moveUp:function(t){if(this.isProcessing)this._queue.push({op:"moveUp",keyA:t,keyB:null});else{var e=this.getIndex(t);if(ei),0,n)}}return this},moveBelow:function(t,e){if(t===e)return this;if(this.isProcessing)this._queue.push({op:"moveBelow",keyA:t,keyB:e});else{var i=this.getIndex(t),s=this.getIndex(e);if(-1!==i&&-1!==s&&s>i){var n=this.getAt(s);this.scenes.splice(s,1),0===i?this.scenes.unshift(n):this.scenes.splice(i-(s{var s=i(82897),n=i(56694),r=i(7599),o=i(72632),a=i(91963),h=new n({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(r.BOOT,this.boot,this),t.sys.events.on(r.START,this.pluginStart,this)},boot:function(){this.systems.events.once(r.DESTROY,this.destroy,this)},pluginStart:function(){this._target=null,this.systems.events.once(r.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=o(t,"target",!1),i=this.manager.getScene(e);if(!e||!this.checkValidTransition(i))return!1;var s=o(t,"duration",1e3);this._elapsed=0,this._target=i,this._duration=s,this._willSleep=o(t,"sleep",!1),this._willRemove=o(t,"remove",!1);var n=o(t,"onUpdate",null);n&&(this._onUpdate=n,this._onUpdateScope=o(t,"onUpdateScope",this.scene));var a=o(t,"allowInput",!1);this.settings.transitionAllowInput=a;var h=i.sys.settings;h.isTransition=!0,h.transitionFrom=this.scene,h.transitionDuration=s,h.transitionAllowInput=a,o(t,"moveAbove",!1)?this.manager.moveAbove(this.key,e):o(t,"moveBelow",!1)&&this.manager.moveBelow(this.key,e),i.sys.isSleeping()?i.sys.wake(o(t,"data")):this.manager.start(e,o(t,"data"));var l=o(t,"onStart",null),u=o(t,"onStartScope",this.scene);return l&&l.call(u,this.scene,i,s),this.systems.events.emit(r.TRANSITION_OUT,i,s),!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=s(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;t.events.emit(r.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,s){return this.manager.add(t,e,i,s)},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 s=this.manager.getScene(e);return s&&s.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)},getStatus:function(t){var e=this.manager.getScene(t);if(e)return e.sys.getStatus()},getIndex:function(t){return void 0===t&&(t=this.key),this.manager.getIndex(t)},shutdown:function(){var t=this.systems.events;t.off(r.SHUTDOWN,this.shutdown,this),t.off(r.TRANSITION_OUT)},destroy:function(){this.shutdown(),this.scene.sys.events.off(r.START,this.start,this),this.scene=null,this.systems=null,this.settings=null,this.manager=null}});a.register("ScenePlugin",h,"scenePlugin"),t.exports=h},36765:(t,e,i)=>{var s=i(92980),n=i(10850),r=i(30657),o=i(90415),a={create:function(t){return"string"==typeof t?t={key:t}:void 0===t&&(t={}),{status:s.PENDING,key:n(t,"key",""),active:n(t,"active",!1),visible:n(t,"visible",!0),isBooted:!1,isTransition:!1,transitionFrom:null,transitionDuration:0,transitionAllowInput:!0,data:{},pack:n(t,"pack",!1),cameras:n(t,"cameras",null),map:n(t,"map",r(o,n(t,"mapAdd",{}))),physics:n(t,"physics",{}),loader:n(t,"loader",{}),plugins:n(t,"plugins",!1),input:n(t,"input",{})}}};t.exports=a},63946:(t,e,i)=>{var s=i(56694),n=i(92980),r=i(18360),o=i(7599),a=i(47736),h=i(91088),l=i(72283),u=i(36765),c=new s({initialize:function(t,e){this.scene=t,this.game,this.renderer,this.config=e,this.settings=u.create(e),this.canvas,this.context,this.anims,this.cache,this.plugins,this.registry,this.scale,this.sound,this.textures,this.add,this.cameras,this.displayList,this.events,this.make,this.scenePlugin,this.updateList,this.sceneUpdate=l},init:function(t){this.settings.status=n.INIT,this.sceneUpdate=l,this.game=t,this.renderer=t.renderer,this.canvas=t.canvas,this.context=t.context;var e=t.plugins;this.plugins=e,e.addToScene(this,r.Global,[r.CoreScene,h(this),a(this)]),this.events.emit(o.BOOT,this),this.settings.isBooted=!0},step:function(t,e){var i=this.events;i.emit(o.PRE_UPDATE,t,e),i.emit(o.UPDATE,t,e),this.sceneUpdate.call(this.scene,t,e),i.emit(o.POST_UPDATE,t,e)},render:function(t){var e=this.displayList;e.depthSort(),this.events.emit(o.PRE_RENDER,t),this.cameras.render(t,e),this.events.emit(o.RENDER,t)},queueDepthSort:function(){this.displayList.queueDepthSort()},depthSort:function(){this.displayList.depthSort()},pause:function(t){var e=this.settings,i=this.getStatus();return i!==n.CREATING&&i!==n.RUNNING?console.warn("Cannot pause non-running Scene",e.key):this.settings.active&&(e.status=n.PAUSED,e.active=!1,this.events.emit(o.PAUSE,this,t)),this},resume:function(t){var e=this.events,i=this.settings;return this.settings.active||(i.status=n.RUNNING,i.active=!0,e.emit(o.RESUME,this,t)),this},sleep:function(t){var e=this.settings,i=this.getStatus();return i!==n.CREATING&&i!==n.RUNNING?console.warn("Cannot sleep non-running Scene",e.key):(e.status=n.SLEEPING,e.active=!1,e.visible=!1,this.events.emit(o.SLEEP,this,t)),this},wake:function(t){var e=this.events,i=this.settings;return i.status=n.RUNNING,i.active=!0,i.visible=!0,e.emit(o.WAKE,this,t),i.isTransition&&e.emit(o.TRANSITION_WAKE,i.transitionFrom,i.transitionDuration),this},getData:function(){return this.settings.data},getStatus:function(){return this.settings.status},canInput:function(){var t=this.settings.status;return t>n.PENDING&&t<=n.RUNNING},isSleeping:function(){return this.settings.status===n.SLEEPING},isActive:function(){return this.settings.status===n.RUNNING},isPaused:function(){return this.settings.status===n.PAUSED},isTransitioning:function(){return this.settings.isTransition||null!==this.scenePlugin._target},isTransitionOut:function(){return null!==this.scenePlugin._target&&this.scenePlugin._duration>0},isTransitionIn:function(){return this.settings.isTransition},isVisible:function(){return this.settings.visible},setVisible:function(t){return this.settings.visible=t,this},setActive:function(t,e){return t?this.resume(e):this.pause(e)},start:function(t){var e=this.events,i=this.settings;t&&(i.data=t),i.status=n.START,i.active=!0,i.visible=!0,e.emit(o.START,this),e.emit(o.READY,this,t)},shutdown:function(t){var e=this.events,i=this.settings;e.off(o.TRANSITION_INIT),e.off(o.TRANSITION_START),e.off(o.TRANSITION_COMPLETE),e.off(o.TRANSITION_OUT),i.status=n.SHUTDOWN,i.active=!1,i.visible=!1,e.emit(o.SHUTDOWN,this,t)},destroy:function(){var t=this.events,e=this.settings;e.status=n.DESTROYED,e.active=!1,e.visible=!1,t.emit(o.DESTROY,this),t.removeAllListeners();for(var i=["scene","game","anims","cache","plugins","registry","sound","textures","add","camera","displayList","events","make","scenePlugin","updateList"],s=0;s{t.exports={PENDING:0,INIT:1,START:2,LOADING:3,CREATING:4,RUNNING:5,PAUSED:6,SLEEPING:7,SHUTDOWN:8,DESTROYED:9}},31803:t=>{t.exports="addedtoscene"},94817:t=>{t.exports="boot"},28977:t=>{t.exports="create"},91959:t=>{t.exports="destroy"},363:t=>{t.exports="pause"},15643:t=>{t.exports="postupdate"},17058:t=>{t.exports="prerender"},77125:t=>{t.exports="preupdate"},76018:t=>{t.exports="ready"},28620:t=>{t.exports="removedfromscene"},41538:t=>{t.exports="render"},34268:t=>{t.exports="resume"},2342:t=>{t.exports="shutdown"},96541:t=>{t.exports="sleep"},74244:t=>{t.exports="start"},17046:t=>{t.exports="transitioncomplete"},13637:t=>{t.exports="transitioninit"},14733:t=>{t.exports="transitionout"},33899:t=>{t.exports="transitionstart"},52418:t=>{t.exports="transitionwake"},31735:t=>{t.exports="update"},8470:t=>{t.exports="wake"},7599:(t,e,i)=>{t.exports={ADDED_TO_SCENE:i(31803),BOOT:i(94817),CREATE:i(28977),DESTROY:i(91959),PAUSE:i(363),POST_UPDATE:i(15643),PRE_RENDER:i(17058),PRE_UPDATE:i(77125),READY:i(76018),REMOVED_FROM_SCENE:i(28620),RENDER:i(41538),RESUME:i(34268),SHUTDOWN:i(2342),SLEEP:i(96541),START:i(74244),TRANSITION_COMPLETE:i(17046),TRANSITION_INIT:i(13637),TRANSITION_OUT:i(14733),TRANSITION_START:i(33899),TRANSITION_WAKE:i(52418),UPDATE:i(31735),WAKE:i(8470)}},20436:(t,e,i)=>{var s=i(92980),n=i(98611),r={Events:i(7599),GetPhysicsPlugins:i(47736),GetScenePlugins:i(91088),SceneManager:i(13553),ScenePlugin:i(64051),Settings:i(36765),Systems:i(63946)};r=n(!1,r,s),t.exports=r},25798:(t,e,i)=>{var s=i(56694),n=i(6659),r=i(76038),o=i(98611),a=i(72283),h=new s({Extends:n,initialize:function(t,e,i){n.call(this),this.manager=t,this.key=e,this.isPlaying=!1,this.isPaused=!1,this.totalRate=1,this.duration=this.duration||0,this.totalDuration=this.totalDuration||0,this.config={mute:!1,volume:1,rate:1,detune:0,seek:0,loop:!1,delay:0,pan:0},this.currentConfig=this.config,this.config=o(this.config,i),this.markers={},this.currentMarker=null,this.pendingRemove=!1},addMarker:function(t){return!(!t||!t.name||"string"!=typeof t.name)&&(this.markers[t.name]?(console.error("addMarker "+t.name+" already exists in Sound"),!1):(t=o(!0,{name:"",start:0,duration:this.totalDuration-(t.start||0),config:{mute:!1,volume:1,rate:1,detune:0,seek:0,loop:!1,delay:0,pan:0}},t),this.markers[t.name]=t,!0))},updateMarker:function(t){return!(!t||!t.name||"string"!=typeof t.name)&&(this.markers[t.name]?(this.markers[t.name]=o(!0,this.markers[t.name],t),!0):(console.warn("Audio Marker: "+t.name+" missing in Sound: "+this.key),!1))},removeMarker:function(t){var e=this.markers[t];return e?(this.markers[t]=null,e):null},play:function(t,e){if(void 0===t&&(t=""),"object"==typeof t&&(e=t,t=""),"string"!=typeof t)return!1;if(t){if(!this.markers[t])return console.warn("Marker: "+t+" missing in Sound: "+this.key),!1;this.currentMarker=this.markers[t],this.currentConfig=this.currentMarker.config,this.duration=this.currentMarker.duration}else this.currentMarker=null,this.currentConfig=this.config,this.duration=this.totalDuration;return this.resetConfig(),this.currentConfig=o(this.currentConfig,e),this.isPlaying=!0,this.isPaused=!1,!0},pause:function(){return!(this.isPaused||!this.isPlaying)&&(this.isPlaying=!1,this.isPaused=!0,!0)},resume:function(){return!(!this.isPaused||this.isPlaying)&&(this.isPlaying=!0,this.isPaused=!1,!0)},stop:function(){return!(!this.isPaused&&!this.isPlaying)&&(this.isPlaying=!1,this.isPaused=!1,this.resetConfig(),!0)},applyConfig:function(){this.mute=this.currentConfig.mute,this.volume=this.currentConfig.volume,this.rate=this.currentConfig.rate,this.detune=this.currentConfig.detune,this.loop=this.currentConfig.loop,this.pan=this.currentConfig.pan},resetConfig:function(){this.currentConfig.seek=0,this.currentConfig.delay=0},update:a,calculateRate:function(){var t=this.currentConfig.detune+this.manager.detune,e=Math.pow(1.0005777895065548,t);this.totalRate=this.currentConfig.rate*this.manager.rate*e},destroy:function(){this.pendingRemove||(this.emit(r.DESTROY,this),this.removeAllListeners(),this.pendingRemove=!0,this.manager=null,this.config=null,this.currentConfig=null,this.markers=null,this.currentMarker=null)}});t.exports=h},12486:(t,e,i)=>{var s=i(56694),n=i(32742),r=i(6659),o=i(76038),a=i(97081),h=i(71608),l=i(51463),u=i(72283),c=i(93736),d=new s({Extends:r,initialize:function(t){r.call(this),this.game=t,this.jsonCache=t.cache.json,this.sounds=[],this.mute=!1,this.volume=1,this.pauseOnBlur=!0,this._rate=1,this._detune=0,this.locked=this.locked||!1,this.unlocked=!1,this.gameLostFocus=!1,this.listenerPosition=new c,t.events.on(a.BLUR,this.onGameBlur,this),t.events.on(a.FOCUS,this.onGameFocus,this),t.events.on(a.PRE_STEP,this.update,this),t.events.once(a.DESTROY,this.destroy,this)},add:u,addAudioSprite:function(t,e){void 0===e&&(e={});var i=this.add(t,e);for(var s in i.spritemap=this.jsonCache.get(t).spritemap,i.spritemap)if(i.spritemap.hasOwnProperty(s)){var r=n(e),o=i.spritemap[s];r.loop=!!o.hasOwnProperty("loop")&&o.loop,i.addMarker({name:s,start:o.start,duration:o.end-o.start,config:r})}return i},get:function(t){return l(this.sounds,"key",t)},getAll:function(t){return t?h(this.sounds,"key",t):h(this.sounds)},getAllPlaying:function(){return h(this.sounds,"isPlaying",!0)},play:function(t,e){var i=this.add(t);return i.once(o.COMPLETE,i.destroy,i),e?e.name?(i.addMarker(e),i.play(e.name)):i.play(e):i.play()},playAudioSprite:function(t,e,i){var s=this.addAudioSprite(t);return s.once(o.COMPLETE,s.destroy,s),s.play(e,i)},remove:function(t){var e=this.sounds.indexOf(t);return-1!==e&&(t.destroy(),this.sounds.splice(e,1),!0)},removeAll:function(){this.sounds.forEach((function(t){t.destroy()})),this.sounds.length=0},removeByKey:function(t){for(var e=0,i=this.sounds.length-1;i>=0;i--){var s=this.sounds[i];s.key===t&&(s.destroy(),this.sounds.splice(i,1),e++)}return e},pauseAll:function(){this.forEachActiveSound((function(t){t.pause()})),this.emit(o.PAUSE_ALL,this)},resumeAll:function(){this.forEachActiveSound((function(t){t.resume()})),this.emit(o.RESUME_ALL,this)},setListenerPosition:u,stopAll:function(){this.forEachActiveSound((function(t){t.stop()})),this.emit(o.STOP_ALL,this)},stopByKey:function(t){var e=0;return this.getAll(t).forEach((function(t){t.stop()&&e++})),e},unlock:u,onBlur:u,onFocus:u,onGameBlur:function(){this.gameLostFocus=!0,this.pauseOnBlur&&this.onBlur()},onGameFocus:function(){this.gameLostFocus=!1,this.pauseOnBlur&&this.onFocus()},update:function(t,e){this.unlocked&&(this.unlocked=!1,this.locked=!1,this.emit(o.UNLOCKED,this));for(var i=this.sounds.length-1;i>=0;i--)this.sounds[i].pendingRemove&&this.sounds.splice(i,1);this.sounds.forEach((function(i){i.update(t,e)}))},destroy:function(){this.game.events.off(a.BLUR,this.onGameBlur,this),this.game.events.off(a.FOCUS,this.onGameFocus,this),this.game.events.off(a.PRE_STEP,this.update,this),this.removeAllListeners(),this.removeAll(),this.sounds.length=0,this.sounds=null,this.listenerPosition=null,this.game=null},forEachActiveSound:function(t,e){var i=this;this.sounds.forEach((function(s,n){s&&!s.pendingRemove&&t.call(e||i,s,n,i.sounds)}))},setRate:function(t){return this.rate=t,this},rate:{get:function(){return this._rate},set:function(t){this._rate=t,this.forEachActiveSound((function(t){t.calculateRate()})),this.emit(o.GLOBAL_RATE,this,t)}},setDetune:function(t){return this.detune=t,this},detune:{get:function(){return this._detune},set:function(t){this._detune=t,this.forEachActiveSound((function(t){t.calculateRate()})),this.emit(o.GLOBAL_DETUNE,this,t)}}});t.exports=d},84191:(t,e,i)=>{var s=i(27622),n=i(17546),r=i(55491),o={create:function(t){var e=t.config.audio,i=t.device.audio;return e.noAudio||!i.webAudio&&!i.audioData?new n(t):i.webAudio&&!e.disableWebAudio?new r(t):new s(t)}};t.exports=o},77578:t=>{t.exports="complete"},19679:t=>{t.exports="decodedall"},56951:t=>{t.exports="decoded"},16436:t=>{t.exports="destroy"},55154:t=>{t.exports="detune"},57818:t=>{t.exports="detune"},57890:t=>{t.exports="mute"},83022:t=>{t.exports="rate"},99170:t=>{t.exports="volume"},64289:t=>{t.exports="looped"},67214:t=>{t.exports="loop"},53128:t=>{t.exports="mute"},73078:t=>{t.exports="pan"},76763:t=>{t.exports="pauseall"},88426:t=>{t.exports="pause"},13765:t=>{t.exports="play"},80291:t=>{t.exports="rate"},11124:t=>{t.exports="resumeall"},55382:t=>{t.exports="resume"},71157:t=>{t.exports="seek"},31776:t=>{t.exports="stopall"},39450:t=>{t.exports="stop"},21939:t=>{t.exports="unlocked"},33019:t=>{t.exports="volume"},76038:(t,e,i)=>{t.exports={COMPLETE:i(77578),DECODED:i(56951),DECODED_ALL:i(19679),DESTROY:i(16436),DETUNE:i(55154),GLOBAL_DETUNE:i(57818),GLOBAL_MUTE:i(57890),GLOBAL_RATE:i(83022),GLOBAL_VOLUME:i(99170),LOOP:i(67214),LOOPED:i(64289),MUTE:i(53128),PAN:i(73078),PAUSE_ALL:i(76763),PAUSE:i(88426),PLAY:i(13765),RATE:i(80291),RESUME_ALL:i(11124),RESUME:i(55382),SEEK:i(71157),STOP_ALL:i(31776),STOP:i(39450),UNLOCKED:i(21939),VOLUME:i(33019)}},34350:(t,e,i)=>{var s=i(25798),n=i(56694),r=i(76038),o=i(82897),a=new n({Extends:s,initialize:function(t,e,i){if(void 0===i&&(i={}),this.tags=t.game.cache.audio.get(e),!this.tags)throw new Error('No cached audio asset with key "'+e);this.audio=null,this.startTime=0,this.previousTime=0,this.duration=this.tags[0].duration,this.totalDuration=this.tags[0].duration,s.call(this,t,e,i)},play:function(t,e){return!this.manager.isLocked(this,"play",[t,e])&&(!!s.prototype.play.call(this,t,e)&&(!!this.pickAndPlayAudioTag()&&(this.emit(r.PLAY,this),!0)))},pause:function(){return!this.manager.isLocked(this,"pause")&&(!(this.startTime>0)&&(!!s.prototype.pause.call(this)&&(this.currentConfig.seek=this.audio.currentTime-(this.currentMarker?this.currentMarker.start:0),this.stopAndReleaseAudioTag(),this.emit(r.PAUSE,this),!0)))},resume:function(){return!this.manager.isLocked(this,"resume")&&(!(this.startTime>0)&&(!!s.prototype.resume.call(this)&&(!!this.pickAndPlayAudioTag()&&(this.emit(r.RESUME,this),!0))))},stop:function(){return!this.manager.isLocked(this,"stop")&&(!!s.prototype.stop.call(this)&&(this.stopAndReleaseAudioTag(),this.emit(r.STOP,this),!0))},pickAndPlayAudioTag:function(){if(!this.pickAudioTag())return this.reset(),!1;var t=this.currentConfig.seek,e=this.currentConfig.delay,i=(this.currentMarker?this.currentMarker.start:0)+t;return this.previousTime=i,this.audio.currentTime=i,this.applyConfig(),0===e?(this.startTime=0,this.audio.paused&&this.playCatchPromise()):(this.startTime=window.performance.now()+1e3*e,this.audio.paused||this.audio.pause()),this.resetConfig(),!0},pickAudioTag:function(){if(this.audio)return!0;for(var t=0;t0)this.startTime=i-this.manager.loopEndOffset?(this.audio.currentTime=e+Math.max(0,s-i),s=this.audio.currentTime):s=i)return this.reset(),this.stopAndReleaseAudioTag(),void this.emit(r.COMPLETE,this);this.previousTime=s}},destroy:function(){s.prototype.destroy.call(this),this.tags=null,this.audio&&this.stopAndReleaseAudioTag()},updateMute:function(){this.audio&&(this.audio.muted=this.currentConfig.mute||this.manager.mute)},updateVolume:function(){this.audio&&(this.audio.volume=o(this.currentConfig.volume*this.manager.volume,0,1))},calculateRate:function(){s.prototype.calculateRate.call(this),this.audio&&(this.audio.playbackRate=this.totalRate)},mute:{get:function(){return this.currentConfig.mute},set:function(t){this.currentConfig.mute=t,this.manager.isLocked(this,"mute",t)||(this.updateMute(),this.emit(r.MUTE,this,t))}},setMute:function(t){return this.mute=t,this},volume:{get:function(){return this.currentConfig.volume},set:function(t){this.currentConfig.volume=t,this.manager.isLocked(this,"volume",t)||(this.updateVolume(),this.emit(r.VOLUME,this,t))}},setVolume:function(t){return this.volume=t,this},rate:{get:function(){return this.currentConfig.rate},set:function(t){this.currentConfig.rate=t,this.manager.isLocked(this,r.RATE,t)||(this.calculateRate(),this.emit(r.RATE,this,t))}},setRate:function(t){return this.rate=t,this},detune:{get:function(){return this.currentConfig.detune},set:function(t){this.currentConfig.detune=t,this.manager.isLocked(this,r.DETUNE,t)||(this.calculateRate(),this.emit(r.DETUNE,this,t))}},setDetune:function(t){return this.detune=t,this},seek:{get:function(){return this.isPlaying?this.audio.currentTime-(this.currentMarker?this.currentMarker.start:0):this.isPaused?this.currentConfig.seek:0},set:function(t){this.manager.isLocked(this,"seek",t)||this.startTime>0||(this.isPlaying||this.isPaused)&&(t=Math.min(Math.max(0,t),this.duration),this.isPlaying?(this.previousTime=t,this.audio.currentTime=t):this.isPaused&&(this.currentConfig.seek=t),this.emit(r.SEEK,this,t))}},setSeek:function(t){return this.seek=t,this},loop:{get:function(){return this.currentConfig.loop},set:function(t){this.currentConfig.loop=t,this.manager.isLocked(this,"loop",t)||(this.audio&&(this.audio.loop=t),this.emit(r.LOOP,this,t))}},setLoop:function(t){return this.loop=t,this},pan:{get:function(){return this.currentConfig.pan},set:function(t){this.currentConfig.pan=t,this.emit(r.PAN,this,t)}},setPan:function(t){return this.pan=t,this}});t.exports=a},27622:(t,e,i)=>{var s=i(12486),n=i(56694),r=i(76038),o=i(34350),a=new n({Extends:s,initialize:function(t){this.override=!0,this.audioPlayDelay=.1,this.loopEndOffset=.05,this.onBlurPausedSounds=[],this.locked="ontouchstart"in window,this.lockedActionsQueue=this.locked?[]:null,this._mute=!1,this._volume=1,s.call(this,t)},add:function(t,e){var i=new o(this,t,e);return this.sounds.push(i),i},unlock:function(){this.locked=!1;var t=this;if(this.game.cache.audio.entries.each((function(e,i){for(var s=0;s{t.exports={SoundManagerCreator:i(84191),Events:i(76038),BaseSound:i(25798),BaseSoundManager:i(12486),WebAudioSound:i(96008),WebAudioSoundManager:i(55491),HTML5AudioSound:i(34350),HTML5AudioSoundManager:i(27622),NoAudioSound:i(38662),NoAudioSoundManager:i(17546)}},38662:(t,e,i)=>{var s=i(25798),n=i(56694),r=i(6659),o=i(98611),a=i(72283),h=function(){return!1},l=function(){return null},u=function(){return this},c=new n({Extends:r,initialize:function(t,e,i){void 0===i&&(i={}),r.call(this),this.manager=t,this.key=e,this.isPlaying=!1,this.isPaused=!1,this.totalRate=1,this.duration=0,this.totalDuration=0,this.config=o({mute:!1,volume:1,rate:1,detune:0,seek:0,loop:!1,delay:0,pan:0},i),this.currentConfig=this.config,this.mute=!1,this.volume=1,this.rate=1,this.detune=0,this.seek=0,this.loop=!1,this.pan=0,this.markers={},this.currentMarker=null,this.pendingRemove=!1},addMarker:h,updateMarker:h,removeMarker:l,play:h,pause:h,resume:h,stop:h,setMute:u,setVolume:u,setRate:u,setDetune:u,setSeek:u,setLoop:u,setPan:u,applyConfig:l,resetConfig:l,update:a,calculateRate:l,destroy:function(){s.prototype.destroy.call(this)}});t.exports=c},17546:(t,e,i)=>{var s=i(12486),n=i(56694),r=i(6659),o=i(38662),a=i(72283),h=new n({Extends:r,initialize:function(t){r.call(this),this.game=t,this.sounds=[],this.mute=!1,this.volume=1,this.rate=1,this.detune=0,this.pauseOnBlur=!0,this.locked=!1},add:function(t,e){var i=new o(this,t,e);return this.sounds.push(i),i},addAudioSprite:function(t,e){var i=this.add(t,e);return i.spritemap={},i},get:function(t){return s.prototype.get.call(this,t)},getAll:function(t){return s.prototype.getAll.call(this,t)},play:function(t,e){return!1},playAudioSprite:function(t,e,i){return!1},remove:function(t){return s.prototype.remove.call(this,t)},removeAll:function(){return s.prototype.removeAll.call(this)},removeByKey:function(t){return s.prototype.removeByKey.call(this,t)},stopByKey:function(t){return s.prototype.stopByKey.call(this,t)},onBlur:a,onFocus:a,onGameBlur:a,onGameFocus:a,pauseAll:a,resumeAll:a,stopAll:a,update:a,setRate:a,setDetune:a,setMute:a,setVolume:a,unlock:a,forEachActiveSound:function(t,e){s.prototype.forEachActiveSound.call(this,t,e)},destroy:function(){s.prototype.destroy.call(this)}});t.exports=h},96008:(t,e,i)=>{var s=i(25798),n=i(56694),r=i(76038),o=i(72632),a=new n({Extends:s,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.spatialNode=null,this.spatialSource=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.createPanner&&(this.spatialNode=t.context.createPanner(),this.volumeNode.connect(this.spatialNode)),t.context.createStereoPanner?(this.pannerNode=t.context.createStereoPanner(),t.context.createPanner?this.spatialNode.connect(this.pannerNode):this.volumeNode.connect(this.pannerNode),this.pannerNode.connect(t.destination)):t.context.createPanner?this.spatialNode.connect(t.destination):this.volumeNode.connect(t.destination),this.duration=this.audioBuffer.duration,this.totalDuration=this.audioBuffer.duration,s.call(this,t,e,i)},play:function(t,e){return!!s.prototype.play.call(this,t,e)&&(this.stopAndRemoveBufferSource(),this.createAndStartBufferSource(),this.emit(r.PLAY,this),!0)},pause:function(){return!(this.manager.context.currentTime{var s=i(82329),n=i(12486),r=i(56694),o=i(76038),a=i(97081),h=i(96008),l=i(72632),u=new r({Extends:n,initialize:function(t){this.context=this.createAudioContext(t),this.masterMuteNode=this.context.createGain(),this.masterVolumeNode=this.context.createGain(),this.masterMuteNode.connect(this.masterVolumeNode),this.masterVolumeNode.connect(this.context.destination),this.destination=this.masterMuteNode,this.locked="suspended"===this.context.state&&("ontouchstart"in window||"onclick"in window),n.call(this,t),this.locked&&t.isBooted?this.unlock():t.events.once(a.BOOT,this.unlock,this)},createAudioContext:function(t){var e=t.config.audio;return e.context?(e.context.resume(),e.context):window.hasOwnProperty("AudioContext")?new AudioContext:window.hasOwnProperty("webkitAudioContext")?new window.webkitAudioContext:void 0},setAudioContext:function(t){return this.context&&this.context.close(),this.masterMuteNode&&this.masterMuteNode.disconnect(),this.masterVolumeNode&&this.masterVolumeNode.disconnect(),this.context=t,this.masterMuteNode=t.createGain(),this.masterVolumeNode=t.createGain(),this.masterMuteNode.connect(this.masterVolumeNode),this.masterVolumeNode.connect(t.destination),this.destination=this.masterMuteNode,this},add:function(t,e){var i=new h(this,t,e);return this.sounds.push(i),i},decodeAudio:function(t,e){var i;i=Array.isArray(t)?t:[{key:t,data:e}];for(var n=this.game.cache.audio,r=i.length,a=0;a{var s=i(59959),n=i(56694),r=i(72283),o=i(17922),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(t,e){return t?(void 0===e&&(e=function(e,i){return e[t]-i[t]}),o(this.list,e),this):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)},moveAbove:function(t,e){return s.MoveAbove(this.list,t,e)},moveBelow:function(t,e){return s.MoveBelow(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 this.list.indexOf(t)>-1},setAll:function(t,e,i,n){return s.SetAll(this.list,t,e,i,n),this},each:function(t,e){for(var i=[null],s=2;s0?this.list[0]:null}},last:{get:function(){return this.list.length>0?(this.position=this.list.length-1,this.list[this.position]):null}},next:{get:function(){return this.position0?(this.position--,this.list[this.position]):null}}});t.exports=a},33885:(t,e,i)=>{var s=new(i(56694))({initialize:function(t){if(this.entries={},this.size=0,Array.isArray(t))for(var e=0;e{var s=i(56694),n=i(6659),r=i(36716),o=new s({Extends:n,initialize:function(){n.call(this),this._pending=[],this._active=[],this._destroy=[],this._toProcess=0,this.checkQueue=!1},isActive:function(t){return this._active.indexOf(t)>-1},isPending:function(t){return this._toProcess>0&&this._pending.indexOf(t)>-1},isDestroying:function(t){return this._destroy.indexOf(t)>-1},add:function(t){return this.checkQueue&&this.isActive()&&!this.isDestroying()||this.isPending()||(this._pending.push(t),this._toProcess++),t},remove:function(t){if(this.isPending(t)){var e=this._pending,i=e.indexOf(t);-1!==i&&e.splice(i,1)}else this.isActive(t)&&(this._destroy.push(t),this._toProcess++);return t},removeAll:function(){for(var t=this._active,e=this._destroy,i=t.length;i--;)e.push(t[i]),this._toProcess++;return this},update:function(){if(0===this._toProcess)return this._active;var t,e,i=this._destroy,s=this._active;for(t=0;t{var s=i(53466);function n(t){if(!(this instanceof n))return new n(t,[".left",".top",".right",".bottom"]);this._maxEntries=Math.max(4,t||9),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()}function r(t,e,i){if(!i)return e.indexOf(t);for(var s=0;s=t.minX&&e.maxY>=t.minY}function v(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,r){for(var o,a=[e,i];a.length;)(i=a.pop())-(e=a.pop())<=n||(o=e+Math.ceil((i-e)/n/2)*n,s(t,o,e,i,r),a.push(e,o,o,i))}n.prototype={all:function(){return this._all(this.data,[])},search:function(t){var e=this.data,i=[],s=this.toBBox;if(!p(t,e))return i;for(var n,r,o,a,h=[];e;){for(n=0,r=e.children.length;n=0&&r[e].children.length>this._maxEntries;)this._split(r,e),e--;this._adjustParentBBoxes(n,r,e)},_split:function(t,e){var i=t[e],s=i.children.length,n=this._minEntries;this._chooseSplitAxis(i,n,s);var r=this._chooseSplitIndex(i,n,s),a=v(i.children.splice(r,i.children.length-r));a.height=i.height,a.leaf=i.leaf,o(i,this.toBBox),o(a,this.toBBox),e?t[e-1].children.push(a):this._splitRoot(i,a)},_splitRoot:function(t,e){this.data=v([t,e]),this.data.height=t.height+1,this.data.leaf=!1,o(this.data,this.toBBox)},_chooseSplitIndex:function(t,e,i){var s,n,r,o,h,l,u,d,f,p,v,g,m,y;for(l=u=1/0,s=e;s<=i-e;s++)n=a(t,0,s,this.toBBox),r=a(t,s,i,this.toBBox),f=n,p=r,v=void 0,g=void 0,m=void 0,y=void 0,v=Math.max(f.minX,p.minX),g=Math.max(f.minY,p.minY),m=Math.min(f.maxX,p.maxX),y=Math.min(f.maxY,p.maxY),o=Math.max(0,m-v)*Math.max(0,y-g),h=c(n)+c(r),o=e;n--)r=t.children[n],h(u,t.leaf?o(r):r),c+=d(u);return c},_adjustParentBBoxes:function(t,e,i){for(var s=i;s>=0;s--)h(e[s],t)},_condense:function(t){for(var e,i=t.length-1;i>=0;i--)0===t[i].children.length?i>0?(e=t[i-1].children).splice(e.indexOf(t[i]),1):this.clear():o(t[i],this.toBBox)},compareMinX:function(t,e){return t.left-e.left},compareMinY:function(t,e){return t.top-e.top},toBBox:function(t){return{minX:t.left,minY:t.top,maxX:t.right,maxY:t.bottom}}},t.exports=n},58403:(t,e,i)=>{var s=new(i(56694))({initialize:function(t){if(this.entries=[],Array.isArray(t))for(var e=0;e-1&&this.entries.splice(e,1),this},dump:function(){console.group("Set");for(var t=0;t-1},union:function(t){var e=new s;return t.entries.forEach((function(t){e.set(t)})),this.entries.forEach((function(t){e.set(t)})),e},intersect:function(t){var e=new s;return this.entries.forEach((function(i){t.contains(i)&&e.set(i)})),e},difference:function(t){var e=new s;return this.entries.forEach((function(i){t.contains(i)||e.set(i)})),e},size:{get:function(){return this.entries.length},set:function(t){return t{var s=i(82897),n=i(56694),r=i(84314),o=i(93736),a=new n({initialize:function(t,e,i,s){void 0===t&&(t=0),void 0===e&&(e=t),void 0===i&&(i=0),void 0===s&&(s=null),this._width=t,this._height=e,this._parent=s,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=s(t,0,this.maxWidth),this.minHeight=s(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=s(t,this.minWidth,Number.MAX_VALUE),this.maxHeight=s(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=s(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=s(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 s=this.snapTo,n=0===e?1:t/e;return i&&this.aspectRatio>n||!i&&this.aspectRatio0&&(t=(e=r(e,s.y))*this.aspectRatio)):(i&&this.aspectRation)&&(t=(e=r(e,s.y))*this.aspectRatio,s.x>0&&(e=(t=r(t,s.x))*(1/this.aspectRatio))),this._width=t,this._height=e,this},fitTo:function(t,e){return this.constrain(t,e,!0)},envelop:function(t,e){return this.constrain(t,e,!1)},setWidth:function(t){return this.setSize(t,this._height)},setHeight:function(t){return this.setSize(this._width,t)},toString:function(){return"[{ Size (width="+this._width+" height="+this._height+" aspectRatio="+this.aspectRatio+" aspectMode="+this.aspectMode+") }]"},setCSS:function(t){t&&t.style&&(t.style.width=this._width+"px",t.style.height=this._height+"px")},copy:function(t){return t.setAspectMode(this.aspectMode),t.aspectRatio=this.aspectRatio,t.setSize(this.width,this.height)},destroy:function(){this._parent=null,this.snapTo=null},width:{get:function(){return this._width},set:function(t){this.setSize(t,this._height)}},height:{get:function(){return this._height},set:function(t){this.setSize(this._width,t)}}});a.NONE=0,a.WIDTH_CONTROLS_HEIGHT=1,a.HEIGHT_CONTROLS_WIDTH=2,a.FIT=3,a.ENVELOP=4,t.exports=a},94160:t=>{t.exports="add"},95393:t=>{t.exports="remove"},36716:(t,e,i)=>{t.exports={PROCESS_QUEUE_ADD:i(94160),PROCESS_QUEUE_REMOVE:i(95393)}},20010:(t,e,i)=>{t.exports={Events:i(36716),List:i(71207),Map:i(33885),ProcessQueue:i(74623),RTree:i(68687),Set:i(58403),Size:i(90881)}},17487:(t,e,i)=>{var s=i(56694),n=i(82897),r=i(27119),o=i(86459),a=i(28621),h=i(31673),l=new s({Extends:h,initialize:function(t,e,i,s,n){h.call(this,t,e,i,s,n),this.add("__BASE",0,0,0,s,n),this._source=this.frames.__BASE.source,this.canvas=this._source.image,this.context=this.canvas.getContext("2d",{willReadFrequently:!0}),this.width=s,this.height=n,this.imageData=this.context.getImageData(0,0,s,n),this.data=null,this.imageData&&(this.data=this.imageData.data),this.pixels=null,this.buffer,this.data&&(this.imageData.data.buffer?(this.buffer=this.imageData.data.buffer,this.pixels=new Uint32Array(this.buffer)):window.ArrayBuffer?(this.buffer=new ArrayBuffer(this.imageData.data.length),this.pixels=new Uint32Array(this.buffer)):this.pixels=this.imageData.data)},update:function(){return this.imageData=this.context.getImageData(0,0,this.width,this.height),this.data=this.imageData.data,this.imageData.data.buffer?(this.buffer=this.imageData.data.buffer,this.pixels=new Uint32Array(this.buffer)):window.ArrayBuffer?(this.buffer=new ArrayBuffer(this.imageData.data.length),this.pixels=new Uint32Array(this.buffer)):this.pixels=this.imageData.data,this.manager.game.config.renderType===o.WEBGL&&this.refresh(),this},draw:function(t,e,i,s){return void 0===s&&(s=!0),this.context.drawImage(i,t,e),s&&this.update(),this},drawFrame:function(t,e,i,s,n){void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=!0);var r=this.manager.getFrame(t,e);if(r){var o=r.canvasData,a=r.cutWidth,h=r.cutHeight,l=r.source.resolution;this.context.drawImage(r.source.image,o.x,o.y,a,h,i,s,a/l,h/l),n&&this.update()}return this},setPixel:function(t,e,i,s,n,r){if(void 0===r&&(r=255),t=Math.abs(Math.floor(t)),e=Math.abs(Math.floor(e)),this.getIndex(t,e)>-1){var o=this.context.getImageData(t,e,1,1);o.data[0]=i,o.data[1]=s,o.data[2]=n,o.data[3]=r,this.context.putImageData(o,t,e)}return this},putData:function(t,e,i,s,n,r,o){return void 0===s&&(s=0),void 0===n&&(n=0),void 0===r&&(r=t.width),void 0===o&&(o=t.height),this.context.putImageData(t,e,i,s,n,r,o),this},getData:function(t,e,i,s){return t=n(Math.floor(t),0,this.width-1),e=n(Math.floor(e),0,this.height-1),i=n(i,1,this.width-t),s=n(s,1,this.height-e),this.context.getImageData(t,e,i,s)},getPixel:function(t,e,i){i||(i=new r);var s=this.getIndex(t,e);if(s>-1){var n=this.data,o=n[s+0],a=n[s+1],h=n[s+2],l=n[s+3];i.setTo(o,a,h,l)}return i},getPixels:function(t,e,i,s){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=this.width),void 0===s&&(s=i),t=Math.abs(Math.round(t)),e=Math.abs(Math.round(e));for(var o=n(t,0,this.width),a=n(t+i,0,this.width),h=n(e,0,this.height),l=n(e+s,0,this.height),u=new r,c=[],d=h;d{var s=i(95723),n=i(51052),r=i(61068),o=i(56694),a=i(86459),h=i(82047),l=i(72632),u=i(65641),c=i(37410),d=i(31673),f=i(75512),p=new o({Extends:d,initialize:function(t,e,i,s){void 0===i&&(i=256),void 0===s&&(s=256),this.type="DynamicTexture";var o=t.game.renderer,h=o&&o.type===a.CANVAS,l=h?r.create2D(this,i,s):[this];d.call(this,t,e,l,i,s),this.add("__BASE",0,0,0,i,s),this.renderer=o,this.isDrawing=!1,this.canvas=h?l:null,this.context=h?l.getContext("2d",{willReadFrequently:!0}):null,this.dirty=!1,this.isSpriteTexture=!0,this._eraseMode=!1,this.camera=new n(0,0,i,s).setScene(t.game.scene.systemScene,!1),this.renderTarget=h?null:new c(o,i,s,1,0,!1,!0,!0,!1),this.pipeline=h?null:o.pipelines.get(u.SINGLE_PIPELINE),this.setSize(i,s)},setSize:function(t,e){void 0===e&&(e=t);var i=this.get(),s=i.source;if(t!==this.width||e!==this.height){this.canvas&&(this.canvas.width=t,this.canvas.height=e);var n=this.renderTarget;n&&(n.resize(t,e),i.glTexture=n.texture,s.isRenderTexture=!0,s.isGLTexture=!0,s.glTexture=n.texture,s.glTexture.flipY=!0),this.camera.setSize(t,e),s.width=t,s.height=e,i.setSize(t,e),this.width=t,this.height=e}else{var r=this.getSourceImage();i.cutX+t>r.width&&(t=r.width-i.cutX),i.cutY+e>r.height&&(e=r.height-i.cutY),i.setSize(t,e,i.cutX,i.cutY)}return this},setIsSpriteTexture:function(t){return this.isSpriteTexture=t,this},fill:function(t,e,i,s,n,r){var o=this.camera,a=this.renderer;void 0===e&&(e=1),void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=this.width),void 0===r&&(r=this.height);var h=t>>16&255,l=t>>8&255,u=255&t,c=this.renderTarget;if(o.preRender(),c){c.bind(!0);var d=this.pipeline.manager.set(this.pipeline),p=a.width/c.width,v=a.height/c.height;d.drawFillRect(i*p,s*v,n*p,r*v,f.getTintFromFloats(u/255,l/255,h/255,1),e),c.unbind(!0)}else{var g=this.context;a.setContext(g),g.globalCompositeOperation="source-over",g.fillStyle="rgba("+h+","+l+","+u+","+e+")",g.fillRect(i,s,n,r),a.setContext()}return this.dirty=!0,this},clear:function(){if(this.dirty){var t=this.context,e=this.renderTarget;e?e.clear():t&&(t.save(),t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,this.width,this.height),t.restore()),this.dirty=!1}return this},stamp:function(t,e,i,s,n){void 0===i&&(i=0),void 0===s&&(s=0);var r=l(n,"alpha",1),o=l(n,"tint",16777215),a=l(n,"angle",0),h=l(n,"rotation",0),u=l(n,"scale",1),c=l(n,"scaleX",u),d=l(n,"scaleY",u),f=l(n,"originX",.5),p=l(n,"originY",.5),v=l(n,"blendMode",0),g=l(n,"erase",!1),m=l(n,"skipBatch",!1),y=this.manager.resetStamp(r,o);return y.setAngle(0),0!==a?y.setAngle(a):0!==h&&y.setRotation(h),y.setScale(c,d),y.setTexture(t,e),y.setOrigin(f,p),y.setBlendMode(v),g&&(this._eraseMode=!0),m?this.batchGameObject(y,i,s):this.draw(y,i,s),g&&(this._eraseMode=!1),this},erase:function(t,e,i){return this._eraseMode=!0,this.draw(t,e,i),this._eraseMode=!1,this},draw:function(t,e,i,s,n){return this.beginDraw(),this.batchDraw(t,e,i,s,n),this.endDraw(),this},drawFrame:function(t,e,i,s,n,r){return this.beginDraw(),this.batchDrawFrame(t,e,i,s,n,r),this.endDraw(),this},repeat:function(t,e,i,s,n,r,o,a,l){if(void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=this.width),void 0===r&&(r=this.height),void 0===o&&(o=1),void 0===a&&(a=16777215),void 0===l&&(l=!1),!(e=t instanceof h?t:this.manager.getFrame(t,e)))return this;var u=this.manager.resetStamp(o,a);u.setFrame(e),u.setOrigin(0);var c=e.width,d=e.height;n=Math.floor(n),r=Math.floor(r);var f=Math.ceil(n/c),p=Math.ceil(r/d),v=f*c-n,g=p*d-r;v>0&&(v=c-v),g>0&&(g=d-g),i<0&&(f+=Math.ceil(Math.abs(i)/c)),s<0&&(p+=Math.ceil(Math.abs(s)/d));var m=i,y=s,x=!1,T=this.manager.stampCrop.setTo(0,0,c,d);l||this.beginDraw();for(var w=0;w0&&b===f-1&&(x=!0,T.width=v),g>0&&w===p-1&&(x=!0,T.height=g),x&&u.setCrop(T),this.batchGameObject(u,m,y),u.isCropped=!1,T.setTo(0,0,c,d)),m+=c;m=i,y+=d}return l||this.endDraw(),this},beginDraw:function(){if(!this.isDrawing){var t=this.camera,e=this.renderer,i=this.renderTarget;t.preRender(),i?e.beginCapture(i.width,i.height):e.setContext(this.context),this.isDrawing=!0}return this},batchDraw:function(t,e,i,s,n){return Array.isArray(t)||(t=[t]),this.batchList(t,e,i,s,n),this},batchDrawFrame:function(t,e,i,s,n,r){void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=1),void 0===r&&(r=16777215);var o=this.manager.getFrame(t,e);return o&&(this.renderTarget?this.pipeline.batchTextureFrame(o,i,s,r,n,this.camera.matrix,null):this.batchTextureFrame(o,i,s,n,r)),this},endDraw:function(t){if(void 0===t&&(t=this._eraseMode),this.isDrawing){var e=this.renderer,i=this.renderTarget;if(i){var s=e.endCapture();e.pipelines.setUtility().blitFrame(s,i,1,!1,!1,t,this.isSpriteTexture),e.resetScissor(),e.resetViewport()}else e.setContext();this.dirty=!0,this.isDrawing=!1}return this},batchList:function(t,e,i,s,n){var r=t.length;if(0!==r)for(var o=0;o0&&a.height>0&&o.drawImage(h,a.x,a.y,a.width,a.height,e,i,a.width,a.height),o.restore()}},snapshotArea:function(t,e,i,s,n,r,o){return this.renderTarget?this.renderer.snapshotFramebuffer(this.renderTarget.framebuffer,this.width,this.height,n,!1,t,e,i,s,r,o):this.renderer.snapshotCanvas(this.canvas,n,!1,t,e,i,s,r,o),this},snapshot:function(t,e,i){return this.snapshotArea(0,0,this.width,this.height,t,e,i)},snapshotPixel:function(t,e,i){return this.snapshotArea(t,e,1,1,i,"pixel")},getWebGLTexture:function(){if(this.renderTarget)return this.renderTarget.texture},renderWebGL:function(t,e,i,s){var n=this.manager.resetStamp();n.setTexture(this),n.setOrigin(0),n.renderWebGL(t,n,i,s)},renderCanvas:function(){},preDestroy:function(){r.remove(this.canvas),this.renderTarget&&this.renderTarget.destroy(),this.camera.destroy(),this.stamp.destroy(),this.canvas=null,this.context=null,this.renderer=null,this.scene=null}});t.exports=p},82047:(t,e,i)=>{var s=i(56694),n=i(82897),r=i(98611),o=new s({initialize:function(t,e,i,s,n,r,o){this.texture=t,this.name=e,this.source=t.source[i],this.sourceIndex=i,this.glTexture=this.source.glTexture,this.cutX,this.cutY,this.cutWidth,this.cutHeight,this.x=0,this.y=0,this.width,this.height,this.halfWidth,this.halfHeight,this.centerX,this.centerY,this.pivotX=0,this.pivotY=0,this.customPivot=!1,this.rotated=!1,this.autoRound=-1,this.customData={},this.u0=0,this.v0=0,this.u1=0,this.v1=0,this.data={cut:{x:0,y:0,w:0,h:0,r:0,b:0},trim:!1,sourceSize:{w:0,h:0},spriteSourceSize:{x:0,y:0,w:0,h:0,r:0,b:0},radius:0,drawImage:{x:0,y:0,width:0,height:0}},this.setSize(r,o,s,n)},setSize:function(t,e,i,s){void 0===i&&(i=0),void 0===s&&(s=0),this.cutX=i,this.cutY=s,this.cutWidth=t,this.cutHeight=e,this.width=t,this.height=e,this.halfWidth=Math.floor(.5*t),this.halfHeight=Math.floor(.5*e),this.centerX=Math.floor(t/2),this.centerY=Math.floor(e/2);var n=this.data,r=n.cut;r.x=i,r.y=s,r.w=t,r.h=e,r.r=i+t,r.b=s+e,n.sourceSize.w=t,n.sourceSize.h=e,n.spriteSourceSize.w=t,n.spriteSourceSize.h=e,n.radius=.5*Math.sqrt(t*t+e*e);var o=n.drawImage;return o.x=i,o.y=s,o.width=t,o.height=e,this.updateUVs()},setTrim:function(t,e,i,s,n,r){var o=this.data,a=o.spriteSourceSize;return o.trim=!0,o.sourceSize.w=t,o.sourceSize.h=e,a.x=i,a.y=s,a.w=n,a.h=r,a.r=i+n,a.b=s+r,this.x=i,this.y=s,this.width=n,this.height=r,this.halfWidth=.5*n,this.halfHeight=.5*r,this.centerX=Math.floor(n/2),this.centerY=Math.floor(r/2),this.updateUVs()},setCropUVs:function(t,e,i,s,r,o,a){var h=this.cutX,l=this.cutY,u=this.cutWidth,c=this.cutHeight,d=this.realWidth,f=this.realHeight,p=h+(e=n(e,0,d)),v=l+(i=n(i,0,f)),g=s=n(s,0,d-e),m=r=n(r,0,f-i),y=this.data;if(y.trim){var x=y.spriteSourceSize,T=e+(s=n(s,0,u-e)),w=i+(r=n(r,0,c-i));if(!(x.rT||x.y>w)){var b=Math.max(x.x,e),S=Math.max(x.y,i),E=Math.min(x.r,T)-b,A=Math.min(x.b,w)-S;g=E,m=A,p=o?h+(u-(b-x.x)-E):h+(b-x.x),v=a?l+(c-(S-x.y)-A):l+(S-x.y),e=b,i=S,s=E,r=A}else p=0,v=0,g=0,m=0}else o&&(p=h+(u-e-s)),a&&(v=l+(c-i-r));var C=this.source.width,_=this.source.height;return t.u0=Math.max(0,p/C),t.v0=Math.max(0,v/_),t.u1=Math.min(1,(p+g)/C),t.v1=Math.min(1,(v+m)/_),t.x=e,t.y=i,t.cx=p,t.cy=v,t.cw=g,t.ch=m,t.width=s,t.height=r,t.flipX=o,t.flipY=a,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,s,n,r){var o=this.data.drawImage;return o.width=t,o.height=e,this.u0=i,this.v0=s,this.u1=n,this.v1=r,this},updateUVs:function(){var t=this.cutX,e=this.cutY,i=this.cutWidth,s=this.cutHeight,n=this.data.drawImage;n.width=i,n.height=s;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+s)/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 o(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=r(!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=o},31673:(t,e,i)=>{var s=i(56694),n=i(82047),r=i(32547),o='Texture "%s" has no frame "%s"',a=new s({initialize:function(t,e,i,s,n){Array.isArray(i)||(i=[i]),this.manager=t,this.key=e,this.source=[],this.dataSource=[],this.frames={},this.customData={},this.firstFrame="__BASE",this.frameTotal=0;for(var o=0;o{var s=i(61068),n=i(17487),r=i(56694),o=i(27119),a=i(86459),h=i(845),l=i(6659),u=i(38203),c=i(82047),d=i(97081),f=i(52780),p=i(10850),v=i(1539),g=i(42911),m=i(69150),y=i(74118),x=i(31673),T=new r({Extends:l,initialize:function(t){l.call(this),this.game=t,this.name="TextureManager",this.list={},this._tempCanvas=s.create2D(this),this._tempContext=this._tempCanvas.getContext("2d",{willReadFrequently:!0}),this._pending=0,this.stamp,this.stampCrop=new y,this.silentWarnings=!1,t.events.once(d.BOOT,this.boot,this)},boot:function(){this._pending=3,this.on(u.LOAD,this.updatePending,this),this.on(u.ERROR,this.updatePending,this);var t=this.game.config;this.addBase64("__DEFAULT",t.defaultImage),this.addBase64("__MISSING",t.missingImage),this.addBase64("__WHITE",t.whiteImage),this.game.events.once(d.DESTROY,this.destroy,this)},updatePending:function(){this._pending--,0===this._pending&&(this.off(u.LOAD),this.off(u.ERROR),this.emit(u.READY),this.stamp=new v(this.game.scene.systemScene).setOrigin(0))},checkKey:function(t){return!this.exists(t)||(this.silentWarnings||console.error("Texture key already in use: "+t),!1)},remove:function(t){if("string"==typeof t){if(!this.exists(t))return this.silentWarnings||console.warn("No texture found matching key: "+t),this;t=this.get(t)}return this.list.hasOwnProperty(t.key)&&(t.destroy(),this.emit(u.REMOVE,t.key),this.emit(u.REMOVE_KEY+t.key)),this},removeKey:function(t){return this.list.hasOwnProperty(t)&&delete this.list[t],this},addBase64:function(t,e){if(this.checkKey(t)){var i=this,s=new Image;s.onerror=function(){i.emit(u.ERROR,t)},s.onload=function(){var e=i.create(t,s);m.Image(e,0),i.emit(u.ADD,t,e),i.emit(u.ADD_KEY+t,e),i.emit(u.LOAD,t,e)},s.src=e}return this},getBase64:function(t,e,i,n){void 0===i&&(i="image/png"),void 0===n&&(n=.92);var r="",o=this.getFrame(t,e);if(o&&(o.source.isRenderTexture||o.source.isGLTexture))this.silentWarnings||console.warn("Cannot getBase64 from WebGL Texture");else if(o){var a=o.canvasData,h=s.create2D(this,a.width,a.height),l=h.getContext("2d",{willReadFrequently:!0});a.width>0&&a.height>0&&l.drawImage(o.source.image,a.x,a.y,a.width,a.height,0,0,a.width,a.height),r=h.toDataURL(i,n),s.remove(h)}return r},addImage:function(t,e,i){var s=null;return this.checkKey(t)&&(s=this.create(t,e),m.Image(s,0),i&&s.setDataSource(i),this.emit(u.ADD,t,s),this.emit(u.ADD_KEY+t,s)),s},addGLTexture:function(t,e,i,s){var n=null;return this.checkKey(t)&&(void 0===i&&(i=e.width),void 0===s&&(s=e.height),(n=this.create(t,e,i,s)).add("__BASE",0,0,0,i,s),this.emit(u.ADD,t,n),this.emit(u.ADD_KEY+t,n)),n},addCompressedTexture:function(t,e,i){var s=null;if(this.checkKey(t)){if((s=this.create(t,e)).add("__BASE",0,0,0,e.width,e.height),i)if(Array.isArray(i))for(var n=0;n=r.x&&t=r.y&&e=r.x&&t=r.y&&e{var s=i(61068),n=i(56694),r=i(28621),o=i(27394),a=new n({initialize:function(t,e,i,s,n){void 0===n&&(n=!1);var a=t.manager.game;this.renderer=a.renderer,this.texture=t,this.source=e,this.image=e.compressed?null:e,this.compressionAlgorithm=e.compressed?e.format:null,this.resolution=1,this.width=i||e.naturalWidth||e.videoWidth||e.width||0,this.height=s||e.naturalHeight||e.videoHeight||e.height||0,this.scaleMode=o.DEFAULT,this.isCanvas=e instanceof HTMLCanvasElement,this.isVideo=window.hasOwnProperty("HTMLVideoElement")&&e instanceof HTMLVideoElement,this.isRenderTexture="RenderTexture"===e.type||"DynamicTexture"===e.type,this.isGLTexture=window.hasOwnProperty("WebGLTexture")&&e instanceof WebGLTexture,this.isPowerOf2=r(this.width,this.height),this.glTexture=null,this.flipY=n,this.init(a)},init:function(t){var e=this.renderer;if(e){var i=this.source;if(e.gl){var s=this.image,n=this.flipY,r=this.width,o=this.height,a=this.scaleMode;this.isCanvas?this.glTexture=e.createCanvasTexture(s,!1,n):this.isVideo?this.glTexture=e.createVideoTexture(s,!1,n):this.isRenderTexture?this.glTexture=e.createTextureFromSource(null,r,o,a):this.isGLTexture?this.glTexture=i:this.compressionAlgorithm?this.glTexture=e.createTextureFromSource(i):this.glTexture=e.createTextureFromSource(s,r,o,a)}else this.isRenderTexture&&(this.image=i.canvas)}t.config.antialias||this.setFilter(1)},setFilter:function(t){this.renderer.gl&&this.renderer.setTextureFilter(this.glTexture,t),this.scaleMode=t},setFlipY:function(t){return void 0===t&&(t=!0),this.flipY=t,this},update:function(){var t=this.renderer,e=this.image,i=this.flipY,s=t.gl;s&&this.isCanvas?this.glTexture=t.updateCanvasTexture(e,this.glTexture,i):s&&this.isVideo&&(this.glTexture=t.updateVideoTexture(e,this.glTexture,i))},destroy:function(){this.glTexture&&this.renderer.deleteTexture(this.glTexture,!0),this.isCanvas&&s.remove(this.image),this.renderer=null,this.texture=null,this.source=null,this.image=null,this.glTexture=null}});t.exports=a},65154:t=>{t.exports={LINEAR:0,NEAREST:1}},49644:t=>{t.exports="addtexture"},29569:t=>{t.exports="addtexture-"},60079:t=>{t.exports="onerror"},72665:t=>{t.exports="onload"},93006:t=>{t.exports="ready"},69018:t=>{t.exports="removetexture"},85549:t=>{t.exports="removetexture-"},38203:(t,e,i)=>{t.exports={ADD:i(49644),ADD_KEY:i(29569),ERROR:i(60079),LOAD:i(72665),READY:i(93006),REMOVE:i(69018),REMOVE_KEY:i(85549)}},87499:(t,e,i)=>{var s=i(98611),n=i(65154),r={CanvasTexture:i(17487),DynamicTexture:i(845),Events:i(38203),FilterMode:n,Frame:i(82047),Parsers:i(69150),Texture:i(31673),TextureManager:i(6237),TextureSource:i(32547)};r=s(!1,r,n),t.exports=r},35082:t=>{t.exports=function(t,e,i){if(i.getElementsByTagName("TextureAtlas")){var s=t.source[e];t.add("__BASE",e,0,0,s.width,s.height);for(var n,r=i.getElementsByTagName("SubTexture"),o=0;o{t.exports=function(t,e){var i=t.source[e];return t.add("__BASE",e,0,0,i.width,i.height),t}},21560:t=>{t.exports=function(t,e){var i=t.source[e];return t.add("__BASE",e,0,0,i.width,i.height),t}},64423:(t,e,i)=>{var s=i(32742);t.exports=function(t,e,i){if(i.frames||i.textures){var n=t.source[e];t.add("__BASE",e,0,0,n.width,n.height);for(var r,o=Array.isArray(i.textures)?i.textures[e].frames:i.frames,a=0;a{var s=i(32742);t.exports=function(t,e,i){if(i.frames){var n=t.source[e];t.add("__BASE",e,0,0,n.width,n.height);var r,o=i.frames;for(var a in o)if(o.hasOwnProperty(a)){var h=o[a];if(r=t.add(a,e,h.frame.x,h.frame.y,h.frame.w,h.frame.h)){h.trimmed&&r.setTrim(h.sourceSize.w,h.sourceSize.h,h.spriteSourceSize.x,h.spriteSourceSize.y,h.spriteSourceSize.w,h.spriteSourceSize.h),h.rotated&&(r.rotated=!0,r.updateUVsInverted());var l=h.anchor||h.pivot;l&&(r.customPivot=!0,r.pivotX=l.x,r.pivotY=l.y),r.customData=s(h)}else console.warn("Invalid atlas json, frame already exists: "+a)}for(var u in i)"frames"!==u&&(Array.isArray(i[u])?t.customData[u]=i[u].slice(0):t.customData[u]=i[u]);return t}console.warn("Invalid Texture Atlas JSON Hash given, missing 'frames' Object")}},67409:t=>{t.exports=function(t){var e,i=[171,75,84,88,32,49,49,187,13,10,26,10],s=new Uint8Array(t,0,12);for(e=0;e>1),v=Math.max(1,v>>1),f+=g}return{mipmaps:d,width:h,height:l,internalFormat:a,compressed:!0,generateMipmap:!1}}console.warn("KTXParser - Only compressed formats supported")}},24904:t=>{function e(t,e,i,s,n,r,o){return void 0===o&&(o=16),Math.floor((t+i)/n)*Math.floor((e+s)/r)*o}function i(t,e){return(t=Math.max(t,16))*(e=Math.max(e,8))/4}function s(t,e){return(t=Math.max(t,8))*(e=Math.max(e,8))/2}function n(t,i){return e(t,i,3,3,4,4,8)}function r(t,i){return e(t,i,3,3,4,4)}var o={0:{sizeFunc:i,glFormat:35841},1:{sizeFunc:i,glFormat:35843},2:{sizeFunc:s,glFormat:35840},3:{sizeFunc:s,glFormat:35842},6:{sizeFunc:n,glFormat:36196},7:{sizeFunc:n,glFormat:33776},8:{sizeFunc:r,glFormat:33777},9:{sizeFunc:r,glFormat:33778},11:{sizeFunc:r,glFormat:33779},22:{sizeFunc:n,glFormat:37492},23:{sizeFunc:r,glFormat:37496},24:{sizeFunc:n,glFormat:37494},25:{sizeFunc:n,glFormat:37488},26:{sizeFunc:r,glFormat:37490},27:{sizeFunc:r,glFormat:37808},28:{sizeFunc:function(t,i){return e(t,i,4,3,5,4)},glFormat:37809},29:{sizeFunc:function(t,i){return e(t,i,4,4,5,5)},glFormat:37810},30:{sizeFunc:function(t,i){return e(t,i,5,4,6,5)},glFormat:37811},31:{sizeFunc:function(t,i){return e(t,i,5,5,6,6)},glFormat:37812},32:{sizeFunc:function(t,i){return e(t,i,7,4,8,5)},glFormat:37813},33:{sizeFunc:function(t,i){return e(t,i,7,5,8,6)},glFormat:37814},34:{sizeFunc:function(t,i){return e(t,i,7,7,8,8)},glFormat:37815},35:{sizeFunc:function(t,i){return e(t,i,9,4,10,5)},glFormat:37816},36:{sizeFunc:function(t,i){return e(t,i,9,5,10,6)},glFormat:37817},37:{sizeFunc:function(t,i){return e(t,i,9,7,10,8)},glFormat:37818},38:{sizeFunc:function(t,i){return e(t,i,9,9,10,10)},glFormat:37819},39:{sizeFunc:function(t,i){return e(t,i,11,9,12,10)},glFormat:37820},40:{sizeFunc:function(t,i){return e(t,i,11,11,12,12)},glFormat:37821}};t.exports=function(t){for(var e=new Uint32Array(t,0,13),i=e[2],s=o[i].glFormat,n=o[i].sizeFunc,r=e[11],a=e[7],h=e[6],l=52+e[12],u=new Uint8Array(t,l),c=new Array(r),d=0,f=a,p=h,v=0;v>1),p=Math.max(1,p>>1),d+=g}return{mipmaps:c,width:a,height:h,internalFormat:s,compressed:!0,generateMipmap:!1}}},6143:(t,e,i)=>{var s=i(72632);t.exports=function(t,e,i,n,r,o,a){var h=s(a,"frameWidth",null),l=s(a,"frameHeight",h);if(null===h)throw new Error("TextureManager.SpriteSheet: Invalid frameWidth given.");var u=t.source[e];t.add("__BASE",e,0,0,u.width,u.height);var c=s(a,"startFrame",0),d=s(a,"endFrame",-1),f=s(a,"margin",0),p=s(a,"spacing",0),v=Math.floor((r-f+p)/(h+p))*Math.floor((o-f+p)/(l+p));0===v&&console.warn("SpriteSheet frame dimensions will result in zero frames for texture:",t.key),(c>v||c<-v)&&(c=0),c<0&&(c=v+c),(-1===d||d>v||dr&&(y=b-r),S>o&&(x=S-o),w>=c&&w<=d&&(t.add(T,e,i+g,n+m,h-y,l-x),T++),(g+=h+p)+h>r&&(g=f,m+=l+p)}return t}},20030:(t,e,i)=>{var s=i(72632);t.exports=function(t,e,i){var n=s(i,"frameWidth",null),r=s(i,"frameHeight",n);if(!n)throw new Error("TextureManager.SpriteSheetFromAtlas: Invalid frameWidth given.");var o=t.source[0];t.add("__BASE",0,0,0,o.width,o.height);var a,h=s(i,"startFrame",0),l=s(i,"endFrame",-1),u=s(i,"margin",0),c=s(i,"spacing",0),d=e.cutX,f=e.cutY,p=e.cutWidth,v=e.cutHeight,g=e.realWidth,m=e.realHeight,y=Math.floor((g-u+c)/(n+c)),x=Math.floor((m-u+c)/(r+c)),T=y*x,w=e.x,b=n-w,S=n-(g-p-w),E=e.y,A=r-E,C=r-(m-v-E);(h>T||h<-T)&&(h=0),h<0&&(h=T+h),-1!==l&&(T=h+(l+1));for(var _=u,M=u,P=0,R=0;R{var e=0,i=function(t,i,s,n){var r=e-n.y-n.height;t.add(s,i,n.x,r,n.width,n.height)};t.exports=function(t,s,n){var r=t.source[s];t.add("__BASE",s,0,0,r.width,r.height),e=r.height;for(var o=n.split("\n"),a=/^[ ]*(- )*(\w+)+[: ]+(.*)/,h="",l="",u={x:0,y:0,width:0,height:0},c=0;c{t.exports={AtlasXML:i(35082),Canvas:i(83332),Image:i(21560),JSONArray:i(64423),JSONHash:i(17264),KTXParser:i(67409),PVRParser:i(24904),SpriteSheet:i(6143),SpriteSheetFromAtlas:i(20030),UnityYAML:i(89187)}},93560:t=>{t.exports={CSV:0,TILED_JSON:1,ARRAY_2D:2,WELTMEISTER:3}},97042:(t,e,i)=>{var s=new(i(56694))({initialize:function(t,e,i,s,n,r,o){(void 0===i||i<=0)&&(i=32),(void 0===s||s<=0)&&(s=32),void 0===n&&(n=0),void 0===r&&(r=0),this.name=t,this.firstgid=0|e,this.imageWidth=0|i,this.imageHeight=0|s,this.imageMargin=0|n,this.imageSpacing=0|r,this.properties=o||{},this.images=[],this.total=0},containsImageIndex:function(t){return t>=this.firstgid&&t{var s=new(i(56694))({initialize:function(t){if(this.gids=[],void 0!==t)for(var e=0;e{var s=i(93560),n=i(16586),r=i(90715),o=i(89797);t.exports=function(t,e,i,a,h,l,u,c){void 0===i&&(i=32),void 0===a&&(a=32),void 0===h&&(h=10),void 0===l&&(l=10),void 0===c&&(c=!1);var d=null;if(Array.isArray(u))d=r(void 0!==e?e:"map",s.ARRAY_2D,u,i,a,c);else if(void 0!==e){var f=t.cache.tilemap.get(e);f?d=r(e,f.format,f.data,i,a,c):console.warn("No map data found for key "+e)}return null===d&&(d=new n({tileWidth:i,tileHeight:a,width:h,height:l})),new o(t,d)}},29633:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(12920),o=i(28699),a=i(66658),h=new s({Mixins:[n.Alpha,n.Flip,n.Visible],initialize:function(t,e,i,s,n,r,o,a){this.layer=t,this.index=e,this.x=i,this.y=s,this.width=n,this.height=r,this.right,this.bottom,this.baseWidth=void 0!==o?o:n,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,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=o(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.tileToWorldXY(this.x,this.y,void 0,t).x: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.tileToWorldXY(this.x,this.y,void 0,t).y:this.y*this.baseWidth-(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 a),e.x=this.getLeft(t),e.y=this.getTop(t),e.width=this.getRight(t)-e.x,e.height=this.getBottom(t)-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,s){return!(i<=this.pixelX||s<=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){(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));return this},resetFaces:function(){return this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this},setCollision:function(t,e,i,s,n){(void 0===e&&(e=t),void 0===i&&(i=t),void 0===s&&(s=t),void 0===n&&(n=!0),this.collideLeft=t,this.collideRight=e,this.collideUp=i,this.collideDown=s,this.faceLeft=t,this.faceRight=e,this.faceTop=i,this.faceBottom=s,n)&&(this.tilemapLayer&&this.tilemapLayer.calculateFacesAt(this.x,this.y));return 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,s){return void 0!==t&&(this.width=t),void 0!==e&&(this.height=e),void 0!==i&&(this.baseWidth=i),void 0!==s&&(this.baseHeight=s),this.updatePixelXY(),this},updatePixelXY:function(){var t=this.layer.orientation;if(t===r.ORTHOGONAL)this.pixelX=this.x*this.baseWidth,this.pixelY=this.y*this.baseHeight;else if(t===r.ISOMETRIC)this.pixelX=(this.x-this.y)*this.baseWidth*.5,this.pixelY=(this.x+this.y)*this.baseHeight*.5;else if(t===r.STAGGERED)this.pixelX=this.x*this.baseWidth+this.y%2*(this.baseWidth/2),this.pixelY=this.y*(this.baseHeight/2);else if(t===r.HEXAGONAL){var e,i,s=this.layer.staggerAxis,n=this.layer.staggerIndex,o=this.layer.hexSideLength;"y"===s?(i=(this.baseHeight-o)/2+o,this.pixelX="odd"===n?this.x*this.baseWidth+this.y%2*(this.baseWidth/2):this.x*this.baseWidth-this.y%2*(this.baseWidth/2),this.pixelY=this.y*i):"x"===s&&(e=(this.baseWidth-o)/2+o,this.pixelX=this.x*e,this.pixelY="odd"===n?this.y*this.baseHeight+this.x%2*(this.baseHeight/2):this.y*this.baseHeight-this.x%2*(this.baseHeight/2))}return 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=h},89797:(t,e,i)=>{var s=i(14556),n=i(56694),r=i(75606),o=i(93560),a=i(72632),h=i(94990),l=i(46422),u=i(12920),c=i(52257),d=i(72677),f=i(13747),p=i(29633),v=i(5047),g=i(87177),m=i(47975),y=new n({initialize:function(t,e){this.scene=t,this.tileWidth=e.tileWidth,this.tileHeight=e.tileHeight,this.width=e.width,this.height=e.height,this.orientation=e.orientation,this.renderOrder=e.renderOrder,this.format=e.format,this.version=e.version,this.properties=e.properties,this.widthInPixels=e.widthInPixels,this.heightInPixels=e.heightInPixels,this.imageCollections=e.imageCollections,this.images=e.images,this.layers=e.layers,this.tiles=e.tiles,this.tilesets=e.tilesets,this.objects=e.objects,this.currentLayerIndex=0,this.hexSideLength=e.hexSideLength;var i=this.orientation;this._convert={WorldToTileXY:v.GetWorldToTileXYFunction(i),WorldToTileX:v.GetWorldToTileXFunction(i),WorldToTileY:v.GetWorldToTileYFunction(i),TileToWorldXY:v.GetTileToWorldXYFunction(i),TileToWorldX:v.GetTileToWorldXFunction(i),TileToWorldY:v.GetTileToWorldYFunction(i),GetTileCorners:v.GetTileCornersFunction(i)}},setRenderOrder:function(t){var e=["right-down","left-down","right-up","left-up"];return"number"==typeof t&&(t=e[t]),e.indexOf(t)>-1&&(this.renderOrder=t),this},addTilesetImage:function(t,e,i,n,r,a,h,l){if(void 0===t)return null;if(null==e&&(e=t),!this.scene.sys.textures.exists(e))return console.warn("Invalid Tileset Image: "+e),null;var u=this.scene.sys.textures.get(e),c=this.getTilesetIndex(t);if(null===c&&this.format===o.TILED_JSON)return console.warn("No data found for Tileset: "+t),null;var d=this.tilesets[c];return d?(d.setTileSize(i,n),d.setSpacing(r,a),d.setImage(u),d):(void 0===i&&(i=this.tileWidth),void 0===n&&(n=this.tileHeight),void 0===r&&(r=0),void 0===a&&(a=0),void 0===h&&(h=0),void 0===l&&(l={x:0,y:0}),(d=new m(t,h,i,n,r,a,void 0,void 0,l)).setImage(u),this.tilesets.push(d),this.tiles=s(this),d)},copy:function(t,e,i,s,n,r,o,a){return null!==(a=this.getLayer(a))?(v.Copy(t,e,i,s,n,r,o,a),this):null},createBlankLayer:function(t,e,i,s,n,r,o,a){if(void 0===i&&(i=0),void 0===s&&(s=0),void 0===n&&(n=this.width),void 0===r&&(r=this.height),void 0===o&&(o=this.tileWidth),void 0===a&&(a=this.tileHeight),null!==this.getLayerIndex(t))return console.warn("Invalid Tilemap Layer ID: "+t),null;for(var l,u=new h({name:t,tileWidth:o,tileHeight:a,width:n,height:r,orientation:this.orientation}),c=0;c-1&&this.putTileAt(e,r.x,r.y,i,r.tilemapLayer)}return s},removeTileAt:function(t,e,i,s,n){return void 0===i&&(i=!0),void 0===s&&(s=!0),null===(n=this.getLayer(n))?null:v.RemoveTileAt(t,e,i,s,n)},removeTileAtWorldXY:function(t,e,i,s,n,r){return void 0===i&&(i=!0),void 0===s&&(s=!0),null===(r=this.getLayer(r))?null:v.RemoveTileAtWorldXY(t,e,i,s,n,r)},renderDebug:function(t,e,i){return null===(i=this.getLayer(i))?null:(this.orientation===u.ORTHOGONAL&&v.RenderDebug(t,e,i),this)},renderDebugFull:function(t,e){for(var i=this.layers,s=0;s{var s=i(99325),n=i(15043);s.register("tilemap",(function(t){var e=void 0!==t?t:{};return n(this.scene,e.key,e.tileWidth,e.tileHeight,e.width,e.height,e.data,e.insertNull)}))},37940:(t,e,i)=>{var s=i(61286),n=i(15043);s.register("tilemap",(function(t,e,i,s,r,o,a){return null===t&&(t=void 0),null===e&&(e=void 0),null===i&&(i=void 0),null===s&&(s=void 0),null===r&&(r=void 0),n(this.scene,t,e,i,s,r,o,a)}))},87177:(t,e,i)=>{var s=i(56694),n=i(64937),r=i(89980),o=i(5047),a=i(96193),h=i(93736),l=new s({Extends:r,Mixins:[n.Alpha,n.BlendMode,n.ComputedSize,n.Depth,n.Flip,n.GetBounds,n.Mask,n.Origin,n.Pipeline,n.PostPipeline,n.Transform,n.Visible,n.ScrollFactor,a],initialize:function(t,e,i,s,n,a){r.call(this,t,"TilemapLayer"),this.isTilemap=!0,this.tilemap=e,this.layerIndex=i,this.layer=e.layers[i],this.layer.tilemapLayer=this,this.tileset=[],this.tilesDrawn=0,this.tilesTotal=this.layer.width*this.layer.height,this.culledTiles=[],this.skipCull=!1,this.cullPaddingX=1,this.cullPaddingY=1,this.cullCallback=o.GetCullTilesFunction(this.layer.orientation),this._renderOrder=0,this.gidMap=[],this.tempVec=new h,this.setTilesets(s),this.setAlpha(this.layer.alpha),this.setPosition(n,a),this.setOrigin(0,0),this.setSize(e.tileWidth*this.layer.width,e.tileHeight*this.layer.height),this.initPipeline(),this.initPostPipeline(!1)},setTilesets:function(t){var e=[],i=[],s=this.tilemap;Array.isArray(t)||(t=[t]);for(var n=0;n=0&&t<4&&(this._renderOrder=t),this},calculateFacesAt:function(t,e){return o.CalculateFacesAt(t,e,this.layer),this},calculateFacesWithin:function(t,e,i,s){return o.CalculateFacesWithin(t,e,i,s,this.layer),this},createFromTiles:function(t,e,i,s,n){return o.CreateFromTiles(t,e,i,s,n,this.layer)},cull:function(t){return this.cullCallback(this.layer,t,this.culledTiles,this._renderOrder)},copy:function(t,e,i,s,n,r,a){return o.Copy(t,e,i,s,n,r,a,this.layer),this},fill:function(t,e,i,s,n,r){return o.Fill(t,e,i,s,n,r,this.layer),this},filterTiles:function(t,e,i,s,n,r,a){return o.FilterTiles(t,e,i,s,n,r,a,this.layer)},findByIndex:function(t,e,i){return o.FindByIndex(t,e,i,this.layer)},findTile:function(t,e,i,s,n,r,a){return o.FindTile(t,e,i,s,n,r,a,this.layer)},forEachTile:function(t,e,i,s,n,r,a){return o.ForEachTile(t,e,i,s,n,r,a,this.layer),this},setTint:function(t,e,i,s,n,r){void 0===t&&(t=16777215);return this.forEachTile((function(e){e.tint=t}),this,e,i,s,n,r)},getTileAt:function(t,e,i){return o.GetTileAt(t,e,i,this.layer)},getTileAtWorldXY:function(t,e,i,s){return o.GetTileAtWorldXY(t,e,i,s,this.layer)},getIsoTileAtWorldXY:function(t,e,i,s,n){void 0===i&&(i=!0);var r=this.tempVec;return o.IsometricWorldToTileXY(t,e,!0,r,n,this.layer,i),this.getTileAt(r.x,r.y,s)},getTilesWithin:function(t,e,i,s,n){return o.GetTilesWithin(t,e,i,s,n,this.layer)},getTilesWithinShape:function(t,e,i){return o.GetTilesWithinShape(t,e,i,this.layer)},getTilesWithinWorldXY:function(t,e,i,s,n,r){return o.GetTilesWithinWorldXY(t,e,i,s,n,r,this.layer)},hasTileAt:function(t,e){return o.HasTileAt(t,e,this.layer)},hasTileAtWorldXY:function(t,e,i){return o.HasTileAtWorldXY(t,e,i,this.layer)},putTileAt:function(t,e,i,s){return o.PutTileAt(t,e,i,s,this.layer)},putTileAtWorldXY:function(t,e,i,s,n){return o.PutTileAtWorldXY(t,e,i,s,n,this.layer)},putTilesAt:function(t,e,i,s){return o.PutTilesAt(t,e,i,s,this.layer),this},randomize:function(t,e,i,s,n){return o.Randomize(t,e,i,s,n,this.layer),this},removeTileAt:function(t,e,i,s){return o.RemoveTileAt(t,e,i,s,this.layer)},removeTileAtWorldXY:function(t,e,i,s,n){return o.RemoveTileAtWorldXY(t,e,i,s,n,this.layer)},renderDebug:function(t,e){return o.RenderDebug(t,e,this.layer),this},replaceByIndex:function(t,e,i,s,n,r){return o.ReplaceByIndex(t,e,i,s,n,r,this.layer),this},setSkipCull:function(t){return void 0===t&&(t=!0),this.skipCull=t,this},setCullPadding:function(t,e){return void 0===t&&(t=1),void 0===e&&(e=1),this.cullPaddingX=t,this.cullPaddingY=e,this},setCollision:function(t,e,i,s){return o.SetCollision(t,e,i,this.layer,s),this},setCollisionBetween:function(t,e,i,s){return o.SetCollisionBetween(t,e,i,s,this.layer),this},setCollisionByProperty:function(t,e,i){return o.SetCollisionByProperty(t,e,i,this.layer),this},setCollisionByExclusion:function(t,e,i){return o.SetCollisionByExclusion(t,e,i,this.layer),this},setCollisionFromCollisionGroup:function(t,e){return o.SetCollisionFromCollisionGroup(t,e,this.layer),this},setTileIndexCallback:function(t,e,i){return o.SetTileIndexCallback(t,e,i,this.layer),this},setTileLocationCallback:function(t,e,i,s,n,r){return o.SetTileLocationCallback(t,e,i,s,n,r,this.layer),this},shuffle:function(t,e,i,s){return o.Shuffle(t,e,i,s,this.layer),this},swapByIndex:function(t,e,i,s,n,r){return o.SwapByIndex(t,e,i,s,n,r,this.layer),this},tileToWorldX:function(t,e){return this.tilemap.tileToWorldX(t,e,this)},tileToWorldY:function(t,e){return this.tilemap.tileToWorldY(t,e,this)},tileToWorldXY:function(t,e,i,s){return this.tilemap.tileToWorldXY(t,e,i,s,this)},getTileCorners:function(t,e,i){return this.tilemap.getTileCorners(t,e,i,this)},weightedRandomize:function(t,e,i,s,n){return o.WeightedRandomize(e,i,s,n,t,this.layer),this},worldToTileX:function(t,e,i){return this.tilemap.worldToTileX(t,e,i,this)},worldToTileY:function(t,e,i){return this.tilemap.worldToTileY(t,e,i,this)},worldToTileXY:function(t,e,i,s,n){return this.tilemap.worldToTileXY(t,e,i,s,n,this)},destroy:function(t){void 0===t&&(t=!0),this.tilemap&&(this.layer.tilemapLayer===this&&(this.layer.tilemapLayer=void 0),t&&this.tilemap.removeLayer(this),this.tilemap=void 0,this.layer=void 0,this.culledTiles.length=0,this.cullCallback=null,this.gidMap=[],this.tileset=[],r.prototype.destroy.call(this))}});t.exports=l},17394:(t,e,i)=>{var s=i(69360),n=new s,r=new s,o=new s;t.exports=function(t,e,i,s){var a=e.cull(i),h=a.length,l=i.alpha*e.alpha;if(!(0===h||l<=0)){var u=n,c=r,d=o;c.applyITRS(e.x,e.y,e.rotation,e.scaleX,e.scaleY),u.copyFrom(i.matrix);var f=t.currentContext,p=e.gidMap;f.save(),s?(u.multiplyWithOffset(s,-i.scrollX*e.scrollFactorX,-i.scrollY*e.scrollFactorY),c.e=e.x,c.f=e.y,u.multiply(c,d),d.copyToContext(f)):(c.e-=i.scrollX*e.scrollFactorX,c.f-=i.scrollY*e.scrollFactorY,c.copyToContext(f)),(!t.antialias||e.scaleX>1||e.scaleY>1)&&(f.imageSmoothingEnabled=!1);for(var v=0;v{var s=i(72283),n=s,r=s;n=i(51395),r=i(17394),t.exports={renderWebGL:n,renderCanvas:r}},51395:(t,e,i)=>{var s=i(75512);t.exports=function(t,e,i){var n=e.cull(i),r=n.length,o=i.alpha*e.alpha;if(!(0===r||o<=0)){var a=e.gidMap,h=t.pipelines.set(e.pipeline,e),l=s.getTintAppendFloatAlpha,u=e.scrollFactorX,c=e.scrollFactorY,d=e.x,f=e.y,p=e.scaleX,v=e.scaleY;t.pipelines.preBatch(e);for(var g=0;g{var s=i(56694),n=i(93736),r=new s({initialize:function(t,e,i,s,r,o,a,h,l){(void 0===i||i<=0)&&(i=32),(void 0===s||s<=0)&&(s=32),void 0===r&&(r=0),void 0===o&&(o=0),void 0===a&&(a={}),void 0===h&&(h={}),this.name=t,this.firstgid=e,this.tileWidth=i,this.tileHeight=s,this.tileMargin=r,this.tileSpacing=o,this.tileProperties=a,this.tileData=h,this.tileOffset=new n,void 0!==l&&this.tileOffset.set(l.x,l.y),this.image=null,this.glTexture=null,this.rows=0,this.columns=0,this.total=0,this.texCoordinates=[]},getTileProperties:function(t){return this.containsTileIndex(t)?this.tileProperties[t-this.firstgid]:null},getTileData:function(t){return this.containsTileIndex(t)?this.tileData[t-this.firstgid]:null},getTileCollisionGroup:function(t){var e=this.getTileData(t);return e&&e.objectgroup?e.objectgroup:null},containsTileIndex:function(t){return t>=this.firstgid&&t{var s=i(15494);t.exports=function(t,e,i){var n=s(t,e,!0,i),r=s(t,e-1,!0,i),o=s(t,e+1,!0,i),a=s(t-1,e,!0,i),h=s(t+1,e,!0,i),l=n&&n.collides;return l&&(n.faceTop=!0,n.faceBottom=!0,n.faceLeft=!0,n.faceRight=!0),r&&r.collides&&(l&&(n.faceTop=!1),r.faceBottom=!l),o&&o.collides&&(l&&(n.faceBottom=!1),o.faceTop=!l),a&&a.collides&&(l&&(n.faceLeft=!1),a.faceRight=!l),h&&h.collides&&(l&&(n.faceRight=!1),h.faceLeft=!l),n&&!n.collides&&n.resetFaces(),n}},60386:(t,e,i)=>{var s=i(15494),n=i(50811);t.exports=function(t,e,i,r,o){for(var a=null,h=null,l=null,u=null,c=n(t,e,i,r,null,o),d=0;d{var s=new(i(93736));t.exports=function(t,e,i,n){var r=i.tilemapLayer,o=r.cullPaddingX,a=r.cullPaddingY,h=r.tilemap.tileToWorldXY(t,e,s,n,r);return h.x>n.worldView.x+r.scaleX*i.tileWidth*(-o-.5)&&h.xn.worldView.y+r.scaleY*i.tileHeight*(-a-1)&&h.y{var s=i(60386),n=i(50811),r=i(62839),o=i(29633);t.exports=function(t,e,i,a,h,l,u,c){void 0===u&&(u=!0);var d=n(t,e,i,a,null,c),f=[];d.forEach((function(t){var e=new o(t.layer,t.index,t.x,t.y,t.width,t.height,t.baseWidth,t.baseHeight);e.copy(t),f.push(e)}));for(var p=h-t,v=l-e,g=0;g{var s=i(50811),n=i(51202);t.exports=function(t,e,i,r,o,a){i||(i={}),Array.isArray(t)||(t=[t]);var h=a.tilemapLayer;r||(r=h.scene),o||(o=r.cameras.main);var l,u=s(0,0,a.width,a.height,null,a),c=[];for(l=0;l{var s=i(74118),n=i(82127),r=i(84314),o=new s;t.exports=function(t,e){var i=t.tilemapLayer.tilemap,s=t.tilemapLayer,a=Math.floor(i.tileWidth*s.scaleX),h=Math.floor(i.tileHeight*s.scaleY),l=r(e.worldView.x-s.x,a,0,!0)-s.cullPaddingX,u=n(e.worldView.right-s.x,a,0,!0)+s.cullPaddingX,c=r(e.worldView.y-s.y,h,0,!0)-s.cullPaddingY,d=n(e.worldView.bottom-s.y,h,0,!0)+s.cullPaddingY;return o.setTo(l,c,u-l,d-c)}},381:(t,e,i)=>{var s=i(71586),n=i(6987);t.exports=function(t,e,i,r){void 0===i&&(i=[]),void 0===r&&(r=0),i.length=0;var o=t.tilemapLayer,a=s(t,e);return(o.skipCull||1!==o.scrollFactorX||1!==o.scrollFactorY)&&(a.left=0,a.right=t.width,a.top=0,a.bottom=t.height),n(t,a,r,i),i}},97734:(t,e,i)=>{var s=i(50811),n=i(60386),r=i(68234);t.exports=function(t,e,i,o,a,h,l){for(var u=-1!==l.collideIndexes.indexOf(t),c=s(e,i,o,a,null,l),d=0;d{var s=i(50811);t.exports=function(t,e,i,n,r,o,a,h){return s(i,n,r,o,a,h).filter(t,e)}},37982:t=>{t.exports=function(t,e,i,s){void 0===e&&(e=0),void 0===i&&(i=!1);var n,r,o,a=0;if(i){for(r=s.height-1;r>=0;r--)for(n=s.width-1;n>=0;n--)if((o=s.data[r][n])&&o.index===t){if(a===e)return o;a+=1}}else for(r=0;r{var s=i(50811);t.exports=function(t,e,i,n,r,o,a,h){return s(i,n,r,o,a,h).find(t,e)||null}},80916:(t,e,i)=>{var s=i(50811);t.exports=function(t,e,i,n,r,o,a,h){s(i,n,r,o,a,h).forEach(t,e)}},31493:(t,e,i)=>{var s=i(12920),n=i(381),r=i(37524),o=i(20887),a=i(72283),h=i(19242);t.exports=function(t){return t===s.ORTHOGONAL?n:t===s.HEXAGONAL?r:t===s.STAGGERED?h:t===s.ISOMETRIC?o:a}},15494:(t,e,i)=>{var s=i(62839);t.exports=function(t,e,i,n){if(void 0===i&&(i=!1),s(t,e,n)){var r=n.data[e][t]||null;return r?-1===r.index?i?r:null:r:null}return null}},24640:(t,e,i)=>{var s=i(15494),n=new(i(93736));t.exports=function(t,e,i,r,o){return o.tilemapLayer.worldToTileXY(t,e,!0,n,r),s(n.x,n.y,i,o)}},48495:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n){var r=n.baseTileWidth,o=n.baseTileHeight,a=n.tilemapLayer,h=0,l=0;a&&(i||(i=a.scene.cameras.main),h=a.x+i.scrollX*(1-a.scrollFactorX),l=a.y+i.scrollY*(1-a.scrollFactorY),r*=a.scaleX,o*=a.scaleY);var u=h+t*r,c=l+e*o;return[new s(u,c),new s(u+r,c),new s(u+r,c+o),new s(u,c+o)]}},7160:(t,e,i)=>{var s=i(12920),n=i(63634),r=i(72283),o=i(48495);t.exports=function(t){return t===s.ORTHOGONAL?o:t===s.ISOMETRIC?r:t===s.HEXAGONAL?n:(s.STAGGERED,r)}},16884:(t,e,i)=>{var s=i(12920),n=i(72283),r=i(44150);t.exports=function(t){return t===s.ORTHOGONAL?r:n}},68182:(t,e,i)=>{var s=i(12920),n=i(21715),r=i(21808),o=i(72283),a=i(33388),h=i(46836);t.exports=function(t){return t===s.ORTHOGONAL?h:t===s.ISOMETRIC?r:t===s.HEXAGONAL?n:t===s.STAGGERED?a:o}},3752:(t,e,i)=>{var s=i(12920),n=i(72283),r=i(84132),o=i(42477);t.exports=function(t){return t===s.ORTHOGONAL?o:t===s.STAGGERED?r:n}},50811:(t,e,i)=>{var s=i(72632);t.exports=function(t,e,i,n,r,o){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=o.width),void 0===n&&(n=o.height),r||(r={});var a=s(r,"isNotEmpty",!1),h=s(r,"isColliding",!1),l=s(r,"hasInterestingFace",!1);t<0&&(i+=t,t=0),e<0&&(n+=e,e=0),t+i>o.width&&(i=Math.max(o.width-t,0)),e+n>o.height&&(n=Math.max(o.height-e,0));for(var u=[],c=e;c{var s=i(84068),n=i(50811),r=i(7563),o=i(72283),a=i(93736),h=function(t,e){return r.RectangleToTriangle(e,t)},l=new a,u=new a,c=new a;t.exports=function(t,e,i,a){if(void 0===t)return[];var d=o;t instanceof s.Circle?d=r.CircleToRectangle:t instanceof s.Rectangle?d=r.RectangleToRectangle:t instanceof s.Triangle?d=h:t instanceof s.Line&&(d=r.LineToRectangle),a.tilemapLayer.worldToTileXY(t.left,t.top,!0,u,i);var f=u.x,p=u.y;a.tilemapLayer.worldToTileXY(t.right,t.bottom,!1,c,i);var v=Math.ceil(c.x),g=Math.ceil(c.y),m=Math.max(v-f,1),y=Math.max(g-p,1),x=n(f,p,m,y,e,a),T=a.tileWidth,w=a.tileHeight;a.tilemapLayer&&(T*=a.tilemapLayer.scaleX,w*=a.tilemapLayer.scaleY);for(var b=[],S=new s.Rectangle(0,0,T,w),E=0;E{var s=i(50811),n=i(93736),r=new n,o=new n;t.exports=function(t,e,i,n,a,h,l){var u=l.tilemapLayer.tilemap._convert.WorldToTileXY;u(t,e,!0,r,h,l);var c=r.x,d=r.y;u(t+i,e+n,!1,o,h,l);var f=Math.ceil(o.x),p=Math.ceil(o.y);return s(c,d,f-c,p-d,a,l)}},29296:(t,e,i)=>{var s=i(12920),n=i(10618),r=i(806);t.exports=function(t){return t===s.ORTHOGONAL?r:n}},32688:(t,e,i)=>{var s=i(12920),n=i(11516),r=i(18750),o=i(72283),a=i(90562),h=i(45676);t.exports=function(t){return t===s.ORTHOGONAL?h:t===s.ISOMETRIC?r:t===s.HEXAGONAL?n:t===s.STAGGERED?a:o}},74326:(t,e,i)=>{var s=i(12920),n=i(10618),r=i(3689),o=i(70520);t.exports=function(t){return t===s.ORTHOGONAL?o:t===s.STAGGERED?r:n}},46598:(t,e,i)=>{var s=i(62839);t.exports=function(t,e,i){if(s(t,e,i)){var n=i.data[e][t];return null!==n&&n.index>-1}return!1}},28654:(t,e,i)=>{var s=i(46598),n=new(i(93736));t.exports=function(t,e,i,r){r.tilemapLayer.worldToTileXY(t,e,!0,n,i);var o=n.x,a=n.y;return s(o,a,r)}},6358:(t,e,i)=>{var s=i(82127),n=i(84314);t.exports=function(t,e){var i,r,o,a,h=t.tilemapLayer.tilemap,l=t.tilemapLayer,u=Math.floor(h.tileWidth*l.scaleX),c=Math.floor(h.tileHeight*l.scaleY),d=t.hexSideLength;if("y"===this.staggerAxis){var f=(c-d)/2+d;i=n(e.worldView.x-l.x,u,0,!0)-l.cullPaddingX,r=s(e.worldView.right-l.x,u,0,!0)+l.cullPaddingX,o=n(e.worldView.y-l.y,f,0,!0)-l.cullPaddingY,a=s(e.worldView.bottom-l.y,f,0,!0)+l.cullPaddingY}else{var p=(u-d)/2+d;i=n(e.worldView.x-l.x,p,0,!0)-l.cullPaddingX,r=s(e.worldView.right-l.x,p,0,!0)+l.cullPaddingX,o=n(e.worldView.y-l.y,c,0,!0)-l.cullPaddingY,a=s(e.worldView.bottom-l.y,c,0,!0)+l.cullPaddingY}return{left:i,right:r,top:o,bottom:a}}},37524:(t,e,i)=>{var s=i(6358),n=i(6987);t.exports=function(t,e,i,r){void 0===i&&(i=[]),void 0===r&&(r=0),i.length=0;var o=t.tilemapLayer,a=s(t,e);return o.skipCull&&1===o.scrollFactorX&&1===o.scrollFactorY&&(a.left=0,a.right=t.width,a.top=0,a.bottom=t.height),n(t,a,r,i),i}},63634:(t,e,i)=>{var s=i(21715),n=i(93736),r=new n;t.exports=function(t,e,i,o){var a=o.baseTileWidth,h=o.baseTileHeight,l=o.tilemapLayer;l&&(a*=l.scaleX,h*=l.scaleY);var u,c,d=s(t,e,r,i,o),f=[],p=.5773502691896257;"y"===this.staggerAxis?(u=p*a,c=h/2):(u=a/2,c=p*h);for(var v=0;v<6;v++){var g=2*Math.PI*(.5-v)/6;f.push(new n(d.x+u*Math.cos(g),d.y+c*Math.sin(g)))}return f}},21715:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n,r){i||(i=new s);var o=r.baseTileWidth,a=r.baseTileHeight,h=r.tilemapLayer,l=0,u=0;h&&(n||(n=h.scene.cameras.main),l=h.x+n.scrollX*(1-h.scrollFactorX),u=h.y+n.scrollY*(1-h.scrollFactorY),o*=h.scaleX,a*=h.scaleY);var c,d,f=o/2,p=a/2;return"y"===this.staggerAxis?(c=l+o*t+o,d=u+1.5*e*p+p,e%2==0&&("odd"===this.staggerIndex?c-=f:c+=f)):"x"===this.staggerAxis&&"odd"===this.staggerIndex&&(c=l+1.5*t*f+f,d=u+a*t+a,t%2==0&&("odd"===this.staggerIndex?d-=p:d+=p)),i.set(c,d)}},11516:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n,r,o){n||(n=new s);var a=o.baseTileWidth,h=o.baseTileHeight,l=o.tilemapLayer;l&&(r||(r=l.scene.cameras.main),t-=l.x+r.scrollX*(1-l.scrollFactorX),e-=l.y+r.scrollY*(1-l.scrollFactorY),a*=l.scaleX,h*=l.scaleY);var u,c,d,f,p,v=.5773502691896257,g=-.3333333333333333,m=.6666666666666666,y=a/2,x=h/2;"y"===o.staggerAxis?(d=v*(u=(t-y)/(v*a))+g*(c=(e-x)/x),f=0*u+m*c):(d=g*(u=(t-y)/y)+v*(c=(e-x)/(v*h)),f=m*u+0*c),p=-d-f;var T,w=Math.round(d),b=Math.round(f),S=Math.round(p),E=Math.abs(w-d),A=Math.abs(b-f),C=Math.abs(S-p);E>A&&E>C?w=-b-S:A>C&&(b=-w-S);var _=b;return T="odd"===o.staggerIndex?_%2==0?b/2+w:b/2+w-.5:_%2==0?b/2+w:b/2+w+.5,n.set(T,_)}},62839:t=>{t.exports=function(t,e,i){return t>=0&&t=0&&e{var s=i(13125);t.exports=function(t,e,i,n){void 0===i&&(i=[]),void 0===n&&(n=0),i.length=0;var r,o,a,h=t.tilemapLayer,l=t.data,u=t.width,c=t.height,d=h.skipCull,f=u,p=c;if(0===n){for(o=0;o=0;r--)if(d||s(r,o,t,e)){if(!(a=l[o][r])||-1===a.index||!a.visible||0===a.alpha)continue;i.push(a)}}else if(2===n){for(o=p;o>=0;o--)for(r=0;r=0;o--)for(r=f;r>=0;r--)if(d||s(r,o,t,e)){if(!(a=l[o][r])||-1===a.index||!a.visible||0===a.alpha)continue;i.push(a)}return h.tilesDrawn=i.length,h.tilesTotal=u*c,i}},21808:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n,r){i||(i=new s);var o=r.baseTileWidth,a=r.baseTileHeight,h=r.tilemapLayer,l=0,u=0;h&&(n||(n=h.scene.cameras.main),l=h.x+n.scrollX*(1-h.scrollFactorX),o*=h.scaleX,u=h.y+n.scrollY*(1-h.scrollFactorY),a*=h.scaleY);var c=l+o/2*(t-e),d=u+(t+e)*(a/2);return i.set(c,d)}},18750:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n,r,o,a){n||(n=new s);var h=o.baseTileWidth,l=o.baseTileHeight,u=o.tilemapLayer;u&&(r||(r=u.scene.cameras.main),e-=u.y+r.scrollY*(1-u.scrollFactorY),l*=u.scaleY,t-=u.x+r.scrollX*(1-u.scrollFactorX),h*=u.scaleX);var c=h/2,d=l/2;a||(e-=l);var f=.5*((t-=c)/c+e/d),p=.5*(-t/c+e/d);return i&&(f=Math.floor(f),p=Math.floor(p)),n.set(f,p)}},29003:(t,e,i)=>{var s=i(29633),n=i(62839),r=i(92839),o=i(68234);t.exports=function(t,e,i,a,h){if(void 0===a&&(a=!0),!n(e,i,h))return null;var l,u=h.data[i][e],c=u&&u.collides;t instanceof s?(null===h.data[i][e]&&(h.data[i][e]=new s(h,t.index,e,i,h.tileWidth,h.tileHeight)),h.data[i][e].copy(t)):(l=t,null===h.data[i][e]?h.data[i][e]=new s(h,l,e,i,h.tileWidth,h.tileHeight):h.data[i][e].index=l);var d=h.data[i][e],f=-1!==h.collideIndexes.indexOf(d.index);if(-1===(l=t instanceof s?t.index:t))d.width=h.tileWidth,d.height=h.tileHeight;else{var p=h.tilemapLayer.tilemap.tiles[l][2],v=h.tilemapLayer.tileset[p];d.width=v.tileWidth,d.height=v.tileHeight}return o(d,f),a&&c!==d.collides&&r(e,i,h),d}},48565:(t,e,i)=>{var s=i(29003),n=new(i(93736));t.exports=function(t,e,i,r,o,a){return a.tilemapLayer.worldToTileXY(e,i,!0,n,o,a),s(t,n.x,n.y,r,a)}},56547:(t,e,i)=>{var s=i(60386),n=i(29003);t.exports=function(t,e,i,r,o){if(void 0===r&&(r=!0),!Array.isArray(t))return null;Array.isArray(t[0])||(t=[t]);for(var a=t.length,h=t[0].length,l=0;l{var s=i(50811),n=i(72861);t.exports=function(t,e,i,r,o,a){var h,l=s(t,e,i,r,{},a);if(!o)for(o=[],h=0;h{var s=i(29633),n=i(62839),r=i(92839);t.exports=function(t,e,i,o,a){if(void 0===i&&(i=!0),void 0===o&&(o=!0),!n(t,e,a))return null;var h=a.data[e][t];return h?(a.data[e][t]=i?null:new s(a,-1,t,e,a.tileWidth,a.tileHeight),o&&h&&h.collides&&r(t,e,a),h):null}},17384:(t,e,i)=>{var s=i(929),n=new(i(93736));t.exports=function(t,e,i,r,o,a){return a.tilemapLayer.worldToTileXY(t,e,!0,n,o,a),s(n.x,n.y,i,r,a)}},93763:(t,e,i)=>{var s=i(50811),n=i(95509),r=new n(105,210,231,150),o=new n(243,134,48,200),a=new n(40,39,37,150);t.exports=function(t,e,i){void 0===e&&(e={});var n=void 0!==e.tileColor?e.tileColor:r,h=void 0!==e.collidingTileColor?e.collidingTileColor:o,l=void 0!==e.faceColor?e.faceColor:a,u=s(0,0,i.width,i.height,null,i);t.translateCanvas(i.tilemapLayer.x,i.tilemapLayer.y),t.scaleCanvas(i.tilemapLayer.scaleX,i.tilemapLayer.scaleY);for(var c=0;c{var s=i(50811);t.exports=function(t,e,i,n,r,o,a){for(var h=s(i,n,r,o,null,a),l=0;l{t.exports=function(t,e,i,s){var n,r,o,a=t.data,h=t.width,l=t.height,u=t.tilemapLayer,c=Math.max(0,e.left),d=Math.min(h,e.right),f=Math.max(0,e.top),p=Math.min(l,e.bottom);if(0===i)for(r=f;r=c;n--)(o=a[r][n])&&-1!==o.index&&o.visible&&0!==o.alpha&&s.push(o);else if(2===i)for(r=p;r>=f;r--)for(n=c;a[r]&&n=f;r--)for(n=d;a[r]&&n>=c;n--)(o=a[r][n])&&-1!==o.index&&o.visible&&0!==o.alpha&&s.push(o);return u.tilesDrawn=s.length,u.tilesTotal=h*l,s}},51710:(t,e,i)=>{var s=i(68234),n=i(60386),r=i(91181);t.exports=function(t,e,i,o,a){void 0===e&&(e=!0),void 0===i&&(i=!0),void 0===a&&(a=!0),Array.isArray(t)||(t=[t]);for(var h=0;h{var s=i(68234),n=i(60386),r=i(91181);t.exports=function(t,e,i,o,a,h){if(void 0===i&&(i=!0),void 0===o&&(o=!0),void 0===h&&(h=!0),!(t>e)){for(var l=t;l<=e;l++)r(l,i,a);if(h)for(var u=0;u=t&&d.index<=e&&s(d,i)}o&&n(0,0,a.width,a.height,a)}}},33158:(t,e,i)=>{var s=i(68234),n=i(60386),r=i(91181);t.exports=function(t,e,i,o){void 0===e&&(e=!0),void 0===i&&(i=!0),Array.isArray(t)||(t=[t]);for(var a=0;a{var s=i(68234),n=i(60386),r=i(19256);t.exports=function(t,e,i,o){void 0===e&&(e=!0),void 0===i&&(i=!0);for(var a=0;a{var s=i(68234),n=i(60386);t.exports=function(t,e,i){void 0===t&&(t=!0),void 0===e&&(e=!0);for(var r=0;r0&&s(a,t)}}e&&n(0,0,i.width,i.height,i)}},91181:t=>{t.exports=function(t,e,i){var s=i.collideIndexes.indexOf(t);e&&-1===s?i.collideIndexes.push(t):e||-1===s||i.collideIndexes.splice(s,1)}},68234:t=>{t.exports=function(t,e){e?t.setCollision(!0,!0,!0,!0,!1):t.resetCollision(!1)}},11628:t=>{t.exports=function(t,e,i,s){if("number"==typeof t)s.callbacks[t]=null!==e?{callback:e,callbackContext:i}:void 0;else for(var n=0,r=t.length;n{var s=i(50811);t.exports=function(t,e,i,n,r,o,a){for(var h=s(t,e,i,n,null,a),l=0;l{var s=i(50811),n=i(18592);t.exports=function(t,e,i,r,o){var a=s(t,e,i,r,null,o),h=a.map((function(t){return t.index}));n(h);for(var l=0;l{var s=i(82127),n=i(84314);t.exports=function(t,e){var i=t.tilemapLayer.tilemap,r=t.tilemapLayer,o=Math.floor(i.tileWidth*r.scaleX),a=Math.floor(i.tileHeight*r.scaleY);return{left:n(e.worldView.x-r.x,o,0,!0)-r.cullPaddingX,right:s(e.worldView.right-r.x,o,0,!0)+r.cullPaddingX,top:n(e.worldView.y-r.y,a/2,0,!0)-r.cullPaddingY,bottom:s(e.worldView.bottom-r.y,a/2,0,!0)+r.cullPaddingY}}},19242:(t,e,i)=>{var s=i(53945),n=i(6987);t.exports=function(t,e,i,r){void 0===i&&(i=[]),void 0===r&&(r=0),i.length=0;var o=t.tilemapLayer,a=s(t,e);return o.skipCull&&1===o.scrollFactorX&&1===o.scrollFactorY&&(a.left=0,a.right=t.width,a.top=0,a.bottom=t.height),n(t,a,r,i),i}},33388:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n,r){i||(i=new s);var o=r.baseTileWidth,a=r.baseTileHeight,h=r.tilemapLayer,l=0,u=0;h&&(n||(n=h.scene.cameras.main),l=h.x+n.scrollX*(1-h.scrollFactorX),o*=h.scaleX,u=h.y+n.scrollY*(1-h.scrollFactorY),a*=h.scaleY);var c=l+t*o+e%2*(o/2),d=u+e*(a/2);return i.set(c,d)}},84132:t=>{t.exports=function(t,e,i){var s=i.baseTileHeight,n=i.tilemapLayer,r=0;return n&&(void 0===e&&(e=n.scene.cameras.main),r=n.y+e.scrollY*(1-n.scrollFactorY),s*=n.scaleY),r+t*(s/2)+s}},90562:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n,r,o){n||(n=new s);var a=o.baseTileWidth,h=o.baseTileHeight,l=o.tilemapLayer;l&&(r||(r=l.scene.cameras.main),e-=l.y+r.scrollY*(1-l.scrollFactorY),h*=l.scaleY,t-=l.x+r.scrollX*(1-l.scrollFactorX),a*=l.scaleX);var u=i?Math.floor(e/(h/2)):e/(h/2),c=i?Math.floor((t+u%2*.5*a)/a):(t+u%2*.5*a)/a;return n.set(c,u)}},3689:t=>{t.exports=function(t,e,i,s){var n=s.baseTileHeight,r=s.tilemapLayer;return r&&(i||(i=r.scene.cameras.main),t-=r.y+i.scrollY*(1-r.scrollFactorY),n*=r.scaleY),e?Math.floor(t/(n/2)):t/(n/2)}},55217:(t,e,i)=>{var s=i(50811);t.exports=function(t,e,i,n,r,o,a){for(var h=s(i,n,r,o,null,a),l=0;l{t.exports=function(t,e,i){var s=i.baseTileWidth,n=i.tilemapLayer,r=0;return n&&(e||(e=n.scene.cameras.main),r=n.x+e.scrollX*(1-n.scrollFactorX),s*=n.scaleX),r+t*s}},46836:(t,e,i)=>{var s=i(44150),n=i(42477),r=i(93736);t.exports=function(t,e,i,o,a){return i||(i=new r(0,0)),i.x=s(t,o,a),i.y=n(e,o,a),i}},42477:t=>{t.exports=function(t,e,i){var s=i.baseTileHeight,n=i.tilemapLayer,r=0;return n&&(e||(e=n.scene.cameras.main),r=n.y+e.scrollY*(1-n.scrollFactorY),s*=n.scaleY),r+t*s}},39677:(t,e,i)=>{var s=i(50811);t.exports=function(t,e,i,n,r,o){if(r){var a,h=s(t,e,i,n,null,o),l=0;for(a=0;a{var s=i(45676),n=new(i(93736));t.exports=function(t,e,i,r){return s(t,0,e,n,i,r),n.x}},45676:(t,e,i)=>{var s=i(93736);t.exports=function(t,e,i,n,r,o){void 0===i&&(i=!0),n||(n=new s);var a=o.baseTileWidth,h=o.baseTileHeight,l=o.tilemapLayer;l&&(r||(r=l.scene.cameras.main),t-=l.x+r.scrollX*(1-l.scrollFactorX),e-=l.y+r.scrollY*(1-l.scrollFactorY),a*=l.scaleX,h*=l.scaleY);var u=t/a,c=e/h;return i&&(u=Math.floor(u),c=Math.floor(c)),n.set(u,c)}},70520:(t,e,i)=>{var s=i(45676),n=new(i(93736));t.exports=function(t,e,i,r){return s(0,t,e,n,i,r),n.y}},5047:(t,e,i)=>{t.exports={CalculateFacesAt:i(92839),CalculateFacesWithin:i(60386),CheckIsoBounds:i(13125),Copy:i(17347),CreateFromTiles:i(93604),CullBounds:i(71586),CullTiles:i(381),Fill:i(97734),FilterTiles:i(63555),FindByIndex:i(37982),FindTile:i(48297),ForEachTile:i(80916),GetCullTilesFunction:i(31493),GetTileAt:i(15494),GetTileAtWorldXY:i(24640),GetTileCorners:i(48495),GetTileCornersFunction:i(7160),GetTilesWithin:i(50811),GetTilesWithinShape:i(31674),GetTilesWithinWorldXY:i(44662),GetTileToWorldXFunction:i(16884),GetTileToWorldXYFunction:i(68182),GetTileToWorldYFunction:i(3752),GetWorldToTileXFunction:i(29296),GetWorldToTileXYFunction:i(32688),GetWorldToTileYFunction:i(74326),HasTileAt:i(46598),HasTileAtWorldXY:i(28654),HexagonalCullBounds:i(6358),HexagonalCullTiles:i(37524),HexagonalGetTileCorners:i(63634),HexagonalTileToWorldXY:i(21715),HexagonalWorldToTileXY:i(11516),IsInLayerBounds:i(62839),IsometricCullTiles:i(20887),IsometricTileToWorldXY:i(21808),IsometricWorldToTileXY:i(18750),PutTileAt:i(29003),PutTileAtWorldXY:i(48565),PutTilesAt:i(56547),Randomize:i(91180),RemoveTileAt:i(929),RemoveTileAtWorldXY:i(17384),RenderDebug:i(93763),ReplaceByIndex:i(51202),RunCull:i(6987),SetCollision:i(51710),SetCollisionBetween:i(15216),SetCollisionByExclusion:i(33158),SetCollisionByProperty:i(4180),SetCollisionFromCollisionGroup:i(18625),SetLayerCollisionIndex:i(91181),SetTileCollision:i(68234),SetTileIndexCallback:i(11628),SetTileLocationCallback:i(72732),Shuffle:i(34397),StaggeredCullBounds:i(53945),StaggeredCullTiles:i(19242),StaggeredTileToWorldXY:i(33388),StaggeredTileToWorldY:i(84132),StaggeredWorldToTileXY:i(90562),StaggeredWorldToTileY:i(3689),SwapByIndex:i(55217),TileToWorldX:i(44150),TileToWorldXY:i(46836),TileToWorldY:i(42477),WeightedRandomize:i(39677),WorldToTileX:i(806),WorldToTileXY:i(45676),WorldToTileY:i(70520)}},12920:t=>{t.exports={ORTHOGONAL:0,ISOMETRIC:1,STAGGERED:2,HEXAGONAL:3}},84758:(t,e,i)=>{var s={ORIENTATION:i(12920)};t.exports=s},52678:(t,e,i)=>{var s=i(98611),n=i(84758),r={Components:i(5047),Parsers:i(34124),Formats:i(93560),ImageCollection:i(97042),ParseToTilemap:i(15043),Tile:i(29633),Tilemap:i(89797),TilemapCreator:i(4843),TilemapFactory:i(37940),Tileset:i(47975),TilemapLayer:i(87177),Orientation:i(12920),LayerData:i(94990),MapData:i(16586),ObjectLayer:i(15256)};r=s(!1,r,n.ORIENTATION),t.exports=r},94990:(t,e,i)=>{var s=i(56694),n=i(12920),r=i(72632),o=new s({initialize:function(t){void 0===t&&(t={}),this.name=r(t,"name","layer"),this.x=r(t,"x",0),this.y=r(t,"y",0),this.width=r(t,"width",0),this.height=r(t,"height",0),this.tileWidth=r(t,"tileWidth",0),this.tileHeight=r(t,"tileHeight",0),this.baseTileWidth=r(t,"baseTileWidth",this.tileWidth),this.baseTileHeight=r(t,"baseTileHeight",this.tileHeight),this.orientation=r(t,"orientation",n.ORTHOGONAL),this.widthInPixels=r(t,"widthInPixels",this.width*this.baseTileWidth),this.heightInPixels=r(t,"heightInPixels",this.height*this.baseTileHeight),this.alpha=r(t,"alpha",1),this.visible=r(t,"visible",!0),this.properties=r(t,"properties",[]),this.indexes=r(t,"indexes",[]),this.collideIndexes=r(t,"collideIndexes",[]),this.callbacks=r(t,"callbacks",[]),this.bodies=r(t,"bodies",[]),this.data=r(t,"data",[]),this.tilemapLayer=r(t,"tilemapLayer",null),this.hexSideLength=r(t,"hexSideLength",0),this.staggerAxis=r(t,"staggerAxis","y"),this.staggerIndex=r(t,"staggerIndex","odd")}});t.exports=o},16586:(t,e,i)=>{var s=i(56694),n=i(12920),r=i(72632),o=new s({initialize:function(t){void 0===t&&(t={}),this.name=r(t,"name","map"),this.width=r(t,"width",0),this.height=r(t,"height",0),this.infinite=r(t,"infinite",!1),this.tileWidth=r(t,"tileWidth",0),this.tileHeight=r(t,"tileHeight",0),this.widthInPixels=r(t,"widthInPixels",this.width*this.tileWidth),this.heightInPixels=r(t,"heightInPixels",this.height*this.tileHeight),this.format=r(t,"format",null),this.orientation=r(t,"orientation",n.ORTHOGONAL),this.renderOrder=r(t,"renderOrder","right-down"),this.version=r(t,"version","1"),this.properties=r(t,"properties",{}),this.layers=r(t,"layers",[]),this.images=r(t,"images",[]),this.objects=r(t,"objects",[]),Array.isArray(this.objects)||(this.objects=[]),this.collision=r(t,"collision",{}),this.tilesets=r(t,"tilesets",[]),this.imageCollections=r(t,"imageCollections",[]),this.tiles=r(t,"tiles",[]),this.hexSideLength=r(t,"hexSideLength",0),this.staggerAxis=r(t,"staggerAxis","y"),this.staggerIndex=r(t,"staggerIndex","odd")}});t.exports=o},15256:(t,e,i)=>{var s=i(56694),n=i(72632),r=new s({initialize:function(t){void 0===t&&(t={}),this.name=n(t,"name","object layer"),this.opacity=n(t,"opacity",1),this.properties=n(t,"properties",{}),this.propertyTypes=n(t,"propertytypes",{}),this.type=n(t,"type","objectgroup"),this.visible=n(t,"visible",!0),this.objects=n(t,"objects",[]),Array.isArray(this.objects)||(this.objects=[])}});t.exports=r},21394:(t,e,i)=>{var s=i(12920);t.exports=function(t){return"isometric"===(t=t.toLowerCase())?s.ISOMETRIC:"staggered"===t?s.STAGGERED:"hexagonal"===t?s.HEXAGONAL:s.ORTHOGONAL}},90715:(t,e,i)=>{var s=i(93560),n=i(84346),r=i(96097),o=i(2378),a=i(44909);t.exports=function(t,e,i,h,l,u){var c;switch(e){case s.ARRAY_2D:c=n(t,i,h,l,u);break;case s.CSV:c=r(t,i,h,l,u);break;case s.TILED_JSON:c=o(t,i,u);break;case s.WELTMEISTER:c=a(t,i,u);break;default:console.warn("Unrecognized tilemap data format: "+e),c=null}return c}},84346:(t,e,i)=>{var s=i(93560),n=i(94990),r=i(16586),o=i(29633);t.exports=function(t,e,i,a,h){for(var l=new n({tileWidth:i,tileHeight:a}),u=new r({name:t,tileWidth:i,tileHeight:a,format:s.ARRAY_2D,layers:[l]}),c=[],d=e.length,f=0,p=0;p{var s=i(93560),n=i(84346);t.exports=function(t,e,i,r,o){var a=e.trim().split("\n").map((function(t){return t.split(",")})),h=n(t,a,i,r,o);return h.format=s.CSV,h}},30951:(t,e,i)=>{var s=i(94990),n=i(29633);t.exports=function(t,e){for(var i=[],r=0;r-1?new n(a,f,c,u,o.tilesize,o.tilesize):e?null:new n(a,-1,c,u,o.tilesize,o.tilesize),h.push(d)}l.push(h),h=[]}a.data=l,i.push(a)}return i}},47488:(t,e,i)=>{var s=i(47975);t.exports=function(t){for(var e=[],i=[],n=0;n{var s=i(93560),n=i(16586),r=i(30951),o=i(47488);t.exports=function(t,e,i){if(0===e.layer.length)return console.warn("No layers found in the Weltmeister map: "+t),null;for(var a=0,h=0,l=0;la&&(a=e.layer[l].width),e.layer[l].height>h&&(h=e.layer[l].height);var u=new n({width:a,height:h,name:t,tileWidth:e.layer[0].tilesize,tileHeight:e.layer[0].tilesize,format:s.WELTMEISTER});return u.layers=r(e,i),u.tilesets=o(e),u}},24507:(t,e,i)=>{t.exports={ParseTileLayers:i(30951),ParseTilesets:i(47488),ParseWeltmeister:i(44909)}},34124:(t,e,i)=>{t.exports={FromOrientationString:i(21394),Parse:i(90715),Parse2DArray:i(84346),ParseCSV:i(96097),Impact:i(24507),Tiled:i(50044)}},48646:(t,e,i)=>{var s=i(98611);t.exports=function(t){for(var e,i,n,r,o,a=0;a{t.exports=function(t){for(var e=window.atob(t),i=e.length,s=new Array(i/4),n=0;n>>0;return s}},14556:(t,e,i)=>{var s=i(47975);t.exports=function(t){var e,i,n=[];for(e=0;e{var s=i(72632);t.exports=function(t,e,i){if(!e)return{i:0,layers:t.layers,name:"",opacity:1,visible:!0,x:0,y:0};var n=e.x+s(e,"startx",0)*t.tilewidth+s(e,"offsetx",0),r=e.y+s(e,"starty",0)*t.tileheight+s(e,"offsety",0);return{i:0,layers:e.layers,name:i.name+e.name+"/",opacity:i.opacity*e.opacity,visible:i.visible&&e.visible,x:i.x+n,y:i.y+r}}},8847:t=>{var e=2147483648,i=1073741824,s=536870912;t.exports=function(t){var n=Boolean(t&e),r=Boolean(t&i),o=Boolean(t&s);t&=536870911;var a=0,h=!1;return n&&r&&o?(a=Math.PI/2,h=!0):n&&r&&!o?(a=Math.PI,h=!1):n&&!r&&o?(a=Math.PI/2,h=!1):!n||r||o?!n&&r&&o?(a=3*Math.PI/2,h=!1):n||!r||o?n||r||!o?n||r||o||(a=0,h=!1):(a=3*Math.PI/2,h=!0):(a=Math.PI,h=!0):(a=0,h=!0),{gid:t,flippedHorizontal:n,flippedVertical:r,flippedAntiDiagonal:o,rotation:a,flipped:h}}},78339:(t,e,i)=>{var s=i(72632),n=i(92044);t.exports=function(t){for(var e=[],i=[],r=n(t);r.i0;)if(r.i>=r.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}r=i.pop()}else{var o=r.layers[r.i];if(r.i++,"imagelayer"===o.type){var a=s(o,"offsetx",0)+s(o,"startx",0),h=s(o,"offsety",0)+s(o,"starty",0);e.push({name:r.name+o.name,image:o.image,x:r.x+a+o.x,y:r.y+h+o.y,alpha:r.opacity*o.opacity,visible:r.visible&&o.visible,properties:s(o,"properties",{})})}else if("group"===o.type){var l=n(t,o,r);i.push(r),r=l}}return e}},2378:(t,e,i)=>{var s=i(48646),n=i(14556),r=i(12920),o=i(28699),a=i(93560),h=i(21394),l=i(16586),u=i(78339),c=i(61136),d=i(95925),f=i(93392);t.exports=function(t,e,i){var p=o(e),v=new l({width:p.width,height:p.height,name:t,tileWidth:p.tilewidth,tileHeight:p.tileheight,orientation:h(p.orientation),format:a.TILED_JSON,version:p.version,properties:p.properties,renderOrder:p.renderorder,infinite:p.infinite});v.orientation===r.HEXAGONAL&&(v.hexSideLength=p.hexsidelength,v.staggerAxis=p.staggeraxis,v.staggerIndex=p.staggerindex),v.layers=d(p,i),v.images=u(p);var g=f(p);return v.tilesets=g.tilesets,v.imageCollections=g.imageCollections,v.objects=c(p),v.tiles=n(v),s(v),v}},4281:(t,e,i)=>{var s=i(28820),n=i(8847),r=function(t){return{x:t.x,y:t.y}},o=["id","name","type","rotation","properties","visible","x","y","width","height"];t.exports=function(t,e,i){void 0===e&&(e=0),void 0===i&&(i=0);var a=s(t,o);if(a.x+=e,a.y+=i,t.gid){var h=n(t.gid);a.gid=h.gid,a.flippedHorizontal=h.flippedHorizontal,a.flippedVertical=h.flippedVertical,a.flippedAntiDiagonal=h.flippedAntiDiagonal}else t.polyline?a.polyline=t.polyline.map(r):t.polygon?a.polygon=t.polygon.map(r):t.ellipse?a.ellipse=t.ellipse:t.text?a.text=t.text:t.point?a.point=!0:a.rectangle=!0;return a}},61136:(t,e,i)=>{var s=i(72632),n=i(4281),r=i(15256),o=i(92044);t.exports=function(t){for(var e=[],i=[],a=o(t);a.i0;)if(a.i>=a.layers.length){if(i.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}a=i.pop()}else{var h=a.layers[a.i];if(a.i++,h.opacity*=a.opacity,h.visible=a.visible&&h.visible,"objectgroup"===h.type){h.name=a.name+h.name;for(var l=a.x+s(h,"startx",0)+s(h,"offsetx",0),u=a.y+s(h,"starty",0)+s(h,"offsety",0),c=[],d=0;d{var s=i(43908),n=i(12920),r=i(92044),o=i(21394),a=i(72632),h=i(94990),l=i(8847),u=i(29633);t.exports=function(t,e){for(var i=a(t,"infinite",!1),c=[],d=[],f=r(t);f.i0;)if(f.i>=f.layers.length){if(d.length<1){console.warn("TilemapParser.parseTiledJSON - Invalid layer group hierarchy");break}f=d.pop()}else{var p=f.layers[f.i];if(f.i++,"tilelayer"===p.type)if(p.compression)console.warn("TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer '"+p.name+"'");else{if(p.encoding&&"base64"===p.encoding){if(p.chunks)for(var v=0;v0?((y=new u(g,m.gid,L,F,t.tilewidth,t.tileheight)).rotation=m.rotation,y.flipX=m.flipped,T[F][L]=y):(x=e?null:new u(g,-1,L,F,t.tilewidth,t.tileheight),T[F][L]=x),++w===C.width&&(P++,w=0)}}else{(g=new h({name:f.name+p.name,x:f.x+a(p,"offsetx",0)+p.x,y:f.y+a(p,"offsety",0)+p.y,width:p.width,height:p.height,tileWidth:t.tilewidth,tileHeight:t.tileheight,alpha:f.opacity*p.opacity,visible:f.visible&&p.visible,properties:a(p,"properties",[]),orientation:o(t.orientation)})).orientation===n.HEXAGONAL&&(g.hexSideLength=t.hexsidelength,g.staggerAxis=t.staggeraxis,g.staggerIndex=t.staggerindex);for(var D=[],I=0,k=p.data.length;I0?((y=new u(g,m.gid,w,T.length,t.tilewidth,t.tileheight)).rotation=m.rotation,y.flipX=m.flipped,D.push(y)):(x=e?null:new u(g,-1,w,T.length,t.tilewidth,t.tileheight),D.push(x)),++w===p.width&&(T.push(D),w=0,D=[])}g.data=T,c.push(g)}else if("group"===p.type){var B=r(t,p,f);d.push(f),f=B}}return c}},93392:(t,e,i)=>{var s=i(47975),n=i(97042),r=i(4281),o=i(39642);t.exports=function(t){for(var e,i=[],a=[],h=null,l=0;l1){var d=void 0,f=void 0;if(Array.isArray(u.tiles)){d=d||{},f=f||{};for(var p=0;p{t.exports=function(t,e){for(var i=0;i0){var r,o,a,h={},l={};if(Array.isArray(s.edgecolors))for(r=0;r{t.exports={AssignTileProperties:i(48646),Base64Decode:i(43908),BuildTilesetIndex:i(14556),CreateGroupLayer:i(92044),ParseGID:i(8847),ParseImageLayers:i(78339),ParseJSONTiled:i(2378),ParseObject:i(4281),ParseObjectLayers:i(61136),ParseTileLayers:i(95925),ParseTilesets:i(93392)}},73779:(t,e,i)=>{var s=i(56694),n=i(91963),r=i(7599),o=i(57911),a=i(66458),h=new s({initialize:function(t){this.scene=t,this.systems=t.sys,this.now=0,this.startTime=0,this.timeScale=1,this.paused=!1,this._active=[],this._pendingInsertion=[],this._pendingRemoval=[],t.sys.events.once(r.BOOT,this.boot,this),t.sys.events.on(r.START,this.start,this)},boot:function(){this.now=this.systems.game.loop.time,this.systems.events.once(r.DESTROY,this.destroy,this)},start:function(){this.startTime=this.systems.game.loop.time;var t=this.systems.events;t.on(r.PRE_UPDATE,this.preUpdate,this),t.on(r.UPDATE,this.update,this),t.once(r.SHUTDOWN,this.shutdown,this)},addEvent:function(t){var e;return t instanceof o?(e=t,this.removeEvent(e),e.elapsed=e.startAt,e.hasDispatched=!1,e.repeatCount=-1===e.repeat||e.loop?999999999999:e.repeat):e=new o(t),this._pendingInsertion.push(e),e},delayedCall:function(t,e,i,s){return this.addEvent({delay:t,callback:e,args:i,callbackScope:s})},clearPendingEvents:function(){return this._pendingInsertion=[],this},removeEvent:function(t){Array.isArray(t)||(t=[t]);for(var e=0;e-1&&this._active.splice(n,1),s.destroy()}for(i=0;i=s.delay)){var n=s.elapsed-s.delay;if(s.elapsed=s.delay,!s.hasDispatched&&s.callback&&(s.hasDispatched=!0,s.callback.apply(s.callbackScope,s.args)),s.repeatCount>0){if(s.repeatCount--,n>=s.delay)for(;n>=s.delay&&s.repeatCount>0;)s.callback&&s.callback.apply(s.callbackScope,s.args),n-=s.delay,s.repeatCount--;s.elapsed=n,s.hasDispatched=!1}else s.hasDispatched&&this._pendingRemoval.push(s)}}}},shutdown:function(){var t;for(t=0;t{var s=i(56694),n=i(6659),r=i(61286),o=i(72632),a=i(7599),h=new s({Extends:n,initialize:function(t,e){n.call(this),this.scene=t,this.systems=t.sys,this.elapsed=0,this.paused=!0,this.complete=!1,this.totalComplete=0,this.events=[];var i=this.systems.events;i.on(a.PRE_UPDATE,this.preUpdate,this),i.on(a.UPDATE,this.update,this),i.once(a.SHUTDOWN,this.destroy,this),e&&this.add(e)},preUpdate:function(t,e){this.paused||(this.elapsed+=e)},update:function(){if(!this.paused){var t,e,i=this.events,s=!1,n=this.systems;for(t=0;t=i.length&&(this.complete=!0)}},play:function(t){return void 0===t&&(t=!0),this.paused=!1,this.complete=!1,this.totalComplete=0,t&&this.reset(),this},pause:function(){return this.paused=!0,this},resume:function(){return this.paused=!1,this},stop:function(){return this.paused=!0,this.complete=!0,this},reset:function(){this.elapsed=0;for(var t=0;t0&&(i=e[e.length-1].time);for(var s=0;s{var s=i(56694),n=i(72632),r=new s({initialize:function(t){this.delay=0,this.repeat=0,this.repeatCount=0,this.loop=!1,this.callback,this.callbackScope,this.args,this.timeScale=1,this.startAt=0,this.elapsed=0,this.paused=!1,this.hasDispatched=!1,this.reset(t)},reset:function(t){if(this.delay=n(t,"delay",0),this.repeat=n(t,"repeat",0),this.loop=n(t,"loop",!1),this.callback=n(t,"callback",void 0),this.callbackScope=n(t,"callbackScope",this),this.args=n(t,"args",[]),this.timeScale=n(t,"timeScale",1),this.startAt=n(t,"startAt",0),this.paused=n(t,"paused",!1),this.elapsed=this.startAt,this.hasDispatched=!1,this.repeatCount=-1===this.repeat||this.loop?999999999999:this.repeat,0===this.delay&&(this.repeat>0||this.loop))throw new Error("TimerEvent infinite loop created via zero delay");return this},getProgress:function(){return this.elapsed/this.delay},getOverallProgress:function(){if(this.repeat>0){var t=this.delay+this.delay*this.repeat;return(this.elapsed+this.delay*(this.repeat-this.repeatCount))/t}return this.getProgress()},getRepeatCount:function(){return this.repeatCount},getElapsed:function(){return this.elapsed},getElapsedSeconds:function(){return.001*this.elapsed},getRemaining:function(){return this.delay-this.elapsed},getRemainingSeconds:function(){return.001*this.getRemaining()},getOverallRemaining:function(){return this.delay*(1+this.repeatCount)-this.elapsed},getOverallRemainingSeconds:function(){return.001*this.getOverallRemaining()},remove:function(t){void 0===t&&(t=!1),this.elapsed=this.delay,this.hasDispatched=!t,this.repeatCount=0},destroy:function(){this.callback=void 0,this.callbackScope=void 0,this.args=[]}});t.exports=r},97121:(t,e,i)=>{t.exports={Clock:i(73779),Timeline:i(20517),TimerEvent:i(57911)}},64532:(t,e,i)=>{var s=i(66458),n=i(56694),r=i(5454),o=i(68710),a=i(91963),h=i(7599),l=i(91944),u=i(39366),c=i(68061),d=i(45641),f=i(56034),p=new n({initialize:function(t){this.scene=t,this.events=t.sys.events,this.timeScale=1,this.paused=!1,this.processing=!1,this.tweens=[],this.time=0,this.startTime=0,this.nextTime=0,this.prevTime=0,this.maxLag=500,this.lagSkip=33,this.gap=1e3/240,this.events.once(h.BOOT,this.boot,this),this.events.on(h.START,this.start,this)},boot:function(){this.events.once(h.DESTROY,this.destroy,this)},start:function(){this.timeScale=1,this.paused=!1,this.startTime=Date.now(),this.prevTime=this.startTime,this.nextTime=this.gap,this.events.on(h.UPDATE,this.update,this),this.events.once(h.SHUTDOWN,this.shutdown,this)},create:function(t){Array.isArray(t)||(t=[t]);for(var e=[],i=0;i-1},existing:function(t){return this.has(t)||this.tweens.push(t.reset()),this},addCounter:function(t){var e=o(this,t);return this.tweens.push(e.reset()),e},stagger:function(t,e){return l(t,e)},setLagSmooth:function(t,e){return void 0===t&&(t=1/1e-8),void 0===e&&(e=0),this.maxLag=t,this.lagSkip=Math.min(e,this.maxLag),this},setFps:function(t){return void 0===t&&(t=240),this.gap=1e3/t,this.nextTime=1e3*this.time+this.gap,this},getDelta:function(t){var e=Date.now()-this.prevTime;e>this.maxLag&&(this.startTime+=e-this.lagSkip),this.prevTime+=e;var i=this.prevTime-this.startTime,s=i-this.nextTime,n=i-1e3*this.time;return s>0||t?(i/=1e3,this.time=i,this.nextTime+=s+(s>=this.gap?4:this.gap-s)):n=0,n},tick:function(){return this.step(!0),this},update:function(){this.paused||this.step(!1)},step:function(t){void 0===t&&(t=!1);var e=this.getDelta(t);if(!(e<=0)){var i,s;this.processing=!0;var n=[],r=this.tweens;for(i=0;i0){for(i=0;i-1&&(s.isPendingRemove()||s.isDestroyed())&&(r.splice(a,1),s.destroy())}n.length=0}this.processing=!1}},remove:function(t){return this.processing?t.setPendingRemoveState():(s(this.tweens,t),t.setRemovedState()),this},reset:function(t){return this.existing(t),t.seek(),t.setActiveState(),this},makeActive:function(t){return this.existing(t),t.setActiveState(),this},each:function(t,e){var i,s=[null];for(i=1;i{t.exports=function(t,e,i){return t&&t.hasOwnProperty(e)?t[e]:i}},21902:(t,e,i)=>{var s=i(35060),n=i(40587);t.exports=function(t,e){var i=s.Power0;if("string"==typeof t)if(s.hasOwnProperty(t))i=s[t];else{var r="";if(t.indexOf(".")){var o=(r=t.substring(t.indexOf(".")+1)).toLowerCase();"in"===o?r="easeIn":"out"===o?r="easeOut":"inout"===o&&(r="easeInOut")}t=n(t.substring(0,t.indexOf(".")+1)+r),s.hasOwnProperty(t)&&(i=s[t])}else"function"==typeof t&&(i=t);if(!e)return i;var a=e.slice(0);return a.unshift(0),function(t){return a[0]=t,i.apply(this,a)}}},4840:(t,e,i)=>{var s=i(63210),n=i(88332),r={bezier:s,catmull:n,catmullrom:n,linear:i(47614)};t.exports=function(t){if(null===t)return null;var e=r.linear;return"string"==typeof t?r.hasOwnProperty(t)&&(e=r[t]):"function"==typeof t&&(e=t),e}},28348:t=>{t.exports=function(t,e,i){var s;t.hasOwnProperty(e)?s="function"===typeof t[e]?function(i,s,n,r,o,a){return t[e](i,s,n,r,o,a)}:function(){return t[e]}:s="function"==typeof i?i:function(){return i};return s}},92407:(t,e,i)=>{var s=i(53709);t.exports=function(t){var e,i=[];if(t.hasOwnProperty("props"))for(e in t.props)"_"!==e.substring(0,1)&&i.push({key:e,value:t.props[e]});else for(e in t)-1===s.indexOf(e)&&"_"!==e.substring(0,1)&&i.push({key:e,value:t[e]});return i}},65868:(t,e,i)=>{var s=i(10850);t.exports=function(t){var e=s(t,"targets",null);return null===e||("function"==typeof e&&(e=e.call()),Array.isArray(e)||(e=[e])),e}},9744:(t,e,i)=>{var s=i(17489),n=i(61616);function r(t){return!!t.getActive&&"function"==typeof t.getActive}function o(t){return!!t.getStart&&"function"==typeof t.getStart}function a(t){return!!t.getEnd&&"function"==typeof t.getEnd}var h=function(t,e){var i,l,u=function(t,e,i){return i},c=function(t,e,i){return i},d=null,f=typeof e;if("number"===f)u=function(){return e};else if(Array.isArray(e))c=function(){return e[0]},u=function(){return e[e.length-1]};else if("string"===f){var p=e.toLowerCase(),v="random"===p.substring(0,6),g="int"===p.substring(0,3);if(v||g){var m=p.indexOf("("),y=p.indexOf(")"),x=p.indexOf(",");if(!(m&&y&&x))throw new Error("invalid random() format");var T=parseFloat(p.substring(m+1,x)),w=parseFloat(p.substring(x+1,y));u=v?function(){return n(T,w)}:function(){return s(T,w)}}else{p=p[0];var b=parseFloat(e.substr(2));switch(p){case"+":u=function(t,e,i){return i+b};break;case"-":u=function(t,e,i){return i-b};break;case"*":u=function(t,e,i){return i*b};break;case"/":u=function(t,e,i){return i/b};break;default:u=function(){return parseFloat(e)}}}}else if("function"===f)u=e;else if("object"===f)if(o(l=e)||a(l)||r(l))r(e)&&(d=e.getActive),a(e)&&(u=e.getEnd),o(e)&&(c=e.getStart);else if(e.hasOwnProperty("value"))i=h(t,e.value);else{var S=e.hasOwnProperty("to"),E=e.hasOwnProperty("from"),A=e.hasOwnProperty("start");if(S&&(E||A)){if(i=h(t,e.to),A){var C=h(t,e.start);i.getActive=C.getEnd}if(E){var _=h(t,e.from);i.getStart=_.getEnd}}}return i||(i={getActive:d,getEnd:u,getStart:c}),i};t.exports=h},68710:(t,e,i)=>{var s=i(502),n=i(99730),r=i(20494),o=i(63130),a=i(21902),h=i(28348),l=i(10850),u=i(9744),c=i(72066),d=i(39366);t.exports=function(t,e,i){if(e instanceof d)return e.parent=t,e;i=void 0===i?n:c(n,i);var f=l(e,"from",0),p=l(e,"to",1),v=[{value:f}],g=l(e,"delay",i.delay),m=l(e,"easeParams",i.easeParams),y=l(e,"ease",i.ease),x=u("value",p),T=new d(t,v),w=T.add(0,"value",x.getEnd,x.getStart,x.getActive,a(l(e,"ease",y),l(e,"easeParams",m)),h(e,"delay",g),l(e,"duration",i.duration),o(e,"yoyo",i.yoyo),l(e,"hold",i.hold),l(e,"repeat",i.repeat),l(e,"repeatDelay",i.repeatDelay),!1,!1);w.start=f,w.current=f,T.completeDelay=r(e,"completeDelay",0),T.loop=Math.round(r(e,"loop",0)),T.loopDelay=Math.round(r(e,"loopDelay",0)),T.paused=o(e,"paused",!1),T.persist=o(e,"persist",!1),T.callbackScope=l(e,"callbackScope",T);for(var b=s.TYPES,S=0;S{var s=i(21902),n=i(10850),r=i(83392);t.exports=function(t,e){var i;void 0===e&&(e={});var o=n(e,"start",0),a=n(e,"ease",null),h=n(e,"grid",null),l=n(e,"from",0),u="first"===l,c="center"===l,d="last"===l,f="number"==typeof l,p=Array.isArray(t),v=p?parseFloat(t[0]):parseFloat(t),g=p?parseFloat(t[1]):0,m=Math.max(v,g);if(p&&(o+=v),h){var y=h[0],x=h[1],T=0,w=0,b=0,S=0,E=[];d?(T=y-1,w=x-1):f?(T=l%y,w=Math.floor(l/y)):c&&(T=(y-1)/2,w=(x-1)/2);for(var A=r.MIN_SAFE_INTEGER,C=0;CA&&(A=M),E[C][_]=M}}}var P=a?s(a):null;return i=h?function(t,e,i,s){var n,r=0,a=s%y,h=Math.floor(s/y);if(a>=0&&a=0&&h{var s=i(502),n=i(99730),r=i(20494),o=i(63130),a=i(21902),h=i(4840),l=i(28348),u=i(92407),c=i(65868),d=i(10850),f=i(9744),p=i(72066),v=i(39366);t.exports=function(t,e,i){if(e instanceof v)return e.parent=t,e;i=void 0===i?n:p(n,i);var g=c(e);!g&&i.targets&&(g=i.targets);for(var m=u(e),y=d(e,"delay",i.delay),x=d(e,"duration",i.duration),T=d(e,"easeParams",i.easeParams),w=d(e,"ease",i.ease),b=d(e,"hold",i.hold),S=d(e,"repeat",i.repeat),E=d(e,"repeatDelay",i.repeatDelay),A=o(e,"yoyo",i.yoyo),C=o(e,"flipX",i.flipX),_=o(e,"flipY",i.flipY),M=d(e,"interpolation",i.interpolation),P=function(t,e,i,s){if("texture"===i){var n=s,r=void 0;Array.isArray(s)?(n=s[0],r=s[1]):s.hasOwnProperty("value")?(n=s.value,Array.isArray(s.value)?(n=s.value[0],r=s.value[1]):"string"==typeof s.value&&(n=s.value)):"string"==typeof s&&(n=s),t.addFrame(e,n,r,l(s,"delay",y),d(s,"duration",x),d(s,"hold",b),d(s,"repeat",S),d(s,"repeatDelay",E),o(s,"flipX",C),o(s,"flipY",_))}else{var u=f(i,s),c=h(d(s,"interpolation",M));t.add(e,i,u.getEnd,u.getStart,u.getActive,a(d(s,"ease",w),d(s,"easeParams",T)),l(s,"delay",y),d(s,"duration",x),o(s,"yoyo",A),d(s,"hold",b),d(s,"repeat",S),d(s,"repeatDelay",E),o(s,"flipX",C),o(s,"flipY",_),c,c?s:null)}},R=new v(t,g),O=0;O{var s=i(502),n=i(20494),r=i(63130),o=i(65868),a=i(10850),h=i(68061),l=i(45641);t.exports=function(t,e){if(e instanceof l)return e.parent=t,e;var i,u=new l(t);u.startDelay=a(e,"delay",0),u.completeDelay=n(e,"completeDelay",0),u.loop=Math.round(n(e,"loop",a(e,"repeat",0))),u.loopDelay=Math.round(n(e,"loopDelay",a(e,"repeatDelay",0))),u.paused=r(e,"paused",!1),u.persist=r(e,"persist",!0),u.callbackScope=a(e,"callbackScope",u);var c=s.TYPES;for(i=0;i{t.exports={GetBoolean:i(63130),GetEaseFunction:i(21902),GetInterpolationFunction:i(4840),GetNewValue:i(28348),GetProps:i(92407),GetTargets:i(65868),GetValueOp:i(9744),NumberTweenBuilder:i(68710),StaggerBuilder:i(91944),TweenBuilder:i(68061)}},5570:t=>{t.exports="active"},6383:t=>{t.exports="complete"},72582:t=>{t.exports="loop"},90281:t=>{t.exports="pause"},80803:t=>{t.exports="repeat"},13640:t=>{t.exports="resume"},10472:t=>{t.exports="start"},5379:t=>{t.exports="stop"},43449:t=>{t.exports="update"},61541:t=>{t.exports="yoyo"},54272:(t,e,i)=>{t.exports={TWEEN_ACTIVE:i(5570),TWEEN_COMPLETE:i(6383),TWEEN_LOOP:i(72582),TWEEN_PAUSE:i(90281),TWEEN_RESUME:i(13640),TWEEN_REPEAT:i(80803),TWEEN_START:i(10472),TWEEN_STOP:i(5379),TWEEN_UPDATE:i(43449),TWEEN_YOYO:i(61541)}},75193:(t,e,i)=>{var s={States:i(55303),Builders:i(79619),Events:i(54272),TweenManager:i(64532),Tween:i(39366),TweenData:i(15718),TweenFrameData:i(96490),BaseTween:i(502),TweenChain:i(45641)};t.exports=s},502:(t,e,i)=>{var s=i(56694),n=i(6659),r=i(54272),o=i(55303),a=new s({Extends:n,initialize:function(t){n.call(this),this.parent=t,this.data=[],this.totalData=0,this.startDelay=0,this.hasStarted=!1,this.timeScale=1,this.loop=0,this.loopDelay=0,this.loopCounter=0,this.completeDelay=0,this.countdown=0,this.state=o.PENDING,this.paused=!1,this.callbacks={onActive:null,onComplete:null,onLoop:null,onPause:null,onRepeat:null,onResume:null,onStart:null,onStop:null,onUpdate:null,onYoyo:null},this.callbackScope,this.persist=!1},setTimeScale:function(t){return this.timeScale=t,this},getTimeScale:function(){return this.timeScale},isPlaying:function(){return!this.paused&&this.isActive()},isPaused:function(){return this.paused},pause:function(){return this.paused||(this.paused=!0,this.dispatchEvent(r.TWEEN_PAUSE,"onPause")),this},resume:function(){return this.paused&&(this.paused=!1,this.dispatchEvent(r.TWEEN_RESUME,"onResume")),this},makeActive:function(){this.parent.makeActive(this),this.dispatchEvent(r.TWEEN_ACTIVE,"onActive")},onCompleteHandler:function(){this.setPendingRemoveState(),this.dispatchEvent(r.TWEEN_COMPLETE,"onComplete")},complete:function(t){return void 0===t&&(t=0),t?(this.setCompleteDelayState(),this.countdown=t):this.onCompleteHandler(),this},completeAfterLoop:function(t){return void 0===t&&(t=0),this.loopCounter>t&&(this.loopCounter=t),this},remove:function(){return this.parent.remove(this),this},stop:function(){return this.isRemoved()||this.isPendingRemove()||this.isDestroyed()||(this.dispatchEvent(r.TWEEN_STOP,"onStop"),this.setPendingRemoveState()),this},updateLoopCountdown:function(t){this.countdown-=t,this.countdown<=0&&(this.setActiveState(),this.dispatchEvent(r.TWEEN_LOOP,"onLoop"))},updateStartCountdown:function(t){return this.countdown-=t,this.countdown<=0&&(this.hasStarted=!0,this.setActiveState(),this.dispatchEvent(r.TWEEN_START,"onStart"),t=0),t},updateCompleteDelay:function(t){this.countdown-=t,this.countdown<=0&&this.onCompleteHandler()},setCallback:function(t,e,i){return void 0===i&&(i=[]),this.callbacks.hasOwnProperty(t)&&(this.callbacks[t]={func:e,params:i}),this},setPendingState:function(){this.state=o.PENDING},setActiveState:function(){this.state=o.ACTIVE},setLoopDelayState:function(){this.state=o.LOOP_DELAY},setCompleteDelayState:function(){this.state=o.COMPLETE_DELAY},setStartDelayState:function(){this.state=o.START_DELAY,this.countdown=this.startDelay,this.hasStarted=!1},setPendingRemoveState:function(){this.state=o.PENDING_REMOVE},setRemovedState:function(){this.state=o.REMOVED},setFinishedState:function(){this.state=o.FINISHED},setDestroyedState:function(){this.state=o.DESTROYED},isPending:function(){return this.state===o.PENDING},isActive:function(){return this.state===o.ACTIVE},isLoopDelayed:function(){return this.state===o.LOOP_DELAY},isCompleteDelayed:function(){return this.state===o.COMPLETE_DELAY},isStartDelayed:function(){return this.state===o.START_DELAY},isPendingRemove:function(){return this.state===o.PENDING_REMOVE},isRemoved:function(){return this.state===o.REMOVED},isFinished:function(){return this.state===o.FINISHED},isDestroyed:function(){return this.state===o.DESTROYED},destroy:function(){this.data&&this.data.forEach((function(t){t.destroy()})),this.removeAllListeners(),this.callbacks=null,this.data=null,this.parent=null,this.setDestroyedState()}});a.TYPES=["onActive","onComplete","onLoop","onPause","onRepeat","onResume","onStart","onStop","onUpdate","onYoyo"],t.exports=a},65521:(t,e,i)=>{var s=i(56694),n=i(54272),r=i(55303),o=new s({initialize:function(t,e,i,s,n,r,o,a,h,l){this.tween=t,this.targetIndex=e,this.duration=s,this.totalDuration=0,this.delay=0,this.getDelay=i,this.yoyo=n,this.hold=r,this.repeat=o,this.repeatDelay=a,this.repeatCounter=0,this.flipX=h,this.flipY=l,this.progress=0,this.elapsed=0,this.state=0,this.isCountdown=!1},getTarget:function(){return this.tween.targets[this.targetIndex]},setTargetValue:function(t){void 0===t&&(t=this.current),this.tween.targets[this.targetIndex][this.key]=t},setCreatedState:function(){this.state=r.CREATED,this.isCountdown=!1},setDelayState:function(){this.state=r.DELAY,this.isCountdown=!0},setPendingRenderState:function(){this.state=r.PENDING_RENDER,this.isCountdown=!1},setPlayingForwardState:function(){this.state=r.PLAYING_FORWARD,this.isCountdown=!1},setPlayingBackwardState:function(){this.state=r.PLAYING_BACKWARD,this.isCountdown=!1},setHoldState:function(){this.state=r.HOLD_DELAY,this.isCountdown=!0},setRepeatState:function(){this.state=r.REPEAT_DELAY,this.isCountdown=!0},setCompleteState:function(){this.state=r.COMPLETE,this.isCountdown=!1},isCreated:function(){return this.state===r.CREATED},isDelayed:function(){return this.state===r.DELAY},isPendingRender:function(){return this.state===r.PENDING_RENDER},isPlayingForward:function(){return this.state===r.PLAYING_FORWARD},isPlayingBackward:function(){return this.state===r.PLAYING_BACKWARD},isHolding:function(){return this.state===r.HOLD_DELAY},isRepeating:function(){return this.state===r.REPEAT_DELAY},isComplete:function(){return this.state===r.COMPLETE},setStateFromEnd:function(t){this.yoyo?this.onRepeat(t,!0,!0):this.repeatCounter>0?this.onRepeat(t,!0,!1):this.setCompleteState()},setStateFromStart:function(t){this.repeatCounter>0?this.onRepeat(t,!1):this.setCompleteState()},reset:function(){var t=this.tween,e=t.totalTargets,i=this.targetIndex,s=t.targets[i],n=this.key;this.progress=0,this.elapsed=0,this.delay=this.getDelay(s,n,0,i,e,t),this.repeatCounter=-1===this.repeat?r.MAX:this.repeat,this.setPendingRenderState();var o=this.duration+this.hold;this.yoyo&&(o+=this.duration);var a=o+this.repeatDelay;this.totalDuration=this.delay+o,-1===this.repeat?(this.totalDuration+=a*r.MAX,t.isInfinite=!0):this.repeat>0&&(this.totalDuration+=a*this.repeat),this.totalDuration>t.duration&&(t.duration=this.totalDuration),this.delay0&&(this.elapsed=this.delay,this.setDelayState())},onRepeat:function(t,e,i){var s=this.tween,r=s.totalTargets,o=this.targetIndex,a=s.targets[o],h=this.key,l="texture"!==h;if(this.elapsed=t,this.progress=t/this.duration,this.flipX&&a.toggleFlipX(),this.flipY&&a.toggleFlipY(),l&&(e||i)&&(this.start=this.getStartValue(a,h,this.start,o,r,s)),i)return this.setPlayingBackwardState(),void this.dispatchEvent(n.TWEEN_YOYO,"onYoyo");this.repeatCounter--,l&&(this.end=this.getEndValue(a,h,this.start,o,r,s)),this.repeatDelay>0?(this.elapsed=this.repeatDelay-t,l&&(this.current=this.start,a[h]=this.current),this.setRepeatState()):(this.setPlayingForwardState(),this.dispatchEvent(n.TWEEN_REPEAT,"onRepeat"))},destroy:function(){this.tween=null,this.getDelay=null,this.setCompleteState()}});t.exports=o},99730:t=>{t.exports={targets:null,delay:0,duration:1e3,ease:"Power0",easeParams:null,hold:0,repeat:0,repeatDelay:0,yoyo:!1,flipX:!1,flipY:!1,persist:!1,interpolation:null}},53709:t=>{t.exports=["callbackScope","completeDelay","delay","duration","ease","easeParams","flipX","flipY","hold","interpolation","loop","loopDelay","onActive","onActiveParams","onComplete","onCompleteParams","onLoop","onLoopParams","onPause","onPauseParams","onRepeat","onRepeatParams","onResume","onResumeParams","onStart","onStartParams","onStop","onStopParams","onUpdate","onUpdateParams","onYoyo","onYoyoParams","paused","persist","props","repeat","repeatDelay","targets","yoyo"]},39366:(t,e,i)=>{var s=i(502),n=i(56694),r=i(54272),o=i(99325),a=i(61286),h=i(83392),l=i(55303),u=i(15718),c=i(96490),d=new n({Extends:s,initialize:function(t,e){s.call(this,t),this.targets=e,this.totalTargets=e.length,this.isSeeking=!1,this.isInfinite=!1,this.elapsed=0,this.totalElapsed=0,this.duration=0,this.progress=0,this.totalDuration=0,this.totalProgress=0},add:function(t,e,i,s,n,r,o,a,h,l,c,d,f,p,v,g){var m=new u(this,t,e,i,s,n,r,o,a,h,l,c,d,f,p,v,g);return this.totalData=this.data.push(m),m},addFrame:function(t,e,i,s,n,r,o,a,h,l){var u=new c(this,t,e,i,s,n,r,o,a,h,l);return this.totalData=this.data.push(u),u},getValue:function(t){void 0===t&&(t=0);var e=null;return this.data&&(e=this.data[t].current),e},hasTarget:function(t){return this.targets&&-1!==this.targets.indexOf(t)},updateTo:function(t,e,i){if(void 0===i&&(i=!1),"texture"!==t)for(var s=0;s0)this.elapsed=0,this.progress=0,this.loopCounter--,this.initTweenData(!0),this.loopDelay>0?(this.countdown=this.loopDelay,this.setLoopDelayState()):(this.setActiveState(),this.dispatchEvent(r.TWEEN_LOOP,"onLoop"));else{if(!(this.completeDelay>0))return this.onCompleteHandler(),!0;this.countdown=this.completeDelay,this.setCompleteDelayState()}return!1},onCompleteHandler:function(){this.progress=1,this.totalProgress=1,s.prototype.onCompleteHandler.call(this)},play:function(){return this.isDestroyed()?(console.warn("Cannot play destroyed Tween",this),this):((this.isPendingRemove()||this.isFinished())&&this.seek(),this.paused=!1,this.setActiveState(),this)},seek:function(t,e,i){if(void 0===t&&(t=0),void 0===e&&(e=16.6),void 0===i&&(i=!1),this.isDestroyed())return console.warn("Cannot seek destroyed Tween",this),this;i||(this.isSeeking=!0),this.reset(!0),this.initTweenData(!0),this.setActiveState(),this.dispatchEvent(r.TWEEN_ACTIVE,"onActive");var s=this.paused;if(this.paused=!1,t>0){for(var n=Math.floor(t/e),o=t-n*e,a=0;a0&&this.update(o)}return this.paused=s,this.isSeeking=!1,this},initTweenData:function(t){void 0===t&&(t=!1),this.duration=0,this.startDelay=h.MAX_SAFE_INTEGER;for(var e=this.data,i=0;i0?s+n+(s+o)*r:s+n},reset:function(t){return void 0===t&&(t=!1),this.elapsed=0,this.totalElapsed=0,this.progress=0,this.totalProgress=0,this.loopCounter=this.loop,-1===this.loop&&(this.isInfinite=!0,this.loopCounter=l.MAX),t||(this.initTweenData(),this.setActiveState(),this.dispatchEvent(r.TWEEN_ACTIVE,"onActive")),this},update:function(t){if(this.isPendingRemove()||this.isDestroyed())return!0;if(this.paused||this.isFinished())return!1;if(t*=this.timeScale*this.parent.timeScale,this.isLoopDelayed())return this.updateLoopCountdown(t),!1;if(this.isCompleteDelayed())return this.updateCompleteDelay(t),!1;this.hasStarted||(this.startDelay-=t,this.startDelay<=0&&(this.hasStarted=!0,this.dispatchEvent(r.TWEEN_START,"onStart"),t=0));var e=!1;if(this.isActive())for(var i=this.data,s=0;s{var s=i(66458),n=i(502),r=i(56694),o=i(54272),a=i(99325),h=i(61286),l=i(55303),u=new r({Extends:n,initialize:function(t){n.call(this,t),this.currentTween=null,this.currentIndex=0},init:function(){return this.loopCounter=-1===this.loop?l.MAX:this.loop,this.setCurrentTween(0),this.startDelay>0&&!this.isStartDelayed()?this.setStartDelayState():this.setActiveState(),this.dispatchEvent(o.TWEEN_ACTIVE,"onActive"),this},add:function(t){var e=this.parent.create(t);Array.isArray(e)||(e=[e]);for(var i=this.data,s=0;s0)this.loopCounter--,this.resetTweens(),this.loopDelay>0?(this.countdown=this.loopDelay,this.setLoopDelayState()):(this.setActiveState(),this.dispatchEvent(o.TWEEN_LOOP,"onLoop"));else{if(!(this.completeDelay>0))return this.onCompleteHandler(),!0;this.countdown=this.completeDelay,this.setCompleteDelayState()}return!1},play:function(){return this.isDestroyed()?(console.warn("Cannot play destroyed TweenChain",this),this):((this.isPendingRemove()||this.isPending())&&this.resetTweens(),this.paused=!1,this.startDelay>0&&!this.isStartDelayed()?this.setStartDelayState():this.setActiveState(),this)},resetTweens:function(){for(var t=this.data,e=this.totalData,i=0;i{var s=i(65521),n=i(82897),r=i(56694),o=i(54272),a=new r({Extends:s,initialize:function(t,e,i,n,r,o,a,h,l,u,c,d,f,p,v,g,m){s.call(this,t,e,h,l,u,c,d,f,p,v),this.key=i,this.getActiveValue=o,this.getEndValue=n,this.getStartValue=r,this.ease=a,this.start=0,this.previous=0,this.current=0,this.end=0,this.interpolation=g,this.interpolationData=m},reset:function(t){s.prototype.reset.call(this);var e=this.tween.targets[this.targetIndex],i=this.key;t&&(e[i]=this.start),this.start=0,this.previous=0,this.current=0,this.end=0,this.getActiveValue&&(e[i]=this.getActiveValue(e,i,0))},update:function(t){var e=this.tween,i=e.totalTargets,s=this.targetIndex,r=e.targets[s],a=this.key;if(!r)return this.setCompleteState(),!1;if(this.isCountdown&&(this.elapsed-=t,this.elapsed<=0&&(this.elapsed=0,t=0,this.isDelayed()?this.setPendingRenderState():this.isRepeating()?(this.setPlayingForwardState(),this.dispatchEvent(o.TWEEN_REPEAT,"onRepeat")):this.isHolding()&&this.setStateFromEnd(0))),this.isPendingRender())return this.start=this.getStartValue(r,a,r[a],s,i,e),this.end=this.getEndValue(r,a,this.start,s,i,e),this.current=this.start,r[a]=this.start,this.setPlayingForwardState(),!0;var h=this.isPlayingForward(),l=this.isPlayingBackward();if(h||l){var u=this.elapsed,c=this.duration,d=0,f=!1;(u+=t)>=c?(d=u-c,u=c,f=!0):u<0&&(u=0);var p=n(u/c,0,1);if(this.elapsed=u,this.progress=p,this.previous=this.current,f)h?(this.current=this.end,r[a]=this.end,this.hold>0?(this.elapsed=this.hold,this.setHoldState()):this.setStateFromEnd(d)):(this.current=this.start,r[a]=this.start,this.setStateFromStart(d));else{h||(p=1-p);var v=this.ease(p);this.interpolation?this.current=this.interpolation(this.interpolationData,v):this.current=this.start+(this.end-this.start)*v,r[a]=this.current}this.dispatchEvent(o.TWEEN_UPDATE,"onUpdate")}return!this.isComplete()},dispatchEvent:function(t,e){var i=this.tween;if(!i.isSeeking){var s=i.targets[this.targetIndex],n=this.key,r=this.current,o=this.previous;i.emit(t,i,n,s,r,o);var a=i.callbacks[e];a&&a.func.apply(i.callbackScope,[i,s,n,r,o].concat(a.params))}},destroy:function(){s.prototype.destroy.call(this),this.getActiveValue=null,this.getEndValue=null,this.getStartValue=null,this.ease=null}});t.exports=a},96490:(t,e,i)=>{var s=i(65521),n=i(82897),r=i(56694),o=i(54272),a=new r({Extends:s,initialize:function(t,e,i,n,r,o,a,h,l,u,c){s.call(this,t,e,r,o,!1,a,h,l,u,c),this.key="texture",this.startTexture=null,this.endTexture=i,this.startFrame=null,this.endFrame=n,this.yoyo=0!==h},reset:function(t){s.prototype.reset.call(this);var e=this.tween.targets[this.targetIndex];this.startTexture||(this.startTexture=e.texture.key,this.startFrame=e.frame.name),t&&e.setTexture(this.startTexture,this.startFrame)},update:function(t){var e=this.tween,i=this.targetIndex,s=e.targets[i];if(!s)return this.setCompleteState(),!1;if(this.isCountdown&&(this.elapsed-=t,this.elapsed<=0&&(this.elapsed=0,t=0,this.isDelayed()?this.setPendingRenderState():this.isRepeating()?(this.setPlayingForwardState(),this.dispatchEvent(o.TWEEN_REPEAT,"onRepeat")):this.isHolding()&&this.setStateFromEnd(0))),this.isPendingRender())return this.startTexture&&s.setTexture(this.startTexture,this.startFrame),this.setPlayingForwardState(),!0;var r=this.isPlayingForward(),a=this.isPlayingBackward();if(r||a){var h=this.elapsed,l=this.duration,u=0,c=!1;(h+=t)>=l?(u=h-l,h=l,c=!0):h<0&&(h=0);var d=n(h/l,0,1);this.elapsed=h,this.progress=d,c&&(r?(s.setTexture(this.endTexture,this.endFrame),this.hold>0?(this.elapsed=this.hold,this.setHoldState()):this.setStateFromEnd(u)):(s.setTexture(this.startTexture,this.startFrame),this.setStateFromStart(u))),this.dispatchEvent(o.TWEEN_UPDATE,"onUpdate")}return!this.isComplete()},dispatchEvent:function(t,e){var i=this.tween;if(!i.isSeeking){var s=i.targets[this.targetIndex],n=this.key;i.emit(t,i,n,s);var r=i.callbacks[e];r&&r.func.apply(i.callbackScope,[i,s,n].concat(r.params))}},destroy:function(){s.prototype.destroy.call(this),this.startTexture=null,this.endTexture=null,this.startFrame=null,this.endFrame=null}});t.exports=a},55303:t=>{t.exports={CREATED:0,DELAY:2,PENDING_RENDER:4,PLAYING_FORWARD:5,PLAYING_BACKWARD:6,HOLD_DELAY:7,REPEAT_DELAY:8,COMPLETE:9,PENDING:20,ACTIVE:21,LOOP_DELAY:22,COMPLETE_DELAY:23,START_DELAY:24,PENDING_REMOVE:25,REMOVED:26,FINISHED:27,DESTROYED:28,MAX:999999999999}},56694:t=>{function e(t,e,i){var s=i?t[e]:Object.getOwnPropertyDescriptor(t,e);return!i&&s.value&&"object"==typeof s.value&&(s=s.value),!(!s||!function(t){return!!t.get&&"function"==typeof t.get||!!t.set&&"function"==typeof t.set}(s))&&(void 0===s.enumerable&&(s.enumerable=!0),void 0===s.configurable&&(s.configurable=!0),s)}function i(t,e){var i=Object.getOwnPropertyDescriptor(t,e);return!!i&&(i.value&&"object"==typeof i.value&&(i=i.value),!1===i.configurable)}function s(t,s,n,o){for(var a in s)if(s.hasOwnProperty(a)){var h=e(s,a,n);if(!1!==h){if(i((o||t).prototype,a)){if(r.ignoreFinals)continue;throw new Error("cannot override final property '"+a+"', set Class.ignoreFinals = true to skip")}Object.defineProperty(t.prototype,a,h)}else t.prototype[a]=s[a]}}function n(t,e){if(e){Array.isArray(e)||(e=[e]);for(var i=0;i{t.exports=function(){}},10618:t=>{t.exports=function(){return null}},78991:t=>{t.exports=function(t,e,i,s,n){if(void 0===n&&(n=t),i>0){var r=i-t.length;if(r<=0)return null}if(!Array.isArray(e))return-1===t.indexOf(e)?(t.push(e),s&&s.call(n,e),e):null;for(var o=e.length-1;o>=0;)-1!==t.indexOf(e[o])&&e.splice(o,1),o--;if(0===(o=e.length))return null;i>0&&o>r&&(e.splice(r),o=r);for(var a=0;a{t.exports=function(t,e,i,s,n,r){if(void 0===i&&(i=0),void 0===r&&(r=t),s>0){var o=s-t.length;if(o<=0)return null}if(!Array.isArray(e))return-1===t.indexOf(e)?(t.splice(i,0,e),n&&n.call(r,e),e):null;for(var a=e.length-1;a>=0;)-1!==t.indexOf(e[a])&&e.pop(),a--;if(0===(a=e.length))return null;s>0&&a>o&&(e.splice(o),a=o);for(var h=a-1;h>=0;h--){var l=e[h];t.splice(i,0,l),n&&n.call(r,l)}return e}},58742:t=>{t.exports=function(t,e){var i=t.indexOf(e);return-1!==i&&i{var s=i(45838);t.exports=function(t,e,i,n,r){void 0===n&&(n=0),void 0===r&&(r=t.length);var o=0;if(s(t,n,r))for(var a=n;a{t.exports=function(t,e,i){var s,n=[null];for(s=3;s{var s=i(45838);t.exports=function(t,e,i,n,r){if(void 0===n&&(n=0),void 0===r&&(r=t.length),s(t,n,r)){var o,a=[null];for(o=5;o{t.exports=function(t,e,i){if(!e.length)return NaN;if(1===e.length)return e[0];var s,n,r=1;if(i){if(te.length&&(r=e.length),i?(s=e[r-1][i],(n=e[r][i])-t<=t-s?e[r]:e[r-1]):(s=e[r-1],(n=e[r])-t<=t-s?n:s)}},5454:t=>{var e=function(t,i){void 0===i&&(i=[]);for(var s=0;s{var s=i(45838);t.exports=function(t,e,i,n,r){void 0===n&&(n=0),void 0===r&&(r=t.length);var o=[];if(s(t,n,r))for(var a=n;a{var s=i(45838);t.exports=function(t,e,i,n,r){if(void 0===n&&(n=0),void 0===r&&(r=t.length),s(t,n,r))for(var o=n;o{t.exports=function(t,e,i){void 0===e&&(e=0),void 0===i&&(i=t.length);var s=e+Math.floor(Math.random()*i);return void 0===t[s]?null:t[s]}},24218:t=>{t.exports=function(t,e,i){if(e===i)return t;var s=t.indexOf(e),n=t.indexOf(i);if(s<0||n<0)throw new Error("Supplied items must be elements of the same array");return s>n||(t.splice(s,1),n===t.length-1?t.push(e):t.splice(n,0,e)),t}},58258:t=>{t.exports=function(t,e,i){if(e===i)return t;var s=t.indexOf(e),n=t.indexOf(i);if(s<0||n<0)throw new Error("Supplied items must be elements of the same array");return s{t.exports=function(t,e){var i=t.indexOf(e);if(i>0){var s=t[i-1],n=t.indexOf(s);t[i]=s,t[n]=e}return t}},68396:t=>{t.exports=function(t,e,i){var s=t.indexOf(e);if(-1===s||i<0||i>=t.length)throw new Error("Supplied index out of bounds");return s!==i&&(t.splice(s,1),t.splice(i,0,e)),e}},27555:t=>{t.exports=function(t,e){var i=t.indexOf(e);if(-1!==i&&i{t.exports=function(t,e,i,s){var n,r=[],o=!1;if((i||s)&&(o=!0,i||(i=""),s||(s="")),e=e;n--)o?r.push(i+n.toString()+s):r.push(n);else for(n=t;n<=e;n++)o?r.push(i+n.toString()+s):r.push(n);return r}},89955:(t,e,i)=>{var s=i(67233);t.exports=function(t,e,i){void 0===t&&(t=0),void 0===e&&(e=null),void 0===i&&(i=1),null===e&&(e=t,t=0);for(var n=[],r=Math.max(s((e-t)/(i||1)),0),o=0;o{function e(t,e,i){var s=t[e];t[e]=t[i],t[i]=s}function i(t,e){return te?1:0}var s=function(t,n,r,o,a){for(void 0===r&&(r=0),void 0===o&&(o=t.length-1),void 0===a&&(a=i);o>r;){if(o-r>600){var h=o-r+1,l=n-r+1,u=Math.log(h),c=.5*Math.exp(2*u/3),d=.5*Math.sqrt(u*c*(h-c)/h)*(l-h/2<0?-1:1),f=Math.max(r,Math.floor(n-l*c/h+d)),p=Math.min(o,Math.floor(n+(h-l)*c/h+d));s(t,n,f,p,a)}var v=t[n],g=r,m=o;for(e(t,r,n),a(t[o],v)>0&&e(t,r,o);g0;)m--}0===a(t[r],v)?e(t,r,m):e(t,++m,o),m<=n&&(r=m+1),n<=m&&(o=m-1)}};t.exports=s},75757:(t,e,i)=>{var s=i(10850),n=i(18592),r=function(t,e,i){for(var s=[],n=0;n{var s=i(72677);t.exports=function(t,e,i,n){var r;if(void 0===n&&(n=t),!Array.isArray(e))return-1!==(r=t.indexOf(e))?(s(t,r),i&&i.call(n,e),e):null;for(var o=e.length-1,a=[];o>=0;){var h=e[o];-1!==(r=t.indexOf(h))&&(s(t,r),a.push(h),i&&i.call(n,h)),o--}return a}},8324:(t,e,i)=>{var s=i(72677);t.exports=function(t,e,i,n){if(void 0===n&&(n=t),e<0||e>t.length-1)throw new Error("Index out of bounds");var r=s(t,e);return i&&i.call(n,r),r}},47427:(t,e,i)=>{var s=i(45838);t.exports=function(t,e,i,n,r){if(void 0===e&&(e=0),void 0===i&&(i=t.length),void 0===r&&(r=t),s(t,e,i)){var o=i-e,a=t.splice(e,o);if(n)for(var h=0;h{var s=i(72677);t.exports=function(t,e,i){void 0===e&&(e=0),void 0===i&&(i=t.length);var n=e+Math.floor(Math.random()*i);return s(t,n)}},80402:t=>{t.exports=function(t,e,i){var s=t.indexOf(e),n=t.indexOf(i);return-1!==s&&-1===n&&(t[s]=i,!0)}},77640:t=>{t.exports=function(t,e){void 0===e&&(e=1);for(var i=null,s=0;s{t.exports=function(t,e){void 0===e&&(e=1);for(var i=null,s=0;s{t.exports=function(t,e,i,s){var n=t.length;if(e<0||e>n||e>=i||i>n){if(s)throw new Error("Range Error: Values outside acceptable range");return!1}return!0}},27847:t=>{t.exports=function(t,e){var i=t.indexOf(e);return-1!==i&&i>0&&(t.splice(i,1),t.unshift(e)),e}},6034:(t,e,i)=>{var s=i(45838);t.exports=function(t,e,i,n,r){if(void 0===n&&(n=0),void 0===r&&(r=t.length),s(t,n,r))for(var o=n;o{t.exports=function(t){for(var e=t.length-1;e>0;e--){var i=Math.floor(Math.random()*(e+1)),s=t[e];t[e]=t[i],t[i]=s}return t}},28834:t=>{t.exports=function(t){var e=/\D/g;return t.sort((function(t,i){return parseInt(t.replace(e,""),10)-parseInt(i.replace(e,""),10)})),t}},72677:t=>{t.exports=function(t,e){if(!(e>=t.length)){for(var i=t.length-1,s=t[e],n=e;n{var s=i(77290);function n(t,e){return String(t).localeCompare(e)}function r(t,e,i,s){var n,r,o,a,h,l=t.length,u=0,c=2*i;for(n=0;nl&&(r=l),o>l&&(o=l),a=n,h=r;;)if(a{t.exports=function(t,e,i){if(e===i)return t;var s=t.indexOf(e),n=t.indexOf(i);if(s<0||n<0)throw new Error("Supplied items must be elements of the same array");return t[s]=i,t[n]=e,t}},59959:(t,e,i)=>{t.exports={Matrix:i(13515),Add:i(78991),AddAt:i(48522),BringToTop:i(58742),CountAllMatching:i(30164),Each:i(36337),EachInRange:i(46208),FindClosestInSorted:i(2406),Flatten:i(5454),GetAll:i(71608),GetFirst:i(51463),GetRandom:i(72861),MoveDown:i(51172),MoveTo:i(68396),MoveUp:i(27555),MoveAbove:i(24218),MoveBelow:i(58258),NumberArray:i(13401),NumberArrayStep:i(89955),QuickSelect:i(53466),Range:i(75757),Remove:i(66458),RemoveAt:i(8324),RemoveBetween:i(47427),RemoveRandomElement:i(50147),Replace:i(80402),RotateLeft:i(77640),RotateRight:i(38487),SafeRange:i(45838),SendToBack:i(27847),SetAll:i(6034),Shuffle:i(18592),SortByDigits:i(28834),SpliceOne:i(72677),StableSort:i(17922),Swap:i(96928)}},97494:t=>{t.exports=function(t){if(!Array.isArray(t)||!Array.isArray(t[0]))return!1;for(var e=t[0].length,i=1;i{var s=i(76400),n=i(97494);t.exports=function(t){var e="";if(!n(t))return e;for(var i=0;i{t.exports=function(t){return t.reverse()}},51995:t=>{t.exports=function(t){for(var e=0;e{var s=i(63515);t.exports=function(t){return s(t,180)}},42549:(t,e,i)=>{var s=i(63515);t.exports=function(t){return s(t,90)}},63515:(t,e,i)=>{var s=i(97494),n=i(78581);t.exports=function(t,e){if(void 0===e&&(e=90),!s(t))return null;if("string"!=typeof e&&(e=(e%360+360)%360),90===e||-270===e||"rotateLeft"===e)(t=n(t)).reverse();else if(-90===e||270===e||"rotateRight"===e)t.reverse(),t=n(t);else if(180===Math.abs(e)||"rotate180"===e){for(var i=0;i{var s=i(63515);t.exports=function(t){return s(t,-90)}},27365:(t,e,i)=>{var s=i(77640),n=i(38487);t.exports=function(t,e,i){if(void 0===e&&(e=0),void 0===i&&(i=0),0!==i&&(i<0?s(t,Math.abs(i)):n(t,i)),0!==e)for(var r=0;r{t.exports=function(t){for(var e=t.length,i=t[0].length,s=new Array(i),n=0;n-1;r--)s[n][r]=t[r][n]}return s}},13515:(t,e,i)=>{t.exports={CheckMatrix:i(97494),MatrixToString:i(68428),ReverseColumns:i(59521),ReverseRows:i(51995),Rotate180:i(89011),RotateLeft:i(42549),RotateMatrix:i(63515),RotateRight:i(14305),Translate:i(27365),TransposeMatrix:i(78581)}},40581:t=>{var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";t.exports=function(t,i){for(var s=new Uint8Array(t),n=s.length,r=i?"data:"+i+";base64,":"",o=0;o>2],r+=e[(3&s[o])<<4|s[o+1]>>4],r+=e[(15&s[o+1])<<2|s[o+2]>>6],r+=e[63&s[o+2]];return n%3==2?r=r.substring(0,r.length-1)+"=":n%3==1&&(r=r.substring(0,r.length-2)+"=="),r}},82329:t=>{for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=new Uint8Array(256),s=0;s>4,u[h++]=(15&s)<<4|n>>2,u[h++]=(3&n)<<6|63&r;return l}},78417:(t,e,i)=>{t.exports={ArrayBufferToBase64:i(40581),Base64ToArrayBuffer:i(82329)}},22178:(t,e,i)=>{t.exports={Array:i(59959),Base64:i(78417),Objects:i(64615),String:i(50379),NOOP:i(72283),NULL:i(10618)}},32742:t=>{t.exports=function(t){var e={};for(var i in t)Array.isArray(t[i])?e[i]=t[i].slice(0):e[i]=t[i];return e}},28699:t=>{var e=function(t){var i,s,n;if("object"!=typeof t||null===t)return t;for(n in i=Array.isArray(t)?[]:{},t)s=t[n],i[n]=e(s);return i};t.exports=e},98611:(t,e,i)=>{var s=i(42911),n=function(){var t,e,i,r,o,a,h=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof h&&(c=h,h=arguments[1]||{},l=2),u===l&&(h=this,--l);l{var s=i(5923),n=i(10850);t.exports=function(t,e,i){var r=n(t,e,null);if(null===r)return i;if(Array.isArray(r))return s.RND.pick(r);if("object"==typeof r){if(r.hasOwnProperty("randInt"))return s.RND.integerInRange(r.randInt[0],r.randInt[1]);if(r.hasOwnProperty("randFloat"))return s.RND.realInRange(r.randFloat[0],r.randFloat[1])}else if("function"==typeof r)return r(e);return r}},72632:t=>{t.exports=function(t,e,i){var s=typeof t;return t&&"number"!==s&&"string"!==s&&t.hasOwnProperty(e)&&void 0!==t[e]?t[e]:i}},94324:(t,e,i)=>{var s=i(10850),n=i(82897);t.exports=function(t,e,i,r,o){void 0===o&&(o=i);var a=s(t,e,o);return n(a,i,r)}},10850:t=>{t.exports=function(t,e,i,s){if(!t&&!s||"number"==typeof t)return i;if(t&&t.hasOwnProperty(e))return t[e];if(s&&s.hasOwnProperty(e))return s[e];if(-1!==e.indexOf(".")){for(var n=e.split("."),r=t,o=s,a=i,h=i,l=!0,u=!0,c=0;c{t.exports=function(t,e){for(var i=0;i{t.exports=function(t,e){for(var i=0;i{t.exports=function(t,e){return t.hasOwnProperty(e)}},42911:t=>{t.exports=function(t){if(!t||"object"!=typeof t||t.nodeType||t===t.window)return!1;try{if(t.constructor&&!{}.hasOwnProperty.call(t.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}return!0}},30657:(t,e,i)=>{var s=i(32742);t.exports=function(t,e){var i=s(t);for(var n in e)i.hasOwnProperty(n)||(i[n]=e[n]);return i}},72066:(t,e,i)=>{var s=i(32742);t.exports=function(t,e){var i=s(t);for(var n in e)i.hasOwnProperty(n)&&(i[n]=e[n]);return i}},28820:(t,e,i)=>{var s=i(19256);t.exports=function(t,e){for(var i={},n=0;n{t.exports=function(t,e,i){if(!t||"number"==typeof t)return!1;if(t.hasOwnProperty(e))return t[e]=i,!0;if(-1!==e.indexOf(".")){for(var s=e.split("."),n=t,r=t,o=0;o{t.exports={Clone:i(32742),DeepCopy:i(28699),Extend:i(98611),GetAdvancedValue:i(20494),GetFastValue:i(72632),GetMinMaxValue:i(94324),GetValue:i(10850),HasAll:i(87701),HasAny:i(53523),HasValue:i(19256),IsPlainObject:i(42911),Merge:i(30657),MergeRight:i(72066),Pick:i(28820),SetValue:i(22440)}},69429:t=>{t.exports=function(t,e){return t.replace(/%([0-9]+)/g,(function(t,i){return e[Number(i)-1]}))}},76400:t=>{t.exports=function(t,e,i,s){void 0===e&&(e=0),void 0===i&&(i=" "),void 0===s&&(s=3);var n=0;if(e+1>=(t=t.toString()).length)switch(s){case 1:t=new Array(e+1-t.length).join(i)+t;break;case 3:var r=Math.ceil((n=e-t.length)/2);t=new Array(n-r+1).join(i)+t+new Array(r+1).join(i);break;default:t+=new Array(e+1-t.length).join(i)}return t}},76872:t=>{t.exports=function(t,e){return 0===e?t.slice(1):t.slice(0,e-1)+t.slice(e)}},8051:t=>{t.exports=function(t){return t.split("").reverse().join("")}},76583:t=>{t.exports=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){var e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)}))}},40587:t=>{t.exports=function(t){return t&&t[0].toUpperCase()+t.slice(1)}},50379:(t,e,i)=>{t.exports={Format:i(69429),Pad:i(76400),RemoveAt:i(76872),Reverse:i(8051),UppercaseFirst:i(40587),UUID:i(76583)}}},e={};function i(s){var n=e[s];if(void 0!==n)return n.exports;var r=e[s]={exports:{}};return t[s](r,r.exports,i),r.exports}return i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),i(92491)})())); \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.phaser/src/phaser/matter.ts b/source/editor/plugins/phasereditor2d.phaser/src/phaser/matter.ts index 49e02eeb0..2e4cadf58 100644 --- a/source/editor/plugins/phasereditor2d.phaser/src/phaser/matter.ts +++ b/source/editor/plugins/phasereditor2d.phaser/src/phaser/matter.ts @@ -105,7 +105,7 @@ declare namespace MatterJS { * @default { x: 0, y: 0 } */ force?: Vector; - + /** * A `Number` that defines the friction of the body. The value is always positive and is in the range `(0, 1)`. * A value of `0` means that the body may slide indefinitely. @@ -436,7 +436,7 @@ declare namespace MatterJS { /** * A callback that is invoked when this Body starts colliding with any other Body. - * + * * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. * * @property onCollideCallback @@ -447,7 +447,7 @@ declare namespace MatterJS { /** * A callback that is invoked when this Body stops colliding with any other Body. - * + * * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. * * @property onCollideEndCallback @@ -458,7 +458,7 @@ declare namespace MatterJS { /** * A callback that is invoked for the duration that this Body is colliding with any other Body. - * + * * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. * * @property onCollideActiveCallback @@ -743,7 +743,7 @@ declare namespace MatterJS { stiffness?: number; /** - * A `Number` that specifies the damping of the constraint, + * A `Number` that specifies the damping of the constraint, * i.e. the amount of resistance applied to each body based on their velocities to limit the amount of oscillation. * Damping will only be apparent when the constraint also has a very low `stiffness`. * A value of `0.1` means the constraint will apply heavy damping, resulting in little to no oscillation. @@ -877,7 +877,7 @@ declare namespace MatterJS { * @default 2 */ constraintIterations?: number; - + /** * A flag that specifies whether the engine should allow sleeping via the `Matter.Sleeping` module. * Sleeping can improve stability and performance, but often at the expense of accuracy. @@ -1267,7 +1267,7 @@ declare namespace MatterJS { pointB: Vector; /** - * A `Number` that specifies the target resting length of the constraint. + * A `Number` that specifies the target resting length of the constraint. * It is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`. * * @property length @@ -1314,7 +1314,7 @@ declare namespace MatterJS { stiffness: number; /** - * A `Number` that specifies the damping of the constraint, + * A `Number` that specifies the damping of the constraint, * i.e. the amount of resistance applied to each body based on their velocities to limit the amount of oscillation. * Damping will only be apparent when the constraint also has a very low `stiffness`. * A value of `0.1` means the constraint will apply heavy damping, resulting in little to no oscillation. @@ -1401,7 +1401,7 @@ declare namespace MatterJS { label: string; /** - * An array of bodies that make up this body. + * An array of bodies that make up this body. * The first body in the array must always be a self reference to the current body instance. * All bodies in the `parts` array together form a single rigid compound body. * Parts are allowed to overlap, have gaps or holes or even form concave bodies. @@ -1437,7 +1437,7 @@ declare namespace MatterJS { * [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }] * * When passed via `Body.create`, the vertices are translated relative to `body.position` (i.e. world-space, and constantly updated by `Body.update` during simulation). - * The `Vector` objects are also augmented with additional properties required for efficient collision detection. + * The `Vector` objects are also augmented with additional properties required for efficient collision detection. * * Other properties such as `inertia` and `bounds` are automatically calculated from the passed vertices (unless provided via `options`). * Concave hulls are not currently supported. The module `Matter.Vertices` contains useful methods for working with vertices. @@ -1915,7 +1915,7 @@ declare namespace MatterJS { /** * A callback that is invoked when this Body starts colliding with any other Body. - * + * * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. * * @property onCollideCallback @@ -1926,7 +1926,7 @@ declare namespace MatterJS { /** * A callback that is invoked when this Body stops colliding with any other Body. - * + * * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. * * @property onCollideEndCallback @@ -1937,7 +1937,7 @@ declare namespace MatterJS { /** * A callback that is invoked for the duration that this Body is colliding with any other Body. - * + * * You can register callbacks by providing a function of type `( pair: Matter.Pair) => void`. * * @property onCollideActiveCallback @@ -2076,6 +2076,7 @@ declare namespace MatterJS { /** * Creates a new rigid body model with a trapezoid hull. + * The `slope` is parameterised as a fraction of `width` and must be < 1 to form a valid trapezoid. * The options parameter is an object that specifies any properties you wish to override the defaults. * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. * @method trapezoid @@ -2110,6 +2111,17 @@ declare namespace MatterJS { * @return {body} */ static fromVertices (x: number, y: number, vertexSets: Array>, options?: IBodyDefinition, flagInternal?: boolean, removeCollinear?: number, minimumArea?: number): BodyType; + + /** + * Takes an array of Body objects and flags all internal edges (coincident parts) based on the maxDistance + * value. The array is changed in-place and returned, so you can pass this function a `Body.parts` property. + * + * @method flagCoincidentParts + * @param {body[]} parts - The Body parts, or array of bodies, to flag. + * @param {number} [maxDistance=5] + * @return {body[]} The modified `parts` parameter. + */ + static flagCoincidentParts (parts: Array, maxDistance?: number): Array; } class BodiesFactory { @@ -2158,6 +2170,7 @@ declare namespace MatterJS { /** * Creates a new rigid body model with a trapezoid hull. + * The `slope` is parameterised as a fraction of `width` and must be < 1 to form a valid trapezoid. * The options parameter is an object that specifies any properties you wish to override the defaults. * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object. * @method trapezoid @@ -2192,6 +2205,18 @@ declare namespace MatterJS { * @return {body} */ fromVertices (x: number, y: number, vertexSets: Array>, options?: IBodyDefinition, flagInternal?: boolean, removeCollinear?: number, minimumArea?: number): BodyType; + + /** + * Takes an array of Body objects and flags all internal edges (coincident parts) based on the maxDistance + * value. The array is changed in-place and returned, so you can pass this function a `Body.parts` property. + * + * @method flagCoincidentParts + * @param {body[]} parts - The Body parts, or array of bodies, to flag. + * @param {number} [maxDistance=5] + * @return {body[]} The modified `parts` parameter. + */ + flagCoincidentParts (parts: Array, maxDistance?: number): Array; + } /** @@ -2200,7 +2225,7 @@ declare namespace MatterJS { * Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the module `Matter.Bodies`. * * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). - * + * * @class Body */ class Body { @@ -2214,6 +2239,13 @@ declare namespace MatterJS { */ static applyForce (body: BodyType, position: Vector, force: Vector): void; + /** + * Updates properties `body.velocity`, `body.speed`, `body.angularVelocity` and `body.angularSpeed` which are normalised in relation to `Body._baseDelta`. + * @method updateVelocities + * @param {body} body + */ + static updateVelocities (body: BodyType): void; + /** * Creates a new rigid body model. The options parameter is an object that specifies any properties you wish to override the defaults. * All properties have default values, and many are pre-calculated automatically based on other properties. @@ -2229,8 +2261,9 @@ declare namespace MatterJS { * @method rotate * @param {body} body * @param {number} rotation + * @param {boolean} [updateVelocity] */ - static rotate (body: BodyType, rotation: number): void; + static rotate (body: BodyType, rotation: number, updateVelocity?: boolean): void; /** * Returns the next unique group index for which bodies will collide. @@ -2306,26 +2339,41 @@ declare namespace MatterJS { * Note that this method will ensure that the first part in `body.parts` will always be the `body`. * @method setParts * @param {body} body - * @param [body] parts + * @param {body[]} parts * @param {bool} [autoHull=true] */ static setParts (body: BodyType, parts: BodyType[], autoHull?: boolean): void; + /** + * Set the centre of mass of the body. + * The `centre` is a vector in world-space unless `relative` is set, in which case it is a translation. + * The centre of mass is the point the body rotates about and can be used to simulate non-uniform density. + * This is equal to moving `body.position` but not the `body.vertices`. + * Invalid if the `centre` falls outside the body's convex hull. + * @method setCentre + * @param {body} body + * @param {vector} centre + * @param {bool} relative + */ + static setCentre (body: BodyType, centre: Vector, relative: boolean): void; + /** * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged. * @method setPosition * @param {body} body * @param {vector} position + * @param {boolean} updateVelocity */ - static setPosition (body: BodyType, position: Vector): void; + static setPosition (body: BodyType, position: Vector, updateVelocity: boolean): void; /** * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged. * @method setAngle * @param {body} body * @param {number} angle + * @param {boolean} updateVelocity */ - static setAngle (body: BodyType, angle: number): void; + static setAngle (body: BodyType, angle: number, updateVelocity: boolean): void; /** * Sets the linear velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. @@ -2366,19 +2414,59 @@ declare namespace MatterJS { * @method translate * @param {body} body * @param {vector} translation + * @param {boolean} [updateVelocity] */ - static translate (body: BodyType, translation: Vector): void; + static translate (body: BodyType, translation: Vector, updateVelocity?: boolean): void; /** * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration. * @method update * @param {body} body * @param {number} deltaTime - * @param {number} timeScale - * @param {number} correction */ - static update (body: BodyType, deltaTime: number, timeScale: number, correction: number): void; + static update (body: BodyType, deltaTime: number): void; + /** + * Gets the current linear speed of the body. + * Equivalent to the magnitude of its velocity. + * @method getSpeed + * @param {body} body + * @return {number} speed + */ + static getSpeed (body: BodyType): number; + + /** + * Sets the current linear speed of the body. + * Direction is maintained. Affects body velocity. + * @method setSpeed + * @param {body} body + * @param {number} speed + */ + static setSpeed (body: BodyType, speed: number): void; + + /** + * Gets the current rotational velocity of the body. + * @method getAngularVelocity + * @param {body} body + * @return {number} angular velocity + */ + static getAngularVelocity (body: BodyType): number; + + /** + * Gets the current rotational velocity of the body. + * @method getAngularSpeed + * @param {body} body + * @return {number} angular velocity + */ + static getAngularSpeed (body: BodyType): number; + + /** + * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. + * @method setAngularSpeed + * @param {body} body + * @param {number} velocity + */ + static setAngularSpeed (body: BodyType, velocity: number): void; } class BodyFactory { @@ -2392,6 +2480,13 @@ declare namespace MatterJS { */ applyForce (body: BodyType, position: Vector, force: Vector): void; + /** + * Updates properties `body.velocity`, `body.speed`, `body.angularVelocity` and `body.angularSpeed` which are normalised in relation to `Body._baseDelta`. + * @method updateVelocities + * @param {body} body + */ + updateVelocities (body: BodyType): void; + /** * Creates a new rigid body model. The options parameter is an object that specifies any properties you wish to override the defaults. * All properties have default values, and many are pre-calculated automatically based on other properties. @@ -2407,8 +2502,9 @@ declare namespace MatterJS { * @method rotate * @param {body} body * @param {number} rotation + * @param {boolean} [updateVelocity] */ - rotate (body: BodyType, rotation: number): void; + rotate (body: BodyType, rotation: number, updateVelocity?: boolean): void; /** * Returns the next unique group index for which bodies will collide. @@ -2489,21 +2585,36 @@ declare namespace MatterJS { */ setParts (body: BodyType, parts: BodyType[], autoHull?: boolean): void; + /** + * Set the centre of mass of the body. + * The `centre` is a vector in world-space unless `relative` is set, in which case it is a translation. + * The centre of mass is the point the body rotates about and can be used to simulate non-uniform density. + * This is equal to moving `body.position` but not the `body.vertices`. + * Invalid if the `centre` falls outside the body's convex hull. + * @method setCentre + * @param {body} body + * @param {vector} centre + * @param {bool} relative + */ + setCentre (body: BodyType, centre: Vector, relative: boolean): void; + /** * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged. * @method setPosition * @param {body} body * @param {vector} position + * @param {boolean} updateVelocity */ - setPosition (body: BodyType, position: Vector): void; + setPosition (body: BodyType, position: Vector, updateVelocity: boolean): void; /** * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged. * @method setAngle * @param {body} body * @param {number} angle + * @param {boolean} updateVelocity */ - setAngle (body: BodyType, angle: number): void; + setAngle (body: BodyType, angle: number, updateVelocity: boolean): void; /** * Sets the linear velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. @@ -2513,6 +2624,14 @@ declare namespace MatterJS { */ setVelocity (body: BodyType, velocity: Vector): void; + /** + * Gets the current linear velocity of the body. + * @method setVelocity + * @param {body} body + * @return {vector} velocity + */ + getVelocity (body: BodyType): Vector; + /** * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. * @method setAngularVelocity @@ -2544,19 +2663,59 @@ declare namespace MatterJS { * @method translate * @param {body} body * @param {vector} translation + * @param {boolean} [updateVelocity] */ - translate (body: BodyType, translation: Vector): void; + translate (body: BodyType, translation: Vector, updateVelocity?: boolean): void; /** * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration. * @method update * @param {body} body * @param {number} deltaTime - * @param {number} timeScale - * @param {number} correction */ - update (body: BodyType, deltaTime: number, timeScale: number, correction: number): void; + update (body: BodyType, deltaTime: number): void; + + /** + * Gets the current linear speed of the body. + * Equivalent to the magnitude of its velocity. + * @method getSpeed + * @param {body} body + * @return {number} speed + */ + getSpeed (body: BodyType): number; + + /** + * Sets the current linear speed of the body. + * Direction is maintained. Affects body velocity. + * @method setSpeed + * @param {body} body + * @param {number} speed + */ + setSpeed (body: BodyType, speed: number): void; + + /** + * Gets the current rotational velocity of the body. + * @method getAngularVelocity + * @param {body} body + * @return {number} angular velocity + */ + getAngularVelocity (body: BodyType): number; + + /** + * Gets the current rotational velocity of the body. + * @method getAngularSpeed + * @param {body} body + * @return {number} angular velocity + */ + getAngularSpeed (body: BodyType): number; + /** + * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`. + * @method setAngularSpeed + * @param {body} body + * @param {number} velocity + */ + setAngularSpeed (body: BodyType, velocity: number): void; } /** @@ -2977,14 +3136,14 @@ declare namespace MatterJS { /** * Creates a composite with simple car setup of bodies and constraints. * @method car - * @param {number} xx - * @param {number} yy + * @param {number} x + * @param {number} y * @param {number} width * @param {number} height * @param {number} wheelSize * @return {composite} A new composite car body */ - static car (xx: number, yy: number, width: number, height: number, wheelSize: number): CompositeType; + static car (x: number, y: number, width: number, height: number, wheelSize: number): CompositeType; /** * Chains all bodies in the given composite together using constraints. @@ -3014,21 +3173,21 @@ declare namespace MatterJS { /** * Creates a composite with a Newton's Cradle setup of bodies and constraints. * @method newtonsCradle - * @param {number} xx - * @param {number} yy + * @param {number} x + * @param {number} y * @param {number} number * @param {number} size * @param {number} length * @return {composite} A new composite newtonsCradle body */ - static newtonsCradle (xx: number, yy: number, number: number, size: number, length: number): CompositeType; + static newtonsCradle (x: number, y: number, number: number, size: number, length: number): CompositeType; /** * Create a new composite containing bodies created in the callback in a pyramid arrangement. * This function uses the body's bounds to prevent overlaps. * @method pyramid - * @param {number} xx - * @param {number} yy + * @param {number} x + * @param {number} y * @param {number} columns * @param {number} rows * @param {number} columnGap @@ -3036,13 +3195,13 @@ declare namespace MatterJS { * @param {function} callback * @return {composite} A new composite containing objects created in the callback */ - static pyramid (xx: number, yy: number, columns: number, rows: number, columnGap: number, rowGap: number, callback: Function): CompositeType; + static pyramid (x: number, y: number, columns: number, rows: number, columnGap: number, rowGap: number, callback: Function): CompositeType; /** * Creates a simple soft body like object. * @method softBody - * @param {number} xx - * @param {number} yy + * @param {number} x + * @param {number} y * @param {number} columns * @param {number} rows * @param {number} columnGap @@ -3053,14 +3212,14 @@ declare namespace MatterJS { * @param {} constraintOptions * @return {composite} A new composite softBody */ - static softBody (xx: number, yy: number, columns: number, rows: number, columnGap: number, rowGap: number, crossBrace: boolean, particleRadius: number, particleOptions: any, constraintOptions: any): CompositeType; + static softBody (x: number, y: number, columns: number, rows: number, columnGap: number, rowGap: number, crossBrace: boolean, particleRadius: number, particleOptions: any, constraintOptions: any): CompositeType; /** * Create a new composite containing bodies created in the callback in a grid arrangement. * This function uses the body's bounds to prevent overlaps. * @method stack - * @param {number} xx - * @param {number} yy + * @param {number} x Starting position in X. + * @param {number} y Starting position in Y. * @param {number} columns * @param {number} rows * @param {number} columnGap @@ -3068,7 +3227,7 @@ declare namespace MatterJS { * @param {function} callback * @return {composite} A new composite containing objects created in the callback */ - static stack (xx: number, yy: number, columns: number, rows: number, columnGap: number, rowGap: number, callback: Function): CompositeType; + static stack (x: number, y: number, columns: number, rows: number, columnGap: number, rowGap: number, callback: Function): CompositeType; } @@ -3077,14 +3236,14 @@ declare namespace MatterJS { /** * Creates a composite with simple car setup of bodies and constraints. * @method car - * @param {number} xx - * @param {number} yy + * @param {number} x + * @param {number} y * @param {number} width * @param {number} height * @param {number} wheelSize * @return {composite} A new composite car body */ - car (xx: number, yy: number, width: number, height: number, wheelSize: number): CompositeType; + car (x: number, y: number, width: number, height: number, wheelSize: number): CompositeType; /** * Chains all bodies in the given composite together using constraints. @@ -3114,21 +3273,21 @@ declare namespace MatterJS { /** * Creates a composite with a Newton's Cradle setup of bodies and constraints. * @method newtonsCradle - * @param {number} xx - * @param {number} yy + * @param {number} x + * @param {number} y * @param {number} number * @param {number} size * @param {number} length * @return {composite} A new composite newtonsCradle body */ - newtonsCradle (xx: number, yy: number, number: number, size: number, length: number): CompositeType; + newtonsCradle (x: number, y: number, number: number, size: number, length: number): CompositeType; /** * Create a new composite containing bodies created in the callback in a pyramid arrangement. * This function uses the body's bounds to prevent overlaps. * @method pyramid - * @param {number} xx - * @param {number} yy + * @param {number} x + * @param {number} y * @param {number} columns * @param {number} rows * @param {number} columnGap @@ -3136,13 +3295,13 @@ declare namespace MatterJS { * @param {function} callback * @return {composite} A new composite containing objects created in the callback */ - pyramid (xx: number, yy: number, columns: number, rows: number, columnGap: number, rowGap: number, callback: Function): CompositeType; + pyramid (x: number, y: number, columns: number, rows: number, columnGap: number, rowGap: number, callback: Function): CompositeType; /** * Creates a simple soft body like object. * @method softBody - * @param {number} xx - * @param {number} yy + * @param {number} x + * @param {number} y * @param {number} columns * @param {number} rows * @param {number} columnGap @@ -3153,14 +3312,14 @@ declare namespace MatterJS { * @param {} constraintOptions * @return {composite} A new composite softBody */ - softBody (xx: number, yy: number, columns: number, rows: number, columnGap: number, rowGap: number, crossBrace: boolean, particleRadius: number, particleOptions: any, constraintOptions: any): CompositeType; + softBody (x: number, y: number, columns: number, rows: number, columnGap: number, rowGap: number, crossBrace: boolean, particleRadius: number, particleOptions: any, constraintOptions: any): CompositeType; /** * Create a new composite containing bodies created in the callback in a grid arrangement. * This function uses the body's bounds to prevent overlaps. * @method stack - * @param {number} xx - * @param {number} yy + * @param {number} x + * @param {number} y * @param {number} columns * @param {number} rows * @param {number} columnGap @@ -3168,7 +3327,7 @@ declare namespace MatterJS { * @param {function} callback * @return {composite} A new composite containing objects created in the callback */ - stack (xx: number, yy: number, columns: number, rows: number, columnGap: number, rowGap: number, callback: Function): CompositeType; + stack (x: number, y: number, columns: number, rows: number, columnGap: number, rowGap: number, callback: Function): CompositeType; } @@ -3193,6 +3352,15 @@ declare namespace MatterJS { */ static create (options: IConstraintDefinition): ConstraintType; + /** + * Returns the current length of the constraint. + * This is the distance between both of the constraint's end points. + * See `constraint.length` for the target rest length. + * @method currentLength + * @param {constraint} ConstraintType + * @return {number} the current length + */ + static currentLength (constraint: ConstraintType): number; } class ConstraintFactory { @@ -3207,6 +3375,15 @@ declare namespace MatterJS { */ create (options: IConstraintDefinition): ConstraintType; + /** + * Returns the current length of the constraint. + * This is the distance between both of the constraint's end points. + * See `constraint.length` for the target rest length. + * @method currentLength + * @param {constraint} ConstraintType + * @return {number} the current length + */ + currentLength (constraint: ConstraintType): number; } /** @@ -3260,20 +3437,13 @@ declare namespace MatterJS { /** * Moves the simulation forward in time by `delta` ms. - * The `correction` argument is an optional `Number` that specifies the time correction factor to apply to the update. - * This can help improve the accuracy of the simulation in cases where `delta` is changing between updates. - * The value of `correction` is defined as `delta / lastDelta`, i.e. the percentage change of `delta` over the last step. - * Therefore the value is always `1` (no correction) when `delta` constant (or when no correction is desired, which is the default). - * See the paper on Time Corrected Verlet for more information. - * * Triggers `beforeUpdate` and `afterUpdate` events. * Triggers `collisionStart`, `collisionActive` and `collisionEnd` events. * @method update * @param {engine} engine * @param {number} [delta=16.666] - * @param {number} [correction=1] */ - static update (engine: Engine, delta?: number, correction?: number): Engine; + static update (engine: Engine, delta?: number): Engine; /** * An alias for `Runner.run`, see `Matter.Runner` for more information. @@ -3360,7 +3530,7 @@ declare namespace MatterJS { world: World; } - + /** * The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures. * @@ -3664,10 +3834,10 @@ declare namespace MatterJS { * Find a solution for pair positions. * @method solvePosition * @param {pair[]} pairs - * @param {body[]} bodies - * @param {number} timeScale + * @param {number} delta + * @param {number} [damping=1] */ - static solvePosition (pairs: IPair[], bodies: BodyType[], timeScale: number): void; + static solvePosition (pairs: IPair[], delta: number, damping?: number): void; /** * Apply position resolution. @@ -3687,9 +3857,9 @@ declare namespace MatterJS { * Find a solution for pair velocities. * @method solveVelocity * @param {pair[]} pairs - * @param {number} timeScale + * @param {number} delta */ - static solveVelocity (pairs: IPair[], timeScale: number): void; + static solveVelocity (pairs: IPair[], delta: number): void; } @@ -3706,10 +3876,10 @@ declare namespace MatterJS { * Find a solution for pair positions. * @method solvePosition * @param {pair[]} pairs - * @param {body[]} bodies - * @param {number} timeScale + * @param {number} delta + * @param {number} [damping=1] */ - solvePosition (pairs: IPair[], bodies: BodyType[], timeScale: number): void; + solvePosition (pairs: IPair[], delta: number, damping?: number): void; /** * Apply position resolution. @@ -3729,9 +3899,9 @@ declare namespace MatterJS { * Find a solution for pair velocities. * @method solveVelocity * @param {pair[]} pairs - * @param {number} timeScale + * @param {number} delta */ - solveVelocity (pairs: IPair[], timeScale: number): void; + solveVelocity (pairs: IPair[], delta: number): void; } @@ -3946,14 +4116,56 @@ declare namespace MatterJS { */ class Sleeping { + /** + * Set a body as sleeping or awake. + * @method set + * @param {body} body + * @param {boolean} isSleeping + */ static set (body: BodyType, isSleeping: boolean): void; + /** + * Puts bodies to sleep or wakes them up depending on their motion. + * @method update + * @param {body[]} bodies + * @param {number} delta + */ + static update (bodies: Array, delta: number): void; + + /** + * Given a set of colliding pairs, wakes the sleeping bodies involved. + * @method afterCollisions + * @param {pair[]} pairs + */ + static afterCollisions (pairs: Array): void; + } class SleepingFactory { + /** + * Set a body as sleeping or awake. + * @method set + * @param {body} body + * @param {boolean} isSleeping + */ set (body: BodyType, isSleeping: boolean): void; + /** + * Puts bodies to sleep or wakes them up depending on their motion. + * @method update + * @param {body[]} bodies + * @param {number} delta + */ + update (bodies: Array, delta: number): void; + + /** + * Given a set of colliding pairs, wakes the sleeping bodies involved. + * @method afterCollisions + * @param {pair[]} pairs + */ + afterCollisions (pairs: Array): void; + } /** @@ -4883,7 +5095,7 @@ declare namespace MatterJS { static trigger(object: any, eventNames: string, event?: (e: any) => void): void; } - + type Dependency = {name: string, range: string} | {name: string, version: string} | string; class Plugin { @@ -4892,7 +5104,7 @@ declare namespace MatterJS { version: string; install: () => void; for?: string; - + /** * Registers a plugin object so it can be resolved later by name. * @method register @@ -4900,16 +5112,16 @@ declare namespace MatterJS { * @return {object} The plugin. */ static register (plugin: Plugin): Plugin; - + /** - * Resolves a dependency to a plugin object from the registry if it exists. + * Resolves a dependency to a plugin object from the registry if it exists. * The `dependency` may contain a version, but only the name matters when resolving. * @method resolve * @param dependency {string} The dependency. * @return {object} The plugin if resolved, otherwise `undefined`. */ static resolve (dependency: string): Plugin | undefined; - + /** * Returns `true` if the object meets the minimum standard to be considered a plugin. * This means it must define the following properties: @@ -4977,7 +5189,7 @@ declare namespace MatterJS { * @return {object} The dependency parsed into its components. */ static dependencyParse (dependency: Dependency) : {name: string, range: string}; - + /** * Parses a version string into its components. * Versions are strictly of the format `x.y.z` (as in [semver](http://semver.org/)). @@ -5014,6 +5226,31 @@ declare namespace MatterJS { static versionSatisfies (version: string, range: string): boolean; } + + // v0.18 Release Updates + + class Collision { + + /** + * Creates a new collision record. + * @method create + * @param {BodyType} bodyA The first body part represented by the collision record + * @param {BodyType} bodyB The second body part represented by the collision record + * @return {collision} A new collision record + */ + create (bodyA: BodyType, bodyB: BodyType): any; + + /** + * Detect collision between two bodies. + * @method collides + * @param {BodyType} bodyA + * @param {BodyType} bodyB + * @param {Pairs} [pairs] Optionally reuse collision records from existing pairs. + * @return {collision|null} A collision record if detected, otherwise null + */ + collides (bodyA: BodyType, bodyB: BodyType, pairs: Pairs): any; + + } } declare module 'matter' { diff --git a/source/editor/plugins/phasereditor2d.phaser/src/phaser/phaser-fixes.ts b/source/editor/plugins/phasereditor2d.phaser/src/phaser/phaser-fixes.ts index 969491769..f87240729 100644 --- a/source/editor/plugins/phasereditor2d.phaser/src/phaser/phaser-fixes.ts +++ b/source/editor/plugins/phasereditor2d.phaser/src/phaser/phaser-fixes.ts @@ -1 +1,3 @@ -declare class ActiveXObject { } \ No newline at end of file +declare class ActiveXObject { } + +declare class VideoFrameCallbackMetadata { } \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.phaser/src/phaser/phaser.ts b/source/editor/plugins/phasereditor2d.phaser/src/phaser/phaser.ts index aa33c828a..7b2e63827 100644 --- a/source/editor/plugins/phasereditor2d.phaser/src/phaser/phaser.ts +++ b/source/editor/plugins/phasereditor2d.phaser/src/phaser/phaser.ts @@ -1,3 +1,5 @@ +// DO NOT EDIT THIS FILE! It was generated by running `npm run tsgen` + declare type CameraRotateCallback = (camera: Phaser.Cameras.Scene2D.Camera, progress: number, angle: number)=>void; declare type DataEachCallback = (parent: any, key: string, value: any, ...args: any[])=>void; @@ -13,9 +15,9 @@ declare type LightForEach = (light: Phaser.GameObjects.Light)=>void; /** * A custom function that will be responsible for wrapping the text. */ -declare type TextStyleWordWrapCallback = (text: string, textObject: Phaser.GameObjects.Text)=>void; +declare type TextStyleWordWrapCallback = (text: string, textObject: Phaser.GameObjects.Text)=>string | string[]; -declare type CenterFunction = (triangle: Phaser.Geom.Triangle)=>void; +declare type CenterFunction = (triangle: Phaser.Geom.Triangle)=>Phaser.Math.Vector2; declare namespace Phaser { namespace Actions { @@ -63,7 +65,7 @@ declare namespace Phaser { * @param compare The comparison object. Each property in this object will be checked against the items of the array. * @param index An optional offset to start searching from within the items array. Default 0. */ - function GetFirst(items: G, compare: object, index?: number): object | Phaser.GameObjects.GameObject; + function GetFirst(items: G, compare: object, index?: number): object | Phaser.GameObjects.GameObject | null; /** * Takes an array of objects and returns the last element in the array that has properties which match @@ -75,7 +77,7 @@ declare namespace Phaser { * @param compare The comparison object. Each property in this object will be checked against the items of the array. * @param index An optional offset to start searching from within the items array. Default 0. */ - function GetLast(items: G, compare: object, index?: number): object | Phaser.GameObjects.GameObject; + function GetLast(items: G, compare: object, index?: number): object | Phaser.GameObjects.GameObject | null; /** * Takes an array of Game Objects, or any objects that have public `x` and `y` properties, @@ -609,17 +611,29 @@ declare namespace Phaser { function SetY(items: G, value: number, step?: number, index?: number, direction?: number): G; /** - * Iterate through the items array changing the position of each element to be that of the element that came before - * it in the array (or after it if direction = 1) + * Takes an array of items, such as Game Objects, or any objects with public `x` and + * `y` properties and then iterates through them. As this function iterates, it moves + * the position of the current element to be that of the previous entry in the array. + * This repeats until all items have been moved. * - * The first items position is set to x/y. + * The direction controls the order of iteration. A value of 0 (the default) assumes + * that the final item in the array is the 'head' item. * - * The final x/y coords are returned - * @param items An array of Game Objects. The contents of this array are updated by this Action. - * @param x The x coordinate to place the first item in the array at. - * @param y The y coordinate to place the first item in the array at. + * A direction value of 1 assumes that the first item in the array is the 'head' item. + * + * The position of the 'head' item is set to the x/y values given to this function. + * Every other item in the array is then updated, in sequence, to be that of the + * previous (or next) entry in the array. + * + * The final x/y coords are returned, or set in the 'output' Vector2. + * + * Think of it as being like the game Snake, where the 'head' is moved and then + * each body piece is moved into the space of the previous piece. + * @param items An array of Game Objects, or objects with public x and y positions. The contents of this array are updated by this Action. + * @param x The x coordinate to place the head item at. + * @param y The y coordinate to place the head item at. * @param direction The iteration direction. 0 = first to last and 1 = last to first. Default 0. - * @param output An optional objec to store the final objects position in. + * @param output An optional Vec2Like object to store the final position in. */ function ShiftPosition(items: G, x: number, y: number, direction?: number, output?: O): O; @@ -680,9 +694,11 @@ declare namespace Phaser { function ToggleVisible(items: G): G; /** - * Wrap each item's coordinates within a rectangle's area. + * Iterates through the given array and makes sure that each objects x and y + * properties are wrapped to keep them contained within the given Rectangles + * area. * @param items An array of Game Objects. The contents of this array are updated by this Action. - * @param rect The rectangle. + * @param rect The rectangle which the objects will be wrapped to remain within. * @param padding An amount added to each side of the rectangle during the operation. Default 0. */ function WrapInRectangle(items: G, rect: Phaser.Geom.Rectangle, padding?: number): G; @@ -775,6 +791,14 @@ declare namespace Phaser { */ yoyo: boolean; + /** + * If the animation has a delay set, before playback will begin, this + * controls when the first frame is set on the Sprite. If this property + * is 'false' then the frame is set only after the delay has expired. + * This is the default behavior. + */ + showBeforeDelay: boolean; + /** * Should the GameObject's `visible` property be set to `true` when the animation starts to play? */ @@ -799,10 +823,10 @@ declare namespace Phaser { * Calculates the duration, frame rate and msPerFrame values. * @param target The target to set the values on. * @param totalFrames The total number of frames in the animation. - * @param duration The duration to calculate the frame rate from. - * @param frameRate The frame ate to calculate the duration from. + * @param duration The duration to calculate the frame rate from. Pass `null` if you wish to set the `frameRate` instead. + * @param frameRate The frame rate to calculate the duration from. */ - calculateDuration(target: Phaser.Animations.Animation, totalFrames: number, duration: number, frameRate: number): void; + calculateDuration(target: Phaser.Animations.Animation, totalFrames: number, duration?: number | undefined, frameRate?: number | undefined): void; /** * Add frames to the end of the animation. @@ -976,12 +1000,12 @@ declare namespace Phaser { /** * A reference to the AnimationFrame that comes before this one in the animation, if any. */ - readonly prevFrame: Phaser.Animations.AnimationFrame; + readonly prevFrame: Phaser.Animations.AnimationFrame | null; /** * A reference to the AnimationFrame that comes after this one in the animation, if any. */ - readonly nextFrame: Phaser.Animations.AnimationFrame; + readonly nextFrame: Phaser.Animations.AnimationFrame | null; /** * Additional time (in ms) that this frame should appear for during playback. @@ -1210,8 +1234,9 @@ declare namespace Phaser { * This will only create the 3 animations defined. Note that the tag names are case-sensitive. * @param key The key of the loaded Aseprite atlas. It must have been loaded prior to calling this method. * @param tags An array of Tag names. If provided, only animations found in this array will be created. + * @param target Create the animations on this target Sprite. If not given, they will be created globally in this Animation Manager. */ - createFromAseprite(key: string, tags?: string[]): Phaser.Animations.Animation[]; + createFromAseprite(key: string, tags?: string[], target?: Phaser.Animations.AnimationManager | Phaser.GameObjects.GameObject): Phaser.Animations.Animation[]; /** * Creates a new Animation and adds it to the Animation Manager. @@ -1242,14 +1267,15 @@ declare namespace Phaser { * Generates objects with string based frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNames}. * * It's a helper method, designed to make it easier for you to extract all of the frame names from texture atlases. + * * If you're working with a sprite sheet, see the `generateFrameNumbers` method instead. * * Example: * * If you have a texture atlases loaded called `gems` and it contains 6 frames called `ruby_0001`, `ruby_0002`, and so on, - * then you can call this method using: `this.anims.generateFrameNames('gems', { prefix: 'ruby_', end: 6, zeroPad: 4 })`. + * then you can call this method using: `this.anims.generateFrameNames('gems', { prefix: 'ruby_', start: 1, end: 6, zeroPad: 4 })`. * - * The `end` value tells it to look for 6 frames, incrementally numbered, all starting with the prefix `ruby_`. The `zeroPad` + * The `end` value tells it to select frames 1 through 6, incrementally numbered, all starting with the prefix `ruby_`. The `zeroPad` * value tells it how many zeroes pad out the numbers. To create an animation using this method, you can do: * * ```javascript @@ -1278,7 +1304,6 @@ declare namespace Phaser { * If you're working with a texture atlas, see the `generateFrameNames` method instead. * * It's a helper method, designed to make it easier for you to extract frames from sprite sheets. - * If you're working with a texture atlas, see the `generateFrameNames` method instead. * * Example: * @@ -1293,7 +1318,7 @@ declare namespace Phaser { * ```javascript * this.anims.create({ * key: 'boom', - * frames: this.anims.generateFrameNames('explosion', { + * frames: this.anims.generateFrameNumbers('explosion', { * start: 0, * end: 11 * }) @@ -1312,7 +1337,7 @@ declare namespace Phaser { * @param key The key for the texture containing the animation frames. * @param config The configuration object for the animation frames. */ - generateFrameNumbers(key: string, config: Phaser.Types.Animations.GenerateFrameNumbers): Phaser.Types.Animations.AnimationFrame[]; + generateFrameNumbers(key: string, config?: Phaser.Types.Animations.GenerateFrameNumbers): Phaser.Types.Animations.AnimationFrame[]; /** * Get an Animation. @@ -1320,6 +1345,14 @@ declare namespace Phaser { */ get(key: string): Phaser.Animations.Animation; + /** + * Returns an array of all Animation keys that are using the given + * Texture. Only Animations that have at least one AnimationFrame + * entry using this texture will be included in the result. + * @param key The unique string-based key of the Texture, or a Texture, or Frame instance. + */ + getAnimsFromTexture(key: string | Phaser.Textures.Texture | Phaser.Textures.Frame): string[]; + /** * Pause all animations. */ @@ -1461,14 +1494,14 @@ declare namespace Phaser { * * Will by `null` if no animation is yet loaded. */ - currentAnim: Phaser.Animations.Animation; + currentAnim: Phaser.Animations.Animation | null; /** * The current AnimationFrame being displayed by this Animation component. * * Will by `null` if no animation is yet loaded. */ - currentFrame: Phaser.Animations.AnimationFrame; + currentFrame: Phaser.Animations.AnimationFrame | null; /** * The key, instance, or config of the next Animation to be loaded into this Animation component @@ -1476,7 +1509,7 @@ declare namespace Phaser { * * Will by `null` if no animation has been queued. */ - nextAnim: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig; + nextAnim: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig | null; /** * A queue of Animations to be loaded into this Animation component when the current animation completes. @@ -1580,6 +1613,17 @@ declare namespace Phaser { */ yoyo: boolean; + /** + * If the animation has a delay set, before playback will begin, this + * controls when the first frame is set on the Sprite. If this property + * is 'false' then the frame is set only after the delay has expired. + * This is the default behavior. + * + * If this property is 'true' then the first frame of this animation + * is set immediately, and then when the delay expires, playback starts. + */ + showBeforeDelay: boolean; + /** * Should the GameObject's `visible` property be set to `true` when the animation starts to play? * @@ -1662,7 +1706,7 @@ declare namespace Phaser { * Call this method with no arguments to reset all currently chained animations. * @param key The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them. */ - chain(key: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig | string[] | Phaser.Animations.Animation[] | Phaser.Types.Animations.PlayAnimationConfig[]): Phaser.GameObjects.GameObject; + chain(key?: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig | string[] | Phaser.Animations.Animation[] | Phaser.Types.Animations.PlayAnimationConfig[]): Phaser.GameObjects.GameObject; /** * Returns the key of the animation currently loaded into this component. @@ -2037,6 +2081,84 @@ declare namespace Phaser { */ create(config: Phaser.Types.Animations.Animation): Phaser.Animations.Animation | false; + /** + * Create one, or more animations from a loaded Aseprite JSON file. + * + * Aseprite is a powerful animated sprite editor and pixel art tool. + * + * You can find more details at https://www.aseprite.org/ + * + * To export a compatible JSON file in Aseprite, please do the following: + * + * 1. Go to "File - Export Sprite Sheet" + * + * 2. On the **Layout** tab: + * 2a. Set the "Sheet type" to "Packed" + * 2b. Set the "Constraints" to "None" + * 2c. Check the "Merge Duplicates" checkbox + * + * 3. On the **Sprite** tab: + * 3a. Set "Layers" to "Visible layers" + * 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags + * + * 4. On the **Borders** tab: + * 4a. Check the "Trim Sprite" and "Trim Cells" options + * 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough) + * + * 5. On the **Output** tab: + * 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type + * 5b. Check "JSON Data" and give your json file a name + * 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind. + * 5d. Make sure "Tags" is checked in the Meta options + * 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more. + * + * 6. Click export + * + * This was tested with Aseprite 1.2.25. + * + * This will export a png and json file which you can load using the Aseprite Loader, i.e.: + * + * ```javascript + * function preload () + * { + * this.load.path = 'assets/animations/aseprite/'; + * this.load.aseprite('paladin', 'paladin.png', 'paladin.json'); + * } + * ``` + * + * Once loaded, you can call this method on a Sprite with the 'atlas' key: + * + * ```javascript + * const sprite = this.add.sprite(400, 300); + * + * sprite.anims.createFromAseprite('paladin'); + * ``` + * + * Any animations defined in the JSON will now be available to use on this Sprite and you play them + * via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline, + * you can play it on the Sprite using that Tag name: + * + * ```javascript + * const sprite = this.add.sprite(400, 300); + * + * sprite.anims.createFromAseprite('paladin'); + * + * sprite.play('War Cry'); + * ``` + * + * When calling this method you can optionally provide an array of tag names, and only those animations + * will be created. For example: + * + * ```javascript + * sprite.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]); + * ``` + * + * This will only create the 3 animations defined. Note that the tag names are case-sensitive. + * @param key The key of the loaded Aseprite atlas. It must have been loaded prior to calling this method. + * @param tags An array of Tag names. If provided, only animations found in this array will be created. + */ + createFromAseprite(key: string, tags?: string[]): Phaser.Animations.Animation[]; + /** * Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object. * @@ -2084,16 +2206,16 @@ declare namespace Phaser { * Example: * * If you have a sprite sheet loaded called `explosion` and it contains 12 frames, then you can call this method using: - * `this.anims.generateFrameNumbers('explosion', { start: 0, end: 12 })`. + * `this.anims.generateFrameNumbers('explosion', { start: 0, end: 11 })`. * * The `end` value tells it to stop after 12 frames. To create an animation using this method, you can do: * * ```javascript * this.anims.create({ * key: 'boom', - * frames: this.anims.generateFrameNames('explosion', { + * frames: this.anims.generateFrameNumbers('explosion', { * start: 0, - * end: 12 + * end: 11 * }) * }); * ``` @@ -2110,7 +2232,7 @@ declare namespace Phaser { * @param key The key for the texture containing the animation frames. * @param config The configuration object for the animation frames. */ - generateFrameNumbers(key: string, config: Phaser.Types.Animations.GenerateFrameNumbers): Phaser.Types.Animations.AnimationFrame[]; + generateFrameNumbers(key: string, config?: Phaser.Types.Animations.GenerateFrameNumbers): Phaser.Types.Animations.AnimationFrame[]; /** * Removes a locally created Animation from this Sprite, based on the given key. @@ -2143,7 +2265,7 @@ declare namespace Phaser { * This can happen either as a result of an animation instance being added to the Animation Manager, * or the Animation Manager creating a new animation directly. */ - const ADD_ANIMATION: any; + const ADD_ANIMATION: string; /** * The Animation Complete Event. @@ -2170,7 +2292,7 @@ declare namespace Phaser { * * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. */ - const ANIMATION_COMPLETE: any; + const ANIMATION_COMPLETE: string; /** * The Animation Complete Dynamic Key Event. @@ -2201,7 +2323,7 @@ declare namespace Phaser { * * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. */ - const ANIMATION_COMPLETE_KEY: any; + const ANIMATION_COMPLETE_KEY: string; /** * The Animation Repeat Event. @@ -2225,7 +2347,7 @@ declare namespace Phaser { * * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. */ - const ANIMATION_REPEAT: any; + const ANIMATION_REPEAT: string; /** * The Animation Restart Event. @@ -2247,7 +2369,7 @@ declare namespace Phaser { * * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. */ - const ANIMATION_RESTART: any; + const ANIMATION_RESTART: string; /** * The Animation Start Event. @@ -2270,7 +2392,7 @@ declare namespace Phaser { * * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. */ - const ANIMATION_START: any; + const ANIMATION_START: string; /** * The Animation Stop Event. @@ -2293,13 +2415,13 @@ declare namespace Phaser { * * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. */ - const ANIMATION_STOP: any; + const ANIMATION_STOP: string; /** * The Animation Update Event. * * This event is dispatched by a Sprite when an animation playing on it updates. This happens when the animation changes frame. - * An animation will change frame based on the frme rate and other factors like `timeScale` and `delay`. It can also change + * An animation will change frame based on the frame rate and other factors like `timeScale` and `delay`. It can also change * frame when stopped or restarted. * * Listen for it on the Sprite using `sprite.on('animationupdate', listener)` @@ -2320,7 +2442,7 @@ declare namespace Phaser { * * If the animation is restarted while it is already playing, `ANIMATION_RESTART` is emitted. */ - const ANIMATION_UPDATE: any; + const ANIMATION_UPDATE: string; /** * The Pause All Animations Event. @@ -2330,14 +2452,14 @@ declare namespace Phaser { * When this happens all current animations will stop updating, although it doesn't necessarily mean * that the game has paused as well. */ - const PAUSE_ALL: any; + const PAUSE_ALL: string; /** * The Remove Animation Event. * * This event is dispatched when an animation is removed from the global Animation Manager. */ - const REMOVE_ANIMATION: any; + const REMOVE_ANIMATION: string; /** * The Resume All Animations Event. @@ -2346,7 +2468,7 @@ declare namespace Phaser { * * When this happens all current animations will continue updating again. */ - const RESUME_ALL: any; + const RESUME_ALL: string; } @@ -2531,14 +2653,14 @@ declare namespace Phaser { * * This event is dispatched by any Cache that extends the BaseCache each time a new object is added to it. */ - const ADD: any; + const ADD: string; /** * The Cache Remove Event. * * This event is dispatched by any Cache that extends the BaseCache each time an object is removed from it. */ - const REMOVE: any; + const REMOVE: string; } @@ -2712,7 +2834,7 @@ declare namespace Phaser { * The Mask this Camera is using during render. * Set the mask using the `setMask` method. Remove the mask using the `clearMask` method. */ - mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask | null; /** * This array is populated with all of the Game Objects that this Camera has rendered @@ -2726,6 +2848,12 @@ declare namespace Phaser { */ renderList: Phaser.GameObjects.GameObject[]; + /** + * Is this Camera a Scene Camera? (which is the default), or a Camera + * belonging to a Texture? + */ + isSceneCamera: boolean; + /** * Adds the given Game Object to this cameras render list. * @@ -2818,7 +2946,7 @@ declare namespace Phaser { * so that they are ignored by this Camera. This means they will not be rendered by this Camera. * @param entries The Game Object, or array of Game Objects, to be ignored by this Camera. */ - ignore(entries: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[] | Phaser.GameObjects.Group): this; + ignore(entries: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[] | Phaser.GameObjects.Group | Phaser.GameObjects.Layer | Phaser.GameObjects.Layer[]): this; /** * Internal preRender step. @@ -2934,8 +3062,9 @@ declare namespace Phaser { /** * Sets the Scene the Camera is bound to. * @param scene The Scene the camera is bound to. + * @param isSceneCamera Is this Camera being used for a Scene (true) or a Texture? (false) Default true. */ - setScene(scene: Phaser.Scene): this; + setScene(scene: Phaser.Scene, isSceneCamera?: boolean): this; /** * Set the position of where the Camera is looking within the game. @@ -3034,6 +3163,13 @@ declare namespace Phaser { */ protected update(time: number, delta: number): void; + /** + * Set if this Camera is being used as a Scene Camera, or a Texture + * Camera. + * @param value Is this being used as a Scene Camera, or a Texture camera? + */ + setIsSceneCamera(value: boolean): void; + /** * Destroys this Camera instance and its internal properties and references. * Once destroyed you cannot use this Camera again, even if re-added to a Camera Manager. @@ -3225,7 +3361,7 @@ declare namespace Phaser { * * A Camera also has built-in special effects including Fade, Flash and Camera Shake. */ - class Camera extends Phaser.Cameras.Scene2D.BaseCamera implements Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Pipeline { + class Camera extends Phaser.Cameras.Scene2D.BaseCamera implements Phaser.GameObjects.Components.PostPipeline { /** * * @param x The x position of the Camera, relative to the top-left of the game canvas. @@ -3316,7 +3452,7 @@ declare namespace Phaser { * Calling `setDeadzone` with no arguments will reset an active deadzone, as will setting this property * to `null`. */ - deadzone: Phaser.Geom.Rectangle; + deadzone: Phaser.Geom.Rectangle | null; /** * Sets the Camera dead zone. @@ -3563,223 +3699,82 @@ declare namespace Phaser { alphaBottomRight: number; /** - * The horizontally flipped state of the Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - flipX: boolean; - - /** - * The vertically flipped state of the Game Object. - * - * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - flipY: boolean; - - /** - * Toggles the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - toggleFlipX(): this; - - /** - * Toggles the vertical flipped state of this Game Object. - */ - toggleFlipY(): this; - - /** - * Sets the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlipX(value: boolean): this; - - /** - * Sets the vertical flipped state of this Game Object. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. + * Does this Game Object have any Post Pipelines set? */ - setFlipY(value: boolean): this; + hasPostPipeline: boolean; /** - * Sets the horizontal and vertical flipped state of this Game Object. + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. * - * A Game Object that is flipped will render inversed on the flipped axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. - * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlip(x: boolean, y: boolean): this; - - /** - * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. - */ - resetFlip(): this; - - /** - * The tint value being applied to the top-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintTopLeft: number; - - /** - * The tint value being applied to the top-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintTopRight: number; - - /** - * The tint value being applied to the bottom-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintBottomLeft: number; - - /** - * The tint value being applied to the bottom-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintBottomRight: number; - - /** - * The tint fill mode. + * The pipelines are processed in the order in which they appear in this array. * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. */ - tintFill: boolean; + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; /** - * Clears all tint values associated with this Game Object. - * - * Immediately sets the color values back to 0xffffff and the tint type to 'additive', - * which results in no visible change to the texture. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - clearTint(): this; + postPipelineData: object; /** - * Sets an additive tint on this Game Object. + * The Pre FX component of this Game Object. * - * The tint works by taking the pixel color values from the Game Objects texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole Game Object will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the Game Object. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` * - * To remove a tint call `clearTint`. + * Only the following Game Objects support Pre FX: * - * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. - * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. - */ - setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - - /** - * Sets a fill-based tint on this Game Object. + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video * - * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture - * with those in the tint. You can use this for effects such as making a player flash 'white' - * if hit by something. You can provide either one color value, in which case the whole - * Game Object will be rendered in that color. Or you can provide a color per corner. The colors - * are blended together across the extent of the Game Object. + * All FX are WebGL only and do not have Canvas counterparts. * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. - * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. + * Please see the FX Class for more details and available methods. */ - setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + preFX: Phaser.GameObjects.Components.FX | null; /** - * The tint value being applied to the whole of the Game Object. - * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. - */ - tint: number; - - /** - * Does this Game Object have a tint applied? + * The Post FX component of this Game Object. * - * It checks to see if the 4 tint properties are set to the value 0xffffff - * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. - */ - readonly isTinted: boolean; - - /** - * The initial WebGL pipeline of this Game Object. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. - */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; - - /** - * The current WebGL pipeline of this Game Object. - */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; - - /** - * Does this Game Object have any Post Pipelines set? - */ - hasPostPipeline: boolean; - - /** - * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` * - * The pipelines are processed in the order in which they appear in this array. + * All FX are WebGL only and do not have Canvas counterparts. * - * If you modify this array directly, be sure to set the - * `hasPostPipeline` property accordingly. - */ - postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - - /** - * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. - */ - pipelineData: object; - - /** - * Sets the initial WebGL Pipeline of this Game Object. + * Please see the FX Class for more details and available methods. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This property is always `null` until the `initPostPipeline` method is called. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + postFX: Phaser.GameObjects.Components.FX; /** - * Sets the main WebGL Pipeline of this Game Object. + * This should only be called during the instantiation of the Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * It is called by default by all core Game Objects and doesn't need + * calling again. * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -3795,27 +3790,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -3823,17 +3814,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -3846,9 +3830,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; } @@ -3976,7 +3964,7 @@ declare namespace Phaser { * @param camera The Camera to be added to the Camera Manager. * @param makeMain Set this Camera as being the 'main' camera. This just makes the property `main` a reference to it. Default false. */ - addExisting(camera: Phaser.Cameras.Scene2D.Camera, makeMain?: boolean): Phaser.Cameras.Scene2D.Camera; + addExisting(camera: Phaser.Cameras.Scene2D.Camera, makeMain?: boolean): Phaser.Cameras.Scene2D.Camera | null; /** * Gets the total number of Cameras in this Camera Manager. @@ -4001,7 +3989,7 @@ declare namespace Phaser { * have given your Cameras unique names. * @param name The name of the Camera. */ - getCamera(name: string): Phaser.Cameras.Scene2D.Camera; + getCamera(name: string): Phaser.Cameras.Scene2D.Camera | null; /** * Returns an array of all cameras below the given Pointer. @@ -4040,7 +4028,7 @@ declare namespace Phaser { * containing only those Game Objects that pass the `willRender` test * against the given Camera. * @param children An array of Game Objects to be checked against the camera. - * @param camera The camera to filte the Game Objects against. + * @param camera The camera to filter the Game Objects against. */ getVisibleChildren(children: Phaser.GameObjects.GameObject[], camera: Phaser.Cameras.Scene2D.Camera): Phaser.GameObjects.GameObject[]; @@ -4213,6 +4201,12 @@ declare namespace Phaser { */ readonly duration: number; + /** + * The value of the alpha channel used during the flash effect. + * A value between 0 and 1. + */ + alpha: number; + /** * If this effect is running this holds the current percentage of the progress, a value between 0 and 1. */ @@ -4664,8 +4658,20 @@ declare namespace Phaser { * The Destroy Camera Event. * * This event is dispatched by a Camera instance when it is destroyed by the Camera Manager. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('cameradestroy', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.DESTROY, () => {}); + * ``` */ - const DESTROY: any; + const DESTROY: string; /** * The Camera Fade In Complete Event. @@ -4674,7 +4680,7 @@ declare namespace Phaser { * * Listen to it from a Camera instance using `Camera.on('camerafadeincomplete', listener)`. */ - const FADE_IN_COMPLETE: any; + const FADE_IN_COMPLETE: string; /** * The Camera Fade In Start Event. @@ -4683,7 +4689,7 @@ declare namespace Phaser { * * Listen to it from a Camera instance using `Camera.on('camerafadeinstart', listener)`. */ - const FADE_IN_START: any; + const FADE_IN_START: string; /** * The Camera Fade Out Complete Event. @@ -4692,7 +4698,7 @@ declare namespace Phaser { * * Listen to it from a Camera instance using `Camera.on('camerafadeoutcomplete', listener)`. */ - const FADE_OUT_COMPLETE: any; + const FADE_OUT_COMPLETE: string; /** * The Camera Fade Out Start Event. @@ -4701,21 +4707,45 @@ declare namespace Phaser { * * Listen to it from a Camera instance using `Camera.on('camerafadeoutstart', listener)`. */ - const FADE_OUT_START: any; + const FADE_OUT_START: string; /** * The Camera Flash Complete Event. * * This event is dispatched by a Camera instance when the Flash Effect completes. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('cameraflashcomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.FLASH_COMPLETE, () => {}); + * ``` */ - const FLASH_COMPLETE: any; + const FLASH_COMPLETE: string; /** * The Camera Flash Start Event. * * This event is dispatched by a Camera instance when the Flash Effect starts. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('cameraflashstart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.FLASH_START, () => {}); + * ``` */ - const FLASH_START: any; + const FLASH_START: string; /** * The Camera Follower Update Event. @@ -4726,21 +4756,45 @@ declare namespace Phaser { * * Listen to it from a Camera instance using: `camera.on('followupdate', listener)`. */ - const FOLLOW_UPDATE: any; + const FOLLOW_UPDATE: string; /** * The Camera Pan Complete Event. * * This event is dispatched by a Camera instance when the Pan Effect completes. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerapancomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.PAN_COMPLETE, () => {}); + * ``` */ - const PAN_COMPLETE: any; + const PAN_COMPLETE: string; /** * The Camera Pan Start Event. * * This event is dispatched by a Camera instance when the Pan Effect starts. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerapanstart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.PAN_START, () => {}); + * ``` */ - const PAN_START: any; + const PAN_START: string; /** * The Camera Post-Render Event. @@ -4750,7 +4804,7 @@ declare namespace Phaser { * * Listen to it from a Camera instance using: `camera.on('postrender', listener)`. */ - const POST_RENDER: any; + const POST_RENDER: string; /** * The Camera Pre-Render Event. @@ -4760,49 +4814,121 @@ declare namespace Phaser { * * Listen to it from a Camera instance using: `camera.on('prerender', listener)`. */ - const PRE_RENDER: any; + const PRE_RENDER: string; /** * The Camera Rotate Complete Event. * * This event is dispatched by a Camera instance when the Rotate Effect completes. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerarotatecomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.ROTATE_COMPLETE, () => {}); + * ``` */ - const ROTATE_COMPLETE: any; + const ROTATE_COMPLETE: string; /** * The Camera Rotate Start Event. * * This event is dispatched by a Camera instance when the Rotate Effect starts. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerarotatestart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.ROTATE_START, () => {}); + * ``` */ - const ROTATE_START: any; + const ROTATE_START: string; /** * The Camera Shake Complete Event. * * This event is dispatched by a Camera instance when the Shake Effect completes. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerashakecomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.SHAKE_COMPLETE, () => {}); + * ``` */ - const SHAKE_COMPLETE: any; + const SHAKE_COMPLETE: string; /** * The Camera Shake Start Event. * * This event is dispatched by a Camera instance when the Shake Effect starts. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerashakestart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.SHAKE_START, () => {}); + * ``` */ - const SHAKE_START: any; + const SHAKE_START: string; /** * The Camera Zoom Complete Event. * * This event is dispatched by a Camera instance when the Zoom Effect completes. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerazoomcomplete', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.ZOOM_COMPLETE, () => {}); + * ``` */ - const ZOOM_COMPLETE: any; + const ZOOM_COMPLETE: string; /** * The Camera Zoom Start Event. * * This event is dispatched by a Camera instance when the Zoom Effect starts. + * + * Listen for it via either of the following: + * + * ```js + * this.cameras.main.on('camerazoomstart', () => {}); + * ``` + * + * or use the constant, to avoid having to remember the correct event string: + * + * ```js + * this.cameras.main.on(Phaser.Cameras.Scene2D.Events.ZOOM_START, () => {}); + * ``` */ - const ZOOM_START: any; + const ZOOM_START: string; } @@ -4837,37 +4963,37 @@ declare namespace Phaser { /** * The Camera that this Control will update. */ - camera: Phaser.Cameras.Scene2D.Camera; + camera: Phaser.Cameras.Scene2D.Camera | null; /** * The Key to be pressed that will move the Camera left. */ - left: Phaser.Input.Keyboard.Key; + left: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will move the Camera right. */ - right: Phaser.Input.Keyboard.Key; + right: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will move the Camera up. */ - up: Phaser.Input.Keyboard.Key; + up: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will move the Camera down. */ - down: Phaser.Input.Keyboard.Key; + down: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will zoom the Camera in. */ - zoomIn: Phaser.Input.Keyboard.Key; + zoomIn: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will zoom the Camera out. */ - zoomOut: Phaser.Input.Keyboard.Key; + zoomOut: Phaser.Input.Keyboard.Key | null; /** * The speed at which the camera will zoom if the `zoomIn` or `zoomOut` keys are pressed. @@ -4964,37 +5090,37 @@ declare namespace Phaser { /** * The Camera that this Control will update. */ - camera: Phaser.Cameras.Scene2D.Camera; + camera: Phaser.Cameras.Scene2D.Camera | null; /** * The Key to be pressed that will move the Camera left. */ - left: Phaser.Input.Keyboard.Key; + left: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will move the Camera right. */ - right: Phaser.Input.Keyboard.Key; + right: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will move the Camera up. */ - up: Phaser.Input.Keyboard.Key; + up: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will move the Camera down. */ - down: Phaser.Input.Keyboard.Key; + down: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will zoom the Camera in. */ - zoomIn: Phaser.Input.Keyboard.Key; + zoomIn: Phaser.Input.Keyboard.Key | null; /** * The Key to be pressed that will zoom the Camera out. */ - zoomOut: Phaser.Input.Keyboard.Key; + zoomOut: Phaser.Input.Keyboard.Key | null; /** * The speed at which the camera will zoom if the `zoomIn` or `zoomOut` keys are pressed. @@ -5234,7 +5360,9 @@ declare namespace Phaser { cache: Phaser.Cache.CacheManager; /** - * An instance of the Data Manager + * An instance of the Data Manager. This is a global manager, available from any Scene + * and allows you to share and exchange your own game-level data or events without having + * to use an internal event system. */ registry: Phaser.Data.DataManager; @@ -5306,6 +5434,13 @@ declare namespace Phaser { */ readonly hasFocus: boolean; + /** + * Is the Game currently paused? This will stop everything from updating, + * except the `TimeStep` and related RequestAnimationFrame or setTimeout. + * Those will continue stepping, but the core Game step will be skipped. + */ + isPaused: boolean; + /** * This method is called automatically when the DOM is ready. It is responsible for creating the renderer, * displaying the Debug Header, adding the game canvas to the DOM and emitting the 'boot' event. @@ -5352,12 +5487,28 @@ declare namespace Phaser { */ protected onHidden(): void; + /** + * This will pause the entire game and emit a `PAUSE` event. + * + * All of Phaser's internal systems will be paused and the game will not re-render. + * + * Note that it does not pause any Loader requests that are currently in-flight. + */ + pause(): void; + /** * Called automatically by the Visibility Handler. * This will resume the main loop and then emit a resume event. */ protected onVisible(): void; + /** + * This will resume the entire game and emit a `RESUME` event. + * + * All of Phaser's internal systems will be resumed and the game will start rendering again. + */ + resume(): void; + /** * Called automatically by the Visibility Handler. * This will set the main loop into a 'blurred' state, which pauses it. @@ -5427,7 +5578,7 @@ declare namespace Phaser { /** * A parent DOM element into which the canvas created by the renderer will be injected. */ - readonly parent: any; + readonly parent: any | null; /** * The scale mode as used by the Scale Manager. The default is zero, which is no scaling. @@ -5457,7 +5608,7 @@ declare namespace Phaser { /** * The DOM element that will be sent into full screen mode, or its `id`. If undefined Phaser will create its own div and insert the canvas into it when entering fullscreen mode. */ - readonly fullscreenTarget: HTMLElement | string; + readonly fullscreenTarget: HTMLElement | string | null; /** * The minimum width, in pixels, the canvas will scale down to. A value of zero means no minimum. @@ -5487,17 +5638,17 @@ declare namespace Phaser { /** * Force Phaser to use your own Canvas element instead of creating one. */ - readonly canvas: HTMLCanvasElement; + readonly canvas: HTMLCanvasElement | null; /** * Force Phaser to use your own Canvas context instead of creating one. */ - readonly context: CanvasRenderingContext2D | WebGLRenderingContext; + readonly context: CanvasRenderingContext2D | WebGLRenderingContext | null; /** * Optional CSS attributes to be set on the canvas object created by the renderer. */ - readonly canvasStyle: string; + readonly canvasStyle: string | null; /** * Is Phaser running under a custom (non-native web) environment? If so, set this to `true` to skip internal Feature detection. If `true` the `renderType` cannot be left as `AUTO`. @@ -5507,7 +5658,7 @@ declare namespace Phaser { /** * The default Scene configuration object. */ - readonly sceneConfig: object; + readonly sceneConfig: object | null; /** * A seed which the Random Data Generator will use. If not given, a dynamic seed based on the time is used. @@ -5535,19 +5686,19 @@ declare namespace Phaser { readonly autoFocus: boolean; /** - * Should the game create a div element to act as a DOM Container? Only enable if you're using DOM Element objects. You must provide a parent object if you use this feature. + * `false` or `0` = Use the built-in StableSort (needed for older browsers), `true` or `1` = Rely on ES2019 Array.sort being stable (modern browsers only), or `-1` = Try and determine this automatically based on browser inspection (not guaranteed to work, errs on side of caution). */ - readonly domCreateContainer: boolean; + readonly stableSort: number | boolean; /** - * Should the DOM Container that is created (if `dom.createContainer` is true) be positioned behind (true) or over the top (false, the default) of the game canvas? + * Should the game create a div element to act as a DOM Container? Only enable if you're using DOM Element objects. You must provide a parent object if you use this feature. */ - readonly domBehindCanvas: boolean; + readonly domCreateContainer: boolean | null; /** * The default `pointerEvents` attribute set on the DOM Container. */ - readonly domPointerEvents: string; + readonly domPointerEvents: string | null; /** * Enable the Keyboard Plugin. This can be disabled in games that don't need keyboard input. @@ -5562,7 +5713,7 @@ declare namespace Phaser { /** * `preventDefault` will be called on every non-modified key which has a key code in this array. By default, it is empty. */ - readonly inputKeyboardCapture: number[]; + readonly inputKeyboardCapture: number[] | null; /** * Enable the Mouse Plugin. This can be disabled in games that don't need mouse input. @@ -5572,7 +5723,7 @@ declare namespace Phaser { /** * The DOM Target to listen for mouse events on. Defaults to the game canvas if not specified. */ - readonly inputMouseEventTarget: any; + readonly inputMouseEventTarget: any | null; /** * Should `mousedown` DOM events have `preventDefault` called on them? @@ -5602,7 +5753,7 @@ declare namespace Phaser { /** * The DOM Target to listen for touch events on. Defaults to the game canvas if not specified. */ - readonly inputTouchEventTarget: any; + readonly inputTouchEventTarget: any | null; /** * Should touch events be captured? I.e. have prevent default called on them. @@ -5674,6 +5825,16 @@ declare namespace Phaser { */ readonly pipeline: Phaser.Types.Core.PipelineConfig; + /** + * Automatically enable the Mobile Pipeline if iOS or Android detected? + */ + readonly autoMobilePipeline: boolean; + + /** + * The WebGL Pipeline that Game Objects will use by default. Set to 'MultiPipeline' as standard. See also 'autoMobilePipeline'. + */ + readonly defaultPipeline: string; + /** * When set to `true`, WebGL uses linear interpolation to draw scaled or rotated textures, giving a smooth appearance. When set to `false`, WebGL uses nearest-neighbor interpolation, giving a crisper appearance. `false` also disables antialiasing of the game canvas itself, if the browser supports it, when the game canvas is scaled. */ @@ -5824,6 +5985,26 @@ declare namespace Phaser { */ readonly loaderWithCredentials: boolean; + /** + * Optional load type for image, `XHR` is default, or `HTMLImageElement` for a lightweight way. + */ + readonly loaderImageLoadType: string; + + /** + * An array of schemes that the Loader considers as being 'local' files. Defaults to: `[ 'file://', 'capacitor://' ]`. + */ + readonly loaderLocalScheme: string[]; + + /** + * The quality of the Glow FX (defaults to 0.1) + */ + readonly glowFXQuality: number; + + /** + * The distance of the Glow FX (defaults to 10) + */ + readonly glowFXDistance: number; + /** * An array of global plugins to be installed. */ @@ -5880,7 +6061,7 @@ declare namespace Phaser { * enters a blurred state. The blur event is raised when the window loses focus. This can happen if a user swaps * tab, or if they simply remove focus from the browser to another app. */ - const BLUR: any; + const BLUR: string; /** * The Game Boot Event. @@ -5888,25 +6069,16 @@ declare namespace Phaser { * This event is dispatched when the Phaser Game instance has finished booting, but before it is ready to start running. * The global systems use this event to know when to set themselves up, dispatching their own `ready` events as required. */ - const BOOT: any; + const BOOT: string; /** * The Game Context Lost Event. * * This event is dispatched by the Game if the WebGL Renderer it is using encounters a WebGL Context Lost event from the browser. * - * The partner event is `CONTEXT_RESTORED`. + * The renderer halts all rendering and cannot resume after this happens. */ - const CONTEXT_LOST: any; - - /** - * The Game Context Restored Event. - * - * This event is dispatched by the Game if the WebGL Renderer it is using encounters a WebGL Context Restored event from the browser. - * - * The partner event is `CONTEXT_LOST`. - */ - const CONTEXT_RESTORED: any; + const CONTEXT_LOST: string; /** * The Game Destroy Event. @@ -5915,7 +6087,7 @@ declare namespace Phaser { * Lots of internal systems listen to this event in order to clear themselves out. * Custom plugins and game code should also do the same. */ - const DESTROY: any; + const DESTROY: string; /** * The Game Focus Event. @@ -5923,7 +6095,7 @@ declare namespace Phaser { * This event is dispatched by the Game Visibility Handler when the window in which the Game instance is embedded * enters a focused state. The focus event is raised when the window re-gains focus, having previously lost it. */ - const FOCUS: any; + const FOCUS: string; /** * The Game Hidden Event. @@ -5935,14 +6107,14 @@ declare namespace Phaser { * control the main game loop, will automatically pause. There is no way to stop this from happening. It is something * your game should account for in its own code, should the pause be an issue (i.e. for multiplayer games) */ - const HIDDEN: any; + const HIDDEN: string; /** * The Game Pause Event. * * This event is dispatched when the Game loop enters a paused state, usually as a result of the Visibility Handler. */ - const PAUSE: any; + const PAUSE: string; /** * The Game Post-Render Event. @@ -5952,7 +6124,7 @@ declare namespace Phaser { * Every Scene will have rendered and been drawn to the canvas by the time this event is fired. * Use it for any last minute post-processing before the next game step begins. */ - const POST_RENDER: any; + const POST_RENDER: string; /** * The Game Post-Step Event. @@ -5960,7 +6132,7 @@ declare namespace Phaser { * This event is dispatched after the Scene Manager has updated. * Hook into it from plugins or systems that need to do things before the render starts. */ - const POST_STEP: any; + const POST_STEP: string; /** * The Game Pre-Render Event. @@ -5969,7 +6141,7 @@ declare namespace Phaser { * * The renderer will already have been initialized this frame, clearing itself and preparing to receive the Scenes for rendering, but it won't have actually drawn anything yet. */ - const PRE_RENDER: any; + const PRE_RENDER: string; /** * The Game Pre-Step Event. @@ -5977,7 +6149,7 @@ declare namespace Phaser { * This event is dispatched before the main Game Step starts. By this point in the game cycle none of the Scene updates have yet happened. * Hook into it from plugins or systems that need to update before the Scene Manager does. */ - const PRE_STEP: any; + const PRE_STEP: string; /** * The Game Ready Event. @@ -5985,14 +6157,14 @@ declare namespace Phaser { * This event is dispatched when the Phaser Game instance has finished booting, the Texture Manager is fully ready, * and all local systems are now able to start. */ - const READY: any; + const READY: string; /** * The Game Resume Event. * * This event is dispatched when the game loop leaves a paused state and resumes running. */ - const RESUME: any; + const RESUME: string; /** * The Game Step Event. @@ -6000,7 +6172,7 @@ declare namespace Phaser { * This event is dispatched after the Game Pre-Step and before the Scene Manager steps. * Hook into it from plugins or systems that need to update before the Scene Manager does, but after the core Systems have. */ - const STEP: any; + const STEP: string; /** * The Game Visible Event. @@ -6010,7 +6182,7 @@ declare namespace Phaser { * * Only browsers that support the Visibility API will cause this event to be emitted. */ - const VISIBLE: any; + const VISIBLE: string; } @@ -6060,6 +6232,9 @@ declare namespace Phaser { /** * The minimum fps rate you want the Time Step to run at. + * + * Setting this cannot guarantee the browser runs at this rate, it merely influences + * the internal timing values to help the Timestep know when it has gone out of sync. */ minFps: number; @@ -6072,6 +6247,35 @@ declare namespace Phaser { */ targetFps: number; + /** + * Enforce a frame rate limit. This forces how often the Game step will run. By default it is zero, + * which means it will run at whatever limit the browser (via RequestAnimationFrame) can handle, which + * is the optimum rate for fast-action or responsive games. + * + * However, if you are building a non-game app, like a graphics generator, or low-intensity game that doesn't + * require 60fps, then you can lower the step rate via this Game Config value: + * + * ```js + * fps: { + * limit: 30 + * } + * ``` + * + * Setting this _beyond_ the rate of RequestAnimationFrame will make no difference at all. + * + * Use it purely to _restrict_ updates in low-intensity situations only. + */ + fpsLimit: number; + + /** + * Is the FPS rate limited? + * + * This is set by setting the Game Config `limit` value to a value above zero. + * + * Consider this property as read-only. + */ + hasFpsLimit: boolean; + /** * An exponential moving average of the frames per second. */ @@ -6079,6 +6283,7 @@ declare namespace Phaser { /** * The time at which the next fps rate update will take place. + * * When an fps update happens, the `framesThisSecond` value is reset. */ readonly nextFpsUpdate: number; @@ -6089,29 +6294,35 @@ declare namespace Phaser { readonly framesThisSecond: number; /** - * A callback to be invoked each time the Time Step steps. + * A callback to be invoked each time the TimeStep steps. */ callback: Phaser.Types.Core.TimeStepCallback; /** - * You can force the Time Step to use Set Timeout instead of Request Animation Frame by setting + * You can force the TimeStep to use SetTimeOut instead of Request Animation Frame by setting * the `forceSetTimeOut` property to `true` in the Game Configuration object. It cannot be changed at run-time. */ readonly forceSetTimeOut: boolean; /** - * The time, calculated at the start of the current step, as smoothed by the delta value. + * The time, updated each step by adding the elapsed delta time to the previous value. + * + * This differs from the `TimeStep.now` value, which is the high resolution time value + * as provided by Request Animation Frame. */ time: number; /** - * The time at which the game started running. This value is adjusted if the game is then - * paused and resumes. + * The time at which the game started running. + * + * This value is adjusted if the game is then paused and resumes. */ startTime: number; /** - * The time, as returned by `performance.now` of the previous step. + * The time of the previous step. + * + * This is typically a high resolution timer value, as provided by Request Animation Frame. */ lastTime: number; @@ -6123,6 +6334,7 @@ declare namespace Phaser { /** * 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. */ readonly inFocus: boolean; @@ -6166,7 +6378,10 @@ declare namespace Phaser { rawDelta: number; /** - * The time, as returned by `performance.now` at the very start of the current step. + * The time, set at the start of the current step. + * + * This is typically a high resolution timer value, as provided by Request Animation Frame. + * * This can differ from the `time` value in that it isn't calculated based on the delta value. */ now: number; @@ -6216,12 +6431,55 @@ declare namespace Phaser { */ start(callback: Phaser.Types.Core.TimeStepCallback): void; + /** + * Takes the delta value and smooths it based on the previous frames. + * + * Called automatically as part of the step. + * @param delta The delta value for this step. + */ + smoothDelta(delta: number): number; + + /** + * 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. + * + * Compute the new exponential moving average with an alpha of 0.25. + * @param time The timestamp passed in from RequestAnimationFrame or setTimeout. + */ + updateFPS(time: number): void; + + /** + * The main step method with an fps limiter. 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. + * @param time The timestamp passed in from RequestAnimationFrame or setTimeout. + */ + stepLimitFPS(time: number): void; + /** * 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. + * @param time The timestamp passed in from RequestAnimationFrame or setTimeout. */ - step(): void; + step(time: number): void; /** * Manually calls `TimeStep.step`. @@ -7018,6 +7276,12 @@ declare namespace Phaser { */ getCurveLengths(): number[]; + /** + * Returns the Curve that forms the Path at the given normalized location (between 0 and 1). + * @param t The normalized location on the Path, between 0 and 1. + */ + getCurveAt(t: number): Phaser.Curves.Curve | null; + /** * Returns the ending point of the Path. * @@ -7366,19 +7630,19 @@ declare namespace Phaser { * * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. - * @param key The key to set the value for. Or an object or key value pairs. If an object the `data` argument is ignored. + * @param key The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. * @param data The value to set for the given key. If an object is provided as the key this argument is ignored. */ - set(key: string | object, data: any): this; + set(key: (string|T), data?: any): this; /** * Increase a value for the given key. If the key doesn't already exist in the Data Manager then it is increased from 0. * * When the value is first set, a `setdata` event is emitted. * @param key The key to increase the value for. - * @param data The value to increase for the given key. + * @param data The amount to increase the given key by. Pass a negative value to decrease the key. Default 1. */ - inc(key: string | object, data?: any): Phaser.Data.DataManager; + inc(key: (string|T), data?: number): this; /** * Toggle a boolean value for the given key. If the key doesn't already exist in the Data Manager then it is toggled from false. @@ -7386,7 +7650,7 @@ declare namespace Phaser { * When the value is first set, a `setdata` event is emitted. * @param key The key to toggle the value for. */ - toggle(key: string | object): Phaser.Data.DataManager; + toggle(key: (string|T)): this; /** * Passes all data entries to the given callback. @@ -7503,12 +7767,12 @@ declare namespace Phaser { * This event is dispatched by a Data Manager when an item in the data store is changed. * * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for - * a change data event from a Game Object you would use: `sprite.data.on('changedata', listener)`. + * a change data event from a Game Object you would use: `sprite.on('changedata', listener)`. * * This event is dispatched for all items that change in the Data Manager. * To listen for the change of a specific item, use the `CHANGE_DATA_KEY_EVENT` event. */ - const CHANGE_DATA: any; + const CHANGE_DATA: string; /** * The Change Data Key Event. @@ -7516,18 +7780,18 @@ declare namespace Phaser { * This event is dispatched by a Data Manager when an item in the data store is changed. * * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for - * the change of a specific data item from a Game Object you would use: `sprite.data.on('changedata-key', listener)`, + * the change of a specific data item from a Game Object you would use: `sprite.on('changedata-key', listener)`, * where `key` is the unique string key of the data item. For example, if you have a data item stored called `gold` - * then you can listen for `sprite.data.on('changedata-gold')`. + * then you can listen for `sprite.on('changedata-gold')`. */ - const CHANGE_DATA_KEY: any; + const CHANGE_DATA_KEY: string; /** * The Data Manager Destroy Event. * * The Data Manager will listen for the destroy event from its parent, and then close itself down. */ - const DESTROY: any; + const DESTROY: string; /** * The Remove Data Event. @@ -7535,9 +7799,9 @@ declare namespace Phaser { * This event is dispatched by a Data Manager when an item is removed from it. * * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for - * the removal of a data item on a Game Object you would use: `sprite.data.on('removedata', listener)`. + * the removal of a data item on a Game Object you would use: `sprite.on('removedata', listener)`. */ - const REMOVE_DATA: any; + const REMOVE_DATA: string; /** * The Set Data Event. @@ -7545,9 +7809,9 @@ declare namespace Phaser { * This event is dispatched by a Data Manager when a new item is added to the data store. * * Game Objects with data enabled have an instance of a Data Manager under the `data` property. So, to listen for - * the addition of a new data item on a Game Object you would use: `sprite.data.on('setdata', listener)`. + * the addition of a new data item on a Game Object you would use: `sprite.on('setdata', listener)`. */ - const SET_DATA: any; + const SET_DATA: string; } @@ -7573,6 +7837,14 @@ declare namespace Phaser { * Can this device can play m4a files. */ m4a: boolean; + /** + * Can this device can play aac files. + */ + aac: boolean; + /** + * Can this device can play flac files. + */ + flac: boolean; /** * Can this device play mp3 files? */ @@ -7688,14 +7960,14 @@ declare namespace Phaser { * via `this.sys.game.device.features` from within any Scene. */ type Features = { - /** - * True if canvas supports a 'copy' bitblt onto itself when the source and destination regions overlap. - */ - canvasBitBltShift: boolean; /** * Is canvas available? */ canvas: boolean; + /** + * True if canvas supports a 'copy' bitblt onto itself when the source and destination regions overlap. + */ + canvasBitBltShift: boolean | null; /** * Is file available? */ @@ -7720,6 +7992,10 @@ declare namespace Phaser { * Is Pointer Lock available? */ pointerLock: boolean; + /** + * Is Array.sort stable? + */ + stableSort: boolean; /** * Does the device context support 32bit pixel manipulation using array buffer views? */ @@ -7773,7 +8049,7 @@ declare namespace Phaser { /** * The newest type of Wheel/Scroll event supported: 'wheel', 'mousewheel', 'DOMMouseScroll' */ - wheelType: string; + wheelType: string | null; /** * Is navigator.getGamepads available? */ @@ -7879,7 +8155,9 @@ declare namespace Phaser { /** * Determines the video support of the browser running this Phaser Game instance. + * * These values are read-only and populated during the boot sequence of the game. + * * They are then referenced by internal game systems and are available for you to access * via `this.sys.game.device.video` from within any Scene. * @@ -7898,6 +8176,10 @@ declare namespace Phaser { * Can this device play h264 mp4 video files? */ mp4: boolean; + /** + * Can this device play m4v (typically mp4) video files? + */ + m4v: boolean; /** * Can this device play ogg video files? */ @@ -7910,6 +8192,10 @@ declare namespace Phaser { * Can this device play webm video files? */ webm: boolean; + /** + * Returns the first video URL that can be played by this browser. + */ + getVideoURL: Function; }; } @@ -8253,7 +8539,7 @@ declare namespace Phaser { /** * Returns the unrotated bounds of the Game Object as a rectangle. * @param gameObject The Game Object to get the bounds value from. - * @param output An object to store the values in. + * @param output An object to store the values in. If not provided a new Rectangle will be created. */ function GetBounds(gameObject: Phaser.GameObjects.GameObject, output?: Phaser.Geom.Rectangle | object): Phaser.Geom.Rectangle | object; @@ -8365,7 +8651,7 @@ declare namespace Phaser { /** * The CanvasPool is a global static object, that allows Phaser to recycle and pool 2D Context Canvas DOM elements. - * It does not pool WebGL Contexts, because once the context options are set they cannot be modified again, + * It does not pool WebGL Contexts, because once the context options are set they cannot be modified again, * which is useless for some of the Phaser pipelines / renderer. * * This singleton is instantiated as soon as Phaser loads, before a Phaser.Game instance has even been created. @@ -8465,7 +8751,7 @@ declare namespace Phaser { * Returns null if no smoothing prefix is available. * @param context The context to check. */ - function isEnabled(context: CanvasRenderingContext2D | WebGLRenderingContext): boolean; + function isEnabled(context: CanvasRenderingContext2D | WebGLRenderingContext): boolean | null; } @@ -8770,7 +9056,7 @@ declare namespace Phaser { static HSLToColor(h: number, s: number, l: number): Phaser.Display.Color; /** - * Get HSV color wheel values in an array which will be 360 elements in size. + * Generates an HSV color wheel which is an array of 360 Color objects, for each step of the wheel. * @param s The saturation, in the range 0 - 1. Default 1. * @param v The value, in the range 0 - 1. Default 1. */ @@ -8878,12 +9164,13 @@ declare namespace Phaser { /** * Sets this ColorMatrix from the given array of color values. - * @param value The ColorMatrix values to set. + * @param value The ColorMatrix values to set. Must have 20 elements. */ - set(value: number[]): this; + set(value: number[] | Float32Array): this; /** - * Resets the ColorMatrix. + * Resets the ColorMatrix to default values and also resets + * the `alpha` property back to 1. */ reset(): this; @@ -9011,8 +9298,64 @@ declare namespace Phaser { /** * Multiplies the two given matrices. * @param a The 5x4 array to multiply with ColorMatrix._matrix. + * @param multiply Multiply the resulting ColorMatrix (`true`), or set it (`false`) ? Default false. + */ + multiply(a: number[], multiply?: boolean): this; + + /** + * A constant array used by the ColorMatrix class for black_white operations. + */ + static readonly BLACK_WHITE: number[]; + + /** + * A constant array used by the ColorMatrix class for negative operations. + */ + static readonly NEGATIVE: number[]; + + /** + * A constant array used by the ColorMatrix class for desatured luminance operations. + */ + static readonly DESATURATE_LUMINANCE: number[]; + + /** + * A constant array used by the ColorMatrix class for sepia operations. + */ + static readonly SEPIA: number[]; + + /** + * A constant array used by the ColorMatrix class for lsd operations. + */ + static readonly LSD: number[]; + + /** + * A constant array used by the ColorMatrix class for brown operations. + */ + static readonly BROWN: number[]; + + /** + * A constant array used by the ColorMatrix class for vintage pinhole operations. + */ + static readonly VINTAGE: number[]; + + /** + * A constant array used by the ColorMatrix class for kodachrome operations. + */ + static readonly KODACHROME: number[]; + + /** + * A constant array used by the ColorMatrix class for technicolor operations. */ - multiply(a: number[]): this; + static readonly TECHNICOLOR: number[]; + + /** + * A constant array used by the ColorMatrix class for polaroid shift operations. + */ + static readonly POLAROID: number[]; + + /** + * A constant array used by the ColorMatrix class for shift BGR operations. + */ + static readonly SHIFT_BGR: number[]; } @@ -9022,15 +9365,15 @@ declare namespace Phaser { * Unlike the Geometry Mask, which is a clipping path, a Bitmap Mask behaves like an alpha mask, * not a clipping path. It is only available when using the WebGL Renderer. * - * A Bitmap Mask can use any Game Object to determine the alpha of each pixel of the masked Game Object(s). + * A Bitmap Mask can use any Game Object or Dynamic Texture to determine the alpha of each pixel of the masked Game Object(s). * For any given point of a masked Game Object's texture, the pixel's alpha will be multiplied by the alpha * of the pixel at the same position in the Bitmap Mask's Game Object. The color of the pixel from the * Bitmap Mask doesn't matter. * * For example, if a pure blue pixel with an alpha of 0.95 is masked with a pure red pixel with an * alpha of 0.5, the resulting pixel will be pure blue with an alpha of 0.475. Naturally, this means - * that a pixel in the mask with an alpha of 0 will hide the corresponding pixel in all masked Game Objects - * A pixel with an alpha of 1 in the masked Game Object will receive the same alpha as the + * that a pixel in the mask with an alpha of 0 will hide the corresponding pixel in all masked Game Objects. + * A pixel with an alpha of 1 in the masked Game Object will receive the same alpha as the * corresponding pixel in the mask. * * Note: You cannot combine Bitmap Masks and Blend Modes on the same Game Object. You can, however, @@ -9049,79 +9392,43 @@ declare namespace Phaser { class BitmapMask { /** * - * @param scene The Scene which this Bitmap Mask will be used in. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. - */ - constructor(scene: Phaser.Scene, renderable: Phaser.GameObjects.GameObject); - - /** - * A reference to either the Canvas or WebGL Renderer that this Mask is using. - */ - renderer: Phaser.Renderer.Canvas.CanvasRenderer | Phaser.Renderer.WebGL.WebGLRenderer; - - /** - * A renderable Game Object that uses a texture, such as a Sprite. - */ - bitmapMask: Phaser.GameObjects.GameObject; - - /** - * The texture used for the masks framebuffer. - */ - maskTexture: WebGLTexture; - - /** - * The texture used for the main framebuffer. - */ - mainTexture: WebGLTexture; - - /** - * Whether the Bitmap Mask is dirty and needs to be updated. - */ - dirty: boolean; - - /** - * The framebuffer to which a masked Game Object is rendered. + * @param scene The Scene to which this mask is being added. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - mainFramebuffer: WebGLFramebuffer; + constructor(scene: Phaser.Scene, maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame); /** - * The framebuffer to which the Bitmap Mask's masking Game Object is rendered. + * The Game Object that is used as the mask. Must use a texture, such as a Sprite. */ - maskFramebuffer: WebGLFramebuffer; + bitmapMask: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture; /** * Whether to invert the masks alpha. * * If `true`, the alpha of the masking pixel will be inverted before it's multiplied with the masked pixel. + * * Essentially, this means that a masked area will be visible only if the corresponding area in the mask is invisible. */ invertAlpha: boolean; /** - * Is this mask a stencil mask? + * Is this mask a stencil mask? This is false by default and should not be changed. */ readonly isStencil: boolean; /** - * Creates the WebGL Texture2D objects and Framebuffers required for this - * mask. If this mask has already been created, then `clearMask` is called first. - */ - createMask(): void; - - /** - * Deletes the `mainTexture` and `maskTexture` WebGL Textures and deletes - * the `mainFramebuffer` and `maskFramebuffer` too, nulling all references. + * Sets a new Game Object or Dynamic Texture for this Bitmap Mask to use. * - * This is called when this mask is destroyed, or if you try to creat a new - * mask from this object when one is already set. - */ - clearMask(): void; - - /** - * Sets a new masking Game Object for the Bitmap Mask. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * If a Game Object it must have a texture, such as a Sprite. + * + * You can update the source of the mask as often as you like. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If a Game Object, it must have a texture, such as a Sprite. */ - setBitmap(renderable: Phaser.GameObjects.GameObject): void; + setBitmap(maskObject: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture): void; /** * Prepares the WebGL Renderer to render a Game Object with this mask applied. @@ -9138,8 +9445,10 @@ declare namespace Phaser { * * This resets the previously bound framebuffer and switches the WebGL Renderer to the Bitmap Mask Pipeline, which uses a special fragment shader to apply the masking effect. * @param renderer The WebGL Renderer to clean up. + * @param camera The Camera to render to. + * @param renderTarget Optional WebGL RenderTarget. */ - postRenderWebGL(renderer: Phaser.Renderer.Canvas.CanvasRenderer | Phaser.Renderer.WebGL.WebGLRenderer): void; + postRenderWebGL(renderer: Phaser.Renderer.Canvas.CanvasRenderer | Phaser.Renderer.WebGL.WebGLRenderer, camera: Phaser.Cameras.Scene2D.Camera, renderTarget?: Phaser.Renderer.WebGL.RenderTarget): void; /** * This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer. @@ -9208,6 +9517,12 @@ declare namespace Phaser { */ readonly isStencil: boolean; + /** + * The current stencil level. This can change dynamically at runtime + * and is set in the applyStencil method. + */ + level: boolean; + /** * Sets a new Graphics object for the Geometry Mask. * @param graphicsGeometry The Graphics object which will be used for the Geometry Mask. @@ -9396,7 +9711,7 @@ declare namespace Phaser { /** * The default uniforms for this shader. */ - uniforms: any; + uniforms: any | null; } @@ -9447,7 +9762,7 @@ declare namespace Phaser { * The parsed XML object is returned, or `null` if there was an error while parsing the data. * @param data The XML source stored in a string. */ - function ParseXML(data: string): DOMParser | ActiveXObject; + function ParseXML(data: string): DOMParser | ActiveXObject | null; /** * Attempts to remove the element from its parentNode in the DOM. @@ -9457,6 +9772,7 @@ declare namespace Phaser { /** * 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 { @@ -9470,11 +9786,6 @@ declare namespace Phaser { */ callback: FrameRequestCallback; - /** - * The most recent timestamp. Either a DOMHighResTimeStamp under RAF or `Date.now` under SetTimeout. - */ - tick: number; - /** * True if the step is using setTimeout instead of RAF. */ @@ -9483,28 +9794,24 @@ declare namespace Phaser { /** * The setTimeout or RAF callback ID used when canceling them. */ - timeOutID: number; - - /** - * The previous time the step was called. - */ - lastTime: number; + timeOutID: number | null; /** - * The target FPS rate in ms. - * Only used when setTimeout is used instead of RAF. + * The delay rate in ms for setTimeOut. */ - target: number; + delay: number; /** * The RAF step function. - * Updates the local tick value, invokes the callback and schedules another call to requestAnimationFrame. + * + * Invokes the callback and schedules another call to requestAnimationFrame. */ step: FrameRequestCallback; /** * The SetTimeout step function. - * Updates the local tick value, invokes the callback and schedules another call to setTimeout. + * + * Invokes the callback and schedules another call to setTimeout. */ stepTimeout: Function; @@ -9512,9 +9819,9 @@ declare namespace Phaser { * Starts the requestAnimationFrame or setTimeout process running. * @param callback The callback to invoke each step. * @param forceSetTimeOut Should it use SetTimeout, even if RAF is available? - * @param targetFPS The target fps rate (in ms). Only used when setTimeout is used. + * @param delay The setTimeout delay rate in ms. */ - start(callback: FrameRequestCallback, forceSetTimeOut: boolean, targetFPS: number): void; + start(callback: FrameRequestCallback, forceSetTimeOut: boolean, delay: number): void; /** * Stops the requestAnimationFrame or setTimeout from running. @@ -9621,929 +9928,1027 @@ declare namespace Phaser { } - namespace GameObjects { + namespace FX { /** - * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. - * - * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to - * match the font structure. - * - * Dynamic Bitmap Text objects are different from Static Bitmap Text in that they invoke a callback for each - * letter being rendered during the render pass. This callback allows you to manipulate the properties of - * each letter being rendered, such as its position, scale or tint, allowing you to create interesting effects - * like jiggling text, which can't be done with Static text. This means that Dynamic Text takes more processing - * time, so only use them if you require the callback ability they have. + * The Barrel FX Controller. * - * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability - * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by - * processing the font texture in an image editor, applying fills and any other effects required. + * This FX controller manages the barrel distortion effect for a Game Object. * - * To create multi-line text insert \r, \n or \r\n escape codes into the text string. + * A barrel effect allows you to apply either a 'pinch' or 'expand' distortion to + * a Game Object. The amount of the effect can be modified in real-time. * - * To create a BitmapText data files you need a 3rd party app such as: + * A Barrel effect is added to a Game Object via the FX component: * - * BMFont (Windows, free): {@link http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/} - * Glyph Designer (OS X, commercial): {@link http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner} - * Littera (Web-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/} + * ```js + * const sprite = this.add.sprite(); * - * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of - * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: {@link http://codebeautify.org/xmltojson|http://codebeautify.org/xmltojson} + * sprite.preFX.addBarrel(); + * sprite.postFX.addBarrel(); + * ``` */ - class DynamicBitmapText extends Phaser.GameObjects.BitmapText { + class Barrel extends Phaser.FX.Controller { /** * - * @param scene The Scene to which this Game Object belongs. It can only belong to one Scene at any given time. - * @param x The x coordinate of this Game Object in world space. - * @param y The y coordinate of this Game Object in world space. - * @param font The key of the font to use from the Bitmap Font cache. - * @param text The string, or array of strings, to be set as the content of this Bitmap Text. - * @param size The font size of this Bitmap Text. - * @param align The alignment of the text in a multi-line BitmapText object. Default 0. + * @param gameObject A reference to the Game Object that has this fx. + * @param amount The amount of distortion applied to the barrel effect. A value of 1 is no distortion. Typically keep this within +- 1. Default 1. */ - constructor(scene: Phaser.Scene, x: number, y: number, font: string, text?: string | string[], size?: number, align?: number); + constructor(gameObject: Phaser.GameObjects.GameObject, amount?: number); /** - * The horizontal scroll position of the Bitmap Text. + * The amount of distortion applied to the barrel effect. + * + * Typically keep this within the range 1 (no distortion) to +- 1. */ - scrollX: number; + amount: number; + + } + /** + * The Bloom FX Controller. + * + * This FX controller manages the bloom effect for a Game Object. + * + * Bloom is an effect used to reproduce an imaging artifact of real-world cameras. + * The effect produces fringes of light extending from the borders of bright areas in an image, + * contributing to the illusion of an extremely bright light overwhelming the + * camera or eye capturing the scene. + * + * A Bloom effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addBloom(); + * sprite.postFX.addBloom(); + * ``` + */ + class Bloom extends Phaser.FX.Controller { /** - * The vertical scroll position of the Bitmap Text. + * + * @param gameObject A reference to the Game Object that has this fx. + * @param color The color of the Bloom, as a hex value. Default 0xffffff. + * @param offsetX The horizontal offset of the bloom effect. Default 1. + * @param offsetY The vertical offset of the bloom effect. Default 1. + * @param blurStrength The strength of the blur process of the bloom effect. Default 1. + * @param strength The strength of the blend process of the bloom effect. Default 1. + * @param steps The number of steps to run the Bloom effect for. This value should always be an integer. Default 4. */ - scrollY: number; + constructor(gameObject: Phaser.GameObjects.GameObject, color?: number, offsetX?: number, offsetY?: number, blurStrength?: number, strength?: number, steps?: number); /** - * The crop width of the Bitmap Text. + * The number of steps to run the Bloom effect for. + * + * This value should always be an integer. + * + * It defaults to 4. The higher the value, the smoother the Bloom, + * but at the cost of exponentially more gl operations. + * + * Keep this to the lowest possible number you can have it, while + * still looking correct for your game. */ - cropWidth: number; + steps: number; /** - * The crop height of the Bitmap Text. + * The horizontal offset of the bloom effect. */ - cropHeight: number; + offsetX: number; /** - * A callback that alters how each character of the Bitmap Text is rendered. + * The vertical offset of the bloom effect. */ - displayCallback: Phaser.Types.GameObjects.BitmapText.DisplayCallback; + offsetY: number; /** - * The data object that is populated during rendering, then passed to the displayCallback. - * You should modify this object then return it back from the callback. It's updated values - * will be used to render the specific glyph. - * - * Please note that if you need a reference to this object locally in your game code then you - * should shallow copy it, as it's updated and re-used for every glyph in the text. + * The strength of the blur process of the bloom effect. */ - callbackData: Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig; + blurStrength: number; /** - * Set the crop size of this Bitmap Text. - * @param width The width of the crop. - * @param height The height of the crop. + * The strength of the blend process of the bloom effect. */ - setSize(width: number, height: number): this; + strength: number; /** - * Set a callback that alters how each character of the Bitmap Text is rendered. - * - * The callback receives a {@link Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig} object that contains information about the character that's - * about to be rendered. - * - * It should return an object with `x`, `y`, `scale` and `rotation` properties that will be used instead of the - * usual values when rendering. - * @param callback The display callback to set. + * The internal gl color array. */ - setDisplayCallback(callback: Phaser.Types.GameObjects.BitmapText.DisplayCallback): this; + glcolor: number[]; /** - * Set the horizontal scroll position of this Bitmap Text. - * @param value The horizontal scroll position to set. + * The color of the bloom as a number value. */ - setScrollX(value: number): this; + color: number; + + } + /** + * The Blur FX Controller. + * + * This FX controller manages the blur effect for a Game Object. + * + * A Gaussian blur is the result of blurring an image by a Gaussian function. It is a widely used effect, + * typically to reduce image noise and reduce detail. The visual effect of this blurring technique is a + * smooth blur resembling that of viewing the image through a translucent screen, distinctly different + * from the bokeh effect produced by an out-of-focus lens or the shadow of an object under usual illumination. + * + * A Blur effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addBlur(); + * sprite.postFX.addBlur(); + * ``` + */ + class Blur extends Phaser.FX.Controller { /** - * Set the vertical scroll position of this Bitmap Text. - * @param value The vertical scroll position to set. + * + * @param gameObject A reference to the Game Object that has this fx. + * @param quality The quality of the blur effect. Can be either 0 for Low Quality, 1 for Medium Quality or 2 for High Quality. Default 0. + * @param x The horizontal offset of the blur effect. Default 2. + * @param y The vertical offset of the blur effect. Default 2. + * @param strength The strength of the blur effect. Default 1. + * @param color The color of the blur, as a hex value. Default 0xffffff. + * @param steps The number of steps to run the blur effect for. This value should always be an integer. Default 4. */ - setScrollY(value: number): this; + constructor(gameObject: Phaser.GameObjects.GameObject, quality?: number, x?: number, y?: number, strength?: number, color?: number, steps?: number); /** - * Clears all alpha values associated with this Game Object. + * The quality of the blur effect. * - * Immediately sets the alpha levels back to 1 (fully opaque). + * This can be: + * + * 0 for Low Quality + * 1 for Medium Quality + * 2 for High Quality + * + * The higher the quality, the more complex shader is used + * and the more processing time is spent on the GPU calculating + * the final blur. This value is used in conjunction with the + * `steps` value, as one has a direct impact on the other. + * + * Keep this value as low as you can, while still achieving the + * desired effect you need for your game. */ - clearAlpha(): this; + quality: number; /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * - * If your game is running under WebGL you can optionally specify four different alpha values, each of which - * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. - * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. - * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. - * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. - * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. + * The horizontal offset of the blur effect. */ - setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + x: number; /** - * The alpha value of the Game Object. - * - * This is a global value, impacting the entire Game Object, not just a region of it. + * The vertical offset of the blur effect. */ - alpha: number; + y: number; /** - * The alpha value starting from the top-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * The number of steps to run the Blur effect for. + * + * This value should always be an integer. + * + * It defaults to 4. The higher the value, the smoother the blur, + * but at the cost of exponentially more gl operations. + * + * Keep this to the lowest possible number you can have it, while + * still looking correct for your game. */ - alphaTopLeft: number; + steps: number; /** - * The alpha value starting from the top-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * The strength of the blur effect. */ - alphaTopRight: number; + strength: number; /** - * The alpha value starting from the bottom-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * The internal gl color array. */ - alphaBottomLeft: number; + glcolor: number[]; /** - * The alpha value starting from the bottom-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * The color of the blur as a number value. */ - alphaBottomRight: number; + color: number; + + } + /** + * The Bokeh FX Controller. + * + * This FX controller manages the bokeh effect for a Game Object. + * + * Bokeh refers to a visual effect that mimics the photographic technique of creating a shallow depth of field. + * This effect is used to emphasize the game's main subject or action, by blurring the background or foreground + * elements, resulting in a more immersive and visually appealing experience. It is achieved through rendering + * techniques that simulate the out-of-focus areas, giving a sense of depth and realism to the game's graphics. + * + * This effect can also be used to generate a Tilt Shift effect, which is a technique used to create a miniature + * effect by blurring everything except a small area of the image. This effect is achieved by blurring the + * top and bottom elements, while keeping the center area in focus. + * + * A Bokeh effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addBokeh(); + * sprite.postFX.addBokeh(); + * ``` + */ + class Bokeh extends Phaser.FX.Controller { /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE - * - * Canvas has more available depending on browser support. * - * You can also create your own custom Blend Modes in WebGL. - * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency of which blend modes - * are used. + * @param gameObject A reference to the Game Object that has this fx. + * @param radius The radius of the bokeh effect. Default 0.5. + * @param amount The amount of the bokeh effect. Default 1. + * @param contrast The color contrast of the bokeh effect. Default 0.2. + * @param isTiltShift Is this a bokeh or Tile Shift effect? Default false. + * @param blurX If Tilt Shift, the amount of horizontal blur. Default 1. + * @param blurY If Tilt Shift, the amount of vertical blur. Default 1. + * @param strength If Tilt Shift, the strength of the blur. Default 1. */ - blendMode: Phaser.BlendModes | string; + constructor(gameObject: Phaser.GameObjects.GameObject, radius?: number, amount?: number, contrast?: number, isTiltShift?: boolean, blurX?: number, blurY?: number, strength?: number); /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE (only works when rendering to a framebuffer, like a Render Texture) - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. + * The radius of the bokeh effect. * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency in which blend modes - * are used. - * @param value The BlendMode value. Either a string or a CONST. + * This is a float value, where a radius of 0 will result in no effect being applied, + * and a radius of 1 will result in a strong bokeh. However, you can exceed this value + * for even stronger effects. */ - setBlendMode(value: string | Phaser.BlendModes): this; + radius: number; /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. - * - * Setting the depth will queue a depth sort event within the Scene. + * The amount, or strength, of the bokeh effect. Defaults to 1. */ - depth: number; + amount: number; /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. - * - * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * The color contrast, or brightness, of the bokeh effect. Defaults to 0.2. */ - setDepth(value: number): this; + contrast: number; /** - * The Mask this Game Object is using during render. + * Is this a Tilt Shift effect or a standard bokeh effect? */ - mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; + isTiltShift: boolean; /** - * Sets the mask that this Game Object will use to render with. - * - * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * If a mask is already set on this Game Object it will be immediately replaced. - * - * Masks are positioned in global space and are not relative to the Game Object to which they - * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * If a Tilt Shift effect this controls the strength of the blur. * - * Masks have no impact on physics or input detection. They are purely a rendering component - * that allows you to limit what is visible during the render pass. - * @param mask The mask this Game Object will use when rendering. + * Setting this value on a non-Tilt Shift effect will have no effect. */ - setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; + strength: number; /** - * Clears the mask that this Game Object was using. - * @param destroyMask Destroy the mask before clearing it? Default false. + * If a Tilt Shift effect this controls the amount of horizontal blur. + * + * Setting this value on a non-Tilt Shift effect will have no effect. */ - clearMask(destroyMask?: boolean): this; + blurX: number; /** - * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. - * - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * If a Tilt Shift effect this controls the amount of vertical blur. * - * To create the mask you need to pass in a reference to a renderable Game Object. - * A renderable Game Object is one that uses a texture to render with, such as an - * Image, Sprite, Render Texture or BitmapText. - * - * If you do not provide a renderable object, and this Game Object has a texture, - * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * Setting this value on a non-Tilt Shift effect will have no effect. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + blurY: number; + + } + /** + * The Circle FX Controller. + * + * This FX controller manages the circle effect for a Game Object. + * + * This effect will draw a circle around the texture of the Game Object, effectively masking off + * any area outside of the circle without the need for an actual mask. You can control the thickness + * of the circle, the color of the circle and the color of the background, should the texture be + * transparent. You can also control the feathering applied to the circle, allowing for a harsh or soft edge. + * + * Please note that adding this effect to a Game Object will not change the input area or physics body of + * the Game Object, should it have one. + * + * A Circle effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addCircle(); + * sprite.postFX.addCircle(); + * ``` + */ + class Circle extends Phaser.FX.Controller { /** - * Creates and returns a Geometry Mask. This mask can be used by any Game Object, - * including this one. - * - * To create the mask you need to pass in a reference to a Graphics Game Object. - * - * If you do not provide a graphics object, and this Game Object is an instance - * of a Graphics object, then it will use itself to create the mask. * - * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param gameObject A reference to the Game Object that has this fx. + * @param thickness The width of the circle around the texture, in pixels. Default 8. + * @param color The color of the circular ring, given as a number value. Default 0xfeedb6. + * @param backgroundColor The color of the background, behind the texture, given as a number value. Default 0xff0000. + * @param scale The scale of the circle. The default scale is 1, which is a circle the full size of the underlying texture. Default 1. + * @param feather The amount of feathering to apply to the circle from the ring. Default 0.005. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + constructor(gameObject: Phaser.GameObjects.GameObject, thickness?: number, color?: number, backgroundColor?: number, scale?: number, feather?: number); /** - * The horizontal origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the left of the Game Object. + * The scale of the circle. The default scale is 1, which is a circle + * the full size of the underlying texture. Reduce this value to create + * a smaller circle, or increase it to create a circle that extends off + * the edges of the texture. */ - originX: number; + scale: number; /** - * The vertical origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the top of the Game Object. + * The amount of feathering to apply to the circle from the ring, + * extending into the middle of the circle. The default is 0.005, + * which is a very low amount of feathering just making sure the ring + * has a smooth edge. Increase this amount to a value such as 0.5 + * or 0.025 for larger amounts of feathering. */ - originY: number; + feather: number; /** - * The horizontal display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * The width of the circle around the texture, in pixels. This value + * doesn't factor in the feather, which can extend the thickness + * internally depending on its value. */ - displayOriginX: number; + thickness: number; /** - * The vertical display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * The internal gl color array for the ring color. */ - displayOriginY: number; + glcolor: number[]; /** - * Sets the origin of this Game Object. - * - * The values are given in the range 0 to 1. - * @param x The horizontal origin value. Default 0.5. - * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. + * The internal gl color array for the background color. */ - setOrigin(x?: number, y?: number): this; + glcolor2: number[]; /** - * Sets the origin of this Game Object based on the Pivot values in its Frame. + * The color of the circular ring, given as a number value. */ - setOriginFromFrame(): this; + color: number; /** - * Sets the display origin of this Game Object. - * The difference between this and setting the origin is that you can use pixel values for setting the display origin. - * @param x The horizontal display origin value. Default 0. - * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + * The color of the background, behind the texture, given as a number value. */ - setDisplayOrigin(x?: number, y?: number): this; + backgroundColor: number; + + } + /** + * The ColorMatrix FX Controller. + * + * This FX controller manages the color matrix effect for a Game Object. + * + * The color matrix effect is a visual technique that involves manipulating the colors of an image + * or scene using a mathematical matrix. This process can adjust hue, saturation, brightness, and contrast, + * allowing developers to create various stylistic appearances or mood settings within the game. + * Common applications include simulating different lighting conditions, applying color filters, + * or achieving a specific visual style. + * + * A ColorMatrix effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addColorMatrix(); + * sprite.postFX.addColorMatrix(); + * ``` + */ + class ColorMatrix extends Phaser.Display.ColorMatrix { /** - * The initial WebGL pipeline of this Game Object. * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + * @param gameObject A reference to the Game Object that has this fx. */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; + constructor(gameObject: Phaser.GameObjects.GameObject); /** - * The current WebGL pipeline of this Game Object. + * The FX_CONST type of this effect. */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + type: number; /** - * Does this Game Object have any Post Pipelines set? + * A reference to the Game Object that owns this effect. */ - hasPostPipeline: boolean; + gameObject: Phaser.GameObjects.GameObject; /** - * The WebGL Post FX Pipelines this Game Object uses for post-render effects. - * - * The pipelines are processed in the order in which they appear in this array. - * - * If you modify this array directly, be sure to set the - * `hasPostPipeline` property accordingly. + * Toggle this boolean to enable or disable this effect, + * without removing and adding it from the Game Object. */ - postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + active: boolean; + + } + + /** + * The Glow FX. + */ + const GLOW: number; + + /** + * The Shadow FX. + */ + const SHADOW: number; + + /** + * The Pixelate FX. + */ + const PIXELATE: number; + + /** + * The Vignette FX. + */ + const VIGNETTE: number; + + /** + * The Shine FX. + */ + const SHINE: number; + + /** + * The Blur FX. + */ + const BLUR: number; + + /** + * The Gradient FX. + */ + const GRADIENT: number; + + /** + * The Bloom FX. + */ + const BLOOM: number; + + /** + * The Color Matrix FX. + */ + const COLOR_MATRIX: number; + + /** + * The Circle FX. + */ + const CIRCLE: number; + + /** + * The Barrel FX. + */ + const BARREL: number; + + /** + * The Displacement FX. + */ + const DISPLACEMENT: number; + /** + * The Wipe FX. + */ + const WIPE: number; + + /** + * The Bokeh and Tilt Shift FX. + */ + const BOKEH: number; + + /** + * FX Controller is the base class that all built-in FX use. + * + * You should not normally create an instance of this class directly, but instead use one of the built-in FX that extend it. + */ + class Controller { /** - * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + * + * @param type The FX Type constant. + * @param gameObject A reference to the Game Object that has this fx. */ - pipelineData: object; + constructor(type: number, gameObject: Phaser.GameObjects.GameObject); /** - * Sets the initial WebGL Pipeline of this Game Object. - * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * The FX_CONST type of this effect. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + type: number; /** - * Sets the main WebGL Pipeline of this Game Object. - * - * Also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * A reference to the Game Object that owns this effect. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + gameObject: Phaser.GameObjects.GameObject; /** - * Sets one, or more, Post Pipelines on this Game Object. - * - * Post Pipelines are invoked after this Game Object has rendered to its target and - * are commonly used for post-fx. - * - * The post pipelines are appended to the `postPipelines` array belonging to this - * Game Object. When the renderer processes this Game Object, it iterates through the post - * pipelines in the order in which they appear in the array. If you are stacking together - * multiple effects, be aware that the order is important. + * Toggle this boolean to enable or disable this effect, + * without removing and adding it from the Game Object. * - * If you call this method multiple times, the new pipelines will be appended to any existing - * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * Only works for Pre FX. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * Post FX are always active. */ - setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; + active: boolean; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Sets the active state of this FX Controller. * - * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. - * - * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param key The key of the pipeline data to set, update, or delete. - * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + * A disabled FX Controller will not be updated. + * @param value `true` to enable this FX Controller, or `false` to disable it. */ - setPipelineData(key: string, value?: any): this; + setActive(value: boolean): this; /** - * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. - * @param pipeline The string-based name of the pipeline, or a pipeline class. + * Destroys this FX Controller. */ - getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + destroy(): void; + } + + /** + * The Displacement FX Controller. + * + * This FX controller manages the displacement effect for a Game Object. + * + * The displacement effect is a visual technique that alters the position of pixels in an image + * or texture based on the values of a displacement map. This effect is used to create the illusion + * of depth, surface irregularities, or distortion in otherwise flat elements. It can be applied to + * characters, objects, or backgrounds to enhance realism, convey movement, or achieve various + * stylistic appearances. + * + * A Displacement effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addDisplacement(); + * sprite.postFX.addDisplacement(); + * ``` + */ + class Displacement extends Phaser.FX.Controller { /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * + * @param gameObject A reference to the Game Object that has this fx. + * @param texture The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager. Default '__WHITE'. + * @param x The amount of horizontal displacement to apply. A very small float number, such as 0.005. Default 0.005. + * @param y The amount of vertical displacement to apply. A very small float number, such as 0.005. Default 0.005. */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; + constructor(gameObject: Phaser.GameObjects.GameObject, texture?: string, x?: number, y?: number); /** - * Resets the WebGL Post Pipelines of this Game Object. It does this by calling - * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * The amount of horizontal displacement to apply. */ - resetPostPipeline(resetData?: boolean): void; + x: number; /** - * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. - * - * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. - * @param pipeline The string-based name of the pipeline, or a pipeline class. + * The amount of vertical displacement to apply. */ - removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; + y: number; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * The underlying WebGLTexture used for displacement. */ - getPipelineName(): string; + glTexture: WebGLTexture; + + } + /** + * The Glow FX Controller. + * + * This FX controller manages the glow effect for a Game Object. + * + * The glow effect is a visual technique that creates a soft, luminous halo around game objects, + * characters, or UI elements. This effect is used to emphasize importance, enhance visual appeal, + * or convey a sense of energy, magic, or otherworldly presence. The effect can also be set on + * the inside of the Game Object. The color and strength of the glow can be modified. + * + * A Glow effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addGlow(); + * sprite.postFX.addGlow(); + * ``` + */ + class Glow extends Phaser.FX.Controller { /** - * The horizontal scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. + * @param gameObject A reference to the Game Object that has this fx. + * @param color The color of the glow effect as a number value. Default 0xffffff. + * @param outerStrength The strength of the glow outward from the edge of the Sprite. Default 4. + * @param innerStrength The strength of the glow inward from the edge of the Sprite. Default 0. + * @param knockout If `true` only the glow is drawn, not the texture itself. Default false. */ - scrollFactorX: number; + constructor(gameObject: Phaser.GameObjects.GameObject, color?: number, outerStrength?: number, innerStrength?: number, knockout?: boolean); /** - * The vertical scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. + * The strength of the glow outward from the edge of the Sprite. */ - scrollFactorY: number; + outerStrength: number; /** - * Sets the scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * @param x The horizontal scroll factor of this Game Object. - * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. + * The strength of the glow inward from the edge of the Sprite. */ - setScrollFactor(x: number, y?: number): this; + innerStrength: number; /** - * The Texture this Game Object is using to render with. + * If `true` only the glow is drawn, not the texture itself. */ - texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + knockout: number; /** - * The Texture Frame this Game Object is using to render with. + * A 4 element array of gl color values. */ - frame: Phaser.Textures.Frame; + glcolor: number[]; /** - * Sets the texture and frame this Game Object will use to render with. - * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. - * @param frame The name or index of the frame within the Texture. + * The color of the glow as a number value. */ - setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; + color: number; + } + + /** + * The Gradient FX Controller. + * + * This FX controller manages the gradient effect for a Game Object. + * + * The gradient overlay effect is a visual technique where a smooth color transition is applied over Game Objects, + * such as sprites or UI components. This effect is used to enhance visual appeal, emphasize depth, or create + * stylistic and atmospheric variations. It can also be utilized to convey information, such as representing + * progress or health status through color changes. + * + * A Gradient effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addGradient(); + * sprite.postFX.addGradient(); + * ``` + */ + class Gradient extends Phaser.FX.Controller { /** - * Sets the frame this Game Object will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. * - * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. - * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. - * @param updateSize Should this call adjust the size of the Game Object? Default true. - * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. + * @param gameObject A reference to the Game Object that has this fx. + * @param color1 The first gradient color, given as a number value. Default 0xff0000. + * @param color2 The second gradient color, given as a number value. Default 0x00ff00. + * @param alpha The alpha value of the gradient effect. Default 0.2. + * @param fromX The horizontal position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. Default 0. + * @param fromY The vertical position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. Default 0. + * @param toX The horizontal position the gradient will end at. This value is noralized, between 0 and 1 and is not in pixels. Default 0. + * @param toY The vertical position the gradient will end at. This value is noralized, between 0 and 1 and is not in pixels. Default 1. + * @param size How many 'chunks' the gradient is divided in to, as spread over the entire height of the texture. Leave this at zero for a smooth gradient, or set higher for a more retro chunky effect. Default 0. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + constructor(gameObject: Phaser.GameObjects.GameObject, color1?: number, color2?: number, alpha?: number, fromX?: number, fromY?: number, toX?: number, toY?: number, size?: number); /** - * The tint value being applied to the top-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * The alpha value of the gradient effect. */ - tintTopLeft: number; + alpha: number; /** - * The tint value being applied to the top-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * Sets how many 'chunks' the gradient is divided in to, as spread over the + * entire height of the texture. Leave this at zero for a smooth gradient, + * or set to a higher number to split the gradient into that many sections, giving + * a more banded 'retro' effect. */ - tintTopRight: number; + size: number; /** - * The tint value being applied to the bottom-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * The horizontal position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. */ - tintBottomLeft: number; + fromX: number; /** - * The tint value being applied to the bottom-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * The vertical position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. */ - tintBottomRight: number; + fromY: number; /** - * The tint fill mode. - * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + * The horizontal position the gradient will end. This value is noralized, between 0 and 1 and is not in pixels. */ - tintFill: boolean; + toX: number; /** - * Clears all tint values associated with this Game Object. - * - * Immediately sets the color values back to 0xffffff and the tint type to 'additive', - * which results in no visible change to the texture. + * The vertical position the gradient will end. This value is noralized, between 0 and 1 and is not in pixels. */ - clearTint(): this; + toY: number; /** - * Sets an additive tint on this Game Object. - * - * The tint works by taking the pixel color values from the Game Objects texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole Game Object will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. - * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. + * The internal gl color array for the starting color. */ - setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + glcolor1: number[]; /** - * Sets a fill-based tint on this Game Object. - * - * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture - * with those in the tint. You can use this for effects such as making a player flash 'white' - * if hit by something. You can provide either one color value, in which case the whole - * Game Object will be rendered in that color. Or you can provide a color per corner. The colors - * are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. - * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. + * The internal gl color array for the ending color. */ - setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + glcolor2: number[]; /** - * The tint value being applied to the whole of the Game Object. - * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. + * The first gradient color, given as a number value. */ - tint: number; + color1: number; /** - * Does this Game Object have a tint applied? - * - * It checks to see if the 4 tint properties are set to the value 0xffffff - * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. + * The second gradient color, given as a number value. */ - readonly isTinted: boolean; + color2: number; + + } + /** + * The Pixelate FX Controller. + * + * This FX controller manages the pixelate effect for a Game Object. + * + * The pixelate effect is a visual technique that deliberately reduces the resolution or detail of an image, + * creating a blocky or mosaic appearance composed of large, visible pixels. This effect can be used for stylistic + * purposes, as a homage to retro gaming, or as a means to obscure certain elements within the game, such as + * during a transition or to censor specific content. + * + * A Pixelate effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addPixelate(); + * sprite.postFX.addPixelate(); + * ``` + */ + class Pixelate extends Phaser.FX.Controller { /** - * The x position of this Game Object. + * + * @param gameObject A reference to the Game Object that has this fx. + * @param amount The amount of pixelation to apply. Default 1. */ - x: number; + constructor(gameObject: Phaser.GameObjects.GameObject, amount?: number); /** - * The y position of this Game Object. + * The amount of pixelation to apply. */ - y: number; + amount: number; + + } + /** + * The Shadow FX Controller. + * + * This FX controller manages the shadow effect for a Game Object. + * + * The shadow effect is a visual technique used to create the illusion of depth and realism by adding darker, + * offset silhouettes or shapes beneath game objects, characters, or environments. These simulated shadows + * help to enhance the visual appeal and immersion, making the 2D game world appear more dynamic and three-dimensional. + * + * A Shadow effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addShadow(); + * sprite.postFX.addShadow(); + * ``` + */ + class Shadow extends Phaser.FX.Controller { /** - * The z position of this Game Object. * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#depth} instead. + * @param gameObject A reference to the Game Object that has this fx. + * @param x The horizontal offset of the shadow effect. Default 0. + * @param y The vertical offset of the shadow effect. Default 0. + * @param decay The amount of decay for shadow effect. Default 0.1. + * @param power The power of the shadow effect. Default 1. + * @param color The color of the shadow. Default 0x000000. + * @param samples The number of samples that the shadow effect will run for. An integer between 1 and 12. Default 6. + * @param intensity The intensity of the shadow effect. Default 1. */ - z: number; + constructor(gameObject: Phaser.GameObjects.GameObject, x?: number, y?: number, decay?: number, power?: number, color?: number, samples?: number, intensity?: number); /** - * The w position of this Game Object. + * The horizontal offset of the shadow effect. */ - w: number; + x: number; /** - * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object - * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. - * - * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this - * isn't the case, use the `scaleX` or `scaleY` properties instead. + * The vertical offset of the shadow effect. */ - scale: number; + y: number; /** - * The horizontal scale of this Game Object. + * The amount of decay for the shadow effect. */ - scaleX: number; + decay: number; /** - * The vertical scale of this Game Object. + * The power of the shadow effect. */ - scaleY: number; + power: number; /** - * The angle of this Game Object as expressed in degrees. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left - * and -90 is up. - * - * If you prefer to work in radians, see the `rotation` property instead. + * The internal gl color array. */ - angle: number; + glcolor: number[]; /** - * The angle of this Game Object in radians. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left - * and -PI/2 is up. + * The number of samples that the shadow effect will run for. * - * If you prefer to work in degrees, see the `angle` property instead. + * This should be an integer with a minimum value of 1 and a maximum of 12. */ - rotation: number; + samples: number; /** - * Sets the position of this Game Object. - * @param x The x position of this Game Object. Default 0. - * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. - * @param z The z position of this Game Object. Default 0. - * @param w The w position of this Game Object. Default 0. + * The intensity of the shadow effect. */ - setPosition(x?: number, y?: number, z?: number, w?: number): this; + intensity: number; /** - * Copies an object's coordinates to this Game Object's position. - * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + * The color of the shadow. */ - copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + color: number; + + } + /** + * The Shine FX Controller. + * + * This FX controller manages the shift effect for a Game Object. + * + * The shine effect is a visual technique that simulates the appearance of reflective + * or glossy surfaces by passing a light beam across a Game Object. This effect is used to + * enhance visual appeal, emphasize certain features, and create a sense of depth or + * material properties. + * + * A Shine effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addShine(); + * sprite.postFX.addShine(); + * ``` + */ + class Shine extends Phaser.FX.Controller { /** - * Sets the position of this Game Object to be a random position within the confines of - * the given area. - * - * If no area is specified a random position between 0 x 0 and the game width x height is used instead. * - * The position does not factor in the size of this Game Object, meaning that only the origin is - * guaranteed to be within the area. - * @param x The x position of the top-left of the random area. Default 0. - * @param y The y position of the top-left of the random area. Default 0. - * @param width The width of the random area. - * @param height The height of the random area. + * @param gameObject A reference to the Game Object that has this fx. + * @param speed The speed of the Shine effect. Default 0.5. + * @param lineWidth The line width of the Shine effect. Default 0.5. + * @param gradient The gradient of the Shine effect. Default 3. + * @param reveal Does this Shine effect reveal or get added to its target? Default false. */ - setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + constructor(gameObject: Phaser.GameObjects.GameObject, speed?: number, lineWidth?: number, gradient?: number, reveal?: boolean); /** - * Sets the rotation of this Game Object. - * @param radians The rotation of this Game Object, in radians. Default 0. + * The speed of the Shine effect. */ - setRotation(radians?: number): this; + speed: number; /** - * Sets the angle of this Game Object. - * @param degrees The rotation of this Game Object, in degrees. Default 0. + * The line width of the Shine effect. */ - setAngle(degrees?: number): this; + lineWidth: number; /** - * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. - * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + * The gradient of the Shine effect. */ - setScale(x: number, y?: number): this; + gradient: number; /** - * Sets the x position of this Game Object. - * @param value The x position of this Game Object. Default 0. + * Does this Shine effect reveal or get added to its target? */ - setX(value?: number): this; + reveal: boolean; - /** - * Sets the y position of this Game Object. - * @param value The y position of this Game Object. Default 0. - */ - setY(value?: number): this; + } + /** + * The Vignette FX Controller. + * + * This FX controller manages the vignette effect for a Game Object. + * + * The vignette effect is a visual technique where the edges of the screen, or a Game Object, gradually darken or blur, + * creating a frame-like appearance. This effect is used to draw the player's focus towards the central action or subject, + * enhance immersion, and provide a cinematic or artistic quality to the game's visuals. + * + * A Vignette effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addVignette(); + * sprite.postFX.addVignette(); + * ``` + */ + class Vignette extends Phaser.FX.Controller { /** - * Sets the z position of this Game Object. * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. - * @param value The z position of this Game Object. Default 0. + * @param gameObject A reference to the Game Object that has this fx. + * @param x The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1. Default 0.5. + * @param y The vertical offset of the vignette effect. This value is normalized to the range 0 to 1. Default 0.5. + * @param radius The radius of the vignette effect. This value is normalized to the range 0 to 1. Default 0.5. + * @param strength The strength of the vignette effect. Default 0.5. */ - setZ(value?: number): this; + constructor(gameObject: Phaser.GameObjects.GameObject, x?: number, y?: number, radius?: number, strength?: number); /** - * Sets the w position of this Game Object. - * @param value The w position of this Game Object. Default 0. + * The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1. */ - setW(value?: number): this; + x: number; /** - * Gets the local transform matrix for this Game Object. - * @param tempMatrix The matrix to populate with the values from this Game Object. + * The vertical offset of the vignette effect. This value is normalized to the range 0 to 1. */ - getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + y: number; /** - * Gets the world transform matrix for this Game Object, factoring in any parent Containers. - * @param tempMatrix The matrix to populate with the values from this Game Object. - * @param parentMatrix A temporary matrix to hold parent values during the calculations. + * The radius of the vignette effect. This value is normalized to the range 0 to 1. */ - getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + radius: number; /** - * Takes the given `x` and `y` coordinates and converts them into local space for this - * Game Object, taking into account parent and local transforms, and the Display Origin. - * - * The returned Vector2 contains the translated point in its properties. - * - * A Camera needs to be provided in order to handle modified scroll factors. If no - * camera is specified, it will use the `main` camera from the Scene to which this - * Game Object belongs. - * @param x The x position to translate. - * @param y The y position to translate. - * @param point A Vector2, or point-like object, to store the results in. - * @param camera The Camera which is being tested against. If not given will use the Scene default camera. + * The strength of the vignette effect. */ - getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + strength: number; - /** - * Gets the sum total rotation of all of this Game Objects parent Containers. - * - * The returned value is in radians and will be zero if this Game Object has no parent container. - */ - getParentRotation(): number; + } + /** + * The Wipe FX Controller. + * + * This FX controller manages the wipe effect for a Game Object. + * + * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements + * in the game, such as images, text, or scene transitions. This effect is often used to create + * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition + * between game states. + * + * You can set both the direction and the axis of the wipe effect. The following combinations are possible: + * + * * left to right: direction 0, axis 0 + * * right to left: direction 1, axis 0 + * * top to bottom: direction 1, axis 1 + * * bottom to top: direction 1, axis 0 + * + * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect. + * + * A Wipe effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.preFX.addWipe(); + * sprite.postFX.addWipe(); + * sprite.preFX.addReveal(); + * sprite.postFX.addReveal(); + * ``` + */ + class Wipe extends Phaser.FX.Controller { /** - * The visible state of the Game Object. * - * An invisible Game Object will skip rendering, but will still process update logic. + * @param gameObject A reference to the Game Object that has this fx. + * @param wipeWidth The width of the wipe effect. This value is normalized in the range 0 to 1. Default 0.1. + * @param direction The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. Default 0. + * @param axis The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. Default 0. + * @param reveal Is this a reveal (true) or a fade (false) effect? Default false. */ - visible: boolean; + constructor(gameObject: Phaser.GameObjects.GameObject, wipeWidth?: number, direction?: number, axis?: number, reveal?: boolean); /** - * Sets the visibility of this Game Object. + * The progress of the Wipe effect. This value is normalized to the range 0 to 1. * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. + * Adjust this value to make the wipe transition (i.e. via a Tween) */ - setVisible(value: boolean): this; - - } + progress: number; - namespace RetroFont { /** - * Text Set 1 = !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ + * The width of the wipe effect. This value is normalized in the range 0 to 1. */ - var TEXT_SET1: string; + wipeWidth: number; /** - * Text Set 2 = !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ + * The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. */ - var TEXT_SET2: string; + direction: number; /** - * Text Set 3 = ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 + * The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. */ - var TEXT_SET3: string; + axis: number; /** - * Text Set 4 = ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 + * Is this a reveal (true) or a fade (false) effect? */ - var TEXT_SET4: string; + reveal: boolean; - /** - * Text Set 5 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789 - */ - var TEXT_SET5: string; + } - /** - * Text Set 6 = ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789"(),-.' - */ - var TEXT_SET6: string; - - /** - * Text Set 7 = AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW")28FLRX-'39 - */ - var TEXT_SET7: string; - - /** - * Text Set 8 = 0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ - */ - var TEXT_SET8: string; - - /** - * Text Set 9 = ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'"?! - */ - var TEXT_SET9: string; - - /** - * Text Set 10 = ABCDEFGHIJKLMNOPQRSTUVWXYZ - */ - var TEXT_SET10: string; - - /** - * Text Set 11 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,"-+!?()':;0123456789 - */ - var TEXT_SET11: string; - - /** - * Parses a Retro Font configuration object so you can pass it to the BitmapText constructor - * and create a BitmapText object using a fixed-width retro font. - * @param scene A reference to the Phaser Scene. - * @param config The font configuration object. - */ - function Parse(scene: Phaser.Scene, config: Phaser.Types.GameObjects.BitmapText.RetroFontConfig): object; - - } + } + namespace GameObjects { /** * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. * * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to * match the font structure. * + * Dynamic Bitmap Text objects are different from Static Bitmap Text in that they invoke a callback for each + * letter being rendered during the render pass. This callback allows you to manipulate the properties of + * each letter being rendered, such as its position, scale or tint, allowing you to create interesting effects + * like jiggling text, which can't be done with Static text. This means that Dynamic Text takes more processing + * time, so only use them if you require the callback ability they have. + * * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by * processing the font texture in an image editor, applying fills and any other effects required. @@ -10554,12 +10959,13 @@ declare namespace Phaser { * * BMFont (Windows, free): {@link http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/} * Glyph Designer (OS X, commercial): {@link http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner} - * Littera (Web-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/} + * Snow BMF (Web-based, free): {@link https://snowb.org//|https://snowb.org/} + * Littera (Flash-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/} * * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: {@link http://codebeautify.org/xmltojson|http://codebeautify.org/xmltojson} */ - class BitmapText extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class DynamicBitmapText extends Phaser.GameObjects.BitmapText { /** * * @param scene The Scene to which this Game Object belongs. It can only belong to one Scene at any given time. @@ -10573,360 +10979,70 @@ declare namespace Phaser { constructor(scene: Phaser.Scene, x: number, y: number, font: string, text?: string | string[], size?: number, align?: number); /** - * The key of the Bitmap Font used by this Bitmap Text. - * To change the font after creation please use `setFont`. - */ - readonly font: string; - - /** - * The data of the Bitmap Font used by this Bitmap Text. - */ - readonly fontData: Phaser.Types.GameObjects.BitmapText.BitmapFontData; - - /** - * The character code used to detect for word wrapping. - * Defaults to 32 (a space character). - */ - wordWrapCharCode: number; - - /** - * The horizontal offset of the drop shadow. - * - * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. - */ - dropShadowX: number; - - /** - * The vertical offset of the drop shadow. - * - * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. - */ - dropShadowY: number; - - /** - * The color of the drop shadow. - * - * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. - */ - dropShadowColor: number; - - /** - * The alpha value of the drop shadow. - * - * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. - */ - dropShadowAlpha: number; - - /** - * Indicates whether the font texture is from an atlas or not. - */ - readonly fromAtlas: boolean; - - /** - * Set the lines of text in this BitmapText to be left-aligned. - * This only has any effect if this BitmapText contains more than one line of text. - */ - setLeftAlign(): this; - - /** - * Set the lines of text in this BitmapText to be center-aligned. - * This only has any effect if this BitmapText contains more than one line of text. - */ - setCenterAlign(): this; - - /** - * Set the lines of text in this BitmapText to be right-aligned. - * This only has any effect if this BitmapText contains more than one line of text. - */ - setRightAlign(): this; - - /** - * Set the font size of this Bitmap Text. - * @param size The font size to set. - */ - setFontSize(size: number): this; - - /** - * Sets the letter spacing between each character of this Bitmap Text. - * Can be a positive value to increase the space, or negative to reduce it. - * Spacing is applied after the kerning values have been set. - * @param spacing The amount of horizontal space to add between each character. Default 0. - */ - setLetterSpacing(spacing?: number): this; - - /** - * Set the textual content of this BitmapText. - * - * An array of strings will be converted into multi-line text. Use the align methods to change multi-line alignment. - * @param value The string, or array of strings, to be set as the content of this BitmapText. - */ - setText(value: string | string[]): this; - - /** - * Sets a drop shadow effect on this Bitmap Text. - * - * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. - * - * You can set the vertical and horizontal offset of the shadow, as well as the color and alpha. - * - * Once a shadow has been enabled you can modify the `dropShadowX` and `dropShadowY` properties of this - * Bitmap Text directly to adjust the position of the shadow in real-time. - * - * If you wish to clear the shadow, call this method with no parameters specified. - * @param x The horizontal offset of the drop shadow. Default 0. - * @param y The vertical offset of the drop shadow. Default 0. - * @param color The color of the drop shadow, given as a hex value, i.e. `0x000000` for black. Default 0x000000. - * @param alpha The alpha of the drop shadow, given as a float between 0 and 1. This is combined with the Bitmap Text alpha as well. Default 0.5. - */ - setDropShadow(x?: number, y?: number, color?: number, alpha?: number): this; - - /** - * Sets a tint on a range of characters in this Bitmap Text, starting from the `start` parameter index - * and running for `length` quantity of characters. - * - * The `start` parameter can be negative. In this case, it starts at the end of the text and counts - * backwards `start` places. - * - * You can also pass in -1 as the `length` and it will tint all characters from `start` - * up until the end of the string. - * Remember that spaces and punctuation count as characters. - * - * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. - * - * The tint works by taking the pixel color values from the Bitmap Text texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole character will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the character range. - * - * To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`. - * - * To modify the tint color once set, call this method again with new color values. - * - * Using `setWordTint` can override tints set by this function, and vice versa. - * - * To remove a tint call this method with just the `start`, and optionally, the `length` parameters defined. - * @param start The starting character to begin the tint at. If negative, it counts back from the end of the text. Default 0. - * @param length The number of characters to tint. Remember that spaces count as a character too. Pass -1 to tint all characters from `start` onwards. Default 1. - * @param tintFill Use a fill-based tint (true), or an additive tint (false) Default false. - * @param topLeft The tint being applied to the top-left of the character. If not other values are given this value is applied evenly, tinting the whole character. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the character. - * @param bottomLeft The tint being applied to the bottom-left of the character. - * @param bottomRight The tint being applied to the bottom-right of the character. - */ - setCharacterTint(start?: number, length?: number, tintFill?: boolean, topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - - /** - * Sets a tint on a matching word within this Bitmap Text. - * - * The `word` parameter can be either a string or a number. - * - * If a string, it will run a string comparison against the text contents, and if matching, - * it will tint the whole word. - * - * If a number, if till that word, based on its offset within the text contents. - * - * The `count` parameter controls how many words are replaced. Pass in -1 to replace them all. - * - * This parameter is ignored if you pass a number as the `word` to be searched for. - * - * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. - * - * The tint works by taking the pixel color values from the Bitmap Text texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole character will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the character range. - * - * To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`. - * - * To modify the tint color once set, call this method again with new color values. - * - * Using `setCharacterTint` can override tints set by this function, and vice versa. - * @param word The word to search for. Either a string, or an index of the word in the words array. - * @param count The number of matching words to tint. Pass -1 to tint all matching words. Default 1. - * @param tintFill Use a fill-based tint (true), or an additive tint (false) Default false. - * @param topLeft The tint being applied to the top-left of the word. If not other values are given this value is applied evenly, tinting the whole word. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the word. - * @param bottomLeft The tint being applied to the bottom-left of the word. - * @param bottomRight The tint being applied to the bottom-right of the word. - */ - setWordTint(word: string | number, count?: number, tintFill?: boolean, topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - - /** - * Calculate the bounds of this Bitmap Text. - * - * An object is returned that contains the position, width and height of the Bitmap Text in local and global - * contexts. - * - * Local size is based on just the font size and a [0, 0] position. - * - * Global size takes into account the Game Object's scale, world position and display origin. - * - * Also in the object is data regarding the length of each line, should this be a multi-line BitmapText. - * @param round Whether to round the results up to the nearest integer. Default false. - */ - getTextBounds(round?: boolean): Phaser.Types.GameObjects.BitmapText.BitmapTextSize; - - /** - * Gets the character located at the given x/y coordinate within this Bitmap Text. - * - * The coordinates you pass in are translated into the local space of the - * Bitmap Text, however, it is up to you to first translate the input coordinates to world space. - * - * If you wish to use this in combination with an input event, be sure - * to pass in `Pointer.worldX` and `worldY` so they are in world space. - * - * In some cases, based on kerning, characters can overlap. When this happens, - * the first character in the word is returned. - * - * Note that this does not work for DynamicBitmapText if you have changed the - * character positions during render. It will only scan characters in their un-translated state. - * @param x The x position to check. - * @param y The y position to check. - * @param camera The Camera which is being tested against. If not given will use the Scene default camera. - */ - getCharacterAt(x: number, y: number, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter; - - /** - * Updates the Display Origin cached values internally stored on this Game Object. - * You don't usually call this directly, but it is exposed for edge-cases where you may. + * The horizontal scroll position of the Bitmap Text. */ - updateDisplayOrigin(): this; + scrollX: number; /** - * Changes the font this BitmapText is using to render. - * - * The new texture is loaded and applied to the BitmapText. The existing test, size and alignment are preserved, - * unless overridden via the arguments. - * @param font The key of the font to use from the Bitmap Font cache. - * @param size The font size of this Bitmap Text. If not specified the current size will be used. - * @param align The alignment of the text in a multi-line BitmapText object. If not specified the current alignment will be used. Default 0. + * The vertical scroll position of the Bitmap Text. */ - setFont(font: string, size?: number, align?: number): this; + scrollY: number; /** - * Sets the maximum display width of this BitmapText in pixels. - * - * If `BitmapText.text` is longer than `maxWidth` then the lines will be automatically wrapped - * based on the previous whitespace character found in the line. - * - * If no whitespace was found then no wrapping will take place and consequently the `maxWidth` value will not be honored. - * - * Disable maxWidth by setting the value to 0. - * - * You can set the whitespace character to be searched for by setting the `wordWrapCharCode` parameter or property. - * @param value The maximum display width of this BitmapText in pixels. Set to zero to disable. - * @param wordWrapCharCode The character code to check for when word wrapping. Defaults to 32 (the space character). + * The crop width of the Bitmap Text. */ - setMaxWidth(value: number, wordWrapCharCode?: number): this; + cropWidth: number; /** - * Controls the alignment of each line of text in this BitmapText object. - * - * Only has any effect when this BitmapText contains multiple lines of text, split with carriage-returns. - * Has no effect with single-lines of text. - * - * See the methods `setLeftAlign`, `setCenterAlign` and `setRightAlign`. - * - * 0 = Left aligned (default) - * 1 = Middle aligned - * 2 = Right aligned - * - * The alignment position is based on the longest line of text. + * The crop height of the Bitmap Text. */ - align: number; + cropHeight: number; /** - * The text that this Bitmap Text object displays. - * - * You can also use the method `setText` if you want a chainable way to change the text content. + * A callback that alters how each character of the Bitmap Text is rendered. */ - text: string; + displayCallback: Phaser.Types.GameObjects.BitmapText.DisplayCallback; /** - * The font size of this Bitmap Text. + * The data object that is populated during rendering, then passed to the displayCallback. + * You should modify this object then return it back from the callback. It's updated values + * will be used to render the specific glyph. * - * You can also use the method `setFontSize` if you want a chainable way to change the font size. + * Please note that if you need a reference to this object locally in your game code then you + * should shallow copy it, as it's updated and re-used for every glyph in the text. */ - fontSize: number; + callbackData: Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig; /** - * Adds / Removes spacing between characters. - * - * Can be a negative or positive number. - * - * You can also use the method `setLetterSpacing` if you want a chainable way to change the letter spacing. + * Set the crop size of this Bitmap Text. + * @param width The width of the crop. + * @param height The height of the crop. */ - letterSpacing: number; + setSize(width: number, height: number): this; /** - * The maximum display width of this BitmapText in pixels. - * - * If BitmapText.text is longer than maxWidth then the lines will be automatically wrapped - * based on the last whitespace character found in the line. + * Set a callback that alters how each character of the Bitmap Text is rendered. * - * If no whitespace was found then no wrapping will take place and consequently the maxWidth value will not be honored. + * The callback receives a {@link Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig} object that contains information about the character that's + * about to be rendered. * - * Disable maxWidth by setting the value to 0. - */ - maxWidth: number; - - /** - * The width of this Bitmap Text. - */ - readonly width: number; - - /** - * The height of this bitmap text. - */ - readonly height: number; - - /** - * Build a JSON representation of this Bitmap Text. - */ - toJSON(): Phaser.Types.GameObjects.BitmapText.JSONBitmapText; - - /** - * Internal destroy handler, called as part of the destroy process. - */ - protected preDestroy(): void; - - /** - * Left align the text characters in a multi-line BitmapText object. - */ - static ALIGN_LEFT: number; - - /** - * Center align the text characters in a multi-line BitmapText object. - */ - static ALIGN_CENTER: number; - - /** - * Right align the text characters in a multi-line BitmapText object. + * It should return an object with `x`, `y`, `scale` and `rotation` properties that will be used instead of the + * usual values when rendering. + * @param callback The display callback to set. */ - static ALIGN_RIGHT: number; + setDisplayCallback(callback: Phaser.Types.GameObjects.BitmapText.DisplayCallback): this; /** - * Parse an XML Bitmap Font from an Atlas. - * - * Adds the parsed Bitmap Font data to the cache with the `fontName` key. - * @param scene The Scene to parse the Bitmap Font for. - * @param fontName The key of the font to add to the Bitmap Font cache. - * @param textureKey The key of the BitmapFont's texture. - * @param frameKey The key of the BitmapFont texture's frame. - * @param xmlKey The key of the XML data of the font to parse. - * @param xSpacing The x-axis spacing to add between each letter. - * @param ySpacing The y-axis spacing to add to the line height. + * Set the horizontal scroll position of this Bitmap Text. + * @param value The horizontal scroll position to set. */ - static ParseFromAtlas(scene: Phaser.Scene, fontName: string, textureKey: string, frameKey: string, xmlKey: string, xSpacing?: number, ySpacing?: number): boolean; + setScrollX(value: number): this; /** - * Parse an XML font to Bitmap Font data for the Bitmap Font cache. - * @param xml The XML Document to parse the font from. - * @param frame The texture frame to take into account when creating the uv data. - * @param xSpacing The x-axis spacing to add between each letter. Default 0. - * @param ySpacing The y-axis spacing to add to the line height. Default 0. + * Set the vertical scroll position of this Bitmap Text. + * @param value The vertical scroll position to set. */ - static ParseXMLBitmapFont(xml: XMLDocument, frame: Phaser.Textures.Frame, xSpacing?: number, ySpacing?: number): Phaser.Types.GameObjects.BitmapText.BitmapFontData; + setScrollY(value: number): this; /** * Clears all alpha values associated with this Game Object. @@ -10986,6 +11102,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -11000,7 +11117,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -11009,6 +11126,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -11022,12 +11140,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -11049,10 +11167,108 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; + /** + * Gets the center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the top-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopLeft(output?: O, includeParent?: boolean): O; + + /** + * Gets the top-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the top-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopRight(output?: O, includeParent?: boolean): O; + + /** + * Gets the left-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getLeftCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the right-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getRightCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomLeft(output?: O, includeParent?: boolean): O; + + /** + * Gets the bottom-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomRight(output?: O, includeParent?: boolean): O; + + /** + * Gets the bounds of this Game Object, regardless of origin. + * + * The values are stored and returned in a Rectangle, or Rectangle-like, object. + * @param output An object to store the values in. If not provided a new Rectangle will be created. + */ + getBounds(output?: O): O; + /** * The Mask this Game Object is using during render. */ @@ -11083,7 +11299,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -11093,10 +11309,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -11108,25 +11328,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -11176,21 +11398,6 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; - /** - * Does this Game Object have any Post Pipelines set? - */ - hasPostPipeline: boolean; - - /** - * The WebGL Post FX Pipelines this Game Object uses for post-render effects. - * - * The pipelines are processed in the order in which they appear in this array. - * - * If you modify this array directly, be sure to set the - * `hasPostPipeline` property accordingly. - */ - postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ @@ -11202,73 +11409,160 @@ declare namespace Phaser { * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; /** * Sets the main WebGL Pipeline of this Game Object. * * Also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the same pipeline data object. * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; - /** - * Sets one, or more, Post Pipelines on this Game Object. - * - * Post Pipelines are invoked after this Game Object has rendered to its target and - * are commonly used for post-fx. - * - * The post pipelines are appended to the `postPipelines` array belonging to this - * Game Object. When the renderer processes this Game Object, it iterates through the post - * pipelines in the order in which they appear in the array. If you are stacking together - * multiple effects, be aware that the order is important. - * - * If you call this method multiple times, the new pipelines will be appended to any existing - * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. - * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. - */ - setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; - /** * Adds an entry to the `pipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ setPipelineData(key: string, value?: any): this; /** - * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. - * @param pipeline The string-based name of the pipeline, or a pipeline class. + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. */ - getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + resetPipeline(resetData?: boolean): boolean; /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + + /** + * Does this Game Object have any Post Pipelines set? + */ + hasPostPipeline: boolean; + + /** + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * + * The pipelines are processed in the order in which they appear in this array. + * + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. + */ + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + postPipelineData: object; + + /** + * The Pre FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + */ + preFX: Phaser.GameObjects.Components.FX | null; + + /** + * The Post FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. + */ + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; + + /** + * Sets one, or more, Post Pipelines on this Game Object. + * + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. + * + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. + * + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * + * You can optionally also set the `postPipelineData` property, if the parameter is given. + * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `postPipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPostPipelineData(key: string, value?: any): this; + + /** + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * @param pipeline The string-based name of the pipeline, or a pipeline class. */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -11281,9 +11575,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -11366,17 +11664,19 @@ declare namespace Phaser { /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** * The tint value being applied to the top-left vertice of the Game Object. @@ -11481,6 +11781,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -11587,10 +11892,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -11672,4030 +11977,9838 @@ declare namespace Phaser { } - /** - * A Blitter Game Object. - * - * The Blitter Game Object is a special kind of container that creates, updates and manages Bob objects. - * Bobs are designed for rendering speed rather than flexibility. They consist of a texture, or frame from a texture, - * a position and an alpha value. You cannot scale or rotate them. They use a batched drawing method for speed - * during rendering. - * - * A Blitter Game Object has one texture bound to it. Bobs created by the Blitter can use any Frame from this - * Texture to render with, but they cannot use any other Texture. It is this single texture-bind that allows - * them their speed. - * - * If you have a need to blast a large volume of frames around the screen then Blitter objects are well worth - * investigating. They are especially useful for using as a base for your own special effects systems. - */ - class Blitter extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { - /** - * - * @param scene The Scene to which this Game Object belongs. It can only belong to one Scene at any given time. - * @param x The x coordinate of this Game Object in world space. Default 0. - * @param y The y coordinate of this Game Object in world space. Default 0. - * @param texture The key of the texture this Game Object will use for rendering. The Texture must already exist in the Texture Manager. Default '__DEFAULT'. - * @param frame The Frame of the Texture that this Game Object will use. Only set if the Texture has multiple frames, such as a Texture Atlas or Sprite Sheet. Default 0. - */ - constructor(scene: Phaser.Scene, x?: number, y?: number, texture?: string, frame?: string | number); - + namespace RetroFont { /** - * The children of this Blitter. - * This List contains all of the Bob objects created by the Blitter. + * Text Set 1 = !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ */ - children: Phaser.Structs.List; + var TEXT_SET1: string; /** - * Is the Blitter considered dirty? - * A 'dirty' Blitter has had its child count changed since the last frame. + * Text Set 2 = !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ */ - dirty: boolean; + var TEXT_SET2: string; /** - * Creates a new Bob in this Blitter. - * - * The Bob is created at the given coordinates, relative to the Blitter and uses the given frame. - * A Bob can use any frame belonging to the texture bound to the Blitter. - * @param x The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param y The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param frame The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using. - * @param visible Should the created Bob render or not? Default true. - * @param index The position in the Blitters Display List to add the new Bob at. Defaults to the top of the list. + * Text Set 3 = ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 */ - create(x: number, y: number, frame?: string | number | Phaser.Textures.Frame, visible?: boolean, index?: number): Phaser.GameObjects.Bob; + var TEXT_SET3: string; /** - * Creates multiple Bob objects within this Blitter and then passes each of them to the specified callback. - * @param callback The callback to invoke after creating a bob. It will be sent two arguments: The Bob and the index of the Bob. - * @param quantity The quantity of Bob objects to create. - * @param frame The Frame the Bobs will use. It must be part of the Blitter Texture. - * @param visible Should the created Bob render or not? Default true. + * Text Set 4 = ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 */ - createFromCallback(callback: CreateCallback, quantity: number, frame?: string | number | Phaser.Textures.Frame | string[] | number[] | Phaser.Textures.Frame[], visible?: boolean): Phaser.GameObjects.Bob[]; + var TEXT_SET4: string; /** - * Creates multiple Bobs in one call. - * - * The amount created is controlled by a combination of the `quantity` argument and the number of frames provided. - * - * If the quantity is set to 10 and you provide 2 frames, then 20 Bobs will be created. 10 with the first - * frame and 10 with the second. - * @param quantity The quantity of Bob objects to create. - * @param frame The Frame the Bobs will use. It must be part of the Blitter Texture. - * @param visible Should the created Bob render or not? Default true. + * Text Set 5 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789 */ - createMultiple(quantity: number, frame?: string | number | Phaser.Textures.Frame | string[] | number[] | Phaser.Textures.Frame[], visible?: boolean): Phaser.GameObjects.Bob[]; + var TEXT_SET5: string; /** - * Checks if the given child can render or not, by checking its `visible` and `alpha` values. - * @param child The Bob to check for rendering. + * Text Set 6 = ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789"(),-.' */ - childCanRender(child: Phaser.GameObjects.Bob): boolean; + var TEXT_SET6: string; /** - * Returns an array of Bobs to be rendered. - * If the Blitter is dirty then a new list is generated and stored in `renderList`. + * Text Set 7 = AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW")28FLRX-'39 */ - getRenderList(): Phaser.GameObjects.Bob[]; + var TEXT_SET7: string; /** - * Removes all Bobs from the children List and clears the dirty flag. + * Text Set 8 = 0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ */ - clear(): void; + var TEXT_SET8: string; /** - * Internal destroy handler, called as part of the destroy process. + * Text Set 9 = ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'"?! */ - protected preDestroy(): void; + var TEXT_SET9: string; /** - * Clears all alpha values associated with this Game Object. - * - * Immediately sets the alpha levels back to 1 (fully opaque). + * Text Set 10 = ABCDEFGHIJKLMNOPQRSTUVWXYZ */ - clearAlpha(): this; + var TEXT_SET10: string; /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * - * If your game is running under WebGL you can optionally specify four different alpha values, each of which - * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. - * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. - * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. - * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. - * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. + * Text Set 11 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,"-+!?()':;0123456789 */ - setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + var TEXT_SET11: string; /** - * The alpha value of the Game Object. - * - * This is a global value, impacting the entire Game Object, not just a region of it. + * Parses a Retro Font configuration object so you can pass it to the BitmapText constructor + * and create a BitmapText object using a fixed-width retro font. + * @param scene A reference to the Phaser Scene. + * @param config The font configuration object. */ - alpha: number; + function Parse(scene: Phaser.Scene, config: Phaser.Types.GameObjects.BitmapText.RetroFontConfig): Phaser.Types.GameObjects.BitmapText.BitmapFontData; - /** - * The alpha value starting from the top-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - */ - alphaTopLeft: number; + } + /** + * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. + * + * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to + * match the font structure. + * + * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability + * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by + * processing the font texture in an image editor, applying fills and any other effects required. + * + * To create multi-line text insert \r, \n or \r\n escape codes into the text string. + * + * To create a BitmapText data files you need a 3rd party app such as: + * + * BMFont (Windows, free): {@link http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/} + * Glyph Designer (OS X, commercial): {@link http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner} + * Snow BMF (Web-based, free): {@link https://snowb.org//|https://snowb.org/} + * Littera (Flash-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/} + * + * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of + * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: {@link http://codebeautify.org/xmltojson|http://codebeautify.org/xmltojson} + */ + class BitmapText extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** - * The alpha value starting from the top-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * + * @param scene The Scene to which this Game Object belongs. It can only belong to one Scene at any given time. + * @param x The x coordinate of this Game Object in world space. + * @param y The y coordinate of this Game Object in world space. + * @param font The key of the font to use from the Bitmap Font cache. + * @param text The string, or array of strings, to be set as the content of this Bitmap Text. + * @param size The font size of this Bitmap Text. + * @param align The alignment of the text in a multi-line BitmapText object. Default 0. */ - alphaTopRight: number; + constructor(scene: Phaser.Scene, x: number, y: number, font: string, text?: string | string[], size?: number, align?: number); /** - * The alpha value starting from the bottom-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * The key of the Bitmap Font used by this Bitmap Text. + * To change the font after creation please use `setFont`. */ - alphaBottomLeft: number; + readonly font: string; /** - * The alpha value starting from the bottom-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * The data of the Bitmap Font used by this Bitmap Text. */ - alphaBottomRight: number; + readonly fontData: Phaser.Types.GameObjects.BitmapText.BitmapFontData; /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. - * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency of which blend modes - * are used. + * The character code used to detect for word wrapping. + * Defaults to 32 (a space character). */ - blendMode: Phaser.BlendModes | string; + wordWrapCharCode: number; /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE (only works when rendering to a framebuffer, like a Render Texture) - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. + * The horizontal offset of the drop shadow. * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency in which blend modes - * are used. - * @param value The BlendMode value. Either a string or a CONST. + * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. */ - setBlendMode(value: string | Phaser.BlendModes): this; + dropShadowX: number; /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. + * The vertical offset of the drop shadow. * - * Setting the depth will queue a depth sort event within the Scene. + * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. */ - depth: number; + dropShadowY: number; /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. + * The color of the drop shadow. * - * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. - */ - setDepth(value: number): this; - - /** - * The Mask this Game Object is using during render. + * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. */ - mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; + dropShadowColor: number; /** - * Sets the mask that this Game Object will use to render with. - * - * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * If a mask is already set on this Game Object it will be immediately replaced. - * - * Masks are positioned in global space and are not relative to the Game Object to which they - * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * The alpha value of the drop shadow. * - * Masks have no impact on physics or input detection. They are purely a rendering component - * that allows you to limit what is visible during the render pass. - * @param mask The mask this Game Object will use when rendering. + * You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`. */ - setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; + dropShadowAlpha: number; /** - * Clears the mask that this Game Object was using. - * @param destroyMask Destroy the mask before clearing it? Default false. + * Indicates whether the font texture is from an atlas or not. */ - clearMask(destroyMask?: boolean): this; + readonly fromAtlas: boolean; /** - * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. - * - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * To create the mask you need to pass in a reference to a renderable Game Object. - * A renderable Game Object is one that uses a texture to render with, such as an - * Image, Sprite, Render Texture or BitmapText. - * - * If you do not provide a renderable object, and this Game Object has a texture, - * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * Set the lines of text in this BitmapText to be left-aligned. + * This only has any effect if this BitmapText contains more than one line of text. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + setLeftAlign(): this; /** - * Creates and returns a Geometry Mask. This mask can be used by any Game Object, - * including this one. - * - * To create the mask you need to pass in a reference to a Graphics Game Object. - * - * If you do not provide a graphics object, and this Game Object is an instance - * of a Graphics object, then it will use itself to create the mask. - * - * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * Set the lines of text in this BitmapText to be center-aligned. + * This only has any effect if this BitmapText contains more than one line of text. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + setCenterAlign(): this; /** - * The initial WebGL pipeline of this Game Object. - * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + * Set the lines of text in this BitmapText to be right-aligned. + * This only has any effect if this BitmapText contains more than one line of text. */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; + setRightAlign(): this; /** - * The current WebGL pipeline of this Game Object. + * Set the font size of this Bitmap Text. + * @param size The font size to set. */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + setFontSize(size: number): this; /** - * Does this Game Object have any Post Pipelines set? + * Sets the letter spacing between each character of this Bitmap Text. + * Can be a positive value to increase the space, or negative to reduce it. + * Spacing is applied after the kerning values have been set. + * @param spacing The amount of horizontal space to add between each character. Default 0. */ - hasPostPipeline: boolean; + setLetterSpacing(spacing?: number): this; /** - * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * Sets the line spacing value. This value is added to the font height to + * calculate the overall line height. * - * The pipelines are processed in the order in which they appear in this array. + * Spacing can be a negative or positive number. * - * If you modify this array directly, be sure to set the - * `hasPostPipeline` property accordingly. - */ - postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - - /** - * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + * Only has an effect if this BitmapText object contains multiple lines of text. + * @param spacing The amount of space to add between each line in multi-line text. Default 0. */ - pipelineData: object; + setLineSpacing(spacing?: number): this; /** - * Sets the initial WebGL Pipeline of this Game Object. + * Set the textual content of this BitmapText. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * An array of strings will be converted into multi-line text. Use the align methods to change multi-line alignment. + * @param value The string, or array of strings, to be set as the content of this BitmapText. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + setText(value: string | string[]): this; /** - * Sets the main WebGL Pipeline of this Game Object. + * Sets a drop shadow effect on this Bitmap Text. * - * Also sets the `pipelineData` property, if the parameter is given. + * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * You can set the vertical and horizontal offset of the shadow, as well as the color and alpha. + * + * Once a shadow has been enabled you can modify the `dropShadowX` and `dropShadowY` properties of this + * Bitmap Text directly to adjust the position of the shadow in real-time. + * + * If you wish to clear the shadow, call this method with no parameters specified. + * @param x The horizontal offset of the drop shadow. Default 0. + * @param y The vertical offset of the drop shadow. Default 0. + * @param color The color of the drop shadow, given as a hex value, i.e. `0x000000` for black. Default 0x000000. + * @param alpha The alpha of the drop shadow, given as a float between 0 and 1. This is combined with the Bitmap Text alpha as well. Default 0.5. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + setDropShadow(x?: number, y?: number, color?: number, alpha?: number): this; /** - * Sets one, or more, Post Pipelines on this Game Object. + * Sets a tint on a range of characters in this Bitmap Text, starting from the `start` parameter index + * and running for `length` quantity of characters. * - * Post Pipelines are invoked after this Game Object has rendered to its target and - * are commonly used for post-fx. + * The `start` parameter can be negative. In this case, it starts at the end of the text and counts + * backwards `start` places. * - * The post pipelines are appended to the `postPipelines` array belonging to this - * Game Object. When the renderer processes this Game Object, it iterates through the post - * pipelines in the order in which they appear in the array. If you are stacking together - * multiple effects, be aware that the order is important. + * You can also pass in -1 as the `length` and it will tint all characters from `start` + * up until the end of the string. + * Remember that spaces and punctuation count as characters. * - * If you call this method multiple times, the new pipelines will be appended to any existing - * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. + * The tint works by taking the pixel color values from the Bitmap Text texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole character will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the character range. * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`. + * + * To modify the tint color once set, call this method again with new color values. + * + * Using `setWordTint` can override tints set by this function, and vice versa. + * + * To remove a tint call this method with just the `start`, and optionally, the `length` parameters defined. + * @param start The starting character to begin the tint at. If negative, it counts back from the end of the text. Default 0. + * @param length The number of characters to tint. Remember that spaces count as a character too. Pass -1 to tint all characters from `start` onwards. Default 1. + * @param tintFill Use a fill-based tint (true), or an additive tint (false) Default false. + * @param topLeft The tint being applied to the top-left of the character. If not other values are given this value is applied evenly, tinting the whole character. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the character. + * @param bottomLeft The tint being applied to the bottom-left of the character. + * @param bottomRight The tint being applied to the bottom-right of the character. */ - setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; + setCharacterTint(start?: number, length?: number, tintFill?: boolean, topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Sets a tint on a matching word within this Bitmap Text. * - * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * The `word` parameter can be either a string or a number. * - * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * If a string, it will run a string comparison against the text contents, and if matching, + * it will tint the whole word. * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param key The key of the pipeline data to set, update, or delete. - * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + * If a number, if till that word, based on its offset within the text contents. + * + * The `count` parameter controls how many words are replaced. Pass in -1 to replace them all. + * + * This parameter is ignored if you pass a number as the `word` to be searched for. + * + * This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic. + * + * The tint works by taking the pixel color values from the Bitmap Text texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole character will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the character range. + * + * To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`. + * + * To modify the tint color once set, call this method again with new color values. + * + * Using `setCharacterTint` can override tints set by this function, and vice versa. + * @param word The word to search for. Either a string, or an index of the word in the words array. + * @param count The number of matching words to tint. Pass -1 to tint all matching words. Default 1. + * @param tintFill Use a fill-based tint (true), or an additive tint (false) Default false. + * @param topLeft The tint being applied to the top-left of the word. If not other values are given this value is applied evenly, tinting the whole word. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the word. + * @param bottomLeft The tint being applied to the bottom-left of the word. + * @param bottomRight The tint being applied to the bottom-right of the word. */ - setPipelineData(key: string, value?: any): this; + setWordTint(word: string | number, count?: number, tintFill?: boolean, topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; /** - * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. - * @param pipeline The string-based name of the pipeline, or a pipeline class. - */ - getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - - /** - * Resets the WebGL Post Pipelines of this Game Object. It does this by calling - * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * Calculate the bounds of this Bitmap Text. + * + * An object is returned that contains the position, width and height of the Bitmap Text in local and global + * contexts. + * + * Local size is based on just the font size and a [0, 0] position. + * + * Global size takes into account the Game Object's scale, world position and display origin. + * + * Also in the object is data regarding the length of each line, should this be a multi-line BitmapText. + * @param round Whether to round the results up to the nearest integer. Default false. */ - resetPostPipeline(resetData?: boolean): void; + getTextBounds(round?: boolean): Phaser.Types.GameObjects.BitmapText.BitmapTextSize; /** - * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. + * Gets the character located at the given x/y coordinate within this Bitmap Text. * - * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. - * @param pipeline The string-based name of the pipeline, or a pipeline class. + * The coordinates you pass in are translated into the local space of the + * Bitmap Text, however, it is up to you to first translate the input coordinates to world space. + * + * If you wish to use this in combination with an input event, be sure + * to pass in `Pointer.worldX` and `worldY` so they are in world space. + * + * In some cases, based on kerning, characters can overlap. When this happens, + * the first character in the word is returned. + * + * Note that this does not work for DynamicBitmapText if you have changed the + * character positions during render. It will only scan characters in their un-translated state. + * @param x The x position to check. + * @param y The y position to check. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. */ - removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; + getCharacterAt(x: number, y: number, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. */ - getPipelineName(): string; + updateDisplayOrigin(): this; /** - * The horizontal scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. + * Changes the font this BitmapText is using to render. * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. + * The new texture is loaded and applied to the BitmapText. The existing test, size and alignment are preserved, + * unless overridden via the arguments. + * @param font The key of the font to use from the Bitmap Font cache. + * @param size The font size of this Bitmap Text. If not specified the current size will be used. + * @param align The alignment of the text in a multi-line BitmapText object. If not specified the current alignment will be used. Default 0. */ - scrollFactorX: number; + setFont(font: string, size?: number, align?: number): this; /** - * The vertical scroll factor of this Game Object. + * Sets the maximum display width of this BitmapText in pixels. * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * If `BitmapText.text` is longer than `maxWidth` then the lines will be automatically wrapped + * based on the previous whitespace character found in the line. * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. + * If no whitespace was found then no wrapping will take place and consequently the `maxWidth` value will not be honored. * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. + * Disable maxWidth by setting the value to 0. * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. + * You can set the whitespace character to be searched for by setting the `wordWrapCharCode` parameter or property. + * @param value The maximum display width of this BitmapText in pixels. Set to zero to disable. + * @param wordWrapCharCode The character code to check for when word wrapping. Defaults to 32 (the space character). */ - scrollFactorY: number; + setMaxWidth(value: number, wordWrapCharCode?: number): this; /** - * Sets the scroll factor of this Game Object. + * Controls the alignment of each line of text in this BitmapText object. * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * Only has any effect when this BitmapText contains multiple lines of text, split with carriage-returns. + * Has no effect with single-lines of text. * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. + * See the methods `setLeftAlign`, `setCenterAlign` and `setRightAlign`. * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. + * 0 = Left aligned (default) + * 1 = Middle aligned + * 2 = Right aligned * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * @param x The horizontal scroll factor of this Game Object. - * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. + * The alignment position is based on the longest line of text. */ - setScrollFactor(x: number, y?: number): this; + align: number; /** - * The native (un-scaled) width of this Game Object. + * The text that this Bitmap Text object displays. * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. + * You can also use the method `setText` if you want a chainable way to change the text content. */ - width: number; + text: string; /** - * The native (un-scaled) height of this Game Object. + * The font size of this Bitmap Text. * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. + * You can also use the method `setFontSize` if you want a chainable way to change the font size. */ - height: number; + fontSize: number; /** - * The displayed width of this Game Object. + * Adds / Removes spacing between characters. * - * This value takes into account the scale factor. + * Can be a negative or positive number. * - * Setting this value will adjust the Game Object's scale property. + * You can also use the method `setLetterSpacing` if you want a chainable way to change the letter spacing. */ - displayWidth: number; + letterSpacing: number; /** - * The displayed height of this Game Object. + * Adds / Removes spacing between lines. * - * This value takes into account the scale factor. + * Can be a negative or positive number. * - * Setting this value will adjust the Game Object's scale property. + * You can also use the method `setLineSpacing` if you want a chainable way to change the line spacing. */ - displayHeight: number; + lineSpacing: number; /** - * Sets the size of this Game Object to be that of the given Frame. - * - * This will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or call the - * `setDisplaySize` method, which is the same thing as changing the scale but allows you - * to do so by giving pixel values. + * The maximum display width of this BitmapText in pixels. * - * 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. - * @param frame The frame to base the size of this Game Object on. - */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; - - /** - * Sets the internal size of this Game Object, as used for frame or physics body creation. + * If BitmapText.text is longer than maxWidth then the lines will be automatically wrapped + * based on the last whitespace character found in the line. * - * 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 no whitespace was found then no wrapping will take place and consequently the maxWidth value will not be honored. * - * 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. - * @param width The width of this Game Object. - * @param height The height of this Game Object. + * Disable maxWidth by setting the value to 0. */ - setSize(width: number, height: number): this; + maxWidth: number; /** - * Sets the display size of this Game Object. + * The width of this Bitmap Text. * - * Calling this will adjust the scale. - * @param width The width of this Game Object. - * @param height The height of this Game Object. + * This property is read-only. */ - setDisplaySize(width: number, height: number): this; + readonly width: number; /** - * The Texture this Game Object is using to render with. + * The height of this Bitmap text. + * + * This property is read-only. */ - texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + readonly height: number; /** - * The Texture Frame this Game Object is using to render with. + * The displayed width of this Bitmap Text. + * + * This value takes into account the scale factor. + * + * This property is read-only. */ - frame: Phaser.Textures.Frame; + readonly displayWidth: number; /** - * Sets the texture and frame this Game Object will use to render with. + * The displayed height of this Bitmap Text. * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. - * @param frame The name or index of the frame within the Texture. + * This value takes into account the scale factor. + * + * This property is read-only. */ - setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; + readonly displayHeight: number; /** - * Sets the frame this Game Object will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. - * - * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. - * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. - * @param updateSize Should this call adjust the size of the Game Object? Default true. - * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. + * Build a JSON representation of this Bitmap Text. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + toJSON(): Phaser.Types.GameObjects.BitmapText.JSONBitmapText; /** - * The x position of this Game Object. + * Internal destroy handler, called as part of the destroy process. */ - x: number; + protected preDestroy(): void; /** - * The y position of this Game Object. + * Left align the text characters in a multi-line BitmapText object. */ - y: number; + static ALIGN_LEFT: number; /** - * The z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#depth} instead. + * Center align the text characters in a multi-line BitmapText object. */ - z: number; + static ALIGN_CENTER: number; /** - * The w position of this Game Object. + * Right align the text characters in a multi-line BitmapText object. */ - w: number; + static ALIGN_RIGHT: number; /** - * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object - * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * Parse an XML Bitmap Font from an Atlas. * - * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this - * isn't the case, use the `scaleX` or `scaleY` properties instead. + * Adds the parsed Bitmap Font data to the cache with the `fontName` key. + * @param scene The Scene to parse the Bitmap Font for. + * @param fontName The key of the font to add to the Bitmap Font cache. + * @param textureKey The key of the BitmapFont's texture. + * @param frameKey The key of the BitmapFont texture's frame. + * @param xmlKey The key of the XML data of the font to parse. + * @param xSpacing The x-axis spacing to add between each letter. + * @param ySpacing The y-axis spacing to add to the line height. */ - scale: number; + static ParseFromAtlas(scene: Phaser.Scene, fontName: string, textureKey: string, frameKey: string, xmlKey: string, xSpacing?: number, ySpacing?: number): boolean; /** - * The horizontal scale of this Game Object. + * Parse an XML font to Bitmap Font data for the Bitmap Font cache. + * @param xml The XML Document to parse the font from. + * @param frame The texture frame to take into account when creating the uv data. + * @param xSpacing The x-axis spacing to add between each letter. Default 0. + * @param ySpacing The y-axis spacing to add to the line height. Default 0. */ - scaleX: number; + static ParseXMLBitmapFont(xml: XMLDocument, frame: Phaser.Textures.Frame, xSpacing?: number, ySpacing?: number): Phaser.Types.GameObjects.BitmapText.BitmapFontData; /** - * The vertical scale of this Game Object. + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). */ - scaleY: number; + clearAlpha(): this; /** - * The angle of this Game Object as expressed in degrees. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left - * and -90 is up. + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. * - * If you prefer to work in radians, see the `rotation` property instead. + * If your game is running under WebGL you can optionally specify four different alpha values, each of which + * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. + * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. + * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. + * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. + * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. */ - angle: number; + setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; /** - * The angle of this Game Object in radians. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left - * and -PI/2 is up. + * The alpha value of the Game Object. * - * If you prefer to work in degrees, see the `angle` property instead. + * This is a global value, impacting the entire Game Object, not just a region of it. */ - rotation: number; + alpha: number; /** - * Sets the position of this Game Object. - * @param x The x position of this Game Object. Default 0. - * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. - * @param z The z position of this Game Object. Default 0. - * @param w The w position of this Game Object. Default 0. + * The alpha value starting from the top-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. */ - setPosition(x?: number, y?: number, z?: number, w?: number): this; + alphaTopLeft: number; /** - * Copies an object's coordinates to this Game Object's position. - * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + * The alpha value starting from the top-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. */ - copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + alphaTopRight: number; /** - * Sets the position of this Game Object to be a random position within the confines of - * the given area. - * - * If no area is specified a random position between 0 x 0 and the game width x height is used instead. - * - * The position does not factor in the size of this Game Object, meaning that only the origin is - * guaranteed to be within the area. - * @param x The x position of the top-left of the random area. Default 0. - * @param y The y position of the top-left of the random area. Default 0. - * @param width The width of the random area. - * @param height The height of the random area. + * The alpha value starting from the bottom-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. */ - setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + alphaBottomLeft: number; /** - * Sets the rotation of this Game Object. - * @param radians The rotation of this Game Object, in radians. Default 0. + * The alpha value starting from the bottom-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. */ - setRotation(radians?: number): this; + alphaBottomRight: number; /** - * Sets the angle of this Game Object. - * @param degrees The rotation of this Game Object, in degrees. Default 0. + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. */ - setAngle(degrees?: number): this; + blendMode: Phaser.BlendModes | string | number; /** - * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. - * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setScale(x: number, y?: number): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * Sets the x position of this Game Object. - * @param value The x position of this Game Object. Default 0. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. */ - setX(value?: number): this; + depth: number; /** - * Sets the y position of this Game Object. - * @param value The y position of this Game Object. Default 0. + * The depth of this Game Object within the Scene. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ - setY(value?: number): this; + setDepth(value: number): this; /** - * Sets the z position of this Game Object. + * Gets the center coordinate of this Game Object, regardless of origin. * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. - * @param value The z position of this Game Object. Default 0. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - setZ(value?: number): this; + getCenter(output?: O, includeParent?: boolean): O; /** - * Sets the w position of this Game Object. - * @param value The w position of this Game Object. Default 0. + * Gets the top-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - setW(value?: number): this; + getTopLeft(output?: O, includeParent?: boolean): O; /** - * Gets the local transform matrix for this Game Object. - * @param tempMatrix The matrix to populate with the values from this Game Object. + * Gets the top-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + getTopCenter(output?: O, includeParent?: boolean): O; /** - * Gets the world transform matrix for this Game Object, factoring in any parent Containers. - * @param tempMatrix The matrix to populate with the values from this Game Object. - * @param parentMatrix A temporary matrix to hold parent values during the calculations. + * Gets the top-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + getTopRight(output?: O, includeParent?: boolean): O; /** - * Takes the given `x` and `y` coordinates and converts them into local space for this - * Game Object, taking into account parent and local transforms, and the Display Origin. - * - * The returned Vector2 contains the translated point in its properties. + * Gets the left-center coordinate of this Game Object, regardless of origin. * - * A Camera needs to be provided in order to handle modified scroll factors. If no - * camera is specified, it will use the `main` camera from the Scene to which this - * Game Object belongs. - * @param x The x position to translate. - * @param y The y position to translate. - * @param point A Vector2, or point-like object, to store the results in. - * @param camera The Camera which is being tested against. If not given will use the Scene default camera. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + getLeftCenter(output?: O, includeParent?: boolean): O; /** - * Gets the sum total rotation of all of this Game Objects parent Containers. + * Gets the right-center coordinate of this Game Object, regardless of origin. * - * The returned value is in radians and will be zero if this Game Object has no parent container. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getParentRotation(): number; + getRightCenter(output?: O, includeParent?: boolean): O; /** - * The visible state of the Game Object. + * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. * - * An invisible Game Object will skip rendering, but will still process update logic. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - visible: boolean; + getBottomLeft(output?: O, includeParent?: boolean): O; /** - * Sets the visibility of this Game Object. + * Gets the bottom-center coordinate of this Game Object, regardless of origin. * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - setVisible(value: boolean): this; - - } + getBottomCenter(output?: O, includeParent?: boolean): O; - /** - * 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 { /** + * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. * - * @param blitter The parent Blitter object is responsible for updating this Bob. - * @param x The horizontal position of this Game Object in the world, relative to the parent Blitter position. - * @param y The vertical position of this Game Object in the world, relative to the parent Blitter position. - * @param frame The Frame this Bob will render with, as defined in the Texture the parent Blitter is using. - * @param visible Should the Bob render visible or not to start with? + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - constructor(blitter: Phaser.GameObjects.Blitter, x: number, y: number, frame: string | number, visible: boolean); + getBottomRight(output?: O, includeParent?: boolean): O; /** - * The Blitter object that this Bob belongs to. + * Gets the bounds of this Game Object, regardless of origin. + * + * The values are stored and returned in a Rectangle, or Rectangle-like, object. + * @param output An object to store the values in. If not provided a new Rectangle will be created. */ - parent: Phaser.GameObjects.Blitter; + getBounds(output?: O): O; /** - * The x position of this Bob, relative to the x position of the Blitter. + * The Mask this Game Object is using during render. */ - x: number; + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; /** - * The y position of this Bob, relative to the y position of the Blitter. + * Sets the mask that this Game Object will use to render with. + * + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * If a mask is already set on this Game Object it will be immediately replaced. + * + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * @param mask The mask this Game Object will use when rendering. */ - y: number; + setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; /** - * The frame that the Bob uses to render with. - * To change the frame use the `Bob.setFrame` method. + * Clears the mask that this Game Object was using. + * @param destroyMask Destroy the mask before clearing it? Default false. */ - protected frame: Phaser.Textures.Frame; + clearMask(destroyMask?: boolean): this; /** - * A blank object which can be used to store data related to this Bob in. + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. + * + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. + * + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - data: object; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** - * The tint value of this Bob. + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. + * + * To create the mask you need to pass in a reference to a Graphics Game Object. + * + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. + * + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - tint: number; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** - * 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. + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - flipX: boolean; + readonly originX: number; /** - * 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. + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - flipY: boolean; + readonly originY: number; /** - * 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. - * @param frame The frame to be used during rendering. + * The horizontal display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. */ - setFrame(frame?: string | number | Phaser.Textures.Frame): this; + displayOriginX: number; /** - * Resets the horizontal and vertical flipped state of this Bob back to their default un-flipped state. + * The vertical display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. */ - resetFlip(): this; + displayOriginY: number; /** - * Resets this Bob. - * - * Changes the position to the values given, and optionally changes the frame. + * Sets the origin of this Game Object. * - * Also resets the flipX and flipY values, sets alpha back to 1 and visible to true. - * @param x The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param y The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param frame The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using. + * The values are given in the range 0 to 1. + * @param x The horizontal origin value. Default 0.5. + * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. */ - reset(x: number, y: number, frame?: string | number | Phaser.Textures.Frame): this; + setOrigin(x?: number, y?: number): this; /** - * Changes the position of this Bob to the values given. - * @param x The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. - * @param y The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * Sets the origin of this Game Object based on the Pivot values in its Frame. */ - setPosition(x: number, y: number): this; + setOriginFromFrame(): this; /** - * Sets the horizontal flipped state of this Bob. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. + * Sets the display origin of this Game Object. + * The difference between this and setting the origin is that you can use pixel values for setting the display origin. + * @param x The horizontal display origin value. Default 0. + * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. */ - setFlipX(value: boolean): this; + setDisplayOrigin(x?: number, y?: number): this; /** - * Sets the vertical flipped state of this Bob. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. + * The initial WebGL pipeline of this Game Object. + * + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. */ - setFlipY(value: boolean): this; + defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * Sets the horizontal and vertical flipped state of this Bob. - * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. - * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. + * The current WebGL pipeline of this Game Object. */ - setFlip(x: boolean, y: boolean): this; + pipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * Sets the visibility of this Bob. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. * - * An invisible Bob will skip rendering. - * @param value The visible state of the Game Object. + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. */ - setVisible(value: boolean): this; + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; /** - * 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. + * Sets the main WebGL Pipeline of this Game Object. * - * A Bob with alpha 0 will skip rendering. - * @param value The alpha value used for this Bob. Between 0 and 1. + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ - setAlpha(value: number): this; + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; /** - * Sets the tint of this Bob. - * @param value The tint value used for this Bob. Between 0 and 0xffffff. + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setTint(value: number): this; + setPipelineData(key: string, value?: any): this; /** - * Destroys this Bob instance. - * Removes itself from the Blitter and clears the parent, frame and data properties. + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. */ - destroy(): void; + resetPipeline(resetData?: boolean): boolean; /** - * The visible state of the Bob. + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + + /** + * Does this Game Object have any Post Pipelines set? + */ + hasPostPipeline: boolean; + + /** + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. * - * An invisible Bob will skip rendering. + * The pipelines are processed in the order in which they appear in this array. + * + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. */ - visible: boolean; + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; /** - * The alpha value of the Bob, between 0 and 1. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + postPipelineData: object; + + /** + * The Pre FX component of this Game Object. * - * A Bob with alpha 0 will skip rendering. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - alpha: number; + preFX: Phaser.GameObjects.Components.FX | null; - } + /** + * The Post FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. + */ + postFX: Phaser.GameObjects.Components.FX; - /** - * Builds a Game Object using the provided configuration object. - * @param scene A reference to the Scene. - * @param gameObject The initial GameObject. - * @param config The config to build the GameObject with. - */ - function BuildGameObject(scene: Phaser.Scene, gameObject: Phaser.GameObjects.GameObject, config: Phaser.Types.GameObjects.GameObjectConfig): Phaser.GameObjects.GameObject; + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; - /** - * Adds an Animation component to a Sprite and populates it based on the given config. - * @param sprite The sprite to add an Animation component to. - * @param config The animation config. - */ - function BuildGameObjectAnimation(sprite: Phaser.GameObjects.Sprite, config: object): Phaser.GameObjects.Sprite; + /** + * Sets one, or more, Post Pipelines on this Game Object. + * + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. + * + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. + * + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * + * You can optionally also set the `postPipelineData` property, if the parameter is given. + * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; - namespace Components { /** - * Provides methods used for setting the alpha properties of a Game Object. - * Should be applied as a mixin and not used directly. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - interface Alpha { - /** - * Clears all alpha values associated with this Game Object. - * - * Immediately sets the alpha levels back to 1 (fully opaque). - */ - clearAlpha(): this; - /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * - * If your game is running under WebGL you can optionally specify four different alpha values, each of which - * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. - * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. - * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. - * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. - * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. - */ - setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - /** - * The alpha value of the Game Object. - * - * This is a global value, impacting the entire Game Object, not just a region of it. - */ - alpha: number; - /** - * The alpha value starting from the top-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - */ - alphaTopLeft: number; - /** - * The alpha value starting from the top-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - */ - alphaTopRight: number; - /** - * The alpha value starting from the bottom-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - */ - alphaBottomLeft: number; - /** - * The alpha value starting from the bottom-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - */ - alphaBottomRight: number; - } + setPostPipelineData(key: string, value?: any): this; /** - * Provides methods used for setting the alpha property of a Game Object. - * Should be applied as a mixin and not used directly. + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * @param pipeline The string-based name of the pipeline, or a pipeline class. */ - interface AlphaSingle { - /** - * Clears all alpha values associated with this Game Object. - * - * Immediately sets the alpha levels back to 1 (fully opaque). - */ - clearAlpha(): this; - /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * @param value The alpha value applied across the whole Game Object. Default 1. - */ - setAlpha(value?: number): this; - /** - * The alpha value of the Game Object. - * - * This is a global value, impacting the entire Game Object, not just a region of it. - */ - alpha: number; - } + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; /** - * Provides methods used for setting the blend mode of a Game Object. - * Should be applied as a mixin and not used directly. + * Resets the WebGL Post Pipelines of this Game Object. It does this by calling + * the `destroy` method on each post pipeline and then clearing the local array. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ - interface BlendMode { - /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. - * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency of which blend modes - * are used. - */ - blendMode: Phaser.BlendModes | string; - /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE (only works when rendering to a framebuffer, like a Render Texture) - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. - * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency in which blend modes - * are used. - * @param value The BlendMode value. Either a string or a CONST. - */ - setBlendMode(value: string | Phaser.BlendModes): this; - } + resetPostPipeline(resetData?: boolean): void; /** - * Provides methods used for calculating and setting the size of a non-Frame based Game Object. - * Should be applied as a mixin and not used directly. + * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. + * + * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. + * @param pipeline The string-based name of the pipeline, or a pipeline class. */ - interface ComputedSize { - /** - * The native (un-scaled) width of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. - */ - width: number; - /** - * The native (un-scaled) height of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. - */ - height: number; - /** - * The displayed width of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - */ - displayWidth: number; - /** - * The displayed height of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - */ - displayHeight: number; - /** - * 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. - * @param width The width of this Game Object. - * @param height The height of this Game Object. - */ - setSize(width: number, height: number): this; - /** - * Sets the display size of this Game Object. - * - * Calling this will adjust the scale. - * @param width The width of this Game Object. - * @param height The height of this Game Object. - */ - setDisplaySize(width: number, height: number): this; - } + removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Provides methods used for getting and setting the texture of a Game Object. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - interface Crop { - /** - * The Texture this Game Object is using to render with. - */ - texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; - /** - * The Texture Frame this Game Object is using to render with. - */ - frame: Phaser.Textures.Frame; - /** - * A boolean flag indicating if this Game Object is being cropped or not. - * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. - * Equally, calling `setCrop` with no arguments will reset the crop and disable it. - */ - isCropped: boolean; - /** - * Applies a crop to a texture based Game Object, such as a Sprite or Image. - * - * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. - * - * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just - * changes what is shown when rendered. - * - * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. - * - * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left - * half of it, you could call `setCrop(0, 0, 400, 600)`. - * - * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop - * an area of 200x100 when applied to a Game Object that had a scale factor of 2. - * - * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. - * - * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. - * - * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow - * the renderer to skip several internal calculations. - * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. - * @param y The y coordinate to start the crop from. - * @param width The width of the crop rectangle in pixels. - * @param height The height of the crop rectangle in pixels. - */ - setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; - } + clearFX(): this; /** - * Provides methods used for setting the depth of a Game Object. - * Should be applied as a mixin and not used directly. + * The horizontal scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. */ - interface Depth { - /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. - * - * Setting the depth will queue a depth sort event within the Scene. - */ - depth: number; - /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. - * - * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. - */ - setDepth(value: number): this; - } + scrollFactorX: number; /** - * Provides methods used for visually flipping a Game Object. - * Should be applied as a mixin and not used directly. + * The vertical scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. */ - interface Flip { - /** - * The horizontally flipped state of the Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - flipX: boolean; - /** - * The vertically flipped state of the Game Object. - * - * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - flipY: boolean; - /** - * Toggles the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - toggleFlipX(): this; - /** - * Toggles the vertical flipped state of this Game Object. - */ - toggleFlipY(): this; - /** - * Sets the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlipX(value: boolean): this; - /** - * Sets the vertical flipped state of this Game Object. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlipY(value: boolean): this; - /** - * Sets the horizontal and vertical flipped state of this Game Object. - * - * A Game Object that is flipped will render inversed on the flipped axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. - * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlip(x: boolean, y: boolean): this; - /** - * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. - */ - resetFlip(): this; - } + scrollFactorY: number; /** - * Provides methods used for obtaining the bounds of a Game Object. - * Should be applied as a mixin and not used directly. + * Sets the scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. */ - interface GetBounds { - /** - * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - */ - getCenter(output?: O): O; - /** - * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getTopLeft(output?: O, includeParent?: boolean): O; - /** - * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getTopCenter(output?: O, includeParent?: boolean): O; - /** - * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getTopRight(output?: O, includeParent?: boolean): O; - /** - * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getLeftCenter(output?: O, includeParent?: boolean): O; - /** - * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getRightCenter(output?: O, includeParent?: boolean): O; - /** - * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getBottomLeft(output?: O, includeParent?: boolean): O; - /** - * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getBottomCenter(output?: O, includeParent?: boolean): O; - /** - * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getBottomRight(output?: O, includeParent?: boolean): O; - /** - * Gets the bounds of this Game Object, regardless of origin. - * The values are stored and returned in a Rectangle, or Rectangle-like, object. - * @param output An object to store the values in. If not provided a new Rectangle will be created. - */ - getBounds(output?: O): O; - } + setScrollFactor(x: number, y?: number): this; /** - * Provides methods used for getting and setting the mask of a Game Object. + * The Texture this Game Object is using to render with. */ - interface Mask { - /** - * The Mask this Game Object is using during render. - */ - mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; - /** - * Sets the mask that this Game Object will use to render with. - * - * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * If a mask is already set on this Game Object it will be immediately replaced. - * - * Masks are positioned in global space and are not relative to the Game Object to which they - * are applied. The reason for this is that multiple Game Objects can all share the same mask. - * - * Masks have no impact on physics or input detection. They are purely a rendering component - * that allows you to limit what is visible during the render pass. - * @param mask The mask this Game Object will use when rendering. - */ - setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; - /** - * Clears the mask that this Game Object was using. - * @param destroyMask Destroy the mask before clearing it? Default false. - */ - clearMask(destroyMask?: boolean): this; - /** - * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. - * - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * To create the mask you need to pass in a reference to a renderable Game Object. - * A renderable Game Object is one that uses a texture to render with, such as an - * Image, Sprite, Render Texture or BitmapText. - * - * If you do not provide a renderable object, and this Game Object has a texture, - * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. - */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; - /** - * Creates and returns a Geometry Mask. This mask can be used by any Game Object, - * including this one. - * - * To create the mask you need to pass in a reference to a Graphics Game Object. - * - * If you do not provide a graphics object, and this Game Object is an instance - * of a Graphics object, then it will use itself to create the mask. - * - * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. - */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; - } + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; /** - * Provides methods used for getting and setting the origin of a Game Object. - * Values are normalized, given in the range 0 to 1. - * Display values contain the calculated pixel values. - * Should be applied as a mixin and not used directly. + * The Texture Frame this Game Object is using to render with. */ - interface Origin { - /** - * The horizontal origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the left of the Game Object. - */ - originX: number; - /** - * The vertical origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the top of the Game Object. - */ - originY: number; - /** - * The horizontal display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. - */ - displayOriginX: number; - /** - * The vertical display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. - */ - displayOriginY: number; - /** - * Sets the origin of this Game Object. - * - * The values are given in the range 0 to 1. - * @param x The horizontal origin value. Default 0.5. - * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. - */ - setOrigin(x?: number, y?: number): this; - /** - * Sets the origin of this Game Object based on the Pivot values in its Frame. - */ - setOriginFromFrame(): this; - /** - * Sets the display origin of this Game Object. - * The difference between this and setting the origin is that you can use pixel values for setting the display origin. - * @param x The horizontal display origin value. Default 0. - * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. - */ - setDisplayOrigin(x?: number, y?: number): this; - /** - * Updates the Display Origin cached values internally stored on this Game Object. - * You don't usually call this directly, but it is exposed for edge-cases where you may. - */ - updateDisplayOrigin(): this; - } + frame: Phaser.Textures.Frame; /** - * Provides methods used for managing a Game Object following a Path. - * Should be applied as a mixin and not used directly. + * Sets the texture and frame this Game Object will use to render with. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. + * @param frame The name or index of the frame within the Texture. */ - interface PathFollower { - /** - * The Path this PathFollower is following. It can only follow one Path at a time. - */ - path: Phaser.Curves.Path; - /** - * Should the PathFollower automatically rotate to point in the direction of the Path? - */ - rotateToPath: boolean; - /** - * Set the Path that this PathFollower should follow. - * - * Optionally accepts {@link Phaser.Types.GameObjects.PathFollower.PathConfig} settings. - * @param path The Path this PathFollower is following. It can only follow one Path at a time. - * @param config Settings for the PathFollower. - */ - setPath(path: Phaser.Curves.Path, config?: number | Phaser.Types.GameObjects.PathFollower.PathConfig | Phaser.Types.Tweens.NumberTweenBuilderConfig): this; - /** - * Set whether the PathFollower should automatically rotate to point in the direction of the Path. - * @param value Whether the PathFollower should automatically rotate to point in the direction of the Path. - * @param offset Rotation offset in degrees. Default 0. - */ - setRotateToPath(value: boolean, offset?: number): this; - /** - * Is this PathFollower actively following a Path or not? - * - * To be considered as `isFollowing` it must be currently moving on a Path, and not paused. - */ - isFollowing(): boolean; - /** - * Starts this PathFollower following its given Path. - * @param config The duration of the follow, or a PathFollower config object. Default {}. - * @param startAt Optional start position of the follow, between 0 and 1. Default 0. - */ - startFollow(config?: number | Phaser.Types.GameObjects.PathFollower.PathConfig | Phaser.Types.Tweens.NumberTweenBuilderConfig, startAt?: number): this; - /** - * Pauses this PathFollower. It will still continue to render, but it will remain motionless at the - * point on the Path at which you paused it. - */ - pauseFollow(): this; - /** - * Resumes a previously paused PathFollower. - * - * If the PathFollower was not paused this has no effect. - */ - resumeFollow(): this; - /** - * Stops this PathFollower from following the path any longer. - * - * This will invoke any 'stop' conditions that may exist on the Path, or for the follower. - */ - stopFollow(): this; - /** - * Internal update handler that advances this PathFollower along the path. - * - * Called automatically by the Scene step, should not typically be called directly. - */ - pathUpdate(): void; - } + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; /** - * Provides methods used for setting the WebGL rendering pipeline of a Game Object. + * Sets the frame this Game Object will use to render with. + * + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. + * + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. + * + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - interface Pipeline { - /** - * The initial WebGL pipeline of this Game Object. - * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. - */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; - /** - * The current WebGL pipeline of this Game Object. - */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; - /** - * Does this Game Object have any Post Pipelines set? - */ - hasPostPipeline: boolean; - /** - * The WebGL Post FX Pipelines this Game Object uses for post-render effects. - * - * The pipelines are processed in the order in which they appear in this array. - * - * If you modify this array directly, be sure to set the - * `hasPostPipeline` property accordingly. - */ - postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. - */ - pipelineData: object; - /** - * Sets the initial WebGL Pipeline of this Game Object. - * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; - /** - * Sets the main WebGL Pipeline of this Game Object. - * - * Also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. - */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; - /** - * Sets one, or more, Post Pipelines on this Game Object. - * - * Post Pipelines are invoked after this Game Object has rendered to its target and - * are commonly used for post-fx. - * - * The post pipelines are appended to the `postPipelines` array belonging to this - * Game Object. When the renderer processes this Game Object, it iterates through the post - * pipelines in the order in which they appear in the array. If you are stacking together - * multiple effects, be aware that the order is important. - * - * If you call this method multiple times, the new pipelines will be appended to any existing - * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. - * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. - */ - setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; - /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. - * - * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. - * - * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param key The key of the pipeline data to set, update, or delete. - * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. - */ - setPipelineData(key: string, value?: any): this; - /** - * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. - * @param pipeline The string-based name of the pipeline, or a pipeline class. - */ - getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** - * Resets the WebGL Post Pipelines of this Game Object. It does this by calling - * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPostPipeline(resetData?: boolean): void; - /** - * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. - * - * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. - * @param pipeline The string-based name of the pipeline, or a pipeline class. - */ - removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; - /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. - */ - getPipelineName(): string; - } + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** - * Provides methods used for getting and setting the Scroll Factor of a Game Object. + * The tint value being applied to the top-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. */ - interface ScrollFactor { - /** - * The horizontal scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - */ - scrollFactorX: number; - /** - * The vertical scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - */ - scrollFactorY: number; - /** - * Sets the scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * @param x The horizontal scroll factor of this Game Object. - * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. - */ - setScrollFactor(x: number, y?: number): this; - } + tintTopLeft: number; /** - * Provides methods used for getting and setting the size of a Game Object. + * The tint value being applied to the top-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. */ - interface Size { - /** - * The native (un-scaled) width of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. - */ - width: number; - /** - * The native (un-scaled) height of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. - */ - height: number; - /** - * The displayed width of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - */ - displayWidth: number; - /** - * The displayed height of this Game Object. + tintTopRight: number; + + /** + * The tint value being applied to the bottom-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomLeft: number; + + /** + * The tint value being applied to the bottom-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomRight: number; + + /** + * The tint fill mode. + * + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + */ + tintFill: boolean; + + /** + * Clears all tint values associated with this Game Object. + * + * Immediately sets the color values back to 0xffffff and the tint type to 'additive', + * which results in no visible change to the texture. + */ + clearTint(): this; + + /** + * Sets an additive tint on this Game Object. + * + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole Game Object will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. + * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + */ + setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + + /** + * Sets a fill-based tint on this Game Object. + * + * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture + * with those in the tint. You can use this for effects such as making a player flash 'white' + * if hit by something. You can provide either one color value, in which case the whole + * Game Object will be rendered in that color. Or you can provide a color per corner. The colors + * are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. + * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + */ + setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + + /** + * The tint value being applied to the whole of the Game Object. + * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. + */ + tint: number; + + /** + * Does this Game Object have a tint applied? + * + * It checks to see if the 4 tint properties are set to the value 0xffffff + * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. + */ + readonly isTinted: boolean; + + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + + /** + * The x position of this Game Object. + */ + x: number; + + /** + * The y position of this Game Object. + */ + y: number; + + /** + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. + */ + z: number; + + /** + * The w position of this Game Object. + */ + w: number; + + /** + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. + */ + scale: number; + + /** + * The horizontal scale of this Game Object. + */ + scaleX: number; + + /** + * The vertical scale of this Game Object. + */ + scaleY: number; + + /** + * The angle of this Game Object as expressed in degrees. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. + * + * If you prefer to work in radians, see the `rotation` property instead. + */ + angle: number; + + /** + * The angle of this Game Object in radians. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. + */ + rotation: number; + + /** + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. + */ + setPosition(x?: number, y?: number, z?: number, w?: number): this; + + /** + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + */ + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + + /** + * Sets the position of this Game Object to be a random position within the confines of + * the given area. + * + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. + */ + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + + /** + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. + */ + setRotation(radians?: number): this; + + /** + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. + */ + setAngle(degrees?: number): this; + + /** + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + */ + setScale(x?: number, y?: number): this; + + /** + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. + */ + setX(value?: number): this; + + /** + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. + */ + setY(value?: number): this; + + /** + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. + */ + setZ(value?: number): this; + + /** + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. + */ + setW(value?: number): this; + + /** + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. + */ + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. + */ + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. + * + * The returned Vector2 contains the translated point in its properties. + * + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. + */ + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + + /** + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. + */ + getParentRotation(): number; + + /** + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + */ + visible: boolean; + + /** + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. + */ + setVisible(value: boolean): this; + + } + + /** + * A Blitter Game Object. + * + * The Blitter Game Object is a special kind of container that creates, updates and manages Bob objects. + * Bobs are designed for rendering speed rather than flexibility. They consist of a texture, or frame from a texture, + * a position and an alpha value. You cannot scale or rotate them. They use a batched drawing method for speed + * during rendering. + * + * A Blitter Game Object has one texture bound to it. Bobs created by the Blitter can use any Frame from this + * Texture to render with, but they cannot use any other Texture. It is this single texture-bind that allows + * them their speed. + * + * If you have a need to blast a large volume of frames around the screen then Blitter objects are well worth + * investigating. They are especially useful for using as a base for your own special effects systems. + */ + class Blitter extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + /** + * + * @param scene The Scene to which this Game Object belongs. It can only belong to one Scene at any given time. + * @param x The x coordinate of this Game Object in world space. Default 0. + * @param y The y coordinate of this Game Object in world space. Default 0. + * @param texture The key of the texture this Game Object will use for rendering. The Texture must already exist in the Texture Manager. Default '__DEFAULT'. + * @param frame The Frame of the Texture that this Game Object will use. Only set if the Texture has multiple frames, such as a Texture Atlas or Sprite Sheet. Default 0. + */ + constructor(scene: Phaser.Scene, x?: number, y?: number, texture?: string, frame?: string | number); + + /** + * The children of this Blitter. + * This List contains all of the Bob objects created by the Blitter. + */ + children: Phaser.Structs.List; + + /** + * Is the Blitter considered dirty? + * A 'dirty' Blitter has had its child count changed since the last frame. + */ + dirty: boolean; + + /** + * Creates a new Bob in this Blitter. + * + * The Bob is created at the given coordinates, relative to the Blitter and uses the given frame. + * A Bob can use any frame belonging to the texture bound to the Blitter. + * @param x The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param y The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param frame The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using. + * @param visible Should the created Bob render or not? Default true. + * @param index The position in the Blitters Display List to add the new Bob at. Defaults to the top of the list. + */ + create(x: number, y: number, frame?: string | number | Phaser.Textures.Frame, visible?: boolean, index?: number): Phaser.GameObjects.Bob; + + /** + * Creates multiple Bob objects within this Blitter and then passes each of them to the specified callback. + * @param callback The callback to invoke after creating a bob. It will be sent two arguments: The Bob and the index of the Bob. + * @param quantity The quantity of Bob objects to create. + * @param frame The Frame the Bobs will use. It must be part of the Blitter Texture. + * @param visible Should the created Bob render or not? Default true. + */ + createFromCallback(callback: CreateCallback, quantity: number, frame?: string | number | Phaser.Textures.Frame | string[] | number[] | Phaser.Textures.Frame[], visible?: boolean): Phaser.GameObjects.Bob[]; + + /** + * Creates multiple Bobs in one call. + * + * The amount created is controlled by a combination of the `quantity` argument and the number of frames provided. + * + * If the quantity is set to 10 and you provide 2 frames, then 20 Bobs will be created. 10 with the first + * frame and 10 with the second. + * @param quantity The quantity of Bob objects to create. + * @param frame The Frame the Bobs will use. It must be part of the Blitter Texture. + * @param visible Should the created Bob render or not? Default true. + */ + createMultiple(quantity: number, frame?: string | number | Phaser.Textures.Frame | string[] | number[] | Phaser.Textures.Frame[], visible?: boolean): Phaser.GameObjects.Bob[]; + + /** + * Checks if the given child can render or not, by checking its `visible` and `alpha` values. + * @param child The Bob to check for rendering. + */ + childCanRender(child: Phaser.GameObjects.Bob): boolean; + + /** + * Returns an array of Bobs to be rendered. + * If the Blitter is dirty then a new list is generated and stored in `renderList`. + */ + getRenderList(): Phaser.GameObjects.Bob[]; + + /** + * Removes all Bobs from the children List and clears the dirty flag. + */ + clear(): void; + + /** + * Internal destroy handler, called as part of the destroy process. + */ + protected preDestroy(): void; + + /** + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). + */ + clearAlpha(): this; + + /** + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * + * If your game is running under WebGL you can optionally specify four different alpha values, each of which + * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. + * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. + * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. + * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. + * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. + */ + setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + + /** + * The alpha value of the Game Object. + * + * This is a global value, impacting the entire Game Object, not just a region of it. + */ + alpha: number; + + /** + * The alpha value starting from the top-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaTopLeft: number; + + /** + * The alpha value starting from the top-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaTopRight: number; + + /** + * The alpha value starting from the bottom-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaBottomLeft: number; + + /** + * The alpha value starting from the bottom-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaBottomRight: number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. + */ + blendMode: Phaser.BlendModes | string | number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * @param value The BlendMode value. Either a string, a CONST or a number. + */ + setBlendMode(value: string | Phaser.BlendModes | number): this; + + /** + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + */ + depth: number; + + /** + * The depth of this Game Object within the Scene. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. + */ + setDepth(value: number): this; + + /** + * The Mask this Game Object is using during render. + */ + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; + + /** + * Sets the mask that this Game Object will use to render with. + * + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * If a mask is already set on this Game Object it will be immediately replaced. + * + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * @param mask The mask this Game Object will use when rendering. + */ + setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; + + /** + * Clears the mask that this Game Object was using. + * @param destroyMask Destroy the mask before clearing it? Default false. + */ + clearMask(destroyMask?: boolean): this; + + /** + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. + * + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. + * + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. + */ + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; + + /** + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. + * + * To create the mask you need to pass in a reference to a Graphics Game Object. + * + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. + * + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. + */ + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; + + /** + * The initial WebGL pipeline of this Game Object. + * + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + */ + defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; + + /** + * The current WebGL pipeline of this Game Object. + */ + pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + + /** + * Does this Game Object have any Post Pipelines set? + */ + hasPostPipeline: boolean; + + /** + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * + * The pipelines are processed in the order in which they appear in this array. + * + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. + */ + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + postPipelineData: object; + + /** + * The Pre FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + */ + preFX: Phaser.GameObjects.Components.FX | null; + + /** + * The Post FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. + */ + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; + + /** + * Sets one, or more, Post Pipelines on this Game Object. + * + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. + * + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. + * + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * + * You can optionally also set the `postPipelineData` property, if the parameter is given. + * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `postPipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPostPipelineData(key: string, value?: any): this; + + /** + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * @param pipeline The string-based name of the pipeline, or a pipeline class. + */ + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + + /** + * Resets the WebGL Post Pipelines of this Game Object. It does this by calling + * the `destroy` method on each post pipeline and then clearing the local array. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. + */ + resetPostPipeline(resetData?: boolean): void; + + /** + * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. + * + * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. + * @param pipeline The string-based name of the pipeline, or a pipeline class. + */ + removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; + + /** + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. + */ + clearFX(): this; + + /** + * The horizontal scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorX: number; + + /** + * The vertical scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorY: number; + + /** + * Sets the scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. + */ + setScrollFactor(x: number, y?: number): this; + + /** + * The native (un-scaled) width of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. + */ + width: number; + + /** + * The native (un-scaled) height of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. + */ + height: number; + + /** + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayWidth: number; + + /** + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayHeight: number; + + /** + * Sets the size of this Game Object to be that of the given Frame. + * + * This will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or call the + * `setDisplaySize` method, which is the same thing as changing the scale but allows you + * to do so by giving pixel values. + * + * If you have enabled this Game Object for input, changing the size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * @param frame The frame to base the size of this Game Object on. + */ + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; + + /** + * Sets the internal size of this Game Object, as used for frame or physics body creation. + * + * This will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or call the + * `setDisplaySize` method, which is the same thing as changing the scale but allows you + * to do so by giving pixel values. + * + * If you have enabled this Game Object for input, changing the size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setSize(width: number, height: number): this; + + /** + * Sets the display size of this Game Object. + * + * Calling this will adjust the scale. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setDisplaySize(width: number, height: number): this; + + /** + * The Texture this Game Object is using to render with. + */ + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + + /** + * The Texture Frame this Game Object is using to render with. + */ + frame: Phaser.Textures.Frame; + + /** + * Sets the texture and frame this Game Object will use to render with. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. + * @param frame The name or index of the frame within the Texture. + */ + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; + + /** + * Sets the frame this Game Object will use to render with. + * + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. + * + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. + * + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. + */ + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; + + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + + /** + * The x position of this Game Object. + */ + x: number; + + /** + * The y position of this Game Object. + */ + y: number; + + /** + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. + */ + z: number; + + /** + * The w position of this Game Object. + */ + w: number; + + /** + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. + */ + scale: number; + + /** + * The horizontal scale of this Game Object. + */ + scaleX: number; + + /** + * The vertical scale of this Game Object. + */ + scaleY: number; + + /** + * The angle of this Game Object as expressed in degrees. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. + * + * If you prefer to work in radians, see the `rotation` property instead. + */ + angle: number; + + /** + * The angle of this Game Object in radians. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. + */ + rotation: number; + + /** + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. + */ + setPosition(x?: number, y?: number, z?: number, w?: number): this; + + /** + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + */ + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + + /** + * Sets the position of this Game Object to be a random position within the confines of + * the given area. + * + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. + */ + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + + /** + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. + */ + setRotation(radians?: number): this; + + /** + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. + */ + setAngle(degrees?: number): this; + + /** + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + */ + setScale(x?: number, y?: number): this; + + /** + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. + */ + setX(value?: number): this; + + /** + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. + */ + setY(value?: number): this; + + /** + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. + */ + setZ(value?: number): this; + + /** + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. + */ + setW(value?: number): this; + + /** + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. + */ + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. + */ + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. + * + * The returned Vector2 contains the translated point in its properties. + * + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. + */ + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + + /** + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. + */ + getParentRotation(): number; + + /** + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + */ + visible: boolean; + + /** + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. + */ + setVisible(value: boolean): this; + + } + + /** + * 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 { + /** + * + * @param blitter The parent Blitter object is responsible for updating this Bob. + * @param x The horizontal position of this Game Object in the world, relative to the parent Blitter position. + * @param y The vertical position of this Game Object in the world, relative to the parent Blitter position. + * @param frame The Frame this Bob will render with, as defined in the Texture the parent Blitter is using. + * @param visible Should the Bob render visible or not to start with? + */ + constructor(blitter: Phaser.GameObjects.Blitter, x: number, y: number, frame: string | number, visible: boolean); + + /** + * The Blitter object that this Bob belongs to. + */ + parent: Phaser.GameObjects.Blitter; + + /** + * The x position of this Bob, relative to the x position of the Blitter. + */ + x: number; + + /** + * The y position of this Bob, relative to the y position of the Blitter. + */ + y: number; + + /** + * The frame that the Bob uses to render with. + * To change the frame use the `Bob.setFrame` method. + */ + protected frame: Phaser.Textures.Frame; + + /** + * A blank object which can be used to store data related to this Bob in. + */ + data: object; + + /** + * The tint value of this Bob. + */ + tint: number; + + /** + * 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. + */ + flipX: boolean; + + /** + * 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. + */ + flipY: boolean; + + /** + * 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. + * @param frame The frame to be used during rendering. + */ + setFrame(frame?: string | number | Phaser.Textures.Frame): this; + + /** + * Resets the horizontal and vertical flipped state of this Bob back to their default un-flipped state. + */ + resetFlip(): 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. + * @param x The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param y The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param frame The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using. + */ + reset(x: number, y: number, frame?: string | number | Phaser.Textures.Frame): this; + + /** + * Changes the position of this Bob to the values given. + * @param x The x position of the Bob. Bob coordinate are relative to the position of the Blitter object. + * @param y The y position of the Bob. Bob coordinate are relative to the position of the Blitter object. + */ + setPosition(x: number, y: number): this; + + /** + * Sets the horizontal flipped state of this Bob. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlipX(value: boolean): this; + + /** + * Sets the vertical flipped state of this Bob. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlipY(value: boolean): this; + + /** + * Sets the horizontal and vertical flipped state of this Bob. + * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. + * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlip(x: boolean, y: boolean): this; + + /** + * Sets the visibility of this Bob. + * + * An invisible Bob will skip rendering. + * @param value The visible state of the Game Object. + */ + setVisible(value: boolean): 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. + * @param value The alpha value used for this Bob. Between 0 and 1. + */ + setAlpha(value: number): this; + + /** + * Sets the tint of this Bob. + * @param value The tint value used for this Bob. Between 0 and 0xffffff. + */ + setTint(value: number): this; + + /** + * Destroys this Bob instance. + * Removes itself from the Blitter and clears the parent, frame and data properties. + */ + destroy(): void; + + /** + * The visible state of the Bob. + * + * An invisible Bob will skip rendering. + */ + visible: boolean; + + /** + * The alpha value of the Bob, between 0 and 1. + * + * A Bob with alpha 0 will skip rendering. + */ + alpha: number; + + } + + /** + * Builds a Game Object using the provided configuration object. + * @param scene A reference to the Scene. + * @param gameObject The initial GameObject. + * @param config The config to build the GameObject with. + */ + function BuildGameObject(scene: Phaser.Scene, gameObject: Phaser.GameObjects.GameObject, config: Phaser.Types.GameObjects.GameObjectConfig): Phaser.GameObjects.GameObject; + + /** + * Adds an Animation component to a Sprite and populates it based on the given config. + * @param sprite The sprite to add an Animation component to. + * @param config The animation config. + */ + function BuildGameObjectAnimation(sprite: Phaser.GameObjects.Sprite, config: object): Phaser.GameObjects.Sprite; + + namespace Components { + /** + * Provides methods used for setting the alpha properties of a Game Object. + * Should be applied as a mixin and not used directly. + */ + interface Alpha { + /** + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). + */ + clearAlpha(): this; + /** + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * + * If your game is running under WebGL you can optionally specify four different alpha values, each of which + * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. + * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. + * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. + * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. + * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. + */ + setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + /** + * The alpha value of the Game Object. + * + * This is a global value, impacting the entire Game Object, not just a region of it. + */ + alpha: number; + /** + * The alpha value starting from the top-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaTopLeft: number; + /** + * The alpha value starting from the top-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaTopRight: number; + /** + * The alpha value starting from the bottom-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaBottomLeft: number; + /** + * The alpha value starting from the bottom-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaBottomRight: number; + } + + /** + * Provides methods used for setting the alpha property of a Game Object. + * Should be applied as a mixin and not used directly. + */ + interface AlphaSingle { + /** + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). + */ + clearAlpha(): this; + /** + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * @param value The alpha value applied across the whole Game Object. Default 1. + */ + setAlpha(value?: number): this; + /** + * The alpha value of the Game Object. + * + * This is a global value, impacting the entire Game Object, not just a region of it. + */ + alpha: number; + } + + /** + * Provides methods used for setting the blend mode of a Game Object. + * Should be applied as a mixin and not used directly. + */ + interface BlendMode { + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. + */ + blendMode: Phaser.BlendModes | string | number; + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * @param value The BlendMode value. Either a string, a CONST or a number. + */ + setBlendMode(value: string | Phaser.BlendModes | number): this; + } + + /** + * Provides methods used for calculating and setting the size of a non-Frame based Game Object. + * Should be applied as a mixin and not used directly. + */ + interface ComputedSize { + /** + * The native (un-scaled) width of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. + */ + width: number; + /** + * The native (un-scaled) height of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. + */ + height: number; + /** + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayWidth: number; + /** + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayHeight: number; + /** + * 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. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setSize(width: number, height: number): this; + /** + * Sets the display size of this Game Object. + * + * Calling this will adjust the scale. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setDisplaySize(width: number, height: number): this; + } + + /** + * Provides methods used for getting and setting the texture of a Game Object. + */ + interface Crop { + /** + * The Texture this Game Object is using to render with. + */ + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + /** + * The Texture Frame this Game Object is using to render with. + */ + frame: Phaser.Textures.Frame; + /** + * A boolean flag indicating if this Game Object is being cropped or not. + * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. + * Equally, calling `setCrop` with no arguments will reset the crop and disable it. + */ + isCropped: boolean; + /** + * Applies a crop to a texture based Game Object, such as a Sprite or Image. + * + * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. + * + * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just + * changes what is shown when rendered. + * + * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. + * + * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left + * half of it, you could call `setCrop(0, 0, 400, 600)`. + * + * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop + * an area of 200x100 when applied to a Game Object that had a scale factor of 2. + * + * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. + * + * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. + * + * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow + * the renderer to skip several internal calculations. + * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. + * @param y The y coordinate to start the crop from. + * @param width The width of the crop rectangle in pixels. + * @param height The height of the crop rectangle in pixels. + */ + setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; + } + + /** + * Provides methods used for setting the depth of a Game Object. + * Should be applied as a mixin and not used directly. + */ + interface Depth { + /** + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + */ + depth: number; + /** + * The depth of this Game Object within the Scene. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. + */ + setDepth(value: number): this; + } + + /** + * Provides methods used for visually flipping a Game Object. + * Should be applied as a mixin and not used directly. + */ + interface Flip { + /** + * The horizontally flipped state of the Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + */ + flipX: boolean; + /** + * The vertically flipped state of the Game Object. + * + * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + */ + flipY: boolean; + /** + * Toggles the horizontal flipped state of this Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + */ + toggleFlipX(): this; + /** + * Toggles the vertical flipped state of this Game Object. + */ + toggleFlipY(): this; + /** + * Sets the horizontal flipped state of this Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlipX(value: boolean): this; + /** + * Sets the vertical flipped state of this Game Object. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlipY(value: boolean): this; + /** + * Sets the horizontal and vertical flipped state of this Game Object. + * + * A Game Object that is flipped will render inversed on the flipped axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. + * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlip(x: boolean, y: boolean): this; + /** + * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. + */ + resetFlip(): this; + } + + interface FX { + /** + * Sets the Texture to be used for the displacement effect. + * + * You can only use a whole texture, not a frame from a texture atlas or sprite sheet. + * @param texture The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager. Default '__WHITE'. + */ + setTexture(texture?: string): this; + /** + * A reference to the Game Object that owns this FX Component. + */ + readonly gameObject: Phaser.GameObjects.GameObject; + /** + * Is this a Post FX Controller? or a Pre FX Controller? + */ + readonly isPost: boolean; + /** + * Has this FX Component been enabled? + * + * You should treat this property as read-only, although it is toggled + * automaticaly during internal use. + */ + enabled: boolean; + /** + * An array containing all of the Pre FX Controllers that + * have been added to this FX Component. They are processed in + * the order they are added. + * + * This array is empty if this is a Post FX Component. + */ + list: Phaser.FX.Controller[]; + /** + * The amount of extra padding to be applied to this Game Object + * when it is being rendered by a PreFX Pipeline. + * + * Lots of FX require additional spacing added to the texture the + * Game Object uses, for example a glow or shadow effect, and this + * method allows you to control how much extra padding is included + * in addition to the texture size. + * + * You do not need to set this if you're only using Post FX. + */ + padding: number; + /** + * Sets the amount of extra padding to be applied to this Game Object + * when it is being rendered by a PreFX Pipeline. + * + * Lots of FX require additional spacing added to the texture the + * Game Object uses, for example a glow or shadow effect, and this + * method allows you to control how much extra padding is included + * in addition to the texture size. + * + * You do not need to set this if you're only using Post FX. + * @param padding The amount of padding to add to this Game Object. Default 0. + */ + setPadding(padding?: number): this; + /** + * This callback is invoked when this Game Object is copied by a PreFX Pipeline. + * + * This happens when the pipeline uses its `copySprite` method. + * + * It's invoked prior to the copy, allowing you to set shader uniforms, etc on the pipeline. + * @param pipeline The PreFX Pipeline that invoked this callback. + */ + onFXCopy(pipeline: Phaser.Renderer.WebGL.Pipelines.PreFXPipeline): void; + /** + * This callback is invoked when this Game Object is rendered by a PreFX Pipeline. + * + * This happens when the pipeline uses its `drawSprite` method. + * + * It's invoked prior to the draw, allowing you to set shader uniforms, etc on the pipeline. + * @param pipeline The PreFX Pipeline that invoked this callback. + */ + onFX(pipeline: Phaser.Renderer.WebGL.Pipelines.PreFXPipeline): void; + /** + * Enables this FX Component and applies the FXPipeline to the parent Game Object. + * + * This is called automatically whenever you call a method such as `addBloom`, etc. + * + * You can check the `enabled` property to see if the Game Object is already enabled, or not. + * + * This only applies to Pre FX. Post FX are always enabled. + * @param padding The amount of padding to add to this Game Object. Default 0. + */ + enable(padding?: number): void; + /** + * Destroys and removes all FX Controllers that are part of this FX Component, + * then disables it. + * + * If this is a Pre FX Component it will only remove Pre FX. + * If this is a Post FX Component it will only remove Post FX. + * + * To remove both at once use the `GameObject.clearFX` method instead. + */ + clear(): this; + /** + * Searches for the given FX Controller within this FX Component. + * + * If found, the controller is removed from this component and then destroyed. + * @param fx The FX Controller to remove from this FX Component. + */ + remove(fx: T): this; + /** + * Disables this FX Component. + * + * This will reset the pipeline on the Game Object that owns this component back to its + * default and flag this component as disabled. + * + * You can re-enable it again by calling `enable` for Pre FX or by adding an FX for Post FX. + * + * Optionally, set `clear` to destroy all current FX Controllers. + * @param clear Destroy and remove all FX Controllers that are part of this component. Default false. + */ + disable(clear?: boolean): this; + /** + * Adds the given FX Controler to this FX Component. + * + * Note that adding an FX Controller does not remove any existing FX. They all stack-up + * on-top of each other. If you don't want this, make sure to call either `remove` or + * `clear` first. + * @param fx The FX Controller to add to this FX Component. + * @param config Optional configuration object that is passed to the pipeline during instantiation. + */ + add(fx: T, config?: object): Phaser.FX.Controller; + /** + * Adds a Glow effect. + * + * The glow effect is a visual technique that creates a soft, luminous halo around game objects, + * characters, or UI elements. This effect is used to emphasize importance, enhance visual appeal, + * or convey a sense of energy, magic, or otherworldly presence. The effect can also be set on + * the inside of the Game Object. The color and strength of the glow can be modified. + * @param color The color of the glow effect as a number value. Default 0xffffff. + * @param outerStrength The strength of the glow outward from the edge of the Sprite. Default 4. + * @param innerStrength The strength of the glow inward from the edge of the Sprite. Default 0. + * @param knockout If `true` only the glow is drawn, not the texture itself. Default false. + * @param quality Only available for PostFX. Sets the quality of this Glow effect. Default is 0.1. Cannot be changed post-creation. Default 0.1. + * @param distance Only available for PostFX. Sets the distance of this Glow effect. Default is 10. Cannot be changed post-creation. Default 10. + */ + addGlow(color?: number, outerStrength?: number, innerStrength?: number, knockout?: boolean, quality?: number, distance?: number): Phaser.FX.Glow; + /** + * Adds a Shadow effect. + * + * The shadow effect is a visual technique used to create the illusion of depth and realism by adding darker, + * offset silhouettes or shapes beneath game objects, characters, or environments. These simulated shadows + * help to enhance the visual appeal and immersion, making the 2D game world appear more dynamic and three-dimensional. + * @param x The horizontal offset of the shadow effect. Default 0. + * @param y The vertical offset of the shadow effect. Default 0. + * @param decay The amount of decay for shadow effect. Default 0.1. + * @param power The power of the shadow effect. Default 1. + * @param color The color of the shadow. Default 0x000000. + * @param samples The number of samples that the shadow effect will run for. An integer between 1 and 12. Default 6. + * @param intensity The intensity of the shadow effect. Default 1. + */ + addShadow(x?: number, y?: number, decay?: number, power?: number, color?: number, samples?: number, intensity?: number): Phaser.FX.Shadow; + /** + * Adds a Pixelate effect. + * + * The pixelate effect is a visual technique that deliberately reduces the resolution or detail of an image, + * creating a blocky or mosaic appearance composed of large, visible pixels. This effect can be used for stylistic + * purposes, as a homage to retro gaming, or as a means to obscure certain elements within the game, such as + * during a transition or to censor specific content. + * @param amount The amount of pixelation to apply. Default 1. + */ + addPixelate(amount?: number): Phaser.FX.Pixelate; + /** + * Adds a Vignette effect. + * + * The vignette effect is a visual technique where the edges of the screen, or a Game Object, gradually darken or blur, + * creating a frame-like appearance. This effect is used to draw the player's focus towards the central action or subject, + * enhance immersion, and provide a cinematic or artistic quality to the game's visuals. + * @param x The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1. Default 0.5. + * @param y The vertical offset of the vignette effect. This value is normalized to the range 0 to 1. Default 0.5. + * @param radius The radius of the vignette effect. This value is normalized to the range 0 to 1. Default 0.5. + * @param strength The strength of the vignette effect. Default 0.5. + */ + addVignette(x?: number, y?: number, radius?: number, strength?: number): Phaser.FX.Vignette; + /** + * Adds a Shine effect. + * + * The shine effect is a visual technique that simulates the appearance of reflective + * or glossy surfaces by passing a light beam across a Game Object. This effect is used to + * enhance visual appeal, emphasize certain features, and create a sense of depth or + * material properties. + * @param speed The speed of the Shine effect. Default 0.5. + * @param lineWidth The line width of the Shine effect. Default 0.5. + * @param gradient The gradient of the Shine effect. Default 3. + * @param reveal Does this Shine effect reveal or get added to its target? Default false. + */ + addShine(speed?: number, lineWidth?: number, gradient?: number, reveal?: boolean): Phaser.FX.Shine; + /** + * Adds a Blur effect. + * + * A Gaussian blur is the result of blurring an image by a Gaussian function. It is a widely used effect, + * typically to reduce image noise and reduce detail. The visual effect of this blurring technique is a + * smooth blur resembling that of viewing the image through a translucent screen, distinctly different + * from the bokeh effect produced by an out-of-focus lens or the shadow of an object under usual illumination. + * @param quality The quality of the blur effect. Can be either 0 for Low Quality, 1 for Medium Quality or 2 for High Quality. Default 0. + * @param x The horizontal offset of the blur effect. Default 2. + * @param y The vertical offset of the blur effect. Default 2. + * @param strength The strength of the blur effect. Default 1. + * @param color The color of the blur, as a hex value. Default 0xffffff. + * @param steps The number of steps to run the blur effect for. This value should always be an integer. Default 4. + */ + addBlur(quality?: number, x?: number, y?: number, strength?: number, color?: number, steps?: number): Phaser.FX.Blur; + /** + * Adds a Gradient effect. + * + * The gradient overlay effect is a visual technique where a smooth color transition is applied over Game Objects, + * such as sprites or UI components. This effect is used to enhance visual appeal, emphasize depth, or create + * stylistic and atmospheric variations. It can also be utilized to convey information, such as representing + * progress or health status through color changes. + * @param color1 The first gradient color, given as a number value. Default 0xff0000. + * @param color2 The second gradient color, given as a number value. Default 0x00ff00. + * @param alpha The alpha value of the gradient effect. Default 0.2. + * @param fromX The horizontal position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. Default 0. + * @param fromY The vertical position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. Default 0. + * @param toX The horizontal position the gradient will end at. This value is noralized, between 0 and 1 and is not in pixels. Default 0. + * @param toY The vertical position the gradient will end at. This value is noralized, between 0 and 1 and is not in pixels. Default 1. + * @param size How many 'chunks' the gradient is divided in to, as spread over the entire height of the texture. Leave this at zero for a smooth gradient, or set higher for a more retro chunky effect. Default 0. + */ + addGradient(color1?: number, color2?: number, alpha?: number, fromX?: number, fromY?: number, toX?: number, toY?: number, size?: number): Phaser.FX.Gradient; + /** + * Adds a Bloom effect. + * + * Bloom is an effect used to reproduce an imaging artifact of real-world cameras. + * The effect produces fringes of light extending from the borders of bright areas in an image, + * contributing to the illusion of an extremely bright light overwhelming the + * camera or eye capturing the scene. + * @param color The color of the Bloom, as a hex value. + * @param offsetX The horizontal offset of the bloom effect. Default 1. + * @param offsetY The vertical offset of the bloom effect. Default 1. + * @param blurStrength The strength of the blur process of the bloom effect. Default 1. + * @param strength The strength of the blend process of the bloom effect. Default 1. + * @param steps The number of steps to run the Bloom effect for. This value should always be an integer. Default 4. + */ + addBloom(color?: number, offsetX?: number, offsetY?: number, blurStrength?: number, strength?: number, steps?: number): Phaser.FX.Bloom; + /** + * Adds a ColorMatrix effect. + * + * The color matrix effect is a visual technique that involves manipulating the colors of an image + * or scene using a mathematical matrix. This process can adjust hue, saturation, brightness, and contrast, + * allowing developers to create various stylistic appearances or mood settings within the game. + * Common applications include simulating different lighting conditions, applying color filters, + * or achieving a specific visual style. + */ + addColorMatrix(): Phaser.FX.ColorMatrix; + /** + * Adds a Circle effect. + * + * This effect will draw a circle around the texture of the Game Object, effectively masking off + * any area outside of the circle without the need for an actual mask. You can control the thickness + * of the circle, the color of the circle and the color of the background, should the texture be + * transparent. You can also control the feathering applied to the circle, allowing for a harsh or soft edge. + * + * Please note that adding this effect to a Game Object will not change the input area or physics body of + * the Game Object, should it have one. + * @param thickness The width of the circle around the texture, in pixels. Default 8. + * @param color The color of the circular ring, given as a number value. Default 0xfeedb6. + * @param backgroundColor The color of the background, behind the texture, given as a number value. Default 0xff0000. + * @param scale The scale of the circle. The default scale is 1, which is a circle the full size of the underlying texture. Default 1. + * @param feather The amount of feathering to apply to the circle from the ring. Default 0.005. + */ + addCircle(thickness?: number, color?: number, backgroundColor?: number, scale?: number, feather?: number): Phaser.FX.Circle; + /** + * Adds a Barrel effect. + * + * A barrel effect allows you to apply either a 'pinch' or 'expand' distortion to + * a Game Object. The amount of the effect can be modified in real-time. + * @param amount The amount of distortion applied to the barrel effect. A value of 1 is no distortion. Typically keep this within +- 1. Default 1. + */ + addBarrel(amount?: number): Phaser.FX.Barrel; + /** + * Adds a Displacement effect. + * + * The displacement effect is a visual technique that alters the position of pixels in an image + * or texture based on the values of a displacement map. This effect is used to create the illusion + * of depth, surface irregularities, or distortion in otherwise flat elements. It can be applied to + * characters, objects, or backgrounds to enhance realism, convey movement, or achieve various + * stylistic appearances. + * @param texture The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager. Default '__WHITE'. + * @param x The amount of horizontal displacement to apply. A very small float number, such as 0.005. Default 0.005. + * @param y The amount of vertical displacement to apply. A very small float number, such as 0.005. Default 0.005. + */ + addDisplacement(texture?: string, x?: number, y?: number): Phaser.FX.Displacement; + /** + * Adds a Wipe effect. + * + * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements + * in the game, such as images, text, or scene transitions. This effect is often used to create + * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition + * between game states. + * + * You can set both the direction and the axis of the wipe effect. The following combinations are possible: + * + * * left to right: direction 0, axis 0 + * * right to left: direction 1, axis 0 + * * top to bottom: direction 1, axis 1 + * * bottom to top: direction 1, axis 0 + * + * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect. + * @param wipeWidth The width of the wipe effect. This value is normalized in the range 0 to 1. Default 0.1. + * @param direction The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. Default 0. + * @param axis The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. Default 0. + */ + addWipe(wipeWidth?: number, direction?: number, axis?: number): Phaser.FX.Wipe; + /** + * Adds a Reveal Wipe effect. + * + * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements + * in the game, such as images, text, or scene transitions. This effect is often used to create + * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition + * between game states. + * + * You can set both the direction and the axis of the wipe effect. The following combinations are possible: + * + * * left to right: direction 0, axis 0 + * * right to left: direction 1, axis 0 + * * top to bottom: direction 1, axis 1 + * * bottom to top: direction 1, axis 0 + * + * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect. + * @param wipeWidth The width of the wipe effect. This value is normalized in the range 0 to 1. Default 0.1. + * @param direction The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. Default 0. + * @param axis The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. Default 0. + */ + addReveal(wipeWidth?: number, direction?: number, axis?: number): Phaser.FX.Wipe; + /** + * Adds a Bokeh effect. + * + * Bokeh refers to a visual effect that mimics the photographic technique of creating a shallow depth of field. + * This effect is used to emphasize the game's main subject or action, by blurring the background or foreground + * elements, resulting in a more immersive and visually appealing experience. It is achieved through rendering + * techniques that simulate the out-of-focus areas, giving a sense of depth and realism to the game's graphics. + * + * See also Tilt Shift. + * @param radius The radius of the bokeh effect. Default 0.5. + * @param amount The amount of the bokeh effect. Default 1. + * @param contrast The color contrast of the bokeh effect. Default 0.2. + */ + addBokeh(radius?: number, amount?: number, contrast?: number): Phaser.FX.Bokeh; + /** + * Adds a Tilt Shift effect. + * + * This Bokeh effect can also be used to generate a Tilt Shift effect, which is a technique used to create a miniature + * effect by blurring everything except a small area of the image. This effect is achieved by blurring the + * top and bottom elements, while keeping the center area in focus. + * + * See also Bokeh. + * @param radius The radius of the bokeh effect. Default 0.5. + * @param amount The amount of the bokeh effect. Default 1. + * @param contrast The color contrast of the bokeh effect. Default 0.2. + * @param blurX The amount of horizontal blur. Default 1. + * @param blurY The amount of vertical blur. Default 1. + * @param strength The strength of the blur. Default 1. + */ + addTiltShift(radius?: number, amount?: number, contrast?: number, blurX?: number, blurY?: number, strength?: number): Phaser.FX.Bokeh; + /** + * Destroys this FX Component. + * + * Called automatically when Game Objects are destroyed. + */ + destroy(): void; + } + + /** + * Provides methods used for obtaining the bounds of a Game Object. + * Should be applied as a mixin and not used directly. + */ + interface GetBounds { + /** + * Gets the center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getCenter(output?: O, includeParent?: boolean): O; + /** + * Gets the top-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopLeft(output?: O, includeParent?: boolean): O; + /** + * Gets the top-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopCenter(output?: O, includeParent?: boolean): O; + /** + * Gets the top-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopRight(output?: O, includeParent?: boolean): O; + /** + * Gets the left-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getLeftCenter(output?: O, includeParent?: boolean): O; + /** + * Gets the right-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getRightCenter(output?: O, includeParent?: boolean): O; + /** + * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomLeft(output?: O, includeParent?: boolean): O; + /** + * Gets the bottom-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomCenter(output?: O, includeParent?: boolean): O; + /** + * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomRight(output?: O, includeParent?: boolean): O; + /** + * Gets the bounds of this Game Object, regardless of origin. + * + * The values are stored and returned in a Rectangle, or Rectangle-like, object. + * @param output An object to store the values in. If not provided a new Rectangle will be created. + */ + getBounds(output?: O): O; + } + + /** + * Provides methods used for getting and setting the mask of a Game Object. + */ + interface Mask { + /** + * The Mask this Game Object is using during render. + */ + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; + /** + * Sets the mask that this Game Object will use to render with. + * + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * If a mask is already set on this Game Object it will be immediately replaced. + * + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * @param mask The mask this Game Object will use when rendering. + */ + setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; + /** + * Clears the mask that this Game Object was using. + * @param destroyMask Destroy the mask before clearing it? Default false. + */ + clearMask(destroyMask?: boolean): this; + /** + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. + * + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. + * + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. + */ + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; + /** + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. + * + * To create the mask you need to pass in a reference to a Graphics Game Object. + * + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. + * + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. + */ + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; + } + + /** + * Provides methods used for getting and setting the origin of a Game Object. + * Values are normalized, given in the range 0 to 1. + * Display values contain the calculated pixel values. + * Should be applied as a mixin and not used directly. + */ + interface Origin { + /** + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originX: number; + /** + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originY: number; + /** + * The horizontal display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginX: number; + /** + * The vertical display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginY: number; + /** + * Sets the origin of this Game Object. + * + * The values are given in the range 0 to 1. + * @param x The horizontal origin value. Default 0.5. + * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. + */ + setOrigin(x?: number, y?: number): this; + /** + * Sets the origin of this Game Object based on the Pivot values in its Frame. + */ + setOriginFromFrame(): this; + /** + * Sets the display origin of this Game Object. + * The difference between this and setting the origin is that you can use pixel values for setting the display origin. + * @param x The horizontal display origin value. Default 0. + * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + */ + setDisplayOrigin(x?: number, y?: number): this; + /** + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. + */ + updateDisplayOrigin(): this; + } + + /** + * Provides methods used for managing a Game Object following a Path. + * Should be applied as a mixin and not used directly. + */ + interface PathFollower { + /** + * The Path this PathFollower is following. It can only follow one Path at a time. + */ + path: Phaser.Curves.Path; + /** + * Should the PathFollower automatically rotate to point in the direction of the Path? + */ + rotateToPath: boolean; + /** + * Set the Path that this PathFollower should follow. + * + * Optionally accepts {@link Phaser.Types.GameObjects.PathFollower.PathConfig} settings. + * @param path The Path this PathFollower is following. It can only follow one Path at a time. + * @param config Settings for the PathFollower. + */ + setPath(path: Phaser.Curves.Path, config?: number | Phaser.Types.GameObjects.PathFollower.PathConfig | Phaser.Types.Tweens.NumberTweenBuilderConfig): this; + /** + * Set whether the PathFollower should automatically rotate to point in the direction of the Path. + * @param value Whether the PathFollower should automatically rotate to point in the direction of the Path. + * @param offset Rotation offset in degrees. Default 0. + */ + setRotateToPath(value: boolean, offset?: number): this; + /** + * Is this PathFollower actively following a Path or not? + * + * To be considered as `isFollowing` it must be currently moving on a Path, and not paused. + */ + isFollowing(): boolean; + /** + * Starts this PathFollower following its given Path. + * @param config The duration of the follow, or a PathFollower config object. Default {}. + * @param startAt Optional start position of the follow, between 0 and 1. Default 0. + */ + startFollow(config?: number | Phaser.Types.GameObjects.PathFollower.PathConfig | Phaser.Types.Tweens.NumberTweenBuilderConfig, startAt?: number): this; + /** + * Pauses this PathFollower. It will still continue to render, but it will remain motionless at the + * point on the Path at which you paused it. + */ + pauseFollow(): this; + /** + * Resumes a previously paused PathFollower. + * + * If the PathFollower was not paused this has no effect. + */ + resumeFollow(): this; + /** + * Stops this PathFollower from following the path any longer. + * + * This will invoke any 'stop' conditions that may exist on the Path, or for the follower. + */ + stopFollow(): this; + /** + * Internal update handler that advances this PathFollower along the path. + * + * Called automatically by the Scene step, should not typically be called directly. + */ + pathUpdate(): void; + } + + /** + * Provides methods used for setting the WebGL rendering pipeline of a Game Object. + */ + interface Pipeline { + /** + * The initial WebGL pipeline of this Game Object. + * + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + */ + defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * The current WebGL pipeline of this Game Object. + */ + pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + } + + /** + * Provides methods used for setting the WebGL rendering post pipeline of a Game Object. + */ + interface PostPipeline { + /** + * Does this Game Object have any Post Pipelines set? + */ + hasPostPipeline: boolean; + /** + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * + * The pipelines are processed in the order in which they appear in this array. + * + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. + */ + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + postPipelineData: object; + /** + * The Pre FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + */ + preFX: Phaser.GameObjects.Components.FX | null; + /** + * The Post FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. + */ + postFX: Phaser.GameObjects.Components.FX; + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; + /** + * Sets one, or more, Post Pipelines on this Game Object. + * + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. + * + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. + * + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * + * You can optionally also set the `postPipelineData` property, if the parameter is given. + * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; + /** + * Adds an entry to the `postPipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPostPipelineData(key: string, value?: any): this; + /** + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * @param pipeline The string-based name of the pipeline, or a pipeline class. + */ + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + /** + * Resets the WebGL Post Pipelines of this Game Object. It does this by calling + * the `destroy` method on each post pipeline and then clearing the local array. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. + */ + resetPostPipeline(resetData?: boolean): void; + /** + * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. + * + * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. + * @param pipeline The string-based name of the pipeline, or a pipeline class. + */ + removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; + /** + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. + */ + clearFX(): this; + } + + /** + * Provides methods used for getting and setting the Scroll Factor of a Game Object. + */ + interface ScrollFactor { + /** + * The horizontal scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorX: number; + /** + * The vertical scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorY: number; + /** + * Sets the scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. + */ + setScrollFactor(x: number, y?: number): this; + } + + /** + * Provides methods used for getting and setting the size of a Game Object. + */ + interface Size { + /** + * The native (un-scaled) width of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. + */ + width: number; + /** + * The native (un-scaled) height of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. + */ + height: number; + /** + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayWidth: number; + /** + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayHeight: number; + /** + * Sets the size of this Game Object to be that of the given Frame. + * + * This will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or call the + * `setDisplaySize` method, which is the same thing as changing the scale but allows you + * to do so by giving pixel values. + * + * If you have enabled this Game Object for input, changing the size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * @param frame The frame to base the size of this Game Object on. + */ + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; + /** + * Sets the internal size of this Game Object, as used for frame or physics body creation. + * + * This will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or call the + * `setDisplaySize` method, which is the same thing as changing the scale but allows you + * to do so by giving pixel values. + * + * If you have enabled this Game Object for input, changing the size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setSize(width: number, height: number): this; + /** + * Sets the display size of this Game Object. + * + * Calling this will adjust the scale. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setDisplaySize(width: number, height: number): this; + } + + /** + * Provides methods used for getting and setting the texture of a Game Object. + */ + interface Texture { + /** + * The Texture this Game Object is using to render with. + */ + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + /** + * The Texture Frame this Game Object is using to render with. + */ + frame: Phaser.Textures.Frame; + /** + * Sets the texture and frame this Game Object will use to render with. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. + * @param frame The name or index of the frame within the Texture. + */ + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; + /** + * Sets the frame this Game Object will use to render with. + * + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. + * + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. + * + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. + */ + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; + } + + /** + * Provides methods used for getting and setting the texture of a Game Object. + */ + interface TextureCrop { + /** + * The Texture this Game Object is using to render with. + */ + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + /** + * The Texture Frame this Game Object is using to render with. + */ + frame: Phaser.Textures.Frame; + /** + * A boolean flag indicating if this Game Object is being cropped or not. + * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. + * Equally, calling `setCrop` with no arguments will reset the crop and disable it. + */ + isCropped: boolean; + /** + * Applies a crop to a texture based Game Object, such as a Sprite or Image. + * + * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. + * + * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just + * changes what is shown when rendered. + * + * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. + * + * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left + * half of it, you could call `setCrop(0, 0, 400, 600)`. + * + * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop + * an area of 200x100 when applied to a Game Object that had a scale factor of 2. + * + * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. + * + * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. + * + * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow + * the renderer to skip several internal calculations. + * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. + * @param y The y coordinate to start the crop from. + * @param width The width of the crop rectangle in pixels. + * @param height The height of the crop rectangle in pixels. + */ + setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; + /** + * Sets the texture and frame this Game Object will use to render with. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. + */ + setTexture(key: string, frame?: string | number): this; + /** + * Sets the frame this Game Object will use to render with. + * + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. + * + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. + * + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. + */ + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; + } + + /** + * Provides methods used for setting the tint of a Game Object. + * Should be applied as a mixin and not used directly. + */ + interface Tint { + /** + * The tint value being applied to the top-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintTopLeft: number; + /** + * The tint value being applied to the top-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintTopRight: number; + /** + * The tint value being applied to the bottom-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomLeft: number; + /** + * The tint value being applied to the bottom-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomRight: number; + /** + * The tint fill mode. + * + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + */ + tintFill: boolean; + /** + * Clears all tint values associated with this Game Object. + * + * Immediately sets the color values back to 0xffffff and the tint type to 'additive', + * which results in no visible change to the texture. + */ + clearTint(): this; + /** + * Sets an additive tint on this Game Object. + * + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole Game Object will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. + * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + */ + setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + /** + * Sets a fill-based tint on this Game Object. + * + * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture + * with those in the tint. You can use this for effects such as making a player flash 'white' + * if hit by something. You can provide either one color value, in which case the whole + * Game Object will be rendered in that color. Or you can provide a color per corner. The colors + * are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. + * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + */ + setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + /** + * The tint value being applied to the whole of the Game Object. + * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. + */ + tint: number; + /** + * Does this Game Object have a tint applied? + * + * It checks to see if the 4 tint properties are set to the value 0xffffff + * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. + */ + readonly isTinted: boolean; + } + + /** + * Build a JSON representation of the given Game Object. + * + * This is typically extended further by Game Object specific implementations. + */ + interface ToJSON { + } + + /** + * Provides methods used for getting and setting the position, scale and rotation of a Game Object. + */ + interface Transform { + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** + * The x position of this Game Object. + */ + x: number; + /** + * The y position of this Game Object. + */ + y: number; + /** + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. + */ + z: number; + /** + * The w position of this Game Object. + */ + w: number; + /** + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. + */ + scale: number; + /** + * The horizontal scale of this Game Object. + */ + scaleX: number; + /** + * The vertical scale of this Game Object. + */ + scaleY: number; + /** + * The angle of this Game Object as expressed in degrees. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. + * + * If you prefer to work in radians, see the `rotation` property instead. + */ + angle: number; + /** + * The angle of this Game Object in radians. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. + */ + rotation: number; + /** + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. + */ + setPosition(x?: number, y?: number, z?: number, w?: number): this; + /** + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + */ + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + /** + * Sets the position of this Game Object to be a random position within the confines of + * the given area. + * + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. + */ + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + /** + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. + */ + setRotation(radians?: number): this; + /** + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. + */ + setAngle(degrees?: number): this; + /** + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + */ + setScale(x?: number, y?: number): this; + /** + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. + */ + setX(value?: number): this; + /** + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. + */ + setY(value?: number): this; + /** + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. + */ + setZ(value?: number): this; + /** + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. + */ + setW(value?: number): this; + /** + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. + */ + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + /** + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. + */ + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + /** + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. + * + * The returned Vector2 contains the translated point in its properties. + * + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. + */ + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + /** + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. + */ + getParentRotation(): number; + } + + /** + * A Matrix used for display transformations for rendering. + * + * It is represented like so: + * + * ``` + * | a | c | tx | + * | b | d | ty | + * | 0 | 0 | 1 | + * ``` + */ + class TransformMatrix { + /** + * + * @param a The Scale X value. Default 1. + * @param b The Skew Y value. Default 0. + * @param c The Skew X value. Default 0. + * @param d The Scale Y value. Default 1. + * @param tx The Translate X value. Default 0. + * @param ty The Translate Y value. Default 0. + */ + constructor(a?: number, b?: number, c?: number, d?: number, tx?: number, ty?: number); + + /** + * The matrix values. + */ + matrix: Float32Array; + + /** + * The decomposed matrix. + */ + decomposedMatrix: object; + + /** + * The temporary quad value cache. + */ + quad: Float32Array; + + /** + * The Scale X value. + */ + a: number; + + /** + * The Skew Y value. + */ + b: number; + + /** + * The Skew X value. + */ + c: number; + + /** + * The Scale Y value. + */ + d: number; + + /** + * The Translate X value. + */ + e: number; + + /** + * The Translate Y value. + */ + f: number; + + /** + * The Translate X value. + */ + tx: number; + + /** + * The Translate Y value. + */ + ty: number; + + /** + * The rotation of the Matrix. Value is in radians. + */ + readonly rotation: number; + + /** + * The rotation of the Matrix, normalized to be within the Phaser right-handed + * clockwise rotation space. Value is in radians. + */ + readonly rotationNormalized: number; + + /** + * The decomposed horizontal scale of the Matrix. This value is always positive. + */ + readonly scaleX: number; + + /** + * The decomposed vertical scale of the Matrix. This value is always positive. + */ + readonly scaleY: number; + + /** + * Reset the Matrix to an identity matrix. + */ + loadIdentity(): this; + + /** + * Translate the Matrix. + * @param x The horizontal translation value. + * @param y The vertical translation value. + */ + translate(x: number, y: number): this; + + /** + * Scale the Matrix. + * @param x The horizontal scale value. + * @param y The vertical scale value. + */ + scale(x: number, y: number): this; + + /** + * Rotate the Matrix. + * @param angle The angle of rotation in radians. + */ + rotate(angle: number): this; + + /** + * Multiply this Matrix by the given Matrix. + * + * If an `out` Matrix is given then the results will be stored in it. + * If it is not given, this matrix will be updated in place instead. + * Use an `out` Matrix if you do not wish to mutate this matrix. + * @param rhs The Matrix to multiply by. + * @param out An optional Matrix to store the results in. + */ + multiply(rhs: Phaser.GameObjects.Components.TransformMatrix, out?: Phaser.GameObjects.Components.TransformMatrix): this | Phaser.GameObjects.Components.TransformMatrix; + + /** + * Multiply this Matrix by the matrix given, including the offset. + * + * The offsetX is added to the tx value: `offsetX * a + offsetY * c + tx`. + * The offsetY is added to the ty value: `offsetY * b + offsetY * d + ty`. + * @param src The source Matrix to copy from. + * @param offsetX Horizontal offset to factor in to the multiplication. + * @param offsetY Vertical offset to factor in to the multiplication. + */ + multiplyWithOffset(src: Phaser.GameObjects.Components.TransformMatrix, offsetX: number, offsetY: number): this; + + /** + * Transform the Matrix. + * @param a The Scale X value. + * @param b The Shear Y value. + * @param c The Shear X value. + * @param d The Scale Y value. + * @param tx The Translate X value. + * @param ty The Translate Y value. + */ + transform(a: number, b: number, c: number, d: number, tx: number, ty: number): this; + + /** + * Transform a point in to the local space of this Matrix. + * @param x The x coordinate of the point to transform. + * @param y The y coordinate of the point to transform. + * @param point Optional Point object to store the transformed coordinates in. + */ + transformPoint(x: number, y: number, point?: Phaser.Types.Math.Vector2Like): Phaser.Types.Math.Vector2Like; + + /** + * Invert the Matrix. + */ + invert(): this; + + /** + * Set the values of this Matrix to copy those of the matrix given. + * @param src The source Matrix to copy from. + */ + copyFrom(src: Phaser.GameObjects.Components.TransformMatrix): this; + + /** + * Set the values of this Matrix to copy those of the array given. + * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f. + * @param src The array of values to set into this matrix. + */ + copyFromArray(src: any[]): this; + + /** + * Copy the values from this Matrix to the given Canvas Rendering Context. + * This will use the Context.transform method. + * @param ctx The Canvas Rendering Context to copy the matrix values to. + */ + copyToContext(ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; + + /** + * Copy the values from this Matrix to the given Canvas Rendering Context. + * This will use the Context.setTransform method. + * @param ctx The Canvas Rendering Context to copy the matrix values to. + */ + setToContext(ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; + + /** + * Copy the values in this Matrix to the array given. * - * This value takes into account the scale factor. + * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f. + * @param out The array to copy the matrix values in to. + */ + copyToArray(out?: any[]): any[]; + + /** + * Set the values of this Matrix. + * @param a The Scale X value. + * @param b The Shear Y value. + * @param c The Shear X value. + * @param d The Scale Y value. + * @param tx The Translate X value. + * @param ty The Translate Y value. + */ + setTransform(a: number, b: number, c: number, d: number, tx: number, ty: number): this; + + /** + * Decompose this Matrix into its translation, scale and rotation values using QR decomposition. * - * Setting this value will adjust the Game Object's scale property. + * The result must be applied in the following order to reproduce the current matrix: + * + * translate -> rotate -> scale */ - displayHeight: number; + decomposeMatrix(): Phaser.Types.GameObjects.DecomposeMatrixResults; + /** - * Sets the size of this Game Object to be that of the given Frame. + * Apply the identity, translate, rotate and scale operations on the Matrix. + * @param x The horizontal translation. + * @param y The vertical translation. + * @param rotation The angle of rotation in radians. + * @param scaleX The horizontal scale. + * @param scaleY The vertical scale. + */ + applyITRS(x: number, y: number, rotation: number, scaleX: number, scaleY: number): this; + + /** + * Takes the `x` and `y` values and returns a new position in the `output` vector that is the inverse of + * the current matrix with its transformation applied. * - * 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. + * Can be used to translate points from world to local space. + * @param x The x position to translate. + * @param y The y position to translate. + * @param output A Vector2, or point-like object, to store the results in. + */ + applyInverse(x: number, y: number, output?: Phaser.Math.Vector2): Phaser.Math.Vector2; + + /** + * Performs the 8 calculations required to create the vertices of + * a quad based on this matrix and the given x/y/xw/yh 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. - * @param frame The frame to base the size of this Game Object on. + * The result is stored in `TransformMatrix.quad`, which is returned + * from this method. + * @param x The x value. + * @param y The y value. + * @param xw The xw value. + * @param yh The yh value. + * @param roundPixels Pass the results via Math.round? + * @param quad Optional Float32Array to store the results in. Otherwises uses the local quad array. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setQuad(x: number, y: number, xw: number, yh: number, roundPixels: boolean, quad?: Float32Array): Float32Array; + /** - * Sets the internal size of this Game Object, as used for frame or physics body creation. + * Returns the X component of this matrix multiplied by the given values. + * This is the same as `x * a + y * c + e`. + * @param x The x value. + * @param y The y value. + */ + getX(x: number, y: number): number; + + /** + * Returns the Y component of this matrix multiplied by the given values. + * This is the same as `x * b + y * d + f`. + * @param x The x value. + * @param y The y value. + */ + getY(x: number, y: number): number; + + /** + * Returns the X component of this matrix multiplied by the given values. * - * 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. + * This is the same as `x * a + y * c + e`, optionally passing via `Math.round`. + * @param x The x value. + * @param y The y value. + * @param round Math.round the resulting value? Default false. + */ + getXRound(x: number, y: number, round?: boolean): number; + + /** + * Returns the Y component of this matrix multiplied by the given 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. - * @param width The width of this Game Object. - * @param height The height of this Game Object. + * This is the same as `x * b + y * d + f`, optionally passing via `Math.round`. + * @param x The x value. + * @param y The y value. + * @param round Math.round the resulting value? Default false. */ - setSize(width: number, height: number): this; + getYRound(x: number, y: number, round?: boolean): number; + /** - * Sets the display size of this Game Object. + * Returns a string that can be used in a CSS Transform call as a `matrix` property. + */ + getCSSMatrix(): string; + + /** + * Destroys this Transform Matrix. + */ + destroy(): void; + + } + + /** + * Provides methods used for setting the visibility of a Game Object. + * Should be applied as a mixin and not used directly. + */ + interface Visible { + /** + * The visible state of the Game Object. * - * Calling this will adjust the scale. - * @param width The width of this Game Object. - * @param height The height of this Game Object. + * An invisible Game Object will skip rendering, but will still process update logic. */ - setDisplaySize(width: number, height: number): this; + visible: boolean; + /** + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. + */ + setVisible(value: boolean): this; } + } + + /** + * A Container Game Object. + * + * A Container, as the name implies, can 'contain' other types of Game Object. + * When a Game Object is added to a Container, the Container becomes responsible for the rendering of it. + * By default it will be removed from the Display List and instead added to the Containers own internal list. + * + * The position of the Game Object automatically becomes relative to the position of the Container. + * + * The transform point of a Container is 0x0 (in local space) and that cannot be changed. The children you add to the + * Container should be positioned with this value in mind. I.e. you should treat 0x0 as being the center of + * the Container, and position children positively and negative around it as required. + * + * When the Container is rendered, all of its children are rendered as well, in the order in which they exist + * within the Container. Container children can be repositioned using methods such as `MoveUp`, `MoveDown` and `SendToBack`. + * + * If you modify a transform property of the Container, such as `Container.x` or `Container.rotation` then it will + * automatically influence all children as well. + * + * Containers can include other Containers for deeply nested transforms. + * + * Containers can have masks set on them and can be used as a mask too. However, Container children cannot be masked. + * The masks do not 'stack up'. Only a Container on the root of the display list will use its mask. + * + * Containers can be enabled for input. Because they do not have a texture you need to provide a shape for them + * to use as their hit area. Container children can also be enabled for input, independent of the Container. + * + * If input enabling a _child_ you should not set both the `origin` and a **negative** scale factor on the child, + * or the input area will become misaligned. + * + * Containers can be given a physics body for either Arcade Physics, Impact Physics or Matter Physics. However, + * if Container _children_ are enabled for physics you may get unexpected results, such as offset bodies, + * if the Container itself, or any of its ancestors, is positioned anywhere other than at 0 x 0. Container children + * with physics do not factor in the Container due to the excessive extra calculations needed. Please structure + * your game to work around this. + * + * It's important to understand the impact of using Containers. They add additional processing overhead into + * every one of their children. The deeper you nest them, the more the cost escalates. This is especially true + * for input events. You also loose the ability to set the display depth of Container children in the same + * flexible manner as those not within them. In short, don't use them for the sake of it. You pay a small cost + * every time you create one, try to structure your game around avoiding that where possible. + */ + class Container extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.ComputedSize, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + /** + * + * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param children An optional array of Game Objects to add to this Container. + */ + constructor(scene: Phaser.Scene, x?: number, y?: number, children?: Phaser.GameObjects.GameObject[]); + + /** + * An array holding the children of this Container. + */ + list: Phaser.GameObjects.GameObject[]; + + /** + * Does this Container exclusively manage its children? + * + * The default is `true` which means a child added to this Container cannot + * belong in another Container, which includes the Scene display list. + * + * If you disable this then this Container will no longer exclusively manage its children. + * This allows you to create all kinds of interesting graphical effects, such as replicating + * Game Objects without reparenting them all over the Scene. + * However, doing so will prevent children from receiving any kind of input event or have + * their physics bodies work by default, as they're no longer a single entity on the + * display list, but are being replicated where-ever this Container is. + */ + exclusive: boolean; + + /** + * Containers can have an optional maximum size. If set to anything above 0 it + * will constrict the addition of new Game Objects into the Container, capping off + * the maximum limit the Container can grow in size to. + */ + maxSize: number; + + /** + * The cursor position. + */ + position: number; + + /** + * Internal Transform Matrix used for local space conversion. + */ + localTransform: Phaser.GameObjects.Components.TransformMatrix; + + /** + * The horizontal scroll factor of this Container. + * + * The scroll factor controls the influence of the movement of a Camera upon this Container. + * + * When a camera scrolls it will change the location at which this Container is rendered on-screen. + * It does not change the Containers actual position values. + * + * For a Container, setting this value will only update the Container itself, not its children. + * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Container. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorX: number; + + /** + * The vertical scroll factor of this Container. + * + * The scroll factor controls the influence of the movement of a Camera upon this Container. + * + * When a camera scrolls it will change the location at which this Container is rendered on-screen. + * It does not change the Containers actual position values. + * + * For a Container, setting this value will only update the Container itself, not its children. + * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Container. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorY: number; + + /** + * Internal value to allow Containers to be used for input and physics. + * Do not change this value. It has no effect other than to break things. + */ + readonly originX: number; + + /** + * Internal value to allow Containers to be used for input and physics. + * Do not change this value. It has no effect other than to break things. + */ + readonly originY: number; + + /** + * Internal value to allow Containers to be used for input and physics. + * Do not change this value. It has no effect other than to break things. + */ + readonly displayOriginX: number; + + /** + * Internal value to allow Containers to be used for input and physics. + * Do not change this value. It has no effect other than to break things. + */ + readonly displayOriginY: number; + + /** + * Does this Container exclusively manage its children? + * + * The default is `true` which means a child added to this Container cannot + * belong in another Container, which includes the Scene display list. + * + * If you disable this then this Container will no longer exclusively manage its children. + * This allows you to create all kinds of interesting graphical effects, such as replicating + * Game Objects without reparenting them all over the Scene. + * However, doing so will prevent children from receiving any kind of input event or have + * their physics bodies work by default, as they're no longer a single entity on the + * display list, but are being replicated where-ever this Container is. + * @param value The exclusive state of this Container. Default true. + */ + setExclusive(value?: boolean): this; + + /** + * Gets the bounds of this Container. It works by iterating all children of the Container, + * getting their respective bounds, and then working out a min-max rectangle from that. + * It does not factor in if the children render or not, all are included. + * + * Some children are unable to return their bounds, such as Graphics objects, in which case + * they are skipped. + * + * Depending on the quantity of children in this Container it could be a really expensive call, + * so cache it and only poll it as needed. + * + * The values are stored and returned in a Rectangle object. + * @param output A Geom.Rectangle object to store the values in. If not provided a new Rectangle will be created. + */ + getBounds(output?: Phaser.Geom.Rectangle): Phaser.Geom.Rectangle; + + /** + * Takes a Point-like object, such as a Vector2, Geom.Point or object with public x and y properties, + * and transforms it into the space of this Container, then returns it in the output object. + * @param source The Source Point to be transformed. + * @param output A destination object to store the transformed point in. If none given a Vector2 will be created and returned. + */ + pointToContainer(source: Phaser.Types.Math.Vector2Like, output?: Phaser.Types.Math.Vector2Like): Phaser.Types.Math.Vector2Like; + + /** + * Returns the world transform matrix as used for Bounds checks. + * + * The returned matrix is temporal and shouldn't be stored. + */ + getBoundsTransformMatrix(): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Adds the given Game Object, or array of Game Objects, to this Container. + * + * Each Game Object must be unique within the Container. + * @param child The Game Object, or array of Game Objects, to add to the Container. + */ + add(child: (T|T[])): this; + + /** + * Adds the given Game Object, or array of Game Objects, to this Container at the specified position. + * + * Existing Game Objects in the Container are shifted up. + * + * Each Game Object must be unique within the Container. + * @param child The Game Object, or array of Game Objects, to add to the Container. + * @param index The position to insert the Game Object/s at. Default 0. + */ + addAt(child: (T|T[]), index?: number): this; + + /** + * Returns the Game Object at the given position in this Container. + * @param index The position to get the Game Object from. + */ + getAt(index: number): T; + + /** + * Returns the index of the given Game Object in this Container. + * @param child The Game Object to search for in this Container. + */ + getIndex(child: T): number; + + /** + * Sort the contents of this Container so the items are in order based on the given property. + * For example: `sort('alpha')` would sort the elements based on the value of their `alpha` property. + * @param property The property to lexically sort by. + * @param handler Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean. + */ + sort(property: string, handler?: Function): this; + + /** + * Searches for the first instance of a child with its `name` property matching the given argument. + * Should more than one child have the same name only the first is returned. + * @param name The name to search for. + */ + getByName(name: string): T; + + /** + * Returns a random Game Object from this Container. + * @param startIndex An optional start index. Default 0. + * @param length An optional length, the total number of elements (from the startIndex) to choose from. + */ + getRandom(startIndex?: number, length?: number): T; + + /** + * Gets the first Game Object in this Container. + * + * You can also specify a property and value to search for, in which case it will return the first + * Game Object in this Container with a matching property and / or value. + * + * For example: `getFirst('visible', true)` would return the first Game Object that had its `visible` property set. + * + * You can limit the search to the `startIndex` - `endIndex` range. + * @param property The property to test on each Game Object in the Container. + * @param value The value to test the property against. Must pass a strict (`===`) comparison check. + * @param startIndex An optional start index to search from. Default 0. + * @param endIndex An optional end index to search up to (but not included) Default Container.length. + */ + getFirst(property: string, value: any, startIndex?: number, endIndex?: number): T; + + /** + * Returns all Game Objects in this Container. + * + * You can optionally specify a matching criteria using the `property` and `value` arguments. + * + * For example: `getAll('body')` would return only Game Objects that have a body property. + * + * You can also specify a value to compare the property to: + * + * `getAll('visible', true)` would return only Game Objects that have their visible property set to `true`. + * + * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects, + * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only + * the first 50 Game Objects. + * @param property The property to test on each Game Object in the Container. + * @param value If property is set then the `property` must strictly equal this value to be included in the results. + * @param startIndex An optional start index to search from. Default 0. + * @param endIndex An optional end index to search up to (but not included) Default Container.length. + */ + getAll(property?: string, value?: any, startIndex?: number, endIndex?: number): T[]; + + /** + * Returns the total number of Game Objects in this Container that have a property + * matching the given value. + * + * For example: `count('visible', true)` would count all the elements that have their visible property set. + * + * You can optionally limit the operation to the `startIndex` - `endIndex` range. + * @param property The property to check. + * @param value The value to check. + * @param startIndex An optional start index to search from. Default 0. + * @param endIndex An optional end index to search up to (but not included) Default Container.length. + */ + count(property: string, value: any, startIndex?: number, endIndex?: number): number; + + /** + * Swaps the position of two Game Objects in this Container. + * Both Game Objects must belong to this Container. + * @param child1 The first Game Object to swap. + * @param child2 The second Game Object to swap. + */ + swap(child1: T, child2: T): this; + + /** + * Moves a Game Object to a new position within this Container. + * + * The Game Object must already be a child of this Container. + * + * The Game Object is removed from its old position and inserted into the new one. + * Therefore the Container size does not change. Other children will change position accordingly. + * @param child The Game Object to move. + * @param index The new position of the Game Object in this Container. + */ + moveTo(child: T, index: number): this; + + /** + * Moves a Game Object above another one within this Container. + * + * These 2 Game Objects must already be children of this Container. + * @param child1 The Game Object to move above base Game Object. + * @param child2 The base Game Object. + */ + moveAbove(child1: T, child2: T): this; + + /** + * Moves a Game Object below another one within this Container. + * + * These 2 Game Objects must already be children of this Container. + * @param child1 The Game Object to move below base Game Object. + * @param child2 The base Game Object. + */ + moveBelow(child1: T, child2: T): this; + + /** + * Removes the given Game Object, or array of Game Objects, from this Container. + * + * The Game Objects must already be children of this Container. + * + * You can also optionally call `destroy` on each Game Object that is removed from the Container. + * @param child The Game Object, or array of Game Objects, to be removed from the Container. + * @param destroyChild Optionally call `destroy` on each child successfully removed from this Container. Default false. + */ + remove(child: (T|T[]), destroyChild?: boolean): this; + + /** + * Removes the Game Object at the given position in this Container. + * + * You can also optionally call `destroy` on the Game Object, if one is found. + * @param index The index of the Game Object to be removed. + * @param destroyChild Optionally call `destroy` on the Game Object if successfully removed from this Container. Default false. + */ + removeAt(index: number, destroyChild?: boolean): this; + + /** + * Removes the Game Objects between the given positions in this Container. + * + * You can also optionally call `destroy` on each Game Object that is removed from the Container. + * @param startIndex An optional start index to search from. Default 0. + * @param endIndex An optional end index to search up to (but not included) Default Container.length. + * @param destroyChild Optionally call `destroy` on each Game Object successfully removed from this Container. Default false. + */ + removeBetween(startIndex?: number, endIndex?: number, destroyChild?: boolean): this; + + /** + * Removes all Game Objects from this Container. + * + * You can also optionally call `destroy` on each Game Object that is removed from the Container. + * @param destroyChild Optionally call `destroy` on each Game Object successfully removed from this Container. Default false. + */ + removeAll(destroyChild?: boolean): this; + + /** + * Brings the given Game Object to the top of this Container. + * This will cause it to render on-top of any other objects in the Container. + * @param child The Game Object to bring to the top of the Container. + */ + bringToTop(child: T): this; + + /** + * Sends the given Game Object to the bottom of this Container. + * This will cause it to render below any other objects in the Container. + * @param child The Game Object to send to the bottom of the Container. + */ + sendToBack(child: T): this; + + /** + * Moves the given Game Object up one place in this Container, unless it's already at the top. + * @param child The Game Object to be moved in the Container. + */ + moveUp(child: T): this; + + /** + * Moves the given Game Object down one place in this Container, unless it's already at the bottom. + * @param child The Game Object to be moved in the Container. + */ + moveDown(child: T): this; + + /** + * Reverses the order of all Game Objects in this Container. + */ + reverse(): this; + + /** + * Shuffles the all Game Objects in this Container using the Fisher-Yates implementation. + */ + shuffle(): this; + + /** + * Replaces a Game Object in this Container with the new Game Object. + * The new Game Object cannot already be a child of this Container. + * @param oldChild The Game Object in this Container that will be replaced. + * @param newChild The Game Object to be added to this Container. + * @param destroyChild Optionally call `destroy` on the Game Object if successfully removed from this Container. Default false. + */ + replace(oldChild: T, newChild: T, destroyChild?: boolean): this; + + /** + * Returns `true` if the given Game Object is a direct child of this Container. + * + * This check does not scan nested Containers. + * @param child The Game Object to check for within this Container. + */ + exists(child: T): boolean; + + /** + * Sets the property to the given value on all Game Objects in this Container. + * + * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects, + * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only + * the first 50 Game Objects. + * @param property The property that must exist on the Game Object. + * @param value The value to get the property to. + * @param startIndex An optional start index to search from. Default 0. + * @param endIndex An optional end index to search up to (but not included) Default Container.length. + */ + setAll(property: string, value: any, startIndex?: number, endIndex?: number): this; + + /** + * Passes all Game Objects in this Container to the given callback. + * + * A copy of the Container is made before passing each entry to your callback. + * This protects against the callback itself modifying the Container. + * + * If you know for sure that the callback will not change the size of this Container + * then you can use the more performant `Container.iterate` method instead. + * @param callback The function to call. + * @param context Value to use as `this` when executing callback. + * @param args Additional arguments that will be passed to the callback, after the child. + */ + each(callback: Function, context?: object, ...args: any[]): this; + + /** + * Passes all Game Objects in this Container to the given callback. + * + * Only use this method when you absolutely know that the Container will not be modified during + * the iteration, i.e. by removing or adding to its contents. + * @param callback The function to call. + * @param context Value to use as `this` when executing callback. + * @param args Additional arguments that will be passed to the callback, after the child. + */ + iterate(callback: Function, context?: object, ...args: any[]): this; + + /** + * Sets the scroll factor of this Container and optionally all of its children. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. + * @param updateChildren Apply this scrollFactor to all Container children as well? Default false. + */ + setScrollFactor(x: number, y?: number, updateChildren?: boolean): this; + + /** + * The number of Game Objects inside this Container. + */ + readonly length: number; + + /** + * Returns the first Game Object within the Container, or `null` if it is empty. + * + * You can move the cursor by calling `Container.next` and `Container.previous`. + */ + readonly first: Phaser.GameObjects.GameObject | null; + + /** + * Returns the last Game Object within the Container, or `null` if it is empty. + * + * You can move the cursor by calling `Container.next` and `Container.previous`. + */ + readonly last: Phaser.GameObjects.GameObject | null; + + /** + * Returns the next Game Object within the Container, or `null` if it is empty. + * + * You can move the cursor by calling `Container.next` and `Container.previous`. + */ + readonly next: Phaser.GameObjects.GameObject | null; + + /** + * Returns the previous Game Object within the Container, or `null` if it is empty. + * + * You can move the cursor by calling `Container.next` and `Container.previous`. + */ + readonly previous: Phaser.GameObjects.GameObject | null; + + /** + * Internal destroy handler, called as part of the destroy process. + */ + protected preDestroy(): void; + + /** + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). + */ + clearAlpha(): this; + + /** + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * @param value The alpha value applied across the whole Game Object. Default 1. + */ + setAlpha(value?: number): this; + + /** + * The alpha value of the Game Object. + * + * This is a global value, impacting the entire Game Object, not just a region of it. + */ + alpha: number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. + */ + blendMode: Phaser.BlendModes | string | number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * @param value The BlendMode value. Either a string, a CONST or a number. + */ + setBlendMode(value: string | Phaser.BlendModes | number): this; + + /** + * The native (un-scaled) width of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. + */ + width: number; + + /** + * The native (un-scaled) height of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. + */ + height: number; + + /** + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayWidth: number; + + /** + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayHeight: number; + + /** + * 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. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setSize(width: number, height: number): this; + + /** + * Sets the display size of this Game Object. + * + * Calling this will adjust the scale. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setDisplaySize(width: number, height: number): this; + + /** + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + */ + depth: number; + + /** + * The depth of this Game Object within the Scene. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. + */ + setDepth(value: number): this; + + /** + * The Mask this Game Object is using during render. + */ + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; + + /** + * Sets the mask that this Game Object will use to render with. + * + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * If a mask is already set on this Game Object it will be immediately replaced. + * + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * @param mask The mask this Game Object will use when rendering. + */ + setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; + + /** + * Clears the mask that this Game Object was using. + * @param destroyMask Destroy the mask before clearing it? Default false. + */ + clearMask(destroyMask?: boolean): this; + + /** + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. + * + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. + * + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. + */ + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; + + /** + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. + * + * To create the mask you need to pass in a reference to a Graphics Game Object. + * + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. + * + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. + */ + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; + + /** + * Does this Game Object have any Post Pipelines set? + */ + hasPostPipeline: boolean; + + /** + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * + * The pipelines are processed in the order in which they appear in this array. + * + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. + */ + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + postPipelineData: object; + + /** + * The Pre FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + */ + preFX: Phaser.GameObjects.Components.FX | null; + + /** + * The Post FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. + */ + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; + + /** + * Sets one, or more, Post Pipelines on this Game Object. + * + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. + * + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. + * + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * + * You can optionally also set the `postPipelineData` property, if the parameter is given. + * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `postPipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPostPipelineData(key: string, value?: any): this; + + /** + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * @param pipeline The string-based name of the pipeline, or a pipeline class. + */ + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + + /** + * Resets the WebGL Post Pipelines of this Game Object. It does this by calling + * the `destroy` method on each post pipeline and then clearing the local array. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. + */ + resetPostPipeline(resetData?: boolean): void; + + /** + * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. + * + * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. + * @param pipeline The string-based name of the pipeline, or a pipeline class. + */ + removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; + + /** + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. + */ + clearFX(): this; + + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + + /** + * The x position of this Game Object. + */ + x: number; + + /** + * The y position of this Game Object. + */ + y: number; + + /** + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. + */ + z: number; + + /** + * The w position of this Game Object. + */ + w: number; + + /** + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. + */ + scale: number; + + /** + * The horizontal scale of this Game Object. + */ + scaleX: number; + + /** + * The vertical scale of this Game Object. + */ + scaleY: number; + + /** + * The angle of this Game Object as expressed in degrees. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. + * + * If you prefer to work in radians, see the `rotation` property instead. + */ + angle: number; + + /** + * The angle of this Game Object in radians. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. + */ + rotation: number; + + /** + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. + */ + setPosition(x?: number, y?: number, z?: number, w?: number): this; + + /** + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + */ + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + + /** + * Sets the position of this Game Object to be a random position within the confines of + * the given area. + * + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. + */ + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + + /** + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. + */ + setRotation(radians?: number): this; + + /** + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. + */ + setAngle(degrees?: number): this; + + /** + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + */ + setScale(x?: number, y?: number): this; + + /** + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. + */ + setX(value?: number): this; + + /** + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. + */ + setY(value?: number): this; + + /** + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. + */ + setZ(value?: number): this; + + /** + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. + */ + setW(value?: number): this; + + /** + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. + */ + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. + */ + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. + * + * The returned Vector2 contains the translated point in its properties. + * + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. + */ + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + + /** + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. + */ + getParentRotation(): number; + + /** + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + */ + visible: boolean; + + /** + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. + */ + setVisible(value: boolean): this; + + } + + /** + * The Display List plugin. + * + * Display Lists belong to a Scene and maintain the list of Game Objects to render every frame. + * + * Some of these Game Objects may also be part of the Scene's [Update List]{@link Phaser.GameObjects.UpdateList}, for updating. + */ + class DisplayList extends Phaser.Structs.List { + /** + * + * @param scene The Scene that this Display List belongs to. + */ + constructor(scene: Phaser.Scene); + + /** + * The flag the determines whether Game Objects should be sorted when `depthSort()` is called. + */ + sortChildrenFlag: boolean; + + /** + * The Scene that this Display List belongs to. + */ + scene: Phaser.Scene; + + /** + * The Scene's Systems. + */ + systems: Phaser.Scenes.Systems; + + /** + * The Scene's Event Emitter. + */ + events: Phaser.Events.EventEmitter; + + /** + * Force a sort of the display list on the next call to depthSort. + */ + queueDepthSort(): void; + + /** + * Immediately sorts the display list if the flag is set. + */ + depthSort(): void; + + /** + * Compare the depth of two Game Objects. + * @param childA The first Game Object. + * @param childB The second Game Object. + */ + sortByDepth(childA: Phaser.GameObjects.GameObject, childB: Phaser.GameObjects.GameObject): number; + + /** + * Returns an array which contains all objects currently on the Display List. + * This is a reference to the main list array, not a copy of it, so be careful not to modify it. + */ + getChildren(): Phaser.GameObjects.GameObject[]; + + } + + /** + * 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 + * } + * ``` + * + * You must also have a parent container for Phaser. This is specified by the `parent` property in the + * game config. + * + * When these two things are 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 implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + /** + * + * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. + * @param x The horizontal position of this DOM Element in the world. Default 0. + * @param y The vertical position of this DOM Element in the world. Default 0. + * @param 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 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 innerText If given, will be set directly as the elements `innerText` property value, replacing whatever was there before. + */ + constructor(scene: Phaser.Scene, x?: number, y?: number, element?: Element | string, style?: string | any, innerText?: string); + + /** + * A reference to the parent DOM Container that the Game instance created when it started. + */ + parent: Element; + + /** + * A reference to the HTML Cache. + */ + cache: Phaser.Cache.BaseCache; + + /** + * 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. + */ + node: Element; + + /** + * 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. + */ + transformOnly: boolean; + + /** + * 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 + */ + skewX: number; + + /** + * 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 + */ + skewY: number; + + /** + * 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 + */ + rotate3d: Phaser.Math.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 + */ + rotate3dAngle: string; + + /** + * Sets the CSS `pointerEvents` attribute on the DOM Element during rendering. + * + * This is 'auto' by default. Changing it may have unintended side-effects with + * internal Phaser input handling, such as dragging, so only change this if you + * understand the implications. + */ + pointerEvents: string; + + /** + * 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. + */ + readonly width: number; + + /** + * 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. + */ + readonly height: number; + + /** + * 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. + */ + readonly displayWidth: number; + + /** + * 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. + */ + readonly displayHeight: number; + + /** + * 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 + * @param x The angle, in radians, by which to skew the DOM Element on the horizontal axis. Default 0. + * @param y The angle, in radians, by which to skew the DOM Element on the vertical axis. Default x. + */ + setSkew(x?: number, y?: number): 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.** + * @param value The perspective value, in pixels, that determines the distance between the z plane and the user. + */ + setPerspective(value: number): 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.** + */ + perspective: number; + + /** + * 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); + * ``` + * @param events The DOM event/s to listen for. You can specify multiple events by separating them with spaces. + */ + addListener(events: string): this; + + /** + * Removes one or more native DOM event listeners from the underlying Element of this Game Object. + * @param events The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces. + */ + removeListener(events: string): this; + + /** + * 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. + * @param 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 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 innerText A DOMString that holds the text that will be set as the innerText of the created element. + */ + createElement(tagName: string, style?: string | any, innerText?: string): this; + + /** + * 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'); + * ``` + * @param element If a string it is passed to `getElementById()`, or it should be a reference to an existing Element. + * @param 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 innerText A DOMString that holds the text that will be set as the innerText of the created element. + */ + setElement(element: string | Element, style?: string | any, innerText?: string): this; + + /** + * 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. + * @param The key of the html cache entry to use for this DOM Element. + * @param tagName The tag name of the element into which all of the loaded html will be inserted. Defaults to a plain div tag. Default 'div'. + */ + createFromCache(The: string, tagName?: string): 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. + * @param html A string of html to be set as the `innerHTML` property of the created element. + * @param tagName The tag name of the element into which all of the html will be inserted. Defaults to a plain div tag. Default 'div'. + */ + createFromHTML(html: string, tagName?: string): this; + + /** + * 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`. + */ + removeElement(): 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. + */ + updateSize(): 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. + * @param property The property to search the children for. + * @param value The value the property must strictly equal. + */ + getChildByProperty(property: string, value: string): Element | 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. + * @param id The id to search the children for. + */ + getChildByID(id: string): Element | 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 name. It then returns this child if found, or `null` if not. + * + * Be aware that class and id names are case-sensitive. + * @param name The name to search the children for. + */ + getChildByName(name: string): Element | null; + + /** + * Sets the `className` property of the DOM Element node and updates the internal sizes. + * @param className A string representing the class or space-separated classes of the element. + */ + setClassName(className: string): 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. + * @param text A DOMString representing the rendered text content of the element. + */ + setText(text: string): this; + + /** + * Sets the `innerHTML` property of the DOM Element node and updates the internal sizes. + * @param html A DOMString of html to be set as the `innerHTML` property of the element. + */ + setHTML(html: string): this; + + /** + * 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. + */ + willRender(): boolean; + + /** + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). + */ + clearAlpha(): this; + + /** + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * @param value The alpha value applied across the whole Game Object. Default 1. + */ + setAlpha(value?: number): this; + + /** + * The alpha value of the Game Object. + * + * This is a global value, impacting the entire Game Object, not just a region of it. + */ + alpha: number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. + */ + blendMode: Phaser.BlendModes | string | number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * @param value The BlendMode value. Either a string, a CONST or a number. + */ + setBlendMode(value: string | Phaser.BlendModes | number): this; + + /** + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + */ + depth: number; + + /** + * The depth of this Game Object within the Scene. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. + */ + setDepth(value: number): this; + + /** + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originX: number; + + /** + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originY: number; + + /** + * The horizontal display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginX: number; + + /** + * The vertical display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginY: number; + + /** + * Sets the origin of this Game Object. + * + * The values are given in the range 0 to 1. + * @param x The horizontal origin value. Default 0.5. + * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. + */ + setOrigin(x?: number, y?: number): this; + + /** + * Sets the origin of this Game Object based on the Pivot values in its Frame. + */ + setOriginFromFrame(): this; + + /** + * Sets the display origin of this Game Object. + * The difference between this and setting the origin is that you can use pixel values for setting the display origin. + * @param x The horizontal display origin value. Default 0. + * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + */ + setDisplayOrigin(x?: number, y?: number): this; + + /** + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. + */ + updateDisplayOrigin(): this; + + /** + * The horizontal scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorX: number; + + /** + * The vertical scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorY: number; + + /** + * Sets the scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. + */ + setScrollFactor(x: number, y?: number): this; + + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + + /** + * The x position of this Game Object. + */ + x: number; + + /** + * The y position of this Game Object. + */ + y: number; + + /** + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. + */ + z: number; + + /** + * The w position of this Game Object. + */ + w: number; + + /** + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. + */ + scale: number; + + /** + * The horizontal scale of this Game Object. + */ + scaleX: number; + + /** + * The vertical scale of this Game Object. + */ + scaleY: number; + + /** + * The angle of this Game Object as expressed in degrees. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. + * + * If you prefer to work in radians, see the `rotation` property instead. + */ + angle: number; + + /** + * The angle of this Game Object in radians. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. + */ + rotation: number; + + /** + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. + */ + setPosition(x?: number, y?: number, z?: number, w?: number): this; + + /** + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + */ + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + + /** + * Sets the position of this Game Object to be a random position within the confines of + * the given area. + * + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. + */ + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + + /** + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. + */ + setRotation(radians?: number): this; + + /** + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. + */ + setAngle(degrees?: number): this; + + /** + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + */ + setScale(x?: number, y?: number): this; + + /** + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. + */ + setX(value?: number): this; + + /** + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. + */ + setY(value?: number): this; + + /** + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. + */ + setZ(value?: number): this; + + /** + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. + */ + setW(value?: number): this; + + /** + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. + */ + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. + */ + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. + * + * The returned Vector2 contains the translated point in its properties. + * + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. + */ + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + + /** + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. + */ + getParentRotation(): number; + + /** + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + */ + visible: boolean; + + /** + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. + */ + setVisible(value: boolean): this; + + } + + namespace Events { + /** + * The Game Object Added to Scene Event. + * + * This event is dispatched when a Game Object is added to a Scene. + * + * Listen for it on a Game Object instance using `GameObject.on('addedtoscene', listener)`. + */ + const ADDED_TO_SCENE: string; + + /** + * The Game Object Destroy Event. + * + * This event is dispatched when a Game Object instance is being destroyed. + * + * Listen for it on a Game Object instance using `GameObject.on('destroy', listener)`. + */ + const DESTROY: string; + + /** + * The Game Object Removed from Scene Event. + * + * This event is dispatched when a Game Object is removed from a Scene. + * + * Listen for it on a Game Object instance using `GameObject.on('removedfromscene', listener)`. + */ + const REMOVED_FROM_SCENE: string; + + /** + * The Video Game Object Complete Event. + * + * This event is dispatched when a Video finishes playback by reaching the end of its duration. It + * is also dispatched if a video marker sequence is being played and reaches the end. + * + * Note that not all videos can fire this event. Live streams, for example, have no fixed duration, + * so never technically 'complete'. + * + * If a video is stopped from playback, via the `Video.stop` method, it will emit the + * `VIDEO_STOP` event instead of this one. + * + * Listen for it from a Video Game Object instance using `Video.on('complete', listener)`. + */ + const VIDEO_COMPLETE: string; + + /** + * The Video Game Object Created Event. + * + * This event is dispatched when the texture for a Video has been created. This happens + * when enough of the video source has been loaded that the browser is able to render a + * frame from it. + * + * Listen for it from a Video Game Object instance using `Video.on('created', listener)`. + */ + const VIDEO_CREATED: string; + + /** + * The Video Game Object Error Event. + * + * This event is dispatched when a Video tries to play a source that does not exist, or is the wrong file type. + * + * Listen for it from a Video Game Object instance using `Video.on('error', listener)`. + */ + const VIDEO_ERROR: string; + + /** + * The Video Game Object Locked Event. + * + * This event is dispatched when a Video was attempted to be played, but the browser prevented it + * from doing so due to the Media Engagement Interaction policy. + * + * If you get this event you will need to wait for the user to interact with the browser before + * the video will play. This is a browser security measure to prevent autoplaying videos with + * audio. An interaction includes a mouse click, a touch, or a key press. + * + * Listen for it from a Video Game Object instance using `Video.on('locked', listener)`. + */ + const VIDEO_LOCKED: string; + + /** + * The Video Game Object Loop Event. + * + * This event is dispatched when a Video that is currently playing has looped. This only + * happens if the `loop` parameter was specified, or the `setLoop` method was called, + * and if the video has a fixed duration. Video streams, for example, cannot loop, as + * they have no duration. + * + * Looping is based on the result of the Video `timeupdate` event. This event is not + * frame-accurate, due to the way browsers work, so please do not rely on this loop + * event to be time or frame precise. + * + * Listen for it from a Video Game Object instance using `Video.on('loop', listener)`. + */ + const VIDEO_LOOP: string; + + /** + * The Video Game Object Playing Event. + * + * The playing event is fired after playback is first started, + * and whenever it is restarted. For example it is fired when playback + * resumes after having been paused or delayed due to lack of data. + * + * Listen for it from a Video Game Object instance using `Video.on('playing', listener)`. + */ + const VIDEO_PLAYING: string; + + /** + * The Video Game Object Play Event. + * + * This event is dispatched when a Video begins playback. For videos that do not require + * interaction unlocking, this is usually as soon as the `Video.play` method is called. + * However, for videos that require unlocking, it is fired once playback begins after + * they've been unlocked. + * + * Listen for it from a Video Game Object instance using `Video.on('play', listener)`. + */ + const VIDEO_PLAY: string; + + /** + * The Video Game Object Seeked Event. + * + * This event is dispatched when a Video completes seeking to a new point in its timeline. + * + * Listen for it from a Video Game Object instance using `Video.on('seeked', listener)`. + */ + const VIDEO_SEEKED: string; + + /** + * The Video Game Object Seeking Event. + * + * This event is dispatched when a Video _begins_ seeking to a new point in its timeline. + * When the seek is complete, it will dispatch the `VIDEO_SEEKED` event to conclude. + * + * Listen for it from a Video Game Object instance using `Video.on('seeking', listener)`. + */ + const VIDEO_SEEKING: string; + + /** + * The Video Game Object Stalled Event. + * + * This event is dispatched by a Video Game Object when the video playback stalls. + * + * This can happen if the video is buffering. + * + * If will fire for any of the following native DOM events: + * + * `stalled` + * `suspend` + * `waiting` + * + * Listen for it from a Video Game Object instance using `Video.on('stalled', listener)`. + * + * Note that being stalled isn't always a negative thing. A video can be stalled if it + * has downloaded enough data in to its buffer to not need to download any more until + * the current batch of frames have rendered. + */ + const VIDEO_STALLED: string; + + /** + * The Video Game Object Stopped Event. + * + * This event is dispatched when a Video is stopped from playback via a call to the `Video.stop` method, + * either directly via game code, or indirectly as the result of changing a video source or destroying it. + * + * Listen for it from a Video Game Object instance using `Video.on('stop', listener)`. + */ + const VIDEO_STOP: string; + + /** + * The Video Game Object Texture Ready Event. + * + * This event is dispatched by a Video Game Object when it has finished creating its texture. + * + * This happens when the video has finished loading enough data for its first frame. + * + * If you wish to use the Video texture elsewhere in your game, such as as a Sprite texture, + * then you should listen for this event first, before creating the Sprites that use it. + * + * Listen for it from a Video Game Object instance using `Video.on('textureready', listener)`. + */ + const VIDEO_TEXTURE: string; + + /** + * The Video Game Object Unlocked Event. + * + * This event is dispatched when a Video that was prevented from playback due to the browsers + * Media Engagement Interaction policy, is unlocked by a user gesture. + * + * Listen for it from a Video Game Object instance using `Video.on('unlocked', listener)`. + */ + const VIDEO_UNLOCKED: string; + + /** + * The Video Game Object Unsupported Event. + * + * This event is dispatched by a Video Game Object if the media source + * (which may be specified as a MediaStream, MediaSource, Blob, or File, + * for example) doesn't represent a supported media format. + * + * Listen for it from a Video Game Object instance using `Video.on('unsupported', listener)`. + */ + const VIDEO_UNSUPPORTED: string; + + } + + /** + * 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 in a 'clean' state, ready for you to bind your own shaders, + * or draw to it, whatever you wish to do. This should all take place in the `render` method. + * The correct way to deploy an Extern object is to create a class that extends it, then + * override the `render` (and optionally `preUpdate`) methods and pass off control to your + * 3rd party libraries or custom WebGL code there. + * + * 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 implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + /** + * + * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. + */ + constructor(scene: Phaser.Scene); + + /** + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). + */ + clearAlpha(): this; + + /** + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * + * If your game is running under WebGL you can optionally specify four different alpha values, each of which + * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. + * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. + * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. + * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. + * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. + */ + setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + + /** + * The alpha value of the Game Object. + * + * This is a global value, impacting the entire Game Object, not just a region of it. + */ + alpha: number; + + /** + * The alpha value starting from the top-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaTopLeft: number; + + /** + * The alpha value starting from the top-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaTopRight: number; + + /** + * The alpha value starting from the bottom-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaBottomLeft: number; + + /** + * The alpha value starting from the bottom-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaBottomRight: number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. + */ + blendMode: Phaser.BlendModes | string | number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * @param value The BlendMode value. Either a string, a CONST or a number. + */ + setBlendMode(value: string | Phaser.BlendModes | number): this; + + /** + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + */ + depth: number; + + /** + * The depth of this Game Object within the Scene. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. + */ + setDepth(value: number): this; + + /** + * The horizontally flipped state of the Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + */ + flipX: boolean; + + /** + * The vertically flipped state of the Game Object. + * + * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + */ + flipY: boolean; + + /** + * Toggles the horizontal flipped state of this Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + */ + toggleFlipX(): this; + + /** + * Toggles the vertical flipped state of this Game Object. + */ + toggleFlipY(): this; + + /** + * Sets the horizontal flipped state of this Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlipX(value: boolean): this; + + /** + * Sets the vertical flipped state of this Game Object. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlipY(value: boolean): this; + + /** + * Sets the horizontal and vertical flipped state of this Game Object. + * + * A Game Object that is flipped will render inversed on the flipped axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. + * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlip(x: boolean, y: boolean): this; + + /** + * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. + */ + resetFlip(): this; + + /** + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originX: number; + + /** + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originY: number; + + /** + * The horizontal display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginX: number; + + /** + * The vertical display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginY: number; + + /** + * Sets the origin of this Game Object. + * + * The values are given in the range 0 to 1. + * @param x The horizontal origin value. Default 0.5. + * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. + */ + setOrigin(x?: number, y?: number): this; + + /** + * Sets the origin of this Game Object based on the Pivot values in its Frame. + */ + setOriginFromFrame(): this; + + /** + * Sets the display origin of this Game Object. + * The difference between this and setting the origin is that you can use pixel values for setting the display origin. + * @param x The horizontal display origin value. Default 0. + * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + */ + setDisplayOrigin(x?: number, y?: number): this; + + /** + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. + */ + updateDisplayOrigin(): this; + + /** + * The horizontal scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorX: number; + + /** + * The vertical scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorY: number; + + /** + * Sets the scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. + */ + setScrollFactor(x: number, y?: number): this; + /** - * Provides methods used for getting and setting the texture of a Game Object. + * The native (un-scaled) width of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. */ - interface Texture { - /** - * The Texture this Game Object is using to render with. - */ - texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; - /** - * The Texture Frame this Game Object is using to render with. - */ - frame: Phaser.Textures.Frame; - /** - * Sets the texture and frame this Game Object will use to render with. - * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. - * @param frame The name or index of the frame within the Texture. - */ - setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; - /** - * Sets the frame this Game Object will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. - * - * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. - * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. - * @param updateSize Should this call adjust the size of the Game Object? Default true. - * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. - */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; - } + width: number; /** - * Provides methods used for getting and setting the texture of a Game Object. + * The native (un-scaled) height of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. */ - interface TextureCrop { - /** - * The Texture this Game Object is using to render with. - */ - texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; - /** - * The Texture Frame this Game Object is using to render with. - */ - frame: Phaser.Textures.Frame; - /** - * A boolean flag indicating if this Game Object is being cropped or not. - * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. - * Equally, calling `setCrop` with no arguments will reset the crop and disable it. - */ - isCropped: boolean; - /** - * Applies a crop to a texture based Game Object, such as a Sprite or Image. - * - * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. - * - * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just - * changes what is shown when rendered. - * - * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. - * - * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left - * half of it, you could call `setCrop(0, 0, 400, 600)`. - * - * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop - * an area of 200x100 when applied to a Game Object that had a scale factor of 2. - * - * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. - * - * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. - * - * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow - * the renderer to skip several internal calculations. - * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. - * @param y The y coordinate to start the crop from. - * @param width The width of the crop rectangle in pixels. - * @param height The height of the crop rectangle in pixels. - */ - setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; - /** - * Sets the texture and frame this Game Object will use to render with. - * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * @param key The key of the texture to be used, as stored in the Texture Manager. - * @param frame The name or index of the frame within the Texture. - */ - setTexture(key: string, frame?: string | number): this; - /** - * Sets the frame this Game Object will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. - * - * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. - * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. - * @param updateSize Should this call adjust the size of the Game Object? Default true. - * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. - */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; - } + height: number; /** - * Provides methods used for setting the tint of a Game Object. - * Should be applied as a mixin and not used directly. + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. */ - interface Tint { - /** - * The tint value being applied to the top-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintTopLeft: number; - /** - * The tint value being applied to the top-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintTopRight: number; - /** - * The tint value being applied to the bottom-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintBottomLeft: number; - /** - * The tint value being applied to the bottom-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintBottomRight: number; - /** - * The tint fill mode. - * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. - */ - tintFill: boolean; - /** - * Clears all tint values associated with this Game Object. - * - * Immediately sets the color values back to 0xffffff and the tint type to 'additive', - * which results in no visible change to the texture. - */ - clearTint(): this; - /** - * Sets an additive tint on this Game Object. - * - * The tint works by taking the pixel color values from the Game Objects texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole Game Object will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. - * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. - */ - setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - /** - * Sets a fill-based tint on this Game Object. - * - * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture - * with those in the tint. You can use this for effects such as making a player flash 'white' - * if hit by something. You can provide either one color value, in which case the whole - * Game Object will be rendered in that color. Or you can provide a color per corner. The colors - * are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. - * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. - */ - setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - /** - * The tint value being applied to the whole of the Game Object. - * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. - */ - tint: number; - /** - * Does this Game Object have a tint applied? - * - * It checks to see if the 4 tint properties are set to the value 0xffffff - * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. - */ - readonly isTinted: boolean; - } + displayWidth: number; + + /** + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayHeight: number; + + /** + * Sets the size of this Game Object to be that of the given Frame. + * + * This will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or call the + * `setDisplaySize` method, which is the same thing as changing the scale but allows you + * to do so by giving pixel values. + * + * If you have enabled this Game Object for input, changing the size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * @param frame The frame to base the size of this Game Object on. + */ + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; + + /** + * Sets the internal size of this Game Object, as used for frame or physics body creation. + * + * This will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or call the + * `setDisplaySize` method, which is the same thing as changing the scale but allows you + * to do so by giving pixel values. + * + * If you have enabled this Game Object for input, changing the size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setSize(width: number, height: number): this; + + /** + * Sets the display size of this Game Object. + * + * Calling this will adjust the scale. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setDisplaySize(width: number, height: number): this; + + /** + * The Texture this Game Object is using to render with. + */ + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + + /** + * The Texture Frame this Game Object is using to render with. + */ + frame: Phaser.Textures.Frame; + + /** + * Sets the texture and frame this Game Object will use to render with. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. + * @param frame The name or index of the frame within the Texture. + */ + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; + + /** + * Sets the frame this Game Object will use to render with. + * + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. + * + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. + * + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. + */ + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; + + /** + * The tint value being applied to the top-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintTopLeft: number; + + /** + * The tint value being applied to the top-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintTopRight: number; + + /** + * The tint value being applied to the bottom-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomLeft: number; + + /** + * The tint value being applied to the bottom-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomRight: number; + + /** + * The tint fill mode. + * + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + */ + tintFill: boolean; + + /** + * Clears all tint values associated with this Game Object. + * + * Immediately sets the color values back to 0xffffff and the tint type to 'additive', + * which results in no visible change to the texture. + */ + clearTint(): this; + + /** + * Sets an additive tint on this Game Object. + * + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole Game Object will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. + * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + */ + setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + + /** + * Sets a fill-based tint on this Game Object. + * + * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture + * with those in the tint. You can use this for effects such as making a player flash 'white' + * if hit by something. You can provide either one color value, in which case the whole + * Game Object will be rendered in that color. Or you can provide a color per corner. The colors + * are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. + * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + */ + setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + + /** + * The tint value being applied to the whole of the Game Object. + * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. + */ + tint: number; + + /** + * Does this Game Object have a tint applied? + * + * It checks to see if the 4 tint properties are set to the value 0xffffff + * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. + */ + readonly isTinted: boolean; + + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + + /** + * The x position of this Game Object. + */ + x: number; + + /** + * The y position of this Game Object. + */ + y: number; + + /** + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. + */ + z: number; + + /** + * The w position of this Game Object. + */ + w: number; + + /** + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. + */ + scale: number; + + /** + * The horizontal scale of this Game Object. + */ + scaleX: number; + + /** + * The vertical scale of this Game Object. + */ + scaleY: number; + + /** + * The angle of this Game Object as expressed in degrees. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. + * + * If you prefer to work in radians, see the `rotation` property instead. + */ + angle: number; + + /** + * The angle of this Game Object in radians. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. + */ + rotation: number; + + /** + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. + */ + setPosition(x?: number, y?: number, z?: number, w?: number): this; + + /** + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + */ + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + + /** + * Sets the position of this Game Object to be a random position within the confines of + * the given area. + * + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. + */ + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + + /** + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. + */ + setRotation(radians?: number): this; + + /** + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. + */ + setAngle(degrees?: number): this; + + /** + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + */ + setScale(x?: number, y?: number): this; + + /** + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. + */ + setX(value?: number): this; /** - * Build a JSON representation of the given Game Object. + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. + */ + setY(value?: number): this; + + /** + * Sets the z position of this Game Object. * - * This is typically extended further by Game Object specific implementations. + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. */ - interface ToJSON { - } + setZ(value?: number): this; /** - * Provides methods used for getting and setting the position, scale and rotation of a Game Object. + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. */ - interface Transform { - /** - * The x position of this Game Object. - */ - x: number; - /** - * The y position of this Game Object. - */ - y: number; - /** - * The z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#depth} instead. - */ - z: number; - /** - * The w position of this Game Object. - */ - w: number; - /** - * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object - * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. - * - * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this - * isn't the case, use the `scaleX` or `scaleY` properties instead. - */ - scale: number; - /** - * The horizontal scale of this Game Object. - */ - scaleX: number; - /** - * The vertical scale of this Game Object. - */ - scaleY: number; - /** - * The angle of this Game Object as expressed in degrees. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left - * and -90 is up. - * - * If you prefer to work in radians, see the `rotation` property instead. - */ - angle: number; - /** - * The angle of this Game Object in radians. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left - * and -PI/2 is up. - * - * If you prefer to work in degrees, see the `angle` property instead. - */ - rotation: number; - /** - * Sets the position of this Game Object. - * @param x The x position of this Game Object. Default 0. - * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. - * @param z The z position of this Game Object. Default 0. - * @param w The w position of this Game Object. Default 0. - */ - setPosition(x?: number, y?: number, z?: number, w?: number): this; - /** - * Copies an object's coordinates to this Game Object's position. - * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. - */ - copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; - /** - * Sets the position of this Game Object to be a random position within the confines of - * the given area. - * - * If no area is specified a random position between 0 x 0 and the game width x height is used instead. - * - * The position does not factor in the size of this Game Object, meaning that only the origin is - * guaranteed to be within the area. - * @param x The x position of the top-left of the random area. Default 0. - * @param y The y position of the top-left of the random area. Default 0. - * @param width The width of the random area. - * @param height The height of the random area. - */ - setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; - /** - * Sets the rotation of this Game Object. - * @param radians The rotation of this Game Object, in radians. Default 0. - */ - setRotation(radians?: number): this; - /** - * Sets the angle of this Game Object. - * @param degrees The rotation of this Game Object, in degrees. Default 0. - */ - setAngle(degrees?: number): this; - /** - * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. - * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. - */ - setScale(x: number, y?: number): this; - /** - * Sets the x position of this Game Object. - * @param value The x position of this Game Object. Default 0. - */ - setX(value?: number): this; - /** - * Sets the y position of this Game Object. - * @param value The y position of this Game Object. Default 0. - */ - setY(value?: number): this; - /** - * Sets the z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. - * @param value The z position of this Game Object. Default 0. - */ - setZ(value?: number): this; - /** - * Sets the w position of this Game Object. - * @param value The w position of this Game Object. Default 0. - */ - setW(value?: number): this; - /** - * Gets the local transform matrix for this Game Object. - * @param tempMatrix The matrix to populate with the values from this Game Object. - */ - getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; - /** - * Gets the world transform matrix for this Game Object, factoring in any parent Containers. - * @param tempMatrix The matrix to populate with the values from this Game Object. - * @param parentMatrix A temporary matrix to hold parent values during the calculations. - */ - getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; - /** - * Takes the given `x` and `y` coordinates and converts them into local space for this - * Game Object, taking into account parent and local transforms, and the Display Origin. - * - * The returned Vector2 contains the translated point in its properties. - * - * A Camera needs to be provided in order to handle modified scroll factors. If no - * camera is specified, it will use the `main` camera from the Scene to which this - * Game Object belongs. - * @param x The x position to translate. - * @param y The y position to translate. - * @param point A Vector2, or point-like object, to store the results in. - * @param camera The Camera which is being tested against. If not given will use the Scene default camera. - */ - getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; - /** - * Gets the sum total rotation of all of this Game Objects parent Containers. - * - * The returned value is in radians and will be zero if this Game Object has no parent container. - */ - getParentRotation(): number; - } + setW(value?: number): this; /** - * A Matrix used for display transformations for rendering. + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. + */ + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. + */ + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + + /** + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. * - * It is represented like so: + * The returned Vector2 contains the translated point in its properties. * - * ``` - * | a | c | tx | - * | b | d | ty | - * | 0 | 0 | 1 | - * ``` + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. */ - class TransformMatrix { - /** - * - * @param a The Scale X value. Default 1. - * @param b The Skew Y value. Default 0. - * @param c The Skew X value. Default 0. - * @param d The Scale Y value. Default 1. - * @param tx The Translate X value. Default 0. - * @param ty The Translate Y value. Default 0. - */ - constructor(a?: number, b?: number, c?: number, d?: number, tx?: number, ty?: number); + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; - /** - * The matrix values. - */ - matrix: Float32Array; + /** + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. + */ + getParentRotation(): number; - /** - * The decomposed matrix. - */ - decomposedMatrix: object; + /** + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + */ + visible: boolean; - /** - * The Scale X value. - */ - a: number; + /** + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. + */ + setVisible(value: boolean): this; - /** - * The Skew Y value. - */ - b: number; + } - /** - * The Skew X value. - */ - c: number; + /** + * The base class that all Game Objects extend. + * You don't create GameObjects directly and they cannot be added to the display list. + * Instead, use them as the base for your own custom classes. + */ + class GameObject extends Phaser.Events.EventEmitter { + /** + * + * @param scene The Scene to which this Game Object belongs. + * @param type A textual representation of the type of Game Object, i.e. `sprite`. + */ + constructor(scene: Phaser.Scene, type: string); - /** - * The Scale Y value. - */ - d: number; + /** + * A reference to the Scene to which this Game Object belongs. + * + * Game Objects can only belong to one Scene. + * + * You should consider this property as being read-only. You cannot move a + * Game Object to another Scene by simply changing it. + */ + scene: Phaser.Scene; - /** - * The Translate X value. - */ - e: number; + /** + * Holds a reference to the Display List that contains this Game Object. + * + * This is set automatically when this Game Object is added to a Scene or Layer. + * + * You should treat this property as being read-only. + */ + displayList: Phaser.GameObjects.DisplayList | Phaser.GameObjects.Layer; - /** - * The Translate Y value. - */ - f: number; + /** + * A textual representation of this Game Object, i.e. `sprite`. + * Used internally by Phaser but is available for your own custom classes to populate. + */ + type: string; - /** - * The Translate X value. - */ - tx: number; + /** + * The current state of this Game Object. + * + * Phaser itself will never modify this value, although plugins may do so. + * + * Use this property to track the state of a Game Object during its lifetime. For example, it could change from + * a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant + * in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons. + * If you need to store complex data about your Game Object, look at using the Data Component instead. + */ + state: number | string; - /** - * The Translate Y value. - */ - ty: number; + /** + * The parent Container of this Game Object, if it has one. + */ + parentContainer: Phaser.GameObjects.Container; - /** - * The rotation of the Matrix. Value is in radians. - */ - readonly rotation: number; + /** + * The name of this Game Object. + * Empty by default and never populated by Phaser, this is left for developers to use. + */ + name: string; - /** - * The rotation of the Matrix, normalized to be within the Phaser right-handed - * clockwise rotation space. Value is in radians. - */ - readonly rotationNormalized: number; + /** + * The active state of this Game Object. + * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it. + * An active object is one which is having its logic and internal systems updated. + */ + active: boolean; - /** - * The decomposed horizontal scale of the Matrix. This value is always positive. - */ - readonly scaleX: number; + /** + * The Tab Index of the Game Object. + * Reserved for future use by plugins and the Input Manager. + */ + tabIndex: number; - /** - * The decomposed vertical scale of the Matrix. This value is always positive. - */ - readonly scaleY: number; + /** + * A Data Manager. + * It allows you to store, query and get key/value paired information specific to this Game Object. + * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`. + */ + data: Phaser.Data.DataManager; - /** - * Reset the Matrix to an identity matrix. - */ - loadIdentity(): this; + /** + * 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. + */ + renderFlags: number; - /** - * Translate the Matrix. - * @param x The horizontal translation value. - * @param y The vertical translation value. - */ - translate(x: number, y: number): this; + /** + * 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: + */ + cameraFilter: number; - /** - * Scale the Matrix. - * @param x The horizontal scale value. - * @param y The vertical scale value. - */ - scale(x: number, y: number): this; + /** + * If this Game Object is enabled for input then this property will contain an InteractiveObject instance. + * Not usually set directly. Instead call `GameObject.setInteractive()`. + */ + input: Phaser.Types.Input.InteractiveObject | null; - /** - * Rotate the Matrix. - * @param angle The angle of rotation in radians. - */ - rotate(angle: number): this; + /** + * If this Game Object is enabled for Arcade or Matter Physics then this property will contain a reference to a Physics Body. + */ + body: Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | MatterJS.BodyType | null; - /** - * Multiply this Matrix by the given Matrix. - * - * If an `out` Matrix is given then the results will be stored in it. - * If it is not given, this matrix will be updated in place instead. - * Use an `out` Matrix if you do not wish to mutate this matrix. - * @param rhs The Matrix to multiply by. - * @param out An optional Matrix to store the results in. - */ - multiply(rhs: Phaser.GameObjects.Components.TransformMatrix, out?: Phaser.GameObjects.Components.TransformMatrix): this | Phaser.GameObjects.Components.TransformMatrix; + /** + * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`. + * This includes calls that may come from a Group, Container or the Scene itself. + * While it allows you to persist a Game Object across Scenes, please understand you are entirely + * responsible for managing references to and from this Game Object. + */ + ignoreDestroy: boolean; - /** - * Multiply this Matrix by the matrix given, including the offset. - * - * The offsetX is added to the tx value: `offsetX * a + offsetY * c + tx`. - * The offsetY is added to the ty value: `offsetY * b + offsetY * d + ty`. - * @param src The source Matrix to copy from. - * @param offsetX Horizontal offset to factor in to the multiplication. - * @param offsetY Vertical offset to factor in to the multiplication. - */ - multiplyWithOffset(src: Phaser.GameObjects.Components.TransformMatrix, offsetX: number, offsetY: number): this; + /** + * Sets the `active` property of this Game Object and returns this Game Object for further chaining. + * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList. + * @param value True if this Game Object should be set as active, false if not. + */ + setActive(value: boolean): this; - /** - * Transform the Matrix. - * @param a The Scale X value. - * @param b The Shear Y value. - * @param c The Shear X value. - * @param d The Scale Y value. - * @param tx The Translate X value. - * @param ty The Translate Y value. - */ - transform(a: number, b: number, c: number, d: number, tx: number, ty: number): this; + /** + * Sets the `name` property of this Game Object and returns this Game Object for further chaining. + * The `name` property is not populated by Phaser and is presented for your own use. + * @param value The name to be given to this Game Object. + */ + setName(value: string): this; - /** - * Transform a point using this Matrix. - * @param x The x coordinate of the point to transform. - * @param y The y coordinate of the point to transform. - * @param point The Point object to store the transformed coordinates. - */ - transformPoint(x: number, y: number, point: Phaser.Geom.Point | Phaser.Math.Vector2 | object): Phaser.Geom.Point | Phaser.Math.Vector2 | object; + /** + * Sets the current state of this Game Object. + * + * Phaser itself will never modify the State of a Game Object, although plugins may do so. + * + * For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'. + * The state value should typically be an integer (ideally mapped to a constant + * in your game code), but could also be a string. It is recommended to keep it light and simple. + * If you need to store complex data about your Game Object, look at using the Data Component instead. + * @param value The state of the Game Object. + */ + setState(value: number | string): this; + + /** + * Adds a Data Manager component to this Game Object. + */ + setDataEnabled(): this; + + /** + * Allows you to store a key value pair within this Game Objects Data Manager. + * + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. + * + * If the key doesn't already exist in the Data Manager then it is created. + * + * ```javascript + * sprite.setData('name', 'Red Gem Stone'); + * ``` + * + * You can also pass in an object of key value pairs as the first argument: + * + * ```javascript + * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); + * ``` + * + * To get a value back again you can call `getData`: + * + * ```javascript + * sprite.getData('gold'); + * ``` + * + * Or you can access the value directly via the `values` property, where it works like any other variable: + * + * ```javascript + * sprite.data.values.gold += 50; + * ``` + * + * When the value is first set, a `setdata` event is emitted from this Game Object. + * + * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. + * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. + * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. + * + * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. + * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. + * @param key The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. + * @param data The value to set for the given key. If an object is provided as the key this argument is ignored. + */ + setData(key: (string|T), data?: any): this; - /** - * Invert the Matrix. - */ - invert(): this; + /** + * Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0. + * + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. + * + * If the key doesn't already exist in the Data Manager then it is created. + * + * When the value is first set, a `setdata` event is emitted from this Game Object. + * @param key The key to increase the value for. + * @param data The value to increase for the given key. + */ + incData(key: (string|T), data?: any): this; - /** - * Set the values of this Matrix to copy those of the matrix given. - * @param src The source Matrix to copy from. - */ - copyFrom(src: Phaser.GameObjects.Components.TransformMatrix): this; + /** + * Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false. + * + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. + * + * If the key doesn't already exist in the Data Manager then it is created. + * + * When the value is first set, a `setdata` event is emitted from this Game Object. + * @param key The key to toggle the value for. + */ + toggleData(key: (string|T)): this; - /** - * Set the values of this Matrix to copy those of the array given. - * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f. - * @param src The array of values to set into this matrix. - */ - copyFromArray(src: any[]): this; + /** + * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist. + * + * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: + * + * ```javascript + * sprite.getData('gold'); + * ``` + * + * Or access the value directly: + * + * ```javascript + * sprite.data.values.gold; + * ``` + * + * You can also pass in an array of keys, in which case an array of values will be returned: + * + * ```javascript + * sprite.getData([ 'gold', 'armor', 'health' ]); + * ``` + * + * This approach is useful for destructuring arrays in ES6. + * @param key The key of the value to retrieve, or an array of keys. + */ + getData(key: string | string[]): any; - /** - * Copy the values from this Matrix to the given Canvas Rendering Context. - * This will use the Context.transform method. - * @param ctx The Canvas Rendering Context to copy the matrix values to. - */ - copyToContext(ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; + /** + * Pass this Game Object to the Input Manager to enable it for Input. + * + * Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area + * for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced + * input detection. + * + * If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If + * this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific + * shape for it to use. + * + * You can also provide an Input Configuration Object as the only argument to this method. + * @param hitArea Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not given it will try to create a Rectangle based on the texture frame. + * @param callback The callback that determines if the pointer is within the Hit Area shape or not. If you provide a shape you must also provide a callback. + * @param dropZone Should this Game Object be treated as a drop zone target? Default false. + */ + setInteractive(hitArea?: Phaser.Types.Input.InputConfiguration | any, callback?: Phaser.Types.Input.HitAreaCallback, dropZone?: boolean): this; - /** - * Copy the values from this Matrix to the given Canvas Rendering Context. - * This will use the Context.setTransform method. - * @param ctx The Canvas Rendering Context to copy the matrix values to. - */ - setToContext(ctx: CanvasRenderingContext2D): CanvasRenderingContext2D; + /** + * If this Game Object has previously been enabled for input, this will disable it. + * + * An object that is disabled for input stops processing or being considered for + * input events, but can be turned back on again at any time by simply calling + * `setInteractive()` with no arguments provided. + * + * If want to completely remove interaction from this Game Object then use `removeInteractive` instead. + */ + disableInteractive(): this; - /** - * Copy the values in this Matrix to the array given. - * - * Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f. - * @param out The array to copy the matrix values in to. - */ - copyToArray(out?: any[]): any[]; + /** + * If this Game Object has previously been enabled for input, this will queue it + * for removal, causing it to no longer be interactive. The removal happens on + * the next game step, it is not immediate. + * + * The Interactive Object that was assigned to this Game Object will be destroyed, + * removed from the Input Manager and cleared from this Game Object. + * + * If you wish to re-enable this Game Object at a later date you will need to + * re-create its InteractiveObject by calling `setInteractive` again. + * + * If you wish to only temporarily stop an object from receiving input then use + * `disableInteractive` instead, as that toggles the interactive state, where-as + * this erases it completely. + * + * If you wish to resize a hit area, don't remove and then set it as being + * interactive. Instead, access the hitarea object directly and resize the shape + * being used. I.e.: `sprite.input.hitArea.setSize(width, height)` (assuming the + * shape is a Rectangle, which it is by default.) + */ + removeInteractive(): this; - /** - * Set the values of this Matrix. - * @param a The Scale X value. - * @param b The Shear Y value. - * @param c The Shear X value. - * @param d The Scale Y value. - * @param tx The Translate X value. - * @param ty The Translate Y value. - */ - setTransform(a: number, b: number, c: number, d: number, tx: number, ty: number): this; + /** + * This callback is invoked when this Game Object is added to a Scene. + * + * Can be overriden by custom Game Objects, but be aware of some Game Objects that + * will use this, such as Sprites, to add themselves into the Update List. + * + * You can also listen for the `ADDED_TO_SCENE` event from this Game Object. + */ + addedToScene(): void; - /** - * Decompose this Matrix into its translation, scale and rotation values using QR decomposition. - * - * The result must be applied in the following order to reproduce the current matrix: - * - * translate -> rotate -> scale - */ - decomposeMatrix(): object; + /** + * This callback is invoked when this Game Object is removed from a Scene. + * + * Can be overriden by custom Game Objects, but be aware of some Game Objects that + * will use this, such as Sprites, to removed themselves from the Update List. + * + * You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object. + */ + removedFromScene(): void; - /** - * Apply the identity, translate, rotate and scale operations on the Matrix. - * @param x The horizontal translation. - * @param y The vertical translation. - * @param rotation The angle of rotation in radians. - * @param scaleX The horizontal scale. - * @param scaleY The vertical scale. - */ - applyITRS(x: number, y: number, rotation: number, scaleX: number, scaleY: number): this; + /** + * To be overridden by custom GameObjects. Allows base objects to be used in a Pool. + * @param args args + */ + update(...args: any[]): void; - /** - * Takes the `x` and `y` values and returns a new position in the `output` vector that is the inverse of - * the current matrix with its transformation applied. - * - * Can be used to translate points from world to local space. - * @param x The x position to translate. - * @param y The y position to translate. - * @param output A Vector2, or point-like object, to store the results in. - */ - applyInverse(x: number, y: number, output?: Phaser.Math.Vector2): Phaser.Math.Vector2; + /** + * Returns a JSON representation of the Game Object. + */ + toJSON(): Phaser.Types.GameObjects.JSONGameObject; - /** - * Returns the X component of this matrix multiplied by the given values. - * This is the same as `x * a + y * c + e`. - * @param x The x value. - * @param y The y value. - */ - getX(x: number, y: number): number; + /** + * 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. + * @param camera The Camera to check against this Game Object. + */ + willRender(camera: Phaser.Cameras.Scene2D.Camera): boolean; - /** - * Returns the Y component of this matrix multiplied by the given values. - * This is the same as `x * b + y * d + f`. - * @param x The x value. - * @param y The y value. - */ - getY(x: number, y: number): number; + /** + * Returns an array containing the display list index of either this Game Object, or if it has one, + * its parent Container. It then iterates up through all of the parent containers until it hits the + * root of the display list (which is index 0 in the returned array). + * + * Used internally by the InputPlugin but also useful if you wish to find out the display depth of + * this Game Object and all of its ancestors. + */ + getIndexList(): number[]; - /** - * Returns the X component of this matrix multiplied by the given values. - * - * This is the same as `x * a + y * c + e`, optionally passing via `Math.round`. - * @param x The x value. - * @param y The y value. - * @param round Math.round the resulting value? Default false. - */ - getXRound(x: number, y: number, round?: boolean): number; + /** + * Adds this Game Object to the given Display List. + * + * If no Display List is specified, it will default to the Display List owned by the Scene to which + * this Game Object belongs. + * + * A Game Object can only exist on one Display List at any given time, but may move freely between them. + * + * If this Game Object is already on another Display List when this method is called, it will first + * be removed from it, before being added to the new list. + * + * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. + * + * If a Game Object isn't on any display list, it will not be rendered. If you just wish to temporarly + * disable it from rendering, consider using the `setVisible` method, instead. + * @param displayList The Display List to add to. Defaults to the Scene Display List. + */ + addToDisplayList(displayList?: Phaser.GameObjects.DisplayList | Phaser.GameObjects.Layer): this; - /** - * Returns the Y component of this matrix multiplied by the given values. - * - * This is the same as `x * b + y * d + f`, optionally passing via `Math.round`. - * @param x The x value. - * @param y The y value. - * @param round Math.round the resulting value? Default false. - */ - getYRound(x: number, y: number, round?: boolean): number; + /** + * Adds this Game Object to the Update List belonging to the Scene. + * + * When a Game Object is added to the Update List it will have its `preUpdate` method called + * every game frame. This method is passed two parameters: `delta` and `time`. + * + * If you wish to run your own logic within `preUpdate` then you should always call + * `super.preUpdate(delta, time)` within it, or it may fail to process required operations, + * such as Sprite animations. + */ + addToUpdateList(): this; - /** - * Returns a string that can be used in a CSS Transform call as a `matrix` property. - */ - getCSSMatrix(): string; + /** + * Removes this Game Object from the Display List it is currently on. + * + * A Game Object can only exist on one Display List at any given time, but may move freely removed + * and added back at a later stage. + * + * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. + * + * If a Game Object isn't on any Display List, it will not be rendered. If you just wish to temporarly + * disable it from rendering, consider using the `setVisible` method, instead. + */ + removeFromDisplayList(): this; - /** - * Destroys this Transform Matrix. - */ - destroy(): void; + /** + * Removes this Game Object from the Scene's Update List. + * + * When a Game Object is on the Update List, it will have its `preUpdate` method called + * every game frame. Calling this method will remove it from the list, preventing this. + * + * Removing a Game Object from the Update List will stop most internal functions working. + * For example, removing a Sprite from the Update List will prevent it from being able to + * run animations. + */ + removeFromUpdateList(): this; - } + /** + * Destroys this Game Object removing it from the Display List and Update List and + * severing all ties to parent resources. + * + * Also removes itself from the Input Manager and Physics Manager if previously enabled. + * + * Use this to remove a Game Object from your game if you don't ever plan to use it again. + * As long as no reference to it exists within your own code it should become free for + * garbage collection by the browser. + * + * If you just want to temporarily disable an object then look at using the + * Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected. + * @param fromScene `True` if this Game Object is being destroyed by the Scene, `false` if not. Default false. + */ + destroy(fromScene?: boolean): void; /** - * Provides methods used for setting the visibility of a Game Object. - * Should be applied as a mixin and not used directly. + * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not. */ - interface Visible { - /** - * The visible state of the Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - */ - visible: boolean; - /** - * Sets the visibility of this Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. - */ - setVisible(value: boolean): this; - } + static readonly RENDER_MASK: number; } /** - * A Container Game Object. - * - * A Container, as the name implies, can 'contain' other types of Game Object. - * When a Game Object is added to a Container, the Container becomes responsible for the rendering of it. - * By default it will be removed from the Display List and instead added to the Containers own internal list. - * - * The position of the Game Object automatically becomes relative to the position of the Container. - * - * The transform point of a Container is 0x0 (in local space) and that cannot be changed. The children you add to the - * Container should be positioned with this value in mind. I.e. you should treat 0x0 as being the center of - * the Container, and position children positively and negative around it as required. - * - * When the Container is rendered, all of its children are rendered as well, in the order in which they exist - * within the Container. Container children can be repositioned using methods such as `MoveUp`, `MoveDown` and `SendToBack`. - * - * If you modify a transform property of the Container, such as `Container.x` or `Container.rotation` then it will - * automatically influence all children as well. - * - * Containers can include other Containers for deeply nested transforms. - * - * Containers can have masks set on them and can be used as a mask too. However, Container children cannot be masked. - * The masks do not 'stack up'. Only a Container on the root of the display list will use its mask. - * - * Containers can be enabled for input. Because they do not have a texture you need to provide a shape for them - * to use as their hit area. Container children can also be enabled for input, independent of the Container. - * - * If input enabling a _child_ you should not set both the `origin` and a **negative** scale factor on the child, - * or the input area will become misaligned. - * - * Containers can be given a physics body for either Arcade Physics, Impact Physics or Matter Physics. However, - * if Container _children_ are enabled for physics you may get unexpected results, such as offset bodies, - * if the Container itself, or any of its ancestors, is positioned anywhere other than at 0 x 0. Container children - * with physics do not factor in the Container due to the excessive extra calculations needed. Please structure - * your game to work around this. + * The Game Object Creator is a Scene plugin that allows you to quickly create many common + * types of Game Objects and return them using a configuration object, rather than + * having to specify a limited set of parameters such as with the GameObjectFactory. * - * It's important to understand the impact of using Containers. They add additional processing overhead into - * every one of their children. The deeper you nest them, the more the cost escalates. This is especially true - * for input events. You also loose the ability to set the display depth of Container children in the same - * flexible manner as those not within them. In short, don't use them for the sake of it. You pay a small cost - * every time you create one, try to structure your game around avoiding that where possible. + * Game Objects made via this class are automatically added to the Scene and Update List + * unless you explicitly set the `add` property in the configuration object to `false`. */ - class Container extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.ComputedSize, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class GameObjectCreator { /** * - * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param children An optional array of Game Objects to add to this Container. + * @param scene The Scene to which this Game Object Factory belongs. */ - constructor(scene: Phaser.Scene, x?: number, y?: number, children?: Phaser.GameObjects.GameObject[]); + constructor(scene: Phaser.Scene); /** - * An array holding the children of this Container. + * Creates a new Dynamic Bitmap Text Game Object and returns it. + * + * Note: This method will only be available if the Dynamic Bitmap Text Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - list: Phaser.GameObjects.GameObject[]; + dynamicBitmapText(config: Phaser.Types.GameObjects.BitmapText.BitmapTextConfig, addToScene?: boolean): Phaser.GameObjects.DynamicBitmapText; /** - * Does this Container exclusively manage its children? + * Creates a new Bitmap Text Game Object and returns it. * - * The default is `true` which means a child added to this Container cannot - * belong in another Container, which includes the Scene display list. + * Note: This method will only be available if the Bitmap Text Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + */ + bitmapText(config: Phaser.Types.GameObjects.BitmapText.BitmapTextConfig, addToScene?: boolean): Phaser.GameObjects.BitmapText; + + /** + * Creates a new Blitter Game Object and returns it. * - * If you disable this then this Container will no longer exclusively manage its children. - * This allows you to create all kinds of interesting graphical effects, such as replicating - * Game Objects without reparenting them all over the Scene. - * However, doing so will prevent children from receiving any kind of input event or have - * their physics bodies work by default, as they're no longer a single entity on the - * display list, but are being replicated where-ever this Container is. + * Note: This method will only be available if the Blitter Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - exclusive: boolean; + blitter(config: Phaser.Types.GameObjects.Sprite.SpriteConfig, addToScene?: boolean): Phaser.GameObjects.Blitter; /** - * Containers can have an optional maximum size. If set to anything above 0 it - * will constrict the addition of new Game Objects into the Container, capping off - * the maximum limit the Container can grow in size to. + * Creates a new Container Game Object and returns it. + * + * Note: This method will only be available if the Container Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - maxSize: number; + container(config: Phaser.Types.GameObjects.Container.ContainerConfig, addToScene?: boolean): Phaser.GameObjects.Container; /** - * The cursor position. + * The Scene to which this Game Object Creator belongs. */ - position: number; + protected scene: Phaser.Scene; /** - * Internal Transform Matrix used for local space conversion. + * A reference to the Scene.Systems. */ - localTransform: Phaser.GameObjects.Components.TransformMatrix; + protected systems: Phaser.Scenes.Systems; /** - * The horizontal scroll factor of this Container. - * - * The scroll factor controls the influence of the movement of a Camera upon this Container. - * - * When a camera scrolls it will change the location at which this Container is rendered on-screen. - * It does not change the Containers actual position values. - * - * For a Container, setting this value will only update the Container itself, not its children. - * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Container. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. + * A reference to the Scene Event Emitter. */ - scrollFactorX: number; + protected events: Phaser.Events.EventEmitter; /** - * The vertical scroll factor of this Container. - * - * The scroll factor controls the influence of the movement of a Camera upon this Container. + * A reference to the Scene Display List. + */ + protected displayList: Phaser.GameObjects.DisplayList; + + /** + * A reference to the Scene Update List. + */ + protected updateList: Phaser.GameObjects.UpdateList; + + /** + * Static method called directly by the Game Object creator functions. + * With this method you can register a custom GameObject factory in the GameObjectCreator, + * providing a name (`factoryType`) and the constructor (`factoryFunction`) in order + * to be called when you invoke Phaser.Scene.make[ factoryType ] method. + * @param factoryType The key of the factory that you will use to call to Phaser.Scene.make[ factoryType ] method. + * @param factoryFunction The constructor function to be called when you invoke to the Phaser.Scene.make method. + */ + static register(factoryType: string, factoryFunction: Function): void; + + /** + * Static method called directly by the Game Object Creator functions. * - * When a camera scrolls it will change the location at which this Container is rendered on-screen. - * It does not change the Containers actual position values. + * With this method you can remove a custom Game Object Creator that has been previously + * registered in the Game Object Creator. Pass in its `factoryType` in order to remove it. + * @param factoryType The key of the factory that you want to remove from the GameObjectCreator. + */ + static remove(factoryType: string): void; + + /** + * Creates a new Graphics Game Object and returns it. * - * For a Container, setting this value will only update the Container itself, not its children. - * If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method. + * Note: This method will only be available if the Graphics Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + */ + graphics(config?: Phaser.Types.GameObjects.Graphics.Options, addToScene?: boolean): Phaser.GameObjects.Graphics; + + /** + * Creates a new Group Game Object and returns it. * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Container. + * Note: This method will only be available if the Group Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + */ + group(config: Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig): Phaser.GameObjects.Group; + + /** + * Creates a new Image Game Object and returns it. * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. + * Note: This method will only be available if the Image Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - scrollFactorY: number; + image(config: Phaser.Types.GameObjects.Sprite.SpriteConfig, addToScene?: boolean): Phaser.GameObjects.Image; /** - * Internal value to allow Containers to be used for input and physics. - * Do not change this value. It has no effect other than to break things. + * Creates a new Layer Game Object and returns it. + * + * Note: This method will only be available if the Layer Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - readonly originX: number; + layer(config: Phaser.Types.GameObjects.Sprite.SpriteConfig, addToScene?: boolean): Phaser.GameObjects.Layer; /** - * Internal value to allow Containers to be used for input and physics. - * Do not change this value. It has no effect other than to break things. + * Creates a new Mesh Game Object and returns it. + * + * Note: This method will only be available if the Mesh Game Object and WebGL support have been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - readonly originY: number; + mesh(config: Phaser.Types.GameObjects.Mesh.MeshConfig, addToScene?: boolean): Phaser.GameObjects.Mesh; /** - * Internal value to allow Containers to be used for input and physics. - * Do not change this value. It has no effect other than to break things. + * Creates a new Nine Slice Game Object and returns it. + * + * Note: This method will only be available if the Nine Slice Game Object and WebGL support have been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - readonly displayOriginX: number; + nineslice(config: Phaser.Types.GameObjects.NineSlice.NineSliceConfig, addToScene?: boolean): Phaser.GameObjects.NineSlice; /** - * Internal value to allow Containers to be used for input and physics. - * Do not change this value. It has no effect other than to break things. + * Creates a new Particle Emitter Game Object and returns it. + * + * Prior to Phaser v3.60 this function would create a `ParticleEmitterManager`. These were removed + * in v3.60 and replaced with creating a `ParticleEmitter` instance directly. Please see the + * updated function parameters and class documentation for more details. + * + * Note: This method will only be available if the Particles Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - readonly displayOriginY: number; + particles(config: Phaser.Types.GameObjects.Particles.ParticleEmitterCreatorConfig, addToScene?: boolean): Phaser.GameObjects.Particles.ParticleEmitter; /** - * Does this Container exclusively manage its children? + * Creates a new Plane Game Object and returns it. * - * The default is `true` which means a child added to this Container cannot - * belong in another Container, which includes the Scene display list. + * Note: This method will only be available if the Plane Game Object and WebGL support have been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + */ + plane(config: Phaser.Types.GameObjects.Plane.PlaneConfig, addToScene?: boolean): Phaser.GameObjects.Plane; + + /** + * Creates a new Point Light Game Object and returns it. * - * If you disable this then this Container will no longer exclusively manage its children. - * This allows you to create all kinds of interesting graphical effects, such as replicating - * Game Objects without reparenting them all over the Scene. - * However, doing so will prevent children from receiving any kind of input event or have - * their physics bodies work by default, as they're no longer a single entity on the - * display list, but are being replicated where-ever this Container is. - * @param value The exclusive state of this Container. Default true. + * Note: This method will only be available if the Point Light Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - setExclusive(value?: boolean): this; + pointlight(config: object, addToScene?: boolean): Phaser.GameObjects.PointLight; /** - * Gets the bounds of this Container. It works by iterating all children of the Container, - * getting their respective bounds, and then working out a min-max rectangle from that. - * It does not factor in if the children render or not, all are included. + * Creates a new Render Texture Game Object and returns it. * - * Some children are unable to return their bounds, such as Graphics objects, in which case - * they are skipped. + * Note: This method will only be available if the Render Texture Game Object has been built into Phaser. * - * Depending on the quantity of children in this Container it could be a really expensive call, - * so cache it and only poll it as needed. + * A Render Texture is a combination of Dynamic Texture and an Image Game Object, that uses the + * Dynamic Texture to display itself with. * - * The values are stored and returned in a Rectangle object. - * @param output A Geom.Rectangle object to store the values in. If not provided a new Rectangle will be created. + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. + * + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. + * + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - getBounds(output?: Phaser.Geom.Rectangle): Phaser.Geom.Rectangle; + renderTexture(config: Phaser.Types.GameObjects.RenderTexture.RenderTextureConfig, addToScene?: boolean): Phaser.GameObjects.RenderTexture; /** - * Takes a Point-like object, such as a Vector2, Geom.Point or object with public x and y properties, - * and transforms it into the space of this Container, then returns it in the output object. - * @param source The Source Point to be transformed. - * @param output A destination object to store the transformed point in. If none given a Vector2 will be created and returned. + * Creates a new Rope Game Object and returns it. + * + * Note: This method will only be available if the Rope Game Object and WebGL support have been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - pointToContainer(source: object | Phaser.Geom.Point | Phaser.Math.Vector2, output?: object | Phaser.Geom.Point | Phaser.Math.Vector2): object | Phaser.Geom.Point | Phaser.Math.Vector2; + rope(config: Phaser.Types.GameObjects.Rope.RopeConfig, addToScene?: boolean): Phaser.GameObjects.Rope; /** - * Returns the world transform matrix as used for Bounds checks. + * Creates a new Shader Game Object and returns it. * - * The returned matrix is temporal and shouldn't be stored. + * Note: This method will only be available if the Shader Game Object and WebGL support have been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - getBoundsTransformMatrix(): Phaser.GameObjects.Components.TransformMatrix; + shader(config: Phaser.Types.GameObjects.Shader.ShaderConfig, addToScene?: boolean): Phaser.GameObjects.Shader; /** - * Adds the given Game Object, or array of Game Objects, to this Container. + * Creates a new Sprite Game Object and returns it. * - * Each Game Object must be unique within the Container. - * @param child The Game Object, or array of Game Objects, to add to the Container. + * Note: This method will only be available if the Sprite Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - add(child: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[]): this; + sprite(config: Phaser.Types.GameObjects.Sprite.SpriteConfig, addToScene?: boolean): Phaser.GameObjects.Sprite; /** - * Adds the given Game Object, or array of Game Objects, to this Container at the specified position. - * - * Existing Game Objects in the Container are shifted up. + * Creates a new Text Game Object and returns it. * - * Each Game Object must be unique within the Container. - * @param child The Game Object, or array of Game Objects, to add to the Container. - * @param index The position to insert the Game Object/s at. Default 0. + * Note: This method will only be available if the Text Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - addAt(child: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[], index?: number): this; + text(config: Phaser.Types.GameObjects.Text.TextConfig, addToScene?: boolean): Phaser.GameObjects.Text; /** - * Returns the Game Object at the given position in this Container. - * @param index The position to get the Game Object from. + * Creates a new TileSprite Game Object and returns it. + * + * Note: This method will only be available if the TileSprite Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - getAt(index: number): Phaser.GameObjects.GameObject; + tileSprite(config: Phaser.Types.GameObjects.TileSprite.TileSpriteConfig, addToScene?: boolean): Phaser.GameObjects.TileSprite; /** - * Returns the index of the given Game Object in this Container. - * @param child The Game Object to search for in this Container. + * Creates a new Video Game Object and returns it. + * + * Note: This method will only be available if the Video Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. + * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. */ - getIndex(child: Phaser.GameObjects.GameObject): number; + video(config: Phaser.Types.GameObjects.Video.VideoConfig, addToScene?: boolean): Phaser.GameObjects.Video; /** - * Sort the contents of this Container so the items are in order based on the given property. - * For example: `sort('alpha')` would sort the elements based on the value of their `alpha` property. - * @param property The property to lexically sort by. - * @param handler Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean. + * Creates a new Zone Game Object and returns it. + * + * Note: This method will only be available if the Zone Game Object has been built into Phaser. + * @param config The configuration object this Game Object will use to create itself. */ - sort(property: string, handler?: Function): this; + zone(config: Phaser.Types.GameObjects.Zone.ZoneConfig): Phaser.GameObjects.Zone; /** - * Searches for the first instance of a child with its `name` property matching the given argument. - * Should more than one child have the same name only the first is returned. - * @param name The name to search for. + * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. + * When loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing + * from a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map + * data. For an empty map, you should specify tileWidth, tileHeight, width & height. + * @param config The config options for the Tilemap. */ - getByName(name: string): Phaser.GameObjects.GameObject; + tilemap(config?: Phaser.Types.Tilemaps.TilemapConfig): Phaser.Tilemaps.Tilemap; /** - * Returns a random Game Object from this Container. - * @param startIndex An optional start index. Default 0. - * @param length An optional length, the total number of elements (from the startIndex) to choose from. + * Creates a new Tween object and returns it. + * + * Note: This method will only be available if Tweens have been built into Phaser. + * @param config A Tween Configuration object, or a Tween or TweenChain instance. */ - getRandom(startIndex?: number, length?: number): Phaser.GameObjects.GameObject; + tween(config: Phaser.Types.Tweens.TweenBuilderConfig | Phaser.Types.Tweens.TweenChainBuilderConfig | Phaser.Tweens.Tween | Phaser.Tweens.TweenChain): Phaser.Tweens.Tween; /** - * Gets the first Game Object in this Container. + * Creates a new TweenChain object and returns it, without adding it to the Tween Manager. * - * You can also specify a property and value to search for, in which case it will return the first - * Game Object in this Container with a matching property and / or value. - * - * For example: `getFirst('visible', true)` would return the first Game Object that had its `visible` property set. + * Note: This method will only be available if Tweens have been built into Phaser. + * @param config The TweenChain configuration. + */ + tweenchain(config: Phaser.Types.Tweens.TweenBuilderConfig | object): Phaser.Tweens.TweenChain; + + } + + /** + * The Game Object Factory is a Scene plugin that allows you to quickly create many common + * types of Game Objects and have them automatically registered with the Scene. + * + * Game Objects directly register themselves with the Factory and inject their own creation + * methods into the class. + */ + class GameObjectFactory { + /** * - * You can limit the search to the `startIndex` - `endIndex` range. - * @param property The property to test on each Game Object in the Container. - * @param value The value to test the property against. Must pass a strict (`===`) comparison check. - * @param startIndex An optional start index to search from. Default 0. - * @param endIndex An optional end index to search up to (but not included) Default Container.length. + * @param scene The Scene to which this Game Object Factory belongs. */ - getFirst(property: string, value: any, startIndex?: number, endIndex?: number): Phaser.GameObjects.GameObject; + constructor(scene: Phaser.Scene); /** - * Returns all Game Objects in this Container. + * Creates a new Path Object. + * @param x The horizontal position of this Path. + * @param y The vertical position of this Path. + */ + path(x: number, y: number): Phaser.Curves.Path; + + /** + * A Bitmap Mask combines the alpha (opacity) of a masked pixel with the alpha of another pixel. + * Unlike the Geometry Mask, which is a clipping path, a Bitmap Mask behaves like an alpha mask, + * not a clipping path. It is only available when using the WebGL Renderer. * - * You can optionally specify a matching criteria using the `property` and `value` arguments. + * A Bitmap Mask can use any Game Object, or Dynamic Texture, to determine the alpha of each pixel of the masked Game Object(s). + * For any given point of a masked Game Object's texture, the pixel's alpha will be multiplied by the alpha + * of the pixel at the same position in the Bitmap Mask's Game Object. The color of the pixel from the + * Bitmap Mask doesn't matter. * - * For example: `getAll('body')` would return only Game Objects that have a body property. + * For example, if a pure blue pixel with an alpha of 0.95 is masked with a pure red pixel with an + * alpha of 0.5, the resulting pixel will be pure blue with an alpha of 0.475. Naturally, this means + * that a pixel in the mask with an alpha of 0 will hide the corresponding pixel in all masked Game Objects + * A pixel with an alpha of 1 in the masked Game Object will receive the same alpha as the + * corresponding pixel in the mask. * - * You can also specify a value to compare the property to: + * Note: You cannot combine Bitmap Masks and Blend Modes on the same Game Object. You can, however, + * combine Geometry Masks and Blend Modes together. * - * `getAll('visible', true)` would return only Game Objects that have their visible property set to `true`. + * The Bitmap Mask's location matches the location of its Game Object, not the location of the + * masked objects. Moving or transforming the underlying Game Object will change the mask + * (and affect the visibility of any masked objects), whereas moving or transforming a masked object + * will not affect the mask. * - * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects, - * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only - * the first 50 Game Objects. - * @param property The property to test on each Game Object in the Container. - * @param value If property is set then the `property` must strictly equal this value to be included in the results. - * @param startIndex An optional start index to search from. Default 0. - * @param endIndex An optional end index to search up to (but not included) Default Container.length. + * The Bitmap Mask will not render its Game Object by itself. If the Game Object is not in a + * Scene's display list, it will only be used for the mask and its full texture will not be directly + * visible. Adding the underlying Game Object to a Scene will not cause any problems - it will + * render as a normal Game Object and will also serve as a mask. + * @param maskObject The Game Object or Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - getAll(property?: string, value?: any, startIndex?: number, endIndex?: number): Phaser.GameObjects.GameObject[]; + bitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** - * Returns the total number of Game Objects in this Container that have a property - * matching the given value. + * Creates a new Dynamic Bitmap Text Game Object and adds it to the Scene. * - * For example: `count('visible', true)` would count all the elements that have their visible property set. + * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. * - * You can optionally limit the operation to the `startIndex` - `endIndex` range. - * @param property The property to check. - * @param value The value to check. - * @param startIndex An optional start index to search from. Default 0. - * @param endIndex An optional end index to search up to (but not included) Default Container.length. - */ - count(property: string, value: any, startIndex?: number, endIndex?: number): number; - - /** - * Swaps the position of two Game Objects in this Container. - * Both Game Objects must belong to this Container. - * @param child1 The first Game Object to swap. - * @param child2 The second Game Object to swap. + * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to + * match the font structure. + * + * Dynamic Bitmap Text objects are different from Static Bitmap Text in that they invoke a callback for each + * letter being rendered during the render pass. This callback allows you to manipulate the properties of + * each letter being rendered, such as its position, scale or tint, allowing you to create interesting effects + * like jiggling text, which can't be done with Static text. This means that Dynamic Text takes more processing + * time, so only use them if you require the callback ability they have. + * + * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability + * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by + * processing the font texture in an image editor, applying fills and any other effects required. + * + * To create multi-line text insert \r, \n or \r\n escape codes into the text string. + * + * To create a BitmapText data files you need a 3rd party app such as: + * + * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/ + * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner + * Littera (Web-based, free): http://kvazars.com/littera/ + * + * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of + * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: http://codebeautify.org/xmltojson + * + * Note: This method will only be available if the Dynamic Bitmap Text Game Object has been built into Phaser. + * @param x The x position of the Game Object. + * @param y The y position of the Game Object. + * @param font The key of the font to use from the BitmapFont cache. + * @param text The string, or array of strings, to be set as the content of this Bitmap Text. + * @param size The font size to set. */ - swap(child1: Phaser.GameObjects.GameObject, child2: Phaser.GameObjects.GameObject): this; + dynamicBitmapText(x: number, y: number, font: string, text?: string | string[], size?: number): Phaser.GameObjects.DynamicBitmapText; /** - * Moves a Game Object to a new position within this Container. + * Creates a new Bitmap Text Game Object and adds it to the Scene. * - * The Game Object must already be a child of this Container. + * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. * - * The Game Object is removed from its old position and inserted into the new one. - * Therefore the Container size does not change. Other children will change position accordingly. - * @param child The Game Object to move. - * @param index The new position of the Game Object in this Container. + * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to + * match the font structure. + * + * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability + * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by + * processing the font texture in an image editor, applying fills and any other effects required. + * + * To create multi-line text insert \r, \n or \r\n escape codes into the text string. + * + * To create a BitmapText data files you need a 3rd party app such as: + * + * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/ + * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner + * Littera (Web-based, free): http://kvazars.com/littera/ + * + * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of + * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: http://codebeautify.org/xmltojson + * + * Note: This method will only be available if the Bitmap Text Game Object has been built into Phaser. + * @param x The x position of the Game Object. + * @param y The y position of the Game Object. + * @param font The key of the font to use from the BitmapFont cache. + * @param text The string, or array of strings, to be set as the content of this Bitmap Text. + * @param size The font size to set. + * @param align The alignment of the text in a multi-line BitmapText object. Default 0. */ - moveTo(child: Phaser.GameObjects.GameObject, index: number): this; + bitmapText(x: number, y: number, font: string, text?: string | string[], size?: number, align?: number): Phaser.GameObjects.BitmapText; /** - * Moves a Game Object above another one within this Container. + * Creates a new Blitter Game Object and adds it to the Scene. * - * These 2 Game Objects must already be children of this Container. - * @param child1 The Game Object to move above base Game Object. - * @param child2 The base Game Object. + * Note: This method will only be available if the Blitter Game Object has been built into Phaser. + * @param x The x position of the Game Object. + * @param y The y position of the Game Object. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame The default Frame children of the Blitter will use. */ - moveAbove(child1: Phaser.GameObjects.GameObject, child2: Phaser.GameObjects.GameObject): this; + blitter(x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number): Phaser.GameObjects.Blitter; /** - * Moves a Game Object below another one within this Container. + * Creates a new Container Game Object and adds it to the Scene. * - * These 2 Game Objects must already be children of this Container. - * @param child1 The Game Object to move below base Game Object. - * @param child2 The base Game Object. + * Note: This method will only be available if the Container Game Object has been built into Phaser. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param children An optional array of Game Objects to add to this Container. */ - moveBelow(child1: Phaser.GameObjects.GameObject, child2: Phaser.GameObjects.GameObject): this; + container(x?: number, y?: number, children?: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[]): Phaser.GameObjects.Container; /** - * Removes the given Game Object, or array of Game Objects, from this Container. + * DOM Element Game Objects are a way to control and manipulate HTML Elements over the top of your game. * - * The Game Objects must already be children of this Container. + * In order for DOM Elements to display you have to enable them by adding the following to your game + * configuration object: * - * You can also optionally call `destroy` on each Game Object that is removed from the Container. - * @param child The Game Object, or array of Game Objects, to be removed from the Container. - * @param destroyChild Optionally call `destroy` on each child successfully removed from this Container. Default false. + * ```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. + * + * 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. + * + * 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. + * + * Note: This method will only be available if the DOM Element Game Object has been built into Phaser. + * @param x The horizontal position of this DOM Element in the world. + * @param y The vertical position of this DOM Element in the world. + * @param 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 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 innerText If given, will be set directly as the elements `innerText` property value, replacing whatever was there before. */ - remove(child: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[], destroyChild?: boolean): this; + dom(x: number, y: number, element?: HTMLElement | string, style?: string | any, innerText?: string): Phaser.GameObjects.DOMElement; /** - * Removes the Game Object at the given position in this Container. + * Creates a new Extern Game Object and adds it to the Scene. * - * You can also optionally call `destroy` on the Game Object, if one is found. - * @param index The index of the Game Object to be removed. - * @param destroyChild Optionally call `destroy` on the Game Object if successfully removed from this Container. Default false. + * Note: This method will only be available if the Extern Game Object has been built into Phaser. */ - removeAt(index: number, destroyChild?: boolean): this; + extern(): Phaser.GameObjects.Extern; /** - * Removes the Game Objects between the given positions in this Container. - * - * You can also optionally call `destroy` on each Game Object that is removed from the Container. - * @param startIndex An optional start index to search from. Default 0. - * @param endIndex An optional end index to search up to (but not included) Default Container.length. - * @param destroyChild Optionally call `destroy` on each Game Object successfully removed from this Container. Default false. + * The Scene to which this Game Object Factory belongs. */ - removeBetween(startIndex?: number, endIndex?: number, destroyChild?: boolean): this; + protected scene: Phaser.Scene; /** - * Removes all Game Objects from this Container. - * - * You can also optionally call `destroy` on each Game Object that is removed from the Container. - * @param destroyChild Optionally call `destroy` on each Game Object successfully removed from this Container. Default false. + * A reference to the Scene.Systems. */ - removeAll(destroyChild?: boolean): this; + protected systems: Phaser.Scenes.Systems; /** - * Brings the given Game Object to the top of this Container. - * This will cause it to render on-top of any other objects in the Container. - * @param child The Game Object to bring to the top of the Container. + * A reference to the Scene Event Emitter. */ - bringToTop(child: Phaser.GameObjects.GameObject): this; + protected events: Phaser.Events.EventEmitter; /** - * Sends the given Game Object to the bottom of this Container. - * This will cause it to render below any other objects in the Container. - * @param child The Game Object to send to the bottom of the Container. + * A reference to the Scene Display List. */ - sendToBack(child: Phaser.GameObjects.GameObject): this; + protected displayList: Phaser.GameObjects.DisplayList; /** - * Moves the given Game Object up one place in this Container, unless it's already at the top. - * @param child The Game Object to be moved in the Container. + * A reference to the Scene Update List. */ - moveUp(child: Phaser.GameObjects.GameObject): this; + protected updateList: Phaser.GameObjects.UpdateList; /** - * Moves the given Game Object down one place in this Container, unless it's already at the bottom. - * @param child The Game Object to be moved in the Container. + * Adds an existing Game Object to this Scene. + * + * If the Game Object renders, it will be added to the Display List. + * If it has a `preUpdate` method, it will be added to the Update List. + * @param child The child to be added to this Scene. */ - moveDown(child: Phaser.GameObjects.GameObject): this; + existing(child: G): G; /** - * Reverses the order of all Game Objects in this Container. + * Static method called directly by the Game Object factory functions. + * With this method you can register a custom GameObject factory in the GameObjectFactory, + * providing a name (`factoryType`) and the constructor (`factoryFunction`) in order + * to be called when you call to Phaser.Scene.add[ factoryType ] method. + * @param factoryType The key of the factory that you will use to call to Phaser.Scene.add[ factoryType ] method. + * @param factoryFunction The constructor function to be called when you invoke to the Phaser.Scene.add method. */ - reverse(): this; + static register(factoryType: string, factoryFunction: Function): void; /** - * Shuffles the all Game Objects in this Container using the Fisher-Yates implementation. + * Static method called directly by the Game Object factory functions. + * With this method you can remove a custom GameObject factory registered in the GameObjectFactory, + * providing a its `factoryType`. + * @param factoryType The key of the factory that you want to remove from the GameObjectFactory. */ - shuffle(): this; + static remove(factoryType: string): void; /** - * Replaces a Game Object in this Container with the new Game Object. - * The new Game Object cannot already be a child of this Container. - * @param oldChild The Game Object in this Container that will be replaced. - * @param newChild The Game Object to be added to this Container. - * @param destroyChild Optionally call `destroy` on the Game Object if successfully removed from this Container. Default false. + * Creates a new Graphics Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Graphics Game Object has been built into Phaser. + * @param config The Graphics configuration. */ - replace(oldChild: Phaser.GameObjects.GameObject, newChild: Phaser.GameObjects.GameObject, destroyChild?: boolean): this; + graphics(config?: Phaser.Types.GameObjects.Graphics.Options): Phaser.GameObjects.Graphics; /** - * Returns `true` if the given Game Object is a direct child of this Container. + * Creates a new Group Game Object and adds it to the Scene. * - * This check does not scan nested Containers. - * @param child The Game Object to check for within this Container. + * Note: This method will only be available if the Group Game Object has been built into Phaser. + * @param children Game Objects to add to this Group; or the `config` argument. + * @param config A Group Configuration object. */ - exists(child: Phaser.GameObjects.GameObject): boolean; + group(children?: Phaser.GameObjects.GameObject[] | Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupConfig[] | Phaser.Types.GameObjects.Group.GroupCreateConfig, config?: Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig): Phaser.GameObjects.Group; /** - * Sets the property to the given value on all Game Objects in this Container. + * Creates a new Image Game Object and adds it to the Scene. * - * Optionally you can specify a start and end index. For example if this Container had 100 Game Objects, - * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only - * the first 50 Game Objects. - * @param property The property that must exist on the Game Object. - * @param value The value to get the property to. - * @param startIndex An optional start index to search from. Default 0. - * @param endIndex An optional end index to search up to (but not included) Default Container.length. + * Note: This method will only be available if the Image Game Object has been built into Phaser. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. */ - setAll(property: string, value: any, startIndex?: number, endIndex?: number): this; + image(x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number): Phaser.GameObjects.Image; /** - * Passes all Game Objects in this Container to the given callback. + * Creates a new Layer Game Object and adds it to the Scene. * - * A copy of the Container is made before passing each entry to your callback. - * This protects against the callback itself modifying the Container. + * Note: This method will only be available if the Layer Game Object has been built into Phaser. + * @param children An optional array of Game Objects to add to this Layer. + */ + layer(children?: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[]): Phaser.GameObjects.Layer; + + /** + * Creates a new Mesh Game Object and adds it to the Scene. * - * If you know for sure that the callback will not change the size of this Container - * then you can use the more performant `Container.iterate` method instead. - * @param callback The function to call. - * @param context Value to use as `this` when executing callback. - * @param args Additional arguments that will be passed to the callback, after the child. + * Note: This method will only be available if the Mesh Game Object and WebGL support have been built into Phaser. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. + * @param vertices The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`. + * @param uvs The UVs pairs array. + * @param indicies Optional vertex indicies array. If you don't have one, pass `null` or an empty array. + * @param containsZ Does the vertices data include a `z` component? Default false. + * @param normals Optional vertex normals array. If you don't have one, pass `null` or an empty array. + * @param colors An array of colors, one per vertex, or a single color value applied to all vertices. Default 0xffffff. + * @param alphas An array of alpha values, one per vertex, or a single alpha value applied to all vertices. Default 1. */ - each(callback: Function, context?: object, ...args: any[]): this; + mesh(x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number, vertices?: number[], uvs?: number[], indicies?: number[], containsZ?: boolean, normals?: number[], colors?: number | number[], alphas?: number | number[]): Phaser.GameObjects.Mesh; /** - * Passes all Game Objects in this Container to the given callback. + * A Nine Slice Game Object allows you to display a texture-based object that + * can be stretched both horizontally and vertically, but that retains + * fixed-sized corners. The dimensions of the corners are set via the + * parameters to this class. + * + * This is extremely useful for UI and button like elements, where you need + * them to expand to accommodate the content without distorting the texture. + * + * The texture you provide for this Game Object should be based on the + * following layout structure: + * + * ``` + * A B + * +---+----------------------+---+ + * C | 1 | 2 | 3 | + * +---+----------------------+---+ + * | | | | + * | 4 | 5 | 6 | + * | | | | + * +---+----------------------+---+ + * D | 7 | 8 | 9 | + * +---+----------------------+---+ + * ``` + * + * When changing this objects width and / or height: + * + * areas 1, 3, 7 and 9 (the corners) will remain unscaled + * areas 2 and 8 will be stretched horizontally only + * areas 4 and 6 will be stretched vertically only + * area 5 will be stretched both horizontally and vertically + * + * You can also create a 3 slice Game Object: + * + * This works in a similar way, except you can only stretch it horizontally. + * Therefore, it requires less configuration: + * + * ``` + * A B + * +---+----------------------+---+ + * | | | | + * C | 1 | 2 | 3 | + * | | | | + * +---+----------------------+---+ + * ``` * - * Only use this method when you absolutely know that the Container will not be modified during - * the iteration, i.e. by removing or adding to its contents. - * @param callback The function to call. - * @param context Value to use as `this` when executing callback. - * @param args Additional arguments that will be passed to the callback, after the child. - */ - iterate(callback: Function, context?: object, ...args: any[]): this; - - /** - * Sets the scroll factor of this Container and optionally all of its children. + * When changing this objects width (you cannot change its height) * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * areas 1 and 3 will remain unscaled + * area 2 will be stretched horizontally * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. + * The above configuration concept is adapted from the Pixi NineSlicePlane. * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. + * To specify a 3 slice object instead of a 9 slice you should only + * provide the `leftWidth` and `rightWidth` parameters. To create a 9 slice + * you must supply all parameters. * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * @param x The horizontal scroll factor of this Game Object. - * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. - * @param updateChildren Apply this scrollFactor to all Container children as well? Default false. + * The _minimum_ width this Game Object can be is the total of + * `leftWidth` + `rightWidth`. The _minimum_ height this Game Object + * can be is the total of `topHeight` + `bottomHeight`. + * If you need to display this object at a smaller size, you can scale it. + * + * In terms of performance, using a 3 slice Game Object is the equivalent of + * having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent + * of having 9 Sprites in a row. The vertices of this object are all batched + * together and can co-exist with other Sprites and graphics on the display + * list, without incurring any additional overhead. + * + * As of Phaser 3.60 this Game Object is WebGL only. + * @param x The horizontal position of the center of this Game Object in the world. + * @param y The vertical position of the center of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. + * @param width The width of the Nine Slice Game Object. You can adjust the width post-creation. Default 256. + * @param height The height of the Nine Slice Game Object. If this is a 3 slice object the height will be fixed to the height of the texture and cannot be changed. Default 256. + * @param leftWidth The size of the left vertical column (A). Default 10. + * @param rightWidth The size of the right vertical column (B). Default 10. + * @param topHeight The size of the top horiztonal row (C). Set to zero or undefined to create a 3 slice object. Default 0. + * @param bottomHeight The size of the bottom horiztonal row (D). Set to zero or undefined to create a 3 slice object. Default 0. */ - setScrollFactor(x: number, y?: number, updateChildren?: boolean): this; + nineslice(x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number, width?: number, height?: number, leftWidth?: number, rightWidth?: number, topHeight?: number, bottomHeight?: number): Phaser.GameObjects.NineSlice; /** - * The number of Game Objects inside this Container. + * Creates a new Particle Emitter Game Object and adds it to the Scene. + * + * If you wish to configure the Emitter after creating it, use the `ParticleEmitter.setConfig` method. + * + * Prior to Phaser v3.60 this function would create a `ParticleEmitterManager`. These were removed + * in v3.60 and replaced with creating a `ParticleEmitter` instance directly. Please see the + * updated function parameters and class documentation for more details. + * + * Note: This method will only be available if the Particles Game Object has been built into Phaser. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param config Configuration settings for the Particle Emitter. */ - readonly length: number; + particles(x?: number, y?: number, texture?: string | Phaser.Textures.Texture, config?: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig): Phaser.GameObjects.Particles.ParticleEmitter; /** - * Returns the first Game Object within the Container, or `null` if it is empty. + * Creates a new PathFollower Game Object and adds it to the Scene. * - * You can move the cursor by calling `Container.next` and `Container.previous`. + * Note: This method will only be available if the PathFollower Game Object has been built into Phaser. + * @param path The Path this PathFollower is connected to. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. */ - readonly first: Phaser.GameObjects.GameObject; + follower(path: Phaser.Curves.Path, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number): Phaser.GameObjects.PathFollower; /** - * Returns the last Game Object within the Container, or `null` if it is empty. + * Creates a new Plane Game Object and adds it to the Scene. * - * You can move the cursor by calling `Container.next` and `Container.previous`. + * Note: This method will only be available if the Plane Game Object has been built into Phaser. + * @param x The horizontal position of this Plane in the world. + * @param y The vertical position of this Plane in the world. + * @param texture The key, or instance of the Texture this Plane will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Plane is rendering with. + * @param width The width of this Plane, in cells, not pixels. Default 8. + * @param height The height of this Plane, in cells, not pixels. Default 8. + * @param tile Is the texture tiled? I.e. repeated across each cell. Default false. */ - readonly last: Phaser.GameObjects.GameObject; + plane(x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number, width?: number, height?: number, tile?: boolean): Phaser.GameObjects.Plane; /** - * Returns the next Game Object within the Container, or `null` if it is empty. + * Creates a new Point Light Game Object and adds it to the Scene. * - * You can move the cursor by calling `Container.next` and `Container.previous`. + * Note: This method will only be available if the Point Light Game Object has been built into Phaser. + * + * The Point Light Game Object provides a way to add a point light effect into your game, + * without the expensive shader processing requirements of the traditional Light Game Object. + * + * The difference is that the Point Light renders using a custom shader, designed to give the + * impression of a point light source, of variable radius, intensity and color, in your game. + * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their + * normal maps for calcuations. This makes them extremely fast to render compared to Lights + * and perfect for special effects, such as flickering torches or muzzle flashes. + * + * For maximum performance you should batch Point Light Game Objects together. This means + * ensuring they follow each other consecutively on the display list. Ideally, use a Layer + * Game Object and then add just Point Lights to it, so that it can batch together the rendering + * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in + * your game then it's perfectly safe to mix them into the dislay list as normal. However, if + * you're using a large number of them, please consider how they are mixed into the display list. + * + * The renderer will automatically cull Point Lights. Those with a radius that does not intersect + * with the Camera will be skipped in the rendering list. This happens automatically and the + * culled state is refreshed every frame, for every camera. + * + * The origin of a Point Light is always 0.5 and it cannot be changed. + * + * Point Lights are a WebGL only feature and do not have a Canvas counterpart. + * @param x The horizontal position of this Point Light in the world. + * @param y The vertical position of this Point Light in the world. + * @param color The color of the Point Light, given as a hex value. Default 0xffffff. + * @param radius The radius of the Point Light. Default 128. + * @param intensity The intensity, or color blend, of the Point Light. Default 1. + * @param attenuation The attenuation of the Point Light. This is the reduction of light from the center point. Default 0.1. */ - readonly next: Phaser.GameObjects.GameObject; + pointlight(x: number, y: number, color?: number, radius?: number, intensity?: number, attenuation?: number): Phaser.GameObjects.PointLight; /** - * Returns the previous Game Object within the Container, or `null` if it is empty. + * Creates a new Render Texture Game Object and adds it to the Scene. * - * You can move the cursor by calling `Container.next` and `Container.previous`. + * Note: This method will only be available if the Render Texture Game Object has been built into Phaser. + * + * A Render Texture is a combination of Dynamic Texture and an Image Game Object, that uses the + * Dynamic Texture to display itself with. + * + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. + * + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. + * + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param width The width of the Render Texture. Default 32. + * @param height The height of the Render Texture. Default 32. */ - readonly previous: Phaser.GameObjects.GameObject; + renderTexture(x: number, y: number, width?: number, height?: number): Phaser.GameObjects.RenderTexture; /** - * Internal destroy handler, called as part of the destroy process. + * Creates a new Rope Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Rope Game Object and WebGL support have been built into Phaser. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. + * @param points An array containing the vertices data for this Rope. If none is provided a simple quad is created. See `setPoints` to set this post-creation. + * @param horizontal Should the vertices of this Rope be aligned horizontally (`true`), or vertically (`false`)? Default true. + * @param colors An optional array containing the color data for this Rope. You should provide one color value per pair of vertices. + * @param alphas An optional array containing the alpha data for this Rope. You should provide one alpha value per pair of vertices. */ - protected preDestroy(): void; + rope(x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number, points?: Phaser.Types.Math.Vector2Like[], horizontal?: boolean, colors?: number[], alphas?: number[]): Phaser.GameObjects.Rope; /** - * Clears all alpha values associated with this Game Object. + * Creates a new Shader Game Object and adds it to the Scene. * - * Immediately sets the alpha levels back to 1 (fully opaque). + * Note: This method will only be available if the Shader Game Object and WebGL support have been built into Phaser. + * @param key The key of the shader to use from the shader cache, or a BaseShader instance. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param width The width of the Game Object. Default 128. + * @param height The height of the Game Object. Default 128. + * @param textures Optional array of texture keys to bind to the iChannel0...3 uniforms. The textures must already exist in the Texture Manager. + * @param textureData Optional additional texture data. */ - clearAlpha(): this; + shader(key: string | Phaser.Display.BaseShader, x?: number, y?: number, width?: number, height?: number, textures?: string[], textureData?: object): Phaser.GameObjects.Shader; /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * @param value The alpha value applied across the whole Game Object. Default 1. + * Creates a new Arc Shape Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Arc Game Object has been built into Phaser. + * + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param radius The radius of the arc. Default 128. + * @param startAngle The start angle of the arc, in degrees. Default 0. + * @param endAngle The end angle of the arc, in degrees. Default 360. + * @param anticlockwise The winding order of the start and end angles. Default false. + * @param fillColor The color the arc will be filled with, i.e. 0xff0000 for red. + * @param fillAlpha The alpha the arc will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. */ - setAlpha(value?: number): this; + arc(x?: number, y?: number, radius?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Arc; /** - * The alpha value of the Game Object. + * Creates a new Circle Shape Game Object and adds it to the Scene. * - * This is a global value, impacting the entire Game Object, not just a region of it. + * A Circle is an Arc with no defined start and end angle, making it render as a complete circle. + * + * Note: This method will only be available if the Arc Game Object has been built into Phaser. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param radius The radius of the circle. Default 128. + * @param fillColor The color the circle will be filled with, i.e. 0xff0000 for red. + * @param fillAlpha The alpha the circle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. */ - alpha: number; + circle(x?: number, y?: number, radius?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Arc; /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * Creates a new Curve Shape Game Object and adds it to the Scene. * - * Under WebGL only the following Blend Modes are available: + * Note: This method will only be available if the Curve Game Object has been built into Phaser. * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE + * 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. * - * Canvas has more available depending on browser support. + * This shape supports both fill and stroke colors. * - * You can also create your own custom Blend Modes in WebGL. + * To render a Curve Shape you must first create a `Phaser.Curves.Curve` object, then pass it to + * the Curve Shape in the constructor. * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency of which blend modes - * are used. + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param curve The Curve object to use to create the Shape. + * @param fillColor The color the curve will be filled with, i.e. 0xff0000 for red. + * @param fillAlpha The alpha the curve will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. */ - blendMode: Phaser.BlendModes | string; + curve(x?: number, y?: number, curve?: Phaser.Curves.Curve, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Curve; /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * Creates a new Ellipse Shape Game Object and adds it to the Scene. * - * Under WebGL only the following Blend Modes are available: + * Note: This method will only be available if the Ellipse Game Object has been built into Phaser. * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * 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. * - * Canvas has more available depending on browser support. + * This shape supports both fill and stroke colors. * - * You can also create your own custom Blend Modes in WebGL. + * 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. * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency in which blend modes - * are used. - * @param value The BlendMode value. Either a string or a CONST. + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param width The width of the ellipse. An ellipse with equal width and height renders as a circle. Default 128. + * @param height The height of the ellipse. An ellipse with equal width and height renders as a circle. Default 128. + * @param fillColor The color the ellipse will be filled with, i.e. 0xff0000 for red. + * @param fillAlpha The alpha the ellipse will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. */ - setBlendMode(value: string | Phaser.BlendModes): this; + ellipse(x?: number, y?: number, width?: number, height?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Ellipse; /** - * The native (un-scaled) width of this Game Object. + * Creates a new Grid Shape Game Object and adds it to the Scene. * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. + * Note: This method will only be available if the Grid Game Object has been built into Phaser. + * + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param width The width of the grid. Default 128. + * @param height The height of the grid. Default 128. + * @param cellWidth The width of one cell in the grid. Default 32. + * @param cellHeight The height of one cell in the grid. Default 32. + * @param fillColor The color the grid cells will be filled with, i.e. 0xff0000 for red. + * @param 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 outlineFillColor The color of the lines between the grid cells. + * @param outlineFillAlpha The alpha of the lines between the grid cells. */ - width: number; + grid(x?: number, y?: number, width?: number, height?: number, cellWidth?: number, cellHeight?: number, fillColor?: number, fillAlpha?: number, outlineFillColor?: number, outlineFillAlpha?: number): Phaser.GameObjects.Grid; /** - * The native (un-scaled) height of this Game Object. + * Creates a new IsoBox Shape Game Object and adds it to the Scene. * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. + * Note: This method will only be available if the IsoBox Game Object has been built into Phaser. + * + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param size The width of the iso box in pixels. The left and right faces will be exactly half this value. Default 48. + * @param height 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. Default 32. + * @param fillTop The fill color of the top face of the iso box. Default 0xeeeeee. + * @param fillLeft The fill color of the left face of the iso box. Default 0x999999. + * @param fillRight The fill color of the right face of the iso box. Default 0xcccccc. */ - height: number; + isobox(x?: number, y?: number, size?: number, height?: number, fillTop?: number, fillLeft?: number, fillRight?: number): Phaser.GameObjects.IsoBox; /** - * The displayed width of this Game Object. + * Creates a new IsoTriangle Shape Game Object and adds it to the Scene. * - * This value takes into account the scale factor. + * Note: This method will only be available if the IsoTriangle Game Object has been built into Phaser. * - * Setting this value will adjust the Game Object's scale property. + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param size The width of the iso triangle in pixels. The left and right faces will be exactly half this value. Default 48. + * @param height 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. Default 32. + * @param reversed Is the iso triangle upside down? Default false. + * @param fillTop The fill color of the top face of the iso triangle. Default 0xeeeeee. + * @param fillLeft The fill color of the left face of the iso triangle. Default 0x999999. + * @param fillRight The fill color of the right face of the iso triangle. Default 0xcccccc. */ - displayWidth: number; + isotriangle(x?: number, y?: number, size?: number, height?: number, reversed?: boolean, fillTop?: number, fillLeft?: number, fillRight?: number): Phaser.GameObjects.IsoTriangle; /** - * The displayed height of this Game Object. + * Creates a new Line Shape Game Object and adds it to the Scene. * - * This value takes into account the scale factor. + * Note: This method will only be available if the Line Game Object has been built into Phaser. * - * Setting this value will adjust the Game Object's scale property. + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param x1 The horizontal position of the start of the line. Default 0. + * @param y1 The vertical position of the start of the line. Default 0. + * @param x2 The horizontal position of the end of the line. Default 128. + * @param y2 The vertical position of the end of the line. Default 0. + * @param strokeColor The color the line will be drawn in, i.e. 0xff0000 for red. + * @param strokeAlpha The alpha the line will be drawn in. You can also set the alpha of the overall Shape using its `alpha` property. */ - displayHeight: number; + line(x?: number, y?: number, x1?: number, y1?: number, x2?: number, y2?: number, strokeColor?: number, strokeAlpha?: number): Phaser.GameObjects.Line; /** - * Sets the internal size of this Game Object, as used for frame or physics body creation. + * Creates a new Polygon Shape Game Object and adds it to the Scene. * - * 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. + * Note: This method will only be available if the Polygon Game Object has been built into Phaser. * - * 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. - * @param width The width of this Game Object. - * @param height The height of this Game Object. + * 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: + * + * - 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param points The points that make up the polygon. + * @param fillColor The color the polygon will be filled with, i.e. 0xff0000 for red. + * @param fillAlpha The alpha the polygon will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. */ - setSize(width: number, height: number): this; + polygon(x?: number, y?: number, points?: any, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Polygon; /** - * Sets the display size of this Game Object. + * Creates a new Rectangle Shape Game Object and adds it to the Scene. * - * Calling this will adjust the scale. - * @param width The width of this Game Object. - * @param height The height of this Game Object. + * Note: This method will only be available if the Rectangle Game Object has been built into Phaser. + * + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param width The width of the rectangle. Default 128. + * @param height The height of the rectangle. Default 128. + * @param fillColor The color the rectangle will be filled with, i.e. 0xff0000 for red. + * @param fillAlpha The alpha the rectangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. */ - setDisplaySize(width: number, height: number): this; + rectangle(x?: number, y?: number, width?: number, height?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Rectangle; /** - * The depth of this Game Object within the Scene. + * Creates a new Star Shape Game Object and adds it to the Scene. * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. + * Note: This method will only be available if the Star Game Object has been built into Phaser. * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. + * 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. * - * Setting the depth will queue a depth sort event within the Scene. + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param points The number of points on the star. Default 5. + * @param innerRadius The inner radius of the star. Default 32. + * @param outerRadius The outer radius of the star. Default 64. + * @param fillColor The color the star will be filled with, i.e. 0xff0000 for red. + * @param fillAlpha The alpha the star will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. */ - depth: number; + star(x?: number, y?: number, points?: number, innerRadius?: number, outerRadius?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Star; /** - * The depth of this Game Object within the Scene. + * Creates a new Triangle Shape Game Object and adds it to the Scene. * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. + * Note: This method will only be available if the Triangle Game Object has been built into Phaser. * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. + * 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. * - * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * 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. + * @param x The horizontal position of this Game Object in the world. Default 0. + * @param y The vertical position of this Game Object in the world. Default 0. + * @param x1 The horizontal position of the first point in the triangle. Default 0. + * @param y1 The vertical position of the first point in the triangle. Default 128. + * @param x2 The horizontal position of the second point in the triangle. Default 64. + * @param y2 The vertical position of the second point in the triangle. Default 0. + * @param x3 The horizontal position of the third point in the triangle. Default 128. + * @param y3 The vertical position of the third point in the triangle. Default 128. + * @param fillColor The color the triangle will be filled with, i.e. 0xff0000 for red. + * @param fillAlpha The alpha the triangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. */ - setDepth(value: number): this; + triangle(x?: number, y?: number, x1?: number, y1?: number, x2?: number, y2?: number, x3?: number, y3?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Triangle; /** - * The Mask this Game Object is using during render. + * Creates a new Sprite Game Object and adds it to the Scene. + * + * Note: This method will only be available if the Sprite Game Object has been built into Phaser. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. */ - mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; + sprite(x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number): Phaser.GameObjects.Sprite; /** - * Sets the mask that this Game Object will use to render with. + * Creates a new Text Game Object and adds it to the Scene. * - * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * A Text Game Object. * - * If a mask is already set on this Game Object it will be immediately replaced. + * Text objects work by creating their own internal hidden Canvas and then renders text to it using + * the standard Canvas `fillText` API. It then creates a texture from this canvas which is rendered + * to your game during the render pass. * - * Masks are positioned in global space and are not relative to the Game Object to which they - * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * Because it uses the Canvas API you can take advantage of all the features this offers, such as + * applying gradient fills to the text, or strokes, shadows and more. You can also use custom fonts + * loaded externally, such as Google or TypeKit Web fonts. * - * Masks have no impact on physics or input detection. They are purely a rendering component - * that allows you to limit what is visible during the render pass. - * @param mask The mask this Game Object will use when rendering. + * You can only display fonts that are currently loaded and available to the browser: therefore fonts must + * be pre-loaded. Phaser does not do ths for you, so you will require the use of a 3rd party font loader, + * or have the fonts ready available in the CSS on the page in which your Phaser game resides. + * + * See {@link http://www.jordanm.co.uk/tinytype this compatibility table} for the available default fonts + * across mobile browsers. + * + * A note on performance: Every time the contents of a Text object changes, i.e. changing the text being + * displayed, or the style of the text, it needs to remake the Text canvas, and if on WebGL, re-upload the + * new texture to the GPU. This can be an expensive operation if used often, or with large quantities of + * Text objects in your game. If you run into performance issues you would be better off using Bitmap Text + * instead, as it benefits from batching and avoids expensive Canvas API calls. + * + * Note: This method will only be available if the Text Game Object has been built into Phaser. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param text The text this Text object will display. + * @param style The Text style configuration object. */ - setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; + text(x: number, y: number, text: string | string[], style?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text; /** - * Clears the mask that this Game Object was using. - * @param destroyMask Destroy the mask before clearing it? Default false. + * Creates a new TileSprite Game Object and adds it to the Scene. + * + * Note: This method will only be available if the TileSprite Game Object has been built into Phaser. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param width The width of the Game Object. If zero it will use the size of the texture frame. + * @param height The height of the Game Object. If zero it will use the size of the texture frame. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. Cannot be a DynamicTexture. + * @param frame An optional frame from the Texture this Game Object is rendering with. */ - clearMask(destroyMask?: boolean): this; + tileSprite(x: number, y: number, width: number, height: number, texture: string | Phaser.Textures.Texture, frame?: string | number): Phaser.GameObjects.TileSprite; /** - * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * Creates a new Video Game Object and adds it to the Scene. * - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * This Game Object is capable of handling playback of a video file, video stream or media stream. * - * To create the mask you need to pass in a reference to a renderable Game Object. - * A renderable Game Object is one that uses a texture to render with, such as an - * Image, Sprite, Render Texture or BitmapText. + * You can optionally 'preload' the video into the Phaser Video Cache: * - * If you do not provide a renderable object, and this Game Object has a texture, - * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. - */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; - - /** - * Creates and returns a Geometry Mask. This mask can be used by any Game Object, - * including this one. + * ```javascript + * preload () { + * this.load.video('ripley', 'assets/aliens.mp4'); + * } * - * To create the mask you need to pass in a reference to a Graphics Game Object. + * create () { + * this.add.video(400, 300, 'ripley'); + * } + * ``` * - * If you do not provide a graphics object, and this Game Object is an instance - * of a Graphics object, then it will use itself to create the mask. + * You don't have to 'preload' the video. You can also play it directly from a URL: * - * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. - */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; - - /** - * The initial WebGL pipeline of this Game Object. + * ```javascript + * create () { + * this.add.video(400, 300).loadURL('assets/aliens.mp4'); + * } + * ``` * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. - */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; - - /** - * The current WebGL pipeline of this Game Object. - */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; - - /** - * Does this Game Object have any Post Pipelines set? - */ - hasPostPipeline: boolean; - - /** - * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * To all intents and purposes, a video is a standard Game Object, just like a Sprite. And as such, you can do + * all the usual things to it, such as scaling, rotating, cropping, tinting, making interactive, giving a + * physics body, etc. * - * The pipelines are processed in the order in which they appear in this array. + * Transparent videos are also possible via the WebM file format. Providing the video file has was encoded with + * an alpha channel, and providing the browser supports WebM playback (not all of them do), then it will render + * in-game with full transparency. * - * If you modify this array directly, be sure to set the - * `hasPostPipeline` property accordingly. - */ - postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - - /** - * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. - */ - pipelineData: object; - - /** - * Sets the initial WebGL Pipeline of this Game Object. + * ### Autoplaying Videos * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; - - /** - * Sets the main WebGL Pipeline of this Game Object. + * Videos can only autoplay if the browser has been unlocked with an interaction, or satisfies the MEI settings. + * The policies that control autoplaying are vast and vary between browser. You can, and should, read more about + * it here: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide * - * Also sets the `pipelineData` property, if the parameter is given. + * If your video doesn't contain any audio, then set the `noAudio` parameter to `true` when the video is _loaded_, + * and it will often allow the video to play immediately: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. - */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; - - /** - * Sets one, or more, Post Pipelines on this Game Object. + * ```javascript + * preload () { + * this.load.video('pixar', 'nemo.mp4', true); + * } + * ``` * - * Post Pipelines are invoked after this Game Object has rendered to its target and - * are commonly used for post-fx. + * The 3rd parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without + * audio can autoplay without requiring a user interaction. Video with audio cannot do this unless it satisfies + * the browsers MEI settings. See the MDN Autoplay Guide for further details. * - * The post pipelines are appended to the `postPipelines` array belonging to this - * Game Object. When the renderer processes this Game Object, it iterates through the post - * pipelines in the order in which they appear in the array. If you are stacking together - * multiple effects, be aware that the order is important. + * Or: * - * If you call this method multiple times, the new pipelines will be appended to any existing - * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * ```javascript + * create () { + * this.add.video(400, 300).loadURL('assets/aliens.mp4', true); + * } + * ``` * - * You can optionally also sets the `pipelineData` property, if the parameter is given. + * You can set the `noAudio` parameter to `true` even if the video does contain audio. It will still allow the video + * to play immediately, but the audio will not start. * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. - */ - setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; - - /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Note that due to a bug in IE11 you cannot play a video texture to a Sprite in WebGL. For IE11 force Canvas mode. * - * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * More details about video playback and the supported media formats can be found on MDN: * - * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement + * https://developer.mozilla.org/en-US/docs/Web/Media/Formats * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param key The key of the pipeline data to set, update, or delete. - * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. - */ - setPipelineData(key: string, value?: any): this; - - /** - * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. - * @param pipeline The string-based name of the pipeline, or a pipeline class. - */ - getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - - /** - * Resets the WebGL Post Pipelines of this Game Object. It does this by calling - * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * Note: This method will only be available if the Video Game Object has been built into Phaser. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param key Optional key of the Video this Game Object will play, as stored in the Video Cache. */ - resetPostPipeline(resetData?: boolean): void; + video(x: number, y: number, key?: string): Phaser.GameObjects.Video; /** - * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. + * Creates a new Zone Game Object and adds it to the Scene. * - * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. - * @param pipeline The string-based name of the pipeline, or a pipeline class. - */ - removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; - - /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. - */ - getPipelineName(): string; - - /** - * The x position of this Game Object. + * Note: This method will only be available if the Zone Game Object has been built into Phaser. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param width The width of the Game Object. + * @param height The height of the Game Object. */ - x: number; + zone(x: number, y: number, width: number, height: number): Phaser.GameObjects.Zone; /** - * The y position of this Game Object. + * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. + * When loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing + * from a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map + * data. For an empty map, you should specify tileWidth, tileHeight, width & height. + * @param key The key in the Phaser cache that corresponds to the loaded tilemap data. + * @param tileWidth The width of a tile in pixels. Pass in `null` to leave as the + * default. Default 32. + * @param tileHeight The height of a tile in pixels. Pass in `null` to leave as the + * default. Default 32. + * @param width The width of the map in tiles. Pass in `null` to leave as the + * default. Default 10. + * @param height The height of the map in tiles. Pass in `null` to leave as the + * default. Default 10. + * @param data Instead of loading from the cache, you can also load directly from + * a 2D array of tile indexes. Pass in `null` for no data. + * @param 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. Default false. */ - y: number; + tilemap(key?: string, tileWidth?: number, tileHeight?: number, width?: number, height?: number, data?: number[][], insertNull?: boolean): Phaser.Tilemaps.Tilemap; /** - * The z position of this Game Object. + * A Timeline is a way to schedule events to happen at specific times in the future. * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#depth} instead. - */ - z: number; - - /** - * The w position of this Game Object. + * You can think of it as an event sequencer for your game, allowing you to schedule the + * running of callbacks, events and other actions at specific times in the future. + * + * A Timeline is a Scene level system, meaning you can have as many Timelines as you like, each + * belonging to a different Scene. You can also have multiple Timelines running at the same time. + * + * If the Scene is paused, the Timeline will also pause. If the Scene is destroyed, the Timeline + * will be automatically destroyed. However, you can control the Timeline directly, pausing, + * resuming and stopping it at any time. + * + * Create an instance of a Timeline via the Game Object Factory: + * + * ```js + * const timeline = this.add.timeline(); + * ``` + * + * The Timeline always starts paused. You must call `play` on it to start it running. + * + * You can also pass in a configuration object on creation, or an array of them: + * + * ```js + * const timeline = this.add.timeline({ + * at: 1000, + * run: () => { + * this.add.sprite(400, 300, 'logo'); + * } + * }); + * + * timeline.play(); + * ``` + * + * In this example we sequence a few different events: + * + * ```js + * const timeline = this.add.timeline([ + * { + * at: 1000, + * run: () => { this.logo = this.add.sprite(400, 300, 'logo'); }, + * sound: 'TitleMusic' + * }, + * { + * at: 2500, + * tween: { + * targets: this.logo, + * y: 600, + * yoyo: true + * }, + * sound: 'Explode' + * }, + * { + * at: 8000, + * event: 'HURRY_PLAYER', + * target: this.background, + * set: { + * tint: 0xff0000 + * } + * } + * ]); + * + * timeline.play(); + * ``` + * + * There are lots of options available to you via the configuration object. See the + * {@link Phaser.Types.Time.TimelineEventConfig} typedef for more details. + * @param config The configuration object for this Timeline Event, or an array of them. */ - w: number; + timeline(config: Phaser.Types.Time.TimelineEventConfig | Phaser.Types.Time.TimelineEventConfig[]): Phaser.Time.Timeline; /** - * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object - * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * Creates a new Tween object. * - * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this - * isn't the case, use the `scaleX` or `scaleY` properties instead. + * Note: This method will only be available if Tweens have been built into Phaser. + * @param config A Tween Configuration object, or a Tween or TweenChain instance. */ - scale: number; + tween(config: Phaser.Types.Tweens.TweenBuilderConfig | Phaser.Types.Tweens.TweenChainBuilderConfig | Phaser.Tweens.Tween | Phaser.Tweens.TweenChain): Phaser.Tweens.Tween; /** - * The horizontal scale of this Game Object. + * Creates a new TweenChain object and adds it to the Tween Manager. + * + * Note: This method will only be available if Tweens have been built into Phaser. + * @param config The TweenChain configuration. */ - scaleX: number; + tweenchain(config: Phaser.Types.Tweens.TweenBuilderConfig | object): Phaser.Tweens.TweenChain; - /** - * The vertical scale of this Game Object. - */ - scaleY: number; + } - /** - * The angle of this Game Object as expressed in degrees. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left - * and -90 is up. - * - * If you prefer to work in radians, see the `rotation` property instead. - */ - angle: number; + /** + * 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. + * @param src The Game Object to calculate the transform matrix for. + * @param camera The camera being used to render the Game Object. + * @param parentMatrix The transform matrix of the parent container, if any. + */ + function GetCalcMatrix(src: Phaser.GameObjects.GameObject, camera: Phaser.Cameras.Scene2D.Camera, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.Types.GameObjects.GetCalcMatrixResults; + /** + * A Graphics object is a way to draw primitive shapes to your game. Primitives include forms of geometry, such as + * Rectangles, Circles, and Polygons. They also include lines, arcs and curves. When you initially create a Graphics + * object it will be empty. + * + * To draw to it you must first specify a line style or fill style (or both), draw shapes using paths, and finally + * fill or stroke them. For example: + * + * ```javascript + * graphics.lineStyle(5, 0xFF00FF, 1.0); + * graphics.beginPath(); + * graphics.moveTo(100, 100); + * graphics.lineTo(200, 200); + * graphics.closePath(); + * graphics.strokePath(); + * ``` + * + * There are also many helpful methods that draw and fill/stroke common shapes for you. + * + * ```javascript + * graphics.lineStyle(5, 0xFF00FF, 1.0); + * graphics.fillStyle(0xFFFFFF, 1.0); + * graphics.fillRect(50, 50, 400, 200); + * graphics.strokeRect(50, 50, 400, 200); + * ``` + * + * When a Graphics object is rendered it will render differently based on if the game is running under Canvas or WebGL. + * Under Canvas it will use the HTML Canvas context drawing operations to draw the path. + * Under WebGL the graphics data is decomposed into polygons. Both of these are expensive processes, especially with + * complex shapes. + * + * If your Graphics object doesn't change much (or at all) once you've drawn your shape to it, then you will help + * performance by calling {@link Phaser.GameObjects.Graphics#generateTexture}. This will 'bake' the Graphics object into + * a Texture, and return it. You can then use this Texture for Sprites or other display objects. If your Graphics object + * updates frequently then you should avoid doing this, as it will constantly generate new textures, which will consume + * memory. + * + * As you can tell, Graphics objects are a bit of a trade-off. While they are extremely useful, you need to be careful + * in their complexity and quantity of them in your game. + */ + class Graphics extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible, Phaser.GameObjects.Components.ScrollFactor { /** - * The angle of this Game Object in radians. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left - * and -PI/2 is up. * - * If you prefer to work in degrees, see the `angle` property instead. - */ - rotation: number; - - /** - * Sets the position of this Game Object. - * @param x The x position of this Game Object. Default 0. - * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. - * @param z The z position of this Game Object. Default 0. - * @param w The w position of this Game Object. Default 0. + * @param scene The Scene to which this Graphics object belongs. + * @param options Options that set the position and default style of this Graphics object. */ - setPosition(x?: number, y?: number, z?: number, w?: number): this; + constructor(scene: Phaser.Scene, options?: Phaser.Types.GameObjects.Graphics.Options); /** - * Copies an object's coordinates to this Game Object's position. - * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + * The horizontal display origin of the Graphics. */ - copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + displayOriginX: number; /** - * Sets the position of this Game Object to be a random position within the confines of - * the given area. - * - * If no area is specified a random position between 0 x 0 and the game width x height is used instead. - * - * The position does not factor in the size of this Game Object, meaning that only the origin is - * guaranteed to be within the area. - * @param x The x position of the top-left of the random area. Default 0. - * @param y The y position of the top-left of the random area. Default 0. - * @param width The width of the random area. - * @param height The height of the random area. + * The vertical display origin of the Graphics. */ - setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + displayOriginY: number; /** - * Sets the rotation of this Game Object. - * @param radians The rotation of this Game Object, in radians. Default 0. + * The array of commands used to render the Graphics. */ - setRotation(radians?: number): this; + commandBuffer: any[]; /** - * Sets the angle of this Game Object. - * @param degrees The rotation of this Game Object, in degrees. Default 0. + * The default fill color for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. */ - setAngle(degrees?: number): this; + readonly defaultFillColor: number; /** - * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. - * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + * The default fill alpha for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. */ - setScale(x: number, y?: number): this; + readonly defaultFillAlpha: number; /** - * Sets the x position of this Game Object. - * @param value The x position of this Game Object. Default 0. + * The default stroke width for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. */ - setX(value?: number): this; + readonly defaultStrokeWidth: number; /** - * Sets the y position of this Game Object. - * @param value The y position of this Game Object. Default 0. + * The default stroke color for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. */ - setY(value?: number): this; + readonly defaultStrokeColor: number; /** - * Sets the z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. - * @param value The z position of this Game Object. Default 0. + * The default stroke alpha for shapes rendered by this Graphics object. + * Set this value with `setDefaultStyles()`. */ - setZ(value?: number): this; + readonly defaultStrokeAlpha: number; /** - * Sets the w position of this Game Object. - * @param value The w position of this Game Object. Default 0. + * Set the default style settings for this Graphics object. + * @param options The styles to set as defaults. */ - setW(value?: number): this; + setDefaultStyles(options: Phaser.Types.GameObjects.Graphics.Styles): this; /** - * Gets the local transform matrix for this Game Object. - * @param tempMatrix The matrix to populate with the values from this Game Object. + * Set the current line style. Used for all 'stroke' related functions. + * @param lineWidth The stroke width. + * @param color The stroke color. + * @param alpha The stroke alpha. Default 1. */ - getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + lineStyle(lineWidth: number, color: number, alpha?: number): this; /** - * Gets the world transform matrix for this Game Object, factoring in any parent Containers. - * @param tempMatrix The matrix to populate with the values from this Game Object. - * @param parentMatrix A temporary matrix to hold parent values during the calculations. + * Set the current fill style. Used for all 'fill' related functions. + * @param color The fill color. + * @param alpha The fill alpha. Default 1. */ - getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + fillStyle(color: number, alpha?: number): this; /** - * Takes the given `x` and `y` coordinates and converts them into local space for this - * Game Object, taking into account parent and local transforms, and the Display Origin. + * Sets a gradient fill style. This is a WebGL only feature. * - * The returned Vector2 contains the translated point in its properties. + * The gradient color values represent the 4 corners of an untransformed rectangle. + * The gradient is used to color all filled shapes and paths drawn after calling this method. + * If you wish to turn a gradient off, call `fillStyle` and provide a new single fill color. * - * A Camera needs to be provided in order to handle modified scroll factors. If no - * camera is specified, it will use the `main` camera from the Scene to which this - * Game Object belongs. - * @param x The x position to translate. - * @param y The y position to translate. - * @param point A Vector2, or point-like object, to store the results in. - * @param camera The Camera which is being tested against. If not given will use the Scene default camera. - */ - getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; - - /** - * Gets the sum total rotation of all of this Game Objects parent Containers. + * When filling a triangle only the first 3 color values provided are used for the 3 points of a triangle. * - * The returned value is in radians and will be zero if this Game Object has no parent container. + * This feature is best used only on rectangles and triangles. All other shapes will give strange results. + * + * Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used + * will be filled with a gradient on its own. There is no ability to gradient fill a shape or path as a single + * entity at this time. + * @param topLeft The top left fill color. + * @param topRight The top right fill color. + * @param bottomLeft The bottom left fill color. + * @param bottomRight The bottom right fill color. Not used when filling triangles. + * @param alphaTopLeft The top left alpha value. If you give only this value, it's used for all corners. Default 1. + * @param alphaTopRight The top right alpha value. Default 1. + * @param alphaBottomLeft The bottom left alpha value. Default 1. + * @param alphaBottomRight The bottom right alpha value. Default 1. */ - getParentRotation(): number; + fillGradientStyle(topLeft: number, topRight: number, bottomLeft: number, bottomRight: number, alphaTopLeft?: number, alphaTopRight?: number, alphaBottomLeft?: number, alphaBottomRight?: number): this; /** - * The visible state of the Game Object. + * Sets a gradient line style. This is a WebGL only feature. * - * An invisible Game Object will skip rendering, but will still process update logic. + * The gradient color values represent the 4 corners of an untransformed rectangle. + * The gradient is used to color all stroked shapes and paths drawn after calling this method. + * If you wish to turn a gradient off, call `lineStyle` and provide a new single line color. + * + * This feature is best used only on single lines. All other shapes will give strange results. + * + * Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used + * will be filled with a gradient on its own. There is no ability to gradient stroke a shape or path as a single + * entity at this time. + * @param lineWidth The stroke width. + * @param topLeft The tint being applied to the top-left of the Game Object. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + * @param alpha The fill alpha. Default 1. */ - visible: boolean; + lineGradientStyle(lineWidth: number, topLeft: number, topRight: number, bottomLeft: number, bottomRight: number, alpha?: number): this; /** - * Sets the visibility of this Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. + * Start a new shape path. */ - setVisible(value: boolean): this; - - } + beginPath(): this; - /** - * The Display List plugin. - * - * Display Lists belong to a Scene and maintain the list of Game Objects to render every frame. - * - * Some of these Game Objects may also be part of the Scene's [Update List]{@link Phaser.GameObjects.UpdateList}, for updating. - */ - class DisplayList extends Phaser.Structs.List { /** - * - * @param scene The Scene that this Display List belongs to. + * Close the current path. */ - constructor(scene: Phaser.Scene); + closePath(): this; /** - * The flag the determines whether Game Objects should be sorted when `depthSort()` is called. + * Fill the current path. */ - sortChildrenFlag: boolean; + fillPath(): this; /** - * The Scene that this Display List belongs to. + * Fill the current path. + * + * This is an alias for `Graphics.fillPath` and does the same thing. + * It was added to match the CanvasRenderingContext 2D API. */ - scene: Phaser.Scene; + fill(): this; /** - * The Scene's Systems. + * Stroke the current path. */ - systems: Phaser.Scenes.Systems; + strokePath(): this; /** - * The Scene's Event Emitter. + * Stroke the current path. + * + * This is an alias for `Graphics.strokePath` and does the same thing. + * It was added to match the CanvasRenderingContext 2D API. */ - events: Phaser.Events.EventEmitter; + stroke(): this; /** - * Force a sort of the display list on the next call to depthSort. + * Fill the given circle. + * @param circle The circle to fill. */ - queueDepthSort(): void; + fillCircleShape(circle: Phaser.Geom.Circle): this; /** - * Immediately sorts the display list if the flag is set. + * Stroke the given circle. + * @param circle The circle to stroke. */ - depthSort(): void; + strokeCircleShape(circle: Phaser.Geom.Circle): this; /** - * Compare the depth of two Game Objects. - * @param childA The first Game Object. - * @param childB The second Game Object. + * Fill a circle with the given position and radius. + * @param x The x coordinate of the center of the circle. + * @param y The y coordinate of the center of the circle. + * @param radius The radius of the circle. */ - sortByDepth(childA: Phaser.GameObjects.GameObject, childB: Phaser.GameObjects.GameObject): number; + fillCircle(x: number, y: number, radius: number): this; /** - * Returns an array which contains all objects currently on the Display List. - * This is a reference to the main list array, not a copy of it, so be careful not to modify it. + * Stroke a circle with the given position and radius. + * @param x The x coordinate of the center of the circle. + * @param y The y coordinate of the center of the circle. + * @param radius The radius of the circle. */ - getChildren(): Phaser.GameObjects.GameObject[]; + strokeCircle(x: number, y: number, radius: number): this; - } + /** + * Fill the given rectangle. + * @param rect The rectangle to fill. + */ + fillRectShape(rect: Phaser.Geom.Rectangle): this; - /** - * 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 implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** - * - * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. - * @param x The horizontal position of this DOM Element in the world. Default 0. - * @param y The vertical position of this DOM Element in the world. Default 0. - * @param 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 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 innerText If given, will be set directly as the elements `innerText` property value, replacing whatever was there before. + * Stroke the given rectangle. + * @param rect The rectangle to stroke. */ - constructor(scene: Phaser.Scene, x?: number, y?: number, element?: Element | string, style?: string | any, innerText?: string); + strokeRectShape(rect: Phaser.Geom.Rectangle): this; /** - * A reference to the parent DOM Container that the Game instance created when it started. + * Fill a rectangle with the given position and size. + * @param x The x coordinate of the top-left of the rectangle. + * @param y The y coordinate of the top-left of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. */ - parent: Element; + fillRect(x: number, y: number, width: number, height: number): this; /** - * A reference to the HTML Cache. + * Stroke a rectangle with the given position and size. + * @param x The x coordinate of the top-left of the rectangle. + * @param y The y coordinate of the top-left of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. */ - cache: Phaser.Cache.BaseCache; + strokeRect(x: number, y: number, width: number, height: number): this; /** - * 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. + * Fill a rounded rectangle with the given position, size and radius. + * @param x The x coordinate of the top-left of the rectangle. + * @param y The y coordinate of the top-left of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + * @param radius The corner radius; It can also be an object to specify different radius for corners. Default 20. */ - node: Element; + fillRoundedRect(x: number, y: number, width: number, height: number, radius?: Phaser.Types.GameObjects.Graphics.RoundedRectRadius | number): this; /** - * 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. + * Stroke a rounded rectangle with the given position, size and radius. + * @param x The x coordinate of the top-left of the rectangle. + * @param y The y coordinate of the top-left of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + * @param radius The corner radius; It can also be an object to specify different radii for corners. Default 20. */ - transformOnly: boolean; + strokeRoundedRect(x: number, y: number, width: number, height: number, radius?: Phaser.Types.GameObjects.Graphics.RoundedRectRadius | number): this; /** - * The angle, in radians, by which to skew the DOM Element on the horizontal axis. + * Fill the given point. * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * Draws a square at the given position, 1 pixel in size by default. + * @param point The point to fill. + * @param size The size of the square to draw. Default 1. */ - skewX: number; + fillPointShape(point: Phaser.Geom.Point | Phaser.Math.Vector2 | object, size?: number): this; /** - * The angle, in radians, by which to skew the DOM Element on the vertical axis. + * Fill a point at the given position. * - * https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * Draws a square at the given position, 1 pixel in size by default. + * @param x The x coordinate of the point. + * @param y The y coordinate of the point. + * @param size The size of the square to draw. Default 1. */ - skewY: number; + fillPoint(x: number, y: number, size?: number): this; /** - * 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 + * Fill the given triangle. + * @param triangle The triangle to fill. */ - rotate3d: Phaser.Math.Vector4; + fillTriangleShape(triangle: Phaser.Geom.Triangle): this; /** - * 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 + * Stroke the given triangle. + * @param triangle The triangle to stroke. */ - rotate3dAngle: string; + strokeTriangleShape(triangle: Phaser.Geom.Triangle): this; /** - * Sets the CSS `pointerEvents` attribute on the DOM Element during rendering. - * - * This is 'auto' by default. Changing it may have unintended side-effects with - * internal Phaser input handling, such as dragging, so only change this if you - * understand the implications. + * Fill a triangle with the given points. + * @param x0 The x coordinate of the first point. + * @param y0 The y coordinate of the first point. + * @param x1 The x coordinate of the second point. + * @param y1 The y coordinate of the second point. + * @param x2 The x coordinate of the third point. + * @param y2 The y coordinate of the third point. */ - pointerEvents: string; + fillTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number): this; /** - * 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. + * Stroke a triangle with the given points. + * @param x0 The x coordinate of the first point. + * @param y0 The y coordinate of the first point. + * @param x1 The x coordinate of the second point. + * @param y1 The y coordinate of the second point. + * @param x2 The x coordinate of the third point. + * @param y2 The y coordinate of the third point. */ - readonly width: number; + strokeTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number): this; /** - * 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. + * Draw the given line. + * @param line The line to stroke. */ - readonly height: number; + strokeLineShape(line: Phaser.Geom.Line): this; /** - * 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. + * Draw a line between the given points. + * @param x1 The x coordinate of the start point of the line. + * @param y1 The y coordinate of the start point of the line. + * @param x2 The x coordinate of the end point of the line. + * @param y2 The y coordinate of the end point of the line. */ - readonly displayWidth: number; + lineBetween(x1: number, y1: number, x2: number, y2: number): this; /** - * The computed display height of this Game Object, based on the `getBoundingClientRect` DOM call. + * Draw a line from the current drawing position to the given position. * - * The property `height` holds the un-scaled height of this DOM Element. + * Moves the current drawing position to the given position. + * @param x The x coordinate to draw the line to. + * @param y The y coordinate to draw the line to. */ - readonly displayHeight: number; + lineTo(x: number, y: number): this; /** - * 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 - * @param x The angle, in radians, by which to skew the DOM Element on the horizontal axis. Default 0. - * @param y The angle, in radians, by which to skew the DOM Element on the vertical axis. Default x. + * Move the current drawing position to the given position. + * @param x The x coordinate to move to. + * @param y The y coordinate to move to. */ - setSkew(x?: number, y?: number): this; + moveTo(x: number, y: number): 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. + * Stroke the shape represented by the given array of points. * - * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective + * Pass `closeShape` to automatically close the shape by joining the last to the first point. * - * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** - * @param value The perspective value, in pixels, that determines the distance between the z plane and the user. + * Pass `closePath` to automatically close the path before it is stroked. + * @param points The points to stroke. + * @param closeShape When `true`, the shape is closed by joining the last point to the first point. Default false. + * @param closePath When `true`, the path is closed before being stroked. Default false. + * @param endIndex The index of `points` to stop drawing at. Defaults to `points.length`. */ - setPerspective(value: number): this; + strokePoints(points: any[] | Phaser.Geom.Point[], closeShape?: boolean, closePath?: boolean, endIndex?: number): 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. + * Fill the shape represented by the given array of points. * - * For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective + * Pass `closeShape` to automatically close the shape by joining the last to the first point. * - * **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.** + * Pass `closePath` to automatically close the path before it is filled. + * @param points The points to fill. + * @param closeShape When `true`, the shape is closed by joining the last point to the first point. Default false. + * @param closePath When `true`, the path is closed before being stroked. Default false. + * @param endIndex The index of `points` to stop at. Defaults to `points.length`. */ - perspective: number; + fillPoints(points: any[] | Phaser.Geom.Point[], closeShape?: boolean, closePath?: boolean, endIndex?: number): this; /** - * 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); - * ``` - * @param events The DOM event/s to listen for. You can specify multiple events by separating them with spaces. + * Stroke the given ellipse. + * @param ellipse The ellipse to stroke. + * @param smoothness The number of points to draw the ellipse with. Default 32. */ - addListener(events: string): this; + strokeEllipseShape(ellipse: Phaser.Geom.Ellipse, smoothness?: number): this; /** - * Removes one or more native DOM event listeners from the underlying Element of this Game Object. - * @param events The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces. + * Stroke an ellipse with the given position and size. + * @param x The x coordinate of the center of the ellipse. + * @param y The y coordinate of the center of the ellipse. + * @param width The width of the ellipse. + * @param height The height of the ellipse. + * @param smoothness The number of points to draw the ellipse with. Default 32. */ - removeListener(events: string): this; + strokeEllipse(x: number, y: number, width: number, height: number, smoothness?: number): this; /** - * 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. - * @param 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 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 innerText A DOMString that holds the text that will be set as the innerText of the created element. + * Fill the given ellipse. + * @param ellipse The ellipse to fill. + * @param smoothness The number of points to draw the ellipse with. Default 32. */ - createElement(tagName: string, style?: string | any, innerText?: string): this; + fillEllipseShape(ellipse: Phaser.Geom.Ellipse, smoothness?: number): this; /** - * 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'); - * ``` - * @param element If a string it is passed to `getElementById()`, or it should be a reference to an existing Element. - * @param 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 innerText A DOMString that holds the text that will be set as the innerText of the created element. + * Fill an ellipse with the given position and size. + * @param x The x coordinate of the center of the ellipse. + * @param y The y coordinate of the center of the ellipse. + * @param width The width of the ellipse. + * @param height The height of the ellipse. + * @param smoothness The number of points to draw the ellipse with. Default 32. */ - setElement(element: string | Element, style?: string | any, innerText?: string): this; + fillEllipse(x: number, y: number, width: number, height: number, smoothness?: number): this; /** - * 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'); - * ``` + * Draw an arc. * - * You can create a DOM Element from it using the cache key: + * This method can be used to create circles, or parts of circles. * - * ```javascript - * this.add.dom().createFromCache('login'); - * ``` + * Make sure you call `beginPath` before starting the arc unless you wish for the arc to automatically + * close when filled or stroked. * - * 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. + * Use the optional `overshoot` argument increase the number of iterations that take place when + * the arc is rendered in WebGL. This is useful if you're drawing an arc with an especially thick line, + * as it will allow the arc to fully join-up. Try small values at first, i.e. 0.01. * - * 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. - * @param The key of the html cache entry to use for this DOM Element. - * @param tagName The tag name of the element into which all of the loaded html will be inserted. Defaults to a plain div tag. Default 'div'. + * Call {@link Phaser.GameObjects.Graphics#fillPath} or {@link Phaser.GameObjects.Graphics#strokePath} after calling + * this method to draw the arc. + * @param x The x coordinate of the center of the circle. + * @param y The y coordinate of the center of the circle. + * @param radius The radius of the circle. + * @param startAngle The starting angle, in radians. + * @param endAngle The ending angle, in radians. + * @param anticlockwise Whether the drawing should be anticlockwise or clockwise. Default false. + * @param overshoot This value allows you to increase the segment iterations in WebGL rendering. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly. Use small numbers such as 0.01 to start with and increase as needed. Default 0. */ - createFromCache(The: string, tagName?: string): this; + arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean, overshoot?: number): 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); - * ``` + * Creates a pie-chart slice shape centered at `x`, `y` with the given radius. + * You must define the start and end angle of the slice. * - * 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. + * Setting the `anticlockwise` argument to `true` creates a shape similar to Pacman. + * Setting it to `false` creates a shape like a slice of pie. * - * 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. - * @param html A string of html to be set as the `innerHTML` property of the created element. - * @param tagName The tag name of the element into which all of the html will be inserted. Defaults to a plain div tag. Default 'div'. + * This method will begin a new path and close the path at the end of it. + * To display the actual slice you need to call either `strokePath` or `fillPath` after it. + * @param x The horizontal center of the slice. + * @param y The vertical center of the slice. + * @param radius The radius of the slice. + * @param startAngle The start angle of the slice, given in radians. + * @param endAngle The end angle of the slice, given in radians. + * @param anticlockwise Whether the drawing should be anticlockwise or clockwise. Default false. + * @param overshoot This value allows you to overshoot the endAngle by this amount. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly. Default 0. */ - createFromHTML(html: string, tagName?: string): this; + slice(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean, overshoot?: number): this; /** - * 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`. + * Saves the state of the Graphics by pushing the current state onto a stack. + * + * The most recently saved state can then be restored with {@link Phaser.GameObjects.Graphics#restore}. */ - removeElement(): this; + save(): 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. + * Restores the most recently saved state of the Graphics by popping from the state stack. * - * This is called automatically whenever a new element is created or set. + * Use {@link Phaser.GameObjects.Graphics#save} to save the current state, and call this afterwards to restore that state. + * + * If there is no saved state, this command does nothing. */ - updateSize(): this; + restore(): 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. - * @param property The property to search the children for. - * @param value The value the property must strictly equal. + * Inserts a translation command into this Graphics objects command buffer. + * + * All objects drawn _after_ calling this method will be translated + * by the given amount. + * + * This does not change the position of the Graphics object itself, + * only of the objects drawn by it after calling this method. + * @param x The horizontal translation to apply. + * @param y The vertical translation to apply. */ - getChildByProperty(property: string, value: string): Element; + translateCanvas(x: number, y: number): this; /** - * 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. + * Inserts a scale command into this Graphics objects command buffer. * - * Be aware that class and id names are case-sensitive. - * @param id The id to search the children for. + * All objects drawn _after_ calling this method will be scaled + * by the given amount. + * + * This does not change the scale of the Graphics object itself, + * only of the objects drawn by it after calling this method. + * @param x The horizontal scale to apply. + * @param y The vertical scale to apply. */ - getChildByID(id: string): Element; + scaleCanvas(x: number, y: number): this; /** - * 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. + * Inserts a rotation command into this Graphics objects command buffer. * - * Be aware that class and id names are case-sensitive. - * @param name The name to search the children for. + * All objects drawn _after_ calling this method will be rotated + * by the given amount. + * + * This does not change the rotation of the Graphics object itself, + * only of the objects drawn by it after calling this method. + * @param radians The rotation angle, in radians. */ - getChildByName(name: string): Element; + rotateCanvas(radians: number): this; /** - * Sets the `className` property of the DOM Element node and updates the internal sizes. - * @param className A string representing the class or space-separated classes of the element. + * Clear the command buffer and reset the fill style and line style to their defaults. */ - setClassName(className: string): this; + clear(): this; /** - * Sets the `innerText` property of the DOM Element node and updates the internal sizes. + * Generate a texture from this Graphics object. + * + * If `key` is a string it'll generate a new texture using it and add it into the + * Texture Manager (assuming no key conflict happens). * - * Note that only certain types of Elements can have `innerText` set on them. - * @param text A DOMString representing the rendered text content of the element. + * If `key` is a Canvas it will draw the texture to that canvas context. Note that it will NOT + * automatically upload it to the GPU in WebGL mode. + * + * Please understand that the texture is created via the Canvas API of the browser, therefore some + * Graphics features, such as `fillGradientStyle`, will not appear on the resulting texture, + * as they're unsupported by the Canvas API. + * @param key The key to store the texture with in the Texture Manager, or a Canvas to draw to. + * @param width The width of the graphics to generate. + * @param height The height of the graphics to generate. */ - setText(text: string): this; + generateTexture(key: string | HTMLCanvasElement, width?: number, height?: number): this; /** - * Sets the `innerHTML` property of the DOM Element node and updates the internal sizes. - * @param html A DOMString of html to be set as the `innerHTML` property of the element. + * Internal destroy handler, called as part of the destroy process. */ - setHTML(html: string): this; + protected preDestroy(): void; /** - * 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. + * A Camera used specifically by the Graphics system for rendering to textures. */ - willRender(): boolean; + static TargetCamera: Phaser.Cameras.Scene2D.Camera; /** * Clears all alpha values associated with this Game Object. @@ -15725,6 +21838,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -15739,7 +21853,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -15748,6 +21862,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -15761,12 +21876,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -15788,735 +21903,463 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** - * The horizontal origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the left of the Game Object. - */ - originX: number; - - /** - * The vertical origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the top of the Game Object. - */ - originY: number; - - /** - * The horizontal display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. - */ - displayOriginX: number; - - /** - * The vertical display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. - */ - displayOriginY: number; - - /** - * Sets the origin of this Game Object. - * - * The values are given in the range 0 to 1. - * @param x The horizontal origin value. Default 0.5. - * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. - */ - setOrigin(x?: number, y?: number): this; - - /** - * Sets the origin of this Game Object based on the Pivot values in its Frame. - */ - setOriginFromFrame(): this; - - /** - * Sets the display origin of this Game Object. - * The difference between this and setting the origin is that you can use pixel values for setting the display origin. - * @param x The horizontal display origin value. Default 0. - * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. - */ - setDisplayOrigin(x?: number, y?: number): this; - - /** - * Updates the Display Origin cached values internally stored on this Game Object. - * You don't usually call this directly, but it is exposed for edge-cases where you may. + * The Mask this Game Object is using during render. */ - updateDisplayOrigin(): this; + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; /** - * The horizontal scroll factor of this Game Object. + * Sets the mask that this Game Object will use to render with. * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. + * If a mask is already set on this Game Object it will be immediately replaced. * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * @param mask The mask this Game Object will use when rendering. */ - scrollFactorX: number; + setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; /** - * The vertical scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. + * Clears the mask that this Game Object was using. + * @param destroyMask Destroy the mask before clearing it? Default false. */ - scrollFactorY: number; + clearMask(destroyMask?: boolean): this; /** - * Sets the scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * @param x The horizontal scroll factor of this Game Object. - * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. - */ - setScrollFactor(x: number, y?: number): this; - - /** - * The x position of this Game Object. - */ - x: number; - - /** - * The y position of this Game Object. - */ - y: number; - - /** - * The z position of this Game Object. + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#depth} instead. - */ - z: number; - - /** - * The w position of this Game Object. + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - w: number; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** - * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object - * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. * - * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this - * isn't the case, use the `scaleX` or `scaleY` properties instead. - */ - scale: number; - - /** - * The horizontal scale of this Game Object. - */ - scaleX: number; - - /** - * The vertical scale of this Game Object. - */ - scaleY: number; - - /** - * The angle of this Game Object as expressed in degrees. + * To create the mask you need to pass in a reference to a Graphics Game Object. * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left - * and -90 is up. + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. * - * If you prefer to work in radians, see the `rotation` property instead. + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - angle: number; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** - * The angle of this Game Object in radians. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left - * and -PI/2 is up. + * The initial WebGL pipeline of this Game Object. * - * If you prefer to work in degrees, see the `angle` property instead. + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. */ - rotation: number; + defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * Sets the position of this Game Object. - * @param x The x position of this Game Object. Default 0. - * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. - * @param z The z position of this Game Object. Default 0. - * @param w The w position of this Game Object. Default 0. + * The current WebGL pipeline of this Game Object. */ - setPosition(x?: number, y?: number, z?: number, w?: number): this; + pipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * Copies an object's coordinates to this Game Object's position. - * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + pipelineData: object; /** - * Sets the position of this Game Object to be a random position within the confines of - * the given area. - * - * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * Sets the initial WebGL Pipeline of this Game Object. * - * The position does not factor in the size of this Game Object, meaning that only the origin is - * guaranteed to be within the area. - * @param x The x position of the top-left of the random area. Default 0. - * @param y The y position of the top-left of the random area. Default 0. - * @param width The width of the random area. - * @param height The height of the random area. - */ - setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; - - /** - * Sets the rotation of this Game Object. - * @param radians The rotation of this Game Object, in radians. Default 0. - */ - setRotation(radians?: number): this; - - /** - * Sets the angle of this Game Object. - * @param degrees The rotation of this Game Object, in degrees. Default 0. - */ - setAngle(degrees?: number): this; - - /** - * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. - * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. - */ - setScale(x: number, y?: number): this; - - /** - * Sets the x position of this Game Object. - * @param value The x position of this Game Object. Default 0. - */ - setX(value?: number): this; - - /** - * Sets the y position of this Game Object. - * @param value The y position of this Game Object. Default 0. + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. */ - setY(value?: number): this; + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; /** - * Sets the z position of this Game Object. + * Sets the main WebGL Pipeline of this Game Object. * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. - * @param value The z position of this Game Object. Default 0. - */ - setZ(value?: number): this; - - /** - * Sets the w position of this Game Object. - * @param value The w position of this Game Object. Default 0. - */ - setW(value?: number): this; - - /** - * Gets the local transform matrix for this Game Object. - * @param tempMatrix The matrix to populate with the values from this Game Object. - */ - getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; - - /** - * Gets the world transform matrix for this Game Object, factoring in any parent Containers. - * @param tempMatrix The matrix to populate with the values from this Game Object. - * @param parentMatrix A temporary matrix to hold parent values during the calculations. + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ - getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; /** - * Takes the given `x` and `y` coordinates and converts them into local space for this - * Game Object, taking into account parent and local transforms, and the Display Origin. - * - * The returned Vector2 contains the translated point in its properties. + * Adds an entry to the `pipelineData` object belonging to this Game Object. * - * A Camera needs to be provided in order to handle modified scroll factors. If no - * camera is specified, it will use the `main` camera from the Scene to which this - * Game Object belongs. - * @param x The x position to translate. - * @param y The y position to translate. - * @param point A Vector2, or point-like object, to store the results in. - * @param camera The Camera which is being tested against. If not given will use the Scene default camera. - */ - getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; - - /** - * Gets the sum total rotation of all of this Game Objects parent Containers. + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * - * The returned value is in radians and will be zero if this Game Object has no parent container. + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - getParentRotation(): number; + setPipelineData(key: string, value?: any): this; /** - * The visible state of the Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. */ - visible: boolean; + resetPipeline(resetData?: boolean): boolean; /** - * Sets the visibility of this Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. + * Gets the name of the WebGL Pipeline this Game Object is currently using. */ - setVisible(value: boolean): this; - - } + getPipelineName(): string; - namespace Events { /** - * The Game Object Added to Scene Event. - * - * This event is dispatched when a Game Object is added to a Scene. - * - * Listen for it on a Game Object instance using `GameObject.on('addedtoscene', listener)`. + * Does this Game Object have any Post Pipelines set? */ - const ADDED_TO_SCENE: any; + hasPostPipeline: boolean; /** - * The Game Object Destroy Event. + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. * - * This event is dispatched when a Game Object instance is being destroyed. + * The pipelines are processed in the order in which they appear in this array. * - * Listen for it on a Game Object instance using `GameObject.on('destroy', listener)`. + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. */ - const DESTROY: any; + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; /** - * The Game Object Removed from Scene Event. - * - * This event is dispatched when a Game Object is removed from a Scene. - * - * Listen for it on a Game Object instance using `GameObject.on('removedfromscene', listener)`. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - const REMOVED_FROM_SCENE: any; + postPipelineData: object; /** - * The Video Game Object Complete Event. + * The Pre FX component of this Game Object. * - * This event is dispatched when a Video finishes playback by reaching the end of its duration. It - * is also dispatched if a video marker sequence is being played and reaches the end. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Note that not all videos can fire this event. Live streams, for example, have no fixed duration, - * so never technically 'complete'. + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` * - * If a video is stopped from playback, via the `Video.stop` method, it will emit the - * `VIDEO_STOP` event instead of this one. + * Only the following Game Objects support Pre FX: * - * Listen for it from a Video Game Object instance using `Video.on('complete', listener)`. - */ - const VIDEO_COMPLETE: any; - - /** - * The Video Game Object Created Event. + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video * - * This event is dispatched when the texture for a Video has been created. This happens - * when enough of the video source has been loaded that the browser is able to render a - * frame from it. + * All FX are WebGL only and do not have Canvas counterparts. * - * Listen for it from a Video Game Object instance using `Video.on('created', listener)`. + * Please see the FX Class for more details and available methods. */ - const VIDEO_CREATED: any; + preFX: Phaser.GameObjects.Components.FX | null; /** - * The Video Game Object Error Event. + * The Post FX component of this Game Object. * - * This event is dispatched when a Video tries to play a source that does not exist, or is the wrong file type. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Listen for it from a Video Game Object instance using `Video.on('error', listener)`. - */ - const VIDEO_ERROR: any; - - /** - * The Video Game Object Loop Event. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` * - * This event is dispatched when a Video that is currently playing has looped. This only - * happens if the `loop` parameter was specified, or the `setLoop` method was called, - * and if the video has a fixed duration. Video streams, for example, cannot loop, as - * they have no duration. + * All FX are WebGL only and do not have Canvas counterparts. * - * Looping is based on the result of the Video `timeupdate` event. This event is not - * frame-accurate, due to the way browsers work, so please do not rely on this loop - * event to be time or frame precise. + * Please see the FX Class for more details and available methods. * - * Listen for it from a Video Game Object instance using `Video.on('loop', listener)`. + * This property is always `null` until the `initPostPipeline` method is called. */ - const VIDEO_LOOP: any; + postFX: Phaser.GameObjects.Components.FX; /** - * The Video Game Object Play Event. + * This should only be called during the instantiation of the Game Object. * - * This event is dispatched when a Video begins playback. For videos that do not require - * interaction unlocking, this is usually as soon as the `Video.play` method is called. - * However, for videos that require unlocking, it is fired once playback begins after - * they've been unlocked. + * It is called by default by all core Game Objects and doesn't need + * calling again. * - * Listen for it from a Video Game Object instance using `Video.on('play', listener)`. + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. */ - const VIDEO_PLAY: any; + initPostPipeline(preFX?: boolean): void; /** - * The Video Game Object Seeked Event. + * Sets one, or more, Post Pipelines on this Game Object. * - * This event is dispatched when a Video completes seeking to a new point in its timeline. + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. * - * Listen for it from a Video Game Object instance using `Video.on('seeked', listener)`. - */ - const VIDEO_SEEKED: any; - - /** - * The Video Game Object Seeking Event. + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. * - * This event is dispatched when a Video _begins_ seeking to a new point in its timeline. - * When the seek is complete, it will dispatch the `VIDEO_SEEKED` event to conclude. + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * Listen for it from a Video Game Object instance using `Video.on('seeking', listener)`. + * You can optionally also set the `postPipelineData` property, if the parameter is given. + * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ - const VIDEO_SEEKING: any; + setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * The Video Game Object Stopped Event. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * - * This event is dispatched when a Video is stopped from playback via a call to the `Video.stop` method, - * either directly via game code, or indirectly as the result of changing a video source or destroying it. + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * - * Listen for it from a Video Game Object instance using `Video.on('stop', listener)`. + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - const VIDEO_STOP: any; + setPostPipelineData(key: string, value?: any): this; /** - * The Video Game Object Timeout Event. - * - * This event is dispatched when a Video has exhausted its allocated time while trying to connect to a video - * source to start playback. - * - * Listen for it from a Video Game Object instance using `Video.on('timeout', listener)`. + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * @param pipeline The string-based name of the pipeline, or a pipeline class. */ - const VIDEO_TIMEOUT: any; + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; /** - * The Video Game Object Unlocked Event. - * - * This event is dispatched when a Video that was prevented from playback due to the browsers - * Media Engagement Interaction policy, is unlocked by a user gesture. - * - * Listen for it from a Video Game Object instance using `Video.on('unlocked', listener)`. + * Resets the WebGL Post Pipelines of this Game Object. It does this by calling + * the `destroy` method on each post pipeline and then clearing the local array. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ - const VIDEO_UNLOCKED: any; - - } + resetPostPipeline(resetData?: boolean): void; - /** - * 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 in a 'clean' state, ready for you to bind your own shaders, - * or draw to it, whatever you wish to do. This should all take place in the `render` method. - * The correct way to deploy an Extern object is to create a class that extends it, then - * override the `render` (and optionally `preUpdate`) methods and pass off control to your - * 3rd party libraries or custom WebGL code there. - * - * 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 implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** + * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. * - * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. + * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. + * @param pipeline The string-based name of the pipeline, or a pipeline class. */ - constructor(scene: Phaser.Scene); + removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Clears all alpha values associated with this Game Object. + * Removes all Pre and Post FX Controllers from this Game Object. * - * Immediately sets the alpha levels back to 1 (fully opaque). + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - clearAlpha(): this; + clearFX(): this; /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * - * If your game is running under WebGL you can optionally specify four different alpha values, each of which - * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. - * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. - * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. - * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. - * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. + * A property indicating that a Game Object has this component. */ - setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + readonly hasTransformComponent: boolean; /** - * The alpha value of the Game Object. - * - * This is a global value, impacting the entire Game Object, not just a region of it. + * The x position of this Game Object. */ - alpha: number; + x: number; /** - * The alpha value starting from the top-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * The y position of this Game Object. */ - alphaTopLeft: number; + y: number; /** - * The alpha value starting from the top-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. */ - alphaTopRight: number; + z: number; /** - * The alpha value starting from the bottom-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * The w position of this Game Object. */ - alphaBottomLeft: number; + w: number; /** - * The alpha value starting from the bottom-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. */ - alphaBottomRight: number; + scale: number; /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. - * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency of which blend modes - * are used. + * The horizontal scale of this Game Object. */ - blendMode: Phaser.BlendModes | string; + scaleX: number; /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE (only works when rendering to a framebuffer, like a Render Texture) - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. - * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency in which blend modes - * are used. - * @param value The BlendMode value. Either a string or a CONST. + * The vertical scale of this Game Object. */ - setBlendMode(value: string | Phaser.BlendModes): this; + scaleY: number; /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. + * The angle of this Game Object as expressed in degrees. * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. * - * Setting the depth will queue a depth sort event within the Scene. + * If you prefer to work in radians, see the `rotation` property instead. */ - depth: number; + angle: number; /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. + * The angle of this Game Object in radians. * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. * - * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * If you prefer to work in degrees, see the `angle` property instead. */ - setDepth(value: number): this; + rotation: number; /** - * The horizontally flipped state of the Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. */ - flipX: boolean; + setPosition(x?: number, y?: number, z?: number, w?: number): this; /** - * The vertically flipped state of the Game Object. - * - * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. */ - flipY: boolean; + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; /** - * Toggles the horizontal flipped state of this Game Object. + * Sets the position of this Game Object to be a random position within the confines of + * the given area. * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. */ - toggleFlipX(): this; + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; /** - * Toggles the vertical flipped state of this Game Object. + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. */ - toggleFlipY(): this; + setRotation(radians?: number): this; /** - * Sets the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. */ - setFlipX(value: boolean): this; + setAngle(degrees?: number): this; /** - * Sets the vertical flipped state of this Game Object. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setFlipY(value: boolean): this; + setScale(x?: number, y?: number): this; /** - * Sets the horizontal and vertical flipped state of this Game Object. - * - * A Game Object that is flipped will render inversed on the flipped axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. - * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. */ - setFlip(x: boolean, y: boolean): this; + setX(value?: number): this; /** - * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. */ - resetFlip(): this; + setY(value?: number): this; /** - * The horizontal origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the left of the Game Object. + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. */ - originX: number; + setZ(value?: number): this; /** - * The vertical origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the top of the Game Object. + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. */ - originY: number; + setW(value?: number): this; /** - * The horizontal display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. */ - displayOriginX: number; + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; /** - * The vertical display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. */ - displayOriginY: number; + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; /** - * Sets the origin of this Game Object. + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. * - * The values are given in the range 0 to 1. - * @param x The horizontal origin value. Default 0.5. - * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. + * The returned Vector2 contains the translated point in its properties. + * + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. */ - setOrigin(x?: number, y?: number): this; + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; /** - * Sets the origin of this Game Object based on the Pivot values in its Frame. + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. */ - setOriginFromFrame(): this; + getParentRotation(): number; /** - * Sets the display origin of this Game Object. - * The difference between this and setting the origin is that you can use pixel values for setting the display origin. - * @param x The horizontal display origin value. Default 0. - * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. */ - setDisplayOrigin(x?: number, y?: number): this; + visible: boolean; /** - * Updates the Display Origin cached values internally stored on this Game Object. - * You don't usually call this directly, but it is exposed for edge-cases where you may. + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. */ - updateDisplayOrigin(): this; + setVisible(value: boolean): this; /** * The horizontal scroll factor of this Game Object. @@ -16577,2460 +22420,2155 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; - /** - * The native (un-scaled) width of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. - */ - width: number; - - /** - * The native (un-scaled) height of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. - */ - height: number; - - /** - * The displayed width of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - */ - displayWidth: number; - - /** - * The displayed height of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - */ - displayHeight: number; - - /** - * Sets the size of this Game Object to be that of the given Frame. - * - * This will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or call the - * `setDisplaySize` method, which is the same thing as changing the scale but allows you - * to do so by giving pixel values. - * - * If you have enabled this Game Object for input, changing the size will _not_ change the - * size of the hit area. To do this you should adjust the `input.hitArea` object directly. - * @param frame The frame to base the size of this Game Object on. - */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; - - /** - * Sets the internal size of this Game Object, as used for frame or physics body creation. - * - * This will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or call the - * `setDisplaySize` method, which is the same thing as changing the scale but allows you - * to do so by giving pixel values. - * - * If you have enabled this Game Object for input, changing the size will _not_ change the - * size of the hit area. To do this you should adjust the `input.hitArea` object directly. - * @param width The width of this Game Object. - * @param height The height of this Game Object. - */ - setSize(width: number, height: number): this; - - /** - * Sets the display size of this Game Object. - * - * Calling this will adjust the scale. - * @param width The width of this Game Object. - * @param height The height of this Game Object. - */ - setDisplaySize(width: number, height: number): this; - - /** - * The Texture this Game Object is using to render with. - */ - texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; - - /** - * The Texture Frame this Game Object is using to render with. - */ - frame: Phaser.Textures.Frame; - - /** - * Sets the texture and frame this Game Object will use to render with. - * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. - * @param frame The name or index of the frame within the Texture. - */ - setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; + } + /** + * A Group is a way for you to create, manipulate, or recycle similar Game Objects. + * + * Group membership is non-exclusive. A Game Object can belong to several groups, one group, or none. + * + * Groups themselves aren't displayable, and can't be positioned, rotated, scaled, or hidden. + */ + class Group extends Phaser.Events.EventEmitter { /** - * Sets the frame this Game Object will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. * - * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. - * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. - * @param updateSize Should this call adjust the size of the Game Object? Default true. - * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. - */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; - - /** - * The tint value being applied to the top-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintTopLeft: number; - - /** - * The tint value being applied to the top-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintTopRight: number; - - /** - * The tint value being applied to the bottom-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintBottomLeft: number; - - /** - * The tint value being applied to the bottom-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * @param scene The scene this group belongs to. + * @param children Game Objects to add to this group; or the `config` argument. + * @param config Settings for this group. If `key` is set, Phaser.GameObjects.Group#createMultiple is also called with these settings. */ - tintBottomRight: number; + constructor(scene: Phaser.Scene, children?: Phaser.GameObjects.GameObject[] | Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig, config?: Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig); /** - * The tint fill mode. - * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + * This scene this group belongs to. */ - tintFill: boolean; + scene: Phaser.Scene; /** - * Clears all tint values associated with this Game Object. - * - * Immediately sets the color values back to 0xffffff and the tint type to 'additive', - * which results in no visible change to the texture. + * Members of this group. */ - clearTint(): this; + children: Phaser.Structs.Set; /** - * Sets an additive tint on this Game Object. - * - * The tint works by taking the pixel color values from the Game Objects texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole Game Object will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. - * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. + * A flag identifying this object as a group. */ - setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + isParent: boolean; /** - * Sets a fill-based tint on this Game Object. - * - * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture - * with those in the tint. You can use this for effects such as making a player flash 'white' - * if hit by something. You can provide either one color value, in which case the whole - * Game Object will be rendered in that color. Or you can provide a color per corner. The colors - * are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. - * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. + * A textual representation of this Game Object. + * Used internally by Phaser but is available for your own custom classes to populate. */ - setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + type: string; /** - * The tint value being applied to the whole of the Game Object. - * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. + * The class to create new group members from. */ - tint: number; + classType: Function; /** - * Does this Game Object have a tint applied? - * - * It checks to see if the 4 tint properties are set to the value 0xffffff - * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. + * The name of this group. + * Empty by default and never populated by Phaser, this is left for developers to use. */ - readonly isTinted: boolean; + name: string; /** - * The x position of this Game Object. + * Whether this group runs its {@link Phaser.GameObjects.Group#preUpdate} method (which may update any members). */ - x: number; + active: boolean; /** - * The y position of this Game Object. + * The maximum size of this group, if used as a pool. -1 is no limit. */ - y: number; + maxSize: number; /** - * The z position of this Game Object. + * A default texture key to use when creating new group members. * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#depth} instead. + * This is used in {@link Phaser.GameObjects.Group#create} + * but not in {@link Phaser.GameObjects.Group#createMultiple}. */ - z: number; + defaultKey: string; /** - * The w position of this Game Object. + * A default texture frame to use when creating new group members. */ - w: number; + defaultFrame: string | number; /** - * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object - * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. - * - * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this - * isn't the case, use the `scaleX` or `scaleY` properties instead. + * Whether to call the update method of any members. */ - scale: number; + runChildUpdate: boolean; /** - * The horizontal scale of this Game Object. + * A function to be called when adding or creating group members. */ - scaleX: number; + createCallback: Phaser.Types.GameObjects.Group.GroupCallback | null; /** - * The vertical scale of this Game Object. + * A function to be called when removing group members. */ - scaleY: number; + removeCallback: Phaser.Types.GameObjects.Group.GroupCallback | null; /** - * The angle of this Game Object as expressed in degrees. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left - * and -90 is up. - * - * If you prefer to work in radians, see the `rotation` property instead. + * A function to be called when creating several group members at once. */ - angle: number; + createMultipleCallback: Phaser.Types.GameObjects.Group.GroupMultipleCreateCallback | null; /** - * The angle of this Game Object in radians. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left - * and -PI/2 is up. + * Creates a new Game Object and adds it to this group, unless the group {@link Phaser.GameObjects.Group#isFull is full}. * - * If you prefer to work in degrees, see the `angle` property instead. - */ - rotation: number; - - /** - * Sets the position of this Game Object. - * @param x The x position of this Game Object. Default 0. - * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. - * @param z The z position of this Game Object. Default 0. - * @param w The w position of this Game Object. Default 0. - */ - setPosition(x?: number, y?: number, z?: number, w?: number): this; - - /** - * Copies an object's coordinates to this Game Object's position. - * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + * Calls {@link Phaser.GameObjects.Group#createCallback}. + * @param x The horizontal position of the new Game Object in the world. Default 0. + * @param y The vertical position of the new Game Object in the world. Default 0. + * @param key The texture key of the new Game Object. Default defaultKey. + * @param frame The texture frame of the new Game Object. Default defaultFrame. + * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of the new Game Object. Default true. + * @param active The {@link Phaser.GameObjects.GameObject#active} state of the new Game Object. Default true. */ - copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + create(x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean, active?: boolean): any; /** - * Sets the position of this Game Object to be a random position within the confines of - * the given area. - * - * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * Creates several Game Objects and adds them to this group. * - * The position does not factor in the size of this Game Object, meaning that only the origin is - * guaranteed to be within the area. - * @param x The x position of the top-left of the random area. Default 0. - * @param y The y position of the top-left of the random area. Default 0. - * @param width The width of the random area. - * @param height The height of the random area. + * If the group becomes {@link Phaser.GameObjects.Group#isFull}, no further Game Objects are created. + * + * Calls {@link Phaser.GameObjects.Group#createMultipleCallback} and {@link Phaser.GameObjects.Group#createCallback}. + * @param config Creation settings. This can be a single configuration object or an array of such objects, which will be applied in turn. */ - setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + createMultiple(config: Phaser.Types.GameObjects.Group.GroupCreateConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig[]): any[]; /** - * Sets the rotation of this Game Object. - * @param radians The rotation of this Game Object, in radians. Default 0. + * A helper for {@link Phaser.GameObjects.Group#createMultiple}. + * @param options Creation settings. */ - setRotation(radians?: number): this; + createFromConfig(options: Phaser.Types.GameObjects.Group.GroupCreateConfig): any[]; /** - * Sets the angle of this Game Object. - * @param degrees The rotation of this Game Object, in degrees. Default 0. + * Updates any group members, if {@link Phaser.GameObjects.Group#runChildUpdate} is enabled. + * @param time The current timestamp. + * @param delta The delta time elapsed since the last frame. */ - setAngle(degrees?: number): this; + preUpdate(time: number, delta: number): void; /** - * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. - * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + * Adds a Game Object to this group. + * + * Calls {@link Phaser.GameObjects.Group#createCallback}. + * @param child The Game Object to add. + * @param addToScene Also add the Game Object to the scene. Default false. */ - setScale(x: number, y?: number): this; + add(child: Phaser.GameObjects.GameObject, addToScene?: boolean): this; /** - * Sets the x position of this Game Object. - * @param value The x position of this Game Object. Default 0. + * Adds several Game Objects to this group. + * + * Calls {@link Phaser.GameObjects.Group#createCallback}. + * @param children The Game Objects to add. + * @param addToScene Also add the Game Objects to the scene. Default false. */ - setX(value?: number): this; + addMultiple(children: Phaser.GameObjects.GameObject[], addToScene?: boolean): this; /** - * Sets the y position of this Game Object. - * @param value The y position of this Game Object. Default 0. + * Removes a member of this Group and optionally removes it from the Scene and / or destroys it. + * + * Calls {@link Phaser.GameObjects.Group#removeCallback}. + * @param child The Game Object to remove. + * @param removeFromScene Optionally remove the Group member from the Scene it belongs to. Default false. + * @param destroyChild Optionally call destroy on the removed Group member. Default false. */ - setY(value?: number): this; + remove(child: Phaser.GameObjects.GameObject, removeFromScene?: boolean, destroyChild?: boolean): this; /** - * Sets the z position of this Game Object. + * Removes all members of this Group and optionally removes them from the Scene and / or destroys them. * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. - * @param value The z position of this Game Object. Default 0. + * Does not call {@link Phaser.GameObjects.Group#removeCallback}. + * @param removeFromScene Optionally remove each Group member from the Scene. Default false. + * @param destroyChild Optionally call destroy on the removed Group members. Default false. */ - setZ(value?: number): this; + clear(removeFromScene?: boolean, destroyChild?: boolean): this; /** - * Sets the w position of this Game Object. - * @param value The w position of this Game Object. Default 0. + * Tests if a Game Object is a member of this group. + * @param child A Game Object. */ - setW(value?: number): this; + contains(child: Phaser.GameObjects.GameObject): boolean; /** - * Gets the local transform matrix for this Game Object. - * @param tempMatrix The matrix to populate with the values from this Game Object. + * All members of the group. */ - getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + getChildren(): Phaser.GameObjects.GameObject[]; /** - * Gets the world transform matrix for this Game Object, factoring in any parent Containers. - * @param tempMatrix The matrix to populate with the values from this Game Object. - * @param parentMatrix A temporary matrix to hold parent values during the calculations. + * The number of members of the group. */ - getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + getLength(): number; /** - * Takes the given `x` and `y` coordinates and converts them into local space for this - * Game Object, taking into account parent and local transforms, and the Display Origin. + * Returns all children in this Group that match the given criteria based on the `property` and `value` arguments. * - * The returned Vector2 contains the translated point in its properties. + * For example: `getMatching('visible', true)` would return only children that have their `visible` property set. * - * A Camera needs to be provided in order to handle modified scroll factors. If no - * camera is specified, it will use the `main` camera from the Scene to which this - * Game Object belongs. - * @param x The x position to translate. - * @param y The y position to translate. - * @param point A Vector2, or point-like object, to store the results in. - * @param camera The Camera which is being tested against. If not given will use the Scene default camera. + * Optionally, you can specify a start and end index. For example if the Group has 100 elements, + * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only + * the first 50. + * @param 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 startIndex An optional start index to search from. + * @param endIndex An optional end index to search to. */ - getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + getMatching(property?: string, value?: any, startIndex?: number, endIndex?: number): any[]; /** - * Gets the sum total rotation of all of this Game Objects parent Containers. + * Scans the Group, from top to bottom, for the first member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, + * assigns `x` and `y`, and returns the member. * - * The returned value is in radians and will be zero if this Game Object has no parent container. + * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * @param state The {@link Phaser.GameObjects.GameObject#active} value to match. Default false. + * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. + * @param x The horizontal position of the Game Object in the world. + * @param y The vertical position of the Game Object in the world. + * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. + * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. + * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. */ - getParentRotation(): number; + getFirst(state?: boolean, createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any | null; /** - * The visible state of the Game Object. + * Scans the Group, from top to bottom, for the nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, + * assigns `x` and `y`, and returns the member. * - * An invisible Game Object will skip rendering, but will still process update logic. + * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * @param nth The nth matching Group member to search for. + * @param state The {@link Phaser.GameObjects.GameObject#active} value to match. Default false. + * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. + * @param x The horizontal position of the Game Object in the world. + * @param y The vertical position of the Game Object in the world. + * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. + * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. + * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. */ - visible: boolean; + getFirstNth(nth: number, state?: boolean, createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any | null; /** - * Sets the visibility of this Game Object. + * Scans the Group for the last member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, + * assigns `x` and `y`, and returns the member. * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. + * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * @param state The {@link Phaser.GameObjects.GameObject#active} value to match. Default false. + * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. + * @param x The horizontal position of the Game Object in the world. + * @param y The vertical position of the Game Object in the world. + * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. + * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. + * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. */ - setVisible(value: boolean): this; - - } + getLast(state?: boolean, createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any | null; - /** - * The base class that all Game Objects extend. - * You don't create GameObjects directly and they cannot be added to the display list. - * Instead, use them as the base for your own custom classes. - */ - class GameObject extends Phaser.Events.EventEmitter { /** + * Scans the Group for the last nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, + * assigns `x` and `y`, and returns the member. * - * @param scene The Scene to which this Game Object belongs. - * @param type A textual representation of the type of Game Object, i.e. `sprite`. + * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * @param nth The nth matching Group member to search for. + * @param state The {@link Phaser.GameObjects.GameObject#active} value to match. Default false. + * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. + * @param x The horizontal position of the Game Object in the world. + * @param y The vertical position of the Game Object in the world. + * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. + * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. + * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. */ - constructor(scene: Phaser.Scene, type: string); + getLastNth(nth: number, state?: boolean, createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any | null; /** - * A reference to the Scene to which this Game Object belongs. - * - * Game Objects can only belong to one Scene. + * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`, + * assigns `x` and `y`, and returns the member. * - * You should consider this property as being read-only. You cannot move a - * Game Object to another Scene by simply changing it. + * If no inactive member is found and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. + * The new Game Object will have its active state set to `true`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * @param x The horizontal position of the Game Object in the world. + * @param y The vertical position of the Game Object in the world. + * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. + * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. + * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. */ - scene: Phaser.Scene; + get(x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any | null; /** - * Holds a reference to the Display List that contains this Game Object. - * - * This is set automatically when this Game Object is added to a Scene or Layer. + * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `true`, + * assigns `x` and `y`, and returns the member. * - * You should treat this property as being read-only. + * If no active member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. + * @param x The horizontal position of the Game Object in the world. + * @param y The vertical position of the Game Object in the world. + * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. + * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. + * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. */ - displayList: Phaser.GameObjects.DisplayList | Phaser.GameObjects.Layer; + getFirstAlive(createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any; /** - * A textual representation of this Game Object, i.e. `sprite`. - * Used internally by Phaser but is available for your own custom classes to populate. + * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`, + * assigns `x` and `y`, and returns the member. + * + * If no inactive member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`. + * The new Game Object will have an active state set to `true`. + * Unless a new member is created, `key`, `frame`, and `visible` are ignored. + * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. + * @param x The horizontal position of the Game Object in the world. + * @param y The vertical position of the Game Object in the world. + * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. + * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. + * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. */ - type: string; + getFirstDead(createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any; /** - * The current state of this Game Object. - * - * Phaser itself will never modify this value, although plugins may do so. - * - * Use this property to track the state of a Game Object during its lifetime. For example, it could change from - * a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant - * in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons. - * If you need to store complex data about your Game Object, look at using the Data Component instead. + * {@link Phaser.GameObjects.Components.Animation#play Plays} an animation for all members of this group. + * @param key The string-based key of the animation to play. + * @param startFrame Optionally start the animation playing from this frame index. Default 0. */ - state: number | string; + playAnimation(key: string, startFrame?: string): this; /** - * The parent Container of this Game Object, if it has one. + * Whether this group's size at its {@link Phaser.GameObjects.Group#maxSize maximum}. */ - parentContainer: Phaser.GameObjects.Container; + isFull(): boolean; /** - * The name of this Game Object. - * Empty by default and never populated by Phaser, this is left for developers to use. + * Counts the number of active (or inactive) group members. + * @param value Count active (true) or inactive (false) group members. Default true. */ - name: string; + countActive(value?: boolean): number; /** - * The active state of this Game Object. - * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it. - * An active object is one which is having its logic and internal systems updated. + * Counts the number of in-use (active) group members. */ - active: boolean; + getTotalUsed(): number; /** - * The Tab Index of the Game Object. - * Reserved for future use by plugins and the Input Manager. + * The difference of {@link Phaser.GameObjects.Group#maxSize} and the number of active group members. + * + * This represents the number of group members that could be created or reactivated before reaching the size limit. */ - tabIndex: number; + getTotalFree(): number; /** - * A Data Manager. - * It allows you to store, query and get key/value paired information specific to this Game Object. - * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`. + * Sets the `active` property of this Group. + * When active, this Group runs its `preUpdate` method. + * @param value True if this Group should be set as active, false if not. */ - data: Phaser.Data.DataManager; + setActive(value: boolean): this; /** - * 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. + * Sets the `name` property of this Group. + * The `name` property is not populated by Phaser and is presented for your own use. + * @param value The name to be given to this Group. */ - renderFlags: number; + setName(value: string): this; /** - * 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: + * Sets the property as defined in `key` of each group member to the given value. + * @param key The property to be updated. + * @param value The amount to set the property to. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * @param index An optional offset to start searching from within the items array. Default 0. + * @param direction The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. Default 1. */ - cameraFilter: number; + propertyValueSet(key: string, value: number, step?: number, index?: number, direction?: number): this; /** - * If this Game Object is enabled for input then this property will contain an InteractiveObject instance. - * Not usually set directly. Instead call `GameObject.setInteractive()`. + * Adds the given value to the property as defined in `key` of each group member. + * @param key The property to be updated. + * @param value The amount to set the property to. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * @param index An optional offset to start searching from within the items array. Default 0. + * @param direction The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. Default 1. */ - input: Phaser.Types.Input.InteractiveObject; + propertyValueInc(key: string, value: number, step?: number, index?: number, direction?: number): this; /** - * If this Game Object is enabled for Arcade or Matter Physics then this property will contain a reference to a Physics Body. + * Sets the x of each group member. + * @param value The amount to set the property to. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - body: Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | MatterJS.BodyType; + setX(value: number, step?: number): this; /** - * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`. - * This includes calls that may come from a Group, Container or the Scene itself. - * While it allows you to persist a Game Object across Scenes, please understand you are entirely - * responsible for managing references to and from this Game Object. + * Sets the y of each group member. + * @param value The amount to set the property to. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - ignoreDestroy: boolean; + setY(value: number, step?: number): this; /** - * Sets the `active` property of this Game Object and returns this Game Object for further chaining. - * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList. - * @param value True if this Game Object should be set as active, false if not. + * Sets the x, y of each group member. + * @param x The amount to set the `x` property to. + * @param y The amount to set the `y` property to. If `undefined` or `null` it uses the `x` value. Default x. + * @param stepX This is added to the `x` amount, multiplied by the iteration counter. Default 0. + * @param stepY This is added to the `y` amount, multiplied by the iteration counter. Default 0. */ - setActive(value: boolean): this; + setXY(x: number, y?: number, stepX?: number, stepY?: number): this; /** - * Sets the `name` property of this Game Object and returns this Game Object for further chaining. - * The `name` property is not populated by Phaser and is presented for your own use. - * @param value The name to be given to this Game Object. + * Adds the given value to the x of each group member. + * @param value The amount to be added to the `x` property. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - setName(value: string): this; + incX(value: number, step?: number): this; /** - * Sets the current state of this Game Object. - * - * Phaser itself will never modify the State of a Game Object, although plugins may do so. - * - * For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'. - * The state value should typically be an integer (ideally mapped to a constant - * in your game code), but could also be a string. It is recommended to keep it light and simple. - * If you need to store complex data about your Game Object, look at using the Data Component instead. - * @param value The state of the Game Object. + * Adds the given value to the y of each group member. + * @param value The amount to be added to the `y` property. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - setState(value: number | string): this; + incY(value: number, step?: number): this; /** - * Adds a Data Manager component to this Game Object. + * Adds the given value to the x, y of each group member. + * @param x The amount to be added to the `x` property. + * @param y The amount to be added to the `y` property. If `undefined` or `null` it uses the `x` value. Default x. + * @param stepX This is added to the `x` amount, multiplied by the iteration counter. Default 0. + * @param stepY This is added to the `y` amount, multiplied by the iteration counter. Default 0. */ - setDataEnabled(): this; + incXY(x: number, y?: number, stepX?: number, stepY?: number): this; /** - * Allows you to store a key value pair within this Game Objects Data Manager. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * ```javascript - * sprite.setData('name', 'Red Gem Stone'); - * ``` - * - * You can also pass in an object of key value pairs as the first argument: - * - * ```javascript - * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); - * ``` - * - * To get a value back again you can call `getData`: - * - * ```javascript - * sprite.getData('gold'); - * ``` - * - * Or you can access the value directly via the `values` property, where it works like any other variable: - * - * ```javascript - * sprite.data.values.gold += 50; - * ``` - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * - * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. - * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. - * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. + * Iterate through the group members changing the position of each element to be that of the element that came before + * it in the array (or after it if direction = 1) * - * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. - * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. - * @param key The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. - * @param data The value to set for the given key. If an object is provided as the key this argument is ignored. + * The first group member position is set to x/y. + * @param x The x coordinate to place the first item in the array at. + * @param y The y coordinate to place the first item in the array at. + * @param direction The iteration direction. 0 = first to last and 1 = last to first. Default 0. */ - setData(key: string | object, data?: any): this; + shiftPosition(x: number, y: number, direction?: number): this; /** - * Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * @param key The key to increase the value for. - * @param data The value to increase for the given key. + * Sets the angle of each group member. + * @param value The amount to set the angle to, in degrees. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - incData(key: string | object, data?: any): this; + angle(value: number, step?: number): this; /** - * Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * @param key The key to toggle the value for. + * Sets the rotation of each group member. + * @param value The amount to set the rotation to, in radians. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - toggleData(key: string | object): this; + rotate(value: number, step?: number): this; /** - * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist. - * - * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: - * - * ```javascript - * sprite.getData('gold'); - * ``` - * - * Or access the value directly: - * - * ```javascript - * sprite.data.values.gold; - * ``` - * - * You can also pass in an array of keys, in which case an array of values will be returned: - * - * ```javascript - * sprite.getData([ 'gold', 'armor', 'health' ]); - * ``` - * - * This approach is useful for destructuring arrays in ES6. - * @param key The key of the value to retrieve, or an array of keys. + * Rotates each group member around the given point by the given angle. + * @param point Any object with public `x` and `y` properties. + * @param angle The angle to rotate by, in radians. */ - getData(key: string | string[]): any; + rotateAround(point: Phaser.Types.Math.Vector2Like, angle: number): this; /** - * Pass this Game Object to the Input Manager to enable it for Input. - * - * Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area - * for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced - * input detection. - * - * If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If - * this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific - * shape for it to use. - * - * You can also provide an Input Configuration Object as the only argument to this method. - * @param hitArea Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not given it will try to create a Rectangle based on the texture frame. - * @param callback The callback that determines if the pointer is within the Hit Area shape or not. If you provide a shape you must also provide a callback. - * @param dropZone Should this Game Object be treated as a drop zone target? Default false. + * Rotates each group member around the given point by the given angle and distance. + * @param point Any object with public `x` and `y` properties. + * @param angle The angle to rotate by, in radians. + * @param distance The distance from the point of rotation in pixels. */ - setInteractive(hitArea?: Phaser.Types.Input.InputConfiguration | any, callback?: Phaser.Types.Input.HitAreaCallback, dropZone?: boolean): this; + rotateAroundDistance(point: Phaser.Types.Math.Vector2Like, angle: number, distance: number): this; /** - * If this Game Object has previously been enabled for input, this will disable it. - * - * An object that is disabled for input stops processing or being considered for - * input events, but can be turned back on again at any time by simply calling - * `setInteractive()` with no arguments provided. - * - * If want to completely remove interaction from this Game Object then use `removeInteractive` instead. + * Sets the alpha of each group member. + * @param value The amount to set the alpha to. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - disableInteractive(): this; + setAlpha(value: number, step?: number): this; /** - * If this Game Object has previously been enabled for input, this will queue it - * for removal, causing it to no longer be interactive. The removal happens on - * the next game step, it is not immediate. - * - * The Interactive Object that was assigned to this Game Object will be destroyed, - * removed from the Input Manager and cleared from this Game Object. - * - * If you wish to re-enable this Game Object at a later date you will need to - * re-create its InteractiveObject by calling `setInteractive` again. - * - * If you wish to only temporarily stop an object from receiving input then use - * `disableInteractive` instead, as that toggles the interactive state, where-as - * this erases it completely. - * - * If you wish to resize a hit area, don't remove and then set it as being - * interactive. Instead, access the hitarea object directly and resize the shape - * being used. I.e.: `sprite.input.hitArea.setSize(width, height)` (assuming the - * shape is a Rectangle, which it is by default.) + * Sets the tint of each group member. + * @param topLeft The tint being applied to top-left corner of item. If other parameters are given no value, this tint will be applied to whole item. + * @param topRight The tint to be applied to top-right corner of item. + * @param bottomLeft The tint to be applied to the bottom-left corner of item. + * @param bottomRight The tint to be applied to the bottom-right corner of item. */ - removeInteractive(): this; + setTint(topLeft: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; /** - * This callback is invoked when this Game Object is added to a Scene. - * - * Can be overriden by custom Game Objects, but be aware of some Game Objects that - * will use this, such as Sprites, to add themselves into the Update List. - * - * You can also listen for the `ADDED_TO_SCENE` event from this Game Object. + * Sets the originX, originY of each group member. + * @param originX The amount to set the `originX` property to. + * @param originY The amount to set the `originY` property to. If `undefined` or `null` it uses the `originX` value. + * @param stepX This is added to the `originX` amount, multiplied by the iteration counter. Default 0. + * @param stepY This is added to the `originY` amount, multiplied by the iteration counter. Default 0. + */ + setOrigin(originX: number, originY?: number, stepX?: number, stepY?: number): this; + + /** + * Sets the scaleX of each group member. + * @param value The amount to set the property to. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - addedToScene(): void; + scaleX(value: number, step?: number): this; /** - * This callback is invoked when this Game Object is removed from a Scene. - * - * Can be overriden by custom Game Objects, but be aware of some Game Objects that - * will use this, such as Sprites, to removed themselves from the Update List. - * - * You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object. + * Sets the scaleY of each group member. + * @param value The amount to set the property to. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - removedFromScene(): void; + scaleY(value: number, step?: number): this; /** - * To be overridden by custom GameObjects. Allows base objects to be used in a Pool. - * @param args args + * Sets the scaleX, scaleY of each group member. + * @param scaleX The amount to be added to the `scaleX` property. + * @param scaleY The amount to be added to the `scaleY` property. If `undefined` or `null` it uses the `scaleX` value. + * @param stepX This is added to the `scaleX` amount, multiplied by the iteration counter. Default 0. + * @param stepY This is added to the `scaleY` amount, multiplied by the iteration counter. Default 0. */ - update(...args: any[]): void; + scaleXY(scaleX: number, scaleY?: number, stepX?: number, stepY?: number): this; /** - * Returns a JSON representation of the Game Object. + * Sets the depth of each group member. + * @param value The amount to set the property to. + * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. */ - toJSON(): Phaser.Types.GameObjects.JSONGameObject; + setDepth(value: number, step?: number): this; /** - * Compares the renderMask with the renderFlags to see if this Game Object will render or not. - * Also checks the Game Object against the given Cameras exclusion list. - * @param camera The Camera to check against this Game Object. + * Sets the blendMode of each group member. + * @param value The amount to set the property to. */ - willRender(camera: Phaser.Cameras.Scene2D.Camera): boolean; + setBlendMode(value: number): this; /** - * Returns an array containing the display list index of either this Game Object, or if it has one, - * its parent Container. It then iterates up through all of the parent containers until it hits the - * root of the display list (which is index 0 in the returned array). - * - * Used internally by the InputPlugin but also useful if you wish to find out the display depth of - * this Game Object and all of its ancestors. + * Passes all group members to the Input Manager to enable them for input with identical areas and callbacks. + * @param hitArea Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. + * @param hitAreaCallback A callback to be invoked when the Game Object is interacted with. If you provide a shape you must also provide a callback. */ - getIndexList(): number[]; + setHitArea(hitArea: any, hitAreaCallback: Phaser.Types.Input.HitAreaCallback): this; /** - * Adds this Game Object to the given Display List. - * - * If no Display List is specified, it will default to the Display List owned by the Scene to which - * this Game Object belongs. - * - * A Game Object can only exist on one Display List at any given time, but may move freely between them. - * - * If this Game Object is already on another Display List when this method is called, it will first - * be removed from it, before being added to the new list. - * - * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. - * - * If a Game Object isn't on any display list, it will not be rendered. If you just wish to temporarly - * disable it from rendering, consider using the `setVisible` method, instead. - * @param displayList The Display List to add to. Defaults to the Scene Display List. + * Shuffles the group members in place. */ - addToDisplayList(displayList?: Phaser.GameObjects.DisplayList | Phaser.GameObjects.Layer): this; + shuffle(): this; /** - * Adds this Game Object to the Update List belonging to the Scene. - * - * When a Game Object is added to the Update List it will have its `preUpdate` method called - * every game frame. This method is passed two parameters: `delta` and `time`. - * - * If you wish to run your own logic within `preUpdate` then you should always call - * `preUpdate.super(delta, time)` within it, or it may fail to process required operations, - * such as Sprite animations. + * Deactivates a member of this group. + * @param gameObject A member of this group. */ - addToUpdateList(): this; + kill(gameObject: Phaser.GameObjects.GameObject): void; /** - * Removes this Game Object from the Display List it is currently on. - * - * A Game Object can only exist on one Display List at any given time, but may move freely removed - * and added back at a later stage. - * - * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. - * - * If a Game Object isn't on any Display List, it will not be rendered. If you just wish to temporarly - * disable it from rendering, consider using the `setVisible` method, instead. + * Deactivates and hides a member of this group. + * @param gameObject A member of this group. */ - removeFromDisplayList(): this; + killAndHide(gameObject: Phaser.GameObjects.GameObject): void; /** - * Removes this Game Object from the Scene's Update List. - * - * When a Game Object is on the Update List, it will have its `preUpdate` method called - * every game frame. Calling this method will remove it from the list, preventing this. - * - * Removing a Game Object from the Update List will stop most internal functions working. - * For example, removing a Sprite from the Update List will prevent it from being able to - * run animations. + * Sets the visible of each group member. + * @param value The value to set the property to. + * @param index An optional offset to start searching from within the items array. Default 0. + * @param direction The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. Default 1. */ - removeFromUpdateList(): this; + setVisible(value: boolean, index?: number, direction?: number): this; /** - * Destroys this Game Object removing it from the Display List and Update List and - * severing all ties to parent resources. - * - * Also removes itself from the Input Manager and Physics Manager if previously enabled. - * - * Use this to remove a Game Object from your game if you don't ever plan to use it again. - * As long as no reference to it exists within your own code it should become free for - * garbage collection by the browser. - * - * If you just want to temporarily disable an object then look at using the - * Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected. - * @param fromScene `True` if this Game Object is being destroyed by the Scene, `false` if not. Default false. + * Toggles (flips) the visible state of each member of this group. */ - destroy(fromScene?: boolean): void; + toggleVisible(): this; /** - * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not. + * Empties this Group of all children and removes it from the Scene. + * + * Does not call {@link Phaser.GameObjects.Group#removeCallback}. + * + * Children of this Group will _not_ be removed from the Scene by calling this method + * unless you specify the `removeFromScene` parameter. + * + * Children of this Group will also _not_ be destroyed by calling this method + * unless you specify the `destroyChildren` parameter. + * @param destroyChildren Also {@link Phaser.GameObjects.GameObject#destroy} each Group member. Default false. + * @param removeFromScene Optionally remove each Group member from the Scene. Default false. */ - static readonly RENDER_MASK: number; + destroy(destroyChildren?: boolean, removeFromScene?: boolean): void; } /** - * The Game Object Creator is a Scene plugin that allows you to quickly create many common - * types of Game Objects and return them. Unlike the Game Object Factory, they are not automatically - * added to the Scene. + * An Image Game Object. * - * Game Objects directly register themselves with the Creator and inject their own creation - * methods into the class. + * An Image is a light-weight Game Object useful for the display of static images in your game, + * such as logos, backgrounds, scenery or other non-animated elements. Images can have input + * events and physics bodies, or be tweened, tinted or scrolled. The main difference between an + * Image and a Sprite is that you cannot animate an Image as they do not have the Animation component. */ - class GameObjectCreator { - /** - * - * @param scene The Scene to which this Game Object Factory belongs. - */ - constructor(scene: Phaser.Scene); - + class Image extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.TextureCrop, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** - * Creates a new Dynamic Bitmap Text Game Object and returns it. * - * Note: This method will only be available if the Dynamic Bitmap Text Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. */ - dynamicBitmapText(config: Phaser.Types.GameObjects.BitmapText.BitmapTextConfig, addToScene?: boolean): Phaser.GameObjects.DynamicBitmapText; + constructor(scene: Phaser.Scene, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number); /** - * Creates a new Bitmap Text Game Object and returns it. + * Clears all alpha values associated with this Game Object. * - * Note: This method will only be available if the Bitmap Text Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * Immediately sets the alpha levels back to 1 (fully opaque). */ - bitmapText(config: Phaser.Types.GameObjects.BitmapText.BitmapTextConfig, addToScene?: boolean): Phaser.GameObjects.BitmapText; + clearAlpha(): this; /** - * Creates a new Blitter Game Object and returns it. + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. * - * Note: This method will only be available if the Blitter Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * If your game is running under WebGL you can optionally specify four different alpha values, each of which + * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. + * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. + * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. + * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. + * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. */ - blitter(config: object, addToScene?: boolean): Phaser.GameObjects.Blitter; + setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; /** - * Creates a new Container Game Object and returns it. + * The alpha value of the Game Object. * - * Note: This method will only be available if the Container Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * This is a global value, impacting the entire Game Object, not just a region of it. */ - container(config: object, addToScene?: boolean): Phaser.GameObjects.Container; + alpha: number; /** - * The Scene to which this Game Object Creator belongs. + * The alpha value starting from the top-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. */ - protected scene: Phaser.Scene; + alphaTopLeft: number; /** - * A reference to the Scene.Systems. + * The alpha value starting from the top-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. */ - protected systems: Phaser.Scenes.Systems; + alphaTopRight: number; /** - * A reference to the Scene Event Emitter. + * The alpha value starting from the bottom-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. */ - protected events: Phaser.Events.EventEmitter; + alphaBottomLeft: number; /** - * A reference to the Scene Display List. + * The alpha value starting from the bottom-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. */ - protected displayList: Phaser.GameObjects.DisplayList; + alphaBottomRight: number; /** - * A reference to the Scene Update List. + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. */ - protected updateList: Phaser.GameObjects.UpdateList; + blendMode: Phaser.BlendModes | string | number; /** - * Static method called directly by the Game Object creator functions. - * With this method you can register a custom GameObject factory in the GameObjectCreator, - * providing a name (`factoryType`) and the constructor (`factoryFunction`) in order - * to be called when you invoke Phaser.Scene.make[ factoryType ] method. - * @param factoryType The key of the factory that you will use to call to Phaser.Scene.make[ factoryType ] method. - * @param factoryFunction The constructor function to be called when you invoke to the Phaser.Scene.make method. + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - static register(factoryType: string, factoryFunction: Function): void; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * Static method called directly by the Game Object Creator functions. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * - * With this method you can remove a custom Game Object Creator that has been previously - * registered in the Game Object Creator. Pass in its `factoryType` in order to remove it. - * @param factoryType The key of the factory that you want to remove from the GameObjectCreator. + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. */ - static remove(factoryType: string): void; + depth: number; /** - * Creates a new Graphics Game Object and returns it. + * The depth of this Game Object within the Scene. * - * Note: This method will only be available if the Graphics Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ - graphics(config: object, addToScene?: boolean): Phaser.GameObjects.Graphics; + setDepth(value: number): this; /** - * Creates a new Group Game Object and returns it. + * The horizontally flipped state of the Game Object. * - * Note: This method will only be available if the Group Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. */ - group(config: Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig): Phaser.GameObjects.Group; + flipX: boolean; /** - * Creates a new Image Game Object and returns it. + * The vertically flipped state of the Game Object. * - * Note: This method will only be available if the Image Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. */ - image(config: object, addToScene?: boolean): Phaser.GameObjects.Image; + flipY: boolean; /** - * Creates a new Layer Game Object and returns it. + * Toggles the horizontal flipped state of this Game Object. * - * Note: This method will only be available if the Layer Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. */ - layer(config: object, addToScene?: boolean): Phaser.GameObjects.Layer; + toggleFlipX(): this; /** - * Creates a new Mesh Game Object and returns it. - * - * Note: This method will only be available if the Mesh Game Object and WebGL support have been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * Toggles the vertical flipped state of this Game Object. */ - mesh(config: object, addToScene?: boolean): Phaser.GameObjects.Mesh; + toggleFlipY(): this; /** - * Creates a new Particle Emitter Manager Game Object and returns it. + * Sets the horizontal flipped state of this Game Object. * - * Note: This method will only be available if the Particles Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. */ - particles(config: object, addToScene?: boolean): Phaser.GameObjects.Particles.ParticleEmitterManager; + setFlipX(value: boolean): this; /** - * Creates a new Point Light Game Object and returns it. - * - * Note: This method will only be available if the Point Light Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * Sets the vertical flipped state of this Game Object. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. */ - pointlight(config: object, addToScene?: boolean): Phaser.GameObjects.PointLight; + setFlipY(value: boolean): this; /** - * Creates a new Render Texture Game Object and returns it. + * Sets the horizontal and vertical flipped state of this Game Object. * - * Note: This method will only be available if the Render Texture Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * A Game Object that is flipped will render inversed on the flipped axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. + * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. */ - renderTexture(config: Phaser.Types.GameObjects.RenderTexture.RenderTextureConfig, addToScene?: boolean): Phaser.GameObjects.RenderTexture; + setFlip(x: boolean, y: boolean): this; /** - * Creates a new Rope Game Object and returns it. - * - * Note: This method will only be available if the Rope Game Object and WebGL support have been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. */ - rope(config: object, addToScene?: boolean): Phaser.GameObjects.Rope; + resetFlip(): this; /** - * Creates a new Shader Game Object and returns it. + * Gets the center coordinate of this Game Object, regardless of origin. * - * Note: This method will only be available if the Shader Game Object and WebGL support have been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - shader(config: object, addToScene?: boolean): Phaser.GameObjects.Shader; + getCenter(output?: O, includeParent?: boolean): O; /** - * Creates a new Sprite Game Object and returns it. + * Gets the top-left corner coordinate of this Game Object, regardless of origin. * - * Note: This method will only be available if the Sprite Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - sprite(config: Phaser.Types.GameObjects.Sprite.SpriteConfig, addToScene?: boolean): Phaser.GameObjects.Sprite; + getTopLeft(output?: O, includeParent?: boolean): O; /** - * Creates a new Text Game Object and returns it. + * Gets the top-center coordinate of this Game Object, regardless of origin. * - * Note: This method will only be available if the Text Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - text(config: Phaser.Types.GameObjects.Text.TextConfig, addToScene?: boolean): Phaser.GameObjects.Text; + getTopCenter(output?: O, includeParent?: boolean): O; /** - * Creates a new TileSprite Game Object and returns it. + * Gets the top-right corner coordinate of this Game Object, regardless of origin. * - * Note: This method will only be available if the TileSprite Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - tileSprite(config: Phaser.Types.GameObjects.TileSprite.TileSpriteConfig, addToScene?: boolean): Phaser.GameObjects.TileSprite; + getTopRight(output?: O, includeParent?: boolean): O; /** - * Creates a new Video Game Object and returns it. + * Gets the left-center coordinate of this Game Object, regardless of origin. * - * Note: This method will only be available if the Video Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. - * @param addToScene Add this Game Object to the Scene after creating it? If set this argument overrides the `add` property in the config object. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - video(config: object, addToScene?: boolean): Phaser.GameObjects.Video; + getLeftCenter(output?: O, includeParent?: boolean): O; /** - * Creates a new Zone Game Object and returns it. + * Gets the right-center coordinate of this Game Object, regardless of origin. * - * Note: This method will only be available if the Zone Game Object has been built into Phaser. - * @param config The configuration object this Game Object will use to create itself. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - zone(config: object): Phaser.GameObjects.Zone; + getRightCenter(output?: O, includeParent?: boolean): O; /** - * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. - * When loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing - * from a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map - * data. For an empty map, you should specify tileWidth, tileHeight, width & height. - * @param config The config options for the Tilemap. + * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - tilemap(config?: Phaser.Types.Tilemaps.TilemapConfig): Phaser.Tilemaps.Tilemap; + getBottomLeft(output?: O, includeParent?: boolean): O; /** - * Creates a new Tween object and returns it. + * Gets the bottom-center coordinate of this Game Object, regardless of origin. * - * Note: This method will only be available if Tweens have been built into Phaser. - * @param config The Tween configuration. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - tween(config: Phaser.Types.Tweens.TweenBuilderConfig | object): Phaser.Tweens.Tween; - - } + getBottomCenter(output?: O, includeParent?: boolean): O; - /** - * The Game Object Factory is a Scene plugin that allows you to quickly create many common - * types of Game Objects and have them automatically registered with the Scene. - * - * Game Objects directly register themselves with the Factory and inject their own creation - * methods into the class. - */ - class GameObjectFactory { /** + * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. * - * @param scene The Scene to which this Game Object Factory belongs. + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - constructor(scene: Phaser.Scene); + getBottomRight(output?: O, includeParent?: boolean): O; /** - * Creates a new Path Object. - * @param x The horizontal position of this Path. - * @param y The vertical position of this Path. + * Gets the bounds of this Game Object, regardless of origin. + * + * The values are stored and returned in a Rectangle, or Rectangle-like, object. + * @param output An object to store the values in. If not provided a new Rectangle will be created. */ - path(x: number, y: number): Phaser.Curves.Path; + getBounds(output?: O): O; /** - * Creates a new Dynamic Bitmap Text Game Object and adds it to the Scene. - * - * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. - * - * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to - * match the font structure. - * - * Dynamic Bitmap Text objects are different from Static Bitmap Text in that they invoke a callback for each - * letter being rendered during the render pass. This callback allows you to manipulate the properties of - * each letter being rendered, such as its position, scale or tint, allowing you to create interesting effects - * like jiggling text, which can't be done with Static text. This means that Dynamic Text takes more processing - * time, so only use them if you require the callback ability they have. - * - * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability - * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by - * processing the font texture in an image editor, applying fills and any other effects required. - * - * To create multi-line text insert \r, \n or \r\n escape codes into the text string. - * - * To create a BitmapText data files you need a 3rd party app such as: - * - * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/ - * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner - * Littera (Web-based, free): http://kvazars.com/littera/ - * - * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of - * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: http://codebeautify.org/xmltojson - * - * Note: This method will only be available if the Dynamic Bitmap Text Game Object has been built into Phaser. - * @param x The x position of the Game Object. - * @param y The y position of the Game Object. - * @param font The key of the font to use from the BitmapFont cache. - * @param text The string, or array of strings, to be set as the content of this Bitmap Text. - * @param size The font size to set. + * The Mask this Game Object is using during render. */ - dynamicBitmapText(x: number, y: number, font: string, text?: string | string[], size?: number): Phaser.GameObjects.DynamicBitmapText; + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; /** - * Creates a new Bitmap Text Game Object and adds it to the Scene. - * - * BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure. - * - * During rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to - * match the font structure. - * - * BitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability - * to use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by - * processing the font texture in an image editor, applying fills and any other effects required. - * - * To create multi-line text insert \r, \n or \r\n escape codes into the text string. - * - * To create a BitmapText data files you need a 3rd party app such as: + * Sets the mask that this Game Object will use to render with. * - * BMFont (Windows, free): http://www.angelcode.com/products/bmfont/ - * Glyph Designer (OS X, commercial): http://www.71squared.com/en/glyphdesigner - * Littera (Web-based, free): http://kvazars.com/littera/ + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * - * For most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of - * converting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: http://codebeautify.org/xmltojson + * If a mask is already set on this Game Object it will be immediately replaced. * - * Note: This method will only be available if the Bitmap Text Game Object has been built into Phaser. - * @param x The x position of the Game Object. - * @param y The y position of the Game Object. - * @param font The key of the font to use from the BitmapFont cache. - * @param text The string, or array of strings, to be set as the content of this Bitmap Text. - * @param size The font size to set. - * @param align The alignment of the text in a multi-line BitmapText object. Default 0. - */ - bitmapText(x: number, y: number, font: string, text?: string | string[], size?: number, align?: number): Phaser.GameObjects.BitmapText; - - /** - * Creates a new Blitter Game Object and adds it to the Scene. + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. * - * Note: This method will only be available if the Blitter Game Object has been built into Phaser. - * @param x The x position of the Game Object. - * @param y The y position of the Game Object. - * @param key The key of the Texture the Blitter object will use. - * @param frame The default Frame children of the Blitter will use. + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * @param mask The mask this Game Object will use when rendering. */ - blitter(x: number, y: number, key: string, frame?: string | number): Phaser.GameObjects.Blitter; + setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; /** - * Creates a new Container Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Container Game Object has been built into Phaser. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param children An optional array of Game Objects to add to this Container. + * Clears the mask that this Game Object was using. + * @param destroyMask Destroy the mask before clearing it? Default false. */ - container(x?: number, y?: number, children?: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[]): Phaser.GameObjects.Container; + clearMask(destroyMask?: boolean): this; /** - * 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. - * - * 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. + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. * - * 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. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * - * 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. + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. * - * 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. + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. + */ + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; + + /** + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. * - * Also, all DOM Elements are inserted into the same DOM Container, regardless of which Scene they are created in. + * To create the mask you need to pass in a reference to a Graphics Game Object. * - * 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. + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. * - * Note: This method will only be available if the DOM Element Game Object has been built into Phaser. - * @param x The horizontal position of this DOM Element in the world. - * @param y The vertical position of this DOM Element in the world. - * @param 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 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 innerText If given, will be set directly as the elements `innerText` property value, replacing whatever was there before. + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - dom(x: number, y: number, element?: HTMLElement | string, style?: string | any, innerText?: string): Phaser.GameObjects.DOMElement; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** - * Creates a new Extern Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Extern Game Object has been built into Phaser. + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - extern(): Phaser.GameObjects.Extern; + readonly originX: number; /** - * The Scene to which this Game Object Factory belongs. + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - protected scene: Phaser.Scene; + readonly originY: number; /** - * A reference to the Scene.Systems. + * The horizontal display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. */ - protected systems: Phaser.Scenes.Systems; + displayOriginX: number; /** - * A reference to the Scene Event Emitter. + * The vertical display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. */ - protected events: Phaser.Events.EventEmitter; + displayOriginY: number; /** - * A reference to the Scene Display List. + * Sets the origin of this Game Object. + * + * The values are given in the range 0 to 1. + * @param x The horizontal origin value. Default 0.5. + * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. */ - protected displayList: Phaser.GameObjects.DisplayList; + setOrigin(x?: number, y?: number): this; /** - * A reference to the Scene Update List. + * Sets the origin of this Game Object based on the Pivot values in its Frame. */ - protected updateList: Phaser.GameObjects.UpdateList; + setOriginFromFrame(): this; /** - * Adds an existing Game Object to this Scene. + * Sets the display origin of this Game Object. + * The difference between this and setting the origin is that you can use pixel values for setting the display origin. + * @param x The horizontal display origin value. Default 0. + * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + */ + setDisplayOrigin(x?: number, y?: number): this; + + /** + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. + */ + updateDisplayOrigin(): this; + + /** + * The initial WebGL pipeline of this Game Object. * - * If the Game Object renders, it will be added to the Display List. - * If it has a `preUpdate` method, it will be added to the Update List. - * @param child The child to be added to this Scene. + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. */ - existing(child: G): G; + defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * Static method called directly by the Game Object factory functions. - * With this method you can register a custom GameObject factory in the GameObjectFactory, - * providing a name (`factoryType`) and the constructor (`factoryFunction`) in order - * to be called when you call to Phaser.Scene.add[ factoryType ] method. - * @param factoryType The key of the factory that you will use to call to Phaser.Scene.add[ factoryType ] method. - * @param factoryFunction The constructor function to be called when you invoke to the Phaser.Scene.add method. + * The current WebGL pipeline of this Game Object. */ - static register(factoryType: string, factoryFunction: Function): void; + pipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * Static method called directly by the Game Object factory functions. - * With this method you can remove a custom GameObject factory registered in the GameObjectFactory, - * providing a its `factoryType`. - * @param factoryType The key of the factory that you want to remove from the GameObjectFactory. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - static remove(factoryType: string): void; + pipelineData: object; /** - * Creates a new Graphics Game Object and adds it to the Scene. + * Sets the initial WebGL Pipeline of this Game Object. * - * Note: This method will only be available if the Graphics Game Object has been built into Phaser. - * @param config The Graphics configuration. + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. */ - graphics(config?: Phaser.Types.GameObjects.Graphics.Options): Phaser.GameObjects.Graphics; + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; /** - * Creates a new Group Game Object and adds it to the Scene. + * Sets the main WebGL Pipeline of this Game Object. * - * Note: This method will only be available if the Group Game Object has been built into Phaser. - * @param children Game Objects to add to this Group; or the `config` argument. - * @param config A Group Configuration object. + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ - group(children?: Phaser.GameObjects.GameObject[] | Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupConfig[], config?: Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig): Phaser.GameObjects.Group; + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; /** - * Creates a new Image Game Object and adds it to the Scene. + * Adds an entry to the `pipelineData` object belonging to this Game Object. * - * Note: This method will only be available if the Image Game Object has been built into Phaser. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - image(x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number): Phaser.GameObjects.Image; + setPipelineData(key: string, value?: any): this; /** - * Creates a new Layer Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Layer Game Object has been built into Phaser. - * @param children An optional array of Game Objects to add to this Layer. + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. */ - layer(children?: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[]): Phaser.GameObjects.Layer; + resetPipeline(resetData?: boolean): boolean; /** - * Creates a new Mesh Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Mesh Game Object and WebGL support have been built into Phaser. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. - * @param vertices The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`. - * @param uvs The UVs pairs array. - * @param indicies Optional vertex indicies array. If you don't have one, pass `null` or an empty array. - * @param containsZ Does the vertices data include a `z` component? Default false. - * @param normals Optional vertex normals array. If you don't have one, pass `null` or an empty array. - * @param colors An array of colors, one per vertex, or a single color value applied to all vertices. Default 0xffffff. - * @param alphas An array of alpha values, one per vertex, or a single alpha value applied to all vertices. Default 1. + * Gets the name of the WebGL Pipeline this Game Object is currently using. */ - mesh(x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number, vertices?: number[], uvs?: number[], indicies?: number[], containsZ?: boolean, normals?: number[], colors?: number | number[], alphas?: number | number[]): Phaser.GameObjects.Mesh; + getPipelineName(): string; /** - * Creates a new Particle Emitter Manager Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Particles Game Object has been built into Phaser. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. - * @param emitters Configuration settings for one or more emitters to create. + * Does this Game Object have any Post Pipelines set? */ - particles(texture: string | Phaser.Textures.Texture, frame?: string | number | object, emitters?: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig | Phaser.Types.GameObjects.Particles.ParticleEmitterConfig[]): Phaser.GameObjects.Particles.ParticleEmitterManager; + hasPostPipeline: boolean; /** - * Creates a new PathFollower Game Object and adds it to the Scene. + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. * - * Note: This method will only be available if the PathFollower Game Object has been built into Phaser. - * @param path The Path this PathFollower is connected to. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. + * The pipelines are processed in the order in which they appear in this array. + * + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. */ - follower(path: Phaser.Curves.Path, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number): Phaser.GameObjects.PathFollower; + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; /** - * Creates a new Point Light Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Point Light Game Object has been built into Phaser. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + postPipelineData: object; + + /** + * The Pre FX component of this Game Object. * - * The Point Light Game Object provides a way to add a point light effect into your game, - * without the expensive shader processing requirements of the traditional Light Game Object. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * The difference is that the Point Light renders using a custom shader, designed to give the - * impression of a point light source, of variable radius, intensity and color, in your game. - * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their - * normal maps for calcuations. This makes them extremely fast to render compared to Lights - * and perfect for special effects, such as flickering torches or muzzle flashes. + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` * - * For maximum performance you should batch Point Light Game Objects together. This means - * ensuring they follow each other consecutively on the display list. Ideally, use a Layer - * Game Object and then add just Point Lights to it, so that it can batch together the rendering - * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in - * your game then it's perfectly safe to mix them into the dislay list as normal. However, if - * you're using a large number of them, please consider how they are mixed into the display list. + * Only the following Game Objects support Pre FX: * - * The renderer will automatically cull Point Lights. Those with a radius that does not intersect - * with the Camera will be skipped in the rendering list. This happens automatically and the - * culled state is refreshed every frame, for every camera. + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video * - * The origin of a Point Light is always 0.5 and it cannot be changed. + * All FX are WebGL only and do not have Canvas counterparts. * - * Point Lights are a WebGL only feature and do not have a Canvas counterpart. - * @param x The horizontal position of this Point Light in the world. - * @param y The vertical position of this Point Light in the world. - * @param color The color of the Point Light, given as a hex value. Default 0xffffff. - * @param radius The radius of the Point Light. Default 128. - * @param intensity The intensity, or colr blend, of the Point Light. Default 1. - * @param attenuation The attenuation of the Point Light. This is the reduction of light from the center point. Default 0.1. + * Please see the FX Class for more details and available methods. */ - pointlight(x: number, y: number, color?: number, radius?: number, intensity?: number, attenuation?: number): Phaser.GameObjects.PointLight; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Creates a new Render Texture Game Object and adds it to the Scene. + * The Post FX component of this Game Object. * - * Note: This method will only be available if the Render Texture Game Object has been built into Phaser. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * A Render Texture is a special texture that allows any number of Game Objects to be drawn to it. You can take many complex objects and - * draw them all to this one texture, which can they be used as the texture for other Game Object's. It's a way to generate dynamic - * textures at run-time that are WebGL friendly and don't invoke expensive GPU uploads. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param width The width of the Render Texture. Default 32. - * @param height The height of the Render Texture. Default 32. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - renderTexture(x: number, y: number, width?: number, height?: number): Phaser.GameObjects.RenderTexture; + postFX: Phaser.GameObjects.Components.FX; /** - * Creates a new Rope Game Object and adds it to the Scene. + * This should only be called during the instantiation of the Game Object. * - * Note: This method will only be available if the Rope Game Object and WebGL support have been built into Phaser. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. - * @param points An array containing the vertices data for this Rope. If none is provided a simple quad is created. See `setPoints` to set this post-creation. - * @param horizontal Should the vertices of this Rope be aligned horizontally (`true`), or vertically (`false`)? Default true. - * @param colors An optional array containing the color data for this Rope. You should provide one color value per pair of vertices. - * @param alphas An optional array containing the alpha data for this Rope. You should provide one alpha value per pair of vertices. + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. */ - rope(x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number, points?: Phaser.Types.Math.Vector2Like[], horizontal?: boolean, colors?: number[], alphas?: number[]): Phaser.GameObjects.Rope; + initPostPipeline(preFX?: boolean): void; /** - * Creates a new Shader Game Object and adds it to the Scene. + * Sets one, or more, Post Pipelines on this Game Object. * - * Note: This method will only be available if the Shader Game Object and WebGL support have been built into Phaser. - * @param key The key of the shader to use from the shader cache, or a BaseShader instance. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param width The width of the Game Object. Default 128. - * @param height The height of the Game Object. Default 128. - * @param textures Optional array of texture keys to bind to the iChannel0...3 uniforms. The textures must already exist in the Texture Manager. - * @param textureData Optional additional texture data. + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. + * + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. + * + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * + * You can optionally also set the `postPipelineData` property, if the parameter is given. + * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ - shader(key: string | Phaser.Display.BaseShader, x?: number, y?: number, width?: number, height?: number, textures?: string[], textureData?: object): Phaser.GameObjects.Shader; + setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Creates a new Arc Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Arc Game Object has been built into Phaser. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * - * 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. + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * - * This shape supports both fill and stroke colors. + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPostPipelineData(key: string, value?: any): this; + + /** + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * @param pipeline The string-based name of the pipeline, or a pipeline class. + */ + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + + /** + * Resets the WebGL Post Pipelines of this Game Object. It does this by calling + * the `destroy` method on each post pipeline and then clearing the local array. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. + */ + resetPostPipeline(resetData?: boolean): void; + + /** + * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. * - * 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. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param radius The radius of the arc. Default 128. - * @param startAngle The start angle of the arc, in degrees. Default 0. - * @param endAngle The end angle of the arc, in degrees. Default 360. - * @param anticlockwise The winding order of the start and end angles. Default false. - * @param fillColor The color the arc will be filled with, i.e. 0xff0000 for red. - * @param fillAlpha The alpha the arc will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. + * @param pipeline The string-based name of the pipeline, or a pipeline class. */ - arc(x?: number, y?: number, radius?: number, startAngle?: number, endAngle?: number, anticlockwise?: boolean, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Arc; + removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Creates a new Circle Shape Game Object and adds it to the Scene. + * Removes all Pre and Post FX Controllers from this Game Object. * - * A Circle is an Arc with no defined start and end angle, making it render as a complete circle. + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. * - * Note: This method will only be available if the Arc Game Object has been built into Phaser. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param radius The radius of the circle. Default 128. - * @param fillColor The color the circle will be filled with, i.e. 0xff0000 for red. - * @param fillAlpha The alpha the circle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - circle(x?: number, y?: number, radius?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Arc; + clearFX(): this; /** - * Creates a new Curve Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Curve Game Object has been built into Phaser. + * The horizontal scroll factor of this Game Object. * - * 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. + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. * - * This shape supports both fill and stroke colors. + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. * - * To render a Curve Shape you must first create a `Phaser.Curves.Curve` object, then pass it to - * the Curve Shape in the constructor. + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. * - * 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. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param curve The Curve object to use to create the Shape. - * @param fillColor The color the curve will be filled with, i.e. 0xff0000 for red. - * @param fillAlpha The alpha the curve will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. */ - curve(x?: number, y?: number, curve?: Phaser.Curves.Curve, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Curve; + scrollFactorX: number; /** - * Creates a new Ellipse Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Ellipse Game Object has been built into Phaser. + * The vertical scroll factor of this Game Object. * - * 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. + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. * - * This shape supports both fill and stroke colors. + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. * - * 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. + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. * - * 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. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param width The width of the ellipse. An ellipse with equal width and height renders as a circle. Default 128. - * @param height The height of the ellipse. An ellipse with equal width and height renders as a circle. Default 128. - * @param fillColor The color the ellipse will be filled with, i.e. 0xff0000 for red. - * @param fillAlpha The alpha the ellipse will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. */ - ellipse(x?: number, y?: number, width?: number, height?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Ellipse; + scrollFactorY: number; /** - * Creates a new Grid Shape Game Object and adds it to the Scene. + * Sets the scroll factor of this Game Object. * - * Note: This method will only be available if the Grid Game Object has been built into Phaser. + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. * - * 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. + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. * - * This shape supports only fill colors and cannot be stroked. + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. * - * 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. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param width The width of the grid. Default 128. - * @param height The height of the grid. Default 128. - * @param cellWidth The width of one cell in the grid. Default 32. - * @param cellHeight The height of one cell in the grid. Default 32. - * @param fillColor The color the grid cells will be filled with, i.e. 0xff0000 for red. - * @param 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 outlineFillColor The color of the lines between the grid cells. - * @param outlineFillAlpha The alpha of the lines between the grid cells. + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. */ - grid(x?: number, y?: number, width?: number, height?: number, cellWidth?: number, cellHeight?: number, fillColor?: number, fillAlpha?: number, outlineFillColor?: number, outlineFillAlpha?: number): Phaser.GameObjects.Grid; + setScrollFactor(x: number, y?: number): this; /** - * Creates a new IsoBox Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the IsoBox Game Object has been built into Phaser. + * The native (un-scaled) width of this Game Object. * - * 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. + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. + */ + width: number; + + /** + * The native (un-scaled) height of this Game Object. * - * This shape supports only fill colors and cannot be stroked. + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. + */ + height: number; + + /** + * The displayed width of this Game Object. * - * 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. + * This value takes into account the scale factor. * - * You cannot view an IsoBox from under-neath, however you can change the 'angle' by setting - * the `projection` property. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param size The width of the iso box in pixels. The left and right faces will be exactly half this value. Default 48. - * @param height 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. Default 32. - * @param fillTop The fill color of the top face of the iso box. Default 0xeeeeee. - * @param fillLeft The fill color of the left face of the iso box. Default 0x999999. - * @param fillRight The fill color of the right face of the iso box. Default 0xcccccc. + * Setting this value will adjust the Game Object's scale property. */ - isobox(x?: number, y?: number, size?: number, height?: number, fillTop?: number, fillLeft?: number, fillRight?: number): Phaser.GameObjects.IsoBox; + displayWidth: number; /** - * Creates a new IsoTriangle Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the IsoTriangle Game Object has been built into Phaser. - * - * 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. + * The displayed height of this Game Object. * - * 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. + * This value takes into account the scale factor. * - * 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. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param size The width of the iso triangle in pixels. The left and right faces will be exactly half this value. Default 48. - * @param height 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. Default 32. - * @param reversed Is the iso triangle upside down? Default false. - * @param fillTop The fill color of the top face of the iso triangle. Default 0xeeeeee. - * @param fillLeft The fill color of the left face of the iso triangle. Default 0x999999. - * @param fillRight The fill color of the right face of the iso triangle. Default 0xcccccc. + * Setting this value will adjust the Game Object's scale property. */ - isotriangle(x?: number, y?: number, size?: number, height?: number, reversed?: boolean, fillTop?: number, fillLeft?: number, fillRight?: number): Phaser.GameObjects.IsoTriangle; + displayHeight: number; /** - * Creates a new Line Shape Game Object and adds it to the Scene. + * Sets the size of this Game Object to be that of the given Frame. * - * Note: This method will only be available if the Line Game Object has been built into Phaser. + * 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. * - * 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. + * 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. + * @param frame The frame to base the size of this Game Object on. + */ + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; + + /** + * Sets the internal size of this Game Object, as used for frame or physics body creation. * - * This shape supports only stroke colors and cannot be filled. + * 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. * - * 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 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. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setSize(width: number, height: number): this; + + /** + * Sets the display size of this Game Object. * - * If you need to draw multiple lines in a sequence you may wish to use the Polygon Shape instead. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param x1 The horizontal position of the start of the line. Default 0. - * @param y1 The vertical position of the start of the line. Default 0. - * @param x2 The horizontal position of the end of the line. Default 128. - * @param y2 The vertical position of the end of the line. Default 0. - * @param strokeColor The color the line will be drawn in, i.e. 0xff0000 for red. - * @param strokeAlpha The alpha the line will be drawn in. You can also set the alpha of the overall Shape using its `alpha` property. + * Calling this will adjust the scale. + * @param width The width of this Game Object. + * @param height The height of this Game Object. */ - line(x?: number, y?: number, x1?: number, y1?: number, x2?: number, y2?: number, strokeColor?: number, strokeAlpha?: number): Phaser.GameObjects.Line; + setDisplaySize(width: number, height: number): this; /** - * Creates a new Polygon Shape Game Object and adds it to the Scene. + * The Texture this Game Object is using to render with. + */ + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + + /** + * The Texture Frame this Game Object is using to render with. + */ + frame: Phaser.Textures.Frame; + + /** + * A boolean flag indicating if this Game Object is being cropped or not. + * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. + * Equally, calling `setCrop` with no arguments will reset the crop and disable it. + */ + isCropped: boolean; + + /** + * Applies a crop to a texture based Game Object, such as a Sprite or Image. * - * Note: This method will only be available if the Polygon Game Object has been built into Phaser. + * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. * - * 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. + * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just + * changes what is shown when rendered. * - * This shape supports both fill and stroke colors. + * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. * - * 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: + * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left + * half of it, you could call `setCrop(0, 0, 400, 600)`. * - * - 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], ...]` + * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop + * an area of 200x100 when applied to a Game Object that had a scale factor of 2. * - * 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. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param points The points that make up the polygon. - * @param fillColor The color the polygon will be filled with, i.e. 0xff0000 for red. - * @param fillAlpha The alpha the polygon will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. + * + * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. + * + * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow + * the renderer to skip several internal calculations. + * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. + * @param y The y coordinate to start the crop from. + * @param width The width of the crop rectangle in pixels. + * @param height The height of the crop rectangle in pixels. */ - polygon(x?: number, y?: number, points?: any, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Polygon; + setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; /** - * Creates a new Rectangle Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Rectangle Game Object has been built into Phaser. - * - * 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. + * Sets the texture and frame this Game Object will use to render with. * - * You can change the size of the rectangle by changing the `width` and `height` properties. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param width The width of the rectangle. Default 128. - * @param height The height of the rectangle. Default 128. - * @param fillColor The color the rectangle will be filled with, i.e. 0xff0000 for red. - * @param fillAlpha The alpha the rectangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. */ - rectangle(x?: number, y?: number, width?: number, height?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Rectangle; + setTexture(key: string, frame?: string | number): this; /** - * Creates a new Star Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Star Game Object has been built into Phaser. + * Sets the frame this Game Object will use to render with. * - * 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. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * This shape supports both fill and stroke colors. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * - * 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. + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. * - * 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. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param points The number of points on the star. Default 5. - * @param innerRadius The inner radius of the star. Default 32. - * @param outerRadius The outer radius of the star. Default 64. - * @param fillColor The color the star will be filled with, i.e. 0xff0000 for red. - * @param fillAlpha The alpha the star will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - star(x?: number, y?: number, points?: number, innerRadius?: number, outerRadius?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Star; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** - * Creates a new Triangle Shape Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Triangle Game Object has been built into Phaser. - * - * 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 tint value being applied to the top-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintTopLeft: number; + + /** + * The tint value being applied to the top-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintTopRight: number; + + /** + * The tint value being applied to the bottom-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomLeft: number; + + /** + * The tint value being applied to the bottom-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomRight: number; + + /** + * The tint fill mode. * - * 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. - * @param x The horizontal position of this Game Object in the world. Default 0. - * @param y The vertical position of this Game Object in the world. Default 0. - * @param x1 The horizontal position of the first point in the triangle. Default 0. - * @param y1 The vertical position of the first point in the triangle. Default 128. - * @param x2 The horizontal position of the second point in the triangle. Default 64. - * @param y2 The vertical position of the second point in the triangle. Default 0. - * @param x3 The horizontal position of the third point in the triangle. Default 128. - * @param y3 The vertical position of the third point in the triangle. Default 128. - * @param fillColor The color the triangle will be filled with, i.e. 0xff0000 for red. - * @param fillAlpha The alpha the triangle will be filled with. You can also set the alpha of the overall Shape using its `alpha` property. + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. */ - triangle(x?: number, y?: number, x1?: number, y1?: number, x2?: number, y2?: number, x3?: number, y3?: number, fillColor?: number, fillAlpha?: number): Phaser.GameObjects.Triangle; + tintFill: boolean; /** - * Creates a new Sprite Game Object and adds it to the Scene. + * Clears all tint values associated with this Game Object. * - * Note: This method will only be available if the Sprite Game Object has been built into Phaser. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. + * Immediately sets the color values back to 0xffffff and the tint type to 'additive', + * which results in no visible change to the texture. */ - sprite(x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number): Phaser.GameObjects.Sprite; + clearTint(): this; /** - * Creates a new Text Game Object and adds it to the Scene. + * Sets an additive tint on this Game Object. * - * A Text Game Object. + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole Game Object will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the Game Object. * - * Text objects work by creating their own internal hidden Canvas and then renders text to it using - * the standard Canvas `fillText` API. It then creates a texture from this canvas which is rendered - * to your game during the render pass. + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. * - * Because it uses the Canvas API you can take advantage of all the features this offers, such as - * applying gradient fills to the text, or strokes, shadows and more. You can also use custom fonts - * loaded externally, such as Google or TypeKit Web fonts. + * To remove a tint call `clearTint`. * - * You can only display fonts that are currently loaded and available to the browser: therefore fonts must - * be pre-loaded. Phaser does not do ths for you, so you will require the use of a 3rd party font loader, - * or have the fonts ready available in the CSS on the page in which your Phaser game resides. + * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. + * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + */ + setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + + /** + * Sets a fill-based tint on this Game Object. * - * See {@link http://www.jordanm.co.uk/tinytype this compatibility table} for the available default fonts - * across mobile browsers. + * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture + * with those in the tint. You can use this for effects such as making a player flash 'white' + * if hit by something. You can provide either one color value, in which case the whole + * Game Object will be rendered in that color. Or you can provide a color per corner. The colors + * are blended together across the extent of the Game Object. * - * A note on performance: Every time the contents of a Text object changes, i.e. changing the text being - * displayed, or the style of the text, it needs to remake the Text canvas, and if on WebGL, re-upload the - * new texture to the GPU. This can be an expensive operation if used often, or with large quantities of - * Text objects in your game. If you run into performance issues you would be better off using Bitmap Text - * instead, as it benefits from batching and avoids expensive Canvas API calls. + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. * - * Note: This method will only be available if the Text Game Object has been built into Phaser. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param text The text this Text object will display. - * @param style The Text style configuration object. + * To remove a tint call `clearTint`. + * + * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. + * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. */ - text(x: number, y: number, text: string | string[], style?: Phaser.Types.GameObjects.Text.TextStyle): Phaser.GameObjects.Text; + setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; /** - * Creates a new TileSprite Game Object and adds it to the Scene. - * - * Note: This method will only be available if the TileSprite Game Object has been built into Phaser. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param width The width of the Game Object. If zero it will use the size of the texture frame. - * @param height The height of the Game Object. If zero it will use the size of the texture frame. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. + * The tint value being applied to the whole of the Game Object. + * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. */ - tileSprite(x: number, y: number, width: number, height: number, texture: string | Phaser.Textures.Texture, frame?: string | number): Phaser.GameObjects.TileSprite; + tint: number; /** - * Creates a new Video Game Object and adds it to the Scene. + * Does this Game Object have a tint applied? * - * Note: This method will only be available if the Video Game Object has been built into Phaser. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param key Optional key of the Video this Game Object will play, as stored in the Video Cache. + * It checks to see if the 4 tint properties are set to the value 0xffffff + * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. */ - video(x: number, y: number, key?: string): Phaser.GameObjects.Video; + readonly isTinted: boolean; /** - * Creates a new Zone Game Object and adds it to the Scene. + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + + /** + * The x position of this Game Object. + */ + x: number; + + /** + * The y position of this Game Object. + */ + y: number; + + /** + * The z position of this Game Object. * - * Note: This method will only be available if the Zone Game Object has been built into Phaser. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param width The width of the Game Object. - * @param height The height of the Game Object. + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. */ - zone(x: number, y: number, width: number, height: number): Phaser.GameObjects.Zone; + z: number; /** - * Creates a Tilemap from the given key or data, or creates a blank Tilemap if no key/data provided. - * When loading from CSV or a 2D array, you should specify the tileWidth & tileHeight. When parsing - * from a map from Tiled, the tileWidth, tileHeight, width & height will be pulled from the map - * data. For an empty map, you should specify tileWidth, tileHeight, width & height. - * @param key The key in the Phaser cache that corresponds to the loaded tilemap data. - * @param tileWidth The width of a tile in pixels. Pass in `null` to leave as the - * default. Default 32. - * @param tileHeight The height of a tile in pixels. Pass in `null` to leave as the - * default. Default 32. - * @param width The width of the map in tiles. Pass in `null` to leave as the - * default. Default 10. - * @param height The height of the map in tiles. Pass in `null` to leave as the - * default. Default 10. - * @param data Instead of loading from the cache, you can also load directly from - * a 2D array of tile indexes. Pass in `null` for no data. - * @param 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. Default false. + * The w position of this Game Object. */ - tilemap(key?: string, tileWidth?: number, tileHeight?: number, width?: number, height?: number, data?: number[][], insertNull?: boolean): Phaser.Tilemaps.Tilemap; + w: number; /** - * Creates a new Tween object. + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. * - * Note: This method will only be available if Tweens have been built into Phaser. - * @param config The Tween configuration. + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. */ - tween(config: Phaser.Types.Tweens.TweenBuilderConfig | object): Phaser.Tweens.Tween; + scale: number; - } + /** + * The horizontal scale of this Game Object. + */ + scaleX: number; - /** - * 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. - * @param src The Game Object to calculate the transform matrix for. - * @param camera The camera being used to render the Game Object. - * @param parentMatrix The transform matrix of the parent container, if any. - */ - function GetCalcMatrix(src: Phaser.GameObjects.GameObject, camera: Phaser.Cameras.Scene2D.Camera, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.Types.GameObjects.GetCalcMatrixResults; + /** + * The vertical scale of this Game Object. + */ + scaleY: number; - /** - * A Graphics object is a way to draw primitive shapes to your game. Primitives include forms of geometry, such as - * Rectangles, Circles, and Polygons. They also include lines, arcs and curves. When you initially create a Graphics - * object it will be empty. - * - * To draw to it you must first specify a line style or fill style (or both), draw shapes using paths, and finally - * fill or stroke them. For example: - * - * ```javascript - * graphics.lineStyle(5, 0xFF00FF, 1.0); - * graphics.beginPath(); - * graphics.moveTo(100, 100); - * graphics.lineTo(200, 200); - * graphics.closePath(); - * graphics.strokePath(); - * ``` - * - * There are also many helpful methods that draw and fill/stroke common shapes for you. - * - * ```javascript - * graphics.lineStyle(5, 0xFF00FF, 1.0); - * graphics.fillStyle(0xFFFFFF, 1.0); - * graphics.fillRect(50, 50, 400, 200); - * graphics.strokeRect(50, 50, 400, 200); - * ``` - * - * When a Graphics object is rendered it will render differently based on if the game is running under Canvas or WebGL. - * Under Canvas it will use the HTML Canvas context drawing operations to draw the path. - * Under WebGL the graphics data is decomposed into polygons. Both of these are expensive processes, especially with - * complex shapes. - * - * If your Graphics object doesn't change much (or at all) once you've drawn your shape to it, then you will help - * performance by calling {@link Phaser.GameObjects.Graphics#generateTexture}. This will 'bake' the Graphics object into - * a Texture, and return it. You can then use this Texture for Sprites or other display objects. If your Graphics object - * updates frequently then you should avoid doing this, as it will constantly generate new textures, which will consume - * memory. - * - * As you can tell, Graphics objects are a bit of a trade-off. While they are extremely useful, you need to be careful - * in their complexity and quantity of them in your game. - */ - class Graphics extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible, Phaser.GameObjects.Components.ScrollFactor { /** + * The angle of this Game Object as expressed in degrees. * - * @param scene The Scene to which this Graphics object belongs. - * @param options Options that set the position and default style of this Graphics object. + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. + * + * If you prefer to work in radians, see the `rotation` property instead. */ - constructor(scene: Phaser.Scene, options?: Phaser.Types.GameObjects.Graphics.Options); + angle: number; /** - * The horizontal display origin of the Graphics. + * The angle of this Game Object in radians. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. */ - displayOriginX: number; + rotation: number; /** - * The vertical display origin of the Graphics. + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. */ - displayOriginY: number; + setPosition(x?: number, y?: number, z?: number, w?: number): this; /** - * The array of commands used to render the Graphics. + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. */ - commandBuffer: any[]; + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; /** - * The default fill color for shapes rendered by this Graphics object. + * Sets the position of this Game Object to be a random position within the confines of + * the given area. + * + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. + */ + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + + /** + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. */ - defaultFillColor: number; + setRotation(radians?: number): this; /** - * The default fill alpha for shapes rendered by this Graphics object. + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. */ - defaultFillAlpha: number; + setAngle(degrees?: number): this; /** - * The default stroke width for shapes rendered by this Graphics object. + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + */ + setScale(x?: number, y?: number): this; + + /** + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. */ - defaultStrokeWidth: number; + setX(value?: number): this; /** - * The default stroke color for shapes rendered by this Graphics object. + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. */ - defaultStrokeColor: number; + setY(value?: number): this; /** - * The default stroke alpha for shapes rendered by this Graphics object. + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. */ - defaultStrokeAlpha: number; + setZ(value?: number): this; /** - * Set the default style settings for this Graphics object. - * @param options The styles to set as defaults. + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. */ - setDefaultStyles(options: Phaser.Types.GameObjects.Graphics.Styles): this; + setW(value?: number): this; /** - * Set the current line style. - * @param lineWidth The stroke width. - * @param color The stroke color. - * @param alpha The stroke alpha. Default 1. + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. */ - lineStyle(lineWidth: number, color: number, alpha?: number): this; + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; /** - * Set the current fill style. - * @param color The fill color. - * @param alpha The fill alpha. Default 1. + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. */ - fillStyle(color: number, alpha?: number): this; + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; /** - * Sets a gradient fill style. This is a WebGL only feature. - * - * The gradient color values represent the 4 corners of an untransformed rectangle. - * The gradient is used to color all filled shapes and paths drawn after calling this method. - * If you wish to turn a gradient off, call `fillStyle` and provide a new single fill color. - * - * When filling a triangle only the first 3 color values provided are used for the 3 points of a triangle. + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. * - * This feature is best used only on rectangles and triangles. All other shapes will give strange results. + * The returned Vector2 contains the translated point in its properties. * - * Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used - * will be filled with a gradient on its own. There is no ability to gradient fill a shape or path as a single - * entity at this time. - * @param topLeft The top left fill color. - * @param topRight The top right fill color. - * @param bottomLeft The bottom left fill color. - * @param bottomRight The bottom right fill color. Not used when filling triangles. - * @param alphaTopLeft The top left alpha value. If you give only this value, it's used for all corners. Default 1. - * @param alphaTopRight The top right alpha value. Default 1. - * @param alphaBottomLeft The bottom left alpha value. Default 1. - * @param alphaBottomRight The bottom right alpha value. Default 1. + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. */ - fillGradientStyle(topLeft: number, topRight: number, bottomLeft: number, bottomRight: number, alphaTopLeft?: number, alphaTopRight?: number, alphaBottomLeft?: number, alphaBottomRight?: number): this; + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; /** - * Sets a gradient line style. This is a WebGL only feature. - * - * The gradient color values represent the 4 corners of an untransformed rectangle. - * The gradient is used to color all stroked shapes and paths drawn after calling this method. - * If you wish to turn a gradient off, call `lineStyle` and provide a new single line color. - * - * This feature is best used only on single lines. All other shapes will give strange results. + * Gets the sum total rotation of all of this Game Objects parent Containers. * - * Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used - * will be filled with a gradient on its own. There is no ability to gradient stroke a shape or path as a single - * entity at this time. - * @param lineWidth The stroke width. - * @param topLeft The tint being applied to the top-left of the Game Object. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. - * @param alpha The fill alpha. Default 1. + * The returned value is in radians and will be zero if this Game Object has no parent container. */ - lineGradientStyle(lineWidth: number, topLeft: number, topRight: number, bottomLeft: number, bottomRight: number, alpha?: number): this; + getParentRotation(): number; /** - * Start a new shape path. + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. */ - beginPath(): this; + visible: boolean; /** - * Close the current path. + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. */ - closePath(): this; + setVisible(value: boolean): this; - /** - * Fill the current path. - */ - fillPath(): this; + } + /** + * A Layer Game Object. + * + * A Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object + * to a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game + * Objects: + * + * ```javascript + * const spaceman = this.add.sprite(150, 300, 'spaceman'); + * const bunny = this.add.sprite(400, 300, 'bunny'); + * const elephant = this.add.sprite(650, 300, 'elephant'); + * + * const layer = this.add.layer(); + * + * layer.add([ spaceman, bunny, elephant ]); + * ``` + * + * The 3 sprites in the example above will now be managed by the Layer they were added to. Therefore, + * if you then set `layer.setVisible(false)` they would all vanish from the display. + * + * You can also control the depth of the Game Objects within the Layer. For example, calling the + * `setDepth` method of a child of a Layer will allow you to adjust the depth of that child _within the + * Layer itself_, rather than the whole Scene. The Layer, too, can have its depth set as well. + * + * The Layer class also offers many different methods for manipulating the list, such as the + * methods `moveUp`, `moveDown`, `sendToBack`, `bringToTop` and so on. These allow you to change the + * display list position of the Layers children, causing it to adjust the order in which they are + * rendered. Using `setDepth` on a child allows you to override this. + * + * Layers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across + * a whole range of children, which, depending on the effect, can often be far more efficient that doing so + * on a per-child basis. + * + * Layers have no position or size within the Scene. This means you cannot enable a Layer for + * physics or input, or change the position, rotation or scale of a Layer. They also have no scroll + * factor, texture, tint, origin, crop or bounds. + * + * If you need those kind of features then you should use a Container instead. Containers can be added + * to Layers, but Layers cannot be added to Containers. + * + * However, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings + * will impact all children being rendered by the Layer. + */ + class Layer extends Phaser.Structs.List implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.Visible { /** - * Fill the current path. * - * This is an alias for `Graphics.fillPath` and does the same thing. - * It was added to match the CanvasRenderingContext 2D API. + * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. + * @param children An optional array of Game Objects to add to this Layer. */ - fill(): this; + constructor(scene: Phaser.Scene, children?: Phaser.GameObjects.GameObject[]); /** - * Stroke the current path. + * A reference to the Scene to which this Game Object belongs. + * + * Game Objects can only belong to one Scene. + * + * You should consider this property as being read-only. You cannot move a + * Game Object to another Scene by simply changing it. */ - strokePath(): this; + scene: Phaser.Scene; /** - * Stroke the current path. + * Holds a reference to the Display List that contains this Game Object. * - * This is an alias for `Graphics.strokePath` and does the same thing. - * It was added to match the CanvasRenderingContext 2D API. + * This is set automatically when this Game Object is added to a Scene or Layer. + * + * You should treat this property as being read-only. */ - stroke(): this; + displayList: Phaser.GameObjects.DisplayList | Phaser.GameObjects.Layer; /** - * Fill the given circle. - * @param circle The circle to fill. + * A textual representation of this Game Object, i.e. `sprite`. + * Used internally by Phaser but is available for your own custom classes to populate. */ - fillCircleShape(circle: Phaser.Geom.Circle): this; + type: string; /** - * Stroke the given circle. - * @param circle The circle to stroke. + * The current state of this Game Object. + * + * Phaser itself will never modify this value, although plugins may do so. + * + * Use this property to track the state of a Game Object during its lifetime. For example, it could change from + * a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant + * in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons. + * If you need to store complex data about your Game Object, look at using the Data Component instead. */ - strokeCircleShape(circle: Phaser.Geom.Circle): this; + state: number | string; /** - * Fill a circle with the given position and radius. - * @param x The x coordinate of the center of the circle. - * @param y The y coordinate of the center of the circle. - * @param radius The radius of the circle. + * A Layer cannot be placed inside a Container. + * + * This property is kept purely so a Layer has the same + * shape as a Game Object. */ - fillCircle(x: number, y: number, radius: number): this; + parentContainer: Phaser.GameObjects.Container; /** - * Stroke a circle with the given position and radius. - * @param x The x coordinate of the center of the circle. - * @param y The y coordinate of the center of the circle. - * @param radius The radius of the circle. + * The name of this Game Object. + * Empty by default and never populated by Phaser, this is left for developers to use. */ - strokeCircle(x: number, y: number, radius: number): this; + name: string; /** - * Fill the given rectangle. - * @param rect The rectangle to fill. + * The active state of this Game Object. + * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it. + * An active object is one which is having its logic and internal systems updated. */ - fillRectShape(rect: Phaser.Geom.Rectangle): this; + active: boolean; /** - * Stroke the given rectangle. - * @param rect The rectangle to stroke. + * The Tab Index of the Game Object. + * Reserved for future use by plugins and the Input Manager. */ - strokeRectShape(rect: Phaser.Geom.Rectangle): this; + tabIndex: number; /** - * Fill a rectangle with the given position and size. - * @param x The x coordinate of the top-left of the rectangle. - * @param y The y coordinate of the top-left of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. + * A Data Manager. + * It allows you to store, query and get key/value paired information specific to this Game Object. + * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`. */ - fillRect(x: number, y: number, width: number, height: number): this; + data: Phaser.Data.DataManager; /** - * Stroke a rectangle with the given position and size. - * @param x The x coordinate of the top-left of the rectangle. - * @param y The y coordinate of the top-left of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. + * 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. */ - strokeRect(x: number, y: number, width: number, height: number): this; + renderFlags: number; /** - * Fill a rounded rectangle with the given position, size and radius. - * @param x The x coordinate of the top-left of the rectangle. - * @param y The y coordinate of the top-left of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. - * @param radius The corner radius; It can also be an object to specify different radii for corners. Default 20. + * 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: */ - fillRoundedRect(x: number, y: number, width: number, height: number, radius?: Phaser.Types.GameObjects.Graphics.RoundedRectRadius | number): this; + cameraFilter: number; /** - * Stroke a rounded rectangle with the given position, size and radius. - * @param x The x coordinate of the top-left of the rectangle. - * @param y The y coordinate of the top-left of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. - * @param radius The corner radius; It can also be an object to specify different radii for corners. Default 20. + * This property is kept purely so a Layer has the same + * shape as a Game Object. You cannot input enable a Layer. */ - strokeRoundedRect(x: number, y: number, width: number, height: number, radius?: Phaser.Types.GameObjects.Graphics.RoundedRectRadius | number): this; + input: Phaser.Types.Input.InteractiveObject | null; /** - * Fill the given point. - * - * Draws a square at the given position, 1 pixel in size by default. - * @param point The point to fill. - * @param size The size of the square to draw. Default 1. + * This property is kept purely so a Layer has the same + * shape as a Game Object. You cannot give a Layer a physics body. */ - fillPointShape(point: Phaser.Geom.Point | Phaser.Math.Vector2 | object, size?: number): this; + body: Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | MatterJS.BodyType | null; /** - * Fill a point at the given position. - * - * Draws a square at the given position, 1 pixel in size by default. - * @param x The x coordinate of the point. - * @param y The y coordinate of the point. - * @param size The size of the square to draw. Default 1. + * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`. + * This includes calls that may come from a Group, Container or the Scene itself. + * While it allows you to persist a Game Object across Scenes, please understand you are entirely + * responsible for managing references to and from this Game Object. */ - fillPoint(x: number, y: number, size?: number): this; + ignoreDestroy: boolean; /** - * Fill the given triangle. - * @param triangle The triangle to fill. + * A reference to the Scene Systems. */ - fillTriangleShape(triangle: Phaser.Geom.Triangle): this; + systems: Phaser.Scenes.Systems; /** - * Stroke the given triangle. - * @param triangle The triangle to stroke. + * A reference to the Scene Event Emitter. */ - strokeTriangleShape(triangle: Phaser.Geom.Triangle): this; + events: Phaser.Events.EventEmitter; /** - * Fill a triangle with the given points. - * @param x0 The x coordinate of the first point. - * @param y0 The y coordinate of the first point. - * @param x1 The x coordinate of the second point. - * @param y1 The y coordinate of the second point. - * @param x2 The x coordinate of the third point. - * @param y2 The y coordinate of the third point. + * The flag the determines whether Game Objects should be sorted when `depthSort()` is called. */ - fillTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number): this; + sortChildrenFlag: boolean; /** - * Stroke a triangle with the given points. - * @param x0 The x coordinate of the first point. - * @param y0 The y coordinate of the first point. - * @param x1 The x coordinate of the second point. - * @param y1 The y coordinate of the second point. - * @param x2 The x coordinate of the third point. - * @param y2 The y coordinate of the third point. + * Sets the `active` property of this Game Object and returns this Game Object for further chaining. + * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList. + * @param value True if this Game Object should be set as active, false if not. */ - strokeTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number): this; + setActive(value: boolean): this; /** - * Draw the given line. - * @param line The line to stroke. + * Sets the `name` property of this Game Object and returns this Game Object for further chaining. + * The `name` property is not populated by Phaser and is presented for your own use. + * @param value The name to be given to this Game Object. */ - strokeLineShape(line: Phaser.Geom.Line): this; + setName(value: string): this; /** - * Draw a line between the given points. - * @param x1 The x coordinate of the start point of the line. - * @param y1 The y coordinate of the start point of the line. - * @param x2 The x coordinate of the end point of the line. - * @param y2 The y coordinate of the end point of the line. + * Sets the current state of this Game Object. + * + * Phaser itself will never modify the State of a Game Object, although plugins may do so. + * + * For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'. + * The state value should typically be an integer (ideally mapped to a constant + * in your game code), but could also be a string. It is recommended to keep it light and simple. + * If you need to store complex data about your Game Object, look at using the Data Component instead. + * @param value The state of the Game Object. */ - lineBetween(x1: number, y1: number, x2: number, y2: number): this; + setState(value: number | string): this; /** - * Draw a line from the current drawing position to the given position. - * - * Moves the current drawing position to the given position. - * @param x The x coordinate to draw the line to. - * @param y The y coordinate to draw the line to. + * Adds a Data Manager component to this Game Object. */ - lineTo(x: number, y: number): this; + setDataEnabled(): this; /** - * Move the current drawing position to the given position. - * @param x The x coordinate to move to. - * @param y The y coordinate to move to. + * Allows you to store a key value pair within this Game Objects Data Manager. + * + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. + * + * If the key doesn't already exist in the Data Manager then it is created. + * + * ```javascript + * sprite.setData('name', 'Red Gem Stone'); + * ``` + * + * You can also pass in an object of key value pairs as the first argument: + * + * ```javascript + * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); + * ``` + * + * To get a value back again you can call `getData`: + * + * ```javascript + * sprite.getData('gold'); + * ``` + * + * Or you can access the value directly via the `values` property, where it works like any other variable: + * + * ```javascript + * sprite.data.values.gold += 50; + * ``` + * + * When the value is first set, a `setdata` event is emitted from this Game Object. + * + * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. + * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. + * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. + * + * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. + * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. + * @param key The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. + * @param data The value to set for the given key. If an object is provided as the key this argument is ignored. */ - moveTo(x: number, y: number): this; + setData(key: string | object, data?: any): this; /** - * Stroke the shape represented by the given array of points. + * Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0. * - * Pass `closeShape` to automatically close the shape by joining the last to the first point. + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. * - * Pass `closePath` to automatically close the path before it is stroked. - * @param points The points to stroke. - * @param closeShape When `true`, the shape is closed by joining the last point to the first point. Default false. - * @param closePath When `true`, the path is closed before being stroked. Default false. - * @param endIndex The index of `points` to stop drawing at. Defaults to `points.length`. + * If the key doesn't already exist in the Data Manager then it is created. + * + * When the value is first set, a `setdata` event is emitted from this Game Object. + * @param key The key to increase the value for. + * @param data The value to increase for the given key. */ - strokePoints(points: any[] | Phaser.Geom.Point[], closeShape?: boolean, closePath?: boolean, endIndex?: number): this; + incData(key: string | object, data?: any): this; /** - * Fill the shape represented by the given array of points. + * Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false. * - * Pass `closeShape` to automatically close the shape by joining the last to the first point. + * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled + * before setting the value. * - * Pass `closePath` to automatically close the path before it is filled. - * @param points The points to fill. - * @param closeShape When `true`, the shape is closed by joining the last point to the first point. Default false. - * @param closePath When `true`, the path is closed before being stroked. Default false. - * @param endIndex The index of `points` to stop at. Defaults to `points.length`. + * If the key doesn't already exist in the Data Manager then it is created. + * + * When the value is first set, a `setdata` event is emitted from this Game Object. + * @param key The key to toggle the value for. */ - fillPoints(points: any[] | Phaser.Geom.Point[], closeShape?: boolean, closePath?: boolean, endIndex?: number): this; + toggleData(key: string | object): this; /** - * Stroke the given ellipse. - * @param ellipse The ellipse to stroke. - * @param smoothness The number of points to draw the ellipse with. Default 32. + * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist. + * + * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: + * + * ```javascript + * sprite.getData('gold'); + * ``` + * + * Or access the value directly: + * + * ```javascript + * sprite.data.values.gold; + * ``` + * + * You can also pass in an array of keys, in which case an array of values will be returned: + * + * ```javascript + * sprite.getData([ 'gold', 'armor', 'health' ]); + * ``` + * + * This approach is useful for destructuring arrays in ES6. + * @param key The key of the value to retrieve, or an array of keys. */ - strokeEllipseShape(ellipse: Phaser.Geom.Ellipse, smoothness?: number): this; + getData(key: string | string[]): any; /** - * Stroke an ellipse with the given position and size. - * @param x The x coordinate of the center of the ellipse. - * @param y The y coordinate of the center of the ellipse. - * @param width The width of the ellipse. - * @param height The height of the ellipse. - * @param smoothness The number of points to draw the ellipse with. Default 32. + * A Layer cannot be enabled for input. + * + * This method does nothing and is kept to ensure + * the Layer has the same shape as a Game Object. */ - strokeEllipse(x: number, y: number, width: number, height: number, smoothness?: number): this; + setInteractive(): this; /** - * Fill the given ellipse. - * @param ellipse The ellipse to fill. - * @param smoothness The number of points to draw the ellipse with. Default 32. + * A Layer cannot be enabled for input. + * + * This method does nothing and is kept to ensure + * the Layer has the same shape as a Game Object. */ - fillEllipseShape(ellipse: Phaser.Geom.Ellipse, smoothness?: number): this; + disableInteractive(): this; /** - * Fill an ellipse with the given position and size. - * @param x The x coordinate of the center of the ellipse. - * @param y The y coordinate of the center of the ellipse. - * @param width The width of the ellipse. - * @param height The height of the ellipse. - * @param smoothness The number of points to draw the ellipse with. Default 32. + * A Layer cannot be enabled for input. + * + * This method does nothing and is kept to ensure + * the Layer has the same shape as a Game Object. */ - fillEllipse(x: number, y: number, width: number, height: number, smoothness?: number): this; + removeInteractive(): this; /** - * Draw an arc. + * This callback is invoked when this Game Object is added to a Scene. * - * This method can be used to create circles, or parts of circles. + * Can be overriden by custom Game Objects, but be aware of some Game Objects that + * will use this, such as Sprites, to add themselves into the Update List. * - * Make sure you call `beginPath` before starting the arc unless you wish for the arc to automatically - * close when filled or stroked. + * You can also listen for the `ADDED_TO_SCENE` event from this Game Object. + */ + addedToScene(): void; + + /** + * This callback is invoked when this Game Object is removed from a Scene. * - * Use the optional `overshoot` argument increase the number of iterations that take place when - * the arc is rendered in WebGL. This is useful if you're drawing an arc with an especially thick line, - * as it will allow the arc to fully join-up. Try small values at first, i.e. 0.01. + * Can be overriden by custom Game Objects, but be aware of some Game Objects that + * will use this, such as Sprites, to removed themselves from the Update List. * - * Call {@link Phaser.GameObjects.Graphics#fillPath} or {@link Phaser.GameObjects.Graphics#strokePath} after calling - * this method to draw the arc. - * @param x The x coordinate of the center of the circle. - * @param y The y coordinate of the center of the circle. - * @param radius The radius of the circle. - * @param startAngle The starting angle, in radians. - * @param endAngle The ending angle, in radians. - * @param anticlockwise Whether the drawing should be anticlockwise or clockwise. Default false. - * @param overshoot This value allows you to increase the segment iterations in WebGL rendering. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly. Use small numbers such as 0.01 to start with and increase as needed. Default 0. + * You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object. + */ + removedFromScene(): void; + + /** + * To be overridden by custom GameObjects. Allows base objects to be used in a Pool. + * @param args args */ - arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean, overshoot?: number): this; + update(...args: any[]): void; /** - * Creates a pie-chart slice shape centered at `x`, `y` with the given radius. - * You must define the start and end angle of the slice. - * - * Setting the `anticlockwise` argument to `true` creates a shape similar to Pacman. - * Setting it to `false` creates a shape like a slice of pie. - * - * This method will begin a new path and close the path at the end of it. - * To display the actual slice you need to call either `strokePath` or `fillPath` after it. - * @param x The horizontal center of the slice. - * @param y The vertical center of the slice. - * @param radius The radius of the slice. - * @param startAngle The start angle of the slice, given in radians. - * @param endAngle The end angle of the slice, given in radians. - * @param anticlockwise Whether the drawing should be anticlockwise or clockwise. Default false. - * @param overshoot This value allows you to overshoot the endAngle by this amount. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly. Default 0. + * Returns a JSON representation of the Game Object. */ - slice(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean, overshoot?: number): this; + toJSON(): Phaser.Types.GameObjects.JSONGameObject; /** - * Saves the state of the Graphics by pushing the current state onto a stack. - * - * The most recently saved state can then be restored with {@link Phaser.GameObjects.Graphics#restore}. + * 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. + * @param camera The Camera to check against this Game Object. */ - save(): this; + willRender(camera: Phaser.Cameras.Scene2D.Camera): boolean; /** - * Restores the most recently saved state of the Graphics by popping from the state stack. - * - * Use {@link Phaser.GameObjects.Graphics#save} to save the current state, and call this afterwards to restore that state. + * Returns an array containing the display list index of either this Game Object, or if it has one, + * its parent Container. It then iterates up through all of the parent containers until it hits the + * root of the display list (which is index 0 in the returned array). * - * If there is no saved state, this command does nothing. + * Used internally by the InputPlugin but also useful if you wish to find out the display depth of + * this Game Object and all of its ancestors. */ - restore(): this; + getIndexList(): number[]; /** - * Inserts a translation command into this Graphics objects command buffer. - * - * All objects drawn _after_ calling this method will be translated - * by the given amount. - * - * This does not change the position of the Graphics object itself, - * only of the objects drawn by it after calling this method. - * @param x The horizontal translation to apply. - * @param y The vertical translation to apply. + * Force a sort of the display list on the next call to depthSort. */ - translateCanvas(x: number, y: number): this; + queueDepthSort(): void; /** - * Inserts a scale command into this Graphics objects command buffer. - * - * All objects drawn _after_ calling this method will be scaled - * by the given amount. - * - * This does not change the scale of the Graphics object itself, - * only of the objects drawn by it after calling this method. - * @param x The horizontal scale to apply. - * @param y The vertical scale to apply. + * Immediately sorts the display list if the flag is set. */ - scaleCanvas(x: number, y: number): this; + depthSort(): void; /** - * Inserts a rotation command into this Graphics objects command buffer. - * - * All objects drawn _after_ calling this method will be rotated - * by the given amount. - * - * This does not change the rotation of the Graphics object itself, - * only of the objects drawn by it after calling this method. - * @param radians The rotation angle, in radians. + * Compare the depth of two Game Objects. + * @param childA The first Game Object. + * @param childB The second Game Object. */ - rotateCanvas(radians: number): this; + sortByDepth(childA: Phaser.GameObjects.GameObject, childB: Phaser.GameObjects.GameObject): number; /** - * Clear the command buffer and reset the fill style and line style to their defaults. + * Returns an array which contains all Game Objects within this Layer. + * + * This is a reference to the main list array, not a copy of it, so be careful not to modify it. */ - clear(): this; + getChildren(): Phaser.GameObjects.GameObject[]; /** - * Generate a texture from this Graphics object. + * Adds this Layer to the given Display List. * - * If `key` is a string it'll generate a new texture using it and add it into the - * Texture Manager (assuming no key conflict happens). + * If no Display List is specified, it will default to the Display List owned by the Scene to which + * this Layer belongs. * - * If `key` is a Canvas it will draw the texture to that canvas context. Note that it will NOT - * automatically upload it to the GPU in WebGL mode. + * A Layer can only exist on one Display List at any given time, but may move freely between them. * - * Please understand that the texture is created via the Canvas API of the browser, therefore some - * Graphics features, such as `fillGradientStyle`, will not appear on the resulting texture, - * as they're unsupported by the Canvas API. - * @param key The key to store the texture with in the Texture Manager, or a Canvas to draw to. - * @param width The width of the graphics to generate. - * @param height The height of the graphics to generate. + * If this Layer is already on another Display List when this method is called, it will first + * be removed from it, before being added to the new list. + * + * You can query which list it is on by looking at the `Phaser.GameObjects.Layer#displayList` property. + * + * If a Layer isn't on any display list, it will not be rendered. If you just wish to temporarily + * disable it from rendering, consider using the `setVisible` method, instead. + * @param displayList The Display List to add to. Defaults to the Scene Display List. */ - generateTexture(key: string | HTMLCanvasElement, width?: number, height?: number): this; + addToDisplayList(displayList?: Phaser.GameObjects.DisplayList | Phaser.GameObjects.Layer): this; /** - * Internal destroy handler, called as part of the destroy process. + * Removes this Layer from the Display List it is currently on. + * + * A Layer can only exist on one Display List at any given time, but may move freely removed + * and added back at a later stage. + * + * You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property. + * + * If a Layer isn't on any Display List, it will not be rendered. If you just wish to temporarily + * disable it from rendering, consider using the `setVisible` method, instead. */ - protected preDestroy(): void; + removeFromDisplayList(): this; /** - * A Camera used specifically by the Graphics system for rendering to textures. + * Destroys this Layer removing it from the Display List and Update List and + * severing all ties to parent resources. + * + * Also destroys all children of this Layer. If you do not wish for the + * children to be destroyed, you should move them from this Layer first. + * + * Use this to remove this Layer from your game if you don't ever plan to use it again. + * As long as no reference to it exists within your own code it should become free for + * garbage collection by the browser. + * + * If you just want to temporarily disable an object then look at using the + * Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected. + * @param fromScene `True` if this Game Object is being destroyed by the Scene, `false` if not. Default false. */ - static TargetCamera: Phaser.Cameras.Scene2D.Camera; + destroy(fromScene?: boolean): void; /** * Clears all alpha values associated with this Game Object. @@ -19060,6 +24598,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -19074,7 +24613,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -19083,6 +24622,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -19096,12 +24636,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -19123,7 +24663,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -19157,7 +24697,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -19167,10 +24707,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -19182,21 +24726,9 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. - */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; - - /** - * The initial WebGL pipeline of this Game Object. - * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; - - /** - * The current WebGL pipeline of this Game Object. - */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * Does this Game Object have any Post Pipelines set? @@ -19216,27 +24748,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -19252,27 +24822,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -19280,17 +24846,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -19303,19 +24862,254 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** - * The x position of this Game Object. + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. */ - x: number; + visible: boolean; /** - * The y position of this Game Object. + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. */ - y: number; + setVisible(value: boolean): this; + + } + + /** + * 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. + * + * As of Phaser 3.60 this Game Object now has the Transform and Origin components. However, changing the scale, + * rotation or origin properties will not make any difference to the Light. They are simply present to allow you + * to add this Light to a Container, or enable it for Physics. + */ + class Light extends Phaser.Geom.Circle implements Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + /** + * + * @param x The horizontal position of the light. + * @param y The vertical position of the light. + * @param radius The radius of the light. + * @param r The red color of the light. A value between 0 and 1. + * @param g The green color of the light. A value between 0 and 1. + * @param b The blue color of the light. A value between 0 and 1. + * @param intensity The intensity of the light. + */ + constructor(x: number, y: number, radius: number, r: number, g: number, b: number, intensity: number); + + /** + * The color of the light. + */ + color: Phaser.Display.RGB; + + /** + * The intensity of the light. + */ + intensity: number; + + /** + * 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. + */ + renderFlags: number; + + /** + * 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: + */ + cameraFilter: number; + + /** + * The width of this Light Game Object. This is the same as `Light.diameter`. + */ + displayWidth: number; + + /** + * The height of this Light Game Object. This is the same as `Light.diameter`. + */ + displayHeight: number; + + /** + * The width of this Light Game Object. This is the same as `Light.diameter`. + */ + width: number; + + /** + * The height of this Light Game Object. This is the same as `Light.diameter`. + */ + height: number; + + /** + * 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. + * @param camera The Camera to check against this Game Object. + */ + willRender(camera: Phaser.Cameras.Scene2D.Camera): boolean; + + /** + * Set the color of the light from a single integer RGB value. + * @param rgb The integer RGB color of the light. + */ + setColor(rgb: number): this; + + /** + * Set the intensity of the light. + * @param intensity The intensity of the light. + */ + setIntensity(intensity: number): this; + + /** + * Set the radius of the light. + * @param radius The radius of the light. + */ + setRadius(radius: number): this; + + /** + * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not. + */ + static readonly RENDER_MASK: number; + + /** + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originX: number; + + /** + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originY: number; + + /** + * The horizontal display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginX: number; + + /** + * The vertical display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginY: number; + + /** + * Sets the origin of this Game Object. + * + * The values are given in the range 0 to 1. + * @param x The horizontal origin value. Default 0.5. + * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. + */ + setOrigin(x?: number, y?: number): this; + + /** + * Sets the origin of this Game Object based on the Pivot values in its Frame. + */ + setOriginFromFrame(): this; + + /** + * Sets the display origin of this Game Object. + * The difference between this and setting the origin is that you can use pixel values for setting the display origin. + * @param x The horizontal display origin value. Default 0. + * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + */ + setDisplayOrigin(x?: number, y?: number): this; + + /** + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. + */ + updateDisplayOrigin(): this; + + /** + * The horizontal scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorX: number; + + /** + * The vertical scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorY: number; + + /** + * Sets the scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. + */ + setScrollFactor(x: number, y?: number): this; + + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; /** * The z position of this Game Object. @@ -19369,15 +25163,6 @@ declare namespace Phaser { */ rotation: number; - /** - * Sets the position of this Game Object. - * @param x The x position of this Game Object. Default 0. - * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. - * @param z The z position of this Game Object. Default 0. - * @param w The w position of this Game Object. Default 0. - */ - setPosition(x?: number, y?: number, z?: number, w?: number): this; - /** * Copies an object's coordinates to this Game Object's position. * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. @@ -19413,10 +25198,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -19496,657 +25281,817 @@ declare namespace Phaser { */ setVisible(value: boolean): this; - /** - * The horizontal scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - */ - scrollFactorX: number; - - /** - * The vertical scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - */ - scrollFactorY: number; - - /** - * Sets the scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * @param x The horizontal scroll factor of this Game Object. - * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. - */ - setScrollFactor(x: number, y?: number): this; - } /** - * A Group is a way for you to create, manipulate, or recycle similar Game Objects. - * - * Group membership is non-exclusive. A Game Object can belong to several groups, one group, or none. + * Manages Lights for a Scene. * - * Groups themselves aren't displayable, and can't be positioned, rotated, scaled, or hidden. + * Affects the rendering of Game Objects using the `Light2D` pipeline. */ - class Group extends Phaser.Events.EventEmitter { - /** - * - * @param scene The scene this group belongs to. - * @param children Game Objects to add to this group; or the `config` argument. - * @param config Settings for this group. If `key` is set, Phaser.GameObjects.Group#createMultiple is also called with these settings. - */ - constructor(scene: Phaser.Scene, children?: Phaser.GameObjects.GameObject[] | Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig, config?: Phaser.Types.GameObjects.Group.GroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig); - - /** - * This scene this group belongs to. - */ - scene: Phaser.Scene; - - /** - * Members of this group. - */ - children: Phaser.Structs.Set; - - /** - * A flag identifying this object as a group. - */ - isParent: boolean; - + class LightsManager { /** - * A textual representation of this Game Object. - * Used internally by Phaser but is available for your own custom classes to populate. + * The Lights in the Scene. */ - type: string; + lights: Phaser.GameObjects.Light[]; /** - * The class to create new group members from. + * The ambient color. */ - classType: Function; + ambientColor: Phaser.Display.RGB; /** - * The name of this group. - * Empty by default and never populated by Phaser, this is left for developers to use. + * Whether the Lights Manager is enabled. */ - name: string; + active: boolean; /** - * Whether this group runs its {@link Phaser.GameObjects.Group#preUpdate} method (which may update any members). + * 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. */ - active: boolean; + readonly maxLights: number; /** - * The maximum size of this group, if used as a pool. -1 is no limit. + * The number of lights that the LightPipeline processed in the _previous_ frame. */ - maxSize: number; + readonly visibleLights: number; /** - * A default texture key to use when creating new group members. + * Creates a new Point Light Game Object and adds it to the Scene. * - * This is used in {@link Phaser.GameObjects.Group#create} - * but not in {@link Phaser.GameObjects.Group#createMultiple}. + * Note: This method will only be available if the Point Light Game Object has been built into Phaser. + * + * The Point Light Game Object provides a way to add a point light effect into your game, + * without the expensive shader processing requirements of the traditional Light Game Object. + * + * The difference is that the Point Light renders using a custom shader, designed to give the + * impression of a point light source, of variable radius, intensity and color, in your game. + * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their + * normal maps for calcuations. This makes them extremely fast to render compared to Lights + * and perfect for special effects, such as flickering torches or muzzle flashes. + * + * For maximum performance you should batch Point Light Game Objects together. This means + * ensuring they follow each other consecutively on the display list. Ideally, use a Layer + * Game Object and then add just Point Lights to it, so that it can batch together the rendering + * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in + * your game then it's perfectly safe to mix them into the dislay list as normal. However, if + * you're using a large number of them, please consider how they are mixed into the display list. + * + * The renderer will automatically cull Point Lights. Those with a radius that does not intersect + * with the Camera will be skipped in the rendering list. This happens automatically and the + * culled state is refreshed every frame, for every camera. + * + * The origin of a Point Light is always 0.5 and it cannot be changed. + * + * Point Lights are a WebGL only feature and do not have a Canvas counterpart. + * @param x The horizontal position of this Point Light in the world. + * @param y The vertical position of this Point Light in the world. + * @param color The color of the Point Light, given as a hex value. Default 0xffffff. + * @param radius The radius of the Point Light. Default 128. + * @param intensity The intensity, or color blend, of the Point Light. Default 1. + * @param attenuation The attenuation of the Point Light. This is the reduction of light from the center point. Default 0.1. */ - defaultKey: string; + addPointLight(x: number, y: number, color?: number, radius?: number, intensity?: number, attenuation?: number): Phaser.GameObjects.PointLight; /** - * A default texture frame to use when creating new group members. + * Enable the Lights Manager. */ - defaultFrame: string | number; + enable(): this; /** - * Whether to call the update method of any members. + * Disable the Lights Manager. */ - runChildUpdate: boolean; + disable(): this; /** - * A function to be called when adding or creating group members. + * 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. + * @param camera The Camera to cull Lights for. */ - createCallback: Phaser.Types.GameObjects.Group.GroupCallback; + getLights(camera: Phaser.Cameras.Scene2D.Camera): Phaser.GameObjects.Light[]; /** - * A function to be called when removing group members. + * Set the ambient light color. + * @param rgb The integer RGB color of the ambient light. */ - removeCallback: Phaser.Types.GameObjects.Group.GroupCallback; + setAmbientColor(rgb: number): this; /** - * A function to be called when creating several group members at once. + * Returns the maximum number of Lights allowed to appear at once. */ - createMultipleCallback: Phaser.Types.GameObjects.Group.GroupMultipleCreateCallback; + getMaxVisibleLights(): number; /** - * Creates a new Game Object and adds it to this group, unless the group {@link Phaser.GameObjects.Group#isFull is full}. - * - * Calls {@link Phaser.GameObjects.Group#createCallback}. - * @param x The horizontal position of the new Game Object in the world. Default 0. - * @param y The vertical position of the new Game Object in the world. Default 0. - * @param key The texture key of the new Game Object. Default defaultKey. - * @param frame The texture frame of the new Game Object. Default defaultFrame. - * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of the new Game Object. Default true. - * @param active The {@link Phaser.GameObjects.GameObject#active} state of the new Game Object. Default true. + * Get the number of Lights managed by this Lights Manager. */ - create(x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean, active?: boolean): any; + getLightCount(): number; /** - * Creates several Game Objects and adds them to this group. - * - * If the group becomes {@link Phaser.GameObjects.Group#isFull}, no further Game Objects are created. - * - * Calls {@link Phaser.GameObjects.Group#createMultipleCallback} and {@link Phaser.GameObjects.Group#createCallback}. - * @param config Creation settings. This can be a single configuration object or an array of such objects, which will be applied in turn. + * Add a Light. + * @param x The horizontal position of the Light. Default 0. + * @param y The vertical position of the Light. Default 0. + * @param radius The radius of the Light. Default 128. + * @param rgb The integer RGB color of the light. Default 0xffffff. + * @param intensity The intensity of the Light. Default 1. */ - createMultiple(config: Phaser.Types.GameObjects.Group.GroupCreateConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig[]): any[]; + addLight(x?: number, y?: number, radius?: number, rgb?: number, intensity?: number): Phaser.GameObjects.Light; /** - * A helper for {@link Phaser.GameObjects.Group#createMultiple}. - * @param options Creation settings. + * Remove a Light. + * @param light The Light to remove. */ - createFromConfig(options: Phaser.Types.GameObjects.Group.GroupCreateConfig): any[]; + removeLight(light: Phaser.GameObjects.Light): this; /** - * Updates any group members, if {@link Phaser.GameObjects.Group#runChildUpdate} is enabled. - * @param time The current timestamp. - * @param delta The delta time elapsed since the last frame. + * 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. */ - preUpdate(time: number, delta: number): void; + shutdown(): void; /** - * Adds a Game Object to this group. + * Destroy the Lights Manager. * - * Calls {@link Phaser.GameObjects.Group#createCallback}. - * @param child The Game Object to add. - * @param addToScene Also add the Game Object to the scene. Default false. + * Cleans up all references by calling {@link Phaser.GameObjects.LightsManager#shutdown}. */ - add(child: Phaser.GameObjects.GameObject, addToScene?: boolean): this; + destroy(): void; + + } + /** + * A Scene plugin that provides a {@link Phaser.GameObjects.LightsManager} for the Light2D pipeline. + * + * Available from within a Scene via `this.lights`. + * + * Add Lights using the {@link Phaser.GameObjects.LightsManager#addLight} method: + * + * ```javascript + * // Enable the Lights Manager because it is disabled by default + * this.lights.enable(); + * + * // Create a Light at [400, 300] with a radius of 200 + * this.lights.addLight(400, 300, 200); + * ``` + * + * For Game Objects to be affected by the Lights when rendered, you will need to set them to use the `Light2D` pipeline like so: + * + * ```javascript + * sprite.setPipeline('Light2D'); + * ``` + * + * Note that you cannot use this pipeline on Graphics Game Objects or Shape Game Objects. + */ + class LightsPlugin extends Phaser.GameObjects.LightsManager { /** - * Adds several Game Objects to this group. * - * Calls {@link Phaser.GameObjects.Group#createCallback}. - * @param children The Game Objects to add. - * @param addToScene Also add the Game Objects to the scene. Default false. + * @param scene The Scene that this Lights Plugin belongs to. */ - addMultiple(children: Phaser.GameObjects.GameObject[], addToScene?: boolean): this; + constructor(scene: Phaser.Scene); /** - * Removes a member of this Group and optionally removes it from the Scene and / or destroys it. - * - * Calls {@link Phaser.GameObjects.Group#removeCallback}. - * @param child The Game Object to remove. - * @param removeFromScene Optionally remove the Group member from the Scene it belongs to. Default false. - * @param destroyChild Optionally call destroy on the removed Group member. Default false. + * A reference to the Scene that this Lights Plugin belongs to. */ - remove(child: Phaser.GameObjects.GameObject, removeFromScene?: boolean, destroyChild?: boolean): this; + scene: Phaser.Scene; /** - * Removes all members of this Group and optionally removes them from the Scene and / or destroys them. - * - * Does not call {@link Phaser.GameObjects.Group#removeCallback}. - * @param removeFromScene Optionally remove each Group member from the Scene. Default false. - * @param destroyChild Optionally call destroy on the removed Group members. Default false. + * A reference to the Scene's systems. */ - clear(removeFromScene?: boolean, destroyChild?: boolean): this; + systems: Phaser.Scenes.Systems; /** - * Tests if a Game Object is a member of this group. - * @param child A Game Object. + * Boot the Lights Plugin. */ - contains(child: Phaser.GameObjects.GameObject): boolean; + boot(): void; /** - * All members of the group. + * Destroy the Lights Plugin. + * + * Cleans up all references. */ - getChildren(): Phaser.GameObjects.GameObject[]; + destroy(): void; + + } + /** + * A Mesh Game Object. + * + * The Mesh Game Object allows you to render a group of textured vertices and manipulate + * the view of those vertices, such as rotation, translation or scaling. + * + * Support for generating mesh data from grids, model data or Wavefront OBJ Files is included. + * + * Although you can use this to render 3D objects, its primary use is for displaying more complex + * Sprites, or Sprites where you need fine-grained control over the vertex positions in order to + * achieve special effects in your games. Note that rendering still takes place using Phaser's + * orthographic camera (after being transformed via `projectionMesh`, see `setPerspective`, + * `setOrtho`, and `panZ` methods). As a result, all depth and face tests are done in an eventually + * orthographic space. + * + * The rendering process will iterate through the faces of this Mesh and render out each face + * that is considered as being in view of the camera. No depth buffer is used, and because of this, + * you should be careful not to use model data with too many vertices, or overlapping geometry, + * or you'll probably encounter z-depth fighting. The Mesh was designed to allow for more advanced + * 2D layouts, rather than displaying 3D objects, even though it can do this to a degree. + * + * In short, if you want to remake Crysis, use a 3D engine, not a Mesh. However, if you want + * to easily add some small fun 3D elements into your game, or create some special effects involving + * vertex warping, this is the right object for you. Mesh data becomes part of the WebGL batch, + * just like standard Sprites, so doesn't introduce any additional shader overhead. Because + * the Mesh just generates vertices into the WebGL batch, like any other Sprite, you can use all of + * the common Game Object components on a Mesh too, such as a custom pipeline, mask, blend mode + * or texture. + * + * Note that the Mesh object is WebGL only and does not have a Canvas counterpart. + * + * The Mesh origin is always 0.5 x 0.5 and cannot be changed. + */ + class Mesh extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** - * The number of members of the group. + * + * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. + * @param vertices The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true` (but see note). + * @param uvs The UVs pairs array. + * @param indicies Optional vertex indicies array. If you don't have one, pass `null` or an empty array. + * @param containsZ Does the vertices data include a `z` component? Note: If not, it will be assumed `z=0`, see method `panZ` or `setOrtho`. Default false. + * @param normals Optional vertex normals array. If you don't have one, pass `null` or an empty array. + * @param colors An array of colors, one per vertex, or a single color value applied to all vertices. Default 0xffffff. + * @param alphas An array of alpha values, one per vertex, or a single alpha value applied to all vertices. Default 1. */ - getLength(): number; + constructor(scene: Phaser.Scene, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number, vertices?: number[], uvs?: number[], indicies?: number[], containsZ?: boolean, normals?: number[], colors?: number | number[], alphas?: number | number[]); /** - * Returns all children in this Group that match the given criteria based on the `property` and `value` arguments. + * An array containing the Face instances belonging to this Mesh. * - * For example: `getMatching('visible', true)` would return only children that have their `visible` property set. + * A Face consists of 3 Vertex objects. * - * Optionally, you can specify a start and end index. For example if the Group has 100 elements, - * and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only - * the first 50. - * @param 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 startIndex An optional start index to search from. - * @param endIndex An optional end index to search to. + * This array is populated during calls such as `addVertices` or `addOBJ`. */ - getMatching(property?: string, value?: any, startIndex?: number, endIndex?: number): any[]; + faces: Phaser.Geom.Mesh.Face[]; /** - * Scans the Group, from top to bottom, for the first member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, - * assigns `x` and `y`, and returns the member. + * An array containing Vertex instances. One instance per vertex in this Mesh. * - * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * @param state The {@link Phaser.GameObjects.GameObject#active} value to match. Default false. - * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. - * @param x The horizontal position of the Game Object in the world. - * @param y The vertical position of the Game Object in the world. - * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. - * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. - * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. + * This array is populated during calls such as `addVertex` or `addOBJ`. */ - getFirst(state?: boolean, createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any; + vertices: Phaser.Geom.Mesh.Vertex[]; /** - * Scans the Group, from top to bottom, for the nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, - * assigns `x` and `y`, and returns the member. + * The tint fill mode. * - * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * @param nth The nth matching Group member to search for. - * @param state The {@link Phaser.GameObjects.GameObject#active} value to match. Default false. - * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. - * @param x The horizontal position of the Game Object in the world. - * @param y The vertical position of the Game Object in the world. - * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. - * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. - * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertex colors replace the texture, but respects texture alpha. */ - getFirstNth(nth: number, state?: boolean, createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any; + tintFill: boolean; /** - * Scans the Group for the last member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, - * assigns `x` and `y`, and returns the member. + * You can optionally choose to render the vertices of this Mesh to a Graphics instance. * - * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * @param state The {@link Phaser.GameObjects.GameObject#active} value to match. Default false. - * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. - * @param x The horizontal position of the Game Object in the world. - * @param y The vertical position of the Game Object in the world. - * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. - * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. - * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. + * Achieve this by setting the `debugCallback` and the `debugGraphic` properties. + * + * You can do this in a single call via the `Mesh.setDebug` method, which will use the + * built-in debug function. You can also set it to your own callback. The callback + * will be invoked _once per render_ and sent the following parameters: + * + * `debugCallback(src, meshLength, verts)` + * + * `src` is the Mesh instance being debugged. + * `meshLength` is the number of mesh vertices in total. + * `verts` is an array of the translated vertex coordinates. + * + * To disable rendering, set this property back to `null`. + * + * Please note that high vertex count Meshes will struggle to debug properly. */ - getLast(state?: boolean, createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any; + debugCallback: Function; /** - * Scans the Group for the last nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument, - * assigns `x` and `y`, and returns the member. - * - * If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * @param nth The nth matching Group member to search for. - * @param state The {@link Phaser.GameObjects.GameObject#active} value to match. Default false. - * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. - * @param x The horizontal position of the Game Object in the world. - * @param y The vertical position of the Game Object in the world. - * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. - * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. - * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. + * The Graphics instance that the debug vertices will be drawn to, if `setDebug` has + * been called. */ - getLastNth(nth: number, state?: boolean, createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any; + debugGraphic: Phaser.GameObjects.Graphics; /** - * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`, - * assigns `x` and `y`, and returns the member. + * When rendering, skip any Face that isn't counter clockwise? * - * If no inactive member is found and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`. - * The new Game Object will have its active state set to `true`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * @param x The horizontal position of the Game Object in the world. - * @param y The vertical position of the Game Object in the world. - * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. - * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. - * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. + * Enable this to hide backward-facing Faces during rendering. + * + * Disable it to render all Faces. */ - get(x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any; + hideCCW: boolean; /** - * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `true`, - * assigns `x` and `y`, and returns the member. + * A Vector3 containing the 3D position of the vertices in this Mesh. * - * If no active member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. - * @param x The horizontal position of the Game Object in the world. - * @param y The vertical position of the Game Object in the world. - * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. - * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. - * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. + * Modifying the components of this property will allow you to reposition where + * the vertices are rendered within the Mesh. This happens in the `preUpdate` phase, + * where each vertex is transformed using the view and projection matrices. + * + * Changing this property will impact all vertices being rendered by this Mesh. + * + * You can also adjust the 'view' by using the `pan` methods. */ - getFirstAlive(createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any; + modelPosition: Phaser.Math.Vector3; /** - * Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`, - * assigns `x` and `y`, and returns the member. + * A Vector3 containing the 3D scale of the vertices in this Mesh. * - * If no inactive member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`. - * The new Game Object will have an active state set to `true`. - * Unless a new member is created, `key`, `frame`, and `visible` are ignored. - * @param createIfNull Create a new Game Object if no matching members are found, using the following arguments. Default false. - * @param x The horizontal position of the Game Object in the world. - * @param y The vertical position of the Game Object in the world. - * @param key The texture key assigned to a new Game Object (if one is created). Default defaultKey. - * @param frame A texture frame assigned to a new Game Object (if one is created). Default defaultFrame. - * @param visible The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created). Default true. + * Modifying the components of this property will allow you to scale + * the vertices within the Mesh. This happens in the `preUpdate` phase, + * where each vertex is transformed using the view and projection matrices. + * + * Changing this property will impact all vertices being rendered by this Mesh. */ - getFirstDead(createIfNull?: boolean, x?: number, y?: number, key?: string, frame?: string | number, visible?: boolean): any; + modelScale: Phaser.Math.Vector3; /** - * {@link Phaser.GameObjects.Components.Animation#play Plays} an animation for all members of this group. - * @param key The string-based key of the animation to play. - * @param startFrame Optionally start the animation playing from this frame index. Default 0. + * A Vector3 containing the 3D rotation of the vertices in this Mesh. + * + * The values should be given in radians, i.e. to rotate the vertices by 90 + * degrees you can use `modelRotation.x = Phaser.Math.DegToRad(90)`. + * + * Modifying the components of this property will allow you to rotate + * the vertices within the Mesh. This happens in the `preUpdate` phase, + * where each vertex is transformed using the view and projection matrices. + * + * Changing this property will impact all vertices being rendered by this Mesh. */ - playAnimation(key: string, startFrame?: string): this; + modelRotation: Phaser.Math.Vector3; /** - * Whether this group's size at its {@link Phaser.GameObjects.Group#maxSize maximum}. + * The transformation matrix for this Mesh. */ - isFull(): boolean; + transformMatrix: Phaser.Math.Matrix4; /** - * Counts the number of active (or inactive) group members. - * @param value Count active (true) or inactive (false) group members. Default true. + * The view position for this Mesh. + * + * Use the methods`panX`, `panY` and `panZ` to adjust the view. */ - countActive(value?: boolean): number; + viewPosition: Phaser.Math.Vector3; /** - * Counts the number of in-use (active) group members. + * The view matrix for this Mesh. */ - getTotalUsed(): number; + viewMatrix: Phaser.Math.Matrix4; /** - * The difference of {@link Phaser.GameObjects.Group#maxSize} and the number of active group members. + * The projection matrix for this Mesh. * - * This represents the number of group members that could be created or reactivated before reaching the size limit. + * Update it with the `setPerspective` or `setOrtho` methods. */ - getTotalFree(): number; + projectionMatrix: Phaser.Math.Matrix4; /** - * Sets the `active` property of this Group. - * When active, this Group runs its `preUpdate` method. - * @param value True if this Group should be set as active, false if not. + * How many faces were rendered by this Mesh Game Object in the last + * draw? This is reset in the `preUpdate` method and then incremented + * each time a face is drawn. Note that in multi-camera Scenes this + * value may exceed that found in `Mesh.getFaceCount` due to + * cameras drawing the same faces more than once. */ - setActive(value: boolean): this; + readonly totalRendered: number; /** - * Sets the `name` property of this Group. - * The `name` property is not populated by Phaser and is presented for your own use. - * @param value The name to be given to this Group. + * By default, the Mesh will check to see if its model or view transform has + * changed each frame and only recalculate the vertex positions if they have. + * + * This avoids lots of additional math in the `preUpdate` step when not required. + * + * However, if you are performing per-Face or per-Vertex manipulation on this Mesh, + * such as tweening a Face, or moving it without moving the rest of the Mesh, + * then you may need to disable the dirty cache in order for the Mesh to re-render + * correctly. You can toggle this property to do that. Please note that leaving + * this set to `true` will cause the Mesh to recalculate the position of every single + * vertex in it, every single frame. So only really do this if you know you + * need it. */ - setName(value: string): this; + ignoreDirtyCache: boolean; /** - * Sets the property as defined in `key` of each group member to the given value. - * @param key The property to be updated. - * @param value The amount to set the property to. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. - * @param index An optional offset to start searching from within the items array. Default 0. - * @param direction The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. Default 1. + * The Camera fov (field of view) in degrees. + * + * This is set automatically as part of the `Mesh.setPerspective` call, but exposed + * here for additional math. + * + * Do not modify this property directly, doing so will not change the fov. For that, + * call the respective Mesh methods. */ - propertyValueSet(key: string, value: number, step?: number, index?: number, direction?: number): this; + readonly fov: number; /** - * Adds the given value to the property as defined in `key` of each group member. - * @param key The property to be updated. - * @param value The amount to set the property to. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. - * @param index An optional offset to start searching from within the items array. Default 0. - * @param direction The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. Default 1. + * Translates the view position of this Mesh on the x axis by the given amount. + * @param v The amount to pan by. */ - propertyValueInc(key: string, value: number, step?: number, index?: number, direction?: number): this; + panX(v: number): void; /** - * Sets the x of each group member. - * @param value The amount to set the property to. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * Translates the view position of this Mesh on the y axis by the given amount. + * @param v The amount to pan by. */ - setX(value: number, step?: number): this; + panY(v: number): void; /** - * Sets the y of each group member. - * @param value The amount to set the property to. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * Translates the view position of this Mesh on the z axis by the given amount. + * + * As the default `panZ` value is 0, vertices with `z=0` (the default) need special + * care or else they will not display as they are "behind" the camera. + * + * Consider using `mesh.panZ(mesh.height / (2 * Math.tan(Math.PI / 16)))`, + * which will interpret vertex geometry 1:1 with pixel geometry (or see `setOrtho`). + * @param v The amount to pan by. */ - setY(value: number, step?: number): this; + panZ(v: number): void; /** - * Sets the x, y of each group member. - * @param x The amount to set the `x` property to. - * @param y The amount to set the `y` property to. If `undefined` or `null` it uses the `x` value. Default x. - * @param stepX This is added to the `x` amount, multiplied by the iteration counter. Default 0. - * @param stepY This is added to the `y` amount, multiplied by the iteration counter. Default 0. + * Builds a new perspective projection matrix from the given values. + * + * These are also the initial projection matrix and parameters for `Mesh` (see `Mesh.panZ` for more discussion). + * + * See also `setOrtho`. + * @param width The width of the projection matrix. Typically the same as the Mesh and/or Renderer. + * @param height The height of the projection matrix. Typically the same as the Mesh and/or Renderer. + * @param fov The field of view, in degrees. Default 45. + * @param near The near value of the view. Default 0.01. + * @param far The far value of the view. Default 1000. + */ + setPerspective(width: number, height: number, fov?: number, near?: number, far?: number): void; + + /** + * Builds a new orthographic projection matrix from the given values. + * + * If using this mode you will often need to set `Mesh.hideCCW` to `false` as well. + * + * By default, calling this method with no parameters will set the scaleX value to + * match the renderer's aspect ratio. If you would like to render vertex positions 1:1 + * to pixel positions, consider calling as `mesh.setOrtho(mesh.width, mesh.height)`. + * + * See also `setPerspective`. + * @param scaleX The default horizontal scale in relation to the Mesh / Renderer dimensions. Default 1. + * @param scaleY The default vertical scale in relation to the Mesh / Renderer dimensions. Default 1. + * @param near The near value of the view. Default -1000. + * @param far The far value of the view. Default 1000. */ - setXY(x: number, y?: number, stepX?: number, stepY?: number): this; + setOrtho(scaleX?: number, scaleY?: number, near?: number, far?: number): void; /** - * Adds the given value to the x of each group member. - * @param value The amount to be added to the `x` property. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * Iterates and destroys all current Faces in this Mesh, then resets the + * `faces` and `vertices` arrays. */ - incX(value: number, step?: number): this; + clear(): this; /** - * Adds the given value to the y of each group member. - * @param value The amount to be added to the `y` property. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * This method will add the data from a triangulated Wavefront OBJ model file to this Mesh. + * + * The data should have been loaded via the OBJFile: + * + * ```javascript + * this.load.obj(key, url); + * ``` + * + * Then use the same `key` as the first parameter to this method. + * + * Multiple Mesh Game Objects can use the same model data without impacting on each other. + * + * Make sure your 3D package has triangulated the model data prior to exporting it. + * + * You can 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 too large, to see. + * You can also offset the vertices of the model via the `x`, `y` and `z` parameters. + * @param key The key of the model data in the OBJ Cache to add to this Mesh. + * @param scale An amount to scale the model data by. Use this if the model has exported too small, or large, to see. Default 1. + * @param x Translate the model x position by this amount. Default 0. + * @param y Translate the model y position by this amount. Default 0. + * @param z Translate the model z position by this amount. Default 0. + * @param rotateX Rotate the model on the x axis by this amount, in radians. Default 0. + * @param rotateY Rotate the model on the y axis by this amount, in radians. Default 0. + * @param rotateZ Rotate the model on the z axis by this amount, in radians. Default 0. + * @param zIsUp Is the z axis up (true), or is y axis up (false)? Default true. */ - incY(value: number, step?: number): this; + addVerticesFromObj(key: string, scale?: number, x?: number, y?: number, z?: number, rotateX?: number, rotateY?: number, rotateZ?: number, zIsUp?: boolean): this; /** - * Adds the given value to the x, y of each group member. - * @param x The amount to be added to the `x` property. - * @param y The amount to be added to the `y` property. If `undefined` or `null` it uses the `x` value. Default x. - * @param stepX This is added to the `x` amount, multiplied by the iteration counter. Default 0. - * @param stepY This is added to the `y` amount, multiplied by the iteration counter. Default 0. + * Compare the depth of two Faces. + * @param faceA The first Face. + * @param faceB The second Face. */ - incXY(x: number, y?: number, stepX?: number, stepY?: number): this; + sortByDepth(faceA: Phaser.Geom.Mesh.Face, faceB: Phaser.Geom.Mesh.Face): number; /** - * Iterate through the group members changing the position of each element to be that of the element that came before - * it in the array (or after it if direction = 1) + * Runs a depth sort across all Faces in this Mesh, comparing their averaged depth. * - * The first group member position is set to x/y. - * @param x The x coordinate to place the first item in the array at. - * @param y The y coordinate to place the first item in the array at. - * @param direction The iteration direction. 0 = first to last and 1 = last to first. Default 0. + * This is called automatically if you use any of the `rotate` methods, but you can + * also invoke it to sort the Faces should you manually position them. */ - shiftPosition(x: number, y: number, direction?: number): this; + depthSort(): this; /** - * Sets the angle of each group member. - * @param value The amount to set the angle to, in degrees. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * Adds a new Vertex into the vertices array of this Mesh. + * + * Just adding a vertex isn't enough to render it. You need to also + * make it part of a Face, with 3 Vertex instances per Face. + * @param x The x position of the vertex. + * @param y The y position of the vertex. + * @param z The z position of the vertex. + * @param u The UV u coordinate of the vertex. + * @param v The UV v coordinate of the vertex. + * @param color The color value of the vertex. Default 0xffffff. + * @param alpha The alpha value of the vertex. Default 1. */ - angle(value: number, step?: number): this; + addVertex(x: number, y: number, z: number, u: number, v: number, color?: number, alpha?: number): this; /** - * Sets the rotation of each group member. - * @param value The amount to set the rotation to, in radians. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * Adds a new Face into the faces array of this Mesh. + * + * A Face consists of references to 3 Vertex instances, which must be provided. + * @param vertex1 The first vertex of the Face. + * @param vertex2 The second vertex of the Face. + * @param vertex3 The third vertex of the Face. */ - rotate(value: number, step?: number): this; + addFace(vertex1: Phaser.Geom.Mesh.Vertex, vertex2: Phaser.Geom.Mesh.Vertex, vertex3: Phaser.Geom.Mesh.Vertex): this; /** - * Rotates each group member around the given point by the given angle. - * @param point Any object with public `x` and `y` properties. - * @param angle The angle to rotate by, in radians. + * Adds new vertices to this Mesh 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, and will result in `z=0` for each vertex). + * + * 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 + * let mesh = new Mesh(this); // Assuming `this` is a scene! + * 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 ]; + * + * mesh.addVertices(vertices, uvs, indicies); + * // Note: Otherwise the added points will be "behind" the camera! This value will project vertex `x` & `y` values 1:1 to pixel values. + * mesh.hideCCW = false; + * mesh.setOrtho(mesh.width, mesh.height); + * ``` + * + * If the data is not indexed, it's assumed that the arrays all contain sequential data. + * @param vertices The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`. + * @param uvs The UVs pairs array. + * @param indicies Optional vertex indicies array. If you don't have one, pass `null` or an empty array. + * @param containsZ Does the vertices data include a `z` component? If not, it will be assumed `z=0`, see methods `panZ` or `setOrtho`. Default false. + * @param normals Optional vertex normals array. If you don't have one, pass `null` or an empty array. + * @param colors An array of colors, one per vertex, or a single color value applied to all vertices. Default 0xffffff. + * @param alphas An array of alpha values, one per vertex, or a single alpha value applied to all vertices. Default 1. */ - rotateAround(point: Phaser.Types.Math.Vector2Like, angle: number): this; + addVertices(vertices: number[], uvs: number[], indicies?: number[], containsZ?: boolean, normals?: number[], colors?: number | number[], alphas?: number | number[]): this; /** - * Rotates each group member around the given point by the given angle and distance. - * @param point Any object with public `x` and `y` properties. - * @param angle The angle to rotate by, in radians. - * @param distance The distance from the point of rotation in pixels. + * Returns the total number of Faces in this Mesh Game Object. */ - rotateAroundDistance(point: Phaser.Types.Math.Vector2Like, angle: number, distance: number): this; + getFaceCount(): number; /** - * Sets the alpha of each group member. - * @param value The amount to set the alpha to. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * Returns the total number of Vertices in this Mesh Game Object. */ - setAlpha(value: number, step?: number): this; + getVertexCount(): number; /** - * Sets the tint of each group member. - * @param topLeft The tint being applied to top-left corner of item. If other parameters are given no value, this tint will be applied to whole item. - * @param topRight The tint to be applied to top-right corner of item. - * @param bottomLeft The tint to be applied to the bottom-left corner of item. - * @param bottomRight The tint to be applied to the bottom-right corner of item. + * Returns the Face at the given index in this Mesh Game Object. + * @param index The index of the Face to get. */ - setTint(topLeft: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + getFace(index: number): Phaser.Geom.Mesh.Face; /** - * Sets the originX, originY of each group member. - * @param originX The amount to set the `originX` property to. - * @param originY The amount to set the `originY` property to. If `undefined` or `null` it uses the `originX` value. - * @param stepX This is added to the `originX` amount, multiplied by the iteration counter. Default 0. - * @param stepY This is added to the `originY` amount, multiplied by the iteration counter. Default 0. + * Tests to see if _any_ face in this Mesh intersects with the given coordinates. + * + * The given position is translated through the matrix of this Mesh and the given Camera, + * before being compared against the vertices. + * @param x The x position to check against. + * @param y The y position to check against. + * @param camera The camera to pass the coordinates through. If not give, the default Scene Camera is used. */ - setOrigin(originX: number, originY?: number, stepX?: number, stepY?: number): this; + hasFaceAt(x: number, y: number, camera?: Phaser.Cameras.Scene2D.Camera): boolean; /** - * Sets the scaleX of each group member. - * @param value The amount to set the property to. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * Return an array of Face objects from this Mesh that intersect with the given coordinates. + * + * The given position is translated through the matrix of this Mesh and the given Camera, + * before being compared against the vertices. + * + * If more than one Face intersects, they will all be returned in the array, but the array will + * be depth sorted first, so the first element will always be that closest to the camera. + * @param x The x position to check against. + * @param y The y position to check against. + * @param camera The camera to pass the coordinates through. If not give, the default Scene Camera is used. */ - scaleX(value: number, step?: number): this; + getFaceAt(x: number, y: number, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Geom.Mesh.Face[]; /** - * Sets the scaleY of each group member. - * @param value The amount to set the property to. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * This method enables rendering of the Mesh vertices to the given Graphics instance. + * + * If you enable this feature, you **must** call `Graphics.clear()` in your Scene `update`, + * otherwise the Graphics instance you provide to debug will fill-up with draw calls, + * eventually crashing the browser. This is not done automatically to allow you to debug + * draw multiple Mesh objects to a single Graphics instance. + * + * The Mesh class has a built-in debug rendering callback `Mesh.renderDebug`, however + * you can also provide your own callback to be used instead. Do this by setting the `callback` parameter. + * + * The callback is invoked _once per render_ and sent the following parameters: + * + * `callback(src, faces)` + * + * `src` is the Mesh instance being debugged. + * `faces` is an array of the Faces that were rendered. + * + * You can get the final drawn vertex position from a Face object like this: + * + * ```javascript + * let face = faces[i]; + * + * let x0 = face.vertex1.tx; + * let y0 = face.vertex1.ty; + * let x1 = face.vertex2.tx; + * let y1 = face.vertex2.ty; + * let x2 = face.vertex3.tx; + * let y2 = face.vertex3.ty; + * + * graphic.strokeTriangle(x0, y0, x1, y1, x2, y2); + * ``` + * + * If using your own callback you do not have to provide a Graphics instance to this method. + * + * To disable debug rendering, to either your own callback or the built-in one, call this method + * with no arguments. + * @param graphic The Graphic instance to render to if using the built-in callback. + * @param callback The callback to invoke during debug render. Leave as undefined to use the built-in callback. */ - scaleY(value: number, step?: number): this; + setDebug(graphic?: Phaser.GameObjects.Graphics, callback?: Function): this; /** - * Sets the scaleX, scaleY of each group member. - * @param scaleX The amount to be added to the `scaleX` property. - * @param scaleY The amount to be added to the `scaleY` property. If `undefined` or `null` it uses the `scaleX` value. - * @param stepX This is added to the `scaleX` amount, multiplied by the iteration counter. Default 0. - * @param stepY This is added to the `scaleY` amount, multiplied by the iteration counter. Default 0. + * Checks if the transformation data in this mesh is dirty. + * + * This is used internally by the `preUpdate` step to determine if the vertices should + * be recalculated or not. */ - scaleXY(scaleX: number, scaleY?: number, stepX?: number, stepY?: number): this; + isDirty(): boolean; /** - * Sets the depth of each group member. - * @param value The amount to set the property to. - * @param step This is added to the `value` amount, multiplied by the iteration counter. Default 0. + * The Mesh update loop. The following takes place in this method: + * + * First, the `totalRendered` and `totalFrame` properties are set. + * + * If the view matrix of this Mesh isn't dirty, and the model position, rotate or scale properties are + * all clean, then the method returns at this point. + * + * Otherwise, if the viewPosition is dirty (i.e. from calling a method like `panZ`), then it will + * refresh the viewMatrix. + * + * After this, a new transformMatrix is built and it then iterates through all Faces in this + * Mesh, calling `transformCoordinatesLocal` on all of them. Internally, this updates every + * vertex, calculating its new transformed position, based on the new transform matrix. + * + * Finally, the faces are depth sorted. + * @param time The current timestamp. + * @param delta The delta time, in ms, elapsed since the last frame. */ - setDepth(value: number, step?: number): this; + protected preUpdate(time: number, delta: number): void; /** - * Sets the blendMode of each group member. - * @param value The amount to set the property to. + * The built-in Mesh debug rendering method. + * + * See `Mesh.setDebug` for more details. + * @param src The Mesh object being rendered. + * @param faces An array of Faces. */ - setBlendMode(value: number): this; + renderDebug(src: Phaser.GameObjects.Mesh, faces: Phaser.Geom.Mesh.Face[]): void; /** - * Passes all group members to the Input Manager to enable them for input with identical areas and callbacks. - * @param hitArea Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used. - * @param hitAreaCallback A callback to be invoked when the Game Object is interacted with. If you provide a shape you must also provide a callback. + * Clears all tint values associated with this Game Object. + * + * Immediately sets the color values back to 0xffffff on all vertices, + * which results in no visible change to the texture. */ - setHitArea(hitArea: any, hitAreaCallback: Phaser.Types.Input.HitAreaCallback): this; + clearTint(): this; /** - * Shuffles the group members in place. + * Pass this Mesh Game Object to the Input Manager to enable it for Input. + * + * Unlike other Game Objects, the Mesh Game Object uses its own special hit area callback, which you cannot override. */ - shuffle(): this; + setInteractive(): this; /** - * Deactivates a member of this group. - * @param gameObject A member of this group. + * Sets an additive tint on all vertices of this Mesh Game Object. + * + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. + * + * To remove a tint call `clearTint`. + * @param tint The tint being applied to all vertices of this Mesh Game Object. Default 0xffffff. */ - kill(gameObject: Phaser.GameObjects.GameObject): void; + setTint(tint?: number): this; /** - * Deactivates and hides a member of this group. - * @param gameObject A member of this group. + * Scrolls the UV texture coordinates of all faces in this Mesh by + * adding the given x/y amounts to them. + * + * If you only wish to scroll one coordinate, pass a value of zero + * to the other. + * + * Use small values for scrolling. UVs are set from the range 0 + * to 1, so you should increment (or decrement) them by suitably + * small values, such as 0.01. + * + * Due to a limitation in WebGL1 you can only UV scroll textures + * that are a power-of-two in size. Scrolling NPOT textures will + * work but will result in clamping the pixels to the edges. + * + * Note that if this Mesh is using a _frame_ from a texture atlas + * then you will be unable to UV scroll its texture. + * @param x The amount to horizontally shift the UV coordinates by. + * @param y The amount to vertically shift the UV coordinates by. */ - killAndHide(gameObject: Phaser.GameObjects.GameObject): void; + uvScroll(x: number, y: number): this; /** - * Sets the visible of each group member. - * @param value The value to set the property to. - * @param index An optional offset to start searching from within the items array. Default 0. - * @param direction The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning. Default 1. + * Scales the UV texture coordinates of all faces in this Mesh by + * the exact given amounts. + * + * If you only wish to scale one coordinate, pass a value of one + * to the other. + * + * Due to a limitation in WebGL1 you can only UV scale textures + * that are a power-of-two in size. Scaling NPOT textures will + * work but will result in clamping the pixels to the edges if + * you scale beyond a value of 1. Scaling below 1 will work + * regardless of texture size. + * + * Note that if this Mesh is using a _frame_ from a texture atlas + * then you will be unable to UV scale its texture. + * @param x The amount to horizontally scale the UV coordinates by. + * @param y The amount to vertically scale the UV coordinates by. */ - setVisible(value: boolean, index?: number, direction?: number): this; + uvScale(x: number, y: number): this; /** - * Toggles (flips) the visible state of each member of this group. + * The tint value being applied to the whole of the Game Object. + * This property is a setter-only. */ - toggleVisible(): this; + tint(): number; /** - * Empties this Group of all children and removes it from the Scene. - * - * Does not call {@link Phaser.GameObjects.Group#removeCallback}. - * - * Children of this Group will _not_ be removed from the Scene by calling this method - * unless you specify the `removeFromScene` parameter. + * The x rotation of the Model in 3D space, as specified in degrees. * - * Children of this Group will also _not_ be destroyed by calling this method - * unless you specify the `destroyChildren` parameter. - * @param destroyChildren Also {@link Phaser.GameObjects.GameObject#destroy} each Group member. Default false. - * @param removeFromScene Optionally remove each Group member from the Scene. Default false. + * If you need the value in radians use the `modelRotation.x` property directly. */ - destroy(destroyChildren?: boolean, removeFromScene?: boolean): void; + rotateX(): number; - } + /** + * The y rotation of the Model in 3D space, as specified in degrees. + * + * If you need the value in radians use the `modelRotation.y` property directly. + */ + rotateY(): number; - /** - * An Image Game Object. - * - * An Image is a light-weight Game Object useful for the display of static images in your game, - * such as logos, backgrounds, scenery or other non-animated elements. Images can have input - * events and physics bodies, or be tweened, tinted or scrolled. The main difference between an - * Image and a Sprite is that you cannot animate an Image as they do not have the Animation component. - */ - class Image extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.TextureCrop, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** + * The z rotation of the Model in 3D space, as specified in degrees. * - * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. + * If you need the value in radians use the `modelRotation.z` property directly. */ - constructor(scene: Phaser.Scene, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number); + rotateZ(): number; /** * Clears all alpha values associated with this Game Object. @@ -20158,15 +26103,9 @@ declare namespace Phaser { /** * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * - * If your game is running under WebGL you can optionally specify four different alpha values, each of which - * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. - * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. - * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. - * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. - * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. + * @param value The alpha value applied across the whole Game Object. Default 1. */ - setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + setAlpha(value?: number): this; /** * The alpha value of the Game Object. @@ -20175,30 +26114,6 @@ declare namespace Phaser { */ alpha: number; - /** - * The alpha value starting from the top-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - */ - alphaTopLeft: number; - - /** - * The alpha value starting from the top-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - */ - alphaTopRight: number; - - /** - * The alpha value starting from the bottom-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - */ - alphaBottomLeft: number; - - /** - * The alpha value starting from the bottom-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - */ - alphaBottomRight: number; - /** * Sets the Blend Mode being used by this Game Object. * @@ -20206,6 +26121,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -20220,7 +26136,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -20229,6 +26145,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -20242,12 +26159,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -20265,155 +26182,13 @@ declare namespace Phaser { * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. - * - * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. - */ - setDepth(value: number): this; - - /** - * The horizontally flipped state of the Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - flipX: boolean; - - /** - * The vertically flipped state of the Game Object. - * - * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - flipY: boolean; - - /** - * Toggles the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - toggleFlipX(): this; - - /** - * Toggles the vertical flipped state of this Game Object. - */ - toggleFlipY(): this; - - /** - * Sets the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlipX(value: boolean): this; - - /** - * Sets the vertical flipped state of this Game Object. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlipY(value: boolean): this; - - /** - * Sets the horizontal and vertical flipped state of this Game Object. - * - * A Game Object that is flipped will render inversed on the flipped axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. - * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlip(x: boolean, y: boolean): this; - - /** - * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. - */ - resetFlip(): this; - - /** - * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - */ - getCenter(output?: O): O; - - /** - * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getTopLeft(output?: O, includeParent?: boolean): O; - - /** - * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getTopCenter(output?: O, includeParent?: boolean): O; - - /** - * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getTopRight(output?: O, includeParent?: boolean): O; - - /** - * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getLeftCenter(output?: O, includeParent?: boolean): O; - - /** - * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getRightCenter(output?: O, includeParent?: boolean): O; - - /** - * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getBottomLeft(output?: O, includeParent?: boolean): O; - - /** - * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getBottomCenter(output?: O, includeParent?: boolean): O; - - /** - * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getBottomRight(output?: O, includeParent?: boolean): O; - - /** - * Gets the bounds of this Game Object, regardless of origin. - * The values are stored and returned in a Rectangle, or Rectangle-like, object. - * @param output An object to store the values in. If not provided a new Rectangle will be created. + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ - getBounds(output?: O): O; + setDepth(value: number): this; /** * The Mask this Game Object is using during render. @@ -20445,7 +26220,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -20455,10 +26230,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -20470,79 +26249,66 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. - */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; - - /** - * The horizontal origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the left of the Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - originX: number; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** - * The vertical origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the top of the Game Object. + * The initial WebGL pipeline of this Game Object. + * + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. */ - originY: number; + defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * The horizontal display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * The current WebGL pipeline of this Game Object. */ - displayOriginX: number; + pipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * The vertical display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - displayOriginY: number; + pipelineData: object; /** - * Sets the origin of this Game Object. + * Sets the initial WebGL Pipeline of this Game Object. * - * The values are given in the range 0 to 1. - * @param x The horizontal origin value. Default 0.5. - * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. - */ - setOrigin(x?: number, y?: number): this; - - /** - * Sets the origin of this Game Object based on the Pivot values in its Frame. + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. */ - setOriginFromFrame(): this; + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; /** - * Sets the display origin of this Game Object. - * The difference between this and setting the origin is that you can use pixel values for setting the display origin. - * @param x The horizontal display origin value. Default 0. - * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ - setDisplayOrigin(x?: number, y?: number): this; + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; /** - * Updates the Display Origin cached values internally stored on this Game Object. - * You don't usually call this directly, but it is exposed for edge-cases where you may. + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - updateDisplayOrigin(): this; + setPipelineData(key: string, value?: any): this; /** - * The initial WebGL pipeline of this Game Object. - * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; + resetPipeline(resetData?: boolean): boolean; /** - * The current WebGL pipeline of this Game Object. + * Gets the name of the WebGL Pipeline this Game Object is currently using. */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + getPipelineName(): string; /** * Does this Game Object have any Post Pipelines set? @@ -20562,27 +26328,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -20598,27 +26402,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -20626,17 +26426,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -20649,9 +26442,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -20760,7 +26557,7 @@ declare namespace Phaser { * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * @param frame The frame to base the size of this Game Object on. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; /** * Sets the internal size of this Game Object, as used for frame or physics body creation. @@ -20796,168 +26593,36 @@ declare namespace Phaser { */ frame: Phaser.Textures.Frame; - /** - * A boolean flag indicating if this Game Object is being cropped or not. - * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. - * Equally, calling `setCrop` with no arguments will reset the crop and disable it. - */ - isCropped: boolean; - - /** - * Applies a crop to a texture based Game Object, such as a Sprite or Image. - * - * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. - * - * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just - * changes what is shown when rendered. - * - * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. - * - * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left - * half of it, you could call `setCrop(0, 0, 400, 600)`. - * - * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop - * an area of 200x100 when applied to a Game Object that had a scale factor of 2. - * - * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. - * - * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. - * - * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow - * the renderer to skip several internal calculations. - * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. - * @param y The y coordinate to start the crop from. - * @param width The width of the crop rectangle in pixels. - * @param height The height of the crop rectangle in pixels. - */ - setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; - /** * Sets the texture and frame this Game Object will use to render with. * * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. * @param frame The name or index of the frame within the Texture. */ - setTexture(key: string, frame?: string | number): this; + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; - - /** - * The tint value being applied to the top-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintTopLeft: number; - - /** - * The tint value being applied to the top-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintTopRight: number; - - /** - * The tint value being applied to the bottom-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintBottomLeft: number; - - /** - * The tint value being applied to the bottom-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintBottomRight: number; - - /** - * The tint fill mode. - * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. - */ - tintFill: boolean; - - /** - * Clears all tint values associated with this Game Object. - * - * Immediately sets the color values back to 0xffffff and the tint type to 'additive', - * which results in no visible change to the texture. - */ - clearTint(): this; - - /** - * Sets an additive tint on this Game Object. - * - * The tint works by taking the pixel color values from the Game Objects texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole Game Object will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. - * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. - */ - setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - - /** - * Sets a fill-based tint on this Game Object. - * - * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture - * with those in the tint. You can use this for effects such as making a player flash 'white' - * if hit by something. You can provide either one color value, in which case the whole - * Game Object will be rendered in that color. Or you can provide a color per corner. The colors - * are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. - * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. - */ - setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - - /** - * The tint value being applied to the whole of the Game Object. - * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. - */ - tint: number; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** - * Does this Game Object have a tint applied? - * - * It checks to see if the 4 tint properties are set to the value 0xffffff - * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. + * A property indicating that a Game Object has this component. */ - readonly isTinted: boolean; + readonly hasTransformComponent: boolean; /** * The x position of this Game Object. @@ -21065,10 +26730,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -21151,415 +26816,381 @@ declare namespace Phaser { } /** - * A Layer Game Object. + * A Nine Slice Game Object allows you to display a texture-based object that + * can be stretched both horizontally and vertically, but that retains + * fixed-sized corners. The dimensions of the corners are set via the + * parameters to this class. * - * A Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object - * to a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game - * Objects: + * This is extremely useful for UI and button like elements, where you need + * them to expand to accommodate the content without distorting the texture. * - * ```javascript - * const spaceman = this.add.sprite(150, 300, 'spaceman'); - * const bunny = this.add.sprite(400, 300, 'bunny'); - * const elephant = this.add.sprite(650, 300, 'elephant'); + * The texture you provide for this Game Object should be based on the + * following layout structure: * - * const layer = this.add.layer(); + * ``` + * A B + * +---+----------------------+---+ + * C | 1 | 2 | 3 | + * +---+----------------------+---+ + * | | | | + * | 4 | 5 | 6 | + * | | | | + * +---+----------------------+---+ + * D | 7 | 8 | 9 | + * +---+----------------------+---+ + * ``` + * + * When changing this objects width and / or height: + * + * areas 1, 3, 7 and 9 (the corners) will remain unscaled + * areas 2 and 8 will be stretched horizontally only + * areas 4 and 6 will be stretched vertically only + * area 5 will be stretched both horizontally and vertically + * + * You can also create a 3 slice Game Object: + * + * This works in a similar way, except you can only stretch it horizontally. + * Therefore, it requires less configuration: * - * layer.add([ spaceman, bunny, elephant ]); + * ``` + * A B + * +---+----------------------+---+ + * | | | | + * C | 1 | 2 | 3 | + * | | | | + * +---+----------------------+---+ * ``` * - * The 3 sprites in the example above will now be managed by the Layer they were added to. Therefore, - * if you then set `layer.setVisible(false)` they would all vanish from the display. + * When changing this objects width (you cannot change its height) * - * You can also control the depth of the Game Objects within the Layer. For example, calling the - * `setDepth` method of a child of a Layer will allow you to adjust the depth of that child _within the - * Layer itself_, rather than the whole Scene. The Layer, too, can have its depth set as well. + * areas 1 and 3 will remain unscaled + * area 2 will be stretched horizontally * - * The Layer class also offers many different methods for manipulating the list, such as the - * methods `moveUp`, `moveDown`, `sendToBack`, `bringToTop` and so on. These allow you to change the - * display list position of the Layers children, causing it to adjust the order in which they are - * rendered. Using `setDepth` on a child allows you to override this. + * The above configuration concept is adapted from the Pixi NineSlicePlane. * - * Layers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across - * a whole range of children, which, depending on the effect, can often be far more efficient that doing so - * on a per-child basis. + * To specify a 3 slice object instead of a 9 slice you should only + * provide the `leftWidth` and `rightWidth` parameters. To create a 9 slice + * you must supply all parameters. * - * Layers have no position or size within the Scene. This means you cannot enable a Layer for - * physics or input, or change the position, rotation or scale of a Layer. They also have no scroll - * factor, texture, tint, origin, crop or bounds. + * The _minimum_ width this Game Object can be is the total of + * `leftWidth` + `rightWidth`. The _minimum_ height this Game Object + * can be is the total of `topHeight` + `bottomHeight`. + * If you need to display this object at a smaller size, you can scale it. * - * If you need those kind of features then you should use a Container instead. Containers can be added - * to Layers, but Layers cannot be added to Containers. + * In terms of performance, using a 3 slice Game Object is the equivalent of + * having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent + * of having 9 Sprites in a row. The vertices of this object are all batched + * together and can co-exist with other Sprites and graphics on the display + * list, without incurring any additional overhead. * - * However, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings - * will impact all children being rendered by the Layer. + * As of Phaser 3.60 this Game Object is WebGL only. */ - class Layer extends Phaser.Structs.List implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.Visible { + class NineSlice extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. - * @param children An optional array of Game Objects to add to this Layer. + * @param x The horizontal position of the center of this Game Object in the world. + * @param y The vertical position of the center of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. + * @param width The width of the Nine Slice Game Object. You can adjust the width post-creation. Default 256. + * @param height The height of the Nine Slice Game Object. If this is a 3 slice object the height will be fixed to the height of the texture and cannot be changed. Default 256. + * @param leftWidth The size of the left vertical column (A). Default 10. + * @param rightWidth The size of the right vertical column (B). Default 10. + * @param topHeight The size of the top horiztonal row (C). Set to zero or undefined to create a 3 slice object. Default 0. + * @param bottomHeight The size of the bottom horiztonal row (D). Set to zero or undefined to create a 3 slice object. Default 0. */ - constructor(scene: Phaser.Scene, children?: Phaser.GameObjects.GameObject[]); + constructor(scene: Phaser.Scene, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number, width?: number, height?: number, leftWidth?: number, rightWidth?: number, topHeight?: number, bottomHeight?: number); /** - * A reference to the Scene to which this Game Object belongs. + * An array of Vertex objects that correspond to the quads that make-up + * this Nine Slice Game Object. They are stored in the following order: * - * Game Objects can only belong to one Scene. + * Top Left - Indexes 0 - 5 + * Top Center - Indexes 6 - 11 + * Top Right - Indexes 12 - 17 + * Center Left - Indexes 18 - 23 + * Center - Indexes 24 - 29 + * Center Right - Indexes 30 - 35 + * Bottom Left - Indexes 36 - 41 + * Bottom Center - Indexes 42 - 47 + * Bottom Right - Indexes 48 - 53 * - * You should consider this property as being read-only. You cannot move a - * Game Object to another Scene by simply changing it. - */ - scene: Phaser.Scene; - - /** - * Holds a reference to the Display List that contains this Game Object. + * Each quad is represented by 6 Vertex instances. * - * This is set automatically when this Game Object is added to a Scene or Layer. + * This array will contain 18 elements for a 3 slice object + * and 54 for a nine slice object. * - * You should treat this property as being read-only. + * You should never modify this array once it has been populated. */ - displayList: Phaser.GameObjects.DisplayList | Phaser.GameObjects.Layer; + vertices: Phaser.Geom.Mesh.Vertex[]; /** - * A textual representation of this Game Object, i.e. `sprite`. - * Used internally by Phaser but is available for your own custom classes to populate. + * The size of the left vertical bar (A). */ - type: string; + readonly leftWidth: number; /** - * The current state of this Game Object. - * - * Phaser itself will never modify this value, although plugins may do so. - * - * Use this property to track the state of a Game Object during its lifetime. For example, it could change from - * a state of 'moving', to 'attacking', to 'dead'. The state value should be an integer (ideally mapped to a constant - * in your game code), or a string. These are recommended to keep it light and simple, with fast comparisons. - * If you need to store complex data about your Game Object, look at using the Data Component instead. + * The size of the right vertical bar (B). */ - state: number | string; + readonly rightWidth: number; /** - * A Layer cannot be placed inside a Container. + * The size of the top horizontal bar (C). * - * This property is kept purely so a Layer has the same - * shape as a Game Object. - */ - parentContainer: Phaser.GameObjects.Container; - - /** - * The name of this Game Object. - * Empty by default and never populated by Phaser, this is left for developers to use. - */ - name: string; - - /** - * The active state of this Game Object. - * A Game Object with an active state of `true` is processed by the Scenes UpdateList, if added to it. - * An active object is one which is having its logic and internal systems updated. - */ - active: boolean; - - /** - * The Tab Index of the Game Object. - * Reserved for future use by plugins and the Input Manager. - */ - tabIndex: number; - - /** - * A Data Manager. - * It allows you to store, query and get key/value paired information specific to this Game Object. - * `null` by default. Automatically created if you use `getData` or `setData` or `setDataEnabled`. - */ - data: Phaser.Data.DataManager; - - /** - * 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. - */ - renderFlags: number; - - /** - * 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: - */ - cameraFilter: number; - - /** - * This property is kept purely so a Layer has the same - * shape as a Game Object. You cannot input enable a Layer. - */ - input: Phaser.Types.Input.InteractiveObject; - - /** - * This property is kept purely so a Layer has the same - * shape as a Game Object. You cannot give a Layer a physics body. - */ - body: Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | MatterJS.BodyType; - - /** - * This Game Object will ignore all calls made to its destroy method if this flag is set to `true`. - * This includes calls that may come from a Group, Container or the Scene itself. - * While it allows you to persist a Game Object across Scenes, please understand you are entirely - * responsible for managing references to and from this Game Object. - */ - ignoreDestroy: boolean; - - /** - * A reference to the Scene Systems. - */ - systems: Phaser.Scenes.Systems; - - /** - * A reference to the Scene Event Emitter. - */ - events: Phaser.Events.EventEmitter; - - /** - * The flag the determines whether Game Objects should be sorted when `depthSort()` is called. - */ - sortChildrenFlag: boolean; - - /** - * Sets the `active` property of this Game Object and returns this Game Object for further chaining. - * A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList. - * @param value True if this Game Object should be set as active, false if not. - */ - setActive(value: boolean): this; - - /** - * Sets the `name` property of this Game Object and returns this Game Object for further chaining. - * The `name` property is not populated by Phaser and is presented for your own use. - * @param value The name to be given to this Game Object. + * If this is a 3 slice object this property will be set to the + * height of the texture being used. */ - setName(value: string): this; + readonly topHeight: number; /** - * Sets the current state of this Game Object. - * - * Phaser itself will never modify the State of a Game Object, although plugins may do so. + * The size of the bottom horizontal bar (D). * - * For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'. - * The state value should typically be an integer (ideally mapped to a constant - * in your game code), but could also be a string. It is recommended to keep it light and simple. - * If you need to store complex data about your Game Object, look at using the Data Component instead. - * @param value The state of the Game Object. + * If this is a 3 slice object this property will be set to zero. */ - setState(value: number | string): this; + readonly bottomHeight: number; /** - * Adds a Data Manager component to this Game Object. + * The tint value being applied to the top-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. */ - setDataEnabled(): this; + tint: number; /** - * Allows you to store a key value pair within this Game Objects Data Manager. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * ```javascript - * sprite.setData('name', 'Red Gem Stone'); - * ``` - * - * You can also pass in an object of key value pairs as the first argument: - * - * ```javascript - * sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 }); - * ``` - * - * To get a value back again you can call `getData`: - * - * ```javascript - * sprite.getData('gold'); - * ``` - * - * Or you can access the value directly via the `values` property, where it works like any other variable: - * - * ```javascript - * sprite.data.values.gold += 50; - * ``` - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * - * If the key already exists, a `changedata` event is emitted instead, along an event named after the key. - * For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`. - * These events will be emitted regardless if you use this method to set the value, or the direct `values` setter. + * The tint fill mode. * - * Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings. - * This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager. - * @param key The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored. - * @param data The value to set for the given key. If an object is provided as the key this argument is ignored. + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. */ - setData(key: string | object, data?: any): this; + tintFill: boolean; /** - * Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0. - * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. - * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * @param key The key to increase the value for. - * @param data The value to increase for the given key. + * This property is `true` if this Nine Slice Game Object was configured + * with just `leftWidth` and `rightWidth` values, making it a 3-slice + * instead of a 9-slice object. */ - incData(key: string | object, data?: any): this; + is3Slice: boolean; /** - * Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false. + * Resets the width, height and slices for this NineSlice Game Object. * - * If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled - * before setting the value. - * - * If the key doesn't already exist in the Data Manager then it is created. + * This allows you to modify the texture being used by this object and then reset the slice configuration, + * to avoid having to destroy this Game Object in order to use it for a different game element. * - * When the value is first set, a `setdata` event is emitted from this Game Object. - * @param key The key to toggle the value for. + * Please note that you cannot change a 9-slice to a 3-slice or vice versa. + * @param width The width of the Nine Slice Game Object. You can adjust the width post-creation. Default 256. + * @param height The height of the Nine Slice Game Object. If this is a 3 slice object the height will be fixed to the height of the texture and cannot be changed. Default 256. + * @param leftWidth The size of the left vertical column (A). Default 10. + * @param rightWidth The size of the right vertical column (B). Default 10. + * @param topHeight The size of the top horiztonal row (C). Set to zero or undefined to create a 3 slice object. Default 0. + * @param bottomHeight The size of the bottom horiztonal row (D). Set to zero or undefined to create a 3 slice object. Default 0. */ - toggleData(key: string | object): this; + setSlices(width?: number, height?: number, leftWidth?: number, rightWidth?: number, topHeight?: number, bottomHeight?: number): this; /** - * Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist. - * - * You can also access values via the `values` object. For example, if you had a key called `gold` you can do either: - * - * ```javascript - * sprite.getData('gold'); - * ``` - * - * Or access the value directly: + * Updates all of the vertice UV coordinates. This is called automatically + * when the NineSlice Game Object is created, or if the texture frame changes. * - * ```javascript - * sprite.data.values.gold; - * ``` + * Unlike with the `updateVertice` method, you do not need to call this + * method if the Nine Slice changes size. Only if it changes texture frame. + */ + updateUVs(): void; + + /** + * Recalculates all of the vertices in this Nine Slice Game Object + * based on the `leftWidth`, `rightWidth`, `topHeight` and `bottomHeight` + * properties, combined with the Game Object size. * - * You can also pass in an array of keys, in which case an array of values will be returned: + * This method is called automatically when this object is created + * or if it's origin is changed. * - * ```javascript - * sprite.getData([ 'gold', 'armor', 'health' ]); - * ``` + * You should not typically need to call this method directly, but it + * is left public should you find a need to modify one of those properties + * after creation. + */ + updateVertices(): void; + + /** + * Internally updates the position coordinates across all vertices of the + * given quad offset. * - * This approach is useful for destructuring arrays in ES6. - * @param key The key of the value to retrieve, or an array of keys. + * You should not typically need to call this method directly, but it + * is left public should an extended class require it. + * @param offset The offset in the vertices array of the quad to update. + * @param x1 The top-left quad coordinate. + * @param y1 The top-left quad coordinate. + * @param x2 The bottom-right quad coordinate. + * @param y2 The bottom-right quad coordinate. */ - getData(key: string | string[]): any; + updateQuad(offset: number, x1: number, y1: number, x2: number, y2: number): void; /** - * A Layer cannot be enabled for input. + * Internally updates the UV coordinates across all vertices of the + * given quad offset, based on the frame size. * - * This method does nothing and is kept to ensure - * the Layer has the same shape as a Game Object. + * You should not typically need to call this method directly, but it + * is left public should an extended class require it. + * @param offset The offset in the vertices array of the quad to update. + * @param u1 The top-left UV coordinate. + * @param v1 The top-left UV coordinate. + * @param u2 The bottom-right UV coordinate. + * @param v2 The bottom-right UV coordinate. */ - setInteractive(): this; + updateQuadUVs(offset: number, u1: number, v1: number, u2: number, v2: number): void; /** - * A Layer cannot be enabled for input. + * Clears all tint values associated with this Game Object. * - * This method does nothing and is kept to ensure - * the Layer has the same shape as a Game Object. + * Immediately sets the color values back to 0xffffff and the tint type to 'additive', + * which results in no visible change to the texture. */ - disableInteractive(): this; + clearTint(): this; /** - * A Layer cannot be enabled for input. + * Sets an additive tint on this Game Object. * - * This method does nothing and is kept to ensure - * the Layer has the same shape as a Game Object. + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property. + * + * To remove a tint call `clearTint`, or call this method with no parameters. + * + * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. + * @param color The tint being applied to the entire Game Object. Default 0xffffff. */ - removeInteractive(): this; + setTint(color?: number): this; /** - * This callback is invoked when this Game Object is added to a Scene. + * Sets a fill-based tint on this Game Object. * - * Can be overriden by custom Game Objects, but be aware of some Game Objects that - * will use this, such as Sprites, to add themselves into the Update List. + * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture + * with those in the tint. You can use this for effects such as making a player flash 'white' + * if hit by something. The whole Game Object will be rendered in the given color. * - * You can also listen for the `ADDED_TO_SCENE` event from this Game Object. + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property. + * + * To remove a tint call `clearTint`, or call this method with no parameters. + * + * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. + * @param color The tint being applied to the entire Game Object. Default 0xffffff. */ - addedToScene(): void; + setTintFill(color?: number): this; /** - * This callback is invoked when this Game Object is removed from a Scene. + * Does this Game Object have a tint applied? * - * Can be overriden by custom Game Objects, but be aware of some Game Objects that - * will use this, such as Sprites, to removed themselves from the Update List. + * It checks to see if the tint property is set to a value other than 0xffffff. + * This indicates that a Game Object is tinted. + */ + readonly isTinted: boolean; + + /** + * The displayed width of this Game Object. * - * You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object. + * Setting this value will adjust the way in which this Nine Slice + * object scales horizontally, if configured to do so. + * + * The _minimum_ width this Game Object can be is the total of + * `leftWidth` + `rightWidth`. If you need to display this object + * at a smaller size, you can also scale it. */ - removedFromScene(): void; + width: number; /** - * To be overridden by custom GameObjects. Allows base objects to be used in a Pool. - * @param args args + * The displayed height of this Game Object. + * + * Setting this value will adjust the way in which this Nine Slice + * object scales vertically, if configured to do so. + * + * The _minimum_ height this Game Object can be is the total of + * `topHeight` + `bottomHeight`. If you need to display this object + * at a smaller size, you can also scale it. + * + * If this is a 3-slice object, you can only stretch it horizontally + * and changing the height will be ignored. */ - update(...args: any[]): void; + height: number; /** - * Returns a JSON representation of the Game Object. + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. */ - toJSON(): Phaser.Types.GameObjects.JSONGameObject; + displayWidth: number; /** - * 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. - * @param camera The Camera to check against this Game Object. + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. */ - willRender(camera: Phaser.Cameras.Scene2D.Camera): boolean; + displayHeight: number; /** - * Returns an array containing the display list index of either this Game Object, or if it has one, - * its parent Container. It then iterates up through all of the parent containers until it hits the - * root of the display list (which is index 0 in the returned array). + * Sets the size of this Game Object. * - * Used internally by the InputPlugin but also useful if you wish to find out the display depth of - * this Game Object and all of its ancestors. + * For a Nine Slice Game Object this means it will be stretched (or shrunk) horizontally + * and vertically depending on the dimensions given to this method, in accordance with + * how it has been configured for the various corner sizes. + * + * If this is a 3-slice object, you can only stretch it horizontally + * and changing the height will be ignored. + * + * If you have enabled this Game Object for input, changing the size will also change the + * size of the hit area. + * @param width The width of this Game Object. + * @param height The height of this Game Object. */ - getIndexList(): number[]; + setSize(width: number, height: number): this; /** - * Force a sort of the display list on the next call to depthSort. + * Sets the display size of this Game Object. + * + * Calling this will adjust the scale. + * @param width The width of this Game Object. + * @param height The height of this Game Object. */ - queueDepthSort(): void; + setDisplaySize(width: number, height: number): this; /** - * Immediately sorts the display list if the flag is set. + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. */ - depthSort(): void; + originX: number; /** - * Compare the depth of two Game Objects. - * @param childA The first Game Object. - * @param childB The second Game Object. + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. */ - sortByDepth(childA: Phaser.GameObjects.GameObject, childB: Phaser.GameObjects.GameObject): number; + originY: number; /** - * Returns an array which contains all Game Objects within this Layer. + * Sets the origin of this Game Object. * - * This is a reference to the main list array, not a copy of it, so be careful not to modify it. + * The values are given in the range 0 to 1. + * @param x The horizontal origin value. Default 0.5. + * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. */ - getChildren(): Phaser.GameObjects.GameObject[]; + setOrigin(x?: number, y?: number): this; /** - * Destroys this Layer removing it from the Display List and Update List and - * severing all ties to parent resources. - * - * Also destroys all children of this Layer. If you do not wish for the - * children to be destroyed, you should move them from this Layer first. - * - * Use this to remove this Layer from your game if you don't ever plan to use it again. - * As long as no reference to it exists within your own code it should become free for - * garbage collection by the browser. + * This method is included but does nothing for the Nine Slice Game Object, + * because the size of the object isn't based on the texture frame. * - * If you just want to temporarily disable an object then look at using the - * Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected. + * You should not call this method. */ - destroy(): void; + setSizeToFrame(): this; /** * Clears all alpha values associated with this Game Object. @@ -21589,6 +27220,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -21603,7 +27235,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -21612,6 +27244,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -21625,12 +27258,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -21652,10 +27285,108 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; + /** + * Gets the center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the top-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopLeft(output?: O, includeParent?: boolean): O; + + /** + * Gets the top-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the top-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopRight(output?: O, includeParent?: boolean): O; + + /** + * Gets the left-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getLeftCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the right-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getRightCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomLeft(output?: O, includeParent?: boolean): O; + + /** + * Gets the bottom-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomCenter(output?: O, includeParent?: boolean): O; + + /** + * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomRight(output?: O, includeParent?: boolean): O; + + /** + * Gets the bounds of this Game Object, regardless of origin. + * + * The values are stored and returned in a Rectangle, or Rectangle-like, object. + * @param output An object to store the values in. If not provided a new Rectangle will be created. + */ + getBounds(output?: O): O; + /** * The Mask this Game Object is using during render. */ @@ -21686,7 +27417,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -21696,10 +27427,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -21711,9 +27446,42 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. + */ + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; + + /** + * The horizontal display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginX: number; + + /** + * The vertical display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginY: number; + + /** + * Sets the origin of this Game Object based on the Pivot values in its Frame. + */ + setOriginFromFrame(): this; + + /** + * Sets the display origin of this Game Object. + * The difference between this and setting the origin is that you can use pixel values for setting the display origin. + * @param x The horizontal display origin value. Default 0. + * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + */ + setDisplayOrigin(x?: number, y?: number): this; + + /** + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + updateDisplayOrigin(): this; /** * The initial WebGL pipeline of this Game Object. @@ -21727,6 +27495,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -21745,27 +27558,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -21781,27 +27632,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -21809,17 +27656,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -21832,88 +27672,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. - */ - getPipelineName(): string; - - /** - * The visible state of the Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - */ - visible: boolean; - - /** - * Sets the visibility of this Game Object. + * Removes all Pre and Post FX Controllers from this Game Object. * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. - */ - setVisible(value: boolean): this; - - } - - /** - * 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 implements Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Visible { - /** + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. * - * @param x The horizontal position of the light. - * @param y The vertical position of the light. - * @param radius The radius of the light. - * @param r The red color of the light. A value between 0 and 1. - * @param g The green color of the light. A value between 0 and 1. - * @param b The blue color of the light. A value between 0 and 1. - * @param intensity The intensity of the light. - */ - constructor(x: number, y: number, radius: number, r: number, g: number, b: number, intensity: number); - - /** - * The color of the light. - */ - color: Phaser.Display.RGB; - - /** - * The intensity of the light. - */ - intensity: number; - - /** - * 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. - * @param camera The Camera to check against this Game Object. - */ - willRender(camera: Phaser.Cameras.Scene2D.Camera): boolean; - - /** - * Set the color of the light from a single integer RGB value. - * @param rgb The integer RGB color of the light. - */ - setColor(rgb: number): this; - - /** - * Set the intensity of the light. - * @param intensity The intensity of the light. - */ - setIntensity(intensity: number): this; - - /** - * Set the radius of the light. - * @param radius The radius of the light. - */ - setRadius(radius: number): this; - - /** - * The bitmask that `GameObject.renderFlags` is compared against to determine if the Game Object will render or not. + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - static readonly RENDER_MASK: number; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -21975,3344 +27740,4855 @@ declare namespace Phaser { setScrollFactor(x: number, y?: number): this; /** - * The visible state of the Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. + * The Texture this Game Object is using to render with. */ - visible: boolean; + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; /** - * Sets the visibility of this Game Object. + * The Texture Frame this Game Object is using to render with. + */ + frame: Phaser.Textures.Frame; + + /** + * Sets the texture and frame this Game Object will use to render with. * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. + * @param frame The name or index of the frame within the Texture. */ - setVisible(value: boolean): this; + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; - } + /** + * Sets the frame this Game Object will use to render with. + * + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. + * + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. + * + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. + */ + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; - /** - * Manages Lights for a Scene. - * - * Affects the rendering of Game Objects using the `Light2D` pipeline. - */ - class LightsManager { /** - * The Lights in the Scene. + * A property indicating that a Game Object has this component. */ - lights: Phaser.GameObjects.Light[]; + readonly hasTransformComponent: boolean; /** - * The ambient color. + * The x position of this Game Object. */ - ambientColor: Phaser.Display.RGB; + x: number; /** - * Whether the Lights Manager is enabled. + * The y position of this Game Object. */ - active: boolean; + y: number; /** - * 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. + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. */ - readonly maxLights: number; + z: number; /** - * The number of lights that the LightPipeline processed in the _previous_ frame. + * The w position of this Game Object. */ - readonly visibleLights: number; + w: number; /** - * Creates a new Point Light Game Object and adds it to the Scene. - * - * Note: This method will only be available if the Point Light Game Object has been built into Phaser. - * - * The Point Light Game Object provides a way to add a point light effect into your game, - * without the expensive shader processing requirements of the traditional Light Game Object. + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. * - * The difference is that the Point Light renders using a custom shader, designed to give the - * impression of a point light source, of variable radius, intensity and color, in your game. - * However, unlike the Light Game Object, it does not impact any other Game Objects, or use their - * normal maps for calcuations. This makes them extremely fast to render compared to Lights - * and perfect for special effects, such as flickering torches or muzzle flashes. + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. + */ + scale: number; + + /** + * The horizontal scale of this Game Object. + */ + scaleX: number; + + /** + * The vertical scale of this Game Object. + */ + scaleY: number; + + /** + * The angle of this Game Object as expressed in degrees. * - * For maximum performance you should batch Point Light Game Objects together. This means - * ensuring they follow each other consecutively on the display list. Ideally, use a Layer - * Game Object and then add just Point Lights to it, so that it can batch together the rendering - * of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in - * your game then it's perfectly safe to mix them into the dislay list as normal. However, if - * you're using a large number of them, please consider how they are mixed into the display list. + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. * - * The renderer will automatically cull Point Lights. Those with a radius that does not intersect - * with the Camera will be skipped in the rendering list. This happens automatically and the - * culled state is refreshed every frame, for every camera. + * If you prefer to work in radians, see the `rotation` property instead. + */ + angle: number; + + /** + * The angle of this Game Object in radians. * - * The origin of a Point Light is always 0.5 and it cannot be changed. + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. * - * Point Lights are a WebGL only feature and do not have a Canvas counterpart. - * @param x The horizontal position of this Point Light in the world. - * @param y The vertical position of this Point Light in the world. - * @param color The color of the Point Light, given as a hex value. Default 0xffffff. - * @param radius The radius of the Point Light. Default 128. - * @param intensity The intensity, or colr blend, of the Point Light. Default 1. - * @param attenuation The attenuation of the Point Light. This is the reduction of light from the center point. Default 0.1. + * If you prefer to work in degrees, see the `angle` property instead. */ - addPointLight(x: number, y: number, color?: number, radius?: number, intensity?: number, attenuation?: number): Phaser.GameObjects.PointLight; + rotation: number; /** - * Enable the Lights Manager. + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. */ - enable(): this; + setPosition(x?: number, y?: number, z?: number, w?: number): this; /** - * Disable the Lights Manager. + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. */ - disable(): this; + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; /** - * Get all lights that can be seen by the given Camera. + * Sets the position of this Game Object to be a random position within the confines of + * the given area. * - * It will automatically cull lights that are outside the world view of the Camera. + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. * - * 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. - * @param camera The Camera to cull Lights for. + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. */ - getLights(camera: Phaser.Cameras.Scene2D.Camera): Phaser.GameObjects.Light[]; + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; /** - * Set the ambient light color. - * @param rgb The integer RGB color of the ambient light. + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. */ - setAmbientColor(rgb: number): this; + setRotation(radians?: number): this; /** - * Returns the maximum number of Lights allowed to appear at once. + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. */ - getMaxVisibleLights(): number; + setAngle(degrees?: number): this; /** - * Get the number of Lights managed by this Lights Manager. + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - getLightCount(): number; + setScale(x?: number, y?: number): this; /** - * Add a Light. - * @param x The horizontal position of the Light. Default 0. - * @param y The vertical position of the Light. Default 0. - * @param radius The radius of the Light. Default 128. - * @param rgb The integer RGB color of the light. Default 0xffffff. - * @param intensity The intensity of the Light. Default 1. + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. */ - addLight(x?: number, y?: number, radius?: number, rgb?: number, intensity?: number): Phaser.GameObjects.Light; + setX(value?: number): this; /** - * Remove a Light. - * @param light The Light to remove. + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. */ - removeLight(light: Phaser.GameObjects.Light): this; + setY(value?: number): this; /** - * Shut down the Lights Manager. + * Sets the z position of this Game Object. * - * Recycles all active Lights into the Light pool, resets ambient light color and clears the lists of Lights and - * culled Lights. + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. */ - shutdown(): void; + setZ(value?: number): this; /** - * Destroy the Lights Manager. - * - * Cleans up all references by calling {@link Phaser.GameObjects.LightsManager#shutdown}. + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. */ - destroy(): void; + setW(value?: number): this; - } + /** + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. + */ + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; - /** - * A Scene plugin that provides a {@link Phaser.GameObjects.LightsManager} for the Light2D pipeline. - * - * Available from within a Scene via `this.lights`. - * - * Add Lights using the {@link Phaser.GameObjects.LightsManager#addLight} method: - * - * ```javascript - * // Enable the Lights Manager because it is disabled by default - * this.lights.enable(); - * - * // Create a Light at [400, 300] with a radius of 200 - * this.lights.addLight(400, 300, 200); - * ``` - * - * For Game Objects to be affected by the Lights when rendered, you will need to set them to use the `Light2D` pipeline like so: - * - * ```javascript - * sprite.setPipeline('Light2D'); - * ``` - * - * Note that you cannot use this pipeline on Graphics Game Objects or Shape Game Objects. - */ - class LightsPlugin extends Phaser.GameObjects.LightsManager { /** - * - * @param scene The Scene that this Lights Plugin belongs to. + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. */ - constructor(scene: Phaser.Scene); + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; /** - * A reference to the Scene that this Lights Plugin belongs to. + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. + * + * The returned Vector2 contains the translated point in its properties. + * + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. */ - scene: Phaser.Scene; + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; /** - * A reference to the Scene's systems. + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. */ - systems: Phaser.Scenes.Systems; + getParentRotation(): number; /** - * Boot the Lights Plugin. + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. */ - boot(): void; + visible: boolean; /** - * Destroy the Lights Plugin. + * Sets the visibility of this Game Object. * - * Cleans up all references. + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. */ - destroy(): void; + setVisible(value: boolean): this; } - /** - * A Mesh Game Object. - * - * The Mesh Game Object allows you to render a group of textured vertices and manipulate - * the view of those vertices, such as rotation, translation or scaling. - * - * Support for generating mesh data from grids, model data or Wavefront OBJ Files is included. - * - * Although you can use this to render 3D objects, its primary use is for displaying more complex - * Sprites, or Sprites where you need fine-grained control over the vertex positions in order to - * achieve special effects in your games. Note that rendering still takes place using Phaser's - * orthographic camera (after being transformed via `projectionMesh`, see `setPerspective`, - * `setOrtho`, and `panZ` methods). As a result, all depth and face tests are done in an eventually - * orthographic space. - * - * The rendering process will iterate through the faces of this Mesh and render out each face - * that is considered as being in view of the camera. No depth buffer is used, and because of this, - * you should be careful not to use model data with too many vertices, or overlapping geometry, - * or you'll probably encounter z-depth fighting. The Mesh was designed to allow for more advanced - * 2D layouts, rather than displaying 3D objects, even though it can do this to a degree. - * - * In short, if you want to remake Crysis, use a 3D engine, not a Mesh. However, if you want - * to easily add some small fun 3D elements into your game, or create some special effects involving - * vertex warping, this is the right object for you. Mesh data becomes part of the WebGL batch, - * just like standard Sprites, so doesn't introduce any additional shader overhead. Because - * the Mesh just generates vertices into the WebGL batch, like any other Sprite, you can use all of - * the common Game Object components on a Mesh too, such as a custom pipeline, mask, blend mode - * or texture. - * - * Note that the Mesh object is WebGL only and does not have a Canvas counterpart. - * - * The Mesh origin is always 0.5 x 0.5 and cannot be changed. - */ - class Mesh extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible, Phaser.GameObjects.Components.ScrollFactor { + namespace Particles { /** + * This class is responsible for taking control over the color property + * in the Particle class and managing its emission and updating functions. * - * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. - * @param vertices The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true` (but see note). - * @param uvs The UVs pairs array. - * @param indicies Optional vertex indicies array. If you don't have one, pass `null` or an empty array. - * @param containsZ Does the vertices data include a `z` component? Note: If not, it will be assumed `z=0`, see method `panZ` or `setOrtho`. Default false. - * @param normals Optional vertex normals array. If you don't have one, pass `null` or an empty array. - * @param colors An array of colors, one per vertex, or a single color value applied to all vertices. Default 0xffffff. - * @param alphas An array of alpha values, one per vertex, or a single alpha value applied to all vertices. Default 1. + * See the `ParticleEmitter` class for more details on emitter op configuration. */ - constructor(scene: Phaser.Scene, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number, vertices?: number[], uvs?: number[], indicies?: number[], containsZ?: boolean, normals?: number[], colors?: number | number[], alphas?: number | number[]); + class EmitterColorOp { + /** + * + * @param key The name of the property. + */ + constructor(key: string); + + /** + * An array containing the red color values. + * + * Populated during the `setMethods` method. + */ + r: number[]; + + /** + * An array containing the green color values. + * + * Populated during the `setMethods` method. + */ + g: number[]; + + /** + * An array containing the blue color values. + * + * Populated during the `setMethods` method. + */ + b: number[]; + + /** + * Checks the type of `EmitterOp.propertyValue` to determine which + * method is required in order to return values from this op function. + */ + getMethod(): number; + + /** + * Sets the EmitterColorOp method values, if in use. + */ + setMethods(): this; + + /** + * Sets the Ease function to use for Color interpolation. + * @param ease The string-based name of the Ease function to use. + */ + setEase(ease: string): void; + + /** + * An `onEmit` callback for an eased property. + * + * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterColorOp#easeValueUpdate}. + * @param particle The particle. + * @param key The name of the property. + */ + easedValueEmit(particle: Phaser.GameObjects.Particles.Particle, key: string): number; + + /** + * An `onUpdate` callback that returns an eased value between the + * {@link Phaser.GameObjects.Particles.EmitterColorOp#start} and {@link Phaser.GameObjects.Particles.EmitterColorOp#end} + * range. + * @param particle The particle. + * @param key The name of the property. + * @param t The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + */ + easeValueUpdate(particle: Phaser.GameObjects.Particles.Particle, key: string, t: number): number; + + } + + /** + * This class is responsible for taking control over a single property + * in the Particle class and managing its emission and updating functions. + * + * Particles properties such as `x`, `y`, `scaleX`, `lifespan` and others all use + * EmitterOp instances to manage them, as they can be given in a variety of + * formats: from simple values, to functions, to dynamic callbacks. + * + * See the `ParticleEmitter` class for more details on emitter op configuration. + */ + class EmitterOp { + /** + * + * @param key The name of the property. + * @param defaultValue The default value of the property. + * @param emitOnly Whether the property can only be modified when a Particle is emitted. Default false. + */ + constructor(key: string, defaultValue: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType, emitOnly?: boolean); + + /** + * The name of this property. + */ + propertyKey: string; + + /** + * The current value of this property. + * + * This can be a simple value, an array, a function or an onEmit + * configuration object. + */ + propertyValue: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + + /** + * The default value of this property. + * + * This can be a simple value, an array, a function or an onEmit + * configuration object. + */ + defaultValue: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + + /** + * The number of steps for stepped easing between {@link Phaser.GameObjects.Particles.EmitterOp#start} and + * {@link Phaser.GameObjects.Particles.EmitterOp#end} values, per emit. + */ + steps: number; + + /** + * The step counter for stepped easing, per emit. + */ + counter: number; + + /** + * When the step counter reaches it's maximum, should it then + * yoyo back to the start again, or flip over to it? + */ + yoyo: boolean; + + /** + * The counter direction. 0 for up and 1 for down. + */ + direction: number; + + /** + * The start value for this property to ease between. + * + * If an interpolation this holds a reference to the number data array. + */ + start: number | number[]; + + /** + * The most recently calculated value. Updated every time an + * emission or update method is called. Treat as read-only. + */ + current: number; + + /** + * The end value for this property to ease between. + */ + end: number; + + /** + * The easing function to use for updating this property, if any. + */ + ease: Function | null; + + /** + * The interpolation function to use for updating this property, if any. + */ + interpolation: Function | null; + + /** + * 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. + */ + emitOnly: boolean; + + /** + * The callback to run for Particles when they are emitted from the Particle Emitter. + */ + onEmit: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitCallback; + + /** + * The callback to run for Particles when they are updated. + */ + onUpdate: Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback; + + /** + * Set to `false` to disable this EmitterOp. + */ + active: boolean; + + /** + * The onEmit method type of this EmitterOp. + * + * Set as part of `setMethod` and cached here to avoid + * re-setting when only the value changes. + */ + method: number; + + /** + * Load the property from a Particle Emitter configuration object. + * + * Optionally accepts a new property key to use, replacing the current one. + * @param config Settings for the Particle Emitter that owns this property. + * @param newKey The new key to use for this property, if any. + */ + loadConfig(config?: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig, newKey?: string): void; + + /** + * Build a JSON representation of this Particle Emitter property. + */ + toJSON(): object; + + /** + * Change the current value of the property and update its callback methods. + * @param value The new numeric value of this property. + */ + onChange(value: number): this; + + /** + * Checks the type of `EmitterOp.propertyValue` to determine which + * method is required in order to return values from this op function. + */ + getMethod(): number; + + /** + * Update the {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and + * {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks based on the method returned + * from `getMethod`. The method is stored in the `EmitterOp.method` property + * and is a number between 0 and 9 inclusively. + */ + setMethods(): this; + + /** + * Check whether an object has the given property. + * @param object The object to check. + * @param key The key of the property to look for in the object. + */ + has(object: object, key: string): boolean; + + /** + * Check whether an object has both of the given properties. + * @param object The object to check. + * @param key1 The key of the first property to check the object for. + * @param key2 The key of the second property to check the object for. + */ + hasBoth(object: object, key1: string, key2: string): boolean; + + /** + * Check whether an object has at least one of the given properties. + * @param object The object to check. + * @param key1 The key of the first property to check the object for. + * @param key2 The key of the second property to check the object for. + */ + hasEither(object: object, key1: string, key2: string): boolean; + + /** + * The returned value sets what the property will be at the START of the particles life, on emit. + * @param particle The particle. + * @param key The name of the property. + * @param value The current value of the property. + */ + defaultEmit(particle: Phaser.GameObjects.Particles.Particle, key: string, value?: number): number; + + /** + * The returned value updates the property for the duration of the particles life. + * @param particle The particle. + * @param key The name of the property. + * @param t The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + * @param value The current value of the property. + */ + defaultUpdate(particle: Phaser.GameObjects.Particles.Particle, key: string, t: number, value: number): number; + + /** + * The returned value sets what the property will be at the START of the particles life, on emit. + * + * This method is only used when you have provided a custom emit callback. + * @param particle The particle. + * @param key The name of the property. + * @param value The current value of the property. + */ + proxyEmit(particle: Phaser.GameObjects.Particles.Particle, key: string, value?: number): number; + + /** + * The returned value updates the property for the duration of the particles life. + * + * This method is only used when you have provided a custom update callback. + * @param particle The particle. + * @param key The name of the property. + * @param t The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + * @param value The current value of the property. + */ + proxyUpdate(particle: Phaser.GameObjects.Particles.Particle, key: string, t: number, value: number): number; + + /** + * An `onEmit` callback that returns the current value of the property. + */ + staticValueEmit(): number; + + /** + * An `onUpdate` callback that returns the current value of the property. + */ + staticValueUpdate(): number; + + /** + * An `onEmit` callback that returns a random value from the current value array. + */ + randomStaticValueEmit(): number; + + /** + * An `onEmit` callback that returns a value between the {@link Phaser.GameObjects.Particles.EmitterOp#start} and + * {@link Phaser.GameObjects.Particles.EmitterOp#end} range. + * @param particle The particle. + * @param key The key of the property. + */ + randomRangedValueEmit(particle: Phaser.GameObjects.Particles.Particle, key: string): number; + + /** + * An `onEmit` callback that returns a value between the {@link Phaser.GameObjects.Particles.EmitterOp#start} and + * {@link Phaser.GameObjects.Particles.EmitterOp#end} range. + * @param particle The particle. + * @param key The key of the property. + */ + randomRangedIntEmit(particle: Phaser.GameObjects.Particles.Particle, key: string): number; + + /** + * An `onEmit` callback that returns a stepped value between the + * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} + * range. + */ + steppedEmit(): number; + + /** + * An `onEmit` callback for an eased property. + * + * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate}. + * @param particle The particle. + * @param key The name of the property. + */ + easedValueEmit(particle: Phaser.GameObjects.Particles.Particle, key: string): number; + + /** + * An `onUpdate` callback that returns an eased value between the + * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} + * range. + * @param particle The particle. + * @param key The name of the property. + * @param t The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + */ + easeValueUpdate(particle: Phaser.GameObjects.Particles.Particle, key: string, t: number): number; + + /** + * Destroys this EmitterOp instance and all of its references. + * + * Called automatically when the ParticleEmitter that owns this + * EmitterOp is destroyed. + */ + destroy(): void; + + } + + namespace Events { + /** + * The Particle Emitter Complete Event. + * + * This event is dispatched when the final particle, emitted from a Particle Emitter that + * has been stopped, dies. Upon receipt of this event you know that no particles are + * still rendering at this point in time. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('complete', listener)`. + */ + const COMPLETE: string; + + /** + * The Particle Emitter Death Zone Event. + * + * This event is dispatched when a Death Zone kills a Particle instance. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('deathzone', listener)`. + * + * If you wish to know when the final particle is killed, see the `COMPLETE` event. + */ + const DEATH_ZONE: string; + + /** + * The Particle Emitter Explode Event. + * + * This event is dispatched when a Particle Emitter explodes a set of particles. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('explode', listener)`. + */ + const EXPLODE: string; + + /** + * The Particle Emitter Start Event. + * + * This event is dispatched when a Particle Emitter starts emission of particles. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('start', listener)`. + */ + const START: string; + + /** + * The Particle Emitter Stop Event. + * + * This event is dispatched when a Particle Emitter is stopped. This can happen either + * when you directly call the `ParticleEmitter.stop` method, or if the emitter has + * been configured to stop after a set time via the `duration` property, or after a + * set number of particles via the `stopAfter` property. + * + * Listen for it on a Particle Emitter instance using `ParticleEmitter.on('stop', listener)`. + * + * Note that just because the emitter has stopped, that doesn't mean there aren't still + * particles alive and rendering. It just means the emitter has stopped emitting particles. + * + * If you wish to know when the final particle is killed, see the `COMPLETE` event. + */ + const STOP: string; + + } /** - * An array containing the Face instances belonging to this Mesh. + * The Gravity Well Particle Processor applies a force on the particles to draw + * them towards, or repel them from, a single point. * - * A Face consists of 3 Vertex objects. + * 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 array is populated during calls such as `addVertices` or `addOBJ`. + * This simulates the effect of gravity over large distances (as between planets, for example). */ - faces: Phaser.Geom.Mesh.Face[]; + class GravityWell extends Phaser.GameObjects.Particles.ParticleProcessor { + /** + * + * @param x The x coordinate of the Gravity Well, in world space. Default 0. + * @param y The y coordinate of the Gravity Well, in world space. Default 0. + * @param power The strength of the gravity force - larger numbers produce a stronger force. Default 0. + * @param epsilon The minimum distance for which the gravity force is calculated. Default 100. + * @param gravity The gravitational force of this Gravity Well. Default 50. + */ + constructor(x?: number | Phaser.Types.GameObjects.Particles.GravityWellConfig, y?: number, power?: number, epsilon?: number, gravity?: number); - /** - * An array containing Vertex instances. One instance per vertex in this Mesh. - * - * This array is populated during calls such as `addVertex` or `addOBJ`. - */ - vertices: Phaser.Geom.Mesh.Vertex[]; + /** + * Takes a Particle and updates it based on the properties of this Gravity Well. + * @param particle The Particle to update. + * @param delta The delta time in ms. + * @param step The delta value divided by 1000. + */ + update(particle: Phaser.GameObjects.Particles.Particle, delta: number, step: number): void; - /** - * The tint fill mode. - * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertex colors replace the texture, but respects texture alpha. - */ - tintFill: boolean; + /** + * The minimum distance for which the gravity force is calculated. + * + * Defaults to 100. + */ + epsilon: number; - /** - * You can optionally choose to render the vertices of this Mesh to a Graphics instance. - * - * Achieve this by setting the `debugCallback` and the `debugGraphic` properties. - * - * You can do this in a single call via the `Mesh.setDebug` method, which will use the - * built-in debug function. You can also set it to your own callback. The callback - * will be invoked _once per render_ and sent the following parameters: - * - * `debugCallback(src, meshLength, verts)` - * - * `src` is the Mesh instance being debugged. - * `meshLength` is the number of mesh vertices in total. - * `verts` is an array of the translated vertex coordinates. - * - * To disable rendering, set this property back to `null`. - * - * Please note that high vertex count Meshes will struggle to debug properly. - */ - debugCallback: Function; + /** + * The strength of the gravity force - larger numbers produce a stronger force. + * + * Defaults to 0. + */ + power: number; - /** - * The Graphics instance that the debug vertices will be drawn to, if `setDebug` has - * been called. - */ - debugGraphic: Phaser.GameObjects.Graphics; + /** + * The gravitational force of this Gravity Well. + * + * Defaults to 50. + */ + gravity: number; - /** - * When rendering, skip any Face that isn't counter clockwise? - * - * Enable this to hide backward-facing Faces during rendering. - * - * Disable it to render all Faces. - */ - hideCCW: boolean; + } /** - * A Vector3 containing the 3D position of the vertices in this Mesh. + * A Particle is a simple object owned and controlled by a Particle Emitter. * - * Modifying the components of this property will allow you to reposition where - * the vertices are rendered within the Mesh. This happens in the `preUpdate` phase, - * where each vertex is transformed using the view and projection matrices. - * - * Changing this property will impact all vertices being rendered by this Mesh. - * - * You can also adjust the 'view' by using the `pan` methods. + * It encapsulates all of the properties required to move and update according + * to the Emitters operations. */ - modelPosition: Phaser.Math.Vector3; + class Particle { + /** + * + * @param emitter The Emitter to which this Particle belongs. + */ + constructor(emitter: Phaser.GameObjects.Particles.ParticleEmitter); - /** - * A Vector3 containing the 3D scale of the vertices in this Mesh. - * - * Modifying the components of this property will allow you to scale - * the vertices within the Mesh. This happens in the `preUpdate` phase, - * where each vertex is transformed using the view and projection matrices. - * - * Changing this property will impact all vertices being rendered by this Mesh. - */ - modelScale: Phaser.Math.Vector3; + /** + * The Emitter to which this Particle belongs. + * + * A Particle can only belong to a single Emitter and is created, updated and destroyed by it. + */ + emitter: Phaser.GameObjects.Particles.ParticleEmitter; - /** - * A Vector3 containing the 3D rotation of the vertices in this Mesh. - * - * The values should be given in radians, i.e. to rotate the vertices by 90 - * degrees you can use `modelRotation.x = Phaser.Math.DegToRad(90)`. - * - * Modifying the components of this property will allow you to rotate - * the vertices within the Mesh. This happens in the `preUpdate` phase, - * where each vertex is transformed using the view and projection matrices. - * - * Changing this property will impact all vertices being rendered by this Mesh. - */ - modelRotation: Phaser.Math.Vector3; + /** + * The texture used by this Particle when it renders. + */ + texture: Phaser.Textures.Texture; - /** - * The transformation matrix for this Mesh. - */ - transformMatrix: Phaser.Math.Matrix4; + /** + * The texture frame used by this Particle when it renders. + */ + frame: Phaser.Textures.Frame; - /** - * The view position for this Mesh. - * - * Use the methods`panX`, `panY` and `panZ` to adjust the view. - */ - viewPosition: Phaser.Math.Vector3; + /** + * The x coordinate of this Particle. + */ + x: number; - /** - * The view matrix for this Mesh. - */ - viewMatrix: Phaser.Math.Matrix4; + /** + * The y coordinate of this Particle. + */ + y: number; - /** - * The projection matrix for this Mesh. - * - * Update it with the `setPerspective` or `setOrtho` methods. - */ - projectionMatrix: Phaser.Math.Matrix4; + /** + * The coordinates of this Particle in world space. + * + * Updated as part of `computeVelocity`. + */ + worldPosition: Phaser.Math.Vector2; - /** - * How many faces were rendered by this Mesh Game Object in the last - * draw? This is reset in the `preUpdate` method and then incremented - * each time a face is drawn. Note that in multi-camera Scenes this - * value may exceed that found in `Mesh.getFaceCount` due to - * cameras drawing the same faces more than once. - */ - readonly totalRendered: number; + /** + * The x velocity of this Particle. + */ + velocityX: number; - /** - * By default, the Mesh will check to see if its model or view transform has - * changed each frame and only recalculate the vertex positions if they have. - * - * This avoids lots of additional math in the `preUpdate` step when not required. - * - * However, if you are performing per-Face or per-Vertex manipulation on this Mesh, - * such as tweening a Face, or moving it without moving the rest of the Mesh, - * then you may need to disable the dirty cache in order for the Mesh to re-render - * correctly. You can toggle this property to do that. Please note that leaving - * this set to `true` will cause the Mesh to recalculate the position of every single - * vertex in it, every single frame. So only really do this if you know you - * need it. - */ - ignoreDirtyCache: boolean; + /** + * The y velocity of this Particle. + */ + velocityY: number; - /** - * Translates the view position of this Mesh on the x axis by the given amount. - * @param v The amount to pan by. - */ - panX(v: number): void; + /** + * The x acceleration of this Particle. + */ + accelerationX: number; - /** - * Translates the view position of this Mesh on the y axis by the given amount. - * @param v The amount to pan by. - */ - panY(v: number): void; + /** + * The y acceleration of this Particle. + */ + accelerationY: number; - /** - * Translates the view position of this Mesh on the z axis by the given amount. - * - * As the default `panZ` value is 0, vertices with `z=0` (the default) need special care or else they will not display as they are behind the camera. - * Consider using `mesh.panZ(mesh.height / (2 * Math.tan(Math.PI / 16)))`, which will interpret vertex geometry 1:1 with pixel geometry (or see `setOrtho`). - * @param v The amount to pan by. - */ - panZ(v: number): void; + /** + * The maximum horizontal velocity this Particle can travel at. + */ + maxVelocityX: number; - /** - * Builds a new perspective projection matrix from the given values. - * - * These are also the initial projection matrix & parameters for `Mesh` (and see `panZ` for more discussion). - * - * See also `setOrtho`. - * @param width The width of the projection matrix. Typically the same as the Mesh and/or Renderer. - * @param height The height of the projection matrix. Typically the same as the Mesh and/or Renderer. - * @param fov The field of view, in degrees. Default 45. - * @param near The near value of the view. Default 0.01. - * @param far The far value of the view. Default 1000. - */ - setPerspective(width: number, height: number, fov?: number, near?: number, far?: number): void; + /** + * The maximum vertical velocity this Particle can travel at. + */ + maxVelocityY: number; - /** - * Builds a new orthographic projection matrix from the given values. - * - * If using this mode you will often need to set `Mesh.hideCCW` to `false` as well. - * - * By default, calling this method with no parameters will set the scaleX value to - * match the renderer's aspect ratio. If you would like to render vertex positions 1:1 - * to pixel positions, consider calling as `mesh.setOrtho(mesh.width, mesh.height)`. - * - * See also `setPerspective`. - * @param scaleX The default horizontal scale in relation to the Mesh / Renderer dimensions. Default 1. - * @param scaleY The default vertical scale in relation to the Mesh / Renderer dimensions. Default 1. - * @param near The near value of the view. Default -1000. - * @param far The far value of the view. Default 1000. - */ - setOrtho(scaleX?: number, scaleY?: number, near?: number, far?: number): void; + /** + * The bounciness, or restitution, of this Particle. + */ + bounce: number; - /** - * Iterates and destroys all current Faces in this Mesh, then resets the - * `faces` and `vertices` arrays. - */ - clear(): this; + /** + * The horizontal scale of this Particle. + */ + scaleX: number; - /** - * This method will add the data from a triangulated Wavefront OBJ model file to this Mesh. - * - * The data should have been loaded via the OBJFile: - * - * ```javascript - * this.load.obj(key, url); - * ``` - * - * Then use the same `key` as the first parameter to this method. - * - * Multiple Mesh Game Objects can use the same model data without impacting on each other. - * - * Make sure your 3D package has triangulated the model data prior to exporting it. - * - * You can 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 too large, to see. - * You can also offset the vertices of the model via the `x`, `y` and `z` parameters. - * @param key The key of the model data in the OBJ Cache to add to this Mesh. - * @param scale An amount to scale the model data by. Use this if the model has exported too small, or large, to see. Default 1. - * @param x Translate the model x position by this amount. Default 0. - * @param y Translate the model y position by this amount. Default 0. - * @param z Translate the model z position by this amount. Default 0. - * @param rotateX Rotate the model on the x axis by this amount, in radians. Default 0. - * @param rotateY Rotate the model on the y axis by this amount, in radians. Default 0. - * @param rotateZ Rotate the model on the z axis by this amount, in radians. Default 0. - * @param zIsUp Is the z axis up (true), or is y axis up (false)? Default true. - */ - addVerticesFromObj(key: string, scale?: number, x?: number, y?: number, z?: number, rotateX?: number, rotateY?: number, rotateZ?: number, zIsUp?: boolean): this; + /** + * The vertical scale of this Particle. + */ + scaleY: number; - /** - * Compare the depth of two Faces. - * @param faceA The first Face. - * @param faceB The second Face. - */ - sortByDepth(faceA: Phaser.Geom.Mesh.Face, faceB: Phaser.Geom.Mesh.Face): number; + /** + * The alpha value of this Particle. + */ + alpha: number; - /** - * Runs a depth sort across all Faces in this Mesh, comparing their averaged depth. - * - * This is called automatically if you use any of the `rotate` methods, but you can - * also invoke it to sort the Faces should you manually position them. - */ - depthSort(): this; + /** + * The angle of this Particle in degrees. + */ + angle: number; - /** - * Adds a new Vertex into the vertices array of this Mesh. - * - * Just adding a vertex isn't enough to render it. You need to also - * make it part of a Face, with 3 Vertex instances per Face. - * @param x The x position of the vertex. - * @param y The y position of the vertex. - * @param z The z position of the vertex. - * @param u The UV u coordinate of the vertex. - * @param v The UV v coordinate of the vertex. - * @param color The color value of the vertex. Default 0xffffff. - * @param alpha The alpha value of the vertex. Default 1. - */ - addVertex(x: number, y: number, z: number, u: number, v: number, color?: number, alpha?: number): this; + /** + * The angle of this Particle in radians. + */ + rotation: number; - /** - * Adds a new Face into the faces array of this Mesh. - * - * A Face consists of references to 3 Vertex instances, which must be provided. - * @param vertex1 The first vertex of the Face. - * @param vertex2 The second vertex of the Face. - * @param vertex3 The third vertex of the Face. - */ - addFace(vertex1: Phaser.Geom.Mesh.Vertex, vertex2: Phaser.Geom.Mesh.Vertex, vertex3: Phaser.Geom.Mesh.Vertex): this; + /** + * The tint applied to this Particle. + */ + tint: number; - /** - * Adds new vertices to this Mesh 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, and will result in `z=0` for each vertex). - * - * 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 - * let mesh = new Mesh(this); // Assuming `this` is a scene! - * 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 ]; - * - * mesh.addVertices(vertices, uvs, indicies); - * // Note: Otherwise the added points will be "behind" the camera! This value will project vertex `x` & `y` values 1:1 to pixel values. - * mesh.hideCCW = false; - * mesh.setOrtho(mesh.width, mesh.height); - * ``` - * - * If the data is not indexed, it's assumed that the arrays all contain sequential data. - * @param vertices The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`. - * @param uvs The UVs pairs array. - * @param indicies Optional vertex indicies array. If you don't have one, pass `null` or an empty array. - * @param containsZ Does the vertices data include a `z` component? If not, it will be assumed `z=0`, see methods `panZ` or `setOrtho`. Default false. - * @param normals Optional vertex normals array. If you don't have one, pass `null` or an empty array. - * @param colors An array of colors, one per vertex, or a single color value applied to all vertices. Default 0xffffff. - * @param alphas An array of alpha values, one per vertex, or a single alpha value applied to all vertices. Default 1. - */ - addVertices(vertices: number[], uvs: number[], indicies?: number[], containsZ?: boolean, normals?: number[], colors?: number | number[], alphas?: number | number[]): this; + /** + * The lifespan of this Particle in ms. + */ + life: number; - /** - * Returns the total number of Faces in this Mesh Game Object. - */ - getFaceCount(): number; + /** + * The current life of this Particle in ms. + */ + lifeCurrent: number; - /** - * Returns the total number of Vertices in this Mesh Game Object. - */ - getVertexCount(): number; + /** + * The delay applied to this Particle upon emission, in ms. + */ + delayCurrent: number; - /** - * Returns the Face at the given index in this Mesh Game Object. - * @param index The index of the Face to get. - */ - getFace(index: number): Phaser.Geom.Mesh.Face; + /** + * The hold applied to this Particle before it expires, in ms. + */ + holdCurrent: number; + + /** + * The normalized lifespan T value, where 0 is the start and 1 is the end. + */ + lifeT: number; + + /** + * The data used by the ease equation. + */ + data: object; + + /** + * A reference to the Scene to which this Game Object belongs. + * + * Game Objects can only belong to one Scene. + * + * You should consider this property as being read-only. You cannot move a + * Game Object to another Scene by simply changing it. + */ + scene: Phaser.Scene; + + /** + * The Animation State component of this Particle. + * + * This component provides features to apply animations to this Particle. + * It is responsible for playing, loading, queuing animations for later playback, + * mixing between animations and setting the current animation frame to this Particle. + */ + anims: Phaser.Animations.AnimationState; + + /** + * A rectangle that holds the bounds of this Particle after a call to + * the `Particle.getBounds` method has been made. + */ + bounds: Phaser.Geom.Rectangle; + + /** + * The Event Emitter proxy. + * + * Passes on all parameters to the `ParticleEmitter` to emit directly. + * @param event The event name. + * @param a1 Optional argument 1. + * @param a2 Optional argument 2. + * @param a3 Optional argument 3. + * @param a4 Optional argument 4. + * @param a5 Optional argument 5. + */ + emit(event: string | Symbol, a1?: any, a2?: any, a3?: any, a4?: any, a5?: any): boolean; + + /** + * Checks to see if this Particle is alive and updating. + */ + isAlive(): boolean; + + /** + * Kills this particle. This sets the `lifeCurrent` value to 0, which forces + * the Particle to be removed the next time its parent Emitter runs an update. + */ + kill(): void; + + /** + * Sets the position of this particle to the given x/y coordinates. + * + * If the parameters are left undefined, it resets the particle back to 0x0. + * @param x The x coordinate to set this Particle to. Default 0. + * @param y The y coordinate to set this Particle to. Default 0. + */ + setPosition(x?: number, y?: number): void; + + /** + * Starts this Particle from the given coordinates. + * @param x The x coordinate to launch this Particle from. + * @param y The y coordinate to launch this Particle from. + */ + fire(x?: number, y?: number): boolean; + + /** + * The main update method for this Particle. + * + * Updates its life values, computes the velocity and repositions the Particle. + * @param delta The delta time in ms. + * @param step The delta value divided by 1000. + * @param processors An array of all active Particle Processors. + */ + update(delta: number, step: number, processors: Phaser.GameObjects.Particles.ParticleProcessor[]): boolean; + + /** + * An internal method that calculates the velocity of the Particle and + * its world position. It also runs it against any active Processors + * that are set on the Emitter. + * @param emitter The Emitter that is updating this Particle. + * @param delta The delta time in ms. + * @param step The delta value divided by 1000. + * @param processors An array of all active Particle Processors. + * @param t The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + */ + computeVelocity(emitter: Phaser.GameObjects.Particles.ParticleEmitter, delta: number, step: number, processors: Phaser.GameObjects.Particles.ParticleProcessor[], t: number): void; + + /** + * This is a NOOP method and does nothing when called. + */ + setSizeToFrame(): void; + + /** + * Gets the bounds of this particle as a Geometry Rectangle, factoring in any + * transforms of the parent emitter and anything else above it in the display list. + * + * Once calculated the bounds can be accessed via the `Particle.bounds` property. + * @param matrix Optional transform matrix to apply to this particle. + */ + getBounds(matrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.Geom.Rectangle; + + /** + * Destroys this Particle. + */ + destroy(): void; + + } /** - * Return an array of Face objects from this Mesh that intersect with the given coordinates. + * The Particle Bounds Processor. * - * The given position is translated through the matrix of this Mesh and the given Camera, - * before being compared against the vertices. + * Defines a rectangular region, in world space, within which particle movement + * is restrained. * - * If more than one Face intersects, they will all be returned in the array, but the array will - * be depth sorted first, so the first element will always be that closest to the camera. - * @param x The x position to check against. - * @param y The y position to check against. - * @param camera The camera to pass the coordinates through. If not give, the default Scene Camera is used. + * Use the properties `collideLeft`, `collideRight`, `collideTop` and + * `collideBottom` to control if a particle will rebound off the sides + * of this boundary, or not. + * + * This happens when the particles worldPosition x/y coordinate hits the boundary. + * + * The strength of the rebound is determined by the `Particle.bounce` property. */ - getFaceAt(x: number, y: number, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Geom.Mesh.Face[]; + class ParticleBounds extends Phaser.GameObjects.Particles.ParticleProcessor { + /** + * + * @param x The x position (top-left) of the bounds, in world space. + * @param y The y position (top-left) of the bounds, in world space. + * @param width The width of the bounds. + * @param height The height of the bounds. + * @param collideLeft Whether particles interact with the left edge of the bounds. Default true. + * @param collideRight Whether particles interact with the right edge of the bounds. Default true. + * @param collideTop Whether particles interact with the top edge of the bounds. Default true. + * @param collideBottom Whether particles interact with the bottom edge of the bounds. Default true. + */ + constructor(x: number, y: number, width: number, height: number, collideLeft?: boolean, collideRight?: boolean, collideTop?: boolean, collideBottom?: boolean); + + /** + * A rectangular boundary constraining particle movement. Use the Emitter properties `collideLeft`, + * `collideRight`, `collideTop` and `collideBottom` to control if a particle will rebound off + * the sides of this boundary, or not. This happens when the particles x/y coordinate hits + * the boundary. + */ + bounds: Phaser.Geom.Rectangle; + + /** + * Whether particles interact with the left edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + */ + collideLeft: boolean; + + /** + * Whether particles interact with the right edge of the emitter {@link Phaser.GameObjects.Particles.ParticleBounds#bounds}. + */ + collideRight: boolean; + + /** + * Whether particles interact with the top edge of the emitter {@link Phaser.GameObjects.Particles.ParticleBounds#bounds}. + */ + collideTop: boolean; + + /** + * Whether particles interact with the bottom edge of the emitter {@link Phaser.GameObjects.Particles.ParticleBounds#bounds}. + */ + collideBottom: boolean; + + /** + * Takes a Particle and updates it against the bounds. + * @param particle The Particle to update. + */ + update(particle: Phaser.GameObjects.Particles.Particle): void; + + } /** - * This method enables rendering of the Mesh vertices to the given Graphics instance. - * - * If you enable this feature, you **must** call `Graphics.clear()` in your Scene `update`, - * otherwise the Graphics instance you provide to debug will fill-up with draw calls, - * eventually crashing the browser. This is not done automatically to allow you to debug - * draw multiple Mesh objects to a single Graphics instance. - * - * The Mesh class has a built-in debug rendering callback `Mesh.renderDebug`, however - * you can also provide your own callback to be used instead. Do this by setting the `callback` parameter. - * - * The callback is invoked _once per render_ and sent the following parameters: + * A Particle Emitter is a special kind of Game Object that controls a pool of {@link Phaser.GameObjects.Particles.Particle Particles}. * - * `callback(src, faces)` + * Particle Emitters are created via a configuration object. The properties of this object + * can be specified in a variety of formats, given you plenty of scope over the values they + * return, leading to complex visual effects. Here are the different forms of configuration + * value you can give: * - * `src` is the Mesh instance being debugged. - * `faces` is an array of the Faces that were rendered. + * ## An explicit static value: * - * You can get the final drawn vertex position from a Face object like this: + * ```js + * x: 400 + * ``` * - * ```javascript - * let face = faces[i]; + * The x value will always be 400 when the particle is spawned. * - * let x0 = face.vertex1.tx; - * let y0 = face.vertex1.ty; - * let x1 = face.vertex2.tx; - * let y1 = face.vertex2.ty; - * let x2 = face.vertex3.tx; - * let y2 = face.vertex3.ty; + * ## A random value: * - * graphic.strokeTriangle(x0, y0, x1, y1, x2, y2); + * ```js + * x: [ 100, 200, 300, 400 ] * ``` * - * If using your own callback you do not have to provide a Graphics instance to this method. + * The x value will be one of the 4 elements in the given array, picked at random on emission. * - * To disable debug rendering, to either your own callback or the built-in one, call this method - * with no arguments. - * @param graphic The Graphic instance to render to if using the built-in callback. - * @param callback The callback to invoke during debug render. Leave as undefined to use the built-in callback. - */ - setDebug(graphic?: Phaser.GameObjects.Graphics, callback?: Function): this; - - /** - * Checks if the transformation data in this mesh is dirty. + * ## A custom callback: * - * This is used internally by the `preUpdate` step to determine if the vertices should - * be recalculated or not. - */ - isDirty(): boolean; - - /** - * The Mesh update loop. The following takes place in this method: + * ```js + * x: (particle, key, t, value) => { + * return value + 50; + * } + * ``` * - * First, the `totalRendered` and `totalFrame` properties are set. + * The x value is the result of calling this function. This is only used when the + * particle is emitted, so it provides it's initial starting value. It is not used + * when the particle is updated (see the onUpdate callback for that) * - * If the view matrix of this Mesh isn't dirty, and the model position, rotate or scale properties are - * all clean, then the method returns at this point. + * ## A start / end object: * - * Otherwise, if the viewPosition is dirty (i.e. from calling a method like `panZ`), then it will - * refresh the viewMatrix. + * This allows you to control the change in value between the given start and + * end parameters over the course of the particles lifetime: * - * After this, a new transformMatrix is built and it then iterates through all Faces in this - * Mesh, calling `transformCoordinatesLocal` on all of them. Internally, this updates every - * vertex, calculating its new transformed position, based on the new transform matrix. + * ```js + * scale: { start: 0, end: 1 } + * ``` * - * Finally, the faces are depth sorted. - * @param time The current timestamp. - * @param delta The delta time, in ms, elapsed since the last frame. - */ - protected preUpdate(time: number, delta: number): void; - - /** - * The built-in Mesh debug rendering method. + * The particle scale will start at 0 when emitted and ease to a scale of 1 + * over the course of its lifetime. You can also specify the ease function + * used for this change (the default is Linear): * - * See `Mesh.setDebug` for more details. - * @param src The Mesh object being rendered. - * @param faces An array of Faces. - */ - renderDebug(src: Phaser.GameObjects.Mesh, faces: Phaser.Geom.Mesh.Face[]): void; - - /** - * Clears all alpha values associated with this Game Object. + * ```js + * scale: { start: 0, end: 1, ease: 'bounce.out' } + * ``` * - * Immediately sets the alpha levels back to 1 (fully opaque). - */ - clearAlpha(): this; - - /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. - * @param value The alpha value applied across the whole Game Object. Default 1. - */ - setAlpha(value?: number): this; - - /** - * The alpha value of the Game Object. + * ## A start / end random object: * - * This is a global value, impacting the entire Game Object, not just a region of it. - */ - alpha: number; - - /** - * Sets the Blend Mode being used by this Game Object. + * The start and end object can have an optional `random` parameter. + * This forces it to pick a random value between the two values and use + * this as the starting value, then easing to the 'end' parameter over + * its lifetime. * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * ```js + * scale: { start: 4, end: 0.5, random: true } + * ``` * - * Under WebGL only the following Blend Modes are available: + * The particle will start with a random scale between 0.5 and 4 and then + * scale to the end value over its lifetime. You can combine the above + * with the `ease` parameter as well to control the value easing. * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE + * ## An interpolation object: * - * Canvas has more available depending on browser support. + * You can provide an array of values which will be used for interpolation + * during the particles lifetime. You can also define the interpolation + * function to be used. There are three provided: `linear` (the default), + * `bezier` and `catmull`, or you can provide your own function. * - * You can also create your own custom Blend Modes in WebGL. + * ```js + * x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull' } + * ``` * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency of which blend modes - * are used. - */ - blendMode: Phaser.BlendModes | string; - - /** - * Sets the Blend Mode being used by this Game Object. + * The particle scale will interpolate from 50 when emitted to 800 via the other + * points over the course of its lifetime. You can also specify an ease function + * used to control the rate of change through the values (the default is Linear): * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * ```js + * x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull', ease: 'bounce.out } + * ``` * - * Under WebGL only the following Blend Modes are available: + * ## A stepped emitter object: * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * The `steps` parameter allows you to control the placement of sequential + * particles across the start-end range: * - * Canvas has more available depending on browser support. + * ```js + * x: { steps: 32, start: 0, end: 576 } + * ``` * - * You can also create your own custom Blend Modes in WebGL. + * Here we have a range of 576 (start to end). This is divided into 32 steps. * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency in which blend modes - * are used. - * @param value The BlendMode value. Either a string or a CONST. - */ - setBlendMode(value: string | Phaser.BlendModes): this; - - /** - * The depth of this Game Object within the Scene. + * The first particle will emit at the x position of 0. The next will emit + * at the next 'step' along, which would be 18. The following particle will emit + * at the next step, which is 36, and so on. Because the range of 576 has been + * divided by 32, creating 18 pixels steps. When a particle reaches the 'end' + * value the next one will start from the beginning again. * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. + * ## A stepped emitter object with yoyo: * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. + * You can add the optional `yoyo` property to a stepped object: * - * Setting the depth will queue a depth sort event within the Scene. - */ - depth: number; - - /** - * The depth of this Game Object within the Scene. + * ```js + * x: { steps: 32, start: 0, end: 576, yoyo: true } + * ``` * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. + * As with the stepped emitter, particles are emitted in sequence, from 'start' + * to 'end' in step sized jumps. Normally, when a stepped emitter reaches the + * end it snaps around to the start value again. However, if you provide the 'yoyo' + * parameter then when it reaches the end it will reverse direction and start + * emitting back down to 'start' again. Depending on the effect you require this + * can often look better. * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. + * ## A min / max object: * - * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. - */ - setDepth(value: number): this; - - /** - * The Mask this Game Object is using during render. - */ - mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; - - /** - * Sets the mask that this Game Object will use to render with. + * This allows you to pick a random float value between the min and max properties: * - * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * ```js + * x: { min: 100, max: 700 } + * ``` * - * If a mask is already set on this Game Object it will be immediately replaced. + * The x value will be a random float between min and max. * - * Masks are positioned in global space and are not relative to the Game Object to which they - * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * You can force it select an integer by setting the 'int' flag: * - * Masks have no impact on physics or input detection. They are purely a rendering component - * that allows you to limit what is visible during the render pass. - * @param mask The mask this Game Object will use when rendering. - */ - setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; - - /** - * Clears the mask that this Game Object was using. - * @param destroyMask Destroy the mask before clearing it? Default false. - */ - clearMask(destroyMask?: boolean): this; - - /** - * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * ```js + * x: { min: 100, max: 700, int: true } + * ``` * - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * Or, you could use the 'random' array approach (see below) * - * To create the mask you need to pass in a reference to a renderable Game Object. - * A renderable Game Object is one that uses a texture to render with, such as an - * Image, Sprite, Render Texture or BitmapText. + * ## A random object: * - * If you do not provide a renderable object, and this Game Object has a texture, - * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. - */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; - - /** - * Creates and returns a Geometry Mask. This mask can be used by any Game Object, - * including this one. + * This allows you to pick a random integer value between the first and second array elements: * - * To create the mask you need to pass in a reference to a Graphics Game Object. + * ```js + * x: { random: [ 100, 700 ] } + * ``` * - * If you do not provide a graphics object, and this Game Object is an instance - * of a Graphics object, then it will use itself to create the mask. + * The x value will be a random integer between 100 and 700 as it takes the first + * element in the 'random' array as the 'min' value and the 2nd element as the 'max' value. * - * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. - */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; - - /** - * The initial WebGL pipeline of this Game Object. + * ## Custom onEmit and onUpdate callbacks: * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. - */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; - - /** - * The current WebGL pipeline of this Game Object. - */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; - - /** - * Does this Game Object have any Post Pipelines set? - */ - hasPostPipeline: boolean; - - /** - * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * If the above won't give you the effect you're after, you can provide your own + * callbacks that will be used when the particle is both emitted and updated: * - * The pipelines are processed in the order in which they appear in this array. + * ```js + * x: { + * onEmit: (particle, key, t, value) => { + * return value; + * }, + * onUpdate: (particle, key, t, value) => { + * return value; + * } + * } + * ``` * - * If you modify this array directly, be sure to set the - * `hasPostPipeline` property accordingly. - */ - postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - - /** - * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. - */ - pipelineData: object; - - /** - * Sets the initial WebGL Pipeline of this Game Object. + * You can provide either one or both functions. The `onEmit` is called at the + * start of the particles life and defines the value of the property on birth. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; - - /** - * Sets the main WebGL Pipeline of this Game Object. + * The `onUpdate` function is called every time the Particle Emitter updates + * until the particle dies. Both must return a value. * - * Also sets the `pipelineData` property, if the parameter is given. + * The properties are: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. - */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; - - /** - * Sets one, or more, Post Pipelines on this Game Object. + * particle - A reference to the Particle instance. + * key - The string based key of the property, i.e. 'x' or 'lifespan'. + * t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death). + * value - The current property value. At a minimum you should return this. * - * Post Pipelines are invoked after this Game Object has rendered to its target and - * are commonly used for post-fx. + * By using the above configuration options you have an unlimited about of + * control over how your particles behave. * - * The post pipelines are appended to the `postPipelines` array belonging to this - * Game Object. When the renderer processes this Game Object, it iterates through the post - * pipelines in the order in which they appear in the array. If you are stacking together - * multiple effects, be aware that the order is important. + * ## v3.55 Differences * - * If you call this method multiple times, the new pipelines will be appended to any existing - * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * Prior to v3.60 Phaser used a `ParticleEmitterManager`. This was removed in v3.60 + * and now calling `this.add.particles` returns a `ParticleEmitter` instance instead. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. + * In order to streamline memory and the display list we have removed the + * `ParticleEmitterManager` entirely. When you call `this.add.particles` you're now + * creating a `ParticleEmitter` instance, which is being added directly to the + * display list and can be manipulated just like any other Game Object, i.e. + * scaled, rotated, positioned, added to a Container, etc. It now extends the + * `GameObject` base class, meaning it's also an event emitter, which allowed us + * to create some handy new events for particles. * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. - */ - setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; - - /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * So, to create an emitter, you now give it an xy coordinate, a texture and an + * emitter configuration object (you can also set this later, but most commonly + * you'd do it on creation). I.e.: * - * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * ```js + * const emitter = this.add.particles(100, 300, 'flares', { + * frame: 'red', + * angle: { min: -30, max: 30 }, + * speed: 150 + * }); + * ``` * - * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * This will create a 'red flare' emitter at 100 x 300. * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param key The key of the pipeline data to set, update, or delete. - * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + * Please update your code to ensure it adheres to the new function signatures. */ - setPipelineData(key: string, value?: any): this; - - /** - * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. - * @param pipeline The string-based name of the pipeline, or a pipeline class. - */ - getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; + class ParticleEmitter extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + /** + * + * @param config Settings for this emitter. + */ + constructor(config: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig); - /** - * Resets the WebGL Post Pipelines of this Game Object. It does this by calling - * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPostPipeline(resetData?: boolean): void; + /** + * The Particle Class which will be emitted by this Emitter. + */ + particleClass: Function; - /** - * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. - * - * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. - * @param pipeline The string-based name of the pipeline, or a pipeline class. - */ - removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; + /** + * An internal object holding all of the EmitterOp instances. + * + * These are populated as part of the Emitter configuration parsing. + * + * You typically do not access them directly, but instead use the + * provided getters and setters on this class, such as `ParticleEmitter.speedX` etc. + */ + ops: Phaser.Types.GameObjects.Particles.ParticleEmitterOps; - /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. - */ - getPipelineName(): string; + /** + * 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. + */ + radial: boolean; - /** - * The native (un-scaled) width of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. - */ - width: number; + /** + * Horizontal acceleration applied to emitted particles, in pixels per second squared. + */ + gravityX: number; - /** - * The native (un-scaled) height of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. - */ - height: number; + /** + * Vertical acceleration applied to emitted particles, in pixels per second squared. + */ + gravityY: number; - /** - * The displayed width of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - */ - displayWidth: number; + /** + * Whether accelerationX and accelerationY are non-zero. Set automatically during configuration. + */ + acceleration: boolean; - /** - * The displayed height of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - */ - displayHeight: number; + /** + * Whether moveToX and moveToY are set. Set automatically during configuration. + * + * When true the particles move toward the moveToX and moveToY coordinates and arrive at the end of their life. + * Emitter angle, speedX, and speedY are ignored. + */ + moveTo: boolean; - /** - * Sets the size of this Game Object to be that of the given Frame. - * - * This will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or call the - * `setDisplaySize` method, which is the same thing as changing the scale but allows you - * to do so by giving pixel values. - * - * If you have enabled this Game Object for input, changing the size will _not_ change the - * size of the hit area. To do this you should adjust the `input.hitArea` object directly. - * @param frame The frame to base the size of this Game Object on. - */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + /** + * A function to call when a particle is emitted. + */ + emitCallback: Phaser.Types.GameObjects.Particles.ParticleEmitterCallback | null; - /** - * 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. - * @param width The width of this Game Object. - * @param height The height of this Game Object. - */ - setSize(width: number, height: number): this; + /** + * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#emitCallback}. + */ + emitCallbackScope: any | null; - /** - * Sets the display size of this Game Object. - * - * Calling this will adjust the scale. - * @param width The width of this Game Object. - * @param height The height of this Game Object. - */ - setDisplaySize(width: number, height: number): this; + /** + * A function to call when a particle dies. + */ + deathCallback: Phaser.Types.GameObjects.Particles.ParticleDeathCallback | null; - /** - * The Texture this Game Object is using to render with. - */ - texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + /** + * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#deathCallback}. + */ + deathCallbackScope: any | null; - /** - * The Texture Frame this Game Object is using to render with. - */ - frame: Phaser.Textures.Frame; + /** + * Set to hard limit the amount of particle objects this emitter is allowed to create + * in total. This is the number of `Particle` instances it can create, not the number + * of 'alive' particles. + * + * 0 means unlimited. + */ + maxParticles: number; - /** - * Sets the texture and frame this Game Object will use to render with. - * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. - * @param frame The name or index of the frame within the Texture. - */ - setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; + /** + * The maximum number of alive and rendering particles this emitter will update. + * When this limit is reached, a particle needs to die before another can be emitted. + * + * 0 means no limits. + */ + maxAliveParticles: number; - /** - * Sets the frame this Game Object will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. - * - * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. - * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. - * @param updateSize Should this call adjust the size of the Game Object? Default true. - * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. - */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + /** + * If set, either via the Emitter config, or by directly setting this property, + * the Particle Emitter will stop emitting particles once this total has been + * reached. It will then enter a 'stopped' state, firing the `STOP` + * event. Note that entering a stopped state doesn't mean all the particles + * have finished, just that it's not emitting any further ones. + * + * To know when the final particle expires, listen for the COMPLETE event. + * + * Use this if you wish to launch an exact number of particles and then stop + * your emitter afterwards. + * + * The counter is reset each time the `ParticleEmitter.start` method is called. + * + * 0 means the emitter will not stop based on total emitted particles. + */ + stopAfter: number; - /** - * The x position of this Game Object. - */ - x: number; + /** + * The number of milliseconds this emitter will emit particles for when in flow mode, + * before it stops emission. A value of 0 (the default) means there is no duration. + * + * When the duration expires the `STOP` event is emitted. Note that entering a + * stopped state doesn't mean all the particles have finished, just that it's + * not emitting any further ones. + * + * To know when the final particle expires, listen for the COMPLETE event. + * + * The counter is reset each time the `ParticleEmitter.start` method is called. + * + * 0 means the emitter will not stop based on duration. + */ + duration: number; - /** - * The y position of this Game Object. - */ - y: number; + /** + * 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). + */ + frequency: number; - /** - * The z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#depth} instead. - */ - z: number; + /** + * 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}. + */ + emitting: boolean; - /** - * The w position of this Game Object. - */ - w: number; + /** + * 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. + * + * Also see the `sortOrder` property for more complex particle sorting. + */ + particleBringToTop: boolean; - /** - * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object - * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. - * - * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this - * isn't the case, use the `scaleX` or `scaleY` properties instead. - */ - scale: number; + /** + * The time rate applied to active particles, affecting lifespan, movement, and tweens. Values larger than 1 are faster than normal. + */ + timeScale: number; - /** - * The horizontal scale of this Game Object. - */ - scaleX: number; + /** + * An array containing Particle Emission Zones. These can be either EdgeZones or RandomZones. + * + * Particles are emitted from a randomly selected zone from this array. + * + * Prior to Phaser v3.60 an Emitter could only have one single Emission Zone. + * In 3.60 they can now have an array of Emission Zones. + */ + emitZones: Phaser.GameObjects.Particles.Zones.EdgeZone[] | Phaser.GameObjects.Particles.Zones.RandomZone[]; - /** - * The vertical scale of this Game Object. - */ - scaleY: number; + /** + * An array containing Particle Death Zone objects. A particle is immediately killed as soon as its x/y coordinates + * intersect with any of the configured Death Zones. + * + * Prior to Phaser v3.60 an Emitter could only have one single Death Zone. + * In 3.60 they can now have an array of Death Zones. + */ + deathZones: Phaser.GameObjects.Particles.Zones.DeathZone[]; - /** - * The angle of this Game Object as expressed in degrees. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left - * and -90 is up. - * - * If you prefer to work in radians, see the `rotation` property instead. - */ - angle: number; + /** + * An optional Rectangle object that is used during rendering to cull Particles from + * display. For example, if your particles are limited to only move within a 300x300 + * sized area from their origin, then you can set this Rectangle to those dimensions. + * + * The renderer will check to see if the `viewBounds` Rectangle intersects with the + * Camera bounds during the render step and if not it will skip rendering the Emitter + * entirely. + * + * This allows you to create many emitters in a Scene without the cost of + * rendering if the contents aren't visible. + * + * Note that the Emitter will not perform any checks to see if the Particles themselves + * are outside of these bounds, or not. It will simply check the bounds against the + * camera. Use the `getBounds` method with the `advance` parameter to help define + * the location and placement of the view bounds. + */ + viewBounds: Phaser.Geom.Rectangle | null; - /** - * The angle of this Game Object in radians. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left - * and -PI/2 is up. - * - * If you prefer to work in degrees, see the `angle` property instead. - */ - rotation: number; + /** + * A Game Object whose position is used as the particle origin. + */ + follow: Phaser.GameObjects.GameObject | null; - /** - * Sets the position of this Game Object. - * @param x The x position of this Game Object. Default 0. - * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. - * @param z The z position of this Game Object. Default 0. - * @param w The w position of this Game Object. Default 0. - */ - setPosition(x?: number, y?: number, z?: number, w?: number): this; + /** + * The offset of the particle origin from the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target. + */ + followOffset: Phaser.Math.Vector2; - /** - * Copies an object's coordinates to this Game Object's position. - * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. - */ - copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + /** + * Whether the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#visible} state will track + * the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target's visibility state. + */ + trackVisible: boolean; - /** - * Sets the position of this Game Object to be a random position within the confines of - * the given area. - * - * If no area is specified a random position between 0 x 0 and the game width x height is used instead. - * - * The position does not factor in the size of this Game Object, meaning that only the origin is - * guaranteed to be within the area. - * @param x The x position of the top-left of the random area. Default 0. - * @param y The y position of the top-left of the random area. Default 0. - * @param width The width of the random area. - * @param height The height of the random area. - */ - setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + /** + * The texture frames assigned to particles. + */ + frames: Phaser.Textures.Frame[]; - /** - * Sets the rotation of this Game Object. - * @param radians The rotation of this Game Object, in radians. Default 0. - */ - setRotation(radians?: number): this; + /** + * Whether texture {@link Phaser.GameObjects.Particles.ParticleEmitter#frames} are selected at random. + */ + randomFrame: boolean; - /** - * Sets the angle of this Game Object. - * @param degrees The rotation of this Game Object, in degrees. Default 0. - */ - setAngle(degrees?: number): this; + /** + * The number of consecutive particles that receive a single texture frame (per frame cycle). + */ + frameQuantity: number; - /** - * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. - * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. - */ - setScale(x: number, y?: number): this; + /** + * The animations assigned to particles. + */ + anims: string[]; - /** - * Sets the x position of this Game Object. - * @param value The x position of this Game Object. Default 0. - */ - setX(value?: number): this; + /** + * Whether animations {@link Phaser.GameObjects.Particles.ParticleEmitter#anims} are selected at random. + */ + randomAnim: boolean; - /** - * Sets the y position of this Game Object. - * @param value The y position of this Game Object. Default 0. - */ - setY(value?: number): this; + /** + * The number of consecutive particles that receive a single animation (per frame cycle). + */ + animQuantity: number; - /** - * Sets the z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. - * @param value The z position of this Game Object. Default 0. - */ - setZ(value?: number): this; + /** + * An internal property used to tell when the emitter is in fast-forwarc mode. + */ + skipping: boolean; - /** - * Sets the w position of this Game Object. - * @param value The w position of this Game Object. Default 0. - */ - setW(value?: number): this; + /** + * An internal Transform Matrix used to cache this emitters world matrix. + */ + worldMatrix: Phaser.GameObjects.Components.TransformMatrix; - /** - * Gets the local transform matrix for this Game Object. - * @param tempMatrix The matrix to populate with the values from this Game Object. - */ - getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + /** + * Optionally sort the particles before they render based on this + * property. The property must exist on the `Particle` class, such + * as `y`, `lifeT`, `scaleX`, etc. + * + * When set this overrides the `particleBringToTop` setting. + * + * To reset this and disable sorting, so this property to an empty string. + */ + sortProperty: string; - /** - * Gets the world transform matrix for this Game Object, factoring in any parent Containers. - * @param tempMatrix The matrix to populate with the values from this Game Object. - * @param parentMatrix A temporary matrix to hold parent values during the calculations. - */ - getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + /** + * When `sortProperty` is defined this controls the sorting order, + * either ascending or descending. Toggle to control the visual effect. + */ + sortOrderAsc: boolean; - /** - * Takes the given `x` and `y` coordinates and converts them into local space for this - * Game Object, taking into account parent and local transforms, and the Display Origin. - * - * The returned Vector2 contains the translated point in its properties. - * - * A Camera needs to be provided in order to handle modified scroll factors. If no - * camera is specified, it will use the `main` camera from the Scene to which this - * Game Object belongs. - * @param x The x position to translate. - * @param y The y position to translate. - * @param point A Vector2, or point-like object, to store the results in. - * @param camera The Camera which is being tested against. If not given will use the Scene default camera. - */ - getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + /** + * The callback used to sort the particles. Only used if `sortProperty` + * has been set. Set this via the `setSortCallback` method. + */ + sortCallback: Phaser.Types.GameObjects.Particles.ParticleSortCallback | null; - /** - * Gets the sum total rotation of all of this Game Objects parent Containers. - * - * The returned value is in radians and will be zero if this Game Object has no parent container. - */ - getParentRotation(): number; + /** + * A list of Particle Processors being managed by this Emitter. + */ + processors: Phaser.Structs.List; - /** - * The visible state of the Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - */ - visible: boolean; + /** + * The tint fill mode used by the Particles in this Emitter. + * + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + */ + tintFill: boolean; - /** - * Sets the visibility of this Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. - */ - setVisible(value: boolean): this; + /** + * Takes an Emitter Configuration file and resets this Emitter, using any + * properties defined in the config to then set it up again. + * @param config Settings for this emitter. + */ + setConfig(config: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig): this; - /** - * The horizontal scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - */ - scrollFactorX: number; + /** + * Creates a description of this emitter suitable for JSON serialization. + */ + toJSON(): Phaser.Types.GameObjects.JSONGameObject; - /** - * The vertical scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - */ - scrollFactorY: number; + /** + * Resets the internal counter trackers. + * + * You shouldn't ever need to call this directly. + * @param frequency The frequency counter. + * @param on Set the complete flag. + */ + resetCounters(frequency: number, on: boolean): void; - /** - * Sets the scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * @param x The horizontal scroll factor of this Game Object. - * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. - */ - setScrollFactor(x: number, y?: number): this; + /** + * Continuously moves the particle origin to follow a Game Object's position. + * @param target The Game Object to follow. + * @param offsetX Horizontal offset of the particle origin from the Game Object. Default 0. + * @param offsetY Vertical offset of the particle origin from the Game Object. Default 0. + * @param trackVisible Whether the emitter's visible state will track the target's visible state. Default false. + */ + startFollow(target: Phaser.GameObjects.GameObject, offsetX?: number, offsetY?: number, trackVisible?: boolean): this; - } + /** + * Stops following a Game Object. + */ + stopFollow(): this; + + /** + * Chooses a texture frame from {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. + */ + getFrame(): Phaser.Textures.Frame; - namespace Particles { - /** - * A Particle Emitter property. - * - * Facilitates changing Particle properties as they are emitted and throughout their lifetime. - */ - class EmitterOp { /** + * Sets a pattern for assigning texture frames to emitted particles. The `frames` configuration can be any of: * - * @param config Settings for the Particle Emitter that owns this property. - * @param key The name of the property. - * @param defaultValue The default value of the property. - * @param emitOnly Whether the property can only be modified when a Particle is emitted. Default false. + * 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] } + * @param frames One or more texture frames, or a configuration object. + * @param pickRandom Whether frames should be assigned at random from `frames`. Default true. + * @param quantity The number of consecutive particles that will receive each frame. Default 1. */ - constructor(config: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig, key: string, defaultValue: number, emitOnly?: boolean); + setEmitterFrame(frames: any[] | string | number | Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig, pickRandom?: boolean, quantity?: number): this; /** - * The name of this property. + * Chooses an animation from {@link Phaser.GameObjects.Particles.ParticleEmitter#anims}, if populated. */ - propertyKey: string; + getAnim(): string; /** - * The value of this property. + * Sets a pattern for assigning animations to emitted particles. The `anims` configuration can be any of: + * + * anim: 'red' + * anim: [ 'red', 'green', 'blue', 'pink', 'white' ] + * anim: { anims: [ 'red', 'green', 'blue', 'pink', 'white' ], [cycle: bool], [quantity: int] } + * @param anims One or more animations, or a configuration object. + * @param pickRandom Whether animations should be assigned at random from `anims`. Default true. + * @param quantity The number of consecutive particles that will receive each animation. Default 1. */ - propertyValue: number; + setAnim(anims: any[] | string | Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig, pickRandom?: boolean, quantity?: number): this; /** - * The default value of this property. + * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle movement on or off. + * @param value Radial mode (true) or point mode (true). Default true. */ - defaultValue: number; + setRadial(value?: boolean): this; /** - * The number of steps for stepped easing between {@link Phaser.GameObjects.Particles.EmitterOp#start} and - * {@link Phaser.GameObjects.Particles.EmitterOp#end} values, per emit. + * Creates a Particle Bounds processor and adds it to this Emitter. + * + * This processor will check to see if any of the active Particles hit + * the defined boundary, as specified by a Rectangle shape in world-space. + * + * If so, they are 'rebounded' back again by having their velocity adjusted. + * + * The strength of the rebound is controlled by the `Particle.bounce` + * property. + * + * You should be careful to ensure that you emit particles within a bounds, + * if set, otherwise it will lead to unpredictable visual results as the + * particles are hastily repositioned. + * + * The Particle Bounds processor is returned from this method. If you wish + * to modify the area you can directly change its `bounds` property, along + * with the `collideLeft` etc values. + * + * To disable the bounds you can either set its `active` property to `false`, + * or if you no longer require it, call `ParticleEmitter.removeParticleProcessor`. + * @param x The x-coordinate of the left edge of the boundary, or an object representing a rectangle. + * @param y The y-coordinate of the top edge of the boundary. + * @param width The width of the boundary. + * @param height The height of the boundary. + * @param collideLeft Whether particles interact with the left edge of the bounds. Default true. + * @param collideRight Whether particles interact with the right edge of the bounds. Default true. + * @param collideTop Whether particles interact with the top edge of the bounds. Default true. + * @param collideBottom Whether particles interact with the bottom edge of the bounds. Default true. */ - steps: number; + addParticleBounds(x: number | Phaser.Types.GameObjects.Particles.ParticleEmitterBounds | Phaser.Types.GameObjects.Particles.ParticleEmitterBoundsAlt, y?: number, width?: number, height?: number, collideLeft?: boolean, collideRight?: boolean, collideTop?: boolean, collideBottom?: boolean): Phaser.GameObjects.Particles.ParticleBounds; /** - * The step counter for stepped easing, per emit. + * Sets the initial radial speed of emitted particles. + * + * Changes the emitter to radial mode. + * @param x The horizontal speed of the emitted Particles. + * @param y The vertical speed of emitted Particles. If not set it will use the `x` value. Default x. */ - counter: number; + setParticleSpeed(x: number, y?: number): this; /** - * The start value for this property to ease between. + * Sets the vertical and horizontal scale of the emitted particles. + * + * You can also set the scale of the entire emitter via `setScale`. + * @param x The horizontal scale of the emitted Particles. Default 1. + * @param y The vertical scale of emitted Particles. If not set it will use the `x` value. Default x. */ - start: number; + setParticleScale(x?: number, y?: number): this; /** - * The end value for this property to ease between. + * Sets the gravity applied to emitted particles. + * @param x Horizontal acceleration due to gravity, in pixels per second squared. Set to zero for no gravity. + * @param y Vertical acceleration due to gravity, in pixels per second squared. Set to zero for no gravity. */ - end: number; + setParticleGravity(x: number, y: number): this; /** - * The easing function to use for updating this property. + * Sets the opacity (alpha) of emitted particles. + * + * You can also set the alpha of the entire emitter via `setAlpha`. + * @param value A value between 0 (transparent) and 1 (opaque). */ - ease: Function; + setParticleAlpha(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType): this; /** - * Whether this property can only be modified when a Particle is emitted. + * Sets the color tint of emitted particles. * - * Set to `true` to allow only {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} callbacks to be set and - * affect this property. + * This is a WebGL only feature. + * @param value A value between 0 and 0xffffff. + */ + setParticleTint(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType): this; + + /** + * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. * - * 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. + * The value is given in degrees using Phaser's right-handed coordinate system. + * @param value The angle of the initial velocity of emitted particles, in degrees. */ - emitOnly: boolean; + setEmitterAngle(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; /** - * The callback to run for Particles when they are emitted from the Particle Emitter. + * Sets the lifespan of newly emitted particles in milliseconds. + * @param value The lifespan of a particle, in ms. */ - onEmit: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitCallback; + setParticleLifespan(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; /** - * The callback to run for Particles when they are updated. + * Sets the number of particles released at each flow cycle or explosion. + * @param quantity The number of particles to release at each flow cycle or explosion. */ - onUpdate: Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback; + setQuantity(quantity: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; /** - * Load the property from a Particle Emitter configuration object. + * Sets the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#frequency} + * and {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. + * @param frequency The time interval (>= 0) of each flow cycle, in ms; or -1 to put the emitter in explosion mode. + * @param quantity The number of particles to release at each flow cycle or explosion. + */ + setFrequency(frequency: number, quantity?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + + /** + * Adds a new Particle Death Zone to this Emitter. * - * Optionally accepts a new property key to use, replacing the current one. - * @param config Settings for the Particle Emitter that owns this property. - * @param newKey The new key to use for this property, if any. + * A particle is immediately killed as soon as its x/y coordinates intersect + * with any of the configured Death Zones. + * + * The `source` can be a Geometry Shape, such as a Circle, Rectangle or Triangle. + * Any valid object from the `Phaser.Geometry` namespace is allowed, as long as + * it supports a `contains` function. You can set the `type` to be either `onEnter` + * or `onLeave`. + * + * A single Death Zone instance can only exist once within this Emitter, but can belong + * to multiple Emitters. + * @param config A Death Zone configuration object, a Death Zone instance, a valid Geometry object or an array of them. */ - loadConfig(config?: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig, newKey?: string): void; + addDeathZone(config: Phaser.Types.GameObjects.Particles.DeathZoneObject | Phaser.Types.GameObjects.Particles.DeathZoneObject[]): Phaser.GameObjects.Particles.Zones.DeathZone; /** - * Build a JSON representation of this Particle Emitter property. + * Removes the given Particle Death Zone from this Emitter. + * @param zone The Death Zone that should be removed from this Emitter. */ - toJSON(): object; + removeDeathZone(zone: Phaser.GameObjects.Particles.Zones.DeathZone): this; /** - * Change the current value of the property and update its callback methods. - * @param value The value of the property. + * Adds a new Particle Emission Zone to this Emitter. + * + * 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 the particles 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. + * + * An Emission Zone can only exist once within this Emitter. + * @param zone An Emission Zone configuration object, a RandomZone or EdgeZone instance, or an array of them. */ - onChange(value: number): this; + addEmitZone(zone: Phaser.Types.GameObjects.Particles.EmitZoneObject | Phaser.Types.GameObjects.Particles.EmitZoneObject[]): Phaser.GameObjects.Particles.Zones.EdgeZone[] | Phaser.GameObjects.Particles.Zones.RandomZone[]; /** - * 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}. + * Removes the given Particle Emission Zone from this Emitter. + * @param zone The Emission Zone that should be removed from this Emitter. */ - setMethods(): this; + removeEmitZone(zone: Phaser.GameObjects.Particles.Zones.EdgeZone | Phaser.GameObjects.Particles.Zones.RandomZone): this; /** - * Check whether an object has the given property. - * @param object The object to check. - * @param key The key of the property to look for in the object. + * Takes the given particle and sets its x/y coordinates to match the next available + * emission zone, if any have been configured. This method is called automatically + * as part of the `Particle.fire` process. + * + * The Emit Zones are iterated in sequence. Once a zone has had a particle emitted + * from it, then the next zone is used and so on, in a loop. + * @param particle The particle to set the emission zone for. */ - has(object: object, key: string): boolean; + getEmitZone(particle: Phaser.GameObjects.Particles.Particle): void; /** - * Check whether an object has both of the given properties. - * @param object The object to check. - * @param key1 The key of the first property to check the object for. - * @param key2 The key of the second property to check the object for. + * Takes the given particle and checks to see if any of the configured Death Zones + * will kill it and returns the result. This method is called automatically as part + * of the `Particle.update` process. + * @param particle The particle to test against the Death Zones. */ - hasBoth(object: object, key1: string, key2: string): boolean; + getDeathZone(particle: Phaser.GameObjects.Particles.Particle): boolean; /** - * Check whether an object has at least one of the given properties. - * @param object The object to check. - * @param key1 The key of the first property to check the object for. - * @param key2 The key of the second property to check the object for. + * Changes the currently active Emission Zone. The zones should have already + * been added to this Emitter either via the emitter config, or the + * `addEmitZone` method. + * + * Call this method by passing either a numeric zone index value, or + * the zone instance itself. + * + * Prior to v3.60 an Emitter could only have a single Emit Zone and this + * method was how you set it. From 3.60 and up it now performs a different + * function and swaps between all available active zones. + * @param zone The Emit Zone to set as the active zone. */ - hasEither(object: object, key1: string, key2: string): boolean; + setEmitZone(zone: number | Phaser.GameObjects.Particles.Zones.EdgeZone | Phaser.GameObjects.Particles.Zones.RandomZone): this; /** - * The returned value sets what the property will be at the START of the particles life, on emit. - * @param particle The particle. - * @param key The name of the property. - * @param value The current value of the property. + * Adds a Particle Processor, such as a Gravity Well, to this Emitter. + * + * It will start processing particles from the next update as long as its `active` + * property is set. + * @param processor The Particle Processor to add to this Emitter Manager. */ - defaultEmit(particle: Phaser.GameObjects.Particles.Particle, key: string, value?: number): number; + addParticleProcessor(processor: T): T; /** - * The returned value updates the property for the duration of the particles life. - * @param particle The particle. - * @param key The name of the property. - * @param t The T value (between 0 and 1) - * @param value The current value of the property. + * Removes a Particle Processor from this Emitter. + * + * The Processor must belong to this Emitter to be removed. + * + * It is not destroyed when removed, allowing you to move it to another Emitter Manager, + * so if you no longer require it you should call its `destroy` method directly. + * @param processor The Particle Processor to remove from this Emitter Manager. */ - defaultUpdate(particle: Phaser.GameObjects.Particles.Particle, key: string, t: number, value: number): number; + removeParticleProcessor(processor: T): T | null; /** - * An `onEmit` callback that returns the current value of the property. + * Gets all active Particle Processors. */ - staticValueEmit(): number; + getProcessors(): Phaser.GameObjects.Particles.ParticleProcessor[]; /** - * An `onUpdate` callback that returns the current value of the property. + * Creates a new Gravity Well, adds it to this Emitter and returns a reference to it. + * @param config Configuration settings for the Gravity Well to create. */ - staticValueUpdate(): number; + createGravityWell(config: Phaser.Types.GameObjects.Particles.GravityWellConfig): Phaser.GameObjects.Particles.GravityWell; /** - * An `onEmit` callback that returns a random value from the current value array. + * Creates inactive particles and adds them to this emitter's pool. + * + * If `ParticleEmitter.maxParticles` is set it will limit the + * value passed to this method to make sure it's not exceeded. + * @param count The number of particles to create. */ - randomStaticValueEmit(): number; + reserve(count: number): this; /** - * An `onEmit` callback that returns a value between the {@link Phaser.GameObjects.Particles.EmitterOp#start} and - * {@link Phaser.GameObjects.Particles.EmitterOp#end} range. - * @param particle The particle. - * @param key The key of the property. + * Gets the number of active (in-use) particles in this emitter. */ - randomRangedValueEmit(particle: Phaser.GameObjects.Particles.Particle, key: string): number; + getAliveParticleCount(): number; /** - * An `onEmit` callback that returns a stepped value between the - * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} - * range. + * Gets the number of inactive (available) particles in this emitter. */ - steppedEmit(): number; + getDeadParticleCount(): number; /** - * An `onEmit` callback for an eased property. - * - * It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate}. - * @param particle The particle. - * @param key The name of the property. + * Gets the total number of particles in this emitter. */ - easedValueEmit(particle: Phaser.GameObjects.Particles.Particle, key: string): number; + getParticleCount(): number; /** - * An `onUpdate` callback that returns an eased value between the - * {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end} - * range. - * @param particle The particle. - * @param key The name of the property. - * @param t The T value (between 0 and 1) + * Whether this emitter is at either its hard-cap limit (maxParticles), if set, or + * the max allowed number of 'alive' particles (maxAliveParticles). */ - easeValueUpdate(particle: Phaser.GameObjects.Particles.Particle, key: string, t: number): number; + atLimit(): boolean; - } + /** + * Sets a function to call for each newly emitted particle. + * @param callback The function. + * @param context The calling context. + */ + onParticleEmit(callback: Phaser.Types.GameObjects.Particles.ParticleEmitterCallback, context?: any): this; - /** - * 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 { /** - * - * @param x The x coordinate of the Gravity Well, in world space. Default 0. - * @param y The y coordinate of the Gravity Well, in world space. Default 0. - * @param power The strength of the gravity force - larger numbers produce a stronger force. Default 0. - * @param epsilon The minimum distance for which the gravity force is calculated. Default 100. - * @param gravity The gravitational force of this Gravity Well. Default 50. + * Sets a function to call for each particle death. + * @param callback The function. + * @param context The function's calling context. */ - constructor(x?: number | Phaser.Types.GameObjects.Particles.GravityWellConfig, y?: number, power?: number, epsilon?: number, gravity?: number); + onParticleDeath(callback: Phaser.Types.GameObjects.Particles.ParticleDeathCallback, context?: any): this; /** - * The x coordinate of the Gravity Well, in world space. + * Deactivates every particle in this emitter immediately. + * + * This particles are killed but do not emit an event or callback. */ - x: number; + killAll(): this; /** - * The y coordinate of the Gravity Well, in world space. + * Calls a function for each active particle in this emitter. The function is + * sent two parameters: a reference to the Particle instance and to this Emitter. + * @param callback The function. + * @param context The functions calling context. */ - y: number; + forEachAlive(callback: Phaser.Types.GameObjects.Particles.ParticleEmitterCallback, context: any): this; /** - * The active state of the Gravity Well. An inactive Gravity Well will not influence any particles. + * Calls a function for each inactive particle in this emitter. + * @param callback The function. + * @param context The functions calling context. */ - active: boolean; + forEachDead(callback: Phaser.Types.GameObjects.Particles.ParticleEmitterCallback, context: any): this; /** - * The strength of the gravity force - larger numbers produce a stronger force. + * 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. + * + * Calling this method will emit the `START` event. + * @param advance Advance this number of ms in time through the emitter. Default 0. + * @param duration Limit this emitter to only emit particles for the given number of ms. Setting this parameter will override any duration already set in the Emitter configuration object. Default 0. */ - power: number; + start(advance?: number, duration?: number): this; /** - * The minimum distance for which the gravity force is calculated. + * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#emitting off} the emitter and + * stops it from emitting further particles. Currently alive particles will remain + * active until they naturally expire unless you set the `kill` parameter to `true`. + * + * Calling this method will emit the `STOP` event. When the final particle has + * expired the `COMPLETE` event will be emitted. + * @param kill Kill all particles immediately (true), or leave them to die after their lifespan expires? (false, the default) Default false. */ - epsilon: number; + stop(kill?: boolean): this; /** - * Takes a Particle and updates it based on the properties of this Gravity Well. - * @param particle The Particle to update. - * @param delta The delta time in ms. - * @param step The delta value divided by 1000. + * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Deactivates} the emitter. */ - update(particle: Phaser.GameObjects.Particles.Particle, delta: number, step: number): void; + pause(): this; - } + /** + * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Activates} the emitter. + */ + resume(): this; - /** - * 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 { /** + * Set the property by which active particles are sorted prior to be rendered. * - * @param emitter The Emitter to which this Particle belongs. + * It allows you to control the rendering order of the particles. + * + * This can be any valid property of the `Particle` class, such as `y`, `alpha` + * or `lifeT`. + * + * The 'alive' particles array is sorted in place each game frame. Setting a + * sort property will override the `particleBringToTop` setting. + * + * If you wish to use your own sorting function, see `setSortCallback` instead. + * @param property The property on the `Particle` class to sort by. + * @param ascending Should the particles be sorted in ascending or descending order? Default true. */ - constructor(emitter: Phaser.GameObjects.Particles.ParticleEmitter); + setSortProperty(property?: string, ascending?: boolean): this; /** - * The Emitter to which this Particle belongs. + * Sets a callback to be used to sort the particles before rendering each frame. + * + * This allows you to define your own logic and behavior in the callback. * - * A Particle can only belong to a single Emitter and is created, updated and destroyed via it. + * The callback will be sent two parameters: the two Particles being compared, + * and must adhere to the criteria of the `compareFn` in `Array.sort`: + * + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description + * + * Call this method with no parameters to reset the sort callback. + * + * Setting your own callback will override both the `particleBringToTop` and + * `sortProperty` settings of this Emitter. + * @param callback The callback to invoke when the particles are sorted. Leave undefined to reset to the default. */ - emitter: Phaser.GameObjects.Particles.ParticleEmitter; + setSortCallback(callback?: Phaser.Types.GameObjects.Particles.ParticleSortCallback): this; /** - * The texture frame used to render this Particle. + * Sorts active particles with {@link Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback}. */ - frame: Phaser.Textures.Frame; + depthSort(): this; /** - * The x coordinate of this Particle. + * Calculates the difference of two particles, for sorting them by depth. + * @param a The first particle. + * @param b The second particle. */ - x: number; + depthSortCallback(a: object, b: object): number; /** - * The y coordinate of this Particle. + * 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. + * @param frequency The time interval (>= 0) of each flow cycle, in ms. + * @param count The number of particles to emit at each flow cycle. Default 1. + * @param stopAfter Stop this emitter from firing any more particles once this value is reached. Set to zero for unlimited. Setting this parameter will override any `stopAfter` value already set in the Emitter configuration object. */ - y: number; + flow(frequency: number, count?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType, stopAfter?: number): this; /** - * The x velocity of this Particle. + * Puts the emitter in explode mode (frequency = -1), stopping any current particle flow, and emits several particles all at once. + * @param count The number of Particles to emit. Default this.quantity. + * @param x The x coordinate to emit the Particles from. Default this.x. + * @param y The y coordinate to emit the Particles from. Default this.x. */ - velocityX: number; + explode(count?: number, x?: number, y?: number): Phaser.GameObjects.Particles.Particle; /** - * The y velocity of this Particle. + * Emits particles at the given position. If no position is given, it will + * emit from this Emitters current location. + * @param x The x coordinate to emit the Particles from. Default this.x. + * @param y The y coordinate to emit the Particles from. Default this.x. + * @param count The number of Particles to emit. Default this.quantity. */ - velocityY: number; + emitParticleAt(x?: number, y?: number, count?: number): Phaser.GameObjects.Particles.Particle; /** - * The x acceleration of this Particle. + * Emits particles at a given position (or the emitters current position). + * @param count The number of Particles to emit. Default this.quantity. + * @param x The x coordinate to emit the Particles from. Default this.x. + * @param y The y coordinate to emit the Particles from. Default this.x. */ - accelerationX: number; + emitParticle(count?: number, x?: number, y?: number): Phaser.GameObjects.Particles.Particle; /** - * The y acceleration of this Particle. + * Fast forwards this Particle Emitter and all of its particles. + * + * Works by running the Emitter `preUpdate` handler in a loop until the `time` + * has been reached at `delta` steps per loop. + * + * All callbacks and emitter related events that would normally be fired + * will still be invoked. + * + * You can make an emitter 'fast forward' via the emitter config using the + * `advance` property. Set this value to the number of ms you wish the + * emitter to be fast-forwarded by. Or, call this method post-creation. + * @param time The number of ms to advance the Particle Emitter by. + * @param delta The amount of delta to use for each step. Defaults to 1000 / 60. */ - accelerationY: number; + fastForward(time: number, delta?: number): this; /** - * The maximum horizontal velocity this Particle can travel at. + * Updates this emitter and its particles. + * @param time The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @param delta The delta time, in ms, elapsed since the last frame. */ - maxVelocityX: number; + preUpdate(time: number, delta: number): void; /** - * The maximum vertical velocity this Particle can travel at. + * Takes either a Rectangle Geometry object or an Arcade Physics Body and tests + * to see if it intersects with any currently alive Particle in this Emitter. + * + * Overlapping particles are returned in an array, where you can perform further + * processing on them. If nothing overlaps then the array will be empty. + * @param target A Rectangle or Arcade Physics Body to check for intersection against all alive particles. */ - maxVelocityY: number; + overlap(target: Phaser.Geom.Rectangle | Phaser.Physics.Arcade.Body): Phaser.GameObjects.Particles.Particle[]; /** - * The bounciness, or restitution, of this Particle. + * Returns a bounds Rectangle calculated from the bounds of all currently + * _active_ Particles in this Emitter. If this Emitter has only just been + * created and not yet rendered, then calling this method will return a Rectangle + * with a max safe integer for dimensions. Use the `advance` parameter to + * avoid this. + * + * Typically it takes a few seconds for a flow Emitter to 'warm up'. You can + * use the `advance` and `delta` parameters to force the Emitter to + * 'fast forward' in time to try and allow the bounds to be more accurate, + * as it will calculate the bounds based on the particle bounds across all + * timesteps, giving a better result. + * + * You can also use the `padding` parameter to increase the size of the + * bounds. Emitters with a lot of randomness in terms of direction or lifespan + * can often return a bounds smaller than their possible maximum. By using + * the `padding` (and `advance` if needed) you can help limit this. + * @param padding The amount of padding, in pixels, to add to the bounds Rectangle. + * @param advance The number of ms to advance the Particle Emitter by. Defaults to 0, i.e. not used. + * @param delta The amount of delta to use for each step. Defaults to 1000 / 60. + * @param output The Rectangle to store the results in. If not given a new one will be created. */ - bounce: number; + getBounds(padding?: number, advance?: number, delta?: number, output?: Phaser.Geom.Rectangle): Phaser.Geom.Rectangle; /** - * The horizontal scale of this Particle. + * Prints a warning to the console if you mistakenly call this function + * thinking it works the same way as Phaser v3.55. */ - scaleX: number; + createEmitter(): void; /** - * The vertical scale of this Particle. + * The x coordinate the particles are emitted from. + * + * This is relative to the Emitters x coordinate and that of any parent. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - scaleY: number; + particleX: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The alpha value of this Particle. + * The y coordinate the particles are emitted from. + * + * This is relative to the Emitters x coordinate and that of any parent. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - alpha: number; + particleY: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The angle of this Particle in degrees. + * The horizontal acceleration applied to emitted particles, in pixels per second squared. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - angle: number; + accelerationX: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The angle of this Particle in radians. + * The vertical acceleration applied to emitted particles, in pixels per second squared. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - rotation: number; + accelerationY: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The tint applied to this Particle. + * The maximum horizontal velocity emitted particles can reach, in pixels per second squared. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - tint: number; + maxVelocityX: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The lifespan of this Particle in ms. + * The maximum vertical velocity emitted particles can reach, in pixels per second squared. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - life: number; + maxVelocityY: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The current life of this Particle in ms. + * The initial speed of emitted particles, in pixels per second. + * + * If using this as a getter it will return the `speedX` value. + * + * If using it as a setter it will update both `speedX` and `speedY` to the + * given value. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - lifeCurrent: number; + speed: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The delay applied to this Particle upon emission, in ms. + * The initial horizontal speed of emitted particles, in pixels per second. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - delayCurrent: number; + speedX: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The normalized lifespan T value, where 0 is the start and 1 is the end. + * The initial vertical speed of emitted particles, in pixels per second. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - lifeT: number; + speedY: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The data used by the ease equation. + * The x coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - data: object; + moveToX: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Checks to see if this Particle is alive and updating. + * The y coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - isAlive(): boolean; + moveToY: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Resets the position of this particle back to zero. + * The amount of velocity particles will use when rebounding off the + * emitter bounds, if set. A value of 0 means no bounce. A value of 1 + * means a full rebound. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - resetPosition(): void; + bounce: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Starts this Particle from the given coordinates. - * @param x The x coordinate to launch this Particle from. - * @param y The y coordinate to launch this Particle from. + * The horizontal scale of emitted particles. + * + * This is relative to the Emitters scale and that of any parent. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - fire(x: number, y: number): void; + particleScaleX: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * An internal method that calculates the velocity of the Particle. - * @param emitter The Emitter that is updating this Particle. - * @param delta The delta time in ms. - * @param step The delta value divided by 1000. - * @param processors Particle processors (gravity wells). + * The vertical scale of emitted particles. + * + * This is relative to the Emitters scale and that of any parent. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - computeVelocity(emitter: Phaser.GameObjects.Particles.ParticleEmitter, delta: number, step: number, processors: any[]): void; + particleScaleY: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Checks if this Particle is still within the bounds defined by the given Emitter. + * A color tint value that is applied to the texture of the emitted + * particle. The value should be given in hex format, i.e. 0xff0000 + * for a red tint, and should not include the alpha channel. + * + * Tints are additive, meaning a tint value of white (0xffffff) will + * effectively reset the tint to nothing. + * + * Modify the `ParticleEmitter.tintFill` property to change between + * an additive and replacement tint mode. * - * If not, and depending on the Emitter collision flags, the Particle may either stop or rebound. - * @param emitter The Emitter to check the bounds against. + * When you define the color via the Emitter config you should give + * it as an array of color values. The Particle will then interpolate + * through these colors over the course of its lifespan. Setting this + * will override any `tint` value that may also be given. + * + * This is a WebGL only feature. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - checkBounds(emitter: Phaser.GameObjects.Particles.ParticleEmitter): void; + particleColor: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The main update method for this Particle. + * Controls the easing function used when you have created an + * Emitter that uses the `color` property to interpolate the + * tint of Particles over their lifetime. * - * Updates its life values, computes the velocity and repositions the Particle. - * @param delta The delta time in ms. - * @param step The delta value divided by 1000. - * @param processors An optional array of update processors. + * Setting this has no effect if you haven't also applied a + * `particleColor` to this Emitter. */ - update(delta: number, step: number, processors: any[]): boolean; - - } + colorEase: string; - /** - * 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 implements Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Visible { /** + * A color tint value that is applied to the texture of the emitted + * particle. The value should be given in hex format, i.e. 0xff0000 + * for a red tint, and should not include the alpha channel. * - * @param manager The Emitter Manager this Emitter belongs to. - * @param config Settings for this emitter. + * Tints are additive, meaning a tint value of white (0xffffff) will + * effectively reset the tint to nothing. + * + * Modify the `ParticleEmitter.tintFill` property to change between + * an additive and replacement tint mode. + * + * The `tint` value will be overriden if a `color` array is provided. + * + * This is a WebGL only feature. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - constructor(manager: Phaser.GameObjects.Particles.ParticleEmitterManager, config: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig); + particleTint: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The Emitter Manager this Emitter belongs to. + * The alpha value of the emitted particles. This is a value + * between 0 and 1. Particles with alpha zero are invisible + * and are therefore not rendered, but are still processed + * by the Emitter. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - manager: Phaser.GameObjects.Particles.ParticleEmitterManager; + particleAlpha: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The texture assigned to particles. + * The lifespan of the emitted particles. This value is given + * in milliseconds and defaults to 1000ms (1 second). When a + * particle reaches this amount it is killed. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - texture: Phaser.Textures.Texture; + lifespan: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The texture frames assigned to particles. + * The angle at which the particles are emitted. The values are + * given in degrees. This allows you to control the direction + * of the emitter. If you wish instead to change the rotation + * of the particles themselves, see the `particleRotate` property. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - frames: Phaser.Textures.Frame[]; + particleAngle: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The default texture frame assigned to particles. + * The rotation (or angle) of each particle when it is emitted. + * The value is given in degrees and uses a right-handed + * coordinate system, where 0 degrees points to the right, 90 degrees + * points down and -90 degrees points up. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - defaultFrame: Phaser.Textures.Frame; + particleRotate: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Names of simple configuration properties. + * The number of particles that are emitted each time an emission + * occurs, i.e. from one 'explosion' or each frame in a 'flow' cycle. + * + * The default is 1. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - configFastMap: object; + quantity: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Names of complex configuration properties. + * The number of milliseconds to wait after emission before + * the particles start updating. This allows you to emit particles + * that appear 'static' or still on-screen and then, after this value, + * begin to move. + * + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - configOpMap: object; + delay: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The name of this Particle Emitter. + * The number of milliseconds to wait after a particle has finished + * its life before it will be removed. This allows you to 'hold' a + * particle on the screen once it has reached its final state + * before it then vanishes. + * + * Note that all particle updates will cease, including changing + * alpha, scale, movement or animation. * - * Empty by default and never populated by Phaser, this is left for developers to use. + * Accessing this property should typically return a number. + * However, it can be set to any valid EmitterOp onEmit type. */ - name: string; + hold: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * The Particle Class which will be emitted by this Emitter. + * The internal flow counter. + * + * Treat this property as read-only. */ - particleClass: Phaser.GameObjects.Particles.Particle; + flowCounter: number; /** - * The x-coordinate of the particle origin (where particles will be emitted). + * The internal frame counter. + * + * Treat this property as read-only. */ - x: Phaser.GameObjects.Particles.EmitterOp; + frameCounter: number; /** - * The y-coordinate of the particle origin (where particles will be emitted). + * The internal animation counter. + * + * Treat this property as read-only. */ - y: Phaser.GameObjects.Particles.EmitterOp; + animCounter: number; /** - * 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. + * The internal elasped counter. + * + * Treat this property as read-only. */ - radial: boolean; + elapsed: number; /** - * Horizontal acceleration applied to emitted particles, in pixels per second squared. + * The internal stop counter. + * + * Treat this property as read-only. */ - gravityX: number; + stopCounter: number; /** - * Vertical acceleration applied to emitted particles, in pixels per second squared. + * The internal complete flag. + * + * Treat this property as read-only. */ - gravityY: number; + completeFlag: boolean; /** - * Whether accelerationX and accelerationY are non-zero. Set automatically during configuration. + * The internal zone index. + * + * Treat this property as read-only. */ - acceleration: boolean; + zoneIndex: number; /** - * Horizontal acceleration applied to emitted particles, in pixels per second squared. + * The internal zone total. + * + * Treat this property as read-only. */ - accelerationX: Phaser.GameObjects.Particles.EmitterOp; + zoneTotal: number; /** - * Vertical acceleration applied to emitted particles, in pixels per second squared. + * The current frame index. + * + * Treat this property as read-only. */ - accelerationY: Phaser.GameObjects.Particles.EmitterOp; + currentFrame: number; /** - * The maximum horizontal velocity of emitted particles, in pixels per second squared. + * The current animation index. + * + * Treat this property as read-only. */ - maxVelocityX: Phaser.GameObjects.Particles.EmitterOp; + currentAnim: number; /** - * The maximum vertical velocity of emitted particles, in pixels per second squared. + * Destroys this Particle Emitter and all Particles it owns. */ - maxVelocityY: Phaser.GameObjects.Particles.EmitterOp; + preDestroy(): void; /** - * The initial horizontal speed of emitted particles, in pixels per second. + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). */ - speedX: Phaser.GameObjects.Particles.EmitterOp; + clearAlpha(): this; /** - * The initial vertical speed of emitted particles, in pixels per second. + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * @param value The alpha value applied across the whole Game Object. Default 1. */ - speedY: Phaser.GameObjects.Particles.EmitterOp; + setAlpha(value?: number): this; /** - * Whether moveToX and moveToY are nonzero. Set automatically during configuration. + * The alpha value of the Game Object. + * + * This is a global value, impacting the entire Game Object, not just a region of it. */ - moveTo: boolean; + alpha: number; /** - * The x-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. */ - moveToX: Phaser.GameObjects.Particles.EmitterOp; + blendMode: Phaser.BlendModes | string | number; /** - * The y-coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true. + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - moveToY: Phaser.GameObjects.Particles.EmitterOp; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * Whether particles will rebound when they meet the emitter bounds. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. */ - bounce: Phaser.GameObjects.Particles.EmitterOp; + depth: number; /** - * The horizontal scale of emitted particles. + * The depth of this Game Object within the Scene. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ - scaleX: Phaser.GameObjects.Particles.EmitterOp; + setDepth(value: number): this; /** - * The vertical scale of emitted particles. + * The Mask this Game Object is using during render. */ - scaleY: Phaser.GameObjects.Particles.EmitterOp; + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; /** - * Color tint applied to emitted particles. Value must not include the alpha channel. + * Sets the mask that this Game Object will use to render with. + * + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * If a mask is already set on this Game Object it will be immediately replaced. + * + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * @param mask The mask this Game Object will use when rendering. */ - tint: Phaser.GameObjects.Particles.EmitterOp; + setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; /** - * The alpha (transparency) of emitted particles. + * Clears the mask that this Game Object was using. + * @param destroyMask Destroy the mask before clearing it? Default false. */ - alpha: Phaser.GameObjects.Particles.EmitterOp; + clearMask(destroyMask?: boolean): this; /** - * The lifespan of emitted particles, in ms. + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. + * + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. + * + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - lifespan: Phaser.GameObjects.Particles.EmitterOp; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** - * The angle of the initial velocity of emitted particles, in degrees. + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. + * + * To create the mask you need to pass in a reference to a Graphics Game Object. + * + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. + * + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - angle: Phaser.GameObjects.Particles.EmitterOp; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** - * The rotation of emitted particles, in degrees. + * The initial WebGL pipeline of this Game Object. + * + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. */ - rotate: Phaser.GameObjects.Particles.EmitterOp; + defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * A function to call when a particle is emitted. + * The current WebGL pipeline of this Game Object. */ - emitCallback: Phaser.Types.GameObjects.Particles.ParticleEmitterCallback; + pipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#emitCallback}. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - emitCallbackScope: any; + pipelineData: object; /** - * A function to call when a particle dies. + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. */ - deathCallback: Phaser.Types.GameObjects.Particles.ParticleDeathCallback; + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; /** - * The calling context for {@link Phaser.GameObjects.Particles.ParticleEmitter#deathCallback}. + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ - deathCallbackScope: any; + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; /** - * Set to hard limit the amount of particle objects this emitter is allowed to create. - * 0 means unlimited. + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - maxParticles: number; + setPipelineData(key: string, value?: any): this; /** - * How many particles are emitted each time particles are emitted (one explosion or one flow cycle). + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. */ - quantity: Phaser.GameObjects.Particles.EmitterOp; + resetPipeline(resetData?: boolean): boolean; /** - * How many ms to wait after emission before the particles start updating. + * Gets the name of the WebGL Pipeline this Game Object is currently using. */ - delay: Phaser.GameObjects.Particles.EmitterOp; + getPipelineName(): string; /** - * 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). + * Does this Game Object have any Post Pipelines set? */ - frequency: number; + hasPostPipeline: boolean; /** - * 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}. + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * + * The pipelines are processed in the order in which they appear in this array. + * + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. */ - on: boolean; + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; /** - * 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. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - particleBringToTop: boolean; + postPipelineData: object; /** - * The time rate applied to active particles, affecting lifespan, movement, and tweens. Values larger than 1 are faster than normal. + * The Pre FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - timeScale: number; + preFX: Phaser.GameObjects.Components.FX | null; /** - * An object describing a shape to emit particles from. + * The Post FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - emitZone: Phaser.GameObjects.Particles.Zones.EdgeZone | Phaser.GameObjects.Particles.Zones.RandomZone; + postFX: Phaser.GameObjects.Components.FX; /** - * An object describing a shape that deactivates particles when they interact with it. + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. */ - deathZone: Phaser.GameObjects.Particles.Zones.DeathZone; + initPostPipeline(preFX?: boolean): void; /** - * A rectangular boundary constraining particle movement. + * Sets one, or more, Post Pipelines on this Game Object. + * + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. + * + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. + * + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * + * You can optionally also set the `postPipelineData` property, if the parameter is given. + * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ - bounds: Phaser.Geom.Rectangle; + setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Whether particles interact with the left edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - collideLeft: boolean; + setPostPipelineData(key: string, value?: any): this; /** - * Whether particles interact with the right edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * @param pipeline The string-based name of the pipeline, or a pipeline class. */ - collideRight: boolean; + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; /** - * Whether particles interact with the top edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * Resets the WebGL Post Pipelines of this Game Object. It does this by calling + * the `destroy` method on each post pipeline and then clearing the local array. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ - collideTop: boolean; + resetPostPipeline(resetData?: boolean): void; /** - * Whether particles interact with the bottom edge of the emitter {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds}. + * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. + * + * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. + * @param pipeline The string-based name of the pipeline, or a pipeline class. */ - collideBottom: boolean; + removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Whether this emitter updates itself and its particles. + * Removes all Pre and Post FX Controllers from this Game Object. * - * Controlled by {@link Phaser.GameObjects.Particles.ParticleEmitter#pause} - * and {@link Phaser.GameObjects.Particles.ParticleEmitter#resume}. + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - active: boolean; + clearFX(): this; /** - * Set this to false to hide any active particles. + * The horizontal scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. */ - visible: boolean; + scrollFactorX: number; /** - * The blend mode of this emitter's particles. + * The vertical scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. */ - blendMode: number; + scrollFactorY: number; /** - * A Game Object whose position is used as the particle origin. + * Sets the scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. */ - follow: Phaser.GameObjects.GameObject; + setScrollFactor(x: number, y?: number): this; /** - * The offset of the particle origin from the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target. + * The Texture this Game Object is using to render with. */ - followOffset: Phaser.Math.Vector2; + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; /** - * Whether the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#visible} state will track - * the {@link Phaser.GameObjects.Particles.ParticleEmitter#follow} target's visibility state. + * The Texture Frame this Game Object is using to render with. */ - trackVisible: boolean; + frame: Phaser.Textures.Frame; /** - * The current texture frame, as an index of {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. + * Sets the texture and frame this Game Object will use to render with. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. + * @param frame The name or index of the frame within the Texture. */ - currentFrame: number; + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; /** - * Whether texture {@link Phaser.GameObjects.Particles.ParticleEmitter#frames} are selected at random. + * Sets the frame this Game Object will use to render with. + * + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. + * + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. + * + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - randomFrame: boolean; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** - * The number of consecutive particles that receive a single texture frame (per frame cycle). + * A property indicating that a Game Object has this component. */ - frameQuantity: number; + readonly hasTransformComponent: boolean; /** - * Merges configuration settings into the emitter's current settings. - * @param config Settings for this emitter. + * The x position of this Game Object. */ - fromJSON(config: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig): this; + x: number; /** - * Creates a description of this emitter suitable for JSON serialization. - * @param output An object to copy output into. + * The y position of this Game Object. */ - toJSON(output?: object): object; + y: number; /** - * Continuously moves the particle origin to follow a Game Object's position. - * @param target The Game Object to follow. - * @param offsetX Horizontal offset of the particle origin from the Game Object. Default 0. - * @param offsetY Vertical offset of the particle origin from the Game Object. Default 0. - * @param trackVisible Whether the emitter's visible state will track the target's visible state. Default false. + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. */ - startFollow(target: Phaser.GameObjects.GameObject, offsetX?: number, offsetY?: number, trackVisible?: boolean): this; + z: number; /** - * Stops following a Game Object. + * The w position of this Game Object. */ - stopFollow(): this; + w: number; /** - * Chooses a texture frame from {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. */ - getFrame(): Phaser.Textures.Frame; + scale: number; /** - * Sets a pattern for assigning texture frames to emitted particles. - * @param frames One or more texture frames, or a configuration object. - * @param pickRandom Whether frames should be assigned at random from `frames`. Default true. - * @param quantity The number of consecutive particles that will receive each frame. Default 1. + * The horizontal scale of this Game Object. */ - setFrame(frames: any[] | string | number | Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig, pickRandom?: boolean, quantity?: number): this; + scaleX: number; /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle movement on or off. - * @param value Radial mode (true) or point mode (true). Default true. + * The vertical scale of this Game Object. */ - setRadial(value?: boolean): this; + scaleY: number; /** - * Sets the position of the emitter's particle origin. - * New particles will be emitted here. - * @param x The x-coordinate of the particle origin. - * @param y The y-coordinate of the particle origin. + * The angle of this Game Object as expressed in degrees. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. + * + * If you prefer to work in radians, see the `rotation` property instead. */ - setPosition(x: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType, y: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + angle: number; /** - * Sets or modifies a rectangular boundary constraining the particles. + * The angle of this Game Object in radians. * - * To remove the boundary, set {@link Phaser.GameObjects.Particles.ParticleEmitter#bounds} to null. - * @param x The x-coordinate of the left edge of the boundary, or an object representing a rectangle. - * @param y The y-coordinate of the top edge of the boundary. - * @param width The width of the boundary. - * @param height The height of the boundary. + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. */ - setBounds(x: number | Phaser.Types.GameObjects.Particles.ParticleEmitterBounds | Phaser.Types.GameObjects.Particles.ParticleEmitterBoundsAlt, y: number, width: number, height: number): this; + rotation: number; /** - * Sets the initial horizontal speed of emitted particles. - * Changes the emitter to point mode. - * @param value The speed, in pixels per second. + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. */ - setSpeedX(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + setPosition(x?: number, y?: number, z?: number, w?: number): this; /** - * Sets the initial vertical speed of emitted particles. - * Changes the emitter to point mode. - * @param value The speed, in pixels per second. + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. */ - setSpeedY(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; /** - * Sets the initial radial speed of emitted particles. - * Changes the emitter to radial mode. - * @param value The speed, in pixels per second. + * Sets the position of this Game Object to be a random position within the confines of + * the given area. + * + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. */ - setSpeed(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; /** - * Sets the horizontal scale of emitted particles. - * @param value The scale, relative to 1. + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. */ - setScaleX(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType): this; + setRotation(radians?: number): this; /** - * Sets the vertical scale of emitted particles. - * @param value The scale, relative to 1. + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. */ - setScaleY(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType): this; + setAngle(degrees?: number): this; /** - * Sets the scale of emitted particles. - * @param value The scale, relative to 1. + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType): this; + setScale(x?: number, y?: number): this; /** - * Sets the horizontal gravity applied to emitted particles. - * @param value Acceleration due to gravity, in pixels per second squared. + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. */ - setGravityX(value: number): this; + setX(value?: number): this; /** - * Sets the vertical gravity applied to emitted particles. - * @param value Acceleration due to gravity, in pixels per second squared. + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. */ - setGravityY(value: number): this; + setY(value?: number): this; /** - * Sets the gravity applied to emitted particles. - * @param x Horizontal acceleration due to gravity, in pixels per second squared. - * @param y Vertical acceleration due to gravity, in pixels per second squared. + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. */ - setGravity(x: number, y: number): this; + setZ(value?: number): this; /** - * Sets the opacity of emitted particles. - * @param value A value between 0 (transparent) and 1 (opaque). + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. */ - setAlpha(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType): this; + setW(value?: number): this; /** - * Sets the color tint of emitted particles. - * @param value A value between 0 and 0xffffff. + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. */ - setTint(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType): this; + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; /** - * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. - * @param value The angle of the initial velocity of emitted particles. + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. */ - setEmitterAngle(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; /** - * Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream. - * @param value The angle of the initial velocity of emitted particles. + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. + * + * The returned Vector2 contains the translated point in its properties. + * + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. */ - setAngle(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; /** - * Sets the lifespan of newly emitted particles. - * @param value The particle lifespan, in ms. + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. */ - setLifespan(value: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + getParentRotation(): number; /** - * Sets the number of particles released at each flow cycle or explosion. - * @param quantity The number of particles to release at each flow cycle or explosion. + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. */ - setQuantity(quantity: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + visible: boolean; /** - * Sets the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#frequency} - * and {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. - * @param frequency The time interval (>= 0) of each flow cycle, in ms; or -1 to put the emitter in explosion mode. - * @param quantity The number of particles to release at each flow cycle or explosion. + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. */ - setFrequency(frequency: number, quantity?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + setVisible(value: boolean): this; + + } + /** + * This class provides the structured required for all Particle Processors. + * + * You should extend it and add the functionality required for your processor, + * including tidying up any resources this may create in the `destroy` method. + * + * See the GravityWell for an example of a processor. + */ + class ParticleProcessor { /** - * 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. - * @param zoneConfig An object describing the zone, or `undefined` to remove any current emit zone. + * @param x The x coordinate of the Particle Processor, in world space. Default 0. + * @param y The y coordinate of the Particle Processor, in world space. Default 0. + * @param active The active state of this Particle Processor. Default true. */ - setEmitZone(zoneConfig?: Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig | Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig): this; + constructor(x?: number, y?: number, active?: boolean); /** - * Sets or removes the {@link Phaser.GameObjects.Particles.ParticleEmitter#deathZone}. - * @param zoneConfig An object describing the zone, or `undefined` to remove any current death zone. + * A reference to the Particle Emitter that owns this Processor. + * This is set automatically when the Processor is added to an Emitter + * and nulled when removed or destroyed. */ - setDeathZone(zoneConfig?: Phaser.Types.GameObjects.Particles.ParticleEmitterDeathZoneConfig): this; + manager: Phaser.GameObjects.Particles.ParticleEmitter; /** - * Creates inactive particles and adds them to this emitter's pool. - * @param particleCount The number of particles to create. + * The x coordinate of the Particle Processor, in world space. */ - reserve(particleCount: number): this; + x: number; /** - * Gets the number of active (in-use) particles in this emitter. + * The y coordinate of the Particle Processor, in world space. */ - getAliveParticleCount(): number; + y: number; /** - * Gets the number of inactive (available) particles in this emitter. + * The active state of the Particle Processor. + * + * An inactive Particle Processor will be skipped for processing by + * its parent Emitter. */ - getDeadParticleCount(): number; + active: boolean; /** - * Gets the total number of particles in this emitter. + * The Particle Processor update method should be overriden by your own + * method and handle the processing of the particles, typically modifying + * their velocityX/Y values based on the criteria of this processor. + * @param particle The Particle to update. + * @param delta The delta time in ms. + * @param step The delta value divided by 1000. + * @param t The current normalized lifetime of the particle, between 0 (birth) and 1 (death). */ - getParticleCount(): number; + update(particle: Phaser.GameObjects.Particles.Particle, delta: number, step: number, t: number): void; /** - * Whether this emitter is at its limit (if set). + * Destroys this Particle Processor by removing all external references. + * + * This is called automatically when the owning Particle Emitter is destroyed. */ - atLimit(): boolean; + destroy(): void; - /** - * Sets a function to call for each newly emitted particle. - * @param callback The function. - * @param context The calling context. - */ - onParticleEmit(callback: Phaser.Types.GameObjects.Particles.ParticleEmitterCallback, context?: any): this; + } + namespace Zones { /** - * Sets a function to call for each particle death. - * @param callback The function. - * @param context The function's calling context. + * 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. */ - onParticleDeath(callback: Phaser.Types.GameObjects.Particles.ParticleDeathCallback, context?: any): this; + class DeathZone { + /** + * + * @param source An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. + * @param killOnEnter Should the Particle be killed when it enters the zone? `true` or leaves it? `false` + */ + constructor(source: Phaser.Types.GameObjects.Particles.DeathZoneSource, killOnEnter: boolean); - /** - * Deactivates every particle in this emitter. - */ - killAll(): this; + /** + * 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. + */ + source: Phaser.Types.GameObjects.Particles.DeathZoneSource; - /** - * Calls a function for each active particle in this emitter. - * @param callback The function. - * @param context The function's calling context. - */ - forEachAlive(callback: Phaser.Types.GameObjects.Particles.ParticleEmitterCallback, context: any): this; + /** + * 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. + */ + killOnEnter: boolean; + + /** + * Checks if the given Particle will be killed or not by this zone. + * @param particle The particle to test against this Death Zones. + */ + willKill(particle: Phaser.GameObjects.Particles.Particle): boolean; + + } /** - * Calls a function for each inactive particle in this emitter. - * @param callback The function. - * @param context The function's calling context. + * A zone that places particles on a shape's edges. */ - forEachDead(callback: Phaser.Types.GameObjects.Particles.ParticleEmitterCallback, context: any): this; + class EdgeZone { + /** + * + * @param source An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + * @param quantity The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. + * @param stepRate The distance between each particle. When set, `quantity` is implied and should be set to 0. + * @param yoyo Whether particles are placed from start to end and then end to start. Default false. + * @param seamless Whether one endpoint will be removed if it's identical to the other. Default true. + * @param total The total number of particles this zone will emit before passing over to the next emission zone in the Emitter. -1 means it will never pass over and you must use `setEmitZone` to change it. Default -1. + */ + constructor(source: Phaser.Types.GameObjects.Particles.EdgeZoneSource, quantity: number, stepRate: number, yoyo?: boolean, seamless?: boolean, total?: number); + + /** + * An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + */ + source: Phaser.Types.GameObjects.Particles.EdgeZoneSource | Phaser.Types.GameObjects.Particles.RandomZoneSource; + + /** + * The points placed on the source edge. + */ + points: Phaser.Geom.Point[]; + + /** + * The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. + */ + quantity: number; + + /** + * The distance between each particle. When set, `quantity` is implied and should be set to 0. + */ + stepRate: number; + + /** + * Whether particles are placed from start to end and then end to start. + */ + yoyo: boolean; + + /** + * The counter used for iterating the EdgeZone's points. + */ + counter: number; + + /** + * Whether one endpoint will be removed if it's identical to the other. + */ + seamless: boolean; + + /** + * The total number of particles this zone will emit before the Emitter + * transfers control over to the next zone in its emission zone list. + * + * By default this is -1, meaning it will never pass over from this + * zone to another one. You can call the `ParticleEmitter.setEmitZone` + * method to change it, or set this value to something else via the + * config, or directly at runtime. + * + * A value of 1 would mean the zones rotate in order, but it can + * be set to any integer value. + */ + total: number; + + /** + * Update the {@link Phaser.GameObjects.Particles.Zones.EdgeZone#points} from the EdgeZone's + * {@link Phaser.GameObjects.Particles.Zones.EdgeZone#source}. + * + * Also updates internal properties. + */ + updateSource(): this; + + /** + * Change the source of the EdgeZone. + * @param source An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. + */ + changeSource(source: Phaser.Types.GameObjects.Particles.EdgeZoneSource): this; + + /** + * Get the next point in the Zone and set its coordinates on the given Particle. + * @param particle The Particle. + */ + getPoint(particle: Phaser.GameObjects.Particles.Particle): void; + + } /** - * 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. + * A zone that places particles randomly within a shapes area. */ - start(): this; + class RandomZone { + /** + * + * @param source An object instance with a `getRandomPoint(point)` method. + */ + constructor(source: Phaser.Types.GameObjects.Particles.RandomZoneSource); + + /** + * An object instance with a `getRandomPoint(point)` method. + */ + source: Phaser.Types.GameObjects.Particles.RandomZoneSource; + + /** + * The total number of particles this zone will emit before the Emitter + * transfers control over to the next zone in its emission zone list. + * + * By default this is -1, meaning it will never pass over from this + * zone to another one. You can call the `ParticleEmitter.setEmitZone` + * method to change it, or set this value to something else via the + * config, or directly at runtime. + * + * A value of 1 would mean the zones rotate in order, but it can + * be set to any integer value. + */ + total: number; + + /** + * Get the next point in the Zone and set its coordinates on the given Particle. + * @param particle The Particle. + */ + getPoint(particle: Phaser.GameObjects.Particles.Particle): void; + + } + + } + + } + + /** + * 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 implements Phaser.GameObjects.Components.PathFollower { + /** + * + * @param scene The Scene to which this PathFollower belongs. + * @param path The Path this PathFollower is following. It can only follow one Path at a time. + * @param x The horizontal position of this Game Object in the world. + * @param y The vertical position of this Game Object in the world. + * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Game Object is rendering with. + */ + constructor(scene: Phaser.Scene, path: Phaser.Curves.Path, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number); + + /** + * If the PathFollower is rotating to match the Path (@see Phaser.GameObjects.PathFollower#rotateToPath) + * this value is added to the rotation value. This allows you to rotate objects to a path but control + * the angle of the rotation as well. + */ + pathRotationOffset: number; + + /** + * An additional vector to add to the PathFollowers position, allowing you to offset it from the + * Path coordinates. + */ + pathOffset: Phaser.Math.Vector2; + + /** + * A Vector2 that stores the current point of the path the follower is on. + */ + pathVector: Phaser.Math.Vector2; + + /** + * The distance the follower has traveled from the previous point to the current one, at the last update. + */ + pathDelta: Phaser.Math.Vector2; + + /** + * The Tween used for following the Path. + */ + pathTween: Phaser.Tweens.Tween; + + /** + * Settings for the PathFollower. + */ + pathConfig: Phaser.Types.GameObjects.PathFollower.PathConfig | null; + + /** + * Internal update handler that advances this PathFollower along the path. + * + * Called automatically by the Scene step, should not typically be called directly. + * @param time The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @param delta The delta time, in ms, elapsed since the last frame. + */ + protected preUpdate(time: number, delta: number): void; + + /** + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). + */ + clearAlpha(): this; + + /** + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * + * If your game is running under WebGL you can optionally specify four different alpha values, each of which + * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. + * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. + * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. + * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. + * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. + */ + setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + + /** + * The alpha value of the Game Object. + * + * This is a global value, impacting the entire Game Object, not just a region of it. + */ + alpha: number; + + /** + * The alpha value starting from the top-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaTopLeft: number; + + /** + * The alpha value starting from the top-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaTopRight: number; + + /** + * The alpha value starting from the bottom-left of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaBottomLeft: number; + + /** + * The alpha value starting from the bottom-right of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + */ + alphaBottomRight: number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency of which blend modes + * are used. + */ + blendMode: Phaser.BlendModes | string | number; + + /** + * Sets the Blend Mode being used by this Game Object. + * + * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) + * + * Under WebGL only the following Blend Modes are available: + * + * * NORMAL + * * ADD + * * MULTIPLY + * * SCREEN + * * ERASE (only works when rendering to a framebuffer, like a Render Texture) + * + * Canvas has more available depending on browser support. + * + * You can also create your own custom Blend Modes in WebGL. + * + * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending + * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these + * reasons try to be careful about the construction of your Scene and the frequency in which blend modes + * are used. + * @param value The BlendMode value. Either a string, a CONST or a number. + */ + setBlendMode(value: string | Phaser.BlendModes | number): this; + + /** + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + */ + depth: number; - /** - * Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on off} the emitter. - */ - stop(): this; + /** + * The depth of this Game Object within the Scene. + * + * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order + * of Game Objects, without actually moving their position in the display list. + * + * The default depth is zero. A Game Object with a higher depth + * value will always render in front of one with a lower value. + * + * Setting the depth will queue a depth sort event within the Scene. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. + */ + setDepth(value: number): this; - /** - * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Deactivates} the emitter. - */ - pause(): this; + /** + * The horizontally flipped state of the Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + */ + flipX: boolean; - /** - * {@link Phaser.GameObjects.Particles.ParticleEmitter#active Activates} the emitter. - */ - resume(): this; + /** + * The vertically flipped state of the Game Object. + * + * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + */ + flipY: boolean; - /** - * Removes the emitter from its manager and the scene. - */ - remove(): this; + /** + * Toggles the horizontal flipped state of this Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + */ + toggleFlipX(): this; - /** - * Sorts active particles with {@link Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback}. - */ - depthSort(): this; + /** + * Toggles the vertical flipped state of this Game Object. + */ + toggleFlipY(): 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. - * @param frequency The time interval (>= 0) of each flow cycle, in ms. - * @param count The number of particles to emit at each flow cycle. Default 1. - */ - flow(frequency: number, count?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType): this; + /** + * Sets the horizontal flipped state of this Game Object. + * + * A Game Object that is flipped horizontally will render inversed on the horizontal axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlipX(value: boolean): this; - /** - * Puts the emitter in explode mode (frequency = -1), stopping any current particle flow, and emits several particles all at once. - * @param count The amount of Particles to emit. - * @param x The x coordinate to emit the Particles from. - * @param y The y coordinate to emit the Particles from. - */ - explode(count: number, x: number, y: number): Phaser.GameObjects.Particles.Particle; + /** + * Sets the vertical flipped state of this Game Object. + * @param value The flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlipY(value: boolean): this; - /** - * Emits particles at a given position (or the emitter's current position). - * @param x The x coordinate to emit the Particles from. Default this.x. - * @param y The y coordinate to emit the Particles from. Default this.x. - * @param count The number of Particles to emit. Default this.quantity. - */ - emitParticleAt(x?: number, y?: number, count?: number): Phaser.GameObjects.Particles.Particle; + /** + * Sets the horizontal and vertical flipped state of this Game Object. + * + * A Game Object that is flipped will render inversed on the flipped axis. + * Flipping always takes place from the middle of the texture and does not impact the scale value. + * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. + * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. + * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. + */ + setFlip(x: boolean, y: boolean): this; - /** - * Emits particles at a given position (or the emitter's current position). - * @param count The number of Particles to emit. Default this.quantity. - * @param x The x coordinate to emit the Particles from. Default this.x. - * @param y The y coordinate to emit the Particles from. Default this.x. - */ - emitParticle(count?: number, x?: number, y?: number): Phaser.GameObjects.Particles.Particle; + /** + * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. + */ + resetFlip(): this; - /** - * Updates this emitter and its particles. - * @param time The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param delta The delta time, in ms, elapsed since the last frame. - */ - preUpdate(time: number, delta: number): void; + /** + * Gets the center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getCenter(output?: O, includeParent?: boolean): O; - /** - * Calculates the difference of two particles, for sorting them by depth. - * @param a The first particle. - * @param b The second particle. - */ - depthSortCallback(a: object, b: object): number; + /** + * Gets the top-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopLeft(output?: O, includeParent?: boolean): O; - /** - * Sets the Blend Mode being used by this Game Object. - * - * This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay) - * - * Under WebGL only the following Blend Modes are available: - * - * * ADD - * * MULTIPLY - * * SCREEN - * * ERASE (only works when rendering to a framebuffer, like a Render Texture) - * - * Canvas has more available depending on browser support. - * - * You can also create your own custom Blend Modes in WebGL. - * - * Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending - * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these - * reasons try to be careful about the construction of your Scene and the frequency in which blend modes - * are used. - * @param value The BlendMode value. Either a string or a CONST. - */ - setBlendMode(value: string | Phaser.BlendModes): this; + /** + * Gets the top-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopCenter(output?: O, includeParent?: boolean): O; - /** - * The Mask this Game Object is using during render. - */ - mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; + /** + * Gets the top-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getTopRight(output?: O, includeParent?: boolean): O; - /** - * Sets the mask that this Game Object will use to render with. - * - * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * If a mask is already set on this Game Object it will be immediately replaced. - * - * Masks are positioned in global space and are not relative to the Game Object to which they - * are applied. The reason for this is that multiple Game Objects can all share the same mask. - * - * Masks have no impact on physics or input detection. They are purely a rendering component - * that allows you to limit what is visible during the render pass. - * @param mask The mask this Game Object will use when rendering. - */ - setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; + /** + * Gets the left-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getLeftCenter(output?: O, includeParent?: boolean): O; - /** - * Clears the mask that this Game Object was using. - * @param destroyMask Destroy the mask before clearing it? Default false. - */ - clearMask(destroyMask?: boolean): this; + /** + * Gets the right-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getRightCenter(output?: O, includeParent?: boolean): O; - /** - * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. - * - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * To create the mask you need to pass in a reference to a renderable Game Object. - * A renderable Game Object is one that uses a texture to render with, such as an - * Image, Sprite, Render Texture or BitmapText. - * - * If you do not provide a renderable object, and this Game Object has a texture, - * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. - */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + /** + * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomLeft(output?: O, includeParent?: boolean): O; - /** - * Creates and returns a Geometry Mask. This mask can be used by any Game Object, - * including this one. - * - * To create the mask you need to pass in a reference to a Graphics Game Object. - * - * If you do not provide a graphics object, and this Game Object is an instance - * of a Graphics object, then it will use itself to create the mask. - * - * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. - */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + /** + * Gets the bottom-center coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomCenter(output?: O, includeParent?: boolean): O; - /** - * The horizontal scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - */ - scrollFactorX: number; + /** + * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. + * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. + */ + getBottomRight(output?: O, includeParent?: boolean): O; - /** - * The vertical scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - */ - scrollFactorY: number; + /** + * Gets the bounds of this Game Object, regardless of origin. + * + * The values are stored and returned in a Rectangle, or Rectangle-like, object. + * @param output An object to store the values in. If not provided a new Rectangle will be created. + */ + getBounds(output?: O): O; - /** - * Sets the scroll factor of this Game Object. - * - * The scroll factor controls the influence of the movement of a Camera upon this Game Object. - * - * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. - * It does not change the Game Objects actual position values. - * - * A value of 1 means it will move exactly in sync with a camera. - * A value of 0 means it will not move at all, even if the camera moves. - * Other values control the degree to which the camera movement is mapped to this Game Object. - * - * Please be aware that scroll factor values other than 1 are not taken in to consideration when - * calculating physics collisions. Bodies always collide based on their world position, but changing - * the scroll factor is a visual adjustment to where the textures are rendered, which can offset - * them from physics bodies if not accounted for in your code. - * @param x The horizontal scroll factor of this Game Object. - * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. - */ - setScrollFactor(x: number, y?: number): this; + /** + * The Mask this Game Object is using during render. + */ + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; - /** - * Sets the visibility of this Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. - */ - setVisible(value: boolean): this; + /** + * Sets the mask that this Game Object will use to render with. + * + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * If a mask is already set on this Game Object it will be immediately replaced. + * + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * @param mask The mask this Game Object will use when rendering. + */ + setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; - } + /** + * Clears the mask that this Game Object was using. + * @param destroyMask Destroy the mask before clearing it? Default false. + */ + clearMask(destroyMask?: boolean): this; /** - * A Particle Emitter Manager creates and controls {@link Phaser.GameObjects.Particles.ParticleEmitter Particle Emitters} and {@link Phaser.GameObjects.Particles.GravityWell Gravity Wells}. + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. + * + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. + * + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - class ParticleEmitterManager extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { - /** - * - * @param scene The Scene to which this Emitter Manager belongs. - * @param texture The key of the Texture this Emitter Manager will use to render particles, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Emitter Manager will use to render particles. - * @param emitters Configuration settings for one or more emitters to create. - */ - constructor(scene: Phaser.Scene, texture: string, frame?: string | number, emitters?: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig | Phaser.Types.GameObjects.Particles.ParticleEmitterConfig[]); + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; - /** - * The time scale applied to all emitters and particles, affecting flow rate, lifespan, and movement. - * Values larger than 1 are faster than normal. - * This is multiplied with any timeScale set on each individual emitter. - */ - timeScale: number; + /** + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. + * + * To create the mask you need to pass in a reference to a Graphics Game Object. + * + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. + * + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. + */ + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; - /** - * The texture used to render this Emitter Manager's particles. - */ - texture: Phaser.Textures.Texture; + /** + * The horizontal origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originX: number; - /** - * The texture frame used to render this Emitter Manager's particles. - */ - frame: Phaser.Textures.Frame; + /** + * The vertical origin of this Game Object. + * The origin maps the relationship between the size and position of the Game Object. + * The default value is 0.5, meaning all Game Objects are positioned based on their center. + * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. + */ + readonly originY: number; - /** - * Names of this Emitter Manager's texture frames. - */ - frameNames: string[]; + /** + * The horizontal display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginX: number; - /** - * A list of Emitters being managed by this Emitter Manager. - */ - emitters: Phaser.Structs.List; + /** + * The vertical display origin of this Game Object. + * The origin is a normalized value between 0 and 1. + * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + */ + displayOriginY: number; - /** - * A list of Gravity Wells being managed by this Emitter Manager. - */ - wells: Phaser.Structs.List; + /** + * Sets the origin of this Game Object. + * + * The values are given in the range 0 to 1. + * @param x The horizontal origin value. Default 0.5. + * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. + */ + setOrigin(x?: number, y?: number): this; - /** - * Sets the texture and frame this Emitter Manager will use to render with. - * - * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * @param key The key of the texture to be used, as stored in the Texture Manager. - * @param frame The name or index of the frame within the Texture. - */ - setTexture(key: string, frame?: string | number): this; + /** + * Sets the origin of this Game Object based on the Pivot values in its Frame. + */ + setOriginFromFrame(): this; - /** - * Sets the frame this Emitter Manager will use to render with. - * - * The Frame has to belong to the current Texture being used. - * - * It can be either a string or an index. - * @param frame The name or index of the frame within the Texture. - */ - setFrame(frame?: string | number): this; + /** + * Sets the display origin of this Game Object. + * The difference between this and setting the origin is that you can use pixel values for setting the display origin. + * @param x The horizontal display origin value. Default 0. + * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + */ + setDisplayOrigin(x?: number, y?: number): this; - /** - * Assigns texture frames to an emitter. - * @param frames The texture frames. - * @param emitter The particle emitter to modify. - */ - setEmitterFrames(frames: Phaser.Textures.Frame | Phaser.Textures.Frame[], emitter: Phaser.GameObjects.Particles.ParticleEmitter): this; + /** + * Updates the Display Origin cached values internally stored on this Game Object. + * You don't usually call this directly, but it is exposed for edge-cases where you may. + */ + updateDisplayOrigin(): this; - /** - * Adds an existing Particle Emitter to this Emitter Manager. - * @param emitter The Particle Emitter to add to this Emitter Manager. - */ - addEmitter(emitter: Phaser.GameObjects.Particles.ParticleEmitter): Phaser.GameObjects.Particles.ParticleEmitter; + /** + * The initial WebGL pipeline of this Game Object. + * + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + */ + defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; - /** - * Creates a new Particle Emitter object, adds it to this Emitter Manager and returns a reference to it. - * @param config Configuration settings for the Particle Emitter to create. - */ - createEmitter(config: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig): Phaser.GameObjects.Particles.ParticleEmitter; + /** + * The current WebGL pipeline of this Game Object. + */ + pipeline: Phaser.Renderer.WebGL.WebGLPipeline; - /** - * Removes a Particle Emitter from this Emitter Manager, if the Emitter belongs to this Manager. - */ - removeEmitter(emitter: Phaser.GameObjects.Particles.ParticleEmitter): Phaser.GameObjects.Particles.ParticleEmitter; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; - /** - * Adds an existing Gravity Well object to this Emitter Manager. - * @param well The Gravity Well to add to this Emitter Manager. - */ - addGravityWell(well: Phaser.GameObjects.Particles.GravityWell): Phaser.GameObjects.Particles.GravityWell; + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; - /** - * Creates a new Gravity Well, adds it to this Emitter Manager and returns a reference to it. - * @param config Configuration settings for the Gravity Well to create. - */ - createGravityWell(config: Phaser.Types.GameObjects.Particles.GravityWellConfig): Phaser.GameObjects.Particles.GravityWell; + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; - /** - * Emits particles from each active emitter. - * @param count The number of particles to release from each emitter. The default is the emitter's own {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. - * @param x The x-coordinate to to emit particles from. The default is the x-coordinate of the emitter's current location. - * @param y The y-coordinate to to emit particles from. The default is the y-coordinate of the emitter's current location. - */ - emitParticle(count?: number, x?: number, y?: number): this; + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; - /** - * Emits particles from each active emitter. - * @param x The x-coordinate to to emit particles from. The default is the x-coordinate of the emitter's current location. - * @param y The y-coordinate to to emit particles from. The default is the y-coordinate of the emitter's current location. - * @param count The number of particles to release from each emitter. The default is the emitter's own {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}. - */ - emitParticleAt(x?: number, y?: number, count?: number): this; + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; - /** - * Pauses this Emitter Manager. - * - * This has the effect of pausing all emitters, and all particles of those emitters, currently under its control. - * - * The particles will still render, but they will not have any of their logic updated. - */ - pause(): this; + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + + /** + * Does this Game Object have any Post Pipelines set? + */ + hasPostPipeline: boolean; - /** - * Resumes this Emitter Manager, should it have been previously paused. - */ - resume(): this; + /** + * The WebGL Post FX Pipelines this Game Object uses for post-render effects. + * + * The pipelines are processed in the order in which they appear in this array. + * + * If you modify this array directly, be sure to set the + * `hasPostPipeline` property accordingly. + */ + postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Gets all active particle processors (gravity wells). - */ - getProcessors(): Phaser.GameObjects.Particles.GravityWell[]; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + postPipelineData: object; - /** - * Updates all active emitters. - * @param time The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param delta The delta time, in ms, elapsed since the last frame. - */ - preUpdate(time: number, delta: number): void; + /** + * The Pre FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + */ + preFX: Phaser.GameObjects.Components.FX | null; - /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. - * - * Setting the depth will queue a depth sort event within the Scene. - */ - depth: number; + /** + * The Post FX component of this Game Object. + * + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. + */ + postFX: Phaser.GameObjects.Components.FX; - /** - * The depth of this Game Object within the Scene. - * - * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order - * of Game Objects, without actually moving their position in the display list. - * - * The default depth is zero. A Game Object with a higher depth - * value will always render in front of one with a lower value. - * - * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. - */ - setDepth(value: number): this; + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; - /** - * The Mask this Game Object is using during render. - */ - mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; + /** + * Sets one, or more, Post Pipelines on this Game Object. + * + * Post Pipelines are invoked after this Game Object has rendered to its target and + * are commonly used for post-fx. + * + * The post pipelines are appended to the `postPipelines` array belonging to this + * Game Object. When the renderer processes this Game Object, it iterates through the post + * pipelines in the order in which they appear in the array. If you are stacking together + * multiple effects, be aware that the order is important. + * + * If you call this method multiple times, the new pipelines will be appended to any existing + * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. + * + * You can optionally also set the `postPipelineData` property, if the parameter is given. + * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; - /** - * Sets the mask that this Game Object will use to render with. - * - * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * If a mask is already set on this Game Object it will be immediately replaced. - * - * Masks are positioned in global space and are not relative to the Game Object to which they - * are applied. The reason for this is that multiple Game Objects can all share the same mask. - * - * Masks have no impact on physics or input detection. They are purely a rendering component - * that allows you to limit what is visible during the render pass. - * @param mask The mask this Game Object will use when rendering. - */ - setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; + /** + * Adds an entry to the `postPipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPostPipelineData(key: string, value?: any): this; - /** - * Clears the mask that this Game Object was using. - * @param destroyMask Destroy the mask before clearing it? Default false. - */ - clearMask(destroyMask?: boolean): this; + /** + * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. + * @param pipeline The string-based name of the pipeline, or a pipeline class. + */ + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. - * - * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. - * - * To create the mask you need to pass in a reference to a renderable Game Object. - * A renderable Game Object is one that uses a texture to render with, such as an - * Image, Sprite, Render Texture or BitmapText. - * - * If you do not provide a renderable object, and this Game Object has a texture, - * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. - */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + /** + * Resets the WebGL Post Pipelines of this Game Object. It does this by calling + * the `destroy` method on each post pipeline and then clearing the local array. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. + */ + resetPostPipeline(resetData?: boolean): void; - /** - * Creates and returns a Geometry Mask. This mask can be used by any Game Object, - * including this one. - * - * To create the mask you need to pass in a reference to a Graphics Game Object. - * - * If you do not provide a graphics object, and this Game Object is an instance - * of a Graphics object, then it will use itself to create the mask. - * - * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. - */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + /** + * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. + * + * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. + * @param pipeline The string-based name of the pipeline, or a pipeline class. + */ + removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; - /** - * The initial WebGL pipeline of this Game Object. - * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. - */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. + */ + clearFX(): this; - /** - * The current WebGL pipeline of this Game Object. - */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * The horizontal scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorX: number; - /** - * Does this Game Object have any Post Pipelines set? - */ - hasPostPipeline: boolean; + /** + * The vertical scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + */ + scrollFactorY: number; - /** - * The WebGL Post FX Pipelines this Game Object uses for post-render effects. - * - * The pipelines are processed in the order in which they appear in this array. - * - * If you modify this array directly, be sure to set the - * `hasPostPipeline` property accordingly. - */ - postPipelines: Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + /** + * Sets the scroll factor of this Game Object. + * + * The scroll factor controls the influence of the movement of a Camera upon this Game Object. + * + * When a camera scrolls it will change the location at which this Game Object is rendered on-screen. + * It does not change the Game Objects actual position values. + * + * A value of 1 means it will move exactly in sync with a camera. + * A value of 0 means it will not move at all, even if the camera moves. + * Other values control the degree to which the camera movement is mapped to this Game Object. + * + * Please be aware that scroll factor values other than 1 are not taken in to consideration when + * calculating physics collisions. Bodies always collide based on their world position, but changing + * the scroll factor is a visual adjustment to where the textures are rendered, which can offset + * them from physics bodies if not accounted for in your code. + * @param x The horizontal scroll factor of this Game Object. + * @param y The vertical scroll factor of this Game Object. If not set it will use the `x` value. Default x. + */ + setScrollFactor(x: number, y?: number): this; - /** - * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. - */ - pipelineData: object; + /** + * The native (un-scaled) width of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. + */ + width: number; - /** - * Sets the initial WebGL Pipeline of this Game Object. - * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + /** + * The native (un-scaled) height of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. + */ + height: number; - /** - * Sets the main WebGL Pipeline of this Game Object. - * - * Also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. - */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + /** + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayWidth: number; - /** - * Sets one, or more, Post Pipelines on this Game Object. - * - * Post Pipelines are invoked after this Game Object has rendered to its target and - * are commonly used for post-fx. - * - * The post pipelines are appended to the `postPipelines` array belonging to this - * Game Object. When the renderer processes this Game Object, it iterates through the post - * pipelines in the order in which they appear in the array. If you are stacking together - * multiple effects, be aware that the order is important. - * - * If you call this method multiple times, the new pipelines will be appended to any existing - * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. - * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. - */ - setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; + /** + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayHeight: number; - /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. - * - * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. - * - * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. - * @param key The key of the pipeline data to set, update, or delete. - * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. - */ - setPipelineData(key: string, value?: any): this; + /** + * Sets the size of this Game Object to be that of the given Frame. + * + * This will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or call the + * `setDisplaySize` method, which is the same thing as changing the scale but allows you + * to do so by giving pixel values. + * + * If you have enabled this Game Object for input, changing the size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * @param frame The frame to base the size of this Game Object on. + */ + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; - /** - * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. - * @param pipeline The string-based name of the pipeline, or a pipeline class. - */ - getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; + /** + * 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. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setSize(width: number, height: number): this; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; + /** + * Sets the display size of this Game Object. + * + * Calling this will adjust the scale. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setDisplaySize(width: number, height: number): this; - /** - * Resets the WebGL Post Pipelines of this Game Object. It does this by calling - * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPostPipeline(resetData?: boolean): void; + /** + * The Texture this Game Object is using to render with. + */ + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; - /** - * Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them. - * - * If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead. - * @param pipeline The string-based name of the pipeline, or a pipeline class. - */ - removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; + /** + * The Texture Frame this Game Object is using to render with. + */ + frame: Phaser.Textures.Frame; - /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. - */ - getPipelineName(): string; + /** + * A boolean flag indicating if this Game Object is being cropped or not. + * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. + * Equally, calling `setCrop` with no arguments will reset the crop and disable it. + */ + isCropped: boolean; - /** - * The x position of this Game Object. - */ - x: number; + /** + * Applies a crop to a texture based Game Object, such as a Sprite or Image. + * + * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. + * + * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just + * changes what is shown when rendered. + * + * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. + * + * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left + * half of it, you could call `setCrop(0, 0, 400, 600)`. + * + * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop + * an area of 200x100 when applied to a Game Object that had a scale factor of 2. + * + * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. + * + * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. + * + * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow + * the renderer to skip several internal calculations. + * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. + * @param y The y coordinate to start the crop from. + * @param width The width of the crop rectangle in pixels. + * @param height The height of the crop rectangle in pixels. + */ + setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; - /** - * The y position of this Game Object. - */ - y: number; + /** + * Sets the texture and frame this Game Object will use to render with. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. + */ + setTexture(key: string, frame?: string | number): this; - /** - * The z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#depth} instead. - */ - z: number; + /** + * Sets the frame this Game Object will use to render with. + * + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. + * + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. + * + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. + */ + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; - /** - * The w position of this Game Object. - */ - w: number; + /** + * The tint value being applied to the top-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintTopLeft: number; - /** - * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object - * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. - * - * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this - * isn't the case, use the `scaleX` or `scaleY` properties instead. - */ - scale: number; + /** + * The tint value being applied to the top-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintTopRight: number; - /** - * The horizontal scale of this Game Object. - */ - scaleX: number; + /** + * The tint value being applied to the bottom-left vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomLeft: number; - /** - * The vertical scale of this Game Object. - */ - scaleY: number; + /** + * The tint value being applied to the bottom-right vertice of the Game Object. + * This value is interpolated from the corner to the center of the Game Object. + * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + */ + tintBottomRight: number; + + /** + * The tint fill mode. + * + * `false` = An additive tint (the default), where vertices colors are blended with the texture. + * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. + */ + tintFill: boolean; - /** - * The angle of this Game Object as expressed in degrees. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left - * and -90 is up. - * - * If you prefer to work in radians, see the `rotation` property instead. - */ - angle: number; + /** + * Clears all tint values associated with this Game Object. + * + * Immediately sets the color values back to 0xffffff and the tint type to 'additive', + * which results in no visible change to the texture. + */ + clearTint(): this; - /** - * The angle of this Game Object in radians. - * - * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left - * and -PI/2 is up. - * - * If you prefer to work in degrees, see the `angle` property instead. - */ - rotation: number; + /** + * Sets an additive tint on this Game Object. + * + * The tint works by taking the pixel color values from the Game Objects texture, and then + * multiplying it by the color value of the tint. You can provide either one color value, + * in which case the whole Game Object will be tinted in that color. Or you can provide a color + * per corner. The colors are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. + * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + */ + setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - /** - * Sets the position of this Game Object. - * @param x The x position of this Game Object. Default 0. - * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. - * @param z The z position of this Game Object. Default 0. - * @param w The w position of this Game Object. Default 0. - */ - setPosition(x?: number, y?: number, z?: number, w?: number): this; + /** + * Sets a fill-based tint on this Game Object. + * + * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture + * with those in the tint. You can use this for effects such as making a player flash 'white' + * if hit by something. You can provide either one color value, in which case the whole + * Game Object will be rendered in that color. Or you can provide a color per corner. The colors + * are blended together across the extent of the Game Object. + * + * To modify the tint color once set, either call this method again with new values or use the + * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, + * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. + * + * To remove a tint call `clearTint`. + * + * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. + * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. + * @param topRight The tint being applied to the top-right of the Game Object. + * @param bottomLeft The tint being applied to the bottom-left of the Game Object. + * @param bottomRight The tint being applied to the bottom-right of the Game Object. + */ + setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - /** - * Copies an object's coordinates to this Game Object's position. - * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. - */ - copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; + /** + * The tint value being applied to the whole of the Game Object. + * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. + */ + tint: number; - /** - * Sets the position of this Game Object to be a random position within the confines of - * the given area. - * - * If no area is specified a random position between 0 x 0 and the game width x height is used instead. - * - * The position does not factor in the size of this Game Object, meaning that only the origin is - * guaranteed to be within the area. - * @param x The x position of the top-left of the random area. Default 0. - * @param y The y position of the top-left of the random area. Default 0. - * @param width The width of the random area. - * @param height The height of the random area. - */ - setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; + /** + * Does this Game Object have a tint applied? + * + * It checks to see if the 4 tint properties are set to the value 0xffffff + * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. + */ + readonly isTinted: boolean; - /** - * Sets the rotation of this Game Object. - * @param radians The rotation of this Game Object, in radians. Default 0. - */ - setRotation(radians?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; - /** - * Sets the angle of this Game Object. - * @param degrees The rotation of this Game Object, in degrees. Default 0. - */ - setAngle(degrees?: number): this; + /** + * The x position of this Game Object. + */ + x: number; - /** - * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. - * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. - */ - setScale(x: number, y?: number): this; + /** + * The y position of this Game Object. + */ + y: number; - /** - * Sets the x position of this Game Object. - * @param value The x position of this Game Object. Default 0. - */ - setX(value?: number): this; + /** + * The z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#depth} instead. + */ + z: number; - /** - * Sets the y position of this Game Object. - * @param value The y position of this Game Object. Default 0. - */ - setY(value?: number): this; + /** + * The w position of this Game Object. + */ + w: number; - /** - * Sets the z position of this Game Object. - * - * Note: The z position does not control the rendering order of 2D Game Objects. Use - * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. - * @param value The z position of this Game Object. Default 0. - */ - setZ(value?: number): this; + /** + * This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object + * to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`. + * + * Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this + * isn't the case, use the `scaleX` or `scaleY` properties instead. + */ + scale: number; - /** - * Sets the w position of this Game Object. - * @param value The w position of this Game Object. Default 0. - */ - setW(value?: number): this; + /** + * The horizontal scale of this Game Object. + */ + scaleX: number; - /** - * Gets the local transform matrix for this Game Object. - * @param tempMatrix The matrix to populate with the values from this Game Object. - */ - getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + /** + * The vertical scale of this Game Object. + */ + scaleY: number; - /** - * Gets the world transform matrix for this Game Object, factoring in any parent Containers. - * @param tempMatrix The matrix to populate with the values from this Game Object. - * @param parentMatrix A temporary matrix to hold parent values during the calculations. - */ - getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; + /** + * The angle of this Game Object as expressed in degrees. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left + * and -90 is up. + * + * If you prefer to work in radians, see the `rotation` property instead. + */ + angle: number; - /** - * Takes the given `x` and `y` coordinates and converts them into local space for this - * Game Object, taking into account parent and local transforms, and the Display Origin. - * - * The returned Vector2 contains the translated point in its properties. - * - * A Camera needs to be provided in order to handle modified scroll factors. If no - * camera is specified, it will use the `main` camera from the Scene to which this - * Game Object belongs. - * @param x The x position to translate. - * @param y The y position to translate. - * @param point A Vector2, or point-like object, to store the results in. - * @param camera The Camera which is being tested against. If not given will use the Scene default camera. - */ - getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + /** + * The angle of this Game Object in radians. + * + * Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left + * and -PI/2 is up. + * + * If you prefer to work in degrees, see the `angle` property instead. + */ + rotation: number; - /** - * Gets the sum total rotation of all of this Game Objects parent Containers. - * - * The returned value is in radians and will be zero if this Game Object has no parent container. - */ - getParentRotation(): number; + /** + * Sets the position of this Game Object. + * @param x The x position of this Game Object. Default 0. + * @param y The y position of this Game Object. If not set it will use the `x` value. Default x. + * @param z The z position of this Game Object. Default 0. + * @param w The w position of this Game Object. Default 0. + */ + setPosition(x?: number, y?: number, z?: number, w?: number): this; - /** - * The visible state of the Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - */ - visible: boolean; + /** + * Copies an object's coordinates to this Game Object's position. + * @param source An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied. + */ + copyPosition(source: Phaser.Types.Math.Vector2Like | Phaser.Types.Math.Vector3Like | Phaser.Types.Math.Vector4Like): this; - /** - * Sets the visibility of this Game Object. - * - * An invisible Game Object will skip rendering, but will still process update logic. - * @param value The visible state of the Game Object. - */ - setVisible(value: boolean): this; + /** + * Sets the position of this Game Object to be a random position within the confines of + * the given area. + * + * If no area is specified a random position between 0 x 0 and the game width x height is used instead. + * + * The position does not factor in the size of this Game Object, meaning that only the origin is + * guaranteed to be within the area. + * @param x The x position of the top-left of the random area. Default 0. + * @param y The y position of the top-left of the random area. Default 0. + * @param width The width of the random area. + * @param height The height of the random area. + */ + setRandomPosition(x?: number, y?: number, width?: number, height?: number): this; - } + /** + * Sets the rotation of this Game Object. + * @param radians The rotation of this Game Object, in radians. Default 0. + */ + setRotation(radians?: number): this; - namespace Zones { - /** - * 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 { - /** - * - * @param source An object instance that has a `contains` method that returns a boolean when given `x` and `y` arguments. - * @param killOnEnter Should the Particle be killed when it enters the zone? `true` or leaves it? `false` - */ - constructor(source: Phaser.Types.GameObjects.Particles.DeathZoneSource, killOnEnter: boolean); + /** + * Sets the angle of this Game Object. + * @param degrees The rotation of this Game Object, in degrees. Default 0. + */ + setAngle(degrees?: number): this; - /** - * 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. - */ - source: Phaser.Types.GameObjects.Particles.DeathZoneSource; + /** + * Sets the scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. + * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. + */ + setScale(x?: number, y?: number): this; - /** - * 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. - */ - killOnEnter: boolean; + /** + * Sets the x position of this Game Object. + * @param value The x position of this Game Object. Default 0. + */ + setX(value?: number): this; - /** - * Checks if the given Particle will be killed or not by this zone. - * @param particle The Particle to be checked against this zone. - */ - willKill(particle: Phaser.GameObjects.Particles.Particle): boolean; + /** + * Sets the y position of this Game Object. + * @param value The y position of this Game Object. Default 0. + */ + setY(value?: number): this; - } + /** + * Sets the z position of this Game Object. + * + * Note: The z position does not control the rendering order of 2D Game Objects. Use + * {@link Phaser.GameObjects.Components.Depth#setDepth} instead. + * @param value The z position of this Game Object. Default 0. + */ + setZ(value?: number): this; - /** - * A zone that places particles on a shape's edges. - */ - class EdgeZone { - /** - * - * @param source An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. - * @param quantity The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. - * @param stepRate The distance between each particle. When set, `quantity` is implied and should be set to 0. - * @param yoyo Whether particles are placed from start to end and then end to start. Default false. - * @param seamless Whether one endpoint will be removed if it's identical to the other. Default true. - */ - constructor(source: Phaser.Types.GameObjects.Particles.EdgeZoneSource, quantity: number, stepRate: number, yoyo?: boolean, seamless?: boolean); + /** + * Sets the w position of this Game Object. + * @param value The w position of this Game Object. Default 0. + */ + setW(value?: number): this; - /** - * An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. - */ - source: Phaser.Types.GameObjects.Particles.EdgeZoneSource | Phaser.Types.GameObjects.Particles.RandomZoneSource; + /** + * Gets the local transform matrix for this Game Object. + * @param tempMatrix The matrix to populate with the values from this Game Object. + */ + getLocalTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; - /** - * The points placed on the source edge. - */ - points: Phaser.Geom.Point[]; + /** + * Gets the world transform matrix for this Game Object, factoring in any parent Containers. + * @param tempMatrix The matrix to populate with the values from this Game Object. + * @param parentMatrix A temporary matrix to hold parent values during the calculations. + */ + getWorldTransformMatrix(tempMatrix?: Phaser.GameObjects.Components.TransformMatrix, parentMatrix?: Phaser.GameObjects.Components.TransformMatrix): Phaser.GameObjects.Components.TransformMatrix; - /** - * The number of particles to place on the source edge. Set to 0 to use `stepRate` instead. - */ - quantity: number; + /** + * Takes the given `x` and `y` coordinates and converts them into local space for this + * Game Object, taking into account parent and local transforms, and the Display Origin. + * + * The returned Vector2 contains the translated point in its properties. + * + * A Camera needs to be provided in order to handle modified scroll factors. If no + * camera is specified, it will use the `main` camera from the Scene to which this + * Game Object belongs. + * @param x The x position to translate. + * @param y The y position to translate. + * @param point A Vector2, or point-like object, to store the results in. + * @param camera The Camera which is being tested against. If not given will use the Scene default camera. + */ + getLocalPoint(x: number, y: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; - /** - * The distance between each particle. When set, `quantity` is implied and should be set to 0. - */ - stepRate: number; + /** + * Gets the sum total rotation of all of this Game Objects parent Containers. + * + * The returned value is in radians and will be zero if this Game Object has no parent container. + */ + getParentRotation(): number; - /** - * Whether particles are placed from start to end and then end to start. - */ - yoyo: boolean; + /** + * The visible state of the Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + */ + visible: boolean; - /** - * The counter used for iterating the EdgeZone's points. - */ - counter: number; + /** + * Sets the visibility of this Game Object. + * + * An invisible Game Object will skip rendering, but will still process update logic. + * @param value The visible state of the Game Object. + */ + setVisible(value: boolean): this; - /** - * Whether one endpoint will be removed if it's identical to the other. - */ - seamless: boolean; + /** + * The Path this PathFollower is following. It can only follow one Path at a time. + */ + path: Phaser.Curves.Path; - /** - * Update the {@link Phaser.GameObjects.Particles.Zones.EdgeZone#points} from the EdgeZone's - * {@link Phaser.GameObjects.Particles.Zones.EdgeZone#source}. - * - * Also updates internal properties. - */ - updateSource(): this; + /** + * Should the PathFollower automatically rotate to point in the direction of the Path? + */ + rotateToPath: boolean; - /** - * Change the source of the EdgeZone. - * @param source An object instance with a `getPoints(quantity, stepRate)` method returning an array of points. - */ - changeSource(source: Phaser.Types.GameObjects.Particles.EdgeZoneSource): this; + /** + * Set the Path that this PathFollower should follow. + * + * Optionally accepts {@link Phaser.Types.GameObjects.PathFollower.PathConfig} settings. + * @param path The Path this PathFollower is following. It can only follow one Path at a time. + * @param config Settings for the PathFollower. + */ + setPath(path: Phaser.Curves.Path, config?: number | Phaser.Types.GameObjects.PathFollower.PathConfig | Phaser.Types.Tweens.NumberTweenBuilderConfig): this; - /** - * Get the next point in the Zone and set its coordinates on the given Particle. - * @param particle The Particle. - */ - getPoint(particle: Phaser.GameObjects.Particles.Particle): void; + /** + * Set whether the PathFollower should automatically rotate to point in the direction of the Path. + * @param value Whether the PathFollower should automatically rotate to point in the direction of the Path. + * @param offset Rotation offset in degrees. Default 0. + */ + setRotateToPath(value: boolean, offset?: number): this; - } + /** + * Is this PathFollower actively following a Path or not? + * + * To be considered as `isFollowing` it must be currently moving on a Path, and not paused. + */ + isFollowing(): boolean; - /** - * A zone that places particles randomly within a shapes area. - */ - class RandomZone { - /** - * - * @param source An object instance with a `getRandomPoint(point)` method. - */ - constructor(source: Phaser.Types.GameObjects.Particles.RandomZoneSource); + /** + * Starts this PathFollower following its given Path. + * @param config The duration of the follow, or a PathFollower config object. Default {}. + * @param startAt Optional start position of the follow, between 0 and 1. Default 0. + */ + startFollow(config?: number | Phaser.Types.GameObjects.PathFollower.PathConfig | Phaser.Types.Tweens.NumberTweenBuilderConfig, startAt?: number): this; - /** - * An object instance with a `getRandomPoint(point)` method. - */ - source: Phaser.Types.GameObjects.Particles.RandomZoneSource; + /** + * Pauses this PathFollower. It will still continue to render, but it will remain motionless at the + * point on the Path at which you paused it. + */ + pauseFollow(): this; - /** - * Get the next point in the Zone and set its coordinates on the given Particle. - * @param particle The Particle. - */ - getPoint(particle: Phaser.GameObjects.Particles.Particle): void; + /** + * Resumes a previously paused PathFollower. + * + * If the PathFollower was not paused this has no effect. + */ + resumeFollow(): this; - } + /** + * Stops this PathFollower from following the path any longer. + * + * This will invoke any 'stop' conditions that may exist on the Path, or for the follower. + */ + stopFollow(): this; - } + /** + * Internal update handler that advances this PathFollower along the path. + * + * Called automatically by the Scene step, should not typically be called directly. + */ + pathUpdate(): void; } /** - * A PathFollower Game Object. + * A Plane Game Object. * - * A PathFollower is a Sprite Game Object with some extra helpers to allow it to follow a Path automatically. + * The Plane Game Object is a helper class that takes the Mesh Game Object and extends it, + * allowing for fast and easy creation of Planes. A Plane is a one-sided grid of cells, + * where you specify the number of cells in each dimension. The Plane can have a texture + * that is either repeated (tiled) across each cell, or applied to the full Plane. * - * 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. + * The Plane can then be manipulated in 3D space, with rotation across all 3 axis. * - * 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. + * This allows you to create effects not possible with regular Sprites, such as perspective + * distortion. You can also adjust the vertices on a per-vertex basis. Plane data becomes + * part of the WebGL batch, just like standard Sprites, so doesn't introduce any additional + * shader overhead. Because the Plane just generates vertices into the WebGL batch, like any + * other Sprite, you can use all of the common Game Object components on a Plane too, + * such as a custom pipeline, mask, blend mode or texture. + * + * You can use the `uvScroll` and `uvScale` methods to adjust the placement and scaling + * of the texture if this Plane is using a single texture, and not a frame from a texture + * atlas or sprite sheet. + * + * The Plane Game Object also has the Animation component, allowing you to play animations + * across the Plane just as you would with a Sprite. + * + * Note that the Plane object is WebGL only and does not have a Canvas counterpart. + * + * The Plane origin is always 0.5 x 0.5 and cannot be changed. */ - class PathFollower extends Phaser.GameObjects.Sprite implements Phaser.GameObjects.Components.PathFollower { + class Plane extends Phaser.GameObjects.Mesh { /** * - * @param scene The Scene to which this PathFollower belongs. - * @param path The Path this PathFollower is following. It can only follow one Path at a time. - * @param x The horizontal position of this Game Object in the world. - * @param y The vertical position of this Game Object in the world. - * @param texture The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. - * @param frame An optional frame from the Texture this Game Object is rendering with. + * @param scene The Scene to which this Plane belongs. A Plane can only belong to one Scene at a time. + * @param x The horizontal position of this Plane in the world. + * @param y The vertical position of this Plane in the world. + * @param texture The key, or instance of the Texture this Plane will use to render with, as stored in the Texture Manager. + * @param frame An optional frame from the Texture this Plane is rendering with. + * @param width The width of this Plane, in cells, not pixels. Default 8. + * @param height The height of this Plane, in cells, not pixels. Default 8. + * @param tile Is the texture tiled? I.e. repeated across each cell. Default false. */ - constructor(scene: Phaser.Scene, path: Phaser.Curves.Path, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number); + constructor(scene: Phaser.Scene, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number, width?: number, height?: number, tile?: boolean); /** - * If the PathFollower is rotating to match the Path (@see Phaser.GameObjects.PathFollower#rotateToPath) - * this value is added to the rotation value. This allows you to rotate objects to a path but control - * the angle of the rotation as well. + * The Animation State component of this Sprite. + * + * This component provides features to apply animations to this Sprite. + * It is responsible for playing, loading, queuing animations for later playback, + * mixing between animations and setting the current animation frame to this Sprite. */ - pathRotationOffset: number; + anims: Phaser.Animations.AnimationState; /** - * An additional vector to add to the PathFollowers position, allowing you to offset it from the - * Path coordinates. + * The width of this Plane in cells, not pixels. + * + * This value is read-only. To adjust it, see the `setGridSize` method. */ - pathOffset: Phaser.Math.Vector2; + readonly gridWidth: number; /** - * A Vector2 that stores the current point of the path the follower is on. + * The height of this Plane in cells, not pixels. + * + * This value is read-only. To adjust it, see the `setGridSize` method. */ - pathVector: Phaser.Math.Vector2; + readonly gridHeight: number; /** - * The distance the follower has traveled from the previous point to the current one, at the last update. + * Is the texture of this Plane tiled across all cells, or not? + * + * This value is read-only. To adjust it, see the `setGridSize` method. */ - pathDelta: Phaser.Math.Vector2; + readonly isTiled: boolean; /** - * The Tween used for following the Path. + * Modifies the layout of this Plane by adjusting the grid dimensions to the + * given width and height. The values are given in cells, not pixels. + * + * The `tile` parameter allows you to control if the texture is tiled, or + * applied across the entire Plane? A tiled texture will repeat with one + * iteration per cell. A non-tiled texture will be applied across the whole + * Plane. + * + * Note that if this Plane is using a single texture, not from a texture atlas + * or sprite sheet, then you can use the `Plane.uvScale` method to have much + * more fine-grained control over the texture tiling. + * @param width The width of this Plane, in cells, not pixels. Default 8. + * @param height The height of this Plane, in cells, not pixels. Default 8. + * @param tile Is the texture tiled? I.e. repeated across each cell. Default false. */ - pathTween: Phaser.Tweens.Tween; + preDestroy(width?: number, height?: number, tile?: boolean): void; /** - * Settings for the PathFollower. + * Sets the height of this Plane to match the given value, in pixels. + * + * This adjusts the `Plane.viewPosition.z` value to achieve this. + * + * If no `value` parameter is given, it will set the view height to match + * that of the current texture frame the Plane is using. + * @param value The height, in pixels, to set this Plane view height to. */ - pathConfig: Phaser.Types.GameObjects.PathFollower.PathConfig; + setViewHeight(value?: number): void; /** - * Internal update handler that advances this PathFollower along the path. + * Creates a checkerboard style texture, based on the given colors and alpha + * values and applies it to this Plane, replacing any current texture it may + * have. * - * Called automatically by the Scene step, should not typically be called directly. - * @param time The current timestamp as generated by the Request Animation Frame or SetTimeout. - * @param delta The delta time, in ms, elapsed since the last frame. + * The colors are used in an alternating pattern, like a chess board. + * + * Calling this method generates a brand new 16x16 pixel WebGLTexture internally + * and applies it to this Plane. While quite fast to do, you should still be + * mindful of calling this method either extensively, or in tight parts of + * your game. + * @param color1 The odd cell color, specified as a hex value. Default 0xffffff. + * @param color2 The even cell color, specified as a hex value. Default 0x0000ff. + * @param alpha1 The odd cell alpha value, specified as a number between 0 and 255. Default 255. + * @param alpha2 The even cell alpha value, specified as a number between 0 and 255. Default 255. + * @param height The view height of the Plane after creation, in pixels. Default 128. */ - protected preUpdate(time: number, delta: number): void; + createCheckerboard(color1?: number, color2?: number, alpha1?: number, alpha2?: number, height?: number): void; /** - * Clears all alpha values associated with this Game Object. + * If this Plane has a Checkerboard Texture, this method will destroy it + * and reset the internal flag for it. + */ + removeCheckerboard(): void; + + /** + * Start playing the given animation on this Plane. * - * Immediately sets the alpha levels back to 1 (fully opaque). + * Animations in Phaser can either belong to the global Animation Manager, or specifically to this Plane. + * + * The benefit of a global animation is that multiple Game Objects can all play the same animation, without + * having to duplicate the data. You can just create it once and then play it on any animating Game Object. + * + * The following code shows how to create a global repeating animation. The animation will be created + * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': + * + * ```javascript + * var config = { + * key: 'run', + * frames: 'muybridge', + * frameRate: 15, + * repeat: -1 + * }; + * + * // This code should be run from within a Scene: + * this.anims.create(config); + * ``` + * + * However, if you wish to create an animation that is unique to this Plane, and this Plane alone, + * you can call the `Animation.create` method instead. It accepts the exact same parameters as when + * creating a global animation, however the resulting data is kept locally in this Plane. + * + * With the animation created, either globally or locally, you can now play it on this Plane: + * + * ```javascript + * const plane = this.add.plane(...); + * plane.play('run'); + * ``` + * + * Alternatively, if you wish to run it at a different frame rate for example, you can pass a config + * object instead: + * + * ```javascript + * const plane = this.add.plane(...); + * plane.play({ key: 'run', frameRate: 24 }); + * ``` + * + * When playing an animation on a Plane it will first check to see if it can find a matching key + * locally within the Plane. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * If you need a Plane to be able to play both local and global animations, make sure they don't + * have conflicting keys. + * + * See the documentation for the `PlayAnimationConfig` config object for more details about this. + * + * Also, see the documentation in the Animation Manager for further details on creating animations. + * @param key The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param ignoreIfPlaying If an animation is already playing then ignore this call. Default false. */ - clearAlpha(): this; + play(key: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig, ignoreIfPlaying?: boolean): this; /** - * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. - * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * Start playing the given animation on this Plane, in reverse. * - * If your game is running under WebGL you can optionally specify four different alpha values, each of which - * correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used. - * @param topLeft The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object. Default 1. - * @param topRight The alpha value used for the top-right of the Game Object. WebGL only. - * @param bottomLeft The alpha value used for the bottom-left of the Game Object. WebGL only. - * @param bottomRight The alpha value used for the bottom-right of the Game Object. WebGL only. + * Animations in Phaser can either belong to the global Animation Manager, or specifically to a Game Object. + * + * The benefit of a global animation is that multiple Game Objects can all play the same animation, without + * having to duplicate the data. You can just create it once and then play it on any animating Game Object. + * + * The following code shows how to create a global repeating animation. The animation will be created + * from all of the frames within the sprite sheet that was loaded with the key 'muybridge': + * + * ```javascript + * var config = { + * key: 'run', + * frames: 'muybridge', + * frameRate: 15, + * repeat: -1 + * }; + * + * // This code should be run from within a Scene: + * this.anims.create(config); + * ``` + * + * However, if you wish to create an animation that is unique to this Game Object, and this Game Object alone, + * you can call the `Animation.create` method instead. It accepts the exact same parameters as when + * creating a global animation, however the resulting data is kept locally in this Game Object. + * + * With the animation created, either globally or locally, you can now play it on this Game Object: + * + * ```javascript + * const plane = this.add.plane(...); + * plane.playReverse('run'); + * ``` + * + * Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config + * object instead: + * + * ```javascript + * const plane = this.add.plane(...); + * plane.playReverse({ key: 'run', frameRate: 24 }); + * ``` + * + * When playing an animation on a Game Object it will first check to see if it can find a matching key + * locally within the Game Object. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * + * If you need a Game Object to be able to play both local and global animations, make sure they don't + * have conflicting keys. + * + * See the documentation for the `PlayAnimationConfig` config object for more details about this. + * + * Also, see the documentation in the Animation Manager for further details on creating animations. + * @param key The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param ignoreIfPlaying If an animation is already playing then ignore this call. Default false. */ - setAlpha(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; + playReverse(key: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig, ignoreIfPlaying?: boolean): this; /** - * The alpha value of the Game Object. + * Waits for the specified delay, in milliseconds, then starts playback of the given animation. * - * This is a global value, impacting the entire Game Object, not just a region of it. + * If the animation _also_ has a delay value set in its config, it will be **added** to the delay given here. + * + * If an animation is already running and a new animation is given to this method, it will wait for + * the given delay before starting the new animation. + * + * If no animation is currently running, the given one begins after the delay. + * + * When playing an animation on a Game Object it will first check to see if it can find a matching key + * locally within the Game Object. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * @param key The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param delay The delay, in milliseconds, to wait before starting the animation playing. */ - alpha: number; + playAfterDelay(key: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig, delay: number): this; /** - * The alpha value starting from the top-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback + * of the given animation. + * + * You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an + * idle animation to a walking animation, by making them blend smoothly into each other. + * + * If no animation is currently running, the given one will start immediately. + * + * When playing an animation on a Game Object it will first check to see if it can find a matching key + * locally within the Game Object. If it can, it will play the local animation. If not, it will then + * search the global Animation Manager and look for it there. + * @param key The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object. + * @param repeatCount How many times should the animation repeat before the next one starts? Default 1. */ - alphaTopLeft: number; + playAfterRepeat(key: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig, repeatCount?: number): this; /** - * The alpha value starting from the top-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` events. + * + * If no animation is playing, no event will be dispatched. + * + * If there is another animation queued (via the `chain` method) then it will start playing immediately. */ - alphaTopRight: number; + stop(): this; /** - * The alpha value starting from the bottom-left of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * Stops the current animation from playing after the specified time delay, given in milliseconds. + * + * It then dispatches the `ANIMATION_STOP` event. + * + * If no animation is running, no events will be dispatched. + * + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. + * @param delay The number of milliseconds to wait before stopping this animation. */ - alphaBottomLeft: number; + stopAfterDelay(delay: number): this; /** - * The alpha value starting from the bottom-right of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. + * Stops the current animation from playing after the given number of repeats. + * + * It then dispatches the `ANIMATION_STOP` event. + * + * If no animation is running, no events will be dispatched. + * + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. + * @param repeatCount How many times should the animation repeat before stopping? Default 1. */ - alphaBottomRight: number; + stopAfterRepeat(repeatCount?: number): this; + + /** + * Stops the current animation from playing when it next sets the given frame. + * If this frame doesn't exist within the animation it will not stop it from playing. + * + * It then dispatches the `ANIMATION_STOP` event. + * + * If no animation is running, no events will be dispatched. + * + * If there is another animation in the queue (set via the `chain` method) then it will start playing, + * when the current one stops. + * @param frame The frame to check before stopping this animation. + */ + stopOnFrame(frame: Phaser.Animations.AnimationFrame): this; + + /** + * Runs the preUpdate for this Plane, which will check its Animation State, + * if one is playing, and refresh view / model matrices, if updated. + * @param time The current timestamp. + * @param delta The delta time, in ms, elapsed since the last frame. + */ + protected preUpdate(time: number, delta: number): void; + + /** + * Clears all alpha values associated with this Game Object. + * + * Immediately sets the alpha levels back to 1 (fully opaque). + */ + clearAlpha(): this; + + /** + * Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders. + * Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque. + * @param value The alpha value applied across the whole Game Object. Default 1. + */ + setAlpha(value?: number): this; + + /** + * The alpha value of the Game Object. + * + * This is a global value, impacting the entire Game Object, not just a region of it. + */ + alpha: number; /** * Sets the Blend Mode being used by this Game Object. @@ -25321,6 +32597,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -25335,7 +32612,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -25344,6 +32621,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -25357,12 +32635,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -25384,152 +32662,10 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; - /** - * The horizontally flipped state of the Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - flipX: boolean; - - /** - * The vertically flipped state of the Game Object. - * - * A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down) - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - flipY: boolean; - - /** - * Toggles the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - */ - toggleFlipX(): this; - - /** - * Toggles the vertical flipped state of this Game Object. - */ - toggleFlipY(): this; - - /** - * Sets the horizontal flipped state of this Game Object. - * - * A Game Object that is flipped horizontally will render inversed on the horizontal axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlipX(value: boolean): this; - - /** - * Sets the vertical flipped state of this Game Object. - * @param value The flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlipY(value: boolean): this; - - /** - * Sets the horizontal and vertical flipped state of this Game Object. - * - * A Game Object that is flipped will render inversed on the flipped axis. - * Flipping always takes place from the middle of the texture and does not impact the scale value. - * If this Game Object has a physics body, it will not change the body. This is a rendering toggle only. - * @param x The horizontal flipped state. `false` for no flip, or `true` to be flipped. - * @param y The horizontal flipped state. `false` for no flip, or `true` to be flipped. - */ - setFlip(x: boolean, y: boolean): this; - - /** - * Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state. - */ - resetFlip(): this; - - /** - * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - */ - getCenter(output?: O): O; - - /** - * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getTopLeft(output?: O, includeParent?: boolean): O; - - /** - * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getTopCenter(output?: O, includeParent?: boolean): O; - - /** - * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getTopRight(output?: O, includeParent?: boolean): O; - - /** - * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getLeftCenter(output?: O, includeParent?: boolean): O; - - /** - * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getRightCenter(output?: O, includeParent?: boolean): O; - - /** - * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getBottomLeft(output?: O, includeParent?: boolean): O; - - /** - * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getBottomCenter(output?: O, includeParent?: boolean): O; - - /** - * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers - * @param output An object to store the values in. If not provided a new Vector2 will be created. - * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. - */ - getBottomRight(output?: O, includeParent?: boolean): O; - - /** - * Gets the bounds of this Game Object, regardless of origin. - * The values are stored and returned in a Rectangle, or Rectangle-like, object. - * @param output An object to store the values in. If not provided a new Rectangle will be created. - */ - getBounds(output?: O): O; - /** * The Mask this Game Object is using during render. */ @@ -25560,7 +32696,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -25570,10 +32706,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -25585,79 +32725,66 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. - */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; - - /** - * The horizontal origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the left of the Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - originX: number; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** - * The vertical origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the top of the Game Object. + * The initial WebGL pipeline of this Game Object. + * + * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. */ - originY: number; + defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * The horizontal display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * The current WebGL pipeline of this Game Object. */ - displayOriginX: number; + pipeline: Phaser.Renderer.WebGL.WebGLPipeline; /** - * The vertical display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - displayOriginY: number; + pipelineData: object; /** - * Sets the origin of this Game Object. + * Sets the initial WebGL Pipeline of this Game Object. * - * The values are given in the range 0 to 1. - * @param x The horizontal origin value. Default 0.5. - * @param y The vertical origin value. If not defined it will be set to the value of `x`. Default x. - */ - setOrigin(x?: number, y?: number): this; - - /** - * Sets the origin of this Game Object based on the Pivot values in its Frame. + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. */ - setOriginFromFrame(): this; + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; /** - * Sets the display origin of this Game Object. - * The difference between this and setting the origin is that you can use pixel values for setting the display origin. - * @param x The horizontal display origin value. Default 0. - * @param y The vertical display origin value. If not defined it will be set to the value of `x`. Default x. + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ - setDisplayOrigin(x?: number, y?: number): this; + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; /** - * Updates the Display Origin cached values internally stored on this Game Object. - * You don't usually call this directly, but it is exposed for edge-cases where you may. + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - updateDisplayOrigin(): this; + setPipelineData(key: string, value?: any): this; /** - * The initial WebGL pipeline of this Game Object. - * - * If you call `resetPipeline` on this Game Object, the pipeline is reset to this default. + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. */ - defaultPipeline: Phaser.Renderer.WebGL.WebGLPipeline; + resetPipeline(resetData?: boolean): boolean; /** - * The current WebGL pipeline of this Game Object. + * Gets the name of the WebGL Pipeline this Game Object is currently using. */ - pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + getPipelineName(): string; /** * Does this Game Object have any Post Pipelines set? @@ -25677,27 +32804,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -25713,27 +32878,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -25741,17 +32902,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -25764,9 +32918,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -25864,18 +33022,12 @@ declare namespace Phaser { displayHeight: number; /** - * Sets the size of this Game Object to be that of the given Frame. - * - * This will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or call the - * `setDisplaySize` method, which is the same thing as changing the scale but allows you - * to do so by giving pixel values. - * - * If you have enabled this Game Object for input, changing the size will _not_ change the - * size of the hit area. To do this you should adjust the `input.hitArea` object directly. - * @param frame The frame to base the size of this Game Object on. + * An internal method that resets the perspective projection for this Plane + * when it changes texture or frame, and also resets the cell UV coordinates, + * if required. + * @param resetUV Reset all of the cell UV coordinates? Default true. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setSizeToFrame(resetUV?: boolean): this; /** * Sets the internal size of this Game Object, as used for frame or physics body creation. @@ -25911,168 +33063,36 @@ declare namespace Phaser { */ frame: Phaser.Textures.Frame; - /** - * A boolean flag indicating if this Game Object is being cropped or not. - * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. - * Equally, calling `setCrop` with no arguments will reset the crop and disable it. - */ - isCropped: boolean; - - /** - * Applies a crop to a texture based Game Object, such as a Sprite or Image. - * - * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. - * - * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just - * changes what is shown when rendered. - * - * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. - * - * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left - * half of it, you could call `setCrop(0, 0, 400, 600)`. - * - * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop - * an area of 200x100 when applied to a Game Object that had a scale factor of 2. - * - * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. - * - * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. - * - * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow - * the renderer to skip several internal calculations. - * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. - * @param y The y coordinate to start the crop from. - * @param width The width of the crop rectangle in pixels. - * @param height The height of the crop rectangle in pixels. - */ - setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; - /** * Sets the texture and frame this Game Object will use to render with. * * Textures are referenced by their string-based keys, as stored in the Texture Manager. - * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager, or a Texture instance. * @param frame The name or index of the frame within the Texture. */ - setTexture(key: string, frame?: string | number): this; + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this; /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; - - /** - * The tint value being applied to the top-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintTopLeft: number; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** - * The tint value being applied to the top-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. + * A property indicating that a Game Object has this component. */ - tintTopRight: number; - - /** - * The tint value being applied to the bottom-left vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintBottomLeft: number; - - /** - * The tint value being applied to the bottom-right vertice of the Game Object. - * This value is interpolated from the corner to the center of the Game Object. - * The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple. - */ - tintBottomRight: number; - - /** - * The tint fill mode. - * - * `false` = An additive tint (the default), where vertices colors are blended with the texture. - * `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha. - */ - tintFill: boolean; - - /** - * Clears all tint values associated with this Game Object. - * - * Immediately sets the color values back to 0xffffff and the tint type to 'additive', - * which results in no visible change to the texture. - */ - clearTint(): this; - - /** - * Sets an additive tint on this Game Object. - * - * The tint works by taking the pixel color values from the Game Objects texture, and then - * multiplying it by the color value of the tint. You can provide either one color value, - * in which case the whole Game Object will be tinted in that color. Or you can provide a color - * per corner. The colors are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`. - * @param topLeft The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. - */ - setTint(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - - /** - * Sets a fill-based tint on this Game Object. - * - * Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture - * with those in the tint. You can use this for effects such as making a player flash 'white' - * if hit by something. You can provide either one color value, in which case the whole - * Game Object will be rendered in that color. Or you can provide a color per corner. The colors - * are blended together across the extent of the Game Object. - * - * To modify the tint color once set, either call this method again with new values or use the - * `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight, - * `tintBottomLeft` and `tintBottomRight` to set the corner color values independently. - * - * To remove a tint call `clearTint`. - * - * To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`. - * @param topLeft The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object. Default 0xffffff. - * @param topRight The tint being applied to the top-right of the Game Object. - * @param bottomLeft The tint being applied to the bottom-left of the Game Object. - * @param bottomRight The tint being applied to the bottom-right of the Game Object. - */ - setTintFill(topLeft?: number, topRight?: number, bottomLeft?: number, bottomRight?: number): this; - - /** - * The tint value being applied to the whole of the Game Object. - * This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value. - */ - tint: number; - - /** - * Does this Game Object have a tint applied? - * - * It checks to see if the 4 tint properties are set to the value 0xffffff - * and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted. - */ - readonly isTinted: boolean; + readonly hasTransformComponent: boolean; /** * The x position of this Game Object. @@ -26180,10 +33200,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -26263,73 +33283,6 @@ declare namespace Phaser { */ setVisible(value: boolean): this; - /** - * The Path this PathFollower is following. It can only follow one Path at a time. - */ - path: Phaser.Curves.Path; - - /** - * Should the PathFollower automatically rotate to point in the direction of the Path? - */ - rotateToPath: boolean; - - /** - * Set the Path that this PathFollower should follow. - * - * Optionally accepts {@link Phaser.Types.GameObjects.PathFollower.PathConfig} settings. - * @param path The Path this PathFollower is following. It can only follow one Path at a time. - * @param config Settings for the PathFollower. - */ - setPath(path: Phaser.Curves.Path, config?: number | Phaser.Types.GameObjects.PathFollower.PathConfig | Phaser.Types.Tweens.NumberTweenBuilderConfig): this; - - /** - * Set whether the PathFollower should automatically rotate to point in the direction of the Path. - * @param value Whether the PathFollower should automatically rotate to point in the direction of the Path. - * @param offset Rotation offset in degrees. Default 0. - */ - setRotateToPath(value: boolean, offset?: number): this; - - /** - * Is this PathFollower actively following a Path or not? - * - * To be considered as `isFollowing` it must be currently moving on a Path, and not paused. - */ - isFollowing(): boolean; - - /** - * Starts this PathFollower following its given Path. - * @param config The duration of the follow, or a PathFollower config object. Default {}. - * @param startAt Optional start position of the follow, between 0 and 1. Default 0. - */ - startFollow(config?: number | Phaser.Types.GameObjects.PathFollower.PathConfig | Phaser.Types.Tweens.NumberTweenBuilderConfig, startAt?: number): this; - - /** - * Pauses this PathFollower. It will still continue to render, but it will remain motionless at the - * point on the Path at which you paused it. - */ - pauseFollow(): this; - - /** - * Resumes a previously paused PathFollower. - * - * If the PathFollower was not paused this has no effect. - */ - resumeFollow(): this; - - /** - * Stops this PathFollower from following the path any longer. - * - * This will invoke any 'stop' conditions that may exist on the Path, or for the follower. - */ - stopFollow(): this; - - /** - * Internal update handler that advances this PathFollower along the path. - * - * Called automatically by the Scene step, should not typically be called directly. - */ - pathUpdate(): void; - } /** @@ -26357,7 +33310,7 @@ declare namespace Phaser { * * Point Lights are a WebGL only feature and do not have a Canvas counterpart. */ - class PointLight extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class PointLight extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Point Light belongs. A Point Light can only belong to one Scene at a time. @@ -26365,7 +33318,7 @@ declare namespace Phaser { * @param y The vertical position of this Point Light in the world. * @param color The color of the Point Light, given as a hex value. Default 0xffffff. * @param radius The radius of the Point Light. Default 128. - * @param intensity The intensity, or colr blend, of the Point Light. Default 1. + * @param intensity The intensity, or color blend, of the Point Light. Default 1. * @param attenuation The attenuation of the Point Light. This is the reduction of light from the center point. Default 0.1. */ constructor(scene: Phaser.Scene, x: number, y: number, color?: number, radius?: number, intensity?: number, attenuation?: number); @@ -26426,6 +33379,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -26440,7 +33394,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -26449,6 +33403,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -26462,12 +33417,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -26489,83 +33444,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -26601,7 +33576,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -26611,10 +33586,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -26626,9 +33605,9 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The initial WebGL pipeline of this Game Object. @@ -26642,6 +33621,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -26660,27 +33684,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -26696,27 +33758,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -26724,17 +33782,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -26747,9 +33798,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -26810,6 +33865,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -26916,10 +33976,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -27002,18 +34062,42 @@ declare namespace Phaser { } /** - * A Render Texture. + * A Render Texture is a combination of Dynamic Texture and an Image Game Object, that uses the + * Dynamic Texture to display itself with. * - * A Render Texture is a special texture that allows any number of Game Objects to be drawn to it. You can take many complex objects and - * draw them all to this one texture, which can they be used as the texture for other Game Object's. It's a way to generate dynamic - * textures at run-time that are WebGL friendly and don't invoke expensive GPU uploads. + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. * - * Note that under WebGL a FrameBuffer, which is what the Render Texture uses internally, cannot be anti-aliased. This means - * that when drawing objects such as Shapes to a Render Texture they will appear to be drawn with no aliasing, however this - * is a technical limitation of WebGL. To get around it, create your shape as a texture in an art package, then draw that - * to the Render Texture. + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. + * + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. + * + * In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture + * like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to + * the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, + * the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers + * proxy methods to the features available from a Dynamic Texture. + * + * **When should you use a Render Texture vs. a Dynamic Texture?** + * + * You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, + * or you want to use it across multiple Scenes, because textures are globally stored. + * + * You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is + * instead going to be used for something like a mask or shader. + * + * You should use a Render Texture if you need to display the texture in-game on a single Game Object, + * as it provides the convenience of wrapping an Image and Dynamic Texture together for you. + * + * Under WebGL1, a FrameBuffer, which is what this Dynamic Texture uses internally, cannot be anti-aliased. + * This means that when drawing objects such as Shapes or Graphics instances to this texture, they may appear + * to be drawn with no aliasing around the edges. This is a technical limitation of WebGL1. To get around it, + * create your shape as a texture in an art package, then draw that to this texture. */ - class RenderTexture extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.ComputedSize, Phaser.GameObjects.Components.Crop, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class RenderTexture extends Phaser.GameObjects.Image { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. @@ -27021,74 +34105,31 @@ declare namespace Phaser { * @param y The vertical position of this Game Object in the world. Default 0. * @param width The width of the Render Texture. Default 32. * @param height The height of the Render Texture. Default 32. - * @param key The texture key to make the RenderTexture from. - * @param frame The frame to make the RenderTexture from. - */ - constructor(scene: Phaser.Scene, x?: number, y?: number, width?: number, height?: number, key?: string, frame?: string); - - /** - * A reference to either the Canvas or WebGL Renderer that the Game instance is using. - */ - renderer: Phaser.Renderer.Canvas.CanvasRenderer | Phaser.Renderer.WebGL.WebGLRenderer; - - /** - * A reference to the Texture Manager. - */ - textureManager: Phaser.Textures.TextureManager; - - /** - * The tint of the Render Texture when rendered. - */ - globalTint: number; - - /** - * The alpha of the Render Texture when rendered. - */ - globalAlpha: number; - - /** - * The HTML Canvas Element that the Render Texture is drawing to when using the Canvas Renderer. */ - canvas: HTMLCanvasElement; + constructor(scene: Phaser.Scene, x?: number, y?: number, width?: number, height?: number); /** - * Is this Render Texture dirty or not? If not it won't spend time clearing or filling itself. - */ - dirty: boolean; - - /** - * The Texture corresponding to this Render Texture. - */ - texture: Phaser.Textures.Texture; - - /** - * The Frame corresponding to this Render Texture. - */ - frame: Phaser.Textures.Frame; - - /** - * A reference to the Rendering Context belonging to the Canvas Element this Render Texture is drawing to. - */ - context: CanvasRenderingContext2D; - - /** - * An internal Camera that can be used to move around the Render Texture. - * Control it just like you would any Scene Camera. The difference is that it only impacts the placement of what - * is drawn to the Render Texture. You can scroll, zoom and rotate this Camera. + * An internal Camera that can be used to move around this Render Texture. + * + * Control it just like you would any Scene Camera. The difference is that it only impacts + * the placement of Game Objects that you then draw to this texture. + * + * You can scroll, zoom and rotate this Camera. + * + * This property is a reference to `RenderTexture.texture.camera`. */ camera: Phaser.Cameras.Scene2D.BaseCamera; /** - * The Render Target that belongs to this Render Texture. + * Sets the internal size of this Render Texture, as used for frame or physics body creation. * - * A Render Target encapsulates a framebuffer and texture for the WebGL Renderer. + * 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. * - * This property remains `null` under Canvas. - */ - renderTarget: Phaser.Renderer.WebGL.RenderTarget; - - /** - * Sets the size of this Game Object. + * 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. * @param width The width of this Game Object. * @param height The height of this Game Object. */ @@ -27097,11 +34138,6 @@ declare namespace Phaser { /** * Resizes the Render Texture to the new dimensions given. * - * If Render Texture was created from specific frame, only the size of the frame will be changed. The size of the source - * texture will not change. - * - * If Render Texture was not created from specific frame, the following will happen: - * * In WebGL it will destroy and then re-create the frame buffer being used by the Render Texture. * In Canvas it will resize the underlying canvas element. * @@ -27113,18 +34149,6 @@ declare namespace Phaser { */ resize(width: number, height?: number): this; - /** - * Set the tint to use when rendering this Render Texture. - * @param tint The tint value. - */ - setGlobalTint(tint: number): this; - - /** - * Set the alpha to use when rendering this Render Texture. - * @param alpha The alpha value. - */ - setGlobalAlpha(alpha: number): this; - /** * Stores a copy of this Render Texture in the Texture Manager using the given key. * @@ -27154,27 +34178,51 @@ declare namespace Phaser { * using it first, before destroying this Render Texture. * @param key The unique key to store the texture as within the global Texture Manager. */ - saveTexture(key: string): Phaser.Textures.Texture; + saveTexture(key: string): Phaser.Textures.DynamicTexture; /** - * Fills the Render Texture with the given color. - * @param rgb The color to fill the Render Texture with. + * Fills this Render Texture with the given color. + * + * By default it will fill the entire texture, however you can set it to fill a specific + * rectangular area by using the x, y, width and height arguments. + * + * The color should be given in hex format, i.e. 0xff0000 for red, 0x00ff00 for green, etc. + * @param rgb The color to fill this Render Texture with, such as 0xff0000 for red. * @param alpha The alpha value used by the fill. Default 1. * @param x The left coordinate of the fill rectangle. Default 0. * @param y The top coordinate of the fill rectangle. Default 0. - * @param width The width of the fill rectangle. Default this.frame.cutWidth. - * @param height The height of the fill rectangle. Default this.frame.cutHeight. + * @param width The width of the fill rectangle. Default this.width. + * @param height The height of the fill rectangle. Default this.height. */ fill(rgb: number, alpha?: number, x?: number, y?: number, width?: number, height?: number): this; /** - * Clears the Render Texture. + * Fully clears this Render Texture, erasing everything from it and resetting it back to + * a blank, transparent, texture. */ clear(): this; + /** + * Takes the given texture key and frame and then stamps it at the given + * x and y coordinates. You can use the optional 'config' argument to provide + * lots more options about how the stamp is applied, including the alpha, + * tint, angle, scale and origin. + * + * By default, the frame will stamp on the x/y coordinates based on its center. + * + * If you wish to stamp from the top-left, set the config `originX` and + * `originY` properties both to zero. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param x The x position to draw the frame at. Default 0. + * @param y The y position to draw the frame at. Default 0. + * @param config The stamp configuration object, allowing you to set the alpha, tint, angle, scale and origin of the stamp. + */ + stamp(key: string, frame?: string | number, x?: number, y?: number, config?: Phaser.Types.Textures.StampConfig): this; + /** * Draws the given object, or an array of objects, to this Render Texture using a blend mode of ERASE. - * This has the effect of erasing any filled pixels in the objects from this Render Texture. + * This has the effect of erasing any filled pixels present in the objects from this texture. * * It can accept any of the following: * @@ -27182,10 +34230,10 @@ declare namespace Phaser { * * Tilemap Layers. * * A Group. The contents of which will be iterated and drawn in turn. * * A Container. The contents of which will be iterated fully, and drawn in turn. - * * A Scene's Display List. Pass in `Scene.children` to draw the whole list. - * * Another Render Texture. + * * A Scene Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture, or a Render Texture. * * A Texture Frame instance. - * * A string. This is used to look-up a texture from the Texture Manager. + * * A string. This is used to look-up the texture from the Texture Manager. * * Note: You cannot erase a Render Texture from itself. * @@ -27209,9 +34257,9 @@ declare namespace Phaser { * after the entries have been iterated. So if you've a bunch of objects to draw, * try and pass them in an array in one single call, rather than making lots of * separate calls. - * @param entries Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these. - * @param x The x position to draw the Frame at, or the offset applied to the object. - * @param y The y position to draw the Frame at, or the offset applied to the object. + * @param entries Any renderable Game Object, or Group, Container, Display List, Render Texture, Texture Frame, or an array of any of these. + * @param x The x position to draw the Frame at, or the offset applied to the object. Default 0. + * @param y The y position to draw the Frame at, or the offset applied to the object. Default 0. */ erase(entries: any, x?: number, y?: number): this; @@ -27224,12 +34272,15 @@ declare namespace Phaser { * * Tilemap Layers. * * A Group. The contents of which will be iterated and drawn in turn. * * A Container. The contents of which will be iterated fully, and drawn in turn. - * * A Scene's Display List. Pass in `Scene.children` to draw the whole list. - * * Another Render Texture. + * * A Scene Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture, or a Render Texture. * * A Texture Frame instance. - * * A string. This is used to look-up a texture from the Texture Manager. + * * A string. This is used to look-up the texture from the Texture Manager. * - * Note: You cannot draw a Render Texture to itself. + * Note 1: You cannot draw a Render Texture to itself. + * + * Note 2: For Game Objects that have Post FX Pipelines, the pipeline _cannot_ be + * used when drawn to this texture. * * If passing in a Group or Container it will only draw children that return `true` * when their `willRender()` method is called. I.e. a Container with 10 children, @@ -27256,10 +34307,10 @@ declare namespace Phaser { * try and pass them in an array in one single call, rather than making lots of * separate calls. * @param entries Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these. - * @param x The x position to draw the Frame at, or the offset applied to the object. - * @param y The y position to draw the Frame at, or the offset applied to the object. - * @param alpha The alpha value. Only used for Texture Frames and if not specified defaults to the `globalAlpha` property. Game Objects use their own current alpha value. - * @param tint WebGL only. The tint color value. Only used for Texture Frames and if not specified defaults to the `globalTint` property. Game Objects use their own current tint value. + * @param x The x position to draw the Frame at, or the offset applied to the object. Default 0. + * @param y The y position to draw the Frame at, or the offset applied to the object. Default 0. + * @param alpha The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. Default 1. + * @param tint The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. Default 0xffffff. */ draw(entries: any, x?: number, y?: number, alpha?: number, tint?: number): this; @@ -27281,23 +34332,53 @@ declare namespace Phaser { * * If you need to draw a Sprite to this Render Texture, use the `draw` method instead. * @param key The key of the texture to be used, as stored in the Texture Manager. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. * @param x The x position to draw the frame at. Default 0. * @param y The y position to draw the frame at. Default 0. - * @param alpha The alpha to use. If not specified it uses the `globalAlpha` property. - * @param tint WebGL only. The tint color to use. If not specified it uses the `globalTint` property. + * @param alpha The alpha value. Only used when drawing Texture Frames to this texture. Default 1. + * @param tint The tint color value. Only used when drawing Texture Frames to this texture. WebGL only. Default 0xffffff. */ drawFrame(key: string, frame?: string | number, x?: number, y?: number, alpha?: number, tint?: number): this; + /** + * Takes the given Texture Frame and draws it to this Render Texture as a fill pattern, + * i.e. in a grid-layout based on the frame dimensions. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * + * You can optionally provide a position, width, height, alpha and tint value to apply to + * the frames before they are drawn. The position controls the top-left where the repeating + * fill will start from. The width and height control the size of the filled area. + * + * The position can be negative if required, but the dimensions cannot. + * + * Calling this method will cause a batch flush by default. Use the `skipBatch` argument + * to disable this if this call is part of a larger batch draw. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param x The x position to start drawing the frames from (can be negative to offset). Default 0. + * @param y The y position to start drawing the frames from (can be negative to offset). Default 0. + * @param width The width of the area to repeat the frame within. Defaults to the width of this Dynamic Texture. Default this.width. + * @param height The height of the area to repeat the frame within. Defaults to the height of this Dynamic Texture. Default this.height. + * @param alpha The alpha to use. Defaults to 1, no alpha. Default 1. + * @param tint WebGL only. The tint color to use. Leave as undefined, or 0xffffff to have no tint. Default 0xffffff. + * @param skipBatch Skip beginning and ending a batch with this call. Use if this is part of a bigger batched draw. Default false. + */ + repeat(key: string, frame?: string | number, x?: number, y?: number, width?: number, height?: number, alpha?: number, tint?: number, skipBatch?: boolean): this; + /** * Use this method if you need to batch draw a large number of Game Objects to - * this Render Texture in a single go, or on a frequent basis. + * this Render Texture in a single pass, or on a frequent basis. This is especially + * useful under WebGL, however, if your game is using Canvas only, it will not make + * any speed difference in that situation. * - * This method starts the beginning of a batched draw. + * This method starts the beginning of a batched draw, unless one is already open. * - * It is faster than calling `draw`, but you must be very careful to manage the - * flow of code and remember to call `endDraw()`. If you don't need to draw large - * numbers of objects it's much safer and easier to use the `draw` method instead. + * Batched drawing is faster than calling `draw` in loop, but you must be careful + * to manage the flow of code and remember to call `endDraw()` when you're finished. + * + * If you don't need to draw large numbers of objects it's much safer and easier + * to use the `draw` method instead. * * The flow should be: * @@ -27316,7 +34397,10 @@ declare namespace Phaser { * * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you * have started a batch. Also, be very careful not to destroy this Render Texture while the - * batch is still open, or call `beginDraw` again. + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is + * currently open, or not. */ beginDraw(): this; @@ -27324,10 +34408,10 @@ declare namespace Phaser { * Use this method if you have already called `beginDraw` and need to batch * draw a large number of objects to this Render Texture. * - * This method batches the drawing of the given objects to this Render Texture, - * without causing a bind or batch flush. + * This method batches the drawing of the given objects to this texture, + * without causing a WebGL bind or batch flush for each one. * - * It is faster than calling `draw`, but you must be very careful to manage the + * It is faster than calling `draw`, but you must be careful to manage the * flow of code and remember to call `endDraw()`. If you don't need to draw large * numbers of objects it's much safer and easier to use the `draw` method instead. * @@ -27348,18 +34432,19 @@ declare namespace Phaser { * * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you * have started a batch. Also, be very careful not to destroy this Render Texture while the - * batch is still open, or call `beginDraw` again. + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. * - * Draws the given object, or an array of objects, to this Render Texture. + * You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is + * currently open, or not. * - * It can accept any of the following: + * This method can accept any of the following: * * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. * * Tilemap Layers. * * A Group. The contents of which will be iterated and drawn in turn. * * A Container. The contents of which will be iterated fully, and drawn in turn. * * A Scene's Display List. Pass in `Scene.children` to draw the whole list. - * * Another Render Texture. + * * Another Dynamic Texture or Render Texture. * * A Texture Frame instance. * * A string. This is used to look-up a texture from the Texture Manager. * @@ -27383,11 +34468,11 @@ declare namespace Phaser { * * The `alpha` and `tint` values are only used by Texture Frames. * Game Objects use their own alpha and tint values when being drawn. - * @param entries Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these. - * @param x The x position to draw the Frame at, or the offset applied to the object. - * @param y The y position to draw the Frame at, or the offset applied to the object. - * @param alpha The alpha value. Only used for Texture Frames and if not specified defaults to the `globalAlpha` property. Game Objects use their own current alpha value. - * @param tint WebGL only. The tint color value. Only used for Texture Frames and if not specified defaults to the `globalTint` property. Game Objects use their own current tint value. + * @param entries Any renderable Game Object, or Group, Container, Display List, other Dynamic or Texture, Texture Frame or an array of any of these. + * @param x The x position to draw the Frame at, or the offset applied to the object. Default 0. + * @param y The y position to draw the Frame at, or the offset applied to the object. Default 0. + * @param alpha The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. Default 1. + * @param tint The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. Default 0xffffff. */ batchDraw(entries: any, x?: number, y?: number, alpha?: number, tint?: number): this; @@ -27396,9 +34481,9 @@ declare namespace Phaser { * draw a large number of texture frames to this Render Texture. * * This method batches the drawing of the given frames to this Render Texture, - * without causing a bind or batch flush. + * without causing a WebGL bind or batch flush for each one. * - * It is faster than calling `drawFrame`, but you must be very careful to manage the + * It is faster than calling `drawFrame`, but you must be careful to manage the * flow of code and remember to call `endDraw()`. If you don't need to draw large * numbers of frames it's much safer and easier to use the `drawFrame` method instead. * @@ -27419,41 +34504,37 @@ declare namespace Phaser { * * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you * have started a batch. Also, be very careful not to destroy this Render Texture while the - * batch is still open, or call `beginDraw` again. + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. * - * Draws the Texture Frame to the Render Texture at the given position. + * You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is + * currently open, or not. * * Textures are referenced by their string-based keys, as stored in the Texture Manager. * - * ```javascript - * var rt = this.add.renderTexture(0, 0, 800, 600); - * rt.drawFrame(key, frame); - * ``` - * * You can optionally provide a position, alpha and tint value to apply to the frame * before it is drawn. - * - * Calling this method will cause a batch flush, so if you've got a stack of things to draw - * in a tight loop, try using the `draw` method instead. - * - * If you need to draw a Sprite to this Render Texture, use the `draw` method instead. * @param key The key of the texture to be used, as stored in the Texture Manager. * @param frame The name or index of the frame within the Texture. * @param x The x position to draw the frame at. Default 0. * @param y The y position to draw the frame at. Default 0. - * @param alpha The alpha to use. If not specified it uses the `globalAlpha` property. - * @param tint WebGL only. The tint color to use. If not specified it uses the `globalTint` property. + * @param alpha The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. Default 1. + * @param tint The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. Default 0xffffff. */ batchDrawFrame(key: string, frame?: string | number, x?: number, y?: number, alpha?: number, tint?: number): this; /** * Use this method to finish batch drawing to this Render Texture. * - * Never call this method without first calling `beginDraw`. + * Doing so will stop the WebGL Renderer from capturing draws and then blit the + * framebuffer to the Render Target owned by this texture. * - * It is faster than calling `draw`, but you must be very careful to manage the - * flow of code and remember to call `endDraw()`. If you don't need to draw large - * numbers of objects it's much safer and easier to use the `draw` method instead. + * Calling this method without first calling `beginDraw` will have no effect. + * + * Batch drawing is faster than calling `draw`, but you must be careful to manage the + * flow of code and remember to call `endDraw()` when you're finished. + * + * If you don't need to draw large numbers of objects it's much safer and easier + * to use the `draw` method instead. * * The flow should be: * @@ -27472,7 +34553,10 @@ declare namespace Phaser { * * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you * have started a batch. Also, be very careful not to destroy this Render Texture while the - * batch is still open, or call `beginDraw` again. + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is + * currently open, or not. * @param erase Draws all objects in this batch using a blend mode of ERASE. This has the effect of erasing any filled pixels in the objects being drawn. Default false. */ endDraw(erase?: boolean): this; @@ -27480,14 +34564,17 @@ declare namespace Phaser { /** * Takes a snapshot of the given area of this Render Texture. * - * The snapshot is taken immediately. + * The snapshot is taken immediately, but the results are returned via the given callback. + * + * To capture the whole Render Texture see the `snapshot` method. + * To capture just a specific pixel, see the `snapshotPixel` method. * - * To capture the whole Render Texture see the `snapshot` method. To capture a specific pixel, see `snapshotPixel`. + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer + * into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally + * creating an Image object from it, which is the image returned to the callback provided. * - * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. - * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, - * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, - * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * All in all, this is a computationally expensive and blocking process, which gets more expensive + * the larger the resolution this Render Texture has, so please be careful how you employ this in your game. * @param x The x coordinate to grab from. * @param y The y coordinate to grab from. * @param width The width of the area to grab. @@ -27501,14 +34588,17 @@ declare namespace Phaser { /** * Takes a snapshot of the whole of this Render Texture. * - * The snapshot is taken immediately. + * The snapshot is taken immediately, but the results are returned via the given callback. * - * To capture just a portion of the Render Texture see the `snapshotArea` method. To capture a specific pixel, see `snapshotPixel`. + * To capture a portion of this Render Texture see the `snapshotArea` method. + * To capture just a specific pixel, see the `snapshotPixel` method. * - * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView. - * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, - * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, - * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer + * into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally + * creating an Image object from it, which is the image returned to the callback provided. + * + * All in all, this is a computationally expensive and blocking process, which gets more expensive + * the larger the resolution this Render Texture has, so please be careful how you employ this in your game. * @param callback The Function to invoke after the snapshot image is created. * @param type The format of the image to create, usually `image/png` or `image/jpeg`. Default 'image/png'. * @param encoderOptions The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. Default 0.92. @@ -27518,13 +34608,14 @@ declare namespace Phaser { /** * Takes a snapshot of the given pixel from this Render Texture. * - * The snapshot is taken immediately. + * The snapshot is taken immediately, but the results are returned via the given callback. * - * To capture the whole Render Texture see the `snapshot` method. To capture a specific portion, see `snapshotArea`. + * To capture the whole Render Texture see the `snapshot` method. + * To capture a portion of this Render Texture see the `snapshotArea` method. * - * Unlike the other two snapshot methods, this one will send your callback a `Color` object containing the color data for - * the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute, - * using less memory, than the other snapshot methods. + * Unlike the two other snapshot methods, this one will send your callback a `Color` object + * containing the color data for the requested pixel. It doesn't need to create an internal + * Canvas or Image object, so is a lot faster to execute, using less memory than the other snapshot methods. * @param x The x coordinate of the pixel to get. * @param y The y coordinate of the pixel to get. * @param callback The Function to invoke after the snapshot pixel data is extracted. @@ -27594,6 +34685,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -27608,7 +34700,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -27617,6 +34709,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -27630,93 +34723,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. - */ - setBlendMode(value: string | Phaser.BlendModes): this; - - /** - * The native (un-scaled) width of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayWidth` property. - */ - width: number; - - /** - * The native (un-scaled) height of this Game Object. - * - * Changing this value will not change the size that the Game Object is rendered in-game. - * For that you need to either set the scale of the Game Object (`setScale`) or use - * the `displayHeight` property. - */ - height: number; - - /** - * The displayed width of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - */ - displayWidth: number; - - /** - * The displayed height of this Game Object. - * - * This value takes into account the scale factor. - * - * Setting this value will adjust the Game Object's scale property. - */ - displayHeight: number; - - /** - * Sets the display size of this Game Object. - * - * Calling this will adjust the scale. - * @param width The width of this Game Object. - * @param height The height of this Game Object. - */ - setDisplaySize(width: number, height: number): this; - - /** - * A boolean flag indicating if this Game Object is being cropped or not. - * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. - * Equally, calling `setCrop` with no arguments will reset the crop and disable it. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - isCropped: boolean; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * Applies a crop to a texture based Game Object, such as a Sprite or Image. - * - * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. - * - * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just - * changes what is shown when rendered. - * - * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. - * - * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left - * half of it, you could call `setCrop(0, 0, 400, 600)`. - * - * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop - * an area of 200x100 when applied to a Game Object that had a scale factor of 2. - * - * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. - * - * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. - * - * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow - * the renderer to skip several internal calculations. - * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. - * @param y The y coordinate to start the crop from. - * @param width The width of the crop rectangle in pixels. - * @param height The height of the crop rectangle in pixels. - */ - setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; - - /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -27738,7 +34750,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -27808,77 +34820,97 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -27914,7 +34946,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -27924,10 +34956,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -27939,25 +34975,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -28013,6 +35051,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -28031,27 +35114,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -28067,27 +35188,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -28095,17 +35212,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -28118,9 +35228,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -28181,6 +35295,137 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * The native (un-scaled) width of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayWidth` property. + */ + width: number; + + /** + * The native (un-scaled) height of this Game Object. + * + * Changing this value will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or use + * the `displayHeight` property. + */ + height: number; + + /** + * The displayed width of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayWidth: number; + + /** + * The displayed height of this Game Object. + * + * This value takes into account the scale factor. + * + * Setting this value will adjust the Game Object's scale property. + */ + displayHeight: number; + + /** + * Sets the size of this Game Object to be that of the given Frame. + * + * This will not change the size that the Game Object is rendered in-game. + * For that you need to either set the scale of the Game Object (`setScale`) or call the + * `setDisplaySize` method, which is the same thing as changing the scale but allows you + * to do so by giving pixel values. + * + * If you have enabled this Game Object for input, changing the size will _not_ change the + * size of the hit area. To do this you should adjust the `input.hitArea` object directly. + * @param frame The frame to base the size of this Game Object on. + */ + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; + + /** + * Sets the display size of this Game Object. + * + * Calling this will adjust the scale. + * @param width The width of this Game Object. + * @param height The height of this Game Object. + */ + setDisplaySize(width: number, height: number): this; + + /** + * The Texture this Game Object is using to render with. + */ + texture: Phaser.Textures.Texture | Phaser.Textures.CanvasTexture; + + /** + * The Texture Frame this Game Object is using to render with. + */ + frame: Phaser.Textures.Frame; + + /** + * A boolean flag indicating if this Game Object is being cropped or not. + * You can toggle this at any time after `setCrop` has been called, to turn cropping on or off. + * Equally, calling `setCrop` with no arguments will reset the crop and disable it. + */ + isCropped: boolean; + + /** + * Applies a crop to a texture based Game Object, such as a Sprite or Image. + * + * The crop is a rectangle that limits the area of the texture frame that is visible during rendering. + * + * Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just + * changes what is shown when rendered. + * + * The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left. + * + * Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left + * half of it, you could call `setCrop(0, 0, 400, 600)`. + * + * It is also scaled to match the Game Object scale automatically. Therefore a crop rect of 100x50 would crop + * an area of 200x100 when applied to a Game Object that had a scale factor of 2. + * + * You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument. + * + * Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`. + * + * You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow + * the renderer to skip several internal calculations. + * @param x The x coordinate to start the crop from. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored. + * @param y The y coordinate to start the crop from. + * @param width The width of the crop rectangle in pixels. + * @param height The height of the crop rectangle in pixels. + */ + setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; + + /** + * Sets the texture and frame this Game Object will use to render with. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. + */ + setTexture(key: string, frame?: string | number): this; + + /** + * Sets the frame this Game Object will use to render with. + * + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. + * + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. + * + * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * + * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. + * @param frame The name or index of the frame within the Texture, or a Frame instance. + * @param updateSize Should this call adjust the size of the Game Object? Default true. + * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. + */ + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; + /** * The tint value being applied to the top-left vertice of the Game Object. * This value is interpolated from the corner to the center of the Game Object. @@ -28284,6 +35529,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -28390,10 +35640,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -28480,14 +35730,15 @@ declare namespace Phaser { * * The Rope object is WebGL only and does not have a Canvas counterpart. * - * A Rope is a special kind of Game Object that has a texture that repeats along its entire length. + * A Rope is a special kind of Game Object that has a texture is stretched along its entire length. + * * Unlike a Sprite, it isn't restricted to using just a quad and can have as many vertices as you define * when creating it. The vertices can be arranged in a horizontal or vertical strip and have their own * color and alpha values as well. * * A Ropes origin is always 0.5 x 0.5 and cannot be changed. */ - class Rope extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible, Phaser.GameObjects.Components.ScrollFactor { + class Rope extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible, Phaser.GameObjects.Components.ScrollFactor { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. @@ -28848,6 +36099,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -28862,7 +36114,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -28871,6 +36123,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -28884,12 +36137,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -28911,7 +36164,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -28991,7 +36244,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -29001,10 +36254,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -29016,9 +36273,9 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The initial WebGL pipeline of this Game Object. @@ -29032,6 +36289,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -29050,27 +36352,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -29086,27 +36426,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -29114,17 +36450,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -29137,9 +36466,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The native (un-scaled) width of this Game Object. @@ -29189,7 +36522,7 @@ declare namespace Phaser { * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * @param frame The frame to base the size of this Game Object on. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; /** * Sets the internal size of this Game Object, as used for frame or physics body creation. @@ -29237,17 +36570,24 @@ declare namespace Phaser { /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; + + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; /** * The x position of this Game Object. @@ -29355,10 +36695,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -29630,13 +36970,13 @@ declare namespace Phaser { * A reference to the GL Frame Buffer this Shader is drawing to. * This property is only set if you have called `Shader.setRenderToTexture`. */ - framebuffer: WebGLFramebuffer; + framebuffer: WebGLFramebuffer | null; /** * A reference to the WebGLTexture this Shader is rendering to. * This property is only set if you have called `Shader.setRenderToTexture`. */ - glTexture: WebGLTexture; + glTexture: WebGLTexture | null; /** * A flag that indicates if this Shader has been set to render to a texture instead of the display list. @@ -29917,7 +37257,7 @@ declare namespace Phaser { setDisplaySize(width: number, height: number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -29939,83 +37279,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -30051,7 +37411,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -30061,10 +37421,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -30076,25 +37440,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -30197,6 +37563,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -30303,10 +37674,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -30505,6 +37876,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -30519,7 +37891,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -30528,6 +37900,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -30541,12 +37914,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -30568,83 +37941,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -30680,7 +38073,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -30690,10 +38083,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -30705,25 +38102,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -30779,6 +38178,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -30797,27 +38241,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -30833,27 +38315,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -30861,17 +38339,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -30884,9 +38355,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -30947,6 +38422,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -31053,10 +38533,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -31208,6 +38688,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -31222,7 +38703,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -31231,6 +38712,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -31244,12 +38726,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -31271,83 +38753,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -31383,7 +38885,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -31393,10 +38895,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -31408,25 +38914,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -31482,6 +38990,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -31500,27 +39053,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -31536,27 +39127,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -31564,17 +39151,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -31587,9 +39167,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -31650,6 +39234,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -31756,10 +39345,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -31921,6 +39510,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -31935,7 +39525,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -31944,6 +39534,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -31957,12 +39548,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -31984,83 +39575,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -32096,7 +39707,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -32106,10 +39717,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -32121,25 +39736,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -32195,6 +39812,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -32213,27 +39875,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -32249,27 +39949,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -32277,17 +39973,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -32300,9 +39989,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -32363,6 +40056,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -32469,10 +40167,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -32704,6 +40402,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -32718,7 +40417,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -32727,6 +40426,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -32740,12 +40440,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -32767,83 +40467,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -32879,7 +40599,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -32889,10 +40609,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -32904,25 +40628,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -32978,6 +40704,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -32996,27 +40767,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -33032,27 +40841,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -33060,17 +40865,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -33083,9 +40881,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -33146,6 +40948,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -33252,10 +41059,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -33454,6 +41261,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -33468,7 +41276,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -33477,6 +41285,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -33490,12 +41299,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -33517,83 +41326,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -33629,7 +41458,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -33639,10 +41468,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -33654,25 +41487,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -33728,6 +41563,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -33746,27 +41626,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -33782,27 +41700,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -33810,17 +41724,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -33833,9 +41740,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -33896,6 +41807,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -34002,10 +41918,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -34218,6 +42134,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -34232,7 +42149,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -34241,6 +42158,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -34254,12 +42172,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -34281,83 +42199,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -34393,7 +42331,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -34403,10 +42341,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -34418,25 +42360,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -34492,6 +42436,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -34510,27 +42499,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -34546,27 +42573,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -34574,17 +42597,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -34597,9 +42613,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -34660,6 +42680,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -34766,10 +42791,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -34938,6 +42963,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -34952,7 +42978,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -34961,6 +42987,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -34974,12 +43001,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -35001,83 +43028,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -35113,7 +43160,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -35123,10 +43170,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -35138,25 +43189,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -35212,6 +43265,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -35230,27 +43328,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -35266,27 +43402,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -35294,17 +43426,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -35317,9 +43442,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -35380,6 +43509,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -35486,10 +43620,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -35611,6 +43745,25 @@ declare namespace Phaser { */ smooth(iterations?: number): this; + /** + * Sets this Polygon to the given points. + * + * 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 objects: `[new Phaser.Point(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], ...]` + * + * Calling this method will reset the size (width, height) and display origin of this Shape. + * + * It also runs both GetAABB and EarCut on the given points, so please be careful not to do this + * at a high frequency, or with too many points. + * @param points Points defining the perimeter of this polygon. Please check function description above for the different supported formats. + */ + setTo(points?: string | number[] | Phaser.Types.Math.Vector2Like[]): this; + /** * Clears all alpha values associated with this Game Object. * @@ -35639,6 +43792,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -35653,7 +43807,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -35662,6 +43816,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -35675,12 +43830,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -35702,83 +43857,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -35814,7 +43989,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -35824,10 +43999,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -35839,25 +44018,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -35913,6 +44094,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -35931,27 +44157,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -35967,27 +44231,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -35995,17 +44255,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -36018,9 +44271,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -36081,6 +44338,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -36187,10 +44449,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -36296,14 +44558,9 @@ declare namespace Phaser { constructor(scene: Phaser.Scene, x: number, y: number, width?: number, height?: number, fillColor?: number, fillAlpha?: number); /** - * Sets the internal size of this Game Object, as used for frame or physics body creation. + * Sets the internal size of this Rectangle, 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 + * If you have assigned a custom input hit area for this Rectangle, changing the Rectangle size will _not_ change the * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * @param width The width of this Game Object. * @param height The height of this Game Object. @@ -36338,6 +44595,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -36352,7 +44610,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -36361,6 +44619,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -36374,12 +44633,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -36401,83 +44660,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -36513,7 +44792,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -36523,10 +44802,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -36538,25 +44821,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -36612,6 +44897,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -36630,27 +44960,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -36666,27 +45034,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -36694,17 +45058,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -36717,9 +45074,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -36780,6 +45141,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -36886,10 +45252,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -36975,7 +45341,7 @@ declare namespace Phaser { * The Shape Game Object is a base class for the various different shapes, such as the Arc, Star or Polygon. * You cannot add a Shape directly to your Scene, it is meant as a base for your own custom Shape classes. */ - class Shape extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class Shape extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.AlphaSingle, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. @@ -37157,6 +45523,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -37171,7 +45538,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -37180,6 +45547,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -37193,12 +45561,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -37220,83 +45588,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -37332,7 +45720,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -37342,10 +45730,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -37357,25 +45749,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -37431,6 +45825,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -37449,27 +45888,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -37485,27 +45962,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -37513,17 +45986,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -37536,9 +46002,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -37599,6 +46069,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -37705,10 +46180,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -37884,6 +46359,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -37898,7 +46374,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -37907,6 +46383,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -37920,12 +46397,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -37947,83 +46424,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -38059,7 +46556,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -38069,10 +46566,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -38084,25 +46585,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -38158,6 +46661,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -38176,27 +46724,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -38212,27 +46798,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -38240,17 +46822,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -38263,9 +46838,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -38326,6 +46905,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -38432,10 +47016,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -38585,6 +47169,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -38599,7 +47184,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -38608,6 +47193,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -38621,12 +47207,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -38648,83 +47234,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -38760,7 +47366,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -38770,10 +47376,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -38785,25 +47395,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -38859,6 +47471,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -38877,27 +47534,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -38913,27 +47608,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -38941,17 +47632,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -38964,9 +47648,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -39027,6 +47715,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -39133,10 +47826,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -39229,7 +47922,7 @@ declare namespace Phaser { * As such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation * Component. If you do not require animation then you can safely use Images to replace Sprites in all cases. */ - class Sprite extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.TextureCrop, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class Sprite extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.TextureCrop, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. @@ -39424,7 +48117,7 @@ declare namespace Phaser { * search the global Animation Manager and look for it there. * @param key The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them. */ - chain(key: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig | string[] | Phaser.Animations.Animation[] | Phaser.Types.Animations.PlayAnimationConfig[]): this; + chain(key?: string | Phaser.Animations.Animation | Phaser.Types.Animations.PlayAnimationConfig | string[] | Phaser.Animations.Animation[] | Phaser.Types.Animations.PlayAnimationConfig[]): this; /** * Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` events. @@ -39538,6 +48231,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -39552,7 +48246,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -39561,6 +48255,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -39574,12 +48269,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -39601,7 +48296,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -39671,77 +48366,97 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -39777,7 +48492,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -39787,10 +48502,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -39802,25 +48521,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -39876,6 +48597,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -39894,27 +48660,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -39930,27 +48734,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -39958,17 +48758,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -39981,9 +48774,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -40092,7 +48889,7 @@ declare namespace Phaser { * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * @param frame The frame to base the size of this Game Object on. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; /** * Sets the internal size of this Game Object, as used for frame or physics body creation. @@ -40176,17 +48973,19 @@ declare namespace Phaser { /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** * The tint value being applied to the top-left vertice of the Game Object. @@ -40291,6 +49090,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -40397,10 +49201,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -40520,7 +49324,7 @@ declare namespace Phaser { * ``` * * You can only display fonts that are currently loaded and available to the browser: therefore fonts must - * be pre-loaded. Phaser does not do ths for you, so you will require the use of a 3rd party font loader, + * be pre-loaded. Phaser does not do this for you, so you will require the use of a 3rd party font loader, * or have the fonts ready available in the CSS on the page in which your Phaser game resides. * * See {@link http://www.jordanm.co.uk/tinytype this compatibility table} for the available default fonts @@ -40532,7 +49336,7 @@ declare namespace Phaser { * Text objects in your game. If you run into performance issues you would be better off using Bitmap Text * instead, as it benefits from batching and avoids expensive Canvas API calls. */ - class Text extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.ComputedSize, Phaser.GameObjects.Components.Crop, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class Text extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.ComputedSize, Phaser.GameObjects.Components.Crop, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. @@ -40645,7 +49449,7 @@ declare namespace Phaser { * array, where each element of the array corresponds to a wrapped line of text. * @param text The text for which the wrapping will be calculated. If unspecified, the Text objects current text will be used. */ - getWrappedText(text: string): string[]; + getWrappedText(text?: string): string[]; /** * Set the text to display. @@ -40655,6 +49459,15 @@ declare namespace Phaser { */ setText(value: string | string[]): this; + /** + * Appends the given text to the content already being displayed by this Text object. + * + * An array of strings will be joined with `\n` line breaks. + * @param value The string, or array of strings, to be appended to the existing content of this Text object. + * @param addCR Insert a carriage-return before the string value. Default true. + */ + appendText(value: string | string[], addCR?: boolean): this; + /** * Set the text style. * @param style The style settings to set. @@ -40707,10 +49520,10 @@ declare namespace Phaser { setFontFamily(family: string): this; /** - * Set the font size. + * Set the font size. Can be a string with a valid CSS unit, i.e. `16px`, or a number. * @param size The font size. */ - setFontSize(size: number): this; + setFontSize(size: string | number): this; /** * Set the font style. @@ -40806,7 +49619,7 @@ declare namespace Phaser { * algorithm. If true, spaces are collapsed and whitespace is trimmed from lines. If false, * spaces and whitespace are left as is. Default false. */ - setWordWrapWidth(width: number, useAdvancedWrap?: boolean): this; + setWordWrapWidth(width: number | undefined, useAdvancedWrap?: boolean): this; /** * Set a custom callback for wrapping lines. Pass in null to remove wrapping by callback. @@ -40953,6 +49766,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -40967,7 +49781,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -40976,6 +49790,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -40989,9 +49804,9 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** * The displayed width of this Game Object. @@ -41082,7 +49897,7 @@ declare namespace Phaser { setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -41104,7 +49919,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -41174,77 +49989,97 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -41280,7 +50115,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -41290,10 +50125,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -41305,25 +50144,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -41379,6 +50220,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -41397,27 +50283,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -41433,27 +50357,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -41461,17 +50381,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -41484,9 +50397,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -41650,6 +50567,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -41756,10 +50678,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -41869,7 +50791,7 @@ declare namespace Phaser { /** * The font size. */ - fontSize: string; + fontSize: string | number; /** * The font style. @@ -42068,7 +50990,7 @@ declare namespace Phaser { setFontStyle(style: string): Phaser.GameObjects.Text; /** - * Set the font size. + * Set the font size. Can be a string with a valid CSS unit, i.e. `16px`, or a number. * @param size The font size. */ setFontSize(size: number | string): Phaser.GameObjects.Text; @@ -42248,7 +51170,7 @@ declare namespace Phaser { * pixel art graphics. If you notice it and it becomes an issue, the only way to avoid it is to ensure that you * provide POT textures for Tile Sprites. */ - class TileSprite extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.ComputedSize, Phaser.GameObjects.Components.Crop, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class TileSprite extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.ComputedSize, Phaser.GameObjects.Components.Crop, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. @@ -42256,7 +51178,7 @@ declare namespace Phaser { * @param y The vertical position of this Game Object in the world. * @param width The width of the Game Object. If zero it will use the size of the texture frame. * @param height The height of the Game Object. If zero it will use the size of the texture frame. - * @param textureKey The key of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * @param textureKey The key of the Texture this Game Object will use to render with, as stored in the Texture Manager. Cannot be a DynamicTexture. * @param frameKey An optional frame from the Texture this Game Object is rendering with. */ constructor(scene: Phaser.Scene, x: number, y: number, width: number, height: number, textureKey: string, frameKey?: string | number); @@ -42277,7 +51199,7 @@ declare namespace Phaser { * The Canvas element that the TileSprite renders its fill pattern in to. * Only used in Canvas mode. */ - canvas: HTMLCanvasElement; + canvas: HTMLCanvasElement | null; /** * The Context of the Canvas element that the TileSprite renders its fill pattern in to. @@ -42320,7 +51242,7 @@ declare namespace Phaser { * The texture that the Tile Sprite is rendered to, which is then rendered to a Scene. * In WebGL this is a WebGLTexture. In Canvas it's a Canvas Fill Pattern. */ - fillPattern: WebGLTexture | CanvasPattern; + fillPattern: WebGLTexture | CanvasPattern | null; /** * Sets the texture and frame this Game Object will use to render with. @@ -42438,6 +51360,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -42452,7 +51375,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -42461,6 +51384,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -42474,9 +51398,9 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** * The native (un-scaled) width of this Game Object. @@ -42575,7 +51499,7 @@ declare namespace Phaser { setCrop(x?: number | Phaser.Geom.Rectangle, y?: number, width?: number, height?: number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -42597,7 +51521,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -42667,77 +51591,97 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -42773,7 +51717,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -42783,10 +51727,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -42798,25 +51746,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -42872,6 +51822,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -42890,27 +51885,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -42926,27 +51959,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -42954,17 +51983,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -42977,9 +51999,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -43143,6 +52169,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -43249,10 +52280,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -43386,16 +52417,25 @@ declare namespace Phaser { /** * A Video Game Object. * - * This Game Object is capable of handling playback of a previously loaded video from the Phaser Video Cache, - * or playing a video based on a given URL. Videos can be either local, or streamed. + * This Game Object is capable of handling playback of a video file, video stream or media stream. + * + * You can optionally 'preload' the video into the Phaser Video Cache: * * ```javascript * preload () { - * this.load.video('pixar', 'nemo.mp4'); + * this.load.video('ripley', 'assets/aliens.mp4'); * } * * create () { - * this.add.video(400, 300, 'pixar'); + * this.add.video(400, 300, 'ripley'); + * } + * ``` + * + * You don't have to 'preload' the video. You can also play it directly from a URL: + * + * ```javascript + * create () { + * this.add.video(400, 300).loadURL('assets/aliens.mp4'); * } * ``` * @@ -43407,25 +52447,39 @@ declare namespace Phaser { * an alpha channel, and providing the browser supports WebM playback (not all of them do), then it will render * in-game with full transparency. * + * Playback is handled entirely via the Request Video Frame API, which is supported by most modern browsers. + * A polyfill is provided for older browsers. + * * ### Autoplaying Videos * * Videos can only autoplay if the browser has been unlocked with an interaction, or satisfies the MEI settings. - * The policies that control autoplaying are vast and vary between browser. - * You can, and should, read more about it here: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide + * The policies that control autoplaying are vast and vary between browser. You can, and should, read more about + * it here: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide * * If your video doesn't contain any audio, then set the `noAudio` parameter to `true` when the video is _loaded_, * and it will often allow the video to play immediately: * * ```javascript * preload () { - * this.load.video('pixar', 'nemo.mp4', 'loadeddata', false, true); + * this.load.video('pixar', 'nemo.mp4', true); * } * ``` * - * The 5th parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without + * The 3rd parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without * audio can autoplay without requiring a user interaction. Video with audio cannot do this unless it satisfies * the browsers MEI settings. See the MDN Autoplay Guide for further details. * + * Or: + * + * ```javascript + * create () { + * this.add.video(400, 300).loadURL('assets/aliens.mp4', true); + * } + * ``` + * + * You can set the `noAudio` parameter to `true` even if the video does contain audio. It will still allow the video + * to play immediately, but the audio will not start. + * * Note that due to a bug in IE11 you cannot play a video texture to a Sprite in WebGL. For IE11 force Canvas mode. * * More details about video playback and the supported media formats can be found on MDN: @@ -43433,7 +52487,7 @@ declare namespace Phaser { * https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement * https://developer.mozilla.org/en-US/docs/Web/Media/Formats */ - class Video extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.TextureCrop, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class Video extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.TextureCrop, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. @@ -43445,27 +52499,33 @@ declare namespace Phaser { /** * A reference to the HTML Video Element this Video Game Object is playing. - * Will be `null` until a video is loaded for playback. + * + * Will be `undefined` until a video is loaded for playback. */ - video: HTMLVideoElement; + video: HTMLVideoElement | null; /** * The Phaser Texture this Game Object is using to render the video to. - * Will be `null` until a video is loaded for playback. + * + * Will be `undefined` until a video is loaded for playback. */ - videoTexture: Phaser.Textures.Texture; + videoTexture: Phaser.Textures.Texture | null; /** - * A reference to the TextureSource belong to the `videoTexture` Texture object. - * Will be `null` until a video is loaded for playback. + * A reference to the TextureSource backing the `videoTexture` Texture object. + * + * Will be `undefined` until a video is loaded for playback. */ - videoTextureSource: Phaser.Textures.TextureSource; + videoTextureSource: Phaser.Textures.TextureSource | null; /** - * A Phaser CanvasTexture instance that holds the most recent snapshot taken from the video. - * This will only be set if `snapshot` or `snapshotArea` have been called, and will be `null` until that point. + * A Phaser `CanvasTexture` instance that holds the most recent snapshot taken from the video. + * + * This will only be set if the `snapshot` or `snapshotArea` methods have been called. + * + * Until those methods are called, this property will be `undefined`. */ - snapshotTexture: Phaser.Textures.CanvasTexture; + snapshotTexture: Phaser.Textures.CanvasTexture | null; /** * If you have saved this video to a texture via the `saveTexture` method, this controls if the video @@ -43479,7 +52539,7 @@ declare namespace Phaser { * An internal flag holding the current state of the video lock, should document interaction be required * before playback can begin. */ - touchLocked: boolean; + readonly touchLocked: boolean; /** * Should the video auto play when document interaction is required and happens? @@ -43487,19 +52547,64 @@ declare namespace Phaser { playWhenUnlocked: boolean; /** - * When starting playback of a video Phaser will monitor its `readyState` using a `setTimeout` call. - * The `setTimeout` happens once every `Video.retryInterval` ms. It will carry on monitoring the video - * state in this manner until the `retryLimit` is reached and then abort. + * Has the video created its texture and populated it with the first frame of video? + */ + frameReady: boolean; + + /** + * This read-only property returns `true` if the video is currently stalled, i.e. it has stopped + * playing due to a lack of data, or too much data, but hasn't yet reached the end of the video. + * + * This is set if the Video DOM element emits any of the following events: + * + * `stalled` + * `suspend` + * `waiting` + * + * And is cleared if the Video DOM element emits the `playing` event, or handles + * a requestVideoFrame call. + * + * Listen for the Phaser Event `VIDEO_STALLED` to be notified and inspect the event + * to see which DOM event caused it. + * + * Note that being stalled isn't always a negative thing. A video can be stalled if it + * has downloaded enough data in to its buffer to not need to download any more until + * the current batch of frames have rendered. + */ + readonly isStalled: boolean; + + /** + * Records the number of times the video has failed to play, + * typically because the user hasn't interacted with the page yet. + */ + failedPlayAttempts: number; + + /** + * If the browser supports the Request Video Frame API then this + * property will hold the metadata that is returned from + * the callback each time it is invoked. + * + * See https://wicg.github.io/video-rvfc/#video-frame-metadata-callback + * for a complete list of all properties that will be in this object. + * Likely of most interest is the `mediaTime` property: + * + * The media presentation timestamp (PTS) in seconds of the frame presented + * (e.g. its timestamp on the video.currentTime timeline). MAY have a zero + * value for live-streams or WebRTC applications. + * + * If the browser doesn't support the API then this property will be undefined. */ - retryLimit: number; + metadata: VideoFrameCallbackMetadata; /** - * The current retry attempt. + * The current retry elapsed time. */ retry: number; /** - * The number of ms between each retry while monitoring the ready state of a downloading video. + * If a video fails to play due to a lack of user interaction, this is the + * amount of time, in ms, that the video will wait before trying again to + * play. The default is 500ms. */ retryInterval: number; @@ -43509,10 +52614,109 @@ declare namespace Phaser { markers: any; /** - * Should the Video element that this Video is using, be removed from the DOM - * when this Video is destroyed? + * The key of the current video as stored in the Video cache. + * + * If the video did not come from the cache this will be an empty string. + */ + readonly cacheKey: string; + + /** + * Is the video currently seeking? + * + * This is set to `true` when the `seeking` event is fired, + * and set to `false` when the `seeked` event is fired. */ - removeVideoElementOnDestroy: boolean; + readonly isSeeking: boolean; + + /** + * Loads a Video from the Video Cache, ready for playback with the `Video.play` method. + * + * If a video is already playing, this method allows you to change the source of the current video element. + * It works by first stopping the current video and then starts playback of the new source through the existing video element. + * + * The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked + * state, even if you change the source of the video. By changing the source to a new video you avoid having to + * go through the unlock process again. + * @param key The key of the Video this Game Object will play, as stored in the Video Cache. + */ + load(key: string): this; + + /** + * This method allows you to change the source of the current video element. It works by first stopping the + * current video, if playing. Then deleting the video texture, if one has been created. Finally, it makes a + * new video texture and starts playback of the new source through the existing video element. + * + * The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked + * state, even if you change the source of the video. By changing the source to a new video you avoid having to + * go through the unlock process again. + * @param key The key of the Video this Game Object will swap to playing, as stored in the Video Cache. + * @param autoplay Should the video start playing immediately, once the swap is complete? Default true. + * @param loop Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats. Default false. + * @param markerIn Optional in marker time, in seconds, for playback of a sequence of the video. + * @param markerOut Optional out marker time, in seconds, for playback of a sequence of the video. + */ + changeSource(key: string, autoplay?: boolean, loop?: boolean, markerIn?: number, markerOut?: number): this; + + /** + * Returns the key of the currently played video, as stored in the Video Cache. + * + * If the video did not come from the cache this will return an empty string. + */ + getVideoKey(): string; + + /** + * Loads a Video from the given URL, ready for playback with the `Video.play` method. + * + * If a video is already playing, this method allows you to change the source of the current video element. + * It works by first stopping the current video and then starts playback of the new source through the existing video element. + * + * The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked + * state, even if you change the source of the video. By changing the source to a new video you avoid having to + * go through the unlock process again. + * @param urls The absolute or relative URL to load the video files from. + * @param noAudio Does the video have an audio track? If not you can enable auto-playing on it. Default false. + * @param crossOrigin The value to use for the `crossOrigin` property in the video load request. Either undefined, `anonymous` or `use-credentials`. If no value is given, `crossorigin` will not be set in the request. + */ + loadURL(urls?: string | string[] | Phaser.Types.Loader.FileTypes.VideoFileURLConfig | Phaser.Types.Loader.FileTypes.VideoFileURLConfig[], noAudio?: boolean, crossOrigin?: string): this; + + /** + * Loads a Video from the given MediaStream object, ready for playback with the `Video.play` method. + * @param stream The MediaStream object. + * @param noAudio Does the video have an audio track? If not you can enable auto-playing on it. Default false. + * @param crossOrigin The value to use for the `crossOrigin` property in the video load request. Either undefined, `anonymous` or `use-credentials`. If no value is given, `crossorigin` will not be set in the request. + */ + loadMediaStream(stream: string, noAudio?: boolean, crossOrigin?: string): this; + + /** + * Internal method that loads a Video from the given URL, ready for playback with the + * `Video.play` method. + * + * Normally you don't call this method directly, but instead use the `Video.loadURL` method, + * or the `Video.load` method if you have preloaded the video. + * + * Calling this method will skip checking if the browser supports the given format in + * the URL, where-as the other two methods enforce these checks. + * @param url The absolute or relative URL to load the video file from. Set to `null` if passing in a MediaStream object. + * @param noAudio Does the video have an audio track? If not you can enable auto-playing on it. + * @param crossOrigin The value to use for the `crossOrigin` property in the video load request. Either undefined, `anonymous` or `use-credentials`. If no value is given, `crossorigin` will not be set in the request. + * @param stream A MediaStream object if this is playing a stream instead of a file. + */ + loadHandler(url?: string, noAudio?: boolean, crossOrigin?: string, stream?: string): this; + + /** + * This method handles the Request Video Frame callback. + * + * It is called by the browser when a new video frame is ready to be displayed. + * + * It's also responsible for the creation of the video texture, if it doesn't + * already exist. If it does, it updates the texture as required. + * + * For more details about the Request Video Frame callback, see: + * https://web.dev/requestvideoframecallback-rvfc + * @param now The current time in milliseconds. + * @param metadata Useful metadata about the video frame that was most recently presented for composition. See https://wicg.github.io/video-rvfc/#video-frame-metadata-callback + */ + requestVideoFrame(now: DOMHighResTimeStamp, metadata: VideoFrameCallbackMetadata): void; /** * Starts this video playing. @@ -43528,11 +52732,11 @@ declare namespace Phaser { * * ```javascript * preload () { - * this.load.video('pixar', 'nemo.mp4', 'loadeddata', false, true); + * this.load.video('pixar', 'nemo.mp4', true); * } * ``` * - * The 5th parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without + * The 3rd parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without * audio can autoplay without requiring a user interaction. Video with audio cannot do this unless it satisfies * the browsers MEI settings. See the MDN Autoplay Guide for details. * @@ -43545,20 +52749,35 @@ declare namespace Phaser { play(loop?: boolean, markerIn?: number, markerOut?: number): this; /** - * This method allows you to change the source of the current video element. It works by first stopping the - * current video, if playing. Then deleting the video texture, if one has been created. Finally, it makes a - * new video texture and starts playback of the new source through the existing video element. + * Adds the loading specific event handlers to the video element. + */ + addLoadEventHandlers(): void; + + /** + * Removes the loading specific event handlers from the video element. + */ + removeLoadEventHandlers(): void; + + /** + * Adds the playback specific event handlers to the video element. + */ + addEventHandlers(): void; + + /** + * Removes the playback specific event handlers from the video element. + */ + removeEventHandlers(): void; + + /** + * Creates the video.play promise and adds the success and error handlers to it. * - * The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked - * state, even if you change the source of the video. By changing the source to a new video you avoid having to - * go through the unlock process again. - * @param key The key of the Video this Game Object will swap to playing, as stored in the Video Cache. - * @param autoplay Should the video start playing immediately, once the swap is complete? Default true. - * @param loop Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats. Default false. - * @param markerIn Optional in marker time, in seconds, for playback of a sequence of the video. - * @param markerOut Optional out marker time, in seconds, for playback of a sequence of the video. + * Not all browsers support the video.play promise, so this method will fall back to + * the old-school way of handling the video.play call. + * + * See https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play#browser_compatibility for details. + * @param catchError Should the error be caught and the video marked as failed to play? Default true. */ - changeSource(key: string, autoplay?: boolean, loop?: boolean, markerIn?: number, markerOut?: number): this; + createPlayPromise(catchError?: boolean): void; /** * Adds a sequence marker to this video. @@ -43657,63 +52876,46 @@ declare namespace Phaser { saveSnapshotTexture(key: string): Phaser.Textures.CanvasTexture; /** - * Loads a Video from the given URL, ready for playback with the `Video.play` method. - * - * You can control at what point the browser determines the video as being ready for playback via - * the `loadEvent` parameter. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement - * for more details. - * @param url The URL of the video to load or be streamed. - * @param loadEvent The load event to listen for. Either `loadeddata`, `canplay` or `canplaythrough`. Default 'loadeddata'. - * @param noAudio Does the video have an audio track? If not you can enable auto-playing on it. Default false. + * This internal method is called automatically if the playback Promise resolves successfully. */ - loadURL(url: string, loadEvent?: string, noAudio?: boolean): this; + playSuccess(): void; /** - * Loads a Video from the given MediaStream object, ready for playback with the `Video.play` method. - * - * You can control at what point the browser determines the video as being ready for playback via - * the `loadEvent` parameter. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement - * for more details. - * @param stream The MediaStream object. - * @param loadEvent The load event to listen for. Either `loadeddata`, `canplay` or `canplaythrough`. Default 'loadeddata'. - * @param noAudio Does the video have an audio track? If not you can enable auto-playing on it. Default false. + * This internal method is called automatically if the playback Promise fails to resolve. + * @param error The Promise DOM Exception error. */ - loadMediaStream(stream: string, loadEvent?: string, noAudio?: boolean): this; + playError(error: DOMException): void; /** - * Called when the video emits a `playing` event during load. + * Called when the video emits a `playing` event. * - * This is only listened for if the browser doesn't support Promises. + * This is the legacy handler for browsers that don't support Promise based playback. */ - playHandler(): void; + legacyPlayHandler(): void; /** - * Called when the video completes playback, i.e. reaches an `ended` state. - * - * This will never happen if the video is coming from a live stream, where the duration is `Infinity`. + * Called when the video emits a `playing` event. */ - completeHandler(): void; + playingHandler(): void; /** - * Called when the video emits a `timeUpdate` event during playback. - * - * This event is too slow and irregular to be used for actual video timing or texture updating, - * but we can use it to determine if a video has looped. + * This internal method is called automatically if the video fails to load. + * @param event The error Event. */ - timeUpdateHandler(): void; + loadErrorHandler(event: Event): void; /** - * Internal method that is called when enough video data has been received in order to create a texture - * from it. The texture is assigned to the `Video.videoTexture` property and given a base frame that - * encompases the whole video size. + * This internal method is called automatically if the video stalls, for whatever reason. + * @param event The error Event. */ - updateTexture(): void; + stalledHandler(event: Event): void; /** - * Returns the key of the currently played video, as stored in the Video Cache. - * If the video did not come from the cache this will return an empty string. + * Called when the video completes playback, i.e. reaches an `ended` state. + * + * This will never happen if the video is coming from a live stream, where the duration is `Infinity`. */ - getVideoKey(): string; + completeHandler(): void; /** * Seeks to a given point in the video. The value is given as a float between 0 and 1, @@ -43725,13 +52927,19 @@ declare namespace Phaser { * seeking (i.e. reaches its designated timestamp) it will emit a `seeked` event. * * If you wish to seek based on time instead, use the `Video.setCurrentTime` method. + * + * Unfortunately, the DOM video element does not guarantee frame-accurate seeking. + * This has been an ongoing subject of discussion: https://github.com/w3c/media-and-entertainment/issues/4 * @param value The point in the video to seek to. A value between 0 and 1. */ seekTo(value: number): this; /** * A double-precision floating-point value indicating the current playback time in seconds. + * * If the media has not started to play and has not been seeked, this value is the media's initial playback time. + * + * For a more accurate value, use the `Video.metadata.mediaTime` property instead. */ getCurrentTime(): number; @@ -43752,15 +52960,13 @@ declare namespace Phaser { setCurrentTime(value: string | number): this; /** - * Returns a boolean indicating if this Video is currently seeking, or not. - */ - isSeeking(): boolean; - - /** - * Returns the current progress of the video. Progress is defined as a value between 0 (the start) - * and 1 (the end). + * Returns the current progress of the video as a float. * - * Progress can only be returned if the video has a duration, otherwise it will always return zero. + * Progress is defined as a value between 0 (the start) and 1 (the end). + * + * Progress can only be returned if the video has a duration. Some videos, + * such as those coming from a live stream, do not have a duration. In this + * case the method will return -1. */ getProgress(): number; @@ -43770,6 +52976,8 @@ declare namespace Phaser { * * If the media has no known end (such as for live streams of unknown duration, web radio, media incoming from WebRTC, * and so forth), this value is +Infinity. + * + * If no video has been loaded, this method will return 0. */ getDuration(): number; @@ -43791,10 +52999,32 @@ declare namespace Phaser { * If the video is paused, calling this method with `false` will resume playback. * * If no video is loaded, this method does nothing. + * + * If the video has not yet been played, `Video.play` will be called with no parameters. + * + * If the video has ended, this method will do nothing. * @param value The paused value. `true` if the video should be paused, `false` to resume it. Default true. */ setPaused(value?: boolean): this; + /** + * Pauses the current Video, if one is playing. + * + * If no video is loaded, this method does nothing. + * + * Call `Video.resume` to resume playback. + */ + pause(): this; + + /** + * Resumes the current Video, if one was previously playing and has been paused. + * + * If no video is loaded, this method does nothing. + * + * Call `Video.pause` to pause playback. + */ + resume(): this; + /** * Returns a double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest). */ @@ -43850,10 +53080,10 @@ declare namespace Phaser { /** * Stores this Video in the Texture Manager using the given key as a dynamic texture, - * which any texture-based Game Object, such as a Sprite, can use as its texture: + * which any texture-based Game Object, such as a Sprite, can use as its source: * * ```javascript - * var vid = this.add.video(0, 0, 'intro'); + * const vid = this.add.video(0, 0, 'intro'); * * vid.play(); * @@ -43862,6 +53092,23 @@ declare namespace Phaser { * this.add.image(400, 300, 'doodle'); * ``` * + * If the video is not yet playing then you need to listen for the `TEXTURE_READY` event before + * you can use this texture on a Game Object: + * + * ```javascript + * const vid = this.add.video(0, 0, 'intro'); + * + * vid.play(); + * + * vid.once('textureready', (video, texture, key) => { + * + * this.add.image(400, 300, key); + * + * }); + * + * vid.saveTexture('doodle'); + * ``` + * * The saved texture is automatically updated as the video plays. If you pause this video, * or change its source, then the saved texture updates instantly. * @@ -43876,7 +53123,7 @@ declare namespace Phaser { * @param key The unique key to store the texture as within the global Texture Manager. * @param flipY Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y` during upload? Default false. */ - saveTexture(key: string, flipY?: boolean): Phaser.Textures.Texture; + saveTexture(key: string, flipY?: boolean): boolean; /** * Stops the video playing and clears all internal event listeners. @@ -43885,20 +53132,20 @@ declare namespace Phaser { * * If the video hasn't finished downloading, calling this method will not abort the download. To do that you need to * call `destroy` instead. + * @param emitStopEvent Should the `VIDEO_STOP` event be emitted? Default true. */ - stop(): this; + stop(emitStopEvent?: boolean): this; /** * Removes the Video element from the DOM by calling parentNode.removeChild on itself. * - * Also removes the autoplay and src attributes and nulls the Video reference. - * - * You should not call this method if you were playing a video from the Video Cache that - * you wish to play again in your game, or if another Video object is also using the same - * video. + * Also removes the autoplay and src attributes and nulls the `Video.video` reference. * * If you loaded an external video via `Video.loadURL` then you should call this function - * to clear up once you are done with the instance. + * to clear up once you are done with the instance, but don't want to destroy this + * Video Game Object. + * + * This method is called automatically by `Video.destroy`. */ removeVideoElement(): void; @@ -43960,6 +53207,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -43974,7 +53222,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -43983,6 +53231,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -43996,12 +53245,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -44023,7 +53272,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -44084,77 +53333,97 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -44190,7 +53459,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -44200,10 +53469,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -44215,25 +53488,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -44289,6 +53564,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -44307,27 +53627,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -44343,27 +53701,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -44371,17 +53725,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -44394,9 +53741,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -44505,7 +53856,7 @@ declare namespace Phaser { * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * @param frame The frame to base the size of this Game Object on. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; /** * Sets the internal size of this Game Object, as used for frame or physics body creation. @@ -44589,17 +53940,19 @@ declare namespace Phaser { /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** * The tint value being applied to the top-left vertice of the Game Object. @@ -44704,6 +54057,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -44810,10 +54168,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -44980,13 +54338,13 @@ declare namespace Phaser { /** * Allows you to define your own Geometry shape to be used as a Drop Zone. - * @param hitArea A Geometry shape instance, such as Phaser.Geom.Ellipse, or your own custom shape. - * @param hitAreaCallback A function that will return `true` if the given x/y coords it is sent are within the shape. + * @param hitArea A Geometry shape instance, such as Phaser.Geom.Ellipse, or your own custom shape. If not given it will try to create a Rectangle based on the size of this zone. + * @param hitAreaCallback A function that will return `true` if the given x/y coords it is sent are within the shape. If you provide a shape you must also provide a callback. */ - setDropZone(hitArea: object, hitAreaCallback: Phaser.Types.Input.HitAreaCallback): this; + setDropZone(hitArea?: object, hitAreaCallback?: Phaser.Types.Input.HitAreaCallback): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -45008,83 +54366,103 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -45095,16 +54473,18 @@ declare namespace Phaser { * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -45148,6 +54528,11 @@ declare namespace Phaser { */ updateDisplayOrigin(): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -45254,10 +54639,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -45966,16 +55351,17 @@ declare namespace Phaser { function GetLineToCircle(line: Phaser.Geom.Line, circle: Phaser.Geom.Circle, out?: any[]): any[]; /** - * 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. + * Checks for intersection between the two line segments, or a ray and a line segment, + * 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. - * @param line1 The first line segment to check. + * @param line1 The first line segment, or a ray, to check. * @param line2 The second line segment to check. + * @param isRay Is `line1` a ray or a line segment? Default false. * @param out A Vector3 to store the intersection results in. */ - function GetLineToLine(line1: Phaser.Geom.Line, line2: Phaser.Geom.Line, out?: Phaser.Math.Vector3): Phaser.Math.Vector3; + function GetLineToLine(line1: Phaser.Geom.Line, line2: Phaser.Geom.Line, isRay?: boolean, out?: Phaser.Math.Vector3): Phaser.Math.Vector3; /** * Checks for the closest point of intersection between a line segment and an array of points, where each pair @@ -45987,11 +55373,12 @@ declare namespace Phaser { * * The `x` and `y` components contain the point of the intersection. * The `z` component contains the closest distance. - * @param line The line segment to check. + * @param line The line segment, or ray, to check. If a ray, set the `isRay` parameter to `true`. * @param points An array of points to check. + * @param isRay Is `line` a ray or a line segment? Default false. * @param out A Vector3 to store the intersection results in. */ - function GetLineToPoints(line: Phaser.Geom.Line, points: Phaser.Math.Vector2[] | Phaser.Geom.Point[], out?: Phaser.Math.Vector3): Phaser.Math.Vector3; + function GetLineToPoints(line: Phaser.Geom.Line, points: Phaser.Math.Vector2[] | Phaser.Geom.Point[], isRay?: boolean, out?: Phaser.Math.Vector3): Phaser.Math.Vector3; /** * Checks for the closest point of intersection between a line segment and an array of polygons. @@ -46003,11 +55390,12 @@ declare namespace Phaser { * 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. - * @param line The line segment to check. + * @param line The line segment, or ray, to check. If a ray, set the `isRay` parameter to `true`. * @param polygons A single polygon, or array of polygons, to check. + * @param isRay Is `line` a ray or a line segment? Default false. * @param out A Vector4 to store the intersection results in. */ - function GetLineToPolygon(line: Phaser.Geom.Line, polygons: Phaser.Geom.Polygon | Phaser.Geom.Polygon[], out?: Phaser.Math.Vector4): Phaser.Math.Vector4; + function GetLineToPolygon(line: Phaser.Geom.Line, polygons: Phaser.Geom.Polygon | Phaser.Geom.Polygon[], isRay?: boolean, out?: Phaser.Math.Vector4): Phaser.Math.Vector4; /** * Checks for intersection between the Line and a Rectangle shape, @@ -46111,9 +55499,9 @@ declare namespace Phaser { * Checks if two Lines intersect. If the Lines are identical, they will be treated as parallel and thus non-intersecting. * @param line1 The first Line to check. * @param line2 The second Line to check. - * @param out A Point in which to optionally store the point of intersection. + * @param out An optional point-like object in which to store the coordinates of intersection, if needed. */ - function LineToLine(line1: Phaser.Geom.Line, line2: Phaser.Geom.Line, out?: Phaser.Geom.Point): boolean; + function LineToLine(line1: Phaser.Geom.Line, line2: Phaser.Geom.Line, out?: Phaser.Types.Math.Vector2Like): boolean; /** * Checks for intersection between the Line and a Rectangle shape, or a rectangle-like @@ -46357,7 +55745,7 @@ declare namespace Phaser { * @param line The line to get the distance from. * @param point The point to get the shortest distance to. */ - static GetShortestDistance(line: Phaser.Geom.Line, point: Phaser.Geom.Point | object): O; + static GetShortestDistance(line: Phaser.Geom.Line, point: Phaser.Types.Math.Vector2Like): boolean | number; /** * Calculate the height of the given line. @@ -46682,6 +56070,50 @@ declare namespace Phaser { */ isInView(camera: Phaser.Cameras.Scene2D.Camera, hideCCW: boolean, z: number, alpha: number, a: number, b: number, c: number, d: number, e: number, f: number, roundPixels: boolean): boolean; + /** + * Translates the original UV positions of each vertex by the given amounts. + * + * The original properties `Vertex.u` and `Vertex.v` + * remain unchanged, only the translated properties + * `Vertex.tu` and `Vertex.tv`, as used in rendering, + * are updated. + * @param x The amount to scroll the UV u coordinate by. + * @param y The amount to scroll the UV v coordinate by. + */ + scrollUV(x: number, y: number): this; + + /** + * Scales the original UV values of each vertex by the given amounts. + * + * The original properties `Vertex.u` and `Vertex.v` + * remain unchanged, only the translated properties + * `Vertex.tu` and `Vertex.tv`, as used in rendering, + * are updated. + * @param x The amount to scale the UV u coordinate by. + * @param y The amount to scale the UV v coordinate by. + */ + scaleUV(x: number, y: number): this; + + /** + * Sets the color value for each Vertex in this Face. + * @param color The color value for each vertex. + */ + setColor(color: number): this; + + /** + * Calls the `Vertex.update` method on each of the vertices. This populates them + * with the new translated values, updating their `tx`, `ty` and `ta` properties. + * @param alpha The alpha of the parent object. + * @param a The parent transform matrix data a component. + * @param b The parent transform matrix data b component. + * @param c The parent transform matrix data c component. + * @param d The parent transform matrix data d component. + * @param e The parent transform matrix data e component. + * @param f The parent transform matrix data f component. + * @param roundPixels Round the vertex position or not? + */ + update(alpha: number, a: number, b: number, c: number, d: number, e: number, f: number, roundPixels: boolean): this; + /** * Translates the vertices of this Face by the given amounts. * @@ -46847,8 +56279,9 @@ declare namespace Phaser { * @param normals Optional vertex normals array. If you don't have one, pass `null` or an empty array. * @param colors An array of colors, one per vertex, or a single color value applied to all vertices. Default 0xffffff. * @param alphas An array of alpha values, one per vertex, or a single alpha value applied to all vertices. Default 1. + * @param flipUV Flip the UV coordinates? Default false. */ - function GenerateVerts(vertices: number[], uvs: number[], indicies?: number[], containsZ?: boolean, normals?: number[], colors?: number | number[], alphas?: number | number[]): Phaser.Types.Geom.Mesh.GenerateVertsResult; + function GenerateVerts(vertices: number[], uvs: number[], indicies?: number[], containsZ?: boolean, normals?: number[], colors?: number | number[], alphas?: number | number[], flipUV?: boolean): Phaser.Types.Geom.Mesh.GenerateVertsResult; /** * Parses a Wavefront OBJ File, extracting the models from it and returning them in an array. @@ -46925,17 +56358,17 @@ declare namespace Phaser { vz: number; /** - * The projected x coordinate of this vertex. + * The normalized projected x coordinate of this vertex. */ nx: number; /** - * The projected y coordinate of this vertex. + * The normalized projected y coordinate of this vertex. */ ny: number; /** - * The projected z coordinate of this vertex. + * The normalized projected z coordinate of this vertex. */ nz: number; @@ -46974,13 +56407,50 @@ declare namespace Phaser { */ ta: number; + /** + * The translated uv u coordinate of this vertex. + */ + tu: number; + + /** + * The translated uv v coordinate of this vertex. + */ + tv: number; + /** * Sets the U and V properties. + * + * Also resets the translated uv properties, undoing any scale + * or shift they may have had. * @param u The UV u coordinate of the vertex. * @param v The UV v coordinate of the vertex. */ setUVs(u: number, v: number): this; + /** + * Translates the original UV positions by the given amounts. + * + * The original properties `Vertex.u` and `Vertex.v` + * remain unchanged, only the translated properties + * `Vertex.tu` and `Vertex.tv`, as used in rendering, + * are updated. + * @param x The amount to scroll the UV u coordinate by. + * @param y The amount to scroll the UV v coordinate by. + */ + scrollUV(x: number, y: number): this; + + /** + * Scales the original UV values by the given amounts. + * + * The original properties `Vertex.u` and `Vertex.v` + * remain unchanged, only the translated properties + * `Vertex.tu` and `Vertex.tv`, as used in rendering, + * are updated. + * @param x The amount to scale the UV u coordinate by. + * @param y The amount to scale the UV v coordinate by. + */ + scaleUV(x: number, y: number): this; + /** * Transforms this vertex by the given matrix, storing the results in `vx`, `vy` and `vz`. * @param transformMatrix The transform matrix to apply to this vertex. @@ -46990,6 +56460,18 @@ declare namespace Phaser { */ transformCoordinatesLocal(transformMatrix: Phaser.Math.Matrix4, width: number, height: number, cameraZ: number): void; + /** + * Resizes this Vertex by setting the x and y coordinates, then transforms this vertex + * by an identity matrix and dimensions, storing the results in `vx`, `vy` and `vz`. + * @param x The x position of the vertex. + * @param y The y position of the vertex. + * @param width The width of the parent Mesh. + * @param height The height of the parent Mesh. + * @param originX The originX of the parent Mesh. + * @param originY The originY of the parent Mesh. + */ + resize(x: number, y: number, width: number, height: number, originX: number, originY: number): this; + /** * Updates this Vertex based on the given transform. * @param a The parent transform matrix data a component. @@ -47492,6 +56974,16 @@ declare namespace Phaser { /** * Constructs new Rectangle or repositions and resizes an existing Rectangle so that all of the given points are on or within its bounds. + * + * The `points` parameter is an array of Point-like objects: + * + * ```js + * const points = [ + * [100, 200], + * [200, 400], + * { x: 30, y: 60 } + * ] + * ``` * @param points An array of points (either arrays with two elements corresponding to the X and Y coordinate or an object with public `x` and `y` properties) which should be surrounded by the Rectangle. * @param out Optional Rectangle to adjust. */ @@ -48228,14 +57720,14 @@ declare namespace Phaser { * * This internal event is dispatched by the Input Plugin when it boots, signalling to all of its systems to create themselves. */ - const BOOT: any; + const BOOT: string; /** * The Input Plugin Destroy Event. * * This internal event is dispatched by the Input Plugin when it is destroyed, signalling to all of its systems to destroy themselves. */ - const DESTROY: any; + const DESTROY: string; /** * The Pointer Drag End Input Event. @@ -48246,7 +57738,7 @@ declare namespace Phaser { * * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_END]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_END} event instead. */ - const DRAG_END: any; + const DRAG_END: string; /** * The Pointer Drag Enter Input Event. @@ -48259,7 +57751,7 @@ declare namespace Phaser { * * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_ENTER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_ENTER} event instead. */ - const DRAG_ENTER: any; + const DRAG_ENTER: string; /** * The Pointer Drag Input Event. @@ -48272,7 +57764,7 @@ declare namespace Phaser { * * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG} event instead. */ - const DRAG: any; + const DRAG: string; /** * The Pointer Drag Leave Input Event. @@ -48285,7 +57777,7 @@ declare namespace Phaser { * * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_LEAVE]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_LEAVE} event instead. */ - const DRAG_LEAVE: any; + const DRAG_LEAVE: string; /** * The Pointer Drag Over Input Event. @@ -48301,7 +57793,7 @@ declare namespace Phaser { * * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_OVER]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_OVER} event instead. */ - const DRAG_OVER: any; + const DRAG_OVER: string; /** * The Pointer Drag Start Input Event. @@ -48314,7 +57806,7 @@ declare namespace Phaser { * * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DRAG_START]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DRAG_START} event instead. */ - const DRAG_START: any; + const DRAG_START: string; /** * The Pointer Drop Input Event. @@ -48325,7 +57817,7 @@ declare namespace Phaser { * * To listen for this event from a _specific_ Game Object, use the [GAMEOBJECT_DROP]{@linkcode Phaser.Input.Events#event:GAMEOBJECT_DROP} event instead. */ - const DROP: any; + const DROP: string; /** * The Game Object Down Input Event. @@ -48348,7 +57840,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_DOWN: any; + const GAMEOBJECT_DOWN: string; /** * The Game Object Drag End Event. @@ -48361,7 +57853,7 @@ declare namespace Phaser { * To receive this event, the Game Object must have been set as interactive and enabled for drag. * See [GameObject.setInteractive](Phaser.GameObjects.GameObject#setInteractive) for more details. */ - const GAMEOBJECT_DRAG_END: any; + const GAMEOBJECT_DRAG_END: string; /** * The Game Object Drag Enter Event. @@ -48374,7 +57866,7 @@ declare namespace Phaser { * To receive this event, the Game Object must have been set as interactive and enabled for drag. * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. */ - const GAMEOBJECT_DRAG_ENTER: any; + const GAMEOBJECT_DRAG_ENTER: string; /** * The Game Object Drag Event. @@ -48387,7 +57879,7 @@ declare namespace Phaser { * To receive this event, the Game Object must have been set as interactive and enabled for drag. * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. */ - const GAMEOBJECT_DRAG: any; + const GAMEOBJECT_DRAG: string; /** * The Game Object Drag Leave Event. @@ -48400,7 +57892,7 @@ declare namespace Phaser { * To receive this event, the Game Object must have been set as interactive and enabled for drag. * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. */ - const GAMEOBJECT_DRAG_LEAVE: any; + const GAMEOBJECT_DRAG_LEAVE: string; /** * The Game Object Drag Over Event. @@ -48416,7 +57908,7 @@ declare namespace Phaser { * To receive this event, the Game Object must have been set as interactive and enabled for drag. * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. */ - const GAMEOBJECT_DRAG_OVER: any; + const GAMEOBJECT_DRAG_OVER: string; /** * The Game Object Drag Start Event. @@ -48432,7 +57924,7 @@ declare namespace Phaser { * There are lots of useful drag related properties that are set within the Game Object when dragging occurs. * For example, `gameObject.input.dragStartX`, `dragStartY` and so on. */ - const GAMEOBJECT_DRAG_START: any; + const GAMEOBJECT_DRAG_START: string; /** * The Game Object Drop Event. @@ -48445,7 +57937,7 @@ declare namespace Phaser { * To receive this event, the Game Object must have been set as interactive and enabled for drag. * See [GameObject.setInteractive]{@link Phaser.GameObjects.GameObject#setInteractive} for more details. */ - const GAMEOBJECT_DROP: any; + const GAMEOBJECT_DROP: string; /** * The Game Object Move Input Event. @@ -48468,7 +57960,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_MOVE: any; + const GAMEOBJECT_MOVE: string; /** * The Game Object Out Input Event. @@ -48490,8 +57982,11 @@ declare namespace Phaser { * * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. + * + * If the pointer leaves the game canvas itself, it will not trigger an this event. To handle those cases, + * please listen for the [GAME_OUT]{@linkcode Phaser.Input.Events#event:GAME_OUT} event. */ - const GAMEOBJECT_OUT: any; + const GAMEOBJECT_OUT: string; /** * The Game Object Over Input Event. @@ -48514,7 +58009,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_OVER: any; + const GAMEOBJECT_OVER: string; /** * The Game Object Pointer Down Event. @@ -48536,7 +58031,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_POINTER_DOWN: any; + const GAMEOBJECT_POINTER_DOWN: string; /** * The Game Object Pointer Move Event. @@ -48558,7 +58053,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_POINTER_MOVE: any; + const GAMEOBJECT_POINTER_MOVE: string; /** * The Game Object Pointer Out Event. @@ -48579,8 +58074,11 @@ declare namespace Phaser { * * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. + * + * If the pointer leaves the game canvas itself, it will not trigger an this event. To handle those cases, + * please listen for the [GAME_OUT]{@linkcode Phaser.Input.Events#event:GAME_OUT} event. */ - const GAMEOBJECT_POINTER_OUT: any; + const GAMEOBJECT_POINTER_OUT: string; /** * The Game Object Pointer Over Event. @@ -48602,7 +58100,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_POINTER_OVER: any; + const GAMEOBJECT_POINTER_OVER: string; /** * The Game Object Pointer Up Event. @@ -48624,7 +58122,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_POINTER_UP: any; + const GAMEOBJECT_POINTER_UP: string; /** * The Game Object Pointer Wheel Event. @@ -48646,7 +58144,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_POINTER_WHEEL: any; + const GAMEOBJECT_POINTER_WHEEL: string; /** * The Game Object Up Input Event. @@ -48669,7 +58167,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_UP: any; + const GAMEOBJECT_UP: string; /** * The Game Object Wheel Input Event. @@ -48692,7 +58190,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const GAMEOBJECT_WHEEL: any; + const GAMEOBJECT_WHEEL: string; /** * The Input Plugin Game Out Event. @@ -48702,7 +58200,7 @@ declare namespace Phaser { * * Listen to this event from within a Scene using: `this.input.on('gameout', listener)`. */ - const GAME_OUT: any; + const GAME_OUT: string; /** * The Input Plugin Game Over Event. @@ -48712,14 +58210,14 @@ declare namespace Phaser { * * Listen to this event from within a Scene using: `this.input.on('gameover', listener)`. */ - const GAME_OVER: any; + const GAME_OVER: string; /** * The Input Manager Boot Event. * * This internal event is dispatched by the Input Manager when it boots. */ - const MANAGER_BOOT: any; + const MANAGER_BOOT: string; /** * The Input Manager Process Event. @@ -48727,21 +58225,21 @@ declare namespace Phaser { * This internal event is dispatched by the Input Manager when not using the legacy queue system, * and it wants the Input Plugins to update themselves. */ - const MANAGER_PROCESS: any; + const MANAGER_PROCESS: string; /** * The Input Manager Update Event. * * This internal event is dispatched by the Input Manager as part of its update step. */ - const MANAGER_UPDATE: any; + const MANAGER_UPDATE: string; /** * The Input Manager Pointer Lock Change Event. * * This event is dispatched by the Input Manager when it is processing a native Pointer Lock Change DOM Event. */ - const POINTERLOCK_CHANGE: any; + const POINTERLOCK_CHANGE: string; /** * The Pointer Down Input Event. @@ -48759,7 +58257,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const POINTER_DOWN: any; + const POINTER_DOWN: string; /** * The Pointer Down Outside Input Event. @@ -48777,7 +58275,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const POINTER_DOWN_OUTSIDE: any; + const POINTER_DOWN_OUTSIDE: string; /** * The Pointer Move Input Event. @@ -48795,7 +58293,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const POINTER_MOVE: any; + const POINTER_MOVE: string; /** * The Pointer Out Input Event. @@ -48812,8 +58310,11 @@ declare namespace Phaser { * * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. + * + * If the pointer leaves the game canvas itself, it will not trigger an this event. To handle those cases, + * please listen for the [GAME_OUT]{@linkcode Phaser.Input.Events#event:GAME_OUT} event. */ - const POINTER_OUT: any; + const POINTER_OUT: string; /** * The Pointer Over Input Event. @@ -48831,7 +58332,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const POINTER_OVER: any; + const POINTER_OVER: string; /** * The Pointer Up Input Event. @@ -48849,7 +58350,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const POINTER_UP: any; + const POINTER_UP: string; /** * The Pointer Up Outside Input Event. @@ -48867,7 +58368,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const POINTER_UP_OUTSIDE: any; + const POINTER_UP_OUTSIDE: string; /** * The Pointer Wheel Input Event. @@ -48885,7 +58386,7 @@ declare namespace Phaser { * With the top event being dispatched first and then flowing down the list. Note that higher-up event handlers can stop * the propagation of this event. */ - const POINTER_WHEEL: any; + const POINTER_WHEEL: string; /** * The Input Plugin Pre-Update Event. @@ -48893,14 +58394,14 @@ declare namespace Phaser { * This internal event is dispatched by the Input Plugin at the start of its `preUpdate` method. * This hook is designed specifically for input plugins, but can also be listened to from user-land code. */ - const PRE_UPDATE: any; + const PRE_UPDATE: string; /** * The Input Plugin Shutdown Event. * * This internal event is dispatched by the Input Plugin when it shuts down, signalling to all of its systems to shut themselves down. */ - const SHUTDOWN: any; + const SHUTDOWN: string; /** * The Input Plugin Start Event. @@ -48908,7 +58409,7 @@ declare namespace Phaser { * This internal event is dispatched by the Input Plugin when it has finished setting-up, * signalling to all of its internal systems to start. */ - const START: any; + const START: string; /** * The Input Plugin Update Event. @@ -48916,7 +58417,7 @@ declare namespace Phaser { * This internal event is dispatched by the Input Plugin at the start of its `update` method. * This hook is designed specifically for input plugins, but can also be listened to from user-land code. */ - const UPDATE: any; + const UPDATE: string; } @@ -49026,18 +58527,296 @@ declare namespace Phaser { * Tatar SNES USB Controller Gamepad Configuration. * USB Gamepad (STANDARD GAMEPAD Vendor: 0079 Product: 0011) */ - var SNES_USB: object; + namespace SNES_USB { + /** + * D-Pad up + */ + const UP: number; + + /** + * D-Pad down + */ + const DOWN: number; + + /** + * D-Pad left + */ + const LEFT: number; + + /** + * D-Pad right + */ + const RIGHT: number; + + /** + * Select button + */ + const SELECT: number; + + /** + * Start button + */ + const START: number; + + /** + * B Button (Bottom) + */ + const B: number; + + /** + * A Button (Right) + */ + const A: number; + + /** + * Y Button (Left) + */ + const Y: number; + + /** + * X Button (Top) + */ + const X: number; + + /** + * Left bumper + */ + const LEFT_SHOULDER: number; + + /** + * Right bumper + */ + const RIGHT_SHOULDER: number; + + } /** * PlayStation DualShock 4 Gamepad Configuration. * Sony PlayStation DualShock 4 (v2) wireless controller */ - var DUALSHOCK_4: object; + namespace DUALSHOCK_4 { + /** + * D-Pad up + */ + const UP: number; + + /** + * D-Pad down + */ + const DOWN: number; + + /** + * D-Pad left + */ + const LEFT: number; + + /** + * D-Pad up + */ + const RIGHT: number; + + /** + * Share button + */ + const SHARE: number; + + /** + * Options button + */ + const OPTIONS: number; + + /** + * PlayStation logo button + */ + const PS: number; + + /** + * Touchpad click + */ + const TOUCHBAR: number; + + /** + * Cross button (Bottom) + */ + const X: number; + + /** + * Circle button (Right) + */ + const CIRCLE: number; + + /** + * Square button (Left) + */ + const SQUARE: number; + + /** + * Triangle button (Top) + */ + const TRIANGLE: number; + + /** + * Left bumper (L1) + */ + const L1: number; + + /** + * Right bumper (R1) + */ + const R1: number; + + /** + * Left trigger (L2) + */ + const L2: number; + + /** + * Right trigger (R2) + */ + const R2: number; + + /** + * Left stick click (L3) + */ + const L3: number; + + /** + * Right stick click (R3) + */ + const R3: number; + + /** + * Left stick horizontal + */ + const LEFT_STICK_H: number; + + /** + * Left stick vertical + */ + const LEFT_STICK_V: number; + + /** + * Right stick horizontal + */ + const RIGHT_STICK_H: number; + + /** + * Right stick vertical + */ + const RIGHT_STICK_V: number; + + } /** * XBox 360 Gamepad Configuration. */ - var XBOX_360: object; + namespace XBOX_360 { + /** + * D-Pad up + */ + const UP: number; + + /** + * D-Pad down + */ + const DOWN: number; + + /** + * D-Pad left + */ + const LEFT: number; + + /** + * D-Pad right + */ + const RIGHT: number; + + /** + * XBox menu button + */ + const MENU: number; + + /** + * A button (Bottom) + */ + const A: number; + + /** + * B button (Right) + */ + const B: number; + + /** + * X button (Left) + */ + const X: number; + + /** + * Y button (Top) + */ + const Y: number; + + /** + * Left Bumper + */ + const LB: number; + + /** + * Right Bumper + */ + const RB: number; + + /** + * Left Trigger + */ + const LT: number; + + /** + * Right Trigger + */ + const RT: number; + + /** + * Back / Change View button + */ + const BACK: number; + + /** + * Start button + */ + const START: number; + + /** + * Left Stick press + */ + const LS: number; + + /** + * Right stick press + */ + const RS: number; + + /** + * Left Stick horizontal + */ + const LEFT_STICK_H: number; + + /** + * Left Stick vertical + */ + const LEFT_STICK_V: number; + + /** + * Right Stick horizontal + */ + const RIGHT_STICK_H: number; + + /** + * Right Stick vertical + */ + const RIGHT_STICK_V: number; + + } } @@ -49051,7 +58830,7 @@ declare namespace Phaser { * * You can also listen for a DOWN event from a Gamepad instance. See the [GAMEPAD_BUTTON_DOWN]{@linkcode Phaser.Input.Gamepad.Events#event:GAMEPAD_BUTTON_DOWN} event for details. */ - const BUTTON_DOWN: any; + const BUTTON_DOWN: string; /** * The Gamepad Button Up Event. @@ -49062,7 +58841,7 @@ declare namespace Phaser { * * You can also listen for an UP event from a Gamepad instance. See the [GAMEPAD_BUTTON_UP]{@linkcode Phaser.Input.Gamepad.Events#event:GAMEPAD_BUTTON_UP} event for details. */ - const BUTTON_UP: any; + const BUTTON_UP: string; /** * The Gamepad Connected Event. @@ -49076,7 +58855,7 @@ declare namespace Phaser { * 'connected' event and instead should check `GamepadPlugin.total` to see if it thinks there are any gamepads * already connected. */ - const CONNECTED: any; + const CONNECTED: string; /** * The Gamepad Disconnected Event. @@ -49085,7 +58864,7 @@ declare namespace Phaser { * * Listen to this event from within a Scene using: `this.input.gamepad.once('disconnected', listener)`. */ - const DISCONNECTED: any; + const DISCONNECTED: string; /** * The Gamepad Button Down Event. @@ -49099,7 +58878,7 @@ declare namespace Phaser { * * You can also listen for a DOWN event from the Gamepad Plugin. See the [BUTTON_DOWN]{@linkcode Phaser.Input.Gamepad.Events#event:BUTTON_DOWN} event for details. */ - const GAMEPAD_BUTTON_DOWN: any; + const GAMEPAD_BUTTON_DOWN: string; /** * The Gamepad Button Up Event. @@ -49113,7 +58892,7 @@ declare namespace Phaser { * * You can also listen for an UP event from the Gamepad Plugin. See the [BUTTON_UP]{@linkcode Phaser.Input.Gamepad.Events#event:BUTTON_UP} event for details. */ - const GAMEPAD_BUTTON_UP: any; + const GAMEPAD_BUTTON_UP: string; } @@ -49559,12 +59338,12 @@ declare namespace Phaser { /** * A reference to the Keyboard Manager class, if enabled via the `input.keyboard` Game Config property. */ - keyboard: Phaser.Input.Keyboard.KeyboardManager; + keyboard: Phaser.Input.Keyboard.KeyboardManager | null; /** * A reference to the Mouse Manager class, if enabled via the `input.mouse` Game Config property. */ - mouse: Phaser.Input.Mouse.MouseManager; + mouse: Phaser.Input.Mouse.MouseManager | null; /** * A reference to the Touch Manager class, if enabled via the `input.touch` Game Config property. @@ -49593,7 +59372,7 @@ declare namespace Phaser { * 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. */ - mousePointer: Phaser.Input.Pointer; + mousePointer: Phaser.Input.Pointer | null; /** * The most recently active Pointer object. @@ -49776,7 +59555,7 @@ declare namespace Phaser { * An instance of the Gamepad Plugin class, if enabled via the `input.gamepad` Scene or Game Config property. * Use this to create access Gamepads connected to the browser and respond to gamepad buttons. */ - gamepad: Phaser.Input.Gamepad.GamepadPlugin; + gamepad: Phaser.Input.Gamepad.GamepadPlugin | null; /** * A reference to the Scene that this Input Plugin is responsible for. @@ -49820,7 +59599,7 @@ declare namespace Phaser { * * If you just wish to get access to the mouse pointer, use the `mousePointer` property instead. */ - mouse: Phaser.Input.Mouse.MouseManager; + mouse: Phaser.Input.Mouse.MouseManager | null; /** * When set to `true` (the default) the Input Plugin will emulate DOM behavior by only emitting events from @@ -49891,7 +59670,7 @@ declare namespace Phaser { * at any time, by passing it to `InputPlugin.enable`. * @param gameObject The Game Object to have its input system disabled. */ - disable(gameObject: Phaser.GameObjects.GameObject): void; + disable(gameObject: Phaser.GameObjects.GameObject): this; /** * Enable a Game Object for interaction. @@ -50213,6 +59992,14 @@ declare namespace Phaser { */ setDefaultCursor(cursor: string): this; + /** + * Loops through all of the Input Manager Pointer instances and calls `reset` on them. + * + * Use this function if you find that input has been stolen from Phaser via a 3rd + * party component, such as Vue, and you need to tell Phaser to reset the Pointer states. + */ + resetPointers(): void; + /** * The x coordinates of the ActivePointer based on the first camera in the camera list. * This is only safe to use if your game has just 1 non-transformed camera and doesn't use multi-touch. @@ -50306,7 +60093,7 @@ declare namespace Phaser { * An instance of the Keyboard Plugin class, if enabled via the `input.keyboard` Scene or Game Config property. * Use this to create Key objects and listen for keyboard specific events. */ - keyboard: Phaser.Input.Keyboard.KeyboardPlugin; + keyboard: Phaser.Input.Keyboard.KeyboardPlugin | null; } @@ -50477,7 +60264,7 @@ declare namespace Phaser { * For example, the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. * There are others. So, please check your extensions if you find you have specific keys that don't work. */ - const ANY_KEY_DOWN: any; + const ANY_KEY_DOWN: string; /** * The Global Key Up Event. @@ -50490,7 +60277,7 @@ declare namespace Phaser { * * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.UP]{@linkcode Phaser.Input.Keyboard.Events#event:UP} for details. */ - const ANY_KEY_UP: any; + const ANY_KEY_UP: string; /** * The Key Combo Match Event. @@ -50507,7 +60294,7 @@ declare namespace Phaser { * }); * ``` */ - const COMBO_MATCH: any; + const COMBO_MATCH: string; /** * The Key Down Event. @@ -50524,7 +60311,7 @@ declare namespace Phaser { * * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_DOWN} for details. */ - const DOWN: any; + const DOWN: string; /** * The Key Down Event. @@ -50533,7 +60320,7 @@ declare namespace Phaser { * * Unlike the `ANY_KEY_DOWN` event, this one has a special dynamic event name. For example, to listen for the `A` key being pressed * use the following from within a Scene: `this.input.keyboard.on('keydown-A', listener)`. You can replace the `-A` part of the event - * name with any valid [Key Code string]{@link Phaser.Input.Keyboard.KeyCodes}. For example, this will listen for the space bar: + * name with any valid [Key Code string]{@link Phaser.Input.Keyboard.KeyCodes}. For example, this will listen for the space bar: * `this.input.keyboard.on('keydown-SPACE', listener)`. * * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_DOWN]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_DOWN} for details. @@ -50547,7 +60334,7 @@ declare namespace Phaser { * For example, the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. * There are others. So, please check your extensions if you find you have specific keys that don't work. */ - const KEY_DOWN: any; + const KEY_DOWN: string; /** * The Key Up Event. @@ -50556,14 +60343,14 @@ declare namespace Phaser { * * Unlike the `ANY_KEY_UP` event, this one has a special dynamic event name. For example, to listen for the `A` key being released * use the following from within a Scene: `this.input.keyboard.on('keyup-A', listener)`. You can replace the `-A` part of the event - * name with any valid [Key Code string]{@link Phaser.Input.Keyboard.KeyCodes}. For example, this will listen for the space bar: + * name with any valid [Key Code string]{@link Phaser.Input.Keyboard.KeyCodes}. For example, this will listen for the space bar: * `this.input.keyboard.on('keyup-SPACE', listener)`. * * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_UP]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_UP} for details. * * Finally, you can create Key objects, which you can also listen for events from. See [Keyboard.Events.UP]{@linkcode Phaser.Input.Keyboard.Events#event:UP} for details. */ - const KEY_UP: any; + const KEY_UP: string; /** * The Key Up Event. @@ -50580,7 +60367,7 @@ declare namespace Phaser { * * You can also create a generic 'global' listener. See [Keyboard.Events.ANY_KEY_UP]{@linkcode Phaser.Input.Keyboard.Events#event:ANY_KEY_UP} for details. */ - const UP: any; + const UP: string; } @@ -50791,7 +60578,8 @@ declare namespace Phaser { * Scene to stop all input, or `this.input.keyboard.preventDefault = false` to stop a Scene halting input on another Scene. * * _Note_: Many keyboards are unable to process certain combinations of keys due to hardware limitations known as ghosting. - * See http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/ for more details. + * See http://www.html5gamedevs.com/topic/4876-impossible-to-use-more-than-2-keyboard-input-buttons-at-the-same-time/ for more details + * and use the site https://w3c.github.io/uievents/tools/key-event-viewer.html to test your n-key support in browser. * * Also please be aware that certain browser extensions can disable or override Phaser keyboard handling. * For example the Chrome extension vimium is known to disable Phaser from using the D key, while EverNote disables the backtick key. @@ -50989,14 +60777,16 @@ declare namespace Phaser { * The given argument can be either a Key object, a string, such as `A` or `SPACE`, or a key code value. * @param key Either a Key object, a string, such as `A` or `SPACE`, or a key code value. * @param destroy Call `Key.destroy` on the removed Key object? Default false. + * @param removeCapture Remove this Key from being captured? Only applies if set to capture when created. Default false. */ - removeKey(key: Phaser.Input.Keyboard.Key | string | number, destroy?: boolean): this; + removeKey(key: Phaser.Input.Keyboard.Key | string | number, destroy?: boolean, removeCapture?: boolean): this; /** * Removes all Key objects created by _this_ Keyboard Plugin. * @param destroy Call `Key.destroy` on each removed Key object? Default false. + * @param removeCapture Remove all key captures for Key objects owened by this plugin? Default false. */ - removeAllKeys(destroy?: boolean): this; + removeAllKeys(destroy?: boolean, removeCapture?: boolean): this; /** * Creates a new KeyCombo. @@ -51208,6 +60998,8 @@ declare namespace Phaser { /** * Resets this Key object back to its default un-pressed state. + * + * As of version 3.60.0 it no longer resets the `enabled` or `preventDefault` flags. */ reset(): this; @@ -51216,7 +61008,7 @@ declare namespace Phaser { * * 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, + * To get the duration the Key was held down for in the previous up-down cycle, * use the `Key.duration` property value instead. */ getDuration(): number; @@ -51864,11 +61656,11 @@ declare namespace Phaser { readonly isTop: boolean; /** - * Attempts to disable the context menu from appearing if you right-click on the browser. + * Attempts to disable the context menu from appearing if you right-click on the game canvas, or specified input target. * * 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 + * Use this if you need to enable right-button mouse support in your game, and the context * menu keeps getting in the way. */ disableContextMenu(): this; @@ -52355,6 +62147,11 @@ declare namespace Phaser { */ getInterpolatedPosition(steps?: number, out?: any[]): any[]; + /** + * Fully reset this Pointer back to its unitialized state. + */ + reset(): void; + /** * Destroys this Pointer instance and resets its external references. */ @@ -52463,16 +62260,13 @@ declare namespace Phaser { onTouchCancelWindow: Function; /** - * The Touch Over event handler function. - * Initially empty and bound in the `startListeners` method. - */ - onTouchOver: Function; - - /** - * The Touch Out event handler function. - * Initially empty and bound in the `startListeners` method. + * 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. */ - onTouchOut: Function; + readonly isTop: boolean; /** * Attempts to disable the context menu from appearing if you touch-hold on the browser. @@ -52541,7 +62335,7 @@ declare namespace Phaser { var LOADER_DESTROYED: number; /** - * File is in the load queue but not yet started + * File is in the load queue but not yet started. */ var FILE_PENDING: number; @@ -52551,12 +62345,12 @@ declare namespace Phaser { var FILE_LOADING: number; /** - * File has loaded successfully, awaiting processing + * File has loaded successfully, awaiting processing. */ var FILE_LOADED: number; /** - * File failed to load + * File failed to load. */ var FILE_FAILED: number; @@ -52576,15 +62370,20 @@ declare namespace Phaser { var FILE_COMPLETE: number; /** - * File has been destroyed + * File has been destroyed. */ var FILE_DESTROYED: number; /** - * File was populated from local data and doesn't need an HTTP request + * File was populated from local data and doesn't need an HTTP request. */ var FILE_POPULATED: number; + /** + * File is pending being destroyed. + */ + var FILE_PENDING_DESTROY: number; + namespace Events { /** * The Loader Plugin Add File Event. @@ -52595,7 +62394,7 @@ declare namespace Phaser { * * If you add lots of files to a Loader from a `preload` method, it will dispatch this event for each one of them. */ - const ADD: any; + const ADD: string; /** * The Loader Plugin Complete Event. @@ -52605,18 +62404,20 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.load.on('complete', listener)`. */ - const COMPLETE: any; + const COMPLETE: string; /** * The File Load Complete Event. * - * This event is dispatched by the Loader Plugin when any file in the queue finishes loading. + * This event is dispatched by the Loader Plugin when _any_ file in the queue finishes loading. * * Listen to it from a Scene using: `this.load.on('filecomplete', listener)`. * + * Make sure you remove this listener when you have finished, or it will continue to fire if the Scene reloads. + * * You can also listen for the completion of a specific file. See the [FILE_KEY_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_KEY_COMPLETE} event. */ - const FILE_COMPLETE: any; + const FILE_COMPLETE: string; /** * The File Load Complete Event. @@ -52637,7 +62438,7 @@ declare namespace Phaser { * Or, if you have loaded a texture `atlas` with a key of `Level1`: * * ```javascript - * this.load.on('filecomplete-atlas-Level1', function (key, type, data) { + * this.load.on('filecomplete-atlasjson-Level1', function (key, type, data) { * // Your handler code * }); * ``` @@ -52650,9 +62451,11 @@ declare namespace Phaser { * }); * ``` * + * Make sure you remove your listeners when you have finished, or they will continue to fire if the Scene reloads. + * * You can also listen for the generic completion of files. See the [FILE_COMPLETE]{@linkcode Phaser.Loader.Events#event:FILE_COMPLETE} event. */ - const FILE_KEY_COMPLETE: any; + const FILE_KEY_COMPLETE: string; /** * The File Load Error Event. @@ -52661,7 +62464,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.load.on('loaderror', listener)`. */ - const FILE_LOAD_ERROR: any; + const FILE_LOAD_ERROR: string; /** * The File Load Event. @@ -52671,7 +62474,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.load.on('load', listener)`. */ - const FILE_LOAD: any; + const FILE_LOAD: string; /** * The File Load Progress Event. @@ -52681,7 +62484,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.load.on('fileprogress', listener)`. */ - const FILE_PROGRESS: any; + const FILE_PROGRESS: string; /** * The Loader Plugin Post Process Event. @@ -52694,7 +62497,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.load.on('postprocess', listener)`. */ - const POST_PROCESS: any; + const POST_PROCESS: string; /** * The Loader Plugin Progress Event. @@ -52703,7 +62506,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.load.on('progress', listener)`. */ - const PROGRESS: any; + const PROGRESS: string; /** * The Loader Plugin Start Event. @@ -52714,7 +62517,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.load.on('start', listener)`. */ - const START: any; + const START: string; } @@ -52773,7 +62576,7 @@ declare namespace Phaser { /** * The XMLHttpRequest instance (as created by XHR Loader) that is loading this File. */ - xhrLoader: XMLHttpRequest; + xhrLoader: XMLHttpRequest | null; /** * The current state of the file. One of the FILE_CONST values. @@ -52818,14 +62621,14 @@ declare namespace Phaser { * If this is a multipart file, i.e. an atlas and its json together, then this is a reference * to the parent MultiFile. Set and used internally by the Loader or specific file types. */ - multiFile: Phaser.Loader.MultiFile; + multiFile: Phaser.Loader.MultiFile | null; /** * Does this file have an associated linked file? Such as an image and a normal map. * Atlases and Bitmap Fonts use the multiFile, because those files need loading together but aren't * actually bound by data, where-as a linkFile is. */ - linkFile: Phaser.Loader.File; + linkFile: Phaser.Loader.File | null; /** * Links this File with another, so they depend upon each other for loading and processing. @@ -53055,7 +62858,7 @@ declare namespace Phaser { * @param xhrSettings Extra XHR Settings specifically for this file. * @param audioContext The AudioContext this file will use to process itself. */ - constructor(loader: Phaser.Loader.LoaderPlugin, key: string | Phaser.Types.Loader.FileTypes.AudioFileConfig, urlConfig?: any, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject, audioContext?: AudioContext); + constructor(loader: Phaser.Loader.LoaderPlugin, key: string | Phaser.Types.Loader.FileTypes.AudioFileConfig, urlConfig?: Phaser.Types.Loader.FileTypes.AudioFileURLConfig, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject, audioContext?: AudioContext); /** * Called automatically by Loader.nextFile. @@ -53150,6 +62953,41 @@ declare namespace Phaser { } + /** + * A Compressed Texture File suitable for loading by the Loader. + * + * These are created when you use the Phaser.Loader.LoaderPlugin#texture method and are not typically created directly. + * + * For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#texture. + */ + class CompressedTextureFile extends Phaser.Loader.MultiFile { + /** + * + * @param loader A reference to the Loader that is responsible for this file. + * @param key The key to use for this file. + * @param entry The compressed texture file entry to load. + * @param xhrSettings Extra XHR Settings specifically for this file. + */ + constructor(loader: Phaser.Loader.LoaderPlugin, key: string, entry: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject); + + /** + * Called by each File when it finishes loading. + * @param file The File that has completed processing. + */ + onFileComplete(file: Phaser.Loader.File): void; + + /** + * Adds this file to its target cache upon successful loading and processing. + */ + addToCache(): void; + + /** + * Adds all of the multi-file entties to their target caches upon successful loading and processing. + */ + addMultiToCache(): void; + + } + /** * A single CSS File suitable for loading by the Loader. * @@ -53474,11 +63312,11 @@ declare namespace Phaser { * * @param loader A reference to the Loader that is responsible for this file. * @param key The key to use for this file, or a file configuration object. - * @param 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". + * @param url The absolute or relative URL to load this file from or a ready formed JSON object. If undefined or `null` it will be set to `.json`, i.e. if `key` was "alien" then the URL will be "alien.json". * @param xhrSettings Extra XHR Settings specifically for this file. * @param dataKey When the JSON file loads only this property will be stored in the Cache. */ - constructor(loader: Phaser.Loader.LoaderPlugin, key: string | Phaser.Types.Loader.FileTypes.PackFileConfig, url?: string, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject, dataKey?: string); + constructor(loader: Phaser.Loader.LoaderPlugin, key: string | Phaser.Types.Loader.FileTypes.PackFileConfig, url?: string | any, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject, dataKey?: string); /** * Called automatically by Loader.nextFile. @@ -53585,9 +63423,10 @@ declare namespace Phaser { * @param loader A reference to the Loader that is responsible for this file. * @param key The key to use for this file, or a file configuration object. * @param 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 type The script type. Should be either 'script' for classic JavaScript, or 'module' if the file contains an exported module. Default 'script'. * @param xhrSettings Extra XHR Settings specifically for this file. */ - constructor(loader: Phaser.Loader.LoaderPlugin, key: string | Phaser.Types.Loader.FileTypes.ScriptFileConfig, url?: string, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject); + constructor(loader: Phaser.Loader.LoaderPlugin, key: string | Phaser.Types.Loader.FileTypes.ScriptFileConfig, url?: string, type?: string, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject); /** * Called automatically by Loader.nextFile. @@ -53794,13 +63633,10 @@ declare namespace Phaser { * * @param loader A reference to the Loader that is responsible for this file. * @param key The key to use for this file, or a file configuration object. - * @param urlConfig The absolute or relative URL to load this file from in a config object. - * @param loadEvent The load event to listen for when _not_ loading as a blob. Either 'loadeddata', 'canplay' or 'canplaythrough'. - * @param asBlob Load the video as a data blob, or via the Video element? - * @param noAudio Does the video have an audio track? If not you can enable auto-playing on it. - * @param xhrSettings Extra XHR Settings specifically for this file. + * @param urls The absolute or relative URL to load the video files from. + * @param noAudio Does the video have an audio track? If not you can enable auto-playing on it. Default false. */ - constructor(loader: Phaser.Loader.LoaderPlugin, key: string | Phaser.Types.Loader.FileTypes.VideoFileConfig, urlConfig?: any, loadEvent?: string, asBlob?: boolean, noAudio?: boolean, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject); + constructor(loader: Phaser.Loader.LoaderPlugin, key: string | Phaser.Types.Loader.FileTypes.VideoFileConfig, urls?: string | string[] | Phaser.Types.Loader.FileTypes.VideoFileURLConfig | Phaser.Types.Loader.FileTypes.VideoFileURLConfig[], noAudio?: boolean); /** * Called automatically by Loader.nextFile. @@ -54146,7 +63982,16 @@ declare namespace Phaser { * its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details. * * Phaser expects the atlas data to be provided in a JSON file, using either the JSON Hash or JSON Array format. - * These files are created by software such as Texture Packer, Shoebox and Adobe Flash / Animate. + * + * These files are created by software such as: + * + * * [Texture Packer](https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?source=photonstorm) + * * [Shoebox](https://renderhjs.net/shoebox/) + * * [Gamma Texture Packer](https://gammafp.com/tool/atlas-packer/) + * * [Adobe Flash / Animate](https://www.adobe.com/uk/products/animate.html) + * * [Free Texture Packer](http://free-tex-packer.com/) + * * [Leshy SpriteSheet Tool](https://www.leshylabs.com/apps/sstool/) + * * If you are using Texture Packer and have enabled multi-atlas support, then please use the Phaser Multi Atlas loader * instead of this one. * @@ -54369,7 +64214,7 @@ declare namespace Phaser { * @param config An object containing an `instances` property for HTML5Audio. Defaults to 1. * @param xhrSettings An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. */ - audio(key: string | Phaser.Types.Loader.FileTypes.AudioFileConfig | Phaser.Types.Loader.FileTypes.AudioFileConfig[], urls?: string | string[], config?: any, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject): this; + audio(key: string | Phaser.Types.Loader.FileTypes.AudioFileConfig | Phaser.Types.Loader.FileTypes.AudioFileConfig[], urls?: string | string[] | Phaser.Types.Loader.FileTypes.AudioFileURLConfig | Phaser.Types.Loader.FileTypes.AudioFileURLConfig[], config?: any, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject): this; /** * Adds a JSON based Audio Sprite, or array of audio sprites, to the current load queue. @@ -54624,6 +64469,140 @@ declare namespace Phaser { */ bitmapFont(key: string | Phaser.Types.Loader.FileTypes.BitmapFontFileConfig | Phaser.Types.Loader.FileTypes.BitmapFontFileConfig[], textureURL?: string | string[], fontDataURL?: string, textureXhrSettings?: Phaser.Types.Loader.XHRSettingsObject, fontDataXhrSettings?: Phaser.Types.Loader.XHRSettingsObject): this; + /** + * Adds a Compressed Texture file to the current load queue. This feature is WebGL only. + * + * This method takes a key and a configuration object, which lists the different formats + * and files associated with them. + * + * The texture format object should be ordered in GPU priority order, with IMG as the last entry. + * + * You can call this method from within your Scene's `preload`, along with any other files you wish to load: + * + * ```javascript + * preload () + * { + * this.load.texture('yourPic', { + * ASTC: { type: 'PVR', textureURL: 'pic-astc-4x4.pvr' }, + * PVRTC: { type: 'PVR', textureURL: 'pic-pvrtc-4bpp-rgba.pvr' }, + * S3TC: { type: 'PVR', textureURL: 'pic-dxt5.pvr' }, + * IMG: { textureURL: 'pic.png' } + * }); + * ``` + * + * If you wish to load a texture atlas, provide the `atlasURL` property: + * + * ```javascript + * preload () + * { + * const path = 'assets/compressed'; + * + * this.load.texture('yourAtlas', { + * 'ASTC': { type: 'PVR', textureURL: `${path}/textures-astc-4x4.pvr`, atlasURL: `${path}/textures.json` }, + * 'PVRTC': { type: 'PVR', textureURL: `${path}/textures-pvrtc-4bpp-rgba.pvr`, atlasURL: `${path}/textures-pvrtc-4bpp-rgba.json` }, + * 'S3TC': { type: 'PVR', textureURL: `${path}/textures-dxt5.pvr`, atlasURL: `${path}/textures-dxt5.json` }, + * 'IMG': { textureURL: `${path}/textures.png`, atlasURL: `${path}/textures.json` } + * }); + * } + * ``` + * + * If you wish to load a Multi Atlas, as exported from Texture Packer Pro, use the `multiAtlasURL` property instead: + * + * ```javascript + * preload () + * { + * const path = 'assets/compressed'; + * + * this.load.texture('yourAtlas', { + * 'ASTC': { type: 'PVR', atlasURL: `${path}/textures.json` }, + * 'PVRTC': { type: 'PVR', atlasURL: `${path}/textures-pvrtc-4bpp-rgba.json` }, + * 'S3TC': { type: 'PVR', atlasURL: `${path}/textures-dxt5.json` }, + * 'IMG': { atlasURL: `${path}/textures.json` } + * }); + * } + * ``` + * + * When loading a Multi Atlas you do not need to specify the `textureURL` property as it will be read from the JSON file. + * + * Instead of passing arguments you can pass a configuration object, such as: + * + * ```javascript + * this.load.texture({ + * key: 'yourPic', + * url: { + * ASTC: { type: 'PVR', textureURL: 'pic-astc-4x4.pvr' }, + * PVRTC: { type: 'PVR', textureURL: 'pic-pvrtc-4bpp-rgba.pvr' }, + * S3TC: { type: 'PVR', textureURL: 'pic-dxt5.pvr' }, + * IMG: { textureURL: 'pic.png' } + * } + * }); + * ``` + * + * See the documentation for `Phaser.Types.Loader.FileTypes.CompressedTextureFileConfig` for more details. + * + * The number of formats you provide to this function is up to you, but you should ensure you + * cover the primary platforms where appropriate. + * + * The 'IMG' entry is a fallback to a JPG or PNG, should the browser be unable to load any of the other + * formats presented to this function. You should really always include this, although it is optional. + * + * Phaser supports loading both the PVR and KTX container formats. Within those, it can parse + * the following texture compression formats: + * + * ETC + * ETC1 + * ATC + * ASTC + * BPTC + * RGTC + * PVRTC + * S3TC + * S3TCSRGB + * + * For more information about the benefits of compressed textures please see the + * following articles: + * + * Texture Compression in 2020 (https://aras-p.info/blog/2020/12/08/Texture-Compression-in-2020/) + * Compressed GPU Texture Formats (https://themaister.net/blog/2020/08/12/compressed-gpu-texture-formats-a-review-and-compute-shader-decoders-part-1/) + * + * To create compressed texture files use a 3rd party application such as: + * + * Texture Packer (https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?utm_source=ad&utm_medium=banner&utm_campaign=phaser-2018-10-16) + * PVRTexTool (https://developer.imaginationtech.com/pvrtextool/) - available for Windows, macOS and Linux. + * Mali Texture Compression Tool (https://developer.arm.com/tools-and-software/graphics-and-gaming/mali-texture-compression-tool) + * ASTC Encoder (https://github.com/ARM-software/astc-encoder) + * + * ASTCs must have a Channel Type of Unsigned Normalized Bytes (UNorm) and a Linear RGB Color Space. + * + * 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 Texture Manager upon a successful load. + * The key should be unique both in terms of files being loaded and files already present in the Texture Manager. + * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file + * then remove it from the Texture Manager first, before loading a new one. + * + * 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 `Data` the final key will be `LEVEL1.Data` and + * this is what you would use to retrieve the text from the Texture Manager. + * + * The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it. + * + * Unlike other file loaders in Phaser, the URLs must include the file extension. + * + * Note: The ability to load this type of file will only be available if the Compressed Texture File type has been built into Phaser. + * It is available in the default build but can be excluded from custom builds. + * @param key The key to use for this file, or a file configuration object, or array of them. + * @param url The compressed texture configuration object. Not required if passing a config object as the `key` parameter. + * @param xhrSettings An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. + */ + texture(key: string | Phaser.Types.Loader.FileTypes.CompressedTextureFileConfig | Phaser.Types.Loader.FileTypes.CompressedTextureFileConfig[], url?: Phaser.Types.Loader.FileTypes.CompressedTextureFileConfig, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject): this; + /** * Adds a CSS file, or array of CSS files, to the current load queue. * @@ -54956,6 +64935,10 @@ declare namespace Phaser { * The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings. * Normal maps are a WebGL only feature. * + * In Phaser 3.60 a new property was added that allows you to control how images are loaded. By default, images are loaded via XHR as Blobs. + * However, you can set `loader.imageLoadType: "HTMLImageElement"` in the Game Configuration and instead, the Loader will load all images + * via the Image tag instead. + * * Note: The ability to load this type of file will only be available if the Image File type has been built into Phaser. * It is available in the default build but can be excluded from custom builds. * @param key The key to use for this file, or a file configuration object, or array of them. @@ -55596,6 +65579,15 @@ declare namespace Phaser { * } * ``` * + * If the script file contains a module, then you should specify that using the 'type' parameter: + * + * ```javascript + * function preload () + * { + * this.load.script('aliens', 'lib/aliens.js', 'module'); + * } + * ``` + * * 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 @@ -55611,7 +65603,8 @@ declare namespace Phaser { * ```javascript * this.load.script({ * key: 'aliens', - * url: 'lib/aliens.js' + * url: 'lib/aliens.js', + * type: 'script' // or 'module' * }); * ``` * @@ -55632,9 +65625,10 @@ declare namespace Phaser { * It is available in the default build but can be excluded from custom builds. * @param key The key to use for this file, or a file configuration object, or array of them. * @param 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 type The script type. Should be either 'script' for classic JavaScript, or 'module' if the file contains an exported module. Default 'script'. * @param xhrSettings An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. */ - script(key: string | Phaser.Types.Loader.FileTypes.ScriptFileConfig | Phaser.Types.Loader.FileTypes.ScriptFileConfig[], url?: string, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject): this; + script(key: string | Phaser.Types.Loader.FileTypes.ScriptFileConfig | Phaser.Types.Loader.FileTypes.ScriptFileConfig[], url?: string, type?: string, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject): this; /** * Adds a Sprite Sheet Image, or array of Sprite Sheet Images, to the current load queue. @@ -56231,7 +66225,6 @@ declare namespace Phaser { * this.load.video({ * key: 'intro', * url: [ 'video/level1.mp4', 'video/level1.webm', 'video/level1.mov' ], - * asBlob: false, * noAudio: true * }); * ``` @@ -56251,12 +66244,9 @@ declare namespace Phaser { * It is available in the default build but can be excluded from custom builds. * @param key The key to use for this file, or a file configuration object, or array of them. * @param urls The absolute or relative URL to load the video files from. - * @param loadEvent The load event to listen for when _not_ loading as a blob. Either `loadeddata`, `canplay` or `canplaythrough`. Default 'loadeddata'. - * @param asBlob Load the video as a data blob, or stream it via the Video element? Default false. * @param noAudio Does the video have an audio track? If not you can enable auto-playing on it. Default false. - * @param xhrSettings An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings. */ - video(key: string | Phaser.Types.Loader.FileTypes.VideoFileConfig | Phaser.Types.Loader.FileTypes.VideoFileConfig[], urls?: string | string[], loadEvent?: string, asBlob?: boolean, noAudio?: boolean, xhrSettings?: Phaser.Types.Loader.XHRSettingsObject): this; + video(key: string | Phaser.Types.Loader.FileTypes.VideoFileConfig | Phaser.Types.Loader.FileTypes.VideoFileConfig[], urls?: string | string[] | Phaser.Types.Loader.FileTypes.VideoFileURLConfig | Phaser.Types.Loader.FileTypes.VideoFileURLConfig[], noAudio?: boolean): this; /** * Adds an XML file, or array of XML files, to the current load queue. @@ -56401,6 +66391,19 @@ declare namespace Phaser { */ crossOrigin: string; + /** + * Optional load type for image files. `XHR` is the default. Set to `HTMLImageElement` to load images using the Image tag instead. + */ + imageLoadType: string; + + /** + * An array of all schemes that the Loader considers as being 'local'. + * + * This is populated by the `Phaser.Core.Config#loaderLocalScheme` game configuration setting and defaults to + * `[ 'file://', 'capacitor://' ]`. Additional local schemes can be added to this array as needed. + */ + localSchemes: string[]; + /** * The total number of files to load. It may not always be accurate because you may add to the Loader during the process * of loading, especially if you load a Pack File. Therefore this value can change, but in most cases remains static. @@ -56697,6 +66700,11 @@ declare namespace Phaser { */ files: Phaser.Loader.File[]; + /** + * The current state of the file. One of the FILE_CONST values. + */ + state: number; + /** * The completion status of this MultiFile. */ @@ -56758,6 +66766,19 @@ declare namespace Phaser { */ onFileFailed(file: Phaser.Loader.File): void; + /** + * Called once all children of this multi file have been added to their caches and is now + * ready for deletion from the Loader. + * + * It will emit a `filecomplete` event from the LoaderPlugin. + */ + pendingDestroy(): void; + + /** + * Destroy this Multi File and any references it holds. + */ + destroy(): void; + } /** @@ -56958,6 +66979,10 @@ declare namespace Phaser { /** * The value of PI * 0.5. + * + * Yes, we understand that this should actually be PI * 2, but + * it has been like this for so long we can't change it now. + * If you need PI * 2, use the PI2 constant instead. */ var TAU: number; @@ -57491,6 +67516,16 @@ declare namespace Phaser { */ function Linear(p0: number, p1: number, t: number): number; + /** + * Interpolates two given Vectors and returns a new Vector between them. + * + * Does not modify either of the passed Vectors. + * @param vector1 Starting vector + * @param vector2 Ending vector + * @param t The percentage between vector1 and vector2 to return, represented as a number between 0 and 1. Default 0. + */ + function LinearXY(vector1: Phaser.Math.Vector2, vector2: Phaser.Math.Vector2, t?: number): Phaser.Math.Vector2; + /** * A three-dimensional matrix. * @@ -58545,8 +68580,8 @@ declare namespace Phaser { class Vector2 { /** * - * @param x The x component, or an object with `x` and `y` properties. - * @param y The y component. + * @param x The x component, or an object with `x` and `y` properties. Default 0. + * @param y The y component. Default x. */ constructor(x?: number | Phaser.Types.Math.Vector2Like, y?: number); @@ -58769,6 +68804,12 @@ declare namespace Phaser { */ rotate(delta: number): Phaser.Math.Vector2; + /** + * Project this Vector onto another. + * @param src The vector to project onto. + */ + project(src: Phaser.Math.Vector2): Phaser.Math.Vector2; + /** * A static zero Vector2 for use by reference. * @@ -59336,7 +69377,7 @@ declare namespace Phaser { function Within(a: number, b: number, tolerance: number): boolean; /** - * Wrap the given `value` between `min` and `max. + * Wrap the given `value` between `min` and `max`. * @param value The value to wrap. * @param min The minimum value. * @param max The maximum value. @@ -59434,7 +69475,11 @@ declare namespace Phaser { */ yoyo?: boolean; /** - * Should sprite.visible = true when the animation starts to play? + * If this animation has a delay, should it show the first frame immediately (true), or only after the delay (false) + */ + showBeforeDelay?: boolean; + /** + * Should sprite.visible = true when the animation starts to play? This happens _after_ any delay, if set. */ showOnStart?: boolean; /** @@ -59557,6 +69602,10 @@ declare namespace Phaser { * Should the animation yoyo? (reverse back down to the start) before repeating? */ yoyo: boolean; + /** + * If this animation has a delay, should it show the first frame immediately (true), or only after the delay (false) + */ + showBeforeDelay: boolean; /** * Should sprite.visible = true when the animation starts to play? */ @@ -59622,6 +69671,10 @@ declare namespace Phaser { * Should the animation yoyo? (reverse back down to the start) before repeating? */ yoyo?: boolean; + /** + * If this animation has a delay, should it show the first frame immediately (true), or only after the delay (false) + */ + showBeforeDelay?: boolean; /** * Should sprite.visible = true when the animation starts to play? */ @@ -59692,7 +69745,7 @@ declare namespace Phaser { /** * Defines the Camera bounds. */ - bounds?: object; + bounds?: object | null; /** * The top-left extent of the Camera bounds. */ @@ -59971,6 +70024,10 @@ declare namespace Phaser { * The optimum rendering rate, in frames per second. This does not enforce the fps rate, it merely tells Phaser what rate is considered optimal for this game. */ target?: number; + /** + * Enforces an fps rate limit that the game step will run at, regardless of browser frequency. 0 means 'no limit'. Never set this higher than RAF can handle. + */ + limit?: number; /** * Use setTimeout instead of requestAnimationFrame to run the game loop. */ @@ -60006,6 +70063,10 @@ declare namespace Phaser { * Which renderer to use. Phaser.AUTO, Phaser.CANVAS, Phaser.HEADLESS, or Phaser.WEBGL. AUTO picks WEBGL if available, otherwise CANVAS. */ type?: number; + /** + * `true` or `1` = Use the built-in StableSort (needed for older browsers), `false` or `0` = Rely on ES2019 Array.sort being stable (modern browsers only), or `-1` = Try and determine this automatically based on browser inspection (not guaranteed to work, errs on side of caution). + */ + stableSort?: number | boolean; /** * The DOM element that will contain the game canvas, or its `id`. If undefined, or if the named element doesn't exist, the game canvas is appended to the document body. If `null` no parent will be used and you are responsible for adding the canvas to the dom. */ @@ -60029,7 +70090,7 @@ declare namespace Phaser { /** * A scene or scenes to add to the game. If several are given, the first is started; the remainder are started only if they have `{ active: true }`. See the `sceneConfig` argument in `Phaser.Scenes.SceneManager#add`. */ - scene?: Phaser.Scene | Phaser.Scene[] | Phaser.Types.Scenes.SettingsConfig | Phaser.Types.Scenes.SettingsConfig[] | Phaser.Types.Scenes.CreateSceneFromObjectConfig | Phaser.Types.Scenes.CreateSceneFromObjectConfig[] | Function | Function[]; + scene?: Phaser.Types.Scenes.SceneType | Phaser.Types.Scenes.SceneType[]; /** * Seed for the random number generator. */ @@ -60170,6 +70231,46 @@ declare namespace Phaser { * The mipmap magFilter to be used when creating WebGL textures. */ mipmapFilter?: string; + /** + * Automatically enable the Mobile Pipeline if iOS or Android detected? + */ + autoMobilePipeline?: boolean; + /** + * The WebGL Pipeline that Game Objects will use by default. Set to 'MultiPipeline' as standard. + */ + defaultPipeline?: string; + /** + * Is the Scale Manager allowed to adjust the CSS height property of the parent and/or document body to be 100%? + */ + expandParent?: boolean; + /** + * The scale mode. + */ + mode?: Phaser.Scale.ScaleModeType; + /** + * The minimum width and height the canvas can be scaled down to. + */ + min?: WidthHeight; + /** + * The maximum width the canvas can be scaled up to. + */ + max?: WidthHeight; + /** + * Automatically round the display and style sizes of the canvas. This can help with performance in lower-powered devices. + */ + autoRound?: boolean; + /** + * Automatically center the canvas within the parent? + */ + autoCenter?: Phaser.Scale.CenterType; + /** + * How many ms should elapse before checking if the browser size has changed? + */ + resizeInterval?: number; + /** + * The DOM element that will be sent into full screen mode, or its `id`. If undefined Phaser will create its own div and insert the canvas into it when entering fullscreen mode. + */ + fullscreenTarget?: HTMLElement | string | null; }; type GamepadInputConfig = { @@ -60233,7 +70334,7 @@ declare namespace Phaser { /** * `preventDefault` will be called on every non-modified key which has a key code in this array. By default it is empty. */ - capture?: number[]; + capture?: number[] | null; }; type LoaderConfig = { @@ -60273,6 +70374,10 @@ declare namespace Phaser { * Optional XHR timeout value, in ms. */ timeout?: number; + /** + * An optional array of schemes that the Loader considers as being 'local' files. Defaults to: `[ 'file://', 'capacitor://' ]` if not specified. + */ + localScheme?: string[]; }; type MouseInputConfig = { @@ -60327,17 +70432,21 @@ declare namespace Phaser { * The pipeline class. This should be a constructable object, **not** an instance of a class. */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * Sets the `PipelineManager.frameInc` value to control the dimension increase in the Render Targets. + */ + frameInc?: number; }; type PluginObject = { /** * Global plugins to install. */ - global?: Phaser.Types.Core.PluginObjectItem[]; + global?: Phaser.Types.Core.PluginObjectItem[] | null; /** * Scene plugins to install. */ - scene?: Phaser.Types.Core.PluginObjectItem[]; + scene?: Phaser.Types.Core.PluginObjectItem[] | null; /** * The default set of scene plugins (names). */ @@ -60444,6 +70553,14 @@ declare namespace Phaser { * The WebGL Pipeline configuration object. */ pipeline?: Phaser.Types.Core.PipelineConfig; + /** + * Automatically enable the Mobile Pipeline if iOS or Android detected? + */ + autoMobilePipeline?: boolean; + /** + * The WebGL Pipeline that Game Objects will use by default. Set to 'MultiPipeline' as standard. + */ + defaultPipeline?: string; }; type ScaleConfig = { @@ -60462,7 +70579,7 @@ declare namespace Phaser { /** * The DOM element that will contain the game canvas, or its `id`. If undefined, or if the named element doesn't exist, the game canvas is inserted directly into the document body. If `null` no parent will be used and you are responsible for adding the canvas to your environment. */ - parent?: HTMLElement | string; + parent?: HTMLElement | string | null; /** * Is the Scale Manager allowed to adjust the CSS height property of the parent and/or document body to be 100%? */ @@ -60494,10 +70611,10 @@ declare namespace Phaser { /** * The DOM element that will be sent into full screen mode, or its `id`. If undefined Phaser will create its own div and insert the canvas into it when entering fullscreen mode. */ - fullscreenTarget?: HTMLElement | string; + fullscreenTarget?: HTMLElement | string | null; }; - type TimeStepCallback = (time: number, average: number, interpolation: number)=>void; + type TimeStepCallback = (time: number, average: number)=>void; type TouchInputConfig = { /** @@ -60763,6 +70880,10 @@ declare namespace Phaser { * The alpha color value in the range 0 to 255. */ a: number; + /** + * The combined color value. + */ + color: number; }; type HSVColorObject = { @@ -60903,9 +71024,13 @@ declare namespace Phaser { */ type BitmapTextCharacter = { /** - * The index of this character within the BitmapText text string. + * The index of this character within the BitmapText wrapped text string. */ i: number; + /** + * The index of this character within the BitmapText text string. + */ + idx: number; /** * The character. */ @@ -61049,7 +71174,7 @@ declare namespace Phaser { */ h: number; /** - * The index of the word within the line. + * The index of the first character of this word within the entire string. Note: this index factors in spaces, quotes, carriage-returns, etc. */ i: number; /** @@ -61097,7 +71222,7 @@ declare namespace Phaser { data: any; }; - type DisplayCallback = (display: Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig)=>void; + type DisplayCallback = (display: Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig)=>Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig; /** * The position and size of the Bitmap Text in global space, taking into account the Game Object's scale and world position. @@ -61138,6 +71263,10 @@ declare namespace Phaser { * Adds / Removes spacing between characters. */ letterSpacing: number; + /** + * Adds / Removes spacing between lines in multi-line text. + */ + lineSpacing: number; /** * The alignment of the text in a multi-line BitmapText object. */ @@ -61230,6 +71359,16 @@ declare namespace Phaser { } + namespace Container { + type ContainerConfig = Phaser.Types.GameObjects.GameObjectConfig & { + /** + * An optional array of Game Objects to add to the Container. + */ + children?: Phaser.GameObjects.GameObject[]; + }; + + } + namespace Graphics { /** * Graphics fill style settings. @@ -61279,19 +71418,19 @@ declare namespace Phaser { type RoundedRectRadius = { /** - * Top left corner radius. + * Top left corner radius. Draw concave arc if this radius is negative. */ tl?: number; /** - * Top right corner radius. + * Top right corner radius. Draw concave arc if this radius is negative. */ tr?: number; /** - * Bottom right corner radius. + * Bottom right corner radius. Draw concave arc if this radius is negative. */ br?: number; /** - * Bottom left corner radius. + * Bottom left corner radius. Draw concave arc if this radius is negative. */ bl?: number; }; @@ -61315,47 +71454,49 @@ declare namespace Phaser { namespace Group { type GroupCallback = (item: Phaser.GameObjects.GameObject)=>void; + type GroupClassTypeConstructor = (scene: Phaser.Scene, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | number)=>void; + type GroupConfig = { /** * Sets {@link Phaser.GameObjects.Group#classType}. */ - classType?: Function; + classType?: Function | null; /** * Sets {@link Phaser.GameObjects.Group#name}. */ - name?: string; + name?: string | null; /** * Sets {@link Phaser.GameObjects.Group#active}. */ - active?: boolean; + active?: boolean | null; /** * Sets {@link Phaser.GameObjects.Group#maxSize}. */ - maxSize?: number; + maxSize?: number | null; /** * Sets {@link Phaser.GameObjects.Group#defaultKey}. */ - defaultKey?: string; + defaultKey?: string | null; /** * Sets {@link Phaser.GameObjects.Group#defaultFrame}. */ - defaultFrame?: string | number; + defaultFrame?: string | number | null; /** * Sets {@link Phaser.GameObjects.Group#runChildUpdate}. */ - runChildUpdate?: boolean; + runChildUpdate?: boolean | null; /** * Sets {@link Phaser.GameObjects.Group#createCallback}. */ - createCallback?: Phaser.Types.GameObjects.Group.GroupCallback; + createCallback?: Phaser.Types.GameObjects.Group.GroupCallback | null; /** * Sets {@link Phaser.GameObjects.Group#removeCallback}. */ - removeCallback?: Phaser.Types.GameObjects.Group.GroupCallback; + removeCallback?: Phaser.Types.GameObjects.Group.GroupCallback | null; /** * Sets {@link Phaser.GameObjects.Group#createMultipleCallback}. */ - createMultipleCallback?: Phaser.Types.GameObjects.Group.GroupMultipleCreateCallback; + createMultipleCallback?: Phaser.Types.GameObjects.Group.GroupMultipleCreateCallback | null; }; /** @@ -61369,172 +71510,254 @@ declare namespace Phaser { */ type GroupCreateConfig = { /** - * The class of each new Game Object. + * The texture key of each new Game Object. Must be provided or not objects will be created. */ - classType?: Function; + key: string | string[]; /** - * The texture key of each new Game Object. + * The class of each new Game Object. */ - key?: string | string[]; + classType?: Function | null; /** * The texture frame of each new Game Object. */ - frame?: string | string[] | number | number[]; + frame?: string | string[] | number | number[] | null; /** * The number of Game Objects to create. If set, this overrides the `frameQuantity` value. Use `frameQuantity` for more advanced control. */ - quantity?: number; + quantity?: number | null; /** * The visible state of each new Game Object. */ - visible?: boolean; + visible?: boolean | null; /** * The active state of each new Game Object. */ - active?: boolean; + active?: boolean | null; /** * The number of times each `key` × `frame` combination will be *repeated* (after the first combination). */ - repeat?: number; + repeat?: number | null; /** * Select a `key` at random. */ - randomKey?: boolean; + randomKey?: boolean | null; /** * Select a `frame` at random. */ - randomFrame?: boolean; + randomFrame?: boolean | null; /** * Select keys and frames by moving forward then backward through `key` and `frame`. */ - yoyo?: boolean; + yoyo?: boolean | null; /** * The number of times each `frame` should be combined with one `key`. */ - frameQuantity?: number; + frameQuantity?: number | null; /** * The maximum number of new Game Objects to create. 0 is no maximum. */ - max?: number; - setXY?: object; + max?: number | null; + setXY?: object | null; /** * The horizontal position of each new Game Object. */ - "setXY.x"?: number; + "setXY.x"?: number | null; /** * The vertical position of each new Game Object. */ - "setXY.y"?: number; + "setXY.y"?: number | null; /** * Increment each Game Object's horizontal position from the previous by this amount, starting from `setXY.x`. */ - "setXY.stepX"?: number; + "setXY.stepX"?: number | null; /** * Increment each Game Object's vertical position from the previous by this amount, starting from `setXY.y`. */ - "setXY.stepY"?: number; - setRotation?: object; + "setXY.stepY"?: number | null; + setRotation?: object | null; /** * Rotation of each new Game Object. */ - "setRotation.value"?: number; + "setRotation.value"?: number | null; /** * Increment each Game Object's rotation from the previous by this amount, starting at `setRotation.value`. */ - "setRotation.step"?: number; - setScale?: object; + "setRotation.step"?: number | null; + setScale?: object | null; /** * The horizontal scale of each new Game Object. */ - "setScale.x"?: number; + "setScale.x"?: number | null; /** * The vertical scale of each new Game Object. */ - "setScale.y"?: number; + "setScale.y"?: number | null; /** * Increment each Game Object's horizontal scale from the previous by this amount, starting from `setScale.x`. */ - "setScale.stepX"?: number; + "setScale.stepX"?: number | null; /** * Increment each Game object's vertical scale from the previous by this amount, starting from `setScale.y`. */ - "setScale.stepY"?: number; - setOrigin?: object; + "setScale.stepY"?: number | null; + setOrigin?: object | null; /** * The horizontal origin of each new Game Object. */ - "setOrigin.x"?: number; + "setOrigin.x"?: number | null; /** * The vertical origin of each new Game Object. */ - "setOrigin.y"?: number; + "setOrigin.y"?: number | null; /** * Increment each Game Object's horizontal origin from the previous by this amount, starting from `setOrigin.x`. */ - "setOrigin.stepX"?: number; + "setOrigin.stepX"?: number | null; /** * Increment each Game object's vertical origin from the previous by this amount, starting from `setOrigin.y`. */ - "setOrigin.stepY"?: number; - setAlpha?: object; + "setOrigin.stepY"?: number | null; + setAlpha?: object | null; /** * The alpha value of each new Game Object. */ - "setAlpha.value"?: number; + "setAlpha.value"?: number | null; /** * Increment each Game Object's alpha from the previous by this amount, starting from `setAlpha.value`. */ - "setAlpha.step"?: number; - setDepth?: object; + "setAlpha.step"?: number | null; + setDepth?: object | null; /** * The depth value of each new Game Object. */ - "setDepth.value"?: number; + "setDepth.value"?: number | null; /** * Increment each Game Object's depth from the previous by this amount, starting from `setDepth.value`. */ - "setDepth.step"?: number; - setScrollFactor?: object; + "setDepth.step"?: number | null; + setScrollFactor?: object | null; /** * The horizontal scroll factor of each new Game Object. */ - "setScrollFactor.x"?: number; + "setScrollFactor.x"?: number | null; /** * The vertical scroll factor of each new Game Object. */ - "setScrollFactor.y"?: number; + "setScrollFactor.y"?: number | null; /** * Increment each Game Object's horizontal scroll factor from the previous by this amount, starting from `setScrollFactor.x`. */ - "setScrollFactor.stepX"?: number; + "setScrollFactor.stepX"?: number | null; /** * Increment each Game object's vertical scroll factor from the previous by this amount, starting from `setScrollFactor.y`. */ - "setScrollFactor.stepY"?: number; + "setScrollFactor.stepY"?: number | null; /** * A geometric shape that defines the hit area for the Game Object. */ - hitArea?: any; + hitArea?: any | null; /** * A callback to be invoked when the Game Object is interacted with. */ - hitAreaCallback?: Phaser.Types.Input.HitAreaCallback; + hitAreaCallback?: Phaser.Types.Input.HitAreaCallback | null; /** * Align the new Game Objects in a grid using these settings. */ - gridAlign?: false | Phaser.Types.Actions.GridAlignConfig; + gridAlign?: false | Phaser.Types.Actions.GridAlignConfig | null; }; type GroupMultipleCreateCallback = (items: Phaser.GameObjects.GameObject[])=>void; } + namespace Mesh { + type MeshConfig = Phaser.Types.GameObjects.GameObjectConfig & { + /** + * The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + */ + key?: string | Phaser.Textures.Texture; + /** + * An optional frame from the Texture this Game Object is rendering with. + */ + frame?: string | number; + /** + * The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`. + */ + vertices?: number[]; + /** + * The UVs pairs array. + */ + uvs?: number[]; + /** + * Optional vertex indicies array. If you don't have one, pass `null` or an empty array. + */ + indicies?: number[]; + /** + * Does the vertices data include a `z` component? + */ + containsZ?: boolean; + /** + * Optional vertex normals array. If you don't have one, pass `null` or an empty array. + */ + normals?: number[]; + /** + * An array of colors, one per vertex, or a single color value applied to all vertices. + */ + colors?: number | number[]; + /** + * An array of alpha values, one per vertex, or a single alpha value applied to all vertices. + */ + alphas?: number | number[]; + }; + + } + + namespace NineSlice { + type NineSliceConfig = Phaser.Types.GameObjects.GameObjectConfig & { + /** + * The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + */ + key?: string | Phaser.Textures.Texture; + /** + * An optional frame from the Texture this Game Object is rendering with. + */ + frame?: string | number; + /** + * The width of the Nine Slice Game Object. You can adjust the width post-creation. + */ + width?: number; + /** + * The height of the Nine Slice Game Object. If this is a 3 slice object the height will be fixed to the height of the texture and cannot be changed. + */ + height?: number; + /** + * The size of the left vertical column (A). + */ + leftWidth?: number; + /** + * The size of the right vertical column (B). + */ + rightWidth?: number; + /** + * The size of the top horiztonal row (C). Set to zero or undefined to create a 3 slice object. + */ + topHeight?: number; + /** + * The size of the bottom horiztonal row (D). Set to zero or undefined to create a 3 slice object. + */ + bottomHeight?: number; + }; + + } + namespace Particles { + type DeathZoneObject = Phaser.GameObjects.Particles.Zones.DeathZone | Phaser.Types.GameObjects.Particles.ParticleEmitterDeathZoneConfig | Phaser.Geom.Circle | Phaser.Geom.Ellipse | Phaser.Geom.Polygon | Phaser.Geom.Triangle; + type DeathZoneSource = { contains: Phaser.Types.GameObjects.Particles.DeathZoneSourceCallback; }; - type DeathZoneSourceCallback = (x: number, y: number)=>void; + type DeathZoneSourceCallback = (x: number, y: number)=>boolean; type EdgeZoneSource = { /** @@ -61543,7 +71766,7 @@ declare namespace Phaser { getPoints: Phaser.Types.GameObjects.Particles.EdgeZoneSourceCallback; }; - type EdgeZoneSourceCallback = (quantity: number, stepRate?: number)=>void; + type EdgeZoneSourceCallback = (quantity: number, stepRate?: number)=>Phaser.Types.Math.Vector2Like[]; type EmitterOpCustomEmitConfig = { /** @@ -61585,19 +71808,41 @@ declare namespace Phaser { easeParams?: number[]; }; + /** + * Defines an operation yielding a value incremented continuously across an interpolated data set. + */ + type EmitterOpInterpolationConfig = { + /** + * The array of number values to interpolate through. + */ + values: number[]; + /** + * The interpolation function to use. Typically one of `linear`, `bezier` or `catmull` or a custom function. + */ + interpolation?: string | Function; + /** + * An optional ease function to use. This can be either a string from the EaseMap, or a custom function. + */ + ease?: string | Function; + /** + * An optional array of ease parameters to go with the ease. + */ + easeParams?: number[]; + }; + /** * The returned value sets what the property will be at the START of the particle's life, on emit. */ - type EmitterOpOnEmitCallback = (particle: Phaser.GameObjects.Particles.Particle, key: string, value: number)=>void; + type EmitterOpOnEmitCallback = (particle: Phaser.GameObjects.Particles.Particle, key: string, value: number)=>number; type EmitterOpOnEmitType = number | number[] | Phaser.Types.GameObjects.Particles.EmitterOpOnEmitCallback | Phaser.Types.GameObjects.Particles.EmitterOpRandomConfig | Phaser.Types.GameObjects.Particles.EmitterOpRandomMinMaxConfig | Phaser.Types.GameObjects.Particles.EmitterOpRandomStartEndConfig | Phaser.Types.GameObjects.Particles.EmitterOpSteppedConfig | Phaser.Types.GameObjects.Particles.EmitterOpCustomEmitConfig; /** * The returned value updates the property for the duration of the particle's life. */ - type EmitterOpOnUpdateCallback = (particle: Phaser.GameObjects.Particles.Particle, key: string, t: number, value: number)=>void; + type EmitterOpOnUpdateCallback = (particle: Phaser.GameObjects.Particles.Particle, key: string, t: number, value: number)=>number; - type EmitterOpOnUpdateType = Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback | Phaser.Types.GameObjects.Particles.EmitterOpEaseConfig | Phaser.Types.GameObjects.Particles.EmitterOpCustomUpdateConfig; + type EmitterOpOnUpdateType = Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateCallback | Phaser.Types.GameObjects.Particles.EmitterOpEaseConfig | Phaser.Types.GameObjects.Particles.EmitterOpCustomUpdateConfig | Phaser.Types.GameObjects.Particles.EmitterOpInterpolationConfig; /** * Defines an operation yielding a random value within a range. @@ -61659,6 +71904,8 @@ declare namespace Phaser { steps: number; }; + type EmitZoneObject = Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig | Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig | Phaser.GameObjects.Particles.Zones.EdgeZone | Phaser.GameObjects.Particles.Zones.RandomZone; + type GravityWellConfig = { /** * The x coordinate of the Gravity Well, in world space. @@ -61682,6 +71929,8 @@ declare namespace Phaser { gravity?: number; }; + type ParticleClassConstructor = (emitter: Phaser.GameObjects.Particles.ParticleEmitter)=>void; + type ParticleDeathCallback = (particle: Phaser.GameObjects.Particles.Particle)=>void; type ParticleEmitterBounds = { @@ -61726,7 +71975,7 @@ declare namespace Phaser { type ParticleEmitterConfig = { /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#active}. + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#active}. Setting this to false will stop the emitter from running at all. If you just wish to stop particles from emitting, set `emitting` property instead. */ active?: boolean; /** @@ -61789,14 +72038,18 @@ declare namespace Phaser { * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#maxParticles}. */ maxParticles?: number; + /** + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#maxAliveParticles}. + */ + maxAliveParticles?: number; /** * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#name}. */ name?: string; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#on}. + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#emitting}. */ - on?: boolean; + emitting?: boolean; /** * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleBringToTop}. */ @@ -61804,7 +72057,7 @@ declare namespace Phaser { /** * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleClass}. */ - particleClass?: Phaser.GameObjects.Particles.Particle; + particleClass?: Function; /** * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#radial}. */ @@ -61822,55 +72075,59 @@ declare namespace Phaser { */ visible?: boolean; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#accelerationX} (emit only). + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#accelerationX}. */ - accelerationX?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + accelerationX?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#accelerationY} (emit only). + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#accelerationY}. */ - accelerationY?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + accelerationY?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#alpha}. + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleAlpha}. */ alpha?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#angle} (emit only). + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleAngle} (emit only). */ angle?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#bounce} (emit only). + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#bounce}. */ - bounce?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + bounce?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#delay} (emit only). */ delay?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + /** + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#hold} (emit only). + */ + hold?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#lifespan} (emit only). */ lifespan?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityX} (emit only). + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityX}. */ - maxVelocityX?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + maxVelocityX?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityY} (emit only). + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityY}. */ - maxVelocityY?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + maxVelocityY?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#moveToX} (emit only). + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#moveToX}. If set, overrides `angle` and `speed` properties. */ - moveToX?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + moveToX?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#moveToY} (emit only). + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#moveToY}. If set, overrides `angle` and `speed` properties. */ - moveToY?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; + moveToY?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity} (emit only). */ quantity?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#rotate}. + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleRotate}. */ rotate?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** @@ -61878,11 +72135,11 @@ declare namespace Phaser { */ scale?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#scaleX}. + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleScaleX}. */ scaleX?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#scaleY}. + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleScaleY}. */ scaleY?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** @@ -61898,15 +72155,23 @@ declare namespace Phaser { */ speedY?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#tint}. + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleTint}. */ tint?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType | Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#x} (emit only). + * An array of color values that the Particles interpolate through during theif life. If set, overrides any `tint` property. + */ + color?: number[]; + /** + * The string-based name of the Easing function to use if you have enabled Particle color interpolation via the `color` property, otherwise has no effect. + */ + colorEase?: string; + /** + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleX}. */ x?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** - * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#y} (emit only). + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#particleY}. */ y?: Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType; /** @@ -61926,21 +72191,64 @@ declare namespace Phaser { */ followOffset?: object; /** - * x-coordinate of the offset. + * x coordinate of the offset. */ "followOffset.x"?: number; /** - * y-coordinate of the offset. + * y coordinate of the offset. */ "followOffset.y"?: number; /** * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}. */ frame?: number | number[] | string | string[] | Phaser.Textures.Frame | Phaser.Textures.Frame[] | Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig; + /** + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#texture}. Overrides any texture already set on the Emitter. + */ + texture?: string | Phaser.Textures.Frame; /** * Creates specified number of inactive particles and adds them to this emitter's pool. {@link Phaser.GameObjects.Particles.ParticleEmitter#reserve} */ reserve?: number; + /** + * If you wish to 'fast forward' the emitter in time, set this value to a number representing the amount of ms the emitter should advance. + */ + advance?: number; + /** + * Limit the emitter to emit particles for a maximum of `duration` ms. Default to zero, meaning 'forever'. + */ + duration?: number; + /** + * Limit the emitter to emit this exact number of particles and then stop. Default to zero, meaning no limit. + */ + stopAfter?: number; + /** + * A custom callback that sorts particles prior to rendering. Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#sortCallback}. + */ + sortCallback?: Phaser.Types.GameObjects.Particles.ParticleSortCallback; + /** + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#sortOrderAsc}. + */ + sortOrderAsc?: boolean; + /** + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#sortProperty}. + */ + sortProperty?: string; + /** + * Sets {@link Phaser.GameObjects.Particles.ParticleEmitter#tintFill}. + */ + tintFill?: boolean; + }; + + type ParticleEmitterCreatorConfig = Phaser.Types.GameObjects.GameObjectConfig & { + /** + * The key of the Texture this Emitter will use to render particles, as stored in the Texture Manager. + */ + key?: string; + /** + * The Particle Emitter configuration object. + */ + config?: Phaser.Types.GameObjects.Particles.ParticleEmitterConfig; }; type ParticleEmitterDeathZoneConfig = { @@ -61979,6 +72287,10 @@ declare namespace Phaser { * Whether one endpoint will be removed if it's identical to the other. */ seamless?: boolean; + /** + * The total number of particles this zone will emit before passing over to the next emission zone in the Emitter. + */ + total?: number; }; type ParticleEmitterFrameConfig = { @@ -61996,6 +72308,97 @@ declare namespace Phaser { quantity?: number; }; + type ParticleEmitterOps = { + /** + * The accelerationX EmitterOp instance. This is an onEmit and onUpdate operator. + */ + accelerationX: Phaser.GameObjects.Particles.EmitterOp; + /** + * The accelerationY EmitterOp instance. This is an onEmit and onUpdate operator. + */ + accelerationY: Phaser.GameObjects.Particles.EmitterOp; + /** + * The alpha EmitterOp instance. This is an onEmit and onUpdate operator. + */ + alpha: Phaser.GameObjects.Particles.EmitterOp; + /** + * The angle EmitterOp instance. This is an onEmit operator only. + */ + angle: Phaser.GameObjects.Particles.EmitterOp; + /** + * The bounce EmitterOp instance. This is an onEmit and onUpdate operator. + */ + bounce: Phaser.GameObjects.Particles.EmitterOp; + /** + * The color EmitterColorOp instance. This is an onEmit and onUpdate operator. + */ + color: Phaser.GameObjects.Particles.EmitterColorOp; + /** + * The delay EmitterOp instance. This is an onEmit operator only. + */ + delay: Phaser.GameObjects.Particles.EmitterOp; + /** + * The hold EmitterOp instance. This is an onEmit operator only. + */ + hold: Phaser.GameObjects.Particles.EmitterOp; + /** + * The lifespan EmitterOp instance. This is an onEmit operator only. + */ + lifespan: Phaser.GameObjects.Particles.EmitterOp; + /** + * The maxVelocityX EmitterOp instance. This is an onEmit and onUpdate operator. + */ + maxVelocityX: Phaser.GameObjects.Particles.EmitterOp; + /** + * The maxVelocityY EmitterOp instance. This is an onEmit and onUpdate operator. + */ + maxVelocityY: Phaser.GameObjects.Particles.EmitterOp; + /** + * The moveToX EmitterOp instance. This is an onEmit and onUpdate operator. + */ + moveToX: Phaser.GameObjects.Particles.EmitterOp; + /** + * The moveToY EmitterOp instance. This is an onEmit and onUpdate operator. + */ + moveToY: Phaser.GameObjects.Particles.EmitterOp; + /** + * The quantity EmitterOp instance. This is an onEmit operator only. + */ + quantity: Phaser.GameObjects.Particles.EmitterOp; + /** + * The rotate EmitterOp instance. This is an onEmit and onUpdate operator. + */ + rotate: Phaser.GameObjects.Particles.EmitterOp; + /** + * The scaleX EmitterOp instance. This is an onEmit and onUpdate operator. + */ + scaleX: Phaser.GameObjects.Particles.EmitterOp; + /** + * The scaleY EmitterOp instance. This is an onEmit and onUpdate operator. + */ + scaleY: Phaser.GameObjects.Particles.EmitterOp; + /** + * The speedX EmitterOp instance. This is an onEmit operator only. + */ + speedX: Phaser.GameObjects.Particles.EmitterOp; + /** + * The speedY EmitterOp instance. This is an onEmit operator only. + */ + speedY: Phaser.GameObjects.Particles.EmitterOp; + /** + * The tint EmitterOp instance. This is an onEmit and onUpdate operator. + */ + tint: Phaser.GameObjects.Particles.EmitterOp; + /** + * The x EmitterOp instance. This is an onEmit and onUpdate operator. + */ + x: Phaser.GameObjects.Particles.EmitterOp; + /** + * The y EmitterOp instance. This is an onEmit and onUpdate operator. + */ + y: Phaser.GameObjects.Particles.EmitterOp; + }; + type ParticleEmitterRandomZoneConfig = { /** * A shape representing the zone. See {@link Phaser.GameObjects.Particles.Zones.RandomZone#source}. @@ -62007,6 +72410,8 @@ declare namespace Phaser { type?: string; }; + type ParticleSortCallback = (a: Phaser.GameObjects.Particles.Particle, b: Phaser.GameObjects.Particles.Particle)=>void; + type RandomZoneSource = { /** * A function modifying its point argument. @@ -62055,6 +72460,59 @@ declare namespace Phaser { } + namespace Plane { + type PlaneCheckerboardConfig = { + /** + * The odd cell color, specified as a hex value. + */ + color1?: number; + /** + * The even cell color, specified as a hex value. + */ + color2?: number; + /** + * The odd cell alpha value, specified as a number between 0 and 255. + */ + alpha1?: number; + /** + * The even cell alpha value, specified as a number between 0 and 255. + */ + alpha2?: number; + /** + * The view height of the Plane after creation, in pixels. + */ + height?: number; + }; + + type PlaneConfig = Phaser.Types.GameObjects.GameObjectConfig & { + /** + * The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. + */ + key?: string | Phaser.Textures.Texture; + /** + * An optional frame from the Texture this Game Object is rendering with. + */ + frame?: string | number; + /** + * The width of this Plane, in cells, not pixels. + */ + width?: number; + /** + * The height of this Plane, in cells, not pixels. + */ + height?: number; + /** + * Is the texture tiled? I.e. repeated across each cell. + */ + tile?: boolean; + /** + * Plane checkerboard configuration object. + */ + checkerboard?: Phaser.Types.GameObjects.Plane.PlaneCheckerboardConfig; + }; + + } + namespace RenderTexture { type RenderTextureConfig = { /** @@ -62073,14 +72531,54 @@ declare namespace Phaser { * The height of the RenderTexture. */ height?: number; + }; + + } + + namespace Rope { + type RopeConfig = Phaser.Types.GameObjects.GameObjectConfig & { /** - * The texture key to make the RenderTexture from. + * The key of the Texture this Game Object will use to render with, as stored in the Texture Manager. If not given, `__DEFAULT` is used. */ key?: string; /** - * the frame to make the RenderTexture from. + * An optional frame from the Texture this Game Object is rendering with. + */ + frame?: string | integer | null; + /** + * An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided a simple quad is created. See `setPoints` to set this post-creation. + */ + points?: integer | Phaser.Types.Math.Vector2Like[]; + /** + * Should the vertices of this Rope be aligned horizontally (`true`), or vertically (`false`)? + */ + horizontal?: boolean; + /** + * An optional array containing the color data for this Rope. You should provide one color value per pair of vertices. + */ + colors?: number[]; + /** + * An optional array containing the alpha data for this Rope. You should provide one alpha value per pair of vertices. */ - frame?: string; + alphas?: number[]; + }; + + } + + namespace Shader { + type ShaderConfig = Phaser.Types.GameObjects.GameObjectConfig & { + /** + * The key of the shader to use from the shader cache, or a BaseShader instance. + */ + key: string | Phaser.Display.BaseShader; + /** + * The width of the Game Object. + */ + width?: number; + /** + * The height of the Game Object. + */ + height?: number; }; } @@ -62088,13 +72586,13 @@ declare namespace Phaser { namespace Sprite { type SpriteConfig = Phaser.Types.GameObjects.GameObjectConfig & { /** - * The key of the Texture this Game Object will use to render with, as stored in the Texture Manager. + * The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager. */ - key?: string; + key?: string | Phaser.Textures.Texture; /** * An optional frame from the Texture this Game Object is rendering with. */ - frame?: number | string; + frame?: string | number; }; } @@ -62234,7 +72732,7 @@ declare namespace Phaser { /** * The font size, as a CSS size string. */ - fontSize?: string; + fontSize?: number | string; /** * Any addition font styles, such as 'strong'. */ @@ -62311,6 +72809,10 @@ declare namespace Phaser { * A Text Metrics object. Use this to avoid expensive font size calculations in text heavy games. */ metrics?: Phaser.Types.GameObjects.Text.TextMetrics; + /** + * The amount to add to the font height to achieve the overall line height. + */ + lineSpacing?: number; }; /** @@ -62362,11 +72864,34 @@ declare namespace Phaser { /** * An optional frame from the Texture this Tile Sprite is rendering with. */ - frame?: string; + frame?: number | string | Phaser.Textures.Frame; }; } + type DecomposeMatrixResults = { + /** + * The translated x value. + */ + translateX: number; + /** + * The translated y value. + */ + translateY: number; + /** + * The rotation value. + */ + rotation: number; + /** + * The scale x value. + */ + scaleX: number; + /** + * The scale y value. + */ + scaleY: number; + }; + type Face = { /** * The first face vertex. @@ -62410,11 +72935,11 @@ declare namespace Phaser { /** * The scale of the GameObject. */ - scale?: number | object; + scale?: number | object | null; /** * The scroll factor of the GameObject. */ - scrollFactor?: number | object; + scrollFactor?: number | object | null; /** * The rotation angle of the Game Object, in radians. */ @@ -62422,7 +72947,7 @@ declare namespace Phaser { /** * The rotation angle of the Game Object, in degrees. */ - angle?: number | object; + angle?: number | object | null; /** * The alpha (opacity) of the Game Object. */ @@ -62430,7 +72955,7 @@ declare namespace Phaser { /** * The origin of the Game Object. */ - origin?: number | object; + origin?: number | object | null; /** * The scale mode of the GameObject. */ @@ -62586,6 +73111,30 @@ declare namespace Phaser { alpha: number; }; + namespace Video { + type VideoConfig = Phaser.Types.GameObjects.GameObjectConfig & { + /** + * Optional key of the Video this Game Object will play, as stored in the Video Cache. + */ + key?: string; + }; + + } + + namespace Zone { + type ZoneConfig = Phaser.Types.GameObjects.GameObjectConfig & { + /** + * The width of the Game Object. + */ + width?: number; + /** + * The height of the Game Object. + */ + height?: number; + }; + + } + } namespace Geom { @@ -62855,7 +73404,7 @@ declare namespace Phaser { stopPropagation: Function; }; - type HitAreaCallback = (hitArea: any, x: number, y: number, gameObject: Phaser.GameObjects.GameObject)=>void; + type HitAreaCallback = (hitArea: any, x: number, y: number, gameObject: Phaser.GameObjects.GameObject)=>boolean; type InputConfiguration = { /** @@ -62916,10 +73465,6 @@ declare namespace Phaser { * Is this Interactive Object currently enabled for input events? */ enabled: boolean; - /** - * An Interactive Object that is 'always enabled' will receive input even if the parent object is invisible or won't render. - */ - alwaysEnabled: boolean; /** * Is this Interactive Object draggable? Enable with `InputPlugin.setDraggable`. */ @@ -62935,7 +73480,7 @@ declare namespace Phaser { /** * An optional drop target for a draggable Interactive Object. */ - target: Phaser.GameObjects.GameObject; + target: Phaser.GameObjects.GameObject | null; /** * The most recent Camera to be tested against this Interactive Object. */ @@ -63107,7 +73652,7 @@ declare namespace Phaser { /** * The absolute or relative URLs to load the audio files from. */ - url?: string | string[]; + url?: string | string[] | Phaser.Types.Loader.FileTypes.AudioFileURLConfig | Phaser.Types.Loader.FileTypes.AudioFileURLConfig[]; /** * Extra XHR Settings specifically for this file. */ @@ -63118,6 +73663,17 @@ declare namespace Phaser { context?: AudioContext; }; + type AudioFileURLConfig = { + /** + * The audio file format. See property names in {@link Phaser.Device.Audio}. + */ + type: string; + /** + * The absolute or relative URL of the audio file. + */ + url: string; + }; + type AudioSpriteFileConfig = { /** * The key of the file. Must be unique within both the Loader and the Audio Cache. @@ -63203,6 +73759,80 @@ declare namespace Phaser { fontDataXhrSettings?: Phaser.Types.Loader.XHRSettingsObject; }; + type CompressedTextureFileEntry = { + /** + * The texture compression base format that the browser must support in order to load this file. Can be any of: 'ETC', 'ETC1', 'ATC', 'ASTC', 'BPTC', 'RGTC', 'PVRTC', 'S3TC', 'S3TCSRGB' or the fallback format of 'IMG'. + */ + format?: string; + /** + * The container format, either PVR or KTX. If not given it will try to extract it from the textureURL extension. + */ + type?: string; + /** + * The URL of the compressed texture file to load. + */ + textureURL?: string; + /** + * Optional URL of a texture atlas JSON data file. If not given, the texture will be loaded as a single image. + */ + atlasURL?: string; + /** + * Optional URL of a multi-texture atlas JSON data file as created by Texture Packer Pro. + */ + multiAtlasURL?: string; + /** + * Optional path to use when loading the textures defined in the multi atlas data. + */ + multiPath?: string; + /** + * Optional Base URL to use when loading the textures defined in the multi atlas data. + */ + multiBaseURL?: string; + }; + + type CompressedTextureFileConfig = { + /** + * The string, or file entry object, for an ETC format texture. + */ + ETC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an ETC1 format texture. + */ + ETC1?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an ATC format texture. + */ + ATC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an ASTC format texture. + */ + ASTC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an BPTC format texture. + */ + BPTC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an RGTC format texture. + */ + RGTC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an PVRTC format texture. + */ + PVRTC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an S3TC format texture. + */ + S3TC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an S3TCRGB format texture. + */ + S3TCRGB?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for the fallback image file. + */ + IMG?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + }; + type CSSFileConfig = { /** * The key of the file. Must be unique within the Loader. @@ -63585,6 +74215,10 @@ declare namespace Phaser { * The default file extension to use if no url is provided. */ extension?: string; + /** + * The script type. Should be either 'script' for classic JavaScript, or 'module' if the file contains an exported module. + */ + type?: string; /** * Extra XHR Settings specifically for this file. */ @@ -63775,23 +74409,22 @@ declare namespace Phaser { /** * The absolute or relative URLs to load the video files from. */ - url?: string | string[]; - /** - * The load event to listen for when _not_ loading as a blob. Either 'loadeddata', 'canplay' or 'canplaythrough'. - */ - loadEvent?: string; - /** - * Load the video as a data blob, or via the Video element? - */ - asBlob?: boolean; + url?: string | string[] | Phaser.Types.Loader.FileTypes.VideoFileURLConfig | Phaser.Types.Loader.FileTypes.VideoFileURLConfig[]; /** * Does the video have an audio track? If not you can enable auto-playing on it. */ noAudio?: boolean; + }; + + type VideoFileURLConfig = { /** - * Extra XHR Settings specifically for this file. + * The video file format. See property names in {@link Phaser.Device.Video}. */ - xhrSettings?: Phaser.Types.Loader.XHRSettingsObject; + type: string; + /** + * The absolute or relative URL of the video file. + */ + url: string; }; type XMLFileConfig = { @@ -63827,7 +74460,7 @@ declare namespace Phaser { /** * The URL of the file, not including baseURL. */ - url?: string; + url?: object | string; /** * The path of the file, not including the baseURL. */ @@ -63848,6 +74481,170 @@ declare namespace Phaser { * A config object that can be used by file types to store transitional data. */ config?: any; + /** + * The absolute or relative URL to load the texture image file from. + */ + textureURL?: string; + /** + * The default file extension to use for the image texture if no url is provided. + */ + textureExtension?: string; + /** + * Extra XHR Settings specifically for the texture image file. + */ + textureXhrSettings?: Phaser.Types.Loader.XHRSettingsObject; + /** + * The absolute or relative URL to load the atlas json file from. Or, a well formed JSON object to use instead. + */ + atlasURL?: object | string; + /** + * The default file extension to use for the atlas json if no url is provided. + */ + atlasExtension?: string; + /** + * Extra XHR Settings specifically for the atlas json file. + */ + atlasXhrSettings?: Phaser.Types.Loader.XHRSettingsObject; + /** + * The filename of an associated normal map. It uses the same path and url to load as the texture image. + */ + normalMap?: string; + /** + * The optional AudioContext this file will use to process itself (only used by Sound objects). + */ + context?: AudioContext; + /** + * The absolute or relative URL to load the json file from. Or a well formed JSON object to use instead. + */ + jsonURL?: string; + /** + * Extra XHR Settings specifically for the json file. + */ + jsonXhrSettings?: Phaser.Types.Loader.XHRSettingsObject; + /** + * The absolute or relative URL to load the audio file from. + */ + audioURL?: Object; + /** + * The audio configuration options. + */ + audioConfig?: any; + /** + * Extra XHR Settings specifically for the audio file. + */ + audioXhrSettings?: Phaser.Types.Loader.XHRSettingsObject; + /** + * Optional type to cast the binary file to once loaded. For example, `Uint8Array`. + */ + dataType?: any; + /** + * The absolute or relative URL to load the font data xml file from. + */ + fontDataURL?: string; + /** + * The default file extension to use for the font data xml if no url is provided. + */ + fontDataExtension?: string; + /** + * Extra XHR Settings specifically for the font data xml file. + */ + fontDataXhrSettings?: Phaser.Types.Loader.XHRSettingsObject; + /** + * The string, or file entry object, for an ETC format texture. + */ + ETC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an ETC1 format texture. + */ + ETC1?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an ATC format texture. + */ + ATC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an ASTC format texture. + */ + ASTC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an BPTC format texture. + */ + BPTC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an RGTC format texture. + */ + RGTC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an PVRTC format texture. + */ + PVRTC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an S3TC format texture. + */ + S3TC?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for an S3TCRGB format texture. + */ + S3TCRGB?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The string, or file entry object, for the fallback image file. + */ + IMG?: Phaser.Types.Loader.FileTypes.CompressedTextureFileEntry | string; + /** + * The type of shader. Either `fragment` for a fragment shader, or `vertex` for a vertex shader. This is ignored if you load a shader bundle. + */ + shaderType?: string; + /** + * The width of the texture the HTML will be rendered to. + */ + width?: number; + /** + * The height of the texture the HTML will be rendered to. + */ + height?: number; + /** + * The frame configuration object. Only provided for, and used by, Sprite Sheets. + */ + frameConfig?: Phaser.Types.Loader.FileTypes.ImageFrameConfig; + /** + * If specified instead of the whole JSON file being parsed and added to the Cache, only the section corresponding to this property key will be added. If the property you want to extract is nested, use periods to divide it. + */ + dataKey?: string; + /** + * Optional Base URL to use when loading the textures defined in the atlas data. + */ + baseURL?: string; + /** + * Flip the UV coordinates stored in the model data? + */ + flipUV?: boolean; + /** + * An optional absolute or relative URL to the object material file from. If undefined or `null`, no material file will be loaded. + */ + matURL?: string; + /** + * The default material file extension to use if no url is provided. + */ + matExtension?: string; + /** + * Automatically start the plugin after loading? + */ + start?: boolean; + /** + * If this plugin is to be injected into the Scene, this is the property key used. + */ + mapping?: string; + /** + * If this plugin is to be added to Scene.Systems, this is the property key for it. + */ + systemKey?: string; + /** + * If this plugin is to be added to the Scene, this is the property key for it. + */ + sceneKey?: string; + /** + * The svg size configuration object. + */ + svgConfig?: Phaser.Types.Loader.FileTypes.SVGSizeConfig; }; type XHRSettingsObject = { @@ -64011,6 +74808,8 @@ declare namespace Phaser { */ type ArcadeColliderType = Phaser.GameObjects.GameObject | Phaser.GameObjects.Group | Phaser.Physics.Arcade.Sprite | Phaser.Physics.Arcade.Image | Phaser.Physics.Arcade.StaticGroup | Phaser.Physics.Arcade.Group | Phaser.Tilemaps.TilemapLayer | Phaser.GameObjects.GameObject[] | Phaser.Physics.Arcade.Sprite[] | Phaser.Physics.Arcade.Image[] | Phaser.Physics.Arcade.StaticGroup[] | Phaser.Physics.Arcade.Group[] | Phaser.Tilemaps.TilemapLayer[]; + type ArcadePhysicsCallback = (object1: Phaser.Types.Physics.Arcade.GameObjectWithBody | Phaser.Tilemaps.Tile, object2: Phaser.Types.Physics.Arcade.GameObjectWithBody | Phaser.Tilemaps.Tile)=>void; + type ArcadeWorldConfig = { /** * Sets {@link Phaser.Physics.Arcade.World#fps}. @@ -64220,6 +75019,10 @@ declare namespace Phaser { * Sets {@link Phaser.Physics.Arcade.Body#allowRotation}. */ allowRotation?: boolean; + /** + * Sets {@link Phaser.Physics.Arcade.Body#useDamping useDamping}. + */ + useDamping?: boolean; /** * Sets {@link Phaser.Physics.Arcade.Body#bounce bounce.x}. */ @@ -64256,6 +75059,10 @@ declare namespace Phaser { * Sets {@link Phaser.Physics.Arcade.Body#friction friction.y}. */ frictionY?: number; + /** + * Sets {@link Phaser.Physics.Arcade.Body#maxSpeed maxSpeed}. + */ + maxSpeed?: number; /** * Sets {@link Phaser.Physics.Arcade.Body#maxVelocity maxVelocity.x}. */ @@ -64323,6 +75130,10 @@ declare namespace Phaser { * As {@link Phaser.Physics.Arcade.Body#setAllowRotation}. */ setAllowRotation: boolean; + /** + * As {@link Phaser.Physics.Arcade.Body#setDamping}. + */ + setDamping: boolean; /** * As {@link Phaser.Physics.Arcade.Body#setBounceX}. */ @@ -64359,6 +75170,10 @@ declare namespace Phaser { * As {@link Phaser.Physics.Arcade.Body#setFrictionY}. */ setFrictionY: number; + /** + * As {@link Phaser.Physics.Arcade.Body#setMaxSpeed}. + */ + setMaxSpeed: number; /** * As {@link Phaser.Physics.Arcade.Body#setVelocityX}. */ @@ -64407,6 +75222,10 @@ declare namespace Phaser { * An arbitrary string-based name to help identify this body. */ label?: string; + /** + * Set this Game Object to create and use a new Body based on the configuration object given. + */ + shape?: string | Phaser.Types.Physics.Matter.MatterSetBodyConfig; /** * An array of bodies that make up this body. The first body in the array must always be a self reference to the current body instance. All bodies in the `parts` array together form a single rigid compound body. */ @@ -64732,7 +75551,7 @@ declare namespace Phaser { */ activeContacts: MatterJS.Vector[]; /** - * The amount of separation that occured between bodies A and B. + * The amount of separation that occurred between bodies A and B. */ separation: number; /** @@ -65163,11 +75982,30 @@ declare namespace Phaser { addToWorld?: boolean; }; + type MatterWalls = { + /** + * The left wall for the Matter World. + */ + left?: MatterJS.BodyType; + /** + * The right wall for the Matter World. + */ + right?: MatterJS.BodyType; + /** + * The top wall for the Matter World. + */ + top?: MatterJS.BodyType; + /** + * The bottom wall for the Matter World. + */ + bottom?: MatterJS.BodyType; + }; + type MatterWorldConfig = { /** - * Sets {@link Phaser.Physics.Matter.World#gravity}. If `false` Gravity will be set to zero. + * Sets {@link Phaser.Physics.Matter.World#gravity}. */ - gravity?: Phaser.Types.Math.Vector2Like | boolean; + gravity?: Phaser.Types.Math.Vector2Like; /** * Should the world have bounds enabled by default? */ @@ -65413,6 +76251,14 @@ declare namespace Phaser { * Controls if this Render Target is automatically cleared (via `gl.COLOR_BUFFER_BIT`) during the bind. */ autoClear?: boolean; + /** + * The width of the Render Target. This is optional. If given it overrides the `scale` property. + */ + width?: number; + /** + * The height of the Render Target. This is optional. If not given, it will be set to the same as the `width` value. + */ + height?: number; }; type WebGLConst = { @@ -65476,6 +76322,29 @@ declare namespace Phaser { normalized?: boolean; }; + type WebGLPipelineBatchEntry = { + /** + * The vertext count this batch entry starts from. + */ + start: number; + /** + * The total number of vertices in this batch entry. + */ + count: number; + /** + * The current texture unit of the batch entry. + */ + unit: number; + /** + * The maximum number of texture units in this batch entry. + */ + maxUnit: number; + /** + * An array of WebGLTexture references used in this batch entry. + */ + texture: WebGLTexture[]; + }; + type WebGLPipelineConfig = { /** * The Phaser.Game instance that owns this pipeline. @@ -65575,17 +76444,45 @@ declare namespace Phaser { type WebGLTextureCompression = { /** - * Indicates if ETC1 compression is supported on current device (mostly Android). + * Indicates if ASTC compression is supported (mostly iOS). + */ + ASTC: object | undefined; + /** + * Indicates if ATC compression is supported. + */ + ATC: object | undefined; + /** + * Indicates if BPTC compression is supported. + */ + BPTC: object | undefined; + /** + * Indicates if ETC compression is supported (mostly Android). + */ + ETC: object | undefined; + /** + * Indicates if ETC1 compression is supported (mostly Android). + */ + ETC1: object | undefined; + /** + * Indicates the browser supports true color images (all browsers). + */ + IMG: object | undefined; + /** + * Indicates if PVRTC compression is supported (mostly iOS). */ - ETC1: object | null; + PVRTC: object | undefined; /** - * Indicates if PVRTC compression is supported on current device (mostly iOS). + * Indicates if RGTC compression is supported (mostly iOS). */ - PVRTC: object | null; + RGTC: object | undefined; /** - * Indicates if S3TC compression is supported on current device. + * Indicates if S3TC compression is supported on current device (mostly Windows). */ - S3TC: object | null; + S3TC: object | undefined; + /** + * Indicates if S3TCRGB compression is supported on current device (mostly Windows). + */ + S3TCRGB: object | undefined; }; } @@ -65677,13 +76574,25 @@ declare namespace Phaser { * The context in which the callback is invoked. */ onUpdateScope?: any; + /** + * This callback is invoked when transition starting. + */ + onStart?: Phaser.Types.Scenes.SceneTransitionOnStartCallback; + /** + * The context in which the callback is invoked. + */ + onStartScope?: any; /** * An object containing any data you wish to be passed to the target scene's init / create methods (if sleep is false) or to the target scene's wake event callback (if sleep is true). */ data?: any; }; - type SceneUpdateCallback = (this: Phaser.Scene)=>void; + type SceneTransitionOnStartCallback = (this: Phaser.Scene, fromScene: Phaser.Scene, toScene: Phaser.Scene)=>void; + + type SceneType = Phaser.Scene | Phaser.Types.Scenes.SettingsConfig | Phaser.Types.Scenes.CreateSceneFromObjectConfig | Function; + + type SceneUpdateCallback = (this: Phaser.Scene, time: number, delta: number)=>void; type SettingsConfig = { /** @@ -65705,7 +76614,7 @@ declare namespace Phaser { /** * An optional Camera configuration object. */ - cameras?: Phaser.Types.Cameras.Scene2D.JSONCamera | Phaser.Types.Cameras.Scene2D.JSONCamera[]; + cameras?: Phaser.Types.Cameras.Scene2D.CameraConfig | Phaser.Types.Cameras.Scene2D.CameraConfig[] | null; /** * Overwrites the default injection map for a scene. */ @@ -65756,7 +76665,7 @@ declare namespace Phaser { /** * The Scene this Scene is transitioning from, if set. */ - transitionFrom: Phaser.Scene; + transitionFrom: Phaser.Scene | null; /** * The duration of the transition, if set. */ @@ -65776,7 +76685,7 @@ declare namespace Phaser { /** * The Camera configuration object. */ - cameras: Phaser.Types.Cameras.Scene2D.JSONCamera | Phaser.Types.Cameras.Scene2D.JSONCamera[]; + cameras: Phaser.Types.Cameras.Scene2D.CameraConfig | Phaser.Types.Cameras.Scene2D.CameraConfig[] | null; /** * The Scene's Injection Map. */ @@ -65863,6 +76772,10 @@ declare namespace Phaser { * A value between -1 (full left pan) and 1 (full right pan). 0 means no pan. */ pan?: number; + /** + * An optional config object containing default spatial sound settings. + */ + source?: Phaser.Types.Sound.SpatialSoundConfig; }; /** @@ -65887,9 +76800,147 @@ declare namespace Phaser { config?: Phaser.Types.Sound.SoundConfig; }; + /** + * Config object containing settings for the source of the spatial sound. + * + * See https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Web_audio_spatialization_basics + */ + type SpatialSoundConfig = { + /** + * The horizontal position of the audio in a right-hand Cartesian coordinate system. + */ + x?: number; + /** + * The vertical position of the audio in a right-hand Cartesian coordinate system. + */ + y?: number; + /** + * Represents the longitudinal (back and forth) position of the audio in a right-hand Cartesian coordinate system. + */ + z?: number; + /** + * An enumerated value determining which spatialization algorithm to use to position the audio in 3D space. + */ + panningModel?: 'equalpower' | 'HRTF'; + /** + * Which algorithm to use to reduce the volume of the audio source as it moves away from the listener. Possible values are "linear", "inverse" and "exponential". The default value is "inverse". + */ + distanceModel?: 'linear' | 'inverse' | 'exponential'; + /** + * The horizontal position of the audio source's vector in a right-hand Cartesian coordinate system. + */ + orientationX?: number; + /** + * The vertical position of the audio source's vector in a right-hand Cartesian coordinate system. + */ + orientationY?: number; + /** + * Represents the longitudinal (back and forth) position of the audio source's vector in a right-hand Cartesian coordinate system. + */ + orientationZ?: number; + /** + * A double value representing the reference distance for reducing volume as the audio source moves further from the listener. For distances greater than this the volume will be reduced based on `rolloffFactor` and `distanceModel`. + */ + refDistance?: number; + /** + * The maximum distance between the audio source and the listener, after which the volume is not reduced any further. + */ + maxDistance?: number; + /** + * A double value describing how quickly the volume is reduced as the source moves away from the listener. This value is used by all distance models. + */ + rolloffFactor?: number; + /** + * The angle, in degrees, of a cone inside of which there will be no volume reduction. + */ + coneInnerAngle?: number; + /** + * The angle, in degrees, of a cone outside of which the volume will be reduced by a constant value, defined by the `coneOuterGain` property. + */ + coneOuterAngle?: number; + /** + * The amount of volume reduction outside the cone defined by the `coneOuterAngle` attribute. Its default value is 0, meaning that no sound can be heard. A value between 0 and 1. + */ + coneOuterGain?: number; + /** + * Set this Sound object to automatically track the x/y position of this object. Can be a Phaser Game Object, Vec2 or anything that exposes public x/y properties. + */ + follow?: Phaser.Types.Math.Vector2Like; + }; + + /** + * An entry in the Web Audio Decoding Queue. + */ + type WebAudioDecodeEntry = { + /** + * The key of the sound. + */ + key: string; + /** + * The callback to invoke on successful decoding. + */ + success: Function; + /** + * The callback to invoke if the decoding fails. + */ + failure: Function; + /** + * Has the decoding of this sound file started? + */ + decoding: boolean; + }; + } namespace Textures { + /** + * An object containing the dimensions and mipmap data for a Compressed Texture. + */ + type CompressedTextureData = { + /** + * Is this a compressed texture? + */ + compressed: boolean; + /** + * Should this texture have mipmaps generated? + */ + generateMipmap: boolean; + /** + * The width of the maximum size of the texture. + */ + width: number; + /** + * The height of the maximum size of the texture. + */ + height: number; + /** + * The WebGL internal texture format. + */ + internalFormat: GLenum; + /** + * An array of MipmapType objects. + */ + mipmaps: Phaser.Types.Textures.MipmapType[]; + }; + + /** + * A Mipmap Data entry for a Compressed Texture. + */ + type MipmapType = { + /** + * The width of this level of the mipmap. + */ + width: number; + /** + * The height of this level of the mipmap. + */ + height: number; + /** + * The decoded pixel data. + */ + data: Uint8Array; + }; + /** * An object containing the position and color data for a single pixel in a CanvasTexture. */ @@ -65974,6 +77025,60 @@ declare namespace Phaser { spacing?: number; }; + /** + * An object containing the position and color data for a single pixel in a CanvasTexture. + */ + type StampConfig = { + /** + * The alpha value used by the stamp. + */ + alpha?: number; + /** + * The tint color value used by the stamp. WebGL only. + */ + tint?: number; + /** + * The angle of the stamp in degrees. Rotation takes place around its origin. + */ + angle?: number; + /** + * The rotation of the stamp in radians. Rotation takes place around its origin. + */ + rotation?: number; + /** + * Sets both the horizontal and vertical scale of the stamp with a single value. + */ + scale?: number; + /** + * Set the horizontal scale of the stamp. Overrides the scale property, if provided. + */ + scaleX?: number; + /** + * Set the vertical scale of the stamp. Overrides the scale property, if provided. + */ + scaleY?: number; + /** + * The horizontal origin of the stamp. 0 is the left, 0.5 is the center and 1 is the right. + */ + originX?: number; + /** + * The vertical origin of the stamp. 0 is the top, 0.5 is the center and 1 is the bottom. + */ + originY?: number; + /** + * The blend mode used when drawing the stamp. Defaults to 0 (normal). + */ + blendMode?: string | Phaser.BlendModes | number; + /** + * Erase this stamp from the texture? + */ + erase?: boolean; + /** + * Skip beginning and ending a batch with this call. Use if this is part of a bigger batched draw. + */ + skipBatch?: boolean; + }; + } namespace Tilemaps { @@ -65991,9 +77096,17 @@ declare namespace Phaser { */ name?: string; /** - * A custom class type to convert the objects in to. + * An Object Type to convert. */ - classType?: Phaser.GameObjects.GameObject; + type?: string; + /** + * A custom class type to convert the objects in to. The default is {@link Phaser.GameObjects.Sprite}. A custom class should resemble Sprite or Image; see {@link Phaser.Types.Tilemaps.CreateFromObjectsClassTypeConstructor}. + */ + classType?: Function; + /** + * By default, gid-based objects copy properties and respect the type of the tile at that gid and treat the object as an override. If this is true, they don't, and use only the fields set on the object itself. + */ + ignoreTileset?: boolean; /** * A Scene reference, passed to the Game Objects constructors. */ @@ -66003,31 +77116,33 @@ declare namespace Phaser { */ container?: Phaser.GameObjects.Container; /** - * Optional key of a Texture to be used, as stored in the Texture Manager, or a Texture instance. + * Optional key of a Texture to be used, as stored in the Texture Manager, or a Texture instance. If omitted, the object's gid's tileset key is used if available. */ key?: string | Phaser.Textures.Texture; /** - * Optional name or index of the frame within the Texture. + * Optional name or index of the frame within the Texture. If omitted, the tileset index is used, assuming that spritesheet frames exactly match tileset indices & geometries -- if available. */ frame?: string | number; }; + type CreateFromObjectsClassTypeConstructor = (scene: Phaser.Scene)=>void; + type DebugStyleOptions = { /** * Color to use for drawing a filled rectangle at * non-colliding tile locations. If set to null, non-colliding tiles will not be drawn. */ - "styleConfig.tileColor"?: Phaser.Display.Color; + "styleConfig.tileColor"?: Phaser.Display.Color | null; /** * Color to use for drawing a filled * rectangle at colliding tile locations. If set to null, colliding tiles will not be drawn. */ - "styleConfig.collidingTileColor"?: Phaser.Display.Color; + "styleConfig.collidingTileColor"?: Phaser.Display.Color | null; /** * Color to use for drawing a line at interesting * tile faces. If set to null, interesting tile faces will not be drawn. */ - "styleConfig.faceColor"?: Phaser.Display.Color; + "styleConfig.faceColor"?: Phaser.Display.Color | null; }; type FilteringOptions = { @@ -66191,7 +77306,7 @@ declare namespace Phaser { /** * The orientation of the map data (i.e. orthogonal, isometric, hexagonal), default 'orthogonal'. */ - orientation?: string; + orientation?: string | Phaser.Tilemaps.Orientation; /** * Determines the draw order of tilemap. Default is right-down. */ @@ -66269,15 +77384,15 @@ declare namespace Phaser { /** * Color to use for drawing a filled rectangle at non-colliding tile locations. If set to null, non-colliding tiles will not be drawn. */ - tileColor?: Phaser.Display.Color | number | null; + tileColor?: Phaser.Display.Color | number | null | null; /** * Color to use for drawing a filled rectangle at colliding tile locations. If set to null, colliding tiles will not be drawn. */ - collidingTileColor?: Phaser.Display.Color | number | null; + collidingTileColor?: Phaser.Display.Color | number | null | null; /** * Color to use for drawing a line at interesting tile faces. If set to null, interesting tile faces will not be drawn. */ - faceColor?: Phaser.Display.Color | number | null; + faceColor?: Phaser.Display.Color | number | null | null; }; type TiledObject = { @@ -66402,6 +77517,92 @@ declare namespace Phaser { } namespace Time { + type TimelineEvent = { + /** + * Has this event completed yet? + */ + complete: boolean; + /** + * Is this a once only event? + */ + once: boolean; + /** + * The time (in elapsed ms) at which this event will fire. + */ + time: number; + /** + * User-land callback which will be called when the Event fires if set. + */ + run?: Function; + /** + * Tween configuration object which will be used to create a Tween when the Event fires if set. + */ + tween?: Phaser.Types.Tweens.TweenBuilderConfig | Phaser.Types.Tweens.TweenChainBuilderConfig | Phaser.Tweens.Tween | Phaser.Tweens.TweenChain; + /** + * Object containing properties to set on the `target` when the Event fires if set. + */ + set?: object; + /** + * Sound configuration object which will be used to create a Sound when the Event fires if set. + */ + sound?: string | object; + /** + * The scope (`this` object) with which to invoke the run `callback`. + */ + target?: any; + /** + * Optional event name to emit when the Event fires. + */ + event?: string; + }; + + type TimelineEventConfig = { + /** + * The time (in ms) at which the Event will fire. The Timeline starts at 0. + */ + at?: number; + /** + * If the Timeline is already running, this is the time (in ms) at which the Event will fire based on its current elapsed value. If set, overrides the `at` property. + */ + in?: number; + /** + * Fire this event 'from' milliseconds after the previous event in the Timeline. If set it overrides the `at` and `in` properties. + */ + from?: number; + /** + * A function which will be called when the Event fires. + */ + run?: Function; + /** + * Optional string-based event name to emit when the Event fires. The event is emitted from the Timeline instance. + */ + event?: string; + /** + * The scope (`this` object) with which to invoke the run `callback`, if set. + */ + target?: any; + /** + * If set, the Event will be removed from the Timeline when it fires. + */ + once?: boolean; + /** + * If set, the Timeline will stop and enter a complete state when this Event fires, even if there are other events after it. + */ + stop?: boolean; + /** + * A Tween or TweenChain configuration object or instance. If set, the Event will create this Tween when it fires. + */ + tween?: Phaser.Types.Tweens.TweenBuilderConfig | Phaser.Types.Tweens.TweenChainBuilderConfig | Phaser.Tweens.Tween | Phaser.Tweens.TweenChain; + /** + * A key-value object of properties to set on the `target` when the Event fires. Ignored if no `target` is given. + */ + set?: object; + /** + * A key from the Sound Manager to play, or a config object for a sound to play when the Event fires. If a config object it must provide two properties: `key` and `config`. The `key` is the key of the sound to play, and the `config` is the config is a Phaser.Types.Sound.SoundConfig object. + */ + sound?: string | object; + }; + type TimerEventConfig = { /** * The delay after which the Timer Event should fire, in milliseconds. @@ -66420,7 +77621,7 @@ declare namespace Phaser { */ callback?: Function; /** - * The scope (`this` object) with which to invoke the `callback`. + * The scope (`this` object) with which to invoke the `callback`. The default is the Timer Event. */ callbackScope?: any; /** @@ -66489,6 +77690,14 @@ declare namespace Phaser { * Vertically flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipY` property. */ flipY?: boolean; + /** + * Retain the tween within the Tween Manager, even after playback completes? + */ + persist?: boolean; + /** + * The interpolation function to use for array-based tween values. + */ + interpolation?: Function; }; /** @@ -66496,11 +77705,11 @@ declare namespace Phaser { */ type Event = string; - type GetActiveCallback = (target: any, key: string, value: number, targetIndex: number, totalTargets: number, tween: Phaser.Tweens.Tween)=>void; + type GetActiveCallback = (target: any, key: string, value: number, targetIndex: number, totalTargets: number, tween: Phaser.Tweens.Tween)=>number; - type GetEndCallback = (target: any, key: string, value: number, targetIndex: number, totalTargets: number, tween: Phaser.Tweens.Tween)=>void; + type GetEndCallback = (target: any, key: string, value: number, targetIndex: number, totalTargets: number, tween: Phaser.Tweens.Tween)=>number; - type GetStartCallback = (target: any, key: string, value: number, targetIndex: number, totalTargets: number, tween: Phaser.Tweens.Tween)=>void; + type GetStartCallback = (target: any, key: string, value: number, targetIndex: number, totalTargets: number, tween: Phaser.Tweens.Tween)=>number; type NumberTweenBuilderConfig = { /** @@ -66543,10 +77752,6 @@ declare namespace Phaser { * Should the tween complete, then reverse the values incrementally to get back to the starting tween values? The reverse tweening will also take `duration` milliseconds to complete. */ yoyo?: boolean; - /** - * Used when the Tween is part of a Timeline. - */ - offset?: string | number | Function | object | any[]; /** * The time the tween will wait before the onComplete event is dispatched once it has completed, in ms. */ @@ -66563,10 +77768,6 @@ declare namespace Phaser { * Does the tween start in a paused state (true) or playing (false)? */ paused?: boolean; - /** - * Use frames or milliseconds? - */ - useFrames?: boolean; /** * Scope (this) for the callbacks. The default scope is the tween. */ @@ -66655,6 +77856,38 @@ declare namespace Phaser { * Scope (this) for `onYoyo`. */ onYoyoScope?: any; + /** + * A function to call when the tween is paused. + */ + onPause?: Phaser.Types.Tweens.TweenOnPauseCallback; + /** + * Additional parameters to pass to `onPause`. + */ + onPauseParams?: any[]; + /** + * Scope (this) for `onPause`. + */ + onPauseScope?: any; + /** + * A function to call when the tween is resumed after being paused. + */ + onResume?: Phaser.Types.Tweens.TweenOnResumeCallback; + /** + * Additional parameters to pass to `onResume`. + */ + onResumeParams?: any[]; + /** + * Scope (this) for `onResume`. + */ + onResumeScope?: any; + /** + * Will the Tween be automatically destroyed on completion, or retained for future playback? + */ + persist?: boolean; + /** + * The interpolation function to use if the `value` given is an array of numbers. + */ + interpolation?: string | Function; }; type StaggerConfig = { @@ -66676,210 +77909,237 @@ declare namespace Phaser { grid?: number[]; }; - type TimelineBuilderConfig = { - /** - * An array of tween configuration objects to create and add into the new Timeline. If this doesn't exist or is empty, the Timeline will start off paused and none of the other configuration settings will be read. If it's a function, it will be called and its return value will be used as the array. - */ - tweens?: Phaser.Types.Tweens.TweenBuilderConfig[] | object[] | Function; + type TweenBuilderConfig = {[key: string]: any} & { /** - * An array (or function which returns one) of default targets to which to apply the Timeline. Each individual Tween configuration can override this value. + * The object, or an array of objects, to run the tween on. */ - targets?: any; + targets: any; /** - * If specified, each Tween in the Timeline will get an equal portion of this duration, usually in milliseconds, by default. Each individual Tween configuration can override the Tween's duration. + * The number of milliseconds to delay before the tween will start. */ - totalDuration?: number; + delay?: number | Function; /** - * If `totalDuration` is not specified, the default duration, usually in milliseconds, of each Tween which will be created. Each individual Tween configuration can override the Tween's duration. + * The duration of the tween in milliseconds. */ duration?: number; /** - * The number of milliseconds to delay before the tween will start. Each individual Tween configuration can override this value. + * The easing equation to use for the tween. */ - delay?: number; + ease?: string | Function; /** - * Optional easing parameters. Each individual Tween configuration can override this value. + * Optional easing parameters. */ easeParams?: any[]; /** - * The easing equation to use for each tween. Each individual Tween configuration can override this value. - */ - ease?: string | Function; - /** - * The number of milliseconds to hold each tween before yoyo'ing. Each individual Tween configuration can override this value. + * The number of milliseconds to hold the tween for before yoyo'ing. */ hold?: number; /** - * The number of times to repeat each tween. Each individual Tween configuration can override this value. + * The number of times each property tween repeats. */ repeat?: number; /** - * The number of milliseconds to pause before each tween will repeat. Each individual Tween configuration can override this value. + * The number of milliseconds to pause before a repeat. */ repeatDelay?: number; /** - * Should each tween complete, then reverse the values incrementally to get back to the starting tween values? The reverse tweening will also take `duration` milliseconds to complete. Each individual Tween configuration can override this value. + * Should the tween complete, then reverse the values incrementally to get back to the starting tween values? The reverse tweening will also take `duration` milliseconds to complete. */ yoyo?: boolean; /** - * Horizontally flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipX` property. Each individual Tween configuration can override this value. + * Horizontally flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipX` property. */ flipX?: boolean; /** - * Vertically flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipY` property. Each individual Tween configuration can override this value. + * Vertically flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipY` property. */ flipY?: boolean; /** - * If specified, the time to wait, usually in milliseconds, before the Timeline completes. + * The time the tween will wait before the onComplete event is dispatched once it has completed, in ms. */ - completeDelay?: number | Function | object | any[]; + completeDelay?: string | number | Function | object | any[]; /** - * How many times the Timeline should loop, or -1 to loop indefinitely. + * The number of times the tween will repeat. (A value of 1 means the tween will play twice, as it repeated once.) The first loop starts after every property in the tween has completed once. */ - loop?: number | Function | object | any[]; + loop?: string | number | Function | object | any[]; /** - * The time, usually in milliseconds, between each loop. + * The time the tween will pause before starting either a yoyo or returning to the start for a repeat. */ - loopDelay?: number | Function | object | any[]; + loopDelay?: string | number | Function | object | any[]; /** - * If `true`, the Timeline will start paused. + * Does the tween start in a paused state (true) or playing (false)? */ paused?: boolean; /** - * If `true`, all duration in the Timeline will be in frames instead of milliseconds. + * The properties to tween. */ - useFrames?: boolean; + props?: {[key: string]: (number|string|Phaser.Types.Tweens.GetEndCallback|Phaser.Types.Tweens.TweenPropConfig)}; /** - * The default scope (`this` value) to use for each callback registered by the Timeline Builder. If not specified, the Timeline itself will be used. + * The scope (or context) for all of the callbacks. The default scope is the tween. */ callbackScope?: any; /** - * If specified, the `onStart` callback for the Timeline, called every time it starts playing. + * A function to call when the tween completes. */ - onStart?: Phaser.Types.Tweens.TimelineOnStartCallback; + onComplete?: Phaser.Types.Tweens.TweenOnCompleteCallback; /** - * The scope (`this` value) to use for the `onStart` callback. If not specified, the `callbackScope` will be used. + * Additional parameters to pass to `onComplete`. */ - onStartScope?: any; + onCompleteParams?: any[]; + /** + * A function to call each time the tween loops. + */ + onLoop?: Phaser.Types.Tweens.TweenOnLoopCallback; + /** + * Additional parameters to pass to `onLoop`. + */ + onLoopParams?: any[]; + /** + * A function to call each time the tween repeats. Called once per property per target. + */ + onRepeat?: Phaser.Types.Tweens.TweenOnRepeatCallback; + /** + * Additional parameters to pass to `onRepeat`. + */ + onRepeatParams?: any[]; + /** + * A function to call when the tween starts playback, after any delays have expired. + */ + onStart?: Phaser.Types.Tweens.TweenOnStartCallback; /** - * Additional arguments to pass to the `onStart` callback. The Timeline will always be the first argument. + * Additional parameters to pass to `onStart`. */ onStartParams?: any[]; /** - * If specified, the `onUpdate` callback for the Timeline, called every frame it's active, regardless of its Tweens. + * A function to call when the tween is stopped. */ - onUpdate?: Phaser.Types.Tweens.TimelineOnUpdateCallback; + onStop?: Phaser.Types.Tweens.TweenOnStopCallback; /** - * The scope (`this` value) to use for the `onUpdate` callback. If not specified, the `callbackScope` will be used. + * Additional parameters to pass to `onStop`. */ - onUpdateScope?: any; + onStopParams?: any[]; /** - * Additional arguments to pass to the `onUpdate` callback. The Timeline will always be the first argument. + * A function to call each time the tween steps. Called once per property per target. + */ + onUpdate?: Phaser.Types.Tweens.TweenOnUpdateCallback; + /** + * Additional parameters to pass to `onUpdate`. */ onUpdateParams?: any[]; /** - * If specified, the `onLoop` callback for the Timeline, called every time it loops. + * A function to call each time the tween yoyos. Called once per property per target. */ - onLoop?: Phaser.Types.Tweens.TimelineOnLoopCallback; + onYoyo?: Phaser.Types.Tweens.TweenOnYoyoCallback; /** - * The scope (`this` value) to use for the `onLoop` callback. If not specified, the `callbackScope` will be used. + * Additional parameters to pass to `onYoyo`. */ - onLoopScope?: any; + onYoyoParams?: any[]; /** - * Additional arguments to pass to the `onLoop` callback. The Timeline will always be the first argument. + * A function to call when the tween becomes active within the Tween Manager. */ - onLoopParams?: any[]; + onActive?: Phaser.Types.Tweens.TweenOnActiveCallback; /** - * If specified, the `onYoyo` callback for the Timeline, called every time it yoyos. + * Additional parameters to pass to `onActive`. */ - onYoyo?: Phaser.Types.Tweens.TimelineOnYoyoCallback; + onActiveParams?: any[]; /** - * The scope (`this` value) to use for the `onYoyo` callback. If not specified, the `callbackScope` will be used. + * A function to call when the tween is paused. */ - onYoyoScope?: any; + onPause?: Phaser.Types.Tweens.TweenOnPauseCallback; /** - * Additional arguments to pass to the `onYoyo` callback. The first argument will always be `null`, while the Timeline will always be the second argument. + * Additional parameters to pass to `onPause`. */ - onYoyoParams?: any[]; + onPauseParams?: any[]; /** - * If specified, the `onComplete` callback for the Timeline, called after it completes. + * A function to call when the tween is resumed after being paused. */ - onComplete?: Phaser.Types.Tweens.TimelineOnCompleteCallback; + onResume?: Phaser.Types.Tweens.TweenOnResumeCallback; /** - * The scope (`this` value) to use for the `onComplete` callback. If not specified, the `callbackScope` will be used. + * Additional parameters to pass to `onResume`. */ - onCompleteScope?: any; + onResumeParams?: any[]; /** - * Additional arguments to pass to the `onComplete` callback. The Timeline will always be the first argument. + * Will the Tween be automatically destroyed on completion, or retained for future playback? */ - onCompleteParams?: any[]; + persist?: boolean; + /** + * The interpolation function to use if the `value` given is an array of numbers. + */ + interpolation?: string | Function; }; - type TimelineOnCompleteCallback = (timeline: Phaser.Tweens.Timeline, ...param: any[])=>void; - - type TimelineOnLoopCallback = (timeline: Phaser.Tweens.Timeline, ...param: any[])=>void; - - type TimelineOnStartCallback = (timeline: Phaser.Tweens.Timeline, ...param: any[])=>void; - - type TimelineOnUpdateCallback = (timeline: Phaser.Tweens.Timeline, ...param: any[])=>void; - - type TimelineOnYoyoCallback = (timeline: Phaser.Tweens.Timeline, ...param: any[])=>void; - - type TweenBuilderConfig = { + type TweenCallbacks = { /** - * The object, or an array of objects, to run the tween on. + * A function to call when the tween becomes active within the Tween Manager. */ - targets: any; + onActive?: Phaser.Types.Tweens.TweenOnActiveCallback; /** - * The number of milliseconds to delay before the tween will start. + * A function to call when the tween starts playback, after any delays have expired. */ - delay?: number | Function; + onStart?: Phaser.Types.Tweens.TweenOnStartCallback; /** - * The duration of the tween in milliseconds. + * A function to call when the tween completes. */ - duration?: number; + onComplete?: Phaser.Types.Tweens.TweenOnCompleteCallback; /** - * The easing equation to use for the tween. + * A function to call each time the tween loops. */ - ease?: string | Function; + onLoop?: Phaser.Types.Tweens.TweenOnLoopCallback; /** - * Optional easing parameters. + * A function to call each time the tween is paused. */ - easeParams?: any[]; + onPause?: Phaser.Types.Tweens.TweenOnPauseCallback; /** - * The number of milliseconds to hold the tween for before yoyo'ing. + * A function to call each time the tween is resumed. */ - hold?: number; + onResume?: Phaser.Types.Tweens.TweenOnResumeCallback; /** - * The number of times each property tween repeats. + * A function to call each time the tween repeats. Called once per property per target. */ - repeat?: number; + onRepeat?: Phaser.Types.Tweens.TweenOnRepeatCallback; /** - * The number of milliseconds to pause before a repeat. + * A function to call when the tween is stopped. */ - repeatDelay?: number; + onStop?: Phaser.Types.Tweens.TweenOnStopCallback; /** - * Should the tween complete, then reverse the values incrementally to get back to the starting tween values? The reverse tweening will also take `duration` milliseconds to complete. + * A function to call each time the tween steps. Called once per property per target. */ - yoyo?: boolean; + onUpdate?: Phaser.Types.Tweens.TweenOnUpdateCallback; /** - * Horizontally flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipX` property. + * A function to call each time the tween yoyos. Called once per property per target. */ - flipX?: boolean; + onYoyo?: Phaser.Types.Tweens.TweenOnYoyoCallback; + }; + + type TweenCallbackTypes = 'onActive' | 'onComplete' | 'onLoop' | 'onPause' | 'onRepeat' | 'onResume' | 'onStart' | 'onStop' | 'onUpdate' | 'onYoyo'; + + type TweenChainBuilderConfig = {[key: string]: any} & { /** - * Vertically flip the target of the Tween when it completes (before it yoyos, if set to do so). Only works for targets that support the `flipY` property. + * The object, or an array of objects, to run the tween on. */ - flipY?: boolean; + targets: any; + /** + * The number of milliseconds to delay before the tween will start. + */ + delay?: number | Function; + /** + * The number of milliseconds to hold the tween for before yoyo'ing. + */ + hold?: number; /** - * Used when the Tween is part of a Timeline. + * The number of times each property tween repeats. */ - offset?: string | number | Function | object | any[]; + repeat?: number; + /** + * The number of milliseconds to pause before a repeat. + */ + repeatDelay?: number; /** * The time the tween will wait before the onComplete event is dispatched once it has completed, in ms. */ completeDelay?: string | number | Function | object | any[]; /** - * The number of times the tween will repeat. (A value of 1 means the tween will play twice, as it repeated once.) The first loop starts after every property tween has completed once. + * The number of times the tween will repeat. (A value of 1 means the tween will play twice, as it repeated once.) The first loop starts after every property in the tween has completed once. */ loop?: string | number | Function | object | any[]; /** @@ -66891,15 +78151,11 @@ declare namespace Phaser { */ paused?: boolean; /** - * The properties to tween. + * The tweens to chain together. */ - props?: {[key: string]: (number|string|Phaser.Types.Tweens.GetEndCallback|Phaser.Types.Tweens.TweenPropConfig)}; + tweens?: Phaser.Types.Tweens.TweenBuilderConfig[]; /** - * Use frames or milliseconds? - */ - useFrames?: boolean; - /** - * Scope (this) for the callbacks. The default scope is the tween. + * The scope (or context) for all of the callbacks. The default scope is the tween. */ callbackScope?: any; /** @@ -66910,10 +78166,6 @@ declare namespace Phaser { * Additional parameters to pass to `onComplete`. */ onCompleteParams?: any[]; - /** - * Scope (this) for `onComplete`. - */ - onCompleteScope?: any; /** * A function to call each time the tween loops. */ @@ -66922,10 +78174,6 @@ declare namespace Phaser { * Additional parameters to pass to `onLoop`. */ onLoopParams?: any[]; - /** - * Scope (this) for `onLoop`. - */ - onLoopScope?: any; /** * A function to call each time the tween repeats. Called once per property per target. */ @@ -66934,10 +78182,6 @@ declare namespace Phaser { * Additional parameters to pass to `onRepeat`. */ onRepeatParams?: any[]; - /** - * Scope (this) for `onRepeat`. - */ - onRepeatScope?: any; /** * A function to call when the tween starts playback, after any delays have expired. */ @@ -66946,10 +78190,6 @@ declare namespace Phaser { * Additional parameters to pass to `onStart`. */ onStartParams?: any[]; - /** - * Scope (this) for `onStart`. - */ - onStartScope?: any; /** * A function to call when the tween is stopped. */ @@ -66958,10 +78198,6 @@ declare namespace Phaser { * Additional parameters to pass to `onStop`. */ onStopParams?: any[]; - /** - * Scope (this) for `onStop`. - */ - onStopScope?: any; /** * A function to call each time the tween steps. Called once per property per target. */ @@ -66970,10 +78206,6 @@ declare namespace Phaser { * Additional parameters to pass to `onUpdate`. */ onUpdateParams?: any[]; - /** - * Scope (this) for `onUpdate`. - */ - onUpdateScope?: any; /** * A function to call each time the tween yoyos. Called once per property per target. */ @@ -66982,10 +78214,6 @@ declare namespace Phaser { * Additional parameters to pass to `onYoyo`. */ onYoyoParams?: any[]; - /** - * Scope (this) for `onYoyo`. - */ - onYoyoScope?: any; /** * A function to call when the tween becomes active within the Tween Manager. */ @@ -66995,9 +78223,25 @@ declare namespace Phaser { */ onActiveParams?: any[]; /** - * Scope (this) for `onActive`. + * A function to call when the tween is paused. + */ + onPause?: Phaser.Types.Tweens.TweenOnPauseCallback; + /** + * Additional parameters to pass to `onPause`. */ - onActiveScope?: any; + onPauseParams?: any[]; + /** + * A function to call when the tween is resumed after being paused. + */ + onResume?: Phaser.Types.Tweens.TweenOnResumeCallback; + /** + * Additional parameters to pass to `onResume`. + */ + onResumeParams?: any[]; + /** + * Will the Tween be automatically destroyed on completion, or retained for future playback? + */ + persist?: boolean; }; type TweenDataConfig = { @@ -67016,7 +78260,7 @@ declare namespace Phaser { /** * If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. */ - getActiveValue: Phaser.Types.Tweens.GetActiveCallback; + getActiveValue: Phaser.Types.Tweens.GetActiveCallback | null; /** * The returned value sets what the property will be at the END of the Tween. */ @@ -67030,7 +78274,7 @@ declare namespace Phaser { */ ease: Function; /** - * Duration of the tween in ms/frames, excludes time for yoyo or repeats. + * Duration of the tween in milliseconds, excludes time for yoyo or repeats. */ duration?: number; /** @@ -67038,7 +78282,7 @@ declare namespace Phaser { */ totalDuration?: number; /** - * Time in ms/frames before tween will start. + * Time in milliseconds before tween will start. */ delay?: number; /** @@ -67046,7 +78290,7 @@ declare namespace Phaser { */ yoyo?: boolean; /** - * Time in ms/frames the tween will pause before running the yoyo or starting a repeat. + * Time in milliseconds the tween will pause before running the yoyo or starting a repeat. */ hold?: number; /** @@ -67054,7 +78298,7 @@ declare namespace Phaser { */ repeat?: number; /** - * Time in ms/frames before the repeat will start. + * Time in milliseconds before the repeat will start. */ repeatDelay?: number; /** @@ -67093,14 +78337,6 @@ declare namespace Phaser { * The property value at the end of the ease. */ end?: number; - /** - * Time duration 1. - */ - t1?: number; - /** - * Time duration 2. - */ - t2?: number; /** * LoadValue generation functions. */ @@ -67108,20 +78344,20 @@ declare namespace Phaser { /** * TWEEN_CONST.CREATED */ - state?: number; + state?: Phaser.Tweens.StateType; }; type TweenDataGenConfig = { /** - * Time in ms/frames before tween will start. + * Time in milliseconds before tween will start. */ delay: Function; /** - * Duration of the tween in ms/frames, excludes time for yoyo or repeats. + * Duration of the tween in milliseconds, excludes time for yoyo or repeats. */ duration: Function; /** - * Time in ms/frames the tween will pause before running the yoyo or starting a repeat. + * Time in milliseconds the tween will pause before running the yoyo or starting a repeat. */ hold: Function; /** @@ -67129,32 +78365,103 @@ declare namespace Phaser { */ repeat: Function; /** - * Time in ms/frames before the repeat will start. + * Time in milliseconds before the repeat will start. */ repeatDelay: Function; }; - type TweenOnActiveCallback = (tween: Phaser.Tweens.Tween, target: any, ...param: any[])=>void; + type TweenFrameDataConfig = { + /** + * The target to tween. + */ + target: any; + /** + * The target index within the Tween targets array. + */ + index: number; + /** + * The property of the target being tweened. + */ + key: string; + /** + * Duration of the tween in milliseconds, excludes time for yoyo or repeats. + */ + duration?: number; + /** + * The total calculated duration of this TweenData (based on duration, repeat, delay and yoyo) + */ + totalDuration?: number; + /** + * Time in milliseconds before tween will start. + */ + delay?: number; + /** + * Time in milliseconds the tween will pause before running the yoyo or starting a repeat. + */ + hold?: number; + /** + * Number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + */ + repeat?: number; + /** + * Time in milliseconds before the repeat will start. + */ + repeatDelay?: number; + /** + * Automatically call toggleFlipX when the TweenData yoyos or repeats + */ + flipX?: boolean; + /** + * Automatically call toggleFlipY when the TweenData yoyos or repeats + */ + flipY?: boolean; + /** + * Between 0 and 1 showing completion of this TweenData. + */ + progress?: number; + /** + * Delta counter + */ + elapsed?: number; + /** + * How many repeats are left to run? + */ + repeatCounter?: number; + /** + * LoadValue generation functions. + */ + gen?: Phaser.Types.Tweens.TweenDataGenConfig; + /** + * TWEEN_CONST.CREATED + */ + state?: Phaser.Tweens.StateType; + }; + + type TweenOnActiveCallback = (tween: Phaser.Tweens.Tween, targets: any | any[], ...param: any[])=>void; + + type TweenOnCompleteCallback = (tween: Phaser.Tweens.Tween, targets: any | any[], ...param: any[])=>void; - type TweenOnCompleteCallback = (tween: Phaser.Tweens.Tween, targets: any[], ...param: any[])=>void; + type TweenOnLoopCallback = (tween: Phaser.Tweens.Tween, targets: any | any[], ...param: any[])=>void; - type TweenOnLoopCallback = (tween: Phaser.Tweens.Tween, targets: any[], ...param: any[])=>void; + type TweenOnPauseCallback = (tween: Phaser.Tweens.Tween, targets: any | any[], ...param: any[])=>void; - type TweenOnRepeatCallback = (tween: Phaser.Tweens.Tween, target: any, ...param: any[])=>void; + type TweenOnRepeatCallback = (tween: Phaser.Tweens.Tween, target: any, key: string, current: number, previous: number, ...param: any[])=>void; - type TweenOnStartCallback = (tween: Phaser.Tweens.Tween, targets: any[], ...param: any[])=>void; + type TweenOnResumeCallback = (tween: Phaser.Tweens.Tween, targets: any | any[], ...param: any[])=>void; - type TweenOnStopCallback = (tween: Phaser.Tweens.Tween, targets: any[], ...param: any[])=>void; + type TweenOnStartCallback = (tween: Phaser.Tweens.Tween, targets: any | any[], ...param: any[])=>void; - type TweenOnUpdateCallback = (tween: Phaser.Tweens.Tween, target: any, ...param: any[])=>void; + type TweenOnStopCallback = (tween: Phaser.Tweens.Tween, targets: any | any[], ...param: any[])=>void; - type TweenOnYoyoCallback = (tween: Phaser.Tweens.Tween, target: any, ...param: any[])=>void; + type TweenOnUpdateCallback = (tween: Phaser.Tweens.Tween, target: any, key: string, current: number, previous: number, ...param: any[])=>void; + + type TweenOnYoyoCallback = (tween: Phaser.Tweens.Tween, target: any, key: string, current: number, previous: number, ...param: any[])=>void; type TweenPropConfig = { /** * What the property will be at the END of the Tween. */ - value?: number | string | Phaser.Types.Tweens.GetEndCallback | Phaser.Types.Tweens.TweenPropConfig; + value?: number | number[] | string | Phaser.Types.Tweens.GetEndCallback | Phaser.Types.Tweens.TweenPropConfig; /** * What the property will be set to immediately when this tween becomes active. */ @@ -67172,11 +78479,11 @@ declare namespace Phaser { */ ease?: string | Function; /** - * Time in ms/frames before tween will start. + * Time in milliseconds before tween will start. */ delay?: number; /** - * Duration of the tween in ms/frames. + * Duration of the tween in milliseconds. */ duration?: number; /** @@ -67184,7 +78491,7 @@ declare namespace Phaser { */ yoyo?: boolean; /** - * Time in ms/frames the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * Time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. */ hold?: number; /** @@ -67192,7 +78499,7 @@ declare namespace Phaser { */ repeat?: number; /** - * Time in ms/frames before the repeat will start. + * Time in milliseconds before the repeat will start. */ repeatDelay?: number; /** @@ -67203,6 +78510,10 @@ declare namespace Phaser { * Should toggleFlipY be called when yoyo or repeat happens? */ flipY?: boolean; + /** + * The interpolation function to use if the `value` given is an array of numbers. + */ + interpolation?: string | Function; }; } @@ -67217,7 +78528,7 @@ declare namespace Phaser { * * 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 implements Phaser.Physics.Arcade.Components.Acceleration, Phaser.Physics.Arcade.Components.Angular, Phaser.Physics.Arcade.Components.Bounce, Phaser.Physics.Arcade.Components.Debug, Phaser.Physics.Arcade.Components.Drag, Phaser.Physics.Arcade.Components.Enable, Phaser.Physics.Arcade.Components.Friction, Phaser.Physics.Arcade.Components.Gravity, Phaser.Physics.Arcade.Components.Immovable, Phaser.Physics.Arcade.Components.Mass, Phaser.Physics.Arcade.Components.Pushable, Phaser.Physics.Arcade.Components.Size, Phaser.Physics.Arcade.Components.Velocity, Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class Image extends Phaser.GameObjects.Image implements Phaser.Physics.Arcade.Components.Acceleration, Phaser.Physics.Arcade.Components.Angular, Phaser.Physics.Arcade.Components.Bounce, Phaser.Physics.Arcade.Components.Debug, Phaser.Physics.Arcade.Components.Drag, Phaser.Physics.Arcade.Components.Enable, Phaser.Physics.Arcade.Components.Friction, Phaser.Physics.Arcade.Components.Gravity, Phaser.Physics.Arcade.Components.Immovable, Phaser.Physics.Arcade.Components.Mass, Phaser.Physics.Arcade.Components.Pushable, Phaser.Physics.Arcade.Components.Size, Phaser.Physics.Arcade.Components.Velocity, Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. @@ -67231,7 +78542,7 @@ declare namespace Phaser { /** * This Game Object's Physics Body. */ - body: Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody; + body: Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | null; /** * Clears all alpha values associated with this Game Object. @@ -67291,6 +78602,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -67305,7 +78617,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -67314,6 +78626,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -67327,12 +78640,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -67354,7 +78667,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -67424,77 +78737,97 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -67530,7 +78863,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -67540,10 +78873,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -67555,25 +78892,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -67629,6 +78968,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -67647,27 +79031,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -67683,27 +79105,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -67711,17 +79129,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -67734,9 +79145,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -67845,7 +79260,7 @@ declare namespace Phaser { * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * @param frame The frame to base the size of this Game Object on. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; /** * Sets the internal size of this Game Object, as used for frame or physics body creation. @@ -67929,17 +79344,19 @@ declare namespace Phaser { /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** * The tint value being applied to the top-left vertice of the Game Object. @@ -68044,6 +79461,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -68150,10 +79572,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -68307,8 +79729,9 @@ declare namespace Phaser { * @param value `true` if this body should collide with the world bounds, otherwise `false`. Default true. * @param bounceX If given this will be replace the `worldBounce.x` value. * @param bounceY If given this will be replace the `worldBounce.y` value. + * @param onWorldBounds If given this replaces the Body's `onWorldBounds` value. */ - setCollideWorldBounds(value?: boolean, bounceX?: number, bounceY?: number): this; + setCollideWorldBounds(value?: boolean, bounceX?: number, bounceY?: number, onWorldBounds?: boolean): this; /** * Sets the debug values of this body. @@ -68410,18 +79833,19 @@ declare namespace Phaser { /** * Enables this Game Object's Body. - * @param reset Also reset the Body and place it at (x, y). - * @param x The horizontal position to place the Game Object and Body. - * @param y The horizontal position to place the Game Object and Body. - * @param enableGameObject Also activate this Game Object. - * @param showGameObject Also show this Game Object. + * If you reset the Body you must also pass `x` and `y`. + * @param reset Also reset the Body and place the Game Object at (x, y). + * @param x The horizontal position to place the Game Object, if `reset` is true. + * @param y The horizontal position to place the Game Object, if `reset` is true. + * @param enableGameObject Also set this Game Object's `active` to true. + * @param showGameObject Also set this Game Object's `visible` to true. */ - enableBody(reset: boolean, x: number, y: number, enableGameObject: boolean, showGameObject: boolean): this; + enableBody(reset?: boolean, x?: number, y?: number, enableGameObject?: boolean, showGameObject?: boolean): this; /** * Stops and disables this Game Object's Body. - * @param disableGameObject Also deactivate this Game Object. Default false. - * @param hideGameObject Also hide this Game Object. Default false. + * @param disableGameObject Also set this Game Object's `active` to false. Default false. + * @param hideGameObject Also set this Game Object's `visible` to false. Default false. */ disableBody(disableGameObject?: boolean, hideGameObject?: boolean): this; @@ -68632,11 +80056,11 @@ declare namespace Phaser { * Tests if Game Objects overlap. See {@link Phaser.Physics.Arcade.World#overlap} * @param object1 The first object or array of objects to check. * @param object2 The second object or array of objects to check, or `undefined`. - * @param collideCallback An optional callback function that is called if the objects collide. + * @param overlapCallback An optional callback function that is called if the objects overlap. * @param processCallback An optional callback function that lets you perform additional checks against the two objects if they overlap. If this is set then `collideCallback` will only be called if this callback returns `true`. * @param callbackContext The context in which to run the callbacks. */ - overlap(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2?: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): boolean; + overlap(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2?: Phaser.Types.Physics.Arcade.ArcadeColliderType, overlapCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): boolean; /** * Performs a collision check and separation between the two physics enabled objects given, which can be single @@ -68663,7 +80087,7 @@ declare namespace Phaser { * @param 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 callbackContext The context in which to run the callbacks. */ - collide(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2?: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): boolean; + collide(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2?: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): boolean; /** * This advanced method is specifically for testing for collision between a single Sprite and an array of Tile objects. @@ -68686,7 +80110,7 @@ declare namespace Phaser { * @param 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 callbackContext The context in which to run the callbacks. */ - collideTiles(sprite: Phaser.GameObjects.GameObject, tiles: Phaser.Tilemaps.Tile[], collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): boolean; + collideTiles(sprite: Phaser.GameObjects.GameObject, tiles: Phaser.Tilemaps.Tile[], collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): boolean; /** * This advanced method is specifically for testing for overlaps between a single Sprite and an array of Tile objects. @@ -68704,7 +80128,7 @@ declare namespace Phaser { * @param 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 callbackContext The context in which to run the callbacks. */ - overlapTiles(sprite: Phaser.GameObjects.GameObject, tiles: Phaser.Tilemaps.Tile[], collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): boolean; + overlapTiles(sprite: Phaser.GameObjects.GameObject, tiles: Phaser.Tilemaps.Tile[], collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): boolean; /** * Pauses the simulation. @@ -68760,7 +80184,7 @@ declare namespace Phaser { * @param source Any object with public `x` and `y` properties, such as a Game Object or Geometry object. * @param targets The targets. */ - closest(source: any, targets?: Phaser.Physics.Arcade.Body[] | Phaser.Physics.Arcade.StaticBody[] | Phaser.GameObjects.GameObject[]): Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | Phaser.GameObjects.GameObject; + closest(source: Phaser.Types.Math.Vector2Like, targets?: Target[]): Target | null; /** * Finds the Body or Game Object farthest from a source point or object. @@ -68775,7 +80199,7 @@ declare namespace Phaser { * @param source Any object with public `x` and `y` properties, such as a Game Object or Geometry object. * @param targets The targets. */ - furthest(source: any, targets?: Phaser.Physics.Arcade.Body[] | Phaser.Physics.Arcade.StaticBody[] | Phaser.GameObjects.GameObject[]): Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | Phaser.GameObjects.GameObject; + furthest(source: any, targets?: Phaser.Physics.Arcade.Body[] | Phaser.Physics.Arcade.StaticBody[] | Phaser.GameObjects.GameObject[]): Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | Phaser.GameObjects.GameObject | null; /** * Move the given display object towards the x/y coordinates at a steady velocity. @@ -68880,7 +80304,7 @@ declare namespace Phaser { * The main difference between an Arcade Sprite and an Arcade Image is that you cannot animate an Arcade Image. * If you do not require animation then you can safely use Arcade Images instead of Arcade Sprites. */ - class Sprite extends Phaser.GameObjects.Sprite implements Phaser.Physics.Arcade.Components.Acceleration, Phaser.Physics.Arcade.Components.Angular, Phaser.Physics.Arcade.Components.Bounce, Phaser.Physics.Arcade.Components.Debug, Phaser.Physics.Arcade.Components.Drag, Phaser.Physics.Arcade.Components.Enable, Phaser.Physics.Arcade.Components.Friction, Phaser.Physics.Arcade.Components.Gravity, Phaser.Physics.Arcade.Components.Immovable, Phaser.Physics.Arcade.Components.Mass, Phaser.Physics.Arcade.Components.Pushable, Phaser.Physics.Arcade.Components.Size, Phaser.Physics.Arcade.Components.Velocity, Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class Sprite extends Phaser.GameObjects.Sprite implements Phaser.Physics.Arcade.Components.Acceleration, Phaser.Physics.Arcade.Components.Angular, Phaser.Physics.Arcade.Components.Bounce, Phaser.Physics.Arcade.Components.Debug, Phaser.Physics.Arcade.Components.Drag, Phaser.Physics.Arcade.Components.Enable, Phaser.Physics.Arcade.Components.Friction, Phaser.Physics.Arcade.Components.Gravity, Phaser.Physics.Arcade.Components.Immovable, Phaser.Physics.Arcade.Components.Mass, Phaser.Physics.Arcade.Components.Pushable, Phaser.Physics.Arcade.Components.Size, Phaser.Physics.Arcade.Components.Velocity, Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time. @@ -68894,7 +80318,7 @@ declare namespace Phaser { /** * This Game Object's Physics Body. */ - body: Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody; + body: Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | null; /** * Clears all alpha values associated with this Game Object. @@ -68954,6 +80378,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -68968,7 +80393,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -68977,6 +80402,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -68990,12 +80416,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -69017,7 +80443,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -69087,77 +80513,97 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -69193,7 +80639,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -69203,10 +80649,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -69218,25 +80668,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -69292,6 +80744,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -69310,27 +80807,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -69346,27 +80881,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -69374,17 +80905,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -69397,9 +80921,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -69508,7 +81036,7 @@ declare namespace Phaser { * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * @param frame The frame to base the size of this Game Object on. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; /** * Sets the internal size of this Game Object, as used for frame or physics body creation. @@ -69592,17 +81120,19 @@ declare namespace Phaser { /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** * The tint value being applied to the top-left vertice of the Game Object. @@ -69707,6 +81237,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -69813,10 +81348,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -69970,8 +81505,9 @@ declare namespace Phaser { * @param value `true` if this body should collide with the world bounds, otherwise `false`. Default true. * @param bounceX If given this will be replace the `worldBounce.x` value. * @param bounceY If given this will be replace the `worldBounce.y` value. + * @param onWorldBounds If given this replaces the Body's `onWorldBounds` value. */ - setCollideWorldBounds(value?: boolean, bounceX?: number, bounceY?: number): this; + setCollideWorldBounds(value?: boolean, bounceX?: number, bounceY?: number, onWorldBounds?: boolean): this; /** * Sets the debug values of this body. @@ -70073,18 +81609,19 @@ declare namespace Phaser { /** * Enables this Game Object's Body. - * @param reset Also reset the Body and place it at (x, y). - * @param x The horizontal position to place the Game Object and Body. - * @param y The horizontal position to place the Game Object and Body. - * @param enableGameObject Also activate this Game Object. - * @param showGameObject Also show this Game Object. + * If you reset the Body you must also pass `x` and `y`. + * @param reset Also reset the Body and place the Game Object at (x, y). + * @param x The horizontal position to place the Game Object, if `reset` is true. + * @param y The horizontal position to place the Game Object, if `reset` is true. + * @param enableGameObject Also set this Game Object's `active` to true. + * @param showGameObject Also set this Game Object's `visible` to true. */ - enableBody(reset: boolean, x: number, y: number, enableGameObject: boolean, showGameObject: boolean): this; + enableBody(reset?: boolean, x?: number, y?: number, enableGameObject?: boolean, showGameObject?: boolean): this; /** * Stops and disables this Game Object's Body. - * @param disableGameObject Also deactivate this Game Object. Default false. - * @param hideGameObject Also hide this Game Object. Default false. + * @param disableGameObject Also set this Game Object's `active` to false. Default false. + * @param hideGameObject Also set this Game Object's `visible` to false. Default false. */ disableBody(disableGameObject?: boolean, hideGameObject?: boolean): this; @@ -70232,9 +81769,9 @@ declare namespace Phaser { /** * * @param world The Arcade Physics simulation this Body belongs to. - * @param gameObject The Game Object this Body belongs to. + * @param gameObject The Game Object this Body belongs to. As of Phaser 3.60 this is now optional. */ - constructor(world: Phaser.Physics.Arcade.World, gameObject: Phaser.GameObjects.GameObject); + constructor(world: Phaser.Physics.Arcade.World, gameObject?: Phaser.GameObjects.GameObject); /** * The Arcade Physics simulation this Body belongs to. @@ -70243,9 +81780,16 @@ declare namespace Phaser { /** * The Game Object this Body belongs to. + * + * As of Phaser 3.60 this is now optional and can be undefined. */ gameObject: Phaser.GameObjects.GameObject; + /** + * A quick-test flag that signifies this is a Body, used in the World collision handler. + */ + readonly isBody: boolean; + /** * Transformations applied to this Body. */ @@ -70424,7 +81968,7 @@ declare namespace Phaser { * Rebound following a collision with the world boundary, relative to 1. * If null, `bounce` is used instead. */ - worldBounce: Phaser.Math.Vector2; + worldBounce: Phaser.Math.Vector2 | null; /** * The rectangle used for world boundary collisions. @@ -70437,7 +81981,8 @@ declare namespace Phaser { customBoundsRectangle: Phaser.Geom.Rectangle; /** - * Whether the simulation emits a `worldbounds` event when this Body collides with the world boundary (and `collideWorldBounds` is also true). + * Whether the simulation emits a `worldbounds` event when this Body collides with the world boundary + * (and `collideWorldBounds` is also true). */ onWorldBounds: boolean; @@ -70452,7 +81997,7 @@ declare namespace Phaser { onOverlap: boolean; /** - * The Body's absolute maximum velocity, in pixels per second. + * The absolute maximum velocity of this body, in pixels per second. * The horizontal and vertical components are applied separately. */ maxVelocity: Phaser.Math.Vector2; @@ -70686,7 +82231,7 @@ declare namespace Phaser { * boundary instead of the world boundaries. * @param bounds The new boundary rectangle. Pass `null` to use the World bounds. */ - setBoundsRectangle(bounds?: Phaser.Geom.Rectangle): this; + setBoundsRectangle(bounds?: Phaser.Geom.Rectangle | undefined): this; /** * Checks for collisions between this Body and the world boundary and separates them. @@ -70701,6 +82246,20 @@ declare namespace Phaser { */ setOffset(x: number, y?: number): Phaser.Physics.Arcade.Body; + /** + * Assign this Body to a new Game Object. + * + * Removes this body from the Physics World, assigns to the new Game Object, calls `setSize` and then + * adds this body back into the World again, setting it enabled, unless the `enable` argument is set to `false`. + * + * If this body already has a Game Object, then it will remove itself from that Game Object first. + * + * Only if the given `gameObject` has a `body` property will this Body be assigned to it. + * @param gameObject The Game Object this Body belongs to. + * @param enable Automatically enable this Body for physics. Default true. + */ + setGameObject(gameObject: Phaser.GameObjects.GameObject, enable?: boolean): Phaser.Physics.Arcade.Body; + /** * Sizes and positions this Body, as a rectangle. * Modifies the Body `offset` if `center` is true (the default). @@ -70893,9 +82452,9 @@ declare namespace Phaser { /** * Sets the Body's bounce. * @param x The horizontal bounce, relative to 1. - * @param y The vertical bounce, relative to 1. + * @param y The vertical bounce, relative to 1. Default x. */ - setBounce(x: number, y: number): Phaser.Physics.Arcade.Body; + setBounce(x: number, y?: number): Phaser.Physics.Arcade.Body; /** * Sets the Body's horizontal bounce. @@ -70912,9 +82471,9 @@ declare namespace Phaser { /** * Sets the Body's acceleration. * @param x The horizontal component, in pixels per second squared. - * @param y The vertical component, in pixels per second squared. + * @param y The vertical component, in pixels per second squared. Default x. */ - setAcceleration(x: number, y: number): Phaser.Physics.Arcade.Body; + setAcceleration(x: number, y?: number): Phaser.Physics.Arcade.Body; /** * Sets the Body's horizontal acceleration. @@ -70949,9 +82508,9 @@ declare namespace Phaser { /** * Sets the Body's drag. * @param x The horizontal component, in pixels per second squared. - * @param y The vertical component, in pixels per second squared. + * @param y The vertical component, in pixels per second squared. Default x. */ - setDrag(x: number, y: number): Phaser.Physics.Arcade.Body; + setDrag(x: number, y?: number): Phaser.Physics.Arcade.Body; /** * If this Body is using `drag` for deceleration this property controls how the drag is applied. @@ -70982,9 +82541,9 @@ declare namespace Phaser { /** * Sets the Body's gravity. * @param x The horizontal component, in pixels per second squared. - * @param y The vertical component, in pixels per second squared. + * @param y The vertical component, in pixels per second squared. Default x. */ - setGravity(x: number, y: number): Phaser.Physics.Arcade.Body; + setGravity(x: number, y?: number): Phaser.Physics.Arcade.Body; /** * Sets the Body's horizontal gravity. @@ -71001,9 +82560,9 @@ declare namespace Phaser { /** * Sets the Body's friction. * @param x The horizontal component, relative to 1. - * @param y The vertical component, relative to 1. + * @param y The vertical component, relative to 1. Default x. */ - setFriction(x: number, y: number): Phaser.Physics.Arcade.Body; + setFriction(x: number, y?: number): Phaser.Physics.Arcade.Body; /** * Sets the Body's horizontal friction. @@ -71120,7 +82679,7 @@ declare namespace Phaser { * @param processCallback The callback to invoke when the two objects collide. Must return a boolean. * @param callbackContext The scope in which to call the callbacks. */ - constructor(world: Phaser.Physics.Arcade.World, overlapOnly: boolean, object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback: ArcadePhysicsCallback, processCallback: ArcadePhysicsCallback, callbackContext: any); + constructor(world: Phaser.Physics.Arcade.World, overlapOnly: boolean, object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext: any); /** * The world in which the bodies will collide. @@ -71155,12 +82714,12 @@ declare namespace Phaser { /** * The callback to invoke when the two objects collide. */ - collideCallback: ArcadePhysicsCallback; + collideCallback: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback; /** * If a processCallback exists it must return true or collision checking will be skipped. */ - processCallback: ArcadePhysicsCallback; + processCallback: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback; /** * The context the collideCallback and processCallback will run in. @@ -71269,8 +82828,9 @@ declare namespace Phaser { * @param value `true` if this body should collide with the world bounds, otherwise `false`. Default true. * @param bounceX If given this will be replace the `worldBounce.x` value. * @param bounceY If given this will be replace the `worldBounce.y` value. + * @param onWorldBounds If given this replaces the Body's `onWorldBounds` value. */ - setCollideWorldBounds(value?: boolean, bounceX?: number, bounceY?: number): this; + setCollideWorldBounds(value?: boolean, bounceX?: number, bounceY?: number, onWorldBounds?: boolean): this; } /** @@ -71380,17 +82940,18 @@ declare namespace Phaser { interface Enable { /** * Enables this Game Object's Body. - * @param reset Also reset the Body and place it at (x, y). - * @param x The horizontal position to place the Game Object and Body. - * @param y The horizontal position to place the Game Object and Body. - * @param enableGameObject Also activate this Game Object. - * @param showGameObject Also show this Game Object. + * If you reset the Body you must also pass `x` and `y`. + * @param reset Also reset the Body and place the Game Object at (x, y). + * @param x The horizontal position to place the Game Object, if `reset` is true. + * @param y The horizontal position to place the Game Object, if `reset` is true. + * @param enableGameObject Also set this Game Object's `active` to true. + * @param showGameObject Also set this Game Object's `visible` to true. */ - enableBody(reset: boolean, x: number, y: number, enableGameObject: boolean, showGameObject: boolean): this; + enableBody(reset?: boolean, x?: number, y?: number, enableGameObject?: boolean, showGameObject?: boolean): this; /** * Stops and disables this Game Object's Body. - * @param disableGameObject Also deactivate this Game Object. Default false. - * @param hideGameObject Also hide this Game Object. Default false. + * @param disableGameObject Also set this Game Object's `active` to false. Default false. + * @param hideGameObject Also set this Game Object's `visible` to false. Default false. */ disableBody(disableGameObject?: boolean, hideGameObject?: boolean): this; /** @@ -71654,7 +83215,7 @@ declare namespace Phaser { * * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. */ - const COLLIDE: any; + const COLLIDE: string; /** * The Arcade Physics World Overlap Event. @@ -71668,7 +83229,7 @@ declare namespace Phaser { * * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. */ - const OVERLAP: any; + const OVERLAP: string; /** * The Arcade Physics World Pause Event. @@ -71677,7 +83238,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.physics.world.on('pause', listener)`. */ - const PAUSE: any; + const PAUSE: string; /** * The Arcade Physics World Resume Event. @@ -71686,7 +83247,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.physics.world.on('resume', listener)`. */ - const RESUME: any; + const RESUME: string; /** * The Arcade Physics Tile Collide Event. @@ -71700,7 +83261,7 @@ declare namespace Phaser { * * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. */ - const TILE_COLLIDE: any; + const TILE_COLLIDE: string; /** * The Arcade Physics Tile Overlap Event. @@ -71714,7 +83275,7 @@ declare namespace Phaser { * * Please note that 'collide' and 'overlap' are two different things in Arcade Physics. */ - const TILE_OVERLAP: any; + const TILE_OVERLAP: string; /** * The Arcade Physics World Bounds Event. @@ -71726,7 +83287,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.physics.world.on('worldbounds', listener)`. */ - const WORLD_BOUNDS: any; + const WORLD_BOUNDS: string; /** * The Arcade Physics World Step Event. @@ -71738,7 +83299,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.physics.world.on('worldstep', listener)`. */ - const WORLD_STEP: any; + const WORLD_STEP: string; } @@ -71776,7 +83337,7 @@ declare namespace Phaser { * @param processCallback The callback to invoke when the two objects collide. Must return a boolean. * @param callbackContext The scope in which to call the callbacks. */ - collider(object1: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[] | Phaser.GameObjects.Group | Phaser.GameObjects.Group[], object2: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[] | Phaser.GameObjects.Group | Phaser.GameObjects.Group[], collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): Phaser.Physics.Arcade.Collider; + collider(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): Phaser.Physics.Arcade.Collider; /** * Creates a new Arcade Physics Collider Overlap object. @@ -71786,7 +83347,7 @@ declare namespace Phaser { * @param processCallback The callback to invoke when the two objects collide. Must return a boolean. * @param callbackContext The scope in which to call the callbacks. */ - overlap(object1: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[] | Phaser.GameObjects.Group | Phaser.GameObjects.Group[], object2: Phaser.GameObjects.GameObject | Phaser.GameObjects.GameObject[] | Phaser.GameObjects.Group | Phaser.GameObjects.Group[], collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): Phaser.Physics.Arcade.Collider; + overlap(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): Phaser.Physics.Arcade.Collider; /** * Adds an Arcade Physics Body to the given Game Object. @@ -71847,6 +83408,30 @@ declare namespace Phaser { */ group(children?: Phaser.GameObjects.GameObject[] | Phaser.Types.Physics.Arcade.PhysicsGroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig, config?: Phaser.Types.Physics.Arcade.PhysicsGroupConfig | Phaser.Types.GameObjects.Group.GroupCreateConfig): Phaser.Physics.Arcade.Group; + /** + * Creates a new physics Body with the given position and size. + * + * This Body is not associated with any Game Object, but still exists within the world + * and can be tested for collision, have velocity, etc. + * @param x The horizontal position of this Body in the physics world. + * @param y The vertical position of this Body in the physics world. + * @param width The width of the Body in pixels. Cannot be negative or zero. Default 64. + * @param height The height of the Body in pixels. Cannot be negative or zero. Default 64. + */ + body(x: number, y: number, width?: number, height?: number): Phaser.Physics.Arcade.Body; + + /** + * Creates a new static physics Body with the given position and size. + * + * This Body is not associated with any Game Object, but still exists within the world + * and can be tested for collision, etc. + * @param x The horizontal position of this Body in the physics world. + * @param y The vertical position of this Body in the physics world. + * @param width The width of the Body in pixels. Cannot be negative or zero. Default 64. + * @param height The height of the Body in pixels. Cannot be negative or zero. Default 64. + */ + staticBody(x: number, y: number, width?: number, height?: number): Phaser.Physics.Arcade.Body; + /** * Destroys this Factory. */ @@ -71977,8 +83562,9 @@ declare namespace Phaser { * @param body2 The second Body to separate. * @param overlapOnly If `true`, the bodies will only have their overlap data set and no separation will take place. * @param bias A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. + * @param overlap If given then this value will be used as the overlap and no check will be run. */ - function SeparateX(body1: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body, overlapOnly: boolean, bias: number): boolean; + function SeparateX(body1: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body, overlapOnly: boolean, bias: number, overlap?: number): boolean; /** * Separates two overlapping bodies on the Y-axis (vertically). @@ -71990,8 +83576,9 @@ declare namespace Phaser { * @param body2 The second Body to separate. * @param overlapOnly If `true`, the bodies will only have their overlap data set and no separation will take place. * @param bias A value to add to the delta value during overlap checking. Used to prevent sprite tunneling. + * @param overlap If given then this value will be used as the overlap and no check will be run. */ - function SeparateY(body1: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body, overlapOnly: boolean, bias: number): boolean; + function SeparateY(body1: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body, overlapOnly: boolean, bias: number, overlap?: number): boolean; /** * A Static Arcade Physics Body. @@ -72007,9 +83594,9 @@ declare namespace Phaser { /** * * @param world The Arcade Physics simulation this Static Body belongs to. - * @param gameObject The Game Object this Static Body belongs to. + * @param gameObject The Game Object this Body belongs to. As of Phaser 3.60 this is now optional. */ - constructor(world: Phaser.Physics.Arcade.World, gameObject: Phaser.GameObjects.GameObject); + constructor(world: Phaser.Physics.Arcade.World, gameObject?: Phaser.GameObjects.GameObject); /** * The Arcade Physics simulation this Static Body belongs to. @@ -72018,9 +83605,16 @@ declare namespace Phaser { /** * The Game Object this Static Body belongs to. + * + * As of Phaser 3.60 this is now optional and can be undefined. */ gameObject: Phaser.GameObjects.GameObject; + /** + * A quick-test flag that signifies this is a Body, used in the World collision handler. + */ + readonly isBody: boolean; + /** * Whether the Static Body's boundary is drawn to the debug display. */ @@ -72658,6 +84252,11 @@ declare namespace Phaser { */ treeMinMax: Phaser.Types.Physics.Arcade.ArcadeWorldTreeMinMax; + /** + * The Filtering Options passed to `GetTilesWithinWorldXY` as part of the `collideSpriteVsTilemapLayer` check. + */ + tileFilterOptions: Phaser.Types.Tilemaps.FilteringOptions; + /** * Adds an Arcade Physics Body to a Game Object, an array of Game Objects, or the children of a Group. * @@ -72825,7 +84424,7 @@ declare namespace Phaser { * @param processCallback The callback to invoke when the two objects collide. Must return a boolean. * @param callbackContext The scope in which to call the callbacks. */ - addCollider(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): Phaser.Physics.Arcade.Collider; + addCollider(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): Phaser.Physics.Arcade.Collider; /** * Creates a new Overlap Collider object and adds it to the simulation. @@ -72843,7 +84442,7 @@ declare namespace Phaser { * @param processCallback The callback to invoke when the two objects overlap. Must return a boolean. * @param callbackContext The scope in which to call the callbacks. */ - addOverlap(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): Phaser.Physics.Arcade.Collider; + addOverlap(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): Phaser.Physics.Arcade.Collider; /** * Removes a Collider from the simulation so it is no longer processed. @@ -72921,18 +84520,16 @@ declare namespace Phaser { * @param processCallback The process callback. * @param callbackContext The context in which to invoke the callback. * @param overlapOnly If this a collide or overlap check? - * @param intersects Assert that the bodies intersect and should not be tested before separation. */ - separate(body1: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body, processCallback?: ArcadePhysicsCallback, callbackContext?: any, overlapOnly?: boolean, intersects?: boolean): boolean; + separate(body1: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any, overlapOnly?: boolean): boolean; /** * Separates two Bodies, when both are circular. * @param body1 The first Body to be separated. * @param body2 The second Body to be separated. * @param overlapOnly If this a collide or overlap check? - * @param bias A small value added to the calculations. */ - separateCircle(body1: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body, overlapOnly?: boolean, bias?: number): boolean; + separateCircle(body1: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body, overlapOnly?: boolean): boolean; /** * Checks to see if two Bodies intersect at all. @@ -72958,7 +84555,7 @@ declare namespace Phaser { * @param 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. */ - overlap(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2?: Phaser.Types.Physics.Arcade.ArcadeColliderType, overlapCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): boolean; + overlap(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2?: Phaser.Types.Physics.Arcade.ArcadeColliderType, overlapCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): boolean; /** * Performs a collision check and separation between the two physics enabled objects given, which can be single @@ -72986,7 +84583,7 @@ declare namespace Phaser { * @param 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 callbackContext The context in which to run the callbacks. */ - collide(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2?: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): boolean; + collide(object1: Phaser.Types.Physics.Arcade.ArcadeColliderType, object2?: Phaser.Types.Physics.Arcade.ArcadeColliderType, collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): boolean; /** * This advanced method is specifically for testing for collision between a single Sprite and an array of Tile objects. @@ -73009,7 +84606,7 @@ declare namespace Phaser { * @param 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 callbackContext The context in which to run the callbacks. */ - collideTiles(sprite: Phaser.GameObjects.GameObject, tiles: Phaser.Tilemaps.Tile[], collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): boolean; + collideTiles(sprite: Phaser.GameObjects.GameObject, tiles: Phaser.Tilemaps.Tile[], collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): boolean; /** * This advanced method is specifically for testing for overlaps between a single Sprite and an array of Tile objects. @@ -73027,7 +84624,7 @@ declare namespace Phaser { * @param 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 callbackContext The context in which to run the callbacks. */ - overlapTiles(sprite: Phaser.GameObjects.GameObject, tiles: Phaser.Tilemaps.Tile[], collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): boolean; + overlapTiles(sprite: Phaser.GameObjects.GameObject, tiles: Phaser.Tilemaps.Tile[], collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): boolean; /** * Internal handler for Sprite vs. Tilemap collisions. @@ -73039,7 +84636,7 @@ declare namespace Phaser { * @param callbackContext The context in which to run the callbacks. * @param overlapOnly Whether this is a collision or overlap check. */ - collideSpriteVsTilemapLayer(sprite: Phaser.GameObjects.GameObject, tilemapLayer: Phaser.Tilemaps.TilemapLayer, collideCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any, overlapOnly?: boolean): boolean; + collideSpriteVsTilemapLayer(sprite: Phaser.GameObjects.GameObject, tilemapLayer: Phaser.Tilemaps.TilemapLayer, collideCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any, overlapOnly?: boolean): boolean; /** * Wrap an object's coordinates (or several objects' coordinates) within {@link Phaser.Physics.Arcade.World#bounds}. @@ -73223,7 +84820,7 @@ declare namespace Phaser { * Sets the restitution on the physics object. * @param value A Number that defines the restitution (elasticity) of the body. The value is always positive and is in the range (0, 1). A value of 0 means collisions may be perfectly inelastic and no bouncing may occur. A value of 0.8 means the body may bounce back with approximately 80% of its kinetic energy. Note that collision response is based on pairs of bodies, and that restitution values are combined with the following formula: `Math.max(bodyA.restitution, bodyB.restitution)` */ - setBounce(value: number): Phaser.GameObjects.GameObject; + setBounce(value: number): this; } /** @@ -73236,7 +84833,7 @@ declare namespace Phaser { * categories are included in their collision masks (see {@link #setCollidesWith}). * @param value Unique category bitfield. */ - setCollisionCategory(value: number): Phaser.GameObjects.GameObject; + setCollisionCategory(value: number): this; /** * Sets the collision group of this Game Object's Matter Body. If this is zero or two Matter Bodies have different values, * they will collide according to the usual rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}). @@ -73244,14 +84841,14 @@ declare namespace Phaser { * they will never collide. * @param value Unique group index. */ - setCollisionGroup(value: number): Phaser.GameObjects.GameObject; + setCollisionGroup(value: number): this; /** * Sets the collision mask for this Game Object's Matter Body. Two Matter Bodies with different collision groups will only * collide if each one includes the other's category in its mask based on a bitwise AND, i.e. `(categoryA & maskB) !== 0` * and `(categoryB & maskA) !== 0` are both true. * @param categories A unique category bitfield, or an array of them. */ - setCollidesWith(categories: number | number[]): Phaser.GameObjects.GameObject; + setCollidesWith(categories: number | number[]): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. * @@ -73259,7 +84856,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke when this body starts colliding with another. */ - setOnCollide(callback: Function): Phaser.GameObjects.GameObject; + setOnCollide(callback: Function): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. * @@ -73267,7 +84864,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke when this body stops colliding with another. */ - setOnCollideEnd(callback: Function): Phaser.GameObjects.GameObject; + setOnCollideEnd(callback: Function): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. * @@ -73275,7 +84872,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke for the duration of this body colliding with another. */ - setOnCollideActive(callback: Function): Phaser.GameObjects.GameObject; + setOnCollideActive(callback: Function): this; /** * The callback is sent a reference to the other body, along with a `Phaser.Types.Physics.Matter.MatterCollisionData` object. * @@ -73284,7 +84881,7 @@ declare namespace Phaser { * @param body The body, or an array of bodies, to test for collisions with. * @param callback The callback to invoke when this body collides with the given body or bodies. */ - setOnCollideWith(body: MatterJS.Body | MatterJS.Body[], callback: Function): Phaser.GameObjects.GameObject; + setOnCollideWith(body: MatterJS.Body | MatterJS.Body[], callback: Function): this; } /** @@ -73295,41 +84892,41 @@ declare namespace Phaser { * Applies a force to a body. * @param force A Vector that specifies the force to apply. */ - applyForce(force: Phaser.Math.Vector2): Phaser.GameObjects.GameObject; + applyForce(force: Phaser.Math.Vector2): this; /** * Applies a force to a body from a given position. * @param position The position in which the force comes from. * @param force A Vector that specifies the force to apply. */ - applyForceFrom(position: Phaser.Math.Vector2, force: Phaser.Math.Vector2): Phaser.GameObjects.GameObject; + applyForceFrom(position: Phaser.Math.Vector2, force: Phaser.Math.Vector2): this; /** * Apply thrust to the forward position of the body. * * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrust(speed: number): Phaser.GameObjects.GameObject; + thrust(speed: number): this; /** * Apply thrust to the left position of the body. * * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrustLeft(speed: number): Phaser.GameObjects.GameObject; + thrustLeft(speed: number): this; /** * Apply thrust to the right position of the body. * * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrustRight(speed: number): Phaser.GameObjects.GameObject; + thrustRight(speed: number): this; /** * Apply thrust to the back position of the body. * * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrustBack(speed: number): Phaser.GameObjects.GameObject; + thrustBack(speed: number): this; } /** @@ -73342,21 +84939,21 @@ declare namespace Phaser { * @param air If provided, the new air resistance of the Body. The higher the value, the faster the Body will slow as it moves through space. 0 means the body has no air resistance. * @param fstatic If provided, the new static friction of the Body. The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. 0 means the body will never "stick" when it is nearly stationary. */ - setFriction(value: number, air?: number, fstatic?: number): Phaser.GameObjects.GameObject; + setFriction(value: number, air?: number, fstatic?: number): this; /** * Sets a new air resistance for this Game Object's Matter Body. * A value of 0 means the Body will never slow as it moves through space. * The higher the value, the faster a Body slows when moving through space. * @param value The new air resistance for the Body. */ - setFrictionAir(value: number): Phaser.GameObjects.GameObject; + setFrictionAir(value: number): this; /** * Sets a new static friction for this Game Object's Matter Body. * A value of 0 means the Body will never "stick" when it is nearly stationary. * The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. * @param value The new static friction for the Body. */ - setFrictionStatic(value: number): Phaser.GameObjects.GameObject; + setFrictionStatic(value: number): this; } /** @@ -73367,7 +84964,7 @@ declare namespace Phaser { * A togglable function for ignoring world gravity in real-time on the current body. * @param value Set to true to ignore the effect of world gravity, or false to not ignore it. */ - setIgnoreGravity(value: boolean): Phaser.GameObjects.GameObject; + setIgnoreGravity(value: boolean): this; } /** @@ -73378,12 +84975,12 @@ declare namespace Phaser { * Sets the mass of the Game Object's Matter Body. * @param value The new mass of the body. */ - setMass(value: number): Phaser.GameObjects.GameObject; + setMass(value: number): this; /** * Sets density of the body. * @param value The new density of the body. */ - setDensity(value: number): Phaser.GameObjects.GameObject; + setDensity(value: number): this; /** * The body's center of mass. * @@ -73403,7 +85000,7 @@ declare namespace Phaser { * Sensors trigger collision events, but don't react with colliding body physically. * @param value `true` to set the body as a sensor, or `false` to disable it. */ - setSensor(value: boolean): Phaser.GameObjects.GameObject; + setSensor(value: boolean): this; /** * Is the body belonging to this Game Object a sensor or not? */ @@ -73423,7 +85020,7 @@ declare namespace Phaser { * @param height Height of the rectangle. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setRectangle(width: number, height: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setRectangle(width: number, height: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set the body on a Game Object to a circle. * @@ -73432,7 +85029,7 @@ declare namespace Phaser { * @param radius The radius of the circle. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setCircle(radius: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setCircle(radius: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set the body on the Game Object to a polygon shape. * @@ -73442,7 +85039,7 @@ declare namespace Phaser { * @param sides The number of sides the polygon will have. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setPolygon(radius: number, sides: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setPolygon(radius: number, sides: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set the body on the Game Object to a trapezoid shape. * @@ -73453,7 +85050,7 @@ declare namespace Phaser { * @param slope The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setTrapezoid(width: number, height: number, slope: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setTrapezoid(width: number, height: number, slope: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set this Game Object to use the given existing Matter Body. * @@ -73461,7 +85058,7 @@ declare namespace Phaser { * @param body The Body this Game Object should use. * @param addToWorld Should the body be immediately added to the World? Default true. */ - setExistingBody(body: MatterJS.BodyType, addToWorld?: boolean): Phaser.GameObjects.GameObject; + setExistingBody(body: MatterJS.BodyType, addToWorld?: boolean): this; /** * Set this Game Object to create and use a new Body based on the configuration object given. * @@ -73470,7 +85067,7 @@ declare namespace Phaser { * @param config Either a string, such as `circle`, or a Matter Set Body Configuration object. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setBody(config: string | Phaser.Types.Physics.Matter.MatterSetBodyConfig, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setBody(config: string | Phaser.Types.Physics.Matter.MatterSetBodyConfig, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; } /** @@ -73521,7 +85118,7 @@ declare namespace Phaser { * Changes the physics body to be either static `true` or dynamic `false`. * @param value `true` to set the body as being static, or `false` to make it dynamic. */ - setStatic(value: boolean): Phaser.GameObjects.GameObject; + setStatic(value: boolean): this; /** * Returns `true` if the body is static, otherwise `false` for a dynamic body. */ @@ -73596,28 +85193,47 @@ declare namespace Phaser { * Contains methods for changing the velocity of a Matter Body. Should be used as a mixin and not called directly. */ interface Velocity { - /** - * Sets the angular velocity of the body instantly. - * Position, angle, force etc. are unchanged. - * @param value The angular velocity. - */ - setAngularVelocity(value: number): Phaser.GameObjects.GameObject; /** * Sets the horizontal velocity of the physics body. * @param x The horizontal velocity value. */ - setVelocityX(x: number): Phaser.GameObjects.GameObject; + setVelocityX(x: number): this; /** * Sets vertical velocity of the physics body. * @param y The vertical velocity value. */ - setVelocityY(y: number): Phaser.GameObjects.GameObject; + setVelocityY(y: number): this; /** * Sets both the horizontal and vertical velocity of the physics body. * @param x The horizontal velocity value. * @param y The vertical velocity value, it can be either positive or negative. If not given, it will be the same as the `x` value. Default x. */ - setVelocity(x: number, y?: number): Phaser.GameObjects.GameObject; + setVelocity(x: number, y?: number): this; + /** + * Gets the current linear velocity of the physics body. + */ + getVelocity(): Phaser.Types.Math.Vector2Like; + /** + * Sets the angular velocity of the body instantly. + * Position, angle, force etc. are unchanged. + * @param velocity The angular velocity. + */ + setAngularVelocity(velocity: number): this; + /** + * Gets the current rotational velocity of the body. + */ + getAngularVelocity(): number; + /** + * Sets the current rotational speed of the body. + * Direction is maintained. Affects body angular velocity. + * @param speed The angular speed. + */ + setAngularSpeed(speed: number): this; + /** + * Gets the current rotational speed of the body. + * Equivalent to the magnitude of its angular velocity. + */ + getAngularSpeed(): number; } } @@ -73649,7 +85265,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('afteradd', listener)`. */ - const AFTER_ADD: any; + const AFTER_ADD: string; type AfterRemoveEvent = { /** @@ -73669,12 +85285,12 @@ declare namespace Phaser { /** * The Matter Physics After Remove Event. * - * This event is dispatched by a Matter Physics World instance at the end of the process when a + * This event is dispatched by a Matter Physics World instance at the end of the process when a * Body or Constraint was removed from the world. * * Listen to it from a Scene using: `this.matter.world.on('afterremove', listener)`. */ - const AFTER_REMOVE: any; + const AFTER_REMOVE: string; type AfterUpdateEvent = { /** @@ -73698,7 +85314,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('afterupdate', listener)`. */ - const AFTER_UPDATE: any; + const AFTER_UPDATE: string; type BeforeAddEvent = { /** @@ -73723,7 +85339,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('beforeadd', listener)`. */ - const BEFORE_ADD: any; + const BEFORE_ADD: string; type BeforeRemoveEvent = { /** @@ -73743,12 +85359,12 @@ declare namespace Phaser { /** * The Matter Physics Before Remove Event. * - * This event is dispatched by a Matter Physics World instance at the start of the process when a + * This event is dispatched by a Matter Physics World instance at the start of the process when a * Body or Constraint is being removed from the world. * * Listen to it from a Scene using: `this.matter.world.on('beforeremove', listener)`. */ - const BEFORE_REMOVE: any; + const BEFORE_REMOVE: string; type BeforeUpdateEvent = { /** @@ -73772,7 +85388,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('beforeupdate', listener)`. */ - const BEFORE_UPDATE: any; + const BEFORE_UPDATE: string; type CollisionActiveEvent = { /** @@ -73801,7 +85417,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('collisionactive', listener)`. */ - const COLLISION_ACTIVE: any; + const COLLISION_ACTIVE: string; type CollisionEndEvent = { /** @@ -73830,7 +85446,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('collisionend', listener)`. */ - const COLLISION_END: any; + const COLLISION_END: string; type CollisionStartEvent = { /** @@ -73859,7 +85475,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('collisionstart', listener)`. */ - const COLLISION_START: any; + const COLLISION_START: string; /** * The Matter Physics Drag End Event. @@ -73869,7 +85485,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('dragend', listener)`. */ - const DRAG_END: any; + const DRAG_END: string; /** * The Matter Physics Drag Event. @@ -73879,7 +85495,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('drag', listener)`. */ - const DRAG: any; + const DRAG: string; /** * The Matter Physics Drag Start Event. @@ -73889,7 +85505,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('dragstart', listener)`. */ - const DRAG_START: any; + const DRAG_START: string; /** * The Matter Physics World Pause Event. @@ -73898,7 +85514,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('pause', listener)`. */ - const PAUSE: any; + const PAUSE: string; /** * The Matter Physics World Resume Event. @@ -73907,7 +85523,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('resume', listener)`. */ - const RESUME: any; + const RESUME: string; type SleepEndEvent = { /** @@ -73927,7 +85543,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('sleepend', listener)`. */ - const SLEEP_END: any; + const SLEEP_END: string; type SleepStartEvent = { /** @@ -73947,7 +85563,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.matter.world.on('sleepstart', listener)`. */ - const SLEEP_START: any; + const SLEEP_START: string; } @@ -74450,7 +86066,7 @@ declare namespace Phaser { * events and physics bodies, or be tweened, tinted or scrolled. The main difference between an * Image and a Sprite is that you cannot animate an Image as they do not have the Animation component. */ - class Image extends Phaser.GameObjects.Image implements Phaser.Physics.Matter.Components.Bounce, Phaser.Physics.Matter.Components.Collision, Phaser.Physics.Matter.Components.Force, Phaser.Physics.Matter.Components.Friction, Phaser.Physics.Matter.Components.Gravity, Phaser.Physics.Matter.Components.Mass, Phaser.Physics.Matter.Components.Sensor, Phaser.Physics.Matter.Components.SetBody, Phaser.Physics.Matter.Components.Sleep, Phaser.Physics.Matter.Components.Static, Phaser.Physics.Matter.Components.Transform, Phaser.Physics.Matter.Components.Velocity, Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class Image extends Phaser.GameObjects.Image implements Phaser.Physics.Matter.Components.Bounce, Phaser.Physics.Matter.Components.Collision, Phaser.Physics.Matter.Components.Force, Phaser.Physics.Matter.Components.Friction, Phaser.Physics.Matter.Components.Gravity, Phaser.Physics.Matter.Components.Mass, Phaser.Physics.Matter.Components.Sensor, Phaser.Physics.Matter.Components.SetBody, Phaser.Physics.Matter.Components.Sleep, Phaser.Physics.Matter.Components.Static, Phaser.Physics.Matter.Components.Transform, Phaser.Physics.Matter.Components.Velocity, Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param world A reference to the Matter.World instance that this body belongs to. @@ -74525,6 +86141,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -74539,7 +86156,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -74548,6 +86165,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -74561,12 +86179,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -74588,7 +86206,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -74658,77 +86276,97 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -74764,7 +86402,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -74774,10 +86412,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -74789,25 +86431,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -74863,6 +86507,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -74881,27 +86570,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -74917,27 +86644,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -74945,17 +86668,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -74968,9 +86684,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -75079,7 +86799,7 @@ declare namespace Phaser { * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * @param frame The frame to base the size of this Game Object on. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; /** * Sets the internal size of this Game Object, as used for frame or physics body creation. @@ -75163,17 +86883,19 @@ declare namespace Phaser { /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** * The tint value being applied to the top-left vertice of the Game Object. @@ -75278,6 +87000,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -75384,10 +87111,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -75471,7 +87198,7 @@ declare namespace Phaser { * Sets the restitution on the physics object. * @param value A Number that defines the restitution (elasticity) of the body. The value is always positive and is in the range (0, 1). A value of 0 means collisions may be perfectly inelastic and no bouncing may occur. A value of 0.8 means the body may bounce back with approximately 80% of its kinetic energy. Note that collision response is based on pairs of bodies, and that restitution values are combined with the following formula: `Math.max(bodyA.restitution, bodyB.restitution)` */ - setBounce(value: number): Phaser.GameObjects.GameObject; + setBounce(value: number): this; /** * Sets the collision category of this Game Object's Matter Body. This number must be a power of two between 2^0 (= 1) and 2^31. @@ -75479,7 +87206,7 @@ declare namespace Phaser { * categories are included in their collision masks (see {@link #setCollidesWith}). * @param value Unique category bitfield. */ - setCollisionCategory(value: number): Phaser.GameObjects.GameObject; + setCollisionCategory(value: number): this; /** * Sets the collision group of this Game Object's Matter Body. If this is zero or two Matter Bodies have different values, @@ -75488,7 +87215,7 @@ declare namespace Phaser { * they will never collide. * @param value Unique group index. */ - setCollisionGroup(value: number): Phaser.GameObjects.GameObject; + setCollisionGroup(value: number): this; /** * Sets the collision mask for this Game Object's Matter Body. Two Matter Bodies with different collision groups will only @@ -75496,7 +87223,7 @@ declare namespace Phaser { * and `(categoryB & maskA) !== 0` are both true. * @param categories A unique category bitfield, or an array of them. */ - setCollidesWith(categories: number | number[]): Phaser.GameObjects.GameObject; + setCollidesWith(categories: number | number[]): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -75505,7 +87232,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke when this body starts colliding with another. */ - setOnCollide(callback: Function): Phaser.GameObjects.GameObject; + setOnCollide(callback: Function): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -75514,7 +87241,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke when this body stops colliding with another. */ - setOnCollideEnd(callback: Function): Phaser.GameObjects.GameObject; + setOnCollideEnd(callback: Function): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -75523,7 +87250,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke for the duration of this body colliding with another. */ - setOnCollideActive(callback: Function): Phaser.GameObjects.GameObject; + setOnCollideActive(callback: Function): this; /** * The callback is sent a reference to the other body, along with a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -75533,20 +87260,20 @@ declare namespace Phaser { * @param body The body, or an array of bodies, to test for collisions with. * @param callback The callback to invoke when this body collides with the given body or bodies. */ - setOnCollideWith(body: MatterJS.Body | MatterJS.Body[], callback: Function): Phaser.GameObjects.GameObject; + setOnCollideWith(body: MatterJS.Body | MatterJS.Body[], callback: Function): this; /** * Applies a force to a body. * @param force A Vector that specifies the force to apply. */ - applyForce(force: Phaser.Math.Vector2): Phaser.GameObjects.GameObject; + applyForce(force: Phaser.Math.Vector2): this; /** * Applies a force to a body from a given position. * @param position The position in which the force comes from. * @param force A Vector that specifies the force to apply. */ - applyForceFrom(position: Phaser.Math.Vector2, force: Phaser.Math.Vector2): Phaser.GameObjects.GameObject; + applyForceFrom(position: Phaser.Math.Vector2, force: Phaser.Math.Vector2): this; /** * Apply thrust to the forward position of the body. @@ -75554,7 +87281,7 @@ declare namespace Phaser { * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrust(speed: number): Phaser.GameObjects.GameObject; + thrust(speed: number): this; /** * Apply thrust to the left position of the body. @@ -75562,7 +87289,7 @@ declare namespace Phaser { * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrustLeft(speed: number): Phaser.GameObjects.GameObject; + thrustLeft(speed: number): this; /** * Apply thrust to the right position of the body. @@ -75570,7 +87297,7 @@ declare namespace Phaser { * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrustRight(speed: number): Phaser.GameObjects.GameObject; + thrustRight(speed: number): this; /** * Apply thrust to the back position of the body. @@ -75578,7 +87305,7 @@ declare namespace Phaser { * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrustBack(speed: number): Phaser.GameObjects.GameObject; + thrustBack(speed: number): this; /** * Sets new friction values for this Game Object's Matter Body. @@ -75586,7 +87313,7 @@ declare namespace Phaser { * @param air If provided, the new air resistance of the Body. The higher the value, the faster the Body will slow as it moves through space. 0 means the body has no air resistance. * @param fstatic If provided, the new static friction of the Body. The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. 0 means the body will never "stick" when it is nearly stationary. */ - setFriction(value: number, air?: number, fstatic?: number): Phaser.GameObjects.GameObject; + setFriction(value: number, air?: number, fstatic?: number): this; /** * Sets a new air resistance for this Game Object's Matter Body. @@ -75594,7 +87321,7 @@ declare namespace Phaser { * The higher the value, the faster a Body slows when moving through space. * @param value The new air resistance for the Body. */ - setFrictionAir(value: number): Phaser.GameObjects.GameObject; + setFrictionAir(value: number): this; /** * Sets a new static friction for this Game Object's Matter Body. @@ -75602,25 +87329,25 @@ declare namespace Phaser { * The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. * @param value The new static friction for the Body. */ - setFrictionStatic(value: number): Phaser.GameObjects.GameObject; + setFrictionStatic(value: number): this; /** * A togglable function for ignoring world gravity in real-time on the current body. * @param value Set to true to ignore the effect of world gravity, or false to not ignore it. */ - setIgnoreGravity(value: boolean): Phaser.GameObjects.GameObject; + setIgnoreGravity(value: boolean): this; /** * Sets the mass of the Game Object's Matter Body. * @param value The new mass of the body. */ - setMass(value: number): Phaser.GameObjects.GameObject; + setMass(value: number): this; /** * Sets density of the body. * @param value The new density of the body. */ - setDensity(value: number): Phaser.GameObjects.GameObject; + setDensity(value: number): this; /** * The body's center of mass. @@ -75636,7 +87363,7 @@ declare namespace Phaser { * Sensors trigger collision events, but don't react with colliding body physically. * @param value `true` to set the body as a sensor, or `false` to disable it. */ - setSensor(value: boolean): Phaser.GameObjects.GameObject; + setSensor(value: boolean): this; /** * Is the body belonging to this Game Object a sensor or not? @@ -75652,7 +87379,7 @@ declare namespace Phaser { * @param height Height of the rectangle. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setRectangle(width: number, height: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setRectangle(width: number, height: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set the body on a Game Object to a circle. @@ -75662,7 +87389,7 @@ declare namespace Phaser { * @param radius The radius of the circle. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setCircle(radius: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setCircle(radius: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set the body on the Game Object to a polygon shape. @@ -75673,7 +87400,7 @@ declare namespace Phaser { * @param sides The number of sides the polygon will have. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setPolygon(radius: number, sides: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setPolygon(radius: number, sides: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set the body on the Game Object to a trapezoid shape. @@ -75685,7 +87412,7 @@ declare namespace Phaser { * @param slope The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setTrapezoid(width: number, height: number, slope: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setTrapezoid(width: number, height: number, slope: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set this Game Object to use the given existing Matter Body. @@ -75694,7 +87421,7 @@ declare namespace Phaser { * @param body The Body this Game Object should use. * @param addToWorld Should the body be immediately added to the World? Default true. */ - setExistingBody(body: MatterJS.BodyType, addToWorld?: boolean): Phaser.GameObjects.GameObject; + setExistingBody(body: MatterJS.BodyType, addToWorld?: boolean): this; /** * Set this Game Object to create and use a new Body based on the configuration object given. @@ -75704,7 +87431,7 @@ declare namespace Phaser { * @param config Either a string, such as `circle`, or a Matter Set Body Configuration object. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setBody(config: string | Phaser.Types.Physics.Matter.MatterSetBodyConfig, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setBody(config: string | Phaser.Types.Physics.Matter.MatterSetBodyConfig, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Sets this Body to sleep. @@ -75750,7 +87477,7 @@ declare namespace Phaser { * Changes the physics body to be either static `true` or dynamic `false`. * @param value `true` to set the body as being static, or `false` to make it dynamic. */ - setStatic(value: boolean): Phaser.GameObjects.GameObject; + setStatic(value: boolean): this; /** * Returns `true` if the body is static, otherwise `false` for a dynamic body. @@ -75763,31 +87490,54 @@ declare namespace Phaser { */ setFixedRotation(): this; - /** - * Sets the angular velocity of the body instantly. - * Position, angle, force etc. are unchanged. - * @param value The angular velocity. - */ - setAngularVelocity(value: number): Phaser.GameObjects.GameObject; - /** * Sets the horizontal velocity of the physics body. * @param x The horizontal velocity value. */ - setVelocityX(x: number): Phaser.GameObjects.GameObject; + setVelocityX(x: number): this; /** * Sets vertical velocity of the physics body. * @param y The vertical velocity value. */ - setVelocityY(y: number): Phaser.GameObjects.GameObject; + setVelocityY(y: number): this; /** * Sets both the horizontal and vertical velocity of the physics body. * @param x The horizontal velocity value. * @param y The vertical velocity value, it can be either positive or negative. If not given, it will be the same as the `x` value. Default x. */ - setVelocity(x: number, y?: number): Phaser.GameObjects.GameObject; + setVelocity(x: number, y?: number): this; + + /** + * Gets the current linear velocity of the physics body. + */ + getVelocity(): Phaser.Types.Math.Vector2Like; + + /** + * Sets the angular velocity of the body instantly. + * Position, angle, force etc. are unchanged. + * @param velocity The angular velocity. + */ + setAngularVelocity(velocity: number): this; + + /** + * Gets the current rotational velocity of the body. + */ + getAngularVelocity(): number; + + /** + * Sets the current rotational speed of the body. + * Direction is maintained. Affects body angular velocity. + * @param speed The angular speed. + */ + setAngularSpeed(speed: number): this; + + /** + * Gets the current rotational speed of the body. + * Equivalent to the magnitude of its angular velocity. + */ + getAngularSpeed(): number; } @@ -75904,18 +87654,20 @@ declare namespace Phaser { composite: MatterJS.CompositeFactory; /** - * A reference to the `Matter.Detector` module. + * A reference to the `Matter.Collision` module. * - * The `Matter.Detector` module contains methods for detecting collisions given a set of pairs. + * The `Matter.Collision` module contains methods for detecting collisions between a given pair of bodies. + * + * For efficient detection between a list of bodies, see `Matter.Detector` and `Matter.Query`. */ - detector: MatterJS.DetectorFactory; + collision: MatterJS.Collision; /** - * A reference to the `Matter.Grid` module. + * A reference to the `Matter.Detector` module. * - * The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures. + * The `Matter.Detector` module contains methods for detecting collisions given a set of pairs. */ - grid: MatterJS.GridFactory; + detector: MatterJS.DetectorFactory; /** * A reference to the `Matter.Pair` module. @@ -75945,13 +87697,6 @@ declare namespace Phaser { */ resolver: MatterJS.ResolverFactory; - /** - * A reference to the `Matter.SAT` module. - * - * The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem. - */ - sat: MatterJS.SATFactory; - /** * A reference to the `Matter.Constraint` module. * @@ -76228,7 +87973,7 @@ declare namespace Phaser { * @param processCallback An optional callback function that lets you perform additional checks against the two bodies if they overlap. If this is set then `overlapCallback` will only be invoked if this callback returns `true`. * @param callbackContext The context, or scope, in which to run the callbacks. */ - overlap(target: Phaser.Types.Physics.Matter.MatterBody | Phaser.Types.Physics.Matter.MatterBody[], bodies?: Phaser.Types.Physics.Matter.MatterBody[], overlapCallback?: ArcadePhysicsCallback, processCallback?: ArcadePhysicsCallback, callbackContext?: any): boolean; + overlap(target: Phaser.Types.Physics.Matter.MatterBody | Phaser.Types.Physics.Matter.MatterBody[], bodies?: Phaser.Types.Physics.Matter.MatterBody[], overlapCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, processCallback?: Phaser.Types.Physics.Arcade.ArcadePhysicsCallback, callbackContext?: any): boolean; /** * Sets the collision filter category of all given Matter Bodies to the given value. @@ -76259,7 +88004,7 @@ declare namespace Phaser { * Sets the collision filter mask of all given Matter Bodies to the given value. * * Two Matter Bodies with different collision groups will only collide if each one includes the others - * category in its mask based on a bitwise AND operation: `(categoryA & maskB) !== 0` and + * category in its mask based on a bitwise AND operation: `(categoryA & maskB) !== 0` and * `(categoryB & maskA) !== 0` are both true. * @param bodies An array of bodies to update. If falsey it will use all bodies in the world. * @param categories A unique category bitfield, or an array of them. @@ -76385,7 +88130,7 @@ declare namespace Phaser { * As such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation * Component. If you do not require animation then you can safely use Images to replace Sprites in all cases. */ - class Sprite extends Phaser.GameObjects.Sprite implements Phaser.Physics.Matter.Components.Bounce, Phaser.Physics.Matter.Components.Collision, Phaser.Physics.Matter.Components.Force, Phaser.Physics.Matter.Components.Friction, Phaser.Physics.Matter.Components.Gravity, Phaser.Physics.Matter.Components.Mass, Phaser.Physics.Matter.Components.Sensor, Phaser.Physics.Matter.Components.SetBody, Phaser.Physics.Matter.Components.Sleep, Phaser.Physics.Matter.Components.Static, Phaser.Physics.Matter.Components.Transform, Phaser.Physics.Matter.Components.Velocity, Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class Sprite extends Phaser.GameObjects.Sprite implements Phaser.Physics.Matter.Components.Bounce, Phaser.Physics.Matter.Components.Collision, Phaser.Physics.Matter.Components.Force, Phaser.Physics.Matter.Components.Friction, Phaser.Physics.Matter.Components.Gravity, Phaser.Physics.Matter.Components.Mass, Phaser.Physics.Matter.Components.Sensor, Phaser.Physics.Matter.Components.SetBody, Phaser.Physics.Matter.Components.Sleep, Phaser.Physics.Matter.Components.Static, Phaser.Physics.Matter.Components.Transform, Phaser.Physics.Matter.Components.Velocity, Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Size, Phaser.GameObjects.Components.Texture, Phaser.GameObjects.Components.Tint, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param world A reference to the Matter.World instance that this body belongs to. @@ -76460,6 +88205,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -76474,7 +88220,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -76483,6 +88229,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -76496,12 +88243,12 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -76523,7 +88270,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -76593,77 +88340,97 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ @@ -76699,7 +88466,7 @@ declare namespace Phaser { /** * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, - * including this one. + * including this one, or a Dynamic Texture. * * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. * @@ -76709,10 +88476,14 @@ declare namespace Phaser { * * If you do not provide a renderable object, and this Game Object has a texture, * it will use itself as the object. This means you can call this method to create - * a Bitmap Mask from any renderable Game Object. - * @param renderable A renderable Game Object that uses a texture, such as a Sprite. + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - createBitmapMask(renderable?: Phaser.GameObjects.GameObject): Phaser.Display.Masks.BitmapMask; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; /** * Creates and returns a Geometry Mask. This mask can be used by any Game Object, @@ -76724,25 +88495,27 @@ declare namespace Phaser { * of a Graphics object, then it will use itself to create the mask. * * This means you can call this method to create a Geometry Mask from any Graphics Game Object. - * @param graphics A Graphics Game Object. The geometry within it will be used as the mask. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. */ - createGeometryMask(graphics?: Phaser.GameObjects.Graphics): Phaser.Display.Masks.GeometryMask; + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * The horizontal origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the left of the Game Object. + * Set this value with `setOrigin()`. */ - originX: number; + readonly originX: number; /** * The vertical origin of this Game Object. * The origin maps the relationship between the size and position of the Game Object. * The default value is 0.5, meaning all Game Objects are positioned based on their center. * Setting the value to 0 means the position now relates to the top of the Game Object. + * Set this value with `setOrigin()`. */ - originY: number; + readonly originY: number; /** * The horizontal display origin of this Game Object. @@ -76798,6 +88571,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -76816,27 +88634,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -76852,27 +88708,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -76880,17 +88732,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -76903,9 +88748,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -77014,7 +88863,7 @@ declare namespace Phaser { * size of the hit area. To do this you should adjust the `input.hitArea` object directly. * @param frame The frame to base the size of this Game Object on. */ - setSizeToFrame(frame: Phaser.Textures.Frame): this; + setSizeToFrame(frame?: Phaser.Textures.Frame | boolean): this; /** * Sets the internal size of this Game Object, as used for frame or physics body creation. @@ -77098,17 +88947,19 @@ declare namespace Phaser { /** * Sets the frame this Game Object will use to render with. * - * The Frame has to belong to the current Texture being used. + * If you pass a string or index then the Frame has to belong to the current Texture being used + * by this Game Object. * - * It can be either a string or an index. + * If you pass a Frame instance, then the Texture being used by this Game Object will also be updated. * * Calling `setFrame` will modify the `width` and `height` properties of your Game Object. + * * It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer. - * @param frame The name or index of the frame within the Texture. + * @param frame The name or index of the frame within the Texture, or a Frame instance. * @param updateSize Should this call adjust the size of the Game Object? Default true. * @param updateOrigin Should this call adjust the origin of the Game Object? Default true. */ - setFrame(frame: string | number, updateSize?: boolean, updateOrigin?: boolean): this; + setFrame(frame: string | number | Phaser.Textures.Frame, updateSize?: boolean, updateOrigin?: boolean): this; /** * The tint value being applied to the top-left vertice of the Game Object. @@ -77213,6 +89064,11 @@ declare namespace Phaser { */ readonly isTinted: boolean; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -77319,10 +89175,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -77406,7 +89262,7 @@ declare namespace Phaser { * Sets the restitution on the physics object. * @param value A Number that defines the restitution (elasticity) of the body. The value is always positive and is in the range (0, 1). A value of 0 means collisions may be perfectly inelastic and no bouncing may occur. A value of 0.8 means the body may bounce back with approximately 80% of its kinetic energy. Note that collision response is based on pairs of bodies, and that restitution values are combined with the following formula: `Math.max(bodyA.restitution, bodyB.restitution)` */ - setBounce(value: number): Phaser.GameObjects.GameObject; + setBounce(value: number): this; /** * Sets the collision category of this Game Object's Matter Body. This number must be a power of two between 2^0 (= 1) and 2^31. @@ -77414,7 +89270,7 @@ declare namespace Phaser { * categories are included in their collision masks (see {@link #setCollidesWith}). * @param value Unique category bitfield. */ - setCollisionCategory(value: number): Phaser.GameObjects.GameObject; + setCollisionCategory(value: number): this; /** * Sets the collision group of this Game Object's Matter Body. If this is zero or two Matter Bodies have different values, @@ -77423,7 +89279,7 @@ declare namespace Phaser { * they will never collide. * @param value Unique group index. */ - setCollisionGroup(value: number): Phaser.GameObjects.GameObject; + setCollisionGroup(value: number): this; /** * Sets the collision mask for this Game Object's Matter Body. Two Matter Bodies with different collision groups will only @@ -77431,7 +89287,7 @@ declare namespace Phaser { * and `(categoryB & maskA) !== 0` are both true. * @param categories A unique category bitfield, or an array of them. */ - setCollidesWith(categories: number | number[]): Phaser.GameObjects.GameObject; + setCollidesWith(categories: number | number[]): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -77440,7 +89296,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke when this body starts colliding with another. */ - setOnCollide(callback: Function): Phaser.GameObjects.GameObject; + setOnCollide(callback: Function): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -77449,7 +89305,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke when this body stops colliding with another. */ - setOnCollideEnd(callback: Function): Phaser.GameObjects.GameObject; + setOnCollideEnd(callback: Function): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -77458,7 +89314,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke for the duration of this body colliding with another. */ - setOnCollideActive(callback: Function): Phaser.GameObjects.GameObject; + setOnCollideActive(callback: Function): this; /** * The callback is sent a reference to the other body, along with a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -77468,20 +89324,20 @@ declare namespace Phaser { * @param body The body, or an array of bodies, to test for collisions with. * @param callback The callback to invoke when this body collides with the given body or bodies. */ - setOnCollideWith(body: MatterJS.Body | MatterJS.Body[], callback: Function): Phaser.GameObjects.GameObject; + setOnCollideWith(body: MatterJS.Body | MatterJS.Body[], callback: Function): this; /** * Applies a force to a body. * @param force A Vector that specifies the force to apply. */ - applyForce(force: Phaser.Math.Vector2): Phaser.GameObjects.GameObject; + applyForce(force: Phaser.Math.Vector2): this; /** * Applies a force to a body from a given position. * @param position The position in which the force comes from. * @param force A Vector that specifies the force to apply. */ - applyForceFrom(position: Phaser.Math.Vector2, force: Phaser.Math.Vector2): Phaser.GameObjects.GameObject; + applyForceFrom(position: Phaser.Math.Vector2, force: Phaser.Math.Vector2): this; /** * Apply thrust to the forward position of the body. @@ -77489,7 +89345,7 @@ declare namespace Phaser { * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrust(speed: number): Phaser.GameObjects.GameObject; + thrust(speed: number): this; /** * Apply thrust to the left position of the body. @@ -77497,7 +89353,7 @@ declare namespace Phaser { * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrustLeft(speed: number): Phaser.GameObjects.GameObject; + thrustLeft(speed: number): this; /** * Apply thrust to the right position of the body. @@ -77505,7 +89361,7 @@ declare namespace Phaser { * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrustRight(speed: number): Phaser.GameObjects.GameObject; + thrustRight(speed: number): this; /** * Apply thrust to the back position of the body. @@ -77513,7 +89369,7 @@ declare namespace Phaser { * Use very small values, such as 0.1, depending on the mass and required speed. * @param speed A speed value to be applied to a directional force. */ - thrustBack(speed: number): Phaser.GameObjects.GameObject; + thrustBack(speed: number): this; /** * Sets new friction values for this Game Object's Matter Body. @@ -77521,7 +89377,7 @@ declare namespace Phaser { * @param air If provided, the new air resistance of the Body. The higher the value, the faster the Body will slow as it moves through space. 0 means the body has no air resistance. * @param fstatic If provided, the new static friction of the Body. The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. 0 means the body will never "stick" when it is nearly stationary. */ - setFriction(value: number, air?: number, fstatic?: number): Phaser.GameObjects.GameObject; + setFriction(value: number, air?: number, fstatic?: number): this; /** * Sets a new air resistance for this Game Object's Matter Body. @@ -77529,7 +89385,7 @@ declare namespace Phaser { * The higher the value, the faster a Body slows when moving through space. * @param value The new air resistance for the Body. */ - setFrictionAir(value: number): Phaser.GameObjects.GameObject; + setFrictionAir(value: number): this; /** * Sets a new static friction for this Game Object's Matter Body. @@ -77537,25 +89393,25 @@ declare namespace Phaser { * The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. * @param value The new static friction for the Body. */ - setFrictionStatic(value: number): Phaser.GameObjects.GameObject; + setFrictionStatic(value: number): this; /** * A togglable function for ignoring world gravity in real-time on the current body. * @param value Set to true to ignore the effect of world gravity, or false to not ignore it. */ - setIgnoreGravity(value: boolean): Phaser.GameObjects.GameObject; + setIgnoreGravity(value: boolean): this; /** * Sets the mass of the Game Object's Matter Body. * @param value The new mass of the body. */ - setMass(value: number): Phaser.GameObjects.GameObject; + setMass(value: number): this; /** * Sets density of the body. * @param value The new density of the body. */ - setDensity(value: number): Phaser.GameObjects.GameObject; + setDensity(value: number): this; /** * The body's center of mass. @@ -77571,7 +89427,7 @@ declare namespace Phaser { * Sensors trigger collision events, but don't react with colliding body physically. * @param value `true` to set the body as a sensor, or `false` to disable it. */ - setSensor(value: boolean): Phaser.GameObjects.GameObject; + setSensor(value: boolean): this; /** * Is the body belonging to this Game Object a sensor or not? @@ -77587,7 +89443,7 @@ declare namespace Phaser { * @param height Height of the rectangle. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setRectangle(width: number, height: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setRectangle(width: number, height: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set the body on a Game Object to a circle. @@ -77597,7 +89453,7 @@ declare namespace Phaser { * @param radius The radius of the circle. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setCircle(radius: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setCircle(radius: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set the body on the Game Object to a polygon shape. @@ -77608,7 +89464,7 @@ declare namespace Phaser { * @param sides The number of sides the polygon will have. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setPolygon(radius: number, sides: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setPolygon(radius: number, sides: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set the body on the Game Object to a trapezoid shape. @@ -77620,7 +89476,7 @@ declare namespace Phaser { * @param slope The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setTrapezoid(width: number, height: number, slope: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setTrapezoid(width: number, height: number, slope: number, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Set this Game Object to use the given existing Matter Body. @@ -77629,7 +89485,7 @@ declare namespace Phaser { * @param body The Body this Game Object should use. * @param addToWorld Should the body be immediately added to the World? Default true. */ - setExistingBody(body: MatterJS.BodyType, addToWorld?: boolean): Phaser.GameObjects.GameObject; + setExistingBody(body: MatterJS.BodyType, addToWorld?: boolean): this; /** * Set this Game Object to create and use a new Body based on the configuration object given. @@ -77639,7 +89495,7 @@ declare namespace Phaser { * @param config Either a string, such as `circle`, or a Matter Set Body Configuration object. * @param options An optional Body configuration object that is used to set initial Body properties on creation. */ - setBody(config: string | Phaser.Types.Physics.Matter.MatterSetBodyConfig, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): Phaser.GameObjects.GameObject; + setBody(config: string | Phaser.Types.Physics.Matter.MatterSetBodyConfig, options?: Phaser.Types.Physics.Matter.MatterBodyConfig): this; /** * Sets this Body to sleep. @@ -77685,7 +89541,7 @@ declare namespace Phaser { * Changes the physics body to be either static `true` or dynamic `false`. * @param value `true` to set the body as being static, or `false` to make it dynamic. */ - setStatic(value: boolean): Phaser.GameObjects.GameObject; + setStatic(value: boolean): this; /** * Returns `true` if the body is static, otherwise `false` for a dynamic body. @@ -77698,31 +89554,54 @@ declare namespace Phaser { */ setFixedRotation(): this; - /** - * Sets the angular velocity of the body instantly. - * Position, angle, force etc. are unchanged. - * @param value The angular velocity. - */ - setAngularVelocity(value: number): Phaser.GameObjects.GameObject; - /** * Sets the horizontal velocity of the physics body. * @param x The horizontal velocity value. */ - setVelocityX(x: number): Phaser.GameObjects.GameObject; + setVelocityX(x: number): this; /** * Sets vertical velocity of the physics body. * @param y The vertical velocity value. */ - setVelocityY(y: number): Phaser.GameObjects.GameObject; + setVelocityY(y: number): this; /** * Sets both the horizontal and vertical velocity of the physics body. * @param x The horizontal velocity value. * @param y The vertical velocity value, it can be either positive or negative. If not given, it will be the same as the `x` value. Default x. */ - setVelocity(x: number, y?: number): Phaser.GameObjects.GameObject; + setVelocity(x: number, y?: number): this; + + /** + * Gets the current linear velocity of the physics body. + */ + getVelocity(): Phaser.Types.Math.Vector2Like; + + /** + * Sets the angular velocity of the body instantly. + * Position, angle, force etc. are unchanged. + * @param velocity The angular velocity. + */ + setAngularVelocity(velocity: number): this; + + /** + * Gets the current rotational velocity of the body. + */ + getAngularVelocity(): number; + + /** + * Sets the current rotational speed of the body. + * Direction is maintained. Affects body angular velocity. + * @param speed The angular speed. + */ + setAngularSpeed(speed: number): this; + + /** + * Gets the current rotational speed of the body. + * Equivalent to the magnitude of its angular velocity. + */ + getAngularSpeed(): number; } @@ -77799,7 +89678,7 @@ declare namespace Phaser { * Sets the restitution on the physics object. * @param value A Number that defines the restitution (elasticity) of the body. The value is always positive and is in the range (0, 1). A value of 0 means collisions may be perfectly inelastic and no bouncing may occur. A value of 0.8 means the body may bounce back with approximately 80% of its kinetic energy. Note that collision response is based on pairs of bodies, and that restitution values are combined with the following formula: `Math.max(bodyA.restitution, bodyB.restitution)` */ - setBounce(value: number): Phaser.GameObjects.GameObject; + setBounce(value: number): this; /** * Sets the collision category of this Game Object's Matter Body. This number must be a power of two between 2^0 (= 1) and 2^31. @@ -77807,7 +89686,7 @@ declare namespace Phaser { * categories are included in their collision masks (see {@link #setCollidesWith}). * @param value Unique category bitfield. */ - setCollisionCategory(value: number): Phaser.GameObjects.GameObject; + setCollisionCategory(value: number): this; /** * Sets the collision group of this Game Object's Matter Body. If this is zero or two Matter Bodies have different values, @@ -77816,7 +89695,7 @@ declare namespace Phaser { * they will never collide. * @param value Unique group index. */ - setCollisionGroup(value: number): Phaser.GameObjects.GameObject; + setCollisionGroup(value: number): this; /** * Sets the collision mask for this Game Object's Matter Body. Two Matter Bodies with different collision groups will only @@ -77824,7 +89703,7 @@ declare namespace Phaser { * and `(categoryB & maskA) !== 0` are both true. * @param categories A unique category bitfield, or an array of them. */ - setCollidesWith(categories: number | number[]): Phaser.GameObjects.GameObject; + setCollidesWith(categories: number | number[]): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -77833,7 +89712,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke when this body starts colliding with another. */ - setOnCollide(callback: Function): Phaser.GameObjects.GameObject; + setOnCollide(callback: Function): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -77842,7 +89721,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke when this body stops colliding with another. */ - setOnCollideEnd(callback: Function): Phaser.GameObjects.GameObject; + setOnCollideEnd(callback: Function): this; /** * The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -77851,7 +89730,7 @@ declare namespace Phaser { * to the callback. * @param callback The callback to invoke for the duration of this body colliding with another. */ - setOnCollideActive(callback: Function): Phaser.GameObjects.GameObject; + setOnCollideActive(callback: Function): this; /** * The callback is sent a reference to the other body, along with a `Phaser.Types.Physics.Matter.MatterCollisionData` object. @@ -77861,7 +89740,7 @@ declare namespace Phaser { * @param body The body, or an array of bodies, to test for collisions with. * @param callback The callback to invoke when this body collides with the given body or bodies. */ - setOnCollideWith(body: MatterJS.Body | MatterJS.Body[], callback: Function): Phaser.GameObjects.GameObject; + setOnCollideWith(body: MatterJS.Body | MatterJS.Body[], callback: Function): this; /** * Sets new friction values for this Game Object's Matter Body. @@ -77869,7 +89748,7 @@ declare namespace Phaser { * @param air If provided, the new air resistance of the Body. The higher the value, the faster the Body will slow as it moves through space. 0 means the body has no air resistance. * @param fstatic If provided, the new static friction of the Body. The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. 0 means the body will never "stick" when it is nearly stationary. */ - setFriction(value: number, air?: number, fstatic?: number): Phaser.GameObjects.GameObject; + setFriction(value: number, air?: number, fstatic?: number): this; /** * Sets a new air resistance for this Game Object's Matter Body. @@ -77877,7 +89756,7 @@ declare namespace Phaser { * The higher the value, the faster a Body slows when moving through space. * @param value The new air resistance for the Body. */ - setFrictionAir(value: number): Phaser.GameObjects.GameObject; + setFrictionAir(value: number): this; /** * Sets a new static friction for this Game Object's Matter Body. @@ -77885,25 +89764,25 @@ declare namespace Phaser { * The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. * @param value The new static friction for the Body. */ - setFrictionStatic(value: number): Phaser.GameObjects.GameObject; + setFrictionStatic(value: number): this; /** * A togglable function for ignoring world gravity in real-time on the current body. * @param value Set to true to ignore the effect of world gravity, or false to not ignore it. */ - setIgnoreGravity(value: boolean): Phaser.GameObjects.GameObject; + setIgnoreGravity(value: boolean): this; /** * Sets the mass of the Game Object's Matter Body. * @param value The new mass of the body. */ - setMass(value: number): Phaser.GameObjects.GameObject; + setMass(value: number): this; /** * Sets density of the body. * @param value The new density of the body. */ - setDensity(value: number): Phaser.GameObjects.GameObject; + setDensity(value: number): this; /** * The body's center of mass. @@ -77919,7 +89798,7 @@ declare namespace Phaser { * Sensors trigger collision events, but don't react with colliding body physically. * @param value `true` to set the body as a sensor, or `false` to disable it. */ - setSensor(value: boolean): Phaser.GameObjects.GameObject; + setSensor(value: boolean): this; /** * Is the body belonging to this Game Object a sensor or not? @@ -77970,7 +89849,7 @@ declare namespace Phaser { * Changes the physics body to be either static `true` or dynamic `false`. * @param value `true` to set the body as being static, or `false` to make it dynamic. */ - setStatic(value: boolean): Phaser.GameObjects.GameObject; + setStatic(value: boolean): this; /** * Returns `true` if the body is static, otherwise `false` for a dynamic body. @@ -78116,12 +89995,12 @@ declare namespace Phaser { /** * The body that is currently being dragged, if any. */ - body: MatterJS.BodyType; + body: MatterJS.BodyType | null; /** * The part of the body that was clicked on to start the drag. */ - part: MatterJS.BodyType; + part: MatterJS.BodyType | null; /** * The native Matter Constraint that is used to attach to bodies. @@ -78220,22 +90099,13 @@ declare namespace Phaser { /** * An object containing the 4 wall bodies that bound the physics world. */ - walls: object; + walls: Phaser.Types.Physics.Matter.MatterWalls; /** * A flag that toggles if the world is enabled or not. */ enabled: boolean; - /** - * The correction argument is an optional Number that specifies the time correction factor to apply to the update. - * This can help improve the accuracy of the simulation in cases where delta is changing between updates. - * The value of correction is defined as delta / lastDelta, i.e. the percentage change of delta over the last step. - * Therefore the value is always 1 (no correction) when delta is constant (or when no correction is desired, which is the default). - * See the paper on Time Corrected Verlet for more information. - */ - correction: number; - /** * This function is called every time the core game loop steps, which is bound to the * Request Animation Frame frequency unless otherwise modified. @@ -78358,6 +90228,7 @@ declare namespace Phaser { /** * Sets the bounds of the Physics world to match the given world pixel dimensions. + * * You can optionally set which 'walls' to create: left, right, top or bottom. * If none of the walls are given it will default to use the walls settings it had previously. * I.e. if you previously told it to not have the left or right walls, and you then adjust the world size @@ -78535,9 +90406,8 @@ declare namespace Phaser { * Adjusting these values can help performance in certain situations, depending on the physics requirements * of your game. * @param delta The delta value. Default 16.666. - * @param correction Optional delta correction value. Default 1. */ - step(delta?: number, correction?: number): void; + step(delta?: number): void; /** * Runs the Matter Engine.update at a fixed timestep of 60Hz. @@ -78764,7 +90634,7 @@ declare namespace Phaser { * On a Scene Plugin, this method is never called. Use {@link Phaser.Plugins.ScenePlugin#boot} instead. * @param 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(data?: any): void; + init(data?: any | undefined): void; /** * The PluginManager calls this method on a Global Plugin when the plugin is started. @@ -78846,7 +90716,7 @@ declare namespace Phaser { * @param mapping If this plugin is to be injected into the Scene Systems, this is the property key map used. * @param data A value to be passed to the plugin's `init` method. */ - function registerCustom(key: string, plugin: Function, mapping: string, data: any): void; + function registerCustom(key: string, plugin: Function, mapping: string, data: any | undefined): void; /** * Checks if the given key is already being used in the core plugin cache. @@ -79035,7 +90905,7 @@ declare namespace Phaser { * @param mapping If this plugin is injected into the Phaser.Scene class, this is the property key to use. * @param data A value passed to the plugin's `init` method. */ - install(key: string, plugin: Function, start?: boolean, mapping?: string, data?: any): Phaser.Plugins.BasePlugin; + install(key: string, plugin: Function, start?: boolean, mapping?: string, data?: any): Phaser.Plugins.BasePlugin | null; /** * Gets an index of a global plugin based on the given key. @@ -79068,7 +90938,7 @@ declare namespace Phaser { * @param key The key of the plugin to start. * @param runAs Run the plugin under a new key. This allows you to run one plugin multiple times. */ - start(key: string, runAs?: string): Phaser.Plugins.BasePlugin; + start(key: string, runAs?: string): Phaser.Plugins.BasePlugin | null; /** * Stops a global plugin from running. @@ -79089,7 +90959,7 @@ declare namespace Phaser { * @param key The key of the plugin to get. * @param autoStart Automatically start a new instance of the plugin if found in the cache, but not actively running. Default true. */ - get(key: string, autoStart?: boolean): Phaser.Plugins.BasePlugin | Function; + get(key: string, autoStart?: boolean): Phaser.Plugins.BasePlugin | Function | null; /** * Returns the plugin class from the cache. @@ -79219,7 +91089,7 @@ declare namespace Phaser { * This property is only set when the plugin is instantiated and added to the Scene, not before. * You can use it during the `boot` method. */ - protected scene: Phaser.Scene; + protected scene: Phaser.Scene | null; /** * A reference to the Scene Systems of the Scene that has installed this plugin. @@ -79227,7 +91097,7 @@ declare namespace Phaser { * This property is only set when the plugin is instantiated and added to the Scene, not before. * You can use it during the `boot` method. */ - protected systems: Phaser.Scenes.Systems; + protected systems: Phaser.Scenes.Systems | null; /** * The key under which this plugin was installed into the Scene Systems. @@ -79549,7 +91419,7 @@ declare namespace Phaser { * Changes the Canvas Rendering Context that all draw operations are performed against. * @param ctx The new Canvas Rendering Context to draw everything to. Leave empty to reset to the Game Canvas. */ - setContext(ctx?: CanvasRenderingContext2D): this; + setContext(ctx?: CanvasRenderingContext2D | undefined): this; /** * Sets the global alpha of the current context. @@ -79689,7 +91559,8 @@ declare namespace Phaser { * 4. Sets the alpha value of the context to be that used by the Game Object combined with the Camera. * 5. Saves the context state. * 6. Sets the final matrix values into the context via setTransform. - * 7. If Renderer.antialias, or the frame.source.scaleMode is set, then imageSmoothingEnabled is set. + * 7. If the Game Object has a texture frame, imageSmoothingEnabled is set based on frame.source.scaleMode. + * 8. If the Game Object does not have a texture frame, imageSmoothingEnabled is set based on Renderer.antialias. * * This function is only meant to be used internally. Most of the Canvas Renderer classes use it. * @param renderer A reference to the current active Canvas renderer. @@ -79709,7 +91580,7 @@ declare namespace Phaser { * This event is dispatched by the Renderer when all rendering, for all cameras in all Scenes, * has completed, but before any pending snap shots have been taken. */ - const POST_RENDER: any; + const POST_RENDER: string; /** * The Pre-Render Event. @@ -79718,7 +91589,7 @@ declare namespace Phaser { * process, after the context has been cleared, the scissors enabled (WebGL only) and everything has been * reset ready for the render. */ - const PRE_RENDER: any; + const PRE_RENDER: string; /** * The Render Event. @@ -79727,7 +91598,7 @@ declare namespace Phaser { * * It is dispatched before any of the children in the Scene have been rendered. */ - const RENDER: any; + const RENDER: string; /** * The Renderer Resize Event. @@ -79735,7 +91606,7 @@ declare namespace Phaser { * This event is dispatched by the Phaser Renderer when it is resized, usually as a result * of the Scale Manager resizing. */ - const RESIZE: any; + const RESIZE: string; } @@ -79755,10 +91626,10 @@ declare namespace Phaser { * * This is then copied to an Image object. When this loads, the results are sent * to the callback provided in the Snapshot Configuration object. - * @param sourceCanvas The canvas to take a snapshot of. + * @param sourceContext The WebGL context to take a snapshot of. * @param config The snapshot configuration object. */ - function WebGL(sourceCanvas: HTMLCanvasElement, config: Phaser.Types.Renderer.Snapshot.SnapshotState): void; + function WebGL(sourceContext: WebGLRenderingContext, config: Phaser.Types.Renderer.Snapshot.SnapshotState): void; } @@ -79805,16 +91676,17 @@ declare namespace Phaser { * The `WebGLRenderer` owns a single instance of the Pipeline Manager, which you can access * via the `WebGLRenderer.pipelines` property. * - * By default, there are 8 pipelines installed into the Pipeline Manager when Phaser boots: + * By default, there are 9 pipelines installed into the Pipeline Manager when Phaser boots: * * 1. The Multi Pipeline. Responsible for all multi-texture rendering, i.e. Sprites and Tilemaps. - * 2. The Graphics Pipeline. Responsible for rendering Graphics and Shape objects. - * 3. The Rope Pipeline. Responsible for rendering the Rope Game Object. - * 4. The Light Pipeline. Responsible for rendering the Light Game Object. - * 5. The Point Light Pipeline. Responsible for rendering the Point Light Game Object. - * 6. The Single Pipeline. Responsible for rendering Game Objects that explicitly require one bound texture. - * 7. The Bitmap Mask Pipeline. Responsible for Bitmap Mask rendering. - * 8. The Utility Pipeline. Responsible for providing lots of handy texture manipulation functions. + * 2. The Rope Pipeline. Responsible for rendering the Rope Game Object. + * 3. The Light Pipeline. Responsible for rendering the Light Game Object. + * 4. The Point Light Pipeline. Responsible for rendering the Point Light Game Object. + * 5. The Single Pipeline. Responsible for rendering Game Objects that explicitly require one bound texture. + * 6. The Bitmap Mask Pipeline. Responsible for Bitmap Mask rendering. + * 7. The Utility Pipeline. Responsible for providing lots of handy texture manipulation functions. + * 8. The Mobile Pipeline. Responsible for rendering on mobile with single-bound textures. + * 9. The FX Pipeline. Responsible for rendering Game Objects with special FX applied to them. * * You can add your own custom pipeline via the `PipelineManager.add` method. Pipelines are * identified by unique string-based keys. @@ -79845,6 +91717,26 @@ declare namespace Phaser { /** * This map stores all Post FX Pipeline classes available in this manager. + * + * As of v3.60 this is now populated by default with the following + * Post FX Pipelines: + * + * * Barrel + * * Bloom + * * Blur + * * Bokeh / TiltShift + * * Circle + * * ColorMatrix + * * Displacement + * * Glow + * * Gradient + * * Pixelate + * * Shadow + * * Shine + * * Vignette + * * Wipe + * + * See the FX Controller class for more details. */ postPipelineClasses: Phaser.Structs.Map; @@ -79855,6 +91747,11 @@ declare namespace Phaser { */ pipelines: Phaser.Structs.Map; + /** + * The default Game Object pipeline. + */ + default: Phaser.Renderer.WebGL.WebGLPipeline; + /** * Current pipeline in use by the WebGLRenderer. */ @@ -79888,6 +91785,22 @@ declare namespace Phaser { */ UTILITY_PIPELINE: Phaser.Renderer.WebGL.Pipelines.UtilityPipeline; + /** + * A constant-style reference to the Mobile Pipeline Instance. + * + * This is the default Phaser 3 mobile pipeline and is used by the WebGL Renderer to manage + * camera effects and more on mobile devices. This property is set during the `boot` method. + */ + MOBILE_PIPELINE: Phaser.Renderer.WebGL.Pipelines.MobilePipeline; + + /** + * A constant-style reference to the FX Pipeline Instance. + * + * This is the default Phaser 3 FX pipeline and is used by the WebGL Renderer to manage + * Game Objects with special effects enabled. This property is set during the `boot` method. + */ + FX_PIPELINE: Phaser.Renderer.WebGL.Pipelines.FXPipeline; + /** * A reference to the Full Frame 1 Render Target that belongs to the * Utility Pipeline. This property is set during the `boot` method. @@ -79932,6 +91845,29 @@ declare namespace Phaser { */ halfFrame2: Phaser.Renderer.WebGL.RenderTarget; + /** + * An array of RenderTarget instances that belong to this pipeline. + */ + renderTargets: Phaser.Renderer.WebGL.RenderTarget[]; + + /** + * The largest render target dimension before we just use a full-screen target. + */ + maxDimension: number; + + /** + * The amount in which each target frame will increase. + * + * Defaults to 32px but can be overridden in the config. + */ + frameInc: number; + + /** + * The Render Target index. Used internally by the methods + * in this class. Do not modify directly. + */ + targetIndex: number; + /** * Internal boot handler, called by the WebGLRenderer durings its boot process. * @@ -79940,8 +91876,25 @@ declare namespace Phaser { * * Finally, the default pipeline is set. * @param pipelineConfig The pipeline configuration object as set in the Game Config. + * @param defaultPipeline The name of the default Game Object pipeline, as set in the Game Config + * @param autoMobilePipeline Automatically set the default pipeline to mobile if non-desktop detected? + */ + boot(pipelineConfig: Phaser.Types.Core.PipelineConfig, defaultPipeline: string, autoMobilePipeline: boolean): void; + + /** + * Sets the default pipeline being used by Game Objects. + * + * If no instance, or matching name, exists in this manager, it returns `undefined`. + * + * You can use this to override the default pipeline, for example by forcing + * the Mobile or Multi Tint Pipelines, which is especially useful for development + * testing. + * + * Make sure you call this method _before_ creating any Game Objects, as it will + * only impact Game Objects created after you call it. + * @param pipeline Either the string-based name of the pipeline to get, or a pipeline instance to look-up. */ - boot(pipelineConfig?: Phaser.Types.Core.PipelineConfig): void; + setDefaultPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): Phaser.Renderer.WebGL.WebGLPipeline; /** * Adds a pipeline instance to this Pipeline Manager. @@ -79953,7 +91906,7 @@ declare namespace Phaser { * For example, you should pass it like this: * * ```javascript - * this.add('yourName', new CustomPipeline());` + * this.add('yourName', new CustomPipeline(game));` * ``` * * and **not** like this: @@ -80016,8 +91969,9 @@ declare namespace Phaser { * If no instance, or matching name, exists in this manager, it returns `undefined`. * @param pipeline Either the string-based name of the pipeline to get, or a pipeline instance, or class to look-up. * @param gameObject If this post pipeline is being installed into a Game Object or Camera, this is a reference to it. + * @param config Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. */ - getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline, gameObject?: Phaser.GameObjects.GameObject): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline; + getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline, gameObject?: Phaser.GameObjects.GameObject, config?: object): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline; /** * Removes a pipeline instance based on the given name. @@ -80049,18 +92003,30 @@ declare namespace Phaser { /** * This method is called by the `WebGLPipeline.batchQuad` method, right before a quad - * belonging to a Game Object is about to be added to the batch. It causes a batch - * flush, then calls the `preBatch` method on the post-fx pipelines belonging to the - * Game Object. + * belonging to a Game Object is about to be added to the batch. + * + * It is also called directly bu custom Game Objects, such as Nine Slice or Mesh, + * from their render methods. + * + * It causes a batch flush, then calls the `preBatch` method on the Post FX Pipelines + * belonging to the Game Object. + * + * It should be followed by a call to `postBatch` to complete the process. * @param gameObject The Game Object about to be batched. */ preBatch(gameObject: Phaser.GameObjects.GameObject): void; /** * This method is called by the `WebGLPipeline.batchQuad` method, right after a quad - * belonging to a Game Object has been added to the batch. It causes a batch - * flush, then calls the `postBatch` method on the post-fx pipelines belonging to the - * Game Object. + * belonging to a Game Object has been added to the batch. + * + * It is also called directly bu custom Game Objects, such as Nine Slice or Mesh, + * from their render methods. + * + * It causes a batch flush, then calls the `postBatch` method on the Post FX Pipelines + * belonging to the Game Object. + * + * It should be preceeded by a call to `preBatch` to start the process. * @param gameObject The Game Object that was just added to the batch. */ postBatch(gameObject: Phaser.GameObjects.GameObject): void; @@ -80226,6 +92192,11 @@ declare namespace Phaser { */ setUtility(currentShader?: Phaser.Renderer.WebGL.WebGLShader): Phaser.Renderer.WebGL.Pipelines.UtilityPipeline; + /** + * Sets the FX Pipeline to be the currently bound pipeline. + */ + setFX(): Phaser.Renderer.WebGL.Pipelines.FXPipeline; + /** * Use this to reset the gl context to the state that Phaser requires to continue rendering. * @@ -80255,6 +92226,27 @@ declare namespace Phaser { */ clear(): void; + /** + * Gets a Render Target the right size to render the Sprite on. + * + * If the Sprite exceeds the size of the renderer, the Render Target will only ever be the maximum + * size of the renderer. + * @param size The maximum dimension required. + */ + getRenderTarget(size: number): Phaser.Renderer.WebGL.RenderTarget; + + /** + * Gets a matching Render Target, the same size as the one the Sprite was drawn to, + * useful for double-buffer style effects such as blurs. + */ + getSwapRenderTarget(): Phaser.Renderer.WebGL.RenderTarget; + + /** + * Gets a matching Render Target, the same size as the one the Sprite was drawn to, + * useful for double-buffer style effects such as blurs. + */ + getAltSwapRenderTarget(): Phaser.Renderer.WebGL.RenderTarget; + /** * Destroy the Pipeline Manager, cleaning up all related resources and references. */ @@ -80292,20 +92284,22 @@ declare namespace Phaser { /** * Binds necessary resources and renders the mask to a separated framebuffer. * The framebuffer for the masked object is also bound for further use. - * @param mask GameObject used as mask. + * @param mask The BitmapMask instance that called beginMask. * @param maskedObject GameObject masked by the mask GameObject. * @param camera The camera rendering the current mask. */ - beginMask(mask: Phaser.GameObjects.GameObject, maskedObject: Phaser.GameObjects.GameObject, camera: Phaser.Cameras.Scene2D.Camera): void; + beginMask(mask: Phaser.Display.Masks.BitmapMask, maskedObject: Phaser.GameObjects.GameObject, camera: Phaser.Cameras.Scene2D.Camera): void; /** * The masked game objects framebuffer is unbound and its texture * is bound together with the mask texture and the mask shader and * a draw call with a single quad is processed. Here is where the * masking effect is applied. - * @param mask GameObject used as a mask. + * @param mask The BitmapMask instance that called endMask. + * @param camera The Camera to render to. + * @param renderTarget Optional WebGL RenderTarget. */ - endMask(mask: Phaser.GameObjects.GameObject): void; + endMask(mask: Phaser.Display.Masks.BitmapMask, camera: Phaser.Cameras.Scene2D.Camera, renderTarget?: Phaser.Renderer.WebGL.RenderTarget): void; } @@ -80354,6 +92348,16 @@ declare namespace Phaser { */ const UTILITY_PIPELINE: string; + /** + * The Mobile Texture Pipeline. + */ + const MOBILE_PIPELINE: string; + + /** + * The Special FX Pipeline. + */ + const FX_PIPELINE: string; + namespace Events { /** * The WebGLPipeline After Flush Event. @@ -80409,140 +92413,934 @@ declare namespace Phaser { } - /** - * The Graphics Pipeline is the rendering pipeline used by Phaser in WebGL when drawing - * primitive geometry objects, such as the Graphics Game Object, or the Shape Game Objects - * such as Arc, Line, Rectangle and Star. It handles the preperation and batching of related vertices. - * - * Prior to Phaser v3.50 the functions of this pipeline were merged with the `TextureTintPipeline`. - * - * The fragment shader it uses can be found in `shaders/src/Graphics.frag`. - * The vertex shader it uses can be found in `shaders/src/Graphics.vert`. - * - * The default shader attributes for this pipeline are: - * - * `inPosition` (vec2) - * `inColor` (vec4, normalized) - * - * The default shader uniforms for this pipeline are: - * - * `uProjectionMatrix` (mat4) - */ - class GraphicsPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + namespace FX { /** + * The Barrel FX Pipeline. * - * @param config The configuration options for this pipeline. + * A barrel effect allows you to apply either a 'pinch' or 'expand' distortion to + * a Game Object. The amount of the effect can be modified in real-time. + * + * A Barrel effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addBarrel(); + * ``` */ - constructor(config: Phaser.Types.Renderer.WebGL.WebGLPipelineConfig); + class BarrelFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The amount of distortion applied to the barrel effect. + * + * Typically keep this within the range 1 (no distortion) to +- 1. + */ + amount: number; + + } /** - * A temporary Transform Matrix, re-used internally during batching by the - * Shape Game Objects. + * The Bloom FX Pipeline. + * + * Bloom is an effect used to reproduce an imaging artifact of real-world cameras. + * The effect produces fringes of light extending from the borders of bright areas in an image, + * contributing to the illusion of an extremely bright light overwhelming the + * camera or eye capturing the scene. + * + * A Bloom effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addBloom(); + * ``` + */ + class BloomFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The number of steps to run the Bloom effect for. + * + * This value should always be an integer. + * + * It defaults to 4. The higher the value, the smoother the Bloom, + * but at the cost of exponentially more gl operations. + * + * Keep this to the lowest possible number you can have it, while + * still looking correct for your game. + */ + steps: number; + + /** + * The horizontal offset of the bloom effect. + */ + offsetX: number; + + /** + * The vertical offset of the bloom effect. + */ + offsetY: number; + + /** + * The strength of the blur process of the bloom effect. + */ + blurStrength: number; + + /** + * The strength of the blend process of the bloom effect. + */ + strength: number; + + /** + * The internal gl color array. + */ + glcolor: number[]; + + } + + /** + * The Blur FX Pipeline. + * + * A Gaussian blur is the result of blurring an image by a Gaussian function. It is a widely used effect, + * typically to reduce image noise and reduce detail. The visual effect of this blurring technique is a + * smooth blur resembling that of viewing the image through a translucent screen, distinctly different + * from the bokeh effect produced by an out-of-focus lens or the shadow of an object under usual illumination. + * + * A Blur effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addBlur(); + * ``` + */ + class BlurFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The horizontal offset of the blur effect. + */ + x: number; + + /** + * The vertical offset of the blur effect. + */ + y: number; + + /** + * The number of steps to run the Blur effect for. + * + * This value should always be an integer. + * + * It defaults to 4. The higher the value, the smoother the blur, + * but at the cost of exponentially more gl operations. + * + * Keep this to the lowest possible number you can have it, while + * still looking correct for your game. + */ + steps: number; + + /** + * The strength of the blur effect. + */ + strength: number; + + /** + * The internal gl color array. + */ + glcolor: number[]; + + /** + * Sets the quality of the blur effect to low. + */ + setQualityLow(): this; + + /** + * Sets the quality of the blur effect to medium. + */ + setQualityMedium(): this; + + /** + * Sets the quality of the blur effect to high. + */ + setQualityHigh(): this; + + } + + /** + * The Bokeh FX Pipeline. + * + * Bokeh refers to a visual effect that mimics the photographic technique of creating a shallow depth of field. + * This effect is used to emphasize the game's main subject or action, by blurring the background or foreground + * elements, resulting in a more immersive and visually appealing experience. It is achieved through rendering + * techniques that simulate the out-of-focus areas, giving a sense of depth and realism to the game's graphics. + * + * This effect can also be used to generate a Tilt Shift effect, which is a technique used to create a miniature + * effect by blurring everything except a small area of the image. This effect is achieved by blurring the + * top and bottom elements, while keeping the center area in focus. + * + * A Bokeh effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addBokeh(); + * ``` + */ + class BokehFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * Is this a Tilt Shift effect or a standard bokeh effect? + */ + isTiltShift: boolean; + + /** + * If a Tilt Shift effect this controls the strength of the blur. + * + * Setting this value on a non-Tilt Shift effect will have no effect. + */ + strength: number; + + /** + * If a Tilt Shift effect this controls the amount of horizontal blur. + * + * Setting this value on a non-Tilt Shift effect will have no effect. + */ + blurX: number; + + /** + * If a Tilt Shift effect this controls the amount of vertical blur. + * + * Setting this value on a non-Tilt Shift effect will have no effect. + */ + blurY: number; + + /** + * The radius of the bokeh effect. + * + * This is a float value, where a radius of 0 will result in no effect being applied, + * and a radius of 1 will result in a strong bokeh. However, you can exceed this value + * for even stronger effects. + */ + radius: number; + + /** + * The amount, or strength, of the bokeh effect. Defaults to 1. + */ + amount: number; + + /** + * The color contrast, or brightness, of the bokeh effect. Defaults to 0.2. + */ + contrast: number; + + } + + /** + * The Circle FX Pipeline. + * + * This effect will draw a circle around the texture of the Game Object, effectively masking off + * any area outside of the circle without the need for an actual mask. You can control the thickness + * of the circle, the color of the circle and the color of the background, should the texture be + * transparent. You can also control the feathering applied to the circle, allowing for a harsh or soft edge. + * + * Please note that adding this effect to a Game Object will not change the input area or physics body of + * the Game Object, should it have one. + * + * A Circle effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addCircle(); + * ``` + */ + class CircleFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The scale of the circle. The default scale is 1, which is a circle + * the full size of the underlying texture. Reduce this value to create + * a smaller circle, or increase it to create a circle that extends off + * the edges of the texture. + */ + scale: number; + + /** + * The amount of feathering to apply to the circle from the ring, + * extending into the middle of the circle. The default is 0.005, + * which is a very low amount of feathering just making sure the ring + * has a smooth edge. Increase this amount to a value such as 0.5 + * or 0.025 for larger amounts of feathering. + */ + feather: number; + + /** + * The width of the circle around the texture, in pixels. This value + * doesn't factor in the feather, which can extend the thickness + * internally depending on its value. + */ + thickness: number; + + /** + * The internal gl color array for the ring color. + */ + glcolor: number[]; + + /** + * The internal gl color array for the background color. + */ + glcolor2: number[]; + + } + + /** + * The ColorMatrix FX Pipeline. + * + * The color matrix effect is a visual technique that involves manipulating the colors of an image + * or scene using a mathematical matrix. This process can adjust hue, saturation, brightness, and contrast, + * allowing developers to create various stylistic appearances or mood settings within the game. + * Common applications include simulating different lighting conditions, applying color filters, + * or achieving a specific visual style. + * + * A ColorMatrix effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addColorMatrix(); + * ``` */ - calcMatrix: Phaser.GameObjects.Components.TransformMatrix; + class ColorMatrixFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + } /** - * Pushes a filled rectangle into the vertex batch. + * The Displacement FX Pipeline. * - * Rectangle factors in the given transform matrices before adding to the batch. - * @param x Horizontal top left coordinate of the rectangle. - * @param y Vertical top left coordinate of the rectangle. - * @param width Width of the rectangle. - * @param height Height of the rectangle. - * @param currentMatrix The current transform. - * @param parentMatrix The parent transform. + * The displacement effect is a visual technique that alters the position of pixels in an image + * or texture based on the values of a displacement map. This effect is used to create the illusion + * of depth, surface irregularities, or distortion in otherwise flat elements. It can be applied to + * characters, objects, or backgrounds to enhance realism, convey movement, or achieve various + * stylistic appearances. + * + * A Displacement effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addDisplacement(); + * ``` */ - batchFillRect(x: number, y: number, width: number, height: number, currentMatrix: Phaser.GameObjects.Components.TransformMatrix, parentMatrix: Phaser.GameObjects.Components.TransformMatrix): void; + class DisplacementFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The amount of horizontal displacement to apply. + */ + x: number; + + /** + * The amount of vertical displacement to apply. + */ + y: number; + + /** + * The underlying WebGLTexture used for displacement. + */ + glTexture: WebGLTexture; + + } /** - * Pushes a filled triangle into the vertex batch. + * The Glow FX Pipeline. * - * Triangle factors in the given transform matrices before adding to the batch. - * @param x0 Point 0 x coordinate. - * @param y0 Point 0 y coordinate. - * @param x1 Point 1 x coordinate. - * @param y1 Point 1 y coordinate. - * @param x2 Point 2 x coordinate. - * @param y2 Point 2 y coordinate. - * @param currentMatrix The current transform. - * @param parentMatrix The parent transform. + * The glow effect is a visual technique that creates a soft, luminous halo around game objects, + * characters, or UI elements. This effect is used to emphasize importance, enhance visual appeal, + * or convey a sense of energy, magic, or otherworldly presence. The effect can also be set on + * the inside of the Game Object. The color and strength of the glow can be modified. + * + * A Glow effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addGlow(); + * ``` */ - batchFillTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, currentMatrix: Phaser.GameObjects.Components.TransformMatrix, parentMatrix: Phaser.GameObjects.Components.TransformMatrix): void; + class GlowFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + * @param config The configuration options for this pipeline. + */ + constructor(game: Phaser.Game, config: object); + + /** + * The strength of the glow outward from the edge of the Sprite. + */ + outerStrength: number; + + /** + * The strength of the glow inward from the edge of the Sprite. + */ + innerStrength: number; + + /** + * If `true` only the glow is drawn, not the texture itself. + */ + knockout: number; + + /** + * A 4 element array of gl color values. + */ + glcolor: number[]; + + } /** - * Pushes a stroked triangle into the vertex batch. + * The Gradient FX Pipeline. * - * Triangle factors in the given transform matrices before adding to the batch. + * The gradient overlay effect is a visual technique where a smooth color transition is applied over Game Objects, + * such as sprites or UI components. This effect is used to enhance visual appeal, emphasize depth, or create + * stylistic and atmospheric variations. It can also be utilized to convey information, such as representing + * progress or health status through color changes. * - * The triangle is created from 3 lines and drawn using the `batchStrokePath` method. - * @param x0 Point 0 x coordinate. - * @param y0 Point 0 y coordinate. - * @param x1 Point 1 x coordinate. - * @param y1 Point 1 y coordinate. - * @param x2 Point 2 x coordinate. - * @param y2 Point 2 y coordinate. - * @param lineWidth The width of the line in pixels. - * @param currentMatrix The current transform. - * @param parentMatrix The parent transform. + * A Gradient effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addGradient(); + * ``` + */ + class GradientFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The alpha value of the gradient effect. + */ + alpha: number; + + /** + * Sets how many 'chunks' the gradient is divided in to, as spread over the + * entire height of the texture. Leave this at zero for a smooth gradient, + * or set to a higher number to split the gradient into that many sections, giving + * a more banded 'retro' effect. + */ + size: number; + + /** + * The horizontal position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + */ + fromX: number; + + /** + * The vertical position the gradient will start from. This value is noralized, between 0 and 1 and is not in pixels. + */ + fromY: number; + + /** + * The horizontal position the gradient will end. This value is noralized, between 0 and 1 and is not in pixels. + */ + toX: number; + + /** + * The vertical position the gradient will end. This value is noralized, between 0 and 1 and is not in pixels. + */ + toY: number; + + /** + * The internal gl color array for the starting color. + */ + glcolor1: number[]; + + /** + * The internal gl color array for the ending color. + */ + glcolor2: number[]; + + } + + /** + * The Pixelate FX Pipeline. + * + * The pixelate effect is a visual technique that deliberately reduces the resolution or detail of an image, + * creating a blocky or mosaic appearance composed of large, visible pixels. This effect can be used for stylistic + * purposes, as a homage to retro gaming, or as a means to obscure certain elements within the game, such as + * during a transition or to censor specific content. + * + * A Pixelate effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addPixelate(); + * ``` */ - batchStrokeTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, lineWidth: number, currentMatrix: Phaser.GameObjects.Components.TransformMatrix, parentMatrix: Phaser.GameObjects.Components.TransformMatrix): void; + class PixelateFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The amount of pixelation to apply. + */ + amount: number; + + } /** - * Adds the given path to the vertex batch for rendering. + * The Shadow FX Pipeline. * - * It works by taking the array of path data and then passing it through Earcut, which - * creates a list of polygons. Each polygon is then added to the batch. + * The shadow effect is a visual technique used to create the illusion of depth and realism by adding darker, + * offset silhouettes or shapes beneath game objects, characters, or environments. These simulated shadows + * help to enhance the visual appeal and immersion, making the 2D game world appear more dynamic and three-dimensional. * - * The path is always automatically closed because it's filled. - * @param path Collection of points that represent the path. - * @param currentMatrix The current transform. - * @param parentMatrix The parent transform. + * A Shadow effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addShadow(); + * ``` + */ + class ShadowFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The horizontal offset of the shadow effect. + */ + x: number; + + /** + * The vertical offset of the shadow effect. + */ + y: number; + + /** + * The amount of decay for the shadow effect. + */ + decay: number; + + /** + * The power of the shadow effect. + */ + power: number; + + /** + * The internal gl color array. + */ + glcolor: number[]; + + /** + * The number of samples that the shadow effect will run for. + * + * This should be an integer with a minimum value of 1 and a maximum of 12. + */ + samples: number; + + /** + * The intensity of the shadow effect. + */ + intensity: number; + + } + + /** + * The Shine FX Pipeline. + * + * The shine effect is a visual technique that simulates the appearance of reflective + * or glossy surfaces by passing a light beam across a Game Object. This effect is used to + * enhance visual appeal, emphasize certain features, and create a sense of depth or + * material properties. + * + * A Shine effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addShine(); + * ``` */ - batchFillPath(path: Phaser.Types.Math.Vector2Like[], currentMatrix: Phaser.GameObjects.Components.TransformMatrix, parentMatrix: Phaser.GameObjects.Components.TransformMatrix): void; + class ShineFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The speed of the Shine effect. + */ + speed: number; + + /** + * The line width of the Shine effect. + */ + lineWidth: number; + + /** + * The gradient of the Shine effect. + */ + gradient: number; + + /** + * Does this Shine effect reveal or get added to its target? + */ + reveal: boolean; + + } /** - * Adds the given path to the vertex batch for rendering. + * The Vignette FX Pipeline. * - * It works by taking the array of path data and calling `batchLine` for each section - * of the path. + * The vignette effect is a visual technique where the edges of the screen, or a Game Object, gradually darken or blur, + * creating a frame-like appearance. This effect is used to draw the player's focus towards the central action or subject, + * enhance immersion, and provide a cinematic or artistic quality to the game's visuals. * - * The path is optionally closed at the end. - * @param path Collection of points that represent the path. - * @param lineWidth The width of the line segments in pixels. - * @param pathOpen Indicates if the path should be closed or left open. - * @param currentMatrix The current transform. - * @param parentMatrix The parent transform. + * A Vignette effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addVignette(); + * ``` */ - batchStrokePath(path: Phaser.Types.Math.Vector2Like[], lineWidth: number, pathOpen: boolean, currentMatrix: Phaser.GameObjects.Components.TransformMatrix, parentMatrix: Phaser.GameObjects.Components.TransformMatrix): void; + class VignetteFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1. + */ + x: number; + + /** + * The vertical offset of the vignette effect. This value is normalized to the range 0 to 1. + */ + y: number; + + /** + * The radius of the vignette effect. This value is normalized to the range 0 to 1. + */ + radius: number; + + /** + * The strength of the vignette effect. + */ + strength: number; + + } /** - * Creates a line out of 4 quads and adds it to the vertex batch based on the given line values. - * @param ax x coordinate of the start of the line. - * @param ay y coordinate of the start of the line. - * @param bx x coordinate of the end of the line. - * @param by y coordinate of the end of the line. - * @param aLineWidth Width of the start of the line. - * @param bLineWidth Width of the end of the line. - * @param index If this line is part of a multi-line draw, the index of the line in the draw. - * @param closePath Does this line close a multi-line path? - * @param currentMatrix The current transform. - * @param parentMatrix The parent transform. + * The Wipe FX Pipeline. + * + * The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements + * in the game, such as images, text, or scene transitions. This effect is often used to create + * a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition + * between game states. + * + * You can set both the direction and the axis of the wipe effect. The following combinations are possible: + * + * * left to right: direction 0, axis 0 + * * right to left: direction 1, axis 0 + * * top to bottom: direction 1, axis 1 + * * bottom to top: direction 1, axis 0 + * + * It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect. + * + * A Wipe effect is added to a Game Object via the FX component: + * + * ```js + * const sprite = this.add.sprite(); + * + * sprite.postFX.addWipe(); + * sprite.postFX.addReveal(); + * ``` + */ + class WipeFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param game A reference to the Phaser Game instance. + */ + constructor(game: Phaser.Game); + + /** + * The progress of the Wipe effect. This value is normalized to the range 0 to 1. + * + * Adjust this value to make the wipe transition (i.e. via a Tween) + */ + progress: number; + + /** + * The width of the wipe effect. This value is normalized in the range 0 to 1. + */ + wipeWidth: number; + + /** + * The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property. + */ + direction: number; + + /** + * The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property. + */ + axis: number; + + /** + * Is this a reveal (true) or a fade (false) effect? + */ + reveal: boolean; + + } + + } + + /** + * The FXPipeline is a built-in pipeline that controls the application of FX Controllers during + * the rendering process. It maintains all of the FX shaders, instances of Post FX Pipelines and + * is responsible for rendering. + * + * You should rarely interact with this pipeline directly. Instead, use the FX Controllers that + * is part of the Game Object class in order to manage the effects. + */ + class FXPipeline extends Phaser.Renderer.WebGL.Pipelines.PreFXPipeline { + /** + * + * @param game A reference to the Phaser game instance. */ - batchLine(ax: number, ay: number, bx: number, by: number, aLineWidth: number, bLineWidth: number, index: number, closePath: boolean, currentMatrix: Phaser.GameObjects.Components.TransformMatrix, parentMatrix: Phaser.GameObjects.Components.TransformMatrix): void; + constructor(game: Phaser.Game); /** - * Adds a single vertex to the current vertex buffer and increments the - * `vertexCount` property by 1. + * An instance of the Glow Post FX Pipeline. + */ + glow: Phaser.Renderer.WebGL.Pipelines.FX.GlowFXPipeline; + + /** + * An instance of the Shadow Post FX Pipeline. + */ + shadow: Phaser.Renderer.WebGL.Pipelines.FX.ShadowFXPipeline; + + /** + * An instance of the Pixelate Post FX Pipeline. + */ + pixelate: Phaser.Renderer.WebGL.Pipelines.FX.PixelateFXPipeline; + + /** + * An instance of the Vignette Post FX Pipeline. + */ + vignette: Phaser.Renderer.WebGL.Pipelines.FX.VignetteFXPipeline; + + /** + * An instance of the Shine Post FX Pipeline. + */ + shine: Phaser.Renderer.WebGL.Pipelines.FX.ShineFXPipeline; + + /** + * An instance of the Gradient Post FX Pipeline. + */ + gradient: Phaser.Renderer.WebGL.Pipelines.FX.GradientFXPipeline; + + /** + * An instance of the Circle Post FX Pipeline. + */ + circle: Phaser.Renderer.WebGL.Pipelines.FX.CircleFXPipeline; + + /** + * An instance of the Barrel Post FX Pipeline. + */ + barrel: Phaser.Renderer.WebGL.Pipelines.FX.BarrelFXPipeline; + + /** + * An instance of the Wipe Post FX Pipeline. + */ + wipe: Phaser.Renderer.WebGL.Pipelines.FX.WipeFXPipeline; + + /** + * An instance of the Bokeh Post FX Pipeline. + */ + bokeh: Phaser.Renderer.WebGL.Pipelines.FX.BokehFXPipeline; + + /** + * An array containing references to the methods that map to the FX CONSTs. + * + * This array is intentionally sparse. Do not adjust. + */ + fxHandlers: Function[]; + + /** + * The source Render Target. + */ + source: Phaser.Renderer.WebGL.RenderTarget; + + /** + * The target Render Target. + */ + target: Phaser.Renderer.WebGL.RenderTarget; + + /** + * The swap Render Target. + */ + swap: Phaser.Renderer.WebGL.RenderTarget; + + /** + * Takes the currently bound Game Object and runs all of its pre-render effects, + * using the given Render Target as the source. * - * This method is called directly by `batchTri` and `batchQuad`. + * Finally calls `drawToGame` to copy the result to the Game Canvas. + * @param target1 The source Render Target. + * @param target2 The target Render Target. + * @param target3 The swap Render Target. + */ + onDraw(target1: Phaser.Renderer.WebGL.RenderTarget, target2: Phaser.Renderer.WebGL.RenderTarget, target3: Phaser.Renderer.WebGL.RenderTarget): void; + + /** + * Takes the source and target and runs a copy from source to target. * - * It does not perform any batch limit checking itself, so if you need to call - * this method directly, do so in the same way that `batchQuad` does, for example. - * @param x The vertex x position. - * @param y The vertex y position. - * @param tint The tint color value. + * This will use the current shader and pipeline. + */ + runDraw(): void; + + /** + * Runs the Glow FX controller. + * @param config The Glow FX controller. + * @param width The width of the target. + * @param height The height of the target. + */ + onGlow(config: Phaser.FX.Glow, width: number, height: number): void; + + /** + * Runs the Shadow FX controller. + * @param config The Shadow FX controller. + */ + onShadow(config: Phaser.FX.Shadow): void; + + /** + * Runs the Pixelate FX controller. + * @param config The Pixelate FX controller. + * @param width The width of the target. + * @param height The height of the target. + */ + onPixelate(config: Phaser.FX.Pixelate, width: number, height: number): void; + + /** + * Runs the Vignette FX controller. + * @param config The Vignette FX controller. + */ + onVignette(config: Phaser.FX.Vignette): void; + + /** + * Runs the Shine FX controller. + * @param config The Shine FX controller. + * @param width The width of the target. + * @param height The height of the target. + */ + onShine(config: Phaser.FX.Shine, width: number, height: number): void; + + /** + * Runs the Blur FX controller. + * @param config The Blur FX controller. + * @param width The width of the target. + * @param height The height of the target. + */ + onBlur(config: Phaser.FX.Blur, width: number, height: number): void; + + /** + * Runs the Gradient FX controller. + * @param config The Gradient FX controller. + */ + onGradient(config: Phaser.FX.Gradient): void; + + /** + * Runs the Bloom FX controller. + * @param config The Bloom FX controller. + * @param width The width of the target. + * @param height The height of the target. + */ + onBloom(config: Phaser.FX.Bloom, width: number, height: number): void; + + /** + * Runs the ColorMatrix FX controller. + * @param config The ColorMatrix FX controller. */ - batchVert(x: number, y: number, tint: number): void; + onColorMatrix(config: Phaser.FX.ColorMatrix): void; + + /** + * Runs the Circle FX controller. + * @param config The Circle FX controller. + * @param width The width of the target. + * @param height The height of the target. + */ + onCircle(config: Phaser.FX.Circle, width: number, height: number): void; + + /** + * Runs the Barrel FX controller. + * @param config The Barrel FX controller. + */ + onBarrel(config: Phaser.FX.Barrel): void; + + /** + * Runs the Displacement FX controller. + * @param config The Displacement FX controller. + */ + onDisplacement(config: Phaser.FX.Displacement): void; + + /** + * Runs the Wipe FX controller. + * @param config The Wipe FX controller. + */ + onWipe(config: Phaser.FX.Wipe): void; + + /** + * Runs the Bokeh FX controller. + * @param config The Bokeh FX controller. + */ + onBokeh(config: Phaser.FX.Bokeh): void; /** * Destroys all shader instances, removes all object references and nulls all external references. @@ -80605,6 +93403,11 @@ declare namespace Phaser { */ readonly lightsActive: boolean; + /** + * A persistent calculation vector used when processing the lights. + */ + tempVec2: Phaser.Math.Vector2; + /** * Called when the Game has fully booted and the Renderer has finished setting up. * @@ -80686,6 +93489,56 @@ declare namespace Phaser { } + /** + * The Mobile Pipeline is the core 2D texture rendering pipeline used by Phaser in WebGL + * when the device running the game is detected to be a mobile. + * + * You can control the use of this pipeline by setting the Game Configuration + * property `autoMobilePipeline`. If set to `false` then all devices will use + * the Multi Tint Pipeline. You can also call the `PipelineManager.setDefaultPipeline` + * method at run-time, rather than boot-time, to modify the default Game Object + * pipeline. + * + * 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. + * + * The fragment shader it uses can be found in `shaders/src/Mobile.frag`. + * The vertex shader it uses can be found in `shaders/src/Mobile.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) + * + * Note that `inTexId` isn't used in the shader, it's just kept to allow us + * to piggy-back on the Multi Tint Pipeline functions. + * + * The default shader uniforms for this pipeline are: + * + * `uProjectionMatrix` (mat4) + * `uMainSampler` (sampler2D) + */ + class MobilePipeline extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline { + /** + * + * @param config The configuration options for this pipeline. + */ + constructor(config: Phaser.Types.Renderer.WebGL.WebGLPipelineConfig); + + /** + * Called when the Game has fully booted and the Renderer has finished setting up. + * + * By this stage all Game level systems are now in place and you can perform any final + * tasks that the pipeline may need that relied on game systems such as the Texture Manager. + */ + boot(): void; + + } + /** * 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 @@ -80714,12 +93567,14 @@ declare namespace Phaser { * `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. + * If you wish to create a custom pipeline extending from this one, you should use the string + * declaration `%count%` in your fragment shader source, which is used to set the number of + * `sampler2Ds` available. Also add `%getSampler%` so Phaser can inject the getSampler glsl function. + * This function can be used to get the pixel vec4 from the texture: + * + * `vec4 texture = getSampler(int(outTexId), outTexCoord);` * - * This pipeline will automatically inject that code for you, should those values exist + * This pipeline will automatically inject the getSampler function for you, should the value exist * in your shader source. If you wish to handle this yourself, you can also use the * function `Utils.parseFragmentShaderMaxTextures`. * @@ -80744,7 +93599,7 @@ declare namespace Phaser { * Sets the shader program, vertex buffer and other resources. * Should only be called when changing pipeline. */ - bind(): this; + boot(): void; /** * Takes a Sprite Game Object, or any object that extends it, and adds it to the batch. @@ -80892,6 +93747,11 @@ declare namespace Phaser { */ batchLine(ax: number, ay: number, bx: number, by: number, aLineWidth: number, bLineWidth: number, index: number, closePath: boolean, currentMatrix: Phaser.GameObjects.Components.TransformMatrix, parentMatrix: Phaser.GameObjects.Components.TransformMatrix): void; + /** + * Destroys all shader instances, removes all object references and nulls all external references. + */ + destroy(): this; + } /** @@ -81040,9 +93900,16 @@ declare namespace Phaser { constructor(config: Phaser.Types.Renderer.WebGL.WebGLPipelineConfig); /** - * If this post-pipeline belongs to a Game Object or Camera, this contains a reference to it. + * If this Post Pipeline belongs to a Game Object or Camera, + * this property contains a reference to it. + */ + gameObject: Phaser.GameObjects.GameObject | Phaser.Cameras.Scene2D.Camera; + + /** + * If this Post Pipeline belongs to an FX Controller, this is a + * reference to it. */ - gameObject: Phaser.GameObjects.GameObject; + controller: Phaser.FX.Controller; /** * A Color Matrix instance belonging to this pipeline. @@ -81095,6 +93962,26 @@ declare namespace Phaser { */ halfFrame2: Phaser.Renderer.WebGL.RenderTarget; + /** + * Returns the FX Controller for this Post FX Pipeline. + * + * This is called internally and not typically required outside. + * @param controller An FX Controller, or undefined. + */ + getController(controller?: Phaser.FX.Controller): Phaser.FX.Controller | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline; + + /** + * Copy the `source` Render Target to the `target` Render Target. + * + * This method does _not_ bind a shader. It uses whatever shader + * is currently bound in this pipeline. It also does _not_ clear + * the frame buffers after use. You should take care of both of + * these things if you call this method directly. + * @param source The source Render Target. + * @param target The target Render Target. + */ + copySprite(source: Phaser.Renderer.WebGL.RenderTarget, target: Phaser.Renderer.WebGL.RenderTarget): void; + /** * Copy the `source` Render Target to the `target` Render Target. * @@ -81125,8 +94012,8 @@ declare namespace Phaser { copyToGame(source: Phaser.Renderer.WebGL.RenderTarget): void; /** - * Copy the `source` Render Target to the `target` Render Target, using the - * given Color Matrix. + * Copy the `source` Render Target to the `target` Render Target, using this pipelines + * 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 @@ -81221,6 +94108,309 @@ declare namespace Phaser { */ bindAndDraw(source: Phaser.Renderer.WebGL.RenderTarget, target?: Phaser.Renderer.WebGL.RenderTarget, clear?: boolean, clearAlpha?: boolean, currentShader?: Phaser.Renderer.WebGL.WebGLShader): void; + /** + * Destroys all shader instances, removes all object references and nulls all external references. + */ + destroy(): this; + + } + + /** + * The Pre FX Pipeline is a special kind of pipeline designed specifically for applying + * special effects to Game Objects before they are rendered. Where-as the Post FX Pipeline applies an effect _after_ the + * object has been rendered, the Pre FX Pipeline allows you to control the rendering of + * the object itself - passing it off to its own texture, where multi-buffer compositing + * can take place. + * + * You can only use the PreFX Pipeline on the following types of Game Objects, or those + * that extend from them: + * + * Sprite + * Image + * Text + * TileSprite + * RenderTexture + * Video + */ + class PreFXPipeline extends Phaser.Renderer.WebGL.WebGLPipeline { + /** + * + * @param config The configuration options for this pipeline. + */ + constructor(config: Phaser.Types.Renderer.WebGL.WebGLPipelineConfig); + + /** + * A reference to the Draw Sprite Shader belonging to this Pipeline. + * + * This shader is used when the sprite is drawn to this fbo (or to the game if drawToFrame is false) + * + * This property is set during the `boot` method. + */ + drawSpriteShader: Phaser.Renderer.WebGL.WebGLShader; + + /** + * A reference to the Copy Shader belonging to this Pipeline. + * + * This shader is used when you call the `copySprite` method. + * + * This property is set during the `boot` method. + */ + copyShader: Phaser.Renderer.WebGL.WebGLShader; + + /** + * A reference to the Game Draw Shader belonging to this Pipeline. + * + * This shader draws the fbo to the game. + * + * This property is set during the `boot` method. + */ + gameShader: Phaser.Renderer.WebGL.WebGLShader; + + /** + * A reference to the Color Matrix Shader belonging to this Pipeline. + * + * This property is set during the `boot` method. + */ + colorMatrixShader: Phaser.Renderer.WebGL.WebGLShader; + + /** + * Raw byte buffer of vertices used specifically during the copySprite method. + */ + readonly quadVertexData: ArrayBuffer; + + /** + * The WebGLBuffer that holds the quadVertexData. + */ + readonly quadVertexBuffer: WebGLBuffer; + + /** + * Float32 view of the quad array buffer. + */ + quadVertexViewF32: Float32Array; + + /** + * The full-screen Render Target that the sprite is first drawn to. + */ + fsTarget: Phaser.Renderer.WebGL.RenderTarget; + + /** + * Handles the resizing of the quad vertex data. + * @param width The new width of the quad. + * @param height The new height of the quad. + */ + onResize(width: number, height: number): void; + + /** + * Adds the vertices data into the batch and flushes if full. + * + * Assumes 6 vertices in the following arrangement: + * + * ``` + * 0----3 + * |\ B| + * | \ | + * | \ | + * | A \| + * | \ + * 1----2 + * ``` + * + * Where x0 / y0 = 0, x1 / y1 = 1, x2 / y2 = 2 and x3 / y3 = 3 + * @param gameObject The Game Object, if any, drawing this quad. + * @param x0 The top-left x position. + * @param y0 The top-left y position. + * @param x1 The bottom-left x position. + * @param y1 The bottom-left y position. + * @param x2 The bottom-right x position. + * @param y2 The bottom-right y position. + * @param x3 The top-right x position. + * @param y3 The top-right y position. + * @param u0 UV u0 value. + * @param v0 UV v0 value. + * @param u1 UV u1 value. + * @param v1 UV v1 value. + * @param tintTL The top-left tint color value. + * @param tintTR The top-right tint color value. + * @param tintBL The bottom-left tint color value. + * @param tintBR The bottom-right tint color value. + * @param tintEffect The tint effect for the shader to use. + * @param texture WebGLTexture that will be assigned to the current batch if a flush occurs. + */ + batchQuad(gameObject: Phaser.GameObjects.GameObject | null, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, u0: number, v0: number, u1: number, v1: number, tintTL: number, tintTR: number, tintBL: number, tintBR: number, tintEffect: number | boolean, texture?: WebGLTexture): boolean; + + /** + * This callback is invoked when a sprite is drawn by this pipeline. + * + * It will fire after the shader has been set, but before the sprite has been drawn, + * so use it to set any additional uniforms you may need. + * + * Note: Manipulating the Sprite during this callback will _not_ change how it is drawn to the Render Target. + * @param gameObject The Sprite being drawn. + * @param target The Render Target the Sprite will be drawn to. + */ + onDrawSprite(gameObject: Phaser.GameObjects.Sprite, target: Phaser.Renderer.WebGL.RenderTarget): void; + + /** + * This callback is invoked when you call the `copySprite` method. + * + * It will fire after the shader has been set, but before the source target has been copied, + * so use it to set any additional uniforms you may need. + * + * Note: Manipulating the Sprite during this callback will _not_ change the Render Targets. + * @param source The source Render Target being copied from. + * @param target The target Render Target that will be copied to. + * @param gameObject The Sprite being copied. + */ + onCopySprite(source: Phaser.Renderer.WebGL.RenderTarget, target: Phaser.Renderer.WebGL.RenderTarget, gameObject: Phaser.GameObjects.Sprite): void; + + /** + * Copy the `source` Render Target to the `target` Render Target. + * + * No target 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. + * + * Calling this method will invoke the `onCopySprite` handler and will also call + * the `onFXCopy` callback on the Sprite. Both of these happen prior to the copy, allowing you + * to use them to set shader uniforms and other values. + * + * You can optionally pass in a ColorMatrix. If so, it will use the ColorMatrix shader + * during the copy, allowing you to manipulate the colors to a fine degree. + * See the `ColorMatrix` class for more details. + * @param source The source Render Target being copied from. + * @param target The target Render Target that will be copied to. + * @param clear Clear the target before copying? Default true. + * @param clearAlpha Clear the alpha channel when running `gl.clear` on the target? Default true. + * @param eraseMode Erase source from target using ERASE Blend Mode? Default false. + * @param colorMatrix Optional ColorMatrix to use when copying the Sprite. + * @param shader The shader to use to copy the target. Defaults to the `copyShader`. + */ + copySprite(source: Phaser.Renderer.WebGL.RenderTarget, target: Phaser.Renderer.WebGL.RenderTarget, clear?: boolean, clearAlpha?: boolean, eraseMode?: boolean, colorMatrix?: Phaser.Display.ColorMatrix, shader?: Phaser.Renderer.WebGL.WebGLShader): void; + + /** + * Draws the `source` Render Target to the `target` Render Target. + * + * This is done using whatever the currently bound shader is. This method does + * not set a shader. All it does is bind the source texture, set the viewport and UVs + * then bind the target framebuffer, clears it and draws the source to it. + * + * At the end a null framebuffer is bound. No other clearing-up takes place, so + * use this method carefully. + * @param source The source Render Target. + * @param target The target Render Target. + */ + copy(source: Phaser.Renderer.WebGL.RenderTarget, target: Phaser.Renderer.WebGL.RenderTarget): void; + + /** + * Draws the `source1` and `source2` Render Targets to the `target` Render Target + * using a linear blend effect, which is controlled by the `strength` parameter. + * @param source1 The first source Render Target. + * @param source2 The second source Render Target. + * @param target The target Render Target. + * @param strength The strength of the blend. Default 1. + * @param clearAlpha Clear the alpha channel when running `gl.clear` on the target? Default true. + */ + blendFrames(source1: Phaser.Renderer.WebGL.RenderTarget, source2: Phaser.Renderer.WebGL.RenderTarget, target?: Phaser.Renderer.WebGL.RenderTarget, strength?: number, clearAlpha?: boolean): void; + + /** + * Draws the `source1` and `source2` Render Targets to the `target` Render Target + * using an additive blend effect, which is controlled by the `strength` parameter. + * @param source1 The first source Render Target. + * @param source2 The second source Render Target. + * @param target The target Render Target. + * @param strength The strength of the blend. Default 1. + * @param clearAlpha Clear the alpha channel when running `gl.clear` on the target? Default true. + */ + blendFramesAdditive(source1: Phaser.Renderer.WebGL.RenderTarget, source2: Phaser.Renderer.WebGL.RenderTarget, target?: Phaser.Renderer.WebGL.RenderTarget, strength?: number, clearAlpha?: boolean): void; + + /** + * This method will copy the given Render Target to the game canvas using the `copyShader`. + * + * This applies the results of the copy shader during the draw. + * + * If you wish to copy the target without any effects see the `copyToGame` method instead. + * + * This method should be the final thing called in your pipeline. + * @param source The Render Target to draw to the game. + */ + drawToGame(source: Phaser.Renderer.WebGL.RenderTarget): void; + + /** + * This method will copy the given Render Target to the game canvas using the `gameShader`. + * + * Unless you've changed it, the `gameShader` copies the target without modifying it, just + * ensuring it is placed in the correct location on the canvas. + * + * If you wish to draw the target with and apply the fragment shader at the same time, + * see the `drawToGame` method instead. + * + * This method should be the final thing called in your pipeline. + * @param source The Render Target to copy to the game. + */ + copyToGame(source: Phaser.Renderer.WebGL.RenderTarget): void; + + /** + * This method is called by `drawToGame` and `copyToGame`. It takes the source Render Target + * and copies it back to the game canvas, or the next frame buffer in the stack, and should + * be considered the very last thing this pipeline does. + * + * You don't normally need to call this method, or override it, however it is left public + * should you wish to do so. + * + * Note that it does _not_ set a shader. You should do this yourself if invoking this. + * @param source The Render Target to draw to the game. + */ + bindAndDraw(source: Phaser.Renderer.WebGL.RenderTarget): void; + + /** + * This method is called every time the `batchSprite` method is called and is passed a + * reference to the current render target. + * + * If you override this method, then it should make sure it calls either the + * `drawToGame` or `copyToGame` methods as the final thing it does. However, you can do as + * much additional processing as you like prior to this. + * @param target The Render Target to draw to the game. + * @param swapTarget The Swap Render Target, useful for double-buffer effects. + * @param altSwapTarget The Swap Render Target, useful for double-buffer effects. + */ + onDraw(target: Phaser.Renderer.WebGL.RenderTarget, swapTarget?: Phaser.Renderer.WebGL.RenderTarget, altSwapTarget?: Phaser.Renderer.WebGL.RenderTarget): void; + + /** + * Set the UV values for the 6 vertices that make up the quad used by the copy shader. + * + * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. + * @param uA The u value of vertex A. + * @param vA The v value of vertex A. + * @param uB The u value of vertex B. + * @param vB The v value of vertex B. + * @param uC The u value of vertex C. + * @param vC The v value of vertex C. + * @param uD The u value of vertex D. + * @param vD The v value of vertex D. + */ + setUVs(uA: number, vA: number, uB: number, vB: number, uC: number, vC: number, uD: number, vD: number): void; + + /** + * Sets the vertex UV coordinates of the quad used by the copy shaders + * so that they correctly adjust the texture coordinates for a blit frame effect. + * + * Be sure to call `resetUVs` once you have finished manipulating the UV coordinates. + * @param source The source Render Target. + * @param target The target Render Target. + */ + setTargetUVs(source: Phaser.Renderer.WebGL.RenderTarget, target: Phaser.Renderer.WebGL.RenderTarget): void; + + /** + * Resets the quad vertice UV values to their default settings. + * + * The quad is used by the copy shader in this pipeline. + */ + resetUVs(): void; + + /** + * Destroys all shader instances, removes all object references and nulls all external references. + */ + destroy(): this; + } /** @@ -81434,8 +94624,9 @@ declare namespace Phaser { * @param clear Clear the target before copying? Default true. * @param clearAlpha Clear the alpha channel when running `gl.clear` on the target? Default true. * @param eraseMode Erase source from target using ERASE Blend Mode? Default false. + * @param flipY Flip the UV on the Y axis before drawing? Default false. */ - blitFrame(source: Phaser.Renderer.WebGL.RenderTarget, target: Phaser.Renderer.WebGL.RenderTarget, brightness?: number, clear?: boolean, clearAlpha?: boolean, eraseMode?: boolean): void; + blitFrame(source: Phaser.Renderer.WebGL.RenderTarget, target: Phaser.Renderer.WebGL.RenderTarget, brightness?: number, clear?: boolean, clearAlpha?: boolean, eraseMode?: boolean, flipY?: boolean): void; /** * Binds the `source` Render Target and then copies a section of it to the `target` Render Target. @@ -81583,8 +94774,10 @@ declare namespace Phaser { * @param minFilter The minFilter mode of the texture when created. 0 is `LINEAR`, 1 is `NEAREST`. Default 0. * @param autoClear Automatically clear this framebuffer when bound? Default true. * @param autoResize Automatically resize this Render Target if the WebGL Renderer resizes? Default false. + * @param addDepthBuffer Add a DEPTH_STENCIL and attachment to this Render Target? Default true. + * @param forceClamp Force the texture to use the CLAMP_TO_EDGE wrap mode, even if a power of two? Default true. */ - constructor(renderer: Phaser.Renderer.WebGL.WebGLRenderer, width: number, height: number, scale?: number, minFilter?: number, autoClear?: boolean, autoResize?: boolean); + constructor(renderer: Phaser.Renderer.WebGL.WebGLRenderer, width: number, height: number, scale?: number, minFilter?: number, autoClear?: boolean, autoResize?: boolean, addDepthBuffer?: boolean, forceClamp?: boolean); /** * A reference to the WebGLRenderer instance. @@ -81643,6 +94836,19 @@ declare namespace Phaser { */ readonly autoResize: boolean; + /** + * Does this Render Target have a Depth Buffer? + */ + readonly hasDepthBuffer: boolean; + + /** + * Force the WebGL Texture to use the CLAMP_TO_EDGE wrap mode, even if a power of two? + * + * If `false` it will use `gl.REPEAT` instead, which may be required for some effects, such + * as using this Render Target as a texture for a Shader. + */ + forceClamp: boolean; + /** * Sets if this Render Target should automatically resize when the WebGL Renderer * emits a resize event. @@ -81701,6 +94907,9 @@ declare namespace Phaser { } + namespace Shaders { + } + namespace Utils { /** * Packs four floats on a range from 0.0 to 1.0 into a single Uint32 @@ -81735,8 +94944,10 @@ declare namespace Phaser { function getFloatsFromUintRGB(rgb: number): any[]; /** - * Check to see how many texture units the GPU supports, based on the given config value. - * Then tests this against the maximum number of iterations GLSL can support. + * Check to see how many texture units the GPU supports in a fragment shader + * and if the value specific in the game config is allowed. + * + * This value is hard-clamped to 16 for performance reasons on Android devices. * @param gl The WebGLContext used to create the shaders. * @param maxTextures The Game Config maxTextures value. */ @@ -81750,6 +94961,16 @@ declare namespace Phaser { */ function parseFragmentShaderMaxTextures(fragmentShaderSource: string, maxTextures: number): string; + /** + * Takes the Glow FX Shader source and parses out the __SIZE__ and __DIST__ + * consts with the configuration values. + * @param shader The Fragment Shader source code to operate on. + * @param game The Phaser Game instance. + * @param quality The quality of the glow (defaults to 0.1) + * @param distance The distance of the glow (defaults to 10) + */ + function setGlowQuality(shader: string, game: Phaser.Game, quality?: number, distance?: number): string; + } /** @@ -81804,7 +95025,7 @@ declare namespace Phaser { * This is initially undefined and only set when this pipeline is added * to the manager. */ - manager: Phaser.Renderer.WebGL.PipelineManager; + manager: Phaser.Renderer.WebGL.PipelineManager | null; /** * The WebGL context this WebGL Pipeline uses. @@ -81854,6 +95075,11 @@ declare namespace Phaser { */ readonly vertexBuffer: WebGLBuffer; + /** + * The currently active WebGLBuffer. + */ + activeBuffer: WebGLBuffer; + /** * The primitive topology which the pipeline will use to submit draw calls. * @@ -81883,13 +95109,6 @@ declare namespace Phaser { */ active: boolean; - /** - * Holds the most recently assigned texture unit. - * - * Treat this value as read-only. - */ - currentUnit: number; - /** * Some pipelines require the forced use of texture zero (like the light pipeline). * @@ -81910,6 +95129,11 @@ declare namespace Phaser { */ readonly isPostFX: boolean; + /** + * Indicates if this is a Pre FX Pipeline, or not. + */ + readonly isPreFX: boolean; + /** * An array of RenderTarget instances that belong to this pipeline. */ @@ -81972,6 +95196,50 @@ declare namespace Phaser { */ glReset: boolean; + /** + * The temporary Pipeline batch. This array contains the batch entries for + * the current frame, which is a package of textures and vertex offsets used + * for drawing. This package is built dynamically as the frame is built + * and cleared during the flush method. + * + * Treat this array and all of its contents as read-only. + */ + batch: Phaser.Types.Renderer.WebGL.WebGLPipelineBatchEntry[]; + + /** + * The most recently created Pipeline batch entry. + * + * Reset to null as part of the flush method. + * + * Treat this value as read-only. + */ + currentBatch: Phaser.Types.Renderer.WebGL.WebGLPipelineBatchEntry | null; + + /** + * The most recently bound WebGLTexture, used as part of the batch process. + * + * Reset to null as part of the flush method. + * + * Treat this value as read-only. + */ + currentTexture: WebGLTexture | null; + + /** + * Holds the most recently assigned texture unit. + * + * Treat this value as read-only. + */ + currentUnit: number; + + /** + * The currently active WebGLTextures, used as part of the batch process. + * + * Reset to empty as part of the bind method. + * + * Treat this array as read-only. + */ + activeTextures: WebGLTexture[]; + /** * Called when the Game has fully booted and the Renderer has finished setting up. * @@ -82001,8 +95269,9 @@ declare namespace Phaser { * Sets the currently active shader within this pipeline. * @param shader The shader to set as being current. * @param setAttributes Should the vertex attribute pointers be set? Default false. + * @param vertexBuffer The vertex buffer to be set before the shader is bound. Defaults to the one owned by this pipeline. */ - setShader(shader: Phaser.Renderer.WebGL.WebGLShader, setAttributes?: boolean): this; + setShader(shader: Phaser.Renderer.WebGL.WebGLShader, setAttributes?: boolean, vertexBuffer?: WebGLBuffer): this; /** * Searches all shaders in this pipeline for one matching the given name, then returns it. @@ -82020,6 +95289,38 @@ declare namespace Phaser { */ setShadersFromConfig(config: Phaser.Types.Renderer.WebGL.WebGLPipelineConfig): this; + /** + * Creates a new WebGL Pipeline Batch Entry, sets the texture unit as zero + * and pushes the entry into the batch. + * @param texture The WebGLTexture assigned to this batch entry. + */ + createBatch(texture: WebGLTexture): number; + + /** + * Adds the given texture to the current WebGL Pipeline Batch Entry and + * increases the batch entry unit and maxUnit values by 1. + * @param texture The WebGLTexture assigned to this batch entry. + */ + addTextureToBatch(texture: WebGLTexture): void; + + /** + * Takes the given WebGLTexture and determines what to do with it. + * + * If there is no current batch (i.e. after a flush) it will create a new + * batch from it. + * + * If the texture is already bound, it will return the current texture unit. + * + * If the texture already exists in the current batch, the unit gets reset + * to match it. + * + * If the texture cannot be found in the current batch, and it supports + * multiple textures, it's added into the batch and the unit indexes are + * advanced. + * @param texture The WebGLTexture assigned to this batch entry. + */ + pushBatch(texture: WebGLTexture): number; + /** * Custom pipelines can use this method in order to perform any required pre-batch tasks * for the given Game Object. It must return the texture unit the Game Object was assigned. @@ -82038,6 +95339,12 @@ declare namespace Phaser { */ shouldFlush(amount?: number): boolean; + /** + * Returns the number of vertices that can be added to the current batch before + * it will trigger a flush to happen. + */ + vertexAvailable(): number; + /** * Resizes the properties used to describe the viewport. * @@ -82057,6 +95364,14 @@ declare namespace Phaser { */ setProjectionMatrix(width: number, height: number): this; + /** + * Adjusts this pipelines ortho Projection Matrix to flip the y + * and bottom values. Call with 'false' as the parameter to flip + * them back again. + * @param flipY Flip the y and bottom values? Default true. + */ + flipProjectionMatrix(flipY?: boolean): void; + /** * Adjusts this pipelines ortho Projection Matrix to match that of the global * WebGL Renderer Projection Matrix. @@ -82088,14 +95403,17 @@ declare namespace Phaser { * * It first checks to see if it's already set as the active buffer and only * binds itself if not. + * @param buffer The Vertex Buffer to be bound. Defaults to the one owned by this pipeline. */ - setVertexBuffer(): boolean; + setVertexBuffer(buffer?: WebGLBuffer): boolean; /** * This method is called as a result of the `WebGLPipeline.batchQuad` method, right before a quad * belonging to a Game Object is about to be added to the batch. When this is called, the * renderer has just performed a flush. It will bind the current render target, if any are set * and finally call the `onPreBatch` hook. + * + * It is also called as part of the `PipelineManager.preBatch` method when processing Post FX Pipelines. * @param gameObject The Game Object or Camera that invoked this pipeline, if any. */ preBatch(gameObject?: Phaser.GameObjects.GameObject | Phaser.Cameras.Scene2D.Camera): this; @@ -82107,12 +95425,14 @@ declare namespace Phaser { * * It calls the `onDraw` hook followed by the `onPostBatch` hook, which can be used to perform * additional Post FX Pipeline processing. + * + * It is also called as part of the `PipelineManager.postBatch` method when processing Post FX Pipelines. * @param gameObject The Game Object or Camera that invoked this pipeline, if any. */ postBatch(gameObject?: Phaser.GameObjects.GameObject | Phaser.Cameras.Scene2D.Camera): this; /** - * This method is only used by Post FX Pipelines and those that extend from them. + * This method is only used by Sprite FX and Post FX Pipelines and those that extend from them. * * This method is called every time the `postBatch` method is called and is passed a * reference to the current render target. @@ -82121,8 +95441,9 @@ declare namespace Phaser { * however, you can do as much additional processing as you like in this method if * you override it from within your own pipelines. * @param renderTarget The Render Target. + * @param swapTarget A Swap Render Target, useful for double-buffer effects. Only set by SpriteFX Pipelines. */ - onDraw(renderTarget: Phaser.Renderer.WebGL.RenderTarget): void; + onDraw(renderTarget: Phaser.Renderer.WebGL.RenderTarget, swapTarget?: Phaser.Renderer.WebGL.RenderTarget): void; /** * This method is called every time the Pipeline Manager deactivates this pipeline, swapping from @@ -82396,8 +95717,23 @@ declare namespace Phaser { * * This can be used for mapping time uniform values, such as `iTime`. * @param name The name of the uniform to set. + * @param shader The shader to set the value on. If not given, the `currentShader` is used. + */ + setTime(name: string, shader?: Phaser.Renderer.WebGL.WebGLShader): this; + + /** + * Sets a boolean uniform value based on the given name on the currently set shader. + * + * The current shader is bound, before the uniform is set, making it active within the + * WebGLRenderer. This means you can safely call this method from a location such as + * a Scene `create` or `update` method. However, when working within a Shader file + * directly, use the `WebGLShader` method equivalent instead, to avoid the program + * being set. + * @param name The name of the uniform to set. + * @param value The new value of the `boolean` uniform. + * @param shader The shader to set the value on. If not given, the `currentShader` is used. */ - setTime(name: string): this; + setBoolean(name: string, value: boolean, shader?: Phaser.Renderer.WebGL.WebGLShader): this; /** * Sets a 1f uniform value based on the given name on the currently set shader. @@ -82674,8 +96010,8 @@ declare namespace Phaser { * directly, use the `WebGLShader` method equivalent instead, to avoid the program * being set. * @param name The name of the uniform to set. - * @param transpose Should the matrix be transpose - * @param matrix Matrix data + * @param transpose Whether to transpose the matrix. Should be `false`. + * @param matrix The matrix data. If using a Matrix4 this should be the `Matrix4.val` property. * @param shader The shader to set the value on. If not given, the `currentShader` is used. */ setMatrix4fv(name: string, transpose: boolean, matrix: Float32Array, shader?: Phaser.Renderer.WebGL.WebGLShader): this; @@ -82703,6 +96039,18 @@ declare namespace Phaser { */ constructor(game: Phaser.Game); + /** + * The currently bound normal map texture at texture unit one, if any. + */ + "currentNormalMap;": WebGLTexture | null; + + /** + * Checks to see if the given diffuse and normal map textures are already bound, or not. + * @param texture The WebGL diffuse texture. + * @param normalMap The WebGL normal map texture. + */ + isNewNormalMap(texture: WebGLTexture, normalMap: WebGLTexture): boolean; + /** * The local configuration settings of this WebGL Renderer. */ @@ -82767,17 +96115,6 @@ declare namespace Phaser { */ snapshotState: Phaser.Types.Renderer.Snapshot.SnapshotState; - /** - * Cached value for the last texture unit that was used. - */ - currentActiveTexture: number; - - /** - * Contains the current starting active texture unit. - * This value is constantly updated and should be treated as read-only by your code. - */ - startActiveTexture: number; - /** * The maximum number of textures the GPU can handle. The minimum under the WebGL1 spec is 8. * This is set via the Game Config `maxTextures` property and should never be changed after boot. @@ -82791,23 +96128,6 @@ declare namespace Phaser { */ textureIndexes: any[]; - /** - * An array of default temporary WebGL Textures. - * - * This array is populated during the init phase and should never be changed after boot. - */ - tempTextures: any[]; - - /** - * The currently bound texture at texture unit zero, if any. - */ - textureZero: WebGLTexture; - - /** - * The currently bound normal map texture at texture unit one, if any. - */ - normalTexture: WebGLTexture; - /** * The currently bound framebuffer in use. */ @@ -82885,11 +96205,15 @@ declare namespace Phaser { /** * Stores the current WebGL component formats for further use. + * + * This array is populated in the `init` method. */ glFormats: any[]; /** - * Stores the supported WebGL texture compression formats. + * Stores the WebGL texture compression formats that this device and browser supports. + * + * Support for using compressed texture formats was added in Phaser version 3.60. */ compression: Phaser.Types.Renderer.WebGL.WebGLTextureCompression; @@ -82964,7 +96288,7 @@ declare namespace Phaser { * * You can specify this as a string in the game config, i.e.: * - * `renderer: { mipmapFilter: 'NEAREST_MIPMAP_LINEAR' }` + * `render: { mipmapFilter: 'NEAREST_MIPMAP_LINEAR' }` * * The 6 options for WebGL1 are, in order from least to most computationally expensive: * @@ -82978,20 +96302,12 @@ declare namespace Phaser { * Mipmaps only work with textures that are fully power-of-two in size. * * For more details see https://webglfundamentals.org/webgl/lessons/webgl-3d-textures.html - */ - mipmapFilter: GLenum; - - /** - * The number of times the renderer had to flush this frame, due to running out of texture units. - */ - textureFlush: number; - - /** - * Are the WebGL Textures in their default state? * - * Used to avoid constant gl binds. + * As of v3.60 no mipmaps will be generated unless a string is given in + * the game config. This saves on VRAM use when it may not be required. + * To obtain the previous result set the property to `LINEAR` in the config. */ - isTextureClean: boolean; + mipmapFilter: GLenum; /** * Has this renderer fully booted yet? @@ -83020,12 +96336,140 @@ declare namespace Phaser { */ projectionHeight: number; + /** + * A RenderTarget used by the BitmapMask Pipeline. + * + * This is the source, i.e. the masked Game Object itself. + */ + maskSource: Phaser.Renderer.WebGL.RenderTarget; + + /** + * A RenderTarget used by the BitmapMask Pipeline. + * + * This is the target, i.e. the framebuffer the masked objects are drawn to. + */ + maskTarget: Phaser.Renderer.WebGL.RenderTarget; + + /** + * An instance of SpectorJS used for WebGL Debugging. + * + * Only available in the Phaser Debug build. + */ + spector: Function; + /** * Creates a new WebGLRenderingContext and initializes all internal state. * @param config The configuration object for the renderer. */ init(config: object): this; + /** + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. + * + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. + * + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method will capture the current WebGL frame and send it to the Spector.js tool for inspection. + * @param quickCapture If `true` thumbnails are not captured in order to speed up the capture. Default false. + * @param fullCapture If `true` all details are captured. Default false. + */ + captureFrame(quickCapture?: boolean, fullCapture?: boolean): void; + + /** + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. + * + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. + * + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method will capture the next WebGL frame and send it to the Spector.js tool for inspection. + */ + captureNextFrame(): void; + + /** + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. + * + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. + * + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method will return the current FPS of the WebGL canvas. + */ + getFps(): number; + + /** + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. + * + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. + * + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method adds a command with the name value in the list. This can be filtered in the search. + * All logs can be filtered searching for "LOG". + * @param arguments The arguments to log to Spector. + */ + log(...arguments: any[]): string; + + /** + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. + * + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. + * + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method will start a capture on the Phaser canvas. The capture will stop once it reaches + * the number of commands specified as a parameter, or after 10 seconds. If quick capture is true, + * the thumbnails are not captured in order to speed up the capture. + * @param commandCount The number of commands to capture. If zero it will capture for 10 seconds. Default 0. + * @param quickCapture If `true` thumbnails are not captured in order to speed up the capture. Default false. + * @param fullCapture If `true` all details are captured. Default false. + */ + startCapture(commandCount?: number, quickCapture?: boolean, fullCapture?: boolean): void; + + /** + * This method is only available in the Debug Build of Phaser, or a build with the + * `WEBGL_DEBUG` flag set in the Webpack Config. + * + * Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector + * that allows for live inspection of your WebGL calls. Although it's easy to add the Spector + * extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile + * browsers too, making it a powerful tool for debugging WebGL games on mobile devices where + * extensions are not permitted. + * + * See https://github.com/BabylonJS/Spector.js for more details. + * + * This method will stop the current capture and returns the result in JSON. It displays the + * result if the UI has been displayed. This returns undefined if the capture has not been completed + * or did not find any commands. + */ + stopCapture(): object; + /** * The event handler that manages the `resize` event dispatched by the Scale Manager. * @param gameSize The default Game Size object. This is the un-modified game dimensions. @@ -83057,6 +96501,28 @@ declare namespace Phaser { */ resize(width?: number, height?: number): this; + /** + * Determines which compressed texture formats this browser and device supports. + * + * Called automatically as part of the WebGL Renderer init process. If you need to investigate + * which formats it supports, see the `Phaser.Renderer.WebGL.WebGLRenderer#compression` property instead. + */ + getCompressedTextures(): Phaser.Types.Renderer.WebGL.WebGLTextureCompression; + + /** + * Returns a compressed texture format GLenum name based on the given format. + * @param baseFormat The Base Format to check. + * @param format An optional GLenum format to check within the base format. + */ + getCompressedTextureName(baseFormat: string, format?: GLenum): string; + + /** + * Checks if the given compressed texture format is supported, or not. + * @param baseFormat The Base Format to check. + * @param format An optional GLenum format to check within the base format. + */ + supportsCompressedTexture(baseFormat: string, format?: GLenum): boolean; + /** * Gets the aspect ratio of the WebGLRenderer dimensions. */ @@ -83075,7 +96541,7 @@ declare namespace Phaser { * This is called during `endCapture`, should the matrix have been changed * as a result of the capture process. */ - resetProjectionMatrix(): void; + resetProjectionMatrix(): this; /** * Checks if a WebGL extension is supported @@ -83169,69 +96635,6 @@ declare namespace Phaser { */ removeBlendMode(index: number): this; - /** - * Activates the Texture Source and assigns it the next available texture unit. - * If none are available, it will flush the current pipeline first. - * @param textureSource The Texture Source to be assigned the texture unit. - */ - setTextureSource(textureSource: Phaser.Textures.TextureSource): number; - - /** - * Checks to see if the given diffuse and normal map textures are already bound, or not. - * @param texture The WebGL diffuse texture. - * @param normalMap The WebGL normal map texture. - */ - isNewNormalMap(texture: WebGLTexture, normalMap: WebGLTexture): boolean; - - /** - * Binds a texture directly to texture unit zero then activates it. - * If the texture is already at unit zero, it skips the bind. - * Make sure to call `clearTextureZero` after using this method. - * @param texture The WebGL texture that needs to be bound. - * @param flush Flush the pipeline if the texture is different? Default false. - */ - setTextureZero(texture: WebGLTexture, flush?: boolean): void; - - /** - * Clears the texture that was directly bound to texture unit zero. - */ - clearTextureZero(): void; - - /** - * Binds a texture directly to texture unit one then activates it. - * If the texture is already at unit one, it skips the bind. - * Make sure to call `clearNormalMap` after using this method. - * @param texture The WebGL texture that needs to be bound. - */ - setNormalMap(texture: WebGLTexture): void; - - /** - * Clears the texture that was directly bound to texture unit one and - * increases the start active texture counter. - */ - clearNormalMap(): void; - - /** - * Activates each texture, in turn, then binds them all to `null`. - * @param all Reset all textures, or just the first two? Default false. - */ - unbindTextures(all?: boolean): void; - - /** - * Flushes the current pipeline, then resets the first two textures - * back to the default temporary textures, resets the start active - * counter and sets texture unit 1 as being active. - * @param all Reset all textures, or just the first two? Default false. - */ - resetTextures(all?: boolean): void; - - /** - * Binds a texture at a texture unit. If a texture is already - * bound to that unit it will force a flush on the current pipeline. - * @param texture The WebGL texture that needs to be bound. - */ - setTexture2D(texture: WebGLTexture): number; - /** * Pushes a new framebuffer onto the FBO stack and makes it the currently bound framebuffer. * @@ -83240,10 +96643,11 @@ declare namespace Phaser { * Call `popFramebuffer` to remove it again. * @param framebuffer The framebuffer that needs to be bound. * @param updateScissor Set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. Default false. - * @param resetTextures Should the WebGL Textures be reset after the new framebuffer is bound? Default false. * @param setViewport Should the WebGL viewport be set? Default true. + * @param texture Bind the given frame buffer texture? Default null. + * @param clear Clear the frame buffer after binding? Default false. */ - pushFramebuffer(framebuffer: WebGLFramebuffer, updateScissor?: boolean, resetTextures?: boolean, setViewport?: boolean): this; + pushFramebuffer(framebuffer: WebGLFramebuffer, updateScissor?: boolean, setViewport?: boolean, texture?: WebGLTexture, clear?: boolean): this; /** * Sets the given framebuffer as the active and currently bound framebuffer. @@ -83253,18 +96657,25 @@ declare namespace Phaser { * Typically, you should call `pushFramebuffer` instead of this method. * @param framebuffer The framebuffer that needs to be bound. * @param updateScissor If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. Default false. - * @param resetTextures Should the WebGL Textures be reset after the new framebuffer is bound? Default false. * @param setViewport Should the WebGL viewport be set? Default true. + * @param texture Bind the given frame buffer texture? Default null. + * @param clear Clear the frame buffer after binding? Default false. */ - setFramebuffer(framebuffer: WebGLFramebuffer, updateScissor?: boolean, resetTextures?: boolean, setViewport?: boolean): this; + setFramebuffer(framebuffer: WebGLFramebuffer, updateScissor?: boolean, setViewport?: boolean, texture?: WebGLTexture, clear?: boolean): this; /** * Pops the previous framebuffer from the fbo stack and sets it. * @param updateScissor If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. Default false. - * @param resetTextures Should the WebGL Textures be reset after the new framebuffer is bound? Default false. * @param setViewport Should the WebGL viewport be set? Default true. */ - popFramebuffer(updateScissor?: boolean, resetTextures?: boolean, setViewport?: boolean): WebGLFramebuffer; + popFramebuffer(updateScissor?: boolean, setViewport?: boolean): WebGLFramebuffer; + + /** + * Restores the previous framebuffer from the fbo stack and sets it. + * @param updateScissor If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack. Default false. + * @param setViewport Should the WebGL viewport be set? Default true. + */ + restoreFramebuffer(updateScissor?: boolean, setViewport?: boolean): void; /** * Binds a shader program. @@ -83289,8 +96700,9 @@ declare namespace Phaser { * @param width The width of the texture. * @param height The height of the texture. * @param scaleMode The scale mode to be used by the texture. + * @param forceClamp Force the texture to use the CLAMP_TO_EDGE wrap mode, even if a power of two? Default false. */ - createTextureFromSource(source: object, width: number, height: number, scaleMode: number): WebGLTexture; + createTextureFromSource(source: object, width: number, height: number, scaleMode: number, forceClamp?: boolean): WebGLTexture | null; /** * A wrapper for creating a WebGLTexture. If no pixel data is passed it will create an empty texture. @@ -83307,7 +96719,7 @@ declare namespace Phaser { * @param forceSize If `true` it will use the width and height passed to this method, regardless of the pixels dimension. Default false. * @param flipY Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. Default false. */ - createTexture2D(mipLevel: number, minFilter: number, magFilter: number, wrapT: number, wrapS: number, format: number, pixels: object, width: number, height: number, pma?: boolean, forceSize?: boolean, flipY?: boolean): WebGLTexture; + createTexture2D(mipLevel: number, minFilter: number, magFilter: number, wrapT: number, wrapS: number, format: number, pixels: object | undefined, width: number, height: number, pma?: boolean, forceSize?: boolean, flipY?: boolean): WebGLTexture; /** * Creates a WebGL Framebuffer object and optionally binds a depth stencil render buffer. @@ -83318,6 +96730,23 @@ declare namespace Phaser { */ createFramebuffer(width: number, height: number, renderTexture: WebGLTexture, addDepthStencilBuffer?: boolean): WebGLFramebuffer; + /** + * Binds necessary resources and renders the mask to a separated framebuffer. + * The framebuffer for the masked object is also bound for further use. + * @param mask The BitmapMask instance that called beginMask. + * @param camera The camera rendering the current mask. + */ + beginBitmapMask(mask: Phaser.Display.Masks.BitmapMask, camera: Phaser.Cameras.Scene2D.Camera): void; + + /** + * Binds necessary resources and renders the mask to a separated framebuffer. + * The framebuffer for the masked object is also bound for further use. + * @param mask The BitmapMask instance that called beginMask. + * @param camera The camera rendering the current mask. + * @param bitmapMaskPipeline The BitmapMask Pipeline instance that is requesting the draw. + */ + drawBitmapMask(mask: Phaser.Display.Masks.BitmapMask, camera: Phaser.Cameras.Scene2D.Camera, bitmapMaskPipeline: Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline): void; + /** * Creates a WebGLProgram instance based on the given vertex and fragment shader source. * @@ -83345,9 +96774,8 @@ declare namespace Phaser { * Calls `GL.deleteTexture` on the given WebGLTexture and also optionally * resets the currently defined textures. * @param texture The WebGL Texture to be deleted. - * @param reset Call the `resetTextures` method after deleting this texture? Default false. */ - deleteTexture(texture: WebGLTexture, reset?: boolean): this; + deleteTexture(texture: WebGLTexture): this; /** * Deletes a WebGLFramebuffer from the GL instance. @@ -83407,6 +96835,18 @@ declare namespace Phaser { */ postRender(): void; + /** + * Disables the STENCIL_TEST but does not change the status + * of the current stencil mask. + */ + clearStencilMask(): void; + + /** + * Restores the current stencil function to the one that was in place + * before `clearStencilMask` was called. + */ + restoreStencilMask(): void; + /** * Schedules a snapshot of the entire game viewport to be taken after the current frame is rendered. * @@ -83437,8 +96877,8 @@ declare namespace Phaser { * It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it, * which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process, * which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game. - * @param x The x coordinate to grab from. - * @param y The y coordinate to grab from. + * @param x The x coordinate to grab from. This is based on the game viewport, not the world. + * @param y The y coordinate to grab from. This is based on the game viewport, not the world. * @param width The width of the area to grab. * @param height The height of the area to grab. * @param callback The Function to invoke after the snapshot image is created. @@ -83458,8 +96898,8 @@ declare namespace Phaser { * Unlike the other two snapshot methods, this one will return a `Color` object containing the color data for * the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute, * using less memory. - * @param x The x coordinate of the pixel to get. - * @param y The y coordinate of the pixel to get. + * @param x The x coordinate of the pixel to get. This is based on the game viewport, not the world. + * @param y The y coordinate of the pixel to get. This is based on the game viewport, not the world. * @param callback The Function to invoke after the snapshot pixel data is extracted. */ snapshotPixel(x: number, y: number, callback: Phaser.Types.Renderer.Snapshot.SnapshotCallback): this; @@ -83478,8 +96918,8 @@ declare namespace Phaser { * @param bufferHeight The height of the framebuffer. * @param callback The Function to invoke after the snapshot image is created. * @param getPixel Grab a single pixel as a Color object, or an area as an Image object? Default false. - * @param x The x coordinate to grab from. Default 0. - * @param y The y coordinate to grab from. Default 0. + * @param x The x coordinate to grab from. This is based on the framebuffer, not the world. Default 0. + * @param y The y coordinate to grab from. This is based on the framebuffer, not the world. Default 0. * @param width The width of the area to grab. Default bufferWidth. * @param height The height of the area to grab. Default bufferHeight. * @param type The format of the image to create, usually `image/png` or `image/jpeg`. Default 'image/png'. @@ -83500,7 +96940,7 @@ declare namespace Phaser { /** * Creates a new WebGL Texture based on the given Canvas Element. - * @param srcCanvas The Canvas to create the WebGL Texture from + * @param srcCanvas The Canvas to create the WebGL Texture from. * @param noRepeat Should this canvas be allowed to set `REPEAT` (such as for Text objects?) Default false. * @param flipY Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`? Default false. */ @@ -83597,6 +97037,16 @@ declare namespace Phaser { */ gl: WebGLRenderingContext; + /** + * The fragment shader source code. + */ + fragSrc: string; + + /** + * The vertex shader source code. + */ + vertSrc: string; + /** * The WebGLProgram created from the vertex and fragment shaders. */ @@ -83778,6 +97228,19 @@ declare namespace Phaser { */ setUniform4(setter: Function, name: string, value1: boolean | number | number[] | Float32Array, value2: boolean | number | number[] | Float32Array, value3: boolean | number | number[] | Float32Array, value4: boolean | number | number[] | Float32Array, skipCheck?: boolean): this; + /** + * Sets a boolean uniform value based on the given name on this shader. + * + * The uniform is only set if the value/s given are different to those previously set. + * + * This method works by first setting this shader as being the current shader within the + * WebGL Renderer, if it isn't already. It also sets this shader as being the current + * one within the pipeline it belongs to. + * @param name The name of the uniform to set. + * @param value The new value of the `boolean` uniform. + */ + setBoolean(name: string, value: boolean): this; + /** * Sets a 1f uniform value based on the given name on this shader. * @@ -84040,6 +97503,25 @@ declare namespace Phaser { */ setMatrix4fv(name: string, transpose: boolean, matrix: Float32Array): this; + /** + * This method will create the Shader Program on the current GL context. + * + * If a program already exists, it will be destroyed and the new one will take its place. + * + * After the program is created the uniforms will be reset and + * this shader will be rebound. + * + * This is a very expensive process and if your shader is referenced elsewhere in + * your game those references may then be lost, so be sure to use this carefully. + * + * However, if you need to update say the fragment shader source, then you can pass + * the new source into this method and it'll rebuild the program using it. If you + * don't want to change the vertex shader src, pass `undefined` as the parameter. + * @param vertSrc The source code of the vertex shader. If not given, uses the source already defined in this Shader. + * @param fragSrc The source code of the fragment shader. If not given, uses the source already defined in this Shader. + */ + createProgram(vertSrc?: string, fragSrc?: string): this; + /** * Removes all external references from this class and deletes the WebGL program from the WebGL context. * @@ -84211,30 +97693,30 @@ declare namespace Phaser { /** * The Scale Manager has successfully entered fullscreen mode. */ - const ENTER_FULLSCREEN: any; + const ENTER_FULLSCREEN: string; /** * The Scale Manager tried to enter fullscreen mode but failed. */ - const FULLSCREEN_FAILED: any; + const FULLSCREEN_FAILED: string; /** * The Scale Manager tried to enter fullscreen mode, but it is unsupported by the browser. */ - const FULLSCREEN_UNSUPPORTED: any; + const FULLSCREEN_UNSUPPORTED: string; /** * The Scale Manager was in fullscreen mode, but has since left, either directly via game code, * or via a user gestured, such as pressing the ESC key. */ - const LEAVE_FULLSCREEN: any; + const LEAVE_FULLSCREEN: string; /** * The Scale Manager Orientation Change Event. * * This event is dispatched whenever the Scale Manager detects an orientation change event from the browser. */ - const ORIENTATION_CHANGE: any; + const ORIENTATION_CHANGE: string; /** * The Scale Manager Resize Event. @@ -84244,7 +97726,7 @@ declare namespace Phaser { * the `width`, `height`, `aspectRatio` and other properties of these components to help with * scaling your own game content. */ - const RESIZE: any; + const RESIZE: string; } @@ -84370,7 +97852,7 @@ declare namespace Phaser { * 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. */ - parent: any; + parent: any | null; /** * Is the parent element the browser window? @@ -84467,7 +97949,7 @@ declare namespace Phaser { /** * The DOM Element which is sent into fullscreen mode. */ - fullscreenTarget: any; + fullscreenTarget: any | null; /** * The dirty state of the Scale Manager. @@ -84509,7 +97991,8 @@ declare namespace Phaser { getParent(config: Phaser.Types.Core.GameConfig): void; /** - * Calculates the size of the parent bounds and updates the `parentSize` component, if the canvas has a dom parent. + * Calculates the size of the parent bounds and updates the `parentSize` + * properties, only if the canvas has a dom parent. */ getParentBounds(): boolean; @@ -84712,6 +98195,13 @@ declare namespace Phaser { */ onFullScreenError(): void; + /** + * Get Rectange of visible area. + * @param camera The camera this viewport is respond upon. + * @param out The Rectangle of visible area. + */ + getViewPort(camera?: Phaser.Cameras.Scene2D.Camera, out?: Phaser.Geom.Rectangle): Phaser.Geom.Rectangle; + /** * 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. @@ -84938,7 +98428,7 @@ declare namespace Phaser { * * Listen for it from a Scene using `this.events.on('addedtoscene', listener)`. */ - const ADDED_TO_SCENE: any; + const ADDED_TO_SCENE: string; /** * The Scene Systems Boot Event. @@ -84947,7 +98437,7 @@ declare namespace Phaser { * * Listen to it from a Scene using `this.events.on('boot', listener)`. */ - const BOOT: any; + const BOOT: string; /** * The Scene Create Event. @@ -84960,7 +98450,7 @@ declare namespace Phaser { * * Listen to it from a Scene using `this.events.on('create', listener)`. */ - const CREATE: any; + const CREATE: string; /** * The Scene Systems Destroy Event. @@ -84971,7 +98461,7 @@ declare namespace Phaser { * * You should destroy any resources that may be in use by your Scene in this event handler. */ - const DESTROY: any; + const DESTROY: string; /** * The Scene Systems Pause Event. @@ -84981,7 +98471,7 @@ declare namespace Phaser { * * Listen to it from a Scene using `this.events.on('pause', listener)`. */ - const PAUSE: any; + const PAUSE: string; /** * The Scene Systems Post Update Event. @@ -85001,7 +98491,7 @@ declare namespace Phaser { * * A Scene will only run its step if it is active. */ - const POST_UPDATE: any; + const POST_UPDATE: string; /** * The Scene Systems Pre-Render Event. @@ -85023,7 +98513,7 @@ declare namespace Phaser { * * This event is dispatched after the Scene Display List is sorted and before the Scene is rendered. */ - const PRE_RENDER: any; + const PRE_RENDER: string; /** * The Scene Systems Pre Update Event. @@ -85043,7 +98533,7 @@ declare namespace Phaser { * * A Scene will only run its step if it is active. */ - const PRE_UPDATE: any; + const PRE_UPDATE: string; /** * The Scene Systems Ready Event. @@ -85054,7 +98544,7 @@ declare namespace Phaser { * * Listen to it from a Scene using `this.events.on('ready', listener)`. */ - const READY: any; + const READY: string; /** * The Game Object Removed from Scene Event. @@ -85063,7 +98553,7 @@ declare namespace Phaser { * * Listen for it from a Scene using `this.events.on('removedfromscene', listener)`. */ - const REMOVED_FROM_SCENE: any; + const REMOVED_FROM_SCENE: string; /** * The Scene Systems Render Event. @@ -85085,7 +98575,7 @@ declare namespace Phaser { * * By the time this event is dispatched, the Scene will have already been rendered. */ - const RENDER: any; + const RENDER: string; /** * The Scene Systems Resume Event. @@ -85095,7 +98585,7 @@ declare namespace Phaser { * * Listen to it from a Scene using `this.events.on('resume', listener)`. */ - const RESUME: any; + const RESUME: string; /** * The Scene Systems Shutdown Event. @@ -85108,7 +98598,7 @@ declare namespace Phaser { * that the Scene may, at any time, become active again. A shutdown Scene is not 'destroyed', it's simply not * currently active. Use the [DESTROY]{@linkcode Phaser.Scenes.Events#event:DESTROY} event to completely clear resources. */ - const SHUTDOWN: any; + const SHUTDOWN: string; /** * The Scene Systems Sleep Event. @@ -85118,7 +98608,7 @@ declare namespace Phaser { * * Listen to it from a Scene using `this.events.on('sleep', listener)`. */ - const SLEEP: any; + const SLEEP: string; /** * The Scene Systems Start Event. @@ -85127,7 +98617,7 @@ declare namespace Phaser { * * Listen to it from a Scene using `this.events.on('start', listener)`. */ - const START: any; + const START: string; /** * The Scene Transition Complete Event. @@ -85147,7 +98637,7 @@ declare namespace Phaser { * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. */ - const TRANSITION_COMPLETE: any; + const TRANSITION_COMPLETE: string; /** * The Scene Transition Init Event. @@ -85167,7 +98657,7 @@ declare namespace Phaser { * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. */ - const TRANSITION_INIT: any; + const TRANSITION_INIT: string; /** * The Scene Transition Out Event. @@ -85184,7 +98674,7 @@ declare namespace Phaser { * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. */ - const TRANSITION_OUT: any; + const TRANSITION_OUT: string; /** * The Scene Transition Start Event. @@ -85207,7 +98697,7 @@ declare namespace Phaser { * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. */ - const TRANSITION_START: any; + const TRANSITION_START: string; /** * The Scene Transition Wake Event. @@ -85225,7 +98715,7 @@ declare namespace Phaser { * 4. [TRANSITION_WAKE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_WAKE} - the Target Scene will emit this event if it was asleep and has been woken-up to be transitioned to. * 5. [TRANSITION_COMPLETE]{@linkcode Phaser.Scenes.Events#event:TRANSITION_COMPLETE} - the Target Scene will emit this event when the transition finishes. */ - const TRANSITION_WAKE: any; + const TRANSITION_WAKE: string; /** * The Scene Systems Update Event. @@ -85236,7 +98726,7 @@ declare namespace Phaser { * * 1. [PRE_UPDATE]{@linkcode Phaser.Scenes.Events#event:PRE_UPDATE} * 2. [UPDATE]{@linkcode Phaser.Scenes.Events#event:UPDATE} - * 3. The `Scene.update` method is called, if it exists + * 3. The `Scene.update` method is called, if it exists and the Scene is in a Running state, otherwise this is skipped. * 4. [POST_UPDATE]{@linkcode Phaser.Scenes.Events#event:POST_UPDATE} * 5. [PRE_RENDER]{@linkcode Phaser.Scenes.Events#event:PRE_RENDER} * 6. [RENDER]{@linkcode Phaser.Scenes.Events#event:RENDER} @@ -85245,7 +98735,7 @@ declare namespace Phaser { * * A Scene will only run its step if it is active. */ - const UPDATE: any; + const UPDATE: string; /** * The Scene Systems Wake Event. @@ -85255,7 +98745,7 @@ declare namespace Phaser { * * Listen to it from a Scene using `this.events.on('wake', listener)`. */ - const WAKE: any; + const WAKE: string; } @@ -85323,6 +98813,14 @@ declare namespace Phaser { */ customViewports: number; + /** + * This system Scene is created during `bootQueue` and is a default + * empty Scene that lives outside of the Scene list, but can be used + * by plugins and managers that need access to a live Scene, without + * being tied to one. + */ + systemScene: Phaser.Scene; + /** * Process the Scene operations queue. */ @@ -85346,7 +98844,7 @@ declare namespace Phaser { * @param autoStart If `true` the Scene will be started immediately after being added. Default false. * @param data Optional data object. This will be set as `Scene.settings.data` and passed to `Scene.init`, and `Scene.create`. */ - add(key: string, sceneConfig: Phaser.Scene | Phaser.Types.Scenes.SettingsConfig | Phaser.Types.Scenes.CreateSceneFromObjectConfig | Function, autoStart?: boolean, data?: object): Phaser.Scene; + add(key: string, sceneConfig: Phaser.Types.Scenes.SceneType, autoStart?: boolean, data?: object): Phaser.Scene | null; /** * Removes a Scene from the SceneManager. @@ -85381,65 +98879,68 @@ declare namespace Phaser { * @param isActive Only include Scene's that are currently active? Default true. * @param inReverse Return the array of Scenes in reverse? Default false. */ - getScenes(isActive?: boolean, inReverse?: boolean): Phaser.Scene[]; + getScenes(isActive?: boolean, inReverse?: boolean): T; /** - * Retrieves a Scene. - * @param key The Scene to retrieve. + * Retrieves a Scene based on the given key. + * + * If an actual Scene is passed to this method, it can be used to check if + * its currently within the Scene Manager, or not. + * @param key The key of the Scene to retrieve. */ - getScene(key: string | Phaser.Scene): Phaser.Scene; + getScene(key: (T|string)): T; /** * Determines whether a Scene is running. * @param key The Scene to check. */ - isActive(key: string | Phaser.Scene): boolean; + isActive(key: (T|string)): boolean; /** * Determines whether a Scene is paused. * @param key The Scene to check. */ - isPaused(key: string | Phaser.Scene): boolean; + isPaused(key: (T|string)): boolean; /** * Determines whether a Scene is visible. * @param key The Scene to check. */ - isVisible(key: string | Phaser.Scene): boolean; + isVisible(key: (T|string)): boolean; /** * Determines whether a Scene is sleeping. * @param key The Scene to check. */ - isSleeping(key: string | Phaser.Scene): boolean; + isSleeping(key: (T|string)): boolean; /** * Pauses the given Scene. * @param key The Scene to pause. * @param data An optional data object that will be passed to the Scene and emitted by its pause event. */ - pause(key: string | Phaser.Scene, data?: object): this; + pause(key: (T|string), data?: object): this; /** * Resumes the given Scene. * @param key The Scene to resume. * @param data An optional data object that will be passed to the Scene and emitted by its resume event. */ - resume(key: string | Phaser.Scene, data?: object): this; + resume(key: (T|string), data?: object): this; /** * Puts the given Scene to sleep. * @param key The Scene to put to sleep. * @param data An optional data object that will be passed to the Scene and emitted by its sleep event. */ - sleep(key: string | Phaser.Scene, data?: object): this; + sleep(key: (T|string), data?: object): this; /** * Awakens the given Scene. * @param key The Scene to wake up. * @param data An optional data object that will be passed to the Scene and emitted by its wake event. */ - wake(key: string | Phaser.Scene, data?: object): this; + wake(key: (T|string), data?: object): this; /** * Runs the given Scene. @@ -85452,40 +98953,42 @@ declare namespace Phaser { * @param key The Scene to run. * @param data A data object that will be passed to the Scene on start, wake, or resume. */ - run(key: string | Phaser.Scene, data?: object): this; + run(key: (T|string), data?: object): this; /** - * Starts the given Scene. + * Starts the given Scene, if it is not starting, loading, or creating. + * + * If the Scene is running, paused, or sleeping, it will be shutdown and then started. * @param key The Scene to start. * @param data Optional data object to pass to `Scene.Settings` and `Scene.init`, and `Scene.create`. */ - start(key: string | Phaser.Scene, data?: object): this; + start(key: (T|string), data?: object): this; /** * Stops the given Scene. * @param key The Scene to stop. * @param data Optional data object to pass to Scene.shutdown. */ - stop(key: string | Phaser.Scene, data?: object): this; + stop(key: (T|string), data?: object): this; /** * Sleeps one one Scene and starts the other. * @param from The Scene to sleep. * @param to The Scene to start. */ - switch(from: string | Phaser.Scene, to: string | Phaser.Scene): this; + switch(from: (T|string), to: (T|string)): this; /** * Retrieves a Scene by numeric index. * @param index The index of the Scene to retrieve. */ - getAt(index: number): Phaser.Scene | undefined; + getAt(index: number): T; /** * Retrieves the numeric index of a Scene. * @param key The key of the Scene. */ - getIndex(key: string | Phaser.Scene): number; + getIndex(key: (T|string)): number; /** * Brings a Scene to the top of the Scenes list. @@ -85493,7 +98996,7 @@ declare namespace Phaser { * This means it will render above all other Scenes. * @param key The Scene to move. */ - bringToTop(key: string | Phaser.Scene): this; + bringToTop(key: (T|string)): this; /** * Sends a Scene to the back of the Scenes list. @@ -85501,19 +99004,19 @@ declare namespace Phaser { * This means it will render below all other Scenes. * @param key The Scene to move. */ - sendToBack(key: string | Phaser.Scene): this; + sendToBack(key: (T|string)): this; /** * Moves a Scene down one position in the Scenes list. * @param key The Scene to move. */ - moveDown(key: string | Phaser.Scene): this; + moveDown(key: (T|string)): this; /** * Moves a Scene up one position in the Scenes list. * @param key The Scene to move. */ - moveUp(key: string | Phaser.Scene): this; + moveUp(key: (T|string)): this; /** * Moves a Scene so it is immediately above another Scene in the Scenes list. @@ -85522,23 +99025,23 @@ declare namespace Phaser { * @param keyA The Scene that Scene B will be moved above. * @param keyB The Scene to be moved. */ - moveAbove(keyA: string | Phaser.Scene, keyB: string | Phaser.Scene): this; + moveAbove(keyA: (T|string), keyB: (T|string)): this; /** * Moves a Scene so it is immediately below another Scene in the Scenes list. * * This means it will render behind the other Scene. - * @param keyA The Scene that Scene B will be moved above. + * @param keyA The Scene that Scene B will be moved below. * @param keyB The Scene to be moved. */ - moveBelow(keyA: string | Phaser.Scene, keyB: string | Phaser.Scene): this; + moveBelow(keyA: (T|string), keyB: (T|string)): this; /** * Swaps the positions of two Scenes in the Scenes list. * @param keyA The first Scene to swap. * @param keyB The second Scene to swap. */ - swapPosition(keyA: string | Phaser.Scene, keyB: string | Phaser.Scene): this; + swapPosition(keyA: (T|string), keyB: (T|string)): this; /** * Dumps debug information about each Scene to the developer console. @@ -85610,21 +99113,23 @@ declare namespace Phaser { * * This will happen at the next Scene Manager update, not immediately. * @param key The Scene to start. - * @param data The Scene data. + * @param data The Scene data. If no value is given it will not overwrite any previous data that may exist. */ - start(key?: string | Phaser.Scene, data?: object): this; + start(key?: (T|string), data?: object): this; /** * Restarts this Scene. * * This will happen at the next Scene Manager update, not immediately. - * @param data The Scene data. + * @param data The Scene data. If no value is given it will not overwrite any previous data that may exist. */ restart(data?: object): this; /** * This will start a transition from the current Scene to the target Scene given. * + * The target Scene cannot be the same as the current Scene. + * * The transition will last for the duration specified in milliseconds. * * You can have the target Scene moved above or below this one in the display list. @@ -85662,7 +99167,7 @@ declare namespace Phaser { * @param autoStart If `true` the Scene will be started immediately after being added. Default false. * @param data Optional data object. This will be set as `Scene.settings.data` and passed to `Scene.init`, and `Scene.create`. */ - add(key: string, sceneConfig: Phaser.Scene | Phaser.Types.Scenes.SettingsConfig | Phaser.Types.Scenes.CreateSceneFromObjectConfig | Function, autoStart?: boolean, data?: object): Phaser.Scene; + add(key: string, sceneConfig: Phaser.Types.Scenes.SceneType, autoStart?: boolean, data?: object): Phaser.Scene | null; /** * Launch the given Scene and run it in parallel with this one. @@ -85671,7 +99176,7 @@ declare namespace Phaser { * @param key The Scene to launch. * @param data The Scene data. */ - launch(key: string | Phaser.Scene, data?: object): this; + launch(key: (T|string), data?: object): this; /** * Runs the given Scene, but does not change the state of this Scene. @@ -85686,7 +99191,7 @@ declare namespace Phaser { * @param key The Scene to run. * @param data A data object that will be passed to the Scene and emitted in its ready, wake, or resume events. */ - run(key: string | Phaser.Scene, data?: object): this; + run(key: (T|string), data?: object): this; /** * Pause the Scene - this stops the update step from happening but it still renders. @@ -85695,7 +99200,7 @@ declare namespace Phaser { * @param key The Scene to pause. * @param data An optional data object that will be passed to the Scene and emitted in its pause event. */ - pause(key?: string | Phaser.Scene, data?: object): this; + pause(key?: (T|string), data?: object): this; /** * Resume the Scene - starts the update loop again. @@ -85704,7 +99209,7 @@ declare namespace Phaser { * @param key The Scene to resume. * @param data An optional data object that will be passed to the Scene and emitted in its resume event. */ - resume(key?: string | Phaser.Scene, data?: object): this; + resume(key?: (T|string), data?: object): this; /** * Makes the Scene sleep (no update, no render) but doesn't shutdown. @@ -85713,7 +99218,7 @@ declare namespace Phaser { * @param key The Scene to put to sleep. * @param data An optional data object that will be passed to the Scene and emitted in its sleep event. */ - sleep(key?: string | Phaser.Scene, data?: object): this; + sleep(key?: (T|string), data?: object): this; /** * Makes the Scene wake-up (starts update and render) @@ -85722,7 +99227,7 @@ declare namespace Phaser { * @param key The Scene to wake up. * @param data An optional data object that will be passed to the Scene and emitted in its wake event. */ - wake(key?: string | Phaser.Scene, data?: object): this; + wake(key?: (T|string), data?: object): this; /** * Makes this Scene sleep then starts the Scene given. @@ -85730,7 +99235,7 @@ declare namespace Phaser { * This will happen at the next Scene Manager update, not immediately. * @param key The Scene to start. */ - switch(key: string | Phaser.Scene): this; + switch(key: (T|string)): this; /** * Shutdown the Scene, clearing display list, timers, etc. @@ -85739,7 +99244,7 @@ declare namespace Phaser { * @param key The Scene to stop. * @param data Optional data object to pass to Scene.Systems.shutdown. */ - stop(key?: string | Phaser.Scene, data?: any): this; + stop(key?: (T|string), data?: any): this; /** * Sets the active state of the given Scene. @@ -85747,38 +99252,38 @@ declare namespace Phaser { * @param key The Scene to set the active state of. * @param data An optional data object that will be passed to the Scene and emitted with its events. */ - setActive(value: boolean, key?: string | Phaser.Scene, data?: object): this; + setActive(value: boolean, key?: (T|string), data?: object): this; /** * Sets the visible state of the given Scene. * @param value The visible value. * @param key The Scene to set the visible state for. */ - setVisible(value: boolean, key?: string | Phaser.Scene): this; + setVisible(value: boolean, key?: (T|string)): this; /** * Checks if the given Scene is sleeping or not? * @param key The Scene to check. */ - isSleeping(key?: string | Phaser.Scene): boolean; + isSleeping(key?: (T|string)): boolean; /** * Checks if the given Scene is running or not? * @param key The Scene to check. */ - isActive(key?: string | Phaser.Scene): boolean; + isActive(key?: (T|string)): boolean; /** * Checks if the given Scene is paused or not? * @param key The Scene to check. */ - isPaused(key?: string | Phaser.Scene): boolean; + isPaused(key?: (T|string)): boolean; /** * Checks if the given Scene is visible or not? * @param key The Scene to check. */ - isVisible(key?: string | Phaser.Scene): boolean; + isVisible(key?: (T|string)): boolean; /** * Swaps the position of two scenes in the Scenes list. @@ -85787,7 +99292,7 @@ declare namespace Phaser { * @param keyA The first Scene to swap. * @param keyB The second Scene to swap. If none is given it defaults to this Scene. */ - swapPosition(keyA: string | Phaser.Scene, keyB?: string | Phaser.Scene): this; + swapPosition(keyA: (T|string), keyB?: (T|string)): this; /** * Swaps the position of two scenes in the Scenes list, so that Scene B is directly above Scene A. @@ -85796,7 +99301,7 @@ declare namespace Phaser { * @param keyA The Scene that Scene B will be moved to be above. * @param keyB The Scene to be moved. If none is given it defaults to this Scene. */ - moveAbove(keyA: string | Phaser.Scene, keyB?: string | Phaser.Scene): this; + moveAbove(keyA: (T|string), keyB?: (T|string)): this; /** * Swaps the position of two scenes in the Scenes list, so that Scene B is directly below Scene A. @@ -85805,7 +99310,7 @@ declare namespace Phaser { * @param keyA The Scene that Scene B will be moved to be below. * @param keyB The Scene to be moved. If none is given it defaults to this Scene. */ - moveBelow(keyA: string | Phaser.Scene, keyB?: string | Phaser.Scene): this; + moveBelow(keyA: (T|string), keyB?: (T|string)): this; /** * Removes a Scene from the SceneManager. @@ -85817,19 +99322,19 @@ declare namespace Phaser { * queue the operation for the next update sequence. * @param key The Scene to be removed. */ - remove(key?: string | Phaser.Scene): this; + remove(key?: (T|string)): this; /** * Moves a Scene up one position in the Scenes list. * @param key The Scene to move. */ - moveUp(key?: string | Phaser.Scene): this; + moveUp(key?: (T|string)): this; /** * Moves a Scene down one position in the Scenes list. * @param key The Scene to move. */ - moveDown(key?: string | Phaser.Scene): this; + moveDown(key?: (T|string)): this; /** * Brings a Scene to the top of the Scenes list. @@ -85837,7 +99342,7 @@ declare namespace Phaser { * This means it will render above all other Scenes. * @param key The Scene to move. */ - bringToTop(key?: string | Phaser.Scene): this; + bringToTop(key?: (T|string)): this; /** * Sends a Scene to the back of the Scenes list. @@ -85845,19 +99350,25 @@ declare namespace Phaser { * This means it will render below all other Scenes. * @param key The Scene to move. */ - sendToBack(key?: string | Phaser.Scene): this; + sendToBack(key?: (T|string)): this; /** * Retrieve a Scene. * @param key The Scene to retrieve. */ - get(key: string | Phaser.Scene): Phaser.Scene; + get(key: (T|string)): T; + + /** + * Return the status of the Scene. + * @param key The Scene to get the status from. + */ + getStatus(key: (T|string)): number; /** * Retrieves the numeric index of a Scene in the Scenes list. * @param key The Scene to get the index of. */ - getIndex(key?: string | Phaser.Scene): number; + getIndex(key?: (T|string)): number; } @@ -86080,7 +99591,8 @@ declare namespace Phaser { /** * Pause this Scene. - * A paused Scene still renders, it just doesn't run ANY of its update handlers or systems. + * + * A paused Scene still renders, it just doesn't run any of its update handlers or systems. * @param data A data object that will be passed in the 'pause' event. */ pause(data?: object): Phaser.Scenes.Systems; @@ -86116,6 +99628,16 @@ declare namespace Phaser { */ getData(): any; + /** + * Returns the current status of this Scene. + */ + getStatus(): number; + + /** + * Can this Scene receive Input events? + */ + canInput(): boolean; + /** * Is this Scene sleeping? */ @@ -86196,9 +99718,9 @@ declare namespace Phaser { class Scene { /** * - * @param config Scene specific configuration settings. + * @param config The scene key or scene specific configuration settings. */ - constructor(config: string | Phaser.Types.Scenes.SettingsConfig); + constructor(config?: string | Phaser.Types.Scenes.SettingsConfig); /** * The Scene Systems. You must never overwrite this property, or all hell will break lose. @@ -86398,6 +99920,11 @@ declare namespace Phaser { */ constructor(manager: Phaser.Sound.BaseSoundManager, key: string, config?: Phaser.Types.Sound.SoundConfig); + /** + * Local reference to the sound manager. + */ + manager: Phaser.Sound.BaseSoundManager; + /** * Asset key for the sound. */ @@ -86442,6 +99969,11 @@ declare namespace Phaser { */ readonly currentMarker: Phaser.Types.Sound.SoundMarker; + /** + * Flag indicating if destroy method was called on this sound. + */ + pendingRemove: boolean; + /** * Adds a marker into the current sound. A marker is represented by name, start time, duration, and optionally config object. * This allows you to bundle multiple sounds together into a single audio file and use markers to jump between them for playback. @@ -86459,10 +99991,11 @@ declare namespace Phaser { * Removes a marker from the sound. * @param markerName The name of the marker to remove. */ - removeMarker(markerName: string): Phaser.Types.Sound.SoundMarker; + removeMarker(markerName: string): Phaser.Types.Sound.SoundMarker | null; /** * 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. * @param markerName If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. Default ''. @@ -86471,12 +100004,16 @@ declare namespace Phaser { play(markerName?: string | Phaser.Types.Sound.SoundConfig, config?: Phaser.Types.Sound.SoundConfig): boolean; /** - * Pauses the sound. + * Pauses the sound. This only works if the sound is currently playing. + * + * You can inspect the `isPlaying` and `isPaused` properties to check the state. */ pause(): boolean; /** - * Resumes the sound. + * Resumes the sound. This only works if the sound is paused and not already playing. + * + * You can inspect the `isPlaying` and `isPaused` properties to check the state. */ resume(): boolean; @@ -86488,24 +100025,24 @@ declare namespace Phaser { /** * Method used internally for applying config values to some of the sound properties. */ - protected applyConfig(): void; + applyConfig(): void; /** * Method used internally for resetting values of some of the config properties. */ - protected resetConfig(): void; + resetConfig(): void; /** * Update method called automatically by sound manager on every game step. * @param time The current timestamp as generated by the Request Animation Frame or SetTimeout. * @param delta The delta time elapsed since the last frame. */ - protected update(time: number, delta: number): void; + update(time: number, delta: number): void; /** * Method used internally to calculate total playback rate of the sound. */ - protected calculateRate(): void; + calculateRate(): void; /** * Destroys this sound and all associated events and marks it for removal from the sound manager. @@ -86557,6 +100094,21 @@ declare namespace Phaser { */ readonly locked: boolean; + /** + * Flag used to track if the game has lost focus. + */ + gameLostFocus: boolean; + + /** + * The Spatial Audio listener position. + * + * Only available with WebAudio. + * + * You can modify the x/y properties of this Vec2 directly to + * adjust the listener position within the game world. + */ + listenerPosition: Phaser.Math.Vector2; + /** * Adds a new sound into the sound manager. * @param key Asset key for the sound. @@ -86571,23 +100123,36 @@ declare namespace Phaser { * @param key Asset key for the sound. * @param config An optional config object containing default sound settings. */ - addAudioSprite(key: string, config?: Phaser.Types.Sound.SoundConfig): Phaser.Sound.HTML5AudioSound | Phaser.Sound.WebAudioSound; + addAudioSprite(key: string, config?: Phaser.Types.Sound.SoundConfig): Phaser.Sound.NoAudioSound | Phaser.Sound.HTML5AudioSound | Phaser.Sound.WebAudioSound; /** - * Gets the first sound in the manager matching the given key, if any. + * Gets the first sound in this Sound Manager that matches the given key. + * If none can be found it returns `null`. * @param key Sound asset key. */ - get(key: string): Phaser.Sound.BaseSound; + get(key: string): T; /** - * Gets any sounds in the manager matching the given key. - * @param key Sound asset key. + * Gets all sounds in this Sound Manager. + * + * You can optionally specify a key, in which case only Sound instances that match the given key + * will be returned. + * @param key Optional asset key. If given, only Sound instances with this key will be returned. + */ + getAll(key?: string): T[]; + + /** + * Returns all sounds from this Sound Manager that are currently + * playing. That is, Sound instances that have their `isPlaying` + * property set to `true`. */ - getAll(key: string): Phaser.Sound.BaseSound[]; + getAllPlaying(): T[]; /** * Adds a new sound to the sound manager and plays it. + * * The sound will be automatically removed (destroyed) once playback ends. + * * This lets you play a new sound on the fly without the need to keep a reference to it. * @param key Asset key for the sound. * @param extra An optional additional object containing settings to be applied to the sound. It could be either config or marker object. @@ -86633,6 +100198,19 @@ declare namespace Phaser { */ resumeAll(): void; + /** + * Sets the X and Y position of the Spatial Audio listener on this Web Audios context. + * + * If you call this method with no parameters it will default to the center-point of + * the game canvas. Depending on the type of game you're making, you may need to call + * this method constantly to reset the listener position as the camera scrolls. + * + * Calling this method does nothing on HTML5Audio. + * @param x The x position of the Spatial Audio listener. + * @param y The y position of the Spatial Audio listener. + */ + setListenerPosition(x?: number, y?: number): void; + /** * Stops all the sounds in the game. */ @@ -86684,7 +100262,7 @@ declare namespace Phaser { * and 2.0 doubles the audios playback speed. * @param value Global playback rate at which all the sounds will be played. */ - setRate(value: number): Phaser.Sound.BaseSoundManager; + setRate(value: number): this; /** * Global playback rate at which all the sounds will be played. @@ -86698,7 +100276,7 @@ declare namespace Phaser { * The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). * @param value The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). */ - setDetune(value: number): Phaser.Sound.BaseSoundManager; + setDetune(value: number): this; /** * Global detuning of all sounds in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29). @@ -86722,7 +100300,7 @@ declare namespace Phaser { * music.play(); * ``` */ - const COMPLETE: any; + const COMPLETE: string; /** * The Audio Data Decoded All Event. @@ -86740,7 +100318,7 @@ declare namespace Phaser { * this.sound.decodeAudio([ audioFiles ]); * ``` */ - const DECODED_ALL: any; + const DECODED_ALL: string; /** * The Audio Data Decoded Event. @@ -86754,7 +100332,7 @@ declare namespace Phaser { * this.sound.decodeAudio(key, audioData); * ``` */ - const DECODED: any; + const DECODED: string; /** * The Sound Destroy Event. @@ -86770,7 +100348,7 @@ declare namespace Phaser { * music.destroy(); * ``` */ - const DESTROY: any; + const DESTROY: string; /** * The Sound Detune Event. @@ -86786,7 +100364,7 @@ declare namespace Phaser { * music.setDetune(200); * ``` */ - const DETUNE: any; + const DETUNE: string; /** * The Sound Manager Global Detune Event. @@ -86797,7 +100375,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.sound.on('rate', listener)`. */ - const GLOBAL_DETUNE: any; + const GLOBAL_DETUNE: string; /** * The Sound Manager Global Mute Event. @@ -86807,7 +100385,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.sound.on('mute', listener)`. */ - const GLOBAL_MUTE: any; + const GLOBAL_MUTE: string; /** * The Sound Manager Global Rate Event. @@ -86818,7 +100396,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.sound.on('rate', listener)`. */ - const GLOBAL_RATE: any; + const GLOBAL_RATE: string; /** * The Sound Manager Global Volume Event. @@ -86828,7 +100406,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.sound.on('volume', listener)`. */ - const GLOBAL_VOLUME: any; + const GLOBAL_VOLUME: string; /** * The Sound Looped Event. @@ -86846,7 +100424,7 @@ declare namespace Phaser { * * This is not to be confused with the [LOOP]{@linkcode Phaser.Sound.Events#event:LOOP} event, which only emits when the loop state of a Sound is changed. */ - const LOOPED: any; + const LOOPED: string; /** * The Sound Loop Event. @@ -86863,7 +100441,7 @@ declare namespace Phaser { * * This is not to be confused with the [LOOPED]{@linkcode Phaser.Sound.Events#event:LOOPED} event, which emits each time a Sound loops during playback. */ - const LOOP: any; + const LOOP: string; /** * The Sound Mute Event. @@ -86879,7 +100457,7 @@ declare namespace Phaser { * music.setMute(true); * ``` */ - const MUTE: any; + const MUTE: string; /** * The Sound Pan Event. @@ -86895,7 +100473,7 @@ declare namespace Phaser { * sound.setPan(0.5); * ``` */ - const PAN: any; + const PAN: string; /** * The Pause All Sounds Event. @@ -86906,7 +100484,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.sound.on('pauseall', listener)`. */ - const PAUSE_ALL: any; + const PAUSE_ALL: string; /** * The Sound Pause Event. @@ -86922,7 +100500,7 @@ declare namespace Phaser { * music.pause(); * ``` */ - const PAUSE: any; + const PAUSE: string; /** * The Sound Play Event. @@ -86937,7 +100515,7 @@ declare namespace Phaser { * music.play(); * ``` */ - const PLAY: any; + const PLAY: string; /** * The Sound Rate Change Event. @@ -86953,7 +100531,7 @@ declare namespace Phaser { * music.setRate(0.5); * ``` */ - const RATE: any; + const RATE: string; /** * The Resume All Sounds Event. @@ -86964,7 +100542,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.sound.on('resumeall', listener)`. */ - const RESUME_ALL: any; + const RESUME_ALL: string; /** * The Sound Resume Event. @@ -86981,7 +100559,7 @@ declare namespace Phaser { * music.resume(); * ``` */ - const RESUME: any; + const RESUME: string; /** * The Sound Seek Event. @@ -86997,7 +100575,7 @@ declare namespace Phaser { * music.setSeek(5000); * ``` */ - const SEEK: any; + const SEEK: string; /** * The Stop All Sounds Event. @@ -87008,7 +100586,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.sound.on('stopall', listener)`. */ - const STOP_ALL: any; + const STOP_ALL: string; /** * The Sound Stop Event. @@ -87024,7 +100602,7 @@ declare namespace Phaser { * music.stop(); * ``` */ - const STOP: any; + const STOP: string; /** * The Sound Manager Unlocked Event. @@ -87035,7 +100613,7 @@ declare namespace Phaser { * * Listen to it from a Scene using: `this.sound.on('unlocked', listener)`. */ - const UNLOCKED: any; + const UNLOCKED: string; /** * The Sound Volume Event. @@ -87051,7 +100629,7 @@ declare namespace Phaser { * music.setVolume(0.5); * ``` */ - const VOLUME: any; + const VOLUME: string; } @@ -87067,10 +100645,40 @@ declare namespace Phaser { */ constructor(manager: Phaser.Sound.HTML5AudioSoundManager, key: string, config?: Phaser.Types.Sound.SoundConfig); + /** + * An array containing all HTML5 Audio tags that could be used for individual + * sound playback. Number of instances depends on the config value passed + * to the `Loader#audio` method call, default is 1. + */ + tags: HTMLAudioElement[]; + + /** + * Reference to an HTML5 Audio tag used for playing sound. + */ + audio: HTMLAudioElement; + + /** + * 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. + */ + startTime: number; + + /** + * Audio tag's playback position recorded on previous + * update method call. Set to 0 if sound is not playing. + */ + previousTime: number; + /** * 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. + * + * If you want to play the same sound simultaneously, then you need to create another instance + * of it and play that Sound. For HTML5 Audio this also requires creating multiple audio instances + * when loading the audio files. * @param markerName If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. Default ''. * @param 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. */ @@ -87091,11 +100699,54 @@ declare namespace Phaser { */ stop(): boolean; + /** + * This method is used internally to pick and play the next available audio tag. + */ + pickAndPlayAudioTag(): boolean; + + /** + * 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. + */ + pickAudioTag(): boolean; + + /** + * Method used for playing audio tag and catching possible exceptions + * thrown from rejected Promise returned from play method call. + */ + playCatchPromise(): void; + + /** + * This method is used internally to stop and release the current audio tag. + */ + stopAndReleaseAudioTag(): void; + + /** + * Method used internally to reset sound state, usually when stopping sound + * or when hijacking audio tag from another sound. + */ + reset(): void; + + /** + * Method used internally by sound manager for pausing sound if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + */ + onBlur(): void; + + /** + * Method used internally by sound manager for resuming sound if + * Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true. + */ + onFocus(): void; + /** * Update method called automatically by sound manager on every game step. * @param time The current timestamp as generated by the Request Animation Frame or SetTimeout. */ - protected update(time: number): void; + update(time: number): void; /** * Calls Phaser.Sound.BaseSound#destroy method @@ -87104,9 +100755,19 @@ declare namespace Phaser { destroy(): void; /** - * Method used internally to calculate total playback rate of the sound. + * This method is used internally to update the mute setting of this sound. + */ + updateMute(): void; + + /** + * This method is used internally to update the volume of this sound. + */ + updateVolume(): void; + + /** + * This method is used internally to update the playback rate of this sound. */ - protected calculateRate(): void; + calculateRate(): void; /** * Boolean indicating whether the sound is muted or not. @@ -87307,7 +100968,7 @@ declare namespace Phaser { * minimal functionality and prevents Phaser projects that use audio from * breaking on devices that don't support any audio playback technologies. */ - class NoAudioSound { + class NoAudioSound extends Phaser.Events.EventEmitter { /** * * @param manager Reference to the current sound manager instance. @@ -87316,6 +100977,116 @@ declare namespace Phaser { */ constructor(manager: Phaser.Sound.NoAudioSoundManager, key: string, config?: Phaser.Types.Sound.SoundConfig); + /** + * Local reference to the sound manager. + */ + manager: Phaser.Sound.BaseSoundManager; + + /** + * Asset key for the sound. + */ + readonly key: string; + + /** + * Flag indicating if sound is currently playing. + */ + readonly isPlaying: boolean; + + /** + * Flag indicating if sound is currently paused. + */ + readonly isPaused: boolean; + + /** + * A property that holds the value of sound's actual playback rate, + * after its rate and detune values has been combined with global + * rate and detune values. + */ + readonly totalRate: number; + + /** + * A value representing the duration, in seconds. + * It could be total sound duration or a marker duration. + */ + readonly duration: number; + + /** + * The total duration of the sound in seconds. + */ + readonly totalDuration: number; + + /** + * A config object used to store default sound settings' values. + * Default values will be set by properties' setters. + */ + config: Phaser.Types.Sound.SoundConfig; + + /** + * Reference to the currently used config. + * It could be default config or marker config. + */ + currentConfig: Phaser.Types.Sound.SoundConfig; + + /** + * Boolean indicating whether the sound is muted or not. + * Gets or sets the muted state of this sound. + */ + mute: boolean; + + /** + * Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume). + */ + volume: number; + + /** + * 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. + */ + rate: number; + + /** + * 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). + */ + detune: number; + + /** + * 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. + */ + seek: number; + + /** + * Flag indicating whether or not the sound or current sound marker will loop. + */ + loop: boolean; + + /** + * 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. + */ + pan: number; + + /** + * Object containing markers definitions. + */ + readonly markers: {[key: string]: Phaser.Types.Sound.SoundMarker}; + + /** + * Currently playing marker. + * 'null' if whole sound is playing. + */ + readonly currentMarker: Phaser.Types.Sound.SoundMarker; + + /** + * Flag indicating if destroy method was called on this sound. + */ + pendingRemove: boolean; + /** * * @param marker Marker object. @@ -87353,6 +101124,76 @@ declare namespace Phaser { */ stop(): boolean; + /** + * Sets the muted state of this Sound. + * @param value `true` to mute this sound, `false` to unmute it. + */ + setMute(value: boolean): this; + + /** + * Sets the volume of this Sound. + * @param value The volume of the sound. + */ + setVolume(value: number): this; + + /** + * 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. + * @param value The playback rate at of this Sound. + */ + setRate(value: number): this; + + /** + * 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). + * @param value The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent). + */ + setDetune(value: number): this; + + /** + * Seeks to a specific point in this sound. + * @param value The point in the sound to seek to. + */ + setSeek(value: number): this; + + /** + * Sets the loop state of this Sound. + * @param value `true` to loop this sound, `false` to not loop it. + */ + setLoop(value: boolean): this; + + /** + * 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. + * @param value The pan of the sound. A value between -1 (full left pan) and 1 (full right pan). + */ + setPan(value: number): this; + + /** + * Method used internally for applying config values to some of the sound properties. + */ + applyConfig(): void; + + /** + * Method used internally for resetting values of some of the config properties. + */ + resetConfig(): void; + + /** + * Update method called automatically by sound manager on every game step. + * @param time The current timestamp as generated by the Request Animation Frame or SetTimeout. + * @param delta The delta time elapsed since the last frame. + */ + update(time: number, delta: number): void; + + /** + * Method used internally to calculate total playback rate of the sound. + */ + calculateRate(): void; + /** * Destroys this sound and all associated events and marks it for removal from the sound manager. */ @@ -87375,6 +101216,146 @@ declare namespace Phaser { */ constructor(game: Phaser.Game); + /** + * Adds a new sound into the sound manager. + * @param key Asset key for the sound. + * @param config An optional config object containing default sound settings. + */ + add(key: string, config?: Phaser.Types.Sound.SoundConfig): Phaser.Sound.NoAudioSound; + + /** + * Adds a new audio sprite sound into the sound manager. + * Audio Sprites are a combination of audio files and a JSON configuration. + * The JSON follows the format of that created by https://github.com/tonistiigi/audiosprite + * @param key Asset key for the sound. + * @param config An optional config object containing default sound settings. + */ + addAudioSprite(key: string, config?: Phaser.Types.Sound.SoundConfig): Phaser.Sound.NoAudioSound; + + /** + * Gets the first sound in the manager matching the given key, if any. + * @param key Sound asset key. + */ + get(key: string): T; + + /** + * Gets any sounds in the manager matching the given key. + * @param key Sound asset key. + */ + getAll(key: string): T[]; + + /** + * This method does nothing but return 'false' for the No Audio Sound Manager, to maintain + * compatibility with the other Sound Managers. + * @param key Asset key for the sound. + * @param extra An optional additional object containing settings to be applied to the sound. It could be either config or marker object. + */ + play(key: string, extra?: Phaser.Types.Sound.SoundConfig | Phaser.Types.Sound.SoundMarker): boolean; + + /** + * This method does nothing but return 'false' for the No Audio Sound Manager, to maintain + * compatibility with the other Sound Managers. + * @param key Asset key for the sound. + * @param spriteName The name of the sound sprite to play. + * @param config An optional config object containing default sound settings. + */ + playAudioSprite(key: string, spriteName: string, config?: Phaser.Types.Sound.SoundConfig): boolean; + + /** + * Removes a sound from the sound manager. + * The removed sound is destroyed before removal. + * @param sound The sound object to remove. + */ + remove(sound: Phaser.Sound.BaseSound): boolean; + + /** + * Removes all sounds from the manager, destroying the sounds. + */ + removeAll(): void; + + /** + * Removes all sounds from the sound manager that have an asset key matching the given value. + * The removed sounds are destroyed before removal. + * @param key The key to match when removing sound objects. + */ + removeByKey(key: string): number; + + /** + * Stops any sounds matching the given key. + * @param key Sound asset key. + */ + stopByKey(key: string): number; + + /** + * Empty function for the No Audio Sound Manager. + */ + onBlur(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + onFocus(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + onGameBlur(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + onGameFocus(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + pauseAll(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + resumeAll(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + stopAll(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + update(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + setRate(): this; + + /** + * Empty function for the No Audio Sound Manager. + */ + setDetune(): this; + + /** + * Empty function for the No Audio Sound Manager. + */ + setMute(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + setVolume(): void; + + /** + * Empty function for the No Audio Sound Manager. + */ + unlock(): void; + + /** + * Destroys all the sounds in the game and all associated events. + */ + destroy(): void; + } /** @@ -87391,7 +101372,7 @@ declare namespace Phaser { class WebAudioSound extends Phaser.Sound.BaseSound { /** * - * @param manager Reference to the current sound manager instance. + * @param manager Reference to the WebAudio Sound Manager that owns this Sound instance. * @param key Asset key for the sound. * @param config An optional config object containing default sound settings. Default {}. */ @@ -87430,6 +101411,51 @@ declare namespace Phaser { */ pannerNode: StereoPannerNode; + /** + * The Stereo Spatial Panner node. + */ + spatialNode: PannerNode; + + /** + * If the Spatial Panner node has been set to track a vector or + * Game Object, this retains a reference to it. + */ + spatialSource: Phaser.Types.Math.Vector2Like; + + /** + * The time at which the sound should have started playback from the beginning. + * + * Treat this property as read-only. + * + * Based on `BaseAudioContext.currentTime` value. + */ + playTime: number; + + /** + * The time at which the sound source should have actually started playback. + * + * Treat this property as read-only. + * + * Based on `BaseAudioContext.currentTime` value. + */ + startTime: number; + + /** + * The time at which the sound loop source should actually start playback. + * + * Based on `BaseAudioContext.currentTime` value. + */ + loopTime: number; + + /** + * An array where we keep track of all rate updates during playback. + * + * Treat this property as read-only. + * + * Array of object types: `{ time: number, rate: number }` + */ + rateUpdates: any[]; + /** * Used for keeping track when sound source playback has ended * so its state can be updated accordingly. @@ -87447,6 +101473,9 @@ declare namespace Phaser { * * 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. + * + * If you want to play the same sound simultaneously, then you need to create another instance + * of it and play that Sound. * @param markerName If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object. Default ''. * @param 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. */ @@ -87467,15 +101496,61 @@ declare namespace Phaser { */ stop(): boolean; + /** + * This method is only used internally and it creates a looping buffer source. + */ + createAndStartLoopBufferSource(): void; + + /** + * This method is only used internally and it creates a buffer source. + */ + createBufferSource(): AudioBufferSourceNode; + + /** + * This method is only used internally and it stops and removes a buffer source. + */ + stopAndRemoveBufferSource(): void; + + /** + * This method is only used internally and it stops and removes a looping buffer source. + */ + stopAndRemoveLoopBufferSource(): void; + /** * Method used internally for applying config values to some of the sound properties. */ - protected applyConfig(): void; + applyConfig(): void; + + /** + * Sets the x position of this Sound in Spatial Audio space. + * + * This only has any effect if the sound was created with a SpatialSoundConfig object. + * + * Also see the `WebAudioSoundManager.setListenerPosition` method. + * + * If you find that the sound becomes too quiet, too quickly, as it moves away from + * the listener, then try different `refDistance` property values when configuring + * the spatial sound. + */ + x: number; + + /** + * Sets the y position of this Sound in Spatial Audio space. + * + * This only has any effect if the sound was created with a SpatialSoundConfig object. + * + * Also see the `WebAudioSoundManager.setListenerPosition` method. + * + * If you find that the sound becomes too quiet, too quickly, as it moves away from + * the listener, then try different `refDistance` property values when configuring + * the spatial sound. + */ + y: number; /** * Update method called automatically by sound manager on every game step. */ - protected update(): void; + update(): void; /** * Calls Phaser.Sound.BaseSound#destroy method @@ -87486,7 +101561,18 @@ declare namespace Phaser { /** * Method used internally to calculate total playback rate of the sound. */ - protected calculateRate(): void; + calculateRate(): void; + + /** + * Method used internally for calculating current playback time of a playing sound. + */ + getCurrentTime(): void; + + /** + * Method used internally for calculating the time + * at witch the loop source should start playing. + */ + getLoopTime(): void; /** * Rate at which this Sound will be played. @@ -87661,6 +101747,19 @@ declare namespace Phaser { */ decodeAudio(audioKey?: Phaser.Types.Sound.DecodeAudioConfig[] | string, audioData?: ArrayBuffer | string): void; + /** + * Sets the X and Y position of the Spatial Audio listener on this Web Audios context. + * + * If you call this method with no parameters it will default to the center-point of + * the game canvas. Depending on the type of game you're making, you may need to call + * this method constantly to reset the listener position as the camera scrolls. + * + * Calling this method does nothing on HTML5Audio. + * @param x The x position of the Spatial Audio listener. + * @param y The y position of the Spatial Audio listener. + */ + setListenerPosition(x?: number, y?: number): void; + /** * Unlocks Web Audio API on the initial input event. * @@ -87682,6 +101781,7 @@ declare namespace Phaser { /** * Update method called on every game step. + * * Removes destroyed sounds and updates every active sound in the game. * @param time The current timestamp as generated by the Request Animation Frame or SetTimeout. * @param delta The delta time elapsed since the last frame. @@ -87725,7 +101825,7 @@ declare namespace Phaser { * * In that instance, listen to this event from within a Scene using: `this.sys.updateList.on('add', listener)`. */ - const PROCESS_QUEUE_ADD: any; + const PROCESS_QUEUE_ADD: string; /** * The Process Queue Remove Event. @@ -87736,7 +101836,7 @@ declare namespace Phaser { * * In that instance, listen to this event from within a Scene using: `this.sys.updateList.on('remove', listener)`. */ - const PROCESS_QUEUE_REMOVE: any; + const PROCESS_QUEUE_REMOVE: string; } @@ -87860,7 +101960,7 @@ declare namespace Phaser { * @param startIndex The first child index to start the search from. * @param endIndex The last child index to search up until. */ - getAll(property?: string, value?: T, startIndex?: number, endIndex?: number): T[]; + getAll(property?: string, value?: any, startIndex?: number, endIndex?: number): T[]; /** * Returns the total number of items in the List which have a property matching the given value. @@ -88151,6 +102251,24 @@ declare namespace Phaser { */ checkQueue: boolean; + /** + * Checks the given item to see if it is already active within this Process Queue. + * @param item The item to check. + */ + isActive(item: T): Phaser.Structs.ProcessQueue; + + /** + * Checks the given item to see if it is already pending addition to this Process Queue. + * @param item The item to check. + */ + isPending(item: T): Phaser.Structs.ProcessQueue; + + /** + * Checks the given item to see if it is already pending destruction from this Process Queue. + * @param item The item to check. + */ + isDestroying(item: T): Phaser.Structs.ProcessQueue; + /** * Adds a new item to the Process Queue. * @@ -88162,7 +102280,7 @@ declare namespace Phaser { /** * Removes an item from the Process Queue. * - * The item is added to the pending destroy and fully removed in the next update. + * The item is added to the 'destroy' list and is fully removed in the next update. * @param item The item to be removed from the queue. */ remove(item: T): Phaser.Structs.ProcessQueue; @@ -88272,7 +102390,12 @@ declare namespace Phaser { /** * Passes each value in this Set to the given callback. + * * For when you absolutely know this Set won't be modified during the iteration. + * + * The callback must return a boolean. If it returns `false` then it will abort + * the Set iteration immediately. If it returns `true`, it will carry on + * iterating the next child in the Set. * @param callback The callback to be invoked and passed each value this Set contains. * @param callbackScope The scope of the callback. */ @@ -88743,8 +102866,9 @@ declare namespace Phaser { * @param x The x coordinate to draw the source at. * @param y The y coordinate to draw the source at. * @param source The element to draw to this canvas. + * @param update Update the internal ImageData buffer and arrays. Default true. */ - draw(x: number, y: number, source: HTMLImageElement | HTMLCanvasElement): Phaser.Textures.CanvasTexture; + draw(x: number, y: number, source: HTMLImageElement | HTMLCanvasElement, update?: boolean): Phaser.Textures.CanvasTexture; /** * Draws the given texture frame to this CanvasTexture, then updates the internal @@ -88753,8 +102877,9 @@ declare namespace Phaser { * @param frame The string-based name, or integer based index, of the Frame to get from the Texture. * @param x The x coordinate to draw the source at. Default 0. * @param y The y coordinate to draw the source at. Default 0. + * @param update Update the internal ImageData buffer and arrays. Default true. */ - drawFrame(key: string, frame?: string | number, x?: number, y?: number): Phaser.Textures.CanvasTexture; + drawFrame(key: string, frame?: string | number, x?: number, y?: number, update?: boolean): Phaser.Textures.CanvasTexture; /** * Sets a pixel in the CanvasTexture to the given color and alpha values. @@ -88853,8 +102978,9 @@ declare namespace Phaser { * @param y The y coordinate of the top-left of the region to clear. Default 0. * @param width The width of the region. * @param height The height of the region. + * @param update Update the internal ImageData buffer and arrays. Default true. */ - clear(x?: number, y?: number, width?: number, height?: number): Phaser.Textures.CanvasTexture; + clear(x?: number, y?: number, width?: number, height?: number, update?: boolean): Phaser.Textures.CanvasTexture; /** * Changes the size of this Canvas Texture. @@ -88884,6 +103010,627 @@ declare namespace Phaser { NEAREST, } + /** + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. + * + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. + * + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. + * + * ```js + * const t = this.textures.addDynamicTexture('player', 64, 128); + * // draw objects to t + * this.add.sprite(x, y, 'player'); + * ``` + * + * Because this is a standard Texture within Phaser, you can add frames to it, meaning you can use it + * to generate sprite sheets, texture atlases or tile sets. + * + * Under WebGL1, a FrameBuffer, which is what this Dynamic Texture uses internally, cannot be anti-aliased. + * This means that when drawing objects such as Shapes or Graphics instances to this texture, they may appear + * to be drawn with no aliasing around the edges. This is a technical limitation of WebGL1. To get around it, + * create your shape as a texture in an art package, then draw that to this texture. + * + * Based on the assumption that you will be using this Dynamic Texture as a source for Sprites, it will + * automatically invert any drawing done to it on the y axis. If you do not require this, please call the + * `setIsSpriteTexture()` method and pass it `false` as its parameter. Do this before you start drawing + * to this texture, otherwise you will get vertically inverted frames under WebGL. This isn't required + * for Canvas. + */ + class DynamicTexture extends Phaser.Textures.Texture { + /** + * + * @param manager A reference to the Texture Manager this Texture belongs to. + * @param key The unique string-based key of this Texture. + * @param width The width of this Dymamic Texture in pixels. Defaults to 256 x 256. Default 256. + * @param height The height of this Dymamic Texture in pixels. Defaults to 256 x 256. Default 256. + */ + constructor(manager: Phaser.Textures.TextureManager, key: string, width?: number, height?: number); + + /** + * The internal data type of this object. + */ + readonly type: string; + + /** + * A reference to either the Canvas or WebGL Renderer that the Game instance is using. + */ + renderer: Phaser.Renderer.Canvas.CanvasRenderer | Phaser.Renderer.WebGL.WebGLRenderer; + + /** + * This flag is set to 'true' during `beginDraw` and reset to 'false` in `endDraw`, + * allowing you to determine if this Dynamic Texture is batch drawing, or not. + */ + readonly isDrawing: boolean; + + /** + * A reference to the Rendering Context belonging to the Canvas Element this Dynamic Texture is drawing to. + */ + canvas: HTMLCanvasElement; + + /** + * The 2D Canvas Rendering Context. + */ + readonly context: CanvasRenderingContext2D; + + /** + * Is this Dynamic Texture dirty or not? If not it won't spend time clearing or filling itself. + */ + dirty: boolean; + + /** + * Is this Dynamic Texture being used as the base texture for a Sprite Game Object? + * + * This is enabled by default, as we expect that will be the core use for Dynamic Textures. + * + * However, to disable it, call `RenderTexture.setIsSpriteTexture(false)`. + * + * You should do this _before_ drawing to this texture, so that it correctly + * inverses the frames for WebGL rendering. Not doing so will result in vertically flipped frames. + * + * This property is used in the `endDraw` method. + */ + isSpriteTexture: boolean; + + /** + * An internal Camera that can be used to move around this Dynamic Texture. + * + * Control it just like you would any Scene Camera. The difference is that it only impacts + * the placement of **Game Objects** (not textures) that you then draw to this texture. + * + * You can scroll, zoom and rotate this Camera. + */ + camera: Phaser.Cameras.Scene2D.BaseCamera; + + /** + * The Render Target that belongs to this Dynamic Texture. + * + * A Render Target encapsulates a framebuffer and texture for the WebGL Renderer. + * + * This property remains `null` under Canvas. + */ + renderTarget: Phaser.Renderer.WebGL.RenderTarget; + + /** + * A reference to the WebGL Single Pipeline. + * + * This property remains `null` under Canvas. + */ + pipeline: Phaser.Renderer.WebGL.Pipelines.SinglePipeline; + + /** + * Resizes this Dynamic Texture to the new dimensions given. + * + * In WebGL it will destroy and then re-create the frame buffer being used by this Dynamic Texture. + * In Canvas it will resize the underlying canvas DOM element. + * + * Both approaches will erase everything currently drawn to this texture. + * + * If the dimensions given are the same as those already being used, calling this method will do nothing. + * @param width The new width of this Dynamic Texture. + * @param height The new height of this Dynamic Texture. If not specified, will be set the same as the `width`. Default width. + */ + setSize(width: number, height?: number): this; + + /** + * If you are planning on using this Render Texture as a base texture for Sprite + * Game Objects, then you should call this method with a value of `true` before + * drawing anything to it, otherwise you will get inverted frames in WebGL. + * @param value Is this Render Target being used as a Sprite Texture, or not? + */ + setIsSpriteTexture(value: boolean): this; + + /** + * Fills this Dynamic Texture with the given color. + * + * By default it will fill the entire texture, however you can set it to fill a specific + * rectangular area by using the x, y, width and height arguments. + * + * The color should be given in hex format, i.e. 0xff0000 for red, 0x00ff00 for green, etc. + * @param rgb The color to fill this Dynamic Texture with, such as 0xff0000 for red. + * @param alpha The alpha value used by the fill. Default 1. + * @param x The left coordinate of the fill rectangle. Default 0. + * @param y The top coordinate of the fill rectangle. Default 0. + * @param width The width of the fill rectangle. Default this.width. + * @param height The height of the fill rectangle. Default this.height. + */ + fill(rgb: number, alpha?: number, x?: number, y?: number, width?: number, height?: number): this; + + /** + * Fully clears this Dynamic Texture, erasing everything from it and resetting it back to + * a blank, transparent, texture. + */ + clear(): this; + + /** + * Takes the given texture key and frame and then stamps it at the given + * x and y coordinates. You can use the optional 'config' argument to provide + * lots more options about how the stamp is applied, including the alpha, + * tint, angle, scale and origin. + * + * By default, the frame will stamp on the x/y coordinates based on its center. + * + * If you wish to stamp from the top-left, set the config `originX` and + * `originY` properties both to zero. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param x The x position to draw the frame at. Default 0. + * @param y The y position to draw the frame at. Default 0. + * @param config The stamp configuration object, allowing you to set the alpha, tint, angle, scale and origin of the stamp. + */ + stamp(key: string, frame?: string | number, x?: number, y?: number, config?: Phaser.Types.Textures.StampConfig): this; + + /** + * Draws the given object, or an array of objects, to this Dynamic Texture using a blend mode of ERASE. + * This has the effect of erasing any filled pixels present in the objects from this texture. + * + * It can accept any of the following: + * + * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. + * * Tilemap Layers. + * * A Group. The contents of which will be iterated and drawn in turn. + * * A Container. The contents of which will be iterated fully, and drawn in turn. + * * A Scene Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture, or a Render Texture. + * * A Texture Frame instance. + * * A string. This is used to look-up the texture from the Texture Manager. + * + * Note: You cannot erase a Dynamic Texture from itself. + * + * If passing in a Group or Container it will only draw children that return `true` + * when their `willRender()` method is called. I.e. a Container with 10 children, + * 5 of which have `visible=false` will only draw the 5 visible ones. + * + * If passing in an array of Game Objects it will draw them all, regardless if + * they pass a `willRender` check or not. + * + * You can pass in a string in which case it will look for a texture in the Texture + * Manager matching that string, and draw the base frame. + * + * You can pass in the `x` and `y` coordinates to draw the objects at. The use of + * the coordinates differ based on what objects are being drawn. If the object is + * a Group, Container or Display List, the coordinates are _added_ to the positions + * of the children. For all other types of object, the coordinates are exact. + * + * Calling this method causes the WebGL batch to flush, so it can write the texture + * data to the framebuffer being used internally. The batch is flushed at the end, + * after the entries have been iterated. So if you've a bunch of objects to draw, + * try and pass them in an array in one single call, rather than making lots of + * separate calls. + * + * If you are not planning on using this Dynamic Texture as a base texture for Sprite + * Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before + * calling this method, otherwise you will get vertically inverted frames in WebGL. + * @param entries Any renderable Game Object, or Group, Container, Display List, Render Texture, Texture Frame, or an array of any of these. + * @param x The x position to draw the Frame at, or the offset applied to the object. Default 0. + * @param y The y position to draw the Frame at, or the offset applied to the object. Default 0. + */ + erase(entries: any, x?: number, y?: number): this; + + /** + * Draws the given object, or an array of objects, to this Dynamic Texture. + * + * It can accept any of the following: + * + * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. + * * Tilemap Layers. + * * A Group. The contents of which will be iterated and drawn in turn. + * * A Container. The contents of which will be iterated fully, and drawn in turn. + * * A Scene Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture, or a Render Texture. + * * A Texture Frame instance. + * * A string. This is used to look-up the texture from the Texture Manager. + * + * Note 1: You cannot draw a Dynamic Texture to itself. + * + * Note 2: For Game Objects that have Post FX Pipelines, the pipeline _cannot_ be + * used when drawn to this texture. + * + * If passing in a Group or Container it will only draw children that return `true` + * when their `willRender()` method is called. I.e. a Container with 10 children, + * 5 of which have `visible=false` will only draw the 5 visible ones. + * + * If passing in an array of Game Objects it will draw them all, regardless if + * they pass a `willRender` check or not. + * + * You can pass in a string in which case it will look for a texture in the Texture + * Manager matching that string, and draw the base frame. If you need to specify + * exactly which frame to draw then use the method `drawFrame` instead. + * + * You can pass in the `x` and `y` coordinates to draw the objects at. The use of + * the coordinates differ based on what objects are being drawn. If the object is + * a Group, Container or Display List, the coordinates are _added_ to the positions + * of the children. For all other types of object, the coordinates are exact. + * + * The `alpha` and `tint` values are only used by Texture Frames. + * Game Objects use their own alpha and tint values when being drawn. + * + * Calling this method causes the WebGL batch to flush, so it can write the texture + * data to the framebuffer being used internally. The batch is flushed at the end, + * after the entries have been iterated. So if you've a bunch of objects to draw, + * try and pass them in an array in one single call, rather than making lots of + * separate calls. + * + * If you are not planning on using this Dynamic Texture as a base texture for Sprite + * Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before + * calling this method, otherwise you will get vertically inverted frames in WebGL. + * @param entries Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these. + * @param x The x position to draw the Frame at, or the offset applied to the object. Default 0. + * @param y The y position to draw the Frame at, or the offset applied to the object. Default 0. + * @param alpha The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. Default 1. + * @param tint The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. Default 0xffffff. + */ + draw(entries: any, x?: number, y?: number, alpha?: number, tint?: number): this; + + /** + * Draws the Texture Frame to the Render Texture at the given position. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * + * ```javascript + * var rt = this.add.renderTexture(0, 0, 800, 600); + * rt.drawFrame(key, frame); + * ``` + * + * You can optionally provide a position, alpha and tint value to apply to the frame + * before it is drawn. + * + * Calling this method will cause a batch flush, so if you've got a stack of things to draw + * in a tight loop, try using the `draw` method instead. + * + * If you need to draw a Sprite to this Render Texture, use the `draw` method instead. + * + * If you are not planning on using this Dynamic Texture as a base texture for Sprite + * Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before + * calling this method, otherwise you will get vertically inverted frames in WebGL. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param x The x position to draw the frame at. Default 0. + * @param y The y position to draw the frame at. Default 0. + * @param alpha The alpha value. Only used when drawing Texture Frames to this texture. Default 1. + * @param tint The tint color value. Only used when drawing Texture Frames to this texture. WebGL only. Default 0xffffff. + */ + drawFrame(key: string, frame?: string | number, x?: number, y?: number, alpha?: number, tint?: number): this; + + /** + * Takes the given Texture Frame and draws it to this Dynamic Texture as a fill pattern, + * i.e. in a grid-layout based on the frame dimensions. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * + * You can optionally provide a position, width, height, alpha and tint value to apply to + * the frames before they are drawn. The position controls the top-left where the repeating + * fill will start from. The width and height control the size of the filled area. + * + * The position can be negative if required, but the dimensions cannot. + * + * Calling this method will cause a batch flush by default. Use the `skipBatch` argument + * to disable this if this call is part of a larger batch draw. + * + * If you are not planning on using this Dynamic Texture as a base texture for Sprite + * Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before + * calling this method, otherwise you will get vertically inverted frames in WebGL. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. Set to `null` to skip this argument if not required. + * @param x The x position to start drawing the frames from (can be negative to offset). Default 0. + * @param y The y position to start drawing the frames from (can be negative to offset). Default 0. + * @param width The width of the area to repeat the frame within. Defaults to the width of this Dynamic Texture. Default this.width. + * @param height The height of the area to repeat the frame within. Defaults to the height of this Dynamic Texture. Default this.height. + * @param alpha The alpha to use. Defaults to 1, no alpha. Default 1. + * @param tint WebGL only. The tint color to use. Leave as undefined, or 0xffffff to have no tint. Default 0xffffff. + * @param skipBatch Skip beginning and ending a batch with this call. Use if this is part of a bigger batched draw. Default false. + */ + repeat(key: string, frame?: string | number, x?: number, y?: number, width?: number, height?: number, alpha?: number, tint?: number, skipBatch?: boolean): this; + + /** + * Use this method if you need to batch draw a large number of Game Objects to + * this Dynamic Texture in a single pass, or on a frequent basis. This is especially + * useful under WebGL, however, if your game is using Canvas only, it will not make + * any speed difference in that situation. + * + * This method starts the beginning of a batched draw, unless one is already open. + * + * Batched drawing is faster than calling `draw` in loop, but you must be careful + * to manage the flow of code and remember to call `endDraw()` when you're finished. + * + * If you don't need to draw large numbers of objects it's much safer and easier + * to use the `draw` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * DynamicTexture.beginDraw(); + * + * // repeat n times: + * DynamicTexture.batchDraw(); + * // or + * DynamicTexture.batchDrawFrame(); + * + * // Call once: + * DynamicTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Dynamic Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + */ + beginDraw(): this; + + /** + * Use this method if you have already called `beginDraw` and need to batch + * draw a large number of objects to this Dynamic Texture. + * + * This method batches the drawing of the given objects to this texture, + * without causing a WebGL bind or batch flush for each one. + * + * It is faster than calling `draw`, but you must be careful to manage the + * flow of code and remember to call `endDraw()`. If you don't need to draw large + * numbers of objects it's much safer and easier to use the `draw` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * DynamicTexture.beginDraw(); + * + * // repeat n times: + * DynamicTexture.batchDraw(); + * // or + * DynamicTexture.batchDrawFrame(); + * + * // Call once: + * DynamicTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Dynamic Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * This method can accept any of the following: + * + * * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite. + * * Tilemap Layers. + * * A Group. The contents of which will be iterated and drawn in turn. + * * A Container. The contents of which will be iterated fully, and drawn in turn. + * * A Scene's Display List. Pass in `Scene.children` to draw the whole list. + * * Another Dynamic Texture or Render Texture. + * * A Texture Frame instance. + * * A string. This is used to look-up a texture from the Texture Manager. + * + * Note: You cannot draw a Dynamic Texture to itself. + * + * If passing in a Group or Container it will only draw children that return `true` + * when their `willRender()` method is called. I.e. a Container with 10 children, + * 5 of which have `visible=false` will only draw the 5 visible ones. + * + * If passing in an array of Game Objects it will draw them all, regardless if + * they pass a `willRender` check or not. + * + * You can pass in a string in which case it will look for a texture in the Texture + * Manager matching that string, and draw the base frame. If you need to specify + * exactly which frame to draw then use the method `drawFrame` instead. + * + * You can pass in the `x` and `y` coordinates to draw the objects at. The use of + * the coordinates differ based on what objects are being drawn. If the object is + * a Group, Container or Display List, the coordinates are _added_ to the positions + * of the children. For all other types of object, the coordinates are exact. + * + * The `alpha` and `tint` values are only used by Texture Frames. + * Game Objects use their own alpha and tint values when being drawn. + * @param entries Any renderable Game Object, or Group, Container, Display List, other Dynamic or Texture, Texture Frame or an array of any of these. + * @param x The x position to draw the Frame at, or the offset applied to the object. Default 0. + * @param y The y position to draw the Frame at, or the offset applied to the object. Default 0. + * @param alpha The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. Default 1. + * @param tint The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. Default 0xffffff. + */ + batchDraw(entries: any, x?: number, y?: number, alpha?: number, tint?: number): this; + + /** + * Use this method if you have already called `beginDraw` and need to batch + * draw a large number of texture frames to this Dynamic Texture. + * + * This method batches the drawing of the given frames to this Dynamic Texture, + * without causing a WebGL bind or batch flush for each one. + * + * It is faster than calling `drawFrame`, but you must be careful to manage the + * flow of code and remember to call `endDraw()`. If you don't need to draw large + * numbers of frames it's much safer and easier to use the `drawFrame` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * DynamicTexture.beginDraw(); + * + * // repeat n times: + * DynamicTexture.batchDraw(); + * // or + * DynamicTexture.batchDrawFrame(); + * + * // Call once: + * DynamicTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Dynamic Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * + * Textures are referenced by their string-based keys, as stored in the Texture Manager. + * + * You can optionally provide a position, alpha and tint value to apply to the frame + * before it is drawn. + * @param key The key of the texture to be used, as stored in the Texture Manager. + * @param frame The name or index of the frame within the Texture. + * @param x The x position to draw the frame at. Default 0. + * @param y The y position to draw the frame at. Default 0. + * @param alpha The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha. Default 1. + * @param tint The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only. Default 0xffffff. + */ + batchDrawFrame(key: string, frame?: string | number, x?: number, y?: number, alpha?: number, tint?: number): this; + + /** + * Use this method to finish batch drawing to this Dynamic Texture. + * + * Doing so will stop the WebGL Renderer from capturing draws and then blit the + * framebuffer to the Render Target owned by this texture. + * + * Calling this method without first calling `beginDraw` will have no effect. + * + * Batch drawing is faster than calling `draw`, but you must be careful to manage the + * flow of code and remember to call `endDraw()` when you're finished. + * + * If you don't need to draw large numbers of objects it's much safer and easier + * to use the `draw` method instead. + * + * The flow should be: + * + * ```javascript + * // Call once: + * DynamicTexture.beginDraw(); + * + * // repeat n times: + * DynamicTexture.batchDraw(); + * // or + * DynamicTexture.batchDrawFrame(); + * + * // Call once: + * DynamicTexture.endDraw(); + * ``` + * + * Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you + * have started a batch. Also, be very careful not to destroy this Dynamic Texture while the + * batch is still open. Doing so will cause a run-time error in the WebGL Renderer. + * + * You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is + * currently open, or not. + * @param erase Draws all objects in this batch using a blend mode of ERASE. This has the effect of erasing any filled pixels in the objects being drawn. Default false. + */ + endDraw(erase?: boolean): this; + + /** + * Takes a snapshot of the given area of this Dynamic Texture. + * + * The snapshot is taken immediately, but the results are returned via the given callback. + * + * To capture the whole Dynamic Texture see the `snapshot` method. + * To capture just a specific pixel, see the `snapshotPixel` method. + * + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer + * into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally + * creating an Image object from it, which is the image returned to the callback provided. + * + * All in all, this is a computationally expensive and blocking process, which gets more expensive + * the larger the resolution this Dynamic Texture has, so please be careful how you employ this in your game. + * @param x The x coordinate to grab from. + * @param y The y coordinate to grab from. + * @param width The width of the area to grab. + * @param height The height of the area to grab. + * @param callback The Function to invoke after the snapshot image is created. + * @param type The format of the image to create, usually `image/png` or `image/jpeg`. Default 'image/png'. + * @param encoderOptions The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. Default 0.92. + */ + snapshotArea(x: number, y: number, width: number, height: number, callback: Phaser.Types.Renderer.Snapshot.SnapshotCallback, type?: string, encoderOptions?: number): this; + + /** + * Takes a snapshot of the whole of this Dynamic Texture. + * + * The snapshot is taken immediately, but the results are returned via the given callback. + * + * To capture a portion of this Dynamic Texture see the `snapshotArea` method. + * To capture just a specific pixel, see the `snapshotPixel` method. + * + * Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer + * into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally + * creating an Image object from it, which is the image returned to the callback provided. + * + * All in all, this is a computationally expensive and blocking process, which gets more expensive + * the larger the resolution this Dynamic Texture has, so please be careful how you employ this in your game. + * @param callback The Function to invoke after the snapshot image is created. + * @param type The format of the image to create, usually `image/png` or `image/jpeg`. Default 'image/png'. + * @param encoderOptions The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`. Default 0.92. + */ + snapshot(callback: Phaser.Types.Renderer.Snapshot.SnapshotCallback, type?: string, encoderOptions?: number): this; + + /** + * Takes a snapshot of the given pixel from this Dynamic Texture. + * + * The snapshot is taken immediately, but the results are returned via the given callback. + * + * To capture the whole Dynamic Texture see the `snapshot` method. + * To capture a portion of this Dynamic Texture see the `snapshotArea` method. + * + * Unlike the two other snapshot methods, this one will send your callback a `Color` object + * containing the color data for the requested pixel. It doesn't need to create an internal + * Canvas or Image object, so is a lot faster to execute, using less memory than the other snapshot methods. + * @param x The x coordinate of the pixel to get. + * @param y The y coordinate of the pixel to get. + * @param callback The Function to invoke after the snapshot pixel data is extracted. + */ + snapshotPixel(x: number, y: number, callback: Phaser.Types.Renderer.Snapshot.SnapshotCallback): this; + + /** + * Returns the underlying WebGLTexture, if not running in Canvas mode. + */ + getWebGLTexture(): WebGLTexture | null; + + /** + * Renders this Dynamic Texture onto the Stamp Game Object as a BitmapMask. + * @param renderer A reference to the current active WebGL renderer. + * @param src The Game Object being rendered in this call. + * @param camera The Camera that is rendering the Game Object. + * @param parentMatrix This transform matrix is defined if the game object is nested + */ + renderWebGL(renderer: Phaser.Renderer.WebGL.WebGLRenderer, src: Phaser.GameObjects.Image, camera: Phaser.Cameras.Scene2D.Camera, parentMatrix: Phaser.GameObjects.Components.TransformMatrix): void; + + /** + * This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer. + * @param renderer The Canvas Renderer which would be rendered to. + * @param mask The masked Game Object which would be rendered. + * @param camera The Camera to render to. + */ + renderCanvas(renderer: Phaser.Renderer.Canvas.CanvasRenderer | Phaser.Renderer.WebGL.WebGLRenderer, mask: Phaser.GameObjects.GameObject, camera: Phaser.Cameras.Scene2D.Camera): void; + + /** + * Internal destroy handler, called as part of the destroy process. + */ + protected preDestroy(): void; + + } + namespace Events { /** * The Texture Add Event. @@ -88892,7 +103639,16 @@ declare namespace Phaser { * * Listen to this event from within a Scene using: `this.textures.on('addtexture', listener)`. */ - const ADD: any; + const ADD: string; + + /** + * The Texture Add Key Event. + * + * This event is dispatched by the Texture Manager when a texture with the given key is added to it. + * + * Listen to this event from within a Scene using: `this.textures.on('addtexture-key', listener)`. + */ + const ADD_KEY: string; /** * The Texture Load Error Event. @@ -88902,7 +103658,7 @@ declare namespace Phaser { * * Listen to this event from within a Scene using: `this.textures.on('onerror', listener)`. */ - const ERROR: any; + const ERROR: string; /** * The Texture Load Event. @@ -88914,7 +103670,7 @@ declare namespace Phaser { * * This event is dispatched after the [ADD]{@linkcode Phaser.Textures.Events#event:ADD} event. */ - const LOAD: any; + const LOAD: string; /** * This internal event signifies that the Texture Manager is now ready and the Game can continue booting. @@ -88923,7 +103679,7 @@ declare namespace Phaser { * async events before it's fully ready to carry on. When those complete the Texture Manager emits this event via the Game * instance, which tells the Game to carry on booting. */ - const READY: any; + const READY: string; /** * The Texture Remove Event. @@ -88935,7 +103691,19 @@ declare namespace Phaser { * If you have any Game Objects still using the removed texture, they will start throwing * errors the next time they try to render. Be sure to clear all use of the texture in this event handler. */ - const REMOVE: any; + const REMOVE: string; + + /** + * The Texture Remove Key Event. + * + * This event is dispatched by the Texture Manager when a texture with the given key is removed from it. + * + * Listen to this event from within a Scene using: `this.textures.on('removetexture-key', listener)`. + * + * If you have any Game Objects still using the removed texture, they will start throwing + * errors the next time they try to render. Be sure to clear all use of the texture in this event handler. + */ + const REMOVE_KEY: string; } @@ -88979,7 +103747,7 @@ declare namespace Phaser { /** * A reference to the Texture Source WebGL Texture that this Frame is using. */ - glTexture: WebGLTexture; + glTexture: WebGLTexture | null; /** * X position within the source image to cut from. @@ -89110,7 +103878,7 @@ declare namespace Phaser { * @param x The x coordinate of the top-left of this Frame. Default 0. * @param y The y coordinate of the top-left of this Frame. Default 0. */ - setSize(width: number, height: number, x?: number, y?: number): Phaser.Textures.Frame; + setSize(width: number, height: number, x?: number, y?: number): this; /** * If the frame was trimmed when added to the Texture Atlas, this records the trim and source data. @@ -89121,7 +103889,7 @@ declare namespace Phaser { * @param destWidth The destination width of the trimmed frame for display. * @param destHeight The destination height of the trimmed frame for display. */ - setTrim(actualWidth: number, actualHeight: number, destX: number, destY: number, destWidth: number, destHeight: number): Phaser.Textures.Frame; + setTrim(actualWidth: number, actualHeight: number, destX: number, destY: number, destWidth: number, destHeight: number): this; /** * Takes a crop data object and, based on the rectangular region given, calculates the @@ -89160,17 +103928,17 @@ declare namespace Phaser { * @param u1 UV u1 value. * @param v1 UV v1 value. */ - setUVs(width: number, height: number, u0: number, v0: number, u1: number, v1: number): Phaser.Textures.Frame; + setUVs(width: number, height: number, u0: number, v0: number, u1: number, v1: number): this; /** * Updates the internal WebGL UV cache and the drawImage cache. */ - updateUVs(): Phaser.Textures.Frame; + updateUVs(): this; /** * Updates the internal WebGL UV cache. */ - updateUVsInverted(): Phaser.Textures.Frame; + updateUVsInverted(): this; /** * Clones this Frame into a new Frame object. @@ -89222,6 +103990,18 @@ declare namespace Phaser { const NEAREST: number; namespace Parsers { + /** + * Parses a KTX format Compressed Texture file and generates texture data suitable for WebGL from it. + * @param data The data object created by the Compressed Texture File Loader. + */ + function KTXParser(data: ArrayBuffer): Phaser.Types.Textures.CompressedTextureData; + + /** + * Parses a PVR format Compressed Texture file and generates texture data suitable for WebGL from it. + * @param data The data object created by the Compressed Texture File Loader. + */ + function PVRParser(data: ArrayBuffer): Phaser.Types.Textures.CompressedTextureData; + } /** @@ -89308,7 +104088,7 @@ declare namespace Phaser { * @param width The width of this Frame. * @param height The height of this Frame. */ - add(name: number | string, sourceIndex: number, x: number, y: number, width: number, height: number): Phaser.Textures.Frame; + add(name: number | string, sourceIndex: number, x: number, y: number, width: number, height: number): Phaser.Textures.Frame | null; /** * Removes the given Frame from this Texture. The Frame is destroyed immediately. @@ -89406,12 +104186,16 @@ declare namespace Phaser { } /** - * 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. + * When Phaser boots it will create an instance of this Texture Manager class. * - * Sprites and other Game Objects get the texture data they need from the TextureManager. + * It is a global manager that handles all textures in your game. You can access it from within + * a Scene via the `this.textures` property. * - * Access it via `scene.textures`. + * Its role is as a manager for all textures that your game uses. It can create, update and remove + * textures globally, as well as parse texture data from external files, such as sprite sheets + * and texture atlases. + * + * Sprites and other texture-based Game Objects get their texture data directly from this class. */ class TextureManager extends Phaser.Events.EventEmitter { /** @@ -89421,23 +104205,52 @@ declare namespace Phaser { constructor(game: Phaser.Game); /** - * The Game that this TextureManager belongs to. + * The Game that the Texture Manager belongs to. + * + * A game will only ever have one instance of a Texture Manager. */ game: Phaser.Game; /** - * The name of this manager. + * The internal name of this manager. */ - name: string; + readonly name: string; /** - * 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. + * This object contains all Textures that belong to this Texture Manager. + * + * Textures are identified by string-based keys, which are used as the property + * within this object. Therefore, you can access any texture directly from this + * object without any iteration. + * + * You should not typically modify this object directly, but instead use the + * methods provided by the Texture Manager to add and remove entries from it. */ list: object; + /** + * An Image Game Object that belongs to this Texture Manager. + * + * Used as a drawing stamp within Dynamic Textures. + * + * This is not part of the display list and doesn't render. + */ + readonly stamp: Phaser.GameObjects.Image; + + /** + * The crop Rectangle as used by the Stamp when it needs to crop itself. + */ + stampCrop: Phaser.Geom.Rectangle; + + /** + * If this flag is `true` then the Texture Manager will never emit any + * warnings to the console log that report missing textures. + */ + silentWarnings: boolean; + /** * 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. * @param key The texture key to check. */ @@ -89493,7 +104306,7 @@ declare namespace Phaser { * @param source The source Image element. * @param dataSource An optional data Image element. */ - addImage(key: string, source: HTMLImageElement, dataSource?: HTMLImageElement | HTMLCanvasElement): Phaser.Textures.Texture; + addImage(key: string, source: HTMLImageElement, dataSource?: HTMLImageElement | HTMLCanvasElement): Phaser.Textures.Texture | null; /** * Takes a WebGL Texture and creates a Phaser Texture from it, which is added to the Texture Manager using the given key. @@ -89509,7 +104322,21 @@ declare namespace Phaser { * @param width The new width of the Texture. Read from `glTexture.width` if omitted. * @param height The new height of the Texture. Read from `glTexture.height` if omitted. */ - addGLTexture(key: string, glTexture: WebGLTexture, width?: number, height?: number): Phaser.Textures.Texture; + addGLTexture(key: string, glTexture: WebGLTexture, width?: number, height?: number): Phaser.Textures.Texture | null; + + /** + * Adds a Compressed Texture to this Texture Manager. + * + * The texture should typically have been loaded via the `CompressedTextureFile` loader, + * in order to prepare the correct data object this method requires. + * + * You can optionally also pass atlas data to this method, in which case a texture atlas + * will be generated from the given compressed texture, combined with the atlas data. + * @param key The unique string-based key of the Texture. + * @param textureData The Compressed Texture data object. + * @param atlasData Optional Texture Atlas data. + */ + addCompressedTexture(key: string, textureData: Phaser.Types.Textures.CompressedTextureData, atlasData?: object): Phaser.Textures.Texture | null; /** * Adds a Render Texture to the Texture Manager using the given key. @@ -89517,7 +104344,7 @@ declare namespace Phaser { * @param key The unique string-based key of the Texture. * @param renderTexture The source Render Texture. */ - addRenderTexture(key: string, renderTexture: Phaser.GameObjects.RenderTexture): Phaser.Textures.Texture; + addRenderTexture(key: string, renderTexture: Phaser.GameObjects.RenderTexture): Phaser.Textures.Texture | null; /** * Creates a new Texture using the given config values. @@ -89556,7 +104383,7 @@ declare namespace Phaser { * @param key The unique string-based key of the Texture. * @param config The configuration object needed to generate the texture. */ - generate(key: string, config: Phaser.Types.Create.GenerateTextureConfig): Phaser.Textures.Texture; + generate(key: string, config: Phaser.Types.Create.GenerateTextureConfig): Phaser.Textures.Texture | null; /** * Creates a new Texture using a blank Canvas element of the size given. @@ -89567,7 +104394,7 @@ declare namespace Phaser { * @param width The width of the Canvas element. Default 256. * @param height The height of the Canvas element. Default 256. */ - createCanvas(key: string, width?: number, height?: number): Phaser.Textures.CanvasTexture; + createCanvas(key: string, width?: number, height?: number): Phaser.Textures.CanvasTexture | null; /** * Creates a new Canvas Texture object from an existing Canvas element @@ -89576,70 +104403,130 @@ declare namespace Phaser { * @param source The Canvas element to form the base of the new Texture. * @param skipCache Skip adding this Texture into the Cache? Default false. */ - addCanvas(key: string, source: HTMLCanvasElement, skipCache?: boolean): Phaser.Textures.CanvasTexture; + addCanvas(key: string, source: HTMLCanvasElement, skipCache?: boolean): Phaser.Textures.CanvasTexture | null; /** - * Adds a new Texture Atlas to this Texture Manager. + * Creates a Dynamic Texture instance and adds itself to this Texture Manager. + * + * A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of + * Game Objects directly to it. + * + * You can take many complex objects and draw them to this one texture, which can then be used as the + * base texture for other Game Objects, such as Sprites. Should you then update this texture, all + * Game Objects using it will instantly be updated as well, reflecting the changes immediately. + * + * It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke + * expensive GPU uploads on each change. + * + * See the methods available on the `DynamicTexture` class for more details. + * + * Optionally, you can also pass a Dynamic Texture instance to this method to have + * it added to the Texture Manager. + * @param key The string-based key of this Texture. Must be unique within the Texture Manager. Or, a DynamicTexture instance. + * @param width The width of this Dynamic Texture in pixels. Defaults to 256 x 256. Ignored if an instance is passed as the key. Default 256. + * @param height The height of this Dynamic Texture in pixels. Defaults to 256 x 256. Ignored if an instance is passed as the key. Default 256. + */ + addDynamicTexture(key: string | Phaser.Textures.DynamicTexture, width?: number, height?: number): Phaser.Textures.DynamicTexture | null; + + /** + * Adds a Texture Atlas to this Texture Manager. + * + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file, + * such as those exported by applications like Texture Packer. + * * It can accept either JSON Array or JSON Hash formats, as exported by Texture Packer and similar software. + * + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. * @param key The unique string-based key of the Texture. - * @param source The source Image element. - * @param data The Texture Atlas data. + * @param source The source Image element/s, or a Phaser Texture. + * @param data The Texture Atlas data/s. * @param dataSource An optional data Image element. */ - addAtlas(key: string, source: HTMLImageElement, data: object, dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture; + addAtlas(key: string, source: HTMLImageElement | HTMLImageElement[] | Phaser.Textures.Texture, data: object | object[], dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture | null; /** * Adds a Texture Atlas to this Texture Manager. + * + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file, + * such as those exported by applications like Texture Packer. + * * 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. + * + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. * @param key The unique string-based key of the Texture. - * @param source The source Image element/s. + * @param source The source Image element/s, or a Phaser Texture. * @param data The Texture Atlas data/s. * @param dataSource An optional data Image element. */ - addAtlasJSONArray(key: string, source: HTMLImageElement | HTMLImageElement[], data: object | object[], dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture; + addAtlasJSONArray(key: string, source: HTMLImageElement | HTMLImageElement[] | Phaser.Textures.Texture, data: object | object[], dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture | null; /** * Adds a Texture Atlas to this Texture Manager. + * + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file, + * such as those exported by applications like Texture Packer. + * * 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. + * + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. * @param key The unique string-based key of the Texture. - * @param source The source Image element. - * @param data The Texture Atlas data. + * @param source The source Image element/s, or a Phaser Texture. + * @param data The Texture Atlas data/s. * @param dataSource An optional data Image element. */ - addAtlasJSONHash(key: string, source: HTMLImageElement, data: object, dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture; + addAtlasJSONHash(key: string, source: HTMLImageElement | HTMLImageElement[] | Phaser.Textures.Texture, data: object | object[], dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture | null; /** - * Adds a Texture Atlas to this Texture Manager, where the atlas data is given - * in the XML format. + * Adds a Texture Atlas to this Texture Manager. + * + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a data file, + * such as those exported by applications like Texture Packer. + * + * The frame data of the atlas must be stored in an XML file. + * + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. * @param key The unique string-based key of the Texture. - * @param source The source Image element. + * @param source The source Image element, or a Phaser Texture. * @param data The Texture Atlas XML data. * @param dataSource An optional data Image element. */ - addAtlasXML(key: string, source: HTMLImageElement, data: object, dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture; + addAtlasXML(key: string, source: HTMLImageElement | Phaser.Textures.Texture, data: object, dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture | null; /** * Adds a Unity Texture Atlas to this Texture Manager. - * The data must be in the form of a Unity YAML file. + * + * In Phaser terminology, a Texture Atlas is a combination of an atlas image and a data file, + * such as those exported by applications like Texture Packer or Unity. + * + * The frame data of the atlas must be stored in a Unity YAML file. + * + * As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture. * @param key The unique string-based key of the Texture. * @param source The source Image element. * @param data The Texture Atlas data. * @param dataSource An optional data Image element. */ - addUnityAtlas(key: string, source: HTMLImageElement, data: object, dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture; + addUnityAtlas(key: string, source: HTMLImageElement, data: object, dataSource?: HTMLImageElement | HTMLCanvasElement | HTMLImageElement[] | HTMLCanvasElement[]): Phaser.Textures.Texture | null; /** * 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. - * @param key The unique string-based key of the Texture. - * @param source The source Image element. + * same size and cannot be trimmed or rotated. This is different to a Texture Atlas, created by tools such as + * Texture Packer, and more akin with the fixed-frame exports you get from apps like Aseprite or old arcade + * games. + * + * As of Phaser 3.60 you can use this method to add a sprite sheet to an existing Phaser Texture. + * @param key The unique string-based key of the Texture. Give an empty string if you provide a Phaser Texture as the 2nd argument. + * @param source The source Image element, or a Phaser Texture. * @param config The configuration object for this Sprite Sheet. + * @param dataSource An optional data Image element. */ - addSpriteSheet(key: string, source: HTMLImageElement, config: Phaser.Types.Textures.SpriteSheetConfig): Phaser.Textures.Texture; + addSpriteSheet(key: string, source: HTMLImageElement | Phaser.Textures.Texture, config: Phaser.Types.Textures.SpriteSheetConfig, dataSource?: HTMLImageElement | HTMLCanvasElement): Phaser.Textures.Texture | null; /** * Adds a Sprite Sheet to this Texture Manager, where the Sprite Sheet exists as a Frame within a Texture Atlas. @@ -89649,7 +104536,7 @@ declare namespace Phaser { * @param key The unique string-based key of the Texture. * @param config The configuration object for this Sprite Sheet. */ - addSpriteSheetFromAtlas(key: string, config: Phaser.Types.Textures.SpriteSheetFromAtlasConfig): Phaser.Textures.Texture; + addSpriteSheetFromAtlas(key: string, config: Phaser.Types.Textures.SpriteSheetFromAtlasConfig): Phaser.Textures.Texture | null; /** * Creates a new Texture using the given source and dimensions. @@ -89658,7 +104545,7 @@ declare namespace Phaser { * @param width The width of the Texture. * @param height The height of the Texture. */ - create(key: string, source: HTMLImageElement, width: number, height: number): Phaser.Textures.Texture; + create(key: string, source: HTMLImageElement, width: number, height: number): Phaser.Textures.Texture | null; /** * Checks the given key to see if a Texture using it exists within this Texture Manager. @@ -89671,12 +104558,14 @@ declare namespace Phaser { * * 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. + * If the key is an instance of a Texture, it will return the instance. * - * Finally. if the key is given, but not found and not a Texture instance, it will return the `__MISSING` Texture. - * @param key The unique string-based key of the Texture, or a Texture instance. + * If the key is an instance of a Frame, it will return the frames parent Texture instance. + * + * Finally, if the key is given, but not found, and not a Texture or Frame instance, it will return the `__MISSING` Texture. + * @param key The unique string-based key of the Texture, or a Texture, or Frame instance. */ - get(key: string | Phaser.Textures.Texture): Phaser.Textures.Texture; + get(key: string | Phaser.Textures.Texture | Phaser.Textures.Frame): Phaser.Textures.Texture; /** * Takes a Texture key and Frame name and returns a clone of that Frame if found. @@ -89692,9 +104581,23 @@ declare namespace Phaser { */ getFrame(key: string, frame?: string | number): Phaser.Textures.Frame; + /** + * Parses the 'key' parameter and returns a Texture Frame instance. + * + * It can accept the following formats: + * + * 1) A string + * 2) An array where the elements are: [ key, [frame] ] + * 3) An object with the properties: { key, [frame] } + * 4) A Texture instance - which returns the default frame from the Texture + * 5) A Frame instance - returns itself + * @param key The key to be parsed. + */ + parseFrame(key: string | any[] | object | Phaser.Textures.Texture | Phaser.Textures.Frame): Phaser.Textures.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. + * The output array will exclude the `__DEFAULT`, `__MISSING`, and `__WHITE` keys. */ getTextureKeys(): string[]; @@ -89707,7 +104610,7 @@ declare namespace Phaser { * @param key The unique string-based key of the Texture. * @param frame The string or index of the Frame. */ - getPixel(x: number, y: number, key: string, frame?: string | number): Phaser.Display.Color; + getPixel(x: number, y: number, key: string, frame?: string | number): Phaser.Display.Color | null; /** * Given a Texture and an `x` and `y` coordinate this method will return a value between 0 and 255 @@ -89749,6 +104652,13 @@ declare namespace Phaser { */ each(callback: EachTextureCallback, scope: object, ...args: any[]): void; + /** + * Resets the internal Stamp object, ready for drawing and returns it. + * @param alpha The alpha to use. Default 1. + * @param tint WebGL only. The tint color to use. Default 0xffffff. + */ + resetStamp(alpha?: number, tint?: number): Phaser.GameObjects.Image; + /** * Destroys the Texture Manager and all Textures stored within it. */ @@ -89772,15 +104682,15 @@ declare namespace Phaser { * @param height Optional height of the source image. If not given it's derived from the source itself. * @param flipY Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. Default false. */ - constructor(texture: Phaser.Textures.Texture, source: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | Phaser.GameObjects.RenderTexture | WebGLTexture, width?: number, height?: number, flipY?: boolean); + constructor(texture: Phaser.Textures.Texture, source: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | Phaser.GameObjects.RenderTexture | WebGLTexture | Phaser.Types.Textures.CompressedTextureData | Phaser.Textures.DynamicTexture, width?: number, height?: number, flipY?: boolean); /** - * The Texture this TextureSource belongs to. + * A reference to the Canvas or WebGL Renderer. */ renderer: Phaser.Renderer.Canvas.CanvasRenderer | Phaser.Renderer.WebGL.WebGLRenderer; /** - * The Texture this TextureSource belongs to. + * The Texture this TextureSource instance belongs to. */ texture: Phaser.Textures.Texture; @@ -89788,8 +104698,10 @@ declare namespace Phaser { * The source of the image data. * * This is either an Image Element, a Canvas Element, a Video Element, a RenderTexture or a WebGLTexture. + * + * In Phaser 3.60 and above it can also be a Compressed Texture data object. */ - source: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | Phaser.GameObjects.RenderTexture | WebGLTexture; + source: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | Phaser.GameObjects.RenderTexture | WebGLTexture | Phaser.Types.Textures.CompressedTextureData | Phaser.Textures.DynamicTexture; /** * The image data. @@ -89799,7 +104711,9 @@ declare namespace Phaser { image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement; /** - * Currently un-used. + * Holds the compressed textured algorithm, or `null` if it's not a compressed texture. + * + * Prior to Phaser 3.60 this value always held `null`. */ compressionAlgorithm: number; @@ -89855,19 +104769,7 @@ declare namespace Phaser { * The WebGL Texture of the source image. If this TextureSource is driven from a WebGLTexture * already, then this is a reference to that WebGLTexture. */ - glTexture: WebGLTexture; - - /** - * The current texture unit index as assigned by the WebGL Renderer. - * Un-used in canvas. Should be treated as read-only. - */ - glIndex: number; - - /** - * 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. - */ - glIndexCounter: number; + glTexture: WebGLTexture | null; /** * Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload. @@ -89946,7 +104848,7 @@ declare namespace Phaser { /** * 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 + * coordinates) within the layer. This copies all tile properties and recalculates collision * information in the destination region. * @param srcTileX The x coordinate of the area to copy from, in tiles, not pixels. * @param srcTileY The y coordinate of the area to copy from, in tiles, not pixels. @@ -89971,7 +104873,7 @@ declare namespace Phaser { * @param camera The Camera to use when determining the world XY * @param layer The Tilemap Layer to act upon. */ - function CreateFromTiles(indexes: number | number[], replacements: number | number[], spriteConfig: Phaser.Types.GameObjects.Sprite.SpriteConfig, scene: Phaser.Scene, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): Phaser.GameObjects.Sprite[]; + function CreateFromTiles(indexes: number | number[], replacements: number | number[] | undefined, spriteConfig: Phaser.Types.GameObjects.Sprite.SpriteConfig, scene: Phaser.Scene, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): Phaser.GameObjects.Sprite[]; /** * Returns the bounds in the given orthogonal layer that are within the cameras viewport. @@ -90032,7 +104934,7 @@ declare namespace Phaser { * @param reverse If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. * @param layer The Tilemap Layer to act upon. */ - function FindByIndex(index: number, skip: number, reverse: boolean, layer: Phaser.Tilemaps.LayerData): Phaser.Tilemaps.Tile; + function FindByIndex(index: number, skip: number, reverse: boolean, layer: Phaser.Tilemaps.LayerData): Phaser.Tilemaps.Tile | null; /** * Find the first tile in the given rectangular area (in tile coordinates) of the layer that @@ -90047,7 +104949,7 @@ declare namespace Phaser { * @param filteringOptions Optional filters to apply when getting the tiles. * @param layer The Tilemap Layer to act upon. */ - function FindTile(callback: FindTileCallback, context: object, tileX: number, tileY: number, width: number, height: number, filteringOptions: Phaser.Types.Tilemaps.FilteringOptions, layer: Phaser.Tilemaps.LayerData): Phaser.Tilemaps.Tile; + function FindTile(callback: FindTileCallback, context: object, tileX: number, tileY: number, width: number, height: number, filteringOptions: Phaser.Types.Tilemaps.FilteringOptions, layer: Phaser.Tilemaps.LayerData): Phaser.Tilemaps.Tile | null; /** * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given @@ -90088,8 +104990,26 @@ declare namespace Phaser { */ function GetTileAtWorldXY(worldX: number, worldY: number, nonNull: boolean, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): Phaser.Tilemaps.Tile; + /** + * Gets the corners of the Tile as an array of Vector2s. + * @param tileX The x coordinate, in tiles, not pixels. + * @param tileY The y coordinate, in tiles, not pixels. + * @param camera The Camera to use when calculating the tile index from the world values. + * @param layer The Tilemap Layer to act upon. + */ + function GetTileCorners(tileX: number, tileY: number, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): Phaser.Math.Vector2[]; + + /** + * Gets the correct function to use to get the tile corners, based on the map orientation. + * @param orientation The Tilemap orientation constant. + */ + function GetTileCornersFunction(orientation: number): Function; + /** * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. + * + * This returns an array with references to the Tile instances in, so be aware of + * modifying them directly. * @param tileX The left most tile index (in tile coordinates) to use as the origin of the area. * @param tileY The top most tile index (in tile coordinates) to use as the origin of the area. * @param width How many tiles wide from the `tileX` index the area will be. @@ -90141,6 +105061,8 @@ declare namespace Phaser { /** * Gets the correct function to use to translate tiles, based on the map orientation. + * + * Only orthogonal maps support this feature. * @param orientation The Tilemap orientation constant. */ function GetWorldToTileXFunction(orientation: number): Function; @@ -90164,7 +105086,7 @@ declare namespace Phaser { * @param tileY Y position to get the tile from (given in tile units, not pixels). * @param layer The Tilemap Layer to act upon. */ - function HasTileAt(tileX: number, tileY: number, layer: Phaser.Tilemaps.LayerData): boolean; + function HasTileAt(tileX: number, tileY: number, layer: Phaser.Tilemaps.LayerData): boolean | null; /** * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns @@ -90174,7 +105096,7 @@ declare namespace Phaser { * @param camera The Camera to use when factoring in which tiles to return. * @param layer The Tilemap Layer to act upon. */ - function HasTileAtWorldXY(worldX: number, worldY: number, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): boolean; + function HasTileAtWorldXY(worldX: number, worldY: number, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): boolean | null; /** * Returns the bounds in the given layer that are within the camera's viewport. @@ -90194,25 +105116,25 @@ declare namespace Phaser { function HexagonalCullTiles(layer: Phaser.Tilemaps.LayerData, camera: Phaser.Cameras.Scene2D.Camera, outputArray?: any[], renderOrder?: number): Phaser.Tilemaps.Tile[]; /** - * 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. + * Gets the corners of the Hexagonal Tile as an array of Vector2s. * @param tileX The x coordinate, in tiles, not pixels. * @param tileY The y coordinate, in tiles, not pixels. - * @param point A Vector2 to store the coordinates in. If not given a new Vector2 is created. * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The Tilemap Layer to act upon. */ - function HexagonalTileToWorldXY(tileX: number, tileY: number, point: Phaser.Math.Vector2, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): Phaser.Math.Vector2; + function HexagonalGetTileCorners(tileX: number, tileY: number, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): Phaser.Math.Vector2[]; /** - * Converts from hexagonal tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the - * layer's position, scale and scroll. + * 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. + * @param tileX The x coordinate, in tiles, not pixels. * @param tileY The y coordinate, in tiles, not pixels. + * @param point A Vector2 to store the coordinates in. If not given a new Vector2 is created. * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The Tilemap Layer to act upon. */ - function HexagonalTileToWorldY(tileY: number, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): number; + function HexagonalTileToWorldXY(tileX: number, tileY: number, point: Phaser.Math.Vector2, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): Phaser.Math.Vector2; /** * Converts from world XY coordinates (pixels) to hexagonal tile XY coordinates (tile units), factoring in the @@ -90227,16 +105149,6 @@ declare namespace Phaser { */ function HexagonalWorldToTileXY(worldX: number, worldY: number, snapToFloor: boolean, point: Phaser.Math.Vector2, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): Phaser.Math.Vector2; - /** - * Converts from world Y coordinates (pixels) to hexagonal tile Y coordinates (tile units), factoring in the - * layers position, scale and scroll. - * @param worldY The y coordinate to be converted, in pixels, not tiles. - * @param snapToFloor Whether or not to round the tile coordinate down to the nearest integer. - * @param camera The Camera to use when calculating the tile index from the world values. - * @param layer The Tilemap Layer to act upon. - */ - function HexagonalWorldToTileY(worldY: number, snapToFloor: boolean, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): number; - /** * Checks if the given tile coordinates are within the bounds of the layer. * @param tileX The x coordinate, in tiles, not pixels. @@ -90268,7 +105180,7 @@ declare namespace Phaser { /** * 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 + * layers position, scale and scroll. This will return a new Vector2 object or update the given * `point` object. * @param worldX The x coordinate to be converted, in pixels, not tiles. * @param worldY The y coordinate to be converted, in pixels, not tiles. @@ -90276,8 +105188,9 @@ declare namespace Phaser { * @param point A Vector2 to store the coordinates in. If not given a new Vector2 is created. * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The Tilemap Layer to act upon. + * @param originTop Which is the active face of the isometric tile? The top (default, true), or the base? (false) Default true. */ - function IsometricWorldToTileXY(worldX: number, worldY: number, snapToFloor: boolean, point: Phaser.Math.Vector2, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): Phaser.Math.Vector2; + function IsometricWorldToTileXY(worldX: number, worldY: number, snapToFloor: boolean, point: Phaser.Math.Vector2, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData, originTop?: boolean): Phaser.Math.Vector2; /** * Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index @@ -90649,7 +105562,7 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The Tilemap Layer to act upon. */ - function WorldToTileX(worldX: number, snapToFloor: boolean, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): number; + function WorldToTileX(worldX: number, snapToFloor: boolean, camera: Phaser.Cameras.Scene2D.Camera | undefined, layer: Phaser.Tilemaps.LayerData): number; /** * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the @@ -90672,7 +105585,7 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The Tilemap Layer to act upon. */ - function WorldToTileY(worldY: number, snapToFloor: boolean, camera: Phaser.Cameras.Scene2D.Camera, layer: Phaser.Tilemaps.LayerData): number; + function WorldToTileY(worldY: number, snapToFloor: boolean, camera: Phaser.Cameras.Scene2D.Camera | undefined, layer: Phaser.Tilemaps.LayerData): number; } @@ -90932,6 +105845,22 @@ declare namespace Phaser { */ hexSideLength: number; + /** + * The Stagger Axis as defined in Tiled. + * + * Only used for hexagonal orientation Tilemaps. + */ + staggerAxis: string; + + /** + * The Stagger Index as defined in Tiled. + * + * Either 'odd' or 'even'. + * + * Only used for hexagonal orientation Tilemaps. + */ + staggerIndex: string; + } /** @@ -91029,7 +105958,7 @@ declare namespace Phaser { /** * An object of Tiled Object Layers. */ - objects: object; + objects: Phaser.Types.Tilemaps.ObjectLayerConfig[]; /** * An object of collision data. Must be created as physics object or will return undefined. @@ -91053,10 +105982,27 @@ declare namespace Phaser { /** * The length of the horizontal sides of the hexagon. + * * Only used for hexagonal orientation Tilemaps. */ hexSideLength: number; + /** + * The Stagger Axis as defined in Tiled. + * + * Only used for hexagonal orientation Tilemaps. + */ + staggerAxis: string; + + /** + * The Stagger Index as defined in Tiled. + * + * Either 'odd' or 'even'. + * + * Only used for hexagonal orientation Tilemaps. + */ + staggerIndex: string; + } /** @@ -91127,6 +106073,55 @@ declare namespace Phaser { } + /** + * The ObjectHelper helps tie objects with `gids` into the tileset + * that sits behind them. + */ + class ObjectHelper { + /** + * + * @param tilesets The backing tileset data. + */ + constructor(tilesets: Phaser.Tilemaps.Tileset[]); + + /** + * The Tile GIDs array. + */ + gids: any[]; + + /** + * Enabled if the object helper reaches in to tilesets for data. + * Disabled if it only uses data directly on a gid object. + */ + enabled: boolean; + + /** + * Gets the Tiled `type` field value from the object or the `gid` behind it. + * @param obj The Tiled object to investigate. + */ + getTypeIncludingTile(obj: Phaser.Types.Tilemaps.TiledObject): string | null; + + /** + * Sets the sprite texture data as specified (usually in a config) or, failing that, + * as specified in the `gid` of the object being loaded (if any). + * + * This fallback will only work if the tileset was loaded as a spritesheet matching + * the geometry of sprites fed into tiled, so that, for example: "tile id #`3`"" within + * the tileset is the same as texture frame `3` from the image of the tileset. + * @param sprite The Game Object to modify. + * @param key The texture key to set (or else the `obj.gid`'s tile is used if available). + * @param frame The frames key to set (or else the `obj.gid`'s tile is used if available). + * @param obj The Tiled object for fallback. + */ + setTextureAndFrame(sprite: Phaser.GameObjects.GameObject, key?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame, obj?: Phaser.Types.Tilemaps.TiledObject): void; + + /** + * Sets the `sprite.data` field from the tiled properties on the object and its tile (if any). + */ + setPropertiesFromTiledObject(sprite: Phaser.GameObjects.GameObject, obj: Phaser.Types.Tilemaps.TiledObject): void; + + } + namespace Parsers { /** * Get the Tilemap orientation from the given string. @@ -91160,7 +106155,7 @@ declare namespace Phaser { * consumption. However if your map is small or you need to update the tiles dynamically, then leave * the default value set. */ - function ParseWeltmeister(name: string, json: object, insertNull: boolean): Phaser.Tilemaps.MapData; + function ParseWeltmeister(name: string, json: object, insertNull: boolean): Phaser.Tilemaps.MapData | null; } @@ -91237,10 +106232,10 @@ declare namespace Phaser { /** * Parse a Tiled group layer and create a state object for inheriting. * @param json The Tiled JSON object. - * @param currentl The current group layer from the Tiled JSON file. - * @param parentstate The state of the parent group (if any). + * @param group The current group layer from the Tiled JSON file. + * @param parentState The state of the parent group (if any). */ - function CreateGroupLayer(json: object, currentl?: object, parentstate?: object): object; + function CreateGroupLayer(json: object, group?: object, parentState?: object): object; /** * See Tiled documentation on tile flipping: @@ -91258,7 +106253,7 @@ declare namespace Phaser { /** * Parses a Tiled JSON object into a new MapData object. * @param name The name of the tilemap, used to set the name on the MapData. - * @param json The Tiled JSON object. + * @param source The original Tiled JSON object. This is deep copied by this function. * @param 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 @@ -91266,7 +106261,7 @@ declare namespace Phaser { * consumption. However if your map is small or you need to update the tiles dynamically, then leave * the default value set. */ - function ParseJSONTiled(name: string, json: object, insertNull: boolean): Phaser.Tilemaps.MapData; + function ParseJSONTiled(name: string, source: object, insertNull: boolean): Phaser.Tilemaps.MapData | null; /** * Convert a Tiled object to an internal parsed object normalising and copying properties over, while applying optional x and y offsets. The parsed object will always have the properties `id`, `name`, `type`, `rotation`, `properties`, `visible`, `x`, `y`, `width` and `height`. Other properties will be added according to the object type (such as text, polyline, gid etc.) @@ -91524,8 +106519,8 @@ declare namespace Phaser { containsPoint(x: number, y: number): boolean; /** - * Copies the tile data & properties from the given tile to this tile. This copies everything - * except for position and interesting faces. + * Copies the tile data and properties from the given Tile to this Tile. This copies everything + * except for position and interesting face calculations. * @param tile The tile to copy from. */ copy(tile: Phaser.Tilemaps.Tile): this; @@ -91535,7 +106530,7 @@ declare namespace Phaser { * the collision group stored within the Tileset, so any modification of the returned object * will impact all tiles that have the same index as this tile. */ - getCollisionGroup(): object; + getCollisionGroup(): object | null; /** * The tile data for this Tile, defined within the Tileset. This typically contains Tiled @@ -91543,7 +106538,7 @@ declare namespace Phaser { * data stored within the Tileset, so any modification of the returned object will impact all * tiles that have the same index as this tile. */ - getTileData(): object; + getTileData(): object | null; /** * Gets the world X position of the left side of the tile, factoring in the layers position, @@ -91680,19 +106675,19 @@ declare namespace Phaser { * before the tile is placed in a TilemapLayer, or if the tile has an index that doesn't correspond * to any of the maps tilesets. */ - readonly tileset: Phaser.Tilemaps.Tileset; + readonly tileset: Phaser.Tilemaps.Tileset | null; /** * The tilemap layer that contains this Tile. This will only return null if accessed from a * LayerData instance before the tile is placed within a TilemapLayer. */ - readonly tilemapLayer: Phaser.Tilemaps.TilemapLayer; + readonly tilemapLayer: Phaser.Tilemaps.TilemapLayer | null; /** * The tilemap that contains this Tile. This will only return null if accessed from a LayerData * instance before the tile is placed within a TilemapLayer. */ - readonly tilemap: Phaser.Tilemaps.Tilemap; + readonly tilemap: Phaser.Tilemaps.Tilemap | null; /** * Clears all alpha values associated with this Game Object. @@ -91869,6 +106864,10 @@ declare namespace Phaser { * 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'. + * + * The Phaser Tiled Parser does **not** support the 'Collection of Images' feature for a Tileset. + * You must ensure all of your tiles are contained in a single tileset image file (per layer) + * and have this 'embedded' in the exported Tiled JSON map data. */ class Tilemap { /** @@ -91961,6 +106960,11 @@ declare namespace Phaser { */ layers: Phaser.Tilemaps.LayerData[]; + /** + * Master list of tiles -> x, y, index in tileset. + */ + tiles: any[]; + /** * An array of Tilesets used in the map. */ @@ -92026,8 +107030,10 @@ declare namespace Phaser { * If not specified, it will default to 0 or the value specified in the Tiled JSON file. * @param gid If adding multiple tilesets to a blank map, specify the starting * GID this set will use here. Default 0. + * @param tileOffset Tile texture drawing offset. + * If not specified, it will default to {0, 0} Default {x: 0, y: 0}. */ - addTilesetImage(tilesetName: string, key?: string, tileWidth?: number, tileHeight?: number, tileMargin?: number, tileSpacing?: number, gid?: number): Phaser.Tilemaps.Tileset; + addTilesetImage(tilesetName: string, key?: string, tileWidth?: number, tileHeight?: number, tileMargin?: number, tileSpacing?: number, gid?: number, tileOffset?: object): Phaser.Tilemaps.Tileset | null; /** * Copies the tiles in the source rectangular area to a new destination (all specified in tile @@ -92044,7 +107050,7 @@ declare namespace Phaser { * @param recalculateFaces `true` if the faces data should be recalculated. Default true. * @param layer The tile layer to use. If not given the current layer is used. */ - copy(srcTileX: number, srcTileY: number, width: number, height: number, destTileX: number, destTileY: number, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + copy(srcTileX: number, srcTileY: number, width: number, height: number, destTileX: number, destTileY: number, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Creates a new and empty Tilemap Layer. The currently selected layer in the map is set to this new layer. @@ -92059,7 +107065,7 @@ declare namespace Phaser { * @param tileWidth The width of the tiles the layer uses for calculations. If not specified, it will default to the map's tileWidth. * @param tileHeight The height of the tiles the layer uses for calculations. If not specified, it will default to the map's tileHeight. */ - createBlankLayer(name: string, tileset: string | string[] | Phaser.Tilemaps.Tileset | Phaser.Tilemaps.Tileset[], x?: number, y?: number, width?: number, height?: number, tileWidth?: number, tileHeight?: number): Phaser.Tilemaps.TilemapLayer; + createBlankLayer(name: string, tileset: string | string[] | Phaser.Tilemaps.Tileset | Phaser.Tilemaps.Tileset[], x?: number, y?: number, width?: number, height?: number, tileWidth?: number, tileHeight?: number): Phaser.Tilemaps.TilemapLayer | null; /** * Creates a new Tilemap Layer that renders the LayerData associated with the given @@ -92075,17 +107081,18 @@ declare namespace Phaser { * @param x The x position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. Default 0. * @param y The y position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0. Default 0. */ - createLayer(layerID: number | string, tileset: string | string[] | Phaser.Tilemaps.Tileset | Phaser.Tilemaps.Tileset[], x?: number, y?: number): Phaser.Tilemaps.TilemapLayer; + createLayer(layerID: number | string, tileset: string | string[] | Phaser.Tilemaps.Tileset | Phaser.Tilemaps.Tileset[], x?: number, y?: number): Phaser.Tilemaps.TilemapLayer | null; /** * 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. + * Objects are matched on one of 4 criteria: The Object ID, the Object GID, the Object Name, or the Object Type. * * 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. + * using the same image. Finally, Object Names and Types are strings and the same name can be used on multiple + * Objects in Tiled, they do not have to be unique; Names are specific to Objects while Types can be inherited + * from Object GIDs using the same image. * * 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: @@ -92112,11 +107119,11 @@ declare namespace Phaser { * }); * ``` * - * You should only specify either `id`, `gid`, `name`, or none of them. Do not add more than + * You should only specify either `id`, `gid`, `name`, `type`, 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 + * By default this method will convert Objects into {@link Phaser.GameObjects.Sprite} instances, but you can override * this by providing your own class type: * * ```javascript @@ -92127,19 +107134,48 @@ declare namespace Phaser { * ``` * * 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. + * any class type here, but it _must_ extend {@link 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. + * specified in the config object or, if not given, the Scene to which this Tilemap belongs. The + * class must have {@link Phaser.GameObjects.Components.Transform#setPosition setPosition} and + * {@link Phaser.GameObjects.Components.Texture#setTexture setTexture} methods. * - * 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 + * Custom properties on the Object are copied onto any existing properties on 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}. + * Custom properties that do not exist on the Game Object are set in the + * Game Object's {@link Phaser.GameObjects.GameObject#data data store}. + * + * When `useTileset` is `true` (the default), Tile Objects will inherit the texture and any tile properties + * from the tileset, and the local tile ID will be used as the texture frame. For the frame selection to work + * you need to load the tileset texture as a spritesheet so its frame names match the local tile IDs. + * + * For instance, a tileset tile + * + * ``` + * { id: 3, type: 'treadmill', speed: 4 } + * ``` + * + * with gid 19 and an object + * + * ``` + * { id: 7, gid: 19, speed: 5, rotation: 90 } + * ``` + * + * will be interpreted as + * + * ``` + * { id: 7, gid: 19, speed: 5, rotation: 90, type: 'treadmill', texture: '[the tileset texture]', frame: 3 } + * ``` + * + * You can suppress this behavior by setting the boolean `ignoreTileset` for each `config` that should ignore + * object gid tilesets. * - * 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. + * You can set a `container` property in the config. If given, the new Game Object will be added to + * the Container or Layer instance instead of the Scene. + * + * You can set named texture-`key` and texture-`frame` properties, which will be set on the new Game Object. * * Finally, you can provide an array of config objects, to convert multiple types of object in * a single call: @@ -92157,15 +107193,20 @@ declare namespace Phaser { * { * name: 'lava', * classType: LavaTile + * }, + * { + * type: 'endzone', + * classType: Phaser.GameObjects.Zone * } * ]); * ``` * - * The signature of this method changed significantly in v3.50.0. Prior to this, it did not take config objects. + * The signature of this method changed significantly in v3.60.0. Prior to this, it did not take config objects. * @param objectLayerName The name of the Tiled object layer to create the Game Objects from. * @param config A CreateFromObjects configuration object, or an array of them. + * @param useTileset True if objects that set gids should also search the underlying tile for properties and data. Default true. */ - createFromObjects(objectLayerName: string, config: Phaser.Types.Tilemaps.CreateFromObjectLayerConfig | Phaser.Types.Tilemaps.CreateFromObjectLayerConfig[]): Phaser.GameObjects.GameObject[]; + createFromObjects(objectLayerName: string, config: Phaser.Types.Tilemaps.CreateFromObjectLayerConfig | Phaser.Types.Tilemaps.CreateFromObjectLayerConfig[], useTileset?: boolean): Phaser.GameObjects.GameObject[]; /** * Creates a Sprite for every object matching the given tile indexes in the layer. You can @@ -92181,7 +107222,7 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - createFromTiles(indexes: number | any[], replacements: number | any[], spriteConfig: Phaser.Types.GameObjects.Sprite.SpriteConfig, scene?: Phaser.Scene, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.GameObjects.Sprite[]; + createFromTiles(indexes: number | any[], replacements: number | any[] | undefined, spriteConfig: Phaser.Types.GameObjects.Sprite.SpriteConfig, scene?: Phaser.Scene, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.GameObjects.Sprite[] | null; /** * Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the @@ -92198,17 +107239,17 @@ declare namespace Phaser { * @param recalculateFaces `true` if the faces data should be recalculated. Default true. * @param layer The tile layer to use. If not given the current layer is used. */ - fill(index: number, tileX?: number, tileY?: number, width?: number, height?: number, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + fill(index: number, tileX?: number, tileY?: number, width?: number, height?: number, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * 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 + * objects that pass the filter test (i.e. where the callback returns true) will be returned in a * new array. Similar to Array.prototype.Filter in vanilla JS. * @param objectLayer The name of an object layer (from Tiled) or an ObjectLayer instance. * @param callback The callback. Each object in the given area will be passed to this callback as the first and only parameter. * @param context The context under which the callback should be run. */ - filterObjects(objectLayer: Phaser.Tilemaps.ObjectLayer | string, callback: TilemapFilterCallback, context?: object): Phaser.Types.Tilemaps.TiledObject[]; + filterObjects(objectLayer: Phaser.Tilemaps.ObjectLayer | string, callback: TilemapFilterCallback, context?: object): Phaser.Types.Tilemaps.TiledObject[] | null; /** * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given @@ -92226,7 +107267,7 @@ declare namespace Phaser { * @param filteringOptions Optional filters to apply when getting the tiles. * @param layer The tile layer to use. If not given the current layer is used. */ - filterTiles(callback: Function, context?: object, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile[]; + filterTiles(callback: Function, context?: object, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile[] | null; /** * Searches the entire map layer for the first tile matching the given index, then returns that Tile @@ -92240,7 +107281,7 @@ declare namespace Phaser { * @param reverse If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left. Default false. * @param layer The tile layer to use. If not given the current layer is used. */ - findByIndex(index: number, skip?: number, reverse?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile; + findByIndex(index: number, skip?: number, reverse?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | null; /** * Find the first object in the given object layer that satisfies the provided testing function. @@ -92250,7 +107291,7 @@ declare namespace Phaser { * @param callback The callback. Each object in the given area will be passed to this callback as the first and only parameter. * @param context The context under which the callback should be run. */ - findObject(objectLayer: Phaser.Tilemaps.ObjectLayer | string, callback: TilemapFindCallback, context?: object): Phaser.Types.Tilemaps.TiledObject; + findObject(objectLayer: Phaser.Tilemaps.ObjectLayer | string, callback: TilemapFindCallback, context?: object): Phaser.Types.Tilemaps.TiledObject | null; /** * Find the first tile in the given rectangular area (in tile coordinates) of the layer that @@ -92266,7 +107307,7 @@ declare namespace Phaser { * @param filteringOptions Optional filters to apply when getting the tiles. * @param layer The Tile layer to run the search on. If not provided will use the current layer. */ - findTile(callback: FindTileCallback, context?: object, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile; + findTile(callback: FindTileCallback, context?: object, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | null; /** * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given @@ -92282,7 +107323,7 @@ declare namespace Phaser { * @param filteringOptions Optional filters to apply when getting the tiles. * @param layer The Tile layer to run the search on. If not provided will use the current layer. */ - forEachTile(callback: EachTileCallback, context?: object, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + forEachTile(callback: EachTileCallback, context?: object, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Gets the image layer index based on its name. @@ -92307,13 +107348,13 @@ declare namespace Phaser { * Gets the LayerData from `this.layers` that is associated with the given `layer`, or null if the layer is invalid. * @param 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. */ - getLayer(layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.LayerData; + getLayer(layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.LayerData | null; /** * Gets the ObjectLayer from `this.objects` that has the given `name`, or null if no ObjectLayer is found with that name. * @param name The name of the object layer from Tiled. */ - getObjectLayer(name?: string): Phaser.Tilemaps.ObjectLayer; + getObjectLayer(name?: string): Phaser.Tilemaps.ObjectLayer | null; /** * Return a list of all valid objectgroup names loaded in this Tilemap. @@ -92343,7 +107384,7 @@ declare namespace Phaser { * @param nonNull If true getTile won't return null for empty tiles, but a Tile object with an index of -1. * @param layer The tile layer to use. If not given the current layer is used. */ - getTileAt(tileX: number, tileY: number, nonNull?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile; + getTileAt(tileX: number, tileY: number, nonNull?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | null; /** * Gets a tile at the given world coordinates from the given layer. @@ -92355,7 +107396,7 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - getTileAtWorldXY(worldX: number, worldY: number, nonNull?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile; + getTileAtWorldXY(worldX: number, worldY: number, nonNull?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | null; /** * Return a list of all valid tilelayer names loaded in this Tilemap. @@ -92373,7 +107414,7 @@ declare namespace Phaser { * @param filteringOptions Optional filters to apply when getting the tiles. * @param layer The tile layer to use. If not given the current layer is used. */ - getTilesWithin(tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile[]; + getTilesWithin(tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile[] | null; /** * Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle, @@ -92385,7 +107426,7 @@ declare namespace Phaser { * @param camera The Camera to use when factoring in which tiles to return. * @param layer The tile layer to use. If not given the current layer is used. */ - getTilesWithinShape(shape: Phaser.Geom.Circle | Phaser.Geom.Line | Phaser.Geom.Rectangle | Phaser.Geom.Triangle, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile[]; + getTilesWithinShape(shape: Phaser.Geom.Circle | Phaser.Geom.Line | Phaser.Geom.Rectangle | Phaser.Geom.Triangle, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile[] | null; /** * Gets the tiles in the given rectangular area (in world coordinates) of the layer. @@ -92399,13 +107440,13 @@ declare namespace Phaser { * @param camera The Camera to use when factoring in which tiles to return. * @param layer The tile layer to use. If not given the current layer is used. */ - getTilesWithinWorldXY(worldX: number, worldY: number, width: number, height: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile[]; + getTilesWithinWorldXY(worldX: number, worldY: number, width: number, height: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile[] | null; /** * Gets the Tileset that has the given `name`, or null if an invalid `name` is given. * @param name The name of the Tileset to get. */ - getTileset(name: string): Phaser.Tilemaps.Tileset; + getTileset(name: string): Phaser.Tilemaps.Tileset | null; /** * Gets the index of the Tileset within this.tilesets that has the given `name`, or null if an @@ -92423,7 +107464,7 @@ declare namespace Phaser { * @param tileY The y coordinate, in tiles, not pixels. * @param layer The tile layer to use. If not given the current layer is used. */ - hasTileAt(tileX: number, tileY: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): boolean; + hasTileAt(tileX: number, tileY: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): boolean | null; /** * Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns @@ -92435,7 +107476,7 @@ declare namespace Phaser { * @param camera The Camera to use when factoring in which tiles to return. * @param layer The tile layer to use. If not given the current layer is used. */ - hasTileAtWorldXY(worldX: number, worldY: number, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): boolean; + hasTileAtWorldXY(worldX: number, worldY: number, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): boolean | null; /** * The LayerData object that is currently selected in the map. You can set this property using @@ -92456,7 +107497,7 @@ declare namespace Phaser { * @param recalculateFaces `true` if the faces data should be recalculated. * @param layer The tile layer to use. If not given the current layer is used. */ - putTileAt(tile: number | Phaser.Tilemaps.Tile, tileX: number, tileY: number, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile; + putTileAt(tile: number | Phaser.Tilemaps.Tile, tileX: number, tileY: number, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | null; /** * Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either @@ -92472,7 +107513,7 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - putTileAtWorldXY(tile: number | Phaser.Tilemaps.Tile, worldX: number, worldY: number, recalculateFaces?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile; + putTileAtWorldXY(tile: number | Phaser.Tilemaps.Tile, worldX: number, worldY: number, recalculateFaces?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | null; /** * Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified @@ -92488,7 +107529,7 @@ declare namespace Phaser { * @param recalculateFaces `true` if the faces data should be recalculated. * @param layer The tile layer to use. If not given the current layer is used. */ - putTilesAt(tile: number[] | number[][] | Phaser.Tilemaps.Tile[] | Phaser.Tilemaps.Tile[][], tileX: number, tileY: number, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + putTilesAt(tile: number[] | number[][] | Phaser.Tilemaps.Tile[] | Phaser.Tilemaps.Tile[][], tileX: number, tileY: number, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the @@ -92505,7 +107546,7 @@ declare namespace Phaser { * @param indexes An array of indexes to randomly draw from during randomization. * @param layer The tile layer to use. If not given the current layer is used. */ - randomize(tileX?: number, tileY?: number, width?: number, height?: number, indexes?: number[], layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + randomize(tileX?: number, tileY?: number, width?: number, height?: number, indexes?: number[], layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Calculates interesting faces at the given tile coordinates of the specified layer. Interesting @@ -92517,7 +107558,7 @@ declare namespace Phaser { * @param tileY The y coordinate, in tiles, not pixels. * @param layer The tile layer to use. If not given the current layer is used. */ - calculateFacesAt(tileX: number, tileY: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + calculateFacesAt(tileX: number, tileY: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Calculates interesting faces within the rectangular area specified (in tile coordinates) of the @@ -92531,7 +107572,7 @@ declare namespace Phaser { * @param height How many tiles tall from the `tileY` index the area will be. * @param layer The tile layer to use. If not given the current layer is used. */ - calculateFacesWithin(tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + calculateFacesWithin(tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Removes the given TilemapLayer from this Tilemap without destroying it. @@ -92539,7 +107580,7 @@ declare namespace Phaser { * If no layer is specified, the maps current layer is used. * @param layer The tile layer to be removed. */ - removeLayer(layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + removeLayer(layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Destroys the given TilemapLayer and removes it from this Tilemap. @@ -92547,7 +107588,7 @@ declare namespace Phaser { * If no layer is specified, the maps current layer is used. * @param layer The tile layer to be destroyed. */ - destroyLayer(layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + destroyLayer(layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Removes all Tilemap Layers from this Tilemap and calls `destroy` on each of them. @@ -92573,7 +107614,7 @@ declare namespace Phaser { * @param recalculateFaces If `true` (the default), the faces data will be recalculated. * @param layer The tile layer to use. If not given the current layer is used. */ - removeTileAt(tileX: number, tileY: number, replaceWithNull?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile; + removeTileAt(tileX: number, tileY: number, replaceWithNull?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | null; /** * Removes the tile at the given world coordinates in the specified layer and updates the layers collision information. @@ -92586,7 +107627,7 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - removeTileAtWorldXY(worldX: number, worldY: number, replaceWithNull?: boolean, recalculateFaces?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile; + removeTileAtWorldXY(worldX: number, worldY: number, replaceWithNull?: boolean, recalculateFaces?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | null; /** * Draws a debug representation of the layer to the given Graphics object. This is helpful when you want to @@ -92601,7 +107642,7 @@ declare namespace Phaser { * @param styleConfig An object specifying the colors to use for the debug drawing. * @param layer The tile layer to use. If not given the current layer is used. */ - renderDebug(graphics: Phaser.GameObjects.Graphics, styleConfig?: Phaser.Types.Tilemaps.StyleConfig, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + renderDebug(graphics: Phaser.GameObjects.Graphics, styleConfig?: Phaser.Types.Tilemaps.StyleConfig, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Draws a debug representation of all layers within this Tilemap to the given Graphics object. @@ -92628,7 +107669,7 @@ declare namespace Phaser { * @param height How many tiles tall from the `tileY` index the area will be. * @param layer The tile layer to use. If not given the current layer is used. */ - replaceByIndex(findIndex: number, newIndex: number, tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + replaceByIndex(findIndex: number, newIndex: number, tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Sets collision on the given tile or tiles within a layer by index. You can pass in either a @@ -92642,7 +107683,7 @@ declare namespace Phaser { * @param layer The tile layer to use. If not given the current layer is used. * @param updateLayer If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost. Default true. */ - setCollision(indexes: number | any[], collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer, updateLayer?: boolean): Phaser.Tilemaps.Tilemap; + setCollision(indexes: number | any[], collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer, updateLayer?: boolean): Phaser.Tilemaps.Tilemap | null; /** * Sets collision on a range of tiles in a layer whose index is between the specified `start` and @@ -92657,7 +107698,7 @@ declare namespace Phaser { * @param recalculateFaces Whether or not to recalculate the tile faces after the update. * @param layer The tile layer to use. If not given the current layer is used. */ - setCollisionBetween(start: number, stop: number, collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + setCollisionBetween(start: number, stop: number, collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Sets collision on the tiles within a layer by checking tile properties. If a tile has a property @@ -92674,7 +107715,7 @@ declare namespace Phaser { * @param recalculateFaces Whether or not to recalculate the tile faces after the update. * @param layer The tile layer to use. If not given the current layer is used. */ - setCollisionByProperty(properties: object, collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + setCollisionByProperty(properties: object, collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Sets collision on all tiles in the given layer, except for tiles that have an index specified in @@ -92687,7 +107728,7 @@ declare namespace Phaser { * @param recalculateFaces Whether or not to recalculate the tile faces after the update. * @param layer The tile layer to use. If not given the current layer is used. */ - setCollisionByExclusion(indexes: number[], collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + setCollisionByExclusion(indexes: number[], collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Sets collision on the tiles within a layer by checking each tiles collision group data @@ -92700,7 +107741,7 @@ declare namespace Phaser { * @param recalculateFaces Whether or not to recalculate the tile faces after the update. * @param layer The tile layer to use. If not given the current layer is used. */ - setCollisionFromCollisionGroup(collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + setCollisionFromCollisionGroup(collides?: boolean, recalculateFaces?: boolean, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Sets a global collision callback for the given tile index within the layer. This will affect all @@ -92714,7 +107755,7 @@ declare namespace Phaser { * @param callbackContext The context under which the callback is called. * @param layer The tile layer to use. If not given the current layer is used. */ - setTileIndexCallback(indexes: number | number[], callback: Function, callbackContext: object, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + setTileIndexCallback(indexes: number | number[], callback: Function, callbackContext: object, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Sets a collision callback for the given rectangular area (in tile coordinates) within the layer. @@ -92730,7 +107771,7 @@ declare namespace Phaser { * @param callbackContext The context under which the callback is called. * @param layer The tile layer to use. If not given the current layer is used. */ - setTileLocationCallback(tileX: number, tileY: number, width: number, height: number, callback: Function, callbackContext?: object, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + setTileLocationCallback(tileX: number, tileY: number, width: number, height: number, callback: Function, callbackContext?: object, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Sets the current layer to the LayerData associated with `layer`. @@ -92769,7 +107810,7 @@ declare namespace Phaser { * @param height How many tiles tall from the `tileY` index the area will be. * @param layer The tile layer to use. If not given the current layer is used. */ - shuffle(tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + shuffle(tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Scans the given rectangular area (given in tile coordinates) for tiles with an index matching @@ -92785,7 +107826,7 @@ declare namespace Phaser { * @param height How many tiles tall from the `tileY` index the area will be. * @param layer The tile layer to use. If not given the current layer is used. */ - swapByIndex(tileA: number, tileB: number, tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + swapByIndex(tileA: number, tileB: number, tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the @@ -92796,7 +107837,7 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - tileToWorldX(tileX: number, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): number; + tileToWorldX(tileX: number, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): number | null; /** * Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the @@ -92807,7 +107848,7 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - tileToWorldY(tileY: number, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): number; + tileToWorldY(tileY: number, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): number | null; /** * Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the @@ -92821,7 +107862,27 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - tileToWorldXY(tileX: number, tileY: number, vec2?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Math.Vector2; + tileToWorldXY(tileX: number, tileY: number, vec2?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Math.Vector2 | null; + + /** + * Returns an array of Vector2s where each entry corresponds to the corner of the requested tile. + * + * The `tileX` and `tileY` parameters are in tile coordinates, not world coordinates. + * + * The corner coordinates are in world space, having factored in TilemapLayer scale, position + * and the camera, if given. + * + * The size of the array will vary based on the orientation of the map. For example an + * orthographic map will return an array of 4 vectors, where-as a hexagonal map will, + * of course, return an array of 6 corner vectors. + * + * If no layer is specified, the maps current layer is used. + * @param tileX The x coordinate, in tiles, not pixels. + * @param tileY The y coordinate, in tiles, not pixels. + * @param camera The Camera to use when calculating the tile index from the world values. + * @param layer The tile layer to use. If not given the current layer is used. + */ + getTileCorners(tileX: number, tileY: number, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Math.Vector2[] | null; /** * Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the @@ -92846,31 +107907,39 @@ declare namespace Phaser { * @param height How many tiles tall from the `tileY` index the area will be. * @param layer The tile layer to use. If not given the current layer is used. */ - weightedRandomize(weightedIndexes: object[], tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap; + weightedRandomize(weightedIndexes: object[], tileX?: number, tileY?: number, width?: number, height?: number, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tilemap | null; /** * 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. + * + * You cannot call this method for Isometric or Hexagonal tilemaps as they require + * both `worldX` and `worldY` values to determine the correct tile, instead you + * should use the `worldToTileXY` method. * @param worldX The x coordinate to be converted, in pixels, not tiles. * @param snapToFloor Whether or not to round the tile coordinate down to the nearest integer. * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - worldToTileX(worldX: number, snapToFloor?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): number; + worldToTileX(worldX: number, snapToFloor?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): number | null; /** * 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. + * + * You cannot call this method for Isometric or Hexagonal tilemaps as they require + * both `worldX` and `worldY` values to determine the correct tile, instead you + * should use the `worldToTileXY` method. * @param worldY The y coordinate to be converted, in pixels, not tiles. * @param snapToFloor Whether or not to round the tile coordinate down to the nearest integer. * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - worldToTileY(worldY: number, snapToFloor?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): number; + worldToTileY(worldY: number, snapToFloor?: boolean, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): number | null; /** * Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the @@ -92885,7 +107954,7 @@ declare namespace Phaser { * @param camera The Camera to use when calculating the tile index from the world values. * @param layer The tile layer to use. If not given the current layer is used. */ - worldToTileXY(worldX: number, worldY: number, snapToFloor?: boolean, vec2?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Math.Vector2; + worldToTileXY(worldX: number, worldY: number, snapToFloor?: boolean, vec2?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera, layer?: string | number | Phaser.Tilemaps.TilemapLayer): Phaser.Math.Vector2 | null; /** * Removes all layer data from this Tilemap and nulls the scene reference. This will destroy any @@ -92899,7 +107968,7 @@ declare namespace Phaser { * 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 implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.ComputedSize, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { + class TilemapLayer extends Phaser.GameObjects.GameObject implements Phaser.GameObjects.Components.Alpha, Phaser.GameObjects.Components.BlendMode, Phaser.GameObjects.Components.ComputedSize, Phaser.GameObjects.Components.Depth, Phaser.GameObjects.Components.Flip, Phaser.GameObjects.Components.GetBounds, Phaser.GameObjects.Components.Mask, Phaser.GameObjects.Components.Origin, Phaser.GameObjects.Components.Pipeline, Phaser.GameObjects.Components.PostPipeline, Phaser.GameObjects.Components.ScrollFactor, Phaser.GameObjects.Components.Transform, Phaser.GameObjects.Components.Visible { /** * * @param scene The Scene to which this Game Object belongs. @@ -93004,6 +108073,26 @@ declare namespace Phaser { */ gidMap: Phaser.Tilemaps.Tileset[]; + /** + * The horizontal origin of this Tilemap Layer. + */ + readonly originX: number; + + /** + * The vertical origin of this Tilemap Layer. + */ + readonly originY: number; + + /** + * The horizontal display origin of this Tilemap Layer. + */ + readonly displayOriginX: number; + + /** + * The vertical display origin of this Tilemap Layer. + */ + readonly displayOriginY: number; + /** * Sets the rendering (draw) order of the tiles in this layer. * @@ -93059,7 +108148,7 @@ declare namespace Phaser { * @param scene The Scene to create the Sprites within. * @param camera The Camera to use when determining the world XY */ - createFromTiles(indexes: number | any[], replacements: number | any[], spriteConfig?: Phaser.Types.GameObjects.Sprite.SpriteConfig, scene?: Phaser.Scene, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.GameObjects.Sprite[]; + createFromTiles(indexes: number | any[], replacements: number | any[] | undefined, spriteConfig?: Phaser.Types.GameObjects.Sprite.SpriteConfig, scene?: Phaser.Scene, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.GameObjects.Sprite[]; /** * Returns the tiles in the given layer that are within the cameras viewport. @@ -93135,7 +108224,7 @@ declare namespace Phaser { * @param height How many tiles tall from the `tileY` index the area will be. * @param filteringOptions Optional filters to apply when getting the tiles. */ - findTile(callback: FindTileCallback, context?: object, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions): Phaser.Tilemaps.Tile; + findTile(callback: FindTileCallback, context?: object, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions): Phaser.Tilemaps.Tile | null; /** * For each tile in the given rectangular area (in tile coordinates) of the layer, run the given @@ -93150,6 +108239,26 @@ declare namespace Phaser { */ forEachTile(callback: EachTileCallback, context?: object, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions): this; + /** + * Sets an additive tint on each Tile within the given area. + * + * The tint works by taking the pixel color values from the tileset texture, and then + * multiplying it by the color value of the tint. + * + * If no area values are given then all tiles will be tinted to the given color. + * + * To remove a tint call this method with either no parameters, or by passing white `0xffffff` as the tint color. + * + * If a tile already has a tint set then calling this method will override that. + * @param tint The tint color being applied to each tile within the region. Given as a hex value, i.e. `0xff0000` for red. Set to white (`0xffffff`) to reset the tint. Default 0xffffff. + * @param tileX The left most tile index (in tile coordinates) to use as the origin of the area to search. + * @param tileY The top most tile index (in tile coordinates) to use as the origin of the area to search. + * @param width How many tiles wide from the `tileX` index the area will be. + * @param height How many tiles tall from the `tileY` index the area will be. + * @param filteringOptions Optional filters to apply when getting the tiles. + */ + setTint(tint?: number, tileX?: number, tileY?: number, width?: number, height?: number, filteringOptions?: Phaser.Types.Tilemaps.FilteringOptions): this; + /** * Gets a tile at the given tile coordinates from the given layer. * @param tileX X position to get the tile from (given in tile units, not pixels). @@ -93167,6 +108276,16 @@ declare namespace Phaser { */ getTileAtWorldXY(worldX: number, worldY: number, nonNull?: boolean, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Tilemaps.Tile; + /** + * Gets a tile at the given world coordinates from the given isometric layer. + * @param worldX X position to get the tile from (given in pixels) + * @param worldY Y position to get the tile from (given in pixels) + * @param originTop Which is the active face of the isometric tile? The top (default, true), or the base? (false) Default true. + * @param nonNull If true, function won't return null for empty tiles, but a Tile object with an index of -1. Default false. + * @param camera The Camera to use when calculating the tile index from the world values. + */ + getIsoTileAtWorldXY(worldX: number, worldY: number, originTop?: boolean, nonNull?: boolean, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Tilemaps.Tile; + /** * Gets the tiles in the given rectangular area (in tile coordinates) of the layer. * @param tileX The left most tile index (in tile coordinates) to use as the origin of the area. @@ -93464,6 +108583,23 @@ declare namespace Phaser { */ tileToWorldXY(tileX: number, tileY: number, point?: Phaser.Math.Vector2, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2; + /** + * Returns an array of Vector2s where each entry corresponds to the corner of the requested tile. + * + * The `tileX` and `tileY` parameters are in tile coordinates, not world coordinates. + * + * The corner coordinates are in world space, having factored in TilemapLayer scale, position + * and the camera, if given. + * + * The size of the array will vary based on the orientation of the map. For example an + * orthographic map will return an array of 4 vectors, where-as a hexagonal map will, + * of course, return an array of 6 corner vectors. + * @param tileX The x coordinate, in tiles, not pixels. + * @param tileY The y coordinate, in tiles, not pixels. + * @param camera The Camera to use when calculating the tile index from the world values. + */ + getTileCorners(tileX: number, tileY: number, camera?: Phaser.Cameras.Scene2D.Camera): Phaser.Math.Vector2[] | null; + /** * 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 @@ -93489,6 +108625,10 @@ declare namespace Phaser { /** * Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the * layers position, scale and scroll. + * + * You cannot call this method for Isometric or Hexagonal tilemaps as they require + * both `worldX` and `worldY` values to determine the correct tile, instead you + * should use the `worldToTileXY` method. * @param worldX The x coordinate to be converted, in pixels, not tiles. * @param snapToFloor Whether or not to round the tile coordinate down to the nearest integer. * @param camera The Camera to use when calculating the tile index from the world values. @@ -93498,6 +108638,10 @@ declare namespace Phaser { /** * Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the * layers position, scale and scroll. + * + * You cannot call this method for Isometric or Hexagonal tilemaps as they require + * both `worldX` and `worldY` values to determine the correct tile, instead you + * should use the `worldToTileXY` method. * @param worldY The y coordinate to be converted, in pixels, not tiles. * @param snapToFloor Whether or not to round the tile coordinate down to the nearest integer. * @param camera The Camera to use when calculating the tile index from the world values. @@ -93580,6 +108724,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -93594,7 +108739,7 @@ declare namespace Phaser { * reasons try to be careful about the construction of your Scene and the frequency of which blend modes * are used. */ - blendMode: Phaser.BlendModes | string; + blendMode: Phaser.BlendModes | string | number; /** * Sets the Blend Mode being used by this Game Object. @@ -93603,6 +108748,7 @@ declare namespace Phaser { * * Under WebGL only the following Blend Modes are available: * + * * NORMAL * * ADD * * MULTIPLY * * SCREEN @@ -93616,9 +108762,9 @@ declare namespace Phaser { * on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these * reasons try to be careful about the construction of your Scene and the frequency in which blend modes * are used. - * @param value The BlendMode value. Either a string or a CONST. + * @param value The BlendMode value. Either a string, a CONST or a number. */ - setBlendMode(value: string | Phaser.BlendModes): this; + setBlendMode(value: string | Phaser.BlendModes | number): this; /** * The native (un-scaled) width of this Game Object. @@ -93681,7 +108827,7 @@ declare namespace Phaser { setDisplaySize(width: number, height: number): this; /** - * The depth of this Game Object within the Scene. + * The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type. * * The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order * of Game Objects, without actually moving their position in the display list. @@ -93703,7 +108849,7 @@ declare namespace Phaser { * value will always render in front of one with a lower value. * * Setting the depth will queue a depth sort event within the Scene. - * @param value The depth of this Game Object. + * @param value The depth of this Game Object. Ensure this value is only ever a number data-type. */ setDepth(value: number): this; @@ -93773,111 +108919,164 @@ declare namespace Phaser { /** * Gets the center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. + * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getCenter(output?: O): O; + getCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopLeft(output?: O, includeParent?: boolean): O; + getTopLeft(output?: O, includeParent?: boolean): O; /** * Gets the top-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopCenter(output?: O, includeParent?: boolean): O; + getTopCenter(output?: O, includeParent?: boolean): O; /** * Gets the top-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getTopRight(output?: O, includeParent?: boolean): O; + getTopRight(output?: O, includeParent?: boolean): O; /** * Gets the left-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getLeftCenter(output?: O, includeParent?: boolean): O; + getLeftCenter(output?: O, includeParent?: boolean): O; /** * Gets the right-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getRightCenter(output?: O, includeParent?: boolean): O; + getRightCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-left corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomLeft(output?: O, includeParent?: boolean): O; + getBottomLeft(output?: O, includeParent?: boolean): O; /** * Gets the bottom-center coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomCenter(output?: O, includeParent?: boolean): O; + getBottomCenter(output?: O, includeParent?: boolean): O; /** * Gets the bottom-right corner coordinate of this Game Object, regardless of origin. - * The returned point is calculated in local space and does not factor in any parent containers + * + * The returned point is calculated in local space and does not factor in any parent Containers, + * unless the `includeParent` argument is set to `true`. * @param output An object to store the values in. If not provided a new Vector2 will be created. * @param includeParent If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector? Default false. */ - getBottomRight(output?: O, includeParent?: boolean): O; + getBottomRight(output?: O, includeParent?: boolean): O; /** * Gets the bounds of this Game Object, regardless of origin. + * * The values are stored and returned in a Rectangle, or Rectangle-like, object. * @param output An object to store the values in. If not provided a new Rectangle will be created. */ getBounds(output?: O): O; /** - * The horizontal origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the left of the Game Object. + * The Mask this Game Object is using during render. */ - originX: number; + mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask; /** - * The vertical origin of this Game Object. - * The origin maps the relationship between the size and position of the Game Object. - * The default value is 0.5, meaning all Game Objects are positioned based on their center. - * Setting the value to 0 means the position now relates to the top of the Game Object. + * Sets the mask that this Game Object will use to render with. + * + * The mask must have been previously created and can be either a GeometryMask or a BitmapMask. + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * If a mask is already set on this Game Object it will be immediately replaced. + * + * Masks are positioned in global space and are not relative to the Game Object to which they + * are applied. The reason for this is that multiple Game Objects can all share the same mask. + * + * Masks have no impact on physics or input detection. They are purely a rendering component + * that allows you to limit what is visible during the render pass. + * @param mask The mask this Game Object will use when rendering. */ - originY: number; + setMask(mask: Phaser.Display.Masks.BitmapMask | Phaser.Display.Masks.GeometryMask): this; /** - * The horizontal display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * Clears the mask that this Game Object was using. + * @param destroyMask Destroy the mask before clearing it? Default false. */ - displayOriginX: number; + clearMask(destroyMask?: boolean): this; /** - * The vertical display origin of this Game Object. - * The origin is a normalized value between 0 and 1. - * The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin. + * Creates and returns a Bitmap Mask. This mask can be used by any Game Object, + * including this one, or a Dynamic Texture. + * + * Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas. + * + * To create the mask you need to pass in a reference to a renderable Game Object. + * A renderable Game Object is one that uses a texture to render with, such as an + * Image, Sprite, Render Texture or BitmapText. + * + * If you do not provide a renderable object, and this Game Object has a texture, + * it will use itself as the object. This means you can call this method to create + * a Bitmap Mask from any renderable texture-based Game Object. + * @param maskObject The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments. + * @param x If creating a Game Object, the horizontal position in the world. + * @param y If creating a Game Object, the vertical position in the world. + * @param texture If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager. + * @param frame If creating a Game Object, an optional frame from the Texture this Game Object is rendering with. */ - displayOriginY: number; + createBitmapMask(maskObject?: Phaser.GameObjects.GameObject | Phaser.Textures.DynamicTexture, x?: number, y?: number, texture?: string | Phaser.Textures.Texture, frame?: string | number | Phaser.Textures.Frame): Phaser.Display.Masks.BitmapMask; + + /** + * Creates and returns a Geometry Mask. This mask can be used by any Game Object, + * including this one. + * + * To create the mask you need to pass in a reference to a Graphics Game Object. + * + * If you do not provide a graphics object, and this Game Object is an instance + * of a Graphics object, then it will use itself to create the mask. + * + * This means you can call this method to create a Geometry Mask from any Graphics Game Object. + * @param graphics A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask. + */ + createGeometryMask(graphics?: Phaser.GameObjects.Graphics | Phaser.GameObjects.Shape): Phaser.Display.Masks.GeometryMask; /** * Sets the origin of this Game Object. @@ -93919,6 +109118,51 @@ declare namespace Phaser { */ pipeline: Phaser.Renderer.WebGL.WebGLPipeline; + /** + * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. + */ + pipelineData: object; + + /** + * Sets the initial WebGL Pipeline of this Game Object. + * + * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + */ + initPipeline(pipeline?: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + + /** + * Sets the main WebGL Pipeline of this Game Object. + * + * Also sets the `pipelineData` property, if the parameter is given. + * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * @param pipelineData Optional pipeline data object that is set in to the `pipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + */ + setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + + /** + * Adds an entry to the `pipelineData` object belonging to this Game Object. + * + * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. + * + * If `value` is undefined, and `key` exists, `key` is removed from the data object. + * @param key The key of the pipeline data to set, update, or delete. + * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. + */ + setPipelineData(key: string, value?: any): this; + + /** + * Resets the WebGL Pipeline of this Game Object back to the default it was created with. + * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + */ + resetPipeline(resetData?: boolean): boolean; + + /** + * Gets the name of the WebGL Pipeline this Game Object is currently using. + */ + getPipelineName(): string; + /** * Does this Game Object have any Post Pipelines set? */ @@ -93937,27 +109181,65 @@ declare namespace Phaser { /** * An object to store pipeline specific data in, to be read by the pipelines this Game Object uses. */ - pipelineData: object; + postPipelineData: object; /** - * Sets the initial WebGL Pipeline of this Game Object. + * The Pre FX component of this Game Object. * - * This should only be called during the instantiation of the Game Object. After that, use `setPipeline`. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: + * + * ```js + * const player = this.add.sprite(); + * player.preFX.addBloom(); + * ``` + * + * Only the following Game Objects support Pre FX: + * + * * Image + * * Sprite + * * TileSprite + * * Text + * * RenderTexture + * * Video + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. */ - initPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline): boolean; + preFX: Phaser.GameObjects.Components.FX | null; /** - * Sets the main WebGL Pipeline of this Game Object. + * The Post FX component of this Game Object. * - * Also sets the `pipelineData` property, if the parameter is given. + * This component allows you to apply a variety of built-in effects to this Game Object, such + * as glow, blur, bloom, displacements, vignettes and more. You access them via this property, + * for example: * - * Both the pipeline and post pipelines share the same pipeline data object. - * @param pipeline Either the string-based name of the pipeline, or a pipeline instance to set. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * ```js + * const player = this.add.sprite(); + * player.postFX.addBloom(); + * ``` + * + * All FX are WebGL only and do not have Canvas counterparts. + * + * Please see the FX Class for more details and available methods. + * + * This property is always `null` until the `initPostPipeline` method is called. */ - setPipeline(pipeline: string | Phaser.Renderer.WebGL.WebGLPipeline, pipelineData?: object, copyData?: boolean): this; + postFX: Phaser.GameObjects.Components.FX; + + /** + * This should only be called during the instantiation of the Game Object. + * + * It is called by default by all core Game Objects and doesn't need + * calling again. + * + * After that, use `setPostPipeline`. + * @param preFX Does this Game Object support Pre FX? Default false. + */ + initPostPipeline(preFX?: boolean): void; /** * Sets one, or more, Post Pipelines on this Game Object. @@ -93973,27 +109255,23 @@ declare namespace Phaser { * If you call this method multiple times, the new pipelines will be appended to any existing * post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required. * - * You can optionally also sets the `pipelineData` property, if the parameter is given. - * - * Both the pipeline and post pipelines share the pipeline data object together. + * You can optionally also set the `postPipelineData` property, if the parameter is given. * @param pipelines Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them. - * @param pipelineData Optional pipeline data object that is _deep copied_ into the `pipelineData` property of this Game Object. - * @param copyData Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. + * @param pipelineData Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object. + * @param copyData Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead. Default true. */ setPostPipeline(pipelines: string | string[] | Function | Function[] | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[], pipelineData?: object, copyData?: boolean): this; /** - * Adds an entry to the `pipelineData` object belonging to this Game Object. + * Adds an entry to the `postPipelineData` object belonging to this Game Object. * * If the 'key' already exists, its value is updated. If it doesn't exist, it is created. * * If `value` is undefined, and `key` exists, `key` is removed from the data object. - * - * Both the pipeline and post pipelines share the pipeline data object together. * @param key The key of the pipeline data to set, update, or delete. * @param value The value to be set with the key. If `undefined` then `key` will be deleted from the object. */ - setPipelineData(key: string, value?: any): this; + setPostPipelineData(key: string, value?: any): this; /** * Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it. @@ -94001,17 +109279,10 @@ declare namespace Phaser { */ getPostPipeline(pipeline: string | Function | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): Phaser.Renderer.WebGL.Pipelines.PostFXPipeline | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]; - /** - * Resets the WebGL Pipeline of this Game Object back to the default it was created with. - * @param resetPostPipelines Reset all of the post pipelines? Default false. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. - */ - resetPipeline(resetPostPipelines?: boolean, resetData?: boolean): boolean; - /** * Resets the WebGL Post Pipelines of this Game Object. It does this by calling * the `destroy` method on each post pipeline and then clearing the local array. - * @param resetData Reset the `pipelineData` object to being an empty object? Default false. + * @param resetData Reset the `postPipelineData` object to being an empty object? Default false. */ resetPostPipeline(resetData?: boolean): void; @@ -94024,9 +109295,13 @@ declare namespace Phaser { removePostPipeline(pipeline: string | Phaser.Renderer.WebGL.Pipelines.PostFXPipeline): this; /** - * Gets the name of the WebGL Pipeline this Game Object is currently using. + * Removes all Pre and Post FX Controllers from this Game Object. + * + * If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead. + * + * If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead. */ - getPipelineName(): string; + clearFX(): this; /** * The horizontal scroll factor of this Game Object. @@ -94087,6 +109362,11 @@ declare namespace Phaser { */ setScrollFactor(x: number, y?: number): this; + /** + * A property indicating that a Game Object has this component. + */ + readonly hasTransformComponent: boolean; + /** * The x position of this Game Object. */ @@ -94193,10 +109473,10 @@ declare namespace Phaser { /** * Sets the scale of this Game Object. - * @param x The horizontal scale of this Game Object. + * @param x The horizontal scale of this Game Object. Default 1. * @param y The vertical scale of this Game Object. If not set it will use the `x` value. Default x. */ - setScale(x: number, y?: number): this; + setScale(x?: number, y?: number): this; /** * Sets the x position of this Game Object. @@ -94279,7 +109559,7 @@ declare namespace Phaser { } /** - * A Tileset is a combination of an image containing the tiles and a container for data about + * A Tileset is a combination of a single image containing the tiles and a container for data about * each tile. */ class Tileset { @@ -94293,10 +109573,10 @@ declare namespace Phaser { * @param tileSpacing The spacing between each tile in the sheet (in pixels). Default 0. * @param tileProperties Custom properties defined per tile in the Tileset. * These typically are custom properties created in Tiled when editing a tileset. Default {}. - * @param tileData Data stored per tile. These typically are created in Tiled - * when editing a tileset, e.g. from Tiled's tile collision editor or terrain editor. Default {}. + * @param tileData Data stored per tile. These typically are created in Tiled when editing a tileset, e.g. from Tiled's tile collision editor or terrain editor. Default {}. + * @param tileOffset Tile texture drawing offset. Default {x: 0, y: 0}. */ - constructor(name: string, firstgid: number, tileWidth?: number, tileHeight?: number, tileMargin?: number, tileSpacing?: number, tileProperties?: object, tileData?: object); + constructor(name: string, firstgid: number, tileWidth?: number, tileHeight?: number, tileMargin?: number, tileSpacing?: number, tileProperties?: object, tileData?: object, tileOffset?: object); /** * The name of the Tileset. @@ -94340,15 +109620,21 @@ declare namespace Phaser { */ tileData: object; + /** + * Controls the drawing offset from the tile origin. + * Defaults to 0x0, no offset. + */ + tileOffset: Phaser.Math.Vector2; + /** * The cached image that contains the individual tiles. Use setImage to set. */ - readonly image: Phaser.Textures.Texture; + readonly image: Phaser.Textures.Texture | null; /** * The gl texture used by the WebGL renderer. */ - readonly glTexture: WebGLTexture; + readonly glTexture: WebGLTexture | null; /** * The number of tile rows in the the tileset. @@ -94376,7 +109662,7 @@ declare namespace Phaser { * contained in this Tileset. This is typically defined in Tiled under the Tileset editor. * @param tileIndex The unique id of the tile across all tilesets in the map. */ - getTileProperties(tileIndex: number): object | undefined; + getTileProperties(tileIndex: number): object | undefined | null; /** * Get a tile's data that is stored in the Tileset. Returns null if tile index is not contained @@ -94391,7 +109677,7 @@ declare namespace Phaser { * contained in this Tileset. This is typically defined within Tiled's tileset collision editor. * @param tileIndex The unique id of the tile across all tilesets in the map. */ - getTileCollisionGroup(tileIndex: number): object; + getTileCollisionGroup(tileIndex: number): object | null; /** * Returns true if and only if this Tileset contains the given tile index. @@ -94404,7 +109690,7 @@ declare namespace Phaser { * Returns null if tile index is not contained in this Tileset. * @param tileIndex The unique id of the tile across all tilesets in the map. */ - getTileTextureCoordinates(tileIndex: number): object; + getTileTextureCoordinates(tileIndex: number): object | null; /** * Sets the image associated with this Tileset and updates the tile data (rows, columns, etc.). @@ -94461,103 +109747,379 @@ declare namespace Phaser { /** * The Clock is a Scene plugin which creates and updates Timer Events for its Scene. */ - class Clock { + class Clock { + /** + * + * @param scene The Scene which owns this Clock. + */ + constructor(scene: Phaser.Scene); + + /** + * The Scene which owns this Clock. + */ + scene: Phaser.Scene; + + /** + * The Scene Systems object of the Scene which owns this Clock. + */ + systems: Phaser.Scenes.Systems; + + /** + * The current time of the Clock, in milliseconds. + * + * If accessed externally, this is equivalent to the `time` parameter normally passed to a Scene's `update` method. + */ + now: number; + + /** + * The time the Clock (and Scene) started, in milliseconds. + * + * This can be compared to the `time` parameter passed to a Scene's `update` method. + */ + startTime: number; + + /** + * The scale of the Clock's time delta. + * + * The time delta is the time elapsed between two consecutive frames and influences the speed of time for this Clock and anything which uses it, such as its Timer Events. Values higher than 1 increase the speed of time, while values smaller than 1 decrease it. A value of 0 freezes time and is effectively equivalent to pausing the Clock. + */ + timeScale: number; + + /** + * Whether the Clock is paused (`true`) or active (`false`). + * + * When paused, the Clock will not update any of its Timer Events, thus freezing time. + */ + paused: boolean; + + /** + * Creates a Timer Event and adds it to this Clock at the start of the next frame. + * + * You can pass in either a `TimerEventConfig` object, from with a new `TimerEvent` will + * be created, or you can pass in a `TimerEvent` instance. + * + * If passing an instance please make sure that this instance hasn't been used before. + * If it has ever entered a 'completed' state then it will no longer be suitable to + * run again. + * + * Also, if the `TimerEvent` instance is being used by _another_ Clock (in another Scene) + * it will still be updated by that Clock as well, so be careful when using this feature. + * @param config The configuration for the Timer Event, or an existing Timer Event object. + */ + addEvent(config: Phaser.Time.TimerEvent | Phaser.Types.Time.TimerEventConfig): Phaser.Time.TimerEvent; + + /** + * Creates a Timer Event and adds it to the Clock at the start of the frame. + * + * This is a shortcut for {@link #addEvent} which can be shorter and is compatible with the syntax of the GreenSock Animation Platform (GSAP). + * @param delay The delay of the function call, in milliseconds. + * @param callback The function to call after the delay expires. + * @param args The arguments to call the function with. + * @param callbackScope The scope (`this` object) to call the function with. + */ + delayedCall(delay: number, callback: Function, args?: any[], callbackScope?: any): Phaser.Time.TimerEvent; + + /** + * Clears and recreates the array of pending Timer Events. + */ + clearPendingEvents(): this; + + /** + * Removes the given Timer Event, or an array of Timer Events, from this Clock. + * + * The events are removed from all internal lists (active, pending and removal), + * freeing the event up to be re-used. + * @param events The Timer Event, or an array of Timer Events, to remove from this Clock. + */ + removeEvent(events: Phaser.Time.TimerEvent | Phaser.Time.TimerEvent[]): this; + + /** + * Schedules all active Timer Events for removal at the start of the frame. + */ + removeAllEvents(): this; + + /** + * Updates the arrays of active and pending Timer Events. Called at the start of the frame. + * @param time The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ + preUpdate(time: number, delta: number): void; + + /** + * Updates the Clock's internal time and all of its Timer Events. + * @param time The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ + update(time: number, delta: number): void; + + } + + /** + * A Timeline is a way to schedule events to happen at specific times in the future. + * + * You can think of it as an event sequencer for your game, allowing you to schedule the + * running of callbacks, events and other actions at specific times in the future. + * + * A Timeline is a Scene level system, meaning you can have as many Timelines as you like, each + * belonging to a different Scene. You can also have multiple Timelines running at the same time. + * + * If the Scene is paused, the Timeline will also pause. If the Scene is destroyed, the Timeline + * will be automatically destroyed. However, you can control the Timeline directly, pausing, + * resuming and stopping it at any time. + * + * Create an instance of a Timeline via the Game Object Factory: + * + * ```js + * const timeline = this.add.timeline(); + * ``` + * + * The Timeline always starts paused. You must call `play` on it to start it running. + * + * You can also pass in a configuration object on creation, or an array of them: + * + * ```js + * const timeline = this.add.timeline({ + * at: 1000, + * run: () => { + * this.add.sprite(400, 300, 'logo'); + * } + * }); + * + * timeline.play(); + * ``` + * + * In this example we sequence a few different events: + * + * ```js + * const timeline = this.add.timeline([ + * { + * at: 1000, + * run: () => { this.logo = this.add.sprite(400, 300, 'logo'); }, + * sound: 'TitleMusic' + * }, + * { + * at: 2500, + * tween: { + * targets: this.logo, + * y: 600, + * yoyo: true + * }, + * sound: 'Explode' + * }, + * { + * at: 8000, + * event: 'HURRY_PLAYER', + * target: this.background, + * set: { + * tint: 0xff0000 + * } + * } + * ]); + * + * timeline.play(); + * ``` + * + * There are lots of options available to you via the configuration object. See the + * {@link Phaser.Types.Time.TimelineEventConfig} typedef for more details. + */ + class Timeline { /** * - * @param scene The Scene which owns this Clock. + * @param scene The Scene which owns this Timeline. + * @param config The configuration object for this Timeline Event, or an array of them. */ - constructor(scene: Phaser.Scene); + constructor(scene: Phaser.Scene, config: Phaser.Types.Time.TimelineEventConfig | Phaser.Types.Time.TimelineEventConfig[]); /** - * The Scene which owns this Clock. + * The Scene to which this Timeline belongs. */ scene: Phaser.Scene; /** - * The Scene Systems object of the Scene which owns this Clock. + * A reference to the Scene Systems. */ systems: Phaser.Scenes.Systems; /** - * The current time of the Clock, in milliseconds. + * The elapsed time counter. * - * If accessed externally, this is equivalent to the `time` parameter normally passed to a Scene's `update` method. + * Treat this as read-only. */ - now: number; + elapsed: number; /** - * The scale of the Clock's time delta. + * Whether the Timeline is running (`true`) or active (`false`). * - * The time delta is the time elapsed between two consecutive frames and influences the speed of time for this Clock and anything which uses it, such as its Timer Events. Values higher than 1 increase the speed of time, while values smaller than 1 decrease it. A value of 0 freezes time and is effectively equivalent to pausing the Clock. + * When paused, the Timeline will not run any of its actions. + * + * By default a Timeline is always paused and should be started by + * calling the `Timeline.play` method. + * + * You can use the `Timeline.pause` and `Timeline.resume` methods to control + * this value in a chainable way. */ - timeScale: number; + paused: boolean; /** - * Whether the Clock is paused (`true`) or active (`false`). + * Whether the Timeline is complete (`true`) or not (`false`). * - * When paused, the Clock will not update any of its Timer Events, thus freezing time. + * A Timeline is considered complete when all of its events have been run. + * + * If you wish to restart a Timeline after it has completed, you can do so + * by calling the `Timeline.restart` method. + * + * You can also use the `Timeline.stop` method to stop a running Timeline, + * at any point, without resetting it. */ - paused: boolean; + complete: boolean; /** - * Creates a Timer Event and adds it to this Clock at the start of the next frame. + * The total number of events that have been run. * - * You can pass in either a `TimerEventConfig` object, from with a new `TimerEvent` will - * be created, or you can pass in a `TimerEvent` instance. + * This value is reset to zero if the Timeline is restarted. * - * If passing an instance please make sure that this instance hasn't been used before. - * If it has ever entered a 'completed' state then it will no longer be suitable to - * run again. + * Treat this as read-only. + */ + totalComplete: number; + + /** + * An array of all the Timeline Events. + */ + events: Phaser.Types.Time.TimelineEvent[]; + + /** + * Updates the elapsed time counter, if this Timeline is not paused. + * @param time The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ + preUpdate(time: number, delta: number): void; + + /** + * Called automatically by the Scene update step. * - * Also, if the `TimerEvent` instance is being used by _another_ Clock (in another Scene) - * it will still be updated by that Clock as well, so be careful when using this feature. - * @param config The configuration for the Timer Event, or an existing Timer Event object. + * Iterates through all of the Timeline Events and checks to see if they should be run. + * + * If they should be run, then the `TimelineEvent.action` callback is invoked. + * + * If the `TimelineEvent.once` property is `true` then the event is removed from the Timeline. + * + * If the `TimelineEvent.event` property is set then the Timeline emits that event. + * + * If the `TimelineEvent.run` property is set then the Timeline invokes that method. + * + * If the `TimelineEvent.target` property is set then the Timeline invokes the `run` method on that target. + * @param time The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. + * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. */ - addEvent(config: Phaser.Time.TimerEvent | Phaser.Types.Time.TimerEventConfig): Phaser.Time.TimerEvent; + update(time: number, delta: number): void; /** - * Creates a Timer Event and adds it to the Clock at the start of the frame. + * Starts this Timeline running. * - * This is a shortcut for {@link #addEvent} which can be shorter and is compatible with the syntax of the GreenSock Animation Platform (GSAP). - * @param delay The delay of the function call, in milliseconds. - * @param callback The function to call after the delay expires. - * @param args The arguments to call the function with. - * @param callbackScope The scope (`this` object) to call the function with. + * If the Timeline is already running and the `fromStart` parameter is `true`, + * then calling this method will reset the Timeline events as incomplete. + * + * If you wish to resume a paused Timeline, then use the `Timeline.resume` method instead. + * @param fromStart Reset this Timeline back to the start before playing. Default true. */ - delayedCall(delay: number, callback: Function, args?: any[], callbackScope?: any): Phaser.Time.TimerEvent; + play(fromStart?: boolean): this; /** - * Clears and recreates the array of pending Timer Events. + * Pauses this Timeline. + * + * To resume it again, call the `Timeline.resume` method or set the `Timeline.paused` property to `false`. + * + * If the Timeline is paused while processing the current game step, then it + * will carry on with all events that are due to run during that step and pause + * from the next game step. */ - clearPendingEvents(): this; + pause(): this; /** - * Removes the given Timer Event, or an array of Timer Events, from this Clock. + * Resumes this Timeline from a paused state. * - * The events are removed from all internal lists (active, pending and removal), - * freeing the event up to be re-used. - * @param events The Timer Event, or an array of Timer Events, to remove from this Clock. + * The Timeline will carry on from where it left off. + * + * If you need to reset the Timeline to the start, then call the `Timeline.reset` method. */ - removeEvent(events: Phaser.Time.TimerEvent | Phaser.Time.TimerEvent[]): this; + resume(): this; /** - * Schedules all active Timer Events for removal at the start of the frame. + * Stops this Timeline. + * + * This will set the `paused` and `complete` properties to `true`. + * + * If you wish to reset the Timeline to the start, then call the `Timeline.reset` method. */ - removeAllEvents(): this; + stop(): this; /** - * Updates the arrays of active and pending Timer Events. Called at the start of the frame. - * @param time The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + * Resets this Timeline back to the start. + * + * This will set the elapsed time to zero and set all events to be incomplete. + * + * If the Timeline had any events that were set to `once` that have already + * been removed, they will **not** be present again after calling this method. + * + * If the Timeline isn't currently running (i.e. it's paused or complete) then + * calling this method resets those states, the same as calling `Timeline.play(true)`. */ - preUpdate(time: number, delta: number): void; + reset(): this; /** - * Updates the Clock's internal time and all of its Timer Events. - * @param time The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + * Adds one or more events to this Timeline. + * + * You can pass in a single configuration object, or an array of them: + * + * ```js + * const timeline = this.add.timeline({ + * at: 1000, + * run: () => { + * this.add.sprite(400, 300, 'logo'); + * } + * }); + * ``` + * @param config The configuration object for this Timeline Event, or an array of them. */ - update(time: number, delta: number): void; + add(config: Phaser.Types.Time.TimelineEventConfig | Phaser.Types.Time.TimelineEventConfig[]): this; + + /** + * Removes all events from this Timeline, resets the elapsed time to zero + * and pauses the Timeline. + */ + clear(): this; + + /** + * Returns `true` if this Timeline is currently playing. + * + * A Timeline is playing if it is not paused or not complete. + */ + isPlaying(): boolean; + + /** + * Returns a number between 0 and 1 representing the progress of this Timeline. + * + * A value of 0 means the Timeline has just started, 0.5 means it's half way through, + * and 1 means it's complete. + * + * If the Timeline has no events, or all events have been removed, this will return 1. + * + * If the Timeline is paused, this will return the progress value at the time it was paused. + * + * Note that the value returned is based on the number of events that have been completed, + * not the 'duration' of the events (as this is unknown to the Timeline). + */ + getProgress(): number; + + /** + * Destroys this Timeline. + * + * This will remove all events from the Timeline and stop it from processing. + * + * This method is called automatically when the Scene shuts down, but you may + * also call it directly should you need to destroy the Timeline earlier. + */ + destroy(): void; } @@ -94715,7 +110277,7 @@ declare namespace Phaser { * @param key The key to look for in the `source` object. * @param defaultValue The default value to return if the `key` doesn't exist or if no `source` object is provided. */ - function GetBoolean(source: object, key: string, defaultValue: any): any; + function GetBoolean(source: object, key: string, defaultValue: boolean): boolean; /** * This internal function is used to return the correct ease function for a Tween. @@ -94726,6 +110288,14 @@ declare namespace Phaser { */ function GetEaseFunction(ease: string | Function, easeParams?: number[]): Function; + /** + * This internal function is used to return the correct interpolation function for a Tween. + * + * It can take a variety of input, including a string, or a custom function. + * @param interpolation The interpolation function to find. This can be either a string, or a custom function, or null. + */ + function GetInterpolationFunction(interpolation: string | Function | null): Function | null; + /** * Internal function used by the Tween Builder to create a function that will return * the given value from the source. @@ -94752,14 +110322,6 @@ declare namespace Phaser { */ function GetTargets(config: object): any[]; - /** - * Internal function used by the Timeline Builder. - * - * It returns an array of all tweens in the given timeline config. - * @param config The configuration object for the Timeline. - */ - function GetTweens(config: Phaser.Types.Tweens.TimelineBuilderConfig): Phaser.Tweens.Tween[]; - /** * Returns `getActive`, `getStart` and `getEnd` functions for a TweenData based on a target property and end value. * @@ -94774,7 +110336,7 @@ declare namespace Phaser { * * A function can be provided to allow greater control over the end value; it will receive the target * object being tweened, the name of the property being tweened, and the current value of the property - * as its arguments. + * as its arguments and must return a value. * * If both the starting and the ending values need to be controlled, an object with `getStart` and `getEnd` * callbacks, which will receive the same arguments, can be provided instead. If an object with a `value` @@ -94790,7 +110352,7 @@ declare namespace Phaser { * @param config Configuration for the new Tween. * @param defaults Tween configuration defaults. */ - function NumberTweenBuilder(parent: Phaser.Tweens.TweenManager | Phaser.Tweens.Timeline, config: Phaser.Types.Tweens.NumberTweenBuilderConfig, defaults: Phaser.Types.Tweens.TweenConfigDefaults): Phaser.Tweens.Tween; + function NumberTweenBuilder(parent: Phaser.Tweens.TweenManager, config: Phaser.Types.Tweens.NumberTweenBuilderConfig, defaults: Phaser.Types.Tweens.TweenConfigDefaults): Phaser.Tweens.Tween; /** * Creates a Stagger function to be used by a Tween property. @@ -94829,148 +110391,24 @@ declare namespace Phaser { */ function StaggerBuilder(value: number | number[], config?: Phaser.Types.Tweens.StaggerConfig): Function; - /** - * Builds a Timeline of Tweens based on a configuration object. - * @param manager The Tween Manager to which the Timeline will belong. - * @param config The configuration object for the Timeline. - */ - function TimelineBuilder(manager: Phaser.Tweens.TweenManager, config: Phaser.Types.Tweens.TimelineBuilderConfig): Phaser.Tweens.Timeline; - /** * Creates a new Tween. * @param parent The owner of the new Tween. * @param config Configuration for the new Tween. * @param defaults Tween configuration defaults. */ - function TweenBuilder(parent: Phaser.Tweens.TweenManager | Phaser.Tweens.Timeline, config: Phaser.Types.Tweens.TweenBuilderConfig | object, defaults: Phaser.Types.Tweens.TweenConfigDefaults): Phaser.Tweens.Tween; - - } - - namespace Events { - /** - * The Timeline Complete Event. - * - * This event is dispatched by a Tween Timeline when it completes playback. - * - * Listen to it from a Timeline instance using `Timeline.on('complete', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('complete', listener); - * timeline.play(); - * ``` - */ - const TIMELINE_COMPLETE: any; - - /** - * The Timeline Loop Event. - * - * This event is dispatched by a Tween Timeline every time it loops. - * - * Listen to it from a Timeline instance using `Timeline.on('loop', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * loop: 4, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('loop', listener); - * timeline.play(); - * ``` - */ - const TIMELINE_LOOP: any; - - /** - * The Timeline Pause Event. - * - * This event is dispatched by a Tween Timeline when it is paused. - * - * Listen to it from a Timeline instance using `Timeline.on('pause', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('pause', listener); - * // At some point later ... - * timeline.pause(); - * ``` - */ - const TIMELINE_PAUSE: any; - - /** - * The Timeline Resume Event. - * - * This event is dispatched by a Tween Timeline when it is resumed from a paused state. - * - * Listen to it from a Timeline instance using `Timeline.on('resume', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('resume', listener); - * // At some point later ... - * timeline.resume(); - * ``` - */ - const TIMELINE_RESUME: any; + function TweenBuilder(parent: Phaser.Tweens.TweenManager, config: Phaser.Types.Tweens.TweenBuilderConfig | object, defaults: Phaser.Types.Tweens.TweenConfigDefaults): Phaser.Tweens.Tween; /** - * The Timeline Start Event. - * - * This event is dispatched by a Tween Timeline when it starts. - * - * Listen to it from a Timeline instance using `Timeline.on('start', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('start', listener); - * timeline.play(); - * ``` + * Creates a new Tween Chain instance. + * @param parent The owner of the new Tween. + * @param config Configuration for the new Tween. */ - const TIMELINE_START: any; + function TweenChainBuilder(parent: Phaser.Tweens.TweenManager, config: Phaser.Types.Tweens.TweenChainBuilderConfig | object): Phaser.Tweens.TweenChain; - /** - * The Timeline Update Event. - * - * This event is dispatched by a Tween Timeline every time it updates, which can happen a lot of times per second, - * so be careful about listening to this event unless you absolutely require it. - * - * Listen to it from a Timeline instance using `Timeline.on('update', listener)`, i.e.: - * - * ```javascript - * var timeline = this.tweens.timeline({ - * targets: image, - * ease: 'Power1', - * duration: 3000, - * tweens: [ { x: 600 }, { y: 500 }, { x: 100 }, { y: 100 } ] - * }); - * timeline.on('update', listener); - * timeline.play(); - * ``` - */ - const TIMELINE_UPDATE: any; + } + namespace Events { /** * The Tween Active Event. * @@ -94983,16 +110421,20 @@ declare namespace Phaser { * Listen to it from a Tween instance using `Tween.on('active', listener)`, i.e.: * * ```javascript - * var tween = this.tweens.add({ + * var tween = this.tweens.create({ * targets: image, * x: 500, * ease: 'Power1', * duration: 3000 * }); * tween.on('active', listener); + * this.tweens.existing(tween); * ``` + * + * Note that this event is usually dispatched already by the time you call `this.tweens.add()`, and is + * meant for use with `tweens.create()` and/or `tweens.existing()`. */ - const TWEEN_ACTIVE: any; + const TWEEN_ACTIVE: string; /** * The Tween Complete Event. @@ -95016,7 +110458,7 @@ declare namespace Phaser { * tween.on('complete', listener); * ``` */ - const TWEEN_COMPLETE: any; + const TWEEN_COMPLETE: string; /** * The Tween Loop Event. @@ -95043,7 +110485,28 @@ declare namespace Phaser { * tween.on('loop', listener); * ``` */ - const TWEEN_LOOP: any; + const TWEEN_LOOP: string; + + /** + * The Tween Pause Event. + * + * This event is dispatched by a Tween when it is paused. + * + * Listen to it from a Tween instance using `Tween.on('pause', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * ease: 'Power1', + * duration: 3000, + * x: 600 + * }); + * tween.on('pause', listener); + * // At some point later ... + * tween.pause(); + * ``` + */ + const TWEEN_PAUSE: string; /** * The Tween Repeat Event. @@ -95070,7 +110533,28 @@ declare namespace Phaser { * tween.on('repeat', listener); * ``` */ - const TWEEN_REPEAT: any; + const TWEEN_REPEAT: string; + + /** + * The Tween Resume Event. + * + * This event is dispatched by a Tween when it is resumed from a paused state. + * + * Listen to it from a Tween instance using `Tween.on('resume', listener)`, i.e.: + * + * ```javascript + * var tween = this.tweens.add({ + * targets: image, + * ease: 'Power1', + * duration: 3000, + * x: 600 + * }); + * tween.on('resume', listener); + * // At some point later ... + * tween.resume(); + * ``` + */ + const TWEEN_RESUME: string; /** * The Tween Start Event. @@ -95093,7 +110577,7 @@ declare namespace Phaser { * tween.on('start', listener); * ``` */ - const TWEEN_START: any; + const TWEEN_START: string; /** * The Tween Stop Event. @@ -95112,7 +110596,7 @@ declare namespace Phaser { * tween.on('stop', listener); * ``` */ - const TWEEN_STOP: any; + const TWEEN_STOP: string; /** * The Tween Update Event. @@ -95135,7 +110619,7 @@ declare namespace Phaser { * tween.on('update', listener); * ``` */ - const TWEEN_UPDATE: any; + const TWEEN_UPDATE: string; /** * The Tween Yoyo Event. @@ -95163,792 +110647,1432 @@ declare namespace Phaser { * tween.on('yoyo', listener); * ``` */ - const TWEEN_YOYO: any; + const TWEEN_YOYO: string; } /** - * A Timeline combines multiple Tweens into one. Its overall behavior is otherwise similar to a single Tween. + * As the name implies, this is the base Tween class that both the Tween and TweenChain + * inherit from. It contains shared properties and methods common to both types of 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. + * Typically you would never instantiate this class directly, although you could certainly + * use it to create your own variation of Tweens from. */ - class Timeline extends Phaser.Events.EventEmitter { + class BaseTween extends Phaser.Events.EventEmitter { /** * - * @param manager The Tween Manager which owns this Timeline. + * @param parent A reference to the Tween Manager, or Tween Chain, that owns this Tween. */ - constructor(manager: Phaser.Tweens.TweenManager); + constructor(parent: Phaser.Tweens.TweenManager | Phaser.Tweens.TweenChain); /** - * The Tween Manager which owns this Timeline. + * A reference to the Tween Manager, or Tween Chain, that owns this Tween. */ - manager: Phaser.Tweens.TweenManager; + parent: Phaser.Tweens.TweenManager | Phaser.Tweens.TweenChain; /** - * A constant value which allows this Timeline to be easily identified as one. + * The main data array. For a Tween, this contains all of the `TweenData` objects, each + * containing a unique property and target that is being tweened. + * + * For a TweenChain, this contains an array of `Tween` instances, which are being played + * through in sequence. */ - isTimeline: boolean; + data: Phaser.Tweens.TweenData[] | Phaser.Tweens.Tween[]; /** - * An array of Tween objects, each containing a unique property and target being tweened. + * The cached size of the data array. */ - data: any[]; + totalData: number; /** - * The cached size of the data array. + * The time in milliseconds before the 'onStart' event fires. + * + * For a Tween, this is the shortest `delay` value across all of the TweenDatas it owns. + * For a TweenChain, it is whatever delay value was given in the configuration. */ - totalData: number; + startDelay: number; /** - * If true then duration, delay, etc values are all frame totals, rather than ms. + * Has this Tween started playback yet? + * + * This boolean is toggled when the Tween leaves the 'start delayed' state and begins running. */ - useFrames: boolean; + readonly hasStarted: boolean; /** - * 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. + * Scales the time applied to this Tween. 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. + * + * This value is multiplied by the `TweenManager.timeScale`. */ timeScale: number; /** - * 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) + * The number of times this Tween will loop. + * + * Can be -1 for an infinite loop, zero for none, or a positive integer. + * + * Typically this is set in the configuration object, but can also be set directly + * as long as this Tween is paused and hasn't started playback. + * + * When enabled it will play through ALL Tweens again. + * + * Use TweenData.repeat to loop a single element. */ loop: number; /** - * Time in ms/frames before this Timeline loops. + * The time in milliseconds before the Tween loops. + * + * Only used if `loop` is > 0. */ loopDelay: number; /** - * How many loops are left to run? + * Internal counter recording how many loops are left to run. */ loopCounter: number; /** - * Time in ms/frames before the 'onComplete' event fires. This never fires if loop = true (as it never completes) + * The time in milliseconds before the 'onComplete' event fires. + * + * This never fires if `loop = -1` as it never completes because it has been + * set to loop forever. */ completeDelay: number; /** - * Countdown timer value, as used by `loopDelay` and `completeDelay`. + * An internal countdown timer (used by loopDelay and completeDelay) */ countdown: number; /** - * The current state of the Timeline. + * The current state of the Tween. */ - state: number; + state: Phaser.Tweens.StateType; /** - * Does the Timeline start off paused? (if so it needs to be started with Timeline.play) + * Is the Tween currently paused? + * + * A paused Tween needs to be started with the `play` method, or resumed with the `resume` method. + * + * This property can be toggled at runtime if required. */ paused: boolean; /** - * Elapsed time in ms/frames of this run through of the Timeline. + * An object containing the different Tween callback functions. + * + * You can either set these in the Tween config, or by calling the `Tween.setCallback` method. + * + * The types available are: + * + * `onActive` - When the Tween is first created it moves to an 'active' state when added to the Tween Manager. 'Active' does not mean 'playing'. + * `onStart` - When the Tween starts playing after a delayed or paused state. This will happen at the same time as `onActive` if the tween has no delay and isn't paused. + * `onLoop` - When a Tween loops, if it has been set to do so. This happens _after_ the `loopDelay` expires, if set. + * `onComplete` - When the Tween finishes playback fully. Never invoked if the Tween is set to repeat infinitely. + * `onStop` - Invoked only if the `Tween.stop` method is called. + * `onPause` - Invoked only if the `Tween.pause` method is called. Not invoked if the Tween Manager is paused. + * `onResume` - Invoked only if the `Tween.resume` method is called. Not invoked if the Tween Manager is resumed. + * + * The following types are also available and are invoked on a `TweenData` level - that is per-object, per-property, being tweened. + * + * `onYoyo` - When a TweenData starts a yoyo. This happens _after_ the `hold` delay expires, if set. + * `onRepeat` - When a TweenData repeats playback. This happens _after_ the `repeatDelay` expires, if set. + * `onUpdate` - When a TweenData updates a property on a source target during playback. */ - elapsed: number; + callbacks: Phaser.Types.Tweens.TweenCallbacks; /** - * Total elapsed time in ms/frames of the entire Timeline, including looping. + * The scope (or context) in which all of the callbacks are invoked. + * + * This defaults to be this Tween, but you can override this property + * to set it to whatever object you require. */ - totalElapsed: number; + callbackScope: any; /** - * Time in ms/frames for the whole Timeline to play through once, excluding loop amounts and loop delays. + * Will this Tween persist after playback? A Tween that persists will _not_ be destroyed by the + * Tween Manager, or when calling `Tween.stop`, and can be re-played as required. You can either + * set this property when creating the tween in the tween config, or set it _prior_ to playback. + * + * However, it's up to you to ensure you destroy persistent tweens when you are finished with them, + * or they will retain references you may no longer require and waste memory. + * + * By default, `Tweens` are set to _not_ persist, so they are automatically cleaned-up by + * the Tween Manager. But `TweenChains` _do_ persist by default, unless overridden in their + * config. This is because the type of situations you use a chain for is far more likely to + * need to be replayed again in the future, rather than disposed of. */ - duration: number; + persist: boolean; + + /** + * Sets the value of the time scale applied to this Tween. 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. + * + * This value is multiplied by the `TweenManager.timeScale`. + * @param value The time scale value to set. + */ + setTimeScale(value: number): this; /** - * Value between 0 and 1. The amount of progress through the Timeline, _excluding loops_. + * Gets the value of the time scale applied to this Tween. A value of 1 runs in real-time. + * A value of 0.5 runs 50% slower, and so on. */ - progress: number; + getTimeScale(): number; /** - * Time in ms/frames for all Tweens in this Timeline to complete (including looping) + * Checks if this Tween is currently playing. + * + * If this Tween is paused, or not active, this method will return false. */ - totalDuration: number; + isPlaying(): boolean; /** - * Value between 0 and 1. The amount through the entire Timeline, including looping. + * Checks if the Tween is currently paused. + * + * This is the same as inspecting the `BaseTween.paused` property directly. */ - totalProgress: number; + isPaused(): boolean; /** - * An object containing the different Tween callback functions. + * Pauses the Tween immediately. Use `resume` to continue playback. * - * You can either set these in the Tween config, or by calling the `Tween.setCallback` method. + * You can also toggle the `Tween.paused` boolean property, but doing so will not trigger the PAUSE event. + */ + pause(): this; + + /** + * Resumes the playback of a previously paused Tween. * - * `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. + * You can also toggle the `Tween.paused` boolean property, but doing so will not trigger the RESUME event. */ - callbacks: object; + resume(): this; /** - * The context in which all callbacks are invoked. + * Internal method that makes this Tween active within the TweenManager + * and emits the onActive event and callback. */ - callbackScope: any; + makeActive(): void; /** - * Internal method that will emit a Timeline based Event and invoke the given callback. - * @param event The Event to be dispatched. - * @param callback The callback to be invoked. Can be `null` or `undefined` to skip invocation. + * Internal method that handles this tween completing and emitting the onComplete event + * and callback. */ - dispatchTimelineEvent(event: Phaser.Types.Tweens.Event, callback: Function): void; + onCompleteHandler(): void; /** - * 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. + * Flags the Tween as being complete, whatever stage of progress it is at. * - * The value isn't used when calculating total duration of the tween, it's a run-time delta adjustment only. - * @param value The time scale value to set. + * If an `onComplete` callback has been defined it will automatically invoke it, unless a `delay` + * argument is provided, in which case the Tween will delay for that period of time before calling the callback. + * + * If you don't need a delay or don't have an `onComplete` callback then call `Tween.stop` instead. + * @param delay The time to wait before invoking the complete callback. If zero it will fire immediately. Default 0. */ - setTimeScale(value: number): this; + complete(delay?: number): 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. + * Flags the Tween as being complete only once the current loop has finished. + * + * This is a useful way to stop an infinitely looping tween once a complete cycle is over, + * rather than abruptly. + * + * If you don't have a loop then call `Tween.stop` instead. + * @param loops The number of loops that should finish before this tween completes. Zero means complete just the current loop. Default 0. */ - getTimeScale(): number; + completeAfterLoop(loops?: number): this; /** - * Check whether or not the Timeline is playing. + * Immediately removes this Tween from the TweenManager and all of its internal arrays, + * no matter what stage it is at. Then sets the tween state to `REMOVED`. + * + * You should dispose of your reference to this tween after calling this method, to + * free it from memory. If you no longer require it, call `Tween.destroy()` on it. */ - isPlaying(): boolean; + remove(): this; /** - * Creates a new Tween, based on the given Tween Config, and adds it to this Timeline. - * @param config The configuration object for the Tween. + * Stops the Tween immediately, whatever stage of progress it is at. + * + * If not a part of a Tween Chain it is also flagged for removal by the Tween Manager. + * + * If an `onStop` callback has been defined it will automatically invoke it. + * + * The Tween will be removed during the next game frame, but should be considered 'destroyed' from this point on. + * + * Typically, you cannot play a Tween that has been stopped. If you just wish to pause the tween, not destroy it, + * then call the `pause` method instead and use `resume` to continue playback. If you wish to restart the Tween, + * use the `restart` or `seek` methods. */ - add(config: Phaser.Types.Tweens.TweenBuilderConfig | object): this; + stop(): this; /** - * Adds an existing Tween to this Timeline. - * @param tween The Tween to be added to this Timeline. + * Internal method that handles the processing of the loop delay countdown timer and + * the dispatch of related events. Called automatically by `Tween.update`. + * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. */ - queue(tween: Phaser.Tweens.Tween): this; + updateLoopCountdown(delta: number): void; /** - * Checks whether a Tween has an offset value. - * @param tween The Tween to check. + * Internal method that handles the processing of the start delay countdown timer and + * the dispatch of related events. Called automatically by `Tween.update`. + * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ + updateStartCountdown(delta: number): void; + + /** + * Internal method that handles the processing of the complete delay countdown timer and + * the dispatch of related events. Called automatically by `Tween.update`. + * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + */ + updateCompleteDelay(delta: number): void; + + /** + * Sets an event based callback to be invoked during playback. + * + * Calling this method will replace a previously set callback for the given type, if any exists. + * + * The types available are: + * + * `onActive` - When the Tween is first created it moves to an 'active' state when added to the Tween Manager. 'Active' does not mean 'playing'. + * `onStart` - When the Tween starts playing after a delayed or paused state. This will happen at the same time as `onActive` if the tween has no delay and isn't paused. + * `onLoop` - When a Tween loops, if it has been set to do so. This happens _after_ the `loopDelay` expires, if set. + * `onComplete` - When the Tween finishes playback fully. Never invoked if the Tween is set to repeat infinitely. + * `onStop` - Invoked only if the `Tween.stop` method is called. + * `onPause` - Invoked only if the `Tween.pause` method is called. Not invoked if the Tween Manager is paused. + * `onResume` - Invoked only if the `Tween.resume` method is called. Not invoked if the Tween Manager is resumed. + * + * The following types are also available and are invoked on a `TweenData` level - that is per-object, per-property, being tweened. + * + * `onYoyo` - When a TweenData starts a yoyo. This happens _after_ the `hold` delay expires, if set. + * `onRepeat` - When a TweenData repeats playback. This happens _after_ the `repeatDelay` expires, if set. + * `onUpdate` - When a TweenData updates a property on a source target during playback. + * @param type The type of callback to set. One of: `onActive`, `onComplete`, `onLoop`, `onPause`, `onRepeat`, `onResume`, `onStart`, `onStop`, `onUpdate` or `onYoyo`. + * @param callback Your callback that will be invoked. + * @param params The parameters to pass to the callback. Pass an empty array if you don't want to define any, but do wish to set the scope. + */ + setCallback(type: Phaser.Types.Tweens.TweenCallbackTypes, callback: Function, params?: any[]): this; + + /** + * Sets this Tween state to PENDING. + */ + setPendingState(): void; + + /** + * Sets this Tween state to ACTIVE. + */ + setActiveState(): void; + + /** + * Sets this Tween state to LOOP_DELAY. + */ + setLoopDelayState(): void; + + /** + * Sets this Tween state to COMPLETE_DELAY. + */ + setCompleteDelayState(): void; + + /** + * Sets this Tween state to START_DELAY. + */ + setStartDelayState(): void; + + /** + * Sets this Tween state to PENDING_REMOVE. + */ + setPendingRemoveState(): void; + + /** + * Sets this Tween state to REMOVED. + */ + setRemovedState(): void; + + /** + * Sets this Tween state to FINISHED. */ - hasOffset(tween: Phaser.Tweens.Tween): boolean; + setFinishedState(): void; /** - * Checks whether the offset value is a number or a directive that is relative to previous tweens. - * @param value The offset value to be evaluated. + * Sets this Tween state to DESTROYED. */ - isOffsetAbsolute(value: number): boolean; + setDestroyedState(): void; /** - * Checks if the offset is a relative value rather than an absolute one. - * If the value is just a number, this returns false. - * @param value The offset value to be evaluated. + * Returns `true` if this Tween has a _current_ state of PENDING, otherwise `false`. */ - isOffsetRelative(value: string): boolean; + isPending(): boolean; /** - * Parses the relative offset value, returning a positive or negative number. - * @param 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 base The value to use as the offset. + * Returns `true` if this Tween has a _current_ state of ACTIVE, otherwise `false`. */ - getRelativeOffset(value: string, base: number): number; + isActive(): boolean; + + /** + * Returns `true` if this Tween has a _current_ state of LOOP_DELAY, otherwise `false`. + */ + isLoopDelayed(): boolean; + + /** + * Returns `true` if this Tween has a _current_ state of COMPLETE_DELAY, otherwise `false`. + */ + isCompleteDelayed(): boolean; + + /** + * Returns `true` if this Tween has a _current_ state of START_DELAY, otherwise `false`. + */ + isStartDelayed(): boolean; + + /** + * Returns `true` if this Tween has a _current_ state of PENDING_REMOVE, otherwise `false`. + */ + isPendingRemove(): boolean; + + /** + * Returns `true` if this Tween has a _current_ state of REMOVED, otherwise `false`. + */ + isRemoved(): boolean; + + /** + * Returns `true` if this Tween has a _current_ state of FINISHED, otherwise `false`. + */ + isFinished(): boolean; + + /** + * Returns `true` if this Tween has a _current_ state of DESTROYED, otherwise `false`. + */ + isDestroyed(): boolean; + + /** + * Handles the destroy process of this Tween, clearing out the + * Tween Data and resetting the targets. A Tween that has been + * destroyed cannot ever be played or used again. + */ + destroy(): void; + + } + + /** + * BaseTweenData is the class that the TweenData and TweenFrameData classes + * extend from. You should not typically instantiate this class directly, but instead + * use it to form your own tween data classes from, should you require it. + * + * Prior to Phaser 3.60 the TweenData was just an object, but was refactored to a class, + * to make it responsible for its own state and updating. + */ + class BaseTweenData { + /** + * + * @param tween The tween this TweenData instance belongs to. + * @param targetIndex The target index within the Tween targets array. + * @param key The property of the target to tween. + * @param getEnd What the property will be at the END of the Tween. + * @param getStart What the property will be at the START of the Tween. + * @param getActive If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. + * @param ease The ease function this tween uses. + * @param delay Function that returns the time in milliseconds before tween will start. + * @param duration The duration of the tween in milliseconds. + * @param yoyo Determines whether the tween should return back to its start value after hold has expired. + * @param hold Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param repeat Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param repeatDelay Function that returns the time in milliseconds before the repeat will start. + * @param flipX Should toggleFlipX be called when yoyo or repeat happens? + * @param flipY Should toggleFlipY be called when yoyo or repeat happens? + * @param interpolation The interpolation function to be used for arrays of data. Defaults to 'null'. + * @param interpolationData The array of interpolation data to be set. Defaults to 'null'. + */ + constructor(tween: Phaser.Tweens.Tween, targetIndex: number, key: string, getEnd: Phaser.Types.Tweens.GetEndCallback, getStart: Phaser.Types.Tweens.GetStartCallback, getActive: Phaser.Types.Tweens.GetActiveCallback | undefined, ease: Function, delay: Function, duration: number, yoyo: boolean, hold: number, repeat: number, repeatDelay: number, flipX: boolean, flipY: boolean, interpolation: Function | undefined, interpolationData: number[] | undefined); + + /** + * A reference to the Tween that this TweenData instance belongs to. + */ + tween: Phaser.Tweens.Tween; + + /** + * The index of the target within the Tween `targets` array. + */ + targetIndex: number; + + /** + * The duration of the tween in milliseconds, excluding any time required + * for yoyo or repeats. + */ + duration: number; + + /** + * The total calculated duration, in milliseconds, of this TweenData. + * Factoring in the duration, repeats, delays and yoyos. + */ + totalDuration: number; + + /** + * The time, in milliseconds, before this tween will start playing. + * + * This value is generated by the `getDelay` function. + */ + delay: number; + + /** + * This function returns the value to be used for `TweenData.delay`. + */ + getDelay: Function; + + /** + * Will the Tween ease back to its starting values, after reaching the end + * and any `hold` value that may be set? + */ + yoyo: boolean; + + /** + * The time, in milliseconds, before this tween will start a yoyo to repeat. + */ + hold: number; /** - * Calculates the total duration of the timeline. + * The number of times this tween will repeat. * - * Computes all tween durations and returns the full duration of the timeline. + * The tween will always run once regardless of this value, + * so a repeat value of '1' will play the tween twice: I.e. the original + * play-through and then it repeats that once (1). * - * The resulting number is stored in the timeline, not as a return value. + * If this value is set to -1 this tween will repeat forever. + */ + repeat: number; + + /** + * The time, in milliseconds, before the repeat will start. + */ + repeatDelay: number; + + /** + * How many repeats are left to run? + */ + repeatCounter: number; + + /** + * If `true` this Tween will call `toggleFlipX` on the Tween target + * whenever it yoyo's or repeats. It will only be called if the target + * has a function matching this name, like most Phaser GameObjects do. + */ + flipX: boolean; + + /** + * If `true` this Tween will call `toggleFlipY` on the Tween target + * whenever it yoyo's or repeats. It will only be called if the target + * has a function matching this name, like most Phaser GameObjects do. + */ + flipY: boolean; + + /** + * A value between 0 and 1 holding the progress of this TweenData. + */ + progress: number; + + /** + * The amount of time, in milliseconds, that has elapsed since this + * TweenData was made active. + */ + elapsed: number; + + /** + * The state of this TweenData. + */ + state: Phaser.Tweens.StateType; + + /** + * Is this Tween Data currently waiting for a countdown to elapse, or not? + */ + isCountdown: boolean; + + /** + * Returns a reference to the target object belonging to this TweenData. + */ + getTarget(): object; + + /** + * Sets this TweenData's target object property to be the given value. + * @param value The value to set on the target. If not given, sets it to the last `current` value. + */ + setTargetValue(value?: number): void; + + /** + * Sets this TweenData state to CREATED. + */ + setCreatedState(): void; + + /** + * Sets this TweenData state to DELAY. + */ + setDelayState(): void; + + /** + * Sets this TweenData state to PENDING_RENDER. + */ + setPendingRenderState(): void; + + /** + * Sets this TweenData state to PLAYING_FORWARD. + */ + setPlayingForwardState(): void; + + /** + * Sets this TweenData state to PLAYING_BACKWARD. + */ + setPlayingBackwardState(): void; + + /** + * Sets this TweenData state to HOLD_DELAY. + */ + setHoldState(): void; + + /** + * Sets this TweenData state to REPEAT_DELAY. + */ + setRepeatState(): void; + + /** + * Sets this TweenData state to COMPLETE. + */ + setCompleteState(): void; + + /** + * Returns `true` if this TweenData has a _current_ state of CREATED, otherwise `false`. */ - calcDuration(): void; + isCreated(): boolean; /** - * 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. + * Returns `true` if this TweenData has a _current_ state of DELAY, otherwise `false`. */ - init(): boolean; + isDelayed(): boolean; /** - * 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. - * @param resetFromLoop If `true`, resets all looping tweens to their initial values. + * Returns `true` if this TweenData has a _current_ state of PENDING_RENDER, otherwise `false`. */ - resetTweens(resetFromLoop: boolean): void; + isPendingRender(): boolean; /** - * Sets a callback for the Timeline. - * @param type The internal type of callback to set. - * @param callback Timeline allows multiple tweens to be linked together to create a streaming sequence. - * @param params The parameters to pass to the callback. - * @param scope The context scope of the callback. + * Returns `true` if this TweenData has a _current_ state of PLAYING_FORWARD, otherwise `false`. */ - setCallback(type: string, callback: Function, params?: any[], scope?: object): this; + isPlayingForward(): boolean; /** - * Passed a Tween to the Tween Manager and requests it be made active. - * @param tween The tween object to make active. + * Returns `true` if this TweenData has a _current_ state of PLAYING_BACKWARD, otherwise `false`. */ - makeActive(tween: Phaser.Tweens.Tween): Phaser.Tweens.TweenManager; + isPlayingBackward(): boolean; /** - * Starts playing the Timeline. + * Returns `true` if this TweenData has a _current_ state of HOLD_DELAY, otherwise `false`. */ - play(): void; + isHolding(): boolean; /** - * Updates the Timeline's `state` and fires callbacks and events. + * Returns `true` if this TweenData has a _current_ state of REPEAT_DELAY, otherwise `false`. */ - nextState(): void; + isRepeating(): boolean; /** - * Returns 'true' if this Timeline has finished and should be removed from the Tween Manager. - * Otherwise, returns false. - * @param timestamp The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + * Returns `true` if this TweenData has a _current_ state of COMPLETE, otherwise `false`. */ - update(timestamp: number, delta: number): boolean; + isComplete(): boolean; /** - * Stops the Timeline immediately, whatever stage of progress it is at and flags it for removal by the TweenManager. + * Internal method used as part of the playback process that checks if this + * TweenData should yoyo, repeat, or has completed. + * @param diff Any extra time that needs to be accounted for in the elapsed and progress values. */ - stop(): void; + setStateFromEnd(diff: number): void; /** - * Pauses the Timeline, retaining its internal state. - * - * Calling this on a Timeline that is already paused has no effect and fires no event. + * Internal method used as part of the playback process that checks if this + * TweenData should repeat or has completed. + * @param diff Any extra time that needs to be accounted for in the elapsed and progress values. */ - pause(): this; + setStateFromStart(diff: number): void; /** - * Resumes a paused Timeline from where it was when it was paused. + * Internal method that resets this Tween Data entirely, including the progress and elapsed values. * - * Calling this on a Timeline that isn't paused has no effect and fires no event. + * Called automatically by the parent Tween. Should not be called directly. */ - resume(): this; + reset(): void; /** - * Checks if any of the Tweens in this Timeline as operating on the target object. + * Internal method that handles repeating or yoyo'ing this TweenData. * - * Returns `false` if no Tweens operate on the target object. - * @param target The target to check all Tweens against. + * Called automatically by `setStateFromStart` and `setStateFromEnd`. + * @param diff Any extra time that needs to be accounted for in the elapsed and progress values. + * @param setStart Set the TweenData start values? + * @param isYoyo Is this call a Yoyo check? */ - hasTarget(target: object): boolean; + onRepeat(diff: number, setStart: boolean, isYoyo: boolean): void; /** - * Stops all the Tweens in the Timeline immediately, whatever stage of progress they are at and flags - * them for removal by the TweenManager. + * Immediately destroys this TweenData, nulling of all its references. */ destroy(): void; } /** - * TweenData state. - */ - var CREATED: number; - - /** - * TweenData state. + * Phaser Tween States. */ - var INIT: number; - - /** - * TweenData state. - */ - var DELAY: number; - - /** - * TweenData state. - */ - var OFFSET_DELAY: number; + enum States { + /** + * TweenData state. + */ + CREATED, + /** + * TweenData state. + */ + DELAY, + /** + * TweenData state. + */ + PENDING_RENDER, + /** + * TweenData state. + */ + PLAYING_FORWARD, + /** + * TweenData state. + */ + PLAYING_BACKWARD, + /** + * TweenData state. + */ + HOLD_DELAY, + /** + * TweenData state. + */ + REPEAT_DELAY, + /** + * TweenData state. + */ + COMPLETE, + /** + * Tween state. The Tween has been created but has not yet been added to the Tween Manager. + */ + PENDING, + /** + * Tween state. The Tween is active within the Tween Manager. This means it is either playing, + * or was playing and is currently paused, but in both cases it's still being processed by + * the Tween Manager, so is considered 'active'. + */ + ACTIVE, + /** + * Tween state. The Tween is waiting for a loop countdown to elapse. + */ + LOOP_DELAY, + /** + * Tween state. The Tween is waiting for a complete delay to elapse. + */ + COMPLETE_DELAY, + /** + * Tween state. The Tween is waiting for a starting delay to elapse. + */ + START_DELAY, + /** + * Tween state. The Tween has finished playback and is waiting to be removed from the Tween Manager. + */ + PENDING_REMOVE, + /** + * Tween state. The Tween has been removed from the Tween Manager. + */ + REMOVED, + /** + * Tween state. The Tween has finished playback but was flagged as 'persistent' during creation, + * so will not be automatically removed by the Tween Manager. + */ + FINISHED, + /** + * Tween state. The Tween has been destroyed and can no longer be played by a Tween Manager. + */ + DESTROYED, + /** + * A large integer value used for 'infinite' style countdowns. + * + * Similar use-case to Number.MAX_SAFE_INTEGER but we cannot use that because it's not + * supported on IE. + */ + MAX, + } /** - * TweenData state. + * Phaser Tween state constants. */ - var PENDING_RENDER: number; + type StateType = Phaser.Tweens.States; /** - * TweenData state. + * A Tween is able to manipulate the properties of one or more objects to any given value, based + * on a duration and type of ease. They are rarely instantiated directly and instead should be + * created via the TweenManager. + * + * Please note that a Tween will not manipulate any property that begins with an underscore. */ - var PLAYING_FORWARD: number; + class Tween extends Phaser.Tweens.BaseTween { + /** + * + * @param parent A reference to the Tween Manager that owns this Tween. + * @param targets An array of targets to be tweened. + */ + constructor(parent: Phaser.Tweens.TweenManager, targets: object[]); - /** - * TweenData state. - */ - var PLAYING_BACKWARD: number; + /** + * An array of references to the target/s this Tween is operating on. + * + * This array should not be manipulated outside of this Tween. + */ + targets: object[]; - /** - * TweenData state. - */ - var HOLD_DELAY: number; + /** + * Cached target total. + * + * Used internally and should be treated as read-only. + * + * This is not necessarily the same as the data total. + */ + totalTargets: number; - /** - * TweenData state. - */ - var REPEAT_DELAY: number; + /** + * Is this Tween currently seeking? + * + * This boolean is toggled in the `Tween.seek` method. + * + * When a tween is seeking, by default it will not dispatch any events or callbacks. + */ + readonly isSeeking: boolean; - /** - * TweenData state. - */ - var COMPLETE: number; + /** + * Does this Tween loop or repeat infinitely? + */ + readonly isInfinite: boolean; - /** - * Tween state. - */ - var PENDING_ADD: number; + /** + * Elapsed time in milliseconds of this run through of the Tween. + */ + elapsed: number; - /** - * Tween state. - */ - var PAUSED: number; + /** + * Total elapsed time in milliseconds of the entire Tween, including looping. + */ + totalElapsed: number; - /** - * Tween state. - */ - var LOOP_DELAY: number; + /** + * Time in milliseconds for the whole Tween to play through once, excluding loop amounts and loop delays. + * + * This value is set in the `Tween.initTweenData` method and is zero before that point. + */ + duration: number; - /** - * Tween state. - */ - var ACTIVE: number; + /** + * Value between 0 and 1. The amount of progress through the Tween, excluding loops. + */ + progress: number; - /** - * Tween state. - */ - var COMPLETE_DELAY: number; + /** + * Time in milliseconds it takes for the Tween to complete a full playthrough (including looping) + * + * For an infinite Tween, this value is a very large integer. + */ + totalDuration: number; - /** - * Tween state. - */ - var PENDING_REMOVE: number; + /** + * The amount of progress that has been made through the entire Tween, including looping. + * + * A value between 0 and 1. + */ + totalProgress: number; - /** - * Tween state. - */ - var REMOVED: number; + /** + * Adds a new TweenData to this Tween. Typically, this method is called + * automatically by the TweenBuilder, however you can also invoke it + * yourself. + * @param targetIndex The target index within the Tween targets array. + * @param key The property of the target to tween. + * @param getEnd What the property will be at the END of the Tween. + * @param getStart What the property will be at the START of the Tween. + * @param getActive If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. + * @param ease The ease function this tween uses. + * @param delay Function that returns the time in milliseconds before tween will start. + * @param duration The duration of the tween in milliseconds. + * @param yoyo Determines whether the tween should return back to its start value after hold has expired. + * @param hold Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param repeat Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param repeatDelay Function that returns the time in milliseconds before the repeat will start. + * @param flipX Should toggleFlipX be called when yoyo or repeat happens? + * @param flipY Should toggleFlipY be called when yoyo or repeat happens? + * @param interpolation The interpolation function to be used for arrays of data. Defaults to 'null'. + * @param interpolationData The array of interpolation data to be set. Defaults to 'null'. + */ + add(targetIndex: number, key: string, getEnd: Phaser.Types.Tweens.GetEndCallback, getStart: Phaser.Types.Tweens.GetStartCallback, getActive: Phaser.Types.Tweens.GetActiveCallback | undefined, ease: Function, delay: Function, duration: number, yoyo: boolean, hold: number, repeat: number, repeatDelay: number, flipX: boolean, flipY: boolean, interpolation: Function | undefined, interpolationData: number[] | undefined): Phaser.Tweens.TweenData; + + /** + * Adds a new TweenFrameData to this Tween. Typically, this method is called + * automatically by the TweenBuilder, however you can also invoke it + * yourself. + * @param targetIndex The target index within the Tween targets array. + * @param texture The texture to set on the target at the end of the tween. + * @param frame The texture frame to set on the target at the end of the tween. + * @param delay Function that returns the time in milliseconds before tween will start. + * @param duration The duration of the tween in milliseconds. + * @param hold Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param repeat Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param repeatDelay Function that returns the time in milliseconds before the repeat will start. + * @param flipX Should toggleFlipX be called when yoyo or repeat happens? + * @param flipY Should toggleFlipY be called when yoyo or repeat happens? + */ + addFrame(targetIndex: number, texture: string, frame: string | number, delay: Function, duration: number, hold: number, repeat: number, repeatDelay: number, flipX: boolean, flipY: boolean): Phaser.Tweens.TweenFrameData; - /** - * A Tween is able to manipulate the properties of one or more objects to any given value, based - * on a duration and type of ease. They are rarely instantiated directly and instead should be - * created via the TweenManager. - */ - class Tween extends Phaser.Events.EventEmitter { /** + * Returns the current value of the specified Tween Data. * - * @param parent A reference to the parent of this Tween. Either the Tween Manager or a Tween Timeline instance. - * @param data An array of TweenData objects, each containing a unique property to be tweened. - * @param targets An array of targets to be tweened. + * If this Tween has been destroyed, it will return `null`. + * @param index The Tween Data to return the value from. Default 0. */ - constructor(parent: Phaser.Tweens.TweenManager | Phaser.Tweens.Timeline, data: Phaser.Types.Tweens.TweenDataConfig[], targets: any[]); + getValue(index?: number): number; /** - * A reference to the parent of this Tween. - * Either the Tween Manager or a Tween Timeline instance. + * See if this Tween is currently acting upon the given target. + * @param target The target to check against this Tween. */ - parent: Phaser.Tweens.TweenManager | Phaser.Tweens.Timeline; + hasTarget(target: object): boolean; /** - * Is the parent of this Tween a Timeline? + * Updates the 'end' value of the given property across all matching targets, as long + * as this Tween is currently playing (either forwards or backwards). + * + * Calling this does not adjust the duration of the Tween, or the current progress. + * + * You can optionally tell it to set the 'start' value to be the current value. + * + * If this Tween is in any other state other than playing then calling this method has no effect. + * + * Additionally, if the Tween repeats, is reset, or is seeked, it will revert to the original + * starting and ending values. + * @param key The property to set the new value for. You cannot update the 'texture' property via this method. + * @param value The new value of the property. + * @param startToCurrent Should this change set the start value to be the current value? Default false. */ - parentIsTimeline: boolean; + updateTo(key: string, value: number, startToCurrent?: boolean): this; /** - * An array of TweenData objects, each containing a unique property and target being tweened. + * Restarts the Tween from the beginning. + * + * If the Tween has already finished and been destroyed, restarting it will throw an error. + * + * If you wish to restart the Tween from a specific point, use the `Tween.seek` method instead. */ - data: Phaser.Types.Tweens.TweenDataConfig[]; + restart(): this; /** - * The cached length of the data array. + * Internal method that advances to the next state of the Tween during playback. */ - totalData: number; + nextState(): boolean; /** - * An array of references to the target/s this Tween is operating on. + * Internal method that handles this tween completing and starting + * the next tween in the chain, if any. */ - targets: object[]; + onCompleteHandler(): void; /** - * Cached target total (not necessarily the same as the data total) + * Starts a Tween playing. + * + * You only need to call this method if you have configured the tween to be paused on creation. + * + * If the Tween is already playing, calling this method again will have no effect. If you wish to + * restart the Tween, use `Tween.restart` instead. + * + * Calling this method after the Tween has completed will start the Tween playing again from the beginning. + * This is the same as calling `Tween.seek(0)` and then `Tween.play()`. */ - totalTargets: number; + play(): this; /** - * If `true` then duration, delay, etc values are all frame totals. + * Seeks to a specific point in the Tween. + * + * The given amount is a value in milliseconds that represents how far into the Tween + * you wish to seek, based on the start of the Tween. + * + * Note that the seek amount takes the entire duration of the Tween into account, including delays, loops and repeats. + * For example, a Tween that lasts for 2 seconds, but that loops 3 times, would have a total duration of 6 seconds, + * so seeking to 3000 ms would seek to the Tweens half-way point based on its _entire_ duration. + * + * Prior to Phaser 3.60 this value was given as a number between 0 and 1 and didn't + * work for Tweens had an infinite repeat. This new method works for all Tweens. + * + * Seeking works by resetting the Tween to its initial values and then iterating through the Tween at `delta` + * jumps per step. The longer the Tween, the longer this can take. If you need more precision you can + * reduce the delta value. If you need a faster seek, you can increase it. When the Tween is + * reset it will refresh the starting and ending values. If these are coming from a dynamic function, + * or a random array, it will be called for each seek. + * + * While seeking the Tween will _not_ emit any of its events or callbacks unless + * the 3rd parameter is set to `true`. + * + * If this Tween is paused, seeking will not change this fact. It will advance the Tween + * to the desired point and then pause it again. + * @param amount The number of milliseconds to seek into the Tween from the beginning. Default 0. + * @param delta The size of each step when seeking through the Tween. A higher value completes faster but at the cost of less precision. Default 16.6. + * @param emit While seeking, should the Tween emit any of its events or callbacks? The default is 'false', i.e. to seek silently. Default false. */ - useFrames: boolean; + seek(amount?: number, delta?: number, emit?: boolean): this; /** - * Scales the time applied to this Tween. 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 tween, it's a run-time delta adjustment only. + * Initialises all of the Tween Data and Tween values. + * + * This is called automatically and should not typically be invoked directly. + * @param isSeeking Is the Tween Data being reset as part of a seek? Default false. */ - timeScale: number; + initTweenData(isSeeking?: boolean): void; /** - * Loop this tween? Can be -1 for an infinite loop, or an integer. - * When enabled it will play through ALL TweenDatas again. Use TweenData.repeat to loop a single element. + * Resets this Tween ready for another play-through. + * + * This is called automatically from the Tween Manager, or from the parent TweenChain, + * and should not typically be invoked directly. + * + * If you wish to restart this Tween, use the `Tween.restart` or `Tween.seek` methods instead. + * @param skipInit Skip resetting the TweenData and Active State? Default false. */ - loop: number; + reset(skipInit?: boolean): this; /** - * Time in ms/frames before the tween loops. + * Internal method that advances the Tween based on the time values. + * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. */ - loopDelay: number; + update(delta: number): boolean; /** - * How many loops are left to run? + * Moves this Tween forward by the given amount of milliseconds. + * + * It will only advance through the current loop of the Tween. For example, if the + * Tween is set to repeat or yoyo, it can only fast forward through a single + * section of the sequence. Use `Tween.seek` for more complex playhead control. + * + * If the Tween is paused or has already finished, calling this will have no effect. + * @param ms The number of milliseconds to advance this Tween by. */ - loopCounter: number; + forward(ms: number): this; /** - * Time in ms/frames before the 'onStart' event fires. - * This is the shortest `delay` value across all of the TweenDatas of this Tween. + * Moves this Tween backward by the given amount of milliseconds. + * + * It will only rewind through the current loop of the Tween. For example, if the + * Tween is set to repeat or yoyo, it can only fast forward through a single + * section of the sequence. Use `Tween.seek` for more complex playhead control. + * + * If the Tween is paused or has already finished, calling this will have no effect. + * @param ms The number of milliseconds to rewind this Tween by. */ - startDelay: number; + rewind(ms: number): this; /** - * Has this Tween started playback yet? - * This boolean is toggled when the Tween leaves the 'delayed' state and starts running. + * Internal method that will emit a Tween based Event and invoke the given callback. + * @param event The Event to be dispatched. + * @param callback The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation. */ - readonly hasStarted: boolean; + dispatchEvent(event: Phaser.Types.Tweens.Event, callback?: Phaser.Types.Tweens.TweenCallbackTypes): void; /** - * Is this Tween currently seeking? - * This boolean is toggled in the `Tween.seek` method. - * When a tween is seeking it will not dispatch any events or callbacks. + * Handles the destroy process of this Tween, clearing out the + * Tween Data and resetting the targets. A Tween that has been + * destroyed cannot ever be played or used again. */ - readonly isSeeking: boolean; + destroy(): void; + + } + /** + * A TweenChain is a special type of Tween that allows you to create a sequence of Tweens, chained to one-another, + * and add them to the Tween Manager. + * + * The tweens are played in order, from start to finish. You can optionally set the chain + * to repeat as many times as you like. Once the chain has finished playing, or repeating if set, + * all tweens in the chain will be destroyed automatically. To override this, set the 'persists' + * argument to 'true'. + * + * Playback will start immediately unless the _first_ Tween has been configured to be paused. + * + * Please note that Tweens will not manipulate any target property that begins with an underscore. + */ + class TweenChain extends Phaser.Tweens.BaseTween { /** - * Time in ms/frames before the 'onComplete' event fires. This never fires if loop = -1 (as it never completes) + * + * @param parent A reference to the Tween Manager, or TweenChain, that owns this TweenChain. */ - completeDelay: number; + constructor(parent: Phaser.Tweens.TweenManager | Phaser.Tweens.TweenChain); /** - * Countdown timer (used by timeline offset, loopDelay and completeDelay) + * A reference to the Tween that this TweenChain is currently playing. */ - countdown: number; + currentTween: Phaser.Tweens.Tween; /** - * Set only if this Tween is part of a Timeline. + * A reference to the data array index of the currently playing tween. */ - offset: number; + currentIndex: number; /** - * Set only if this Tween is part of a Timeline. The calculated offset amount. + * Prepares this TweenChain for playback. + * + * Called automatically by the TweenManager. Should not be called directly. */ - calculatedOffset: number; + init(): this; /** - * The current state of the tween + * Create a sequence of Tweens, chained to one-another, and add them to this Tween Manager. + * + * The tweens are played in order, from start to finish. You can optionally set the chain + * to repeat as many times as you like. Once the chain has finished playing, or repeating if set, + * all tweens in the chain will be destroyed automatically. To override this, set the 'persists' + * argument to 'true'. + * + * Playback will start immediately unless the _first_ Tween has been configured to be paused. + * + * Please note that Tweens will not manipulate any target property that begins with an underscore. + * @param tweens An array of Tween configuration objects for the Tweens in this chain. */ - state: number; + add(tweens: Phaser.Types.Tweens.TweenBuilderConfig[] | object[]): this; /** - * Does the Tween start off paused? (if so it needs to be started with Tween.play) + * See if any of the tweens in this Tween Chain is currently acting upon the given target. + * @param target The target to check against this TweenChain. */ - paused: boolean; + hasTarget(target: object): boolean; /** - * Elapsed time in ms/frames of this run through the Tween. + * Restarts the TweenChain from the beginning. + * + * If this TweenChain was configured to have a loop, or start delay, those + * are reset to their initial values as well. It will also dispatch the + * `onActive` callback and event again. */ - elapsed: number; + restart(): this; /** - * Total elapsed time in ms/frames of the entire Tween, including looping. + * Resets the given Tween. + * + * It will seek to position 0 and playback will start on the next frame. + * @param tween The Tween to be reset. */ - totalElapsed: number; + reset(tween: Phaser.Tweens.Tween): this; /** - * Time in ms/frames for the whole Tween to play through once, excluding loop amounts and loop delays. + * Internal method that advances to the next state of the TweenChain playback. */ - duration: number; + nextState(): boolean; /** - * Value between 0 and 1. The amount through the Tween, excluding loops. + * Starts this TweenChain playing. + * + * You only need to call this method if you have configured this TweenChain to be paused on creation. + * + * If the TweenChain is already playing, calling this method again will have no effect. If you wish to + * restart the chain, use `TweenChain.restart` instead. + * + * Calling this method after the TweenChain has completed will start the chain playing again from the beginning. */ - progress: number; + play(): this; /** - * Time in ms/frames for the Tween to complete (including looping) + * Internal method that resets all of the Tweens and the current index pointer. */ - totalDuration: number; + resetTweens(): void; /** - * Value between 0 and 1. The amount through the entire Tween, including looping. + * Internal method that advances the TweenChain based on the time values. + * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. */ - totalProgress: number; + update(delta: number): boolean; /** - * An object containing the different Tween callback functions. - * - * You can either set these in the Tween config, or by calling the `Tween.setCallback` method. + * Immediately advances to the next Tween in the chain. * - * `onActive` When the Tween is moved from the pending to the active list in the Tween Manager, even if playback paused. - * `onStart` When the Tween starts playing after a delayed state. Will happen at the same time as `onActive` if it has no delay. - * `onYoyo` When a TweenData starts a yoyo. This happens _after_ the `hold` delay expires, if set. - * `onRepeat` When a TweenData repeats playback. This happens _after_ the `repeatDelay` expires, if set. - * `onComplete` When the Tween finishes playback fully. Never invoked if tween is set to repeat infinitely. - * `onUpdate` When a TweenData updates a property on a source target during playback. - * `onLoop` When a Tween loops. This happens _after_ the `loopDelay` expires, if set. + * This is typically called internally, but can be used if you need to + * advance playback for some reason. */ - callbacks: object; + nextTween(): boolean; /** - * The context in which all callbacks are invoked. + * Sets the current active Tween to the given index, based on its + * entry in the TweenChain data array. + * @param index The index of the Tween to be made current. */ - callbackScope: any; + setCurrentTween(index: number): void; /** - * Returns the current value of the specified Tween Data. - * @param index The Tween Data to return the value from. Default 0. + * Internal method that will emit a TweenChain based Event and invoke the given callback. + * @param event The Event to be dispatched. + * @param callback The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation. */ - getValue(index?: number): number; + dispatchEvent(event: Phaser.Types.Tweens.Event, callback?: Phaser.Types.Tweens.TweenCallbackTypes): void; /** - * Set the scale the time applied to this Tween. A value of 1 runs in real-time. A value of 0.5 runs 50% slower, and so on. - * @param value The scale factor for timescale. + * Immediately destroys this TweenChain, nulling of all its references. */ - setTimeScale(value: number): this; + destroy(): void; + + } + /** + * The TweenData is a class that contains a single target and property that is being tweened. + * + * Tweens create TweenData instances when they are created, with one TweenData instance per + * target, per property. A Tween can own multiple TweenData instances, but a TweenData only + * ever belongs to a single Tween. + * + * You should not typically create these yourself, but rather use the TweenBuilder, + * or the `Tween.add` method. + * + * Prior to Phaser 3.60 the TweenData was just an object, but was refactored to a class, + * to make it responsible for its own state and updating. + */ + class TweenData extends Phaser.Tweens.BaseTweenData { /** - * Returns the scale of the time applied to this Tween. + * + * @param tween The tween this TweenData instance belongs to. + * @param targetIndex The target index within the Tween targets array. + * @param key The property of the target to tween. + * @param getEnd What the property will be at the END of the Tween. + * @param getStart What the property will be at the START of the Tween. + * @param getActive If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. + * @param ease The ease function this tween uses. + * @param delay Function that returns the time in milliseconds before tween will start. + * @param duration The duration of the tween in milliseconds. + * @param yoyo Determines whether the tween should return back to its start value after hold has expired. + * @param hold Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param repeat Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param repeatDelay Function that returns the time in milliseconds before the repeat will start. + * @param flipX Should toggleFlipX be called when yoyo or repeat happens? + * @param flipY Should toggleFlipY be called when yoyo or repeat happens? + * @param interpolation The interpolation function to be used for arrays of data. Defaults to 'null'. + * @param interpolationData The array of interpolation data to be set. Defaults to 'null'. */ - getTimeScale(): number; + constructor(tween: Phaser.Tweens.Tween, targetIndex: number, key: string, getEnd: Phaser.Types.Tweens.GetEndCallback, getStart: Phaser.Types.Tweens.GetStartCallback, getActive: Phaser.Types.Tweens.GetActiveCallback | undefined, ease: Function, delay: Function, duration: number, yoyo: boolean, hold: number, repeat: number, repeatDelay: number, flipX: boolean, flipY: boolean, interpolation: Function | undefined, interpolationData: number[] | undefined); /** - * Checks if the Tween is currently active. + * The property of the target to be tweened. */ - isPlaying(): boolean; + readonly key: string; /** - * Checks if the Tween is currently paused. + * A function that returns what to set the target property to, + * the moment the TweenData is invoked. + * + * This is called when this TweenData is inititalised or reset. */ - isPaused(): boolean; + getActiveValue: Phaser.Types.Tweens.GetActiveCallback | null; /** - * See if this Tween is currently acting upon the given target. - * @param target The target to check against this Tween. + * A function that returns what to set the target property to + * at the end of the tween. + * + * This is called when the tween starts playing, after any initial + * start delay, or if the tween is reset, or is set to repeat. */ - hasTarget(target: object): boolean; + getEndValue: Phaser.Types.Tweens.GetEndCallback; /** - * Updates the 'end' value of the given property across all matching targets. + * A function that returns what to set the target property to + * at the start of the tween. * - * Calling this does not adjust the duration of the tween, or the current progress. - * - * You can optionally tell it to set the 'start' value to be the current value (before the change). - * @param key The property to set the new value for. - * @param value The new value of the property. - * @param startToCurrent Should this change set the start value to be the current value? Default false. + * This is called when the tween starts playing, after any initial + * start delay, or if the tween is reset, or is set to repeat. */ - updateTo(key: string, value: any, startToCurrent?: boolean): this; + getStartValue: Phaser.Types.Tweens.GetStartCallback; /** - * Restarts the tween from the beginning. + * The ease function this Tween uses to calculate the target value. */ - restart(): this; + ease: Function; /** - * Internal method that calculates the overall duration of the Tween. + * The targets starting value, as returned by `getStartValue`. */ - calcDuration(): void; + start: number; /** - * Called by TweenManager.preUpdate as part of its loop to check pending and active tweens. - * Should not be called directly. + * The target value from the previous step. */ - init(): boolean; + previous: number; /** - * Internal method that makes this Tween active within the TweenManager - * and emits the onActive event and callback. + * The targets current value, as recorded in the most recent step. */ - makeActive(): void; + current: number; /** - * Internal method that advances to the next state of the Tween during playback. + * The targets ending value, as returned by `getEndValue`. */ - nextState(): void; + end: number; /** - * Pauses the Tween immediately. Use `resume` to continue playback. + * The interpolation function to be used for arrays of data. */ - pause(): this; + interpolation: Function | null; /** - * Starts a Tween playing. - * - * You only need to call this method if you have configured the tween to be paused on creation. - * - * If the Tween is already playing, calling this method again will have no effect. If you wish to - * restart the Tween, use `Tween.restart` instead. + * The array of data to interpolate, if interpolation is being used. + */ + interpolationData: number[] | null; + + /** + * Internal method that resets this Tween Data entirely, including the progress and elapsed values. * - * Calling this method after the Tween has completed will start the Tween playing again from the start. - * This is the same as calling `Tween.seek(0)` and then `Tween.play()`. - * @param resetFromTimeline Is this Tween being played as part of a Timeline? Default false. + * Called automatically by the parent Tween. Should not be called directly. + * @param isSeeking Is the Tween Data being reset as part of a Tween seek? Default false. */ - play(resetFromTimeline?: boolean): this; + reset(isSeeking?: boolean): void; /** - * Internal method that resets all of the Tween Data, including the progress and elapsed values. - * @param resetFromLoop Has this method been called as part of a loop? + * Internal method that advances this TweenData based on the delta value given. + * @param delta The elapsed delta time in ms. */ - resetTweenData(resetFromLoop: boolean): void; + update(delta: number): boolean; /** - * Resumes the playback of a previously paused Tween. + * Internal method that will emit a TweenData based Event on the + * parent Tween and also invoke the given callback, if provided. + * @param event The Event to be dispatched. + * @param callback The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation. */ - resume(): this; + dispatchEvent(event: Phaser.Types.Tweens.Event, callback?: Phaser.Types.Tweens.TweenCallbackTypes): void; /** - * Seeks to a specific point in the Tween. - * - * **Note:** Be careful when seeking a Tween that repeats or loops forever, - * or that has an unusually long total duration, as it's possible to hang the browser. - * - * The given position is a value between 0 and 1 which represents how far through the Tween to seek to. - * A value of 0.5 would seek to half-way through the Tween, where-as a value of zero would seek to the start. - * - * Note that the seek takes the entire duration of the Tween into account, including delays, loops and repeats. - * For example, a Tween that lasts for 2 seconds, but that loops 3 times, would have a total duration of 6 seconds, - * so seeking to 0.5 would seek to 3 seconds into the Tween, as that's half-way through its _entire_ duration. - * - * Seeking works by resetting the Tween to its initial values and then iterating through the Tween at `delta` - * jumps per step. The longer the Tween, the longer this can take. - * @param toPosition A value between 0 and 1 which represents the progress point to seek to. - * @param delta The size of each step when seeking through the Tween. A higher value completes faster but at a cost of less precision. Default 16.6. + * Immediately destroys this TweenData, nulling of all its references. */ - seek(toPosition: number, delta?: number): this; + destroy(): void; + + } + /** + * The TweenFrameData is a class that contains a single target that will change the texture frame + * at the conclusion of the Tween. + * + * TweenFrameData instances are typically created by the TweenBuilder automatically, when it + * detects the prescence of a 'texture' property as the key being tweened. + * + * A Tween can own multiple TweenFrameData instances, but a TweenFrameData only + * ever belongs to a single Tween. + * + * You should not typically create these yourself, but rather use the TweenBuilder, + * or the `Tween.addFrame` method. + */ + class TweenFrameData extends Phaser.Tweens.BaseTweenData { /** - * Sets an event based callback to be invoked during playback. - * - * Calling this method will replace a previously set callback for the given type, if any exists. * - * The types available are: - * - * `onActive` When the Tween is moved from the pending to the active list in the Tween Manager, even if playback paused. - * `onStart` When the Tween starts playing after a delayed state. Will happen at the same time as `onActive` if it has no delay. - * `onYoyo` When a TweenData starts a yoyo. This happens _after_ the `hold` delay expires, if set. - * `onRepeat` When a TweenData repeats playback. This happens _after_ the `repeatDelay` expires, if set. - * `onComplete` When the Tween finishes playback fully or `Tween.stop` is called. Never invoked if tween is set to repeat infinitely. - * `onUpdate` When a TweenData updates a property on a source target during playback. - * `onLoop` When a Tween loops. This happens _after_ the `loopDelay` expires, if set. - * @param type Type of the callback to set. - * @param callback The function to invoke when this callback happens. - * @param params An array of parameters for specified callbacks types. - * @param scope The context the callback will be invoked in. + * @param tween The tween this TweenData instance belongs to. + * @param targetIndex The target index within the Tween targets array. + * @param texture The texture key to set at the end of this tween. + * @param frame The texture frame to set at the end of this tween. + * @param delay Function that returns the time in milliseconds before tween will start. + * @param duration The duration of the tween in milliseconds. + * @param hold Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true. + * @param repeat Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. + * @param repeatDelay Function that returns the time in milliseconds before the repeat will start. + * @param flipX Should toggleFlipX be called when yoyo or repeat happens? + * @param flipY Should toggleFlipY be called when yoyo or repeat happens? */ - setCallback(type: string, callback: Function, params?: any[], scope?: any): this; + constructor(tween: Phaser.Tweens.Tween, targetIndex: number, texture: string, frame: string | number, delay: Function, duration: number, hold: number, repeat: number, repeatDelay: number, flipX: boolean, flipY: boolean); /** - * Flags the Tween as being complete, whatever stage of progress it is at. - * - * If an onComplete callback has been defined it will automatically invoke it, unless a `delay` - * argument is provided, in which case the Tween will delay for that period of time before calling the callback. + * The property of the target to be tweened. * - * If you don't need a delay, or have an onComplete callback, then call `Tween.stop` instead. - * @param delay The time to wait before invoking the complete callback. If zero it will fire immediately. Default 0. + * Always 'texture' for a TweenFrameData object. */ - complete(delay?: number): this; + readonly key: string; /** - * Immediately removes this Tween from the TweenManager and all of its internal arrays, - * no matter what stage it as it. Then sets the tween state to `REMOVED`. - * - * You should dispose of your reference to this tween after calling this method, to - * free it from memory. + * The texture to be set at the start of the tween. */ - remove(): this; + startTexture: string; /** - * Stops the Tween immediately, whatever stage of progress it is at and flags it for removal by the TweenManager. - * @param resetTo If you want to seek the tween, provide a value between 0 and 1. + * The texture to be set at the end of the tween. */ - stop(resetTo?: number): this; + endTexture: string; /** - * Internal method that advances the Tween based on the time values. - * @param timestamp The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout. - * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + * The frame to be set at the start of the tween. */ - update(timestamp: number, delta: number): boolean; + startFrame: string | number; /** - * Internal method that will emit a TweenData based Event and invoke the given callback. - * @param event The Event to be dispatched. - * @param callback The callback to be invoked. Can be `null` or `undefined` to skip invocation. - * @param tweenData The TweenData object that caused this event. + * The frame to be set at the end of the tween. */ - dispatchTweenDataEvent(event: Phaser.Types.Tweens.Event, callback: Function, tweenData: Phaser.Types.Tweens.TweenDataConfig): void; + endFrame: string | number; /** - * Internal method that will emit a Tween based Event and invoke the given callback. - * @param event The Event to be dispatched. - * @param callback The callback to be invoked. Can be `null` or `undefined` to skip invocation. + * Will the Tween ease back to its starting values, after reaching the end + * and any `hold` value that may be set? */ - dispatchTweenEvent(event: Phaser.Types.Tweens.Event, callback: Function): void; + yoyo: boolean; /** - * Internal method used as part of the playback process that sets a tween to play in reverse. - * @param tween The Tween to update. - * @param tweenData The TweenData property to update. - * @param diff Any extra time that needs to be accounted for in the elapsed and progress values. + * Internal method that resets this Tween Data entirely, including the progress and elapsed values. + * + * Called automatically by the parent Tween. Should not be called directly. + * @param isSeeking Is the Tween Data being reset as part of a Tween seek? Default false. */ - setStateFromEnd(tween: Phaser.Tweens.Tween, tweenData: Phaser.Types.Tweens.TweenDataConfig, diff: number): number; + reset(isSeeking?: boolean): void; /** - * Internal method used as part of the playback process that sets a tween to play from the start. - * @param tween The Tween to update. - * @param tweenData The TweenData property to update. - * @param diff Any extra time that needs to be accounted for in the elapsed and progress values. + * Internal method that advances this TweenData based on the delta value given. + * @param delta The elapsed delta time in ms. + */ + update(delta: number): boolean; + + /** + * Internal method that will emit a TweenData based Event on the + * parent Tween and also invoke the given callback, if provided. + * @param event The Event to be dispatched. + * @param callback The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation. */ - setStateFromStart(tween: Phaser.Tweens.Tween, tweenData: Phaser.Types.Tweens.TweenDataConfig, diff: number): number; + dispatchEvent(event: Phaser.Types.Tweens.Event, callback?: Phaser.Types.Tweens.TweenCallbackTypes): void; /** - * Internal method that advances the TweenData based on the time value given. - * @param tween The Tween to update. - * @param tweenData The TweenData property to update. - * @param delta Either a value in ms, or 1 if Tween.useFrames is true. + * Immediately destroys this TweenData, nulling of all its references. */ - updateTweenData(tween: Phaser.Tweens.Tween, tweenData: Phaser.Types.Tweens.TweenDataConfig, delta: number): boolean; + destroy(): void; } /** - * Returns a TweenDataConfig object that describes the tween data for a unique property of a unique target. - * A single Tween consists of multiple TweenDatas, depending on how many properties are being changed by the Tween. + * The Tween Manager is a default Scene Plugin which controls and updates Tweens. * - * This is an internal function used by the TweenBuilder and should not be accessed directly, instead, - * Tweens should be created using the GameObjectFactory or GameObjectCreator. - * @param target The target to tween. - * @param index The target index within the Tween targets array. - * @param key The property of the target to tween. - * @param getEnd What the property will be at the END of the Tween. - * @param getStart What the property will be at the START of the Tween. - * @param getActive If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property. - * @param ease The ease function this tween uses. - * @param delay Time in ms/frames before tween will start. - * @param duration Duration of the tween in ms/frames. - * @param yoyo Determines whether the tween should return back to its start value after hold has expired. - * @param hold Time in ms/frames the tween will pause before repeating or returning to its starting value if yoyo is set to true. - * @param repeat Number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice. - * @param repeatDelay Time in ms/frames before the repeat will start. - * @param flipX Should toggleFlipX be called when yoyo or repeat happens? - * @param flipY Should toggleFlipY be called when yoyo or repeat happens? - */ - function TweenData(target: any, index: number, key: string, getEnd: Function, getStart: Function, getActive: Function, ease: Function, delay: number, duration: number, yoyo: boolean, hold: number, repeat: number, repeatDelay: number, flipX: boolean, flipY: boolean): Phaser.Types.Tweens.TweenDataConfig; - - /** - * The Tween Manager is a default Scene Plugin which controls and updates Tweens and Timelines. + * A tween is a way to alter one or more properties of a target object over a defined period of time. + * + * Tweens are created by calling the `add` method and passing in the configuration object. + * + * ```js + * const logo = this.add.image(100, 100, 'logo'); + * + * this.tweens.add({ + * targets: logo, + * x: 600, + * ease: 'Power1', + * duration: 2000 + * }); + * ``` + * + * See the `TweenBuilderConfig` for all of the options you have available. + * + * Playback will start immediately unless the tween has been configured to be paused. + * + * Please note that a Tween will not manipulate any target property that begins with an underscore. + * + * Tweens are designed to be 'fire-and-forget'. They automatically destroy themselves once playback + * is complete, to free-up memory and resources. If you wish to keep a tween after playback, i.e. to + * play it again at a later time, then you should set the `persist` property to `true` in the config. + * However, doing so means it's entirely up to _you_ to destroy the tween when you're finished with it, + * otherwise it will linger in memory forever. + * + * If you wish to chain Tweens together for sequential playback, see the `TweenManager.chain` method. */ class TweenManager { /** @@ -95963,9 +112087,9 @@ declare namespace Phaser { scene: Phaser.Scene; /** - * The Systems object of the Scene which owns this Tween Manager. + * The Scene Systems Event Emitter. */ - systems: Phaser.Scenes.Systems; + events: Phaser.Events.EventEmitter; /** * The time scale of the Tween Manager. @@ -95975,37 +112099,189 @@ declare namespace Phaser { timeScale: number; /** - * Create a Tween Timeline and return it, but do NOT add it to the active or pending Tween lists. - * @param config The configuration object for the Timeline and its Tweens. + * This toggles the updating state of this Tween Manager. + * + * Setting `paused` to `true` (or calling the `pauseAll` method) will + * stop this Tween Manager from updating any of its tweens, including + * newly created ones. Set back to `false` to resume playback. + */ + paused: boolean; + + /** + * Is this Tween Manager currently processing the tweens as part of + * its 'update' loop? This is set to 'true' at the start of 'update' + * and reset to 'false' at the end of the function. Allows you to trap + * Tween Manager status during tween callbacks. */ - createTimeline(config?: Phaser.Types.Tweens.TimelineBuilderConfig): Phaser.Tweens.Timeline; + processing: boolean; /** - * Create a Tween Timeline and add it to the active Tween list. - * @param config The configuration object for the Timeline and its Tweens. + * An array of Tweens which are actively being processed by the Tween Manager. */ - timeline(config?: Phaser.Types.Tweens.TimelineBuilderConfig): Phaser.Tweens.Timeline; + tweens: Phaser.Tweens.Tween[]; /** - * Create a Tween and return it, but do NOT add it to the active or pending Tween lists. - * @param config The configuration object for the Tween. + * The time the Tween Manager was updated. */ - create(config: Phaser.Types.Tweens.TweenBuilderConfig | object): Phaser.Tweens.Tween; + time: number; + + /** + * The time the Tween Manager was started. + */ + startTime: number; + + /** + * The time the Tween Manager should next update. + */ + nextTime: number; /** - * Create a Tween and add it to the active Tween list. - * @param config The configuration object for the Tween. + * The time the Tween Manager previously updated. + */ + prevTime: number; + + /** + * The maximum amount of time, in milliseconds, the browser can + * lag for, before lag smoothing is applied. + * + * See the `TweenManager.setLagSmooth` method for further details. + */ + maxLag: number; + + /** + * The amount of time, in milliseconds, that is used to set the + * delta when lag smoothing is applied. + * + * See the `TweenManager.setLagSmooth` method for further details. */ - add(config: Phaser.Types.Tweens.TweenBuilderConfig | object): Phaser.Tweens.Tween; + lagSkip: number; /** - * Add an existing tween into the active Tween list. + * An internal value that holds the fps rate. + */ + gap: number; + + /** + * Create a Tween and return it, but does not add it to this Tween Manager. + * + * Please note that a Tween will not manipulate any target property that begins with an underscore. + * + * In order to play this tween, you'll need to add it to a Tween Manager via + * the `TweenManager.existing` method. + * + * You can optionally pass an **array** of Tween Configuration objects to this method and it will create + * one Tween per entry in the array. If an array is given, an array of tweens is returned. + * @param config A Tween Configuration object. Or an array of Tween Configuration objects. + */ + create(config: Phaser.Types.Tweens.TweenBuilderConfig | Phaser.Types.Tweens.TweenBuilderConfig[] | object | object[]): Phaser.Tweens.Tween | Phaser.Tweens.Tween[]; + + /** + * Create a Tween and add it to this Tween Manager by passing a Tween Configuration object. + * + * Example, run from within a Scene: + * + * ```js + * const logo = this.add.image(100, 100, 'logo'); + * + * this.tweens.add({ + * targets: logo, + * x: 600, + * ease: 'Power1', + * duration: 2000 + * }); + * ``` + * + * See the `TweenBuilderConfig` for all of the options you have available. + * + * Playback will start immediately unless the tween has been configured to be paused. + * + * Please note that a Tween will not manipulate any target property that begins with an underscore. + * + * Tweens are designed to be 'fire-and-forget'. They automatically destroy themselves once playback + * is complete, to free-up memory and resources. If you wish to keep a tween after playback, i.e. to + * play it again at a later time, then you should set the `persist` property to `true` in the config. + * However, doing so means it's entirely up to _you_ to destroy the tween when you're finished with it, + * otherwise it will linger in memory forever. + * + * If you wish to chain Tweens together for sequential playback, see the `TweenManager.chain` method. + * @param config A Tween Configuration object, or a Tween or TweenChain instance. + */ + add(config: Phaser.Types.Tweens.TweenBuilderConfig | Phaser.Types.Tweens.TweenChainBuilderConfig | Phaser.Tweens.Tween | Phaser.Tweens.TweenChain): Phaser.Tweens.Tween; + + /** + * Create multiple Tweens and add them all to this Tween Manager, by passing an array of Tween Configuration objects. + * + * See the `TweenBuilderConfig` for all of the options you have available. + * + * Playback will start immediately unless the tweens have been configured to be paused. + * + * Please note that a Tween will not manipulate any target property that begins with an underscore. + * + * Tweens are designed to be 'fire-and-forget'. They automatically destroy themselves once playback + * is complete, to free-up memory and resources. If you wish to keep a tween after playback, i.e. to + * play it again at a later time, then you should set the `persist` property to `true` in the config. + * However, doing so means it's entirely up to _you_ to destroy the tween when you're finished with it, + * otherwise it will linger in memory forever. + * + * If you wish to chain Tweens together for sequential playback, see the `TweenManager.chain` method. + * @param configs An array of Tween Configuration objects. + */ + addMultiple(configs: Phaser.Types.Tweens.TweenBuilderConfig[] | object[]): Phaser.Tweens.Tween[]; + + /** + * Create a sequence of Tweens, chained to one-another, and add them to this Tween Manager. + * + * The tweens are played in order, from start to finish. You can optionally set the chain + * to repeat as many times as you like. Once the chain has finished playing, or repeating if set, + * all tweens in the chain will be destroyed automatically. To override this, set the 'persists' + * argument to 'true'. + * + * Playback will start immediately unless the _first_ Tween has been configured to be paused. + * + * Please note that Tweens will not manipulate any target property that begins with an underscore. + * @param tweens A Tween Chain configuration object. + */ + chain(tweens: Phaser.Types.Tweens.TweenChainBuilderConfig | object): Phaser.Tweens.TweenChain; + + /** + * Returns an array containing this Tween and all Tweens chained to it, + * in the order in which they will be played. + * + * If there are no chained Tweens an empty array is returned. + * @param tween The Tween to return the chain from. + */ + getChainedTweens(tween: Phaser.Tweens.Tween): Phaser.Tweens.Tween[]; + + /** + * Check to see if the given Tween instance exists within this Tween Manager. + * + * Will return `true` as long as the Tween is being processed by this Tween Manager. + * + * Will return `false` if not present, or has a state of `REMOVED` or `DESTROYED`. + * @param tween The Tween instance to check. + */ + has(tween: Phaser.Tweens.Tween): boolean; + + /** + * Add an existing Tween to this Tween Manager. + * + * Playback will start immediately unless the tween has been configured to be paused. * @param tween The Tween to add. */ - existing(tween: Phaser.Tweens.Tween): Phaser.Tweens.TweenManager; + existing(tween: Phaser.Tweens.Tween): this; /** * Create a Number Tween and add it to the active Tween list. + * + * A Number Tween is a special kind of tween that doesn't have a target. Instead, + * it allows you to tween between 2 numeric values. The default values are + * `0` and `1`, but you can change them via the `from` and `to` properties. + * + * You can get the current tweened value via the `Tween.getValue()` method. + * + * Playback will start immediately unless the tween has been configured to be paused. + * + * Please note that a Tween will not manipulate any target property that begins with an underscore. * @param config The configuration object for the Number Tween. */ addCounter(config: Phaser.Types.Tweens.NumberTweenBuilderConfig): Phaser.Tweens.Tween; @@ -96048,30 +112324,92 @@ declare namespace Phaser { stagger(value: number | number[], config: Phaser.Types.Tweens.StaggerConfig): Function; /** - * Updates the Tween Manager's internal lists at the start of the frame. + * Set the limits that are used when a browser encounters lag, or delays that cause the elapsed + * time between two frames to exceed the expected amount. If this occurs, the Tween Manager will + * act as if the 'skip' amount of times has passed, in order to maintain strict tween sequencing. + * + * This is enabled by default with the values 500ms for the lag limit and 33ms for the skip. + * + * You should not set these to low values, as it won't give time for the browser to ever + * catch-up with itself and reclaim sync. + * + * Call this method with no arguments to disable smoothing. + * + * Call it with the arguments `500` and `33` to reset to the defaults. + * @param limit If the browser exceeds this amount, in milliseconds, it will act as if the 'skip' amount has elapsed instead. Default 0. + * @param skip The amount, in milliseconds, to use as the step delta should the browser lag beyond the 'limit'. Default 0. + */ + setLagSmooth(limit?: number, skip?: number): this; + + /** + * Limits the Tween system to run at a particular frame rate. * - * This method will return immediately if no changes have been indicated. + * You should not set this _above_ the frequency of the browser, + * but instead can use it to throttle the frame rate lower, should + * you need to in certain situations. + * @param fps The frame rate to tick at. Default 240. */ - preUpdate(): void; + setFps(fps?: number): this; /** - * Updates all Tweens and Timelines of the Tween Manager. - * @param timestamp The current time in milliseconds. - * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. + * Internal method that calculates the delta value, along with the other timing values, + * and returns the new delta. + * + * You should not typically call this method directly. + * @param tick Is this a manual tick, or an automated tick? Default false. */ - update(timestamp: number, delta: number): void; + getDelta(tick?: boolean): number; /** - * Removes the given tween from the Tween Manager, regardless of its state (pending or active). + * Manually advance the Tween system by one step. + * + * This will update all Tweens even if the Tween Manager is currently + * paused. + */ + tick(): this; + + /** + * Internal update handler. + * + * Calls `TweenManager.step` as long as the Tween Manager has not + * been paused. + */ + update(): void; + + /** + * Updates all Tweens belonging to this Tween Manager. + * + * Called automatically by `update` and `tick`. + * @param tick Is this a manual tick, or an automated tick? Default false. + */ + step(tick?: boolean): void; + + /** + * Removes the given Tween from this Tween Manager, even if it hasn't started + * playback yet. If this method is called while the Tween Manager is processing + * an update loop, then the tween will be flagged for removal at the start of + * the next frame. Otherwise, it is removed immediately. + * + * The removed tween is _not_ destroyed. It is just removed from this Tween Manager. * @param tween The Tween to be removed. */ - remove(tween: Phaser.Tweens.Tween): Phaser.Tweens.TweenManager; + remove(tween: Phaser.Tweens.Tween): this; /** - * Checks if a Tween or Timeline is active and adds it to the Tween Manager at the start of the frame if it isn't. + * Resets the given Tween. + * + * If the Tween does not belong to this Tween Manager, it will first be added. + * + * Then it will seek to position 0 and playback will start on the next frame. + * @param tween The Tween to be reset. + */ + reset(tween: Phaser.Tweens.Tween): this; + + /** + * Checks if a Tween is active and adds it to the Tween Manager at the start of the frame if it isn't. * @param tween The Tween to check. */ - makeActive(tween: Phaser.Tweens.Tween): Phaser.Tweens.TweenManager; + makeActive(tween: Phaser.Tweens.Tween): this; /** * Passes all Tweens to the given callback. @@ -96079,67 +112417,100 @@ declare namespace Phaser { * @param scope The scope (`this` object) to call the function with. * @param args The arguments to pass into the function. Its first argument will always be the Tween currently being iterated. */ - each(callback: Function, scope?: object, ...args: any[]): void; + each(callback: Function, scope?: object, ...args: any[]): this; /** - * Returns an array of all active Tweens and Timelines in the Tween Manager. + * Returns an array containing references to all Tweens in this Tween Manager. + * + * It is safe to mutate the returned array. However, acting upon any of the Tweens + * within it, will adjust those stored in this Tween Manager, as they are passed + * by reference and not cloned. + * + * If you wish to get tweens for a specific target, see `getTweensOf`. */ - getAllTweens(): Phaser.Tweens.Tween[]; + getTweens(): Phaser.Tweens.Tween[]; /** - * Returns the scale of the time delta for all Tweens and Timelines owned by this Tween Manager. + * Returns an array of all Tweens in the Tween Manager which affect the given target, or array of targets. + * + * It's possible for this method to return tweens that are about to be removed from + * the Tween Manager. You should check the state of the returned tween before acting + * upon it. + * @param target The target to look for. Provide an array to look for multiple targets. */ - getGlobalTimeScale(): number; + getTweensOf(target: object | object[]): Phaser.Tweens.Tween[]; /** - * Returns an array of all Tweens or Timelines in the Tween Manager which affect the given target or array of targets. - * - * Only the currently active tweens are tested. A tween that has completed and is - * awaiting removal will not be included in the results. - * - * If you wish to also search pending tweens, use the `includePending` flag. - * @param target The target to look for. Provide an array to look for multiple targets. - * @param includePending Also check for pending tweens, not just active ones? Default false. + * Returns the scale of the time delta for all Tweens owned by this Tween Manager. */ - getTweensOf(target: object | any[], includePending?: boolean): Phaser.Tweens.Tween[]; + getGlobalTimeScale(): number; /** - * Checks if the given object is being affected by a playing Tween. - * @param target target Phaser.Tweens.Tween object + * Sets a new scale of the time delta for this Tween Manager. + * + * The time delta is the time elapsed between two consecutive frames and influences the speed of time for this Tween Manager and all Tweens it owns. Values higher than 1 increase the speed of time, while values smaller than 1 decrease it. A value of 0 freezes time and is effectively equivalent to pausing all Tweens. + * @param value The new scale of the time delta, where 1 is the normal speed. */ - isTweening(target: object): boolean; + setGlobalTimeScale(value: number): this; /** - * Stops all Tweens in this Tween Manager. They will be removed at the start of the frame. + * Checks if the given object is being affected by a _playing_ Tween. + * + * If the Tween is paused, this method will return false. + * @param target The object to check if a tween is active for it, or not. */ - killAll(): Phaser.Tweens.TweenManager; + isTweening(target: object): boolean; /** - * Stops all Tweens which affect the given target or array of targets. The Tweens will be removed from the Tween Manager at the start of the frame. - * @param target The target to look for. Provide an array to look for multiple targets. + * Destroys all Tweens in this Tween Manager. + * + * The tweens will erase all references to any targets they hold + * and be stopped immediately. + * + * If this method is called while the Tween Manager is running its + * update process, then the tweens will be removed at the start of + * the next frame. Outside of this, they are removed immediately. */ - killTweensOf(target: object | any[]): Phaser.Tweens.TweenManager; + killAll(): this; /** - * Pauses all Tweens in this Tween Manager. + * Stops all Tweens which affect the given target or array of targets. + * + * The tweens will erase all references to any targets they hold + * and be stopped immediately. + * + * If this method is called while the Tween Manager is running its + * update process, then the tweens will be removed at the start of + * the next frame. Outside of this, they are removed immediately. + * @param target The target to kill the tweens of. Provide an array to use multiple targets. */ - pauseAll(): Phaser.Tweens.TweenManager; + killTweensOf(target: object | any[]): this; /** - * Resumes all Tweens in this Tween Manager. + * Pauses this Tween Manager. No Tweens will update while paused. + * + * This includes tweens created after this method was called. + * + * See `TweenManager#resumeAll` to resume the playback. + * + * As of Phaser 3.60 you can also toggle the boolean property `TweenManager.paused`. */ - resumeAll(): Phaser.Tweens.TweenManager; + pauseAll(): this; /** - * Sets a new scale of the time delta for this Tween Manager. + * Resumes playback of this Tween Manager. * - * The time delta is the time elapsed between two consecutive frames and influences the speed of time for this Tween Manager and all Tweens it owns. Values higher than 1 increase the speed of time, while values smaller than 1 decrease it. A value of 0 freezes time and is effectively equivalent to pausing all Tweens. - * @param value The new scale of the time delta, where 1 is the normal speed. + * All active Tweens will continue updating. + * + * See `TweenManager#pauseAll` to pause the playback. + * + * As of Phaser 3.60 you can also toggle the boolean property `TweenManager.paused`. */ - setGlobalTimeScale(value: number): Phaser.Tweens.TweenManager; + resumeAll(): this; /** * The Scene that owns this plugin is shutting down. + * * We need to kill and reset all internal properties as well as stop listening to Scene events. */ shutdown(): void; @@ -96246,6 +112617,13 @@ declare namespace Phaser { */ function FindClosestInSorted(value: number, array: any[], key?: string): number | any; + /** + * Takes an array and flattens it, returning a shallow-copy flattened array. + * @param array The array to flatten. + * @param output An array to hold the results in. + */ + function Flatten(array: any[], output?: any[]): any[]; + /** * Returns all elements in the array. * @@ -96294,7 +112672,7 @@ declare namespace Phaser { * Checks if an array can be used as a matrix. * * A matrix is a two-dimensional array (array of arrays), where all sub-arrays (rows) - * have the same length. There must be at least two rows. This is an example matrix: + * have the same length. This is an example matrix: * * ``` * [ @@ -96818,6 +113196,16 @@ declare namespace Phaser { */ function NOOP(): void; + /** + * A NULL OP callback function. + * + * This function always returns `null`. + * + * Used internally by Phaser when it's more expensive to determine if a callback exists + * than it is to just invoke an empty function. + */ + function NULL(): void; + namespace Objects { /** * Shallow Object Clone. Will not clone nested objects. @@ -96891,12 +113279,36 @@ declare namespace Phaser { function GetMinMaxValue(source: object, key: string, min: number, max: number, defaultValue: number): number; /** - * Retrieves a value from an object. - * @param source The object to retrieve the value from. + * Retrieves a value from an object, or an alternative object, falling to a back-up default value if not found. + * + * The key is a string, which can be split based on the use of the period character. + * + * For example: + * + * ```javascript + * const source = { + * lives: 3, + * render: { + * screen: { + * width: 1024 + * } + * } + * } + * + * const lives = GetValue(source, 'lives', 1); + * const width = GetValue(source, 'render.screen.width', 800); + * const height = GetValue(source, 'render.screen.height', 600); + * ``` + * + * In the code above, `lives` will be 3 because it's defined at the top level of `source`. + * The `width` value will be 1024 because it can be found inside the `render.screen` object. + * The `height` value will be 600, the default value, because it is missing from the `render.screen` object. + * @param source The primary object to try to retrieve the value from. If not found in here, `altSource` is checked. * @param key The name of the property to retrieve from the object. If a property is nested, the names of its preceding properties should be separated by a dot (`.`) - `banner.hideBanner` would return the value of the `hideBanner` property from the object stored in the `banner` property of the `source` object. * @param defaultValue The value to return if the `key` isn't found in the `source` object. + * @param altSource An alternative object to retrieve the value from. If the property exists in `source` then `altSource` will not be used. */ - function GetValue(source: object, key: string, defaultValue: any): any; + function GetValue(source: object, key: string, defaultValue: any, altSource?: object): any; /** * Verifies that an object contains all requested keys @@ -97154,7 +113566,7 @@ declare namespace Phaser { * * This value is populated automatically during boot. */ - contextType: string; + contextType: string | null; /** * The current locale. @@ -97162,31 +113574,31 @@ declare namespace Phaser { * Use this to determine what languages the current game should be localized with. * This value is populated automatically during boot. */ - locale: string; + locale: string | null; /** * The platform on which the game is currently running, i.e. `IOS`. * This value is populated automatically during boot. */ - platform: string; + platform: string | null; /** * The string representation of the Facebook Instant Games SDK version being used. * This value is populated automatically during boot. */ - version: string; + version: string | null; /** * Holds the id of the player. This is a string based ID, the same as `FBInstant.player.getID()`. * This value is populated automatically during boot if the API is supported. */ - playerID: string; + playerID: string | null; /** * The player's localized display name. * This value is populated automatically during boot if the API is supported. */ - playerName: string; + playerName: string | null; /** * A url to the player's public profile photo. The photo will always be a square, and with dimensions @@ -97194,7 +113606,7 @@ declare namespace Phaser { * It's recommended to always scale the image to a desired size before rendering. * This value is populated automatically during boot if the API is supported. */ - playerPhotoURL: string; + playerPhotoURL: string | null; /** * Whether a player can subscribe to the game bot or not. @@ -97277,7 +113689,7 @@ declare namespace Phaser { * * It is only populated if `contextGetType` is in the list of supported APIs. */ - getType(): string; + getType(): string | null; /** * Returns the current locale. @@ -97285,31 +113697,31 @@ declare namespace Phaser { * Use this to determine what languages the current game should be localized with. * It is only populated if `getLocale` is in the list of supported APIs. */ - getLocale(): string; + getLocale(): string | null; /** * Returns the platform on which the game is currently running, i.e. `IOS`. * It is only populated if `getPlatform` is in the list of supported APIs. */ - getPlatform(): string; + getPlatform(): string | null; /** * Returns the string representation of the Facebook Instant Games SDK version being used. * It is only populated if `getSDKVersion` is in the list of supported APIs. */ - getSDKVersion(): string; + getSDKVersion(): string | null; /** * Returns the id of the player. This is a string based ID, the same as `FBInstant.player.getID()`. * It is only populated if `playerGetID` is in the list of supported APIs. */ - getPlayerID(): string; + getPlayerID(): string | null; /** * Returns the player's localized display name. * It is only populated if `playerGetName` is in the list of supported APIs. */ - getPlayerName(): string; + getPlayerName(): string | null; /** * Returns the url to the player's public profile photo. The photo will always be a square, and with dimensions @@ -97317,7 +113729,7 @@ declare namespace Phaser { * It's recommended to always scale the image to a desired size before rendering. * It is only populated if `playerGetPhoto` is in the list of supported APIs. */ - getPlayerPhotoURL(): string; + getPlayerPhotoURL(): string | null; /** * Load the player's photo and store it in the Texture Manager, ready for use in-game. @@ -97609,7 +114021,7 @@ declare namespace Phaser { * Use this to look-up product details based on a purchase list. * @param productID The Product ID of the item to get from the catalog. */ - getProduct(productID: string): Product; + getProduct(productID: string): Product | null; /** * Begins the purchase flow for a specific product. @@ -97684,7 +114096,7 @@ declare namespace Phaser { * @param template The update template key. * @param updateData The update data object payload. */ - update(cta: string, text: object, key: string, frame: string | integer, template: string, updateData: object): this; + update(cta: string, text: object, key: string, frame: string | integer | undefined, template: string, updateData: object): this; /** * Informs Facebook of a leaderboard update that occurred in the game. @@ -97713,7 +114125,7 @@ declare namespace Phaser { * @param template The update template key. * @param updateData The update data object payload. */ - updateLeaderboard(cta: string, text: object, key: string, frame: string | integer, template: string, updateData: object): this; + updateLeaderboard(cta: string, text: object, key: string, frame: string | integer | undefined, template: string, updateData: object): this; /** * Request that the client switch to a different Instant Game. @@ -97943,25 +114355,26 @@ declare namespace Phaser { } -declare type ArcadePhysicsCallback = (object1: Phaser.Types.Physics.Arcade.GameObjectWithBody, object2: Phaser.Types.Physics.Arcade.GameObjectWithBody)=>void; - declare type WebGLContextCallback = (renderer: Phaser.Renderer.WebGL.WebGLRenderer)=>void; declare type EachListCallback = (item: I, ...args: any[])=>void; -declare type EachMapCallback = (key: string, entry: E)=>void; +declare type EachMapCallback = (key: string, entry: E)=>boolean | null; -declare type EachSetCallback = (entry: E, index: number)=>void; +declare type EachSetCallback = (entry: E, index: number)=>boolean | null; declare type EachTextureCallback = (texture: Phaser.Textures.Texture, ...args: any[])=>void; -declare type FindTileCallback = (value: Phaser.Tilemaps.Tile, index: number, array: Phaser.Tilemaps.Tile[])=>void; +declare type FindTileCallback = (value: Phaser.Tilemaps.Tile, index: number, array: Phaser.Tilemaps.Tile[])=>boolean; declare type EachTileCallback = (value: Phaser.Tilemaps.Tile, index: number, array: Phaser.Tilemaps.Tile[])=>void; -declare type TilemapFilterCallback = (value: Phaser.GameObjects.GameObject, index: number, array: Phaser.GameObjects.GameObject[])=>void; +/** + * A predicate, to test each element of the array. + */ +declare type TilemapFilterCallback = (value: Phaser.GameObjects.GameObject, index: number, array: Phaser.GameObjects.GameObject[])=>boolean; -declare type TilemapFindCallback = (value: Phaser.GameObjects.GameObject, index: number, array: Phaser.GameObjects.GameObject[])=>void; +declare type TilemapFindCallback = (value: Phaser.GameObjects.GameObject, index: number, array: Phaser.GameObjects.GameObject[])=>boolean; /** * Phaser.Class diff --git a/source/editor/plugins/phasereditor2d.scene/code-resources/js-module/ScriptNode.js b/source/editor/plugins/phasereditor2d.scene/code-resources/js-module/ScriptNode.js new file mode 100755 index 000000000..869743607 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/code-resources/js-module/ScriptNode.js @@ -0,0 +1,186 @@ +import Phaser from "phaser"; + + +export default class ScriptNode { + + /** + * @private + * @type {Phaser.Scene} + */ + _scene; + + /** + * @private + * @type {Phaser.GameObjects.GameObject} + */ + _gameObject; + + /** + * @private + * @type {ScriptNode | Phaser.GameObjects.GameObject | Phaser.Scene} + */ + _parent; + + /** + * @private + * @type {ScriptNode[]} + */ + _children; + + /** + * + * @param {ScriptNode | Phaser.GameObjects.GameObject | Phaser.Scene} parent + */ + constructor(parent) { + + this._parent = parent; + + if (parent instanceof ScriptNode) { + + this._scene = parent.scene; + this._gameObject = parent.gameObject; + + parent.add(this); + + } else if (parent instanceof Phaser.GameObjects.GameObject) { + + this._scene = parent.scene; + this._gameObject = parent; + + } else { + + this._scene = parent; + } + + const listenAwake = this.awake !== ScriptNode.prototype.awake; + const listenStart = this.start !== ScriptNode.prototype.start; + const listenUpdate = this.update !== ScriptNode.prototype.update; + const listenDestroy = this.destroy !== ScriptNode.prototype.destroy; + + if (listenAwake) { + + this.scene.events.once("scene-awake", this.awake, this); + } + + if (listenStart) { + + this.scene.events.once(Phaser.Scenes.Events.UPDATE, this.start, this); + } + + if (listenUpdate) { + + this.scene.events.on(Phaser.Scenes.Events.UPDATE, this.update, this); + } + + if (listenStart || listenUpdate || listenDestroy) { + + const destroyCallback = () => { + + this.scene.events.off(Phaser.Scenes.Events.UPDATE, this.start, this); + this.scene.events.off(Phaser.Scenes.Events.UPDATE, this.update, this); + + if (listenDestroy) { + + this.destroy(); + } + }; + + if (this.gameObject) { + + this.gameObject.on(Phaser.GameObjects.Events.DESTROY, destroyCallback); + + } else { + + this.scene.events.on(Phaser.Scenes.Events.DESTROY, destroyCallback); + } + } + } + + get scene() { + + return this._scene; + } + + get gameObject() { + + return this._gameObject; + } + + get parent() { + + return this._parent; + } + + /** + * @type {ScriptNode[]} + */ + get children() { + + if (!this._children) { + + this._children = []; + } + + return this._children; + } + + /** + * + * @param {ScriptNode} child + */ + add(child) { + + this.children.push(child); + } + + /** + * + * @param {any | undefined} args + */ + executeChildren(args) { + + if (this._children) { + + for(const child of this._children) { + + child.execute(args); + } + } + } + + /** + * + * @param {any | undefined} args + */ + execute(args) { + // override this on executable nodes + } + + /** + * @protected + */ + awake() { + // override this + } + + /** + * @protected + */ + start() { + // override this + } + + /** + * @protected + */ + update() { + // override this + } + + /** + * @protected + */ + destroy() { + // override this + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/code-resources/js/ScriptNode.js b/source/editor/plugins/phasereditor2d.scene/code-resources/js/ScriptNode.js new file mode 100755 index 000000000..3fbdc6bc6 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/code-resources/js/ScriptNode.js @@ -0,0 +1,183 @@ +class ScriptNode { + + /** + * @private + * @type {Phaser.Scene} + */ + _scene; + + /** + * @private + * @type {Phaser.GameObjects.GameObject} + */ + _gameObject; + + /** + * @private + * @type {ScriptNode | Phaser.GameObjects.GameObject | Phaser.Scene} + */ + _parent; + + /** + * @private + * @type {ScriptNode[]} + */ + _children; + + /** + * + * @param {ScriptNode | Phaser.GameObjects.GameObject | Phaser.Scene} parent + */ + constructor(parent) { + + this._parent = parent; + + if (parent instanceof ScriptNode) { + + this._scene = parent.scene; + this._gameObject = parent.gameObject; + + parent.add(this); + + } else if (parent instanceof Phaser.GameObjects.GameObject) { + + this._scene = parent.scene; + this._gameObject = parent; + + } else { + + this._scene = parent; + } + + const listenAwake = this.awake !== ScriptNode.prototype.awake; + const listenStart = this.start !== ScriptNode.prototype.start; + const listenUpdate = this.update !== ScriptNode.prototype.update; + const listenDestroy = this.destroy !== ScriptNode.prototype.destroy; + + if (listenAwake) { + + this.scene.events.once("scene-awake", this.awake, this); + } + + if (listenStart) { + + this.scene.events.once(Phaser.Scenes.Events.UPDATE, this.start, this); + } + + if (listenUpdate) { + + this.scene.events.on(Phaser.Scenes.Events.UPDATE, this.update, this); + } + + if (listenStart || listenUpdate || listenDestroy) { + + const destroyCallback = () => { + + this.scene.events.off(Phaser.Scenes.Events.UPDATE, this.start, this); + this.scene.events.off(Phaser.Scenes.Events.UPDATE, this.update, this); + + if (listenDestroy) { + + this.destroy(); + } + }; + + if (this.gameObject) { + + this.gameObject.on(Phaser.GameObjects.Events.DESTROY, destroyCallback); + + } else { + + this.scene.events.on(Phaser.Scenes.Events.DESTROY, destroyCallback); + } + } + } + + get scene() { + + return this._scene; + } + + get gameObject() { + + return this._gameObject; + } + + get parent() { + + return this._parent; + } + + /** + * @type {ScriptNode[]} + */ + get children() { + + if (!this._children) { + + this._children = []; + } + + return this._children; + } + + /** + * + * @param {ScriptNode} child + */ + add(child) { + + this.children.push(child); + } + + /** + * + * @param {any | undefined} args + */ + executeChildren(args) { + + if (this._children) { + + for(const child of this._children) { + + child.execute(args); + } + } + } + + /** + * + * @param {any | undefined} args + */ + execute(args) { + // override this on executable nodes + } + + /** + * @protected + */ + awake() { + // override this + } + + /** + * @protected + */ + start() { + // override this + } + + /** + * @protected + */ + update() { + // override this + } + + /** + * @protected + */ + destroy() { + // override this + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/code-resources/ts-module/ScriptNode.ts b/source/editor/plugins/phasereditor2d.scene/code-resources/ts-module/ScriptNode.ts new file mode 100755 index 000000000..aa45c8079 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/code-resources/ts-module/ScriptNode.ts @@ -0,0 +1,135 @@ +import Phaser from "phaser"; + +export default class ScriptNode { + + private _scene: Phaser.Scene; + private _gameObject?: Phaser.GameObjects.GameObject; + private _parent: ScriptNode | Phaser.GameObjects.GameObject | Phaser.Scene; + private _children?: ScriptNode[]; + + constructor(parent: ScriptNode | Phaser.GameObjects.GameObject | Phaser.Scene) { + + this._parent = parent; + + if (parent instanceof ScriptNode) { + + this._scene = parent.scene; + this._gameObject = parent.gameObject; + + parent.add(this); + + } else if (parent instanceof Phaser.GameObjects.GameObject) { + + this._scene = parent.scene; + this._gameObject = parent; + + } else { + + this._scene = parent; + } + + const listenAwake = this.awake !== ScriptNode.prototype.awake; + const listenStart = this.start !== ScriptNode.prototype.start; + const listenUpdate = this.update !== ScriptNode.prototype.update; + const listenDestroy = this.destroy !== ScriptNode.prototype.destroy; + + if (listenAwake) { + + this.scene.events.once("scene-awake", this.awake, this); + } + + if (listenStart) { + + this.scene.events.once(Phaser.Scenes.Events.UPDATE, this.start, this); + } + + if (listenUpdate) { + + this.scene.events.on(Phaser.Scenes.Events.UPDATE, this.update, this); + } + + if (listenStart || listenUpdate || listenDestroy) { + + const destroyCallback = () => { + + this.scene.events.off(Phaser.Scenes.Events.UPDATE, this.start, this); + this.scene.events.off(Phaser.Scenes.Events.UPDATE, this.update, this); + + if (listenDestroy) { + + this.destroy(); + } + }; + + if (this.gameObject) { + + this.gameObject.on(Phaser.GameObjects.Events.DESTROY, destroyCallback); + + } else { + + this.scene.events.on(Phaser.Scenes.Events.DESTROY, destroyCallback); + } + } + } + + get scene() { + + return this._scene; + } + + get gameObject() { + + return this._gameObject; + } + + get parent() { + + return this._parent; + } + + get children(): ScriptNode[] { + + if (!this._children) { + + this._children = []; + } + + return this._children; + } + + add(child: ScriptNode) { + + this.children.push(child); + } + + executeChildren(args?: any) { + + if (this._children) { + + for(const child of this._children) { + + child.execute(args); + } + } + } + + execute(args?: any): void { + // override this on executable nodes + } + + protected awake() { + // override this + } + + protected start() { + // override this + } + + protected update() { + // override this + } + + protected destroy() { + // override this + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/code-resources/ts/ScriptNode.ts b/source/editor/plugins/phasereditor2d.scene/code-resources/ts/ScriptNode.ts new file mode 100755 index 000000000..d76670ddd --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/code-resources/ts/ScriptNode.ts @@ -0,0 +1,133 @@ +class ScriptNode { + + private _scene: Phaser.Scene; + private _gameObject?: Phaser.GameObjects.GameObject; + private _parent: ScriptNode | Phaser.GameObjects.GameObject | Phaser.Scene; + private _children?: ScriptNode[]; + + constructor(parent: ScriptNode | Phaser.GameObjects.GameObject | Phaser.Scene) { + + this._parent = parent; + + if (parent instanceof ScriptNode) { + + this._scene = parent.scene; + this._gameObject = parent.gameObject; + + parent.add(this); + + } else if (parent instanceof Phaser.GameObjects.GameObject) { + + this._scene = parent.scene; + this._gameObject = parent; + + } else { + + this._scene = parent; + } + + const listenAwake = this.awake !== ScriptNode.prototype.awake; + const listenStart = this.start !== ScriptNode.prototype.start; + const listenUpdate = this.update !== ScriptNode.prototype.update; + const listenDestroy = this.destroy !== ScriptNode.prototype.destroy; + + if (listenAwake) { + + this.scene.events.once("scene-awake", this.awake, this); + } + + if (listenStart) { + + this.scene.events.once(Phaser.Scenes.Events.UPDATE, this.start, this); + } + + if (listenUpdate) { + + this.scene.events.on(Phaser.Scenes.Events.UPDATE, this.update, this); + } + + if (listenStart || listenUpdate || listenDestroy) { + + const destroyCallback = () => { + + this.scene.events.off(Phaser.Scenes.Events.UPDATE, this.start, this); + this.scene.events.off(Phaser.Scenes.Events.UPDATE, this.update, this); + + if (listenDestroy) { + + this.destroy(); + } + }; + + if (this.gameObject) { + + this.gameObject.on(Phaser.GameObjects.Events.DESTROY, destroyCallback); + + } else { + + this.scene.events.on(Phaser.Scenes.Events.DESTROY, destroyCallback); + } + } + } + + get scene() { + + return this._scene; + } + + get gameObject() { + + return this._gameObject; + } + + get parent() { + + return this._parent; + } + + get children(): ScriptNode[] { + + if (!this._children) { + + this._children = []; + } + + return this._children; + } + + add(child: ScriptNode) { + + this.children.push(child); + } + + executeChildren(args?: any) { + + if (this._children) { + + for(const child of this._children) { + + child.execute(args); + } + } + } + + execute(args?: any): void { + // override this on executable nodes + } + + protected awake() { + // override this + } + + protected start() { + // override this + } + + protected update() { + // override this + } + + protected destroy() { + // override this + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/data/phaser-docs.json b/source/editor/plugins/phasereditor2d.scene/data/phaser-docs.json index a4e330592..17bdf2dd9 100644 --- a/source/editor/plugins/phasereditor2d.scene/data/phaser-docs.json +++ b/source/editor/plugins/phasereditor2d.scene/data/phaser-docs.json @@ -1,54 +1,59 @@ { - "Phaser.GameObjects.Image": "An Image Game Object.\r\rAn Image is a light-weight Game Object useful for the display of static images in your game,\rsuch as logos, backgrounds, scenery or other non-animated elements. Images can have input\revents and physics bodies, or be tweened, tinted or scrolled. The main difference between an\rImage and a Sprite is that you cannot animate an Image as they do not have the Animation component.", - "Phaser.GameObjects.Sprite": "A Sprite Game Object.\r\rA Sprite Game Object is used for the display of both static and animated images in your game.\rSprites can have input events and physics bodies. They can also be tweened, tinted, scrolled\rand animated.\r\rThe main difference between a Sprite and an Image Game Object is that you cannot animate Images.\rAs such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation\rComponent. If you do not require animation then you can safely use Images to replace Sprites in all cases.", - "Phaser.GameObjects.Container": "A Container Game Object.\r\rA Container, as the name implies, can 'contain' other types of Game Object.\rWhen a Game Object is added to a Container, the Container becomes responsible for the rendering of it.\rBy default it will be removed from the Display List and instead added to the Containers own internal list.\r\rThe position of the Game Object automatically becomes relative to the position of the Container.\r\rThe transform point of a Container is 0x0 (in local space) and that cannot be changed. The children you add to the\rContainer should be positioned with this value in mind. I.e. you should treat 0x0 as being the center of\rthe Container, and position children positively and negative around it as required.\r\rWhen the Container is rendered, all of its children are rendered as well, in the order in which they exist\rwithin the Container. Container children can be repositioned using methods such as `MoveUp`, `MoveDown` and `SendToBack`.\r\rIf you modify a transform property of the Container, such as `Container.x` or `Container.rotation` then it will\rautomatically influence all children as well.\r\rContainers can include other Containers for deeply nested transforms.\r\rContainers can have masks set on them and can be used as a mask too. However, Container children cannot be masked.\rThe masks do not 'stack up'. Only a Container on the root of the display list will use its mask.\r\rContainers can be enabled for input. Because they do not have a texture you need to provide a shape for them\rto use as their hit area. Container children can also be enabled for input, independent of the Container.\r\rIf input enabling a _child_ you should not set both the `origin` and a **negative** scale factor on the child,\ror the input area will become misaligned.\r\rContainers can be given a physics body for either Arcade Physics, Impact Physics or Matter Physics. However,\rif Container _children_ are enabled for physics you may get unexpected results, such as offset bodies,\rif the Container itself, or any of its ancestors, is positioned anywhere other than at 0 x 0. Container children\rwith physics do not factor in the Container due to the excessive extra calculations needed. Please structure\ryour game to work around this.\r\rIt's important to understand the impact of using Containers. They add additional processing overhead into\revery one of their children. The deeper you nest them, the more the cost escalates. This is especially true\rfor input events. You also loose the ability to set the display depth of Container children in the same\rflexible manner as those not within them. In short, don't use them for the sake of it. You pay a small cost\revery time you create one, try to structure your game around avoiding that where possible.", + "Phaser.GameObjects.Image": "An Image Game Object.\n\nAn Image is a light-weight Game Object useful for the display of static images in your game,\nsuch as logos, backgrounds, scenery or other non-animated elements. Images can have input\nevents and physics bodies, or be tweened, tinted or scrolled. The main difference between an\nImage and a Sprite is that you cannot animate an Image as they do not have the Animation component.", + "Phaser.GameObjects.Sprite": "A Sprite Game Object.\n\nA Sprite Game Object is used for the display of both static and animated images in your game.\nSprites can have input events and physics bodies. They can also be tweened, tinted, scrolled\nand animated.\n\nThe main difference between a Sprite and an Image Game Object is that you cannot animate Images.\nAs such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation\nComponent. If you do not require animation then you can safely use Images to replace Sprites in all cases.", + "Phaser.GameObjects.Container": "A Container Game Object.\n\nA Container, as the name implies, can 'contain' other types of Game Object.\nWhen a Game Object is added to a Container, the Container becomes responsible for the rendering of it.\nBy default it will be removed from the Display List and instead added to the Containers own internal list.\n\nThe position of the Game Object automatically becomes relative to the position of the Container.\n\nThe transform point of a Container is 0x0 (in local space) and that cannot be changed. The children you add to the\nContainer should be positioned with this value in mind. I.e. you should treat 0x0 as being the center of\nthe Container, and position children positively and negative around it as required.\n\nWhen the Container is rendered, all of its children are rendered as well, in the order in which they exist\nwithin the Container. Container children can be repositioned using methods such as `MoveUp`, `MoveDown` and `SendToBack`.\n\nIf you modify a transform property of the Container, such as `Container.x` or `Container.rotation` then it will\nautomatically influence all children as well.\n\nContainers can include other Containers for deeply nested transforms.\n\nContainers can have masks set on them and can be used as a mask too. However, Container children cannot be masked.\nThe masks do not 'stack up'. Only a Container on the root of the display list will use its mask.\n\nContainers can be enabled for input. Because they do not have a texture you need to provide a shape for them\nto use as their hit area. Container children can also be enabled for input, independent of the Container.\n\nIf input enabling a _child_ you should not set both the `origin` and a **negative** scale factor on the child,\nor the input area will become misaligned.\n\nContainers can be given a physics body for either Arcade Physics, Impact Physics or Matter Physics. However,\nif Container _children_ are enabled for physics you may get unexpected results, such as offset bodies,\nif the Container itself, or any of its ancestors, is positioned anywhere other than at 0 x 0. Container children\nwith physics do not factor in the Container due to the excessive extra calculations needed. Please structure\nyour game to work around this.\n\nIt's important to understand the impact of using Containers. They add additional processing overhead into\nevery one of their children. The deeper you nest them, the more the cost escalates. This is especially true\nfor input events. You also loose the ability to set the display depth of Container children in the same\nflexible manner as those not within them. In short, don't use them for the sake of it. You pay a small cost\nevery time you create one, try to structure your game around avoiding that where possible.", "Phaser.GameObjects.Components.Transform.x": "The x position of this Game Object.", "Phaser.GameObjects.Components.Transform.y": "The y position of this Game Object.", "Phaser.GameObjects.Components.Transform.setPosition": "Sets the position of this Game Object.", "Phaser.GameObjects.Components.Transform.scaleX": "The horizontal scale of this Game Object.", "Phaser.GameObjects.Components.Transform.scaleY": "The vertical scale of this Game Object.", - "Phaser.GameObjects.Components.Transform.angle": "The angle of this Game Object as expressed in degrees.\r\rPhaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left\rand -90 is up.\r\rIf you prefer to work in radians, see the `rotation` property instead.", - "Phaser.GameObjects.Components.Origin.originX": "The horizontal origin of this Game Object.\rThe origin maps the relationship between the size and position of the Game Object.\rThe default value is 0.5, meaning all Game Objects are positioned based on their center.\rSetting the value to 0 means the position now relates to the left of the Game Object.", - "Phaser.GameObjects.Components.Origin.originY": "The vertical origin of this Game Object.\rThe origin maps the relationship between the size and position of the Game Object.\rThe default value is 0.5, meaning all Game Objects are positioned based on their center.\rSetting the value to 0 means the position now relates to the top of the Game Object.", - "Phaser.GameObjects.Components.Origin.setOrigin": "Sets the origin of this Game Object.\r\rThe values are given in the range 0 to 1.", - "Phaser.GameObjects.Components.Alpha.alpha": "The alpha value of the Game Object.\r\rThis is a global value, impacting the entire Game Object, not just a region of it.", - "Phaser.GameObjects.Components.Alpha.alphaTopLeft": "The alpha value starting from the top-left of the Game Object.\rThis value is interpolated from the corner to the center of the Game Object.", - "Phaser.GameObjects.Components.Alpha.alphaTopRight": "The alpha value starting from the top-right of the Game Object.\rThis value is interpolated from the corner to the center of the Game Object.", - "Phaser.GameObjects.Components.Alpha.alphaBottomLeft": "The alpha value starting from the bottom-left of the Game Object.\rThis value is interpolated from the corner to the center of the Game Object.", - "Phaser.GameObjects.Components.Alpha.alphaBottomRight": "The alpha value starting from the bottom-right of the Game Object.\rThis value is interpolated from the corner to the center of the Game Object.", - "Phaser.GameObjects.Components.Flip.flipX": "The horizontally flipped state of the Game Object.\r\rA Game Object that is flipped horizontally will render inversed on the horizontal axis.\rFlipping always takes place from the middle of the texture and does not impact the scale value.\rIf this Game Object has a physics body, it will not change the body. This is a rendering toggle only.", - "Phaser.GameObjects.Components.Flip.flipY": "The vertically flipped state of the Game Object.\r\rA Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down)\rFlipping always takes place from the middle of the texture and does not impact the scale value.\rIf this Game Object has a physics body, it will not change the body. This is a rendering toggle only.", - "Phaser.GameObjects.Components.Visible.visible": "The visible state of the Game Object.\r\rAn invisible Game Object will skip rendering, but will still process update logic.", - "Phaser.GameObjects.Components.Tint.tint": "The tint value being applied to the whole of the Game Object.\rThis property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value.", - "Phaser.GameObjects.Components.Tint.tintFill": "The tint fill mode.\r\r`false` = An additive tint (the default), where vertices colors are blended with the texture.\r`true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha.", - "Phaser.GameObjects.Components.Tint.tintTopLeft": "The tint value being applied to the top-left vertice of the Game Object.\rThis value is interpolated from the corner to the center of the Game Object.\rThe value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.", - "Phaser.GameObjects.Components.Tint.tintTopRight": "The tint value being applied to the top-right vertice of the Game Object.\rThis value is interpolated from the corner to the center of the Game Object.\rThe value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.", - "Phaser.GameObjects.Components.Tint.tintBottomLeft": "The tint value being applied to the bottom-left vertice of the Game Object.\rThis value is interpolated from the corner to the center of the Game Object.\rThe value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.", - "Phaser.GameObjects.Components.Tint.tintBottomRight": "The tint value being applied to the bottom-right vertice of the Game Object.\rThis value is interpolated from the corner to the center of the Game Object.\rThe value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.", - "Phaser.GameObjects.TileSprite": "A TileSprite is a Sprite that has a repeating texture.\r\rThe texture can be scrolled and scaled independently of the TileSprite itself. Textures will automatically wrap and\rare designed so that you can create game backdrops using seamless textures as a source.\r\rYou shouldn't ever create a TileSprite any larger than your actual canvas size. If you want to create a large repeating background\rthat scrolls across the whole map of your game, then you create a TileSprite that fits the canvas size and then use the `tilePosition`\rproperty to scroll the texture as the player moves. If you create a TileSprite that is thousands of pixels in size then it will\rconsume huge amounts of memory and cause performance issues. Remember: use `tilePosition` to scroll your texture and `tileScale` to\radjust the scale of the texture - don't resize the sprite itself or make it larger than it needs.\r\rAn important note about Tile Sprites and NPOT textures: Internally, TileSprite textures use GL_REPEAT to provide\rseamless repeating of the textures. This, combined with the way in which the textures are handled in WebGL, means\rthey need to be POT (power-of-two) sizes in order to wrap. If you provide a NPOT (non power-of-two) texture to a\rTileSprite it will generate a POT sized canvas and draw your texture to it, scaled up to the POT size. It's then\rscaled back down again during rendering to the original dimensions. While this works, in that it allows you to use\rany size texture for a Tile Sprite, it does mean that NPOT textures are going to appear anti-aliased when rendered,\rdue to the interpolation that took place when it was resized into a POT texture. This is especially visible in\rpixel art graphics. If you notice it and it becomes an issue, the only way to avoid it is to ensure that you\rprovide POT textures for Tile Sprites.", - "Phaser.GameObjects.Components.ComputedSize.width": "The native (un-scaled) width of this Game Object.\r\rChanging this value will not change the size that the Game Object is rendered in-game.\rFor that you need to either set the scale of the Game Object (`setScale`) or use\rthe `displayWidth` property.", - "Phaser.GameObjects.Components.ComputedSize.height": "The native (un-scaled) height of this Game Object.\r\rChanging this value will not change the size that the Game Object is rendered in-game.\rFor that you need to either set the scale of the Game Object (`setScale`) or use\rthe `displayHeight` property.", - "Phaser.GameObjects.Components.ComputedSize.setSize": "Sets the internal size of this Game Object, as used for frame or physics body creation.\r\rThis will not change the size that the Game Object is rendered in-game.\rFor that you need to either set the scale of the Game Object (`setScale`) or call the\r`setDisplaySize` method, which is the same thing as changing the scale but allows you\rto do so by giving pixel values.\r\rIf you have enabled this Game Object for input, changing the size will _not_ change the\rsize of the hit area. To do this you should adjust the `input.hitArea` object directly.", + "Phaser.GameObjects.Components.Transform.angle": "The angle of this Game Object as expressed in degrees.\n\nPhaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left\nand -90 is up.\n\nIf you prefer to work in radians, see the `rotation` property instead.", + "Phaser.GameObjects.Components.Origin.originX": "The horizontal origin of this Game Object.\nThe origin maps the relationship between the size and position of the Game Object.\nThe default value is 0.5, meaning all Game Objects are positioned based on their center.\nSetting the value to 0 means the position now relates to the left of the Game Object.\nSet this value with `setOrigin()`.", + "Phaser.GameObjects.Components.Origin.originY": "The vertical origin of this Game Object.\nThe origin maps the relationship between the size and position of the Game Object.\nThe default value is 0.5, meaning all Game Objects are positioned based on their center.\nSetting the value to 0 means the position now relates to the top of the Game Object.\nSet this value with `setOrigin()`.", + "Phaser.GameObjects.Components.Origin.setOrigin": "Sets the origin of this Game Object.\n\nThe values are given in the range 0 to 1.", + "Phaser.GameObjects.Components.Alpha.alpha": "The alpha value of the Game Object.\n\nThis is a global value, impacting the entire Game Object, not just a region of it.", + "Phaser.GameObjects.Components.Alpha.alphaTopLeft": "The alpha value starting from the top-left of the Game Object.\nThis value is interpolated from the corner to the center of the Game Object.", + "Phaser.GameObjects.Components.Alpha.alphaTopRight": "The alpha value starting from the top-right of the Game Object.\nThis value is interpolated from the corner to the center of the Game Object.", + "Phaser.GameObjects.Components.Alpha.alphaBottomLeft": "The alpha value starting from the bottom-left of the Game Object.\nThis value is interpolated from the corner to the center of the Game Object.", + "Phaser.GameObjects.Components.Alpha.alphaBottomRight": "The alpha value starting from the bottom-right of the Game Object.\nThis value is interpolated from the corner to the center of the Game Object.", + "Phaser.GameObjects.Components.Flip.flipX": "The horizontally flipped state of the Game Object.\n\nA Game Object that is flipped horizontally will render inversed on the horizontal axis.\nFlipping always takes place from the middle of the texture and does not impact the scale value.\nIf this Game Object has a physics body, it will not change the body. This is a rendering toggle only.", + "Phaser.GameObjects.Components.Flip.flipY": "The vertically flipped state of the Game Object.\n\nA Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down)\nFlipping always takes place from the middle of the texture and does not impact the scale value.\nIf this Game Object has a physics body, it will not change the body. This is a rendering toggle only.", + "Phaser.GameObjects.Components.Visible.visible": "The visible state of the Game Object.\n\nAn invisible Game Object will skip rendering, but will still process update logic.", + "Phaser.GameObjects.Components.Tint.tint": "The tint value being applied to the whole of the Game Object.\nThis property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value.", + "Phaser.GameObjects.Components.Tint.tintFill": "The tint fill mode.\n\n`false` = An additive tint (the default), where vertices colors are blended with the texture.\n`true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha.", + "Phaser.GameObjects.Components.Tint.tintTopLeft": "The tint value being applied to the top-left vertice of the Game Object.\nThis value is interpolated from the corner to the center of the Game Object.\nThe value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.", + "Phaser.GameObjects.Components.Tint.tintTopRight": "The tint value being applied to the top-right vertice of the Game Object.\nThis value is interpolated from the corner to the center of the Game Object.\nThe value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.", + "Phaser.GameObjects.Components.Tint.tintBottomLeft": "The tint value being applied to the bottom-left vertice of the Game Object.\nThis value is interpolated from the corner to the center of the Game Object.\nThe value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.", + "Phaser.GameObjects.Components.Tint.tintBottomRight": "The tint value being applied to the bottom-right vertice of the Game Object.\nThis value is interpolated from the corner to the center of the Game Object.\nThe value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.", + "Phaser.GameObjects.TileSprite": "A TileSprite is a Sprite that has a repeating texture.\n\nThe texture can be scrolled and scaled independently of the TileSprite itself. Textures will automatically wrap and\nare designed so that you can create game backdrops using seamless textures as a source.\n\nYou shouldn't ever create a TileSprite any larger than your actual canvas size. If you want to create a large repeating background\nthat scrolls across the whole map of your game, then you create a TileSprite that fits the canvas size and then use the `tilePosition`\nproperty to scroll the texture as the player moves. If you create a TileSprite that is thousands of pixels in size then it will\nconsume huge amounts of memory and cause performance issues. Remember: use `tilePosition` to scroll your texture and `tileScale` to\nadjust the scale of the texture - don't resize the sprite itself or make it larger than it needs.\n\nAn important note about Tile Sprites and NPOT textures: Internally, TileSprite textures use GL_REPEAT to provide\nseamless repeating of the textures. This, combined with the way in which the textures are handled in WebGL, means\nthey need to be POT (power-of-two) sizes in order to wrap. If you provide a NPOT (non power-of-two) texture to a\nTileSprite it will generate a POT sized canvas and draw your texture to it, scaled up to the POT size. It's then\nscaled back down again during rendering to the original dimensions. While this works, in that it allows you to use\nany size texture for a Tile Sprite, it does mean that NPOT textures are going to appear anti-aliased when rendered,\ndue to the interpolation that took place when it was resized into a POT texture. This is especially visible in\npixel art graphics. If you notice it and it becomes an issue, the only way to avoid it is to ensure that you\nprovide POT textures for Tile Sprites.", + "Phaser.GameObjects.Components.ComputedSize.width": "The native (un-scaled) width of this Game Object.\n\nChanging this value will not change the size that the Game Object is rendered in-game.\nFor that you need to either set the scale of the Game Object (`setScale`) or use\nthe `displayWidth` property.", + "Phaser.GameObjects.Components.ComputedSize.height": "The native (un-scaled) height of this Game Object.\n\nChanging this value will not change the size that the Game Object is rendered in-game.\nFor that you need to either set the scale of the Game Object (`setScale`) or use\nthe `displayHeight` property.", + "Phaser.GameObjects.Components.ComputedSize.setSize": "Sets the internal size of this Game Object, as used for frame or physics body creation.\n\nThis will not change the size that the Game Object is rendered in-game.\nFor that you need to either set the scale of the Game Object (`setScale`) or call the\n`setDisplaySize` method, which is the same thing as changing the scale but allows you\nto do so by giving pixel values.\n\nIf you have enabled this Game Object for input, changing the size will _not_ change the\nsize of the hit area. To do this you should adjust the `input.hitArea` object directly.", "Phaser.GameObjects.TileSprite.tilePositionX": "The horizontal scroll position of the Tile Sprite.", "Phaser.GameObjects.TileSprite.tilePositionY": "The vertical scroll position of the Tile Sprite.", "Phaser.GameObjects.TileSprite.setTilePosition": "Sets {@link Phaser.GameObjects.TileSprite#tilePositionX} and {@link Phaser.GameObjects.TileSprite#tilePositionY}.", "Phaser.GameObjects.TileSprite.tileScaleX": "The horizontal scale of the Tile Sprite texture.", "Phaser.GameObjects.TileSprite.tileScaleY": "The vertical scale of the Tile Sprite texture.", "Phaser.GameObjects.TileSprite.setTileScale": "Sets {@link Phaser.GameObjects.TileSprite#tileScaleX} and {@link Phaser.GameObjects.TileSprite#tileScaleY}.", + "Phaser.GameObjects.NineSlice": "A Nine Slice Game Object allows you to display a texture-based object that\ncan be stretched both horizontally and vertically, but that retains\nfixed-sized corners. The dimensions of the corners are set via the\nparameters to this class.\n\nThis is extremely useful for UI and button like elements, where you need\nthem to expand to accommodate the content without distorting the texture.\n\nThe texture you provide for this Game Object should be based on the\nfollowing layout structure:\n\n```\n A B\n +---+----------------------+---+\n C | 1 | 2 | 3 |\n +---+----------------------+---+\n | | | |\n | 4 | 5 | 6 |\n | | | |\n +---+----------------------+---+\n D | 7 | 8 | 9 |\n +---+----------------------+---+\n```\n\nWhen changing this objects width and / or height:\n\n areas 1, 3, 7 and 9 (the corners) will remain unscaled\n areas 2 and 8 will be stretched horizontally only\n areas 4 and 6 will be stretched vertically only\n area 5 will be stretched both horizontally and vertically\n\nYou can also create a 3 slice Game Object:\n\nThis works in a similar way, except you can only stretch it horizontally.\nTherefore, it requires less configuration:\n\n```\n A B\n +---+----------------------+---+\n | | | |\n C | 1 | 2 | 3 |\n | | | |\n +---+----------------------+---+\n```\n\nWhen changing this objects width (you cannot change its height)\n\n areas 1 and 3 will remain unscaled\n area 2 will be stretched horizontally\n\nThe above configuration concept is adapted from the Pixi NineSlicePlane.\n\nTo specify a 3 slice object instead of a 9 slice you should only\nprovide the `leftWidth` and `rightWidth` parameters. To create a 9 slice\nyou must supply all parameters.\n\nThe _minimum_ width this Game Object can be is the total of\n`leftWidth` + `rightWidth`. The _minimum_ height this Game Object\ncan be is the total of `topHeight` + `bottomHeight`.\nIf you need to display this object at a smaller size, you can scale it.\n\nIn terms of performance, using a 3 slice Game Object is the equivalent of\nhaving 3 Sprites in a row. Using a 9 slice Game Object is the equivalent\nof having 9 Sprites in a row. The vertices of this object are all batched\ntogether and can co-exist with other Sprites and graphics on the display\nlist, without incurring any additional overhead.\n\nAs of Phaser 3.60 this Game Object is WebGL only.", + "Phaser.GameObjects.NineSlice.leftWidth": "The size of the left vertical bar (A).", + "Phaser.GameObjects.NineSlice.rightWidth": "The size of the right vertical bar (B).", + "Phaser.GameObjects.NineSlice.topHeight": "The size of the top horizontal bar (C).\n\nIf this is a 3 slice object this property will be set to the\nheight of the texture being used.", + "Phaser.GameObjects.NineSlice.bottomHeight": "The size of the bottom horizontal bar (D).\n\nIf this is a 3 slice object this property will be set to zero.", "Phaser.GameObjects.GameObject.parentContainer": "The parent Container of this Game Object, if it has one.", - "Phaser.GameObjects.Text": "A Text Game Object.\r\rText objects work by creating their own internal hidden Canvas and then renders text to it using\rthe standard Canvas `fillText` API. It then creates a texture from this canvas which is rendered\rto your game during the render pass.\r\rBecause it uses the Canvas API you can take advantage of all the features this offers, such as\rapplying gradient fills to the text, or strokes, shadows and more. You can also use custom fonts\rloaded externally, such as Google or TypeKit Web fonts.\r\r**Important:** The font name must be quoted if it contains certain combinations of digits or\rspecial characters, either when creating the Text object, or when setting the font via `setFont`\ror `setFontFamily`, e.g.:\r\r```javascript\rthis.add.text(0, 0, 'Hello World', { fontFamily: 'Georgia, \"Goudy Bookletter 1911\", Times, serif' });\r```\r\r```javascript\rthis.add.text(0, 0, 'Hello World', { font: '\"Press Start 2P\"' });\r```\r\rYou can only display fonts that are currently loaded and available to the browser: therefore fonts must\rbe pre-loaded. Phaser does not do ths for you, so you will require the use of a 3rd party font loader,\ror have the fonts ready available in the CSS on the page in which your Phaser game resides.\r\rSee {@link http://www.jordanm.co.uk/tinytype this compatibility table} for the available default fonts\racross mobile browsers.\r\rA note on performance: Every time the contents of a Text object changes, i.e. changing the text being\rdisplayed, or the style of the text, it needs to remake the Text canvas, and if on WebGL, re-upload the\rnew texture to the GPU. This can be an expensive operation if used often, or with large quantities of\rText objects in your game. If you run into performance issues you would be better off using Bitmap Text\rinstead, as it benefits from batching and avoids expensive Canvas API calls.", + "Phaser.GameObjects.Text": "A Text Game Object.\n\nText objects work by creating their own internal hidden Canvas and then renders text to it using\nthe standard Canvas `fillText` API. It then creates a texture from this canvas which is rendered\nto your game during the render pass.\n\nBecause it uses the Canvas API you can take advantage of all the features this offers, such as\napplying gradient fills to the text, or strokes, shadows and more. You can also use custom fonts\nloaded externally, such as Google or TypeKit Web fonts.\n\n**Important:** The font name must be quoted if it contains certain combinations of digits or\nspecial characters, either when creating the Text object, or when setting the font via `setFont`\nor `setFontFamily`, e.g.:\n\n```javascript\nthis.add.text(0, 0, 'Hello World', { fontFamily: 'Georgia, \"Goudy Bookletter 1911\", Times, serif' });\n```\n\n```javascript\nthis.add.text(0, 0, 'Hello World', { font: '\"Press Start 2P\"' });\n```\n\nYou can only display fonts that are currently loaded and available to the browser: therefore fonts must\nbe pre-loaded. Phaser does not do this for you, so you will require the use of a 3rd party font loader,\nor have the fonts ready available in the CSS on the page in which your Phaser game resides.\n\nSee {@link http://www.jordanm.co.uk/tinytype this compatibility table} for the available default fonts\nacross mobile browsers.\n\nA note on performance: Every time the contents of a Text object changes, i.e. changing the text being\ndisplayed, or the style of the text, it needs to remake the Text canvas, and if on WebGL, re-upload the\nnew texture to the GPU. This can be an expensive operation if used often, or with large quantities of\nText objects in your game. If you run into performance issues you would be better off using Bitmap Text\ninstead, as it benefits from batching and avoids expensive Canvas API calls.", "Phaser.Types.GameObjects.Text.TextStyle.fixedWidth": "Force the Text object to have the exact width specified in this property. Leave as zero for it to change accordingly to content.", "Phaser.Types.GameObjects.Text.TextStyle.fixedHeight": "Force the Text object to have the exact height specified in this property. Leave as zero for it to change accordingly to content.", - "Phaser.GameObjects.TextStyle.setFixedSize": "Set a fixed width and height for the text.\r\rPass in `0` for either of these parameters to disable fixed width or height respectively.", - "Phaser.GameObjects.Text.setPadding": "Set the text padding.\r\r'left' can be an object.\r\rIf only 'left' and 'top' are given they are treated as 'x' and 'y'.", + "Phaser.GameObjects.TextStyle.setFixedSize": "Set a fixed width and height for the text.\n\nPass in `0` for either of these parameters to disable fixed width or height respectively.", + "Phaser.GameObjects.Text.setPadding": "Set the text padding.\n\n'left' can be an object.\n\nIf only 'left' and 'top' are given they are treated as 'x' and 'y'.", "Phaser.Types.GameObjects.Text.TextPadding.left": "The amount of padding added to the left of the Text object.", "Phaser.Types.GameObjects.Text.TextPadding.top": "The amount of padding added to the top of the Text object.", "Phaser.Types.GameObjects.Text.TextPadding.right": "The amount of padding added to the right of the Text object.", "Phaser.Types.GameObjects.Text.TextPadding.bottom": "The amount of padding added to the bottom of the Text object.", - "Phaser.GameObjects.Text.lineSpacing": "The line spacing value.\rThis value is added to the font height to calculate the overall line height.\rOnly has an effect if this Text object contains multiple lines of text.\r\rIf you update this property directly, instead of using the `setLineSpacing` method, then\rbe sure to call `updateText` after, or you won't see the change reflected in the Text object.", - "Phaser.GameObjects.Text.setAlign": "Set the alignment of the text in this Text object.\r\rThe argument can be one of: `left`, `right`, `center` or `justify`.\r\rAlignment only works if the Text object has more than one line of text.", - "Phaser.GameObjects.Text.setFontFamily": "Set the font family.\r\r**Important:** The font name must be quoted if it contains certain combinations of digits or\rspecial characters:\r\r```javascript\rText.setFont('\"Press Start 2P\"');\r```\r\rEqually, if you wish to provide a list of fallback fonts, then you should ensure they are all\rquoted properly, too:\r\r```javascript\rText.setFont('Georgia, \"Goudy Bookletter 1911\", Times, serif');\r```", - "Phaser.GameObjects.Text.setFontSize": "Set the font size.", + "Phaser.GameObjects.Text.lineSpacing": "The line spacing value.\nThis value is added to the font height to calculate the overall line height.\nOnly has an effect if this Text object contains multiple lines of text.\n\nIf you update this property directly, instead of using the `setLineSpacing` method, then\nbe sure to call `updateText` after, or you won't see the change reflected in the Text object.", + "Phaser.GameObjects.Text.setAlign": "Set the alignment of the text in this Text object.\n\nThe argument can be one of: `left`, `right`, `center` or `justify`.\n\nAlignment only works if the Text object has more than one line of text.", + "Phaser.GameObjects.Text.setFontFamily": "Set the font family.\n\n**Important:** The font name must be quoted if it contains certain combinations of digits or\nspecial characters:\n\n```javascript\nText.setFont('\"Press Start 2P\"');\n```\n\nEqually, if you wish to provide a list of fallback fonts, then you should ensure they are all\nquoted properly, too:\n\n```javascript\nText.setFont('Georgia, \"Goudy Bookletter 1911\", Times, serif');\n```", + "Phaser.GameObjects.Text.setFontSize": "Set the font size. Can be a string with a valid CSS unit, i.e. `16px`, or a number.", "Phaser.GameObjects.Text.setFontStyle": "Set the font style.", "Phaser.GameObjects.Text.setColor": "Set the text fill color.", "Phaser.GameObjects.Text.setStroke(color)": "The stroke color.", @@ -64,30 +69,30 @@ "Phaser.GameObjects.TextStyle.baselineX": "The amount of horizontal padding added to the width of the text when calculating the font metrics.", "Phaser.GameObjects.TextStyle.baselineY": "The amount of vertical padding added to the height of the text when calculating the font metrics.", "Phaser.GameObjects.Text.setMaxLines": "Set the maximum number of lines to draw.", - "Phaser.GameObjects.Text.setWordWrapWidth(useAdvancedWrap)": "Whether or not to use the advanced wrapping\ralgorithm. If true, spaces are collapsed and whitespace is trimmed from lines. If false,\rspaces and whitespace are left as is.", + "Phaser.GameObjects.Text.setWordWrapWidth(useAdvancedWrap)": "Whether or not to use the advanced wrapping\nalgorithm. If true, spaces are collapsed and whitespace is trimmed from lines. If false,\nspaces and whitespace are left as is.", "Phaser.GameObjects.Text.setWordWrapWidth(width)": "The maximum width of a line in pixels. Set to null to remove wrapping.", - "Phaser.GameObjects.BitmapText": "BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure.\r\rDuring rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to\rmatch the font structure.\r\rBitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability\rto use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by\rprocessing the font texture in an image editor, applying fills and any other effects required.\r\rTo create multi-line text insert \\r, \\n or \\r\\n escape codes into the text string.\r\rTo create a BitmapText data files you need a 3rd party app such as:\r\rBMFont (Windows, free): {@link http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/}\rGlyph Designer (OS X, commercial): {@link http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner}\rLittera (Web-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/}\r\rFor most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of\rconverting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: {@link http://codebeautify.org/xmltojson|http://codebeautify.org/xmltojson}", - "Phaser.GameObjects.BitmapText.setFont": "Changes the font this BitmapText is using to render.\r\rThe new texture is loaded and applied to the BitmapText. The existing test, size and alignment are preserved,\runless overridden via the arguments.", - "Phaser.GameObjects.BitmapText.align": "Controls the alignment of each line of text in this BitmapText object.\r\rOnly has any effect when this BitmapText contains multiple lines of text, split with carriage-returns.\rHas no effect with single-lines of text.\r\rSee the methods `setLeftAlign`, `setCenterAlign` and `setRightAlign`.\r\r0 = Left aligned (default)\r1 = Middle aligned\r2 = Right aligned\r\rThe alignment position is based on the longest line of text.", + "Phaser.GameObjects.BitmapText": "BitmapText objects work by taking a texture file and an XML or JSON file that describes the font structure.\n\nDuring rendering for each letter of the text is rendered to the display, proportionally spaced out and aligned to\nmatch the font structure.\n\nBitmapText objects are less flexible than Text objects, in that they have less features such as shadows, fills and the ability\nto use Web Fonts, however you trade this flexibility for rendering speed. You can also create visually compelling BitmapTexts by\nprocessing the font texture in an image editor, applying fills and any other effects required.\n\nTo create multi-line text insert \\r, \\n or \\r\\n escape codes into the text string.\n\nTo create a BitmapText data files you need a 3rd party app such as:\n\nBMFont (Windows, free): {@link http://www.angelcode.com/products/bmfont/|http://www.angelcode.com/products/bmfont/}\nGlyph Designer (OS X, commercial): {@link http://www.71squared.com/en/glyphdesigner|http://www.71squared.com/en/glyphdesigner}\nSnow BMF (Web-based, free): {@link https://snowb.org//|https://snowb.org/}\nLittera (Flash-based, free): {@link http://kvazars.com/littera/|http://kvazars.com/littera/}\n\nFor most use cases it is recommended to use XML. If you wish to use JSON, the formatting should be equal to the result of\nconverting a valid XML file through the popular X2JS library. An online tool for conversion can be found here: {@link http://codebeautify.org/xmltojson|http://codebeautify.org/xmltojson}", + "Phaser.GameObjects.BitmapText.setFont": "Changes the font this BitmapText is using to render.\n\nThe new texture is loaded and applied to the BitmapText. The existing test, size and alignment are preserved,\nunless overridden via the arguments.", + "Phaser.GameObjects.BitmapText.align": "Controls the alignment of each line of text in this BitmapText object.\n\nOnly has any effect when this BitmapText contains multiple lines of text, split with carriage-returns.\nHas no effect with single-lines of text.\n\nSee the methods `setLeftAlign`, `setCenterAlign` and `setRightAlign`.\n\n0 = Left aligned (default)\n1 = Middle aligned\n2 = Right aligned\n\nThe alignment position is based on the longest line of text.", "Phaser.GameObjects.BitmapText.setFontSize": "Set the font size of this Bitmap Text.", - "Phaser.GameObjects.BitmapText.setLetterSpacing": "Sets the letter spacing between each character of this Bitmap Text.\rCan be a positive value to increase the space, or negative to reduce it.\rSpacing is applied after the kerning values have been set.", - "Phaser.GameObjects.BitmapText.dropShadowX": "The horizontal offset of the drop shadow.\r\rYou can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.", - "Phaser.GameObjects.BitmapText.dropShadowY": "The vertical offset of the drop shadow.\r\rYou can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.", - "Phaser.GameObjects.BitmapText.dropShadowColor": "The color of the drop shadow.\r\rYou can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.", - "Phaser.GameObjects.BitmapText.dropShadowAlpha": "The alpha value of the drop shadow.\r\rYou can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.", - "Phaser.Tilemaps.Tilemap": "A Tilemap is a container for Tilemap data. This isn't a display object, rather, it holds data\rabout the map and allows you to add tilesets and tilemap layers to it. A map can have one or\rmore tilemap layers, which are the display objects that actually render the tiles.\r\rThe Tilemap data can be parsed from a Tiled JSON file, a CSV file or a 2D array. Tiled is a free\rsoftware package specifically for creating tile maps, and is available from:\rhttp://www.mapeditor.org\r\rAs of Phaser 3.50.0 the Tilemap API now supports the following types of map:\r\r1) Orthogonal\r2) Isometric\r3) Hexagonal\r4) Staggered\r\rPrior to this release, only orthogonal maps were supported.\r\rAnother large change in 3.50 was the consolidation of Tilemap Layers. Previously, you created\reither a Static or Dynamic Tilemap Layer. However, as of 3.50 the features of both have been\rmerged and the API simplified, so now there is just the single `TilemapLayer` class.\r\rA Tilemap has handy methods for getting and manipulating the tiles within a layer, allowing\ryou to build or modify the tilemap data at runtime.\r\rNote that all Tilemaps use a base tile size to calculate dimensions from, but that a\rTilemapLayer may have its own unique tile size that overrides this.\r\rAs of Phaser 3.21.0, if your tilemap includes layer groups (a feature of Tiled 1.2.0+) these\rwill be traversed and the following properties will impact children:\r\r- Opacity (blended with parent) and visibility (parent overrides child)\r- Vertical and horizontal offset\r\rThe grouping hierarchy is not preserved and all layers will be flattened into a single array.\r\rGroup layers are parsed during Tilemap construction but are discarded after parsing so dynamic\rlayers will NOT continue to be affected by a parent.\r\rTo avoid duplicate layer names, a layer that is a child of a group layer will have its parent\rgroup name prepended with a '/'. For example, consider a group called 'ParentGroup' with a\rchild called 'Layer 1'. In the Tilemap object, 'Layer 1' will have the name\r'ParentGroup/Layer 1'.", - "Phaser.Tilemaps.Tilemap.tileWidth": "The base width of a tile in pixels. Note that individual layers may have a different tile\rwidth.", - "Phaser.Tilemaps.Tilemap.tileHeight": "The base height of a tile in pixels. Note that individual layers may have a different\rtile height.", + "Phaser.GameObjects.BitmapText.setLetterSpacing": "Sets the letter spacing between each character of this Bitmap Text.\nCan be a positive value to increase the space, or negative to reduce it.\nSpacing is applied after the kerning values have been set.", + "Phaser.GameObjects.BitmapText.dropShadowX": "The horizontal offset of the drop shadow.\n\nYou can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.", + "Phaser.GameObjects.BitmapText.dropShadowY": "The vertical offset of the drop shadow.\n\nYou can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.", + "Phaser.GameObjects.BitmapText.dropShadowColor": "The color of the drop shadow.\n\nYou can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.", + "Phaser.GameObjects.BitmapText.dropShadowAlpha": "The alpha value of the drop shadow.\n\nYou can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.", + "Phaser.Tilemaps.Tilemap": "A Tilemap is a container for Tilemap data. This isn't a display object, rather, it holds data\nabout the map and allows you to add tilesets and tilemap layers to it. A map can have one or\nmore tilemap layers, which are the display objects that actually render the tiles.\n\nThe Tilemap data can be parsed from a Tiled JSON file, a CSV file or a 2D array. Tiled is a free\nsoftware package specifically for creating tile maps, and is available from:\nhttp://www.mapeditor.org\n\nAs of Phaser 3.50.0 the Tilemap API now supports the following types of map:\n\n1) Orthogonal\n2) Isometric\n3) Hexagonal\n4) Staggered\n\nPrior to this release, only orthogonal maps were supported.\n\nAnother large change in 3.50 was the consolidation of Tilemap Layers. Previously, you created\neither a Static or Dynamic Tilemap Layer. However, as of 3.50 the features of both have been\nmerged and the API simplified, so now there is just the single `TilemapLayer` class.\n\nA Tilemap has handy methods for getting and manipulating the tiles within a layer, allowing\nyou to build or modify the tilemap data at runtime.\n\nNote that all Tilemaps use a base tile size to calculate dimensions from, but that a\nTilemapLayer may have its own unique tile size that overrides this.\n\nAs of Phaser 3.21.0, if your tilemap includes layer groups (a feature of Tiled 1.2.0+) these\nwill be traversed and the following properties will impact children:\n\n- Opacity (blended with parent) and visibility (parent overrides child)\n- Vertical and horizontal offset\n\nThe grouping hierarchy is not preserved and all layers will be flattened into a single array.\n\nGroup layers are parsed during Tilemap construction but are discarded after parsing so dynamic\nlayers will NOT continue to be affected by a parent.\n\nTo avoid duplicate layer names, a layer that is a child of a group layer will have its parent\ngroup name prepended with a '/'. For example, consider a group called 'ParentGroup' with a\nchild called 'Layer 1'. In the Tilemap object, 'Layer 1' will have the name\n'ParentGroup/Layer 1'.", + "Phaser.Tilemaps.Tilemap.tileWidth": "The base width of a tile in pixels. Note that individual layers may have a different tile\nwidth.", + "Phaser.Tilemaps.Tilemap.tileHeight": "The base height of a tile in pixels. Note that individual layers may have a different\ntile height.", "Phaser.GameObjects.GameObjectFactory.tilemap(key)": "The key in the Phaser cache that corresponds to the loaded tilemap data.", - "Phaser.Tilemaps.Tileset": "A Tileset is a combination of an image containing the tiles and a container for data about\reach tile.", + "Phaser.Tilemaps.Tileset": "A Tileset is a combination of an image containing the tiles and a container for data about\neach tile.", "Phaser.Tilemaps.Tileset.name": "The name of the Tileset.", "Phaser.Tilemaps.Tileset.image": "The cached image that contains the individual tiles. Use setImage to set.", "Phaser.Tilemaps.Tileset.tileWidth": "The width of each tile (in pixels). Use setTileSize to change.", "Phaser.Tilemaps.Tileset.tileHeight": "The height of each tile (in pixels). Use setTileSize to change.", "Phaser.Tilemaps.Tileset.tileMargin": "The margin around the tiles in the sheet (in pixels). Use `setSpacing` to change.", "Phaser.Tilemaps.Tileset.tileSpacing": "The spacing between each the tile in the sheet (in pixels). Use `setSpacing` to change.", - "Phaser.Tilemaps.TilemapLayer": "A Tilemap Layer is a Game Object that renders LayerData from a Tilemap when used in combination\rwith one, or more, Tilesets.", - "Phaser.Tilemaps.LayerData": "A class for representing data about about a layer in a map. Maps are parsed from CSV, Tiled,\retc. into this format. Tilemap and TilemapLayer objects have a reference\rto this data and use it to look up and perform operations on tiles.", + "Phaser.Tilemaps.TilemapLayer": "A Tilemap Layer is a Game Object that renders LayerData from a Tilemap when used in combination\nwith one, or more, Tilesets.", + "Phaser.Tilemaps.LayerData": "A class for representing data about about a layer in a map. Maps are parsed from CSV, Tiled,\netc. into this format. Tilemap and TilemapLayer objects have a reference\nto this data and use it to look up and perform operations on tiles.", "Phaser.Tilemaps.LayerData.name": "The name of the layer, if specified in Tiled.", "Phaser.Tilemaps.LayerData.width": "The width of the layer in tiles.", "Phaser.Tilemaps.LayerData.height": "The height of the layer in tiles.", @@ -95,55 +100,55 @@ "Phaser.Tilemaps.LayerData.tileHeight": "The pixel height of the tiles.", "Phaser.Tilemaps.LayerData.widthInPixels": "The width in pixels of the entire layer.", "Phaser.Tilemaps.LayerData.heightInPixels": "The height in pixels of the entire layer.", - "Phaser.GameObjects.Shape": "The Shape Game Object is a base class for the various different shapes, such as the Arc, Star or Polygon.\rYou cannot add a Shape directly to your Scene, it is meant as a base for your own custom Shape classes.", - "Phaser.GameObjects.Shape.isFilled": "Controls if this Shape is filled or not.\rNote that some Shapes do not support being filled (such as Line shapes)", + "Phaser.GameObjects.Shape": "The Shape Game Object is a base class for the various different shapes, such as the Arc, Star or Polygon.\nYou cannot add a Shape directly to your Scene, it is meant as a base for your own custom Shape classes.", + "Phaser.GameObjects.Shape.isFilled": "Controls if this Shape is filled or not.\nNote that some Shapes do not support being filled (such as Line shapes)", "Phaser.GameObjects.Shape.fillColor": "The fill color used by this Shape.", "Phaser.GameObjects.Shape.fillAlpha": "The fill alpha value used by this Shape.", - "Phaser.GameObjects.Shape.isStroked": "Controls if this Shape is stroked or not.\rNote that some Shapes do not support being stroked (such as Iso Box shapes)", + "Phaser.GameObjects.Shape.isStroked": "Controls if this Shape is stroked or not.\nNote that some Shapes do not support being stroked (such as Iso Box shapes)", "Phaser.GameObjects.Shape.strokeColor": "The stroke color used by this Shape.", "Phaser.GameObjects.Shape.strokeAlpha": "The stroke alpha value used by this Shape.", "Phaser.GameObjects.Shape.lineWidth": "The stroke line width used by this Shape.", - "Phaser.GameObjects.Rectangle": "The Rectangle Shape is a Game Object that can be added to a Scene, Group or Container. You can\rtreat it like any other Game Object in your game, such as tweening it, scaling it, or enabling\rit for input or physics. It provides a quick and easy way for you to render this shape in your\rgame without using a texture, while still taking advantage of being fully batched in WebGL.\r\rThis shape supports both fill and stroke colors.\r\rYou can change the size of the rectangle by changing the `width` and `height` properties.", - "Phaser.GameObjects.Ellipse": "The Ellipse Shape is a Game Object that can be added to a Scene, Group or Container. You can\rtreat it like any other Game Object in your game, such as tweening it, scaling it, or enabling\rit for input or physics. It provides a quick and easy way for you to render this shape in your\rgame without using a texture, while still taking advantage of being fully batched in WebGL.\r\rThis shape supports both fill and stroke colors.\r\rWhen it renders it displays an ellipse shape. You can control the width and height of the ellipse.\rIf the width and height match it will render as a circle. If the width is less than the height,\rit will look more like an egg shape.\r\rThe Ellipse shape also has a `smoothness` property and corresponding `setSmoothness` method.\rThis allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations\rthat take place during construction. Increase and decrease the default value for smoother, or more\rjagged, shapes.", - "Phaser.GameObjects.Ellipse.smoothness": "The smoothness of the ellipse. The number of points used when rendering it.\rIncrease this value for a smoother ellipse, at the cost of more polygons being rendered.", - "Phaser.GameObjects.Triangle": "The Triangle Shape is a Game Object that can be added to a Scene, Group or Container. You can\rtreat it like any other Game Object in your game, such as tweening it, scaling it, or enabling\rit for input or physics. It provides a quick and easy way for you to render this shape in your\rgame without using a texture, while still taking advantage of being fully batched in WebGL.\r\rThis shape supports both fill and stroke colors.\r\rThe Triangle consists of 3 lines, joining up to form a triangular shape. You can control the\rposition of each point of these lines. The triangle is always closed and cannot have an open\rface. If you require that, consider using a Polygon instead.", + "Phaser.GameObjects.Rectangle": "The Rectangle Shape is a Game Object that can be added to a Scene, Group or Container. You can\ntreat it like any other Game Object in your game, such as tweening it, scaling it, or enabling\nit for input or physics. It provides a quick and easy way for you to render this shape in your\ngame without using a texture, while still taking advantage of being fully batched in WebGL.\n\nThis shape supports both fill and stroke colors.\n\nYou can change the size of the rectangle by changing the `width` and `height` properties.", + "Phaser.GameObjects.Ellipse": "The Ellipse Shape is a Game Object that can be added to a Scene, Group or Container. You can\ntreat it like any other Game Object in your game, such as tweening it, scaling it, or enabling\nit for input or physics. It provides a quick and easy way for you to render this shape in your\ngame without using a texture, while still taking advantage of being fully batched in WebGL.\n\nThis shape supports both fill and stroke colors.\n\nWhen it renders it displays an ellipse shape. You can control the width and height of the ellipse.\nIf the width and height match it will render as a circle. If the width is less than the height,\nit will look more like an egg shape.\n\nThe Ellipse shape also has a `smoothness` property and corresponding `setSmoothness` method.\nThis allows you to control how smooth the shape renders in WebGL, by controlling the number of iterations\nthat take place during construction. Increase and decrease the default value for smoother, or more\njagged, shapes.", + "Phaser.GameObjects.Ellipse.smoothness": "The smoothness of the ellipse. The number of points used when rendering it.\nIncrease this value for a smoother ellipse, at the cost of more polygons being rendered.", + "Phaser.GameObjects.Triangle": "The Triangle Shape is a Game Object that can be added to a Scene, Group or Container. You can\ntreat it like any other Game Object in your game, such as tweening it, scaling it, or enabling\nit for input or physics. It provides a quick and easy way for you to render this shape in your\ngame without using a texture, while still taking advantage of being fully batched in WebGL.\n\nThis shape supports both fill and stroke colors.\n\nThe Triangle consists of 3 lines, joining up to form a triangular shape. You can control the\nposition of each point of these lines. The triangle is always closed and cannot have an open\nface. If you require that, consider using a Polygon instead.", "Phaser.Geom.Triangle.x1": "`x` coordinate of the first point.", "Phaser.Geom.Triangle.y1": "`y` coordinate of the first point.", "Phaser.Geom.Triangle.x2": "`x` coordinate of the second point.", "Phaser.Geom.Triangle.y2": "`y` coordinate of the second point.", "Phaser.Geom.Triangle.x3": "`x` coordinate of the third point.", "Phaser.Geom.Triangle.y3": "`y` coordinate of the third point.", - "Phaser.GameObjects.Polygon": "The Polygon Shape is a Game Object that can be added to a Scene, Group or Container. You can\rtreat it like any other Game Object in your game, such as tweening it, scaling it, or enabling\rit for input or physics. It provides a quick and easy way for you to render this shape in your\rgame without using a texture, while still taking advantage of being fully batched in WebGL.\r\rThis shape supports both fill and stroke colors.\r\rThe Polygon Shape is created by providing a list of points, which are then used to create an\rinternal Polygon geometry object. The points can be set from a variety of formats:\r\r- A string containing paired values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'`\r- An array of Point or Vector2 objects: `[new Phaser.Math.Vector2(x1, y1), ...]`\r- An array of objects with public x/y properties: `[obj1, obj2, ...]`\r- An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]`\r- An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]`\r\rBy default the `x` and `y` coordinates of this Shape refer to the center of it. However, depending\ron the coordinates of the points provided, the final shape may be rendered offset from its origin.", - "Phaser.GameObjects.Layer": "A Layer Game Object.\r\rA Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object\rto a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game\rObjects:\r\r```javascript\rconst spaceman = this.add.sprite(150, 300, 'spaceman');\rconst bunny = this.add.sprite(400, 300, 'bunny');\rconst elephant = this.add.sprite(650, 300, 'elephant');\r\rconst layer = this.add.layer();\r\rlayer.add([ spaceman, bunny, elephant ]);\r```\r\rThe 3 sprites in the example above will now be managed by the Layer they were added to. Therefore,\rif you then set `layer.setVisible(false)` they would all vanish from the display.\r\rYou can also control the depth of the Game Objects within the Layer. For example, calling the\r`setDepth` method of a child of a Layer will allow you to adjust the depth of that child _within the\rLayer itself_, rather than the whole Scene. The Layer, too, can have its depth set as well.\r\rThe Layer class also offers many different methods for manipulating the list, such as the\rmethods `moveUp`, `moveDown`, `sendToBack`, `bringToTop` and so on. These allow you to change the\rdisplay list position of the Layers children, causing it to adjust the order in which they are\rrendered. Using `setDepth` on a child allows you to override this.\r\rLayers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across\ra whole range of children, which, depending on the effect, can often be far more efficient that doing so\ron a per-child basis.\r\rLayers have no position or size within the Scene. This means you cannot enable a Layer for\rphysics or input, or change the position, rotation or scale of a Layer. They also have no scroll\rfactor, texture, tint, origin, crop or bounds.\r\rIf you need those kind of features then you should use a Container instead. Containers can be added\rto Layers, but Layers cannot be added to Containers.\r\rHowever, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings\rwill impact all children being rendered by the Layer.", - "Phaser.Physics.Arcade.Collider": "An Arcade Physics Collider will automatically check for collision, or overlaps, between two objects\revery step. If a collision, or overlap, occurs it will invoke the given callbacks.", - "Phaser.Physics.Arcade.Image": "An Arcade Physics Image is an Image with an Arcade Physics body and related components.\rThe body can be dynamic or static.\r\rThe main difference between an Arcade Image and an Arcade Sprite is that you cannot animate an Arcade Image.", - "Phaser.Physics.Arcade.Sprite": "An Arcade Physics Sprite is a Sprite with an Arcade Physics body and related components.\rThe body can be dynamic or static.\r\rThe main difference between an Arcade Sprite and an Arcade Image is that you cannot animate an Arcade Image.\rIf you do not require animation then you can safely use Arcade Images instead of Arcade Sprites.", - "Phaser.Physics.Arcade.Body": "A Dynamic Arcade Body.\r\rIts static counterpart is {@link Phaser.Physics.Arcade.StaticBody}.", + "Phaser.GameObjects.Polygon": "The Polygon Shape is a Game Object that can be added to a Scene, Group or Container. You can\ntreat it like any other Game Object in your game, such as tweening it, scaling it, or enabling\nit for input or physics. It provides a quick and easy way for you to render this shape in your\ngame without using a texture, while still taking advantage of being fully batched in WebGL.\n\nThis shape supports both fill and stroke colors.\n\nThe Polygon Shape is created by providing a list of points, which are then used to create an\ninternal Polygon geometry object. The points can be set from a variety of formats:\n\n- A string containing paired values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'`\n- An array of Point or Vector2 objects: `[new Phaser.Math.Vector2(x1, y1), ...]`\n- An array of objects with public x/y properties: `[obj1, obj2, ...]`\n- An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]`\n- An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]`\n\nBy default the `x` and `y` coordinates of this Shape refer to the center of it. However, depending\non the coordinates of the points provided, the final shape may be rendered offset from its origin.", + "Phaser.GameObjects.Layer": "A Layer Game Object.\n\nA Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object\nto a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game\nObjects:\n\n```javascript\nconst spaceman = this.add.sprite(150, 300, 'spaceman');\nconst bunny = this.add.sprite(400, 300, 'bunny');\nconst elephant = this.add.sprite(650, 300, 'elephant');\n\nconst layer = this.add.layer();\n\nlayer.add([ spaceman, bunny, elephant ]);\n```\n\nThe 3 sprites in the example above will now be managed by the Layer they were added to. Therefore,\nif you then set `layer.setVisible(false)` they would all vanish from the display.\n\nYou can also control the depth of the Game Objects within the Layer. For example, calling the\n`setDepth` method of a child of a Layer will allow you to adjust the depth of that child _within the\nLayer itself_, rather than the whole Scene. The Layer, too, can have its depth set as well.\n\nThe Layer class also offers many different methods for manipulating the list, such as the\nmethods `moveUp`, `moveDown`, `sendToBack`, `bringToTop` and so on. These allow you to change the\ndisplay list position of the Layers children, causing it to adjust the order in which they are\nrendered. Using `setDepth` on a child allows you to override this.\n\nLayers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across\na whole range of children, which, depending on the effect, can often be far more efficient that doing so\non a per-child basis.\n\nLayers have no position or size within the Scene. This means you cannot enable a Layer for\nphysics or input, or change the position, rotation or scale of a Layer. They also have no scroll\nfactor, texture, tint, origin, crop or bounds.\n\nIf you need those kind of features then you should use a Container instead. Containers can be added\nto Layers, but Layers cannot be added to Containers.\n\nHowever, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings\nwill impact all children being rendered by the Layer.", + "Phaser.Physics.Arcade.Collider": "An Arcade Physics Collider will automatically check for collision, or overlaps, between two objects\nevery step. If a collision, or overlap, occurs it will invoke the given callbacks.", + "Phaser.Physics.Arcade.Image": "An Arcade Physics Image is an Image with an Arcade Physics body and related components.\nThe body can be dynamic or static.\n\nThe main difference between an Arcade Image and an Arcade Sprite is that you cannot animate an Arcade Image.", + "Phaser.Physics.Arcade.Sprite": "An Arcade Physics Sprite is a Sprite with an Arcade Physics body and related components.\nThe body can be dynamic or static.\n\nThe main difference between an Arcade Sprite and an Arcade Image is that you cannot animate an Arcade Image.\nIf you do not require animation then you can safely use Arcade Images instead of Arcade Sprites.", + "Phaser.Physics.Arcade.Body": "A Dynamic Arcade Body.\n\nIts static counterpart is {@link Phaser.Physics.Arcade.StaticBody}.", "Phaser.Physics.Arcade.Body.enable": "Whether this Body is updated by the physics simulation.", "Phaser.Physics.Arcade.Body.offset": "The offset of this Body's position from its Game Object's position, in source pixels.", - "Phaser.Physics.Arcade.Body.radius": "If this Body is circular, this is the unscaled radius of the Body, as set by setCircle(), in source pixels.\rThe true radius is equal to `halfWidth`.", + "Phaser.Physics.Arcade.Body.radius": "If this Body is circular, this is the unscaled radius of the Body, as set by setCircle(), in source pixels.\nThe true radius is equal to `halfWidth`.", "Phaser.Physics.Arcade.Body.moves": "Whether the Body's position and rotation are affected by its velocity, acceleration, drag, and gravity.", "Phaser.Physics.Arcade.Body.velocity": "The Body's velocity, in pixels per second.", - "Phaser.Physics.Arcade.Body.maxVelocity": "The Body's absolute maximum velocity, in pixels per second.\rThe horizontal and vertical components are applied separately.", - "Phaser.Physics.Arcade.Body.maxSpeed": "The maximum speed this Body is allowed to reach, in pixels per second.\r\rIf not negative it limits the scalar value of speed.\r\rAny negative value means no maximum is being applied (the default).", + "Phaser.Physics.Arcade.Body.maxVelocity": "The Body's absolute maximum velocity, in pixels per second.\nThe horizontal and vertical components are applied separately.", + "Phaser.Physics.Arcade.Body.maxSpeed": "The maximum speed this Body is allowed to reach, in pixels per second.\n\nIf not negative it limits the scalar value of speed.\n\nAny negative value means no maximum is being applied (the default).", "Phaser.Physics.Arcade.Body.allowGravity": "Whether this Body's position is affected by gravity (local or world).", - "Phaser.Physics.Arcade.Body.gravity": "Acceleration due to gravity (specific to this Body), in pixels per second squared.\rTotal gravity is the sum of this vector and the simulation's `gravity`.", + "Phaser.Physics.Arcade.Body.gravity": "Acceleration due to gravity (specific to this Body), in pixels per second squared.\nTotal gravity is the sum of this vector and the simulation's `gravity`.", "Phaser.Physics.Arcade.Body.acceleration": "The Body's change in velocity, in pixels per second squared.", - "Phaser.Physics.Arcade.Body.useDamping": "If this Body is using `drag` for deceleration this property controls how the drag is applied.\rIf set to `true` drag will use a damping effect rather than a linear approach. If you are\rcreating a game where the Body moves freely at any angle (i.e. like the way the ship moves in\rthe game Asteroids) then you will get a far smoother and more visually correct deceleration\rby using damping, avoiding the axis-drift that is prone with linear deceleration.\r\rIf you enable this property then you should use far smaller `drag` values than with linear, as\rthey are used as a multiplier on the velocity. Values such as 0.05 will give a nice slow\rdeceleration.", + "Phaser.Physics.Arcade.Body.useDamping": "If this Body is using `drag` for deceleration this property controls how the drag is applied.\nIf set to `true` drag will use a damping effect rather than a linear approach. If you are\ncreating a game where the Body moves freely at any angle (i.e. like the way the ship moves in\nthe game Asteroids) then you will get a far smoother and more visually correct deceleration\nby using damping, avoiding the axis-drift that is prone with linear deceleration.\n\nIf you enable this property then you should use far smaller `drag` values than with linear, as\nthey are used as a multiplier on the velocity. Values such as 0.05 will give a nice slow\ndeceleration.", "Phaser.Physics.Arcade.Body.allowDrag": "Whether this Body's velocity is affected by its `drag`.", - "Phaser.Physics.Arcade.Body.drag": "When `useDamping` is false (the default), this is absolute loss of velocity due to movement, in pixels per second squared.\r\rWhen `useDamping` is true, this is a damping multiplier between 0 and 1.\rA value of 0 means the Body stops instantly.\rA value of 0.01 mean the Body keeps 1% of its velocity per second, losing 99%.\rA value of 0.1 means the Body keeps 10% of its velocity per second, losing 90%.\rA value of 1 means the Body loses no velocity.\rYou can use very small values (e.g., 0.001) to stop the Body quickly.\r\rThe x and y components are applied separately.\r\rDrag is applied only when `acceleration` is zero.", + "Phaser.Physics.Arcade.Body.drag": "When `useDamping` is false (the default), this is absolute loss of velocity due to movement, in pixels per second squared.\n\nWhen `useDamping` is true, this is a damping multiplier between 0 and 1.\nA value of 0 means the Body stops instantly.\nA value of 0.01 mean the Body keeps 1% of its velocity per second, losing 99%.\nA value of 0.1 means the Body keeps 10% of its velocity per second, losing 90%.\nA value of 1 means the Body loses no velocity.\nYou can use very small values (e.g., 0.001) to stop the Body quickly.\n\nThe x and y components are applied separately.\n\nDrag is applied only when `acceleration` is zero.", "Phaser.Physics.Arcade.Body.allowRotation": "Whether this Body's `rotation` is affected by its angular acceleration and angular velocity.", - "Phaser.Physics.Arcade.Body.rotation": "This body's rotation, in degrees, based on its angular acceleration and angular velocity.\rThe Body's rotation controls the `angle` of its Game Object.\rIt doesn't rotate the Body's own geometry, which is always an axis-aligned rectangle or a circle.", + "Phaser.Physics.Arcade.Body.rotation": "This body's rotation, in degrees, based on its angular acceleration and angular velocity.\nThe Body's rotation controls the `angle` of its Game Object.\nIt doesn't rotate the Body's own geometry, which is always an axis-aligned rectangle or a circle.", "Phaser.Physics.Arcade.Body.angularVelocity": "The rate of change of this Body's `rotation`, in degrees per second.", "Phaser.Physics.Arcade.Body.angularAcceleration": "The Body's angular acceleration (change in angular velocity), in degrees per second squared.", - "Phaser.Physics.Arcade.Body.angularDrag": "Loss of angular velocity due to angular movement, in degrees per second.\r\rAngular drag is applied only when angular acceleration is zero.", + "Phaser.Physics.Arcade.Body.angularDrag": "Loss of angular velocity due to angular movement, in degrees per second.\n\nAngular drag is applied only when angular acceleration is zero.", "Phaser.Physics.Arcade.Body.maxAngular": "The Body's maximum angular velocity, in degrees per second.", - "Phaser.Physics.Arcade.Body.pushable": "Sets if this Body can be pushed by another Body.\r\rA body that cannot be pushed will reflect back all of the velocity it is given to the\rcolliding body. If that body is also not pushable, then the separation will be split\rbetween them evenly.\r\rIf you want your body to never move or seperate at all, see the `setImmovable` method.\r\rBy default, Dynamic Bodies are always pushable.", + "Phaser.Physics.Arcade.Body.pushable": "Sets if this Body can be pushed by another Body.\n\nA body that cannot be pushed will reflect back all of the velocity it is given to the\ncolliding body. If that body is also not pushable, then the separation will be split\nbetween them evenly.\n\nIf you want your body to never move or seperate at all, see the `setImmovable` method.\n\nBy default, Dynamic Bodies are always pushable.", "Phaser.Physics.Arcade.Body.immovable": "Whether this Body can be moved by collisions with another Body.", "Phaser.Physics.Arcade.Body.collideWorldBounds": "Whether this Body interacts with the world boundary.", - "Phaser.Physics.Arcade.Body.mass": "The Body's inertia, relative to a default unit (1).\rWith `bounce`, this affects the exchange of momentum (velocities) during collisions.", + "Phaser.Physics.Arcade.Body.mass": "The Body's inertia, relative to a default unit (1).\nWith `bounce`, this affects the exchange of momentum (velocities) during collisions.", "Phaser.Physics.Arcade.Body.bounce": "Rebound following a collision, relative to 1.", - "Phaser.Physics.Arcade.Body.friction": "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.\rThe horizontal component (x) is applied only when two colliding Bodies are separated vertically.\rThe vertical component (y) is applied only when two colliding Bodies are separated horizontally.\rThe default value (1, 0) moves the riding Body horizontally in equal proportion to this Body and vertically not at all.", + "Phaser.Physics.Arcade.Body.friction": "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.\nThe horizontal component (x) is applied only when two colliding Bodies are separated vertically.\nThe vertical component (y) is applied only when two colliding Bodies are separated horizontally.\nThe default value (1, 0) moves the riding Body horizontally in equal proportion to this Body and vertically not at all.", "Phaser.Physics.Arcade.Body.overlapX": "The amount of horizontal overlap (before separation), if this Body is colliding with another.", "Phaser.Physics.Arcade.Body.overlapY": "The amount of vertical overlap (before separation), if this Body is colliding with another.", "Phaser.Physics.Arcade.Body.overlapR": "The amount of overlap (before separation), if this Body is circular and colliding with another circular body.", @@ -153,5 +158,5 @@ "Phaser.Physics.Arcade.Collider(collideCallback)": "The callback to invoke when the two objects collide.", "Phaser.Physics.Arcade.Collider(processCallback)": "The callback to invoke when the two objects collide. Must return a boolean.", "Phaser.Physics.Arcade.Collider(callbackContext)": "The scope in which to call the callbacks.", - "Phaser.Input.Keyboard.Key": "A generic Key object which can be passed to the Process functions (and so on)\rkeycode must be an integer" + "Phaser.Input.Keyboard.Key": "A generic Key object which can be passed to the Process functions (and so on)\nkeycode must be an integer" } \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/icons/dark/3slice.png b/source/editor/plugins/phasereditor2d.scene/icons/dark/3slice.png new file mode 100644 index 000000000..29eb8687a Binary files /dev/null and b/source/editor/plugins/phasereditor2d.scene/icons/dark/3slice.png differ diff --git a/source/editor/plugins/phasereditor2d.scene/icons/dark/3slice@2x.png b/source/editor/plugins/phasereditor2d.scene/icons/dark/3slice@2x.png new file mode 100644 index 000000000..d60f64cb2 Binary files /dev/null and b/source/editor/plugins/phasereditor2d.scene/icons/dark/3slice@2x.png differ diff --git a/source/editor/plugins/phasereditor2d.scene/icons/dark/9slice.png b/source/editor/plugins/phasereditor2d.scene/icons/dark/9slice.png new file mode 100644 index 000000000..91be9336d Binary files /dev/null and b/source/editor/plugins/phasereditor2d.scene/icons/dark/9slice.png differ diff --git a/source/editor/plugins/phasereditor2d.scene/icons/dark/9slice@2x.png b/source/editor/plugins/phasereditor2d.scene/icons/dark/9slice@2x.png new file mode 100644 index 000000000..7a314516e Binary files /dev/null and b/source/editor/plugins/phasereditor2d.scene/icons/dark/9slice@2x.png differ diff --git a/source/editor/plugins/phasereditor2d.scene/icons/light/3slice.png b/source/editor/plugins/phasereditor2d.scene/icons/light/3slice.png new file mode 100644 index 000000000..b7d2c2f06 Binary files /dev/null and b/source/editor/plugins/phasereditor2d.scene/icons/light/3slice.png differ diff --git a/source/editor/plugins/phasereditor2d.scene/icons/light/3slice@2x.png b/source/editor/plugins/phasereditor2d.scene/icons/light/3slice@2x.png new file mode 100644 index 000000000..c7df8adf1 Binary files /dev/null and b/source/editor/plugins/phasereditor2d.scene/icons/light/3slice@2x.png differ diff --git a/source/editor/plugins/phasereditor2d.scene/icons/light/9slice.png b/source/editor/plugins/phasereditor2d.scene/icons/light/9slice.png new file mode 100644 index 000000000..5dd748809 Binary files /dev/null and b/source/editor/plugins/phasereditor2d.scene/icons/light/9slice.png differ diff --git a/source/editor/plugins/phasereditor2d.scene/icons/light/9slice@2x.png b/source/editor/plugins/phasereditor2d.scene/icons/light/9slice@2x.png new file mode 100644 index 000000000..896514625 Binary files /dev/null and b/source/editor/plugins/phasereditor2d.scene/icons/light/9slice@2x.png differ diff --git a/source/editor/plugins/phasereditor2d.scene/src/ScenePlugin.ts b/source/editor/plugins/phasereditor2d.scene/src/ScenePlugin.ts index 84cf9a0cb..bb55933dd 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ScenePlugin.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ScenePlugin.ts @@ -47,6 +47,8 @@ namespace phasereditor2d.scene { export const ICON_ORIGIN_BOTTOM_RIGHT = "origin-bottomright"; export const ICON_ARCADE_COLLIDER = "collider"; export const ICON_KEYBOARD_KEY = "keyboard-key"; + export const ICON_9_SLICE = "9slice"; + export const ICON_3_SLICE = "3slice"; export const SCENE_OBJECT_IMAGE_CATEGORY = "Texture"; export const SCENE_OBJECT_TEXT_CATEGORY = "String"; @@ -55,6 +57,7 @@ namespace phasereditor2d.scene { export const SCENE_OBJECT_TILEMAP_CATEGORY = "Tile Map"; export const SCENE_OBJECT_ARCADE_CATEGORY = "Arcade"; export const SCENE_OBJECT_INPUT_CATEGORY = "Input"; + export const SCENE_OBJECT_SCRIPT_CATEGORY = "Script"; export const SCENE_OBJECT_CATEGORIES = [ SCENE_OBJECT_IMAGE_CATEGORY, @@ -63,7 +66,8 @@ namespace phasereditor2d.scene { SCENE_OBJECT_ARCADE_CATEGORY, SCENE_OBJECT_SHAPE_CATEGORY, SCENE_OBJECT_TILEMAP_CATEGORY, - SCENE_OBJECT_INPUT_CATEGORY + SCENE_OBJECT_INPUT_CATEGORY, + SCENE_OBJECT_SCRIPT_CATEGORY ]; export const SCENE_OBJECT_CATEGORY_SET = new Set(SCENE_OBJECT_CATEGORIES); @@ -76,6 +80,10 @@ namespace phasereditor2d.scene { static DEFAULT_EDITOR_CANVAS_CONTEXT = Phaser.WEBGL; + static DEFAULT_PIXEL_ART = true; + + static DEFAULT_EDITOR_PIXEL_ART = true; + private _sceneFinder: core.json.SceneFinder; private _docs: phasereditor2d.ide.core.PhaserDocs; @@ -97,6 +105,12 @@ namespace phasereditor2d.scene { console.log("ScenePlugin: default render type: " + (type === "canvas" ? "Phaser.CANVAS" : "Phaser.WEBGL")); this.setDefaultRenderType(type as any); + + const pixelArt = window.localStorage.getItem("phasereditor2d.scene.PIXEL_ART") !== "0"; + + this.setDefaultRenderPixelArt(pixelArt); + + console.log("ScenePlugin: default pixelArt: " + pixelArt); } setDefaultRenderType(type?: "canvas" | "webgl") { @@ -107,6 +121,14 @@ namespace phasereditor2d.scene { ScenePlugin.DEFAULT_EDITOR_CANVAS_CONTEXT = ScenePlugin.DEFAULT_CANVAS_CONTEXT; } + setDefaultRenderPixelArt(pixelArt: boolean) { + + window.localStorage.setItem("phasereditor2d.scene.PIXEL_ART", pixelArt ? "1" : "0"); + + ScenePlugin.DEFAULT_PIXEL_ART = pixelArt; + ScenePlugin.DEFAULT_EDITOR_PIXEL_ART = pixelArt; + } + getPhaserDocs() { return this._docs; } @@ -135,6 +157,16 @@ namespace phasereditor2d.scene { await ui.editor.usercomponent.UserComponentCodeResources.getInstance().preload(); })); + // preload ScriptNode files + + reg.addExtension(new ide.PluginResourceLoaderExtension(async () => { + + await ui.sceneobjects.ScriptNodeCodeResources.getInstance().preload(); + })); + + ui.sceneobjects.ScriptNodeCodeResources.getInstance().registerCommands( + "phasereditor.scene.ScriptNodeCategory", "ScriptNode", reg); + // preload project reg.addExtension(this._sceneFinder.getProjectPreloader()); @@ -211,7 +243,9 @@ namespace phasereditor2d.scene { ICON_ORIGIN_BOTTOM_CENTER, ICON_ORIGIN_BOTTOM_RIGHT, ICON_ARCADE_COLLIDER, - ICON_KEYBOARD_KEY + ICON_KEYBOARD_KEY, + ICON_9_SLICE, + ICON_3_SLICE ]) ); @@ -288,6 +322,8 @@ namespace phasereditor2d.scene { ui.sceneobjects.ImageExtension.getInstance(), ui.sceneobjects.SpriteExtension.getInstance(), ui.sceneobjects.TileSpriteExtension.getInstance(), + ui.sceneobjects.NineSliceExtension.getInstance(), + ui.sceneobjects.ThreeSliceExtension.getInstance(), ui.sceneobjects.TextExtension.getInstance(), ui.sceneobjects.BitmapTextExtension.getInstance(), ui.sceneobjects.ContainerExtension.getInstance(), @@ -300,7 +336,8 @@ namespace phasereditor2d.scene { ui.sceneobjects.ArcadeImageExtension.getInstance(), ui.sceneobjects.ArcadeSpriteExtension.getInstance(), ui.sceneobjects.ColliderExtension.getInstance(), - ui.sceneobjects.KeyboardKeyExtension.getInstance() + ui.sceneobjects.KeyboardKeyExtension.getInstance(), + ui.sceneobjects.ScriptNodeExtension.getInstance() ); // scene plain object extensions @@ -317,12 +354,13 @@ namespace phasereditor2d.scene { reg.addExtension(new ui.editor.properties.SceneEditorPropertySectionExtension( page => new ui.sceneobjects.GameObjectVariableSection(page), + page => new ui.sceneobjects.PrefabObjectVariableSection(page), + page => new ui.sceneobjects.NestedPrefabObjectVariableSection(page), page => new ui.sceneobjects.PrefabInstanceSection(page), page => new ui.sceneobjects.ObjectUserComponentsSection(page), page => new ui.sceneobjects.ObjectSingleUserComponentSection(page), page => new ui.sceneobjects.ListVariableSection(page), page => new ui.sceneobjects.GameObjectListSection(page), - page => new ui.sceneobjects.ParentSection(page), page => new ui.sceneobjects.ChildrenSection(page), page => new ui.sceneobjects.TransformSection(page), page => new ui.sceneobjects.OriginSection(page), @@ -331,8 +369,11 @@ namespace phasereditor2d.scene { page => new ui.sceneobjects.AlphaSection(page), page => new ui.sceneobjects.AlphaSingleSection(page), page => new ui.sceneobjects.TintSection(page), + page => new ui.sceneobjects.TintSingleSection(page), page => new ui.sceneobjects.SizeSection(page), page => new ui.sceneobjects.TileSpriteSection(page), + page => new ui.sceneobjects.NineSliceSection(page), + page => new ui.sceneobjects.ThreeSliceSection(page), page => new ui.sceneobjects.ArcadeBodySection(page), page => new ui.sceneobjects.ArcadeGeometrySection(page), page => new ui.sceneobjects.ArcadeBodyMovementSection(page), @@ -364,6 +405,7 @@ namespace phasereditor2d.scene { new ui.sceneobjects.OriginTool(), new ui.sceneobjects.SizeTool(), new ui.sceneobjects.ArcadeBodyTool(), + new ui.sceneobjects.SliceTool(), new ui.sceneobjects.PolygonTool(), new ui.sceneobjects.SelectionRegionTool(), new ui.sceneobjects.PanTool(), @@ -445,6 +487,16 @@ namespace phasereditor2d.scene { return this.createUserPropertyTypes().find(t => t.getId() === typeId); } + getPrefabColor() { + + return colibri.ui.controls.Controls.getTheme().dark? "lightGreen" : "darkGreen"; + } + + getNestedPrefabColor() { + + return "olive"; + } + getSceneFinder() { return this._sceneFinder; diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/code/CodeResources.ts b/source/editor/plugins/phasereditor2d.scene/src/core/code/CodeResources.ts index 93e13a566..bfd8c4237 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/core/code/CodeResources.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/core/code/CodeResources.ts @@ -32,7 +32,7 @@ namespace phasereditor2d.scene.core.code { addResource(id: string, path: string) { - this._resources.push({ id, path }) + this._resources.push({ id, path }); } addCodeResource(fileName: string) { @@ -105,13 +105,21 @@ namespace phasereditor2d.scene.core.code { const newFiles = []; const resources = this._resources.filter(r => r.id.startsWith(`${spec}/`)); - resources.push(this._resources.find(r => r.id.startsWith("defs"))); + + const defsRes = this._resources.find(r => r.id.startsWith("defs")); + + if (defsRes) { + + resources.push(defsRes); + } monitor.addTotal(resources.length + 1); await this.preload(); monitor.step(); + console.log(resources); + for (const resource of resources) { const fileName = resource.path.split("/").pop(); @@ -133,6 +141,8 @@ namespace phasereditor2d.scene.core.code { } catch (e) { + console.log(e); + alert("Error: " + e.message); } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/code/JavaScriptUnitCodeGenerator.ts b/source/editor/plugins/phasereditor2d.scene/src/core/code/JavaScriptUnitCodeGenerator.ts index 0632d0d6d..8e7fe1f90 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/core/code/JavaScriptUnitCodeGenerator.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/core/code/JavaScriptUnitCodeGenerator.ts @@ -396,6 +396,12 @@ namespace phasereditor2d.scene.core.code { if (call.getContextExpr() && call.getContextExpr().length > 0) { this.append(call.getContextExpr()); + + if (this.isTypeScript() && call.isOptionalContext()) { + + this.append("!"); + } + this.append("."); } diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/code/MethodCallCodeDOM.ts b/source/editor/plugins/phasereditor2d.scene/src/core/code/MethodCallCodeDOM.ts index 78f205167..0effa31fe 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/core/code/MethodCallCodeDOM.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/core/code/MethodCallCodeDOM.ts @@ -7,9 +7,9 @@ namespace phasereditor2d.scene.core.code { private _args: string[]; private _returnToVar: string; private _declareReturnToVar: boolean; - private _declareReturnToField: boolean; private _isConstructor: boolean; private _explicitType: string; + private _optionalContext: boolean; constructor(methodName: string, contextExpr = "") { super(); @@ -19,26 +19,40 @@ namespace phasereditor2d.scene.core.code { this._args = []; this._declareReturnToVar = false; this._isConstructor = false; - this._declareReturnToField = false; + } + + setOptionalContext(optionalContext: boolean) { + + this._optionalContext = optionalContext; + } + + isOptionalContext() { + + return this._optionalContext; } isConstructor() { + return this._isConstructor; } setConstructor(isConstructor: boolean) { + this._isConstructor = isConstructor; } getReturnToVar() { + return this._returnToVar; } setReturnToVar(returnToVar: string) { + this._returnToVar = returnToVar; } setDeclareReturnToVar(declareReturnToVar: boolean) { + this._declareReturnToVar = declareReturnToVar; } @@ -47,16 +61,6 @@ namespace phasereditor2d.scene.core.code { return this._declareReturnToVar; } - setDeclareReturnToField(declareReturnToField: boolean) { - - this._declareReturnToField = declareReturnToField; - } - - isDeclareReturnToField() { - - return this._declareReturnToField; - } - setExplicitType(explicitType: string) { this._explicitType = explicitType; @@ -72,6 +76,11 @@ namespace phasereditor2d.scene.core.code { this._args.push(expr); } + argUndefined() { + + this.arg("undefined"); + } + argStringOrFloat(expr: string | number) { switch (typeof expr) { @@ -97,6 +106,10 @@ namespace phasereditor2d.scene.core.code { case "number": this.argInt(expr); break; + + case "undefined": + this.arg("undefined"); + break; } } @@ -121,18 +134,22 @@ namespace phasereditor2d.scene.core.code { } getMethodName() { + return this._methodName; } setMethodName(methodName: string) { + this._methodName = methodName; } getContextExpr() { + return this._contextExpr; } getArgs() { + return this._args; } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCodeDOMBuilder.ts b/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCodeDOMBuilder.ts index 6e0086402..d54e5d20a 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCodeDOMBuilder.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCodeDOMBuilder.ts @@ -1,11 +1,7 @@ -/// -/// namespace phasereditor2d.scene.core.code { import io = colibri.core.io; import ISceneGameObject = ui.sceneobjects.ISceneGameObject; - import Container = ui.sceneobjects.Container; - import Layer = ui.sceneobjects.Layer; export class SceneCodeDOMBuilder { @@ -14,6 +10,8 @@ namespace phasereditor2d.scene.core.code { private _sceneFile: io.FilePath; private _unit: UnitCodeDOM; private _fileNameMap: Map; + private _requireDeclareVarSet: Set; + private _objectsToFieldList: ISceneGameObject[]; constructor(scene: ui.Scene, file: io.FilePath) { @@ -21,6 +19,8 @@ namespace phasereditor2d.scene.core.code { this._sceneFile = file; this._isPrefabScene = this._scene.isPrefabSceneType(); this._fileNameMap = new Map(); + this._requireDeclareVarSet = new Set(); + this._objectsToFieldList = []; } async build(): Promise { @@ -136,7 +136,7 @@ namespace phasereditor2d.scene.core.code { const fields: MemberDeclCodeDOM[] = []; - this.buildObjectClassFields(fields, this._scene.getDisplayListChildren()); + this.buildObjectClassFields(fields, this._scene.getGameObjects()); this.buildPlainObjectsClassFields(fields); this.buildListClassFields(fields); @@ -177,6 +177,30 @@ namespace phasereditor2d.scene.core.code { return unit; } + private addImportForType(type: string) { + + if (!this._scene.getSettings().autoImport) { + + return; + } + + if (type) { + + if (type.startsWith("Phaser.")) { + + this._unit.addImport("Phaser", "phaser"); + + } else if (this._fileNameMap.has(type)) { + + const importFile = this._fileNameMap.get(type); + + const importPath = code.getImportPath(this._sceneFile, importFile); + + this._unit.addImport(type, importPath); + } + } + } + private getClassName() { return this._sceneFile.getNameWithoutExtension(); @@ -242,14 +266,13 @@ namespace phasereditor2d.scene.core.code { private buildObjectClassFields(fields: MemberDeclCodeDOM[], children: ISceneGameObject[]) { - for (const obj of children) { + for (const obj of this._objectsToFieldList) { const objES = obj.getEditorSupport(); - const isMethodScope = objES.getScope() === ui.sceneobjects.ObjectScope.METHOD; const isPrefabObj = this._scene.isPrefabSceneType() && this._scene.getPrefabObject() === obj; const isPrefabScene = this._scene.isPrefabSceneType(); - if (!isMethodScope && !isPrefabObj) { + if (!isPrefabObj) { const varName = code.formatToValidVarName(objES.getLabel()); @@ -268,46 +291,7 @@ namespace phasereditor2d.scene.core.code { fields.push(field); } - - const children = this.getWalkingChildren(obj); - - if (children) { - - this.buildObjectClassFields(fields, children); - } - } - } - - private getWalkingChildren(obj: ISceneGameObject) { - - let children: ISceneGameObject[]; - - if (obj instanceof Container || obj instanceof Layer) { - - const objES = obj.getEditorSupport(); - - if (objES.isPrefabInstance()) { - - if (objES.isPrefeabInstanceAppendedChild()) { - - children = objES.getChildren(); - - } else if (objES.isMutableNestedPrefabInstance()) { - - children = objES.getMutableNestedPrefabChildren(); - - } else { - - children = obj.getEditorSupport().getAppendedChildren(); - } - - } else { - - children = objES.getChildren(); - } } - - return children; } private buildPrefabConstructorMethod() { @@ -326,17 +310,25 @@ namespace phasereditor2d.scene.core.code { const type = prefabObj.getEditorSupport().getObjectType(); const ext = ScenePlugin.getInstance().getGameObjectExtensionByObjectType(type); - + const objBuilder = ext.getCodeDOMBuilder(); this.buildPrefabTypeScriptDefinitionsCodeDOM(prefabObj, objBuilder); ctrDecl.arg("scene", "Phaser.Scene"); - objBuilder.buildPrefabConstructorDeclarationCodeDOM({ + const args: ui.sceneobjects.IBuildPrefabConstructorDeclarationCodeDOM = { ctrDeclCodeDOM: ctrDecl, - prefabObj - }); + prefabObj, + importTypes: [] + }; + + objBuilder.buildPrefabConstructorDeclarationCodeDOM(args); + + for (const type of args.importTypes) { + + this.addImportForType(type); + } { const superCall = new MethodCallCodeDOM("super"); @@ -345,7 +337,7 @@ namespace phasereditor2d.scene.core.code { objBuilder.buildPrefabConstructorDeclarationSupperCallCodeDOM({ superMethodCallCodeDOM: superCall, - prefabObj: prefabObj + prefabObj: prefabObj, }); body.push(superCall); @@ -363,14 +355,11 @@ namespace phasereditor2d.scene.core.code { body.push(...result.statements); - if (prefabObj instanceof Container || prefabObj instanceof Layer) { - - this.addChildrenObjects({ - createMethodDecl: ctrDecl, - obj: prefabObj, - lazyStatements - }); - } + this.addChildrenObjects({ + createMethodDecl: ctrDecl, + obj: prefabObj, + lazyStatements + }); this.addCreateAllPlainObjectCode(ctrDecl.getBody(), lazyStatements); @@ -399,10 +388,10 @@ namespace phasereditor2d.scene.core.code { return ctrDecl; } - + private buildPrefabTypeScriptDefinitionsCodeDOM(prefabObj: ISceneGameObject, objBuilder: ui.sceneobjects.GameObjectCodeDOMBuilder) { - - for(const comp of prefabObj.getEditorSupport().getActiveComponents()) { + + for (const comp of prefabObj.getEditorSupport().getActiveComponents()) { comp.buildPrefabTypeScriptDefinitionsCodeDOM({ unit: this._unit, @@ -413,7 +402,7 @@ namespace phasereditor2d.scene.core.code { const settings = this._scene.getSettings(); - for(const iface of this._unit.getTypeScriptInterfaces()) { + for (const iface of this._unit.getTypeScriptInterfaces()) { iface.setExportInterface(settings.exportClass); } @@ -463,7 +452,7 @@ namespace phasereditor2d.scene.core.code { this.addCreateAllPlainObjectCode(body, lazyStatements); - for (const obj of this._scene.getDisplayListChildren()) { + for (const obj of this._scene.getGameObjects()) { if (obj.getEditorSupport().isMutableNestedPrefabInstance()) { @@ -530,12 +519,9 @@ namespace phasereditor2d.scene.core.code { const objectFactoryMethodCall = result.objectFactoryMethodCall; - // methodCall.setDeclareReturnToVar(true); - if (!objSupport.isMethodScope()) { objectFactoryMethodCall.setDeclareReturnToVar(true); - objectFactoryMethodCall.setDeclareReturnToField(true); } if (objectFactoryMethodCall.isDeclareReturnToVar()) { @@ -590,11 +576,11 @@ namespace phasereditor2d.scene.core.code { private addFieldInitCode_GameObjects(fields: CodeDOM[], prefabObj: ISceneGameObject, children: ISceneGameObject[]) { - for (const obj of children) { + for (const obj of this._objectsToFieldList) { const objES = obj.getEditorSupport(); - if (!objES.isMethodScope() && prefabObj !== obj) { + if (prefabObj !== obj) { const varname = formatToValidVarName(objES.getLabel()); @@ -603,14 +589,29 @@ namespace phasereditor2d.scene.core.code { fields.push(dom); } + } - const walkingChildren = this.getWalkingChildren(obj); + // for (const obj of children) { - if (walkingChildren) { + // const objES = obj.getEditorSupport(); - this.addFieldInitCode_GameObjects(fields, prefabObj, walkingChildren); - } - } + // if (!objES.isMethodScope() && prefabObj !== obj) { + + // const varname = formatToValidVarName(objES.getLabel()); + + // const dom = new AssignPropertyCodeDOM(varname, "this"); + // dom.value(varname); + + // fields.push(dom); + // } + + // const walkingChildren = this.getWalkingChildren(obj); + + // if (walkingChildren) { + + // this.addFieldInitCode_GameObjects(fields, prefabObj, walkingChildren); + // } + // } } private addFieldInitCode(body: CodeDOM[]) { @@ -619,7 +620,7 @@ namespace phasereditor2d.scene.core.code { const prefabObj = this._scene.isPrefabSceneType() ? this._scene.getPrefabObject() : null; - this.addFieldInitCode_GameObjects(fields, prefabObj, this._scene.getDisplayListChildren()); + this.addFieldInitCode_GameObjects(fields, prefabObj, this._scene.getGameObjects()); for (const obj of this._scene.getPlainObjects()) { @@ -669,15 +670,27 @@ namespace phasereditor2d.scene.core.code { lazyStatements.push(...result.lazyStatements); + if (result.statements.length + result.lazyStatements.length > 0) { + + this.addVarNameToRequiredDeclareVarSet(varname); + } + createMethodDecl.getBody().push(...result.statements); - if (obj instanceof Container || obj instanceof Layer) { + this.addChildrenObjects({ + createMethodDecl, + obj, + lazyStatements + }); + } - this.addChildrenObjects({ - createMethodDecl, - obj, - lazyStatements - }); + private addVarNameToRequiredDeclareVarSet(varName: string) { + + const split = varName.split("."); + + if (split.length > 1) { + + this._requireDeclareVarSet.add(split[0]); } } @@ -687,6 +700,26 @@ namespace phasereditor2d.scene.core.code { let createObjectMethodCall: MethodCallCodeDOM; + const objParent = objES.getObjectParent(); + let parentVarName: string; + + if (objParent) { + + const parentIsPrefabObject = this._scene.isPrefabSceneType() + && objParent === this._scene.getPrefabObject(); + + parentVarName = parentIsPrefabObject ? "this" + : this.getPrefabInstanceVarName(objParent); + } + + // the script nodes require using the varname of the parents + // so we need to generate a var for it. This covers the cases of + // nested prefabs which are parents of new nodes + if (obj instanceof ui.sceneobjects.ScriptNode && parentVarName) { + + this.addVarNameToRequiredDeclareVarSet(parentVarName); + } + if (objES.isPrefabInstance()) { const clsName = objES.getPrefabName(); @@ -708,6 +741,7 @@ namespace phasereditor2d.scene.core.code { obj, methodCallDOM: createObjectMethodCall, sceneExpr: this._isPrefabScene ? "scene" : "this", + parentVarName, prefabSerializer }); @@ -723,14 +757,30 @@ namespace phasereditor2d.scene.core.code { const builder = objES.getExtension().getCodeDOMBuilder(); - const factoryVarname = builder.getChainToFactory(); - + const factoryVarName = builder.getChainToFactory(); + const sceneVarName = this._scene.isPrefabSceneType() ? `scene` : `this`; createObjectMethodCall = builder.buildCreateObjectWithFactoryCodeDOM({ - gameObjectFactoryExpr: this._scene.isPrefabSceneType() ? - `scene.${factoryVarname}` : `this.${factoryVarname}`, + gameObjectFactoryExpr: `${sceneVarName}.${factoryVarName}`, + sceneExpr: sceneVarName, + parentVarName, obj: obj }); + // for example, in case it is adding a ScriptNode to a scene + if (createObjectMethodCall.isConstructor()) { + + const clsName = createObjectMethodCall.getMethodName(); + + const clsFile = this._fileNameMap.get(clsName); + + if (clsFile) { + + const filePath = code.getImportPath(this._sceneFile, clsFile); + + this._unit.addImport(clsName, filePath); + } + } + const forcingType = this.getExplicitType(obj); createObjectMethodCall.setExplicitType(forcingType); @@ -738,11 +788,10 @@ namespace phasereditor2d.scene.core.code { const varname = formatToValidVarName(objES.getLabel()); - const objParent = ui.sceneobjects.getObjectParent(obj); - createMethodDecl.getBody().push(createObjectMethodCall); - if (objES.isPrefabInstance()) { + // script nodes are not added to the scene this way + if (objES.isPrefabInstance() && objES.isDisplayObject()) { createObjectMethodCall.setDeclareReturnToVar(true); @@ -759,7 +808,6 @@ namespace phasereditor2d.scene.core.code { varname }); - if (result.statements.length + result.lazyStatements.length > 0) { createObjectMethodCall.setDeclareReturnToVar(true); @@ -769,34 +817,50 @@ namespace phasereditor2d.scene.core.code { createMethodDecl.getBody().push(...result.statements); - if (objParent) { + // the script nodes are not added to the parent this way + if (objParent && objES.isDisplayObject()) { createObjectMethodCall.setDeclareReturnToVar(true); - const parentIsPrefabObject = this._scene.isPrefabSceneType() - && objParent === this._scene.getPrefabObject(); - - const parentVarname = parentIsPrefabObject ? "this" - : this.getPrefabInstanceVarName(objParent); - - const addToParentCall = new MethodCallCodeDOM("add", parentVarname); + const addToParentCall = new MethodCallCodeDOM("add", parentVarName); addToParentCall.arg(varname); createMethodDecl.getBody().push(addToParentCall); } - if (obj instanceof Container || obj instanceof Layer) { + // generate children + { + let declareVar: boolean; - createObjectMethodCall.setDeclareReturnToVar(true); + if (objES.isPrefabInstance()) { + + declareVar = objES.getAppendedChildren().length > 0; + + } else { + + declareVar = objES.getObjectChildren().length > 0; + } this.addChildrenObjects({ createMethodDecl, obj, lazyStatements }); + + if (this._requireDeclareVarSet.has(varname)) { + + declareVar = true; + } + + if (declareVar) { + + createObjectMethodCall.setDeclareReturnToVar(true); + } } + // generate lists + { const lists = objES.getScene().getObjectLists().getListsByObjectId(objES.getId()); @@ -806,10 +870,12 @@ namespace phasereditor2d.scene.core.code { } } + // set var flags + if (!objES.isMethodScope()) { createObjectMethodCall.setDeclareReturnToVar(true); - createObjectMethodCall.setDeclareReturnToField(true); + this._objectsToFieldList.push(obj); } if (createObjectMethodCall.isDeclareReturnToVar()) { @@ -817,34 +883,34 @@ namespace phasereditor2d.scene.core.code { createObjectMethodCall.setReturnToVar(varname); } } - + getExplicitType(obj: ISceneGameObject) { - + const objES = obj.getEditorSupport(); return objES.getActiveComponents() - .map(comp => comp.getExplicitTypesForMethodFactory()) + .map(comp => comp.getExplicitTypesForMethodFactory()) - .filter(type => type !== undefined) + .filter(type => type !== undefined) - .join(" & "); + .join(" & "); } - private getPrefabInstanceVarName(obj: ISceneGameObject) { + private getPrefabInstanceVarName(obj: ISceneGameObject): string { - const objSupport = obj.getEditorSupport(); + const objES = obj.getEditorSupport(); - if (objSupport.isScenePrefabObject()) { + if (objES.isScenePrefabObject()) { return "this"; } - const varName = formatToValidVarName(objSupport.getLabel()); + const varName = formatToValidVarName(objES.getLabel()); - if (objSupport.isNestedPrefabInstance()) { + if (objES.isNestedPrefabInstance()) { - const parent = this.findPrefabInstanceThatIsDefinedAsRootPrefab(obj); + const parent = this.findPrefabInstanceWhereTheGivenObjectIsDefined(obj); const parentVarName = this.getPrefabInstanceVarName(parent); @@ -854,16 +920,56 @@ namespace phasereditor2d.scene.core.code { return varName; } - private findPrefabInstanceThatIsDefinedAsRootPrefab(obj: ui.sceneobjects.ISceneGameObject): ui.sceneobjects.ISceneGameObject { + private findPrefabInstanceWhereTheGivenObjectIsDefined(obj: ui.sceneobjects.ISceneGameObject): ui.sceneobjects.ISceneGameObject { - const parent = ui.sceneobjects.getObjectParent(obj); + const objES = obj.getEditorSupport(); - if (parent.getEditorSupport().isRootPrefabDefined()) { + // get the prefab file of the object... - return parent; + const objPrefabFile = objES.getPrefabFile(); + + // ...so find the parent that is an instance of this file + + const parent = objES.getObjectParent(); + + return this.findPrefabInstanceOfFile(parent, objPrefabFile); + } + + private findPrefabInstanceOfFile(obj: ISceneGameObject, targetPrefaFile: io.FilePath): ISceneGameObject { + + const finder = ScenePlugin.getInstance().getSceneFinder(); + + const objES = obj.getEditorSupport(); + + // it is posible the object is a nested prefab, + // but what we need is the original prefab file or a variant of it. + const firstNonNestedPrefabId = finder.getFirstNonNestedPrefabId(objES.getPrefabId()); + + // maybe it is a nested prefab of a built-in type, + // in that case, the prefabId is undefined, and it should + // keep searching in the parent + if (firstNonNestedPrefabId) { + + // the original prefab file (or a variant of it) + // this could be 'undefined' if the obj is a nested prefab + // of a primitive type. + const prefabFile = finder.getPrefabFile(firstNonNestedPrefabId); + + // ok, if both file are the same, I found it! + if (prefabFile === targetPrefaFile) { + + return obj; + } + + // no, wait, it is a variant! That's ok too. + if (finder.isPrefabVariant(prefabFile, targetPrefaFile)) { + + return obj; + } } - return this.findPrefabInstanceThatIsDefinedAsRootPrefab(parent); + // not found? keep searching with the parent... + return this.findPrefabInstanceOfFile(objES.getObjectParent(), targetPrefaFile); } private buildSetObjectProperties(args: { @@ -901,15 +1007,16 @@ namespace phasereditor2d.scene.core.code { } private addChildrenObjects(args: { - obj: Container | Layer, + obj: ISceneGameObject, createMethodDecl: MethodDeclCodeDOM, lazyStatements: CodeDOM[] }) { + const objES = args.obj.getEditorSupport(); const body = args.createMethodDecl.getBody(); - const parentIsPrefab = args.obj.getEditorSupport().isPrefabInstance(); + const parentIsPrefab = objES.isPrefabInstance(); - for (const child of args.obj.getChildren()) { + for (const child of objES.getObjectChildren()) { const childES = child.getEditorSupport(); diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCompiler.ts b/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCompiler.ts index ed723b475..550f51afe 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCompiler.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/core/code/SceneCompiler.ts @@ -30,6 +30,8 @@ namespace phasereditor2d.scene.core.code { async compile() { + console.log(`Compiling ${this._sceneFile.getName()}`); + const settings = this._scene.getSettings(); if (!settings.compilerEnabled) { diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneFinder.ts b/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneFinder.ts index 44c57e9a8..ebce30ae2 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneFinder.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneFinder.ts @@ -24,7 +24,7 @@ namespace phasereditor2d.scene.core.json { async preload(monitor: controls.IProgressMonitor) { await this._finder.preload(monitor); - + this._finder.runMigrations(); } } @@ -367,6 +367,48 @@ namespace phasereditor2d.scene.core.json { return this._prefabFiles; } + getScriptPrefabFiles() { + + return this._prefabFiles.filter(file => this.isScriptPrefabFile(file)); + } + + isScriptPrefabFile(file: io.FilePath) { + + let prefabId = this.getPrefabId(file); + + if (prefabId) { + + prefabId = this.getOriginalPrefabId(prefabId); + + const data = this.getPrefabData(prefabId); + + if (data && data.type === ui.sceneobjects.ScriptNodeExtension + .getInstance().getTypeName()) { + + return true; + } + } + + return false; + } + + getFirstNonNestedPrefabId(prefabId: string): string | undefined { + + if (this.isNestedPrefab(prefabId)) { + + const data = this.getPrefabData(prefabId); + + if (data.prefabId) { + + return this.getFirstNonNestedPrefabId(data.prefabId); + } + + return undefined; + } + + return prefabId; + } + getOriginalPrefabId(prefabId: string): string | undefined { const objData = this.getPrefabData(prefabId); @@ -409,6 +451,20 @@ namespace phasereditor2d.scene.core.json { return this.getPrefabHierarchy2(prefabId, []); } + isPrefabVariant(basePrefabFile: io.FilePath, superPrefanFile: io.FilePath) { + + const basePrefabId = this.getPrefabId(basePrefabFile); + + const result = this.getPrefabHierarchy(basePrefabId); + + if (result.indexOf(superPrefanFile) >= 0) { + + return true; + } + + return false; + } + private getPrefabHierarchy2(prefabId: string, result: io.FilePath[]) { const file = this.getPrefabFile(prefabId); @@ -428,6 +484,13 @@ namespace phasereditor2d.scene.core.json { return result; } + isPrefabFile(file: io.FilePath) { + + const data = this.getSceneData(file); + + return data && data.sceneType === SceneType.PREFAB; + } + getSceneData(file: io.FilePath) { return this._sceneFilename_Data_Map.get(file.getFullName()); diff --git a/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneWriter.ts b/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneWriter.ts index e1b78b97c..8325fe47c 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneWriter.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/core/json/SceneWriter.ts @@ -41,7 +41,7 @@ namespace phasereditor2d.scene.core.json { // display list - for (const obj of this._scene.getDisplayListChildren()) { + for (const obj of this._scene.getGameObjects()) { const objData = {} as IObjectData; obj.getEditorSupport().writeJSON(objData); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/BaseScene.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/BaseScene.ts index 86b79216a..dc6a552ea 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/BaseScene.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/BaseScene.ts @@ -35,8 +35,11 @@ namespace phasereditor2d.scene.ui { if (this.game) { - this.game.destroy(true); - this.game.loop.tick(); + // we need to start the loop so the game could be destroyed + // for checking if the game is destroyed, you can listen to Phaser.Core.Events.DESTROY. + this.game.loop.start(this.game.loop.callback); + + this.game.destroy(true, false); } } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/Scene.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/Scene.ts index 0879ef7cd..6e983b934 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/Scene.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/Scene.ts @@ -46,7 +46,7 @@ namespace phasereditor2d.scene.ui { const map: Map = new Map(); - this.buildSortingMap(map, this.getDisplayListChildren(), 0); + this.buildSortingMap(map, this.getGameObjects(), 0); objects.sort((a, b) => { @@ -65,9 +65,11 @@ namespace phasereditor2d.scene.ui { map.set(obj, index); - if (!(obj as sceneobjects.ISceneGameObject).getEditorSupport().isPrefabInstance()) { + const objES = (obj as sceneobjects.ISceneGameObject).getEditorSupport(); - const children = sceneobjects.GameObjectEditorSupport.getObjectChildren(obj as any); + if (!objES.isPrefabInstance()) { + + const children = objES.getObjectChildren(); index = this.buildSortingMap(map, children, index); } @@ -110,6 +112,31 @@ namespace phasereditor2d.scene.ui { } } + getGameObjectIndex(obj: sceneobjects.ISceneGameObject) { + + return this.children.getIndex(obj); + } + + removeGameObject(obj: sceneobjects.ISceneGameObject) { + + this.children.remove(obj); + + if (obj instanceof sceneobjects.ScriptNode) { + + obj.setParent(undefined); + } + } + + addGameObject(obj: sceneobjects.ISceneGameObject, skipCallback = false) { + + this.children.add(obj, skipCallback); + } + + addGameObjectAt(obj: sceneobjects.ISceneGameObject, index: number, skipCallback = false) { + + this.children.addAt(obj, index, skipCallback); + } + addPlainObject(obj: sceneobjects.IScenePlainObject) { this._plainObjects.push(obj); @@ -158,17 +185,32 @@ namespace phasereditor2d.scene.ui { this.input["_pendingInsertion"].length = 0; this.input["_pendingRemoval"].length = 0; - for (const obj of this.getDisplayListChildren()) { + for (const obj of this.getGameObjects()) { obj.getEditorSupport().destroy(); } } + isScriptNodePrefabScene() { + + if (this.isPrefabSceneType()) { + + const obj = this.getPrefabObject(); + + if (obj) { + + return obj instanceof sceneobjects.ScriptNode; + } + } + + return false; + } + getPrefabObject(): sceneobjects.ISceneGameObject { if (this.sys.displayList) { - const list = this.getDisplayListChildren(); + const list = this.getGameObjects(); return list[list.length - 1]; } @@ -178,17 +220,17 @@ namespace phasereditor2d.scene.ui { isNonTopPrefabObject(obj: any) { - const support = sceneobjects.GameObjectEditorSupport.getEditorSupport(obj); + const objES = sceneobjects.GameObjectEditorSupport.getEditorSupport(obj); - if (support) { + if (objES) { - const scene = support.getScene(); + const scene = objES.getScene(); if (scene.isPrefabSceneType()) { if (scene.getPrefabObject() !== obj) { - const parent = sceneobjects.getObjectParent(obj); + const parent = objES.getObjectParent(); if (parent) { @@ -248,14 +290,19 @@ namespace phasereditor2d.scene.ui { return super.getMaker() as SceneMaker; } - getDisplayListChildren(): sceneobjects.ISceneGameObject[] { + sortGameObjects() { + + sceneobjects.sortObjectsAlgorithm(this.getGameObjects(), 0); + } + + getGameObjects(): sceneobjects.ISceneGameObject[] { return this.sys.displayList.getChildren() as any; } getInputSortedObjects(): Phaser.GameObjects.GameObject[] { - return this.getInputSortedObjects2([], this.getDisplayListChildren()); + return this.getInputSortedObjects2([], this.getGameObjects()); } private getInputSortedObjects2( @@ -267,7 +314,7 @@ namespace phasereditor2d.scene.ui { if (obj.visible && obj.alpha > 0) { - this.getInputSortedObjects2(result, obj.getChildren()); + this.getInputSortedObjects2(result, obj.getEditorSupport().getObjectChildren()); } } else { @@ -281,7 +328,7 @@ namespace phasereditor2d.scene.ui { visitAll(visitor: (obj: sceneobjects.ISceneGameObject) => void) { - this.visit(visitor, this.getDisplayListChildren()); + this.visit(visitor, this.getGameObjects()); } visit(visitor: (obj: sceneobjects.ISceneGameObject) => void, children: sceneobjects.ISceneGameObject[]) { @@ -290,16 +337,13 @@ namespace phasereditor2d.scene.ui { visitor(obj); - if (obj instanceof sceneobjects.Container || obj instanceof sceneobjects.Layer) { - - this.visit(visitor, obj.getChildren()); - } + this.visit(visitor, obj.getEditorSupport().getObjectChildren()); } } visitAllAskChildren(visitor: (obj: sceneobjects.ISceneGameObject) => boolean) { - this.visitAskChildren(visitor, this.getDisplayListChildren()); + this.visitAskChildren(visitor, this.getGameObjects()); } visitAskChildren( @@ -311,10 +355,7 @@ namespace phasereditor2d.scene.ui { if (visitChildren) { - if (obj instanceof sceneobjects.Container || obj instanceof sceneobjects.Layer) { - - this.visitAskChildren(visitor, obj.getChildren()); - } + this.visitAskChildren(visitor, obj.getEditorSupport().getObjectChildren()); } } } @@ -363,7 +404,7 @@ namespace phasereditor2d.scene.ui { const map = new Map(); - this.buildObjectSortingMap2(map, this.getDisplayListChildren()); + this.buildObjectSortingMap2(map, this.getGameObjects()); return map; } @@ -391,7 +432,7 @@ namespace phasereditor2d.scene.ui { if (obj instanceof sceneobjects.Container || obj instanceof sceneobjects.Layer) { - i += this.buildObjectSortingMap2(map, obj.getChildren()); + i += this.buildObjectSortingMap2(map, obj.getEditorSupport().getObjectChildren()); } i++; @@ -418,7 +459,7 @@ namespace phasereditor2d.scene.ui { this.visitAll(obj => { - for(const node of obj.getEditorSupport().getUserComponentsComponent().getUserComponentNodes()) { + for (const node of obj.getEditorSupport().getUserComponentsComponent().getUserComponentNodes()) { map.set(node.getId(), node); } @@ -449,7 +490,7 @@ namespace phasereditor2d.scene.ui { getByEditorId(id: string) { - const obj = Scene.findByEditorId(this.getDisplayListChildren(), id); + const obj = Scene.findByEditorId(this.getGameObjects(), id); return obj; } @@ -491,7 +532,7 @@ namespace phasereditor2d.scene.ui { set = set ?? new Set(); - for (const obj of (list ?? this.getDisplayListChildren())) { + for (const obj of (list ?? this.getGameObjects())) { const id = obj.getEditorSupport().getId(); @@ -518,16 +559,14 @@ namespace phasereditor2d.scene.ui { for (const obj of list) { if (obj.getEditorSupport().getId() === id) { + return obj; } - if (obj instanceof sceneobjects.Container || obj instanceof sceneobjects.Layer) { - - const result = this.findByEditorId(obj.getChildren(), id); + const result = this.findByEditorId(obj.getEditorSupport().getObjectChildren(), id); - if (result) { - return result; - } + if (result) { + return result; } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts index 2221d99a5..9c9364ff1 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneMaker.ts @@ -2,7 +2,6 @@ namespace phasereditor2d.scene.ui { import controls = colibri.ui.controls; - import ide = colibri.ui.ide; import io = colibri.core.io; import json = core.json; import FileUtils = colibri.ui.ide.FileUtils; @@ -17,9 +16,33 @@ namespace phasereditor2d.scene.ui { this._editorScene = scene; } + private findDropScriptTargetParent(obj: sceneobjects.ISceneGameObject) { + + // if (obj instanceof sceneobjects.ScriptNode) { + + // return obj; + // } + + // const parent = obj.getEditorSupport().getObjectParent(); + + // const objES = obj.getEditorSupport(); + + // if (objES.isPrefabInstanceElement() && !objES.isMutableNestedPrefabInstance()) { + + // if (parent) { + + // return this.findDropTargetParent(parent); + // } + + // return undefined; + // } + + return obj; + } + private findDropTargetParent(obj: sceneobjects.ISceneGameObject) { - const parent = sceneobjects.getObjectParent(obj); + const parent = obj.getEditorSupport().getObjectParent(); if (obj instanceof sceneobjects.Container || obj instanceof sceneobjects.Layer) { @@ -27,7 +50,7 @@ namespace phasereditor2d.scene.ui { if (objES.isPrefabInstanceElement() || objES.isPrefabInstance()) { - if (!objES.isAllowAppendChildren() || !objES.isMutableNestedPrefabInstance()) { + if (!objES.isAllowAppendChildren() || objES.isPrefabInstanceElement() && !objES.isMutableNestedPrefabInstance()) { if (parent) { @@ -49,66 +72,78 @@ namespace phasereditor2d.scene.ui { return undefined; } - afterDropObjects(prefabObj: sceneobjects.ISceneGameObject, sprites: sceneobjects.ISceneGameObject[]) { + afterDropObjects(prefabObj: sceneobjects.ISceneGameObject, dropObjects: sceneobjects.ISceneGameObject[]) { - let container: sceneobjects.Container; - let layer: sceneobjects.Layer; + let dropInContainer: sceneobjects.Container; + let dropInObj: sceneobjects.ISceneGameObject; - for (const sprite of this._editorScene.getEditor().getSelectedGameObjects()) { + const selection = this._editorScene.getEditor().getSelectedGameObjects(); - let sprite2 = sprite; + const areDropingScriptNodes = dropObjects.filter(obj => obj instanceof sceneobjects.ScriptNode).length === dropObjects.length; - const dropTarget = this.findDropTargetParent(sprite2); + for (const sprite of selection) { + + const dropTarget = areDropingScriptNodes ? this.findDropScriptTargetParent(sprite) : this.findDropTargetParent(sprite); if (dropTarget) { - if (dropTarget instanceof sceneobjects.Container) { + if (areDropingScriptNodes) { + + dropInObj = dropTarget; + + } else if (dropTarget instanceof sceneobjects.Container) { - container = dropTarget; + dropInContainer = dropTarget; } else if (dropTarget instanceof sceneobjects.Layer) { - layer = dropTarget; + dropInObj = dropTarget; } else if (dropTarget.displayList instanceof sceneobjects.Layer) { - layer = dropTarget.displayList; + dropInObj = dropTarget.displayList; } - } } - if (container) { + if (dropInContainer) { - for (const obj of sprites) { + for (const dropObj of dropObjects) { - if (obj instanceof sceneobjects.Layer) { + if (dropObj instanceof sceneobjects.Layer) { continue; } - const sprite = obj as sceneobjects.Sprite; - const p = new Phaser.Math.Vector2(); - sprite.getWorldTransformMatrix().transformPoint(0, 0, p); + if (dropObj.getEditorSupport().isDisplayObject()) { + + const sprite = dropObj as sceneobjects.Sprite; + const p = new Phaser.Math.Vector2(); + sprite.getWorldTransformMatrix().transformPoint(0, 0, p); + + this._editorScene.removeGameObject(sprite); + dropInContainer.getEditorSupport().addObjectChild(sprite); - this._editorScene.sys.displayList.remove(sprite); - container.add(sprite); + dropInContainer.getWorldTransformMatrix().applyInverse(p.x, p.y, p); + sprite.x = p.x; + sprite.y = p.y; - container.getWorldTransformMatrix().applyInverse(p.x, p.y, p); - sprite.x = p.x; - sprite.y = p.y; + } else { + + dropInContainer.getEditorSupport().addObjectChild(dropObj); + } } - } else if (layer) { + } else if (dropInObj) { - for (const obj of sprites) { + for (const obj of dropObjects) { - layer.add(obj); + dropInObj.getEditorSupport().addObjectChild(obj); } } else { - this.afterDropObjectsInPrefabScene(prefabObj, sprites); + this.afterDropObjectsInPrefabScene(prefabObj, dropObjects); } } @@ -126,14 +161,21 @@ namespace phasereditor2d.scene.ui { return; } - let parent: sceneobjects.Container | sceneobjects.Layer; + const dropOnlyScripts = sprites + .filter(obj => obj instanceof sceneobjects.ScriptNode).length === sprites.length; + + let parent: sceneobjects.Container | sceneobjects.Layer | sceneobjects.ScriptNode; if (scene.isPrefabSceneType()) { if (sprites.length > 0) { - if (!prefabObj.getEditorSupport().isPrefabInstance() - && (prefabObj instanceof sceneobjects.Container || prefabObj instanceof sceneobjects.Layer)) { + const prefabObjES = prefabObj.getEditorSupport(); + + if ((!prefabObjES.isPrefabInstance() || prefabObjES.isAllowAppendChildren()) + && (prefabObj instanceof sceneobjects.Container + || prefabObj instanceof sceneobjects.Layer + || (dropOnlyScripts && prefabObj instanceof sceneobjects.ScriptNode))) { parent = prefabObj; @@ -147,8 +189,8 @@ namespace phasereditor2d.scene.ui { parent.getEditorSupport().setLabel(scene.makeNewName("container")); - scene.sys.displayList.remove(prefabObj); - parent.add(prefabObj); + scene.removeGameObject(prefabObj); + parent.getEditorSupport().addObjectChild(prefabObj); } if (parent) { @@ -164,9 +206,11 @@ namespace phasereditor2d.scene.ui { } } - scene.sys.displayList.remove(sprite); + scene.removeGameObject(sprite); + + const parentES: sceneobjects.GameObjectEditorSupport = parent.getEditorSupport(); - parent.add(sprite); + parentES.addObjectChild(sprite); } if (parent !== prefabObj && parent instanceof sceneobjects.Container) { @@ -227,7 +271,7 @@ namespace phasereditor2d.scene.ui { const builder = new phasereditor2d.ide.core.MultiHashBuilder(); - for (const obj of this._editorScene.getDisplayListChildren()) { + for (const obj of this._editorScene.getGameObjects()) { await obj.getEditorSupport().buildDependencyHash({ builder }); } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailCache.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailCache.ts index 8ef78b537..ccd15646d 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailCache.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailCache.ts @@ -70,7 +70,7 @@ namespace phasereditor2d.scene.ui { } } - const image = new SceneThumbnail(file); + const image = new SceneThumbnailImage(file); await image.preload(); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnail.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailImage.ts similarity index 94% rename from source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnail.ts rename to source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailImage.ts index 188e04938..093e17b67 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnail.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/SceneThumbnailImage.ts @@ -37,7 +37,7 @@ namespace phasereditor2d.scene.ui { maker.createScene(this._data); - const children = this.getDisplayListChildren(); + const children = this.getGameObjects(); let singleObject: sceneobjects.ISceneGameObject; @@ -158,7 +158,7 @@ namespace phasereditor2d.scene.ui { private computeSceneBounds() { - const children = this.getDisplayListChildren(); + const children = this.getGameObjects().filter(obj => obj.getEditorSupport().isDisplayObject()); if (children.length === 0) { @@ -172,7 +172,7 @@ namespace phasereditor2d.scene.ui { let maxX = Number.MIN_SAFE_INTEGER; let maxY = Number.MIN_SAFE_INTEGER; - for (const obj of this.getDisplayListChildren()) { + for (const obj of children) { const points = obj.getEditorSupport().getScreenBounds(camera); @@ -194,7 +194,7 @@ namespace phasereditor2d.scene.ui { } } - export class SceneThumbnail implements controls.IImage { + export class SceneThumbnailImage implements controls.IImage { private _file: io.FilePath; private _image: controls.ImageWrapper; @@ -290,16 +290,16 @@ namespace phasereditor2d.scene.ui { let canvas: HTMLCanvasElement; - if (SceneThumbnail._canvas) { + if (SceneThumbnailImage._canvas) { - canvas = SceneThumbnail._canvas; + canvas = SceneThumbnailImage._canvas; } else { canvas = document.createElement("canvas"); canvas.style.width = (canvas.width = width) + "px"; canvas.style.height = (canvas.height = height) + "px"; - SceneThumbnail._canvas = canvas; + SceneThumbnailImage._canvas = canvas; const parent = document.createElement("div"); parent.style.position = "fixed"; @@ -319,7 +319,7 @@ namespace phasereditor2d.scene.ui { mode: Phaser.Scale.NONE }, render: { - pixelArt: true, + pixelArt: ScenePlugin.DEFAULT_PIXEL_ART, transparent: true }, audio: { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksCellRendererProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksCellRendererProvider.ts index 368884118..5ae1786ad 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksCellRendererProvider.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksCellRendererProvider.ts @@ -19,6 +19,12 @@ namespace phasereditor2d.scene.ui.blocks { if (element instanceof colibri.core.io.FilePath && ScenePlugin.getInstance().isSceneContentType(element)) { + if (ScenePlugin.getInstance().getSceneFinder().isScriptPrefabFile(element)) { + + return new colibri.ui.controls.viewers.IconGridCellRenderer( + ScenePlugin.getInstance().getIcon(ICON_BUILD)); + } + return new viewers.SceneFileCellRenderer(); } else if (element instanceof sceneobjects.SceneObjectExtension) { @@ -32,6 +38,10 @@ namespace phasereditor2d.scene.ui.blocks { } else if (typeof (element) === "string" && BLOCKS_SECTIONS.indexOf(element) >= 0) { return new controls.viewers.IconImageCellRenderer(colibri.ColibriPlugin.getInstance().getIcon(colibri.ICON_FOLDER)); + + } else if (element instanceof viewers.PhaserTypeSymbol) { + + return new controls.viewers.IconImageCellRenderer(colibri.ColibriPlugin.getInstance().getIcon(colibri.ICON_FOLDER)); } return super.getCellRenderer(element); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksContentProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksContentProvider.ts index b008b2150..f660991e9 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksContentProvider.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksContentProvider.ts @@ -16,11 +16,13 @@ namespace phasereditor2d.scene.ui.blocks { const grouping = pack.ui.viewers.AssetPackGrouping; + const SCRIPTS_CATEGORY = "Scripts"; + export class SceneEditorBlocksContentProvider extends pack.ui.viewers.AssetPackContentProvider { private _getPacks: () => pack.core.AssetPack[]; private _blocksProvider: SceneEditorBlocksProvider; - private _editor: editor.SceneEditor; + protected _editor: editor.SceneEditor; constructor(editor: editor.SceneEditor, getPacks: () => pack.core.AssetPack[]) { super(); @@ -41,6 +43,17 @@ namespace phasereditor2d.scene.ui.blocks { getRoots(input: any) { + if (this._editor.getScene().isScriptNodePrefabScene()) { + + const sceneFinder = ScenePlugin.getInstance().getSceneFinder(); + + return [ + sceneobjects.ScriptNodeExtension.getInstance(), + ...this.getSceneFiles("prefabs") + .filter(f => sceneFinder.isScriptPrefabFile(f)) + ]; + } + const groupingType = grouping.getGroupingPreference(); const section = this._blocksProvider.getSelectedTabSection(); @@ -54,7 +67,10 @@ namespace phasereditor2d.scene.ui.blocks { if (groupingType === grouping.GROUP_ASSETS_BY_LOCATION) { - return colibri.ui.ide.FileUtils.distinct(this.getSceneFiles("prefabs").map(f => f.getParent())); + const files = colibri.ui.ide.FileUtils.distinct( + this.getSceneFiles("prefabs").map(f => f.getParent())); + + return files; } return viewers.PhaserTypeSymbol.getSymbols(); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksProvider.ts index 6deb06132..0c24c6433 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksProvider.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksProvider.ts @@ -138,6 +138,11 @@ namespace phasereditor2d.scene.ui.blocks { return new SceneEditorBlocksLabelProvider(); } + getStyledLabelProvider(): controls.viewers.IStyledLabelProvider { + + return new SceneEditorBlocksStyledLabelProvider(); + } + getCellRendererProvider(): controls.viewers.ICellRendererProvider { return new SceneEditorBlocksCellRendererProvider(); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksStyledLabelProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksStyledLabelProvider.ts new file mode 100644 index 000000000..57c4404de --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksStyledLabelProvider.ts @@ -0,0 +1,18 @@ +namespace phasereditor2d.scene.ui.blocks { + + export class SceneEditorBlocksStyledLabelProvider extends SceneEditorBlocksLabelProvider implements colibri.ui.controls.viewers.IStyledLabelProvider { + + getStyledTexts(obj: any, dark: boolean): colibri.ui.controls.viewers.IStyledText[] { + + const text = super.getLabel(obj); + const isPrefab = obj instanceof colibri.core.io.FilePath + && ScenePlugin.getInstance().getSceneFinder().isPrefabFile(obj); + + return [{ + text, + color: isPrefab ? ScenePlugin.getInstance().getPrefabColor() + : colibri.ui.controls.Controls.getTheme().viewerForeground + }]; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksTreeRendererProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksTreeRendererProvider.ts index aefcf5054..97ac3d3e3 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksTreeRendererProvider.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/blocks/SceneEditorBlocksTreeRendererProvider.ts @@ -16,7 +16,6 @@ namespace phasereditor2d.scene.ui.blocks { ] export const BLOCKS_SECTIONS = [ - BUILTIN_SECTION, PREFAB_SECTION, ...BLOCKS_ASSET_SECTIONS diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/dialogs/AddObjectDialog.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/dialogs/AddObjectDialog.ts index 6b324e0b3..f289b7493 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/dialogs/AddObjectDialog.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/dialogs/AddObjectDialog.ts @@ -10,6 +10,7 @@ namespace phasereditor2d.scene.ui.dialogs { viewer.setContentProvider(new AddObjectContentProvider(editor)); viewer.setLabelProvider(new blocks.SceneEditorBlocksLabelProvider()); + viewer.setStyledLabelProvider(new blocks.SceneEditorBlocksStyledLabelProvider()); viewer.setCellRendererProvider(new blocks.SceneEditorBlocksCellRendererProvider()); viewer.setInput([]); @@ -68,6 +69,11 @@ namespace phasereditor2d.scene.ui.dialogs { getRoots(input: any) { + if (this._editor.getScene().isScriptNodePrefabScene()) { + + return [sceneobjects.ScriptNodeExtension.getInstance()]; + } + return SCENE_OBJECT_CATEGORIES; } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/ConvertTypeDialog.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/ConvertTypeDialog.ts index 189fb1584..f911e40fb 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/ConvertTypeDialog.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/ConvertTypeDialog.ts @@ -22,7 +22,7 @@ namespace phasereditor2d.scene.ui.editor { private static getObjectsToMorph(editor: SceneEditor) { - return editor.getSelection().filter(obj => sceneobjects.isGameObject(obj)); + return editor.getSelectedGameObjects().filter(obj => sceneobjects.isGameObject(obj)); } create() { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/DropManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/DropManager.ts index 4fcc25577..25ab1fc0c 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/DropManager.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/DropManager.ts @@ -222,25 +222,26 @@ namespace phasereditor2d.scene.ui.editor { for (const sceneObject of [...newSprites, ...newPlainObjects]) { - const support = sceneObject.getEditorSupport(); + const sceneObjectES = sceneObject.getEditorSupport(); - let label = support.getLabel(); + let label = sceneObjectES.getLabel(); - if (support instanceof sceneobjects.GameObjectEditorSupport) { - - label = support.isPrefabInstance() ? support.getPrefabName() : support.getLabel(); + if (sceneObjectES instanceof sceneobjects.GameObjectEditorSupport) { + label = sceneObjectES.isPrefabInstance() ? sceneObjectES.getPrefabName() : sceneObjectES.getLabel(); } label = core.code.formatToValidVarName(label); label = nameMaker.makeName(label); - support.setLabel(label); + sceneObjectES.setLabel(label); } scene.getMaker().afterDropObjects(prefabObj, newSprites); + sceneobjects.sortGameObjects(newSprites); + return [...newSprites, ...newPlainObjects, ...newLists]; } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/MouseManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/MouseManager.ts index bfe8a54af..8bdd9460f 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/MouseManager.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/MouseManager.ts @@ -61,9 +61,15 @@ namespace phasereditor2d.scene.ui.editor { if (tool.isObjectTool()) { + if (!tool.isValidForAll(args.objects)) { + + return; + } + for (const obj of args.objects) { if (!tool.canEdit(obj)) { + return; } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts index 4f3d24a73..45ade5977 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/OverlayLayer.ts @@ -29,12 +29,19 @@ namespace phasereditor2d.scene.ui.editor { const tool = manager.getActiveTool(); if (!tool) { + + return; + } + + if (!tool.isValidForAll(this._editor.getSelectedGameObjects())) { + return; } const renderSel = this._editor.getSelection().filter(obj => tool.canRender(obj)); if (renderSel.length === 0 && tool.isObjectTool()) { + return; } @@ -71,10 +78,15 @@ namespace phasereditor2d.scene.ui.editor { ctx.save(); const isGameObject = sceneobjects.isGameObject(obj); + const isUserCompNode = obj instanceof sceneobjects.UserComponentNode && !gameObjectsSet.has(obj.getObject()); - if (isGameObject || isUserCompNode) { + const isScriptNode = obj instanceof sceneobjects.ScriptNode && !gameObjectsSet.has(obj.getParentDisplayObject()); + + const isNonDisplayObject = isUserCompNode || isScriptNode; + + if (isGameObject || isNonDisplayObject) { let sprite: sceneobjects.ISceneGameObject; @@ -82,17 +94,28 @@ namespace phasereditor2d.scene.ui.editor { sprite = obj.getObject(); + } else if (isScriptNode) { + + sprite = obj.getParentDisplayObject(); + } else { sprite = obj as sceneobjects.ISceneGameObject; } - const points = sprite.getEditorSupport().getScreenBounds(camera); + if (!sprite) { + + continue; + } + + const spriteES = sprite.getEditorSupport(); + + const points = spriteES.getScreenBounds(camera); if (points.length === 4) { ctx.strokeStyle = "black"; - ctx.lineWidth = isUserCompNode ? 1 : 4; + ctx.lineWidth = isNonDisplayObject ? 1 : 4; ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y); @@ -105,7 +128,7 @@ namespace phasereditor2d.scene.ui.editor { ctx.strokeStyle = "#00ff00"; // ctx.strokeStyle = controls.Controls.getTheme().viewerSelectionBackground; - if (isUserCompNode) { + if (isNonDisplayObject) { ctx.lineWidth = 1; ctx.setLineDash([1, 2]); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditor.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditor.ts index df98487bb..bd78ff7d3 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditor.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditor.ts @@ -334,7 +334,7 @@ namespace phasereditor2d.scene.ui.editor { }, // resolution: window.devicePixelRatio, render: { - pixelArt: true, + pixelArt: ScenePlugin.DEFAULT_EDITOR_PIXEL_ART, transparent: true }, audio: { @@ -382,6 +382,11 @@ namespace phasereditor2d.scene.ui.editor { if (file) { + if (ScenePlugin.getInstance().getSceneFinder().isScriptPrefabFile(file)) { + + return ScenePlugin.getInstance().getIcon(ICON_BUILD); + } + const img = SceneThumbnailCache.getInstance().getContent(file); if (img) { @@ -730,7 +735,7 @@ namespace phasereditor2d.scene.ui.editor { private async refreshSceneWithData(sceneData: json.ISceneData) { - for (const obj of this._scene.getDisplayListChildren()) { + for (const obj of this._scene.getGameObjects()) { obj.getEditorSupport().destroy(); } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditorMenuCreator.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditorMenuCreator.ts index 08cc5b732..90ad7ca40 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditorMenuCreator.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SceneEditorMenuCreator.ts @@ -27,6 +27,8 @@ namespace phasereditor2d.scene.ui.editor { menu.addMenu(this.createPrefabMenu()); + menu.addMenu(this.createScriptsMenu()); + menu.addMenu(this.createTypeMenu()); menu.addMenu(this.createOriginMenu()); @@ -52,6 +54,16 @@ namespace phasereditor2d.scene.ui.editor { menu.addMenu(this.createCompilerMenu()); } + createScriptsMenu(): controls.Menu { + + const menu = new controls.Menu("Scripts"); + + menu.addCommand(commands.CMD_OPEN_ADD_SCRIPT_DIALOG); + menu.addCommand(commands.CMD_OPEN_SCRIPT_DIALOG); + + return menu; + } + createArcadePhysicsMenu(): controls.Menu { const menu = new controls.Menu("Arcade Physics"); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SelectionManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SelectionManager.ts index 72c15a3f8..0bd3e0e49 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SelectionManager.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/SelectionManager.ts @@ -141,7 +141,7 @@ namespace phasereditor2d.scene.ui.editor { selectAll() { - const sel = this._editor.getScene().getDisplayListChildren(); + const sel = this._editor.getScene().getGameObjects(); this._editor.setSelection(sel); this._editor.repaint(); } @@ -176,7 +176,7 @@ namespace phasereditor2d.scene.ui.editor { private parentsAllowPickingChildren(obj: sceneobjects.ISceneGameObject) { - const parent = sceneobjects.getObjectParent(obj); + const parent = obj.getEditorSupport().getObjectParent(); if (parent) { @@ -200,7 +200,7 @@ namespace phasereditor2d.scene.ui.editor { } } - const parent = sceneobjects.getObjectParent(obj); + const parent = obj.getEditorSupport().getObjectParent(); return this.findPickableObject(parent); } @@ -227,7 +227,7 @@ namespace phasereditor2d.scene.ui.editor { if (selected) { - const objParent = sceneobjects.getObjectParent(selected); + const objParent = selected.getEditorSupport().getObjectParent(); if (objParent) { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/commands/SceneEditorCommands.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/commands/SceneEditorCommands.ts index 3d6033096..2b6178818 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/commands/SceneEditorCommands.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/commands/SceneEditorCommands.ts @@ -22,6 +22,7 @@ namespace phasereditor2d.scene.ui.editor.commands { export const CMD_SCALE_SCENE_OBJECT = "phasereditor2d.scene.ui.editor.commands.ScaleSceneObject"; export const CMD_EDIT_POLYGON_OBJECT = "phasereditor2d.scene.ui.editor.commands.EditPolygonObject"; export const CMD_RESIZE_SCENE_OBJECT = "phasereditor2d.scene.ui.editor.commands.ResizeSceneObject"; + export const CMD_EDIT_SLICE_SCENE_OBJECT = "phasereditor2d.scene.ui.editor.commands.EditSliceSceneObject"; export const CMD_EDIT_ARCADE_BODY = "phasereditor2d.scene.ui.editor.commands.EditArcadeBody"; export const CMD_SELECT_REGION = "phasereditor2d.scene.ui.editor.commands.SelectRegion"; export const CMD_PAN_SCENE = "phasereditor2d.scene.ui.editor.commands.PanScene"; @@ -48,11 +49,15 @@ namespace phasereditor2d.scene.ui.editor.commands { export const CMD_DISABLE_AWAKE_EVENT_PREFABS = "phasereditor2d.scene.ui.editor.commands.DisableAwakeEventPrefabs"; export const CMD_SET_DEFAULT_RENDER_TYPE_TO_CANVAS = "phasereditor2d.scene.ui.editor.commands.SetDefaultRenderTypeToCanvas"; export const CMD_SET_DEFAULT_RENDER_TYPE_TO_WEBGL = "phasereditor2d.scene.ui.editor.commands.SetDefaultRenderTypeToWebGL"; + export const CMD_ENABLE_PIXEL_ART_RENDERING = "phasereditor2d.scene.ui.editor.commands.EnablePixelArtRendering"; + export const CMD_DISABLE_PIXEL_ART_RENDERING = "phasereditor2d.scene.ui.editor.commands.DisablePixelArtRendering"; export const CMD_PASTE_IN_PLACE = "phasereditor2d.scene.ui.editor.commands.PasteInPlace"; export const CMD_ARCADE_ENABLE_BODY = "phasereditor2d.scene.ui.editor.commands.ArcadeEnableBody"; export const CMD_ARCADE_DISABLE_BODY = "phasereditor2d.scene.ui.editor.commands.ArcadeDisableBody"; export const CMD_ARCADE_CENTER_BODY = "phasereditor2d.scene.ui.editor.commands.ArcadeCenterBody"; export const CMD_ARCADE_RESIZE_TO_OBJECT_BODY = "phasereditor2d.scene.ui.editor.commands.ArcadeResizeBodyToObject"; + export const CMD_OPEN_SCRIPT_DIALOG = "phasereditor2d.scene.ui.editor.commands.OpenScriptDialog"; + export const CMD_OPEN_ADD_SCRIPT_DIALOG = "phasereditor2d.scene.ui.editor.commands.OpenAddScriptDialog"; function isSceneScope(args: colibri.ui.ide.commands.HandlerArgs) { @@ -142,6 +147,52 @@ namespace phasereditor2d.scene.ui.editor.commands { this.registerSnappingCommands(manager); this.registerArcadeCommands(manager); + + this.registerScriptNodeCommands(manager); + } + + private static registerScriptNodeCommands(manager: colibri.ui.ide.commands.CommandManager) { + + manager.add({ + command: { + id: CMD_OPEN_SCRIPT_DIALOG, + category: CAT_SCENE_EDITOR, + name: "Browse Scripts", + tooltip: "Opens the Browse Scripts dialog", + }, + handler: { + testFunc: isSceneScope, + executeFunc: args => { + + const dlg = new sceneobjects.BrowseScriptsDialog(args.activeEditor as SceneEditor); + dlg.create(); + } + }, + keys: { + key: "KeyU", + shift: true + } + }); + + manager.add({ + command: { + id: CMD_OPEN_ADD_SCRIPT_DIALOG, + category: CAT_SCENE_EDITOR, + name: "Add Script", + tooltip: "Opens the Add Script Dialog", + }, + handler: { + testFunc: isSceneScope, + executeFunc: args => { + + const dlg = new sceneobjects.AddScriptDialog(args.activeEditor as SceneEditor); + dlg.create(); + } + }, + keys: { + key: "KeyU", + } + }); } private static registerArcadeCommands(manager: colibri.ui.ide.commands.CommandManager) { @@ -171,6 +222,11 @@ namespace phasereditor2d.scene.ui.editor.commands { const objES = obj.getEditorSupport(); + if (!objES.isDisplayObject()) { + + return false; + } + if (objES.hasComponent(ui.sceneobjects.ArcadeComponent)) { return false; @@ -425,6 +481,40 @@ namespace phasereditor2d.scene.ui.editor.commands { } }); + // enable pixel art rendering + + manager.add({ + command: { + id: CMD_ENABLE_PIXEL_ART_RENDERING, + name: "Enable Pixel Art Rendering", + category: CAT_SCENE_EDITOR, + tooltip: "Enable pixel-art rendering in the scenes" + }, + handler: { + testFunc: phasereditor2d.ide.ui.actions.isNotWelcomeWindowScope, + executeFunc: args => { + + ScenePlugin.getInstance().setDefaultRenderPixelArt(true); + } + } + }); + + manager.add({ + command: { + id: CMD_DISABLE_PIXEL_ART_RENDERING, + name: "Disable Pixel Art Rendering", + category: CAT_SCENE_EDITOR, + tooltip: "Disable pixel-art rendering in the scenes" + }, + handler: { + testFunc: phasereditor2d.ide.ui.actions.isNotWelcomeWindowScope, + executeFunc: args => { + + ScenePlugin.getInstance().setDefaultRenderPixelArt(false); + } + } + }); + // fix scene id manager.add({ @@ -1039,9 +1129,14 @@ namespace phasereditor2d.scene.ui.editor.commands { for (const obj of editor.getSelectedGameObjects()) { - const editorSupport = obj.getEditorSupport(); + const objES = obj.getEditorSupport(); - if (editorSupport.isNestedPrefabInstance()) { + if (!objES.isDisplayObject()) { + + return false; + } + + if (objES.isNestedPrefabInstance()) { return false; } @@ -1087,7 +1182,14 @@ namespace phasereditor2d.scene.ui.editor.commands { for (const obj of editor.getSelectedGameObjects()) { - if (obj.getEditorSupport().isNestedPrefabInstance()) { + const objES = obj.getEditorSupport(); + + if (!objES.isDisplayObject()) { + + return false; + } + + if (objES.isNestedPrefabInstance()) { return false; } @@ -1183,7 +1285,7 @@ namespace phasereditor2d.scene.ui.editor.commands { .getSelectedGameObjects() - .map(obj => sceneobjects.getObjectParent(obj)) + .map(obj => obj.getEditorSupport().getObjectParent()) .filter(parent => parent !== undefined && parent !== null) @@ -1195,7 +1297,7 @@ namespace phasereditor2d.scene.ui.editor.commands { const sel = editor.getSelectedGameObjects() - .map(obj => sceneobjects.getObjectParent(obj)) + .map(obj => obj.getEditorSupport().getObjectParent()) .filter(parent => parent !== undefined && parent !== null); @@ -1239,7 +1341,9 @@ namespace phasereditor2d.scene.ui.editor.commands { const sel = editor.getSelection() - .flatMap(obj => sceneobjects.GameObjectEditorSupport.getObjectChildren(obj)) + .filter(obj => sceneobjects.isGameObject(obj)) + + .flatMap((obj: sceneobjects.ISceneGameObject) => obj.getEditorSupport().getObjectChildren()) .filter(obj => { @@ -1745,6 +1849,20 @@ namespace phasereditor2d.scene.ui.editor.commands { key: "KeyB" } }); + + manager.add({ + command: { + id: CMD_EDIT_SLICE_SCENE_OBJECT, + name: "Slice Tool", + tooltip: "Edit selected slice objects.", + category: CAT_SCENE_EDITOR + }, + handler: { + testFunc: isSceneScope, + executeFunc: args => (args.activeEditor as SceneEditor) + .getToolsManager().swapTool(ui.sceneobjects.SliceTool.ID) + } + }); } private static registerVisibilityCommands(manager: colibri.ui.ide.commands.CommandManager) { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineContentProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineContentProvider.ts index 71035c1b8..0bab7dcf3 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineContentProvider.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineContentProvider.ts @@ -4,7 +4,7 @@ namespace phasereditor2d.scene.ui.editor.outline { export class SceneEditorOutlineContentProvider implements controls.viewers.ITreeContentProvider { - private _editor: SceneEditor; + protected _editor: SceneEditor; constructor(editor: SceneEditor) { @@ -29,9 +29,18 @@ namespace phasereditor2d.scene.ui.editor.outline { roots.push(displayList); } - roots.push(scene.getObjectLists()); + if (scene.getObjectLists().getLists().length > 0) { - roots.push(...ScenePlugin.getInstance().getPlainObjectCategories()); + roots.push(scene.getObjectLists()); + } + + if (!scene.isScriptNodePrefabScene()) { + + roots.push(...ScenePlugin.getInstance().getPlainObjectCategories().filter(cat => { + + return this.getChildren(cat).length > 0; + })); + } if (scene.isPrefabSceneType()) { @@ -41,7 +50,7 @@ namespace phasereditor2d.scene.ui.editor.outline { return roots; } - getChildren(parent: sceneobjects.ISceneGameObject): any[] { + getChildren(parent: any): any[] { if (parent instanceof sceneobjects.PrefabUserProperties) { @@ -50,42 +59,39 @@ namespace phasereditor2d.scene.ui.editor.outline { if (sceneobjects.GameObjectEditorSupport.hasEditorSupport(parent)) { - let list = []; + const parentObj = parent as sceneobjects.ISceneGameObject; - if (parent instanceof sceneobjects.Container || parent instanceof sceneobjects.Layer) { + let list = []; - const parentES = parent.getEditorSupport(); + const parentES = parentObj.getEditorSupport(); - if (!parentES.isShowChildrenInOutline()) { + if (!parentES.isShowChildrenInOutline()) { - list = []; + list = []; - } else if (parentES.isPrefabInstance()) { + } else if (parentES.isPrefabInstance()) { - const prefabChildren = parentES.getMutableNestedPrefabChildren(); + const prefabChildren = parentES.getMutableNestedPrefabChildren(); - const appendedChildren = parentES.getAppendedChildren(); + const appendedChildren = parentES.getAppendedChildren(); - list = [...prefabChildren, ...appendedChildren]; + list = [...prefabChildren.reverse(), ...appendedChildren.reverse()]; - } else { + } else { - list = [...parent.getChildren()]; + list = [...parentES.getObjectChildren()]; - list.reverse(); - } + list.reverse(); } // prepend the user components - const parentES = sceneobjects.GameObjectEditorSupport.getEditorSupport(parent); - - const nodes = parentES + const compNodes = parentES .getUserComponentsComponent() .getUserComponentNodes() .filter(n => n.isPublished()); - list = [...nodes, ...list]; + list = [...compNodes, ...list]; return list; } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineStyledLabelProvider.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineStyledLabelProvider.ts index 79d1f1ced..dc8eacc87 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineStyledLabelProvider.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/outline/SceneEditorOutlineStyledLabelProvider.ts @@ -27,7 +27,7 @@ namespace phasereditor2d.scene.ui.editor.outline { } else if (obj instanceof Phaser.GameObjects.DisplayList) { - return "Display List"; + return "Scene"; } else if (obj instanceof sceneobjects.ObjectLists) { @@ -67,6 +67,8 @@ namespace phasereditor2d.scene.ui.editor.outline { const theme = controls.Controls.getTheme(); + let color = theme.viewerForeground; + const baseLabel = this.getLabel(obj); let hintText = ""; @@ -77,6 +79,15 @@ namespace phasereditor2d.scene.ui.editor.outline { hintText += ` (comp ← ${obj.getPrefabFile().getNameWithoutExtension()})`; + if (obj.getObject().getEditorSupport().isMutableNestedPrefabInstance()) { + + color = ScenePlugin.getInstance().getNestedPrefabColor(); + + } else { + + color = ScenePlugin.getInstance().getPrefabColor(); + } + } else { hintText += " (comp)"; @@ -99,11 +110,15 @@ namespace phasereditor2d.scene.ui.editor.outline { if (support.isMutableNestedPrefabInstance()) { - hintText += "(nested)"; + hintText += "- nested prefab"; + + color = ScenePlugin.getInstance().getNestedPrefabColor(); } else if (support.isPrefabInstance()) { - hintText += "(prefab)" + hintText += "- prefab" + + color = ScenePlugin.getInstance().getPrefabColor(); } } @@ -119,7 +134,7 @@ namespace phasereditor2d.scene.ui.editor.outline { return [ { text: baseLabel, - color: theme.viewerForeground + color }, { text: " " + hintText, diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneTool.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneTool.ts index beb5b36a5..6c2ec2c1a 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneTool.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneTool.ts @@ -78,6 +78,11 @@ namespace phasereditor2d.scene.ui.editor.tools { abstract canRender(obj: unknown): boolean; + isValidForAll(objects: ISceneObject[]) { + + return true; + } + requiresRepaintOnMouseMove() { return false; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneToolItem.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneToolItem.ts index 45821a1ef..943981de6 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneToolItem.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneToolItem.ts @@ -198,6 +198,39 @@ namespace phasereditor2d.scene.ui.editor.tools { return a; } + protected drawLinePath(ctx: CanvasRenderingContext2D, color: string, x1: number, y1: number, x2: number, y2: number, dashed = false) { + + ctx.save(); + + if (dashed) { + + ctx.setLineDash([5, 10]); + ctx.lineCap = "square"; + } + + ctx.strokeStyle = "#000"; + ctx.lineWidth = 1.5; + + ctx.beginPath(); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); + ctx.closePath(); + ctx.stroke(); + + ctx.strokeStyle = color; + ctx.lineWidth = 1; + + ctx.beginPath(); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); + ctx.closePath(); + ctx.stroke(); + + ctx.restore(); + } + protected drawArrowPath(ctx: CanvasRenderingContext2D, color: string) { ctx.save(); @@ -262,8 +295,8 @@ namespace phasereditor2d.scene.ui.editor.tools { protected getAvgScreenPointOfObjects( args: ISceneToolContextArgs, - fx: (ob: sceneobjects.Image) => number = obj => 0, - fy: (ob: sceneobjects.Image) => number = obj => 0, + fx: (ob: sceneobjects.Image | any) => number = obj => 0, + fy: (ob: sceneobjects.Image | any) => number = obj => 0, removeRotation = false) { let avgY = 0; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneToolsManager.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneToolsManager.ts index a54a69d4d..c3336f32d 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneToolsManager.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/tools/SceneToolsManager.ts @@ -51,9 +51,24 @@ namespace phasereditor2d.scene.ui.editor.tools { } getActiveTool() { + return this._activeTool; } + activateTool(toolId: string) { + + const tool = this.findTool(toolId); + + if (tool) { + + this.setActiveTool(tool); + + } else { + + console.error(`Tool not found ${toolId}`); + } + } + setActiveTool(tool: SceneTool) { const args = this.createToolArgs(); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/CreateObjectWithAssetOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/CreateObjectWithAssetOperation.ts index 2fbe45d06..1e493c757 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/CreateObjectWithAssetOperation.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/CreateObjectWithAssetOperation.ts @@ -7,7 +7,7 @@ namespace phasereditor2d.scene.ui.editor.undo { private _offsetY: number; private _data: any[]; - constructor(editor: SceneEditor, data: any[], offsetX: number, offsetY: number) { + constructor(editor: SceneEditor, data: any[], offsetX = 0, offsetY = 0) { super(editor); this._offsetX = offsetX; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/DepthOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/DepthOperation.ts index a669b13b5..f6c3d1173 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/DepthOperation.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/DepthOperation.ts @@ -14,20 +14,21 @@ namespace phasereditor2d.scene.ui.editor.undo { static allow(editor: SceneEditor, move: DepthMove) { - const sel = this.sortedSelection(editor); + let sel = this.sortedSelection(editor); for (const obj of sel) { - const parent = sceneobjects.getObjectParentOrDisplayList(obj); + const parent = obj.getEditorSupport().getObjectParent(); + const siblings =obj.getEditorSupport().getObjectSiblings(); - const index = parent.getIndex(obj); + const index = siblings.indexOf(obj); let bottomIndex = 0; - const len = parent.list.length; + const len = siblings.length; - if (parent instanceof Phaser.GameObjects.GameObject) { + if (sceneobjects.isGameObject(parent)) { - const parentES: sceneobjects.ParentGameObjectEditorSupport + const parentES: sceneobjects.DisplayParentGameObjectEditorSupport = (parent as sceneobjects.ISceneGameObject).getEditorSupport() as any; bottomIndex = parentES.getCountPrefabChildren(); @@ -58,11 +59,11 @@ namespace phasereditor2d.scene.ui.editor.undo { sel.sort((a, b) => { - const aParent = sceneobjects.getObjectParentOrDisplayList(a); - const bParent = sceneobjects.getObjectParentOrDisplayList(a); + const aParent = a.getEditorSupport().getObjectSiblings(); + const bParent = b.getEditorSupport().getObjectSiblings(); - const aa = aParent.getIndex(a); - const bb = bParent.getIndex(b); + const aa = aParent.indexOf(a); + const bb = bParent.indexOf(b); return aa - bb; }); @@ -80,7 +81,9 @@ namespace phasereditor2d.scene.ui.editor.undo { for (const obj of sel) { - sceneobjects.getObjectParentOrDisplayList(obj).bringToTop(obj); + const siblings = obj.getEditorSupport().getObjectSiblings(); + + Phaser.Utils.Array.BringToTop(siblings, obj); } break; @@ -90,12 +93,14 @@ namespace phasereditor2d.scene.ui.editor.undo { for (let i = 0; i < sel.length; i++) { const obj = sel[sel.length - i - 1]; + const objES = obj.getEditorSupport(); - const parent = sceneobjects.getObjectParentOrDisplayList(obj); + const parent = objES.getObjectParent(); + const siblings = objES.getObjectSiblings(); let bottomIndex = 0; - if (sceneobjects.isGameObject(parent)) { + if (parent && sceneobjects.isGameObject(parent)) { const parentES = (parent as sceneobjects.Container).getEditorSupport(); @@ -104,15 +109,15 @@ namespace phasereditor2d.scene.ui.editor.undo { if (bottomIndex === 0) { - parent.sendToBack(obj); + Phaser.Utils.Array.SendToBack(siblings, obj) } else { - let i = parent.getIndex(obj); + let i = siblings.indexOf(obj); for(; i > bottomIndex; i--) { - parent.moveDown(obj); + Phaser.Utils.Array.MoveDown(siblings, obj); } } } @@ -125,7 +130,9 @@ namespace phasereditor2d.scene.ui.editor.undo { const obj = sel[sel.length - i - 1]; - sceneobjects.getObjectParentOrDisplayList(obj).moveUp(obj); + const siblings = obj.getEditorSupport().getObjectSiblings(); + + Phaser.Utils.Array.MoveUp(siblings, obj); } break; @@ -134,12 +141,16 @@ namespace phasereditor2d.scene.ui.editor.undo { for (const obj of sel) { - sceneobjects.getObjectParentOrDisplayList(obj).moveDown(obj); + const siblings = obj.getEditorSupport().getObjectSiblings(); + + Phaser.Utils.Array.MoveDown(siblings, obj); } break; } + sceneobjects.sortGameObjects(sel); + this.getEditor().repaint(); } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/ObjectSnapshotOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/ObjectSnapshotOperation.ts index 2bd58c43a..6b5a316cd 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/ObjectSnapshotOperation.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/ObjectSnapshotOperation.ts @@ -52,8 +52,8 @@ namespace phasereditor2d.scene.ui.editor.undo { let parentId: string; - const parent = sceneobjects.getObjectParent(obj); - + const parent = obj.getEditorSupport().getObjectParent(); + if (parent) { parentId = parent.getEditorSupport().getId(); @@ -94,7 +94,7 @@ namespace phasereditor2d.scene.ui.editor.undo { if (newObj) { - scene.sys.displayList.remove(newObj); + scene.removeGameObject(newObj); if (objSnapshot.parentId) { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/SceneSnapshotOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/SceneSnapshotOperation.ts index 0cff6c3fa..724a3db36 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/SceneSnapshotOperation.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/editor/undo/SceneSnapshotOperation.ts @@ -51,7 +51,7 @@ namespace phasereditor2d.scene.ui.editor.undo { return { - displayList: scene.getDisplayListChildren().map(obj => { + displayList: scene.getGameObjects().map(obj => { const data = {} as any; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ChildrenComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ChildrenComponent.ts index 4fe11a622..a679d749e 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ChildrenComponent.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ChildrenComponent.ts @@ -1,7 +1,7 @@ /// namespace phasereditor2d.scene.ui.sceneobjects { - export class ChildrenComponent extends Component { + export class ChildrenComponent extends Component { static allowPickChildren: IProperty = { name: "allowPickChildren", @@ -33,7 +33,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { setValue: (obj, value) => obj.getEditorSupport().setAllowAppendChildren(value) }; - constructor(obj: Container | Layer) { + constructor(obj: Container | Layer | ScriptNode) { super(obj, [ ChildrenComponent.allowPickChildren, ChildrenComponent.showChildrenInOutline, diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Component.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Component.ts index 4790f19ad..b84e67bc4 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Component.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Component.ts @@ -21,8 +21,8 @@ namespace phasereditor2d.scene.ui.sceneobjects { } export abstract class Component implements core.json.ISerializable { - - + + private _obj: T; private _properties: Set>; private _active: boolean; @@ -157,29 +157,35 @@ namespace phasereditor2d.scene.ui.sceneobjects { buildSetObjectPropertyCodeDOM( properties: Array>, - codeDomBuilder: (builderArgs: { prop: IProperty, fieldCodeName: string, value: any }) => void) { + codeDomBuilder: (builderArgs: { prop: IProperty, fieldCodeName: string, value: any }) => void, + onPropertyIgnored?: (builderArgs: { prop: IProperty, fieldCodeName: string, value: any }) => void) { + + const objES = this.getEditorSupport(); for (const prop of properties) { const fieldCodeName = prop.codeName ?? prop.name; const value = prop.getValue(this.getObject()); + const builderArgs = { prop, fieldCodeName, value }; let local = true; + let skip = true; - if (this.getEditorSupport().isPrefabInstance()) { + if (objES.isPrefabInstance()) { local = false; if (prop instanceof UserComponentPropertyWrapper) { - local = this.getEditorSupport().isLocalUserProperty(prop); + local = objES.isLocalUserProperty(prop); } if (!local) { - if (this.getEditorSupport().isUnlockedProperty(prop)) { + if (objES.isUnlockedProperty(prop)) { - codeDomBuilder({ prop, fieldCodeName, value }); + skip = false; + codeDomBuilder(builderArgs); } } } @@ -190,9 +196,15 @@ namespace phasereditor2d.scene.ui.sceneobjects { if (value !== defValue) { - codeDomBuilder({ prop, fieldCodeName, value }); + skip = false; + codeDomBuilder(builderArgs); } } + + if (skip && onPropertyIgnored) { + + onPropertyIgnored(builderArgs); + } } } @@ -255,11 +267,45 @@ namespace phasereditor2d.scene.ui.sceneobjects { }); } - /** - * Build extra typescript definitions at the top of the file. - * - * @param args This method args. - */ + buildSetObjectPropertiesWithMethodCodeDOM_FloatProperty( + args: ISetObjectPropertiesCodeDOMArgs, + methodName: string, + ...properties: Array>) { + + const values: string[] = []; + const generateCode = { yes: false }; + + this.buildSetObjectPropertyCodeDOM(properties, args2 => { + + const codeValue = args2.prop.valueToCodeConverter ? args2.prop.valueToCodeConverter(args2.value) : args2.value; + + values.push(codeValue); + + generateCode.yes = true; + + }, args2 => { + + values.push(`${args.objectVarName}.${args2.fieldCodeName}`); + }); + + if (generateCode.yes) { + + const dom = new code.MethodCallCodeDOM(methodName, args.objectVarName); + + for (const value of values) { + + dom.arg(value); + } + + args.statements.push(dom); + } + } + + /** + * Build extra typescript definitions at the top of the file. + * + * @param args This method args. + */ buildPrefabTypeScriptDefinitionsCodeDOM(args: IBuildPrefabExtraTypeScriptDefinitionsCodeDOMArgs) { // nothing by default } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/DisplayParentGameObjectEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/DisplayParentGameObjectEditorSupport.ts new file mode 100644 index 000000000..ab5267200 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/DisplayParentGameObjectEditorSupport.ts @@ -0,0 +1,35 @@ +/// +namespace phasereditor2d.scene.ui.sceneobjects { + + import controls = colibri.ui.controls; + + export abstract class DisplayParentGameObjectEditorSupport + extends GameObjectEditorSupport { + + getCellRenderer(): colibri.ui.controls.viewers.ICellRenderer { + + if (this.isPrefabInstance() && !this.isNestedPrefabInstance()) { + + const finder = ScenePlugin.getInstance().getSceneFinder(); + + const file = finder.getPrefabFile(this.getPrefabId()); + + if (file) { + + const image = SceneThumbnailCache.getInstance().getContent(file); + + if (image) { + + return new controls.viewers.ImageCellRenderer(image); + } + } + } + + return new controls.viewers.IconImageCellRenderer(ScenePlugin.getInstance().getIcon(ICON_GROUP)); + } + + setInteractive() { + // nothing + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/GameObjectEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/GameObjectEditorSupport.ts index a89226fe5..1ee9fb474 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/GameObjectEditorSupport.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/GameObjectEditorSupport.ts @@ -1,49 +1,8 @@ +/// namespace phasereditor2d.scene.ui.sceneobjects { import json = core.json; - export function isNestedPrefabInstance(obj: any) { - - const support = GameObjectEditorSupport.getEditorSupport(obj); - - if (support) { - - return support.isNestedPrefabInstance(); - } - - return false; - } - - export function isGameObject(obj: any) { - - return GameObjectEditorSupport.hasEditorSupport(obj); - } - - export function isGameObjectParent(obj: any) { - - return obj instanceof Container || obj instanceof Layer; - } - - export function getObjectChildren(obj: ISceneGameObject) { - - if (obj instanceof Layer || obj instanceof Container) { - - return obj.getChildren(); - } - - return []; - } - - export function getObjectParent(obj: ISceneGameObject) { - - return GameObjectEditorSupport.getObjectParent(obj); - } - - export function getObjectParentOrDisplayList(obj: ISceneGameObject) { - - return getObjectParent(obj) || obj.getEditorSupport().getScene().sys.displayList; - } - export abstract class GameObjectEditorSupport extends EditorSupport { private _extension: SceneGameObjectExtension; @@ -54,6 +13,14 @@ namespace phasereditor2d.scene.ui.sceneobjects { private _unlockedProperties: Set; private _isNestedPrefabInstance: boolean; + // parent + private _allowPickChildren: boolean; + private _showChildrenInOutline: boolean; + private _countPrefabChildren: number; + private _allowAppendChildren: boolean; + + private _objectChildren: ISceneGameObject[]; + constructor(extension: SceneGameObjectExtension, obj: T, scene: Scene) { super(obj, extension.getTypeName().toLowerCase(), scene); @@ -63,6 +30,13 @@ namespace phasereditor2d.scene.ui.sceneobjects { this._componentMap = new Map(); this._isNestedPrefabInstance = false; + this._allowPickChildren = true; + this._showChildrenInOutline = true; + this._countPrefabChildren = 0; + this._allowAppendChildren = false; + + this._objectChildren = []; + obj.setDataEnabled(); this.setId(Phaser.Utils.String.UUID()); @@ -73,44 +47,150 @@ namespace phasereditor2d.scene.ui.sceneobjects { this.setInteractive(); - scene.sys.displayList.add(obj as Phaser.GameObjects.GameObject); + scene.addGameObject(obj); } - static isParentObject(obj: ISceneGameObject) { + static isDisplayObjectType(type: string) { - return obj instanceof Layer || obj instanceof Container; + return type !== ScriptNodeExtension.getInstance().getTypeName(); } - static getObjectParent(obj: ISceneGameObject): Container | Layer { + isDisplayObject() { - if (obj.parentContainer) { + return true; + } - return obj.parentContainer as Container; + addObjectChild(child: ISceneGameObject): void { + + const obj = this.getObject(); + + if (obj instanceof Layer || obj instanceof Container) { + + obj.add(child); + + } else { + + this._objectChildren.push(child); } - if (obj.displayList instanceof Layer) { + if (child instanceof ScriptNode) { - return obj.displayList; + child.removeFromParent(); + + child.setParent(obj); } + } - return null; + removeObjectChild(child: ISceneGameObject): void { + + const obj = this.getObject(); + + if (obj instanceof Layer || obj instanceof Container) { + + obj.remove(child); + + } else { + + const i = this._objectChildren.indexOf(child); + + if (i >= 0) { + + this._objectChildren.splice(i, 1); + } + } + + if (child instanceof ScriptNode) { + + child.setParent(undefined); + } + } + + removeAllObjectChildren() { + + const obj = this.getObject(); + + if (obj instanceof Layer || obj instanceof Container) { + + return obj.removeAll(true); + + } else { + + this._objectChildren = []; + } + } + + getDisplayObjectChildren() { + + return this.getObjectChildren() + .filter(obj => obj.getEditorSupport().isDisplayObject()); } - static getObjectChildren(obj: ISceneGameObject): ISceneGameObject[] { + getObjectScriptNodes() { - if (obj instanceof Container - || obj instanceof Layer - || obj instanceof Phaser.GameObjects.DisplayList) { + return this.getObjectChildren().filter(o => o instanceof ScriptNode); + } + + getEditableObjectChildren() { + + if (this.isPrefabInstance()) { + + return this.getAppendedChildren(); + } + + return this.getObjectChildren(); + } + + getObjectChildren(): ISceneGameObject[] { + + const obj = this.getObject(); + + if (obj instanceof Layer) { + + return obj.getChildren() as T[]; + } + + if (obj instanceof Container) { return obj.list as ISceneGameObject[]; } - return []; + return this._objectChildren; } - getChildren() { + getObjectSiblings() { + + const parent = this.getObjectParent(); + + if (parent) { - return GameObjectEditorSupport.getObjectChildren(this.getObject()); + return parent.getEditorSupport().getObjectChildren(); + } + + return this.getScene().getGameObjects(); + } + + sortObjectChildren() { + + const children = this.getObjectChildren(); + + sortObjectsAlgorithm(children, this._countPrefabChildren); + } + + getObjectParent(): ISceneGameObject | undefined { + + const obj = this.getObject(); + + if (obj.parentContainer) { + + return obj.parentContainer as Container; + } + + if (obj.displayList instanceof Layer) { + + return obj.displayList; + } + + return undefined; } abstract setInteractive(): void; @@ -132,25 +212,48 @@ namespace phasereditor2d.scene.ui.sceneobjects { */ destroy(): boolean | void { - const obj = this.getObject() as Phaser.GameObjects.GameObject; + for (const obj of this.getObjectChildren()) { + + obj.getEditorSupport().destroy(); + } + + if (this.isDisplayObject()) { + + const obj = this.getObject() as Phaser.GameObjects.GameObject; + + obj.disableInteractive(); + + obj.destroy(); + + obj.active = false; - obj.disableInteractive(); + (obj as unknown as Phaser.GameObjects.Components.Visible).visible = false; - obj.destroy(); + // hack, to remove the object from the input list - obj.active = false; + const list = this.getScene().input["_list"] as any[]; - (obj as unknown as Phaser.GameObjects.Components.Visible).visible = false; + const i = list.indexOf(obj); - // hack, to remove the object from the input list + if (i > 0) { - const list = this.getScene().input["_list"] as any[]; + list.splice(i, 1); + } + + } else { + + const obj = this.getObject(); + + const parent = this.getObjectParent(); + + if (parent) { - const i = list.indexOf(obj); + parent.getEditorSupport().removeObjectChild(obj); - if (i > 0) { + } else { - list.splice(i, 1); + this.getScene().removeGameObject(obj); + } } return false; @@ -277,6 +380,14 @@ namespace phasereditor2d.scene.ui.sceneobjects { comp.buildDependenciesHash(args); } + + if (!this.isPrefabInstance()) { + + for (const obj of this.getObjectChildren()) { + + obj.getEditorSupport().buildDependencyHash(args); + } + } } getScreenBounds(camera: Phaser.Cameras.Scene2D.Camera) { @@ -483,7 +594,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { getParentId(): string { - const parent = GameObjectEditorSupport.getObjectParent(this.getObject()); + const parent = this.getObjectParent(); if (parent) { @@ -504,34 +615,23 @@ namespace phasereditor2d.scene.ui.sceneobjects { if (this.isNestedPrefabInstance()) { - const parentSupport = (getObjectParent(this.getObject()) as ISceneGameObject) - .getEditorSupport(); + const parent = this.getObjectParent(); + const parentES = parent.getEditorSupport(); - return parentSupport.isMutableNestedPrefabInstance() - || parentSupport.isPrefabInstanceRoot(); + return parentES.isMutableNestedPrefabInstance() + || parentES.isPrefabInstanceRoot(); } return false; } - /** - * If it is a prefab instance that was first defined as root prefab. - * It maybe pointing to a nested prefab, but it then will point to a root prefab. - * - * @returns If it is. - */ - isRootPrefabDefined() { - - return this.isPrefabInstance() && !this.isNestedPrefabDefined(); - } - /** * If it's first definition as prefab is a nested prefab. * It means, in any case, it isn't an instance of a root prefab. * * @returns Is it defined as nested prefab? */ - private isNestedPrefabDefined() { + public isNestedPrefabDefined() { const finder = ScenePlugin.getInstance().getSceneFinder(); @@ -557,9 +657,12 @@ namespace phasereditor2d.scene.ui.sceneobjects { if (this.isPrefabInstance() && !this.isNestedPrefabInstance()) { - const parent = getObjectParent(this.getObject()); + const parent = this.getObjectParent(); + const parentES = parent?.getEditorSupport(); - if (!parent || !parent.getEditorSupport().isPrefabInstance()) { + if (!parent + || !parentES.isPrefabInstance() + || this.isPrefeabInstanceAppendedChild()) { return true; } @@ -585,15 +688,15 @@ namespace phasereditor2d.scene.ui.sceneobjects { isPrefeabInstanceAppendedChild() { - const parent = GameObjectEditorSupport.getObjectParent(this.getObject()); + const parent = this.getObjectParent(); if (parent && parent.getEditorSupport().isPrefabInstance()) { - const parentSupport = (parent.getEditorSupport() as ParentGameObjectEditorSupport); + const parentES = (parent.getEditorSupport() as DisplayParentGameObjectEditorSupport); - const countPrefabChildren = parentSupport.getCountPrefabChildren(); + const countPrefabChildren = parentES.getCountPrefabChildren(); - const index = parent.getChildren().indexOf(this.getObject()); + const index = parentES.getObjectChildren().indexOf(this.getObject()); return index >= countPrefabChildren; } @@ -620,13 +723,28 @@ namespace phasereditor2d.scene.ui.sceneobjects { getAllParents() { - const list: Array = []; + const list: Array = []; this.getAllParents2(this.getObject(), list); return list; } + /** + * If this object type has a custom method for setting the size of the object. + * + * @returns Generate a custom code for setting the size properties. + */ + isCustom_SizeComponent_buildSetObjectPropertiesCodeDOM() { + + return false; + } + + /** + * Get the size properties for this object type. By default it uses the properties from the SizeComponent. + * + * @returns The size properties. + */ getSizeProperties() { if (this.hasComponent(SizeComponent)) { @@ -637,11 +755,33 @@ namespace phasereditor2d.scene.ui.sceneobjects { return []; } + /** + * The section ID for the size properties of this object type. By default it retures the SizeSection ID. + * + * @returns The size section id. + */ getSizeSectionId() { return SizeSection.SECTION_ID; } + /** + * If this object type requires to update the display origin after changing the size. + * + * @returns Generate updateDisplayOrigin()? + */ + getSizeComponentGeneratesUpdateDisplayOrigin() { + + return true; + } + + /** + * This callback method is executed when the texture of this object is changed by TextureComponent. + */ + onUpdateAfterSetTexture() { + // nothing by default + } + isDescendentOf(parent: Container | Layer) { const set = new Set(this.getAllParents()); @@ -649,9 +789,9 @@ namespace phasereditor2d.scene.ui.sceneobjects { return set.has(parent); } - private getAllParents2(obj: ISceneGameObject, list: Array) { + private getAllParents2(obj: ISceneGameObject, list: Array) { - const objParent = GameObjectEditorSupport.getObjectParent(obj); + const objParent = obj.getEditorSupport().getObjectParent(); if (objParent) { @@ -672,10 +812,21 @@ namespace phasereditor2d.scene.ui.sceneobjects { if (this.isPrefabInstance()) { - const children = sceneobjects.getObjectChildren(this.getObject()); + const children = this.getObjectChildren(); - return children - .filter(obj => obj.getEditorSupport().isMutableNestedPrefabInstance()); + const result = []; + + for(const obj of children) { + + const objES = obj.getEditorSupport(); + + if (objES.isMutableNestedPrefabInstance()) { + + result.push(obj); + } + } + + return result; } return []; @@ -724,39 +875,53 @@ namespace phasereditor2d.scene.ui.sceneobjects { return null; } - getPrefabFile() { + /** + * Get the display name of the prefab. The display name of a prefab is a composition of the prefab's name and the nested prefab's name. + * If this is a nested prefab, then it may be instance of another prefab file, so it returns two prefab names. + */ + getDisplayPrefabName() { - if (this._prefabId) { + if (!this.isPrefabInstance()) { - const finder = ScenePlugin.getInstance().getSceneFinder(); + return undefined; + } - const file = finder.getPrefabFile(this._prefabId); + if (this.isNestedPrefabDefined()) { - return file; + return this.getPrefabName(); } - return null; - } - - getPrefabOrNestedPrefabFile() { + const name1 = this.getPrefabName(); const finder = ScenePlugin.getInstance().getSceneFinder(); - if (this.isNestedPrefabInstance()) { - - const originalId = finder.getOriginalPrefabId(this._prefabId); + const data = finder.getPrefabData(this.getPrefabId()); - if (finder.isNestedPrefab(originalId)) { + if (data && data.prefabId) { - return null; + const file2 = finder.getPrefabFile(data.prefabId); - } else { + if (file2) { - return finder.getPrefabFile(originalId); + return `${name1}#${file2.getNameWithoutExtension()}` } } - return this.getPrefabFile(); + return name1; + } + + getPrefabFile() { + + if (this._prefabId) { + + const finder = ScenePlugin.getInstance().getSceneFinder(); + + const file = finder.getPrefabFile(this._prefabId); + + return file; + } + + return null; } getPrefabData() { @@ -855,6 +1020,8 @@ namespace phasereditor2d.scene.ui.sceneobjects { s.writeJSON(ser); } + + this.writeJSON_children(this.getObject(), data); } readJSON(data: json.IObjectData) { @@ -870,6 +1037,357 @@ namespace phasereditor2d.scene.ui.sceneobjects { s.readJSON(ser); } + + this.readJSON_children(this.getObject(), data); + } + + // parent methods + + getCountPrefabChildren() { + + return this._countPrefabChildren; + } + + isAllowAppendChildren() { + + return this._allowAppendChildren; + } + + setAllowAppendChildren(allowAppendChild: boolean) { + + this._allowAppendChildren = allowAppendChild; + } + + isAllowPickChildren() { + + return this._allowPickChildren; + } + + setAllowPickChildren(childrenPickable: boolean) { + + this._allowPickChildren = childrenPickable; + } + + isShowChildrenInOutline() { + + return this._showChildrenInOutline; + } + + setShowChildrenInOutline(showChildrenInOutline: boolean) { + + this._showChildrenInOutline = showChildrenInOutline; + } + + getAppendedChildren() { + + const children = this.getObjectChildren(); + + const appended = children.slice(this._countPrefabChildren); + + return appended; + } + + private writeJSON_children(container: ISceneGameObject, containerData: json.IObjectData) { + + const finder = ScenePlugin.getInstance().getSceneFinder(); + + const containerES = container.getEditorSupport(); + + if (containerES.isPrefabInstance()) { + + // write nested prefabs + + containerData.nestedPrefabs = containerES.getObjectChildren() + + .filter(obj => obj.getEditorSupport().isMutableNestedPrefabInstance()) + + .filter(obj => finder.existsPrefab(obj.getEditorSupport().getPrefabId())) + + .map(obj => { + + const objData = {} as json.IObjectData; + + obj.getEditorSupport().writeJSON(objData); + + return objData as json.IObjectData; + }) + + .filter(data => + (data.nestedPrefabs ?? []).length > 0 + || (data.unlock ?? []).length > 0 + || (data.components ?? []).length > 0 + || (data.list ?? []).length > 0); + + // write appended objects + + containerData.list = containerES.getAppendedChildren().map(obj => { + + const objData = {} as json.IObjectData; + + obj.getEditorSupport().writeJSON(objData); + + return objData as json.IObjectData; + }); + + } else { + + containerData.list = containerES.getObjectChildren().map(obj => { + + const objData = {} as json.IObjectData; + + obj.getEditorSupport().writeJSON(objData); + + return objData as json.IObjectData; + }); + } + } + + private static readPrefabChildren(serializer: core.json.Serializer, list: json.IObjectData[]) { + + if (serializer.isPrefabInstance()) { + + this.readPrefabChildren(serializer.getPrefabSerializer(), list); + } + + const localList = serializer.getData()["list"] || []; + + list.push(...localList); + } + + static buildRawChildrenData(containerData: json.IObjectData) { + + const serializer = new json.Serializer(containerData); + + const isPrefabContainer = serializer.isPrefabInstance(); + + /** + * The orginal children of the container's prefab. + * It means, it doesn't include the appended children. + */ + let prefabChildren: json.IObjectData[] = []; + + /** + * All the final children to be added to the container. + */ + let children: json.IObjectData[]; + + /** + * Just the children added explicity to this container (without looking to the prefab). + */ + const localChildren = containerData.list || []; + + if (isPrefabContainer) { + + prefabChildren = []; + + this.readPrefabChildren(serializer.getPrefabSerializer(), prefabChildren); + + const updatedPrefabChildren = DisplayParentGameObjectEditorSupport + .buildUpdatedPrefabChildrenDataWithNestedPrefab(containerData, prefabChildren); + + children = [...updatedPrefabChildren, ...localChildren]; + + } else { + + // it is not a prefab, just get the local children + children = localChildren; + } + + return { prefabChildren, children }; + } + + private readJSON_children(parent: ISceneGameObject, containerData: json.IObjectData) { + + const parentES = parent.getEditorSupport(); + + const { children, prefabChildren } = DisplayParentGameObjectEditorSupport + .buildRawChildrenData(containerData); + + parentES._countPrefabChildren = prefabChildren.length; + + const maker = parentES.getScene().getMaker(); + + parent.getEditorSupport().removeAllObjectChildren(); + + let i = 0; + + for (const childData of children) { + + let initObjData: any = { + id: childData.id, + prefabId: childData.prefabId, + type: childData.type, + label: childData.label, + }; + + // This is a very very ugly solution for this issue: + // https://github.com/PhaserEditor2D/PhaserEditor2D-v3/issues/229 + // but making a bigger change in serialization at this moment could introduce a lot of bugs + // and the TilemapLayer is a unique case in Phaser & the editor. + // For example, you cannot create a prefab instance of a TilemapLayer + if (childData.type === "TilemapLayer") { + + initObjData = childData; + } + + // creates an empty object + const sprite = maker.createObject(initObjData); + + if (sprite) { + + parent.getEditorSupport().addObjectChild(sprite); + + // if it is not an appended child + if (i < prefabChildren.length) { + + const prefabData = prefabChildren[i]; + + if (prefabData.scope === sceneobjects.ObjectScope.NESTED_PREFAB) { + + sprite.getEditorSupport()._setNestedPrefabInstance(true); + } + } + + // updates the object with the final data + sprite.getEditorSupport().readJSON(childData); + } + + i++; + } + } + + /** + * Build the children data but modified by the nested prefab info. + * + * @param objData The container data + * @param originalPrefabChildren The container's prefab children + * @returns The children but modified by the nested prefabs + */ + private static buildUpdatedPrefabChildrenDataWithNestedPrefab(objData: core.json.IObjectData, originalPrefabChildren: core.json.IObjectData[]) { + + const result: json.IObjectData[] = []; + + const localNestedPrefabs = objData.nestedPrefabs ?? []; + + for (const originalChild of originalPrefabChildren) { + + if (originalChild.scope !== sceneobjects.ObjectScope.NESTED_PREFAB) { + + result.push(originalChild); + + } else { + + // find a local nested prefab + + let localNestedPrefab: json.IObjectData; + + for (const local of localNestedPrefabs) { + + const localOriginalIdOfNestedPrefab = this.findOriginalIdOfNestedPrefab(local); + + if (localOriginalIdOfNestedPrefab === originalChild.id) { + + const remoteNestedPrefab = this.findRemoteNestedPrefab(objData.prefabId, originalChild.id); + + if (remoteNestedPrefab) { + + localNestedPrefab = colibri.core.json.copy(local) as json.IObjectData; + localNestedPrefab.prefabId = remoteNestedPrefab.id; + + } else { + + localNestedPrefab = local; + } + + break; + } + } + + if (localNestedPrefab) { + + result.push(localNestedPrefab); + + } else { + + // we don't have a local prefab, find one remote and create a pointer to it + + const remoteNestedPrefab = this.findRemoteNestedPrefab(objData.prefabId, originalChild.id); + + if (remoteNestedPrefab) { + + // we found a remote nested prefab, create a link to it + + const nestedPrefab: core.json.IObjectData = { + id: Phaser.Utils.String.UUID(), + prefabId: remoteNestedPrefab.id, + label: remoteNestedPrefab.label, + }; + + result.push(nestedPrefab); + + } else { + + // ok, just create a link with the original child + + const nestedPrefab: core.json.IObjectData = { + id: Phaser.Utils.String.UUID(), + prefabId: originalChild.id, + label: originalChild.label, + }; + + result.push(nestedPrefab); + } + } + } + } + + return result; + } + + private static findRemoteNestedPrefab(parentPrefabId: string, originalNestedPrefabId: string): json.IObjectData { + + const finder = ScenePlugin.getInstance().getSceneFinder(); + + const prefabData = finder.getPrefabData(parentPrefabId); + + if (!prefabData) { + + return null; + } + + const nestedPrefab = (prefabData.nestedPrefabs ?? []).find(obj => { + + // const thisOriginalId = finder.getOriginalPrefabId(obj.prefabId); + const thisOriginalId = this.findOriginalIdOfNestedPrefab(obj); + + return thisOriginalId === originalNestedPrefabId + }); + + if (nestedPrefab) { + + return nestedPrefab; + } + + if (prefabData.prefabId) { + + return this.findRemoteNestedPrefab(prefabData.prefabId, originalNestedPrefabId); + } + + return null; + } + + private static findOriginalIdOfNestedPrefab(obj: json.IObjectData) { + + const finder = ScenePlugin.getInstance().getSceneFinder(); + + if (obj.prefabId && finder.isNestedPrefab(obj.prefabId)) { + + const prefabData = finder.getPrefabData(obj.prefabId); + + return this.findOriginalIdOfNestedPrefab(prefabData); + } + + return obj.id; } } } \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ParentGameObjectEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ParentGameObjectEditorSupport.ts deleted file mode 100644 index a2af6cd3a..000000000 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/ParentGameObjectEditorSupport.ts +++ /dev/null @@ -1,424 +0,0 @@ -namespace phasereditor2d.scene.ui.sceneobjects { - - import controls = colibri.ui.controls; - import json = core.json; - - export abstract class ParentGameObjectEditorSupport - extends GameObjectEditorSupport { - - private _allowPickChildren = true; - private _showChildrenInOutline = true; - private _countPrefabChildren = 0; - private _allowAppendChildren = false; - - getCountPrefabChildren() { - - return this._countPrefabChildren; - } - - isAllowAppendChildren() { - - return this._allowAppendChildren; - } - - setAllowAppendChildren(allowAppendChild: boolean) { - - this._allowAppendChildren = allowAppendChild; - } - - isAllowPickChildren() { - - return this._allowPickChildren; - } - - setAllowPickChildren(childrenPickable: boolean) { - - this._allowPickChildren = childrenPickable; - } - - isShowChildrenInOutline() { - - return this._showChildrenInOutline; - } - - setShowChildrenInOutline(showChildrenInOutline: boolean) { - - this._showChildrenInOutline = showChildrenInOutline; - } - - getAppendedChildren() { - - const children = this.getObject().getChildren(); - - const appended = children.slice(this._countPrefabChildren); - - return appended; - } - - setInteractive() { - // nothing - } - - destroy() { - - for (const obj of this.getObject().getChildren()) { - - obj.getEditorSupport().destroy(); - } - - super.destroy(); - } - - getCellRenderer(): colibri.ui.controls.viewers.ICellRenderer { - - if (this.isPrefabInstance() && !this.isNestedPrefabInstance()) { - - const finder = ScenePlugin.getInstance().getSceneFinder(); - - const file = finder.getPrefabFile(this.getPrefabId()); - - if (file) { - - const image = SceneThumbnailCache.getInstance().getContent(file); - - if (image) { - - return new controls.viewers.ImageCellRenderer(image); - } - } - } - - return new controls.viewers.IconImageCellRenderer(ScenePlugin.getInstance().getIcon(ICON_GROUP)); - } - - writeJSON(containerData: json.IObjectData) { - - super.writeJSON(containerData); - - this.writeJSON_children(this.getObject(), containerData); - } - - readJSON(containerData: json.IObjectData) { - - super.readJSON(containerData); - - this.readJSON_children(this.getObject(), containerData); - } - - private writeJSON_children(container: Container | Layer, containerData: json.IObjectData) { - - const finder = ScenePlugin.getInstance().getSceneFinder(); - - const support = container.getEditorSupport(); - - if (support.isPrefabInstance()) { - - // write nested prefabs - - containerData.nestedPrefabs = container.getChildren() - - .filter(obj => obj.getEditorSupport().isMutableNestedPrefabInstance()) - - .filter(obj => finder.existsPrefab(obj.getEditorSupport().getPrefabId())) - - .map(obj => { - - const objData = {} as json.IObjectData; - - obj.getEditorSupport().writeJSON(objData); - - return objData as json.IObjectData; - }) - - .filter(data => - (data.nestedPrefabs ?? []).length > 0 - || (data.unlock ?? []).length > 0 - || (data.components ?? []).length > 0 - || (data.list ?? []).length > 0); - - // write appended objects - - containerData.list = support.getAppendedChildren().map(obj => { - - const objData = {} as json.IObjectData; - - obj.getEditorSupport().writeJSON(objData); - - return objData as json.IObjectData; - }); - - } else { - - containerData.list = container.getChildren().map(obj => { - - const objData = {} as json.IObjectData; - - obj.getEditorSupport().writeJSON(objData); - - return objData as json.IObjectData; - }); - } - } - - private static readPrefabChildren(serializer: core.json.Serializer, list: json.IObjectData[]) { - - if (serializer.isPrefabInstance()) { - - this.readPrefabChildren(serializer.getPrefabSerializer(), list); - } - - const localList = serializer.getData()["list"] || []; - - list.push(...localList); - } - - static buildRawChildrenData(containerData: json.IObjectData) { - - const serializer = new json.Serializer(containerData); - - const isPrefabContainer = serializer.isPrefabInstance(); - - /** - * The orginal children of the container's prefab. - * It means, it doesn't include the appended children. - */ - let prefabChildren: json.IObjectData[] = []; - - /** - * All the final children to be added to the container. - */ - let children: json.IObjectData[]; - - /** - * Just the children added explicity to this container (without looking to the prefab). - */ - const localChildren = containerData.list || []; - - if (isPrefabContainer) { - - prefabChildren = []; - - this.readPrefabChildren(serializer.getPrefabSerializer(), prefabChildren); - - const updatedPrefabChildren = ParentGameObjectEditorSupport - .buildUpdatedPrefabChildrenDataWithNestedPrefab(containerData, prefabChildren); - - children = [...updatedPrefabChildren, ...localChildren]; - - } else { - - // it is not a prefab, just get the local children - children = localChildren; - } - - return { prefabChildren, children }; - } - - private readJSON_children(container: Container | Layer, containerData: json.IObjectData) { - - const containerSupport = container.getEditorSupport(); - - const { children, prefabChildren } = ParentGameObjectEditorSupport - .buildRawChildrenData(containerData); - - containerSupport._countPrefabChildren = prefabChildren.length; - - const maker = containerSupport.getScene().getMaker(); - - container.removeAll(true); - - let i = 0; - - for (const childData of children) { - - let initObjData: any = { - id: childData.id, - prefabId: childData.prefabId, - type: childData.type, - label: childData.label, - }; - - // This is a very very ugly solution for this issue: - // https://github.com/PhaserEditor2D/PhaserEditor2D-v3/issues/229 - // but making a bigger change in serialization at this moment could introduce a lot of bugs - // and the TilemapLayer is a unique case in Phaser & the editor. - // For example, you cannot create a prefab instance of a TilemapLayer - if (childData.type === "TilemapLayer") { - - initObjData = childData; - } - - // creates an empty object - const sprite = maker.createObject(initObjData); - - if (sprite) { - - container.add(sprite); - - // if it is not an appended child - if (i < prefabChildren.length) { - - const prefabData = prefabChildren[i]; - - if (prefabData.scope === sceneobjects.ObjectScope.NESTED_PREFAB) { - - sprite.getEditorSupport()._setNestedPrefabInstance(true); - } - } - - // updates the object with the final data - sprite.getEditorSupport().readJSON(childData); - } - - i++; - } - } - - /** - * Build the children data but modified by the nested prefab info. - * - * @param objData The container data - * @param originalPrefabChildren The container's prefab children - * @returns The children but modified by the nested prefabs - */ - static buildUpdatedPrefabChildrenDataWithNestedPrefab(objData: core.json.IObjectData, originalPrefabChildren: core.json.IObjectData[]) { - - const result: json.IObjectData[] = []; - - const localNestedPrefabs = objData.nestedPrefabs ?? []; - - for (const originalChild of originalPrefabChildren) { - - if (originalChild.scope !== sceneobjects.ObjectScope.NESTED_PREFAB) { - - result.push(originalChild); - - } else { - - // find a local nested prefab - - let localNestedPrefab: json.IObjectData; - - for (const local of localNestedPrefabs) { - - const localOriginalIdOfNestedPrefab = this.findOriginalIdOfNestedPrefab(local); - - if (localOriginalIdOfNestedPrefab === originalChild.id) { - - const remoteNestedPrefab = this.findRemoteNestedPrefab(objData.prefabId, originalChild.id); - - if (remoteNestedPrefab) { - - localNestedPrefab = colibri.core.json.copy(local) as json.IObjectData; - localNestedPrefab.prefabId = remoteNestedPrefab.id; - - } else { - - localNestedPrefab = local; - } - - break; - } - } - - if (localNestedPrefab) { - - result.push(localNestedPrefab); - - } else { - - // we don't have a local prefab, find one remote and create a pointer to it - - const remoteNestedPrefab = this.findRemoteNestedPrefab(objData.prefabId, originalChild.id); - - if (remoteNestedPrefab) { - - // we found a remote nested prefab, create a link to it - - const nestedPrefab: core.json.IObjectData = { - id: Phaser.Utils.String.UUID(), - prefabId: remoteNestedPrefab.id, - label: remoteNestedPrefab.label, - }; - - result.push(nestedPrefab); - - } else { - - // ok, just create a link with the original child - - const nestedPrefab: core.json.IObjectData = { - id: Phaser.Utils.String.UUID(), - prefabId: originalChild.id, - label: originalChild.label, - }; - - result.push(nestedPrefab); - } - } - } - } - - return result; - } - - private static findRemoteNestedPrefab(parentPrefabId: string, originalNestedPrefabId: string): json.IObjectData { - - const finder = ScenePlugin.getInstance().getSceneFinder(); - - const prefabData = finder.getPrefabData(parentPrefabId); - - if (!prefabData) { - - return null; - } - - const nestedPrefab = (prefabData.nestedPrefabs ?? []).find(obj => { - - // const thisOriginalId = finder.getOriginalPrefabId(obj.prefabId); - const thisOriginalId = this.findOriginalIdOfNestedPrefab(obj); - - return thisOriginalId === originalNestedPrefabId - }); - - if (nestedPrefab) { - - return nestedPrefab; - } - - if (prefabData.prefabId) { - - return this.findRemoteNestedPrefab(prefabData.prefabId, originalNestedPrefabId); - } - - return null; - } - - private static findOriginalIdOfNestedPrefab(obj: json.IObjectData) { - - const finder = ScenePlugin.getInstance().getSceneFinder(); - - if (obj.prefabId && finder.isNestedPrefab(obj.prefabId)) { - - const prefabData = finder.getPrefabData(obj.prefabId); - - return this.findOriginalIdOfNestedPrefab(prefabData); - } - - return obj.id; - } - - async buildDependencyHash(args: IBuildDependencyHashArgs) { - - super.buildDependencyHash(args); - - if (!this.isPrefabInstance()) { - - for (const obj of this.getObject().getChildren()) { - - obj.getEditorSupport().buildDependencyHash(args); - } - } - } - } -} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/SceneGameObjectExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/SceneGameObjectExtension.ts index 564e992f4..4b1732779 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/SceneGameObjectExtension.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/SceneGameObjectExtension.ts @@ -35,12 +35,15 @@ namespace phasereditor2d.scene.ui.sceneobjects { obj: ISceneGameObject; gameObjectFactoryExpr: string; + sceneExpr: string; + parentVarName: string; } export interface IBuildPrefabConstructorCodeDOMArgs { obj: ISceneGameObject; sceneExpr: string; + parentVarName?: string; methodCallDOM: code.MethodCallCodeDOM; prefabSerializer: json.Serializer; } @@ -49,6 +52,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { ctrDeclCodeDOM: code.MethodDeclCodeDOM; prefabObj: ISceneGameObject; + importTypes: string[]; } export interface IBuildPrefabConstructorDeclarationSupperCallCodeDOMArgs { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/SizeComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/SizeComponent.ts index 47b44990d..0e86bf468 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/SizeComponent.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/SizeComponent.ts @@ -9,11 +9,14 @@ namespace phasereditor2d.scene.ui.sceneobjects { export class SizeComponent extends Component { + static FLAG_DISABLE_GENERATE_UPDATE_DISPALY_ORIGIN = "updateDispyOrigin"; + // static width = SimpleProperty("width", 0, "Width", "The object's width.", false, updateDisplayOrigin); // static height = SimpleProperty("height", 0, "Height", "The object's height.", false, updateDisplayOrigin); static width: IProperty = { name: "width", defValue: 0, + label: "W", tooltip: "The object's width.", local: false, getValue: obj => obj.width, @@ -26,6 +29,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { static height: IProperty = { name: "height", + label: "H", defValue: 0, tooltip: "The object's height.", local: false, @@ -47,21 +51,31 @@ namespace phasereditor2d.scene.ui.sceneobjects { super(obj, [SizeComponent.width, SizeComponent.height]); } - buildSetObjectPropertiesCodeDOM(args: ISetObjectPropertiesCodeDOMArgs): void { + buildSetObjectPropertiesCodeDOM(args: ISetObjectPropertiesCodeDOMArgs, checkCustom = true): void { const obj = this.getObject(); - const support = obj.getEditorSupport(); + const objES = obj.getEditorSupport(); + + if (checkCustom && objES.isCustom_SizeComponent_buildSetObjectPropertiesCodeDOM()) { + + return; + } + const prop = SizeComponent.size; - if (support.isNestedPrefabInstance() - && support.isUnlockedPropertyXY(prop)) { + if (objES.isNestedPrefabInstance() + && objES.isUnlockedPropertyXY(prop)) { const dom = new core.code.MethodCallCodeDOM("setSize", args.objectVarName); dom.argFloat(prop.x.getValue(obj)); dom.argFloat(prop.y.getValue(obj)); args.statements.push(dom); - args.statements.push( - new core.code.MethodCallCodeDOM("updateDisplayOrigin", args.objectVarName)); + + if (objES.getSizeComponentGeneratesUpdateDisplayOrigin()) { + + args.statements.push( + new core.code.MethodCallCodeDOM("updateDisplayOrigin", args.objectVarName)); + } } } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Utils.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Utils.ts new file mode 100644 index 000000000..11a3e12c6 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/Utils.ts @@ -0,0 +1,75 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export function sortGameObjects(objects: ISceneGameObject[]) { + + const sorted = new Set(); + + for (const obj of objects) { + + const objES = obj.getEditorSupport(); + const scene = objES.getScene(); + const parent = objES.getObjectParent(); + + if (parent && !sorted.has(parent)) { + + parent.getEditorSupport().sortObjectChildren(); + + sorted.add(parent); + + } else if (!sorted.has(scene)) { + + scene.sortGameObjects(); + + sorted.add(scene); + } + } + } + + export function sortObjectsAlgorithm(children: ISceneGameObject[], countPrefabChildren: number) { + + const start = countPrefabChildren; + const len = children.length; + + for (let i = start; i < len - 1 ; i++) { + + for (let j = i + 1; j < len; j++) { + + const a = children[i]; + const b = children[j]; + + if (gameObjectSortingWeight(b) < gameObjectSortingWeight(a)) { + + children[i] = b; + children[j] = a; + } + } + } + } + + export function gameObjectSortingWeight(obj: ISceneGameObject) { + + if (obj instanceof ScriptNode) { + + return 1; + } + + return 0; + } + + export function isNestedPrefabInstance(obj: any) { + + const support = GameObjectEditorSupport.getEditorSupport(obj); + + if (support) { + + return support.isNestedPrefabInstance(); + } + + return false; + } + + export function isGameObject(obj: any) { + + return GameObjectEditorSupport.hasEditorSupport(obj); + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/bitmapText/BitmapText.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/bitmapText/BitmapText.ts index b6de9c0ff..1b655351a 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/bitmapText/BitmapText.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/bitmapText/BitmapText.ts @@ -43,21 +43,5 @@ namespace phasereditor2d.scene.ui.sceneobjects { return this._editorSupport; } - - /** - * For compatibility with other game objects. It is used for LayoutExtension. - */ - get displayWidth() { - - return this.width * this.scaleX; - } - - /** - * For compatibility with other game objects. It is used for LayoutExtension. - */ - get displayHeight() { - - return this.height * this.scaleY; - } } } \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/BreakParentOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/BreakParentOperation.ts index b4ad4f6af..15f70a9e1 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/BreakParentOperation.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/BreakParentOperation.ts @@ -19,54 +19,60 @@ namespace phasereditor2d.scene.ui.sceneobjects { static breakParent(scene: Scene, selectedObjects: ISceneGameObject[]) { - const displayList = scene.sys.displayList; - const sel = []; for (const obj of selectedObjects) { const parent = obj as sceneobjects.Container | sceneobjects.Layer; - const children = [...parent.getChildren()]; + const children = [...parent.getEditorSupport().getObjectChildren()]; + + for (const childObj of children) { + + const pos = new Phaser.Math.Vector2(0, 0); - for (const child of children) { + let childAsSprite: Image; - const sprite = child as unknown as Phaser.GameObjects.Sprite; + if (childObj.getEditorSupport().hasComponent(TransformComponent)) { - const p = new Phaser.Math.Vector2(0, 0); + childAsSprite = childObj as Image; - sprite.getWorldTransformMatrix().transformPoint(0, 0, p); + childAsSprite.getWorldTransformMatrix().transformPoint(0, 0, pos); + } - sel.push(sprite); + sel.push(childObj); - parent.remove(sprite); + parent.getEditorSupport().removeObjectChild(childObj); - displayList.remove(sprite); + scene.removeGameObject(childObj); - sprite.displayList = null; + childObj.displayList = null; if (parent.parentContainer) { - parent.parentContainer.getWorldTransformMatrix().applyInverse(p.x, p.y, p); + parent.parentContainer.getWorldTransformMatrix().applyInverse(pos.x, pos.y, pos); - parent.parentContainer.add(sprite); + (parent.parentContainer as Container).getEditorSupport().addObjectChild(childObj); } else { if (parent.displayList instanceof Layer) { - parent.displayList.add(sprite); + parent.displayList.getEditorSupport().addObjectChild(childObj); } else { - const i = displayList.getIndex(parent); + const i = scene.getGameObjectIndex(parent); - displayList.addAt(sprite, i, true); + scene.addGameObjectAt(childObj, i, true); } } - sprite.x = p.x; - sprite.y = p.y; + if (childAsSprite) { + + childAsSprite.x = pos.x; + childAsSprite.y = pos.y; + } } parent.getEditorSupport().destroy(); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/Container.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/Container.ts index 748a855ec..aba098b46 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/Container.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/Container.ts @@ -14,10 +14,5 @@ namespace phasereditor2d.scene.ui.sceneobjects { return this._editorSupport; } - - getChildren(): ISceneGameObject[] { - - return this.list as any; - } } } \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/ContainerEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/ContainerEditorSupport.ts index b5d94d2dd..bf7965429 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/ContainerEditorSupport.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/ContainerEditorSupport.ts @@ -1,7 +1,7 @@ -/// +/// namespace phasereditor2d.scene.ui.sceneobjects { - export class ContainerEditorSupport extends ParentGameObjectEditorSupport { + export class ContainerEditorSupport extends DisplayParentGameObjectEditorSupport { constructor(obj: Container, scene: Scene) { super(ContainerExtension.getInstance(), obj, scene); @@ -42,7 +42,10 @@ namespace phasereditor2d.scene.ui.sceneobjects { const container = this.getObject(); - if (container.list.length === 0) { + const children = this.getDisplayObjectChildren(); + + if (children.length === 0) { + return []; } @@ -51,7 +54,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { const points: Phaser.Math.Vector2[] = []; - for (const obj of container.getChildren()) { + for (const obj of children) { const bounds = obj.getEditorSupport().getScreenBounds(camera); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/ContainerExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/ContainerExtension.ts index d520ea5fb..60d8c94a2 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/ContainerExtension.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/ContainerExtension.ts @@ -28,7 +28,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { const list = []; - const { children } = ParentGameObjectEditorSupport.buildRawChildrenData(args.serializer.getData()); + const { children } = GameObjectEditorSupport.buildRawChildrenData(args.serializer.getData()); for (const objData of children) { @@ -78,7 +78,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { container.getEditorSupport().setScene(scene); - scene.sys.displayList.add(container); + scene.addGameObject(container); return container; } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/CreateContainerWithObjectsOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/CreateContainerWithObjectsOperation.ts index 87f1b475c..ddba42b8d 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/CreateContainerWithObjectsOperation.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/container/CreateContainerWithObjectsOperation.ts @@ -6,8 +6,10 @@ namespace phasereditor2d.scene.ui.sceneobjects { protected async performModification() { + const scene = this.getScene(); + const [container] = sceneobjects.ContainerExtension.getInstance().createDefaultSceneObject({ - scene: this.getScene(), + scene, x: 0, y: 0 }); @@ -16,15 +18,15 @@ namespace phasereditor2d.scene.ui.sceneobjects { const list = [...this._editor.getSelectedGameObjects()]; - this._editor.getScene().sortObjectsByRenderingOrder(list); + scene.sortObjectsByRenderingOrder(list); let newParent: Container | Layer; for (const obj of list) { - const objParent = getObjectParent(obj); + const objParent = obj.getEditorSupport().getObjectParent(); - if (objParent) { + if (objParent && (objParent instanceof Layer || objParent instanceof Container)) { if (newParent) { @@ -42,27 +44,34 @@ namespace phasereditor2d.scene.ui.sceneobjects { if (newParent) { - this.getScene().sys.displayList.remove(container); + scene.removeGameObject(container); + + const newParentES = newParent.getEditorSupport(); + + newParentES.addObjectChild(container); + newParentES.sortObjectChildren(); + + } else { - newParent.add(container); + scene.sortGameObjects(); } for (const obj of list) { - const sprite = obj as unknown as Phaser.GameObjects.Sprite; + const sprite = obj as unknown as Sprite; const worldPoint = new Phaser.Math.Vector2(0, 0); sprite.getWorldTransformMatrix().transformPoint(0, 0, worldPoint); - const objParent = getObjectParent(obj); + const objParent = obj.getEditorSupport().getObjectParent(); if (objParent) { - objParent.remove(sprite); + objParent.getEditorSupport().removeObjectChild(sprite); } - container.add(sprite); + container.getEditorSupport().addObjectChild(sprite); const localPoint = new Phaser.Math.Vector2(0, 0); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/image/BaseImageEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/image/BaseImageEditorSupport.ts index 2ed05624e..323bba422 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/image/BaseImageEditorSupport.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/image/BaseImageEditorSupport.ts @@ -2,23 +2,47 @@ namespace phasereditor2d.scene.ui.sceneobjects { export class BaseImageEditorSupport extends GameObjectEditorSupport { - constructor(extension: SceneGameObjectExtension, obj: T, scene: Scene, includeTextureComponent = true) { + constructor(extension: SceneGameObjectExtension, obj: T, scene: Scene, + includeTextureComponent = true, includeAlphaComponent = true, includeFlipComponent = true, includeTint = true) { + super(extension, obj, scene); + // texture if (includeTextureComponent) { this.addComponent(new TextureComponent(obj as unknown as ITextureLikeObject)); } + // transform + // origin this.addComponent( new TransformComponent(obj as unknown as ITransformLikeObject), - new OriginComponent(obj as unknown as IOriginLikeObject), - new FlipComponent(obj as unknown as IFlipLikeObject), - new VisibleComponent(obj as unknown as IVisibleLikeObject), - new AlphaComponent(obj as unknown as IAlphaLikeObject), - new TintComponent(obj), - new ArcadeComponent(obj, false) - ); + new OriginComponent(obj as unknown as IOriginLikeObject)); + + // flip + if (includeFlipComponent) { + + this.addComponent(new FlipComponent(obj as unknown as IFlipLikeObject)); + } + + // visible + this.addComponent( + new VisibleComponent(obj as unknown as IVisibleLikeObject)); + + // alpha + if (includeAlphaComponent) { + + this.addComponent(new AlphaComponent(obj as unknown as IAlphaLikeObject)); + } + + // tint + if (includeTint) { + + this.addComponent(new TintComponent(obj)); + } + + // arcade + this.addComponent(new ArcadeComponent(obj, false)); } getCellRenderer(): colibri.ui.controls.viewers.ICellRenderer { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/keyboard/KeyboardKeyExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/keyboard/KeyboardKeyExtension.ts index 4273a4af5..3521186a9 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/keyboard/KeyboardKeyExtension.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/keyboard/KeyboardKeyExtension.ts @@ -39,6 +39,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { const sceneCtx = obj.getEditorSupport().getScene().isPrefabSceneType() ? "this.scene" : "this"; const call = new core.code.MethodCallCodeDOM("addKey", `${sceneCtx}.input.keyboard`); + call.setOptionalContext(true); call.arg(`Phaser.Input.Keyboard.KeyCodes.${obj.keyCode}`); return { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/CreateLayerWithObjectsOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/CreateLayerWithObjectsOperation.ts index d755557b5..fffe8d6f5 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/CreateLayerWithObjectsOperation.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/CreateLayerWithObjectsOperation.ts @@ -6,7 +6,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { private findParentLayer(obj: ISceneGameObject) { - const parent = getObjectParent(obj); + const parent = obj.getEditorSupport().getObjectParent(); if (parent) { @@ -23,17 +23,19 @@ namespace phasereditor2d.scene.ui.sceneobjects { protected async performModification() { + const scene = this.getScene(); + const [layer] = sceneobjects.LayerExtension.getInstance().createDefaultSceneObject({ scene: this.getScene(), x: 0, y: 0 }) as sceneobjects.Layer[]; - layer.getEditorSupport().setLabel(this.getScene().makeNewName("layer")); + layer.getEditorSupport().setLabel(scene.makeNewName("layer")); const list = [...this._editor.getSelectedGameObjects()]; - this._editor.getScene().sortObjectsByRenderingOrder(list); + scene.sortObjectsByRenderingOrder(list); let newParent: Layer; @@ -59,24 +61,38 @@ namespace phasereditor2d.scene.ui.sceneobjects { if (newParent) { - this.getScene().sys.displayList.remove(layer); + scene.removeGameObject(layer); + + const newParentES = newParent.getEditorSupport(); + + newParentES.addObjectChild(layer); + newParentES.sortObjectChildren(); + + } else { - newParent.add(layer); + scene.sortGameObjects(); } for (const obj of list) { - const sprite = obj as unknown as Phaser.GameObjects.Sprite; + const sprite = obj as unknown as Sprite; const worldPoint = new Phaser.Math.Vector2(0, 0); sprite.getWorldTransformMatrix().transformPoint(0, 0, worldPoint); - const objParent = getObjectParentOrDisplayList(obj); + const objParent = obj.getEditorSupport().getObjectParent(); - objParent.remove(sprite); + if (objParent) { + + objParent.getEditorSupport().removeObjectChild(sprite); + + } else { + + scene.removeGameObject(sprite); + } - layer.add(sprite); + layer.getEditorSupport().addObjectChild(sprite); sprite.x = worldPoint.x; sprite.y = worldPoint.y; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/Layer.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/Layer.ts index ae89e31e0..a7d14c3ba 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/Layer.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/Layer.ts @@ -16,9 +16,21 @@ namespace phasereditor2d.scene.ui.sceneobjects { return this._editorSupport; } - getChildren(): ISceneGameObject[] { + // polyfill GameObject methods + + setData(key: string | any, data?: any): this { + + return super.setData(key, data); + } + + incData(key: string | any, data?: any): this { - return super.getChildren() as any; + return super.incData(key, data); + } + + toggleData(key: string | any): this { + + return super.toggleData(key); } replace(oldChild: Phaser.GameObjects.GameObject, newChild: Phaser.GameObjects.GameObject) { @@ -28,13 +40,6 @@ namespace phasereditor2d.scene.ui.sceneobjects { return super.replace(oldChild, newChild); } - // polyfill GameObject methods - - parentContainer: Phaser.GameObjects.Container; - tabIndex: number; - input: Phaser.Types.Input.InteractiveObject; - body: Phaser.Physics.Arcade.Body | Phaser.Physics.Arcade.StaticBody | MatterJS.BodyType; - setInteractive(hitArea?: any, callback?: Phaser.Types.Input.HitAreaCallback, dropZone?: boolean): this { return this; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/LayerEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/LayerEditorSupport.ts index 069e47b52..50c808436 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/LayerEditorSupport.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/LayerEditorSupport.ts @@ -3,7 +3,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { import controls = colibri.ui.controls; import json = phasereditor2d.scene.core.json; - export class LayerEditorSupport extends ParentGameObjectEditorSupport { + export class LayerEditorSupport extends DisplayParentGameObjectEditorSupport { constructor(obj: Layer, scene: Scene) { super(LayerExtension.getInstance(), obj, scene); @@ -17,9 +17,10 @@ namespace phasereditor2d.scene.ui.sceneobjects { getScreenBounds(camera: Phaser.Cameras.Scene2D.Camera) { - const layer = this.getObject(); + const children = this.getObjectChildren(); + + if (children.length === 0) { - if (layer.list.length === 0) { return []; } @@ -28,7 +29,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { const points: Phaser.Math.Vector2[] = []; - for (const obj of layer.getChildren()) { + for (const obj of children) { const bounds = obj.getEditorSupport().getScreenBounds(camera); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/LayerExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/LayerExtension.ts index e17194b87..f08ef1765 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/LayerExtension.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/layer/LayerExtension.ts @@ -26,7 +26,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { const containerData = serializer.getData(); - const children = originalObject.getChildren(); + const children = originalObject.getEditorSupport().getObjectChildren(); // tslint:disable-next-line:prefer-for-of for (let i = 0; i < children.length; i++) { @@ -76,7 +76,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { layer.getEditorSupport().setScene(scene); - scene.sys.displayList.add(layer); + scene.addGameObject(layer); return layer; } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSlice.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSlice.ts new file mode 100644 index 000000000..4a28d6caf --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSlice.ts @@ -0,0 +1,49 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class NineSlice extends Phaser.GameObjects.NineSlice implements ISceneGameObject { + + private _editorSupport: NineSliceEditorSupport; + + constructor( + scene: Scene, x: number, y: number, + texture: string, frame: string | number, width: number, height: number, + leftWidth: number, rightWidth: number, topHeight: number, bottomHeight: number + ) { + super(scene, x, y, texture, frame, width, height, + leftWidth, rightWidth, topHeight, bottomHeight); + + this._editorSupport = new NineSliceEditorSupport(this, scene); + } + + getEditorSupport(): NineSliceEditorSupport { + + return this._editorSupport; + } + + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this { + + super.setTexture(key, frame); + + if (this.is3Slice) { + + this.setSizeToFrame(); + } + + return this; + } + + setSize(width: number, height: number): this { + + if (this.is3Slice) { + + super.setSize(width, this.height); + + } else { + + super.setSize(width, height); + } + + return this; + } + } +} diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceCodeDOMBuilder.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceCodeDOMBuilder.ts new file mode 100644 index 000000000..f0f631460 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceCodeDOMBuilder.ts @@ -0,0 +1,136 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + import code = core.code; + + export class NineSliceCodeDOMBuilder extends BaseImageCodeDOMBuilder { + + constructor() { + super("nineslice"); + } + + buildCreatePrefabInstanceCodeDOM(args: IBuildPrefabConstructorCodeDOMArgs) { + + const obj = args.obj as NineSlice; + const objES = obj.getEditorSupport(); + const call = args.methodCallDOM; + + call.arg(args.sceneExpr); + + this.buildCreatePrefabInstanceCodeDOM_XY_Arguments(args); + + if (objES.isUnlockedProperty(TextureComponent.texture)) { + + this.addTextureFrameArgsToObjectFactoryMethodCallDOM( + args.methodCallDOM, args.obj as ITextureLikeObject); + } else { + + call.argUndefined(); + call.argUndefined(); + } + + if (obj.getEditorSupport().isUnlockedPropertyXY(SizeComponent.size)) { + + call.argFloat(obj.width); + call.argFloat(obj.height); + + } else { + + call.argUndefined(); + call.argUndefined(); + } + + for (const prop of [ + NineSliceComponent.leftWidth, + NineSliceComponent.rightWidth, + NineSliceComponent.topHeight, + NineSliceComponent.bottomHeight]) { + + if (objES.isUnlockedProperty(prop)) { + + call.argFloat(prop.getValue(obj)); + + } else { + + call.arg("undefined"); + } + } + } + + buildPrefabConstructorDeclarationCodeDOM(args: IBuildPrefabConstructorDeclarationCodeDOM): void { + + const ctr = args.ctrDeclCodeDOM; + + ctr.arg("x", "number", true); + ctr.arg("y", "number", true); + ctr.arg("texture", "string", true); + ctr.arg("frame", "number | string", true); + ctr.arg("width", "number", true); + ctr.arg("height", "number", true); + ctr.arg("leftWidth", "number", true); + ctr.arg("rightWidth", "number", true); + ctr.arg("topHeight", "number", true); + ctr.arg("bottomHeight", "number", true); + } + + buildPrefabConstructorDeclarationSupperCallCodeDOM( + args: IBuildPrefabConstructorDeclarationSupperCallCodeDOMArgs): void { + + const obj = args.prefabObj as NineSlice; + const objES = obj.getEditorSupport(); + + const call = args.superMethodCallCodeDOM; + + this.buildPrefabConstructorDeclarationSupperCallCodeDOM_XYParameters(args); + + this.buildPrefabConstructorDeclarationSupperCallCodeDOM_TextureParameters(args, call); + + if (objES.isUnlockedPropertyXY(SizeComponent.size)) { + + call.arg("width ?? " + obj.width); + call.arg("height ?? " + obj.height); + + } else { + + call.arg("width"); + call.arg("height"); + } + + for (const prop of [ + NineSliceComponent.leftWidth, + NineSliceComponent.rightWidth, + NineSliceComponent.topHeight, + NineSliceComponent.bottomHeight]) { + + if (objES.isUnlockedProperty(prop)) { + + call.arg(prop.name + " ?? " + prop.getValue(obj)); + + } else { + + call.arg(prop.name); + } + } + } + + buildCreateObjectWithFactoryCodeDOM(args: IBuildObjectFactoryCodeDOMArgs): code.MethodCallCodeDOM { + + const obj = args.obj as NineSlice; + const call = new code.MethodCallCodeDOM("nineslice", args.gameObjectFactoryExpr); + + call.argFloat(obj.x); + call.argFloat(obj.y); + + this.addTextureFrameArgsToObjectFactoryMethodCallDOM(call, obj); + + call.argFloat(obj.width); + call.argFloat(obj.height); + + call.argFloat(obj.leftWidth); + call.argFloat(obj.rightWidth); + call.argFloat(obj.topHeight); + call.argFloat(obj.bottomHeight); + + return call; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceComponent.ts new file mode 100644 index 000000000..68c4aa1f0 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceComponent.ts @@ -0,0 +1,102 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export const updateVertices = (obj: NineSlice) => { + + obj.updateVertices(); + (obj as any).updateUVs(); + }; + + function sliceProperty( + name: "leftWidth" | "rightWidth" | "topHeight" | "bottomHeight", defValue: any, label: string): IProperty { + + return { + name, + defValue, + label, + tooltip: `phaser:Phaser.GameObjects.NineSlice.${name}`, + local: false, + getValue: obj => obj[name], + setValue: (obj: NineSlice, value) => { + + const data = { + leftWidth: obj.leftWidth, + rightWidth: obj.rightWidth, + topHeight: obj.topHeight, + bottomHeight: obj.bottomHeight + }; + + data[name] = value; + + obj.setSlices( + obj.width, obj.height, + data.leftWidth, data.rightWidth, + data.topHeight, data.bottomHeight); + } + }; + } + + export class NineSliceComponent extends Component { + + static leftWidth = sliceProperty("leftWidth", 10, "L"); + static rightWidth = sliceProperty("rightWidth", 10, "R"); + static topHeight = sliceProperty("topHeight", 10, "T"); + static bottomHeight = sliceProperty("bottomHeight", 10, "B"); + + static horizontalWidth: IPropertyXY = { + label: "Slice Width", + x: NineSliceComponent.leftWidth, + y: NineSliceComponent.rightWidth, + } + static verticalWidth: IPropertyXY = { + label: "Slice Height", + x: NineSliceComponent.topHeight, + y: NineSliceComponent.bottomHeight, + } + + static sliceProperties = [ + NineSliceComponent.leftWidth, + NineSliceComponent.rightWidth, + NineSliceComponent.topHeight, + NineSliceComponent.bottomHeight + ]; + + constructor(obj: NineSlice) { + super(obj, + NineSliceComponent.sliceProperties); + } + + buildSetObjectPropertiesCodeDOM(args: ISetObjectPropertiesCodeDOMArgs): void { + + const objES = this.getEditorSupport(); + + if (objES.isNestedPrefabInstance()) { + + let onlySizeChanged = true; + + for (const prop of NineSliceComponent.sliceProperties) { + + if (objES.isUnlockedProperty(prop)) { + + onlySizeChanged = false; + } + } + + if (onlySizeChanged) { + + const sizeComponent = objES.getComponent(SizeComponent) as SizeComponent; + + sizeComponent.buildSetObjectPropertiesCodeDOM(args, false); + + } else { + + this.buildSetObjectPropertiesWithMethodCodeDOM_FloatProperty( + args, + "setSlices", + SizeComponent.width, + SizeComponent.height, + ...NineSliceComponent.sliceProperties); + } + } + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceEditorSupport.ts new file mode 100644 index 000000000..df5d1f536 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceEditorSupport.ts @@ -0,0 +1,37 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class NineSliceEditorSupport extends BaseImageEditorSupport { + + constructor(obj: NineSlice, scene: Scene) { + super(NineSliceExtension.getInstance(), obj, scene, true, false, false, false); + + this.addComponent( + new AlphaSingleComponent(obj), + new TintSingleComponent(obj), + new SizeComponent(obj), + new NineSliceComponent(obj)); + } + + setInteractive() { + + this.getObject().setInteractive(interactive_getAlpha_RenderTexture); + } + + getSizeComponentGeneratesUpdateDisplayOrigin(): boolean { + + return false; + } + + isCustom_SizeComponent_buildSetObjectPropertiesCodeDOM(): boolean { + + return true; + } + + onUpdateAfterSetTexture(): void { + + const obj = this.getObject(); + obj.updateVertices(); + (obj as any).updateUVs(); + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceExtension.ts new file mode 100644 index 000000000..1637fff94 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceExtension.ts @@ -0,0 +1,49 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class NineSliceExtension extends BaseImageExtension { + + private static _instance = new NineSliceExtension(); + + static getInstance() { + + return this._instance; + } + + constructor() { + super({ + phaserTypeName: "Phaser.GameObjects.NineSlice", + typeName: "NineSlice", + category: SCENE_OBJECT_IMAGE_CATEGORY, + icon: ScenePlugin.getInstance().getIconDescriptor(ICON_9_SLICE) + }); + } + + adaptDataAfterTypeConversion(serializer: core.json.Serializer, originalObject: ISceneGameObject, extraData: any) { + + super.adaptDataAfterTypeConversion(serializer, originalObject, extraData); + + const obj = originalObject as unknown as Phaser.GameObjects.Components.ComputedSize; + + const width = obj.width === undefined ? 20 : obj.width; + const height = obj.height === undefined ? 20 : obj.height; + + serializer.getData()[SizeComponent.width.name] = width; + serializer.getData()[SizeComponent.height.name] = height; + } + + getCodeDOMBuilder(): GameObjectCodeDOMBuilder { + + return new NineSliceCodeDOMBuilder(); + } + + protected newObject(scene: Scene, x: number, y: number, key?: string, frame?: string | number): ISceneGameObject { + + if (key) { + + return new NineSlice(scene, x, y, key, frame, 256, 256, 10, 10, 10, 10); + } + + return new NineSlice(scene, x, y, undefined, undefined, 256, 256, 10, 10, 10, 10); + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceSection.ts new file mode 100644 index 000000000..125f13a07 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/NineSliceSection.ts @@ -0,0 +1,51 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + import controls = colibri.ui.controls; + + export class NineSliceSection extends SceneGameObjectSection { + + static SECTION_ID = "phasereditor2d.scene.ui.sceneobjects.NineSliceSection"; + + constructor(page: controls.properties.PropertyPage) { + super(page, NineSliceSection.SECTION_ID, "Nine Slice", false, false); + } + + createForm(parent: HTMLDivElement) { + + const comp = this.createGridElementWithPropertiesXY(parent); + + this.createPropertyXYRow(comp, NineSliceComponent.horizontalWidth); + this.createPropertyXYRow(comp, NineSliceComponent.verticalWidth); + + const btn = this.createButton(comp, "Edit Slices", () => { + + this.getEditor().getToolsManager().activateTool(SliceTool.ID); + }); + + btn.style.gridColumn = "1 / span 6"; + } + + createMenu(menu: controls.Menu): void { + + super.createMenu(menu); + + menu.addCommand(ui.editor.commands.CMD_EDIT_SLICE_SCENE_OBJECT); + } + + canEdit(obj: any, n: number): boolean { + + return obj instanceof NineSlice; + } + + canEditNumber(n: number): boolean { + + return n > 0; + } + + getSectionHelpPath() { + // return "scene-editor/tile-sprite-object.html#tile-sprite-properties"; + // TODO + return ""; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSlice.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSlice.ts new file mode 100644 index 000000000..7534bf453 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSlice.ts @@ -0,0 +1,49 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class ThreeSlice extends Phaser.GameObjects.NineSlice implements ISceneGameObject { + + private _editorSupport: ThreeSliceEditorSupport; + + constructor( + scene: Scene, x: number, y: number, + texture: string, frame: string | number, width: number, + leftWidth: number, rightWidth: number + ) { + super(scene, x, y, texture, frame, width, 0, + leftWidth, rightWidth, 0, 0); + + this._editorSupport = new ThreeSliceEditorSupport(this, scene); + } + + getEditorSupport() { + + return this._editorSupport; + } + + setTexture(key: string | Phaser.Textures.Texture, frame?: string | number): this { + + super.setTexture(key, frame); + + if (this.is3Slice) { + + this.setSizeToFrame(); + } + + return this; + } + + setSize(width: number, height: number): this { + + if (this.is3Slice) { + + super.setSize(width, this.height); + + } else { + + super.setSize(width, height); + } + + return this; + } + } +} diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceCodeDOMBuilder.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceCodeDOMBuilder.ts new file mode 100644 index 000000000..2efead282 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceCodeDOMBuilder.ts @@ -0,0 +1,136 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + import code = core.code; + + export class ThreeSliceCodeDOMBuilder extends BaseImageCodeDOMBuilder { + + constructor() { + super("nineslice"); + } + + buildCreatePrefabInstanceCodeDOM(args: IBuildPrefabConstructorCodeDOMArgs) { + + const obj = args.obj as NineSlice; + const objES = obj.getEditorSupport(); + const call = args.methodCallDOM; + + call.arg(args.sceneExpr); + + this.buildCreatePrefabInstanceCodeDOM_XY_Arguments(args); + + // texture + + if (objES.isUnlockedProperty(TextureComponent.texture)) { + + this.addTextureFrameArgsToObjectFactoryMethodCallDOM( + args.methodCallDOM, args.obj as ITextureLikeObject); + } else { + + call.argUndefined(); + call.argUndefined(); + } + + // size (only the "width" argument matters) + + if (obj.getEditorSupport().isUnlockedPropertyXY(SizeComponent.size)) { + + call.argFloat(obj.width); + + } else { + + call.argUndefined(); + } + + // 3-slice + + for (const prop of [ + NineSliceComponent.leftWidth, + NineSliceComponent.rightWidth]) { + + if (objES.isUnlockedProperty(prop)) { + + call.argFloat(prop.getValue(obj)); + + } else { + + call.arg("undefined"); + } + } + } + + buildPrefabConstructorDeclarationCodeDOM(args: IBuildPrefabConstructorDeclarationCodeDOM): void { + + const ctr = args.ctrDeclCodeDOM; + + ctr.arg("x", "number", true); + ctr.arg("y", "number", true); + ctr.arg("texture", "string", true); + ctr.arg("frame", "number | string", true); + ctr.arg("width", "number", true); + ctr.arg("leftWidth", "number", true); + ctr.arg("rightWidth", "number", true); + } + + buildPrefabConstructorDeclarationSupperCallCodeDOM( + args: IBuildPrefabConstructorDeclarationSupperCallCodeDOMArgs): void { + + const obj = args.prefabObj as NineSlice; + const objES = obj.getEditorSupport(); + + const call = args.superMethodCallCodeDOM; + + this.buildPrefabConstructorDeclarationSupperCallCodeDOM_XYParameters(args); + + this.buildPrefabConstructorDeclarationSupperCallCodeDOM_TextureParameters(args, call); + + if (objES.isUnlockedPropertyXY(SizeComponent.size)) { + + call.arg("width ?? " + obj.width); + call.argFloat(0); // height + + } else { + + call.arg("width"); + call.argFloat(0); // height + } + + for (const prop of [ + ThreeSliceComponent.leftWidth, + ThreeSliceComponent.rightWidth]) { + + if (objES.isUnlockedProperty(prop)) { + + call.arg(prop.name + " ?? " + prop.getValue(obj)); + + } else { + + call.arg(prop.name); + } + } + + call.argFloat(0); // topHeight + call.argFloat(0); // bottomHeight + } + + buildCreateObjectWithFactoryCodeDOM(args: IBuildObjectFactoryCodeDOMArgs): code.MethodCallCodeDOM { + + const obj = args.obj as NineSlice; + const call = new code.MethodCallCodeDOM("nineslice", args.gameObjectFactoryExpr); + + call.argFloat(obj.x); + call.argFloat(obj.y); + + this.addTextureFrameArgsToObjectFactoryMethodCallDOM(call, obj); + + call.argFloat(obj.width); + call.argFloat(0); + + call.argFloat(obj.leftWidth); + call.argFloat(obj.rightWidth); + call.argFloat(0); + call.argFloat(0); + + return call; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceComponent.ts new file mode 100644 index 000000000..9eb697576 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceComponent.ts @@ -0,0 +1,83 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + function sliceProperty( + name: "leftWidth" | "rightWidth", defValue: any, label: string): IProperty { + + return { + name, + defValue, + label, + tooltip: `phaser:Phaser.GameObjects.NineSlice.${name}`, + local: false, + getValue: obj => obj[name], + setValue: (obj: ThreeSlice, value) => { + + const data = { + leftWidth: obj.leftWidth, + rightWidth: obj.rightWidth + }; + + data[name] = value; + + obj.setSlices( + obj.width, 0, + data.leftWidth, data.rightWidth, + 0, 0); + } + }; + } + + export class ThreeSliceComponent extends Component { + + static leftWidth = sliceProperty("leftWidth", 10, "L"); + static rightWidth = sliceProperty("rightWidth", 10, "R"); + static sliceProperties = [ + ThreeSliceComponent.leftWidth, + ThreeSliceComponent.rightWidth + ]; + + static horizontalWidth: IPropertyXY = { + label: "Slice Width", + x: ThreeSliceComponent.leftWidth, + y: ThreeSliceComponent.rightWidth, + } + + constructor(obj: ThreeSlice) { + super(obj, ThreeSliceComponent.sliceProperties); + } + + buildSetObjectPropertiesCodeDOM(args: ISetObjectPropertiesCodeDOMArgs): void { + + const objES = this.getEditorSupport(); + + if (objES.isNestedPrefabInstance()) { + + let onlySizeChanged = true; + + for (const prop of ThreeSliceComponent.sliceProperties) { + + if (objES.isUnlockedProperty(prop)) { + + onlySizeChanged = false; + } + } + + if (onlySizeChanged) { + + const sizeComponent = objES.getComponent(SizeComponent) as SizeComponent; + + sizeComponent.buildSetObjectPropertiesCodeDOM(args, false); + + } else { + + this.buildSetObjectPropertiesWithMethodCodeDOM_FloatProperty( + args, + "setSlices", + SizeComponent.width, + SizeComponent.height, + ...ThreeSliceComponent.sliceProperties); + } + } + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceEditorSupport.ts new file mode 100644 index 000000000..0ab09d8a5 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceEditorSupport.ts @@ -0,0 +1,37 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class ThreeSliceEditorSupport extends BaseImageEditorSupport { + + constructor(obj: ThreeSlice, scene: Scene) { + super(ThreeSliceExtension.getInstance(), obj, scene, true, false, false, false); + + this.addComponent( + new AlphaSingleComponent(obj), + new TintSingleComponent(obj), + new SizeComponent(obj), + new ThreeSliceComponent(obj)); + } + + setInteractive() { + + this.getObject().setInteractive(interactive_getAlpha_RenderTexture); + } + + isCustom_SizeComponent_buildSetObjectPropertiesCodeDOM(): boolean { + + return true; + } + + getSizeComponentGeneratesUpdateDisplayOrigin(): boolean { + + return false; + } + + onUpdateAfterSetTexture(): void { + + const obj = this.getObject(); + obj.updateVertices(); + (obj as any).updateUVs(); + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceExtension.ts new file mode 100644 index 000000000..fd6db22a8 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceExtension.ts @@ -0,0 +1,49 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class ThreeSliceExtension extends BaseImageExtension { + + private static _instance = new ThreeSliceExtension(); + + static getInstance() { + + return this._instance; + } + + constructor() { + super({ + phaserTypeName: "Phaser.GameObjects.NineSlice", + typeName: "ThreeSlice", + category: SCENE_OBJECT_IMAGE_CATEGORY, + icon: ScenePlugin.getInstance().getIconDescriptor(ICON_3_SLICE) + }); + } + + adaptDataAfterTypeConversion(serializer: core.json.Serializer, originalObject: ISceneGameObject, extraData: any) { + + super.adaptDataAfterTypeConversion(serializer, originalObject, extraData); + + const obj = originalObject as unknown as Phaser.GameObjects.Components.ComputedSize; + + const width = obj.width === undefined ? 20 : obj.width; + const height = obj.height === undefined ? 20 : obj.height; + + serializer.getData()[SizeComponent.width.name] = width; + serializer.getData()[SizeComponent.height.name] = height; + } + + getCodeDOMBuilder(): GameObjectCodeDOMBuilder { + + return new ThreeSliceCodeDOMBuilder(); + } + + protected newObject(scene: Scene, x: number, y: number, key?: string, frame?: string | number) { + + if (key) { + + return new ThreeSlice(scene, x, y, key, frame, 256, 10, 10); + } + + return new ThreeSlice(scene, x, y, undefined, undefined, 256, 10, 10); + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceSection.ts new file mode 100644 index 000000000..ed001427e --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/nineslice/ThreeSliceSection.ts @@ -0,0 +1,43 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + import controls = colibri.ui.controls; + + export class ThreeSliceSection extends SceneGameObjectSection { + + static SECTION_ID = "phasereditor2d.scene.ui.sceneobjects.ThreeSliceSection"; + + constructor(page: controls.properties.PropertyPage) { + super(page, ThreeSliceSection.SECTION_ID, "Three Slice", false, false); + } + + createForm(parent: HTMLDivElement) { + + const comp = this.createGridElementWithPropertiesXY(parent); + + this.createPropertyXYRow(comp, ThreeSliceComponent.horizontalWidth); + + const btn = this.createButton(comp, "Edit Slices", () => { + + this.getEditor().getToolsManager().activateTool(SliceTool.ID); + }); + + btn.style.gridColumn = "1 / span 6"; + } + + canEdit(obj: any, n: number): boolean { + + return obj instanceof ThreeSlice; + } + + canEditNumber(n: number): boolean { + + return n > 0; + } + + getSectionHelpPath() { + // return "scene-editor/tile-sprite-object.html#tile-sprite-properties"; + // TODO + return ""; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/PrefabUserPropertyComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/PrefabUserPropertyComponent.ts index c299b8297..e63e54a40 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/PrefabUserPropertyComponent.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/PrefabUserPropertyComponent.ts @@ -37,15 +37,22 @@ namespace phasereditor2d.scene.ui.sceneobjects { const propertiesInObject: IUserPropertiesInObject[] = []; - const editorSupport = this.getObject().getEditorSupport(); + const objES = this.getObject().getEditorSupport(); - if (editorSupport.isPrefabInstance()) { + const finder = ScenePlugin.getInstance().getSceneFinder(); + + if (objES.isPrefabInstance()) { + + const nextPrefabId = finder.getFirstNonNestedPrefabId(objES.getPrefabId()); - const prefabFile = this.getObject().getEditorSupport().getPrefabOrNestedPrefabFile(); + if (nextPrefabId) { - if (prefabFile) { + const prefabFile = finder.getPrefabFile(nextPrefabId); - this.getPrefabProperties(propertiesInObject, prefabFile); + if (prefabFile) { + + this.getPrefabProperties(propertiesInObject, prefabFile); + } } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/TintComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/TintComponent.ts index 4eb14e2a8..c0e3b6fb1 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/TintComponent.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/TintComponent.ts @@ -2,7 +2,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { import controls = colibri.ui.controls; - function colorStringToColorNumberConverter(value: string) { + export function colorStringToColorNumberConverter(value: string) { if (typeof (value) === "string" && value.trim() === "") { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/TintSingleComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/TintSingleComponent.ts new file mode 100644 index 000000000..3b9ff78c0 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/TintSingleComponent.ts @@ -0,0 +1,21 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class TintSingleComponent extends Component { + + static tintFill = SimpleProperty("tintFill", false, "Tint Fill", "Fill the tint?"); + static tint = TintProperty("tint", "Tint", "The tint."); + + constructor(obj: ISceneGameObject) { + super(obj, [ + TintSingleComponent.tintFill, + TintSingleComponent.tint, + ]); + } + + buildSetObjectPropertiesCodeDOM(args: ISetObjectPropertiesCodeDOMArgs): void { + + this.buildSetObjectPropertyCodeDOM_BooleanProperty(args, TintSingleComponent.tintFill); + this.buildSetObjectPropertyCodeDOM_FloatProperty(args, TintSingleComponent.tint); + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/GameObjectVariableSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/GameObjectVariableSection.ts index 46a2727dd..7b2f9ccec 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/GameObjectVariableSection.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/GameObjectVariableSection.ts @@ -48,53 +48,58 @@ namespace phasereditor2d.scene.ui.sceneobjects { this.createBooleanField(comp, VariableComponent.useGameObjectName, false); } + GameObjectVariableSection.createTypeEditor(this, comp); + { - // Type + // Scope - this.createLabel(comp, "Type", "The type of the object."); + this.createLabel(comp, "Scope", "The lexical scope of this object's variable, in code."); + this.createEnumField(comp, VariableComponent.scope, false, scope => { - const btn = this.createButton(comp, "", e => { + if (this.getEditor().getScene().isPrefabSceneType()) { - const dlg = new editor.ConvertTypeDialog(this.getEditor()); + return true; + } - dlg.create(); + return scope !== ObjectScope.NESTED_PREFAB; }); + } + } - this.addUpdater(() => { + static createTypeEditor(section: SceneGameObjectSection, parentElement: HTMLElement) { - btn.textContent = this.flatValues_StringJoinDifferent( + const label = section.createLabel(parentElement, "Type", "The type of the object."); - this.getSelection().map(obj => { + const btn = section.createButton(parentElement, "", e => { - const support = obj.getEditorSupport(); + const dlg = new editor.ConvertTypeDialog(section.getEditor()); - let typename = support.getObjectType(); + dlg.create(); + }); - if (support.isPrefabInstance()) { + section.addUpdater(() => { - typename = `prefab ${support.getPrefabName()} (${typename})`; - } + const finder = ScenePlugin.getInstance().getSceneFinder(); - return typename; - }) - ); - }); - } + btn.textContent = section.flatValues_StringJoinDifferent( - { - // Scope + section.getSelection().map(obj => { - this.createLabel(comp, "Scope", "The lexical scope of this object's variable, in code."); - this.createEnumField(comp, VariableComponent.scope, false, scope => { + const objES = obj.getEditorSupport(); - if (this.getEditor().getScene().isPrefabSceneType()) { + let typename = objES.getObjectType(); - return true; - } + if (objES.isPrefabInstance()) { - return scope !== ObjectScope.NESTED_PREFAB; - }); - } + typename = `prefab ${objES.getDisplayPrefabName()} (${typename})`; + } + + return typename; + }) + ); + }); + + return { label, btn }; } canEdit(obj: any, n: number): boolean { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/MoveToParentOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/MoveToParentOperation.ts index bee9818b0..4a80345c4 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/MoveToParentOperation.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/MoveToParentOperation.ts @@ -10,71 +10,12 @@ namespace phasereditor2d.scene.ui.sceneobjects { this._parentId = parentId; } - static canMoveAllTo(objList: ISceneGameObject[], parent: Container | Layer) { - - for (const obj of objList) { - - if (!this.canMoveTo(obj, parent)) { - - return false; - } - } - - return true; - } - - private static canMoveTo(obj: ISceneGameObject, targetParent: Container | Layer) { - - if (!(targetParent instanceof Container || targetParent instanceof Layer)) { - - return false; - } - - const targetParentSupport = targetParent.getEditorSupport(); - - const objParent = getObjectParent(obj); - - if (objParent === targetParent) { - - return false; - } - - if (obj instanceof Container || obj instanceof Layer) { - - if (obj === targetParent) { - - return false; - } - - const parents = new Set(targetParentSupport.getAllParents()); - - if (parents.has(obj)) { - - return false; - } - - if (obj instanceof Layer && targetParent instanceof Container) { - - return false; - } - } - - if (targetParentSupport.isPrefabInstance() && !targetParentSupport.isAllowAppendChildren()) { - - return false; - } - - return true; - } - protected async performModification() { const scene = this.getScene(); const map = scene.buildObjectIdMap(); - const displayList = scene.sys.displayList; - const objects = this.getEditor().getSelectedGameObjects(); scene.sortObjectsByIndex(objects); @@ -83,65 +24,66 @@ namespace phasereditor2d.scene.ui.sceneobjects { const sprite = obj as unknown as Sprite; - const hasPosition = obj.getEditorSupport().isUnlockedProperty(TransformComponent.x); + const objES = obj.getEditorSupport(); - const currentParent = getObjectParent(obj); + const canTranslate = objES.hasComponent(TransformComponent) + && objES.isUnlockedProperty(TransformComponent.x); - const objSupport = obj.getEditorSupport(); + const currentParent = objES.getObjectParent(); - if (objSupport.getParentId() === this._parentId) { + if (objES.getParentId() === this._parentId) { continue; } const worldPoint = new Phaser.Math.Vector2(0, 0); - if (hasPosition) { + if (canTranslate) { sprite.getWorldTransformMatrix().transformPoint(0, 0, worldPoint); } if (currentParent) { - currentParent.remove(obj); + currentParent.getEditorSupport().removeObjectChild(obj); } else { - displayList.remove(obj); + scene.removeGameObject(obj); } if (this._parentId) { - const newParent = map.get(this._parentId) as (Container | Layer); + const newParent = map.get(this._parentId); - const p = new Phaser.Math.Vector2(0, 0); + if (canTranslate) { - if (newParent instanceof Container) { + const p = new Phaser.Math.Vector2(0, 0); - newParent.getWorldTransformMatrix().applyInverse(worldPoint.x, worldPoint.y, p); + if (newParent instanceof Container) { - } else { + newParent.getWorldTransformMatrix().applyInverse(worldPoint.x, worldPoint.y, p); - p.set(worldPoint.x, worldPoint.y); - } + } else { - if (hasPosition) { + p.set(worldPoint.x, worldPoint.y); + } sprite.x = p.x; sprite.y = p.y; } - newParent.add(sprite); + newParent.getEditorSupport().addObjectChild(sprite); } else { - if (hasPosition) { + if (canTranslate) { sprite.x = worldPoint.x; sprite.y = worldPoint.y; } - displayList.add(sprite, true); + scene.addGameObject(sprite, true); } } } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/NestedPrefabObjectVariableSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/NestedPrefabObjectVariableSection.ts new file mode 100644 index 000000000..c99fa52c8 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/NestedPrefabObjectVariableSection.ts @@ -0,0 +1,43 @@ +/// + +namespace phasereditor2d.scene.ui.sceneobjects { + + import controls = colibri.ui.controls; + + export class NestedPrefabObjectVariableSection extends SceneGameObjectSection { + + constructor(page: controls.properties.PropertyPage) { + super(page, "phasereditor2d.scene.ui.sceneobjects.NestedPrefabObjectVariableSection", "Variable", false); + } + + getSectionHelpPath() { + + return "scene-editor/variable-properties.html"; + } + + createForm(parent: HTMLDivElement) { + + const comp = this.createGridElement(parent, 2); + + const { btn } = GameObjectVariableSection.createTypeEditor(this, comp); + btn.disabled = true; + } + + canEdit(obj: any, n: number): boolean { + + if (isGameObject(obj)) { + + const objES = (obj as sceneobjects.ISceneGameObject).getEditorSupport(); + + return objES.isNestedPrefabInstance(); + } + + return false; + } + + canEditNumber(n: number): boolean { + + return n === 1; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ObjectUserComponentsSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ObjectUserComponentsSection.ts index ae28c1a6a..4d0cb8f55 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ObjectUserComponentsSection.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ObjectUserComponentsSection.ts @@ -225,7 +225,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { btn.style.marginTop = "10px"; }); } - + private createComponentMenuIcon( headerDiv: HTMLElement, nodes: UserComponentNode[]) { @@ -248,7 +248,8 @@ namespace phasereditor2d.scene.ui.sceneobjects { canEdit(obj: any, n: number): boolean { - return GameObjectEditorSupport.hasEditorSupport(obj); + return GameObjectEditorSupport.hasEditorSupport(obj) + && (obj as ISceneGameObject).getEditorSupport().isDisplayObject(); } canEditNumber(n: number): boolean { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ParentDialog.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ParentDialog.ts index 7b0b5078f..3cd1ac608 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ParentDialog.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ParentDialog.ts @@ -16,6 +16,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { const viewer = this.getViewer(); viewer.setLabelProvider(new editor.outline.SceneEditorOutlineLabelProvider()); + viewer.setStyledLabelProvider(new editor.outline.SceneEditorOutlineStyledLabelProvider()); viewer.setCellRendererProvider(new editor.outline.SceneEditorOutlineRendererProvider()); viewer.setContentProvider(new ParentContentProvider(this._editor)); @@ -43,7 +44,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { this.setTitle("Parent"); - this.enableButtonOnlyWhenOneElementIsSelected(this.addOpenButton("Move", sel => { + const btn = this.addOpenButton("Move", sel => { const parent = sel[0] as (Container | Layer); @@ -57,55 +58,114 @@ namespace phasereditor2d.scene.ui.sceneobjects { new MoveToParentOperation(this._editor, parent.getEditorSupport().getId())); } - })); + }); + + this.enableButtonOnlyWhenOneElementIsSelected(btn, dstObj => { + + const editorSelection = this._editor.getSelectedGameObjects(); + + for(const selObj of editorSelection) { + + // cannot move a root obj to the display list + if (dstObj instanceof Phaser.GameObjects.DisplayList) { + + if (dstObj.exists(selObj)) { + + return false; + } + + return true; + } + + const selObjParent = selObj.getEditorSupport().getObjectParent(); + + if (dstObj === selObjParent) { + // cannot move the obj to its own parent + return false; + } + + if (selObj instanceof ScriptNode) { + // you can move a script node to any object in the dialog + return true; + } + + if (isGameObject(dstObj)) { + + const dstObjES = (dstObj as ISceneGameObject).getEditorSupport(); + + if (dstObjES.isPrefabInstance() && !dstObjES.isAllowAppendChildren()) { + // you cannot move an object to a parent + // who is not allowing adding more children + return false; + } + } + } + + return true; + }); this.addCancelButton(); } } - class ParentContentProvider implements controls.viewers.ITreeContentProvider { + class ParentContentProvider extends ui.editor.outline.SceneEditorOutlineContentProvider { - private _editor: ui.editor.SceneEditor; + private _selection: ISceneGameObject[]; constructor(editor: ui.editor.SceneEditor) { + super(editor); - this._editor = editor; + this._selection = editor.getSelectedGameObjects(); } - getRoots(input: Phaser.GameObjects.DisplayList): any[] { + getRoots(input: any): any[] { - return [input]; + return [this._editor.getScene().children]; } getChildren(parent: any): any[] { - if (parent instanceof Phaser.Structs.List) { + let children = super.getChildren(parent); - return this.filterList(parent.list); - } + children = children.filter(dstObj => { - if (parent instanceof Phaser.GameObjects.DisplayList) { + // cannot add anything different to an scene or a game object + if (!isGameObject(dstObj) && !(dstObj instanceof Phaser.GameObjects.DisplayList)) { - return this.filterList(parent.list); - } + return false; + } - if (parent instanceof Container) { + for (const selObj of this._selection) { - return this.filterList(parent.list); - } + // cannot move a layer to a container + if (selObj instanceof Layer && dstObj instanceof Container) { - return []; - } + return false; + } + + // cannot add to itself or any's childlren + if (selObj === dstObj) { - private filterList(list: any[]) { + return false; + } - const sel = this._editor.getSelectedGameObjects(); + // cannot add a non-script-node to a script node + if (dstObj instanceof ScriptNode && !(selObj instanceof ScriptNode)) { - return list.filter(obj => { + return false; + } - return MoveToParentOperation.canMoveAllTo(sel, obj); + // cannot add a non-script-node to a non-layer-or-container + if (!(dstObj instanceof Layer || dstObj instanceof Container) && !(selObj instanceof ScriptNode)) { + + return false; + } + + return true; + } + }); - }).reverse(); + return children; } } } \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ParentSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ParentSection.ts deleted file mode 100644 index a8b7f86e9..000000000 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/ParentSection.ts +++ /dev/null @@ -1,88 +0,0 @@ -namespace phasereditor2d.scene.ui.sceneobjects { - - import controls = colibri.ui.controls; - - export class ParentSection extends SceneGameObjectSection { - - constructor(page: controls.properties.PropertyPage) { - super(page, - "phasereditor2d.scene.ui.sceneobjects.ParentSection", "Parent", false, true); - } - - getSectionHelpPath() { - - return "scene-editor/parent-container-properties.html"; - } - - createMenu(menu: controls.Menu) { - - menu.addCommand(editor.commands.CMD_JOIN_IN_LAYER); - menu.addCommand(editor.commands.CMD_JOIN_IN_CONTAINER); - menu.addCommand(editor.commands.CMD_MOVE_TO_PARENT); - menu.addCommand(editor.commands.CMD_SELECT_PARENT); - - menu.addSeparator(); - - super.createMenu(menu); - } - - createForm(parent: HTMLDivElement) { - - const comp = this.createGridElement(parent, 2); - - this.createLabel(comp, "Parent", "The parent Container or Layer of the object, or the Display List"); - - const btn = this.createButton(comp, "(Select)", e => { - - const dlg = new ParentDialog(this.getEditor()); - dlg.create(); - dlg.eventDialogClose.addListener(() => { - - this.updateWithSelection(); - }); - }); - - controls.Tooltip.tooltip(btn, "Moves the objects for a new container or the Display List."); - - this.addUpdater(() => { - - const sel = this.getSelection(); - - const parents = sel - - .map(obj => sceneobjects.getObjectParent(obj)) - - .filter(cont => cont); - - const parentsSet = new Set(parents); - - let str: string; - - if (parentsSet.size === 1 && parents.length === sel.length) { - - str = parents[0].getEditorSupport().getLabel(); - - } else if (parents.length === 0) { - - str = "Display List"; - - } else { - - str = `(${parentsSet.size} selected)`; - } - - btn.textContent = str; - }); - } - - canEdit(obj: any, n: number): boolean { - - return sceneobjects.isGameObject(obj) && !isNestedPrefabInstance(obj); - } - - canEditNumber(n: number): boolean { - - return n > 0; - } - } -} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/PrefabInstanceUserPropertySection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/PrefabInstanceUserPropertySection.ts index 9e62a17b4..6712d7ba8 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/PrefabInstanceUserPropertySection.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/PrefabInstanceUserPropertySection.ts @@ -41,12 +41,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { const obj = this.getSelectionFirstElement() as ISceneGameObject; - if (obj.getEditorSupport().isNestedPrefabInstance()) { - - const file = obj.getEditorSupport().getPrefabFile(); - - this.createPrefabLink(file, `Root Prefab: ${file.getNameWithoutExtension()}`); - } + // properties of non-nested prefabs const userPropsComponent = GameObjectEditorSupport .getObjectComponent(obj, PrefabUserPropertyComponent) as PrefabUserPropertyComponent; @@ -107,6 +102,17 @@ namespace phasereditor2d.scene.ui.sceneobjects { prop.getType().createInspectorPropertyEditor(this, this._propArea, prop, true); } } + + // link to nested prefab + + const objES = obj.getEditorSupport(); + + if (objES.isNestedPrefabInstance()) { + + const file = objES.getPrefabFile(); + + this.createPrefabLink(file, `${file.getNameWithoutExtension()} (nested in)`); + } }); } diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/PrefabObjectVariableSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/PrefabObjectVariableSection.ts new file mode 100644 index 000000000..b1f182978 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/PrefabObjectVariableSection.ts @@ -0,0 +1,36 @@ +/// + +namespace phasereditor2d.scene.ui.sceneobjects { + + import controls = colibri.ui.controls; + + export class PrefabObjectVariableSection extends SceneGameObjectSection { + + constructor(page: controls.properties.PropertyPage) { + super(page, "phasereditor2d.scene.ui.sceneobjects.PrefabObjectVariableSection", "Variable", false); + } + + getSectionHelpPath() { + + return "scene-editor/variable-properties.html"; + } + + createForm(parent: HTMLDivElement) { + + const comp = this.createGridElement(parent, 2); + + GameObjectVariableSection.createTypeEditor(this, comp); + } + + canEdit(obj: any, n: number): boolean { + + return GameObjectEditorSupport.hasObjectComponent(obj, VariableComponent) + && this.isPrefabSceneObject(obj); + } + + canEditNumber(n: number): boolean { + + return n === 1; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneGameObjectSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneGameObjectSection.ts index 799ebc58c..8dab6e833 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneGameObjectSection.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneGameObjectSection.ts @@ -173,7 +173,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { const text = this.createStringField(parent, prop); - return text; + return { label, text }; } createPropertyStringDialogRow(parent: HTMLElement, prop: IProperty, lockIcon: boolean = true) { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneObjectSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneObjectSection.ts index c62753082..90c95fc02 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneObjectSection.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/SceneObjectSection.ts @@ -284,7 +284,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { const scene = sceneEditor.getScene(); const input = [ - ...scene.getDisplayListChildren(), + ...scene.getGameObjects(), ...scene.getObjectLists().getLists() ]; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tint/TintSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/TintSection.ts similarity index 100% rename from source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/tint/TintSection.ts rename to source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/TintSection.ts diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/TintSingleSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/TintSingleSection.ts new file mode 100644 index 000000000..1ecc5a6d5 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/properties/TintSingleSection.ts @@ -0,0 +1,37 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + import controls = colibri.ui.controls; + + export class TintSingleSection extends SceneGameObjectSection { + + constructor(page: controls.properties.PropertyPage) { + super(page, "phasereditor2d.scene.ui.sceneobjects.TintSingleSection", "Tint", false, true); + } + + getSectionHelpPath() { + + return "scene-editor/tint-properties.html"; + } + + createForm(parent: HTMLDivElement) { + + const comp = this.createGridElement(parent); + comp.style.gridTemplateColumns = "auto auto 1fr"; + + this.createPropertyBoolean(comp, TintSingleComponent.tintFill); + + this.createPropertyColorRow(comp, TintSingleComponent.tint, false); + } + + + canEdit(obj: any, n: number): boolean { + + return GameObjectEditorSupport.hasObjectComponent(obj, TintSingleComponent); + } + + canEditNumber(n: number): boolean { + + return n > 0; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/OriginTool.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/OriginTool.ts index 1e5345514..baa071bfe 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/OriginTool.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/OriginTool.ts @@ -41,9 +41,11 @@ namespace phasereditor2d.scene.ui.sceneobjects { if (obj instanceof Container) { - if (obj.getEditorSupport().isPrefabInstance()) { + const objES = obj.getEditorSupport(); - for (const test of [obj, ...obj.getChildren()]) { + if (objES.isPrefabInstance()) { + + for (const test of [obj, ...objES.getObjectChildren()]) { if (!test.getEditorSupport().isUnlockedPropertyXY(TransformComponent.position)) { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/PolygonTool.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/PolygonTool.ts index a77f50700..01fb0d4fd 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/PolygonTool.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/PolygonTool.ts @@ -39,6 +39,11 @@ namespace phasereditor2d.scene.ui.sceneobjects { "points", PolygonSection.SECTION_ID); } + isValidForAll(objects: ISceneGameObject[]): boolean { + + return objects.length === 1; + } + canRender(obj: unknown): boolean { return obj instanceof Polygon; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/SliceOperation.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/SliceOperation.ts new file mode 100644 index 000000000..5eab8cb71 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/SliceOperation.ts @@ -0,0 +1,42 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class SliceOperation extends editor.tools.SceneToolOperation { + + getInitialValue(obj: any) { + + return SliceToolItem.getInitialData(obj); + } + + getFinalValue(obj: NineSlice | ThreeSlice): ISliceData { + + if (obj instanceof NineSlice) { + + return { + leftWidth: obj.leftWidth, + rightWidth: obj.rightWidth, + topHeight: obj.topHeight, + bottomHeight: obj.bottomHeight + }; + } + + return { + leftWidth: obj.leftWidth, + rightWidth: obj.rightWidth, + topHeight: 0, + bottomHeight: 0 + }; + } + + setValue(obj: NineSlice | ThreeSlice, value: ISliceData) { + + const props = obj instanceof NineSlice ? + NineSliceComponent.sliceProperties : ThreeSliceComponent.sliceProperties; + + for (const prop of props) { + + console.log("set ", prop.name, value[prop.name]); + prop.setValue(obj, value[prop.name]); + } + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/SliceTool.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/SliceTool.ts new file mode 100644 index 000000000..cf0dbe442 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/SliceTool.ts @@ -0,0 +1,68 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class SliceTool extends BaseObjectTool { + + static ID = "phasereditor2d.scene.ui.sceneobjects.SliceTool"; + + constructor() { + super({ + id: SliceTool.ID, + command: editor.commands.CMD_EDIT_SLICE_SCENE_OBJECT, + }); + + this.addItems( + new SliceToolItem("leftWidth"), + new SliceToolItem("rightWidth"), + new SliceToolItem("topHeight"), + new SliceToolItem("bottomHeight"), + ); + } + + isValidForAll(objects: ISceneGameObject[]): boolean { + + return objects.length === 1; + } + + getProperties(obj: ISceneGameObject) { + + if (obj instanceof NineSlice) { + + return NineSliceComponent.sliceProperties; + } + + if (obj instanceof ThreeSlice) { + + return ThreeSliceComponent.sliceProperties; + } + + return []; + } + + onActivated(args: editor.tools.ISceneToolContextArgs) { + + super.onActivated(args); + + const props = args.objects.flatMap(obj => { + + if (obj instanceof NineSlice) { + + return NineSliceComponent.sliceProperties; + } + + return ThreeSliceComponent.sliceProperties; + }); + + const sections = args.objects.flatMap(obj => { + + if (obj instanceof NineSlice) { + + return NineSliceSection.SECTION_ID; + } + + return ThreeSliceSection.SECTION_ID; + }); + + this.confirmUnlockProperty(args, props, "slice", ...sections); + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/SliceToolItem.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/SliceToolItem.ts new file mode 100644 index 000000000..aefa0d025 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/object/tools/SliceToolItem.ts @@ -0,0 +1,343 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + type ISliceID = "leftWidth" | "rightWidth" | "topHeight" | "bottomHeight"; + + export interface ISliceData { + leftWidth: number; + rightWidth: number; + topHeight: number; + bottomHeight: number; + } + + const HANDLER_ANGLE = { + "leftWidth": 90, + "rightWidth": -90, + "topHeight": 0, + "bottomHeight": -180 + }; + + const HANDLER_OFFSET = 12; + const HANDLER_OFFSET_DIR = { + "leftWidth": { x: 0, y: -1 }, + "rightWidth": { x: 0, y: 1 }, + "topHeight": { x: -1, y: 0 }, + "bottomHeight": { x: 1, y: 0 } + }; + + const HANDLER_COLOR = "skyblue"; + + + export class SliceToolItem + extends editor.tools.SceneToolItem implements editor.tools.ISceneToolItemXY { + + private _slice: ISliceID; + private _dragging: boolean; + + constructor(slice: ISliceID) { + super(); + + this._slice = slice; + } + + isValidFor(objects: ISceneGameObject[]): boolean { + + for (const obj of objects) { + + if (obj instanceof ThreeSlice) { + + if (this._slice === "topHeight" || this._slice == "bottomHeight") { + + return false; + } + } + + if (!(obj instanceof ThreeSlice) && !(obj instanceof NineSlice)) { + + return false; + } + } + + return true; + } + + getPoint(args: editor.tools.ISceneToolContextArgs): { x: number; y: number; } { + + return this.getAvgScreenPointOfObjects(args, + + (sprite: sceneobjects.NineSlice) => { + + const ox = sprite.getEditorSupport().computeOrigin().originX; + + switch (this._slice) { + + case "leftWidth": + + return sprite.leftWidth / sprite.width - ox; + + case "rightWidth": + + return 1 - sprite.rightWidth / sprite.width - ox; + + case "topHeight": + + return -ox; + + case "bottomHeight": + + return 1 - ox; + } + }, + + (sprite: sceneobjects.NineSlice) => { + + const oy = sprite.getEditorSupport().computeOrigin().originY; + + switch (this._slice) { + + case "leftWidth": + + return -oy; + + case "rightWidth": + + return 1 - oy; + + case "topHeight": + + return sprite.topHeight / sprite.height - oy; + + case "bottomHeight": + + return 1 - sprite.bottomHeight / sprite.height - oy; + } + }, + ); + } + + render(args: editor.tools.ISceneToolRenderArgs) { + + const point = this.getPoint(args); + + const ctx = args.canvasContext; + + ctx.save(); + + ctx.translate(point.x, point.y); + + let angle = this.globalAngle(args.objects[0] as any); + + ctx.rotate(Phaser.Math.DegToRad(angle)); + + ctx.save(); + + const obj = args.objects[0] as NineSlice; + const scale = this.getScreenToObjectScale(args, obj); + + scale.x *= obj.scaleX; + scale.y *= obj.scaleY; + + ctx.strokeStyle = "#fff"; + + switch (this._slice) { + + case "leftWidth": + + this.drawLinePath(ctx, HANDLER_COLOR, 0, 0, 0, obj.height * scale.y, true); + break; + + case "rightWidth": + + this.drawLinePath(ctx, HANDLER_COLOR, 0, 0, 0, -obj.height * scale.y, true); + break; + + case "topHeight": + + this.drawLinePath(ctx, HANDLER_COLOR, 0, 0, obj.width * scale.x, 0, true); + break; + + case "bottomHeight": + + this.drawLinePath(ctx, HANDLER_COLOR, 0, 0, -obj.width * scale.x, 0, true); + break; + } + + ctx.restore(); + + ctx.translate( + HANDLER_OFFSET_DIR[this._slice].x * HANDLER_OFFSET, + HANDLER_OFFSET_DIR[this._slice].y * HANDLER_OFFSET); + + ctx.rotate(Phaser.Math.DegToRad(HANDLER_ANGLE[this._slice])); + + this.drawArrowPath(ctx, args.canEdit ? HANDLER_COLOR : editor.tools.SceneTool.COLOR_CANNOT_EDIT); + + ctx.restore(); + } + + containsPoint(args: editor.tools.ISceneToolDragEventArgs): boolean { + + const point = this.getPoint(args); + + return Phaser.Math.Distance.Between(args.x, args.y, point.x, point.y) < 20; + } + + onStartDrag(args: editor.tools.ISceneToolDragEventArgs): void { + + if (!this.containsPoint(args)) { + return; + } + + this._dragging = true; + + const point = this.getPoint(args); + + for (const obj of args.objects) { + + const sprite = obj as unknown as NineSlice; + + const worldTx = new Phaser.GameObjects.Components.TransformMatrix(); + + const initLocalPos = new Phaser.Math.Vector2(); + + sprite.getWorldTransformMatrix(worldTx); + + worldTx.applyInverse(point.x, point.y, initLocalPos); + + sprite.setData("SliceTool", { + initLeftWidth: sprite.leftWidth, + initRightWidth: sprite.rightWidth, + initTopHeight: sprite.topHeight, + initBottomHeight: sprite.bottomHeight, + initLocalPos: initLocalPos, + initWorldTx: worldTx + }); + } + } + + onDrag(args: editor.tools.ISceneToolDragEventArgs): void { + + if (!this._dragging) { + return; + } + + const mirror = args.event.shiftKey; + + const camera = args.camera; + + for (const obj of args.objects) { + + const sprite = obj as NineSlice; + const data = sprite.data.get("SliceTool"); + const initLocalPos: Phaser.Math.Vector2 = data.initLocalPos; + const worldTx: Phaser.GameObjects.Components.TransformMatrix = data.initWorldTx; + const { initLeftWidth, initRightWidth, initTopHeight, initBottomHeight } = data; + + const localPos = new Phaser.Math.Vector2(); + + worldTx.applyInverse(args.x, args.y, localPos); + + const dx = Math.floor((localPos.x - initLocalPos.x) / camera.zoom); + const dy = Math.floor((localPos.y - initLocalPos.y) / camera.zoom); + + const comp = obj instanceof NineSlice ? NineSliceComponent : ThreeSliceComponent; + + let value: number; + + switch (this._slice) { + + case "leftWidth": + + value = initLeftWidth + dx; + + comp.leftWidth.setValue(obj, value); + + if (mirror) { + + comp.rightWidth.setValue(obj, value); + } + + break; + + case "rightWidth": + + value = initRightWidth - dx; + + comp.rightWidth.setValue(obj, value); + + if (mirror) { + + comp.leftWidth.setValue(obj, value); + } + + break; + + case "topHeight": + + value = initTopHeight + dy; + + NineSliceComponent.topHeight.setValue(obj, value); + + if (mirror) { + + NineSliceComponent.bottomHeight.setValue(obj, value); + } + + break; + + case "bottomHeight": + + value = initBottomHeight - dy; + + NineSliceComponent.bottomHeight.setValue(obj, value); + + if (mirror) { + + NineSliceComponent.topHeight.setValue(obj, value); + } + + break; + } + } + + for (const obj of args.objects) { + + if (obj instanceof NineSlice) { + + args.editor.updateInspectorViewSection(NineSliceSection.SECTION_ID); + break; + } + } + + for (const obj of args.objects) { + + if (obj instanceof ThreeSlice) { + + args.editor.updateInspectorViewSection(ThreeSliceSection.SECTION_ID); + break; + } + } + } + + onStopDrag(args: editor.tools.ISceneToolDragEventArgs): void { + + if (this._dragging) { + + args.editor.getUndoManager().add(new SliceOperation(args)); + + this._dragging = false; + } + } + + static getInitialData(obj: any): ISliceData { + + const data = obj.getData("SliceTool"); + + return { + leftWidth: data.initLeftWidth, + rightWidth: data.initRightWidth, + topHeight: data.initTopHeight, + bottomHeight: data.initBottomHeight + }; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/AddScriptDialog.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/AddScriptDialog.ts new file mode 100644 index 000000000..7335d06dc --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/AddScriptDialog.ts @@ -0,0 +1,85 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + import controls = colibri.ui.controls; + import io = colibri.core.io; + + export class AddScriptDialog extends controls.dialogs.ViewerDialog { + + private static createViewer() { + + const viewer = new controls.viewers.TreeViewer("AddScriptsDialog"); + viewer.setLabelProvider(new controls.viewers.LabelProvider((obj: colibri.core.io.FilePath | ScriptNodeExtension) => { + + if (obj instanceof ScriptNodeExtension) { + + return obj.getTypeName(); + } + + return obj.getNameWithoutExtension(); + })); + viewer.setStyledLabelProvider(new (class s { + getStyledTexts(obj: any, dark: boolean) { + + let text: string; + let color: string; + + if (obj instanceof ScriptNodeExtension) { + + text = obj.getTypeName(); + color = controls.Controls.getTheme().viewerForeground; + + } else { + + text = obj.getNameWithoutExtension(); + color = ScenePlugin.getInstance().getPrefabColor(); + } + + return [{ text, color }]; + } + })); + viewer.setContentProvider(new controls.viewers.ArrayTreeContentProvider()); + viewer.setCellRendererProvider( + new controls.viewers.EmptyCellRendererProvider( + e => new controls.viewers.IconImageCellRenderer( + ScenePlugin.getInstance().getIcon(ICON_BUILD)))); + + const finder = ScenePlugin.getInstance().getSceneFinder(); + + const input = [ScriptNodeExtension.getInstance(), ...finder.getScriptPrefabFiles()]; + + viewer.setInput(input); + + return viewer; + } + + private _editor: ui.editor.SceneEditor; + + constructor(editor: ui.editor.SceneEditor) { + super(AddScriptDialog.createViewer(), false); + + this._editor = editor; + } + + create(): void { + + super.create(); + + this.setTitle("Add Script"); + + this.enableButtonOnlyWhenOneElementIsSelected( + this.addOpenButton("Add Script", sel => { + + this.addScript(sel[0]); + + })); + + this.addCancelButton(); + } + + addScript(script: any) { + + this._editor.getUndoManager().add( + new ui.editor.undo.CreateObjectWithAssetOperation(this._editor, [script], 0, 0)); + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/BrowseScriptsDialog.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/BrowseScriptsDialog.ts new file mode 100644 index 000000000..ba79e52c7 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/BrowseScriptsDialog.ts @@ -0,0 +1,127 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + import controls = colibri.ui.controls; + + export class BrowseScriptsDialog extends controls.dialogs.ViewerDialog { + + private static createViewer(editor: ui.editor.SceneEditor) { + + const viewer = new controls.viewers.TreeViewer("BrowseScriptsDialog"); + + viewer.setLabelProvider(new ui.editor.outline.SceneEditorOutlineLabelProvider()); + viewer.setStyledLabelProvider(new ui.editor.outline.SceneEditorOutlineStyledLabelProvider()); + viewer.setCellRendererProvider(new ui.editor.outline.SceneEditorOutlineRendererProvider()); + viewer.setContentProvider(new ScriptDialogContentProvider(editor)); + viewer.setInput([]) + viewer.expandRoots(); + + return viewer; + } + + private _editor: ui.editor.SceneEditor; + + constructor(editor: ui.editor.SceneEditor) { + super(BrowseScriptsDialog.createViewer(editor), true); + + this._editor = editor; + } + + create(): void { + + super.create(); + + this.setTitle("Browse Scripts"); + + this.addOpenButton("Select", sel => { + + this._editor.setSelection(sel); + }); + + this.addCancelButton(); + } + } + + class ScriptDialogContentProvider extends ui.editor.outline.SceneEditorOutlineContentProvider { + + getRoots(input: any): any[] { + + const sel = this._editor.getSelectedGameObjects(); + + let result: ISceneGameObject[]; + + if (sel.length === 0) { + + result = [...this._editor.getScene().getGameObjects()].reverse(); + + } else { + + sel.sort(sceneobjects.gameObjectSortingWeight); + + result = sel; + } + + result = result.filter(obj => { + + return obj instanceof ScriptNode || this.hasUserComponentOrScriptNode(obj); + }); + + return result; + } + + getChildren(parent: any): any[] { + + const children = super.getChildren(parent); + + let result = []; + + for (const obj of children) { + + if (obj instanceof ScriptNode) { + + result.push(obj); + + } else if (isGameObject(obj)) { + + if (this.hasUserComponentOrScriptNode(obj)) { + + result.push(obj); + } + } + } + + return result; + } + + private hasUserComponentOrScriptNode(obj: ISceneGameObject) { + + let result = obj.getEditorSupport().getObjectScriptNodes().length + + obj.getEditorSupport().getUserComponentsComponent() + .getUserComponentNodes().length > 0; + + if (!result) { + + const children = super.getChildren(obj); + + for (const child of children) { + + if (isGameObject(child)) { + + if (child instanceof ScriptNode) { + + return true; + } + + result = this.hasUserComponentOrScriptNode(child); + + if (result) { + + return true; + } + } + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNode.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNode.ts new file mode 100644 index 000000000..44dd197b1 --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNode.ts @@ -0,0 +1,67 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class ScriptNode extends Phaser.GameObjects.GameObject implements ISceneGameObject { + + private _editorSupport: ScriptNodeEditorSupport; + private _parent: ISceneGameObject | Phaser.GameObjects.DisplayList; + + constructor(scene: Scene) { + super(scene, "ScriptNode"); + + this._editorSupport = new ScriptNodeEditorSupport(scene, this); + + this._parent = scene.children; + } + + getParentDisplayObject() { + + if (this._parent) { + + if (this._parent instanceof ScriptNode) { + + return this._parent.getParentDisplayObject(); + + } else if (isGameObject(this._parent)) { + + return this._parent; + } + } + + return undefined; + } + + willRender(camera: Phaser.Cameras.Scene2D.Camera): boolean { + + return false; + } + + getEditorSupport() { + + return this._editorSupport; + } + + getParent() { + + return this._parent; + } + + setParent(parent: ISceneGameObject) { + + this._parent = parent; + } + + removeFromParent() { + + if (isGameObject(this._parent)) { + + (this._parent as ISceneGameObject).getEditorSupport().removeObjectChild(this); + + } else { + + (this.scene as Scene).removeGameObject(this); + } + + this._parent = undefined; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeCodeDOMBuilder.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeCodeDOMBuilder.ts new file mode 100644 index 000000000..0c38abc8a --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeCodeDOMBuilder.ts @@ -0,0 +1,52 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + import code = scene.core.code; + + export class ScriptNodeCodeDOMBuilder extends GameObjectCodeDOMBuilder { + + constructor() { + super("ScriptNode"); + } + + buildCreateObjectWithFactoryCodeDOM(args: IBuildObjectFactoryCodeDOMArgs): core.code.MethodCallCodeDOM { + + const call = new code.MethodCallCodeDOM("ScriptNode"); + + call.setConstructor(true); + + call.arg(args.parentVarName || args.sceneExpr) + + return call; + } + + buildCreatePrefabInstanceCodeDOM(args: IBuildPrefabConstructorCodeDOMArgs): void { + + const call = args.methodCallDOM; + + call.arg(args.parentVarName || args.sceneExpr); + } + + buildPrefabConstructorDeclarationCodeDOM(args: IBuildPrefabConstructorDeclarationCodeDOM): void { + + const types = ScriptNodeEditorSupport.DEFAULT_PARENT_VARIABLE_TYPES; + args.importTypes = types; + + const decl = args.ctrDeclCodeDOM; + + // remove the scene arg + decl.getArgs().pop(); + + decl.arg("parent", types.join(" | ")); + } + + buildPrefabConstructorDeclarationSupperCallCodeDOM(args: IBuildPrefabConstructorDeclarationSupperCallCodeDOMArgs): void { + + const call = args.superMethodCallCodeDOM; + + // remove the scene arg + call.getArgs().pop(); + + call.arg("parent"); + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeCodeResources.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeCodeResources.ts new file mode 100644 index 000000000..1764b349c --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeCodeResources.ts @@ -0,0 +1,18 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class ScriptNodeCodeResources extends core.code.CodeResources { + + private static _instance = new ScriptNodeCodeResources(); + + static getInstance() { + + return this._instance; + } + + private constructor() { + super(ScenePlugin.getInstance()); + + this.addCodeResource("ScriptNode"); + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeEditorSupport.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeEditorSupport.ts new file mode 100644 index 000000000..4a5119fda --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeEditorSupport.ts @@ -0,0 +1,46 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + import controls = colibri.ui.controls; + + export class ScriptNodeEditorSupport extends GameObjectEditorSupport { + + static DEFAULT_PARENT_VARIABLE_TYPES = ["ScriptNode", "Phaser.GameObjects.GameObject", "Phaser.Scene"]; + + constructor(scene: Scene, obj: ScriptNode) { + super(ScriptNodeExtension.getInstance(), obj, scene); + } + + destroy(): boolean | void { + + this.getObject().removeFromParent(); + + super.destroy(); + } + + isDisplayObject(): boolean { + + return false; + } + + setInteractive(): void { + // nothing + } + + getCellRenderer(): colibri.ui.controls.viewers.ICellRenderer { + + return new controls.viewers.IconImageCellRenderer(ScenePlugin.getInstance().getIcon(ICON_BUILD)); + } + + getObjectParent(): ISceneGameObject { + + const parent = this.getObject().getParent(); + + if (isGameObject(parent)) { + + return parent as ISceneGameObject; + } + + return undefined; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeExtension.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeExtension.ts new file mode 100644 index 000000000..ed0340cca --- /dev/null +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/scriptNode/ScriptNodeExtension.ts @@ -0,0 +1,64 @@ +namespace phasereditor2d.scene.ui.sceneobjects { + + export class ScriptNodeExtension extends SceneGameObjectExtension { + + private static _instance: ScriptNodeExtension; + + static getInstance() { + + return this._instance || (this._instance = new ScriptNodeExtension()); + } + + constructor() { + super({ + typeName: "ScriptNode", + phaserTypeName: "ScriptNode", + category: SCENE_OBJECT_SCRIPT_CATEGORY, + icon: ScenePlugin.getInstance().getIconDescriptor(ICON_BUILD) + }); + } + + getHelp(): string { + + return "A custom Phaser Editor 2D object for implementing game logic and object behaviors."; + } + + acceptsDropData(data: any): boolean { + + return false; + } + + createSceneObjectWithAsset(args: ICreateWithAssetArgs): ISceneGameObject { + + // not supported + + return null; + } + + createGameObjectWithData(args: ICreateWithDataArgs): ISceneGameObject { + + const script = new ScriptNode(args.scene); + + script.getEditorSupport().readJSON(args.data); + + return script; + } + + async getAssetsFromObjectData(args: IGetAssetsFromObjectArgs): Promise { + + return []; + } + + getCodeDOMBuilder(): GameObjectCodeDOMBuilder { + + return new ScriptNodeCodeDOMBuilder(); + } + + createDefaultSceneObject(args: ICreateDefaultArgs): ISceneObject[] { + + const script = new ScriptNode(args.scene); + + return [script]; + } + } +} \ No newline at end of file diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/shapes/rect/RectangleCodeDOMBuilder.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/shapes/rect/RectangleCodeDOMBuilder.ts index c52b1e5ca..372737df7 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/shapes/rect/RectangleCodeDOMBuilder.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/shapes/rect/RectangleCodeDOMBuilder.ts @@ -39,7 +39,8 @@ namespace phasereditor2d.scene.ui.sceneobjects { buildCreateObjectWithFactoryCodeDOM(args: IBuildObjectFactoryCodeDOMArgs): code.MethodCallCodeDOM { - const obj = args.obj as TileSprite; + const obj = args.obj as Rectangle; + const call = new code.MethodCallCodeDOM("rectangle", args.gameObjectFactoryExpr); call.argFloat(obj.x); diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/text/TextSection.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/text/TextSection.ts index 2f9fc811f..3d783af52 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/text/TextSection.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/text/TextSection.ts @@ -18,10 +18,10 @@ namespace phasereditor2d.scene.ui.sceneobjects { const comp = this.createGridElementWithPropertiesXY(parent); // fontFamily - this.createPropertyStringRow(comp, TextComponent.fontFamily).style.gridColumn = "3 / span 4"; + this.createPropertyStringRow(comp, TextComponent.fontFamily).text.style.gridColumn = "3 / span 4"; // fontSize - this.createPropertyStringRow(comp, TextComponent.fontSize).style.gridColumn = "3 / span 4"; + this.createPropertyStringRow(comp, TextComponent.fontSize).text.style.gridColumn = "3 / span 4"; // fontStyle this.createPropertyEnumRow(comp, TextComponent.fontStyle).style.gridColumn = "3 / span 4"; diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/texture/TextureComponent.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/texture/TextureComponent.ts index 7d659086d..ed0854b36 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/texture/TextureComponent.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/texture/TextureComponent.ts @@ -87,10 +87,14 @@ namespace phasereditor2d.scene.ui.sceneobjects { obj.setTexture(keys.key || null, keys.frame); - if (obj.getEditorSupport().hasComponent(OriginComponent)) { + const objES = obj.getEditorSupport(); + + if (objES.hasComponent(OriginComponent)) { obj.setOrigin(ox, oy); } + + objES.onUpdateAfterSetTexture(); } removeTexture() { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/ObjectVarPropertyType.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/ObjectVarPropertyType.ts index b449a0ca3..398158fc1 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/ObjectVarPropertyType.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/sceneobjects/userProperties/ObjectVarPropertyType.ts @@ -67,7 +67,7 @@ namespace phasereditor2d.scene.ui.sceneobjects { protected loadViewerInput(viewer: colibri.ui.controls.viewers.TreeViewer): void { - viewer.setInput(this.getEditor().getScene().getDisplayListChildren()); + viewer.setInput(this.getEditor().getScene().getGameObjects()); } protected async updateIcon(iconControl: controls.IconControl, value: string): Promise { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/viewers/ObjectExtensionAndPrefabViewer.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/viewers/ObjectExtensionAndPrefabViewer.ts index 49adc04c9..e4d7aea5f 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/viewers/ObjectExtensionAndPrefabViewer.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/viewers/ObjectExtensionAndPrefabViewer.ts @@ -17,9 +17,8 @@ namespace phasereditor2d.scene.ui.viewers { const treeRenderer = new controls.viewers.GridTreeViewerRenderer(this); treeRenderer.setPaintItemShadow(true); treeRenderer.setSectionCriteria(obj => ObjectExtensionAndPrefabViewer.SECTIONS.indexOf(obj) >= 0); - this.setLabelProvider(new ui.blocks.SceneEditorBlocksLabelProvider()); - this.setCellRendererProvider(new ui.blocks.SceneEditorBlocksCellRendererProvider()); + this.setCellRendererProvider(new CellRendererProvider()); this.setContentProvider(new ObjectExtensionAndPrefabContentProvider()); this.setTreeRenderer(treeRenderer); this.setInput(ObjectExtensionAndPrefabViewer.SECTIONS); @@ -28,6 +27,19 @@ namespace phasereditor2d.scene.ui.viewers { } } + class CellRendererProvider extends ui.blocks.SceneEditorBlocksCellRendererProvider { + + getCellRenderer(element: any) { + + if (element === ObjectExtensionAndPrefabViewer.PREFAB_SECTION) { + + return new controls.viewers.IconImageCellRenderer(colibri.ColibriPlugin.getInstance().getIcon(colibri.ICON_FOLDER)); + } + + return super.getCellRenderer(element); + } + } + export class ObjectExtensionAndPrefabContentProvider implements controls.viewers.ITreeContentProvider { getRoots(input: any): any[] { diff --git a/source/editor/plugins/phasereditor2d.scene/src/ui/viewers/SceneFileCellRenderer.ts b/source/editor/plugins/phasereditor2d.scene/src/ui/viewers/SceneFileCellRenderer.ts index 2a9fb4a01..263e1e665 100644 --- a/source/editor/plugins/phasereditor2d.scene/src/ui/viewers/SceneFileCellRenderer.ts +++ b/source/editor/plugins/phasereditor2d.scene/src/ui/viewers/SceneFileCellRenderer.ts @@ -7,9 +7,20 @@ namespace phasereditor2d.scene.ui.viewers { renderCell(args: controls.viewers.RenderCellArgs): void { + const finder = ScenePlugin.getInstance().getSceneFinder(); + const file = args.obj as core.io.FilePath; - const image = SceneThumbnailCache.getInstance().getContent(file); + let image: controls.IImage; + + if (finder.isScriptPrefabFile(file)) { + + image = ScenePlugin.getInstance().getIcon(ICON_BUILD); + + } else { + + image = SceneThumbnailCache.getInstance().getContent(file); + } if (image) { diff --git a/source/editor/tsconfig-base.json b/source/editor/tsconfig-base.json index 7ed4b6120..de65540a5 100644 --- a/source/editor/tsconfig-base.json +++ b/source/editor/tsconfig-base.json @@ -4,7 +4,7 @@ "esnext", "dom" ], - "target": "ES2020", + "target": "ESNext", "composite": true, "declaration": true, "declarationMap": true, diff --git a/tests/workspace/test-typescript/scenes/TestTileSpriteSizeInInspector.scene b/tests/workspace/test-typescript/scenes/TestTileSpriteSizeInInspector.scene new file mode 100755 index 000000000..842dacfff --- /dev/null +++ b/tests/workspace/test-typescript/scenes/TestTileSpriteSizeInInspector.scene @@ -0,0 +1,43 @@ +{ + "id": "22f975d4-0322-485d-915b-0548ee638fea", + "sceneType": "SCENE", + "settings": { + "preloadPackFiles": [], + "createMethodName": "editorCreate", + "sceneKey": "TestTileSpriteSizeInInspector", + "compilerOutputLanguage": "TYPE_SCRIPT" + }, + "displayList": [ + { + "type": "TileSprite", + "id": "103bcf21-ad8c-4b01-a348-754cb35b17df", + "label": "dino", + "components": [], + "texture": { + "key": "dino" + }, + "x": 418, + "y": 329, + "width": 756, + "height": 565 + }, + { + "type": "Rectangle", + "id": "ca3762b4-26b3-4016-9437-57f38d7d56cf", + "label": "rectangle_1", + "components": [], + "x": 89, + "y": 84, + "isFilled": true, + "width": 128, + "height": 128 + } + ], + "plainObjects": [], + "meta": { + "app": "Phaser Editor 2D - Scene Editor", + "url": "https://phasereditor2d.com", + "contentType": "phasereditor2d.core.scene.SceneContentType", + "version": 3 + } +} \ No newline at end of file diff --git a/tests/workspace/test-typescript/scenes/TestTileSpriteSizeInInspector.ts b/tests/workspace/test-typescript/scenes/TestTileSpriteSizeInInspector.ts new file mode 100755 index 000000000..263e97977 --- /dev/null +++ b/tests/workspace/test-typescript/scenes/TestTileSpriteSizeInInspector.ts @@ -0,0 +1,42 @@ + +// You can write more code here + +/* START OF COMPILED CODE */ + +class TestTileSpriteSizeInInspector extends Phaser.Scene { + + constructor() { + super("TestTileSpriteSizeInInspector"); + + /* START-USER-CTR-CODE */ + // Write your code here. + /* END-USER-CTR-CODE */ + } + + editorCreate(): void { + + // dino + this.add.tileSprite(418, 329, 756, 565, "dino"); + + // rectangle_1 + const rectangle_1 = this.add.rectangle(89, 84, 128, 128); + rectangle_1.isFilled = true; + + this.events.emit("scene-awake"); + } + + /* START-USER-CODE */ + + // Write your code here + + create() { + + this.editorCreate(); + } + + /* END-USER-CODE */ +} + +/* END OF COMPILED CODE */ + +// You can write more code here